From b7f78b11ddfab36514c64409382f26fd8301bed5 Mon Sep 17 00:00:00 2001 From: Undeemiss Date: Thu, 21 Apr 2022 21:38:04 -0500 Subject: [PATCH 01/30] BREAKING: Capitalized the E in the hamming code encoding contract --- src/data/codingcontracttypes.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/data/codingcontracttypes.ts b/src/data/codingcontracttypes.ts index c1af176a3..dd9f57ea4 100644 --- a/src/data/codingcontracttypes.ts +++ b/src/data/codingcontracttypes.ts @@ -1249,7 +1249,7 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [ }, }, { - name: "HammingCodes: Integer to encoded Binary", + name: "HammingCodes: Integer to Encoded Binary", numTries: 10, difficulty: 5, desc: (n: number): string => { From c6327ee6822263d2af27d2a9a89e0320252c76f7 Mon Sep 17 00:00:00 2001 From: JP Sugarbroad Date: Mon, 18 Apr 2022 17:47:33 -0700 Subject: [PATCH 02/30] add better typing to Electron.tsx --- src/@types/global.d.ts | 7 +++- src/Achievements/Achievements.ts | 2 +- src/Electron.tsx | 71 +++++++++++++++++++++----------- 3 files changed, 55 insertions(+), 25 deletions(-) diff --git a/src/@types/global.d.ts b/src/@types/global.d.ts index 8840ea1b8..154295e4b 100644 --- a/src/@types/global.d.ts +++ b/src/@types/global.d.ts @@ -1,8 +1,13 @@ // Defined by webpack on startup or compilation -declare let __COMMIT_HASH__: string; +declare const __COMMIT_HASH__: string; // When using file-loader, we'll get a path to the resource declare module "*.png" { const value: string; export default value; } + +// Achievements communicated back to Electron shell for Steam. +declare interface Document { + achievements: string[]; +} diff --git a/src/Achievements/Achievements.ts b/src/Achievements/Achievements.ts index 2920125db..a7ac79205 100644 --- a/src/Achievements/Achievements.ts +++ b/src/Achievements/Achievements.ts @@ -798,5 +798,5 @@ export function calculateAchievements(): void { // Write all player's achievements to document for Steam/Electron // This could be replaced by "availableAchievements" // if we don't want to grant the save game achievements to steam but only currently available - (document as any).achievements = [...Player.achievements.map((a) => a.ID)]; + document.achievements = [...Player.achievements.map((a) => a.ID)]; } diff --git a/src/Electron.tsx b/src/Electron.tsx index ff31fa3c9..2c5cd35fe 100644 --- a/src/Electron.tsx +++ b/src/Electron.tsx @@ -11,11 +11,41 @@ import { exportScripts } from "./Terminal/commands/download"; import { CONSTANTS } from "./Constants"; import { hash } from "./hash/hash"; +interface IReturnWebStatus extends IReturnStatus { + data?: Record; +} + +declare global { + interface Window { + appNotifier: { + terminal: (message: string, type?: string) => void; + toast: (message: string, type: ToastVariant, duration?: number) => void; + }; + appSaveFns: { + triggerSave: () => Promise; + triggerGameExport: () => void; + triggerScriptsExport: () => void; + getSaveData: () => { save: string; fileName: string }; + getSaveInfo: (base64save: string) => Promise; + pushSaveData: (base64save: string, automatic?: boolean) => void; + }; + electronBridge: { + send: (channel: string, data?: unknown) => void; + receive: (channel: string, func: (...args: any[]) => void) => void; + }; + } + interface Document { + getFiles: () => IReturnWebStatus; + deleteFile: (filename: string) => IReturnWebStatus; + saveFile: (filename: string, code: string) => IReturnWebStatus; + } +} + export function initElectron(): void { const userAgent = navigator.userAgent.toLowerCase(); if (userAgent.indexOf(" electron/") > -1) { // Electron-specific code - (document as any).achievements = []; + document.achievements = []; initWebserver(); initAppNotifier(); initSaveFunctions(); @@ -24,11 +54,6 @@ export function initElectron(): void { } function initWebserver(): void { - interface IReturnWebStatus extends IReturnStatus { - data?: { - [propName: string]: any; - }; - } function normalizeFileName(filename: string): string { filename = filename.replace(/\/\/+/g, "/"); filename = removeLeadingSlash(filename); @@ -38,7 +63,7 @@ function initWebserver(): void { return filename; } - (document as any).getFiles = function (): IReturnWebStatus { + document.getFiles = function (): IReturnWebStatus { const home = GetServer("home"); if (home === null) { return { @@ -58,7 +83,7 @@ function initWebserver(): void { }; }; - (document as any).deleteFile = function (filename: string): IReturnWebStatus { + document.deleteFile = function (filename: string): IReturnWebStatus { filename = normalizeFileName(filename); const home = GetServer("home"); if (home === null) { @@ -70,7 +95,7 @@ function initWebserver(): void { return home.removeFile(filename); }; - (document as any).saveFile = function (filename: string, code: string): IReturnWebStatus { + document.saveFile = function (filename: string, code: string): IReturnWebStatus { filename = normalizeFileName(filename); code = Buffer.from(code, "base64").toString(); @@ -115,7 +140,7 @@ function initAppNotifier(): void { }; // Will be consumud by the electron wrapper. - (window as any).appNotifier = funcs; + window.appNotifier = funcs; } function initSaveFunctions(): void { @@ -149,38 +174,38 @@ function initSaveFunctions(): void { }; // Will be consumud by the electron wrapper. - (window as any).appSaveFns = funcs; + window.appSaveFns = funcs; } function initElectronBridge(): void { - const bridge = (window as any).electronBridge as any; + const bridge = window.electronBridge; if (!bridge) return; bridge.receive("get-save-data-request", () => { - const data = (window as any).appSaveFns.getSaveData(); + const data = window.appSaveFns.getSaveData(); bridge.send("get-save-data-response", data); }); bridge.receive("get-save-info-request", async (save: string) => { - const data = await (window as any).appSaveFns.getSaveInfo(save); + const data = await window.appSaveFns.getSaveInfo(save); bridge.send("get-save-info-response", data); }); bridge.receive("push-save-request", ({ save, automatic = false }: { save: string; automatic: boolean }) => { - (window as any).appSaveFns.pushSaveData(save, automatic); + window.appSaveFns.pushSaveData(save, automatic); }); bridge.receive("trigger-save", () => { - return (window as any).appSaveFns + return window.appSaveFns .triggerSave() .then(() => { bridge.send("save-completed"); }) - .catch((error: any) => { + .catch((error: unknown) => { console.log(error); SnackbarEvents.emit("Could not save game.", ToastVariant.ERROR, 2000); }); }); bridge.receive("trigger-game-export", () => { try { - (window as any).appSaveFns.triggerGameExport(); + window.appSaveFns.triggerGameExport(); } catch (error) { console.log(error); SnackbarEvents.emit("Could not export game.", ToastVariant.ERROR, 2000); @@ -188,7 +213,7 @@ function initElectronBridge(): void { }); bridge.receive("trigger-scripts-export", () => { try { - (window as any).appSaveFns.triggerScriptsExport(); + window.appSaveFns.triggerScriptsExport(); } catch (error) { console.log(error); SnackbarEvents.emit("Could not export scripts.", ToastVariant.ERROR, 2000); @@ -197,14 +222,14 @@ function initElectronBridge(): void { } export function pushGameSaved(data: SaveData): void { - const bridge = (window as any).electronBridge as any; + const bridge = window.electronBridge; if (!bridge) return; bridge.send("push-game-saved", data); } export function pushGameReady(): void { - const bridge = (window as any).electronBridge as any; + const bridge = window.electronBridge; if (!bridge) return; // Send basic information to the electron wrapper @@ -222,7 +247,7 @@ export function pushGameReady(): void { } export function pushImportResult(wasImported: boolean): void { - const bridge = (window as any).electronBridge as any; + const bridge = window.electronBridge; if (!bridge) return; bridge.send("push-import-result", { wasImported }); @@ -230,7 +255,7 @@ export function pushImportResult(wasImported: boolean): void { } export function pushDisableRestore(): void { - const bridge = (window as any).electronBridge as any; + const bridge = window.electronBridge; if (!bridge) return; bridge.send("push-disable-restore", { duration: 1000 * 60 }); From bececf7a6f064d8e11addc88b32829a33af202d7 Mon Sep 17 00:00:00 2001 From: nickofolas Date: Fri, 22 Apr 2022 11:19:47 -0500 Subject: [PATCH 03/30] Move purchaseable aug files around --- .../ui/PurchaseAugmentationModal.tsx | 8 ++++---- .../ui/PurchaseableAugmentations.tsx} | 8 ++++---- src/Faction/ui/AugmentationsPage.tsx | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) rename src/{Faction => Augmentation}/ui/PurchaseAugmentationModal.tsx (84%) rename src/{Faction/ui/PurchaseableAugmentation.tsx => Augmentation/ui/PurchaseableAugmentations.tsx} (95%) diff --git a/src/Faction/ui/PurchaseAugmentationModal.tsx b/src/Augmentation/ui/PurchaseAugmentationModal.tsx similarity index 84% rename from src/Faction/ui/PurchaseAugmentationModal.tsx rename to src/Augmentation/ui/PurchaseAugmentationModal.tsx index 658978aaf..58c4cf76c 100644 --- a/src/Faction/ui/PurchaseAugmentationModal.tsx +++ b/src/Augmentation/ui/PurchaseAugmentationModal.tsx @@ -1,9 +1,9 @@ import React from "react"; -import { Augmentation } from "../../Augmentation/Augmentation"; -import { Faction } from "../Faction"; -import { purchaseAugmentation } from "../FactionHelpers"; -import { isRepeatableAug } from "../../Augmentation/AugmentationHelpers"; +import { Augmentation } from "../Augmentation"; +import { Faction } from "../../Faction/Faction"; +import { purchaseAugmentation } from "../../Faction/FactionHelpers"; +import { isRepeatableAug } from "../AugmentationHelpers"; import { Money } from "../../ui/React/Money"; import { Modal } from "../../ui/React/Modal"; import { use } from "../../ui/Context"; diff --git a/src/Faction/ui/PurchaseableAugmentation.tsx b/src/Augmentation/ui/PurchaseableAugmentations.tsx similarity index 95% rename from src/Faction/ui/PurchaseableAugmentation.tsx rename to src/Augmentation/ui/PurchaseableAugmentations.tsx index 2e6b34910..b9da1f2a3 100644 --- a/src/Faction/ui/PurchaseableAugmentation.tsx +++ b/src/Augmentation/ui/PurchaseableAugmentations.tsx @@ -4,12 +4,12 @@ */ import React, { useState } from "react"; -import { getNextNeurofluxLevel, hasAugmentationPrereqs, purchaseAugmentation } from "../FactionHelpers"; +import { getNextNeurofluxLevel, hasAugmentationPrereqs, purchaseAugmentation } from "../../Faction/FactionHelpers"; import { PurchaseAugmentationModal } from "./PurchaseAugmentationModal"; -import { Augmentations } from "../../Augmentation/Augmentations"; -import { AugmentationNames } from "../../Augmentation/data/AugmentationNames"; -import { Faction } from "../Faction"; +import { Augmentations } from "../Augmentations"; +import { AugmentationNames } from "../data/AugmentationNames"; +import { Faction } from "../../Faction/Faction"; import { IPlayer } from "../../PersonObjects/IPlayer"; import { Settings } from "../../Settings/Settings"; import { Money } from "../../ui/React/Money"; diff --git a/src/Faction/ui/AugmentationsPage.tsx b/src/Faction/ui/AugmentationsPage.tsx index b5acaee49..c2d24c3be 100644 --- a/src/Faction/ui/AugmentationsPage.tsx +++ b/src/Faction/ui/AugmentationsPage.tsx @@ -3,7 +3,7 @@ */ import React, { useState } from "react"; -import { PurchaseableAugmentation } from "./PurchaseableAugmentation"; +import { PurchaseableAugmentation } from "../../Augmentation/ui/PurchaseableAugmentations"; import { Augmentations } from "../../Augmentation/Augmentations"; import { AugmentationNames } from "../../Augmentation/data/AugmentationNames"; From 7853144b1862ed1dcbb7e010ab0d3b42e849b15c Mon Sep 17 00:00:00 2001 From: nickofolas Date: Fri, 22 Apr 2022 12:50:51 -0500 Subject: [PATCH 04/30] Initial changes to purchaseable augs --- .../ui/PurchaseableAugmentations.tsx | 182 ++++++++++++++---- src/Faction/ui/AugmentationsPage.tsx | 58 ++++-- 2 files changed, 178 insertions(+), 62 deletions(-) diff --git a/src/Augmentation/ui/PurchaseableAugmentations.tsx b/src/Augmentation/ui/PurchaseableAugmentations.tsx index b9da1f2a3..e931de57a 100644 --- a/src/Augmentation/ui/PurchaseableAugmentations.tsx +++ b/src/Augmentation/ui/PurchaseableAugmentations.tsx @@ -12,59 +12,159 @@ import { AugmentationNames } from "../data/AugmentationNames"; import { Faction } from "../../Faction/Faction"; import { IPlayer } from "../../PersonObjects/IPlayer"; import { Settings } from "../../Settings/Settings"; +import { numeralWrapper } from "../../ui/numeralFormat"; import { Money } from "../../ui/React/Money"; import { Reputation } from "../../ui/React/Reputation"; +import { CheckBox, CheckBoxOutlineBlank } from "@mui/icons-material"; 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 { Paper, Button, Typography, Tooltip, Box, TableRow, Container, List, ListItem } from "@mui/material"; import { TableCell } from "../../ui/React/Table"; -import TableRow from "@mui/material/TableRow"; +import { Augmentation } from "../Augmentation"; + +// 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 ( +// +// +// Requires{" "} +// {aug.prereqs.map((aug, i) => ( +// +// ))} +// +// +// ); +// } + +// return ( +// +// +// +// +// +// +// +// +// Requires faction reputation +// +// +// +// ); +// } interface IReqProps { - augName: string; - p: IPlayer; - hasReq: boolean; - rep: number; - hasRep: boolean; - cost: number; - hasCost: boolean; + value: string; + valueColor: string; + fulfilled: boolean; } -function Requirements(props: IReqProps): React.ReactElement { - const aug = Augmentations[props.augName]; - if (!props.hasReq) { - return ( - - - Requires{" "} - {aug.prereqs.map((aug, i) => ( - - ))} - - - ); - } - +const Requirement = (props: IReqProps): React.ReactElement => { return ( - - - - - - - - - Requires faction reputation - - - + + {props.fulfilled ? : } + {props.value} + ); +}; + +interface IPurchaseableAugsProps { + augNames: string[]; + player: IPlayer; + + canPurchase: (player: IPlayer, aug: Augmentation) => boolean; + purchaseAugmentation: (player: IPlayer, aug: Augmentation, showModal: (open: boolean) => void) => void; + + rep?: number; } -interface IProps { +export const PurchaseableAugmentations = (props: IPurchaseableAugsProps): React.ReactElement => { + return ( + + {props.augNames.map((augName: string) => { + const aug = Augmentations[augName]; + + const info = typeof aug.info === "string" ? {aug.info} : aug.info; + const description = ( + <> + {info} +
+
+ {aug.stats} + + ); + + return ( + + + + + Cost: + + aug.baseCost} + value={numeralWrapper.formatMoney(aug.baseCost)} + valueColor={Settings.theme.money} + /> + {props.rep !== undefined && ( + = aug.baseRepRequirement} + value={`${numeralWrapper.formatReputation(aug.baseRepRequirement)} reputation`} + valueColor={Settings.theme.rep} + /> + )} + {aug.prereqs.length > 0 && ( + <> + + Pre-Requisites: + + {aug.prereqs.map((preAug) => ( + + ))} + + )} + + + {aug.name} + {description} + + + ); + })} +
+ ); +}; + +interface IPurchaseableAugProps { augName: string; faction: Faction; p: IPlayer; @@ -72,7 +172,7 @@ interface IProps { owned?: boolean; } -export function PurchaseableAugmentation(props: IProps): React.ReactElement { +export function PurchaseableAugmentation(props: IPurchaseableAugProps): React.ReactElement { const [open, setOpen] = useState(false); const aug = Augmentations[props.augName]; if (aug == null) throw new Error(`aug ${props.augName} does not exists`); diff --git a/src/Faction/ui/AugmentationsPage.tsx b/src/Faction/ui/AugmentationsPage.tsx index c2d24c3be..b8ad88522 100644 --- a/src/Faction/ui/AugmentationsPage.tsx +++ b/src/Faction/ui/AugmentationsPage.tsx @@ -1,29 +1,25 @@ /** * Root React Component for displaying a faction's "Purchase Augmentations" page */ -import React, { useState } from "react"; - -import { PurchaseableAugmentation } from "../../Augmentation/ui/PurchaseableAugmentations"; - -import { Augmentations } from "../../Augmentation/Augmentations"; -import { AugmentationNames } from "../../Augmentation/data/AugmentationNames"; -import { Faction } from "../Faction"; -import { PurchaseAugmentationsOrderSetting } from "../../Settings/SettingEnums"; -import { Settings } from "../../Settings/Settings"; -import { hasAugmentationPrereqs, getFactionAugmentationsFiltered } from "../FactionHelpers"; - -import { use } from "../../ui/Context"; -import { Reputation } from "../../ui/React/Reputation"; -import { Favor } from "../../ui/React/Favor"; -import { numeralWrapper } from "../../ui/numeralFormat"; - import Box from "@mui/material/Box"; 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 TableBody from "@mui/material/TableBody"; +import Tooltip from "@mui/material/Tooltip"; +import Typography from "@mui/material/Typography"; +import React, { useState } from "react"; import { getGenericAugmentationPriceMultiplier } from "../../Augmentation/AugmentationHelpers"; +import { Augmentations } from "../../Augmentation/Augmentations"; +import { AugmentationNames } from "../../Augmentation/data/AugmentationNames"; +import { PurchaseableAugmentation, PurchaseableAugmentations } from "../../Augmentation/ui/PurchaseableAugmentations"; +import { PurchaseAugmentationsOrderSetting } from "../../Settings/SettingEnums"; +import { Settings } from "../../Settings/Settings"; +import { use } from "../../ui/Context"; +import { numeralWrapper } from "../../ui/numeralFormat"; +import { Favor } from "../../ui/React/Favor"; +import { Reputation } from "../../ui/React/Reputation"; +import { Faction } from "../Faction"; +import { getFactionAugmentationsFiltered, hasAugmentationPrereqs, purchaseAugmentation } from "../FactionHelpers"; type IProps = { faction: Faction; @@ -198,13 +194,33 @@ export function AugmentationsPage(props: IProps): React.ReactElement {
- + { + 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(); + } + }} + rep={props.faction.playerReputation} + /> + {/*
{augListElems}
{ownedElem} -
+ */} ); } From f12a117f06929a4aa0a7233f14d22f9acde2ca7f Mon Sep 17 00:00:00 2001 From: nickofolas Date: Fri, 22 Apr 2022 13:21:20 -0500 Subject: [PATCH 05/30] Further design updates --- .../ui/PurchaseableAugmentations.tsx | 32 ++++++++------ .../Sleeve/ui/SleeveAugmentationsModal.tsx | 43 +++++++++++-------- 2 files changed, 45 insertions(+), 30 deletions(-) diff --git a/src/Augmentation/ui/PurchaseableAugmentations.tsx b/src/Augmentation/ui/PurchaseableAugmentations.tsx index e931de57a..ae40d5602 100644 --- a/src/Augmentation/ui/PurchaseableAugmentations.tsx +++ b/src/Augmentation/ui/PurchaseableAugmentations.tsx @@ -16,7 +16,7 @@ import { numeralWrapper } from "../../ui/numeralFormat"; import { Money } from "../../ui/React/Money"; import { Reputation } from "../../ui/React/Reputation"; -import { CheckBox, CheckBoxOutlineBlank } from "@mui/icons-material"; +import { CheckBox, CheckBoxOutlineBlank, Verified, Info } from "@mui/icons-material"; import { Augmentation as AugFormat } from "../../ui/React/Augmentation"; import { Paper, Button, Typography, Tooltip, Box, TableRow, Container, List, ListItem } from "@mui/material"; import { TableCell } from "../../ui/React/Table"; @@ -93,23 +93,16 @@ export const PurchaseableAugmentations = (props: IPurchaseableAugsProps): React. {props.augNames.map((augName: string) => { const aug = Augmentations[augName]; const info = typeof aug.info === "string" ? {aug.info} : aug.info; - const description = ( - <> - {info} -
-
- {aug.stats} - - ); + const description = aug.stats; return ( - + + + {aug.factions.length === 1 && ( + + + Faction-Exclusive Augmentation + + )} + Cost: @@ -137,6 +138,7 @@ export const PurchaseableAugmentations = (props: IPurchaseableAugsProps): React. valueColor={Settings.theme.rep} /> )} + {aug.prereqs.length > 0 && ( <> @@ -153,8 +155,14 @@ export const PurchaseableAugmentations = (props: IPurchaseableAugsProps): React. )} + - {aug.name} + + {info}}> + + + {aug.name} + {description} diff --git a/src/PersonObjects/Sleeve/ui/SleeveAugmentationsModal.tsx b/src/PersonObjects/Sleeve/ui/SleeveAugmentationsModal.tsx index e17118e8c..9087fffc1 100644 --- a/src/PersonObjects/Sleeve/ui/SleeveAugmentationsModal.tsx +++ b/src/PersonObjects/Sleeve/ui/SleeveAugmentationsModal.tsx @@ -3,13 +3,11 @@ import { Sleeve } from "../Sleeve"; import { findSleevePurchasableAugs } from "../SleeveHelpers"; import { Augmentations } from "../../../Augmentation/Augmentations"; import { Augmentation } from "../../../Augmentation/Augmentation"; +import { PurchaseableAugmentations } from "../../../Augmentation/ui/PurchaseableAugmentations"; 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 { Typography, Tooltip, Paper, Box, Container } from "@mui/material"; import Button from "@mui/material/Button"; import TableBody from "@mui/material/TableBody"; import Table from "@mui/material/Table"; @@ -49,17 +47,27 @@ export function SleeveAugmentationsModal(props: IProps): React.ReactElement { return ( - <> - - - 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. -
-
- 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. -
- + + + 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. +
+
+ 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. +
+ aug.name)} + player={player} + canPurchase={(player, aug) => { + return player.money > aug.startingCost; + }} + purchaseAugmentation={(player, aug, _showModal) => { + props.sleeve.tryBuyAugmentation(player, aug); + rerender(); + }} + /> + {/* {availableAugs.map((aug) => { @@ -85,8 +93,7 @@ export function SleeveAugmentationsModal(props: IProps): React.ReactElement { })}
-
-
+
*/} {ownedAugNames.length > 0 && ( <> @@ -115,7 +122,7 @@ export function SleeveAugmentationsModal(props: IProps): React.ReactElement { )} - +
); } From e77654158b63d9c6879e6babc9ff33934a2d3678 Mon Sep 17 00:00:00 2001 From: nickofolas <60761231+nickofolas@users.noreply.github.com> Date: Fri, 22 Apr 2022 15:14:34 -0500 Subject: [PATCH 06/30] Redesign the redesign --- .../ui/PurchaseableAugmentations.tsx | 139 +++++++++++------- 1 file changed, 84 insertions(+), 55 deletions(-) diff --git a/src/Augmentation/ui/PurchaseableAugmentations.tsx b/src/Augmentation/ui/PurchaseableAugmentations.tsx index ae40d5602..7062858d0 100644 --- a/src/Augmentation/ui/PurchaseableAugmentations.tsx +++ b/src/Augmentation/ui/PurchaseableAugmentations.tsx @@ -16,7 +16,7 @@ import { numeralWrapper } from "../../ui/numeralFormat"; import { Money } from "../../ui/React/Money"; import { Reputation } from "../../ui/React/Reputation"; -import { CheckBox, CheckBoxOutlineBlank, Verified, Info } from "@mui/icons-material"; +import { CheckBox, CheckBoxOutlineBlank, Verified, Info, Report, CheckCircle } from "@mui/icons-material"; import { Augmentation as AugFormat } from "../../ui/React/Augmentation"; import { Paper, Button, Typography, Tooltip, Box, TableRow, Container, List, ListItem } from "@mui/material"; import { TableCell } from "../../ui/React/Table"; @@ -65,15 +65,15 @@ import { Augmentation } from "../Augmentation"; interface IReqProps { value: string; - valueColor: string; + color: string; fulfilled: boolean; } const Requirement = (props: IReqProps): React.ReactElement => { return ( - + {props.fulfilled ? : } - {props.value} + {props.value} ); }; @@ -91,19 +91,29 @@ interface IPurchaseableAugsProps { export const PurchaseableAugmentations = (props: IPurchaseableAugsProps): React.ReactElement => { return ( {props.augNames.map((augName: string) => { const aug = Augmentations[augName]; const info = typeof aug.info === "string" ? {aug.info} : aug.info; - const description = aug.stats; + const description = ( + <> + {info} +
+
+ {aug.stats} + + ); + + const ownedPreReqs = aug.prereqs.filter((aug) => props.player.hasAugmentation(aug)); + const hasPreReqs = aug.prereqs.length > 0 && ownedPreReqs.length === aug.prereqs.length; return ( - - + + - {aug.factions.length === 1 && ( - - - Faction-Exclusive Augmentation + + + {description}}> + + + {aug.factions.length === 1 && ( + Faction-Exclusive Augmentation + } + > + + + )} + {aug.name}
- )} - - Cost: - - aug.baseCost} - value={numeralWrapper.formatMoney(aug.baseCost)} - valueColor={Settings.theme.money} - /> - {props.rep !== undefined && ( - = aug.baseRepRequirement} - value={`${numeralWrapper.formatReputation(aug.baseRepRequirement)} reputation`} - valueColor={Settings.theme.rep} - /> - )} - - {aug.prereqs.length > 0 && ( - <> - - Pre-Requisites: - - {aug.prereqs.map((preAug) => ( - - ))} - - )} + {aug.prereqs.length > 0 && ( + ( + + ))} + > + + {hasPreReqs ? ( + <> + + Pre-Requisites Owned + + ) : ( + <> + + Missing Pre-Requisites + + )} + + + )} + - - - {info}}> - - - {aug.name} - - {description} + + + aug.baseCost} + value={numeralWrapper.formatMoney(aug.baseCost)} + color={Settings.theme.money} + /> + {props.rep !== undefined && ( + = aug.baseRepRequirement} + value={`${numeralWrapper.formatReputation(aug.baseRepRequirement)} reputation`} + color={Settings.theme.rep} + /> + )} + ); From ec53a805519b9d4298db7136b66414e6c625081e Mon Sep 17 00:00:00 2001 From: nickofolas Date: Fri, 22 Apr 2022 16:47:12 -0500 Subject: [PATCH 07/30] Update after merge --- .../ui/PurchaseableAugmentations.tsx | 5 +- src/Faction/ui/PurchaseableAugmentation.tsx | 170 ------------------ 2 files changed, 3 insertions(+), 172 deletions(-) delete mode 100644 src/Faction/ui/PurchaseableAugmentation.tsx diff --git a/src/Augmentation/ui/PurchaseableAugmentations.tsx b/src/Augmentation/ui/PurchaseableAugmentations.tsx index 7062858d0..61c0c3b5f 100644 --- a/src/Augmentation/ui/PurchaseableAugmentations.tsx +++ b/src/Augmentation/ui/PurchaseableAugmentations.tsx @@ -4,7 +4,7 @@ */ import React, { useState } from "react"; -import { getNextNeurofluxLevel, hasAugmentationPrereqs, purchaseAugmentation } from "../../Faction/FactionHelpers"; +import { hasAugmentationPrereqs, purchaseAugmentation } from "../../Faction/FactionHelpers"; import { PurchaseAugmentationModal } from "./PurchaseAugmentationModal"; import { Augmentations } from "../Augmentations"; @@ -20,6 +20,7 @@ import { CheckBox, CheckBoxOutlineBlank, Verified, Info, Report, CheckCircle } f import { Augmentation as AugFormat } from "../../ui/React/Augmentation"; import { Paper, Button, Typography, Tooltip, Box, TableRow, Container, List, ListItem } from "@mui/material"; import { TableCell } from "../../ui/React/Table"; +import { getNextNeuroFluxLevel } from "../../Augmentation/AugmentationHelpers"; import { Augmentation } from "../Augmentation"; // interface IReqProps { @@ -233,7 +234,7 @@ export function PurchaseableAugmentation(props: IPurchaseableAugProps): React.Re // Determine button txt let btnTxt = aug.name; if (aug.name === AugmentationNames.NeuroFluxGovernor) { - btnTxt += ` - Level ${getNextNeurofluxLevel()}`; + btnTxt += ` - Level ${getNextNeuroFluxLevel()}`; } let tooltip = <>; diff --git a/src/Faction/ui/PurchaseableAugmentation.tsx b/src/Faction/ui/PurchaseableAugmentation.tsx deleted file mode 100644 index feebb29e0..000000000 --- a/src/Faction/ui/PurchaseableAugmentation.tsx +++ /dev/null @@ -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 ( - - - Requires{" "} - {aug.prereqs.map((aug, i) => ( - - ))} - - - ); - } - - return ( - - - - - - - - - Requires faction reputation - - - - ); -} - -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 = ( - <> - {aug.info} -
-
- {aug.stats} - - ); - } else - tooltip = ( - <> - {aug.info} -
-
- {aug.stats} - - ); - - function handleClick(): void { - if (color === "error") return; - if (!Settings.SuppressBuyAugmentationConfirmation) { - setOpen(true); - } else { - purchaseAugmentation(aug, props.faction); - props.rerender(); - } - } - - return ( - - {!props.owned && ( - - - setOpen(false)} - aug={aug} - faction={props.faction} - rerender={props.rerender} - /> - - )} - - - {tooltip}} placement="top"> - {btnTxt} - - - - {!props.owned && ( - - )} - - ); -} From f6a9eb746a530e55b184c384cd2777e4471e1c78 Mon Sep 17 00:00:00 2001 From: nickofolas Date: Fri, 22 Apr 2022 16:51:36 -0500 Subject: [PATCH 08/30] Move elements around for clarity --- .../ui/PurchaseableAugmentations.tsx | 161 ++++++++++++------ 1 file changed, 111 insertions(+), 50 deletions(-) diff --git a/src/Augmentation/ui/PurchaseableAugmentations.tsx b/src/Augmentation/ui/PurchaseableAugmentations.tsx index 61c0c3b5f..eb1747a2a 100644 --- a/src/Augmentation/ui/PurchaseableAugmentations.tsx +++ b/src/Augmentation/ui/PurchaseableAugmentations.tsx @@ -64,6 +64,89 @@ import { Augmentation } from "../Augmentation"; // ); // } +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 ( + + This Augmentation has the following pre-requisite(s): + {props.aug.prereqs.map((preAug) => ( + + ))} + + } + > + + {hasPreReqs ? ( + <> + + Pre-requisites Owned + + ) : ( + <> + + Missing {props.aug.prereqs.length - ownedPreReqs.length} pre-requisite(s) + + )} + + + ); +}; + +interface IExclusiveProps { + player: IPlayer; + aug: Augmentation; +} + +const Exclusive = (props: IExclusiveProps): React.ReactElement => { + return ( + + This Augmentation can only be acquired from the following source(s): +
    +
  • + {props.aug.factions[0]} faction +
  • + {props.player.canAccessGang() && ( +
  • + Certain gangs +
  • + )} + {props.player.canAccessGrafting() && ( +
  • + Grafting +
  • + )} +
+ + } + > + +
+ ); +}; + interface IReqProps { value: string; color: string; @@ -109,11 +192,8 @@ export const PurchaseableAugmentations = (props: IPurchaseableAugsProps): React. ); - const ownedPreReqs = aug.prereqs.filter((aug) => props.player.hasAugmentation(aug)); - const hasPreReqs = aug.prereqs.length > 0 && ownedPreReqs.length === aug.prereqs.length; - return ( - + - - - {description}}> + + + + + {augName} + {augName === AugmentationNames.NeuroFluxGovernor && ` - Level ${getNextNeuroFluxLevel()}`} + + {description} + + } + > - {aug.factions.length === 1 && ( - Faction-Exclusive Augmentation - } - > - - - )} - {aug.name} - - - {aug.prereqs.length > 0 && ( - ( - - ))} + - - {hasPreReqs ? ( - <> - - Pre-Requisites Owned - - ) : ( - <> - - Missing Pre-Requisites - - )} - - - )} + {aug.name} + {aug.name === AugmentationNames.NeuroFluxGovernor && ` - Level ${getNextNeuroFluxLevel()}`} + + {aug.factions.length === 1 && } + + + {aug.prereqs.length > 0 && } From de78060ff9e7931a45be5ca9877209bdf38c47a1 Mon Sep 17 00:00:00 2001 From: nickofolas Date: Fri, 22 Apr 2022 16:51:42 -0500 Subject: [PATCH 09/30] Update sleeve modal width --- src/PersonObjects/Sleeve/ui/SleeveAugmentationsModal.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PersonObjects/Sleeve/ui/SleeveAugmentationsModal.tsx b/src/PersonObjects/Sleeve/ui/SleeveAugmentationsModal.tsx index 9087fffc1..4d660800c 100644 --- a/src/PersonObjects/Sleeve/ui/SleeveAugmentationsModal.tsx +++ b/src/PersonObjects/Sleeve/ui/SleeveAugmentationsModal.tsx @@ -47,7 +47,7 @@ export function SleeveAugmentationsModal(props: IProps): React.ReactElement { return ( - + 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. From 4d1f5c657a625f5b1448d38a32e9cde13d467afc Mon Sep 17 00:00:00 2001 From: nickofolas Date: Fri, 22 Apr 2022 16:58:06 -0500 Subject: [PATCH 10/30] Check `isSpecial` for exclusive aug tooltip --- src/Augmentation/ui/PurchaseableAugmentations.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Augmentation/ui/PurchaseableAugmentations.tsx b/src/Augmentation/ui/PurchaseableAugmentations.tsx index eb1747a2a..68cf4d460 100644 --- a/src/Augmentation/ui/PurchaseableAugmentations.tsx +++ b/src/Augmentation/ui/PurchaseableAugmentations.tsx @@ -128,12 +128,12 @@ const Exclusive = (props: IExclusiveProps): React.ReactElement => {
  • {props.aug.factions[0]} faction
  • - {props.player.canAccessGang() && ( + {props.player.canAccessGang() && !props.aug.isSpecial && (
  • Certain gangs
  • )} - {props.player.canAccessGrafting() && ( + {props.player.canAccessGrafting() && !props.aug.isSpecial && (
  • Grafting
  • From 46e5738f0a592d946f1f067c7d1b5131272e4a49 Mon Sep 17 00:00:00 2001 From: nickofolas Date: Fri, 22 Apr 2022 17:04:14 -0500 Subject: [PATCH 11/30] Change exclusive aug icon --- .../ui/PurchaseableAugmentations.tsx | 45 +------------------ 1 file changed, 2 insertions(+), 43 deletions(-) diff --git a/src/Augmentation/ui/PurchaseableAugmentations.tsx b/src/Augmentation/ui/PurchaseableAugmentations.tsx index 68cf4d460..aff025490 100644 --- a/src/Augmentation/ui/PurchaseableAugmentations.tsx +++ b/src/Augmentation/ui/PurchaseableAugmentations.tsx @@ -16,54 +16,13 @@ import { numeralWrapper } from "../../ui/numeralFormat"; import { Money } from "../../ui/React/Money"; import { Reputation } from "../../ui/React/Reputation"; -import { CheckBox, CheckBoxOutlineBlank, Verified, Info, Report, CheckCircle } from "@mui/icons-material"; +import { CheckBox, CheckBoxOutlineBlank, NewReleases, Info, Report, CheckCircle } from "@mui/icons-material"; import { Augmentation as AugFormat } from "../../ui/React/Augmentation"; import { Paper, Button, Typography, Tooltip, Box, TableRow, Container, List, ListItem } from "@mui/material"; import { TableCell } from "../../ui/React/Table"; import { getNextNeuroFluxLevel } from "../../Augmentation/AugmentationHelpers"; import { Augmentation } from "../Augmentation"; -// 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 ( -// -// -// Requires{" "} -// {aug.prereqs.map((aug, i) => ( -// -// ))} -// -// -// ); -// } - -// return ( -// -// -// -// -// -// -// -// -// Requires faction reputation -// -// -// -// ); -// } - interface IPreReqsProps { player: IPlayer; aug: Augmentation; @@ -142,7 +101,7 @@ const Exclusive = (props: IExclusiveProps): React.ReactElement => {
    } > - + ); }; From bb78326dd9d52478c418bbdb035358e23893e206 Mon Sep 17 00:00:00 2001 From: nickofolas Date: Fri, 22 Apr 2022 17:09:14 -0500 Subject: [PATCH 12/30] Skip pre-reqs and exclusives in sleeve modal --- src/Augmentation/ui/PurchaseableAugmentations.tsx | 8 ++++++-- src/PersonObjects/Sleeve/ui/SleeveAugmentationsModal.tsx | 2 ++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/Augmentation/ui/PurchaseableAugmentations.tsx b/src/Augmentation/ui/PurchaseableAugmentations.tsx index aff025490..d3d9a70a4 100644 --- a/src/Augmentation/ui/PurchaseableAugmentations.tsx +++ b/src/Augmentation/ui/PurchaseableAugmentations.tsx @@ -129,6 +129,8 @@ interface IPurchaseableAugsProps { purchaseAugmentation: (player: IPlayer, aug: Augmentation, showModal: (open: boolean) => void) => void; rep?: number; + skipPreReqs?: boolean; + skipExclusiveIndicator?: boolean; } export const PurchaseableAugmentations = (props: IPurchaseableAugsProps): React.ReactElement => { @@ -192,10 +194,12 @@ export const PurchaseableAugmentations = (props: IPurchaseableAugsProps): React. {aug.name} {aug.name === AugmentationNames.NeuroFluxGovernor && ` - Level ${getNextNeuroFluxLevel()}`} - {aug.factions.length === 1 && } + {aug.factions.length === 1 && !props.skipExclusiveIndicator && ( + + )}
    - {aug.prereqs.length > 0 && } + {aug.prereqs.length > 0 && !props.skipPreReqs && }
    diff --git a/src/PersonObjects/Sleeve/ui/SleeveAugmentationsModal.tsx b/src/PersonObjects/Sleeve/ui/SleeveAugmentationsModal.tsx index 4d660800c..c487a9808 100644 --- a/src/PersonObjects/Sleeve/ui/SleeveAugmentationsModal.tsx +++ b/src/PersonObjects/Sleeve/ui/SleeveAugmentationsModal.tsx @@ -66,6 +66,8 @@ export function SleeveAugmentationsModal(props: IProps): React.ReactElement { props.sleeve.tryBuyAugmentation(player, aug); rerender(); }} + skipPreReqs + skipExclusiveIndicator /> {/* From 60bfc6d2a732278902e4628bf1bcee7cdd408e9d Mon Sep 17 00:00:00 2001 From: nickofolas Date: Fri, 22 Apr 2022 18:02:26 -0500 Subject: [PATCH 13/30] First round of modal fixes --- .../ui/PurchaseAugmentationModal.tsx | 14 +- .../ui/PurchaseableAugmentations.tsx | 251 ++++++------------ src/Faction/ui/AugmentationsPage.tsx | 3 +- 3 files changed, 91 insertions(+), 177 deletions(-) diff --git a/src/Augmentation/ui/PurchaseAugmentationModal.tsx b/src/Augmentation/ui/PurchaseAugmentationModal.tsx index 58c4cf76c..0a6c2e938 100644 --- a/src/Augmentation/ui/PurchaseAugmentationModal.tsx +++ b/src/Augmentation/ui/PurchaseAugmentationModal.tsx @@ -13,21 +13,23 @@ import Button from "@mui/material/Button"; interface IProps { open: boolean; onClose: () => void; - faction: Faction; - aug: Augmentation; - rerender: () => void; + faction?: Faction; + aug?: Augmentation; } export function PurchaseAugmentationModal(props: IProps): React.ReactElement { + if (typeof props.aug === "undefined" || typeof props.faction === "undefined") { + return <>; + } + const player = use.Player(); function buy(): void { - if (!isRepeatableAug(props.aug) && player.hasAugmentation(props.aug)) { + if (!isRepeatableAug(props.aug as Augmentation) && player.hasAugmentation(props.aug as Augmentation)) { return; } - purchaseAugmentation(props.aug, props.faction); - props.rerender(); + purchaseAugmentation(props.aug as Augmentation, props.faction as Faction); props.onClose(); } diff --git a/src/Augmentation/ui/PurchaseableAugmentations.tsx b/src/Augmentation/ui/PurchaseableAugmentations.tsx index d3d9a70a4..fe07b39b2 100644 --- a/src/Augmentation/ui/PurchaseableAugmentations.tsx +++ b/src/Augmentation/ui/PurchaseableAugmentations.tsx @@ -131,6 +131,7 @@ interface IPurchaseableAugsProps { rep?: number; skipPreReqs?: boolean; skipExclusiveIndicator?: boolean; + faction?: Faction; } export const PurchaseableAugmentations = (props: IPurchaseableAugsProps): React.ReactElement => { @@ -140,192 +141,102 @@ export const PurchaseableAugmentations = (props: IPurchaseableAugsProps): React. disableGutters sx={{ mx: 0, display: "grid", gridTemplateColumns: "repeat(1, 1fr)", gap: 1 }} > - {props.augNames.map((augName: string) => { - const aug = Augmentations[augName]; - - const info = typeof aug.info === "string" ? {aug.info} : aug.info; - const description = ( - <> - {info} -
    -
    - {aug.stats} - - ); - - return ( - - - - - - - - - {augName} - {augName === AugmentationNames.NeuroFluxGovernor && ` - Level ${getNextNeuroFluxLevel()}`} - - {description} - - } - > - - - - {aug.name} - {aug.name === AugmentationNames.NeuroFluxGovernor && ` - Level ${getNextNeuroFluxLevel()}`} - - {aug.factions.length === 1 && !props.skipExclusiveIndicator && ( - - )} - - - {aug.prereqs.length > 0 && !props.skipPreReqs && } - - - - - - aug.baseCost} - value={numeralWrapper.formatMoney(aug.baseCost)} - color={Settings.theme.money} - /> - {props.rep !== undefined && ( - = aug.baseRepRequirement} - value={`${numeralWrapper.formatReputation(aug.baseRepRequirement)} reputation`} - color={Settings.theme.rep} - /> - )} - - - - ); - })} + {props.augNames.map((augName: string) => ( + + ))} ); }; interface IPurchaseableAugProps { + parent: IPurchaseableAugsProps; augName: string; - faction: Faction; - p: IPlayer; - rerender: () => void; - owned?: boolean; } export function PurchaseableAugmentation(props: IPurchaseableAugProps): 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 = ( - <> - {aug.info} -
    -
    - {aug.stats} - - ); - } else - tooltip = ( - <> - {aug.info} -
    -
    - {aug.stats} - - ); - - function handleClick(): void { - if (color === "error") return; - if (!Settings.SuppressBuyAugmentationConfirmation) { - setOpen(true); - } else { - purchaseAugmentation(aug, props.faction); - props.rerender(); - } - } + const info = typeof aug.info === "string" ? {aug.info} : aug.info; + const description = ( + <> + {info} +
    +
    + {aug.stats} + + ); return ( - - {!props.owned && ( - - - setOpen(false)} - aug={aug} - faction={props.faction} - rerender={props.rerender} - /> - - )} - - - {tooltip}} placement="top"> - {btnTxt} - + + + + + + {props.augName} + {props.augName === AugmentationNames.NeuroFluxGovernor && ` - Level ${getNextNeuroFluxLevel()}`} + + {description} + + } + > + + + + {aug.name} + {aug.name === AugmentationNames.NeuroFluxGovernor && ` - Level ${getNextNeuroFluxLevel()}`} + + {aug.factions.length === 1 && !props.parent.skipExclusiveIndicator && ( + + )} + + + {aug.prereqs.length > 0 && !props.parent.skipPreReqs && } + - - {!props.owned && ( - - )} - + + + + aug.baseCost} + value={numeralWrapper.formatMoney(aug.baseCost)} + color={Settings.theme.money} + /> + {props.parent.rep !== undefined && ( + = aug.baseRepRequirement} + value={`${numeralWrapper.formatReputation(aug.baseRepRequirement)} reputation`} + color={Settings.theme.rep} + /> + )} + + + + setOpen(false)} faction={props.parent.faction} aug={aug} /> + ); } diff --git a/src/Faction/ui/AugmentationsPage.tsx b/src/Faction/ui/AugmentationsPage.tsx index 35718b458..25a94a363 100644 --- a/src/Faction/ui/AugmentationsPage.tsx +++ b/src/Faction/ui/AugmentationsPage.tsx @@ -14,7 +14,7 @@ import { Reputation } from "../../ui/React/Reputation"; import { Faction } from "../Faction"; import { getFactionAugmentationsFiltered, hasAugmentationPrereqs, purchaseAugmentation } from "../FactionHelpers"; -import {Box, Button, Typography, Tooltip, TableBody, Table} from "@mui/material"; +import { Box, Button, Typography, Tooltip, TableBody, Table } from "@mui/material"; import { getGenericAugmentationPriceMultiplier } from "../../Augmentation/AugmentationHelpers"; import { FactionNames } from "../data/FactionNames"; @@ -217,6 +217,7 @@ export function AugmentationsPage(props: IProps): React.ReactElement { } }} rep={props.faction.playerReputation} + faction={props.faction} /> {/*
    {augListElems} From fd6c5fa1dced8feb28c5c0e07f8c9a91dd990f0b Mon Sep 17 00:00:00 2001 From: nickofolas Date: Fri, 22 Apr 2022 18:20:50 -0500 Subject: [PATCH 14/30] Implement display for owned augs --- .../ui/PurchaseableAugmentations.tsx | 74 ++++++++++--------- src/Faction/ui/AugmentationsPage.tsx | 46 ++---------- .../Sleeve/ui/SleeveAugmentationsModal.tsx | 56 +++----------- 3 files changed, 56 insertions(+), 120 deletions(-) diff --git a/src/Augmentation/ui/PurchaseableAugmentations.tsx b/src/Augmentation/ui/PurchaseableAugmentations.tsx index fe07b39b2..346aaaacc 100644 --- a/src/Augmentation/ui/PurchaseableAugmentations.tsx +++ b/src/Augmentation/ui/PurchaseableAugmentations.tsx @@ -2,26 +2,18 @@ * 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 { hasAugmentationPrereqs, purchaseAugmentation } from "../../Faction/FactionHelpers"; -import { PurchaseAugmentationModal } from "./PurchaseAugmentationModal"; - -import { Augmentations } from "../Augmentations"; -import { AugmentationNames } from "../data/AugmentationNames"; +import { getNextNeuroFluxLevel } from "../../Augmentation/AugmentationHelpers"; import { Faction } from "../../Faction/Faction"; import { IPlayer } from "../../PersonObjects/IPlayer"; import { Settings } from "../../Settings/Settings"; import { numeralWrapper } from "../../ui/numeralFormat"; -import { Money } from "../../ui/React/Money"; -import { Reputation } from "../../ui/React/Reputation"; - -import { CheckBox, CheckBoxOutlineBlank, NewReleases, Info, Report, CheckCircle } from "@mui/icons-material"; -import { Augmentation as AugFormat } from "../../ui/React/Augmentation"; -import { Paper, Button, Typography, Tooltip, Box, TableRow, Container, List, ListItem } from "@mui/material"; -import { TableCell } from "../../ui/React/Table"; -import { getNextNeuroFluxLevel } from "../../Augmentation/AugmentationHelpers"; import { Augmentation } from "../Augmentation"; +import { Augmentations } from "../Augmentations"; +import { AugmentationNames } from "../data/AugmentationNames"; +import { PurchaseAugmentationModal } from "./PurchaseAugmentationModal"; interface IPreReqsProps { player: IPlayer; @@ -123,6 +115,7 @@ const Requirement = (props: IReqProps): React.ReactElement => { interface IPurchaseableAugsProps { augNames: string[]; + ownedAugNames: string[]; player: IPlayer; canPurchase: (player: IPlayer, aug: Augmentation) => boolean; @@ -142,7 +135,10 @@ export const PurchaseableAugmentations = (props: IPurchaseableAugsProps): React. sx={{ mx: 0, display: "grid", gridTemplateColumns: "repeat(1, 1fr)", gap: 1 }} > {props.augNames.map((augName: string) => ( - + + ))} + {props.ownedAugNames.map((augName: string) => ( + ))} ); @@ -151,6 +147,7 @@ export const PurchaseableAugmentations = (props: IPurchaseableAugsProps): React. interface IPurchaseableAugProps { parent: IPurchaseableAugsProps; augName: string; + owned: boolean; } export function PurchaseableAugmentation(props: IPurchaseableAugProps): React.ReactElement { @@ -170,7 +167,16 @@ export function PurchaseableAugmentation(props: IPurchaseableAugProps): React.Re return ( <> - + - + - - - aug.baseCost} - value={numeralWrapper.formatMoney(aug.baseCost)} - color={Settings.theme.money} - /> - {props.parent.rep !== undefined && ( + {props.owned || ( + + = aug.baseRepRequirement} - value={`${numeralWrapper.formatReputation(aug.baseRepRequirement)} reputation`} - color={Settings.theme.rep} + fulfilled={aug.baseCost === 0 || props.parent.player.money > aug.baseCost} + value={numeralWrapper.formatMoney(aug.baseCost)} + color={Settings.theme.money} /> - )} - - + {props.parent.rep !== undefined && ( + = aug.baseRepRequirement} + value={`${numeralWrapper.formatReputation(aug.baseRepRequirement)} reputation`} + color={Settings.theme.rep} + /> + )} + + + )} setOpen(false)} faction={props.parent.faction} aug={aug} /> diff --git a/src/Faction/ui/AugmentationsPage.tsx b/src/Faction/ui/AugmentationsPage.tsx index 25a94a363..e45011c86 100644 --- a/src/Faction/ui/AugmentationsPage.tsx +++ b/src/Faction/ui/AugmentationsPage.tsx @@ -1,24 +1,22 @@ /** * Root React Component for displaying a faction's "Purchase Augmentations" page */ +import { Box, Button, Tooltip, Typography } from "@mui/material"; import React, { useState } from "react"; +import { getGenericAugmentationPriceMultiplier } from "../../Augmentation/AugmentationHelpers"; import { Augmentations } from "../../Augmentation/Augmentations"; import { AugmentationNames } from "../../Augmentation/data/AugmentationNames"; -import { PurchaseableAugmentation, PurchaseableAugmentations } from "../../Augmentation/ui/PurchaseableAugmentations"; +import { PurchaseableAugmentations } from "../../Augmentation/ui/PurchaseableAugmentations"; import { PurchaseAugmentationsOrderSetting } from "../../Settings/SettingEnums"; import { Settings } from "../../Settings/Settings"; import { use } from "../../ui/Context"; import { numeralWrapper } from "../../ui/numeralFormat"; import { Favor } from "../../ui/React/Favor"; import { Reputation } from "../../ui/React/Reputation"; +import { FactionNames } from "../data/FactionNames"; import { Faction } from "../Faction"; import { getFactionAugmentationsFiltered, hasAugmentationPrereqs, purchaseAugmentation } from "../FactionHelpers"; -import { Box, Button, Typography, Tooltip, TableBody, Table } from "@mui/material"; - -import { getGenericAugmentationPriceMultiplier } from "../../Augmentation/AugmentationHelpers"; -import { FactionNames } from "../data/FactionNames"; - type IProps = { faction: Faction; routeToMainPage: () => void; @@ -130,34 +128,8 @@ export function AugmentationsPage(props: IProps): React.ReactElement { aug === AugmentationNames.NeuroFluxGovernor || (!player.augmentations.some((a) => a.name === aug) && !player.queuedAugmentations.some((a) => a.name === aug)), ); - - const purchaseableAugmentation = (aug: string, owned = false): React.ReactNode => { - return ( - - ); - }; - - const augListElems = purchasable.map((aug) => purchaseableAugmentation(aug)); - - let ownedElem = <>; const owned = augs.filter((aug: string) => !purchasable.includes(aug)); - if (owned.length !== 0) { - ownedElem = ( - <> -
    - Purchased Augmentations - This faction also offers these augmentations but you already own them. - {owned.map((aug) => purchaseableAugmentation(aug, true))} - - ); - } + const multiplierComponent = props.faction.name !== FactionNames.ShadowsOfAnarchy ? ( @@ -200,6 +172,7 @@ export function AugmentationsPage(props: IProps): React.ReactElement { { return ( @@ -219,13 +192,6 @@ export function AugmentationsPage(props: IProps): React.ReactElement { rep={props.faction.playerReputation} faction={props.faction} /> - {/*
    - {augListElems} -
    - - - {ownedElem} -
    */} ); } diff --git a/src/PersonObjects/Sleeve/ui/SleeveAugmentationsModal.tsx b/src/PersonObjects/Sleeve/ui/SleeveAugmentationsModal.tsx index c487a9808..ee1f9e07e 100644 --- a/src/PersonObjects/Sleeve/ui/SleeveAugmentationsModal.tsx +++ b/src/PersonObjects/Sleeve/ui/SleeveAugmentationsModal.tsx @@ -1,18 +1,11 @@ -import React, { useState, useEffect } from "react"; +import { Box, Container, Paper, Tooltip, Typography } from "@mui/material"; +import React, { useEffect, useState } from "react"; +import { Augmentations } from "../../../Augmentation/Augmentations"; +import { PurchaseableAugmentations } from "../../../Augmentation/ui/PurchaseableAugmentations"; +import { use } from "../../../ui/Context"; +import { Modal } from "../../../ui/React/Modal"; import { Sleeve } from "../Sleeve"; import { findSleevePurchasableAugs } from "../SleeveHelpers"; -import { Augmentations } from "../../../Augmentation/Augmentations"; -import { Augmentation } from "../../../Augmentation/Augmentation"; -import { PurchaseableAugmentations } from "../../../Augmentation/ui/PurchaseableAugmentations"; -import { Money } from "../../../ui/React/Money"; -import { Modal } from "../../../ui/React/Modal"; -import { use } from "../../../ui/Context"; -import { Typography, Tooltip, Paper, Box, Container } from "@mui/material"; -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 { open: boolean; @@ -40,11 +33,6 @@ export function SleeveAugmentationsModal(props: IProps): React.ReactElement { // and you must also have enough rep in that faction in order to purchase it. const availableAugs = findSleevePurchasableAugs(props.sleeve, player); - function purchaseAugmentation(aug: Augmentation): void { - props.sleeve.tryBuyAugmentation(player, aug); - rerender(); - } - return ( @@ -58,6 +46,7 @@ export function SleeveAugmentationsModal(props: IProps): React.ReactElement { aug.name)} + ownedAugNames={ownedAugNames} player={player} canPurchase={(player, aug) => { return player.money > aug.startingCost; @@ -69,38 +58,11 @@ export function SleeveAugmentationsModal(props: IProps): React.ReactElement { skipPreReqs skipExclusiveIndicator /> - {/* - - - {availableAugs.map((aug) => { - return ( - - - - - - - - {aug.name} - - - - - - - - ); - })} - -
    -
    */} {ownedAugNames.length > 0 && ( <> - Owned Augmentations: - + Owned Augmentations: + {ownedAugNames.map((augName) => { const aug = Augmentations[augName]; const info = typeof aug.info === "string" ? {aug.info} : aug.info; From cb34afbe5ba382cdc03f48f578ef5dbb721620db Mon Sep 17 00:00:00 2001 From: nickofolas Date: Fri, 22 Apr 2022 18:21:58 -0500 Subject: [PATCH 15/30] Remove old sleeve owned augs grid --- .../Sleeve/ui/SleeveAugmentationsModal.tsx | 31 +------------------ 1 file changed, 1 insertion(+), 30 deletions(-) diff --git a/src/PersonObjects/Sleeve/ui/SleeveAugmentationsModal.tsx b/src/PersonObjects/Sleeve/ui/SleeveAugmentationsModal.tsx index ee1f9e07e..52f441c29 100644 --- a/src/PersonObjects/Sleeve/ui/SleeveAugmentationsModal.tsx +++ b/src/PersonObjects/Sleeve/ui/SleeveAugmentationsModal.tsx @@ -1,6 +1,5 @@ -import { Box, Container, Paper, Tooltip, Typography } from "@mui/material"; +import { Container, Typography } from "@mui/material"; import React, { useEffect, useState } from "react"; -import { Augmentations } from "../../../Augmentation/Augmentations"; import { PurchaseableAugmentations } from "../../../Augmentation/ui/PurchaseableAugmentations"; import { use } from "../../../ui/Context"; import { Modal } from "../../../ui/React/Modal"; @@ -58,34 +57,6 @@ export function SleeveAugmentationsModal(props: IProps): React.ReactElement { skipPreReqs skipExclusiveIndicator /> - - {ownedAugNames.length > 0 && ( - <> - Owned Augmentations: - - {ownedAugNames.map((augName) => { - const aug = Augmentations[augName]; - const info = typeof aug.info === "string" ? {aug.info} : aug.info; - const tooltip = ( - <> - {info} -
    -
    - {aug.stats} - - ); - - return ( - {tooltip}}> - - {augName} - - - ); - })} -
    - - )}
    ); From b193953b983fa7d9a4a613480e25c854bc0289cf Mon Sep 17 00:00:00 2001 From: nickofolas Date: Fri, 22 Apr 2022 19:18:35 -0500 Subject: [PATCH 16/30] Augs prereqs now include all augs in succession --- src/Augmentation/data/AugmentationCreator.tsx | 25 ++++++--- .../ui/PurchaseableAugmentations.tsx | 2 +- src/Faction/FactionHelpers.tsx | 29 ++--------- .../Grafting/ui/GraftingRoot.tsx | 52 ++++++++++--------- 4 files changed, 49 insertions(+), 59 deletions(-) diff --git a/src/Augmentation/data/AugmentationCreator.tsx b/src/Augmentation/data/AugmentationCreator.tsx index 02ce0bdd2..33c125fc8 100644 --- a/src/Augmentation/data/AugmentationCreator.tsx +++ b/src/Augmentation/data/AugmentationCreator.tsx @@ -242,7 +242,7 @@ export const initGeneralAugmentations = (): Augmentation[] => [ moneyCost: 1.15e8, repCost: 2.75e4, 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, factions: [ FactionNames.TheDarkArmy, @@ -339,7 +339,7 @@ export const initGeneralAugmentations = (): Augmentation[] => [ info: "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.", - prereqs: [AugmentationNames.CombatRib2], + prereqs: [AugmentationNames.CombatRib2, AugmentationNames.CombatRib1], strength_mult: 1.18, defense_mult: 1.18, factions: [ @@ -673,7 +673,7 @@ export const initGeneralAugmentations = (): Augmentation[] => [ "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 " + "packets.", - prereqs: [AugmentationNames.ENMCore], + prereqs: [AugmentationNames.ENMCore, AugmentationNames.ENM], hacking_speed_mult: 1.05, hacking_money_mult: 1.3, hacking_chance_mult: 1.05, @@ -698,7 +698,7 @@ export const initGeneralAugmentations = (): Augmentation[] => [ "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 " + "any device on a network.", - prereqs: [AugmentationNames.ENMCoreV2], + prereqs: [AugmentationNames.ENMCoreV2, AugmentationNames.ENMCore, AugmentationNames.ENM], hacking_speed_mult: 1.05, hacking_money_mult: 1.4, hacking_chance_mult: 1.1, @@ -826,7 +826,7 @@ export const initGeneralAugmentations = (): Augmentation[] => [ "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 " + "so that the brain doesn't have to.", - prereqs: [AugmentationNames.CranialSignalProcessorsG2], + prereqs: [AugmentationNames.CranialSignalProcessorsG2, AugmentationNames.CranialSignalProcessorsG1], hacking_speed_mult: 1.02, hacking_money_mult: 1.15, hacking_mult: 1.09, @@ -841,7 +841,11 @@ export const initGeneralAugmentations = (): Augmentation[] => [ "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 " + "so that the brain doesn't have to.", - prereqs: [AugmentationNames.CranialSignalProcessorsG3], + prereqs: [ + AugmentationNames.CranialSignalProcessorsG3, + AugmentationNames.CranialSignalProcessorsG2, + AugmentationNames.CranialSignalProcessorsG1, + ], hacking_speed_mult: 1.02, hacking_money_mult: 1.2, hacking_grow_mult: 1.25, @@ -856,7 +860,12 @@ export const initGeneralAugmentations = (): Augmentation[] => [ "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 " + "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_money_mult: 1.25, hacking_grow_mult: 1.75, @@ -1952,7 +1961,7 @@ export const initChurchOfTheMachineGodAugmentations = (): Augmentation[] => [ "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 " + "of no longer suffering a stat penalty. ", - prereqs: [AugmentationNames.StaneksGift2], + prereqs: [AugmentationNames.StaneksGift2, AugmentationNames.StaneksGift1], isSpecial: true, hacking_chance_mult: 1 / 0.95, hacking_speed_mult: 1 / 0.95, diff --git a/src/Augmentation/ui/PurchaseableAugmentations.tsx b/src/Augmentation/ui/PurchaseableAugmentations.tsx index 346aaaacc..9c29a8ae7 100644 --- a/src/Augmentation/ui/PurchaseableAugmentations.tsx +++ b/src/Augmentation/ui/PurchaseableAugmentations.tsx @@ -236,7 +236,7 @@ export function PurchaseableAugmentation(props: IPurchaseableAugProps): React.Re {props.parent.rep !== undefined && ( = aug.baseRepRequirement} - value={`${numeralWrapper.formatReputation(aug.baseRepRequirement)} reputation`} + value={`${numeralWrapper.formatReputation(aug.baseRepRequirement)} rep`} color={Settings.theme.rep} /> )} diff --git a/src/Faction/FactionHelpers.tsx b/src/Faction/FactionHelpers.tsx index 84519d5af..ee027fcf6 100644 --- a/src/Faction/FactionHelpers.tsx +++ b/src/Faction/FactionHelpers.tsx @@ -54,36 +54,15 @@ export function joinFaction(faction: Faction): void { //Returns a boolean indicating whether the player has the prerequisites for the //specified Augmentation export function hasAugmentationPrereqs(aug: Augmentation): boolean { - let hasPrereqs = true; - 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; + return aug.prereqs.every((aug) => Player.hasAugmentation(aug)); } export function purchaseAugmentation(aug: Augmentation, fac: Faction, sing = false): string { const hasPrereqs = hasAugmentationPrereqs(aug); 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) { return txt; } else { diff --git a/src/PersonObjects/Grafting/ui/GraftingRoot.tsx b/src/PersonObjects/Grafting/ui/GraftingRoot.tsx index 34e3a1a61..02d8d265c 100644 --- a/src/PersonObjects/Grafting/ui/GraftingRoot.tsx +++ b/src/PersonObjects/Grafting/ui/GraftingRoot.tsx @@ -129,34 +129,36 @@ export const GraftingRoot = (): React.ReactElement => { } /> - - Time to Graft:{" "} - {convertTimeMsToTimeElapsedString( - GraftableAugmentations[selectedAug].time / (1 + (player.getIntelligenceBonus(3) - 1) / 3), + + + Time to Graft:{" "} + {convertTimeMsToTimeElapsedString( + GraftableAugmentations[selectedAug].time / (1 + (player.getIntelligenceBonus(3) - 1) / 3), + )} + {/* Use formula so the displayed creation time is accurate to player bonus */} + + {Augmentations[selectedAug].prereqs.length > 0 && ( + )} - {/* Use formula so the displayed creation time is accurate to player bonus */} - - {Augmentations[selectedAug].prereqs.length > 0 && ( - - )} -
    - - {(() => { - const aug = Augmentations[selectedAug]; +
    + + {(() => { + const aug = Augmentations[selectedAug]; - const info = typeof aug.info === "string" ? {aug.info} : aug.info; - const tooltip = ( - <> - {info} -
    -
    - {aug.stats} - - ); - return tooltip; - })()} -
    + const info = typeof aug.info === "string" ? {aug.info} : aug.info; + const tooltip = ( + <> + {info} +
    +
    + {aug.stats} + + ); + return tooltip; + })()} +
    +
    ) : ( From a7d980c2dd09d84c1a02269465d00a023e06a742 Mon Sep 17 00:00:00 2001 From: nickofolas Date: Fri, 22 Apr 2022 19:48:40 -0500 Subject: [PATCH 17/30] Polish sleeve aug modal and faction aug page --- src/Faction/ui/AugmentationsPage.tsx | 69 +++++++++++-------- .../Sleeve/ui/SleeveAugmentationsModal.tsx | 35 +++++----- 2 files changed, 60 insertions(+), 44 deletions(-) diff --git a/src/Faction/ui/AugmentationsPage.tsx b/src/Faction/ui/AugmentationsPage.tsx index e45011c86..a8b0dda3e 100644 --- a/src/Faction/ui/AugmentationsPage.tsx +++ b/src/Faction/ui/AugmentationsPage.tsx @@ -1,7 +1,7 @@ /** * Root React Component for displaying a faction's "Purchase Augmentations" page */ -import { Box, Button, Tooltip, Typography } from "@mui/material"; +import { Box, Button, Tooltip, Typography, Paper, Container } from "@mui/material"; import React, { useState } from "react"; import { getGenericAugmentationPriceMultiplier } from "../../Augmentation/AugmentationHelpers"; import { Augmentations } from "../../Augmentation/Augmentations"; @@ -133,7 +133,7 @@ export function AugmentationsPage(props: IProps): React.ReactElement { const multiplierComponent = props.faction.name !== FactionNames.ShadowsOfAnarchy ? ( - Price multiplier: x {numeralWrapper.formatMultiplier(getGenericAugmentationPriceMultiplier())} + Price multiplier: x {numeralWrapper.formatMultiplier(getGenericAugmentationPriceMultiplier())} ) : ( <> @@ -141,34 +141,47 @@ export function AugmentationsPage(props: IProps): React.ReactElement { return ( <> - - Faction Augmentations - - These are all of the Augmentations that are available to purchase from {props.faction.name}. Augmentations are - powerful upgrades that will enhance your abilities. -
    - Reputation: Favor:{" "} - -
    - - + + Faction Augmentations + + + These are all of the Augmentations that are available to purchase from {props.faction.name}. + Augmentations are powerful upgrades that will enhance your abilities. +
    +
    + + + The price of every Augmentation increases for every queued Augmentation and it is reset when you + install them. + + } + > + {multiplierComponent} + - The price of every Augmentation increases for every queued Augmentation and it is reset when you install - them. + Reputation: - } - > - {multiplierComponent} -
    -
    - - - - -
    + + Favor: + + + + + + + + + + - + 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. @@ -42,22 +42,25 @@ export function SleeveAugmentationsModal(props: IProps): React.ReactElement {
    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. +
    +
    + Augmentations will appear below as they become available.
    - aug.name)} - ownedAugNames={ownedAugNames} - player={player} - canPurchase={(player, aug) => { - return player.money > aug.startingCost; - }} - purchaseAugmentation={(player, aug, _showModal) => { - props.sleeve.tryBuyAugmentation(player, aug); - rerender(); - }} - skipPreReqs - skipExclusiveIndicator - />
    + aug.name)} + ownedAugNames={ownedAugNames} + player={player} + canPurchase={(player, aug) => { + return player.money > aug.startingCost; + }} + purchaseAugmentation={(player, aug, _showModal) => { + props.sleeve.tryBuyAugmentation(player, aug); + rerender(); + }} + skipPreReqs + skipExclusiveIndicator + /> ); } From 304151f91040878b04af714fe99a1cea850a34fc Mon Sep 17 00:00:00 2001 From: nickofolas Date: Fri, 22 Apr 2022 19:59:27 -0500 Subject: [PATCH 18/30] Fix TRP being listed as graftable --- src/Augmentation/ui/PurchaseableAugmentations.tsx | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/Augmentation/ui/PurchaseableAugmentations.tsx b/src/Augmentation/ui/PurchaseableAugmentations.tsx index 9c29a8ae7..abad20650 100644 --- a/src/Augmentation/ui/PurchaseableAugmentations.tsx +++ b/src/Augmentation/ui/PurchaseableAugmentations.tsx @@ -84,11 +84,13 @@ const Exclusive = (props: IExclusiveProps): React.ReactElement => { Certain gangs )} - {props.player.canAccessGrafting() && !props.aug.isSpecial && ( -
  • - Grafting -
  • - )} + {props.player.canAccessGrafting() && + !props.aug.isSpecial && + props.aug.name !== AugmentationNames.TheRedPill && ( +
  • + Grafting +
  • + )} } From 46613a07cbaca19c8974f516c11b093ee1c9e013 Mon Sep 17 00:00:00 2001 From: nickofolas Date: Fri, 22 Apr 2022 22:58:03 -0500 Subject: [PATCH 19/30] Change rotate method to work in chrome --- src/Augmentation/ui/PurchaseableAugmentations.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Augmentation/ui/PurchaseableAugmentations.tsx b/src/Augmentation/ui/PurchaseableAugmentations.tsx index abad20650..fd39fb268 100644 --- a/src/Augmentation/ui/PurchaseableAugmentations.tsx +++ b/src/Augmentation/ui/PurchaseableAugmentations.tsx @@ -95,7 +95,7 @@ const Exclusive = (props: IExclusiveProps): React.ReactElement => { } > - + ); }; From e6df46e520c7224ec5eba74df92d7a8c66ea4a5e Mon Sep 17 00:00:00 2001 From: nickofolas Date: Fri, 22 Apr 2022 23:27:05 -0500 Subject: [PATCH 20/30] Fix spelling --- ...ntations.tsx => PurchasableAugmentations.tsx} | 16 ++++++++-------- src/Faction/ui/AugmentationsPage.tsx | 4 ++-- .../Sleeve/ui/SleeveAugmentationsModal.tsx | 4 ++-- 3 files changed, 12 insertions(+), 12 deletions(-) rename src/Augmentation/ui/{PurchaseableAugmentations.tsx => PurchasableAugmentations.tsx} (92%) diff --git a/src/Augmentation/ui/PurchaseableAugmentations.tsx b/src/Augmentation/ui/PurchasableAugmentations.tsx similarity index 92% rename from src/Augmentation/ui/PurchaseableAugmentations.tsx rename to src/Augmentation/ui/PurchasableAugmentations.tsx index fd39fb268..7872a6e84 100644 --- a/src/Augmentation/ui/PurchaseableAugmentations.tsx +++ b/src/Augmentation/ui/PurchasableAugmentations.tsx @@ -5,7 +5,7 @@ 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 "../../Augmentation/AugmentationHelpers"; +import { getNextNeuroFluxLevel } from "../AugmentationHelpers"; import { Faction } from "../../Faction/Faction"; import { IPlayer } from "../../PersonObjects/IPlayer"; import { Settings } from "../../Settings/Settings"; @@ -115,7 +115,7 @@ const Requirement = (props: IReqProps): React.ReactElement => { ); }; -interface IPurchaseableAugsProps { +interface IPurchasableAugsProps { augNames: string[]; ownedAugNames: string[]; player: IPlayer; @@ -129,7 +129,7 @@ interface IPurchaseableAugsProps { faction?: Faction; } -export const PurchaseableAugmentations = (props: IPurchaseableAugsProps): React.ReactElement => { +export const PurchasableAugmentations = (props: IPurchasableAugsProps): React.ReactElement => { return ( {props.augNames.map((augName: string) => ( - + ))} {props.ownedAugNames.map((augName: string) => ( - + ))} ); }; -interface IPurchaseableAugProps { - parent: IPurchaseableAugsProps; +interface IPurchasableAugProps { + parent: IPurchasableAugsProps; augName: string; owned: boolean; } -export function PurchaseableAugmentation(props: IPurchaseableAugProps): React.ReactElement { +export function PurchasableAugmentation(props: IPurchasableAugProps): React.ReactElement { const [open, setOpen] = useState(false); const aug = Augmentations[props.augName]; diff --git a/src/Faction/ui/AugmentationsPage.tsx b/src/Faction/ui/AugmentationsPage.tsx index a8b0dda3e..455f3d2fd 100644 --- a/src/Faction/ui/AugmentationsPage.tsx +++ b/src/Faction/ui/AugmentationsPage.tsx @@ -6,7 +6,7 @@ import React, { useState } from "react"; import { getGenericAugmentationPriceMultiplier } from "../../Augmentation/AugmentationHelpers"; import { Augmentations } from "../../Augmentation/Augmentations"; import { AugmentationNames } from "../../Augmentation/data/AugmentationNames"; -import { PurchaseableAugmentations } from "../../Augmentation/ui/PurchaseableAugmentations"; +import { PurchasableAugmentations } from "../../Augmentation/ui/PurchasableAugmentations"; import { PurchaseAugmentationsOrderSetting } from "../../Settings/SettingEnums"; import { Settings } from "../../Settings/Settings"; import { use } from "../../ui/Context"; @@ -183,7 +183,7 @@ export function AugmentationsPage(props: IProps): React.ReactElement {
    - - aug.name)} ownedAugNames={ownedAugNames} player={player} From c6cb70a117bfd34388c2ce7badd4cd6f2210cdc1 Mon Sep 17 00:00:00 2001 From: nickofolas Date: Sat, 23 Apr 2022 10:49:20 -0500 Subject: [PATCH 21/30] Fix displayed Aug cost for sleeves --- src/Augmentation/ui/PurchasableAugmentations.tsx | 13 +++++++------ .../Sleeve/ui/SleeveAugmentationsModal.tsx | 3 +-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Augmentation/ui/PurchasableAugmentations.tsx b/src/Augmentation/ui/PurchasableAugmentations.tsx index 7872a6e84..37a2f95af 100644 --- a/src/Augmentation/ui/PurchasableAugmentations.tsx +++ b/src/Augmentation/ui/PurchasableAugmentations.tsx @@ -124,8 +124,7 @@ interface IPurchasableAugsProps { purchaseAugmentation: (player: IPlayer, aug: Augmentation, showModal: (open: boolean) => void) => void; rep?: number; - skipPreReqs?: boolean; - skipExclusiveIndicator?: boolean; + sleeveAugs?: boolean; faction?: Faction; } @@ -157,6 +156,8 @@ export function PurchasableAugmentation(props: IPurchasableAugProps): React.Reac const aug = Augmentations[props.augName]; + const cost = props.parent.sleeveAugs ? aug.startingCost : aug.baseCost; + const info = typeof aug.info === "string" ? {aug.info} : aug.info; const description = ( <> @@ -218,12 +219,12 @@ export function PurchasableAugmentation(props: IPurchasableAugProps): React.Reac {aug.name} {aug.name === AugmentationNames.NeuroFluxGovernor && ` - Level ${getNextNeuroFluxLevel()}`} - {aug.factions.length === 1 && !props.parent.skipExclusiveIndicator && ( + {aug.factions.length === 1 && !props.parent.sleeveAugs && ( )} - {aug.prereqs.length > 0 && !props.parent.skipPreReqs && } + {aug.prereqs.length > 0 && !props.parent.sleeveAugs && } @@ -231,8 +232,8 @@ export function PurchasableAugmentation(props: IPurchasableAugProps): React.Reac aug.baseCost} - value={numeralWrapper.formatMoney(aug.baseCost)} + fulfilled={aug.baseCost === 0 || props.parent.player.money > cost} + value={numeralWrapper.formatMoney(cost)} color={Settings.theme.money} /> {props.parent.rep !== undefined && ( diff --git a/src/PersonObjects/Sleeve/ui/SleeveAugmentationsModal.tsx b/src/PersonObjects/Sleeve/ui/SleeveAugmentationsModal.tsx index adb1c2800..a421a2220 100644 --- a/src/PersonObjects/Sleeve/ui/SleeveAugmentationsModal.tsx +++ b/src/PersonObjects/Sleeve/ui/SleeveAugmentationsModal.tsx @@ -58,8 +58,7 @@ export function SleeveAugmentationsModal(props: IProps): React.ReactElement { props.sleeve.tryBuyAugmentation(player, aug); rerender(); }} - skipPreReqs - skipExclusiveIndicator + sleeveAugs /> ); From f676e8bc9be06fce70c8c83eff99ea7c753f0a29 Mon Sep 17 00:00:00 2001 From: nickofolas Date: Sat, 23 Apr 2022 11:29:55 -0500 Subject: [PATCH 22/30] Fix rep and favor alignment for SoA --- src/Faction/ui/AugmentationsPage.tsx | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/Faction/ui/AugmentationsPage.tsx b/src/Faction/ui/AugmentationsPage.tsx index 455f3d2fd..a3fdfed02 100644 --- a/src/Faction/ui/AugmentationsPage.tsx +++ b/src/Faction/ui/AugmentationsPage.tsx @@ -150,7 +150,14 @@ export function AugmentationsPage(props: IProps): React.ReactElement { Augmentations are powerful upgrades that will enhance your abilities.
    - + From fb654dd5a17cf9dca58a10f637ff6223cfa15be3 Mon Sep 17 00:00:00 2001 From: nickofolas Date: Sat, 23 Apr 2022 12:20:05 -0500 Subject: [PATCH 23/30] Truncate Aug price multiplier more --- src/Faction/ui/AugmentationsPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Faction/ui/AugmentationsPage.tsx b/src/Faction/ui/AugmentationsPage.tsx index a3fdfed02..8175f47bc 100644 --- a/src/Faction/ui/AugmentationsPage.tsx +++ b/src/Faction/ui/AugmentationsPage.tsx @@ -133,7 +133,7 @@ export function AugmentationsPage(props: IProps): React.ReactElement { const multiplierComponent = props.faction.name !== FactionNames.ShadowsOfAnarchy ? ( - Price multiplier: x {numeralWrapper.formatMultiplier(getGenericAugmentationPriceMultiplier())} + Price multiplier: x {numeralWrapper.formatReallyBigNumber(getGenericAugmentationPriceMultiplier())} ) : ( <> From e11a8fddd8424faa39b5b52d4c12f40734a453b9 Mon Sep 17 00:00:00 2001 From: nickofolas Date: Sun, 24 Apr 2022 22:06:40 -0500 Subject: [PATCH 24/30] Use `lg` Container width --- .../ui/PurchasableAugmentations.tsx | 37 +++++++++++-------- src/Faction/ui/AugmentationsPage.tsx | 2 +- .../Sleeve/ui/SleeveAugmentationsModal.tsx | 2 +- 3 files changed, 23 insertions(+), 18 deletions(-) diff --git a/src/Augmentation/ui/PurchasableAugmentations.tsx b/src/Augmentation/ui/PurchasableAugmentations.tsx index 37a2f95af..0332cead6 100644 --- a/src/Augmentation/ui/PurchasableAugmentations.tsx +++ b/src/Augmentation/ui/PurchasableAugmentations.tsx @@ -131,7 +131,7 @@ interface IPurchasableAugsProps { export const PurchasableAugmentations = (props: IPurchasableAugsProps): React.ReactElement => { return ( @@ -175,7 +175,7 @@ export function PurchasableAugmentation(props: IPurchasableAugProps): React.Reac sx={{ p: 1, display: "grid", - gridTemplateColumns: "minmax(0, 3fr) 1fr", + gridTemplateColumns: "minmax(0, 4fr) 1fr", gap: 1, opacity: props.owned ? 0.75 : 1, }} @@ -229,25 +229,30 @@ export function PurchasableAugmentation(props: IPurchasableAugProps): React.Reac {props.owned || ( - - + + cost} + value={numeralWrapper.formatMoney(cost)} + color={Settings.theme.money} + /> + {props.parent.rep !== undefined && ( cost} - value={numeralWrapper.formatMoney(cost)} - color={Settings.theme.money} + fulfilled={props.parent.rep >= aug.baseRepRequirement} + value={`${numeralWrapper.formatReputation(aug.baseRepRequirement)} rep`} + color={Settings.theme.rep} /> - {props.parent.rep !== undefined && ( - = aug.baseRepRequirement} - value={`${numeralWrapper.formatReputation(aug.baseRepRequirement)} rep`} - color={Settings.theme.rep} - /> - )} - + )} )} - setOpen(false)} faction={props.parent.faction} aug={aug} /> + {Settings.SuppressBuyAugmentationConfirmation || ( + setOpen(false)} + faction={props.parent.faction} + aug={aug} + /> + )} ); } diff --git a/src/Faction/ui/AugmentationsPage.tsx b/src/Faction/ui/AugmentationsPage.tsx index 8175f47bc..c169520fd 100644 --- a/src/Faction/ui/AugmentationsPage.tsx +++ b/src/Faction/ui/AugmentationsPage.tsx @@ -141,7 +141,7 @@ export function AugmentationsPage(props: IProps): React.ReactElement { return ( <> - + Faction Augmentations diff --git a/src/PersonObjects/Sleeve/ui/SleeveAugmentationsModal.tsx b/src/PersonObjects/Sleeve/ui/SleeveAugmentationsModal.tsx index a421a2220..71eaf08a4 100644 --- a/src/PersonObjects/Sleeve/ui/SleeveAugmentationsModal.tsx +++ b/src/PersonObjects/Sleeve/ui/SleeveAugmentationsModal.tsx @@ -34,7 +34,7 @@ export function SleeveAugmentationsModal(props: IProps): React.ReactElement { return ( - + 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. From d36f7bb480bd3b011f00f9b97892eddffd2086b2 Mon Sep 17 00:00:00 2001 From: nickofolas Date: Sun, 24 Apr 2022 23:08:37 -0500 Subject: [PATCH 25/30] Fix some console warnings --- .../ui/PurchasableAugmentations.tsx | 80 ++++++++++--------- 1 file changed, 43 insertions(+), 37 deletions(-) diff --git a/src/Augmentation/ui/PurchasableAugmentations.tsx b/src/Augmentation/ui/PurchasableAugmentations.tsx index 0332cead6..488327f4b 100644 --- a/src/Augmentation/ui/PurchasableAugmentations.tsx +++ b/src/Augmentation/ui/PurchasableAugmentations.tsx @@ -27,8 +27,10 @@ const PreReqs = (props: IPreReqsProps): React.ReactElement => { return ( - This Augmentation has the following pre-requisite(s): + <> + + This Augmentation has the following pre-requisite(s): + {props.aug.prereqs.map((preAug) => ( { key={preAug} /> ))} - + } > { return ( - This Augmentation can only be acquired from the following source(s): + <> + + This Augmentation can only be acquired from the following source(s): +
      -
    • - {props.aug.factions[0]} faction -
    • - {props.player.canAccessGang() && !props.aug.isSpecial && ( +
    • - Certain gangs + {props.aug.factions[0]} faction
    • - )} - {props.player.canAccessGrafting() && - !props.aug.isSpecial && - props.aug.name !== AugmentationNames.TheRedPill && ( + {props.player.canAccessGang() && !props.aug.isSpecial && (
    • - Grafting + Certain gangs
    • )} + {props.player.canAccessGrafting() && + !props.aug.isSpecial && + props.aug.name !== AugmentationNames.TheRedPill && ( +
    • + Grafting +
    • + )} +
    -
    + } > @@ -169,17 +175,16 @@ export function PurchasableAugmentation(props: IPurchasableAugProps): React.Reac ); return ( - <> - + + <>