mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2025-03-26 20:22:28 +01:00
Added BitNode multipliers for purchased servers. Fixed bugs in new Script Editor implementation. Added documentation for script editors
This commit is contained in:
css
dist
doc/source
index.htmlsrc
BitNode
Constants.tsFaction
InteractiveTutorial.jsLocation.jsNetscriptFunctions.jsPersonObjects/Sleeve
Player.jsScript.jsScriptEditor
ServerPurchases.jsSettings
engine.jsindex.htmlui/MainMenu
utils/uiHelpers
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
#codemirror-form-wrapper {
|
#codemirror-form-wrapper {
|
||||||
height: 80%;
|
height: 80%;
|
||||||
margin: 10px 0px 10px 6px;
|
margin: 10px 0px 0px 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.CodeMirror {
|
.CodeMirror {
|
||||||
@ -29,7 +29,6 @@
|
|||||||
background-color: #8F908A;
|
background-color: #8F908A;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show Invisibles
|
* Show Invisibles
|
||||||
*/
|
*/
|
||||||
@ -38,3 +37,13 @@
|
|||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
color: #404F7D;
|
color: #404F7D;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vim command display
|
||||||
|
*/
|
||||||
|
#codemirror-vim-command-display-wrapper {
|
||||||
|
background-color: white;
|
||||||
|
font-size: 13px;
|
||||||
|
height: 30px;
|
||||||
|
margin-left: 6px;
|
||||||
|
}
|
||||||
|
@ -93,6 +93,7 @@
|
|||||||
overflow: auto;
|
overflow: auto;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
|
max-height: 50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
#script-editor-options-panel fieldset {
|
#script-editor-options-panel fieldset {
|
||||||
|
3284
dist/engine.bundle.js
vendored
3284
dist/engine.bundle.js
vendored
File diff suppressed because it is too large
Load Diff
14
dist/engine.css
vendored
14
dist/engine.css
vendored
@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
#codemirror-form-wrapper {
|
#codemirror-form-wrapper {
|
||||||
height: 80%;
|
height: 80%;
|
||||||
margin: 10px 0px 10px 6px; }
|
margin: 10px 0px 0px 6px; }
|
||||||
|
|
||||||
.CodeMirror {
|
.CodeMirror {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
@ -32,6 +32,15 @@
|
|||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
color: #404F7D; }
|
color: #404F7D; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vim command display
|
||||||
|
*/
|
||||||
|
#codemirror-vim-command-display-wrapper {
|
||||||
|
background-color: white;
|
||||||
|
font-size: 13px;
|
||||||
|
height: 30px;
|
||||||
|
margin-left: 6px; }
|
||||||
|
|
||||||
/* COLORS */
|
/* COLORS */
|
||||||
/* Attributes */
|
/* Attributes */
|
||||||
/* COLORS */
|
/* COLORS */
|
||||||
@ -886,7 +895,8 @@ button {
|
|||||||
padding: 2px;
|
padding: 2px;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
color: #fff; }
|
color: #fff;
|
||||||
|
max-height: 50%; }
|
||||||
|
|
||||||
#script-editor-options-panel fieldset {
|
#script-editor-options-panel fieldset {
|
||||||
margin-top: 8px;
|
margin-top: 8px;
|
||||||
|
1855
dist/vendor.bundle.js
vendored
1855
dist/vendor.bundle.js
vendored
File diff suppressed because one or more lines are too long
29
dist/vendor.css
vendored
29
dist/vendor.css
vendored
@ -5383,6 +5383,35 @@ THE SOFTWARE.
|
|||||||
.cm-s-zenburn .CodeMirror-focused div.CodeMirror-selected {
|
.cm-s-zenburn .CodeMirror-focused div.CodeMirror-selected {
|
||||||
background: #4f4f4f; }
|
background: #4f4f4f; }
|
||||||
|
|
||||||
|
.CodeMirror-dialog {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
background: inherit;
|
||||||
|
z-index: 15;
|
||||||
|
padding: .1em .8em;
|
||||||
|
overflow: hidden;
|
||||||
|
color: inherit; }
|
||||||
|
|
||||||
|
.CodeMirror-dialog-top {
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
top: 0; }
|
||||||
|
|
||||||
|
.CodeMirror-dialog-bottom {
|
||||||
|
border-top: 1px solid #eee;
|
||||||
|
bottom: 0; }
|
||||||
|
|
||||||
|
.CodeMirror-dialog input {
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
background: transparent;
|
||||||
|
width: 20em;
|
||||||
|
color: inherit;
|
||||||
|
font-family: monospace; }
|
||||||
|
|
||||||
|
.CodeMirror-dialog button {
|
||||||
|
font-size: 70%; }
|
||||||
|
|
||||||
.CodeMirror-foldmarker {
|
.CodeMirror-foldmarker {
|
||||||
color: blue;
|
color: blue;
|
||||||
text-shadow: #b9f 1px 1px 2px, #b9f -1px -1px 2px, #b9f 1px -1px 2px, #b9f -1px 1px 2px;
|
text-shadow: #b9f 1px 1px 2px, #b9f -1px -1px 2px, #b9f 1px -1px 2px, #b9f -1px 1px 2px;
|
||||||
|
@ -23,6 +23,7 @@ secrets that you've been searching for.
|
|||||||
Basic Gameplay <basicgameplay>
|
Basic Gameplay <basicgameplay>
|
||||||
Advanced Gameplay <advancedgameplay>
|
Advanced Gameplay <advancedgameplay>
|
||||||
Keyboard Shortcuts <shortcuts>
|
Keyboard Shortcuts <shortcuts>
|
||||||
|
Script Editors <scripteditors>
|
||||||
Game Frozen or Stuck? <gamefrozen>
|
Game Frozen or Stuck? <gamefrozen>
|
||||||
Changelog <changelog>
|
Changelog <changelog>
|
||||||
|
|
||||||
|
140
doc/source/scripteditors.rst
Normal file
140
doc/source/scripteditors.rst
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
.. _scripteditors:
|
||||||
|
|
||||||
|
Script Editors
|
||||||
|
==============
|
||||||
|
Third-party libraries are used to implement the game's Script Editor(s). There are
|
||||||
|
currently two options for the Script Editor:
|
||||||
|
|
||||||
|
* `Ace <https://ace.c9.io/>`_
|
||||||
|
* `CodeMirror <https://codemirror.net/>`_
|
||||||
|
|
||||||
|
You can select which of the two editors you want to use on the Script Editor page
|
||||||
|
('Create Script' on the main menu).
|
||||||
|
|
||||||
|
Ace was the game's original Script Editor, while CodeMirror was added later in
|
||||||
|
v0.43.0. The two editors share many of the same features, so there is not a significant
|
||||||
|
difference between the two. Currently, CodeMirror is slightly more modern,
|
||||||
|
more customizable, and has a few quality-of-life improvements compared to Ace.
|
||||||
|
|
||||||
|
Universal Key Bindings
|
||||||
|
----------------------
|
||||||
|
These keyboard shortcuts are available in both the Ace and CodeMirror editors, regardless
|
||||||
|
of what key binding option you are using:
|
||||||
|
|
||||||
|
============= ===========================================================================
|
||||||
|
Shortcut Action
|
||||||
|
============= ===========================================================================
|
||||||
|
Ctrl + b Save script and return to :ref:`terminal`
|
||||||
|
Ctrl + space Show Autocomplete Hints
|
||||||
|
============= ===========================================================================
|
||||||
|
|
||||||
|
.. _scripteditor_linter:
|
||||||
|
|
||||||
|
Linter
|
||||||
|
------
|
||||||
|
Both script editors contain a linter, which is a tool that analyzes your
|
||||||
|
code and flags anything it thinks might be an error. You can see
|
||||||
|
warnings and errors from the linter on the left-hand side of the script editor. There
|
||||||
|
will be an icon on whatever lines the linter thinks might be problematic. Hovering
|
||||||
|
over the icon will display information on what the issue is.
|
||||||
|
|
||||||
|
Note that **just because the linter shows an error/warning, this does NOT automatically mean that**
|
||||||
|
**your script is broken and will fail to run.** This is especially true if you are using
|
||||||
|
:ref:`netscriptjs`. The linter used by the script editors isn't necessarily perfect or
|
||||||
|
up-to-date. Furthermore, the linter does not affect anything when you actually run scripts.
|
||||||
|
|
||||||
|
Ace
|
||||||
|
---
|
||||||
|
The following documents what the different settings/options do for the Ace editor,
|
||||||
|
as well as the different key binding settings. Note that the
|
||||||
|
information for the key bindings may not be completely comprehensive. You'll
|
||||||
|
have to dig into the editor source code if you want to learn more.
|
||||||
|
|
||||||
|
Settings
|
||||||
|
~~~~~~~~
|
||||||
|
|
||||||
|
===================== ===========================================================================================================
|
||||||
|
Setting Effect
|
||||||
|
===================== ===========================================================================================================
|
||||||
|
Theme Switch between different color schemes
|
||||||
|
Key Binding Switch between different key binding options. This changes what keyboard shortcuts are available
|
||||||
|
Highlight Active Line When enabled, the line on which the cursor currently resides will be highlighted.
|
||||||
|
Show Invisibles When enabled, you will be able to view hidden whitespace characters such as spaces, tabs, and newlines.
|
||||||
|
Use Soft Tab When enabled, tabs will be replaced with spaces
|
||||||
|
Max Error Count Specifies the (approximate) number of lines that will be linted
|
||||||
|
===================== ===========================================================================================================
|
||||||
|
|
||||||
|
Ace Key Bindings
|
||||||
|
~~~~~~~~~~~~~~~~
|
||||||
|
For Ace, the "Ace" Key Binding setting uses the default configuration. A list of these
|
||||||
|
`can be found here <https://github.com/ajaxorg/ace/wiki/Default-Keyboard-Shortcuts>`_.
|
||||||
|
|
||||||
|
Vim Key Bindings
|
||||||
|
~~~~~~~~~~~~~~~~
|
||||||
|
For Ace, the "Vim" Key Binding setting configures the editor to use
|
||||||
|
`Vim <https://en.wikipedia.org/wiki/Vim_(text_editor)>`_ key mappings. Note that while this tries
|
||||||
|
to emulate Vim features as faithfully as possible, it is not a complete Vim implementation.
|
||||||
|
|
||||||
|
Since I'm not familiar with Vim, I'll leave
|
||||||
|
`Ace's Vim Mode implementation here <https://github.com/ajaxorg/ace/blob/96088d0fc292daf0706b2d029cc03c3799be5974/lib/ace/keyboard/vim.js#L860>`_,
|
||||||
|
which I believe shows most of the implemented features.
|
||||||
|
|
||||||
|
Note that the following Vim Ex commands will properly save the script and/or quit the editor in game:
|
||||||
|
|
||||||
|
======= ==============================================
|
||||||
|
Command Effect
|
||||||
|
======= ==============================================
|
||||||
|
:w Save the script and return to :ref:`terminal`
|
||||||
|
:q Return to :ref:`terminal` **WITHOUT** saving
|
||||||
|
:x Save the script and return to :ref:`terminal`
|
||||||
|
:wq Save the script and return to :ref:`terminal`
|
||||||
|
======= ==============================================
|
||||||
|
|
||||||
|
Emacs Key Bindings
|
||||||
|
~~~~~~~~~~~~~~~~~~
|
||||||
|
For Ace, the "Emacs" Key Binding setting configures the editor to use
|
||||||
|
`Emacs <https://en.wikipedia.org/wiki/Emacs>`_ key mappings. Note that while this tries
|
||||||
|
to emulate the Emacs key mappings as faithfully as possible, it won't necessarily be a
|
||||||
|
complete implementation.
|
||||||
|
|
||||||
|
Since I'm not familiar with Emacs, I'll leave
|
||||||
|
`Ace's Emacs Mode implementation here <https://github.com/ajaxorg/ace/blob/96088d0fc292daf0706b2d029cc03c3799be5974/lib/ace/keyboard/emacs.js#L343>`_,
|
||||||
|
which I believe shows most of the implemented features.
|
||||||
|
|
||||||
|
CodeMirror
|
||||||
|
----------
|
||||||
|
The following documents what the different settings/options do for the CodeMirror editor,
|
||||||
|
as well as the shortcuts for the different key binding settings. Note that the
|
||||||
|
information for the key bindings may not be completely comprehensive. You'll
|
||||||
|
have to dig into the editor source code if you want to learn everything.
|
||||||
|
|
||||||
|
Settings
|
||||||
|
~~~~~~~~
|
||||||
|
========================== ===========================================================================================================
|
||||||
|
Setting Effect
|
||||||
|
========================== ===========================================================================================================
|
||||||
|
Theme Switch between different color schemes
|
||||||
|
Key Binding Switch between different key binding options. This changes what keyboard shortcuts are available
|
||||||
|
Highlight Active Line When enabled, the line on which the cursor currently resides will be highlighted.
|
||||||
|
Show Invisibles When enabled, you will be able to view hidden whitespace characters such as spaces, tabs, and newlines.
|
||||||
|
Use Soft Tab When enabled, tabs will be replaced with spaces
|
||||||
|
Auto-Close Brackets/Quotes When enabled, any opening brackets or quotes that are typed will be closed
|
||||||
|
Enable Linting Enable/Disable the :ref:`scripteditor_linter`
|
||||||
|
Continue Comments When enabled, pressing 'Enter' inside a comment block will continue the comment on the next line
|
||||||
|
========================== ===========================================================================================================
|
||||||
|
|
||||||
|
Default Key Bindings
|
||||||
|
~~~~~~~~~~~~~~~~~~~~
|
||||||
|
.. todo:: Fill out
|
||||||
|
|
||||||
|
Sublime Key Bindings
|
||||||
|
~~~~~~~~~~~~~~~~~~~~
|
||||||
|
.. todo:: Fill out
|
||||||
|
|
||||||
|
Vim Key Bindings
|
||||||
|
~~~~~~~~~~~~~~~~
|
||||||
|
.. todo:: Fill out
|
||||||
|
|
||||||
|
Emacs Key Bindings
|
||||||
|
~~~~~~~~~~~~~~~~~~
|
||||||
|
.. todo:: Fill out
|
@ -35,20 +35,7 @@ Alt + o Switch to 'Options' page
|
|||||||
|
|
||||||
Script Editor
|
Script Editor
|
||||||
-------------
|
-------------
|
||||||
These shortcuts are available only in the Script Editor
|
See the :ref:`Script Editor <scripteditors>` documentation for more details.
|
||||||
|
|
||||||
============= ===========================================================================
|
|
||||||
Shortcut Action
|
|
||||||
============= ===========================================================================
|
|
||||||
Ctrl + b Save script and return to :ref:`terminal`
|
|
||||||
Ctrl + space Function autocompletion
|
|
||||||
============= ===========================================================================
|
|
||||||
|
|
||||||
In the Script Editor you can configure your key binding mode to three preset options:
|
|
||||||
|
|
||||||
* `Ace <https://github.com/ajaxorg/ace/wiki/Default-Keyboard-Shortcuts>`_
|
|
||||||
* Vim
|
|
||||||
* Emacs
|
|
||||||
|
|
||||||
Terminal Shortcuts
|
Terminal Shortcuts
|
||||||
------------------
|
------------------
|
||||||
@ -92,10 +79,13 @@ Alt + f Move cursor to next word
|
|||||||
Ctrl + h/d Delete previous character ('Backspace')
|
Ctrl + h/d Delete previous character ('Backspace')
|
||||||
============= ===========================================================================
|
============= ===========================================================================
|
||||||
|
|
||||||
Misc Shortcuts
|
Popup/Dialog Box Shortcuts
|
||||||
--------------
|
--------------------------
|
||||||
|
The following shortcuts work if there are any popup or dialog boxes on the screen.
|
||||||
|
|
||||||
============= ===========================================================================
|
============= ===========================================================================
|
||||||
Shortcut Action
|
Shortcut Action
|
||||||
============= ===========================================================================
|
============= ===========================================================================
|
||||||
Esc Close a script's log window
|
Esc Close the current popup, cancelling any prompts on a dialog box
|
||||||
|
Enter Clicks the "Yes/Confirm" option for every dialog box
|
||||||
============= ===========================================================================
|
============= ===========================================================================
|
||||||
|
@ -120,6 +120,9 @@
|
|||||||
|
|
||||||
<div id="ace-editor"></div>
|
<div id="ace-editor"></div>
|
||||||
<form id="codemirror-form-wrapper"><textarea id="codemirror-editor"></textarea></form>
|
<form id="codemirror-form-wrapper"><textarea id="codemirror-editor"></textarea></form>
|
||||||
|
<div id="codemirror-vim-command-display-wrapper">
|
||||||
|
Key Buffer: <span id="codemirror-vim-command-display"></span>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div id="script-editor-buttons-wrapper"></div> <!-- Buttons below script editor -->
|
<div id="script-editor-buttons-wrapper"></div> <!-- Buttons below script editor -->
|
||||||
</div> <!-- End wrapper -->
|
</div> <!-- End wrapper -->
|
||||||
|
@ -168,6 +168,7 @@ function initBitNodes() {
|
|||||||
"In this BitNode:<br><br>" +
|
"In this BitNode:<br><br>" +
|
||||||
"Your stats are significantly decreased.<br>" +
|
"Your stats are significantly decreased.<br>" +
|
||||||
"All methods of gaining money are half as profitable (except Stock Market)<br>" +
|
"All methods of gaining money are half as profitable (except Stock Market)<br>" +
|
||||||
|
"Purchased servers are more expensive, have less max RAM, and a lower maximum limit<br>" +
|
||||||
"Augmentations are 5x as expensive and require twice as much reputation<br><br>" +
|
"Augmentations are 5x as expensive and require twice as much reputation<br><br>" +
|
||||||
"Destroying this BitNode will give you Source-File 10, or if you already have this Source-File it will " +
|
"Destroying this BitNode will give you Source-File 10, or if you already have this Source-File it will " +
|
||||||
"upgrade its level up to a maximum of 3. This Source-File unlocks Sleeve technology in other BitNodes. " +
|
"upgrade its level up to a maximum of 3. This Source-File unlocks Sleeve technology in other BitNodes. " +
|
||||||
@ -337,6 +338,9 @@ function initBitNodeMultipliers() {
|
|||||||
BitNodeMultipliers.CorporationValuation = 0.5;
|
BitNodeMultipliers.CorporationValuation = 0.5;
|
||||||
BitNodeMultipliers.AugmentationMoneyCost = 5;
|
BitNodeMultipliers.AugmentationMoneyCost = 5;
|
||||||
BitNodeMultipliers.AugmentationRepCost = 2;
|
BitNodeMultipliers.AugmentationRepCost = 2;
|
||||||
|
BitNodeMultipliers.PurchasedServerCost = 5;
|
||||||
|
BitNodeMultipliers.PurchasedServerLimit = 0.6;
|
||||||
|
BitNodeMultipliers.PurchasedServerMaxRam = 0.5;
|
||||||
case 11: //The Big Crash
|
case 11: //The Big Crash
|
||||||
BitNodeMultipliers.ServerMaxMoney = 0.1;
|
BitNodeMultipliers.ServerMaxMoney = 0.1;
|
||||||
BitNodeMultipliers.ServerStartingMoney = 0.1;
|
BitNodeMultipliers.ServerStartingMoney = 0.1;
|
||||||
|
@ -125,6 +125,20 @@ interface IBitNodeMultipliers {
|
|||||||
*/
|
*/
|
||||||
ManualHackMoney: number;
|
ManualHackMoney: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Influence how much it costs to purchase a server
|
||||||
|
*/
|
||||||
|
PurchasedServerCost: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Influences the maximum number of purchased servers you can have
|
||||||
|
*/
|
||||||
|
PurchasedServerLimit: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Influences the maximum allowed RAM for a purchased server
|
||||||
|
*/
|
||||||
|
PurchasedServerMaxRam: number;
|
||||||
/**
|
/**
|
||||||
* Influences the minimum favor the player must have with a faction before they can donate to gain rep.
|
* Influences the minimum favor the player must have with a faction before they can donate to gain rep.
|
||||||
*/
|
*/
|
||||||
@ -184,6 +198,10 @@ export const BitNodeMultipliers: IBitNodeMultipliers = {
|
|||||||
ServerStartingSecurity: 1,
|
ServerStartingSecurity: 1,
|
||||||
ServerWeakenRate: 1,
|
ServerWeakenRate: 1,
|
||||||
|
|
||||||
|
PurchasedServerCost: 1,
|
||||||
|
PurchasedServerLimit: 1,
|
||||||
|
PurchasedServerMaxRam: 1,
|
||||||
|
|
||||||
CompanyWorkMoney: 1,
|
CompanyWorkMoney: 1,
|
||||||
CrimeMoney: 1,
|
CrimeMoney: 1,
|
||||||
HacknetNodeMoney: 1,
|
HacknetNodeMoney: 1,
|
||||||
|
@ -524,10 +524,11 @@ export let CONSTANTS: IMap<any> = {
|
|||||||
|
|
||||||
* Script Editor Changes:
|
* Script Editor Changes:
|
||||||
** Added new script editor: CodeMirror. You can choose between the old editor (Ace) or CodeMirror
|
** Added new script editor: CodeMirror. You can choose between the old editor (Ace) or CodeMirror
|
||||||
** Navigation keyboard shortcuts no longer work on the script editor page
|
** Navigation keyboard shortcuts no longer work if the script editor is focused
|
||||||
|
|
||||||
* Trying to programmatically run a script (run(), exec()) with a 'threads' argument of 0 will now cause the function to return false without running the script
|
* Trying to programmatically run a script (run(), exec()) with a 'threads' argument of 0 will now cause the function to return false without running the script
|
||||||
* Home Computer RAM is now capped at 2 ^ 30 GB (1073741824 GB)
|
* Home Computer RAM is now capped at 2 ^ 30 GB (1073741824 GB)
|
||||||
|
* The maximum amount, maximum RAM, and cost of purchasing servers can now vary between different BitNodes (new BitNode multipliers)
|
||||||
* Pop-up dialog boxes are a little bit bigger
|
* Pop-up dialog boxes are a little bit bigger
|
||||||
* Bug Fix: When importing scripts, "./" will now be properly ignored (e.g. import { foo } from "./lib.script" )
|
* Bug Fix: When importing scripts, "./" will now be properly ignored (e.g. import { foo } from "./lib.script" )
|
||||||
`
|
`
|
||||||
|
@ -481,7 +481,7 @@ function createFactionAugmentationDisplayElements(augmentationsList, augs, facti
|
|||||||
}
|
}
|
||||||
|
|
||||||
var item = createElement("li");
|
var item = createElement("li");
|
||||||
var span = createElement("span", {display:"inline-block"});
|
var span = createElement("span", { display:"inline-block", margin: "4px", padding: "4px" });
|
||||||
var aDiv = createElement("div", {tooltip:aug.info});
|
var aDiv = createElement("div", {tooltip:aug.info});
|
||||||
var aElem = createElement("a", {
|
var aElem = createElement("a", {
|
||||||
innerText:aug.name, display:"inline",
|
innerText:aug.name, display:"inline",
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
import {Engine} from "./engine";
|
import { Engine } from "./engine";
|
||||||
import {Player} from "./Player";
|
import { Player } from "./Player";
|
||||||
import {Settings} from "./Settings/Settings";
|
import { Settings } from "./Settings/Settings";
|
||||||
import {clearEventListeners} from "../utils/uiHelpers/clearEventListeners";
|
import { initializeMainMenuLinks } from "./ui/MainMenu/Links";
|
||||||
import {createElement} from "../utils/uiHelpers/createElement";
|
import { exceptionAlert } from "../utils/helpers/exceptionAlert";
|
||||||
import {createPopup} from "../utils/uiHelpers/createPopup";
|
import { clearEventListeners } from "../utils/uiHelpers/clearEventListeners";
|
||||||
import {removeElementById} from "../utils/uiHelpers/removeElementById";
|
import { createElement } from "../utils/uiHelpers/createElement";
|
||||||
|
import { createPopup } from "../utils/uiHelpers/createPopup";
|
||||||
|
import { removeElementById } from "../utils/uiHelpers/removeElementById";
|
||||||
|
|
||||||
//Ordered array of keys to Interactive Tutorial Steps
|
//Ordered array of keys to Interactive Tutorial Steps
|
||||||
const orderedITutorialSteps = [
|
const orderedITutorialSteps = [
|
||||||
@ -472,7 +474,19 @@ function iTutorialEnd() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
console.log("Ending interactive tutorial");
|
console.log("Ending interactive tutorial");
|
||||||
|
|
||||||
|
// Initialize references to main menu links
|
||||||
|
// We have to call initializeMainMenuLinks() again because the Interactive Tutorial
|
||||||
|
// re-creates Main menu links with clearEventListeners()
|
||||||
|
if (!initializeMainMenuLinks()) {
|
||||||
|
const errorMsg = "Failed to initialize Main Menu Links. Please try refreshing the page. " +
|
||||||
|
"If that doesn't work, report the issue to the developer";
|
||||||
|
exceptionAlert(new Error(errorMsg));
|
||||||
|
console.error(errorMsg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
Engine.init();
|
Engine.init();
|
||||||
|
|
||||||
ITutorial.currStep = iTutorialSteps.End;
|
ITutorial.currStep = iTutorialSteps.End;
|
||||||
ITutorial.isRunning = false;
|
ITutorial.isRunning = false;
|
||||||
document.getElementById("interactive-tutorial-container").style.display = "none";
|
document.getElementById("interactive-tutorial-container").style.display = "none";
|
||||||
|
@ -12,8 +12,9 @@ import {hasBladeburnerSF} from "./NetscriptFunctions";
|
|||||||
import {Locations} from "./Locations";
|
import {Locations} from "./Locations";
|
||||||
import {Player} from "./Player";
|
import {Player} from "./Player";
|
||||||
import {Server, AllServers, AddToAllServers} from "./Server";
|
import {Server, AllServers, AddToAllServers} from "./Server";
|
||||||
import {purchaseServer,
|
import { getPurchaseServerCost,
|
||||||
purchaseRamForHomeComputer} from "./ServerPurchases";
|
purchaseServer,
|
||||||
|
purchaseRamForHomeComputer} from "./ServerPurchases";
|
||||||
import {Settings} from "./Settings/Settings";
|
import {Settings} from "./Settings/Settings";
|
||||||
import { SourceFileFlags } from "./SourceFile/SourceFileFlags";
|
import { SourceFileFlags } from "./SourceFile/SourceFileFlags";
|
||||||
import {SpecialServerNames, SpecialServerIps} from "./SpecialServerIps";
|
import {SpecialServerNames, SpecialServerIps} from "./SpecialServerIps";
|
||||||
@ -191,16 +192,16 @@ function displayLocationContent() {
|
|||||||
purchaseHomeRam.style.display = "none";
|
purchaseHomeRam.style.display = "none";
|
||||||
purchaseHomeCores.style.display = "none";
|
purchaseHomeCores.style.display = "none";
|
||||||
|
|
||||||
purchase2gb.innerHTML = "Purchase 2GB Server - $" + formatNumber(2*CONSTANTS.BaseCostFor1GBOfRamServer, 2);
|
purchase2gb.innerHTML = "Purchase 2GB Server - " + numeralWrapper.formatMoney(getPurchaseServerCost(2));
|
||||||
purchase4gb.innerHTML = "Purchase 4GB Server - $" + formatNumber(4*CONSTANTS.BaseCostFor1GBOfRamServer, 2);
|
purchase4gb.innerHTML = "Purchase 4GB Server - " + numeralWrapper.formatMoney(getPurchaseServerCost(4));
|
||||||
purchase8gb.innerHTML = "Purchase 8GB Server - $" + formatNumber(8*CONSTANTS.BaseCostFor1GBOfRamServer, 2);
|
purchase8gb.innerHTML = "Purchase 8GB Server - " + numeralWrapper.formatMoney(getPurchaseServerCost(8));
|
||||||
purchase16gb.innerHTML = "Purchase 16GB Server - $" + formatNumber(16*CONSTANTS.BaseCostFor1GBOfRamServer, 2);
|
purchase16gb.innerHTML = "Purchase 16GB Server - " + numeralWrapper.formatMoney(getPurchaseServerCost(16));
|
||||||
purchase32gb.innerHTML = "Purchase 32GB Server - $" + formatNumber(32*CONSTANTS.BaseCostFor1GBOfRamServer, 2);
|
purchase32gb.innerHTML = "Purchase 32GB Server - " + numeralWrapper.formatMoney(getPurchaseServerCost(32));
|
||||||
purchase64gb.innerHTML = "Purchase 64GB Server - $" + formatNumber(64*CONSTANTS.BaseCostFor1GBOfRamServer, 2);
|
purchase64gb.innerHTML = "Purchase 64GB Server - " + numeralWrapper.formatMoney(getPurchaseServerCost(64));
|
||||||
purchase128gb.innerHTML = "Purchase 128GB Server - $" + formatNumber(128*CONSTANTS.BaseCostFor1GBOfRamServer, 2);
|
purchase128gb.innerHTML = "Purchase 128GB Server - " + numeralWrapper.formatMoney(getPurchaseServerCost(128));
|
||||||
purchase256gb.innerHTML = "Purchase 256GB Server - $" + formatNumber(256*CONSTANTS.BaseCostFor1GBOfRamServer, 2);
|
purchase256gb.innerHTML = "Purchase 256GB Server - " + numeralWrapper.formatMoney(getPurchaseServerCost(256));
|
||||||
purchase512gb.innerHTML = "Purchase 512GB Server - $" + formatNumber(512*CONSTANTS.BaseCostFor1GBOfRamServer, 2);
|
purchase512gb.innerHTML = "Purchase 512GB Server - " + numeralWrapper.formatMoney(getPurchaseServerCost(512));
|
||||||
purchase1tb.innerHTML = "Purchase 1TB Server - $" + formatNumber(1024*CONSTANTS.BaseCostFor1GBOfRamServer, 2);
|
purchase1tb.innerHTML = "Purchase 1TB Server - " + numeralWrapper.formatMoney(getPurchaseServerCost(1024));
|
||||||
if (!SpecialServerIps.hasOwnProperty("Darkweb Server")) {
|
if (!SpecialServerIps.hasOwnProperty("Darkweb Server")) {
|
||||||
purchaseTor.classList.add("a-link-button");
|
purchaseTor.classList.add("a-link-button");
|
||||||
purchaseTor.classList.remove("a-link-button-bought");
|
purchaseTor.classList.remove("a-link-button-bought");
|
||||||
@ -1726,61 +1727,61 @@ function initLocationButtons() {
|
|||||||
|
|
||||||
purchase2gb.addEventListener("click", function(e) {
|
purchase2gb.addEventListener("click", function(e) {
|
||||||
if (!e.isTrusted) {return false;}
|
if (!e.isTrusted) {return false;}
|
||||||
purchaseServerBoxCreate(2, 2 * CONSTANTS.BaseCostFor1GBOfRamServer);
|
purchaseServerBoxCreate(2);
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
purchase4gb.addEventListener("click", function(e) {
|
purchase4gb.addEventListener("click", function(e) {
|
||||||
if (!e.isTrusted) {return false;}
|
if (!e.isTrusted) {return false;}
|
||||||
purchaseServerBoxCreate(4, 4 * CONSTANTS.BaseCostFor1GBOfRamServer);
|
purchaseServerBoxCreate(4);
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
purchase8gb.addEventListener("click", function(e) {
|
purchase8gb.addEventListener("click", function(e) {
|
||||||
if (!e.isTrusted) {return false;}
|
if (!e.isTrusted) {return false;}
|
||||||
purchaseServerBoxCreate(8, 8 * CONSTANTS.BaseCostFor1GBOfRamServer);
|
purchaseServerBoxCreate(8);
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
purchase16gb.addEventListener("click", function(e) {
|
purchase16gb.addEventListener("click", function(e) {
|
||||||
if (!e.isTrusted) {return false;}
|
if (!e.isTrusted) {return false;}
|
||||||
purchaseServerBoxCreate(16, 16 * CONSTANTS.BaseCostFor1GBOfRamServer);
|
purchaseServerBoxCreate(16);
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
purchase32gb.addEventListener("click", function(e) {
|
purchase32gb.addEventListener("click", function(e) {
|
||||||
if (!e.isTrusted) {return false;}
|
if (!e.isTrusted) {return false;}
|
||||||
purchaseServerBoxCreate(32, 32 * CONSTANTS.BaseCostFor1GBOfRamServer);
|
purchaseServerBoxCreate(32);
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
purchase64gb.addEventListener("click", function(e) {
|
purchase64gb.addEventListener("click", function(e) {
|
||||||
if (!e.isTrusted) {return false;}
|
if (!e.isTrusted) {return false;}
|
||||||
purchaseServerBoxCreate(64, 64 * CONSTANTS.BaseCostFor1GBOfRamServer);
|
purchaseServerBoxCreate(64);
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
purchase128gb.addEventListener("click", function(e) {
|
purchase128gb.addEventListener("click", function(e) {
|
||||||
if (!e.isTrusted) {return false;}
|
if (!e.isTrusted) {return false;}
|
||||||
purchaseServerBoxCreate(128, 128 * CONSTANTS.BaseCostFor1GBOfRamServer);
|
purchaseServerBoxCreate(128);
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
purchase256gb.addEventListener("click", function(e) {
|
purchase256gb.addEventListener("click", function(e) {
|
||||||
if (!e.isTrusted) {return false;}
|
if (!e.isTrusted) {return false;}
|
||||||
purchaseServerBoxCreate(256, 256 * CONSTANTS.BaseCostFor1GBOfRamServer);
|
purchaseServerBoxCreate(256);
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
purchase512gb.addEventListener("click", function(e) {
|
purchase512gb.addEventListener("click", function(e) {
|
||||||
if (!e.isTrusted) {return false;}
|
if (!e.isTrusted) {return false;}
|
||||||
purchaseServerBoxCreate(512, 512 * CONSTANTS.BaseCostFor1GBOfRamServer);
|
purchaseServerBoxCreate(512);
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
purchase1tb.addEventListener("click", function(e) {
|
purchase1tb.addEventListener("click", function(e) {
|
||||||
if (!e.isTrusted) {return false;}
|
if (!e.isTrusted) {return false;}
|
||||||
purchaseServerBoxCreate(1024, 1024 * CONSTANTS.BaseCostFor1GBOfRamServer);
|
purchaseServerBoxCreate(1024);
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -2264,13 +2265,19 @@ function travelBoxCreate(destCityName, cost) {
|
|||||||
yesNoBoxCreate("Would you like to travel to " + destCityName + "? The trip will cost $" + formatNumber(cost, 2) + ".");
|
yesNoBoxCreate("Would you like to travel to " + destCityName + "? The trip will cost $" + formatNumber(cost, 2) + ".");
|
||||||
}
|
}
|
||||||
|
|
||||||
function purchaseServerBoxCreate(ram, cost) {
|
function purchaseServerBoxCreate(ram) {
|
||||||
|
const cost = getPurchaseServerCost(ram);
|
||||||
|
if (cost === Infinity) {
|
||||||
|
dialogBoxCreate("Something went wrong when trying to purchase this server. Please contact developer");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var yesBtn = yesNoTxtInpBoxGetYesButton();
|
var yesBtn = yesNoTxtInpBoxGetYesButton();
|
||||||
var noBtn = yesNoTxtInpBoxGetNoButton();
|
var noBtn = yesNoTxtInpBoxGetNoButton();
|
||||||
yesBtn.innerHTML = "Purchase Server";
|
yesBtn.innerHTML = "Purchase Server";
|
||||||
noBtn.innerHTML = "Cancel";
|
noBtn.innerHTML = "Cancel";
|
||||||
yesBtn.addEventListener("click", function() {
|
yesBtn.addEventListener("click", function() {
|
||||||
purchaseServer(ram, cost);
|
purchaseServer(ram);
|
||||||
yesNoTxtInpBoxClose();
|
yesNoTxtInpBoxClose();
|
||||||
});
|
});
|
||||||
noBtn.addEventListener("click", function() {
|
noBtn.addEventListener("click", function() {
|
||||||
|
@ -40,6 +40,9 @@ import {Script, findRunningScript, RunningScript,
|
|||||||
import {Server, getServer, AddToAllServers,
|
import {Server, getServer, AddToAllServers,
|
||||||
AllServers, processSingleServerGrowth,
|
AllServers, processSingleServerGrowth,
|
||||||
GetServerByHostname, numCycleForGrowth} from "./Server";
|
GetServerByHostname, numCycleForGrowth} from "./Server";
|
||||||
|
import { getPurchaseServerCost,
|
||||||
|
getPurchaseServerLimit,
|
||||||
|
getPurchaseServerMaxRam } from "./ServerPurchases";
|
||||||
import {Settings} from "./Settings/Settings";
|
import {Settings} from "./Settings/Settings";
|
||||||
import {SpecialServerIps} from "./SpecialServerIps";
|
import {SpecialServerIps} from "./SpecialServerIps";
|
||||||
import {Stock} from "./StockMarket/Stock";
|
import {Stock} from "./StockMarket/Stock";
|
||||||
@ -234,24 +237,6 @@ function NetscriptFunctions(workerScript) {
|
|||||||
return server.getContract(fn);
|
return server.getContract(fn);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {number} ram The amount of server RAM to calculate cost of.
|
|
||||||
* @exception {Error} If the value passed in is not numeric, out of range, or too large of a value.
|
|
||||||
* @returns {number} The cost of
|
|
||||||
*/
|
|
||||||
const getPurchaseServerRamCostGuard = (ram) => {
|
|
||||||
const guardedRam = Math.round(ram);
|
|
||||||
if (isNaN(guardedRam) || !isPowerOfTwo(guardedRam)) {
|
|
||||||
throw Error("failed due to invalid ram argument. Must be numeric and a power of 2");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (guardedRam > CONSTANTS.PurchasedServerMaxRam) {
|
|
||||||
throw Error("failed because specified RAM was too high. Maximum RAM on a purchased server is " + CONSTANTS.PurchasedServerMaxRam + "GB");
|
|
||||||
}
|
|
||||||
|
|
||||||
return guardedRam * CONSTANTS.BaseCostFor1GBOfRamServer;
|
|
||||||
};
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
hacknet : {
|
hacknet : {
|
||||||
numNodes : function() {
|
numNodes : function() {
|
||||||
@ -1911,7 +1896,7 @@ function NetscriptFunctions(workerScript) {
|
|||||||
}
|
}
|
||||||
updateDynamicRam("getPurchasedServerLimit", CONSTANTS.ScriptGetPurchasedServerLimit);
|
updateDynamicRam("getPurchasedServerLimit", CONSTANTS.ScriptGetPurchasedServerLimit);
|
||||||
|
|
||||||
return CONSTANTS.PurchasedServerLimit;
|
return getPurchaseServerLimit();
|
||||||
},
|
},
|
||||||
getPurchasedServerMaxRam: function() {
|
getPurchasedServerMaxRam: function() {
|
||||||
if (workerScript.checkingRam) {
|
if (workerScript.checkingRam) {
|
||||||
@ -1919,7 +1904,7 @@ function NetscriptFunctions(workerScript) {
|
|||||||
}
|
}
|
||||||
updateDynamicRam("getPurchasedServerMaxRam", CONSTANTS.ScriptGetPurchasedServerMaxRam);
|
updateDynamicRam("getPurchasedServerMaxRam", CONSTANTS.ScriptGetPurchasedServerMaxRam);
|
||||||
|
|
||||||
return CONSTANTS.PurchasedServerMaxRam;
|
return getPurchaseServerMaxRam();
|
||||||
},
|
},
|
||||||
getPurchasedServerCost: function(ram) {
|
getPurchasedServerCost: function(ram) {
|
||||||
if (workerScript.checkingRam) {
|
if (workerScript.checkingRam) {
|
||||||
@ -1927,11 +1912,9 @@ function NetscriptFunctions(workerScript) {
|
|||||||
}
|
}
|
||||||
updateDynamicRam("getPurchasedServerCost", CONSTANTS.ScriptGetPurchaseServerRamCost);
|
updateDynamicRam("getPurchasedServerCost", CONSTANTS.ScriptGetPurchaseServerRamCost);
|
||||||
|
|
||||||
let cost = 0;
|
const cost = getPurchaseServerCost(ram);
|
||||||
try {
|
if (cost === Infinity) {
|
||||||
cost = getPurchaseServerRamCostGuard(ram);
|
workerScript.scriptRef.log("ERROR: 'getPurchasedServerCost()' failed due to an invalid 'ram' argument");
|
||||||
} catch (e) {
|
|
||||||
workerScript.scriptRef.log("ERROR: 'getPurchasedServerCost()' " + e.message);
|
|
||||||
return Infinity;
|
return Infinity;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1945,26 +1928,23 @@ function NetscriptFunctions(workerScript) {
|
|||||||
var hostnameStr = String(hostname);
|
var hostnameStr = String(hostname);
|
||||||
hostnameStr = hostnameStr.replace(/\s+/g, '');
|
hostnameStr = hostnameStr.replace(/\s+/g, '');
|
||||||
if (hostnameStr == "") {
|
if (hostnameStr == "") {
|
||||||
workerScript.scriptRef.log("ERROR: Passed empty string for hostname argument of purchaseServer()");
|
workerScript.log("ERROR: Passed empty string for hostname argument of purchaseServer()");
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Player.purchasedServers.length >= CONSTANTS.PurchasedServerLimit) {
|
if (Player.purchasedServers.length >= getPurchaseServerLimit()) {
|
||||||
workerScript.scriptRef.log("ERROR: You have reached the maximum limit of " + CONSTANTS.PurchasedServerLimit +
|
workerScript.log(`ERROR: You have reached the maximum limit of ${getPurchaseServerLimit()} servers. You cannot purchase any more.`);
|
||||||
" servers. You cannot purchase any more.");
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
let cost = 0;
|
const cost = getPurchaseServerCost(ram);
|
||||||
try {
|
if (cost === Infinity) {
|
||||||
cost = getPurchaseServerRamCostGuard(ram);
|
workerScript.log("ERROR: 'purchaseServer()' failed due to an invalid 'ram' argument");
|
||||||
} catch (e) {
|
return Infinity;
|
||||||
workerScript.scriptRef.log("ERROR: 'purchaseServer()' " + e.message);
|
|
||||||
return "";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Player.money.lt(cost)) {
|
if (Player.money.lt(cost)) {
|
||||||
workerScript.scriptRef.log("ERROR: Not enough money to purchase server. Need $" + formatNumber(cost, 2));
|
workerScript.log("ERROR: Not enough money to purchase server. Need $" + formatNumber(cost, 2));
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
var newServ = new Server({
|
var newServ = new Server({
|
||||||
|
@ -16,6 +16,7 @@ import { Person,
|
|||||||
import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers";
|
import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers";
|
||||||
|
|
||||||
import { Crime } from "../../Crime/Crime";
|
import { Crime } from "../../Crime/Crime";
|
||||||
|
import { Crimes } from "../../Crime/Crimes";
|
||||||
|
|
||||||
import { Cities } from "../../Locations/Cities";
|
import { Cities } from "../../Locations/Cities";
|
||||||
|
|
||||||
@ -42,6 +43,12 @@ export class Sleeve extends Person {
|
|||||||
return Generic_fromJSON(Sleeve, value.data);
|
return Generic_fromJSON(Sleeve, value.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores the type of crime the sleeve is currently attempting
|
||||||
|
* Must match the name of a Crime object
|
||||||
|
*/
|
||||||
|
crimeType: string = "";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enum value for current task
|
* Enum value for current task
|
||||||
*/
|
*/
|
||||||
@ -136,8 +143,10 @@ export class Sleeve extends Person {
|
|||||||
/**
|
/**
|
||||||
* Commit crimes
|
* Commit crimes
|
||||||
*/
|
*/
|
||||||
commitCrime(p: IPlayer, crime: Crime): boolean {
|
commitCrime(p: IPlayer, crimeKey: string): boolean {
|
||||||
|
const crime: Crime | null = Crimes[crimeKey];
|
||||||
if (!(crime instanceof Crime)) { return false; }
|
if (!(crime instanceof Crime)) { return false; }
|
||||||
|
|
||||||
if (this.currentTask !== SleeveTaskType.Idle) {
|
if (this.currentTask !== SleeveTaskType.Idle) {
|
||||||
this.finishTask(p);
|
this.finishTask(p);
|
||||||
} else {
|
} else {
|
||||||
@ -154,19 +163,7 @@ export class Sleeve extends Person {
|
|||||||
|
|
||||||
this.currentTaskLocation = String(this.gainRatesForTask.money);
|
this.currentTaskLocation = String(this.gainRatesForTask.money);
|
||||||
|
|
||||||
// We'll determine success now and adjust the earnings accordingly
|
this.crimeType = crimeKey;
|
||||||
if (Math.random() < crime.successRate(p)) {
|
|
||||||
this.gainRatesForTask.hack *= 2;
|
|
||||||
this.gainRatesForTask.str *= 2;
|
|
||||||
this.gainRatesForTask.def *= 2;
|
|
||||||
this.gainRatesForTask.dex *= 2;
|
|
||||||
this.gainRatesForTask.agi *= 2;
|
|
||||||
this.gainRatesForTask.cha *= 2;
|
|
||||||
} else {
|
|
||||||
this.gainRatesForTask.money = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
this.currentTaskMaxTime = crime.time;
|
this.currentTaskMaxTime = crime.time;
|
||||||
this.currentTask = SleeveTaskType.Crime;
|
this.currentTask = SleeveTaskType.Crime;
|
||||||
return true;
|
return true;
|
||||||
@ -181,8 +178,26 @@ export class Sleeve extends Person {
|
|||||||
if (this.currentTask === SleeveTaskType.Crime) {
|
if (this.currentTask === SleeveTaskType.Crime) {
|
||||||
// For crimes, all experience and money is gained at the end
|
// For crimes, all experience and money is gained at the end
|
||||||
if (this.currentTaskTime >= this.currentTaskMaxTime) {
|
if (this.currentTaskTime >= this.currentTaskMaxTime) {
|
||||||
retValue = this.gainExperience(p, this.gainRatesForTask);
|
const crime: Crime | null = Crimes[this.crimeType];
|
||||||
this.gainMoney(p, this.gainRatesForTask);
|
if (!(crime instanceof Crime)) {
|
||||||
|
console.error(`Invalid data stored in sleeve.crimeType: ${this.crimeType}`);
|
||||||
|
this.resetTaskStatus();
|
||||||
|
return retValue;
|
||||||
|
}
|
||||||
|
if (Math.random() < crime.successRate(p)) {
|
||||||
|
// Success
|
||||||
|
const successGainRates: ITaskTracker = createTaskTracker();
|
||||||
|
|
||||||
|
const keysForIteration: (keyof ITaskTracker)[] = (<(keyof ITaskTracker)[]>Object.keys(successGainRates));
|
||||||
|
for (let i = 0; i < keysForIteration.length; ++i) {
|
||||||
|
const key = keysForIteration[i];
|
||||||
|
successGainRates[key] = this.gainRatesForTask[key] * 2;
|
||||||
|
}
|
||||||
|
retValue = this.gainExperience(p, successGainRates);
|
||||||
|
this.gainMoney(p, this.gainRatesForTask);
|
||||||
|
} else {
|
||||||
|
retValue = this.gainExperience(p, this.gainRatesForTask);
|
||||||
|
}
|
||||||
|
|
||||||
// Do not reset task to IDLE
|
// Do not reset task to IDLE
|
||||||
this.currentTaskTime = 0;
|
this.currentTaskTime = 0;
|
||||||
@ -261,7 +276,7 @@ export class Sleeve extends Person {
|
|||||||
this.defense_exp += pDefExp;
|
this.defense_exp += pDefExp;
|
||||||
p.gainDefenseExp(pDefExp);
|
p.gainDefenseExp(pDefExp);
|
||||||
this.earningsForPlayer.def += pDefExp;
|
this.earningsForPlayer.def += pDefExp;
|
||||||
this.earningsForTask.dex += pDefExp;
|
this.earningsForTask.def += pDefExp;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pDexExp > 0) {
|
if (pDexExp > 0) {
|
||||||
@ -464,6 +479,9 @@ export class Sleeve extends Person {
|
|||||||
this.currentTaskTime = 0;
|
this.currentTaskTime = 0;
|
||||||
this.currentTaskMaxTime = 0;
|
this.currentTaskMaxTime = 0;
|
||||||
this.factionWorkType = FactionWorkType.None;
|
this.factionWorkType = FactionWorkType.None;
|
||||||
|
this.crimeType = "";
|
||||||
|
this.currentTaskLocation = "";
|
||||||
|
this.gymStatType = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -630,12 +648,16 @@ export class Sleeve extends Person {
|
|||||||
this.resetTaskStatus();
|
this.resetTaskStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const factionInfo = Factions[factionName].getInfo();
|
||||||
|
|
||||||
// Set type of work (hacking/field/security), and the experience gains
|
// Set type of work (hacking/field/security), and the experience gains
|
||||||
const sanitizedWorkType: string = workType.toLowerCase();
|
const sanitizedWorkType: string = workType.toLowerCase();
|
||||||
if (sanitizedWorkType.includes("hack")) {
|
if (sanitizedWorkType.includes("hack")) {
|
||||||
|
if (!factionInfo.offerHackingWork) { return false; }
|
||||||
this.factionWorkType = FactionWorkType.Hacking;
|
this.factionWorkType = FactionWorkType.Hacking;
|
||||||
this.gainRatesForTask.hack = .15 * this.hacking_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
|
this.gainRatesForTask.hack = .15 * this.hacking_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
|
||||||
} else if (sanitizedWorkType.includes("field")) {
|
} else if (sanitizedWorkType.includes("field")) {
|
||||||
|
if (!factionInfo.offerFieldWork) { return false; }
|
||||||
this.factionWorkType = FactionWorkType.Field;
|
this.factionWorkType = FactionWorkType.Field;
|
||||||
this.gainRatesForTask.hack = .1 * this.hacking_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
|
this.gainRatesForTask.hack = .1 * this.hacking_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
|
||||||
this.gainRatesForTask.str = .1 * this.strength_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
|
this.gainRatesForTask.str = .1 * this.strength_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
|
||||||
@ -644,6 +666,7 @@ export class Sleeve extends Person {
|
|||||||
this.gainRatesForTask.agi = .1 * this.agility_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
|
this.gainRatesForTask.agi = .1 * this.agility_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
|
||||||
this.gainRatesForTask.cha = .1 * this.charisma_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
|
this.gainRatesForTask.cha = .1 * this.charisma_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
|
||||||
} else if (sanitizedWorkType.includes("security")) {
|
} else if (sanitizedWorkType.includes("security")) {
|
||||||
|
if (!factionInfo.offerSecurityWork) { return false; }
|
||||||
this.factionWorkType = FactionWorkType.Security;
|
this.factionWorkType = FactionWorkType.Security;
|
||||||
this.gainRatesForTask.hack = .1 * this.hacking_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
|
this.gainRatesForTask.hack = .1 * this.hacking_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
|
||||||
this.gainRatesForTask.str = .15 * this.strength_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
|
this.gainRatesForTask.str = .15 * this.strength_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
|
||||||
|
@ -10,8 +10,12 @@ import { IPlayer } from "../IPlayer";
|
|||||||
import { CONSTANTS } from "../../Constants";
|
import { CONSTANTS } from "../../Constants";
|
||||||
import { Locations } from "../../Locations";
|
import { Locations } from "../../Locations";
|
||||||
|
|
||||||
|
import { Faction } from "../../Faction/Faction";
|
||||||
|
import { Factions } from "../../Faction/Factions";
|
||||||
import { FactionWorkType } from "../../Faction/FactionWorkTypeEnum";
|
import { FactionWorkType } from "../../Faction/FactionWorkTypeEnum";
|
||||||
|
|
||||||
import { Cities } from "../../Locations/Cities";
|
import { Cities } from "../../Locations/Cities";
|
||||||
|
import { Crime } from "../../Crime/Crime";
|
||||||
import { Crimes } from "../../Crime/Crimes";
|
import { Crimes } from "../../Crime/Crimes";
|
||||||
|
|
||||||
import { numeralWrapper } from "../../ui/numeralFormat";
|
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||||
@ -23,6 +27,7 @@ import { dialogBoxCreate } from "../../../utils/DialogBox";
|
|||||||
import { createProgressBarText } from "../../../utils/helpers/createProgressBarText";
|
import { createProgressBarText } from "../../../utils/helpers/createProgressBarText";
|
||||||
import { exceptionAlert } from "../../../utils/helpers/exceptionAlert";
|
import { exceptionAlert } from "../../../utils/helpers/exceptionAlert";
|
||||||
|
|
||||||
|
import { clearEventListeners } from "../../../utils/uiHelpers/clearEventListeners";
|
||||||
import { createElement } from "../../../utils/uiHelpers/createElement";
|
import { createElement } from "../../../utils/uiHelpers/createElement";
|
||||||
import { createOptionElement } from "../../../utils/uiHelpers/createOptionElement";
|
import { createOptionElement } from "../../../utils/uiHelpers/createOptionElement";
|
||||||
import { createPopup } from "../../../utils/uiHelpers/createPopup";
|
import { createPopup } from "../../../utils/uiHelpers/createPopup";
|
||||||
@ -229,7 +234,7 @@ function createSleeveUi(sleeve: Sleeve, allSleeves: Sleeve[]): ISleeveUIElems {
|
|||||||
popupArguments.push(createElement("p", {
|
popupArguments.push(createElement("p", {
|
||||||
innerText: "Have this sleeve travel to a different city. This affects " +
|
innerText: "Have this sleeve travel to a different city. This affects " +
|
||||||
"the gyms and universities at which this sleeve can study. " +
|
"the gyms and universities at which this sleeve can study. " +
|
||||||
`Traveling to a different city costs ${numeralWrapper.formatMoney(CONSTANTS.TravelCost)}.` +
|
`Traveling to a different city costs ${numeralWrapper.formatMoney(CONSTANTS.TravelCost)}. ` +
|
||||||
"It will also CANCEL the sleeve's current task (setting it to idle)",
|
"It will also CANCEL the sleeve's current task (setting it to idle)",
|
||||||
}));
|
}));
|
||||||
for (const label in Cities) {
|
for (const label in Cities) {
|
||||||
@ -250,6 +255,7 @@ function createSleeveUi(sleeve: Sleeve, allSleeves: Sleeve[]): ISleeveUIElems {
|
|||||||
sleeve.resetTaskStatus();
|
sleeve.resetTaskStatus();
|
||||||
removeElementById(popupId);
|
removeElementById(popupId);
|
||||||
updateSleeveUi(sleeve, elems);
|
updateSleeveUi(sleeve, elems);
|
||||||
|
updateSleeveTaskSelector(sleeve, elems, allSleeves);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
@ -401,12 +407,6 @@ function updateSleeveUi(sleeve: Sleeve, elems: ISleeveUIElems) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const factionWorkTypeSelectorOptions: string[] = [
|
|
||||||
"Hacking Contracts",
|
|
||||||
"Security Work",
|
|
||||||
"Field Work"
|
|
||||||
];
|
|
||||||
|
|
||||||
const universitySelectorOptions: string[] = [
|
const universitySelectorOptions: string[] = [
|
||||||
"Study Computer Science",
|
"Study Computer Science",
|
||||||
"Data Structures",
|
"Data Structures",
|
||||||
@ -450,6 +450,7 @@ function updateSleeveTaskSelector(sleeve: Sleeve, elems: ISleeveUIElems, allSlee
|
|||||||
// Reset Selectors
|
// Reset Selectors
|
||||||
removeChildrenFromElement(elems.taskDetailsSelector);
|
removeChildrenFromElement(elems.taskDetailsSelector);
|
||||||
removeChildrenFromElement(elems.taskDetailsSelector2);
|
removeChildrenFromElement(elems.taskDetailsSelector2);
|
||||||
|
elems.taskDetailsSelector2 = clearEventListeners(elems.taskDetailsSelector2!) as HTMLSelectElement;
|
||||||
|
|
||||||
const value: string = getSelectValue(elems.taskSelector);
|
const value: string = getSelectValue(elems.taskSelector);
|
||||||
switch(value) {
|
switch(value) {
|
||||||
@ -486,29 +487,57 @@ function updateSleeveTaskSelector(sleeve: Sleeve, elems: ISleeveUIElems, allSlee
|
|||||||
++factionCount;
|
++factionCount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (let i = 0; i < factionWorkTypeSelectorOptions.length; ++i) {
|
|
||||||
elems.taskDetailsSelector2!.add(createOptionElement(factionWorkTypeSelectorOptions[i]));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set initial value for faction work type
|
// The available faction work types depends on the faction
|
||||||
switch (sleeve.factionWorkType) {
|
elems.taskDetailsSelector!.addEventListener("change", () => {
|
||||||
case FactionWorkType.Hacking:
|
const facName = getSelectValue(elems.taskDetailsSelector!);
|
||||||
elems.taskDetailsSelector2!.selectedIndex = 0;
|
const faction: Faction | null = Factions[facName];
|
||||||
break;
|
if (faction == null) {
|
||||||
case FactionWorkType.Security:
|
console.warn(`Invalid faction name when trying to update Sleeve Task Selector: ${facName}`);
|
||||||
elems.taskDetailsSelector2!.selectedIndex = 0;
|
return;
|
||||||
break;
|
}
|
||||||
case FactionWorkType.Field:
|
const facInfo = faction.getInfo();
|
||||||
elems.taskDetailsSelector2!.selectedIndex = 0;
|
removeChildrenFromElement(elems.taskDetailsSelector2!);
|
||||||
break;
|
let numOptionsAdded = 0;
|
||||||
default:
|
if (facInfo.offerHackingWork) {
|
||||||
break;
|
elems.taskDetailsSelector2!.add(createOptionElement("Hacking Contracts"));
|
||||||
}
|
if (sleeve.factionWorkType === FactionWorkType.Hacking) {
|
||||||
|
elems.taskDetailsSelector2!.selectedIndex = numOptionsAdded;
|
||||||
|
}
|
||||||
|
++numOptionsAdded;
|
||||||
|
}
|
||||||
|
if (facInfo.offerFieldWork) {
|
||||||
|
elems.taskDetailsSelector2!.add(createOptionElement("Field Work"));
|
||||||
|
if (sleeve.factionWorkType === FactionWorkType.Field) {
|
||||||
|
elems.taskDetailsSelector2!.selectedIndex = numOptionsAdded;
|
||||||
|
}
|
||||||
|
++numOptionsAdded;
|
||||||
|
}
|
||||||
|
if (facInfo.offerSecurityWork) {
|
||||||
|
elems.taskDetailsSelector2!.add(createOptionElement("Security Work"));
|
||||||
|
if (sleeve.factionWorkType === FactionWorkType.Security) {
|
||||||
|
elems.taskDetailsSelector2!.selectedIndex = numOptionsAdded;
|
||||||
|
}
|
||||||
|
++numOptionsAdded;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
elems.taskDetailsSelector!.dispatchEvent(new Event("change"));
|
||||||
break;
|
break;
|
||||||
case "Commit Crime":
|
case "Commit Crime":
|
||||||
|
let i = 0;
|
||||||
for (const crimeLabel in Crimes) {
|
for (const crimeLabel in Crimes) {
|
||||||
const name: string = Crimes[crimeLabel].name;
|
const name: string = Crimes[crimeLabel].name;
|
||||||
elems.taskDetailsSelector!.add(createOptionElement(name, crimeLabel));
|
elems.taskDetailsSelector!.add(createOptionElement(name, crimeLabel));
|
||||||
|
|
||||||
|
// Set initial value for crime type
|
||||||
|
if (sleeve.crimeType === "") { continue; }
|
||||||
|
const crime: Crime | null = Crimes[sleeve.crimeType];
|
||||||
|
if (crime == null) { continue; }
|
||||||
|
if (name === crime!.name) {
|
||||||
|
elems.taskDetailsSelector!.selectedIndex = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
++i;
|
||||||
}
|
}
|
||||||
|
|
||||||
elems.taskDetailsSelector2!.add(createOptionElement("------"));
|
elems.taskDetailsSelector2!.add(createOptionElement("------"));
|
||||||
@ -614,7 +643,7 @@ function setSleeveTask(sleeve: Sleeve, elems: ISleeveUIElems): boolean {
|
|||||||
res = sleeve.workForFaction(playerRef!, detailValue, detailValue2);
|
res = sleeve.workForFaction(playerRef!, detailValue, detailValue2);
|
||||||
break;
|
break;
|
||||||
case "Commit Crime":
|
case "Commit Crime":
|
||||||
res = sleeve.commitCrime(playerRef!, Crimes[detailValue]);
|
res = sleeve.commitCrime(playerRef!, detailValue);
|
||||||
break;
|
break;
|
||||||
case "Take University Course":
|
case "Take University Course":
|
||||||
res = sleeve.takeUniversityCourse(playerRef!, detailValue2, detailValue);
|
res = sleeve.takeUniversityCourse(playerRef!, detailValue2, detailValue);
|
||||||
@ -637,7 +666,15 @@ function setSleeveTask(sleeve: Sleeve, elems: ISleeveUIElems): boolean {
|
|||||||
if (res) {
|
if (res) {
|
||||||
updateSleeveTaskDescription(sleeve, elems);
|
updateSleeveTaskDescription(sleeve, elems);
|
||||||
} else {
|
} else {
|
||||||
elems.taskDescription!.innerText = "Failed to assign sleeve to task. Invalid choice(s).";
|
switch (taskValue) {
|
||||||
|
case "Work for Faction":
|
||||||
|
elems.taskDescription!.innerText = "Failed to assign sleeve to task. This is most likely because the selected faction does not offer the selected work type.";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
elems.taskDescription!.innerText = "Failed to assign sleeve to task. Invalid choice(s).";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (routing.isOn(Page.Sleeves)) {
|
if (routing.isOn(Page.Sleeves)) {
|
||||||
@ -672,16 +709,13 @@ function updateSleeveTaskDescription(sleeve: Sleeve, elems: ISleeveUIElems): voi
|
|||||||
elems.taskDescription!.innerText = "This sleeve is currently idle";
|
elems.taskDescription!.innerText = "This sleeve is currently idle";
|
||||||
break;
|
break;
|
||||||
case "Work for Company":
|
case "Work for Company":
|
||||||
elems.taskDescription!.innerText = `This sleeve is currently working your ` +
|
elems.taskDescription!.innerText = `This sleeve is currently working your job at ${sleeve.currentTaskLocation}.`;
|
||||||
`job at ${sleeve.currentTaskLocation}.`;
|
|
||||||
break;
|
break;
|
||||||
case "Work for Faction":
|
case "Work for Faction":
|
||||||
elems.taskDescription!.innerText = `This sleeve is currently doing ${detailValue2} for ` +
|
elems.taskDescription!.innerText = `This sleeve is currently doing ${detailValue2} for ${sleeve.currentTaskLocation}.`;
|
||||||
`${sleeve.currentTaskLocation}.`;
|
|
||||||
break;
|
break;
|
||||||
case "Commit Crime":
|
case "Commit Crime":
|
||||||
elems.taskDescription!.innerText = `This sleeve is currently attempting to ` +
|
elems.taskDescription!.innerText = `This sleeve is currently attempting to ${Crimes[detailValue].type} (Success Rate: ${numeralWrapper.formatPercentage(Crimes[detailValue].successRate(playerRef))}).`;
|
||||||
`${Crimes[detailValue].type}.`;
|
|
||||||
break;
|
break;
|
||||||
case "Take University Course":
|
case "Take University Course":
|
||||||
elems.taskDescription!.innerText = `This sleeve is currently studying/taking a course at ${sleeve.currentTaskLocation}.`;
|
elems.taskDescription!.innerText = `This sleeve is currently studying/taking a course at ${sleeve.currentTaskLocation}.`;
|
||||||
|
@ -201,6 +201,7 @@ function PlayerObject() {
|
|||||||
// Sleeves & Re-sleeving
|
// Sleeves & Re-sleeving
|
||||||
this.sleeves = [];
|
this.sleeves = [];
|
||||||
this.resleeves = [];
|
this.resleeves = [];
|
||||||
|
this.sleevesFromCovenant = 0; // # of Duplicate sleeves purchased from the covenant
|
||||||
|
|
||||||
//bitnode
|
//bitnode
|
||||||
this.bitNodeN = 1;
|
this.bitNodeN = 1;
|
||||||
@ -369,9 +370,7 @@ PlayerObject.prototype.prestigeSourceFile = function() {
|
|||||||
this.resleeves = [];
|
this.resleeves = [];
|
||||||
|
|
||||||
// Duplicate sleeves are reset to level 1 every Bit Node (but the number of sleeves you have persists)
|
// Duplicate sleeves are reset to level 1 every Bit Node (but the number of sleeves you have persists)
|
||||||
if (this.sleeves.length < SourceFileFlags[10]) {
|
this.sleeves.length = SourceFileFlags[10] + this.sleevesFromCovenant;
|
||||||
this.sleeves.length = SourceFileFlags[10];
|
|
||||||
}
|
|
||||||
for (let i = 0; i < this.sleeves.length; ++i) {
|
for (let i = 0; i < this.sleeves.length; ++i) {
|
||||||
this.sleeves[i] = new Sleeve();
|
this.sleeves[i] = new Sleeve();
|
||||||
}
|
}
|
||||||
|
@ -41,8 +41,6 @@ function scriptEditorInit() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Beautify button
|
// Beautify button
|
||||||
const beautifyButton = createElement("button", {
|
const beautifyButton = createElement("button", {
|
||||||
class: "std-button",
|
class: "std-button",
|
||||||
@ -210,8 +208,9 @@ $(document).keydown(function(e) {
|
|||||||
function saveAndCloseScriptEditor() {
|
function saveAndCloseScriptEditor() {
|
||||||
var filename = document.getElementById("script-editor-filename").value;
|
var filename = document.getElementById("script-editor-filename").value;
|
||||||
|
|
||||||
|
let code;
|
||||||
try {
|
try {
|
||||||
let code = getCurrentEditor().getCode();
|
code = getCurrentEditor().getCode();
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
dialogBoxCreate("Something went wrong when trying to save (getCurrentEditor().getCode()). Please report to game developer with details");
|
dialogBoxCreate("Something went wrong when trying to save (getCurrentEditor().getCode()). Please report to game developer with details");
|
||||||
return;
|
return;
|
||||||
|
@ -18,6 +18,7 @@ require("brace/ext/language_tools");
|
|||||||
|
|
||||||
import { NetscriptFunctions } from "../NetscriptFunctions";
|
import { NetscriptFunctions } from "../NetscriptFunctions";
|
||||||
import { Settings } from "../Settings/Settings";
|
import { Settings } from "../Settings/Settings";
|
||||||
|
import { AceKeybindingSetting } from "../Settings/SettingEnums";
|
||||||
|
|
||||||
import { clearEventListeners } from "../../utils/uiHelpers/clearEventListeners";
|
import { clearEventListeners } from "../../utils/uiHelpers/clearEventListeners";
|
||||||
import { createElement } from "../../utils/uiHelpers/createElement";
|
import { createElement } from "../../utils/uiHelpers/createElement";
|
||||||
@ -43,6 +44,7 @@ function validateInitializationParamters(params) {
|
|||||||
class AceEditorWrapper extends ScriptEditor {
|
class AceEditorWrapper extends ScriptEditor {
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
|
this.vimCommandDisplayWrapper = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
init(params) {
|
init(params) {
|
||||||
@ -73,7 +75,7 @@ class AceEditorWrapper extends ScriptEditor {
|
|||||||
editorElement.style.fontSize = '16px';
|
editorElement.style.fontSize = '16px';
|
||||||
this.editor.setOption("showPrintMargin", false);
|
this.editor.setOption("showPrintMargin", false);
|
||||||
|
|
||||||
//Configure some of the VIM keybindings
|
// Configure some of the VIM keybindings
|
||||||
ace.config.loadModule('ace/keyboard/vim', function(module) {
|
ace.config.loadModule('ace/keyboard/vim', function(module) {
|
||||||
var VimApi = module.CodeMirror.Vim;
|
var VimApi = module.CodeMirror.Vim;
|
||||||
VimApi.defineEx('write', 'w', function(cm, input) {
|
VimApi.defineEx('write', 'w', function(cm, input) {
|
||||||
@ -90,6 +92,13 @@ class AceEditorWrapper extends ScriptEditor {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Store a reference to the VIM command display
|
||||||
|
this.vimCommandDisplayWrapper = document.getElementById("codemirror-vim-command-display-wrapper");
|
||||||
|
if (this.vimCommandDisplayWrapper == null) {
|
||||||
|
console.error(`Could not get Vim Command Display element (id=codemirror-vim-command-display-wrapper)`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
//Function autocompleter
|
//Function autocompleter
|
||||||
this.editor.setOption("enableBasicAutocompletion", true);
|
this.editor.setOption("enableBasicAutocompletion", true);
|
||||||
var autocompleter = {
|
var autocompleter = {
|
||||||
@ -160,6 +169,11 @@ class AceEditorWrapper extends ScriptEditor {
|
|||||||
elem.style.display = "block";
|
elem.style.display = "block";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Make sure the Vim command display from CodeMirror is invisible
|
||||||
|
if (this.vimCommandDisplayWrapper instanceof HTMLElement) {
|
||||||
|
this.vimCommandDisplayWrapper.style.display = "none";
|
||||||
|
}
|
||||||
|
|
||||||
// Theme
|
// Theme
|
||||||
const themeDropdown = safeClearEventListeners("script-editor-option-theme", "Theme Selector");
|
const themeDropdown = safeClearEventListeners("script-editor-option-theme", "Theme Selector");
|
||||||
removeChildrenFromElement(themeDropdown);
|
removeChildrenFromElement(themeDropdown);
|
||||||
@ -195,10 +209,14 @@ class AceEditorWrapper extends ScriptEditor {
|
|||||||
// Keybinding
|
// Keybinding
|
||||||
const keybindingDropdown = safeClearEventListeners("script-editor-option-keybinding", "Keybinding Selector");
|
const keybindingDropdown = safeClearEventListeners("script-editor-option-keybinding", "Keybinding Selector");
|
||||||
removeChildrenFromElement(keybindingDropdown);
|
removeChildrenFromElement(keybindingDropdown);
|
||||||
keybindingDropdown.add(createOptionElement("Ace", "ace"));
|
keybindingDropdown.add(createOptionElement("Ace", AceKeybindingSetting.Ace));
|
||||||
keybindingDropdown.add(createOptionElement("Vim", "vim"));
|
keybindingDropdown.add(createOptionElement("Vim", AceKeybindingSetting.Vim));
|
||||||
keybindingDropdown.add(createOptionElement("Emacs", "emacs"));
|
keybindingDropdown.add(createOptionElement("Emacs", AceKeybindingSetting.Emacs));
|
||||||
if (Settings.EditorKeybinding) {
|
if (Settings.EditorKeybinding) {
|
||||||
|
// Sanitize the Keybinding setting
|
||||||
|
if (!(Object.values(AceKeybindingSetting).includes(Settings.EditorKeybinding))) {
|
||||||
|
Settings.EditorKeybinding = AceKeybindingSetting.Ace;
|
||||||
|
}
|
||||||
var initialIndex = 0;
|
var initialIndex = 0;
|
||||||
for (var i = 0; i < keybindingDropdown.options.length; ++i) {
|
for (var i = 0; i < keybindingDropdown.options.length; ++i) {
|
||||||
if (keybindingDropdown.options[i].value === Settings.EditorKeybinding) {
|
if (keybindingDropdown.options[i].value === Settings.EditorKeybinding) {
|
||||||
|
@ -71,6 +71,8 @@ import 'codemirror/keymap/vim.js';
|
|||||||
import 'codemirror/keymap/emacs.js';
|
import 'codemirror/keymap/emacs.js';
|
||||||
|
|
||||||
import 'codemirror/addon/comment/continuecomment.js';
|
import 'codemirror/addon/comment/continuecomment.js';
|
||||||
|
import 'codemirror/addon/dialog/dialog.css';
|
||||||
|
import 'codemirror/addon/dialog/dialog.js';
|
||||||
import 'codemirror/addon/edit/closebrackets.js';
|
import 'codemirror/addon/edit/closebrackets.js';
|
||||||
import 'codemirror/addon/edit/matchbrackets.js';
|
import 'codemirror/addon/edit/matchbrackets.js';
|
||||||
import 'codemirror/addon/fold/foldcode.js';
|
import 'codemirror/addon/fold/foldcode.js';
|
||||||
@ -79,6 +81,7 @@ import 'codemirror/addon/fold/foldgutter.css';
|
|||||||
import 'codemirror/addon/fold/brace-fold.js';
|
import 'codemirror/addon/fold/brace-fold.js';
|
||||||
import 'codemirror/addon/fold/indent-fold.js';
|
import 'codemirror/addon/fold/indent-fold.js';
|
||||||
import 'codemirror/addon/fold/comment-fold.js';
|
import 'codemirror/addon/fold/comment-fold.js';
|
||||||
|
import 'codemirror/addon/hint/javascript-hint.js';
|
||||||
import 'codemirror/addon/hint/show-hint.js';
|
import 'codemirror/addon/hint/show-hint.js';
|
||||||
import 'codemirror/addon/hint/show-hint.css';
|
import 'codemirror/addon/hint/show-hint.css';
|
||||||
import 'codemirror/addon/lint/lint.js';
|
import 'codemirror/addon/lint/lint.js';
|
||||||
@ -87,10 +90,11 @@ import 'codemirror/addon/search/match-highlighter.js';
|
|||||||
import 'codemirror/addon/selection/active-line.js';
|
import 'codemirror/addon/selection/active-line.js';
|
||||||
|
|
||||||
window.JSHINT = require('jshint').JSHINT;
|
window.JSHINT = require('jshint').JSHINT;
|
||||||
import './CodeMirrorNetscriptHint.js';
|
import './CodeMirrorNetscriptLint.js';
|
||||||
|
|
||||||
import { NetscriptFunctions } from "../NetscriptFunctions";
|
import { NetscriptFunctions } from "../NetscriptFunctions";
|
||||||
import { CodeMirrorThemeSetting } from "../Settings/SettingEnums";
|
import { CodeMirrorKeybindingSetting,
|
||||||
|
CodeMirrorThemeSetting } from "../Settings/SettingEnums";
|
||||||
import { Settings } from "../Settings/Settings";
|
import { Settings } from "../Settings/Settings";
|
||||||
|
|
||||||
import { clearEventListeners } from "../../utils/uiHelpers/clearEventListeners";
|
import { clearEventListeners } from "../../utils/uiHelpers/clearEventListeners";
|
||||||
@ -114,6 +118,8 @@ function validateInitializationParamters(params) {
|
|||||||
class CodeMirrorEditorWrapper extends ScriptEditor {
|
class CodeMirrorEditorWrapper extends ScriptEditor {
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
|
this.vimCommandDisplay = null;
|
||||||
|
this.vimCommandDisplayWrapper = null;
|
||||||
this.tabsStyleElement = null;
|
this.tabsStyleElement = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,6 +166,10 @@ class CodeMirrorEditorWrapper extends ScriptEditor {
|
|||||||
this.tabsStyleElement = document.createElement('style');
|
this.tabsStyleElement = document.createElement('style');
|
||||||
document.head.appendChild(this.tabsStyleElement);
|
document.head.appendChild(this.tabsStyleElement);
|
||||||
|
|
||||||
|
// Store a reference to the VIM command display
|
||||||
|
this.vimCommandDisplay = document.getElementById("codemirror-vim-command-display");
|
||||||
|
this.vimCommandDisplayWrapper = document.getElementById("codemirror-vim-command-display-wrapper");
|
||||||
|
|
||||||
// Define a "Save" command for CodeMirror so shortcuts like Ctrl + s
|
// Define a "Save" command for CodeMirror so shortcuts like Ctrl + s
|
||||||
// will save in-game
|
// will save in-game
|
||||||
CodeMirror.commands.save = function() { params.saveAndCloseFn(); }
|
CodeMirror.commands.save = function() { params.saveAndCloseFn(); }
|
||||||
@ -206,6 +216,21 @@ class CodeMirrorEditorWrapper extends ScriptEditor {
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Configure VIM keybindings
|
||||||
|
var VimApi = CodeMirror.Vim;
|
||||||
|
VimApi.defineEx('write', 'w', function(cm, input) {
|
||||||
|
params.saveAndCloseFn();
|
||||||
|
});
|
||||||
|
VimApi.defineEx('quit', 'q', function(cm, input) {
|
||||||
|
params.quitFn();
|
||||||
|
});
|
||||||
|
VimApi.defineEx('xwritequit', 'x', function(cm, input) {
|
||||||
|
params.saveAndCloseFn();
|
||||||
|
});
|
||||||
|
VimApi.defineEx('wqwritequit', 'wq', function(cm, input) {
|
||||||
|
params.saveAndCloseFn();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
initialized() {
|
initialized() {
|
||||||
@ -237,6 +262,11 @@ class CodeMirrorEditorWrapper extends ScriptEditor {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get and sanitize the keybinding (keymap) setting
|
||||||
|
if (!(Object.values(CodeMirrorKeybindingSetting).includes(Settings.EditorKeybinding))) {
|
||||||
|
Settings.EditorKeybinding = CodeMirrorKeybindingSetting.Default;
|
||||||
|
}
|
||||||
|
|
||||||
// Initialize CodeMirror Editor
|
// Initialize CodeMirror Editor
|
||||||
const textAreaElement = safeGetElementById("codemirror-editor", "CodeMirror Textarea");
|
const textAreaElement = safeGetElementById("codemirror-editor", "CodeMirror Textarea");
|
||||||
const formElement = safeGetElementById("codemirror-form-wrapper", "CodeMirror Form Wrapper");
|
const formElement = safeGetElementById("codemirror-form-wrapper", "CodeMirror Form Wrapper");
|
||||||
@ -294,10 +324,10 @@ class CodeMirrorEditorWrapper extends ScriptEditor {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
removeChildrenFromElement(keybindingDropdown);
|
removeChildrenFromElement(keybindingDropdown);
|
||||||
keybindingDropdown.add(createOptionElement("Default", "default"));
|
keybindingDropdown.add(createOptionElement("Default", CodeMirrorKeybindingSetting.Default));
|
||||||
keybindingDropdown.add(createOptionElement("Sublime", "sublime"));
|
keybindingDropdown.add(createOptionElement("Sublime", CodeMirrorKeybindingSetting.Sublime));
|
||||||
keybindingDropdown.add(createOptionElement("Vim", "vim"));
|
keybindingDropdown.add(createOptionElement("Vim", CodeMirrorKeybindingSetting.Vim));
|
||||||
keybindingDropdown.add(createOptionElement("Emacs", "emacs"));
|
keybindingDropdown.add(createOptionElement("Emacs", CodeMirrorKeybindingSetting.Emacs));
|
||||||
if (Settings.EditorKeybinding) {
|
if (Settings.EditorKeybinding) {
|
||||||
var initialIndex = 0;
|
var initialIndex = 0;
|
||||||
for (var i = 0; i < keybindingDropdown.options.length; ++i) {
|
for (var i = 0; i < keybindingDropdown.options.length; ++i) {
|
||||||
@ -311,14 +341,39 @@ class CodeMirrorEditorWrapper extends ScriptEditor {
|
|||||||
keybindingDropdown.selectedIndex = 0;
|
keybindingDropdown.selectedIndex = 0;
|
||||||
}
|
}
|
||||||
keybindingDropdown.onchange = () => {
|
keybindingDropdown.onchange = () => {
|
||||||
|
// Set Vim command display to be invisible initially
|
||||||
|
this.vimCommandDisplayWrapper.style.display = "none";
|
||||||
|
|
||||||
const val = keybindingDropdown.value;
|
const val = keybindingDropdown.value;
|
||||||
Settings.EditorKeybinding = val;
|
Settings.EditorKeybinding = val;
|
||||||
this.editor.removeKeyMap("sublime");
|
this.editor.removeKeyMap(CodeMirror.keyMap.default);
|
||||||
this.editor.removeKeyMap("emacs");
|
this.editor.removeKeyMap(CodeMirror.keyMap.sublime);
|
||||||
this.editor.removeKeyMap("vim");
|
this.editor.removeKeyMap(CodeMirror.keyMap.emacs);
|
||||||
|
this.editor.removeKeyMap(CodeMirror.keyMap.vim);
|
||||||
|
|
||||||
|
// Setup the VIM command display
|
||||||
|
let keys = '';
|
||||||
|
const handleVimKeyPress = (key) => {
|
||||||
|
keys = keys + key;
|
||||||
|
this.vimCommandDisplay.innerHTML = keys;
|
||||||
|
}
|
||||||
|
const handleVimCommandDone = (e) => {
|
||||||
|
keys = '';
|
||||||
|
this.vimCommandDisplay.innerHTML = keys;
|
||||||
|
}
|
||||||
|
if (val === CodeMirrorKeybindingSetting.Vim) {
|
||||||
|
this.vimCommandDisplayWrapper.style.display = "block";
|
||||||
|
this.editor.on('vim-keypress', handleVimKeyPress);
|
||||||
|
this.editor.on('vim-command-done', handleVimCommandDone);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
this.vimCommandDisplayWrapper.style.display = "none";
|
||||||
|
this.editor.off('vim-keypress', handleVimKeyPress);
|
||||||
|
this.editor.off('vim-command-done', handleVimCommandDone);
|
||||||
|
}
|
||||||
|
|
||||||
this.editor.addKeyMap(val);
|
this.editor.addKeyMap(val);
|
||||||
this.editor.setOption("keyMap", val);
|
this.editor.setOption("keyMap", val);
|
||||||
console.log(`Set keymap to ${val} for CodeMirror`);
|
|
||||||
};
|
};
|
||||||
keybindingDropdown.onchange();
|
keybindingDropdown.onchange();
|
||||||
|
|
||||||
@ -489,9 +544,8 @@ class CodeMirrorEditorWrapper extends ScriptEditor {
|
|||||||
removeFlexibleOption("script-editor-option-flex4-fieldset");
|
removeFlexibleOption("script-editor-option-flex4-fieldset");
|
||||||
|
|
||||||
this.editor.refresh();
|
this.editor.refresh();
|
||||||
console.log(this.editor.options);
|
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
console.error(`Exception caught: ${e}`);
|
console.error(`Exception caught: ${e}. ${e.stack}`);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,8 +33,12 @@
|
|||||||
}
|
}
|
||||||
const sanitizedText = splitText.join("\n");
|
const sanitizedText = splitText.join("\n");
|
||||||
|
|
||||||
|
// Configure JSHINT options
|
||||||
if (!options.indent) // JSHint error.character actually is a column index, this fixes underlining on lines using tabs for indentation
|
if (!options.indent) // JSHint error.character actually is a column index, this fixes underlining on lines using tabs for indentation
|
||||||
options.indent = 1; // JSHint default value is 4
|
options.indent = 1; // JSHint default value is 4
|
||||||
|
|
||||||
|
options.esversion = 6;
|
||||||
|
|
||||||
JSHINT(sanitizedText, options, options.globals);
|
JSHINT(sanitizedText, options, options.globals);
|
||||||
var errors = JSHINT.data().errors, result = [];
|
var errors = JSHINT.data().errors, result = [];
|
||||||
if (errors) parseErrors(errors, result);
|
if (errors) parseErrors(errors, result);
|
@ -1,16 +1,46 @@
|
|||||||
import {CONSTANTS} from "./Constants";
|
/**
|
||||||
import {Player} from "./Player";
|
* Implements functions for purchasing servers or purchasing more RAM for
|
||||||
import {Server, AllServers, AddToAllServers} from "./Server";
|
* the home computer
|
||||||
import {dialogBoxCreate} from "../utils/DialogBox";
|
|
||||||
import {createRandomIp} from "../utils/IPAddress";
|
|
||||||
import {yesNoTxtInpBoxGetInput} from "../utils/YesNoBox";
|
|
||||||
|
|
||||||
|
|
||||||
/* Functions to handle any server-related purchasing:
|
|
||||||
* Purchasing new servers
|
|
||||||
* Purchasing more RAM for home computer
|
|
||||||
*/
|
*/
|
||||||
function purchaseServer(ram, cost) {
|
import { BitNodeMultipliers } from "./BitNode/BitNodeMultipliers";
|
||||||
|
import { CONSTANTS } from "./Constants";
|
||||||
|
import { Player } from "./Player";
|
||||||
|
import { Server,
|
||||||
|
AllServers,
|
||||||
|
AddToAllServers} from "./Server";
|
||||||
|
import { dialogBoxCreate } from "../utils/DialogBox";
|
||||||
|
import { createRandomIp } from "../utils/IPAddress";
|
||||||
|
import { yesNoTxtInpBoxGetInput } from "../utils/YesNoBox";
|
||||||
|
import { isPowerOfTwo } from "../utils/helpers/isPowerOfTwo";
|
||||||
|
|
||||||
|
// Returns the cost of purchasing a server with the given RAM
|
||||||
|
// Returns Infinity for invalid 'ram' arguments
|
||||||
|
export function getPurchaseServerCost(ram) {
|
||||||
|
const sanitizedRam = Math.round(ram);
|
||||||
|
if (isNaN(sanitizedRam) || !isPowerOfTwo(sanitizedRam)) {
|
||||||
|
return Infinity;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sanitizedRam > getPurchaseServerMaxRam()) {
|
||||||
|
return Infinity;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sanitizedRam * CONSTANTS.BaseCostFor1GBOfRamServer * BitNodeMultipliers.PurchasedServerCost;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getPurchaseServerLimit() {
|
||||||
|
return Math.round(CONSTANTS.PurchasedServerLimit * BitNodeMultipliers.PurchasedServerLimit);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getPurchaseServerMaxRam() {
|
||||||
|
// TODO ensure this is a power of 2?
|
||||||
|
return Math.round(CONSTANTS.PurchasedServerMaxRam * BitNodeMultipliers.PurchasedServerMaxRam);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Manually purchase a server (NOT through Netscript)
|
||||||
|
export function purchaseServer(ram) {
|
||||||
|
const cost = getPurchaseServerCost(ram);
|
||||||
|
|
||||||
//Check if player has enough money
|
//Check if player has enough money
|
||||||
if (Player.money.lt(cost)) {
|
if (Player.money.lt(cost)) {
|
||||||
dialogBoxCreate("You don't have enough money to purchase this server!");
|
dialogBoxCreate("You don't have enough money to purchase this server!");
|
||||||
@ -18,8 +48,8 @@ function purchaseServer(ram, cost) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Maximum server limit
|
//Maximum server limit
|
||||||
if (Player.purchasedServers.length >= CONSTANTS.PurchasedServerLimit) {
|
if (Player.purchasedServers.length >= getPurchaseServerLimit()) {
|
||||||
dialogBoxCreate("You have reached the maximum limit of " + CONSTANTS.PurchasedServerLimit + " servers. " +
|
dialogBoxCreate("You have reached the maximum limit of " + getPurchaseServerLimit() + " servers. " +
|
||||||
"You cannot purchase any more. You can " +
|
"You cannot purchase any more. You can " +
|
||||||
"delete some of your purchased servers using the deleteServer() Netscript function in a script");
|
"delete some of your purchased servers using the deleteServer() Netscript function in a script");
|
||||||
return;
|
return;
|
||||||
@ -51,8 +81,8 @@ function purchaseServer(ram, cost) {
|
|||||||
dialogBoxCreate("Server successfully purchased with hostname " + hostname);
|
dialogBoxCreate("Server successfully purchased with hostname " + hostname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Manually upgrade RAM on home computer (NOT through Netscript)
|
||||||
function purchaseRamForHomeComputer(cost) {
|
export function purchaseRamForHomeComputer(cost) {
|
||||||
if (Player.money.lt(cost)) {
|
if (Player.money.lt(cost)) {
|
||||||
dialogBoxCreate("You do not have enough money to purchase additional RAM for your home computer");
|
dialogBoxCreate("You do not have enough money to purchase additional RAM for your home computer");
|
||||||
return;
|
return;
|
||||||
@ -70,5 +100,3 @@ function purchaseRamForHomeComputer(cost) {
|
|||||||
|
|
||||||
dialogBoxCreate("Purchased additional RAM for home computer! It now has " + homeComputer.maxRam + "GB of RAM.");
|
dialogBoxCreate("Purchased additional RAM for home computer! It now has " + homeComputer.maxRam + "GB of RAM.");
|
||||||
}
|
}
|
||||||
|
|
||||||
export {purchaseServer, purchaseRamForHomeComputer};
|
|
||||||
|
@ -1,5 +1,27 @@
|
|||||||
// Enums that defined allowed values for setting configuration
|
// Enums that defined allowed values for setting configuration
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allowed values for 'Keybinding/Keymap' setting in Ace editor
|
||||||
|
*/
|
||||||
|
export enum AceKeybindingSetting {
|
||||||
|
Ace = "ace",
|
||||||
|
Emacs = "emacs",
|
||||||
|
Vim = "vim",
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allowed values for 'Keybinding/Keymap' setting in Code Mirror editor
|
||||||
|
*/
|
||||||
|
export enum CodeMirrorKeybindingSetting {
|
||||||
|
Default = "default",
|
||||||
|
Emacs = "emacs",
|
||||||
|
Sublime = "sublime",
|
||||||
|
Vim = "vim",
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allowed values for 'Theme' setting in Code Mirror editor
|
||||||
|
*/
|
||||||
export enum CodeMirrorThemeSetting {
|
export enum CodeMirrorThemeSetting {
|
||||||
Monokai = "monokai",
|
Monokai = "monokai",
|
||||||
Day_3024 = "3024-day",
|
Day_3024 = "3024-day",
|
||||||
@ -57,6 +79,7 @@ export enum CodeMirrorThemeSetting {
|
|||||||
Yeti = "yeti",
|
Yeti = "yeti",
|
||||||
Zenburn = "zenburn",
|
Zenburn = "zenburn",
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allowed values for the "Editor" setting
|
* Allowed values for the "Editor" setting
|
||||||
*/
|
*/
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
import { ISelfInitializer, ISelfLoading } from "../types";
|
import { ISelfInitializer, ISelfLoading } from "../types";
|
||||||
import { CodeMirrorThemeSetting,
|
import { AceKeybindingSetting,
|
||||||
|
CodeMirrorKeybindingSetting,
|
||||||
|
CodeMirrorThemeSetting,
|
||||||
EditorSetting,
|
EditorSetting,
|
||||||
OwnedAugmentationsOrderSetting,
|
OwnedAugmentationsOrderSetting,
|
||||||
PurchaseAugmentationsOrderSetting } from "./SettingEnums";
|
PurchaseAugmentationsOrderSetting } from "./SettingEnums";
|
||||||
@ -77,7 +79,7 @@ interface ISettings extends IDefaultSettings {
|
|||||||
* The keybinding to use in the script editor.
|
* The keybinding to use in the script editor.
|
||||||
* TODO: This should really be an enum of allowed values.
|
* TODO: This should really be an enum of allowed values.
|
||||||
*/
|
*/
|
||||||
EditorKeybinding: string;
|
EditorKeybinding: AceKeybindingSetting | CodeMirrorKeybindingSetting;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The theme used in the script editor.
|
* The theme used in the script editor.
|
||||||
@ -119,7 +121,7 @@ export const Settings: ISettings & ISelfInitializer & ISelfLoading = {
|
|||||||
CodeInstructionRunTime: 25,
|
CodeInstructionRunTime: 25,
|
||||||
DisableHotkeys: defaultSettings.DisableHotkeys,
|
DisableHotkeys: defaultSettings.DisableHotkeys,
|
||||||
Editor: EditorSetting.Ace,
|
Editor: EditorSetting.Ace,
|
||||||
EditorKeybinding: "ace",
|
EditorKeybinding: AceKeybindingSetting.Ace,
|
||||||
EditorTheme: "Monokai",
|
EditorTheme: "Monokai",
|
||||||
Locale: "en",
|
Locale: "en",
|
||||||
MaxLogCapacity: defaultSettings.MaxLogCapacity,
|
MaxLogCapacity: defaultSettings.MaxLogCapacity,
|
||||||
|
@ -564,6 +564,7 @@ const Engine = {
|
|||||||
MainMenuLinks.Factions.classList.remove("active");
|
MainMenuLinks.Factions.classList.remove("active");
|
||||||
MainMenuLinks.Augmentations.classList.remove("active");
|
MainMenuLinks.Augmentations.classList.remove("active");
|
||||||
MainMenuLinks.HacknetNodes.classList.remove("active");
|
MainMenuLinks.HacknetNodes.classList.remove("active");
|
||||||
|
MainMenuLinks.Sleeves.classList.remove("active");
|
||||||
MainMenuLinks.City.classList.remove("active");
|
MainMenuLinks.City.classList.remove("active");
|
||||||
MainMenuLinks.Travel.classList.remove("active");
|
MainMenuLinks.Travel.classList.remove("active");
|
||||||
MainMenuLinks.Job.classList.remove("active");
|
MainMenuLinks.Job.classList.remove("active");
|
||||||
@ -1580,6 +1581,7 @@ const Engine = {
|
|||||||
const errorMsg = "Failed to initialize Main Menu Links. Please try refreshing the page. " +
|
const errorMsg = "Failed to initialize Main Menu Links. Please try refreshing the page. " +
|
||||||
"If that doesn't work, report the issue to the developer";
|
"If that doesn't work, report the issue to the developer";
|
||||||
exceptionAlert(new Error(errorMsg));
|
exceptionAlert(new Error(errorMsg));
|
||||||
|
console.error(errorMsg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -1596,6 +1598,7 @@ const Engine = {
|
|||||||
const errorMsg = "Failed to initialize Main Menu Headers. Please try refreshing the page. " +
|
const errorMsg = "Failed to initialize Main Menu Headers. Please try refreshing the page. " +
|
||||||
"If that doesn't work, report the issue to the developer";
|
"If that doesn't work, report the issue to the developer";
|
||||||
exceptionAlert(new Error(errorMsg));
|
exceptionAlert(new Error(errorMsg));
|
||||||
|
console.error(errorMsg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1641,6 +1644,7 @@ const Engine = {
|
|||||||
|
|
||||||
MainMenuLinks.Sleeves.addEventListener("click", function() {
|
MainMenuLinks.Sleeves.addEventListener("click", function() {
|
||||||
Engine.loadSleevesContent();
|
Engine.loadSleevesContent();
|
||||||
|
MainMenuLinks.Sleeves.classList.add("active");
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -122,6 +122,9 @@ if (htmlWebpackPlugin.options.googleAnalytics.trackingId) { %>
|
|||||||
|
|
||||||
<div id="ace-editor"></div>
|
<div id="ace-editor"></div>
|
||||||
<form id="codemirror-form-wrapper"><textarea id="codemirror-editor"></textarea></form>
|
<form id="codemirror-form-wrapper"><textarea id="codemirror-editor"></textarea></form>
|
||||||
|
<div id="codemirror-vim-command-display-wrapper">
|
||||||
|
Key Buffer: <span id="codemirror-vim-command-display"></span>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div id="script-editor-buttons-wrapper"></div> <!-- Buttons below script editor -->
|
<div id="script-editor-buttons-wrapper"></div> <!-- Buttons below script editor -->
|
||||||
</div> <!-- End wrapper -->
|
</div> <!-- End wrapper -->
|
||||||
|
@ -65,7 +65,7 @@ export function initializeMainMenuLinks(): boolean {
|
|||||||
MainMenuLinks.Factions = safeGetLink("factions-menu-link");
|
MainMenuLinks.Factions = safeGetLink("factions-menu-link");
|
||||||
MainMenuLinks.Augmentations = safeGetLink("augmentations-menu-link");
|
MainMenuLinks.Augmentations = safeGetLink("augmentations-menu-link");
|
||||||
MainMenuLinks.HacknetNodes = safeGetLink("hacknet-nodes-menu-link");
|
MainMenuLinks.HacknetNodes = safeGetLink("hacknet-nodes-menu-link");
|
||||||
MainMenuLinks.Sleeves = safeGetLink("sleeves-menu-link");
|
MainMenuLinks.Sleeves = safeGetLink("sleeves-menu-link");
|
||||||
MainMenuLinks.City = safeGetLink("city-menu-link");
|
MainMenuLinks.City = safeGetLink("city-menu-link");
|
||||||
MainMenuLinks.Travel = safeGetLink("travel-menu-link");
|
MainMenuLinks.Travel = safeGetLink("travel-menu-link");
|
||||||
MainMenuLinks.Job = safeGetLink("job-menu-link");
|
MainMenuLinks.Job = safeGetLink("job-menu-link");
|
||||||
|
@ -5,9 +5,15 @@ import { getElementById } from "./getElementById";
|
|||||||
* replacing. Then returns the new cloned element.
|
* replacing. Then returns the new cloned element.
|
||||||
* @param elemId The HTML ID to retrieve the element by.
|
* @param elemId The HTML ID to retrieve the element by.
|
||||||
*/
|
*/
|
||||||
export function clearEventListeners(elemId: string): HTMLElement | null {
|
export function clearEventListeners(elemId: string | HTMLElement): HTMLElement | null {
|
||||||
try {
|
try {
|
||||||
const elem: HTMLElement = getElementById(elemId);
|
let elem: HTMLElement;
|
||||||
|
if (typeof elemId === "string") {
|
||||||
|
elem = getElementById(elemId);
|
||||||
|
} else {
|
||||||
|
elem = elemId;
|
||||||
|
}
|
||||||
|
|
||||||
const newElem: HTMLElement = elem.cloneNode(true) as HTMLElement;
|
const newElem: HTMLElement = elem.cloneNode(true) as HTMLElement;
|
||||||
if (elem.parentNode !== null) {
|
if (elem.parentNode !== null) {
|
||||||
elem.parentNode.replaceChild(newElem, elem);
|
elem.parentNode.replaceChild(newElem, elem);
|
||||||
|
Reference in New Issue
Block a user