bitburner-src/src/Faction/ui/PurchaseableAugmentation.tsx

240 lines
6.4 KiB
TypeScript
Raw Normal View History

2019-04-14 11:08:10 +02:00
/**
* React component for displaying a single augmentation for purchase through
* the faction UI
*/
import * as React from "react";
2021-09-13 00:03:07 +02:00
import { getNextNeurofluxLevel, hasAugmentationPrereqs, purchaseAugmentation } from "../FactionHelpers";
import { PurchaseAugmentationPopup } from "./PurchaseAugmentationPopup";
2019-04-14 11:08:10 +02:00
import { Augmentations } from "../../Augmentation/Augmentations";
import { AugmentationNames } from "../../Augmentation/data/AugmentationNames";
import { Faction } from "../../Faction/Faction";
import { IPlayer } from "../../PersonObjects/IPlayer";
import { Settings } from "../../Settings/Settings";
import { Money } from "../../ui/React/Money";
import { Reputation } from "../../ui/React/Reputation";
2021-09-13 00:03:07 +02:00
import { createPopup } from "../../ui/React/createPopup";
2019-04-14 11:08:10 +02:00
import { IMap } from "../../types";
import { StdButton } from "../../ui/React/StdButton";
import { Augmentation as AugFormat } from "../../ui/React/Augmentation";
2021-09-21 02:42:13 +02:00
import Button from "@mui/material/Button";
import Typography from "@mui/material/Typography";
import Tooltip from "@mui/material/Tooltip";
import Box from "@mui/material/Box";
import { TableCell } from "../../ui/React/Table";
import TableRow from "@mui/material/TableRow";
interface IReqProps {
augName: string;
p: IPlayer;
hasReq: boolean;
rep: number;
hasRep: boolean;
cost: number;
hasCost: boolean;
}
function Requirements(props: IReqProps): React.ReactElement {
const aug = Augmentations[props.augName];
if (!props.hasReq) {
return (
<TableCell colSpan={2}>
<Typography color="error">Requires {aug.prereqs.map((aug) => AugFormat(aug))}</Typography>
</TableCell>
);
}
let color = !props.hasRep && !props.hasCost ? "error" : "primary";
return (
<>
<TableCell>
<Typography color={color}>
<Money money={props.cost} player={props.p} />
</Typography>
</TableCell>
<TableCell>
<Typography color={color}>Requires {Reputation(props.rep)} faction reputation</Typography>
</TableCell>
</>
);
}
2019-04-14 11:08:10 +02:00
2021-09-21 02:42:13 +02:00
interface IProps {
2021-09-05 01:09:30 +02:00
augName: string;
faction: Faction;
p: IPlayer;
rerender: () => void;
2021-09-21 02:42:13 +02:00
owned?: boolean;
}
2019-04-14 11:08:10 +02:00
2021-09-18 01:43:08 +02:00
export function PurchaseableAugmentation(props: IProps): React.ReactElement {
const aug = Augmentations[props.augName];
if (aug == null) throw new Error(`aug ${props.augName} does not exists`);
2021-09-05 01:09:30 +02:00
2021-09-18 01:43:08 +02:00
function getMoneyCost(): number {
return aug.baseCost * props.faction.getInfo().augmentationPriceMult;
2021-09-05 01:09:30 +02:00
}
2021-09-18 01:43:08 +02:00
function getRepCost(): number {
return aug.baseRepRequirement * props.faction.getInfo().augmentationRepRequirementMult;
2021-09-05 01:09:30 +02:00
}
// Whether the player has the prerequisite Augmentations
2021-09-18 01:43:08 +02:00
function hasPrereqs(): boolean {
return hasAugmentationPrereqs(aug);
2021-09-05 01:09:30 +02:00
}
// Whether the player has enough rep for this Augmentation
2021-09-18 01:43:08 +02:00
function hasReputation(): boolean {
return props.faction.playerReputation >= getRepCost();
2021-09-05 01:09:30 +02:00
}
// Whether the player has this augmentations (purchased OR installed)
2021-09-18 01:43:08 +02:00
function owned(): boolean {
2021-09-05 01:09:30 +02:00
let owned = false;
2021-09-18 01:43:08 +02:00
for (const queuedAug of props.p.queuedAugmentations) {
if (queuedAug.name === props.augName) {
2021-09-05 01:09:30 +02:00
owned = true;
break;
}
2019-04-14 11:08:10 +02:00
}
2021-09-18 01:43:08 +02:00
for (const installedAug of props.p.augmentations) {
if (installedAug.name === props.augName) {
2021-09-05 01:09:30 +02:00
owned = true;
break;
}
2019-04-14 11:08:10 +02:00
}
2021-09-05 01:09:30 +02:00
return owned;
}
2019-04-14 11:08:10 +02:00
2021-09-18 01:43:08 +02:00
if (aug == null) {
console.error(
`Invalid Augmentation when trying to create PurchaseableAugmentation display element: ${props.augName}`,
);
return <></>;
}
2019-04-14 11:08:10 +02:00
2021-09-18 01:43:08 +02:00
const moneyCost = getMoneyCost();
const repCost = getRepCost();
2021-09-21 02:42:13 +02:00
const hasReq = hasPrereqs();
const hasRep = hasReputation();
const hasCost = aug.baseCost !== 0 && props.p.money.lt(aug.baseCost * props.faction.getInfo().augmentationPriceMult);
2021-09-18 01:43:08 +02:00
// Determine UI properties
let disabled = false;
2021-09-21 02:42:13 +02:00
let status: JSX.Element | null = null;
let color: "primary" | "error" = "primary";
if (!hasReq) {
2021-09-18 01:43:08 +02:00
disabled = true;
status = <>LOCKED (Requires {aug.prereqs.map((aug) => AugFormat(aug))} as prerequisite)</>;
2021-09-21 02:42:13 +02:00
color = "error";
2021-09-18 01:43:08 +02:00
} else if (aug.name !== AugmentationNames.NeuroFluxGovernor && (aug.owned || owned())) {
disabled = true;
2021-09-21 02:42:13 +02:00
} else if (hasRep) {
2021-09-18 01:43:08 +02:00
status = (
<>
UNLOCKED (at {Reputation(repCost)} faction reputation) - <Money money={moneyCost} player={props.p} />
</>
);
} else {
disabled = true;
status = (
<>
LOCKED (Requires {Reputation(repCost)} faction reputation - <Money money={moneyCost} player={props.p} />)
</>
);
2021-09-21 02:42:13 +02:00
color = "error";
2021-09-18 01:43:08 +02:00
}
2019-04-14 11:08:10 +02:00
2021-09-21 02:42:13 +02:00
if (hasCost) {
disabled = true;
color = "error";
2021-09-18 01:43:08 +02:00
}
2019-04-14 11:08:10 +02:00
2021-09-18 01:43:08 +02:00
// Determine button txt
let btnTxt = aug.name;
if (aug.name === AugmentationNames.NeuroFluxGovernor) {
btnTxt += ` - Level ${getNextNeurofluxLevel()}`;
}
2021-09-05 01:09:30 +02:00
2021-09-18 01:43:08 +02:00
let tooltip = <></>;
if (typeof aug.info === "string")
tooltip = (
<>
<span dangerouslySetInnerHTML={{ __html: aug.info }} />
<br />
<br />
{aug.stats}
</>
);
else
tooltip = (
<>
{aug.info}
<br />
<br />
{aug.stats}
</>
);
2021-09-21 02:42:13 +02:00
function handleClick(): void {
if (disabled) return;
if (!Settings.SuppressBuyAugmentationConfirmation) {
const popupId = "purchase-augmentation-popup";
createPopup(popupId, PurchaseAugmentationPopup, {
aug: aug,
faction: props.faction,
player: props.p,
rerender: props.rerender,
popupId: popupId,
});
} else {
purchaseAugmentation(aug, props.faction);
props.rerender();
}
}
2021-09-18 01:43:08 +02:00
return (
2021-09-21 02:42:13 +02:00
<TableRow>
{!props.owned && (
<TableCell>
{status && (
<Button onClick={handleClick} color={color}>
Buy
</Button>
)}
</TableCell>
)}
<TableCell>
<Box display="flex">
<Tooltip
title={<Typography>{tooltip}</Typography>}
placement="top"
disableFocusListener
disableTouchListener
enterDelay={500}
leaveDelay={0}
>
<Typography>{btnTxt}</Typography>
</Tooltip>
</Box>
</TableCell>
{!props.owned && (
<Requirements
augName={props.augName}
p={props.p}
cost={moneyCost}
rep={repCost}
hasReq={hasReq}
hasRep={hasRep}
hasCost={hasCost}
2021-09-18 01:43:08 +02:00
/>
2021-09-21 02:42:13 +02:00
)}
</TableRow>
2021-09-18 01:43:08 +02:00
);
2019-04-14 11:08:10 +02:00
}