mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-11-26 17:43:48 +01:00
Merge pull request #3545 from nickofolas/improvement/purchase-augs-ui
UI: Redesign purchasable Augmentations
This commit is contained in:
commit
d0d700077a
@ -251,7 +251,7 @@ export const initGeneralAugmentations = (): Augmentation[] => [
|
|||||||
moneyCost: 1.15e8,
|
moneyCost: 1.15e8,
|
||||||
repCost: 2.75e4,
|
repCost: 2.75e4,
|
||||||
info: "The latest version of the 'Augmented Targeting' implant adds the ability to lock-on and track threats.",
|
info: "The latest version of the 'Augmented Targeting' implant adds the ability to lock-on and track threats.",
|
||||||
prereqs: [AugmentationNames.Targeting2],
|
prereqs: [AugmentationNames.Targeting2, AugmentationNames.Targeting1],
|
||||||
dexterity_mult: 1.3,
|
dexterity_mult: 1.3,
|
||||||
factions: [
|
factions: [
|
||||||
FactionNames.TheDarkArmy,
|
FactionNames.TheDarkArmy,
|
||||||
@ -348,7 +348,7 @@ export const initGeneralAugmentations = (): Augmentation[] => [
|
|||||||
info:
|
info:
|
||||||
"The latest version of the 'Combat Rib' augmentation releases advanced anabolic steroids that " +
|
"The latest version of the 'Combat Rib' augmentation releases advanced anabolic steroids that " +
|
||||||
"improve muscle mass and physical performance while being safe and free of side effects.",
|
"improve muscle mass and physical performance while being safe and free of side effects.",
|
||||||
prereqs: [AugmentationNames.CombatRib2],
|
prereqs: [AugmentationNames.CombatRib2, AugmentationNames.CombatRib1],
|
||||||
strength_mult: 1.18,
|
strength_mult: 1.18,
|
||||||
defense_mult: 1.18,
|
defense_mult: 1.18,
|
||||||
factions: [
|
factions: [
|
||||||
@ -682,7 +682,7 @@ export const initGeneralAugmentations = (): Augmentation[] => [
|
|||||||
"This upgraded firmware allows the Embedded Netburner Module to control information on " +
|
"This upgraded firmware allows the Embedded Netburner Module to control information on " +
|
||||||
"a network by re-routing traffic, spoofing IP addresses, and altering the data inside network " +
|
"a network by re-routing traffic, spoofing IP addresses, and altering the data inside network " +
|
||||||
"packets.",
|
"packets.",
|
||||||
prereqs: [AugmentationNames.ENMCore],
|
prereqs: [AugmentationNames.ENMCore, AugmentationNames.ENM],
|
||||||
hacking_speed_mult: 1.05,
|
hacking_speed_mult: 1.05,
|
||||||
hacking_money_mult: 1.3,
|
hacking_money_mult: 1.3,
|
||||||
hacking_chance_mult: 1.05,
|
hacking_chance_mult: 1.05,
|
||||||
@ -707,7 +707,7 @@ export const initGeneralAugmentations = (): Augmentation[] => [
|
|||||||
"The Core V3 library is an implant that upgrades the firmware of the Embedded Netburner Module. " +
|
"The Core V3 library is an implant that upgrades the firmware of the Embedded Netburner Module. " +
|
||||||
"This upgraded firmware allows the Embedded Netburner Module to seamlessly inject code into " +
|
"This upgraded firmware allows the Embedded Netburner Module to seamlessly inject code into " +
|
||||||
"any device on a network.",
|
"any device on a network.",
|
||||||
prereqs: [AugmentationNames.ENMCoreV2],
|
prereqs: [AugmentationNames.ENMCoreV2, AugmentationNames.ENMCore, AugmentationNames.ENM],
|
||||||
hacking_speed_mult: 1.05,
|
hacking_speed_mult: 1.05,
|
||||||
hacking_money_mult: 1.4,
|
hacking_money_mult: 1.4,
|
||||||
hacking_chance_mult: 1.1,
|
hacking_chance_mult: 1.1,
|
||||||
@ -835,7 +835,7 @@ export const initGeneralAugmentations = (): Augmentation[] => [
|
|||||||
"are a set of specialized microprocessors that are attached to " +
|
"are a set of specialized microprocessors that are attached to " +
|
||||||
"neurons in the brain. These chips process neural signals to quickly and automatically perform specific computations " +
|
"neurons in the brain. These chips process neural signals to quickly and automatically perform specific computations " +
|
||||||
"so that the brain doesn't have to.",
|
"so that the brain doesn't have to.",
|
||||||
prereqs: [AugmentationNames.CranialSignalProcessorsG2],
|
prereqs: [AugmentationNames.CranialSignalProcessorsG2, AugmentationNames.CranialSignalProcessorsG1],
|
||||||
hacking_speed_mult: 1.02,
|
hacking_speed_mult: 1.02,
|
||||||
hacking_money_mult: 1.15,
|
hacking_money_mult: 1.15,
|
||||||
hacking_mult: 1.09,
|
hacking_mult: 1.09,
|
||||||
@ -850,7 +850,11 @@ export const initGeneralAugmentations = (): Augmentation[] => [
|
|||||||
"are a set of specialized microprocessors that are attached to " +
|
"are a set of specialized microprocessors that are attached to " +
|
||||||
"neurons in the brain. These chips process neural signals to quickly and automatically perform specific computations " +
|
"neurons in the brain. These chips process neural signals to quickly and automatically perform specific computations " +
|
||||||
"so that the brain doesn't have to.",
|
"so that the brain doesn't have to.",
|
||||||
prereqs: [AugmentationNames.CranialSignalProcessorsG3],
|
prereqs: [
|
||||||
|
AugmentationNames.CranialSignalProcessorsG3,
|
||||||
|
AugmentationNames.CranialSignalProcessorsG2,
|
||||||
|
AugmentationNames.CranialSignalProcessorsG1,
|
||||||
|
],
|
||||||
hacking_speed_mult: 1.02,
|
hacking_speed_mult: 1.02,
|
||||||
hacking_money_mult: 1.2,
|
hacking_money_mult: 1.2,
|
||||||
hacking_grow_mult: 1.25,
|
hacking_grow_mult: 1.25,
|
||||||
@ -865,7 +869,12 @@ export const initGeneralAugmentations = (): Augmentation[] => [
|
|||||||
"are a set of specialized microprocessors that are attached to " +
|
"are a set of specialized microprocessors that are attached to " +
|
||||||
"neurons in the brain. These chips process neural signals to quickly and automatically perform specific computations " +
|
"neurons in the brain. These chips process neural signals to quickly and automatically perform specific computations " +
|
||||||
"so that the brain doesn't have to.",
|
"so that the brain doesn't have to.",
|
||||||
prereqs: [AugmentationNames.CranialSignalProcessorsG4],
|
prereqs: [
|
||||||
|
AugmentationNames.CranialSignalProcessorsG4,
|
||||||
|
AugmentationNames.CranialSignalProcessorsG3,
|
||||||
|
AugmentationNames.CranialSignalProcessorsG2,
|
||||||
|
AugmentationNames.CranialSignalProcessorsG1,
|
||||||
|
],
|
||||||
hacking_mult: 1.3,
|
hacking_mult: 1.3,
|
||||||
hacking_money_mult: 1.25,
|
hacking_money_mult: 1.25,
|
||||||
hacking_grow_mult: 1.75,
|
hacking_grow_mult: 1.75,
|
||||||
@ -1962,7 +1971,7 @@ export const initChurchOfTheMachineGodAugmentations = (): Augmentation[] => [
|
|||||||
"You will become greater than the sum of our parts. As One. Embrace your gift " +
|
"You will become greater than the sum of our parts. As One. Embrace your gift " +
|
||||||
"fully and wholly free of it's accursed toll. Serenity brings tranquility the form " +
|
"fully and wholly free of it's accursed toll. Serenity brings tranquility the form " +
|
||||||
"of no longer suffering a stat penalty. ",
|
"of no longer suffering a stat penalty. ",
|
||||||
prereqs: [AugmentationNames.StaneksGift2],
|
prereqs: [AugmentationNames.StaneksGift2, AugmentationNames.StaneksGift1],
|
||||||
isSpecial: true,
|
isSpecial: true,
|
||||||
hacking_chance_mult: 1 / 0.95,
|
hacking_chance_mult: 1 / 0.95,
|
||||||
hacking_speed_mult: 1 / 0.95,
|
hacking_speed_mult: 1 / 0.95,
|
||||||
|
264
src/Augmentation/ui/PurchasableAugmentations.tsx
Normal file
264
src/Augmentation/ui/PurchasableAugmentations.tsx
Normal file
@ -0,0 +1,264 @@
|
|||||||
|
/**
|
||||||
|
* React component for displaying a single augmentation for purchase through
|
||||||
|
* the faction UI
|
||||||
|
*/
|
||||||
|
import { CheckBox, CheckBoxOutlineBlank, CheckCircle, Info, NewReleases, Report } from "@mui/icons-material";
|
||||||
|
import { Box, Button, Container, Paper, Tooltip, Typography } from "@mui/material";
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import { getNextNeuroFluxLevel } from "../AugmentationHelpers";
|
||||||
|
import { Faction } from "../../Faction/Faction";
|
||||||
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||||
|
import { Settings } from "../../Settings/Settings";
|
||||||
|
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||||
|
import { Augmentation } from "../Augmentation";
|
||||||
|
import { Augmentations } from "../Augmentations";
|
||||||
|
import { AugmentationNames } from "../data/AugmentationNames";
|
||||||
|
import { PurchaseAugmentationModal } from "./PurchaseAugmentationModal";
|
||||||
|
|
||||||
|
interface IPreReqsProps {
|
||||||
|
player: IPlayer;
|
||||||
|
aug: Augmentation;
|
||||||
|
}
|
||||||
|
|
||||||
|
const PreReqs = (props: IPreReqsProps): React.ReactElement => {
|
||||||
|
const ownedPreReqs = props.aug.prereqs.filter((aug) => props.player.hasAugmentation(aug));
|
||||||
|
const hasPreReqs = props.aug.prereqs.length > 0 && ownedPreReqs.length === props.aug.prereqs.length;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Tooltip
|
||||||
|
title={
|
||||||
|
<>
|
||||||
|
<Typography sx={{ color: Settings.theme.money }}>
|
||||||
|
This Augmentation has the following pre-requisite(s):
|
||||||
|
</Typography>
|
||||||
|
{props.aug.prereqs.map((preAug) => (
|
||||||
|
<Requirement
|
||||||
|
fulfilled={props.player.hasAugmentation(preAug)}
|
||||||
|
value={preAug}
|
||||||
|
color={Settings.theme.money}
|
||||||
|
key={preAug}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Typography
|
||||||
|
variant="body2"
|
||||||
|
sx={{
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
color: hasPreReqs ? Settings.theme.successlight : Settings.theme.error,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{hasPreReqs ? (
|
||||||
|
<>
|
||||||
|
<CheckCircle fontSize="small" sx={{ mr: 1 }} />
|
||||||
|
Pre-requisites Owned
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<Report fontSize="small" sx={{ mr: 1 }} />
|
||||||
|
Missing {props.aug.prereqs.length - ownedPreReqs.length} pre-requisite(s)
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Typography>
|
||||||
|
</Tooltip>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
interface IExclusiveProps {
|
||||||
|
player: IPlayer;
|
||||||
|
aug: Augmentation;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Exclusive = (props: IExclusiveProps): React.ReactElement => {
|
||||||
|
return (
|
||||||
|
<Tooltip
|
||||||
|
title={
|
||||||
|
<>
|
||||||
|
<Typography sx={{ color: Settings.theme.money }}>
|
||||||
|
This Augmentation can only be acquired from the following source(s):
|
||||||
|
</Typography>
|
||||||
|
<ul>
|
||||||
|
<Typography sx={{ color: Settings.theme.money }}>
|
||||||
|
<li>
|
||||||
|
<b>{props.aug.factions[0]}</b> faction
|
||||||
|
</li>
|
||||||
|
{props.player.canAccessGang() && !props.aug.isSpecial && (
|
||||||
|
<li>
|
||||||
|
Certain <b>gangs</b>
|
||||||
|
</li>
|
||||||
|
)}
|
||||||
|
{props.player.canAccessGrafting() &&
|
||||||
|
!props.aug.isSpecial &&
|
||||||
|
props.aug.name !== AugmentationNames.TheRedPill && (
|
||||||
|
<li>
|
||||||
|
<b>Grafting</b>
|
||||||
|
</li>
|
||||||
|
)}
|
||||||
|
</Typography>
|
||||||
|
</ul>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<NewReleases sx={{ ml: 1, color: Settings.theme.money, transform: "rotate(180deg)" }} />
|
||||||
|
</Tooltip>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
interface IReqProps {
|
||||||
|
value: string;
|
||||||
|
color: string;
|
||||||
|
fulfilled: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Requirement = (props: IReqProps): React.ReactElement => {
|
||||||
|
return (
|
||||||
|
<Typography sx={{ display: "flex", alignItems: "center", color: props.color }}>
|
||||||
|
{props.fulfilled ? <CheckBox sx={{ mr: 1 }} /> : <CheckBoxOutlineBlank sx={{ mr: 1 }} />}
|
||||||
|
{props.value}
|
||||||
|
</Typography>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
interface IPurchasableAugsProps {
|
||||||
|
augNames: string[];
|
||||||
|
ownedAugNames: string[];
|
||||||
|
player: IPlayer;
|
||||||
|
|
||||||
|
canPurchase: (player: IPlayer, aug: Augmentation) => boolean;
|
||||||
|
purchaseAugmentation: (player: IPlayer, aug: Augmentation, showModal: (open: boolean) => void) => void;
|
||||||
|
|
||||||
|
rep?: number;
|
||||||
|
sleeveAugs?: boolean;
|
||||||
|
faction?: Faction;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const PurchasableAugmentations = (props: IPurchasableAugsProps): React.ReactElement => {
|
||||||
|
return (
|
||||||
|
<Container
|
||||||
|
maxWidth="lg"
|
||||||
|
disableGutters
|
||||||
|
sx={{ mx: 0, display: "grid", gridTemplateColumns: "repeat(1, 1fr)", gap: 1 }}
|
||||||
|
>
|
||||||
|
{props.augNames.map((augName: string) => (
|
||||||
|
<PurchasableAugmentation key={augName} parent={props} augName={augName} owned={false} />
|
||||||
|
))}
|
||||||
|
{props.ownedAugNames.map((augName: string) => (
|
||||||
|
<PurchasableAugmentation key={augName} parent={props} augName={augName} owned={true} />
|
||||||
|
))}
|
||||||
|
</Container>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
interface IPurchasableAugProps {
|
||||||
|
parent: IPurchasableAugsProps;
|
||||||
|
augName: string;
|
||||||
|
owned: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function PurchasableAugmentation(props: IPurchasableAugProps): React.ReactElement {
|
||||||
|
const [open, setOpen] = useState(false);
|
||||||
|
|
||||||
|
const aug = Augmentations[props.augName];
|
||||||
|
|
||||||
|
const cost = props.parent.sleeveAugs ? aug.startingCost : aug.baseCost;
|
||||||
|
|
||||||
|
const info = typeof aug.info === "string" ? <span>{aug.info}</span> : aug.info;
|
||||||
|
const description = (
|
||||||
|
<>
|
||||||
|
{info}
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
{aug.stats}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Paper
|
||||||
|
sx={{
|
||||||
|
p: 1,
|
||||||
|
display: "grid",
|
||||||
|
gridTemplateColumns: "minmax(0, 4fr) 1fr",
|
||||||
|
gap: 1,
|
||||||
|
opacity: props.owned ? 0.75 : 1,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<>
|
||||||
|
<Box sx={{ display: "flex", alignItems: "center" }}>
|
||||||
|
<Button
|
||||||
|
onClick={() =>
|
||||||
|
props.parent.purchaseAugmentation(props.parent.player, aug, (open): void => {
|
||||||
|
setOpen(open);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
disabled={!props.parent.canPurchase(props.parent.player, aug) || props.owned}
|
||||||
|
sx={{ width: "48px", height: "48px", float: "left", clear: "none", mr: 1 }}
|
||||||
|
>
|
||||||
|
{props.owned ? "Owned" : "Buy"}
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<Box sx={{ maxWidth: props.owned ? "100%" : "85%" }}>
|
||||||
|
<Box sx={{ display: "flex", alignItems: "center" }}>
|
||||||
|
<Tooltip
|
||||||
|
title={
|
||||||
|
<>
|
||||||
|
<Typography variant="h5">
|
||||||
|
{props.augName}
|
||||||
|
{props.augName === AugmentationNames.NeuroFluxGovernor && ` - Level ${getNextNeuroFluxLevel()}`}
|
||||||
|
</Typography>
|
||||||
|
<Typography>{description}</Typography>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Info sx={{ mr: 1 }} color="info" />
|
||||||
|
</Tooltip>
|
||||||
|
<Typography
|
||||||
|
variant="h6"
|
||||||
|
sx={{
|
||||||
|
textOverflow: "ellipsis",
|
||||||
|
whiteSpace: "nowrap",
|
||||||
|
overflow: "hidden",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{aug.name}
|
||||||
|
{aug.name === AugmentationNames.NeuroFluxGovernor && ` - Level ${getNextNeuroFluxLevel()}`}
|
||||||
|
</Typography>
|
||||||
|
{aug.factions.length === 1 && !props.parent.sleeveAugs && (
|
||||||
|
<Exclusive player={props.parent.player} aug={aug} />
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
{aug.prereqs.length > 0 && !props.parent.sleeveAugs && <PreReqs player={props.parent.player} aug={aug} />}
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
{props.owned || (
|
||||||
|
<Box sx={{ display: "grid", alignItems: "center", justifyItems: "left" }}>
|
||||||
|
<Requirement
|
||||||
|
fulfilled={aug.baseCost === 0 || props.parent.player.money > cost}
|
||||||
|
value={numeralWrapper.formatMoney(cost)}
|
||||||
|
color={Settings.theme.money}
|
||||||
|
/>
|
||||||
|
{props.parent.rep !== undefined && (
|
||||||
|
<Requirement
|
||||||
|
fulfilled={props.parent.rep >= aug.baseRepRequirement}
|
||||||
|
value={`${numeralWrapper.formatReputation(aug.baseRepRequirement)} rep`}
|
||||||
|
color={Settings.theme.rep}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{Settings.SuppressBuyAugmentationConfirmation || (
|
||||||
|
<PurchaseAugmentationModal
|
||||||
|
open={open}
|
||||||
|
onClose={() => setOpen(false)}
|
||||||
|
faction={props.parent.faction}
|
||||||
|
aug={aug}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
</Paper>
|
||||||
|
);
|
||||||
|
}
|
@ -1,9 +1,9 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
import { Augmentation } from "../../Augmentation/Augmentation";
|
import { Augmentation } from "../Augmentation";
|
||||||
import { Faction } from "../Faction";
|
import { Faction } from "../../Faction/Faction";
|
||||||
import { purchaseAugmentation } from "../FactionHelpers";
|
import { purchaseAugmentation } from "../../Faction/FactionHelpers";
|
||||||
import { isRepeatableAug } from "../../Augmentation/AugmentationHelpers";
|
import { isRepeatableAug } from "../AugmentationHelpers";
|
||||||
import { Money } from "../../ui/React/Money";
|
import { Money } from "../../ui/React/Money";
|
||||||
import { Modal } from "../../ui/React/Modal";
|
import { Modal } from "../../ui/React/Modal";
|
||||||
import { use } from "../../ui/Context";
|
import { use } from "../../ui/Context";
|
||||||
@ -13,21 +13,23 @@ import Button from "@mui/material/Button";
|
|||||||
interface IProps {
|
interface IProps {
|
||||||
open: boolean;
|
open: boolean;
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
faction: Faction;
|
faction?: Faction;
|
||||||
aug: Augmentation;
|
aug?: Augmentation;
|
||||||
rerender: () => void;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function PurchaseAugmentationModal(props: IProps): React.ReactElement {
|
export function PurchaseAugmentationModal(props: IProps): React.ReactElement {
|
||||||
|
if (typeof props.aug === "undefined" || typeof props.faction === "undefined") {
|
||||||
|
return <></>;
|
||||||
|
}
|
||||||
|
|
||||||
const player = use.Player();
|
const player = use.Player();
|
||||||
|
|
||||||
function buy(): void {
|
function buy(): void {
|
||||||
if (!isRepeatableAug(props.aug) && player.hasAugmentation(props.aug)) {
|
if (!isRepeatableAug(props.aug as Augmentation) && player.hasAugmentation(props.aug as Augmentation)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
purchaseAugmentation(props.aug, props.faction);
|
purchaseAugmentation(props.aug as Augmentation, props.faction as Faction);
|
||||||
props.rerender();
|
|
||||||
props.onClose();
|
props.onClose();
|
||||||
}
|
}
|
||||||
|
|
@ -54,36 +54,15 @@ export function joinFaction(faction: Faction): void {
|
|||||||
//Returns a boolean indicating whether the player has the prerequisites for the
|
//Returns a boolean indicating whether the player has the prerequisites for the
|
||||||
//specified Augmentation
|
//specified Augmentation
|
||||||
export function hasAugmentationPrereqs(aug: Augmentation): boolean {
|
export function hasAugmentationPrereqs(aug: Augmentation): boolean {
|
||||||
let hasPrereqs = true;
|
return aug.prereqs.every((aug) => Player.hasAugmentation(aug));
|
||||||
if (aug.prereqs && aug.prereqs.length > 0) {
|
|
||||||
for (let i = 0; i < aug.prereqs.length; ++i) {
|
|
||||||
const prereqAug = Augmentations[aug.prereqs[i]];
|
|
||||||
if (prereqAug == null) {
|
|
||||||
console.error(`Invalid prereq Augmentation ${aug.prereqs[i]}`);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Player.hasAugmentation(prereqAug, true) === false) {
|
|
||||||
hasPrereqs = false;
|
|
||||||
|
|
||||||
// Check if the aug is purchased
|
|
||||||
for (let j = 0; j < Player.queuedAugmentations.length; ++j) {
|
|
||||||
if (Player.queuedAugmentations[j].name === prereqAug.name) {
|
|
||||||
hasPrereqs = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return hasPrereqs;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function purchaseAugmentation(aug: Augmentation, fac: Faction, sing = false): string {
|
export function purchaseAugmentation(aug: Augmentation, fac: Faction, sing = false): string {
|
||||||
const hasPrereqs = hasAugmentationPrereqs(aug);
|
const hasPrereqs = hasAugmentationPrereqs(aug);
|
||||||
if (!hasPrereqs) {
|
if (!hasPrereqs) {
|
||||||
const txt = `You must first purchase or install ${aug.prereqs.join(",")} before you can purchase this one.`;
|
const txt = `You must first purchase or install ${aug.prereqs
|
||||||
|
.filter((req) => !Player.hasAugmentation(req))
|
||||||
|
.join(",")} before you can purchase this one.`;
|
||||||
if (sing) {
|
if (sing) {
|
||||||
return txt;
|
return txt;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,30 +1,21 @@
|
|||||||
/**
|
/**
|
||||||
* Root React Component for displaying a faction's "Purchase Augmentations" page
|
* Root React Component for displaying a faction's "Purchase Augmentations" page
|
||||||
*/
|
*/
|
||||||
|
import { Box, Button, Tooltip, Typography, Paper, Container } from "@mui/material";
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
|
import { getGenericAugmentationPriceMultiplier } from "../../Augmentation/AugmentationHelpers";
|
||||||
import { PurchaseableAugmentation } from "./PurchaseableAugmentation";
|
|
||||||
|
|
||||||
import { Augmentations } from "../../Augmentation/Augmentations";
|
import { Augmentations } from "../../Augmentation/Augmentations";
|
||||||
import { AugmentationNames } from "../../Augmentation/data/AugmentationNames";
|
import { AugmentationNames } from "../../Augmentation/data/AugmentationNames";
|
||||||
import { Faction } from "../Faction";
|
import { PurchasableAugmentations } from "../../Augmentation/ui/PurchasableAugmentations";
|
||||||
import { PurchaseAugmentationsOrderSetting } from "../../Settings/SettingEnums";
|
import { PurchaseAugmentationsOrderSetting } from "../../Settings/SettingEnums";
|
||||||
import { Settings } from "../../Settings/Settings";
|
import { Settings } from "../../Settings/Settings";
|
||||||
import { hasAugmentationPrereqs, getFactionAugmentationsFiltered } from "../FactionHelpers";
|
|
||||||
|
|
||||||
import { use } from "../../ui/Context";
|
import { use } from "../../ui/Context";
|
||||||
import { Reputation } from "../../ui/React/Reputation";
|
|
||||||
import { Favor } from "../../ui/React/Favor";
|
|
||||||
import { numeralWrapper } from "../../ui/numeralFormat";
|
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||||
|
import { Favor } from "../../ui/React/Favor";
|
||||||
import Box from "@mui/material/Box";
|
import { Reputation } from "../../ui/React/Reputation";
|
||||||
import Button from "@mui/material/Button";
|
|
||||||
import Typography from "@mui/material/Typography";
|
|
||||||
import Tooltip from "@mui/material/Tooltip";
|
|
||||||
import TableBody from "@mui/material/TableBody";
|
|
||||||
import Table from "@mui/material/Table";
|
|
||||||
import { getGenericAugmentationPriceMultiplier } from "../../Augmentation/AugmentationHelpers";
|
|
||||||
import { FactionNames } from "../data/FactionNames";
|
import { FactionNames } from "../data/FactionNames";
|
||||||
|
import { Faction } from "../Faction";
|
||||||
|
import { getFactionAugmentationsFiltered, hasAugmentationPrereqs, purchaseAugmentation } from "../FactionHelpers";
|
||||||
|
|
||||||
type IProps = {
|
type IProps = {
|
||||||
faction: Faction;
|
faction: Faction;
|
||||||
@ -137,38 +128,12 @@ export function AugmentationsPage(props: IProps): React.ReactElement {
|
|||||||
aug === AugmentationNames.NeuroFluxGovernor ||
|
aug === AugmentationNames.NeuroFluxGovernor ||
|
||||||
(!player.augmentations.some((a) => a.name === aug) && !player.queuedAugmentations.some((a) => a.name === aug)),
|
(!player.augmentations.some((a) => a.name === aug) && !player.queuedAugmentations.some((a) => a.name === aug)),
|
||||||
);
|
);
|
||||||
|
|
||||||
const purchaseableAugmentation = (aug: string, owned = false): React.ReactNode => {
|
|
||||||
return (
|
|
||||||
<PurchaseableAugmentation
|
|
||||||
augName={aug}
|
|
||||||
faction={props.faction}
|
|
||||||
key={aug}
|
|
||||||
p={player}
|
|
||||||
rerender={rerender}
|
|
||||||
owned={owned}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const augListElems = purchasable.map((aug) => purchaseableAugmentation(aug));
|
|
||||||
|
|
||||||
let ownedElem = <></>;
|
|
||||||
const owned = augs.filter((aug: string) => !purchasable.includes(aug));
|
const owned = augs.filter((aug: string) => !purchasable.includes(aug));
|
||||||
if (owned.length !== 0) {
|
|
||||||
ownedElem = (
|
|
||||||
<>
|
|
||||||
<br />
|
|
||||||
<Typography variant="h4">Purchased Augmentations</Typography>
|
|
||||||
<Typography>This faction also offers these augmentations but you already own them.</Typography>
|
|
||||||
{owned.map((aug) => purchaseableAugmentation(aug, true))}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
const multiplierComponent =
|
const multiplierComponent =
|
||||||
props.faction.name !== FactionNames.ShadowsOfAnarchy ? (
|
props.faction.name !== FactionNames.ShadowsOfAnarchy ? (
|
||||||
<Typography>
|
<Typography>
|
||||||
Price multiplier: x {numeralWrapper.formatMultiplier(getGenericAugmentationPriceMultiplier())}
|
<b>Price multiplier:</b> x {numeralWrapper.formatReallyBigNumber(getGenericAugmentationPriceMultiplier())}
|
||||||
</Typography>
|
</Typography>
|
||||||
) : (
|
) : (
|
||||||
<></>
|
<></>
|
||||||
@ -176,42 +141,77 @@ export function AugmentationsPage(props: IProps): React.ReactElement {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Button onClick={props.routeToMainPage}>Back</Button>
|
<Container disableGutters maxWidth="lg" sx={{ mx: 0 }}>
|
||||||
<Typography variant="h4">Faction Augmentations</Typography>
|
<Button onClick={props.routeToMainPage}>Back</Button>
|
||||||
<Typography>
|
<Typography variant="h4">Faction Augmentations</Typography>
|
||||||
These are all of the Augmentations that are available to purchase from {props.faction.name}. Augmentations are
|
<Paper sx={{ p: 1, mb: 1 }}>
|
||||||
powerful upgrades that will enhance your abilities.
|
<Typography>
|
||||||
<br />
|
These are all of the Augmentations that are available to purchase from <b>{props.faction.name}</b>.
|
||||||
Reputation: <Reputation reputation={props.faction.playerReputation} /> Favor:{" "}
|
Augmentations are powerful upgrades that will enhance your abilities.
|
||||||
<Favor favor={Math.floor(props.faction.favor)} />
|
<br />
|
||||||
</Typography>
|
</Typography>
|
||||||
<Box display="flex">
|
<Box
|
||||||
<Tooltip
|
sx={{
|
||||||
title={
|
display: "grid",
|
||||||
|
gridTemplateColumns: `repeat(${props.faction.name === FactionNames.ShadowsOfAnarchy ? "2" : "3"}, 1fr)`,
|
||||||
|
justifyItems: "center",
|
||||||
|
my: 1,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Tooltip
|
||||||
|
title={
|
||||||
|
<Typography>
|
||||||
|
The price of every Augmentation increases for every queued Augmentation and it is reset when you
|
||||||
|
install them.
|
||||||
|
</Typography>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{multiplierComponent}
|
||||||
|
</Tooltip>
|
||||||
<Typography>
|
<Typography>
|
||||||
The price of every Augmentation increases for every queued Augmentation and it is reset when you install
|
<b>Reputation:</b> <Reputation reputation={props.faction.playerReputation} />
|
||||||
them.
|
|
||||||
</Typography>
|
</Typography>
|
||||||
|
<Typography>
|
||||||
|
<b>Favor:</b> <Favor favor={Math.floor(props.faction.favor)} />
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
<Box sx={{ display: "grid", gridTemplateColumns: "repeat(4, 1fr)" }}>
|
||||||
|
<Button onClick={() => switchSortOrder(PurchaseAugmentationsOrderSetting.Cost)}>Sort by Cost</Button>
|
||||||
|
<Button onClick={() => switchSortOrder(PurchaseAugmentationsOrderSetting.Reputation)}>
|
||||||
|
Sort by Reputation
|
||||||
|
</Button>
|
||||||
|
<Button onClick={() => switchSortOrder(PurchaseAugmentationsOrderSetting.Default)}>
|
||||||
|
Sort by Default Order
|
||||||
|
</Button>
|
||||||
|
<Button onClick={() => switchSortOrder(PurchaseAugmentationsOrderSetting.Purchasable)}>
|
||||||
|
Sort by Purchasable
|
||||||
|
</Button>
|
||||||
|
</Box>
|
||||||
|
</Paper>
|
||||||
|
</Container>
|
||||||
|
|
||||||
|
<PurchasableAugmentations
|
||||||
|
augNames={purchasable}
|
||||||
|
ownedAugNames={owned}
|
||||||
|
player={player}
|
||||||
|
canPurchase={(player, aug) => {
|
||||||
|
return (
|
||||||
|
hasAugmentationPrereqs(aug) &&
|
||||||
|
props.faction.playerReputation >= aug.baseRepRequirement &&
|
||||||
|
(aug.baseCost === 0 || player.money > aug.baseCost)
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
purchaseAugmentation={(player, aug, showModal) => {
|
||||||
|
if (!Settings.SuppressBuyAugmentationConfirmation) {
|
||||||
|
showModal(true);
|
||||||
|
} else {
|
||||||
|
purchaseAugmentation(aug, props.faction);
|
||||||
|
rerender();
|
||||||
}
|
}
|
||||||
>
|
}}
|
||||||
{multiplierComponent}
|
rep={props.faction.playerReputation}
|
||||||
</Tooltip>
|
faction={props.faction}
|
||||||
</Box>
|
/>
|
||||||
<Button onClick={() => switchSortOrder(PurchaseAugmentationsOrderSetting.Cost)}>Sort by Cost</Button>
|
|
||||||
<Button onClick={() => switchSortOrder(PurchaseAugmentationsOrderSetting.Reputation)}>Sort by Reputation</Button>
|
|
||||||
<Button onClick={() => switchSortOrder(PurchaseAugmentationsOrderSetting.Default)}>Sort by Default Order</Button>
|
|
||||||
<Button onClick={() => switchSortOrder(PurchaseAugmentationsOrderSetting.Purchasable)}>
|
|
||||||
Sort by Purchasable
|
|
||||||
</Button>
|
|
||||||
<br />
|
|
||||||
|
|
||||||
<Table size="small" padding="none">
|
|
||||||
<TableBody>{augListElems}</TableBody>
|
|
||||||
</Table>
|
|
||||||
|
|
||||||
<Table size="small" padding="none">
|
|
||||||
<TableBody>{ownedElem}</TableBody>
|
|
||||||
</Table>
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,170 +0,0 @@
|
|||||||
/**
|
|
||||||
* React component for displaying a single augmentation for purchase through
|
|
||||||
* the faction UI
|
|
||||||
*/
|
|
||||||
import React, { useState } from "react";
|
|
||||||
|
|
||||||
import { hasAugmentationPrereqs, purchaseAugmentation } from "../FactionHelpers";
|
|
||||||
import { PurchaseAugmentationModal } from "./PurchaseAugmentationModal";
|
|
||||||
|
|
||||||
import { Augmentations } from "../../Augmentation/Augmentations";
|
|
||||||
import { AugmentationNames } from "../../Augmentation/data/AugmentationNames";
|
|
||||||
import { Faction } from "../Faction";
|
|
||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
|
||||||
import { Settings } from "../../Settings/Settings";
|
|
||||||
import { Money } from "../../ui/React/Money";
|
|
||||||
import { Reputation } from "../../ui/React/Reputation";
|
|
||||||
|
|
||||||
import { Augmentation as AugFormat } from "../../ui/React/Augmentation";
|
|
||||||
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";
|
|
||||||
import { getNextNeuroFluxLevel } from "../../Augmentation/AugmentationHelpers";
|
|
||||||
|
|
||||||
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 key={1} colSpan={2}>
|
|
||||||
<Typography color="error">
|
|
||||||
Requires{" "}
|
|
||||||
{aug.prereqs.map((aug, i) => (
|
|
||||||
<AugFormat key={i} name={aug} />
|
|
||||||
))}
|
|
||||||
</Typography>
|
|
||||||
</TableCell>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<React.Fragment key="f">
|
|
||||||
<TableCell key={1}>
|
|
||||||
<Typography>
|
|
||||||
<Money money={props.cost} player={props.p} />
|
|
||||||
</Typography>
|
|
||||||
</TableCell>
|
|
||||||
<TableCell key={2}>
|
|
||||||
<Typography color={props.hasRep ? "primary" : "error"}>
|
|
||||||
Requires <Reputation reputation={props.rep} /> faction reputation
|
|
||||||
</Typography>
|
|
||||||
</TableCell>
|
|
||||||
</React.Fragment>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
interface IProps {
|
|
||||||
augName: string;
|
|
||||||
faction: Faction;
|
|
||||||
p: IPlayer;
|
|
||||||
rerender: () => void;
|
|
||||||
owned?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function PurchaseableAugmentation(props: IProps): React.ReactElement {
|
|
||||||
const [open, setOpen] = useState(false);
|
|
||||||
const aug = Augmentations[props.augName];
|
|
||||||
if (aug == null) throw new Error(`aug ${props.augName} does not exists`);
|
|
||||||
|
|
||||||
if (aug == null) {
|
|
||||||
console.error(
|
|
||||||
`Invalid Augmentation when trying to create PurchaseableAugmentation display element: ${props.augName}`,
|
|
||||||
);
|
|
||||||
return <></>;
|
|
||||||
}
|
|
||||||
|
|
||||||
const moneyCost = aug.baseCost;
|
|
||||||
const repCost = aug.baseRepRequirement;
|
|
||||||
const hasReq = hasAugmentationPrereqs(aug);
|
|
||||||
const hasRep = props.faction.playerReputation >= repCost;
|
|
||||||
const hasCost = aug.baseCost === 0 || props.p.money > aug.baseCost;
|
|
||||||
|
|
||||||
// Determine UI properties
|
|
||||||
const color: "error" | "primary" = !hasReq || !hasRep || !hasCost ? "error" : "primary";
|
|
||||||
|
|
||||||
// Determine button txt
|
|
||||||
let btnTxt = aug.name;
|
|
||||||
if (aug.name === AugmentationNames.NeuroFluxGovernor) {
|
|
||||||
btnTxt += ` - Level ${getNextNeuroFluxLevel()}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
let tooltip = <></>;
|
|
||||||
if (typeof aug.info === "string") {
|
|
||||||
tooltip = (
|
|
||||||
<>
|
|
||||||
<span>{aug.info}</span>
|
|
||||||
<br />
|
|
||||||
<br />
|
|
||||||
{aug.stats}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
} else
|
|
||||||
tooltip = (
|
|
||||||
<>
|
|
||||||
{aug.info}
|
|
||||||
<br />
|
|
||||||
<br />
|
|
||||||
{aug.stats}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
|
|
||||||
function handleClick(): void {
|
|
||||||
if (color === "error") return;
|
|
||||||
if (!Settings.SuppressBuyAugmentationConfirmation) {
|
|
||||||
setOpen(true);
|
|
||||||
} else {
|
|
||||||
purchaseAugmentation(aug, props.faction);
|
|
||||||
props.rerender();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<TableRow>
|
|
||||||
{!props.owned && (
|
|
||||||
<TableCell key={0}>
|
|
||||||
<Button onClick={handleClick} color={color}>
|
|
||||||
Buy
|
|
||||||
</Button>
|
|
||||||
<PurchaseAugmentationModal
|
|
||||||
open={open}
|
|
||||||
onClose={() => setOpen(false)}
|
|
||||||
aug={aug}
|
|
||||||
faction={props.faction}
|
|
||||||
rerender={props.rerender}
|
|
||||||
/>
|
|
||||||
</TableCell>
|
|
||||||
)}
|
|
||||||
<TableCell key={1}>
|
|
||||||
<Box display="flex">
|
|
||||||
<Tooltip title={<Typography>{tooltip}</Typography>} placement="top">
|
|
||||||
<Typography>{btnTxt}</Typography>
|
|
||||||
</Tooltip>
|
|
||||||
</Box>
|
|
||||||
</TableCell>
|
|
||||||
{!props.owned && (
|
|
||||||
<Requirements
|
|
||||||
key={2}
|
|
||||||
augName={props.augName}
|
|
||||||
p={props.p}
|
|
||||||
cost={moneyCost}
|
|
||||||
rep={repCost}
|
|
||||||
hasReq={hasReq}
|
|
||||||
hasRep={hasRep}
|
|
||||||
hasCost={hasCost}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</TableRow>
|
|
||||||
);
|
|
||||||
}
|
|
@ -139,34 +139,37 @@ export const GraftingRoot = (): React.ReactElement => {
|
|||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<Typography color={Settings.theme.info}>
|
<Box sx={{ maxHeight: 330, overflowY: "scroll" }}>
|
||||||
<b>Time to Graft:</b>{" "}
|
<Typography color={Settings.theme.info}>
|
||||||
{convertTimeMsToTimeElapsedString(
|
<b>Time to Graft:</b>{" "}
|
||||||
calculateGraftingTimeWithBonus(player, GraftableAugmentations[selectedAug]),
|
{convertTimeMsToTimeElapsedString(
|
||||||
|
calculateGraftingTimeWithBonus(player, GraftableAugmentations[selectedAug]),
|
||||||
|
)}
|
||||||
|
{/* Use formula so the displayed creation time is accurate to player bonus */}
|
||||||
|
</Typography>
|
||||||
|
|
||||||
|
{Augmentations[selectedAug].prereqs.length > 0 && (
|
||||||
|
<AugPreReqsChecklist player={player} aug={Augmentations[selectedAug]} />
|
||||||
)}
|
)}
|
||||||
{/* Use formula so the displayed creation time is accurate to player bonus */}
|
<br />
|
||||||
</Typography>
|
|
||||||
{Augmentations[selectedAug].prereqs.length > 0 && (
|
|
||||||
<AugPreReqsChecklist player={player} aug={Augmentations[selectedAug]} />
|
|
||||||
)}
|
|
||||||
|
|
||||||
<br />
|
<Typography>
|
||||||
<Typography sx={{ maxHeight: 305, overflowY: "scroll" }}>
|
{(() => {
|
||||||
{(() => {
|
const aug = Augmentations[selectedAug];
|
||||||
const aug = Augmentations[selectedAug];
|
|
||||||
|
|
||||||
const info = typeof aug.info === "string" ? <span>{aug.info}</span> : aug.info;
|
const info = typeof aug.info === "string" ? <span>{aug.info}</span> : aug.info;
|
||||||
const tooltip = (
|
const tooltip = (
|
||||||
<>
|
<>
|
||||||
{info}
|
{info}
|
||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
{aug.stats}
|
{aug.stats}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
return tooltip;
|
return tooltip;
|
||||||
})()}
|
})()}
|
||||||
</Typography>
|
</Typography>
|
||||||
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
</Paper>
|
</Paper>
|
||||||
) : (
|
) : (
|
||||||
|
@ -1,20 +1,10 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
import { Container, Typography, Paper } from "@mui/material";
|
||||||
|
import React, { useEffect, useState } from "react";
|
||||||
|
import { PurchasableAugmentations } from "../../../Augmentation/ui/PurchasableAugmentations";
|
||||||
|
import { use } from "../../../ui/Context";
|
||||||
|
import { Modal } from "../../../ui/React/Modal";
|
||||||
import { Sleeve } from "../Sleeve";
|
import { Sleeve } from "../Sleeve";
|
||||||
import { findSleevePurchasableAugs } from "../SleeveHelpers";
|
import { findSleevePurchasableAugs } from "../SleeveHelpers";
|
||||||
import { Augmentations } from "../../../Augmentation/Augmentations";
|
|
||||||
import { Augmentation } from "../../../Augmentation/Augmentation";
|
|
||||||
import { Money } from "../../../ui/React/Money";
|
|
||||||
import { Modal } from "../../../ui/React/Modal";
|
|
||||||
import { use } from "../../../ui/Context";
|
|
||||||
import Typography from "@mui/material/Typography";
|
|
||||||
import Tooltip from "@mui/material/Tooltip";
|
|
||||||
import Paper from "@mui/material/Paper";
|
|
||||||
import Box from "@mui/material/Box";
|
|
||||||
import Button from "@mui/material/Button";
|
|
||||||
import TableBody from "@mui/material/TableBody";
|
|
||||||
import Table from "@mui/material/Table";
|
|
||||||
import { TableCell } from "../../../ui/React/Table";
|
|
||||||
import TableRow from "@mui/material/TableRow";
|
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
open: boolean;
|
open: boolean;
|
||||||
@ -42,80 +32,34 @@ export function SleeveAugmentationsModal(props: IProps): React.ReactElement {
|
|||||||
// and you must also have enough rep in that faction in order to purchase it.
|
// and you must also have enough rep in that faction in order to purchase it.
|
||||||
const availableAugs = findSleevePurchasableAugs(props.sleeve, player);
|
const availableAugs = findSleevePurchasableAugs(props.sleeve, player);
|
||||||
|
|
||||||
function purchaseAugmentation(aug: Augmentation): void {
|
|
||||||
props.sleeve.tryBuyAugmentation(player, aug);
|
|
||||||
rerender();
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal open={props.open} onClose={props.onClose}>
|
<Modal open={props.open} onClose={props.onClose}>
|
||||||
<>
|
<Container component={Paper} disableGutters maxWidth="lg" sx={{ mx: 0, mb: 1, p: 1 }}>
|
||||||
<Box sx={{ mx: 1 }}>
|
<Typography>
|
||||||
<Typography>
|
You can purchase Augmentations for your Duplicate Sleeves. These Augmentations have the same effect as they
|
||||||
You can purchase Augmentations for your Duplicate Sleeves. These Augmentations have the same effect as they
|
would for you. You can only purchase Augmentations that you have unlocked through Factions.
|
||||||
would for you. You can only purchase Augmentations that you have unlocked through Factions.
|
<br />
|
||||||
<br />
|
<br />
|
||||||
<br />
|
When purchasing an Augmentation for a Duplicate Sleeve, they are immediately installed. This means that the
|
||||||
When purchasing an Augmentation for a Duplicate Sleeve, they are immediately installed. This means that the
|
Duplicate Sleeve will immediately lose all of its stat experience.
|
||||||
Duplicate Sleeve will immediately lose all of its stat experience.
|
<br />
|
||||||
</Typography>
|
<br />
|
||||||
<Box component={Paper} sx={{ my: 1, p: 1 }}>
|
Augmentations will appear below as they become available.
|
||||||
<Table size="small" padding="none">
|
</Typography>
|
||||||
<TableBody>
|
</Container>
|
||||||
{availableAugs.map((aug) => {
|
<PurchasableAugmentations
|
||||||
return (
|
augNames={availableAugs.map((aug) => aug.name)}
|
||||||
<TableRow key={aug.name}>
|
ownedAugNames={ownedAugNames}
|
||||||
<TableCell>
|
player={player}
|
||||||
<Button onClick={() => purchaseAugmentation(aug)} disabled={player.money < aug.startingCost}>
|
canPurchase={(player, aug) => {
|
||||||
Buy
|
return player.money > aug.startingCost;
|
||||||
</Button>
|
}}
|
||||||
</TableCell>
|
purchaseAugmentation={(player, aug, _showModal) => {
|
||||||
<TableCell>
|
props.sleeve.tryBuyAugmentation(player, aug);
|
||||||
<Box display="flex">
|
rerender();
|
||||||
<Tooltip title={aug.stats || ""}>
|
}}
|
||||||
<Typography>{aug.name}</Typography>
|
sleeveAugs
|
||||||
</Tooltip>
|
/>
|
||||||
</Box>
|
|
||||||
</TableCell>
|
|
||||||
<TableCell>
|
|
||||||
<Money money={aug.startingCost} player={player} />
|
|
||||||
</TableCell>
|
|
||||||
</TableRow>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</TableBody>
|
|
||||||
</Table>
|
|
||||||
</Box>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
{ownedAugNames.length > 0 && (
|
|
||||||
<>
|
|
||||||
<Typography sx={{ mx: 1 }}>Owned Augmentations:</Typography>
|
|
||||||
<Box display="grid" sx={{ gridTemplateColumns: "repeat(5, 1fr)", m: 1 }}>
|
|
||||||
{ownedAugNames.map((augName) => {
|
|
||||||
const aug = Augmentations[augName];
|
|
||||||
const info = typeof aug.info === "string" ? <span>{aug.info}</span> : aug.info;
|
|
||||||
const tooltip = (
|
|
||||||
<>
|
|
||||||
{info}
|
|
||||||
<br />
|
|
||||||
<br />
|
|
||||||
{aug.stats}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Tooltip key={augName} title={<Typography>{tooltip}</Typography>}>
|
|
||||||
<Paper sx={{ p: 1 }}>
|
|
||||||
<Typography>{augName}</Typography>
|
|
||||||
</Paper>
|
|
||||||
</Tooltip>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</Box>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
</Modal>
|
</Modal>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user