mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-12-18 04:05:46 +01:00
fix sleeve memory bug
This commit is contained in:
parent
bada8a5f39
commit
2a13db39c7
@ -1,4 +1,5 @@
|
||||
{
|
||||
"trailingComma": "all",
|
||||
"tabWidth": 2
|
||||
"tabWidth": 2,
|
||||
"printWidth": 120
|
||||
}
|
||||
|
@ -1,7 +1,3 @@
|
||||
module.exports = {
|
||||
presets: [
|
||||
"@babel/preset-react",
|
||||
"@babel/preset-env",
|
||||
"@babel/preset-typescript",
|
||||
],
|
||||
presets: ["@babel/preset-react", "@babel/preset-env", "@babel/preset-typescript"],
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
$fontFamily: "Lucida Console", "Lucida Sans Unicode", "Fira Mono", "Consolas",
|
||||
"Courier New", Courier, monospace, "Times New Roman";
|
||||
$fontFamily: "Lucida Console", "Lucida Sans Unicode", "Fira Mono", "Consolas", "Courier New", Courier, monospace,
|
||||
"Times New Roman";
|
||||
$defaultFontSize: 16px;
|
||||
|
||||
/* COLORS */
|
||||
|
@ -21,8 +21,7 @@
|
||||
white-space: nowrap;
|
||||
|
||||
&.hacknet-node {
|
||||
$boxShadowArgs: inset 0 0 8px rgba(0, 0, 0, 0.1),
|
||||
0 0 16px rgba(0, 0, 0, 0.1);
|
||||
$boxShadowArgs: inset 0 0 8px rgba(0, 0, 0, 0.1), 0 0 16px rgba(0, 0, 0, 0.1);
|
||||
@include boxShadow($boxShadowArgs);
|
||||
|
||||
margin: 6px;
|
||||
|
@ -17,8 +17,7 @@ describe("netscript", () => {
|
||||
cy.findByRole("textbox").type("nano script.js{enter}");
|
||||
|
||||
// monaco can take a bit
|
||||
cy.findByRole("code", { timeout: 15_000 }).type("{selectall}{del}")
|
||||
.type(`export const main = async (ns) => {{}
|
||||
cy.findByRole("code", { timeout: 15_000 }).type("{selectall}{del}").type(`export const main = async (ns) => {{}
|
||||
while(true) {{}
|
||||
await ns.hack("n00dles");`);
|
||||
|
||||
@ -39,8 +38,7 @@ describe("netscript", () => {
|
||||
cy.findByRole("textbox").type("nano script.js{enter}");
|
||||
|
||||
// monaco can take a bit
|
||||
cy.findByRole("code", { timeout: 15_000 }).type("{selectall}{del}")
|
||||
.type(`export const main = async (ns) => {{}
|
||||
cy.findByRole("code", { timeout: 15_000 }).type("{selectall}{del}").type(`export const main = async (ns) => {{}
|
||||
const command = "hack";
|
||||
ns[command]("n00dles");`);
|
||||
|
||||
@ -48,8 +46,6 @@ ns[command]("n00dles");`);
|
||||
cy.findByRole("button", { name: /Save & Close/i }).click();
|
||||
|
||||
cy.findByRole("textbox").type("run script.js{enter}");
|
||||
cy.findByText(
|
||||
/Dynamic RAM usage calculated to be greater than initial RAM usage on fn: hack./i,
|
||||
);
|
||||
cy.findByText(/Dynamic RAM usage calculated to be greater than initial RAM usage on fn: hack./i);
|
||||
});
|
||||
});
|
||||
|
@ -49,14 +49,10 @@ describe("tutorial", () => {
|
||||
cy.findByRole("button", { name: "Next" }).click();
|
||||
|
||||
cy.findByText(/hacking exp/i);
|
||||
cy.findByRole("textbox", { timeout: 15_000 })
|
||||
.should("not.be.disabled")
|
||||
.type("nano n00dles.script{enter}");
|
||||
cy.findByRole("textbox", { timeout: 15_000 }).should("not.be.disabled").type("nano n00dles.script{enter}");
|
||||
|
||||
// monaco can take a bit
|
||||
cy.findByRole("code", { timeout: 15_000 })
|
||||
.type("{selectall}{del}")
|
||||
.type("while(true) {{}{enter}hack('n00dles');");
|
||||
cy.findByRole("code", { timeout: 15_000 }).type("{selectall}{del}").type("while(true) {{}{enter}hack('n00dles');");
|
||||
|
||||
cy.findByRole("button", { name: /Save & Close/i }).click();
|
||||
|
||||
|
@ -19,4 +19,4 @@
|
||||
module.exports = (on, config) => {
|
||||
// `on` is used to hook into various events Cypress emits
|
||||
// `config` is the resolved Cypress config
|
||||
}
|
||||
};
|
||||
|
554
index.html
554
index.html
@ -1,18 +1,18 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<meta charset="utf-8" />
|
||||
<title>Bitburner</title>
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="dist/apple-touch-icon.png"/>
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="dist/favicon-32x32.png"/>
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="dist/favicon-16x16.png"/>
|
||||
<link rel="manifest" href="dist/site.webmanifest"/>
|
||||
<link rel="mask-icon" href="dist/safari-pinned-tab.svg" color="#000000"/>
|
||||
<meta name="apple-mobile-web-app-title" content="Bitburner"/>
|
||||
<meta name="application-name" content="Bitburner"/>
|
||||
<meta name="msapplication-TileColor" content="#000000"/>
|
||||
<meta name="msapplication-config" content="dist/browserconfig.xml"/>
|
||||
<meta name="theme-color" content="#ffffff"/>
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="dist/apple-touch-icon.png" />
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="dist/favicon-32x32.png" />
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="dist/favicon-16x16.png" />
|
||||
<link rel="manifest" href="dist/site.webmanifest" />
|
||||
<link rel="mask-icon" href="dist/safari-pinned-tab.svg" color="#000000" />
|
||||
<meta name="apple-mobile-web-app-title" content="Bitburner" />
|
||||
<meta name="application-name" content="Bitburner" />
|
||||
<meta name="msapplication-TileColor" content="#000000" />
|
||||
<meta name="msapplication-config" content="dist/browserconfig.xml" />
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
|
||||
<!-- Google Analytics -->
|
||||
<script>
|
||||
@ -28,25 +28,18 @@
|
||||
a.async = 1;
|
||||
a.src = g;
|
||||
m.parentNode.insertBefore(a, m);
|
||||
})(
|
||||
window,
|
||||
document,
|
||||
"script",
|
||||
"https://www.google-analytics.com/analytics.js",
|
||||
"ga",
|
||||
);
|
||||
})(window, document, "script", "https://www.google-analytics.com/analytics.js", "ga");
|
||||
</script>
|
||||
|
||||
|
||||
<script>
|
||||
ga(
|
||||
"create",
|
||||
"UA-100157497-1",
|
||||
"auto",
|
||||
);
|
||||
ga("create", "UA-100157497-1", "auto");
|
||||
ga("send", "pageview");
|
||||
</script>
|
||||
|
||||
<link rel="shortcut icon" href="favicon.ico"><link href="dist/vendor.css" rel="stylesheet"><link href="dist/engineStyle.css" rel="stylesheet"></head>
|
||||
|
||||
<link rel="shortcut icon" href="favicon.ico" />
|
||||
<link href="dist/vendor.css" rel="stylesheet" />
|
||||
<link href="dist/engineStyle.css" rel="stylesheet" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="entire-game-container" style="visibility: hidden">
|
||||
<div id="mainmenu-container">
|
||||
@ -54,9 +47,7 @@
|
||||
<ul id="mainmenu" class="mainmenu noscrollbar">
|
||||
<!-- Hacking dropdown -->
|
||||
<li id="hacking-menu-header-li">
|
||||
<button id="hacking-menu-header" class="mainmenu-accordion-header noselect">
|
||||
Hacking
|
||||
</button>
|
||||
<button id="hacking-menu-header" class="mainmenu-accordion-header noselect">Hacking</button>
|
||||
</li>
|
||||
<li id="terminal-tab" class="mainmenu-accordion-panel noselect">
|
||||
<button id="terminal-menu-link">Terminal</button>
|
||||
@ -69,15 +60,12 @@
|
||||
</li>
|
||||
<li id="create-program-tab" class="mainmenu-accordion-panel noselect">
|
||||
<button id="create-program-menu-link">Create Program</button>
|
||||
<span id="create-program-notification" class="notification-off">
|
||||
</span>
|
||||
<span id="create-program-notification" class="notification-off"> </span>
|
||||
</li>
|
||||
|
||||
<!-- Character dropdown -->
|
||||
<li id="character-menu-header-li">
|
||||
<button id="character-menu-header" class="mainmenu-accordion-header noselect">
|
||||
Character
|
||||
</button>
|
||||
<button id="character-menu-header" class="mainmenu-accordion-header noselect">Character</button>
|
||||
</li>
|
||||
<li id="stats-tab" class="mainmenu-accordion-panel noselect">
|
||||
<button id="stats-menu-link">Stats</button>
|
||||
@ -87,13 +75,10 @@
|
||||
<span id="factions-notification" class="notification-off"> </span>
|
||||
</li>
|
||||
<li id="augmentations-tab" class="mainmenu-accordion-panel noselect">
|
||||
<button id="augmentations-menu-link" style="overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;">
|
||||
<button id="augmentations-menu-link" style="overflow: hidden; text-overflow: ellipsis; white-space: nowrap">
|
||||
Augmentations
|
||||
</button>
|
||||
<span id="augmentations-notification" class="notification-off">
|
||||
</span>
|
||||
<span id="augmentations-notification" class="notification-off"> </span>
|
||||
</li>
|
||||
<li id="hacknet-nodes-tab" class="mainmenu-accordion-panel noselect">
|
||||
<button id="hacknet-nodes-menu-link">Hacknet</button>
|
||||
@ -104,9 +89,7 @@
|
||||
|
||||
<!-- World dropdown -->
|
||||
<li id="world-menu-header-li">
|
||||
<button id="world-menu-header" class="mainmenu-accordion-header noselect">
|
||||
World
|
||||
</button>
|
||||
<button id="world-menu-header" class="mainmenu-accordion-header noselect">World</button>
|
||||
</li>
|
||||
<li id="city-tab" class="mainmenu-accordion-panel noselect">
|
||||
<button id="city-menu-link">City</button>
|
||||
@ -131,9 +114,7 @@
|
||||
</li>
|
||||
|
||||
<li id="help-menu-header-li">
|
||||
<button id="help-menu-header" class="mainmenu-accordion-header noselect">
|
||||
Help
|
||||
</button>
|
||||
<button id="help-menu-header" class="mainmenu-accordion-header noselect">Help</button>
|
||||
</li>
|
||||
<li id="milestones-tab" class="mainmenu-accordion-panel noselect">
|
||||
<button id="milestones-menu-link">Milestones</button>
|
||||
@ -156,7 +137,7 @@
|
||||
<p id="script-editor-filename-tag">
|
||||
<strong style="background-color: #555">Script name: </strong>
|
||||
</p>
|
||||
<input id="script-editor-filename" type="text" maxlength="100" tabindex="1"/>
|
||||
<input id="script-editor-filename" type="text" maxlength="100" tabindex="1" />
|
||||
</div>
|
||||
|
||||
<div id="monaco-editor"></div>
|
||||
@ -188,17 +169,34 @@
|
||||
|
||||
<fieldset>
|
||||
<label for="script-editor-option-highlightactiveline">Highlight Active Line</label>
|
||||
<input type="checkbox" class="optionCheckbox" name="script-editor-option-highlightactiveline" id="script-editor-option-highlightactiveline" checked/>
|
||||
<input
|
||||
type="checkbox"
|
||||
class="optionCheckbox"
|
||||
name="script-editor-option-highlightactiveline"
|
||||
id="script-editor-option-highlightactiveline"
|
||||
checked
|
||||
/>
|
||||
</fieldset>
|
||||
|
||||
<fieldset>
|
||||
<label for="script-editor-option-showinvisibles">Show Invisibles</label>
|
||||
<input type="checkbox" class="optionCheckbox" name="script-editor-option-showinvisibles" id="script-editor-option-showinvisibles"/>
|
||||
<input
|
||||
type="checkbox"
|
||||
class="optionCheckbox"
|
||||
name="script-editor-option-showinvisibles"
|
||||
id="script-editor-option-showinvisibles"
|
||||
/>
|
||||
</fieldset>
|
||||
|
||||
<fieldset>
|
||||
<label for="script-editor-option-usesofttab">Use Soft Tab</label>
|
||||
<input type="checkbox" class="optionCheckbox" name="script-editor-option-usesofttab" id="script-editor-option-usesofttab" checked/>
|
||||
<input
|
||||
type="checkbox"
|
||||
class="optionCheckbox"
|
||||
name="script-editor-option-usesofttab"
|
||||
id="script-editor-option-usesofttab"
|
||||
checked
|
||||
/>
|
||||
</fieldset>
|
||||
|
||||
<fieldset id="script-editor-option-flex1-fieldset"></fieldset>
|
||||
@ -224,7 +222,14 @@
|
||||
<tr id="terminal-input">
|
||||
<td id="terminal-input-td" tabindex="2">
|
||||
$
|
||||
<input type="text" id="terminal-input-text-box" class="terminal-input" tabindex="1" onfocus="this.value = this.value;" autocomplete="off"/>
|
||||
<input
|
||||
type="text"
|
||||
id="terminal-input-text-box"
|
||||
class="terminal-input"
|
||||
tabindex="1"
|
||||
onfocus="this.value = this.value;"
|
||||
autocomplete="off"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@ -238,19 +243,18 @@
|
||||
<!-- Active scripts info page -->
|
||||
<div id="active-scripts-container" class="generic-menupage-container">
|
||||
<p id="active-scripts-text">
|
||||
This page displays a list of all of your scripts that are currently
|
||||
running across every machine. It also provides information about each
|
||||
script's production. The scripts are categorized by the hostname of
|
||||
the servers on which they are running.
|
||||
This page displays a list of all of your scripts that are currently running across every machine. It also
|
||||
provides information about each script's production. The scripts are categorized by the hostname of the
|
||||
servers on which they are running.
|
||||
</p>
|
||||
<p id="active-scripts-total-prod">
|
||||
Total online production of Active scripts:
|
||||
<span class="money-gold"><span id="active-scripts-total-production-active">$0.000</span> /
|
||||
sec</span><br/>
|
||||
<span class="money-gold"><span id="active-scripts-total-production-active">$0.000</span> / sec</span><br />
|
||||
Total online production since last Aug installation:
|
||||
<span id="active-scripts-total-prod-aug-total" class="money-gold">$0.000</span>
|
||||
(<span class="money-gold"><span id="active-scripts-total-prod-aug-avg" class="money-gold">$0.000</span>
|
||||
/ sec</span>)
|
||||
(<span class="money-gold"
|
||||
><span id="active-scripts-total-prod-aug-avg" class="money-gold">$0.000</span> / sec</span
|
||||
>)
|
||||
</p>
|
||||
<ul class="active-scripts-list" id="active-scripts-list" style="list-style: none"></ul>
|
||||
</div>
|
||||
@ -263,11 +267,9 @@
|
||||
<!-- Create a program(executable) -->
|
||||
<div id="create-program-container" class="generic-menupage-container">
|
||||
<p id="create-program-page-text">
|
||||
This page displays any programs that you are able to create. Writing
|
||||
the code for a program takes time, which can vary based on how complex
|
||||
the program is. If you are working on creating a program you can
|
||||
cancel at any time. Your progress will be saved and you can continue
|
||||
later.
|
||||
This page displays any programs that you are able to create. Writing the code for a program takes time, which
|
||||
can vary based on how complex the program is. If you are working on creating a program you can cancel at any
|
||||
time. Your progress will be saved and you can continue later.
|
||||
</p>
|
||||
|
||||
<ul id="create-program-list"></ul>
|
||||
@ -291,28 +293,76 @@
|
||||
<!-- Tutorial content -->
|
||||
<div id="tutorial-container" class="generic-menupage-container">
|
||||
<h1>Tutorial (AKA Links to Documentation)</h1>
|
||||
<a id="tutorial-getting-started-link" class="a-link-button" target="_blank" href="https://bitburner.readthedocs.io/en/latest/guidesandtips/gettingstartedguideforbeginnerprogrammers.html">
|
||||
Getting Started</a><br/><br/>
|
||||
<a class="a-link-button" target="_blank" href="https://bitburner.readthedocs.io/en/latest/basicgameplay/servers.html">
|
||||
Servers & Networking</a><br/><br/>
|
||||
<a class="a-link-button" target="_blank" href="https://bitburner.readthedocs.io/en/latest/basicgameplay/hacking.html">
|
||||
Hacking</a><br/><br/>
|
||||
<a class="a-link-button" target="_blank" href="https://bitburner.readthedocs.io/en/latest/basicgameplay/scripts.html">
|
||||
Scripts</a><br/><br/>
|
||||
<a
|
||||
id="tutorial-getting-started-link"
|
||||
class="a-link-button"
|
||||
target="_blank"
|
||||
href="https://bitburner.readthedocs.io/en/latest/guidesandtips/gettingstartedguideforbeginnerprogrammers.html"
|
||||
>
|
||||
Getting Started</a
|
||||
><br /><br />
|
||||
<a
|
||||
class="a-link-button"
|
||||
target="_blank"
|
||||
href="https://bitburner.readthedocs.io/en/latest/basicgameplay/servers.html"
|
||||
>
|
||||
Servers & Networking</a
|
||||
><br /><br />
|
||||
<a
|
||||
class="a-link-button"
|
||||
target="_blank"
|
||||
href="https://bitburner.readthedocs.io/en/latest/basicgameplay/hacking.html"
|
||||
>
|
||||
Hacking</a
|
||||
><br /><br />
|
||||
<a
|
||||
class="a-link-button"
|
||||
target="_blank"
|
||||
href="https://bitburner.readthedocs.io/en/latest/basicgameplay/scripts.html"
|
||||
>
|
||||
Scripts</a
|
||||
><br /><br />
|
||||
<a class="a-link-button" target="_blank" href="https://bitburner.readthedocs.io/en/latest/netscript.html">
|
||||
Netscript Programming Language</a><br/><br/>
|
||||
<a class="a-link-button" target="_blank" href="https://bitburner.readthedocs.io/en/latest/basicgameplay/world.html">
|
||||
Traveling</a><br/><br/>
|
||||
<a class="a-link-button" target="_blank" href="https://bitburner.readthedocs.io/en/latest/basicgameplay/companies.html">
|
||||
Companies</a><br/><br/>
|
||||
<a class="a-link-button" target="_blank" href="https://bitburner.readthedocs.io/en/latest/basicgameplay/infiltration.html">
|
||||
Infiltration</a><br/><br/>
|
||||
<a class="a-link-button" target="_blank" href="https://bitburner.readthedocs.io/en/latest/basicgameplay/factions.html">
|
||||
Factions</a><br/><br/>
|
||||
<a class="a-link-button" target="_blank" href="https://bitburner.readthedocs.io/en/latest/basicgameplay/augmentations.html">
|
||||
Augmentations</a><br/><br/>
|
||||
Netscript Programming Language</a
|
||||
><br /><br />
|
||||
<a
|
||||
class="a-link-button"
|
||||
target="_blank"
|
||||
href="https://bitburner.readthedocs.io/en/latest/basicgameplay/world.html"
|
||||
>
|
||||
Traveling</a
|
||||
><br /><br />
|
||||
<a
|
||||
class="a-link-button"
|
||||
target="_blank"
|
||||
href="https://bitburner.readthedocs.io/en/latest/basicgameplay/companies.html"
|
||||
>
|
||||
Companies</a
|
||||
><br /><br />
|
||||
<a
|
||||
class="a-link-button"
|
||||
target="_blank"
|
||||
href="https://bitburner.readthedocs.io/en/latest/basicgameplay/infiltration.html"
|
||||
>
|
||||
Infiltration</a
|
||||
><br /><br />
|
||||
<a
|
||||
class="a-link-button"
|
||||
target="_blank"
|
||||
href="https://bitburner.readthedocs.io/en/latest/basicgameplay/factions.html"
|
||||
>
|
||||
Factions</a
|
||||
><br /><br />
|
||||
<a
|
||||
class="a-link-button"
|
||||
target="_blank"
|
||||
href="https://bitburner.readthedocs.io/en/latest/basicgameplay/augmentations.html"
|
||||
>
|
||||
Augmentations</a
|
||||
><br /><br />
|
||||
<a class="a-link-button" target="_blank" href="https://bitburner.readthedocs.io/en/latest/shortcuts.html">
|
||||
Keyboard Shortcuts</a>
|
||||
Keyboard Shortcuts</a
|
||||
>
|
||||
</div>
|
||||
|
||||
<!-- Location (visiting a location in World) -->
|
||||
@ -341,13 +391,9 @@
|
||||
<div id="yes-no-text-input-box-container" class="popup-box-container">
|
||||
<div id="yes-no-text-input-box-content" class="popup-box-content">
|
||||
<p id="yes-no-text-input-box-text"></p>
|
||||
<input type="text" id="yes-no-text-input-box-input" pattern="[a-zA-Z0-9-_]" maxlength="30"/>
|
||||
<button id="yes-no-text-input-box-yes" class="popup-box-button">
|
||||
Yes
|
||||
</button>
|
||||
<button id="yes-no-text-input-box-no" class="popup-box-button">
|
||||
No
|
||||
</button>
|
||||
<input type="text" id="yes-no-text-input-box-input" pattern="[a-zA-Z0-9-_]" maxlength="30" />
|
||||
<button id="yes-no-text-input-box-yes" class="popup-box-button">Yes</button>
|
||||
<button id="yes-no-text-input-box-no" class="popup-box-button">No</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -357,17 +403,12 @@
|
||||
<p id="faction-invitation-box-text"></p>
|
||||
<p id="faction-invitation-box-message"></p>
|
||||
<p id="faction-invitation-box-warning">
|
||||
Would you like to join? <br/>
|
||||
<br/>
|
||||
Warning: Joining this faction may prevent you from joining other
|
||||
factions during this run!
|
||||
Would you like to join? <br />
|
||||
<br />
|
||||
Warning: Joining this faction may prevent you from joining other factions during this run!
|
||||
</p>
|
||||
<button id="faction-invitation-box-yes" class="popup-box-button">
|
||||
Join!
|
||||
</button>
|
||||
<button id="faction-invitation-box-no" class="popup-box-button">
|
||||
Decide later
|
||||
</button>
|
||||
<button id="faction-invitation-box-yes" class="popup-box-button">Join!</button>
|
||||
<button id="faction-invitation-box-no" class="popup-box-button">Decide later</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -376,15 +417,11 @@
|
||||
<div id="infiltration-box-content" class="popup-box-content">
|
||||
<p id="infiltration-box-text"></p>
|
||||
|
||||
<button id="infiltration-box-sell" class="a-link-button">
|
||||
Sell on Black Market
|
||||
</button>
|
||||
<br/><br/>
|
||||
<button id="infiltration-box-sell" class="a-link-button">Sell on Black Market</button>
|
||||
<br /><br />
|
||||
<select id="infiltration-faction-select" class="dropdown"></select>
|
||||
<br/>
|
||||
<button id="infiltration-box-faction" class="a-link-button">
|
||||
Give to Faction for Reputation
|
||||
</button>
|
||||
<br />
|
||||
<button id="infiltration-box-faction" class="a-link-button">Give to Faction for Reputation</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -395,9 +432,7 @@
|
||||
<div id="work-in-progress-container" class="generic-fullscreen-container">
|
||||
<p id="work-in-progress-text"></p>
|
||||
|
||||
<button id="work-in-progress-cancel-button" class="work-button">
|
||||
Cancel Work
|
||||
</button>
|
||||
<button id="work-in-progress-cancel-button" class="work-button">Cancel Work</button>
|
||||
<button id="work-in-progress-something-else-button" class="work-button">
|
||||
Do something else simultaneously
|
||||
</button>
|
||||
@ -428,12 +463,8 @@
|
||||
<!-- ReactJS Component -->
|
||||
</div>
|
||||
<div class="character-quick-options noselect">
|
||||
<button id="character-overview-save-button" class="character-overview-btn">
|
||||
Save Game
|
||||
</button>
|
||||
<button id="character-overview-options-button" class="character-overview-btn">
|
||||
Options
|
||||
</button>
|
||||
<button id="character-overview-save-button" class="character-overview-btn">Save Game</button>
|
||||
<button id="character-overview-options-button" class="character-overview-btn">Options</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -446,180 +477,251 @@
|
||||
<!-- Game Options -->
|
||||
<div id="game-options-container" class="popup-box-container">
|
||||
<div id="game-options-content" class="game-options-box">
|
||||
<button id="game-options-close-button" aria-label="close options dialog">
|
||||
×
|
||||
</button>
|
||||
<button id="game-options-close-button" aria-label="close options dialog">×</button>
|
||||
<h1>Game Options</h1>
|
||||
<br/>
|
||||
<br />
|
||||
<div id="game-options-left-panel">
|
||||
<!-- Netscript execution time -->
|
||||
<fieldset>
|
||||
<label for="settingsNSExecTimeRangeVal" class="tooltip">Netscript exec time:
|
||||
<label for="settingsNSExecTimeRangeVal" class="tooltip"
|
||||
>Netscript exec time:
|
||||
<span class="tooltiptext">
|
||||
The minimum number of milliseconds it takes to execute an
|
||||
operation in Netscript. Setting this too low can result in
|
||||
poor performance if you have many scripts running. The default
|
||||
value is 25ms.
|
||||
The minimum number of milliseconds it takes to execute an operation in Netscript. Setting this too low
|
||||
can result in poor performance if you have many scripts running. The default value is 25ms.
|
||||
</span>
|
||||
</label>
|
||||
|
||||
<input class="optionRange" type="range" max="100" min="10" step="1" name="settingsNSExecTimeRangeVal" id="settingsNSExecTimeRangeVal" value="25"/>
|
||||
<input
|
||||
class="optionRange"
|
||||
type="range"
|
||||
max="100"
|
||||
min="10"
|
||||
step="1"
|
||||
name="settingsNSExecTimeRangeVal"
|
||||
id="settingsNSExecTimeRangeVal"
|
||||
value="25"
|
||||
/>
|
||||
<em id="settingsNSExecTimeRangeValLabel" style="font-style: normal"></em>
|
||||
</fieldset>
|
||||
|
||||
<!-- Log capacity -->
|
||||
<fieldset>
|
||||
<label for="settingsNSLogRangeVal" class="tooltip">Netscript log size:
|
||||
<label for="settingsNSLogRangeVal" class="tooltip"
|
||||
>Netscript log size:
|
||||
<span class="tooltiptext">
|
||||
The maximum number of lines a script's logs can hold. Setting
|
||||
this too high can cause the game to use a lot of memory if you
|
||||
have many scripts running. The default value is 50.
|
||||
The maximum number of lines a script's logs can hold. Setting this too high can cause the game to use
|
||||
a lot of memory if you have many scripts running. The default value is 50.
|
||||
</span>
|
||||
</label>
|
||||
|
||||
<input class="optionRange" type="range" max="100" min="20" step="1" name="settingsNSLogRangeVal" id="settingsNSLogRangeVal" value="50"/>
|
||||
<input
|
||||
class="optionRange"
|
||||
type="range"
|
||||
max="100"
|
||||
min="20"
|
||||
step="1"
|
||||
name="settingsNSLogRangeVal"
|
||||
id="settingsNSLogRangeVal"
|
||||
value="50"
|
||||
/>
|
||||
<em id="settingsNSLogRangeValLabel" style="font-style: normal"></em>
|
||||
</fieldset>
|
||||
|
||||
<!-- Port capacity -->
|
||||
<fieldset>
|
||||
<label for="settingsNSPortRangeVal" class="tooltip">Netscript port size:
|
||||
<label for="settingsNSPortRangeVal" class="tooltip"
|
||||
>Netscript port size:
|
||||
<span class="tooltiptext">
|
||||
The maximum number of entries that can be written to a port
|
||||
using Netscript's write() function. Setting this too high can
|
||||
cause the game to use a lot of memory. The default value is
|
||||
50.
|
||||
The maximum number of entries that can be written to a port using Netscript's write() function.
|
||||
Setting this too high can cause the game to use a lot of memory. The default value is 50.
|
||||
</span>
|
||||
</label>
|
||||
|
||||
<input class="optionRange" type="range" max="100" min="20" step="1" name="settingsNSPortRangeVal" id="settingsNSPortRangeVal" value="50"/>
|
||||
<input
|
||||
class="optionRange"
|
||||
type="range"
|
||||
max="100"
|
||||
min="20"
|
||||
step="1"
|
||||
name="settingsNSPortRangeVal"
|
||||
id="settingsNSPortRangeVal"
|
||||
value="50"
|
||||
/>
|
||||
<em id="settingsNSPortRangeValLabel" style="font-style: normal"></em>
|
||||
</fieldset>
|
||||
|
||||
<!-- Autosave Interval -->
|
||||
<fieldset>
|
||||
<label for="settingsAutosaveIntervalVal" class="tooltip">Autosave Interval:
|
||||
<label for="settingsAutosaveIntervalVal" class="tooltip"
|
||||
>Autosave Interval:
|
||||
<span class="tooltiptext">
|
||||
The time (in seconds) between each autosave. Set to 0 to
|
||||
disable autosave.
|
||||
The time (in seconds) between each autosave. Set to 0 to disable autosave.
|
||||
</span>
|
||||
</label>
|
||||
|
||||
<input class="optionRange" type="range" max="600" min="0" step="1" name="settingsAutosaveIntervalVal" id="settingsAutosaveIntervalVal" value="60"/>
|
||||
<input
|
||||
class="optionRange"
|
||||
type="range"
|
||||
max="600"
|
||||
min="0"
|
||||
step="1"
|
||||
name="settingsAutosaveIntervalVal"
|
||||
id="settingsAutosaveIntervalVal"
|
||||
value="60"
|
||||
/>
|
||||
<em id="settingsAutosaveIntervalValLabel" style="font-style: normal"></em>
|
||||
</fieldset>
|
||||
|
||||
<!-- Suppress messages -->
|
||||
<fieldset>
|
||||
<label for="settingsSuppressMessages" class="tooltip">Suppress Messages:
|
||||
<label for="settingsSuppressMessages" class="tooltip"
|
||||
>Suppress Messages:
|
||||
<span class="tooltiptext">
|
||||
If this is set, then any messages you receive will not appear
|
||||
as popups on the screen. They will still get sent to your home
|
||||
computer as '.msg' files and can be viewed with the 'cat'
|
||||
Terminal command.
|
||||
If this is set, then any messages you receive will not appear as popups on the screen. They will still
|
||||
get sent to your home computer as '.msg' files and can be viewed with the 'cat' Terminal command.
|
||||
</span>
|
||||
</label>
|
||||
<input class="optionCheckbox" type="checkbox" name="settingsSuppressMessages" id="settingsSuppressMessages"/>
|
||||
<input
|
||||
class="optionCheckbox"
|
||||
type="checkbox"
|
||||
name="settingsSuppressMessages"
|
||||
id="settingsSuppressMessages"
|
||||
/>
|
||||
</fieldset>
|
||||
|
||||
<!-- Suppress faction invites -->
|
||||
<fieldset>
|
||||
<label for="settingsSuppressFactionInvites" class="tooltip">Suppress Faction Invites:
|
||||
<label for="settingsSuppressFactionInvites" class="tooltip"
|
||||
>Suppress Faction Invites:
|
||||
<span class="tooltiptexthigh">
|
||||
If this is set, then any faction invites you receive will not
|
||||
appear as popups on the screen. Your outstanding faction
|
||||
invites can be viewed in the 'Factions' page.
|
||||
If this is set, then any faction invites you receive will not appear as popups on the screen. Your
|
||||
outstanding faction invites can be viewed in the 'Factions' page.
|
||||
</span>
|
||||
</label>
|
||||
<input class="optionCheckbox" type="checkbox" name="settingsSuppressFactionInvites" id="settingsSuppressFactionInvites"/>
|
||||
<input
|
||||
class="optionCheckbox"
|
||||
type="checkbox"
|
||||
name="settingsSuppressFactionInvites"
|
||||
id="settingsSuppressFactionInvites"
|
||||
/>
|
||||
</fieldset>
|
||||
|
||||
<!-- Suppress travel confirmation -->
|
||||
<fieldset>
|
||||
<label for="settingsSuppressTravelConfirmation" class="tooltip">Suppress Travel Confirmation:
|
||||
<label for="settingsSuppressTravelConfirmation" class="tooltip"
|
||||
>Suppress Travel Confirmation:
|
||||
<span class="tooltiptexthigh">
|
||||
If this is set, the confirmation message before traveling will
|
||||
not show up. You will automatically be deducted the travel
|
||||
cost as soon as you click.
|
||||
If this is set, the confirmation message before traveling will not show up. You will automatically be
|
||||
deducted the travel cost as soon as you click.
|
||||
</span>
|
||||
</label>
|
||||
<input class="optionCheckbox" type="checkbox" name="settingsSuppressTravelConfirmation" id="settingsSuppressTravelConfirmation"/>
|
||||
<input
|
||||
class="optionCheckbox"
|
||||
type="checkbox"
|
||||
name="settingsSuppressTravelConfirmation"
|
||||
id="settingsSuppressTravelConfirmation"
|
||||
/>
|
||||
</fieldset>
|
||||
|
||||
<!-- Suppress buy aug confirmation -->
|
||||
<fieldset>
|
||||
<label for="settingsSuppressBuyAugmentationConfirmation" class="tooltip">Suppress buy augmentation confirmation:
|
||||
<label for="settingsSuppressBuyAugmentationConfirmation" class="tooltip"
|
||||
>Suppress buy augmentation confirmation:
|
||||
<span class="tooltiptexthigh">
|
||||
If this is set, the confirmation message before buying
|
||||
augmentation will not show up.
|
||||
If this is set, the confirmation message before buying augmentation will not show up.
|
||||
</span>
|
||||
</label>
|
||||
<input class="optionCheckbox" type="checkbox" name="settingsSuppressBuyAugmentationConfirmation" id="settingsSuppressBuyAugmentationConfirmation"/>
|
||||
<input
|
||||
class="optionCheckbox"
|
||||
type="checkbox"
|
||||
name="settingsSuppressBuyAugmentationConfirmation"
|
||||
id="settingsSuppressBuyAugmentationConfirmation"
|
||||
/>
|
||||
</fieldset>
|
||||
|
||||
<!-- Hospitalization Popup -->
|
||||
<fieldset>
|
||||
<label for="settingsSuppressHospitalizationPopup" class="tooltip">Suppress Hospitalization popup:
|
||||
<label for="settingsSuppressHospitalizationPopup" class="tooltip"
|
||||
>Suppress Hospitalization popup:
|
||||
<span class="tooltiptexthigh">
|
||||
If this is set, a popup message will no longer be shown when
|
||||
you are hospitalized after taking too much damage.
|
||||
If this is set, a popup message will no longer be shown when you are hospitalized after taking too
|
||||
much damage.
|
||||
</span>
|
||||
</label>
|
||||
<input class="optionCheckbox" type="checkbox" name="settingsSuppressHospitalizationPopup" id="settingsSuppressHospitalizationPopup"/>
|
||||
<input
|
||||
class="optionCheckbox"
|
||||
type="checkbox"
|
||||
name="settingsSuppressHospitalizationPopup"
|
||||
id="settingsSuppressHospitalizationPopup"
|
||||
/>
|
||||
</fieldset>
|
||||
|
||||
<!-- Suppress Bladeburner popups -->
|
||||
<fieldset>
|
||||
<label for="settingsSuppressBladeburnerPopup" class="tooltip">Suppress Bladeburner Popup:
|
||||
<label for="settingsSuppressBladeburnerPopup" class="tooltip"
|
||||
>Suppress Bladeburner Popup:
|
||||
<span class="tooltiptext">
|
||||
If this is set, then having your Bladeburner actions
|
||||
interrupted by being busy with something else will not display
|
||||
a popup message.
|
||||
If this is set, then having your Bladeburner actions interrupted by being busy with something else
|
||||
will not display a popup message.
|
||||
</span>
|
||||
</label>
|
||||
<input class="optionCheckbox" type="checkbox" name="settingsSuppressBladeburnerPopup" id="settingsSuppressBladeburnerPopup"/>
|
||||
<input
|
||||
class="optionCheckbox"
|
||||
type="checkbox"
|
||||
name="settingsSuppressBladeburnerPopup"
|
||||
id="settingsSuppressBladeburnerPopup"
|
||||
/>
|
||||
</fieldset>
|
||||
|
||||
<!-- Disable Terminal and Navigation Shortcuts -->
|
||||
<fieldset>
|
||||
<label for="settingsDisableHotkeys" class="tooltip">Disable Hotkeys:
|
||||
<label for="settingsDisableHotkeys" class="tooltip"
|
||||
>Disable Hotkeys:
|
||||
<span class="tooltiptexthigh">
|
||||
If this is set, then most hotkeys (keyboard shortcuts) in the
|
||||
game are disabled. This includes Terminal commands, hotkeys to
|
||||
navigate between different parts of the game, and the "Save
|
||||
and Close (Ctrl + b)" hotkey in the Text Editor.
|
||||
If this is set, then most hotkeys (keyboard shortcuts) in the game are disabled. This includes
|
||||
Terminal commands, hotkeys to navigate between different parts of the game, and the "Save and Close
|
||||
(Ctrl + b)" hotkey in the Text Editor.
|
||||
</span>
|
||||
</label>
|
||||
<input class="optionCheckbox" type="checkbox" name="settingsDisableHotkeys" id="settingsDisableHotkeys"/>
|
||||
<input class="optionCheckbox" type="checkbox" name="settingsDisableHotkeys" id="settingsDisableHotkeys" />
|
||||
</fieldset>
|
||||
|
||||
<!-- View city as list of buttons instead of ASCII art. -->
|
||||
<fieldset>
|
||||
<label for="settingsDisableASCIIArt" class="tooltip">Disable ASCII art:
|
||||
<span class="tooltiptexthigh">
|
||||
If this is set all ASCII art will be disabled.
|
||||
</span>
|
||||
<label for="settingsDisableASCIIArt" class="tooltip"
|
||||
>Disable ASCII art:
|
||||
<span class="tooltiptexthigh"> If this is set all ASCII art will be disabled. </span>
|
||||
</label>
|
||||
<input class="optionCheckbox" type="checkbox" name="settingsDisableASCIIArt" id="settingsDisableASCIIArt"/>
|
||||
<input
|
||||
class="optionCheckbox"
|
||||
type="checkbox"
|
||||
name="settingsDisableASCIIArt"
|
||||
id="settingsDisableASCIIArt"
|
||||
/>
|
||||
</fieldset>
|
||||
|
||||
<!-- Disable text effects such as corruption. -->
|
||||
<fieldset>
|
||||
<label for="settingsDisableTextEffects" class="tooltip">Disable Text Effects:
|
||||
<label for="settingsDisableTextEffects" class="tooltip"
|
||||
>Disable Text Effects:
|
||||
<span class="tooltiptexthigh">
|
||||
If this is set, text effects will not be displayed. This can
|
||||
help if text is difficult to read in certain areas.
|
||||
If this is set, text effects will not be displayed. This can help if text is difficult to read in
|
||||
certain areas.
|
||||
</span>
|
||||
</label>
|
||||
<input class="optionCheckbox" type="checkbox" name="settingsDisableTextEffects" id="settingsDisableTextEffects"/>
|
||||
<input
|
||||
class="optionCheckbox"
|
||||
type="checkbox"
|
||||
name="settingsDisableTextEffects"
|
||||
id="settingsDisableTextEffects"
|
||||
/>
|
||||
</fieldset>
|
||||
|
||||
<!-- Locale for displaying numbers -->
|
||||
<fieldset>
|
||||
<label for="settingsLocale" class="tooltip">Locale:
|
||||
<span class="tooltiptexthigh">
|
||||
Sets the locale for displaying numbers. Defaults to 'en'
|
||||
</span>
|
||||
<label for="settingsLocale" class="tooltip"
|
||||
>Locale:
|
||||
<span class="tooltiptexthigh"> Sets the locale for displaying numbers. Defaults to 'en' </span>
|
||||
</label>
|
||||
<select name="settingsLocale" id="settingsLocale" class="dropdown">
|
||||
<option value="en">en</option>
|
||||
@ -642,60 +744,59 @@
|
||||
|
||||
<!-- Donate button -->
|
||||
<form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_blank">
|
||||
<input type="hidden" name="cmd" value="_s-xclick"/>
|
||||
<input type="hidden" name="encrypted" value="-----BEGIN PKCS7-----MIIHRwYJKoZIhvcNAQcEoIIHODCCBzQCAQExggEwMIIBLAIBADCBlDCBjjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQKEwtQYXlQYWwgSW5jLjETMBEGA1UECxQKbGl2ZV9jZXJ0czERMA8GA1UEAxQIbGl2ZV9hcGkxHDAaBgkqhkiG9w0BCQEWDXJlQHBheXBhbC5jb20CAQAwDQYJKoZIhvcNAQEBBQAEgYA2Y2VGE75oWct89z//G2YEJKmzx0uDTXNrpje9ThxmUnBLFZCY+I11Pors7lGRvFqo5okwnu41CfYMPHDxpAgyYyQndMX9pWUX0gLfBMm2BaHwsNBCwt34WmpQqj7TGsQ+aw9NbmkxiJltGnOa+6/gy10mPZAA3HxiieLeCKkGgDELMAkGBSsOAwIaBQAwgcQGCSqGSIb3DQEHATAUBggqhkiG9w0DBwQI72F1YSzHUd2AgaDMekHU3AKT93Ey9wkB3486bV+ngFSD6VOHrPweH9QATsp+PMe9QM9vmq+s2bGtTbZaYrFqM3M97SnQ0l7IQ5yuOzdZhRdfysu5uJ8dnuHUzq4gLSzqMnZ6/3c+PoHB8AS1nYHUVL4U0+ogZsO1s97IAQyfck9SaoFlxVtqQhkb8752MkQJJvGu3ZQSQGcVC4hFDPk8prXqyq4BU/k/EliwoIIDhzCCA4MwggLsoAMCAQICAQAwDQYJKoZIhvcNAQEFBQAwgY4xCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEUMBIGA1UEChMLUGF5UGFsIEluYy4xEzARBgNVBAsUCmxpdmVfY2VydHMxETAPBgNVBAMUCGxpdmVfYXBpMRwwGgYJKoZIhvcNAQkBFg1yZUBwYXlwYWwuY29tMB4XDTA0MDIxMzEwMTMxNVoXDTM1MDIxMzEwMTMxNVowgY4xCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEUMBIGA1UEChMLUGF5UGFsIEluYy4xEzARBgNVBAsUCmxpdmVfY2VydHMxETAPBgNVBAMUCGxpdmVfYXBpMRwwGgYJKoZIhvcNAQkBFg1yZUBwYXlwYWwuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDBR07d/ETMS1ycjtkpkvjXZe9k+6CieLuLsPumsJ7QC1odNz3sJiCbs2wC0nLE0uLGaEtXynIgRqIddYCHx88pb5HTXv4SZeuv0Rqq4+axW9PLAAATU8w04qqjaSXgbGLP3NmohqM6bV9kZZwZLR/klDaQGo1u9uDb9lr4Yn+rBQIDAQABo4HuMIHrMB0GA1UdDgQWBBSWn3y7xm8XvVk/UtcKG+wQ1mSUazCBuwYDVR0jBIGzMIGwgBSWn3y7xm8XvVk/UtcKG+wQ1mSUa6GBlKSBkTCBjjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQKEwtQYXlQYWwgSW5jLjETMBEGA1UECxQKbGl2ZV9jZXJ0czERMA8GA1UEAxQIbGl2ZV9hcGkxHDAaBgkqhkiG9w0BCQEWDXJlQHBheXBhbC5jb22CAQAwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQCBXzpWmoBa5e9fo6ujionW1hUhPkOBakTr3YCDjbYfvJEiv/2P+IobhOGJr85+XHhN0v4gUkEDI8r2/rNk1m0GA8HKddvTjyGw/XqXa+LSTlDYkqI8OwR8GEYj4efEtcRpRYBxV8KxAW93YDWzFGvruKnnLbDAF6VR5w/cCMn5hzGCAZowggGWAgEBMIGUMIGOMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExFjAUBgNVBAcTDU1vdW50YWluIFZpZXcxFDASBgNVBAoTC1BheVBhbCBJbmMuMRMwEQYDVQQLFApsaXZlX2NlcnRzMREwDwYDVQQDFAhsaXZlX2FwaTEcMBoGCSqGSIb3DQEJARYNcmVAcGF5cGFsLmNvbQIBADAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAcBgkqhkiG9w0BCQUxDxcNMTcwNzI1MDExODE2WjAjBgkqhkiG9w0BCQQxFgQUNo8efiZ7sk7nwKM/6B6Z7sU8hIIwDQYJKoZIhvcNAQEBBQAEgYB+JB4vZ/r48815/1HF/xK3+rOx7bPz3kAXmbhW/mkoF4OUbzqMeljvDIA9q/BDdlCLtxFOw9XlftTzv0eZCW/uCIiwu5wTzPIfPY1SI8WHe4cJbP2f2EYxIVs8D7OSirbW4yVa0+gACaLLj0rzIzNN8P/5PxgB03D+jwkcJABqng==-----END PKCS7-----
|
||||
"/>
|
||||
<input type="image" src="https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!"/>
|
||||
<img alt="" border="0" src="https://www.paypalobjects.com/en_US/i/scr/pixel.gif" width="1" height="1"/>
|
||||
<input type="hidden" name="cmd" value="_s-xclick" />
|
||||
<input
|
||||
type="hidden"
|
||||
name="encrypted"
|
||||
value="-----BEGIN PKCS7-----MIIHRwYJKoZIhvcNAQcEoIIHODCCBzQCAQExggEwMIIBLAIBADCBlDCBjjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQKEwtQYXlQYWwgSW5jLjETMBEGA1UECxQKbGl2ZV9jZXJ0czERMA8GA1UEAxQIbGl2ZV9hcGkxHDAaBgkqhkiG9w0BCQEWDXJlQHBheXBhbC5jb20CAQAwDQYJKoZIhvcNAQEBBQAEgYA2Y2VGE75oWct89z//G2YEJKmzx0uDTXNrpje9ThxmUnBLFZCY+I11Pors7lGRvFqo5okwnu41CfYMPHDxpAgyYyQndMX9pWUX0gLfBMm2BaHwsNBCwt34WmpQqj7TGsQ+aw9NbmkxiJltGnOa+6/gy10mPZAA3HxiieLeCKkGgDELMAkGBSsOAwIaBQAwgcQGCSqGSIb3DQEHATAUBggqhkiG9w0DBwQI72F1YSzHUd2AgaDMekHU3AKT93Ey9wkB3486bV+ngFSD6VOHrPweH9QATsp+PMe9QM9vmq+s2bGtTbZaYrFqM3M97SnQ0l7IQ5yuOzdZhRdfysu5uJ8dnuHUzq4gLSzqMnZ6/3c+PoHB8AS1nYHUVL4U0+ogZsO1s97IAQyfck9SaoFlxVtqQhkb8752MkQJJvGu3ZQSQGcVC4hFDPk8prXqyq4BU/k/EliwoIIDhzCCA4MwggLsoAMCAQICAQAwDQYJKoZIhvcNAQEFBQAwgY4xCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEUMBIGA1UEChMLUGF5UGFsIEluYy4xEzARBgNVBAsUCmxpdmVfY2VydHMxETAPBgNVBAMUCGxpdmVfYXBpMRwwGgYJKoZIhvcNAQkBFg1yZUBwYXlwYWwuY29tMB4XDTA0MDIxMzEwMTMxNVoXDTM1MDIxMzEwMTMxNVowgY4xCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEUMBIGA1UEChMLUGF5UGFsIEluYy4xEzARBgNVBAsUCmxpdmVfY2VydHMxETAPBgNVBAMUCGxpdmVfYXBpMRwwGgYJKoZIhvcNAQkBFg1yZUBwYXlwYWwuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDBR07d/ETMS1ycjtkpkvjXZe9k+6CieLuLsPumsJ7QC1odNz3sJiCbs2wC0nLE0uLGaEtXynIgRqIddYCHx88pb5HTXv4SZeuv0Rqq4+axW9PLAAATU8w04qqjaSXgbGLP3NmohqM6bV9kZZwZLR/klDaQGo1u9uDb9lr4Yn+rBQIDAQABo4HuMIHrMB0GA1UdDgQWBBSWn3y7xm8XvVk/UtcKG+wQ1mSUazCBuwYDVR0jBIGzMIGwgBSWn3y7xm8XvVk/UtcKG+wQ1mSUa6GBlKSBkTCBjjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQKEwtQYXlQYWwgSW5jLjETMBEGA1UECxQKbGl2ZV9jZXJ0czERMA8GA1UEAxQIbGl2ZV9hcGkxHDAaBgkqhkiG9w0BCQEWDXJlQHBheXBhbC5jb22CAQAwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQCBXzpWmoBa5e9fo6ujionW1hUhPkOBakTr3YCDjbYfvJEiv/2P+IobhOGJr85+XHhN0v4gUkEDI8r2/rNk1m0GA8HKddvTjyGw/XqXa+LSTlDYkqI8OwR8GEYj4efEtcRpRYBxV8KxAW93YDWzFGvruKnnLbDAF6VR5w/cCMn5hzGCAZowggGWAgEBMIGUMIGOMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExFjAUBgNVBAcTDU1vdW50YWluIFZpZXcxFDASBgNVBAoTC1BheVBhbCBJbmMuMRMwEQYDVQQLFApsaXZlX2NlcnRzMREwDwYDVQQDFAhsaXZlX2FwaTEcMBoGCSqGSIb3DQEJARYNcmVAcGF5cGFsLmNvbQIBADAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAcBgkqhkiG9w0BCQUxDxcNMTcwNzI1MDExODE2WjAjBgkqhkiG9w0BCQQxFgQUNo8efiZ7sk7nwKM/6B6Z7sU8hIIwDQYJKoZIhvcNAQEBBQAEgYB+JB4vZ/r48815/1HF/xK3+rOx7bPz3kAXmbhW/mkoF4OUbzqMeljvDIA9q/BDdlCLtxFOw9XlftTzv0eZCW/uCIiwu5wTzPIfPY1SI8WHe4cJbP2f2EYxIVs8D7OSirbW4yVa0+gACaLLj0rzIzNN8P/5PxgB03D+jwkcJABqng==-----END PKCS7-----
|
||||
"
|
||||
/>
|
||||
<input
|
||||
type="image"
|
||||
src="https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif"
|
||||
border="0"
|
||||
name="submit"
|
||||
alt="PayPal - The safer, easier way to pay online!"
|
||||
/>
|
||||
<img alt="" border="0" src="https://www.paypalobjects.com/en_US/i/scr/pixel.gif" width="1" height="1" />
|
||||
</form>
|
||||
</div>
|
||||
<div id="game-options-right-panel">
|
||||
<a class="a-link-button" href="https://bitburner.readthedocs.io/en/latest/changelog.html" target="_blank">
|
||||
Changelog
|
||||
</a>
|
||||
<a class="a-link-button" href="https://bitburner.readthedocs.io/en/latest/index.html" target="_blank">Documentation</a>
|
||||
<a class="a-link-button" href="https://bitburner.readthedocs.io/en/latest/index.html" target="_blank"
|
||||
>Documentation</a
|
||||
>
|
||||
<a class="a-link-button" href="https://discord.gg/TFc3hKD" target="_blank">Discord</a>
|
||||
<a class="a-link-button" href="https://www.reddit.com/r/bitburner" target="_blank">Subreddit</a>
|
||||
<button id="save-game-link" class="a-link-button">Save Game</button>
|
||||
<button id="delete-game-link" class="a-link-button">
|
||||
Delete Game
|
||||
</button>
|
||||
<button id="export-game-link" class="a-link-button">
|
||||
Export Game
|
||||
</button>
|
||||
<input type="file" id="import-game-file-selector" name="file"/>
|
||||
<button id="import-game-link" class="a-link-button">
|
||||
Import Game
|
||||
</button>
|
||||
<button id="copy-save-to-clipboard-link" class="std-button">
|
||||
Copy Save data to Clipboard
|
||||
</button>
|
||||
<button id="delete-game-link" class="a-link-button">Delete Game</button>
|
||||
<button id="export-game-link" class="a-link-button">Export Game</button>
|
||||
<input type="file" id="import-game-file-selector" name="file" />
|
||||
<button id="import-game-link" class="a-link-button">Import Game</button>
|
||||
<button id="copy-save-to-clipboard-link" class="std-button">Copy Save data to Clipboard</button>
|
||||
<button id="debug-delete-scripts-link" class="a-link-button tooltip">
|
||||
Force kill all active scripts
|
||||
<span class="tooltiptextleft">
|
||||
Forcefully kill all active running scripts, in case there is a
|
||||
bug or some unexpected issue with the game. After using this,
|
||||
save the game and then reload the page. This is different then
|
||||
normal kill in that normal kill will tell the script to shut
|
||||
down while force kill just removes the references to it (and it
|
||||
should crash on it's own). This will not remove the files on
|
||||
your computer. Just forcefully kill all running instance of all
|
||||
scripts.
|
||||
Forcefully kill all active running scripts, in case there is a bug or some unexpected issue with the
|
||||
game. After using this, save the game and then reload the page. This is different then normal kill in
|
||||
that normal kill will tell the script to shut down while force kill just removes the references to it
|
||||
(and it should crash on it's own). This will not remove the files on your computer. Just forcefully kill
|
||||
all running instance of all scripts.
|
||||
</span>
|
||||
</button>
|
||||
<button id="debug-soft-reset" class="a-link-button tooltip">
|
||||
Soft Reset
|
||||
<span class="tooltiptextleft">
|
||||
Perform a soft reset. Resets everything as if you had just
|
||||
purchased an Augmentation.
|
||||
Perform a soft reset. Resets everything as if you had just purchased an Augmentation.
|
||||
</span>
|
||||
</button>
|
||||
<button id="debug-files" class="a-link-button tooltip">
|
||||
Diagnose files
|
||||
<span class="tooltiptextleft">
|
||||
If your save file is extremely big you can use this button to
|
||||
view a map of all the files on every server. Be careful there
|
||||
might be spoilers.
|
||||
If your save file is extremely big you can use this button to view a map of all the files on every
|
||||
server. Be careful there might be spoilers.
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
@ -725,10 +826,11 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="unclickable" style="display: none">
|
||||
Click on this to upgrade your Source-File -1!
|
||||
</div>
|
||||
<script type="text/javascript" src="dist/vendor.bundle.js"></script><script type="text/javascript" src="dist/engine.bundle.js"></script><script type="text/javascript" src="dist/engineStyle.bundle.js"></script></body>
|
||||
<div id="unclickable" style="display: none">Click on this to upgrade your Source-File -1!</div>
|
||||
<script type="text/javascript" src="dist/vendor.bundle.js"></script>
|
||||
<script type="text/javascript" src="dist/engine.bundle.js"></script>
|
||||
<script type="text/javascript" src="dist/engineStyle.bundle.js"></script>
|
||||
</body>
|
||||
|
||||
<!-- Misc Scripts -->
|
||||
<script src="src/ThirdParty/raphael.min.js"></script>
|
||||
|
@ -2,433 +2,366 @@ const numSpaces = 4;
|
||||
const maxLineLength = 160;
|
||||
|
||||
module.exports = {
|
||||
"env": {
|
||||
"es6": true,
|
||||
"node": true
|
||||
env: {
|
||||
es6: true,
|
||||
node: true,
|
||||
},
|
||||
extends: "eslint:recommended",
|
||||
parserOptions: {
|
||||
ecmaFeatures: {
|
||||
experimentalObjectRestSpread: true,
|
||||
},
|
||||
"extends": "eslint:recommended",
|
||||
"parserOptions": {
|
||||
"ecmaFeatures": {
|
||||
"experimentalObjectRestSpread": true
|
||||
},
|
||||
"ecmaVersion": 8,
|
||||
"sourceType": "module"
|
||||
},
|
||||
"rules": {
|
||||
"accessor-pairs": [
|
||||
"error",
|
||||
{
|
||||
"getWithoutSet": false,
|
||||
"setWithoutGet": true
|
||||
}
|
||||
],
|
||||
"array-bracket-newline": ["error"],
|
||||
"array-bracket-spacing": ["error"],
|
||||
"array-callback-return": ["error"],
|
||||
"array-element-newline": ["error"],
|
||||
"arrow-body-style": ["error"],
|
||||
"arrow-parens": ["error"],
|
||||
"arrow-spacing": ["error"],
|
||||
"block-scoped-var": ["error"],
|
||||
"block-spacing": ["error"],
|
||||
"brace-style": ["error"],
|
||||
"callback-return": ["error"],
|
||||
"camelcase": ["error"],
|
||||
"capitalized-comments": ["error"],
|
||||
"class-methods-use-this": ["error"],
|
||||
"comma-dangle": ["error"],
|
||||
"comma-spacing": ["error"],
|
||||
"comma-style": [
|
||||
"error",
|
||||
"last"
|
||||
],
|
||||
"complexity": ["error"],
|
||||
"computed-property-spacing": [
|
||||
"error",
|
||||
"never"
|
||||
],
|
||||
"consistent-return": ["error"],
|
||||
"consistent-this": ["error"],
|
||||
"constructor-super": ["error"],
|
||||
"curly": ["error"],
|
||||
"default-case": ["error"],
|
||||
"dot-location": [
|
||||
"error",
|
||||
"property"
|
||||
],
|
||||
"dot-notation": ["error"],
|
||||
"eol-last": ["error"],
|
||||
"eqeqeq": ["error"],
|
||||
"for-direction": ["error"],
|
||||
"func-call-spacing": ["error"],
|
||||
"func-name-matching": ["error"],
|
||||
"func-names": [
|
||||
"error",
|
||||
"never"
|
||||
],
|
||||
"func-style": ["error"],
|
||||
"function-paren-newline": ["error"],
|
||||
"generator-star-spacing": [
|
||||
"error",
|
||||
"before"
|
||||
],
|
||||
"getter-return": [
|
||||
"error",
|
||||
{
|
||||
"allowImplicit": false
|
||||
}
|
||||
],
|
||||
"global-require": ["error"],
|
||||
"guard-for-in": ["error"],
|
||||
"handle-callback-err": ["error"],
|
||||
"id-blacklist": ["error"],
|
||||
"id-length": ["error"],
|
||||
"id-match": ["error"],
|
||||
"implicit-arrow-linebreak": [
|
||||
"error",
|
||||
"beside"
|
||||
],
|
||||
"indent": [
|
||||
"error",
|
||||
numSpaces,
|
||||
{
|
||||
"SwitchCase": 1
|
||||
}
|
||||
],
|
||||
"init-declarations": ["error"],
|
||||
"jsx-quotes": ["error"],
|
||||
"key-spacing": ["error"],
|
||||
"keyword-spacing": ["error"],
|
||||
"line-comment-position": ["error"],
|
||||
"linebreak-style": [
|
||||
"error",
|
||||
"windows"
|
||||
],
|
||||
"lines-around-comment": ["error"],
|
||||
"lines-between-class-members": ["error"],
|
||||
"max-depth": ["error"],
|
||||
"max-len": [
|
||||
"error",
|
||||
maxLineLength
|
||||
],
|
||||
"max-lines": [
|
||||
"error",
|
||||
{
|
||||
"skipBlankLines": true,
|
||||
"skipComments": true
|
||||
}
|
||||
],
|
||||
"max-nested-callbacks": ["error"],
|
||||
"max-params": ["error"],
|
||||
"max-statements": ["error"],
|
||||
"max-statements-per-line": ["error"],
|
||||
"multiline-comment-style": [
|
||||
"off",
|
||||
"starred-block"
|
||||
],
|
||||
"multiline-ternary": [
|
||||
"error",
|
||||
"never"
|
||||
],
|
||||
"new-cap": ["error"],
|
||||
"new-parens": ["error"],
|
||||
// TODO: configure this...
|
||||
"newline-before-return": ["error"],
|
||||
"newline-per-chained-call": ["error"],
|
||||
"no-alert": ["error"],
|
||||
"no-array-constructor": ["error"],
|
||||
"no-await-in-loop": ["error"],
|
||||
"no-bitwise": ["error"],
|
||||
"no-buffer-constructor": ["error"],
|
||||
"no-caller": ["error"],
|
||||
"no-case-declarations": ["error"],
|
||||
"no-catch-shadow": ["error"],
|
||||
"no-class-assign": ["error"],
|
||||
"no-compare-neg-zero": ["error"],
|
||||
"no-cond-assign": [
|
||||
"error",
|
||||
"except-parens"
|
||||
],
|
||||
"no-confusing-arrow": ["error"],
|
||||
"no-console": ["error"],
|
||||
"no-const-assign": ["error"],
|
||||
"no-constant-condition": [
|
||||
"error",
|
||||
{
|
||||
"checkLoops": false
|
||||
}
|
||||
],
|
||||
"no-continue": ["off"],
|
||||
"no-control-regex": ["error"],
|
||||
"no-debugger": ["error"],
|
||||
"no-delete-var": ["error"],
|
||||
"no-div-regex": ["error"],
|
||||
"no-dupe-args": ["error"],
|
||||
"no-dupe-class-members": ["error"],
|
||||
"no-dupe-keys": ["error"],
|
||||
"no-duplicate-case": ["error"],
|
||||
"no-duplicate-imports": [
|
||||
"error",
|
||||
{
|
||||
"includeExports": true
|
||||
}
|
||||
],
|
||||
"no-else-return": ["error"],
|
||||
"no-empty": [
|
||||
"error",
|
||||
{
|
||||
"allowEmptyCatch": false
|
||||
}
|
||||
],
|
||||
"no-empty-character-class": ["error"],
|
||||
"no-empty-function": ["error"],
|
||||
"no-empty-pattern": ["error"],
|
||||
"no-eq-null": ["error"],
|
||||
"no-eval": ["error"],
|
||||
"no-ex-assign": ["error"],
|
||||
"no-extend-native": ["error"],
|
||||
"no-extra-bind": ["error"],
|
||||
"no-extra-boolean-cast": ["error"],
|
||||
"no-extra-label": ["error"],
|
||||
"no-extra-parens": [
|
||||
"error",
|
||||
"all",
|
||||
{
|
||||
"conditionalAssign": false
|
||||
}
|
||||
],
|
||||
"no-extra-semi": ["error"],
|
||||
"no-fallthrough": ["error"],
|
||||
"no-floating-decimal": ["error"],
|
||||
"no-func-assign": ["error"],
|
||||
"no-global-assign": ["error"],
|
||||
"no-implicit-coercion": ["error"],
|
||||
"no-implicit-globals": ["error"],
|
||||
"no-implied-eval": ["error"],
|
||||
"no-inline-comments": ["error"],
|
||||
"no-inner-declarations": [
|
||||
"error",
|
||||
"both"
|
||||
],
|
||||
"no-invalid-regexp": ["error"],
|
||||
"no-invalid-this": ["error"],
|
||||
"no-irregular-whitespace": [
|
||||
"error",
|
||||
{
|
||||
"skipComments": false,
|
||||
"skipRegExps": false,
|
||||
"skipStrings": false,
|
||||
"skipTemplates": false
|
||||
}
|
||||
],
|
||||
"no-iterator": ["error"],
|
||||
"no-label-var": ["error"],
|
||||
"no-labels": ["error"],
|
||||
"no-lone-blocks": ["error"],
|
||||
"no-lonely-if": ["error"],
|
||||
"no-loop-func": ["error"],
|
||||
"no-magic-numbers": [
|
||||
"error",
|
||||
{
|
||||
"ignore": [
|
||||
-1,
|
||||
0,
|
||||
1
|
||||
],
|
||||
"ignoreArrayIndexes": true
|
||||
}
|
||||
],
|
||||
"no-mixed-operators": ["error"],
|
||||
"no-mixed-requires": ["error"],
|
||||
"no-mixed-spaces-and-tabs": ["error"],
|
||||
"no-multi-assign": ["error"],
|
||||
"no-multi-spaces": ["error"],
|
||||
"no-multi-str": ["error"],
|
||||
"no-multiple-empty-lines": [
|
||||
"error",
|
||||
{
|
||||
"max": 1
|
||||
}
|
||||
],
|
||||
"no-native-reassign": ["error"],
|
||||
"no-negated-condition": ["error"],
|
||||
"no-negated-in-lhs": ["error"],
|
||||
"no-nested-ternary": ["error"],
|
||||
"no-new": ["error"],
|
||||
"no-new-func": ["error"],
|
||||
"no-new-object": ["error"],
|
||||
"no-new-require": ["error"],
|
||||
"no-new-symbol": ["error"],
|
||||
"no-new-wrappers": ["error"],
|
||||
"no-obj-calls": ["error"],
|
||||
"no-octal": ["error"],
|
||||
"no-octal-escape": ["error"],
|
||||
"no-param-reassign": ["error"],
|
||||
"no-path-concat": ["error"],
|
||||
"no-plusplus": [
|
||||
"error",
|
||||
{
|
||||
"allowForLoopAfterthoughts": true
|
||||
}
|
||||
],
|
||||
"no-process-env": ["error"],
|
||||
"no-process-exit": ["error"],
|
||||
"no-proto": ["error"],
|
||||
"no-prototype-builtins": ["error"],
|
||||
"no-redeclare": ["error"],
|
||||
"no-regex-spaces": ["error"],
|
||||
"no-restricted-globals": ["error"],
|
||||
"no-restricted-imports": ["error"],
|
||||
"no-restricted-modules": ["error"],
|
||||
"no-restricted-properties": [
|
||||
"error",
|
||||
{
|
||||
"message": "'log' is too general, use an appropriate level when logging.",
|
||||
"object": "console",
|
||||
"property": "log"
|
||||
}
|
||||
],
|
||||
"no-restricted-syntax": ["error"],
|
||||
"no-return-assign": ["error"],
|
||||
"no-return-await": ["error"],
|
||||
"no-script-url": ["error"],
|
||||
"no-self-assign": [
|
||||
"error",
|
||||
{
|
||||
"props": false
|
||||
}
|
||||
],
|
||||
"no-self-compare": ["error"],
|
||||
"no-sequences": ["error"],
|
||||
"no-shadow": ["error"],
|
||||
"no-shadow-restricted-names": ["error"],
|
||||
"no-spaced-func": ["error"],
|
||||
"no-sparse-arrays": ["error"],
|
||||
"no-sync": ["error"],
|
||||
"no-tabs": ["error"],
|
||||
"no-template-curly-in-string": ["error"],
|
||||
"no-ternary": ["off"],
|
||||
"no-this-before-super": ["error"],
|
||||
"no-throw-literal": ["error"],
|
||||
"no-trailing-spaces": ["error"],
|
||||
"no-undef": ["error"],
|
||||
"no-undef-init": ["error"],
|
||||
"no-undefined": ["error"],
|
||||
"no-underscore-dangle": ["error"],
|
||||
"no-unexpected-multiline": ["error"],
|
||||
"no-unmodified-loop-condition": ["error"],
|
||||
"no-unneeded-ternary": ["error"],
|
||||
"no-unreachable": ["error"],
|
||||
"no-unsafe-finally": ["error"],
|
||||
"no-unsafe-negation": ["error"],
|
||||
"no-unused-expressions": ["error"],
|
||||
"no-unused-labels": ["error"],
|
||||
"no-unused-vars": ["error"],
|
||||
"no-use-before-define": ["error"],
|
||||
"no-useless-call": ["error"],
|
||||
"no-useless-computed-key": ["error"],
|
||||
"no-useless-concat": ["error"],
|
||||
"no-useless-constructor": ["error"],
|
||||
"no-useless-escape": ["error"],
|
||||
"no-useless-rename": [
|
||||
"error",
|
||||
{
|
||||
"ignoreDestructuring": false,
|
||||
"ignoreExport": false,
|
||||
"ignoreImport": false
|
||||
}
|
||||
],
|
||||
"no-useless-return": ["error"],
|
||||
"no-var": ["error"],
|
||||
"no-void": ["error"],
|
||||
"no-warning-comments": ["error"],
|
||||
"no-whitespace-before-property": ["error"],
|
||||
"no-with": ["error"],
|
||||
"nonblock-statement-body-position": [
|
||||
"error",
|
||||
"below"
|
||||
],
|
||||
"object-curly-newline": ["error"],
|
||||
"object-curly-spacing": ["error"],
|
||||
"object-property-newline": ["error"],
|
||||
"object-shorthand": ["error"],
|
||||
"one-var": ["off"],
|
||||
"one-var-declaration-per-line": ["error"],
|
||||
"operator-assignment": ["error"],
|
||||
"operator-linebreak": [
|
||||
"error",
|
||||
"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"
|
||||
]
|
||||
}
|
||||
ecmaVersion: 8,
|
||||
sourceType: "module",
|
||||
},
|
||||
rules: {
|
||||
"accessor-pairs": [
|
||||
"error",
|
||||
{
|
||||
getWithoutSet: false,
|
||||
setWithoutGet: true,
|
||||
},
|
||||
],
|
||||
"array-bracket-newline": ["error"],
|
||||
"array-bracket-spacing": ["error"],
|
||||
"array-callback-return": ["error"],
|
||||
"array-element-newline": ["error"],
|
||||
"arrow-body-style": ["error"],
|
||||
"arrow-parens": ["error"],
|
||||
"arrow-spacing": ["error"],
|
||||
"block-scoped-var": ["error"],
|
||||
"block-spacing": ["error"],
|
||||
"brace-style": ["error"],
|
||||
"callback-return": ["error"],
|
||||
camelcase: ["error"],
|
||||
"capitalized-comments": ["error"],
|
||||
"class-methods-use-this": ["error"],
|
||||
"comma-dangle": ["error"],
|
||||
"comma-spacing": ["error"],
|
||||
"comma-style": ["error", "last"],
|
||||
complexity: ["error"],
|
||||
"computed-property-spacing": ["error", "never"],
|
||||
"consistent-return": ["error"],
|
||||
"consistent-this": ["error"],
|
||||
"constructor-super": ["error"],
|
||||
curly: ["error"],
|
||||
"default-case": ["error"],
|
||||
"dot-location": ["error", "property"],
|
||||
"dot-notation": ["error"],
|
||||
"eol-last": ["error"],
|
||||
eqeqeq: ["error"],
|
||||
"for-direction": ["error"],
|
||||
"func-call-spacing": ["error"],
|
||||
"func-name-matching": ["error"],
|
||||
"func-names": ["error", "never"],
|
||||
"func-style": ["error"],
|
||||
"function-paren-newline": ["error"],
|
||||
"generator-star-spacing": ["error", "before"],
|
||||
"getter-return": [
|
||||
"error",
|
||||
{
|
||||
allowImplicit: false,
|
||||
},
|
||||
],
|
||||
"global-require": ["error"],
|
||||
"guard-for-in": ["error"],
|
||||
"handle-callback-err": ["error"],
|
||||
"id-blacklist": ["error"],
|
||||
"id-length": ["error"],
|
||||
"id-match": ["error"],
|
||||
"implicit-arrow-linebreak": ["error", "beside"],
|
||||
indent: [
|
||||
"error",
|
||||
numSpaces,
|
||||
{
|
||||
SwitchCase: 1,
|
||||
},
|
||||
],
|
||||
"init-declarations": ["error"],
|
||||
"jsx-quotes": ["error"],
|
||||
"key-spacing": ["error"],
|
||||
"keyword-spacing": ["error"],
|
||||
"line-comment-position": ["error"],
|
||||
"linebreak-style": ["error", "windows"],
|
||||
"lines-around-comment": ["error"],
|
||||
"lines-between-class-members": ["error"],
|
||||
"max-depth": ["error"],
|
||||
"max-len": ["error", maxLineLength],
|
||||
"max-lines": [
|
||||
"error",
|
||||
{
|
||||
skipBlankLines: true,
|
||||
skipComments: true,
|
||||
},
|
||||
],
|
||||
"max-nested-callbacks": ["error"],
|
||||
"max-params": ["error"],
|
||||
"max-statements": ["error"],
|
||||
"max-statements-per-line": ["error"],
|
||||
"multiline-comment-style": ["off", "starred-block"],
|
||||
"multiline-ternary": ["error", "never"],
|
||||
"new-cap": ["error"],
|
||||
"new-parens": ["error"],
|
||||
// TODO: configure this...
|
||||
"newline-before-return": ["error"],
|
||||
"newline-per-chained-call": ["error"],
|
||||
"no-alert": ["error"],
|
||||
"no-array-constructor": ["error"],
|
||||
"no-await-in-loop": ["error"],
|
||||
"no-bitwise": ["error"],
|
||||
"no-buffer-constructor": ["error"],
|
||||
"no-caller": ["error"],
|
||||
"no-case-declarations": ["error"],
|
||||
"no-catch-shadow": ["error"],
|
||||
"no-class-assign": ["error"],
|
||||
"no-compare-neg-zero": ["error"],
|
||||
"no-cond-assign": ["error", "except-parens"],
|
||||
"no-confusing-arrow": ["error"],
|
||||
"no-console": ["error"],
|
||||
"no-const-assign": ["error"],
|
||||
"no-constant-condition": [
|
||||
"error",
|
||||
{
|
||||
checkLoops: false,
|
||||
},
|
||||
],
|
||||
"no-continue": ["off"],
|
||||
"no-control-regex": ["error"],
|
||||
"no-debugger": ["error"],
|
||||
"no-delete-var": ["error"],
|
||||
"no-div-regex": ["error"],
|
||||
"no-dupe-args": ["error"],
|
||||
"no-dupe-class-members": ["error"],
|
||||
"no-dupe-keys": ["error"],
|
||||
"no-duplicate-case": ["error"],
|
||||
"no-duplicate-imports": [
|
||||
"error",
|
||||
{
|
||||
includeExports: true,
|
||||
},
|
||||
],
|
||||
"no-else-return": ["error"],
|
||||
"no-empty": [
|
||||
"error",
|
||||
{
|
||||
allowEmptyCatch: false,
|
||||
},
|
||||
],
|
||||
"no-empty-character-class": ["error"],
|
||||
"no-empty-function": ["error"],
|
||||
"no-empty-pattern": ["error"],
|
||||
"no-eq-null": ["error"],
|
||||
"no-eval": ["error"],
|
||||
"no-ex-assign": ["error"],
|
||||
"no-extend-native": ["error"],
|
||||
"no-extra-bind": ["error"],
|
||||
"no-extra-boolean-cast": ["error"],
|
||||
"no-extra-label": ["error"],
|
||||
"no-extra-parens": [
|
||||
"error",
|
||||
"all",
|
||||
{
|
||||
conditionalAssign: false,
|
||||
},
|
||||
],
|
||||
"no-extra-semi": ["error"],
|
||||
"no-fallthrough": ["error"],
|
||||
"no-floating-decimal": ["error"],
|
||||
"no-func-assign": ["error"],
|
||||
"no-global-assign": ["error"],
|
||||
"no-implicit-coercion": ["error"],
|
||||
"no-implicit-globals": ["error"],
|
||||
"no-implied-eval": ["error"],
|
||||
"no-inline-comments": ["error"],
|
||||
"no-inner-declarations": ["error", "both"],
|
||||
"no-invalid-regexp": ["error"],
|
||||
"no-invalid-this": ["error"],
|
||||
"no-irregular-whitespace": [
|
||||
"error",
|
||||
{
|
||||
skipComments: false,
|
||||
skipRegExps: false,
|
||||
skipStrings: false,
|
||||
skipTemplates: false,
|
||||
},
|
||||
],
|
||||
"no-iterator": ["error"],
|
||||
"no-label-var": ["error"],
|
||||
"no-labels": ["error"],
|
||||
"no-lone-blocks": ["error"],
|
||||
"no-lonely-if": ["error"],
|
||||
"no-loop-func": ["error"],
|
||||
"no-magic-numbers": [
|
||||
"error",
|
||||
{
|
||||
ignore: [-1, 0, 1],
|
||||
ignoreArrayIndexes: true,
|
||||
},
|
||||
],
|
||||
"no-mixed-operators": ["error"],
|
||||
"no-mixed-requires": ["error"],
|
||||
"no-mixed-spaces-and-tabs": ["error"],
|
||||
"no-multi-assign": ["error"],
|
||||
"no-multi-spaces": ["error"],
|
||||
"no-multi-str": ["error"],
|
||||
"no-multiple-empty-lines": [
|
||||
"error",
|
||||
{
|
||||
max: 1,
|
||||
},
|
||||
],
|
||||
"no-native-reassign": ["error"],
|
||||
"no-negated-condition": ["error"],
|
||||
"no-negated-in-lhs": ["error"],
|
||||
"no-nested-ternary": ["error"],
|
||||
"no-new": ["error"],
|
||||
"no-new-func": ["error"],
|
||||
"no-new-object": ["error"],
|
||||
"no-new-require": ["error"],
|
||||
"no-new-symbol": ["error"],
|
||||
"no-new-wrappers": ["error"],
|
||||
"no-obj-calls": ["error"],
|
||||
"no-octal": ["error"],
|
||||
"no-octal-escape": ["error"],
|
||||
"no-param-reassign": ["error"],
|
||||
"no-path-concat": ["error"],
|
||||
"no-plusplus": [
|
||||
"error",
|
||||
{
|
||||
allowForLoopAfterthoughts: true,
|
||||
},
|
||||
],
|
||||
"no-process-env": ["error"],
|
||||
"no-process-exit": ["error"],
|
||||
"no-proto": ["error"],
|
||||
"no-prototype-builtins": ["error"],
|
||||
"no-redeclare": ["error"],
|
||||
"no-regex-spaces": ["error"],
|
||||
"no-restricted-globals": ["error"],
|
||||
"no-restricted-imports": ["error"],
|
||||
"no-restricted-modules": ["error"],
|
||||
"no-restricted-properties": [
|
||||
"error",
|
||||
{
|
||||
message: "'log' is too general, use an appropriate level when logging.",
|
||||
object: "console",
|
||||
property: "log",
|
||||
},
|
||||
],
|
||||
"no-restricted-syntax": ["error"],
|
||||
"no-return-assign": ["error"],
|
||||
"no-return-await": ["error"],
|
||||
"no-script-url": ["error"],
|
||||
"no-self-assign": [
|
||||
"error",
|
||||
{
|
||||
props: false,
|
||||
},
|
||||
],
|
||||
"no-self-compare": ["error"],
|
||||
"no-sequences": ["error"],
|
||||
"no-shadow": ["error"],
|
||||
"no-shadow-restricted-names": ["error"],
|
||||
"no-spaced-func": ["error"],
|
||||
"no-sparse-arrays": ["error"],
|
||||
"no-sync": ["error"],
|
||||
"no-tabs": ["error"],
|
||||
"no-template-curly-in-string": ["error"],
|
||||
"no-ternary": ["off"],
|
||||
"no-this-before-super": ["error"],
|
||||
"no-throw-literal": ["error"],
|
||||
"no-trailing-spaces": ["error"],
|
||||
"no-undef": ["error"],
|
||||
"no-undef-init": ["error"],
|
||||
"no-undefined": ["error"],
|
||||
"no-underscore-dangle": ["error"],
|
||||
"no-unexpected-multiline": ["error"],
|
||||
"no-unmodified-loop-condition": ["error"],
|
||||
"no-unneeded-ternary": ["error"],
|
||||
"no-unreachable": ["error"],
|
||||
"no-unsafe-finally": ["error"],
|
||||
"no-unsafe-negation": ["error"],
|
||||
"no-unused-expressions": ["error"],
|
||||
"no-unused-labels": ["error"],
|
||||
"no-unused-vars": ["error"],
|
||||
"no-use-before-define": ["error"],
|
||||
"no-useless-call": ["error"],
|
||||
"no-useless-computed-key": ["error"],
|
||||
"no-useless-concat": ["error"],
|
||||
"no-useless-constructor": ["error"],
|
||||
"no-useless-escape": ["error"],
|
||||
"no-useless-rename": [
|
||||
"error",
|
||||
{
|
||||
ignoreDestructuring: false,
|
||||
ignoreExport: false,
|
||||
ignoreImport: false,
|
||||
},
|
||||
],
|
||||
"no-useless-return": ["error"],
|
||||
"no-var": ["error"],
|
||||
"no-void": ["error"],
|
||||
"no-warning-comments": ["error"],
|
||||
"no-whitespace-before-property": ["error"],
|
||||
"no-with": ["error"],
|
||||
"nonblock-statement-body-position": ["error", "below"],
|
||||
"object-curly-newline": ["error"],
|
||||
"object-curly-spacing": ["error"],
|
||||
"object-property-newline": ["error"],
|
||||
"object-shorthand": ["error"],
|
||||
"one-var": ["off"],
|
||||
"one-var-declaration-per-line": ["error"],
|
||||
"operator-assignment": ["error"],
|
||||
"operator-linebreak": ["error", "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"],
|
||||
},
|
||||
};
|
||||
|
@ -8,66 +8,74 @@ const path = require("path");
|
||||
const exec = require("child_process").exec;
|
||||
const semver = require("./semver");
|
||||
|
||||
const getPackageJson = () => new Promise((resolve, reject) => {
|
||||
const getPackageJson = () =>
|
||||
new Promise((resolve, reject) => {
|
||||
try {
|
||||
/* eslint-disable-next-line global-require */
|
||||
resolve(require(path.resolve(process.cwd(), "package.json")));
|
||||
/* eslint-disable-next-line global-require */
|
||||
resolve(require(path.resolve(process.cwd(), "package.json")));
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
const getEngines = (data) => new Promise((resolve, reject) => {
|
||||
const getEngines = (data) =>
|
||||
new Promise((resolve, reject) => {
|
||||
let versions = null;
|
||||
|
||||
if (data.engines) {
|
||||
versions = data.engines;
|
||||
versions = data.engines;
|
||||
}
|
||||
|
||||
if (versions) {
|
||||
resolve(versions);
|
||||
resolve(versions);
|
||||
} else {
|
||||
reject("Missing or improper 'engines' property in 'package.json'");
|
||||
reject("Missing or improper 'engines' property in 'package.json'");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
const checkNpmVersion = (engines) => new Promise((resolve, reject) => {
|
||||
const checkNpmVersion = (engines) =>
|
||||
new Promise((resolve, reject) => {
|
||||
exec("npm -v", (error, stdout, stderr) => {
|
||||
if (error) {
|
||||
reject(`Unable to find NPM version\n${stderr}`);
|
||||
}
|
||||
if (error) {
|
||||
reject(`Unable to find NPM version\n${stderr}`);
|
||||
}
|
||||
|
||||
const npmVersion = stdout.trim();
|
||||
const engineVersion = engines.npm || ">=0";
|
||||
const npmVersion = stdout.trim();
|
||||
const engineVersion = engines.npm || ">=0";
|
||||
|
||||
if (semver.satisfies(npmVersion, engineVersion)) {
|
||||
resolve();
|
||||
} else {
|
||||
reject(`Incorrect npm version\n'package.json' specifies "${engineVersion}", you are currently running "${npmVersion}".`);
|
||||
}
|
||||
if (semver.satisfies(npmVersion, engineVersion)) {
|
||||
resolve();
|
||||
} else {
|
||||
reject(
|
||||
`Incorrect npm version\n'package.json' specifies "${engineVersion}", you are currently running "${npmVersion}".`,
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
const checkNodeVersion = (engines) => new Promise((resolve, reject) => {
|
||||
const checkNodeVersion = (engines) =>
|
||||
new Promise((resolve, reject) => {
|
||||
const nodeVersion = process.version.substring(1);
|
||||
|
||||
if (semver.satisfies(nodeVersion, engines.node)) {
|
||||
resolve(engines);
|
||||
resolve(engines);
|
||||
} else {
|
||||
reject(`Incorrect node version\n'package.json' specifies "${engines.node}", you are currently running "${process.version}".`);
|
||||
reject(
|
||||
`Incorrect node version\n'package.json' specifies "${engines.node}", you are currently running "${process.version}".`,
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
getPackageJson()
|
||||
.then(getEngines)
|
||||
.then(checkNodeVersion)
|
||||
.then(checkNpmVersion)
|
||||
.then(
|
||||
() => true,
|
||||
(error) => {
|
||||
// Specifically disable these as the error message gets lost in the normal unhandled output.
|
||||
/* eslint-disable no-console, no-process-exit */
|
||||
console.error(error);
|
||||
process.exit(1);
|
||||
}
|
||||
);
|
||||
.then(getEngines)
|
||||
.then(checkNodeVersion)
|
||||
.then(checkNpmVersion)
|
||||
.then(
|
||||
() => true,
|
||||
(error) => {
|
||||
// Specifically disable these as the error message gets lost in the normal unhandled output.
|
||||
/* eslint-disable no-console, no-process-exit */
|
||||
console.error(error);
|
||||
process.exit(1);
|
||||
},
|
||||
);
|
||||
|
1028
scripts/semver.js
1028
scripts/semver.js
File diff suppressed because it is too large
Load Diff
@ -8,11 +8,7 @@ import { Factions } from "../Faction/Factions";
|
||||
import { numeralWrapper } from "../ui/numeralFormat";
|
||||
import { Money } from "../ui/React/Money";
|
||||
|
||||
import {
|
||||
Generic_fromJSON,
|
||||
Generic_toJSON,
|
||||
Reviver,
|
||||
} from "../../utils/JSONReviver";
|
||||
import { Generic_fromJSON, Generic_toJSON, Reviver } from "../../utils/JSONReviver";
|
||||
|
||||
interface IConstructorParams {
|
||||
info: string | JSX.Element;
|
||||
@ -58,11 +54,7 @@ interface IConstructorParams {
|
||||
programs?: string[];
|
||||
}
|
||||
|
||||
function generateStatsDescription(
|
||||
mults: IMap<number>,
|
||||
programs?: string[],
|
||||
startingMoney?: number,
|
||||
): JSX.Element {
|
||||
function generateStatsDescription(mults: IMap<number>, programs?: string[], startingMoney?: number): JSX.Element {
|
||||
const f = (x: number, decimals = 0): string => {
|
||||
// look, I don't know how to make a "smart decimals"
|
||||
// todo, make it smarter
|
||||
@ -224,8 +216,7 @@ function generateStatsDescription(
|
||||
desc = (
|
||||
<>
|
||||
{desc}
|
||||
<br />+{f(mults.hacking_speed_mult - 1)} faster hack(), grow(), and
|
||||
weaken()
|
||||
<br />+{f(mults.hacking_speed_mult - 1)} faster hack(), grow(), and weaken()
|
||||
</>
|
||||
);
|
||||
if (mults.hacking_chance_mult)
|
||||
@ -250,15 +241,11 @@ function generateStatsDescription(
|
||||
</>
|
||||
);
|
||||
|
||||
if (
|
||||
mults.faction_rep_mult &&
|
||||
mults.faction_rep_mult === mults.company_rep_mult
|
||||
) {
|
||||
if (mults.faction_rep_mult && mults.faction_rep_mult === mults.company_rep_mult) {
|
||||
desc = (
|
||||
<>
|
||||
{desc}
|
||||
<br />+{f(mults.faction_rep_mult - 1)} reputation from factions and
|
||||
companies
|
||||
<br />+{f(mults.faction_rep_mult - 1)} reputation from factions and companies
|
||||
</>
|
||||
);
|
||||
} else {
|
||||
@ -311,16 +298,14 @@ function generateStatsDescription(
|
||||
desc = (
|
||||
<>
|
||||
{desc}
|
||||
<br />-{f(-(mults.hacknet_node_purchase_cost_mult - 1))} hacknet nodes
|
||||
cost
|
||||
<br />-{f(-(mults.hacknet_node_purchase_cost_mult - 1))} hacknet nodes cost
|
||||
</>
|
||||
);
|
||||
if (mults.hacknet_node_level_cost_mult)
|
||||
desc = (
|
||||
<>
|
||||
{desc}
|
||||
<br />-{f(-(mults.hacknet_node_level_cost_mult - 1))} hacknet nodes
|
||||
upgrade cost
|
||||
<br />-{f(-(mults.hacknet_node_level_cost_mult - 1))} hacknet nodes upgrade cost
|
||||
</>
|
||||
);
|
||||
|
||||
@ -328,32 +313,28 @@ function generateStatsDescription(
|
||||
desc = (
|
||||
<>
|
||||
{desc}
|
||||
<br />+{f(mults.bladeburner_max_stamina_mult - 1)} Bladeburner Max
|
||||
Stamina
|
||||
<br />+{f(mults.bladeburner_max_stamina_mult - 1)} Bladeburner Max Stamina
|
||||
</>
|
||||
);
|
||||
if (mults.bladeburner_stamina_gain_mult)
|
||||
desc = (
|
||||
<>
|
||||
{desc}
|
||||
<br />+{f(mults.bladeburner_stamina_gain_mult - 1)} Bladeburner Stamina
|
||||
gain
|
||||
<br />+{f(mults.bladeburner_stamina_gain_mult - 1)} Bladeburner Stamina gain
|
||||
</>
|
||||
);
|
||||
if (mults.bladeburner_analysis_mult)
|
||||
desc = (
|
||||
<>
|
||||
{desc}
|
||||
<br />+{f(mults.bladeburner_analysis_mult - 1)} Bladeburner Field
|
||||
Analysis effectiveness
|
||||
<br />+{f(mults.bladeburner_analysis_mult - 1)} Bladeburner Field Analysis effectiveness
|
||||
</>
|
||||
);
|
||||
if (mults.bladeburner_success_chance_mult)
|
||||
desc = (
|
||||
<>
|
||||
{desc}
|
||||
<br />+{f(mults.bladeburner_success_chance_mult - 1)} Bladeburner
|
||||
Contracts and Operations success chance
|
||||
<br />+{f(mults.bladeburner_success_chance_mult - 1)} Bladeburner Contracts and Operations success chance
|
||||
</>
|
||||
);
|
||||
|
||||
@ -362,8 +343,7 @@ function generateStatsDescription(
|
||||
<>
|
||||
{desc}
|
||||
<br />
|
||||
Start with <Money money={startingMoney} /> after installing
|
||||
Augmentations.
|
||||
Start with <Money money={startingMoney} /> after installing Augmentations.
|
||||
</>
|
||||
);
|
||||
|
||||
@ -425,8 +405,7 @@ export class Augmentation {
|
||||
this.info = params.info;
|
||||
this.prereqs = params.prereqs ? params.prereqs : [];
|
||||
|
||||
this.baseRepRequirement =
|
||||
params.repCost * BitNodeMultipliers.AugmentationRepCost;
|
||||
this.baseRepRequirement = params.repCost * BitNodeMultipliers.AugmentationRepCost;
|
||||
this.baseCost = params.moneyCost * BitNodeMultipliers.AugmentationMoneyCost;
|
||||
this.startingCost = this.baseCost;
|
||||
|
||||
@ -504,43 +483,32 @@ export class Augmentation {
|
||||
this.mults.hacknet_node_money_mult = params.hacknet_node_money_mult;
|
||||
}
|
||||
if (params.hacknet_node_purchase_cost_mult) {
|
||||
this.mults.hacknet_node_purchase_cost_mult =
|
||||
params.hacknet_node_purchase_cost_mult;
|
||||
this.mults.hacknet_node_purchase_cost_mult = params.hacknet_node_purchase_cost_mult;
|
||||
}
|
||||
if (params.hacknet_node_ram_cost_mult) {
|
||||
this.mults.hacknet_node_ram_cost_mult = params.hacknet_node_ram_cost_mult;
|
||||
}
|
||||
if (params.hacknet_node_core_cost_mult) {
|
||||
this.mults.hacknet_node_core_cost_mult =
|
||||
params.hacknet_node_core_cost_mult;
|
||||
this.mults.hacknet_node_core_cost_mult = params.hacknet_node_core_cost_mult;
|
||||
}
|
||||
if (params.hacknet_node_level_cost_mult) {
|
||||
this.mults.hacknet_node_level_cost_mult =
|
||||
params.hacknet_node_level_cost_mult;
|
||||
this.mults.hacknet_node_level_cost_mult = params.hacknet_node_level_cost_mult;
|
||||
}
|
||||
if (params.bladeburner_max_stamina_mult) {
|
||||
this.mults.bladeburner_max_stamina_mult =
|
||||
params.bladeburner_max_stamina_mult;
|
||||
this.mults.bladeburner_max_stamina_mult = params.bladeburner_max_stamina_mult;
|
||||
}
|
||||
if (params.bladeburner_stamina_gain_mult) {
|
||||
this.mults.bladeburner_stamina_gain_mult =
|
||||
params.bladeburner_stamina_gain_mult;
|
||||
this.mults.bladeburner_stamina_gain_mult = params.bladeburner_stamina_gain_mult;
|
||||
}
|
||||
if (params.bladeburner_analysis_mult) {
|
||||
this.mults.bladeburner_analysis_mult = params.bladeburner_analysis_mult;
|
||||
}
|
||||
if (params.bladeburner_success_chance_mult) {
|
||||
this.mults.bladeburner_success_chance_mult =
|
||||
params.bladeburner_success_chance_mult;
|
||||
this.mults.bladeburner_success_chance_mult = params.bladeburner_success_chance_mult;
|
||||
}
|
||||
|
||||
if (params.stats) this.stats = params.stats;
|
||||
else
|
||||
this.stats = generateStatsDescription(
|
||||
this.mults,
|
||||
params.programs,
|
||||
params.startingMoney,
|
||||
);
|
||||
else this.stats = generateStatsDescription(this.mults, params.programs, params.startingMoney);
|
||||
}
|
||||
|
||||
// Adds this Augmentation to the specified Factions
|
||||
@ -548,9 +516,7 @@ export class Augmentation {
|
||||
for (let i = 0; i < factionList.length; ++i) {
|
||||
const faction: Faction | null = Factions[factionList[i]];
|
||||
if (faction == null) {
|
||||
console.warn(
|
||||
`In Augmentation.addToFactions(), could not find faction with this name: ${factionList[i]}`,
|
||||
);
|
||||
console.warn(`In Augmentation.addToFactions(), could not find faction with this name: ${factionList[i]}`);
|
||||
continue;
|
||||
}
|
||||
faction.augmentations.push(this.name);
|
||||
@ -563,9 +529,7 @@ export class Augmentation {
|
||||
if (Factions.hasOwnProperty(fac)) {
|
||||
const facObj: Faction | null = Factions[fac];
|
||||
if (facObj == null) {
|
||||
console.warn(
|
||||
`Invalid Faction object in addToAllFactions(). Key value: ${fac}`,
|
||||
);
|
||||
console.warn(`Invalid Faction object in addToAllFactions(). Key value: ${fac}`);
|
||||
continue;
|
||||
}
|
||||
facObj.augmentations.push(this.name);
|
||||
|
@ -141,9 +141,7 @@ function initAugmentations() {
|
||||
Object.keys(randomBonuses.bonuses).forEach(
|
||||
(key) => (UnstableCircadianModulatorParams[key] = randomBonuses.bonuses[key]),
|
||||
);
|
||||
const UnstableCircadianModulator = new Augmentation(
|
||||
UnstableCircadianModulatorParams,
|
||||
);
|
||||
const UnstableCircadianModulator = new Augmentation(UnstableCircadianModulatorParams);
|
||||
|
||||
UnstableCircadianModulator.addToFactions(["Speakers for the Dead"]);
|
||||
if (augmentationExists(AugmentationNames.UnstableCircadianModulator)) {
|
||||
@ -156,9 +154,7 @@ function initAugmentations() {
|
||||
name: AugmentationNames.HemoRecirculator,
|
||||
moneyCost: 4.5e7,
|
||||
repCost: 1e4,
|
||||
info:
|
||||
"A heart implant that greatly increases the body's ability to effectively use and pump " +
|
||||
"blood.",
|
||||
info: "A heart implant that greatly increases the body's ability to effectively use and pump " + "blood.",
|
||||
strength_mult: 1.08,
|
||||
defense_mult: 1.08,
|
||||
agility_mult: 1.08,
|
||||
@ -221,9 +217,7 @@ function initAugmentations() {
|
||||
name: AugmentationNames.Targeting3,
|
||||
moneyCost: 1.15e8,
|
||||
repCost: 2.75e4,
|
||||
info:
|
||||
"The latest version of the 'Augmented Targeting' implant adds the ability to " +
|
||||
"lock-on and track threats.",
|
||||
info: "The latest version of the 'Augmented Targeting' implant adds the ability to " + "lock-on and track threats.",
|
||||
prereqs: [AugmentationNames.Targeting2],
|
||||
dexterity_mult: 1.3,
|
||||
});
|
||||
@ -442,15 +436,11 @@ function initAugmentations() {
|
||||
repCost: 1.125e6,
|
||||
moneyCost: 4.25e9,
|
||||
info:
|
||||
"Graphene is grafted and fused into the skeletal structure, " +
|
||||
"enhancing bone density and tensile strength.",
|
||||
"Graphene is grafted and fused into the skeletal structure, " + "enhancing bone density and tensile strength.",
|
||||
strength_mult: 1.7,
|
||||
defense_mult: 1.7,
|
||||
});
|
||||
GrapheneBoneLacings.addToFactions([
|
||||
"Fulcrum Secret Technologies",
|
||||
"The Covenant",
|
||||
]);
|
||||
GrapheneBoneLacings.addToFactions(["Fulcrum Secret Technologies", "The Covenant"]);
|
||||
if (augmentationExists(AugmentationNames.GrapheneBoneLacings)) {
|
||||
delete Augmentations[AugmentationNames.GrapheneBoneLacings];
|
||||
}
|
||||
@ -530,11 +520,7 @@ function initAugmentations() {
|
||||
prereqs: [AugmentationNames.BionicLegs],
|
||||
agility_mult: 2.5,
|
||||
});
|
||||
GrapheneBionicLegs.addToFactions([
|
||||
"MegaCorp",
|
||||
"ECorp",
|
||||
"Fulcrum Secret Technologies",
|
||||
]);
|
||||
GrapheneBionicLegs.addToFactions(["MegaCorp", "ECorp", "Fulcrum Secret Technologies"]);
|
||||
if (augmentationExists(AugmentationNames.GrapheneBionicLegs)) {
|
||||
delete Augmentations[AugmentationNames.GrapheneBionicLegs];
|
||||
}
|
||||
@ -638,10 +624,7 @@ function initAugmentations() {
|
||||
hacking_money_mult: 1.15,
|
||||
hacking_mult: 1.12,
|
||||
});
|
||||
ArtificialBioNeuralNetwork.addToFactions([
|
||||
"BitRunners",
|
||||
"Fulcrum Secret Technologies",
|
||||
]);
|
||||
ArtificialBioNeuralNetwork.addToFactions(["BitRunners", "Fulcrum Secret Technologies"]);
|
||||
if (augmentationExists(AugmentationNames.ArtificialBioNeuralNetwork)) {
|
||||
delete Augmentations[AugmentationNames.ArtificialBioNeuralNetwork];
|
||||
}
|
||||
@ -677,11 +660,7 @@ function initAugmentations() {
|
||||
hacking_exp_mult: 1.1,
|
||||
hacking_mult: 1.08,
|
||||
});
|
||||
EnhancedMyelinSheathing.addToFactions([
|
||||
"Fulcrum Secret Technologies",
|
||||
"BitRunners",
|
||||
"The Black Hand",
|
||||
]);
|
||||
EnhancedMyelinSheathing.addToFactions(["Fulcrum Secret Technologies", "BitRunners", "The Black Hand"]);
|
||||
if (augmentationExists(AugmentationNames.EnhancedMyelinSheathing)) {
|
||||
delete Augmentations[AugmentationNames.EnhancedMyelinSheathing];
|
||||
}
|
||||
@ -727,13 +706,7 @@ function initAugmentations() {
|
||||
"and delete it.",
|
||||
hacking_money_mult: 1.25,
|
||||
});
|
||||
DataJack.addToFactions([
|
||||
"BitRunners",
|
||||
"The Black Hand",
|
||||
"NiteSec",
|
||||
"Chongqing",
|
||||
"New Tokyo",
|
||||
]);
|
||||
DataJack.addToFactions(["BitRunners", "The Black Hand", "NiteSec", "Chongqing", "New Tokyo"]);
|
||||
if (augmentationExists(AugmentationNames.DataJack)) {
|
||||
delete Augmentations[AugmentationNames.DataJack];
|
||||
}
|
||||
@ -1001,11 +974,7 @@ function initAugmentations() {
|
||||
hacking_money_mult: 1.15,
|
||||
hacking_mult: 1.09,
|
||||
});
|
||||
CranialSignalProcessorsG3.addToFactions([
|
||||
"NiteSec",
|
||||
"The Black Hand",
|
||||
"BitRunners",
|
||||
]);
|
||||
CranialSignalProcessorsG3.addToFactions(["NiteSec", "The Black Hand", "BitRunners"]);
|
||||
if (augmentationExists(AugmentationNames.CranialSignalProcessorsG3)) {
|
||||
delete Augmentations[AugmentationNames.CranialSignalProcessorsG3];
|
||||
}
|
||||
@ -1122,9 +1091,7 @@ function initAugmentations() {
|
||||
name: AugmentationNames.FocusWire,
|
||||
repCost: 7.5e4,
|
||||
moneyCost: 9e8,
|
||||
info:
|
||||
"A cranial implant that stops procrastination by blocking specific neural pathways " +
|
||||
"in the brain.",
|
||||
info: "A cranial implant that stops procrastination by blocking specific neural pathways " + "in the brain.",
|
||||
hacking_exp_mult: 1.05,
|
||||
strength_exp_mult: 1.05,
|
||||
defense_exp_mult: 1.05,
|
||||
@ -1134,12 +1101,7 @@ function initAugmentations() {
|
||||
company_rep_mult: 1.1,
|
||||
work_money_mult: 1.2,
|
||||
});
|
||||
FocusWire.addToFactions([
|
||||
"Bachman & Associates",
|
||||
"Clarke Incorporated",
|
||||
"Four Sigma",
|
||||
"KuaiGong International",
|
||||
]);
|
||||
FocusWire.addToFactions(["Bachman & Associates", "Clarke Incorporated", "Four Sigma", "KuaiGong International"]);
|
||||
if (augmentationExists(AugmentationNames.FocusWire)) {
|
||||
delete Augmentations[AugmentationNames.FocusWire];
|
||||
}
|
||||
@ -1156,12 +1118,7 @@ function initAugmentations() {
|
||||
company_rep_mult: 1.3,
|
||||
hacking_mult: 1.08,
|
||||
});
|
||||
PCDNI.addToFactions([
|
||||
"Four Sigma",
|
||||
"OmniTek Incorporated",
|
||||
"ECorp",
|
||||
"Blade Industries",
|
||||
]);
|
||||
PCDNI.addToFactions(["Four Sigma", "OmniTek Incorporated", "ECorp", "Blade Industries"]);
|
||||
if (augmentationExists(AugmentationNames.PCDNI)) {
|
||||
delete Augmentations[AugmentationNames.PCDNI];
|
||||
}
|
||||
@ -1179,11 +1136,7 @@ function initAugmentations() {
|
||||
company_rep_mult: 1.75,
|
||||
hacking_mult: 1.1,
|
||||
});
|
||||
PCDNIOptimizer.addToFactions([
|
||||
"Fulcrum Secret Technologies",
|
||||
"ECorp",
|
||||
"Blade Industries",
|
||||
]);
|
||||
PCDNIOptimizer.addToFactions(["Fulcrum Secret Technologies", "ECorp", "Blade Industries"]);
|
||||
if (augmentationExists(AugmentationNames.PCDNIOptimizer)) {
|
||||
delete Augmentations[AugmentationNames.PCDNIOptimizer];
|
||||
}
|
||||
@ -1220,13 +1173,7 @@ function initAugmentations() {
|
||||
company_rep_mult: 1.1,
|
||||
faction_rep_mult: 1.1,
|
||||
});
|
||||
ADRPheromone1.addToFactions([
|
||||
"Tian Di Hui",
|
||||
"The Syndicate",
|
||||
"NWO",
|
||||
"MegaCorp",
|
||||
"Four Sigma",
|
||||
]);
|
||||
ADRPheromone1.addToFactions(["Tian Di Hui", "The Syndicate", "NWO", "MegaCorp", "Four Sigma"]);
|
||||
if (augmentationExists(AugmentationNames.ADRPheromone1)) {
|
||||
delete Augmentations[AugmentationNames.ADRPheromone1];
|
||||
}
|
||||
@ -1243,12 +1190,7 @@ function initAugmentations() {
|
||||
company_rep_mult: 1.2,
|
||||
faction_rep_mult: 1.2,
|
||||
});
|
||||
ADRPheromone2.addToFactions([
|
||||
"Silhouette",
|
||||
"Four Sigma",
|
||||
"Bachman & Associates",
|
||||
"Clarke Incorporated",
|
||||
]);
|
||||
ADRPheromone2.addToFactions(["Silhouette", "Four Sigma", "Bachman & Associates", "Clarke Incorporated"]);
|
||||
if (augmentationExists(AugmentationNames.ADRPheromone2)) {
|
||||
delete Augmentations[AugmentationNames.ADRPheromone2];
|
||||
}
|
||||
@ -1267,11 +1209,7 @@ function initAugmentations() {
|
||||
company_rep_mult: 1.15,
|
||||
faction_rep_mult: 1.15,
|
||||
});
|
||||
ShadowsSimulacrum.addToFactions([
|
||||
"The Syndicate",
|
||||
"The Dark Army",
|
||||
"Speakers for the Dead",
|
||||
]);
|
||||
ShadowsSimulacrum.addToFactions(["The Syndicate", "The Dark Army", "Speakers for the Dead"]);
|
||||
if (augmentationExists(AugmentationNames.ShadowsSimulacrum)) {
|
||||
delete Augmentations[AugmentationNames.ShadowsSimulacrum];
|
||||
}
|
||||
@ -1373,9 +1311,8 @@ function initAugmentations() {
|
||||
"body's nervous system.",
|
||||
stats: (
|
||||
<>
|
||||
This special augmentation can be leveled up infinitely. Each level of
|
||||
this augmentation increases ALL multipliers by 1%, stacking
|
||||
multiplicatively.
|
||||
This special augmentation can be leveled up infinitely. Each level of this augmentation increases ALL
|
||||
multipliers by 1%, stacking multiplicatively.
|
||||
</>
|
||||
),
|
||||
hacking_chance_mult: 1.01,
|
||||
@ -1419,17 +1356,13 @@ function initAugmentations() {
|
||||
// levels that are purchased but not yet installed
|
||||
let nextLevel = currLevel;
|
||||
for (let i = 0; i < Player.queuedAugmentations.length; ++i) {
|
||||
if (
|
||||
Player.queuedAugmentations[i].name === AugmentationNames.NeuroFluxGovernor
|
||||
) {
|
||||
if (Player.queuedAugmentations[i].name === AugmentationNames.NeuroFluxGovernor) {
|
||||
++nextLevel;
|
||||
}
|
||||
}
|
||||
let mult = Math.pow(CONSTANTS.NeuroFluxGovernorLevelMult, nextLevel);
|
||||
NeuroFluxGovernor.baseRepRequirement =
|
||||
500 * mult * BitNodeMultipliers.AugmentationRepCost;
|
||||
NeuroFluxGovernor.baseCost =
|
||||
750e3 * mult * BitNodeMultipliers.AugmentationMoneyCost;
|
||||
NeuroFluxGovernor.baseRepRequirement = 500 * mult * BitNodeMultipliers.AugmentationRepCost;
|
||||
NeuroFluxGovernor.baseCost = 750e3 * mult * BitNodeMultipliers.AugmentationMoneyCost;
|
||||
if (augmentationExists(AugmentationNames.NeuroFluxGovernor)) {
|
||||
delete Augmentations[AugmentationNames.NeuroFluxGovernor];
|
||||
}
|
||||
@ -1559,9 +1492,7 @@ function initAugmentations() {
|
||||
name: AugmentationNames.SmartSonar,
|
||||
repCost: 2.25e4,
|
||||
moneyCost: 7.5e7,
|
||||
info:
|
||||
"A cochlear implant that helps the player detect and locate enemies " +
|
||||
"using sound propagation.",
|
||||
info: "A cochlear implant that helps the player detect and locate enemies " + "using sound propagation.",
|
||||
dexterity_mult: 1.1,
|
||||
dexterity_exp_mult: 1.15,
|
||||
crime_money_mult: 1.25,
|
||||
@ -1593,12 +1524,7 @@ function initAugmentations() {
|
||||
agility_exp_mult: 1.1,
|
||||
charisma_exp_mult: 1.1,
|
||||
});
|
||||
PowerRecirculator.addToFactions([
|
||||
"Tetrads",
|
||||
"The Dark Army",
|
||||
"The Syndicate",
|
||||
"NWO",
|
||||
]);
|
||||
PowerRecirculator.addToFactions(["Tetrads", "The Dark Army", "The Syndicate", "NWO"]);
|
||||
if (augmentationExists(AugmentationNames.PowerRecirculator)) {
|
||||
delete Augmentations[AugmentationNames.PowerRecirculator];
|
||||
}
|
||||
@ -1941,9 +1867,8 @@ function initAugmentations() {
|
||||
moneyCost: 1.25e8,
|
||||
info: (
|
||||
<>
|
||||
A collection of digital assets saved on a small chip. The chip is
|
||||
implanted into your wrist. A small jack in the chip allows you to
|
||||
connect it to a computer and upload the assets.
|
||||
A collection of digital assets saved on a small chip. The chip is implanted into your wrist. A small jack in the
|
||||
chip allows you to connect it to a computer and upload the assets.
|
||||
</>
|
||||
),
|
||||
startingMoney: 1e6,
|
||||
@ -2006,8 +1931,7 @@ function initAugmentations() {
|
||||
repCost: 7.5e3,
|
||||
moneyCost: 3e7,
|
||||
info:
|
||||
"A tiny chip that sits behind the retinae. This implant lets the" +
|
||||
"user visually detect infrared radiation.",
|
||||
"A tiny chip that sits behind the retinae. This implant lets the" + "user visually detect infrared radiation.",
|
||||
crime_success_mult: 1.25,
|
||||
crime_money_mult: 1.1,
|
||||
dexterity_mult: 1.1,
|
||||
@ -2098,8 +2022,7 @@ function initAugmentations() {
|
||||
repCost: 6.25e4,
|
||||
moneyCost: 2.75e8,
|
||||
info:
|
||||
"Cybernetic arms created from plasteel and carbon fibers that completely replace " +
|
||||
"the user's organic arms.",
|
||||
"Cybernetic arms created from plasteel and carbon fibers that completely replace " + "the user's organic arms.",
|
||||
strength_mult: 1.3,
|
||||
dexterity_mult: 1.3,
|
||||
});
|
||||
@ -2417,8 +2340,8 @@ function initAugmentations() {
|
||||
"weaponized by Bladeburner units to be used against Synthoids.",
|
||||
stats: (
|
||||
<>
|
||||
This augmentation allows you to perform Bladeburner actions and other
|
||||
actions (such as working, commiting crimes, etc.) at the same time.
|
||||
This augmentation allows you to perform Bladeburner actions and other actions (such as working, commiting
|
||||
crimes, etc.) at the same time.
|
||||
</>
|
||||
),
|
||||
isSpecial: true,
|
||||
@ -2429,8 +2352,7 @@ function initAugmentations() {
|
||||
|
||||
// Update costs based on how many have been purchased
|
||||
mult = Math.pow(
|
||||
CONSTANTS.MultipleAugMultiplier *
|
||||
[1, 0.96, 0.94, 0.93][SourceFileFlags[11]],
|
||||
CONSTANTS.MultipleAugMultiplier * [1, 0.96, 0.94, 0.93][SourceFileFlags[11]],
|
||||
Player.queuedAugmentations.length,
|
||||
);
|
||||
for (var name in Augmentations) {
|
||||
@ -2445,9 +2367,7 @@ function initAugmentations() {
|
||||
//Resets an Augmentation during (re-initizliation)
|
||||
function resetAugmentation(newAugObject) {
|
||||
if (!(newAugObject instanceof Augmentation)) {
|
||||
throw new Error(
|
||||
"Invalid argument 'newAugObject' passed into resetAugmentation",
|
||||
);
|
||||
throw new Error("Invalid argument 'newAugObject' passed into resetAugmentation");
|
||||
}
|
||||
var name = newAugObject.name;
|
||||
if (augmentationExists(name)) {
|
||||
@ -2464,9 +2384,7 @@ function applyAugmentation(aug, reapply = false) {
|
||||
// Apply multipliers
|
||||
for (const mult in augObj.mults) {
|
||||
if (Player[mult] == null) {
|
||||
console.warn(
|
||||
`Augmentation has unrecognized multiplier property: ${mult}`,
|
||||
);
|
||||
console.warn(`Augmentation has unrecognized multiplier property: ${mult}`);
|
||||
} else {
|
||||
Player[mult] *= augObj.mults[mult];
|
||||
}
|
||||
@ -2477,9 +2395,7 @@ function applyAugmentation(aug, reapply = false) {
|
||||
if (!reapply) {
|
||||
Augmentations[aug.name].level = aug.level;
|
||||
for (let i = 0; i < Player.augmentations.length; ++i) {
|
||||
if (
|
||||
Player.augmentations[i].name == AugmentationNames.NeuroFluxGovernor
|
||||
) {
|
||||
if (Player.augmentations[i].name == AugmentationNames.NeuroFluxGovernor) {
|
||||
Player.augmentations[i].level = aug.level;
|
||||
return;
|
||||
// break;
|
||||
@ -2503,9 +2419,7 @@ function installAugmentations() {
|
||||
let augmentationList = "";
|
||||
let nfgIndex = -1;
|
||||
for (let i = Player.queuedAugmentations.length - 1; i >= 0; i--) {
|
||||
if (
|
||||
Player.queuedAugmentations[i].name === AugmentationNames.NeuroFluxGovernor
|
||||
) {
|
||||
if (Player.queuedAugmentations[i].name === AugmentationNames.NeuroFluxGovernor) {
|
||||
nfgIndex = i;
|
||||
break;
|
||||
}
|
||||
@ -2519,8 +2433,7 @@ function installAugmentations() {
|
||||
}
|
||||
|
||||
applyAugmentation(Player.queuedAugmentations[i]);
|
||||
if (ownedAug.name === AugmentationNames.NeuroFluxGovernor && i !== nfgIndex)
|
||||
continue;
|
||||
if (ownedAug.name === AugmentationNames.NeuroFluxGovernor && i !== nfgIndex) continue;
|
||||
|
||||
let level = "";
|
||||
if (ownedAug.name === AugmentationNames.NeuroFluxGovernor) {
|
||||
@ -2555,13 +2468,7 @@ export function displayAugmentationsContent(contentEl) {
|
||||
onExport(Player);
|
||||
}
|
||||
|
||||
ReactDOM.render(
|
||||
<AugmentationsRoot
|
||||
exportGameFn={backup}
|
||||
installAugmentationsFn={installAugmentations}
|
||||
/>,
|
||||
contentEl,
|
||||
);
|
||||
ReactDOM.render(<AugmentationsRoot exportGameFn={backup} installAugmentationsFn={installAugmentations} />, contentEl);
|
||||
}
|
||||
|
||||
export function isRepeatableAug(aug) {
|
||||
@ -2574,9 +2481,4 @@ export function isRepeatableAug(aug) {
|
||||
return false;
|
||||
}
|
||||
|
||||
export {
|
||||
installAugmentations,
|
||||
initAugmentations,
|
||||
applyAugmentation,
|
||||
augmentationExists,
|
||||
};
|
||||
export { installAugmentations, initAugmentations, applyAugmentation, augmentationExists };
|
||||
|
@ -15,10 +15,7 @@ import { AugmentationAccordion } from "../../ui/React/AugmentationAccordion";
|
||||
export function InstalledAugmentations(): React.ReactElement {
|
||||
const sourceAugs = Player.augmentations.slice();
|
||||
|
||||
if (
|
||||
Settings.OwnedAugmentationsOrder ===
|
||||
OwnedAugmentationsOrderSetting.Alphabetically
|
||||
) {
|
||||
if (Settings.OwnedAugmentationsOrder === OwnedAugmentationsOrderSetting.Alphabetically) {
|
||||
sourceAugs.sort((aug1, aug2) => {
|
||||
return aug1.name <= aug2.name ? -1 : 1;
|
||||
});
|
||||
|
@ -23,10 +23,7 @@ type IState = {
|
||||
rerenderFlag: boolean;
|
||||
};
|
||||
|
||||
export class InstalledAugmentationsAndSourceFiles extends React.Component<
|
||||
IProps,
|
||||
IState
|
||||
> {
|
||||
export class InstalledAugmentationsAndSourceFiles extends React.Component<IProps, IState> {
|
||||
listRef: React.RefObject<HTMLUListElement>;
|
||||
|
||||
constructor(props: IProps) {
|
||||
@ -89,14 +86,12 @@ export class InstalledAugmentationsAndSourceFiles extends React.Component<
|
||||
}
|
||||
|
||||
sortByAcquirementTime(): void {
|
||||
Settings.OwnedAugmentationsOrder =
|
||||
OwnedAugmentationsOrderSetting.AcquirementTime;
|
||||
Settings.OwnedAugmentationsOrder = OwnedAugmentationsOrderSetting.AcquirementTime;
|
||||
this.rerender();
|
||||
}
|
||||
|
||||
sortInOrder(): void {
|
||||
Settings.OwnedAugmentationsOrder =
|
||||
OwnedAugmentationsOrderSetting.Alphabetically;
|
||||
Settings.OwnedAugmentationsOrder = OwnedAugmentationsOrderSetting.Alphabetically;
|
||||
this.rerender();
|
||||
}
|
||||
|
||||
|
@ -14,10 +14,7 @@ import { SourceFileAccordion } from "../../ui/React/SourceFileAccordion";
|
||||
export function OwnedSourceFiles(): React.ReactElement {
|
||||
const sourceSfs = Player.sourceFiles.slice();
|
||||
|
||||
if (
|
||||
Settings.OwnedAugmentationsOrder ===
|
||||
OwnedAugmentationsOrderSetting.Alphabetically
|
||||
) {
|
||||
if (Settings.OwnedAugmentationsOrder === OwnedAugmentationsOrderSetting.Alphabetically) {
|
||||
sourceSfs.sort((sf1, sf2) => {
|
||||
return sf1.n - sf2.n;
|
||||
});
|
||||
|
@ -25,10 +25,7 @@ export function PlayerMultipliers(): React.ReactElement {
|
||||
function improvements(r: number): JSX.Element[] {
|
||||
let elems: JSX.Element[] = [];
|
||||
if (r) {
|
||||
elems = [
|
||||
<td key="2"> {"=>"} </td>,
|
||||
<td key="3">{numeralWrapper.formatPercentage(r)}</td>,
|
||||
];
|
||||
elems = [<td key="2"> {"=>"} </td>, <td key="3">{numeralWrapper.formatPercentage(r)}</td>];
|
||||
}
|
||||
return elems;
|
||||
}
|
||||
@ -60,20 +57,17 @@ export function PlayerMultipliers(): React.ReactElement {
|
||||
[
|
||||
"Bladeburner Success Chance",
|
||||
Player.bladeburner_success_chance_mult,
|
||||
Player.bladeburner_success_chance_mult *
|
||||
mults.bladeburner_success_chance_mult,
|
||||
Player.bladeburner_success_chance_mult * mults.bladeburner_success_chance_mult,
|
||||
],
|
||||
[
|
||||
"Bladeburner Max Stamina",
|
||||
Player.bladeburner_max_stamina_mult,
|
||||
Player.bladeburner_max_stamina_mult *
|
||||
mults.bladeburner_max_stamina_mult,
|
||||
Player.bladeburner_max_stamina_mult * mults.bladeburner_max_stamina_mult,
|
||||
],
|
||||
[
|
||||
"Bladeburner Stamina Gain",
|
||||
Player.bladeburner_stamina_gain_mult,
|
||||
Player.bladeburner_stamina_gain_mult *
|
||||
mults.bladeburner_stamina_gain_mult,
|
||||
Player.bladeburner_stamina_gain_mult * mults.bladeburner_stamina_gain_mult,
|
||||
],
|
||||
[
|
||||
"Bladeburner Field Analysis",
|
||||
@ -95,110 +89,46 @@ export function PlayerMultipliers(): React.ReactElement {
|
||||
</p>
|
||||
<br />
|
||||
{MultiplierTable([
|
||||
[
|
||||
"Hacking Chance ",
|
||||
Player.hacking_chance_mult,
|
||||
Player.hacking_chance_mult * mults.hacking_chance_mult,
|
||||
],
|
||||
[
|
||||
"Hacking Speed ",
|
||||
Player.hacking_speed_mult,
|
||||
Player.hacking_speed_mult * mults.hacking_speed_mult,
|
||||
],
|
||||
[
|
||||
"Hacking Money ",
|
||||
Player.hacking_money_mult,
|
||||
Player.hacking_money_mult * mults.hacking_money_mult,
|
||||
],
|
||||
[
|
||||
"Hacking Growth ",
|
||||
Player.hacking_grow_mult,
|
||||
Player.hacking_grow_mult * mults.hacking_grow_mult,
|
||||
],
|
||||
["Hacking Chance ", Player.hacking_chance_mult, Player.hacking_chance_mult * mults.hacking_chance_mult],
|
||||
["Hacking Speed ", Player.hacking_speed_mult, Player.hacking_speed_mult * mults.hacking_speed_mult],
|
||||
["Hacking Money ", Player.hacking_money_mult, Player.hacking_money_mult * mults.hacking_money_mult],
|
||||
["Hacking Growth ", Player.hacking_grow_mult, Player.hacking_grow_mult * mults.hacking_grow_mult],
|
||||
])}
|
||||
<br />
|
||||
|
||||
{MultiplierTable([
|
||||
[
|
||||
"Hacking Level ",
|
||||
Player.hacking_mult,
|
||||
Player.hacking_mult * mults.hacking_mult,
|
||||
],
|
||||
[
|
||||
"Hacking Experience ",
|
||||
Player.hacking_exp_mult,
|
||||
Player.hacking_exp_mult * mults.hacking_exp_mult,
|
||||
],
|
||||
["Hacking Level ", Player.hacking_mult, Player.hacking_mult * mults.hacking_mult],
|
||||
["Hacking Experience ", Player.hacking_exp_mult, Player.hacking_exp_mult * mults.hacking_exp_mult],
|
||||
])}
|
||||
<br />
|
||||
|
||||
{MultiplierTable([
|
||||
[
|
||||
"Strength Level ",
|
||||
Player.strength_mult,
|
||||
Player.strength_mult * mults.strength_mult,
|
||||
],
|
||||
[
|
||||
"Strength Experience ",
|
||||
Player.strength_exp_mult,
|
||||
Player.strength_exp_mult * mults.strength_exp_mult,
|
||||
],
|
||||
["Strength Level ", Player.strength_mult, Player.strength_mult * mults.strength_mult],
|
||||
["Strength Experience ", Player.strength_exp_mult, Player.strength_exp_mult * mults.strength_exp_mult],
|
||||
])}
|
||||
<br />
|
||||
|
||||
{MultiplierTable([
|
||||
[
|
||||
"Defense Level ",
|
||||
Player.defense_mult,
|
||||
Player.defense_mult * mults.defense_mult,
|
||||
],
|
||||
[
|
||||
"Defense Experience ",
|
||||
Player.defense_exp_mult,
|
||||
Player.defense_exp_mult * mults.defense_exp_mult,
|
||||
],
|
||||
["Defense Level ", Player.defense_mult, Player.defense_mult * mults.defense_mult],
|
||||
["Defense Experience ", Player.defense_exp_mult, Player.defense_exp_mult * mults.defense_exp_mult],
|
||||
])}
|
||||
<br />
|
||||
|
||||
{MultiplierTable([
|
||||
[
|
||||
"Dexterity Level ",
|
||||
Player.dexterity_mult,
|
||||
Player.dexterity_mult * mults.dexterity_mult,
|
||||
],
|
||||
[
|
||||
"Dexterity Experience ",
|
||||
Player.dexterity_exp_mult,
|
||||
Player.dexterity_exp_mult * mults.dexterity_exp_mult,
|
||||
],
|
||||
["Dexterity Level ", Player.dexterity_mult, Player.dexterity_mult * mults.dexterity_mult],
|
||||
["Dexterity Experience ", Player.dexterity_exp_mult, Player.dexterity_exp_mult * mults.dexterity_exp_mult],
|
||||
])}
|
||||
<br />
|
||||
|
||||
{MultiplierTable([
|
||||
[
|
||||
"Agility Level ",
|
||||
Player.agility_mult,
|
||||
Player.agility_mult * mults.agility_mult,
|
||||
],
|
||||
[
|
||||
"Agility Experience ",
|
||||
Player.agility_exp_mult,
|
||||
Player.agility_exp_mult * mults.agility_exp_mult,
|
||||
],
|
||||
["Agility Level ", Player.agility_mult, Player.agility_mult * mults.agility_mult],
|
||||
["Agility Experience ", Player.agility_exp_mult, Player.agility_exp_mult * mults.agility_exp_mult],
|
||||
])}
|
||||
<br />
|
||||
|
||||
{MultiplierTable([
|
||||
[
|
||||
"Charisma Level ",
|
||||
Player.charisma_mult,
|
||||
Player.charisma_mult * mults.charisma_mult,
|
||||
],
|
||||
[
|
||||
"Charisma Experience ",
|
||||
Player.charisma_exp_mult,
|
||||
Player.charisma_exp_mult * mults.charisma_exp_mult,
|
||||
],
|
||||
["Charisma Level ", Player.charisma_mult, Player.charisma_mult * mults.charisma_mult],
|
||||
["Charisma Experience ", Player.charisma_exp_mult, Player.charisma_exp_mult * mults.charisma_exp_mult],
|
||||
])}
|
||||
<br />
|
||||
|
||||
@ -211,8 +141,7 @@ export function PlayerMultipliers(): React.ReactElement {
|
||||
[
|
||||
"Hacknet Node purchase cost ",
|
||||
Player.hacknet_node_purchase_cost_mult,
|
||||
Player.hacknet_node_purchase_cost_mult *
|
||||
mults.hacknet_node_purchase_cost_mult,
|
||||
Player.hacknet_node_purchase_cost_mult * mults.hacknet_node_purchase_cost_mult,
|
||||
],
|
||||
[
|
||||
"Hacknet Node RAM upgrade cost ",
|
||||
@ -222,48 +151,26 @@ export function PlayerMultipliers(): React.ReactElement {
|
||||
[
|
||||
"Hacknet Node Core purchase cost ",
|
||||
Player.hacknet_node_core_cost_mult,
|
||||
Player.hacknet_node_core_cost_mult *
|
||||
mults.hacknet_node_core_cost_mult,
|
||||
Player.hacknet_node_core_cost_mult * mults.hacknet_node_core_cost_mult,
|
||||
],
|
||||
[
|
||||
"Hacknet Node level upgrade cost ",
|
||||
Player.hacknet_node_level_cost_mult,
|
||||
Player.hacknet_node_level_cost_mult *
|
||||
mults.hacknet_node_level_cost_mult,
|
||||
Player.hacknet_node_level_cost_mult * mults.hacknet_node_level_cost_mult,
|
||||
],
|
||||
])}
|
||||
<br />
|
||||
|
||||
{MultiplierTable([
|
||||
[
|
||||
"Company reputation gain ",
|
||||
Player.company_rep_mult,
|
||||
Player.company_rep_mult * mults.company_rep_mult,
|
||||
],
|
||||
[
|
||||
"Faction reputation gain ",
|
||||
Player.faction_rep_mult,
|
||||
Player.faction_rep_mult * mults.faction_rep_mult,
|
||||
],
|
||||
[
|
||||
"Salary ",
|
||||
Player.work_money_mult,
|
||||
Player.work_money_mult * mults.work_money_mult,
|
||||
],
|
||||
["Company reputation gain ", Player.company_rep_mult, Player.company_rep_mult * mults.company_rep_mult],
|
||||
["Faction reputation gain ", Player.faction_rep_mult, Player.faction_rep_mult * mults.faction_rep_mult],
|
||||
["Salary ", Player.work_money_mult, Player.work_money_mult * mults.work_money_mult],
|
||||
])}
|
||||
<br />
|
||||
|
||||
{MultiplierTable([
|
||||
[
|
||||
"Crime success ",
|
||||
Player.crime_success_mult,
|
||||
Player.crime_success_mult * mults.crime_success_mult,
|
||||
],
|
||||
[
|
||||
"Crime money ",
|
||||
Player.crime_money_mult,
|
||||
Player.crime_money_mult * mults.crime_money_mult,
|
||||
],
|
||||
["Crime success ", Player.crime_success_mult, Player.crime_success_mult * mults.crime_success_mult],
|
||||
["Crime money ", Player.crime_money_mult, Player.crime_money_mult * mults.crime_money_mult],
|
||||
])}
|
||||
<br />
|
||||
|
||||
|
@ -15,17 +15,14 @@ export function PurchasedAugmentations(): React.ReactElement {
|
||||
// Only render the last NeuroFlux (there are no findLastIndex btw)
|
||||
let nfgIndex = -1;
|
||||
for (let i = Player.queuedAugmentations.length - 1; i >= 0; i--) {
|
||||
if (
|
||||
Player.queuedAugmentations[i].name === AugmentationNames.NeuroFluxGovernor
|
||||
) {
|
||||
if (Player.queuedAugmentations[i].name === AugmentationNames.NeuroFluxGovernor) {
|
||||
nfgIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (let i = 0; i < Player.queuedAugmentations.length; i++) {
|
||||
const ownedAug = Player.queuedAugmentations[i];
|
||||
if (ownedAug.name === AugmentationNames.NeuroFluxGovernor && i !== nfgIndex)
|
||||
continue;
|
||||
if (ownedAug.name === AugmentationNames.NeuroFluxGovernor && i !== nfgIndex) continue;
|
||||
const aug = Augmentations[ownedAug.name];
|
||||
let level = null;
|
||||
if (ownedAug.name === AugmentationNames.NeuroFluxGovernor) {
|
||||
|
@ -47,13 +47,10 @@ export class AugmentationsRoot extends React.Component<IProps, IState> {
|
||||
<div id="augmentations-content">
|
||||
<h1>Purchased Augmentations</h1>
|
||||
<p>
|
||||
Below is a list of all Augmentations you have purchased but not yet
|
||||
installed. Click the button below to install them.
|
||||
</p>
|
||||
<p>
|
||||
WARNING: Installing your Augmentations resets most of your progress,
|
||||
including:
|
||||
Below is a list of all Augmentations you have purchased but not yet installed. Click the button below to
|
||||
install them.
|
||||
</p>
|
||||
<p>WARNING: Installing your Augmentations resets most of your progress, including:</p>
|
||||
<br />
|
||||
<p>- Stats/Skill levels and Experience</p>
|
||||
<p>- Money</p>
|
||||
@ -64,10 +61,9 @@ export class AugmentationsRoot extends React.Component<IProps, IState> {
|
||||
<p>- Stocks</p>
|
||||
<br />
|
||||
<p>
|
||||
Installing Augmentations lets you start over with the perks and
|
||||
benefits granted by all of the Augmentations you have ever installed.
|
||||
Also, you will keep any scripts and RAM/Core upgrades on your home
|
||||
computer (but you will lose all programs besides NUKE.exe)
|
||||
Installing Augmentations lets you start over with the perks and benefits granted by all of the Augmentations
|
||||
you have ever installed. Also, you will keep any scripts and RAM/Core upgrades on your home computer (but you
|
||||
will lose all programs besides NUKE.exe)
|
||||
</p>
|
||||
<StdButton
|
||||
onClick={this.props.installAugmentationsFn}
|
||||
@ -83,9 +79,7 @@ export class AugmentationsRoot extends React.Component<IProps, IState> {
|
||||
<PurchasedAugmentations />
|
||||
<h1>Installed Augmentations</h1>
|
||||
<p>
|
||||
{`List of all Augmentations ${
|
||||
Player.sourceFiles.length > 0 ? "and Source Files " : ""
|
||||
} ` +
|
||||
{`List of all Augmentations ${Player.sourceFiles.length > 0 ? "and Source Files " : ""} ` +
|
||||
`that have been installed. You have gained the effects of these.`}
|
||||
</p>
|
||||
<InstalledAugmentationsAndSourceFiles />
|
||||
|
@ -29,8 +29,8 @@ export function SourceFileMinus1(): React.ReactElement {
|
||||
panelContent={
|
||||
<>
|
||||
<p>
|
||||
This Source-File can only be acquired with obscure knowledge of
|
||||
the game, javascript, and the web ecosystem.
|
||||
This Source-File can only be acquired with obscure knowledge of the game, javascript, and the web
|
||||
ecosystem.
|
||||
</p>
|
||||
<p>It increases all of the player's multipliers by 0.1%</p>
|
||||
<br />
|
||||
|
@ -1,11 +1,7 @@
|
||||
import { Player } from "../Player";
|
||||
import { getRandomInt } from "../../utils/helpers/getRandomInt";
|
||||
import { addOffset } from "../../utils/helpers/addOffset";
|
||||
import {
|
||||
Generic_fromJSON,
|
||||
Generic_toJSON,
|
||||
Reviver,
|
||||
} from "../../utils/JSONReviver";
|
||||
import { Generic_fromJSON, Generic_toJSON, Reviver } from "../../utils/JSONReviver";
|
||||
import { BladeburnerConstants } from "./data/Constants";
|
||||
import { IBladeburner } from "./IBladeburner";
|
||||
import { IAction, ISuccessChanceParams } from "./IAction";
|
||||
@ -106,10 +102,8 @@ export class Action implements IAction {
|
||||
if (params && params.name) this.name = params.name;
|
||||
if (params && params.desc) this.desc = params.desc;
|
||||
|
||||
if (params && params.baseDifficulty)
|
||||
this.baseDifficulty = addOffset(params.baseDifficulty, 10);
|
||||
if (params && params.difficultyFac)
|
||||
this.difficultyFac = params.difficultyFac;
|
||||
if (params && params.baseDifficulty) this.baseDifficulty = addOffset(params.baseDifficulty, 10);
|
||||
if (params && params.difficultyFac) this.difficultyFac = params.difficultyFac;
|
||||
|
||||
if (params && params.rewardFac) this.rewardFac = params.rewardFac;
|
||||
if (params && params.rankGain) this.rankGain = params.rankGain;
|
||||
@ -144,11 +138,7 @@ export class Action implements IAction {
|
||||
if (this.decays.hasOwnProperty(decay)) {
|
||||
if (this.decays[decay] > 1) {
|
||||
throw new Error(
|
||||
"Invalid decays when constructing " +
|
||||
"Action " +
|
||||
this.name +
|
||||
". " +
|
||||
"Decay value cannot be greater than 1",
|
||||
"Invalid decays when constructing " + "Action " + this.name + ". " + "Decay value cannot be greater than 1",
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -156,8 +146,7 @@ export class Action implements IAction {
|
||||
}
|
||||
|
||||
getDifficulty(): number {
|
||||
const difficulty =
|
||||
this.baseDifficulty * Math.pow(this.difficultyFac, this.level - 1);
|
||||
const difficulty = this.baseDifficulty * Math.pow(this.difficultyFac, this.level - 1);
|
||||
if (isNaN(difficulty)) {
|
||||
throw new Error("Calculated NaN in Action.getDifficulty()");
|
||||
}
|
||||
@ -207,27 +196,16 @@ export class Action implements IAction {
|
||||
return 1;
|
||||
}
|
||||
|
||||
getChaosCompetencePenalty(
|
||||
inst: IBladeburner,
|
||||
params: ISuccessChanceParams,
|
||||
): number {
|
||||
getChaosCompetencePenalty(inst: IBladeburner, params: ISuccessChanceParams): number {
|
||||
const city = inst.getCurrentCity();
|
||||
if (params.est) {
|
||||
return Math.pow(
|
||||
city.popEst / BladeburnerConstants.PopulationThreshold,
|
||||
BladeburnerConstants.PopulationExponent,
|
||||
);
|
||||
return Math.pow(city.popEst / BladeburnerConstants.PopulationThreshold, BladeburnerConstants.PopulationExponent);
|
||||
} else {
|
||||
return Math.pow(
|
||||
city.pop / BladeburnerConstants.PopulationThreshold,
|
||||
BladeburnerConstants.PopulationExponent,
|
||||
);
|
||||
return Math.pow(city.pop / BladeburnerConstants.PopulationThreshold, BladeburnerConstants.PopulationExponent);
|
||||
}
|
||||
}
|
||||
|
||||
getChaosDifficultyBonus(
|
||||
inst: IBladeburner /*, params: ISuccessChanceParams*/,
|
||||
): number {
|
||||
getChaosDifficultyBonus(inst: IBladeburner /*, params: ISuccessChanceParams*/): number {
|
||||
const city = inst.getCurrentCity();
|
||||
if (city.chaos > BladeburnerConstants.ChaosThreshold) {
|
||||
const diff = 1 + (city.chaos - BladeburnerConstants.ChaosThreshold);
|
||||
@ -260,14 +238,9 @@ export class Action implements IAction {
|
||||
* @params - options:
|
||||
* est (bool): Get success chance estimate instead of real success chance
|
||||
*/
|
||||
getSuccessChance(
|
||||
inst: IBladeburner,
|
||||
params: ISuccessChanceParams = { est: false },
|
||||
): number {
|
||||
getSuccessChance(inst: IBladeburner, params: ISuccessChanceParams = { est: false }): number {
|
||||
if (inst == null) {
|
||||
throw new Error(
|
||||
"Invalid Bladeburner instance passed into Action.getSuccessChance",
|
||||
);
|
||||
throw new Error("Invalid Bladeburner instance passed into Action.getSuccessChance");
|
||||
}
|
||||
let difficulty = this.getDifficulty();
|
||||
let competence = 0;
|
||||
@ -277,14 +250,10 @@ export class Action implements IAction {
|
||||
const key = "eff" + stat.charAt(0).toUpperCase() + stat.slice(1);
|
||||
let effMultiplier = inst.skillMultipliers[key];
|
||||
if (effMultiplier == null) {
|
||||
console.error(
|
||||
`Failed to find Bladeburner Skill multiplier for: ${stat}`,
|
||||
);
|
||||
console.error(`Failed to find Bladeburner Skill multiplier for: ${stat}`);
|
||||
effMultiplier = 1;
|
||||
}
|
||||
competence +=
|
||||
this.weights[stat] *
|
||||
Math.pow(effMultiplier * playerStatLvl, this.decays[stat]);
|
||||
competence += this.weights[stat] * Math.pow(effMultiplier * playerStatLvl, this.decays[stat]);
|
||||
}
|
||||
}
|
||||
competence *= Player.getIntelligenceBonus(0.75);
|
||||
@ -313,24 +282,17 @@ export class Action implements IAction {
|
||||
competence *= Player.bladeburner_success_chance_mult;
|
||||
|
||||
if (isNaN(competence)) {
|
||||
throw new Error(
|
||||
"Competence calculated as NaN in Action.getSuccessChance()",
|
||||
);
|
||||
throw new Error("Competence calculated as NaN in Action.getSuccessChance()");
|
||||
}
|
||||
return Math.min(1, competence / difficulty);
|
||||
}
|
||||
|
||||
getSuccessesNeededForNextLevel(baseSuccessesPerLevel: number): number {
|
||||
return Math.ceil(
|
||||
0.5 * this.maxLevel * (2 * baseSuccessesPerLevel + (this.maxLevel - 1)),
|
||||
);
|
||||
return Math.ceil(0.5 * this.maxLevel * (2 * baseSuccessesPerLevel + (this.maxLevel - 1)));
|
||||
}
|
||||
|
||||
setMaxLevel(baseSuccessesPerLevel: number): void {
|
||||
if (
|
||||
this.successes >=
|
||||
this.getSuccessesNeededForNextLevel(baseSuccessesPerLevel)
|
||||
) {
|
||||
if (this.successes >= this.getSuccessesNeededForNextLevel(baseSuccessesPerLevel)) {
|
||||
++this.maxLevel;
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,5 @@
|
||||
import { IActionIdentifier } from "./IActionIdentifier";
|
||||
import {
|
||||
Generic_fromJSON,
|
||||
Generic_toJSON,
|
||||
Reviver,
|
||||
} from "../../utils/JSONReviver";
|
||||
import { Generic_fromJSON, Generic_toJSON, Reviver } from "../../utils/JSONReviver";
|
||||
|
||||
interface IParams {
|
||||
name?: string;
|
||||
|
@ -1,9 +1,5 @@
|
||||
import { Operation, IOperationParams } from "./Operation";
|
||||
import {
|
||||
Generic_fromJSON,
|
||||
Generic_toJSON,
|
||||
Reviver,
|
||||
} from "../../utils/JSONReviver";
|
||||
import { Generic_fromJSON, Generic_toJSON, Reviver } from "../../utils/JSONReviver";
|
||||
|
||||
export class BlackOperation extends Operation {
|
||||
constructor(params: IOperationParams | null = null) {
|
||||
|
@ -735,9 +735,7 @@ export const BlackOperations: IMap<BlackOperation> = {};
|
||||
});
|
||||
BlackOperations["Operation Daedalus"] = new BlackOperation({
|
||||
name: "Operation Daedalus",
|
||||
desc:
|
||||
"Yesterday we obeyed kings and bent our neck to emperors. " +
|
||||
"Today we kneel only to truth.",
|
||||
desc: "Yesterday we obeyed kings and bent our neck to emperors. " + "Today we kneel only to truth.",
|
||||
baseDifficulty: 80e3,
|
||||
reqdRank: 400e3,
|
||||
rankGain: 40e3,
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,10 +1,6 @@
|
||||
import { BladeburnerConstants } from "./data/Constants";
|
||||
import { getRandomInt } from "../../utils/helpers/getRandomInt";
|
||||
import {
|
||||
Generic_fromJSON,
|
||||
Generic_toJSON,
|
||||
Reviver,
|
||||
} from "../../utils/JSONReviver";
|
||||
import { Generic_fromJSON, Generic_toJSON, Reviver } from "../../utils/JSONReviver";
|
||||
import { addOffset } from "../../utils/helpers/addOffset";
|
||||
|
||||
interface IChangePopulationByCountParams {
|
||||
@ -52,10 +48,7 @@ export class City {
|
||||
this.name = name;
|
||||
|
||||
// Synthoid population and estimate
|
||||
this.pop = getRandomInt(
|
||||
BladeburnerConstants.PopulationThreshold,
|
||||
1.5 * BladeburnerConstants.PopulationThreshold,
|
||||
);
|
||||
this.pop = getRandomInt(BladeburnerConstants.PopulationThreshold, 1.5 * BladeburnerConstants.PopulationThreshold);
|
||||
this.popEst = this.pop * (Math.random() + 0.5);
|
||||
|
||||
// Number of Synthoid communities population and estimate
|
||||
@ -83,9 +76,7 @@ export class City {
|
||||
|
||||
improvePopulationEstimateByCount(n: number): void {
|
||||
if (isNaN(n)) {
|
||||
throw new Error(
|
||||
"NaN passeed into City.improvePopulationEstimateByCount()",
|
||||
);
|
||||
throw new Error("NaN passeed into City.improvePopulationEstimateByCount()");
|
||||
}
|
||||
if (this.popEst < this.pop) {
|
||||
this.popEst += n;
|
||||
@ -106,9 +97,7 @@ export class City {
|
||||
improvePopulationEstimateByPercentage(p: number, skillMult = 1): void {
|
||||
p = p * skillMult;
|
||||
if (isNaN(p)) {
|
||||
throw new Error(
|
||||
"NaN passed into City.improvePopulationEstimateByPercentage()",
|
||||
);
|
||||
throw new Error("NaN passed into City.improvePopulationEstimateByPercentage()");
|
||||
}
|
||||
if (this.popEst < this.pop) {
|
||||
++this.popEst; // In case estimate is 0
|
||||
@ -146,10 +135,7 @@ export class City {
|
||||
* estChange(int): How much the estimate should change by
|
||||
* estOffset(int): Add offset to estimate (offset by percentage)
|
||||
*/
|
||||
changePopulationByCount(
|
||||
n: number,
|
||||
params: IChangePopulationByCountParams = { estChange: 0, estOffset: 0 },
|
||||
): void {
|
||||
changePopulationByCount(n: number, params: IChangePopulationByCountParams = { estChange: 0, estOffset: 0 }): void {
|
||||
if (isNaN(n)) {
|
||||
throw new Error("NaN passed into City.changePopulationByCount()");
|
||||
}
|
||||
|
@ -1,10 +1,6 @@
|
||||
import { IBladeburner } from "./IBladeburner";
|
||||
import { Action, IActionParams } from "./Action";
|
||||
import {
|
||||
Generic_fromJSON,
|
||||
Generic_toJSON,
|
||||
Reviver,
|
||||
} from "../../utils/JSONReviver";
|
||||
import { Generic_fromJSON, Generic_toJSON, Reviver } from "../../utils/JSONReviver";
|
||||
|
||||
export class Contract extends Action {
|
||||
constructor(params: IActionParams | null = null) {
|
||||
|
@ -61,10 +61,7 @@ export interface IAction {
|
||||
getActionTime(inst: IBladeburner): number;
|
||||
getTeamSuccessBonus(inst: IBladeburner): number;
|
||||
getActionTypeSkillSuccessBonus(inst: IBladeburner): number;
|
||||
getChaosCompetencePenalty(
|
||||
inst: IBladeburner,
|
||||
params: ISuccessChanceParams,
|
||||
): number;
|
||||
getChaosCompetencePenalty(inst: IBladeburner, params: ISuccessChanceParams): number;
|
||||
getChaosDifficultyBonus(inst: IBladeburner): number;
|
||||
getEstSuccessChance(inst: IBladeburner): number[];
|
||||
getSuccessChance(inst: IBladeburner, params: ISuccessChanceParams): number;
|
||||
|
@ -68,57 +68,22 @@ export interface IBladeburner {
|
||||
getBlackOpNamesNetscriptFn(): string[];
|
||||
getGeneralActionNamesNetscriptFn(): string[];
|
||||
getSkillNamesNetscriptFn(): string[];
|
||||
startActionNetscriptFn(
|
||||
player: IPlayer,
|
||||
type: string,
|
||||
name: string,
|
||||
workerScript: WorkerScript,
|
||||
): boolean;
|
||||
getActionTimeNetscriptFn(
|
||||
player: IPlayer,
|
||||
type: string,
|
||||
name: string,
|
||||
workerScript: WorkerScript,
|
||||
): number;
|
||||
startActionNetscriptFn(player: IPlayer, type: string, name: string, workerScript: WorkerScript): boolean;
|
||||
getActionTimeNetscriptFn(player: IPlayer, type: string, name: string, workerScript: WorkerScript): number;
|
||||
getActionEstimatedSuccessChanceNetscriptFn(
|
||||
player: IPlayer,
|
||||
type: string,
|
||||
name: string,
|
||||
workerScript: WorkerScript,
|
||||
): number[];
|
||||
getActionCountRemainingNetscriptFn(
|
||||
type: string,
|
||||
name: string,
|
||||
workerScript: WorkerScript,
|
||||
): number;
|
||||
getSkillLevelNetscriptFn(
|
||||
skillName: string,
|
||||
workerScript: WorkerScript,
|
||||
): number;
|
||||
getSkillUpgradeCostNetscriptFn(
|
||||
skillName: string,
|
||||
workerScript: WorkerScript,
|
||||
): number;
|
||||
upgradeSkillNetscriptFn(
|
||||
skillName: string,
|
||||
workerScript: WorkerScript,
|
||||
): boolean;
|
||||
getTeamSizeNetscriptFn(
|
||||
type: string,
|
||||
name: string,
|
||||
workerScript: WorkerScript,
|
||||
): number;
|
||||
setTeamSizeNetscriptFn(
|
||||
type: string,
|
||||
name: string,
|
||||
size: number,
|
||||
workerScript: WorkerScript,
|
||||
): number;
|
||||
getActionCountRemainingNetscriptFn(type: string, name: string, workerScript: WorkerScript): number;
|
||||
getSkillLevelNetscriptFn(skillName: string, workerScript: WorkerScript): number;
|
||||
getSkillUpgradeCostNetscriptFn(skillName: string, workerScript: WorkerScript): number;
|
||||
upgradeSkillNetscriptFn(skillName: string, workerScript: WorkerScript): boolean;
|
||||
getTeamSizeNetscriptFn(type: string, name: string, workerScript: WorkerScript): number;
|
||||
setTeamSizeNetscriptFn(type: string, name: string, size: number, workerScript: WorkerScript): number;
|
||||
joinBladeburnerFactionNetscriptFn(workerScript: WorkerScript): boolean;
|
||||
getActionIdFromTypeAndName(
|
||||
type: string,
|
||||
name: string,
|
||||
): IActionIdentifier | null;
|
||||
getActionIdFromTypeAndName(type: string, name: string): IActionIdentifier | null;
|
||||
executeStartConsoleCommand(player: IPlayer, args: string[]): void;
|
||||
executeSkillConsoleCommand(args: string[]): void;
|
||||
executeLogConsoleCommand(args: string[]): void;
|
||||
|
@ -1,11 +1,7 @@
|
||||
import { IBladeburner } from "./IBladeburner";
|
||||
import { BladeburnerConstants } from "./data/Constants";
|
||||
import { Action, IActionParams } from "./Action";
|
||||
import {
|
||||
Generic_fromJSON,
|
||||
Generic_toJSON,
|
||||
Reviver,
|
||||
} from "../../utils/JSONReviver";
|
||||
import { Generic_fromJSON, Generic_toJSON, Reviver } from "../../utils/JSONReviver";
|
||||
|
||||
export interface IOperationParams extends IActionParams {
|
||||
reqdRank?: number;
|
||||
@ -37,9 +33,7 @@ export class Operation extends Action {
|
||||
return inst.skillMultipliers.successChanceOperation;
|
||||
}
|
||||
|
||||
getChaosDifficultyBonus(
|
||||
inst: IBladeburner /*, params: ISuccessChanceParams*/,
|
||||
): number {
|
||||
getChaosDifficultyBonus(inst: IBladeburner /*, params: ISuccessChanceParams*/): number {
|
||||
const city = inst.getCurrentCity();
|
||||
if (city.chaos > BladeburnerConstants.ChaosThreshold) {
|
||||
const diff = 1 + (city.chaos - BladeburnerConstants.ChaosThreshold);
|
||||
|
@ -66,14 +66,10 @@ export class Skill {
|
||||
|
||||
constructor(params: ISkillParams = { name: "foo", desc: "foo" }) {
|
||||
if (!params.name) {
|
||||
throw new Error(
|
||||
"Failed to initialize Bladeburner Skill. No name was specified in ctor",
|
||||
);
|
||||
throw new Error("Failed to initialize Bladeburner Skill. No name was specified in ctor");
|
||||
}
|
||||
if (!params.desc) {
|
||||
throw new Error(
|
||||
"Failed to initialize Bladeburner Skills. No desc was specified in ctor",
|
||||
);
|
||||
throw new Error("Failed to initialize Bladeburner Skills. No desc was specified in ctor");
|
||||
}
|
||||
this.name = params.name;
|
||||
this.desc = params.desc;
|
||||
@ -138,10 +134,7 @@ export class Skill {
|
||||
}
|
||||
|
||||
calculateCost(currentLevel: number): number {
|
||||
return Math.floor(
|
||||
(this.baseCost + currentLevel * this.costInc) *
|
||||
BitNodeMultipliers.BladeburnerSkillCost,
|
||||
);
|
||||
return Math.floor((this.baseCost + currentLevel * this.costInc) * BitNodeMultipliers.BladeburnerSkillCost);
|
||||
}
|
||||
|
||||
getMultiplier(name: string): number {
|
||||
|
@ -8,8 +8,7 @@ export const Skills: IMap<Skill> = {};
|
||||
Skills[SkillNames.BladesIntuition] = new Skill({
|
||||
name: SkillNames.BladesIntuition,
|
||||
desc:
|
||||
"Each level of this skill increases your success chance " +
|
||||
"for all Contracts, Operations, and BlackOps by 3%",
|
||||
"Each level of this skill increases your success chance " + "for all Contracts, Operations, and BlackOps by 3%",
|
||||
baseCost: 3,
|
||||
costInc: 2.1,
|
||||
successChanceAll: 3,
|
||||
@ -34,18 +33,14 @@ export const Skills: IMap<Skill> = {};
|
||||
});
|
||||
Skills[SkillNames.DigitalObserver] = new Skill({
|
||||
name: SkillNames.DigitalObserver,
|
||||
desc:
|
||||
"Each level of this skill increases your success chance in " +
|
||||
"all Operations and BlackOps by 4%",
|
||||
desc: "Each level of this skill increases your success chance in " + "all Operations and BlackOps by 4%",
|
||||
baseCost: 2,
|
||||
costInc: 2.1,
|
||||
successChanceOperation: 4,
|
||||
});
|
||||
Skills[SkillNames.Tracer] = new Skill({
|
||||
name: SkillNames.Tracer,
|
||||
desc:
|
||||
"Each level of this skill increases your success chance in " +
|
||||
"all Contracts by 4%",
|
||||
desc: "Each level of this skill increases your success chance in " + "all Contracts by 4%",
|
||||
baseCost: 2,
|
||||
costInc: 2.1,
|
||||
successChanceContract: 4,
|
||||
@ -72,9 +67,7 @@ export const Skills: IMap<Skill> = {};
|
||||
});
|
||||
Skills[SkillNames.EvasiveSystem] = new Skill({
|
||||
name: SkillNames.EvasiveSystem,
|
||||
desc:
|
||||
"Each level of this skill increases your effective " +
|
||||
"dexterity and agility for Bladeburner actions by 4%",
|
||||
desc: "Each level of this skill increases your effective " + "dexterity and agility for Bladeburner actions by 4%",
|
||||
baseCost: 2,
|
||||
costInc: 2.1,
|
||||
effDex: 4,
|
||||
|
@ -27,14 +27,7 @@ export const BladeburnerConstants: {
|
||||
HrcHpGain: number;
|
||||
HrcStaminaGain: number;
|
||||
} = {
|
||||
CityNames: [
|
||||
"Aevum",
|
||||
"Chongqing",
|
||||
"Sector-12",
|
||||
"New Tokyo",
|
||||
"Ishima",
|
||||
"Volhaven",
|
||||
],
|
||||
CityNames: ["Aevum", "Chongqing", "Sector-12", "New Tokyo", "Ishima", "Volhaven"],
|
||||
CyclesPerSecond: 5, // Game cycle is 200 ms
|
||||
|
||||
StaminaGainPerSecond: 0.0085,
|
||||
|
@ -1,13 +1,7 @@
|
||||
import * as React from "react";
|
||||
|
||||
export const stealthIcon = (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="16px"
|
||||
height="16px"
|
||||
viewBox="0 0 166 132"
|
||||
style={{ fill: "#adff2f" }}
|
||||
>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16px" height="16px" viewBox="0 0 166 132" style={{ fill: "#adff2f" }}>
|
||||
<g>
|
||||
<path d="M132.658-0.18l-24.321,24.321c-7.915-2.71-16.342-4.392-25.087-4.392c-45.84,0-83,46-83,46 s14.1,17.44,35.635,30.844L12.32,120.158l12.021,12.021L144.68,11.841L132.658-0.18z M52.033,80.445 c-2.104-4.458-3.283-9.438-3.283-14.695c0-19.054,15.446-34.5,34.5-34.5c5.258,0,10.237,1.179,14.695,3.284L52.033,80.445z" />
|
||||
<path d="M134.865,37.656l-18.482,18.482c0.884,3.052,1.367,6.275,1.367,9.612c0,19.055-15.446,34.5-34.5,34.5 c-3.337,0-6.56-0.483-9.611-1.367l-10.124,10.124c6.326,1.725,12.934,2.743,19.735,2.743c45.84,0,83-46,83-46 S153.987,50.575,134.865,37.656z" />
|
||||
|
@ -26,11 +26,7 @@ export function AllPages(props: IProps): React.ReactElement {
|
||||
return (
|
||||
<a
|
||||
onClick={() => setPage(props.name)}
|
||||
className={
|
||||
page !== props.name
|
||||
? "bladeburner-nav-button noselect"
|
||||
: "bladeburner-nav-button-inactive noselect"
|
||||
}
|
||||
className={page !== props.name ? "bladeburner-nav-button noselect" : "bladeburner-nav-button-inactive noselect"}
|
||||
>
|
||||
{props.name}
|
||||
</a>
|
||||
@ -44,29 +40,14 @@ export function AllPages(props: IProps): React.ReactElement {
|
||||
<Header name={"BlackOps"} />
|
||||
<Header name={"Skills"} />
|
||||
<div style={{ display: "block", margin: "4px", padding: "4px" }}>
|
||||
{page === "General" && (
|
||||
<GeneralActionPage
|
||||
bladeburner={props.bladeburner}
|
||||
player={props.player}
|
||||
/>
|
||||
)}
|
||||
{page === "Contracts" && (
|
||||
<ContractPage bladeburner={props.bladeburner} player={props.player} />
|
||||
)}
|
||||
{page === "Operations" && (
|
||||
<OperationPage
|
||||
bladeburner={props.bladeburner}
|
||||
player={props.player}
|
||||
/>
|
||||
)}
|
||||
{page === "BlackOps" && (
|
||||
<BlackOpPage bladeburner={props.bladeburner} player={props.player} />
|
||||
)}
|
||||
{page === "General" && <GeneralActionPage bladeburner={props.bladeburner} player={props.player} />}
|
||||
{page === "Contracts" && <ContractPage bladeburner={props.bladeburner} player={props.player} />}
|
||||
{page === "Operations" && <OperationPage bladeburner={props.bladeburner} player={props.player} />}
|
||||
{page === "BlackOps" && <BlackOpPage bladeburner={props.bladeburner} player={props.player} />}
|
||||
{page === "Skills" && <SkillPage bladeburner={props.bladeburner} />}
|
||||
</div>
|
||||
<span className="text">
|
||||
{stealthIcon} = This action requires stealth, {killIcon} = This action
|
||||
involves retirement
|
||||
{stealthIcon} = This action requires stealth, {killIcon} = This action involves retirement
|
||||
</span>
|
||||
</>
|
||||
);
|
||||
|
@ -1,8 +1,5 @@
|
||||
import React, { useState } from "react";
|
||||
import {
|
||||
formatNumber,
|
||||
convertTimeMsToTimeElapsedString,
|
||||
} from "../../../utils/StringHelperFunctions";
|
||||
import { formatNumber, convertTimeMsToTimeElapsedString } from "../../../utils/StringHelperFunctions";
|
||||
import { ActionTypes } from "../data/ActionTypes";
|
||||
import { createProgressBarText } from "../../../utils/helpers/createProgressBarText";
|
||||
import { stealthIcon, killIcon } from "../data/Icons";
|
||||
@ -23,17 +20,13 @@ export function BlackOpElem(props: IProps): React.ReactElement {
|
||||
const setRerender = useState(false)[1];
|
||||
const isCompleted = props.bladeburner.blackops[props.action.name] != null;
|
||||
if (isCompleted) {
|
||||
return (
|
||||
<h2 style={{ display: "block" }}>{props.action.name} (COMPLETED)</h2>
|
||||
);
|
||||
return <h2 style={{ display: "block" }}>{props.action.name} (COMPLETED)</h2>;
|
||||
}
|
||||
|
||||
const isActive =
|
||||
props.bladeburner.action.type === ActionTypes["BlackOperation"] &&
|
||||
props.action.name === props.bladeburner.action.name;
|
||||
const estimatedSuccessChance = props.action.getEstSuccessChance(
|
||||
props.bladeburner,
|
||||
);
|
||||
const estimatedSuccessChance = props.action.getEstSuccessChance(props.bladeburner);
|
||||
const actionTime = props.action.getActionTime(props.bladeburner);
|
||||
const hasReqdRank = props.bladeburner.rank >= props.action.reqdRank;
|
||||
const computedActionTimeCurrent = Math.min(
|
||||
@ -62,8 +55,7 @@ export function BlackOpElem(props: IProps): React.ReactElement {
|
||||
<h2 style={{ display: "inline-block" }}>
|
||||
{isActive ? (
|
||||
<>
|
||||
<CopyableText value={props.action.name} /> (IN PROGRESS -{" "}
|
||||
{formatNumber(computedActionTimeCurrent, 0)} /{" "}
|
||||
<CopyableText value={props.action.name} /> (IN PROGRESS - {formatNumber(computedActionTimeCurrent, 0)} /{" "}
|
||||
{formatNumber(props.bladeburner.actionTimeToComplete, 0)})
|
||||
</>
|
||||
) : (
|
||||
@ -73,9 +65,7 @@ export function BlackOpElem(props: IProps): React.ReactElement {
|
||||
{isActive ? (
|
||||
<p style={{ display: "block" }}>
|
||||
{createProgressBarText({
|
||||
progress:
|
||||
computedActionTimeCurrent /
|
||||
props.bladeburner.actionTimeToComplete,
|
||||
progress: computedActionTimeCurrent / props.bladeburner.actionTimeToComplete,
|
||||
})}
|
||||
</p>
|
||||
) : (
|
||||
@ -87,21 +77,14 @@ export function BlackOpElem(props: IProps): React.ReactElement {
|
||||
>
|
||||
Start
|
||||
</a>
|
||||
<a
|
||||
onClick={onTeam}
|
||||
style={{ margin: "3px", padding: "3px" }}
|
||||
className="a-link-button"
|
||||
>
|
||||
<a onClick={onTeam} style={{ margin: "3px", padding: "3px" }} className="a-link-button">
|
||||
Set Team Size (Curr Size: {formatNumber(props.action.teamCount, 0)})
|
||||
</a>
|
||||
</>
|
||||
)}
|
||||
<br />
|
||||
<br />
|
||||
<p
|
||||
style={{ display: "inline-block" }}
|
||||
dangerouslySetInnerHTML={{ __html: props.action.desc }}
|
||||
/>
|
||||
<p style={{ display: "inline-block" }} dangerouslySetInnerHTML={{ __html: props.action.desc }} />
|
||||
<br />
|
||||
<br />
|
||||
<p style={{ display: "block", color: hasReqdRank ? "white" : "red" }}>
|
||||
@ -109,8 +92,7 @@ export function BlackOpElem(props: IProps): React.ReactElement {
|
||||
</p>
|
||||
<br />
|
||||
<pre style={{ display: "inline-block" }}>
|
||||
Estimated Success Chance:{" "}
|
||||
<SuccessChance chance={estimatedSuccessChance} />{" "}
|
||||
Estimated Success Chance: <SuccessChance chance={estimatedSuccessChance} />{" "}
|
||||
{props.action.isStealth ? stealthIcon : <></>}
|
||||
{props.action.isKill ? killIcon : <></>}
|
||||
<br />
|
||||
|
@ -22,7 +22,8 @@ export function BlackOpList(props: IProps): React.ReactElement {
|
||||
});
|
||||
|
||||
blackops = blackops.filter(
|
||||
(blackop: BlackOperation, i: number) => !(
|
||||
(blackop: BlackOperation, i: number) =>
|
||||
!(
|
||||
props.bladeburner.blackops[blackops[i].name] == null &&
|
||||
i !== 0 &&
|
||||
props.bladeburner.blackops[blackops[i - 1].name] == null
|
||||
@ -35,11 +36,7 @@ export function BlackOpList(props: IProps): React.ReactElement {
|
||||
<>
|
||||
{blackops.map((blackop: BlackOperation) => (
|
||||
<li key={blackop.name} className="bladeburner-action">
|
||||
<BlackOpElem
|
||||
bladeburner={props.bladeburner}
|
||||
action={blackop}
|
||||
player={props.player}
|
||||
/>
|
||||
<BlackOpElem bladeburner={props.bladeburner} action={blackop} player={props.player} />
|
||||
</li>
|
||||
))}
|
||||
</>
|
||||
|
@ -12,19 +12,15 @@ export function BlackOpPage(props: IProps): React.ReactElement {
|
||||
return (
|
||||
<>
|
||||
<p style={{ display: "block", margin: "4px", padding: "4px" }}>
|
||||
Black Operations (Black Ops) are special, one-time covert operations.
|
||||
Each Black Op must be unlocked successively by completing the one before
|
||||
it.
|
||||
Black Operations (Black Ops) are special, one-time covert operations. Each Black Op must be unlocked
|
||||
successively by completing the one before it.
|
||||
<br />
|
||||
<br />
|
||||
<b>
|
||||
Your ultimate goal to climb through the ranks of Bladeburners is to
|
||||
complete all of the Black Ops.
|
||||
</b>
|
||||
<b>Your ultimate goal to climb through the ranks of Bladeburners is to complete all of the Black Ops.</b>
|
||||
<br />
|
||||
<br />
|
||||
Like normal operations, you may use a team for Black Ops. Failing a
|
||||
black op will incur heavy HP and rank losses.
|
||||
Like normal operations, you may use a team for Black Ops. Failing a black op will incur heavy HP and rank
|
||||
losses.
|
||||
</p>
|
||||
<BlackOpList bladeburner={props.bladeburner} player={props.player} />
|
||||
</>
|
||||
|
@ -10,10 +10,7 @@ interface ILineProps {
|
||||
function Line(props: ILineProps): React.ReactElement {
|
||||
return (
|
||||
<tr>
|
||||
<td
|
||||
className="bladeburner-console-line"
|
||||
style={{ color: "var(--my-font-color)", whiteSpace: "pre-wrap" }}
|
||||
>
|
||||
<td className="bladeburner-console-line" style={{ color: "var(--my-font-color)", whiteSpace: "pre-wrap" }}>
|
||||
{props.content}
|
||||
</td>
|
||||
</tr>
|
||||
@ -29,9 +26,7 @@ export function Console(props: IProps): React.ReactElement {
|
||||
const lastRef = useRef<HTMLDivElement>(null);
|
||||
const setRerender = useState(false)[1];
|
||||
|
||||
const [consoleHistoryIndex, setConsoleHistoryIndex] = useState(
|
||||
props.bladeburner.consoleHistory.length,
|
||||
);
|
||||
const [consoleHistoryIndex, setConsoleHistoryIndex] = useState(props.bladeburner.consoleHistory.length);
|
||||
|
||||
// TODO: Figure out how to actually make the scrolling work correctly.
|
||||
function scrollToBottom(): void {
|
||||
@ -121,11 +116,7 @@ export function Console(props: IProps): React.ReactElement {
|
||||
{props.bladeburner.consoleLogs.map((log: any, i: number) => (
|
||||
<Line key={i} content={log} />
|
||||
))}
|
||||
<tr
|
||||
key="input"
|
||||
id="bladeburner-console-input-row"
|
||||
className="bladeburner-console-input-row"
|
||||
>
|
||||
<tr key="input" id="bladeburner-console-input-row" className="bladeburner-console-input-row">
|
||||
<td className="bladeburner-console-input-cell">
|
||||
<pre>{"> "}</pre>
|
||||
<input
|
||||
|
@ -1,10 +1,7 @@
|
||||
import React, { useState } from "react";
|
||||
import { ActionTypes } from "../data/ActionTypes";
|
||||
import { createProgressBarText } from "../../../utils/helpers/createProgressBarText";
|
||||
import {
|
||||
formatNumber,
|
||||
convertTimeMsToTimeElapsedString,
|
||||
} from "../../../utils/StringHelperFunctions";
|
||||
import { formatNumber, convertTimeMsToTimeElapsedString } from "../../../utils/StringHelperFunctions";
|
||||
import { stealthIcon, killIcon } from "../data/Icons";
|
||||
import { BladeburnerConstants } from "../data/Constants";
|
||||
import { IBladeburner } from "../IBladeburner";
|
||||
@ -21,11 +18,8 @@ interface IProps {
|
||||
export function ContractElem(props: IProps): React.ReactElement {
|
||||
const setRerender = useState(false)[1];
|
||||
const isActive =
|
||||
props.bladeburner.action.type === ActionTypes["Contract"] &&
|
||||
props.action.name === props.bladeburner.action.name;
|
||||
const estimatedSuccessChance = props.action.getEstSuccessChance(
|
||||
props.bladeburner,
|
||||
);
|
||||
props.bladeburner.action.type === ActionTypes["Contract"] && props.action.name === props.bladeburner.action.name;
|
||||
const estimatedSuccessChance = props.action.getEstSuccessChance(props.bladeburner);
|
||||
const computedActionTimeCurrent = Math.min(
|
||||
props.bladeburner.actionTimeCurrent + props.bladeburner.actionTimeOverflow,
|
||||
props.bladeburner.actionTimeToComplete,
|
||||
@ -43,15 +37,13 @@ export function ContractElem(props: IProps): React.ReactElement {
|
||||
|
||||
function increaseLevel(): void {
|
||||
++props.action.level;
|
||||
if (isActive)
|
||||
props.bladeburner.startAction(props.player, props.bladeburner.action);
|
||||
if (isActive) props.bladeburner.startAction(props.player, props.bladeburner.action);
|
||||
setRerender((old) => !old);
|
||||
}
|
||||
|
||||
function decreaseLevel(): void {
|
||||
--props.action.level;
|
||||
if (isActive)
|
||||
props.bladeburner.startAction(props.player, props.bladeburner.action);
|
||||
if (isActive) props.bladeburner.startAction(props.player, props.bladeburner.action);
|
||||
setRerender((old) => !old);
|
||||
}
|
||||
|
||||
@ -65,8 +57,7 @@ export function ContractElem(props: IProps): React.ReactElement {
|
||||
<h2 style={{ display: "inline-block" }}>
|
||||
{isActive ? (
|
||||
<>
|
||||
<CopyableText value={props.action.name} /> (IN PROGRESS -{" "}
|
||||
{formatNumber(computedActionTimeCurrent, 0)} /{" "}
|
||||
<CopyableText value={props.action.name} /> (IN PROGRESS - {formatNumber(computedActionTimeCurrent, 0)} /{" "}
|
||||
{formatNumber(props.bladeburner.actionTimeToComplete, 0)})
|
||||
</>
|
||||
) : (
|
||||
@ -76,18 +67,12 @@ export function ContractElem(props: IProps): React.ReactElement {
|
||||
{isActive ? (
|
||||
<p style={{ display: "block" }}>
|
||||
{createProgressBarText({
|
||||
progress:
|
||||
computedActionTimeCurrent /
|
||||
props.bladeburner.actionTimeToComplete,
|
||||
progress: computedActionTimeCurrent / props.bladeburner.actionTimeToComplete,
|
||||
})}
|
||||
</p>
|
||||
) : (
|
||||
<>
|
||||
<a
|
||||
onClick={onStart}
|
||||
className="a-link-button"
|
||||
style={{ margin: "3px", padding: "3px" }}
|
||||
>
|
||||
<a onClick={onStart} className="a-link-button" style={{ margin: "3px", padding: "3px" }}>
|
||||
Start
|
||||
</a>
|
||||
</>
|
||||
@ -96,40 +81,24 @@ export function ContractElem(props: IProps): React.ReactElement {
|
||||
<br />
|
||||
<pre className="tooltip" style={{ display: "inline-block" }}>
|
||||
<span className="tooltiptext">
|
||||
{props.action.getSuccessesNeededForNextLevel(
|
||||
BladeburnerConstants.ContractSuccessesPerLevel,
|
||||
)}{" "}
|
||||
successes needed for next level
|
||||
{props.action.getSuccessesNeededForNextLevel(BladeburnerConstants.ContractSuccessesPerLevel)} successes needed
|
||||
for next level
|
||||
</span>
|
||||
Level: {props.action.level} / {props.action.maxLevel}
|
||||
</pre>
|
||||
<a
|
||||
onClick={increaseLevel}
|
||||
style={{ padding: "2px", margin: "2px" }}
|
||||
className={`tooltip ${
|
||||
maxLevel ? "a-link-button-inactive" : "a-link-button"
|
||||
}`}
|
||||
className={`tooltip ${maxLevel ? "a-link-button-inactive" : "a-link-button"}`}
|
||||
>
|
||||
{isActive && (
|
||||
<span className="tooltiptext">
|
||||
WARNING: changing the level will restart the Operation
|
||||
</span>
|
||||
)}
|
||||
↑
|
||||
{isActive && <span className="tooltiptext">WARNING: changing the level will restart the Operation</span>}↑
|
||||
</a>
|
||||
<a
|
||||
onClick={decreaseLevel}
|
||||
style={{ padding: "2px", margin: "2px" }}
|
||||
className={`tooltip ${
|
||||
props.action.level <= 1 ? "a-link-button-inactive" : "a-link-button"
|
||||
}`}
|
||||
className={`tooltip ${props.action.level <= 1 ? "a-link-button-inactive" : "a-link-button"}`}
|
||||
>
|
||||
{isActive && (
|
||||
<span className="tooltiptext">
|
||||
WARNING: changing the level will restart the Operation
|
||||
</span>
|
||||
)}
|
||||
↓
|
||||
{isActive && <span className="tooltiptext">WARNING: changing the level will restart the Operation</span>}↓
|
||||
</a>
|
||||
<br />
|
||||
<br />
|
||||
@ -137,8 +106,7 @@ export function ContractElem(props: IProps): React.ReactElement {
|
||||
<span dangerouslySetInnerHTML={{ __html: props.action.desc }} />
|
||||
<br />
|
||||
<br />
|
||||
Estimated success chance:{" "}
|
||||
<SuccessChance chance={estimatedSuccessChance} />{" "}
|
||||
Estimated success chance: <SuccessChance chance={estimatedSuccessChance} />{" "}
|
||||
{props.action.isStealth ? stealthIcon : <></>}
|
||||
{props.action.isKill ? killIcon : <></>}
|
||||
<br />
|
||||
@ -151,22 +119,11 @@ export function ContractElem(props: IProps): React.ReactElement {
|
||||
Failures: {props.action.failures}
|
||||
</pre>
|
||||
<br />
|
||||
<label
|
||||
className="tooltip"
|
||||
style={{ color: "white" }}
|
||||
htmlFor={autolevelCheckboxId}
|
||||
>
|
||||
<label className="tooltip" style={{ color: "white" }} htmlFor={autolevelCheckboxId}>
|
||||
Autolevel:
|
||||
<span className="tooltiptext">
|
||||
Automatically increase operation level when possible
|
||||
</span>
|
||||
<span className="tooltiptext">Automatically increase operation level when possible</span>
|
||||
</label>
|
||||
<input
|
||||
type="checkbox"
|
||||
id={autolevelCheckboxId}
|
||||
checked={props.action.autoLevel}
|
||||
onChange={onAutolevel}
|
||||
/>
|
||||
<input type="checkbox" id={autolevelCheckboxId} checked={props.action.autoLevel} onChange={onAutolevel} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
@ -15,11 +15,7 @@ export function ContractList(props: IProps): React.ReactElement {
|
||||
<>
|
||||
{names.map((name: string) => (
|
||||
<li key={name} className="bladeburner-action">
|
||||
<ContractElem
|
||||
bladeburner={props.bladeburner}
|
||||
action={contracts[name]}
|
||||
player={props.player}
|
||||
/>
|
||||
<ContractElem bladeburner={props.bladeburner} action={contracts[name]} player={props.player} />
|
||||
</li>
|
||||
))}
|
||||
</>
|
||||
|
@ -12,14 +12,12 @@ export function ContractPage(props: IProps): React.ReactElement {
|
||||
return (
|
||||
<>
|
||||
<p style={{ display: "block", margin: "4px", padding: "4px" }}>
|
||||
Complete contracts in order to increase your Bladeburner rank and earn
|
||||
money. Failing a contract will cause you to lose HP, which can lead to
|
||||
hospitalization.
|
||||
Complete contracts in order to increase your Bladeburner rank and earn money. Failing a contract will cause you
|
||||
to lose HP, which can lead to hospitalization.
|
||||
<br />
|
||||
<br />
|
||||
You can unlock higher-level contracts by successfully completing them.
|
||||
Higher-level contracts are more difficult, but grant more rank,
|
||||
experience, and money.
|
||||
You can unlock higher-level contracts by successfully completing them. Higher-level contracts are more
|
||||
difficult, but grant more rank, experience, and money.
|
||||
</p>
|
||||
<ContractList bladeburner={props.bladeburner} player={props.player} />
|
||||
</>
|
||||
|
@ -1,10 +1,7 @@
|
||||
import React, { useState } from "react";
|
||||
import { ActionTypes } from "../data/ActionTypes";
|
||||
import { createProgressBarText } from "../../../utils/helpers/createProgressBarText";
|
||||
import {
|
||||
formatNumber,
|
||||
convertTimeMsToTimeElapsedString,
|
||||
} from "../../../utils/StringHelperFunctions";
|
||||
import { formatNumber, convertTimeMsToTimeElapsedString } from "../../../utils/StringHelperFunctions";
|
||||
import { IBladeburner } from "../IBladeburner";
|
||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||
import { CopyableText } from "../../ui/React/CopyableText";
|
||||
@ -37,13 +34,7 @@ export function GeneralActionElem(props: IProps): React.ReactElement {
|
||||
})();
|
||||
const successChance =
|
||||
props.action.name === "Recruitment"
|
||||
? Math.max(
|
||||
0,
|
||||
Math.min(
|
||||
props.bladeburner.getRecruitmentSuccessChance(props.player),
|
||||
1,
|
||||
),
|
||||
)
|
||||
? Math.max(0, Math.min(props.bladeburner.getRecruitmentSuccessChance(props.player), 1))
|
||||
: -1;
|
||||
|
||||
function onStart(): void {
|
||||
@ -58,8 +49,7 @@ export function GeneralActionElem(props: IProps): React.ReactElement {
|
||||
<h2 style={{ display: "inline-block" }}>
|
||||
{isActive ? (
|
||||
<>
|
||||
<CopyableText value={props.action.name} /> (IN PROGRESS -{" "}
|
||||
{formatNumber(computedActionTimeCurrent, 0)} /{" "}
|
||||
<CopyableText value={props.action.name} /> (IN PROGRESS - {formatNumber(computedActionTimeCurrent, 0)} /{" "}
|
||||
{formatNumber(props.bladeburner.actionTimeToComplete, 0)})
|
||||
</>
|
||||
) : (
|
||||
@ -69,28 +59,19 @@ export function GeneralActionElem(props: IProps): React.ReactElement {
|
||||
{isActive ? (
|
||||
<p style={{ display: "block" }}>
|
||||
{createProgressBarText({
|
||||
progress:
|
||||
computedActionTimeCurrent /
|
||||
props.bladeburner.actionTimeToComplete,
|
||||
progress: computedActionTimeCurrent / props.bladeburner.actionTimeToComplete,
|
||||
})}
|
||||
</p>
|
||||
) : (
|
||||
<>
|
||||
<a
|
||||
onClick={onStart}
|
||||
className="a-link-button"
|
||||
style={{ margin: "3px", padding: "3px" }}
|
||||
>
|
||||
<a onClick={onStart} className="a-link-button" style={{ margin: "3px", padding: "3px" }}>
|
||||
Start
|
||||
</a>
|
||||
</>
|
||||
)}
|
||||
<br />
|
||||
<br />
|
||||
<pre
|
||||
style={{ display: "inline-block" }}
|
||||
dangerouslySetInnerHTML={{ __html: props.action.desc }}
|
||||
></pre>
|
||||
<pre style={{ display: "inline-block" }} dangerouslySetInnerHTML={{ __html: props.action.desc }}></pre>
|
||||
<br />
|
||||
<br />
|
||||
<pre style={{ display: "inline-block" }}>
|
||||
|
@ -21,11 +21,7 @@ export function GeneralActionList(props: IProps): React.ReactElement {
|
||||
<>
|
||||
{actions.map((action: Action) => (
|
||||
<li key={action.name} className="bladeburner-action">
|
||||
<GeneralActionElem
|
||||
bladeburner={props.bladeburner}
|
||||
action={action}
|
||||
player={props.player}
|
||||
/>
|
||||
<GeneralActionElem bladeburner={props.bladeburner} action={action} player={props.player} />
|
||||
</li>
|
||||
))}
|
||||
</>
|
||||
|
@ -12,13 +12,10 @@ export function GeneralActionPage(props: IProps): React.ReactElement {
|
||||
return (
|
||||
<>
|
||||
<p style={{ display: "block", margin: "4px", padding: "4px" }}>
|
||||
These are generic actions that will assist you in your Bladeburner
|
||||
duties. They will not affect your Bladeburner rank in any way.
|
||||
These are generic actions that will assist you in your Bladeburner duties. They will not affect your Bladeburner
|
||||
rank in any way.
|
||||
</p>
|
||||
<GeneralActionList
|
||||
bladeburner={props.bladeburner}
|
||||
player={props.player}
|
||||
/>
|
||||
<GeneralActionList bladeburner={props.bladeburner} player={props.player} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
@ -1,10 +1,7 @@
|
||||
import React, { useState } from "react";
|
||||
import { ActionTypes } from "../data/ActionTypes";
|
||||
import { createProgressBarText } from "../../../utils/helpers/createProgressBarText";
|
||||
import {
|
||||
formatNumber,
|
||||
convertTimeMsToTimeElapsedString,
|
||||
} from "../../../utils/StringHelperFunctions";
|
||||
import { formatNumber, convertTimeMsToTimeElapsedString } from "../../../utils/StringHelperFunctions";
|
||||
import { stealthIcon, killIcon } from "../data/Icons";
|
||||
import { BladeburnerConstants } from "../data/Constants";
|
||||
import { createPopup } from "../../ui/React/createPopup";
|
||||
@ -23,11 +20,8 @@ interface IProps {
|
||||
export function OperationElem(props: IProps): React.ReactElement {
|
||||
const setRerender = useState(false)[1];
|
||||
const isActive =
|
||||
props.bladeburner.action.type === ActionTypes["Operation"] &&
|
||||
props.action.name === props.bladeburner.action.name;
|
||||
const estimatedSuccessChance = props.action.getEstSuccessChance(
|
||||
props.bladeburner,
|
||||
);
|
||||
props.bladeburner.action.type === ActionTypes["Operation"] && props.action.name === props.bladeburner.action.name;
|
||||
const estimatedSuccessChance = props.action.getEstSuccessChance(props.bladeburner);
|
||||
const computedActionTimeCurrent = Math.min(
|
||||
props.bladeburner.actionTimeCurrent + props.bladeburner.actionTimeOverflow,
|
||||
props.bladeburner.actionTimeToComplete,
|
||||
@ -54,15 +48,13 @@ export function OperationElem(props: IProps): React.ReactElement {
|
||||
|
||||
function increaseLevel(): void {
|
||||
++props.action.level;
|
||||
if (isActive)
|
||||
props.bladeburner.startAction(props.player, props.bladeburner.action);
|
||||
if (isActive) props.bladeburner.startAction(props.player, props.bladeburner.action);
|
||||
setRerender((old) => !old);
|
||||
}
|
||||
|
||||
function decreaseLevel(): void {
|
||||
--props.action.level;
|
||||
if (isActive)
|
||||
props.bladeburner.startAction(props.player, props.bladeburner.action);
|
||||
if (isActive) props.bladeburner.startAction(props.player, props.bladeburner.action);
|
||||
setRerender((old) => !old);
|
||||
}
|
||||
|
||||
@ -76,8 +68,7 @@ export function OperationElem(props: IProps): React.ReactElement {
|
||||
<h2 style={{ display: "inline-block" }}>
|
||||
{isActive ? (
|
||||
<>
|
||||
<CopyableText value={props.action.name} /> (IN PROGRESS -{" "}
|
||||
{formatNumber(computedActionTimeCurrent, 0)} /{" "}
|
||||
<CopyableText value={props.action.name} /> (IN PROGRESS - {formatNumber(computedActionTimeCurrent, 0)} /{" "}
|
||||
{formatNumber(props.bladeburner.actionTimeToComplete, 0)})
|
||||
</>
|
||||
) : (
|
||||
@ -87,25 +78,15 @@ export function OperationElem(props: IProps): React.ReactElement {
|
||||
{isActive ? (
|
||||
<p style={{ display: "block" }}>
|
||||
{createProgressBarText({
|
||||
progress:
|
||||
computedActionTimeCurrent /
|
||||
props.bladeburner.actionTimeToComplete,
|
||||
progress: computedActionTimeCurrent / props.bladeburner.actionTimeToComplete,
|
||||
})}
|
||||
</p>
|
||||
) : (
|
||||
<>
|
||||
<a
|
||||
onClick={onStart}
|
||||
className="a-link-button"
|
||||
style={{ margin: "3px", padding: "3px" }}
|
||||
>
|
||||
<a onClick={onStart} className="a-link-button" style={{ margin: "3px", padding: "3px" }}>
|
||||
Start
|
||||
</a>
|
||||
<a
|
||||
onClick={onTeam}
|
||||
style={{ margin: "3px", padding: "3px" }}
|
||||
className="a-link-button"
|
||||
>
|
||||
<a onClick={onTeam} style={{ margin: "3px", padding: "3px" }} className="a-link-button">
|
||||
Set Team Size (Curr Size: {formatNumber(props.action.teamCount, 0)})
|
||||
</a>
|
||||
</>
|
||||
@ -114,40 +95,24 @@ export function OperationElem(props: IProps): React.ReactElement {
|
||||
<br />
|
||||
<pre className="tooltip" style={{ display: "inline-block" }}>
|
||||
<span className="tooltiptext">
|
||||
{props.action.getSuccessesNeededForNextLevel(
|
||||
BladeburnerConstants.OperationSuccessesPerLevel,
|
||||
)}{" "}
|
||||
successes needed for next level
|
||||
{props.action.getSuccessesNeededForNextLevel(BladeburnerConstants.OperationSuccessesPerLevel)} successes
|
||||
needed for next level
|
||||
</span>
|
||||
Level: {props.action.level} / {props.action.maxLevel}
|
||||
</pre>
|
||||
<a
|
||||
onClick={increaseLevel}
|
||||
style={{ padding: "2px", margin: "2px" }}
|
||||
className={`tooltip ${
|
||||
maxLevel ? "a-link-button-inactive" : "a-link-button"
|
||||
}`}
|
||||
className={`tooltip ${maxLevel ? "a-link-button-inactive" : "a-link-button"}`}
|
||||
>
|
||||
{isActive && (
|
||||
<span className="tooltiptext">
|
||||
WARNING: changing the level will restart the Operation
|
||||
</span>
|
||||
)}
|
||||
↑
|
||||
{isActive && <span className="tooltiptext">WARNING: changing the level will restart the Operation</span>}↑
|
||||
</a>
|
||||
<a
|
||||
onClick={decreaseLevel}
|
||||
style={{ padding: "2px", margin: "2px" }}
|
||||
className={`tooltip ${
|
||||
props.action.level <= 1 ? "a-link-button-inactive" : "a-link-button"
|
||||
}`}
|
||||
className={`tooltip ${props.action.level <= 1 ? "a-link-button-inactive" : "a-link-button"}`}
|
||||
>
|
||||
{isActive && (
|
||||
<span className="tooltiptext">
|
||||
WARNING: changing the level will restart the Operation
|
||||
</span>
|
||||
)}
|
||||
↓
|
||||
{isActive && <span className="tooltiptext">WARNING: changing the level will restart the Operation</span>}↓
|
||||
</a>
|
||||
<br />
|
||||
<br />
|
||||
@ -155,8 +120,7 @@ export function OperationElem(props: IProps): React.ReactElement {
|
||||
<span dangerouslySetInnerHTML={{ __html: props.action.desc }} />
|
||||
<br />
|
||||
<br />
|
||||
Estimated success chance:{" "}
|
||||
<SuccessChance chance={estimatedSuccessChance} />{" "}
|
||||
Estimated success chance: <SuccessChance chance={estimatedSuccessChance} />{" "}
|
||||
{props.action.isStealth ? stealthIcon : <></>}
|
||||
{props.action.isKill ? killIcon : <></>}
|
||||
<br />
|
||||
@ -169,22 +133,11 @@ export function OperationElem(props: IProps): React.ReactElement {
|
||||
Failures: {props.action.failures}
|
||||
</pre>
|
||||
<br />
|
||||
<label
|
||||
className="tooltip"
|
||||
style={{ color: "white" }}
|
||||
htmlFor={autolevelCheckboxId}
|
||||
>
|
||||
<label className="tooltip" style={{ color: "white" }} htmlFor={autolevelCheckboxId}>
|
||||
Autolevel:
|
||||
<span className="tooltiptext">
|
||||
Automatically increase operation level when possible
|
||||
</span>
|
||||
<span className="tooltiptext">Automatically increase operation level when possible</span>
|
||||
</label>
|
||||
<input
|
||||
type="checkbox"
|
||||
id={autolevelCheckboxId}
|
||||
checked={props.action.autoLevel}
|
||||
onChange={onAutolevel}
|
||||
/>
|
||||
<input type="checkbox" id={autolevelCheckboxId} checked={props.action.autoLevel} onChange={onAutolevel} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
@ -15,11 +15,7 @@ export function OperationList(props: IProps): React.ReactElement {
|
||||
<>
|
||||
{names.map((name: string) => (
|
||||
<li key={name} className="bladeburner-action">
|
||||
<OperationElem
|
||||
bladeburner={props.bladeburner}
|
||||
action={operations[name]}
|
||||
player={props.player}
|
||||
/>
|
||||
<OperationElem bladeburner={props.bladeburner} action={operations[name]} player={props.player} />
|
||||
</li>
|
||||
))}
|
||||
</>
|
||||
|
@ -12,23 +12,21 @@ export function OperationPage(props: IProps): React.ReactElement {
|
||||
return (
|
||||
<>
|
||||
<p style={{ display: "block", margin: "4px", padding: "4px" }}>
|
||||
Carry out operations for the Bladeburner division. Failing an operation
|
||||
will reduce your Bladeburner rank. It will also cause you to lose HP,
|
||||
which can lead to hospitalization. In general, operations are harder and
|
||||
more punishing than contracts, but are also more rewarding.
|
||||
Carry out operations for the Bladeburner division. Failing an operation will reduce your Bladeburner rank. It
|
||||
will also cause you to lose HP, which can lead to hospitalization. In general, operations are harder and more
|
||||
punishing than contracts, but are also more rewarding.
|
||||
<br />
|
||||
<br />
|
||||
Operations can affect the chaos level and Synthoid population of your
|
||||
current city. The exact effects vary between different Operations.
|
||||
Operations can affect the chaos level and Synthoid population of your current city. The exact effects vary
|
||||
between different Operations.
|
||||
<br />
|
||||
<br />
|
||||
For operations, you can use a team. You must first recruit team members.
|
||||
Having a larger team will improves your chances of success.
|
||||
For operations, you can use a team. You must first recruit team members. Having a larger team will improves your
|
||||
chances of success.
|
||||
<br />
|
||||
<br />
|
||||
You can unlock higher-level operations by successfully completing them.
|
||||
Higher-level operations are more difficult, but grant more rank and
|
||||
experience.
|
||||
You can unlock higher-level operations by successfully completing them. Higher-level operations are more
|
||||
difficult, but grant more rank and experience.
|
||||
</p>
|
||||
<OperationList bladeburner={props.bladeburner} player={props.player} />
|
||||
</>
|
||||
|
@ -25,11 +25,7 @@ export function Root(props: IProps): React.ReactElement {
|
||||
border: "1px solid white",
|
||||
}}
|
||||
>
|
||||
<Stats
|
||||
bladeburner={props.bladeburner}
|
||||
player={props.player}
|
||||
engine={props.engine}
|
||||
/>
|
||||
<Stats bladeburner={props.bladeburner} player={props.player} engine={props.engine} />
|
||||
</div>
|
||||
<Console bladeburner={props.bladeburner} player={props.player} />
|
||||
</div>
|
||||
|
@ -12,18 +12,13 @@ interface IProps {
|
||||
export function SkillElem(props: IProps): React.ReactElement {
|
||||
const skillName = props.skill.name;
|
||||
let currentLevel = 0;
|
||||
if (
|
||||
props.bladeburner.skills[skillName] &&
|
||||
!isNaN(props.bladeburner.skills[skillName])
|
||||
) {
|
||||
if (props.bladeburner.skills[skillName] && !isNaN(props.bladeburner.skills[skillName])) {
|
||||
currentLevel = props.bladeburner.skills[skillName];
|
||||
}
|
||||
const pointCost = props.skill.calculateCost(currentLevel);
|
||||
|
||||
const canLevel = props.bladeburner.skillPoints >= pointCost;
|
||||
const maxLvl = props.skill.maxLvl
|
||||
? currentLevel >= props.skill.maxLvl
|
||||
: false;
|
||||
const maxLvl = props.skill.maxLvl ? currentLevel >= props.skill.maxLvl : false;
|
||||
|
||||
function onClick(): void {
|
||||
if (props.bladeburner.skillPoints < pointCost) return;
|
||||
@ -40,9 +35,7 @@ export function SkillElem(props: IProps): React.ReactElement {
|
||||
<a
|
||||
onClick={onClick}
|
||||
style={{ display: "inline-block", margin: "3px", padding: "3px" }}
|
||||
className={
|
||||
canLevel && !maxLvl ? "a-link-button" : "a-link-button-inactive"
|
||||
}
|
||||
className={canLevel && !maxLvl ? "a-link-button" : "a-link-button-inactive"}
|
||||
>
|
||||
Level
|
||||
</a>
|
||||
@ -52,14 +45,9 @@ export function SkillElem(props: IProps): React.ReactElement {
|
||||
{maxLvl ? (
|
||||
<p style={{ color: "red", display: "block" }}>MAX LEVEL</p>
|
||||
) : (
|
||||
<p style={{ display: "block" }}>
|
||||
Skill Points required: {formatNumber(pointCost, 0)}
|
||||
</p>
|
||||
<p style={{ display: "block" }}>Skill Points required: {formatNumber(pointCost, 0)}</p>
|
||||
)}
|
||||
<p
|
||||
style={{ display: "inline-block" }}
|
||||
dangerouslySetInnerHTML={{ __html: props.skill.desc }}
|
||||
/>
|
||||
<p style={{ display: "inline-block" }} dangerouslySetInnerHTML={{ __html: props.skill.desc }} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
@ -13,11 +13,7 @@ export function SkillList(props: IProps): React.ReactElement {
|
||||
<>
|
||||
{Object.keys(Skills).map((skill: string) => (
|
||||
<li key={skill} className="bladeburner-action">
|
||||
<SkillElem
|
||||
bladeburner={props.bladeburner}
|
||||
skill={Skills[skill]}
|
||||
onUpgrade={props.onUpgrade}
|
||||
/>
|
||||
<SkillElem bladeburner={props.bladeburner} skill={Skills[skill]} onUpgrade={props.onUpgrade} />
|
||||
</li>
|
||||
))}
|
||||
</>
|
||||
|
@ -19,94 +19,46 @@ export function SkillPage(props: IProps): React.ReactElement {
|
||||
return (
|
||||
<>
|
||||
<p>
|
||||
<strong>
|
||||
Skill Points: {formatNumber(props.bladeburner.skillPoints, 0)}
|
||||
</strong>
|
||||
<strong>Skill Points: {formatNumber(props.bladeburner.skillPoints, 0)}</strong>
|
||||
</p>
|
||||
<p>
|
||||
You will gain one skill point every{" "}
|
||||
{BladeburnerConstants.RanksPerSkillPoint} ranks.
|
||||
You will gain one skill point every {BladeburnerConstants.RanksPerSkillPoint} ranks.
|
||||
<br />
|
||||
<br />
|
||||
Note that when upgrading a skill, the benefit for that skill is
|
||||
additive. However, the effects of different skills with each other is
|
||||
multiplicative.
|
||||
Note that when upgrading a skill, the benefit for that skill is additive. However, the effects of different
|
||||
skills with each other is multiplicative.
|
||||
<br />
|
||||
</p>
|
||||
<br />
|
||||
{valid(mults["successChanceAll"]) && (
|
||||
<p>
|
||||
Total Success Chance: x{formatNumber(mults["successChanceAll"], 3)}
|
||||
</p>
|
||||
)}
|
||||
{valid(mults["successChanceAll"]) && <p>Total Success Chance: x{formatNumber(mults["successChanceAll"], 3)}</p>}
|
||||
{valid(mults["successChanceStealth"]) && (
|
||||
<p>
|
||||
Stealth Success Chance: x
|
||||
{formatNumber(mults["successChanceStealth"], 3)}
|
||||
</p>
|
||||
<p>Stealth Success Chance: x{formatNumber(mults["successChanceStealth"], 3)}</p>
|
||||
)}
|
||||
{valid(mults["successChanceKill"]) && (
|
||||
<p>
|
||||
Retirement Success Chance: x
|
||||
{formatNumber(mults["successChanceKill"], 3)}
|
||||
</p>
|
||||
<p>Retirement Success Chance: x{formatNumber(mults["successChanceKill"], 3)}</p>
|
||||
)}
|
||||
{valid(mults["successChanceContract"]) && (
|
||||
<p>
|
||||
Contract Success Chance: x
|
||||
{formatNumber(mults["successChanceContract"], 3)}
|
||||
</p>
|
||||
<p>Contract Success Chance: x{formatNumber(mults["successChanceContract"], 3)}</p>
|
||||
)}
|
||||
{valid(mults["successChanceOperation"]) && (
|
||||
<p>
|
||||
Operation Success Chance: x
|
||||
{formatNumber(mults["successChanceOperation"], 3)}
|
||||
</p>
|
||||
<p>Operation Success Chance: x{formatNumber(mults["successChanceOperation"], 3)}</p>
|
||||
)}
|
||||
{valid(mults["successChanceEstimate"]) && (
|
||||
<p>
|
||||
Synthoid Data Estimate: x
|
||||
{formatNumber(mults["successChanceEstimate"], 3)}
|
||||
</p>
|
||||
)}
|
||||
{valid(mults["actionTime"]) && (
|
||||
<p>Action Time: x{formatNumber(mults["actionTime"], 3)}</p>
|
||||
)}
|
||||
{valid(mults["effHack"]) && (
|
||||
<p>Hacking Skill: x{formatNumber(mults["effHack"], 3)}</p>
|
||||
)}
|
||||
{valid(mults["effStr"]) && (
|
||||
<p>Strength: x{formatNumber(mults["effStr"], 3)}</p>
|
||||
)}
|
||||
{valid(mults["effDef"]) && (
|
||||
<p>Defense: x{formatNumber(mults["effDef"], 3)}</p>
|
||||
)}
|
||||
{valid(mults["effDex"]) && (
|
||||
<p>Dexterity: x{formatNumber(mults["effDex"], 3)}</p>
|
||||
)}
|
||||
{valid(mults["effAgi"]) && (
|
||||
<p>Agility: x{formatNumber(mults["effAgi"], 3)}</p>
|
||||
)}
|
||||
{valid(mults["effCha"]) && (
|
||||
<p>Charisma: x{formatNumber(mults["effCha"], 3)}</p>
|
||||
)}
|
||||
{valid(mults["effInt"]) && (
|
||||
<p>Intelligence: x{formatNumber(mults["effInt"], 3)}</p>
|
||||
)}
|
||||
{valid(mults["stamina"]) && (
|
||||
<p>Stamina: x{formatNumber(mults["stamina"], 3)}</p>
|
||||
)}
|
||||
{valid(mults["money"]) && (
|
||||
<p>Contract Money: x{formatNumber(mults["money"], 3)}</p>
|
||||
)}
|
||||
{valid(mults["expGain"]) && (
|
||||
<p>Exp Gain: x{formatNumber(mults["expGain"], 3)}</p>
|
||||
<p>Synthoid Data Estimate: x{formatNumber(mults["successChanceEstimate"], 3)}</p>
|
||||
)}
|
||||
{valid(mults["actionTime"]) && <p>Action Time: x{formatNumber(mults["actionTime"], 3)}</p>}
|
||||
{valid(mults["effHack"]) && <p>Hacking Skill: x{formatNumber(mults["effHack"], 3)}</p>}
|
||||
{valid(mults["effStr"]) && <p>Strength: x{formatNumber(mults["effStr"], 3)}</p>}
|
||||
{valid(mults["effDef"]) && <p>Defense: x{formatNumber(mults["effDef"], 3)}</p>}
|
||||
{valid(mults["effDex"]) && <p>Dexterity: x{formatNumber(mults["effDex"], 3)}</p>}
|
||||
{valid(mults["effAgi"]) && <p>Agility: x{formatNumber(mults["effAgi"], 3)}</p>}
|
||||
{valid(mults["effCha"]) && <p>Charisma: x{formatNumber(mults["effCha"], 3)}</p>}
|
||||
{valid(mults["effInt"]) && <p>Intelligence: x{formatNumber(mults["effInt"], 3)}</p>}
|
||||
{valid(mults["stamina"]) && <p>Stamina: x{formatNumber(mults["stamina"], 3)}</p>}
|
||||
{valid(mults["money"]) && <p>Contract Money: x{formatNumber(mults["money"], 3)}</p>}
|
||||
{valid(mults["expGain"]) && <p>Exp Gain: x{formatNumber(mults["expGain"], 3)}</p>}
|
||||
<br />
|
||||
<SkillList
|
||||
bladeburner={props.bladeburner}
|
||||
onUpgrade={() => setRerender((old) => !old)}
|
||||
/>
|
||||
<SkillList bladeburner={props.bladeburner} onUpgrade={() => setRerender((old) => !old)} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
@ -1,8 +1,5 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import {
|
||||
formatNumber,
|
||||
convertTimeMsToTimeElapsedString,
|
||||
} from "../../../utils/StringHelperFunctions";
|
||||
import { formatNumber, convertTimeMsToTimeElapsedString } from "../../../utils/StringHelperFunctions";
|
||||
import { BladeburnerConstants } from "../data/Constants";
|
||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||
import { IEngine } from "../../IEngine";
|
||||
@ -12,10 +9,7 @@ import { numeralWrapper } from "../../ui/numeralFormat";
|
||||
import { dialogBoxCreate } from "../../../utils/DialogBox";
|
||||
import { createPopup } from "../../ui/React/createPopup";
|
||||
import { Factions } from "../../Faction/Factions";
|
||||
import {
|
||||
joinFaction,
|
||||
displayFactionContent,
|
||||
} from "../../Faction/FactionHelpers";
|
||||
import { joinFaction, displayFactionContent } from "../../Faction/FactionHelpers";
|
||||
import { IBladeburner } from "../IBladeburner";
|
||||
|
||||
import { TravelPopup } from "./TravelPopup";
|
||||
@ -83,13 +77,9 @@ export function Stats(props: IProps): React.ReactElement {
|
||||
} else {
|
||||
if (props.bladeburner.rank >= BladeburnerConstants.RankNeededForFaction) {
|
||||
joinFaction(faction);
|
||||
dialogBoxCreate(
|
||||
"Congratulations! You were accepted into the Bladeburners faction",
|
||||
);
|
||||
dialogBoxCreate("Congratulations! You were accepted into the Bladeburners faction");
|
||||
} else {
|
||||
dialogBoxCreate(
|
||||
"You need a rank of 25 to join the Bladeburners Faction!",
|
||||
);
|
||||
dialogBoxCreate("You need a rank of 25 to join the Bladeburners Faction!");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -98,46 +88,31 @@ export function Stats(props: IProps): React.ReactElement {
|
||||
<>
|
||||
<p className="tooltip" style={{ display: "inline-block" }}>
|
||||
Rank: {formatNumber(props.bladeburner.rank, 2)}
|
||||
<span className="tooltiptext">
|
||||
Your rank within the Bladeburner division.
|
||||
</span>
|
||||
<span className="tooltiptext">Your rank within the Bladeburner division.</span>
|
||||
</p>
|
||||
<br />
|
||||
<p>
|
||||
Stamina: {formatNumber(props.bladeburner.stamina, 3)} /{" "}
|
||||
{formatNumber(props.bladeburner.maxStamina, 3)}
|
||||
Stamina: {formatNumber(props.bladeburner.stamina, 3)} / {formatNumber(props.bladeburner.maxStamina, 3)}
|
||||
</p>
|
||||
<div className="help-tip" onClick={openStaminaHelp}>
|
||||
?
|
||||
</div>
|
||||
<br />
|
||||
<p>
|
||||
Stamina Penalty:{" "}
|
||||
{formatNumber(
|
||||
(1 - props.bladeburner.calculateStaminaPenalty()) * 100,
|
||||
1,
|
||||
)}
|
||||
%
|
||||
</p>
|
||||
<p>Stamina Penalty: {formatNumber((1 - props.bladeburner.calculateStaminaPenalty()) * 100, 1)}%</p>
|
||||
<br />
|
||||
<p>Team Size: {formatNumber(props.bladeburner.teamSize, 0)}</p>
|
||||
<p>Team Members Lost: {formatNumber(props.bladeburner.teamLost, 0)}</p>
|
||||
<br />
|
||||
<p>Num Times Hospitalized: {props.bladeburner.numHosp}</p>
|
||||
<p>
|
||||
Money Lost From Hospitalizations:{" "}
|
||||
<Money money={props.bladeburner.moneyLost} />
|
||||
Money Lost From Hospitalizations: <Money money={props.bladeburner.moneyLost} />
|
||||
</p>
|
||||
<br />
|
||||
<p>Current City: {props.bladeburner.city}</p>
|
||||
<p className="tooltip" style={{ display: "inline-block" }}>
|
||||
Est. Synthoid Population:{" "}
|
||||
{numeralWrapper.formatPopulation(
|
||||
props.bladeburner.getCurrentCity().popEst,
|
||||
)}
|
||||
Est. Synthoid Population: {numeralWrapper.formatPopulation(props.bladeburner.getCurrentCity().popEst)}
|
||||
<span className="tooltiptext">
|
||||
This is your Bladeburner division's estimate of how many Synthoids
|
||||
exist in your current city.
|
||||
This is your Bladeburner division's estimate of how many Synthoids exist in your current city.
|
||||
</span>
|
||||
</p>
|
||||
<div className="help-tip" onClick={openPopulationHelp}>
|
||||
@ -145,20 +120,17 @@ export function Stats(props: IProps): React.ReactElement {
|
||||
</div>
|
||||
<br />
|
||||
<p className="tooltip" style={{ display: "inline-block" }}>
|
||||
Est. Synthoid Communities:{" "}
|
||||
{formatNumber(props.bladeburner.getCurrentCity().comms, 0)}
|
||||
Est. Synthoid Communities: {formatNumber(props.bladeburner.getCurrentCity().comms, 0)}
|
||||
<span className="tooltiptext">
|
||||
This is your Bladeburner divison's estimate of how many Synthoid
|
||||
communities exist in your current city.
|
||||
This is your Bladeburner divison's estimate of how many Synthoid communities exist in your current city.
|
||||
</span>
|
||||
</p>
|
||||
<br />
|
||||
<p className="tooltip" style={{ display: "inline-block" }}>
|
||||
City Chaos: {formatNumber(props.bladeburner.getCurrentCity().chaos)}
|
||||
<span className="tooltiptext">
|
||||
The city's chaos level due to tensions and conflicts between humans
|
||||
and Synthoids. Having too high of a chaos level can make contracts and
|
||||
operations harder.
|
||||
The city's chaos level due to tensions and conflicts between humans and Synthoids. Having too high of a chaos
|
||||
level can make contracts and operations harder.
|
||||
</span>
|
||||
</p>
|
||||
<br />
|
||||
@ -166,56 +138,29 @@ export function Stats(props: IProps): React.ReactElement {
|
||||
<p className="tooltip" style={{ display: "inline-block" }}>
|
||||
Bonus time:{" "}
|
||||
{convertTimeMsToTimeElapsedString(
|
||||
(props.bladeburner.storedCycles /
|
||||
BladeburnerConstants.CyclesPerSecond) *
|
||||
1000,
|
||||
(props.bladeburner.storedCycles / BladeburnerConstants.CyclesPerSecond) * 1000,
|
||||
)}
|
||||
<br />
|
||||
<span className="tooltiptext">
|
||||
You gain bonus time while offline or when the game is inactive (e.g.
|
||||
when the tab is throttled by browser). Bonus time makes the
|
||||
Bladeburner mechanic progress faster, up to 5x the normal speed.
|
||||
You gain bonus time while offline or when the game is inactive (e.g. when the tab is throttled by browser).
|
||||
Bonus time makes the Bladeburner mechanic progress faster, up to 5x the normal speed.
|
||||
</span>
|
||||
</p>
|
||||
<p>Skill Points: {formatNumber(props.bladeburner.skillPoints, 0)}</p>
|
||||
<br />
|
||||
{StatsTable([
|
||||
[
|
||||
"Aug. Success Chance mult: ",
|
||||
formatNumber(props.player.bladeburner_success_chance_mult * 100, 1) +
|
||||
"%",
|
||||
],
|
||||
[
|
||||
"Aug. Max Stamina mult: ",
|
||||
formatNumber(props.player.bladeburner_max_stamina_mult * 100, 1) +
|
||||
"%",
|
||||
],
|
||||
[
|
||||
"Aug. Stamina Gain mult: ",
|
||||
formatNumber(props.player.bladeburner_stamina_gain_mult * 100, 1) +
|
||||
"%",
|
||||
],
|
||||
[
|
||||
"Aug. Field Analysis mult: ",
|
||||
formatNumber(props.player.bladeburner_analysis_mult * 100, 1) + "%",
|
||||
],
|
||||
["Aug. Success Chance mult: ", formatNumber(props.player.bladeburner_success_chance_mult * 100, 1) + "%"],
|
||||
["Aug. Max Stamina mult: ", formatNumber(props.player.bladeburner_max_stamina_mult * 100, 1) + "%"],
|
||||
["Aug. Stamina Gain mult: ", formatNumber(props.player.bladeburner_stamina_gain_mult * 100, 1) + "%"],
|
||||
["Aug. Field Analysis mult: ", formatNumber(props.player.bladeburner_analysis_mult * 100, 1) + "%"],
|
||||
])}
|
||||
<br />
|
||||
<a
|
||||
onClick={openTravel}
|
||||
className="a-link-button"
|
||||
style={{ display: "inline-block" }}
|
||||
>
|
||||
<a onClick={openTravel} className="a-link-button" style={{ display: "inline-block" }}>
|
||||
Travel
|
||||
</a>
|
||||
<a
|
||||
onClick={openFaction}
|
||||
className="a-link-button tooltip"
|
||||
style={{ display: "inline-block" }}
|
||||
>
|
||||
<a onClick={openFaction} className="a-link-button tooltip" style={{ display: "inline-block" }}>
|
||||
<span className="tooltiptext">
|
||||
Apply to the Bladeburner Faction, or go to the faction page if you are
|
||||
already a member
|
||||
Apply to the Bladeburner Faction, or go to the faction page if you are already a member
|
||||
</span>
|
||||
Faction
|
||||
</a>
|
||||
|
@ -12,8 +12,7 @@ export function SuccessChance(props: IProps): React.ReactElement {
|
||||
|
||||
return (
|
||||
<>
|
||||
{formatNumber(props.chance[0] * 100, 1)}% ~{" "}
|
||||
{formatNumber(props.chance[1] * 100, 1)}%
|
||||
{formatNumber(props.chance[0] * 100, 1)}% ~ {formatNumber(props.chance[1] * 100, 1)}%
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
@ -17,9 +17,7 @@ export function TeamSizePopup(props: IProps): React.ReactElement {
|
||||
if (teamSize === undefined) return;
|
||||
const num = Math.round(teamSize);
|
||||
if (isNaN(num) || num < 0) {
|
||||
dialogBoxCreate(
|
||||
"Invalid value entered for number of Team Members (must be numeric, positive)",
|
||||
);
|
||||
dialogBoxCreate("Invalid value entered for number of Team Members (must be numeric, positive)");
|
||||
} else {
|
||||
props.action.teamCount = num;
|
||||
}
|
||||
@ -29,10 +27,8 @@ export function TeamSizePopup(props: IProps): React.ReactElement {
|
||||
return (
|
||||
<>
|
||||
<p>
|
||||
Enter the amount of team members you would like to take on this Op. If
|
||||
you do not have the specified number of team members, then as many as
|
||||
possible will be used. Note that team members may be lost during
|
||||
operations.
|
||||
Enter the amount of team members you would like to take on this Op. If you do not have the specified number of
|
||||
team members, then as many as possible will be used. Note that team members may be lost during operations.
|
||||
</p>
|
||||
<input
|
||||
autoFocus
|
||||
|
@ -17,19 +17,14 @@ export function TravelPopup(props: IProps): React.ReactElement {
|
||||
return (
|
||||
<>
|
||||
<p>
|
||||
Travel to a different city for your Bladeburner activities. This does
|
||||
not cost any money. The city you are in for your Bladeburner duties does
|
||||
not affect your location in the game otherwise.
|
||||
Travel to a different city for your Bladeburner activities. This does not cost any money. The city you are in
|
||||
for your Bladeburner duties does not affect your location in the game otherwise.
|
||||
</p>
|
||||
{BladeburnerConstants.CityNames.map((city) => {
|
||||
// Reusing this css class...it adds a border and makes it
|
||||
// so that background color changes when you hover
|
||||
return (
|
||||
<div
|
||||
key={city}
|
||||
className="cmpy-mgmt-find-employee-option"
|
||||
onClick={() => travel(city)}
|
||||
>
|
||||
<div key={city} className="cmpy-mgmt-find-employee-option" onClick={() => travel(city)}>
|
||||
{city}
|
||||
</div>
|
||||
);
|
||||
|
@ -76,14 +76,8 @@ export class Blackjack extends Game<Props, State> {
|
||||
// always reload without saving but w.e)
|
||||
this.props.p.loseMoney(this.state.bet);
|
||||
|
||||
const playerHand = new Hand([
|
||||
this.deck.safeDrawCard(),
|
||||
this.deck.safeDrawCard(),
|
||||
]);
|
||||
const dealerHand = new Hand([
|
||||
this.deck.safeDrawCard(),
|
||||
this.deck.safeDrawCard(),
|
||||
]);
|
||||
const playerHand = new Hand([this.deck.safeDrawCard(), this.deck.safeDrawCard()]);
|
||||
const dealerHand = new Hand([this.deck.safeDrawCard(), this.deck.safeDrawCard()]);
|
||||
|
||||
this.setState({
|
||||
playerHand,
|
||||
@ -242,9 +236,7 @@ export class Blackjack extends Game<Props, State> {
|
||||
};
|
||||
|
||||
isPlayerWinResult = (result: Result): boolean => {
|
||||
return (
|
||||
result === Result.PlayerWon || result === Result.PlayerWonByBlackjack
|
||||
);
|
||||
return result === Result.PlayerWon || result === Result.PlayerWonByBlackjack;
|
||||
};
|
||||
|
||||
wagerOnChange = (event: React.ChangeEvent<HTMLInputElement>): void => {
|
||||
@ -304,16 +296,8 @@ export class Blackjack extends Game<Props, State> {
|
||||
};
|
||||
|
||||
render(): React.ReactNode {
|
||||
const {
|
||||
betInput,
|
||||
playerHand,
|
||||
dealerHand,
|
||||
gameInProgress,
|
||||
result,
|
||||
wagerInvalid,
|
||||
wagerInvalidHelperText,
|
||||
gains,
|
||||
} = this.state;
|
||||
const { betInput, playerHand, dealerHand, gameInProgress, result, wagerInvalid, wagerInvalidHelperText, gains } =
|
||||
this.state;
|
||||
|
||||
// Get the player totals to display.
|
||||
const playerHandValues = this.getHandDisplayValues(playerHand);
|
||||
@ -342,9 +326,7 @@ export class Blackjack extends Game<Props, State> {
|
||||
width: "200px",
|
||||
}}
|
||||
InputProps={{
|
||||
startAdornment: (
|
||||
<InputAdornment position="start">$</InputAdornment>
|
||||
),
|
||||
startAdornment: <InputAdornment position="start">$</InputAdornment>,
|
||||
}}
|
||||
/>
|
||||
|
||||
@ -357,11 +339,7 @@ export class Blackjack extends Game<Props, State> {
|
||||
{/* Buttons */}
|
||||
{!gameInProgress ? (
|
||||
<div>
|
||||
<MuiButton
|
||||
color="primary"
|
||||
onClick={this.startOnClick}
|
||||
disabled={wagerInvalid || !this.canStartGame()}
|
||||
>
|
||||
<MuiButton color="primary" onClick={this.startOnClick} disabled={wagerInvalid || !this.canStartGame()}>
|
||||
Start
|
||||
</MuiButton>
|
||||
</div>
|
||||
@ -398,11 +376,7 @@ export class Blackjack extends Game<Props, State> {
|
||||
<pre>Dealer</pre>
|
||||
{dealerHand.cards.map((card, i) => (
|
||||
// Hide every card except the first while game is in progress
|
||||
<ReactCard
|
||||
card={card}
|
||||
hidden={gameInProgress && i !== 0}
|
||||
key={i}
|
||||
/>
|
||||
<ReactCard card={card} hidden={gameInProgress && i !== 0} key={i} />
|
||||
))}
|
||||
|
||||
{!gameInProgress && (
|
||||
|
@ -91,23 +91,10 @@ export class CoinFlip extends Game<IProps, IState> {
|
||||
<pre>{`| | | |`}</pre>
|
||||
<pre>{`+———————+`}</pre>
|
||||
<span className="text">Play for: </span>
|
||||
<input
|
||||
type="number"
|
||||
className="text-input"
|
||||
onChange={this.updateInvestment}
|
||||
value={this.state.investment}
|
||||
/>
|
||||
<input type="number" className="text-input" onChange={this.updateInvestment} value={this.state.investment} />
|
||||
<br />
|
||||
<StdButton
|
||||
onClick={trusted(() => this.play("H"))}
|
||||
text={"Head!"}
|
||||
disabled={this.state.playLock}
|
||||
/>
|
||||
<StdButton
|
||||
onClick={trusted(() => this.play("T"))}
|
||||
text={"Tail!"}
|
||||
disabled={this.state.playLock}
|
||||
/>
|
||||
<StdButton onClick={trusted(() => this.play("H"))} text={"Head!"} disabled={this.state.playLock} />
|
||||
<StdButton onClick={trusted(() => this.play("T"))} text={"Tail!"} disabled={this.state.playLock} />
|
||||
<h1>{this.state.status}</h1>
|
||||
</>
|
||||
);
|
||||
|
@ -13,9 +13,7 @@ export class Game<T, U> extends React.Component<T, U> {
|
||||
reachedLimit(p: IPlayer): boolean {
|
||||
const reached = p.getCasinoWinnings() > gainLimit;
|
||||
if (reached) {
|
||||
dialogBoxCreate(
|
||||
<>Alright cheater get out of here. You're not allowed here anymore.</>,
|
||||
);
|
||||
dialogBoxCreate(<>Alright cheater get out of here. You're not allowed here anymore.</>);
|
||||
}
|
||||
return reached;
|
||||
}
|
||||
|
@ -24,9 +24,7 @@ const minPlay = 0;
|
||||
const maxPlay = 1e7;
|
||||
|
||||
function isRed(n: number): boolean {
|
||||
return [
|
||||
1, 3, 5, 7, 9, 12, 14, 16, 18, 19, 21, 23, 25, 27, 30, 32, 34, 36,
|
||||
].includes(n);
|
||||
return [1, 3, 5, 7, 9, 12, 14, 16, 18, 19, 21, 23, 25, 27, 30, 32, 34, 36].includes(n);
|
||||
}
|
||||
|
||||
type Strategy = {
|
||||
@ -34,9 +32,7 @@ type Strategy = {
|
||||
payout: number;
|
||||
};
|
||||
|
||||
const redNumbers: number[] = [
|
||||
1, 3, 5, 7, 9, 12, 14, 16, 18, 19, 21, 23, 25, 27, 30, 32, 34, 36,
|
||||
];
|
||||
const redNumbers: number[] = [1, 3, 5, 7, 9, 12, 14, 16, 18, 19, 21, 23, 25, 27, 30, 32, 34, 36];
|
||||
|
||||
const strategies: {
|
||||
Red: Strategy;
|
||||
@ -246,260 +242,116 @@ export class Roulette extends Game<IProps, IState> {
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<StdButton
|
||||
text={"3"}
|
||||
disabled={!this.state.canPlay}
|
||||
onClick={trusted(() => this.play(Single(3)))}
|
||||
/>
|
||||
<StdButton text={"3"} disabled={!this.state.canPlay} onClick={trusted(() => this.play(Single(3)))} />
|
||||
</td>
|
||||
<td>
|
||||
<StdButton
|
||||
text={"6"}
|
||||
disabled={!this.state.canPlay}
|
||||
onClick={trusted(() => this.play(Single(6)))}
|
||||
/>
|
||||
<StdButton text={"6"} disabled={!this.state.canPlay} onClick={trusted(() => this.play(Single(6)))} />
|
||||
</td>
|
||||
<td>
|
||||
<StdButton
|
||||
text={"9"}
|
||||
disabled={!this.state.canPlay}
|
||||
onClick={trusted(() => this.play(Single(9)))}
|
||||
/>
|
||||
<StdButton text={"9"} disabled={!this.state.canPlay} onClick={trusted(() => this.play(Single(9)))} />
|
||||
</td>
|
||||
<td>
|
||||
<StdButton
|
||||
text={"12"}
|
||||
disabled={!this.state.canPlay}
|
||||
onClick={trusted(() => this.play(Single(12)))}
|
||||
/>
|
||||
<StdButton text={"12"} disabled={!this.state.canPlay} onClick={trusted(() => this.play(Single(12)))} />
|
||||
</td>
|
||||
<td>
|
||||
<StdButton
|
||||
text={"15"}
|
||||
disabled={!this.state.canPlay}
|
||||
onClick={trusted(() => this.play(Single(15)))}
|
||||
/>
|
||||
<StdButton text={"15"} disabled={!this.state.canPlay} onClick={trusted(() => this.play(Single(15)))} />
|
||||
</td>
|
||||
<td>
|
||||
<StdButton
|
||||
text={"18"}
|
||||
disabled={!this.state.canPlay}
|
||||
onClick={trusted(() => this.play(Single(18)))}
|
||||
/>
|
||||
<StdButton text={"18"} disabled={!this.state.canPlay} onClick={trusted(() => this.play(Single(18)))} />
|
||||
</td>
|
||||
<td>
|
||||
<StdButton
|
||||
text={"21"}
|
||||
disabled={!this.state.canPlay}
|
||||
onClick={trusted(() => this.play(Single(21)))}
|
||||
/>
|
||||
<StdButton text={"21"} disabled={!this.state.canPlay} onClick={trusted(() => this.play(Single(21)))} />
|
||||
</td>
|
||||
<td>
|
||||
<StdButton
|
||||
text={"24"}
|
||||
disabled={!this.state.canPlay}
|
||||
onClick={trusted(() => this.play(Single(24)))}
|
||||
/>
|
||||
<StdButton text={"24"} disabled={!this.state.canPlay} onClick={trusted(() => this.play(Single(24)))} />
|
||||
</td>
|
||||
<td>
|
||||
<StdButton
|
||||
text={"27"}
|
||||
disabled={!this.state.canPlay}
|
||||
onClick={trusted(() => this.play(Single(27)))}
|
||||
/>
|
||||
<StdButton text={"27"} disabled={!this.state.canPlay} onClick={trusted(() => this.play(Single(27)))} />
|
||||
</td>
|
||||
<td>
|
||||
<StdButton
|
||||
text={"30"}
|
||||
disabled={!this.state.canPlay}
|
||||
onClick={trusted(() => this.play(Single(30)))}
|
||||
/>
|
||||
<StdButton text={"30"} disabled={!this.state.canPlay} onClick={trusted(() => this.play(Single(30)))} />
|
||||
</td>
|
||||
<td>
|
||||
<StdButton
|
||||
text={"33"}
|
||||
disabled={!this.state.canPlay}
|
||||
onClick={trusted(() => this.play(Single(33)))}
|
||||
/>
|
||||
<StdButton text={"33"} disabled={!this.state.canPlay} onClick={trusted(() => this.play(Single(33)))} />
|
||||
</td>
|
||||
<td>
|
||||
<StdButton
|
||||
text={"36"}
|
||||
disabled={!this.state.canPlay}
|
||||
onClick={trusted(() => this.play(Single(36)))}
|
||||
/>
|
||||
<StdButton text={"36"} disabled={!this.state.canPlay} onClick={trusted(() => this.play(Single(36)))} />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<StdButton
|
||||
text={"2"}
|
||||
disabled={!this.state.canPlay}
|
||||
onClick={trusted(() => this.play(Single(2)))}
|
||||
/>
|
||||
<StdButton text={"2"} disabled={!this.state.canPlay} onClick={trusted(() => this.play(Single(2)))} />
|
||||
</td>
|
||||
<td>
|
||||
<StdButton
|
||||
text={"5"}
|
||||
disabled={!this.state.canPlay}
|
||||
onClick={trusted(() => this.play(Single(5)))}
|
||||
/>
|
||||
<StdButton text={"5"} disabled={!this.state.canPlay} onClick={trusted(() => this.play(Single(5)))} />
|
||||
</td>
|
||||
<td>
|
||||
<StdButton
|
||||
text={"8"}
|
||||
disabled={!this.state.canPlay}
|
||||
onClick={trusted(() => this.play(Single(8)))}
|
||||
/>
|
||||
<StdButton text={"8"} disabled={!this.state.canPlay} onClick={trusted(() => this.play(Single(8)))} />
|
||||
</td>
|
||||
<td>
|
||||
<StdButton
|
||||
text={"11"}
|
||||
disabled={!this.state.canPlay}
|
||||
onClick={trusted(() => this.play(Single(11)))}
|
||||
/>
|
||||
<StdButton text={"11"} disabled={!this.state.canPlay} onClick={trusted(() => this.play(Single(11)))} />
|
||||
</td>
|
||||
<td>
|
||||
<StdButton
|
||||
text={"14"}
|
||||
disabled={!this.state.canPlay}
|
||||
onClick={trusted(() => this.play(Single(14)))}
|
||||
/>
|
||||
<StdButton text={"14"} disabled={!this.state.canPlay} onClick={trusted(() => this.play(Single(14)))} />
|
||||
</td>
|
||||
<td>
|
||||
<StdButton
|
||||
text={"17"}
|
||||
disabled={!this.state.canPlay}
|
||||
onClick={trusted(() => this.play(Single(17)))}
|
||||
/>
|
||||
<StdButton text={"17"} disabled={!this.state.canPlay} onClick={trusted(() => this.play(Single(17)))} />
|
||||
</td>
|
||||
<td>
|
||||
<StdButton
|
||||
text={"20"}
|
||||
disabled={!this.state.canPlay}
|
||||
onClick={trusted(() => this.play(Single(20)))}
|
||||
/>
|
||||
<StdButton text={"20"} disabled={!this.state.canPlay} onClick={trusted(() => this.play(Single(20)))} />
|
||||
</td>
|
||||
<td>
|
||||
<StdButton
|
||||
text={"23"}
|
||||
disabled={!this.state.canPlay}
|
||||
onClick={trusted(() => this.play(Single(23)))}
|
||||
/>
|
||||
<StdButton text={"23"} disabled={!this.state.canPlay} onClick={trusted(() => this.play(Single(23)))} />
|
||||
</td>
|
||||
<td>
|
||||
<StdButton
|
||||
text={"26"}
|
||||
disabled={!this.state.canPlay}
|
||||
onClick={trusted(() => this.play(Single(26)))}
|
||||
/>
|
||||
<StdButton text={"26"} disabled={!this.state.canPlay} onClick={trusted(() => this.play(Single(26)))} />
|
||||
</td>
|
||||
<td>
|
||||
<StdButton
|
||||
text={"29"}
|
||||
disabled={!this.state.canPlay}
|
||||
onClick={trusted(() => this.play(Single(29)))}
|
||||
/>
|
||||
<StdButton text={"29"} disabled={!this.state.canPlay} onClick={trusted(() => this.play(Single(29)))} />
|
||||
</td>
|
||||
<td>
|
||||
<StdButton
|
||||
text={"32"}
|
||||
disabled={!this.state.canPlay}
|
||||
onClick={trusted(() => this.play(Single(32)))}
|
||||
/>
|
||||
<StdButton text={"32"} disabled={!this.state.canPlay} onClick={trusted(() => this.play(Single(32)))} />
|
||||
</td>
|
||||
<td>
|
||||
<StdButton
|
||||
text={"35"}
|
||||
disabled={!this.state.canPlay}
|
||||
onClick={trusted(() => this.play(Single(35)))}
|
||||
/>
|
||||
<StdButton text={"35"} disabled={!this.state.canPlay} onClick={trusted(() => this.play(Single(35)))} />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<StdButton
|
||||
text={"1"}
|
||||
disabled={!this.state.canPlay}
|
||||
onClick={trusted(() => this.play(Single(1)))}
|
||||
/>
|
||||
<StdButton text={"1"} disabled={!this.state.canPlay} onClick={trusted(() => this.play(Single(1)))} />
|
||||
</td>
|
||||
<td>
|
||||
<StdButton
|
||||
text={"4"}
|
||||
disabled={!this.state.canPlay}
|
||||
onClick={trusted(() => this.play(Single(4)))}
|
||||
/>
|
||||
<StdButton text={"4"} disabled={!this.state.canPlay} onClick={trusted(() => this.play(Single(4)))} />
|
||||
</td>
|
||||
<td>
|
||||
<StdButton
|
||||
text={"7"}
|
||||
disabled={!this.state.canPlay}
|
||||
onClick={trusted(() => this.play(Single(7)))}
|
||||
/>
|
||||
<StdButton text={"7"} disabled={!this.state.canPlay} onClick={trusted(() => this.play(Single(7)))} />
|
||||
</td>
|
||||
<td>
|
||||
<StdButton
|
||||
text={"10"}
|
||||
disabled={!this.state.canPlay}
|
||||
onClick={trusted(() => this.play(Single(10)))}
|
||||
/>
|
||||
<StdButton text={"10"} disabled={!this.state.canPlay} onClick={trusted(() => this.play(Single(10)))} />
|
||||
</td>
|
||||
<td>
|
||||
<StdButton
|
||||
text={"13"}
|
||||
disabled={!this.state.canPlay}
|
||||
onClick={trusted(() => this.play(Single(13)))}
|
||||
/>
|
||||
<StdButton text={"13"} disabled={!this.state.canPlay} onClick={trusted(() => this.play(Single(13)))} />
|
||||
</td>
|
||||
<td>
|
||||
<StdButton
|
||||
text={"16"}
|
||||
disabled={!this.state.canPlay}
|
||||
onClick={trusted(() => this.play(Single(16)))}
|
||||
/>
|
||||
<StdButton text={"16"} disabled={!this.state.canPlay} onClick={trusted(() => this.play(Single(16)))} />
|
||||
</td>
|
||||
<td>
|
||||
<StdButton
|
||||
text={"19"}
|
||||
disabled={!this.state.canPlay}
|
||||
onClick={trusted(() => this.play(Single(19)))}
|
||||
/>
|
||||
<StdButton text={"19"} disabled={!this.state.canPlay} onClick={trusted(() => this.play(Single(19)))} />
|
||||
</td>
|
||||
<td>
|
||||
<StdButton
|
||||
text={"22"}
|
||||
disabled={!this.state.canPlay}
|
||||
onClick={trusted(() => this.play(Single(22)))}
|
||||
/>
|
||||
<StdButton text={"22"} disabled={!this.state.canPlay} onClick={trusted(() => this.play(Single(22)))} />
|
||||
</td>
|
||||
<td>
|
||||
<StdButton
|
||||
text={"25"}
|
||||
disabled={!this.state.canPlay}
|
||||
onClick={trusted(() => this.play(Single(25)))}
|
||||
/>
|
||||
<StdButton text={"25"} disabled={!this.state.canPlay} onClick={trusted(() => this.play(Single(25)))} />
|
||||
</td>
|
||||
<td>
|
||||
<StdButton
|
||||
text={"28"}
|
||||
disabled={!this.state.canPlay}
|
||||
onClick={trusted(() => this.play(Single(28)))}
|
||||
/>
|
||||
<StdButton text={"28"} disabled={!this.state.canPlay} onClick={trusted(() => this.play(Single(28)))} />
|
||||
</td>
|
||||
<td>
|
||||
<StdButton
|
||||
text={"31"}
|
||||
disabled={!this.state.canPlay}
|
||||
onClick={trusted(() => this.play(Single(31)))}
|
||||
/>
|
||||
<StdButton text={"31"} disabled={!this.state.canPlay} onClick={trusted(() => this.play(Single(31)))} />
|
||||
</td>
|
||||
<td>
|
||||
<StdButton
|
||||
text={"34"}
|
||||
disabled={!this.state.canPlay}
|
||||
onClick={trusted(() => this.play(Single(34)))}
|
||||
/>
|
||||
<StdButton text={"34"} disabled={!this.state.canPlay} onClick={trusted(() => this.play(Single(34)))} />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@ -571,11 +423,7 @@ export class Roulette extends Game<IProps, IState> {
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<StdButton
|
||||
text={"0"}
|
||||
disabled={!this.state.canPlay}
|
||||
onClick={trusted(() => this.play(Single(0)))}
|
||||
/>
|
||||
<StdButton text={"0"} disabled={!this.state.canPlay} onClick={trusted(() => this.play(Single(0)))} />
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
@ -1,8 +1,6 @@
|
||||
import * as React from "react";
|
||||
|
||||
export function trusted(
|
||||
f: () => void,
|
||||
): (event: React.MouseEvent<HTMLElement, MouseEvent>) => any {
|
||||
export function trusted(f: () => void): (event: React.MouseEvent<HTMLElement, MouseEvent>) => any {
|
||||
return function (event: React.MouseEvent<HTMLElement, MouseEvent>): any {
|
||||
if (!event.isTrusted) return;
|
||||
f();
|
||||
|
@ -18,9 +18,7 @@ export function writeCinematicText(lines) {
|
||||
cinematicTextFlag = true;
|
||||
|
||||
if (lines.constructor !== Array) {
|
||||
throw new Error(
|
||||
"Invalid non-array argument passed into writeCinematicText()",
|
||||
);
|
||||
throw new Error("Invalid non-array argument passed into writeCinematicText()");
|
||||
}
|
||||
|
||||
// Reuse the 'Red Pill' content
|
||||
@ -28,17 +26,13 @@ export function writeCinematicText(lines) {
|
||||
const container = document.getElementById("cinematic-text-container");
|
||||
container.style.width = "75%";
|
||||
if (container == null) {
|
||||
throw new Error(
|
||||
"Could not find cinematic-text-container for writeCinematicText()",
|
||||
);
|
||||
throw new Error("Could not find cinematic-text-container for writeCinematicText()");
|
||||
}
|
||||
removeChildrenFromElement(container);
|
||||
|
||||
for (let i = 0; i < lines.length; ++i) {
|
||||
if (!isString(lines[i])) {
|
||||
throw new Error(
|
||||
"Invalid non-string element in 'lines' argument. writeCinematicText() failed",
|
||||
);
|
||||
throw new Error("Invalid non-string element in 'lines' argument. writeCinematicText() failed");
|
||||
}
|
||||
}
|
||||
|
||||
@ -88,8 +82,7 @@ function writeCinematicTextLetter(pElem, line, i = 0) {
|
||||
return resolve(true);
|
||||
}
|
||||
|
||||
pElem.innerHTML =
|
||||
textToShow + "<span class='typed-cursor'> █ </span>";
|
||||
pElem.innerHTML = textToShow + "<span class='typed-cursor'> █ </span>";
|
||||
const promise = writeCinematicTextLetter(pElem, line, i + 1);
|
||||
promise.then(
|
||||
function (res) {
|
||||
|
@ -92,37 +92,24 @@ export function generateContract(params: IGenerateContractParams): void {
|
||||
}
|
||||
|
||||
// Ensures that a contract's reward type is valid
|
||||
function sanitizeRewardType(
|
||||
rewardType: CodingContractRewardType,
|
||||
): CodingContractRewardType {
|
||||
function sanitizeRewardType(rewardType: CodingContractRewardType): CodingContractRewardType {
|
||||
let type = rewardType; // Create copy
|
||||
|
||||
const factionsThatAllowHacking = Player.factions.filter((fac) => {
|
||||
try {
|
||||
return Factions[fac].getInfo().offerHackingWork;
|
||||
} catch (e) {
|
||||
console.error(
|
||||
`Error when trying to filter Hacking Factions for Coding Contract Generation: ${e}`,
|
||||
);
|
||||
console.error(`Error when trying to filter Hacking Factions for Coding Contract Generation: ${e}`);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
if (
|
||||
type === CodingContractRewardType.FactionReputation &&
|
||||
factionsThatAllowHacking.length === 0
|
||||
) {
|
||||
if (type === CodingContractRewardType.FactionReputation && factionsThatAllowHacking.length === 0) {
|
||||
type = CodingContractRewardType.CompanyReputation;
|
||||
}
|
||||
if (
|
||||
type === CodingContractRewardType.FactionReputationAll &&
|
||||
factionsThatAllowHacking.length === 0
|
||||
) {
|
||||
if (type === CodingContractRewardType.FactionReputationAll && factionsThatAllowHacking.length === 0) {
|
||||
type = CodingContractRewardType.CompanyReputation;
|
||||
}
|
||||
if (
|
||||
type === CodingContractRewardType.CompanyReputation &&
|
||||
Object.keys(Player.jobs).length === 0
|
||||
) {
|
||||
if (type === CodingContractRewardType.CompanyReputation && Object.keys(Player.jobs).length === 0) {
|
||||
type = CodingContractRewardType.Money;
|
||||
}
|
||||
|
||||
@ -148,9 +135,7 @@ function getRandomReward(): ICodingContractReward {
|
||||
try {
|
||||
return Factions[fac].getInfo().offerHackingWork;
|
||||
} catch (e) {
|
||||
console.error(
|
||||
`Error when trying to filter Hacking Factions for Coding Contract Generation: ${e}`,
|
||||
);
|
||||
console.error(`Error when trying to filter Hacking Factions for Coding Contract Generation: ${e}`);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
@ -160,8 +145,7 @@ function getRandomReward(): ICodingContractReward {
|
||||
// Get a random faction that player is a part of. That
|
||||
// faction must allow hacking contracts
|
||||
const numFactions = factionsThatAllowHacking.length;
|
||||
const randFaction =
|
||||
factionsThatAllowHacking[getRandomInt(0, numFactions - 1)];
|
||||
const randFaction = factionsThatAllowHacking[getRandomInt(0, numFactions - 1)];
|
||||
reward.name = randFaction;
|
||||
break;
|
||||
}
|
||||
@ -203,10 +187,7 @@ function getRandomServer(): Server | HacknetServer {
|
||||
return randServer;
|
||||
}
|
||||
|
||||
function getRandomFilename(
|
||||
server: Server | HacknetServer,
|
||||
reward: ICodingContractReward,
|
||||
): string {
|
||||
function getRandomFilename(server: Server | HacknetServer, reward: ICodingContractReward): string {
|
||||
let contractFn = `contract-${getRandomInt(0, 1e6)}`;
|
||||
|
||||
for (let i = 0; i < 1000; ++i) {
|
||||
|
@ -1,17 +1,8 @@
|
||||
import {
|
||||
codingContractTypesMetadata,
|
||||
DescriptionFunc,
|
||||
GeneratorFunc,
|
||||
SolverFunc,
|
||||
} from "./data/codingcontracttypes";
|
||||
import { codingContractTypesMetadata, DescriptionFunc, GeneratorFunc, SolverFunc } from "./data/codingcontracttypes";
|
||||
|
||||
import { IMap } from "./types";
|
||||
|
||||
import {
|
||||
Generic_fromJSON,
|
||||
Generic_toJSON,
|
||||
Reviver,
|
||||
} from "../utils/JSONReviver";
|
||||
import { Generic_fromJSON, Generic_toJSON, Reviver } from "../utils/JSONReviver";
|
||||
import { createPopup, removePopup } from "./ui/React/createPopup";
|
||||
import { CodingContractPopup } from "./ui/React/CodingContractPopup";
|
||||
|
||||
@ -131,11 +122,7 @@ export class CodingContract {
|
||||
/* String representing the contract's type. Must match type in ContractTypes */
|
||||
type: string;
|
||||
|
||||
constructor(
|
||||
fn = "",
|
||||
type = "Find Largest Prime Factor",
|
||||
reward: ICodingContractReward | null = null,
|
||||
) {
|
||||
constructor(fn = "", type = "Find Largest Prime Factor", reward: ICodingContractReward | null = null) {
|
||||
this.fn = fn;
|
||||
if (!this.fn.endsWith(".cct")) {
|
||||
this.fn += ".cct";
|
||||
@ -143,9 +130,7 @@ export class CodingContract {
|
||||
|
||||
// tslint:disable-next-line
|
||||
if (CodingContractTypes[type] == null) {
|
||||
throw new Error(
|
||||
`Error: invalid contract type: ${type} please contact developer`,
|
||||
);
|
||||
throw new Error(`Error: invalid contract type: ${type} please contact developer`);
|
||||
}
|
||||
|
||||
this.type = type;
|
||||
|
@ -4,11 +4,7 @@ import * as posNames from "./data/companypositionnames";
|
||||
import { CONSTANTS } from "../Constants";
|
||||
import { IMap } from "../types";
|
||||
|
||||
import {
|
||||
Generic_fromJSON,
|
||||
Generic_toJSON,
|
||||
Reviver,
|
||||
} from "../../utils/JSONReviver";
|
||||
import { Generic_fromJSON, Generic_toJSON, Reviver } from "../../utils/JSONReviver";
|
||||
|
||||
export interface IConstructorParams {
|
||||
name: string;
|
||||
@ -98,10 +94,7 @@ export class Company {
|
||||
}
|
||||
|
||||
hasBusinessConsultantPositions(): boolean {
|
||||
return (
|
||||
this.companyPositions[posNames.BusinessConsultantCompanyPositions[0]] !=
|
||||
null
|
||||
);
|
||||
return this.companyPositions[posNames.BusinessConsultantCompanyPositions[0]] != null;
|
||||
}
|
||||
|
||||
hasBusinessPositions(): boolean {
|
||||
@ -121,10 +114,7 @@ export class Company {
|
||||
}
|
||||
|
||||
hasSoftwareConsultantPositions(): boolean {
|
||||
return (
|
||||
this.companyPositions[posNames.SoftwareConsultantCompanyPositions[0]] !=
|
||||
null
|
||||
);
|
||||
return this.companyPositions[posNames.SoftwareConsultantCompanyPositions[0]] != null;
|
||||
}
|
||||
|
||||
hasSoftwarePositions(): boolean {
|
||||
@ -161,9 +151,7 @@ export class Company {
|
||||
}
|
||||
let favorGain = 0,
|
||||
rep = this.playerReputation + this.rolloverRep;
|
||||
let reqdRep =
|
||||
CONSTANTS.CompanyReputationToFavorBase *
|
||||
Math.pow(CONSTANTS.CompanyReputationToFavorMult, this.favor);
|
||||
let reqdRep = CONSTANTS.CompanyReputationToFavorBase * Math.pow(CONSTANTS.CompanyReputationToFavorMult, this.favor);
|
||||
while (rep > 0) {
|
||||
if (rep >= reqdRep) {
|
||||
++favorGain;
|
||||
|
@ -103,18 +103,12 @@ export class CompanyPosition {
|
||||
this.requiredCharisma = p.reqdCharisma != null ? p.reqdCharisma : 0;
|
||||
this.requiredReputation = p.reqdReputation != null ? p.reqdReputation : 0;
|
||||
|
||||
this.hackingEffectiveness =
|
||||
p.hackingEffectiveness != null ? p.hackingEffectiveness : 0;
|
||||
this.strengthEffectiveness =
|
||||
p.strengthEffectiveness != null ? p.strengthEffectiveness : 0;
|
||||
this.defenseEffectiveness =
|
||||
p.defenseEffectiveness != null ? p.defenseEffectiveness : 0;
|
||||
this.dexterityEffectiveness =
|
||||
p.dexterityEffectiveness != null ? p.dexterityEffectiveness : 0;
|
||||
this.agilityEffectiveness =
|
||||
p.agilityEffectiveness != null ? p.agilityEffectiveness : 0;
|
||||
this.charismaEffectiveness =
|
||||
p.charismaEffectiveness != null ? p.charismaEffectiveness : 0;
|
||||
this.hackingEffectiveness = p.hackingEffectiveness != null ? p.hackingEffectiveness : 0;
|
||||
this.strengthEffectiveness = p.strengthEffectiveness != null ? p.strengthEffectiveness : 0;
|
||||
this.defenseEffectiveness = p.defenseEffectiveness != null ? p.defenseEffectiveness : 0;
|
||||
this.dexterityEffectiveness = p.dexterityEffectiveness != null ? p.dexterityEffectiveness : 0;
|
||||
this.agilityEffectiveness = p.agilityEffectiveness != null ? p.agilityEffectiveness : 0;
|
||||
this.charismaEffectiveness = p.charismaEffectiveness != null ? p.charismaEffectiveness : 0;
|
||||
|
||||
if (
|
||||
Math.round(
|
||||
@ -126,9 +120,7 @@ export class CompanyPosition {
|
||||
this.charismaEffectiveness,
|
||||
) !== 100
|
||||
) {
|
||||
console.error(
|
||||
`CompanyPosition ${this.name} parameters do not sum to 100`,
|
||||
);
|
||||
console.error(`CompanyPosition ${this.name} parameters do not sum to 100`);
|
||||
}
|
||||
|
||||
this.hackingExpGain = p.hackingExpGain != null ? p.hackingExpGain : 0;
|
||||
@ -139,31 +131,16 @@ export class CompanyPosition {
|
||||
this.charismaExpGain = p.charismaExpGain != null ? p.charismaExpGain : 0;
|
||||
}
|
||||
|
||||
calculateJobPerformance(
|
||||
hack: number,
|
||||
str: number,
|
||||
def: number,
|
||||
dex: number,
|
||||
agi: number,
|
||||
cha: number,
|
||||
): number {
|
||||
const hackRatio: number =
|
||||
(this.hackingEffectiveness * hack) / CONSTANTS.MaxSkillLevel;
|
||||
const strRatio: number =
|
||||
(this.strengthEffectiveness * str) / CONSTANTS.MaxSkillLevel;
|
||||
const defRatio: number =
|
||||
(this.defenseEffectiveness * def) / CONSTANTS.MaxSkillLevel;
|
||||
const dexRatio: number =
|
||||
(this.dexterityEffectiveness * dex) / CONSTANTS.MaxSkillLevel;
|
||||
const agiRatio: number =
|
||||
(this.agilityEffectiveness * agi) / CONSTANTS.MaxSkillLevel;
|
||||
const chaRatio: number =
|
||||
(this.charismaEffectiveness * cha) / CONSTANTS.MaxSkillLevel;
|
||||
calculateJobPerformance(hack: number, str: number, def: number, dex: number, agi: number, cha: number): number {
|
||||
const hackRatio: number = (this.hackingEffectiveness * hack) / CONSTANTS.MaxSkillLevel;
|
||||
const strRatio: number = (this.strengthEffectiveness * str) / CONSTANTS.MaxSkillLevel;
|
||||
const defRatio: number = (this.defenseEffectiveness * def) / CONSTANTS.MaxSkillLevel;
|
||||
const dexRatio: number = (this.dexterityEffectiveness * dex) / CONSTANTS.MaxSkillLevel;
|
||||
const agiRatio: number = (this.agilityEffectiveness * agi) / CONSTANTS.MaxSkillLevel;
|
||||
const chaRatio: number = (this.charismaEffectiveness * cha) / CONSTANTS.MaxSkillLevel;
|
||||
|
||||
let reputationGain: number =
|
||||
(this.repMultiplier *
|
||||
(hackRatio + strRatio + defRatio + dexRatio + agiRatio + chaRatio)) /
|
||||
100;
|
||||
(this.repMultiplier * (hackRatio + strRatio + defRatio + dexRatio + agiRatio + chaRatio)) / 100;
|
||||
if (isNaN(reputationGain)) {
|
||||
console.error("Company reputation gain calculated to be NaN");
|
||||
reputationGain = 0;
|
||||
|
@ -5,25 +5,15 @@ import { CompanyPosition } from "./CompanyPosition";
|
||||
* Returns a string with the given CompanyPosition's stat requirements
|
||||
*/
|
||||
|
||||
export function getJobRequirementText(
|
||||
company: Company,
|
||||
pos: CompanyPosition,
|
||||
tooltiptext = false,
|
||||
): string {
|
||||
export function getJobRequirementText(company: Company, pos: CompanyPosition, tooltiptext = false): string {
|
||||
let reqText = "";
|
||||
const offset: number = company.jobStatReqOffset;
|
||||
const reqHacking: number =
|
||||
pos.requiredHacking > 0 ? pos.requiredHacking + offset : 0;
|
||||
const reqStrength: number =
|
||||
pos.requiredStrength > 0 ? pos.requiredStrength + offset : 0;
|
||||
const reqDefense: number =
|
||||
pos.requiredDefense > 0 ? pos.requiredDefense + offset : 0;
|
||||
const reqDexterity: number =
|
||||
pos.requiredDexterity > 0 ? pos.requiredDexterity + offset : 0;
|
||||
const reqAgility: number =
|
||||
pos.requiredDexterity > 0 ? pos.requiredDexterity + offset : 0;
|
||||
const reqCharisma: number =
|
||||
pos.requiredCharisma > 0 ? pos.requiredCharisma + offset : 0;
|
||||
const reqHacking: number = pos.requiredHacking > 0 ? pos.requiredHacking + offset : 0;
|
||||
const reqStrength: number = pos.requiredStrength > 0 ? pos.requiredStrength + offset : 0;
|
||||
const reqDefense: number = pos.requiredDefense > 0 ? pos.requiredDefense + offset : 0;
|
||||
const reqDexterity: number = pos.requiredDexterity > 0 ? pos.requiredDexterity + offset : 0;
|
||||
const reqAgility: number = pos.requiredDexterity > 0 ? pos.requiredDexterity + offset : 0;
|
||||
const reqCharisma: number = pos.requiredCharisma > 0 ? pos.requiredCharisma + offset : 0;
|
||||
const reqRep: number = pos.requiredReputation;
|
||||
if (tooltiptext) {
|
||||
reqText = "Requires:<br>";
|
||||
|
@ -3,9 +3,7 @@
|
||||
import { CompanyPosition } from "./CompanyPosition";
|
||||
import { CompanyPositions } from "./CompanyPositions";
|
||||
|
||||
export function getNextCompanyPositionHelper(
|
||||
currPos: CompanyPosition | null,
|
||||
): CompanyPosition | null {
|
||||
export function getNextCompanyPositionHelper(currPos: CompanyPosition | null): CompanyPosition | null {
|
||||
if (currPos == null) {
|
||||
return null;
|
||||
}
|
||||
|
@ -92,12 +92,7 @@ export const companiesMetadata: IConstructorParams[] = [
|
||||
{
|
||||
name: LocationName.AevumECorp,
|
||||
info: "",
|
||||
companyPositions: Object.assign(
|
||||
{},
|
||||
AllTechnologyPositions,
|
||||
AllBusinessPositions,
|
||||
AllSecurityPositions,
|
||||
),
|
||||
companyPositions: Object.assign({}, AllTechnologyPositions, AllBusinessPositions, AllSecurityPositions),
|
||||
expMultiplier: 3,
|
||||
salaryMultiplier: 3,
|
||||
jobStatReqOffset: 249,
|
||||
@ -105,12 +100,7 @@ export const companiesMetadata: IConstructorParams[] = [
|
||||
{
|
||||
name: LocationName.Sector12MegaCorp,
|
||||
info: "",
|
||||
companyPositions: Object.assign(
|
||||
{},
|
||||
AllTechnologyPositions,
|
||||
AllBusinessPositions,
|
||||
AllSecurityPositions,
|
||||
),
|
||||
companyPositions: Object.assign({}, AllTechnologyPositions, AllBusinessPositions, AllSecurityPositions),
|
||||
expMultiplier: 3,
|
||||
salaryMultiplier: 3,
|
||||
jobStatReqOffset: 249,
|
||||
@ -118,12 +108,7 @@ export const companiesMetadata: IConstructorParams[] = [
|
||||
{
|
||||
name: LocationName.AevumBachmanAndAssociates,
|
||||
info: "",
|
||||
companyPositions: Object.assign(
|
||||
{},
|
||||
AllTechnologyPositions,
|
||||
AllBusinessPositions,
|
||||
AllSecurityPositions,
|
||||
),
|
||||
companyPositions: Object.assign({}, AllTechnologyPositions, AllBusinessPositions, AllSecurityPositions),
|
||||
expMultiplier: 2.6,
|
||||
salaryMultiplier: 2.6,
|
||||
jobStatReqOffset: 224,
|
||||
@ -131,12 +116,7 @@ export const companiesMetadata: IConstructorParams[] = [
|
||||
{
|
||||
name: LocationName.Sector12BladeIndustries,
|
||||
info: "",
|
||||
companyPositions: Object.assign(
|
||||
{},
|
||||
AllTechnologyPositions,
|
||||
AllBusinessPositions,
|
||||
AllSecurityPositions,
|
||||
),
|
||||
companyPositions: Object.assign({}, AllTechnologyPositions, AllBusinessPositions, AllSecurityPositions),
|
||||
expMultiplier: 2.75,
|
||||
salaryMultiplier: 2.75,
|
||||
jobStatReqOffset: 224,
|
||||
@ -144,12 +124,7 @@ export const companiesMetadata: IConstructorParams[] = [
|
||||
{
|
||||
name: LocationName.VolhavenNWO,
|
||||
info: "",
|
||||
companyPositions: Object.assign(
|
||||
{},
|
||||
AllTechnologyPositions,
|
||||
AllBusinessPositions,
|
||||
AllSecurityPositions,
|
||||
),
|
||||
companyPositions: Object.assign({}, AllTechnologyPositions, AllBusinessPositions, AllSecurityPositions),
|
||||
expMultiplier: 2.75,
|
||||
salaryMultiplier: 2.75,
|
||||
jobStatReqOffset: 249,
|
||||
@ -157,12 +132,7 @@ export const companiesMetadata: IConstructorParams[] = [
|
||||
{
|
||||
name: LocationName.AevumClarkeIncorporated,
|
||||
info: "",
|
||||
companyPositions: Object.assign(
|
||||
{},
|
||||
AllTechnologyPositions,
|
||||
AllBusinessPositions,
|
||||
AllSecurityPositions,
|
||||
),
|
||||
companyPositions: Object.assign({}, AllTechnologyPositions, AllBusinessPositions, AllSecurityPositions),
|
||||
expMultiplier: 2.25,
|
||||
salaryMultiplier: 2.25,
|
||||
jobStatReqOffset: 224,
|
||||
@ -170,12 +140,7 @@ export const companiesMetadata: IConstructorParams[] = [
|
||||
{
|
||||
name: LocationName.VolhavenOmniTekIncorporated,
|
||||
info: "",
|
||||
companyPositions: Object.assign(
|
||||
{},
|
||||
AllTechnologyPositions,
|
||||
AllBusinessPositions,
|
||||
AllSecurityPositions,
|
||||
),
|
||||
companyPositions: Object.assign({}, AllTechnologyPositions, AllBusinessPositions, AllSecurityPositions),
|
||||
expMultiplier: 2.25,
|
||||
salaryMultiplier: 2.25,
|
||||
jobStatReqOffset: 224,
|
||||
@ -183,12 +148,7 @@ export const companiesMetadata: IConstructorParams[] = [
|
||||
{
|
||||
name: LocationName.Sector12FourSigma,
|
||||
info: "",
|
||||
companyPositions: Object.assign(
|
||||
{},
|
||||
AllTechnologyPositions,
|
||||
AllBusinessPositions,
|
||||
AllSecurityPositions,
|
||||
),
|
||||
companyPositions: Object.assign({}, AllTechnologyPositions, AllBusinessPositions, AllSecurityPositions),
|
||||
expMultiplier: 2.5,
|
||||
salaryMultiplier: 2.5,
|
||||
jobStatReqOffset: 224,
|
||||
@ -196,12 +156,7 @@ export const companiesMetadata: IConstructorParams[] = [
|
||||
{
|
||||
name: LocationName.ChongqingKuaiGongInternational,
|
||||
info: "",
|
||||
companyPositions: Object.assign(
|
||||
{},
|
||||
AllTechnologyPositions,
|
||||
AllBusinessPositions,
|
||||
AllSecurityPositions,
|
||||
),
|
||||
companyPositions: Object.assign({}, AllTechnologyPositions, AllBusinessPositions, AllSecurityPositions),
|
||||
expMultiplier: 2.2,
|
||||
salaryMultiplier: 2.2,
|
||||
jobStatReqOffset: 224,
|
||||
@ -209,11 +164,7 @@ export const companiesMetadata: IConstructorParams[] = [
|
||||
{
|
||||
name: LocationName.AevumFulcrumTechnologies,
|
||||
info: "",
|
||||
companyPositions: Object.assign(
|
||||
{},
|
||||
AllTechnologyPositions,
|
||||
AllBusinessPositions,
|
||||
),
|
||||
companyPositions: Object.assign({}, AllTechnologyPositions, AllBusinessPositions),
|
||||
expMultiplier: 2,
|
||||
salaryMultiplier: 2,
|
||||
jobStatReqOffset: 224,
|
||||
@ -221,12 +172,7 @@ export const companiesMetadata: IConstructorParams[] = [
|
||||
{
|
||||
name: LocationName.IshimaStormTechnologies,
|
||||
info: "",
|
||||
companyPositions: Object.assign(
|
||||
{},
|
||||
AllTechnologyPositions,
|
||||
AllSoftwareConsultantPositions,
|
||||
AllBusinessPositions,
|
||||
),
|
||||
companyPositions: Object.assign({}, AllTechnologyPositions, AllSoftwareConsultantPositions, AllBusinessPositions),
|
||||
expMultiplier: 1.8,
|
||||
salaryMultiplier: 1.8,
|
||||
jobStatReqOffset: 199,
|
||||
@ -234,12 +180,7 @@ export const companiesMetadata: IConstructorParams[] = [
|
||||
{
|
||||
name: LocationName.NewTokyoDefComm,
|
||||
info: "",
|
||||
companyPositions: Object.assign(
|
||||
{},
|
||||
CEOOnly,
|
||||
AllTechnologyPositions,
|
||||
AllSoftwareConsultantPositions,
|
||||
),
|
||||
companyPositions: Object.assign({}, CEOOnly, AllTechnologyPositions, AllSoftwareConsultantPositions),
|
||||
expMultiplier: 1.75,
|
||||
salaryMultiplier: 1.75,
|
||||
jobStatReqOffset: 199,
|
||||
@ -247,12 +188,7 @@ export const companiesMetadata: IConstructorParams[] = [
|
||||
{
|
||||
name: LocationName.VolhavenHeliosLabs,
|
||||
info: "",
|
||||
companyPositions: Object.assign(
|
||||
{},
|
||||
CEOOnly,
|
||||
AllTechnologyPositions,
|
||||
AllSoftwareConsultantPositions,
|
||||
),
|
||||
companyPositions: Object.assign({}, CEOOnly, AllTechnologyPositions, AllSoftwareConsultantPositions),
|
||||
expMultiplier: 1.8,
|
||||
salaryMultiplier: 1.8,
|
||||
jobStatReqOffset: 199,
|
||||
@ -260,12 +196,7 @@ export const companiesMetadata: IConstructorParams[] = [
|
||||
{
|
||||
name: LocationName.NewTokyoVitaLife,
|
||||
info: "",
|
||||
companyPositions: Object.assign(
|
||||
{},
|
||||
AllTechnologyPositions,
|
||||
AllBusinessPositions,
|
||||
AllSoftwareConsultantPositions,
|
||||
),
|
||||
companyPositions: Object.assign({}, AllTechnologyPositions, AllBusinessPositions, AllSoftwareConsultantPositions),
|
||||
expMultiplier: 1.8,
|
||||
salaryMultiplier: 1.8,
|
||||
jobStatReqOffset: 199,
|
||||
@ -273,12 +204,7 @@ export const companiesMetadata: IConstructorParams[] = [
|
||||
{
|
||||
name: LocationName.Sector12IcarusMicrosystems,
|
||||
info: "",
|
||||
companyPositions: Object.assign(
|
||||
{},
|
||||
AllTechnologyPositions,
|
||||
AllBusinessPositions,
|
||||
AllSoftwareConsultantPositions,
|
||||
),
|
||||
companyPositions: Object.assign({}, AllTechnologyPositions, AllBusinessPositions, AllSoftwareConsultantPositions),
|
||||
expMultiplier: 1.9,
|
||||
salaryMultiplier: 1.9,
|
||||
jobStatReqOffset: 199,
|
||||
@ -286,12 +212,7 @@ export const companiesMetadata: IConstructorParams[] = [
|
||||
{
|
||||
name: LocationName.Sector12UniversalEnergy,
|
||||
info: "",
|
||||
companyPositions: Object.assign(
|
||||
{},
|
||||
AllTechnologyPositions,
|
||||
AllBusinessPositions,
|
||||
AllSoftwareConsultantPositions,
|
||||
),
|
||||
companyPositions: Object.assign({}, AllTechnologyPositions, AllBusinessPositions, AllSoftwareConsultantPositions),
|
||||
expMultiplier: 2,
|
||||
salaryMultiplier: 2,
|
||||
jobStatReqOffset: 199,
|
||||
@ -299,12 +220,7 @@ export const companiesMetadata: IConstructorParams[] = [
|
||||
{
|
||||
name: LocationName.AevumGalacticCybersystems,
|
||||
info: "",
|
||||
companyPositions: Object.assign(
|
||||
{},
|
||||
AllTechnologyPositions,
|
||||
AllBusinessPositions,
|
||||
AllSoftwareConsultantPositions,
|
||||
),
|
||||
companyPositions: Object.assign({}, AllTechnologyPositions, AllBusinessPositions, AllSoftwareConsultantPositions),
|
||||
expMultiplier: 1.9,
|
||||
salaryMultiplier: 1.9,
|
||||
jobStatReqOffset: 199,
|
||||
@ -312,13 +228,7 @@ export const companiesMetadata: IConstructorParams[] = [
|
||||
{
|
||||
name: LocationName.AevumAeroCorp,
|
||||
info: "",
|
||||
companyPositions: Object.assign(
|
||||
{},
|
||||
CEOOnly,
|
||||
OperationsManagerOnly,
|
||||
AllTechnologyPositions,
|
||||
AllSecurityPositions,
|
||||
),
|
||||
companyPositions: Object.assign({}, CEOOnly, OperationsManagerOnly, AllTechnologyPositions, AllSecurityPositions),
|
||||
expMultiplier: 1.7,
|
||||
salaryMultiplier: 1.7,
|
||||
jobStatReqOffset: 199,
|
||||
@ -326,13 +236,7 @@ export const companiesMetadata: IConstructorParams[] = [
|
||||
{
|
||||
name: LocationName.VolhavenOmniaCybersystems,
|
||||
info: "",
|
||||
companyPositions: Object.assign(
|
||||
{},
|
||||
CEOOnly,
|
||||
OperationsManagerOnly,
|
||||
AllTechnologyPositions,
|
||||
AllSecurityPositions,
|
||||
),
|
||||
companyPositions: Object.assign({}, CEOOnly, OperationsManagerOnly, AllTechnologyPositions, AllSecurityPositions),
|
||||
expMultiplier: 1.7,
|
||||
salaryMultiplier: 1.7,
|
||||
jobStatReqOffset: 199,
|
||||
@ -340,13 +244,7 @@ export const companiesMetadata: IConstructorParams[] = [
|
||||
{
|
||||
name: LocationName.ChongqingSolarisSpaceSystems,
|
||||
info: "",
|
||||
companyPositions: Object.assign(
|
||||
{},
|
||||
CEOOnly,
|
||||
OperationsManagerOnly,
|
||||
AllTechnologyPositions,
|
||||
AllSecurityPositions,
|
||||
),
|
||||
companyPositions: Object.assign({}, CEOOnly, OperationsManagerOnly, AllTechnologyPositions, AllSecurityPositions),
|
||||
expMultiplier: 1.7,
|
||||
salaryMultiplier: 1.7,
|
||||
jobStatReqOffset: 199,
|
||||
@ -354,13 +252,7 @@ export const companiesMetadata: IConstructorParams[] = [
|
||||
{
|
||||
name: LocationName.Sector12DeltaOne,
|
||||
info: "",
|
||||
companyPositions: Object.assign(
|
||||
{},
|
||||
CEOOnly,
|
||||
OperationsManagerOnly,
|
||||
AllTechnologyPositions,
|
||||
AllSecurityPositions,
|
||||
),
|
||||
companyPositions: Object.assign({}, CEOOnly, OperationsManagerOnly, AllTechnologyPositions, AllSecurityPositions),
|
||||
expMultiplier: 1.6,
|
||||
salaryMultiplier: 1.6,
|
||||
jobStatReqOffset: 199,
|
||||
@ -458,11 +350,7 @@ export const companiesMetadata: IConstructorParams[] = [
|
||||
{
|
||||
name: LocationName.AevumRhoConstruction,
|
||||
info: "",
|
||||
companyPositions: Object.assign(
|
||||
{},
|
||||
SoftwarePositionsUpToLeadDeveloper,
|
||||
BusinessPositionsUpToOperationsManager,
|
||||
),
|
||||
companyPositions: Object.assign({}, SoftwarePositionsUpToLeadDeveloper, BusinessPositionsUpToOperationsManager),
|
||||
expMultiplier: 1.3,
|
||||
salaryMultiplier: 1.3,
|
||||
jobStatReqOffset: 49,
|
||||
@ -483,11 +371,7 @@ export const companiesMetadata: IConstructorParams[] = [
|
||||
{
|
||||
name: LocationName.AevumPolice,
|
||||
info: "",
|
||||
companyPositions: Object.assign(
|
||||
{},
|
||||
AllSecurityPositions,
|
||||
SoftwarePositionsUpToLeadDeveloper,
|
||||
),
|
||||
companyPositions: Object.assign({}, AllSecurityPositions, SoftwarePositionsUpToLeadDeveloper),
|
||||
expMultiplier: 1.3,
|
||||
salaryMultiplier: 1.3,
|
||||
jobStatReqOffset: 99,
|
||||
@ -549,12 +433,7 @@ export const companiesMetadata: IConstructorParams[] = [
|
||||
{
|
||||
name: LocationName.IshimaOmegaSoftware,
|
||||
info: "",
|
||||
companyPositions: Object.assign(
|
||||
{},
|
||||
AllSoftwarePositions,
|
||||
AllSoftwareConsultantPositions,
|
||||
AllITPositions,
|
||||
),
|
||||
companyPositions: Object.assign({}, AllSoftwarePositions, AllSoftwareConsultantPositions, AllITPositions),
|
||||
expMultiplier: 1.1,
|
||||
salaryMultiplier: 1.1,
|
||||
jobStatReqOffset: 49,
|
||||
|
@ -11,19 +11,11 @@ export const SoftwareCompanyPositions: string[] = [
|
||||
"Chief Technology Officer",
|
||||
];
|
||||
|
||||
export const ITCompanyPositions: string[] = [
|
||||
"IT Intern",
|
||||
"IT Analyst",
|
||||
"IT Manager",
|
||||
"Systems Administrator",
|
||||
];
|
||||
export const ITCompanyPositions: string[] = ["IT Intern", "IT Analyst", "IT Manager", "Systems Administrator"];
|
||||
|
||||
export const SecurityEngineerCompanyPositions: string[] = ["Security Engineer"];
|
||||
|
||||
export const NetworkEngineerCompanyPositions: string[] = [
|
||||
"Network Engineer",
|
||||
"Network Administrator",
|
||||
];
|
||||
export const NetworkEngineerCompanyPositions: string[] = ["Network Engineer", "Network Administrator"];
|
||||
|
||||
export const BusinessCompanyPositions: string[] = [
|
||||
"Business Intern",
|
||||
@ -43,25 +35,12 @@ export const SecurityCompanyPositions: string[] = [
|
||||
"Head of Security",
|
||||
];
|
||||
|
||||
export const AgentCompanyPositions: string[] = [
|
||||
"Field Agent",
|
||||
"Secret Agent",
|
||||
"Special Operative",
|
||||
];
|
||||
export const AgentCompanyPositions: string[] = ["Field Agent", "Secret Agent", "Special Operative"];
|
||||
|
||||
export const MiscCompanyPositions: string[] = ["Waiter", "Employee"];
|
||||
|
||||
export const SoftwareConsultantCompanyPositions: string[] = [
|
||||
"Software Consultant",
|
||||
"Senior Software Consultant",
|
||||
];
|
||||
export const SoftwareConsultantCompanyPositions: string[] = ["Software Consultant", "Senior Software Consultant"];
|
||||
|
||||
export const BusinessConsultantCompanyPositions: string[] = [
|
||||
"Business Consultant",
|
||||
"Senior Business Consultant",
|
||||
];
|
||||
export const BusinessConsultantCompanyPositions: string[] = ["Business Consultant", "Senior Business Consultant"];
|
||||
|
||||
export const PartTimeCompanyPositions: string[] = [
|
||||
"Part-time Waiter",
|
||||
"Part-time Employee",
|
||||
];
|
||||
export const PartTimeCompanyPositions: string[] = ["Part-time Waiter", "Part-time Employee"];
|
||||
|
@ -11,11 +11,7 @@ import { CorporationUnlockUpgrade } from "./data/CorporationUnlockUpgrades";
|
||||
import { CorporationUpgrade } from "./data/CorporationUpgrades";
|
||||
import { Cities } from "../Locations/Cities";
|
||||
|
||||
export function NewIndustry(
|
||||
corporation: ICorporation,
|
||||
industry: string,
|
||||
name: string,
|
||||
): void {
|
||||
export function NewIndustry(corporation: ICorporation, industry: string, name: string): void {
|
||||
for (let i = 0; i < corporation.divisions.length; ++i) {
|
||||
if (corporation.divisions[i].name === name) {
|
||||
throw new Error("This division name is already in use!");
|
||||
@ -28,9 +24,7 @@ export function NewIndustry(
|
||||
throw new Error(`Invalid industry: '${industry}'`);
|
||||
}
|
||||
if (corporation.funds.lt(cost)) {
|
||||
throw new Error(
|
||||
"Not enough money to create a new division in this industry",
|
||||
);
|
||||
throw new Error("Not enough money to create a new division in this industry");
|
||||
} else if (name === "") {
|
||||
throw new Error("New division must have a name!");
|
||||
} else {
|
||||
@ -45,19 +39,11 @@ export function NewIndustry(
|
||||
}
|
||||
}
|
||||
|
||||
export function NewCity(
|
||||
corporation: ICorporation,
|
||||
division: IIndustry,
|
||||
city: string,
|
||||
): void {
|
||||
export function NewCity(corporation: ICorporation, division: IIndustry, city: string): void {
|
||||
if (corporation.funds.lt(CorporationConstants.OfficeInitialCost)) {
|
||||
throw new Error(
|
||||
"You don't have enough company funds to open a new office!",
|
||||
);
|
||||
throw new Error("You don't have enough company funds to open a new office!");
|
||||
} else {
|
||||
corporation.funds = corporation.funds.minus(
|
||||
CorporationConstants.OfficeInitialCost,
|
||||
);
|
||||
corporation.funds = corporation.funds.minus(CorporationConstants.OfficeInitialCost);
|
||||
division.offices[city] = new OfficeSpace({
|
||||
loc: city,
|
||||
size: CorporationConstants.OfficeInitialSize,
|
||||
@ -65,20 +51,14 @@ export function NewCity(
|
||||
}
|
||||
}
|
||||
|
||||
export function UnlockUpgrade(
|
||||
corporation: ICorporation,
|
||||
upgrade: CorporationUnlockUpgrade,
|
||||
): void {
|
||||
export function UnlockUpgrade(corporation: ICorporation, upgrade: CorporationUnlockUpgrade): void {
|
||||
if (corporation.funds.lt(upgrade[1])) {
|
||||
throw new Error("Insufficient funds");
|
||||
}
|
||||
corporation.unlock(upgrade);
|
||||
}
|
||||
|
||||
export function LevelUpgrade(
|
||||
corporation: ICorporation,
|
||||
upgrade: CorporationUpgrade,
|
||||
): void {
|
||||
export function LevelUpgrade(corporation: ICorporation, upgrade: CorporationUpgrade): void {
|
||||
const baseCost = upgrade[1];
|
||||
const priceMult = upgrade[2];
|
||||
const level = corporation.upgrades[upgrade[0]];
|
||||
@ -90,18 +70,9 @@ export function LevelUpgrade(
|
||||
}
|
||||
}
|
||||
|
||||
export function IssueDividends(
|
||||
corporation: ICorporation,
|
||||
percent: number,
|
||||
): void {
|
||||
if (
|
||||
isNaN(percent) ||
|
||||
percent < 0 ||
|
||||
percent > CorporationConstants.DividendMaxPercentage
|
||||
) {
|
||||
throw new Error(
|
||||
`Invalid value. Must be an integer between 0 and ${CorporationConstants.DividendMaxPercentage}`,
|
||||
);
|
||||
export function IssueDividends(corporation: ICorporation, percent: number): void {
|
||||
if (isNaN(percent) || percent < 0 || percent > CorporationConstants.DividendMaxPercentage) {
|
||||
throw new Error(`Invalid value. Must be an integer between 0 and ${CorporationConstants.DividendMaxPercentage}`);
|
||||
}
|
||||
|
||||
corporation.dividendPercentage = percent * 100;
|
||||
@ -148,9 +119,7 @@ export function SellMaterial(mat: Material, amt: string, price: string): void {
|
||||
mat.sllman[0] = true;
|
||||
mat.sllman[1] = q; //Use sanitized input
|
||||
} else if (isNaN(parseFloat(amt))) {
|
||||
throw new Error(
|
||||
"Invalid value for sell quantity field! Must be numeric or 'MAX'",
|
||||
);
|
||||
throw new Error("Invalid value for sell quantity field! Must be numeric or 'MAX'");
|
||||
} else {
|
||||
let q = parseFloat(amt);
|
||||
if (isNaN(q)) {
|
||||
@ -166,13 +135,7 @@ export function SellMaterial(mat: Material, amt: string, price: string): void {
|
||||
}
|
||||
}
|
||||
|
||||
export function SellProduct(
|
||||
product: Product,
|
||||
city: string,
|
||||
amt: string,
|
||||
price: string,
|
||||
all: boolean,
|
||||
): void {
|
||||
export function SellProduct(product: Product, city: string, amt: string, price: string, all: boolean): void {
|
||||
//Parse price
|
||||
if (price.includes("MP")) {
|
||||
//Dynamically evaluated quantity. First test to make sure its valid
|
||||
@ -183,9 +146,7 @@ export function SellProduct(
|
||||
try {
|
||||
temp = eval(temp);
|
||||
} catch (e) {
|
||||
throw new Error(
|
||||
"Invalid value or expression for sell quantity field: " + e,
|
||||
);
|
||||
throw new Error("Invalid value or expression for sell quantity field: " + e);
|
||||
}
|
||||
if (temp == null || isNaN(parseFloat(temp))) {
|
||||
throw new Error("Invalid value or expression for sell quantity field.");
|
||||
@ -261,18 +222,13 @@ export function SellProduct(
|
||||
}
|
||||
}
|
||||
|
||||
export function SetSmartSupply(
|
||||
warehouse: Warehouse,
|
||||
smartSupply: boolean,
|
||||
): void {
|
||||
export function SetSmartSupply(warehouse: Warehouse, smartSupply: boolean): void {
|
||||
warehouse.smartSupplyEnabled = smartSupply;
|
||||
}
|
||||
|
||||
export function BuyMaterial(material: Material, amt: number): void {
|
||||
if (isNaN(amt)) {
|
||||
throw new Error(
|
||||
`Invalid amount '${amt}' to buy material '${material.name}'`,
|
||||
);
|
||||
throw new Error(`Invalid amount '${amt}' to buy material '${material.name}'`);
|
||||
}
|
||||
material.buy = amt;
|
||||
}
|
||||
|
@ -1,12 +1,6 @@
|
||||
import { CorporationState } from "./CorporationState";
|
||||
import {
|
||||
CorporationUnlockUpgrade,
|
||||
CorporationUnlockUpgrades,
|
||||
} from "./data/CorporationUnlockUpgrades";
|
||||
import {
|
||||
CorporationUpgrade,
|
||||
CorporationUpgrades,
|
||||
} from "./data/CorporationUpgrades";
|
||||
import { CorporationUnlockUpgrade, CorporationUnlockUpgrades } from "./data/CorporationUnlockUpgrades";
|
||||
import { CorporationUpgrade, CorporationUpgrades } from "./data/CorporationUpgrades";
|
||||
import { Warehouse } from "./Warehouse";
|
||||
import { CorporationConstants } from "./data/Constants";
|
||||
import { Industry } from "./Industry";
|
||||
@ -19,11 +13,7 @@ import { IPlayer } from "../PersonObjects/IPlayer";
|
||||
import { Page, routing } from "../ui/navigationTracking";
|
||||
|
||||
import { dialogBoxCreate } from "../../utils/DialogBox";
|
||||
import {
|
||||
Reviver,
|
||||
Generic_toJSON,
|
||||
Generic_fromJSON,
|
||||
} from "../../utils/JSONReviver";
|
||||
import { Reviver, Generic_toJSON, Generic_fromJSON } from "../../utils/JSONReviver";
|
||||
import { createElement } from "../../utils/uiHelpers/createElement";
|
||||
import { isString } from "../../utils/helpers/isString";
|
||||
import { removeElementById } from "../../utils/uiHelpers/removeElementById";
|
||||
@ -81,9 +71,7 @@ export class Corporation {
|
||||
|
||||
addFunds(amt: number): void {
|
||||
if (!isFinite(amt)) {
|
||||
console.error(
|
||||
"Trying to add invalid amount of funds. Report to a developper.",
|
||||
);
|
||||
console.error("Trying to add invalid amount of funds. Report to a developper.");
|
||||
return;
|
||||
}
|
||||
this.funds = this.funds.plus(amt);
|
||||
@ -101,8 +89,7 @@ export class Corporation {
|
||||
if (this.storedCycles >= CorporationConstants.CyclesPerIndustryStateCycle) {
|
||||
const state = this.getState();
|
||||
const marketCycles = 1;
|
||||
const gameCycles =
|
||||
marketCycles * CorporationConstants.CyclesPerIndustryStateCycle;
|
||||
const gameCycles = marketCycles * CorporationConstants.CyclesPerIndustryStateCycle;
|
||||
this.storedCycles -= gameCycles;
|
||||
|
||||
this.divisions.forEach((ind) => {
|
||||
@ -122,30 +109,18 @@ export class Corporation {
|
||||
this.revenue = new Decimal(0);
|
||||
this.expenses = new Decimal(0);
|
||||
this.divisions.forEach((ind) => {
|
||||
if (
|
||||
ind.lastCycleRevenue === -Infinity ||
|
||||
ind.lastCycleRevenue === Infinity
|
||||
) {
|
||||
if (ind.lastCycleRevenue === -Infinity || ind.lastCycleRevenue === Infinity) {
|
||||
return;
|
||||
}
|
||||
if (
|
||||
ind.lastCycleExpenses === -Infinity ||
|
||||
ind.lastCycleExpenses === Infinity
|
||||
) {
|
||||
if (ind.lastCycleExpenses === -Infinity || ind.lastCycleExpenses === Infinity) {
|
||||
return;
|
||||
}
|
||||
this.revenue = this.revenue.plus(ind.lastCycleRevenue);
|
||||
this.expenses = this.expenses.plus(ind.lastCycleExpenses);
|
||||
});
|
||||
const profit = this.revenue.minus(this.expenses);
|
||||
const cycleProfit = profit.times(
|
||||
marketCycles * CorporationConstants.SecsPerMarketCycle,
|
||||
);
|
||||
if (
|
||||
isNaN(this.funds) ||
|
||||
this.funds === Infinity ||
|
||||
this.funds === -Infinity
|
||||
) {
|
||||
const cycleProfit = profit.times(marketCycles * CorporationConstants.SecsPerMarketCycle);
|
||||
if (isNaN(this.funds) || this.funds === Infinity || this.funds === -Infinity) {
|
||||
dialogBoxCreate(
|
||||
"There was an error calculating your Corporations funds and they got reset to 0. " +
|
||||
"This is a bug. Please report to game developer.<br><br>" +
|
||||
@ -160,21 +135,14 @@ export class Corporation {
|
||||
if (
|
||||
isNaN(this.dividendPercentage) ||
|
||||
this.dividendPercentage < 0 ||
|
||||
this.dividendPercentage >
|
||||
CorporationConstants.DividendMaxPercentage * 100
|
||||
this.dividendPercentage > CorporationConstants.DividendMaxPercentage * 100
|
||||
) {
|
||||
console.error(
|
||||
`Invalid Corporation dividend percentage: ${this.dividendPercentage}`,
|
||||
);
|
||||
console.error(`Invalid Corporation dividend percentage: ${this.dividendPercentage}`);
|
||||
} else {
|
||||
const totalDividends =
|
||||
(this.dividendPercentage / 100) * cycleProfit;
|
||||
const totalDividends = (this.dividendPercentage / 100) * cycleProfit;
|
||||
const retainedEarnings = cycleProfit - totalDividends;
|
||||
const dividendsPerShare = totalDividends / this.totalShares;
|
||||
const profit =
|
||||
this.numShares *
|
||||
dividendsPerShare *
|
||||
(1 - this.dividendTaxPercentage / 100);
|
||||
const profit = this.numShares * dividendsPerShare * (1 - this.dividendTaxPercentage / 100);
|
||||
player.gainMoney(profit);
|
||||
player.recordMoneySource(profit, "corporation");
|
||||
this.addFunds(retainedEarnings);
|
||||
@ -220,9 +188,7 @@ export class Corporation {
|
||||
getTargetSharePrice(): number {
|
||||
// Note: totalShares - numShares is not the same as issuedShares because
|
||||
// issuedShares does not account for private investors
|
||||
return (
|
||||
this.determineValuation() / (2 * (this.totalShares - this.numShares) + 1)
|
||||
);
|
||||
return this.determineValuation() / (2 * (this.totalShares - this.numShares) + 1);
|
||||
}
|
||||
|
||||
updateSharePrice(): void {
|
||||
@ -251,9 +217,7 @@ export class Corporation {
|
||||
let sharesSold = 0;
|
||||
let profit = 0;
|
||||
|
||||
const maxIterations = Math.ceil(
|
||||
numShares / CorporationConstants.SHARESPERPRICEUPDATE,
|
||||
);
|
||||
const maxIterations = Math.ceil(numShares / CorporationConstants.SHARESPERPRICEUPDATE);
|
||||
if (isNaN(maxIterations) || maxIterations > 10e6) {
|
||||
console.error(
|
||||
`Something went wrong or unexpected when calculating share sale. Maxiterations calculated to be ${maxIterations}`,
|
||||
@ -273,9 +237,7 @@ export class Corporation {
|
||||
sharesSold += sharesUntilUpdate;
|
||||
|
||||
// Calculate what new share price would be
|
||||
sharePrice =
|
||||
this.determineValuation() /
|
||||
(2 * (this.totalShares + sharesSold - this.numShares));
|
||||
sharePrice = this.determineValuation() / (2 * (this.totalShares + sharesSold - this.numShares));
|
||||
}
|
||||
}
|
||||
|
||||
@ -350,10 +312,7 @@ export class Corporation {
|
||||
for (const city in industry.warehouses) {
|
||||
const warehouse = industry.warehouses[city];
|
||||
if (warehouse === 0) continue;
|
||||
if (
|
||||
industry.warehouses.hasOwnProperty(city) &&
|
||||
warehouse instanceof Warehouse
|
||||
) {
|
||||
if (industry.warehouses.hasOwnProperty(city) && warehouse instanceof Warehouse) {
|
||||
warehouse.updateSize(this, industry);
|
||||
}
|
||||
}
|
||||
@ -456,10 +415,7 @@ export class Corporation {
|
||||
let hasHandbook = false;
|
||||
const handbookFn = LiteratureNames.CorporationManagementHandbook;
|
||||
for (let i = 0; i < homeComp.messages.length; ++i) {
|
||||
if (
|
||||
isString(homeComp.messages[i]) &&
|
||||
homeComp.messages[i] === handbookFn
|
||||
) {
|
||||
if (isString(homeComp.messages[i]) && homeComp.messages[i] === handbookFn) {
|
||||
hasHandbook = true;
|
||||
break;
|
||||
}
|
||||
@ -486,17 +442,12 @@ export class Corporation {
|
||||
|
||||
rerender(player: IPlayer): void {
|
||||
if (companyManagementDiv == null) {
|
||||
console.warn(
|
||||
`Corporation.rerender() called when companyManagementDiv is null`,
|
||||
);
|
||||
console.warn(`Corporation.rerender() called when companyManagementDiv is null`);
|
||||
return;
|
||||
}
|
||||
if (!routing.isOn(Page.Corporation)) return;
|
||||
|
||||
ReactDOM.render(
|
||||
<CorporationRoot corp={this} player={player} />,
|
||||
companyManagementDiv,
|
||||
);
|
||||
ReactDOM.render(<CorporationRoot corp={this} player={player} />, companyManagementDiv);
|
||||
}
|
||||
|
||||
clearUI(): void {
|
||||
|
@ -1,17 +1,7 @@
|
||||
import {
|
||||
Generic_fromJSON,
|
||||
Generic_toJSON,
|
||||
Reviver,
|
||||
} from "../../utils/JSONReviver";
|
||||
import { Generic_fromJSON, Generic_toJSON, Reviver } from "../../utils/JSONReviver";
|
||||
|
||||
// Array of all valid states
|
||||
export const AllCorporationStates: string[] = [
|
||||
"START",
|
||||
"PURCHASE",
|
||||
"PRODUCTION",
|
||||
"SALE",
|
||||
"EXPORT",
|
||||
];
|
||||
export const AllCorporationStates: string[] = ["START", "PURCHASE", "PRODUCTION", "SALE", "EXPORT"];
|
||||
|
||||
export class CorporationState {
|
||||
// Number representing what state the Corporation is in. The number
|
||||
|
@ -1,10 +1,6 @@
|
||||
import { CorporationConstants } from "./data/Constants";
|
||||
import { getRandomInt } from "../../utils/helpers/getRandomInt";
|
||||
import {
|
||||
Generic_fromJSON,
|
||||
Generic_toJSON,
|
||||
Reviver,
|
||||
} from "../../utils/JSONReviver";
|
||||
import { Generic_fromJSON, Generic_toJSON, Reviver } from "../../utils/JSONReviver";
|
||||
import { createElement } from "../../utils/uiHelpers/createElement";
|
||||
import { EmployeePositions } from "./EmployeePositions";
|
||||
import { ICorporation } from "./ICorporation";
|
||||
@ -93,39 +89,22 @@ export class Employee {
|
||||
if (this.hap < office.minHap) {
|
||||
this.hap = office.minHap;
|
||||
}
|
||||
const salary =
|
||||
this.sal * marketCycles * CorporationConstants.SecsPerMarketCycle;
|
||||
const salary = this.sal * marketCycles * CorporationConstants.SecsPerMarketCycle;
|
||||
return salary;
|
||||
}
|
||||
|
||||
calculateProductivity(
|
||||
corporation: ICorporation,
|
||||
industry: IIndustry,
|
||||
): number {
|
||||
const effCre =
|
||||
this.cre *
|
||||
corporation.getEmployeeCreMultiplier() *
|
||||
industry.getEmployeeCreMultiplier(),
|
||||
effCha =
|
||||
this.cha *
|
||||
corporation.getEmployeeChaMultiplier() *
|
||||
industry.getEmployeeChaMultiplier(),
|
||||
effInt =
|
||||
this.int *
|
||||
corporation.getEmployeeIntMultiplier() *
|
||||
industry.getEmployeeIntMultiplier(),
|
||||
effEff =
|
||||
this.eff *
|
||||
corporation.getEmployeeEffMultiplier() *
|
||||
industry.getEmployeeEffMultiplier();
|
||||
calculateProductivity(corporation: ICorporation, industry: IIndustry): number {
|
||||
const effCre = this.cre * corporation.getEmployeeCreMultiplier() * industry.getEmployeeCreMultiplier(),
|
||||
effCha = this.cha * corporation.getEmployeeChaMultiplier() * industry.getEmployeeChaMultiplier(),
|
||||
effInt = this.int * corporation.getEmployeeIntMultiplier() * industry.getEmployeeIntMultiplier(),
|
||||
effEff = this.eff * corporation.getEmployeeEffMultiplier() * industry.getEmployeeEffMultiplier();
|
||||
const prodBase = this.mor * this.hap * this.ene * 1e-6;
|
||||
let prodMult = 0;
|
||||
switch (this.pos) {
|
||||
//Calculate productivity based on position. This is multipled by prodBase
|
||||
//to get final value
|
||||
case EmployeePositions.Operations:
|
||||
prodMult =
|
||||
0.6 * effInt + 0.1 * effCha + this.exp + 0.5 * effCre + effEff;
|
||||
prodMult = 0.6 * effInt + 0.1 * effCha + this.exp + 0.5 * effCre + effEff;
|
||||
break;
|
||||
case EmployeePositions.Engineer:
|
||||
prodMult = effInt + 0.1 * effCha + 1.5 * this.exp + effEff;
|
||||
@ -161,27 +140,11 @@ export class Employee {
|
||||
}
|
||||
|
||||
//'panel' is the DOM element on which to create the UI
|
||||
createUI(
|
||||
panel: HTMLElement,
|
||||
corporation: ICorporation,
|
||||
industry: IIndustry,
|
||||
): void {
|
||||
const effCre =
|
||||
this.cre *
|
||||
corporation.getEmployeeCreMultiplier() *
|
||||
industry.getEmployeeCreMultiplier(),
|
||||
effCha =
|
||||
this.cha *
|
||||
corporation.getEmployeeChaMultiplier() *
|
||||
industry.getEmployeeChaMultiplier(),
|
||||
effInt =
|
||||
this.int *
|
||||
corporation.getEmployeeIntMultiplier() *
|
||||
industry.getEmployeeIntMultiplier(),
|
||||
effEff =
|
||||
this.eff *
|
||||
corporation.getEmployeeEffMultiplier() *
|
||||
industry.getEmployeeEffMultiplier();
|
||||
createUI(panel: HTMLElement, corporation: ICorporation, industry: IIndustry): void {
|
||||
const effCre = this.cre * corporation.getEmployeeCreMultiplier() * industry.getEmployeeCreMultiplier(),
|
||||
effCha = this.cha * corporation.getEmployeeChaMultiplier() * industry.getEmployeeChaMultiplier(),
|
||||
effInt = this.int * corporation.getEmployeeIntMultiplier() * industry.getEmployeeIntMultiplier(),
|
||||
effEff = this.eff * corporation.getEmployeeEffMultiplier() * industry.getEmployeeEffMultiplier();
|
||||
panel.style.color = "white";
|
||||
panel.appendChild(
|
||||
createElement("p", {
|
||||
|
@ -52,28 +52,12 @@ export interface IIndustry {
|
||||
process(marketCycles: number, state: string, corporation: ICorporation): void;
|
||||
processMaterialMarket(): void;
|
||||
processProductMarket(marketCycles: number): void;
|
||||
processMaterials(
|
||||
marketCycles: number,
|
||||
corporation: ICorporation,
|
||||
): [number, number];
|
||||
processProducts(
|
||||
marketCycles: number,
|
||||
corporation: ICorporation,
|
||||
): [number, number];
|
||||
processProduct(
|
||||
marketCycles: number,
|
||||
product: Product,
|
||||
corporation: ICorporation,
|
||||
): number;
|
||||
processMaterials(marketCycles: number, corporation: ICorporation): [number, number];
|
||||
processProducts(marketCycles: number, corporation: ICorporation): [number, number];
|
||||
processProduct(marketCycles: number, product: Product, corporation: ICorporation): number;
|
||||
discontinueProduct(product: Product): void;
|
||||
upgrade(
|
||||
upgrade: IndustryUpgrade,
|
||||
refs: { corporation: ICorporation; office: OfficeSpace },
|
||||
): void;
|
||||
getOfficeProductivity(
|
||||
office: OfficeSpace,
|
||||
params?: { forProduct?: boolean },
|
||||
): number;
|
||||
upgrade(upgrade: IndustryUpgrade, refs: { corporation: ICorporation; office: OfficeSpace }): void;
|
||||
getOfficeProductivity(office: OfficeSpace, params?: { forProduct?: boolean }): number;
|
||||
getBusinessFactor(office: OfficeSpace): number;
|
||||
getAdvertisingFactors(): [number, number, number, number];
|
||||
getMarketFactor(mat: { dmd: number; cmp: number }): number;
|
||||
|
@ -1,15 +1,7 @@
|
||||
import {
|
||||
Reviver,
|
||||
Generic_toJSON,
|
||||
Generic_fromJSON,
|
||||
} from "../../utils/JSONReviver";
|
||||
import { Reviver, Generic_toJSON, Generic_fromJSON } from "../../utils/JSONReviver";
|
||||
import { CityName } from "../Locations/data/CityNames";
|
||||
import Decimal from "decimal.js";
|
||||
import {
|
||||
Industries,
|
||||
IndustryStartingCosts,
|
||||
IndustryResearchTrees,
|
||||
} from "./IndustryData";
|
||||
import { Industries, IndustryStartingCosts, IndustryResearchTrees } from "./IndustryData";
|
||||
import { CorporationConstants } from "./data/Constants";
|
||||
import { EmployeePositions } from "./EmployeePositions";
|
||||
import { Material } from "./Material";
|
||||
@ -121,8 +113,7 @@ export class Industry implements IIndustry {
|
||||
init(): void {
|
||||
//Set the unique properties of an industry (how much its affected by real estate/scientific research, etc.)
|
||||
const startingCost = IndustryStartingCosts[this.type];
|
||||
if (startingCost === undefined)
|
||||
throw new Error(`Invalid industry: "${this.type}"`);
|
||||
if (startingCost === undefined) throw new Error(`Invalid industry: "${this.type}"`);
|
||||
this.startingCost = startingCost;
|
||||
switch (this.type) {
|
||||
case Industries.Energy:
|
||||
@ -316,9 +307,7 @@ export class Industry implements IIndustry {
|
||||
this.makesProducts = true;
|
||||
break;
|
||||
default:
|
||||
console.error(
|
||||
`Invalid Industry Type passed into Industry.init(): ${this.type}`,
|
||||
);
|
||||
console.error(`Invalid Industry Type passed into Industry.init(): ${this.type}`);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -344,9 +333,7 @@ export class Industry implements IIndustry {
|
||||
case Industries.RealEstate:
|
||||
return "develop and manage real estate properties";
|
||||
default:
|
||||
console.error(
|
||||
"Invalid industry type in Industry.getProductDescriptionText",
|
||||
);
|
||||
console.error("Invalid industry type in Industry.getProductDescriptionText");
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@ -399,11 +386,7 @@ export class Industry implements IIndustry {
|
||||
if (prod === undefined) continue;
|
||||
warehouse.sizeUsed += prod.data[warehouse.loc][0] * prod.siz;
|
||||
if (prod.data[warehouse.loc][0] > 0) {
|
||||
warehouse.breakdown +=
|
||||
prodName +
|
||||
": " +
|
||||
formatNumber(prod.data[warehouse.loc][0] * prod.siz, 0) +
|
||||
"<br>";
|
||||
warehouse.breakdown += prodName + ": " + formatNumber(prod.data[warehouse.loc][0] * prod.siz, 0) + "<br>";
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -423,12 +406,8 @@ export class Industry implements IIndustry {
|
||||
this.thisCycleRevenue = new Decimal(0);
|
||||
this.thisCycleExpenses = new Decimal(0);
|
||||
}
|
||||
this.lastCycleRevenue = this.thisCycleRevenue.dividedBy(
|
||||
marketCycles * CorporationConstants.SecsPerMarketCycle,
|
||||
);
|
||||
this.lastCycleExpenses = this.thisCycleExpenses.dividedBy(
|
||||
marketCycles * CorporationConstants.SecsPerMarketCycle,
|
||||
);
|
||||
this.lastCycleRevenue = this.thisCycleRevenue.dividedBy(marketCycles * CorporationConstants.SecsPerMarketCycle);
|
||||
this.lastCycleExpenses = this.thisCycleExpenses.dividedBy(marketCycles * CorporationConstants.SecsPerMarketCycle);
|
||||
this.thisCycleRevenue = new Decimal(0);
|
||||
this.thisCycleExpenses = new Decimal(0);
|
||||
|
||||
@ -493,9 +472,7 @@ export class Industry implements IIndustry {
|
||||
for (let i = 0; i < CorporationConstants.Cities.length; ++i) {
|
||||
//If this industry has a warehouse in this city, process the market
|
||||
//for every material this industry requires or produces
|
||||
if (
|
||||
this.warehouses[CorporationConstants.Cities[i]] instanceof Warehouse
|
||||
) {
|
||||
if (this.warehouses[CorporationConstants.Cities[i]] instanceof Warehouse) {
|
||||
const wh = this.warehouses[CorporationConstants.Cities[i]];
|
||||
if (wh === 0) continue;
|
||||
for (const name in reqMats) {
|
||||
@ -545,10 +522,7 @@ export class Industry implements IIndustry {
|
||||
}
|
||||
|
||||
//Process production, purchase, and import/export of materials
|
||||
processMaterials(
|
||||
marketCycles = 1,
|
||||
corporation: ICorporation,
|
||||
): [number, number] {
|
||||
processMaterials(marketCycles = 1, corporation: ICorporation): [number, number] {
|
||||
let revenue = 0,
|
||||
expenses = 0;
|
||||
this.calculateProductionFactors();
|
||||
@ -588,24 +562,15 @@ export class Industry implements IIndustry {
|
||||
const mat = warehouse.materials[matName];
|
||||
let buyAmt = 0;
|
||||
let maxAmt = 0;
|
||||
if (
|
||||
warehouse.smartSupplyEnabled &&
|
||||
Object.keys(this.reqMats).includes(matName)
|
||||
) {
|
||||
if (warehouse.smartSupplyEnabled && Object.keys(this.reqMats).includes(matName)) {
|
||||
continue;
|
||||
}
|
||||
buyAmt =
|
||||
mat.buy *
|
||||
CorporationConstants.SecsPerMarketCycle *
|
||||
marketCycles;
|
||||
buyAmt = mat.buy * CorporationConstants.SecsPerMarketCycle * marketCycles;
|
||||
|
||||
if (matName == "RealEstate") {
|
||||
maxAmt = buyAmt;
|
||||
} else {
|
||||
maxAmt = Math.floor(
|
||||
(warehouse.size - warehouse.sizeUsed) /
|
||||
MaterialSizes[matName],
|
||||
);
|
||||
maxAmt = Math.floor((warehouse.size - warehouse.sizeUsed) / MaterialSizes[matName]);
|
||||
}
|
||||
buyAmt = Math.min(buyAmt, maxAmt);
|
||||
if (buyAmt > 0) {
|
||||
@ -619,25 +584,15 @@ export class Industry implements IIndustry {
|
||||
const smartBuy: { [key: string]: number | undefined } = {};
|
||||
for (const matName in warehouse.materials) {
|
||||
if (!warehouse.materials.hasOwnProperty(matName)) continue;
|
||||
if (
|
||||
!warehouse.smartSupplyEnabled ||
|
||||
!Object.keys(this.reqMats).includes(matName)
|
||||
)
|
||||
continue;
|
||||
if (!warehouse.smartSupplyEnabled || !Object.keys(this.reqMats).includes(matName)) continue;
|
||||
const mat = warehouse.materials[matName];
|
||||
|
||||
//Smart supply tracker is stored as per second rate
|
||||
const reqMat = this.reqMats[matName];
|
||||
if (reqMat === undefined)
|
||||
throw new Error(`reqMat "${matName}" is undefined`);
|
||||
if (reqMat === undefined) throw new Error(`reqMat "${matName}" is undefined`);
|
||||
mat.buy = reqMat * warehouse.smartSupplyStore;
|
||||
let buyAmt =
|
||||
mat.buy *
|
||||
CorporationConstants.SecsPerMarketCycle *
|
||||
marketCycles;
|
||||
const maxAmt = Math.floor(
|
||||
(warehouse.size - warehouse.sizeUsed) / MaterialSizes[matName],
|
||||
);
|
||||
let buyAmt = mat.buy * CorporationConstants.SecsPerMarketCycle * marketCycles;
|
||||
const maxAmt = Math.floor((warehouse.size - warehouse.sizeUsed) / MaterialSizes[matName]);
|
||||
buyAmt = Math.min(buyAmt, maxAmt);
|
||||
if (buyAmt > 0) smartBuy[matName] = buyAmt;
|
||||
}
|
||||
@ -646,11 +601,9 @@ export class Industry implements IIndustry {
|
||||
let worseAmt = 1e99;
|
||||
for (const matName in smartBuy) {
|
||||
const buyAmt = smartBuy[matName];
|
||||
if (buyAmt === undefined)
|
||||
throw new Error(`Somehow smartbuy matname is undefined`);
|
||||
if (buyAmt === undefined) throw new Error(`Somehow smartbuy matname is undefined`);
|
||||
const reqMat = this.reqMats[matName];
|
||||
if (reqMat === undefined)
|
||||
throw new Error(`reqMat "${matName}" is undefined`);
|
||||
if (reqMat === undefined) throw new Error(`reqMat "${matName}" is undefined`);
|
||||
const amt = buyAmt / reqMat;
|
||||
if (amt < worseAmt) worseAmt = amt;
|
||||
}
|
||||
@ -658,8 +611,7 @@ export class Industry implements IIndustry {
|
||||
// Align all the materials to the smallest amount.
|
||||
for (const matName in smartBuy) {
|
||||
const reqMat = this.reqMats[matName];
|
||||
if (reqMat === undefined)
|
||||
throw new Error(`reqMat "${matName}" is undefined`);
|
||||
if (reqMat === undefined) throw new Error(`reqMat "${matName}" is undefined`);
|
||||
smartBuy[matName] = worseAmt * reqMat;
|
||||
}
|
||||
|
||||
@ -667,8 +619,7 @@ export class Industry implements IIndustry {
|
||||
let totalSize = 0;
|
||||
for (const matName in smartBuy) {
|
||||
const buyAmt = smartBuy[matName];
|
||||
if (buyAmt === undefined)
|
||||
throw new Error(`Somehow smartbuy matname is undefined`);
|
||||
if (buyAmt === undefined) throw new Error(`Somehow smartbuy matname is undefined`);
|
||||
totalSize += buyAmt * MaterialSizes[matName];
|
||||
}
|
||||
|
||||
@ -677,11 +628,8 @@ export class Industry implements IIndustry {
|
||||
if (totalSize > freeSpace) {
|
||||
for (const matName in smartBuy) {
|
||||
const buyAmt = smartBuy[matName];
|
||||
if (buyAmt === undefined)
|
||||
throw new Error(`Somehow smartbuy matname is undefined`);
|
||||
smartBuy[matName] = Math.floor(
|
||||
(buyAmt * freeSpace) / totalSize,
|
||||
);
|
||||
if (buyAmt === undefined) throw new Error(`Somehow smartbuy matname is undefined`);
|
||||
smartBuy[matName] = Math.floor((buyAmt * freeSpace) / totalSize);
|
||||
}
|
||||
}
|
||||
|
||||
@ -690,8 +638,7 @@ export class Industry implements IIndustry {
|
||||
if (!warehouse.smartSupplyUseLeftovers[matName]) continue;
|
||||
const mat = warehouse.materials[matName];
|
||||
const buyAmt = smartBuy[matName];
|
||||
if (buyAmt === undefined)
|
||||
throw new Error(`Somehow smartbuy matname is undefined`);
|
||||
if (buyAmt === undefined) throw new Error(`Somehow smartbuy matname is undefined`);
|
||||
smartBuy[matName] = Math.max(0, buyAmt - mat.qty);
|
||||
}
|
||||
|
||||
@ -699,8 +646,7 @@ export class Industry implements IIndustry {
|
||||
for (const matName in smartBuy) {
|
||||
const mat = warehouse.materials[matName];
|
||||
const buyAmt = smartBuy[matName];
|
||||
if (buyAmt === undefined)
|
||||
throw new Error(`Somehow smartbuy matname is undefined`);
|
||||
if (buyAmt === undefined) throw new Error(`Somehow smartbuy matname is undefined`);
|
||||
mat.qty += buyAmt;
|
||||
expenses += buyAmt * mat.bCost;
|
||||
}
|
||||
@ -741,9 +687,7 @@ export class Industry implements IIndustry {
|
||||
}
|
||||
// If not enough space in warehouse, limit the amount of produced materials
|
||||
if (totalMatSize > 0) {
|
||||
const maxAmt = Math.floor(
|
||||
(warehouse.size - warehouse.sizeUsed) / totalMatSize,
|
||||
);
|
||||
const maxAmt = Math.floor((warehouse.size - warehouse.sizeUsed) / totalMatSize);
|
||||
prod = Math.min(maxAmt, prod);
|
||||
}
|
||||
|
||||
@ -752,8 +696,7 @@ export class Industry implements IIndustry {
|
||||
}
|
||||
|
||||
// Keep track of production for smart supply (/s)
|
||||
warehouse.smartSupplyStore +=
|
||||
prod / (CorporationConstants.SecsPerMarketCycle * marketCycles);
|
||||
warehouse.smartSupplyStore += prod / (CorporationConstants.SecsPerMarketCycle * marketCycles);
|
||||
|
||||
// Make sure we have enough resource to make our materials
|
||||
let producableFrac = 1;
|
||||
@ -763,10 +706,7 @@ export class Industry implements IIndustry {
|
||||
if (reqMat === undefined) continue;
|
||||
const req = reqMat * prod;
|
||||
if (warehouse.materials[reqMatName].qty < req) {
|
||||
producableFrac = Math.min(
|
||||
producableFrac,
|
||||
warehouse.materials[reqMatName].qty / req,
|
||||
);
|
||||
producableFrac = Math.min(producableFrac, warehouse.materials[reqMatName].qty / req);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -784,17 +724,14 @@ export class Industry implements IIndustry {
|
||||
warehouse.materials[reqMatName].qty -= reqMatQtyNeeded;
|
||||
warehouse.materials[reqMatName].prd = 0;
|
||||
warehouse.materials[reqMatName].prd -=
|
||||
reqMatQtyNeeded /
|
||||
(CorporationConstants.SecsPerMarketCycle * marketCycles);
|
||||
reqMatQtyNeeded / (CorporationConstants.SecsPerMarketCycle * marketCycles);
|
||||
}
|
||||
for (let j = 0; j < this.prodMats.length; ++j) {
|
||||
warehouse.materials[this.prodMats[j]].qty +=
|
||||
prod * producableFrac;
|
||||
warehouse.materials[this.prodMats[j]].qty += prod * producableFrac;
|
||||
warehouse.materials[this.prodMats[j]].qlt =
|
||||
office.employeeProd[EmployeePositions.Engineer] / 90 +
|
||||
Math.pow(this.sciResearch.qty, this.sciFac) +
|
||||
Math.pow(warehouse.materials["AICores"].qty, this.aiFac) /
|
||||
10e3;
|
||||
Math.pow(warehouse.materials["AICores"].qty, this.aiFac) / 10e3;
|
||||
}
|
||||
} else {
|
||||
for (const reqMatName in this.reqMats) {
|
||||
@ -805,9 +742,7 @@ export class Industry implements IIndustry {
|
||||
}
|
||||
|
||||
//Per second
|
||||
const fooProd =
|
||||
(prod * producableFrac) /
|
||||
(CorporationConstants.SecsPerMarketCycle * marketCycles);
|
||||
const fooProd = (prod * producableFrac) / (CorporationConstants.SecsPerMarketCycle * marketCycles);
|
||||
for (let fooI = 0; fooI < this.prodMats.length; ++fooI) {
|
||||
warehouse.materials[this.prodMats[fooI]].prd = fooProd;
|
||||
}
|
||||
@ -855,18 +790,14 @@ export class Industry implements IIndustry {
|
||||
corporation.getSalesMultiplier() *
|
||||
advertisingFactor *
|
||||
this.getSalesMultiplier();
|
||||
const denominator = Math.sqrt(
|
||||
sqrtNumerator / sqrtDenominator,
|
||||
);
|
||||
const denominator = Math.sqrt(sqrtNumerator / sqrtDenominator);
|
||||
let optimalPrice;
|
||||
if (sqrtDenominator === 0 || denominator === 0) {
|
||||
if (sqrtNumerator === 0) {
|
||||
optimalPrice = 0; // No production
|
||||
} else {
|
||||
optimalPrice = mat.bCost + markupLimit;
|
||||
console.warn(
|
||||
`In Corporation, found illegal 0s when trying to calculate MarketTA2 sale cost`,
|
||||
);
|
||||
console.warn(`In Corporation, found illegal 0s when trying to calculate MarketTA2 sale cost`);
|
||||
}
|
||||
} else {
|
||||
optimalPrice = numerator / denominator + mat.bCost;
|
||||
@ -913,10 +844,7 @@ export class Industry implements IIndustry {
|
||||
let sellAmt;
|
||||
if (isString(mat.sllman[1])) {
|
||||
//Dynamically evaluated
|
||||
let tmp = (mat.sllman[1] as string).replace(
|
||||
/MAX/g,
|
||||
maxSell + "",
|
||||
);
|
||||
let tmp = (mat.sllman[1] as string).replace(/MAX/g, maxSell + "");
|
||||
tmp = tmp.replace(/PROD/g, mat.prd + "");
|
||||
try {
|
||||
sellAmt = eval(tmp);
|
||||
@ -942,24 +870,17 @@ export class Industry implements IIndustry {
|
||||
sellAmt = Math.min(maxSell, mat.sllman[1] as number);
|
||||
}
|
||||
|
||||
sellAmt =
|
||||
sellAmt *
|
||||
CorporationConstants.SecsPerMarketCycle *
|
||||
marketCycles;
|
||||
sellAmt = sellAmt * CorporationConstants.SecsPerMarketCycle * marketCycles;
|
||||
sellAmt = Math.min(mat.qty, sellAmt);
|
||||
if (sellAmt < 0) {
|
||||
console.warn(
|
||||
`sellAmt calculated to be negative for ${matName} in ${city}`,
|
||||
);
|
||||
console.warn(`sellAmt calculated to be negative for ${matName} in ${city}`);
|
||||
mat.sll = 0;
|
||||
continue;
|
||||
}
|
||||
if (sellAmt && sCost >= 0) {
|
||||
mat.qty -= sellAmt;
|
||||
revenue += sellAmt * sCost;
|
||||
mat.sll =
|
||||
sellAmt /
|
||||
(CorporationConstants.SecsPerMarketCycle * marketCycles);
|
||||
mat.sll = sellAmt / (CorporationConstants.SecsPerMarketCycle * marketCycles);
|
||||
} else {
|
||||
mat.sll = 0;
|
||||
}
|
||||
@ -976,9 +897,7 @@ export class Industry implements IIndustry {
|
||||
const exp = mat.exp[expI];
|
||||
const amtStr = exp.amt.replace(
|
||||
/MAX/g,
|
||||
mat.qty /
|
||||
(CorporationConstants.SecsPerMarketCycle * marketCycles) +
|
||||
"",
|
||||
mat.qty / (CorporationConstants.SecsPerMarketCycle * marketCycles) + "",
|
||||
);
|
||||
let amt = 0;
|
||||
try {
|
||||
@ -1009,10 +928,7 @@ export class Industry implements IIndustry {
|
||||
);
|
||||
continue;
|
||||
}
|
||||
amt =
|
||||
amt *
|
||||
CorporationConstants.SecsPerMarketCycle *
|
||||
marketCycles;
|
||||
amt = amt * CorporationConstants.SecsPerMarketCycle * marketCycles;
|
||||
|
||||
if (mat.qty < amt) {
|
||||
amt = mat.qty;
|
||||
@ -1025,9 +941,7 @@ export class Industry implements IIndustry {
|
||||
const expIndustry = corporation.divisions[foo];
|
||||
const expWarehouse = expIndustry.warehouses[exp.city];
|
||||
if (!(expWarehouse instanceof Warehouse)) {
|
||||
console.error(
|
||||
`Invalid export! ${expIndustry.name} ${exp.city}`,
|
||||
);
|
||||
console.error(`Invalid export! ${expIndustry.name} ${exp.city}`);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1037,16 +951,11 @@ export class Industry implements IIndustry {
|
||||
// affect revenue so just return 0's
|
||||
return [0, 0];
|
||||
} else {
|
||||
const maxAmt = Math.floor(
|
||||
(expWarehouse.size - expWarehouse.sizeUsed) /
|
||||
MaterialSizes[matName],
|
||||
);
|
||||
const maxAmt = Math.floor((expWarehouse.size - expWarehouse.sizeUsed) / MaterialSizes[matName]);
|
||||
amt = Math.min(maxAmt, amt);
|
||||
}
|
||||
expWarehouse.materials[matName].imp +=
|
||||
amt /
|
||||
(CorporationConstants.SecsPerMarketCycle *
|
||||
marketCycles);
|
||||
amt / (CorporationConstants.SecsPerMarketCycle * marketCycles);
|
||||
expWarehouse.materials[matName].qty += amt;
|
||||
expWarehouse.materials[matName].qlt = mat.qlt;
|
||||
mat.qty -= amt;
|
||||
@ -1057,8 +966,7 @@ export class Industry implements IIndustry {
|
||||
}
|
||||
}
|
||||
//totalExp should be per second
|
||||
mat.totalExp /=
|
||||
CorporationConstants.SecsPerMarketCycle * marketCycles;
|
||||
mat.totalExp /= CorporationConstants.SecsPerMarketCycle * marketCycles;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1087,10 +995,7 @@ export class Industry implements IIndustry {
|
||||
}
|
||||
|
||||
//Process production & sale of this industry's FINISHED products (including all of their stats)
|
||||
processProducts(
|
||||
marketCycles = 1,
|
||||
corporation: ICorporation,
|
||||
): [number, number] {
|
||||
processProducts(marketCycles = 1, corporation: ICorporation): [number, number] {
|
||||
let revenue = 0;
|
||||
const expenses = 0;
|
||||
|
||||
@ -1116,8 +1021,7 @@ export class Industry implements IIndustry {
|
||||
// Management is a multiplier for the production from Engineers
|
||||
const mgmtFactor = 1 + mgmtProd / (1.2 * total);
|
||||
|
||||
const progress =
|
||||
(Math.pow(engrProd, 0.34) + Math.pow(opProd, 0.2)) * mgmtFactor;
|
||||
const progress = (Math.pow(engrProd, 0.34) + Math.pow(opProd, 0.2)) * mgmtFactor;
|
||||
|
||||
prod.createProduct(marketCycles, progress);
|
||||
if (prod.prog >= 100) {
|
||||
@ -1141,11 +1045,7 @@ export class Industry implements IIndustry {
|
||||
}
|
||||
|
||||
//Processes FINISHED products
|
||||
processProduct(
|
||||
marketCycles = 1,
|
||||
product: Product,
|
||||
corporation: ICorporation,
|
||||
): number {
|
||||
processProduct(marketCycles = 1, product: Product, corporation: ICorporation): number {
|
||||
let totalProfit = 0;
|
||||
for (let i = 0; i < CorporationConstants.Cities.length; ++i) {
|
||||
const city = CorporationConstants.Cities[i];
|
||||
@ -1184,14 +1084,11 @@ export class Industry implements IIndustry {
|
||||
|
||||
//If there's not enough space in warehouse, limit the amount of Product
|
||||
if (netStorageSize > 0) {
|
||||
const maxAmt = Math.floor(
|
||||
(warehouse.size - warehouse.sizeUsed) / netStorageSize,
|
||||
);
|
||||
const maxAmt = Math.floor((warehouse.size - warehouse.sizeUsed) / netStorageSize);
|
||||
prod = Math.min(maxAmt, prod);
|
||||
}
|
||||
|
||||
warehouse.smartSupplyStore +=
|
||||
prod / (CorporationConstants.SecsPerMarketCycle * marketCycles);
|
||||
warehouse.smartSupplyStore += prod / (CorporationConstants.SecsPerMarketCycle * marketCycles);
|
||||
|
||||
//Make sure we have enough resources to make our Products
|
||||
let producableFrac = 1;
|
||||
@ -1199,10 +1096,7 @@ export class Industry implements IIndustry {
|
||||
if (product.reqMats.hasOwnProperty(reqMatName)) {
|
||||
const req = product.reqMats[reqMatName] * prod;
|
||||
if (warehouse.materials[reqMatName].qty < req) {
|
||||
producableFrac = Math.min(
|
||||
producableFrac,
|
||||
warehouse.materials[reqMatName].qty / req,
|
||||
);
|
||||
producableFrac = Math.min(producableFrac, warehouse.materials[reqMatName].qty / req);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1211,12 +1105,10 @@ export class Industry implements IIndustry {
|
||||
if (producableFrac > 0 && prod > 0) {
|
||||
for (const reqMatName in product.reqMats) {
|
||||
if (product.reqMats.hasOwnProperty(reqMatName)) {
|
||||
const reqMatQtyNeeded =
|
||||
product.reqMats[reqMatName] * prod * producableFrac;
|
||||
const reqMatQtyNeeded = product.reqMats[reqMatName] * prod * producableFrac;
|
||||
warehouse.materials[reqMatName].qty -= reqMatQtyNeeded;
|
||||
warehouse.materials[reqMatName].prd -=
|
||||
reqMatQtyNeeded /
|
||||
(CorporationConstants.SecsPerMarketCycle * marketCycles);
|
||||
reqMatQtyNeeded / (CorporationConstants.SecsPerMarketCycle * marketCycles);
|
||||
}
|
||||
}
|
||||
//Quantity
|
||||
@ -1224,9 +1116,7 @@ export class Industry implements IIndustry {
|
||||
}
|
||||
|
||||
//Keep track of production Per second
|
||||
product.data[city][1] =
|
||||
(prod * producableFrac) /
|
||||
(CorporationConstants.SecsPerMarketCycle * marketCycles);
|
||||
product.data[city][1] = (prod * producableFrac) / (CorporationConstants.SecsPerMarketCycle * marketCycles);
|
||||
break;
|
||||
}
|
||||
case "SALE": {
|
||||
@ -1234,9 +1124,7 @@ export class Industry implements IIndustry {
|
||||
product.pCost = 0; //Estimated production cost
|
||||
for (const reqMatName in product.reqMats) {
|
||||
if (product.reqMats.hasOwnProperty(reqMatName)) {
|
||||
product.pCost +=
|
||||
product.reqMats[reqMatName] *
|
||||
warehouse.materials[reqMatName].bCost;
|
||||
product.pCost += product.reqMats[reqMatName] * warehouse.materials[reqMatName].bCost;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1275,9 +1163,7 @@ export class Industry implements IIndustry {
|
||||
optimalPrice = 0; // No production
|
||||
} else {
|
||||
optimalPrice = product.pCost + markupLimit;
|
||||
console.warn(
|
||||
`In Corporation, found illegal 0s when trying to calculate MarketTA2 sale cost`,
|
||||
);
|
||||
console.warn(`In Corporation, found illegal 0s when trying to calculate MarketTA2 sale cost`);
|
||||
}
|
||||
} else {
|
||||
optimalPrice = numerator / denominator + product.pCost;
|
||||
@ -1294,10 +1180,7 @@ export class Industry implements IIndustry {
|
||||
console.error(`mku is zero, reverting to 1 to avoid Infinity`);
|
||||
product.mku = 1;
|
||||
}
|
||||
sCost = sCostString.replace(
|
||||
/MP/g,
|
||||
product.pCost + product.rat / product.mku + "",
|
||||
);
|
||||
sCost = sCostString.replace(/MP/g, product.pCost + product.rat / product.mku + "");
|
||||
sCost = eval(sCost);
|
||||
} else {
|
||||
sCost = product.sCost;
|
||||
@ -1350,15 +1233,12 @@ export class Industry implements IIndustry {
|
||||
if (sellAmt < 0) {
|
||||
sellAmt = 0;
|
||||
}
|
||||
sellAmt =
|
||||
sellAmt * CorporationConstants.SecsPerMarketCycle * marketCycles;
|
||||
sellAmt = sellAmt * CorporationConstants.SecsPerMarketCycle * marketCycles;
|
||||
sellAmt = Math.min(product.data[city][0], sellAmt); //data[0] is qty
|
||||
if (sellAmt && sCost) {
|
||||
product.data[city][0] -= sellAmt; //data[0] is qty
|
||||
totalProfit += sellAmt * sCost;
|
||||
product.data[city][2] =
|
||||
sellAmt /
|
||||
(CorporationConstants.SecsPerMarketCycle * marketCycles); //data[2] is sell property
|
||||
product.data[city][2] = sellAmt / (CorporationConstants.SecsPerMarketCycle * marketCycles); //data[2] is sell property
|
||||
} else {
|
||||
product.data[city][2] = 0; //data[2] is sell property
|
||||
}
|
||||
@ -1387,10 +1267,7 @@ export class Industry implements IIndustry {
|
||||
}
|
||||
}
|
||||
|
||||
upgrade(
|
||||
upgrade: IndustryUpgrade,
|
||||
refs: { corporation: ICorporation; office: OfficeSpace },
|
||||
): void {
|
||||
upgrade(upgrade: IndustryUpgrade, refs: { corporation: ICorporation; office: OfficeSpace }): void {
|
||||
const corporation = refs.corporation;
|
||||
const office = refs.office;
|
||||
const upgN = upgrade[0];
|
||||
@ -1403,18 +1280,13 @@ export class Industry implements IIndustry {
|
||||
case 0: {
|
||||
//Coffee, 5% energy per employee
|
||||
for (let i = 0; i < office.employees.length; ++i) {
|
||||
office.employees[i].ene = Math.min(
|
||||
office.employees[i].ene * 1.05,
|
||||
office.maxEne,
|
||||
);
|
||||
office.employees[i].ene = Math.min(office.employees[i].ene * 1.05, office.maxEne);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
//AdVert.Inc,
|
||||
const advMult =
|
||||
corporation.getAdvertisingMultiplier() *
|
||||
this.getAdvertisingMultiplier();
|
||||
const advMult = corporation.getAdvertisingMultiplier() * this.getAdvertisingMultiplier();
|
||||
this.awareness += 3 * advMult;
|
||||
this.popularity += 1 * advMult;
|
||||
this.awareness *= 1.01 * advMult;
|
||||
@ -1429,10 +1301,7 @@ export class Industry implements IIndustry {
|
||||
}
|
||||
|
||||
// Returns how much of a material can be produced based of office productivity (employee stats)
|
||||
getOfficeProductivity(
|
||||
office: OfficeSpace,
|
||||
params: { forProduct?: boolean } = {},
|
||||
): number {
|
||||
getOfficeProductivity(office: OfficeSpace, params: { forProduct?: boolean } = {}): number {
|
||||
const opProd = office.employeeProd[EmployeePositions.Operations];
|
||||
const engrProd = office.employeeProd[EmployeePositions.Engineer];
|
||||
const mgmtProd = office.employeeProd[EmployeePositions.Management];
|
||||
@ -1471,10 +1340,7 @@ export class Industry implements IIndustry {
|
||||
getAdvertisingFactors(): [number, number, number, number] {
|
||||
const awarenessFac = Math.pow(this.awareness + 1, this.advFac);
|
||||
const popularityFac = Math.pow(this.popularity + 1, this.advFac);
|
||||
const ratioFac =
|
||||
this.awareness === 0
|
||||
? 0.01
|
||||
: Math.max((this.popularity + 0.001) / this.awareness, 0.01);
|
||||
const ratioFac = this.awareness === 0 ? 0.01 : Math.max((this.popularity + 0.001) / this.awareness, 0.01);
|
||||
const totalFac = Math.pow(awarenessFac * popularityFac * ratioFac, 0.85);
|
||||
return [totalFac, awarenessFac, popularityFac, ratioFac];
|
||||
}
|
||||
@ -1491,15 +1357,11 @@ export class Industry implements IIndustry {
|
||||
|
||||
updateResearchTree(): void {
|
||||
const researchTree = IndustryResearchTrees[this.type];
|
||||
if (researchTree === undefined)
|
||||
throw new Error(`Invalid industry "${this.type}"`);
|
||||
if (researchTree === undefined) throw new Error(`Invalid industry "${this.type}"`);
|
||||
|
||||
// Since ResearchTree data isnt saved, we'll update the Research Tree data
|
||||
// based on the stored 'researched' property in the Industry object
|
||||
if (
|
||||
Object.keys(researchTree.researched).length !==
|
||||
Object.keys(this.researched).length
|
||||
) {
|
||||
if (Object.keys(researchTree.researched).length !== Object.keys(this.researched).length) {
|
||||
for (const research in this.researched) {
|
||||
researchTree.research(research);
|
||||
}
|
||||
@ -1509,80 +1371,70 @@ export class Industry implements IIndustry {
|
||||
// Get multipliers from Research
|
||||
getAdvertisingMultiplier(): number {
|
||||
const researchTree = IndustryResearchTrees[this.type];
|
||||
if (researchTree === undefined)
|
||||
throw new Error(`Invalid industry: "${this.type}"`);
|
||||
if (researchTree === undefined) throw new Error(`Invalid industry: "${this.type}"`);
|
||||
this.updateResearchTree();
|
||||
return researchTree.getAdvertisingMultiplier();
|
||||
}
|
||||
|
||||
getEmployeeChaMultiplier(): number {
|
||||
const researchTree = IndustryResearchTrees[this.type];
|
||||
if (researchTree === undefined)
|
||||
throw new Error(`Invalid industry: "${this.type}"`);
|
||||
if (researchTree === undefined) throw new Error(`Invalid industry: "${this.type}"`);
|
||||
this.updateResearchTree();
|
||||
return researchTree.getEmployeeChaMultiplier();
|
||||
}
|
||||
|
||||
getEmployeeCreMultiplier(): number {
|
||||
const researchTree = IndustryResearchTrees[this.type];
|
||||
if (researchTree === undefined)
|
||||
throw new Error(`Invalid industry: "${this.type}"`);
|
||||
if (researchTree === undefined) throw new Error(`Invalid industry: "${this.type}"`);
|
||||
this.updateResearchTree();
|
||||
return researchTree.getEmployeeCreMultiplier();
|
||||
}
|
||||
|
||||
getEmployeeEffMultiplier(): number {
|
||||
const researchTree = IndustryResearchTrees[this.type];
|
||||
if (researchTree === undefined)
|
||||
throw new Error(`Invalid industry: "${this.type}"`);
|
||||
if (researchTree === undefined) throw new Error(`Invalid industry: "${this.type}"`);
|
||||
this.updateResearchTree();
|
||||
return researchTree.getEmployeeEffMultiplier();
|
||||
}
|
||||
|
||||
getEmployeeIntMultiplier(): number {
|
||||
const researchTree = IndustryResearchTrees[this.type];
|
||||
if (researchTree === undefined)
|
||||
throw new Error(`Invalid industry: "${this.type}"`);
|
||||
if (researchTree === undefined) throw new Error(`Invalid industry: "${this.type}"`);
|
||||
this.updateResearchTree();
|
||||
return researchTree.getEmployeeIntMultiplier();
|
||||
}
|
||||
|
||||
getProductionMultiplier(): number {
|
||||
const researchTree = IndustryResearchTrees[this.type];
|
||||
if (researchTree === undefined)
|
||||
throw new Error(`Invalid industry: "${this.type}"`);
|
||||
if (researchTree === undefined) throw new Error(`Invalid industry: "${this.type}"`);
|
||||
this.updateResearchTree();
|
||||
return researchTree.getProductionMultiplier();
|
||||
}
|
||||
|
||||
getProductProductionMultiplier(): number {
|
||||
const researchTree = IndustryResearchTrees[this.type];
|
||||
if (researchTree === undefined)
|
||||
throw new Error(`Invalid industry: "${this.type}"`);
|
||||
if (researchTree === undefined) throw new Error(`Invalid industry: "${this.type}"`);
|
||||
this.updateResearchTree();
|
||||
return researchTree.getProductProductionMultiplier();
|
||||
}
|
||||
|
||||
getSalesMultiplier(): number {
|
||||
const researchTree = IndustryResearchTrees[this.type];
|
||||
if (researchTree === undefined)
|
||||
throw new Error(`Invalid industry: "${this.type}"`);
|
||||
if (researchTree === undefined) throw new Error(`Invalid industry: "${this.type}"`);
|
||||
this.updateResearchTree();
|
||||
return researchTree.getSalesMultiplier();
|
||||
}
|
||||
|
||||
getScientificResearchMultiplier(): number {
|
||||
const researchTree = IndustryResearchTrees[this.type];
|
||||
if (researchTree === undefined)
|
||||
throw new Error(`Invalid industry: "${this.type}"`);
|
||||
if (researchTree === undefined) throw new Error(`Invalid industry: "${this.type}"`);
|
||||
this.updateResearchTree();
|
||||
return researchTree.getScientificResearchMultiplier();
|
||||
}
|
||||
|
||||
getStorageMultiplier(): number {
|
||||
const researchTree = IndustryResearchTrees[this.type];
|
||||
if (researchTree === undefined)
|
||||
throw new Error(`Invalid industry: "${this.type}"`);
|
||||
if (researchTree === undefined) throw new Error(`Invalid industry: "${this.type}"`);
|
||||
this.updateResearchTree();
|
||||
return researchTree.getStorageMultiplier();
|
||||
}
|
||||
|
@ -1,10 +1,7 @@
|
||||
import React from "react";
|
||||
import { ResearchTree } from "./ResearchTree";
|
||||
import { ICorporation } from "./ICorporation";
|
||||
import {
|
||||
getBaseResearchTreeCopy,
|
||||
getProductIndustryResearchTreeCopy,
|
||||
} from "./data/BaseResearchTree";
|
||||
import { getBaseResearchTreeCopy, getProductIndustryResearchTreeCopy } from "./data/BaseResearchTree";
|
||||
import { MoneyCost } from "./ui/MoneyCost";
|
||||
|
||||
interface IIndustryMap<T> {
|
||||
@ -62,16 +59,13 @@ export const IndustryStartingCosts: IIndustryMap<number> = {
|
||||
};
|
||||
|
||||
// Map of description for each industry
|
||||
export const IndustryDescriptions: IIndustryMap<
|
||||
(corp: ICorporation) => React.ReactElement
|
||||
> = {
|
||||
export const IndustryDescriptions: IIndustryMap<(corp: ICorporation) => React.ReactElement> = {
|
||||
Energy: (corp: ICorporation) => (
|
||||
<>
|
||||
Engage in the production and distribution of energy.
|
||||
<br />
|
||||
<br />
|
||||
Starting cost:{" "}
|
||||
<MoneyCost money={IndustryStartingCosts.Energy} corp={corp} />
|
||||
Starting cost: <MoneyCost money={IndustryStartingCosts.Energy} corp={corp} />
|
||||
<br />
|
||||
Recommended starting Industry: NO
|
||||
</>
|
||||
@ -81,8 +75,7 @@ export const IndustryDescriptions: IIndustryMap<
|
||||
Distribute water and provide wastewater services.
|
||||
<br />
|
||||
<br />
|
||||
Starting cost:{" "}
|
||||
<MoneyCost money={IndustryStartingCosts.Utilities} corp={corp} />
|
||||
Starting cost: <MoneyCost money={IndustryStartingCosts.Utilities} corp={corp} />
|
||||
<br />
|
||||
Recommended starting Industry: NO
|
||||
</>
|
||||
@ -92,20 +85,17 @@ export const IndustryDescriptions: IIndustryMap<
|
||||
Cultivate crops and breed livestock to produce food.
|
||||
<br />
|
||||
<br />
|
||||
Starting cost:{" "}
|
||||
<MoneyCost money={IndustryStartingCosts.Agriculture} corp={corp} />
|
||||
Starting cost: <MoneyCost money={IndustryStartingCosts.Agriculture} corp={corp} />
|
||||
<br />
|
||||
Recommended starting Industry: YES
|
||||
</>
|
||||
),
|
||||
Fishing: (corp: ICorporation) => (
|
||||
<>
|
||||
Produce food through the breeding and processing of fish and fish
|
||||
products.
|
||||
Produce food through the breeding and processing of fish and fish products.
|
||||
<br />
|
||||
<br />
|
||||
Starting cost:{" "}
|
||||
<MoneyCost money={IndustryStartingCosts.Fishing} corp={corp} />
|
||||
Starting cost: <MoneyCost money={IndustryStartingCosts.Fishing} corp={corp} />
|
||||
<br />
|
||||
Recommended starting Industry: NO
|
||||
</>
|
||||
@ -115,8 +105,7 @@ export const IndustryDescriptions: IIndustryMap<
|
||||
Extract and process metals from the earth.
|
||||
<br />
|
||||
<br />
|
||||
Starting cost:{" "}
|
||||
<MoneyCost money={IndustryStartingCosts.Mining} corp={corp} />
|
||||
Starting cost: <MoneyCost money={IndustryStartingCosts.Mining} corp={corp} />
|
||||
<br />
|
||||
Recommended starting Industry: NO
|
||||
</>
|
||||
@ -126,8 +115,7 @@ export const IndustryDescriptions: IIndustryMap<
|
||||
Create your own restaurants all around the world.
|
||||
<br />
|
||||
<br />
|
||||
Starting cost:{" "}
|
||||
<MoneyCost money={IndustryStartingCosts.Food} corp={corp} />
|
||||
Starting cost: <MoneyCost money={IndustryStartingCosts.Food} corp={corp} />
|
||||
<br />
|
||||
Recommended starting Industry: YES
|
||||
</>
|
||||
@ -137,8 +125,7 @@ export const IndustryDescriptions: IIndustryMap<
|
||||
Create and distribute tobacco and tobacco-related products.
|
||||
<br />
|
||||
<br />
|
||||
Starting cost:{" "}
|
||||
<MoneyCost money={IndustryStartingCosts.Tobacco} corp={corp} />
|
||||
Starting cost: <MoneyCost money={IndustryStartingCosts.Tobacco} corp={corp} />
|
||||
<br />
|
||||
Recommended starting Industry: YES
|
||||
</>
|
||||
@ -148,8 +135,7 @@ export const IndustryDescriptions: IIndustryMap<
|
||||
Produce industrial chemicals.
|
||||
<br />
|
||||
<br />
|
||||
Starting cost:{" "}
|
||||
<MoneyCost money={IndustryStartingCosts.Chemical} corp={corp} />
|
||||
Starting cost: <MoneyCost money={IndustryStartingCosts.Chemical} corp={corp} />
|
||||
<br />
|
||||
Recommended starting Industry: NO
|
||||
</>
|
||||
@ -159,20 +145,17 @@ export const IndustryDescriptions: IIndustryMap<
|
||||
Discover, develop, and create new pharmaceutical drugs.
|
||||
<br />
|
||||
<br />
|
||||
Starting cost:{" "}
|
||||
<MoneyCost money={IndustryStartingCosts.Pharmaceutical} corp={corp} />
|
||||
Starting cost: <MoneyCost money={IndustryStartingCosts.Pharmaceutical} corp={corp} />
|
||||
<br />
|
||||
Recommended starting Industry: NO
|
||||
</>
|
||||
),
|
||||
Computer: (corp: ICorporation) => (
|
||||
<>
|
||||
Develop and manufacture new computer hardware and networking
|
||||
infrastructures.
|
||||
Develop and manufacture new computer hardware and networking infrastructures.
|
||||
<br />
|
||||
<br />
|
||||
Starting cost:{" "}
|
||||
<MoneyCost money={IndustryStartingCosts.Computer} corp={corp} />
|
||||
Starting cost: <MoneyCost money={IndustryStartingCosts.Computer} corp={corp} />
|
||||
<br />
|
||||
Recommended starting Industry: NO
|
||||
</>
|
||||
@ -182,8 +165,7 @@ export const IndustryDescriptions: IIndustryMap<
|
||||
Develop and create robots.
|
||||
<br />
|
||||
<br />
|
||||
Starting cost:{" "}
|
||||
<MoneyCost money={IndustryStartingCosts.Robotics} corp={corp} />
|
||||
Starting cost: <MoneyCost money={IndustryStartingCosts.Robotics} corp={corp} />
|
||||
<br />
|
||||
Recommended starting Industry: NO
|
||||
</>
|
||||
@ -193,8 +175,7 @@ export const IndustryDescriptions: IIndustryMap<
|
||||
Develop computer software and create AI Cores.
|
||||
<br />
|
||||
<br />
|
||||
Starting cost:{" "}
|
||||
<MoneyCost money={IndustryStartingCosts.Software} corp={corp} />
|
||||
Starting cost: <MoneyCost money={IndustryStartingCosts.Software} corp={corp} />
|
||||
<br />
|
||||
Recommended starting Industry: YES
|
||||
</>
|
||||
@ -204,8 +185,7 @@ export const IndustryDescriptions: IIndustryMap<
|
||||
Create and manage hospitals.
|
||||
<br />
|
||||
<br />
|
||||
Starting cost:{" "}
|
||||
<MoneyCost money={IndustryStartingCosts.Healthcare} corp={corp} />
|
||||
Starting cost: <MoneyCost money={IndustryStartingCosts.Healthcare} corp={corp} />
|
||||
<br />
|
||||
Recommended starting Industry: NO
|
||||
</>
|
||||
@ -215,8 +195,7 @@ export const IndustryDescriptions: IIndustryMap<
|
||||
Develop and manage real estate properties.
|
||||
<br />
|
||||
<br />
|
||||
Starting cost:{" "}
|
||||
<MoneyCost money={IndustryStartingCosts.RealEstate} corp={corp} />
|
||||
Starting cost: <MoneyCost money={IndustryStartingCosts.RealEstate} corp={corp} />
|
||||
<br />
|
||||
Recommended starting Industry: NO
|
||||
</>
|
||||
|
@ -6,14 +6,7 @@ export type IndustryUpgrade = [number, number, number, number, string, string];
|
||||
// The data structure is an array with the following format:
|
||||
// [index in array, base price, price mult, benefit mult (if applicable), name, desc]
|
||||
export const IndustryUpgrades: IMap<IndustryUpgrade> = {
|
||||
"0": [
|
||||
0,
|
||||
500e3,
|
||||
1,
|
||||
1.05,
|
||||
"Coffee",
|
||||
"Provide your employees with coffee, increasing their energy by 5%.",
|
||||
],
|
||||
"0": [0, 500e3, 1, 1.05, "Coffee", "Provide your employees with coffee, increasing their energy by 5%."],
|
||||
"1": [
|
||||
1,
|
||||
1e9,
|
||||
|
@ -1,8 +1,4 @@
|
||||
import {
|
||||
Generic_fromJSON,
|
||||
Generic_toJSON,
|
||||
Reviver,
|
||||
} from "../../utils/JSONReviver";
|
||||
import { Generic_fromJSON, Generic_toJSON, Reviver } from "../../utils/JSONReviver";
|
||||
import { Export } from "./Export";
|
||||
|
||||
interface IConstructorParams {
|
||||
|
@ -2,11 +2,7 @@ import { EmployeePositions } from "./EmployeePositions";
|
||||
import { CorporationConstants } from "./data/Constants";
|
||||
import { getRandomInt } from "../../utils/helpers/getRandomInt";
|
||||
import { generateRandomString } from "../../utils/StringHelperFunctions";
|
||||
import {
|
||||
Generic_fromJSON,
|
||||
Generic_toJSON,
|
||||
Reviver,
|
||||
} from "../../utils/JSONReviver";
|
||||
import { Generic_fromJSON, Generic_toJSON, Reviver } from "../../utils/JSONReviver";
|
||||
import { Employee } from "./Employee";
|
||||
import { IIndustry } from "./IIndustry";
|
||||
import { ICorporation } from "./ICorporation";
|
||||
@ -53,11 +49,7 @@ export class OfficeSpace {
|
||||
return this.employees.length >= this.size;
|
||||
}
|
||||
|
||||
process(
|
||||
marketCycles = 1,
|
||||
corporation: ICorporation,
|
||||
industry: IIndustry,
|
||||
): number {
|
||||
process(marketCycles = 1, corporation: ICorporation, industry: IIndustry): number {
|
||||
// HRBuddy AutoRecruitment and training
|
||||
if (industry.hasResearch("HRBuddy-Recruitment") && !this.atCapacity()) {
|
||||
const emp = this.hireRandomEmployee();
|
||||
@ -119,10 +111,7 @@ export class OfficeSpace {
|
||||
return salaryPaid;
|
||||
}
|
||||
|
||||
calculateEmployeeProductivity(
|
||||
corporation: ICorporation,
|
||||
industry: IIndustry,
|
||||
): void {
|
||||
calculateEmployeeProductivity(corporation: ICorporation, industry: IIndustry): void {
|
||||
//Reset
|
||||
for (const name in this.employeeProd) {
|
||||
this.employeeProd[name] = 0;
|
||||
@ -140,8 +129,7 @@ export class OfficeSpace {
|
||||
|
||||
hireRandomEmployee(): Employee | undefined {
|
||||
if (this.atCapacity()) return;
|
||||
if (document.getElementById("cmpy-mgmt-hire-employee-popup") != null)
|
||||
return;
|
||||
if (document.getElementById("cmpy-mgmt-hire-employee-popup") != null) return;
|
||||
|
||||
//Generate three random employees (meh, decent, amazing)
|
||||
const mult = getRandomInt(76, 100) / 100;
|
||||
@ -150,9 +138,7 @@ export class OfficeSpace {
|
||||
exp = getRandomInt(50, 100),
|
||||
cre = getRandomInt(50, 100),
|
||||
eff = getRandomInt(50, 100),
|
||||
sal =
|
||||
CorporationConstants.EmployeeSalaryMultiplier *
|
||||
(int + cha + exp + cre + eff);
|
||||
sal = CorporationConstants.EmployeeSalaryMultiplier * (int + cha + exp + cre + eff);
|
||||
|
||||
const emp = new Employee({
|
||||
intelligence: int * mult,
|
||||
|
@ -1,19 +1,12 @@
|
||||
import { EmployeePositions } from "./EmployeePositions";
|
||||
import { MaterialSizes } from "./MaterialSizes";
|
||||
import { IIndustry } from "./IIndustry";
|
||||
import {
|
||||
ProductRatingWeights,
|
||||
IProductRatingWeight,
|
||||
} from "./ProductRatingWeights";
|
||||
import { ProductRatingWeights, IProductRatingWeight } from "./ProductRatingWeights";
|
||||
|
||||
import { createCityMap } from "../Locations/createCityMap";
|
||||
import { IMap } from "../types";
|
||||
|
||||
import {
|
||||
Generic_fromJSON,
|
||||
Generic_toJSON,
|
||||
Reviver,
|
||||
} from "../../utils/JSONReviver";
|
||||
import { Generic_fromJSON, Generic_toJSON, Reviver } from "../../utils/JSONReviver";
|
||||
import { getRandomInt } from "../../utils/helpers/getRandomInt";
|
||||
|
||||
interface IConstructorParams {
|
||||
@ -132,34 +125,20 @@ export class Product {
|
||||
}
|
||||
|
||||
// @param industry - Industry object. Reference to industry that makes this Product
|
||||
finishProduct(
|
||||
employeeProd: { [key: string]: number },
|
||||
industry: IIndustry,
|
||||
): void {
|
||||
finishProduct(employeeProd: { [key: string]: number }, industry: IIndustry): void {
|
||||
this.fin = true;
|
||||
|
||||
//Calculate properties
|
||||
const progrMult = this.prog / 100;
|
||||
|
||||
const engrRatio =
|
||||
employeeProd[EmployeePositions.Engineer] / employeeProd["total"];
|
||||
const mgmtRatio =
|
||||
employeeProd[EmployeePositions.Management] / employeeProd["total"];
|
||||
const rndRatio =
|
||||
employeeProd[EmployeePositions.RandD] / employeeProd["total"];
|
||||
const opsRatio =
|
||||
employeeProd[EmployeePositions.Operations] / employeeProd["total"];
|
||||
const busRatio =
|
||||
employeeProd[EmployeePositions.Business] / employeeProd["total"];
|
||||
const engrRatio = employeeProd[EmployeePositions.Engineer] / employeeProd["total"];
|
||||
const mgmtRatio = employeeProd[EmployeePositions.Management] / employeeProd["total"];
|
||||
const rndRatio = employeeProd[EmployeePositions.RandD] / employeeProd["total"];
|
||||
const opsRatio = employeeProd[EmployeePositions.Operations] / employeeProd["total"];
|
||||
const busRatio = employeeProd[EmployeePositions.Business] / employeeProd["total"];
|
||||
const designMult = 1 + Math.pow(this.designCost, 0.1) / 100;
|
||||
const balanceMult =
|
||||
1.2 * engrRatio +
|
||||
0.9 * mgmtRatio +
|
||||
1.3 * rndRatio +
|
||||
1.5 * opsRatio +
|
||||
busRatio;
|
||||
const sciMult =
|
||||
1 + Math.pow(industry.sciResearch.qty, industry.sciFac) / 800;
|
||||
const balanceMult = 1.2 * engrRatio + 0.9 * mgmtRatio + 1.3 * rndRatio + 1.5 * opsRatio + busRatio;
|
||||
const sciMult = 1 + Math.pow(industry.sciResearch.qty, industry.sciFac) / 800;
|
||||
const totalMult = progrMult * balanceMult * designMult * sciMult;
|
||||
|
||||
this.qlt =
|
||||
@ -206,21 +185,14 @@ export class Product {
|
||||
0.05 * employeeProd[EmployeePositions.Business]);
|
||||
this.calculateRating(industry);
|
||||
const advMult = 1 + Math.pow(this.advCost, 0.1) / 100;
|
||||
this.mku =
|
||||
100 /
|
||||
(advMult * Math.pow(this.qlt + 0.001, 0.65) * (busRatio + mgmtRatio));
|
||||
this.mku = 100 / (advMult * Math.pow(this.qlt + 0.001, 0.65) * (busRatio + mgmtRatio));
|
||||
|
||||
// I actually don't understand well enough to know if this is right.
|
||||
// I'm adding this to prevent a crash.
|
||||
if (this.mku === 0) this.mku = 1;
|
||||
|
||||
this.dmd =
|
||||
industry.awareness === 0
|
||||
? 20
|
||||
: Math.min(
|
||||
100,
|
||||
advMult * (100 * (industry.popularity / industry.awareness)),
|
||||
);
|
||||
industry.awareness === 0 ? 20 : Math.min(100, advMult * (100 * (industry.popularity / industry.awareness)));
|
||||
this.cmp = getRandomInt(0, 70);
|
||||
|
||||
//Calculate the product's required materials
|
||||
|
@ -40,9 +40,7 @@ export class Node {
|
||||
|
||||
constructor(p: IConstructorParams = { cost: 0, text: "" }) {
|
||||
if (ResearchMap[p.text] == null) {
|
||||
throw new Error(
|
||||
`Invalid Research name used when constructing ResearchTree Node: ${p.text}`,
|
||||
);
|
||||
throw new Error(`Invalid Research name used when constructing ResearchTree Node: ${p.text}`);
|
||||
}
|
||||
|
||||
this.text = p.text;
|
||||
@ -87,10 +85,7 @@ export class Node {
|
||||
HTMLclass: htmlClass,
|
||||
innerHTML:
|
||||
`<div id="${sanitizedName}-corp-research-click-listener" class="tooltip">` +
|
||||
`${this.text}<br>${numeralWrapper.format(
|
||||
this.cost,
|
||||
"0,0",
|
||||
)} Scientific Research` +
|
||||
`${this.text}<br>${numeralWrapper.format(this.cost, "0,0")} Scientific Research` +
|
||||
`<span class="tooltiptext">` +
|
||||
`${research.desc}` +
|
||||
`</span>` +
|
||||
@ -243,9 +238,7 @@ export class ResearchTree {
|
||||
|
||||
const mult: any = (research as any)[propName];
|
||||
if (mult == null) {
|
||||
console.warn(
|
||||
`Invalid propName specified in ResearchTree.getMultiplierHelper: ${propName}`,
|
||||
);
|
||||
console.warn(`Invalid propName specified in ResearchTree.getMultiplierHelper: ${propName}`);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -292,9 +285,7 @@ export class ResearchTree {
|
||||
}
|
||||
}
|
||||
|
||||
console.warn(
|
||||
`ResearchTree.research() did not find the specified Research node for: ${name}`,
|
||||
);
|
||||
console.warn(`ResearchTree.research() did not find the specified Research node for: ${name}`);
|
||||
}
|
||||
|
||||
// Set the tree's Root Node
|
||||
|
@ -4,11 +4,7 @@ import { IIndustry } from "./IIndustry";
|
||||
import { MaterialSizes } from "./MaterialSizes";
|
||||
import { IMap } from "../types";
|
||||
import { numeralWrapper } from "../ui/numeralFormat";
|
||||
import {
|
||||
Generic_fromJSON,
|
||||
Generic_toJSON,
|
||||
Reviver,
|
||||
} from "../../utils/JSONReviver";
|
||||
import { Generic_fromJSON, Generic_toJSON, Reviver } from "../../utils/JSONReviver";
|
||||
import { exceptionAlert } from "../../utils/helpers/exceptionAlert";
|
||||
|
||||
interface IConstructorParams {
|
||||
@ -95,28 +91,18 @@ export class Warehouse {
|
||||
if (MaterialSizes.hasOwnProperty(matName)) {
|
||||
this.sizeUsed += mat.qty * MaterialSizes[matName];
|
||||
if (mat.qty > 0) {
|
||||
this.breakdown +=
|
||||
matName +
|
||||
": " +
|
||||
numeralWrapper.format(mat.qty * MaterialSizes[matName], "0,0.0") +
|
||||
"<br>";
|
||||
this.breakdown += matName + ": " + numeralWrapper.format(mat.qty * MaterialSizes[matName], "0,0.0") + "<br>";
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this.sizeUsed > this.size) {
|
||||
console.warn(
|
||||
"Warehouse size used greater than capacity, something went wrong",
|
||||
);
|
||||
console.warn("Warehouse size used greater than capacity, something went wrong");
|
||||
}
|
||||
}
|
||||
|
||||
updateSize(corporation: ICorporation, industry: IIndustry): void {
|
||||
try {
|
||||
this.size =
|
||||
this.level *
|
||||
100 *
|
||||
corporation.getStorageMultiplier() *
|
||||
industry.getStorageMultiplier();
|
||||
this.size = this.level * 100 * corporation.getStorageMultiplier() * industry.getStorageMultiplier();
|
||||
} catch (e) {
|
||||
exceptionAlert(e);
|
||||
}
|
||||
|
@ -1,11 +1,5 @@
|
||||
const CyclesPerMarketCycle = 50;
|
||||
const AllCorporationStates = [
|
||||
"START",
|
||||
"PURCHASE",
|
||||
"PRODUCTION",
|
||||
"SALE",
|
||||
"EXPORT",
|
||||
];
|
||||
const AllCorporationStates = ["START", "PURCHASE", "PRODUCTION", "SALE", "EXPORT"];
|
||||
export const CorporationConstants: {
|
||||
INITIALSHARES: number;
|
||||
SHARESPERPRICEUPDATE: number;
|
||||
@ -38,18 +32,10 @@ export const CorporationConstants: {
|
||||
SellSharesCooldown: 18e3, // 1 Hour in terms of game cycles
|
||||
|
||||
CyclesPerMarketCycle: CyclesPerMarketCycle,
|
||||
CyclesPerIndustryStateCycle:
|
||||
CyclesPerMarketCycle / AllCorporationStates.length,
|
||||
CyclesPerIndustryStateCycle: CyclesPerMarketCycle / AllCorporationStates.length,
|
||||
SecsPerMarketCycle: CyclesPerMarketCycle / 5,
|
||||
|
||||
Cities: [
|
||||
"Aevum",
|
||||
"Chongqing",
|
||||
"Sector-12",
|
||||
"New Tokyo",
|
||||
"Ishima",
|
||||
"Volhaven",
|
||||
],
|
||||
Cities: ["Aevum", "Chongqing", "Sector-12", "New Tokyo", "Ishima", "Volhaven"],
|
||||
|
||||
WarehouseInitialCost: 5e9, //Initial purchase cost of warehouse
|
||||
WarehouseInitialSize: 100,
|
||||
|
@ -1,13 +1,6 @@
|
||||
import { IMap } from "../../types";
|
||||
|
||||
export type CorporationUpgrade = [
|
||||
number,
|
||||
number,
|
||||
number,
|
||||
number,
|
||||
string,
|
||||
string,
|
||||
];
|
||||
export type CorporationUpgrade = [number, number, number, number, string, string];
|
||||
|
||||
// Corporation Upgrades
|
||||
// Upgrades for entire corporation, levelable upgrades
|
||||
|
@ -106,9 +106,7 @@ export const researchMetadata: IConstructorParams[] = [
|
||||
{
|
||||
name: "JoyWire",
|
||||
cost: 20e3,
|
||||
desc:
|
||||
"A brain implant which is installed in employees, increasing their " +
|
||||
"maximum happiness by 10.",
|
||||
desc: "A brain implant which is installed in employees, increasing their " + "maximum happiness by 10.",
|
||||
},
|
||||
{
|
||||
name: "Market-TA.I",
|
||||
@ -162,9 +160,7 @@ export const researchMetadata: IConstructorParams[] = [
|
||||
{
|
||||
name: "sudo.Assist",
|
||||
cost: 15e3,
|
||||
desc:
|
||||
"Develop a virtual assistant AI to handle and manage administrative " +
|
||||
"issues for your corporation.",
|
||||
desc: "Develop a virtual assistant AI to handle and manage administrative " + "issues for your corporation.",
|
||||
},
|
||||
{
|
||||
name: "uPgrade: Capacity.I",
|
||||
|
@ -33,10 +33,7 @@ export function BribeFactionPopup(props: IProps): React.ReactElement {
|
||||
}
|
||||
|
||||
function repGain(money: number, stock: number): number {
|
||||
return (
|
||||
(money + stock * props.corp.sharePrice) /
|
||||
CorporationConstants.BribeToRepRatio
|
||||
);
|
||||
return (money + stock * props.corp.sharePrice) / CorporationConstants.BribeToRepRatio;
|
||||
}
|
||||
|
||||
function getRepText(money: number, stock: number): string {
|
||||
@ -69,11 +66,7 @@ export function BribeFactionPopup(props: IProps): React.ReactElement {
|
||||
} else {
|
||||
const rep = repGain(money, stock);
|
||||
dialogBoxCreate(
|
||||
"You gained " +
|
||||
numeralWrapper.formatReputation(rep) +
|
||||
" reputation with " +
|
||||
fac.name +
|
||||
" by bribing them.",
|
||||
"You gained " + numeralWrapper.formatReputation(rep) + " reputation with " + fac.name + " by bribing them.",
|
||||
);
|
||||
fac.playerReputation += rep;
|
||||
props.corp.funds = props.corp.funds.minus(money);
|
||||
@ -84,16 +77,8 @@ export function BribeFactionPopup(props: IProps): React.ReactElement {
|
||||
|
||||
return (
|
||||
<>
|
||||
<p>
|
||||
You can use Corporation funds or stock shares to bribe Faction Leaders
|
||||
in exchange for faction reputation.
|
||||
</p>
|
||||
<select
|
||||
className="dropdown"
|
||||
style={{ margin: "3px" }}
|
||||
defaultValue={selectedFaction}
|
||||
onChange={changeFaction}
|
||||
>
|
||||
<p>You can use Corporation funds or stock shares to bribe Faction Leaders in exchange for faction reputation.</p>
|
||||
<select className="dropdown" style={{ margin: "3px" }} defaultValue={selectedFaction} onChange={changeFaction}>
|
||||
{props.player.factions.map((name: string) => {
|
||||
const info = Factions[name].getInfo();
|
||||
if (!info.offersWork()) return;
|
||||
@ -111,12 +96,7 @@ export function BribeFactionPopup(props: IProps): React.ReactElement {
|
||||
placeholder="Corporation funds"
|
||||
style={{ margin: "5px" }}
|
||||
/>
|
||||
<input
|
||||
className="text-input"
|
||||
onChange={onStockChange}
|
||||
placeholder="Stock Shares"
|
||||
style={{ margin: "5px" }}
|
||||
/>
|
||||
<input className="text-input" onChange={onStockChange} placeholder="Stock Shares" style={{ margin: "5px" }} />
|
||||
<button
|
||||
className="a-link-button"
|
||||
onClick={() => bribe(money ? money : 0, stock ? stock : 0)}
|
||||
|
@ -31,9 +31,7 @@ export function BuybackSharesPopup(props: IProps): React.ReactElement {
|
||||
if (isNaN(shares) || shares <= 0) {
|
||||
dialogBoxCreate("ERROR: Invalid value for number of shares");
|
||||
} else if (shares > props.corp.issuedShares) {
|
||||
dialogBoxCreate(
|
||||
"ERROR: There are not this many oustanding shares to buy back",
|
||||
);
|
||||
dialogBoxCreate("ERROR: There are not this many oustanding shares to buy back");
|
||||
} else if (shares * buybackPrice > props.player.money) {
|
||||
dialogBoxCreate(
|
||||
"ERROR: You do not have enough money to purchase this many shares (you need " +
|
||||
@ -43,9 +41,7 @@ export function BuybackSharesPopup(props: IProps): React.ReactElement {
|
||||
} else {
|
||||
props.corp.numShares += shares;
|
||||
if (isNaN(props.corp.issuedShares)) {
|
||||
console.warn(
|
||||
"Corporation issuedShares is NaN: " + props.corp.issuedShares,
|
||||
);
|
||||
console.warn("Corporation issuedShares is NaN: " + props.corp.issuedShares);
|
||||
console.warn("Converting to number now");
|
||||
const res = props.corp.issuedShares;
|
||||
if (isNaN(res)) {
|
||||
@ -69,15 +65,13 @@ export function BuybackSharesPopup(props: IProps): React.ReactElement {
|
||||
return (
|
||||
<>
|
||||
There are not this many shares available to buy back. There are only{" "}
|
||||
{numeralWrapper.formatBigNumber(props.corp.issuedShares)} outstanding
|
||||
shares.
|
||||
{numeralWrapper.formatBigNumber(props.corp.issuedShares)} outstanding shares.
|
||||
</>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<>
|
||||
Purchase {shares} shares for a total of{" "}
|
||||
{numeralWrapper.formatMoney(shares * buybackPrice)}
|
||||
Purchase {shares} shares for a total of {numeralWrapper.formatMoney(shares * buybackPrice)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
@ -90,19 +84,15 @@ export function BuybackSharesPopup(props: IProps): React.ReactElement {
|
||||
return (
|
||||
<>
|
||||
<p>
|
||||
Enter the number of outstanding shares you would like to buy back. These
|
||||
shares must be bought at a 10% premium. However, repurchasing shares
|
||||
from the market tends to lead to an increase in stock price.
|
||||
Enter the number of outstanding shares you would like to buy back. These shares must be bought at a 10% premium.
|
||||
However, repurchasing shares from the market tends to lead to an increase in stock price.
|
||||
<br />
|
||||
<br />
|
||||
To purchase these shares, you must use your own money (NOT your
|
||||
Corporation's funds).
|
||||
To purchase these shares, you must use your own money (NOT your Corporation's funds).
|
||||
<br />
|
||||
<br />
|
||||
The current buyback price of your company's stock is{" "}
|
||||
{numeralWrapper.formatMoney(buybackPrice)}. Your company currently has{" "}
|
||||
{numeralWrapper.formatBigNumber(props.corp.issuedShares)} outstanding
|
||||
stock shares.
|
||||
The current buyback price of your company's stock is {numeralWrapper.formatMoney(buybackPrice)}. Your company
|
||||
currently has {numeralWrapper.formatBigNumber(props.corp.issuedShares)} outstanding stock shares.
|
||||
</p>
|
||||
<CostIndicator />
|
||||
<br />
|
||||
@ -115,11 +105,7 @@ export function BuybackSharesPopup(props: IProps): React.ReactElement {
|
||||
onChange={changeShares}
|
||||
onKeyDown={onKeyDown}
|
||||
/>
|
||||
<button
|
||||
onClick={buy}
|
||||
className="a-link-button"
|
||||
style={{ display: "inline-block" }}
|
||||
>
|
||||
<button onClick={buy} className="a-link-button" style={{ display: "inline-block" }}>
|
||||
Buy shares
|
||||
</button>
|
||||
</>
|
||||
|
@ -61,7 +61,8 @@ export function CityTabs(props: IProps): React.ReactElement {
|
||||
return (
|
||||
<>
|
||||
{Object.values(props.division.offices).map(
|
||||
(office: OfficeSpace | 0) => office !== 0 && (
|
||||
(office: OfficeSpace | 0) =>
|
||||
office !== 0 && (
|
||||
<CityTab
|
||||
current={city === office.loc}
|
||||
key={office.loc}
|
||||
@ -70,11 +71,7 @@ export function CityTabs(props: IProps): React.ReactElement {
|
||||
/>
|
||||
),
|
||||
)}
|
||||
<ExpandButton
|
||||
corp={props.corp}
|
||||
division={props.division}
|
||||
setCity={setCity}
|
||||
/>
|
||||
<ExpandButton corp={props.corp} division={props.division} setCity={setCity} />
|
||||
<Industry
|
||||
corp={props.corp}
|
||||
division={props.division}
|
||||
|
@ -24,9 +24,8 @@ export function DiscontinueProductPopup(props: IProps): React.ReactElement {
|
||||
return (
|
||||
<>
|
||||
<p>
|
||||
Are you sure you want to do this? Discontinuing a product removes it
|
||||
completely and permanently. You will no longer produce this product and
|
||||
all of its existing stock will be removed and left unsold
|
||||
Are you sure you want to do this? Discontinuing a product removes it completely and permanently. You will no
|
||||
longer produce this product and all of its existing stock will be removed and left unsold
|
||||
</p>
|
||||
<button className="popup-box-button" onClick={discontinue}>
|
||||
Discontinue
|
||||
|
@ -35,12 +35,8 @@ export function ExpandNewCityPopup(props: IProps): React.ReactElement {
|
||||
return (
|
||||
<>
|
||||
<p>
|
||||
Would you like to expand into a new city by opening an office? This
|
||||
would cost{" "}
|
||||
<MoneyCost
|
||||
money={CorporationConstants.OfficeInitialCost}
|
||||
corp={props.corp}
|
||||
/>
|
||||
Would you like to expand into a new city by opening an office? This would cost{" "}
|
||||
<MoneyCost money={CorporationConstants.OfficeInitialCost} corp={props.corp} />
|
||||
</p>
|
||||
<select ref={dropdown} className="dropdown" style={{ margin: "5px" }}>
|
||||
{Object.keys(props.division.offices)
|
||||
|
@ -14,16 +14,11 @@ interface IProps {
|
||||
|
||||
// Create a popup that lets the player manage exports
|
||||
export function ExportPopup(props: IProps): React.ReactElement {
|
||||
if (props.corp.divisions.length === 0)
|
||||
throw new Error("Export popup created with no divisions.");
|
||||
if (props.corp.divisions.length === 0) throw new Error("Export popup created with no divisions.");
|
||||
if (Object.keys(props.corp.divisions[0].warehouses).length === 0)
|
||||
throw new Error("Export popup created in a division with no warehouses.");
|
||||
const [industry, setIndustry] = useState<string>(
|
||||
props.corp.divisions[0].name,
|
||||
);
|
||||
const [city, setCity] = useState<string>(
|
||||
Object.keys(props.corp.divisions[0].warehouses)[0],
|
||||
);
|
||||
const [industry, setIndustry] = useState<string>(props.corp.divisions[0].name);
|
||||
const [city, setCity] = useState<string>(Object.keys(props.corp.divisions[0].warehouses)[0]);
|
||||
const [amt, setAmt] = useState("");
|
||||
const setRerender = useState(false)[1];
|
||||
|
||||
@ -71,11 +66,7 @@ export function ExportPopup(props: IProps): React.ReactElement {
|
||||
|
||||
function removeExport(exp: Export): void {
|
||||
for (let i = 0; i < props.mat.exp.length; ++i) {
|
||||
if (
|
||||
props.mat.exp[i].ind !== exp.ind ||
|
||||
props.mat.exp[i].city !== exp.city ||
|
||||
props.mat.exp[i].amt !== exp.amt
|
||||
)
|
||||
if (props.mat.exp[i].ind !== exp.ind || props.mat.exp[i].city !== exp.city || props.mat.exp[i].amt !== exp.amt)
|
||||
continue;
|
||||
props.mat.exp.splice(i, 1);
|
||||
break;
|
||||
@ -83,22 +74,15 @@ export function ExportPopup(props: IProps): React.ReactElement {
|
||||
rerender();
|
||||
}
|
||||
|
||||
const currentDivision = props.corp.divisions.find(
|
||||
(division: IIndustry) => division.name === industry,
|
||||
);
|
||||
const currentDivision = props.corp.divisions.find((division: IIndustry) => division.name === industry);
|
||||
|
||||
return (
|
||||
<>
|
||||
<p>
|
||||
Select the industry and city to export this material to, as well as how
|
||||
much of this material to export per second. You can set the export
|
||||
amount to 'MAX' to export all of the materials in this warehouse.
|
||||
Select the industry and city to export this material to, as well as how much of this material to export per
|
||||
second. You can set the export amount to 'MAX' to export all of the materials in this warehouse.
|
||||
</p>
|
||||
<select
|
||||
className="dropdown"
|
||||
onChange={onIndustryChange}
|
||||
defaultValue={industry}
|
||||
>
|
||||
<select className="dropdown" onChange={onIndustryChange} defaultValue={industry}>
|
||||
{props.corp.divisions.map((division: IIndustry) => (
|
||||
<option key={division.name} value={division.name}>
|
||||
{division.name}
|
||||
@ -116,28 +100,16 @@ export function ExportPopup(props: IProps): React.ReactElement {
|
||||
);
|
||||
})}
|
||||
</select>
|
||||
<input
|
||||
className="text-input"
|
||||
placeholder="Export amount / s"
|
||||
onChange={onAmtChange}
|
||||
/>
|
||||
<button
|
||||
className="std-button"
|
||||
style={{ display: "inline-block" }}
|
||||
onClick={exportMaterial}
|
||||
>
|
||||
<input className="text-input" placeholder="Export amount / s" onChange={onAmtChange} />
|
||||
<button className="std-button" style={{ display: "inline-block" }} onClick={exportMaterial}>
|
||||
Export
|
||||
</button>
|
||||
<p>
|
||||
Below is a list of all current exports of this material from this
|
||||
warehouse. Clicking on one of the exports below will REMOVE that export.
|
||||
Below is a list of all current exports of this material from this warehouse. Clicking on one of the exports
|
||||
below will REMOVE that export.
|
||||
</p>
|
||||
{props.mat.exp.map((exp: Export, index: number) => (
|
||||
<div
|
||||
key={index}
|
||||
className="cmpy-mgmt-existing-export"
|
||||
onClick={() => removeExport(exp)}
|
||||
>
|
||||
<div key={index} className="cmpy-mgmt-existing-export" onClick={() => removeExport(exp)}>
|
||||
Industry: {exp.ind}
|
||||
<br />
|
||||
City: {exp.city}
|
||||
|
@ -37,9 +37,7 @@ export function FindInvestorsPopup(props: IProps): React.ReactElement {
|
||||
return <></>;
|
||||
}
|
||||
const funding = val * percShares * roundMultiplier;
|
||||
const investShares = Math.floor(
|
||||
CorporationConstants.INITIALSHARES * percShares,
|
||||
);
|
||||
const investShares = Math.floor(CorporationConstants.INITIALSHARES * percShares);
|
||||
|
||||
function findInvestors(): void {
|
||||
props.corp.fundingRound++;
|
||||
@ -51,17 +49,15 @@ export function FindInvestorsPopup(props: IProps): React.ReactElement {
|
||||
return (
|
||||
<>
|
||||
<p>
|
||||
An investment firm has offered you {numeralWrapper.formatMoney(funding)}{" "}
|
||||
in funding in exchange for a{" "}
|
||||
{numeralWrapper.format(percShares * 100, "0.000a")}% stake in the
|
||||
company ({numeralWrapper.format(investShares, "0.000a")} shares).
|
||||
An investment firm has offered you {numeralWrapper.formatMoney(funding)} in funding in exchange for a{" "}
|
||||
{numeralWrapper.format(percShares * 100, "0.000a")}% stake in the company (
|
||||
{numeralWrapper.format(investShares, "0.000a")} shares).
|
||||
<br />
|
||||
<br />
|
||||
Do you accept or reject this offer?
|
||||
<br />
|
||||
<br />
|
||||
Hint: Investment firms will offer more money if your corporation is
|
||||
turning a profit
|
||||
Hint: Investment firms will offer more money if your corporation is turning a profit
|
||||
</p>
|
||||
<button onClick={findInvestors} className="std-button">
|
||||
Accept
|
||||
|
@ -14,13 +14,11 @@ interface IProps {
|
||||
// Create a popup that lets the player manage exports
|
||||
export function GoPublicPopup(props: IProps): React.ReactElement {
|
||||
const [shares, setShares] = useState("");
|
||||
const initialSharePrice =
|
||||
props.corp.determineValuation() / props.corp.totalShares;
|
||||
const initialSharePrice = props.corp.determineValuation() / props.corp.totalShares;
|
||||
|
||||
function goPublic(): void {
|
||||
const numShares = parseFloat(shares);
|
||||
const initialSharePrice =
|
||||
props.corp.determineValuation() / props.corp.totalShares;
|
||||
const initialSharePrice = props.corp.determineValuation() / props.corp.totalShares;
|
||||
if (isNaN(numShares)) {
|
||||
dialogBoxCreate("Invalid value for number of issued shares");
|
||||
return;
|
||||
@ -37,9 +35,7 @@ export function GoPublicPopup(props: IProps): React.ReactElement {
|
||||
props.corp.rerender(props.player);
|
||||
dialogBoxCreate(
|
||||
`You took your ${props.corp.name} public and earned ` +
|
||||
`${numeralWrapper.formatMoney(
|
||||
numShares * initialSharePrice,
|
||||
)} in your IPO`,
|
||||
`${numeralWrapper.formatMoney(numShares * initialSharePrice)} in your IPO`,
|
||||
);
|
||||
removePopup(props.popupId);
|
||||
}
|
||||
@ -55,16 +51,12 @@ export function GoPublicPopup(props: IProps): React.ReactElement {
|
||||
return (
|
||||
<>
|
||||
<p>
|
||||
Enter the number of shares you would like to issue for your IPO. These
|
||||
shares will be publicly sold and you will no longer own them. Your
|
||||
Corporation will receive {numeralWrapper.formatMoney(initialSharePrice)}{" "}
|
||||
per share (the IPO money will be deposited directly into your
|
||||
Corporation's funds).
|
||||
Enter the number of shares you would like to issue for your IPO. These shares will be publicly sold and you will
|
||||
no longer own them. Your Corporation will receive {numeralWrapper.formatMoney(initialSharePrice)} per share (the
|
||||
IPO money will be deposited directly into your Corporation's funds).
|
||||
<br />
|
||||
<br />
|
||||
You have a total of{" "}
|
||||
{numeralWrapper.format(props.corp.numShares, "0.000a")} of shares that
|
||||
you can issue.
|
||||
You have a total of {numeralWrapper.format(props.corp.numShares, "0.000a")} of shares that you can issue.
|
||||
</p>
|
||||
<input
|
||||
className="text-input"
|
||||
|
@ -20,9 +20,8 @@ function ExpandButton(props: IExpandButtonProps): React.ReactElement {
|
||||
const allIndustries = Object.keys(Industries).sort();
|
||||
const possibleIndustries = allIndustries
|
||||
.filter(
|
||||
(industryType: string) => props.corp.divisions.find(
|
||||
(division: IIndustry) => division.type === industryType,
|
||||
) === undefined,
|
||||
(industryType: string) =>
|
||||
props.corp.divisions.find((division: IIndustry) => division.type === industryType) === undefined,
|
||||
)
|
||||
.sort();
|
||||
if (possibleIndustries.length === 0) return <></>;
|
||||
@ -36,13 +35,7 @@ function ExpandButton(props: IExpandButtonProps): React.ReactElement {
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<HeaderTab
|
||||
current={false}
|
||||
onClick={openNewIndustryPopup}
|
||||
text={"Expand into new Industry"}
|
||||
/>
|
||||
);
|
||||
return <HeaderTab current={false} onClick={openNewIndustryPopup} text={"Expand into new Industry"} />;
|
||||
}
|
||||
|
||||
interface IProps {
|
||||
@ -72,11 +65,7 @@ export function HeaderTabs(props: IProps): React.ReactElement {
|
||||
))}
|
||||
<ExpandButton corp={props.corp} setDivisionName={setDivisionName} />
|
||||
</div>
|
||||
<MainPanel
|
||||
corp={props.corp}
|
||||
divisionName={divisionName}
|
||||
player={props.player}
|
||||
/>
|
||||
<MainPanel corp={props.corp} divisionName={divisionName} player={props.player} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
@ -2,10 +2,7 @@ import { IIndustry } from "../IIndustry";
|
||||
|
||||
// Returns a boolean indicating whether the given material is relevant for the
|
||||
// current industry.
|
||||
export function isRelevantMaterial(
|
||||
matName: string,
|
||||
division: IIndustry,
|
||||
): boolean {
|
||||
export function isRelevantMaterial(matName: string, division: IIndustry): boolean {
|
||||
// Materials that affect Production multiplier
|
||||
const prodMultiplierMats = ["Hardware", "Robots", "AICores", "RealEstate"];
|
||||
|
||||
|
@ -117,9 +117,7 @@ export function HireEmployeePopup(props: IProps): React.ReactElement {
|
||||
const exp = getRandomInt(50, 100);
|
||||
const cre = getRandomInt(50, 100);
|
||||
const eff = getRandomInt(50, 100);
|
||||
const sal =
|
||||
CorporationConstants.EmployeeSalaryMultiplier *
|
||||
(int + cha + exp + cre + eff);
|
||||
const sal = CorporationConstants.EmployeeSalaryMultiplier * (int + cha + exp + cre + eff);
|
||||
|
||||
const emp1 = new Employee({
|
||||
intelligence: int * mult1,
|
||||
|
@ -31,12 +31,7 @@ export function Industry(props: IProps): React.ReactElement {
|
||||
currentCity={props.city}
|
||||
office={props.office}
|
||||
/>
|
||||
<IndustryOffice
|
||||
player={props.player}
|
||||
corp={props.corp}
|
||||
division={props.division}
|
||||
office={props.office}
|
||||
/>
|
||||
<IndustryOffice player={props.player} corp={props.corp} division={props.division} office={props.office} />
|
||||
</div>
|
||||
<div className={"cmpy-mgmt-industry-right-panel"}>
|
||||
<IndustryWarehouse
|
||||
|
@ -41,28 +41,20 @@ interface ISwitchProps {
|
||||
function SwitchButton(props: ISwitchProps): React.ReactElement {
|
||||
if (props.manualMode) {
|
||||
return (
|
||||
<button
|
||||
className={"std-button tooltip"}
|
||||
onClick={() => props.switchMode((old) => !old)}
|
||||
>
|
||||
<button className={"std-button tooltip"} onClick={() => props.switchMode((old) => !old)}>
|
||||
Switch to Auto Mode
|
||||
<span className={"tooltiptext"}>
|
||||
Switch to Automatic Assignment Mode, which will automatically assign
|
||||
employees to your selected jobs. You simply have to select the number
|
||||
of assignments for each job
|
||||
Switch to Automatic Assignment Mode, which will automatically assign employees to your selected jobs. You
|
||||
simply have to select the number of assignments for each job
|
||||
</span>
|
||||
</button>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<button
|
||||
className={"std-button tooltip"}
|
||||
onClick={() => props.switchMode((old) => !old)}
|
||||
>
|
||||
<button className={"std-button tooltip"} onClick={() => props.switchMode((old) => !old)}>
|
||||
Switch to Manual Mode
|
||||
<span className={"tooltiptext"}>
|
||||
Switch to Manual Assignment Mode, which allows you to specify which
|
||||
employees should get which jobs
|
||||
Switch to Manual Assignment Mode, which allows you to specify which employees should get which jobs
|
||||
</span>
|
||||
</button>
|
||||
);
|
||||
@ -83,16 +75,10 @@ function ManualManagement(props: IProps): React.ReactElement {
|
||||
// Employee Selector
|
||||
const employees = [];
|
||||
for (let i = 0; i < props.office.employees.length; ++i) {
|
||||
employees.push(
|
||||
<option key={props.office.employees[i].name}>
|
||||
{props.office.employees[i].name}
|
||||
</option>,
|
||||
);
|
||||
employees.push(<option key={props.office.employees[i].name}>{props.office.employees[i].name}</option>);
|
||||
}
|
||||
|
||||
function employeeSelectorOnChange(
|
||||
e: React.ChangeEvent<HTMLSelectElement>,
|
||||
): void {
|
||||
function employeeSelectorOnChange(e: React.ChangeEvent<HTMLSelectElement>): void {
|
||||
const name = getSelectText(e.target);
|
||||
for (let i = 0; i < props.office.employees.length; ++i) {
|
||||
if (name === props.office.employees[i].name) {
|
||||
@ -120,9 +106,7 @@ function ManualManagement(props: IProps): React.ReactElement {
|
||||
}
|
||||
}
|
||||
|
||||
function employeePositionSelectorOnChange(
|
||||
e: React.ChangeEvent<HTMLSelectElement>,
|
||||
): void {
|
||||
function employeePositionSelectorOnChange(e: React.ChangeEvent<HTMLSelectElement>): void {
|
||||
if (employee === null) return;
|
||||
const pos = getSelectText(e.target);
|
||||
employee.pos = pos;
|
||||
@ -133,26 +117,10 @@ function ManualManagement(props: IProps): React.ReactElement {
|
||||
const nf = "0.000";
|
||||
|
||||
// Employee stats (after applying multipliers)
|
||||
const effCre = emp
|
||||
? emp.cre *
|
||||
props.corp.getEmployeeCreMultiplier() *
|
||||
props.division.getEmployeeCreMultiplier()
|
||||
: 0;
|
||||
const effCha = emp
|
||||
? emp.cha *
|
||||
props.corp.getEmployeeChaMultiplier() *
|
||||
props.division.getEmployeeChaMultiplier()
|
||||
: 0;
|
||||
const effInt = emp
|
||||
? emp.int *
|
||||
props.corp.getEmployeeIntMultiplier() *
|
||||
props.division.getEmployeeIntMultiplier()
|
||||
: 0;
|
||||
const effEff = emp
|
||||
? emp.eff *
|
||||
props.corp.getEmployeeEffMultiplier() *
|
||||
props.division.getEmployeeEffMultiplier()
|
||||
: 0;
|
||||
const effCre = emp ? emp.cre * props.corp.getEmployeeCreMultiplier() * props.division.getEmployeeCreMultiplier() : 0;
|
||||
const effCha = emp ? emp.cha * props.corp.getEmployeeChaMultiplier() * props.division.getEmployeeChaMultiplier() : 0;
|
||||
const effInt = emp ? emp.int * props.corp.getEmployeeIntMultiplier() * props.division.getEmployeeIntMultiplier() : 0;
|
||||
const effEff = emp ? emp.eff * props.corp.getEmployeeEffMultiplier() * props.division.getEmployeeEffMultiplier() : 0;
|
||||
|
||||
return (
|
||||
<div style={employeeInfoDivStyle}>
|
||||
@ -204,10 +172,7 @@ interface IAutoAssignProps {
|
||||
|
||||
function AutoAssignJob(props: IAutoAssignProps): React.ReactElement {
|
||||
const numJob = countEmployee(props.office.employees, props.job);
|
||||
const numUnassigned = countEmployee(
|
||||
props.office.employees,
|
||||
EmployeePositions.Unassigned,
|
||||
);
|
||||
const numUnassigned = countEmployee(props.office.employees, EmployeePositions.Unassigned);
|
||||
function assignEmployee(): void {
|
||||
if (numUnassigned <= 0) {
|
||||
console.warn("Cannot assign employee. No unassigned employees available");
|
||||
@ -232,19 +197,12 @@ function AutoAssignJob(props: IAutoAssignProps): React.ReactElement {
|
||||
return (
|
||||
<>
|
||||
<h2 className={"tooltip"} style={positionHeaderStyle}>
|
||||
{props.job} ({numJob})
|
||||
<span className={"tooltiptext"}>{props.desc}</span>
|
||||
{props.job} ({numJob})<span className={"tooltiptext"}>{props.desc}</span>
|
||||
</h2>
|
||||
<button
|
||||
className={numUnassigned > 0 ? "std-button" : "a-link-button-inactive"}
|
||||
onClick={assignEmployee}
|
||||
>
|
||||
<button className={numUnassigned > 0 ? "std-button" : "a-link-button-inactive"} onClick={assignEmployee}>
|
||||
+
|
||||
</button>
|
||||
<button
|
||||
className={numJob > 0 ? "std-button" : "a-link-button-inactive"}
|
||||
onClick={unassignEmployee}
|
||||
>
|
||||
<button className={numJob > 0 ? "std-button" : "a-link-button-inactive"} onClick={unassignEmployee}>
|
||||
-
|
||||
</button>
|
||||
<br />
|
||||
@ -253,10 +211,7 @@ function AutoAssignJob(props: IAutoAssignProps): React.ReactElement {
|
||||
}
|
||||
|
||||
function AutoManagement(props: IProps): React.ReactElement {
|
||||
const numUnassigned = countEmployee(
|
||||
props.office.employees,
|
||||
EmployeePositions.Unassigned,
|
||||
);
|
||||
const numUnassigned = countEmployee(props.office.employees, EmployeePositions.Unassigned);
|
||||
const vechain = props.corp.unlockUpgrades[4] === 1; // Has Vechain upgrade
|
||||
|
||||
// Calculate average morale, happiness, and energy. Also salary
|
||||
@ -330,20 +285,14 @@ function AutoManagement(props: IProps): React.ReactElement {
|
||||
<p className={"tooltip"} style={{ display: "inline-block" }}>
|
||||
Material Production:
|
||||
<span className={"tooltiptext"}>
|
||||
The base amount of material this office can produce. Does
|
||||
not include production multipliers from upgrades and
|
||||
materials. This value is based off the productivity of
|
||||
your Operations, Engineering, and Management employees
|
||||
The base amount of material this office can produce. Does not include production multipliers from
|
||||
upgrades and materials. This value is based off the productivity of your Operations, Engineering,
|
||||
and Management employees
|
||||
</span>
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
{numeralWrapper.format(
|
||||
props.division.getOfficeProductivity(props.office),
|
||||
"0.000",
|
||||
)}
|
||||
</p>
|
||||
<p>{numeralWrapper.format(props.division.getOfficeProductivity(props.office), "0.000")}</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@ -351,11 +300,9 @@ function AutoManagement(props: IProps): React.ReactElement {
|
||||
<p className={"tooltip"} style={{ display: "inline-block" }}>
|
||||
Product Production:
|
||||
<span className={"tooltiptext"}>
|
||||
The base amount of any given Product this office can
|
||||
produce. Does not include production multipliers from
|
||||
upgrades and materials. This value is based off the
|
||||
productivity of your Operations, Engineering, and
|
||||
Management employees
|
||||
The base amount of any given Product this office can produce. Does not include production
|
||||
multipliers from upgrades and materials. This value is based off the productivity of your
|
||||
Operations, Engineering, and Management employees
|
||||
</span>
|
||||
</p>
|
||||
</td>
|
||||
@ -375,19 +322,12 @@ function AutoManagement(props: IProps): React.ReactElement {
|
||||
<p className={"tooltip"} style={{ display: "inline-block" }}>
|
||||
Business Multiplier:
|
||||
<span className={"tooltiptext"}>
|
||||
The effect this office's 'Business' employees has on
|
||||
boosting sales
|
||||
The effect this office's 'Business' employees has on boosting sales
|
||||
</span>
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
x
|
||||
{numeralWrapper.format(
|
||||
props.division.getBusinessFactor(props.office),
|
||||
"0.000",
|
||||
)}
|
||||
</p>
|
||||
<p>x{numeralWrapper.format(props.division.getBusinessFactor(props.office), "0.000")}</p>
|
||||
</td>
|
||||
</tr>
|
||||
</>
|
||||
@ -400,9 +340,7 @@ function AutoManagement(props: IProps): React.ReactElement {
|
||||
division={props.division}
|
||||
player={props.player}
|
||||
job={EmployeePositions.Operations}
|
||||
desc={
|
||||
"Manages supply chain operations. Improves the amount of Materials and Products you produce."
|
||||
}
|
||||
desc={"Manages supply chain operations. Improves the amount of Materials and Products you produce."}
|
||||
/>
|
||||
|
||||
<AutoAssignJob
|
||||
@ -422,9 +360,7 @@ function AutoManagement(props: IProps): React.ReactElement {
|
||||
division={props.division}
|
||||
player={props.player}
|
||||
job={EmployeePositions.Business}
|
||||
desc={
|
||||
"Handles sales and finances. Improves the amount of Materials and Products you can sell."
|
||||
}
|
||||
desc={"Handles sales and finances. Improves the amount of Materials and Products you can sell."}
|
||||
/>
|
||||
|
||||
<AutoAssignJob
|
||||
@ -444,9 +380,7 @@ function AutoManagement(props: IProps): React.ReactElement {
|
||||
division={props.division}
|
||||
player={props.player}
|
||||
job={EmployeePositions.RandD}
|
||||
desc={
|
||||
"Research new innovative ways to improve the company. Generates Scientific Research."
|
||||
}
|
||||
desc={"Research new innovative ways to improve the company. Generates Scientific Research."}
|
||||
/>
|
||||
|
||||
<AutoAssignJob
|
||||
@ -464,8 +398,7 @@ function AutoManagement(props: IProps): React.ReactElement {
|
||||
}
|
||||
|
||||
export function IndustryOffice(props: IProps): React.ReactElement {
|
||||
const [employeeManualAssignMode, setEmployeeManualAssignMode] =
|
||||
useState(false);
|
||||
const [employeeManualAssignMode, setEmployeeManualAssignMode] = useState(false);
|
||||
|
||||
const buttonStyle = {
|
||||
fontSize: "13px",
|
||||
@ -530,28 +463,18 @@ export function IndustryOffice(props: IProps): React.ReactElement {
|
||||
<p>
|
||||
Size: {props.office.employees.length} / {props.office.size} employees
|
||||
</p>
|
||||
<button
|
||||
className={hireEmployeeButtonClass}
|
||||
onClick={openHireEmployeePopup}
|
||||
style={buttonStyle}
|
||||
>
|
||||
<button className={hireEmployeeButtonClass} onClick={openHireEmployeePopup} style={buttonStyle}>
|
||||
Hire Employee
|
||||
{props.office.employees.length === 0 && (
|
||||
<span className={"tooltiptext"}>
|
||||
You'll need to hire some employees to get your operations started!
|
||||
It's recommended to have at least one employee in every position
|
||||
You'll need to hire some employees to get your operations started! It's recommended to have at least one
|
||||
employee in every position
|
||||
</span>
|
||||
)}
|
||||
</button>
|
||||
<button
|
||||
className={autohireEmployeeButtonClass}
|
||||
onClick={autohireEmployeeButtonOnClick}
|
||||
style={buttonStyle}
|
||||
>
|
||||
<button className={autohireEmployeeButtonClass} onClick={autohireEmployeeButtonOnClick} style={buttonStyle}>
|
||||
Autohire Employee
|
||||
<span className={"tooltiptext"}>
|
||||
Automatically hires an employee and gives him/her a random name
|
||||
</span>
|
||||
<span className={"tooltiptext"}>Automatically hires an employee and gives him/her a random name</span>
|
||||
</button>
|
||||
<br />
|
||||
<button
|
||||
@ -561,9 +484,7 @@ export function IndustryOffice(props: IProps): React.ReactElement {
|
||||
disabled={props.corp.funds.lt(0)}
|
||||
>
|
||||
Upgrade size
|
||||
<span className={"tooltiptext"}>
|
||||
Upgrade the office's size so that it can hold more employees!
|
||||
</span>
|
||||
<span className={"tooltiptext"}>Upgrade the office's size so that it can hold more employees!</span>
|
||||
</button>
|
||||
{!props.division.hasResearch("AutoPartyManager") && (
|
||||
<button
|
||||
@ -574,33 +495,19 @@ export function IndustryOffice(props: IProps): React.ReactElement {
|
||||
>
|
||||
Throw Party
|
||||
<span className={"tooltiptext"}>
|
||||
"Throw an office party to increase your employee's morale and
|
||||
happiness"
|
||||
"Throw an office party to increase your employee's morale and happiness"
|
||||
</span>
|
||||
</button>
|
||||
)}
|
||||
<br />
|
||||
|
||||
<div>
|
||||
<SwitchButton
|
||||
manualMode={employeeManualAssignMode}
|
||||
switchMode={setEmployeeManualAssignMode}
|
||||
/>
|
||||
<SwitchButton manualMode={employeeManualAssignMode} switchMode={setEmployeeManualAssignMode} />
|
||||
</div>
|
||||
{employeeManualAssignMode ? (
|
||||
<ManualManagement
|
||||
corp={props.corp}
|
||||
division={props.division}
|
||||
office={props.office}
|
||||
player={props.player}
|
||||
/>
|
||||
<ManualManagement corp={props.corp} division={props.division} office={props.office} player={props.player} />
|
||||
) : (
|
||||
<AutoManagement
|
||||
corp={props.corp}
|
||||
division={props.division}
|
||||
office={props.office}
|
||||
player={props.player}
|
||||
/>
|
||||
<AutoManagement corp={props.corp} division={props.division} office={props.office} player={props.player} />
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
@ -40,19 +40,16 @@ export function IndustryOverview(props: IProps): React.ReactElement {
|
||||
break;
|
||||
case Industries.Pharmaceutical:
|
||||
createProductButtonText = "Create Drug";
|
||||
createProductPopupText =
|
||||
"Design and develop a new pharmaceutical drug!";
|
||||
createProductPopupText = "Design and develop a new pharmaceutical drug!";
|
||||
break;
|
||||
case Industries.Computer:
|
||||
case "Computer":
|
||||
createProductButtonText = "Create Product";
|
||||
createProductPopupText =
|
||||
"Design and manufacture a new computer hardware product!";
|
||||
createProductPopupText = "Design and manufacture a new computer hardware product!";
|
||||
break;
|
||||
case Industries.Robotics:
|
||||
createProductButtonText = "Design Robot";
|
||||
createProductPopupText =
|
||||
"Design and create a new robot or robotic system!";
|
||||
createProductPopupText = "Design and create a new robot or robotic system!";
|
||||
break;
|
||||
case Industries.Software:
|
||||
createProductButtonText = "Develop Software";
|
||||
@ -82,9 +79,7 @@ export function IndustryOverview(props: IProps): React.ReactElement {
|
||||
|
||||
const hasMaxProducts = props.division.hasMaximumNumberProducts();
|
||||
|
||||
const className = hasMaxProducts
|
||||
? "a-link-button-inactive tooltip"
|
||||
: "std-button";
|
||||
const className = hasMaxProducts ? "a-link-button-inactive tooltip" : "std-button";
|
||||
const buttonStyle = {
|
||||
margin: "6px",
|
||||
display: "inline-block",
|
||||
@ -110,8 +105,7 @@ export function IndustryOverview(props: IProps): React.ReactElement {
|
||||
{createProductButtonText}
|
||||
{hasMaxProducts && (
|
||||
<span className={"tooltiptext"}>
|
||||
You have reached the maximum number of products:{" "}
|
||||
{props.division.getMaximumNumberProducts()}
|
||||
You have reached the maximum number of products: {props.division.getMaximumNumberProducts()}
|
||||
</span>
|
||||
)}
|
||||
</button>
|
||||
@ -120,9 +114,7 @@ export function IndustryOverview(props: IProps): React.ReactElement {
|
||||
|
||||
function renderText(): React.ReactElement {
|
||||
const vechain = props.corp.unlockUpgrades[4] === 1;
|
||||
const profit = props.division.lastCycleRevenue
|
||||
.minus(props.division.lastCycleExpenses)
|
||||
.toNumber();
|
||||
const profit = props.division.lastCycleRevenue.minus(props.division.lastCycleExpenses).toNumber();
|
||||
|
||||
let advertisingInfo = false;
|
||||
const advertisingFactors = props.division.getAdvertisingFactors();
|
||||
@ -158,15 +150,9 @@ export function IndustryOverview(props: IProps): React.ReactElement {
|
||||
"production multiplier of your entire Division.<br><br>" +
|
||||
"Below are approximations for how effective each material is at boosting " +
|
||||
"this industry's production multiplier (Bigger bars = more effective):<br><br>" +
|
||||
`Hardware: ${convertEffectFacToGraphic(
|
||||
props.division.hwFac,
|
||||
)}<br>` +
|
||||
`Robots: ${convertEffectFacToGraphic(
|
||||
props.division.robFac,
|
||||
)}<br>` +
|
||||
`AI Cores: ${convertEffectFacToGraphic(
|
||||
props.division.aiFac,
|
||||
)}<br>` +
|
||||
`Hardware: ${convertEffectFacToGraphic(props.division.hwFac)}<br>` +
|
||||
`Robots: ${convertEffectFacToGraphic(props.division.robFac)}<br>` +
|
||||
`AI Cores: ${convertEffectFacToGraphic(props.division.aiFac)}<br>` +
|
||||
`Real Estate: ${convertEffectFacToGraphic(props.division.reFac)}`,
|
||||
);
|
||||
}
|
||||
@ -181,35 +167,21 @@ export function IndustryOverview(props: IProps): React.ReactElement {
|
||||
|
||||
return (
|
||||
<div>
|
||||
Industry: {props.division.type} (Corp Funds:{" "}
|
||||
<Money money={props.corp.funds.toNumber()} />)
|
||||
Industry: {props.division.type} (Corp Funds: <Money money={props.corp.funds.toNumber()} />)
|
||||
<br /> <br />
|
||||
Awareness: {numeralWrapper.format(
|
||||
props.division.awareness,
|
||||
"0.000",
|
||||
)}{" "}
|
||||
<br />
|
||||
Popularity: {numeralWrapper.format(
|
||||
props.division.popularity,
|
||||
"0.000",
|
||||
)}{" "}
|
||||
<br />
|
||||
Awareness: {numeralWrapper.format(props.division.awareness, "0.000")} <br />
|
||||
Popularity: {numeralWrapper.format(props.division.popularity, "0.000")} <br />
|
||||
{advertisingInfo !== false && (
|
||||
<p className={"tooltip"}>
|
||||
Advertising Multiplier: x
|
||||
{numeralWrapper.format(totalAdvertisingFac, "0.000")}
|
||||
Advertising Multiplier: x{numeralWrapper.format(totalAdvertisingFac, "0.000")}
|
||||
<span className={"tooltiptext cmpy-mgmt-advertising-info"}>
|
||||
Total multiplier for this industrys sales due to its awareness and
|
||||
popularity
|
||||
Total multiplier for this industrys sales due to its awareness and popularity
|
||||
<br />
|
||||
Awareness Bonus: x
|
||||
{numeralWrapper.format(Math.pow(awarenessFac, 0.85), "0.000")}
|
||||
Awareness Bonus: x{numeralWrapper.format(Math.pow(awarenessFac, 0.85), "0.000")}
|
||||
<br />
|
||||
Popularity Bonus: x
|
||||
{numeralWrapper.format(Math.pow(popularityFac, 0.85), "0.000")}
|
||||
Popularity Bonus: x{numeralWrapper.format(Math.pow(popularityFac, 0.85), "0.000")}
|
||||
<br />
|
||||
Ratio Multiplier: x
|
||||
{numeralWrapper.format(Math.pow(ratioFac, 0.85), "0.000")}
|
||||
Ratio Multiplier: x{numeralWrapper.format(Math.pow(ratioFac, 0.85), "0.000")}
|
||||
</span>
|
||||
</p>
|
||||
)}
|
||||
@ -224,8 +196,7 @@ export function IndustryOverview(props: IProps): React.ReactElement {
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
<Money money={props.division.lastCycleRevenue.toNumber()} /> /
|
||||
s
|
||||
<Money money={props.division.lastCycleRevenue.toNumber()} /> / s
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
@ -235,8 +206,7 @@ export function IndustryOverview(props: IProps): React.ReactElement {
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
<Money money={props.division.lastCycleExpenses.toNumber()} />{" "}
|
||||
/ s
|
||||
<Money money={props.division.lastCycleExpenses.toNumber()} /> / s
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
@ -254,11 +224,10 @@ export function IndustryOverview(props: IProps): React.ReactElement {
|
||||
</table>
|
||||
<br />
|
||||
<p className={"tooltip"}>
|
||||
Production Multiplier:{" "}
|
||||
{numeralWrapper.format(props.division.prodMult, "0.00")}
|
||||
Production Multiplier: {numeralWrapper.format(props.division.prodMult, "0.00")}
|
||||
<span className={"tooltiptext"}>
|
||||
Production gain from owning production-boosting materials such as
|
||||
hardware, Robots, AI Cores, and Real Estate
|
||||
Production gain from owning production-boosting materials such as hardware, Robots, AI Cores, and Real
|
||||
Estate
|
||||
</span>
|
||||
</p>
|
||||
<div className={"help-tip"} onClick={productionMultHelpTipOnClick}>
|
||||
@ -266,11 +235,9 @@ export function IndustryOverview(props: IProps): React.ReactElement {
|
||||
</div>
|
||||
<br /> <br />
|
||||
<p className={"tooltip"}>
|
||||
Scientific Research:{" "}
|
||||
{numeralWrapper.format(props.division.sciResearch.qty, "0.000a")}
|
||||
Scientific Research: {numeralWrapper.format(props.division.sciResearch.qty, "0.000a")}
|
||||
<span className={"tooltiptext"}>
|
||||
Scientific Research increases the quality of the materials and
|
||||
products that you produce.
|
||||
Scientific Research increases the quality of the materials and products that you produce.
|
||||
</span>
|
||||
</p>
|
||||
<button className={"help-tip"} onClick={openResearchPopup}>
|
||||
@ -340,15 +307,9 @@ export function IndustryOverview(props: IProps): React.ReactElement {
|
||||
|
||||
function renderUpgrade(props: IRenderUpgradeProps): React.ReactElement {
|
||||
return (
|
||||
<div
|
||||
className={"cmpy-mgmt-upgrade-div tooltip"}
|
||||
onClick={props.onClick}
|
||||
key={props.key}
|
||||
>
|
||||
<div className={"cmpy-mgmt-upgrade-div tooltip"} onClick={props.onClick} key={props.key}>
|
||||
{props.text}
|
||||
{props.tooltip != null && (
|
||||
<span className={"tooltiptext"}>{props.tooltip}</span>
|
||||
)}
|
||||
{props.tooltip != null && <span className={"tooltiptext"}>{props.tooltip}</span>}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@ -359,9 +320,7 @@ export function IndustryOverview(props: IProps): React.ReactElement {
|
||||
<div className={"cmpy-mgmt-industry-overview-panel"}>
|
||||
{renderText()}
|
||||
<br />
|
||||
<u className={"industry-purchases-and-upgrades-header"}>
|
||||
Purchases & Upgrades
|
||||
</u>
|
||||
<u className={"industry-purchases-and-upgrades-header"}>Purchases & Upgrades</u>
|
||||
<br />
|
||||
{renderUpgrades()} <br />
|
||||
{props.division.makesProducts && makeProductButton}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user