mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-12-23 14:42:28 +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 {
|
export interface IConstructorParams {
|
||||||
info: string | JSX.Element;
|
info: string | JSX.Element;
|
||||||
stats?: JSX.Element;
|
stats?: JSX.Element | null;
|
||||||
isSpecial?: boolean;
|
isSpecial?: boolean;
|
||||||
moneyCost: number;
|
moneyCost: number;
|
||||||
name: string;
|
name: string;
|
||||||
@ -369,7 +369,7 @@ export class Augmentation {
|
|||||||
info: string | JSX.Element;
|
info: string | JSX.Element;
|
||||||
|
|
||||||
// Description of the stats, often autogenerated, sometimes manually written.
|
// 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)
|
// Any Augmentation not immediately available in BitNode-1 is special (e.g. Bladeburner augs)
|
||||||
isSpecial = false;
|
isSpecial = false;
|
||||||
@ -507,8 +507,9 @@ export class Augmentation {
|
|||||||
this.mults.bladeburner_success_chance_mult = params.bladeburner_success_chance_mult;
|
this.mults.bladeburner_success_chance_mult = params.bladeburner_success_chance_mult;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (params.stats) this.stats = params.stats;
|
if (params.stats === undefined)
|
||||||
else this.stats = generateStatsDescription(this.mults, params.programs, params.startingMoney);
|
this.stats = generateStatsDescription(this.mults, params.programs, params.startingMoney);
|
||||||
|
else this.stats = params.stats;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adds this Augmentation to the specified Factions
|
// Adds this Augmentation to the specified Factions
|
||||||
|
@ -1555,7 +1555,7 @@ function initAugmentations() {
|
|||||||
repCost: 2.5e6,
|
repCost: 2.5e6,
|
||||||
moneyCost: 0,
|
moneyCost: 0,
|
||||||
info: "It's time to leave the cave.",
|
info: "It's time to leave the cave.",
|
||||||
stats: <></>,
|
stats: null,
|
||||||
});
|
});
|
||||||
RedPill.addToFactions(["Daedalus"]);
|
RedPill.addToFactions(["Daedalus"]);
|
||||||
if (augmentationExists(AugmentationNames.TheRedPill)) {
|
if (augmentationExists(AugmentationNames.TheRedPill)) {
|
||||||
@ -1595,7 +1595,7 @@ function initAugmentations() {
|
|||||||
"exactly the implant does, but they promise that it will greatly " +
|
"exactly the implant does, but they promise that it will greatly " +
|
||||||
"enhance your abilities.",
|
"enhance your abilities.",
|
||||||
hacking_grow_mult: 3,
|
hacking_grow_mult: 3,
|
||||||
stats: <></>,
|
stats: null,
|
||||||
});
|
});
|
||||||
HiveMind.addToFactions(["ECorp"]);
|
HiveMind.addToFactions(["ECorp"]);
|
||||||
if (augmentationExists(AugmentationNames.HiveMind)) {
|
if (augmentationExists(AugmentationNames.HiveMind)) {
|
||||||
|
@ -2,92 +2,78 @@
|
|||||||
* Root React component for the Augmentations UI page that display all of your
|
* Root React component for the Augmentations UI page that display all of your
|
||||||
* owned and purchased Augmentations and Source-Files.
|
* 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 { PlayerMultipliers } from "./PlayerMultipliers";
|
||||||
import { PurchasedAugmentations } from "./PurchasedAugmentations";
|
import { PurchasedAugmentations } from "./PurchasedAugmentations";
|
||||||
|
import { SourceFiles } from "./SourceFiles";
|
||||||
|
|
||||||
import { Player } from "../../Player";
|
import { Player } from "../../Player";
|
||||||
import { StdButton } from "../../ui/React/StdButton";
|
import { StdButton } from "../../ui/React/StdButton";
|
||||||
import { canGetBonus } from "../../ExportBonus";
|
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;
|
exportGameFn: () => void;
|
||||||
installAugmentationsFn: () => void;
|
installAugmentationsFn: () => void;
|
||||||
};
|
}
|
||||||
|
|
||||||
type IState = {
|
export function AugmentationsRoot(props: IProps): React.ReactElement {
|
||||||
rerender: boolean;
|
const setRerender = useState(false)[1];
|
||||||
};
|
|
||||||
|
function doExport(): void {
|
||||||
export class AugmentationsRoot extends React.Component<IProps, IState> {
|
props.exportGameFn();
|
||||||
constructor(props: IProps) {
|
setRerender((o) => !o);
|
||||||
super(props);
|
}
|
||||||
this.state = {
|
|
||||||
rerender: false,
|
function exportBonusStr(): string {
|
||||||
};
|
if (canGetBonus()) return "(+1 favor to all factions)";
|
||||||
this.export = this.export.bind(this);
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
export(): void {
|
return (
|
||||||
this.props.exportGameFn();
|
<>
|
||||||
this.setState({
|
<Typography variant="h4">Augmentations</Typography>
|
||||||
rerender: !this.state.rerender,
|
<Typography>
|
||||||
});
|
Below is a list of all Augmentations you have purchased but not yet installed. Click the button below to install
|
||||||
}
|
them.
|
||||||
|
</Typography>
|
||||||
render(): React.ReactNode {
|
<Typography>WARNING: Installing your Augmentations resets most of your progress, including:</Typography>
|
||||||
function exportBonusStr(): string {
|
<br />
|
||||||
if (canGetBonus()) return "(+1 favor to all factions)";
|
<Typography>- Stats/Skill levels and Experience</Typography>
|
||||||
return "";
|
<Typography>- Money</Typography>
|
||||||
}
|
<Typography>- Scripts on every computer but your home computer</Typography>
|
||||||
|
<Typography>- Purchased servers</Typography>
|
||||||
return (
|
<Typography>- Hacknet Nodes</Typography>
|
||||||
<>
|
<Typography>- Faction/Company reputation</Typography>
|
||||||
<div className="augmentations-content">
|
<Typography>- Stocks</Typography>
|
||||||
<h1>Purchased Augmentations</h1>
|
<br />
|
||||||
<p>
|
<Typography>
|
||||||
Below is a list of all Augmentations you have purchased but not yet installed. Click the button below to
|
Installing Augmentations lets you start over with the perks and benefits granted by all of the Augmentations you
|
||||||
install them.
|
have ever installed. Also, you will keep any scripts and RAM/Core upgrades on your home computer (but you will
|
||||||
</p>
|
lose all programs besides NUKE.exe)
|
||||||
<p>WARNING: Installing your Augmentations resets most of your progress, including:</p>
|
</Typography>
|
||||||
<br />
|
<Tooltip title={"'I never asked for this'"}>
|
||||||
<p>- Stats/Skill levels and Experience</p>
|
<Button onClick={props.installAugmentationsFn}>
|
||||||
<p>- Money</p>
|
<Typography>Install Augmentations</Typography>
|
||||||
<p>- Scripts on every computer but your home computer</p>
|
</Button>
|
||||||
<p>- Purchased servers</p>
|
</Tooltip>
|
||||||
<p>- Hacknet Nodes</p>
|
<Tooltip title={"It's always a good idea to backup/export your save!"}>
|
||||||
<p>- Faction/Company reputation</p>
|
<Button sx={{ mx: 2 }} onClick={doExport}>
|
||||||
<p>- Stocks</p>
|
<Typography color="error">Backup Save {exportBonusStr()}</Typography>
|
||||||
<br />
|
</Button>
|
||||||
<p>
|
</Tooltip>
|
||||||
Installing Augmentations lets you start over with the perks and benefits granted by all of the Augmentations
|
<PurchasedAugmentations />
|
||||||
you have ever installed. Also, you will keep any scripts and RAM/Core upgrades on your home computer (but
|
<Typography variant="h4">Installed Augmentations</Typography>
|
||||||
you will lose all programs besides NUKE.exe)
|
<Typography>List of all Augmentations that have been installed. You have gained the effects of these.</Typography>
|
||||||
</p>
|
<InstalledAugmentations />
|
||||||
<StdButton
|
<br /> <br />
|
||||||
onClick={this.props.installAugmentationsFn}
|
<PlayerMultipliers />
|
||||||
text="Install Augmentations"
|
<SourceFiles />
|
||||||
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!"
|
|
||||||
/>
|
|
||||||
<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 />
|
|
||||||
<br /> <br />
|
|
||||||
<PlayerMultipliers />
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,19 +1,31 @@
|
|||||||
/**
|
/**
|
||||||
* React Component for displaying a list of the player's installed Augmentations
|
* React Component for displaying all of the player's installed Augmentations and
|
||||||
* on the Augmentations UI
|
* 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 { Augmentations } from "../../Augmentation/Augmentations";
|
||||||
import { AugmentationNames } from "../../Augmentation/data/AugmentationNames";
|
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 {
|
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) {
|
if (Settings.OwnedAugmentationsOrder === OwnedAugmentationsOrderSetting.Alphabetically) {
|
||||||
sourceAugs.sort((aug1, aug2) => {
|
sourceAugs.sort((aug1, aug2) => {
|
||||||
@ -21,20 +33,42 @@ export function InstalledAugmentations(): React.ReactElement {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const augs = sourceAugs.map((e) => {
|
function rerender(): void {
|
||||||
const aug = Augmentations[e.name];
|
setRerender((old) => !old);
|
||||||
|
}
|
||||||
|
|
||||||
let level = null;
|
function sortByAcquirementTime(): void {
|
||||||
if (e.name === AugmentationNames.NeuroFluxGovernor) {
|
Settings.OwnedAugmentationsOrder = OwnedAugmentationsOrderSetting.AcquirementTime;
|
||||||
level = e.level;
|
rerender();
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
function sortInOrder(): void {
|
||||||
<li key={e.name}>
|
Settings.OwnedAugmentationsOrder = OwnedAugmentationsOrderSetting.Alphabetically;
|
||||||
<AugmentationAccordion aug={aug} level={level} />
|
rerender();
|
||||||
</li>
|
}
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
return <>{augs}</>;
|
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;
|
||||||
|
if (e.name === AugmentationNames.NeuroFluxGovernor) {
|
||||||
|
level = e.level;
|
||||||
|
}
|
||||||
|
|
||||||
|
return <AugmentationAccordion key={aug.name} aug={aug} level={level} />;
|
||||||
|
})}
|
||||||
|
</List>
|
||||||
|
</>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
@ -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,20 +20,18 @@ export function OwnedSourceFiles(): React.ReactElement {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const sfs = sourceSfs.map((e) => {
|
return (
|
||||||
const srcFileKey = "SourceFile" + e.n;
|
<>
|
||||||
const sfObj = SourceFiles[srcFileKey];
|
{sourceSfs.map((e) => {
|
||||||
if (sfObj == null) {
|
const srcFileKey = "SourceFile" + e.n;
|
||||||
console.error(`Invalid source file number: ${e.n}`);
|
const sfObj = SourceFiles[srcFileKey];
|
||||||
return null;
|
if (sfObj == null) {
|
||||||
}
|
console.error(`Invalid source file number: ${e.n}`);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return <SourceFileAccordion key={e.n} level={e.lvl} sf={sfObj} />;
|
||||||
<li key={e.n}>
|
})}
|
||||||
<SourceFileAccordion level={e.lvl} sf={sfObj} />
|
</>
|
||||||
</li>
|
);
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
return <>{sfs}</>;
|
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,11 @@ import * as React from "react";
|
|||||||
import { Player } from "../../Player";
|
import { Player } from "../../Player";
|
||||||
import { numeralWrapper } from "../../ui/numeralFormat";
|
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||||
import { Augmentations } from "../Augmentations";
|
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 {
|
function calculateAugmentedStats(): any {
|
||||||
const augP: any = {};
|
const augP: any = {};
|
||||||
@ -19,62 +24,74 @@ function calculateAugmentedStats(): any {
|
|||||||
return augP;
|
return augP;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function PlayerMultipliers(): React.ReactElement {
|
function Improvements({ r }: { r: number }): React.ReactElement {
|
||||||
const mults = calculateAugmentedStats();
|
if (r) {
|
||||||
function MultiplierTable(rows: any[]): React.ReactElement {
|
console.log(r);
|
||||||
function improvements(r: number): JSX.Element[] {
|
|
||||||
let elems: JSX.Element[] = [];
|
|
||||||
if (r) {
|
|
||||||
elems = [<td key="2"> {"=>"} </td>, <td key="3">{numeralWrapper.formatPercentage(r)}</td>];
|
|
||||||
}
|
|
||||||
return elems;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<table>
|
<>
|
||||||
<tbody>
|
<TableCell key="2">
|
||||||
{rows.map((r: any) => (
|
<Typography> {"=>"} </Typography>
|
||||||
<tr key={r[0]}>
|
</TableCell>
|
||||||
<td key="0">
|
<TableCell key="3">
|
||||||
<span>{r[0]} multiplier: </span>
|
<Typography>{numeralWrapper.formatPercentage(r)}</Typography>
|
||||||
</td>
|
</TableCell>
|
||||||
<td key="1" style={{ textAlign: "right" }}>
|
</>
|
||||||
{numeralWrapper.formatPercentage(r[1])}
|
|
||||||
</td>
|
|
||||||
{improvements(r[2])}
|
|
||||||
</tr>
|
|
||||||
))}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
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 {
|
function BladeburnerMults(): React.ReactElement {
|
||||||
if (!Player.canAccessBladeburner()) return <></>;
|
if (!Player.canAccessBladeburner()) return <></>;
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{MultiplierTable([
|
<MultiplierTable
|
||||||
[
|
rows={[
|
||||||
"Bladeburner Success Chance",
|
[
|
||||||
Player.bladeburner_success_chance_mult,
|
"Bladeburner Success Chance",
|
||||||
Player.bladeburner_success_chance_mult * mults.bladeburner_success_chance_mult,
|
Player.bladeburner_success_chance_mult,
|
||||||
],
|
Player.bladeburner_success_chance_mult * mults.bladeburner_success_chance_mult,
|
||||||
[
|
],
|
||||||
"Bladeburner Max Stamina",
|
[
|
||||||
Player.bladeburner_max_stamina_mult,
|
"Bladeburner Max Stamina",
|
||||||
Player.bladeburner_max_stamina_mult * mults.bladeburner_max_stamina_mult,
|
Player.bladeburner_max_stamina_mult,
|
||||||
],
|
Player.bladeburner_max_stamina_mult * mults.bladeburner_max_stamina_mult,
|
||||||
[
|
],
|
||||||
"Bladeburner Stamina Gain",
|
[
|
||||||
Player.bladeburner_stamina_gain_mult,
|
"Bladeburner Stamina Gain",
|
||||||
Player.bladeburner_stamina_gain_mult * mults.bladeburner_stamina_gain_mult,
|
Player.bladeburner_stamina_gain_mult,
|
||||||
],
|
Player.bladeburner_stamina_gain_mult * mults.bladeburner_stamina_gain_mult,
|
||||||
[
|
],
|
||||||
"Bladeburner Field Analysis",
|
[
|
||||||
Player.bladeburner_analysis_mult,
|
"Bladeburner Field Analysis",
|
||||||
Player.bladeburner_analysis_mult * mults.bladeburner_analysis_mult,
|
Player.bladeburner_analysis_mult,
|
||||||
],
|
Player.bladeburner_analysis_mult * mults.bladeburner_analysis_mult,
|
||||||
])}
|
],
|
||||||
|
]}
|
||||||
|
/>
|
||||||
<br />
|
<br />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
@ -88,90 +105,110 @@ export function PlayerMultipliers(): React.ReactElement {
|
|||||||
</strong>
|
</strong>
|
||||||
</p>
|
</p>
|
||||||
<br />
|
<br />
|
||||||
{MultiplierTable([
|
<MultiplierTable
|
||||||
["Hacking Chance ", Player.hacking_chance_mult, Player.hacking_chance_mult * mults.hacking_chance_mult],
|
rows={[
|
||||||
["Hacking Speed ", Player.hacking_speed_mult, Player.hacking_speed_mult * mults.hacking_speed_mult],
|
["Hacking Chance ", Player.hacking_chance_mult, Player.hacking_chance_mult * mults.hacking_chance_mult],
|
||||||
["Hacking Money ", Player.hacking_money_mult, Player.hacking_money_mult * mults.hacking_money_mult],
|
["Hacking Speed ", Player.hacking_speed_mult, Player.hacking_speed_mult * mults.hacking_speed_mult],
|
||||||
["Hacking Growth ", Player.hacking_grow_mult, Player.hacking_grow_mult * mults.hacking_grow_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 />
|
<br />
|
||||||
|
|
||||||
{MultiplierTable([
|
<MultiplierTable
|
||||||
["Hacking Level ", Player.hacking_mult, Player.hacking_mult * mults.hacking_mult],
|
rows={[
|
||||||
["Hacking Experience ", Player.hacking_exp_mult, Player.hacking_exp_mult * mults.hacking_exp_mult],
|
["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 />
|
<br />
|
||||||
|
|
||||||
{MultiplierTable([
|
<MultiplierTable
|
||||||
["Strength Level ", Player.strength_mult, Player.strength_mult * mults.strength_mult],
|
rows={[
|
||||||
["Strength Experience ", Player.strength_exp_mult, Player.strength_exp_mult * mults.strength_exp_mult],
|
["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 />
|
<br />
|
||||||
|
|
||||||
{MultiplierTable([
|
<MultiplierTable
|
||||||
["Defense Level ", Player.defense_mult, Player.defense_mult * mults.defense_mult],
|
rows={[
|
||||||
["Defense Experience ", Player.defense_exp_mult, Player.defense_exp_mult * mults.defense_exp_mult],
|
["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 />
|
<br />
|
||||||
|
|
||||||
{MultiplierTable([
|
<MultiplierTable
|
||||||
["Dexterity Level ", Player.dexterity_mult, Player.dexterity_mult * mults.dexterity_mult],
|
rows={[
|
||||||
["Dexterity Experience ", Player.dexterity_exp_mult, Player.dexterity_exp_mult * mults.dexterity_exp_mult],
|
["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 />
|
<br />
|
||||||
|
|
||||||
{MultiplierTable([
|
<MultiplierTable
|
||||||
["Agility Level ", Player.agility_mult, Player.agility_mult * mults.agility_mult],
|
rows={[
|
||||||
["Agility Experience ", Player.agility_exp_mult, Player.agility_exp_mult * mults.agility_exp_mult],
|
["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 />
|
<br />
|
||||||
|
|
||||||
{MultiplierTable([
|
<MultiplierTable
|
||||||
["Charisma Level ", Player.charisma_mult, Player.charisma_mult * mults.charisma_mult],
|
rows={[
|
||||||
["Charisma Experience ", Player.charisma_exp_mult, Player.charisma_exp_mult * mults.charisma_exp_mult],
|
["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 />
|
<br />
|
||||||
|
|
||||||
{MultiplierTable([
|
<MultiplierTable
|
||||||
[
|
rows={[
|
||||||
"Hacknet Node production ",
|
[
|
||||||
Player.hacknet_node_money_mult,
|
"Hacknet Node production ",
|
||||||
Player.hacknet_node_money_mult * mults.hacknet_node_money_mult,
|
Player.hacknet_node_money_mult,
|
||||||
],
|
Player.hacknet_node_money_mult * mults.hacknet_node_money_mult,
|
||||||
[
|
],
|
||||||
"Hacknet Node purchase cost ",
|
[
|
||||||
Player.hacknet_node_purchase_cost_mult,
|
"Hacknet Node purchase cost ",
|
||||||
Player.hacknet_node_purchase_cost_mult * mults.hacknet_node_purchase_cost_mult,
|
Player.hacknet_node_purchase_cost_mult,
|
||||||
],
|
Player.hacknet_node_purchase_cost_mult * mults.hacknet_node_purchase_cost_mult,
|
||||||
[
|
],
|
||||||
"Hacknet Node RAM upgrade cost ",
|
[
|
||||||
Player.hacknet_node_ram_cost_mult,
|
"Hacknet Node RAM upgrade cost ",
|
||||||
Player.hacknet_node_ram_cost_mult * mults.hacknet_node_ram_cost_mult,
|
Player.hacknet_node_ram_cost_mult,
|
||||||
],
|
Player.hacknet_node_ram_cost_mult * mults.hacknet_node_ram_cost_mult,
|
||||||
[
|
],
|
||||||
"Hacknet Node Core purchase cost ",
|
[
|
||||||
Player.hacknet_node_core_cost_mult,
|
"Hacknet Node Core purchase cost ",
|
||||||
Player.hacknet_node_core_cost_mult * mults.hacknet_node_core_cost_mult,
|
Player.hacknet_node_core_cost_mult,
|
||||||
],
|
Player.hacknet_node_core_cost_mult * mults.hacknet_node_core_cost_mult,
|
||||||
[
|
],
|
||||||
"Hacknet Node level upgrade cost ",
|
[
|
||||||
Player.hacknet_node_level_cost_mult,
|
"Hacknet Node level upgrade cost ",
|
||||||
Player.hacknet_node_level_cost_mult * mults.hacknet_node_level_cost_mult,
|
Player.hacknet_node_level_cost_mult,
|
||||||
],
|
Player.hacknet_node_level_cost_mult * mults.hacknet_node_level_cost_mult,
|
||||||
])}
|
],
|
||||||
|
]}
|
||||||
|
/>
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
{MultiplierTable([
|
<MultiplierTable
|
||||||
["Company reputation gain ", Player.company_rep_mult, Player.company_rep_mult * mults.company_rep_mult],
|
rows={[
|
||||||
["Faction reputation gain ", Player.faction_rep_mult, Player.faction_rep_mult * mults.faction_rep_mult],
|
["Company reputation gain ", Player.company_rep_mult, Player.company_rep_mult * mults.company_rep_mult],
|
||||||
["Salary ", Player.work_money_mult, Player.work_money_mult * mults.work_money_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 />
|
<br />
|
||||||
|
|
||||||
{MultiplierTable([
|
<MultiplierTable
|
||||||
["Crime success ", Player.crime_success_mult, Player.crime_success_mult * mults.crime_success_mult],
|
rows={[
|
||||||
["Crime money ", Player.crime_money_mult, Player.crime_money_mult * mults.crime_money_mult],
|
["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 />
|
<br />
|
||||||
|
|
||||||
<BladeburnerMults />
|
<BladeburnerMults />
|
||||||
|
@ -9,6 +9,7 @@ import { AugmentationNames } from "../../Augmentation/data/AugmentationNames";
|
|||||||
import { Player } from "../../Player";
|
import { Player } from "../../Player";
|
||||||
|
|
||||||
import { AugmentationAccordion } from "../../ui/React/AugmentationAccordion";
|
import { AugmentationAccordion } from "../../ui/React/AugmentationAccordion";
|
||||||
|
import List from "@mui/material/List";
|
||||||
|
|
||||||
export function PurchasedAugmentations(): React.ReactElement {
|
export function PurchasedAugmentations(): React.ReactElement {
|
||||||
const augs: React.ReactElement[] = [];
|
const augs: React.ReactElement[] = [];
|
||||||
@ -29,12 +30,8 @@ export function PurchasedAugmentations(): React.ReactElement {
|
|||||||
level = ownedAug.level;
|
level = ownedAug.level;
|
||||||
}
|
}
|
||||||
|
|
||||||
augs.push(
|
augs.push(<AugmentationAccordion key={aug.name} aug={aug} level={level} />);
|
||||||
<li key={`${ownedAug.name}${ownedAug.level}`}>
|
|
||||||
<AugmentationAccordion aug={aug} level={level} />
|
|
||||||
</li>,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
* React Component for displaying a list of the player's Source-Files
|
||||||
* on the Augmentations UI
|
* on the Augmentations UI
|
||||||
*/
|
*/
|
||||||
import * as React from "react";
|
import React, { useState } from "react";
|
||||||
|
|
||||||
import { Player } from "../../Player";
|
import { Player } from "../../Player";
|
||||||
import { Exploit, ExploitName } from "../../Exploits/Exploit";
|
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 {
|
export function SourceFileMinus1(): React.ReactElement {
|
||||||
|
const [open, setOpen] = useState(false);
|
||||||
const exploits = Player.exploits;
|
const exploits = Player.exploits;
|
||||||
|
|
||||||
if (exploits.length === 0) {
|
if (exploits.length === 0) {
|
||||||
@ -17,33 +25,35 @@ export function SourceFileMinus1(): React.ReactElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<li key={-1}>
|
<Box component={Paper}>
|
||||||
<BBAccordion
|
<ListItemButton onClick={() => setOpen((old) => !old)}>
|
||||||
headerContent={
|
<ListItemText
|
||||||
<>
|
primary={
|
||||||
Source-File -1: Exploits in the BitNodes
|
<Typography style={{ whiteSpace: "pre-wrap" }}>
|
||||||
<br />
|
Source-File -1: Exploits in the BitNodes
|
||||||
Level {exploits.length} / ?
|
<br />
|
||||||
</>
|
Level {exploits.length} / ?
|
||||||
}
|
</Typography>
|
||||||
panelContent={
|
}
|
||||||
<>
|
/>
|
||||||
<p>
|
{open ? <ExpandLess color="primary" /> : <ExpandMore color="primary" />}
|
||||||
This Source-File can only be acquired with obscure knowledge of the game, javascript, and the web
|
</ListItemButton>
|
||||||
ecosystem.
|
<Collapse in={open} unmountOnExit>
|
||||||
</p>
|
<Box m={4}>
|
||||||
<p>It increases all of the player's multipliers by 0.1%</p>
|
<Typography>
|
||||||
<br />
|
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 />
|
||||||
|
|
||||||
<p>You have found the following exploits:</p>
|
<Typography>You have found the following exploits:</Typography>
|
||||||
<ul>
|
<Box mx={2}>
|
||||||
{exploits.map((c: Exploit) => (
|
{exploits.map((c: Exploit) => (
|
||||||
<li key={c}>* {ExploitName(c)}</li>
|
<Typography key={c}>* {ExploitName(c)}</Typography>
|
||||||
))}
|
))}
|
||||||
</ul>
|
</Box>
|
||||||
</>
|
</Box>
|
||||||
}
|
</Collapse>
|
||||||
/>
|
</Box>
|
||||||
</li>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
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 = renderToStaticMarkup(tooltip);
|
||||||
}
|
}
|
||||||
tooltip += "<br /><br />";
|
tooltip += "<br /><br />";
|
||||||
tooltip += renderToStaticMarkup(aug.stats);
|
tooltip += renderToStaticMarkup(aug.stats || <></>);
|
||||||
return (
|
return (
|
||||||
<div key={augName} className="gang-owned-upgrade tooltip">
|
<div key={augName} className="gang-owned-upgrade tooltip">
|
||||||
{augName}
|
{augName}
|
||||||
@ -70,7 +70,7 @@ export function SleeveAugmentationsPopup(props: IProps): React.ReactElement {
|
|||||||
info = renderToStaticMarkup(info);
|
info = renderToStaticMarkup(info);
|
||||||
}
|
}
|
||||||
info += "<br /><br />";
|
info += "<br /><br />";
|
||||||
info += renderToStaticMarkup(aug.stats);
|
info += renderToStaticMarkup(aug.stats || <></>);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div key={aug.name} className="cmpy-mgmt-upgrade-div" onClick={() => purchaseAugmentation(aug)}>
|
<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 {string} code - The new contents of the script
|
||||||
* @param {Script[]} otherScripts - Other scripts on the server. Used to process imports
|
* @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
|
// Update code and filename
|
||||||
this.code = code.replace(/^\s+|\s+$/g, "");
|
this.code = code.replace(/^\s+|\s+$/g, "");
|
||||||
|
|
||||||
const filenameElem: HTMLInputElement | null = document.getElementById("script-editor-filename") as HTMLInputElement;
|
this.filename = filename;
|
||||||
if (filenameElem == null) {
|
|
||||||
console.error(`Failed to get Script filename DOM element`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.filename = filenameElem.value;
|
|
||||||
this.server = serverIp;
|
this.server = serverIp;
|
||||||
this.updateRamUsage(otherScripts);
|
this.updateRamUsage(otherScripts);
|
||||||
this.markUpdated();
|
this.markUpdated();
|
||||||
|
@ -130,14 +130,14 @@ export function Root(props: IProps): React.ReactElement {
|
|||||||
let found = false;
|
let found = false;
|
||||||
for (let i = 0; i < server.scripts.length; i++) {
|
for (let i = 0; i < server.scripts.length; i++) {
|
||||||
if (filename == server.scripts[i].filename) {
|
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;
|
found = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!found) {
|
if (!found) {
|
||||||
const script = new Script();
|
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);
|
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
|
//If the current script already exists on the server, overwrite it
|
||||||
for (let i = 0; i < server.scripts.length; i++) {
|
for (let i = 0; i < server.scripts.length; i++) {
|
||||||
if (filename == server.scripts[i].filename) {
|
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();
|
props.router.toTerminal();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -173,7 +173,7 @@ export function Root(props: IProps): React.ReactElement {
|
|||||||
|
|
||||||
//If the current script does NOT exist, create a new one
|
//If the current script does NOT exist, create a new one
|
||||||
const script = new Script();
|
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);
|
server.scripts.push(script);
|
||||||
} else if (filename.endsWith(".txt")) {
|
} else if (filename.endsWith(".txt")) {
|
||||||
for (let i = 0; i < server.textFiles.length; ++i) {
|
for (let i = 0; i < server.textFiles.length; ++i) {
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
import { BitNodes } from "../BitNode/BitNode";
|
import { BitNodes } from "../BitNode/BitNode";
|
||||||
|
|
||||||
export class SourceFile {
|
export class SourceFile {
|
||||||
info: string;
|
info: JSX.Element;
|
||||||
lvl = 1;
|
lvl = 1;
|
||||||
n: number;
|
n: number;
|
||||||
name: string;
|
name: string;
|
||||||
owned = false;
|
owned = false;
|
||||||
|
|
||||||
constructor(number: number, info = "") {
|
constructor(number: number, info: JSX.Element) {
|
||||||
const bitnodeKey = "BitNode" + number;
|
const bitnodeKey = "BitNode" + number;
|
||||||
const bitnode = BitNodes[bitnodeKey];
|
const bitnode = BitNodes[bitnodeKey];
|
||||||
if (bitnode == null) {
|
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
|
* The header of the accordion contains the Augmentation's name (and level, if
|
||||||
* applicable), and the accordion's panel contains the Augmentation's description.
|
* applicable), and the accordion's panel contains the Augmentation's description.
|
||||||
*/
|
*/
|
||||||
import * as React from "react";
|
import React, { useState } from "react";
|
||||||
|
|
||||||
import { BBAccordion } from "./BBAccordion";
|
|
||||||
|
|
||||||
import { Augmentation } from "../../Augmentation/Augmentation";
|
import { Augmentation } from "../../Augmentation/Augmentation";
|
||||||
import { AugmentationNames } from "../../Augmentation/data/AugmentationNames";
|
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 = {
|
type IProps = {
|
||||||
aug: Augmentation;
|
aug: Augmentation;
|
||||||
@ -17,6 +23,7 @@ type IProps = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export function AugmentationAccordion(props: IProps): React.ReactElement {
|
export function AugmentationAccordion(props: IProps): React.ReactElement {
|
||||||
|
const [open, setOpen] = useState(false);
|
||||||
let displayName = props.aug.name;
|
let displayName = props.aug.name;
|
||||||
if (props.level != null) {
|
if (props.level != null) {
|
||||||
if (props.aug.name === AugmentationNames.NeuroFluxGovernor) {
|
if (props.aug.name === AugmentationNames.NeuroFluxGovernor) {
|
||||||
@ -26,31 +33,47 @@ export function AugmentationAccordion(props: IProps): React.ReactElement {
|
|||||||
|
|
||||||
if (typeof props.aug.info === "string") {
|
if (typeof props.aug.info === "string") {
|
||||||
return (
|
return (
|
||||||
<BBAccordion
|
<Box component={Paper}>
|
||||||
headerContent={<>{displayName}</>}
|
<ListItemButton onClick={() => setOpen((old) => !old)}>
|
||||||
panelContent={
|
<ListItemText primary={<Typography style={{ whiteSpace: "pre-wrap" }}>{displayName}</Typography>} />
|
||||||
<p>
|
{open ? <ExpandLess color="primary" /> : <ExpandMore color="primary" />}
|
||||||
<span dangerouslySetInnerHTML={{ __html: props.aug.info }} />
|
</ListItemButton>
|
||||||
<br />
|
<Collapse in={open} unmountOnExit>
|
||||||
<br />
|
<Box m={4}>
|
||||||
{props.aug.stats}
|
<Typography dangerouslySetInnerHTML={{ __html: props.aug.info }} />
|
||||||
</p>
|
{props.aug.stats && (
|
||||||
}
|
<>
|
||||||
/>
|
<br />
|
||||||
|
<br />
|
||||||
|
<Typography>{props.aug.stats}</Typography>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
|
</Collapse>
|
||||||
|
</Box>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<BBAccordion
|
<Box component={Paper}>
|
||||||
headerContent={<>{displayName}</>}
|
<ListItemButton onClick={() => setOpen((old) => !old)}>
|
||||||
panelContent={
|
<ListItemText primary={<Typography style={{ whiteSpace: "pre-wrap" }}>{displayName}</Typography>} />
|
||||||
<p>
|
{open ? <ExpandLess color="primary" /> : <ExpandMore color="primary" />}
|
||||||
{props.aug.info}
|
</ListItemButton>
|
||||||
<br />
|
<Collapse in={open} unmountOnExit>
|
||||||
<br />
|
<Box m={4}>
|
||||||
{props.aug.stats}
|
<Typography>
|
||||||
</p>
|
{props.aug.info}
|
||||||
}
|
{props.aug.stats && (
|
||||||
/>
|
<>
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
{props.aug.stats}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
</Collapse>
|
||||||
|
</Box>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -4,30 +4,47 @@
|
|||||||
* The header of the accordion contains the Source-Files's name and level,
|
* The header of the accordion contains the Source-Files's name and level,
|
||||||
* and the accordion's panel contains the Source-File's description.
|
* and the accordion's panel contains the Source-File's description.
|
||||||
*/
|
*/
|
||||||
import * as React from "react";
|
import React, { useState } from "react";
|
||||||
|
|
||||||
import { BBAccordion } from "./BBAccordion";
|
|
||||||
|
|
||||||
import { SourceFile } from "../../SourceFile/SourceFile";
|
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 = {
|
type IProps = {
|
||||||
level: number;
|
level: number;
|
||||||
sf: SourceFile;
|
sf: SourceFile;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function SourceFileAccordion(props: IProps): React.ReactElement {
|
export function SourceFileAccordion(props: IProps): React.ReactElement {
|
||||||
|
const [open, setOpen] = useState(false);
|
||||||
const maxLevel = props.sf.n === 12 ? "∞" : "3";
|
const maxLevel = props.sf.n === 12 ? "∞" : "3";
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<BBAccordion
|
<Box component={Paper}>
|
||||||
headerContent={
|
<ListItemButton onClick={() => setOpen((old) => !old)}>
|
||||||
<>
|
<ListItemText
|
||||||
{props.sf.name}
|
primary={
|
||||||
<br />
|
<Typography style={{ whiteSpace: "pre-wrap" }}>
|
||||||
{`Level ${props.level} / ${maxLevel}`}
|
{props.sf.name}
|
||||||
</>
|
<br />
|
||||||
}
|
{`Level ${props.level} / ${maxLevel}`}
|
||||||
panelContent={<p dangerouslySetInnerHTML={{ __html: props.sf.info }}></p>}
|
</Typography>
|
||||||
/>
|
}
|
||||||
|
/>
|
||||||
|
{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