mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-11-26 09:33:49 +01:00
commit
e69f360ec4
@ -84,7 +84,9 @@ changes are okay to contribute:
|
|||||||
- Changes that directly affect the game's balance
|
- Changes that directly affect the game's balance
|
||||||
- New gameplay mechanics
|
- New gameplay mechanics
|
||||||
|
|
||||||
### How to setup fork properly
|
---
|
||||||
|
|
||||||
|
## How to setup fork properly
|
||||||
|
|
||||||
Fork and clone the repo
|
Fork and clone the repo
|
||||||
|
|
||||||
@ -106,7 +108,15 @@ Fork and clone the repo
|
|||||||
# Makes sure you always start from `danielyxie/dev` to avoid merge conflicts.
|
# Makes sure you always start from `danielyxie/dev` to avoid merge conflicts.
|
||||||
```
|
```
|
||||||
|
|
||||||
### Running locally.
|
## Development Workflow Best Practices
|
||||||
|
|
||||||
|
- Work in a new branch forked from the `dev` branch to isolate your new code
|
||||||
|
- Keep code-changes on a branch as small as possible. This makes it easier for code review. Each branch should be its own independent feature.
|
||||||
|
- Regularly rebase your branch against `dev` to make sure you have the latest updates pulled.
|
||||||
|
- When merging, always merge your branch into `dev`. When releasing a new update, then merge `dev` into `master`
|
||||||
|
|
||||||
|
|
||||||
|
## Running locally.
|
||||||
|
|
||||||
Install
|
Install
|
||||||
|
|
||||||
@ -168,9 +178,14 @@ the following rules:
|
|||||||
|
|
||||||
## As a Documentor
|
## As a Documentor
|
||||||
|
|
||||||
To contribute to and view your changes to the BitBurner documentation, you will
|
To contribute to and view your changes to the BitBurner documentation on [Read The
|
||||||
|
Docs](http://bitburner.readthedocs.io/), you will
|
||||||
need to have Python installed, along with [Sphinx](http://www.sphinx-doc.org).
|
need to have Python installed, along with [Sphinx](http://www.sphinx-doc.org).
|
||||||
|
|
||||||
|
To make change to the [in-game documentation](./markdown/bitburner.md), you will need to modify the [TypeScript definitions](./src/ScriptEditor/NetscriptDefinitions.d.ts), not the markdown files.
|
||||||
|
|
||||||
|
We are using [API Extractor](https://api-extractor.com/pages/tsdoc/doc_comment_syntax/) (tsdoc hints) to generate the markdown doc. Make your changes to the TypeScript definitions and then run `npm run doc`.
|
||||||
|
|
||||||
Before submitting your code for a pull request, please try to follow these
|
Before submitting your code for a pull request, please try to follow these
|
||||||
rules:
|
rules:
|
||||||
|
|
||||||
@ -182,3 +197,14 @@ rules:
|
|||||||
_danielyxie/bitburner_ and the base is _dev_.
|
_danielyxie/bitburner_ and the base is _dev_.
|
||||||
- Do not check in any generated files under `doc\`. The documentation is built
|
- Do not check in any generated files under `doc\`. The documentation is built
|
||||||
automatically by ReadTheDocs.
|
automatically by ReadTheDocs.
|
||||||
|
|
||||||
|
## Deploying a new version
|
||||||
|
|
||||||
|
Update the following
|
||||||
|
|
||||||
|
- `src/Constants.ts` `Version` and `LatestUpdate`
|
||||||
|
- `package.json` `version`
|
||||||
|
- `doc/source/conf.py` `version` and `release`
|
||||||
|
- `doc/source/changelog.rst`
|
||||||
|
- post to discord
|
||||||
|
- post to reddit.com/r/Bitburner
|
||||||
|
87
FAQ.md
Normal file
87
FAQ.md
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
# Frequently Asked Questions
|
||||||
|
|
||||||
|
## Can I donate to the project?
|
||||||
|
|
||||||
|
No, the project does not take donation.
|
||||||
|
|
||||||
|
If you still want to donate, go donate blood to your local blood bank or donate to the [Electronic Frontier Foundation](https://www.eff.org/) or [Médecins Sans Frontières](https://www.msf.org/)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## I need help / Where can I learn?
|
||||||
|
|
||||||
|
The best way to get help is to join the [official discord server](https://discord.gg/TFc3hKD). People of all skill levels will be able to give you hints and tips.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Can I play the same save on browser & steam?
|
||||||
|
|
||||||
|
Yes, just export the save file from the options menu & import it in the other platform.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Game is stuck after running scripts!
|
||||||
|
|
||||||
|
You may have created an infinite loop with no sleep. You'll have to restart the game by killing all scripts.
|
||||||
|
* On Browser: Stick `?noScript` at the end of the URL
|
||||||
|
* On Steam:
|
||||||
|
* In the menu, "Reloads" -> "Reload & Kill All Scripts".
|
||||||
|
* If this does not work, when launching the game, use the kill all script options.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Steam: Where is the save game located?
|
||||||
|
|
||||||
|
To maintain compatibility with the web browser version, the save game is not stored as a file on your filesystem. It lives inside the localStorage of the WebKit instance. You may export the save (and should backup it!) in the option menu.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Steam: Game won't stop / Game is shown as "Running"
|
||||||
|
|
||||||
|
Due to a limitation with the way Steam tracks the game, if you launch an external link (such as documentation), Steam may keep tracking the game as "Running" even after it is closed. You should simply have to close your web browser to fix this.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Steam: How do I get to the game files? <a name="game-files"></a>
|
||||||
|
|
||||||
|
You can navigate to the game files by right-clicking the game in your library and then go into "Manage" -> "Browse Local Files". The game can be launched directly from that location, if you're having issues with Steam.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Steam: Game won't launch
|
||||||
|
|
||||||
|
### **On Windows**
|
||||||
|
If the game is installed on a network drive, it will fail to start due to a [limitation in Chromium](https://github.com/electron/electron/issues/27356).
|
||||||
|
|
||||||
|
If you cannot move the game to another drive, you'll have to add the `--no-sandbox` launch option. In your Steam Library, Right click the game and hit "Properties". You'll see the launch option section in the "General" window.
|
||||||
|
|
||||||
|
### **On Linux**
|
||||||
|
The game is built natively, do not use Proton unless native does not work.
|
||||||
|
|
||||||
|
When launching the game, you will be prompted with three options. If the standard launch does not work, you may attempt the `--disable-seccomp-filter-sandbox` or `--no-sandbox` launch option. If this still does not work, the game should be able to start by launching it directly or through the terminal. See [How do I get to the game files?](#game-files).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Steam: File locations
|
||||||
|
|
||||||
|
### Logs (using [electron-log](https://github.com/megahertz/electron-log#readme))
|
||||||
|
|
||||||
|
You may want access the logs to get information about crashes or such.
|
||||||
|
|
||||||
|
* on Linux: `~/.config/bitburner/logs/main.log`
|
||||||
|
* on macOS: `~/Library/Logs/bitburner/main.log`
|
||||||
|
* on Windows: `%USERPROFILE%\AppData\Roaming\bitburner\logs\main.log`
|
||||||
|
|
||||||
|
### Config (using [electron-store](https://github.com/sindresorhus/electron-store#readme))
|
||||||
|
|
||||||
|
Configuration file will be written to disk in the application data directory.
|
||||||
|
|
||||||
|
* on Linux: `~/.config/bitburner/config.json`
|
||||||
|
* on macOS: `~/Library/Application\ Support/bitburner/config.json`
|
||||||
|
* on Windows: `%USERPROFILE%\AppData\Roaming\bitburner\config.json`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Steam: What is the API Server?
|
||||||
|
|
||||||
|
The API Server allows the official [Visual Studio Code Extension](https://github.com/bitburner-official/bitburner-vscode) to push script file from VSCode to your in-game home.
|
11
README.md
11
README.md
@ -1,16 +1,19 @@
|
|||||||
# Bitburner
|
# Bitburner
|
||||||
|
|
||||||
|
[![Build Status](https://github.com/danielyxie/bitburner/actions/workflows/ci.yml/badge.svg?branch=dev)](https://github.com/danielyxie/bitburner/actions/workflows/ci.yml)
|
||||||
|
|
||||||
Bitburner is a programming-based [incremental game](https://en.wikipedia.org/wiki/Incremental_game)
|
Bitburner is a programming-based [incremental game](https://en.wikipedia.org/wiki/Incremental_game)
|
||||||
that revolves around hacking and cyberpunk themes.
|
that revolves around hacking and cyberpunk themes.
|
||||||
The game can be played at https://danielyxie.github.io/bitburner.
|
The game can be played at https://danielyxie.github.io/bitburner or installed through [Steam](https://store.steampowered.com/app/1812820/Bitburner/).
|
||||||
|
|
||||||
|
See the [frequently asked questions](./FAQ.md) for more information . To discuss the game or get help, join the [official discord server](https://discord.gg/TFc3hKD)
|
||||||
|
|
||||||
# Documentation
|
# Documentation
|
||||||
|
|
||||||
The game's official documentation can be found on [Read The
|
The game's official documentation can be found on [Read The
|
||||||
Docs](http://bitburner.readthedocs.io/). Please note that this is still a
|
Docs](http://bitburner.readthedocs.io/). Please note that this is still a work-in-progress.
|
||||||
work-in-progress.
|
|
||||||
|
|
||||||
The documentation is created using [Sphinx](http://www.sphinx-doc.org).
|
The [in-game documentation](./markdown/bitburner.md) is generated from the [TypeScript definitions](./src/ScriptEditor/NetscriptDefinitions.d.ts).
|
||||||
|
|
||||||
Anyone is welcome to contribute to the documentation by editing the [source
|
Anyone is welcome to contribute to the documentation by editing the [source
|
||||||
files](/doc/source) and then making a pull request with your contributions.
|
files](/doc/source) and then making a pull request with your contributions.
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
## Deploying a new version
|
|
||||||
|
|
||||||
Update the following
|
|
||||||
|
|
||||||
- `src/Constants.ts` `Version` and `LatestUpdate`
|
|
||||||
- `package.json` `version`
|
|
||||||
- `doc/source/conf.py` `version` and `release`
|
|
||||||
- `doc/source/changelog.rst`
|
|
||||||
- post to discord
|
|
||||||
- post to reddit.com/r/Bitburner
|
|
||||||
|
|
||||||
## Deploying `dev` to the Beta Branch
|
|
||||||
|
|
||||||
TODO
|
|
||||||
|
|
||||||
## Development Workflow Best Practices
|
|
||||||
|
|
||||||
- Work in a new branch forked from the `dev` branch to isolate your new code
|
|
||||||
- Keep code-changes on a branch as small as possible. This makes it easier for code review. Each branch should be its own independent feature.
|
|
||||||
- Regularly rebase your branch against `dev` to make sure you have the latest updates pulled.
|
|
||||||
- When merging, always merge your branch into `dev`. When releasing a new update, then merge `dev` into `master`
|
|
BIN
doc/source/advancedgameplay/batch.png
Normal file
BIN
doc/source/advancedgameplay/batch.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 50 KiB |
143
doc/source/advancedgameplay/hackingalgorithms.rst
Normal file
143
doc/source/advancedgameplay/hackingalgorithms.rst
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
|
||||||
|
|
||||||
|
Hacking algorithms
|
||||||
|
==================
|
||||||
|
|
||||||
|
There are 3 main family of hacking algorithms. This guide will go over each of them and give advice on how to
|
||||||
|
implement them.
|
||||||
|
|
||||||
|
Self-contained algorithms
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
Implementation difficulty: Easy
|
||||||
|
|
||||||
|
pros:
|
||||||
|
|
||||||
|
* Easy to implement
|
||||||
|
* Does not require other scripts to work
|
||||||
|
* Works at any stage of the game
|
||||||
|
|
||||||
|
cons:
|
||||||
|
|
||||||
|
* Limits income generation
|
||||||
|
* Very inefficient with ram
|
||||||
|
* Makes poor use of your script online time.
|
||||||
|
|
||||||
|
This family of algorithms are the simplest to implement they are called self-contained because a single script
|
||||||
|
contains everything needed to maintain a constant flow of money.
|
||||||
|
|
||||||
|
The general logic goes like this:
|
||||||
|
|
||||||
|
.. code-block:: javascript
|
||||||
|
|
||||||
|
for ever {
|
||||||
|
if security is not minimum {
|
||||||
|
weaken(target)
|
||||||
|
} else if money is not maximum {
|
||||||
|
grow(target)
|
||||||
|
} else {
|
||||||
|
hack(target)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
This is a perfectly fine algorithm to start with and can get you through most of the game. But it does have
|
||||||
|
some very serious issues.
|
||||||
|
|
||||||
|
- It tends to make all your scripts on every server do the same thing.
|
||||||
|
This means if you are 0.01 security above minimum most scripts will be doing a weaken when only a
|
||||||
|
handful of thread should be.
|
||||||
|
- At higher thread count it can drain a server of all it's money in 1 hack(). Recovering from $0 is
|
||||||
|
possible but extremely slow.
|
||||||
|
- It makes very poor use of the servers RAM. To implement this you will need to call functions like
|
||||||
|
getServerSecurityLevel and that functions ram cost will be multiplied by the number of thread.
|
||||||
|
|
||||||
|
loop algorithms
|
||||||
|
---------------
|
||||||
|
|
||||||
|
Implementation difficulty: Easy to Medium.
|
||||||
|
|
||||||
|
pros:
|
||||||
|
|
||||||
|
* Simple to understand
|
||||||
|
* Works at any stage of the game
|
||||||
|
* Maximize RAM usage.
|
||||||
|
|
||||||
|
cons:
|
||||||
|
|
||||||
|
* Support scripts are required to make things easy.
|
||||||
|
|
||||||
|
We can kill 2 birds with 1 stone from the previous algorithm by splitting our 3 main functions into 3 files
|
||||||
|
|
||||||
|
.. code-block:: javascript
|
||||||
|
|
||||||
|
for ever {
|
||||||
|
hack(target) // or grow, or weaken
|
||||||
|
}
|
||||||
|
|
||||||
|
Now we take the total amount of thread available and split it. We allocate:
|
||||||
|
- 1 part to the hack script.
|
||||||
|
- 10 part to the grow script.
|
||||||
|
- 2 part to the weaken script.
|
||||||
|
|
||||||
|
Meaning if we have room for 100 thread across all network 7 thread will go to hack, 76 thread to grow and 15 to weaken.
|
||||||
|
These ratios are arbitrary and can be improved but this is generally a good idea.
|
||||||
|
|
||||||
|
Carefull when applying this algorithm that you monitor the amount of money in the server, it should hover around maximum.
|
||||||
|
For that reason it may be wise to start the hack script later than the grow / weaken. If you find that the ratio is not
|
||||||
|
right feel free to modify it.
|
||||||
|
|
||||||
|
To some extent it's better to split the grow processes into smaller parts.
|
||||||
|
4 process with 20 thread each is better than 1 process with 80 threads.
|
||||||
|
|
||||||
|
It can be useful to add a delay to your scripts in order to prevent them from all starting at the same time.
|
||||||
|
The sleep function has no RAM cost.
|
||||||
|
|
||||||
|
batch algorithms (aka hwgw or cycles)
|
||||||
|
-------------------------------------
|
||||||
|
|
||||||
|
Implementation difficulty: Hard
|
||||||
|
|
||||||
|
pros:
|
||||||
|
|
||||||
|
* Maximize money
|
||||||
|
|
||||||
|
cons:
|
||||||
|
|
||||||
|
* Very hard to implement
|
||||||
|
* Does not work well without a large player bought server.
|
||||||
|
|
||||||
|
Batch algorithms are so called because you have a master script that `exec` a lot of other scripts in batches.
|
||||||
|
|
||||||
|
The basic building blocks are even simpler than the previous algorithm but a controller is required and is much
|
||||||
|
more complex.
|
||||||
|
|
||||||
|
.. code-block:: javascript
|
||||||
|
|
||||||
|
sleep(a bit)
|
||||||
|
hack(target) // or grow, or weaken
|
||||||
|
|
||||||
|
We need to know a couple of things before we can implement this algorithm.
|
||||||
|
|
||||||
|
- The effect of hack / grow depends on the server security.
|
||||||
|
- The time it takes for hack/grow/weaken takes to complete is determined when the
|
||||||
|
function is called but the effect is calculated at the end.
|
||||||
|
|
||||||
|
A batch consist of a set of 4 special process
|
||||||
|
|
||||||
|
1. A hack script that will remove a predefined, precalculated amount of money from the server.
|
||||||
|
2. A weaken script that counters the security increase of the hack process.
|
||||||
|
3. A grow script that counters the money decrease of the hack process.
|
||||||
|
4. A weaken script that counters the security increase of the grow process.
|
||||||
|
|
||||||
|
It is also important that these 4 scripts finish in the order specified. Hence why you need a delay in your script.
|
||||||
|
It's possible to make a batch with 3 scripts (hgw) but that it less efficient as the effectiveness of `grow` is based off server security.
|
||||||
|
|
||||||
|
Here's a picture demonstrating batch in action.
|
||||||
|
|
||||||
|
.. image:: batch.png
|
||||||
|
|
||||||
|
For batches to work the server needs to be at max money and min security. It is possible to use batches
|
||||||
|
to reach max money and min sec, just don't use any hack in your cycles.
|
||||||
|
|
||||||
|
The time set between each script ending cannot be tighter than 20ms as this is the best the javascript engine can do.
|
||||||
|
|
@ -16,6 +16,10 @@ cp main.css .package/main.css
|
|||||||
cp dist/vendor.bundle.js .package/dist/vendor.bundle.js
|
cp dist/vendor.bundle.js .package/dist/vendor.bundle.js
|
||||||
cp main.bundle.js .package/main.bundle.js
|
cp main.bundle.js .package/main.bundle.js
|
||||||
|
|
||||||
|
# Source maps
|
||||||
|
cp dist/vendor.bundle.js.map .package/dist/vendor.bundle.js.map
|
||||||
|
cp main.bundle.js.map .package/main.bundle.js.map
|
||||||
|
|
||||||
# Install electron sub-dependencies
|
# Install electron sub-dependencies
|
||||||
cd electron
|
cd electron
|
||||||
npm install
|
npm install
|
||||||
|
@ -89,7 +89,8 @@ export const ConsoleHelpText: {
|
|||||||
"Note that the name of the skill is case-sensitive. Enter it exactly as seen in the UI. If " +
|
"Note that the name of the skill is case-sensitive. Enter it exactly as seen in the UI. If " +
|
||||||
"the name of the skill has whitespace, enclose the name of the skill in double quotation marks:",
|
"the name of the skill has whitespace, enclose the name of the skill in double quotation marks:",
|
||||||
"",
|
"",
|
||||||
" skill list Reaper<br>" + " skill list 'Digital Observer'",
|
" skill list Reaper",
|
||||||
|
" skill list 'Digital Observer'",
|
||||||
"",
|
"",
|
||||||
"This console command can also be used to level up skills:",
|
"This console command can also be used to level up skills:",
|
||||||
"",
|
"",
|
||||||
|
@ -138,6 +138,7 @@ export function Console(props: IProps): React.ReactElement {
|
|||||||
paddingBottom: '8px',
|
paddingBottom: '8px',
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
alignItems: 'stretch',
|
alignItems: 'stretch',
|
||||||
|
whiteSpace: 'pre-wrap',
|
||||||
}}>
|
}}>
|
||||||
<Box>
|
<Box>
|
||||||
<Logs entries={[...props.bladeburner.consoleLogs]} />
|
<Logs entries={[...props.bladeburner.consoleLogs]} />
|
||||||
|
@ -22,7 +22,8 @@ export function makeRuntimeRejectMsg(workerScript: WorkerScript, msg: string): s
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (const scriptUrl of workerScript.scriptRef.dependencies) {
|
for (const scriptUrl of workerScript.scriptRef.dependencies) {
|
||||||
msg = msg.replace(new RegExp(scriptUrl.url, "g"), scriptUrl.filename);
|
// Return just the original msg if it's nullish so that we don't get a workerscript error
|
||||||
|
msg = msg?.replace(new RegExp(scriptUrl.url, "g"), scriptUrl.filename) ?? msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
return "|DELIMITER|" + server.hostname + "|DELIMITER|" + workerScript.name + "|DELIMITER|" + msg;
|
return "|DELIMITER|" + server.hostname + "|DELIMITER|" + workerScript.name + "|DELIMITER|" + msg;
|
||||||
|
@ -1639,7 +1639,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
|
|||||||
|
|
||||||
const cost = getPurchaseServerCost(ram);
|
const cost = getPurchaseServerCost(ram);
|
||||||
if (cost === Infinity) {
|
if (cost === Infinity) {
|
||||||
workerScript.log("purchaseServer", () => `Invalid argument: ram='${ram}' must be power of 2`);
|
workerScript.log("purchaseServer", () => `Invalid argument: ram='${ram}' must be a positive power of 2`);
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
|
export type WordWrapOptions = 'on' | 'off' | 'bounded' | 'wordWrapColumn';
|
||||||
export interface Options {
|
export interface Options {
|
||||||
theme: string;
|
theme: string;
|
||||||
insertSpaces: boolean;
|
insertSpaces: boolean;
|
||||||
fontSize: number;
|
fontSize: number;
|
||||||
|
wordWrap: WordWrapOptions;
|
||||||
vim: boolean;
|
vim: boolean;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { Options } from "./Options";
|
import { Options, WordWrapOptions } from "./Options";
|
||||||
import { Modal } from "../../ui/React/Modal";
|
import { Modal } from "../../ui/React/Modal";
|
||||||
|
|
||||||
import Button from "@mui/material/Button";
|
import Button from "@mui/material/Button";
|
||||||
@ -21,6 +21,7 @@ export function OptionsModal(props: IProps): React.ReactElement {
|
|||||||
const [theme, setTheme] = useState(props.options.theme);
|
const [theme, setTheme] = useState(props.options.theme);
|
||||||
const [insertSpaces, setInsertSpaces] = useState(props.options.insertSpaces);
|
const [insertSpaces, setInsertSpaces] = useState(props.options.insertSpaces);
|
||||||
const [fontSize, setFontSize] = useState(props.options.fontSize);
|
const [fontSize, setFontSize] = useState(props.options.fontSize);
|
||||||
|
const [wordWrap, setWordWrap] = useState(props.options.wordWrap);
|
||||||
const [vim, setVim] = useState(props.options.vim);
|
const [vim, setVim] = useState(props.options.vim);
|
||||||
|
|
||||||
function save(): void {
|
function save(): void {
|
||||||
@ -28,6 +29,7 @@ export function OptionsModal(props: IProps): React.ReactElement {
|
|||||||
theme,
|
theme,
|
||||||
insertSpaces,
|
insertSpaces,
|
||||||
fontSize,
|
fontSize,
|
||||||
|
wordWrap,
|
||||||
vim,
|
vim,
|
||||||
});
|
});
|
||||||
props.onClose();
|
props.onClose();
|
||||||
@ -50,6 +52,7 @@ export function OptionsModal(props: IProps): React.ReactElement {
|
|||||||
<MenuItem value="vs-dark">dark</MenuItem>
|
<MenuItem value="vs-dark">dark</MenuItem>
|
||||||
<MenuItem value="light">light</MenuItem>
|
<MenuItem value="light">light</MenuItem>
|
||||||
<MenuItem value="dracula">dracula</MenuItem>
|
<MenuItem value="dracula">dracula</MenuItem>
|
||||||
|
<MenuItem value="one-dark">one-dark</MenuItem>
|
||||||
</Select>
|
</Select>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
@ -58,6 +61,16 @@ export function OptionsModal(props: IProps): React.ReactElement {
|
|||||||
<Switch onChange={(event) => setInsertSpaces(event.target.checked)} checked={insertSpaces} />
|
<Switch onChange={(event) => setInsertSpaces(event.target.checked)} checked={insertSpaces} />
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
|
<Box display="flex" flexDirection="row" alignItems="center">
|
||||||
|
<Typography>Word Wrap: </Typography>
|
||||||
|
<Select onChange={(event) => setWordWrap(event.target.value as WordWrapOptions)} value={wordWrap}>
|
||||||
|
<MenuItem value={"off"}>Off</MenuItem>
|
||||||
|
<MenuItem value={"on"}>On</MenuItem>
|
||||||
|
<MenuItem value={"bounded"}>Bounded</MenuItem>
|
||||||
|
<MenuItem value={"wordWrapColumn"}>Word Wrap Column</MenuItem>
|
||||||
|
</Select>
|
||||||
|
</Box>
|
||||||
|
|
||||||
<Box display="flex" flexDirection="row" alignItems="center">
|
<Box display="flex" flexDirection="row" alignItems="center">
|
||||||
<Typography>Enable vim mode: </Typography>
|
<Typography>Enable vim mode: </Typography>
|
||||||
<Switch onChange={(event) => setVim(event.target.checked)} checked={vim} />
|
<Switch onChange={(event) => setVim(event.target.checked)} checked={vim} />
|
||||||
|
@ -117,6 +117,7 @@ export function Root(props: IProps): React.ReactElement {
|
|||||||
theme: Settings.MonacoTheme,
|
theme: Settings.MonacoTheme,
|
||||||
insertSpaces: Settings.MonacoInsertSpaces,
|
insertSpaces: Settings.MonacoInsertSpaces,
|
||||||
fontSize: Settings.MonacoFontSize,
|
fontSize: Settings.MonacoFontSize,
|
||||||
|
wordWrap: Settings.MonacoWordWrap,
|
||||||
vim: props.vim || Settings.MonacoVim,
|
vim: props.vim || Settings.MonacoVim,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -794,6 +795,7 @@ export function Root(props: IProps): React.ReactElement {
|
|||||||
theme: Settings.MonacoTheme,
|
theme: Settings.MonacoTheme,
|
||||||
insertSpaces: Settings.MonacoInsertSpaces,
|
insertSpaces: Settings.MonacoInsertSpaces,
|
||||||
fontSize: Settings.MonacoFontSize,
|
fontSize: Settings.MonacoFontSize,
|
||||||
|
wordWrap: Settings.MonacoWordWrap,
|
||||||
vim: Settings.MonacoVim,
|
vim: Settings.MonacoVim,
|
||||||
}}
|
}}
|
||||||
save={(options: Options) => {
|
save={(options: Options) => {
|
||||||
@ -801,6 +803,7 @@ export function Root(props: IProps): React.ReactElement {
|
|||||||
Settings.MonacoTheme = options.theme;
|
Settings.MonacoTheme = options.theme;
|
||||||
Settings.MonacoInsertSpaces = options.insertSpaces;
|
Settings.MonacoInsertSpaces = options.insertSpaces;
|
||||||
Settings.MonacoFontSize = options.fontSize;
|
Settings.MonacoFontSize = options.fontSize;
|
||||||
|
Settings.MonacoWordWrap = options.wordWrap;
|
||||||
Settings.MonacoVim = options.vim;
|
Settings.MonacoVim = options.vim;
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
@ -218,6 +218,7 @@ export async function loadThemes(monaco: { editor: any }): Promise<void> {
|
|||||||
"editor.selectionHighlightBorder": "#073642",
|
"editor.selectionHighlightBorder": "#073642",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
monaco.editor.defineTheme("dracula", {
|
monaco.editor.defineTheme("dracula", {
|
||||||
base: "vs-dark",
|
base: "vs-dark",
|
||||||
inherit: true,
|
inherit: true,
|
||||||
@ -313,4 +314,94 @@ export async function loadThemes(monaco: { editor: any }): Promise<void> {
|
|||||||
"editor.snippetFinalTabstopHighlightBorder": "#50FA7B",
|
"editor.snippetFinalTabstopHighlightBorder": "#50FA7B",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
monaco.editor.defineTheme("one-dark", {
|
||||||
|
base: "vs-dark",
|
||||||
|
inherit: true,
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
token: "",
|
||||||
|
background: "333842",
|
||||||
|
foreground: "ABB2BF",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
token: "comment",
|
||||||
|
foreground: "5C6370",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
token: "string",
|
||||||
|
foreground: "98C379",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
token: "number",
|
||||||
|
foreground: "D19A66",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
token: "function",
|
||||||
|
foreground: "C678DD",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
token: "keyword",
|
||||||
|
foreground: "C678DD",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
token: "otherkeyvars",
|
||||||
|
foreground: "D19A66",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
token: "otherkeywords",
|
||||||
|
foreground: "C678DD",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
token: "ns",
|
||||||
|
foreground: "E06C75",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
token: "netscriptfunction",
|
||||||
|
foreground: "61AFEF",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
token: "type.identifier",
|
||||||
|
foreground: "E5C07B",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
token: "delimiter",
|
||||||
|
foreground: "ABB2BF",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
token: "this",
|
||||||
|
foreground: "E06C75",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
colors: {
|
||||||
|
"editor.background": "#282C34",
|
||||||
|
"editor.foreground": "#ABB2BF",
|
||||||
|
"editor.lineHighlightBackground": "#99BBFF0A",
|
||||||
|
"editor.selectionBackground": "#3E4451",
|
||||||
|
"editor.findMatchHighlightBackground": "#528BFF3D",
|
||||||
|
"editorCursor.foreground": "#528BFF",
|
||||||
|
"editorHoverWidget.background": "#21252B",
|
||||||
|
"editorHoverWidget.border": "#181A1F",
|
||||||
|
"editorIndentGuide.background": "#ABB2BF26",
|
||||||
|
"editorIndentGuide.activeBackground": "#626772",
|
||||||
|
"editorLineNumber.foreground": "#636D83",
|
||||||
|
"editorLineNumber.activeForeground": "#ABB2BF",
|
||||||
|
"editorSuggestWidget.background": "#21252B",
|
||||||
|
"editorSuggestWidget.border": "#181A1F",
|
||||||
|
"editorSuggestWidget.selectedBackground": "#2C313A",
|
||||||
|
"editorWhitespace.foreground": "#ABB2BF26",
|
||||||
|
"editorWidget.background": "#21252B",
|
||||||
|
"editorWidget.border": "#3A3F4B",
|
||||||
|
"input.background": "#1B1D23",
|
||||||
|
"input.border": "#181A1F",
|
||||||
|
"peekView.border": "#528BFF",
|
||||||
|
"peekViewResult.background": "#21252B",
|
||||||
|
"peekViewResult.selectionBackground": "#2C313A",
|
||||||
|
"peekViewTitle.background": "#1B1D23",
|
||||||
|
"peekViewEditor.background": "#1B1D23",
|
||||||
|
"scrollbarSlider.background": "#4E566680",
|
||||||
|
"scrollbarSlider.activeBackground": "#747D9180",
|
||||||
|
"scrollbarSlider.hoverBackground": "#5A637580",
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ import { isPowerOfTwo } from "../utils/helpers/isPowerOfTwo";
|
|||||||
*/
|
*/
|
||||||
export function getPurchaseServerCost(ram: number): number {
|
export function getPurchaseServerCost(ram: number): number {
|
||||||
const sanitizedRam = Math.round(ram);
|
const sanitizedRam = Math.round(ram);
|
||||||
if (isNaN(sanitizedRam) || !isPowerOfTwo(sanitizedRam)) {
|
if (isNaN(sanitizedRam) || !isPowerOfTwo(sanitizedRam) || !(Math.sign(sanitizedRam) === 1)) {
|
||||||
return Infinity;
|
return Infinity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { ISelfInitializer, ISelfLoading } from "../types";
|
import { ISelfInitializer, ISelfLoading } from "../types";
|
||||||
import { OwnedAugmentationsOrderSetting, PurchaseAugmentationsOrderSetting } from "./SettingEnums";
|
import { OwnedAugmentationsOrderSetting, PurchaseAugmentationsOrderSetting } from "./SettingEnums";
|
||||||
import { defaultTheme, ITheme } from "./Themes";
|
import { defaultTheme, ITheme } from "./Themes";
|
||||||
|
import { WordWrapOptions } from '../ScriptEditor/ui/Options';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents the default settings the player could customize.
|
* Represents the default settings the player could customize.
|
||||||
@ -141,6 +142,8 @@ interface ISettings extends IDefaultSettings {
|
|||||||
MonacoFontSize: number;
|
MonacoFontSize: number;
|
||||||
|
|
||||||
MonacoVim: boolean;
|
MonacoVim: boolean;
|
||||||
|
|
||||||
|
MonacoWordWrap: WordWrapOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const defaultSettings: IDefaultSettings = {
|
export const defaultSettings: IDefaultSettings = {
|
||||||
@ -203,6 +206,7 @@ export const Settings: ISettings & ISelfInitializer & ISelfLoading = {
|
|||||||
MonacoInsertSpaces: false,
|
MonacoInsertSpaces: false,
|
||||||
MonacoFontSize: 20,
|
MonacoFontSize: 20,
|
||||||
MonacoVim: false,
|
MonacoVim: false,
|
||||||
|
MonacoWordWrap: 'off',
|
||||||
|
|
||||||
theme: { ...defaultTheme },
|
theme: { ...defaultTheme },
|
||||||
init() {
|
init() {
|
||||||
|
Loading…
Reference in New Issue
Block a user