diff --git a/markdown/bitburner.ns.getgrowtime.md b/markdown/bitburner.ns.getgrowtime.md index b62e13fb4..5637cf820 100644 --- a/markdown/bitburner.ns.getgrowtime.md +++ b/markdown/bitburner.ns.getgrowtime.md @@ -28,5 +28,5 @@ Returns the amount of time in milliseconds it takes to execute the grow Netscrip RAM cost: 0.05 GB -Returns the amount of time in milliseconds it takes to execute the grow Netscript function on the target server. The function takes in an optional hackLvl parameter that can be specified to see what the grow time would be at different hacking levels. +Returns the amount of time in milliseconds it takes to execute the grow Netscript function on the target server. diff --git a/markdown/bitburner.ns.gethacktime.md b/markdown/bitburner.ns.gethacktime.md index f0b518f7d..34d6450f3 100644 --- a/markdown/bitburner.ns.gethacktime.md +++ b/markdown/bitburner.ns.gethacktime.md @@ -28,5 +28,5 @@ Returns the amount of time in milliseconds it takes to execute the hack Netscrip RAM cost: 0.05 GB -Returns the amount of time in milliseconds it takes to execute the hack Netscript function on the target server. The function takes in an optional hackLvl parameter that can be specified to see what the hack time would be at different hacking levels. +Returns the amount of time in milliseconds it takes to execute the hack Netscript function on the target server. diff --git a/markdown/bitburner.ns.getweakentime.md b/markdown/bitburner.ns.getweakentime.md index 8b0d8d911..06b69cb95 100644 --- a/markdown/bitburner.ns.getweakentime.md +++ b/markdown/bitburner.ns.getweakentime.md @@ -28,5 +28,5 @@ Returns the amount of time in milliseconds it takes to execute the grow Netscrip RAM cost: 0.05 GB -Returns the amount of time in milliseconds it takes to execute the weaken() Netscript function on the target server. The function takes in an optional hackLvl parameter that can be specified to see what the weaken time would be at different hacking levels. +Returns the amount of time in milliseconds it takes to execute the weaken() Netscript function on the target server. diff --git a/src/BitNode/BitNode.tsx b/src/BitNode/BitNode.tsx index 48e2aa97f..c59a339de 100644 --- a/src/BitNode/BitNode.tsx +++ b/src/BitNode/BitNode.tsx @@ -745,7 +745,7 @@ export function initBitNodeMultipliers(p: IPlayer): void { BitNodeMultipliers.StaneksGiftPowerMultiplier = 0.5; BitNodeMultipliers.StaneksGiftExtraSize = 2; BitNodeMultipliers.GangSoftcap = 0.8; - BitNodeMultipliers.CorporationSoftCap = 0.9; + BitNodeMultipliers.CorporationSoftCap = 0.7; BitNodeMultipliers.WorldDaemonDifficulty = 2; break; case 10: // Digital Carbon diff --git a/src/NetscriptFunctions.ts b/src/NetscriptFunctions.ts index cae6f3dc4..e23dd6ff1 100644 --- a/src/NetscriptFunctions.ts +++ b/src/NetscriptFunctions.ts @@ -64,7 +64,7 @@ import { NetscriptSleeve } from "./NetscriptFunctions/Sleeve"; import { NetscriptExtra } from "./NetscriptFunctions/Extra"; import { NetscriptHacknet } from "./NetscriptFunctions/Hacknet"; import { NetscriptStanek } from "./NetscriptFunctions/Stanek"; -import { NetscriptUserInterface } from './NetscriptFunctions/UserInterface'; +import { NetscriptUserInterface } from "./NetscriptFunctions/UserInterface"; import { NetscriptBladeburner } from "./NetscriptFunctions/Bladeburner"; import { NetscriptCodingContract } from "./NetscriptFunctions/CodingContract"; import { NetscriptCorporation } from "./NetscriptFunctions/Corporation"; @@ -2317,10 +2317,12 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS { ...base, ...extra, }; - function getFunctionNames(obj: NS, prefix: string): string[] { + function getFunctionNames(obj: any, prefix: string): string[] { const functionNames: string[] = []; for (const [key, value] of Object.entries(obj)) { - if (typeof value == "function") { + if (key === "args") { + continue; + } else if (typeof value == "function") { functionNames.push(prefix + key); } else if (typeof value == "object") { functionNames.push(...getFunctionNames(value, key + ".")); diff --git a/src/PersonObjects/formulas/skill.ts b/src/PersonObjects/formulas/skill.ts index 2aa52bff4..c320cc526 100644 --- a/src/PersonObjects/formulas/skill.ts +++ b/src/PersonObjects/formulas/skill.ts @@ -17,6 +17,17 @@ export function calculateSkillProgress(exp: number, mult = 1): ISkillProgress { if (nextExperience < 0) nextExperience = 0; const normalize = (value: number): number => ((value - baseExperience) * 100) / (nextExperience - baseExperience); + let progress = (nextExperience - baseExperience !== 0) ? normalize(exp) : 99.99; + + // Clamp progress: When sleeves are working out, the player gets way too much progress + if (progress < 0) progress = 0 + if (progress > 100) progress = 100; + + // Clamp floating point imprecisions + let currentExperience = exp - baseExperience; + let remainingExperience = nextExperience - exp; + if (currentExperience < 0) currentExperience = 0; + if (remainingExperience < 0) remainingExperience = 0; return { currentSkill, @@ -24,7 +35,9 @@ export function calculateSkillProgress(exp: number, mult = 1): ISkillProgress { baseExperience, experience: exp, nextExperience, - progress: (nextExperience - baseExperience !== 0) ? normalize(exp) : 99.99 + currentExperience, + remainingExperience, + progress } } @@ -34,6 +47,8 @@ export interface ISkillProgress { baseExperience: number; experience: number; nextExperience: number; + currentExperience: number; + remainingExperience: number; progress: number; } @@ -41,6 +56,7 @@ export function getEmptySkillProgress(): ISkillProgress { return { currentSkill: 0, nextSkill: 0, baseExperience: 0, experience: 0, nextExperience: 0, + currentExperience: 0, remainingExperience: 0, progress: 0, }; } diff --git a/src/Script/RamCalculations.ts b/src/Script/RamCalculations.ts index bf0bfe855..05920baf9 100644 --- a/src/Script/RamCalculations.ts +++ b/src/Script/RamCalculations.ts @@ -109,7 +109,6 @@ async function parseOnlyRamCalculate( for (const s of otherScripts) { if (areImportsEquals(s.filename, fn)) { script = s; - console.log(`${s.filename} ${fn}`); break; } } diff --git a/src/ScriptEditor/NetscriptDefinitions.d.ts b/src/ScriptEditor/NetscriptDefinitions.d.ts index 1e46e57c8..01a405a47 100644 --- a/src/ScriptEditor/NetscriptDefinitions.d.ts +++ b/src/ScriptEditor/NetscriptDefinitions.d.ts @@ -2890,7 +2890,7 @@ export interface Bladeburner { } /** - * Coding Contact API + * Coding Contract API * @public */ export interface CodingContract { @@ -5487,8 +5487,6 @@ export interface NS extends Singularity { * The required time is increased by the security level of the target server and decreased by the player's hacking level. * * @param host - Host of target server. - * @param hackLvl - Optional hacking level for the calculation. Defaults to player’s current hacking level. - * @param intLvl - Optional intelligence level for the calculation. Defaults to player’s current intelligence level. (Intelligence is unlocked after obtaining Source-File 5). * @returns Returns the amount of time in milliseconds it takes to execute the hack Netscript function. Returns Infinity if called on a Hacknet Server. */ getHackTime(host: string): number; @@ -5503,8 +5501,6 @@ export interface NS extends Singularity { * The required time is increased by the security level of the target server and decreased by the player's hacking level. * * @param host - Host of target server. - * @param hackLvl - Optional hacking level for the calculation. Defaults to player’s current hacking level. - * @param intLvl - Optional intelligence level for the calculation. Defaults to player’s current intelligence level. (Intelligence is unlocked after obtaining Source-File 5). * @returns Returns the amount of time in milliseconds it takes to execute the grow Netscript function. Returns Infinity if called on a Hacknet Server. */ getGrowTime(host: string): number; @@ -5519,8 +5515,6 @@ export interface NS extends Singularity { * The required time is increased by the security level of the target server and decreased by the player's hacking level. * * @param host - Host of target server. - * @param hackLvl - Optional hacking level for the calculation. Defaults to player’s current hacking level. - * @param intLvl - Optional intelligence level for the calculation. Defaults to player’s current intelligence level. (Intelligence is unlocked after obtaining Source-File 5). * @returns Returns the amount of time in milliseconds it takes to execute the grow Netscript function. Returns Infinity if called on a Hacknet Server. */ getWeakenTime(host: string): number; diff --git a/src/ScriptEditor/ui/ScriptEditorRoot.tsx b/src/ScriptEditor/ui/ScriptEditorRoot.tsx index 1d4653dd4..b2cc86304 100644 --- a/src/ScriptEditor/ui/ScriptEditorRoot.tsx +++ b/src/ScriptEditor/ui/ScriptEditorRoot.tsx @@ -93,26 +93,21 @@ class OpenScript { } } +let openScripts: OpenScript[] = []; +let currentScript: OpenScript | null = null; + // Called every time script editor is opened export function Root(props: IProps): React.ReactElement { + const setRerender = useState(false)[1]; + function rerender(): void { + setRerender((o) => !o); + } const editorRef = useRef(null); const monacoRef = useRef(null); const vimStatusRef = useRef(null); const [vimEditor, setVimEditor] = useState(null); const [editor, setEditor] = useState(null); - const [openScripts, setOpenScripts] = useState( - window.localStorage.getItem("scriptEditorOpenScripts") !== null - ? JSON.parse(window.localStorage.getItem("scriptEditorOpenScripts")!) - : [], - ); - - const [currentScript, setCurrentScript] = useState( - window.localStorage.getItem("scriptEditorCurrentScript") !== null - ? JSON.parse(window.localStorage.getItem("scriptEditorCurrentScript")!) - : null, - ); - const [ram, setRAM] = useState("RAM: ???"); const [updatingRam, setUpdatingRam] = useState(false); const [decorations, setDecorations] = useState([]); @@ -144,26 +139,6 @@ export function Root(props: IProps): React.ReactElement { }; }, []); - useEffect(() => { - // Save currentScript - window.localStorage.setItem( - "scriptEditorCurrentScript", - JSON.stringify(currentScript, (key, value) => { - if (key == "model") return undefined; - return value; - }), - ); - - // Save openScripts - window.localStorage.setItem( - "scriptEditorOpenScripts", - JSON.stringify(openScripts, (key, value) => { - if (key == "model") return undefined; - return value; - }), - ); - }, [currentScript, openScripts]); - useEffect(() => { if (currentScript !== null) { updateRAM(currentScript.code); @@ -171,23 +146,23 @@ export function Root(props: IProps): React.ReactElement { }, []); useEffect(() => { - function maybeSave(event: KeyboardEvent): void { + function keydown(event: KeyboardEvent): void { if (Settings.DisableHotkeys) return; //Ctrl + b - if (event.keyCode == 66 && (event.ctrlKey || event.metaKey)) { + if (event.code == "KeyB" && (event.ctrlKey || event.metaKey)) { event.preventDefault(); - save(); + props.router.toTerminal(); } // CTRL/CMD + S - if (event.code == `KeyS` && (event.ctrlKey || event.metaKey)) { + if (event.code == "KeyS" && (event.ctrlKey || event.metaKey)) { event.preventDefault(); event.stopPropagation(); save(); } } - document.addEventListener("keydown", maybeSave); - return () => document.removeEventListener("keydown", maybeSave); + document.addEventListener("keydown", keydown); + return () => document.removeEventListener("keydown", keydown); }); useEffect(() => { @@ -362,7 +337,7 @@ export function Root(props: IProps): React.ReactElement { regenerateModel(openScript); } - setCurrentScript(openScript); + currentScript = openScript; editorRef.current.setModel(openScript.model); editorRef.current.setPosition(openScript.lastPosition); editorRef.current.revealLineInCenter(openScript.lastPosition.lineNumber); @@ -376,14 +351,12 @@ export function Root(props: IProps): React.ReactElement { new monacoRef.current.Position(0, 0), monacoRef.current.editor.createModel(code, filename.endsWith(".txt") ? "plaintext" : "javascript"), ); - setOpenScripts((oldArray) => [...oldArray, newScript]); - setCurrentScript({ ...newScript }); + openScripts.push(newScript); + currentScript = { ...newScript }; editorRef.current.setModel(newScript.model); updateRAM(newScript.code); } } - } else { - console.log("here we need to load something if we can"); } editorRef.current.focus(); @@ -422,24 +395,26 @@ export function Root(props: IProps): React.ReactElement { function updateCode(newCode?: string): void { if (newCode === undefined) return; updateRAM(newCode); - if (editorRef.current !== null) { - const newPos = editorRef.current.getPosition(); - if (newPos === null) return; - setCurrentScript((oldScript) => ({ ...oldScript!, code: newCode, lastPosition: newPos! })); - if (currentScript !== null) { - const curIndex = openScripts.findIndex( - (script) => script.fileName === currentScript.fileName && script.hostname === currentScript.hostname, - ); - const newArr = [...openScripts]; - const tempScript = currentScript; - tempScript.code = newCode; - newArr[curIndex] = tempScript; - setOpenScripts([...newArr]); - } - try { - infLoop(newCode); - } catch (err) {} + if (editorRef.current === null) return; + const newPos = editorRef.current.getPosition(); + if (newPos === null) return; + if (currentScript !== null) { + currentScript = { ...currentScript, code: newCode, lastPosition: newPos }; + const curIndex = openScripts.findIndex( + (script) => + currentScript !== null && + script.fileName === currentScript.fileName && + script.hostname === currentScript.hostname, + ); + const newArr = [...openScripts]; + const tempScript = currentScript; + tempScript.code = newCode; + newArr[curIndex] = tempScript; + openScripts = [...newArr]; } + try { + infLoop(newCode); + } catch (err) {} } function saveScript(scriptToSave: OpenScript): void { @@ -487,7 +462,7 @@ export function Root(props: IProps): React.ReactElement { function save(): void { if (currentScript === null) { - console.log("currentScript is null when it shouldn't be. Unabel to save script"); + console.error("currentScript is null when it shouldn't be. Unable to save script"); return; } // this is duplicate code with saving later. @@ -507,7 +482,6 @@ export function Root(props: IProps): React.ReactElement { iTutorialNextStep(); - props.router.toTerminal(); return; } @@ -536,7 +510,6 @@ export function Root(props: IProps): React.ReactElement { server.scripts, ); if (Settings.SaveGameOnFileSave) saveObject.saveGame(); - props.router.toTerminal(); return; } } @@ -550,7 +523,6 @@ export function Root(props: IProps): React.ReactElement { if (server.textFiles[i].fn === currentScript.fileName) { server.textFiles[i].write(currentScript.code); if (Settings.SaveGameOnFileSave) saveObject.saveGame(); - props.router.toTerminal(); return; } } @@ -562,7 +534,6 @@ export function Root(props: IProps): React.ReactElement { } if (Settings.SaveGameOnFileSave) saveObject.saveGame(); - props.router.toTerminal(); } function reorder(list: Array, startIndex: number, endIndex: number): OpenScript[] { @@ -582,19 +553,22 @@ export function Root(props: IProps): React.ReactElement { const items = reorder(openScripts, result.source.index, result.destination.index); - setOpenScripts(items); + openScripts = items; } function onTabClick(index: number): void { if (currentScript !== null) { // Save currentScript to openScripts const curIndex = openScripts.findIndex( - (script) => script.fileName === currentScript.fileName && script.hostname === currentScript.hostname, + (script) => + currentScript !== null && + script.fileName === currentScript.fileName && + script.hostname === currentScript.hostname, ); openScripts[curIndex] = currentScript; } - setCurrentScript({ ...openScripts[index] }); + currentScript = { ...openScripts[index] }; if (editorRef.current !== null && openScripts[index] !== null) { if (openScripts[index].model === undefined || openScripts[index].model.isDisposed()) { @@ -609,25 +583,21 @@ export function Root(props: IProps): React.ReactElement { } } - async function onTabClose(index: number): Promise { + function onTabClose(index: number): void { // See if the script on the server is up to date const closingScript = openScripts[index]; - const savedOpenScripts: Array = JSON.parse(window.localStorage.getItem("scriptEditorOpenScripts")!); - const savedScriptIndex = savedOpenScripts.findIndex( + const savedScriptIndex = openScripts.findIndex( (script) => script.fileName === closingScript.fileName && script.hostname === closingScript.hostname, ); let savedScriptCode = ""; if (savedScriptIndex !== -1) { - savedScriptCode = savedOpenScripts[savedScriptIndex].code; + savedScriptCode = openScripts[savedScriptIndex].code; } + const server = GetServer(closingScript.hostname); + if (server === null) throw new Error(`Server '${closingScript.hostname}' should not be null, but it is.`); - const serverScriptIndex = GetServer(closingScript.hostname)?.scripts.findIndex( - (script) => script.filename === closingScript.fileName, - ); - if ( - serverScriptIndex === -1 || - savedScriptCode !== GetServer(closingScript.hostname)?.scripts[serverScriptIndex as number].code - ) { + const serverScriptIndex = server.scripts.findIndex((script) => script.filename === closingScript.fileName); + if (serverScriptIndex === -1 || savedScriptCode !== server.scripts[serverScriptIndex as number].code) { PromptEvent.emit({ txt: "Do you want to save changes to " + closingScript.fileName + "?", resolve: (result: boolean) => { @@ -641,15 +611,18 @@ export function Root(props: IProps): React.ReactElement { } if (openScripts.length > 1) { - setOpenScripts((oldScripts) => oldScripts.filter((value, i) => i !== index)); + openScripts = openScripts.filter((value, i) => i !== index); let indexOffset = -1; if (openScripts[index + indexOffset] === undefined) { indexOffset = 1; + if (openScripts[index + indexOffset] === undefined) { + indexOffset = 0; + } } // Change current script if we closed it - setCurrentScript(openScripts[index + indexOffset]); + currentScript = openScripts[index + indexOffset]; if (editorRef.current !== null) { if ( openScripts[index + indexOffset].model === undefined || @@ -664,14 +637,26 @@ export function Root(props: IProps): React.ReactElement { editorRef.current.revealLineInCenter(openScripts[index + indexOffset].lastPosition.lineNumber); editorRef.current.focus(); } + rerender(); } else { // No more scripts are open - setOpenScripts([]); - setCurrentScript(null); + openScripts = []; + currentScript = null; props.router.toTerminal(); } } + function dirty(index: number): string { + const openScript = openScripts[index]; + const server = GetServer(openScript.hostname); + if (server === null) throw new Error(`Server '${openScript.hostname}' should not be null, but it is.`); + + const serverScript = server.scripts.find((s) => s.filename === openScript.fileName); + if (serverScript === undefined) return " *"; + + return serverScript.code !== openScript.code ? " *" : ""; + } + // Toolbars are roughly 112px: // 8px body margin top // 38.5px filename tabs @@ -718,7 +703,6 @@ export function Root(props: IProps): React.ReactElement { }} > + + {" "} Documentation:{" "} @@ -825,10 +809,14 @@ export function Root(props: IProps): React.ReactElement { alignItems: "center", }} > -

-

No open files

-
Use "nano [File Name]" in the terminal to open files
-

+ + No open files + + Use `nano FILENAME` in +
+ the terminal to open files +
+
); diff --git a/src/StockMarket/data/InitStockMetadata.ts b/src/StockMarket/data/InitStockMetadata.ts index 8bcef396f..53e5a5852 100644 --- a/src/StockMarket/data/InitStockMetadata.ts +++ b/src/StockMarket/data/InitStockMetadata.ts @@ -779,7 +779,7 @@ export const InitStockMetadata: IConstructorParams[] = [ max: 350, min: 200, }, - name: "Joes Guns", + name: LocationName.Sector12JoesGuns, otlkMag: 1, spreadPerc: { divisor: 10, @@ -790,7 +790,7 @@ export const InitStockMetadata: IConstructorParams[] = [ max: 52e3, min: 15e3, }, - symbol: StockSymbols["Joes Guns"], + symbol: StockSymbols[LocationName.Sector12JoesGuns], }, { diff --git a/src/Terminal/commands/mv.ts b/src/Terminal/commands/mv.ts index 449f92cc8..9276f4bdb 100644 --- a/src/Terminal/commands/mv.ts +++ b/src/Terminal/commands/mv.ts @@ -53,7 +53,7 @@ export function mv( // Also, you can't convert between different file types if (isScriptFilename(source)) { const script = srcFile as Script; - if (!isScriptFilename(dest)) { + if (!isScriptFilename(destPath)) { terminal.error(`Source and destination files must have the same type`); return; } @@ -66,7 +66,7 @@ export function mv( if (destFile != null) { // Already exists, will be overwritten, so we'll delete it - const status = server.removeFile(dest); + const status = server.removeFile(destPath); if (!status.res) { terminal.error(`Something went wrong...please contact game dev (probably a bug)`); return; diff --git a/src/ui/React/StatsProgressBar.tsx b/src/ui/React/StatsProgressBar.tsx index 085d5afca..1e583a7d5 100644 --- a/src/ui/React/StatsProgressBar.tsx +++ b/src/ui/React/StatsProgressBar.tsx @@ -9,6 +9,7 @@ interface IProgressProps { min: number; max: number; current: number; + remaining: number; progress: number; color?: React.CSSProperties["color"]; } @@ -18,14 +19,14 @@ interface IStatsOverviewCellProps { color?: React.CSSProperties["color"]; } -export function StatsProgressBar({ min, max, current, progress, color }: IProgressProps): React.ReactElement { +export function StatsProgressBar({ min, max, current, remaining, progress, color }: IProgressProps): React.ReactElement { const tooltip = ( Progress:  - {numeralWrapper.formatExp(current - min)} / {numeralWrapper.formatExp(max - min)} + {numeralWrapper.formatExp(current)} / {numeralWrapper.formatExp(max - min)}
Remaining:  - {numeralWrapper.formatExp(max - current)} ({progress.toFixed(2)}%) + {numeralWrapper.formatExp(remaining)} ({progress.toFixed(2)}%)
); @@ -58,7 +59,8 @@ export function StatsProgressOverviewCell({ progress: skill, color }: IStatsOver