diff --git a/src/SaveObject.tsx b/src/SaveObject.ts old mode 100755 new mode 100644 similarity index 99% rename from src/SaveObject.tsx rename to src/SaveObject.ts index d345f88f7..a12e50e7c --- a/src/SaveObject.tsx +++ b/src/SaveObject.ts @@ -1,3 +1,5 @@ +import { Skills } from "@nsdefs"; + import { loadAliases, loadGlobalAliases, Aliases, GlobalAliases } from "./Alias"; import { Companies, loadCompanies } from "./Company/Companies"; import { CONSTANTS } from "./Constants"; @@ -60,7 +62,7 @@ export interface ImportPlayerData { totalPlaytime: number; money: number; - hacking: number; + skills: Skills; augmentations: number; factions: number; @@ -222,7 +224,7 @@ class BitburnerSaveObject { totalPlaytime: importedPlayer.totalPlaytime, money: importedPlayer.money, - hacking: importedPlayer.skills.hacking, + skills: importedPlayer.skills, augmentations: importedPlayer.augmentations?.reduce((total, current) => (total += current.level), 0) ?? 0, factions: importedPlayer.factions?.length ?? 0, diff --git a/src/ui/GameRoot.tsx b/src/ui/GameRoot.tsx index 089de2750..5a5e20e79 100644 --- a/src/ui/GameRoot.tsx +++ b/src/ui/GameRoot.tsx @@ -68,7 +68,7 @@ import { RecoveryMode, RecoveryRoot } from "./React/RecoveryRoot"; import { AchievementsRoot } from "../Achievements/AchievementsRoot"; import { ErrorBoundary } from "./ErrorBoundary"; import { ThemeBrowser } from "../Themes/ui/ThemeBrowser"; -import { ImportSaveRoot } from "./React/ImportSaveRoot"; +import { ImportSave } from "./React/ImportSave"; import { BypassWrapper } from "./React/BypassWrapper"; import { Apr1 } from "./Apr1"; @@ -415,7 +415,7 @@ export function GameRoot(): React.ReactElement { break; } case Page.ImportSave: { - mainPage = ; + mainPage = ; withSidebar = false; withPopups = false; bypassGame = true; diff --git a/src/ui/React/ImportSave/ComparisonIcon.tsx b/src/ui/React/ImportSave/ComparisonIcon.tsx new file mode 100644 index 000000000..6ace78b21 --- /dev/null +++ b/src/ui/React/ImportSave/ComparisonIcon.tsx @@ -0,0 +1,13 @@ +import React from "react"; + +import { Tooltip } from "@mui/material"; + +import ThumbUpAlt from "@mui/icons-material/ThumbUpAlt"; +import ThumbDownAlt from "@mui/icons-material/ThumbDownAlt"; + +export const ComparisonIcon = ({ isBetter }: { isBetter: boolean }): JSX.Element => { + const title = isBetter ? "Imported value is larger!" : "Imported value is smaller!"; + const icon = isBetter ? : ; + + return {icon}; +}; diff --git a/src/ui/React/ImportSaveRoot.tsx b/src/ui/React/ImportSave/ImportSave.tsx similarity index 71% rename from src/ui/React/ImportSaveRoot.tsx rename to src/ui/React/ImportSave/ImportSave.tsx index 3487ba2ee..028e6b971 100644 --- a/src/ui/React/ImportSaveRoot.tsx +++ b/src/ui/React/ImportSave/ImportSave.tsx @@ -1,38 +1,43 @@ import React, { useEffect, useState } from "react"; -import { - Paper, - Table, - TableHead, - TableRow, - TableBody, - TableContainer, - TableCell, - Typography, - Tooltip, - Box, - Button, - ButtonGroup, -} from "@mui/material"; +import Box from "@mui/material/Box"; +import Button from "@mui/material/Button"; +import ButtonGroup from "@mui/material/ButtonGroup"; +import Collapse from "@mui/material/Collapse"; +import IconButton from "@mui/material/IconButton"; +import Paper from "@mui/material/Paper"; +import Table from "@mui/material/Table"; +import TableHead from "@mui/material/TableHead"; +import TableRow from "@mui/material/TableRow"; +import TableBody from "@mui/material/TableBody"; +import TableContainer from "@mui/material/TableContainer"; +import TableCell from "@mui/material/TableCell"; +import Tooltip from "@mui/material/Tooltip"; +import Typography from "@mui/material/Typography"; import makeStyles from "@mui/styles/makeStyles"; import createStyles from "@mui/styles/createStyles"; import { Theme } from "@mui/material/styles"; -import ThumbUpAlt from "@mui/icons-material/ThumbUpAlt"; -import ThumbDownAlt from "@mui/icons-material/ThumbDownAlt"; +import WarningIcon from "@mui/icons-material/Warning"; import DirectionsRunIcon from "@mui/icons-material/DirectionsRun"; import ArrowBackIcon from "@mui/icons-material/ArrowBack"; -import WarningIcon from "@mui/icons-material/Warning"; +import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown"; +import KeyboardArrowUpIcon from "@mui/icons-material/KeyboardArrowUp"; -import { ImportData, saveObject } from "../../SaveObject"; -import { Settings } from "../../Settings/Settings"; -import { convertTimeMsToTimeElapsedString } from "../../utils/StringHelperFunctions"; -import { formatMoney, formatNumberNoSuffix } from "../formatNumber"; -import { ConfirmationModal } from "./ConfirmationModal"; -import { pushImportResult } from "../../Electron"; -import { Router } from "../GameRoot"; -import { Page } from "../Router"; +import { Skills } from "@nsdefs"; + +import { ImportData, saveObject } from "../../../SaveObject"; +import { Settings } from "../../../Settings/Settings"; +import { convertTimeMsToTimeElapsedString } from "../../../utils/StringHelperFunctions"; +import { formatMoney, formatNumberNoSuffix } from "../../formatNumber"; +import { ConfirmationModal } from "../ConfirmationModal"; +import { pushImportResult } from "../../../Electron"; +import { Router } from "../../GameRoot"; +import { Page } from "../../Router"; +import { useBoolean } from "../hooks"; + +import { ComparisonIcon } from "./ComparisonIcon"; const useStyles = makeStyles((theme: Theme) => createStyles({ @@ -72,62 +77,37 @@ const useStyles = makeStyles((theme: Theme) => }, }, }, + + skillTitle: { + textTransform: "capitalize", + }, }), ); -function ComparisonIcon({ isBetter }: { isBetter: boolean }): JSX.Element { - if (isBetter) { - return ( - - Imported value is larger! - - } - > - - - ); - } else { - return ( - - Imported value is smaller! - - } - > - - - ); - } -} - -export interface IProps { - importString: string; - automatic: boolean; -} +// TODO: move to game constants and/or extract as an enum +const playerSkills: (keyof Skills)[] = ["hacking", "strength", "defense", "dexterity", "agility", "charisma"]; let initialAutosave = 0; -export function ImportSaveRoot(props: IProps): JSX.Element { +export const ImportSave = (props: { importString: string; automatic: boolean }): JSX.Element => { const classes = useStyles(); const [importData, setImportData] = useState(); const [currentData, setCurrentData] = useState(); - const [importModalOpen, setImportModalOpen] = useState(false); + const [isImportModalOpen, { on: openImportModal, off: closeImportModal }] = useBoolean(false); + const [isSkillsExpanded, { toggle: toggleSkillsExpand }] = useBoolean(true); const [headback, setHeadback] = useState(false); - function handleGoBack(): void { + const handleGoBack = (): void => { Settings.AutosaveInterval = initialAutosave; pushImportResult(false); Router.allowRouting(true); setHeadback(true); - } + }; - async function handleImport(): Promise { + const handleImport = async (): Promise => { await saveObject.importGame(props.importString, true); pushImportResult(true); - } + }; useEffect(() => { // We want to disable autosave while we're in this mode @@ -154,6 +134,7 @@ export function ImportSaveRoot(props: IProps): JSX.Element { }, [props.importString]); if (!importData || !currentData) return <>; + return ( @@ -176,7 +157,7 @@ export function ImportSaveRoot(props: IProps): JSX.Element { Current Game Being Imported - + @@ -241,19 +222,43 @@ export function ImportSaveRoot(props: IProps): JSX.Element { )} - - Hacking - {formatNumberNoSuffix(currentData.playerData?.hacking ?? 0, 0)} - {formatNumberNoSuffix(importData.playerData?.hacking ?? 0, 0)} - - {importData.playerData?.hacking !== currentData.playerData?.hacking && ( - (currentData.playerData?.hacking ?? 0)} - /> - )} + + + {isSkillsExpanded ? : } + + Skills + + + + + + {/* empty row to keep even/odd coloring */} + {playerSkills.map((skill) => { + const currentSkill = currentData.playerData?.skills[skill] ?? 0; + const importSkill = importData.playerData?.skills[skill] ?? 0; + return ( + + {skill} + {formatNumberNoSuffix(currentSkill, 0)} + {formatNumberNoSuffix(importSkill, 0)} + + {currentSkill !== importSkill && currentSkill} />} + + + ); + })} + {playerSkills.length % 2 === 1 && ( + {/* empty row to keep even/odd coloring */} + )} + +
+
+
+
+ {/* empty row to keep even/odd coloring */} Augmentations @@ -327,18 +332,13 @@ export function ImportSaveRoot(props: IProps): JSX.Element { - setImportModalOpen(false)} + open={isImportModalOpen} + onClose={closeImportModal} onConfirm={handleImport} confirmationText={ <> @@ -350,4 +350,4 @@ export function ImportSaveRoot(props: IProps): JSX.Element {
); -} +}; diff --git a/src/ui/React/ImportSave/index.ts b/src/ui/React/ImportSave/index.ts new file mode 100644 index 000000000..fb63bd9dd --- /dev/null +++ b/src/ui/React/ImportSave/index.ts @@ -0,0 +1 @@ +export * from "./ImportSave";