diff --git a/doc/source/netscript/basicfunctions/getServerMaxRam.rst b/doc/source/netscript/basicfunctions/getServerMaxRam.rst new file mode 100644 index 000000000..d895c494e --- /dev/null +++ b/doc/source/netscript/basicfunctions/getServerMaxRam.rst @@ -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"); diff --git a/doc/source/netscript/basicfunctions/getServerRam.rst b/doc/source/netscript/basicfunctions/getServerRam.rst index 40e46df42..70d3ce032 100644 --- a/doc/source/netscript/basicfunctions/getServerRam.rst +++ b/doc/source/netscript/basicfunctions/getServerRam.rst @@ -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 diff --git a/doc/source/netscript/basicfunctions/getServerUsedRam.rst b/doc/source/netscript/basicfunctions/getServerUsedRam.rst new file mode 100644 index 000000000..878389cb0 --- /dev/null +++ b/doc/source/netscript/basicfunctions/getServerUsedRam.rst @@ -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"); diff --git a/doc/source/netscript/netscriptfunctions.rst b/doc/source/netscript/netscriptfunctions.rst index d0cb3ce37..deea623f9 100644 --- a/doc/source/netscript/netscriptfunctions.rst +++ b/doc/source/netscript/netscriptfunctions.rst @@ -54,7 +54,8 @@ This includes information such as function signatures, what they do, and their r getServerMinSecurityLevel() getServerRequiredHackingLevel() getServerNumPortsRequired() - getServerRam() + getServerMaxRam() + getServerUsedRam() serverExists() fileExists() isRunning() @@ -90,3 +91,8 @@ This includes information such as function signatures, what they do, and their r wget() getFavorToDonate() flags() + +.. toctree:: + :caption: Deprecated: + + getServerRam() \ No newline at end of file diff --git a/doc/source/netscript/netscripthacknetnodeapi.rst b/doc/source/netscript/netscripthacknetnodeapi.rst index 075633cf4..25b09b4b7 100644 --- a/doc/source/netscript/netscripthacknetnodeapi.rst +++ b/doc/source/netscript/netscripthacknetnodeapi.rst @@ -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"); diff --git a/index.html b/index.html index f09efe1da..65a1cdad5 100644 --- a/index.html +++ b/index.html @@ -327,8 +327,8 @@ Would you like to join?

Warning: Joining this faction may prevent you from joining other factions during this run!

- - + + diff --git a/src/Augmentation/Augmentation.ts b/src/Augmentation/Augmentation.ts index e1597038f..283265fae 100644 --- a/src/Augmentation/Augmentation.ts +++ b/src/Augmentation/Augmentation.ts @@ -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; diff --git a/src/Augmentation/AugmentationHelpers.jsx b/src/Augmentation/AugmentationHelpers.jsx index 3db94a334..30cf40e00 100644 --- a/src/Augmentation/AugmentationHelpers.jsx +++ b/src/Augmentation/AugmentationHelpers.jsx @@ -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]; } diff --git a/src/BitNode/BitNode.ts b/src/BitNode/BitNode.ts index ed86041cc..67adcc3c9 100644 --- a/src/BitNode/BitNode.ts +++ b/src/BitNode/BitNode.ts @@ -236,8 +236,7 @@ BitNodes["BitNode12"] = new BitNode(12, "The Recursion", "Repeat.", "To iterate is human, to recurse divine.

" + "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"); diff --git a/src/Bladeburner/BlackOperations.ts b/src/Bladeburner/BlackOperations.ts index f7ed13fc6..cb75f91d4 100644 --- a/src/Bladeburner/BlackOperations.ts +++ b/src/Bladeburner/BlackOperations.ts @@ -160,7 +160,7 @@ export const BlackOperations: IMap = {}; "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.

" + "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 = {}; "means that the supercomputer may be able to reason abstractly " + "and become self-aware.

" + "I do not need to remind you why sentient-level AIs pose a serious " + - "thread to all of mankind.

" + + "threat to all of mankind.

" + "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 = {}; 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}, }); -})() \ No newline at end of file +})() diff --git a/src/DevMenu.jsx b/src/DevMenu.jsx index 98b53fcd1..fd19c44eb 100644 --- a/src/DevMenu.jsx +++ b/src/DevMenu.jsx @@ -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 {
- + +
diff --git a/src/Exploits/applyExploits.ts b/src/Exploits/applyExploits.ts index f1cdfe32d..fede837a4 100644 --- a/src/Exploits/applyExploits.ts +++ b/src/Exploits/applyExploits.ts @@ -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; diff --git a/src/Faction/ui/DonateOption.tsx b/src/Faction/ui/DonateOption.tsx index 9b0c63d48..c7bed8247 100644 --- a/src/Faction/ui/DonateOption.tsx +++ b/src/Faction/ui/DonateOption.tsx @@ -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 { 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 { return (
- +

{this.state.status}

diff --git a/src/Faction/ui/Root.tsx b/src/Faction/ui/Root.tsx index fb9156309..5e8259436 100644 --- a/src/Faction/ui/Root.tsx +++ b/src/Faction/ui/Root.tsx @@ -264,11 +264,13 @@ export class FactionRoot extends React.Component { /> } { - (!isPlayersGang && canDonate) && + !isPlayersGang && }
diff --git a/src/ui/ActiveScripts/WorkerScriptAccordion.tsx b/src/ui/ActiveScripts/WorkerScriptAccordion.tsx index f084f659f..f055fd07a 100644 --- a/src/ui/ActiveScripts/WorkerScriptAccordion.tsx +++ b/src/ui/ActiveScripts/WorkerScriptAccordion.tsx @@ -49,7 +49,7 @@ export function WorkerScriptAccordion(props: IProps): React.ReactElement { panelClass="active-scripts-script-panel" panelContent={ <> -
Threads: {props.workerScript.scriptRef.threads}
+
Threads: {numeralWrapper.formatThreads(props.workerScript.scriptRef.threads)}
Args: {arrayToString(props.workerScript.args)}
Online Time: {convertTimeMsToTimeElapsedString(scriptRef.onlineRunningTime * 1e3)}
Offline Time: {convertTimeMsToTimeElapsedString(scriptRef.offlineRunningTime * 1e3)}
diff --git a/src/ui/React/AugmentationAccordion.tsx b/src/ui/React/AugmentationAccordion.tsx index 87ab4ae8f..19eb601f2 100644 --- a/src/ui/React/AugmentationAccordion.tsx +++ b/src/ui/React/AugmentationAccordion.tsx @@ -24,10 +24,19 @@ export function AugmentationAccordion(props: IProps): React.ReactElement { } } + if(typeof props.aug.info === 'string') { + return ( + {displayName}} + panelContent={

} + /> + ) + } + return ( {displayName}} - panelContent={

} + panelContent={

{props.aug.info}

} /> ) } diff --git a/src/ui/React/CharacterOverview.jsx b/src/ui/React/CharacterOverview.jsx index 631145721..638da227f 100644 --- a/src/ui/React/CharacterOverview.jsx +++ b/src/ui/React/CharacterOverview.jsx @@ -15,8 +15,7 @@ export class CharacterOverviewComponent extends Component { ); return ( -
- +
@@ -47,8 +46,7 @@ export class CharacterOverviewComponent extends Component { intelligence } -
Hp:{numeralWrapper.formatHp(Player.hp) + " / " + numeralWrapper.formatHp(Player.max_hp)}
-
+ ) } } \ No newline at end of file diff --git a/src/ui/numeralFormat.ts b/src/ui/numeralFormat.ts index df84e3ed7..30d55cf3c 100644 --- a/src/ui/numeralFormat.ts +++ b/src/ui/numeralFormat.ts @@ -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(); diff --git a/test/Netscript/DynamicRamCalculationTests.js b/test/Netscript/DynamicRamCalculationTests.js index 95d5040bb..5552508f0 100644 --- a/test/Netscript/DynamicRamCalculationTests.js +++ b/test/Netscript/DynamicRamCalculationTests.js @@ -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); diff --git a/test/Netscript/StaticRamCalculationTests.js b/test/Netscript/StaticRamCalculationTests.js index a883e3b71..bd40a32c3 100644 --- a/test/Netscript/StaticRamCalculationTests.js +++ b/test/Netscript/StaticRamCalculationTests.js @@ -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); diff --git a/test/StringHelperFunctionsTests.ts b/test/StringHelperFunctionsTests.ts new file mode 100644 index 000000000..2e45f7845 --- /dev/null +++ b/test/StringHelperFunctionsTests.ts @@ -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"); +}) \ No newline at end of file diff --git a/test/index.js b/test/index.js index 68045825f..3b95de359 100644 --- a/test/index.js +++ b/test/index.js @@ -1,4 +1,5 @@ export * from "./Netscript/DynamicRamCalculationTests"; export * from "./Netscript/StaticRamCalculationTests"; export * from "./StockMarketTests"; +export * from "./StringHelperFunctionsTests"; export * from "./Terminal/DirectoryTests"; diff --git a/utils/StringHelperFunctions.ts b/utils/StringHelperFunctions.ts index effe284d4..90f80fab5 100644 --- a/utils/StringHelperFunctions.ts +++ b/utils/StringHelperFunctions.ts @@ -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 `; }