From 542f164930e44350d54f7f6178a41a22173e208d Mon Sep 17 00:00:00 2001 From: nickofolas Date: Wed, 19 Jan 2022 17:59:22 -0600 Subject: [PATCH 01/10] Align warehouse buttons --- src/Corporation/ui/IndustryWarehouse.tsx | 10 +++++----- src/Corporation/ui/MaterialElem.tsx | 7 ++----- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/Corporation/ui/IndustryWarehouse.tsx b/src/Corporation/ui/IndustryWarehouse.tsx index 9b6c7b474..4707afdef 100644 --- a/src/Corporation/ui/IndustryWarehouse.tsx +++ b/src/Corporation/ui/IndustryWarehouse.tsx @@ -139,13 +139,13 @@ function WarehouseRoot(props: IProps): React.ReactElement { {numeralWrapper.formatBigNumber(props.warehouse.size)} - - + + This industry uses the following equation for its production:
diff --git a/src/Corporation/ui/MaterialElem.tsx b/src/Corporation/ui/MaterialElem.tsx index 64471859a..616345cdc 100644 --- a/src/Corporation/ui/MaterialElem.tsx +++ b/src/Corporation/ui/MaterialElem.tsx @@ -112,7 +112,7 @@ export function MaterialElem(props: IMaterialProps): React.ReactElement { return ( - + - + Purchase your required materials to get production started! : ""} > - - setExportOpen(false)} /> )} -
- - -
- Upgrade the office's size so that it can hold more employees!}> - - - - - setUpgradeOfficeSizeOpen(false)} - /> - - {!division.hasResearch("AutoPartyManager") && ( - <> - Throw an office party to increase your employee's morale and happiness} - > - - - + + + Automatically hires an employee and gives him/her a random name}> + - Upgrade the office's size so that it can hold more employees!}> + + + setThrowPartyOpen(false)} + open={upgradeOfficeSizeOpen} + onClose={() => setUpgradeOfficeSizeOpen(false)} /> - - )} -
+ {!division.hasResearch("AutoPartyManager") && ( + <> + Throw an office party to increase your employee's morale and happiness} + > + + + setThrowPartyOpen(false)} + /> + + )} - + + + {employeeManualAssignMode ? ( ) : ( From 844b22859627cd51e26c72a2ed2294337506c17f Mon Sep 17 00:00:00 2001 From: nickofolas Date: Wed, 19 Jan 2022 18:39:39 -0600 Subject: [PATCH 03/10] Align overview page --- src/Corporation/ui/Overview.tsx | 75 ++++++++++++++------------------- 1 file changed, 32 insertions(+), 43 deletions(-) diff --git a/src/Corporation/ui/Overview.tsx b/src/Corporation/ui/Overview.tsx index 93d7c1c73..a35b3a50f 100644 --- a/src/Corporation/ui/Overview.tsx +++ b/src/Corporation/ui/Overview.tsx @@ -89,19 +89,21 @@ export function Overview({ rerender }: IProps): React.ReactElement {
- - Get a copy of and read 'The Complete Handbook for Creating a Successful Corporation.' This is a .lit file - that guides you through the beginning of setting up a Corporation and provides some tips/pointers for - helping you get started with managing it. - - } - > - - - {corp.public ? : } - + + + Get a copy of and read 'The Complete Handbook for Creating a Successful Corporation.' This is a .lit file + that guides you through the beginning of setting up a Corporation and provides some tips/pointers for + helping you get started with managing it. + + } + > + + + {corp.public ? : } + +
@@ -125,11 +127,9 @@ function PrivateButtons({ rerender }: IPrivateButtonsProps): React.ReactElement return ( <> {findInvestorsTooltip}}> - - - + setFindInvestorsopen(false)} rerender={rerender} /> setGoPublicopen(false)} rerender={rerender} /> -
); } @@ -201,8 +200,8 @@ function PublicButtons({ rerender }: IPublicButtonsProps): React.ReactElement { const sellSharesTooltip = sellSharesOnCd ? "Cannot sell shares for " + corp.convertCooldownToString(corp.shareSaleCooldown) : "Sell your shares in the company. The money earned from selling your " + - "shares goes into your personal account, not the Corporation's. " + - "This is one of the only ways to profit from your business venture."; + "shares goes into your personal account, not the Corporation's. " + + "This is one of the only ways to profit from your business venture."; const issueNewSharesOnCd = corp.issueNewSharesCooldown > 0; const issueNewSharesTooltip = issueNewSharesOnCd @@ -212,28 +211,21 @@ function PublicButtons({ rerender }: IPublicButtonsProps): React.ReactElement { return ( <> {sellSharesTooltip}}> - - - + setSellSharesOpen(false)} rerender={rerender} /> Buy back shares you that previously issued or sold at market price.}> - - - + setBuybackSharesOpen(false)} rerender={rerender} /> -
{issueNewSharesTooltip}}> - - - + setIssueNewSharesOpen(false)} /> setIssueDividendsOpen(true)}>Issue Dividends setIssueDividendsOpen(false)} /> -
); } @@ -269,11 +260,9 @@ function BribeButton(): React.ReactElement { : "Your Corporation is not powerful enough to bribe Faction leaders" } > - - - +
setOpen(false)} /> From 6018f2280d48f166dd865f85e1d7ee9fe682d0aa Mon Sep 17 00:00:00 2001 From: nickofolas Date: Fri, 21 Jan 2022 16:08:02 -0600 Subject: [PATCH 04/10] Research modal UI pass --- src/Corporation/ui/ResearchModal.tsx | 53 +++++++++++++++++++--------- 1 file changed, 37 insertions(+), 16 deletions(-) diff --git a/src/Corporation/ui/ResearchModal.tsx b/src/Corporation/ui/ResearchModal.tsx index fc34c2be3..3c882c2b1 100644 --- a/src/Corporation/ui/ResearchModal.tsx +++ b/src/Corporation/ui/ResearchModal.tsx @@ -6,17 +6,18 @@ import { IIndustry } from "../IIndustry"; import { Research } from "../Actions"; import { Node } from "../ResearchTree"; import { ResearchMap } from "../ResearchMap"; +import { Settings } from "../../Settings/Settings"; import { dialogBoxCreate } from "../../ui/React/DialogBox"; import Typography from "@mui/material/Typography"; import Tooltip from "@mui/material/Tooltip"; import Button from "@mui/material/Button"; import Box from "@mui/material/Box"; -import ListItemButton from "@mui/material/ListItemButton"; -import ListItemText from "@mui/material/ListItemText"; import Collapse from "@mui/material/Collapse"; import ExpandMore from "@mui/icons-material/ExpandMore"; import ExpandLess from "@mui/icons-material/ExpandLess"; +import CheckIcon from '@mui/icons-material/Check'; + interface INodeProps { n: Node | null; division: IIndustry; @@ -42,8 +43,8 @@ function Upgrade({ n, division }: INodeProps): React.ReactElement { dialogBoxCreate( `Researched ${n.text}. It may take a market cycle ` + - `(~${CorporationConstants.SecsPerMarketCycle} seconds) before the effects of ` + - `the Research apply.`, + `(~${CorporationConstants.SecsPerMarketCycle} seconds) before the effects of ` + + `the Research apply.`, ); } @@ -52,8 +53,8 @@ function Upgrade({ n, division }: INodeProps): React.ReactElement { color = "info"; } - const but = ( - + const wrapInTooltip = (ele: React.ReactElement): React.ReactElement => { + return ( @@ -63,12 +64,22 @@ function Upgrade({ n, division }: INodeProps): React.ReactElement { } > + {ele} + + ) + } + + const but = ( + + {wrapInTooltip( - - + )} ); @@ -76,15 +87,25 @@ function Upgrade({ n, division }: INodeProps): React.ReactElement { return ( - - {but} - setOpen((old) => !old)}> - + + {wrapInTooltip( + + + + )} + - + {n.children.map((m) => ( ))} @@ -108,7 +129,7 @@ export function ResearchModal(props: IProps): React.ReactElement { return ( - + Research points: {props.industry.sciResearch.qty.toFixed(3)}
Multipliers from research: From a954095519bb944b057028bac3da3a0c69375ed7 Mon Sep 17 00:00:00 2001 From: nickofolas Date: Fri, 21 Jan 2022 16:15:41 -0600 Subject: [PATCH 05/10] Prevent FactionRoot options from extending beyond the window --- src/Faction/ui/DonateOption.tsx | 2 +- src/Faction/ui/Option.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Faction/ui/DonateOption.tsx b/src/Faction/ui/DonateOption.tsx index c189e3ce1..255c73711 100644 --- a/src/Faction/ui/DonateOption.tsx +++ b/src/Faction/ui/DonateOption.tsx @@ -77,7 +77,7 @@ export function DonateOption(props: IProps): React.ReactElement { } return ( - + {props.disabled ? ( diff --git a/src/Faction/ui/Option.tsx b/src/Faction/ui/Option.tsx index 1307955d1..9ec2af68b 100644 --- a/src/Faction/ui/Option.tsx +++ b/src/Faction/ui/Option.tsx @@ -19,7 +19,7 @@ type IProps = { export function Option(props: IProps): React.ReactElement { return ( - + {props.infoText} From 259071e3d544724d27ed04a64f9bdd6ec6c8c2ef Mon Sep 17 00:00:00 2001 From: nickofolas Date: Fri, 21 Jan 2022 16:32:32 -0600 Subject: [PATCH 06/10] Align slider endpoints in settings --- src/ui/React/GameOptionsRoot.tsx | 188 +++++++++++++++---------------- 1 file changed, 91 insertions(+), 97 deletions(-) diff --git a/src/ui/React/GameOptionsRoot.tsx b/src/ui/React/GameOptionsRoot.tsx index e1ce714a6..cff5167e0 100644 --- a/src/ui/React/GameOptionsRoot.tsx +++ b/src/ui/React/GameOptionsRoot.tsx @@ -205,103 +205,97 @@ export function GameOptionsRoot(props: IProps): React.ReactElement { - - The minimum number of milliseconds it takes to execute an operation in Netscript. Setting this too - low can result in poor performance if you have many scripts running. - - } - > - .script exec time (ms) - - - - - - The maximum number of lines a script's logs can hold. Setting this too high can cause the game to - use a lot of memory if you have many scripts running. -
- } - > - Netscript log size - - - - - - The maximum number of entries that can be written to a port using Netscript's write() function. - Setting this too high can cause the game to use a lot of memory. -
- } - > - Netscript port size - - - - - - The maximum number of entries that can be written to the terminal. Setting this too high can cause - the game to use a lot of memory. - - } - > - Terminal capacity - - - - - The time (in seconds) between each autosave. Set to 0 to disable autosave. - } - > - Autosave interval (s) - - + + + The minimum number of milliseconds it takes to execute an operation in Netscript. Setting this too + low can result in poor performance if you have many scripts running. + + } + > + .script exec time (ms) + + + + The maximum number of lines a script's logs can hold. Setting this too high can cause the game to + use a lot of memory if you have many scripts running. + + } + > + Netscript log size + + + + The maximum number of entries that can be written to a port using Netscript's write() function. + Setting this too high can cause the game to use a lot of memory. + + } + > + Netscript port size + + + + The maximum number of entries that can be written to the terminal. Setting this too high can cause + the game to use a lot of memory. + + } + > + Terminal capacity + + + The time (in seconds) between each autosave. Set to 0 to disable autosave. + } + > + Autosave interval (s) + + + Date: Fri, 21 Jan 2022 20:02:29 -0600 Subject: [PATCH 07/10] Redesign Gang management page --- src/Gang/ui/GangMemberAccordion.tsx | 36 ------- src/Gang/ui/GangMemberAccordionContent.tsx | 31 ------ src/Gang/ui/GangMemberCard.tsx | 26 +++++ src/Gang/ui/GangMemberCardContent.tsx | 62 +++++++++++ src/Gang/ui/GangMemberList.tsx | 52 +++++++-- src/Gang/ui/GangMemberStats.tsx | 116 +++++++++++---------- src/Gang/ui/RecruitButton.tsx | 10 +- src/Gang/ui/TaskSelector.tsx | 25 ++--- 8 files changed, 210 insertions(+), 148 deletions(-) delete mode 100644 src/Gang/ui/GangMemberAccordion.tsx delete mode 100644 src/Gang/ui/GangMemberAccordionContent.tsx create mode 100644 src/Gang/ui/GangMemberCard.tsx create mode 100644 src/Gang/ui/GangMemberCardContent.tsx diff --git a/src/Gang/ui/GangMemberAccordion.tsx b/src/Gang/ui/GangMemberAccordion.tsx deleted file mode 100644 index 0f9cefcef..000000000 --- a/src/Gang/ui/GangMemberAccordion.tsx +++ /dev/null @@ -1,36 +0,0 @@ -/** - * React Component for a gang member on the management subpage. - */ -import React, { useState } from "react"; -import { GangMember } from "../GangMember"; -import { GangMemberAccordionContent } from "./GangMemberAccordionContent"; - -import Box from "@mui/material/Box"; - -import Typography from "@mui/material/Typography"; -import ListItemButton from "@mui/material/ListItemButton"; -import ListItemText from "@mui/material/ListItemText"; -import Paper from "@mui/material/Paper"; -import Collapse from "@mui/material/Collapse"; -import ExpandMore from "@mui/icons-material/ExpandMore"; -import ExpandLess from "@mui/icons-material/ExpandLess"; -interface IProps { - member: GangMember; -} - -export function GangMemberAccordion(props: IProps): React.ReactElement { - const [open, setOpen] = useState(true); - return ( - - setOpen((old) => !old)}> - {props.member.name}} /> - {open ? : } - - - - - - - - ); -} diff --git a/src/Gang/ui/GangMemberAccordionContent.tsx b/src/Gang/ui/GangMemberAccordionContent.tsx deleted file mode 100644 index a79592b36..000000000 --- a/src/Gang/ui/GangMemberAccordionContent.tsx +++ /dev/null @@ -1,31 +0,0 @@ -/** - * React Component for the content of the accordion of gang members on the - * management subpage. - */ -import React, { useState } from "react"; -import { GangMemberStats } from "./GangMemberStats"; -import { TaskSelector } from "./TaskSelector"; -import { TaskDescription } from "./TaskDescription"; -import { GangMember } from "../GangMember"; -import Grid from "@mui/material/Grid"; - -interface IProps { - member: GangMember; -} - -export function GangMemberAccordionContent(props: IProps): React.ReactElement { - const setRerender = useState(false)[1]; - return ( - - - setRerender((old) => !old)} member={props.member} /> - - - setRerender((old) => !old)} member={props.member} /> - - - - - - ); -} diff --git a/src/Gang/ui/GangMemberCard.tsx b/src/Gang/ui/GangMemberCard.tsx new file mode 100644 index 000000000..f8ed9dd06 --- /dev/null +++ b/src/Gang/ui/GangMemberCard.tsx @@ -0,0 +1,26 @@ +/** + * React Component for a gang member on the management subpage. + */ +import React from "react"; +import { GangMember } from "../GangMember"; +import { GangMemberCardContent } from "./GangMemberCardContent"; + +import Box from "@mui/material/Box"; + +import ListItemText from "@mui/material/ListItemText"; +import Paper from "@mui/material/Paper"; + +interface IProps { + member: GangMember; +} + +export function GangMemberCard(props: IProps): React.ReactElement { + return ( + + + {props.member.name}} /> + + + + ); +} diff --git a/src/Gang/ui/GangMemberCardContent.tsx b/src/Gang/ui/GangMemberCardContent.tsx new file mode 100644 index 000000000..ca3cb9de5 --- /dev/null +++ b/src/Gang/ui/GangMemberCardContent.tsx @@ -0,0 +1,62 @@ +/** + * React Component for the content of the accordion of gang members on the + * management subpage. + */ +import React, { useState } from "react"; +import { GangMemberStats } from "./GangMemberStats"; +import { TaskSelector } from "./TaskSelector"; +import { AscensionModal } from "./AscensionModal"; + +import { Box } from "@mui/system"; +import { Button, Typography } from "@mui/material"; +import HelpIcon from "@mui/icons-material/Help"; + +import { GangMember } from "../GangMember"; +import { StaticModal } from "../../ui/React/StaticModal"; + +interface IProps { + member: GangMember; +} + +export function GangMemberCardContent(props: IProps): React.ReactElement { + const setRerender = useState(false)[1]; + const [helpOpen, setHelpOpen] = useState(false); + const [ascendOpen, setAscendOpen] = useState(false); + + return ( + <> + {props.member.canAscend() && ( + + + setAscendOpen(false)} + member={props.member} + onAscend={() => setRerender((old) => !old)} + /> + + setHelpOpen(false)}> + + Ascending a Gang Member resets the member's progress and stats in exchange for a permanent boost to their + stat multipliers. +
+
+ The additional stat multiplier that the Gang Member gains upon ascension is based on the amount of exp + they have. +
+
+ Upon ascension, the member will lose all of its non-Augmentation Equipment and your gang will lose respect + equal to the total respect earned by the member. +
+
+
+ )} + + + setRerender((old) => !old)} member={props.member} /> + + + ); +} diff --git a/src/Gang/ui/GangMemberList.tsx b/src/Gang/ui/GangMemberList.tsx index 104e218b8..fcd8a6b6f 100644 --- a/src/Gang/ui/GangMemberList.tsx +++ b/src/Gang/ui/GangMemberList.tsx @@ -2,23 +2,63 @@ * React Component for the list of gang members on the management subpage. */ import React, { useState } from "react"; -import { GangMemberAccordion } from "./GangMemberAccordion"; -import { GangMember } from "../GangMember"; +import { GangMemberCard } from "./GangMemberCard"; import { RecruitButton } from "./RecruitButton"; import { useGang } from "./Context"; +import { Box, TextField } from "@mui/material"; +import SearchIcon from "@mui/icons-material/Search"; + +import { GangMember } from "../GangMember"; +import { OptionSwitch } from "../../ui/React/OptionSwitch"; + export function GangMemberList(): React.ReactElement { const gang = useGang(); const setRerender = useState(false)[1]; + const [filter, setFilter] = useState(""); + const [ascendOnly, setAscendOnly] = useState(false); + + const handleFilterChange = (event: React.ChangeEvent): void => { + setFilter(event.target.value.toLowerCase()); + } + + const members = gang.members + .filter((member) => member && member.name.toLowerCase().includes(filter)) + .filter((member) => { + if (ascendOnly) return member.canAscend(); + return true; + }); return ( <> setRerender((old) => !old)} /> -
    - {gang.members.map((member: GangMember) => ( - + , + spellCheck: false + }} + placeholder="Filter by member name" + sx={{ m: 1, width: '15%' }} + /> + (setAscendOnly(newValue))} + text="Show only ascendable" + tooltip={ + <> + Filter the members list by whether or not the member + can be ascended. + + } + /> + + {members.map((member: GangMember) => ( + ))} -
+
); } diff --git a/src/Gang/ui/GangMemberStats.tsx b/src/Gang/ui/GangMemberStats.tsx index c81161a7e..03198f01d 100644 --- a/src/Gang/ui/GangMemberStats.tsx +++ b/src/Gang/ui/GangMemberStats.tsx @@ -2,26 +2,31 @@ * React Component for the first part of a gang member details. * Contains skills and exp. */ -import React, { useState } from "react"; -import { formatNumber } from "../../utils/StringHelperFunctions"; -import { numeralWrapper } from "../../ui/numeralFormat"; -import { GangMember } from "../GangMember"; -import { AscensionModal } from "./AscensionModal"; +import React from "react"; +import { useGang } from "./Context"; + import Typography from "@mui/material/Typography"; import Tooltip from "@mui/material/Tooltip"; -import Button from "@mui/material/Button"; -import { StaticModal } from "../../ui/React/StaticModal"; -import IconButton from "@mui/material/IconButton"; -import HelpIcon from "@mui/icons-material/Help"; +import { + Table, + TableBody, + TableCell, + TableRow, +} from "@mui/material"; + +import { numeralWrapper } from "../../ui/numeralFormat"; +import { GangMember } from "../GangMember"; +import { Settings } from "../../Settings/Settings"; +import { formatNumber } from "../../utils/StringHelperFunctions"; +import { MoneyRate } from "../../ui/React/MoneyRate"; +import { characterOverviewStyles as useStyles } from "../../ui/React/CharacterOverview"; interface IProps { member: GangMember; - onAscend: () => void; } export function GangMemberStats(props: IProps): React.ReactElement { - const [helpOpen, setHelpOpen] = useState(false); - const [ascendOpen, setAscendOpen] = useState(false); + const classes = useStyles(); const asc = { hack: props.member.calculateAscensionMult(props.member.hack_asc_points), @@ -32,6 +37,29 @@ export function GangMemberStats(props: IProps): React.ReactElement { cha: props.member.calculateAscensionMult(props.member.cha_asc_points), }; + const generateTableRow = (name: string, level: number, exp: number, color: string): React.ReactElement => { + return ( + + + {name} + + + + {formatNumber(level, 0)} ({numeralWrapper.formatExp(exp)} exp) + + + + ) + } + + const gang = useGang(); + const data = [ + [`Money:`, ], + [`Respect:`, `${numeralWrapper.formatRespect(5 * props.member.calculateRespectGain(gang))} / sec`], + [`Wanted Level:`, `${numeralWrapper.formatWanted(5 * props.member.calculateWantedLevelGain(gang))} / sec`], + [`Total Respect:`, `${numeralWrapper.formatRespect(props.member.earnedRespect)}`], + ]; + return ( <> } > - - Hacking: {formatNumber(props.member.hack, 0)} ({numeralWrapper.formatExp(props.member.hack_exp)} exp) -
- Strength: {formatNumber(props.member.str, 0)} ({numeralWrapper.formatExp(props.member.str_exp)} exp) -
- Defense: {formatNumber(props.member.def, 0)} ({numeralWrapper.formatExp(props.member.def_exp)} exp) -
- Dexterity: {formatNumber(props.member.dex, 0)} ({numeralWrapper.formatExp(props.member.dex_exp)} exp) -
- Agility: {formatNumber(props.member.agi, 0)} ({numeralWrapper.formatExp(props.member.agi_exp)} exp) -
- Charisma: {formatNumber(props.member.cha, 0)} ({numeralWrapper.formatExp(props.member.cha_exp)} exp) -
-
+ + + {generateTableRow("Hacking", props.member.hack, props.member.hack_exp, Settings.theme.hack)} + {generateTableRow("Strength", props.member.str, props.member.str_exp, Settings.theme.combat)} + {generateTableRow("Defense", props.member.def, props.member.def_exp, Settings.theme.combat)} + {generateTableRow("Dexterity", props.member.dex, props.member.dex_exp, Settings.theme.combat)} + {generateTableRow("Agility", props.member.agi, props.member.agi_exp, Settings.theme.combat)} + {generateTableRow("Charisma", props.member.cha, props.member.cha_exp, Settings.theme.cha)} +
+ {data.map(([a, b]) => ( + + + {a} + + + {b} + + + ))} +
+
-
- {props.member.canAscend() && ( - <> - - setAscendOpen(false)} - member={props.member} - onAscend={props.onAscend} - /> - setHelpOpen(true)}> - - - setHelpOpen(false)}> - - Ascending a Gang Member resets the member's progress and stats in exchange for a permanent boost to their - stat multipliers. -
-
- The additional stat multiplier that the Gang Member gains upon ascension is based on the amount of exp - they have. -
-
- Upon ascension, the member will lose all of its non-Augmentation Equipment and your gang will lose respect - equal to the total respect earned by the member. -
-
- - )} ); } diff --git a/src/Gang/ui/RecruitButton.tsx b/src/Gang/ui/RecruitButton.tsx index 9897557d5..bea1f5e4f 100644 --- a/src/Gang/ui/RecruitButton.tsx +++ b/src/Gang/ui/RecruitButton.tsx @@ -24,18 +24,20 @@ export function RecruitButton(props: IProps): React.ReactElement { if (!gang.canRecruitMember()) { const respect = gang.getRespectNeededToRecruitMember(); return ( - - - {numeralWrapper.formatRespect(respect)} respect needed to recruit next member + {numeralWrapper.formatRespect(respect)} respect needed to recruit next member ); } return ( <> - + + + setOpen(false)} onRecruit={props.onRecruit} /> ); diff --git a/src/Gang/ui/TaskSelector.tsx b/src/Gang/ui/TaskSelector.tsx index 02e3e2013..ff19ff550 100644 --- a/src/Gang/ui/TaskSelector.tsx +++ b/src/Gang/ui/TaskSelector.tsx @@ -3,14 +3,15 @@ * the task selector as well as some stats. */ import React, { useState } from "react"; -import { numeralWrapper } from "../../ui/numeralFormat"; -import { StatsTable } from "../../ui/React/StatsTable"; -import { MoneyRate } from "../../ui/React/MoneyRate"; import { useGang } from "./Context"; -import { GangMember } from "../GangMember"; +import { TaskDescription } from "./TaskDescription"; + +import { Box } from "@mui/material"; import MenuItem from "@mui/material/MenuItem"; import Select, { SelectChangeEvent } from "@mui/material/Select"; +import { GangMember } from "../GangMember"; + interface IProps { member: GangMember; onTaskChange: () => void; @@ -29,16 +30,9 @@ export function TaskSelector(props: IProps): React.ReactElement { const tasks = gang.getAllTaskNames(); - const data = [ - [`Money:`, ], - [`Respect:`, `${numeralWrapper.formatRespect(5 * props.member.calculateRespectGain(gang))} / sec`], - [`Wanted Level:`, `${numeralWrapper.formatWanted(5 * props.member.calculateWantedLevelGain(gang))} / sec`], - [`Total Respect:`, `${numeralWrapper.formatRespect(props.member.earnedRespect)}`], - ]; - return ( - <> - Unassigned @@ -48,8 +42,7 @@ export function TaskSelector(props: IProps): React.ReactElement { ))} - - - + +
); } From 310374dc567800f351b34cdc70dd413a99d237f0 Mon Sep 17 00:00:00 2001 From: nickofolas Date: Sat, 22 Jan 2022 09:36:36 -0600 Subject: [PATCH 08/10] Fix console complaints with gang cards --- src/Gang/ui/GangMemberStats.tsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Gang/ui/GangMemberStats.tsx b/src/Gang/ui/GangMemberStats.tsx index 03198f01d..676d78f01 100644 --- a/src/Gang/ui/GangMemberStats.tsx +++ b/src/Gang/ui/GangMemberStats.tsx @@ -99,9 +99,13 @@ export function GangMemberStats(props: IProps): React.ReactElement { {generateTableRow("Dexterity", props.member.dex, props.member.dex_exp, Settings.theme.combat)} {generateTableRow("Agility", props.member.agi, props.member.agi_exp, Settings.theme.combat)} {generateTableRow("Charisma", props.member.cha, props.member.cha_exp, Settings.theme.cha)} -
+ + +
+
+
{data.map(([a, b]) => ( - + {a} From 3921457ee6ab1d92c2d7cdf27e6707a3ddbe32b4 Mon Sep 17 00:00:00 2001 From: nickofolas Date: Sat, 22 Jan 2022 11:16:51 -0600 Subject: [PATCH 09/10] Update Gang equip. page UI --- src/Gang/ui/EquipmentsSubpage.tsx | 240 +++++++++++++++++++----------- src/Gang/ui/GangMemberStats.tsx | 49 +++--- 2 files changed, 181 insertions(+), 108 deletions(-) diff --git a/src/Gang/ui/EquipmentsSubpage.tsx b/src/Gang/ui/EquipmentsSubpage.tsx index b5f2b1e60..b2f53c0d8 100644 --- a/src/Gang/ui/EquipmentsSubpage.tsx +++ b/src/Gang/ui/EquipmentsSubpage.tsx @@ -2,20 +2,27 @@ * React Component for the popup that manages gang members upgrades */ import React, { useState } from "react"; -import { formatNumber } from "../../utils/StringHelperFunctions"; -import { numeralWrapper } from "../../ui/numeralFormat"; -import { GangMemberUpgrades } from "../GangMemberUpgrades"; -import { GangMemberUpgrade } from "../GangMemberUpgrade"; -import { Money } from "../../ui/React/Money"; import { useGang } from "./Context"; -import { GangMember } from "../GangMember"; -import { UpgradeType } from "../data/upgrades"; -import { use } from "../../ui/Context"; +import { generateTableRow } from "./GangMemberStats"; + import Typography from "@mui/material/Typography"; import Button from "@mui/material/Button"; import Tooltip from "@mui/material/Tooltip"; import Box from "@mui/material/Box"; import Paper from "@mui/material/Paper"; +import Select, { SelectChangeEvent } from "@mui/material/Select"; +import { MenuItem, Table, TableBody, TextField } from "@mui/material"; +import SearchIcon from "@mui/icons-material/Search"; + +import { numeralWrapper } from "../../ui/numeralFormat"; +import { GangMemberUpgrades } from "../GangMemberUpgrades"; +import { GangMemberUpgrade } from "../GangMemberUpgrade"; +import { Money } from "../../ui/React/Money"; +import { GangMember } from "../GangMember"; +import { UpgradeType } from "../data/upgrades"; +import { use } from "../../ui/Context"; +import { Settings } from "../../Settings/Settings"; +import { characterOverviewStyles as useStyles } from "../../ui/React/CharacterOverview"; interface INextRevealProps { upgrades: string[]; @@ -46,12 +53,10 @@ function NextReveal(props: INextRevealProps): React.ReactElement { function PurchasedUpgrade({ upgName }: { upgName: string }): React.ReactElement { const upg = GangMemberUpgrades[upgName]; return ( - - - }> - {upg.name} - - + + }> + {upg.name} + ); } @@ -72,8 +77,8 @@ function UpgradeButton(props: IUpgradeButtonProps): React.ReactElement { return ( }> - {props.upg.name} - @@ -86,12 +91,16 @@ interface IPanelProps { } function GangMemberUpgradePanel(props: IPanelProps): React.ReactElement { + const classes = useStyles(); const gang = useGang(); const player = use.Player(); const setRerender = useState(false)[1]; + const [currentCategory, setCurrentCategory] = useState("Weapons"); + function rerender(): void { setRerender((old) => !old); } + function filterUpgrades(list: string[], type: UpgradeType): GangMemberUpgrade[] { return Object.keys(GangMemberUpgrades) .filter((upgName: string) => { @@ -103,12 +112,26 @@ function GangMemberUpgradePanel(props: IPanelProps): React.ReactElement { }) .map((upgName: string) => GangMemberUpgrades[upgName]); } + + const onChange = (event: SelectChangeEvent): void => { + setCurrentCategory(event.target.value); + rerender() + } + const weaponUpgrades = filterUpgrades(props.member.upgrades, UpgradeType.Weapon); const armorUpgrades = filterUpgrades(props.member.upgrades, UpgradeType.Armor); const vehicleUpgrades = filterUpgrades(props.member.upgrades, UpgradeType.Vehicle); const rootkitUpgrades = filterUpgrades(props.member.upgrades, UpgradeType.Rootkit); const augUpgrades = filterUpgrades(props.member.augmentations, UpgradeType.Augmentation); + const categories: { [key: string]: (GangMemberUpgrade[] | UpgradeType)[] } = { + 'Weapons': [weaponUpgrades, UpgradeType.Weapon], + 'Armor': [armorUpgrades, UpgradeType.Armor], + 'Vehicles': [vehicleUpgrades, UpgradeType.Vehicle], + 'Rootkits': [rootkitUpgrades, UpgradeType.Rootkit], + 'Augmentations': [augUpgrades, UpgradeType.Augmentation] + }; + const asc = { hack: props.member.calculateAscensionMult(props.member.hack_asc_points), str: props.member.calculateAscensionMult(props.member.str_asc_points), @@ -119,26 +142,89 @@ function GangMemberUpgradePanel(props: IPanelProps): React.ReactElement { }; return ( - - {props.member.name} ({props.member.task}) - - - Hack: {props.member.hack} (x - {formatNumber(props.member.hack_mult * asc.hack, 2)})
- Str: {props.member.str} (x - {formatNumber(props.member.str_mult * asc.str, 2)})
- Def: {props.member.def} (x - {formatNumber(props.member.def_mult * asc.def, 2)})
- Dex: {props.member.dex} (x - {formatNumber(props.member.dex_mult * asc.dex, 2)})
- Agi: {props.member.agi} (x - {formatNumber(props.member.agi_mult * asc.agi, 2)})
- Cha: {props.member.cha} (x - {formatNumber(props.member.cha_mult * asc.cha, 2)}) -
- - Purchased Upgrades: -
+ + + + {props.member.name} ({props.member.task}) + + + Hk: x{numeralWrapper.formatMultiplier(props.member.hack_mult * asc.hack)}(x + {numeralWrapper.formatMultiplier(props.member.hack_mult)} Eq, x{numeralWrapper.formatMultiplier(asc.hack)}{" "} + Asc) +
+ St: x{numeralWrapper.formatMultiplier(props.member.str_mult * asc.str)} + (x{numeralWrapper.formatMultiplier(props.member.str_mult)} Eq, x{numeralWrapper.formatMultiplier(asc.str)}{" "} + Asc) +
+ Df: x{numeralWrapper.formatMultiplier(props.member.def_mult * asc.def)} + (x{numeralWrapper.formatMultiplier(props.member.def_mult)} Eq, x{numeralWrapper.formatMultiplier(asc.def)}{" "} + Asc) +
+ Dx: x{numeralWrapper.formatMultiplier(props.member.dex_mult * asc.dex)} + (x{numeralWrapper.formatMultiplier(props.member.dex_mult)} Eq, x{numeralWrapper.formatMultiplier(asc.dex)}{" "} + Asc) +
+ Ag: x{numeralWrapper.formatMultiplier(props.member.agi_mult * asc.agi)} + (x{numeralWrapper.formatMultiplier(props.member.agi_mult)} Eq, x{numeralWrapper.formatMultiplier(asc.agi)}{" "} + Asc) +
+ Ch: x{numeralWrapper.formatMultiplier(props.member.cha_mult * asc.cha)} + (x{numeralWrapper.formatMultiplier(props.member.cha_mult)} Eq, x{numeralWrapper.formatMultiplier(asc.cha)}{" "} + Asc) + + } + > + + + {generateTableRow("Hacking", props.member.hack, props.member.hack_exp, Settings.theme.hack, classes)} + {generateTableRow("Strength", props.member.str, props.member.str_exp, Settings.theme.combat, classes)} + {generateTableRow("Defense", props.member.def, props.member.def_exp, Settings.theme.combat, classes)} + {generateTableRow("Dexterity", props.member.dex, props.member.dex_exp, Settings.theme.combat, classes)} + {generateTableRow("Agility", props.member.agi, props.member.agi_exp, Settings.theme.combat, classes)} + {generateTableRow("Charisma", props.member.cha, props.member.cha_exp, Settings.theme.cha, classes)} + +
+
+ +
+ + + + + + {(categories[currentCategory][0] as GangMemberUpgrade[]).length === 0 && ( + + All upgrades owned! + + )} + + {(categories[currentCategory][0] as GangMemberUpgrade[]).map((upg) => ( + + ))} + + + + +
+ + Purchased Upgrades: + {props.member.upgrades.map((upg: string) => ( ))} @@ -146,59 +232,22 @@ function GangMemberUpgradePanel(props: IPanelProps): React.ReactElement { ))} - - - - Weapons - - {weaponUpgrades.map((upg) => ( - - ))} - - - - - Armor - - {armorUpgrades.map((upg) => ( - - ))} - - - - - Vehicles - - {vehicleUpgrades.map((upg) => ( - - ))} - - - - - Rootkits - - {rootkitUpgrades.map((upg) => ( - - ))} - - - - - Augmentations - - {augUpgrades.map((upg) => ( - - ))} - - - -
+
); } export function EquipmentsSubpage(): React.ReactElement { const gang = useGang(); + const [filter, setFilter] = useState(""); + + + const handleFilterChange = (event: React.ChangeEvent): void => { + setFilter(event.target.value.toLowerCase()); + } + + const members = gang.members + .filter((member) => member && member.name.toLowerCase().includes(filter)); + return ( <> } > - Discount: -{numeralWrapper.formatPercentage(1 - 1 / gang.getDiscount())} + Discount: -{numeralWrapper.formatPercentage(1 - 1 / gang.getDiscount())} - {gang.members.map((member: GangMember) => ( - - ))} + + , + spellCheck: false + }} + placeholder="Filter by member name" + sx={{ m: 1, width: '15%' }} + /> + + + {members.map((member: GangMember) => ( + + ))} + ); } diff --git a/src/Gang/ui/GangMemberStats.tsx b/src/Gang/ui/GangMemberStats.tsx index 676d78f01..859057837 100644 --- a/src/Gang/ui/GangMemberStats.tsx +++ b/src/Gang/ui/GangMemberStats.tsx @@ -25,6 +25,28 @@ interface IProps { member: GangMember; } +export const generateTableRow = ( + name: string, + level: number, + exp: number, + color: string, + // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types + classes: any +): React.ReactElement => { + return ( + + + {name} + + + + {formatNumber(level, 0)} ({numeralWrapper.formatExp(exp)} exp) + + + + ) +} + export function GangMemberStats(props: IProps): React.ReactElement { const classes = useStyles(); @@ -37,20 +59,7 @@ export function GangMemberStats(props: IProps): React.ReactElement { cha: props.member.calculateAscensionMult(props.member.cha_asc_points), }; - const generateTableRow = (name: string, level: number, exp: number, color: string): React.ReactElement => { - return ( - - - {name} - - - - {formatNumber(level, 0)} ({numeralWrapper.formatExp(exp)} exp) - - - - ) - } + const gang = useGang(); const data = [ @@ -93,12 +102,12 @@ export function GangMemberStats(props: IProps): React.ReactElement { > - {generateTableRow("Hacking", props.member.hack, props.member.hack_exp, Settings.theme.hack)} - {generateTableRow("Strength", props.member.str, props.member.str_exp, Settings.theme.combat)} - {generateTableRow("Defense", props.member.def, props.member.def_exp, Settings.theme.combat)} - {generateTableRow("Dexterity", props.member.dex, props.member.dex_exp, Settings.theme.combat)} - {generateTableRow("Agility", props.member.agi, props.member.agi_exp, Settings.theme.combat)} - {generateTableRow("Charisma", props.member.cha, props.member.cha_exp, Settings.theme.cha)} + {generateTableRow("Hacking", props.member.hack, props.member.hack_exp, Settings.theme.hack, classes)} + {generateTableRow("Strength", props.member.str, props.member.str_exp, Settings.theme.combat, classes)} + {generateTableRow("Defense", props.member.def, props.member.def_exp, Settings.theme.combat, classes)} + {generateTableRow("Dexterity", props.member.dex, props.member.dex_exp, Settings.theme.combat, classes)} + {generateTableRow("Agility", props.member.agi, props.member.agi_exp, Settings.theme.combat, classes)} + {generateTableRow("Charisma", props.member.cha, props.member.cha_exp, Settings.theme.cha, classes)}
From f6bb4e013871dfdf9c6a24564980527e2fbadf6f Mon Sep 17 00:00:00 2001 From: nickofolas Date: Sat, 22 Jan 2022 11:37:27 -0600 Subject: [PATCH 10/10] Fix console warning on ascension modal --- src/Gang/ui/AscensionModal.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Gang/ui/AscensionModal.tsx b/src/Gang/ui/AscensionModal.tsx index bd9b5d868..82f7c50b6 100644 --- a/src/Gang/ui/AscensionModal.tsx +++ b/src/Gang/ui/AscensionModal.tsx @@ -31,7 +31,7 @@ export function AscensionModal(props: IProps): React.ReactElement { props.onAscend(); const res = gang.ascendMember(props.member); dialogBoxCreate( - + <> You ascended {props.member.name}!

Your gang lost {numeralWrapper.formatRespect(res.respect)} respect. @@ -51,7 +51,7 @@ export function AscensionModal(props: IProps): React.ReactElement {
Charisma: x{numeralWrapper.format(res.cha, "0.000")}
-
, + ); props.onClose(); }