diff --git a/src/Constants.ts b/src/Constants.ts index c806327d2..b184abd0d 100644 --- a/src/Constants.ts +++ b/src/Constants.ts @@ -293,6 +293,7 @@ export const CONSTANTS: { ** Misc. ** + * scripts logs are colorized. * documentation for scp not say string | string[] * nerf noodle bar `, diff --git a/src/NetscriptFunctions.ts b/src/NetscriptFunctions.ts index 9666b0535..8ec07fc82 100644 --- a/src/NetscriptFunctions.ts +++ b/src/NetscriptFunctions.ts @@ -670,10 +670,45 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS { if (args.length === 0) { throw makeRuntimeErrorMsg("tprint", "Takes at least 1 argument."); } - Terminal.print(`${workerScript.scriptRef.filename}: ${argsToString(args)}`); + const str = argsToString(args); + if (str.startsWith("ERROR") || str.startsWith("FAIL")) { + Terminal.error(`${workerScript.scriptRef.filename}: ${str}`); + return; + } + if (str.startsWith("SUCCESS")) { + Terminal.success(`${workerScript.scriptRef.filename}: ${str}`); + return; + } + if (str.startsWith("WARN")) { + Terminal.warn(`${workerScript.scriptRef.filename}: ${str}`); + return; + } + if (str.startsWith("INFO")) { + Terminal.info(`${workerScript.scriptRef.filename}: ${str}`); + return; + } + Terminal.print(`${workerScript.scriptRef.filename}: ${str}`); }, tprintf: function (format: any, ...args: any): any { - Terminal.print(vsprintf(format, args)); + const str = vsprintf(format, args); + + if (str.startsWith("ERROR") || str.startsWith("FAIL")) { + Terminal.error(`${workerScript.scriptRef.filename}: ${str}`); + return; + } + if (str.startsWith("SUCCESS")) { + Terminal.success(`${workerScript.scriptRef.filename}: ${str}`); + return; + } + if (str.startsWith("WARN")) { + Terminal.warn(`${workerScript.scriptRef.filename}: ${str}`); + return; + } + if (str.startsWith("INFO")) { + Terminal.info(`${workerScript.scriptRef.filename}: ${str}`); + return; + } + Terminal.print(`${workerScript.scriptRef.filename}: ${str}`); }, clearLog: function (): any { workerScript.scriptRef.clearLog(); diff --git a/src/PersonObjects/Player/PlayerObjectGeneralMethods.tsx b/src/PersonObjects/Player/PlayerObjectGeneralMethods.tsx index 14fe4a749..e6698dde0 100644 --- a/src/PersonObjects/Player/PlayerObjectGeneralMethods.tsx +++ b/src/PersonObjects/Player/PlayerObjectGeneralMethods.tsx @@ -872,7 +872,6 @@ export function startFactionFieldWork(this: IPlayer, router: IRouter, faction: F this.workAgiExpGainRate = 0.1 * this.agility_exp_mult * BitNodeMultipliers.FactionWorkExpGain; this.workChaExpGainRate = 0.1 * this.charisma_exp_mult * BitNodeMultipliers.FactionWorkExpGain; this.workRepGainRate = getFactionFieldWorkRepGain(this, faction); - console.log(this.workRepGainRate); this.factionWorkType = CONSTANTS.FactionWorkField; this.currentWorkFactionDescription = "carrying out field missions"; @@ -907,7 +906,6 @@ export function workForFaction(this: IPlayer, numCycles: number): boolean { break; case CONSTANTS.FactionWorkField: this.workRepGainRate = getFactionFieldWorkRepGain(this, faction); - console.log(this.workRepGainRate); break; case CONSTANTS.FactionWorkSecurity: this.workRepGainRate = getFactionSecurityWorkRepGain(this, faction); @@ -1484,7 +1482,7 @@ export function finishCrime(this: IPlayer, cancelled: boolean): string { if (this.committingCrimeThruSingFn && ws !== null) { if (ws.disableLogs.ALL == null && ws.disableLogs.commitCrime == null) { ws.scriptRef.log( - "Crime successful! Gained " + + "SUCCESS: Crime successful! Gained " + numeralWrapper.formatMoney(this.workMoneyGained) + ", " + numeralWrapper.formatExp(this.workHackExpGained) + @@ -1536,7 +1534,7 @@ export function finishCrime(this: IPlayer, cancelled: boolean): string { if (this.committingCrimeThruSingFn && ws !== null) { if (ws.disableLogs.ALL == null && ws.disableLogs.commitCrime == null) { ws.scriptRef.log( - "Crime failed! Gained " + + "FAIL: Crime failed! Gained " + numeralWrapper.formatExp(this.workHackExpGained) + " hack exp, " + numeralWrapper.formatExp(this.workStrExpGained) + diff --git a/src/Settings/Settings.ts b/src/Settings/Settings.ts index 93647e3ab..cf97a382e 100644 --- a/src/Settings/Settings.ts +++ b/src/Settings/Settings.ts @@ -106,6 +106,9 @@ interface IDefaultSettings { primarylight: string; primary: string; primarydark: string; + successlight: string; + success: string; + successdark: string; errorlight: string; error: string; errordark: string; @@ -182,6 +185,9 @@ export const defaultSettings: IDefaultSettings = { primarylight: "#0f0", primary: "#0c0", primarydark: "#090", + successlight: "#0f0", + success: "#0c0", + successdark: "#090", errorlight: "#f00", error: "#c00", errordark: "#900", @@ -246,6 +252,9 @@ export const Settings: ISettings & ISelfInitializer & ISelfLoading = { primarylight: defaultSettings.theme.primarylight, primary: defaultSettings.theme.primary, primarydark: defaultSettings.theme.primarydark, + successlight: defaultSettings.theme.successlight, + success: defaultSettings.theme.success, + successdark: defaultSettings.theme.successdark, errorlight: defaultSettings.theme.errorlight, error: defaultSettings.theme.error, errordark: defaultSettings.theme.errordark, diff --git a/src/Terminal/ITerminal.tsx b/src/Terminal/ITerminal.tsx index 574045ff3..840cbd65c 100644 --- a/src/Terminal/ITerminal.tsx +++ b/src/Terminal/ITerminal.tsx @@ -8,11 +8,8 @@ import { formatTime } from "../utils/helpers/formatTime"; export class Output { text: string; - color: "inherit" | "initial" | "primary" | "secondary" | "error" | "textPrimary" | "textSecondary" | undefined; - constructor( - text: string, - color: "inherit" | "initial" | "primary" | "secondary" | "error" | "textPrimary" | "textSecondary" | undefined, - ) { + color: "primary" | "error" | "success" | "info" | "warn"; + constructor(text: string, color: "primary" | "error" | "success" | "info" | "warn") { if (Settings.TimestampsFormat) text = "[" + formatTime(Settings.TimestampsFormat) + "] " + text; this.text = text; this.color = color; @@ -72,6 +69,9 @@ export interface ITerminal { print(s: string): void; printRaw(node: React.ReactNode): void; error(s: string): void; + success(s: string): void; + info(s: string): void; + warn(s: string): void; clear(): void; startAnalyze(): void; diff --git a/src/Terminal/Terminal.ts b/src/Terminal/Terminal.ts index bfdd1cc25..a14716b2c 100644 --- a/src/Terminal/Terminal.ts +++ b/src/Terminal/Terminal.ts @@ -113,6 +113,18 @@ export class Terminal implements ITerminal { this.append(new Output(s, "error")); } + success(s: string): void { + this.append(new Output(s, "success")); + } + + info(s: string): void { + this.append(new Output(s, "info")); + } + + warn(s: string): void { + this.append(new Output(s, "warn")); + } + startHack(player: IPlayer): void { // Hacking through Terminal should be faster than hacking through a script const server = player.getCurrentServer(); diff --git a/src/Terminal/ui/TerminalRoot.tsx b/src/Terminal/ui/TerminalRoot.tsx index 47ded43a7..487af7c7a 100644 --- a/src/Terminal/ui/TerminalRoot.tsx +++ b/src/Terminal/ui/TerminalRoot.tsx @@ -43,6 +43,37 @@ const useStyles = makeStyles((theme: Theme) => padding: theme.spacing(0), height: "100%", }, + + success: { + whiteSpace: "pre-wrap", + overflowWrap: "anywhere", + margin: theme.spacing(0), + color: theme.colors.success, + }, + error: { + whiteSpace: "pre-wrap", + overflowWrap: "anywhere", + margin: theme.spacing(0), + color: theme.palette.error.main, + }, + primary: { + whiteSpace: "pre-wrap", + overflowWrap: "anywhere", + margin: theme.spacing(0), + color: theme.palette.primary.main, + }, + info: { + whiteSpace: "pre-wrap", + overflowWrap: "anywhere", + margin: theme.spacing(0), + color: theme.palette.info.main, + }, + warning: { + whiteSpace: "pre-wrap", + overflowWrap: "anywhere", + margin: theme.spacing(0), + color: theme.palette.warning.main, + }, }), ); @@ -80,6 +111,23 @@ export function TerminalRoot({ terminal, router, player }: IProps): React.ReactE setTimeout(doScroll, 50); }, []); + function lineClass(s: string): string { + if (s === "error") { + return classes.error; + } + if (s === "success") { + return classes.success; + } + if (s === "info") { + return classes.info; + } + if (s === "warn") { + return classes.warning; + } + + return classes.primary; + } + const classes = useStyles(); return ( <> @@ -89,7 +137,7 @@ export function TerminalRoot({ terminal, router, player }: IProps): React.ReactE if (item instanceof Output) return ( - + {item.text} diff --git a/src/ui/React/LogBoxManager.tsx b/src/ui/React/LogBoxManager.tsx index c739084b6..7b7aa71c9 100644 --- a/src/ui/React/LogBoxManager.tsx +++ b/src/ui/React/LogBoxManager.tsx @@ -14,6 +14,7 @@ import ArrowForwardIosIcon from "@mui/icons-material/ArrowForwardIos"; import { workerScripts } from "../../Netscript/WorkerScripts"; import { startWorkerScript } from "../../NetscriptWorker"; import { GetServer } from "../../Server/AllServers"; +import { Theme } from "@mui/material"; let layerCounter = 0; @@ -65,7 +66,7 @@ interface IProps { onClose: () => void; } -const useStyles = makeStyles(() => +const useStyles = makeStyles((theme: Theme) => createStyles({ logs: { overflowY: "scroll", @@ -74,6 +75,21 @@ const useStyles = makeStyles(() => display: "flex", flexDirection: "column-reverse", }, + success: { + color: theme.colors.success, + }, + error: { + color: theme.palette.error.main, + }, + primary: { + color: theme.palette.primary.main, + }, + info: { + color: theme.palette.info.main, + }, + warning: { + color: theme.palette.warning.main, + }, }), ); @@ -117,6 +133,22 @@ function LogWindow(props: IProps): React.ReactElement { return t.slice(0, maxLength - 3) + "..."; } + function lineClass(s: string): string { + if (s.startsWith("ERROR") || s.startsWith("FAIL")) { + return classes.error; + } + if (s.startsWith("SUCCESS")) { + return classes.success; + } + if (s.startsWith("WARN")) { + return classes.warning; + } + if (s.startsWith("INFO")) { + return classes.info; + } + return classes.primary; + } + return ( {props.script.logs.map( (line: string, i: number): JSX.Element => ( - + {line}
diff --git a/src/ui/React/Theme.tsx b/src/ui/React/Theme.tsx index 0137fe63c..cbbb1bb37 100644 --- a/src/ui/React/Theme.tsx +++ b/src/ui/React/Theme.tsx @@ -18,6 +18,9 @@ declare module "@mui/material/styles" { backgroundprimary: React.CSSProperties["color"]; backgroundsecondary: React.CSSProperties["color"]; button: React.CSSProperties["color"]; + successlight: React.CSSProperties["color"]; + success: React.CSSProperties["color"]; + successdark: React.CSSProperties["color"]; }; } interface ThemeOptions { @@ -32,6 +35,9 @@ declare module "@mui/material/styles" { backgroundprimary: React.CSSProperties["color"]; backgroundsecondary: React.CSSProperties["color"]; button: React.CSSProperties["color"]; + successlight: React.CSSProperties["color"]; + success: React.CSSProperties["color"]; + successdark: React.CSSProperties["color"]; }; } } @@ -51,6 +57,9 @@ export function refreshTheme(): void { backgroundprimary: Settings.theme.backgroundprimary, backgroundsecondary: Settings.theme.backgroundsecondary, button: Settings.theme.button, + successlight: Settings.theme.successlight, + success: Settings.theme.success, + successdark: Settings.theme.successdark, }, palette: { primary: { diff --git a/src/ui/React/ThemeEditorModal.tsx b/src/ui/React/ThemeEditorModal.tsx index 4af6ca956..d4b847b54 100644 --- a/src/ui/React/ThemeEditorModal.tsx +++ b/src/ui/React/ThemeEditorModal.tsx @@ -132,6 +132,27 @@ export function ThemeEditorModal(props: IProps): React.ReactElement { defaultColor={defaultSettings.theme["primarydark"]} /> +
+ + + + +