mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-12-23 06:32:26 +01:00
Augmentations in mui
This commit is contained in:
parent
5170c0e004
commit
5c6c472b64
@ -12,7 +12,7 @@ import { Generic_fromJSON, Generic_toJSON, Reviver } from "../../utils/JSONReviv
|
||||
|
||||
export interface IConstructorParams {
|
||||
info: string | JSX.Element;
|
||||
stats?: JSX.Element;
|
||||
stats?: JSX.Element | null;
|
||||
isSpecial?: boolean;
|
||||
moneyCost: number;
|
||||
name: string;
|
||||
@ -369,7 +369,7 @@ export class Augmentation {
|
||||
info: string | JSX.Element;
|
||||
|
||||
// Description of the stats, often autogenerated, sometimes manually written.
|
||||
stats: JSX.Element;
|
||||
stats: JSX.Element | null;
|
||||
|
||||
// Any Augmentation not immediately available in BitNode-1 is special (e.g. Bladeburner augs)
|
||||
isSpecial = false;
|
||||
@ -507,8 +507,9 @@ export class Augmentation {
|
||||
this.mults.bladeburner_success_chance_mult = params.bladeburner_success_chance_mult;
|
||||
}
|
||||
|
||||
if (params.stats) this.stats = params.stats;
|
||||
else this.stats = generateStatsDescription(this.mults, params.programs, params.startingMoney);
|
||||
if (params.stats === undefined)
|
||||
this.stats = generateStatsDescription(this.mults, params.programs, params.startingMoney);
|
||||
else this.stats = params.stats;
|
||||
}
|
||||
|
||||
// Adds this Augmentation to the specified Factions
|
||||
|
@ -1555,7 +1555,7 @@ function initAugmentations() {
|
||||
repCost: 2.5e6,
|
||||
moneyCost: 0,
|
||||
info: "It's time to leave the cave.",
|
||||
stats: <></>,
|
||||
stats: null,
|
||||
});
|
||||
RedPill.addToFactions(["Daedalus"]);
|
||||
if (augmentationExists(AugmentationNames.TheRedPill)) {
|
||||
@ -1595,7 +1595,7 @@ function initAugmentations() {
|
||||
"exactly the implant does, but they promise that it will greatly " +
|
||||
"enhance your abilities.",
|
||||
hacking_grow_mult: 3,
|
||||
stats: <></>,
|
||||
stats: null,
|
||||
});
|
||||
HiveMind.addToFactions(["ECorp"]);
|
||||
if (augmentationExists(AugmentationNames.HiveMind)) {
|
||||
|
@ -2,42 +2,34 @@
|
||||
* Root React component for the Augmentations UI page that display all of your
|
||||
* owned and purchased Augmentations and Source-Files.
|
||||
*/
|
||||
import * as React from "react";
|
||||
import React, { useState } from "react";
|
||||
|
||||
import { InstalledAugmentationsAndSourceFiles } from "./InstalledAugmentationsAndSourceFiles";
|
||||
import { InstalledAugmentations } from "./InstalledAugmentations";
|
||||
import { PlayerMultipliers } from "./PlayerMultipliers";
|
||||
import { PurchasedAugmentations } from "./PurchasedAugmentations";
|
||||
import { SourceFiles } from "./SourceFiles";
|
||||
|
||||
import { Player } from "../../Player";
|
||||
import { StdButton } from "../../ui/React/StdButton";
|
||||
import { canGetBonus } from "../../ExportBonus";
|
||||
|
||||
type IProps = {
|
||||
import Typography from "@mui/material/Typography";
|
||||
import Button from "@mui/material/Button";
|
||||
import Tooltip from "@mui/material/Tooltip";
|
||||
|
||||
interface IProps {
|
||||
exportGameFn: () => void;
|
||||
installAugmentationsFn: () => void;
|
||||
};
|
||||
|
||||
type IState = {
|
||||
rerender: boolean;
|
||||
};
|
||||
|
||||
export class AugmentationsRoot extends React.Component<IProps, IState> {
|
||||
constructor(props: IProps) {
|
||||
super(props);
|
||||
this.state = {
|
||||
rerender: false,
|
||||
};
|
||||
this.export = this.export.bind(this);
|
||||
}
|
||||
|
||||
export(): void {
|
||||
this.props.exportGameFn();
|
||||
this.setState({
|
||||
rerender: !this.state.rerender,
|
||||
});
|
||||
export function AugmentationsRoot(props: IProps): React.ReactElement {
|
||||
const setRerender = useState(false)[1];
|
||||
|
||||
function doExport(): void {
|
||||
props.exportGameFn();
|
||||
setRerender((o) => !o);
|
||||
}
|
||||
|
||||
render(): React.ReactNode {
|
||||
function exportBonusStr(): string {
|
||||
if (canGetBonus()) return "(+1 favor to all factions)";
|
||||
return "";
|
||||
@ -45,49 +37,43 @@ export class AugmentationsRoot extends React.Component<IProps, IState> {
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="augmentations-content">
|
||||
<h1>Purchased Augmentations</h1>
|
||||
<p>
|
||||
Below is a list of all Augmentations you have purchased but not yet installed. Click the button below to
|
||||
install them.
|
||||
</p>
|
||||
<p>WARNING: Installing your Augmentations resets most of your progress, including:</p>
|
||||
<Typography variant="h4">Augmentations</Typography>
|
||||
<Typography>
|
||||
Below is a list of all Augmentations you have purchased but not yet installed. Click the button below to install
|
||||
them.
|
||||
</Typography>
|
||||
<Typography>WARNING: Installing your Augmentations resets most of your progress, including:</Typography>
|
||||
<br />
|
||||
<p>- Stats/Skill levels and Experience</p>
|
||||
<p>- Money</p>
|
||||
<p>- Scripts on every computer but your home computer</p>
|
||||
<p>- Purchased servers</p>
|
||||
<p>- Hacknet Nodes</p>
|
||||
<p>- Faction/Company reputation</p>
|
||||
<p>- Stocks</p>
|
||||
<Typography>- Stats/Skill levels and Experience</Typography>
|
||||
<Typography>- Money</Typography>
|
||||
<Typography>- Scripts on every computer but your home computer</Typography>
|
||||
<Typography>- Purchased servers</Typography>
|
||||
<Typography>- Hacknet Nodes</Typography>
|
||||
<Typography>- Faction/Company reputation</Typography>
|
||||
<Typography>- Stocks</Typography>
|
||||
<br />
|
||||
<p>
|
||||
Installing Augmentations lets you start over with the perks and benefits granted by all of the Augmentations
|
||||
you have ever installed. Also, you will keep any scripts and RAM/Core upgrades on your home computer (but
|
||||
you will lose all programs besides NUKE.exe)
|
||||
</p>
|
||||
<StdButton
|
||||
onClick={this.props.installAugmentationsFn}
|
||||
text="Install Augmentations"
|
||||
tooltip="'I never asked for this'"
|
||||
/>
|
||||
<StdButton
|
||||
addClasses="flashing-button"
|
||||
onClick={this.export}
|
||||
text={`Backup Save ${exportBonusStr()}`}
|
||||
tooltip="It's always a good idea to backup/export your save!"
|
||||
/>
|
||||
<Typography>
|
||||
Installing Augmentations lets you start over with the perks and benefits granted by all of the Augmentations you
|
||||
have ever installed. Also, you will keep any scripts and RAM/Core upgrades on your home computer (but you will
|
||||
lose all programs besides NUKE.exe)
|
||||
</Typography>
|
||||
<Tooltip title={"'I never asked for this'"}>
|
||||
<Button onClick={props.installAugmentationsFn}>
|
||||
<Typography>Install Augmentations</Typography>
|
||||
</Button>
|
||||
</Tooltip>
|
||||
<Tooltip title={"It's always a good idea to backup/export your save!"}>
|
||||
<Button sx={{ mx: 2 }} onClick={doExport}>
|
||||
<Typography color="error">Backup Save {exportBonusStr()}</Typography>
|
||||
</Button>
|
||||
</Tooltip>
|
||||
<PurchasedAugmentations />
|
||||
<h1>Installed Augmentations</h1>
|
||||
<p>
|
||||
{`List of all Augmentations ${Player.sourceFiles.length > 0 ? "and Source Files " : ""} ` +
|
||||
`that have been installed. You have gained the effects of these.`}
|
||||
</p>
|
||||
<InstalledAugmentationsAndSourceFiles />
|
||||
<Typography variant="h4">Installed Augmentations</Typography>
|
||||
<Typography>List of all Augmentations that have been installed. You have gained the effects of these.</Typography>
|
||||
<InstalledAugmentations />
|
||||
<br /> <br />
|
||||
<PlayerMultipliers />
|
||||
</div>
|
||||
<SourceFiles />
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,19 +1,31 @@
|
||||
/**
|
||||
* React Component for displaying a list of the player's installed Augmentations
|
||||
* on the Augmentations UI
|
||||
* React Component for displaying all of the player's installed Augmentations and
|
||||
* Source-Files.
|
||||
*
|
||||
* It also contains 'configuration' buttons that allow you to change how the
|
||||
* Augs/SF's are displayed
|
||||
*/
|
||||
import * as React from "react";
|
||||
import React, { useState } from "react";
|
||||
|
||||
import { Player } from "../../Player";
|
||||
import { OwnedSourceFiles } from "./OwnedSourceFiles";
|
||||
import { SourceFileMinus1 } from "./SourceFileMinus1";
|
||||
import { AugmentationAccordion } from "../../ui/React/AugmentationAccordion";
|
||||
import { Augmentations } from "../../Augmentation/Augmentations";
|
||||
import { AugmentationNames } from "../../Augmentation/data/AugmentationNames";
|
||||
import { Settings } from "../../Settings/Settings";
|
||||
import { OwnedAugmentationsOrderSetting } from "../../Settings/SettingEnums";
|
||||
|
||||
import { AugmentationAccordion } from "../../ui/React/AugmentationAccordion";
|
||||
import { Settings } from "../../Settings/Settings";
|
||||
import { use } from "../../ui/Context";
|
||||
import { OwnedAugmentationsOrderSetting } from "../../Settings/SettingEnums";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import Button from "@mui/material/Button";
|
||||
import Tooltip from "@mui/material/Tooltip";
|
||||
import List from "@mui/material/List";
|
||||
|
||||
export function InstalledAugmentations(): React.ReactElement {
|
||||
const sourceAugs = Player.augmentations.slice();
|
||||
const setRerender = useState(true)[1];
|
||||
const player = use.Player();
|
||||
|
||||
const sourceAugs = player.augmentations.slice();
|
||||
|
||||
if (Settings.OwnedAugmentationsOrder === OwnedAugmentationsOrderSetting.Alphabetically) {
|
||||
sourceAugs.sort((aug1, aug2) => {
|
||||
@ -21,7 +33,32 @@ export function InstalledAugmentations(): React.ReactElement {
|
||||
});
|
||||
}
|
||||
|
||||
const augs = sourceAugs.map((e) => {
|
||||
function rerender(): void {
|
||||
setRerender((old) => !old);
|
||||
}
|
||||
|
||||
function sortByAcquirementTime(): void {
|
||||
Settings.OwnedAugmentationsOrder = OwnedAugmentationsOrderSetting.AcquirementTime;
|
||||
rerender();
|
||||
}
|
||||
|
||||
function sortInOrder(): void {
|
||||
Settings.OwnedAugmentationsOrder = OwnedAugmentationsOrderSetting.Alphabetically;
|
||||
rerender();
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Tooltip title={"Sorts the Augmentations alphabetically in numeral order"}>
|
||||
<Button onClick={sortInOrder}>Sort in Order</Button>
|
||||
</Tooltip>
|
||||
<Tooltip title={"Sorts the Augmentations based on when you acquired them (same as default)"}>
|
||||
<Button sx={{ mx: 2 }} onClick={sortByAcquirementTime}>
|
||||
Sort by Acquirement Time
|
||||
</Button>
|
||||
</Tooltip>
|
||||
<List dense>
|
||||
{sourceAugs.map((e) => {
|
||||
const aug = Augmentations[e.name];
|
||||
|
||||
let level = null;
|
||||
@ -29,12 +66,9 @@ export function InstalledAugmentations(): React.ReactElement {
|
||||
level = e.level;
|
||||
}
|
||||
|
||||
return (
|
||||
<li key={e.name}>
|
||||
<AugmentationAccordion aug={aug} level={level} />
|
||||
</li>
|
||||
return <AugmentationAccordion key={aug.name} aug={aug} level={level} />;
|
||||
})}
|
||||
</List>
|
||||
</>
|
||||
);
|
||||
});
|
||||
|
||||
return <>{augs}</>;
|
||||
}
|
||||
|
@ -1,115 +0,0 @@
|
||||
/**
|
||||
* React Component for displaying all of the player's installed Augmentations and
|
||||
* Source-Files.
|
||||
*
|
||||
* It also contains 'configuration' buttons that allow you to change how the
|
||||
* Augs/SF's are displayed
|
||||
*/
|
||||
import * as React from "react";
|
||||
|
||||
import { InstalledAugmentations } from "./InstalledAugmentations";
|
||||
import { ListConfiguration } from "./ListConfiguration";
|
||||
import { OwnedSourceFiles } from "./OwnedSourceFiles";
|
||||
import { SourceFileMinus1 } from "./SourceFileMinus1";
|
||||
|
||||
import { Settings } from "../../Settings/Settings";
|
||||
import { OwnedAugmentationsOrderSetting } from "../../Settings/SettingEnums";
|
||||
|
||||
type IProps = {
|
||||
// nothing special.
|
||||
};
|
||||
|
||||
type IState = {
|
||||
rerenderFlag: boolean;
|
||||
};
|
||||
|
||||
export class InstalledAugmentationsAndSourceFiles extends React.Component<IProps, IState> {
|
||||
listRef: React.RefObject<HTMLUListElement>;
|
||||
|
||||
constructor(props: IProps) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
rerenderFlag: false,
|
||||
};
|
||||
|
||||
this.collapseAllHeaders = this.collapseAllHeaders.bind(this);
|
||||
this.expandAllHeaders = this.expandAllHeaders.bind(this);
|
||||
this.sortByAcquirementTime = this.sortByAcquirementTime.bind(this);
|
||||
this.sortInOrder = this.sortInOrder.bind(this);
|
||||
|
||||
this.listRef = React.createRef();
|
||||
}
|
||||
|
||||
collapseAllHeaders(): void {
|
||||
const ul = this.listRef.current;
|
||||
if (ul == null) {
|
||||
return;
|
||||
}
|
||||
const tickers = ul.getElementsByClassName("accordion-header");
|
||||
for (let i = 0; i < tickers.length; ++i) {
|
||||
const ticker = tickers[i];
|
||||
if (!(ticker instanceof HTMLButtonElement)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ticker.classList.contains("active")) {
|
||||
ticker.click();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
expandAllHeaders(): void {
|
||||
const ul = this.listRef.current;
|
||||
if (ul == null) {
|
||||
return;
|
||||
}
|
||||
const tickers = ul.getElementsByClassName("accordion-header");
|
||||
for (let i = 0; i < tickers.length; ++i) {
|
||||
const ticker = tickers[i];
|
||||
if (!(ticker instanceof HTMLButtonElement)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!ticker.classList.contains("active")) {
|
||||
ticker.click();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rerender(): void {
|
||||
this.setState((prevState) => {
|
||||
return {
|
||||
rerenderFlag: !prevState.rerenderFlag,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
sortByAcquirementTime(): void {
|
||||
Settings.OwnedAugmentationsOrder = OwnedAugmentationsOrderSetting.AcquirementTime;
|
||||
this.rerender();
|
||||
}
|
||||
|
||||
sortInOrder(): void {
|
||||
Settings.OwnedAugmentationsOrder = OwnedAugmentationsOrderSetting.Alphabetically;
|
||||
this.rerender();
|
||||
}
|
||||
|
||||
render(): React.ReactNode {
|
||||
return (
|
||||
<>
|
||||
<ListConfiguration
|
||||
collapseAllButtonsFn={this.collapseAllHeaders}
|
||||
expandAllButtonsFn={this.expandAllHeaders}
|
||||
sortByAcquirementTimeFn={this.sortByAcquirementTime}
|
||||
sortInOrderFn={this.sortInOrder}
|
||||
/>
|
||||
<ul className="augmentations-list" ref={this.listRef}>
|
||||
<SourceFileMinus1 />
|
||||
<OwnedSourceFiles />
|
||||
<InstalledAugmentations />
|
||||
</ul>
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
/**
|
||||
* React Component for configuring the way installed augmentations and
|
||||
* Source-Files are displayed in the Augmentations UI
|
||||
*/
|
||||
import * as React from "react";
|
||||
|
||||
import { StdButton } from "../../ui/React/StdButton";
|
||||
|
||||
type IProps = {
|
||||
collapseAllButtonsFn: () => void;
|
||||
expandAllButtonsFn: () => void;
|
||||
sortByAcquirementTimeFn: () => void;
|
||||
sortInOrderFn: () => void;
|
||||
};
|
||||
|
||||
export function ListConfiguration(props: IProps): React.ReactElement {
|
||||
return (
|
||||
<>
|
||||
<StdButton onClick={props.expandAllButtonsFn} text="Expand All" />
|
||||
<StdButton onClick={props.collapseAllButtonsFn} text="Collapse All" />
|
||||
<StdButton
|
||||
onClick={props.sortInOrderFn}
|
||||
text="Sort in Order"
|
||||
tooltip="Sorts the Augmentations alphabetically and Source-Files in numeral order"
|
||||
/>
|
||||
<StdButton
|
||||
onClick={props.sortByAcquirementTimeFn}
|
||||
text="Sort by Acquirement Time"
|
||||
tooltip="Sorts the Augmentations and Source-Files based on when you acquired them (same as default)"
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
@ -20,7 +20,9 @@ export function OwnedSourceFiles(): React.ReactElement {
|
||||
});
|
||||
}
|
||||
|
||||
const sfs = sourceSfs.map((e) => {
|
||||
return (
|
||||
<>
|
||||
{sourceSfs.map((e) => {
|
||||
const srcFileKey = "SourceFile" + e.n;
|
||||
const sfObj = SourceFiles[srcFileKey];
|
||||
if (sfObj == null) {
|
||||
@ -28,12 +30,8 @@ export function OwnedSourceFiles(): React.ReactElement {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<li key={e.n}>
|
||||
<SourceFileAccordion level={e.lvl} sf={sfObj} />
|
||||
</li>
|
||||
return <SourceFileAccordion key={e.n} level={e.lvl} sf={sfObj} />;
|
||||
})}
|
||||
</>
|
||||
);
|
||||
});
|
||||
|
||||
return <>{sfs}</>;
|
||||
}
|
||||
|
@ -6,6 +6,11 @@ import * as React from "react";
|
||||
import { Player } from "../../Player";
|
||||
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||
import { Augmentations } from "../Augmentations";
|
||||
import { Table, TableCell } from "../../ui/React/Table";
|
||||
import TableBody from "@mui/material/TableBody";
|
||||
import { Table as MuiTable } from "@mui/material";
|
||||
import TableRow from "@mui/material/TableRow";
|
||||
import Typography from "@mui/material/Typography";
|
||||
|
||||
function calculateAugmentedStats(): any {
|
||||
const augP: any = {};
|
||||
@ -19,41 +24,52 @@ function calculateAugmentedStats(): any {
|
||||
return augP;
|
||||
}
|
||||
|
||||
export function PlayerMultipliers(): React.ReactElement {
|
||||
const mults = calculateAugmentedStats();
|
||||
function MultiplierTable(rows: any[]): React.ReactElement {
|
||||
function improvements(r: number): JSX.Element[] {
|
||||
let elems: JSX.Element[] = [];
|
||||
function Improvements({ r }: { r: number }): React.ReactElement {
|
||||
if (r) {
|
||||
elems = [<td key="2"> {"=>"} </td>, <td key="3">{numeralWrapper.formatPercentage(r)}</td>];
|
||||
}
|
||||
return elems;
|
||||
}
|
||||
|
||||
console.log(r);
|
||||
return (
|
||||
<table>
|
||||
<tbody>
|
||||
{rows.map((r: any) => (
|
||||
<tr key={r[0]}>
|
||||
<td key="0">
|
||||
<span>{r[0]} multiplier: </span>
|
||||
</td>
|
||||
<td key="1" style={{ textAlign: "right" }}>
|
||||
{numeralWrapper.formatPercentage(r[1])}
|
||||
</td>
|
||||
{improvements(r[2])}
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
<>
|
||||
<TableCell key="2">
|
||||
<Typography> {"=>"} </Typography>
|
||||
</TableCell>
|
||||
<TableCell key="3">
|
||||
<Typography>{numeralWrapper.formatPercentage(r)}</Typography>
|
||||
</TableCell>
|
||||
</>
|
||||
);
|
||||
}
|
||||
return <></>;
|
||||
}
|
||||
|
||||
function MultiplierTable({ rows }: { rows: [string, number, number][] }): React.ReactElement {
|
||||
return (
|
||||
<Table size="small" padding="none">
|
||||
<TableBody>
|
||||
{rows.map((r: any) => (
|
||||
<TableRow key={r[0]}>
|
||||
<TableCell key="0">
|
||||
<Typography noWrap>{r[0]} multiplier: </Typography>
|
||||
</TableCell>
|
||||
<TableCell key="1" style={{ textAlign: "right" }}>
|
||||
<Typography noWrap>{numeralWrapper.formatPercentage(r[1])}</Typography>
|
||||
</TableCell>
|
||||
<Improvements r={r[2]} />
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
);
|
||||
}
|
||||
|
||||
export function PlayerMultipliers(): React.ReactElement {
|
||||
const mults = calculateAugmentedStats();
|
||||
|
||||
function BladeburnerMults(): React.ReactElement {
|
||||
if (!Player.canAccessBladeburner()) return <></>;
|
||||
return (
|
||||
<>
|
||||
{MultiplierTable([
|
||||
<MultiplierTable
|
||||
rows={[
|
||||
[
|
||||
"Bladeburner Success Chance",
|
||||
Player.bladeburner_success_chance_mult,
|
||||
@ -74,7 +90,8 @@ export function PlayerMultipliers(): React.ReactElement {
|
||||
Player.bladeburner_analysis_mult,
|
||||
Player.bladeburner_analysis_mult * mults.bladeburner_analysis_mult,
|
||||
],
|
||||
])}
|
||||
]}
|
||||
/>
|
||||
<br />
|
||||
</>
|
||||
);
|
||||
@ -88,51 +105,66 @@ export function PlayerMultipliers(): React.ReactElement {
|
||||
</strong>
|
||||
</p>
|
||||
<br />
|
||||
{MultiplierTable([
|
||||
<MultiplierTable
|
||||
rows={[
|
||||
["Hacking Chance ", Player.hacking_chance_mult, Player.hacking_chance_mult * mults.hacking_chance_mult],
|
||||
["Hacking Speed ", Player.hacking_speed_mult, Player.hacking_speed_mult * mults.hacking_speed_mult],
|
||||
["Hacking Money ", Player.hacking_money_mult, Player.hacking_money_mult * mults.hacking_money_mult],
|
||||
["Hacking Growth ", Player.hacking_grow_mult, Player.hacking_grow_mult * mults.hacking_grow_mult],
|
||||
])}
|
||||
]}
|
||||
/>
|
||||
<br />
|
||||
|
||||
{MultiplierTable([
|
||||
<MultiplierTable
|
||||
rows={[
|
||||
["Hacking Level ", Player.hacking_mult, Player.hacking_mult * mults.hacking_mult],
|
||||
["Hacking Experience ", Player.hacking_exp_mult, Player.hacking_exp_mult * mults.hacking_exp_mult],
|
||||
])}
|
||||
]}
|
||||
/>
|
||||
<br />
|
||||
|
||||
{MultiplierTable([
|
||||
<MultiplierTable
|
||||
rows={[
|
||||
["Strength Level ", Player.strength_mult, Player.strength_mult * mults.strength_mult],
|
||||
["Strength Experience ", Player.strength_exp_mult, Player.strength_exp_mult * mults.strength_exp_mult],
|
||||
])}
|
||||
]}
|
||||
/>
|
||||
<br />
|
||||
|
||||
{MultiplierTable([
|
||||
<MultiplierTable
|
||||
rows={[
|
||||
["Defense Level ", Player.defense_mult, Player.defense_mult * mults.defense_mult],
|
||||
["Defense Experience ", Player.defense_exp_mult, Player.defense_exp_mult * mults.defense_exp_mult],
|
||||
])}
|
||||
]}
|
||||
/>
|
||||
<br />
|
||||
|
||||
{MultiplierTable([
|
||||
<MultiplierTable
|
||||
rows={[
|
||||
["Dexterity Level ", Player.dexterity_mult, Player.dexterity_mult * mults.dexterity_mult],
|
||||
["Dexterity Experience ", Player.dexterity_exp_mult, Player.dexterity_exp_mult * mults.dexterity_exp_mult],
|
||||
])}
|
||||
]}
|
||||
/>
|
||||
<br />
|
||||
|
||||
{MultiplierTable([
|
||||
<MultiplierTable
|
||||
rows={[
|
||||
["Agility Level ", Player.agility_mult, Player.agility_mult * mults.agility_mult],
|
||||
["Agility Experience ", Player.agility_exp_mult, Player.agility_exp_mult * mults.agility_exp_mult],
|
||||
])}
|
||||
]}
|
||||
/>
|
||||
<br />
|
||||
|
||||
{MultiplierTable([
|
||||
<MultiplierTable
|
||||
rows={[
|
||||
["Charisma Level ", Player.charisma_mult, Player.charisma_mult * mults.charisma_mult],
|
||||
["Charisma Experience ", Player.charisma_exp_mult, Player.charisma_exp_mult * mults.charisma_exp_mult],
|
||||
])}
|
||||
]}
|
||||
/>
|
||||
<br />
|
||||
|
||||
{MultiplierTable([
|
||||
<MultiplierTable
|
||||
rows={[
|
||||
[
|
||||
"Hacknet Node production ",
|
||||
Player.hacknet_node_money_mult,
|
||||
@ -158,20 +190,25 @@ export function PlayerMultipliers(): React.ReactElement {
|
||||
Player.hacknet_node_level_cost_mult,
|
||||
Player.hacknet_node_level_cost_mult * mults.hacknet_node_level_cost_mult,
|
||||
],
|
||||
])}
|
||||
]}
|
||||
/>
|
||||
<br />
|
||||
|
||||
{MultiplierTable([
|
||||
<MultiplierTable
|
||||
rows={[
|
||||
["Company reputation gain ", Player.company_rep_mult, Player.company_rep_mult * mults.company_rep_mult],
|
||||
["Faction reputation gain ", Player.faction_rep_mult, Player.faction_rep_mult * mults.faction_rep_mult],
|
||||
["Salary ", Player.work_money_mult, Player.work_money_mult * mults.work_money_mult],
|
||||
])}
|
||||
]}
|
||||
/>
|
||||
<br />
|
||||
|
||||
{MultiplierTable([
|
||||
<MultiplierTable
|
||||
rows={[
|
||||
["Crime success ", Player.crime_success_mult, Player.crime_success_mult * mults.crime_success_mult],
|
||||
["Crime money ", Player.crime_money_mult, Player.crime_money_mult * mults.crime_money_mult],
|
||||
])}
|
||||
]}
|
||||
/>
|
||||
<br />
|
||||
|
||||
<BladeburnerMults />
|
||||
|
@ -9,6 +9,7 @@ import { AugmentationNames } from "../../Augmentation/data/AugmentationNames";
|
||||
import { Player } from "../../Player";
|
||||
|
||||
import { AugmentationAccordion } from "../../ui/React/AugmentationAccordion";
|
||||
import List from "@mui/material/List";
|
||||
|
||||
export function PurchasedAugmentations(): React.ReactElement {
|
||||
const augs: React.ReactElement[] = [];
|
||||
@ -29,12 +30,8 @@ export function PurchasedAugmentations(): React.ReactElement {
|
||||
level = ownedAug.level;
|
||||
}
|
||||
|
||||
augs.push(
|
||||
<li key={`${ownedAug.name}${ownedAug.level}`}>
|
||||
<AugmentationAccordion aug={aug} level={level} />
|
||||
</li>,
|
||||
);
|
||||
augs.push(<AugmentationAccordion key={aug.name} aug={aug} level={level} />);
|
||||
}
|
||||
|
||||
return <ul className="augmentations-list">{augs}</ul>;
|
||||
return <List dense>{augs}</List>;
|
||||
}
|
||||
|
@ -2,14 +2,22 @@
|
||||
* React Component for displaying a list of the player's Source-Files
|
||||
* on the Augmentations UI
|
||||
*/
|
||||
import * as React from "react";
|
||||
import React, { useState } from "react";
|
||||
|
||||
import { Player } from "../../Player";
|
||||
import { Exploit, ExploitName } from "../../Exploits/Exploit";
|
||||
|
||||
import { BBAccordion } from "../../ui/React/BBAccordion";
|
||||
import ListItemButton from "@mui/material/ListItemButton";
|
||||
import ListItemText from "@mui/material/ListItemText";
|
||||
import Box from "@mui/material/Box";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import Paper from "@mui/material/Paper";
|
||||
import Collapse from "@mui/material/Collapse";
|
||||
import ExpandMore from "@mui/icons-material/ExpandMore";
|
||||
import ExpandLess from "@mui/icons-material/ExpandLess";
|
||||
|
||||
export function SourceFileMinus1(): React.ReactElement {
|
||||
const [open, setOpen] = useState(false);
|
||||
const exploits = Player.exploits;
|
||||
|
||||
if (exploits.length === 0) {
|
||||
@ -17,33 +25,35 @@ export function SourceFileMinus1(): React.ReactElement {
|
||||
}
|
||||
|
||||
return (
|
||||
<li key={-1}>
|
||||
<BBAccordion
|
||||
headerContent={
|
||||
<>
|
||||
<Box component={Paper}>
|
||||
<ListItemButton onClick={() => setOpen((old) => !old)}>
|
||||
<ListItemText
|
||||
primary={
|
||||
<Typography style={{ whiteSpace: "pre-wrap" }}>
|
||||
Source-File -1: Exploits in the BitNodes
|
||||
<br />
|
||||
Level {exploits.length} / ?
|
||||
</>
|
||||
}
|
||||
panelContent={
|
||||
<>
|
||||
<p>
|
||||
This Source-File can only be acquired with obscure knowledge of the game, javascript, and the web
|
||||
ecosystem.
|
||||
</p>
|
||||
<p>It increases all of the player's multipliers by 0.1%</p>
|
||||
<br />
|
||||
|
||||
<p>You have found the following exploits:</p>
|
||||
<ul>
|
||||
{exploits.map((c: Exploit) => (
|
||||
<li key={c}>* {ExploitName(c)}</li>
|
||||
))}
|
||||
</ul>
|
||||
</>
|
||||
</Typography>
|
||||
}
|
||||
/>
|
||||
</li>
|
||||
{open ? <ExpandLess color="primary" /> : <ExpandMore color="primary" />}
|
||||
</ListItemButton>
|
||||
<Collapse in={open} unmountOnExit>
|
||||
<Box m={4}>
|
||||
<Typography>
|
||||
This Source-File can only be acquired with obscure knowledge of the game, javascript, and the web ecosystem.
|
||||
</Typography>
|
||||
<Typography>It increases all of the player's multipliers by 0.1%</Typography>
|
||||
<br />
|
||||
|
||||
<Typography>You have found the following exploits:</Typography>
|
||||
<Box mx={2}>
|
||||
{exploits.map((c: Exploit) => (
|
||||
<Typography key={c}>* {ExploitName(c)}</Typography>
|
||||
))}
|
||||
</Box>
|
||||
</Box>
|
||||
</Collapse>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
20
src/Augmentation/ui/SourceFiles.tsx
Normal file
20
src/Augmentation/ui/SourceFiles.tsx
Normal file
@ -0,0 +1,20 @@
|
||||
import React from "react";
|
||||
import { use } from "../../ui/Context";
|
||||
import { SourceFileMinus1 } from "./SourceFileMinus1";
|
||||
import { OwnedSourceFiles } from "./OwnedSourceFiles";
|
||||
import List from "@mui/material/List";
|
||||
|
||||
import Typography from "@mui/material/Typography";
|
||||
|
||||
export function SourceFiles(): React.ReactElement {
|
||||
const player = use.Player();
|
||||
return (
|
||||
<>
|
||||
<Typography variant="h4">Source Files</Typography>
|
||||
<List dense>
|
||||
<SourceFileMinus1 />
|
||||
<OwnedSourceFiles />
|
||||
</List>
|
||||
</>
|
||||
);
|
||||
}
|
@ -47,7 +47,7 @@ export function SleeveAugmentationsPopup(props: IProps): React.ReactElement {
|
||||
tooltip = renderToStaticMarkup(tooltip);
|
||||
}
|
||||
tooltip += "<br /><br />";
|
||||
tooltip += renderToStaticMarkup(aug.stats);
|
||||
tooltip += renderToStaticMarkup(aug.stats || <></>);
|
||||
return (
|
||||
<div key={augName} className="gang-owned-upgrade tooltip">
|
||||
{augName}
|
||||
@ -70,7 +70,7 @@ export function SleeveAugmentationsPopup(props: IProps): React.ReactElement {
|
||||
info = renderToStaticMarkup(info);
|
||||
}
|
||||
info += "<br /><br />";
|
||||
info += renderToStaticMarkup(aug.stats);
|
||||
info += renderToStaticMarkup(aug.stats || <></>);
|
||||
|
||||
return (
|
||||
<div key={aug.name} className="cmpy-mgmt-upgrade-div" onClick={() => purchaseAugmentation(aug)}>
|
||||
|
@ -91,16 +91,11 @@ export class Script {
|
||||
* @param {string} code - The new contents of the script
|
||||
* @param {Script[]} otherScripts - Other scripts on the server. Used to process imports
|
||||
*/
|
||||
saveScript(code: string, serverIp: string, otherScripts: Script[]): void {
|
||||
saveScript(filename: string, code: string, serverIp: string, otherScripts: Script[]): void {
|
||||
// Update code and filename
|
||||
this.code = code.replace(/^\s+|\s+$/g, "");
|
||||
|
||||
const filenameElem: HTMLInputElement | null = document.getElementById("script-editor-filename") as HTMLInputElement;
|
||||
if (filenameElem == null) {
|
||||
console.error(`Failed to get Script filename DOM element`);
|
||||
return;
|
||||
}
|
||||
this.filename = filenameElem.value;
|
||||
this.filename = filename;
|
||||
this.server = serverIp;
|
||||
this.updateRamUsage(otherScripts);
|
||||
this.markUpdated();
|
||||
|
@ -130,14 +130,14 @@ export function Root(props: IProps): React.ReactElement {
|
||||
let found = false;
|
||||
for (let i = 0; i < server.scripts.length; i++) {
|
||||
if (filename == server.scripts[i].filename) {
|
||||
server.scripts[i].saveScript(code, props.player.currentServer, server.scripts);
|
||||
server.scripts[i].saveScript(filename, code, props.player.currentServer, server.scripts);
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
const script = new Script();
|
||||
script.saveScript(code, props.player.currentServer, server.scripts);
|
||||
script.saveScript(filename, code, props.player.currentServer, server.scripts);
|
||||
server.scripts.push(script);
|
||||
}
|
||||
|
||||
@ -165,7 +165,7 @@ export function Root(props: IProps): React.ReactElement {
|
||||
//If the current script already exists on the server, overwrite it
|
||||
for (let i = 0; i < server.scripts.length; i++) {
|
||||
if (filename == server.scripts[i].filename) {
|
||||
server.scripts[i].saveScript(code, props.player.currentServer, server.scripts);
|
||||
server.scripts[i].saveScript(filename, code, props.player.currentServer, server.scripts);
|
||||
props.router.toTerminal();
|
||||
return;
|
||||
}
|
||||
@ -173,7 +173,7 @@ export function Root(props: IProps): React.ReactElement {
|
||||
|
||||
//If the current script does NOT exist, create a new one
|
||||
const script = new Script();
|
||||
script.saveScript(code, props.player.currentServer, server.scripts);
|
||||
script.saveScript(filename, code, props.player.currentServer, server.scripts);
|
||||
server.scripts.push(script);
|
||||
} else if (filename.endsWith(".txt")) {
|
||||
for (let i = 0; i < server.textFiles.length; ++i) {
|
||||
|
@ -1,13 +1,13 @@
|
||||
import { BitNodes } from "../BitNode/BitNode";
|
||||
|
||||
export class SourceFile {
|
||||
info: string;
|
||||
info: JSX.Element;
|
||||
lvl = 1;
|
||||
n: number;
|
||||
name: string;
|
||||
owned = false;
|
||||
|
||||
constructor(number: number, info = "") {
|
||||
constructor(number: number, info: JSX.Element) {
|
||||
const bitnodeKey = "BitNode" + number;
|
||||
const bitnode = BitNodes[bitnodeKey];
|
||||
if (bitnode == null) {
|
||||
|
@ -1,104 +0,0 @@
|
||||
import { SourceFile } from "./SourceFile";
|
||||
import { IMap } from "../types";
|
||||
|
||||
export const SourceFiles: IMap<SourceFile> = {};
|
||||
|
||||
SourceFiles["SourceFile1"] = new SourceFile(
|
||||
1,
|
||||
"This Source-File lets the player start with 32GB of RAM on his/her " +
|
||||
"home computer. It also increases all of the player's multipliers by:<br><br>" +
|
||||
"Level 1: 16%<br>" +
|
||||
"Level 2: 24%<br>" +
|
||||
"Level 3: 28%",
|
||||
);
|
||||
SourceFiles["SourceFile2"] = new SourceFile(
|
||||
2,
|
||||
"This Source-File allows you to form gangs in other BitNodes " +
|
||||
"once your karma decreases to a certain value. It also increases the player's " +
|
||||
"crime success rate, crime money, and charisma multipliers by:<br><br>" +
|
||||
"Level 1: 24%<br>" +
|
||||
"Level 2: 36%<br>" +
|
||||
"Level 3: 42%",
|
||||
);
|
||||
SourceFiles["SourceFile3"] = new SourceFile(
|
||||
3,
|
||||
"This Source-File lets you create corporations on other BitNodes (although " +
|
||||
"some BitNodes will disable this mechanic). This Source-File also increases your charisma and company salary multipliers by:<br>" +
|
||||
"Level 1: 8%<br>" +
|
||||
"Level 2: 12%<br>" +
|
||||
"Level 3: 14%",
|
||||
);
|
||||
SourceFiles["SourceFile4"] = new SourceFile(
|
||||
4,
|
||||
"This Source-File lets you access and use the Singularity Functions in every BitNode. Every " +
|
||||
"level of this Source-File opens up more of the Singularity Functions you can use.",
|
||||
);
|
||||
SourceFiles["SourceFile5"] = new SourceFile(
|
||||
5,
|
||||
"This Source-File grants a special new stat called Intelligence. Intelligence " +
|
||||
"is unique because it is permanent and persistent (it never gets reset back to 1). However, " +
|
||||
"gaining Intelligence experience is much slower than other stats, and it is also hidden (you won't " +
|
||||
"know when you gain experience and how much). Higher Intelligence levels will boost your production " +
|
||||
"for many actions in the game. In addition, this Source-File will unlock the getBitNodeMultipliers() " +
|
||||
"and getServer() Netscript functions, as well as the formulas API, and will raise all of your " +
|
||||
"hacking-related multipliers by:<br><br> " +
|
||||
"Level 1: 8%<br>" +
|
||||
"Level 2: 12%<br>" +
|
||||
"Level 3: 14%",
|
||||
);
|
||||
SourceFiles["SourceFile6"] = new SourceFile(
|
||||
6,
|
||||
"This Source-File allows you to access the NSA's Bladeburner Division in other " +
|
||||
"BitNodes. In addition, this Source-File will raise both the level and experience gain rate of all your combat stats by:<br><br>" +
|
||||
"Level 1: 8%<br>" +
|
||||
"Level 2: 12%<br>" +
|
||||
"Level 3: 14%",
|
||||
);
|
||||
SourceFiles["SourceFile7"] = new SourceFile(
|
||||
7,
|
||||
"This Source-File allows you to access the Bladeburner Netscript API in other " +
|
||||
"BitNodes. In addition, this Source-File will increase all of your Bladeburner multipliers by:<br><br>" +
|
||||
"Level 1: 8%<br>" +
|
||||
"Level 2: 12%<br>" +
|
||||
"Level 3: 14%",
|
||||
);
|
||||
SourceFiles["SourceFile8"] = new SourceFile(
|
||||
8,
|
||||
"This Source-File grants the following benefits:<br><br>" +
|
||||
"Level 1: Permanent access to WSE and TIX API<br>" +
|
||||
"Level 2: Ability to short stocks in other BitNodes<br>" +
|
||||
"Level 3: Ability to use limit/stop orders in other BitNodes<br><br>" +
|
||||
"This Source-File also increases your hacking growth multipliers by: " +
|
||||
"<br>Level 1: 12%<br>Level 2: 18%<br>Level 3: 21%",
|
||||
);
|
||||
SourceFiles["SourceFile9"] = new SourceFile(
|
||||
9,
|
||||
"This Source-File grants the following benefits:<br><br>" +
|
||||
"Level 1: Permanently unlocks the Hacknet Server in other BitNodes<br>" +
|
||||
"Level 2: You start with 128GB of RAM on your home computer when entering a new BitNode<br>" +
|
||||
"Level 3: Grants a highly-upgraded Hacknet Server when entering a new BitNode<br><br>" +
|
||||
"(Note that the Level 3 effect of this Source-File only applies when entering a new BitNode, NOT " +
|
||||
"when installing Augmentations)",
|
||||
);
|
||||
SourceFiles["SourceFile10"] = new SourceFile(
|
||||
10,
|
||||
"This Source-File unlocks Sleeve technology in other BitNodes. Each level of this " +
|
||||
"Source-File also grants you a Duplicate Sleeve",
|
||||
);
|
||||
SourceFiles["SourceFile11"] = new SourceFile(
|
||||
11,
|
||||
"This Source-File makes it so that company favor increases BOTH the player's salary and reputation gain rate " +
|
||||
"at that company by 1% per favor (rather than just the reputation gain). This Source-File also " +
|
||||
" increases the player's company salary and reputation gain multipliers by:<br><br>" +
|
||||
"Level 1: 32%<br>" +
|
||||
"Level 2: 48%<br>" +
|
||||
"Level 3: 56%<br><br>" +
|
||||
"It also reduces the price increase for every aug bought by:<br><br>" +
|
||||
"Level 1: 4%<br>" +
|
||||
"Level 2: 6%<br>" +
|
||||
"Level 3: 7%",
|
||||
);
|
||||
SourceFiles["SourceFile12"] = new SourceFile(
|
||||
12,
|
||||
"This Source-File lets the player start with Neuroflux Governor equal to the level of this Source-File.",
|
||||
);
|
197
src/SourceFile/SourceFiles.tsx
Normal file
197
src/SourceFile/SourceFiles.tsx
Normal file
@ -0,0 +1,197 @@
|
||||
import React from "react";
|
||||
import { SourceFile } from "./SourceFile";
|
||||
import { IMap } from "../types";
|
||||
|
||||
export const SourceFiles: IMap<SourceFile> = {};
|
||||
|
||||
SourceFiles["SourceFile1"] = new SourceFile(
|
||||
1,
|
||||
(
|
||||
<>
|
||||
This Source-File lets the player start with 32GB of RAM on his/her home computer. It also increases all of the
|
||||
player's multipliers by:
|
||||
<br />
|
||||
<br />
|
||||
Level 1: 16%
|
||||
<br />
|
||||
Level 2: 24%
|
||||
<br />
|
||||
Level 3: 28%
|
||||
</>
|
||||
),
|
||||
);
|
||||
SourceFiles["SourceFile2"] = new SourceFile(
|
||||
2,
|
||||
(
|
||||
<>
|
||||
This Source-File allows you to form gangs in other BitNodes once your karma decreases to a certain value. It also
|
||||
increases the player's crime success rate, crime money, and charisma multipliers by:
|
||||
<br />
|
||||
<br />
|
||||
Level 1: 24%
|
||||
<br />
|
||||
Level 2: 36%
|
||||
<br />
|
||||
Level 3: 42%
|
||||
</>
|
||||
),
|
||||
);
|
||||
SourceFiles["SourceFile3"] = new SourceFile(
|
||||
3,
|
||||
(
|
||||
<>
|
||||
This Source-File lets you create corporations on other BitNodes (although some BitNodes will disable this
|
||||
mechanic). This Source-File also increases your charisma and company salary multipliers by:
|
||||
<br />
|
||||
Level 1: 8%
|
||||
<br />
|
||||
Level 2: 12%
|
||||
<br />
|
||||
Level 3: 14%
|
||||
</>
|
||||
),
|
||||
);
|
||||
SourceFiles["SourceFile4"] = new SourceFile(
|
||||
4,
|
||||
(
|
||||
<>
|
||||
This Source-File lets you access and use the Singularity Functions in every BitNode. Every level of this
|
||||
Source-File opens up more of the Singularity Functions you can use.
|
||||
</>
|
||||
),
|
||||
);
|
||||
SourceFiles["SourceFile5"] = new SourceFile(
|
||||
5,
|
||||
(
|
||||
<>
|
||||
This Source-File grants a special new stat called Intelligence. Intelligence is unique because it is permanent and
|
||||
persistent (it never gets reset back to 1). However, gaining Intelligence experience is much slower than other
|
||||
stats, and it is also hidden (you won't know when you gain experience and how much). Higher Intelligence levels
|
||||
will boost your production for many actions in the game. In addition, this Source-File will unlock the
|
||||
getBitNodeMultipliers() and getServer() Netscript functions, as well as the formulas API, and will raise all of
|
||||
your hacking-related multipliers by:
|
||||
<br />
|
||||
<br />
|
||||
Level 1: 8%
|
||||
<br />
|
||||
Level 2: 12%
|
||||
<br />
|
||||
Level 3: 14%
|
||||
</>
|
||||
),
|
||||
);
|
||||
SourceFiles["SourceFile6"] = new SourceFile(
|
||||
6,
|
||||
(
|
||||
<>
|
||||
This Source-File allows you to access the NSA's Bladeburner Division in other BitNodes. In addition, this
|
||||
Source-File will raise both the level and experience gain rate of all your combat stats by:
|
||||
<br />
|
||||
<br />
|
||||
Level 1: 8%
|
||||
<br />
|
||||
Level 2: 12%
|
||||
<br />
|
||||
Level 3: 14%
|
||||
</>
|
||||
),
|
||||
);
|
||||
SourceFiles["SourceFile7"] = new SourceFile(
|
||||
7,
|
||||
(
|
||||
<>
|
||||
This Source-File allows you to access the Bladeburner Netscript API in other BitNodes. In addition, this
|
||||
Source-File will increase all of your Bladeburner multipliers by:
|
||||
<br />
|
||||
<br />
|
||||
Level 1: 8%
|
||||
<br />
|
||||
Level 2: 12%
|
||||
<br />
|
||||
Level 3: 14%
|
||||
</>
|
||||
),
|
||||
);
|
||||
SourceFiles["SourceFile8"] = new SourceFile(
|
||||
8,
|
||||
(
|
||||
<>
|
||||
This Source-File grants the following benefits:
|
||||
<br />
|
||||
<br />
|
||||
Level 1: Permanent access to WSE and TIX API
|
||||
<br />
|
||||
Level 2: Ability to short stocks in other BitNodes
|
||||
<br />
|
||||
Level 3: Ability to use limit/stop orders in other BitNodes
|
||||
<br />
|
||||
<br />
|
||||
This Source-File also increases your hacking growth multipliers by:
|
||||
<br />
|
||||
Level 1: 12%
|
||||
<br />
|
||||
Level 2: 18%
|
||||
<br />
|
||||
Level 3: 21%
|
||||
</>
|
||||
),
|
||||
);
|
||||
SourceFiles["SourceFile9"] = new SourceFile(
|
||||
9,
|
||||
(
|
||||
<>
|
||||
This Source-File grants the following benefits:
|
||||
<br />
|
||||
<br />
|
||||
Level 1: Permanently unlocks the Hacknet Server in other BitNodes
|
||||
<br />
|
||||
Level 2: You start with 128GB of RAM on your home computer when entering a new BitNode
|
||||
<br />
|
||||
Level 3: Grants a highly-upgraded Hacknet Server when entering a new BitNode
|
||||
<br />
|
||||
<br />
|
||||
(Note that the Level 3 effect of this Source-File only applies when entering a new BitNode, NOT when installing
|
||||
Augmentations)
|
||||
</>
|
||||
),
|
||||
);
|
||||
SourceFiles["SourceFile10"] = new SourceFile(
|
||||
10,
|
||||
(
|
||||
<>
|
||||
This Source-File unlocks Sleeve technology in other BitNodes. Each level of this Source-File also grants you a
|
||||
Duplicate Sleeve
|
||||
</>
|
||||
),
|
||||
);
|
||||
SourceFiles["SourceFile11"] = new SourceFile(
|
||||
11,
|
||||
(
|
||||
<>
|
||||
This Source-File makes it so that company favor increases BOTH the player's salary and reputation gain rate at
|
||||
that company by 1% per favor (rather than just the reputation gain). This Source-File also increases the player's
|
||||
company salary and reputation gain multipliers by:
|
||||
<br />
|
||||
<br />
|
||||
Level 1: 32%
|
||||
<br />
|
||||
Level 2: 48%
|
||||
<br />
|
||||
Level 3: 56%
|
||||
<br />
|
||||
<br />
|
||||
It also reduces the price increase for every aug bought by:
|
||||
<br />
|
||||
<br />
|
||||
Level 1: 4%
|
||||
<br />
|
||||
Level 2: 6%
|
||||
<br />
|
||||
Level 3: 7%
|
||||
</>
|
||||
),
|
||||
);
|
||||
SourceFiles["SourceFile12"] = new SourceFile(
|
||||
12,
|
||||
<>This Source-File lets the player start with Neuroflux Governor equal to the level of this Source-File.</>,
|
||||
);
|
@ -4,12 +4,18 @@
|
||||
* The header of the accordion contains the Augmentation's name (and level, if
|
||||
* applicable), and the accordion's panel contains the Augmentation's description.
|
||||
*/
|
||||
import * as React from "react";
|
||||
|
||||
import { BBAccordion } from "./BBAccordion";
|
||||
import React, { useState } from "react";
|
||||
|
||||
import { Augmentation } from "../../Augmentation/Augmentation";
|
||||
import { AugmentationNames } from "../../Augmentation/data/AugmentationNames";
|
||||
import ListItemButton from "@mui/material/ListItemButton";
|
||||
import ListItemText from "@mui/material/ListItemText";
|
||||
import Box from "@mui/material/Box";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import Paper from "@mui/material/Paper";
|
||||
import Collapse from "@mui/material/Collapse";
|
||||
import ExpandMore from "@mui/icons-material/ExpandMore";
|
||||
import ExpandLess from "@mui/icons-material/ExpandLess";
|
||||
|
||||
type IProps = {
|
||||
aug: Augmentation;
|
||||
@ -17,6 +23,7 @@ type IProps = {
|
||||
};
|
||||
|
||||
export function AugmentationAccordion(props: IProps): React.ReactElement {
|
||||
const [open, setOpen] = useState(false);
|
||||
let displayName = props.aug.name;
|
||||
if (props.level != null) {
|
||||
if (props.aug.name === AugmentationNames.NeuroFluxGovernor) {
|
||||
@ -26,31 +33,47 @@ export function AugmentationAccordion(props: IProps): React.ReactElement {
|
||||
|
||||
if (typeof props.aug.info === "string") {
|
||||
return (
|
||||
<BBAccordion
|
||||
headerContent={<>{displayName}</>}
|
||||
panelContent={
|
||||
<p>
|
||||
<span dangerouslySetInnerHTML={{ __html: props.aug.info }} />
|
||||
<Box component={Paper}>
|
||||
<ListItemButton onClick={() => setOpen((old) => !old)}>
|
||||
<ListItemText primary={<Typography style={{ whiteSpace: "pre-wrap" }}>{displayName}</Typography>} />
|
||||
{open ? <ExpandLess color="primary" /> : <ExpandMore color="primary" />}
|
||||
</ListItemButton>
|
||||
<Collapse in={open} unmountOnExit>
|
||||
<Box m={4}>
|
||||
<Typography dangerouslySetInnerHTML={{ __html: props.aug.info }} />
|
||||
{props.aug.stats && (
|
||||
<>
|
||||
<br />
|
||||
<br />
|
||||
{props.aug.stats}
|
||||
</p>
|
||||
}
|
||||
/>
|
||||
<Typography>{props.aug.stats}</Typography>
|
||||
</>
|
||||
)}
|
||||
</Box>
|
||||
</Collapse>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<BBAccordion
|
||||
headerContent={<>{displayName}</>}
|
||||
panelContent={
|
||||
<p>
|
||||
<Box component={Paper}>
|
||||
<ListItemButton onClick={() => setOpen((old) => !old)}>
|
||||
<ListItemText primary={<Typography style={{ whiteSpace: "pre-wrap" }}>{displayName}</Typography>} />
|
||||
{open ? <ExpandLess color="primary" /> : <ExpandMore color="primary" />}
|
||||
</ListItemButton>
|
||||
<Collapse in={open} unmountOnExit>
|
||||
<Box m={4}>
|
||||
<Typography>
|
||||
{props.aug.info}
|
||||
{props.aug.stats && (
|
||||
<>
|
||||
<br />
|
||||
<br />
|
||||
{props.aug.stats}
|
||||
</p>
|
||||
}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</Typography>
|
||||
</Box>
|
||||
</Collapse>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
@ -4,30 +4,47 @@
|
||||
* The header of the accordion contains the Source-Files's name and level,
|
||||
* and the accordion's panel contains the Source-File's description.
|
||||
*/
|
||||
import * as React from "react";
|
||||
|
||||
import { BBAccordion } from "./BBAccordion";
|
||||
import React, { useState } from "react";
|
||||
|
||||
import { SourceFile } from "../../SourceFile/SourceFile";
|
||||
|
||||
import ListItemButton from "@mui/material/ListItemButton";
|
||||
import ListItemText from "@mui/material/ListItemText";
|
||||
import Box from "@mui/material/Box";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import Paper from "@mui/material/Paper";
|
||||
import Collapse from "@mui/material/Collapse";
|
||||
import ExpandMore from "@mui/icons-material/ExpandMore";
|
||||
import ExpandLess from "@mui/icons-material/ExpandLess";
|
||||
|
||||
type IProps = {
|
||||
level: number;
|
||||
sf: SourceFile;
|
||||
};
|
||||
|
||||
export function SourceFileAccordion(props: IProps): React.ReactElement {
|
||||
const [open, setOpen] = useState(false);
|
||||
const maxLevel = props.sf.n === 12 ? "∞" : "3";
|
||||
|
||||
return (
|
||||
<BBAccordion
|
||||
headerContent={
|
||||
<>
|
||||
<Box component={Paper}>
|
||||
<ListItemButton onClick={() => setOpen((old) => !old)}>
|
||||
<ListItemText
|
||||
primary={
|
||||
<Typography style={{ whiteSpace: "pre-wrap" }}>
|
||||
{props.sf.name}
|
||||
<br />
|
||||
{`Level ${props.level} / ${maxLevel}`}
|
||||
</>
|
||||
</Typography>
|
||||
}
|
||||
panelContent={<p dangerouslySetInnerHTML={{ __html: props.sf.info }}></p>}
|
||||
/>
|
||||
{open ? <ExpandLess color="primary" /> : <ExpandMore color="primary" />}
|
||||
</ListItemButton>
|
||||
<Collapse in={open} unmountOnExit>
|
||||
<Box m={4}>
|
||||
<Typography>{props.sf.info}</Typography>
|
||||
</Box>
|
||||
</Collapse>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user