From dc9b5c33410e3704065fd2a15745a491a0e42aa3 Mon Sep 17 00:00:00 2001 From: Olivier Gagnon Date: Tue, 14 Sep 2021 21:05:49 -0400 Subject: [PATCH] rework options menu --- src/DevMenu/ui/CodingContracts.tsx | 7 +- src/IEngine.ts | 1 + src/Sidebar/ui/SidebarRoot.tsx | 13 +- src/engine.jsx | 24 +- src/ui/React/GameOptionsRoot.tsx | 842 ++++++++++++++++++----------- src/ui/React/Modal.tsx | 47 ++ src/ui/React/Theme.tsx | 21 +- src/ui/navigationTracking.ts | 5 + 8 files changed, 618 insertions(+), 342 deletions(-) create mode 100644 src/ui/React/Modal.tsx diff --git a/src/DevMenu/ui/CodingContracts.tsx b/src/DevMenu/ui/CodingContracts.tsx index 152dd8ea1..7585d1109 100644 --- a/src/DevMenu/ui/CodingContracts.tsx +++ b/src/DevMenu/ui/CodingContracts.tsx @@ -40,12 +40,7 @@ export function CodingContracts(): React.ReactElement { - {Object.values(CodingContractTypes).map((cc) => ( {cc.name} diff --git a/src/IEngine.ts b/src/IEngine.ts index bbcd1a2d7..6f26ee1c9 100644 --- a/src/IEngine.ts +++ b/src/IEngine.ts @@ -29,4 +29,5 @@ export interface IEngine { loadInfiltrationContent: (name: string, difficulty: number, maxLevel: number) => void; loadMissionContent: () => void; loadResleevingContent: () => void; + loadGameOptionsContent: () => void; } diff --git a/src/Sidebar/ui/SidebarRoot.tsx b/src/Sidebar/ui/SidebarRoot.tsx index 94164b210..15c667e81 100644 --- a/src/Sidebar/ui/SidebarRoot.tsx +++ b/src/Sidebar/ui/SidebarRoot.tsx @@ -254,6 +254,10 @@ export function SidebarRoot(props: IProps): React.ReactElement { setActiveTab("Milestones"); props.engine.loadMilestonesContent(); } + function clickOptions(): void { + setActiveTab("Options"); + props.engine.loadGameOptionsContent(); + } function clickDev(): void { setActiveTab("Dev"); @@ -355,7 +359,7 @@ export function SidebarRoot(props: IProps): React.ReactElement { > {!open ? : } - Bitburner {CONSTANTS.Version}} /> + Bitburner v{CONSTANTS.Version}} /> @@ -711,20 +715,21 @@ export function SidebarRoot(props: IProps): React.ReactElement { - {/* - options + Options - */} + {process.env.NODE_ENV === "development" && ( , Engine.Display.content); + ReactDOM.render( + + saveObject.saveGame(Engine.indexedDb)} + delete={() => saveObject.deleteGame(Engine.indexedDb)} + export={() => saveObject.exportGame()} + import={() => saveObject.importGame()} + forceKill={() => { + for (const hostname of Object.keys(AllServers)) { + AllServers[hostname].runningScripts = []; + } + dialogBoxCreate("Forcefully deleted all running scripts. Please save and refresh page."); + }} + softReset={() => { + dialogBoxCreate("Soft Reset!"); + prestigeAugmentation(); + }} + /> + , + Engine.Display.content, + ); }, // Helper function that hides all content diff --git a/src/ui/React/GameOptionsRoot.tsx b/src/ui/React/GameOptionsRoot.tsx index 01a5758c3..88345d8fa 100644 --- a/src/ui/React/GameOptionsRoot.tsx +++ b/src/ui/React/GameOptionsRoot.tsx @@ -1,337 +1,521 @@ -import React from "react"; +import React, { useState } from "react"; -interface IProps {} +import { IPlayer } from "../../PersonObjects/IPlayer"; + +import { makeStyles, createStyles, Theme } from "@material-ui/core/styles"; +import Typography from "@material-ui/core/Typography"; +import Slider from "@material-ui/core/Slider"; +import Grid from "@material-ui/core/Grid"; +import FormControlLabel from "@material-ui/core/FormControlLabel"; +import Switch from "@material-ui/core/Switch"; +import Select from "@material-ui/core/Select"; +import MenuItem from "@material-ui/core/MenuItem"; +import Button from "@material-ui/core/Button"; +import Box from "@material-ui/core/Box"; +import List from "@material-ui/core/List"; +import ListItem from "@material-ui/core/ListItem"; +import Link from "@material-ui/core/Link"; +import Tooltip from "@material-ui/core/Tooltip"; +import { Modal } from "../../ui/React/Modal"; +import { FileDiagnosticPopup } from "../../Diagnostic/FileDiagnosticPopup"; + +import { Settings } from "../../Settings/Settings"; + +const useStyles = makeStyles((theme: Theme) => + createStyles({ + root: { + width: theme.spacing(50), + padding: theme.spacing(2), + userSelect: "none", + }, + pad: { + padding: theme.spacing(2), + }, + }), +); + +interface IProps { + player: IPlayer; + save: () => void; + delete: () => void; + export: () => void; + import: () => void; + forceKill: () => void; + softReset: () => void; +} export function GameOptionsRoot(props: IProps): React.ReactElement { - return ( - <> -

Game Options

- + const classes = useStyles(); + + const [execTime, setExecTime] = useState(Settings.CodeInstructionRunTime); + const [logSize, setLogSize] = useState(Settings.MaxLogCapacity); + const [portSize, setPortSize] = useState(Settings.MaxPortCapacity); + const [autosaveInterval, setAutosaveInterval] = useState(Settings.AutosaveInterval); + + const [suppressMessages, setSuppressMessages] = useState(Settings.SuppressMessages); + const [suppressFactionInvites, setSuppressFactionInvites] = useState(Settings.SuppressFactionInvites); + const [suppressTravelConfirmations, setSuppressTravelConfirmations] = useState(Settings.SuppressTravelConfirmation); + const [suppressBuyAugmentationConfirmation, setSuppressBuyAugmentationConfirmation] = useState( + Settings.SuppressBuyAugmentationConfirmation, + ); + const [suppressHospitalizationPopup, setSuppressHospitalizationPopup] = useState( + Settings.SuppressHospitalizationPopup, ); - /* -

Game Options

+ const [suppressBladeburnerPopup, setSuppressBladeburnerPopup] = useState(Settings.SuppressBladeburnerPopup); + + const [disableHotkeys, setDisableHotkeys] = useState(Settings.DisableHotkeys); + const [disableASCIIArt, setDisableASCIIArt] = useState(Settings.DisableASCIIArt); + const [disableTextEffects, setDisableTextEffects] = useState(Settings.DisableTextEffects); + const [locale, setLocale] = useState(Settings.Locale); + const [diagnosticOpen, setDiagnosticOpen] = useState(false); + + function handleExecTimeChange(event: any, newValue: number | number[]): void { + setExecTime(newValue as number); + Settings.CodeInstructionRunTime = newValue as number; + } + + function handleLogSizeChange(event: any, newValue: number | number[]): void { + setLogSize(newValue as number); + Settings.MaxLogCapacity = newValue as number; + } + + function handlePortSizeChange(event: any, newValue: number | number[]): void { + setPortSize(newValue as number); + Settings.MaxPortCapacity = newValue as number; + } + + function handleAutosaveIntervalChange(event: any, newValue: number | number[]): void { + setAutosaveInterval(newValue as number); + Settings.AutosaveInterval = newValue as number; + } + + function handleSuppressMessagesChange(event: React.ChangeEvent): void { + setSuppressMessages(event.target.checked); + Settings.SuppressMessages = event.target.checked; + } + + function handleSuppressFactionInvitesChange(event: React.ChangeEvent): void { + setSuppressFactionInvites(event.target.checked); + Settings.SuppressFactionInvites = event.target.checked; + } + + function handleSuppressTravelConfirmationsChange(event: React.ChangeEvent): void { + setSuppressTravelConfirmations(event.target.checked); + Settings.SuppressTravelConfirmation = event.target.checked; + } + + function handleSuppressBuyAugmentationConfirmationChange(event: React.ChangeEvent): void { + setSuppressBuyAugmentationConfirmation(event.target.checked); + Settings.SuppressBuyAugmentationConfirmation = event.target.checked; + } + + function handleSuppressHospitalizationPopupChange(event: React.ChangeEvent): void { + setSuppressHospitalizationPopup(event.target.checked); + Settings.SuppressHospitalizationPopup = event.target.checked; + } + + function handleSuppressBladeburnerPopupChange(event: React.ChangeEvent): void { + setSuppressBladeburnerPopup(event.target.checked); + Settings.SuppressBladeburnerPopup = event.target.checked; + } + + function handleDisableHotkeysChange(event: React.ChangeEvent): void { + setDisableHotkeys(event.target.checked); + Settings.DisableHotkeys = event.target.checked; + } + + function handleDisableASCIIArtChange(event: React.ChangeEvent): void { + setDisableASCIIArt(event.target.checked); + Settings.DisableASCIIArt = event.target.checked; + } + + function handleDisableTextEffectsChange(event: React.ChangeEvent): void { + setDisableTextEffects(event.target.checked); + Settings.DisableTextEffects = event.target.checked; + } + function handleLocaleChange(event: React.ChangeEvent<{ value: unknown }>): void { + setLocale(event.target.value as string); + Settings.Locale = event.target.value as string; + } + + return ( +
+ + Options + + + + + + + + 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. + + } + > + Netscript 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 time (in seconds) between each autosave. Set to 0 to disable autosave. + } + > + Autosave interval (s) + + + + + } + label={ + + If this is set, then any messages you receive will not appear as popups on the screen. They will + still get sent to your home computer as '.msg' files and can be viewed with the 'cat' Terminal + command. + + } + > + Supress messages + + } + /> + + + + } + label={ + + If this is set, then any faction invites you receive will not appear as popups on the screen. + Your outstanding faction invites can be viewed in the 'Factions' page. + + } + > + Supress faction invites + + } + /> + + + + } + label={ + + If this is set, the confirmation message before traveling will not show up. You will + automatically be deducted the travel cost as soon as you click. + + } + > + Supress travel confirmations + + } + /> + + + + } + label={ + + If this is set, the confirmation message before buying augmentation will not show up. + + } + > + Supress buy augmentation confirmation + + } + /> + + + + } + label={ + + If this is set, a popup message will no longer be shown when you are hospitalized after taking + too much damage. + + } + > + Supress hospitalization popup + + } + /> + + {!!props.player.bladeburner && ( + + + } + label={ + + If this is set, then having your Bladeburner actions interrupted by being busy with something + else will not display a popup message. + + } + > + Supress bladeburner popup + + } + /> + + )} + + } + label={ + + If this is set, then most hotkeys (keyboard shortcuts) in the game are disabled. This includes + Terminal commands, hotkeys to navigate between different parts of the game, and the "Save and + Close (Ctrl + b)" hotkey in the Text Editor. + + } + > + Disable hotkeys + + } + /> + + + } + label={ + If this is set all ASCII art will be disabled.}> + Disable ascii art + + } + /> + + + + } + label={ + + If this is set, text effects will not be displayed. This can help if text is difficult to read + in certain areas. + + } + > + Disable text effects + + } + /> + + + Sets the locale for displaying numbers.}> + Locale  + + + +
-
- -
- - - - -
- - -
- - - - -
- - -
- - - - -
- - -
- - - - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - - - -
-
-
- - Changelog - - Documentation +
+ + + +
+ + + + + + + + + + + + + Forcefully kill all active running scripts, in case there is a bug or some unexpected issue with the + game. After using this, save the game and then reload the page. This is different then normal kill in + that normal kill will tell the script to shut down while force kill just removes the references to it + (and it should crash on it's own). This will not remove the files on your computer. Just forcefully + kill all running instance of all scripts. + + } > - Discord - Subreddit - - - - - - - - - -
- - */ + + + + + + Perform a soft reset. Resets everything as if you had just purchased an Augmentation. + + } + > + + + + + + If your save file is extremely big you can use this button to view a map of all the files on every + server. Be careful there might be spoilers. + + } + > + + + + + + Changelog + + + Documentation + + + Changelog + + + Discord + + + Reddit + + +
+
+ setDiagnosticOpen(false)}> + + +
+ ); } diff --git a/src/ui/React/Modal.tsx b/src/ui/React/Modal.tsx new file mode 100644 index 000000000..9b3d077cf --- /dev/null +++ b/src/ui/React/Modal.tsx @@ -0,0 +1,47 @@ +import React from "react"; +import { makeStyles, createStyles, Theme } from "@material-ui/core"; +import M from "@material-ui/core/Modal"; +import Backdrop from "@material-ui/core/Backdrop"; +import Fade from "@material-ui/core/Fade"; + +const useStyles = makeStyles((theme: Theme) => + createStyles({ + modal: { + display: "flex", + alignItems: "center", + justifyContent: "center", + }, + paper: { + backgroundColor: theme.palette.background.paper, + border: "2px solid " + theme.palette.primary.main, + boxShadow: theme.shadows[5], + padding: theme.spacing(2, 4, 3), + }, + }), +); + +interface IProps { + open: boolean; + close: () => void; + children: JSX.Element[] | JSX.Element; +} + +export const Modal = (props: IProps): React.ReactElement => { + const classes = useStyles(); + return ( + + +
{props.children}
+
+
+ ); +}; diff --git a/src/ui/React/Theme.tsx b/src/ui/React/Theme.tsx index 65100af9d..221ddf6e0 100644 --- a/src/ui/React/Theme.tsx +++ b/src/ui/React/Theme.tsx @@ -14,6 +14,7 @@ export const colors = { secondary: "#888", secondarydark: "#666", + welllight: "#444", well: "#222", white: "#fff", black: "#000", @@ -36,6 +37,9 @@ export const theme = createMuiTheme({ main: colors.error, dark: colors.errordark, }, + background: { + paper: colors.well, + }, }, typography: { fontFamily: "monospace", @@ -150,12 +154,25 @@ export const theme = createMuiTheme({ backgroundColor: colors.black, }, paperAnchorDockedLeft: { - borderRight: "1px solid #444", + borderRight: "1px solid " + colors.welllight, }, }, MuiDivider: { root: { - backgroundColor: "#444", + backgroundColor: colors.welllight, + }, + }, + MuiFormControlLabel: { + root: { + color: colors.primary, + }, + }, + MuiSwitch: { + switchBase: { + color: colors.primarydark, + }, + track: { + backgroundColor: colors.welllight, }, }, }, diff --git a/src/ui/navigationTracking.ts b/src/ui/navigationTracking.ts index 2e4abd51f..274d60af2 100644 --- a/src/ui/navigationTracking.ts +++ b/src/ui/navigationTracking.ts @@ -122,6 +122,11 @@ export enum Page { * Purchase Resleeves */ Resleeves = "Re-sleeving", + + /** + * Game options + */ + GameOptions = "GameOptions", } /**