mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2026-04-16 06:18:42 +02:00
2nd commit
This commit is contained in:
12
src/Hacknet/ui/Components/HacknetExpenses.tsx
Normal file
12
src/Hacknet/ui/Components/HacknetExpenses.tsx
Normal file
@@ -0,0 +1,12 @@
|
||||
import React from "react";
|
||||
|
||||
import { PlayerObject } from "../../../PersonObjects/Player/PlayerObject";
|
||||
import { Money } from "../../../ui/React/Money";
|
||||
import { usePlayerSelector } from "../../../utils/PlayerExternalStore";
|
||||
|
||||
const selectHacknetExpenses = (p: PlayerObject) => -p.moneySourceA.hacknet_expenses || 0;
|
||||
|
||||
export function HacknetExpenses(): React.ReactElement {
|
||||
const spent = usePlayerSelector(selectHacknetExpenses);
|
||||
return <Money key="money" money={spent} />;
|
||||
}
|
||||
11
src/Hacknet/ui/Components/HacknetProduced.tsx
Normal file
11
src/Hacknet/ui/Components/HacknetProduced.tsx
Normal file
@@ -0,0 +1,11 @@
|
||||
import React from "react";
|
||||
import { PlayerObject } from "../../../PersonObjects/Player/PlayerObject";
|
||||
import { Money } from "../../../ui/React/Money";
|
||||
import { usePlayerSelector } from "../../../utils/PlayerExternalStore";
|
||||
|
||||
const selectHacknetMoney = (p: PlayerObject) => p.moneySourceA.hacknet;
|
||||
|
||||
export function HacknetProduced(): React.ReactElement {
|
||||
const produced = usePlayerSelector(selectHacknetMoney);
|
||||
return <Money key="money" money={produced} />;
|
||||
}
|
||||
16
src/Hacknet/ui/Components/HacknetServerLevel.tsx
Normal file
16
src/Hacknet/ui/Components/HacknetServerLevel.tsx
Normal file
@@ -0,0 +1,16 @@
|
||||
import React from "react";
|
||||
import { useCallback } from "react";
|
||||
import { PlayerObject } from "../../../PersonObjects/Player/PlayerObject";
|
||||
import { usePlayerSelector } from "../../../utils/PlayerExternalStore";
|
||||
import { safeGetHacknetServer } from "../utils";
|
||||
|
||||
interface IProps {
|
||||
index: number;
|
||||
}
|
||||
|
||||
export function HacknetServerLevel({ index }: IProps): React.ReactElement {
|
||||
const level = usePlayerSelector(
|
||||
useCallback((p: PlayerObject) => safeGetHacknetServer(p, index)?.level ?? "???", [index]),
|
||||
);
|
||||
return <>{level}</>;
|
||||
}
|
||||
34
src/Hacknet/ui/Components/HashTotalProduction.tsx
Normal file
34
src/Hacknet/ui/Components/HashTotalProduction.tsx
Normal file
@@ -0,0 +1,34 @@
|
||||
import React from "react";
|
||||
import { hasHacknetServers } from "../../../Hacknet/HacknetHelpers";
|
||||
import { HacknetNode } from "../../../Hacknet/HacknetNode";
|
||||
import { HacknetServer } from "../../../Hacknet/HacknetServer";
|
||||
import { PlayerObject } from "../../../PersonObjects/Player/PlayerObject";
|
||||
import { GetServer } from "../../../Server/AllServers";
|
||||
import { usePlayerSelector } from "../../../utils/PlayerExternalStore";
|
||||
import { HashRate } from "../../../ui/React/HashRate";
|
||||
|
||||
const selectTotalProduction = (p: PlayerObject) => {
|
||||
let totalProduction = 0;
|
||||
for (let i = 0; i < p.hacknetNodes.length; ++i) {
|
||||
const node = p.hacknetNodes[i];
|
||||
if (hasHacknetServers()) {
|
||||
if (node instanceof HacknetNode) throw new Error("node was hacknet node"); // should never happen
|
||||
const hserver = GetServer(node);
|
||||
if (!(hserver instanceof HacknetServer)) throw new Error("node was not hacknet server"); // should never happen
|
||||
if (hserver) {
|
||||
totalProduction += hserver.hashRate;
|
||||
} else {
|
||||
console.warn(`Could not find Hacknet Server object in AllServers map (i=${i})`);
|
||||
}
|
||||
} else {
|
||||
if (typeof node === "string") throw new Error("node was ip string"); // should never happen
|
||||
totalProduction += node.moneyGainRatePerSecond;
|
||||
}
|
||||
}
|
||||
return totalProduction;
|
||||
};
|
||||
|
||||
export function HashTotalProduction(): React.ReactElement {
|
||||
const prod = usePlayerSelector(selectTotalProduction);
|
||||
return <HashRate key="hashRate" hashes={prod} />;
|
||||
}
|
||||
17
src/Hacknet/ui/Components/MoneyButton.tsx
Normal file
17
src/Hacknet/ui/Components/MoneyButton.tsx
Normal file
@@ -0,0 +1,17 @@
|
||||
import React from "react";
|
||||
import { Button, ButtonProps } from "@mui/material";
|
||||
import { usePlayerSelector } from "../../../utils/PlayerExternalStore";
|
||||
import { PlayerObject } from "../../../PersonObjects/Player/PlayerObject";
|
||||
|
||||
type MoneyButtonProps = {
|
||||
cost: number;
|
||||
} & ButtonProps;
|
||||
|
||||
export function MoneyButton(props: MoneyButtonProps): React.ReactElement {
|
||||
const canAfford = usePlayerSelector(React.useCallback((p: PlayerObject) => p.canAfford(props.cost), [props.cost]));
|
||||
return (
|
||||
<Button disabled={!canAfford || props.disabled} {...props}>
|
||||
{props.children}
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
25
src/Hacknet/ui/Components/MoneyCost.tsx
Normal file
25
src/Hacknet/ui/Components/MoneyCost.tsx
Normal file
@@ -0,0 +1,25 @@
|
||||
import * as React from "react";
|
||||
import { formatMoney } from "../../../ui/formatNumber";
|
||||
import type { Theme } from "@mui/material/styles";
|
||||
import { makeStyles } from "tss-react/mui";
|
||||
import { usePlayerSelector } from "../../../utils/PlayerExternalStore";
|
||||
import { PlayerObject } from "../../../PersonObjects/Player/PlayerObject";
|
||||
|
||||
const useStyles = makeStyles()((theme: Theme) => ({
|
||||
unbuyable: {
|
||||
color: theme.palette.action.disabled,
|
||||
},
|
||||
money: {
|
||||
color: theme.colors.money,
|
||||
},
|
||||
}));
|
||||
|
||||
interface IProps {
|
||||
cost: number;
|
||||
}
|
||||
|
||||
export function MoneyCost({ cost }: IProps): React.ReactElement {
|
||||
const { classes } = useStyles();
|
||||
const canAfford = usePlayerSelector(React.useCallback((p: PlayerObject) => p.canAfford(cost), [cost]));
|
||||
return <span className={canAfford ? classes.money : classes.unbuyable}>{formatMoney(cost)}</span>;
|
||||
}
|
||||
11
src/Hacknet/ui/Components/PlayerHashCapacity.tsx
Normal file
11
src/Hacknet/ui/Components/PlayerHashCapacity.tsx
Normal file
@@ -0,0 +1,11 @@
|
||||
import React from "react";
|
||||
import { PlayerObject } from "../../../PersonObjects/Player/PlayerObject";
|
||||
import { Hashes } from "../../../ui/React/Hashes";
|
||||
import { usePlayerSelector } from "../../../utils/PlayerExternalStore";
|
||||
|
||||
const selectHashCapacity = (p: PlayerObject) => p.hashManager.capacity;
|
||||
|
||||
export function PlayerHashCapacity(): React.ReactElement {
|
||||
const capacity = usePlayerSelector(selectHashCapacity);
|
||||
return <Hashes hashes={capacity} />;
|
||||
}
|
||||
11
src/Hacknet/ui/Components/PlayerHashes.tsx
Normal file
11
src/Hacknet/ui/Components/PlayerHashes.tsx
Normal file
@@ -0,0 +1,11 @@
|
||||
import React from "react";
|
||||
import { PlayerObject } from "../../../PersonObjects/Player/PlayerObject";
|
||||
import { Hashes } from "../../../ui/React/Hashes";
|
||||
import { usePlayerSelector } from "../../../utils/PlayerExternalStore";
|
||||
|
||||
const selectHashes = (p: PlayerObject) => p.hashManager.hashes;
|
||||
|
||||
export function PlayerHashes(): React.ReactElement {
|
||||
const hashes = usePlayerSelector(selectHashes);
|
||||
return <Hashes hashes={hashes} />;
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
import React, { useCallback } from "react";
|
||||
import { Button, Tooltip } from "@mui/material";
|
||||
import { HacknetServerConstants } from "../../data/Constants";
|
||||
import { PlayerObject } from "../../../PersonObjects/Player/PlayerObject";
|
||||
import { usePlayerSelector } from "../../../utils/PlayerExternalStore";
|
||||
import { getMaxNumberLevelUpgrades, purchaseLevelUpgrade } from "../../HacknetHelpers";
|
||||
import { Money } from "../../../ui/React/Money";
|
||||
import { UpgradeHacknetServerLevelTooltip } from "./UpgradeHacknetServerLevelTooltip";
|
||||
import { HacknetServer } from "../../HacknetServer";
|
||||
|
||||
interface IProps {
|
||||
node: HacknetServer;
|
||||
purchaseMult: number | string;
|
||||
}
|
||||
|
||||
const selectHacknetNodeLevelCost = (p: PlayerObject) => p.mults.hacknet_node_level_cost;
|
||||
const selectMoney = (p: PlayerObject) => p.money;
|
||||
|
||||
export function UpgradeHacknetServerLevelButton({ purchaseMult, node }: IProps): React.ReactElement {
|
||||
const level = usePlayerSelector(useCallback((): number => node.level, [node]));
|
||||
const hacknet_node_level_cost = usePlayerSelector(selectHacknetNodeLevelCost);
|
||||
usePlayerSelector(selectMoney); // we have to hook on money change for the max level algorithm
|
||||
|
||||
function upgradeLevelOnClick(): void {
|
||||
let numUpgrades = purchaseMult;
|
||||
if (purchaseMult === "MAX") {
|
||||
numUpgrades = getMaxNumberLevelUpgrades(node, HacknetServerConstants.MaxLevel);
|
||||
}
|
||||
purchaseLevelUpgrade(node, numUpgrades as number);
|
||||
}
|
||||
|
||||
if (level >= HacknetServerConstants.MaxLevel) {
|
||||
return <Button disabled>MAX LEVEL</Button>;
|
||||
} else {
|
||||
let multiplier = 0;
|
||||
if (purchaseMult === "MAX") {
|
||||
multiplier = getMaxNumberLevelUpgrades(node, HacknetServerConstants.MaxLevel);
|
||||
} else {
|
||||
const levelsToMax = HacknetServerConstants.MaxLevel - level;
|
||||
multiplier = Math.min(levelsToMax, purchaseMult as number);
|
||||
}
|
||||
|
||||
const upgradeLevelCost = node.calculateLevelUpgradeCost(multiplier, hacknet_node_level_cost) ?? 0;
|
||||
return (
|
||||
<Tooltip title={<UpgradeHacknetServerLevelTooltip purchaseMult={purchaseMult} node={node} />}>
|
||||
<Button onClick={upgradeLevelOnClick}>
|
||||
+{multiplier} -
|
||||
<Money money={upgradeLevelCost} forPurchase={true} />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
import { Typography } from "@mui/material";
|
||||
import React, { useCallback } from "react";
|
||||
import { calculateHashGainRate } from "../../formulas/HacknetServers";
|
||||
import { PlayerObject } from "../../../PersonObjects/Player/PlayerObject";
|
||||
import { HashRate } from "../../../ui/React/HashRate";
|
||||
import { arrayShallowEquals, usePlayerSelector } from "../../../utils/PlayerExternalStore";
|
||||
import { getMaxNumberLevelUpgrades } from "../../HacknetHelpers";
|
||||
import { HacknetServerConstants } from "../../data/Constants";
|
||||
import { HacknetServer } from "../../HacknetServer";
|
||||
|
||||
interface IProps {
|
||||
node: HacknetServer;
|
||||
purchaseMult: number | string;
|
||||
}
|
||||
|
||||
const selectHacknetNodeMoney = (p: PlayerObject) => p.mults.hacknet_node_money;
|
||||
|
||||
export function UpgradeHacknetServerLevelTooltip({ purchaseMult, node }: IProps): React.ReactElement {
|
||||
const [level, ramUsed, maxRam, cores] = usePlayerSelector(
|
||||
useCallback((): [number, number, number, number] => [node.level, node.ramUsed, node.maxRam, node.cores], [node]),
|
||||
arrayShallowEquals,
|
||||
);
|
||||
|
||||
const hacknetNodeMoney = usePlayerSelector(selectHacknetNodeMoney);
|
||||
|
||||
let multiplier = 0;
|
||||
if (purchaseMult === "MAX") {
|
||||
multiplier = getMaxNumberLevelUpgrades(node, HacknetServerConstants.MaxLevel);
|
||||
} else {
|
||||
const levelsToMax = HacknetServerConstants.MaxLevel - level;
|
||||
multiplier = Math.min(levelsToMax, purchaseMult as number);
|
||||
}
|
||||
|
||||
const base_increase =
|
||||
calculateHashGainRate(level + multiplier, 0, maxRam, cores, hacknetNodeMoney) -
|
||||
calculateHashGainRate(level, 0, maxRam, cores, hacknetNodeMoney);
|
||||
const modded_increase = (base_increase * (maxRam - ramUsed)) / maxRam;
|
||||
return (
|
||||
<Typography>
|
||||
+<HashRate hashes={modded_increase} /> (effective increase, taking current RAM usage into account)
|
||||
<br />
|
||||
<span style={{ opacity: 0.5 }}>
|
||||
+<HashRate hashes={base_increase} />
|
||||
</span>{" "}
|
||||
(base increase, attained when no script is running)
|
||||
</Typography>
|
||||
);
|
||||
}
|
||||
@@ -75,7 +75,7 @@ export function HacknetRoot(): React.ReactElement {
|
||||
];
|
||||
|
||||
// HacknetNode components
|
||||
const nodes = Player.hacknetNodes.map((node: string | HacknetNode) => {
|
||||
const nodes = Player.hacknetNodes.map((node: string | HacknetNode, index: number) => {
|
||||
if (hasHacknetServers()) {
|
||||
if (node instanceof HacknetNode) throw new Error("node was hacknet node"); // should never happen
|
||||
const hserver = GetServer(node);
|
||||
@@ -83,7 +83,14 @@ export function HacknetRoot(): React.ReactElement {
|
||||
throw new Error(`Could not find Hacknet Server object in AllServers map for IP: ${node}`);
|
||||
}
|
||||
if (!(hserver instanceof HacknetServer)) throw new Error("node was not hacknet server"); // should never happen
|
||||
return <HacknetServerElem key={hserver.hostname} node={hserver} purchaseMultiplier={purchaseMultiplier} />;
|
||||
return (
|
||||
<HacknetServerElem
|
||||
key={hserver.hostname}
|
||||
index={index}
|
||||
node={hserver}
|
||||
purchaseMultiplier={purchaseMultiplier}
|
||||
/>
|
||||
);
|
||||
} else {
|
||||
if (typeof node === "string") throw new Error("node was ip string"); // should never happen
|
||||
return <HacknetNodeElem key={node.name} node={node} purchaseMultiplier={purchaseMultiplier} />;
|
||||
|
||||
@@ -6,11 +6,9 @@ import React from "react";
|
||||
|
||||
import { HacknetServerConstants } from "../data/Constants";
|
||||
import {
|
||||
getMaxNumberLevelUpgrades,
|
||||
getMaxNumberRamUpgrades,
|
||||
getMaxNumberCoreUpgrades,
|
||||
getMaxNumberCacheUpgrades,
|
||||
purchaseLevelUpgrade,
|
||||
purchaseRamUpgrade,
|
||||
purchaseCoreUpgrade,
|
||||
purchaseCacheUpgrade,
|
||||
@@ -34,8 +32,11 @@ import TableRow from "@mui/material/TableRow";
|
||||
import { formatRam } from "../../ui/formatNumber";
|
||||
import { calculateHashGainRate } from "../formulas/HacknetServers";
|
||||
import Tooltip from "@mui/material/Tooltip";
|
||||
import { HacknetServerLevel } from "./Components/HacknetServerLevel";
|
||||
import { UpgradeHacknetServerLevelButton } from "./Components/UpgradeHacknetServerLevelButton";
|
||||
|
||||
interface IProps {
|
||||
index: number;
|
||||
node: HacknetServer;
|
||||
purchaseMultiplier: number | string;
|
||||
}
|
||||
@@ -43,53 +44,7 @@ interface IProps {
|
||||
export function HacknetServerElem(props: IProps): React.ReactElement {
|
||||
const node = props.node;
|
||||
const purchaseMult = props.purchaseMultiplier;
|
||||
|
||||
// Upgrade Level Button
|
||||
let upgradeLevelButton;
|
||||
if (node.level >= HacknetServerConstants.MaxLevel) {
|
||||
upgradeLevelButton = <Button disabled>MAX LEVEL</Button>;
|
||||
} else {
|
||||
let multiplier = 0;
|
||||
if (purchaseMult === "MAX") {
|
||||
multiplier = getMaxNumberLevelUpgrades(node, HacknetServerConstants.MaxLevel);
|
||||
} else {
|
||||
const levelsToMax = HacknetServerConstants.MaxLevel - node.level;
|
||||
multiplier = Math.min(levelsToMax, purchaseMult as number);
|
||||
}
|
||||
|
||||
const base_increase =
|
||||
calculateHashGainRate(node.level + multiplier, 0, node.maxRam, node.cores, Player.mults.hacknet_node_money) -
|
||||
calculateHashGainRate(node.level, 0, node.maxRam, node.cores, Player.mults.hacknet_node_money);
|
||||
const modded_increase = (base_increase * (node.maxRam - node.ramUsed)) / node.maxRam;
|
||||
|
||||
const upgradeLevelCost = node.calculateLevelUpgradeCost(multiplier, Player.mults.hacknet_node_level_cost);
|
||||
upgradeLevelButton = (
|
||||
<Tooltip
|
||||
title={
|
||||
<Typography>
|
||||
+<HashRate hashes={modded_increase} /> (effective increase, taking current RAM usage into account)
|
||||
<br />
|
||||
<span style={{ opacity: 0.5 }}>
|
||||
+<HashRate hashes={base_increase} />
|
||||
</span>{" "}
|
||||
(base increase, attained when no script is running)
|
||||
</Typography>
|
||||
}
|
||||
>
|
||||
<Button onClick={upgradeLevelOnClick}>
|
||||
+{multiplier} -
|
||||
<Money money={upgradeLevelCost} forPurchase={true} />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
function upgradeLevelOnClick(): void {
|
||||
let numUpgrades = purchaseMult;
|
||||
if (purchaseMult === "MAX") {
|
||||
numUpgrades = getMaxNumberLevelUpgrades(node, HacknetServerConstants.MaxLevel);
|
||||
}
|
||||
purchaseLevelUpgrade(node, numUpgrades as number);
|
||||
}
|
||||
const index = props.index;
|
||||
|
||||
function upgradeRamOnClick(): void {
|
||||
let numUpgrades = purchaseMult;
|
||||
@@ -293,9 +248,13 @@ export function HacknetServerElem(props: IProps): React.ReactElement {
|
||||
<Typography>Level:</Typography>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Typography>{node.level}</Typography>
|
||||
<Typography>
|
||||
<HacknetServerLevel index={index} />
|
||||
</Typography>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<UpgradeHacknetServerLevelButton purchaseMult={purchaseMult} node={node} />
|
||||
</TableCell>
|
||||
<TableCell>{upgradeLevelButton}</TableCell>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableCell>
|
||||
|
||||
@@ -7,34 +7,20 @@
|
||||
import React from "react";
|
||||
|
||||
import { hasHacknetServers } from "../HacknetHelpers";
|
||||
import { Player } from "@player";
|
||||
import { Money } from "../../ui/React/Money";
|
||||
import { MoneyRate } from "../../ui/React/MoneyRate";
|
||||
import { HashRate } from "../../ui/React/HashRate";
|
||||
import { Hashes } from "../../ui/React/Hashes";
|
||||
import { Paper, Typography } from "@mui/material";
|
||||
import { StatsTable } from "../../ui/React/StatsTable";
|
||||
import { Tooltip } from "@mui/material";
|
||||
import { usePlayerSelector } from "../../utils/PlayerExternalStore";
|
||||
import { PlayerObject } from "src/PersonObjects/Player/PlayerObject";
|
||||
import { HashTotalProduction } from "./Components/HashTotalProduction";
|
||||
import { HacknetExpenses } from "./Components/HacknetExpenses";
|
||||
import { HacknetProduced } from "./Components/HacknetProduced";
|
||||
import { PlayerHashes } from "./Components/PlayerHashes";
|
||||
import { PlayerHashCapacity } from "./Components/PlayerHashCapacity";
|
||||
|
||||
interface IProps {
|
||||
totalProduction: number;
|
||||
}
|
||||
|
||||
const selectHacknetExpenses = (p: PlayerObject) => -p.moneySourceA.hacknet_expenses || 0;
|
||||
const selectHacknetMoney = (p: PlayerObject) => p.moneySourceA.hacknet;
|
||||
|
||||
function HacknetExpenses(): React.ReactElement {
|
||||
const spent = usePlayerSelector(selectHacknetExpenses);
|
||||
return <Money key="money" money={spent} />;
|
||||
}
|
||||
|
||||
function HacknetProduced(): React.ReactElement {
|
||||
const produced = usePlayerSelector(selectHacknetMoney);
|
||||
return <Money key="money" money={produced} />;
|
||||
}
|
||||
|
||||
export function PlayerInfo(props: IProps): React.ReactElement {
|
||||
const hasServers = hasHacknetServers();
|
||||
|
||||
@@ -45,7 +31,7 @@ export function PlayerInfo(props: IProps): React.ReactElement {
|
||||
rows.push([
|
||||
"Hashes:",
|
||||
<span key={"hashes"}>
|
||||
<Hashes hashes={Player.hashManager.hashes} /> / <Hashes hashes={Player.hashManager.capacity} />
|
||||
<PlayerHashes /> / <PlayerHashCapacity />
|
||||
</span>,
|
||||
]);
|
||||
rows.push([
|
||||
@@ -59,7 +45,7 @@ export function PlayerInfo(props: IProps): React.ReactElement {
|
||||
}
|
||||
>
|
||||
<span>
|
||||
<HashRate key="hashRate" hashes={props.totalProduction} />
|
||||
<HashTotalProduction />
|
||||
</span>
|
||||
</Tooltip>,
|
||||
]);
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
import React from "react";
|
||||
|
||||
import { hasHacknetServers, hasMaxNumberHacknetServers } from "../HacknetHelpers";
|
||||
import { Player } from "@player";
|
||||
import { Money } from "../../ui/React/Money";
|
||||
|
||||
import Button from "@mui/material/Button";
|
||||
import { MoneyCost } from "./Components/MoneyCost";
|
||||
import { MoneyButton } from "./Components/MoneyButton";
|
||||
|
||||
interface IProps {
|
||||
multiplier: number | string;
|
||||
@@ -23,7 +21,7 @@ export function PurchaseButton(props: IProps): React.ReactElement {
|
||||
text = (
|
||||
<>
|
||||
Purchase Hacknet Server -
|
||||
<Money money={cost} forPurchase={true} />
|
||||
<MoneyCost cost={cost} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -31,14 +29,14 @@ export function PurchaseButton(props: IProps): React.ReactElement {
|
||||
text = (
|
||||
<>
|
||||
Purchase Hacknet Node -
|
||||
<Money money={cost} forPurchase={true} />
|
||||
<MoneyCost cost={cost} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Button disabled={!Player.canAfford(cost)} onClick={props.onClick}>
|
||||
<MoneyButton cost={cost} onClick={props.onClick}>
|
||||
{text}
|
||||
</Button>
|
||||
</MoneyButton>
|
||||
);
|
||||
}
|
||||
|
||||
19
src/Hacknet/ui/utils.ts
Normal file
19
src/Hacknet/ui/utils.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { PlayerObject } from "src/PersonObjects/Player/PlayerObject";
|
||||
import { HacknetServer } from "../HacknetServer";
|
||||
import { HacknetNode } from "../HacknetNode";
|
||||
import { GetServer } from "../../Server/AllServers";
|
||||
|
||||
export function safeGetHacknetServer(p: PlayerObject, index: number): HacknetServer | undefined {
|
||||
const node = p.hacknetNodes[index];
|
||||
if (node instanceof HacknetNode) return undefined;
|
||||
const hserver = GetServer(node);
|
||||
if (hserver == null) return undefined;
|
||||
if (!(hserver instanceof HacknetServer)) return undefined;
|
||||
return hserver;
|
||||
}
|
||||
|
||||
export function safeGetHacknetNode(p: PlayerObject, index: number): HacknetNode | undefined {
|
||||
const node = p.hacknetNodes[index];
|
||||
if (!(node instanceof HacknetNode)) return undefined;
|
||||
return node;
|
||||
}
|
||||
Reference in New Issue
Block a user