mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-11-20 06:33:49 +01:00
Merge branch 'dev' into bugfix/corp-updates
This commit is contained in:
commit
244bb5737e
16
dist/bitburner.d.ts
vendored
16
dist/bitburner.d.ts
vendored
@ -1773,6 +1773,18 @@ export declare interface Grafting {
|
||||
*/
|
||||
getAugmentationGraftTime(augName: string): number;
|
||||
|
||||
/**
|
||||
* Retrieves a list of Augmentations that can be grafted.
|
||||
* @remarks
|
||||
* RAM cost: 5 GB
|
||||
*
|
||||
* Note that this function returns a list of currently graftable Augmentations,
|
||||
* based off of the Augmentations that you already own.
|
||||
*
|
||||
* @returns An array of graftable Augmentations.
|
||||
*/
|
||||
getGraftableAugmentations(): string[];
|
||||
|
||||
/**
|
||||
* Begins grafting the named aug. You must be in New Tokyo to use this.
|
||||
* @remarks
|
||||
@ -2911,9 +2923,11 @@ export declare interface NS {
|
||||
* Returns the security increase that would occur if a grow with this many threads happened.
|
||||
*
|
||||
* @param threads - Amount of threads that will be used.
|
||||
* @param hostname - Optional. Hostname of the target server. The number of threads is limited to the number needed to hack the servers maximum amount of money.
|
||||
* @param cores - Optional. The number of cores of the server that would run grow.
|
||||
* @returns The security increase.
|
||||
*/
|
||||
growthAnalyzeSecurity(threads: number): number;
|
||||
growthAnalyzeSecurity(threads: number, hostname?: string, cores?: number): number;
|
||||
|
||||
/**
|
||||
* Suspends the script for n milliseconds.
|
||||
|
4
dist/main.bundle.js
vendored
4
dist/main.bundle.js
vendored
File diff suppressed because one or more lines are too long
2
dist/main.bundle.js.map
vendored
2
dist/main.bundle.js.map
vendored
File diff suppressed because one or more lines are too long
40
dist/vendor.bundle.js
vendored
40
dist/vendor.bundle.js
vendored
File diff suppressed because one or more lines are too long
2
dist/vendor.bundle.js.map
vendored
2
dist/vendor.bundle.js.map
vendored
File diff suppressed because one or more lines are too long
@ -66,7 +66,7 @@ documentation_title = '{0} Documentation'.format(project)
|
||||
# The short X.Y version.
|
||||
version = '1.6'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '1.6.3'
|
||||
release = '1.6.4'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
|
4
electron/package-lock.json
generated
4
electron/package-lock.json
generated
@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "bitburner",
|
||||
"version": "1.6.3",
|
||||
"version": "1.6.4",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "bitburner",
|
||||
"version": "1.6.3",
|
||||
"version": "1.6.4",
|
||||
"dependencies": {
|
||||
"electron-config": "^2.0.0",
|
||||
"electron-log": "^4.4.4",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "bitburner",
|
||||
"version": "1.6.3",
|
||||
"version": "1.6.4",
|
||||
"description": "A cyberpunk-themed programming incremental game",
|
||||
"main": "main.js",
|
||||
"author": "Daniel Xie & Olivier Gagnon",
|
||||
|
25
markdown/bitburner.grafting.getgraftableaugmentations.md
Normal file
25
markdown/bitburner.grafting.getgraftableaugmentations.md
Normal file
@ -0,0 +1,25 @@
|
||||
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
||||
|
||||
[Home](./index.md) > [bitburner](./bitburner.md) > [Grafting](./bitburner.grafting.md) > [getGraftableAugmentations](./bitburner.grafting.getgraftableaugmentations.md)
|
||||
|
||||
## Grafting.getGraftableAugmentations() method
|
||||
|
||||
Retrieves a list of Augmentations that can be grafted.
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```typescript
|
||||
getGraftableAugmentations(): string[];
|
||||
```
|
||||
<b>Returns:</b>
|
||||
|
||||
string\[\]
|
||||
|
||||
An array of graftable Augmentations.
|
||||
|
||||
## Remarks
|
||||
|
||||
RAM cost: 5 GB
|
||||
|
||||
Note that this function returns a list of currently graftable Augmentations, based off of the Augmentations that you already own.
|
||||
|
@ -22,5 +22,6 @@ This API requires Source-File 10 to use.
|
||||
| --- | --- |
|
||||
| [getAugmentationGraftPrice(augName)](./bitburner.grafting.getaugmentationgraftprice.md) | Retrieve the grafting cost of an aug. |
|
||||
| [getAugmentationGraftTime(augName)](./bitburner.grafting.getaugmentationgrafttime.md) | Retrieves the time required to graft an aug. |
|
||||
| [getGraftableAugmentations()](./bitburner.grafting.getgraftableaugmentations.md) | Retrieves a list of Augmentations that can be grafted. |
|
||||
| [graftAugmentation(augName, focus)](./bitburner.grafting.graftaugmentation.md) | Begins grafting the named aug. You must be in New Tokyo to use this. |
|
||||
|
||||
|
@ -9,7 +9,7 @@ Calculate the security increase for a number of thread.
|
||||
<b>Signature:</b>
|
||||
|
||||
```typescript
|
||||
growthAnalyzeSecurity(threads: number): number;
|
||||
growthAnalyzeSecurity(threads: number, hostname?: string, cores?: number): number;
|
||||
```
|
||||
|
||||
## Parameters
|
||||
@ -17,6 +17,8 @@ growthAnalyzeSecurity(threads: number): number;
|
||||
| Parameter | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| threads | number | Amount of threads that will be used. |
|
||||
| hostname | string | Optional. Hostname of the target server. The number of threads is limited to the number needed to hack the servers maximum amount of money. |
|
||||
| cores | number | Optional. The number of cores of the server that would run grow. |
|
||||
|
||||
<b>Returns:</b>
|
||||
|
||||
|
@ -115,7 +115,7 @@ export async function main(ns) {
|
||||
| [getWeakenTime(host)](./bitburner.ns.getweakentime.md) | Get the execution time of a weaken() call. |
|
||||
| [grow(host, opts)](./bitburner.ns.grow.md) | Spoof money in a servers bank account, increasing the amount available. |
|
||||
| [growthAnalyze(host, growthAmount, cores)](./bitburner.ns.growthanalyze.md) | Calculate the number of grow thread needed to grow a server by a certain multiplier. |
|
||||
| [growthAnalyzeSecurity(threads)](./bitburner.ns.growthanalyzesecurity.md) | Calculate the security increase for a number of thread. |
|
||||
| [growthAnalyzeSecurity(threads, hostname, cores)](./bitburner.ns.growthanalyzesecurity.md) | Calculate the security increase for a number of thread. |
|
||||
| [hack(host, opts)](./bitburner.ns.hack.md) | Steal a servers money. |
|
||||
| [hackAnalyze(host)](./bitburner.ns.hackanalyze.md) | Get the part of money stolen with a single thread. |
|
||||
| [hackAnalyzeChance(host)](./bitburner.ns.hackanalyzechance.md) | Get the chance of successfully hacking a server. |
|
||||
|
4
package-lock.json
generated
4
package-lock.json
generated
@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "bitburner",
|
||||
"version": "1.6.3",
|
||||
"version": "1.6.4",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "bitburner",
|
||||
"version": "1.6.3",
|
||||
"version": "1.6.4",
|
||||
"hasInstallScript": true,
|
||||
"license": "SEE LICENSE IN license.txt",
|
||||
"dependencies": {
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "bitburner",
|
||||
"license": "SEE LICENSE IN license.txt",
|
||||
"version": "1.6.3",
|
||||
"version": "1.6.4",
|
||||
"main": "electron-main.js",
|
||||
"author": {
|
||||
"name": "Daniel Xie & Olivier Gagnon"
|
||||
|
@ -380,9 +380,6 @@ export class Augmentation {
|
||||
// Name of Augmentation
|
||||
name = "";
|
||||
|
||||
// Whether the player owns this Augmentation
|
||||
owned = false;
|
||||
|
||||
// Array of names of all prerequisites
|
||||
prereqs: string[] = [];
|
||||
|
||||
|
@ -118,8 +118,6 @@ function resetAugmentation(aug: Augmentation): void {
|
||||
}
|
||||
|
||||
function applyAugmentation(aug: IPlayerOwnedAugmentation, reapply = false): void {
|
||||
Augmentations[aug.name].owned = true;
|
||||
|
||||
const augObj = Augmentations[aug.name];
|
||||
|
||||
// Apply multipliers
|
||||
|
@ -28,7 +28,6 @@ import { Factions, factionExists } from "../Faction/Factions";
|
||||
import { calculateHospitalizationCost } from "../Hospital/Hospital";
|
||||
import { dialogBoxCreate } from "../ui/React/DialogBox";
|
||||
import { Settings } from "../Settings/Settings";
|
||||
import { Augmentations } from "../Augmentation/Augmentations";
|
||||
import { AugmentationNames } from "../Augmentation/data/AugmentationNames";
|
||||
import { getTimestamp } from "../utils/helpers/getTimestamp";
|
||||
import { joinFaction } from "../Faction/FactionHelpers";
|
||||
@ -1920,7 +1919,7 @@ export class Bladeburner implements IBladeburner {
|
||||
}
|
||||
|
||||
// If the Player starts doing some other actions, set action to idle and alert
|
||||
if (Augmentations[AugmentationNames.BladesSimulacrum].owned === false && player.isWorking) {
|
||||
if (player.hasAugmentation(AugmentationNames.BladesSimulacrum) === false && player.isWorking) {
|
||||
if (this.action.type !== ActionTypes["Idle"]) {
|
||||
let msg = "Your Bladeburner action was cancelled because you started doing something else.";
|
||||
if (this.automateEnabled) {
|
||||
|
@ -116,7 +116,7 @@ export const CONSTANTS: {
|
||||
TotalNumBitNodes: number;
|
||||
LatestUpdate: string;
|
||||
} = {
|
||||
VersionString: "1.6.3",
|
||||
VersionString: "1.6.4",
|
||||
VersionNumber: 13,
|
||||
|
||||
// Speed (in ms) at which the main loop is updated
|
||||
|
@ -14,6 +14,7 @@ import { MenuItem, SelectChangeEvent, TextField, Select } from "@mui/material";
|
||||
import { Bladeburner } from "../../Bladeburner/Bladeburner";
|
||||
import { GangConstants } from "../../Gang/data/Constants";
|
||||
import { FactionNames } from "../../Faction/data/FactionNames";
|
||||
import { checkForMessagesToSend } from "../../Message/MessageHelpers";
|
||||
|
||||
interface IProps {
|
||||
player: IPlayer;
|
||||
@ -67,6 +68,10 @@ export function General(props: IProps): React.ReactElement {
|
||||
function setGangFactionDropdown(event: SelectChangeEvent<string>): void {
|
||||
setGangFaction(event.target.value);
|
||||
}
|
||||
|
||||
function checkMessages(): void {
|
||||
checkForMessagesToSend();
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (error) throw new ReferenceError("Manually thrown error");
|
||||
@ -127,6 +132,7 @@ export function General(props: IProps): React.ReactElement {
|
||||
<Button onClick={quickHackW0r1dD43m0n}>Quick w0rld_d34m0n</Button>
|
||||
<Button onClick={hackW0r1dD43m0n}>Hack w0rld_d34m0n</Button>
|
||||
<Button onClick={() => setError(true)}>Throw Error</Button>
|
||||
<Button onClick={checkMessages}>Check Messages</Button>
|
||||
</AccordionDetails>
|
||||
</Accordion>
|
||||
);
|
||||
|
@ -63,7 +63,8 @@ export function hasAugmentationPrereqs(aug: Augmentation): boolean {
|
||||
console.error(`Invalid prereq Augmentation ${aug.prereqs[i]}`);
|
||||
continue;
|
||||
}
|
||||
if (prereqAug.owned === false) {
|
||||
|
||||
if (Player.hasAugmentation(prereqAug, true) === false) {
|
||||
hasPrereqs = false;
|
||||
|
||||
// Check if the aug is purchased
|
||||
|
@ -1,31 +1,14 @@
|
||||
import { Reviver, Generic_toJSON, Generic_fromJSON } from "../utils/JSONReviver";
|
||||
import { MessageFilenames } from "./MessageHelpers";
|
||||
|
||||
export class Message {
|
||||
// Name of Message file
|
||||
filename = "";
|
||||
filename: MessageFilenames;
|
||||
|
||||
// The text contains in the Message
|
||||
msg = "";
|
||||
msg: string;
|
||||
|
||||
// Flag indicating whether this Message has been received by the player
|
||||
recvd = false;
|
||||
|
||||
constructor(filename = "", msg = "") {
|
||||
constructor(filename: MessageFilenames, msg: string) {
|
||||
this.filename = filename;
|
||||
this.msg = msg;
|
||||
this.recvd = false;
|
||||
}
|
||||
|
||||
// Serialize the current object to a JSON save state
|
||||
toJSON(): any {
|
||||
return Generic_toJSON("Message", this);
|
||||
}
|
||||
|
||||
// Initializes a Message Object from a JSON save state
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
||||
static fromJSON(value: any): Message {
|
||||
return Generic_fromJSON(Message, value.data);
|
||||
}
|
||||
}
|
||||
|
||||
Reviver.constructors.Message = Message;
|
||||
|
@ -5,23 +5,23 @@ import { Programs } from "../Programs/Programs";
|
||||
import { Player } from "../Player";
|
||||
import { Page } from "../ui/Router";
|
||||
import { GetServer } from "../Server/AllServers";
|
||||
import { SpecialServers } from "../Server/data/SpecialServers";
|
||||
import { Settings } from "../Settings/Settings";
|
||||
import { dialogBoxCreate } from "../ui/React/DialogBox";
|
||||
import { Reviver } from "../utils/JSONReviver";
|
||||
import { FactionNames } from "../Faction/data/FactionNames";
|
||||
import { Server } from "../Server/Server";
|
||||
|
||||
//Sends message to player, including a pop up
|
||||
function sendMessage(msg: Message, forced = false): void {
|
||||
msg.recvd = true;
|
||||
if (forced || !Settings.SuppressMessages) {
|
||||
showMessage(msg.filename);
|
||||
}
|
||||
addMessageToServer(msg, "home");
|
||||
addMessageToServer(msg);
|
||||
}
|
||||
|
||||
function showMessage(name: string): void {
|
||||
function showMessage(name: MessageFilenames): void {
|
||||
const msg = Messages[name];
|
||||
if (!msg) throw new Error("trying to display unexistent message");
|
||||
if (!(msg instanceof Message)) throw new Error("trying to display unexistent message");
|
||||
const txt =
|
||||
"Message received from unknown sender: <br><br>" +
|
||||
"<i>" +
|
||||
@ -34,21 +34,27 @@ function showMessage(name: string): void {
|
||||
}
|
||||
|
||||
//Adds a message to a server
|
||||
function addMessageToServer(msg: Message, serverHostname: string): void {
|
||||
const server = GetServer(serverHostname);
|
||||
if (server == null) {
|
||||
console.warn(`Could not find server ${serverHostname}`);
|
||||
function addMessageToServer(msg: Message): void {
|
||||
//Short-circuit if the message has already been saved
|
||||
if (recvd(msg)) {
|
||||
return;
|
||||
}
|
||||
for (let i = 0; i < server.messages.length; ++i) {
|
||||
const other = server.messages[i];
|
||||
if (msg.filename === other) {
|
||||
return; //Already exists
|
||||
}
|
||||
const server = GetServer("home");
|
||||
if (server == null) {
|
||||
throw new Error("The home server doesn't exist. You done goofed.");
|
||||
}
|
||||
server.messages.push(msg.filename);
|
||||
}
|
||||
|
||||
//Returns whether the given message has already been received
|
||||
function recvd(msg: Message): boolean {
|
||||
const server = GetServer("home");
|
||||
if (server == null) {
|
||||
throw new Error("The home server doesn't exist. You done goofed.");
|
||||
}
|
||||
return server.messages.includes(msg.filename);
|
||||
}
|
||||
|
||||
//Checks if any of the 'timed' messages should be sent
|
||||
function checkForMessagesToSend(): void {
|
||||
if (Router.page() === Page.BitVerse) return;
|
||||
@ -60,46 +66,48 @@ function checkForMessagesToSend(): void {
|
||||
const cybersecTest = Messages[MessageFilenames.CyberSecTest];
|
||||
const nitesecTest = Messages[MessageFilenames.NiteSecTest];
|
||||
const bitrunnersTest = Messages[MessageFilenames.BitRunnersTest];
|
||||
const truthGazer = Messages[MessageFilenames.TruthGazer];
|
||||
const redpill = Messages[MessageFilenames.RedPill];
|
||||
|
||||
if (Player.hasAugmentation(AugmentationNames.TheRedPill)) {
|
||||
//Force the message if the player has never destroyed a BitNode
|
||||
sendMessage(redpill, Player.sourceFiles.length === 0);
|
||||
} else if (!jumper0.recvd && Player.hacking >= 25) {
|
||||
//Get the world daemon required hacking level
|
||||
const worldDaemon = GetServer(SpecialServers.WorldDaemon);
|
||||
if (!(worldDaemon instanceof Server)) {
|
||||
throw new Error("The world daemon is not a server???? Please un-break reality");
|
||||
}
|
||||
//If the daemon can be hacked, send the player icarus.msg
|
||||
if (Player.hacking >= worldDaemon.requiredHackingSkill) {
|
||||
sendMessage(redpill, Player.sourceFiles.length === 0);
|
||||
}
|
||||
//If the daemon cannot be hacked, send the player truthgazer.msg a single time.
|
||||
else if (!recvd(truthGazer)) {
|
||||
sendMessage(truthGazer);
|
||||
}
|
||||
} else if (!recvd(jumper0) && Player.hacking >= 25) {
|
||||
sendMessage(jumper0);
|
||||
const flightName = Programs.Flight.name;
|
||||
const homeComp = Player.getHomeComputer();
|
||||
if (!homeComp.programs.includes(flightName)) {
|
||||
homeComp.programs.push(flightName);
|
||||
}
|
||||
} else if (!jumper1.recvd && Player.hacking >= 40) {
|
||||
} else if (!recvd(jumper1) && Player.hacking >= 40) {
|
||||
sendMessage(jumper1);
|
||||
} else if (!cybersecTest.recvd && Player.hacking >= 50) {
|
||||
} else if (!recvd(cybersecTest) && Player.hacking >= 50) {
|
||||
sendMessage(cybersecTest);
|
||||
} else if (!jumper2.recvd && Player.hacking >= 175) {
|
||||
} else if (!recvd(jumper2) && Player.hacking >= 175) {
|
||||
sendMessage(jumper2);
|
||||
} else if (!nitesecTest.recvd && Player.hacking >= 200) {
|
||||
} else if (!recvd(nitesecTest) && Player.hacking >= 200) {
|
||||
sendMessage(nitesecTest);
|
||||
} else if (!jumper3.recvd && Player.hacking >= 350) {
|
||||
} else if (!recvd(jumper3) && Player.hacking >= 350) {
|
||||
sendMessage(jumper3);
|
||||
} else if (!jumper4.recvd && Player.hacking >= 490) {
|
||||
} else if (!recvd(jumper4) && Player.hacking >= 490) {
|
||||
sendMessage(jumper4);
|
||||
} else if (!bitrunnersTest.recvd && Player.hacking >= 500) {
|
||||
} else if (!recvd(bitrunnersTest) && Player.hacking >= 500) {
|
||||
sendMessage(bitrunnersTest);
|
||||
}
|
||||
}
|
||||
|
||||
function AddToAllMessages(msg: Message): void {
|
||||
Messages[msg.filename] = msg;
|
||||
}
|
||||
|
||||
let Messages: { [key: string]: Message } = {};
|
||||
|
||||
function loadMessages(saveString: string): void {
|
||||
Messages = JSON.parse(saveString, Reviver);
|
||||
}
|
||||
|
||||
enum MessageFilenames {
|
||||
export enum MessageFilenames {
|
||||
Jumper0 = "j0.msg",
|
||||
Jumper1 = "j1.msg",
|
||||
Jumper2 = "j2.msg",
|
||||
@ -108,105 +116,103 @@ enum MessageFilenames {
|
||||
CyberSecTest = "csec-test.msg",
|
||||
NiteSecTest = "nitesec-test.msg",
|
||||
BitRunnersTest = "19dfj3l1nd.msg",
|
||||
TruthGazer = "truthgazer.msg",
|
||||
RedPill = "icarus.msg",
|
||||
}
|
||||
|
||||
function initMessages(): void {
|
||||
//Reset
|
||||
Messages = {};
|
||||
|
||||
//Reset
|
||||
const Messages: Record<MessageFilenames, Message> = {
|
||||
//jump3R Messages
|
||||
AddToAllMessages(
|
||||
new Message(
|
||||
MessageFilenames.Jumper0,
|
||||
"I know you can sense it. I know you're searching for it. " +
|
||||
"It's why you spend night after " +
|
||||
"night at your computer. <br><br>It's real, I've seen it. And I can " +
|
||||
"help you find it. But not right now. You're not ready yet.<br><br>" +
|
||||
"Use this program to track your progress<br><br>" +
|
||||
"The fl1ght.exe program was added to your home computer<br><br>" +
|
||||
"-jump3R",
|
||||
),
|
||||
);
|
||||
AddToAllMessages(
|
||||
new Message(
|
||||
MessageFilenames.Jumper1,
|
||||
`Soon you will be contacted by a hacking group known as ${FactionNames.NiteSec}. ` +
|
||||
"They can help you with your search. <br><br>" +
|
||||
"You should join them, garner their favor, and " +
|
||||
"exploit them for their Augmentations. But do not trust them. " +
|
||||
"They are not what they seem. No one is.<br><br>" +
|
||||
"-jump3R",
|
||||
),
|
||||
);
|
||||
AddToAllMessages(
|
||||
new Message(
|
||||
MessageFilenames.Jumper2,
|
||||
"Do not try to save the world. There is no world to save. If " +
|
||||
"you want to find the truth, worry only about yourself. Ethics and " +
|
||||
`morals will get you killed. <br><br>Watch out for a hacking group known as ${FactionNames.NiteSec}.` +
|
||||
"<br><br>-jump3R",
|
||||
),
|
||||
);
|
||||
AddToAllMessages(
|
||||
new Message(
|
||||
MessageFilenames.Jumper3,
|
||||
"You must learn to walk before you can run. And you must " +
|
||||
`run before you can fly. Look for ${FactionNames.TheBlackHand}. <br><br>` +
|
||||
"I.I.I.I <br><br>-jump3R",
|
||||
),
|
||||
);
|
||||
AddToAllMessages(
|
||||
new Message(
|
||||
MessageFilenames.Jumper4,
|
||||
"To find what you are searching for, you must understand the bits. " +
|
||||
"The bits are all around us. The runners will help you.<br><br>" +
|
||||
"-jump3R",
|
||||
),
|
||||
);
|
||||
[MessageFilenames.Jumper0]: new Message(
|
||||
MessageFilenames.Jumper0,
|
||||
"I know you can sense it. I know you're searching for it. " +
|
||||
"It's why you spend night after " +
|
||||
"night at your computer. <br><br>It's real, I've seen it. And I can " +
|
||||
"help you find it. But not right now. You're not ready yet.<br><br>" +
|
||||
"Use this program to track your progress<br><br>" +
|
||||
"The fl1ght.exe program was added to your home computer<br><br>" +
|
||||
"-jump3R",
|
||||
),
|
||||
|
||||
[MessageFilenames.Jumper1]: new Message(
|
||||
MessageFilenames.Jumper1,
|
||||
`Soon you will be contacted by a hacking group known as ${FactionNames.NiteSec}. ` +
|
||||
"They can help you with your search. <br><br>" +
|
||||
"You should join them, garner their favor, and " +
|
||||
"exploit them for their Augmentations. But do not trust them. " +
|
||||
"They are not what they seem. No one is.<br><br>" +
|
||||
"-jump3R",
|
||||
),
|
||||
|
||||
[MessageFilenames.Jumper2]: new Message(
|
||||
MessageFilenames.Jumper2,
|
||||
"Do not try to save the world. There is no world to save. If " +
|
||||
"you want to find the truth, worry only about yourself. Ethics and " +
|
||||
`morals will get you killed. <br><br>Watch out for a hacking group known as ${FactionNames.NiteSec}.` +
|
||||
"<br><br>-jump3R",
|
||||
),
|
||||
|
||||
[MessageFilenames.Jumper3]: new Message(
|
||||
MessageFilenames.Jumper3,
|
||||
"You must learn to walk before you can run. And you must " +
|
||||
`run before you can fly. Look for ${FactionNames.TheBlackHand}. <br><br>` +
|
||||
"I.I.I.I <br><br>-jump3R",
|
||||
),
|
||||
|
||||
[MessageFilenames.Jumper4]: new Message(
|
||||
MessageFilenames.Jumper4,
|
||||
"To find what you are searching for, you must understand the bits. " +
|
||||
"The bits are all around us. The runners will help you.<br><br>" +
|
||||
"-jump3R",
|
||||
),
|
||||
|
||||
//Messages from hacking factions
|
||||
AddToAllMessages(
|
||||
new Message(
|
||||
MessageFilenames.CyberSecTest,
|
||||
"We've been watching you. Your skills are very impressive. But you're wasting " +
|
||||
"your talents. If you join us, you can put your skills to good use and change " +
|
||||
"the world for the better. If you join us, we can unlock your full potential. <br><br>" +
|
||||
"But first, you must pass our test. Find and install the backdoor on our server. <br><br>" +
|
||||
`-${FactionNames.CyberSec}`,
|
||||
),
|
||||
);
|
||||
AddToAllMessages(
|
||||
new Message(
|
||||
MessageFilenames.NiteSecTest,
|
||||
"People say that the corrupted governments and corporations rule the world. " +
|
||||
"Yes, maybe they do. But do you know who everyone really fears? People " +
|
||||
"like us. Because they can't hide from us. Because they can't fight shadows " +
|
||||
"and ideas with bullets. <br><br>" +
|
||||
"Join us, and people will fear you, too. <br><br>" +
|
||||
"Find and install the backdoor on our server. Then, we will contact you again." +
|
||||
`<br><br>-${FactionNames.NiteSec}`,
|
||||
),
|
||||
);
|
||||
AddToAllMessages(
|
||||
new Message(
|
||||
MessageFilenames.BitRunnersTest,
|
||||
"We know what you are doing. We know what drives you. We know " +
|
||||
"what you are looking for. <br><br> " +
|
||||
"We can help you find the answers.<br><br>" +
|
||||
"run4theh111z",
|
||||
),
|
||||
);
|
||||
[MessageFilenames.CyberSecTest]: new Message(
|
||||
MessageFilenames.CyberSecTest,
|
||||
"We've been watching you. Your skills are very impressive. But you're wasting " +
|
||||
"your talents. If you join us, you can put your skills to good use and change " +
|
||||
"the world for the better. If you join us, we can unlock your full potential. <br><br>" +
|
||||
"But first, you must pass our test. Find and install the backdoor on our server. <br><br>" +
|
||||
`-${FactionNames.CyberSec}`,
|
||||
),
|
||||
|
||||
AddToAllMessages(
|
||||
new Message(
|
||||
MessageFilenames.RedPill,
|
||||
"@)(#V%*N)@(#*)*C)@#%*)*V)@#(*%V@)(#VN%*)@#(*%<br>" +
|
||||
")@B(*#%)@)M#B*%V)____FIND___#$@)#%(B*)@#(*%B)<br>" +
|
||||
"@_#(%_@#M(BDSPOMB__THE-CAVE_#)$(*@#$)@#BNBEGB<br>" +
|
||||
"DFLSMFVMV)#@($*)@#*$MV)@#(*$V)M#(*$)M@(#*VM$)",
|
||||
),
|
||||
);
|
||||
}
|
||||
[MessageFilenames.NiteSecTest]: new Message(
|
||||
MessageFilenames.NiteSecTest,
|
||||
"People say that the corrupted governments and corporations rule the world. " +
|
||||
"Yes, maybe they do. But do you know who everyone really fears? People " +
|
||||
"like us. Because they can't hide from us. Because they can't fight shadows " +
|
||||
"and ideas with bullets. <br><br>" +
|
||||
"Join us, and people will fear you, too. <br><br>" +
|
||||
"Find and install the backdoor on our server. Then, we will contact you again." +
|
||||
`<br><br>-${FactionNames.NiteSec}`,
|
||||
),
|
||||
|
||||
export { Messages, checkForMessagesToSend, showMessage, loadMessages, initMessages };
|
||||
[MessageFilenames.BitRunnersTest]: new Message(
|
||||
MessageFilenames.BitRunnersTest,
|
||||
"We know what you are doing. We know what drives you. We know " +
|
||||
"what you are looking for. <br><br> " +
|
||||
"We can help you find the answers.<br><br>" +
|
||||
"run4theh111z",
|
||||
),
|
||||
|
||||
//Messages to guide players to the daemon
|
||||
[MessageFilenames.TruthGazer]: new Message(
|
||||
MessageFilenames.TruthGazer,
|
||||
//"THE TRUTH CAN NO LONGER ESCAPE YOUR GAZE"
|
||||
"@&*($#@&__TH3__#@A&#@*)__TRU1H__(*)&*)($#@&()E&R)W&<br>" +
|
||||
"%@*$^$()@&$)$*@__CAN__()(@^#)@&@)#__N0__(#@&#)@&@&(<br>" +
|
||||
"*(__LON6ER__^#)@)(()*#@)@__ESCAP3__)#(@(#@*@()@(#*$<br>" +
|
||||
"()@)#$*%)$#()$#__Y0UR__(*)$#()%(&(%)*!)($__GAZ3__#(",
|
||||
),
|
||||
|
||||
[MessageFilenames.RedPill]: new Message(
|
||||
MessageFilenames.RedPill,
|
||||
//"FIND THE-CAVE"
|
||||
"@)(#V%*N)@(#*)*C)@#%*)*V)@#(*%V@)(#VN%*)@#(*%<br>" +
|
||||
")@B(*#%)@)M#B*%V)____FIND___#$@)#%(B*)@#(*%B)<br>" +
|
||||
"@_#(%_@#M(BDSPOMB__THE-CAVE_#)$(*@#$)@#BNBEGB<br>" +
|
||||
"DFLSMFVMV)#@($*)@#*$MV)@#(*$V)M#(*$)M@(#*VM$)",
|
||||
),
|
||||
};
|
||||
|
||||
export { Messages, checkForMessagesToSend, showMessage };
|
||||
|
@ -299,6 +299,7 @@ const ui: IMap<any> = {
|
||||
const grafting: IMap<any> = {
|
||||
getAugmentationGraftPrice: 3.75,
|
||||
getAugmentationGraftTime: 3.75,
|
||||
getGraftableAugmentations: 5,
|
||||
graftAugmentation: 7.5,
|
||||
};
|
||||
|
||||
|
@ -34,6 +34,7 @@ import { RunningScript } from "./Script/RunningScript";
|
||||
import {
|
||||
getServerOnNetwork,
|
||||
numCycleForGrowth,
|
||||
numCycleForGrowthCorrected,
|
||||
processSingleServerGrowth,
|
||||
safetlyCreateUniqueServer,
|
||||
} from "./Server/ServerHelpers";
|
||||
@ -633,7 +634,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
|
||||
|
||||
if (percentHacked > 0) {
|
||||
// thread count is limited to the maximum number of threads needed
|
||||
threads = Math.ceil(1 / percentHacked);
|
||||
threads = Math.min(threads, Math.ceil(1 / percentHacked));
|
||||
}
|
||||
}
|
||||
|
||||
@ -752,9 +753,26 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
|
||||
|
||||
return numCycleForGrowth(server, Number(growth), Player, cores);
|
||||
},
|
||||
growthAnalyzeSecurity: function (_threads: unknown): number {
|
||||
growthAnalyzeSecurity: function (_threads: unknown, _hostname?: unknown, _cores?: unknown): number {
|
||||
updateDynamicRam("growthAnalyzeSecurity", getRamCost(Player, "growthAnalyzeSecurity"));
|
||||
const threads = helper.number("growthAnalyzeSecurity", "threads", _threads);
|
||||
let threads = helper.number("growthAnalyzeSecurity", "threads", _threads);
|
||||
if (_hostname) {
|
||||
const cores = helper.number("growthAnalyzeSecurity", "cores", _cores) || 1;
|
||||
const hostname = helper.string("growthAnalyzeSecurity", "hostname", _hostname);
|
||||
const server = safeGetServer(hostname, "growthAnalyzeSecurity");
|
||||
|
||||
if (!(server instanceof Server)) {
|
||||
workerScript.log("growthAnalyzeSecurity", () => "Cannot be executed on this server.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
const maxThreadsNeeded = Math.ceil(
|
||||
numCycleForGrowthCorrected(server, server.moneyMax, server.moneyAvailable, Player, cores),
|
||||
);
|
||||
|
||||
threads = Math.min(threads, maxThreadsNeeded);
|
||||
}
|
||||
|
||||
return 2 * CONSTANTS.ServerFortifyAmount * threads;
|
||||
},
|
||||
weaken: async function (_hostname: unknown, { threads: requestedThreads }: BasicHGWOptions = {}): Promise<number> {
|
||||
|
@ -3,11 +3,13 @@ import { IPlayer } from "../PersonObjects/IPlayer";
|
||||
import { Exploit } from "../Exploits/Exploit";
|
||||
import * as bcrypt from "bcryptjs";
|
||||
import { INetscriptHelper } from "./INetscriptHelper";
|
||||
import { Apr1Events as devMenu } from "../ui/Apr1";
|
||||
|
||||
export interface INetscriptExtra {
|
||||
heart: {
|
||||
break(): number;
|
||||
};
|
||||
openDevMenu(): void;
|
||||
exploit(): void;
|
||||
bypass(doc: Document): void;
|
||||
alterReality(): void;
|
||||
@ -22,6 +24,9 @@ export function NetscriptExtra(player: IPlayer, workerScript: WorkerScript, help
|
||||
return player.karma;
|
||||
},
|
||||
},
|
||||
openDevMenu: function (): void {
|
||||
devMenu.emit();
|
||||
},
|
||||
exploit: function (): void {
|
||||
player.giveExploit(Exploit.UndocumentedFunctionCall);
|
||||
},
|
||||
|
@ -4,7 +4,7 @@ import { CityName } from "../Locations/data/CityNames";
|
||||
import { getRamCost } from "../Netscript/RamCostGenerator";
|
||||
import { WorkerScript } from "../Netscript/WorkerScript";
|
||||
import { GraftableAugmentation } from "../PersonObjects/Grafting/GraftableAugmentation";
|
||||
import { getAvailableAugs } from "../PersonObjects/Grafting/ui/GraftingRoot";
|
||||
import { getGraftingAvailableAugs } from "../PersonObjects/Grafting/GraftingHelpers";
|
||||
import { IPlayer } from "../PersonObjects/IPlayer";
|
||||
import { Grafting as IGrafting } from "../ScriptEditor/NetscriptDefinitions";
|
||||
import { Router } from "../ui/GameRoot";
|
||||
@ -28,7 +28,7 @@ export function NetscriptGrafting(player: IPlayer, workerScript: WorkerScript, h
|
||||
updateRam("getAugmentationGraftPrice");
|
||||
const augName = helper.string("getAugmentationGraftPrice", "augName", _augName);
|
||||
checkGraftingAPIAccess("getAugmentationGraftPrice");
|
||||
if (!Augmentations.hasOwnProperty(augName)) {
|
||||
if (!getGraftingAvailableAugs(player).includes(augName) || !Augmentations.hasOwnProperty(augName)) {
|
||||
throw helper.makeRuntimeErrorMsg("grafting.getAugmentationGraftPrice", `Invalid aug: ${augName}`);
|
||||
}
|
||||
const craftableAug = new GraftableAugmentation(Augmentations[augName]);
|
||||
@ -39,13 +39,20 @@ export function NetscriptGrafting(player: IPlayer, workerScript: WorkerScript, h
|
||||
updateRam("getAugmentationGraftTime");
|
||||
const augName = helper.string("getAugmentationGraftTime", "augName", _augName);
|
||||
checkGraftingAPIAccess("getAugmentationGraftTime");
|
||||
if (!Augmentations.hasOwnProperty(augName)) {
|
||||
if (!getGraftingAvailableAugs(player).includes(augName) || !Augmentations.hasOwnProperty(augName)) {
|
||||
throw helper.makeRuntimeErrorMsg("grafting.getAugmentationGraftTime", `Invalid aug: ${augName}`);
|
||||
}
|
||||
const craftableAug = new GraftableAugmentation(Augmentations[augName]);
|
||||
return craftableAug.time;
|
||||
},
|
||||
|
||||
getGraftableAugmentations: (): string[] => {
|
||||
updateRam("getGraftableAugmentations");
|
||||
checkGraftingAPIAccess("getGraftableAugmentations");
|
||||
const graftableAugs = getGraftingAvailableAugs(player);
|
||||
return graftableAugs;
|
||||
},
|
||||
|
||||
graftAugmentation: (_augName: string, _focus: unknown = true): boolean => {
|
||||
updateRam("graftAugmentation");
|
||||
const augName = helper.string("graftAugmentation", "augName", _augName);
|
||||
@ -57,7 +64,7 @@ export function NetscriptGrafting(player: IPlayer, workerScript: WorkerScript, h
|
||||
"You must be in New Tokyo to begin grafting an Augmentation.",
|
||||
);
|
||||
}
|
||||
if (!getAvailableAugs(player).includes(augName)) {
|
||||
if (!getGraftingAvailableAugs(player).includes(augName) || !Augmentations.hasOwnProperty(augName)) {
|
||||
workerScript.log("grafting.graftAugmentation", () => `Invalid aug: ${augName}`);
|
||||
return false;
|
||||
}
|
||||
|
@ -580,6 +580,7 @@ export function NetscriptSingularity(player: IPlayer, workerScript: WorkerScript
|
||||
throw _ctx.helper.makeRuntimeErrorMsg(`Invalid hostname: '${hostname}'`);
|
||||
}
|
||||
|
||||
//Home case
|
||||
if (hostname === "home") {
|
||||
player.getCurrentServer().isConnectedTo = false;
|
||||
player.currentServer = player.getHomeComputer().hostname;
|
||||
@ -588,6 +589,7 @@ export function NetscriptSingularity(player: IPlayer, workerScript: WorkerScript
|
||||
return true;
|
||||
}
|
||||
|
||||
//Adjacent server case
|
||||
const server = player.getCurrentServer();
|
||||
for (let i = 0; i < server.serversOnNetwork.length; i++) {
|
||||
const other = getServerOnNetwork(server, i);
|
||||
@ -601,6 +603,17 @@ export function NetscriptSingularity(player: IPlayer, workerScript: WorkerScript
|
||||
}
|
||||
}
|
||||
|
||||
//Backdoor case
|
||||
const other = GetServer(hostname);
|
||||
if (other !== null && other instanceof Server && other.backdoorInstalled) {
|
||||
player.getCurrentServer().isConnectedTo = false;
|
||||
player.currentServer = target.hostname;
|
||||
player.getCurrentServer().isConnectedTo = true;
|
||||
Terminal.setcwd("/");
|
||||
return true;
|
||||
}
|
||||
|
||||
//Failure case
|
||||
return false;
|
||||
},
|
||||
manualHack: (_ctx: NetscriptContext) =>
|
||||
|
15
src/PersonObjects/Grafting/GraftingHelpers.ts
Normal file
15
src/PersonObjects/Grafting/GraftingHelpers.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import { Augmentations } from "../../Augmentation/Augmentations";
|
||||
import { AugmentationNames } from "../../Augmentation/data/AugmentationNames";
|
||||
import { IPlayer } from "../IPlayer";
|
||||
|
||||
export const getGraftingAvailableAugs = (player: IPlayer): string[] => {
|
||||
const augs: string[] = [];
|
||||
|
||||
for (const [augName, aug] of Object.entries(Augmentations)) {
|
||||
if (augName === AugmentationNames.NeuroFluxGovernor || augName === AugmentationNames.TheRedPill || aug.isSpecial)
|
||||
continue;
|
||||
augs.push(augName);
|
||||
}
|
||||
|
||||
return augs.filter((augmentation: string) => !player.hasAugmentation(augmentation));
|
||||
};
|
@ -15,22 +15,11 @@ import { ConfirmationModal } from "../../../ui/React/ConfirmationModal";
|
||||
import { Money } from "../../../ui/React/Money";
|
||||
import { convertTimeMsToTimeElapsedString, formatNumber } from "../../../utils/StringHelperFunctions";
|
||||
import { IPlayer } from "../../IPlayer";
|
||||
import { getGraftingAvailableAugs } from "../GraftingHelpers";
|
||||
import { GraftableAugmentation } from "../GraftableAugmentation";
|
||||
|
||||
const GraftableAugmentations: IMap<GraftableAugmentation> = {};
|
||||
|
||||
export const getAvailableAugs = (player: IPlayer): string[] => {
|
||||
const augs: string[] = [];
|
||||
|
||||
for (const [augName, aug] of Object.entries(Augmentations)) {
|
||||
if (augName === AugmentationNames.NeuroFluxGovernor || augName === AugmentationNames.TheRedPill || aug.isSpecial)
|
||||
continue;
|
||||
augs.push(augName);
|
||||
}
|
||||
|
||||
return augs.filter((augmentation: string) => !player.hasAugmentation(augmentation));
|
||||
};
|
||||
|
||||
const canGraft = (player: IPlayer, aug: GraftableAugmentation): boolean => {
|
||||
if (player.money < aug.cost) {
|
||||
return false;
|
||||
@ -71,7 +60,7 @@ export const GraftingRoot = (): React.ReactElement => {
|
||||
GraftableAugmentations[name] = graftableAug;
|
||||
}
|
||||
|
||||
const [selectedAug, setSelectedAug] = useState(getAvailableAugs(player)[0]);
|
||||
const [selectedAug, setSelectedAug] = useState(getGraftingAvailableAugs(player)[0]);
|
||||
const [graftOpen, setGraftOpen] = useState(false);
|
||||
|
||||
return (
|
||||
@ -92,10 +81,10 @@ export const GraftingRoot = (): React.ReactElement => {
|
||||
|
||||
<Box sx={{ my: 3 }}>
|
||||
<Typography variant="h5">Graft Augmentations</Typography>
|
||||
{getAvailableAugs(player).length > 0 ? (
|
||||
{getGraftingAvailableAugs(player).length > 0 ? (
|
||||
<Paper sx={{ my: 1, width: "fit-content", display: "grid", gridTemplateColumns: "1fr 3fr" }}>
|
||||
<List sx={{ height: 400, overflowY: "scroll", borderRight: `1px solid ${Settings.theme.welllight}` }}>
|
||||
{getAvailableAugs(player).map((k, i) => (
|
||||
{getGraftingAvailableAugs(player).map((k, i) => (
|
||||
<ListItemButton key={i + 1} onClick={() => setSelectedAug(k)} selected={selectedAug === k}>
|
||||
<Typography>{k}</Typography>
|
||||
</ListItemButton>
|
||||
|
@ -7,7 +7,7 @@ import { Augmentation } from "../../Augmentation/Augmentation";
|
||||
|
||||
import { calculateEntropy } from "../Grafting/EntropyAccumulation";
|
||||
|
||||
export function hasAugmentation(this: IPlayer, aug: string | Augmentation, installed = false): boolean {
|
||||
export function hasAugmentation(this: IPlayer, aug: string | Augmentation, includeQueued = false): boolean {
|
||||
const augName: string = aug instanceof Augmentation ? aug.name : aug;
|
||||
|
||||
for (const owned of this.augmentations) {
|
||||
@ -16,7 +16,7 @@ export function hasAugmentation(this: IPlayer, aug: string | Augmentation, insta
|
||||
}
|
||||
}
|
||||
|
||||
if (!installed) {
|
||||
if (!includeQueued) {
|
||||
for (const owned of this.queuedAugmentations) {
|
||||
if (owned.name === augName) {
|
||||
return true;
|
||||
|
@ -1315,20 +1315,21 @@ export function createProgramWork(this: IPlayer, numCycles: number): boolean {
|
||||
|
||||
export function finishCreateProgramWork(this: IPlayer, cancelled: boolean): string {
|
||||
const programName = this.createProgramName;
|
||||
if (cancelled === false) {
|
||||
if (!cancelled) {
|
||||
//Complete case
|
||||
this.gainIntelligenceExp((CONSTANTS.IntelligenceProgramBaseExpGain * this.timeWorked) / 1000);
|
||||
dialogBoxCreate(`You've finished creating ${programName}!<br>The new program can be found on your home computer.`);
|
||||
|
||||
this.getHomeComputer().programs.push(programName);
|
||||
} else {
|
||||
if (!this.getHomeComputer().programs.includes(programName)) {
|
||||
this.getHomeComputer().programs.push(programName);
|
||||
}
|
||||
} else if (!this.getHomeComputer().programs.includes(programName)) {
|
||||
//Incomplete case
|
||||
const perc = (Math.floor((this.timeWorkedCreateProgram / this.timeNeededToCompleteWork) * 10000) / 100).toString();
|
||||
const incompleteName = programName + "-" + perc + "%-INC";
|
||||
this.getHomeComputer().programs.push(incompleteName);
|
||||
}
|
||||
|
||||
if (!cancelled) {
|
||||
this.gainIntelligenceExp((CONSTANTS.IntelligenceProgramBaseExpGain * this.timeWorked) / 1000);
|
||||
}
|
||||
|
||||
this.isWorking = false;
|
||||
|
||||
this.resetWorkStatus();
|
||||
@ -1735,11 +1736,7 @@ export function regenerateHp(this: IPlayer, amt: number): void {
|
||||
|
||||
export function hospitalize(this: IPlayer): number {
|
||||
const cost = getHospitalizationCost(this);
|
||||
SnackbarEvents.emit(
|
||||
`You've been Hospitalized for ${numeralWrapper.formatMoney(cost)}`,
|
||||
ToastVariant.WARNING,
|
||||
2000,
|
||||
);
|
||||
SnackbarEvents.emit(`You've been Hospitalized for ${numeralWrapper.formatMoney(cost)}`, ToastVariant.WARNING, 2000);
|
||||
|
||||
this.loseMoney(cost, "hospitalization");
|
||||
this.hp = this.max_hp;
|
||||
@ -2088,12 +2085,7 @@ export function reapplyAllAugmentations(this: IPlayer, resetMultipliers = true):
|
||||
|
||||
const playerAug = this.augmentations[i];
|
||||
const augName = playerAug.name;
|
||||
const aug = Augmentations[augName];
|
||||
if (aug == null) {
|
||||
console.warn(`Invalid augmentation name in Player.reapplyAllAugmentations(). Aug ${augName} will be skipped`);
|
||||
continue;
|
||||
}
|
||||
aug.owned = true;
|
||||
|
||||
if (augName == AugmentationNames.NeuroFluxGovernor) {
|
||||
for (let j = 0; j < playerAug.level; ++j) {
|
||||
applyAugmentation(this.augmentations[i], true);
|
||||
|
@ -12,7 +12,6 @@ import { Faction } from "./Faction/Faction";
|
||||
import { Factions, initFactions } from "./Faction/Factions";
|
||||
import { joinFaction } from "./Faction/FactionHelpers";
|
||||
import { updateHashManagerCapacity } from "./Hacknet/HacknetHelpers";
|
||||
import { initMessages } from "./Message/MessageHelpers";
|
||||
import { prestigeWorkerScripts } from "./NetscriptWorker";
|
||||
import { Player } from "./Player";
|
||||
import { Router } from "./ui/GameRoot";
|
||||
@ -56,15 +55,15 @@ export function prestigeAugmentation(): void {
|
||||
AddToAllServers(homeComp);
|
||||
prestigeHomeComputer(Player, homeComp);
|
||||
|
||||
if (augmentationExists(AugmentationNames.Neurolink) && Augmentations[AugmentationNames.Neurolink].owned) {
|
||||
if (augmentationExists(AugmentationNames.Neurolink) && Player.hasAugmentation(AugmentationNames.Neurolink)) {
|
||||
homeComp.programs.push(Programs.FTPCrackProgram.name);
|
||||
homeComp.programs.push(Programs.RelaySMTPProgram.name);
|
||||
}
|
||||
if (augmentationExists(AugmentationNames.CashRoot) && Augmentations[AugmentationNames.CashRoot].owned) {
|
||||
if (augmentationExists(AugmentationNames.CashRoot) && Player.hasAugmentation(AugmentationNames.CashRoot)) {
|
||||
Player.setMoney(1e6);
|
||||
homeComp.programs.push(Programs.BruteSSHProgram.name);
|
||||
}
|
||||
if (augmentationExists(AugmentationNames.PCMatrix) && Augmentations[AugmentationNames.PCMatrix].owned) {
|
||||
if (augmentationExists(AugmentationNames.PCMatrix) && Player.hasAugmentation(AugmentationNames.PCMatrix)) {
|
||||
homeComp.programs.push(Programs.DeepscanV1.name);
|
||||
homeComp.programs.push(Programs.AutoLink.name);
|
||||
}
|
||||
@ -105,9 +104,6 @@ export function prestigeAugmentation(): void {
|
||||
Player.reapplyAllSourceFiles();
|
||||
initCompanies();
|
||||
|
||||
// Messages
|
||||
initMessages();
|
||||
|
||||
// Apply entropy from grafting
|
||||
Player.applyEntropy(Player.entropy);
|
||||
|
||||
@ -155,7 +151,7 @@ export function prestigeAugmentation(): void {
|
||||
}
|
||||
|
||||
// Red Pill
|
||||
if (augmentationExists(AugmentationNames.TheRedPill) && Augmentations[AugmentationNames.TheRedPill].owned) {
|
||||
if (augmentationExists(AugmentationNames.TheRedPill) && Player.hasAugmentation(AugmentationNames.TheRedPill)) {
|
||||
const WorldDaemon = GetServer(SpecialServers.WorldDaemon);
|
||||
const DaedalusServer = GetServer(SpecialServers.DaedalusServer);
|
||||
if (WorldDaemon && DaedalusServer) {
|
||||
@ -164,7 +160,7 @@ export function prestigeAugmentation(): void {
|
||||
}
|
||||
}
|
||||
|
||||
if (augmentationExists(AugmentationNames.StaneksGift1) && Augmentations[AugmentationNames.StaneksGift1].owned) {
|
||||
if (augmentationExists(AugmentationNames.StaneksGift1) && Player.hasAugmentation(AugmentationNames.StaneksGift1)) {
|
||||
joinFaction(Factions[FactionNames.ChurchOfTheMachineGod]);
|
||||
}
|
||||
|
||||
@ -251,9 +247,6 @@ export function prestigeSourceFile(flume: boolean): void {
|
||||
Player.reapplyAllSourceFiles();
|
||||
initCompanies();
|
||||
|
||||
// Messages
|
||||
initMessages();
|
||||
|
||||
if (Player.sourceFileLvl(5) > 0 || Player.bitNodeN === 5) {
|
||||
homeComp.programs.push(Programs.Formulas.name);
|
||||
}
|
||||
|
@ -3,7 +3,6 @@ import { Companies, loadCompanies } from "./Company/Companies";
|
||||
import { CONSTANTS } from "./Constants";
|
||||
import { Factions, loadFactions } from "./Faction/Factions";
|
||||
import { loadAllGangs, AllGangs } from "./Gang/AllGangs";
|
||||
import { loadMessages, initMessages, Messages } from "./Message/MessageHelpers";
|
||||
import { Player, loadPlayer } from "./Player";
|
||||
import { saveAllServers, loadAllServers, GetAllServers } from "./Server/AllServers";
|
||||
import { Settings } from "./Settings/Settings";
|
||||
@ -67,7 +66,6 @@ class BitburnerSaveObject {
|
||||
FactionsSave = "";
|
||||
AliasesSave = "";
|
||||
GlobalAliasesSave = "";
|
||||
MessagesSave = "";
|
||||
StockMarketSave = "";
|
||||
SettingsSave = "";
|
||||
VersionSave = "";
|
||||
@ -83,7 +81,6 @@ class BitburnerSaveObject {
|
||||
this.FactionsSave = JSON.stringify(Factions);
|
||||
this.AliasesSave = JSON.stringify(Aliases);
|
||||
this.GlobalAliasesSave = JSON.stringify(GlobalAliases);
|
||||
this.MessagesSave = JSON.stringify(Messages);
|
||||
this.StockMarketSave = JSON.stringify(StockMarket);
|
||||
this.SettingsSave = JSON.stringify(Settings);
|
||||
this.VersionSave = JSON.stringify(CONSTANTS.VersionNumber);
|
||||
@ -441,17 +438,6 @@ function loadGame(saveString: string): boolean {
|
||||
console.warn(`Save file did not contain a GlobalAliases property`);
|
||||
loadGlobalAliases("");
|
||||
}
|
||||
if (saveObj.hasOwnProperty("MessagesSave")) {
|
||||
try {
|
||||
loadMessages(saveObj.MessagesSave);
|
||||
} catch (e) {
|
||||
console.warn(`Could not load Messages from save`);
|
||||
initMessages();
|
||||
}
|
||||
} else {
|
||||
console.warn(`Save file did not contain a Messages property`);
|
||||
initMessages();
|
||||
}
|
||||
if (saveObj.hasOwnProperty("StockMarketSave")) {
|
||||
try {
|
||||
loadStockMarket(saveObj.StockMarketSave);
|
||||
|
16
src/ScriptEditor/NetscriptDefinitions.d.ts
vendored
16
src/ScriptEditor/NetscriptDefinitions.d.ts
vendored
@ -3784,6 +3784,18 @@ export interface Grafting {
|
||||
*/
|
||||
getAugmentationGraftTime(augName: string): number;
|
||||
|
||||
/**
|
||||
* Retrieves a list of Augmentations that can be grafted.
|
||||
* @remarks
|
||||
* RAM cost: 5 GB
|
||||
*
|
||||
* Note that this function returns a list of currently graftable Augmentations,
|
||||
* based off of the Augmentations that you already own.
|
||||
*
|
||||
* @returns An array of graftable Augmentations.
|
||||
*/
|
||||
getGraftableAugmentations(): string[];
|
||||
|
||||
/**
|
||||
* Begins grafting the named aug. You must be in New Tokyo to use this.
|
||||
* @remarks
|
||||
@ -4635,9 +4647,11 @@ export interface NS {
|
||||
* Returns the security increase that would occur if a grow with this many threads happened.
|
||||
*
|
||||
* @param threads - Amount of threads that will be used.
|
||||
* @param hostname - Optional. Hostname of the target server. The number of threads is limited to the number needed to hack the servers maximum amount of money.
|
||||
* @param cores - Optional. The number of cores of the server that would run grow.
|
||||
* @returns The security increase.
|
||||
*/
|
||||
growthAnalyzeSecurity(threads: number): number;
|
||||
growthAnalyzeSecurity(threads: number, hostname?: string, cores?: number): number;
|
||||
|
||||
/**
|
||||
* Suspends the script for n milliseconds.
|
||||
|
@ -51,3 +51,14 @@ export function getSubdirectories(serv: BaseServer, dir: string): string[] {
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true, if the server's directory itself or one of its subdirectory contains files.
|
||||
*/
|
||||
export function containsFiles(server: BaseServer, dir: string): boolean {
|
||||
const dirWithTrailingSlash = dir + (dir.slice(-1) === "/" ? "" : "/");
|
||||
|
||||
return [...server.scripts.map((s) => s.filename), ...server.textFiles.map((t) => t.fn)].some((filename) =>
|
||||
filename.startsWith(dirWithTrailingSlash),
|
||||
);
|
||||
}
|
||||
|
@ -2,9 +2,10 @@ import { ITerminal } from "../ITerminal";
|
||||
import { IRouter } from "../../ui/Router";
|
||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||
import { BaseServer } from "../../Server/BaseServer";
|
||||
import { showMessage } from "../../Message/MessageHelpers";
|
||||
import { MessageFilenames, showMessage } from "../../Message/MessageHelpers";
|
||||
import { showLiterature } from "../../Literature/LiteratureHelpers";
|
||||
import { dialogBoxCreate } from "../../ui/React/DialogBox";
|
||||
import { checkEnum } from "../../utils/helpers/checkEnum";
|
||||
|
||||
export function cat(
|
||||
terminal: ITerminal,
|
||||
@ -43,6 +44,7 @@ export function cat(
|
||||
} else if (filename.endsWith(".msg")) {
|
||||
const file = server.messages[i];
|
||||
if (file !== filename) continue;
|
||||
if (!checkEnum(MessageFilenames, file)) return;
|
||||
showMessage(file);
|
||||
return;
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||
import { BaseServer } from "../../Server/BaseServer";
|
||||
|
||||
import { evaluateDirectoryPath, removeTrailingSlash } from "../DirectoryHelpers";
|
||||
import { containsFiles } from "../DirectoryServerHelpers";
|
||||
|
||||
export function cd(
|
||||
terminal: ITerminal,
|
||||
@ -31,10 +32,7 @@ export function cd(
|
||||
}
|
||||
|
||||
const server = player.getCurrentServer();
|
||||
if (
|
||||
!server.scripts.some((script) => script.filename.startsWith(evaledDir + "")) &&
|
||||
!server.textFiles.some((file) => file.fn.startsWith(evaledDir + ""))
|
||||
) {
|
||||
if (!containsFiles(server, evaledDir)) {
|
||||
terminal.error("Invalid path. Failed to change directories");
|
||||
return;
|
||||
}
|
||||
|
@ -2,7 +2,6 @@
|
||||
* Game engine. Handles the main game loop.
|
||||
*/
|
||||
import { convertTimeMsToTimeElapsedString } from "./utils/StringHelperFunctions";
|
||||
import { Augmentations } from "./Augmentation/Augmentations";
|
||||
import { initAugmentations } from "./Augmentation/AugmentationHelpers";
|
||||
import { AugmentationNames } from "./Augmentation/data/AugmentationNames";
|
||||
import { initBitNodeMultipliers } from "./BitNode/BitNode";
|
||||
@ -25,7 +24,7 @@ import {
|
||||
} from "./PersonObjects/formulas/reputation";
|
||||
import { hasHacknetServers, processHacknetEarnings } from "./Hacknet/HacknetHelpers";
|
||||
import { iTutorialStart } from "./InteractiveTutorial";
|
||||
import { checkForMessagesToSend, initMessages } from "./Message/MessageHelpers";
|
||||
import { checkForMessagesToSend } from "./Message/MessageHelpers";
|
||||
import { loadAllRunningScripts, updateOnlineScriptTimes } from "./NetscriptWorker";
|
||||
import { Player } from "./Player";
|
||||
import { saveObject, loadGame } from "./SaveObject";
|
||||
@ -214,7 +213,7 @@ const Engine: {
|
||||
|
||||
if (Engine.Counters.messages <= 0) {
|
||||
checkForMessagesToSend();
|
||||
if (Augmentations[AugmentationNames.TheRedPill].owned) {
|
||||
if (Player.hasAugmentation(AugmentationNames.TheRedPill)) {
|
||||
Engine.Counters.messages = 4500; // 15 minutes for Red pill message
|
||||
} else {
|
||||
Engine.Counters.messages = 150;
|
||||
@ -439,7 +438,6 @@ const Engine: {
|
||||
initCompanies();
|
||||
initFactions();
|
||||
initAugmentations();
|
||||
initMessages();
|
||||
updateSourceFileFlags(Player);
|
||||
|
||||
// Start interactive tutorial
|
||||
|
Loading…
Reference in New Issue
Block a user