mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-12-23 22:52:29 +01:00
Convert Locations and Faction implementations to TypeScript. Also restructed directory. Implemented Sleeve, but untested
This commit is contained in:
parent
8fcb1706cc
commit
48c694c9c1
58892
dist/engine.bundle.js
vendored
58892
dist/engine.bundle.js
vendored
File diff suppressed because one or more lines are too long
111064
dist/vendor.bundle.js
vendored
111064
dist/vendor.bundle.js
vendored
File diff suppressed because one or more lines are too long
54
index.html
54
index.html
@ -2,7 +2,7 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Bitburner</title>
|
||||
<title>Bitburner - development</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">
|
||||
@ -112,7 +112,7 @@
|
||||
|
||||
<div id="script-editor-filename-wrapper">
|
||||
<p id="script-editor-filename-tag"> <strong style="background-color:#555;">Script name: </strong></p>
|
||||
<input id="script-editor-filename" type="text" maxlength="30" tabindex="1"/>
|
||||
<input id="script-editor-filename" type="text" maxlength="30" tabindex="1" />
|
||||
</div>
|
||||
|
||||
<div id="javascript-editor"></div>
|
||||
@ -162,7 +162,7 @@
|
||||
|
||||
<fieldset>
|
||||
<label for="script-editor-option-maxerr" class="tooltip">Max Error Count</label>
|
||||
<input type="range" max="1000" min="50" value="200" step="1" name="script-editor-option-maxerr" id="script-editor-option-maxerr"/>
|
||||
<input type="range" max="1000" min="50" value="200" step="1" name="script-editor-option-maxerr" id="script-editor-option-maxerr" />
|
||||
<em id="script-editor-option-maxerror-value-label" style="font-style: normal;"></em>
|
||||
</fieldset>
|
||||
</div> <!-- End script editor options panel -->
|
||||
@ -173,7 +173,7 @@
|
||||
<table id="terminal">
|
||||
<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;"/>
|
||||
<input type="text" id="terminal-input-text-box" class="terminal-input" tabindex="1" onfocus="this.value = this.value;" />
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@ -190,7 +190,7 @@
|
||||
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/>
|
||||
Active scripts: <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>)</p>
|
||||
<ul class="active-scripts-list" id="active-scripts-list" style="list-style: none;">
|
||||
@ -204,19 +204,19 @@
|
||||
The Hacknet is a global, decentralized network of machines. It is used by hackers all around
|
||||
the world to anonymously share computing power and perform distributed cyberattacks without the
|
||||
fear of being traced.
|
||||
<br/><br/>
|
||||
<br /><br />
|
||||
Here, you can purchase a Hacknet Node, a specialized machine that can connect and contribute its
|
||||
resources to the Hacknet network. This allows you to take a small percentage of profits
|
||||
from hacks performed on the network. Essentially, you are renting out your Node's computing power.
|
||||
<br/><br/>
|
||||
<br /><br />
|
||||
Each Hacknet Node you purchase will passively earn you money. Each Hacknet Node can be upgraded
|
||||
in order to increase its computing power and thereby increase the profit you earn from it.
|
||||
</p>
|
||||
<a id="hacknet-nodes-purchase-button" class="a-link-button"> Purchase Hacknet Node </a>
|
||||
<br/>
|
||||
<br />
|
||||
<div id="hacknet-nodes-money-multipliers-div">
|
||||
<p id="hacknet-nodes-money">
|
||||
<span>Money:</span><span id="hacknet-nodes-player-money" class="money-gold"></span><br/>
|
||||
<span>Money:</span><span id="hacknet-nodes-player-money" class="money-gold"></span><br />
|
||||
<span>Total Hacknet Node Production:</span><span id="hacknet-nodes-total-production" class="money-gold"></span>
|
||||
</p>
|
||||
<span id="hacknet-nodes-multipliers">
|
||||
@ -474,7 +474,8 @@
|
||||
|
||||
<!-- Tutorial content -->
|
||||
<div id="tutorial-container" class="generic-menupage-container">
|
||||
<a id="tutorial-getting-started-link" class="a-link-button" href="http://bitburner.wikia.com/wiki/Chapt3rs_Guide_to_Getting_Started_with_Bitburner" target="_blank"> Getting Started </a>
|
||||
<a id="tutorial-getting-started-link" class="a-link-button"
|
||||
href="http://bitburner.wikia.com/wiki/Chapt3rs_Guide_to_Getting_Started_with_Bitburner" target="_blank"> Getting Started </a>
|
||||
<a id="tutorial-networking-link" class="a-link-button"> Servers & Networking </a>
|
||||
<a id="tutorial-hacking-link" class="a-link-button"> Hacking </a>
|
||||
<a id="tutorial-scripts-link" class="a-link-button"> Scripts </a>
|
||||
@ -483,7 +484,8 @@
|
||||
<a id="tutorial-jobs-link" class="a-link-button"> Companies and Infiltration </a>
|
||||
<a id="tutorial-factions-link" class="a-link-button"> Factions </a>
|
||||
<a id="tutorial-augmentations-link" class="a-link-button"> Augmentations </a>
|
||||
<a id="tutorial-shortcuts-link" class="a-link-button" href="https://bitburner.wikia.com/wiki/Shortcuts" target="_blank"> Keyboard Shortcuts </a>
|
||||
<a id="tutorial-shortcuts-link" class="a-link-button"
|
||||
href="https://bitburner.wikia.com/wiki/Shortcuts" target="_blank"> Keyboard Shortcuts </a>
|
||||
|
||||
<a id="tutorial-back-button" class="a-link-button"> Back </a>
|
||||
<p id="tutorial-text"> </p>
|
||||
@ -574,7 +576,7 @@
|
||||
<p id="location-slums-description">
|
||||
You have entered the Slums, a poverty-ridden district filled with gangs, criminals, and
|
||||
other shadowy entities. The city's government and police have neglected this area for years...
|
||||
<br/><br/><br/>
|
||||
<br /><br /><br />
|
||||
In the Slums, you can commit crimes to earn money and experience. Crime attempts are not always
|
||||
successful. Your chance at successfully committing a crime is determined by your stats.
|
||||
</p>
|
||||
@ -621,7 +623,7 @@
|
||||
|
||||
<div id="stock-market-container" class="generic-menupage-container">
|
||||
<p>
|
||||
Welcome to the World Stock Exchange (WSE)! <br/><br/>
|
||||
Welcome to the World Stock Exchange (WSE)! <br /><br />
|
||||
|
||||
To begin trading, you must first purchase an account. WSE accounts will persist
|
||||
after you 'reset' by installing Augmentations.
|
||||
@ -634,7 +636,7 @@
|
||||
TIX, short for Trade Information eXchange, is the communications protocol supported by the WSE.
|
||||
Purchasing access to the TIX API lets you write code to create your own algorithmic/automated
|
||||
trading strategies.
|
||||
<br/><br/>
|
||||
<br /><br />
|
||||
If you purchase access to the TIX API, you will retain that access even after
|
||||
you 'reset' by installing Augmentations.
|
||||
</p>
|
||||
@ -644,7 +646,7 @@
|
||||
<p>
|
||||
Four Sigma's (4S) Market Data Feed provides information about stocks
|
||||
that will help your trading strategies.
|
||||
<br/><br/>
|
||||
<br /><br />
|
||||
If you purchase access to 4S Market Data and/or the 4S TIX API, you will
|
||||
retain that access even after you 'reset' by installing Augmentations.
|
||||
</p>
|
||||
@ -662,7 +664,7 @@
|
||||
<a id="stock-market-mode" class="a-link-button tooltip"></a>
|
||||
<a id="stock-market-expand-tickers" class="a-link-button tooltip">Expand tickers</a>
|
||||
<a id="stock-market-collapse-tickers" class="a-link-button tooltip">Collapse tickers</a>
|
||||
<br/><br/>
|
||||
<br /><br />
|
||||
<input id="stock-market-watchlist-filter" type="text" placeholder="Filter Stocks by symbol (comma-separated list)"/>
|
||||
<a id="stock-market-watchlist-filter-update" class="a-link-button"> Update Watchlist </a>
|
||||
<ul id="stock-market-list" style="list-style:none;">
|
||||
@ -692,7 +694,7 @@
|
||||
<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"/>
|
||||
<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>
|
||||
@ -704,7 +706,7 @@
|
||||
<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/>
|
||||
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"> Yes </button>
|
||||
@ -717,8 +719,8 @@
|
||||
<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/>
|
||||
<select id="infiltration-faction-select"> </select> <br/>
|
||||
<button id="infiltration-box-sell" class="a-link-button"> Sell on Black Market </button> <br /><br />
|
||||
<select id="infiltration-faction-select"> </select> <br />
|
||||
<button id="infiltration-box-faction" class="a-link-button"> Give to Faction for Reputation </button>
|
||||
|
||||
</div>
|
||||
@ -804,7 +806,7 @@
|
||||
<div id="game-options-content" class="game-options-box">
|
||||
<button id="game-options-close-button">×</button>
|
||||
<h1> Game Options </h1>
|
||||
<br/>
|
||||
<br />
|
||||
<div id="game-options-left-panel">
|
||||
<!-- Netscript execution time -->
|
||||
<fieldset>
|
||||
@ -816,7 +818,7 @@
|
||||
</span>
|
||||
</label>
|
||||
|
||||
<input type="range" max="100" min="10" step="1" name="settingsNSExecTimeRangeVal" id="settingsNSExecTimeRangeVal" value="25"/>
|
||||
<input type ="range" max="100" min="10" step="1" name="settingsNSExecTimeRangeVal" id="settingsNSExecTimeRangeVal" value="25" />
|
||||
<em id="settingsNSExecTimeRangeValLabel" style="font-style: normal;"></em>
|
||||
</fieldset>
|
||||
|
||||
@ -830,7 +832,7 @@
|
||||
</span>
|
||||
</label>
|
||||
|
||||
<input type="range" max="100" min="20" step="1" name="settingsNSLogRangeVal" id="settingsNSLogRangeVal" value="50"/>
|
||||
<input type="range" max="100" min="20" step="1" name="settingsNSLogRangeVal" id="settingsNSLogRangeVal" value="50" />
|
||||
<em id="settingsNSLogRangeValLabel" style="font-style: normal;"></em>
|
||||
</fieldset>
|
||||
|
||||
@ -844,7 +846,7 @@
|
||||
</span>
|
||||
</label>
|
||||
|
||||
<input type="range" max="100" min="20" step="1" name="settingsNSPortRangeVal" id="settingsNSPortRangeVal" value="50"/>
|
||||
<input type="range" max="100" min="20" step="1" name="settingsNSPortRangeVal" id="settingsNSPortRangeVal" value="50" />
|
||||
<em id="settingsNSPortRangeValLabel" style="font-style: normal;"></em>
|
||||
</fieldset>
|
||||
|
||||
@ -856,7 +858,7 @@
|
||||
</span>
|
||||
</label>
|
||||
|
||||
<input type="range" max="600" min="0" step="1" name="settingsAutosaveIntervalVal" id="settingsAutosaveIntervalVal" value="60"/>
|
||||
<input type="range" max="600" min="0" step="1" name="settingsAutosaveIntervalVal" id="settingsAutosaveIntervalVal" value="60" />
|
||||
<em id="settingsAutosaveIntervalValLabel" style="font-style: normal;"></em>
|
||||
</fieldset>
|
||||
|
||||
@ -968,7 +970,7 @@
|
||||
<a id="save-game-link" class="a-link-button" style="display:inline-block;width:46%;"> Save Game </a>
|
||||
<a id="delete-game-link" class="a-link-button" style="display:inline-block;width:46%;"> Delete Game </a>
|
||||
<a id="export-game-link" class="a-link-button" style="display:inline-block;width:46%;"> Export Game </a>
|
||||
<input type="file" id="import-game-file-selector" name="file"/>
|
||||
<input type="file" id="import-game-file-selector" name="file" />
|
||||
<a id="import-game-link" class="a-link-button" style="display:inline-block;width:46%;"> Import Game </a>
|
||||
<a id="debug-delete-scripts-link" class="a-link-button tooltip" style="display:block;width:46%;">
|
||||
(DEBUG) Delete Active Scripts
|
||||
|
@ -1,26 +1,27 @@
|
||||
import {BitNodeMultipliers} from "./BitNodeMultipliers";
|
||||
import {CONSTANTS} from "./Constants";
|
||||
import {Engine} from "./engine";
|
||||
import {Factions, factionExists} from "./Faction";
|
||||
import {hasBladeburnerSF} from "./NetscriptFunctions";
|
||||
import {addWorkerScript} from "./NetscriptWorker";
|
||||
import {Player} from "./Player";
|
||||
import {prestigeAugmentation} from "./Prestige";
|
||||
import {saveObject} from "./SaveObject";
|
||||
import {Script, RunningScript} from "./Script";
|
||||
import {Server} from "./Server";
|
||||
import {OwnedAugmentationsOrderSetting} from "./SettingEnums";
|
||||
import {Settings} from "./Settings";
|
||||
import { BitNodeMultipliers } from "./BitNodeMultipliers";
|
||||
import { CONSTANTS } from "./Constants";
|
||||
import { Engine } from "./engine";
|
||||
import { Factions,
|
||||
factionExists } from "./Faction/Factions";
|
||||
import { hasBladeburnerSF } from "./NetscriptFunctions";
|
||||
import { addWorkerScript } from "./NetscriptWorker";
|
||||
import { Player } from "./Player";
|
||||
import { prestigeAugmentation } from "./Prestige";
|
||||
import { saveObject } from "./SaveObject";
|
||||
import { Script , RunningScript} from "./Script";
|
||||
import { Server } from "./Server";
|
||||
import { OwnedAugmentationsOrderSetting } from "./SettingEnums";
|
||||
import { Settings } from "./Settings";
|
||||
|
||||
import {SourceFiles} from "./SourceFile";
|
||||
import {dialogBoxCreate} from "../utils/DialogBox";
|
||||
import {createAccordionElement} from "../utils/uiHelpers/createAccordionElement";
|
||||
import {Reviver, Generic_toJSON,
|
||||
Generic_fromJSON} from "../utils/JSONReviver";
|
||||
import {clearObject} from "../utils/helpers/clearObject";
|
||||
import {createElement} from "../utils/uiHelpers/createElement";
|
||||
import {isString} from "../utils/helpers/isString";
|
||||
import {removeChildrenFromElement} from "../utils/uiHelpers/removeChildrenFromElement";
|
||||
import { SourceFiles } from "./SourceFile";
|
||||
import { dialogBoxCreate } from "../utils/DialogBox";
|
||||
import { createAccordionElement } from "../utils/uiHelpers/createAccordionElement";
|
||||
import { Reviver, Generic_toJSON,
|
||||
Generic_fromJSON } from "../utils/JSONReviver";
|
||||
import { clearObject } from "../utils/helpers/clearObject";
|
||||
import { createElement } from "../utils/uiHelpers/createElement";
|
||||
import { isString } from "../utils/helpers/isString";
|
||||
import { removeChildrenFromElement } from "../utils/uiHelpers/removeChildrenFromElement";
|
||||
|
||||
//Augmentations
|
||||
function Augmentation(params) {
|
||||
@ -1569,13 +1570,13 @@ function initAugmentations() {
|
||||
//Do this before adding special Augmentations that become available in later BitNodes
|
||||
if (Player.bitNodeN === 2) {
|
||||
console.log("Adding all augmentations to crime factions for Bit node 2");
|
||||
Factions["Slum Snakes"].addAllAugmentations();
|
||||
Factions["Tetrads"].addAllAugmentations();
|
||||
Factions["The Syndicate"].addAllAugmentations();
|
||||
Factions["The Dark Army"].addAllAugmentations();
|
||||
Factions["Speakers for the Dead"].addAllAugmentations();
|
||||
Factions["NiteSec"].addAllAugmentations();
|
||||
Factions["The Black Hand"].addAllAugmentations();
|
||||
Factions["Slum Snakes"].addAllAugmentations(Augmentations);
|
||||
Factions["Tetrads"].addAllAugmentations(Augmentations);
|
||||
Factions["The Syndicate"].addAllAugmentations(Augmentations);
|
||||
Factions["The Dark Army"].addAllAugmentations(Augmentations);
|
||||
Factions["Speakers for the Dead"].addAllAugmentations(Augmentations);
|
||||
Factions["NiteSec"].addAllAugmentations(Augmentations);
|
||||
Factions["The Black Hand"].addAllAugmentations(Augmentations);
|
||||
}
|
||||
|
||||
//Special Bladeburner Augmentations
|
||||
|
@ -1,32 +1,33 @@
|
||||
import {Augmentations, AugmentationNames} from "./Augmentations";
|
||||
import {BitNodeMultipliers} from "./BitNodeMultipliers";
|
||||
import {CONSTANTS} from "./Constants";
|
||||
import {Engine} from "./engine";
|
||||
import {Faction, Factions, factionExists,
|
||||
joinFaction, displayFactionContent} from "./Faction";
|
||||
import {Locations} from "./Locations";
|
||||
import {Player} from "./Player";
|
||||
import {hackWorldDaemon, redPillFlag} from "./RedPill";
|
||||
import {numeralWrapper} from "./ui/numeralFormat";
|
||||
import {KEY} from "../utils/helpers/keyCodes";
|
||||
import { Augmentations , AugmentationNames } from "./Augmentations";
|
||||
import { BitNodeMultipliers } from "./BitNodeMultipliers";
|
||||
import { CONSTANTS } from "./Constants";
|
||||
import { Engine } from "./engine";
|
||||
import { Faction } from "./Faction/Faction";
|
||||
import { Factions, factionExists } from "./Faction/Factions";
|
||||
import { joinFaction, displayFactionContent } from "./Faction/FactionHelpers";
|
||||
import { Locations } from "./Locations";
|
||||
import { Player } from "./Player";
|
||||
import { hackWorldDaemon, redPillFlag } from "./RedPill";
|
||||
import { numeralWrapper } from "./ui/numeralFormat";
|
||||
import { KEY } from "../utils/helpers/keyCodes";
|
||||
|
||||
import {createProgressBarText} from "../utils/helpers/createProgressBarText";
|
||||
import {dialogBoxCreate} from "../utils/DialogBox";
|
||||
import {removeChildrenFromElement} from "../utils/uiHelpers/removeChildrenFromElement";
|
||||
import {Reviver, Generic_toJSON,
|
||||
Generic_fromJSON} from "../utils/JSONReviver";
|
||||
import {addOffset} from "../utils/helpers/addOffset";
|
||||
import {appendLineBreaks} from "../utils/uiHelpers/appendLineBreaks";
|
||||
import {clearObject} from "../utils/helpers/clearObject";
|
||||
import {createElement} from "../utils/uiHelpers/createElement";
|
||||
import {createPopup} from "../utils/uiHelpers/createPopup";
|
||||
import {Page, routing} from "./ui/navigationTracking";
|
||||
import {exceptionAlert} from "../utils/helpers/exceptionAlert";
|
||||
import {formatNumber} from "../utils/StringHelperFunctions";
|
||||
import {getRandomInt} from "../utils/helpers/getRandomInt";
|
||||
import {getTimestamp} from "../utils/helpers/getTimestamp";
|
||||
import {removeElement} from "../utils/uiHelpers/removeElement";
|
||||
import {removeElementById} from "../utils/uiHelpers/removeElementById";
|
||||
import { createProgressBarText } from "../utils/helpers/createProgressBarText";
|
||||
import { dialogBoxCreate } from "../utils/DialogBox";
|
||||
import { removeChildrenFromElement } from "../utils/uiHelpers/removeChildrenFromElement";
|
||||
import { Reviver, Generic_toJSON,
|
||||
Generic_fromJSON } from "../utils/JSONReviver";
|
||||
import { addOffset } from "../utils/helpers/addOffset";
|
||||
import { appendLineBreaks } from "../utils/uiHelpers/appendLineBreaks";
|
||||
import { clearObject } from "../utils/helpers/clearObject";
|
||||
import { createElement } from "../utils/uiHelpers/createElement";
|
||||
import { createPopup } from "../utils/uiHelpers/createPopup";
|
||||
import { Page, routing } from "./ui/navigationTracking";
|
||||
import { exceptionAlert } from "../utils/helpers/exceptionAlert";
|
||||
import { formatNumber } from "../utils/StringHelperFunctions";
|
||||
import { getRandomInt } from "../utils/helpers/getRandomInt";
|
||||
import { getTimestamp } from "../utils/helpers/getTimestamp";
|
||||
import { removeElement } from "../utils/uiHelpers/removeElement";
|
||||
import { removeElementById } from "../utils/uiHelpers/removeElementById";
|
||||
|
||||
|
||||
var CityNames = ["Aevum", "Chongqing", "Sector-12", "New Tokyo", "Ishima", "Volhaven"];
|
||||
|
@ -1,12 +1,12 @@
|
||||
import {CodingContract,
|
||||
CodingContractRewardType,
|
||||
CodingContractTypes} from "./CodingContracts";
|
||||
import {Factions} from "./Faction";
|
||||
import {Player} from "./Player";
|
||||
import {GetServerByHostname,
|
||||
AllServers} from "./Server";
|
||||
import { CodingContract,
|
||||
CodingContractRewardType,
|
||||
CodingContractTypes } from "./CodingContracts";
|
||||
import { Factions } from "./Faction/Factions";
|
||||
import { Player } from "./Player";
|
||||
import { GetServerByHostname,
|
||||
AllServers } from "./Server";
|
||||
|
||||
import {getRandomInt} from "../utils/helpers/getRandomInt";
|
||||
import { getRandomInt } from "../utils/helpers/getRandomInt";
|
||||
|
||||
export function generateRandomContract() {
|
||||
// First select a random problem type
|
||||
|
@ -125,7 +125,7 @@ export class Company {
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize the current file to a JSON save state.
|
||||
* Serialize the current object to a JSON save state.
|
||||
*/
|
||||
toJSON(): any {
|
||||
return Generic_toJSON("Company", this);
|
||||
|
@ -1,29 +1,34 @@
|
||||
import {BitNodeMultipliers} from "./BitNodeMultipliers";
|
||||
import {Factions} from "./Faction";
|
||||
import {showLiterature} from "./Literature";
|
||||
import {Locations} from "./Locations";
|
||||
import {Player} from "./Player";
|
||||
import { BitNodeMultipliers } from "./BitNodeMultipliers";
|
||||
import { Factions } from "./Faction/Factions";
|
||||
import { showLiterature } from "./Literature";
|
||||
import { Locations } from "./Locations";
|
||||
import { Player } from "./Player";
|
||||
|
||||
import Decimal from "decimal.js";
|
||||
import {numeralWrapper} from "./ui/numeralFormat";
|
||||
import { numeralWrapper } from "./ui/numeralFormat";
|
||||
|
||||
import {dialogBoxCreate} from "../utils/DialogBox";
|
||||
import {clearSelector} from "../utils/uiHelpers/clearSelector";
|
||||
import {Reviver, Generic_toJSON,
|
||||
Generic_fromJSON} from "../utils/JSONReviver";
|
||||
import {createElement} from "../utils/uiHelpers/createElement";
|
||||
import {createPopup} from "../utils/uiHelpers/createPopup";
|
||||
import {Page, routing} from "./ui/navigationTracking";
|
||||
import {formatNumber, generateRandomString} from "../utils/StringHelperFunctions";
|
||||
import {getRandomInt} from "../utils/helpers/getRandomInt";
|
||||
import {isString} from "../utils/helpers/isString";
|
||||
import {removeChildrenFromElement} from "../utils/uiHelpers/removeChildrenFromElement";
|
||||
import {removeElementById} from "../utils/uiHelpers/removeElementById";
|
||||
import {yesNoBoxCreate, yesNoTxtInpBoxCreate,
|
||||
yesNoBoxGetYesButton, yesNoBoxGetNoButton,
|
||||
yesNoTxtInpBoxGetYesButton, yesNoTxtInpBoxGetNoButton,
|
||||
yesNoTxtInpBoxGetInput, yesNoBoxClose,
|
||||
yesNoTxtInpBoxClose, yesNoBoxOpen} from "../utils/YesNoBox";
|
||||
import { dialogBoxCreate } from "../utils/DialogBox";
|
||||
import { clearSelector } from "../utils/uiHelpers/clearSelector";
|
||||
import { Reviver, Generic_toJSON,
|
||||
Generic_fromJSON } from "../utils/JSONReviver";
|
||||
import { createElement } from "../utils/uiHelpers/createElement";
|
||||
import { createPopup } from "../utils/uiHelpers/createPopup";
|
||||
import { Page, routing } from "./ui/navigationTracking";
|
||||
import { formatNumber, generateRandomString } from "../utils/StringHelperFunctions";
|
||||
import { getRandomInt } from "../utils/helpers/getRandomInt";
|
||||
import { isString } from "../utils/helpers/isString";
|
||||
import { removeChildrenFromElement } from "../utils/uiHelpers/removeChildrenFromElement";
|
||||
import { removeElementById } from "../utils/uiHelpers/removeElementById";
|
||||
import { yesNoBoxCreate,
|
||||
yesNoTxtInpBoxCreate,
|
||||
yesNoBoxGetYesButton,
|
||||
yesNoBoxGetNoButton,
|
||||
yesNoTxtInpBoxGetYesButton,
|
||||
yesNoTxtInpBoxGetNoButton,
|
||||
yesNoTxtInpBoxGetInput,
|
||||
yesNoBoxClose,
|
||||
yesNoTxtInpBoxClose,
|
||||
yesNoBoxOpen } from "../utils/YesNoBox";
|
||||
|
||||
/* State */
|
||||
var companyStates = ["START", "PURCHASE", "PRODUCTION", "SALE", "EXPORT"];
|
||||
|
@ -1,19 +1,19 @@
|
||||
import {AugmentationNames} from "./Augmentations";
|
||||
import {generateRandomContract} from "./CodingContractGenerator";
|
||||
import {Programs} from "./CreateProgram";
|
||||
import {Factions} from "./Faction";
|
||||
import {Player} from "./Player";
|
||||
import {AllServers} from "./Server";
|
||||
import {hackWorldDaemon} from "./RedPill";
|
||||
import {StockMarket,
|
||||
SymbolToStockMap} from "./StockMarket";
|
||||
import {Stock} from "./Stock";
|
||||
import {Terminal} from "./Terminal";
|
||||
import {numeralWrapper} from "./ui/numeralFormat";
|
||||
import {dialogBoxCreate} from "../utils/DialogBox";
|
||||
import {exceptionAlert} from "../utils/helpers/exceptionAlert";
|
||||
import {createElement} from "../utils/uiHelpers/createElement";
|
||||
import {removeElementById} from "../utils/uiHelpers/removeElementById";
|
||||
import { AugmentationNames } from "./Augmentations";
|
||||
import { generateRandomContract } from "./CodingContractGenerator";
|
||||
import { Programs } from "./CreateProgram";
|
||||
import { Factions } from "./Faction/Factions";
|
||||
import { Player } from "./Player";
|
||||
import { AllServers } from "./Server";
|
||||
import { hackWorldDaemon } from "./RedPill";
|
||||
import { StockMarket,
|
||||
SymbolToStockMap } from "./StockMarket";
|
||||
import { Stock } from "./Stock";
|
||||
import { Terminal } from "./Terminal";
|
||||
import { numeralWrapper } from "./ui/numeralFormat";
|
||||
import { dialogBoxCreate } from "../utils/DialogBox";
|
||||
import { exceptionAlert } from "../utils/helpers/exceptionAlert";
|
||||
import { createElement } from "../utils/uiHelpers/createElement";
|
||||
import { removeElementById } from "../utils/uiHelpers/removeElementById";
|
||||
|
||||
const devMenuContainerId = "dev-menu-container";
|
||||
|
||||
|
118
src/Faction/Faction.ts
Normal file
118
src/Faction/Faction.ts
Normal file
@ -0,0 +1,118 @@
|
||||
import { CONSTANTS } from "../Constants";
|
||||
import { FactionInfo,
|
||||
FactionInfos } from "./FactionInfo";
|
||||
import { Generic_fromJSON, Generic_toJSON, Reviver } from "../../utils/JSONReviver";
|
||||
|
||||
export class Faction {
|
||||
/**
|
||||
* Initiatizes a Faction object from a JSON save state.
|
||||
*/
|
||||
static fromJSON(value: any): Faction {
|
||||
return Generic_fromJSON(Faction, value.data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Flag signalling whether the player has already received an invitation
|
||||
* to this faction
|
||||
*/
|
||||
alreadyInvited: boolean = false;
|
||||
|
||||
/**
|
||||
* Holds names of all augmentations that this Faction offers
|
||||
*/
|
||||
augmentations: string[] = [];
|
||||
|
||||
/**
|
||||
* Amount of favor the player has with this faction.
|
||||
*/
|
||||
favor: number = 0;
|
||||
|
||||
/**
|
||||
* Flag signalling whether player has been banned from this faction
|
||||
*/
|
||||
isBanned: boolean = false;
|
||||
|
||||
/**
|
||||
* Flag signalling whether player is a member of this faction
|
||||
*/
|
||||
isMember: boolean = false;
|
||||
|
||||
/**
|
||||
* Name of faction
|
||||
*/
|
||||
name: string = "";
|
||||
|
||||
/**
|
||||
* Amount of reputation player has with this faction
|
||||
*/
|
||||
playerReputation: number = 0;
|
||||
|
||||
/**
|
||||
* Reputation from the last "prestige" that was not converted to favor.
|
||||
* This reputation rolls over and is used for the next favor calculation
|
||||
*/
|
||||
rolloverRep: number = 0;
|
||||
|
||||
constructor(name: string="") {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
getInfo(): FactionInfo {
|
||||
const info = FactionInfos[this.name];
|
||||
if (info == null) {
|
||||
throw new Error(`Missing faction from FactionInfos: ${this.name} this probably means the faction got corrupted somehow`);
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
gainFavor(): void {
|
||||
if (this.favor == null) { this.favor = 0; }
|
||||
if (this.rolloverRep == null) { this.rolloverRep = 0; }
|
||||
const res = this.getFavorGain();
|
||||
if (res.length !== 2) {
|
||||
console.error("Invalid result from getFavorGain() function");
|
||||
return;
|
||||
}
|
||||
this.favor += res[0];
|
||||
this.rolloverRep = res[1];
|
||||
}
|
||||
|
||||
//Returns an array with [How much favor would be gained, how much rep would be left over]
|
||||
getFavorGain(): number[] {
|
||||
if (this.favor == null) { this.favor = 0; }
|
||||
if (this.rolloverRep == null) { this.rolloverRep = 0; }
|
||||
var favorGain = 0, rep = this.playerReputation + this.rolloverRep;
|
||||
let reqdRep = CONSTANTS.FactionReputationToFavorBase *
|
||||
Math.pow(CONSTANTS.FactionReputationToFavorMult, this.favor);
|
||||
while(rep > 0) {
|
||||
if (rep >= reqdRep) {
|
||||
++favorGain;
|
||||
rep -= reqdRep;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
reqdRep *= CONSTANTS.FactionReputationToFavorMult;
|
||||
}
|
||||
return [favorGain, rep];
|
||||
}
|
||||
|
||||
//Adds all Augmentations to this faction.
|
||||
addAllAugmentations(augs: object): void {
|
||||
this.augmentations.length = 0;
|
||||
for (const name in augs) {
|
||||
if (augs.hasOwnProperty(name)) {
|
||||
this.augmentations.push(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize the current object to a JSON save state.
|
||||
*/
|
||||
toJSON(): any {
|
||||
return Generic_toJSON("Faction", this);
|
||||
}
|
||||
}
|
||||
|
||||
Reviver.constructors.Faction = Faction;
|
@ -1,139 +1,26 @@
|
||||
import {Augmentations, AugmentationNames,
|
||||
PlayerOwnedAugmentation} from "./Augmentations";
|
||||
import {BitNodeMultipliers} from "./BitNodeMultipliers";
|
||||
import {CONSTANTS} from "./Constants";
|
||||
import {Engine} from "./engine";
|
||||
PlayerOwnedAugmentation} from "../Augmentations";
|
||||
import {BitNodeMultipliers} from "../BitNodeMultipliers";
|
||||
import {CONSTANTS} from "../Constants";
|
||||
import {Engine} from "../engine";
|
||||
import {FactionInfos} from "./FactionInfo";
|
||||
import {Locations} from "./Location";
|
||||
import {HackingMission, setInMission} from "./Missions";
|
||||
import {Player} from "./Player";
|
||||
import {PurchaseAugmentationsOrderSetting} from "./SettingEnums";
|
||||
import {Settings} from "./Settings";
|
||||
import {Locations} from "../Location";
|
||||
import {HackingMission, setInMission} from "../Missions";
|
||||
import {Player} from "../Player";
|
||||
import {PurchaseAugmentationsOrderSetting} from "../SettingEnums";
|
||||
import {Settings} from "../Settings";
|
||||
|
||||
import {Page, routing} from "./ui/navigationTracking";
|
||||
import {numeralWrapper} from "./ui/numeralFormat";
|
||||
import {dialogBoxCreate} from "../utils/DialogBox";
|
||||
import {factionInvitationBoxCreate} from "../utils/FactionInvitationBox";
|
||||
import {removeChildrenFromElement} from "../utils/uiHelpers/removeChildrenFromElement";
|
||||
import {createElement} from "../utils/uiHelpers/createElement";
|
||||
import {Page, routing} from "../ui/navigationTracking";
|
||||
import {numeralWrapper} from "../ui/numeralFormat";
|
||||
import {dialogBoxCreate} from "../../utils/DialogBox";
|
||||
import {factionInvitationBoxCreate} from "../../utils/FactionInvitationBox";
|
||||
import {removeChildrenFromElement} from "../../utils/uiHelpers/removeChildrenFromElement";
|
||||
import {createElement} from "../../utils/uiHelpers/createElement";
|
||||
import {Reviver, Generic_toJSON,
|
||||
Generic_fromJSON} from "../utils/JSONReviver";
|
||||
import {formatNumber} from "../utils/StringHelperFunctions";
|
||||
Generic_fromJSON} from "../../utils/JSONReviver";
|
||||
import {formatNumber} from "../../utils/StringHelperFunctions";
|
||||
import {yesNoBoxCreate, yesNoBoxGetYesButton,
|
||||
yesNoBoxGetNoButton, yesNoBoxClose} from "../utils/YesNoBox";
|
||||
|
||||
function Faction(name="") {
|
||||
this.name = name;
|
||||
this.augmentations = []; //Name of augmentation only
|
||||
|
||||
//Player-related properties for faction
|
||||
this.isMember = false; //Whether player is member
|
||||
this.isBanned = false; //Whether or not player is banned from joining this faction
|
||||
this.playerReputation = 0; //"Reputation" within faction
|
||||
this.alreadyInvited = false;
|
||||
|
||||
//Faction favor
|
||||
this.favor = 0;
|
||||
this.rolloverRep = 0;
|
||||
};
|
||||
|
||||
Faction.prototype.getInfo = function() {
|
||||
const info = FactionInfos[this.name];
|
||||
if(info == null) {
|
||||
throw new Error("Missing faction from FactionInfos: " + this.name+" this probably means the faction got corrupted somehow");
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
Faction.prototype.gainFavor = function() {
|
||||
if (this.favor == null || this.favor == undefined) {this.favor = 0;}
|
||||
if (this.rolloverRep == null || this.rolloverRep == undefined) {this.rolloverRep = 0;}
|
||||
var res = this.getFavorGain();
|
||||
if (res.length != 2) {
|
||||
console.log("Error: invalid result from getFavorGain() function");
|
||||
return;
|
||||
}
|
||||
this.favor += res[0];
|
||||
this.rolloverRep = res[1];
|
||||
}
|
||||
|
||||
//Returns an array with [How much favor would be gained, how much rep would be left over]
|
||||
Faction.prototype.getFavorGain = function() {
|
||||
if (this.favor == null || this.favor == undefined) {this.favor = 0;}
|
||||
if (this.rolloverRep == null || this.rolloverRep == undefined) {this.rolloverRep = 0;}
|
||||
var favorGain = 0, rep = this.playerReputation + this.rolloverRep;
|
||||
var reqdRep = CONSTANTS.FactionReputationToFavorBase *
|
||||
Math.pow(CONSTANTS.FactionReputationToFavorMult, this.favor);
|
||||
while(rep > 0) {
|
||||
if (rep >= reqdRep) {
|
||||
++favorGain;
|
||||
rep -= reqdRep;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
reqdRep *= CONSTANTS.FactionReputationToFavorMult;
|
||||
}
|
||||
return [favorGain, rep];
|
||||
}
|
||||
|
||||
//Adds all Augmentations to this faction.
|
||||
Faction.prototype.addAllAugmentations = function() {
|
||||
this.augmentations.length = 0;
|
||||
for (var name in Augmentations) {
|
||||
if (Augmentations.hasOwnProperty(name)) {
|
||||
this.augmentations.push(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Faction.prototype.toJSON = function() {
|
||||
return Generic_toJSON("Faction", this);
|
||||
}
|
||||
|
||||
Faction.fromJSON = function(value) {
|
||||
return Generic_fromJSON(Faction, value.data);
|
||||
}
|
||||
|
||||
Reviver.constructors.Faction = Faction;
|
||||
|
||||
//Map of factions indexed by faction name
|
||||
let Factions = {}
|
||||
|
||||
function loadFactions(saveString) {
|
||||
Factions = JSON.parse(saveString, Reviver);
|
||||
}
|
||||
|
||||
function AddToFactions(faction) {
|
||||
var name = faction.name;
|
||||
Factions[name] = faction;
|
||||
}
|
||||
|
||||
function factionExists(name) {
|
||||
return Factions.hasOwnProperty(name);
|
||||
}
|
||||
|
||||
//TODO Augmentation price and rep requirement mult are 1 for everything right now,
|
||||
// This might change in the future for balance
|
||||
function initFactions() {
|
||||
for(const name in FactionInfos) {
|
||||
resetFaction(new Faction(name));
|
||||
}
|
||||
}
|
||||
|
||||
//Resets a faction during (re-)initialization. Saves the favor in the new
|
||||
//Faction object and deletes the old Faction Object from "Factions". Then
|
||||
//reinserts the new Faction object
|
||||
function resetFaction(newFactionObject) {
|
||||
if (!(newFactionObject instanceof Faction)) {
|
||||
throw new Error("Invalid argument 'newFactionObject' passed into resetFaction()");
|
||||
}
|
||||
var factionName = newFactionObject.name;
|
||||
if (factionExists(factionName)) {
|
||||
newFactionObject.favor = Factions[factionName].favor;
|
||||
delete Factions[factionName];
|
||||
}
|
||||
AddToFactions(newFactionObject);
|
||||
}
|
||||
yesNoBoxGetNoButton, yesNoBoxClose} from "../../utils/YesNoBox";
|
||||
|
||||
function inviteToFaction(faction) {
|
||||
if (Settings.SuppressFactionInvites) {
|
||||
@ -783,6 +670,6 @@ function processPassiveFactionRepGain(numCycles) {
|
||||
}
|
||||
}
|
||||
|
||||
export {getNextNeurofluxLevel, Factions, initFactions, inviteToFaction,
|
||||
export {getNextNeurofluxLevel, inviteToFaction,
|
||||
joinFaction, displayFactionContent, processPassiveFactionRepGain,
|
||||
loadFactions, Faction, purchaseAugmentation, factionExists};
|
||||
purchaseAugmentation};
|
@ -1,9 +1,9 @@
|
||||
import { IMap } from "./types";
|
||||
import { IMap } from "../types";
|
||||
|
||||
/**
|
||||
* Contains the "information" property for all the Factions, which is just a description of each faction
|
||||
*/
|
||||
class FactionInfo {
|
||||
export class FactionInfo {
|
||||
/**
|
||||
* The multiplier to apply to augmentation base purchase price.
|
||||
*/
|
6
src/Faction/FactionWorkTypeEnum.ts
Normal file
6
src/Faction/FactionWorkTypeEnum.ts
Normal file
@ -0,0 +1,6 @@
|
||||
export enum FactionWorkType {
|
||||
Field,
|
||||
Hacking,
|
||||
None,
|
||||
Security,
|
||||
}
|
47
src/Faction/Factions.ts
Normal file
47
src/Faction/Factions.ts
Normal file
@ -0,0 +1,47 @@
|
||||
/**
|
||||
* Initialization and manipulation of the Factions object, which stores data
|
||||
* about all Factions in the game
|
||||
*/
|
||||
import { Faction } from "./Faction";
|
||||
import { FactionInfos } from "./FactionInfo";
|
||||
|
||||
import { IMap } from "../types";
|
||||
|
||||
import { Reviver } from "../../utils/JSONReviver";
|
||||
|
||||
|
||||
export let Factions: IMap<Faction> = {};
|
||||
|
||||
export function loadFactions(saveString: string): void {
|
||||
Factions = JSON.parse(saveString, Reviver);
|
||||
}
|
||||
|
||||
export function AddToFactions(faction: Faction) {
|
||||
const name: string = faction.name;
|
||||
Factions[name] = faction;
|
||||
}
|
||||
|
||||
export function factionExists(name: string): boolean {
|
||||
return Factions.hasOwnProperty(name);
|
||||
}
|
||||
|
||||
export function initFactions(bitNode: number=1) {
|
||||
for (const name in FactionInfos) {
|
||||
resetFaction(new Faction(name));
|
||||
}
|
||||
}
|
||||
|
||||
//Resets a faction during (re-)initialization. Saves the favor in the new
|
||||
//Faction object and deletes the old Faction Object from "Factions". Then
|
||||
//reinserts the new Faction object
|
||||
export function resetFaction(newFactionObject: Faction) {
|
||||
if (!(newFactionObject instanceof Faction)) {
|
||||
throw new Error("Invalid argument 'newFactionObject' passed into resetFaction()");
|
||||
}
|
||||
const factionName: string = newFactionObject.name;
|
||||
if (factionExists(factionName)) {
|
||||
newFactionObject.favor = Factions[factionName].favor;
|
||||
delete Factions[factionName];
|
||||
}
|
||||
AddToFactions(newFactionObject);
|
||||
}
|
1
src/Faction/README.md
Normal file
1
src/Faction/README.md
Normal file
@ -0,0 +1 @@
|
||||
Implementation of Faction-related mechanics
|
57
src/Gang.js
57
src/Gang.js
@ -3,32 +3,39 @@ Also add police clashes
|
||||
balance point to keep them from running out of control
|
||||
*/
|
||||
|
||||
import {gangMemberTasksMetadata} from "./data/gangmembertasks";
|
||||
import {gangMemberUpgradesMetadata} from "./data/gangmemberupgrades";
|
||||
import { gangMemberTasksMetadata } from "./data/gangmembertasks";
|
||||
import { gangMemberUpgradesMetadata } from "./data/gangmemberupgrades";
|
||||
|
||||
import {Engine} from "./engine";
|
||||
import {Faction, Factions,
|
||||
displayFactionContent} from "./Faction";
|
||||
import {numeralWrapper} from "./ui/numeralFormat";
|
||||
import {dialogBoxCreate} from "../utils/DialogBox";
|
||||
import {Reviver, Generic_toJSON,
|
||||
Generic_fromJSON} from "../utils/JSONReviver";
|
||||
import {KEY} from "../utils/helpers/keyCodes";
|
||||
import {createAccordionElement} from "../utils/uiHelpers/createAccordionElement";
|
||||
import {createElement} from "../utils/uiHelpers/createElement";
|
||||
import {createPopup} from "../utils/uiHelpers/createPopup";
|
||||
import {Page, routing} from "./ui/navigationTracking";
|
||||
import {formatNumber} from "../utils/StringHelperFunctions";
|
||||
import {exceptionAlert} from "../utils/helpers/exceptionAlert";
|
||||
import {getRandomInt} from "../utils/helpers/getRandomInt";
|
||||
import {removeChildrenFromElement} from "../utils/uiHelpers/removeChildrenFromElement";
|
||||
import {removeElement} from "../utils/uiHelpers/removeElement";
|
||||
import {removeElementById} from "../utils/uiHelpers/removeElementById";
|
||||
import {yesNoBoxCreate, yesNoTxtInpBoxCreate,
|
||||
yesNoBoxGetYesButton, yesNoBoxGetNoButton,
|
||||
yesNoTxtInpBoxGetYesButton, yesNoTxtInpBoxGetNoButton,
|
||||
yesNoTxtInpBoxGetInput, yesNoBoxClose,
|
||||
yesNoTxtInpBoxClose, yesNoBoxOpen} from "../utils/YesNoBox";
|
||||
import { Engine } from "./engine";
|
||||
import { Faction } from "./Faction/Faction";
|
||||
import { Factions } from "./Faction/Factions";
|
||||
import { displayFactionContent } from "./Faction/FactionHelpers";
|
||||
import { numeralWrapper } from "./ui/numeralFormat";
|
||||
import { dialogBoxCreate } from "../utils/DialogBox";
|
||||
import { Reviver, Generic_toJSON,
|
||||
Generic_fromJSON } from "../utils/JSONReviver";
|
||||
import { KEY } from "../utils/helpers/keyCodes";
|
||||
import { createAccordionElement } from "../utils/uiHelpers/createAccordionElement";
|
||||
import { createElement } from "../utils/uiHelpers/createElement";
|
||||
import { createPopup } from "../utils/uiHelpers/createPopup";
|
||||
import { Page,
|
||||
routing } from "./ui/navigationTracking";
|
||||
import { formatNumber } from "../utils/StringHelperFunctions";
|
||||
import { exceptionAlert } from "../utils/helpers/exceptionAlert";
|
||||
import { getRandomInt } from "../utils/helpers/getRandomInt";
|
||||
import { removeChildrenFromElement } from "../utils/uiHelpers/removeChildrenFromElement";
|
||||
import { removeElement } from "../utils/uiHelpers/removeElement";
|
||||
import { removeElementById } from "../utils/uiHelpers/removeElementById";
|
||||
import { yesNoBoxCreate,
|
||||
yesNoTxtInpBoxCreate,
|
||||
yesNoBoxGetYesButton,
|
||||
yesNoBoxGetNoButton,
|
||||
yesNoTxtInpBoxGetYesButton,
|
||||
yesNoTxtInpBoxGetNoButton,
|
||||
yesNoTxtInpBoxGetInput,
|
||||
yesNoBoxClose,
|
||||
yesNoTxtInpBoxClose,
|
||||
yesNoBoxOpen } from "../utils/YesNoBox";
|
||||
|
||||
// Constants
|
||||
const GangRespectToReputationRatio = 5; // Respect is divided by this to get rep gain
|
||||
|
14
src/Locations/Cities.ts
Normal file
14
src/Locations/Cities.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { IMap } from "../types";
|
||||
|
||||
/**
|
||||
* Display Location Content when visiting somewhere in the World
|
||||
*/
|
||||
// tslint:disable-next-line:variable-name
|
||||
export const Cities: IMap<string> = {
|
||||
Aevum: "Aevum",
|
||||
Chongqing: "Chongqing",
|
||||
Ishima: "Ishima",
|
||||
NewTokyo: "New Tokyo",
|
||||
Sector12: "Sector-12",
|
||||
Volhaven: "Volhaven",
|
||||
};
|
@ -1,14 +1,14 @@
|
||||
import {CONSTANTS} from "./Constants";
|
||||
import {Engine} from "./engine";
|
||||
import {displayFactionContent} from "./Faction";
|
||||
import {Player} from "./Player";
|
||||
import {dialogBoxCreate} from "../utils/DialogBox";
|
||||
import {clearEventListeners} from "../utils/uiHelpers/clearEventListeners";
|
||||
import {addOffset} from "../utils/helpers/addOffset";
|
||||
import {formatNumber} from "../utils/StringHelperFunctions";
|
||||
import {getRandomInt} from "../utils/helpers/getRandomInt";
|
||||
import {isString} from "../utils/helpers/isString";
|
||||
import jsplumb from 'jsplumb'
|
||||
import { CONSTANTS } from "./Constants";
|
||||
import { Engine } from "./engine";
|
||||
import { displayFactionContent } from "./Faction/FactionHelpers";
|
||||
import { Player } from "./Player";
|
||||
import { dialogBoxCreate } from "../utils/DialogBox";
|
||||
import { clearEventListeners } from "../utils/uiHelpers/clearEventListeners";
|
||||
import { addOffset } from "../utils/helpers/addOffset";
|
||||
import { formatNumber } from "../utils/StringHelperFunctions";
|
||||
import { getRandomInt } from "../utils/helpers/getRandomInt";
|
||||
import { isString } from "../utils/helpers/isString";
|
||||
import jsplumb from 'jsplumb'
|
||||
|
||||
let inMission = false; //Flag to denote whether a mission is running
|
||||
let currMission = null;
|
||||
|
@ -22,9 +22,13 @@ import {calculateHackingChance,
|
||||
calculateGrowTime,
|
||||
calculateWeakenTime} from "./Hacking";
|
||||
import {AllGangs} from "./Gang";
|
||||
import {Factions, Faction, joinFaction,
|
||||
factionExists, purchaseAugmentation} from "./Faction";
|
||||
import {getCostOfNextHacknetNode, purchaseHacknet} from "./HacknetNode";
|
||||
import { Faction } from "./Faction/Faction";
|
||||
import { Factions,
|
||||
factionExists } from "./Faction/Factions";
|
||||
import { joinFaction,
|
||||
purchaseAugmentation } from "./Faction/FactionHelpers";
|
||||
import { getCostOfNextHacknetNode,
|
||||
purchaseHacknet } from "./HacknetNode";
|
||||
import {Locations} from "./Locations";
|
||||
import {Message, Messages} from "./Message";
|
||||
import {inMission} from "./Missions";
|
||||
|
268
src/PersonObjects/Person.ts
Normal file
268
src/PersonObjects/Person.ts
Normal file
@ -0,0 +1,268 @@
|
||||
// Base class representing a person-like object
|
||||
import { BitNodeMultipliers } from "../BitNodeMultipliers";
|
||||
import { Cities } from "../Locations/Cities";
|
||||
import { CONSTANTS } from "../Constants";
|
||||
|
||||
// Interface for an object that represents the player (PlayerObject)
|
||||
// Used because at the time of implementation, the PlayerObject
|
||||
// cant be converted to TypeScript.
|
||||
//
|
||||
// Only contains the needed properties for Sleeve implementation
|
||||
export interface IPlayer {
|
||||
companyName: string;
|
||||
factions: string[];
|
||||
money: any;
|
||||
gainHackingExp(exp: number): void;
|
||||
gainStrengthExp(exp: number): void;
|
||||
gainDefenseExp(exp: number): void;
|
||||
gainDexterityExp(exp: number): void;
|
||||
gainAgilityExp(exp: number): void;
|
||||
gainCharismaExp(exp: number): void;
|
||||
gainMoney(money: number): void;
|
||||
loseMoney(money: number): void;
|
||||
}
|
||||
|
||||
// Interface for a Crime object
|
||||
// Used because at the time of implementation, the Crime object has not been converted
|
||||
// to Typescript
|
||||
export interface ICrime {
|
||||
name: string;
|
||||
type: string;
|
||||
time: number;
|
||||
money: number;
|
||||
difficulty: number;
|
||||
karma: number;
|
||||
|
||||
hacking_success_weight: number;
|
||||
strength_success_weight: number;
|
||||
defense_success_weight: number;
|
||||
dexterity_success_weight: number;
|
||||
agility_success_weight: number;
|
||||
charisma_success_weight: number;
|
||||
|
||||
hacking_exp: number;
|
||||
strength_exp: number;
|
||||
defense_exp: number;
|
||||
dexterity_exp: number;
|
||||
agility_exp: number;
|
||||
charisma_exp: number;
|
||||
intelligence_exp: number;
|
||||
|
||||
kills: number;
|
||||
}
|
||||
|
||||
// Interface for Faction object
|
||||
// Used because at the time of implementation, the Faction object has not been
|
||||
// converted to TypeScript
|
||||
export interface IFaction {
|
||||
name: string;
|
||||
playerReputation: number;
|
||||
}
|
||||
|
||||
// Interface that defines a generic object used to track experience/money
|
||||
// earnings for tasks
|
||||
export interface ITaskTracker {
|
||||
hack: number;
|
||||
str: number;
|
||||
def: number;
|
||||
dex: number;
|
||||
agi: number;
|
||||
cha: number;
|
||||
money: number;
|
||||
}
|
||||
|
||||
export function createTaskTracker(): ITaskTracker {
|
||||
return {
|
||||
hack: 0,
|
||||
str: 0,
|
||||
def: 0,
|
||||
dex: 0,
|
||||
agi: 0,
|
||||
cha: 0,
|
||||
money: 0,
|
||||
}
|
||||
}
|
||||
|
||||
export abstract class Person {
|
||||
/**
|
||||
* Stats
|
||||
*/
|
||||
hacking_skill: number;
|
||||
strength: number;
|
||||
defense: number;
|
||||
dexterity: number;
|
||||
agility: number;
|
||||
charisma: number;
|
||||
hp: number;
|
||||
max_hp: number;
|
||||
|
||||
/**
|
||||
* Multipliers
|
||||
*/
|
||||
hacking_exp: number;
|
||||
strength_exp: number;
|
||||
defense_exp: number;
|
||||
dexterity_exp: number;
|
||||
agility_exp: number;
|
||||
charisma_exp: number;
|
||||
intelligence_exp: number;
|
||||
|
||||
hacking_mult: number;
|
||||
strength_mult: number;
|
||||
defense_mult: number;
|
||||
dexterity_mult: number;
|
||||
agility_mult: number;
|
||||
charisma_mult: number;
|
||||
|
||||
hacking_exp_mult: number;
|
||||
strength_exp_mult: number;
|
||||
defense_exp_mult: number;
|
||||
dexterity_exp_mult: number;
|
||||
agility_exp_mult: number;
|
||||
charisma_exp_mult: number;
|
||||
|
||||
company_rep_mult: number;
|
||||
faction_rep_mult: number;
|
||||
|
||||
crime_money_mult: number;
|
||||
crime_success_mult: number;
|
||||
|
||||
work_money_mult: number;
|
||||
|
||||
/**
|
||||
* City that the person is in
|
||||
*/
|
||||
city: string;
|
||||
|
||||
constructor() {
|
||||
this.hacking_skill = 1;
|
||||
this.strength = 1;
|
||||
this.defense = 1;
|
||||
this.dexterity = 1;
|
||||
this.agility = 1;
|
||||
this.charisma = 1;
|
||||
this.hp = 10;
|
||||
this.max_hp = 10;
|
||||
|
||||
// Multipliers
|
||||
this.hacking_exp = 0;
|
||||
this.strength_exp = 0;
|
||||
this.defense_exp = 0;
|
||||
this.dexterity_exp = 0;
|
||||
this.agility_exp = 0;
|
||||
this.charisma_exp = 0;
|
||||
this.intelligence_exp = 0;
|
||||
|
||||
this.hacking_mult = 1;
|
||||
this.strength_mult = 1;
|
||||
this.defense_mult = 1;
|
||||
this.dexterity_mult = 1;
|
||||
this.agility_mult = 1;
|
||||
this.charisma_mult = 1;
|
||||
|
||||
this.hacking_exp_mult = 1;
|
||||
this.strength_exp_mult = 1;
|
||||
this.defense_exp_mult = 1;
|
||||
this.dexterity_exp_mult = 1;
|
||||
this.agility_exp_mult = 1;
|
||||
this.charisma_exp_mult = 1;
|
||||
|
||||
this.company_rep_mult = 1;
|
||||
this.faction_rep_mult = 1;
|
||||
|
||||
this.crime_money_mult = 1;
|
||||
this.crime_success_mult = 1;
|
||||
|
||||
this.work_money_mult = 1;
|
||||
|
||||
this.city = Cities.Sector12;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an experience amount and stat multiplier, calculates the
|
||||
* stat level. Stat-agnostic (same formula for every stat)
|
||||
*/
|
||||
calculateStat(exp: number, mult: number=1): number {
|
||||
return Math.max(Math.floor(mult*(32 * Math.log(exp + 534.5) - 200)), 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate and return the amount of faction reputation earned per cycle
|
||||
* when doing Field Work for a faction
|
||||
*/
|
||||
getFactionFieldWorkRepGain(): number {
|
||||
const t = 0.9 * (this.hacking_skill / CONSTANTS.MaxSkillLevel +
|
||||
this.strength / CONSTANTS.MaxSkillLevel +
|
||||
this.defense / CONSTANTS.MaxSkillLevel +
|
||||
this.dexterity / CONSTANTS.MaxSkillLevel +
|
||||
this.agility / CONSTANTS.MaxSkillLevel +
|
||||
this.charisma / CONSTANTS.MaxSkillLevel) / 5.5;
|
||||
return t * this.faction_rep_mult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate and return the amount of faction reputation earned per cycle
|
||||
* when doing Hacking Work for a faction
|
||||
*/
|
||||
getFactionHackingWorkRepGain(): number {
|
||||
return this.hacking_skill / CONSTANTS.MaxSkillLevel * this.faction_rep_mult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate and return the amount of faction reputation earned per cycle
|
||||
* when doing Security Work for a faction
|
||||
*/
|
||||
getFactionSecurityWorkRepGain(): number {
|
||||
const t = 0.9 * (this.hacking_skill / CONSTANTS.MaxSkillLevel +
|
||||
this.strength / CONSTANTS.MaxSkillLevel +
|
||||
this.defense / CONSTANTS.MaxSkillLevel +
|
||||
this.dexterity / CONSTANTS.MaxSkillLevel +
|
||||
this.agility / CONSTANTS.MaxSkillLevel) / 4.5;
|
||||
return t * this.faction_rep_mult;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Reset all multipliers to 1
|
||||
*/
|
||||
resetMultipliers(): void {
|
||||
this.hacking_mult = 1;
|
||||
this.strength_mult = 1;
|
||||
this.defense_mult = 1;
|
||||
this.dexterity_mult = 1;
|
||||
this.agility_mult = 1;
|
||||
this.charisma_mult = 1;
|
||||
|
||||
this.hacking_exp_mult = 1;
|
||||
this.strength_exp_mult = 1;
|
||||
this.defense_exp_mult = 1;
|
||||
this.dexterity_exp_mult = 1;
|
||||
this.agility_exp_mult = 1;
|
||||
this.charisma_exp_mult = 1;
|
||||
|
||||
this.company_rep_mult = 1;
|
||||
this.faction_rep_mult = 1;
|
||||
|
||||
this.crime_money_mult = 1;
|
||||
this.crime_success_mult = 1;
|
||||
|
||||
this.work_money_mult = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update all stat levels
|
||||
*/
|
||||
updateStatLevels(): void {
|
||||
this.hacking_skill = Math.max(1, Math.floor(this.calculateStat(this.hacking_exp, this.hacking_mult * BitNodeMultipliers.HackingLevelMultiplier)));
|
||||
this.strength = Math.max(1, Math.floor(this.calculateStat(this.strength_exp, this.strength_mult)));
|
||||
this.defense = Math.max(1, Math.floor(this.calculateStat(this.defense_exp, this.defense_mult)));
|
||||
this.dexterity = Math.max(1, Math.floor(this.calculateStat(this.dexterity_exp, this.dexterity_mult)));
|
||||
this.agility = Math.max(1, Math.floor(this.calculateStat(this.agility_exp, this.agility_mult)));
|
||||
this.charisma = Math.max(1, Math.floor(this.calculateStat(this.charisma_exp, this.charisma_mult)));
|
||||
|
||||
const ratio: number = this.hp / this.max_hp;
|
||||
this.max_hp = Math.floor(10 + this.defense / 10);
|
||||
this.hp = Math.round(this.max_hp * ratio);
|
||||
}
|
||||
}
|
2
src/PersonObjects/README.md
Normal file
2
src/PersonObjects/README.md
Normal file
@ -0,0 +1,2 @@
|
||||
Implementation of all Person-type objects, including but not limited to
|
||||
the "PlayerObject" and Sleeves.
|
598
src/PersonObjects/Sleeve/Sleeve.ts
Normal file
598
src/PersonObjects/Sleeve/Sleeve.ts
Normal file
@ -0,0 +1,598 @@
|
||||
/**
|
||||
* Sleeves are clones of the player that can be used to perform
|
||||
* different tasks synchronously.
|
||||
*
|
||||
* Each sleeve is its own individual, meaning it has its own stats/exp
|
||||
*
|
||||
* Sleeves are unlocked in BitNode-10.
|
||||
*/
|
||||
import { SleeveTaskType } from "./SleeveTaskTypesEnum";
|
||||
|
||||
import { Person,
|
||||
IPlayer,
|
||||
ICrime,
|
||||
IFaction,
|
||||
ITaskTracker,
|
||||
createTaskTracker } from "../Person";
|
||||
|
||||
import { BitNodeMultipliers } from "../../BitNodeMultipliers";
|
||||
import { Cities } from "../../Locations/Cities";
|
||||
import { Companies } from "../../Company/Companies";
|
||||
import { Company } from "../../Company/Company";
|
||||
import { CONSTANTS } from "../../Constants";
|
||||
import { Faction } from "../../Faction/Faction";
|
||||
import { Factions } from "../../Faction/Factions";
|
||||
import { FactionWorkType } from "../../Faction/FactionWorkTypeEnum";
|
||||
import { Locations } from "../../Locations";
|
||||
|
||||
import { Generic_fromJSON, Generic_toJSON, Reviver } from "../../../utils/JSONReviver";
|
||||
|
||||
export class Sleeve extends Person {
|
||||
/**
|
||||
* Initiatizes a Sleeve object from a JSON save state.
|
||||
*/
|
||||
static fromJSON(value: any): Sleeve {
|
||||
return Generic_fromJSON(Sleeve, value.data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enum value for current task
|
||||
*/
|
||||
currentTask: SleeveTaskType = SleeveTaskType.Idle;
|
||||
|
||||
/**
|
||||
* Description of current task. Used only for logging purposes
|
||||
*/
|
||||
currentTaskDescription: string = "";
|
||||
|
||||
/**
|
||||
* For what company/faction the current task is assigned to.
|
||||
* Only applicable when working for faction or company, obviously
|
||||
*/
|
||||
currentTaskLocation: string = "";
|
||||
|
||||
/**
|
||||
* Maximum amount of time (in milliseconds) that can be spent on current task.
|
||||
*/
|
||||
currentTaskMaxTime: number = 0;
|
||||
|
||||
/**
|
||||
* Milliseconds spent on current task
|
||||
*/
|
||||
currentTaskTime: number = 0;
|
||||
|
||||
/**
|
||||
* Keeps track of experience earned for other sleeves
|
||||
*/
|
||||
earningsForSleeves: ITaskTracker = createTaskTracker();
|
||||
|
||||
/**
|
||||
* Keeps track of experience + money earned for player
|
||||
*/
|
||||
earningsForPlayer: ITaskTracker = createTaskTracker();
|
||||
|
||||
/**
|
||||
* Keeps track of experienced earned in the current task/action
|
||||
*/
|
||||
earningsForTask: ITaskTracker = createTaskTracker();
|
||||
|
||||
/**
|
||||
* Keeps track of what type of work sleeve is doing for faction, if applicable
|
||||
*/
|
||||
factionWorkType: FactionWorkType = FactionWorkType.None;
|
||||
|
||||
/**
|
||||
* Records experience gain rate for the current task
|
||||
*/
|
||||
gainRatesForTask: ITaskTracker = createTaskTracker();
|
||||
|
||||
/**
|
||||
* Keeps track of events/notifications for this sleeve
|
||||
*/
|
||||
logs: string[] = [];
|
||||
|
||||
/**
|
||||
* Clone retains memory% of exp upon prestige. If exp would be lower than previously
|
||||
* kept exp, nothing happens
|
||||
*/
|
||||
memory: number = 0;
|
||||
|
||||
/**
|
||||
* Sleeve shock. Number between 1 and 100
|
||||
* Trauma/shock that comes with being in a sleeve. Experience earned
|
||||
* is multipled by shock%. This gets applied before synchronization
|
||||
*/
|
||||
shock: number = 1;
|
||||
|
||||
/**
|
||||
* Stored number of game "loop" cycles
|
||||
*/
|
||||
storedCycles: number = 0;
|
||||
|
||||
/**
|
||||
* Synchronization. Number between 0 and 100
|
||||
* When experience is earned by sleeve, both the player and the sleeve get
|
||||
* sync% of the experience earned. Other sleeves get sync^2% of exp
|
||||
*/
|
||||
sync: number = 1;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
/*
|
||||
this.currentTask = SleeveTaskType.Idle;
|
||||
this.currentTaskDescription = "";
|
||||
this.currentTaskTime = 0;
|
||||
this.currentTaskMaxTime = 0;
|
||||
this.earningsForSleeves = createTaskTracker();
|
||||
this.earningsForPlayer = createTaskTracker();
|
||||
this.earningsForTask = createTaskTracker();
|
||||
this.gainRatesForTask = createTaskTracker();
|
||||
this.logs = [];
|
||||
this.memory = 0;
|
||||
this.shock = 1;
|
||||
this.storedCycles = 0;
|
||||
this.sync = 1;
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Commit crimes
|
||||
*/
|
||||
commitCrime(p: IPlayer, crime: ICrime): void {
|
||||
if (this.currentTask !== SleeveTaskType.Idle) {
|
||||
this.finishTask();
|
||||
} else {
|
||||
this.resetTaskStatus();
|
||||
}
|
||||
|
||||
this.gainRatesForTask.hack = crime.hacking_exp * this.hacking_exp_mult * BitNodeMultipliers.CrimeExpGain;
|
||||
this.gainRatesForTask.str = crime.strength_exp * this.strength_exp_mult * BitNodeMultipliers.CrimeExpGain;
|
||||
this.gainRatesForTask.def = crime.defense_exp * this.defense_exp_mult * BitNodeMultipliers.CrimeExpGain;
|
||||
this.gainRatesForTask.dex = crime.dexterity_exp * this.dexterity_exp_mult * BitNodeMultipliers.CrimeExpGain;
|
||||
this.gainRatesForTask.agi = crime.agility_exp * this.agility_exp_mult * BitNodeMultipliers.CrimeExpGain;
|
||||
this.gainRatesForTask.cha = crime.charisma_exp * this.charisma_exp_mult * BitNodeMultipliers.CrimeExpGain;
|
||||
|
||||
this.currentTaskMaxTime = crime.time;
|
||||
|
||||
this.currentTask = SleeveTaskType.Crime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to stop the current task
|
||||
*/
|
||||
finishTask(): void {
|
||||
if (this.currentTask === SleeveTaskType.Crime) {
|
||||
} else {
|
||||
|
||||
}
|
||||
|
||||
this.resetTaskStatus();
|
||||
}
|
||||
|
||||
/**
|
||||
* Earn experience for any stats (supports multiple)
|
||||
* This function also handles experience propogating to Player and other sleeves
|
||||
*/
|
||||
gainExperience(p: IPlayer, exp: ITaskTracker, numCycles: number=1): ITaskTracker {
|
||||
// Experience is first multiplied by shock. Then 'synchronization'
|
||||
// is accounted for
|
||||
const multFac = (this.shock / 100) * (this.sync / 100) * numCycles;
|
||||
const pHackExp = exp.hack * multFac;
|
||||
const pStrExp = exp.str * multFac;
|
||||
const pDefExp = exp.def * multFac;
|
||||
const pDexExp = exp.dex * multFac;
|
||||
const pAgiExp = exp.agi * multFac;
|
||||
const pChaExp = exp.cha * multFac;
|
||||
|
||||
// Experience is gained by both this sleeve and player
|
||||
if (pHackExp > 0) {
|
||||
this.hacking_exp += pHackExp;
|
||||
p.gainHackingExp(pHackExp);
|
||||
this.earningsForPlayer.hack += pHackExp;
|
||||
this.earningsForTask.hack += pHackExp;
|
||||
}
|
||||
|
||||
if (pStrExp > 0) {
|
||||
this.strength_exp += pStrExp;
|
||||
p.gainStrengthExp(pStrExp);
|
||||
this.earningsForPlayer.str += pStrExp;
|
||||
this.earningsForTask.str += pStrExp;
|
||||
}
|
||||
|
||||
if (pDefExp > 0) {
|
||||
this.defense_exp += pDefExp;
|
||||
p.gainDefenseExp(pDefExp);
|
||||
this.earningsForPlayer.def += pDefExp;
|
||||
this.earningsForTask.dex += pDefExp;
|
||||
}
|
||||
|
||||
if (pDexExp > 0) {
|
||||
this.dexterity_exp += pDexExp;
|
||||
p.gainDexterityExp(pDexExp);
|
||||
this.earningsForPlayer.dex += pDexExp;
|
||||
this.earningsForTask.dex += pDexExp;
|
||||
}
|
||||
|
||||
if (pAgiExp > 0) {
|
||||
this.agility_exp += pAgiExp;
|
||||
p.gainAgilityExp(pAgiExp);
|
||||
this.earningsForPlayer.agi += pAgiExp;
|
||||
this.earningsForTask.agi += pAgiExp;
|
||||
}
|
||||
|
||||
if (pChaExp > 0) {
|
||||
this.charisma_exp += pChaExp;
|
||||
p.gainCharismaExp(pChaExp);
|
||||
this.earningsForPlayer.cha += pChaExp;
|
||||
this.earningsForTask.cha += pChaExp;
|
||||
}
|
||||
|
||||
// Record earnings for other sleeves
|
||||
this.earningsForSleeves.hack += (pHackExp * (this.sync / 100));
|
||||
this.earningsForSleeves.str += (pStrExp * (this.sync / 100));
|
||||
this.earningsForSleeves.def += (pDefExp * (this.sync / 100));
|
||||
this.earningsForSleeves.dex += (pDexExp * (this.sync / 100));
|
||||
this.earningsForSleeves.agi += (pAgiExp * (this.sync / 100));
|
||||
this.earningsForSleeves.cha += (pChaExp * (this.sync / 100));
|
||||
|
||||
// Return the experience to be gained by other sleeves
|
||||
return {
|
||||
hack: pHackExp * (this.sync / 100),
|
||||
str: pStrExp * (this.sync / 100),
|
||||
def: pDefExp * (this.sync / 100),
|
||||
dex: pDexExp * (this.sync / 100),
|
||||
agi: pAgiExp * (this.sync / 100),
|
||||
cha: pChaExp * (this.sync / 100),
|
||||
money: 0,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Earn money for player
|
||||
*/
|
||||
gainMoney(p: IPlayer, task: ITaskTracker, numCycles: number=1): void {
|
||||
p.gainMoney(task.money * numCycles);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets reputation gain for the current task
|
||||
* Only applicable when working for company or faction
|
||||
*/
|
||||
getRepGain(): number {
|
||||
if (this.currentTask === SleeveTaskType.Faction) {
|
||||
switch (this.factionWorkType) {
|
||||
case FactionWorkType.Hacking:
|
||||
return this.getFactionHackingWorkRepGain();
|
||||
case FactionWorkType.Field:
|
||||
return this.getFactionFieldWorkRepGain();
|
||||
case FactionWorkType.Security:
|
||||
return this.getFactionSecurityWorkRepGain();
|
||||
default:
|
||||
console.warn(`Invalid Sleeve.factionWorkType property in Sleeve.getRepGain(): ${this.factionWorkType}`);
|
||||
return 0;
|
||||
}
|
||||
} else if (this.currentTask === SleeveTaskType.Company) {
|
||||
return 0;
|
||||
} else {
|
||||
console.warn(`Sleeve.getRepGain() called for invalid task type: ${this.currentTask}`);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
log(entry: string): void {
|
||||
const MaxLogSize: number = 50;
|
||||
this.logs.push(entry);
|
||||
if (this.logs.length > MaxLogSize) {
|
||||
this.logs.shift();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process loop
|
||||
* Returns an object containing the amount of experience that should be
|
||||
* transferred to all other sleeves
|
||||
*/
|
||||
process(p: IPlayer, numCycles: number=1): ITaskTracker | null {
|
||||
// Only process once every second (5 cycles)
|
||||
const CyclesPerSecond = 1000 / CONSTANTS.MilliPerCycle;
|
||||
this.storedCycles += numCycles;
|
||||
if (this.storedCycles < CyclesPerSecond) { return null; }
|
||||
|
||||
// Shock gradually goes towards 100
|
||||
this.shock = Math.max(100, this.shock + (0.0001 * this.storedCycles));
|
||||
|
||||
if (this.currentTask === SleeveTaskType.Idle) { return null; }
|
||||
|
||||
let time = this.storedCycles * CONSTANTS.MilliPerCycle;
|
||||
let cyclesUsed = this.storedCycles;
|
||||
if (this.currentTaskTime + time > this.currentTaskMaxTime) {
|
||||
time = this.currentTaskMaxTime - this.currentTaskTime;
|
||||
cyclesUsed = Math.floor(time / CONSTANTS.MilliPerCycle);
|
||||
|
||||
if (time < 0 || cyclesUsed < 0) {
|
||||
console.warn(`Sleeve.process() calculated negative cycle usage`);
|
||||
time = 0;
|
||||
cyclesUsed = 0;
|
||||
}
|
||||
}
|
||||
this.currentTaskTime += time;
|
||||
|
||||
let retValue: ITaskTracker = createTaskTracker();
|
||||
switch (this.currentTask) {
|
||||
case SleeveTaskType.Class:
|
||||
retValue = this.gainExperience(p, this.gainRatesForTask, cyclesUsed);
|
||||
this.gainMoney(p, this.gainRatesForTask, cyclesUsed);
|
||||
break;
|
||||
case SleeveTaskType.Faction:
|
||||
retValue = this.gainExperience(p, this.gainRatesForTask, cyclesUsed);
|
||||
this.gainMoney(p, this.gainRatesForTask, cyclesUsed);
|
||||
|
||||
// TODO REP for both this and company
|
||||
const fac = Factions[this.currentTaskLocation];
|
||||
if (!(fac instanceof Faction)) {
|
||||
console.error(`Invalid faction for Sleeve task: ${this.currentTaskLocation}`);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SleeveTaskType.Company:
|
||||
retValue = this.gainExperience(p, this.gainRatesForTask, cyclesUsed);
|
||||
this.gainMoney(p, this.gainRatesForTask, cyclesUsed);
|
||||
break;
|
||||
case SleeveTaskType.Recovery:
|
||||
this.shock = Math.max(100, this.shock + (0.001 * this.storedCycles));
|
||||
break;
|
||||
case SleeveTaskType.Sync:
|
||||
this.sync = Math.max(100, this.sync + (0.001 * this.storedCycles));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (this.currentTaskMaxTime !== 0 && this.currentTaskTime >= this.currentTaskMaxTime) {
|
||||
this.finishTask();
|
||||
}
|
||||
|
||||
this.storedCycles -= cyclesUsed;
|
||||
|
||||
// TODO Finish this
|
||||
return retValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets all parameters used to keep information about the current task
|
||||
*/
|
||||
resetTaskStatus(): void {
|
||||
this.earningsForTask = createTaskTracker();
|
||||
this.gainRatesForTask = createTaskTracker();
|
||||
this.currentTask = SleeveTaskType.Idle;
|
||||
this.currentTaskTime = 0;
|
||||
this.currentTaskMaxTime = 0;
|
||||
this.factionWorkType = FactionWorkType.None;
|
||||
}
|
||||
|
||||
/**
|
||||
* Take a course at a university
|
||||
*/
|
||||
takeUniversityCourse(p: IPlayer, universityName: string, className: string): boolean {
|
||||
if (this.currentTask !== SleeveTaskType.Idle) {
|
||||
this.finishTask();
|
||||
} else {
|
||||
this.resetTaskStatus();
|
||||
}
|
||||
|
||||
// Set exp/money multipliers based on which university.
|
||||
// Also check that the sleeve is in the right city
|
||||
let costMult: number = 1;
|
||||
let expMult: number = 1;
|
||||
switch (universityName.toLowerCase()) {
|
||||
case Locations.AevumSummitUniversity.toLowerCase():
|
||||
if (this.city !== Cities.Aevum) { return false; }
|
||||
costMult = 4;
|
||||
expMult = 3;
|
||||
break;
|
||||
case Locations.Sector12RothmanUniversity.toLowerCase():
|
||||
if (this.city !== Cities.Sector12) { return false; }
|
||||
costMult = 3;
|
||||
expMult = 2;
|
||||
break;
|
||||
case Locations.VolhavenZBInstituteOfTechnology.toLowerCase():
|
||||
if (this.city !== Cities.Volhaven) { return false; }
|
||||
costMult = 5;
|
||||
expMult = 4;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
// Number of game cycles in a second
|
||||
const cps: number = 1000 / CONSTANTS.MilliPerCycle;
|
||||
|
||||
// Set experience/money gains based on class
|
||||
// TODO Refactor University Courses into its own class or something
|
||||
const baseStudyComputerScienceExp: number = 0.5;
|
||||
const baseDataStructuresExp: number = 1;
|
||||
const baseNetworksExp: number = 2;
|
||||
const baseAlgorithmsExp: number = 4;
|
||||
const baseManagementExp: number = 2;
|
||||
const baseLeadershipExp: number = 4;
|
||||
|
||||
switch (className.toLowerCase()) {
|
||||
case "study computer science":
|
||||
this.gainRatesForTask.hack = (baseStudyComputerScienceExp * expMult * this.hacking_exp_mult);
|
||||
break;
|
||||
case "data structures":
|
||||
this.gainRatesForTask.hack = (baseDataStructuresExp * expMult * this.hacking_exp_mult);
|
||||
this.gainRatesForTask.money = -1 * (CONSTANTS.ClassDataStructuresBaseCost * costMult);
|
||||
break;
|
||||
case "networks":
|
||||
this.gainRatesForTask.hack = (baseNetworksExp * expMult * this.hacking_exp_mult);
|
||||
this.gainRatesForTask.money = -1 * (CONSTANTS.ClassNetworksBaseCost * costMult);
|
||||
break;
|
||||
case "algorithms":
|
||||
this.gainRatesForTask.hack = (baseAlgorithmsExp * expMult * this.hacking_exp_mult);
|
||||
this.gainRatesForTask.money = -1 * (CONSTANTS.ClassAlgorithmsBaseCost * costMult);
|
||||
break;
|
||||
case "management":
|
||||
this.gainRatesForTask.cha = (baseManagementExp * expMult * this.charisma_exp_mult);
|
||||
this.gainRatesForTask.money = -1 * (CONSTANTS.ClassManagementBaseCost * costMult);
|
||||
break;
|
||||
case "leadership":
|
||||
this.gainRatesForTask.cha = (baseLeadershipExp * expMult * this.charisma_exp_mult);
|
||||
this.gainRatesForTask.money = -1 * (CONSTANTS.ClassLeadershipBaseCost * costMult);
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
this.currentTask = SleeveTaskType.Class;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Travel to another City. Costs money from player
|
||||
*/
|
||||
travel(p: IPlayer, newCity: string): boolean {
|
||||
if (Cities[newCity] == null) {
|
||||
console.error(`Invalid city ${newCity} passed into Sleeve.travel()`);
|
||||
return false;
|
||||
}
|
||||
|
||||
p.loseMoney(CONSTANTS.TravelCost);
|
||||
this.city = newCity;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Work for a company
|
||||
*/
|
||||
workForCompany(p: IPlayer): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Work for one of the player's factions
|
||||
*/
|
||||
workForFaction(p: IPlayer, factionName: string, workType: string): boolean {
|
||||
if (!(Factions[factionName] instanceof Faction) || !p.factions.includes(factionName)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.currentTask !== SleeveTaskType.Idle) {
|
||||
this.finishTask();
|
||||
} else {
|
||||
this.resetTaskStatus();
|
||||
}
|
||||
|
||||
// Set type of work (hacking/field/security), and the experience gains
|
||||
const sanitizedWorkType: string = workType.toLowerCase();
|
||||
if (sanitizedWorkType.includes("hack")) {
|
||||
this.factionWorkType = FactionWorkType.Hacking;
|
||||
this.gainRatesForTask.hack = .15 * this.hacking_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
|
||||
} else if (sanitizedWorkType.includes("field")) {
|
||||
this.factionWorkType = FactionWorkType.Field;
|
||||
this.gainRatesForTask.hack = .1 * this.hacking_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
|
||||
this.gainRatesForTask.str = .1 * this.strength_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
|
||||
this.gainRatesForTask.def = .1 * this.defense_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
|
||||
this.gainRatesForTask.dex = .1 * this.dexterity_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
|
||||
this.gainRatesForTask.agi = .1 * this.agility_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
|
||||
this.gainRatesForTask.cha = .1 * this.charisma_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
|
||||
} else if (sanitizedWorkType.includes("security")) {
|
||||
this.factionWorkType = FactionWorkType.Security;
|
||||
this.gainRatesForTask.hack = .1 * this.hacking_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
|
||||
this.gainRatesForTask.str = .15 * this.strength_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
|
||||
this.gainRatesForTask.def = .15 * this.defense_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
|
||||
this.gainRatesForTask.dex = .15 * this.dexterity_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
|
||||
this.gainRatesForTask.agi = .15 * this.agility_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.currentTaskLocation = factionName;
|
||||
this.currentTask = SleeveTaskType.Faction;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Begin a gym workout task
|
||||
*/
|
||||
workoutAtGym(p: IPlayer, gymName: string, stat: string): boolean {
|
||||
if (this.currentTask !== SleeveTaskType.Idle) {
|
||||
this.finishTask();
|
||||
} else {
|
||||
this.resetTaskStatus();
|
||||
}
|
||||
|
||||
// Set exp/money multipliers based on which university.
|
||||
// Also check that the sleeve is in the right city
|
||||
let costMult: number = 1;
|
||||
let expMult: number = 1;
|
||||
switch (gymName.toLowerCase()) {
|
||||
case Locations.AevumCrushFitnessGym.toLowerCase():
|
||||
if (this.city != Cities.Aevum) { return false; }
|
||||
costMult = 3;
|
||||
expMult = 2;
|
||||
break;
|
||||
case Locations.AevumSnapFitnessGym.toLowerCase():
|
||||
if (this.city != Cities.Aevum) { return false; }
|
||||
costMult = 10;
|
||||
expMult = 5;
|
||||
break;
|
||||
case Locations.Sector12IronGym.toLowerCase():
|
||||
if (this.city != Cities.Sector12) { return false; }
|
||||
costMult = 1;
|
||||
expMult = 1;
|
||||
break;
|
||||
case Locations.Sector12PowerhouseGym.toLowerCase():
|
||||
if (this.city != Cities.Sector12) { return false; }
|
||||
costMult = 20;
|
||||
expMult = 10;
|
||||
break;
|
||||
case Locations.VolhavenMilleniumFitnessGym:
|
||||
if (this.city != Cities.Volhaven) { return false; }
|
||||
costMult = 7;
|
||||
expMult = 4;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
// Number of game cycles in a second
|
||||
const cps = 1000 / CONSTANTS.MilliPerCycle;
|
||||
|
||||
// Set experience/money gains based on class
|
||||
// TODO Refactor University Courses into its own class or something
|
||||
const baseGymExp: number = 1;
|
||||
const sanitizedStat: string = stat.toLowerCase();
|
||||
|
||||
// Set cost
|
||||
this.gainRatesForTask.money = -1 * (CONSTANTS.ClassGymBaseCost * costMult);
|
||||
|
||||
// Set stat gain rate
|
||||
if (sanitizedStat.includes("str")) {
|
||||
this.gainRatesForTask.str = (baseGymExp * expMult);
|
||||
} else if (sanitizedStat.includes("def")) {
|
||||
this.gainRatesForTask.def = (baseGymExp * expMult);
|
||||
} else if (sanitizedStat.includes("dex")) {
|
||||
this.gainRatesForTask.dex = (baseGymExp * expMult);
|
||||
} else if (sanitizedStat.includes("agi")) {
|
||||
this.gainRatesForTask.agi = (baseGymExp * expMult);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.currentTask = SleeveTaskType.Class;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize the current object to a JSON save state.
|
||||
*/
|
||||
toJSON(): any {
|
||||
return Generic_toJSON("Sleeve", this);
|
||||
}
|
||||
}
|
||||
|
||||
Reviver.constructors.Sleeve = Sleeve;
|
12
src/PersonObjects/Sleeve/SleeveTaskTypesEnum.ts
Normal file
12
src/PersonObjects/Sleeve/SleeveTaskTypesEnum.ts
Normal file
@ -0,0 +1,12 @@
|
||||
/**
|
||||
* Enum for different types of tasks that a Sleeve can perform
|
||||
*/
|
||||
export enum SleeveTaskType {
|
||||
Class,
|
||||
Company,
|
||||
Crime,
|
||||
Faction,
|
||||
Idle,
|
||||
Recovery,
|
||||
Sync,
|
||||
}
|
@ -14,8 +14,9 @@ import {Corporation} from "./CompanyManagement";
|
||||
import {Programs} from "./CreateProgram";
|
||||
import {determineCrimeSuccess, Crimes} from "./Crimes";
|
||||
import {Engine} from "./engine";
|
||||
import {Factions, Faction,
|
||||
displayFactionContent} from "./Faction";
|
||||
import { Faction } from "./Faction/Faction";
|
||||
import { Factions } from "./Faction/Factions";
|
||||
import { displayFactionContent } from "./Faction/FactionHelpers";
|
||||
import {Gang, resetGangs} from "./Gang";
|
||||
import {Locations} from "./Locations";
|
||||
import {hasBn11SF, hasWallStreetSF,hasAISF} from "./NetscriptFunctions";
|
||||
@ -41,10 +42,10 @@ function PlayerObject() {
|
||||
//Combat stats
|
||||
this.hp = 10;
|
||||
this.max_hp = 10;
|
||||
this.strength = 1; //Damage dealt
|
||||
this.defense = 1; //Damage received
|
||||
this.dexterity = 1; //Accuracy
|
||||
this.agility = 1; //Dodge %
|
||||
this.strength = 1;
|
||||
this.defense = 1;
|
||||
this.dexterity = 1;
|
||||
this.agility = 1;
|
||||
|
||||
//Labor stats
|
||||
this.charisma = 1;
|
||||
@ -594,7 +595,7 @@ PlayerObject.prototype.gainIntelligenceExp = function(exp) {
|
||||
|
||||
//Given a string expression like "str" or "strength", returns the given stat
|
||||
PlayerObject.prototype.queryStatFromString = function(str) {
|
||||
var tempStr = str.toLowerCase();
|
||||
const tempStr = str.toLowerCase();
|
||||
if (tempStr.includes("hack")) {return Player.hacking_skill;}
|
||||
if (tempStr.includes("str")) {return Player.strength;}
|
||||
if (tempStr.includes("def")) {return Player.defense;}
|
||||
|
@ -7,8 +7,10 @@ import {writeCinematicText} from "./CinematicText";
|
||||
import {Companies, initCompanies} from "./Company/Companies";
|
||||
import {Programs} from "./CreateProgram";
|
||||
import {Engine} from "./engine";
|
||||
import {Factions, Faction, initFactions,
|
||||
joinFaction} from "./Faction";
|
||||
import { Faction } from "./Faction/Faction";
|
||||
import { Factions,
|
||||
initFactions } from "./Faction/Factions";
|
||||
import { joinFaction } from "./Faction/FactionHelpers";
|
||||
import {deleteGangDisplayContent} from "./Gang";
|
||||
import {Locations} from "./Location";
|
||||
import {initMessages, Messages, Message} from "./Message";
|
||||
|
@ -4,8 +4,9 @@ import {Companies, loadCompanies} from "./Company/Companies";
|
||||
import {CompanyPosition} from "./Company/CompanyPosition";
|
||||
import {CONSTANTS} from "./Constants";
|
||||
import {Engine} from "./engine";
|
||||
import {loadFactions, Factions,
|
||||
processPassiveFactionRepGain} from "./Faction";
|
||||
import { Factions,
|
||||
loadFactions } from "./Faction/Factions";
|
||||
import { processPassiveFactionRepGain } from "./Faction/FactionHelpers";
|
||||
import {FconfSettings, loadFconf} from "./Fconf";
|
||||
import {loadAllGangs, AllGangs} from "./Gang";
|
||||
import {processAllHacknetNodeEarnings} from "./HacknetNode";
|
||||
|
@ -34,9 +34,10 @@ import {displayCreateProgramContent,
|
||||
initCreateProgramButtons,
|
||||
Programs} from "./CreateProgram";
|
||||
import {createDevMenu, closeDevMenu} from "./DevMenu";
|
||||
import {displayFactionContent, joinFaction,
|
||||
processPassiveFactionRepGain, Factions,
|
||||
inviteToFaction, initFactions} from "./Faction";
|
||||
import { Factions, initFactions } from "./Faction/Factions";
|
||||
import { displayFactionContent, joinFaction,
|
||||
processPassiveFactionRepGain,
|
||||
inviteToFaction } from "./Faction/FactionHelpers";
|
||||
import {FconfSettings} from "./Fconf";
|
||||
import {displayLocationContent,
|
||||
initLocationButtons} from "./Location";
|
||||
|
@ -1,4 +1,4 @@
|
||||
import {joinFaction} from "../src/Faction";
|
||||
import {joinFaction} from "../src/Faction/FactionHelpers";
|
||||
import {Engine} from "../src/engine";
|
||||
import {Player} from "../src/Player";
|
||||
import {clearEventListeners} from "./uiHelpers/clearEventListeners";
|
||||
|
@ -1,10 +1,11 @@
|
||||
import {BitNodeMultipliers} from "../src/BitNodeMultipliers";
|
||||
import {CONSTANTS} from "../src/Constants";
|
||||
import {Factions, Faction} from "../src/Faction";
|
||||
import {Player} from "../src/Player";
|
||||
import {dialogBoxCreate} from "./DialogBox";
|
||||
import {clearEventListeners} from "./uiHelpers/clearEventListeners";
|
||||
import {formatNumber} from "./StringHelperFunctions";
|
||||
import { BitNodeMultipliers } from "../src/BitNodeMultipliers";
|
||||
import { CONSTANTS } from "../src/Constants";
|
||||
import { Faction } from "../src/Faction/Faction";
|
||||
import { Factions } from "../src/Faction/Factions";
|
||||
import { Player } from "../src/Player";
|
||||
import { dialogBoxCreate } from "./DialogBox";
|
||||
import { clearEventListeners } from "./uiHelpers/clearEventListeners";
|
||||
import { formatNumber } from "./StringHelperFunctions";
|
||||
|
||||
//Keep track of last faction
|
||||
var lastFac = "";
|
||||
|
Loading…
Reference in New Issue
Block a user