From 5d6952dbacf0ffeb2f4a6ac967d94ab58e604f8a Mon Sep 17 00:00:00 2001 From: nickofolas Date: Mon, 7 Mar 2022 20:03:23 -0600 Subject: [PATCH] First iteration of sleeves UI improvements --- .../Sleeve/ui/SleeveAugmentationsModal.tsx | 116 +++++------ src/PersonObjects/Sleeve/ui/SleeveElem.tsx | 153 +++++++-------- src/PersonObjects/Sleeve/ui/SleeveRoot.tsx | 9 +- src/PersonObjects/Sleeve/ui/StatsElement.tsx | 181 ++++++++++++++++-- src/PersonObjects/Sleeve/ui/TaskSelector.tsx | 8 +- 5 files changed, 289 insertions(+), 178 deletions(-) diff --git a/src/PersonObjects/Sleeve/ui/SleeveAugmentationsModal.tsx b/src/PersonObjects/Sleeve/ui/SleeveAugmentationsModal.tsx index 301137b24..57c402878 100644 --- a/src/PersonObjects/Sleeve/ui/SleeveAugmentationsModal.tsx +++ b/src/PersonObjects/Sleeve/ui/SleeveAugmentationsModal.tsx @@ -50,74 +50,62 @@ 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. -
- - - {availableAugs.map((aug) => { - return ( - - - - - - - - {aug.name} - - - - - - - - ); - })} - -
+ + + 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. +
+ + + + {availableAugs.map((aug) => { + return ( + + + + + + + + {aug.name} + + + + + + + + ); + })} + +
+
+
{ownedAugNames.length > 0 && ( <> - Owned Augmentations: - {ownedAugNames.map((augName) => { - const aug = Augmentations[augName]; - let tooltip = <>; - if (typeof aug.info === "string") { - tooltip = ( - <> - {aug.info} -
-
- {aug.stats} - - ); - } else { - tooltip = ( - <> - {aug.info} -
-
- {aug.stats} - - ); - } + 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} - - - ); - })} + return ( + {tooltip}}> + + {augName} + + + ); + })} +
)} diff --git a/src/PersonObjects/Sleeve/ui/SleeveElem.tsx b/src/PersonObjects/Sleeve/ui/SleeveElem.tsx index 45a3e909d..61c9f5cbc 100644 --- a/src/PersonObjects/Sleeve/ui/SleeveElem.tsx +++ b/src/PersonObjects/Sleeve/ui/SleeveElem.tsx @@ -13,20 +13,16 @@ import { createProgressBarText } from "../../../utils/helpers/createProgressBarT import { SleeveAugmentationsModal } from "./SleeveAugmentationsModal"; import { TravelModal } from "./TravelModal"; -import { Money } from "../../../ui/React/Money"; -import { MoneyRate } from "../../../ui/React/MoneyRate"; import { use } from "../../../ui/Context"; -import { ReputationRate } from "../../../ui/React/ReputationRate"; -import { StatsElement } from "./StatsElement"; +import { StatsElement, EarningsElement } from "./StatsElement"; import { MoreStatsModal } from "./MoreStatsModal"; import { MoreEarningsModal } from "./MoreEarningsModal"; import { TaskSelector } from "./TaskSelector"; import { FactionWorkType } from "../../../Faction/FactionWorkTypeEnum"; -import { StatsTable } from "../../../ui/React/StatsTable"; import Typography from "@mui/material/Typography"; import Paper from "@mui/material/Paper"; -import Grid from "@mui/material/Grid"; +import { Box } from "@mui/material"; import Button from "@mui/material/Button"; import Tooltip from "@mui/material/Tooltip"; @@ -141,86 +137,71 @@ export function SleeveElem(props: IProps): React.ReactElement { console.error(`Invalid/Unrecognized taskValue in updateSleeveTaskDescription(): ${abc[0]}`); } - let data: any[][] = []; - if (props.sleeve.currentTask === SleeveTaskType.Crime) { - data = [ - [`Money`, , `(on success)`], - [`Hacking Exp`, numeralWrapper.formatExp(props.sleeve.gainRatesForTask.hack), `(2x on success)`], - [`Strength Exp`, numeralWrapper.formatExp(props.sleeve.gainRatesForTask.str), `(2x on success)`], - [`Defense Exp`, numeralWrapper.formatExp(props.sleeve.gainRatesForTask.def), `(2x on success)`], - [`Dexterity Exp`, numeralWrapper.formatExp(props.sleeve.gainRatesForTask.dex), `(2x on success)`], - [`Agility Exp`, numeralWrapper.formatExp(props.sleeve.gainRatesForTask.agi), `(2x on success)`], - [`Charisma Exp`, numeralWrapper.formatExp(props.sleeve.gainRatesForTask.cha), `(2x on success)`], - ]; - } else { - data = [ - [`Money:`, ], - [`Hacking Exp:`, `${numeralWrapper.formatExp(5 * props.sleeve.gainRatesForTask.hack)} / s`], - [`Strength Exp:`, `${numeralWrapper.formatExp(5 * props.sleeve.gainRatesForTask.str)} / s`], - [`Defense Exp:`, `${numeralWrapper.formatExp(5 * props.sleeve.gainRatesForTask.def)} / s`], - [`Dexterity Exp:`, `${numeralWrapper.formatExp(5 * props.sleeve.gainRatesForTask.dex)} / s`], - [`Agility Exp:`, `${numeralWrapper.formatExp(5 * props.sleeve.gainRatesForTask.agi)} / s`], - [`Charisma Exp:`, `${numeralWrapper.formatExp(5 * props.sleeve.gainRatesForTask.cha)} / s`], - ]; - if (props.sleeve.currentTask === SleeveTaskType.Company || props.sleeve.currentTask === SleeveTaskType.Faction) { - const repGain: number = props.sleeve.getRepGain(player); - data.push([`Reputation:`, ]); - } - } - return ( - <> - - - - - Insufficient funds : ""}> - - - - - Unlocked when sleeve has fully recovered : ""} - > - - - - - - - - {desc} - - {props.sleeve.currentTask === SleeveTaskType.Crime && - createProgressBarText({ - progress: props.sleeve.currentTaskTime / props.sleeve.currentTaskMaxTime, - totalTicks: 25, - })} - - - - - - - - - setStatsOpen(false)} sleeve={props.sleeve} /> - setEarningsOpen(false)} sleeve={props.sleeve} /> - setTravelOpen(false)} - sleeve={props.sleeve} - rerender={props.rerender} - /> - setAugmentationsOpen(false)} - sleeve={props.sleeve} - /> - + + + + + + + + + Insufficient funds : ""}> + + + + + Unlocked when sleeve has fully recovered : ""} + > + + + + + + + + + + + + {desc} + + {props.sleeve.currentTask === SleeveTaskType.Crime && + createProgressBarText({ + progress: props.sleeve.currentTaskTime / props.sleeve.currentTaskMaxTime, + totalTicks: 25, + })} + + + + setStatsOpen(false)} sleeve={props.sleeve} /> + setEarningsOpen(false)} sleeve={props.sleeve} /> + setTravelOpen(false)} + sleeve={props.sleeve} + rerender={props.rerender} + /> + setAugmentationsOpen(false)} + sleeve={props.sleeve} + /> + + + ); } diff --git a/src/PersonObjects/Sleeve/ui/SleeveRoot.tsx b/src/PersonObjects/Sleeve/ui/SleeveRoot.tsx index 808b84723..a41a59e87 100644 --- a/src/PersonObjects/Sleeve/ui/SleeveRoot.tsx +++ b/src/PersonObjects/Sleeve/ui/SleeveRoot.tsx @@ -7,6 +7,7 @@ import { use } from "../../../ui/Context"; import Typography from "@mui/material/Typography"; import Button from "@mui/material/Button"; import Link from "@mui/material/Link"; +import { Box } from "@mui/material"; export function SleeveRoot(): React.ReactElement { const player = use.Player(); @@ -41,9 +42,11 @@ export function SleeveRoot(): React.ReactElement { > Documentation - {player.sleeves.map((sleeve, i) => ( - - ))} + + {player.sleeves.map((sleeve, i) => ( + + ))} + setFAQOpen(false)} /> ); diff --git a/src/PersonObjects/Sleeve/ui/StatsElement.tsx b/src/PersonObjects/Sleeve/ui/StatsElement.tsx index 9e51214fc..d348280e6 100644 --- a/src/PersonObjects/Sleeve/ui/StatsElement.tsx +++ b/src/PersonObjects/Sleeve/ui/StatsElement.tsx @@ -1,31 +1,172 @@ import { Sleeve } from "../Sleeve"; import { numeralWrapper } from "../../../ui/numeralFormat"; import React from "react"; +import Typography from "@mui/material/Typography"; +import { + Table, + TableBody, + TableCell, + TableRow, +} from "@mui/material"; -import { StatsTable } from "../../../ui/React/StatsTable"; +import { Settings } from "../../../Settings/Settings"; +import { formatNumber } from "../../../utils/StringHelperFunctions"; +import { characterOverviewStyles as useStyles } from "../../../ui/React/CharacterOverview"; + +import { Money } from "../../../ui/React/Money"; +import { MoneyRate } from "../../../ui/React/MoneyRate"; +import { ReputationRate } from "../../../ui/React/ReputationRate"; +import { SleeveTaskType } from "../SleeveTaskTypesEnum"; +import { use } from "../../../ui/Context"; + +interface ITableRowData { + content?: string; + level?: number; + exp?: number; +} + +export const generateTableRow = ( + name: string, + color: string, + // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types + classes: any, + data: ITableRowData +): React.ReactElement => { + let content; + + if (data.content !== undefined) { + content = data.content; + } else if (data.level !== undefined && data.exp !== undefined) { + content = `${formatNumber(data.level, 0)} (${numeralWrapper.formatExp(data.exp)} exp)`; + } else if (data.level !== undefined && data.exp === undefined) { + content = `${formatNumber(data.level, 0)}`; + } + + return ( + + + {name} + + + + {content} + + + + ) +} interface IProps { sleeve: Sleeve; } export function StatsElement(props: IProps): React.ReactElement { - const rows = [ - [ - "HP: ", - <> - {numeralWrapper.formatHp(props.sleeve.hp)} / {numeralWrapper.formatHp(props.sleeve.max_hp)} - , - ], - ["City: ", <>{props.sleeve.city}], - ["Hacking: ", <>{numeralWrapper.formatSkill(props.sleeve.hacking)}], - ["Strength: ", <>{numeralWrapper.formatSkill(props.sleeve.strength)}], - ["Defense: ", <>{numeralWrapper.formatSkill(props.sleeve.defense)}], - ["Dexterity: ", <>{numeralWrapper.formatSkill(props.sleeve.dexterity)}], - ["Agility: ", <>{numeralWrapper.formatSkill(props.sleeve.agility)}], - ["Charisma: ", <>{numeralWrapper.formatSkill(props.sleeve.charisma)}], - ["Shock: ", <>{numeralWrapper.formatSleeveShock(100 - props.sleeve.shock)}], - ["Sync: ", <>{numeralWrapper.formatSleeveSynchro(props.sleeve.sync)}], - ["Memory: ", <>{numeralWrapper.formatSleeveMemory(props.sleeve.memory)}], - ]; - return ; + const classes = useStyles(); + + return ( + + + {generateTableRow("City", Settings.theme.primary, classes, { + content: props.sleeve.city + })} + {generateTableRow("HP", Settings.theme.hp, classes, { + content: `${numeralWrapper.formatHp(props.sleeve.hp)} / ${numeralWrapper.formatHp(props.sleeve.max_hp)}` + })} + {generateTableRow("Hacking", Settings.theme.hack, classes, { + level: props.sleeve.hacking, + exp: props.sleeve.hacking_exp + })} + {generateTableRow("Strength", Settings.theme.combat, classes, { + level: props.sleeve.strength, + exp: props.sleeve.strength_exp + })} + {generateTableRow("Defense", Settings.theme.combat, classes, { + level: props.sleeve.defense, + exp: props.sleeve.defense_exp + })} + {generateTableRow("Dexterity", Settings.theme.combat, classes, { + level: props.sleeve.dexterity, + exp: props.sleeve.dexterity_exp + })} + {generateTableRow("Agility", Settings.theme.combat, classes, { + level: props.sleeve.agility, + exp: props.sleeve.agility_exp + })} + {generateTableRow("Charisma", Settings.theme.cha, classes, { + level: props.sleeve.charisma, + exp: props.sleeve.charisma_exp + })} + + +
+
+
+ {generateTableRow("Shock", Settings.theme.primary, classes, { + content: numeralWrapper.formatSleeveShock(100 - props.sleeve.shock) + })} + {generateTableRow("Sync", Settings.theme.primary, classes, { + content: numeralWrapper.formatSleeveSynchro(props.sleeve.sync) + })} + {generateTableRow("Memory", Settings.theme.primary, classes, { + content: numeralWrapper.formatSleeveMemory(props.sleeve.memory) + })} +
+
+ ) } + +export function EarningsElement(props: IProps): React.ReactElement { + const classes = useStyles(); + const player = use.Player(); + + let data: any[][] = []; + if (props.sleeve.currentTask === SleeveTaskType.Crime) { + data = [ + [`Money`, <> (on success)], + [`Hacking Exp`, `${numeralWrapper.formatExp(props.sleeve.gainRatesForTask.hack)} (2x on success)`], + [`Strength Exp`, `${numeralWrapper.formatExp(props.sleeve.gainRatesForTask.str)} (2x on success)`], + [`Defense Exp`, `${numeralWrapper.formatExp(props.sleeve.gainRatesForTask.def)} (2x on success)`], + [`Dexterity Exp`, `${numeralWrapper.formatExp(props.sleeve.gainRatesForTask.dex)} (2x on success)`], + [`Agility Exp`, `${numeralWrapper.formatExp(props.sleeve.gainRatesForTask.agi)} (2x on success)`], + [`Charisma Exp`, `${numeralWrapper.formatExp(props.sleeve.gainRatesForTask.cha)} (2x on success)`], + ]; + } else { + data = [ + [`Money:`, ], + [`Hacking Exp:`, `${numeralWrapper.formatExp(5 * props.sleeve.gainRatesForTask.hack)} / sec`], + [`Strength Exp:`, `${numeralWrapper.formatExp(5 * props.sleeve.gainRatesForTask.str)} / sec`], + [`Defense Exp:`, `${numeralWrapper.formatExp(5 * props.sleeve.gainRatesForTask.def)} / sec`], + [`Dexterity Exp:`, `${numeralWrapper.formatExp(5 * props.sleeve.gainRatesForTask.dex)} / sec`], + [`Agility Exp:`, `${numeralWrapper.formatExp(5 * props.sleeve.gainRatesForTask.agi)} / sec`], + [`Charisma Exp:`, `${numeralWrapper.formatExp(5 * props.sleeve.gainRatesForTask.cha)} / sec`], + ]; + if (props.sleeve.currentTask === SleeveTaskType.Company || props.sleeve.currentTask === SleeveTaskType.Faction) { + const repGain: number = props.sleeve.getRepGain(player); + data.push([`Reputation:`, ]); + } + } + + return ( + + + + + + Earnings + + + + {data.map(([a, b]) => ( + + + {a} + + + {b} + + + ))} + +
+ ) +} \ No newline at end of file diff --git a/src/PersonObjects/Sleeve/ui/TaskSelector.tsx b/src/PersonObjects/Sleeve/ui/TaskSelector.tsx index 724352aaa..bff6af55e 100644 --- a/src/PersonObjects/Sleeve/ui/TaskSelector.tsx +++ b/src/PersonObjects/Sleeve/ui/TaskSelector.tsx @@ -278,7 +278,7 @@ export function TaskSelector(props: IProps): React.ReactElement { return ( <> - {validActions.map((task) => ( {task} @@ -287,8 +287,7 @@ export function TaskSelector(props: IProps): React.ReactElement { {!(details.first.length === 1 && details.first[0] === "------") && ( <> -
- {details.first.map((detail) => ( {detail} @@ -299,8 +298,7 @@ export function TaskSelector(props: IProps): React.ReactElement { )} {!(details2.length === 1 && details2[0] === "------") && ( <> -
- {details2.map((detail) => ( {detail}