mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-12-19 12:45:45 +01:00
Merge branch 'dev' of github.com:danielyxie/bitburner into dev
This commit is contained in:
commit
ee759a8dd6
15
doc/source/netscript/basicfunctions/getServerMaxRam.rst
Normal file
15
doc/source/netscript/basicfunctions/getServerMaxRam.rst
Normal file
@ -0,0 +1,15 @@
|
||||
getServerMaxRam() Netscript Function
|
||||
====================================
|
||||
|
||||
.. js:function:: getServerMaxRam(hostname)
|
||||
|
||||
:RAM cost: 0.05 GB
|
||||
:param string hostname: Hostname of target server.
|
||||
:returns: Total ram available on that server. In GB.
|
||||
|
||||
Example:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
maxRam = getServerMaxRam("helios"); // returns: 16
|
||||
print("helios has "+maxRam + "GB");
|
@ -3,6 +3,8 @@ getServerRam() Netscript Function
|
||||
|
||||
.. js:function:: getServerRam(hostname)
|
||||
|
||||
.. warning:: This function is deprecated.
|
||||
|
||||
:RAM cost: 0.1 GB
|
||||
:param string hostname: Hostname of target server.
|
||||
:returns: An array of 2 number, first number is the total RAM, second the
|
||||
|
15
doc/source/netscript/basicfunctions/getServerUsedRam.rst
Normal file
15
doc/source/netscript/basicfunctions/getServerUsedRam.rst
Normal file
@ -0,0 +1,15 @@
|
||||
getServerUsedRam() Netscript Function
|
||||
=====================================
|
||||
|
||||
.. js:function:: getServerUsedRam(hostname)
|
||||
|
||||
:RAM cost: 0.05 GB
|
||||
:param string hostname: Hostname of target server.
|
||||
:returns: Used ram on that server. In GB.
|
||||
|
||||
Example:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
usedRam = getServerUsedRam("harakiri-sushi"); // returns: 5.6
|
||||
print("harakiri-sushi uses "+usedRam + "GB");
|
@ -54,7 +54,8 @@ This includes information such as function signatures, what they do, and their r
|
||||
getServerMinSecurityLevel() <basicfunctions/getServerMinSecurityLevel>
|
||||
getServerRequiredHackingLevel() <basicfunctions/getServerRequiredHackingLevel>
|
||||
getServerNumPortsRequired() <basicfunctions/getServerNumPortsRequired>
|
||||
getServerRam() <basicfunctions/getServerRam>
|
||||
getServerMaxRam() <basicfunctions/getServerMaxRam>
|
||||
getServerUsedRam() <basicfunctions/getServerUsedRam>
|
||||
serverExists() <basicfunctions/serverExists>
|
||||
fileExists() <basicfunctions/fileExists>
|
||||
isRunning() <basicfunctions/isRunning>
|
||||
@ -90,3 +91,8 @@ This includes information such as function signatures, what they do, and their r
|
||||
wget() <basicfunctions/wget>
|
||||
getFavorToDonate() <basicfunctions/getFavorToDonate>
|
||||
flags() <basicfunctions/flags>
|
||||
|
||||
.. toctree::
|
||||
:caption: Deprecated:
|
||||
|
||||
getServerRam() <basicfunctions/getServerRam>
|
@ -86,7 +86,7 @@ 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 80, 16 GB RAM, and 8 cores
|
||||
|
||||
.. code:: javascript
|
||||
|
||||
@ -129,3 +129,16 @@ it gradually upgrades those Node's to a minimum of level 140, 64 GB RAM, and 8 c
|
||||
};
|
||||
|
||||
print("All nodes upgraded to 16GB RAM");
|
||||
|
||||
for (var i = 0; i < cnt; i++) {
|
||||
while (hacknet.getNodeStats(i).cores < 8) {
|
||||
var cost = hacknet.getCoreUpgradeCost(i, 1);
|
||||
while (myMoney() < cost) {
|
||||
print("Need $" + cost + " . Have $" + myMoney());
|
||||
sleep(3000);
|
||||
}
|
||||
res = hacknet.upgradeCore(i, 1);
|
||||
};
|
||||
};
|
||||
|
||||
print("All nodes upgraded to 8 cores");
|
||||
|
@ -327,8 +327,8 @@
|
||||
Would you like to join? <br/> <br/>
|
||||
Warning: Joining this faction may prevent you from joining other factions during this run!
|
||||
</p>
|
||||
<button id="faction-invitation-box-yes" class="popup-box-button"> Yes </button>
|
||||
<button id="faction-invitation-box-no" class="popup-box-button"> No </button>
|
||||
<button id="faction-invitation-box-yes" class="popup-box-button"> Join! </button>
|
||||
<button id="faction-invitation-box-no" class="popup-box-button"> Decide later. </button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -9,7 +9,7 @@ import { Factions } from "../Faction/Factions";
|
||||
import { Generic_fromJSON, Generic_toJSON, Reviver } from "../../utils/JSONReviver";
|
||||
|
||||
interface IConstructorParams {
|
||||
info: string;
|
||||
info: string | JSX.Element;
|
||||
isSpecial?: boolean;
|
||||
moneyCost: number;
|
||||
name: string;
|
||||
@ -57,7 +57,7 @@ export class Augmentation {
|
||||
baseRepRequirement = 0;
|
||||
|
||||
// Description of what this Aug is and what it does
|
||||
info = "";
|
||||
info: string | JSX.Element;
|
||||
|
||||
// Any Augmentation not immediately available in BitNode-1 is special (e.g. Bladeburner augs)
|
||||
isSpecial = false;
|
||||
|
@ -60,7 +60,7 @@ function initAugmentations() {
|
||||
"This augmentation increases the player's dexterity by 10%.",
|
||||
dexterity_mult: 1.1,
|
||||
});
|
||||
Targeting1.addToFactions(["Slum Snakes", "The Dark Army", "The Syndicate", "Sector-12", "Volhaven", "Ishima",
|
||||
Targeting1.addToFactions(["Slum Snakes", "The Dark Army", "The Syndicate", "Sector-12", "Ishima",
|
||||
"OmniTek Incorporated", "KuaiGong International", "Blade Industries"]);
|
||||
if (augmentationExists(AugmentationNames.Targeting1)) {
|
||||
delete Augmentations[AugmentationNames.Targeting1];
|
||||
@ -75,7 +75,7 @@ function initAugmentations() {
|
||||
prereqs:[AugmentationNames.Targeting1],
|
||||
dexterity_mult: 1.2,
|
||||
});
|
||||
Targeting2.addToFactions(["The Dark Army", "The Syndicate", "Sector-12", "Volhaven", "Ishima",
|
||||
Targeting2.addToFactions(["The Dark Army", "The Syndicate", "Sector-12",
|
||||
"OmniTek Incorporated", "KuaiGong International", "Blade Industries"]);
|
||||
if (augmentationExists(AugmentationNames.Targeting2)) {
|
||||
delete Augmentations[AugmentationNames.Targeting2];
|
||||
@ -136,7 +136,7 @@ function initAugmentations() {
|
||||
strength_mult: 1.1,
|
||||
defense_mult: 1.1,
|
||||
});
|
||||
CombatRib1.addToFactions(["Slum Snakes", "The Dark Army", "The Syndicate", "Sector-12", "Volhaven", "Ishima",
|
||||
CombatRib1.addToFactions(["Slum Snakes", "The Dark Army", "The Syndicate", "Volhaven", "Ishima",
|
||||
"OmniTek Incorporated", "KuaiGong International", "Blade Industries"]);
|
||||
if (augmentationExists(AugmentationNames.CombatRib1)) {
|
||||
delete Augmentations[AugmentationNames.CombatRib1];
|
||||
@ -152,7 +152,7 @@ function initAugmentations() {
|
||||
strength_mult: 1.14,
|
||||
defense_mult: 1.14,
|
||||
});
|
||||
CombatRib2.addToFactions(["The Dark Army", "The Syndicate", "Sector-12", "Volhaven", "Ishima",
|
||||
CombatRib2.addToFactions(["The Dark Army", "The Syndicate", "Volhaven",
|
||||
"OmniTek Incorporated", "KuaiGong International", "Blade Industries"]);
|
||||
if (augmentationExists(AugmentationNames.CombatRib2)) {
|
||||
delete Augmentations[AugmentationNames.CombatRib2];
|
||||
@ -428,7 +428,7 @@ function initAugmentations() {
|
||||
"This augmentation increases the player's hacking speed by 3%.",
|
||||
hacking_speed_mult: 1.03,
|
||||
});
|
||||
SynapticEnhancement.addToFactions(["CyberSec"]);
|
||||
SynapticEnhancement.addToFactions(["CyberSec", "Aevum"]);
|
||||
if (augmentationExists(AugmentationNames.SynapticEnhancement)) {
|
||||
delete Augmentations[AugmentationNames.SynapticEnhancement];
|
||||
}
|
||||
@ -756,7 +756,7 @@ function initAugmentations() {
|
||||
"when working for a company by 20%.",
|
||||
company_rep_mult: 1.2,
|
||||
});
|
||||
NuoptimalInjectorImplant.addToFactions(["Tian Di Hui", "Volhaven", "New Tokyo", "Chongqing", "Ishima",
|
||||
NuoptimalInjectorImplant.addToFactions(["Tian Di Hui", "Volhaven", "New Tokyo", "Chongqing",
|
||||
"Clarke Incorporated", "Four Sigma", "Bachman & Associates"]);
|
||||
if (augmentationExists(AugmentationNames.NuoptimalInjectorImplant)) {
|
||||
delete Augmentations[AugmentationNames.NuoptimalInjectorImplant];
|
||||
@ -1064,7 +1064,7 @@ function initAugmentations() {
|
||||
agility_exp_mult: 1.1,
|
||||
charisma_exp_mult: 1.1,
|
||||
});
|
||||
Neurotrainer1.addToFactions(["CyberSec"]);
|
||||
Neurotrainer1.addToFactions(["CyberSec", "Aevum"]);
|
||||
if (augmentationExists(AugmentationNames.Neurotrainer1)) {
|
||||
delete Augmentations[AugmentationNames.Neurotrainer1];
|
||||
}
|
||||
|
@ -236,8 +236,7 @@ BitNodes["BitNode12"] = new BitNode(12, "The Recursion", "Repeat.",
|
||||
"To iterate is human, to recurse divine.<br><br>" +
|
||||
"Every time this BitNode is destroyed, it becomes slightly harder. Destroying this BitNode will give you Source-File 12, or " +
|
||||
"if you already have this Source-File it will upgrade its level. There is no maximum level for Source-File 12. Each level " +
|
||||
"of Source-File 12 will increase all of your multipliers by 1%. This effect is multiplicative with itself. " +
|
||||
"In other words, level N of this Source-File will result in a multiplier of 1.01^N (or 0.99^N for multipliers that decrease)");
|
||||
"of Source-File 12 lets you start any BitNodes with NeuroFlux Governor equal to the level of this source file.");
|
||||
// Books: Frontera, Shiner
|
||||
BitNodes["BitNode13"] = new BitNode(13, "fOS", "COMING SOON"); //Unlocks the new game mode and the rest of the BitNodes
|
||||
BitNodes["BitNode14"] = new BitNode(14, "", "COMING SOON");
|
||||
|
@ -160,7 +160,7 @@ export const BlackOperations: IMap<BlackOperation> = {};
|
||||
"technology in Operation K, we've discovered that a small group of " +
|
||||
"MK-VI Synthoids were able to make off with the schematics and design " +
|
||||
"of the technology before the Operation. It is almost a certainty that " +
|
||||
"these Synthoids are some of the rogue MK-VI ones from the Synthoid Uprising." +
|
||||
"these Synthoids are some of the rogue MK-VI ones from the Synthoid Uprising.<br><br>" +
|
||||
"The goal of Operation Deckard is to hunt down these Synthoids and retire " +
|
||||
"them. I don't need to tell you how critical this mission is.",
|
||||
baseDifficulty:20e3, reqdRank:40e3,
|
||||
@ -231,7 +231,7 @@ export const BlackOperations: IMap<BlackOperation> = {};
|
||||
"means that the supercomputer may be able to reason abstractly " +
|
||||
"and become self-aware.<br><br>" +
|
||||
"I do not need to remind you why sentient-level AIs pose a serious " +
|
||||
"thread to all of mankind.<br><br>" +
|
||||
"threat to all of mankind.<br><br>" +
|
||||
"The research for this project is being conducted at one of Fulcrum " +
|
||||
"Technologies secret facilities in Aevum, codenamed 'Alpha Ranch'. " +
|
||||
"Infiltrate the compound, delete and destroy the work, and then find and kill the " +
|
||||
@ -342,4 +342,4 @@ export const BlackOperations: IMap<BlackOperation> = {};
|
||||
weights:{hack:0.1,str:0.2,def:0.2,dex:0.2,agi:0.2,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.75},
|
||||
});
|
||||
})()
|
||||
})()
|
||||
|
@ -135,6 +135,10 @@ class DevMenuComponent extends Component {
|
||||
Player.getHomeComputer().maxRam *= 2;
|
||||
}
|
||||
|
||||
quickB1tFlum3() {
|
||||
hackWorldDaemon(Player.bitNodeN, true, true);
|
||||
}
|
||||
|
||||
b1tflum3() {
|
||||
hackWorldDaemon(Player.bitNodeN, true);
|
||||
}
|
||||
@ -705,7 +709,8 @@ class DevMenuComponent extends Component {
|
||||
<button className="std-button" onClick={this.upgradeRam}>Upgrade Home Computer's RAM</button>
|
||||
</div>
|
||||
<div className="row">
|
||||
<button className="std-button" onClick={this.b1tflum3}>Run bit_flum3.exe</button>
|
||||
<button className="std-button" onClick={this.quickB1tFlum3}>Quick b1t_flum3.exe</button>
|
||||
<button className="std-button" onClick={this.b1tflum3}>Run b1t_flum3.exe</button>
|
||||
<button className="std-button" onClick={this.hackW0r1dD43m0n}>Hack w0rld_d34m0n</button>
|
||||
</div>
|
||||
<div className="row">
|
||||
|
@ -4,8 +4,8 @@ export function applyExploit(): void {
|
||||
if (Player.exploits && Player.exploits.length === 0) {
|
||||
return;
|
||||
}
|
||||
const inc = Math.pow(1.0001, Player.exploits.length);
|
||||
const dec = Math.pow(0.9999, Player.exploits.length);
|
||||
const inc = Math.pow(1.001, Player.exploits.length);
|
||||
const dec = Math.pow(0.999, Player.exploits.length);
|
||||
|
||||
Player.hacking_chance_mult *= inc;
|
||||
Player.hacking_speed_mult *= inc;
|
||||
|
@ -16,6 +16,8 @@ import { dialogBoxCreate } from "../../../utils/DialogBox";
|
||||
|
||||
type IProps = {
|
||||
faction: Faction;
|
||||
disabled: boolean;
|
||||
favorToDonate: number;
|
||||
p: IPlayer;
|
||||
rerender: () => void;
|
||||
}
|
||||
@ -36,9 +38,10 @@ export class DonateOption extends React.Component<IProps, IState> {
|
||||
constructor(props: IProps) {
|
||||
super(props);
|
||||
|
||||
|
||||
this.state = {
|
||||
donateAmt: 0,
|
||||
status: <></>,
|
||||
status: props.disabled ? <>Unlocked at {props.favorToDonate} favor with {props.faction.name}</> : <></>,
|
||||
}
|
||||
|
||||
this.calculateRepGain = this.calculateRepGain.bind(this);
|
||||
@ -90,10 +93,17 @@ export class DonateOption extends React.Component<IProps, IState> {
|
||||
return (
|
||||
<div className={"faction-work-div"}>
|
||||
<div className={"faction-work-div-wrapper"}>
|
||||
<input className="text-input" onChange={this.handleChange} placeholder={"Donation amount"} style={inputStyleMarkup} />
|
||||
<input
|
||||
className="text-input"
|
||||
onChange={this.handleChange}
|
||||
placeholder={"Donation amount"}
|
||||
style={inputStyleMarkup}
|
||||
disabled={this.props.disabled}
|
||||
/>
|
||||
<StdButton
|
||||
onClick={this.donate}
|
||||
text={"Donate Money"}
|
||||
disabled={this.props.disabled}
|
||||
/>
|
||||
<p style={this.blockStyle}>{this.state.status}</p>
|
||||
</div>
|
||||
|
@ -264,11 +264,13 @@ export class FactionRoot extends React.Component<IProps, IState> {
|
||||
/>
|
||||
}
|
||||
{
|
||||
(!isPlayersGang && canDonate) &&
|
||||
!isPlayersGang &&
|
||||
<DonateOption
|
||||
faction={this.props.faction}
|
||||
p={this.props.p}
|
||||
rerender={this.rerender}
|
||||
favorToDonate={favorToDonate}
|
||||
disabled={!canDonate}
|
||||
/>
|
||||
}
|
||||
<Option
|
||||
|
@ -23,6 +23,8 @@ export const RamCostConstants: IMap<number> = {
|
||||
ScriptGetHackingLevelRamCost: 0.05,
|
||||
ScriptGetMultipliersRamCost: 4.0,
|
||||
ScriptGetServerRamCost: 0.1,
|
||||
ScriptGetServerMaxRam: 0.05,
|
||||
ScriptGetServerUsedRam: 0.05,
|
||||
ScriptFileExistsRamCost: 0.1,
|
||||
ScriptIsRunningRamCost: 0.1,
|
||||
ScriptHacknetNodesRamCost: 4.0,
|
||||
@ -122,6 +124,8 @@ export const RamCosts: IMap<any> = {
|
||||
getServerGrowth: () => RamCostConstants.ScriptGetServerRamCost,
|
||||
getServerNumPortsRequired: () => RamCostConstants.ScriptGetServerRamCost,
|
||||
getServerRam: () => RamCostConstants.ScriptGetServerRamCost,
|
||||
getServerMaxRam: () => RamCostConstants.ScriptGetServerMaxRam,
|
||||
getServerUsedRam: () => RamCostConstants.ScriptGetServerUsedRam,
|
||||
serverExists: () => RamCostConstants.ScriptGetServerRamCost,
|
||||
fileExists: () => RamCostConstants.ScriptFileExistsRamCost,
|
||||
isRunning: () => RamCostConstants.ScriptIsRunningRamCost,
|
||||
|
@ -670,7 +670,7 @@ function NetscriptFunctions(workerScript) {
|
||||
throw makeRuntimeErrorMsg('hack', canHack.msg);
|
||||
}
|
||||
|
||||
workerScript.log("hack", `Executing ${ip} in ${hackingTime.toFixed(3)} seconds (t=${threads})`);
|
||||
workerScript.log("hack", `Executing ${ip} in ${convertTimeMsToTimeElapsedString(hackingTime*1000, true)} (t=${numeralWrapper.formatThreads(threads)})`);
|
||||
|
||||
return netscriptDelay(hackingTime * 1000, workerScript).then(function() {
|
||||
if (workerScript.env.stopFlag) {return Promise.reject(workerScript);}
|
||||
@ -706,7 +706,7 @@ function NetscriptFunctions(workerScript) {
|
||||
workerScript.scriptRef.recordHack(server.ip, moneyGained, threads);
|
||||
Player.gainHackingExp(expGainedOnSuccess);
|
||||
workerScript.scriptRef.onlineExpGained += expGainedOnSuccess;
|
||||
workerScript.log("hack", `Successfully hacked '${server.hostname}' for ${numeralWrapper.formatMoney(moneyGained)} and ${numeralWrapper.formatExp(expGainedOnSuccess)} exp (t=${threads})`);
|
||||
workerScript.log("hack", `Successfully hacked '${server.hostname}' for ${numeralWrapper.formatMoney(moneyGained)} and ${numeralWrapper.formatExp(expGainedOnSuccess)} exp (t=${numeralWrapper.formatThreads(threads)})`);
|
||||
server.fortify(CONSTANTS.ServerFortifyAmount * Math.min(threads, maxThreadNeeded));
|
||||
if (stock) {
|
||||
influenceStockThroughServerHack(server, moneyGained);
|
||||
@ -719,7 +719,7 @@ function NetscriptFunctions(workerScript) {
|
||||
// Player only gains 25% exp for failure?
|
||||
Player.gainHackingExp(expGainedOnFailure);
|
||||
workerScript.scriptRef.onlineExpGained += expGainedOnFailure;
|
||||
workerScript.log("hack", `Failed to hack '${server.hostname}'. Gained ${numeralWrapper.formatExp(expGainedOnFailure)} exp (t=${threads})`);
|
||||
workerScript.log("hack", `Failed to hack '${server.hostname}'. Gained ${numeralWrapper.formatExp(expGainedOnFailure)} exp (t=${numeralWrapper.formatThreads(threads)})`);
|
||||
return Promise.resolve(0);
|
||||
}
|
||||
});
|
||||
@ -937,7 +937,7 @@ function NetscriptFunctions(workerScript) {
|
||||
}
|
||||
|
||||
var growTime = calculateGrowTime(server, Player);
|
||||
workerScript.log("grow", `Executing on '${server.hostname}' in ${formatNumber(growTime, 3)} seconds (t=${threads}).`);
|
||||
workerScript.log("grow", `Executing on '${server.hostname}' in ${convertTimeMsToTimeElapsedString(growTime*1000, true)} (t=${numeralWrapper.formatThreads(threads)}).`);
|
||||
return netscriptDelay(growTime * 1000, workerScript).then(function() {
|
||||
if (workerScript.env.stopFlag) {return Promise.reject(workerScript);}
|
||||
const moneyBefore = server.moneyAvailable <= 0 ? 1 : server.moneyAvailable;
|
||||
@ -950,7 +950,7 @@ function NetscriptFunctions(workerScript) {
|
||||
expGain = 0;
|
||||
}
|
||||
const logGrowPercent = (moneyAfter/moneyBefore)*100 - 100;
|
||||
workerScript.log("grow", `Available money on '${server.hostname}' grown by ${formatNumber(logGrowPercent, 6)}%. Gained ${numeralWrapper.formatExp(expGain)} hacking exp (t=${threads}).`);
|
||||
workerScript.log("grow", `Available money on '${server.hostname}' grown by ${formatNumber(logGrowPercent, 6)}%. Gained ${numeralWrapper.formatExp(expGain)} hacking exp (t=${numeralWrapper.formatThreads(threads)}).`);
|
||||
workerScript.scriptRef.onlineExpGained += expGain;
|
||||
Player.gainHackingExp(expGain);
|
||||
if (stock) {
|
||||
@ -988,13 +988,13 @@ function NetscriptFunctions(workerScript) {
|
||||
}
|
||||
|
||||
var weakenTime = calculateWeakenTime(server, Player);
|
||||
workerScript.log("weaken", `Executing on '${server.hostname}' in ${formatNumber(weakenTime, 3)} seconds (t=${threads})`);
|
||||
workerScript.log("weaken", `Executing on '${server.hostname}' in ${convertTimeMsToTimeElapsedString(weakenTime*1000, true)} (t=${numeralWrapper.formatThreads(threads)})`);
|
||||
return netscriptDelay(weakenTime * 1000, workerScript).then(function() {
|
||||
if (workerScript.env.stopFlag) {return Promise.reject(workerScript);}
|
||||
server.weaken(CONSTANTS.ServerWeakenAmount * threads);
|
||||
workerScript.scriptRef.recordWeaken(server.ip, threads);
|
||||
var expGain = calculateHackingExpGain(server, Player) * threads;
|
||||
workerScript.log("weaken", `'${server.hostname}' security level weakened to ${server.hackDifficulty}. Gained ${numeralWrapper.formatExp(expGain)} hacking exp (t=${threads})`);
|
||||
workerScript.log("weaken", `'${server.hostname}' security level weakened to ${server.hackDifficulty}. Gained ${numeralWrapper.formatExp(expGain)} hacking exp (t=${numeralWrapper.formatThreads(threads)})`);
|
||||
workerScript.scriptRef.onlineExpGained += expGain;
|
||||
Player.gainHackingExp(expGain);
|
||||
return Promise.resolve(CONSTANTS.ServerWeakenAmount * threads);
|
||||
@ -1619,7 +1619,7 @@ function NetscriptFunctions(workerScript) {
|
||||
},
|
||||
getBitNodeMultipliers: function() {
|
||||
updateDynamicRam("getBitNodeMultipliers", getRamCost("getBitNodeMultipliers"));
|
||||
if (SourceFileFlags[5] <= 0) {
|
||||
if (SourceFileFlags[5] <= 0 && Player.bitNodeN !== 5) {
|
||||
throw makeRuntimeErrorMsg("getBitNodeMultipliers", "Requires Source-File 5 to run.");
|
||||
}
|
||||
let copy = Object.assign({}, BitNodeMultipliers);
|
||||
@ -1709,6 +1709,18 @@ function NetscriptFunctions(workerScript) {
|
||||
workerScript.log("getServerRam", `returned [${formatNumber(server.maxRam, 2)}GB, ${formatNumber(server.ramUsed, 2)}GB]`);
|
||||
return [server.maxRam, server.ramUsed];
|
||||
},
|
||||
getServerMaxRam: function(ip) {
|
||||
updateDynamicRam("getServerMaxRam", getRamCost("getServerMaxRam"));
|
||||
const server = safeGetServer(ip, "getServerMaxRam");
|
||||
workerScript.log("getServerMaxRam", `returned ${formatNumber(server.maxRam, 2)}GB`);
|
||||
return server.maxRam;
|
||||
},
|
||||
getServerUsedRam: function(ip) {
|
||||
updateDynamicRam("getServerUsedRam", getRamCost("getServerUsedRam"));
|
||||
const server = safeGetServer(ip, "getServerUsedRam");
|
||||
workerScript.log("getServerUsedRam", `returned ${formatNumber(server.ramUsed, 2)}GB`);
|
||||
return server.ramUsed;
|
||||
},
|
||||
serverExists: function(ip) {
|
||||
updateDynamicRam("serverExists", getRamCost("serverExists"));
|
||||
return (getServer(ip) !== null);
|
||||
|
@ -368,5 +368,10 @@ function updateAugDescription(elems: IResleeveUIElems): void {
|
||||
return;
|
||||
}
|
||||
|
||||
elems.augDescription.innerHTML = aug.info;
|
||||
let innerHTML = aug.info;
|
||||
if(typeof innerHTML !== 'string') {
|
||||
innerHTML = renderToStaticMarkup(innerHTML);
|
||||
}
|
||||
|
||||
elems.augDescription.innerHTML = innerHTML;
|
||||
}
|
||||
|
@ -907,7 +907,7 @@ export class Sleeve extends Person {
|
||||
this.currentTaskLocation = LocationName.Sector12PowerhouseGym;
|
||||
costMult = 20;
|
||||
break;
|
||||
case LocationName.VolhavenMilleniumFitnessGym:
|
||||
case LocationName.VolhavenMilleniumFitnessGym.toLowerCase():
|
||||
if (this.city != CityName.Volhaven) { return false; }
|
||||
this.currentTaskLocation = LocationName.VolhavenMilleniumFitnessGym;
|
||||
costMult = 7;
|
||||
|
@ -55,10 +55,15 @@ export function createSleevePurchaseAugsPopup(sleeve: Sleeve, p: IPlayer): void
|
||||
continue;
|
||||
}
|
||||
|
||||
let tooltip = aug.info;
|
||||
if(typeof tooltip !== 'string') {
|
||||
tooltip = renderToStaticMarkup(tooltip);
|
||||
}
|
||||
|
||||
ownedAugsDiv.appendChild(createElement("div", {
|
||||
class: "gang-owned-upgrade", // Reusing a class from the Gang UI
|
||||
innerText: ownedAug,
|
||||
tooltip: aug.info,
|
||||
tooltip: tooltip,
|
||||
}))
|
||||
}
|
||||
popupElems.push(ownedAugsDiv);
|
||||
@ -83,13 +88,18 @@ export function createSleevePurchaseAugsPopup(sleeve: Sleeve, p: IPlayer): void
|
||||
class: "cmpy-mgmt-upgrade-div", // We'll reuse this CSS class
|
||||
});
|
||||
|
||||
let info = aug.info;
|
||||
if(typeof info !== 'string') {
|
||||
info = renderToStaticMarkup(info);
|
||||
}
|
||||
|
||||
div.appendChild(createElement("p", {
|
||||
fontSize: "12px",
|
||||
innerHTML:
|
||||
[
|
||||
`<h2>${aug.name}</h2><br>`,
|
||||
`Cost: ${renderToStaticMarkup(Money(aug.startingCost))}<br><br>`,
|
||||
`${aug.info}`,
|
||||
`${info}`,
|
||||
].join(" "),
|
||||
padding: "2px",
|
||||
clickListener: () => {
|
||||
|
@ -340,6 +340,11 @@ function prestigeSourceFile() {
|
||||
updateHashManagerCapacity();
|
||||
}
|
||||
|
||||
if(SourceFileFlags[12] > 0) {
|
||||
Player.augmentations.push({name: AugmentationNames.NeuroFluxGovernor, level: SourceFileFlags[12]})
|
||||
Player.reapplyAllAugmentations(true);
|
||||
}
|
||||
|
||||
// Refresh Main Menu (the 'World' menu, specifically)
|
||||
document.getElementById("world-menu-header").click();
|
||||
document.getElementById("world-menu-header").click();
|
||||
|
@ -58,13 +58,17 @@ function writeRedPillLetter(pElem, line, i=0) {
|
||||
}
|
||||
|
||||
let redPillFlag = false;
|
||||
function hackWorldDaemon(currentNodeNumber, flume=false) {
|
||||
function hackWorldDaemon(currentNodeNumber, flume=false, quick=false) {
|
||||
// Clear Red Pill screen first
|
||||
var container = document.getElementById("red-pill-content");
|
||||
removeChildrenFromElement(container);
|
||||
|
||||
redPillFlag = true;
|
||||
Engine.loadRedPillContent();
|
||||
|
||||
if(quick) {
|
||||
return loadBitVerse(currentNodeNumber, flume, quick);
|
||||
}
|
||||
return writeRedPillLine("[ERROR] SEMPOOL INVALID").then(function() {
|
||||
return writeRedPillLine("[ERROR] Segmentation Fault");
|
||||
}).then(function() {
|
||||
@ -143,7 +147,7 @@ function giveSourceFile(bitNodeNumber) {
|
||||
// is destroyed. Updated every time loadBitVerse() is called
|
||||
let nextSourceFileFlags = [];
|
||||
|
||||
function loadBitVerse(destroyedBitNodeNum, flume=false) {
|
||||
function loadBitVerse(destroyedBitNodeNum, flume=false, quick=false) {
|
||||
// Clear the screen
|
||||
const container = document.getElementById("red-pill-content");
|
||||
removeChildrenFromElement(container);
|
||||
@ -151,7 +155,7 @@ function loadBitVerse(destroyedBitNodeNum, flume=false) {
|
||||
// Update NextSourceFileFlags
|
||||
nextSourceFileFlags = SourceFileFlags.slice();
|
||||
if (!flume) {
|
||||
if (nextSourceFileFlags[destroyedBitNodeNum] < 3 && destroyedBitNodeNum !== 12)
|
||||
if (nextSourceFileFlags[destroyedBitNodeNum] < 3)
|
||||
++nextSourceFileFlags[destroyedBitNodeNum];
|
||||
}
|
||||
|
||||
@ -221,6 +225,10 @@ function loadBitVerse(destroyedBitNodeNum, flume=false) {
|
||||
}(i)); // Immediate invocation closure
|
||||
}
|
||||
|
||||
if(quick) {
|
||||
return Promise.resolve(true);
|
||||
}
|
||||
|
||||
// Create lore text
|
||||
return writeRedPillLine("Many decades ago, a humanoid extraterrestial species which we call the Enders descended on the Earth...violently").then(function() {
|
||||
return writeRedPillLine("Our species fought back, but it was futile. The Enders had technology far beyond our own...");
|
||||
|
@ -1203,10 +1203,10 @@ export const serverMetadata: IServerMetadata[] = [
|
||||
},
|
||||
{
|
||||
hackDifficulty: 1,
|
||||
hostname: "foodnstuff",
|
||||
hostname: "n00dles",
|
||||
literature: [LiteratureNames.Sector12Crime],
|
||||
maxRamExponent: 4,
|
||||
moneyAvailable: 40000,
|
||||
maxRamExponent: 2,
|
||||
moneyAvailable: 70000,
|
||||
networkLayer: 1,
|
||||
numOpenPortsRequired: 0,
|
||||
organizationName: LocationName.Sector12FoodNStuff,
|
||||
@ -1215,26 +1215,39 @@ export const serverMetadata: IServerMetadata[] = [
|
||||
specialName: LocationName.Sector12FoodNStuff,
|
||||
},
|
||||
{
|
||||
hackDifficulty: 3,
|
||||
hackDifficulty: 10,
|
||||
hostname: "foodnstuff",
|
||||
literature: [LiteratureNames.Sector12Crime],
|
||||
maxRamExponent: 4,
|
||||
moneyAvailable: 2000000,
|
||||
networkLayer: 1,
|
||||
numOpenPortsRequired: 0,
|
||||
organizationName: LocationName.Sector12FoodNStuff,
|
||||
requiredHackingSkill: 1,
|
||||
serverGrowth: 5,
|
||||
specialName: LocationName.Sector12FoodNStuff,
|
||||
},
|
||||
{
|
||||
hackDifficulty: 10,
|
||||
hostname: "sigma-cosmetics",
|
||||
maxRamExponent: 4,
|
||||
moneyAvailable: 70000,
|
||||
moneyAvailable: 2300000,
|
||||
networkLayer: 1,
|
||||
numOpenPortsRequired: 0,
|
||||
organizationName: "Sigma Cosmetics",
|
||||
requiredHackingSkill: 5,
|
||||
serverGrowth: 3000,
|
||||
serverGrowth: 10,
|
||||
},
|
||||
{
|
||||
hackDifficulty: 9,
|
||||
hackDifficulty: 15,
|
||||
hostname: "joesguns",
|
||||
maxRamExponent: 4,
|
||||
moneyAvailable: 600000,
|
||||
moneyAvailable: 2500000,
|
||||
networkLayer: 1,
|
||||
numOpenPortsRequired: 0,
|
||||
organizationName: LocationName.Sector12JoesGuns,
|
||||
requiredHackingSkill: 10,
|
||||
serverGrowth: 500,
|
||||
serverGrowth: 20,
|
||||
specialName: LocationName.Sector12JoesGuns,
|
||||
},
|
||||
{
|
||||
@ -1569,4 +1582,4 @@ export const serverMetadata: IServerMetadata[] = [
|
||||
serverGrowth: 0,
|
||||
specialName: "w0r1d_d43m0n",
|
||||
},
|
||||
];
|
||||
];
|
@ -60,5 +60,4 @@ SourceFiles["SourceFile11"] = new SourceFile(11, "This Source-File makes it so t
|
||||
"Level 1: 32%<br>" +
|
||||
"Level 2: 48%<br>" +
|
||||
"Level 3: 56%<br>");
|
||||
SourceFiles["SourceFile12"] = new SourceFile(12, "This Source-File increases all your multipliers by 1% per level. This effect is multiplicative with itself. " +
|
||||
"In other words, level N of this Source-File will result in a multiplier of 1.01^N (or 0.99^N for multipliers that decrease)");
|
||||
SourceFiles["SourceFile12"] = new SourceFile(12, "This Source-File lets the player start with Neuroflux Governor equal to the level of this Source-File.");
|
||||
|
@ -141,44 +141,9 @@ export function applySourceFile(srcFile: PlayerOwnedSourceFile): void {
|
||||
Player.company_rep_mult *= incMult;
|
||||
break;
|
||||
}
|
||||
case 12: { // The Recursion
|
||||
const inc = Math.pow(1.01, srcFile.lvl);
|
||||
const dec = Math.pow(0.99, srcFile.lvl);
|
||||
|
||||
Player.hacking_chance_mult *= inc;
|
||||
Player.hacking_speed_mult *= inc;
|
||||
Player.hacking_money_mult *= inc;
|
||||
Player.hacking_grow_mult *= inc;
|
||||
Player.hacking_mult *= inc;
|
||||
|
||||
Player.strength_mult *= inc;
|
||||
Player.defense_mult *= inc;
|
||||
Player.dexterity_mult *= inc;
|
||||
Player.agility_mult *= inc;
|
||||
Player.charisma_mult *= inc;
|
||||
|
||||
Player.hacking_exp_mult *= inc;
|
||||
Player.strength_exp_mult *= inc;
|
||||
Player.defense_exp_mult *= inc;
|
||||
Player.dexterity_exp_mult *= inc;
|
||||
Player.agility_exp_mult *= inc;
|
||||
Player.charisma_exp_mult *= inc;
|
||||
|
||||
Player.company_rep_mult *= inc;
|
||||
Player.faction_rep_mult *= inc;
|
||||
|
||||
Player.crime_money_mult *= inc;
|
||||
Player.crime_success_mult *= inc;
|
||||
|
||||
Player.hacknet_node_money_mult *= inc;
|
||||
Player.hacknet_node_purchase_cost_mult *= dec;
|
||||
Player.hacknet_node_ram_cost_mult *= dec;
|
||||
Player.hacknet_node_core_cost_mult *= dec;
|
||||
Player.hacknet_node_level_cost_mult *= dec;
|
||||
|
||||
Player.work_money_mult *= inc;
|
||||
case 12: // The Recursion
|
||||
// No effects, grants neuroflux.
|
||||
break;
|
||||
}
|
||||
default:
|
||||
console.error(`Invalid source file number: ${srcFile.n}`);
|
||||
break;
|
||||
|
@ -53,7 +53,11 @@ import { Player } from "./Player";
|
||||
import { hackWorldDaemon } from "./RedPill";
|
||||
import { RunningScript } from "./Script/RunningScript";
|
||||
import { getRamUsageFromRunningScript } from "./Script/RunningScriptHelpers";
|
||||
import { getCurrentEditor, findRunningScript } from "./Script/ScriptHelpers";
|
||||
import {
|
||||
getCurrentEditor,
|
||||
findRunningScript,
|
||||
findRunningScriptByPid,
|
||||
} from "./Script/ScriptHelpers";
|
||||
import { isScriptFilename } from "./Script/ScriptHelpersTS";
|
||||
import { AllServers } from "./Server/AllServers";
|
||||
import {
|
||||
@ -571,47 +575,26 @@ let Terminal = {
|
||||
let currServ = Player.getCurrentServer();
|
||||
const isHacknet = currServ instanceof HacknetServer;
|
||||
post(currServ.hostname + ": ");
|
||||
post("Organization name: " + currServ.organizationName);
|
||||
var rootAccess = "";
|
||||
if (currServ.hasAdminRights) {rootAccess = "YES";}
|
||||
else {rootAccess = "NO";}
|
||||
post("Root Access: " + rootAccess);
|
||||
if (!isHacknet) { post("Required hacking skill: " + currServ.requiredHackingSkill); }
|
||||
post("Server security level: " + numeralWrapper.formatServerSecurity(currServ.hackDifficulty));
|
||||
post("Chance to hack: " + numeralWrapper.formatPercentage(calculateHackingChance(currServ, Player)));
|
||||
post("Time to hack: " + convertTimeMsToTimeElapsedString(calculateHackingTime(currServ, Player)*1000));
|
||||
postElement(<>Total money available on server: {Money(currServ.moneyAvailable)}</>);
|
||||
if (!isHacknet) { post("Required number of open ports for NUKE: " + currServ.numOpenPortsRequired); }
|
||||
|
||||
if (currServ.sshPortOpen) {
|
||||
post("SSH port: Open")
|
||||
} else {
|
||||
post("SSH port: Closed")
|
||||
}
|
||||
|
||||
if (currServ.ftpPortOpen) {
|
||||
post("FTP port: Open")
|
||||
} else {
|
||||
post("FTP port: Closed")
|
||||
}
|
||||
|
||||
if (currServ.smtpPortOpen) {
|
||||
post("SMTP port: Open")
|
||||
} else {
|
||||
post("SMTP port: Closed")
|
||||
}
|
||||
|
||||
if (currServ.httpPortOpen) {
|
||||
post("HTTP port: Open")
|
||||
} else {
|
||||
post("HTTP port: Closed")
|
||||
}
|
||||
|
||||
if (currServ.sqlPortOpen) {
|
||||
post("SQL port: Open")
|
||||
} else {
|
||||
post("SQL port: Closed")
|
||||
}
|
||||
const org = currServ.organizationName
|
||||
post("Organization name: " + (!isHacknet ? org : "Player"));
|
||||
const admin = currServ.hasAdminRights;
|
||||
post("Root Access: " + (!isHacknet ? "YES" : "NO"));
|
||||
const hackingSkill = currServ.requiredHackingSkill
|
||||
post("Required hacking skill: " + (!isHacknet ? hackingSkill : "N/A"));
|
||||
const security = currServ.hackDifficulty;
|
||||
post("Server security level: " + (!isHacknet ? numeralWrapper.formatServerSecurity(security) : "N/A"));
|
||||
const hackingChance = calculateHackingChance(currServ, Player)
|
||||
post("Chance to hack: " + (!isHacknet ? numeralWrapper.formatPercentage(hackingChance) : "N/A"));
|
||||
const hackingTime = calculateHackingTime(currServ, Player)*1000;
|
||||
post("Time to hack: " + (!isHacknet ? convertTimeMsToTimeElapsedString(hackingTime, true) : "N/A"));
|
||||
postElement(<>Total money available on server: {!isHacknet ? Money(currServ.moneyAvailable) : "N/A"}</>);
|
||||
const numPort = currServ.numOpenPortsRequired;
|
||||
post("Required number of open ports for NUKE: " + (!isHacknet ? numPort : "N/A"));
|
||||
post("SSH port: "+ (currServ.sshPortOpen ? "Open" : "Closed"))
|
||||
post("FTP port: "+ (currServ.ftpPortOpen ? "Open" : "Closed"))
|
||||
post("SMTP port: "+ (currServ.smtpPortOpen ? "Open" : "Closed"))
|
||||
post("HTTP port: "+ (currServ.httpPortOpen ? "Open" : "Closed"))
|
||||
post("SQL port: "+ (currServ.sqlPortOpen ? "Open" : "Closed"))
|
||||
}
|
||||
Terminal.analyzeFlag = false;
|
||||
},
|
||||
@ -1405,10 +1388,10 @@ let Terminal = {
|
||||
try {
|
||||
if (commandArray.length < 2) {
|
||||
postError("Incorrect number of arguments. Usage: tail [script] [arg1] [arg2]...");
|
||||
} else {
|
||||
} else if(typeof commandArray[1] === 'string') {
|
||||
const scriptName = Terminal.getFilepath(commandArray[1]);
|
||||
if (!isScriptFilename(scriptName)) {
|
||||
postError("tail can only be called on .script files (filename must end with .script)");
|
||||
postError("tail can only be called on .script, .ns, .js files, or by pid");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1425,6 +1408,13 @@ let Terminal = {
|
||||
return;
|
||||
}
|
||||
logBoxCreate(runningScript);
|
||||
} else {
|
||||
const runningScript = findRunningScriptByPid(commandArray[1], Player.getCurrentServer());
|
||||
if (runningScript == null) {
|
||||
postError("No such script exists");
|
||||
return;
|
||||
}
|
||||
logBoxCreate(runningScript);
|
||||
}
|
||||
} catch(e) {
|
||||
Terminal.postThrownError(e);
|
||||
@ -2136,13 +2126,19 @@ let Terminal = {
|
||||
post("Invalid server IP/hostname");
|
||||
return;
|
||||
}
|
||||
|
||||
if(targetServer instanceof HacknetServer) {
|
||||
post(`${Programs.ServerProfiler.name} cannot be run on a Hacknet Server.`);
|
||||
return
|
||||
}
|
||||
|
||||
post(targetServer.hostname + ":");
|
||||
post("Server base security level: " + targetServer.baseDifficulty);
|
||||
post("Server current security level: " + targetServer.hackDifficulty);
|
||||
post("Server growth rate: " + targetServer.serverGrowth);
|
||||
post(`Netscript hack() execution time: ${convertTimeMsToTimeElapsedString(calculateHackingTime(targetServer, Player)*1000)}`);
|
||||
post(`Netscript grow() execution time: ${convertTimeMsToTimeElapsedString(calculateGrowTime(targetServer, Player)*1000)}`);
|
||||
post(`Netscript weaken() execution time: ${convertTimeMsToTimeElapsedString(calculateWeakenTime(targetServer, Player)*1000)}`);
|
||||
post(`Netscript hack() execution time: ${convertTimeMsToTimeElapsedString(calculateHackingTime(targetServer, Player)*1000, true)}`);
|
||||
post(`Netscript grow() execution time: ${convertTimeMsToTimeElapsedString(calculateGrowTime(targetServer, Player)*1000, true)}`);
|
||||
post(`Netscript weaken() execution time: ${convertTimeMsToTimeElapsedString(calculateWeakenTime(targetServer, Player)*1000, true)}`);
|
||||
};
|
||||
programHandlers[Programs.AutoLink.name] = () => {
|
||||
post("This executable cannot be run.");
|
||||
|
@ -340,8 +340,8 @@ if (htmlWebpackPlugin.options.googleAnalytics.trackingId) { %>
|
||||
Would you like to join? <br /> <br />
|
||||
Warning: Joining this faction may prevent you from joining other factions during this run!
|
||||
</p>
|
||||
<button id="faction-invitation-box-yes" class="popup-box-button"> Yes </button>
|
||||
<button id="faction-invitation-box-no" class="popup-box-button"> No </button>
|
||||
<button id="faction-invitation-box-yes" class="popup-box-button"> Join! </button>
|
||||
<button id="faction-invitation-box-no" class="popup-box-button"> Decide later </button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -49,7 +49,7 @@ export function WorkerScriptAccordion(props: IProps): React.ReactElement {
|
||||
panelClass="active-scripts-script-panel"
|
||||
panelContent={
|
||||
<>
|
||||
<pre>Threads: {props.workerScript.scriptRef.threads}</pre>
|
||||
<pre>Threads: {numeralWrapper.formatThreads(props.workerScript.scriptRef.threads)}</pre>
|
||||
<pre>Args: {arrayToString(props.workerScript.args)}</pre>
|
||||
<pre>Online Time: {convertTimeMsToTimeElapsedString(scriptRef.onlineRunningTime * 1e3)}</pre>
|
||||
<pre>Offline Time: {convertTimeMsToTimeElapsedString(scriptRef.offlineRunningTime * 1e3)}</pre>
|
||||
|
@ -24,10 +24,19 @@ export function AugmentationAccordion(props: IProps): React.ReactElement {
|
||||
}
|
||||
}
|
||||
|
||||
if(typeof props.aug.info === 'string') {
|
||||
return (
|
||||
<Accordion
|
||||
headerContent={<>{displayName}</>}
|
||||
panelContent={<p dangerouslySetInnerHTML={{__html: props.aug.info}}></p>}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<Accordion
|
||||
headerContent={<>{displayName}</>}
|
||||
panelContent={<p dangerouslySetInnerHTML={{__html: props.aug.info}}></p>}
|
||||
panelContent={<p>{props.aug.info}</p>}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
@ -15,8 +15,7 @@ export class CharacterOverviewComponent extends Component {
|
||||
);
|
||||
|
||||
return (
|
||||
<div id="character-overview-text">
|
||||
<table>
|
||||
<table>
|
||||
<tbody>
|
||||
<tr id="character-hp-wrapper">
|
||||
<td className="character-hp-cell">Hp:</td><td id="character-hp-text" className="character-hp-cell character-stat-cell">{numeralWrapper.formatHp(Player.hp) + " / " + numeralWrapper.formatHp(Player.max_hp)}</td>
|
||||
@ -47,8 +46,7 @@ export class CharacterOverviewComponent extends Component {
|
||||
intelligence
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</table>
|
||||
)
|
||||
}
|
||||
}
|
@ -53,6 +53,9 @@ class NumeralFormatter {
|
||||
}
|
||||
|
||||
formatMoney(n: number): string {
|
||||
if(n < 1000) {
|
||||
return this.format(n, "$0.00");
|
||||
}
|
||||
return this.format(n, "$0.000a");
|
||||
}
|
||||
|
||||
@ -131,6 +134,10 @@ class NumeralFormatter {
|
||||
formatInfiltrationSecurity(n: number): string {
|
||||
return this.format(n, "0.000a");
|
||||
}
|
||||
|
||||
formatThreads(n: number): string {
|
||||
return this.format(n, "0,0");
|
||||
}
|
||||
}
|
||||
|
||||
export const numeralWrapper = new NumeralFormatter();
|
||||
|
@ -394,6 +394,16 @@ describe("Netscript Dynamic RAM Calculation/Generation Tests", function() {
|
||||
await testNonzeroDynamicRamCost(f);
|
||||
});
|
||||
|
||||
it("getServerMaxRam()", async function() {
|
||||
const f = ["getServerMaxRam"];
|
||||
await testNonzeroDynamicRamCost(f);
|
||||
});
|
||||
|
||||
it("getServerUsedRam()", async function() {
|
||||
const f = ["getServerUsedRam"];
|
||||
await testNonzeroDynamicRamCost(f);
|
||||
});
|
||||
|
||||
it("serverExists()", async function() {
|
||||
const f = ["serverExists"];
|
||||
await testNonzeroDynamicRamCost(f);
|
||||
|
@ -284,6 +284,16 @@ describe("Netscript Static RAM Calculation/Generation Tests", function() {
|
||||
await expectNonZeroRamCost(f);
|
||||
});
|
||||
|
||||
it("getServerMaxRam()", async function() {
|
||||
const f = ["getServerMaxRam"];
|
||||
await expectNonZeroRamCost(f);
|
||||
});
|
||||
|
||||
it("getServerUsedRam()", async function() {
|
||||
const f = ["getServerUsedRam"];
|
||||
await expectNonZeroRamCost(f);
|
||||
});
|
||||
|
||||
it("serverExists()", async function() {
|
||||
const f = ["serverExists"];
|
||||
await expectNonZeroRamCost(f);
|
||||
|
11
test/StringHelperFunctionsTests.ts
Normal file
11
test/StringHelperFunctionsTests.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import { expect } from "chai";
|
||||
import { convertTimeMsToTimeElapsedString } from "../utils/StringHelperFunctions";
|
||||
|
||||
describe("StringHelperFunctions Tests", function() {
|
||||
expect(convertTimeMsToTimeElapsedString(1000)).to.equal("1 seconds");
|
||||
expect(convertTimeMsToTimeElapsedString(5*60*1000+34*1000)).to.equal("5 minutes 34 seconds");
|
||||
expect(convertTimeMsToTimeElapsedString(2*60*60*24*1000+5*60*1000+34*1000)).to.equal("2 days 5 minutes 34 seconds");
|
||||
expect(convertTimeMsToTimeElapsedString(2*60*60*24*1000+5*60*1000+34*1000, true)).to.equal("2 days 5 minutes 34.000 seconds");
|
||||
expect(convertTimeMsToTimeElapsedString(2*60*60*24*1000+5*60*1000+34*1000+123, true)).to.equal("2 days 5 minutes 34.123 seconds");
|
||||
expect(convertTimeMsToTimeElapsedString(2*60*60*24*1000+5*60*1000+34*1000+123.888, true)).to.equal("2 days 5 minutes 34.123 seconds");
|
||||
})
|
@ -1,4 +1,5 @@
|
||||
export * from "./Netscript/DynamicRamCalculationTests";
|
||||
export * from "./Netscript/StaticRamCalculationTests";
|
||||
export * from "./StockMarketTests";
|
||||
export * from "./StringHelperFunctionsTests";
|
||||
export * from "./Terminal/DirectoryTests";
|
||||
|
@ -13,7 +13,8 @@ Converts a date representing time in milliseconds to a string with the format H
|
||||
e.g. 10000 -> "10 seconds"
|
||||
120000 -> "2 minutes and 0 seconds"
|
||||
*/
|
||||
function convertTimeMsToTimeElapsedString(time: number): string {
|
||||
function convertTimeMsToTimeElapsedString(time: number, showMilli=false): string {
|
||||
time = Math.floor(time);
|
||||
const millisecondsPerSecond = 1000;
|
||||
const secondPerMinute = 60;
|
||||
const minutesPerHours = 60;
|
||||
@ -33,7 +34,13 @@ function convertTimeMsToTimeElapsedString(time: number): string {
|
||||
const minutes: number = Math.floor(secTruncHours / secondPerMinute);
|
||||
const secTruncMinutes: number = secTruncHours % secondPerMinute;
|
||||
|
||||
const seconds: number = secTruncMinutes;
|
||||
const milliTruncSec: string = (() => {
|
||||
let str: string = `${time % millisecondsPerSecond}`;
|
||||
while(str.length < 3) str = "0"+str;
|
||||
return str;
|
||||
})()
|
||||
|
||||
const seconds: string = showMilli ? `${secTruncMinutes}.${milliTruncSec}` : `${secTruncMinutes}`;
|
||||
|
||||
let res = "";
|
||||
if (days > 0) {res += `${days} days `; }
|
||||
|
Loading…
Reference in New Issue
Block a user