This commit is contained in:
Olivier Gagnon 2021-12-18 16:26:50 -05:00
parent 853125009b
commit 02605090df
11 changed files with 399 additions and 201 deletions

136
dist/vendor.bundle.js vendored

File diff suppressed because one or more lines are too long

@ -3,8 +3,107 @@
Changelog Changelog
========= =========
v1.1.0 - 2021-12-18 You guys are awesome (community because they're god damn awesome)
-------------------------------------------------------------------------------------
** Script Editor **
* The text editor can open several files at once. (@Rez855 / @Shadow72)
It's not perfect so keep the feedback coming.
** Steam **
* Windows has a new launch option that lets player start with killing all their scripts
This is a safety net in case all the other safety nets fail.
* Linux has several launch options that use different flags for different OS.
* Debug and Fullscreen are available in the window utility bar.
* Tried (and maybe failed) to make the game completely kill itself after closing.
This one I still don't know wtf is going.
* No longer has background throttling.
* Default color should be pitch black when loading
* Add BN13: Challenge achievement.
** Tutorial **
* I watched someone play bitburner on youtube and reworked part of
the tutorial to try to make some parts of the game clearer.
https://www.youtube.com/watch?v=-_JETXff4Zo
* Add option to restart tutorial.
** Netscript **
* getGangInformation returns more information.
* getAscensionResult added
* getMemberInformation returns more info
* Formulas API has new functions for gang.
* Added documentation for corp API.
* exec has clearer error message when you send invalid data.
* getServer returns all defined field for hacknet servers.
* Fix a bug with scp multiple files (@theit8514)
* Stack traces should be smarter at replacing blobs with filenames
* Fix a weird error message that would occur when throwing raw strings.
* Fix shortcuts not working.
* Re-added setFocus and isFocused (@theit8514)
* new function getHashUpgrades (@MartinFournier)
* enableLog accepts "ALL" like disableLog (@wynro)
* toast() doesn't crash on invalid data (@ivanjermakov)
* alert() doesn't crash on invalid data (@Siern)
* Fixed an issue where scripts don't run where they should.
* Sleeve getInformation now returns cha
* getServer does work with no argument now
* workForFaction returns false when it mistakenly returned null
** Character Overview **
* The character overview now shows the amount of exp needed to next level (@MartinFournier)
** Misc. **
* Add option to supress Game Saved! toasts (@MartinFournier)
* Fix bug where ctrl+alt+j was eaten by the wrong process. (@billyvg)
* Theme Editor lets you paste colors (@MartinFournier)
* ctrl + u/k/w should work on terminal (@billyvg)
* Game now shows commit number, this is mostly for me. (@MartinFourier)
* running a bad script will give a clearer error message (@TheCoderJT)
* Default terminal capacity is maximum (@SayntGarmo)
* Fix problems with cp and mv (@theit8514)
* Make monaco load fully offline for players behind firewalls.
* change beginer guide to use n00dles instead of foodnstuff
* BN13 is harder
* nerf int gain from manualHack
* Fix UI displaying wrong stats (@DJMatch3000)
* Fix button not disabling as it should.
* New location in Ishima.
* Add setting to suppress stock market popups.
* Typo fixes (@Hedrauta, @cvr-119, @Ationi, @millennIumAMbiguity
@TealKoi, @TheCoderJT, @cblte, @2PacIsAlive, @MageKing17,
@Xynrati, @Adraxas, @pobiega)
* Fix 100% territory achievement.
* Reword message on active scripts page.
* Fix terminal not clearing after BN
* Remove references to .fconf
* Augmentation pages shows BN difficulty with SF5
* Fix scripts saving on wrong server while 'connect'ing
* Fix gym discount not working.
* Fix scan-analyze not working with timestamps
* Hash upgrades remember last choice.
* Save files now sort by date
* The covenant no longer supports negative memory purchases
* Fix corp shares buyback triggering by pressing enter
* Staneks gift display avg / num charges
* Infiltration rewards no longer decay with better stats
* terminal 'true' is parsed as boolean not string
* tail and kill use autocomplete()
* Fix focus for coding contract
* massive boost to noodle bar.
** Special Thanks **
* Special thank you to everyone on Discord who can answer
new player questions so I can focus on more important things.
v1.1.0 - 2021-12-03 BN13: They're Lunatics (hydroflame & community) v1.1.0 - 2021-12-03 BN13: They're Lunatics (hydroflame & community)
------------------------------------------------------- -------------------------------------------------------------------
** BN13: They're Lunatics ** ** BN13: They're Lunatics **

@ -64,9 +64,9 @@ documentation_title = '{0} Documentation'.format(project)
# built documents. # built documents.
# #
# The short X.Y version. # The short X.Y version.
version = '1.1' version = '1.2'
# The full version, including alpha/beta/rc tags. # The full version, including alpha/beta/rc tags.
release = '1.1.0' release = '1.2.0'
# The language for content autogenerated by Sphinx. Refer to documentation # The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages. # for a list of supported languages.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -1,10 +1,10 @@
{ {
"name": "bitburner", "name": "bitburner",
"license": "SEE LICENSE IN license.txt", "license": "SEE LICENSE IN license.txt",
"version": "1.1.0", "version": "1.2.0",
"main": "electron-main.js", "main": "electron-main.js",
"author": { "author": {
"name": "Daniel Xie" "name": "Daniel Xie & Olivier Gagnon"
}, },
"bugs": { "bugs": {
"url": "https://github.com/danielyxie/bitburner/issues" "url": "https://github.com/danielyxie/bitburner/issues"

@ -29,7 +29,6 @@ export function PurchasedAugmentations(): React.ReactElement {
if (ownedAug.name === AugmentationNames.NeuroFluxGovernor) { if (ownedAug.name === AugmentationNames.NeuroFluxGovernor) {
level = ownedAug.level; level = ownedAug.level;
} }
augs.push(<AugmentationAccordion key={aug.name} aug={aug} level={level} />); augs.push(<AugmentationAccordion key={aug.name} aug={aug} level={level} />);
} }

@ -111,8 +111,8 @@ export const CONSTANTS: {
TotalNumBitNodes: number; TotalNumBitNodes: number;
LatestUpdate: string; LatestUpdate: string;
} = { } = {
VersionString: "1.1.0", VersionString: "1.2.0",
VersionNumber: 6, VersionNumber: 7,
// Speed (in ms) at which the main loop is updated // Speed (in ms) at which the main loop is updated
_idleSpeed: 200, _idleSpeed: 200,
@ -273,72 +273,103 @@ export const CONSTANTS: {
TotalNumBitNodes: 24, TotalNumBitNodes: 24,
LatestUpdate: ` LatestUpdate: `
v1.1.0 - 2021-12-03 BN13: They're Lunatics (hydroflame & community) v1.1.0 - 2021-12-18 You guys are awesome (community because they're god damn awesome)
------------------------------------------------------- -------------------------------------------------------------------------------------
** BN13: They're Lunatics ** ** Script Editor **
* BN13 added. * The text editor can open several files at once. (@Rez855 / @Shadow72)
It's not perfect so keep the feedback coming.
** Steam ** ** Steam **
* Tested on all 3 major OS. * Windows has a new launch option that lets player start with killing all their scripts
* 94 achievements added This is a safety net in case all the other safety nets fail.
* Release is 2021-12-10. * Linux has several launch options that use different flags for different OS.
* Debug and Fullscreen are available in the window utility bar.
* Tried (and maybe failed) to make the game completely kill itself after closing.
This one I still don't know wtf is going.
* No longer has background throttling.
* Default color should be pitch black when loading
* Add BN13: Challenge achievement.
** Corporation API ** ** Tutorial **
* Added corporation API. (Unstable) * I watched someone play bitburner on youtube and reworked part of
the tutorial to try to make some parts of the game clearer.
https://www.youtube.com/watch?v=-_JETXff4Zo
* Add option to restart tutorial.
** Netscript ** ** Netscript **
* tprintf crashes when not giving a format as first arg.
* tprintf no longer prints filename (@BartKoppelmans)
* TIX buy/sell/sellShort all return askprice/bidprice (@Insight)
* getRunningScript now works.
* Fix disableLog for gang and TIX API
* getOwnedSourceFiles is not singularity anymore (makes it easier to share scripts.) (@theit8514)
* true/false is a valid value to send to other scripts.
* workForFaction no longer returns null when trying to work for gang.
* Scripts logging no longer generates the string if logging is disabled.
This should give performance boost for some scripts.
** Gang ** * getGangInformation returns more information.
* getAscensionResult added
* Gang with 0 territory can no longer fight * getMemberInformation returns more info
* Territory now caps at exactly 0 or 1. * Formulas API has new functions for gang.
* Added documentation for corp API.
* exec has clearer error message when you send invalid data.
* getServer returns all defined field for hacknet servers.
* Fix a bug with scp multiple files (@theit8514)
* Stack traces should be smarter at replacing blobs with filenames
* Fix a weird error message that would occur when throwing raw strings.
* Fix shortcuts not working.
* Re-added setFocus and isFocused (@theit8514)
* new function getHashUpgrades (@MartinFournier)
* enableLog accepts "ALL" like disableLog (@wynro)
* toast() doesn't crash on invalid data (@ivanjermakov)
* alert() doesn't crash on invalid data (@Siern)
* Fixed an issue where scripts don't run where they should.
* Sleeve getInformation now returns cha
* getServer does work with no argument now
* workForFaction returns false when it mistakenly returned null
** Character Overview **
* The character overview now shows the amount of exp needed to next level (@MartinFournier)
** Misc. ** ** Misc. **
* Clicking "previous" on the browser will not pretend you had unsaved information * Add option to supress Game Saved! toasts (@MartinFournier)
allowing you to cancel if needs be. * Fix bug where ctrl+alt+j was eaten by the wrong process. (@billyvg)
* Fixed some tail box coloring issue. * Theme Editor lets you paste colors (@MartinFournier)
* Fixed BladeBurner getCityCommunities ram cost * ctrl + u/k/w should work on terminal (@billyvg)
* The download terminal command no longer duplicate extensions (@Insight) * Game now shows commit number, this is mostly for me. (@MartinFourier)
* Fix #000 on #000 text in blackjack. (@Insight) * running a bad script will give a clearer error message (@TheCoderJT)
* Remove reference to .fconf * Default terminal capacity is maximum (@SayntGarmo)
* Tail boxes all die on soft reset. * Fix problems with cp and mv (@theit8514)
* Fix codign contract focus bug. * Make monaco load fully offline for players behind firewalls.
* Megacorp factions simply re-invite you instead of auto added on reset. (@theit8514) * change beginer guide to use n00dles instead of foodnstuff
* Tail window is bound to html body. * BN13 is harder
* Infiltration reward is tied to your potential stats, not your actual stats * nerf int gain from manualHack
So you won't lose reward for doing the same thing over and over. * Fix UI displaying wrong stats (@DJMatch3000)
* intelligence lowers program creation requirements. * Fix button not disabling as it should.
* Terminal parses true as the boolean, not the string. * New location in Ishima.
* Tail and kill autocomplete using the ns2 autocomplete feature. * Add setting to suppress stock market popups.
* scan-analyze doesn't take up as many terminal entries. * Typo fixes (@Hedrauta, @cvr-119, @Ationi, @millennIumAMbiguity
* GangOtherInfo documentation now renders correctly. @TealKoi, @TheCoderJT, @cblte, @2PacIsAlive, @MageKing17,
* ActiveScripts search box also searches for script names. @Xynrati, @Adraxas, @pobiega)
* Infinite money no longer allows for infinite hacknet server. * Fix 100% territory achievement.
* Blackjack doesn't make you lose money twice. * Reword message on active scripts page.
* Recent Scripts is now from most to least recent. * Fix terminal not clearing after BN
* Fix mathjax ascii art bug in NiteSec. * Remove references to .fconf
* Remove warning that the theme editor is slow, it's only slow in dev mode. * Augmentation pages shows BN difficulty with SF5
* In BN8 is it possible to reduce the money on a server without gaining any. * Fix scripts saving on wrong server while 'connect'ing
* In the options, the timestamp feature has a placeholder explaining the expected format. * Fix gym discount not working.
* Bunch of doc typo fix. (hydroflame & @BartKoppelmans & @cvr-119) * Fix scan-analyze not working with timestamps
* World Daemon difficulty is increased depending on BitNode. * Hash upgrades remember last choice.
* hacking skill nerf was loosened in some BNs. * Save files now sort by date
* nerf noodle bar * The covenant no longer supports negative memory purchases
* Fix corp shares buyback triggering by pressing enter
* Staneks gift display avg / num charges
* Infiltration rewards no longer decay with better stats
* terminal 'true' is parsed as boolean not string
* tail and kill use autocomplete()
* Fix focus for coding contract
* massive boost to noodle bar.
** Special Thanks **
* Special thank you to everyone on Discord who can answer
new player questions so I can focus on more important things.
`, `,
}; };

@ -189,7 +189,7 @@ const achievements: Achievement[] = [
}, },
{ {
ID: "GANG_TERRITORY", ID: "GANG_TERRITORY",
Condition: () => Player.gang !== null && AllGangs[Player.gang.facName].territory === 1, Condition: () => Player.gang !== null && AllGangs[Player.gang.facName].territory >= 0.999,
}, },
{ {
ID: "GANG_MEMBER_POWER", ID: "GANG_MEMBER_POWER",

@ -27,18 +27,14 @@ import { loadThemes } from "./themes";
import { GetServer } from "../../Server/AllServers"; import { GetServer } from "../../Server/AllServers";
import Button from "@mui/material/Button"; import Button from "@mui/material/Button";
import Tooltip from "@mui/material/Tooltip";
import Typography from "@mui/material/Typography"; import Typography from "@mui/material/Typography";
import Link from "@mui/material/Link"; import Link from "@mui/material/Link";
import Box from "@mui/material/Box"; import Box from "@mui/material/Box";
import TextField from "@mui/material/TextField";
import IconButton from "@mui/material/IconButton"; import IconButton from "@mui/material/IconButton";
import SettingsIcon from "@mui/icons-material/Settings"; import SettingsIcon from "@mui/icons-material/Settings";
import libSource from "!!raw-loader!../NetscriptDefinitions.d.ts"; import libSource from "!!raw-loader!../NetscriptDefinitions.d.ts";
import { cssNumber } from "cypress/types/jquery";
import { buttonBaseClasses } from "@mui/material";
import { fromPairs } from "cypress/types/lodash";
import { StringMatcher } from "cypress/types/net-stubbing";
let symbolsLoaded = false; let symbolsLoaded = false;
let symbols: string[] = []; let symbols: string[] = [];
@ -102,8 +98,8 @@ class openScript {
} }
} }
const openScripts = new Array<openScript>(); // Holds all open scripts const openScripts = new Array<openScript>(); // Holds all open scripts
let currentScript = {} as openScript; // Script currently being viewed let currentScript = {} as openScript; // Script currently being viewed
export function Root(props: IProps): React.ReactElement { export function Root(props: IProps): React.ReactElement {
const editorRef = useRef<IStandaloneCodeEditor | null>(null); const editorRef = useRef<IStandaloneCodeEditor | null>(null);
@ -120,8 +116,6 @@ export function Root(props: IProps): React.ReactElement {
fontSize: Settings.MonacoFontSize, fontSize: Settings.MonacoFontSize,
}); });
const debouncedSetRAM = useMemo( const debouncedSetRAM = useMemo(
() => () =>
debounce((s) => { debounce((s) => {
@ -171,7 +165,12 @@ export function Root(props: IProps): React.ReactElement {
//If the current script already exists on the server, overwrite it //If the current script already exists on the server, overwrite it
for (let i = 0; i < server.scripts.length; i++) { for (let i = 0; i < server.scripts.length; i++) {
if (currentScript.fileName == server.scripts[i].filename) { if (currentScript.fileName == server.scripts[i].filename) {
server.scripts[i].saveScript(currentScript.fileName, currentScript.code, props.player.currentServer, server.scripts); server.scripts[i].saveScript(
currentScript.fileName,
currentScript.code,
props.player.currentServer,
server.scripts,
);
if (Settings.SaveGameOnFileSave) saveObject.saveGame(); if (Settings.SaveGameOnFileSave) saveObject.saveGame();
return; return;
} }
@ -241,7 +240,7 @@ export function Root(props: IProps): React.ReactElement {
if (editorRef.current !== null) { if (editorRef.current !== null) {
infLoop(newCode); infLoop(newCode);
} }
} catch (err) { } } catch (err) {}
} }
// calculate it once the first time the file is loaded. // calculate it once the first time the file is loaded.
@ -289,18 +288,18 @@ export function Root(props: IProps): React.ReactElement {
}); });
// Generates a new model for the script // Generates a new model for the script
function regenerateModel(script: openScript) { function regenerateModel(script: openScript): void {
if (monacoRef.current !== null) { if (monacoRef.current !== null) {
script.model = monacoRef.current.editor.createModel(script.code, 'javascript'); script.model = monacoRef.current.editor.createModel(script.code, "javascript");
} }
} }
// Sets the currently viewed script // Sets the currently viewed script
function setCurrentScript(script: openScript) { function setCurrentScript(script: openScript): void {
// Update last position // Update last position
if (editorRef.current !== null) { if (editorRef.current !== null) {
if (currentScript !== null) { if (currentScript !== null) {
var currentPosition = editorRef.current.getPosition(); const currentPosition = editorRef.current.getPosition();
if (currentPosition !== null) { if (currentPosition !== null) {
currentScript.lastPosition = currentPosition; currentScript.lastPosition = currentPosition;
} }
@ -315,7 +314,7 @@ export function Root(props: IProps): React.ReactElement {
} }
// Gets a currently opened script // Gets a currently opened script
function getOpenedScript(fileName: string, hostname: string) { function getOpenedScript(fileName: string, hostname: string): openScript | null {
for (const script of openScripts) { for (const script of openScripts) {
if (script.fileName === fileName && script.hostname === hostname) { if (script.fileName === fileName && script.hostname === hostname) {
return script; return script;
@ -325,7 +324,7 @@ export function Root(props: IProps): React.ReactElement {
return null; return null;
} }
function saveScript(script: openScript) { function saveScript(script: openScript): void {
const server = GetServer(script.hostname); const server = GetServer(script.hostname);
if (server === null) throw new Error("Server should not be null but it is."); if (server === null) throw new Error("Server should not be null but it is.");
let found = false; let found = false;
@ -368,7 +367,13 @@ export function Root(props: IProps): React.ReactElement {
if (filename !== undefined) { if (filename !== undefined) {
// Create new model // Create new model
if (monacoRef.current !== null) { if (monacoRef.current !== null) {
var newScript = new openScript(filename, code, props.player.getCurrentServer().hostname, new monaco.Position(0, 0), monacoRef.current.editor.createModel(code, 'javascript')); const newScript = new openScript(
filename,
code,
props.player.getCurrentServer().hostname,
new monaco.Position(0, 0),
monacoRef.current.editor.createModel(code, "javascript"),
);
setCurrentScript(newScript); setCurrentScript(newScript);
openScripts.push(newScript); openScripts.push(newScript);
} }
@ -384,7 +389,13 @@ export function Root(props: IProps): React.ReactElement {
} else { } else {
// Create a new temporary file // Create a new temporary file
if (monacoRef.current !== null) { if (monacoRef.current !== null) {
var newScript = new openScript('NewFile.ns', '', props.player.getCurrentServer().hostname, new monaco.Position(0, 0), monacoRef.current.editor.createModel('', 'javascript')); const newScript = new openScript(
"newfile.script",
"",
props.player.getCurrentServer().hostname,
new monaco.Position(0, 0),
monacoRef.current.editor.createModel("", "javascript"),
);
setCurrentScript(newScript); setCurrentScript(newScript);
openScripts.push(newScript); openScripts.push(newScript);
} }
@ -432,37 +443,41 @@ export function Root(props: IProps): React.ReactElement {
} }
// Change tab highlight from old tab to new tab // Change tab highlight from old tab to new tab
function changeTabButtonColor(oldButtonFileName: string, oldButtonHostname: string, newButtonFileName: string, newButtonHostname: string) { function changeTabButtonColor(
const oldTabButton = document.getElementById('tabButton' + oldButtonFileName + oldButtonHostname); oldButtonFileName: string,
oldButtonHostname: string,
newButtonFileName: string,
newButtonHostname: string,
): void {
const oldTabButton = document.getElementById("tabButton" + oldButtonFileName + oldButtonHostname);
if (oldTabButton !== null) { if (oldTabButton !== null) {
oldTabButton.style.backgroundColor = ''; oldTabButton.style.backgroundColor = "";
} }
const oldTabCloseButton = document.getElementById('tabCloseButton' + oldButtonFileName + oldButtonHostname); const oldTabCloseButton = document.getElementById("tabCloseButton" + oldButtonFileName + oldButtonHostname);
if (oldTabCloseButton !== null) { if (oldTabCloseButton !== null) {
oldTabCloseButton.style.backgroundColor = ''; oldTabCloseButton.style.backgroundColor = "";
} }
const newTabButton = document.getElementById('tabButton' + newButtonFileName + newButtonHostname); const newTabButton = document.getElementById("tabButton" + newButtonFileName + newButtonHostname);
if (newTabButton !== null) { if (newTabButton !== null) {
newTabButton.style.backgroundColor = '#173b2d'; newTabButton.style.backgroundColor = "#666";
} }
const newTabCloseButton = document.getElementById('tabCloseButton' + newButtonFileName + newButtonHostname); const newTabCloseButton = document.getElementById("tabCloseButton" + newButtonFileName + newButtonHostname);
if (newTabCloseButton !== null) { if (newTabCloseButton !== null) {
newTabCloseButton.style.backgroundColor = '#173b2d'; newTabCloseButton.style.backgroundColor = "#666";
} }
} }
// Called when a script tab was clicked // Called when a script tab was clicked
function onTabButtonClick(e: React.MouseEvent<HTMLButtonElement>) { function onTabButtonClick(e: React.MouseEvent<HTMLButtonElement>): void {
const valSplit = e.currentTarget.value.split(':'); const valSplit = e.currentTarget.value.split(":");
const fileName = valSplit[0]; const fileName = valSplit[0];
const hostname = valSplit[1]; const hostname = valSplit[1];
// Change tab highlight from old tab to new tab // Change tab highlight from old tab to new tab
changeTabButtonColor(currentScript.fileName, currentScript.hostname, fileName, hostname) changeTabButtonColor(currentScript.fileName, currentScript.hostname, fileName, hostname);
// Update current script // Update current script
const clickedScript = getOpenedScript(fileName, hostname); const clickedScript = getOpenedScript(fileName, hostname);
@ -477,8 +492,8 @@ export function Root(props: IProps): React.ReactElement {
} }
// Called when a script tab close button was clicked // Called when a script tab close button was clicked
function onCloseButtonClick(e: React.MouseEvent<HTMLButtonElement>) { function onCloseButtonClick(e: React.MouseEvent<HTMLButtonElement>): void {
const valSplit = e.currentTarget.value.split(':'); const valSplit = e.currentTarget.value.split(":");
const fileName = valSplit[0]; const fileName = valSplit[0];
const hostname = valSplit[1]; const hostname = valSplit[1];
@ -494,20 +509,23 @@ export function Root(props: IProps): React.ReactElement {
if (openScripts.length === 0) { if (openScripts.length === 0) {
// No other scripts are open, create a new temporary file // No other scripts are open, create a new temporary file
if (monacoRef.current !== null) { if (monacoRef.current !== null) {
const newScript = new openScript("NewFile.ns", '', props.player.getCurrentServer().hostname, new monacoRef.current.Position(0, 0), monacoRef.current.editor.createModel('', 'javascript')); const newScript = new openScript(
"newfile.script",
"",
props.player.getCurrentServer().hostname,
new monacoRef.current.Position(0, 0),
monacoRef.current.editor.createModel("", "javascript"),
);
setCurrentScript(newScript) setCurrentScript(newScript);
openScripts.push(newScript); openScripts.push(newScript);
// Create new tab button for temporary file
const element = (<div style={{ paddingRight: '5px' }}><Button style={{ backgroundColor: '#173b2d' }} value={newScript.fileName + ':' + newScript.hostname} onClick={onTabButtonClick}>{newScript.fileName}</Button><Button value={newScript.fileName + ':' + newScript.hostname} onClick={onCloseButtonClick} style={{ maxWidth: '20px', minWidth: '20px', backgroundColor: '#173b2d' }}>x</Button></div>)
// Modify button for temp file // Modify button for temp file
var parent = e.currentTarget.parentElement; const parent = e.currentTarget.parentElement;
if (parent !== null) { if (parent !== null) {
(parent.children[0] as HTMLButtonElement).value = 'NewFile.ns:home'; (parent.children[0] as HTMLButtonElement).value = "newfile.script:home";
(parent.children[0] as HTMLButtonElement).textContent = 'NewFile.ns'; (parent.children[0] as HTMLButtonElement).textContent = "newfile.script";
e.currentTarget.value = 'NewFile.ns:home'; e.currentTarget.value = "newfile.script:home";
} }
} }
} else { } else {
@ -515,7 +533,12 @@ export function Root(props: IProps): React.ReactElement {
regenerateModel(openScripts[0]); regenerateModel(openScripts[0]);
} }
changeTabButtonColor(currentScript.fileName, currentScript.hostname, openScripts[0].fileName, openScripts[0].hostname); changeTabButtonColor(
currentScript.fileName,
currentScript.hostname,
openScripts[0].fileName,
openScripts[0].hostname,
);
setCurrentScript(openScripts[0]); setCurrentScript(openScripts[0]);
} }
@ -524,14 +547,53 @@ export function Root(props: IProps): React.ReactElement {
// Generate a button for each open script // Generate a button for each open script
const scriptButtons = []; const scriptButtons = [];
for (let i = 0; i < openScripts.length; i++) { for (let i = 0; i < openScripts.length; i++) {
if (openScripts[i].fileName !== '') { if (openScripts[i].fileName !== "") {
const fileName2 = openScripts[i].fileName; const fileName2 = openScripts[i].fileName;
const hostname = openScripts[i].hostname; const hostname = openScripts[i].hostname;
if (openScripts[i].fileName === currentScript.fileName && openScripts[i].hostname === currentScript.hostname) { if (openScripts[i].fileName === currentScript.fileName && openScripts[i].hostname === currentScript.hostname) {
// Set special background color for current script tab button // Set special background color for current script tab button
scriptButtons.push(<div id={'scriptEditorTab' + fileName2 + hostname} key={'tabButton' + i} style={{ paddingRight: '5px' }}><Button id={'tabButton' + openScripts[i].fileName + openScripts[i].hostname} style={{ backgroundColor: '#173b2d' }} value={fileName2 + ':' + hostname} onClick={onTabButtonClick}>{openScripts[i].fileName}</Button><Button id={'tabCloseButton' + openScripts[i].fileName + openScripts[i].hostname} value={fileName2 + ':' + hostname} onClick={onCloseButtonClick} style={{ maxWidth: '20px', minWidth: '20px', backgroundColor: '#173b2d' }}>x</Button></div>) scriptButtons.push(
<Tooltip
title={
<Typography>
{hostname}:~/{fileName2}
</Typography>
}
>
<div key={fileName2 + hostname} style={{ paddingRight: "5px" }}>
<Button style={{ backgroundColor: "#666" }} value={fileName2 + ":" + hostname} onClick={onTabButtonClick}>
{openScripts[i].fileName}
</Button>
<Button
value={fileName2 + ":" + hostname}
onClick={onCloseButtonClick}
style={{ maxWidth: "20px", minWidth: "20px", backgroundColor: "#666" }}
>
x
</Button>
</div>
</Tooltip>,
);
} else { } else {
scriptButtons.push(<div id={'scriptEditorTab' + fileName2 + hostname} key={'tabButton' + i} style={{ paddingRight: '5px' }}><Button id={'tabButton' + openScripts[i].fileName + openScripts[i].hostname} value={fileName2 + ':' + hostname} onClick={onTabButtonClick}>{openScripts[i].fileName}</Button><Button id={'tabCloseButton' + openScripts[i].fileName + openScripts[i].hostname} value={fileName2 + ':' + hostname} onClick={onCloseButtonClick} style={{ maxWidth: '20px', minWidth: '20px' }}>x</Button></div>) scriptButtons.push(
<div id={"scriptEditorTab" + fileName2 + hostname} key={"tabButton" + i} style={{ paddingRight: "5px" }}>
<Button
id={"tabButton" + openScripts[i].fileName + openScripts[i].hostname}
value={fileName2 + ":" + hostname}
onClick={onTabButtonClick}
>
{openScripts[i].fileName}
</Button>
<Button
id={"tabCloseButton" + openScripts[i].fileName + openScripts[i].hostname}
value={fileName2 + ":" + hostname}
onClick={onCloseButtonClick}
style={{ maxWidth: "20px", minWidth: "20px" }}
>
x
</Button>
</div>,
);
} }
} }
} }
@ -541,7 +603,7 @@ export function Root(props: IProps): React.ReactElement {
const p = 11000 / -window.innerHeight + 100; const p = 11000 / -window.innerHeight + 100;
return ( return (
<> <>
<Box display="flex" flexDirection="row" alignItems="center" paddingBottom='5px'> <Box display="flex" flexDirection="row" alignItems="center" paddingBottom="5px">
{scriptButtons} {scriptButtons}
</Box> </Box>
<Editor <Editor
@ -557,7 +619,7 @@ export function Root(props: IProps): React.ReactElement {
/> />
<Box display="flex" flexDirection="row" sx={{ m: 1 }} alignItems="center"> <Box display="flex" flexDirection="row" sx={{ m: 1 }} alignItems="center">
<Button onClick={beautify}>Beautify</Button> <Button onClick={beautify}>Beautify</Button>
<Typography color={updatingRam ? "secondary" : "primary"} sx={{ mx: 1 }}> <Typography color={updatingRam ? "secondary" : "primary"} sx={{ mx: 1 }}>
{ram} {ram}
</Typography> </Typography>
<Button onClick={save}>Save (Ctrl/Cmd + b)</Button> <Button onClick={save}>Save (Ctrl/Cmd + b)</Button>
@ -572,7 +634,7 @@ export function Root(props: IProps): React.ReactElement {
Full Full
</Link> </Link>
</Typography> </Typography>
<IconButton style={{ marginLeft: 'auto' }} onClick={() => setOptionsOpen(true)}> <IconButton style={{ marginLeft: "auto" }} onClick={() => setOptionsOpen(true)}>
<> <>
<SettingsIcon /> <SettingsIcon />
options options
@ -596,4 +658,4 @@ export function Root(props: IProps): React.ReactElement {
/> />
</> </>
); );
} }

@ -1,8 +1,9 @@
import * as React from 'react'; import * as React from "react";
import LinearProgress from '@mui/material/LinearProgress'; import LinearProgress from "@mui/material/LinearProgress";
import { TableCell, Tooltip } from '@mui/material'; import { TableCell, Tooltip } from "@mui/material";
import { characterOverviewStyles } from './CharacterOverview'; import { characterOverviewStyles } from "./CharacterOverview";
import { ISkillProgress } from 'src/PersonObjects/formulas/skill'; import { ISkillProgress } from "src/PersonObjects/formulas/skill";
import { numeralWrapper } from "../numeralFormat";
interface IProgressProps { interface IProgressProps {
min: number; min: number;
@ -18,11 +19,13 @@ interface IStatsOverviewCellProps {
export function StatsProgressBar({ min, max, current, color }: IProgressProps): React.ReactElement { export function StatsProgressBar({ min, max, current, color }: IProgressProps): React.ReactElement {
const normalise = (value: number): number => ((value - min) * 100) / (max - min); const normalise = (value: number): number => ((value - min) * 100) / (max - min);
const tooltipText = <> const tooltipText = (
Experience: {current.toFixed(2)}/{max.toFixed(2)} <>
<br /> Experience: {numeralWrapper.formatExp(current)}/{numeralWrapper.formatExp(max)}
{normalise(current).toFixed(2)}% <br />
</>; {normalise(current).toFixed(2)}%
</>
);
return ( return (
<Tooltip title={tooltipText}> <Tooltip title={tooltipText}>
@ -30,8 +33,8 @@ export function StatsProgressBar({ min, max, current, color }: IProgressProps):
variant="determinate" variant="determinate"
value={normalise(current)} value={normalise(current)}
sx={{ sx={{
backgroundColor: '#111111', backgroundColor: "#111111",
'& .MuiLinearProgress-bar1Determinate': { "& .MuiLinearProgress-bar1Determinate": {
backgroundColor: color, backgroundColor: color,
}, },
}} }}
@ -40,12 +43,16 @@ export function StatsProgressBar({ min, max, current, color }: IProgressProps):
); );
} }
export function StatsProgressOverviewCell({progress, color}: IStatsOverviewCellProps): React.ReactElement { export function StatsProgressOverviewCell({ progress, color }: IStatsOverviewCellProps): React.ReactElement {
const classes = characterOverviewStyles(); const classes = characterOverviewStyles();
return ( return (
<TableCell component="th" scope="row" colSpan={2} <TableCell
component="th"
scope="row"
colSpan={2}
classes={{ root: classes.cellNone }} classes={{ root: classes.cellNone }}
style={{ paddingBottom: '2px', position: 'relative', top: '-3px' }}> style={{ paddingBottom: "2px", position: "relative", top: "-3px" }}
>
<StatsProgressBar <StatsProgressBar
min={progress.baseExperience} min={progress.baseExperience}
max={progress.nextExperience} max={progress.nextExperience}
@ -53,5 +60,5 @@ export function StatsProgressOverviewCell({progress, color}: IStatsOverviewCellP
color={color} color={color}
/> />
</TableCell> </TableCell>
) );
} }