Merge pull request #1491 from danielyxie/dev

Added atExit
This commit is contained in:
hydroflame
2021-10-14 20:13:43 -04:00
committed by GitHub
47 changed files with 2502 additions and 14236 deletions

22
dist/vendor.bundle.js vendored

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,18 @@
atExit() Netscript Function
============================
.. js:function:: atExit(f)
:RAM cost: 0 GB
:param function f: function to call when the script dies.
Runs when the script dies.
Example:
.. code-block:: javascript
function onDeath() {
console.log('I died!!!')
}
atExit(onDeath);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

14362
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -14,7 +14,6 @@
"@emotion/styled": "^11.3.0", "@emotion/styled": "^11.3.0",
"@monaco-editor/react": "^4.2.2", "@monaco-editor/react": "^4.2.2",
"@mui/icons-material": "^5.0.3", "@mui/icons-material": "^5.0.3",
"@mui/lab": "^5.0.0-alpha.46",
"@mui/material": "^5.0.3", "@mui/material": "^5.0.3",
"@mui/styles": "^5.0.1", "@mui/styles": "^5.0.1",
"@types/escodegen": "^0.0.7", "@types/escodegen": "^0.0.7",
@ -25,47 +24,23 @@
"@types/react-resizable": "^1.7.3", "@types/react-resizable": "^1.7.3",
"acorn": "^8.4.1", "acorn": "^8.4.1",
"acorn-walk": "^8.1.1", "acorn-walk": "^8.1.1",
"ajv": "^5.1.5",
"ajv-keywords": "^2.0.0",
"arg": "^5.0.0", "arg": "^5.0.0",
"async": "^2.6.1",
"autosize": "^4.0.2",
"better-react-mathjax": "^1.0.3", "better-react-mathjax": "^1.0.3",
"brace": "^0.11.1", "clsx": "^1.1.1",
"codemirror": "^5.58.2",
"decimal.js": "7.2.3", "decimal.js": "7.2.3",
"enhanced-resolve": "^4.0.0",
"escodegen": "^1.11.0", "escodegen": "^1.11.0",
"escope": "^3.6.0",
"file-saver": "^1.3.8", "file-saver": "^1.3.8",
"interpret": "^1.0.0",
"jquery": "^3.5.0", "jquery": "^3.5.0",
"jshint": "^2.10.2",
"json-loader": "^0.5.4",
"jsplumb": "^2.6.8",
"jszip": "^3.7.0", "jszip": "^3.7.0",
"loader-runner": "^2.3.0",
"loader-utils": "^1.1.0",
"material-ui-color": "^1.2.0", "material-ui-color": "^1.2.0",
"mathjax-full": "^3.2.0",
"memory-fs": "~0.4.1",
"monaco-editor": "^0.27.0", "monaco-editor": "^0.27.0",
"node-sass": "^6.0.1",
"normalize.css": "^8.0.0",
"notistack": "^2.0.2", "notistack": "^2.0.2",
"numeral": "2.0.6", "numeral": "2.0.6",
"react": "^17.0.2", "react": "^17.0.2",
"react-dom": "^17.0.2", "react-dom": "^17.0.2",
"react-draggable": "^4.4.4", "react-draggable": "^4.4.4",
"react-modal": "^3.12.1",
"react-resizable": "^3.0.4", "react-resizable": "^3.0.4",
"sprintf-js": "^1.1.1", "sprintf-js": "^1.1.1"
"tapable": "^1.0.0",
"treant-js": "^1.0.1",
"unused-webpack-plugin": "^2.4.0",
"uuid": "^3.2.1",
"w3c-blob": "0.0.1",
"webpack-deadcode-plugin": "^0.1.15"
}, },
"description": "A cyberpunk-themed incremental game", "description": "A cyberpunk-themed incremental game",
"devDependencies": { "devDependencies": {
@ -76,64 +51,33 @@
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.1", "@pmmmwh/react-refresh-webpack-plugin": "^0.5.1",
"@testing-library/cypress": "^8.0.1", "@testing-library/cypress": "^8.0.1",
"@types/file-saver": "^2.0.3", "@types/file-saver": "^2.0.3",
"@types/jest": "^27.0.1",
"@types/lodash": "^4.14.168", "@types/lodash": "^4.14.168",
"@types/node": "^16.9.1",
"@typescript-eslint/eslint-plugin": "^4.22.0", "@typescript-eslint/eslint-plugin": "^4.22.0",
"@typescript-eslint/parser": "^4.22.0", "@typescript-eslint/parser": "^4.22.0",
"babel-jest": "^27.0.6", "babel-jest": "^27.0.6",
"babel-loader": "^8.0.5", "babel-loader": "^8.0.5",
"beautify-lint": "^1.0.3",
"benchmark": "^2.1.1",
"bundle-loader": "~0.5.0",
"css-loader": "^0.28.11",
"cypress": "^8.3.1", "cypress": "^8.3.1",
"electron": "^14.0.1", "electron": "^14.0.1",
"electron-packager": "^15.4.0", "electron-packager": "^15.4.0",
"es6-promise-polyfill": "^1.1.1",
"eslint": "^7.24.0", "eslint": "^7.24.0",
"eslint-plugin-node": "^11.1.0",
"file-loader": "^1.1.11",
"fork-ts-checker-webpack-plugin": "^6.3.3", "fork-ts-checker-webpack-plugin": "^6.3.3",
"html-webpack-plugin": "^3.2.0", "html-webpack-plugin": "^3.2.0",
"http-server": "^13.0.1", "http-server": "^13.0.1",
"i18n-webpack-plugin": "^1.0.0",
"istanbul": "^0.4.5",
"jest": "^27.1.0", "jest": "^27.1.0",
"js-beautify": "^1.5.10", "js-beautify": "^1.5.10",
"jsdom": "^15.0.0", "jsdom": "^15.0.0",
"jsdom-global": "^3.0.2",
"json5": "^1.0.1",
"less": "^3.9.0",
"less-loader": "^4.1.0",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"mini-css-extract-plugin": "^0.4.1", "mini-css-extract-plugin": "^0.4.1",
"mkdirp": "^0.5.1",
"null-loader": "^1.0.0",
"prettier": "^2.3.2", "prettier": "^2.3.2",
"raw-loader": "~0.5.0",
"react-refresh": "^0.10.0", "react-refresh": "^0.10.0",
"regenerator-runtime": "^0.13.9", "regenerator-runtime": "^0.13.9",
"sass-loader": "^7.0.3",
"script-loader": "~0.7.0",
"should": "^11.1.1",
"simple-git": "^1.96.0",
"sinon": "^2.3.2",
"source-map": "^0.7.3", "source-map": "^0.7.3",
"start-server-and-test": "^1.14.0", "start-server-and-test": "^1.14.0",
"style-loader": "^0.21.0",
"stylelint": "^9.2.1",
"stylelint-order": "^0.8.1",
"typescript": "^4.2.4", "typescript": "^4.2.4",
"uglify-es": "^3.3.9",
"uglifyjs-webpack-plugin": "^1.3.0",
"url-loader": "^1.0.1",
"watchpack": "^1.6.0",
"webpack": "^4.46.0", "webpack": "^4.46.0",
"webpack-cli": "^3.3.12", "webpack-cli": "^3.3.12",
"webpack-dev-middleware": "^3.7.3", "webpack-dev-middleware": "^3.7.3",
"webpack-dev-server": "^3.11.2", "webpack-dev-server": "^3.11.2"
"worker-loader": "^2.0.0"
}, },
"engines": { "engines": {
"node": ">=8 || <=9" "node": ">=8 || <=9"
@ -157,7 +101,6 @@
"build:dev": "webpack --mode development", "build:dev": "webpack --mode development",
"lint": "npm run lint:jsts & npm run lint:style", "lint": "npm run lint:jsts & npm run lint:style",
"lint:jsts": "eslint --fix . --ext js,jsx,ts,tsx", "lint:jsts": "eslint --fix . --ext js,jsx,ts,tsx",
"lint:style": "stylelint --fix ./css/*",
"preinstall": "node ./scripts/engines-check.js", "preinstall": "node ./scripts/engines-check.js",
"test": "jest", "test": "jest",
"test:watch": "jest --watch", "test:watch": "jest --watch",

View File

@ -2,366 +2,433 @@ const numSpaces = 4;
const maxLineLength = 160; const maxLineLength = 160;
module.exports = { module.exports = {
env: { "env": {
es6: true, "es6": true,
node: true, "node": true
},
extends: "eslint:recommended",
parserOptions: {
ecmaFeatures: {
experimentalObjectRestSpread: true,
}, },
ecmaVersion: 8, "extends": "eslint:recommended",
sourceType: "module", "parserOptions": {
}, "ecmaFeatures": {
rules: { "experimentalObjectRestSpread": true
"accessor-pairs": [ },
"error", "ecmaVersion": 8,
{ "sourceType": "module"
getWithoutSet: false, },
setWithoutGet: true, "rules": {
}, "accessor-pairs": [
], "error",
"array-bracket-newline": ["error"], {
"array-bracket-spacing": ["error"], "getWithoutSet": false,
"array-callback-return": ["error"], "setWithoutGet": true
"array-element-newline": ["error"], }
"arrow-body-style": ["error"], ],
"arrow-parens": ["error"], "array-bracket-newline": ["error"],
"arrow-spacing": ["error"], "array-bracket-spacing": ["error"],
"block-scoped-var": ["error"], "array-callback-return": ["error"],
"block-spacing": ["error"], "array-element-newline": ["error"],
"brace-style": ["error"], "arrow-body-style": ["error"],
"callback-return": ["error"], "arrow-parens": ["error"],
camelcase: ["error"], "arrow-spacing": ["error"],
"capitalized-comments": ["error"], "block-scoped-var": ["error"],
"class-methods-use-this": ["error"], "block-spacing": ["error"],
"comma-dangle": ["error"], "brace-style": ["error"],
"comma-spacing": ["error"], "callback-return": ["error"],
"comma-style": ["error", "last"], "camelcase": ["error"],
complexity: ["error"], "capitalized-comments": ["error"],
"computed-property-spacing": ["error", "never"], "class-methods-use-this": ["error"],
"consistent-return": ["error"], "comma-dangle": ["error"],
"consistent-this": ["error"], "comma-spacing": ["error"],
"constructor-super": ["error"], "comma-style": [
curly: ["error"], "error",
"default-case": ["error"], "last"
"dot-location": ["error", "property"], ],
"dot-notation": ["error"], "complexity": ["error"],
"eol-last": ["error"], "computed-property-spacing": [
eqeqeq: ["error"], "error",
"for-direction": ["error"], "never"
"func-call-spacing": ["error"], ],
"func-name-matching": ["error"], "consistent-return": ["error"],
"func-names": ["error", "never"], "consistent-this": ["error"],
"func-style": ["error"], "constructor-super": ["error"],
"function-paren-newline": ["error"], "curly": ["error"],
"generator-star-spacing": ["error", "before"], "default-case": ["error"],
"getter-return": [ "dot-location": [
"error", "error",
{ "property"
allowImplicit: false, ],
}, "dot-notation": ["error"],
], "eol-last": ["error"],
"global-require": ["error"], "eqeqeq": ["error"],
"guard-for-in": ["error"], "for-direction": ["error"],
"handle-callback-err": ["error"], "func-call-spacing": ["error"],
"id-blacklist": ["error"], "func-name-matching": ["error"],
"id-length": ["error"], "func-names": [
"id-match": ["error"], "error",
"implicit-arrow-linebreak": ["error", "beside"], "never"
indent: [ ],
"error", "func-style": ["error"],
numSpaces, "function-paren-newline": ["error"],
{ "generator-star-spacing": [
SwitchCase: 1, "error",
}, "before"
], ],
"init-declarations": ["error"], "getter-return": [
"jsx-quotes": ["error"], "error",
"key-spacing": ["error"], {
"keyword-spacing": ["error"], "allowImplicit": false
"line-comment-position": ["error"], }
"linebreak-style": ["error", "windows"], ],
"lines-around-comment": ["error"], "global-require": ["error"],
"lines-between-class-members": ["error"], "guard-for-in": ["error"],
"max-depth": ["error"], "handle-callback-err": ["error"],
"max-len": ["error", maxLineLength], "id-blacklist": ["error"],
"max-lines": [ "id-length": ["error"],
"error", "id-match": ["error"],
{ "implicit-arrow-linebreak": [
skipBlankLines: true, "error",
skipComments: true, "beside"
}, ],
], "indent": [
"max-nested-callbacks": ["error"], "error",
"max-params": ["error"], numSpaces,
"max-statements": ["error"], {
"max-statements-per-line": ["error"], "SwitchCase": 1
"multiline-comment-style": ["off", "starred-block"], }
"multiline-ternary": ["error", "never"], ],
"new-cap": ["error"], "init-declarations": ["error"],
"new-parens": ["error"], "jsx-quotes": ["error"],
// TODO: configure this... "key-spacing": ["error"],
"newline-before-return": ["error"], "keyword-spacing": ["error"],
"newline-per-chained-call": ["error"], "line-comment-position": ["error"],
"no-alert": ["error"], "linebreak-style": [
"no-array-constructor": ["error"], "error",
"no-await-in-loop": ["error"], "windows"
"no-bitwise": ["error"], ],
"no-buffer-constructor": ["error"], "lines-around-comment": ["error"],
"no-caller": ["error"], "lines-between-class-members": ["error"],
"no-case-declarations": ["error"], "max-depth": ["error"],
"no-catch-shadow": ["error"], "max-len": [
"no-class-assign": ["error"], "error",
"no-compare-neg-zero": ["error"], maxLineLength
"no-cond-assign": ["error", "except-parens"], ],
"no-confusing-arrow": ["error"], "max-lines": [
"no-console": ["error"], "error",
"no-const-assign": ["error"], {
"no-constant-condition": [ "skipBlankLines": true,
"error", "skipComments": true
{ }
checkLoops: false, ],
}, "max-nested-callbacks": ["error"],
], "max-params": ["error"],
"no-continue": ["off"], "max-statements": ["error"],
"no-control-regex": ["error"], "max-statements-per-line": ["error"],
"no-debugger": ["error"], "multiline-comment-style": [
"no-delete-var": ["error"], "off",
"no-div-regex": ["error"], "starred-block"
"no-dupe-args": ["error"], ],
"no-dupe-class-members": ["error"], "multiline-ternary": [
"no-dupe-keys": ["error"], "error",
"no-duplicate-case": ["error"], "never"
"no-duplicate-imports": [ ],
"error", "new-cap": ["error"],
{ "new-parens": ["error"],
includeExports: true, // TODO: configure this...
}, "newline-before-return": ["error"],
], "newline-per-chained-call": ["error"],
"no-else-return": ["error"], "no-alert": ["error"],
"no-empty": [ "no-array-constructor": ["error"],
"error", "no-await-in-loop": ["error"],
{ "no-bitwise": ["error"],
allowEmptyCatch: false, "no-buffer-constructor": ["error"],
}, "no-caller": ["error"],
], "no-case-declarations": ["error"],
"no-empty-character-class": ["error"], "no-catch-shadow": ["error"],
"no-empty-function": ["error"], "no-class-assign": ["error"],
"no-empty-pattern": ["error"], "no-compare-neg-zero": ["error"],
"no-eq-null": ["error"], "no-cond-assign": [
"no-eval": ["error"], "error",
"no-ex-assign": ["error"], "except-parens"
"no-extend-native": ["error"], ],
"no-extra-bind": ["error"], "no-confusing-arrow": ["error"],
"no-extra-boolean-cast": ["error"], "no-console": ["error"],
"no-extra-label": ["error"], "no-const-assign": ["error"],
"no-extra-parens": [ "no-constant-condition": [
"error", "error",
"all", {
{ "checkLoops": false
conditionalAssign: false, }
}, ],
], "no-continue": ["off"],
"no-extra-semi": ["error"], "no-control-regex": ["error"],
"no-fallthrough": ["error"], "no-debugger": ["error"],
"no-floating-decimal": ["error"], "no-delete-var": ["error"],
"no-func-assign": ["error"], "no-div-regex": ["error"],
"no-global-assign": ["error"], "no-dupe-args": ["error"],
"no-implicit-coercion": ["error"], "no-dupe-class-members": ["error"],
"no-implicit-globals": ["error"], "no-dupe-keys": ["error"],
"no-implied-eval": ["error"], "no-duplicate-case": ["error"],
"no-inline-comments": ["error"], "no-duplicate-imports": [
"no-inner-declarations": ["error", "both"], "error",
"no-invalid-regexp": ["error"], {
"no-invalid-this": ["error"], "includeExports": true
"no-irregular-whitespace": [ }
"error", ],
{ "no-else-return": ["error"],
skipComments: false, "no-empty": [
skipRegExps: false, "error",
skipStrings: false, {
skipTemplates: false, "allowEmptyCatch": false
}, }
], ],
"no-iterator": ["error"], "no-empty-character-class": ["error"],
"no-label-var": ["error"], "no-empty-function": ["error"],
"no-labels": ["error"], "no-empty-pattern": ["error"],
"no-lone-blocks": ["error"], "no-eq-null": ["error"],
"no-lonely-if": ["error"], "no-eval": ["error"],
"no-loop-func": ["error"], "no-ex-assign": ["error"],
"no-magic-numbers": [ "no-extend-native": ["error"],
"error", "no-extra-bind": ["error"],
{ "no-extra-boolean-cast": ["error"],
ignore: [-1, 0, 1], "no-extra-label": ["error"],
ignoreArrayIndexes: true, "no-extra-parens": [
}, "error",
], "all",
"no-mixed-operators": ["error"], {
"no-mixed-requires": ["error"], "conditionalAssign": false
"no-mixed-spaces-and-tabs": ["error"], }
"no-multi-assign": ["error"], ],
"no-multi-spaces": ["error"], "no-extra-semi": ["error"],
"no-multi-str": ["error"], "no-fallthrough": ["error"],
"no-multiple-empty-lines": [ "no-floating-decimal": ["error"],
"error", "no-func-assign": ["error"],
{ "no-global-assign": ["error"],
max: 1, "no-implicit-coercion": ["error"],
}, "no-implicit-globals": ["error"],
], "no-implied-eval": ["error"],
"no-native-reassign": ["error"], "no-inline-comments": ["error"],
"no-negated-condition": ["error"], "no-inner-declarations": [
"no-negated-in-lhs": ["error"], "error",
"no-nested-ternary": ["error"], "both"
"no-new": ["error"], ],
"no-new-func": ["error"], "no-invalid-regexp": ["error"],
"no-new-object": ["error"], "no-invalid-this": ["error"],
"no-new-require": ["error"], "no-irregular-whitespace": [
"no-new-symbol": ["error"], "error",
"no-new-wrappers": ["error"], {
"no-obj-calls": ["error"], "skipComments": false,
"no-octal": ["error"], "skipRegExps": false,
"no-octal-escape": ["error"], "skipStrings": false,
"no-param-reassign": ["error"], "skipTemplates": false
"no-path-concat": ["error"], }
"no-plusplus": [ ],
"error", "no-iterator": ["error"],
{ "no-label-var": ["error"],
allowForLoopAfterthoughts: true, "no-labels": ["error"],
}, "no-lone-blocks": ["error"],
], "no-lonely-if": ["error"],
"no-process-env": ["error"], "no-loop-func": ["error"],
"no-process-exit": ["error"], "no-magic-numbers": [
"no-proto": ["error"], "error",
"no-prototype-builtins": ["error"], {
"no-redeclare": ["error"], "ignore": [
"no-regex-spaces": ["error"], -1,
"no-restricted-globals": ["error"], 0,
"no-restricted-imports": ["error"], 1
"no-restricted-modules": ["error"], ],
"no-restricted-properties": [ "ignoreArrayIndexes": true
"error", }
{ ],
message: "'log' is too general, use an appropriate level when logging.", "no-mixed-operators": ["error"],
object: "console", "no-mixed-requires": ["error"],
property: "log", "no-mixed-spaces-and-tabs": ["error"],
}, "no-multi-assign": ["error"],
], "no-multi-spaces": ["error"],
"no-restricted-syntax": ["error"], "no-multi-str": ["error"],
"no-return-assign": ["error"], "no-multiple-empty-lines": [
"no-return-await": ["error"], "error",
"no-script-url": ["error"], {
"no-self-assign": [ "max": 1
"error", }
{ ],
props: false, "no-native-reassign": ["error"],
}, "no-negated-condition": ["error"],
], "no-negated-in-lhs": ["error"],
"no-self-compare": ["error"], "no-nested-ternary": ["error"],
"no-sequences": ["error"], "no-new": ["error"],
"no-shadow": ["error"], "no-new-func": ["error"],
"no-shadow-restricted-names": ["error"], "no-new-object": ["error"],
"no-spaced-func": ["error"], "no-new-require": ["error"],
"no-sparse-arrays": ["error"], "no-new-symbol": ["error"],
"no-sync": ["error"], "no-new-wrappers": ["error"],
"no-tabs": ["error"], "no-obj-calls": ["error"],
"no-template-curly-in-string": ["error"], "no-octal": ["error"],
"no-ternary": ["off"], "no-octal-escape": ["error"],
"no-this-before-super": ["error"], "no-param-reassign": ["error"],
"no-throw-literal": ["error"], "no-path-concat": ["error"],
"no-trailing-spaces": ["error"], "no-plusplus": [
"no-undef": ["error"], "error",
"no-undef-init": ["error"], {
"no-undefined": ["error"], "allowForLoopAfterthoughts": true
"no-underscore-dangle": ["error"], }
"no-unexpected-multiline": ["error"], ],
"no-unmodified-loop-condition": ["error"], "no-process-env": ["error"],
"no-unneeded-ternary": ["error"], "no-process-exit": ["error"],
"no-unreachable": ["error"], "no-proto": ["error"],
"no-unsafe-finally": ["error"], "no-prototype-builtins": ["error"],
"no-unsafe-negation": ["error"], "no-redeclare": ["error"],
"no-unused-expressions": ["error"], "no-regex-spaces": ["error"],
"no-unused-labels": ["error"], "no-restricted-globals": ["error"],
"no-unused-vars": ["error"], "no-restricted-imports": ["error"],
"no-use-before-define": ["error"], "no-restricted-modules": ["error"],
"no-useless-call": ["error"], "no-restricted-properties": [
"no-useless-computed-key": ["error"], "error",
"no-useless-concat": ["error"], {
"no-useless-constructor": ["error"], "message": "'log' is too general, use an appropriate level when logging.",
"no-useless-escape": ["error"], "object": "console",
"no-useless-rename": [ "property": "log"
"error", }
{ ],
ignoreDestructuring: false, "no-restricted-syntax": ["error"],
ignoreExport: false, "no-return-assign": ["error"],
ignoreImport: false, "no-return-await": ["error"],
}, "no-script-url": ["error"],
], "no-self-assign": [
"no-useless-return": ["error"], "error",
"no-var": ["error"], {
"no-void": ["error"], "props": false
"no-warning-comments": ["error"], }
"no-whitespace-before-property": ["error"], ],
"no-with": ["error"], "no-self-compare": ["error"],
"nonblock-statement-body-position": ["error", "below"], "no-sequences": ["error"],
"object-curly-newline": ["error"], "no-shadow": ["error"],
"object-curly-spacing": ["error"], "no-shadow-restricted-names": ["error"],
"object-property-newline": ["error"], "no-spaced-func": ["error"],
"object-shorthand": ["error"], "no-sparse-arrays": ["error"],
"one-var": ["off"], "no-sync": ["error"],
"one-var-declaration-per-line": ["error"], "no-tabs": ["error"],
"operator-assignment": ["error"], "no-template-curly-in-string": ["error"],
"operator-linebreak": ["error", "none"], "no-ternary": ["off"],
"padded-blocks": ["off"], "no-this-before-super": ["error"],
"padding-line-between-statements": ["error"], "no-throw-literal": ["error"],
"prefer-arrow-callback": ["error"], "no-trailing-spaces": ["error"],
"prefer-const": ["error"], "no-undef": ["error"],
"prefer-destructuring": ["off"], "no-undef-init": ["error"],
"prefer-numeric-literals": ["error"], "no-undefined": ["error"],
"prefer-promise-reject-errors": ["off"], "no-underscore-dangle": ["error"],
"prefer-reflect": ["error"], "no-unexpected-multiline": ["error"],
"prefer-rest-params": ["error"], "no-unmodified-loop-condition": ["error"],
"prefer-spread": ["error"], "no-unneeded-ternary": ["error"],
"prefer-template": ["error"], "no-unreachable": ["error"],
"quote-props": ["error"], "no-unsafe-finally": ["error"],
quotes: ["error"], "no-unsafe-negation": ["error"],
radix: ["error", "as-needed"], "no-unused-expressions": ["error"],
"require-await": ["error"], "no-unused-labels": ["error"],
"require-jsdoc": ["off"], "no-unused-vars": ["error"],
"require-yield": ["error"], "no-use-before-define": ["error"],
"rest-spread-spacing": ["error", "never"], "no-useless-call": ["error"],
semi: ["error"], "no-useless-computed-key": ["error"],
"semi-spacing": ["error"], "no-useless-concat": ["error"],
"semi-style": ["error", "last"], "no-useless-constructor": ["error"],
"sort-imports": ["error"], "no-useless-escape": ["error"],
"sort-keys": ["error"], "no-useless-rename": [
"sort-vars": ["error"], "error",
"space-before-blocks": ["error"], {
"space-before-function-paren": ["off"], "ignoreDestructuring": false,
"space-in-parens": ["error"], "ignoreExport": false,
"space-infix-ops": ["error"], "ignoreImport": false
"space-unary-ops": ["error"], }
"spaced-comment": ["error"], ],
strict: ["error"], "no-useless-return": ["error"],
"switch-colon-spacing": [ "no-var": ["error"],
"error", "no-void": ["error"],
{ "no-warning-comments": ["error"],
after: true, "no-whitespace-before-property": ["error"],
before: false, "no-with": ["error"],
}, "nonblock-statement-body-position": [
], "error",
"symbol-description": ["error"], "below"
"template-curly-spacing": ["error"], ],
"template-tag-spacing": ["error"], "object-curly-newline": ["error"],
"unicode-bom": ["error", "never"], "object-curly-spacing": ["error"],
"use-isnan": ["error"], "object-property-newline": ["error"],
"valid-jsdoc": ["error"], "object-shorthand": ["error"],
"valid-typeof": ["error"], "one-var": ["off"],
"vars-on-top": ["error"], "one-var-declaration-per-line": ["error"],
"wrap-iife": ["error", "any"], "operator-assignment": ["error"],
"wrap-regex": ["error"], "operator-linebreak": [
"yield-star-spacing": ["error", "before"], "error",
yoda: ["error", "never"], "none"
}, ],
"padded-blocks": ["off"],
"padding-line-between-statements": ["error"],
"prefer-arrow-callback": ["error"],
"prefer-const": ["error"],
"prefer-destructuring": ["off"],
"prefer-numeric-literals": ["error"],
"prefer-promise-reject-errors": ["off"],
"prefer-reflect": ["error"],
"prefer-rest-params": ["error"],
"prefer-spread": ["error"],
"prefer-template": ["error"],
"quote-props": ["error"],
"quotes": ["error"],
"radix": [
"error",
"as-needed"
],
"require-await": ["error"],
"require-jsdoc": ["off"],
"require-yield": ["error"],
"rest-spread-spacing": [
"error",
"never"
],
"semi": ["error"],
"semi-spacing": ["error"],
"semi-style": [
"error",
"last"
],
"sort-imports": ["error"],
"sort-keys": ["error"],
"sort-vars": ["error"],
"space-before-blocks": ["error"],
"space-before-function-paren": ["off"],
"space-in-parens": ["error"],
"space-infix-ops": ["error"],
"space-unary-ops": ["error"],
"spaced-comment": ["error"],
"strict": ["error"],
"switch-colon-spacing": [
"error",
{
"after": true,
"before": false
}
],
"symbol-description": ["error"],
"template-curly-spacing": ["error"],
"template-tag-spacing": ["error"],
"unicode-bom": [
"error",
"never"
],
"use-isnan": ["error"],
"valid-jsdoc": ["error"],
"valid-typeof": ["error"],
"vars-on-top": ["error"],
"wrap-iife": [
"error",
"any"
],
"wrap-regex": ["error"],
"yield-star-spacing": [
"error",
"before"
],
"yoda": [
"error",
"never"
]
}
}; };

View File

@ -8,74 +8,66 @@ const path = require("path");
const exec = require("child_process").exec; const exec = require("child_process").exec;
const semver = require("./semver"); const semver = require("./semver");
const getPackageJson = () => const getPackageJson = () => new Promise((resolve, reject) => {
new Promise((resolve, reject) => {
try { try {
/* eslint-disable-next-line global-require */ /* eslint-disable-next-line global-require */
resolve(require(path.resolve(process.cwd(), "package.json"))); resolve(require(path.resolve(process.cwd(), "package.json")));
} catch (error) { } catch (error) {
reject(error); reject(error);
} }
}); });
const getEngines = (data) => const getEngines = (data) => new Promise((resolve, reject) => {
new Promise((resolve, reject) => {
let versions = null; let versions = null;
if (data.engines) { if (data.engines) {
versions = data.engines; versions = data.engines;
} }
if (versions) { if (versions) {
resolve(versions); resolve(versions);
} else { } else {
reject("Missing or improper 'engines' property in 'package.json'"); reject("Missing or improper 'engines' property in 'package.json'");
} }
}); });
const checkNpmVersion = (engines) => const checkNpmVersion = (engines) => new Promise((resolve, reject) => {
new Promise((resolve, reject) => {
exec("npm -v", (error, stdout, stderr) => { exec("npm -v", (error, stdout, stderr) => {
if (error) { if (error) {
reject(`Unable to find NPM version\n${stderr}`); reject(`Unable to find NPM version\n${stderr}`);
} }
const npmVersion = stdout.trim(); const npmVersion = stdout.trim();
const engineVersion = engines.npm || ">=0"; const engineVersion = engines.npm || ">=0";
if (semver.satisfies(npmVersion, engineVersion)) { if (semver.satisfies(npmVersion, engineVersion)) {
resolve(); resolve();
} else { } else {
reject( reject(`Incorrect npm version\n'package.json' specifies "${engineVersion}", you are currently running "${npmVersion}".`);
`Incorrect npm version\n'package.json' specifies "${engineVersion}", you are currently running "${npmVersion}".`, }
);
}
}); });
}); });
const checkNodeVersion = (engines) => const checkNodeVersion = (engines) => new Promise((resolve, reject) => {
new Promise((resolve, reject) => {
const nodeVersion = process.version.substring(1); const nodeVersion = process.version.substring(1);
if (semver.satisfies(nodeVersion, engines.node)) { if (semver.satisfies(nodeVersion, engines.node)) {
resolve(engines); resolve(engines);
} else { } else {
reject( reject(`Incorrect node version\n'package.json' specifies "${engines.node}", you are currently running "${process.version}".`);
`Incorrect node version\n'package.json' specifies "${engines.node}", you are currently running "${process.version}".`,
);
} }
}); });
getPackageJson() getPackageJson()
.then(getEngines) .then(getEngines)
.then(checkNodeVersion) .then(checkNodeVersion)
.then(checkNpmVersion) .then(checkNpmVersion)
.then( .then(
() => true, () => true,
(error) => { (error) => {
// Specifically disable these as the error message gets lost in the normal unhandled output. // Specifically disable these as the error message gets lost in the normal unhandled output.
/* eslint-disable no-console, no-process-exit */ /* eslint-disable no-console, no-process-exit */
console.error(error); console.error(error);
process.exit(1); process.exit(1);
}, }
); );

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
import { IBladeburner } from "./IBladeburner"; import { IBladeburner } from "./IBladeburner";
export interface IStatsMultiplier { interface IStatsMultiplier {
[key: string]: number; [key: string]: number;
hack: number; hack: number;

View File

@ -1,4 +1,4 @@
export interface RNG { interface RNG {
random(): number; random(): number;
} }

View File

@ -45,7 +45,7 @@ export function generateRandomContractOnHome(): void {
serv.addContract(contract); serv.addContract(contract);
} }
export interface IGenerateContractParams { interface IGenerateContractParams {
problemType?: string; problemType?: string;
server?: string; server?: string;
fn?: string; fn?: string;

View File

@ -8,7 +8,7 @@ import { CodingContractEvent } from "./ui/React/CodingContractModal";
/* tslint:disable:no-magic-numbers completed-docs max-classes-per-file no-console */ /* tslint:disable:no-magic-numbers completed-docs max-classes-per-file no-console */
/* Represents different types of problems that a Coding Contract can have */ /* Represents different types of problems that a Coding Contract can have */
export class CodingContractType { class CodingContractType {
/** /**
* Function that generates a description of the problem * Function that generates a description of the problem
*/ */

View File

@ -45,8 +45,3 @@ export function initCompanies(): void {
export function loadCompanies(saveString: string): void { export function loadCompanies(saveString: string): void {
Companies = JSON.parse(saveString, Reviver); Companies = JSON.parse(saveString, Reviver);
} }
// Utility function to check if a string is valid company name
export function companyExists(name: string): boolean {
return Companies.hasOwnProperty(name);
}

View File

@ -20,7 +20,7 @@ export function IndustryProductEquation(props: IProps): React.ReactElement {
return ( return (
<MathJaxContext> <MathJaxContext>
<MathJax>{"\\(" + reqs.join("+") + `\\Rightarrow` + prod.map((p) => `1\\text{ }${p}`).join("+") + "\\)"}</MathJax> <MathJax>{"\\(" + reqs.join("+") + `\\Rightarrow` + prod.map((p) => `1 \\text{${p}}`).join("+") + "\\)"}</MathJax>
</MathJaxContext> </MathJaxContext>
); );
} }

View File

@ -76,11 +76,6 @@ function MarketTA2(props: IMarketTA2Props): React.ReactElement {
</Tooltip> </Tooltip>
} }
/> />
<Typography>
Note that Market-TA.II overrides Market-TA.I. This means that if both are enabled, then Market-TA.II will take
effect, not Market-TA.I
</Typography>
</> </>
); );
} }
@ -93,6 +88,7 @@ interface IProps {
// Create a popup that lets the player use the Market TA research for Materials // Create a popup that lets the player use the Market TA research for Materials
export function MaterialMarketTaModal(props: IProps): React.ReactElement { export function MaterialMarketTaModal(props: IProps): React.ReactElement {
const division = useDivision();
const setRerender = useState(false)[1]; const setRerender = useState(false)[1];
function rerender(): void { function rerender(): void {
setRerender((old) => !old); setRerender((old) => !old);
@ -106,28 +102,32 @@ export function MaterialMarketTaModal(props: IProps): React.ReactElement {
return ( return (
<Modal open={props.open} onClose={props.onClose}> <Modal open={props.open} onClose={props.onClose}>
<Typography variant="h4">Market-TA.I</Typography> {!division.hasResearch("Market-TA.II") && (
<Typography> <>
The maximum sale price you can mark this up to is {numeralWrapper.formatMoney(props.mat.bCost + markupLimit)}. <Typography variant="h4">Market-TA.I</Typography>
This means that if you set the sale price higher than this, you will begin to experience a loss in number of <Typography>
sales The maximum sale price you can mark this up to is{" "}
</Typography> {numeralWrapper.formatMoney(props.mat.bCost + markupLimit)}. This means that if you set the sale price
higher than this, you will begin to experience a loss in number of sales
</Typography>
<FormControlLabel <FormControlLabel
control={<Switch checked={props.mat.marketTa1} onChange={onMarketTA1} />} control={<Switch checked={props.mat.marketTa1} onChange={onMarketTA1} />}
label={ label={
<Tooltip <Tooltip
title={ title={
<Typography> <Typography>
If this is enabled, then this Material will automatically be sold at the price identified by Market-TA.I If this is enabled, then this Material will automatically be sold at the price identified by
(i.e. the price shown above) Market-TA.I (i.e. the price shown above)
</Typography> </Typography>
}
>
<Typography>Use Market-TA.I for Auto-Sale Price</Typography>
</Tooltip>
} }
> />
<Typography>Use Market-TA.I for Auto-Sale Price</Typography> </>
</Tooltip> )}
}
/>
<MarketTA2 mat={props.mat} /> <MarketTA2 mat={props.mat} />
</Modal> </Modal>
); );

View File

@ -66,11 +66,6 @@ function MarketTA2(props: ITa2Props): React.ReactElement {
</Tooltip> </Tooltip>
} }
/> />
<Typography>
Note that Market-TA.II overrides Market-TA.I. This means that if both are enabled, then Market-TA.II will take
effect, not Market-TA.I
</Typography>
</> </>
); );
} }
@ -83,6 +78,7 @@ interface IProps {
// Create a popup that lets the player use the Market TA research for Products // Create a popup that lets the player use the Market TA research for Products
export function ProductMarketTaModal(props: IProps): React.ReactElement { export function ProductMarketTaModal(props: IProps): React.ReactElement {
const division = useDivision();
const markupLimit = props.product.rat / props.product.mku; const markupLimit = props.product.rat / props.product.mku;
const setRerender = useState(false)[1]; const setRerender = useState(false)[1];
function rerender(): void { function rerender(): void {
@ -96,29 +92,32 @@ export function ProductMarketTaModal(props: IProps): React.ReactElement {
return ( return (
<Modal open={props.open} onClose={props.onClose}> <Modal open={props.open} onClose={props.onClose}>
<Typography variant="h4">Market-TA.I</Typography> {!division.hasResearch("Market-TA.II") && (
<Typography> <>
The maximum sale price you can mark this up to is{" "} <Typography variant="h4">Market-TA.I</Typography>
{numeralWrapper.formatMoney(props.product.pCost + markupLimit)}. This means that if you set the sale price <Typography>
higher than this, you will begin to experience a loss in number of sales The maximum sale price you can mark this up to is{" "}
</Typography> {numeralWrapper.formatMoney(props.product.pCost + markupLimit)}. This means that if you set the sale price
higher than this, you will begin to experience a loss in number of sales
</Typography>
<FormControlLabel <FormControlLabel
control={<Switch checked={props.product.marketTa1} onChange={onChange} />} control={<Switch checked={props.product.marketTa1} onChange={onChange} />}
label={ label={
<Tooltip <Tooltip
title={ title={
<Typography> <Typography>
If this is enabled, then this Material will automatically be sold at the price identified by Market-TA.I If this is enabled, then this Material will automatically be sold at the price identified by
(i.e. the price shown above) Market-TA.I (i.e. the price shown above)
</Typography> </Typography>
}
>
<Typography>Use Market-TA.I for Auto-Sale Price</Typography>
</Tooltip>
} }
> />
<Typography>Use Market-TA.I for Auto-Sale Price</Typography> </>
</Tooltip> )}
}
/>
<MarketTA2 product={props.product} /> <MarketTA2 product={props.product} />
</Modal> </Modal>
); );

View File

@ -4,7 +4,7 @@ import { IPlayerOrSleeve } from "../PersonObjects/IPlayerOrSleeve";
import { IRouter } from "../ui/Router"; import { IRouter } from "../ui/Router";
import { WorkerScript } from "../Netscript/WorkerScript"; import { WorkerScript } from "../Netscript/WorkerScript";
export interface IConstructorParams { interface IConstructorParams {
hacking_success_weight?: number; hacking_success_weight?: number;
strength_success_weight?: number; strength_success_weight?: number;
defense_success_weight?: number; defense_success_weight?: number;

View File

@ -24,7 +24,7 @@ export function loadFactions(saveString: string): void {
} }
} }
export function AddToFactions(faction: Faction): void { function AddToFactions(faction: Faction): void {
const name: string = faction.name; const name: string = faction.name;
Factions[name] = faction; Factions[name] = faction;
} }
@ -42,7 +42,7 @@ export function initFactions(): void {
//Resets a faction during (re-)initialization. Saves the favor in the new //Resets a faction during (re-)initialization. Saves the favor in the new
//Faction object and deletes the old Faction Object from "Factions". Then //Faction object and deletes the old Faction Object from "Factions". Then
//reinserts the new Faction object //reinserts the new Faction object
export function resetFaction(newFactionObject: Faction): void { function resetFaction(newFactionObject: Faction): void {
if (!(newFactionObject instanceof Faction)) { if (!(newFactionObject instanceof Faction)) {
throw new Error("Invalid argument 'newFactionObject' passed into resetFaction()"); throw new Error("Invalid argument 'newFactionObject' passed into resetFaction()");
} }

View File

@ -5,7 +5,7 @@ import { ITaskParams } from "../ITaskParams";
* Defines the parameters that can be used to initialize and describe a GangMemberTask * Defines the parameters that can be used to initialize and describe a GangMemberTask
* (defined in Gang.js) * (defined in Gang.js)
*/ */
export interface IGangMemberTaskMetadata { interface IGangMemberTaskMetadata {
/** /**
* Description of the task * Description of the task
*/ */

View File

@ -19,7 +19,7 @@ export enum UpgradeType {
* Defines the parameters that can be used to initialize and describe a GangMemberUpgrade * Defines the parameters that can be used to initialize and describe a GangMemberUpgrade
* (defined in Gang.js) * (defined in Gang.js)
*/ */
export interface IGangMemberUpgradeMetadata { interface IGangMemberUpgradeMetadata {
cost: number; cost: number;
mults: IMults; mults: IMults;
name: string; name: string;

View File

@ -69,6 +69,7 @@ export function TechVendorLocation(props: IProps): React.ReactElement {
return ( return (
<> <>
<br />
{purchaseServerButtons} {purchaseServerButtons}
<br /> <br />
<Typography> <Typography>

View File

@ -217,4 +217,4 @@ function initMessages(): void {
); );
} }
export { Messages, checkForMessagesToSend, sendMessage, showMessage, loadMessages, initMessages, Message }; export { Messages, checkForMessagesToSend, showMessage, loadMessages, initMessages };

View File

@ -1,11 +0,0 @@
import { Milestone } from "./Milestone";
export class Quest {
title: string;
milestones: Milestone[];
constructor(title: string, milestones: Milestone[]) {
this.title = title;
this.milestones = milestones;
}
}

View File

@ -106,6 +106,11 @@ export class WorkerScript {
*/ */
hostname: string; hostname: string;
/**
* Function called when the script ends.
*/
atExit: any;
constructor(runningScriptObj: RunningScript, pid: number, nsFuncsGenerator?: (ws: WorkerScript) => any) { constructor(runningScriptObj: RunningScript, pid: number, nsFuncsGenerator?: (ws: WorkerScript) => any) {
this.name = runningScriptObj.filename; this.name = runningScriptObj.filename;
this.hostname = runningScriptObj.server; this.hostname = runningScriptObj.server;

View File

@ -10,6 +10,7 @@ import { RunningScript } from "../Script/RunningScript";
import { GetServer } from "../Server/AllServers"; import { GetServer } from "../Server/AllServers";
import { compareArrays } from "../utils/helpers/compareArrays"; import { compareArrays } from "../utils/helpers/compareArrays";
import { dialogBoxCreate } from "../ui/React/DialogBox";
export function killWorkerScript(runningScriptObj: RunningScript, hostname: string, rerenderUi?: boolean): boolean; export function killWorkerScript(runningScriptObj: RunningScript, hostname: string, rerenderUi?: boolean): boolean;
export function killWorkerScript(workerScript: WorkerScript): boolean; export function killWorkerScript(workerScript: WorkerScript): boolean;
@ -67,6 +68,16 @@ function killWorkerScriptByPid(pid: number, rerenderUi = true): boolean {
function stopAndCleanUpWorkerScript(workerScript: WorkerScript, rerenderUi = true): void { function stopAndCleanUpWorkerScript(workerScript: WorkerScript, rerenderUi = true): void {
workerScript.env.stopFlag = true; workerScript.env.stopFlag = true;
killNetscriptDelay(workerScript); killNetscriptDelay(workerScript);
if (typeof workerScript.atExit === "function") {
try {
workerScript.atExit();
} catch (e: any) {
dialogBoxCreate(
`Error trying to call atExit for script ${workerScript.name} on ${workerScript.hostname} ${workerScript.scriptRef.args} ${e}`,
);
}
workerScript.atExit = undefined;
}
removeWorkerScript(workerScript, rerenderUi); removeWorkerScript(workerScript, rerenderUi);
} }

View File

@ -86,6 +86,7 @@ import { INetscriptStockMarket, NetscriptStockMarket } from "./NetscriptFunction
import { dialogBoxCreate } from "./ui/React/DialogBox"; import { dialogBoxCreate } from "./ui/React/DialogBox";
import { SnackbarEvents } from "./ui/React/Snackbar"; import { SnackbarEvents } from "./ui/React/Snackbar";
import { Locations } from "./Locations/Locations";
const defaultInterpreter = new Interpreter("", () => undefined); const defaultInterpreter = new Interpreter("", () => undefined);
@ -2211,6 +2212,19 @@ function NetscriptFunctions(workerScript: WorkerScript): NS {
}, },
/* Singularity Functions */ /* Singularity Functions */
goToLocation: function (locationName: any): boolean {
const location = Object.values(Locations).find((l) => l.name === locationName);
if (!location) {
workerScript.log("goToLocation", `No location named ${locationName}`);
return false;
}
if (Player.city !== location.city) {
workerScript.log("goToLocation", `No location named ${locationName} in ${Player.city}`);
return false;
}
Router.toLocation(location);
return true;
},
universityCourse: function (universityName: any, className: any): any { universityCourse: function (universityName: any, className: any): any {
updateDynamicRam("universityCourse", getRamCost("universityCourse")); updateDynamicRam("universityCourse", getRamCost("universityCourse"));
checkSingularityAccess("universityCourse", 1); checkSingularityAccess("universityCourse", 1);
@ -3263,6 +3277,13 @@ function NetscriptFunctions(workerScript: WorkerScript): NS {
corporation: corporation, corporation: corporation,
formulas: formulas, formulas: formulas,
atExit: function (f: any): void {
if (typeof f !== "function") {
throw makeRuntimeErrorMsg("atExit", "argument should be function");
}
workerScript.atExit = f;
},
flags: function (data: any): any { flags: function (data: any): any {
data = toNative(data); data = toNative(data);
// We always want the help flag. // We always want the help flag.

View File

@ -469,11 +469,7 @@ export function startWorkerScript(runningScript: RunningScript, server: BaseServ
* @param {Server} server - Server on which the script is to be run * @param {Server} server - Server on which the script is to be run
* returns {boolean} indicating whether or not the workerScript was successfully added * returns {boolean} indicating whether or not the workerScript was successfully added
*/ */
export function createAndAddWorkerScript( function createAndAddWorkerScript(runningScriptObj: RunningScript, server: BaseServer, parent?: WorkerScript): boolean {
runningScriptObj: RunningScript,
server: BaseServer,
parent?: WorkerScript,
): boolean {
// Update server's ram usage // Update server's ram usage
let threads = 1; let threads = 1;
if (runningScriptObj.threads && !isNaN(runningScriptObj.threads)) { if (runningScriptObj.threads && !isNaN(runningScriptObj.threads)) {

View File

@ -1,3 +0,0 @@
import { EventEmitter } from "../utils/EventEmitter";
export const PlayerEvents = new EventEmitter<[]>();

View File

@ -1,100 +0,0 @@
import * as React from "react";
export const SleeveFaq = (
<>
<strong>
<u>How do Duplicate Sleeves work?</u>
</strong>
<br />
Duplicate Sleeves are essentially clones. You can use them to perform any work type action, such as working for a
company/faction or committing a crime. Having sleeves perform these tasks earns you money, experience, and
reputation.
<br />
<br />
Sleeves are their own individuals, which means they each have their own experience and stats.
<br />
<br />
When a sleeve earns experience, it earns experience for itself, the player's original 'consciousness', as well as
all of the player's other sleeves.
<br />
<br />
<strong>
<u>What is Synchronization (Sync)?</u>
</strong>
<br />
Synchronization is a measure of how aligned your consciousness is with that of your Duplicate Sleeves. It is a
numerical value between 1 and 100, and it affects how much experience is earned when the sleeve is performing a
task.
<br />
<br />
Let N be the sleeve's synchronization. When the sleeve earns experience by performing a task, both the sleeve and
the player's original host consciousness earn N% of the amount of experience normally earned by the task. All of the
player's other sleeves earn ((N/100)^2 * 100)% of the experience.
<br />
<br />
Synchronization can be increased by assigning sleeves to the 'Synchronize' task.
<br />
<br />
<strong>
<u>What is Shock?</u>
</strong>
<br />
Sleeve shock is a measure of how much trauma the sleeve has due to being placed in a new body. It is a numerical
value between 0 and 99, where 99 indicates full shock and 0 indicates no shock. Shock affects the amount of
experience earned by the sleeve.
<br />
<br />
Sleeve shock slowly decreases over time. You can further increase the rate at which it decreases by assigning
sleeves to the 'Shock Recovery' task.
<br />
<br />
<strong>
<u>Why can't I work for this company or faction?</u>
</strong>
<br />
Only one of your sleeves can work for a given company/faction a time. To clarify further, if you have two sleeves
they can work for two different companies, but they cannot both work for the same company.
<br />
<br />
<strong>
<u>Why did my Sleeve stop working?</u>
</strong>
<br />
Sleeves are subject to the same time restrictions as you. This means that they automatically stop working at a
company after 8 hours, and stop working for a faction after 20 hours.
<br />
<br />
<strong>
<u>How do I buy Augmentations for my Sleeves?</u>
</strong>
<br />
Your Sleeve needs to have a Shock of 0 in order for you to buy Augmentations for it.
<br />
<br />
<strong>
<u>Why can't I buy the X Augmentation for my sleeve?</u>
</strong>
<br />
Certain Augmentations, like Bladeburner-specific ones and NeuroFlux Governor, are not available for sleeves.
<br />
<br />
<strong>
<u>Do sleeves get reset when installing Augmentations or switching BitNodes?</u>
</strong>
<br />
Sleeves are reset when switching BitNodes, but not when installing Augmentations.
<br />
<br />
<strong>
<u>What is Memory?</u>
</strong>
<br />
Sleeve memory dictates what a sleeve's synchronization will be when its reset by switching BitNodes. For example, if
a sleeve has a memory of 25, then when you switch BitNodes its synchronization will initially be set to 25, rather
than 1.
<br />
<br />
Memory can only be increased by purchasing upgrades from The Covenant. It is a persistent stat, meaning it never
gets resets back to 1. The maximum possible value for a sleeve's memory is 100.
</>
);

View File

@ -24,7 +24,7 @@ function bitFlumeRequirements() {
}; };
} }
export interface IProgramCreationParams { interface IProgramCreationParams {
key: string; key: string;
name: string; name: string;
create: IProgramCreate | null; create: IProgramCreate | null;

View File

@ -1,7 +1,7 @@
export type Position = { interface Position {
row: number; row: number;
column: number; column: number;
}; }
class PositionTracker { class PositionTracker {
positions: Map<string, Position>; positions: Map<string, Position>;

View File

@ -197,7 +197,7 @@ export function initSymbolToStockMap(): void {
} }
} }
export function stockMarketCycle(): void { function stockMarketCycle(): void {
for (const name in StockMarket) { for (const name in StockMarket) {
const stock = StockMarket[name]; const stock = StockMarket[name];
if (!(stock instanceof Stock)) { if (!(stock instanceof Stock)) {

View File

@ -1,14 +1,6 @@
import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers"; import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers";
import { CONSTANTS } from "../Constants"; import { CONSTANTS } from "../Constants";
export function getStockMarketAccountCost(): number {
return CONSTANTS.WSEAccountCost;
}
export function getStockMarketTixApiCost(): number {
return CONSTANTS.TIXAPICost;
}
export function getStockMarket4SDataCost(): number { export function getStockMarket4SDataCost(): number {
return CONSTANTS.MarketData4SCost * BitNodeMultipliers.FourSigmaMarketDataCost; return CONSTANTS.MarketData4SCost * BitNodeMultipliers.FourSigmaMarketDataCost;
} }

View File

@ -15,7 +15,7 @@ import { IPlayer } from "../../PersonObjects/IPlayer";
import { EventEmitter } from "../../utils/EventEmitter"; import { EventEmitter } from "../../utils/EventEmitter";
type txFn = (stock: Stock, shares: number) => boolean; type txFn = (stock: Stock, shares: number) => boolean;
export type placeOrderFn = ( type placeOrderFn = (
stock: Stock, stock: Stock,
shares: number, shares: number,
price: number, price: number,

View File

@ -39,8 +39,8 @@ enum SelectorOrderType {
Stop = "Stop Order", Stop = "Stop Order",
} }
export type txFn = (stock: Stock, shares: number) => boolean; type txFn = (stock: Stock, shares: number) => boolean;
export type placeOrderFn = ( type placeOrderFn = (
stock: Stock, stock: Stock,
shares: number, shares: number,
price: number, price: number,

View File

@ -47,7 +47,7 @@ function LongPosition(props: IProps): React.ReactElement {
</Box> </Box>
<Typography>Shares: {numeralWrapper.formatShares(stock.playerShares)}</Typography> <Typography>Shares: {numeralWrapper.formatShares(stock.playerShares)}</Typography>
<Typography> <Typography>
Average Price: <Money money={stock.playerAvgPx} /> (Total Cost: <Money money={totalCost} /> Average Price: <Money money={stock.playerAvgPx} /> (Total Cost: <Money money={totalCost} />)
</Typography> </Typography>
<Typography> <Typography>
Profit: <Money money={gains} /> ({numeralWrapper.formatPercentage(percentageGains)}) Profit: <Money money={gains} /> ({numeralWrapper.formatPercentage(percentageGains)})

View File

@ -16,8 +16,8 @@ import { PositionTypes } from "../data/PositionTypes";
import { IPlayer } from "../../PersonObjects/IPlayer"; import { IPlayer } from "../../PersonObjects/IPlayer";
import { EventEmitter } from "../../utils/EventEmitter"; import { EventEmitter } from "../../utils/EventEmitter";
export type txFn = (stock: Stock, shares: number) => boolean; type txFn = (stock: Stock, shares: number) => boolean;
export type placeOrderFn = ( type placeOrderFn = (
stock: Stock, stock: Stock,
shares: number, shares: number,
price: number, price: number,

View File

@ -35,7 +35,7 @@ export function removeTrailingSlash(s: string): string {
* Checks whether a string is a valid filename. Only used for the filename itself, * Checks whether a string is a valid filename. Only used for the filename itself,
* not the entire filepath * not the entire filepath
*/ */
export function isValidFilename(filename: string): boolean { function isValidFilename(filename: string): boolean {
// Allows alphanumerics, hyphens, underscores, and percentage signs // Allows alphanumerics, hyphens, underscores, and percentage signs
// Must have a file extension // Must have a file extension
const regex = /^[.a-zA-Z0-9_-]+[.][a-zA-Z0-9]+(?:-\d+(?:\.\d*)?%-INC)?$/; const regex = /^[.a-zA-Z0-9_-]+[.][a-zA-Z0-9]+(?:-\d+(?:\.\d*)?%-INC)?$/;
@ -48,7 +48,7 @@ export function isValidFilename(filename: string): boolean {
* Checks whether a string is a valid directory name. Only used for the directory itself, * Checks whether a string is a valid directory name. Only used for the directory itself,
* not an entire path * not an entire path
*/ */
export function isValidDirectoryName(name: string): boolean { function isValidDirectoryName(name: string): boolean {
// Allows alphanumerics, hyphens, underscores, and percentage signs. // Allows alphanumerics, hyphens, underscores, and percentage signs.
// Name can begin with a single period, but otherwise cannot have any // Name can begin with a single period, but otherwise cannot have any
const regex = /^.?[a-zA-Z0-9_-]+$/; const regex = /^.?[a-zA-Z0-9_-]+$/;

View File

@ -12,7 +12,7 @@ export type SolverFunc = (data: any, answer: string) => boolean;
Requires the 'data' of a Contract as input */ Requires the 'data' of a Contract as input */
export type DescriptionFunc = (data: any) => string; export type DescriptionFunc = (data: any) => string;
export interface ICodingContractTypeMetadata { interface ICodingContractTypeMetadata {
desc: DescriptionFunc; desc: DescriptionFunc;
difficulty: number; difficulty: number;
gen: GeneratorFunc; gen: GeneratorFunc;

View File

@ -10,11 +10,6 @@ export interface IMap<T> {
[key: string]: T; [key: string]: T;
} }
/**
* Performs some action, with no returned value.
*/
export type Action = () => void;
/** /**
* Contains a method to initialize itself to a known state. * Contains a method to initialize itself to a known state.
*/ */

View File

@ -1,7 +1,7 @@
import React, { useState, useEffect } from "react"; import React, { useState, useEffect } from "react";
import { KEY } from "../../utils/helpers/keyCodes"; import { KEY } from "../../utils/helpers/keyCodes";
import { CodingContract, CodingContractType, CodingContractTypes } from "../../CodingContracts"; import { CodingContract, CodingContractTypes } from "../../CodingContracts";
import { CopyableText } from "./CopyableText"; import { CopyableText } from "./CopyableText";
import { Modal } from "./Modal"; import { Modal } from "./Modal";
import { EventEmitter } from "../../utils/EventEmitter"; import { EventEmitter } from "../../utils/EventEmitter";
@ -49,7 +49,7 @@ export function CodingContractModal(): React.ReactElement {
setProps(null); setProps(null);
} }
const contractType: CodingContractType = CodingContractTypes[props.c.type]; const contractType = CodingContractTypes[props.c.type];
const description = []; const description = [];
for (const [i, value] of contractType.desc(props.c.data).split("\n").entries()) for (const [i, value] of contractType.desc(props.c.data).split("\n").entries())
description.push(<span key={i} dangerouslySetInnerHTML={{ __html: value + "<br />" }}></span>); description.push(<span key={i} dangerouslySetInnerHTML={{ __html: value + "<br />" }}></span>);

View File

@ -1,32 +0,0 @@
/**
* React component for a popup content container
*
* Takes in a prop for rendering the content inside the popup
*/
import React, { useEffect } from "react";
interface IProps<T> {
content: (props: T) => React.ReactElement;
id: string;
props: T;
removePopup: () => void;
}
export function Popup<T>(props: IProps<T>): React.ReactElement {
function keyDown(event: KeyboardEvent): void {
if (event.key === "Escape") props.removePopup();
}
useEffect(() => {
document.addEventListener("keydown", keyDown);
return () => {
document.removeEventListener("keydown", keyDown);
};
});
return (
<div className={"popup-box-content"} id={`${props.id}-content`}>
{React.createElement(props.content, props.props)}
</div>
);
}

View File

@ -4,7 +4,7 @@
type cbFn = (...args: any[]) => any; type cbFn = (...args: any[]) => any;
export interface ISubscriber { interface ISubscriber {
/** /**
* Callback function that will be run when an event is emitted * Callback function that will be run when an event is emitted
*/ */

View File

@ -1,6 +1,6 @@
/* Generic Reviver, toJSON, and fromJSON functions used for saving and loading objects */ /* Generic Reviver, toJSON, and fromJSON functions used for saving and loading objects */
export interface IReviverValue { interface IReviverValue {
ctor: string; ctor: string;
data: any; data: any;
} }

View File

@ -1,13 +1,6 @@
import { EqualityFunc } from "../types"; import { EqualityFunc } from "../types";
import { isString } from "./helpers/isString"; import { isString } from "./helpers/isString";
// Netburner String helper functions
// Replaces the character at an index with a new character
function replaceAt(base: string, index: number, character: string): string {
return base.substr(0, index) + character + base.substr(index + character.length);
}
/* /*
Converts a date representing time in milliseconds to a string with the format H hours M minutes and S seconds Converts a date representing time in milliseconds to a string with the format H hours M minutes and S seconds
e.g. 10000 -> "10 seconds" e.g. 10000 -> "10 seconds"
@ -92,20 +85,6 @@ function formatNumber(num: number, numFractionDigits = 0): string {
}); });
} }
// Checks if a string contains HTML elements
function isHTML(str: string): boolean {
const element: HTMLDivElement = document.createElement("div");
element.innerHTML = str;
const c: NodeListOf<Node & ChildNode> = element.childNodes;
for (let i: number = c.length - 1; i >= 0; i--) {
if (c[i].nodeType === 1) {
return true;
}
}
return false;
}
// Generates a random alphanumeric string with N characters // Generates a random alphanumeric string with N characters
function generateRandomString(n: number): string { function generateRandomString(n: number): string {
let str = ""; let str = "";
@ -118,12 +97,4 @@ function generateRandomString(n: number): string {
return str; return str;
} }
export { export { convertTimeMsToTimeElapsedString, longestCommonStart, containsAllStrings, formatNumber, generateRandomString };
convertTimeMsToTimeElapsedString,
longestCommonStart,
containsAllStrings,
formatNumber,
isHTML,
generateRandomString,
replaceAt,
};

View File

@ -4,9 +4,7 @@ const webpack = require("webpack");
const MiniCssExtractPlugin = require("mini-css-extract-plugin"); const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin"); const HtmlWebpackPlugin = require("html-webpack-plugin");
const ForkTsCheckerWebpackPlugin = require("fork-ts-checker-webpack-plugin"); const ForkTsCheckerWebpackPlugin = require("fork-ts-checker-webpack-plugin");
const UnusedWebpackPlugin = require("unused-webpack-plugin");
const ReactRefreshWebpackPlugin = require("@pmmmwh/react-refresh-webpack-plugin"); const ReactRefreshWebpackPlugin = require("@pmmmwh/react-refresh-webpack-plugin");
const DeadCodePlugin = require("webpack-deadcode-plugin");
module.exports = (env, argv) => { module.exports = (env, argv) => {
const isDevServer = (env || {}).devServer === true; const isDevServer = (env || {}).devServer === true;
@ -107,14 +105,6 @@ module.exports = (env, argv) => {
}, },
}, },
}), }),
new UnusedWebpackPlugin({
// Source directories
directories: [path.join(__dirname, "src"), path.join(__dirname, "utils")],
// Exclude patterns
exclude: ["*.test.js"],
// Root directory (optional)
root: __dirname,
}),
// In dev mode, use a faster method of create sourcemaps // In dev mode, use a faster method of create sourcemaps
// while keeping lines/columns accurate // while keeping lines/columns accurate
isDevServer && isDevServer &&
@ -132,10 +122,6 @@ module.exports = (env, argv) => {
module: true, module: true,
}), }),
isFastRefresh && new ReactRefreshWebpackPlugin(), isFastRefresh && new ReactRefreshWebpackPlugin(),
new DeadCodePlugin({
patterns: ["src/**/*.(js|jsx|css|ts|tsx)"],
exclude: ["**/*.(stories|spec).(js|jsx)"],
}),
].filter(Boolean), ].filter(Boolean),
target: "web", target: "web",
entry: entry, entry: entry,