mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-12-24 07:02:26 +01:00
Merged from dev. Fixed merge conflicts. Updated terminal documentation for wget
This commit is contained in:
commit
b36855fe52
13
.editorconfig
Normal file
13
.editorconfig
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 4
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
insert_final_newline = true
|
||||||
|
|
||||||
|
[package.json]
|
||||||
|
indent_size = 2
|
||||||
|
|
||||||
|
[md]
|
||||||
|
trim_trailing_whitespace = false
|
@ -57,8 +57,8 @@ You can contact him through:
|
|||||||
* Discord
|
* Discord
|
||||||
* [Reddit](https://www.reddit.com/user/chapt3r/)
|
* [Reddit](https://www.reddit.com/user/chapt3r/)
|
||||||
|
|
||||||
Otherwise, here are some general guidelines for determining what types of changes
|
Otherwise, here are some general guidelines for determining what types of
|
||||||
are okay to contribute:
|
changes are okay to contribute:
|
||||||
|
|
||||||
##### Contributions that Will Most Likely Be Accepted
|
##### Contributions that Will Most Likely Be Accepted
|
||||||
* Bug Fixes
|
* Bug Fixes
|
||||||
@ -88,12 +88,16 @@ the following rules:
|
|||||||
the changes to the UI
|
the changes to the UI
|
||||||
- If your changes affect Netscript, provide some
|
- If your changes affect Netscript, provide some
|
||||||
scripts that can be used to test the Netscript changes.
|
scripts that can be used to test the Netscript changes.
|
||||||
- Do not check in any bundled files (`dist\*.bundle.js`). These will be
|
- Ensure you have run `npm run lint` to make sure your changes conform to the
|
||||||
updated as part of official releases.
|
rules enforced across the code base. The command will fail if any of the
|
||||||
|
linters find a violation.
|
||||||
|
- Do not check in any bundled files (`dist\*.bundle.js`) or the `index.html`
|
||||||
|
in the root of the repository. These will be updated as part of official
|
||||||
|
releases.
|
||||||
|
|
||||||
## As a Documentor
|
## As a Documentor
|
||||||
To contribute to BitBurner documentation, you will need to have Python
|
To contribute to and view your changes to the BitBurner documentation, you will
|
||||||
installed, along with [Sphinx](http://www.sphinx-doc.org).
|
need to have Python installed, along with [Sphinx](http://www.sphinx-doc.org).
|
||||||
|
|
||||||
Before submitting your code for a pull request, please try to follow these
|
Before submitting your code for a pull request, please try to follow these
|
||||||
rules:
|
rules:
|
||||||
@ -103,3 +107,5 @@ rules:
|
|||||||
- Rebase your branch if necessary
|
- Rebase your branch if necessary
|
||||||
- When submitting the pull request, make sure that the base fork is
|
- When submitting the pull request, make sure that the base fork is
|
||||||
_danielyxie/bitburner_ and the base is _dev_.
|
_danielyxie/bitburner_ and the base is _dev_.
|
||||||
|
- Do not check in any generated files under `doc\`. The documentation is built
|
||||||
|
automatically by ReadTheDocs.
|
||||||
|
@ -1,2 +1,17 @@
|
|||||||
$fontFamily: 'Lucida Console', 'Lucida Sans Unicode', 'Fira Mono', 'Consolas', 'Courier New', Courier, monospace, 'Times New Roman';
|
$fontFamily: 'Lucida Console', 'Lucida Sans Unicode', 'Fira Mono', 'Consolas', 'Courier New', Courier, monospace, 'Times New Roman';
|
||||||
$defaultFontSize: 16px;
|
$defaultFontSize: 16px;
|
||||||
|
|
||||||
|
/* COLORS */
|
||||||
|
$hacker-green: #adff2f;
|
||||||
|
$success-green: #3adb76;
|
||||||
|
$alert-red: #ff2929;
|
||||||
|
$money-gold: #ffd700;
|
||||||
|
$light-yellow: #faffdf;
|
||||||
|
|
||||||
|
/* Attributes */
|
||||||
|
$my-stat-hp-color: #dd3434;
|
||||||
|
$my-stat-money-color: $money-gold;
|
||||||
|
$my-stat-hack-color: $hacker-green;
|
||||||
|
$my-stat-physical: $light-yellow;
|
||||||
|
$my-stat-cha-color: #a671d1;
|
||||||
|
$my-stat-int-color: #6495ed;
|
||||||
|
@ -11,11 +11,11 @@
|
|||||||
position: absolute; /* Stay in place */
|
position: absolute; /* Stay in place */
|
||||||
right: 0;
|
right: 0;
|
||||||
top: 0;
|
top: 0;
|
||||||
height: 400px; /* Full height */
|
height: 450px;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
border: 5px solid #fff;
|
border: 5px solid #fff;
|
||||||
width: 20%;
|
width: 23%;
|
||||||
overflow: auto; /* Enable scroll if needed */
|
overflow: hidden;
|
||||||
background-color: #444; /* Fallback color */
|
background-color: #444; /* Fallback color */
|
||||||
color: #fff;
|
color: #fff;
|
||||||
|
|
||||||
@ -29,6 +29,9 @@
|
|||||||
margin: 4px;
|
margin: 4px;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
background-color: #444;
|
background-color: #444;
|
||||||
|
font-size: $defaultFontSize * 0.875;
|
||||||
|
max-height: 350px;
|
||||||
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
#interactive-tutorial-exit,
|
#interactive-tutorial-exit,
|
||||||
@ -38,7 +41,7 @@
|
|||||||
@include boxShadow(1px 1px 3px #000);
|
@include boxShadow(1px 1px 3px #000);
|
||||||
|
|
||||||
color: #aaa;
|
color: #aaa;
|
||||||
font-size: $defaultFontSize * 1.25;
|
font-size: $defaultFontSize * 1.125;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
background-color: #000;
|
background-color: #000;
|
||||||
|
|
||||||
@ -50,6 +53,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
#interactive-tutorial-exit {
|
#interactive-tutorial-exit {
|
||||||
float: left;
|
float: left;
|
||||||
}
|
}
|
||||||
@ -58,6 +62,16 @@
|
|||||||
margin-right: 20%;
|
margin-right: 20%;
|
||||||
float: right;
|
float: right;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
#interactive-tutorial-exit {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#interactive-tutorial-back {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
#interactive-tutorial-next {
|
#interactive-tutorial-next {
|
||||||
float: right;
|
float: right;
|
||||||
|
@ -22,17 +22,15 @@
|
|||||||
#script-editor-container {
|
#script-editor-container {
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
#javascript-editor {
|
#javascript-editor {
|
||||||
margin: 10px;
|
margin: 10px;
|
||||||
|
|
||||||
height: 80%;
|
height: 80%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin-left: 6px;
|
margin-left: 6px;
|
||||||
|
|
||||||
padding-left: 6px;
|
padding-left: 6px;
|
||||||
padding-top: 6px;
|
padding-top: 6px;
|
||||||
padding-bottom: 6px;
|
padding-bottom: 6px;
|
||||||
|
|
||||||
border: 2px solid var(--my-highlight-color);
|
border: 2px solid var(--my-highlight-color);
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
font-family: $fontFamily;
|
font-family: $fontFamily;
|
||||||
@ -101,9 +99,7 @@
|
|||||||
resize: none;
|
resize: none;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
margin: 4px;
|
margin: 4px;
|
||||||
|
|
||||||
padding: 2px;
|
padding: 2px;
|
||||||
|
|
||||||
border: 2px solid var(--my-highlight-color);
|
border: 2px solid var(--my-highlight-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,38 +200,37 @@
|
|||||||
.active-scripts-script-header {
|
.active-scripts-script-header {
|
||||||
background-color: #555;
|
background-color: #555;
|
||||||
color: var(--my-font-color);
|
color: var(--my-font-color);
|
||||||
padding: 4px;
|
padding: 4px 25px 4px 10px;
|
||||||
padding-left: 10px;
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
width: auto;
|
width: auto;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
border: none;
|
border: none;
|
||||||
outline: none;
|
outline: none;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
content: '\02795'; /* "plus" sign (+) */
|
||||||
|
font-size: $defaultFontSize * 0.8125;
|
||||||
|
float: right;
|
||||||
|
margin-left: 5px;
|
||||||
|
color: transparent;
|
||||||
|
text-shadow: 0 0 0 var(--my-font-color);
|
||||||
|
position: absolute;
|
||||||
|
bottom: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.active-scripts-script-header:hover,
|
&.active:after {
|
||||||
.active-scripts-script-header.active:hover {
|
content: "\2796"; /* "minus" sign (-) */
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&.active:hover {
|
||||||
background-color: #666;
|
background-color: #666;
|
||||||
}
|
}
|
||||||
|
|
||||||
.active-scripts-script-header.active {
|
&.active {
|
||||||
background-color: #555;
|
background-color: #555;
|
||||||
}
|
}
|
||||||
|
|
||||||
.active-scripts-script-header:after {
|
|
||||||
content: '\02795'; /* "plus" sign (+) */
|
|
||||||
font-size: $defaultFontSize * 0.8125;
|
|
||||||
color: var(--my-font-color);
|
|
||||||
float: right;
|
|
||||||
margin-left: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.active-scripts-script-header.active:after {
|
|
||||||
content: "\2796"; /* "minus" sign (-) */
|
|
||||||
font-size: $defaultFontSize * 0.8125;
|
|
||||||
color: var(--my-font-color);
|
|
||||||
float: right;
|
|
||||||
margin-left: 5px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.active-scripts-script-panel {
|
.active-scripts-script-panel {
|
||||||
@ -244,17 +239,14 @@
|
|||||||
width: auto;
|
width: auto;
|
||||||
display: none;
|
display: none;
|
||||||
margin-bottom: 6px;
|
margin-bottom: 6px;
|
||||||
}
|
|
||||||
|
|
||||||
.active-scripts-script-panel p,
|
p, h2, ul, li {
|
||||||
.active-scripts-script-panel h2,
|
|
||||||
.active-scripts-script-panel ul,
|
|
||||||
.active-scripts-script-panel li {
|
|
||||||
background-color: #555;
|
background-color: #555;
|
||||||
width: auto;
|
width: auto;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
margin-left: 5%;
|
margin-left: 5%;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.active-scripts-button {
|
.active-scripts-button {
|
||||||
@include borderRadius(12px);
|
@include borderRadius(12px);
|
||||||
@ -266,14 +258,14 @@
|
|||||||
margin: 4px;
|
margin: 4px;
|
||||||
padding: 4px;
|
padding: 4px;
|
||||||
background-color: #000;
|
background-color: #000;
|
||||||
}
|
|
||||||
|
|
||||||
.active-scripts-button:hover,
|
&:hover,
|
||||||
.active-scripts-button:focus {
|
&:focus {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Hacknet Nodes */
|
/* Hacknet Nodes */
|
||||||
#hacknet-nodes-container {
|
#hacknet-nodes-container {
|
||||||
@ -291,6 +283,16 @@
|
|||||||
float: left;
|
float: left;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
|
||||||
|
&.hacknet-node {
|
||||||
|
$boxShadowArgs: inset 0 0 8px rgba(0, 0, 0, 0.1), 0 0 16px rgba(0, 0, 0, 0.1);
|
||||||
|
@include boxShadow($boxShadowArgs);
|
||||||
|
|
||||||
|
margin: 6px;
|
||||||
|
padding: 7px;
|
||||||
|
width: 35vw;
|
||||||
|
border: 2px solid var(--my-highlight-color);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#hacknet-nodes-list {
|
#hacknet-nodes-list {
|
||||||
@ -316,35 +318,25 @@
|
|||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hacknet-node {
|
|
||||||
$boxShadowArgs: inset 0 0 8px rgba(0, 0, 0, 0.1), 0 0 16px rgba(0, 0, 0, 0.1);
|
|
||||||
@include boxShadow($boxShadowArgs);
|
|
||||||
|
|
||||||
margin: 6px;
|
|
||||||
padding: 6px;
|
|
||||||
width: 34vw;
|
|
||||||
border: 2px solid var(--my-highlight-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.hacknet-node-container {
|
.hacknet-node-container {
|
||||||
display: inline-table;
|
display: inline-table;
|
||||||
}
|
|
||||||
|
|
||||||
.hacknet-node-container .row {
|
.row {
|
||||||
display: table-row;
|
display: table-row;
|
||||||
height: 30px;
|
height: 30px;
|
||||||
}
|
|
||||||
|
|
||||||
.hacknet-node-container .row p {
|
p {
|
||||||
display: table-cell;
|
display: table-cell;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.hacknet-node-container .upgradable-info {
|
.upgradable-info {
|
||||||
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: $defaultFontSize * 4;
|
width: $defaultFontSize * 4;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.menu-page-text {
|
.menu-page-text {
|
||||||
width: 70vw;
|
width: 70vw;
|
||||||
@ -412,8 +404,8 @@
|
|||||||
|
|
||||||
#faction-container p,
|
#faction-container p,
|
||||||
#faction-container pre {
|
#faction-container pre {
|
||||||
padding: 6px;
|
padding: 4px 6px;
|
||||||
margin: 6px;
|
margin: 4px 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#faction-container pre {
|
#faction-container pre {
|
||||||
@ -429,15 +421,12 @@
|
|||||||
#faction-augmentations-container {
|
#faction-augmentations-container {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
padding-top: 10px;
|
padding-top: 10px;
|
||||||
}
|
|
||||||
|
|
||||||
#faction-augmentations-container p,
|
p, a, ul, h1 {
|
||||||
#faction-augmentations-container a,
|
|
||||||
#faction-augmentations-container ul,
|
|
||||||
#faction-augmentations-container h1{
|
|
||||||
margin: 8px;
|
margin: 8px;
|
||||||
padding: 4px;
|
padding: 4px;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* World */
|
/* World */
|
||||||
#world-container li {
|
#world-container li {
|
||||||
@ -451,13 +440,22 @@
|
|||||||
padding-top: 10px;
|
padding-top: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.augmentations-list button,
|
.augmentations-list {
|
||||||
.augmentations-list div {
|
button,
|
||||||
|
div {
|
||||||
color: var(--my-font-color);
|
color: var(--my-font-color);
|
||||||
padding: 8px;
|
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
padding: 2px 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div {
|
||||||
|
padding: 6px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Tutorial */
|
/* Tutorial */
|
||||||
#tutorial-container {
|
#tutorial-container {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
@ -510,11 +508,12 @@
|
|||||||
padding: 6px;
|
padding: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#location-container * {
|
#location-container > * {
|
||||||
margin: 10px 5px 10px 5px;
|
margin: 10px 5px 10px 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#location-job-reputation, #location-company-favor {
|
#location-job-reputation,
|
||||||
|
#location-company-favor {
|
||||||
display: inline;
|
display: inline;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -522,7 +521,13 @@
|
|||||||
#infiltration-container {
|
#infiltration-container {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
padding: 6px;
|
padding: 6px;
|
||||||
|
|
||||||
|
span {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#infiltration-left-panel,
|
#infiltration-left-panel,
|
||||||
#infiltration-right-panel {
|
#infiltration-right-panel {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
@ -543,6 +548,10 @@
|
|||||||
margin: 4px;
|
margin: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#infiltration-buttons {
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
#infiltration-buttons .a-link-button {
|
#infiltration-buttons .a-link-button {
|
||||||
display: inline;
|
display: inline;
|
||||||
width: 25%;
|
width: 25%;
|
||||||
@ -552,6 +561,7 @@
|
|||||||
#stock-market-container {
|
#stock-market-container {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
padding: 6px;
|
padding: 6px;
|
||||||
|
|
||||||
p {
|
p {
|
||||||
font-size: $defaultFontSize * 0.8125;
|
font-size: $defaultFontSize * 0.8125;
|
||||||
}
|
}
|
||||||
|
@ -87,6 +87,11 @@
|
|||||||
z-index: 2;
|
z-index: 2;
|
||||||
background-color: var(--my-background-color);
|
background-color: var(--my-background-color);
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
|
|
||||||
|
p span {
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.dialog-box-close-button {
|
.dialog-box-close-button {
|
||||||
@ -138,6 +143,11 @@
|
|||||||
margin: 8px;
|
margin: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#infiltration-box-content span {
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
#infiltration-faction-select {
|
#infiltration-faction-select {
|
||||||
background-color: #000;
|
background-color: #000;
|
||||||
}
|
}
|
||||||
|
206
css/styles.scss
206
css/styles.scss
@ -7,6 +7,7 @@
|
|||||||
--my-font-color: #6f3;
|
--my-font-color: #6f3;
|
||||||
--my-background-color: #000;
|
--my-background-color: #000;
|
||||||
--my-highlight-color: #fff;
|
--my-highlight-color: #fff;
|
||||||
|
--my-prompt-color: #f92672;
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
@ -83,7 +84,7 @@ tr:focus {
|
|||||||
display: block;
|
display: block;
|
||||||
color: #e6e6e6;
|
color: #e6e6e6;
|
||||||
background-color: #555;
|
background-color: #555;
|
||||||
padding: 16px;
|
padding: 12px 8px;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,21 +106,36 @@ tr:focus {
|
|||||||
background-color: #aaa;
|
background-color: #aaa;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#hacking-menu-header-li,
|
||||||
|
#character-menu-header-li,
|
||||||
|
#world-menu-header-li,
|
||||||
|
#help-menu-header-li {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Accordion Outline */
|
||||||
|
.mainmenu-accordion-header {
|
||||||
|
outline: 2px solid #fff;
|
||||||
|
}
|
||||||
|
|
||||||
/* Plus and minus signs */
|
/* Plus and minus signs */
|
||||||
.mainmenu-accordion-header:after {
|
.mainmenu-accordion-header:after {
|
||||||
content: '\02795';
|
content: '\02795';
|
||||||
font-size: $defaultFontSize * 0.8125;
|
|
||||||
color: #fff;
|
|
||||||
float: right;
|
float: right;
|
||||||
margin-left: 5px;
|
font-size: $defaultFontSize * 0.8125;
|
||||||
}
|
position: absolute;
|
||||||
|
bottom: 25%;
|
||||||
.mainmenu-accordion-header.opened:after {
|
right: 3px;
|
||||||
content: "\2796";
|
color: transparent;
|
||||||
|
text-shadow: 0 0 0 #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mainmenu-accordion-header.opened {
|
.mainmenu-accordion-header.opened {
|
||||||
background-color: #222;
|
background-color: #222;
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
content: "\2796";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Slide down transition */
|
/* Slide down transition */
|
||||||
@ -129,11 +145,6 @@ tr:focus {
|
|||||||
transition: max-height 0.2s ease-out;
|
transition: max-height 0.2s ease-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Borders */
|
|
||||||
.mainmenu-accordion-header {
|
|
||||||
border: 2px solid #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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:link,
|
||||||
a:visited {
|
a:visited {
|
||||||
@ -144,7 +155,7 @@ a:visited {
|
|||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
background-color: #555;
|
background-color: #555;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
padding: 5px;
|
padding: 3px 5px;
|
||||||
margin: 5px;
|
margin: 5px;
|
||||||
border: 1px solid #333;
|
border: 1px solid #333;
|
||||||
|
|
||||||
@ -152,57 +163,61 @@ a:visited {
|
|||||||
-ms-user-select: none;
|
-ms-user-select: none;
|
||||||
-khtml-user-select: none;
|
-khtml-user-select: none;
|
||||||
-webkit-user-select: none;
|
-webkit-user-select: none;
|
||||||
}
|
|
||||||
|
|
||||||
.a-link-button:hover {
|
&:hover {
|
||||||
background-color: #666;
|
background-color: #666;
|
||||||
}
|
}
|
||||||
|
|
||||||
.a-link-button:active {
|
&:active {
|
||||||
@include boxShadow(inset 0 1px 4px rgba(0, 0, 0, 0.6));
|
@include boxShadow(inset 0 1px 4px rgba(0, 0, 0, 0.6));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Make anchor tags ("a" elements) inactive (not clickable) */
|
/* Make anchor tags ("a" elements) inactive (not clickable) */
|
||||||
.a-link-button-inactive {
|
.a-link-button-inactive {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
background-color: #333;
|
background-color: #333;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
padding: 5px;
|
padding: 3px 5px;
|
||||||
margin: 5px;
|
margin: 5px;
|
||||||
border: 1px solid #333;
|
border: 1px solid #333;
|
||||||
cursor: default;
|
cursor: default;
|
||||||
}
|
|
||||||
|
|
||||||
.a-link-button-inactive:hover .tooltiptext,
|
&:hover {
|
||||||
.a-link-button-inactive:hover .tooltiptexthigh,
|
.tooltiptext,
|
||||||
.a-link-button-inactive:hover .tooltiptextleft {
|
.tooltiptexthigh,
|
||||||
|
.tooltiptextleft {
|
||||||
visibility: visible;
|
visibility: visible;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.a-link-button-inactive:active {
|
&:active {
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Make anchor tags ("a" elements) for activated actions */
|
/* Make anchor tags ("a" elements) for activated actions */
|
||||||
.a-link-button-bought {
|
.a-link-button-bought {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
background-color: #0a0;
|
background-color: #0a0;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
padding: 5px;
|
padding: 3px 5px;
|
||||||
margin: 5px;
|
margin: 5px;
|
||||||
border: 1px solid #0a0;
|
border: 1px solid #0a0;
|
||||||
cursor: default;
|
cursor: default;
|
||||||
}
|
|
||||||
|
|
||||||
.a-link-button-bought:hover .tooltiptext,
|
&:hover {
|
||||||
.a-link-button-bought:hover .tooltiptexthigh,
|
.tooltiptext,
|
||||||
.a-link-button-bought:hover .tooltiptextleft {
|
.tooltiptexthigh,
|
||||||
|
.tooltiptextleft {
|
||||||
visibility: visible;
|
visibility: visible;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.a-link-button-bought:active {
|
&:active {
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.dropdown {
|
.dropdown {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
@ -218,9 +233,9 @@ a:visited {
|
|||||||
#create-program-tab {
|
#create-program-tab {
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
#create-program-notification {
|
#create-program-notification {
|
||||||
font-size: $defaultFontSize * 0.625;
|
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;
|
||||||
right: 0;
|
right: 0;
|
||||||
@ -242,11 +257,10 @@ a:visited {
|
|||||||
|
|
||||||
/* Tool tips (when hovering over an element */
|
/* Tool tips (when hovering over an element */
|
||||||
.tooltip {
|
.tooltip {
|
||||||
position: relative;
|
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
position: relative;
|
||||||
|
|
||||||
.tooltip .tooltiptext {
|
.tooltiptext {
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
width: 300px;
|
width: 300px;
|
||||||
background-color: var(--my-background-color);
|
background-color: var(--my-background-color);
|
||||||
@ -256,9 +270,11 @@ a:visited {
|
|||||||
padding: 4px;
|
padding: 4px;
|
||||||
left: 101%;
|
left: 101%;
|
||||||
|
|
||||||
|
pointer-events: none;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 99;
|
z-index: 99;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Same thing as a normal tooltip except its a bit higher */
|
/* Same thing as a normal tooltip except its a bit higher */
|
||||||
.tooltip .tooltiptexthigh {
|
.tooltip .tooltiptexthigh {
|
||||||
@ -276,7 +292,7 @@ a:visited {
|
|||||||
z-index: 99;
|
z-index: 99;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Similar to a normal tooltip except its positioned on the left of the elemnt
|
/* Similar to a normal tooltip except its positioned on the left of the element
|
||||||
rather than the right to avoid exceeding the elements normal width */
|
rather than the right to avoid exceeding the elements normal width */
|
||||||
.tooltip .tooltiptextleft {
|
.tooltip .tooltiptextleft {
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
@ -437,47 +453,78 @@ a:visited {
|
|||||||
#character-overview-wrapper {
|
#character-overview-wrapper {
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
#character-overview-container {
|
#character-overview-container {
|
||||||
display: none;
|
display: none;
|
||||||
position: absolute; /* Stay in place */
|
position: absolute; /* Stay in place */
|
||||||
right: 0;
|
right: 0;
|
||||||
top: 0;
|
top: 0;
|
||||||
height: auto; /* Full height */
|
height: auto; /* Full height */
|
||||||
padding: 8px;
|
padding: 10px 2px;
|
||||||
border: 2px solid var(--my-highlight-color);
|
border: 2px solid var(--my-highlight-color);
|
||||||
width: 19%;
|
width: auto;
|
||||||
|
max-width: 280px;
|
||||||
overflow: auto; /* Enable scroll if needed */
|
overflow: auto; /* Enable scroll if needed */
|
||||||
background-color: #444; /* Fallback color */
|
background-color: rgba(57, 54, 54, 0.9); /* Fallback color */
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#character-overview-text {
|
#character-overview-text {
|
||||||
color: #fff;
|
color: $my-stat-physical;
|
||||||
background-color: #444;
|
|
||||||
|
table {
|
||||||
|
border-collapse: collapse;
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
td {
|
||||||
|
padding: 2px;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.character-stat-text {
|
.character-stat-text {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
background-color: #444;
|
background-color: #444;
|
||||||
}
|
}
|
||||||
|
|
||||||
.character-stat-cell {
|
.character-stat-cell {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#character-hack-wrapper td,
|
||||||
|
#character-agi-wrapper td {
|
||||||
|
border-bottom: 1px #aaa solid;
|
||||||
|
padding-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#character-str-wrapper td,
|
||||||
|
#character-cha-wrapper td {
|
||||||
|
padding-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#character-hp-wrapper { color: $my-stat-hp-color; }
|
||||||
|
#character-money-wrapper { color: $my-stat-money-color; }
|
||||||
|
#character-hack-wrapper { color: $my-stat-hack-color; }
|
||||||
|
#character-cha-wrapper { color: $my-stat-cha-color; }
|
||||||
|
#character-int-wrapper { color: $my-stat-int-color; }
|
||||||
|
|
||||||
#character-overview-save-button,
|
#character-overview-save-button,
|
||||||
#character-overview-options-button {
|
#character-overview-options-button {
|
||||||
@include borderRadius(12px);
|
@include borderRadius(12px);
|
||||||
@include boxShadow(1px 1px 3px #000);
|
@include boxShadow(1px 1px 3px #000);
|
||||||
|
color: #cecece;
|
||||||
color: #aaa;
|
display: inline-block;
|
||||||
font-size: $defaultFontSize * 0.875;
|
font-size: $defaultFontSize * 0.875;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
height: 22px;
|
height: 25px;
|
||||||
background-color: #000;
|
background-color: #000;
|
||||||
|
padding: 5px 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.character-quick-options {
|
.character-quick-options {
|
||||||
padding-top: 5px;
|
margin-top: 10px;
|
||||||
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
#character-overview-save-button:hover,
|
#character-overview-save-button:hover,
|
||||||
@ -489,19 +536,16 @@ a:visited {
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
#character-overview-options-button {
|
|
||||||
display: inline;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Scan analyze links from AutoLink */
|
/* Scan analyze links from AutoLink */
|
||||||
.scan-analyze-link {
|
.scan-analyze-link {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
|
||||||
.scan-analyze-link:hover {
|
&:hover {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Accordion menus (Header with collapsible panel) */
|
/* Accordion menus (Header with collapsible panel) */
|
||||||
.accordion-header {
|
.accordion-header {
|
||||||
@ -509,37 +553,37 @@ a:visited {
|
|||||||
font-size: $defaultFontSize * 1.25;
|
font-size: $defaultFontSize * 1.25;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
margin: 6px 6px 0 6px;
|
margin: 6px 6px 0 6px;
|
||||||
padding: 6px;
|
padding: 4px 6px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
width: 80%;
|
width: 80%;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
border: none;
|
border: none;
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
position: relative;
|
||||||
|
|
||||||
.accordion-header.active,
|
&.active,
|
||||||
.accordion-header:hover {
|
&:hover {
|
||||||
background-color: #555;
|
background-color: #555;
|
||||||
}
|
}
|
||||||
|
|
||||||
.accordion-header.active:hover {
|
&.active:hover {
|
||||||
background-color: #666;
|
background-color: #666;
|
||||||
}
|
}
|
||||||
|
|
||||||
.accordion-header:after {
|
&:after {
|
||||||
content: '\02795'; /* "plus" sign (+) */
|
content: '\02795'; /* "plus" sign (+) */
|
||||||
font-size: $defaultFontSize * 0.8125;
|
font-size: $defaultFontSize * 0.8125;
|
||||||
color: #fff;
|
|
||||||
float: right;
|
float: right;
|
||||||
margin-left: 5px;
|
color: transparent;
|
||||||
|
text-shadow: 0 0 0 #fff;
|
||||||
|
position: absolute;
|
||||||
|
bottom: 5px;
|
||||||
|
right: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.accordion-header.active:after {
|
&.active:after {
|
||||||
content: "\2796"; /* "minus" sign (-) */
|
content: "\2796"; /* "minus" sign (-) */
|
||||||
font-size: $defaultFontSize * 0.8125;
|
}
|
||||||
color: #fff;
|
|
||||||
float: right;
|
|
||||||
margin-left: 5px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.accordion-panel {
|
.accordion-panel {
|
||||||
@ -551,14 +595,11 @@ a:visited {
|
|||||||
background-color: #555;
|
background-color: #555;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
overflow-x: none;
|
overflow-x: none;
|
||||||
}
|
|
||||||
|
|
||||||
.accordion-panel div,
|
div, ul, p, ul > li {
|
||||||
.accordion-panel ul,
|
|
||||||
.accordion-panel p,
|
|
||||||
.accordion-panel ul > li {
|
|
||||||
background-color: #555;
|
background-color: #555;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* override the global <span> styling */
|
/* override the global <span> styling */
|
||||||
#active-scripts-total-production-active,
|
#active-scripts-total-production-active,
|
||||||
@ -567,3 +608,34 @@ a:visited {
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Helper Classes */
|
||||||
|
.hacker-green {
|
||||||
|
color: $hacker-green;
|
||||||
|
}
|
||||||
|
|
||||||
|
.money-gold {
|
||||||
|
color: $money-gold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.light-yellow {
|
||||||
|
color: $light-yellow;
|
||||||
|
}
|
||||||
|
|
||||||
|
.failure {
|
||||||
|
color: $alert-red;
|
||||||
|
text-shadow: 0 0 0 $alert-red;
|
||||||
|
}
|
||||||
|
|
||||||
|
.success {
|
||||||
|
color: $success-green;
|
||||||
|
text-shadow: 0 0 0 $success-green;
|
||||||
|
}
|
||||||
|
|
||||||
|
.physical-yellow {
|
||||||
|
color: $my-stat-physical;
|
||||||
|
}
|
||||||
|
|
||||||
|
.charisma-purple {
|
||||||
|
color: $my-stat-cha-color;
|
||||||
|
}
|
||||||
|
@ -19,6 +19,12 @@
|
|||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
background-color: var(--my-background-color);
|
background-color: var(--my-background-color);
|
||||||
table-layout: fixed;
|
table-layout: fixed;
|
||||||
|
|
||||||
|
.prompt {
|
||||||
|
color: var(--my-prompt-color);
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#terminal-input {
|
#terminal-input {
|
||||||
|
@ -3,9 +3,10 @@ Netscript Documentation
|
|||||||
Netscript is the programming language used in the world of Bitburner.
|
Netscript is the programming language used in the world of Bitburner.
|
||||||
|
|
||||||
When you write scripts in Bitburner, they are written in the Netscript language.
|
When you write scripts in Bitburner, they are written in the Netscript language.
|
||||||
Netscript is simply a tiny subset of Javascript. This means that Netscript's
|
Netscript is simply a subset of `JavaScript <https://developer.mozilla.org/en-US/docs/Web/JavaScript>`_,.
|
||||||
syntax is almost idental to Javascript's, but it does not implement many of the
|
This means that Netscript's syntax is
|
||||||
features that Javascript has.
|
identical to that of JavaScript, but it does not implement some of the features
|
||||||
|
that JavaScript has.
|
||||||
|
|
||||||
If you have any requests or suggestions to improve the Netscript language, feel free
|
If you have any requests or suggestions to improve the Netscript language, feel free
|
||||||
to reach out to the developer!
|
to reach out to the developer!
|
||||||
|
@ -2,14 +2,18 @@
|
|||||||
|
|
||||||
Netscript 1.0
|
Netscript 1.0
|
||||||
=============
|
=============
|
||||||
Netscript 1.0 is implemented using modified version of Neil Fraser's
|
Netscript 1.0 is implemented using a modified version of Neil Fraser's
|
||||||
`JS-Interpreter <https://github.com/NeilFraser/JS-Interpreter>`_.
|
`JS-Interpreter <https://github.com/NeilFraser/JS-Interpreter>`_.
|
||||||
|
|
||||||
This interpreter was created for ES5, which means that the code written
|
This is an ES5 JavaScript interpreter. This means that (almost) any JavaScript feature
|
||||||
for Netscript 1.0 must be compliant for that version. However, some additional
|
that is available in ES5 is also available in Netscript 1.0. However, this also means
|
||||||
ES6+ features are implemented through polyfills.
|
that the interpreter does not natively support any JavaScript features introduced in versions
|
||||||
|
ES6 or after.
|
||||||
|
|
||||||
Netscript 1.0 scripts end with the ".script" extension.
|
If you are confused by the ES5/ES6/etc. terminology, consider reading this:
|
||||||
|
`WTF is ES6, ES8, ES2017, ECMAScript... <https://codeburst.io/javascript-wtf-is-es6-es8-es-2017-ecmascript-dca859e4821c>`_
|
||||||
|
|
||||||
|
Netscript 1.0 scripts end with the ".script" extension in their filenames.
|
||||||
|
|
||||||
Which ES6+ features are supported?
|
Which ES6+ features are supported?
|
||||||
----------------------------------
|
----------------------------------
|
||||||
|
@ -772,6 +772,18 @@ write
|
|||||||
is set to "w", then the data is written in "write" mode which means that it will overwrite all existing data on the text file. If *mode* is set to
|
is set to "w", then the data is written in "write" mode which means that it will overwrite all existing data on the text file. If *mode* is set to
|
||||||
any other value then the data will be written in "append" mode which means that the data will be added at the end of the text file.
|
any other value then the data will be written in "append" mode which means that the data will be added at the end of the text file.
|
||||||
|
|
||||||
|
tryWrite
|
||||||
|
^^^^^^^^
|
||||||
|
|
||||||
|
.. js:function:: tryWrite(port, data="")
|
||||||
|
|
||||||
|
:param number port: Port to be written to
|
||||||
|
:param string data: Data to try to write
|
||||||
|
:returns: True if the data is successfully written to the port, and false otherwise
|
||||||
|
|
||||||
|
Attempts to write data to the specified Netscript Port. If the port is full, the data will
|
||||||
|
not be written. Otherwise, the data will be written normally
|
||||||
|
|
||||||
read
|
read
|
||||||
^^^^
|
^^^^
|
||||||
|
|
||||||
@ -813,6 +825,17 @@ clear
|
|||||||
|
|
||||||
If the *port/fn* argument is a string, then it specifies the name of a text file (.txt) and will delete all data from that text file.
|
If the *port/fn* argument is a string, then it specifies the name of a text file (.txt) and will delete all data from that text file.
|
||||||
|
|
||||||
|
getPortHandle
|
||||||
|
^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
.. js:function:: getPortHandle(port)
|
||||||
|
|
||||||
|
:param number port: Port number
|
||||||
|
|
||||||
|
Get a handle to a Netscript Port. See more details here: :ref:`netscript_ports`
|
||||||
|
|
||||||
|
**WARNING:** Port Handles only work in :ref:`netscriptjs`. They will not work in :ref:`netscript1`.
|
||||||
|
|
||||||
rm
|
rm
|
||||||
^^
|
^^
|
||||||
|
|
||||||
|
@ -1,9 +1,13 @@
|
|||||||
|
.. _netscript_misc:
|
||||||
|
|
||||||
Netscript Miscellaneous
|
Netscript Miscellaneous
|
||||||
=======================
|
=======================
|
||||||
|
|
||||||
|
.. _netscript_ports:
|
||||||
|
|
||||||
Netscript Ports
|
Netscript Ports
|
||||||
---------------
|
---------------
|
||||||
Netscript ports are endpoints that can be used to communicate between scripts.
|
Netscript Ports are endpoints that can be used to communicate between scripts.
|
||||||
A port is implemented as a sort of serialized queue, where you can only write
|
A port is implemented as a sort of serialized queue, where you can only write
|
||||||
and read one element at a time from the port. When you read data from a port,
|
and read one element at a time from the port. When you read data from a port,
|
||||||
the element that is read is removed from the port.
|
the element that is read is removed from the port.
|
||||||
@ -55,9 +59,11 @@ And the data in port 1 will look like::
|
|||||||
|
|
||||||
**Port Handles**
|
**Port Handles**
|
||||||
|
|
||||||
|
WARNING: Port Handles only work in :ref:`netscriptjs`. They do not work in :ref:`netscript1`
|
||||||
|
|
||||||
The :js:func:`getPortHandle` Netscript function can be used to get a handle to a Netscript Port.
|
The :js:func:`getPortHandle` Netscript function can be used to get a handle to a Netscript Port.
|
||||||
This handle allows you to access several new port-related functions and the
|
This handle allows you to access several new port-related functions and the
|
||||||
port's underlying data structure, which is just a Javascript array. The functions are:
|
port's underlying data structure, which is just a JavaScript array. The functions are:
|
||||||
|
|
||||||
.. js:method:: NetscriptPort.write(data)
|
.. js:method:: NetscriptPort.write(data)
|
||||||
|
|
||||||
|
@ -412,3 +412,18 @@ Then it could be removed using::
|
|||||||
$ unalias "r"
|
$ unalias "r"
|
||||||
|
|
||||||
It is not necessary to differentiate between global and non-global aliases when using 'unalias'
|
It is not necessary to differentiate between global and non-global aliases when using 'unalias'
|
||||||
|
|
||||||
|
wget
|
||||||
|
^^^^
|
||||||
|
|
||||||
|
$ wget [url] [target file]
|
||||||
|
|
||||||
|
Retrieves data from a url and downloads it to a file on the current server.
|
||||||
|
The data can only be downloaded to a script (.script, .ns, .js) or a text file
|
||||||
|
(.txt). If the target file already exists, it will be overwritten by this command.
|
||||||
|
|
||||||
|
Note that will not be possible to download data from many websites because they
|
||||||
|
do not allow cross-origin origin sharing (CORS). This includes websites such
|
||||||
|
as gist and pastebin. One notable site it will work on is rawgithub. Example::
|
||||||
|
|
||||||
|
$ wget https://raw.githubusercontent.com/danielyxie/bitburner/master/README.md game_readme.txt
|
||||||
|
57
index.html
57
index.html
@ -2,19 +2,17 @@
|
|||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>Bitburner</title>
|
<title>Bitburner - development</title>
|
||||||
<link rel="apple-touch-icon" sizes="180x180" href="dist/apple-touch-icon.png">
|
<link rel="apple-touch-icon" sizes="180x180" href="dist/apple-touch-icon.png">
|
||||||
<link rel="icon" type="image/png" sizes="32x32" href="dist/favicon-32x32.png">
|
<link rel="icon" type="image/png" sizes="32x32" href="dist/favicon-32x32.png">
|
||||||
<link rel="icon" type="image/png" sizes="16x16" href="dist/favicon-16x16.png">
|
<link rel="icon" type="image/png" sizes="16x16" href="dist/favicon-16x16.png">
|
||||||
<link rel="manifest" href="dist/site.webmanifest">
|
<link rel="manifest" href="dist/site.webmanifest">
|
||||||
<link rel="mask-icon" href="dist/safari-pinned-tab.svg" color="#000000">
|
<link rel="mask-icon" href="dist/safari-pinned-tab.svg" color="#000000">
|
||||||
<link rel="shortcut icon" href="favicon.ico">
|
|
||||||
<meta name="apple-mobile-web-app-title" content="Bitburner">
|
<meta name="apple-mobile-web-app-title" content="Bitburner">
|
||||||
<meta name="application-name" content="Bitburner">
|
<meta name="application-name" content="Bitburner">
|
||||||
<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="dist/engine.css" />
|
|
||||||
|
|
||||||
<!-- Google Analytics -->
|
<!-- Google Analytics -->
|
||||||
<script>
|
<script>
|
||||||
@ -22,11 +20,12 @@
|
|||||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||||||
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
|
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
|
||||||
|
</script>
|
||||||
|
<script>
|
||||||
ga('create', 'UA-100157497-1', 'auto');
|
ga('create', 'UA-100157497-1', 'auto');
|
||||||
ga('send', 'pageview');
|
ga('send', 'pageview');
|
||||||
</script>
|
</script>
|
||||||
</head>
|
<link rel="shortcut icon" href="favicon.ico"><link href="dist/engine.css" rel="stylesheet"></head>
|
||||||
<body>
|
<body>
|
||||||
<div id="entire-game-container" style="visibility:hidden;">
|
<div id="entire-game-container" style="visibility:hidden;">
|
||||||
<div id="mainmenu-container">
|
<div id="mainmenu-container">
|
||||||
@ -188,9 +187,9 @@
|
|||||||
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 of
|
<p id="active-scripts-total-prod">Total online production of
|
||||||
Active scripts: <span id="active-scripts-total-production-active">$0.000</span> / sec<br />
|
Active scripts: <span class="money-gold"><span id="active-scripts-total-production-active">$0.000</span> / sec</span><br />
|
||||||
Total online production since last Aug installation: <span id="active-scripts-total-prod-aug-total">$0.000</span>
|
Total online production since last Aug installation: <span id="active-scripts-total-prod-aug-total" class="money-gold">$0.000</span>
|
||||||
(<span id="active-scripts-total-prod-aug-avg">$0.000</span> / sec)</p>
|
(<span class="money-gold"><span id="active-scripts-total-prod-aug-avg" class="money-gold">$0.000</span> / sec</span>)</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>
|
||||||
@ -202,20 +201,20 @@
|
|||||||
The Hacknet is a global, decentralized network of machines. It is used by hackers all around
|
The Hacknet is a global, decentralized network of machines. It is used by hackers all around
|
||||||
the world to anonymously share computing power and perform distributed cyberattacks without the
|
the world to anonymously share computing power and perform distributed cyberattacks without the
|
||||||
fear of being traced.
|
fear of being traced.
|
||||||
<br><br>
|
<br /><br />
|
||||||
Here, you can purchase a Hacknet Node, a specialized machine that can connect and contribute its
|
Here, you can purchase a Hacknet Node, a specialized machine that can connect and contribute its
|
||||||
resources to the Hacknet network. This allows you to take a small percentage of profits
|
resources to the Hacknet network. This allows you to take a small percentage of profits
|
||||||
from hacks performed on the network. Essentially, you are renting out your Node's computing power.
|
from hacks performed on the network. Essentially, you are renting out your Node's computing power.
|
||||||
<br><br>
|
<br /><br />
|
||||||
Each Hacknet Node you purchase will passively earn you money. Each Hacknet Node can be upgraded
|
Each Hacknet Node you purchase will passively earn you money. Each Hacknet Node can be upgraded
|
||||||
in order to increase its computing power and thereby increase the profit you earn from it.
|
in order to increase its computing power and thereby increase the profit you earn from it.
|
||||||
</p>
|
</p>
|
||||||
<a id="hacknet-nodes-purchase-button" class="a-link-button"> Purchase Hacknet Node </a>
|
<a id="hacknet-nodes-purchase-button" class="a-link-button"> Purchase Hacknet Node </a>
|
||||||
<br>
|
<br />
|
||||||
<div id="hacknet-nodes-money-multipliers-div">
|
<div id="hacknet-nodes-money-multipliers-div">
|
||||||
<p id="hacknet-nodes-money">
|
<p id="hacknet-nodes-money">
|
||||||
<span>Money:</span><span id="hacknet-nodes-player-money"></span><br/>
|
<span>Money:</span><span id="hacknet-nodes-player-money" class="money-gold"></span><br />
|
||||||
<span>Total Hacknet Node Prodution:</span><span id="hacknet-nodes-total-production"></span>
|
<span>Total Hacknet Node Production:</span><span id="hacknet-nodes-total-production" class="money-gold"></span>
|
||||||
</p>
|
</p>
|
||||||
<span id="hacknet-nodes-multipliers">
|
<span id="hacknet-nodes-multipliers">
|
||||||
<a id="hacknet-nodes-1x-multiplier" class="a-link-button-inactive"> x1 </a>
|
<a id="hacknet-nodes-1x-multiplier" class="a-link-button-inactive"> x1 </a>
|
||||||
@ -452,7 +451,7 @@
|
|||||||
<div id="create-program-container" class="generic-menupage-container">
|
<div id="create-program-container" class="generic-menupage-container">
|
||||||
<p id="create-program-page-text">
|
<p id="create-program-page-text">
|
||||||
This page displays any programs that you are able to create. Writing the code for a program takes time, which
|
This page displays any programs that you are able to create. Writing the code for a program takes time, which
|
||||||
can vary based on how complex the program is. If you are working on creating on a program you can cancel
|
can vary based on how complex the program is. If you are working on creating a program you can cancel
|
||||||
at any time. Your progress will be saved and you can continue later.
|
at any time. Your progress will be saved and you can continue later.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
@ -625,9 +624,9 @@
|
|||||||
<!-- Slums -->
|
<!-- Slums -->
|
||||||
<p id="location-slums-description">
|
<p id="location-slums-description">
|
||||||
You have entered the Slums, a poverty-ridden district filled with gangs, criminals, and
|
You have entered the Slums, a poverty-ridden district filled with gangs, criminals, and
|
||||||
other shadowy entities. The city's government and police have neglected this area for years... <br><br><br>
|
other shadowy entities. The city's government and police have neglected this area for years...
|
||||||
|
<br /><br /><br />
|
||||||
In the Slums you can commit crimes to earn money and experience. Crime attempts are not always
|
In the Slums, you can commit crimes to earn money and experience. Crime attempts are not always
|
||||||
successful. Your chance at successfully committing a crime is determined by your stats.
|
successful. Your chance at successfully committing a crime is determined by your stats.
|
||||||
</p>
|
</p>
|
||||||
<a class="a-link-button tooltip" id="location-slums-shoplift"> Shoplift </a>
|
<a class="a-link-button tooltip" id="location-slums-shoplift"> Shoplift </a>
|
||||||
@ -673,7 +672,7 @@
|
|||||||
|
|
||||||
<div id="stock-market-container" class="generic-menupage-container">
|
<div id="stock-market-container" class="generic-menupage-container">
|
||||||
<p>
|
<p>
|
||||||
Welcome to the World Stock Exchange (WSE)! <br><br>
|
Welcome to the World Stock Exchange (WSE)! <br /><br />
|
||||||
|
|
||||||
To begin trading, you must first purchase an account. WSE accounts will persist
|
To begin trading, you must first purchase an account. WSE accounts will persist
|
||||||
after you 'reset' by installing Augmentations.
|
after you 'reset' by installing Augmentations.
|
||||||
@ -686,7 +685,7 @@
|
|||||||
TIX, short for Trade Information eXchange, is the communications protocol supported by the WSE.
|
TIX, short for Trade Information eXchange, is the communications protocol supported by the WSE.
|
||||||
Purchasing access to the TIX API lets you write code to create your own algorithmic/automated
|
Purchasing access to the TIX API lets you write code to create your own algorithmic/automated
|
||||||
trading strategies.
|
trading strategies.
|
||||||
<br><br>
|
<br /><br />
|
||||||
If you purchase access to the TIX API, you will retain that access even after
|
If you purchase access to the TIX API, you will retain that access even after
|
||||||
you 'reset' by installing Augmentations.
|
you 'reset' by installing Augmentations.
|
||||||
</p>
|
</p>
|
||||||
@ -696,7 +695,7 @@
|
|||||||
<p>
|
<p>
|
||||||
Four Sigma's (4S) Market Data Feed provides information about stocks
|
Four Sigma's (4S) Market Data Feed provides information about stocks
|
||||||
that will help your trading strategies.
|
that will help your trading strategies.
|
||||||
<br><br>
|
<br /><br />
|
||||||
If you purchase access to 4S Market Data and/or the 4S TIX API, you will
|
If you purchase access to 4S Market Data and/or the 4S TIX API, you will
|
||||||
retain that access even after you 'reset' by installing Augmentations.
|
retain that access even after you 'reset' by installing Augmentations.
|
||||||
</p>
|
</p>
|
||||||
@ -714,8 +713,8 @@
|
|||||||
<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>
|
||||||
<a id="stock-market-collapse-tickers" class="a-link-button tooltip">Collapse tickers</a>
|
<a id="stock-market-collapse-tickers" class="a-link-button tooltip">Collapse tickers</a>
|
||||||
<br><br>
|
<br /><br />
|
||||||
<input id="stock-market-watchlist-filter" type="text" placeholder="Filter Stocks by symbol (comma-separated list)"> </input>
|
<input id="stock-market-watchlist-filter" type="text" placeholder="Filter Stocks by symbol (comma-separated list)"/>
|
||||||
<a id="stock-market-watchlist-filter-update" class="a-link-button"> Update Watchlist </a>
|
<a id="stock-market-watchlist-filter-update" class="a-link-button"> Update Watchlist </a>
|
||||||
<ul id="stock-market-list" style="list-style:none;">
|
<ul id="stock-market-list" style="list-style:none;">
|
||||||
</ul>
|
</ul>
|
||||||
@ -756,7 +755,7 @@
|
|||||||
<p id="faction-invitation-box-text"> </p>
|
<p id="faction-invitation-box-text"> </p>
|
||||||
<p id="faction-invitation-box-message"> </p>
|
<p id="faction-invitation-box-message"> </p>
|
||||||
<p id="faction-invitation-box-warning">
|
<p id="faction-invitation-box-warning">
|
||||||
Would you like to join? <br> <br>
|
Would you like to join? <br /> <br />
|
||||||
Warning: Joining this faction may prevent you from joining other factions during this run!
|
Warning: Joining this faction may prevent you from joining other factions during this run!
|
||||||
</p>
|
</p>
|
||||||
<span id="faction-invitation-box-yes" class="popup-box-button"> Yes </span>
|
<span id="faction-invitation-box-yes" class="popup-box-button"> Yes </span>
|
||||||
@ -769,8 +768,8 @@
|
|||||||
<div id="infiltration-box-content" class="popup-box-content">
|
<div id="infiltration-box-content" class="popup-box-content">
|
||||||
<p id="infiltration-box-text"> </p>
|
<p id="infiltration-box-text"> </p>
|
||||||
|
|
||||||
<span id="infiltration-box-sell" class="a-link-button"> Sell on Black Market </span> <br><br>
|
<span id="infiltration-box-sell" class="a-link-button"> Sell on Black Market </span> <br /><br />
|
||||||
<select id="infiltration-faction-select"> </select> <br>
|
<select id="infiltration-faction-select"> </select> <br />
|
||||||
<span id="infiltration-box-faction" class="a-link-button"> Give to Faction for Reputation </span>
|
<span id="infiltration-box-faction" class="a-link-button"> Give to Faction for Reputation </span>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@ -856,7 +855,7 @@
|
|||||||
<div id="game-options-content" class="game-options-box">
|
<div id="game-options-content" class="game-options-box">
|
||||||
<span id="game-options-close-button">×</span>
|
<span id="game-options-close-button">×</span>
|
||||||
<h1> Game Options </h1>
|
<h1> Game Options </h1>
|
||||||
<br>
|
<br />
|
||||||
<div id="game-options-left-panel">
|
<div id="game-options-left-panel">
|
||||||
<!-- Netscript execution time -->
|
<!-- Netscript execution time -->
|
||||||
<fieldset>
|
<fieldset>
|
||||||
@ -1006,7 +1005,7 @@
|
|||||||
<a id="debug-soft-reset" class="a-link-button tooltip" style="display:block;width:46%;">
|
<a id="debug-soft-reset" class="a-link-button tooltip" style="display:block;width:46%;">
|
||||||
(DEBUG) Soft Reset
|
(DEBUG) Soft Reset
|
||||||
<span class="tooltiptext">
|
<span class="tooltiptext">
|
||||||
Perform a soft reset. Resets everything as if you had just purchased an Augmentation
|
Perform a soft reset. Resets everything as if you had just purchased an Augmentation.
|
||||||
</span>
|
</span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
@ -1019,7 +1018,5 @@
|
|||||||
<div class="loaderspinner"></div>
|
<div class="loaderspinner"></div>
|
||||||
<div class="loaderlabel">Loading Bitburner...</div>
|
<div class="loaderlabel">Loading Bitburner...</div>
|
||||||
</div>
|
</div>
|
||||||
<script src="dist/vendor.bundle.js"></script>
|
<script type="text/javascript" src="dist/vendor.bundle.js"></script><script type="text/javascript" src="dist/engine.bundle.js"></script></body>
|
||||||
<script src="dist/engine.bundle.js"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
</html>
|
||||||
|
316
package-lock.json
generated
316
package-lock.json
generated
@ -805,6 +805,12 @@
|
|||||||
"multicast-dns-service-types": "1.1.0"
|
"multicast-dns-service-types": "1.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"boolbase": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
|
||||||
|
"integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"boom": {
|
"boom": {
|
||||||
"version": "2.10.1",
|
"version": "2.10.1",
|
||||||
"resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz",
|
"resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz",
|
||||||
@ -1085,6 +1091,16 @@
|
|||||||
"integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=",
|
"integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"camel-case": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz",
|
||||||
|
"integrity": "sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"no-case": "2.3.2",
|
||||||
|
"upper-case": "1.1.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
"camelcase": {
|
"camelcase": {
|
||||||
"version": "1.2.1",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz",
|
||||||
@ -1684,6 +1700,23 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"clean-css": {
|
||||||
|
"version": "4.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.1.tgz",
|
||||||
|
"integrity": "sha512-4ZxI6dy4lrY6FHzfiy1aEOXgu4LIsW2MhwG0VBKdcoGoH/XLFgaHSdLTGr4O8Be6A8r3MOphEiI8Gc1n0ecf3g==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"source-map": "0.6.1"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"source-map": {
|
||||||
|
"version": "0.6.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||||
|
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
|
||||||
|
"dev": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"cli-cursor": {
|
"cli-cursor": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz",
|
||||||
@ -2186,6 +2219,30 @@
|
|||||||
"source-list-map": "2.0.0"
|
"source-list-map": "2.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"css-select": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz",
|
||||||
|
"integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"boolbase": "1.0.0",
|
||||||
|
"css-what": "2.1.0",
|
||||||
|
"domutils": "1.5.1",
|
||||||
|
"nth-check": "1.0.1"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"domutils": {
|
||||||
|
"version": "1.5.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz",
|
||||||
|
"integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"dom-serializer": "0.1.0",
|
||||||
|
"domelementtype": "1.3.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"css-selector-tokenizer": {
|
"css-selector-tokenizer": {
|
||||||
"version": "0.7.0",
|
"version": "0.7.0",
|
||||||
"resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.0.tgz",
|
"resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.0.tgz",
|
||||||
@ -2197,6 +2254,12 @@
|
|||||||
"regexpu-core": "1.0.0"
|
"regexpu-core": "1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"css-what": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.0.tgz",
|
||||||
|
"integrity": "sha1-lGfQMsOM+u+58teVASUwYvh/ob0=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"cssesc": {
|
"cssesc": {
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/cssesc/-/cssesc-0.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/cssesc/-/cssesc-0.1.0.tgz",
|
||||||
@ -2529,6 +2592,23 @@
|
|||||||
"esutils": "2.0.2"
|
"esutils": "2.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"dom-converter": {
|
||||||
|
"version": "0.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.1.4.tgz",
|
||||||
|
"integrity": "sha1-pF71cnuJDJv/5tfIduexnLDhfzs=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"utila": "0.3.3"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"utila": {
|
||||||
|
"version": "0.3.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/utila/-/utila-0.3.3.tgz",
|
||||||
|
"integrity": "sha1-1+jn1+MJEHCSsF+NloiCTWM6QiY=",
|
||||||
|
"dev": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"dom-serializer": {
|
"dom-serializer": {
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz",
|
||||||
@ -4795,12 +4875,86 @@
|
|||||||
"integrity": "sha1-DfKTUfByEWNRXfueVUPl9u7VFi8=",
|
"integrity": "sha1-DfKTUfByEWNRXfueVUPl9u7VFi8=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"html-minifier": {
|
||||||
|
"version": "3.5.20",
|
||||||
|
"resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-3.5.20.tgz",
|
||||||
|
"integrity": "sha512-ZmgNLaTp54+HFKkONyLFEfs5dd/ZOtlquKaTnqIWFmx3Av5zG6ZPcV2d0o9XM2fXOTxxIf6eDcwzFFotke/5zA==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"camel-case": "3.0.0",
|
||||||
|
"clean-css": "4.2.1",
|
||||||
|
"commander": "2.17.1",
|
||||||
|
"he": "1.1.1",
|
||||||
|
"param-case": "2.1.1",
|
||||||
|
"relateurl": "0.2.7",
|
||||||
|
"uglify-js": "3.4.8"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"commander": {
|
||||||
|
"version": "2.17.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz",
|
||||||
|
"integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"source-map": {
|
||||||
|
"version": "0.6.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||||
|
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"uglify-js": {
|
||||||
|
"version": "3.4.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.8.tgz",
|
||||||
|
"integrity": "sha512-WatYTD84gP/867bELqI2F/2xC9PQBETn/L+7RGq9MQOA/7yFBNvY1UwXqvtILeE6n0ITwBXxp34M0/o70dzj6A==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"commander": "2.17.1",
|
||||||
|
"source-map": "0.6.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"html-tags": {
|
"html-tags": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/html-tags/-/html-tags-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/html-tags/-/html-tags-2.0.0.tgz",
|
||||||
"integrity": "sha1-ELMKOGCF9Dzt41PMj6fLDe7qZos=",
|
"integrity": "sha1-ELMKOGCF9Dzt41PMj6fLDe7qZos=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"html-webpack-plugin": {
|
||||||
|
"version": "3.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-3.2.0.tgz",
|
||||||
|
"integrity": "sha1-sBq71yOsqqeze2r0SS69oD2d03s=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"html-minifier": "3.5.20",
|
||||||
|
"loader-utils": "0.2.17",
|
||||||
|
"lodash": "4.17.10",
|
||||||
|
"pretty-error": "2.1.1",
|
||||||
|
"tapable": "1.0.0",
|
||||||
|
"toposort": "1.0.7",
|
||||||
|
"util.promisify": "1.0.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"json5": {
|
||||||
|
"version": "0.5.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz",
|
||||||
|
"integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"loader-utils": {
|
||||||
|
"version": "0.2.17",
|
||||||
|
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.17.tgz",
|
||||||
|
"integrity": "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"big.js": "3.2.0",
|
||||||
|
"emojis-list": "2.1.0",
|
||||||
|
"json5": "0.5.1",
|
||||||
|
"object-assign": "4.1.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"htmlparser2": {
|
"htmlparser2": {
|
||||||
"version": "3.9.2",
|
"version": "3.9.2",
|
||||||
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.9.2.tgz",
|
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.9.2.tgz",
|
||||||
@ -6385,6 +6539,12 @@
|
|||||||
"signal-exit": "3.0.2"
|
"signal-exit": "3.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"lower-case": {
|
||||||
|
"version": "1.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz",
|
||||||
|
"integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"lru-cache": {
|
"lru-cache": {
|
||||||
"version": "4.1.1",
|
"version": "4.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz",
|
||||||
@ -7001,6 +7161,15 @@
|
|||||||
"integrity": "sha512-2NpiFHqC87y/zFke0fC0spBXL3bBsoh/p5H1EFhshxjCR5+0g2d6BiXbUFz9v1sAcxsk2htp2eQnNIci2dIYcA==",
|
"integrity": "sha512-2NpiFHqC87y/zFke0fC0spBXL3bBsoh/p5H1EFhshxjCR5+0g2d6BiXbUFz9v1sAcxsk2htp2eQnNIci2dIYcA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"no-case": {
|
||||||
|
"version": "2.3.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz",
|
||||||
|
"integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"lower-case": "1.1.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node-forge": {
|
"node-forge": {
|
||||||
"version": "0.7.5",
|
"version": "0.7.5",
|
||||||
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.7.5.tgz",
|
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.7.5.tgz",
|
||||||
@ -7608,6 +7777,15 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"nth-check": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.1.tgz",
|
||||||
|
"integrity": "sha1-mSms32KPwsQQmN6rgqxYDPFJquQ=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"boolbase": "1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"num2fraction": {
|
"num2fraction": {
|
||||||
"version": "1.2.2",
|
"version": "1.2.2",
|
||||||
"resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz",
|
||||||
@ -7731,6 +7909,16 @@
|
|||||||
"object-keys": "1.0.11"
|
"object-keys": "1.0.11"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"object.getownpropertydescriptors": {
|
||||||
|
"version": "2.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz",
|
||||||
|
"integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"define-properties": "1.1.2",
|
||||||
|
"es-abstract": "1.12.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"object.omit": {
|
"object.omit": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz",
|
||||||
@ -7931,6 +8119,15 @@
|
|||||||
"readable-stream": "2.3.4"
|
"readable-stream": "2.3.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"param-case": {
|
||||||
|
"version": "2.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz",
|
||||||
|
"integrity": "sha1-35T9jPZTHs915r75oIWPvHK+Ikc=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"no-case": "2.3.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"parse-asn1": {
|
"parse-asn1": {
|
||||||
"version": "5.1.1",
|
"version": "5.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.1.tgz",
|
||||||
@ -8984,6 +9181,16 @@
|
|||||||
"integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=",
|
"integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"pretty-error": {
|
||||||
|
"version": "2.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.1.tgz",
|
||||||
|
"integrity": "sha1-X0+HyPkeWuPzuoerTPXgOxoX8aM=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"renderkid": "2.0.1",
|
||||||
|
"utila": "0.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"process": {
|
"process": {
|
||||||
"version": "0.11.10",
|
"version": "0.11.10",
|
||||||
"resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
|
"resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
|
||||||
@ -9360,6 +9567,12 @@
|
|||||||
"jsesc": "0.5.0"
|
"jsesc": "0.5.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"relateurl": {
|
||||||
|
"version": "0.2.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz",
|
||||||
|
"integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"remark": {
|
"remark": {
|
||||||
"version": "9.0.0",
|
"version": "9.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/remark/-/remark-9.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/remark/-/remark-9.0.0.tgz",
|
||||||
@ -9422,6 +9635,81 @@
|
|||||||
"integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=",
|
"integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"renderkid": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.1.tgz",
|
||||||
|
"integrity": "sha1-iYyr/Ivt5Le5ETWj/9Mj5YwNsxk=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"css-select": "1.2.0",
|
||||||
|
"dom-converter": "0.1.4",
|
||||||
|
"htmlparser2": "3.3.0",
|
||||||
|
"strip-ansi": "3.0.1",
|
||||||
|
"utila": "0.3.3"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"domhandler": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.1.0.tgz",
|
||||||
|
"integrity": "sha1-0mRvXlf2w7qxHPbLBdPArPdBJZQ=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"domelementtype": "1.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"domutils": {
|
||||||
|
"version": "1.1.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/domutils/-/domutils-1.1.6.tgz",
|
||||||
|
"integrity": "sha1-vdw94Jm5ou+sxRxiPyj0FuzFdIU=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"domelementtype": "1.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"htmlparser2": {
|
||||||
|
"version": "3.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.3.0.tgz",
|
||||||
|
"integrity": "sha1-zHDQWln2VC5D8OaFyYLhTJJKnv4=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"domelementtype": "1.3.0",
|
||||||
|
"domhandler": "2.1.0",
|
||||||
|
"domutils": "1.1.6",
|
||||||
|
"readable-stream": "1.0.34"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"isarray": {
|
||||||
|
"version": "0.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
|
||||||
|
"integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"readable-stream": {
|
||||||
|
"version": "1.0.34",
|
||||||
|
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
|
||||||
|
"integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"core-util-is": "1.0.2",
|
||||||
|
"inherits": "2.0.3",
|
||||||
|
"isarray": "0.0.1",
|
||||||
|
"string_decoder": "0.10.31"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"string_decoder": {
|
||||||
|
"version": "0.10.31",
|
||||||
|
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
|
||||||
|
"integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"utila": {
|
||||||
|
"version": "0.3.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/utila/-/utila-0.3.3.tgz",
|
||||||
|
"integrity": "sha1-1+jn1+MJEHCSsF+NloiCTWM6QiY=",
|
||||||
|
"dev": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"repeat-element": {
|
"repeat-element": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz",
|
||||||
@ -11693,6 +11981,12 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"toposort": {
|
||||||
|
"version": "1.0.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/toposort/-/toposort-1.0.7.tgz",
|
||||||
|
"integrity": "sha1-LmhELZ9k7HILjMieZEOsbKqVACk=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"tough-cookie": {
|
"tough-cookie": {
|
||||||
"version": "2.3.3",
|
"version": "2.3.3",
|
||||||
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz",
|
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz",
|
||||||
@ -12232,6 +12526,12 @@
|
|||||||
"integrity": "sha512-d4SJySNBXDaQp+DPrziv3xGS6w3d2Xt69FijJr86zMPBy23JEloMCEOUBBzuN7xCtjLCnmB9tI/z7SBCahHBOw==",
|
"integrity": "sha512-d4SJySNBXDaQp+DPrziv3xGS6w3d2Xt69FijJr86zMPBy23JEloMCEOUBBzuN7xCtjLCnmB9tI/z7SBCahHBOw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"upper-case": {
|
||||||
|
"version": "1.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz",
|
||||||
|
"integrity": "sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"uri-js": {
|
"uri-js": {
|
||||||
"version": "4.2.2",
|
"version": "4.2.2",
|
||||||
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
|
||||||
@ -12377,6 +12677,22 @@
|
|||||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||||
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
|
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
|
||||||
},
|
},
|
||||||
|
"util.promisify": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"define-properties": "1.1.2",
|
||||||
|
"object.getownpropertydescriptors": "2.0.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"utila": {
|
||||||
|
"version": "0.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz",
|
||||||
|
"integrity": "sha1-ihagXURWV6Oupe7MWxKk+lN5dyw=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"utils-merge": {
|
"utils-merge": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
|
||||||
|
@ -46,6 +46,7 @@
|
|||||||
"eslint": "^4.19.1",
|
"eslint": "^4.19.1",
|
||||||
"eslint-plugin-node": "^6.0.1",
|
"eslint-plugin-node": "^6.0.1",
|
||||||
"file-loader": "^1.1.11",
|
"file-loader": "^1.1.11",
|
||||||
|
"html-webpack-plugin": "^3.2.0",
|
||||||
"i18n-webpack-plugin": "^1.0.0",
|
"i18n-webpack-plugin": "^1.0.0",
|
||||||
"istanbul": "^0.4.5",
|
"istanbul": "^0.4.5",
|
||||||
"js-beautify": "^1.5.10",
|
"js-beautify": "^1.5.10",
|
||||||
|
@ -44,9 +44,9 @@ var DifficultyToTimeFactor = 10; //Action Difficulty divided by this to ge
|
|||||||
var DiffMultExponentialFactor = 0.28;
|
var DiffMultExponentialFactor = 0.28;
|
||||||
var DiffMultLinearFactor = 650;
|
var DiffMultLinearFactor = 650;
|
||||||
|
|
||||||
var EffAgiLinearFactor = 90e3;
|
var EffAgiLinearFactor = 40e3;
|
||||||
var EffDexLinearFactor = 90e3;
|
var EffDexLinearFactor = 40e3;
|
||||||
var EffAgiExponentialFactor = 0.031;
|
var EffAgiExponentialFactor = 0.032;
|
||||||
var EffDexExponentialFactor = 0.03;
|
var EffDexExponentialFactor = 0.03;
|
||||||
|
|
||||||
var BaseRecruitmentTimeNeeded = 300; //Base time needed (s) to complete a Recruitment action
|
var BaseRecruitmentTimeNeeded = 300; //Base time needed (s) to complete a Recruitment action
|
||||||
@ -659,7 +659,7 @@ function Bladeburner(params={}) {
|
|||||||
|
|
||||||
this.storedCycles = 0;
|
this.storedCycles = 0;
|
||||||
|
|
||||||
this.randomEventCounter = getRandomInt(300, 600); //5-10 minutes
|
this.randomEventCounter = getRandomInt(240, 600); //4-10 minutes
|
||||||
|
|
||||||
//These times are in seconds
|
//These times are in seconds
|
||||||
this.actionTimeToComplete = 0; //0 or -1 is an infinite running action (like training)
|
this.actionTimeToComplete = 0; //0 or -1 is an infinite running action (like training)
|
||||||
@ -734,7 +734,7 @@ Bladeburner.prototype.create = function() {
|
|||||||
"whatever city you are currently in.",
|
"whatever city you are currently in.",
|
||||||
baseDifficulty:125,difficultyFac:1.02,rewardFac:1.041,
|
baseDifficulty:125,difficultyFac:1.02,rewardFac:1.041,
|
||||||
rankGain:0.3, hpLoss:0.5,
|
rankGain:0.3, hpLoss:0.5,
|
||||||
count:getRandomInt(100, 500), countGrowth:getRandomInt(5, 75)/10,
|
count:getRandomInt(25, 500), countGrowth:getRandomInt(5, 75)/10,
|
||||||
weights:{hack:0,str:0.05,def:0.05,dex:0.35,agi:0.35,cha:0.1, int:0.05},
|
weights:{hack:0,str:0.05,def:0.05,dex:0.35,agi:0.35,cha:0.1, int:0.05},
|
||||||
decays:{hack:0,str:0.91,def:0.91,dex:0.91,agi:0.91,cha:0.9, int:1},
|
decays:{hack:0,str:0.91,def:0.91,dex:0.91,agi:0.91,cha:0.9, int:1},
|
||||||
isStealth:true
|
isStealth:true
|
||||||
@ -746,7 +746,7 @@ Bladeburner.prototype.create = function() {
|
|||||||
"current city, and will also increase its chaos level.",
|
"current city, and will also increase its chaos level.",
|
||||||
baseDifficulty:250, difficultyFac:1.04,rewardFac:1.085,
|
baseDifficulty:250, difficultyFac:1.04,rewardFac:1.085,
|
||||||
rankGain:0.9, hpLoss:1,
|
rankGain:0.9, hpLoss:1,
|
||||||
count:getRandomInt(25, 750), countGrowth:getRandomInt(5, 75)/10,
|
count:getRandomInt(5, 500), countGrowth:getRandomInt(5, 75)/10,
|
||||||
weights:{hack:0,str:0.15,def:0.15,dex:0.25,agi:0.25,cha:0.1, int:0.1},
|
weights:{hack:0,str:0.15,def:0.15,dex:0.25,agi:0.25,cha:0.1, int:0.1},
|
||||||
decays:{hack:0,str:0.91,def:0.91,dex:0.91,agi:0.91,cha:0.8, int:0.9},
|
decays:{hack:0,str:0.91,def:0.91,dex:0.91,agi:0.91,cha:0.8, int:0.9},
|
||||||
isKill:true
|
isKill:true
|
||||||
@ -758,7 +758,7 @@ Bladeburner.prototype.create = function() {
|
|||||||
"city, and will also increase its chaos level.",
|
"city, and will also increase its chaos level.",
|
||||||
baseDifficulty:200, difficultyFac:1.03, rewardFac:1.065,
|
baseDifficulty:200, difficultyFac:1.03, rewardFac:1.065,
|
||||||
rankGain:0.6, hpLoss:1,
|
rankGain:0.6, hpLoss:1,
|
||||||
count:getRandomInt(50, 1000), countGrowth:getRandomInt(5,75)/10,
|
count:getRandomInt(5, 500), countGrowth:getRandomInt(5,75)/10,
|
||||||
weights:{hack:0,str:0.2,def:0.2,dex:0.2,agi:0.2,cha:0.1, int:0.1},
|
weights:{hack:0,str:0.2,def:0.2,dex:0.2,agi:0.2,cha:0.1, int:0.1},
|
||||||
decays:{hack:0,str:0.91,def:0.91,dex:0.91,agi:0.91,cha:0.8, int:0.9},
|
decays:{hack:0,str:0.91,def:0.91,dex:0.91,agi:0.91,cha:0.8, int:0.9},
|
||||||
isKill:true
|
isKill:true
|
||||||
@ -773,7 +773,7 @@ Bladeburner.prototype.create = function() {
|
|||||||
"You will NOT lose HP from failed Investigation ops.",
|
"You will NOT lose HP from failed Investigation ops.",
|
||||||
baseDifficulty:400, difficultyFac:1.03,rewardFac:1.07,reqdRank:25,
|
baseDifficulty:400, difficultyFac:1.03,rewardFac:1.07,reqdRank:25,
|
||||||
rankGain:2.2, rankLoss:0.2,
|
rankGain:2.2, rankLoss:0.2,
|
||||||
count:getRandomInt(50, 200), countGrowth:getRandomInt(10, 40)/10,
|
count:getRandomInt(1, 250), countGrowth:getRandomInt(10, 40)/10,
|
||||||
weights:{hack:0.25,str:0.05,def:0.05,dex:0.2,agi:0.1,cha:0.25, int:0.1},
|
weights:{hack:0.25,str:0.05,def:0.05,dex:0.2,agi:0.1,cha:0.25, int:0.1},
|
||||||
decays:{hack:0.85,str:0.9,def:0.9,dex:0.9,agi:0.9,cha:0.7, int:0.9},
|
decays:{hack:0.85,str:0.9,def:0.9,dex:0.9,agi:0.9,cha:0.7, int:0.9},
|
||||||
isStealth:true
|
isStealth:true
|
||||||
@ -786,7 +786,7 @@ Bladeburner.prototype.create = function() {
|
|||||||
"data.",
|
"data.",
|
||||||
baseDifficulty:500, difficultyFac:1.04, rewardFac:1.09, reqdRank:100,
|
baseDifficulty:500, difficultyFac:1.04, rewardFac:1.09, reqdRank:100,
|
||||||
rankGain:4.4, rankLoss:0.4, hpLoss:2,
|
rankGain:4.4, rankLoss:0.4, hpLoss:2,
|
||||||
count:getRandomInt(25, 300), countGrowth:getRandomInt(10, 40)/10,
|
count:getRandomInt(1, 250), countGrowth:getRandomInt(10, 40)/10,
|
||||||
weights:{hack:0.2,str:0.05,def:0.05,dex:0.2,agi:0.2,cha:0.2, int:0.1},
|
weights:{hack:0.2,str:0.05,def:0.05,dex:0.2,agi:0.2,cha:0.2, int:0.1},
|
||||||
decays:{hack:0.8,str:0.9,def:0.9,dex:0.9,agi:0.9,cha:0.7, int:0.9},
|
decays:{hack:0.8,str:0.9,def:0.9,dex:0.9,agi:0.9,cha:0.7, int:0.9},
|
||||||
isStealth:true
|
isStealth:true
|
||||||
@ -797,7 +797,7 @@ Bladeburner.prototype.create = function() {
|
|||||||
"notorious Synthoid criminals.",
|
"notorious Synthoid criminals.",
|
||||||
baseDifficulty:650, difficultyFac:1.04, rewardFac:1.095, reqdRank:500,
|
baseDifficulty:650, difficultyFac:1.04, rewardFac:1.095, reqdRank:500,
|
||||||
rankGain:5.5, rankLoss:0.5, hpLoss:2.5,
|
rankGain:5.5, rankLoss:0.5, hpLoss:2.5,
|
||||||
count:getRandomInt(25,400), countGrowth:getRandomInt(3, 40)/10,
|
count:getRandomInt(1, 300), countGrowth:getRandomInt(3, 40)/10,
|
||||||
weights:{hack:0.25,str:0.05,def:0.05,dex:0.25,agi:0.1,cha:0.2, int:0.1},
|
weights:{hack:0.25,str:0.05,def:0.05,dex:0.25,agi:0.1,cha:0.2, int:0.1},
|
||||||
decays:{hack:0.8,str:0.85,def:0.85,dex:0.85,agi:0.85,cha:0.7, int:0.9},
|
decays:{hack:0.8,str:0.85,def:0.85,dex:0.85,agi:0.85,cha:0.7, int:0.9},
|
||||||
isStealth:true
|
isStealth:true
|
||||||
@ -809,7 +809,7 @@ Bladeburner.prototype.create = function() {
|
|||||||
"in order for this Operation to be successful",
|
"in order for this Operation to be successful",
|
||||||
baseDifficulty:800, difficultyFac:1.045, rewardFac:1.1, reqdRank:3000,
|
baseDifficulty:800, difficultyFac:1.045, rewardFac:1.1, reqdRank:3000,
|
||||||
rankGain:55,rankLoss:2.5,hpLoss:50,
|
rankGain:55,rankLoss:2.5,hpLoss:50,
|
||||||
count:getRandomInt(25, 150), countGrowth:getRandomInt(2, 40)/10,
|
count:getRandomInt(1, 200), countGrowth:getRandomInt(2, 40)/10,
|
||||||
weights:{hack:0.1,str:0.2,def:0.2,dex:0.2,agi:0.2,cha:0, int:0.1},
|
weights:{hack:0.1,str:0.2,def:0.2,dex:0.2,agi:0.2,cha:0, int:0.1},
|
||||||
decays:{hack:0.7,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.9},
|
decays:{hack:0.7,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.9},
|
||||||
isKill:true
|
isKill:true
|
||||||
@ -821,7 +821,7 @@ Bladeburner.prototype.create = function() {
|
|||||||
"drawing any attention. Stealth and discretion are key.",
|
"drawing any attention. Stealth and discretion are key.",
|
||||||
baseDifficulty:1000, difficultyFac:1.05, rewardFac:1.11, reqdRank:20e3,
|
baseDifficulty:1000, difficultyFac:1.05, rewardFac:1.11, reqdRank:20e3,
|
||||||
rankGain:22, rankLoss:2, hpLoss:10,
|
rankGain:22, rankLoss:2, hpLoss:10,
|
||||||
count:getRandomInt(25, 250), countGrowth:getRandomInt(1, 20)/10,
|
count:getRandomInt(1, 250), countGrowth:getRandomInt(1, 20)/10,
|
||||||
weights:{hack:0.1,str:0.1,def:0.1,dex:0.3,agi:0.3,cha:0, int:0.1},
|
weights:{hack:0.1,str:0.1,def:0.1,dex:0.3,agi:0.3,cha:0, int:0.1},
|
||||||
decays:{hack:0.7,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.9},
|
decays:{hack:0.7,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.9},
|
||||||
isStealth:true, isKill:true
|
isStealth:true, isKill:true
|
||||||
@ -833,7 +833,7 @@ Bladeburner.prototype.create = function() {
|
|||||||
"in the Synthoid communities.",
|
"in the Synthoid communities.",
|
||||||
baseDifficulty:1500, difficultyFac:1.06, rewardFac:1.14, reqdRank:50e3,
|
baseDifficulty:1500, difficultyFac:1.06, rewardFac:1.14, reqdRank:50e3,
|
||||||
rankGain:44, rankLoss:4, hpLoss:5,
|
rankGain:44, rankLoss:4, hpLoss:5,
|
||||||
count:getRandomInt(25, 200), countGrowth:getRandomInt(1, 20)/10,
|
count:getRandomInt(1, 200), countGrowth:getRandomInt(1, 20)/10,
|
||||||
weights:{hack:0.1,str:0.1,def:0.1,dex:0.3,agi:0.3,cha:0, int:0.1},
|
weights:{hack:0.1,str:0.1,def:0.1,dex:0.3,agi:0.3,cha:0, int:0.1},
|
||||||
decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.8},
|
decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.8},
|
||||||
isStealth:true, isKill:true
|
isStealth:true, isKill:true
|
||||||
@ -900,7 +900,7 @@ Bladeburner.prototype.process = function() {
|
|||||||
this.randomEventCounter -= seconds;
|
this.randomEventCounter -= seconds;
|
||||||
if (this.randomEventCounter <= 0) {
|
if (this.randomEventCounter <= 0) {
|
||||||
this.randomEvent();
|
this.randomEvent();
|
||||||
this.randomEventCounter = getRandomInt(300, 600);
|
this.randomEventCounter = getRandomInt(240, 600);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.processAction(seconds);
|
this.processAction(seconds);
|
||||||
@ -3703,7 +3703,7 @@ function initBladeburner() {
|
|||||||
name:SkillNames.Overclock,
|
name:SkillNames.Overclock,
|
||||||
desc:"Each level of this skill decreases the time it takes " +
|
desc:"Each level of this skill decreases the time it takes " +
|
||||||
"to attempt a Contract, Operation, and BlackOp by 1% (Max Level: 95)",
|
"to attempt a Contract, Operation, and BlackOp by 1% (Max Level: 95)",
|
||||||
baseCost:5, costInc:1, maxLvl:95,
|
baseCost:5, costInc:1.1, maxLvl:95,
|
||||||
actionTime:1
|
actionTime:1
|
||||||
});
|
});
|
||||||
Skills[SkillNames.EvasiveSystem] = new Skill({
|
Skills[SkillNames.EvasiveSystem] = new Skill({
|
||||||
|
@ -6,6 +6,9 @@ let CONSTANTS = {
|
|||||||
//the player will have this level assuming no multipliers. Multipliers can cause skills to go above this.
|
//the player will have this level assuming no multipliers. Multipliers can cause skills to go above this.
|
||||||
MaxSkillLevel: 975,
|
MaxSkillLevel: 975,
|
||||||
|
|
||||||
|
//Milliseconds per game cycle
|
||||||
|
MilliPerCycle: 200,
|
||||||
|
|
||||||
//How much reputation is needed to join a megacorporation's faction
|
//How much reputation is needed to join a megacorporation's faction
|
||||||
CorpFactionRepRequirement: 200e3,
|
CorpFactionRepRequirement: 200e3,
|
||||||
|
|
||||||
@ -493,9 +496,24 @@ let CONSTANTS = {
|
|||||||
"World Stock Exchange account and TIX API Access<br>",
|
"World Stock Exchange account and TIX API Access<br>",
|
||||||
|
|
||||||
LatestUpdate:
|
LatestUpdate:
|
||||||
"v0.40.3<br>" +
|
`v0.40.3<br>
|
||||||
"* Added a setting in .fconf for enabling line-wrap in the Terminal input<br>"
|
-----------------------------------------------<br>
|
||||||
|
* Bladeburner Changes:<br>
|
||||||
|
*** Increased the effect that agi and dexterity have on action time<br>
|
||||||
|
*** Starting number of contracts/operations available will be slightly lower<br>
|
||||||
|
*** Random events will now happen slightly more often<br>
|
||||||
|
*** Slightly increased the rate at which the Overclock skill point cost increases<br>
|
||||||
|
-----------------------------------------------<br>
|
||||||
|
* The maximum volatility of stocks is now randomized (randomly generated within a certain range every time the game resets)<br>
|
||||||
|
* Increased the range of possible values for initial stock prices<br>
|
||||||
|
* b1t_flum3.exe program can now be created immediately at Hacking level 1 (rather than hacking level 5)<br>
|
||||||
|
* UI improvements for the character overview panel and the left-hand menu (by mat-jaworski)<br>
|
||||||
|
* Updated documentation to reflect the fact that Netscript port handles (getPortHandle()) only works in NetscriptJS (2.0), NOT Netscript 1.0<br>
|
||||||
|
* Added tryWrite() Netscript function<br>
|
||||||
|
* When working (for a company/faction), experience is gained immediately/continuously rather than all at once when the work is finished<br>
|
||||||
|
* Added a setting in .fconf for enabling line-wrap in the Terminal input<br>
|
||||||
|
* Added 'wget' Terminal command<br>
|
||||||
|
* Improved the introductory tutorial`
|
||||||
}
|
}
|
||||||
|
|
||||||
export {CONSTANTS};
|
export {CONSTANTS};
|
||||||
|
@ -83,9 +83,9 @@ const Programs = {
|
|||||||
time: CONSTANTS.MillisecondsPerQuarterHour,
|
time: CONSTANTS.MillisecondsPerQuarterHour,
|
||||||
}),
|
}),
|
||||||
BitFlume: new Program("b1t_flum3.exe", {
|
BitFlume: new Program("b1t_flum3.exe", {
|
||||||
level: 5,
|
level: 1,
|
||||||
tooltip:"This program creates a portal to the BitNode Nexus (allows you to restart and switch BitNodes)",
|
tooltip:"This program creates a portal to the BitNode Nexus (allows you to restart and switch BitNodes)",
|
||||||
req: function() {return Player.sourceFiles.length > 0 && Player.hacking_skill >= 5},
|
req: function() {return Player.sourceFiles.length > 0 && Player.hacking_skill >= 1},
|
||||||
time: CONSTANTS.MillisecondsPerFiveMinutes / 5,
|
time: CONSTANTS.MillisecondsPerFiveMinutes / 5,
|
||||||
}),
|
}),
|
||||||
// special because you can't create it.
|
// special because you can't create it.
|
||||||
|
@ -66,26 +66,43 @@ class FactionInfo {
|
|||||||
export const FactionInfos: IMap<FactionInfo> = {
|
export const FactionInfos: IMap<FactionInfo> = {
|
||||||
// Endgame
|
// Endgame
|
||||||
Illuminati: new FactionInfo(
|
Illuminati: new FactionInfo(
|
||||||
"Humanity never changes. No matter how civilized society becomes, it will eventually fall back into chaos. And " +
|
"Humanity never changes. No matter how civilized society becomes, it will eventually fall back into chaos. " +
|
||||||
"from this chaos, we are the Invisible hand that guides them to order.",
|
"And from this chaos, we are the Invisible hand that guides them to order. ",
|
||||||
[], true, true, true, false),
|
[],
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
false),
|
||||||
|
|
||||||
Daedalus: new FactionInfo(
|
Daedalus: new FactionInfo(
|
||||||
"Yesterday we obeyed kings and bent our necks to emperors. Today we kneel only to truth.",
|
"Yesterday we obeyed kings and bent our necks to emperors. Today we kneel only to truth.",
|
||||||
[], true, true, true, false),
|
[],
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
false),
|
||||||
|
|
||||||
"The Covenant": new FactionInfo(
|
"The Covenant": new FactionInfo(
|
||||||
"Surrender yourself. Give up your empty individuality to become part of something great, something eternal. " +
|
"Surrender yourself. Give up your empty individuality to become part of something great, something eternal. " +
|
||||||
"Become a slave. Submit your mind, body, and soul. Only then can you set yourself free.<br>" +
|
"Become a slave. Submit your mind, body, and soul. Only then can you set yourself free.<br>" +
|
||||||
"<br>" +
|
"<br>" +
|
||||||
"Only then can you discover immortality.",
|
"Only then can you discover immortality.",
|
||||||
[], true, true, true, false),
|
[],
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
false),
|
||||||
|
|
||||||
// Megacorporations, each forms its own faction
|
// Megacorporations, each forms its own faction
|
||||||
ECorp: new FactionInfo(
|
ECorp: new FactionInfo(
|
||||||
"ECorp's mission is simple: to connect the world of today with the technology of tomorrow. With our wide range " +
|
"ECorp's mission is simple: to connect the world of today with the technology of tomorrow. With our wide " +
|
||||||
"of Internet-related software and commercial hardware, ECorp makes the world's information universally accessible.",
|
"range of Internet-related software and commercial hardware, ECorp makes the world's information " +
|
||||||
[], true, true, true, true),
|
"universally accessible.",
|
||||||
|
[],
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true),
|
||||||
|
|
||||||
MegaCorp: new FactionInfo(
|
MegaCorp: new FactionInfo(
|
||||||
"MegaCorp does things that others don't. We imagine. We create. We invent. We build things that others have " +
|
"MegaCorp does things that others don't. We imagine. We create. We invent. We build things that others have " +
|
||||||
@ -93,66 +110,110 @@ export const FactionInfos: IMap<FactionInfo> = {
|
|||||||
"unprecendented scale, in ways that no other company can.<br>" +
|
"unprecendented scale, in ways that no other company can.<br>" +
|
||||||
"<br>" +
|
"<br>" +
|
||||||
"In our labs and factories and on the ground with customers, MegaCorp is ushering in a new era for the world.",
|
"In our labs and factories and on the ground with customers, MegaCorp is ushering in a new era for the world.",
|
||||||
[], true, true, true, true),
|
[],
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true),
|
||||||
|
|
||||||
"Bachman & Associates": new FactionInfo(
|
"Bachman & Associates": new FactionInfo(
|
||||||
"Where Law and Business meet - thats where we are.<br>" +
|
"Where Law and Business meet - thats where we are.<br>" +
|
||||||
"<br>" +
|
"<br>" +
|
||||||
"Legal Insight - Business Instinct - Experience Innovation",
|
"Legal Insight - Business Instinct - Experience Innovation",
|
||||||
[], true, true, true, true),
|
[],
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true),
|
||||||
|
|
||||||
"Blade Industries": new FactionInfo(
|
"Blade Industries": new FactionInfo(
|
||||||
"Augmentation is salvation",
|
"Augmentation is salvation",
|
||||||
[], true, true, true, true),
|
[],
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true),
|
||||||
|
|
||||||
NWO: new FactionInfo(
|
NWO: new FactionInfo(
|
||||||
"The human being does not truly desire freedom. It wants to be observed, understood, and judged. It wants to be " +
|
"The human being does not truly desire freedom. It wants to be observed, understood, and judged. It wants to " +
|
||||||
"given purpose and direction in its life. That is why humans created God. And that is why humans created " +
|
"be given purpose and direction in its life. That is why humans created God. And that is why humans created " +
|
||||||
"civilization - not because of willingness, but because of a need to be incorporated into higher orders of " +
|
"civilization - not because of willingness, but because of a need to be incorporated into higher orders of " +
|
||||||
"structure and meaning.",
|
"structure and meaning.",
|
||||||
[], true, true, true, true),
|
[],
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true),
|
||||||
|
|
||||||
"Clarke Incorporated": new FactionInfo(
|
"Clarke Incorporated": new FactionInfo(
|
||||||
"Unlocking the power of the genome",
|
"Unlocking the power of the genome",
|
||||||
[], true, true, true, true),
|
[],
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true),
|
||||||
|
|
||||||
"OmniTek Incorporated": new FactionInfo(
|
"OmniTek Incorporated": new FactionInfo(
|
||||||
"Simply put, our mission is to design and build robots that make a difference",
|
"Simply put, our mission is to design and build robots that make a difference",
|
||||||
[], true, true, true, true),
|
[],
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true),
|
||||||
|
|
||||||
"Four Sigma": new FactionInfo(
|
"Four Sigma": new FactionInfo(
|
||||||
"The scientific method is the best way to approach investing. Big strategies backed up with big data. Driven by " +
|
"The scientific method is the best way to approach investing. Big strategies backed up with big data. Driven " +
|
||||||
"deep learning and innovative ideas. And improved by iteration. That's Four Sigma.",
|
"by deep learning and innovative ideas. And improved by iteration. That's Four Sigma.",
|
||||||
[], true, true, true, true),
|
[],
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true),
|
||||||
|
|
||||||
"KuaiGong International": new FactionInfo(
|
"KuaiGong International": new FactionInfo(
|
||||||
"Dream big. Work hard. Make history.",
|
"Dream big. Work hard. Make history.",
|
||||||
[], true, true, true, true),
|
[],
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true),
|
||||||
|
|
||||||
// Other Corporations
|
// Other Corporations
|
||||||
"Fulcrum Secret Technologies": new FactionInfo(
|
"Fulcrum Secret Technologies": new FactionInfo(
|
||||||
"The human organism has an innate desire to worship. That is why they created gods. If there were no gods, it " +
|
"The human organism has an innate desire to worship. That is why they created gods. If there were no gods, it " +
|
||||||
"would be necessary to create them. And now we can.",
|
"would be necessary to create them. And now we can.",
|
||||||
[], true, true, false, true),
|
[],
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
true),
|
||||||
|
|
||||||
// Hacker groups
|
// Hacker groups
|
||||||
BitRunners: new FactionInfo(
|
BitRunners: new FactionInfo(
|
||||||
"Our entire lives are controlled by bits. All of our actions, our thoughts, our personal information. It's all " +
|
"Our entire lives are controlled by bits. All of our actions, our thoughts, our personal information. It's " +
|
||||||
"transformed into bits, stored in bits, communicated through bits. It’s impossible for any person to move, to " +
|
"all transformed into bits, stored in bits, communicated through bits. It’s impossible for any person to move, " +
|
||||||
"live, to operate at any level without the use of bits. And when a person moves, lives, and operates, they leave " +
|
"to live, to operate at any level without the use of bits. And when a person moves, lives, and operates, they " +
|
||||||
"behind their bits, mere traces of seemingly meaningless fragments of information. But these bits can be " +
|
"leave behind their bits, mere traces of seemingly meaningless fragments of information. But these bits can be " +
|
||||||
"reconstructed. Transformed. Used.<br>" +
|
"reconstructed. Transformed. Used.<br>" +
|
||||||
"<br>" +
|
"<br>" +
|
||||||
"Those who run the bits, run the world",
|
"Those who run the bits, run the world",
|
||||||
[], true, true, false, false),
|
[],
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
false),
|
||||||
|
|
||||||
"The Black Hand": new FactionInfo(
|
"The Black Hand": new FactionInfo(
|
||||||
"The world, so afraid of strong government, now has no government. Only power - Digital power. Financial power. " +
|
"The world, so afraid of strong government, now has no government. Only power - Digital power. Financial " +
|
||||||
"Technological power. And those at the top rule with an invisible hand. They built a society where the rich get " +
|
"power. Technological power. And those at the top rule with an invisible hand. They built a society where the " +
|
||||||
"richer, and everyone else suffers.<br>" +
|
"rich get richer, and everyone else suffers.<br>" +
|
||||||
"<br>" +
|
"<br>" +
|
||||||
"So much pain. So many lives. Their darkness must end.",
|
"So much pain. So many lives. Their darkness must end.",
|
||||||
[], true, true, true, false),
|
[],
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
false),
|
||||||
|
|
||||||
NiteSec: new FactionInfo(
|
NiteSec: new FactionInfo(
|
||||||
" __..__ <br>" +
|
" __..__ <br>" +
|
||||||
@ -190,40 +251,108 @@ export const FactionInfos: IMap<FactionInfo> = {
|
|||||||
" d .dNITESEC $ | <br>" +
|
" d .dNITESEC $ | <br>" +
|
||||||
" :bp.__.gNITESEC$$ :$ ; <br>" +
|
" :bp.__.gNITESEC$$ :$ ; <br>" +
|
||||||
" NITESECNITESECNIT $$b : <br>",
|
" NITESECNITESECNIT $$b : <br>",
|
||||||
[], true, true, false, false),
|
[],
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
false),
|
||||||
|
|
||||||
// City factions, essentially governments
|
// City factions, essentially governments
|
||||||
Aevum: new FactionInfo(
|
Aevum: new FactionInfo(
|
||||||
"The Silicon City",
|
"The Silicon City",
|
||||||
["Chongqing", "New Tokyo", "Ishima", "Volhaven"], true, true, true, true),
|
[
|
||||||
|
"Chongqing",
|
||||||
|
"New Tokyo",
|
||||||
|
"Ishima",
|
||||||
|
"Volhaven",
|
||||||
|
],
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true),
|
||||||
Chongqing: new FactionInfo(
|
Chongqing: new FactionInfo(
|
||||||
"Serve the people",
|
"Serve the people",
|
||||||
["Sector-12", "Aevum", "Volhaven"], true, true, true, true),
|
[
|
||||||
|
"Sector-12",
|
||||||
|
"Aevum",
|
||||||
|
"Volhaven",
|
||||||
|
],
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true),
|
||||||
Ishima: new FactionInfo(
|
Ishima: new FactionInfo(
|
||||||
"The East Asian Order of the Future",
|
"The East Asian Order of the Future",
|
||||||
["Sector-12", "Aevum", "Volhaven"], true, true, true, true),
|
[
|
||||||
|
"Sector-12",
|
||||||
|
"Aevum",
|
||||||
|
"Volhaven",
|
||||||
|
],
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true),
|
||||||
"New Tokyo": new FactionInfo(
|
"New Tokyo": new FactionInfo(
|
||||||
"Asia's World City",
|
"Asia's World City",
|
||||||
["Sector-12", "Aevum", "Volhaven"], true, true, true, true),
|
[
|
||||||
|
"Sector-12",
|
||||||
|
"Aevum",
|
||||||
|
"Volhaven",
|
||||||
|
],
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true),
|
||||||
"Sector-12": new FactionInfo(
|
"Sector-12": new FactionInfo(
|
||||||
"The City of the Future",
|
"The City of the Future",
|
||||||
["Chongqing", "New Tokyo", "Ishima", "Volhaven"], true, true, true, true),
|
[
|
||||||
|
"Chongqing",
|
||||||
|
"New Tokyo",
|
||||||
|
"Ishima",
|
||||||
|
"Volhaven",
|
||||||
|
],
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true),
|
||||||
Volhaven: new FactionInfo(
|
Volhaven: new FactionInfo(
|
||||||
"Benefit, Honour, and Glory",
|
"Benefit, Honour, and Glory",
|
||||||
["Chongqing", "Sector-12", "New Tokyo", "Aevum", "Ishima"], true, true, true, true),
|
[
|
||||||
|
"Chongqing",
|
||||||
|
"Sector-12",
|
||||||
|
"New Tokyo",
|
||||||
|
"Aevum",
|
||||||
|
"Ishima",
|
||||||
|
],
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true),
|
||||||
|
|
||||||
// Criminal Organizations/Gangs
|
// Criminal Organizations/Gangs
|
||||||
"Speakers for the Dead": new FactionInfo(
|
"Speakers for the Dead": new FactionInfo(
|
||||||
"It is better to reign in hell than to serve in heaven.",
|
"It is better to reign in hell than to serve in heaven.",
|
||||||
[], true, true, true, true),
|
[],
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true),
|
||||||
|
|
||||||
"The Dark Army": new FactionInfo(
|
"The Dark Army": new FactionInfo(
|
||||||
"The World doesn't care about right or wrong. It's all about power.",
|
"The World doesn't care about right or wrong. It's all about power.",
|
||||||
[], true, true, true, false),
|
[],
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
false),
|
||||||
|
|
||||||
"The Syndicate": new FactionInfo(
|
"The Syndicate": new FactionInfo(
|
||||||
"Honor holds you back",
|
"Honor holds you back",
|
||||||
[], true, true, true, true),
|
[],
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true),
|
||||||
|
|
||||||
Silhouette: new FactionInfo(
|
Silhouette: new FactionInfo(
|
||||||
"Corporations have filled the void of power left behind by the collapse of Western government. The issue is " +
|
"Corporations have filled the void of power left behind by the collapse of Western government. The issue is " +
|
||||||
@ -231,35 +360,64 @@ export const FactionInfos: IMap<FactionInfo> = {
|
|||||||
"corporations, you don't even know who you're working for.<br>" +
|
"corporations, you don't even know who you're working for.<br>" +
|
||||||
"<br>" +
|
"<br>" +
|
||||||
"That's terror. Terror, fear, and corruption. All born into the system, all propagated by the system.",
|
"That's terror. Terror, fear, and corruption. All born into the system, all propagated by the system.",
|
||||||
[], true, true, true, false),
|
[],
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
false),
|
||||||
|
|
||||||
Tetrads: new FactionInfo(
|
Tetrads: new FactionInfo(
|
||||||
"Following the Mandate of Heaven and Carrying out the Way",
|
"Following the Mandate of Heaven and Carrying out the Way",
|
||||||
[], false, false, true, true),
|
[],
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
true),
|
||||||
|
|
||||||
"Slum Snakes": new FactionInfo(
|
"Slum Snakes": new FactionInfo(
|
||||||
"Slum Snakes rule!",
|
"Slum Snakes rule!",
|
||||||
[], false, false, true, true),
|
[],
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
true),
|
||||||
|
|
||||||
// Earlygame factions - factions the player will prestige with early on that don't belong in other categories.
|
// Earlygame factions - factions the player will prestige with early on that don't belong in other categories.
|
||||||
Netburners: new FactionInfo(
|
Netburners: new FactionInfo(
|
||||||
"~~//*>H4CK|\|3T 8URN3R5**>?>\\~~",
|
"~~//*>H4CK|\|3T 8URN3R5**>?>\\~~",
|
||||||
[], true, true, false, false),
|
[],
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
false),
|
||||||
|
|
||||||
"Tian Di Hui": new FactionInfo(
|
"Tian Di Hui": new FactionInfo(
|
||||||
"Obey Heaven and Work Righteousness",
|
"Obey Heaven and Work Righteousness",
|
||||||
[], true, true, false, true),
|
[],
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
true),
|
||||||
|
|
||||||
CyberSec: new FactionInfo(
|
CyberSec: new FactionInfo(
|
||||||
"The Internet is the first thing that humanity has built that humanity doesn’t understand, the largest " +
|
"The Internet is the first thing that humanity has built that humanity doesn’t understand, the largest " +
|
||||||
"experiment in anarchy that we have ever had. And as the world becomes increasingly dominated by the internet, " +
|
"experiment in anarchy that we have ever had. And as the world becomes increasingly dominated by the internet, " +
|
||||||
"society approaches the brink of total chaos. We serve only to protect society, to protect humanity, to protect " +
|
"society approaches the brink of total chaos. We serve only to protect society, to protect humanity, to " +
|
||||||
"the world from its imminent collapse.",
|
"protect the world from its imminent collapse.",
|
||||||
[], true, true, false, false),
|
[],
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
false),
|
||||||
|
|
||||||
// Special Factions
|
// Special Factions
|
||||||
Bladeburners: new FactionInfo(
|
Bladeburners: new FactionInfo(
|
||||||
"It's too bad they won't live. But then again, who does?<br><br>Note that for this faction, reputation can only " +
|
"It's too bad they won't live. But then again, who does?<br><br>Note that for this faction, reputation can " +
|
||||||
"be gained through Bladeburner actions. Completing Bladeburner contracts/operations will increase your reputation.",
|
"only be gained through Bladeburner actions. Completing Bladeburner contracts/operations will increase your " +
|
||||||
[], false, false, false, false),
|
"reputation.",
|
||||||
|
[],
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false),
|
||||||
};
|
};
|
||||||
|
90
src/Hacking.js
Normal file
90
src/Hacking.js
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
import { BitNodeMultipliers } from "./BitNodeMultipliers";
|
||||||
|
import { Player } from "./Player";
|
||||||
|
import { Server } from "./Server";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the chance the player has to successfully hack a server
|
||||||
|
*/
|
||||||
|
export function calculateHackingChance(server) {
|
||||||
|
const hackFactor = 1.75;
|
||||||
|
const intFactor = 0.2;
|
||||||
|
const difficultyMult = (100 - server.hackDifficulty) / 100;
|
||||||
|
const skillMult = (hackFactor * Player.hacking_skill) + (intFactor * Player.intelligence);
|
||||||
|
const skillChance = (skillMult - server.requiredHackingSkill) / skillMult;
|
||||||
|
const chance = skillChance * difficultyMult * Player.hacking_chance_mult;
|
||||||
|
if (chance > 1) { return 1; }
|
||||||
|
if (chance < 0) { return 0; }
|
||||||
|
|
||||||
|
return chance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the amount of hacking experience the player will gain upon
|
||||||
|
* successfully hacking a server
|
||||||
|
*/
|
||||||
|
export function calculateHackingExpGain(server) {
|
||||||
|
const baseExpGain = 3;
|
||||||
|
const diffFactor = 0.3;
|
||||||
|
if (server.baseDifficulty == null) {
|
||||||
|
server.baseDifficulty = server.hackDifficulty;
|
||||||
|
}
|
||||||
|
var expGain = baseExpGain;
|
||||||
|
expGain += (server.baseDifficulty * Player.hacking_exp_mult * diffFactor);
|
||||||
|
|
||||||
|
return expGain * BitNodeMultipliers.HackExpGain;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the percentage of money that will be stolen from a server if
|
||||||
|
* it is successfully hacked (returns the decimal form, not the actual percent value)
|
||||||
|
*/
|
||||||
|
export function calculatePercentMoneyHacked(server) {
|
||||||
|
// Adjust if needed for balancing. This is the divisor for the final calculation
|
||||||
|
const balanceFactor = 240;
|
||||||
|
|
||||||
|
const difficultyMult = (100 - server.hackDifficulty) / 100;
|
||||||
|
const skillMult = (Player.hacking_skill - (server.requiredHackingSkill - 1)) / Player.hacking_skill;
|
||||||
|
const percentMoneyHacked = difficultyMult * skillMult * Player.hacking_money_mult / balanceFactor;
|
||||||
|
if (percentMoneyHacked < 0) { return 0; }
|
||||||
|
if (percentMoneyHacked > 1) { return 1; }
|
||||||
|
|
||||||
|
return percentMoneyHacked * BitNodeMultipliers.ScriptHackMoney;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns time it takes to complete a hack on a server, in seconds
|
||||||
|
*/
|
||||||
|
export function calculateHackingTime(server) {
|
||||||
|
const difficultyMult = server.requiredHackingSkill * server.hackDifficulty;
|
||||||
|
|
||||||
|
const baseDiff = 500;
|
||||||
|
const baseSkill = 50;
|
||||||
|
const diffFactor = 2.5;
|
||||||
|
const intFactor = 0.1;
|
||||||
|
var skillFactor = (diffFactor * difficultyMult + baseDiff);
|
||||||
|
// tslint:disable-next-line
|
||||||
|
skillFactor /= (Player.hacking_skill + baseSkill + (intFactor * Player.intelligence));
|
||||||
|
|
||||||
|
const hackTimeMultiplier = 5;
|
||||||
|
const hackingTime = hackTimeMultiplier * skillFactor / Player.hacking_speed_mult;
|
||||||
|
|
||||||
|
return hackingTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns time it takes to complete a grow operation on a server, in seconds
|
||||||
|
*/
|
||||||
|
export function calculateGrowTime(server) {
|
||||||
|
const growTimeMultiplier = 3.2; // Relative to hacking time. 16/5 = 3.2
|
||||||
|
|
||||||
|
return growTimeMultiplier * calculateHackingTime(server);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns time it takes to complete a weaken operation on a server, in seconds
|
||||||
|
*/
|
||||||
|
export function calculateWeakenTime(server) {
|
||||||
|
const weakenTimeMultiplier = 4; // Relative to hacking time
|
||||||
|
|
||||||
|
return weakenTimeMultiplier * calculateHackingTime(server);
|
||||||
|
}
|
@ -2,7 +2,7 @@ import {BitNodeMultipliers} from "./BitNodeMultipliers";
|
|||||||
import {CONSTANTS} from "./Constants";
|
import {CONSTANTS} from "./Constants";
|
||||||
import {Engine} from "./engine";
|
import {Engine} from "./engine";
|
||||||
import {iTutorialSteps, iTutorialNextStep,
|
import {iTutorialSteps, iTutorialNextStep,
|
||||||
iTutorialIsRunning, currITutorialStep} from "./InteractiveTutorial";
|
ITutorial} from "./InteractiveTutorial";
|
||||||
import {Player} from "./Player";
|
import {Player} from "./Player";
|
||||||
import {dialogBoxCreate} from "../utils/DialogBox";
|
import {dialogBoxCreate} from "../utils/DialogBox";
|
||||||
import {clearEventListeners} from "../utils/uiHelpers/clearEventListeners";
|
import {clearEventListeners} from "../utils/uiHelpers/clearEventListeners";
|
||||||
@ -245,8 +245,8 @@ Reviver.constructors.HacknetNode = HacknetNode;
|
|||||||
|
|
||||||
function purchaseHacknet() {
|
function purchaseHacknet() {
|
||||||
/* INTERACTIVE TUTORIAL */
|
/* INTERACTIVE TUTORIAL */
|
||||||
if (iTutorialIsRunning) {
|
if (ITutorial.isRunning) {
|
||||||
if (currITutorialStep == iTutorialSteps.HacknetNodesIntroduction) {
|
if (ITutorial.currStep === iTutorialSteps.HacknetNodesIntroduction) {
|
||||||
iTutorialNextStep();
|
iTutorialNextStep();
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
@ -446,7 +446,7 @@ function updateHacknetNodesContent() {
|
|||||||
|
|
||||||
//Update player's money
|
//Update player's money
|
||||||
updateText("hacknet-nodes-player-money", "$" + formatNumber(Player.money.toNumber(), 2));
|
updateText("hacknet-nodes-player-money", "$" + formatNumber(Player.money.toNumber(), 2));
|
||||||
updateText("hacknet-nodes-total-production", "$" + formatNumber(Player.totalHacknetNodeProduction, 2) + " / second");
|
updateText("hacknet-nodes-total-production", "$" + formatNumber(Player.totalHacknetNodeProduction, 2) + " / sec");
|
||||||
|
|
||||||
//Update information in each owned hacknet node
|
//Update information in each owned hacknet node
|
||||||
for (var i = 0; i < Player.hacknetNodes.length; ++i) {
|
for (var i = 0; i < Player.hacknetNodes.length; ++i) {
|
||||||
@ -548,7 +548,7 @@ function updateHacknetNodeDomElement(nodeObj) {
|
|||||||
|
|
||||||
updateText("hacknet-node-name-" + nodeName, nodeName);
|
updateText("hacknet-node-name-" + nodeName, nodeName);
|
||||||
updateText("hacknet-node-total-production-" + nodeName, "$" + formatNumber(nodeObj.totalMoneyGenerated, 2));
|
updateText("hacknet-node-total-production-" + nodeName, "$" + formatNumber(nodeObj.totalMoneyGenerated, 2));
|
||||||
updateText("hacknet-node-production-rate-" + nodeName, "($" + formatNumber(nodeObj.moneyGainRatePerSecond, 2) + " / second)");
|
updateText("hacknet-node-production-rate-" + nodeName, "($" + formatNumber(nodeObj.moneyGainRatePerSecond, 2) + " / sec)");
|
||||||
updateText("hacknet-node-level-" + nodeName, nodeObj.level);
|
updateText("hacknet-node-level-" + nodeName, nodeObj.level);
|
||||||
updateText("hacknet-node-ram-" + nodeName, nodeObj.ram + "GB");
|
updateText("hacknet-node-ram-" + nodeName, nodeObj.ram + "GB");
|
||||||
updateText("hacknet-node-cores-" + nodeName, nodeObj.cores);
|
updateText("hacknet-node-cores-" + nodeName, nodeObj.cores);
|
||||||
|
@ -162,7 +162,7 @@ function nextInfiltrationLevel(inst) {
|
|||||||
if (!e.isTrusted) {return false;}
|
if (!e.isTrusted) {return false;}
|
||||||
var res = attemptInfiltrationKill(inst);
|
var res = attemptInfiltrationKill(inst);
|
||||||
if (res[0]) {
|
if (res[0]) {
|
||||||
writeInfiltrationStatusText("You SUCCESSFULLY killed the security bots! Unfortunately you alerted the " +
|
writeInfiltrationStatusText("You <span class='success'>SUCCESSFULLY</span> killed the security bots! Unfortunately you alerted the " +
|
||||||
"rest of the facility's security. The facility's security " +
|
"rest of the facility's security. The facility's security " +
|
||||||
"level increased by " + formatNumber((res[1]*100)-100, 2).toString() + "%");
|
"level increased by " + formatNumber((res[1]*100)-100, 2).toString() + "%");
|
||||||
Player.karma -= 1;
|
Player.karma -= 1;
|
||||||
@ -170,7 +170,7 @@ function nextInfiltrationLevel(inst) {
|
|||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
var dmgTaken = Math.max(1, Math.round(1.5 * inst.securityLevel / Player.defense));
|
var dmgTaken = Math.max(1, Math.round(1.5 * inst.securityLevel / Player.defense));
|
||||||
writeInfiltrationStatusText("You FAILED to kill the security bots. The bots fight back " +
|
writeInfiltrationStatusText("You <span class='failure'>FAILED</span> to kill the security bots. The bots fight back " +
|
||||||
"and raise the alarm! You take " + dmgTaken + " damage and " +
|
"and raise the alarm! You take " + dmgTaken + " damage and " +
|
||||||
"the facility's security level increases by " +
|
"the facility's security level increases by " +
|
||||||
formatNumber((res[1]*100)-100, 2).toString() + "%");
|
formatNumber((res[1]*100)-100, 2).toString() + "%");
|
||||||
@ -186,12 +186,12 @@ function nextInfiltrationLevel(inst) {
|
|||||||
if (!e.isTrusted) {return false;}
|
if (!e.isTrusted) {return false;}
|
||||||
var res = attemptInfiltrationAssassinate(inst);
|
var res = attemptInfiltrationAssassinate(inst);
|
||||||
if (res[0]) {
|
if (res[0]) {
|
||||||
writeInfiltrationStatusText("You SUCCESSFULLY assassinated the security bots without being detected!");
|
writeInfiltrationStatusText("You <span class='success'>SUCCESSFULLY</span> assassinated the security bots without being detected!");
|
||||||
Player.karma -= 1;
|
Player.karma -= 1;
|
||||||
endInfiltrationLevel(inst);
|
endInfiltrationLevel(inst);
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
writeInfiltrationStatusText("You FAILED to assassinate the security bots. The bots have not detected " +
|
writeInfiltrationStatusText("You <span class='failure'>FAILED</span> to assassinate the security bots. The bots have not detected " +
|
||||||
"you but are now more alert for an intruder. The facility's security level " +
|
"you but are now more alert for an intruder. The facility's security level " +
|
||||||
"has increased by " + formatNumber((res[1]*100)-100, 2).toString() + "%");
|
"has increased by " + formatNumber((res[1]*100)-100, 2).toString() + "%");
|
||||||
}
|
}
|
||||||
@ -209,7 +209,7 @@ function nextInfiltrationLevel(inst) {
|
|||||||
if (!e.isTrusted) {return false;}
|
if (!e.isTrusted) {return false;}
|
||||||
var res = attemptInfiltrationKill(inst);
|
var res = attemptInfiltrationKill(inst);
|
||||||
if (res[0]) {
|
if (res[0]) {
|
||||||
writeInfiltrationStatusText("You SUCCESSFULLY killed the security guard! Unfortunately you alerted the " +
|
writeInfiltrationStatusText("You <span class='success'>SUCCESSFULLY</span> killed the security guard! Unfortunately you alerted the " +
|
||||||
"rest of the facility's security. The facility's security " +
|
"rest of the facility's security. The facility's security " +
|
||||||
"level has increased by " + formatNumber((res[1]*100)-100, 2).toString() + "%");
|
"level has increased by " + formatNumber((res[1]*100)-100, 2).toString() + "%");
|
||||||
Player.karma -= 3;
|
Player.karma -= 3;
|
||||||
@ -218,7 +218,7 @@ function nextInfiltrationLevel(inst) {
|
|||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
var dmgTaken = Math.max(1, Math.round(inst.securityLevel / Player.defense));
|
var dmgTaken = Math.max(1, Math.round(inst.securityLevel / Player.defense));
|
||||||
writeInfiltrationStatusText("You FAILED to kill the security guard. The guard fights back " +
|
writeInfiltrationStatusText("You <span class='failure'>FAILED</span> to kill the security guard. The guard fights back " +
|
||||||
"and raises the alarm! You take " + dmgTaken + " damage and " +
|
"and raises the alarm! You take " + dmgTaken + " damage and " +
|
||||||
"the facility's security level has increased by " +
|
"the facility's security level has increased by " +
|
||||||
formatNumber((res[1]*100)-100, 2).toString() + "%");
|
formatNumber((res[1]*100)-100, 2).toString() + "%");
|
||||||
@ -236,13 +236,13 @@ function nextInfiltrationLevel(inst) {
|
|||||||
if (!e.isTrusted) {return false;}
|
if (!e.isTrusted) {return false;}
|
||||||
var res = attemptInfiltrationAssassinate(inst);
|
var res = attemptInfiltrationAssassinate(inst);
|
||||||
if (res[0]) {
|
if (res[0]) {
|
||||||
writeInfiltrationStatusText("You SUCCESSFULLY assassinated the security guard without being detected!");
|
writeInfiltrationStatusText("You <span class='success'>SUCCESSFULLY</span> assassinated the security guard without being detected!");
|
||||||
Player.karma -= 3;
|
Player.karma -= 3;
|
||||||
++Player.numPeopleKilled;
|
++Player.numPeopleKilled;
|
||||||
endInfiltrationLevel(inst);
|
endInfiltrationLevel(inst);
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
writeInfiltrationStatusText("You FAILED to assassinate the security guard. The guard has not detected " +
|
writeInfiltrationStatusText("You <span class='failure'>FAILED</span> to assassinate the security guard. The guard has not detected " +
|
||||||
"you but is now more alert for an intruder. The facility's security level " +
|
"you but is now more alert for an intruder. The facility's security level " +
|
||||||
"has increased by " + formatNumber((res[1]*100)-100, 2).toString() + "%");
|
"has increased by " + formatNumber((res[1]*100)-100, 2).toString() + "%");
|
||||||
}
|
}
|
||||||
@ -259,14 +259,14 @@ function nextInfiltrationLevel(inst) {
|
|||||||
if (!e.isTrusted) {return false;}
|
if (!e.isTrusted) {return false;}
|
||||||
var res = attemptInfiltrationKnockout(inst);
|
var res = attemptInfiltrationKnockout(inst);
|
||||||
if (res[0]) {
|
if (res[0]) {
|
||||||
writeInfiltrationStatusText("You SUCCESSFULLY knocked out the security guard! " +
|
writeInfiltrationStatusText("You <span class='success'>SUCCESSFULLY</span> knocked out the security guard! " +
|
||||||
"Unfortunately you made a lot of noise and alerted other security.");
|
"Unfortunately you made a lot of noise and alerted other security.");
|
||||||
writeInfiltrationStatusText("The facility's security level increased by " + formatNumber((res[1]*100)-100, 2).toString() + "%");
|
writeInfiltrationStatusText("The facility's security level increased by " + formatNumber((res[1]*100)-100, 2).toString() + "%");
|
||||||
endInfiltrationLevel(inst);
|
endInfiltrationLevel(inst);
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
var dmgTaken = Math.max(1, Math.round(inst.securityLevel / Player.defense));
|
var dmgTaken = Math.max(1, Math.round(inst.securityLevel / Player.defense));
|
||||||
writeInfiltrationStatusText("You FAILED to knockout the security guard. The guard " +
|
writeInfiltrationStatusText("You <span class='failure'>FAILED</span> to knockout the security guard. The guard " +
|
||||||
"raises the alarm and fights back! You take " + dmgTaken + " damage and " +
|
"raises the alarm and fights back! You take " + dmgTaken + " damage and " +
|
||||||
"the facility's security level increases by " + formatNumber((res[1]*100)-100, 2).toString() + "%");
|
"the facility's security level increases by " + formatNumber((res[1]*100)-100, 2).toString() + "%");
|
||||||
if (Player.takeDamage(dmgTaken)) {
|
if (Player.takeDamage(dmgTaken)) {
|
||||||
@ -282,13 +282,13 @@ function nextInfiltrationLevel(inst) {
|
|||||||
if (!e.isTrusted) {return false;}
|
if (!e.isTrusted) {return false;}
|
||||||
var res = attemptInfiltrationStealthKnockout(inst);
|
var res = attemptInfiltrationStealthKnockout(inst);
|
||||||
if (res[0]) {
|
if (res[0]) {
|
||||||
writeInfiltrationStatusText("You SUCCESSFULLY knocked out the security guard without making " +
|
writeInfiltrationStatusText("You <span class='success'>SUCCESSFULLY</span> knocked out the security guard without making " +
|
||||||
"any noise!");
|
"any noise!");
|
||||||
endInfiltrationLevel(inst);
|
endInfiltrationLevel(inst);
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
var dmgTaken = Math.max(1, Math.round(inst.securityLevel / Player.defense));
|
var dmgTaken = Math.max(1, Math.round(inst.securityLevel / Player.defense));
|
||||||
writeInfiltrationStatusText("You FAILED to stealthily knockout the security guard. The guard " +
|
writeInfiltrationStatusText("You <span class='failure'>FAILED</span> to stealthily knockout the security guard. The guard " +
|
||||||
"raises the alarm and fights back! You take " + dmgTaken + " damage and " +
|
"raises the alarm and fights back! You take " + dmgTaken + " damage and " +
|
||||||
"the facility's security level increases by " + formatNumber((res[1]*100)-100, 2).toString() + "%");
|
"the facility's security level increases by " + formatNumber((res[1]*100)-100, 2).toString() + "%");
|
||||||
if (Player.takeDamage(dmgTaken)) {
|
if (Player.takeDamage(dmgTaken)) {
|
||||||
@ -304,12 +304,12 @@ function nextInfiltrationLevel(inst) {
|
|||||||
if (!e.isTrusted) {return false;}
|
if (!e.isTrusted) {return false;}
|
||||||
var res = attemptInfiltrationHack(inst);
|
var res = attemptInfiltrationHack(inst);
|
||||||
if (res[0]) {
|
if (res[0]) {
|
||||||
writeInfiltrationStatusText("You SUCCESSFULLY hacked and disabled the security system!");
|
writeInfiltrationStatusText("You <span class='success'>SUCCESSFULLY</span> hacked and disabled the security system!");
|
||||||
writeInfiltrationStatusText("The facility's security level increased by " + ((res[1]*100) - 100).toString() + "%");
|
writeInfiltrationStatusText("The facility's security level increased by " + ((res[1]*100) - 100).toString() + "%");
|
||||||
endInfiltrationLevel(inst);
|
endInfiltrationLevel(inst);
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
writeInfiltrationStatusText("You FAILED to hack the security system. The facility's " +
|
writeInfiltrationStatusText("You <span class='failure'>FAILED</span> to hack the security system. The facility's " +
|
||||||
"security level increased by " + formatNumber((res[1]*100)-100, 2).toString() + "%");
|
"security level increased by " + formatNumber((res[1]*100)-100, 2).toString() + "%");
|
||||||
}
|
}
|
||||||
updateInfiltrationButtons(inst, scenario);
|
updateInfiltrationButtons(inst, scenario);
|
||||||
@ -321,12 +321,12 @@ function nextInfiltrationLevel(inst) {
|
|||||||
if (!e.isTrusted) {return false;}
|
if (!e.isTrusted) {return false;}
|
||||||
var res = attemptInfiltrationDestroySecurity(inst);
|
var res = attemptInfiltrationDestroySecurity(inst);
|
||||||
if (res[0]) {
|
if (res[0]) {
|
||||||
writeInfiltrationStatusText("You SUCCESSFULLY and violently destroy the security system!");
|
writeInfiltrationStatusText("You <span class='success'>SUCCESSFULLY</span> and violently destroy the security system!");
|
||||||
writeInfiltrationStatusText("The facility's security level increased by " + formatNumber((res[1]*100)-100, 2).toString() + "%");
|
writeInfiltrationStatusText("The facility's security level increased by " + formatNumber((res[1]*100)-100, 2).toString() + "%");
|
||||||
endInfiltrationLevel(inst);
|
endInfiltrationLevel(inst);
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
writeInfiltrationStatusText("You FAILED to destroy the security system. The facility's " +
|
writeInfiltrationStatusText("You <span class='failure'>FAILED</span> to destroy the security system. The facility's " +
|
||||||
"security level increased by " + formatNumber((res[1]*100)-100, 2).toString() + "%");
|
"security level increased by " + formatNumber((res[1]*100)-100, 2).toString() + "%");
|
||||||
}
|
}
|
||||||
updateInfiltrationButtons(inst, scenario);
|
updateInfiltrationButtons(inst, scenario);
|
||||||
@ -338,11 +338,11 @@ function nextInfiltrationLevel(inst) {
|
|||||||
if (!e.isTrusted) {return false;}
|
if (!e.isTrusted) {return false;}
|
||||||
var res = attemptInfiltrationSneak(inst);
|
var res = attemptInfiltrationSneak(inst);
|
||||||
if (res[0]) {
|
if (res[0]) {
|
||||||
writeInfiltrationStatusText("You SUCCESSFULLY sneak past the security undetected!");
|
writeInfiltrationStatusText("You <span class='success'>SUCCESSFULLY</span> sneak past the security undetected!");
|
||||||
endInfiltrationLevel(inst);
|
endInfiltrationLevel(inst);
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
writeInfiltrationStatusText("You FAILED and were detected while trying to sneak past security! The facility's " +
|
writeInfiltrationStatusText("You <span class='failure'>FAILED</span> and were detected while trying to sneak past security! The facility's " +
|
||||||
"security level increased by " + formatNumber((res[1]*100)-100, 2).toString() + "%");
|
"security level increased by " + formatNumber((res[1]*100)-100, 2).toString() + "%");
|
||||||
}
|
}
|
||||||
updateInfiltrationButtons(inst, scenario);
|
updateInfiltrationButtons(inst, scenario);
|
||||||
@ -354,12 +354,12 @@ function nextInfiltrationLevel(inst) {
|
|||||||
if (!e.isTrusted) {return false;}
|
if (!e.isTrusted) {return false;}
|
||||||
var res = attemptInfiltrationPickLockedDoor(inst);
|
var res = attemptInfiltrationPickLockedDoor(inst);
|
||||||
if (res[0]) {
|
if (res[0]) {
|
||||||
writeInfiltrationStatusText("You SUCCESSFULLY pick the locked door!");
|
writeInfiltrationStatusText("You <span class='success'>SUCCESSFULLY</span> pick the locked door!");
|
||||||
writeInfiltrationStatusText("The facility's security level increased by " + formatNumber((res[1]*100)-100, 2).toString() + "%");
|
writeInfiltrationStatusText("The facility's security level increased by " + formatNumber((res[1]*100)-100, 2).toString() + "%");
|
||||||
endInfiltrationLevel(inst);
|
endInfiltrationLevel(inst);
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
writeInfiltrationStatusText("You FAILED to pick the locked door. The facility's security level " +
|
writeInfiltrationStatusText("You <span class='failure'>FAILED</span> to pick the locked door. The facility's security level " +
|
||||||
"increased by " + formatNumber((res[1]*100)-100, 2).toString() + "%");
|
"increased by " + formatNumber((res[1]*100)-100, 2).toString() + "%");
|
||||||
}
|
}
|
||||||
updateInfiltrationButtons(inst, scenario);
|
updateInfiltrationButtons(inst, scenario);
|
||||||
@ -377,13 +377,13 @@ function nextInfiltrationLevel(inst) {
|
|||||||
}
|
}
|
||||||
var res = attemptInfiltrationBribe(inst);
|
var res = attemptInfiltrationBribe(inst);
|
||||||
if (res[0]) {
|
if (res[0]) {
|
||||||
writeInfiltrationStatusText("You SUCCESSFULLY bribed a guard to let you through " +
|
writeInfiltrationStatusText("You <span class='success'>SUCCESSFULLY</span> bribed a guard to let you through " +
|
||||||
"to the next clearance level for $" + bribeAmt);
|
"to the next clearance level for $" + bribeAmt);
|
||||||
Player.loseMoney(bribeAmt);
|
Player.loseMoney(bribeAmt);
|
||||||
endInfiltrationLevel(inst);
|
endInfiltrationLevel(inst);
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
writeInfiltrationStatusText("You FAILED to bribe a guard! The guard is alerting " +
|
writeInfiltrationStatusText("You <span class='failure'>FAILED</span> to bribe a guard! The guard is alerting " +
|
||||||
"other security guards about your presence! The facility's " +
|
"other security guards about your presence! The facility's " +
|
||||||
"security level increased by " + formatNumber((res[1]*100)-100, 2).toString() + "%");
|
"security level increased by " + formatNumber((res[1]*100)-100, 2).toString() + "%");
|
||||||
}
|
}
|
||||||
@ -396,12 +396,12 @@ function nextInfiltrationLevel(inst) {
|
|||||||
if (!e.isTrusted) {return false;}
|
if (!e.isTrusted) {return false;}
|
||||||
var res = attemptInfiltrationEscape(inst);
|
var res = attemptInfiltrationEscape(inst);
|
||||||
if (res[0]) {
|
if (res[0]) {
|
||||||
writeInfiltrationStatusText("You SUCCESSFULLY escape from the facility with the stolen classified " +
|
writeInfiltrationStatusText("You <span class='success'>SUCCESSFULLY</span> escape from the facility with the stolen classified " +
|
||||||
"documents and company secrets!");
|
"documents and company secrets!");
|
||||||
endInfiltration(inst, true);
|
endInfiltration(inst, true);
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
writeInfiltrationStatusText("You FAILED to escape from the facility. You took 1 damage. The facility's " +
|
writeInfiltrationStatusText("You <span class='failure'>FAILED</span> to escape from the facility. You took 1 damage. The facility's " +
|
||||||
"security level increased by " + formatNumber((res[1]*100)-100, 2).toString() + "%");
|
"security level increased by " + formatNumber((res[1]*100)-100, 2).toString() + "%");
|
||||||
if (Player.takeDamage(1)) {
|
if (Player.takeDamage(1)) {
|
||||||
endInfiltration(inst, false);
|
endInfiltration(inst, false);
|
||||||
@ -429,9 +429,9 @@ function endInfiltrationLevel(inst) {
|
|||||||
BitNodeMultipliers.InfiltrationMoney;
|
BitNodeMultipliers.InfiltrationMoney;
|
||||||
inst.secretsStolen.push(baseSecretValue);
|
inst.secretsStolen.push(baseSecretValue);
|
||||||
dialogBoxCreate("You found and stole a set of classified documents from the company. " +
|
dialogBoxCreate("You found and stole a set of classified documents from the company. " +
|
||||||
"These classified secrets could probably be sold for money ($" +
|
"These classified secrets could probably be sold for money (<span class='money-gold'>$" +
|
||||||
formatNumber(secretMoneyValue, 2) + "), or they " +
|
formatNumber(secretMoneyValue, 2) + "</span>), or they " +
|
||||||
"could be given to factions for reputation (" + formatNumber(secretValue, 3) + " rep)");
|
"could be given to factions for reputation (<span class='light-yellow'>" + formatNumber(secretValue, 3) + " rep</span>)");
|
||||||
}
|
}
|
||||||
|
|
||||||
//Increase security level based on difficulty
|
//Increase security level based on difficulty
|
||||||
@ -469,17 +469,18 @@ function updateInfiltrationLevelText(inst) {
|
|||||||
|
|
||||||
var expMultiplier = 2 * inst.clearanceLevel / inst.maxClearanceLevel;
|
var expMultiplier = 2 * inst.clearanceLevel / inst.maxClearanceLevel;
|
||||||
document.getElementById("infiltration-level-text").innerHTML =
|
document.getElementById("infiltration-level-text").innerHTML =
|
||||||
"Facility name: " + inst.companyName + "<br>" +
|
"Facility name: " + inst.companyName + "<br>" +
|
||||||
"Clearance Level: " + inst.clearanceLevel + "<br>" +
|
"Clearance Level: " + inst.clearanceLevel + "<br>" +
|
||||||
"Security Level: " + formatNumber(inst.securityLevel, 3) + "<br><br>" +
|
"Security Level: " + formatNumber(inst.securityLevel, 3) + "<br><br>" +
|
||||||
"Total reputation value of secrets stolen: " + formatNumber(totalValue, 3) + "<br>" +
|
"Total value of stolen secrets<br>" +
|
||||||
"Total monetary value of secrets stolen: $" + formatNumber(totalMoneyValue, 2) + "<br><br>" +
|
"Reputation: <span class='light-yellow'>" + formatNumber(totalValue, 3) + "</span><br>" +
|
||||||
"Hack exp gained: " + formatNumber(inst.hackingExpGained * expMultiplier, 3) + "<br>" +
|
"Money: <span class='money-gold'>$" + formatNumber(totalMoneyValue, 2) + "</span><br><br>" +
|
||||||
"Str exp gained: " + formatNumber(inst.strExpGained * expMultiplier, 3) + "<br>" +
|
"Hack exp gained: " + formatNumber(inst.hackingExpGained * expMultiplier, 3) + "<br>" +
|
||||||
"Def exp gained: " + formatNumber(inst.defExpGained * expMultiplier, 3) + "<br>" +
|
"Str exp gained: " + formatNumber(inst.strExpGained * expMultiplier, 3) + "<br>" +
|
||||||
"Dex exp gained: " + formatNumber(inst.dexExpGained * expMultiplier, 3) + "<br>" +
|
"Def exp gained: " + formatNumber(inst.defExpGained * expMultiplier, 3) + "<br>" +
|
||||||
"Agi exp gained: " + formatNumber(inst.agiExpGained * expMultiplier, 3) + "<br>" +
|
"Dex exp gained: " + formatNumber(inst.dexExpGained * expMultiplier, 3) + "<br>" +
|
||||||
"Cha exp gained: " + formatNumber(inst.chaExpGained * expMultiplier, 3);
|
"Agi exp gained: " + formatNumber(inst.agiExpGained * expMultiplier, 3) + "<br>" +
|
||||||
|
"Cha exp gained: " + formatNumber(inst.chaExpGained * expMultiplier, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateInfiltrationButtons(inst, scenario) {
|
function updateInfiltrationButtons(inst, scenario) {
|
||||||
|
@ -1,55 +1,75 @@
|
|||||||
import {Engine} from "./engine";
|
import {Engine} from "./engine";
|
||||||
import {Player} from "./Player";
|
import {Player} from "./Player";
|
||||||
import {dialogBoxCreate} from "../utils/DialogBox";
|
import {Settings} from "./Settings";
|
||||||
import {clearEventListeners} from "../utils/uiHelpers/clearEventListeners";
|
import {clearEventListeners} from "../utils/uiHelpers/clearEventListeners";
|
||||||
|
import {createElement} from "../utils/uiHelpers/createElement";
|
||||||
|
import {createPopup} from "../utils/uiHelpers/createPopup";
|
||||||
|
import {removeElementById} from "../utils/uiHelpers/removeElementById";
|
||||||
|
|
||||||
/* InteractiveTutorial.js */
|
//Ordered array of keys to Interactive Tutorial Steps
|
||||||
let iTutorialSteps = {
|
const orderedITutorialSteps = [
|
||||||
Start: "Start",
|
"Start",
|
||||||
GoToCharacterPage: "Click on the Character page menu link",
|
"GoToCharacterPage", //Click on 'Stats' page
|
||||||
CharacterPage: "Introduction to Character page",
|
"CharacterPage", //Introduction to 'Stats' page
|
||||||
CharacterGoToTerminalPage: "Click on the Terminal link",
|
"CharacterGoToTerminalPage", //Go back to Terminal
|
||||||
TerminalIntro: "Introduction to terminal interface",
|
"TerminalIntro", //Introduction to Terminal
|
||||||
TerminalHelp: "Using the help command to display all options in terminal",
|
"TerminalHelp", //Using 'help' Terminal command
|
||||||
TerminalLs: "Use the ls command to show all programs/scripts. Right now we have NUKE.exe",
|
"TerminalLs", //Using 'ls' Terminal command
|
||||||
TerminalScan: "Using the scan command to display all available connections",
|
"TerminalScan", //Using 'scan' Terminal command
|
||||||
TerminalScanAnalyze1: "Use the scan-analyze command to show hacking related information",
|
"TerminalScanAnalyze1", //Using 'scan-analyze' Terminal command
|
||||||
TerminalScanAnalyze2: "Use the scan-analyze command with a depth of 3",
|
"TerminalScanAnalyze2", //Using 'scan-analyze 3' Terminal command
|
||||||
TerminalConnect: "Using the telnet/connect command to connect to another server",
|
"TerminalConnect", //Connecting to foodnstuff
|
||||||
TerminalAnalyze: "Use the analyze command to display details about this server",
|
"TerminalAnalyze", //Analyzing foodnstuff
|
||||||
TerminalNuke: "Use the NUKE Program to gain root access to a server",
|
"TerminalNuke", //NUKE foodnstuff
|
||||||
TerminalManualHack: "Use the hack command to manually hack a server",
|
"TerminalManualHack", //Hack foodnstuff
|
||||||
TerminalHackingMechanics: "Briefly explain hacking mechanics",
|
"TerminalHackingMechanics", //Explanation of hacking mechanics
|
||||||
TerminalCreateScript: "Create a script using nano",
|
"TerminalCreateScript", //Create a script using 'nano'
|
||||||
TerminalTypeScript: "This occurs in the Script Editor page...type the script then save and close",
|
"TerminalTypeScript", //Script Editor page - Type script and then save & close
|
||||||
TerminalFree: "Use the free command to check RAM",
|
"TerminalFree", //Using 'Free' Terminal command
|
||||||
TerminalRunScript: "Use the run command to run a script",
|
"TerminalRunScript", //Running script using 'run' Terminal command
|
||||||
TerminalGoToActiveScriptsPage: "Go to the ActiveScriptsPage",
|
"TerminalGoToActiveScriptsPage",
|
||||||
ActiveScriptsPage: "Introduction to the Active Scripts Page",
|
"ActiveScriptsPage",
|
||||||
ActiveScriptsToTerminal: "Go from Active Scripts Page Back to Terminal",
|
"ActiveScriptsToTerminal",
|
||||||
TerminalTailScript: "Use the tail command to show a script's logs",
|
"TerminalTailScript",
|
||||||
GoToHacknetNodesPage: "Go to the Hacknet Nodes page",
|
"GoToHacknetNodesPage",
|
||||||
HacknetNodesIntroduction: "Introduction to Hacknet Nodesm and have user purchase one",
|
"HacknetNodesIntroduction",
|
||||||
HacknetNodesGoToWorldPage: "Go to the world page",
|
"HacknetNodesGoToWorldPage",
|
||||||
WorldDescription: "Tell the user to explore..theres a lot of different stuff to do out there",
|
"WorldDescription",
|
||||||
TutorialPageInfo: "The tutorial page contains a lot of info on different subjects",
|
"TutorialPageInfo",
|
||||||
End: "End",
|
"End"
|
||||||
|
]
|
||||||
|
|
||||||
|
//Create an 'enum' for the Steps
|
||||||
|
const iTutorialSteps = {};
|
||||||
|
for (let i = 0; i < orderedITutorialSteps.length; ++i) {
|
||||||
|
iTutorialSteps[orderedITutorialSteps[i]] = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
var currITutorialStep = iTutorialSteps.Start;
|
var ITutorial = {
|
||||||
var iTutorialIsRunning = false;
|
currStep: 0, //iTutorialSteps.Start
|
||||||
|
isRunning: false,
|
||||||
|
|
||||||
|
//Keeps track of whether each step has been done
|
||||||
|
stepIsDone: {},
|
||||||
|
}
|
||||||
|
|
||||||
function iTutorialStart() {
|
function iTutorialStart() {
|
||||||
|
//Initialize Interactive Tutorial state by settings 'done' for each state to false
|
||||||
|
ITutorial.stepIsDone = {};
|
||||||
|
for (let i = 0; i < orderedITutorialSteps.length; ++i) {
|
||||||
|
ITutorial.stepIsDone[i] = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Engine.loadTerminalContent();
|
||||||
|
|
||||||
//Don't autosave during this interactive tutorial
|
//Don't autosave during this interactive tutorial
|
||||||
Engine.Counters.autoSaveCounter = 999000000000;
|
Engine.Counters.autoSaveCounter = Infinity;
|
||||||
console.log("Interactive Tutorial started");
|
console.log("Interactive Tutorial started");
|
||||||
currITutorialStep = iTutorialSteps.Start;
|
ITutorial.currStep = 0;
|
||||||
iTutorialIsRunning = true;
|
ITutorial.isRunning = true;
|
||||||
|
|
||||||
document.getElementById("interactive-tutorial-container").style.display = "block";
|
document.getElementById("interactive-tutorial-container").style.display = "block";
|
||||||
|
|
||||||
iTutorialEvaluateStep();
|
|
||||||
|
|
||||||
//Exit tutorial button
|
//Exit tutorial button
|
||||||
var exitButton = clearEventListeners("interactive-tutorial-exit");
|
var exitButton = clearEventListeners("interactive-tutorial-exit");
|
||||||
exitButton.addEventListener("click", function() {
|
exitButton.addEventListener("click", function() {
|
||||||
@ -59,142 +79,150 @@ function iTutorialStart() {
|
|||||||
|
|
||||||
//Back button
|
//Back button
|
||||||
var backButton = clearEventListeners("interactive-tutorial-back");
|
var backButton = clearEventListeners("interactive-tutorial-back");
|
||||||
backButton.style.display = "none";
|
|
||||||
backButton.addEventListener("click", function() {
|
backButton.addEventListener("click", function() {
|
||||||
iTutorialPrevStep();
|
iTutorialPrevStep();
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//Next button
|
||||||
|
var nextButton = clearEventListeners("interactive-tutorial-next");
|
||||||
|
nextButton.addEventListener("click", function() {
|
||||||
|
iTutorialNextStep();
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
iTutorialEvaluateStep();
|
||||||
}
|
}
|
||||||
|
|
||||||
function iTutorialEvaluateStep() {
|
function iTutorialEvaluateStep() {
|
||||||
if (!iTutorialIsRunning) {console.log("Interactive Tutorial not running"); return;}
|
if (!ITutorial.isRunning) {console.log("Interactive Tutorial not running"); return;}
|
||||||
switch(currITutorialStep) {
|
|
||||||
|
//Disable and clear main menu
|
||||||
|
var terminalMainMenu = clearEventListeners("terminal-menu-link");
|
||||||
|
var statsMainMenu = clearEventListeners("stats-menu-link");
|
||||||
|
var activeScriptsMainMenu = clearEventListeners("active-scripts-menu-link");
|
||||||
|
var hacknetMainMenu = clearEventListeners("hacknet-nodes-menu-link");
|
||||||
|
var cityMainMenu = clearEventListeners("city-menu-link");
|
||||||
|
var tutorialMainMenu = clearEventListeners("tutorial-menu-link");
|
||||||
|
terminalMainMenu.removeAttribute("class");
|
||||||
|
statsMainMenu.removeAttribute("class");
|
||||||
|
activeScriptsMainMenu.removeAttribute("class");
|
||||||
|
hacknetMainMenu.removeAttribute("class");
|
||||||
|
cityMainMenu.removeAttribute("class");
|
||||||
|
tutorialMainMenu.removeAttribute("class");
|
||||||
|
|
||||||
|
//Interactive Tutorial Next button
|
||||||
|
var nextBtn = document.getElementById("interactive-tutorial-next");
|
||||||
|
|
||||||
|
switch(ITutorial.currStep) {
|
||||||
case iTutorialSteps.Start:
|
case iTutorialSteps.Start:
|
||||||
Engine.loadTerminalContent();
|
Engine.loadTerminalContent();
|
||||||
|
|
||||||
iTutorialSetText("Welcome to Bitburner, a cyberpunk-themed incremental RPG! " +
|
iTutorialSetText("Welcome to Bitburner, a cyberpunk-themed incremental RPG! " +
|
||||||
"The game takes place in a dark, dystopian future...The year is 2077...<br><br>" +
|
"The game takes place in a dark, dystopian future...The year is 2077...<br><br>" +
|
||||||
"This tutorial will show you the basics of the game. " +
|
"This tutorial will show you the basics of the game. " +
|
||||||
"You may skip the tutorial at any time.");
|
"You may skip the tutorial at any time.");
|
||||||
var next = clearEventListeners("interactive-tutorial-next");
|
nextBtn.style.display = "inline-block";
|
||||||
next.style.display = "inline-block";
|
|
||||||
next.addEventListener("click", function() {
|
|
||||||
iTutorialNextStep();
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
break;
|
break;
|
||||||
case iTutorialSteps.GoToCharacterPage:
|
case iTutorialSteps.GoToCharacterPage:
|
||||||
|
Engine.loadTerminalContent();
|
||||||
iTutorialSetText("Let's start by heading to the Stats page. Click the 'Stats' tab on " +
|
iTutorialSetText("Let's start by heading to the Stats page. Click the 'Stats' tab on " +
|
||||||
"the main navigation menu (left-hand side of the screen)");
|
"the main navigation menu (left-hand side of the screen)");
|
||||||
|
nextBtn.style.display = "none";
|
||||||
|
|
||||||
//No next button
|
//Flash 'Stats' menu and set its tutorial click handler
|
||||||
var next = clearEventListeners("interactive-tutorial-next");
|
statsMainMenu.setAttribute("class", "flashing-button");
|
||||||
next.style.display = "none";
|
statsMainMenu.addEventListener("click", function() {
|
||||||
|
|
||||||
//Flash Character tab
|
|
||||||
document.getElementById("stats-menu-link").setAttribute("class", "flashing-button");
|
|
||||||
|
|
||||||
//Initialize everything necessary to open the "Character" page
|
|
||||||
var charaterMainMenuButton = document.getElementById("stats-menu-link");
|
|
||||||
charaterMainMenuButton.addEventListener("click", function() {
|
|
||||||
Engine.loadCharacterContent();
|
Engine.loadCharacterContent();
|
||||||
iTutorialNextStep(); //Opening the character page will go to the next step
|
iTutorialNextStep(); //Opening the character page will go to the next step
|
||||||
clearEventListeners("stats-menu-link");
|
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case iTutorialSteps.CharacterPage:
|
case iTutorialSteps.CharacterPage:
|
||||||
|
Engine.loadCharacterContent();
|
||||||
iTutorialSetText("The Stats page shows a lot of important information about your progress, " +
|
iTutorialSetText("The Stats page shows a lot of important information about your progress, " +
|
||||||
"such as your skills, money, and bonuses/multipliers. ")
|
"such as your skills, money, and bonuses/multipliers. ")
|
||||||
var next = clearEventListeners("interactive-tutorial-next");
|
nextBtn.style.display = "inline-block";
|
||||||
next.style.display = "inline-block";
|
|
||||||
next.addEventListener("click", function() {
|
|
||||||
iTutorialNextStep();
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
break;
|
break;
|
||||||
case iTutorialSteps.CharacterGoToTerminalPage:
|
case iTutorialSteps.CharacterGoToTerminalPage:
|
||||||
|
Engine.loadCharacterContent();
|
||||||
iTutorialSetText("Let's head to your computer's terminal by clicking the 'Terminal' tab on the " +
|
iTutorialSetText("Let's head to your computer's terminal by clicking the 'Terminal' tab on the " +
|
||||||
"main navigation menu.");
|
"main navigation menu.");
|
||||||
//No next button
|
nextBtn.style.display = "none";
|
||||||
var next = clearEventListeners("interactive-tutorial-next");
|
|
||||||
next.style.display = "none";
|
|
||||||
|
|
||||||
document.getElementById("terminal-menu-link").setAttribute("class", "flashing-button");
|
//Flash 'Terminal' menu and set its tutorial click handler
|
||||||
|
terminalMainMenu.setAttribute("class", "flashing-button");
|
||||||
//Initialize everything necessary to open the 'Terminal' Page
|
terminalMainMenu.addEventListener("click", function() {
|
||||||
var terminalMainMenuButton = document.getElementById("terminal-menu-link");
|
|
||||||
terminalMainMenuButton.addEventListener("click", function() {
|
|
||||||
Engine.loadTerminalContent();
|
Engine.loadTerminalContent();
|
||||||
iTutorialNextStep();
|
iTutorialNextStep();
|
||||||
clearEventListeners("terminal-menu-link");
|
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case iTutorialSteps.TerminalIntro:
|
case iTutorialSteps.TerminalIntro:
|
||||||
|
Engine.loadTerminalContent();
|
||||||
iTutorialSetText("The Terminal is used to interface with your home computer as well as " +
|
iTutorialSetText("The Terminal is used to interface with your home computer as well as " +
|
||||||
"all of the other machines around the world.");
|
"all of the other machines around the world.");
|
||||||
var next = clearEventListeners("interactive-tutorial-next");
|
nextBtn.style.display = "inline-block";
|
||||||
next.style.display = "inline-block";
|
|
||||||
next.addEventListener("click", function() {
|
|
||||||
iTutorialNextStep();
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
break;
|
break;
|
||||||
case iTutorialSteps.TerminalHelp:
|
case iTutorialSteps.TerminalHelp:
|
||||||
|
Engine.loadTerminalContent();
|
||||||
iTutorialSetText("Let's try it out. Start by entering the 'help' command into the Terminal " +
|
iTutorialSetText("Let's try it out. Start by entering the 'help' command into the Terminal " +
|
||||||
"(Don't forget to press Enter after typing the command)");
|
"(Don't forget to press Enter after typing the command)");
|
||||||
var next = clearEventListeners("interactive-tutorial-next");
|
nextBtn.style.display = "none"; //next step triggered by terminal command
|
||||||
next.style.display = "none";
|
|
||||||
//next step triggered by terminal command
|
|
||||||
break;
|
break;
|
||||||
case iTutorialSteps.TerminalLs:
|
case iTutorialSteps.TerminalLs:
|
||||||
|
Engine.loadTerminalContent();
|
||||||
iTutorialSetText("The 'help' command displays a list of all available Terminal commands, how to use them, " +
|
iTutorialSetText("The 'help' command displays a list of all available Terminal commands, how to use them, " +
|
||||||
"and a description of what they do. <br><br>Let's try another command. Enter the 'ls' command");
|
"and a description of what they do. <br><br>Let's try another command. Enter the 'ls' command");
|
||||||
//next step triggered by terminal command
|
nextBtn.style.display = "none"; //next step triggered by terminal command
|
||||||
break;
|
break;
|
||||||
case iTutorialSteps.TerminalScan:
|
case iTutorialSteps.TerminalScan:
|
||||||
|
Engine.loadTerminalContent();
|
||||||
iTutorialSetText("'ls' is a basic command that shows all of the contents (programs/scripts) " +
|
iTutorialSetText("'ls' is a basic command that shows all of the contents (programs/scripts) " +
|
||||||
"on the computer. Right now, it shows that you have a program called 'NUKE.exe' on your computer. " +
|
"on the computer. Right now, it shows that you have a program called 'NUKE.exe' on your computer. " +
|
||||||
"We'll get to what this does later. <br><br>Using your home computer's terminal, you can connect " +
|
"We'll get to what this does later. <br><br>Using your home computer's terminal, you can connect " +
|
||||||
"to other machines throughout the world. Let's do that now by first entering " +
|
"to other machines throughout the world. Let's do that now by first entering " +
|
||||||
"the 'scan' command.");
|
"the 'scan' command.");
|
||||||
//next step triggered by terminal command
|
nextBtn.style.display = "none"; //next step triggered by terminal command
|
||||||
break;
|
break;
|
||||||
case iTutorialSteps.TerminalScanAnalyze1:
|
case iTutorialSteps.TerminalScanAnalyze1:
|
||||||
|
Engine.loadTerminalContent();
|
||||||
iTutorialSetText("The 'scan' command shows all available network connections. In other words, " +
|
iTutorialSetText("The 'scan' command shows all available network connections. In other words, " +
|
||||||
"it displays a list of all servers that can be connected to from your " +
|
"it displays a list of all servers that can be connected to from your " +
|
||||||
"current machine. A server is identified by either its IP or its hostname. <br><br> " +
|
"current machine. A server is identified by either its IP or its hostname. <br><br> " +
|
||||||
"That's great and all, but there's so many servers. Which one should you go to? " +
|
"That's great and all, but there's so many servers. Which one should you go to? " +
|
||||||
"The 'scan-analyze' command gives some more detailed information about servers on the " +
|
"The 'scan-analyze' command gives some more detailed information about servers on the " +
|
||||||
"network. Try it now");
|
"network. Try it now");
|
||||||
//next step triggered by terminal command
|
nextBtn.style.display = "none"; //next step triggered by terminal command
|
||||||
break;
|
break;
|
||||||
case iTutorialSteps.TerminalScanAnalyze2:
|
case iTutorialSteps.TerminalScanAnalyze2:
|
||||||
|
Engine.loadTerminalContent();
|
||||||
iTutorialSetText("You just ran 'scan-analyze' with a depth of one. This command shows more detailed " +
|
iTutorialSetText("You just ran 'scan-analyze' with a depth of one. This command shows more detailed " +
|
||||||
"information about each server that you can connect to (servers that are a distance of " +
|
"information about each server that you can connect to (servers that are a distance of " +
|
||||||
"one node away). <br><br> It is also possible to run 'scan-analyze' with " +
|
"one node away). <br><br> It is also possible to run 'scan-analyze' with " +
|
||||||
"a higher depth. Let's try a depth of two with the following command: 'scan-analyze 2'.")
|
"a higher depth. Let's try a depth of two with the following command: 'scan-analyze 2'.")
|
||||||
//next step triggered by terminal command
|
nextBtn.style.display = "none"; //next step triggered by terminal command
|
||||||
break;
|
break;
|
||||||
case iTutorialSteps.TerminalConnect:
|
case iTutorialSteps.TerminalConnect:
|
||||||
|
Engine.loadTerminalContent();
|
||||||
iTutorialSetText("Now you can see information about all servers that are up to two nodes away, as well " +
|
iTutorialSetText("Now you can see information about all servers that are up to two nodes away, as well " +
|
||||||
"as figure out how to navigate to those servers through the network. You can only connect to " +
|
"as figure out how to navigate to those servers through the network. You can only connect to " +
|
||||||
"a server that is one node away. To connect to a machine, use the 'connect [ip/hostname]' command. You can type in " +
|
"a server that is one node away. To connect to a machine, use the 'connect [ip/hostname]' command. You can type in " +
|
||||||
"the ip or the hostname, but dont use both.<br><br>" +
|
"the ip or the hostname, but dont use both.<br><br>" +
|
||||||
"From the results of the 'scan-analyze' command, we can see that the 'foodnstuff' server is " +
|
"From the results of the 'scan-analyze' command, we can see that the 'foodnstuff' server is " +
|
||||||
"only one node away. Let's connect so it now using: 'connect foodnstuff'");
|
"only one node away. Let's connect so it now using: 'connect foodnstuff'");
|
||||||
//next step triggered by terminal command
|
nextBtn.style.display = "none"; //next step triggered by terminal command
|
||||||
break;
|
break;
|
||||||
case iTutorialSteps.TerminalAnalyze:
|
case iTutorialSteps.TerminalAnalyze:
|
||||||
|
Engine.loadTerminalContent();
|
||||||
iTutorialSetText("You are now connected to another machine! What can you do now? You can hack it!<br><br> In the year 2077, currency has " +
|
iTutorialSetText("You are now connected to another machine! What can you do now? You can hack it!<br><br> In the year 2077, currency has " +
|
||||||
"become digital and decentralized. People and corporations store their money " +
|
"become digital and decentralized. People and corporations store their money " +
|
||||||
"on servers and computers. Using your hacking abilities, you can hack servers " +
|
"on servers and computers. Using your hacking abilities, you can hack servers " +
|
||||||
"to steal money and gain experience. <br><br> " +
|
"to steal money and gain experience. <br><br> " +
|
||||||
"Before you try to hack a server, you should run diagnostics using the 'analyze' command");
|
"Before you try to hack a server, you should run diagnostics using the 'analyze' command");
|
||||||
//next step triggered by terminal command
|
nextBtn.style.display = "none"; //next step triggered by terminal command
|
||||||
break;
|
break;
|
||||||
case iTutorialSteps.TerminalNuke:
|
case iTutorialSteps.TerminalNuke:
|
||||||
|
Engine.loadTerminalContent();
|
||||||
iTutorialSetText("When the 'analyze' command finishes running it will show useful information " +
|
iTutorialSetText("When the 'analyze' command finishes running it will show useful information " +
|
||||||
"about hacking the server. <br><br> For this server, the required hacking skill is only 1, " +
|
"about hacking the server. <br><br> For this server, the required hacking skill is only 1, " +
|
||||||
"which means you can hack it right now. However, in order to hack a server " +
|
"which means you can hack it right now. However, in order to hack a server " +
|
||||||
@ -203,14 +231,16 @@ function iTutorialEvaluateStep() {
|
|||||||
"open ports.<br><br> The 'analyze' results shows that there do not need to be any open ports " +
|
"open ports.<br><br> The 'analyze' results shows that there do not need to be any open ports " +
|
||||||
"on this machine for the NUKE virus to work, so go ahead and run the virus using the " +
|
"on this machine for the NUKE virus to work, so go ahead and run the virus using the " +
|
||||||
"'run NUKE.exe' command.");
|
"'run NUKE.exe' command.");
|
||||||
//next step triggered by terminal command
|
nextBtn.style.display = "none"; //next step triggered by terminal command
|
||||||
break;
|
break;
|
||||||
case iTutorialSteps.TerminalManualHack:
|
case iTutorialSteps.TerminalManualHack:
|
||||||
|
Engine.loadTerminalContent();
|
||||||
iTutorialSetText("You now have root access! You can hack the server using the 'hack' command. " +
|
iTutorialSetText("You now have root access! You can hack the server using the 'hack' command. " +
|
||||||
"Try doing that now.");
|
"Try doing that now.");
|
||||||
//next step triggered by terminal command
|
nextBtn.style.display = "none"; //next step triggered by terminal command
|
||||||
break;
|
break;
|
||||||
case iTutorialSteps.TerminalHackingMechanics:
|
case iTutorialSteps.TerminalHackingMechanics:
|
||||||
|
Engine.loadTerminalContent();
|
||||||
iTutorialSetText("You are now attempting to hack the server. Note that performing a hack takes time and " +
|
iTutorialSetText("You are now attempting to hack the server. Note that performing a hack takes time and " +
|
||||||
"only has a certain percentage chance " +
|
"only has a certain percentage chance " +
|
||||||
"of success. This time and success chance is determined by a variety of factors, including " +
|
"of success. This time and success chance is determined by a variety of factors, including " +
|
||||||
@ -220,25 +250,20 @@ function iTutorialEvaluateStep() {
|
|||||||
"the server's security level.<br><br>The amount of money on a server is not limitless. So, if " +
|
"the server's security level.<br><br>The amount of money on a server is not limitless. So, if " +
|
||||||
"you constantly hack a server and deplete its money, then you will encounter " +
|
"you constantly hack a server and deplete its money, then you will encounter " +
|
||||||
"diminishing returns in your hacking.");
|
"diminishing returns in your hacking.");
|
||||||
var next = clearEventListeners("interactive-tutorial-next");
|
nextBtn.style.display = "inline-block";
|
||||||
next.style.display = "inline-block";
|
|
||||||
next.addEventListener("click", function() {
|
|
||||||
iTutorialNextStep();
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
break;
|
break;
|
||||||
case iTutorialSteps.TerminalCreateScript:
|
case iTutorialSteps.TerminalCreateScript:
|
||||||
|
Engine.loadTerminalContent();
|
||||||
iTutorialSetText("Hacking is the core mechanic of the game and is necessary for progressing. However, " +
|
iTutorialSetText("Hacking is the core mechanic of the game and is necessary for progressing. However, " +
|
||||||
"you don't want to be hacking manually the entire time. You can automate your hacking " +
|
"you don't want to be hacking manually the entire time. You can automate your hacking " +
|
||||||
"by writing scripts!<br><br>To create a new script or edit an existing one, you can use the 'nano' " +
|
"by writing scripts!<br><br>To create a new script or edit an existing one, you can use the 'nano' " +
|
||||||
"command. Scripts must end with the '.script' extension. Let's make a script now by " +
|
"command. Scripts must end with the '.script' extension. Let's make a script now by " +
|
||||||
"entering 'nano foodnstuff.script' after the hack command finishes running (Sidenote: Pressing ctrl + c" +
|
"entering 'nano foodnstuff.script' after the hack command finishes running (Sidenote: Pressing ctrl + c" +
|
||||||
" will end a command like hack early)");
|
" will end a command like hack early)");
|
||||||
var next = clearEventListeners("interactive-tutorial-next");
|
nextBtn.style.display = "none"; //next step triggered by terminal command
|
||||||
next.style.display = "none";
|
|
||||||
//next step triggered by terminal command
|
|
||||||
break;
|
break;
|
||||||
case iTutorialSteps.TerminalTypeScript:
|
case iTutorialSteps.TerminalTypeScript:
|
||||||
|
Engine.loadScriptEditorContent("foodnstuff.script", "");
|
||||||
iTutorialSetText("This is the script editor. You can use it to program your scripts. Scripts are " +
|
iTutorialSetText("This is the script editor. You can use it to program your scripts. Scripts are " +
|
||||||
"written in the Netscript language, a programming language created for " +
|
"written in the Netscript language, a programming language created for " +
|
||||||
"this game. <strong style='background-color:#444;'>There are details about the Netscript language in the documentation, which " +
|
"this game. <strong style='background-color:#444;'>There are details about the Netscript language in the documentation, which " +
|
||||||
@ -251,21 +276,24 @@ function iTutorialEvaluateStep() {
|
|||||||
"For anyone with basic programming experience, this code should be straightforward. " +
|
"For anyone with basic programming experience, this code should be straightforward. " +
|
||||||
"This script will continuously hack the 'foodnstuff' server.<br><br>" +
|
"This script will continuously hack the 'foodnstuff' server.<br><br>" +
|
||||||
"To save and close the script editor, press the button in the bottom left, or press ctrl + b.");
|
"To save and close the script editor, press the button in the bottom left, or press ctrl + b.");
|
||||||
//next step triggered in saveAndCloseScriptEditor() (Script.js)
|
nextBtn.style.display = "none"; //next step triggered in saveAndCloseScriptEditor() (Script.js)
|
||||||
break;
|
break;
|
||||||
case iTutorialSteps.TerminalFree:
|
case iTutorialSteps.TerminalFree:
|
||||||
|
Engine.loadTerminalContent();
|
||||||
iTutorialSetText("Now we'll run the script. Scripts require a certain amount of RAM to run, and can be " +
|
iTutorialSetText("Now we'll run the script. Scripts require a certain amount of RAM to run, and can be " +
|
||||||
"run on any machine which you have root access to. Different servers have different " +
|
"run on any machine which you have root access to. Different servers have different " +
|
||||||
"amounts of RAM. You can also purchase more RAM for your home server.<br><br>To check how much " +
|
"amounts of RAM. You can also purchase more RAM for your home server.<br><br>To check how much " +
|
||||||
"RAM is available on this machine, enter the 'free' command.");
|
"RAM is available on this machine, enter the 'free' command.");
|
||||||
//next step triggered by terminal commmand
|
nextBtn.style.display = "none"; //next step triggered by terminal commmand
|
||||||
break;
|
break;
|
||||||
case iTutorialSteps.TerminalRunScript:
|
case iTutorialSteps.TerminalRunScript:
|
||||||
|
Engine.loadTerminalContent();
|
||||||
iTutorialSetText("We have 16GB of free RAM on this machine, which is enough to run our " +
|
iTutorialSetText("We have 16GB of free RAM on this machine, which is enough to run our " +
|
||||||
"script. Let's run our script using 'run foodnstuff.script'.");
|
"script. Let's run our script using 'run foodnstuff.script'.");
|
||||||
//next step triggered by terminal commmand
|
nextBtn.style.display = "none"; //next step triggered by terminal commmand
|
||||||
break;
|
break;
|
||||||
case iTutorialSteps.TerminalGoToActiveScriptsPage:
|
case iTutorialSteps.TerminalGoToActiveScriptsPage:
|
||||||
|
Engine.loadTerminalContent();
|
||||||
iTutorialSetText("Your script is now running! The script might take a few seconds to 'fully start up'. " +
|
iTutorialSetText("Your script is now running! The script might take a few seconds to 'fully start up'. " +
|
||||||
"Your scripts will continuously run in the background and will automatically stop if " +
|
"Your scripts will continuously run in the background and will automatically stop if " +
|
||||||
"the code ever completes (the 'foodnstuff.script' will never complete because it " +
|
"the code ever completes (the 'foodnstuff.script' will never complete because it " +
|
||||||
@ -274,117 +302,114 @@ function iTutorialEvaluateStep() {
|
|||||||
"much slower rate. <br><br> " +
|
"much slower rate. <br><br> " +
|
||||||
"Let's check out some statistics for our running scripts by clicking the " +
|
"Let's check out some statistics for our running scripts by clicking the " +
|
||||||
"'Active Scripts' link in the main navigation menu.");
|
"'Active Scripts' link in the main navigation menu.");
|
||||||
document.getElementById("active-scripts-menu-link").setAttribute("class", "flashing-button");
|
nextBtn.style.display = "none";
|
||||||
var activeScriptsMainMenuButton = document.getElementById("active-scripts-menu-link");
|
|
||||||
activeScriptsMainMenuButton.addEventListener("click", function() {
|
//Flash 'Active Scripts' menu and set its tutorial click handler
|
||||||
|
activeScriptsMainMenu.setAttribute("class", "flashing-button");
|
||||||
|
activeScriptsMainMenu.addEventListener("click", function() {
|
||||||
Engine.loadActiveScriptsContent();
|
Engine.loadActiveScriptsContent();
|
||||||
iTutorialNextStep();
|
iTutorialNextStep();
|
||||||
clearEventListeners("active-scripts-menu-link");
|
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case iTutorialSteps.ActiveScriptsPage:
|
case iTutorialSteps.ActiveScriptsPage:
|
||||||
|
Engine.loadActiveScriptsContent();
|
||||||
iTutorialSetText("This page displays stats/information about all of your scripts that are " +
|
iTutorialSetText("This page displays stats/information about all of your scripts that are " +
|
||||||
"running across every existing server. You can use this to gauge how well " +
|
"running across every existing server. You can use this to gauge how well " +
|
||||||
"your scripts are doing. Let's go back to the Terminal now using the 'Terminal'" +
|
"your scripts are doing. Let's go back to the Terminal now using the 'Terminal'" +
|
||||||
"link.");
|
"link.");
|
||||||
document.getElementById("terminal-menu-link").setAttribute("class", "flashing-button");
|
nextBtn.style.display = "none";
|
||||||
//Initialize everything necessary to open the 'Terminal' Page
|
|
||||||
var terminalMainMenuButton = clearEventListeners("terminal-menu-link");
|
//Flash 'Terminal' button and set its tutorial click handler
|
||||||
terminalMainMenuButton.addEventListener("click", function() {
|
terminalMainMenu.setAttribute("class", "flashing-button");
|
||||||
|
terminalMainMenu.addEventListener("click", function() {
|
||||||
Engine.loadTerminalContent();
|
Engine.loadTerminalContent();
|
||||||
iTutorialNextStep();
|
iTutorialNextStep();
|
||||||
clearEventListeners("terminal-menu-link");
|
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case iTutorialSteps.ActiveScriptsToTerminal:
|
case iTutorialSteps.ActiveScriptsToTerminal:
|
||||||
|
Engine.loadTerminalContent();
|
||||||
iTutorialSetText("One last thing about scripts, each active script contains logs that detail " +
|
iTutorialSetText("One last thing about scripts, each active script contains logs that detail " +
|
||||||
"what it's doing. We can check these logs using the 'tail' command. Do that " +
|
"what it's doing. We can check these logs using the 'tail' command. Do that " +
|
||||||
"now for the script we just ran by typing 'tail foodnstuff.script'");
|
"now for the script we just ran by typing 'tail foodnstuff.script'");
|
||||||
//next step triggered by terminal command
|
nextBtn.style.display = "none"; //next step triggered by terminal command
|
||||||
break;
|
break;
|
||||||
case iTutorialSteps.TerminalTailScript:
|
case iTutorialSteps.TerminalTailScript:
|
||||||
|
Engine.loadTerminalContent();
|
||||||
iTutorialSetText("The log for this script won't show much right now (it might show nothing at all) because it " +
|
iTutorialSetText("The log for this script won't show much right now (it might show nothing at all) because it " +
|
||||||
"just started running...but check back again in a few minutes! <br><br>" +
|
"just started running...but check back again in a few minutes! <br><br>" +
|
||||||
"This pretty much covers the basics of hacking. To learn more about writing " +
|
"This pretty much covers the basics of hacking. To learn more about writing " +
|
||||||
"scripts using the Netscript language, select the 'Tutorial' link in the " +
|
"scripts using the Netscript language, select the 'Tutorial' link in the " +
|
||||||
"main navigation menu to look at the documentation. For now, let's move on " +
|
"main navigation menu to look at the documentation. " +
|
||||||
"to something else!");
|
"<strong style='background-color:#444;'>If you are an experienced JavaScript " +
|
||||||
var next = clearEventListeners("interactive-tutorial-next");
|
"developer, I would highly suggest you check out the section on " +
|
||||||
next.style.display = "inline-block";
|
"NetscriptJS/Netscript 2.0.</strong><br><br>For now, let's move on to something else!");
|
||||||
next.addEventListener("click", function() {
|
nextBtn.style.display = "inline-block";
|
||||||
iTutorialNextStep();
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
break;
|
break;
|
||||||
case iTutorialSteps.GoToHacknetNodesPage:
|
case iTutorialSteps.GoToHacknetNodesPage:
|
||||||
|
Engine.loadTerminalContent();
|
||||||
iTutorialSetText("Hacking is not the only way to earn money. One other way to passively " +
|
iTutorialSetText("Hacking is not the only way to earn money. One other way to passively " +
|
||||||
"earn money is by purchasing and upgrading Hacknet Nodes. Let's go to " +
|
"earn money is by purchasing and upgrading Hacknet Nodes. Let's go to " +
|
||||||
"the 'Hacknet Nodes' page through the main navigation menu now.");
|
"the 'Hacknet Nodes' page through the main navigation menu now.");
|
||||||
document.getElementById("hacknet-nodes-menu-link").setAttribute("class", "flashing-button");
|
nextBtn.style.display = "none";
|
||||||
var hacknetNodesButton = clearEventListeners("hacknet-nodes-menu-link");
|
|
||||||
var next = clearEventListeners("interactive-tutorial-next");
|
//Flash 'Hacknet' menu and set its tutorial click handler
|
||||||
next.style.display = "none";
|
hacknetMainMenu.setAttribute("class", "flashing-button");
|
||||||
hacknetNodesButton.addEventListener("click", function() {
|
hacknetMainMenu.addEventListener("click", function() {
|
||||||
Engine.loadHacknetNodesContent();
|
Engine.loadHacknetNodesContent();
|
||||||
iTutorialNextStep();
|
iTutorialNextStep();
|
||||||
clearEventListeners("hacknet-nodes-menu-link");
|
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case iTutorialSteps.HacknetNodesIntroduction:
|
case iTutorialSteps.HacknetNodesIntroduction:
|
||||||
|
Engine.loadHacknetNodesContent();
|
||||||
iTutorialSetText("From this page you can purchase new Hacknet Nodes and upgrade your " +
|
iTutorialSetText("From this page you can purchase new Hacknet Nodes and upgrade your " +
|
||||||
"existing ones. Let's purchase a new one now.");
|
"existing ones. Let's purchase a new one now.");
|
||||||
//Next step triggered by purchaseHacknet() (HacknetNode.js)
|
nextBtn.style.display = "none"; //Next step triggered by purchaseHacknet() (HacknetNode.js)
|
||||||
break;
|
break;
|
||||||
case iTutorialSteps.HacknetNodesGoToWorldPage:
|
case iTutorialSteps.HacknetNodesGoToWorldPage:
|
||||||
|
Engine.loadHacknetNodesContent();
|
||||||
iTutorialSetText("You just purchased a Hacknet Node! This Hacknet Node will passively " +
|
iTutorialSetText("You just purchased a Hacknet Node! This Hacknet Node will passively " +
|
||||||
"earn you money over time, both online and offline. When you get enough " +
|
"earn you money over time, both online and offline. When you get enough " +
|
||||||
" money, you can upgrade " +
|
" money, you can upgrade " +
|
||||||
"your newly-purchased Hacknet Node below.<br><br>" +
|
"your newly-purchased Hacknet Node below.<br><br>" +
|
||||||
"Let's go to the 'City' page through the main navigation menu.");
|
"Let's go to the 'City' page through the main navigation menu.");
|
||||||
document.getElementById("city-menu-link").setAttribute("class", "flashing-button");
|
nextBtn.style.display = "none";
|
||||||
var worldButton = clearEventListeners("city-menu-link");
|
|
||||||
worldButton.addEventListener("click", function() {
|
//Flash 'City' menu and set its tutorial click handler
|
||||||
|
cityMainMenu.setAttribute("class", "flashing-button");
|
||||||
|
cityMainMenu.addEventListener("click", function() {
|
||||||
Engine.loadWorldContent();
|
Engine.loadWorldContent();
|
||||||
iTutorialNextStep();
|
iTutorialNextStep();
|
||||||
clearEventListeners("city-menu-link");
|
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case iTutorialSteps.WorldDescription:
|
case iTutorialSteps.WorldDescription:
|
||||||
|
Engine.loadWorldContent();
|
||||||
iTutorialSetText("This page lists all of the different locations you can currently " +
|
iTutorialSetText("This page lists all of the different locations you can currently " +
|
||||||
"travel to. Each location has something that you can do. " +
|
"travel to. Each location has something that you can do. " +
|
||||||
"There's a lot of content out in the world, make sure " +
|
"There's a lot of content out in the world, make sure " +
|
||||||
"you explore and discover!<br><br>" +
|
"you explore and discover!<br><br>" +
|
||||||
"Lastly, click on the 'Tutorial' link in the main navigation menu.");
|
"Lastly, click on the 'Tutorial' link in the main navigation menu.");
|
||||||
document.getElementById("tutorial-menu-link").setAttribute("class", "flashing-button");
|
nextBtn.style.display = "none";
|
||||||
var tutorialButton = clearEventListeners("tutorial-menu-link");
|
|
||||||
tutorialButton.addEventListener("click", function() {
|
//Flash 'Tutorial' menu and set its tutorial click handler
|
||||||
|
tutorialMainMenu.setAttribute("class", "flashing-button");
|
||||||
|
tutorialMainMenu.addEventListener("click", function() {
|
||||||
Engine.loadTutorialContent();
|
Engine.loadTutorialContent();
|
||||||
iTutorialNextStep();
|
iTutorialNextStep();
|
||||||
clearEventListeners("tutorial-menu-link");
|
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case iTutorialSteps.TutorialPageInfo:
|
case iTutorialSteps.TutorialPageInfo:
|
||||||
|
Engine.loadTutorialContent();
|
||||||
iTutorialSetText("This page contains a lot of different documentation about the game's " +
|
iTutorialSetText("This page contains a lot of different documentation about the game's " +
|
||||||
"content and mechanics. <strong style='background-color:#444;'> I know it's a lot, but I highly suggest you read " +
|
"content and mechanics. <strong style='background-color:#444;'> I know it's a lot, but I highly suggest you read " +
|
||||||
"(or at least skim) through this before you start playing</strong>. That's the end of the tutorial. " +
|
"(or at least skim) through this before you start playing</strong>. That's the end of the tutorial. " +
|
||||||
"Hope you enjoy the game!");
|
"Hope you enjoy the game!");
|
||||||
var next = clearEventListeners("interactive-tutorial-next");
|
nextBtn.style.display = "inline-block";
|
||||||
next.style.display = "inline-block";
|
nextBtn.innerHTML = "Finish Tutorial";
|
||||||
next.innerHTML = "Finish Tutorial";
|
|
||||||
|
|
||||||
var backButton = clearEventListeners("interactive-tutorial-back");
|
|
||||||
backButton.style.display = "none";
|
|
||||||
|
|
||||||
next.addEventListener("click", function() {
|
|
||||||
iTutorialNextStep();
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
break;
|
break;
|
||||||
case iTutorialSteps.End:
|
case iTutorialSteps.End:
|
||||||
iTutorialEnd();
|
iTutorialEnd();
|
||||||
@ -392,264 +417,85 @@ function iTutorialEvaluateStep() {
|
|||||||
default:
|
default:
|
||||||
throw new Error("Invalid tutorial step");
|
throw new Error("Invalid tutorial step");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ITutorial.stepIsDone[ITutorial.currStep] === true) {
|
||||||
|
nextBtn.style.display = "inline-block";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Go to the next step and evaluate it
|
//Go to the next step and evaluate it
|
||||||
function iTutorialNextStep() {
|
function iTutorialNextStep() {
|
||||||
switch(currITutorialStep) {
|
//Special behavior for certain steps
|
||||||
case iTutorialSteps.Start:
|
if (ITutorial.currStep === iTutorialSteps.GoToCharacterPage) {
|
||||||
currITutorialStep = iTutorialSteps.GoToCharacterPage;
|
|
||||||
iTutorialEvaluateStep();
|
|
||||||
break;
|
|
||||||
case iTutorialSteps.GoToCharacterPage:
|
|
||||||
document.getElementById("stats-menu-link").removeAttribute("class");
|
document.getElementById("stats-menu-link").removeAttribute("class");
|
||||||
currITutorialStep = iTutorialSteps.CharacterPage;
|
|
||||||
iTutorialEvaluateStep();
|
|
||||||
break;
|
|
||||||
case iTutorialSteps.CharacterPage:
|
|
||||||
currITutorialStep = iTutorialSteps.CharacterGoToTerminalPage;
|
|
||||||
iTutorialEvaluateStep();
|
|
||||||
break;
|
|
||||||
case iTutorialSteps.CharacterGoToTerminalPage:
|
|
||||||
document.getElementById("terminal-menu-link").removeAttribute("class");
|
|
||||||
currITutorialStep = iTutorialSteps.TerminalIntro;
|
|
||||||
iTutorialEvaluateStep();
|
|
||||||
break;
|
|
||||||
case iTutorialSteps.TerminalIntro:
|
|
||||||
currITutorialStep = iTutorialSteps.TerminalHelp;
|
|
||||||
iTutorialEvaluateStep();
|
|
||||||
break;
|
|
||||||
case iTutorialSteps.TerminalHelp:
|
|
||||||
currITutorialStep = iTutorialSteps.TerminalLs;
|
|
||||||
iTutorialEvaluateStep();
|
|
||||||
break;
|
|
||||||
case iTutorialSteps.TerminalLs:
|
|
||||||
currITutorialStep = iTutorialSteps.TerminalScan;
|
|
||||||
iTutorialEvaluateStep();
|
|
||||||
break;
|
|
||||||
case iTutorialSteps.TerminalScan:
|
|
||||||
currITutorialStep = iTutorialSteps.TerminalScanAnalyze1;
|
|
||||||
iTutorialEvaluateStep();
|
|
||||||
break;
|
|
||||||
case iTutorialSteps.TerminalScanAnalyze1:
|
|
||||||
currITutorialStep = iTutorialSteps.TerminalScanAnalyze2;
|
|
||||||
iTutorialEvaluateStep();
|
|
||||||
break;
|
|
||||||
case iTutorialSteps.TerminalScanAnalyze2:
|
|
||||||
currITutorialStep = iTutorialSteps.TerminalConnect;
|
|
||||||
iTutorialEvaluateStep();
|
|
||||||
break;
|
|
||||||
case iTutorialSteps.TerminalConnect:
|
|
||||||
currITutorialStep = iTutorialSteps.TerminalAnalyze;
|
|
||||||
iTutorialEvaluateStep();
|
|
||||||
break;
|
|
||||||
case iTutorialSteps.TerminalAnalyze:
|
|
||||||
currITutorialStep = iTutorialSteps.TerminalNuke;
|
|
||||||
iTutorialEvaluateStep();
|
|
||||||
break;
|
|
||||||
case iTutorialSteps.TerminalNuke:
|
|
||||||
currITutorialStep = iTutorialSteps.TerminalManualHack;
|
|
||||||
iTutorialEvaluateStep();
|
|
||||||
break;
|
|
||||||
case iTutorialSteps.TerminalManualHack:
|
|
||||||
currITutorialStep = iTutorialSteps.TerminalHackingMechanics;
|
|
||||||
iTutorialEvaluateStep();
|
|
||||||
break;
|
|
||||||
case iTutorialSteps.TerminalHackingMechanics:
|
|
||||||
currITutorialStep = iTutorialSteps.TerminalCreateScript;
|
|
||||||
iTutorialEvaluateStep();
|
|
||||||
break;
|
|
||||||
case iTutorialSteps.TerminalCreateScript:
|
|
||||||
currITutorialStep = iTutorialSteps.TerminalTypeScript;
|
|
||||||
iTutorialEvaluateStep();
|
|
||||||
break;
|
|
||||||
case iTutorialSteps.TerminalTypeScript:
|
|
||||||
currITutorialStep = iTutorialSteps.TerminalFree;
|
|
||||||
iTutorialEvaluateStep();
|
|
||||||
break;
|
|
||||||
case iTutorialSteps.TerminalFree:
|
|
||||||
currITutorialStep = iTutorialSteps.TerminalRunScript;
|
|
||||||
iTutorialEvaluateStep();
|
|
||||||
break;
|
|
||||||
case iTutorialSteps.TerminalRunScript:
|
|
||||||
currITutorialStep = iTutorialSteps.TerminalGoToActiveScriptsPage;
|
|
||||||
iTutorialEvaluateStep();
|
|
||||||
break;
|
|
||||||
case iTutorialSteps.TerminalGoToActiveScriptsPage:
|
|
||||||
document.getElementById("active-scripts-menu-link").removeAttribute("class");
|
|
||||||
currITutorialStep = iTutorialSteps.ActiveScriptsPage;
|
|
||||||
iTutorialEvaluateStep();
|
|
||||||
break;
|
|
||||||
case iTutorialSteps.ActiveScriptsPage:
|
|
||||||
document.getElementById("terminal-menu-link").removeAttribute("class");
|
|
||||||
currITutorialStep = iTutorialSteps.ActiveScriptsToTerminal;
|
|
||||||
iTutorialEvaluateStep();
|
|
||||||
break;
|
|
||||||
case iTutorialSteps.ActiveScriptsToTerminal:
|
|
||||||
currITutorialStep = iTutorialSteps.TerminalTailScript;
|
|
||||||
iTutorialEvaluateStep();
|
|
||||||
break;
|
|
||||||
case iTutorialSteps.TerminalTailScript:
|
|
||||||
currITutorialStep = iTutorialSteps.GoToHacknetNodesPage;
|
|
||||||
iTutorialEvaluateStep();
|
|
||||||
break;
|
|
||||||
case iTutorialSteps.GoToHacknetNodesPage:
|
|
||||||
document.getElementById("hacknet-nodes-menu-link").removeAttribute("class");
|
|
||||||
currITutorialStep = iTutorialSteps.HacknetNodesIntroduction;
|
|
||||||
iTutorialEvaluateStep();
|
|
||||||
break;
|
|
||||||
case iTutorialSteps.HacknetNodesIntroduction:
|
|
||||||
currITutorialStep = iTutorialSteps.HacknetNodesGoToWorldPage;
|
|
||||||
iTutorialEvaluateStep();
|
|
||||||
break;
|
|
||||||
case iTutorialSteps.HacknetNodesGoToWorldPage:
|
|
||||||
document.getElementById("city-menu-link").removeAttribute("class");
|
|
||||||
currITutorialStep = iTutorialSteps.WorldDescription;
|
|
||||||
iTutorialEvaluateStep();
|
|
||||||
break;
|
|
||||||
case iTutorialSteps.WorldDescription:
|
|
||||||
document.getElementById("tutorial-menu-link").removeAttribute("class");
|
|
||||||
currITutorialStep = iTutorialSteps.TutorialPageInfo;
|
|
||||||
iTutorialEvaluateStep();
|
|
||||||
break;
|
|
||||||
case iTutorialSteps.TutorialPageInfo:
|
|
||||||
currITutorialStep = iTutorialSteps.End;
|
|
||||||
iTutorialEvaluateStep();
|
|
||||||
break;
|
|
||||||
case iTutorialSteps.End:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new Error("Invalid tutorial step");
|
|
||||||
}
|
}
|
||||||
|
if (ITutorial.currStep === iTutorialSteps.CharacterGoToTerminalPage) {
|
||||||
|
document.getElementById("terminal-menu-link").removeAttribute("class");
|
||||||
|
}
|
||||||
|
if (ITutorial.currStep === iTutorialSteps.TerminalGoToActiveScriptsPage) {
|
||||||
|
document.getElementById("active-scripts-menu-link").removeAttribute("class");
|
||||||
|
}
|
||||||
|
if (ITutorial.currStep === iTutorialSteps.ActiveScriptsPage) {
|
||||||
|
document.getElementById("terminal-menu-link").removeAttribute("class");
|
||||||
|
}
|
||||||
|
if (ITutorial.currStep === iTutorialSteps.GoToHacknetNodesPage) {
|
||||||
|
document.getElementById("hacknet-nodes-menu-link").removeAttribute("class");
|
||||||
|
}
|
||||||
|
if (ITutorial.currStep === iTutorialSteps.HacknetNodesGoToWorldPage) {
|
||||||
|
document.getElementById("city-menu-link").removeAttribute("class");
|
||||||
|
}
|
||||||
|
if (ITutorial.currStep === iTutorialSteps.WorldDescription) {
|
||||||
|
document.getElementById("tutorial-menu-link").removeAttribute("class");
|
||||||
|
}
|
||||||
|
|
||||||
|
ITutorial.stepIsDone[ITutorial.currStep] = true;
|
||||||
|
if (ITutorial.currStep < iTutorialSteps.End) {
|
||||||
|
ITutorial.currStep += 1;
|
||||||
|
}
|
||||||
|
iTutorialEvaluateStep();
|
||||||
}
|
}
|
||||||
|
|
||||||
//Go to previous step and evaluate
|
//Go to previous step and evaluate
|
||||||
function iTutorialPrevStep() {
|
function iTutorialPrevStep() {
|
||||||
switch(currITutorialStep) {
|
if (ITutorial.currStep > iTutorialSteps.Start) {
|
||||||
case iTutorialSteps.Start:
|
ITutorial.currStep -= 1;
|
||||||
currITutorialStep = iTutorialSteps.Start;
|
|
||||||
iTutorialEvaluateStep();
|
|
||||||
break;
|
|
||||||
case iTutorialSteps.GoToCharacterPage:
|
|
||||||
currITutorialStep = iTutorialSteps.Start;
|
|
||||||
iTutorialEvaluateStep();
|
|
||||||
break;
|
|
||||||
case iTutorialSteps.CharacterPage:
|
|
||||||
currITutorialStep = iTutorialSteps.GoToCharacterPage;
|
|
||||||
iTutorialEvaluateStep();
|
|
||||||
break;
|
|
||||||
case iTutorialSteps.CharacterGoToTerminalPage:
|
|
||||||
currITutorialStep = iTutorialSteps.CharacterPage;
|
|
||||||
iTutorialEvaluateStep();
|
|
||||||
break;
|
|
||||||
case iTutorialSteps.TerminalIntro:
|
|
||||||
currITutorialStep = iTutorialSteps.CharacterGoToTerminalPage;
|
|
||||||
iTutorialEvaluateStep();
|
|
||||||
break;
|
|
||||||
case iTutorialSteps.TerminalHelp:
|
|
||||||
currITutorialStep = iTutorialSteps.TerminalIntro;
|
|
||||||
iTutorialEvaluateStep();
|
|
||||||
break;
|
|
||||||
case iTutorialSteps.TerminalLs:
|
|
||||||
currITutorialStep = iTutorialSteps.TerminalHelp;
|
|
||||||
iTutorialEvaluateStep();
|
|
||||||
break;
|
|
||||||
case iTutorialSteps.TerminalScan:
|
|
||||||
currITutorialStep = iTutorialSteps.TerminalLs;
|
|
||||||
iTutorialEvaluateStep();
|
|
||||||
break;
|
|
||||||
case iTutorialSteps.TerminalConnect:
|
|
||||||
currITutorialStep = iTutorialSteps.TerminalScan;
|
|
||||||
iTutorialEvaluateStep();
|
|
||||||
break;
|
|
||||||
case iTutorialSteps.TerminalAnalyze:
|
|
||||||
currITutorialStep = iTutorialSteps.TerminalConnect;
|
|
||||||
iTutorialEvaluateStep();
|
|
||||||
break;
|
|
||||||
case iTutorialSteps.TerminalNuke:
|
|
||||||
currITutorialStep = iTutorialSteps.TerminalAnalyze;
|
|
||||||
iTutorialEvaluateStep();
|
|
||||||
break;
|
|
||||||
case iTutorialSteps.TerminalManualHack:
|
|
||||||
currITutorialStep = iTutorialSteps.TerminalNuke;
|
|
||||||
iTutorialEvaluateStep();
|
|
||||||
break;
|
|
||||||
case iTutorialSteps.TerminalHackingMechanics:
|
|
||||||
currITutorialStep = iTutorialSteps.TerminalManualHack;
|
|
||||||
iTutorialEvaluateStep();
|
|
||||||
break;
|
|
||||||
case iTutorialSteps.TerminalCreateScript:
|
|
||||||
currITutorialStep = iTutorialSteps.TerminalManualHack;
|
|
||||||
iTutorialEvaluateStep();
|
|
||||||
break;
|
|
||||||
case iTutorialSteps.TerminalTypeScript:
|
|
||||||
currITutorialStep = iTutorialSteps.TerminalCreateScript;
|
|
||||||
iTutorialEvaluateStep();
|
|
||||||
break;
|
|
||||||
case iTutorialSteps.TerminalFree:
|
|
||||||
currITutorialStep = iTutorialSteps.TerminalTypeScript;
|
|
||||||
iTutorialEvaluateStep();
|
|
||||||
break;
|
|
||||||
case iTutorialSteps.TerminalRunScript:
|
|
||||||
currITutorialStep = iTutorialSteps.TerminalFree;
|
|
||||||
iTutorialEvaluateStep();
|
|
||||||
break;
|
|
||||||
case iTutorialSteps.TerminalGoToActiveScriptsPage:
|
|
||||||
currITutorialStep = iTutorialSteps.TerminalRunScript;
|
|
||||||
iTutorialEvaluateStep();
|
|
||||||
break;
|
|
||||||
case iTutorialSteps.ActiveScriptsPage:
|
|
||||||
currITutorialStep = iTutorialSteps.TerminalGoToActiveScriptsPage;
|
|
||||||
iTutorialEvaluateStep();
|
|
||||||
break;
|
|
||||||
case iTutorialSteps.ActiveScriptsToTerminal:
|
|
||||||
currITutorialStep = iTutorialSteps.ActiveScriptsPage;
|
|
||||||
iTutorialEvaluateStep();
|
|
||||||
break;
|
|
||||||
case iTutorialSteps.TerminalTailScript:
|
|
||||||
currITutorialStep = iTutorialSteps.ActiveScriptsToTerminal;
|
|
||||||
iTutorialEvaluateStep();
|
|
||||||
break;
|
|
||||||
case iTutorialSteps.GoToHacknetNodesPage:
|
|
||||||
currITutorialStep = iTutorialSteps.TerminalTailScript;
|
|
||||||
iTutorialEvaluateStep();
|
|
||||||
break;
|
|
||||||
case iTutorialSteps.HacknetNodesIntroduction:
|
|
||||||
currITutorialStep = iTutorialSteps.GoToHacknetNodesPage;
|
|
||||||
iTutorialEvaluateStep();
|
|
||||||
break;
|
|
||||||
case iTutorialSteps.HacknetNodesGoToWorldPage:
|
|
||||||
currITutorialStep = iTutorialSteps.HacknetNodesIntroduction;
|
|
||||||
iTutorialEvaluateStep();
|
|
||||||
break;
|
|
||||||
case iTutorialSteps.WorldDescription:
|
|
||||||
currITutorialStep = iTutorialSteps.HacknetNodesGoToWorldPage;
|
|
||||||
iTutorialEvaluateStep();
|
|
||||||
break;
|
|
||||||
case iTutorialSteps.TutorialPageInfo:
|
|
||||||
currITutorialStep = iTutorialSteps.WorldDescription;
|
|
||||||
iTutorialEvaluateStep();
|
|
||||||
break;
|
|
||||||
case iTutorialSteps.End:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new Error("Invalid tutorial step");
|
|
||||||
}
|
}
|
||||||
|
iTutorialEvaluateStep();
|
||||||
}
|
}
|
||||||
|
|
||||||
function iTutorialEnd() {
|
function iTutorialEnd() {
|
||||||
//Re-enable auto save
|
//Re-enable auto save
|
||||||
Engine.Counters.autoSaveCounter = 300;
|
if (Settings.AutosaveInterval === 0) {
|
||||||
|
Engine.Counters.autoSaveCounter = Infinity;
|
||||||
|
} else {
|
||||||
|
Engine.Counters.autoSaveCounter = Settings.AutosaveInterval * 5;
|
||||||
|
}
|
||||||
|
|
||||||
console.log("Ending interactive tutorial");
|
console.log("Ending interactive tutorial");
|
||||||
Engine.init();
|
Engine.init();
|
||||||
currITutorialStep = iTutorialSteps.End;
|
ITutorial.currStep = iTutorialSteps.End;
|
||||||
iTutorialIsRunning = false;
|
ITutorial.isRunning = false;
|
||||||
document.getElementById("interactive-tutorial-container").style.display = "none";
|
document.getElementById("interactive-tutorial-container").style.display = "none";
|
||||||
dialogBoxCreate("If you are new to the game, the following links may be useful for you!<br><br>" +
|
|
||||||
|
//Create a popup with final introductory stuff
|
||||||
|
var popupId = "interactive-tutorial-ending-popup";
|
||||||
|
var txt = createElement("p", {
|
||||||
|
innerHTML:
|
||||||
|
"If you are new to the game, the following links may be useful for you!<br><br>" +
|
||||||
"<a class='a-link-button' href='http://bitburner.wikia.com/wiki/Chapt3rs_Guide_to_Getting_Started_with_Bitburner' target='_blank'>Getting Started Guide</a>" +
|
"<a class='a-link-button' href='http://bitburner.wikia.com/wiki/Chapt3rs_Guide_to_Getting_Started_with_Bitburner' target='_blank'>Getting Started Guide</a>" +
|
||||||
"<a class='a-link-button' href='http://bitburner.wikia.com/wiki/Bitburner_Wiki' target='_blank'>Wiki</a><br><br>" +
|
"<a class='a-link-button' href='http://bitburner.wikia.com/wiki/Bitburner_Wiki' target='_blank'>Wiki</a>" +
|
||||||
|
"<a class='a-link-button' href='https://bitburner.readthedocs.io/en/latest/' target='_blank'>Documentation</a><br><br>" +
|
||||||
"The Beginner's Guide to Hacking was added to your home computer! It contains some tips/pointers for starting out with the game. " +
|
"The Beginner's Guide to Hacking was added to your home computer! It contains some tips/pointers for starting out with the game. " +
|
||||||
"To read it, go to Terminal and enter<br><br>cat hackers-starting-handbook.lit");
|
"To read it, go to Terminal and enter<br><br>cat hackers-starting-handbook.lit"
|
||||||
|
});
|
||||||
|
var gotitBtn = createElement("a", {
|
||||||
|
class:"a-link-button", float:"right", padding:"6px", innerText:"Got it!",
|
||||||
|
clickListener:()=>{
|
||||||
|
removeElementById(popupId);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
createPopup(popupId, [txt, gotitBtn]);
|
||||||
|
|
||||||
Player.getHomeComputer().messages.push("hackers-starting-handbook.lit");
|
Player.getHomeComputer().messages.push("hackers-starting-handbook.lit");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -660,5 +506,4 @@ function iTutorialSetText(txt) {
|
|||||||
textBox.parentElement.scrollTop = 0; // this resets scroll position
|
textBox.parentElement.scrollTop = 0; // this resets scroll position
|
||||||
}
|
}
|
||||||
|
|
||||||
export {iTutorialSteps, iTutorialEnd, iTutorialStart, iTutorialNextStep, currITutorialStep,
|
export {iTutorialSteps, iTutorialEnd, iTutorialStart, iTutorialNextStep, ITutorial};
|
||||||
iTutorialIsRunning};
|
|
||||||
|
@ -23,7 +23,11 @@ function initLiterature() {
|
|||||||
var title, fn, txt;
|
var title, fn, txt;
|
||||||
title = "The Beginner's Guide to Hacking";
|
title = "The Beginner's Guide to Hacking";
|
||||||
fn = "hackers-starting-handbook.lit";
|
fn = "hackers-starting-handbook.lit";
|
||||||
txt = "When starting out, hacking is the most profitable way to earn money and progress. This " +
|
txt = "Some resources:<br><br>" +
|
||||||
|
"<a class='a-link-button' href='https://bitburner.readthedocs.io/en/latest/netscriptlearntoprogram.html' target='_blank' style='margin:4px'>Learn to Program</a><br><br>" +
|
||||||
|
"<a class='a-link-button' href='https://bitburner.readthedocs.io/en/latest/netscriptjs.html' target='_blank' style='margin:4px'>For Experienced JavaScript Developers: NetscriptJS</a><br><br>" +
|
||||||
|
"<a class='a-link-button' href='https://bitburner.readthedocs.io/en/latest/netscript.html' target='_blank' style='margin:4px'>Netscript Documentation</a><br><br>" +
|
||||||
|
"When starting out, hacking is the most profitable way to earn money and progress. This " +
|
||||||
"is a brief collection of tips/pointers on how to make the most out of your hacking scripts.<br><br>" +
|
"is a brief collection of tips/pointers on how to make the most out of your hacking scripts.<br><br>" +
|
||||||
"-hack() and grow() both work by percentages. hack() steals a certain percentage of the " +
|
"-hack() and grow() both work by percentages. hack() steals a certain percentage of the " +
|
||||||
"money on a server, and grow() increases the amount of money on a server by some percentage (multiplicatively)<br><br>" +
|
"money on a server, and grow() increases the amount of money on a server by some percentage (multiplicatively)<br><br>" +
|
||||||
|
@ -911,61 +911,5 @@ function isScriptErrorMessage(msg) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//The same as Player's calculateHackingChance() function but takes in the server as an argument
|
export {makeRuntimeRejectMsg, netscriptDelay, runScriptFromScript, evaluate,
|
||||||
function scriptCalculateHackingChance(server) {
|
|
||||||
var difficultyMult = (100 - server.hackDifficulty) / 100;
|
|
||||||
var skillMult = (1.75 * Player.hacking_skill) + (0.2 * Player.intelligence);
|
|
||||||
var skillChance = (skillMult - server.requiredHackingSkill) / skillMult;
|
|
||||||
var chance = skillChance * difficultyMult * Player.hacking_chance_mult;
|
|
||||||
if (chance > 1) {return 1;}
|
|
||||||
if (chance < 0) {return 0;}
|
|
||||||
else {return chance;}
|
|
||||||
}
|
|
||||||
|
|
||||||
//The same as Player's calculateHackingTime() function but takes in the server as an argument
|
|
||||||
function scriptCalculateHackingTime(server) {
|
|
||||||
var difficultyMult = server.requiredHackingSkill * server.hackDifficulty;
|
|
||||||
var skillFactor = (2.5 * difficultyMult + 500) / (Player.hacking_skill + 50 + (0.1 * Player.intelligence));
|
|
||||||
var hackingTime = 5 * skillFactor / Player.hacking_speed_mult; //This is in seconds
|
|
||||||
return hackingTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
//The same as Player's calculateExpGain() function but takes in the server as an argument
|
|
||||||
function scriptCalculateExpGain(server) {
|
|
||||||
if (server.baseDifficulty == null) {
|
|
||||||
server.baseDifficulty = server.hackDifficulty;
|
|
||||||
}
|
|
||||||
return (server.baseDifficulty * Player.hacking_exp_mult * 0.3 + 3) * BitNodeMultipliers.HackExpGain;
|
|
||||||
}
|
|
||||||
|
|
||||||
//The same as Player's calculatePercentMoneyHacked() function but takes in the server as an argument
|
|
||||||
function scriptCalculatePercentMoneyHacked(server) {
|
|
||||||
var difficultyMult = (100 - server.hackDifficulty) / 100;
|
|
||||||
var skillMult = (Player.hacking_skill - (server.requiredHackingSkill - 1)) / Player.hacking_skill;
|
|
||||||
var percentMoneyHacked = difficultyMult * skillMult * Player.hacking_money_mult / 240;
|
|
||||||
if (percentMoneyHacked < 0) {return 0;}
|
|
||||||
if (percentMoneyHacked > 1) {return 1;}
|
|
||||||
return percentMoneyHacked * BitNodeMultipliers.ScriptHackMoney;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Amount of time to execute grow() in milliseconds
|
|
||||||
function scriptCalculateGrowTime(server) {
|
|
||||||
var difficultyMult = server.requiredHackingSkill * server.hackDifficulty;
|
|
||||||
var skillFactor = (2.5 * difficultyMult + 500) / (Player.hacking_skill + 50 + (0.1 * Player.intelligence));
|
|
||||||
var growTime = 16 * skillFactor / Player.hacking_speed_mult; //This is in seconds
|
|
||||||
return growTime * 1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Amount of time to execute weaken() in milliseconds
|
|
||||||
function scriptCalculateWeakenTime(server) {
|
|
||||||
var difficultyMult = server.requiredHackingSkill * server.hackDifficulty;
|
|
||||||
var skillFactor = (2.5 * difficultyMult + 500) / (Player.hacking_skill + 50 + (0.1 * Player.intelligence));
|
|
||||||
var weakenTime = 20 * skillFactor / Player.hacking_speed_mult; //This is in seconds
|
|
||||||
return weakenTime * 1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
export {makeRuntimeRejectMsg, netscriptDelay, runScriptFromScript,
|
|
||||||
scriptCalculateHackingChance, scriptCalculateHackingTime,
|
|
||||||
scriptCalculateExpGain, scriptCalculatePercentMoneyHacked,
|
|
||||||
scriptCalculateGrowTime, scriptCalculateWeakenTime, evaluate,
|
|
||||||
isScriptErrorMessage, killNetscriptDelay, evaluateImport};
|
isScriptErrorMessage, killNetscriptDelay, evaluateImport};
|
||||||
|
@ -13,6 +13,12 @@ import {Companies, Company, CompanyPosition,
|
|||||||
import {CONSTANTS} from "./Constants";
|
import {CONSTANTS} from "./Constants";
|
||||||
import {Programs} from "./CreateProgram";
|
import {Programs} from "./CreateProgram";
|
||||||
import {DarkWebItems} from "./DarkWeb";
|
import {DarkWebItems} from "./DarkWeb";
|
||||||
|
import {calculateHackingChance,
|
||||||
|
calculateHackingExpGain,
|
||||||
|
calculatePercentMoneyHacked,
|
||||||
|
calculateHackingTime,
|
||||||
|
calculateGrowTime,
|
||||||
|
calculateWeakenTime} from "./Hacking";
|
||||||
import {AllGangs} from "./Gang";
|
import {AllGangs} from "./Gang";
|
||||||
import {Factions, Faction, joinFaction,
|
import {Factions, Faction, joinFaction,
|
||||||
factionExists, purchaseAugmentation} from "./Faction";
|
factionExists, purchaseAugmentation} from "./Faction";
|
||||||
@ -28,11 +34,12 @@ import {Server, getServer, AddToAllServers,
|
|||||||
GetServerByHostname} from "./Server";
|
GetServerByHostname} from "./Server";
|
||||||
import {Settings} from "./Settings";
|
import {Settings} from "./Settings";
|
||||||
import {SpecialServerIps} from "./SpecialServerIps";
|
import {SpecialServerIps} from "./SpecialServerIps";
|
||||||
|
import {Stock} from "./Stock";
|
||||||
import {StockMarket, StockSymbols, SymbolToStockMap, initStockSymbols,
|
import {StockMarket, StockSymbols, SymbolToStockMap, initStockSymbols,
|
||||||
initStockMarket, initSymbolToStockMap, stockMarketCycle, buyStock,
|
initStockMarket, initSymbolToStockMap, stockMarketCycle, buyStock,
|
||||||
sellStock, updateStockPrices, displayStockMarketContent,
|
sellStock, updateStockPrices, displayStockMarketContent,
|
||||||
updateStockTicker, updateStockPlayerPosition,
|
updateStockTicker, updateStockPlayerPosition,
|
||||||
Stock, shortStock, sellShort, OrderTypes,
|
shortStock, sellShort, OrderTypes,
|
||||||
PositionTypes, placeOrder, cancelOrder} from "./StockMarket";
|
PositionTypes, placeOrder, cancelOrder} from "./StockMarket";
|
||||||
import {post} from "./ui/postToTerminal";
|
import {post} from "./ui/postToTerminal";
|
||||||
import {TextFile, getTextFile, createTextFile} from "./TextFile";
|
import {TextFile, getTextFile, createTextFile} from "./TextFile";
|
||||||
@ -42,10 +49,8 @@ import {unknownBladeburnerActionErrorMessage,
|
|||||||
checkBladeburnerAccess} from "./NetscriptBladeburner.js";
|
checkBladeburnerAccess} from "./NetscriptBladeburner.js";
|
||||||
import {WorkerScript, workerScripts,
|
import {WorkerScript, workerScripts,
|
||||||
killWorkerScript, NetscriptPorts} from "./NetscriptWorker";
|
killWorkerScript, NetscriptPorts} from "./NetscriptWorker";
|
||||||
import {makeRuntimeRejectMsg, netscriptDelay, runScriptFromScript,
|
import {makeRuntimeRejectMsg, netscriptDelay,
|
||||||
scriptCalculateHackingChance, scriptCalculateHackingTime,
|
runScriptFromScript} from "./NetscriptEvaluator";
|
||||||
scriptCalculateExpGain, scriptCalculatePercentMoneyHacked,
|
|
||||||
scriptCalculateGrowTime, scriptCalculateWeakenTime} from "./NetscriptEvaluator";
|
|
||||||
import {NetscriptPort} from "./NetscriptPort";
|
import {NetscriptPort} from "./NetscriptPort";
|
||||||
|
|
||||||
import Decimal from "decimal.js";
|
import Decimal from "decimal.js";
|
||||||
@ -292,7 +297,7 @@ function NetscriptFunctions(workerScript) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Calculate the hacking time
|
//Calculate the hacking time
|
||||||
var hackingTime = scriptCalculateHackingTime(server); //This is in seconds
|
var hackingTime = calculateHackingTime(server); //This is in seconds
|
||||||
|
|
||||||
//No root access or skill level too low
|
//No root access or skill level too low
|
||||||
if (server.hasAdminRights == false) {
|
if (server.hasAdminRights == false) {
|
||||||
@ -310,12 +315,12 @@ function NetscriptFunctions(workerScript) {
|
|||||||
}
|
}
|
||||||
return netscriptDelay(hackingTime * 1000, workerScript).then(function() {
|
return netscriptDelay(hackingTime * 1000, workerScript).then(function() {
|
||||||
if (workerScript.env.stopFlag) {return Promise.reject(workerScript);}
|
if (workerScript.env.stopFlag) {return Promise.reject(workerScript);}
|
||||||
var hackChance = scriptCalculateHackingChance(server);
|
var hackChance = calculateHackingChance(server);
|
||||||
var rand = Math.random();
|
var rand = Math.random();
|
||||||
var expGainedOnSuccess = scriptCalculateExpGain(server) * threads;
|
var expGainedOnSuccess = calculateHackingExpGain(server) * threads;
|
||||||
var expGainedOnFailure = (expGainedOnSuccess / 4);
|
var expGainedOnFailure = (expGainedOnSuccess / 4);
|
||||||
if (rand < hackChance) { //Success!
|
if (rand < hackChance) { //Success!
|
||||||
const percentHacked = scriptCalculatePercentMoneyHacked(server);
|
const percentHacked = calculatePercentMoneyHacked(server);
|
||||||
let maxThreadNeeded = Math.ceil(1/percentHacked*(server.moneyAvailable/server.moneyMax));
|
let maxThreadNeeded = Math.ceil(1/percentHacked*(server.moneyAvailable/server.moneyMax));
|
||||||
if (isNaN(maxThreadNeeded)) {
|
if (isNaN(maxThreadNeeded)) {
|
||||||
//Server has a 'max money' of 0 (probably).
|
//Server has a 'max money' of 0 (probably).
|
||||||
@ -390,18 +395,18 @@ function NetscriptFunctions(workerScript) {
|
|||||||
throw makeRuntimeRejectMsg(workerScript, "Cannot grow this server (" + server.hostname + ") because user does not have root access");
|
throw makeRuntimeRejectMsg(workerScript, "Cannot grow this server (" + server.hostname + ") because user does not have root access");
|
||||||
}
|
}
|
||||||
|
|
||||||
var growTime = scriptCalculateGrowTime(server);
|
var growTime = calculateGrowTime(server);
|
||||||
if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.grow == null) {
|
if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.grow == null) {
|
||||||
workerScript.scriptRef.log("Executing grow() on server " + server.hostname + " in " + formatNumber(growTime/1000, 3) + " seconds (t=" + threads + ")");
|
workerScript.scriptRef.log("Executing grow() on server " + server.hostname + " in " + formatNumber(growTime, 3) + " seconds (t=" + threads + ")");
|
||||||
}
|
}
|
||||||
return netscriptDelay(growTime, workerScript).then(function() {
|
return netscriptDelay(growTime * 1000, workerScript).then(function() {
|
||||||
if (workerScript.env.stopFlag) {return Promise.reject(workerScript);}
|
if (workerScript.env.stopFlag) {return Promise.reject(workerScript);}
|
||||||
const moneyBefore = server.moneyAvailable;
|
const moneyBefore = server.moneyAvailable;
|
||||||
server.moneyAvailable += (1 * threads); //It can be grown even if it has no money
|
server.moneyAvailable += (1 * threads); //It can be grown even if it has no money
|
||||||
var growthPercentage = processSingleServerGrowth(server, 450 * threads);
|
var growthPercentage = processSingleServerGrowth(server, 450 * threads);
|
||||||
const moneyAfter = server.moneyAvailable;
|
const moneyAfter = server.moneyAvailable;
|
||||||
workerScript.scriptRef.recordGrow(server.ip, threads);
|
workerScript.scriptRef.recordGrow(server.ip, threads);
|
||||||
var expGain = scriptCalculateExpGain(server) * threads;
|
var expGain = calculateHackingExpGain(server) * threads;
|
||||||
if (growthPercentage == 1) {
|
if (growthPercentage == 1) {
|
||||||
expGain = 0;
|
expGain = 0;
|
||||||
}
|
}
|
||||||
@ -437,16 +442,16 @@ function NetscriptFunctions(workerScript) {
|
|||||||
throw makeRuntimeRejectMsg(workerScript, "Cannot weaken this server (" + server.hostname + ") because user does not have root access");
|
throw makeRuntimeRejectMsg(workerScript, "Cannot weaken this server (" + server.hostname + ") because user does not have root access");
|
||||||
}
|
}
|
||||||
|
|
||||||
var weakenTime = scriptCalculateWeakenTime(server);
|
var weakenTime = calculateWeakenTime(server);
|
||||||
if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.weaken == null) {
|
if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.weaken == null) {
|
||||||
workerScript.scriptRef.log("Executing weaken() on server " + server.hostname + " in " +
|
workerScript.scriptRef.log("Executing weaken() on server " + server.hostname + " in " +
|
||||||
formatNumber(weakenTime/1000, 3) + " seconds (t=" + threads + ")");
|
formatNumber(weakenTime, 3) + " seconds (t=" + threads + ")");
|
||||||
}
|
}
|
||||||
return netscriptDelay(weakenTime, workerScript).then(function() {
|
return netscriptDelay(weakenTime * 1000, workerScript).then(function() {
|
||||||
if (workerScript.env.stopFlag) {return Promise.reject(workerScript);}
|
if (workerScript.env.stopFlag) {return Promise.reject(workerScript);}
|
||||||
server.weaken(CONSTANTS.ServerWeakenAmount * threads);
|
server.weaken(CONSTANTS.ServerWeakenAmount * threads);
|
||||||
workerScript.scriptRef.recordWeaken(server.ip, threads);
|
workerScript.scriptRef.recordWeaken(server.ip, threads);
|
||||||
var expGain = scriptCalculateExpGain(server) * threads;
|
var expGain = calculateHackingExpGain(server) * threads;
|
||||||
if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.weaken == null) {
|
if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.weaken == null) {
|
||||||
workerScript.scriptRef.log("Server security level on " + server.hostname + " weakened to " + server.hackDifficulty +
|
workerScript.scriptRef.log("Server security level on " + server.hostname + " weakened to " + server.hackDifficulty +
|
||||||
". Gained " + formatNumber(expGain, 4) + " hacking exp (t=" + threads + ")");
|
". Gained " + formatNumber(expGain, 4) + " hacking exp (t=" + threads + ")");
|
||||||
@ -1843,6 +1848,25 @@ function NetscriptFunctions(workerScript) {
|
|||||||
throw makeRuntimeRejectMsg(workerScript, "Invalid argument passed in for write: " + port);
|
throw makeRuntimeRejectMsg(workerScript, "Invalid argument passed in for write: " + port);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
tryWrite : function(port, data="") {
|
||||||
|
if (workerScript.checkingRam) {
|
||||||
|
return updateStaticRam("tryWrite", CONSTANTS.ScriptReadWriteRamCost);
|
||||||
|
}
|
||||||
|
updateDynamicRam("tryWrite", CONSTANTS.ScriptReadWriteRamCost);
|
||||||
|
if (!isNaN(port)) {
|
||||||
|
port = Math.round(port);
|
||||||
|
if (port < 1 || port > CONSTANTS.NumNetscriptPorts) {
|
||||||
|
throw makeRuntimeRejectMsg(workerScript, "ERROR: tryWrite() called on invalid port: " + port + ". Only ports 1-" + CONSTANTS.NumNetscriptPorts + " are valid.");
|
||||||
|
}
|
||||||
|
var port = NetscriptPorts[port-1];
|
||||||
|
if (port == null || !(port instanceof NetscriptPort)) {
|
||||||
|
throw makeRuntimeRejectMsg(workerScript, "Could not find port: " + port + ". This is a bug contact the game developer");
|
||||||
|
}
|
||||||
|
return port.tryWrite(data);
|
||||||
|
} else {
|
||||||
|
throw makeRuntimeRejectMsg(workerScript, "Invalid argument passed in for tryWrite: " + port);
|
||||||
|
}
|
||||||
|
},
|
||||||
read : function(port) {
|
read : function(port) {
|
||||||
if (workerScript.checkingRam) {
|
if (workerScript.checkingRam) {
|
||||||
return updateStaticRam("read", CONSTANTS.ScriptReadWriteRamCost);
|
return updateStaticRam("read", CONSTANTS.ScriptReadWriteRamCost);
|
||||||
@ -2057,7 +2081,7 @@ function NetscriptFunctions(workerScript) {
|
|||||||
workerScript.scriptRef.log("getHackTime() failed. Invalid IP or hostname passed in: " + ip);
|
workerScript.scriptRef.log("getHackTime() failed. Invalid IP or hostname passed in: " + ip);
|
||||||
throw makeRuntimeRejectMsg(workerScript, "getHackTime() failed. Invalid IP or hostname passed in: " + ip);
|
throw makeRuntimeRejectMsg(workerScript, "getHackTime() failed. Invalid IP or hostname passed in: " + ip);
|
||||||
}
|
}
|
||||||
return scriptCalculateHackingTime(server); //Returns seconds
|
return calculateHackingTime(server); //Returns seconds
|
||||||
},
|
},
|
||||||
getGrowTime : function(ip) {
|
getGrowTime : function(ip) {
|
||||||
if (workerScript.checkingRam) {
|
if (workerScript.checkingRam) {
|
||||||
@ -2069,7 +2093,7 @@ function NetscriptFunctions(workerScript) {
|
|||||||
workerScript.scriptRef.log("getGrowTime() failed. Invalid IP or hostname passed in: " + ip);
|
workerScript.scriptRef.log("getGrowTime() failed. Invalid IP or hostname passed in: " + ip);
|
||||||
throw makeRuntimeRejectMsg(workerScript, "getGrowTime() failed. Invalid IP or hostname passed in: " + ip);
|
throw makeRuntimeRejectMsg(workerScript, "getGrowTime() failed. Invalid IP or hostname passed in: " + ip);
|
||||||
}
|
}
|
||||||
return scriptCalculateGrowTime(server) / 1000; //Returns seconds
|
return calculateGrowTime(server); //Returns seconds
|
||||||
},
|
},
|
||||||
getWeakenTime : function(ip) {
|
getWeakenTime : function(ip) {
|
||||||
if (workerScript.checkingRam) {
|
if (workerScript.checkingRam) {
|
||||||
@ -2081,7 +2105,7 @@ function NetscriptFunctions(workerScript) {
|
|||||||
workerScript.scriptRef.log("getWeakenTime() failed. Invalid IP or hostname passed in: " + ip);
|
workerScript.scriptRef.log("getWeakenTime() failed. Invalid IP or hostname passed in: " + ip);
|
||||||
throw makeRuntimeRejectMsg(workerScript, "getWeakenTime() failed. Invalid IP or hostname passed in: " + ip);
|
throw makeRuntimeRejectMsg(workerScript, "getWeakenTime() failed. Invalid IP or hostname passed in: " + ip);
|
||||||
}
|
}
|
||||||
return scriptCalculateWeakenTime(server) / 1000; //Returns seconds
|
return calculateWeakenTime(server); //Returns seconds
|
||||||
},
|
},
|
||||||
getScriptIncome : function(scriptname, ip) {
|
getScriptIncome : function(scriptname, ip) {
|
||||||
if (workerScript.checkingRam) {
|
if (workerScript.checkingRam) {
|
||||||
|
507
src/Player.js
507
src/Player.js
@ -30,6 +30,8 @@ import numeral from "numeral/min/numeral.min";
|
|||||||
import {formatNumber,
|
import {formatNumber,
|
||||||
convertTimeMsToTimeElapsedString} from "../utils/StringHelperFunctions";
|
convertTimeMsToTimeElapsedString} from "../utils/StringHelperFunctions";
|
||||||
|
|
||||||
|
const CYCLES_PER_SEC = 1000 / CONSTANTS.MilliPerCycle;
|
||||||
|
|
||||||
function PlayerObject() {
|
function PlayerObject() {
|
||||||
//Skills and stats
|
//Skills and stats
|
||||||
this.hacking_skill = 1;
|
this.hacking_skill = 1;
|
||||||
@ -119,11 +121,6 @@ function PlayerObject() {
|
|||||||
this.crime_money_mult = 1;
|
this.crime_money_mult = 1;
|
||||||
this.crime_success_mult = 1;
|
this.crime_success_mult = 1;
|
||||||
|
|
||||||
//Flag to let the engine know the player is starting an action
|
|
||||||
// Current actions: hack, analyze
|
|
||||||
this.startAction = false;
|
|
||||||
this.actionTime = 0;
|
|
||||||
|
|
||||||
//Flags/variables for working (Company, Faction, Creating Program, Taking Class)
|
//Flags/variables for working (Company, Faction, Creating Program, Taking Class)
|
||||||
this.isWorking = false;
|
this.isWorking = false;
|
||||||
this.workType = "";
|
this.workType = "";
|
||||||
@ -265,9 +262,6 @@ PlayerObject.prototype.prestigeAugmentation = function() {
|
|||||||
|
|
||||||
this.queuedAugmentations = [];
|
this.queuedAugmentations = [];
|
||||||
|
|
||||||
this.startAction = false;
|
|
||||||
this.actionTime = 0;
|
|
||||||
|
|
||||||
this.isWorking = false;
|
this.isWorking = false;
|
||||||
this.currentWorkFactionName = "";
|
this.currentWorkFactionName = "";
|
||||||
this.currentWorkFactionDescription = "";
|
this.currentWorkFactionDescription = "";
|
||||||
@ -349,9 +343,6 @@ PlayerObject.prototype.prestigeSourceFile = function() {
|
|||||||
this.queuedAugmentations = [];
|
this.queuedAugmentations = [];
|
||||||
this.augmentations = [];
|
this.augmentations = [];
|
||||||
|
|
||||||
this.startAction = false;
|
|
||||||
this.actionTime = 0;
|
|
||||||
|
|
||||||
this.isWorking = false;
|
this.isWorking = false;
|
||||||
this.currentWorkFactionName = "";
|
this.currentWorkFactionName = "";
|
||||||
this.currentWorkFactionDescription = "";
|
this.currentWorkFactionDescription = "";
|
||||||
@ -498,74 +489,10 @@ PlayerObject.prototype.resetMultipliers = function() {
|
|||||||
this.bladeburner_success_chance_mult = 1;
|
this.bladeburner_success_chance_mult = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Calculates the chance of hacking a server
|
|
||||||
//The formula is:
|
|
||||||
// (2 * hacking_chance_multiplier * hacking_skill - requiredLevel) 100 - difficulty
|
|
||||||
// ----------------------------------------------------------- * -----------------
|
|
||||||
// (2 * hacking_chance_multiplier * hacking_skill) 100
|
|
||||||
PlayerObject.prototype.calculateHackingChance = function() {
|
|
||||||
var difficultyMult = (100 - this.getCurrentServer().hackDifficulty) / 100;
|
|
||||||
var skillMult = (1.75 * this.hacking_skill) + (0.2 * this.intelligence);
|
|
||||||
var skillChance = (skillMult - this.getCurrentServer().requiredHackingSkill) / skillMult;
|
|
||||||
var chance = skillChance * difficultyMult * this.hacking_chance_mult;
|
|
||||||
if (chance > 1) {return 1;}
|
|
||||||
if (chance < 0) {return 0;}
|
|
||||||
return chance;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Calculate the time it takes to hack a server in seconds. Returns the time
|
|
||||||
//The formula is:
|
|
||||||
// (2.5 * requiredLevel * difficulty + 200)
|
|
||||||
// ----------------------------------- * hacking_speed_multiplier
|
|
||||||
// hacking_skill + 100
|
|
||||||
PlayerObject.prototype.calculateHackingTime = function() {
|
|
||||||
var difficultyMult = this.getCurrentServer().requiredHackingSkill * this.getCurrentServer().hackDifficulty;
|
|
||||||
var skillFactor = (2.5 * difficultyMult + 200) / (this.hacking_skill + 100 + (0.1 * this.intelligence));
|
|
||||||
return 5 * skillFactor / this.hacking_speed_mult;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Calculates the PERCENTAGE of a server's money that the player will hack from the server if successful
|
|
||||||
//The formula is:
|
|
||||||
// (hacking_skill - (requiredLevel-1)) 100 - difficulty
|
|
||||||
// --------------------------------------* ----------------------- * hacking_money_multiplier
|
|
||||||
// hacking_skill 100
|
|
||||||
PlayerObject.prototype.calculatePercentMoneyHacked = function() {
|
|
||||||
var difficultyMult = (100 - this.getCurrentServer().hackDifficulty) / 100;
|
|
||||||
var skillMult = (this.hacking_skill - (this.getCurrentServer().requiredHackingSkill - 1)) / this.hacking_skill;
|
|
||||||
var percentMoneyHacked = difficultyMult * skillMult * this.hacking_money_mult / 240;
|
|
||||||
console.log("Percent money hacked calculated to be: " + percentMoneyHacked);
|
|
||||||
if (percentMoneyHacked < 0) {return 0;}
|
|
||||||
if (percentMoneyHacked > 1) {return 1;}
|
|
||||||
return percentMoneyHacked * BitNodeMultipliers.ManualHackMoney;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Returns how much EXP the player gains on a successful hack
|
|
||||||
//The formula is:
|
|
||||||
// difficulty * requiredLevel * hacking_multiplier
|
|
||||||
PlayerObject.prototype.calculateExpGain = function() {
|
|
||||||
var s = this.getCurrentServer();
|
|
||||||
if (s.baseDifficulty == null) {
|
|
||||||
s.baseDifficulty = s.hackDifficulty;
|
|
||||||
}
|
|
||||||
return (s.baseDifficulty * this.hacking_exp_mult * 0.3 + 3) * BitNodeMultipliers.HackExpGain;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Hack/Analyze a server. Return the amount of time the hack will take. This lets the Terminal object know how long to disable itself for
|
|
||||||
//This assumes that the server being hacked is not purchased by the player, that the player's hacking skill is greater than the
|
|
||||||
//required hacking skill and that the player has admin rights.
|
|
||||||
PlayerObject.prototype.hack = function() {
|
|
||||||
this.actionTime = this.calculateHackingTime();
|
|
||||||
console.log("Hacking time: " + this.actionTime);
|
|
||||||
this.startAction = true; //Set the startAction flag so the engine starts the hacking process
|
|
||||||
}
|
|
||||||
|
|
||||||
PlayerObject.prototype.analyze = function() {
|
|
||||||
this.actionTime = 1;
|
|
||||||
this.startAction = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
PlayerObject.prototype.hasProgram = function(programName) {
|
PlayerObject.prototype.hasProgram = function(programName) {
|
||||||
var home = Player.getHomeComputer();
|
var home = Player.getHomeComputer();
|
||||||
|
if (home == null) {return false;}
|
||||||
|
|
||||||
for (var i = 0; i < home.programs.length; ++i) {
|
for (var i = 0; i < home.programs.length; ++i) {
|
||||||
if (programName.toLowerCase() == home.programs[i].toLowerCase()) {return true;}
|
if (programName.toLowerCase() == home.programs[i].toLowerCase()) {return true;}
|
||||||
}
|
}
|
||||||
@ -688,6 +615,7 @@ PlayerObject.prototype.resetWorkStatus = function() {
|
|||||||
this.workChaExpGainRate = 0;
|
this.workChaExpGainRate = 0;
|
||||||
this.workRepGainRate = 0;
|
this.workRepGainRate = 0;
|
||||||
this.workMoneyGainRate = 0;
|
this.workMoneyGainRate = 0;
|
||||||
|
this.workMoneyLossRate = 0;
|
||||||
|
|
||||||
this.workHackExpGained = 0;
|
this.workHackExpGained = 0;
|
||||||
this.workStrExpGained = 0;
|
this.workStrExpGained = 0;
|
||||||
@ -709,24 +637,109 @@ PlayerObject.prototype.resetWorkStatus = function() {
|
|||||||
document.getElementById("work-in-progress-text").innerHTML = "";
|
document.getElementById("work-in-progress-text").innerHTML = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
PlayerObject.prototype.gainWorkExp = function() {
|
PlayerObject.prototype.processWorkEarnings = function(numCycles=1) {
|
||||||
this.gainHackingExp(this.workHackExpGained);
|
var hackExpGain = this.workHackExpGainRate * numCycles;
|
||||||
this.gainStrengthExp(this.workStrExpGained);
|
var strExpGain = this.workStrExpGainRate * numCycles;
|
||||||
this.gainDefenseExp(this.workDefExpGained);
|
var defExpGain = this.workDefExpGainRate * numCycles;
|
||||||
this.gainDexterityExp(this.workDexExpGained);
|
var dexExpGain = this.workDexExpGainRate * numCycles;
|
||||||
this.gainAgilityExp(this.workAgiExpGained);
|
var agiExpGain = this.workAgiExpGainRate * numCycles;
|
||||||
this.gainCharismaExp(this.workChaExpGained);
|
var chaExpGain = this.workChaExpGainRate * numCycles;
|
||||||
|
|
||||||
|
this.gainHackingExp(hackExpGain);
|
||||||
|
this.gainStrengthExp(strExpGain);
|
||||||
|
this.gainDefenseExp(defExpGain);
|
||||||
|
this.gainDexterityExp(dexExpGain);
|
||||||
|
this.gainAgilityExp(agiExpGain);
|
||||||
|
this.gainCharismaExp(chaExpGain);
|
||||||
|
this.workHackExpGained += hackExpGain;
|
||||||
|
this.workStrExpGained += strExpGain;
|
||||||
|
this.workDefExpGained += defExpGain;
|
||||||
|
this.workDexExpGained += dexExpGain;
|
||||||
|
this.workAgiExpGained += agiExpGain;
|
||||||
|
this.workChaExpGained += chaExpGain;
|
||||||
|
this.workRepGained += this.workRepGainRate * numCycles;
|
||||||
|
this.workMoneyGained += this.workMoneyGainRate * numCycles;
|
||||||
|
this.workMoneyGained -= this.workMoneyLossRate * numCycles;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Working for Company */
|
/* Working for Company */
|
||||||
|
PlayerObject.prototype.startWork = function() {
|
||||||
|
this.resetWorkStatus();
|
||||||
|
this.isWorking = true;
|
||||||
|
this.workType = CONSTANTS.WorkTypeCompany;
|
||||||
|
|
||||||
|
this.workHackExpGainRate = this.getWorkHackExpGain();
|
||||||
|
this.workStrExpGainRate = this.getWorkStrExpGain();
|
||||||
|
this.workDefExpGainRate = this.getWorkDefExpGain();
|
||||||
|
this.workDexExpGainRate = this.getWorkDexExpGain();
|
||||||
|
this.workAgiExpGainRate = this.getWorkAgiExpGain();
|
||||||
|
this.workChaExpGainRate = this.getWorkChaExpGain();
|
||||||
|
this.workRepGainRate = this.getWorkRepGain();
|
||||||
|
this.workMoneyGainRate = this.getWorkMoneyGain();
|
||||||
|
|
||||||
|
this.timeNeededToCompleteWork = CONSTANTS.MillisecondsPer8Hours;
|
||||||
|
|
||||||
|
//Remove all old event listeners from Cancel button
|
||||||
|
var newCancelButton = clearEventListeners("work-in-progress-cancel-button");
|
||||||
|
newCancelButton.innerHTML = "Cancel Work";
|
||||||
|
newCancelButton.addEventListener("click", function() {
|
||||||
|
Player.finishWork(true);
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
//Display Work In Progress Screen
|
||||||
|
Engine.loadWorkInProgressContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
PlayerObject.prototype.work = function(numCycles) {
|
||||||
|
//Cap the number of cycles being processed to whatever would put you at
|
||||||
|
//the work time limit (8 hours)
|
||||||
|
var overMax = false;
|
||||||
|
if (this.timeWorked + (Engine._idleSpeed * numCycles) >= CONSTANTS.MillisecondsPer8Hours) {
|
||||||
|
overMax = true;
|
||||||
|
numCycles = Math.round((CONSTANTS.MillisecondsPer8Hours - this.timeWorked) / Engine._idleSpeed);
|
||||||
|
}
|
||||||
|
this.timeWorked += Engine._idleSpeed * numCycles;
|
||||||
|
|
||||||
|
this.workRepGainRate = this.getWorkRepGain();
|
||||||
|
this.processWorkEarnings(numCycles);
|
||||||
|
|
||||||
|
//If timeWorked == 8 hours, then finish. You can only gain 8 hours worth of exp and money
|
||||||
|
if (overMax || this.timeWorked >= CONSTANTS.MillisecondsPer8Hours) {
|
||||||
|
return this.finishWork(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
var comp = Companies[this.companyName], companyRep = "0";
|
||||||
|
if (comp == null || !(comp instanceof Company)) {
|
||||||
|
console.log("ERROR: Could not find Company: " + this.companyName);
|
||||||
|
} else {
|
||||||
|
companyRep = comp.playerReputation;
|
||||||
|
}
|
||||||
|
|
||||||
|
var txt = document.getElementById("work-in-progress-text");
|
||||||
|
txt.innerHTML = "You are currently working as a " + this.companyPosition.positionName +
|
||||||
|
" at " + this.companyName + " (Current Company Reputation: " +
|
||||||
|
formatNumber(companyRep, 0) + ")<br><br>" +
|
||||||
|
"You have been working for " + convertTimeMsToTimeElapsedString(this.timeWorked) + "<br><br>" +
|
||||||
|
"You have earned: <br><br>" +
|
||||||
|
"$" + formatNumber(this.workMoneyGained, 2) + " ($" + formatNumber(this.workMoneyGainRate * CYCLES_PER_SEC, 2) + " / sec) <br><br>" +
|
||||||
|
formatNumber(this.workRepGained, 4) + " (" + formatNumber(this.workRepGainRate * CYCLES_PER_SEC, 4) + " / sec) reputation for this company <br><br>" +
|
||||||
|
formatNumber(this.workHackExpGained, 4) + " (" + formatNumber(this.workHackExpGainRate * CYCLES_PER_SEC, 4) + " / sec) hacking exp <br><br>" +
|
||||||
|
formatNumber(this.workStrExpGained, 4) + " (" + formatNumber(this.workStrExpGainRate * CYCLES_PER_SEC, 4) + " / sec) strength exp <br>" +
|
||||||
|
formatNumber(this.workDefExpGained, 4) + " (" + formatNumber(this.workDefExpGainRate * CYCLES_PER_SEC, 4) + " / sec) defense exp <br>" +
|
||||||
|
formatNumber(this.workDexExpGained, 4) + " (" + formatNumber(this.workDexExpGainRate * CYCLES_PER_SEC, 4) + " / sec) dexterity exp <br>" +
|
||||||
|
formatNumber(this.workAgiExpGained, 4) + " (" + formatNumber(this.workAgiExpGainRate * CYCLES_PER_SEC, 4) + " / sec) agility exp <br><br> " +
|
||||||
|
formatNumber(this.workChaExpGained, 4) + " (" + formatNumber(this.workChaExpGainRate * CYCLES_PER_SEC, 4) + " / sec) charisma exp <br><br>" +
|
||||||
|
"You will automatically finish after working for 8 hours. You can cancel earlier if you wish, " +
|
||||||
|
"but you will only gain half of the reputation you've earned so far."
|
||||||
|
}
|
||||||
|
|
||||||
PlayerObject.prototype.finishWork = function(cancelled, sing=false) {
|
PlayerObject.prototype.finishWork = function(cancelled, sing=false) {
|
||||||
//Since the work was cancelled early, player only gains half of what they've earned so far
|
//Since the work was cancelled early, player only gains half of what they've earned so far
|
||||||
if (cancelled) {
|
if (cancelled) {
|
||||||
this.workRepGained /= 2;
|
this.workRepGained /= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.gainWorkExp();
|
|
||||||
|
|
||||||
var company = Companies[this.companyName];
|
var company = Companies[this.companyName];
|
||||||
company.playerReputation += (this.workRepGained);
|
company.playerReputation += (this.workRepGained);
|
||||||
|
|
||||||
@ -773,91 +786,6 @@ PlayerObject.prototype.finishWork = function(cancelled, sing=false) {
|
|||||||
this.resetWorkStatus();
|
this.resetWorkStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
PlayerObject.prototype.startWork = function() {
|
|
||||||
this.resetWorkStatus();
|
|
||||||
this.isWorking = true;
|
|
||||||
this.workType = CONSTANTS.WorkTypeCompany;
|
|
||||||
|
|
||||||
this.workHackExpGainRate = this.getWorkHackExpGain();
|
|
||||||
this.workStrExpGainRate = this.getWorkStrExpGain();
|
|
||||||
this.workDefExpGainRate = this.getWorkDefExpGain();
|
|
||||||
this.workDexExpGainRate = this.getWorkDexExpGain();
|
|
||||||
this.workAgiExpGainRate = this.getWorkAgiExpGain();
|
|
||||||
this.workChaExpGainRate = this.getWorkChaExpGain();
|
|
||||||
this.workRepGainRate = this.getWorkRepGain();
|
|
||||||
this.workMoneyGainRate = this.getWorkMoneyGain();
|
|
||||||
|
|
||||||
this.timeNeededToCompleteWork = CONSTANTS.MillisecondsPer8Hours;
|
|
||||||
|
|
||||||
//Remove all old event listeners from Cancel button
|
|
||||||
var newCancelButton = clearEventListeners("work-in-progress-cancel-button");
|
|
||||||
newCancelButton.innerHTML = "Cancel Work";
|
|
||||||
newCancelButton.addEventListener("click", function() {
|
|
||||||
Player.finishWork(true);
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
//Display Work In Progress Screen
|
|
||||||
Engine.loadWorkInProgressContent();
|
|
||||||
}
|
|
||||||
|
|
||||||
PlayerObject.prototype.work = function(numCycles) {
|
|
||||||
this.workRepGainRate = this.getWorkRepGain();
|
|
||||||
|
|
||||||
this.workHackExpGained += this.workHackExpGainRate * numCycles;
|
|
||||||
this.workStrExpGained += this.workStrExpGainRate * numCycles;
|
|
||||||
this.workDefExpGained += this.workDefExpGainRate * numCycles;
|
|
||||||
this.workDexExpGained += this.workDexExpGainRate * numCycles;
|
|
||||||
this.workAgiExpGained += this.workAgiExpGainRate * numCycles;
|
|
||||||
this.workChaExpGained += this.workChaExpGainRate * numCycles;
|
|
||||||
this.workRepGained += this.workRepGainRate * numCycles;
|
|
||||||
this.workMoneyGained += this.workMoneyGainRate * numCycles;
|
|
||||||
|
|
||||||
var cyclesPerSec = 1000 / Engine._idleSpeed;
|
|
||||||
|
|
||||||
this.timeWorked += Engine._idleSpeed * numCycles;
|
|
||||||
|
|
||||||
//If timeWorked == 8 hours, then finish. You can only gain 8 hours worth of exp and money
|
|
||||||
if (this.timeWorked >= CONSTANTS.MillisecondsPer8Hours) {
|
|
||||||
var maxCycles = CONSTANTS.GameCyclesPer8Hours;
|
|
||||||
this.workHackExpGained = this.workHackExpGainRate * maxCycles;
|
|
||||||
this.workStrExpGained = this.workStrExpGainRate * maxCycles;
|
|
||||||
this.workDefExpGained = this.workDefExpGainRate * maxCycles;
|
|
||||||
this.workDexExpGained = this.workDexExpGainRate * maxCycles;
|
|
||||||
this.workAgiExpGained = this.workAgiExpGainRate * maxCycles;
|
|
||||||
this.workChaExpGained = this.workChaExpGainRate * maxCycles;
|
|
||||||
this.workRepGained = this.workRepGainRate * maxCycles;
|
|
||||||
this.workMoneyGained = this.workMoneyGainRate * maxCycles;
|
|
||||||
this.finishWork(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var comp = Companies[this.companyName], companyRep = "0";
|
|
||||||
if (comp == null || !(comp instanceof Company)) {
|
|
||||||
console.log("ERROR: Could not find Company: " + this.companyName);
|
|
||||||
} else {
|
|
||||||
companyRep = comp.playerReputation;
|
|
||||||
}
|
|
||||||
|
|
||||||
var txt = document.getElementById("work-in-progress-text");
|
|
||||||
txt.innerHTML = "You are currently working as a " + this.companyPosition.positionName +
|
|
||||||
" at " + this.companyName + " (Current Company Reputation: " +
|
|
||||||
formatNumber(companyRep, 0) + ")<br><br>" +
|
|
||||||
"You have been working for " + convertTimeMsToTimeElapsedString(this.timeWorked) + "<br><br>" +
|
|
||||||
"You have earned: <br><br>" +
|
|
||||||
"$" + formatNumber(this.workMoneyGained, 2) + " ($" + formatNumber(this.workMoneyGainRate * cyclesPerSec, 2) + " / sec) <br><br>" +
|
|
||||||
formatNumber(this.workRepGained, 4) + " (" + formatNumber(this.workRepGainRate * cyclesPerSec, 4) + " / sec) reputation for this company <br><br>" +
|
|
||||||
formatNumber(this.workHackExpGained, 4) + " (" + formatNumber(this.workHackExpGainRate * cyclesPerSec, 4) + " / sec) hacking exp <br><br>" +
|
|
||||||
formatNumber(this.workStrExpGained, 4) + " (" + formatNumber(this.workStrExpGainRate * cyclesPerSec, 4) + " / sec) strength exp <br>" +
|
|
||||||
formatNumber(this.workDefExpGained, 4) + " (" + formatNumber(this.workDefExpGainRate * cyclesPerSec, 4) + " / sec) defense exp <br>" +
|
|
||||||
formatNumber(this.workDexExpGained, 4) + " (" + formatNumber(this.workDexExpGainRate * cyclesPerSec, 4) + " / sec) dexterity exp <br>" +
|
|
||||||
formatNumber(this.workAgiExpGained, 4) + " (" + formatNumber(this.workAgiExpGainRate * cyclesPerSec, 4) + " / sec) agility exp <br><br> " +
|
|
||||||
formatNumber(this.workChaExpGained, 4) + " (" + formatNumber(this.workChaExpGainRate * cyclesPerSec, 4) + " / sec) charisma exp <br><br>" +
|
|
||||||
"You will automatically finish after working for 8 hours. You can cancel earlier if you wish, " +
|
|
||||||
"but you will only gain half of the reputation you've earned so far."
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
PlayerObject.prototype.startWorkPartTime = function() {
|
PlayerObject.prototype.startWorkPartTime = function() {
|
||||||
this.resetWorkStatus();
|
this.resetWorkStatus();
|
||||||
this.isWorking = true;
|
this.isWorking = true;
|
||||||
@ -886,57 +814,50 @@ PlayerObject.prototype.startWorkPartTime = function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
PlayerObject.prototype.workPartTime = function(numCycles) {
|
PlayerObject.prototype.workPartTime = function(numCycles) {
|
||||||
this.workRepGainRate = this.getWorkRepGain();
|
//Cap the number of cycles being processed to whatever would put you at the
|
||||||
|
//work time limit (8 hours)
|
||||||
this.workHackExpGained += this.workHackExpGainRate * numCycles;
|
var overMax = false;
|
||||||
this.workStrExpGained += this.workStrExpGainRate * numCycles;
|
if (this.timeWorked + (Engine._idleSpeed * numCycles) >= CONSTANTS.MillisecondsPer8Hours) {
|
||||||
this.workDefExpGained += this.workDefExpGainRate * numCycles;
|
overMax = true;
|
||||||
this.workDexExpGained += this.workDexExpGainRate * numCycles;
|
numCycles = Math.round((CONSTANTS.MillisecondsPer8Hours - this.timeWorked) / Engine._idleSpeed);
|
||||||
this.workAgiExpGained += this.workAgiExpGainRate * numCycles;
|
}
|
||||||
this.workChaExpGained += this.workChaExpGainRate * numCycles;
|
|
||||||
this.workRepGained += this.workRepGainRate * numCycles;
|
|
||||||
this.workMoneyGained += this.workMoneyGainRate * numCycles;
|
|
||||||
|
|
||||||
var cyclesPerSec = 1000 / Engine._idleSpeed;
|
|
||||||
|
|
||||||
this.timeWorked += Engine._idleSpeed * numCycles;
|
this.timeWorked += Engine._idleSpeed * numCycles;
|
||||||
|
|
||||||
|
this.workRepGainRate = this.getWorkRepGain();
|
||||||
|
this.processWorkEarnings(numCycles);
|
||||||
|
|
||||||
//If timeWorked == 8 hours, then finish. You can only gain 8 hours worth of exp and money
|
//If timeWorked == 8 hours, then finish. You can only gain 8 hours worth of exp and money
|
||||||
if (this.timeWorked >= CONSTANTS.MillisecondsPer8Hours) {
|
if (overMax || this.timeWorked >= CONSTANTS.MillisecondsPer8Hours) {
|
||||||
var maxCycles = CONSTANTS.GameCyclesPer8Hours;
|
return this.finishWorkPartTime();
|
||||||
this.workHackExpGained = this.workHackExpGainRate * maxCycles;
|
}
|
||||||
this.workStrExpGained = this.workStrExpGainRate * maxCycles;
|
|
||||||
this.workDefExpGained = this.workDefExpGainRate * maxCycles;
|
var comp = Companies[this.companyName], companyRep = "0";
|
||||||
this.workDexExpGained = this.workDexExpGainRate * maxCycles;
|
if (comp == null || !(comp instanceof Company)) {
|
||||||
this.workAgiExpGained = this.workAgiExpGainRate * maxCycles;
|
console.log("ERROR: Could not find Company: " + this.companyName);
|
||||||
this.workChaExpGained = this.workChaExpGainRate * maxCycles;
|
} else {
|
||||||
this.workRepGained = this.workRepGainRate * maxCycles;
|
companyRep = comp.playerReputation;
|
||||||
this.workMoneyGained = this.workMoneyGainRate * maxCycles;
|
|
||||||
this.finishWorkPartTime();
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var txt = document.getElementById("work-in-progress-text");
|
var txt = document.getElementById("work-in-progress-text");
|
||||||
txt.innerHTML = "You are currently working as a " + this.companyPosition.positionName +
|
txt.innerHTML = "You are currently working as a " + this.companyPosition.positionName +
|
||||||
" at " + Player.companyName + "<br><br>" +
|
" at " + Player.companyName + " (Current Company Reputation: " +
|
||||||
|
formatNumber(companyRep, 0) + ")<br><br>" +
|
||||||
"You have been working for " + convertTimeMsToTimeElapsedString(this.timeWorked) + "<br><br>" +
|
"You have been working for " + convertTimeMsToTimeElapsedString(this.timeWorked) + "<br><br>" +
|
||||||
"You have earned: <br><br>" +
|
"You have earned: <br><br>" +
|
||||||
"$" + formatNumber(this.workMoneyGained, 2) + " ($" + formatNumber(this.workMoneyGainRate * cyclesPerSec, 2) + " / sec) <br><br>" +
|
"$" + formatNumber(this.workMoneyGained, 2) + " ($" + formatNumber(this.workMoneyGainRate * CYCLES_PER_SEC, 2) + " / sec) <br><br>" +
|
||||||
formatNumber(this.workRepGained, 4) + " (" + formatNumber(this.workRepGainRate * cyclesPerSec, 4) + " / sec) reputation for this company <br><br>" +
|
formatNumber(this.workRepGained, 4) + " (" + formatNumber(this.workRepGainRate * CYCLES_PER_SEC, 4) + " / sec) reputation for this company <br><br>" +
|
||||||
formatNumber(this.workHackExpGained, 4) + " (" + formatNumber(this.workHackExpGainRate * cyclesPerSec, 4) + " / sec) hacking exp <br><br>" +
|
formatNumber(this.workHackExpGained, 4) + " (" + formatNumber(this.workHackExpGainRate * CYCLES_PER_SEC, 4) + " / sec) hacking exp <br><br>" +
|
||||||
formatNumber(this.workStrExpGained, 4) + " (" + formatNumber(this.workStrExpGainRate * cyclesPerSec, 4) + " / sec) strength exp <br>" +
|
formatNumber(this.workStrExpGained, 4) + " (" + formatNumber(this.workStrExpGainRate * CYCLES_PER_SEC, 4) + " / sec) strength exp <br>" +
|
||||||
formatNumber(this.workDefExpGained, 4) + " (" + formatNumber(this.workDefExpGainRate * cyclesPerSec, 4) + " / sec) defense exp <br>" +
|
formatNumber(this.workDefExpGained, 4) + " (" + formatNumber(this.workDefExpGainRate * CYCLES_PER_SEC, 4) + " / sec) defense exp <br>" +
|
||||||
formatNumber(this.workDexExpGained, 4) + " (" + formatNumber(this.workDexExpGainRate * cyclesPerSec, 4) + " / sec) dexterity exp <br>" +
|
formatNumber(this.workDexExpGained, 4) + " (" + formatNumber(this.workDexExpGainRate * CYCLES_PER_SEC, 4) + " / sec) dexterity exp <br>" +
|
||||||
formatNumber(this.workAgiExpGained, 4) + " (" + formatNumber(this.workAgiExpGainRate * cyclesPerSec, 4) + " / sec) agility exp <br><br> " +
|
formatNumber(this.workAgiExpGained, 4) + " (" + formatNumber(this.workAgiExpGainRate * CYCLES_PER_SEC, 4) + " / sec) agility exp <br><br> " +
|
||||||
formatNumber(this.workChaExpGained, 4) + " (" + formatNumber(this.workChaExpGainRate * cyclesPerSec, 4) + " / sec) charisma exp <br><br>" +
|
formatNumber(this.workChaExpGained, 4) + " (" + formatNumber(this.workChaExpGainRate * CYCLES_PER_SEC, 4) + " / sec) charisma exp <br><br>" +
|
||||||
"You will automatically finish after working for 8 hours. You can cancel earlier if you wish, <br>" +
|
"You will automatically finish after working for 8 hours. You can cancel earlier if you wish, <br>" +
|
||||||
"and there will be no penalty because this is a part-time job.";
|
"and there will be no penalty because this is a part-time job.";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PlayerObject.prototype.finishWorkPartTime = function(sing=false) {
|
PlayerObject.prototype.finishWorkPartTime = function(sing=false) {
|
||||||
this.gainWorkExp();
|
|
||||||
|
|
||||||
var company = Companies[this.companyName];
|
var company = Companies[this.companyName];
|
||||||
company.playerReputation += (this.workRepGained);
|
company.playerReputation += (this.workRepGained);
|
||||||
|
|
||||||
@ -978,51 +899,6 @@ PlayerObject.prototype.finishWorkPartTime = function(sing=false) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Working for Faction */
|
/* Working for Faction */
|
||||||
PlayerObject.prototype.finishFactionWork = function(cancelled, sing=false) {
|
|
||||||
this.gainWorkExp();
|
|
||||||
|
|
||||||
var faction = Factions[this.currentWorkFactionName];
|
|
||||||
faction.playerReputation += (this.workRepGained);
|
|
||||||
|
|
||||||
this.gainMoney(this.workMoneyGained);
|
|
||||||
|
|
||||||
this.updateSkillLevels();
|
|
||||||
|
|
||||||
var txt = "You worked for your faction " + faction.name + " for a total of " + convertTimeMsToTimeElapsedString(this.timeWorked) + " <br><br> " +
|
|
||||||
"You earned a total of: <br>" +
|
|
||||||
"$" + formatNumber(this.workMoneyGained, 2) + "<br>" +
|
|
||||||
formatNumber(this.workRepGained, 4) + " reputation for the faction <br>" +
|
|
||||||
formatNumber(this.workHackExpGained, 4) + " hacking exp <br>" +
|
|
||||||
formatNumber(this.workStrExpGained, 4) + " strength exp <br>" +
|
|
||||||
formatNumber(this.workDefExpGained, 4) + " defense exp <br>" +
|
|
||||||
formatNumber(this.workDexExpGained, 4) + " dexterity exp <br>" +
|
|
||||||
formatNumber(this.workAgiExpGained, 4) + " agility exp <br>" +
|
|
||||||
formatNumber(this.workChaExpGained, 4) + " charisma exp<br>";
|
|
||||||
if (!sing) {dialogBoxCreate(txt);}
|
|
||||||
|
|
||||||
var mainMenu = document.getElementById("mainmenu-container");
|
|
||||||
mainMenu.style.visibility = "visible";
|
|
||||||
|
|
||||||
this.isWorking = false;
|
|
||||||
|
|
||||||
Engine.loadFactionContent();
|
|
||||||
displayFactionContent(faction.name);
|
|
||||||
if (sing) {
|
|
||||||
var res="You worked for your faction " + faction.name + " for a total of " + convertTimeMsToTimeElapsedString(this.timeWorked) + ". " +
|
|
||||||
"You earned " +
|
|
||||||
formatNumber(this.workRepGained, 4) + " rep, " +
|
|
||||||
formatNumber(this.workHackExpGained, 4) + " hacking exp, " +
|
|
||||||
formatNumber(this.workStrExpGained, 4) + " str exp, " +
|
|
||||||
formatNumber(this.workDefExpGained, 4) + " def exp, " +
|
|
||||||
formatNumber(this.workDexExpGained, 4) + " dex exp, " +
|
|
||||||
formatNumber(this.workAgiExpGained, 4) + " agi exp, and " +
|
|
||||||
formatNumber(this.workChaExpGained, 4) + " cha exp.";
|
|
||||||
this.resetWorkStatus();
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
this.resetWorkStatus();
|
|
||||||
}
|
|
||||||
|
|
||||||
PlayerObject.prototype.startFactionWork = function(faction) {
|
PlayerObject.prototype.startFactionWork = function(faction) {
|
||||||
//Update reputation gain rate to account for faction favor
|
//Update reputation gain rate to account for faction favor
|
||||||
var favorMult = 1 + (faction.favor / 100);
|
var favorMult = 1 + (faction.favor / 100);
|
||||||
@ -1117,52 +993,81 @@ PlayerObject.prototype.workForFaction = function(numCycles) {
|
|||||||
this.workRepGainRate *= favorMult;
|
this.workRepGainRate *= favorMult;
|
||||||
this.workRepGainRate *= BitNodeMultipliers.FactionWorkRepGain;
|
this.workRepGainRate *= BitNodeMultipliers.FactionWorkRepGain;
|
||||||
|
|
||||||
this.workHackExpGained += this.workHackExpGainRate * numCycles;
|
//Cap the number of cycles being processed to whatever would put you at limit (20 hours)
|
||||||
this.workStrExpGained += this.workStrExpGainRate * numCycles;
|
var overMax = false;
|
||||||
this.workDefExpGained += this.workDefExpGainRate * numCycles;
|
if (this.timeWorked + (Engine._idleSpeed * numCycles) >= CONSTANTS.MillisecondsPer20Hours) {
|
||||||
this.workDexExpGained += this.workDexExpGainRate * numCycles;
|
overMax = true;
|
||||||
this.workAgiExpGained += this.workAgiExpGainRate * numCycles;
|
numCycles = Math.round((CONSTANTS.MillisecondsPer20Hours - this.timeWorked) / Engine._idleSpeed);
|
||||||
this.workChaExpGained += this.workChaExpGainRate * numCycles;
|
}
|
||||||
this.workRepGained += this.workRepGainRate * numCycles;
|
|
||||||
this.workMoneyGained += this.workMoneyGainRate * numCycles;
|
|
||||||
|
|
||||||
var cyclesPerSec = 1000 / Engine._idleSpeed;
|
|
||||||
|
|
||||||
this.timeWorked += Engine._idleSpeed * numCycles;
|
this.timeWorked += Engine._idleSpeed * numCycles;
|
||||||
|
|
||||||
|
this.processWorkEarnings(numCycles);
|
||||||
|
|
||||||
//If timeWorked == 20 hours, then finish. You can only work for the faction for 20 hours
|
//If timeWorked == 20 hours, then finish. You can only work for the faction for 20 hours
|
||||||
if (this.timeWorked >= CONSTANTS.MillisecondsPer20Hours) {
|
if (overMax || this.timeWorked >= CONSTANTS.MillisecondsPer20Hours) {
|
||||||
var maxCycles = CONSTANTS.GameCyclesPer20Hours;
|
return this.finishWork(false);
|
||||||
this.timeWorked = CONSTANTS.MillisecondsPer20Hours;
|
|
||||||
this.workHackExpGained = this.workHackExpGainRate * maxCycles;
|
|
||||||
this.workStrExpGained = this.workStrExpGainRate * maxCycles;
|
|
||||||
this.workDefExpGained = this.workDefExpGainRate * maxCycles;
|
|
||||||
this.workDexExpGained = this.workDexExpGainRate * maxCycles;
|
|
||||||
this.workAgiExpGained = this.workAgiExpGainRate * maxCycles;
|
|
||||||
this.workChaExpGained = this.workChaExpGainRate * maxCycles;
|
|
||||||
this.workRepGained = this.workRepGainRate * maxCycles;
|
|
||||||
this.workMoneyGained = this.workMoneyGainRate * maxCycles;
|
|
||||||
this.finishFactionWork(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var txt = document.getElementById("work-in-progress-text");
|
var txt = document.getElementById("work-in-progress-text");
|
||||||
txt.innerHTML = "You are currently " + this.currentWorkFactionDescription + " for your faction " + faction.name +
|
txt.innerHTML = "You are currently " + this.currentWorkFactionDescription + " for your faction " + faction.name +
|
||||||
" (Current Faction Reputation: " + formatNumber(faction.playerReputation, 0) + "). " +
|
" (Current Faction Reputation: " + formatNumber(faction.playerReputation, 0) + "). <br>" +
|
||||||
"You have been doing this for " + convertTimeMsToTimeElapsedString(this.timeWorked) + "<br><br>" +
|
"You have been doing this for " + convertTimeMsToTimeElapsedString(this.timeWorked) + "<br><br>" +
|
||||||
"You have earned: <br><br>" +
|
"You have earned: <br><br>" +
|
||||||
"$" + formatNumber(this.workMoneyGained, 2) + " (" + formatNumber(this.workMoneyGainRate * cyclesPerSec, 2) + " / sec) <br><br>" +
|
"$" + formatNumber(this.workMoneyGained, 2) + " (" + formatNumber(this.workMoneyGainRate * CYCLES_PER_SEC, 2) + " / sec) <br><br>" +
|
||||||
formatNumber(this.workRepGained, 4) + " (" + formatNumber(this.workRepGainRate * cyclesPerSec, 4) + " / sec) reputation for this faction <br><br>" +
|
formatNumber(this.workRepGained, 4) + " (" + formatNumber(this.workRepGainRate * CYCLES_PER_SEC, 4) + " / sec) reputation for this faction <br><br>" +
|
||||||
formatNumber(this.workHackExpGained, 4) + " (" + formatNumber(this.workHackExpGainRate * cyclesPerSec, 4) + " / sec) hacking exp <br><br>" +
|
formatNumber(this.workHackExpGained, 4) + " (" + formatNumber(this.workHackExpGainRate * CYCLES_PER_SEC, 4) + " / sec) hacking exp <br><br>" +
|
||||||
formatNumber(this.workStrExpGained, 4) + " (" + formatNumber(this.workStrExpGainRate * cyclesPerSec, 4) + " / sec) strength exp <br>" +
|
formatNumber(this.workStrExpGained, 4) + " (" + formatNumber(this.workStrExpGainRate * CYCLES_PER_SEC, 4) + " / sec) strength exp <br>" +
|
||||||
formatNumber(this.workDefExpGained, 4) + " (" + formatNumber(this.workDefExpGainRate * cyclesPerSec, 4) + " / sec) defense exp <br>" +
|
formatNumber(this.workDefExpGained, 4) + " (" + formatNumber(this.workDefExpGainRate * CYCLES_PER_SEC, 4) + " / sec) defense exp <br>" +
|
||||||
formatNumber(this.workDexExpGained, 4) + " (" + formatNumber(this.workDexExpGainRate * cyclesPerSec, 4) + " / sec) dexterity exp <br>" +
|
formatNumber(this.workDexExpGained, 4) + " (" + formatNumber(this.workDexExpGainRate * CYCLES_PER_SEC, 4) + " / sec) dexterity exp <br>" +
|
||||||
formatNumber(this.workAgiExpGained, 4) + " (" + formatNumber(this.workAgiExpGainRate * cyclesPerSec, 4) + " / sec) agility exp <br><br> " +
|
formatNumber(this.workAgiExpGained, 4) + " (" + formatNumber(this.workAgiExpGainRate * CYCLES_PER_SEC, 4) + " / sec) agility exp <br><br> " +
|
||||||
formatNumber(this.workChaExpGained, 4) + " (" + formatNumber(this.workChaExpGainRate * cyclesPerSec, 4) + " / sec) charisma exp <br><br>" +
|
formatNumber(this.workChaExpGained, 4) + " (" + formatNumber(this.workChaExpGainRate * CYCLES_PER_SEC, 4) + " / sec) charisma exp <br><br>" +
|
||||||
|
|
||||||
"You will automatically finish after working for 20 hours. You can cancel earlier if you wish.<br>" +
|
"You will automatically finish after working for 20 hours. You can cancel earlier if you wish.<br>" +
|
||||||
"There is no penalty for cancelling earlier.";
|
"There is no penalty for cancelling earlier.";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PlayerObject.prototype.finishFactionWork = function(cancelled, sing=false) {
|
||||||
|
var faction = Factions[this.currentWorkFactionName];
|
||||||
|
faction.playerReputation += (this.workRepGained);
|
||||||
|
|
||||||
|
this.gainMoney(this.workMoneyGained);
|
||||||
|
|
||||||
|
this.updateSkillLevels();
|
||||||
|
|
||||||
|
var txt = "You worked for your faction " + faction.name + " for a total of " + convertTimeMsToTimeElapsedString(this.timeWorked) + " <br><br> " +
|
||||||
|
"You earned a total of: <br>" +
|
||||||
|
"$" + formatNumber(this.workMoneyGained, 2) + "<br>" +
|
||||||
|
formatNumber(this.workRepGained, 4) + " reputation for the faction <br>" +
|
||||||
|
formatNumber(this.workHackExpGained, 4) + " hacking exp <br>" +
|
||||||
|
formatNumber(this.workStrExpGained, 4) + " strength exp <br>" +
|
||||||
|
formatNumber(this.workDefExpGained, 4) + " defense exp <br>" +
|
||||||
|
formatNumber(this.workDexExpGained, 4) + " dexterity exp <br>" +
|
||||||
|
formatNumber(this.workAgiExpGained, 4) + " agility exp <br>" +
|
||||||
|
formatNumber(this.workChaExpGained, 4) + " charisma exp<br>";
|
||||||
|
if (!sing) {dialogBoxCreate(txt);}
|
||||||
|
|
||||||
|
var mainMenu = document.getElementById("mainmenu-container");
|
||||||
|
mainMenu.style.visibility = "visible";
|
||||||
|
|
||||||
|
this.isWorking = false;
|
||||||
|
|
||||||
|
Engine.loadFactionContent();
|
||||||
|
displayFactionContent(faction.name);
|
||||||
|
if (sing) {
|
||||||
|
var res="You worked for your faction " + faction.name + " for a total of " + convertTimeMsToTimeElapsedString(this.timeWorked) + ". " +
|
||||||
|
"You earned " +
|
||||||
|
formatNumber(this.workRepGained, 4) + " rep, " +
|
||||||
|
formatNumber(this.workHackExpGained, 4) + " hacking exp, " +
|
||||||
|
formatNumber(this.workStrExpGained, 4) + " str exp, " +
|
||||||
|
formatNumber(this.workDefExpGained, 4) + " def exp, " +
|
||||||
|
formatNumber(this.workDexExpGained, 4) + " dex exp, " +
|
||||||
|
formatNumber(this.workAgiExpGained, 4) + " agi exp, and " +
|
||||||
|
formatNumber(this.workChaExpGained, 4) + " cha exp.";
|
||||||
|
this.resetWorkStatus();
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
this.resetWorkStatus();
|
||||||
|
}
|
||||||
|
|
||||||
//Money gained per game cycle
|
//Money gained per game cycle
|
||||||
PlayerObject.prototype.getWorkMoneyGain = function() {
|
PlayerObject.prototype.getWorkMoneyGain = function() {
|
||||||
@ -1438,36 +1343,25 @@ PlayerObject.prototype.takeClass = function(numCycles) {
|
|||||||
this.timeWorked += Engine._idleSpeed * numCycles;
|
this.timeWorked += Engine._idleSpeed * numCycles;
|
||||||
var className = this.className;
|
var className = this.className;
|
||||||
|
|
||||||
this.workHackExpGained += this.workHackExpGainRate * numCycles;
|
this.processWorkEarnings(numCycles);
|
||||||
this.workStrExpGained += this.workStrExpGainRate * numCycles;
|
|
||||||
this.workDefExpGained += this.workDefExpGainRate * numCycles;
|
|
||||||
this.workDexExpGained += this.workDexExpGainRate * numCycles;
|
|
||||||
this.workAgiExpGained += this.workAgiExpGainRate * numCycles;
|
|
||||||
this.workChaExpGained += this.workChaExpGainRate * numCycles;
|
|
||||||
this.workRepGained += this.workRepGainRate * numCycles;
|
|
||||||
this.workMoneyGained += this.workMoneyGainRate * numCycles;
|
|
||||||
this.workMoneyGained -= this.workMoneyLossRate * numCycles;
|
|
||||||
|
|
||||||
var cyclesPerSec = 1000 / Engine._idleSpeed;
|
|
||||||
|
|
||||||
var txt = document.getElementById("work-in-progress-text");
|
var txt = document.getElementById("work-in-progress-text");
|
||||||
txt.innerHTML = "You have been " + className + " for " + convertTimeMsToTimeElapsedString(this.timeWorked) + "<br><br>" +
|
txt.innerHTML = "You have been " + className + " for " + convertTimeMsToTimeElapsedString(this.timeWorked) + "<br><br>" +
|
||||||
"This has cost you: <br>" +
|
"This has cost you: <br>" +
|
||||||
"$" + formatNumber(this.workMoneyGained, 2) + " ($" + formatNumber(this.workMoneyLossRate * cyclesPerSec, 2) + " / sec) <br><br>" +
|
"$" + formatNumber(this.workMoneyGained, 2) + " ($" + formatNumber(this.workMoneyLossRate * CYCLES_PER_SEC, 2) + " / sec) <br><br>" +
|
||||||
"You have gained: <br>" +
|
"You have gained: <br>" +
|
||||||
formatNumber(this.workHackExpGained, 4) + " (" + formatNumber(this.workHackExpGainRate * cyclesPerSec, 4) + " / sec) hacking exp <br>" +
|
formatNumber(this.workHackExpGained, 4) + " (" + formatNumber(this.workHackExpGainRate * CYCLES_PER_SEC, 4) + " / sec) hacking exp <br>" +
|
||||||
formatNumber(this.workStrExpGained, 4) + " (" + formatNumber(this.workStrExpGainRate * cyclesPerSec, 4) + " / sec) strength exp <br>" +
|
formatNumber(this.workStrExpGained, 4) + " (" + formatNumber(this.workStrExpGainRate * CYCLES_PER_SEC, 4) + " / sec) strength exp <br>" +
|
||||||
formatNumber(this.workDefExpGained, 4) + " (" + formatNumber(this.workDefExpGainRate * cyclesPerSec, 4) + " / sec) defense exp <br>" +
|
formatNumber(this.workDefExpGained, 4) + " (" + formatNumber(this.workDefExpGainRate * CYCLES_PER_SEC, 4) + " / sec) defense exp <br>" +
|
||||||
formatNumber(this.workDexExpGained, 4) + " (" + formatNumber(this.workDexExpGainRate * cyclesPerSec, 4) + " / sec) dexterity exp <br>" +
|
formatNumber(this.workDexExpGained, 4) + " (" + formatNumber(this.workDexExpGainRate * CYCLES_PER_SEC, 4) + " / sec) dexterity exp <br>" +
|
||||||
formatNumber(this.workAgiExpGained, 4) + " (" + formatNumber(this.workAgiExpGainRate * cyclesPerSec, 4) + " / sec) agility exp <br>" +
|
formatNumber(this.workAgiExpGained, 4) + " (" + formatNumber(this.workAgiExpGainRate * CYCLES_PER_SEC, 4) + " / sec) agility exp <br>" +
|
||||||
formatNumber(this.workChaExpGained, 4) + " (" + formatNumber(this.workChaExpGainRate * cyclesPerSec, 4) + " / sec) charisma exp <br>" +
|
formatNumber(this.workChaExpGained, 4) + " (" + formatNumber(this.workChaExpGainRate * CYCLES_PER_SEC, 4) + " / sec) charisma exp <br>" +
|
||||||
"You may cancel at any time";
|
"You may cancel at any time";
|
||||||
}
|
}
|
||||||
|
|
||||||
//The 'sing' argument defines whether or not this function was called
|
//The 'sing' argument defines whether or not this function was called
|
||||||
//through a Singularity Netscript function
|
//through a Singularity Netscript function
|
||||||
PlayerObject.prototype.finishClass = function(sing=false) {
|
PlayerObject.prototype.finishClass = function(sing=false) {
|
||||||
this.gainWorkExp();
|
|
||||||
this.gainIntelligenceExp(CONSTANTS.IntelligenceClassBaseExpGain * Math.round(this.timeWorked / 1000));
|
this.gainIntelligenceExp(CONSTANTS.IntelligenceClassBaseExpGain * Math.round(this.timeWorked / 1000));
|
||||||
|
|
||||||
if (this.workMoneyGained > 0) {
|
if (this.workMoneyGained > 0) {
|
||||||
@ -1642,7 +1536,12 @@ PlayerObject.prototype.finishCrime = function(cancelled) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.gainWorkExp();
|
this.gainHackingExp(this.workHackExpGained);
|
||||||
|
this.gainStrengthExp(this.workStrExpGained);
|
||||||
|
this.gainDefenseExp(this.workDefExpGained);
|
||||||
|
this.gainDexterityExp(this.workDexExpGained);
|
||||||
|
this.gainAgilityExp(this.workAgiExpGained);
|
||||||
|
this.gainCharismaExp(this.workChaExpGained);
|
||||||
}
|
}
|
||||||
this.committingCrimeThruSingFn = false;
|
this.committingCrimeThruSingFn = false;
|
||||||
this.singFnCrimeWorkerScript = null;
|
this.singFnCrimeWorkerScript = null;
|
||||||
|
@ -516,9 +516,9 @@ function loadImportedGame(saveObj, saveString) {
|
|||||||
|
|
||||||
Player.lastUpdate = Engine._lastUpdate;
|
Player.lastUpdate = Engine._lastUpdate;
|
||||||
Engine.start(); //Run main game loop and Scripts loop
|
Engine.start(); //Run main game loop and Scripts loop
|
||||||
dialogBoxCreate("While you were offline, your scripts generated $" +
|
dialogBoxCreate("While you were offline, your scripts generated <span class='money-gold'>$" +
|
||||||
formatNumber(offlineProductionFromScripts, 2) + " and your Hacknet Nodes generated $" +
|
formatNumber(offlineProductionFromScripts, 2) + "</span> and your Hacknet Nodes generated <span class='money-gold'>$" +
|
||||||
formatNumber(offlineProductionFromHacknetNodes, 2));
|
formatNumber(offlineProductionFromHacknetNodes, 2) + "</span>");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ import {CONSTANTS} from "./Constants";
|
|||||||
import {Engine} from "./engine";
|
import {Engine} from "./engine";
|
||||||
import {FconfSettings, parseFconfSettings} from "./Fconf";
|
import {FconfSettings, parseFconfSettings} from "./Fconf";
|
||||||
import {iTutorialSteps, iTutorialNextStep,
|
import {iTutorialSteps, iTutorialNextStep,
|
||||||
iTutorialIsRunning, currITutorialStep} from "./InteractiveTutorial";
|
ITutorial} from "./InteractiveTutorial";
|
||||||
import {evaluateImport} from "./NetscriptEvaluator";
|
import {evaluateImport} from "./NetscriptEvaluator";
|
||||||
import {NetscriptFunctions} from "./NetscriptFunctions";
|
import {NetscriptFunctions} from "./NetscriptFunctions";
|
||||||
import {addWorkerScript,
|
import {addWorkerScript,
|
||||||
@ -281,8 +281,9 @@ function saveAndCloseScriptEditor() {
|
|||||||
var filename = document.getElementById("script-editor-filename").value;
|
var filename = document.getElementById("script-editor-filename").value;
|
||||||
var editor = ace.edit('javascript-editor');
|
var editor = ace.edit('javascript-editor');
|
||||||
var code = editor.getValue();
|
var code = editor.getValue();
|
||||||
if (iTutorialIsRunning && currITutorialStep == iTutorialSteps.TerminalTypeScript) {
|
if (ITutorial.isRunning && ITutorial.currStep === iTutorialSteps.TerminalTypeScript) {
|
||||||
if (filename != "foodnstuff.script") {
|
//Make sure filename + code properly follow tutorial
|
||||||
|
if (filename !== "foodnstuff.script") {
|
||||||
dialogBoxCreate("Leave the script name as 'foodnstuff'!");
|
dialogBoxCreate("Leave the script name as 'foodnstuff'!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -291,7 +292,23 @@ function saveAndCloseScriptEditor() {
|
|||||||
dialogBoxCreate("Please copy and paste the code from the tutorial!");
|
dialogBoxCreate("Please copy and paste the code from the tutorial!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
iTutorialNextStep();
|
|
||||||
|
//Save the script
|
||||||
|
let s = Player.getCurrentServer();
|
||||||
|
for (var i = 0; i < s.scripts.length; i++) {
|
||||||
|
if (filename == s.scripts[i].filename) {
|
||||||
|
s.scripts[i].saveScript();
|
||||||
|
Engine.loadTerminalContent();
|
||||||
|
return iTutorialNextStep();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//If the current script does NOT exist, create a new one
|
||||||
|
let script = new Script();
|
||||||
|
script.saveScript();
|
||||||
|
s.scripts.push(script);
|
||||||
|
|
||||||
|
return iTutorialNextStep();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (filename == "") {
|
if (filename == "") {
|
||||||
|
@ -39,6 +39,11 @@ interface IDefaultSettings {
|
|||||||
*/
|
*/
|
||||||
SuppressFactionInvites: boolean;
|
SuppressFactionInvites: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether to show a popup message when player is hospitalized from taking too much damage
|
||||||
|
*/
|
||||||
|
SuppressHospitalizationPopup: boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether the user should be shown a dialog box whenever they receive a new message file.
|
* Whether the user should be shown a dialog box whenever they receive a new message file.
|
||||||
*/
|
*/
|
||||||
@ -48,11 +53,6 @@ interface IDefaultSettings {
|
|||||||
* Whether the user should be asked to confirm travelling between cities.
|
* Whether the user should be asked to confirm travelling between cities.
|
||||||
*/
|
*/
|
||||||
SuppressTravelConfirmation: boolean;
|
SuppressTravelConfirmation: boolean;
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether to show a popup message when player is hospitalized from taking too much damage
|
|
||||||
*/
|
|
||||||
SuppressHospitalizationPopup: boolean;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -95,9 +95,9 @@ const defaultSettings: IDefaultSettings = {
|
|||||||
MaxPortCapacity: 50,
|
MaxPortCapacity: 50,
|
||||||
SuppressBuyAugmentationConfirmation: false,
|
SuppressBuyAugmentationConfirmation: false,
|
||||||
SuppressFactionInvites: false,
|
SuppressFactionInvites: false,
|
||||||
|
SuppressHospitalizationPopup: false,
|
||||||
SuppressMessages: false,
|
SuppressMessages: false,
|
||||||
SuppressTravelConfirmation: false,
|
SuppressTravelConfirmation: false,
|
||||||
SuppressHospitalizationPopup: false,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -114,9 +114,9 @@ export const Settings: ISettings & ISelfInitializer & ISelfLoading = {
|
|||||||
MaxPortCapacity: defaultSettings.MaxPortCapacity,
|
MaxPortCapacity: defaultSettings.MaxPortCapacity,
|
||||||
SuppressBuyAugmentationConfirmation: defaultSettings.SuppressBuyAugmentationConfirmation,
|
SuppressBuyAugmentationConfirmation: defaultSettings.SuppressBuyAugmentationConfirmation,
|
||||||
SuppressFactionInvites: defaultSettings.SuppressFactionInvites,
|
SuppressFactionInvites: defaultSettings.SuppressFactionInvites,
|
||||||
|
SuppressHospitalizationPopup: defaultSettings.SuppressHospitalizationPopup,
|
||||||
SuppressMessages: defaultSettings.SuppressMessages,
|
SuppressMessages: defaultSettings.SuppressMessages,
|
||||||
SuppressTravelConfirmation: defaultSettings.SuppressTravelConfirmation,
|
SuppressTravelConfirmation: defaultSettings.SuppressTravelConfirmation,
|
||||||
SuppressHospitalizationPopup: defaultSettings.SuppressHospitalizationPopup,
|
|
||||||
ThemeBackgroundColor: "#000000",
|
ThemeBackgroundColor: "#000000",
|
||||||
ThemeFontColor: "#66ff33",
|
ThemeFontColor: "#66ff33",
|
||||||
ThemeHighlightColor: "#ffffff",
|
ThemeHighlightColor: "#ffffff",
|
||||||
|
95
src/Stock.ts
Normal file
95
src/Stock.ts
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
import { Generic_fromJSON, Generic_toJSON, Reviver } from "../utils/JSONReviver";
|
||||||
|
|
||||||
|
export class Stock {
|
||||||
|
/**
|
||||||
|
* Initializes a Stock from a JSON save state
|
||||||
|
*/
|
||||||
|
static fromJSON(value: any): Stock {
|
||||||
|
return Generic_fromJSON(Stock, value.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The stock's ticker symbol
|
||||||
|
*/
|
||||||
|
readonly symbol: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Name of the company that the stock is for
|
||||||
|
*/
|
||||||
|
readonly name: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stock's share price
|
||||||
|
*/
|
||||||
|
price: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Number of shares the player owns in the LONG position
|
||||||
|
*/
|
||||||
|
playerShares: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Average price of stocks that the player owns in the LONG position
|
||||||
|
*/
|
||||||
|
playerAvgPx: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Number of shares the player owns in the SHORT position
|
||||||
|
*/
|
||||||
|
playerShortShares: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Average price of stocks that the player owns in the SHORT position
|
||||||
|
*/
|
||||||
|
playerAvgShortPx: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maximum volatility
|
||||||
|
*/
|
||||||
|
readonly mv: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bear or bull (more likely to go up or down, based on otlkMag)
|
||||||
|
*/
|
||||||
|
b: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Outlook magnitude. Represents the stock's forecast and likelihood
|
||||||
|
* of increasing/decreasing (based on whether its in bear or bull mode)
|
||||||
|
*/
|
||||||
|
otlkMag: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The HTML element that displays the stock's info in the UI
|
||||||
|
*/
|
||||||
|
posTxtEl: HTMLElement | null;
|
||||||
|
|
||||||
|
constructor(name: string="",
|
||||||
|
symbol: string="",
|
||||||
|
mv: number=1,
|
||||||
|
b: boolean=true,
|
||||||
|
otlkMag: number=0,
|
||||||
|
initPrice: number = 10e3) {
|
||||||
|
this.name = name;
|
||||||
|
this.symbol = symbol;
|
||||||
|
this.price = initPrice;
|
||||||
|
this.playerShares = 0;
|
||||||
|
this.playerAvgPx = 0;
|
||||||
|
this.playerShortShares = 0;
|
||||||
|
this.playerAvgShortPx = 0;
|
||||||
|
this.mv = mv;
|
||||||
|
this.b = b;
|
||||||
|
this.otlkMag = otlkMag;
|
||||||
|
|
||||||
|
this.posTxtEl = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serialize the Stock to a JSON save state.
|
||||||
|
*/
|
||||||
|
toJSON(): any {
|
||||||
|
return Generic_toJSON("Stock", this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Reviver.constructors.Stock = Stock;
|
@ -3,6 +3,7 @@ import {Locations} from "./Locations";
|
|||||||
import {hasWallStreetSF, wallStreetSFLvl} from "./NetscriptFunctions";
|
import {hasWallStreetSF, wallStreetSFLvl} from "./NetscriptFunctions";
|
||||||
import {WorkerScript} from "./NetscriptWorker";
|
import {WorkerScript} from "./NetscriptWorker";
|
||||||
import {Player} from "./Player";
|
import {Player} from "./Player";
|
||||||
|
import {Stock} from "./Stock";
|
||||||
|
|
||||||
import {dialogBoxCreate} from "../utils/DialogBox";
|
import {dialogBoxCreate} from "../utils/DialogBox";
|
||||||
import {clearEventListeners} from "../utils/uiHelpers/clearEventListeners";
|
import {clearEventListeners} from "../utils/uiHelpers/clearEventListeners";
|
||||||
@ -24,32 +25,6 @@ import {yesNoBoxCreate, yesNoTxtInpBoxCreate,
|
|||||||
|
|
||||||
let StockPriceCap = 1e9; //Put a limit on how high a price can go
|
let StockPriceCap = 1e9; //Put a limit on how high a price can go
|
||||||
|
|
||||||
function Stock(name, symbol, mv, b, otlkMag, initPrice=10000) {
|
|
||||||
this.symbol = symbol;
|
|
||||||
this.name = name;
|
|
||||||
this.price = initPrice;
|
|
||||||
|
|
||||||
this.playerShares = 0;
|
|
||||||
this.playerAvgPx = 0;
|
|
||||||
this.playerShortShares = 0;
|
|
||||||
this.playerAvgShortPx = 0;
|
|
||||||
this.mv = mv;
|
|
||||||
this.b = b;
|
|
||||||
this.otlkMag = otlkMag;
|
|
||||||
|
|
||||||
this.posTxtEl = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
Stock.prototype.toJSON = function() {
|
|
||||||
return Generic_toJSON("Stock", this);
|
|
||||||
}
|
|
||||||
|
|
||||||
Stock.fromJSON = function(value) {
|
|
||||||
return Generic_fromJSON(Stock, value.data);
|
|
||||||
}
|
|
||||||
|
|
||||||
Reviver.constructors.Stock = Stock;
|
|
||||||
|
|
||||||
var OrderTypes = {
|
var OrderTypes = {
|
||||||
LimitBuy: "Limit Buy Order",
|
LimitBuy: "Limit Buy Order",
|
||||||
LimitSell: "Limit Sell Order",
|
LimitSell: "Limit Sell Order",
|
||||||
@ -253,135 +228,135 @@ function initStockMarket() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var ecorp = Locations.AevumECorp;
|
var ecorp = Locations.AevumECorp;
|
||||||
var ecorpStk = new Stock(ecorp, StockSymbols[ecorp], 0.45, true, 19, getRandomInt(20000, 25000));
|
var ecorpStk = new Stock(ecorp, StockSymbols[ecorp], getRandomInt(40, 50)/100, true, 19, getRandomInt(17e3, 28e3));
|
||||||
StockMarket[ecorp] = ecorpStk;
|
StockMarket[ecorp] = ecorpStk;
|
||||||
|
|
||||||
var megacorp = Locations.Sector12MegaCorp;
|
var megacorp = Locations.Sector12MegaCorp;
|
||||||
var megacorpStk = new Stock(megacorp, StockSymbols[megacorp], 0.45, true, 19, getRandomInt(25000, 33000));
|
var megacorpStk = new Stock(megacorp, StockSymbols[megacorp], getRandomInt(40,50)/100, true, 19, getRandomInt(24e3, 34e3));
|
||||||
StockMarket[megacorp] = megacorpStk;
|
StockMarket[megacorp] = megacorpStk;
|
||||||
|
|
||||||
var blade = Locations.Sector12BladeIndustries;
|
var blade = Locations.Sector12BladeIndustries;
|
||||||
var bladeStk = new Stock(blade, StockSymbols[blade], 0.75, true, 13, getRandomInt(15000, 22000));
|
var bladeStk = new Stock(blade, StockSymbols[blade], getRandomInt(70, 80)/100, true, 13, getRandomInt(12e3, 25e3));
|
||||||
StockMarket[blade] = bladeStk;
|
StockMarket[blade] = bladeStk;
|
||||||
|
|
||||||
var clarke = Locations.AevumClarkeIncorporated;
|
var clarke = Locations.AevumClarkeIncorporated;
|
||||||
var clarkeStk = new Stock(clarke, StockSymbols[clarke], 0.7, true, 12, getRandomInt(15000, 20000));
|
var clarkeStk = new Stock(clarke, StockSymbols[clarke], getRandomInt(65, 75)/100, true, 12, getRandomInt(10e3, 25e3));
|
||||||
StockMarket[clarke] = clarkeStk;
|
StockMarket[clarke] = clarkeStk;
|
||||||
|
|
||||||
var omnitek = Locations.VolhavenOmniTekIncorporated;
|
var omnitek = Locations.VolhavenOmniTekIncorporated;
|
||||||
var omnitekStk = new Stock(omnitek, StockSymbols[omnitek], 0.65, true, 12, getRandomInt(35000, 40000));
|
var omnitekStk = new Stock(omnitek, StockSymbols[omnitek], getRandomInt(60, 70)/100, true, 12, getRandomInt(32e3, 43e3));
|
||||||
StockMarket[omnitek] = omnitekStk;
|
StockMarket[omnitek] = omnitekStk;
|
||||||
|
|
||||||
var foursigma = Locations.Sector12FourSigma;
|
var foursigma = Locations.Sector12FourSigma;
|
||||||
var foursigmaStk = new Stock(foursigma, StockSymbols[foursigma], 1.05, true, 17, getRandomInt(60000, 70000));
|
var foursigmaStk = new Stock(foursigma, StockSymbols[foursigma], getRandomInt(100, 110)/100, true, 17, getRandomInt(50e3, 80e3));
|
||||||
StockMarket[foursigma] = foursigmaStk;
|
StockMarket[foursigma] = foursigmaStk;
|
||||||
|
|
||||||
var kuaigong = Locations.ChongqingKuaiGongInternational;
|
var kuaigong = Locations.ChongqingKuaiGongInternational;
|
||||||
var kuaigongStk = new Stock(kuaigong, StockSymbols[kuaigong], 0.8, true, 10, getRandomInt(20000, 24000));
|
var kuaigongStk = new Stock(kuaigong, StockSymbols[kuaigong], getRandomInt(75, 85)/100, true, 10, getRandomInt(16e3, 28e3));
|
||||||
StockMarket[kuaigong] = kuaigongStk;
|
StockMarket[kuaigong] = kuaigongStk;
|
||||||
|
|
||||||
var fulcrum = Locations.AevumFulcrumTechnologies;
|
var fulcrum = Locations.AevumFulcrumTechnologies;
|
||||||
var fulcrumStk = new Stock(fulcrum, StockSymbols[fulcrum], 1.25, true, 16, getRandomInt(30000, 35000));
|
var fulcrumStk = new Stock(fulcrum, StockSymbols[fulcrum], getRandomInt(120, 130)/100, true, 16, getRandomInt(29e3, 36e3));
|
||||||
StockMarket[fulcrum] = fulcrumStk;
|
StockMarket[fulcrum] = fulcrumStk;
|
||||||
|
|
||||||
var storm = Locations.IshimaStormTechnologies;
|
var storm = Locations.IshimaStormTechnologies;
|
||||||
var stormStk = new Stock(storm, StockSymbols[storm], 0.85, true, 7, getRandomInt(21000, 24000));
|
var stormStk = new Stock(storm, StockSymbols[storm], getRandomInt(80, 90)/100, true, 7, getRandomInt(20e3, 25e3));
|
||||||
StockMarket[storm] = stormStk;
|
StockMarket[storm] = stormStk;
|
||||||
|
|
||||||
var defcomm = Locations.NewTokyoDefComm;
|
var defcomm = Locations.NewTokyoDefComm;
|
||||||
var defcommStk = new Stock(defcomm, StockSymbols[defcomm], 0.65, true, 10, getRandomInt(10000, 15000));
|
var defcommStk = new Stock(defcomm, StockSymbols[defcomm], getRandomInt(60, 70)/100, true, 10, getRandomInt(6e3, 19e3));
|
||||||
StockMarket[defcomm] = defcommStk;
|
StockMarket[defcomm] = defcommStk;
|
||||||
|
|
||||||
var helios = Locations.VolhavenHeliosLabs;
|
var helios = Locations.VolhavenHeliosLabs;
|
||||||
var heliosStk = new Stock(helios, StockSymbols[helios], 0.6, true, 9, getRandomInt(12000, 16000));
|
var heliosStk = new Stock(helios, StockSymbols[helios], getRandomInt(55, 65)/100, true, 9, getRandomInt(10e3, 18e3));
|
||||||
StockMarket[helios] = heliosStk;
|
StockMarket[helios] = heliosStk;
|
||||||
|
|
||||||
var vitalife = Locations.NewTokyoVitaLife;
|
var vitalife = Locations.NewTokyoVitaLife;
|
||||||
var vitalifeStk = new Stock(vitalife, StockSymbols[vitalife], 0.75, true, 7, getRandomInt(10000, 12000));
|
var vitalifeStk = new Stock(vitalife, StockSymbols[vitalife], getRandomInt(70, 80)/100, true, 7, getRandomInt(8e3, 14e3));
|
||||||
StockMarket[vitalife] = vitalifeStk;
|
StockMarket[vitalife] = vitalifeStk;
|
||||||
|
|
||||||
var icarus = Locations.Sector12IcarusMicrosystems;
|
var icarus = Locations.Sector12IcarusMicrosystems;
|
||||||
var icarusStk = new Stock(icarus, StockSymbols[icarus], 0.65, true, 7.5, getRandomInt(16000, 20000));
|
var icarusStk = new Stock(icarus, StockSymbols[icarus], getRandomInt(60, 70)/100, true, 7.5, getRandomInt(12e3, 24e3));
|
||||||
StockMarket[icarus] = icarusStk;
|
StockMarket[icarus] = icarusStk;
|
||||||
|
|
||||||
var universalenergy = Locations.Sector12UniversalEnergy;
|
var universalenergy = Locations.Sector12UniversalEnergy;
|
||||||
var universalenergyStk = new Stock(universalenergy, StockSymbols[universalenergy], 0.55, true, 10, getRandomInt(20000, 25000));
|
var universalenergyStk = new Stock(universalenergy, StockSymbols[universalenergy], getRandomInt(50, 60)/100, true, 10, getRandomInt(16e3, 29e3));
|
||||||
StockMarket[universalenergy] = universalenergyStk;
|
StockMarket[universalenergy] = universalenergyStk;
|
||||||
|
|
||||||
var aerocorp = Locations.AevumAeroCorp;
|
var aerocorp = Locations.AevumAeroCorp;
|
||||||
var aerocorpStk = new Stock(aerocorp, StockSymbols[aerocorp], 0.6, true, 6, getRandomInt(10000, 15000));
|
var aerocorpStk = new Stock(aerocorp, StockSymbols[aerocorp], getRandomInt(55, 65)/100, true, 6, getRandomInt(8e3, 17e3));
|
||||||
StockMarket[aerocorp] = aerocorpStk;
|
StockMarket[aerocorp] = aerocorpStk;
|
||||||
|
|
||||||
var omnia = Locations.VolhavenOmniaCybersystems;
|
var omnia = Locations.VolhavenOmniaCybersystems;
|
||||||
var omniaStk = new Stock(omnia, StockSymbols[omnia], 0.7, true, 4.5, getRandomInt(9000, 12000));
|
var omniaStk = new Stock(omnia, StockSymbols[omnia], getRandomInt(65, 75)/100, true, 4.5, getRandomInt(6e3, 15e3));
|
||||||
StockMarket[omnia] = omniaStk;
|
StockMarket[omnia] = omniaStk;
|
||||||
|
|
||||||
var solaris = Locations.ChongqingSolarisSpaceSystems;
|
var solaris = Locations.ChongqingSolarisSpaceSystems;
|
||||||
var solarisStk = new Stock(solaris, StockSymbols[solaris], 0.75, true, 8.5, getRandomInt(18000, 24000));
|
var solarisStk = new Stock(solaris, StockSymbols[solaris], getRandomInt(70, 80)/100, true, 8.5, getRandomInt(14e3, 28e3));
|
||||||
StockMarket[solaris] = solarisStk;
|
StockMarket[solaris] = solarisStk;
|
||||||
|
|
||||||
var globalpharm = Locations.NewTokyoGlobalPharmaceuticals;
|
var globalpharm = Locations.NewTokyoGlobalPharmaceuticals;
|
||||||
var globalpharmStk = new Stock(globalpharm, StockSymbols[globalpharm], 0.6, true, 10.5, getRandomInt(18000, 24000));
|
var globalpharmStk = new Stock(globalpharm, StockSymbols[globalpharm], getRandomInt(55, 65)/100, true, 10.5, getRandomInt(12e3, 30e3));
|
||||||
StockMarket[globalpharm] = globalpharmStk;
|
StockMarket[globalpharm] = globalpharmStk;
|
||||||
|
|
||||||
var nova = Locations.IshimaNovaMedical;
|
var nova = Locations.IshimaNovaMedical;
|
||||||
var novaStk = new Stock(nova, StockSymbols[nova], 0.75, true, 5, getRandomInt(18000, 24000));
|
var novaStk = new Stock(nova, StockSymbols[nova], getRandomInt(70, 80)/100, true, 5, getRandomInt(15e3, 27e3));
|
||||||
StockMarket[nova] = novaStk;
|
StockMarket[nova] = novaStk;
|
||||||
|
|
||||||
var watchdog = Locations.AevumWatchdogSecurity;
|
var watchdog = Locations.AevumWatchdogSecurity;
|
||||||
var watchdogStk = new Stock(watchdog, StockSymbols[watchdog], 2.5, true, 1.5, getRandomInt(5000, 7500));
|
var watchdogStk = new Stock(watchdog, StockSymbols[watchdog], getRandomInt(240, 260)/100, true, 1.5, getRandomInt(4e3, 8.5e3));
|
||||||
StockMarket[watchdog] = watchdogStk;
|
StockMarket[watchdog] = watchdogStk;
|
||||||
|
|
||||||
var lexocorp = Locations.VolhavenLexoCorp;
|
var lexocorp = Locations.VolhavenLexoCorp;
|
||||||
var lexocorpStk = new Stock(lexocorp, StockSymbols[lexocorp], 1.25, true, 6, getRandomInt(5000, 7500));
|
var lexocorpStk = new Stock(lexocorp, StockSymbols[lexocorp], getRandomInt(115, 135)/100, true, 6, getRandomInt(4.5e3, 8e3));
|
||||||
StockMarket[lexocorp] = lexocorpStk;
|
StockMarket[lexocorp] = lexocorpStk;
|
||||||
|
|
||||||
var rho = Locations.AevumRhoConstruction;
|
var rho = Locations.AevumRhoConstruction;
|
||||||
var rhoStk = new Stock(rho, StockSymbols[rho], 0.6, true, 1, getRandomInt(3000, 6000));
|
var rhoStk = new Stock(rho, StockSymbols[rho], getRandomInt(50, 70)/100, true, 1, getRandomInt(2e3, 7e3));
|
||||||
StockMarket[rho] = rhoStk;
|
StockMarket[rho] = rhoStk;
|
||||||
|
|
||||||
var alpha = Locations.Sector12AlphaEnterprises;
|
var alpha = Locations.Sector12AlphaEnterprises;
|
||||||
var alphaStk = new Stock(alpha, StockSymbols[alpha], 1.9, true, 10, getRandomInt(5000, 7500));
|
var alphaStk = new Stock(alpha, StockSymbols[alpha], getRandomInt(175, 205)/100, true, 10, getRandomInt(4e3, 8.5e3));
|
||||||
StockMarket[alpha] = alphaStk;
|
StockMarket[alpha] = alphaStk;
|
||||||
|
|
||||||
var syscore = Locations.VolhavenSysCoreSecurities;
|
var syscore = Locations.VolhavenSysCoreSecurities;
|
||||||
var syscoreStk = new Stock(syscore, StockSymbols[syscore], 1.6, true, 3, getRandomInt(4000, 7000))
|
var syscoreStk = new Stock(syscore, StockSymbols[syscore], getRandomInt(150, 170)/100, true, 3, getRandomInt(3e3, 8e3));
|
||||||
StockMarket[syscore] = syscoreStk;
|
StockMarket[syscore] = syscoreStk;
|
||||||
|
|
||||||
var computek = Locations.VolhavenCompuTek;
|
var computek = Locations.VolhavenCompuTek;
|
||||||
var computekStk = new Stock(computek, StockSymbols[computek], 0.9, true, 4, getRandomInt(2000, 5000));
|
var computekStk = new Stock(computek, StockSymbols[computek], getRandomInt(80, 100)/100, true, 4, getRandomInt(1e3, 6e3));
|
||||||
StockMarket[computek] = computekStk;
|
StockMarket[computek] = computekStk;
|
||||||
|
|
||||||
var netlink = Locations.AevumNetLinkTechnologies;
|
var netlink = Locations.AevumNetLinkTechnologies;
|
||||||
var netlinkStk = new Stock(netlink, StockSymbols[netlink], 4.2, true, 1, getRandomInt(2000, 4000));
|
var netlinkStk = new Stock(netlink, StockSymbols[netlink], getRandomInt(400, 430)/100, true, 1, getRandomInt(1e3, 5e3));
|
||||||
StockMarket[netlink] = netlinkStk;
|
StockMarket[netlink] = netlinkStk;
|
||||||
|
|
||||||
var omega = Locations.IshimaOmegaSoftware;
|
var omega = Locations.IshimaOmegaSoftware;
|
||||||
var omegaStk = new Stock(omega, StockSymbols[omega], 1, true, 0.5, getRandomInt(3000, 6000));
|
var omegaStk = new Stock(omega, StockSymbols[omega], getRandomInt(90, 110)/100, true, 0.5, getRandomInt(1e3, 8e3));
|
||||||
StockMarket[omega] = omegaStk;
|
StockMarket[omega] = omegaStk;
|
||||||
|
|
||||||
var fns = Locations.Sector12FoodNStuff;
|
var fns = Locations.Sector12FoodNStuff;
|
||||||
var fnsStk = new Stock(fns, StockSymbols[fns], 0.75, false, 1, getRandomInt(1000, 4000));
|
var fnsStk = new Stock(fns, StockSymbols[fns], getRandomInt(70, 80)/100, false, 1, getRandomInt(500, 4.5e3));
|
||||||
StockMarket[fns] = fnsStk;
|
StockMarket[fns] = fnsStk;
|
||||||
|
|
||||||
var sigmacosm = "Sigma Cosmetics";
|
var sigmacosm = "Sigma Cosmetics";
|
||||||
var sigmacosmStk = new Stock(sigmacosm, StockSymbols[sigmacosm], 2.8, true, 0, getRandomInt(2000, 3000));
|
var sigmacosmStk = new Stock(sigmacosm, StockSymbols[sigmacosm], getRandomInt(260, 300)/100, true, 0, getRandomInt(1.5e3, 3.5e3));
|
||||||
StockMarket[sigmacosm] = sigmacosmStk;
|
StockMarket[sigmacosm] = sigmacosmStk;
|
||||||
|
|
||||||
var joesguns = "Joes Guns";
|
var joesguns = "Joes Guns";
|
||||||
var joesgunsStk = new Stock(joesguns, StockSymbols[joesguns], 3.8, true, 1, getRandomInt(500, 1000));
|
var joesgunsStk = new Stock(joesguns, StockSymbols[joesguns], getRandomInt(360, 400)/100, true, 1, getRandomInt(250, 1.5e3));
|
||||||
StockMarket[joesguns] = joesgunsStk;
|
StockMarket[joesguns] = joesgunsStk;
|
||||||
|
|
||||||
var catalyst = "Catalyst Ventures";
|
var catalyst = "Catalyst Ventures";
|
||||||
var catalystStk = new Stock(catalyst, StockSymbols[catalyst], 1.45, true, 13.5, getRandomInt(500, 1000));
|
var catalystStk = new Stock(catalyst, StockSymbols[catalyst], getRandomInt(120, 175)/100, true, 13.5, getRandomInt(250, 1.5e3));
|
||||||
StockMarket[catalyst] = catalystStk;
|
StockMarket[catalyst] = catalystStk;
|
||||||
|
|
||||||
var microdyne = "Microdyne Technologies";
|
var microdyne = "Microdyne Technologies";
|
||||||
var microdyneStk = new Stock(microdyne, StockSymbols[microdyne], 0.75, true, 8, getRandomInt(20000, 25000));
|
var microdyneStk = new Stock(microdyne, StockSymbols[microdyne], getRandomInt(70, 80)/100, true, 8, getRandomInt(15e3, 30e3));
|
||||||
StockMarket[microdyne] = microdyneStk;
|
StockMarket[microdyne] = microdyneStk;
|
||||||
|
|
||||||
var titanlabs = "Titan Laboratories";
|
var titanlabs = "Titan Laboratories";
|
||||||
var titanlabsStk = new Stock(titanlabs, StockSymbols[titanlabs], 0.6, true, 11, getRandomInt(15000, 20000));
|
var titanlabsStk = new Stock(titanlabs, StockSymbols[titanlabs], getRandomInt(50, 70)/100, true, 11, getRandomInt(12e3, 24e3));
|
||||||
StockMarket[titanlabs] = titanlabsStk;
|
StockMarket[titanlabs] = titanlabsStk;
|
||||||
|
|
||||||
var orders = {};
|
var orders = {};
|
||||||
|
128
src/Terminal.js
128
src/Terminal.js
@ -10,15 +10,17 @@ import {executeDarkwebTerminalCommand,
|
|||||||
import {Engine} from "./engine";
|
import {Engine} from "./engine";
|
||||||
import {FconfSettings, parseFconfSettings,
|
import {FconfSettings, parseFconfSettings,
|
||||||
createFconf} from "./Fconf";
|
createFconf} from "./Fconf";
|
||||||
|
import {calculateHackingChance,
|
||||||
|
calculateHackingExpGain,
|
||||||
|
calculatePercentMoneyHacked,
|
||||||
|
calculateHackingTime,
|
||||||
|
calculateGrowTime,
|
||||||
|
calculateWeakenTime} from "./Hacking";
|
||||||
import {TerminalHelpText, HelpTexts} from "./HelpText";
|
import {TerminalHelpText, HelpTexts} from "./HelpText";
|
||||||
import {iTutorialNextStep, iTutorialSteps,
|
import {iTutorialNextStep, iTutorialSteps,
|
||||||
iTutorialIsRunning,
|
ITutorial} from "./InteractiveTutorial";
|
||||||
currITutorialStep} from "./InteractiveTutorial";
|
|
||||||
import {showLiterature} from "./Literature";
|
import {showLiterature} from "./Literature";
|
||||||
import {showMessage, Message} from "./Message";
|
import {showMessage, Message} from "./Message";
|
||||||
import {scriptCalculateHackingTime,
|
|
||||||
scriptCalculateGrowTime,
|
|
||||||
scriptCalculateWeakenTime} from "./NetscriptEvaluator";
|
|
||||||
import {killWorkerScript, addWorkerScript} from "./NetscriptWorker";
|
import {killWorkerScript, addWorkerScript} from "./NetscriptWorker";
|
||||||
import numeral from "numeral/min/numeral.min";
|
import numeral from "numeral/min/numeral.min";
|
||||||
import {Player} from "./Player";
|
import {Player} from "./Player";
|
||||||
@ -70,7 +72,7 @@ $(document).keydown(function(event) {
|
|||||||
"[" +
|
"[" +
|
||||||
(FconfSettings.ENABLE_TIMESTAMPS ? getTimestamp() + " " : "") +
|
(FconfSettings.ENABLE_TIMESTAMPS ? getTimestamp() + " " : "") +
|
||||||
Player.getCurrentServer().hostname +
|
Player.getCurrentServer().hostname +
|
||||||
" ~]> " + command
|
" ~]></span> " + command
|
||||||
);
|
);
|
||||||
|
|
||||||
if (command.length > 0) {
|
if (command.length > 0) {
|
||||||
@ -516,6 +518,8 @@ let Terminal = {
|
|||||||
//Flags to determine whether the player is currently running a hack or an analyze
|
//Flags to determine whether the player is currently running a hack or an analyze
|
||||||
hackFlag: false,
|
hackFlag: false,
|
||||||
analyzeFlag: false,
|
analyzeFlag: false,
|
||||||
|
actionStarted: false,
|
||||||
|
actionTime: 0,
|
||||||
|
|
||||||
commandHistory: [],
|
commandHistory: [],
|
||||||
commandHistoryIndex: 0,
|
commandHistoryIndex: 0,
|
||||||
@ -630,6 +634,32 @@ let Terminal = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
startHack: function() {
|
||||||
|
Terminal.hackFlag = true;
|
||||||
|
|
||||||
|
//Hacking through Terminal should be faster than hacking through a script
|
||||||
|
Terminal.actionTime = calculateHackingTime(Player.getCurrentServer()) / 4;
|
||||||
|
Terminal.startAction();
|
||||||
|
},
|
||||||
|
|
||||||
|
startAnalyze: function() {
|
||||||
|
Terminal.analyzeFlag = true;
|
||||||
|
Terminal.actionTime = 1;
|
||||||
|
post("Analyzing system...");
|
||||||
|
Terminal.startAction();
|
||||||
|
},
|
||||||
|
|
||||||
|
startAction: function() {
|
||||||
|
Terminal.actionStarted = true;
|
||||||
|
|
||||||
|
hackProgressPost("Time left:");
|
||||||
|
hackProgressBarPost("[");
|
||||||
|
|
||||||
|
//Disable terminal
|
||||||
|
document.getElementById("terminal-input-td").innerHTML = '<input type="text" class="terminal-input"/>';
|
||||||
|
$('input[class=terminal-input]').prop('disabled', true);
|
||||||
|
},
|
||||||
|
|
||||||
finishAction: function(cancelled = false) {
|
finishAction: function(cancelled = false) {
|
||||||
if (Terminal.hackFlag) {
|
if (Terminal.hackFlag) {
|
||||||
Terminal.finishHack(cancelled);
|
Terminal.finishHack(cancelled);
|
||||||
@ -644,10 +674,10 @@ let Terminal = {
|
|||||||
var server = Player.getCurrentServer();
|
var server = Player.getCurrentServer();
|
||||||
|
|
||||||
//Calculate whether hack was successful
|
//Calculate whether hack was successful
|
||||||
var hackChance = Player.calculateHackingChance();
|
var hackChance = calculateHackingChance(server);
|
||||||
var rand = Math.random();
|
var rand = Math.random();
|
||||||
console.log("Hack success chance: " + hackChance + ", rand: " + rand);
|
console.log("Hack success chance: " + hackChance + ", rand: " + rand);
|
||||||
var expGainedOnSuccess = Player.calculateExpGain();
|
var expGainedOnSuccess = calculateHackingExpGain(server);
|
||||||
var expGainedOnFailure = (expGainedOnSuccess / 4);
|
var expGainedOnFailure = (expGainedOnSuccess / 4);
|
||||||
if (rand < hackChance) { //Success!
|
if (rand < hackChance) { //Success!
|
||||||
if (SpecialServerIps[SpecialServerNames.WorldDaemon] &&
|
if (SpecialServerIps[SpecialServerNames.WorldDaemon] &&
|
||||||
@ -659,7 +689,7 @@ let Terminal = {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
server.manuallyHacked = true;
|
server.manuallyHacked = true;
|
||||||
var moneyGained = Player.calculatePercentMoneyHacked();
|
var moneyGained = calculatePercentMoneyHacked(server);
|
||||||
moneyGained = Math.floor(server.moneyAvailable * moneyGained);
|
moneyGained = Math.floor(server.moneyAvailable * moneyGained);
|
||||||
|
|
||||||
if (moneyGained <= 0) {moneyGained = 0;} //Safety check
|
if (moneyGained <= 0) {moneyGained = 0;} //Safety check
|
||||||
@ -690,43 +720,44 @@ let Terminal = {
|
|||||||
|
|
||||||
finishAnalyze: function(cancelled = false) {
|
finishAnalyze: function(cancelled = false) {
|
||||||
if (cancelled == false) {
|
if (cancelled == false) {
|
||||||
post(Player.getCurrentServer().hostname + ": ");
|
let currServ = Player.getCurrentServer();
|
||||||
post("Organization name: " + Player.getCurrentServer().organizationName);
|
post(currServ.hostname + ": ");
|
||||||
|
post("Organization name: " + currServ.organizationName);
|
||||||
var rootAccess = "";
|
var rootAccess = "";
|
||||||
if (Player.getCurrentServer().hasAdminRights) {rootAccess = "YES";}
|
if (currServ.hasAdminRights) {rootAccess = "YES";}
|
||||||
else {rootAccess = "NO";}
|
else {rootAccess = "NO";}
|
||||||
post("Root Access: " + rootAccess);
|
post("Root Access: " + rootAccess);
|
||||||
post("Required hacking skill: " + Player.getCurrentServer().requiredHackingSkill);
|
post("Required hacking skill: " + currServ.requiredHackingSkill);
|
||||||
post("Estimated server security level: " + formatNumber(addOffset(Player.getCurrentServer().hackDifficulty, 5), 3));
|
post("Server security level: " + formatNumber(currServ.hackDifficulty, 3));
|
||||||
post("Estimated chance to hack: " + formatNumber(addOffset(Player.calculateHackingChance() * 100, 5), 2) + "%");
|
post("Chance to hack: " + formatNumber(calculateHackingChance(currServ) * 100, 2) + "%");
|
||||||
post("Estimated time to hack: " + formatNumber(addOffset(Player.calculateHackingTime(), 5), 3) + " seconds");
|
post("Time to hack: " + formatNumber(calculateHackingTime(currServ), 3) + " seconds");
|
||||||
post("Estimated total money available on server: $" + formatNumber(addOffset(Player.getCurrentServer().moneyAvailable, 5), 2));
|
post("Total money available on server: $" + formatNumber(currServ.moneyAvailable, 2));
|
||||||
post("Required number of open ports for NUKE: " + Player.getCurrentServer().numOpenPortsRequired);
|
post("Required number of open ports for NUKE: " + currServ.numOpenPortsRequired);
|
||||||
if (Player.getCurrentServer().sshPortOpen) {
|
if (currServ.sshPortOpen) {
|
||||||
post("SSH port: Open")
|
post("SSH port: Open")
|
||||||
} else {
|
} else {
|
||||||
post("SSH port: Closed")
|
post("SSH port: Closed")
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Player.getCurrentServer().ftpPortOpen) {
|
if (currServ.ftpPortOpen) {
|
||||||
post("FTP port: Open")
|
post("FTP port: Open")
|
||||||
} else {
|
} else {
|
||||||
post("FTP port: Closed")
|
post("FTP port: Closed")
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Player.getCurrentServer().smtpPortOpen) {
|
if (currServ.smtpPortOpen) {
|
||||||
post("SMTP port: Open")
|
post("SMTP port: Open")
|
||||||
} else {
|
} else {
|
||||||
post("SMTP port: Closed")
|
post("SMTP port: Closed")
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Player.getCurrentServer().httpPortOpen) {
|
if (currServ.httpPortOpen) {
|
||||||
post("HTTP port: Open")
|
post("HTTP port: Open")
|
||||||
} else {
|
} else {
|
||||||
post("HTTP port: Closed")
|
post("HTTP port: Closed")
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Player.getCurrentServer().sqlPortOpen) {
|
if (currServ.sqlPortOpen) {
|
||||||
post("SQL port: Open")
|
post("SQL port: Open")
|
||||||
} else {
|
} else {
|
||||||
post("SQL port: Closed")
|
post("SQL port: Closed")
|
||||||
@ -821,11 +852,11 @@ let Terminal = {
|
|||||||
if (commandArray.length == 0) {return;}
|
if (commandArray.length == 0) {return;}
|
||||||
|
|
||||||
/****************** Interactive Tutorial Terminal Commands ******************/
|
/****************** Interactive Tutorial Terminal Commands ******************/
|
||||||
if (iTutorialIsRunning) {
|
if (ITutorial.isRunning) {
|
||||||
var foodnstuffServ = GetServerByHostname("foodnstuff");
|
var foodnstuffServ = GetServerByHostname("foodnstuff");
|
||||||
if (foodnstuffServ == null) {throw new Error("Could not get foodnstuff server"); return;}
|
if (foodnstuffServ == null) {throw new Error("Could not get foodnstuff server"); return;}
|
||||||
|
|
||||||
switch(currITutorialStep) {
|
switch(ITutorial.currStep) {
|
||||||
case iTutorialSteps.TerminalHelp:
|
case iTutorialSteps.TerminalHelp:
|
||||||
if (commandArray[0] == "help") {
|
if (commandArray[0] == "help") {
|
||||||
post(TerminalHelpText);
|
post(TerminalHelpText);
|
||||||
@ -875,16 +906,7 @@ let Terminal = {
|
|||||||
if (commandArray.length != 1) {
|
if (commandArray.length != 1) {
|
||||||
post("Incorrect usage of analyze command. Usage: analyze"); return;
|
post("Incorrect usage of analyze command. Usage: analyze"); return;
|
||||||
}
|
}
|
||||||
//Analyze the current server for information
|
Terminal.startAnalyze();
|
||||||
Terminal.analyzeFlag = true;
|
|
||||||
post("Analyzing system...");
|
|
||||||
hackProgressPost("Time left:");
|
|
||||||
hackProgressBarPost("[");
|
|
||||||
Player.analyze();
|
|
||||||
|
|
||||||
//Disable terminal
|
|
||||||
document.getElementById("terminal-input-td").innerHTML = '<input type="text" class="terminal-input"/>';
|
|
||||||
$('input[class=terminal-input]').prop('disabled', true);
|
|
||||||
iTutorialNextStep();
|
iTutorialNextStep();
|
||||||
} else {
|
} else {
|
||||||
post("Bad command. Please follow the tutorial");
|
post("Bad command. Please follow the tutorial");
|
||||||
@ -900,14 +922,7 @@ let Terminal = {
|
|||||||
break;
|
break;
|
||||||
case iTutorialSteps.TerminalManualHack:
|
case iTutorialSteps.TerminalManualHack:
|
||||||
if (commandArray.length == 1 && commandArray[0] == "hack") {
|
if (commandArray.length == 1 && commandArray[0] == "hack") {
|
||||||
Terminal.hackFlag = true;
|
Terminal.startHack();
|
||||||
hackProgressPost("Time left:");
|
|
||||||
hackProgressBarPost("[");
|
|
||||||
Player.hack();
|
|
||||||
|
|
||||||
//Disable terminal
|
|
||||||
document.getElementById("terminal-input-td").innerHTML = '<input type="text" class="terminal-input"/>';
|
|
||||||
$('input[class=terminal-input]').prop('disabled', true);
|
|
||||||
iTutorialNextStep();
|
iTutorialNextStep();
|
||||||
} else {post("Bad command. Please follow the tutorial");}
|
} else {post("Bad command. Please follow the tutorial");}
|
||||||
break;
|
break;
|
||||||
@ -978,16 +993,7 @@ let Terminal = {
|
|||||||
if (commandArray.length != 1) {
|
if (commandArray.length != 1) {
|
||||||
post("Incorrect usage of analyze command. Usage: analyze"); return;
|
post("Incorrect usage of analyze command. Usage: analyze"); return;
|
||||||
}
|
}
|
||||||
//Analyze the current server for information
|
Terminal.startAnalyze();
|
||||||
Terminal.analyzeFlag = true;
|
|
||||||
post("Analyzing system...");
|
|
||||||
hackProgressPost("Time left:");
|
|
||||||
hackProgressBarPost("[");
|
|
||||||
Player.analyze();
|
|
||||||
|
|
||||||
//Disable terminal
|
|
||||||
document.getElementById("terminal-input-td").innerHTML = '<input type="text" class="terminal-input"/>';
|
|
||||||
$('input[class=terminal-input]').prop('disabled', true);
|
|
||||||
break;
|
break;
|
||||||
case "buy":
|
case "buy":
|
||||||
if (SpecialServerIps.hasOwnProperty("Darkweb Server")) {
|
if (SpecialServerIps.hasOwnProperty("Darkweb Server")) {
|
||||||
@ -1140,14 +1146,7 @@ let Terminal = {
|
|||||||
} else if (Player.getCurrentServer().requiredHackingSkill > Player.hacking_skill) {
|
} else if (Player.getCurrentServer().requiredHackingSkill > Player.hacking_skill) {
|
||||||
post("Your hacking skill is not high enough to attempt hacking this machine. Try analyzing the machine to determine the required hacking skill");
|
post("Your hacking skill is not high enough to attempt hacking this machine. Try analyzing the machine to determine the required hacking skill");
|
||||||
} else {
|
} else {
|
||||||
Terminal.hackFlag = true;
|
Terminal.startHack();
|
||||||
hackProgressPost("Time left:");
|
|
||||||
hackProgressBarPost("[");
|
|
||||||
Player.hack();
|
|
||||||
|
|
||||||
//Disable terminal
|
|
||||||
document.getElementById("terminal-input-td").innerHTML = '<input type="text" class="terminal-input"/>';
|
|
||||||
$('input[class=terminal-input]').prop('disabled', true);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "help":
|
case "help":
|
||||||
@ -1964,9 +1963,9 @@ let Terminal = {
|
|||||||
post("Server base security level: " + targetServer.baseDifficulty);
|
post("Server base security level: " + targetServer.baseDifficulty);
|
||||||
post("Server current security level: " + targetServer.hackDifficulty);
|
post("Server current security level: " + targetServer.hackDifficulty);
|
||||||
post("Server growth rate: " + targetServer.serverGrowth);
|
post("Server growth rate: " + targetServer.serverGrowth);
|
||||||
post("Netscript hack() execution time: " + formatNumber(scriptCalculateHackingTime(targetServer), 1) + "s");
|
post("Netscript hack() execution time: " + formatNumber(calculateHackingTime(targetServer), 1) + "s");
|
||||||
post("Netscript grow() execution time: " + formatNumber(scriptCalculateGrowTime(targetServer)/1000, 1) + "s");
|
post("Netscript grow() execution time: " + formatNumber(calculateGrowTime(targetServer), 1) + "s");
|
||||||
post("Netscript weaken() execution time: " + formatNumber(scriptCalculateWeakenTime(targetServer)/1000, 1) + "s");
|
post("Netscript weaken() execution time: " + formatNumber(calculateWeakenTime(targetServer), 1) + "s");
|
||||||
};
|
};
|
||||||
programHandlers[Programs.AutoLink.name] = () => {
|
programHandlers[Programs.AutoLink.name] = () => {
|
||||||
post("This executable cannot be run.");
|
post("This executable cannot be run.");
|
||||||
@ -2125,6 +2124,7 @@ let Terminal = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
post("ERROR: No such script");
|
post("ERROR: No such script");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -150,7 +150,7 @@ $(document).keydown(function(e) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let Engine = {
|
const Engine = {
|
||||||
version: "",
|
version: "",
|
||||||
Debug: true,
|
Debug: true,
|
||||||
overview: new CharacterOverview(),
|
overview: new CharacterOverview(),
|
||||||
@ -570,7 +570,7 @@ let Engine = {
|
|||||||
|
|
||||||
var intText = "";
|
var intText = "";
|
||||||
if (Player.intelligence > 0) {
|
if (Player.intelligence > 0) {
|
||||||
intText = 'Intelligence: ' + (Player.intelligence).toLocaleString() + "<br><br><br>";
|
intText = 'Intelligence: ' + (Player.intelligence).toLocaleString() + '<br>';
|
||||||
}
|
}
|
||||||
|
|
||||||
let bitNodeTimeText = "";
|
let bitNodeTimeText = "";
|
||||||
@ -587,18 +587,18 @@ let Engine = {
|
|||||||
'Money: $' + formatNumber(Player.money.toNumber(), 2) + '<br><br><br>' +
|
'Money: $' + formatNumber(Player.money.toNumber(), 2) + '<br><br><br>' +
|
||||||
'<b>Stats</b><br><br>' +
|
'<b>Stats</b><br><br>' +
|
||||||
'Hacking Level: ' + (Player.hacking_skill).toLocaleString() +
|
'Hacking Level: ' + (Player.hacking_skill).toLocaleString() +
|
||||||
" (" + numeral(Player.hacking_exp).format('(0.000a)') + ' experience)<br>' +
|
' (' + numeral(Player.hacking_exp).format('(0.000a)') + ' experience)<br>' +
|
||||||
'Strength: ' + (Player.strength).toLocaleString() +
|
'Strength: ' + (Player.strength).toLocaleString() +
|
||||||
" (" + numeral(Player.strength_exp).format('(0.000a)') + ' experience)<br>' +
|
' (' + numeral(Player.strength_exp).format('(0.000a)') + ' experience)<br>' +
|
||||||
'Defense: ' + (Player.defense).toLocaleString() +
|
'Defense: ' + (Player.defense).toLocaleString() +
|
||||||
" (" + numeral(Player.defense_exp).format('(0.000a)')+ ' experience)<br>' +
|
' (' + numeral(Player.defense_exp).format('(0.000a)')+ ' experience)<br>' +
|
||||||
'Dexterity: ' + (Player.dexterity).toLocaleString() +
|
'Dexterity: ' + (Player.dexterity).toLocaleString() +
|
||||||
" (" + numeral(Player.dexterity_exp).format('(0.000a)') + ' experience)<br>' +
|
' (' + numeral(Player.dexterity_exp).format('(0.000a)') + ' experience)<br>' +
|
||||||
'Agility: ' + (Player.agility).toLocaleString() +
|
'Agility: ' + (Player.agility).toLocaleString() +
|
||||||
" (" + numeral(Player.agility_exp).format('(0.000a)') + ' experience)<br>' +
|
' (' + numeral(Player.agility_exp).format('(0.000a)') + ' experience)<br>' +
|
||||||
'Charisma: ' + (Player.charisma).toLocaleString() +
|
'Charisma: ' + (Player.charisma).toLocaleString() +
|
||||||
" (" + numeral(Player.charisma_exp).format('(0.000a)') + ' experience)<br>' +
|
' (' + numeral(Player.charisma_exp).format('(0.000a)') + ' experience)<br>' +
|
||||||
intText +
|
intText + '<br><br>' +
|
||||||
'<b>Multipliers</b><br><br>' +
|
'<b>Multipliers</b><br><br>' +
|
||||||
'Hacking Chance multiplier: ' + formatNumber(Player.hacking_chance_mult * 100, 2) + '%<br>' +
|
'Hacking Chance multiplier: ' + formatNumber(Player.hacking_chance_mult * 100, 2) + '%<br>' +
|
||||||
'Hacking Speed multiplier: ' + formatNumber(Player.hacking_speed_mult * 100, 2) + '%<br>' +
|
'Hacking Speed multiplier: ' + formatNumber(Player.hacking_speed_mult * 100, 2) + '%<br>' +
|
||||||
@ -923,14 +923,14 @@ let Engine = {
|
|||||||
Player.playtimeSinceLastBitnode += time;
|
Player.playtimeSinceLastBitnode += time;
|
||||||
|
|
||||||
//Start Manual hack
|
//Start Manual hack
|
||||||
if (Player.startAction == true) {
|
if (Terminal.actionStarted === true) {
|
||||||
Engine._totalActionTime = Player.actionTime;
|
Engine._totalActionTime = Terminal.actionTime;
|
||||||
Engine._actionTimeLeft = Player.actionTime;
|
Engine._actionTimeLeft = Terminal.actionTime;
|
||||||
Engine._actionInProgress = true;
|
Engine._actionInProgress = true;
|
||||||
Engine._actionProgressBarCount = 1;
|
Engine._actionProgressBarCount = 1;
|
||||||
Engine._actionProgressStr = "[ ]";
|
Engine._actionProgressStr = "[ ]";
|
||||||
Engine._actionTimeStr = "Time left: ";
|
Engine._actionTimeStr = "Time left: ";
|
||||||
Player.startAction = false;
|
Terminal.actionStarted = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Working
|
//Working
|
||||||
@ -1324,9 +1324,9 @@ let Engine = {
|
|||||||
Player.lastUpdate = Engine._lastUpdate;
|
Player.lastUpdate = Engine._lastUpdate;
|
||||||
Engine.start(); //Run main game loop and Scripts loop
|
Engine.start(); //Run main game loop and Scripts loop
|
||||||
removeLoadingScreen();
|
removeLoadingScreen();
|
||||||
dialogBoxCreate("While you were offline, your scripts generated $" +
|
dialogBoxCreate("While you were offline, your scripts generated <span class='money-gold'>$" +
|
||||||
formatNumber(offlineProductionFromScripts, 2) + " and your Hacknet Nodes generated $" +
|
formatNumber(offlineProductionFromScripts, 2) + "</span> and your Hacknet Nodes generated <span class='money-gold'>$" +
|
||||||
formatNumber(offlineProductionFromHacknetNodes, 2));
|
formatNumber(offlineProductionFromHacknetNodes, 2) + "</span>");
|
||||||
//Close main menu accordions for loaded game
|
//Close main menu accordions for loaded game
|
||||||
var visibleMenuTabs = [terminal, createScript, activeScripts, stats,
|
var visibleMenuTabs = [terminal, createScript, activeScripts, stats,
|
||||||
hacknetnodes, city, tutorial, options, dev];
|
hacknetnodes, city, tutorial, options, dev];
|
||||||
|
1024
src/index.html
Normal file
1024
src/index.html
Normal file
File diff suppressed because it is too large
Load Diff
@ -48,6 +48,7 @@
|
|||||||
"ignore-params",
|
"ignore-params",
|
||||||
"ignore-properties"
|
"ignore-properties"
|
||||||
],
|
],
|
||||||
|
"no-magic-numbers": [true, -1, 0, 1, 2, 10, 100],
|
||||||
"no-null-keyword": false,
|
"no-null-keyword": false,
|
||||||
"no-unsafe-any": false,
|
"no-unsafe-any": false,
|
||||||
"object-literal-key-quotes": [
|
"object-literal-key-quotes": [
|
||||||
@ -59,6 +60,7 @@
|
|||||||
"allow-declarations",
|
"allow-declarations",
|
||||||
"allow-named-functions"
|
"allow-named-functions"
|
||||||
],
|
],
|
||||||
|
"triple-equals": [true, "allow-null-check", "allow-undefined-check"],
|
||||||
"typedef": [
|
"typedef": [
|
||||||
true,
|
true,
|
||||||
"call-signatures",
|
"call-signatures",
|
||||||
|
@ -57,9 +57,9 @@ function infiltrationBoxCreate(inst) {
|
|||||||
CONSTANTS.InfiltrationRepValue * BitNodeMultipliers.InfiltrationRep;
|
CONSTANTS.InfiltrationRepValue * BitNodeMultipliers.InfiltrationRep;
|
||||||
var moneyValue = totalValue * CONSTANTS.InfiltrationMoneyValue * BitNodeMultipliers.InfiltrationMoney;
|
var moneyValue = totalValue * CONSTANTS.InfiltrationMoneyValue * BitNodeMultipliers.InfiltrationMoney;
|
||||||
infiltrationSetText("You can sell the classified documents and secrets " +
|
infiltrationSetText("You can sell the classified documents and secrets " +
|
||||||
"you stole from " + inst.companyName + " for $" +
|
"you stole from " + inst.companyName + " for <span class='money-gold'>$" +
|
||||||
formatNumber(moneyValue, 2) + " on the black market or you can give it " +
|
formatNumber(moneyValue, 2) + "</span> on the black market or you can give it " +
|
||||||
"to a faction to gain " + formatNumber(facValue, 3) + " reputation with " +
|
"to a faction to gain <span class='light-yellow'>" + formatNumber(facValue, 3) + " reputation</span> with " +
|
||||||
"that faction.");
|
"that faction.");
|
||||||
var selector = document.getElementById("infiltration-faction-select");
|
var selector = document.getElementById("infiltration-faction-select");
|
||||||
selector.innerHTML = "";
|
selector.innerHTML = "";
|
||||||
@ -85,7 +85,7 @@ function infiltrationBoxCreate(inst) {
|
|||||||
if (!e.isTrusted) {return false;}
|
if (!e.isTrusted) {return false;}
|
||||||
Player.gainMoney(moneyValue);
|
Player.gainMoney(moneyValue);
|
||||||
dialogBoxCreate("You sold the classified information you stole from " + inst.companyName +
|
dialogBoxCreate("You sold the classified information you stole from " + inst.companyName +
|
||||||
" for $" + moneyValue + " on the black market!<br><br>" +
|
" for <span class='money-gold'>$" + formatNumber(moneyValue, 2) + "</span> on the black market!<br><br>" +
|
||||||
"You gained:<br>" +
|
"You gained:<br>" +
|
||||||
formatNumber(inst.hackingExpGained, 3) + " hacking exp<br>" +
|
formatNumber(inst.hackingExpGained, 3) + " hacking exp<br>" +
|
||||||
formatNumber(inst.strExpGained, 3) + " str exp<br>" +
|
formatNumber(inst.strExpGained, 3) + " str exp<br>" +
|
||||||
@ -111,7 +111,7 @@ function infiltrationBoxCreate(inst) {
|
|||||||
}
|
}
|
||||||
faction.playerReputation += facValue;
|
faction.playerReputation += facValue;
|
||||||
dialogBoxCreate("You gave the classified information you stole from " + inst.companyName +
|
dialogBoxCreate("You gave the classified information you stole from " + inst.companyName +
|
||||||
" to " + facName + " and gained " + formatNumber(facValue, 3) + " reputation with the faction. <br><br>" +
|
" to " + facName + " and gained <span class='light-yellow'>" + formatNumber(facValue, 3) + " reputation</span> with the faction. <br><br>" +
|
||||||
"You gained:<br>" +
|
"You gained:<br>" +
|
||||||
formatNumber(inst.hackingExpGained, 3) + " hacking exp<br>" +
|
formatNumber(inst.hackingExpGained, 3) + " hacking exp<br>" +
|
||||||
formatNumber(inst.strExpGained, 3) + " str exp<br>" +
|
formatNumber(inst.strExpGained, 3) + " str exp<br>" +
|
||||||
|
@ -34,11 +34,14 @@ export function createProgressBarText(params: IProgressBarConfiguration) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// tslint:disable-next-line:prefer-object-spread
|
// tslint:disable-next-line:prefer-object-spread
|
||||||
const derivedParams: IProgressBarConfigurationMaterialized = Object.assign({}, defaultParams, params);
|
const derived: IProgressBarConfigurationMaterialized = Object.assign({}, defaultParams, params);
|
||||||
|
// Ensure it is 0..1
|
||||||
|
derived.progress = Math.max(Math.min(derived.progress, 1), 0);
|
||||||
|
|
||||||
const bars: number = Math.floor(derivedParams.progress / (1 / derivedParams.totalTicks));
|
// This way there is always at least one bar filled in...
|
||||||
const dashes: number = derivedParams.totalTicks - bars;
|
const bars: number = Math.max(Math.floor(derived.progress / (1 / derived.totalTicks)), 1);
|
||||||
|
const dashes: number = Math.max(derived.totalTicks - bars, 0);
|
||||||
|
|
||||||
// String.prototype.repeat isn't completley supported, but good enough for our purposes
|
// String.prototype.repeat isn't completley supported, but good enough for our purposes
|
||||||
return `[${"|".repeat(bars + 1)}${"-".repeat(dashes + 1)}]`;
|
return `[${"|".repeat(bars)}${"-".repeat(dashes)}]`;
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
/**
|
||||||
|
* Returns a MM/DD HH:MM timestamp for the current time
|
||||||
|
*/
|
||||||
export function getTimestamp() {
|
export function getTimestamp() {
|
||||||
const d: Date = new Date();
|
const d: Date = new Date();
|
||||||
// A negative slice value takes from the end of the string rather than the beginning.
|
// A negative slice value takes from the end of the string rather than the beginning.
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
var path = require('path');
|
var path = require('path');
|
||||||
var webpack = require('webpack');
|
var webpack = require('webpack');
|
||||||
var MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
var MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
||||||
|
var HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||||
|
|
||||||
module.exports = (env, argv) => ({
|
module.exports = (env, argv) => ({
|
||||||
plugins: [
|
plugins: [
|
||||||
@ -16,6 +17,45 @@ module.exports = (env, argv) => ({
|
|||||||
jQuery: "jquery",
|
jQuery: "jquery",
|
||||||
$: "jquery"
|
$: "jquery"
|
||||||
}),
|
}),
|
||||||
|
new HtmlWebpackPlugin({
|
||||||
|
title: "Bitburner" + (argv.mode === 'development' ? ' - development' : ""),
|
||||||
|
template: "src/index.html",
|
||||||
|
favicon: "favicon.ico",
|
||||||
|
googleAnalytics: {
|
||||||
|
trackingId: 'UA-100157497-1'
|
||||||
|
},
|
||||||
|
meta: {},
|
||||||
|
minify: argv.mode === 'development' ? false : {
|
||||||
|
collapseBooleanAttributes: true,
|
||||||
|
collapseInlineTagWhitespace: false,
|
||||||
|
collapseWhitespace: false,
|
||||||
|
conservativeCollapse: false,
|
||||||
|
html5: true,
|
||||||
|
includeAutoGeneratedTags: false,
|
||||||
|
keepClosingSlash: true,
|
||||||
|
minifyCSS: false,
|
||||||
|
minifyJS: false,
|
||||||
|
minifyURLs: false,
|
||||||
|
preserveLineBreaks: false,
|
||||||
|
preventAttributesEscaping: false,
|
||||||
|
processConditionalComments: false,
|
||||||
|
quoteCharacter: "\"",
|
||||||
|
removeAttributeQuotes: false,
|
||||||
|
removeComments: false,
|
||||||
|
removeEmptyAttributes: false,
|
||||||
|
removeEmptyElements: false,
|
||||||
|
removeOptionalTags: false,
|
||||||
|
removeScriptTypeAttributes: false,
|
||||||
|
removeStyleLinkTypeAttributes: false,
|
||||||
|
removeTagWhitespace: false,
|
||||||
|
sortAttributes: false,
|
||||||
|
sortClassName: false,
|
||||||
|
useShortDoctype: false
|
||||||
|
},
|
||||||
|
excludeChunks: [
|
||||||
|
"tests/tests"
|
||||||
|
]
|
||||||
|
}),
|
||||||
new MiniCssExtractPlugin({
|
new MiniCssExtractPlugin({
|
||||||
filename: "[name].css",
|
filename: "[name].css",
|
||||||
chunkFilename: "[id].css"
|
chunkFilename: "[id].css"
|
||||||
|
Loading…
Reference in New Issue
Block a user