diff --git a/src/Locations/ui/SpecialLocation.tsx b/src/Locations/ui/SpecialLocation.tsx index d7be2c170..6e0d77d6e 100644 --- a/src/Locations/ui/SpecialLocation.tsx +++ b/src/Locations/ui/SpecialLocation.tsx @@ -54,7 +54,7 @@ export function SpecialLocation(props: IProps): React.ReactElement { router.toBladeburner(); } else if (p.strength >= 100 && p.defense >= 100 && p.dexterity >= 100 && p.agility >= 100) { // Apply for Bladeburner division - p.startBladeburner({new: true}); + p.startBladeburner({ new: true }); dialogBoxCreate("You have been accepted into the Bladeburner division!"); setRerender((old) => !old); @@ -71,8 +71,8 @@ export function SpecialLocation(props: IProps): React.ReactElement { /** * Click handler for Resleeving button at New Tokyo VitaLife */ - function handleResleeving(): void { - router.toResleeves(); + function handleGrafting(): void { + router.toGrafting(); } function renderBladeburner(): React.ReactElement { @@ -150,11 +150,11 @@ export function SpecialLocation(props: IProps): React.ReactElement { ); } - function renderResleeving(): React.ReactElement { - if (!player.canAccessResleeving()) { + function renderGrafting(): React.ReactElement { + if (!player.canAccessGrafting()) { return <></>; } - return <Button onClick={handleResleeving}>Re-Sleeve</Button>; + return <Button onClick={handleGrafting} sx={{ my: 5 }}>Enter the secret lab</Button>; } function handleCotMG(): void { @@ -174,35 +174,35 @@ export function SpecialLocation(props: IProps): React.ReactElement { function renderCotMG(): React.ReactElement { // prettier-ignore - const symbol = <Typography sx={{lineHeight: '1em',whiteSpace: 'pre'}}> - {" `` "}<br /> - {" -odmmNmds: "}<br /> - {" `hNmo:..-omNh. "}<br /> - {" yMd` `hNh "}<br /> - {" mMd oNm "}<br /> - {" oMNo .mM/ "}<br /> - {" `dMN+ -mM+ "}<br /> - {" -mMNo -mN+ "}<br /> - {" .+- :mMNo/mN/ "}<br /> - {":yNMd. :NMNNN/ "}<br /> - {"-mMMMh. /NMMh` "}<br /> - {" .dMMMd. /NMMMy` "}<br /> - {" `yMMMd. /NNyNMMh` "}<br /> - {" `sMMMd. +Nm: +NMMh. "}<br /> - {" oMMMm- oNm: /NMMd. "}<br /> - {" +NMMmsMm- :mMMd. "}<br /> - {" /NMMMm- -mMMd. "}<br /> - {" /MMMm- -mMMd. "}<br /> - {" `sMNMMm- .mMmo "}<br /> - {" `sMd:hMMm. ./. "}<br /> - {" `yMy` `yNMd` "}<br /> - {" `hMs` oMMy "}<br /> - {" `hMh sMN- "}<br /> - {" /MM- .NMo "}<br /> - {" +MM: :MM+ "}<br /> - {" sNNo-.`.-omNy` "}<br /> - {" -smNNNNmdo- "}<br /> - {" `..` "}</Typography> + const symbol = <Typography sx={{ lineHeight: '1em', whiteSpace: 'pre' }}> + {" `` "}<br /> + {" -odmmNmds: "}<br /> + {" `hNmo:..-omNh. "}<br /> + {" yMd` `hNh "}<br /> + {" mMd oNm "}<br /> + {" oMNo .mM/ "}<br /> + {" `dMN+ -mM+ "}<br /> + {" -mMNo -mN+ "}<br /> + {" .+- :mMNo/mN/ "}<br /> + {":yNMd. :NMNNN/ "}<br /> + {"-mMMMh. /NMMh` "}<br /> + {" .dMMMd. /NMMMy` "}<br /> + {" `yMMMd. /NNyNMMh` "}<br /> + {" `sMMMd. +Nm: +NMMh. "}<br /> + {" oMMMm- oNm: /NMMd. "}<br /> + {" +NMMmsMm- :mMMd. "}<br /> + {" /NMMMm- -mMMd. "}<br /> + {" /MMMm- -mMMd. "}<br /> + {" `sMNMMm- .mMmo "}<br /> + {" `sMd:hMMm. ./. "}<br /> + {" `yMy` `yNMd` "}<br /> + {" `hMs` oMMy "}<br /> + {" `hMh sMN- "}<br /> + {" /MM- .NMo "}<br /> + {" +MM: :MM+ "}<br /> + {" sNNo-.`.-omNy` "}<br /> + {" -smNNNNmdo- "}<br /> + {" `..` "}</Typography> if (player.hasAugmentation(AugmentationNames.StaneksGift3, true)) { return ( <> @@ -298,7 +298,7 @@ export function SpecialLocation(props: IProps): React.ReactElement { switch (props.loc.name) { case LocationName.NewTokyoVitaLife: { - return renderResleeving(); + return renderGrafting(); } case LocationName.Sector12CityHall: { return <CreateCorporation />; diff --git a/src/PersonObjects/Grafting/formulas/.gitkeep b/src/PersonObjects/Grafting/formulas/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/src/PersonObjects/Grafting/ui/GraftingRoot.tsx b/src/PersonObjects/Grafting/ui/GraftingRoot.tsx new file mode 100644 index 000000000..7efa09eca --- /dev/null +++ b/src/PersonObjects/Grafting/ui/GraftingRoot.tsx @@ -0,0 +1,103 @@ +import React, { useState } from "react"; + +import { + Typography, + Container, + Box, + Paper, + List, + ListItemButton, + Button +} from "@mui/material"; +import { + Construction +} from "@mui/icons-material"; + +import { use } from "../../../ui/Context"; +import { Augmentations } from "../../../Augmentation/Augmentations"; +import { AugmentationNames } from "../../../Augmentation/data/AugmentationNames" +import { Settings } from "../../../Settings/Settings"; + +import { IPlayer } from "../../IPlayer"; + +const getAvailableAugs = (player: IPlayer): string[] => { + const augs: string[] = []; + + for (const [augName, aug] of Object.entries(Augmentations)) { + if ( + augName === AugmentationNames.NeuroFluxGovernor || + augName === AugmentationNames.TheRedPill || + aug.isSpecial + ) continue; + augs.push(augName); + } + + return augs.filter( + (augmentation: string) => !player.hasAugmentation(augmentation) + ); +} + +export const GraftingRoot = (): React.ReactElement => { + const player = use.Player(); + const [selectedAug, setSelectedAug] = useState(getAvailableAugs(player)[0]); + + return <> + <Container disableGutters maxWidth="lg" sx={{ mx: 0 }}> + <Typography variant="h4">Grafting Laboratory</Typography> + <Typography> + blah blah blah exposition that isn't important right now <br /> + Lorem ipsum dolor sit amet et et sed et et sanctus duo vero. + Stet amet iriure consetetur elit in magna et diam dolores invidunt ipsum gubergren nihil. + Diam et et ipsum consectetuer voluptua et clita lorem sit. + Et et lorem id no suscipit wisi. + Illum velit takimata et aliquyam takimata labore vel dolor dolores duo amet lorem elitr facer invidunt. + </Typography> + + <Box sx={{ my: 5 }}> + <Typography variant="h5">Craft Augmentations</Typography> + <Typography> + here goes a list with available augmentations with a purchase button (with price shown) to the side of it <br /> + getAvailableAugs function to the rescue + </Typography> + <Paper sx={{ my: 1, width: 'fit-content', display: 'grid', gridTemplateColumns: '1fr 3fr' }}> + <List sx={{ maxHeight: 400, overflowY: 'scroll', borderRight: `1px solid ${Settings.theme.welllight}` }}> + {getAvailableAugs(player).map((k, i) => ( + <ListItemButton key={i + 1} onClick={() => setSelectedAug(k)} selected={selectedAug === k}> + <Typography> + {k} + </Typography> + </ListItemButton> + ))} + </List> + <Box sx={{ m: 1 }}> + <Typography variant="h6" sx={{ display: 'flex', alignItems: 'center', flexWrap: 'wrap' }}> + <Construction sx={{ mr: 1 }} /> {selectedAug} + </Typography> + <Button sx={{ width: '100%' }}> + Craft Augmentation (<Typography color={Settings.theme.money}>$foo</Typography>) + </Button> + <Typography color={Settings.theme.info}> + <b>Time to Craft:</b> bar + </Typography> + <Typography sx={{ maxHeight: 305, overflowY: 'scroll' }}> + {(() => { + const aug = Augmentations[selectedAug]; + + const info = typeof aug.info === "string" ? <span>{aug.info}</span> : aug.info + const tooltip = (<>{info}<br /><br />{aug.stats}</>); + return tooltip; + })()} + </Typography> + </Box> + </Paper> + </Box> + + <Box sx={{ my: 5 }}> + <Typography variant="h5">name tbd</Typography> + <Typography> + probably some info about the cumulative negative effects here + </Typography> + </Box> + </Container> + </> +} diff --git a/src/PersonObjects/IPlayer.ts b/src/PersonObjects/IPlayer.ts index 7b5053adc..24470271e 100644 --- a/src/PersonObjects/IPlayer.ts +++ b/src/PersonObjects/IPlayer.ts @@ -181,7 +181,7 @@ export interface IPlayer { canAccessBladeburner(): boolean; canAccessCorporation(): boolean; canAccessGang(): boolean; - canAccessResleeving(): boolean; + canAccessGrafting(): boolean; canAfford(cost: number): boolean; gainHackingExp(exp: number): void; gainStrengthExp(exp: number): void; diff --git a/src/PersonObjects/Player/PlayerObject.ts b/src/PersonObjects/Player/PlayerObject.ts index 0ecf6628c..4d1500ef1 100644 --- a/src/PersonObjects/Player/PlayerObject.ts +++ b/src/PersonObjects/Player/PlayerObject.ts @@ -190,7 +190,7 @@ export class PlayerObject implements IPlayer { canAccessBladeburner: () => boolean; canAccessCorporation: () => boolean; canAccessGang: () => boolean; - canAccessResleeving: () => boolean; + canAccessGrafting: () => boolean; canAfford: (cost: number) => boolean; gainHackingExp: (exp: number) => void; gainStrengthExp: (exp: number) => void; @@ -577,7 +577,7 @@ export class PlayerObject implements IPlayer { this.gainCodingContractReward = generalMethods.gainCodingContractReward; this.travel = generalMethods.travel; this.gotoLocation = generalMethods.gotoLocation; - this.canAccessResleeving = generalMethods.canAccessResleeving; + this.canAccessGrafting = generalMethods.canAccessGrafting; this.giveExploit = generalMethods.giveExploit; this.giveAchievement = generalMethods.giveAchievement; this.getIntelligenceBonus = generalMethods.getIntelligenceBonus; diff --git a/src/PersonObjects/Player/PlayerObjectGeneralMethods.tsx b/src/PersonObjects/Player/PlayerObjectGeneralMethods.tsx index ee97fc982..238e2893f 100644 --- a/src/PersonObjects/Player/PlayerObjectGeneralMethods.tsx +++ b/src/PersonObjects/Player/PlayerObjectGeneralMethods.tsx @@ -2641,7 +2641,7 @@ export function gotoLocation(this: IPlayer, to: LocationName): boolean { return true; } -export function canAccessResleeving(this: IPlayer): boolean { +export function canAccessGrafting(this: IPlayer): boolean { return this.bitNodeN === 10 || SourceFileFlags[10] > 0; } diff --git a/src/Sidebar/ui/SidebarRoot.tsx b/src/Sidebar/ui/SidebarRoot.tsx index bd1a1fbf8..b1d98e2ea 100644 --- a/src/Sidebar/ui/SidebarRoot.tsx +++ b/src/Sidebar/ui/SidebarRoot.tsx @@ -617,7 +617,7 @@ export function SidebarRoot(props: IProps): React.ReactElement { key={"City"} className={clsx({ [classes.active]: - props.page === Page.City || props.page === Page.Resleeves || props.page === Page.Location, + props.page === Page.City || props.page === Page.Grafting || props.page === Page.Location, })} onClick={clickCity} > diff --git a/src/ui/GameRoot.tsx b/src/ui/GameRoot.tsx index 40790ab3e..ed0114ccc 100644 --- a/src/ui/GameRoot.tsx +++ b/src/ui/GameRoot.tsx @@ -42,7 +42,7 @@ import { BladeburnerRoot } from "../Bladeburner/ui/BladeburnerRoot"; import { GangRoot } from "../Gang/ui/GangRoot"; import { CorporationRoot } from "../Corporation/ui/CorporationRoot"; import { InfiltrationRoot } from "../Infiltration/ui/InfiltrationRoot"; -import { ResleeveRoot } from "../PersonObjects/Resleeving/ui/ResleeveRoot"; +import { GraftingRoot } from "../PersonObjects/Grafting/ui/GraftingRoot"; import { WorkInProgressRoot } from "./WorkInProgressRoot"; import { GameOptionsRoot } from "./React/GameOptionsRoot"; import { SleeveRoot } from "../PersonObjects/Sleeve/ui/SleeveRoot"; @@ -135,7 +135,7 @@ export let Router: IRouter = { toInfiltration: uninitialized, toJob: uninitialized, toMilestones: uninitialized, - toResleeves: uninitialized, + toGrafting: uninitialized, toScriptEditor: uninitialized, toSleeves: uninitialized, toStockMarket: uninitialized, @@ -226,7 +226,7 @@ export function GameRoot({ player, engine, terminal }: IProps): React.ReactEleme toGang: () => setPage(Page.Gang), toHacknetNodes: () => setPage(Page.Hacknet), toMilestones: () => setPage(Page.Milestones), - toResleeves: () => setPage(Page.Resleeves), + toGrafting: () => setPage(Page.Grafting), toScriptEditor: (files: Record<string, string>, options?: ScriptEditorRouteOptions) => { setEditorOptions({ files, @@ -429,8 +429,8 @@ export function GameRoot({ player, engine, terminal }: IProps): React.ReactEleme mainPage = <BladeburnerRoot />; break; } - case Page.Resleeves: { - mainPage = <ResleeveRoot />; + case Page.Grafting: { + mainPage = <GraftingRoot />; break; } case Page.Travel: { diff --git a/src/ui/Router.ts b/src/ui/Router.ts index 2e4613611..e761d917c 100644 --- a/src/ui/Router.ts +++ b/src/ui/Router.ts @@ -23,7 +23,7 @@ export enum Page { Job, Milestones, Options, - Resleeves, + Grafting, Sleeves, Stats, StockMarket, @@ -74,7 +74,7 @@ export interface IRouter { toInfiltration(location: Location): void; toJob(): void; toMilestones(): void; - toResleeves(): void; + toGrafting(): void; toScriptEditor(files?: Record<string, string>, options?: ScriptEditorRouteOptions): void; toSleeves(): void; toStockMarket(): void;