mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-11-30 03:23:48 +01:00
Fixed merge conflicts with dev
This commit is contained in:
commit
b5ebbba43d
2
dist/engine.bundle.js
vendored
2
dist/engine.bundle.js
vendored
File diff suppressed because one or more lines are too long
125
dist/engine.css
vendored
125
dist/engine.css
vendored
@ -486,6 +486,7 @@ button {
|
||||
box-shadow: inset 0 1px 4px rgba(0, 0, 0, 0.6); }
|
||||
|
||||
.a-link-button-inactive,
|
||||
.std-button-disabled,
|
||||
.std-button:disabled {
|
||||
text-decoration: none;
|
||||
background-color: #333;
|
||||
@ -501,11 +502,15 @@ button {
|
||||
.a-link-button-inactive:hover .tooltiptext,
|
||||
.a-link-button-inactive:hover .tooltiptexthigh,
|
||||
.a-link-button-inactive:hover .tooltiptextleft,
|
||||
.std-button-disabled:hover .tooltiptext,
|
||||
.std-button-disabled:hover .tooltiptexthigh,
|
||||
.std-button-disabled:hover .tooltiptextleft,
|
||||
.std-button:disabled:hover .tooltiptext,
|
||||
.std-button:disabled:hover .tooltiptexthigh,
|
||||
.std-button:disabled:hover .tooltiptextleft {
|
||||
visibility: visible; }
|
||||
.a-link-button-inactive:active,
|
||||
.std-button-disabled:active,
|
||||
.std-button:disabled:active {
|
||||
pointer-events: none; }
|
||||
|
||||
@ -671,7 +676,7 @@ button {
|
||||
/* COLORS */
|
||||
/* Attributes */
|
||||
/**
|
||||
* Styling for the Character Overview Panel (top-right)
|
||||
* Styling for the Character Overview Panel (top-right panel)
|
||||
*/
|
||||
#character-overview-wrapper {
|
||||
position: relative; }
|
||||
@ -927,6 +932,64 @@ button {
|
||||
|
||||
/* Specified overrides for Code mirror Editor are defined in codemirror-override.scss */
|
||||
|
||||
/* COLORS */
|
||||
/* Attributes */
|
||||
/**
|
||||
* Styling for the Hacknet Nodes UI Page
|
||||
*/
|
||||
#hacknet-nodes-container {
|
||||
position: fixed;
|
||||
padding: 10px; }
|
||||
|
||||
.hacknet-general-info {
|
||||
margin: 10px;
|
||||
width: 70vw; }
|
||||
|
||||
#hacknet-nodes-container li {
|
||||
float: left;
|
||||
overflow: hidden;
|
||||
white-space: nowrap; }
|
||||
#hacknet-nodes-container li.hacknet-node {
|
||||
-webkit-box-shadow: inset 0 0 8px rgba(0, 0, 0, 0.1), 0 0 16px rgba(0, 0, 0, 0.1);
|
||||
-moz-box-shadow: inset 0 0 8px rgba(0, 0, 0, 0.1), 0 0 16px rgba(0, 0, 0, 0.1);
|
||||
box-shadow: inset 0 0 8px rgba(0, 0, 0, 0.1), 0 0 16px rgba(0, 0, 0, 0.1);
|
||||
margin: 6px;
|
||||
padding: 7px;
|
||||
width: 35vw;
|
||||
border: 2px solid var(--my-highlight-color); }
|
||||
|
||||
#hacknet-nodes-list {
|
||||
list-style: none;
|
||||
width: 82vw; }
|
||||
|
||||
#hacknet-nodes-money {
|
||||
margin: 10px;
|
||||
float: left; }
|
||||
|
||||
#hacknet-nodes-money-multipliers-div {
|
||||
display: inline-block;
|
||||
width: 70vw; }
|
||||
|
||||
#hacknet-nodes-multipliers {
|
||||
float: right; }
|
||||
|
||||
#hacknet-nodes-purchase-button {
|
||||
display: inline-block; }
|
||||
|
||||
.hacknet-node-container {
|
||||
display: inline-table; }
|
||||
.hacknet-node-container .row {
|
||||
display: table-row;
|
||||
height: 30px; }
|
||||
.hacknet-node-container .row p {
|
||||
display: table-cell; }
|
||||
.hacknet-node-container .upgradable-info {
|
||||
display: inline-block;
|
||||
margin: 0 4px;
|
||||
/* Don't want the vertical margin/padding, just left & right */
|
||||
padding: 0 4px;
|
||||
width: 64px; }
|
||||
|
||||
/* COLORS */
|
||||
/* Attributes */
|
||||
/* CSS for different main menu pages, such as character info, script editor, etc (but excluding
|
||||
@ -1044,64 +1107,6 @@ button {
|
||||
color: #fff;
|
||||
margin-left: 5%; }
|
||||
|
||||
/* Hacknet Nodes */
|
||||
#hacknet-nodes-container {
|
||||
position: fixed;
|
||||
padding: 10px; }
|
||||
|
||||
#hacknet-nodes-text,
|
||||
#hacknet-nodes-container li {
|
||||
margin: 10px;
|
||||
padding: 10px; }
|
||||
|
||||
#hacknet-nodes-container li {
|
||||
float: left;
|
||||
overflow: hidden;
|
||||
white-space: nowrap; }
|
||||
#hacknet-nodes-container li.hacknet-node {
|
||||
-webkit-box-shadow: inset 0 0 8px rgba(0, 0, 0, 0.1), 0 0 16px rgba(0, 0, 0, 0.1);
|
||||
-moz-box-shadow: inset 0 0 8px rgba(0, 0, 0, 0.1), 0 0 16px rgba(0, 0, 0, 0.1);
|
||||
box-shadow: inset 0 0 8px rgba(0, 0, 0, 0.1), 0 0 16px rgba(0, 0, 0, 0.1);
|
||||
margin: 6px;
|
||||
padding: 7px;
|
||||
width: 35vw;
|
||||
border: 2px solid var(--my-highlight-color); }
|
||||
|
||||
#hacknet-nodes-list {
|
||||
list-style: none;
|
||||
width: 82vw; }
|
||||
|
||||
#hacknet-nodes-money {
|
||||
margin: 10px;
|
||||
float: left; }
|
||||
|
||||
#hacknet-nodes-money-multipliers-div {
|
||||
display: inline-block;
|
||||
width: 70vw; }
|
||||
|
||||
#hacknet-nodes-multipliers {
|
||||
float: right; }
|
||||
|
||||
#hacknet-nodes-purchase-button {
|
||||
display: inline-block; }
|
||||
|
||||
.hacknet-node-container {
|
||||
display: inline-table; }
|
||||
.hacknet-node-container .row {
|
||||
display: table-row;
|
||||
height: 30px; }
|
||||
.hacknet-node-container .row p {
|
||||
display: table-cell; }
|
||||
.hacknet-node-container .upgradable-info {
|
||||
display: inline-block;
|
||||
margin: 0 4px;
|
||||
/* Don't want the vertical margin/padding, just left & right */
|
||||
padding: 0 4px;
|
||||
width: 64px; }
|
||||
|
||||
.menu-page-text {
|
||||
width: 70vw; }
|
||||
|
||||
/* World */
|
||||
#world-container {
|
||||
position: fixed;
|
||||
@ -1402,7 +1407,7 @@ button {
|
||||
/* Pop-up boxes */
|
||||
.popup-box-container {
|
||||
display: none;
|
||||
/* Hidden by default */
|
||||
/* Initially hidden */
|
||||
position: fixed;
|
||||
/* Stay in place */
|
||||
z-index: 10;
|
||||
|
130
dist/vendor.bundle.js
vendored
130
dist/vendor.bundle.js
vendored
File diff suppressed because one or more lines are too long
@ -3,6 +3,24 @@
|
||||
Changelog
|
||||
=========
|
||||
|
||||
v0.46.0 - 4/3/2019
|
||||
------------------
|
||||
* Added BitNode-9: Hacktocracy
|
||||
* Changed BitNode-11's multipliers to make it slightly harder overall
|
||||
* Source-File 11 is now slightly stronger
|
||||
* Added several functions to Netscript Sleeve API for buying Sleeve augmentations (by hydroflame)
|
||||
* Added a new stat for Duplicate Sleeves: Memory
|
||||
* Increase baseline experience earned from Infiltration, but it now gives diminishing returns (on exp) as you get to higher difficulties/levels
|
||||
* In Bladeburner, stamina gained from Hyperbolic Regeneration Chamber is now a percentage of your max stamina
|
||||
|
||||
* Corporation Changes:
|
||||
* 'Demand' value of products decreases more slowly
|
||||
* Bug Fix: Fixed a Corporation issue that broke the Market-TA2 Research
|
||||
* Bug Fix: Issuing New Shares now works properly
|
||||
|
||||
* Bug Fix: Money Statistics tracker was incorrectly recording profits when selling stocks manually
|
||||
* Bug Fix: Fixed an issue with the job requirement tooltip for security jobs
|
||||
|
||||
v0.45.1 - 3/23/2019
|
||||
-------------------
|
||||
* Added two new Corporation Researches
|
||||
|
@ -64,9 +64,9 @@ documentation_title = '{0} Documentation'.format(project)
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = '0.45'
|
||||
version = '0.46'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '0.45.0'
|
||||
release = '0.46.0'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
|
17
doc/source/netscript/hacknetnodeapi/getCacheUpgradeCost.rst
Normal file
17
doc/source/netscript/hacknetnodeapi/getCacheUpgradeCost.rst
Normal file
@ -0,0 +1,17 @@
|
||||
getCacheUpgradeCost() Netscript Function
|
||||
========================================
|
||||
|
||||
.. warning:: This page contains spoilers for the game
|
||||
|
||||
.. js:function:: getCacheUpgradeCost(i, n)
|
||||
|
||||
:param number i: Index/Identifier of Hacknet Node. :ref:`See here for details <netscript_hacknetnodeapi_referencingahacknetnode>`
|
||||
:param number n: Number of times to upgrade cache. Must be positive. Rounded to nearest integer
|
||||
|
||||
.. note:: This function is only applicable for Hacknet Servers (the upgraded version of
|
||||
a Hacknet Node).
|
||||
|
||||
Returns the cost of upgrading the cache level of the specified Hacknet Server by *n*.
|
||||
|
||||
If an invalid value for *n* is provided, then this function returns 0. If the
|
||||
specified Hacknet Server is already at the max cache level, then Infinity is returned.
|
@ -1,6 +1,8 @@
|
||||
getNodeStats() Netscript Function
|
||||
=================================
|
||||
|
||||
.. warning:: This page contains spoilers for the game
|
||||
|
||||
.. js:function:: getNodeStats(i)
|
||||
|
||||
:param number i: Index/Identifier of Hacknet Node. :ref:`See here for details <netscript_hacknetnodeapi_referencingahacknetnode>`
|
||||
@ -12,7 +14,12 @@ getNodeStats() Netscript Function
|
||||
level: Node's level,
|
||||
ram: Node's RAM,
|
||||
cores: Node's number of cores,
|
||||
production: Node's money earned per second,
|
||||
cache: Cache level. Only applicable for Hacknet Servers
|
||||
production: Node's production per second
|
||||
timeOnline: Number of seconds since Node has been purchased,
|
||||
totalProduction: Total number of money Node has produced
|
||||
totalProduction: Total amount that the Node has produced
|
||||
}
|
||||
|
||||
.. note:: Note that for Hacknet Nodes, production refers to the amount of money the node generates.
|
||||
For Hacknet Servers (the upgraded version of Hacknet Nodes), production refers to the amount
|
||||
of hashes the node generates.
|
||||
|
19
doc/source/netscript/hacknetnodeapi/upgradeCache.rst
Normal file
19
doc/source/netscript/hacknetnodeapi/upgradeCache.rst
Normal file
@ -0,0 +1,19 @@
|
||||
upgradeCache() Netscript Function
|
||||
=================================
|
||||
|
||||
.. warning:: This page contains spoilers for the game
|
||||
|
||||
.. js:function:: upgradeCache(i, n)
|
||||
|
||||
:param number i: Index/Identifier of Hacknet Node. :ref:`See here for details <netscript_hacknetnodeapi_referencingahacknetnode>`
|
||||
:param number n: Number of cache levels to purchase. Must be positive. Rounded to nearest integer
|
||||
|
||||
.. note:: This function is only applicable for Hacknet Servers (the upgraded version of
|
||||
a Hacknet Node).
|
||||
|
||||
Tries to upgrade the specified Hacknet Server's cache *n* times.
|
||||
|
||||
Returns true if it successfully upgrades the Server's cache *n* times, or if
|
||||
it purchases some positive amount and the Server reaches its max cache level.
|
||||
|
||||
Returns false otherwise.
|
@ -31,9 +31,11 @@ In :ref:`netscriptjs`::
|
||||
upgradeLevel() <hacknetnodeapi/upgradeLevel>
|
||||
upgradeRam() <hacknetnodeapi/upgradeRam>
|
||||
upgradeCore() <hacknetnodeapi/upgradeCore>
|
||||
upgradeCache() <hacknetnodeapi/upgradeCache>
|
||||
getLevelUpgradeCost() <hacknetnodeapi/getLevelUpgradeCost>
|
||||
getRamUpgradeCost() <hacknetnodeapi/getRamUpgradeCost>
|
||||
getCoreUpgradeCost() <hacknetnodeapi/getCoreUpgradeCost>
|
||||
getCacheUpgradeCost() <hacknetnodeapi/getCacheUpgradeCost>
|
||||
|
||||
.. _netscript_hacknetnodeapi_referencingahacknetnode:
|
||||
|
||||
@ -68,23 +70,25 @@ The following is an example of one way a script can be used to automate the
|
||||
purchasing and upgrading of Hacknet Nodes.
|
||||
|
||||
This script attempts to purchase Hacknet Nodes until the player has a total of 8. Then
|
||||
it gradually upgrades those Node's to a minimum of level 140, 64 GB RAM, and 8 cores::
|
||||
it gradually upgrades those Node's to a minimum of level 140, 64 GB RAM, and 8 cores
|
||||
|
||||
.. code:: javascript
|
||||
|
||||
function myMoney() {
|
||||
return getServerMoneyAvailable("home");() <hacknetnodeapi/ return getServerMoneyAvailable("home");>
|
||||
return getServerMoneyAvailable("home");
|
||||
}
|
||||
}() <hacknetnodeapi/>
|
||||
|
||||
disableLog("getServerMoneyAvailable");
|
||||
disableLog("sleep");
|
||||
|
||||
cnt = 8;
|
||||
var cnt = 8;
|
||||
|
||||
while(hacknet.numNodes() < cnt) {
|
||||
res = hacknet.purchaseNode();
|
||||
print("Purchased hacknet Node with index " + res);
|
||||
};
|
||||
|
||||
for (i = 0; i < cnt; i++) {
|
||||
for (var i = 0; i < cnt; i++) {
|
||||
while (hacknet.getNodeStats(i).level <= 80) {
|
||||
var cost = hacknet.getLevelUpgradeCost(i, 10);
|
||||
while (myMoney() < cost) {
|
||||
@ -95,9 +99,9 @@ it gradually upgrades those Node's to a minimum of level 140, 64 GB RAM, and 8 c
|
||||
};
|
||||
};
|
||||
|
||||
print("All nodes upgrade to level 80");
|
||||
print("All nodes upgraded to level 80");
|
||||
|
||||
for (i = 0; i < cnt; i++) {
|
||||
for (var i = 0; i < cnt; i++) {
|
||||
while (hacknet.getNodeStats(i).ram < 16) {
|
||||
var cost = hacknet.getRamUpgradeCost(i, 2);
|
||||
while (myMoney() < cost) {
|
||||
@ -108,43 +112,4 @@ it gradually upgrades those Node's to a minimum of level 140, 64 GB RAM, and 8 c
|
||||
};
|
||||
};
|
||||
|
||||
print("All nodes upgrade to 16GB RAM");
|
||||
|
||||
for (i = 0; i < cnt; i++) {
|
||||
while (hacknet.getNodeStats(i).level <= 140) {
|
||||
var cost = hacknet.getLevelUpgradeCost(i, 5);
|
||||
while (myMoney() < cost) {
|
||||
print("Need $" + cost + " . Have $" + myMoney());
|
||||
sleep(3000);
|
||||
}
|
||||
res = hacknet.upgradeLevel(i, 5);
|
||||
};
|
||||
};
|
||||
|
||||
print("All nodes upgrade to level 140");
|
||||
|
||||
for (i = 0; i < cnt; i++) {
|
||||
while (hacknet.getNodeStats(i).ram < 64) {
|
||||
var cost = hacknet.getRamUpgradeCost(i, 2);
|
||||
while (myMoney() < cost) {
|
||||
print("Need $" + cost + " . Have $" + myMoney());
|
||||
sleep(3000);
|
||||
}
|
||||
res = hacknet.upgradeRam(i, 2);
|
||||
};
|
||||
};
|
||||
|
||||
print("All nodes upgrade to 64GB RAM (MAX)");
|
||||
|
||||
for (i = 0; i < cnt; i++) {
|
||||
while (hacknetnodes.getNodeStatsi(i).cores < 8) {
|
||||
var cost = hacknet.getCoreUpgradeCost(7);
|
||||
while (myMoney() < cost) {
|
||||
print("Need $" + cost + " . Have $" + myMoney());
|
||||
sleep(3000);
|
||||
}
|
||||
res = hacknet.upgradeCore(i, 7);
|
||||
};
|
||||
};
|
||||
|
||||
print("All nodes upgrade to 8 cores");
|
||||
print("All nodes upgraded to 16GB RAM");
|
||||
|
30
index.html
30
index.html
@ -201,35 +201,7 @@
|
||||
|
||||
<!-- Hacknet Nodes -->
|
||||
<div id="hacknet-nodes-container" class="generic-menupage-container">
|
||||
<h1 id="hacknet-nodes-title"> Hacknet Nodes </h1>
|
||||
<p id="hacknet-nodes-text" class="menu-page-text">
|
||||
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
|
||||
fear of being traced.
|
||||
<br/><br/>
|
||||
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
|
||||
from hacks performed on the network. Essentially, you are renting out your Node's computing power.
|
||||
<br/><br/>
|
||||
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.
|
||||
</p>
|
||||
<a id="hacknet-nodes-purchase-button" class="a-link-button"> Purchase Hacknet Node </a>
|
||||
<br/>
|
||||
<div id="hacknet-nodes-money-multipliers-div">
|
||||
<p id="hacknet-nodes-money">
|
||||
<span>Money:</span><span id="hacknet-nodes-player-money" class="money-gold"></span><br/>
|
||||
<span>Total Hacknet Node Production:</span><span id="hacknet-nodes-total-production" class="money-gold"></span>
|
||||
</p>
|
||||
<span id="hacknet-nodes-multipliers">
|
||||
<a id="hacknet-nodes-1x-multiplier" class="a-link-button-inactive"> x1 </a>
|
||||
<a id="hacknet-nodes-5x-multiplier" class="a-link-button"> x5 </a>
|
||||
<a id="hacknet-nodes-10x-multiplier" class="a-link-button"> x10 </a>
|
||||
<a id="hacknet-nodes-max-multiplier" class="a-link-button"> MAX </a>
|
||||
</span>
|
||||
</div>
|
||||
<ul id="hacknet-nodes-list">
|
||||
</ul>
|
||||
<!-- React Component -->
|
||||
</div>
|
||||
|
||||
<!-- World -->
|
||||
|
@ -176,7 +176,21 @@ export function initBitNodes() {
|
||||
BitNodes["BitNode9"] = new BitNode(9, "Hacktocracy", "Hacknet Unleashed",
|
||||
"When Fulcrum Technologies released their open-source Linux distro Chapeau, it quickly " +
|
||||
"became the OS of choice for the underground hacking community. Chapeau became especially notorious for " +
|
||||
"powering the Hacknet, ");
|
||||
"powering the Hacknet, a global, decentralized network used for nefarious purposes. Fulcrum quickly " +
|
||||
"abandoned the project and dissociated themselves from it.<br><br>" +
|
||||
"This BitNode unlocks the Hacknet Server, an upgraded version of the Hacknet Node. Hacknet Servers generate " +
|
||||
"hashes, which can be spent on a variety of different upgrades.<br><br>" +
|
||||
"In this BitNode:<br><br>" +
|
||||
"Your stats are significantly decreased<br>" +
|
||||
"You cannnot purchase additional servers<br>" +
|
||||
"Hacking is significantly less profitable<br><br>" +
|
||||
"Destroying this BitNode will give you Source-File 9, or if you already have this Source-File it will " +
|
||||
"upgrade its level up to a maximum of 3. This Source-File grants the following benefits:<br><br>" +
|
||||
"Level 1: Permanently unlocks the Hacknet Server in other BitNodes<br>" +
|
||||
"Level 2: You start with 128GB of RAM on your home computer when entering a new BitNode<br>" +
|
||||
"Level 3: Grants a highly-upgraded Hacknet Server when entering a new BitNode<br><br>" +
|
||||
"(Note that the Level 3 effect of this Source-File only applies when entering a new BitNode, NOT " +
|
||||
"when installing Augmentations)");
|
||||
BitNodes["BitNode10"] = new BitNode(10, "Digital Carbon", "Your body is not who you are",
|
||||
"In 2084, VitaLife unveiled to the world the Persona Core, a technology that allowed people " +
|
||||
"to digitize their consciousness. Their consciousness could then be transferred into Synthoids " +
|
||||
@ -186,7 +200,7 @@ export function initBitNodes() {
|
||||
"1. Re-sleeve: Purchase and transfer your consciousness into a new body<br>" +
|
||||
"2. Duplicate Sleeves: Duplicate your consciousness into Synthoids, allowing you to perform different tasks synchronously<br><br>" +
|
||||
"In this BitNode:<br><br>" +
|
||||
"Your stats are significantly decreased.<br>" +
|
||||
"Your stats are significantly decreased<br>" +
|
||||
"All methods of gaining money are half as profitable (except Stock Market)<br>" +
|
||||
"Purchased servers are more expensive, have less max RAM, and a lower maximum limit<br>" +
|
||||
"Augmentations are 5x as expensive and require twice as much reputation<br><br>" +
|
||||
@ -360,11 +374,15 @@ export function initBitNodeMultipliers(p: IPlayer) {
|
||||
BitNodeMultipliers.HomeComputerRamCost = 5;
|
||||
BitNodeMultipliers.CrimeMoney = 0.5;
|
||||
BitNodeMultipliers.ScriptHackMoney = 0.1;
|
||||
BitNodeMultipliers.HackExpGain = 0.1;
|
||||
BitNodeMultipliers.HackExpGain = 0.05;
|
||||
BitNodeMultipliers.ServerStartingMoney = 0.1;
|
||||
BitNodeMultipliers.ServerMaxMoney = 0.1;
|
||||
BitNodeMultipliers.ServerStartingSecurity = 2.5;
|
||||
BitNodeMultipliers.CorporationValuation = 0.5;
|
||||
BitNodeMultipliers.FourSigmaMarketDataCost = 5;
|
||||
BitNodeMultipliers.FourSigmaMarketDataApiCost = 4;
|
||||
BitNodeMultipliers.BladeburnerRank = 0.9;
|
||||
BitNodeMultipliers.BladeburnerSkillCost = 1.2;
|
||||
break;
|
||||
case 10: // Digital Carbon
|
||||
BitNodeMultipliers.HackingLevelMultiplier = 0.2;
|
||||
|
@ -6,7 +6,7 @@
|
||||
import {IMap} from "./types";
|
||||
|
||||
export let CONSTANTS: IMap<any> = {
|
||||
Version: "0.45.1",
|
||||
Version: "0.46.0",
|
||||
|
||||
//Max level for any skill, assuming no multipliers. Determined by max numerical value in javascript for experience
|
||||
//and the skill level formula in Player.js. Note that all this means it that when experience hits MAX_INT, then
|
||||
@ -285,6 +285,7 @@ export let CONSTANTS: IMap<any> = {
|
||||
* Corporation Changes:
|
||||
** 'Demand' value of products decreases more slowly
|
||||
** Bug Fix: Fixed a Corporation issue that broke the Market-TA2 Research
|
||||
** Bug Fix: Issuing New Shares now works properly
|
||||
|
||||
* Bug Fix: Money Statistics tracker was incorrectly recording profits when selling stocks manually
|
||||
* Bug Fix: Fixed an issue with the job requirement tooltip for security jobs
|
||||
|
@ -31,6 +31,7 @@ import { numeralWrapper } from "../../ui/numeralFormat";
|
||||
|
||||
import { dialogBoxCreate } from "../../../utils/DialogBox";
|
||||
|
||||
import { getRandomInt } from "../../../utils/helpers/getRandomInt";
|
||||
import { KEY } from "../../../utils/helpers/keyCodes";
|
||||
|
||||
import { clearSelector } from "../../../utils/uiHelpers/clearSelector";
|
||||
|
1
src/Hacking/README.md
Normal file
1
src/Hacking/README.md
Normal file
@ -0,0 +1 @@
|
||||
Implementation of underlying Hacking mechanics
|
53
src/Hacking/netscriptCanHack.ts
Normal file
53
src/Hacking/netscriptCanHack.ts
Normal file
@ -0,0 +1,53 @@
|
||||
/**
|
||||
* Functions used to determine whether the target can be hacked (or grown/weakened).
|
||||
* Meant to be used for Netscript implementation
|
||||
*
|
||||
* The returned status object's message should be used for logging in Netscript
|
||||
*/
|
||||
import { IReturnStatus } from "../types";
|
||||
|
||||
import { HacknetServer } from "../Hacknet/HacknetServer";
|
||||
import { IPlayer } from "../PersonObjects/IPlayer";
|
||||
import { Server } from "../Server/Server";
|
||||
|
||||
function baseCheck(server: Server | HacknetServer, fnName: string): IReturnStatus {
|
||||
if (server instanceof HacknetServer) {
|
||||
return {
|
||||
res: false,
|
||||
msg: `Cannot ${fnName} ${server.hostname} server because it is a Hacknet Node`
|
||||
}
|
||||
}
|
||||
|
||||
if (server.hasAdminRights === false) {
|
||||
return {
|
||||
res: false,
|
||||
msg: `Cannot ${fnName} ${server.hostname} server because you do not have root access`,
|
||||
}
|
||||
}
|
||||
|
||||
return { res: true }
|
||||
}
|
||||
|
||||
export function netscriptCanHack(server: Server | HacknetServer, p: IPlayer): IReturnStatus {
|
||||
const initialCheck = baseCheck(server, "hack");
|
||||
if (!initialCheck.res) { return initialCheck; }
|
||||
|
||||
let s = <Server>server;
|
||||
|
||||
if (s.requiredHackingSkill > p.hacking_skill) {
|
||||
return {
|
||||
res: false,
|
||||
msg: `Cannot hack ${server.hostname} server because your hacking skill is not high enough`,
|
||||
}
|
||||
}
|
||||
|
||||
return { res: true }
|
||||
}
|
||||
|
||||
export function netscriptCanGrow(server: Server | HacknetServer): IReturnStatus {
|
||||
return baseCheck(server, "grow");
|
||||
}
|
||||
|
||||
export function netscriptCanWeaken(server: Server | HacknetServer): IReturnStatus {
|
||||
return baseCheck(server, "weaken");
|
||||
}
|
@ -45,6 +45,25 @@ export function hasHacknetServers() {
|
||||
return (Player.bitNodeN === 9 || SourceFileFlags[9] > 0);
|
||||
}
|
||||
|
||||
export function createHacknetServer() {
|
||||
const numOwned = Player.hacknetNodes.length;
|
||||
const name = `hacknet-node-${numOwned}`;
|
||||
const server = new HacknetServer({
|
||||
adminRights: true,
|
||||
hostname: name,
|
||||
player: Player,
|
||||
});
|
||||
Player.hacknetNodes.push(server.ip);
|
||||
|
||||
// Configure the HacknetServer to actually act as a Server
|
||||
AddToAllServers(server);
|
||||
const homeComputer = Player.getHomeComputer();
|
||||
homeComputer.serversOnNetwork.push(server.ip);
|
||||
server.serversOnNetwork.push(homeComputer.ip);
|
||||
|
||||
return server;
|
||||
}
|
||||
|
||||
export function purchaseHacknet() {
|
||||
/* INTERACTIVE TUTORIAL */
|
||||
if (ITutorial.isRunning) {
|
||||
@ -54,9 +73,9 @@ export function purchaseHacknet() {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* END INTERACTIVE TUTORIAL */
|
||||
|
||||
const numOwned = Player.hacknetNodes.length;
|
||||
if (hasHacknetServers()) {
|
||||
const cost = getCostOfNextHacknetServer();
|
||||
if (isNaN(cost)) {
|
||||
@ -64,24 +83,9 @@ export function purchaseHacknet() {
|
||||
}
|
||||
|
||||
if (!Player.canAfford(cost)) { return -1; }
|
||||
|
||||
// Auto generate a hostname for this Server
|
||||
const numOwned = Player.hacknetNodes.length;
|
||||
const name = `hacknet-node-${numOwned}`;
|
||||
const server = new HacknetServer({
|
||||
adminRights: true,
|
||||
hostname: name,
|
||||
player: Player,
|
||||
});
|
||||
|
||||
Player.loseMoney(cost);
|
||||
Player.hacknetNodes.push(server.ip);
|
||||
|
||||
// Configure the HacknetServer to actually act as a Server
|
||||
AddToAllServers(server);
|
||||
const homeComputer = Player.getHomeComputer();
|
||||
homeComputer.serversOnNetwork.push(server.ip);
|
||||
server.serversOnNetwork.push(homeComputer.ip);
|
||||
const server = createHacknetServer();
|
||||
Player.hashManager.updateCapacity(Player);
|
||||
|
||||
return numOwned;
|
||||
} else {
|
||||
@ -93,7 +97,6 @@ export function purchaseHacknet() {
|
||||
if (!Player.canAfford(cost)) { return -1; }
|
||||
|
||||
// Auto generate a name for the Node
|
||||
const numOwned = Player.hacknetNodes.length;
|
||||
const name = "hacknet-node-" + numOwned;
|
||||
const node = new HacknetNode(name);
|
||||
node.updateMoneyGainRate(Player);
|
||||
@ -396,11 +399,21 @@ export function purchaseHashUpgrade(upgName, upgTarget) {
|
||||
break;
|
||||
}
|
||||
case "Exchange for Bladeburner Rank": {
|
||||
// This will throw if player doesn't have a corporation
|
||||
// This will throw if player isnt in Bladeburner
|
||||
try {
|
||||
for (const division of Player.corporation.divisions) {
|
||||
division.sciResearch.qty += upg.value;
|
||||
Player.bladeburner.changeRank(upg.value);
|
||||
} catch(e) {
|
||||
Player.hashManager.refundUpgrade(upgName);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "Exchange for Bladeburner SP": {
|
||||
// This will throw if player isn't in Bladeburner
|
||||
try {
|
||||
// As long as we don't change `Bladeburner.totalSkillPoints`, this
|
||||
// shouldn't affect anything else
|
||||
Player.bladeburner.skillPoints += upg.value;
|
||||
} catch(e) {
|
||||
Player.hashManager.refundUpgrade(upgName);
|
||||
return false;
|
||||
@ -413,6 +426,7 @@ export function purchaseHashUpgrade(upgName, upgTarget) {
|
||||
}
|
||||
default:
|
||||
console.warn(`Unrecognized upgrade name ${upgName}. Upgrade has no effect`)
|
||||
Player.hashManager.refundUpgrade(upgName);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -327,16 +327,17 @@ export class HacknetServer extends BaseServer implements IHacknetNode {
|
||||
|
||||
updateHashRate(p: IPlayer): void {
|
||||
const baseGain = HacknetServerHashesPerLevel * this.level;
|
||||
const coreMultiplier = Math.pow(1.1, this.cores - 1);
|
||||
const ramMultiplier = Math.pow(1.07, Math.log2(this.maxRam));
|
||||
const coreMultiplier = 1 + (this.cores - 1) / 5;
|
||||
const ramRatio = (1 - this.ramUsed / this.maxRam);
|
||||
|
||||
const hashRate = baseGain * coreMultiplier * ramRatio;
|
||||
const hashRate = baseGain * ramMultiplier * coreMultiplier * ramRatio;
|
||||
|
||||
this.hashRate = hashRate * p.hacknet_node_money_mult * BitNodeMultipliers.HacknetNodeMoney;
|
||||
|
||||
if (isNaN(this.hashRate)) {
|
||||
this.hashRate = 0;
|
||||
dialogBoxCreate(`Error calculating Hacknet Server hash production. This is a bug. Please report to game dev`, false);
|
||||
console.error(`Error calculating Hacknet Server hash production. This is a bug. Please report to game dev`, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -84,9 +84,14 @@ export class HashManager {
|
||||
return upg.getCost(currLevel);
|
||||
}
|
||||
|
||||
storeHashes(numHashes: number): void {
|
||||
this.hashes += numHashes;
|
||||
this.hashes = Math.min(this.hashes, this.capacity);
|
||||
prestige(p: IPlayer): void {
|
||||
for (const name in HashUpgrades) {
|
||||
this.upgrades[name] = 0;
|
||||
}
|
||||
this.hashes = 0;
|
||||
if (p != null) {
|
||||
this.updateCapacity(p);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -106,6 +111,11 @@ export class HashManager {
|
||||
this.hashes += cost;
|
||||
}
|
||||
|
||||
storeHashes(numHashes: number): void {
|
||||
this.hashes += numHashes;
|
||||
this.hashes = Math.min(this.hashes, this.capacity);
|
||||
}
|
||||
|
||||
updateCapacity(p: IPlayer): void {
|
||||
if (p.hacknetNodes.length <= 0) {
|
||||
this.capacity = 0;
|
||||
|
@ -3,7 +3,7 @@ import { IConstructorParams } from "../HashUpgrade";
|
||||
|
||||
export const HashUpgradesMetadata: IConstructorParams[] = [
|
||||
{
|
||||
costPerLevel: 2,
|
||||
costPerLevel: 1,
|
||||
desc: "Sell hashes for $1m",
|
||||
name: "Sell for Money",
|
||||
value: 1e6,
|
||||
@ -15,36 +15,36 @@ export const HashUpgradesMetadata: IConstructorParams[] = [
|
||||
value: 1e9,
|
||||
},
|
||||
{
|
||||
costPerLevel: 100,
|
||||
desc: "Use hashes to decrease the minimum security of a single server by 5%. " +
|
||||
costPerLevel: 50,
|
||||
desc: "Use hashes to decrease the minimum security of a single server by 2%. " +
|
||||
"Note that a server's minimum security cannot go below 1.",
|
||||
hasTargetServer: true,
|
||||
name: "Reduce Minimum Security",
|
||||
value: 0.95,
|
||||
value: 0.98,
|
||||
},
|
||||
{
|
||||
costPerLevel: 100,
|
||||
desc: "Use hashes to increase the maximum amount of money on a single server by 5%",
|
||||
costPerLevel: 50,
|
||||
desc: "Use hashes to increase the maximum amount of money on a single server by 2%",
|
||||
hasTargetServer: true,
|
||||
name: "Increase Maximum Money",
|
||||
value: 1.05,
|
||||
value: 1.02,
|
||||
},
|
||||
{
|
||||
costPerLevel: 100,
|
||||
desc: "Use hashes to improve the experience earned when studying at a university. " +
|
||||
costPerLevel: 50,
|
||||
desc: "Use hashes to improve the experience earned when studying at a university by 20%. " +
|
||||
"This effect persists until you install Augmentations",
|
||||
name: "Improve Studying",
|
||||
value: 20, // Improves studying by value%
|
||||
},
|
||||
{
|
||||
costPerLevel: 100,
|
||||
desc: "Use hashes to improve the experience earned when training at the gym. This effect " +
|
||||
costPerLevel: 50,
|
||||
desc: "Use hashes to improve the experience earned when training at the gym by 20%. This effect " +
|
||||
"persists until you install Augmentations",
|
||||
name: "Improve Gym Training",
|
||||
value: 20, // Improves training by value%
|
||||
},
|
||||
{
|
||||
costPerLevel: 250,
|
||||
costPerLevel: 200,
|
||||
desc: "Exchange hashes for 1k Scientific Research in all of your Corporation's Industries",
|
||||
name: "Exchange for Corporation Research",
|
||||
value: 1000,
|
||||
@ -56,7 +56,13 @@ export const HashUpgradesMetadata: IConstructorParams[] = [
|
||||
value: 100,
|
||||
},
|
||||
{
|
||||
costPerLevel: 200,
|
||||
costPerLevel: 250,
|
||||
desc: "Exchanges hashes for 10 Bladeburner Skill Points",
|
||||
name: "Exchange for Bladeburner SP",
|
||||
value: 10,
|
||||
},
|
||||
{
|
||||
costPerLevel: 150,
|
||||
desc: "Generate a random Coding Contract on your home computer",
|
||||
name: "Generate Coding Contract",
|
||||
value: 1,
|
||||
|
@ -14,6 +14,7 @@ import { Server } from "../../Server/Server";
|
||||
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||
|
||||
import { removePopup } from "../../ui/React/createPopup";
|
||||
import { PopupCloseButton } from "../../ui/React/PopupCloseButton";
|
||||
import { ServerDropdown,
|
||||
ServerType } from "../../ui/React/ServerDropdown"
|
||||
|
||||
@ -85,8 +86,6 @@ export class HashUpgradePopup extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.closePopup = this.closePopup.bind(this);
|
||||
|
||||
this.state = {
|
||||
totalHashes: Player.hashManager.hashes,
|
||||
}
|
||||
@ -100,10 +99,6 @@ export class HashUpgradePopup extends React.Component {
|
||||
clearInterval(this.interval);
|
||||
}
|
||||
|
||||
closePopup() {
|
||||
removePopup(this.props.popupId);
|
||||
}
|
||||
|
||||
tick() {
|
||||
this.setState({
|
||||
totalHashes: Player.hashManager.hashes,
|
||||
@ -125,9 +120,7 @@ export class HashUpgradePopup extends React.Component {
|
||||
|
||||
return (
|
||||
<div>
|
||||
<button className={"std-button"} onClick={this.closePopup}>
|
||||
Close
|
||||
</button>
|
||||
<PopupCloseButton popup={this.props.popupId} text={"Close"} />
|
||||
<p>Spend your hashes on a variety of different upgrades</p>
|
||||
<p>Hashes: {numeralWrapper.formatBigNumber(this.state.totalHashes)}</p>
|
||||
{upgradeElems}
|
||||
|
@ -89,7 +89,6 @@ export class HacknetRoot extends React.Component {
|
||||
const purchaseOnClick = () => {
|
||||
if (purchaseHacknet() >= 0) {
|
||||
this.recalculateTotalProduction();
|
||||
Player.hashManager.updateCapacity(Player);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,10 +29,19 @@ import { Factions,
|
||||
import { joinFaction,
|
||||
purchaseAugmentation } from "./Faction/FactionHelpers";
|
||||
import { FactionWorkType } from "./Faction/FactionWorkTypeEnum";
|
||||
import { netscriptCanGrow,
|
||||
netscriptCanHack,
|
||||
netscriptCanWeaken } from "./Hacking/netscriptCanHack";
|
||||
|
||||
import { getCostOfNextHacknetNode,
|
||||
purchaseHacknet } from "./Hacknet/HacknetNode";
|
||||
getCostOfNextHacknetServer,
|
||||
purchaseHacknet,
|
||||
hasHacknetServers } from "./Hacknet/HacknetHelpers";
|
||||
import { CityName } from "./Locations/data/CityNames";
|
||||
import { LocationName } from "./Locations/data/LocationNames";
|
||||
|
||||
import { HacknetServer } from "./Hacknet/HacknetServer";
|
||||
import {Locations} from "./Locations";
|
||||
import { Message } from "./Message/Message";
|
||||
import { Messages } from "./Message/MessageHelpers";
|
||||
import {inMission} from "./Missions";
|
||||
@ -195,11 +204,11 @@ function initSingularitySFFlags() {
|
||||
}
|
||||
|
||||
function NetscriptFunctions(workerScript) {
|
||||
var updateDynamicRam = function(fnName, ramCost) {
|
||||
const updateDynamicRam = function(fnName, ramCost) {
|
||||
if (workerScript.dynamicLoadedFns[fnName]) {return;}
|
||||
workerScript.dynamicLoadedFns[fnName] = true;
|
||||
|
||||
const threads = workerScript.scriptRef.threads;
|
||||
let threads = workerScript.scriptRef.threads;
|
||||
if (typeof threads !== 'number') {
|
||||
console.warn(`WorkerScript detected NaN for threadcount for ${workerScript.name} on ${workerScript.serverIp}`);
|
||||
threads = 1;
|
||||
@ -216,7 +225,7 @@ function NetscriptFunctions(workerScript) {
|
||||
}
|
||||
};
|
||||
|
||||
var updateStaticRam = function(fnName, ramCost) {
|
||||
const updateStaticRam = function(fnName, ramCost) {
|
||||
if (workerScript.loadedFns[fnName]) {
|
||||
return 0;
|
||||
} else {
|
||||
@ -229,28 +238,56 @@ function NetscriptFunctions(workerScript) {
|
||||
* Gets the Server for a specific hostname/ip, throwing an error
|
||||
* if the server doesn't exist.
|
||||
* @param {string} Hostname or IP of the server
|
||||
* @param {string} callingFnName - Name of calling function. For logging purposes
|
||||
* @returns {Server} The specified Server
|
||||
*/
|
||||
var safeGetServer = function(ip, callingFnName="") {
|
||||
const safeGetServer = function(ip, callingFnName="") {
|
||||
var server = getServer(ip);
|
||||
if (server == null) {
|
||||
workerScript.log(`ERROR: Invalid IP or hostname passed into ${callingFnName}()`);
|
||||
throw makeRuntimeRejectMsg(workerScript, `Invalid IP or hostname passed into ${callingFnName}() function`);
|
||||
}
|
||||
return server;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to fail a function if the function's target is a Hacknet Server.
|
||||
* This is used for functions that should run on normal Servers, but not Hacknet Servers
|
||||
* @param {Server} server - Target server
|
||||
* @param {string} callingFn - Name of calling function. For logging purposes
|
||||
* @returns {boolean} True if the server is a Hacknet Server, false otherwise
|
||||
*/
|
||||
const failOnHacknetServer = function(server, callingFn="") {
|
||||
if (server instanceof HacknetServer) {
|
||||
workerScript.log(`ERROR: ${callingFn}() failed because it does not work on Hacknet Servers`);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Utility function to get Hacknet Node object
|
||||
var getHacknetNode = function(i) {
|
||||
const getHacknetNode = function(i) {
|
||||
if (isNaN(i)) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "Invalid index specified for Hacknet Node: " + i);
|
||||
}
|
||||
if (i < 0 || i >= Player.hacknetNodes.length) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "Index specified for Hacknet Node is out-of-bounds: " + i);
|
||||
}
|
||||
|
||||
if (hasHacknetServers()) {
|
||||
const hserver = AllServers[Player.hacknetNodes[i]];
|
||||
if (hserver == null) {
|
||||
throw makeRuntimeRejectMsg(workerScript, `Could not get Hacknet Server for index ${i}. This is probably a bug, please report to game dev`);
|
||||
}
|
||||
|
||||
return hserver;
|
||||
} else {
|
||||
return Player.hacknetNodes[i];
|
||||
}
|
||||
};
|
||||
|
||||
var getCodingContract = function(fn, ip) {
|
||||
const getCodingContract = function(fn, ip) {
|
||||
var server = safeGetServer(ip, "getCodingContract");
|
||||
return server.getContract(fn);
|
||||
}
|
||||
@ -264,43 +301,68 @@ function NetscriptFunctions(workerScript) {
|
||||
return purchaseHacknet();
|
||||
},
|
||||
getPurchaseNodeCost : function() {
|
||||
if (hasHacknetServers()) {
|
||||
return getCostOfNextHacknetServer();
|
||||
} else {
|
||||
return getCostOfNextHacknetNode();
|
||||
}
|
||||
},
|
||||
getNodeStats : function(i) {
|
||||
var node = getHacknetNode(i);
|
||||
return {
|
||||
const node = getHacknetNode(i);
|
||||
const hasUpgraded = hasHacknetServers();
|
||||
const res = {
|
||||
name: node.name,
|
||||
level: node.level,
|
||||
ram: node.ram,
|
||||
ram: hasUpgraded ? node.maxRam : node.ram,
|
||||
cores: node.cores,
|
||||
production: node.moneyGainRatePerSecond,
|
||||
production: hasUpgraded ? node.hashRate : node.moneyGainRatePerSecond,
|
||||
timeOnline: node.onlineTimeSeconds,
|
||||
totalProduction: node.totalMoneyGenerated,
|
||||
totalProduction: hasUpgraded ? node.totalHashesGenerated : node.totalMoneyGenerated,
|
||||
};
|
||||
|
||||
if (hasUpgraded) {
|
||||
res.cache = node.cache;
|
||||
}
|
||||
|
||||
return res;
|
||||
},
|
||||
upgradeLevel : function(i, n) {
|
||||
var node = getHacknetNode(i);
|
||||
const node = getHacknetNode(i);
|
||||
return node.purchaseLevelUpgrade(n, Player);
|
||||
},
|
||||
upgradeRam : function(i, n) {
|
||||
var node = getHacknetNode(i);
|
||||
const node = getHacknetNode(i);
|
||||
return node.purchaseRamUpgrade(n, Player);
|
||||
},
|
||||
upgradeCore : function(i, n) {
|
||||
var node = getHacknetNode(i);
|
||||
const node = getHacknetNode(i);
|
||||
return node.purchaseCoreUpgrade(n, Player);
|
||||
},
|
||||
upgradeCache : function(i, n) {
|
||||
if (!hasHacknetServers()) { return false; }
|
||||
const node = getHacknetNode(i);
|
||||
const res = node.purchaseCacheUpgrade(n, Player);
|
||||
if (res) {
|
||||
Player.hashManager.updateCapacity(Player);
|
||||
}
|
||||
return res;
|
||||
},
|
||||
getLevelUpgradeCost : function(i, n) {
|
||||
var node = getHacknetNode(i);
|
||||
const node = getHacknetNode(i);
|
||||
return node.calculateLevelUpgradeCost(n, Player);
|
||||
},
|
||||
getRamUpgradeCost : function(i, n) {
|
||||
var node = getHacknetNode(i);
|
||||
const node = getHacknetNode(i);
|
||||
return node.calculateRamUpgradeCost(n, Player);
|
||||
},
|
||||
getCoreUpgradeCost : function(i, n) {
|
||||
var node = getHacknetNode(i);
|
||||
const node = getHacknetNode(i);
|
||||
return node.calculateCoreUpgradeCost(n, Player);
|
||||
},
|
||||
getCacheUpgradeCost : function(i, n) {
|
||||
if (!hasHacknetServers()) { return Infinity; }
|
||||
const node = getHacknetNode(i);
|
||||
return node.calculateCacheUpgradeCost(n);
|
||||
}
|
||||
},
|
||||
sprintf : sprintf,
|
||||
@ -352,19 +414,16 @@ function NetscriptFunctions(workerScript) {
|
||||
var hackingTime = calculateHackingTime(server); //This is in seconds
|
||||
|
||||
//No root access or skill level too low
|
||||
if (server.hasAdminRights == false) {
|
||||
workerScript.scriptRef.log("Cannot hack this server (" + server.hostname + ") because user does not have root access");
|
||||
throw makeRuntimeRejectMsg(workerScript, "Cannot hack this server (" + server.hostname + ") because user does not have root access");
|
||||
}
|
||||
|
||||
if (server.requiredHackingSkill > Player.hacking_skill) {
|
||||
workerScript.scriptRef.log("Cannot hack this server (" + server.hostname + ") because user's hacking skill is not high enough");
|
||||
throw makeRuntimeRejectMsg(workerScript, "Cannot hack this server (" + server.hostname + ") because user's hacking skill is not high enough");
|
||||
const canHack = netscriptCanHack(server, Player);
|
||||
if (!canHack.res) {
|
||||
workerScript.scriptRef.log(`ERROR: ${canHack.msg}`);
|
||||
throw makeRuntimeRejectMsg(workerScript, canHack.msg);
|
||||
}
|
||||
|
||||
if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.hack == null) {
|
||||
workerScript.scriptRef.log("Attempting to hack " + ip + " in " + hackingTime.toFixed(3) + " seconds (t=" + threads + ")");
|
||||
}
|
||||
|
||||
return netscriptDelay(hackingTime * 1000, workerScript).then(function() {
|
||||
if (workerScript.env.stopFlag) {return Promise.reject(workerScript);}
|
||||
var hackChance = calculateHackingChance(server);
|
||||
@ -483,9 +542,10 @@ function NetscriptFunctions(workerScript) {
|
||||
}
|
||||
|
||||
//No root access or skill level too low
|
||||
if (server.hasAdminRights == false) {
|
||||
workerScript.scriptRef.log("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");
|
||||
const canHack = netscriptCanGrow(server);
|
||||
if (!canHack.res) {
|
||||
workerScript.scriptRef.log(`ERROR: ${canHack.msg}`);
|
||||
throw makeRuntimeRejectMsg(workerScript, canHack.msg);
|
||||
}
|
||||
|
||||
var growTime = calculateGrowTime(server);
|
||||
@ -544,9 +604,10 @@ function NetscriptFunctions(workerScript) {
|
||||
}
|
||||
|
||||
//No root access or skill level too low
|
||||
if (server.hasAdminRights == false) {
|
||||
workerScript.scriptRef.log("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");
|
||||
const canHack = netscriptCanWeaken(server);
|
||||
if (!canHack.res) {
|
||||
workerScript.scriptRef.log(`ERROR: ${canHack.msg}`);
|
||||
throw makeRuntimeRejectMsg(workerScript, canHack.msg);
|
||||
}
|
||||
|
||||
var weakenTime = calculateWeakenTime(server);
|
||||
@ -1307,20 +1368,17 @@ function NetscriptFunctions(workerScript) {
|
||||
return updateStaticRam("getServerMoneyAvailable", CONSTANTS.ScriptGetServerRamCost);
|
||||
}
|
||||
updateDynamicRam("getServerMoneyAvailable", CONSTANTS.ScriptGetServerRamCost);
|
||||
var server = getServer(ip);
|
||||
if (server == null) {
|
||||
workerScript.scriptRef.log("getServerMoneyAvailable() failed. Invalid IP or hostname passed in: " + ip);
|
||||
throw makeRuntimeRejectMsg(workerScript, "getServerMoneyAvailable() failed. Invalid IP or hostname passed in: " + ip);
|
||||
}
|
||||
const server = safeGetServer(ip, "getServerMoneyAvailable");
|
||||
if (failOnHacknetServer(server, "getServerMoneyAvailable")) { return 0; }
|
||||
if (server.hostname == "home") {
|
||||
// Return player's money
|
||||
if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.getServerMoneyAvailable == null) {
|
||||
workerScript.scriptRef.log("getServerMoneyAvailable('home') returned player's money: $" + formatNumber(Player.money.toNumber(), 2));
|
||||
if (workerScript.shouldLog("getServerMoneyAvailable")) {
|
||||
workerScript.log("getServerMoneyAvailable('home') returned player's money: $" + formatNumber(Player.money.toNumber(), 2));
|
||||
}
|
||||
return Player.money.toNumber();
|
||||
}
|
||||
if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.getServerMoneyAvailable == null) {
|
||||
workerScript.scriptRef.log("getServerMoneyAvailable() returned " + formatNumber(server.moneyAvailable, 2) + " for " + server.hostname);
|
||||
if (workerScript.shouldLog("getServerMoneyAvailable")) {
|
||||
workerScript.log("getServerMoneyAvailable() returned " + formatNumber(server.moneyAvailable, 2) + " for " + server.hostname);
|
||||
}
|
||||
return server.moneyAvailable;
|
||||
},
|
||||
@ -1329,13 +1387,10 @@ function NetscriptFunctions(workerScript) {
|
||||
return updateStaticRam("getServerSecurityLevel", CONSTANTS.ScriptGetServerRamCost);
|
||||
}
|
||||
updateDynamicRam("getServerSecurityLevel", CONSTANTS.ScriptGetServerRamCost);
|
||||
var server = getServer(ip);
|
||||
if (server == null) {
|
||||
workerScript.scriptRef.log("getServerSecurityLevel() failed. Invalid IP or hostname passed in: " + ip);
|
||||
throw makeRuntimeRejectMsg(workerScript, "getServerSecurityLevel() failed. Invalid IP or hostname passed in: " + ip);
|
||||
}
|
||||
if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.getServerSecurityLevel == null) {
|
||||
workerScript.scriptRef.log("getServerSecurityLevel() returned " + formatNumber(server.hackDifficulty, 3) + " for " + server.hostname);
|
||||
const server = safeGetServer(ip, "getServerSecurityLevel");
|
||||
if (failOnHacknetServer(server, "getServerSecurityLevel")) { return 1; }
|
||||
if (workerScript.shouldLog("getServerSecurityLevel")) {
|
||||
workerScript.log("getServerSecurityLevel() returned " + formatNumber(server.hackDifficulty, 3) + " for " + server.hostname);
|
||||
}
|
||||
return server.hackDifficulty;
|
||||
},
|
||||
@ -1344,13 +1399,10 @@ function NetscriptFunctions(workerScript) {
|
||||
return updateStaticRam("getServerBaseSecurityLevel", CONSTANTS.ScriptGetServerRamCost);
|
||||
}
|
||||
updateDynamicRam("getServerBaseSecurityLevel", CONSTANTS.ScriptGetServerRamCost);
|
||||
var server = getServer(ip);
|
||||
if (server == null) {
|
||||
workerScript.scriptRef.log("getServerBaseSecurityLevel() failed. Invalid IP or hostname passed in: " + ip);
|
||||
throw makeRuntimeRejectMsg(workerScript, "getServerBaseSecurityLevel() failed. Invalid IP or hostname passed in: " + ip);
|
||||
}
|
||||
if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.getServerBaseSecurityLevel == null) {
|
||||
workerScript.scriptRef.log("getServerBaseSecurityLevel() returned " + formatNumber(server.baseDifficulty, 3) + " for " + server.hostname);
|
||||
const server = safeGetServer(ip, "getServerBaseSecurityLevel");
|
||||
if (failOnHacknetServer(server, "getServerBaseSecurityLevel")) { return 1; }
|
||||
if (workerScript.shouldLog("getServerBaseSecurityLevel")) {
|
||||
workerScript.log("getServerBaseSecurityLevel() returned " + formatNumber(server.baseDifficulty, 3) + " for " + server.hostname);
|
||||
}
|
||||
return server.baseDifficulty;
|
||||
},
|
||||
@ -1359,13 +1411,10 @@ function NetscriptFunctions(workerScript) {
|
||||
return updateStaticRam("getServerMinSecurityLevel", CONSTANTS.ScriptGetServerRamCost);
|
||||
}
|
||||
updateDynamicRam("getServerMinSecurityLevel", CONSTANTS.ScriptGetServerRamCost);
|
||||
var server = getServer(ip);
|
||||
if (server == null) {
|
||||
workerScript.scriptRef.log("getServerMinSecurityLevel() failed. Invalid IP or hostname passed in: " + ip);
|
||||
throw makeRuntimeRejectMsg(workerScript, "getServerMinSecurityLevel() failed. Invalid IP or hostname passed in: " + ip);
|
||||
}
|
||||
if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.getServerMinSecurityLevel == null) {
|
||||
workerScript.scriptRef.log("getServerMinSecurityLevel() returned " + formatNumber(server.minDifficulty, 3) + " for " + server.hostname);
|
||||
const server = safeGetServer(ip, "getServerMinSecurityLevel");
|
||||
if (failOnHacknetServer(server, "getServerMinSecurityLevel")) { return 1; }
|
||||
if (workerScript.shouldLog("getServerMinSecurityLevel")) {
|
||||
workerScript.log("getServerMinSecurityLevel() returned " + formatNumber(server.minDifficulty, 3) + " for " + server.hostname);
|
||||
}
|
||||
return server.minDifficulty;
|
||||
},
|
||||
@ -1374,13 +1423,10 @@ function NetscriptFunctions(workerScript) {
|
||||
return updateStaticRam("getServerRequiredHackingLevel", CONSTANTS.ScriptGetServerRamCost);
|
||||
}
|
||||
updateDynamicRam("getServerRequiredHackingLevel", CONSTANTS.ScriptGetServerRamCost);
|
||||
var server = getServer(ip);
|
||||
if (server == null) {
|
||||
workerScript.scriptRef.log("getServerRequiredHackingLevel() failed. Invalid IP or hostname passed in: " + ip);
|
||||
throw makeRuntimeRejectMsg(workerScript, "getServerRequiredHackingLevel() failed. Invalid IP or hostname passed in: " + ip);
|
||||
}
|
||||
if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.getServerRequiredHackingLevel == null) {
|
||||
workerScript.scriptRef.log("getServerRequiredHackingLevel returned " + formatNumber(server.requiredHackingSkill, 0) + " for " + server.hostname);
|
||||
const server = safeGetServer(ip, "getServerRequiredHackingLevel");
|
||||
if (failOnHacknetServer(server, "getServerRequiredHackingLevel")) { return 1; }
|
||||
if (workerScript.shouldLog("getServerRequiredHackingLevel")) {
|
||||
workerScript.log("getServerRequiredHackingLevel returned " + formatNumber(server.requiredHackingSkill, 0) + " for " + server.hostname);
|
||||
}
|
||||
return server.requiredHackingSkill;
|
||||
},
|
||||
@ -1389,13 +1435,10 @@ function NetscriptFunctions(workerScript) {
|
||||
return updateStaticRam("getServerMaxMoney", CONSTANTS.ScriptGetServerRamCost);
|
||||
}
|
||||
updateDynamicRam("getServerMaxMoney", CONSTANTS.ScriptGetServerRamCost);
|
||||
var server = getServer(ip);
|
||||
if (server == null) {
|
||||
workerScript.scriptRef.log("getServerMaxMoney() failed. Invalid IP or hostname passed in: " + ip);
|
||||
throw makeRuntimeRejectMsg(workerScript, "getServerMaxMoney() failed. Invalid IP or hostname passed in: " + ip);
|
||||
}
|
||||
if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.getServerMaxMoney == null) {
|
||||
workerScript.scriptRef.log("getServerMaxMoney() returned " + formatNumber(server.moneyMax, 0) + " for " + server.hostname);
|
||||
const server = safeGetServer(ip, "getServerMaxMoney");
|
||||
if (failOnHacknetServer(server, "getServerMaxMoney")) { return 0; }
|
||||
if (workerScript.shouldLog("getServerMaxMoney")) {
|
||||
workerScript.log("getServerMaxMoney() returned " + formatNumber(server.moneyMax, 0) + " for " + server.hostname);
|
||||
}
|
||||
return server.moneyMax;
|
||||
},
|
||||
@ -1404,13 +1447,10 @@ function NetscriptFunctions(workerScript) {
|
||||
return updateStaticRam("getServerGrowth", CONSTANTS.ScriptGetServerRamCost);
|
||||
}
|
||||
updateDynamicRam("getServerGrowth", CONSTANTS.ScriptGetServerRamCost);
|
||||
var server = getServer(ip);
|
||||
if (server == null) {
|
||||
workerScript.scriptRef.log("getServerGrowth() failed. Invalid IP or hostname passed in: " + ip);
|
||||
throw makeRuntimeRejectMsg(workerScript, "getServerGrowth() failed. Invalid IP or hostname passed in: " + ip);
|
||||
}
|
||||
if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.getServerGrowth == null) {
|
||||
workerScript.scriptRef.log("getServerGrowth() returned " + formatNumber(server.serverGrowth, 0) + " for " + server.hostname);
|
||||
const server = safeGetServer(ip, "getServerGrowth");
|
||||
if (failOnHacknetServer(server, "getServerGrowth")) { return 1; }
|
||||
if (workerScript.shouldLog("getServerGrowth")) {
|
||||
workerScript.log("getServerGrowth() returned " + formatNumber(server.serverGrowth, 0) + " for " + server.hostname);
|
||||
}
|
||||
return server.serverGrowth;
|
||||
},
|
||||
@ -1419,13 +1459,10 @@ function NetscriptFunctions(workerScript) {
|
||||
return updateStaticRam("getServerNumPortsRequired", CONSTANTS.ScriptGetServerRamCost);
|
||||
}
|
||||
updateDynamicRam("getServerNumPortsRequired", CONSTANTS.ScriptGetServerRamCost);
|
||||
var server = getServer(ip);
|
||||
if (server == null) {
|
||||
workerScript.scriptRef.log("getServerNumPortsRequired() failed. Invalid IP or hostname passed in: " + ip);
|
||||
throw makeRuntimeRejectMsg(workerScript, "getServerNumPortsRequired() failed. Invalid IP or hostname passed in: " + ip);
|
||||
}
|
||||
if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.getServerNumPortsRequired == null) {
|
||||
workerScript.scriptRef.log("getServerNumPortsRequired() returned " + formatNumber(server.numOpenPortsRequired, 0) + " for " + server.hostname);
|
||||
const server = safeGetServer(ip, "getServerNumPortsRequired");
|
||||
if (failOnHacknetServer(server, "getServerNumPortsRequired")) { return 5; }
|
||||
if (workerScript.shouldLog("getServerNumPortsRequired")) {
|
||||
workerScript.log("getServerNumPortsRequired() returned " + formatNumber(server.numOpenPortsRequired, 0) + " for " + server.hostname);
|
||||
}
|
||||
return server.numOpenPortsRequired;
|
||||
},
|
||||
@ -1434,13 +1471,9 @@ function NetscriptFunctions(workerScript) {
|
||||
return updateStaticRam("getServerRam", CONSTANTS.ScriptGetServerRamCost);
|
||||
}
|
||||
updateDynamicRam("getServerRam", CONSTANTS.ScriptGetServerRamCost);
|
||||
var server = getServer(ip);
|
||||
if (server == null) {
|
||||
workerScript.scriptRef.log("getServerRam() failed. Invalid IP or hostname passed in: " + ip);
|
||||
throw makeRuntimeRejectMsg(workerScript, "getServerRam() failed. Invalid IP or hostname passed in: " + ip);
|
||||
}
|
||||
if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.getServerRam == null) {
|
||||
workerScript.scriptRef.log("getServerRam() returned [" + formatNumber(server.maxRam, 2) + "GB, " + formatNumber(server.ramUsed, 2) + "GB]");
|
||||
const server = safeGetServer(ip, "getServerRam");
|
||||
if (workerScript.shouldLog("getServerRam")) {
|
||||
workerScript.log("getServerRam() returned [" + formatNumber(server.maxRam, 2) + "GB, " + formatNumber(server.ramUsed, 2) + "GB]");
|
||||
}
|
||||
return [server.maxRam, server.ramUsed];
|
||||
},
|
||||
@ -4711,7 +4744,7 @@ function NetscriptFunctions(workerScript) {
|
||||
answer = String(answer);
|
||||
}
|
||||
|
||||
const serv = safeGetServer(ip, "codingcontract.attempt()");
|
||||
const serv = safeGetServer(ip, "codingcontract.attempt");
|
||||
if (contract.isSolution(answer)) {
|
||||
const reward = Player.gainCodingContractReward(contract.reward, contract.getDifficulty());
|
||||
workerScript.log(`Successfully completed Coding Contract ${fn}. Reward: ${reward}`);
|
||||
|
@ -435,6 +435,12 @@ export class Sleeve extends Person {
|
||||
* Called on every sleeve for a Source File prestige
|
||||
*/
|
||||
prestige(p: IPlayer) {
|
||||
this.hacking_exp = 0;
|
||||
this.strength_exp = 0;
|
||||
this.defense_exp = 0;
|
||||
this.dexterity_exp = 0;
|
||||
this.agility_exp = 0;
|
||||
this.charisma_exp = 0;
|
||||
this.resetTaskStatus();
|
||||
this.earningsForSleeves = createTaskTracker();
|
||||
this.earningsForPlayer = createTaskTracker();
|
||||
|
@ -14,6 +14,7 @@ import { Faction } from "./Faction/Faction";
|
||||
import { Factions,
|
||||
initFactions } from "./Faction/Factions";
|
||||
import { joinFaction } from "./Faction/FactionHelpers";
|
||||
import { createHacknetServer } from "./Hacknet/HacknetHelpers";
|
||||
import {deleteGangDisplayContent} from "./Gang";
|
||||
import { Message } from "./Message/Message";
|
||||
import { initMessages,
|
||||
@ -29,7 +30,8 @@ import { AllServers,
|
||||
prestigeAllServers } from "./Server/AllServers";
|
||||
import { Server } from "./Server/Server"
|
||||
import { prestigeHomeComputer } from "./Server/ServerHelpers";
|
||||
import { updateSourceFileFlags } from "./SourceFile/SourceFileFlags";
|
||||
import { SourceFileFlags,
|
||||
updateSourceFileFlags } from "./SourceFile/SourceFileFlags";
|
||||
import { SpecialServerIps,
|
||||
SpecialServerIpsMap,
|
||||
prestigeSpecialServerIps,
|
||||
@ -200,13 +202,9 @@ function prestigeSourceFile() {
|
||||
//Re-create foreign servers
|
||||
initForeignServers(Player.getHomeComputer());
|
||||
|
||||
var srcFile1Owned = false;
|
||||
for (var i = 0; i < Player.sourceFiles.length; ++i) {
|
||||
if (Player.sourceFiles[i].n == 1) {
|
||||
srcFile1Owned = true;
|
||||
}
|
||||
}
|
||||
if (srcFile1Owned) {
|
||||
if (SourceFileFlags[9] >= 2) {
|
||||
homeComp.setMaxRam(128);
|
||||
} else if (SourceFileFlags[1] > 0) {
|
||||
homeComp.setMaxRam(32);
|
||||
} else {
|
||||
homeComp.setMaxRam(8);
|
||||
@ -340,6 +338,16 @@ function prestigeSourceFile() {
|
||||
Player.corporation = null; resetIndustryResearchTrees();
|
||||
Player.bladeburner = null;
|
||||
|
||||
// Source-File 9 (level 3) effect
|
||||
if (SourceFileFlags[9] >= 3) {
|
||||
const hserver = createHacknetServer();
|
||||
hserver.level = 100;
|
||||
hserver.cores = 10;
|
||||
hserver.cache = 5;
|
||||
hserver.updateHashRate(Player);
|
||||
hserver.updateHashCapacity();
|
||||
Player.hashManager.updateCapacity(Player);
|
||||
}
|
||||
|
||||
// Refresh Main Menu (the 'World' menu, specifically)
|
||||
document.getElementById("world-menu-header").click();
|
||||
|
@ -101,8 +101,8 @@ let NetscriptFunctions =
|
||||
|
||||
// Hacknet Node API
|
||||
"hacknet|numNodes|purchaseNode|getPurchaseNodeCost|getNodeStats|" +
|
||||
"upgradeLevel|upgradeRam|upgradeCore|getLevelUpgradeCost|" +
|
||||
"getRamUpgradeCost|getCoreUpgradeCost|" +
|
||||
"upgradeLevel|upgradeRam|upgradeCore|upgradeCache|getLevelUpgradeCost|" +
|
||||
"getRamUpgradeCost|getCoreUpgradeCost|getCacheUpgradeCost|" +
|
||||
|
||||
// Gang API
|
||||
"gang|" +
|
||||
|
@ -177,9 +177,11 @@ CodeMirror.defineMode("netscript", function(config, parserConfig) {
|
||||
"upgradeLevel": atom,
|
||||
"upgradeRam": atom,
|
||||
"upgradeCore": atom,
|
||||
"upgradeCache": atom,
|
||||
"getLevelUpgradeCost": atom,
|
||||
"getRamUpgradeCost": atom,
|
||||
"getCoreUpgradeCost": atom,
|
||||
"getCacheUpgradeCost": atom,
|
||||
|
||||
// Netscript Gang API
|
||||
"gang": atom,
|
||||
|
@ -62,7 +62,12 @@ function initSourceFiles() {
|
||||
"Level 3: Ability to use limit/stop orders in other BitNodes<br><br>" +
|
||||
"This Source-File also increases your hacking growth multipliers by: " +
|
||||
"<br>Level 1: 12%<br>Level 2: 18%<br>Level 3: 21%");
|
||||
SourceFiles["SourceFile9"] = new SourceFile(9);
|
||||
SourceFiles["SourceFile9"] = new SourceFile(9, "This Source-File grants the following benefits:<br><br>" +
|
||||
"Level 1: Permanently unlocks the Hacknet Server in other BitNodes<br>" +
|
||||
"Level 2: You start with 128GB of RAM on your home computer when entering a new BitNode<br>" +
|
||||
"Level 3: Grants a highly-upgraded Hacknet Server when entering a new BitNode<br><br>" +
|
||||
"(Note that the Level 3 effect of this Source-File only applies when entering a new BitNode, NOT " +
|
||||
"when installing Augmentations)");
|
||||
SourceFiles["SourceFile10"] = new SourceFile(10, "This Source-File unlocks Sleeve technology in other BitNodes. Each level of this " +
|
||||
"Source-File also grants you a Duplicate Sleeve");
|
||||
SourceFiles["SourceFile11"] = new SourceFile(11, "This Source-File makes it so that company favor increases BOTH the player's salary and reputation gain rate " +
|
||||
@ -188,6 +193,9 @@ function applySourceFile(srcFile) {
|
||||
var incMult = 1 + (mult / 100);
|
||||
Player.hacking_grow_mult *= incMult;
|
||||
break;
|
||||
case 9: // Hacktocracy
|
||||
// This has non-multiplier effects
|
||||
break;
|
||||
case 10: // Digital Carbon
|
||||
// No effects, just grants sleeves
|
||||
break;
|
||||
|
@ -2,6 +2,7 @@ import {substituteAliases, printAliases,
|
||||
parseAliasDeclaration,
|
||||
removeAlias, GlobalAliases,
|
||||
Aliases} from "./Alias";
|
||||
import { BitNodeMultipliers } from "./BitNode/BitNodeMultipliers";
|
||||
import {CodingContract, CodingContractResult,
|
||||
CodingContractRewardType} from "./CodingContracts";
|
||||
import {CONSTANTS} from "./Constants";
|
||||
@ -1246,23 +1247,26 @@ let Terminal = {
|
||||
case "free":
|
||||
Terminal.executeFreeCommand(commandArray);
|
||||
break;
|
||||
case "hack":
|
||||
case "hack": {
|
||||
if (commandArray.length !== 1) {
|
||||
postError("Incorrect usage of hack command. Usage: hack");
|
||||
return;
|
||||
}
|
||||
//Hack the current PC (usually for money)
|
||||
//You can't hack your home pc or servers you purchased
|
||||
if (Player.getCurrentServer().purchasedByPlayer) {
|
||||
if (s.purchasedByPlayer) {
|
||||
postError("Cannot hack your own machines! You are currently connected to your home PC or one of your purchased servers");
|
||||
} else if (Player.getCurrentServer().hasAdminRights == false ) {
|
||||
} else if (s.hasAdminRights == false ) {
|
||||
postError("You do not have admin rights for this machine! Cannot hack");
|
||||
} else if (Player.getCurrentServer().requiredHackingSkill > Player.hacking_skill) {
|
||||
} else if (s.requiredHackingSkill > Player.hacking_skill) {
|
||||
postError("Your hacking skill is not high enough to attempt hacking this machine. Try analyzing the machine to determine the required hacking skill");
|
||||
} else if (s instanceof HacknetServer) {
|
||||
postError("Cannot hack this type of Server")
|
||||
} else {
|
||||
Terminal.startHack();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "help":
|
||||
if (commandArray.length !== 1 && commandArray.length !== 2) {
|
||||
postError("Incorrect usage of help command. Usage: help");
|
||||
@ -1640,9 +1644,15 @@ let Terminal = {
|
||||
postError("Incorrect usage of free command. Usage: free");
|
||||
return;
|
||||
}
|
||||
post("Total: " + numeralWrapper.format(Player.getCurrentServer().maxRam, '0.00') + " GB");
|
||||
post("Used: " + numeralWrapper.format(Player.getCurrentServer().ramUsed, '0.00') + " GB");
|
||||
post("Available: " + numeralWrapper.format(Player.getCurrentServer().maxRam - Player.getCurrentServer().ramUsed, '0.00') + " GB");
|
||||
const ram = numeralWrapper.format(Player.getCurrentServer().maxRam, '0.00');
|
||||
const used = numeralWrapper.format(Player.getCurrentServer().ramUsed, '0.00');
|
||||
const avail = numeralWrapper.format(Player.getCurrentServer().maxRam - Player.getCurrentServer().ramUsed, '0.00');
|
||||
const maxLength = Math.max(ram.length, Math.max(used.length, avail.length));
|
||||
const usedPercent = numeralWrapper.format(Player.getCurrentServer().ramUsed/Player.getCurrentServer().maxRam*100, '0.00');
|
||||
|
||||
post(`Total: ${" ".repeat(maxLength-ram.length)}${ram} GB`);
|
||||
post(`Used: ${" ".repeat(maxLength-used.length)}${used} GB (${usedPercent}%)`);
|
||||
post(`Available: ${" ".repeat(maxLength-avail.length)}${avail} GB`);
|
||||
},
|
||||
|
||||
executeKillCommand: function(commandArray) {
|
||||
@ -2138,7 +2148,8 @@ let Terminal = {
|
||||
post("DeepscanV2.exe lets you run 'scan-analyze' with a depth up to 10.");
|
||||
};
|
||||
programHandlers[Programs.Flight.name] = () => {
|
||||
const fulfilled = Player.augmentations.length >= 30 &&
|
||||
const numAugReq = Math.round(BitNodeMultipliers.DaedalusAugsRequirement*30)
|
||||
const fulfilled = Player.augmentations.length >= numAugReq &&
|
||||
Player.money.gt(1e11) &&
|
||||
((Player.hacking_skill >= 2500)||
|
||||
(Player.strength >= 1500 &&
|
||||
@ -2146,17 +2157,17 @@ let Terminal = {
|
||||
Player.dexterity >= 1500 &&
|
||||
Player.agility >= 1500));
|
||||
if(!fulfilled) {
|
||||
post("Augmentations: " + Player.augmentations.length + " / 30");
|
||||
post(`Augmentations: ${Player.augmentations.length} / ${numAugReq}`);
|
||||
|
||||
post("Money: " + numeralWrapper.format(Player.money.toNumber(), '($0.000a)') + " / " + numeralWrapper.format(1e11, '($0.000a)'));
|
||||
post(`Money: ${numeralWrapper.format(Player.money.toNumber(), '($0.000a)')} / ${numeralWrapper.format(1e11, '($0.000a)')}`);
|
||||
post("One path below must be fulfilled...");
|
||||
post("----------HACKING PATH----------");
|
||||
post("Hacking skill: " + Player.hacking_skill + " / 2500");
|
||||
post(`Hacking skill: ${Player.hacking_skill} / 2500`);
|
||||
post("----------COMBAT PATH----------");
|
||||
post("Strength: " + Player.strength + " / 1500");
|
||||
post("Defense: " + Player.defense + " / 1500");
|
||||
post("Dexterity: " + Player.dexterity + " / 1500");
|
||||
post("Agility: " + Player.agility + " / 1500");
|
||||
post(`Strength: ${Player.strength} / 1500`);
|
||||
post(`Defense: ${Player.defense} / 1500`);
|
||||
post(`Dexterity: ${Player.dexterity} / 1500`);
|
||||
post(`Agility: ${Player.agility} / 1500`);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -35,3 +35,12 @@ export interface ISelfLoading {
|
||||
*/
|
||||
load(saveState: string): void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Status object for functions that return a boolean indicating success/failure
|
||||
* and an optional message
|
||||
*/
|
||||
export interface IReturnStatus {
|
||||
res: boolean;
|
||||
msg?: string;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user