Merge pull request #2006 from danielyxie/dev

Confirmation on augmentation
This commit is contained in:
hydroflame 2021-12-19 00:24:07 -05:00 committed by GitHub
commit bd7af955ee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 98 additions and 44 deletions

26
dist/vendor.bundle.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -16,6 +16,8 @@ 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 { Settings } from "../../Settings/Settings";
import { ConfirmationModal } from "../../ui/React/ConfirmationModal";
interface IProps {
exportGameFn: () => void;
@ -23,6 +25,7 @@ interface IProps {
}
export function AugmentationsRoot(props: IProps): React.ReactElement {
const [installOpen, setInstallOpen] = useState(false);
const player = use.Player();
const setRerender = useState(false)[1];
function rerender(): void {
@ -43,6 +46,14 @@ export function AugmentationsRoot(props: IProps): React.ReactElement {
return "";
}
function doInstall(): void {
if (!Settings.SuppressBuyAugmentationConfirmation) {
setInstallOpen(true);
} else {
props.installAugmentationsFn();
}
}
return (
<>
<Typography variant="h4">Augmentations</Typography>
@ -73,11 +84,36 @@ export function AugmentationsRoot(props: IProps): React.ReactElement {
<Box mx={2}>
<Tooltip title={<Typography>'I never asked for this'</Typography>}>
<span>
<Button disabled={player.queuedAugmentations.length === 0} onClick={props.installAugmentationsFn}>
<Button disabled={player.queuedAugmentations.length === 0} onClick={doInstall}>
Install Augmentations
</Button>
</span>
</Tooltip>
<ConfirmationModal
open={installOpen}
onClose={() => setInstallOpen(false)}
onConfirm={props.installAugmentationsFn}
confirmationText={
<>
Installing will reset
<br />
<br />- money
<br />- skill / experience
<br />- every server except home
<br />- factions and reputation
<br />
<br />
You will keep:
<br />
<br />- All scripts on home
<br />- home ram and cores
<br />
<br />
It is recommended to install several Augmentations at once. Preferably everything from any faction of your
chosing.
</>
}
/>
<Tooltip title={<Typography>It's always a good idea to backup/export your save!</Typography>}>
<Button sx={{ mx: 2 }} onClick={doExport} color="error">
Backup Save {exportBonusStr()}

@ -24,9 +24,9 @@ function timeCompression(): void {
return;
}
last = now;
window.setTimeout(minute, 1000);
window.setTimeout(minute, 1000 * 60);
}
window.setTimeout(minute, 1000);
window.setTimeout(minute, 1000 * 60);
}
export function startExploits(): void {

@ -304,7 +304,10 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
const checkSingularityAccess = function (func: any, n: any): void {
if (Player.bitNodeN !== 4) {
if (SourceFileFlags[4] < n) {
throw makeRuntimeErrorMsg(func, `This singularity function requires Source-File 4-${n} to run.`);
throw makeRuntimeErrorMsg(
func,
`This singularity function requires Source-File 4-${n} to run. A power up you obtain later in the game. It will be very obvious when and how you can obtain it.`,
);
}
}
};
@ -1611,7 +1614,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
const cost = getPurchaseServerCost(ram);
if (cost === Infinity) {
workerScript.log("purchaseServer", () => `Invalid argument: ram='${ram}'`);
workerScript.log("purchaseServer", () => `Invalid argument: ram='${ram}' must be power of 2`);
return "";
}

@ -1,3 +1,5 @@
export const validScriptExtensions: Array<string> = [`.js`, `.script`, `.ns`];
export function isScriptFilename(f: string): boolean {
return f.endsWith(".js") || f.endsWith(".script") || f.endsWith(".ns");
return validScriptExtensions.some((ext) => f.endsWith(ext));
}

@ -3,7 +3,7 @@ import { IRouter } from "../../ui/Router";
import { IPlayer } from "../../PersonObjects/IPlayer";
import { BaseServer } from "../../Server/BaseServer";
import { findRunningScript } from "../../Script/ScriptHelpers";
import { isScriptFilename } from "../../Script/isScriptFilename";
import { isScriptFilename, validScriptExtensions } from "../../Script/isScriptFilename";
export function check(
terminal: ITerminal,
@ -13,19 +13,21 @@ export function check(
args: (string | number | boolean)[],
): void {
if (args.length < 1) {
terminal.error("Incorrect number of arguments. Usage: check [script] [arg1] [arg2]...");
terminal.error(`Incorrect number of arguments. Usage: check [script] [arg1] [arg2]...`);
} else {
const scriptName = terminal.getFilepath(args[0] + "");
// Can only tail script files
if (!isScriptFilename(scriptName)) {
terminal.error("tail can only be called on .script files (filename must end with .script)");
terminal.error(
`'check' can only be called on scripts files (filename must end with ${validScriptExtensions.join(", ")})`,
);
return;
}
// Check that the script exists on this machine
// Check that the script is running on this machine
const runningScript = findRunningScript(scriptName, args.slice(1), server);
if (runningScript == null) {
terminal.error("No such script exists");
terminal.error(`No script named ${scriptName} is running on the server`);
return;
}
runningScript.displayLog();

@ -27,7 +27,7 @@ export function kill(
if (res) {
terminal.print(`Killing script with PID ${pid}`);
} else {
terminal.error(`Failed to kill script with PID ${pid}. No such script exists`);
terminal.error(`Failed to kill script with PID ${pid}. No such script is running`);
}
return;

@ -29,7 +29,7 @@ export function mem(
const script = terminal.getScript(player, scriptName);
if (script == null) {
terminal.error("No such script exists!");
terminal.error("mem failed. No such script exists!");
return;
}

@ -33,7 +33,7 @@ export function runProgram(
}
for (const program of Object.values(Programs)) {
if (program.name === programName) {
if (program.name.toLocaleLowerCase() === programName.toLocaleLowerCase()) {
program.run(
router,
terminal,

@ -90,7 +90,7 @@ export function scp(
}
}
if (sourceScript == null) {
terminal.error("scp() failed. No such script exists");
terminal.error("scp failed. No such script exists");
return;
}

@ -3,7 +3,7 @@ import { IRouter } from "../../ui/Router";
import { IPlayer } from "../../PersonObjects/IPlayer";
import { BaseServer } from "../../Server/BaseServer";
import { findRunningScriptByPid } from "../../Script/ScriptHelpers";
import { isScriptFilename } from "../../Script/isScriptFilename";
import { isScriptFilename, validScriptExtensions } from "../../Script/isScriptFilename";
import { compareArrays } from "../../utils/helpers/compareArrays";
import { LogBoxEvents } from "../../ui/React/LogBoxManager";
@ -20,7 +20,7 @@ export function tail(
} else if (typeof commandArray[0] === "string") {
const scriptName = terminal.getFilepath(commandArray[0]);
if (!isScriptFilename(scriptName)) {
terminal.error("tail can only be called on .script, .ns, .js files, or by pid");
terminal.error(`tail can only be called on ${validScriptExtensions.join(", ")} files, or by PID`);
return;
}
@ -66,11 +66,11 @@ export function tail(
}
// if there's no candidate then we just don't know.
terminal.error("No such script exists.");
terminal.error(`No script named ${scriptName} is running on the server`);
} else if (typeof commandArray[0] === "number") {
const runningScript = findRunningScriptByPid(commandArray[0], server);
if (runningScript == null) {
terminal.error("No such script exists");
terminal.error(`No script with PID ${commandArray[0]} is running on the server`);
return;
}
LogBoxEvents.emit(runningScript);

@ -8,7 +8,7 @@ interface IProps {
open: boolean;
onClose: () => void;
onConfirm: () => void;
confirmationText: string;
confirmationText: string | React.ReactNode;
}
export function ConfirmationModal(props: IProps): React.ReactElement {

@ -83,6 +83,7 @@ export function GameOptionsRoot(props: IProps): React.ReactElement {
const [diagnosticOpen, setDiagnosticOpen] = useState(false);
const [deleteGameOpen, setDeleteOpen] = useState(false);
const [themeEditorOpen, setThemeEditorOpen] = useState(false);
const [softResetOpen, setSoftResetOpen] = useState(false);
function handleExecTimeChange(event: any, newValue: number | number[]): void {
setExecTime(newValue as number);
@ -210,6 +211,14 @@ export function GameOptionsRoot(props: IProps): React.ReactElement {
reader.readAsText(file);
}
function doSoftReset(): void {
if (!Settings.SuppressBuyAugmentationConfirmation) {
setSoftResetOpen(true);
} else {
props.softReset();
}
}
return (
<div className={classes.root} style={{ width: "90%" }}>
<Typography variant="h4" gutterBottom>
@ -388,7 +397,7 @@ export function GameOptionsRoot(props: IProps): React.ReactElement {
</Typography>
}
>
<Typography>Suppress buy augmentation confirmation</Typography>
<Typography>Suppress augmentations confirmation</Typography>
</Tooltip>
}
/>
@ -428,15 +437,11 @@ export function GameOptionsRoot(props: IProps): React.ReactElement {
)}
<ListItem>
<FormControlLabel
control={
<Switch checked={suppressSavedGameToast} onChange={handleSuppressSavedGameToastChange} />
}
control={<Switch checked={suppressSavedGameToast} onChange={handleSuppressSavedGameToastChange} />}
label={
<Tooltip
title={
<Typography>
If this is set, there will be no "Saved Game" toast appearing after save.
</Typography>
<Typography>If this is set, there will be no "Saved Game" toast appearing after save.</Typography>
}
>
<Typography>Suppress Saved Game Toast</Typography>
@ -650,8 +655,14 @@ export function GameOptionsRoot(props: IProps): React.ReactElement {
</Typography>
}
>
<Button onClick={() => props.softReset()}>Soft Reset</Button>
<Button onClick={doSoftReset}>Soft Reset</Button>
</Tooltip>
<ConfirmationModal
open={softResetOpen}
onClose={() => setSoftResetOpen(false)}
onConfirm={props.softReset}
confirmationText={"This will perform the same action as installing Augmentations, are you sure?"}
/>
</Box>
<Box>
<Tooltip