mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-12-23 22:52:29 +01:00
commit
27d5b74744
@ -288,30 +288,44 @@
|
||||
}
|
||||
|
||||
#hacknet-nodes-text,
|
||||
#hacknet-nodes-money,
|
||||
#hacknet-nodes-container li {
|
||||
width: 70%;
|
||||
margin: 10px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
#hacknet-nodes-purchase-button {
|
||||
display: inline-block;
|
||||
#hacknet-nodes-container li {
|
||||
float: left;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
#hacknet-nodes-list {
|
||||
list-style: none;
|
||||
width: 82vw;
|
||||
}
|
||||
|
||||
#hacknet-nodes-money {
|
||||
margin: 10px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
#hacknet-nodes-money-multipliers-div {
|
||||
display: inline-block;
|
||||
width: 70%;
|
||||
width: 70vw;
|
||||
}
|
||||
|
||||
#hacknet-nodes-multipliers {
|
||||
float: right;
|
||||
}
|
||||
|
||||
#hacknet-nodes-purchase-button {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.hacknet-node {
|
||||
margin: 6px;
|
||||
padding: 6px;
|
||||
width: 85%;
|
||||
width: 34vw;
|
||||
border: 2px solid var(--my-highlight-color);
|
||||
-webkit-box-shadow:
|
||||
inset 0 0 8px rgba(0,0,0,0.1),
|
||||
@ -324,12 +338,28 @@
|
||||
0 0 16px rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
.hacknet-node-button-div a {
|
||||
display: block;
|
||||
.hacknet-node-container {
|
||||
display: inline-table;
|
||||
}
|
||||
|
||||
.hacknet-node-button-div:not(:last-child) {
|
||||
border-bottom: none;
|
||||
.hacknet-node-container .row {
|
||||
display: table-row;
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
.hacknet-node-container .row p {
|
||||
display: table-cell;
|
||||
}
|
||||
|
||||
.hacknet-node-container .upgradable-info {
|
||||
display: inline-block;
|
||||
margin: 0 4px; /* Don't want the vertical margin/padding, just left & right */
|
||||
padding: 0 4px;
|
||||
width: 48px; /* Four times font-size */
|
||||
}
|
||||
|
||||
.menu-page-text {
|
||||
width: 70vw;
|
||||
}
|
||||
|
||||
/* World */
|
||||
|
@ -15,7 +15,10 @@ body {
|
||||
background-color: var(--my-background-color);
|
||||
}
|
||||
|
||||
p, pre, h2 {
|
||||
p,
|
||||
pre,
|
||||
h2,
|
||||
.text {
|
||||
color: var(--my-font-color);
|
||||
}
|
||||
|
||||
|
11991
dist/engine.bundle.js
vendored
11991
dist/engine.bundle.js
vendored
File diff suppressed because it is too large
Load Diff
12
index.html
12
index.html
@ -23,7 +23,6 @@
|
||||
|
||||
ga('create', 'UA-100157497-1', 'auto');
|
||||
ga('send', 'pageview');
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
@ -185,7 +184,7 @@
|
||||
<!-- Hacknet Nodes -->
|
||||
<div id="hacknet-nodes-container" class="generic-menupage-container">
|
||||
<h1 id="hacknet-nodes-title"> Hacknet Nodes </h1>
|
||||
<p id="hacknet-nodes-text">
|
||||
<p id="hacknet-nodes-text" class="menu-page-text">
|
||||
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.
|
||||
@ -199,8 +198,11 @@
|
||||
</p>
|
||||
<a id="hacknet-nodes-purchase-button" class="a-link-button"> Purchase Hacknet Node </a>
|
||||
<br>
|
||||
<div id="hacknet-nodes-money-multipliers-div">"
|
||||
<p id="hacknet-nodes-money"> </p>
|
||||
<div id="hacknet-nodes-money-multipliers-div">
|
||||
<p id="hacknet-nodes-money">
|
||||
<span>Money:</span><span id="hacknet-nodes-player-money" ></span><br />
|
||||
<span>Total Hacknet Node Prodution:</span><span id="hacknet-nodes-total-production"></span>
|
||||
</p>
|
||||
<span id="hacknet-nodes-multipliers">
|
||||
<a id="hacknet-nodes-1x-multiplier" class="a-link-button-inactive"> x1 </a>
|
||||
<a id="hacknet-nodes-5x-multiplier" class="a-link-button"> x5 </a>
|
||||
@ -208,7 +210,7 @@
|
||||
<a id="hacknet-nodes-max-multiplier" class="a-link-button"> MAX </a>
|
||||
</span>
|
||||
</div>
|
||||
<ul id="hacknet-nodes-list" style="list-style : none;">
|
||||
<ul id="hacknet-nodes-list">
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
5
package-lock.json
generated
5
package-lock.json
generated
@ -12486,6 +12486,11 @@
|
||||
"resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
|
||||
"integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0="
|
||||
},
|
||||
"numeral": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/numeral/-/numeral-2.0.6.tgz",
|
||||
"integrity": "sha1-StCAk21EPCVhrtnyGX7//iX05QY="
|
||||
},
|
||||
"oauth-sign": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.4.0.tgz",
|
||||
|
@ -28,6 +28,7 @@
|
||||
"memory-fs": "~0.4.1",
|
||||
"mkdirp": "~0.5.0",
|
||||
"node-libs-browser": "^2.0.0",
|
||||
"numeral": "2.0.6",
|
||||
"source-map": "^0.5.3",
|
||||
"sprintf-js": "^1.1.1",
|
||||
"supports-color": "^4.2.1",
|
||||
|
@ -9,7 +9,7 @@ import {printArray, createElement,
|
||||
createAccordionElement, removeElement,
|
||||
removeChildrenFromElement, exceptionAlert} from "../utils/HelperFunctions.js";
|
||||
import {logBoxCreate} from "../utils/LogBox.js";
|
||||
import numeral from "../utils/numeral.min.js";
|
||||
import numeral from "numeral/min/numeral.min";
|
||||
import {formatNumber} from "../utils/StringHelperFunctions.js";
|
||||
|
||||
/* {
|
||||
|
@ -184,6 +184,7 @@ let AugmentationNames = {
|
||||
BladeArmorUnibeam: "BLADE-51b Tesla Armor: Unibeam Upgrade",
|
||||
BladeArmorOmnibeam: "BLADE-51b Tesla Armor: Omnibeam Upgrade",
|
||||
BladeArmorIPU: "BLADE-51b Tesla Armor: IPU Upgrade",
|
||||
BladesSimulacrum: "The Blade's Simulacrum",
|
||||
|
||||
//Wasteland Augs
|
||||
//PepBoy: "P.E.P-Boy", Plasma Energy Projection System
|
||||
@ -1552,7 +1553,7 @@ function initAugmentations() {
|
||||
var BladeburnersFactionName = "Bladeburners";
|
||||
if (factionExists(BladeburnersFactionName)) {
|
||||
var EsperEyewear = new Augmentation({
|
||||
name:AugmentationNames.EsperEyewear, repCost:400, moneyCost:30e6,
|
||||
name:AugmentationNames.EsperEyewear, repCost:500, moneyCost:33e6,
|
||||
info:"Ballistic-grade protective and retractable eyewear that was designed specially " +
|
||||
"for Bladeburner units. This " +
|
||||
"is implanted by installing a mechanical frame in the skull's orbit. " +
|
||||
@ -1569,7 +1570,7 @@ function initAugmentations() {
|
||||
resetAugmentation(EsperEyewear);
|
||||
|
||||
var EMS4Recombination = new Augmentation({
|
||||
name:AugmentationNames.EMS4Recombination, repCost: 800, moneyCost:50e6,
|
||||
name:AugmentationNames.EMS4Recombination, repCost: 1e3, moneyCost:55e6,
|
||||
info:"A DNA recombination of the EMS-4 Gene. This genetic engineering " +
|
||||
"technique was originally used on Bladeburners during the Synthoid uprising " +
|
||||
"to induce wakefulness and concentration, suppress fear, reduce empathy, and " +
|
||||
@ -1583,7 +1584,7 @@ function initAugmentations() {
|
||||
resetAugmentation(EMS4Recombination);
|
||||
|
||||
var OrionShoulder = new Augmentation({
|
||||
name:AugmentationNames.OrionShoulder, repCost:2e3, moneyCost:100e6,
|
||||
name:AugmentationNames.OrionShoulder, repCost:2.5e3, moneyCost:110e6,
|
||||
info:"A bionic shoulder augmentation for the right shoulder. Using cybernetics, " +
|
||||
"the ORION-MKIV shoulder enhances the strength and dexterity " +
|
||||
"of the user's right arm. It also provides protection due to its " +
|
||||
@ -1597,7 +1598,7 @@ function initAugmentations() {
|
||||
resetAugmentation(OrionShoulder);
|
||||
|
||||
var HyperionV1 = new Augmentation({
|
||||
name:AugmentationNames.HyperionV1, repCost: 4e3, moneyCost:500e6,
|
||||
name:AugmentationNames.HyperionV1, repCost: 5e3, moneyCost:550e6,
|
||||
info:"A pair of mini plasma cannons embedded into the hands. The Hyperion is capable " +
|
||||
"of rapidly firing bolts of high-density plasma. The weapon is meant to " +
|
||||
"be used against augmented enemies as the ionized " +
|
||||
@ -1611,7 +1612,7 @@ function initAugmentations() {
|
||||
resetAugmentation(HyperionV1);
|
||||
|
||||
var HyperionV2 = new Augmentation({
|
||||
name:AugmentationNames.HyperionV2, repCost:8e3, moneyCost:1e9,
|
||||
name:AugmentationNames.HyperionV2, repCost:10e3, moneyCost:1.1e9,
|
||||
info:"A pair of mini plasma cannons embedded into the hands. This augmentation " +
|
||||
"is more advanced and powerful than the original V1 model. This V2 model is " +
|
||||
"more power-efficiency, more accurate, and can fire plasma bolts at a much " +
|
||||
@ -1624,7 +1625,7 @@ function initAugmentations() {
|
||||
resetAugmentation(HyperionV2);
|
||||
|
||||
var GolemSerum = new Augmentation({
|
||||
name:AugmentationNames.GolemSerum, repCost:10e3, moneyCost:2e9,
|
||||
name:AugmentationNames.GolemSerum, repCost:12.5e3, moneyCost:2.2e9,
|
||||
info:"A serum that permanently enhances many aspects of a human's capabilities, " +
|
||||
"including strength, speed, immune system performance, and mitochondrial efficiency. The " +
|
||||
"serum was originally developed by the Chinese military in an attempt to " +
|
||||
@ -1637,7 +1638,7 @@ function initAugmentations() {
|
||||
resetAugmentation(GolemSerum);
|
||||
|
||||
var VangelisVirus = new Augmentation({
|
||||
name:AugmentationNames.VangelisVirus, repCost:6e3, moneyCost:500e6,
|
||||
name:AugmentationNames.VangelisVirus, repCost:7.5e3, moneyCost:550e6,
|
||||
info:"A synthetic symbiotic virus that is injected into the human brain tissue. The Vangelis virus " +
|
||||
"heightens the senses and focus of its host, and also enhances its intuition.<br><br>" +
|
||||
"This augmentation:<br>" +
|
||||
@ -1649,7 +1650,7 @@ function initAugmentations() {
|
||||
resetAugmentation(VangelisVirus);
|
||||
|
||||
var VangelisVirus3 = new Augmentation({
|
||||
name:AugmentationNames.VangelisVirus3, repCost:12e3, moneyCost:2e9,
|
||||
name:AugmentationNames.VangelisVirus3, repCost:15e3, moneyCost:2.2e9,
|
||||
info:"An improved version of Vangelis, a synthetic symbiotic virus that is " +
|
||||
"injected into the human brain tissue. On top of the benefits of the original " +
|
||||
"virus, this also grants an accelerated healing factor and enhanced " +
|
||||
@ -1664,7 +1665,7 @@ function initAugmentations() {
|
||||
resetAugmentation(VangelisVirus3);
|
||||
|
||||
var INTERLINKED = new Augmentation({
|
||||
name:AugmentationNames.INTERLINKED, repCost:8e3, moneyCost:1e9,
|
||||
name:AugmentationNames.INTERLINKED, repCost:10e3, moneyCost:1.1e9,
|
||||
info:"The DNA is genetically modified to enhance the human's body " +
|
||||
"extracellular matrix (ECM). This improves the ECM's ability to " +
|
||||
"structurally support the body and grants heightened strength and " +
|
||||
@ -1677,7 +1678,7 @@ function initAugmentations() {
|
||||
resetAugmentation(INTERLINKED);
|
||||
|
||||
var BladeRunner = new Augmentation({
|
||||
name:AugmentationNames.BladeRunner, repCost:8e3, moneyCost:1.5e9,
|
||||
name:AugmentationNames.BladeRunner, repCost:8e3, moneyCost:1.65e9,
|
||||
info:"A cybernetic foot augmentation that was specially created for Bladeburners " +
|
||||
"during the Synthoid Uprising. The organic musculature of the human foot " +
|
||||
"is enhanced with flexible carbon nanotube matrices that are controlled by " +
|
||||
@ -1691,7 +1692,7 @@ function initAugmentations() {
|
||||
resetAugmentation(BladeRunner);
|
||||
|
||||
var BladeArmor = new Augmentation({
|
||||
name:AugmentationNames.BladeArmor, repCost:4e3, moneyCost:250e6,
|
||||
name:AugmentationNames.BladeArmor, repCost:5e3, moneyCost:275e6,
|
||||
info:"A powered exoskeleton suit (exosuit) designed as armor for Bladeburner units. This " +
|
||||
"exoskeleton is incredibly adaptable and can protect the wearer from blunt, piercing, " +
|
||||
"concussive, thermal, chemical, and electric trauma. It also enhances the user's " +
|
||||
@ -1705,7 +1706,7 @@ function initAugmentations() {
|
||||
resetAugmentation(BladeArmor);
|
||||
|
||||
var BladeArmorPowerCells = new Augmentation({
|
||||
name:AugmentationNames.BladeArmorPowerCells, repCost:6e3, moneyCost:500e6,
|
||||
name:AugmentationNames.BladeArmorPowerCells, repCost:7.5e3, moneyCost:550e6,
|
||||
info:"Upgrades the BLADE-51b Tesla Armor with Ion Power Cells, which are capable of " +
|
||||
"more efficiently storing and using power.<br><br>" +
|
||||
"This augmentation:<br>" +
|
||||
@ -1718,7 +1719,7 @@ function initAugmentations() {
|
||||
resetAugmentation(BladeArmorPowerCells);
|
||||
|
||||
var BladeArmorEnergyShielding = new Augmentation({
|
||||
name:AugmentationNames.BladeArmorEnergyShielding, repCost:7e3, moneyCost:1e9,
|
||||
name:AugmentationNames.BladeArmorEnergyShielding, repCost:8.5e3, moneyCost:1.1e9,
|
||||
info:"Upgrades the BLADE-51b Tesla Armor with a plasma energy propulsion system " +
|
||||
"that is capable of projecting an energy shielding force field.<br><br>" +
|
||||
"This augmentation:<br>" +
|
||||
@ -1730,7 +1731,7 @@ function initAugmentations() {
|
||||
resetAugmentation(BladeArmorEnergyShielding);
|
||||
|
||||
var BladeArmorUnibeam = new Augmentation({
|
||||
name:AugmentationNames.BladeArmorUnibeam, repCost:10e3, moneyCost:3e9,
|
||||
name:AugmentationNames.BladeArmorUnibeam, repCost:12.5e3, moneyCost:3.3e9,
|
||||
info:"Upgrades the BLADE-51b Tesla Armor with a concentrated deuterium-fluoride laser " +
|
||||
"weapon. It's precision an accuracy makes it useful for quickly neutralizing " +
|
||||
"threats while keeping casualties to a minimum.<br><br>" +
|
||||
@ -1742,7 +1743,7 @@ function initAugmentations() {
|
||||
resetAugmentation(BladeArmorUnibeam);
|
||||
|
||||
var BladeArmorOmnibeam = new Augmentation({
|
||||
name:AugmentationNames.BladeArmorOmnibeam, repCost:20e3, moneyCost:5e9,
|
||||
name:AugmentationNames.BladeArmorOmnibeam, repCost:25e3, moneyCost:5.5e9,
|
||||
info:"Upgrades the BLADE-51b Tesla Armor Unibeam augmentation to use " +
|
||||
"multiple-fiber system. The upgraded weapon uses multiple fiber laser " +
|
||||
"modules that combine together to form a single, more powerful beam of up to " +
|
||||
@ -1755,7 +1756,7 @@ function initAugmentations() {
|
||||
resetAugmentation(BladeArmorOmnibeam);
|
||||
|
||||
var BladeArmorIPU = new Augmentation({
|
||||
name:AugmentationNames.BladeArmorIPU, repCost: 5e3, moneyCost:200e6,
|
||||
name:AugmentationNames.BladeArmorIPU, repCost: 6e3, moneyCost:220e6,
|
||||
info:"Upgrades the BLADE-51b Tesla Armor with an AI Information Processing " +
|
||||
"Unit that was specially designed to analyze Synthoid related data and " +
|
||||
"information.<br><br>" +
|
||||
@ -1766,6 +1767,19 @@ function initAugmentations() {
|
||||
});
|
||||
BladeArmorIPU.addToFactions([BladeburnersFactionName]);
|
||||
resetAugmentation(BladeArmorIPU);
|
||||
|
||||
var BladesSimulacrum = new Augmentation({
|
||||
name:AugmentationNames.BladesSimulacrum, repCost:6e3, moneyCost:75e9,
|
||||
info:"A highly-advanced matter phase-shifter module that is embedded " +
|
||||
"in the brainstem and cerebellum. This augmentation allows " +
|
||||
"the user to project and control a holographic simulacrum within an " +
|
||||
"extremely large radius. These specially-modified holograms were specially " +
|
||||
"weaponized by Bladeburner units to be used against Synthoids.<br><br>" +
|
||||
"This augmentation allows you to perform Bladeburner actions and other " +
|
||||
"actions (such as working, commiting crimes, etc.) at the same time."
|
||||
});
|
||||
BladesSimulacrum.addToFactions([BladeburnersFactionName]);
|
||||
resetAugmentation(BladesSimulacrum);
|
||||
}
|
||||
|
||||
//Update costs based on how many have been purchased
|
||||
@ -1777,8 +1791,6 @@ function initAugmentations() {
|
||||
}
|
||||
|
||||
Player.reapplyAllAugmentations();
|
||||
|
||||
|
||||
}
|
||||
|
||||
//Resets an Augmentation during (re-initizliation)
|
||||
@ -2350,6 +2362,8 @@ function applyAugmentation(aug, reapply=false) {
|
||||
Player.bladeburner_analysis_mult *= 1.15;
|
||||
Player.bladeburner_success_chance_mult *= 1.02;
|
||||
break;
|
||||
case AugmentationNames.BladesSimulacrum: //No multiplier effect
|
||||
break;
|
||||
default:
|
||||
throw new Error("ERROR: No such augmentation!");
|
||||
return;
|
||||
@ -2594,8 +2608,9 @@ function displaySourceFiles(listElement, sourceFiles) {
|
||||
console.log("ERROR: Invalid source file number: " + sourceFiles[i].n);
|
||||
continue;
|
||||
}
|
||||
const maxLevel = sourceFiles[i].n == 12 ? "∞" : "3";
|
||||
var accordion = createAccordionElement({
|
||||
hdrText:sourceFileObject.name + "<br>" + "Level " + (sourceFiles[i].lvl) + " / 3",
|
||||
hdrText:sourceFileObject.name + "<br>" + "Level " + (sourceFiles[i].lvl) + " / "+maxLevel,
|
||||
panelText:sourceFileObject.info
|
||||
});
|
||||
|
||||
|
@ -156,10 +156,13 @@ function initBitNodes() {
|
||||
"Level 1: 24%<br>" +
|
||||
"Level 2: 36%<br>" +
|
||||
"Level 3: 42%");
|
||||
|
||||
BitNodes["BitNode12"] = new BitNode(12, "The Recursion", "Repeat.",
|
||||
"To iterate is human, to recurse divine.<br><br>" +
|
||||
"Every time this BitNode is destroyed, it becomes slightly harder. Destroying this BitNode will give your Souce-File 12, or " +
|
||||
"if you already have this Source-File it will upgrade its level. There is no maximum level for Source-File 12. Each level " +
|
||||
"of Source-File 12 will increase all of your multipliers by 1%.");
|
||||
//Books: Frontera, Shiner
|
||||
BitNodes["BitNode12"] = new BitNode(12, "fOS", "COMING SOON"); //Unlocks the new game mode and the rest of the BitNodes
|
||||
BitNodes["BitNode13"] = new BitNode(13, "", "COMING SOON");
|
||||
BitNodes["BitNode13"] = new BitNode(13, "fOS", "COMING SOON"); //Unlocks the new game mode and the rest of the BitNodes
|
||||
BitNodes["BitNode14"] = new BitNode(14, "", "COMING SOON");
|
||||
BitNodes["BitNode15"] = new BitNode(15, "", "COMING SOON");
|
||||
BitNodes["BitNode16"] = new BitNode(16, "", "COMING SOON");
|
||||
@ -232,10 +235,10 @@ function initBitNodeMultipliers() {
|
||||
BitNodeMultipliers.RepToDonateToFaction = 0.5;
|
||||
BitNodeMultipliers.AugmentationRepCost = 3;
|
||||
BitNodeMultipliers.AugmentationMoneyCost = 3;
|
||||
BitNodeMultipliers.ServerMaxMoney = 0.25;
|
||||
BitNodeMultipliers.ServerStartingMoney = 0.25;
|
||||
BitNodeMultipliers.ServerGrowthRate = 0.20;
|
||||
BitNodeMultipliers.ScriptHackMoney = 0.25;
|
||||
BitNodeMultipliers.ServerMaxMoney = 0.2;
|
||||
BitNodeMultipliers.ServerStartingMoney = 0.2;
|
||||
BitNodeMultipliers.ServerGrowthRate = 0.2;
|
||||
BitNodeMultipliers.ScriptHackMoney = 0.2;
|
||||
BitNodeMultipliers.CompanyWorkMoney = 0.25;
|
||||
BitNodeMultipliers.CrimeMoney = 0.25;
|
||||
BitNodeMultipliers.HacknetNodeMoney = 0.25;
|
||||
@ -304,10 +307,56 @@ function initBitNodeMultipliers() {
|
||||
BitNodeMultipliers.InfiltrationRep = 2.5;
|
||||
BitNodeMultipliers.CorporationValuation = 0.01;
|
||||
break;
|
||||
case 12: //The Recursion
|
||||
let sf12Lvl = 0;
|
||||
for (let i = 0; i < Player.sourceFiles.length; i++) {
|
||||
if (Player.sourceFiles[i].n === 12) {
|
||||
sf12Lvl = Player.sourceFiles[i].lvl;
|
||||
}
|
||||
}
|
||||
const inc = Math.pow(1.01, sf12Lvl);
|
||||
const dec = Math.pow(0.99, sf12Lvl);
|
||||
BitNodeMultipliers.HackingLevelMultiplier = dec;
|
||||
|
||||
BitNodeMultipliers.ServerMaxMoney = dec;
|
||||
BitNodeMultipliers.ServerStartingMoney = dec;
|
||||
BitNodeMultipliers.ServerGrowthRate = dec;
|
||||
BitNodeMultipliers.ServerWeakenRate = dec;
|
||||
|
||||
//Does not scale, otherwise security might start at 300+
|
||||
BitNodeMultipliers.ServerStartingSecurity = 1.5;
|
||||
|
||||
BitNodeMultipliers.ManualHackMoney = dec;
|
||||
BitNodeMultipliers.ScriptHackMoney = dec;
|
||||
BitNodeMultipliers.CompanyWorkMoney = dec;
|
||||
BitNodeMultipliers.CrimeMoney = dec;
|
||||
BitNodeMultipliers.HacknetNodeMoney = dec;
|
||||
|
||||
BitNodeMultipliers.CompanyWorkExpGain = dec;
|
||||
BitNodeMultipliers.ClassGymExpGain = dec;
|
||||
BitNodeMultipliers.FactionWorkExpGain = dec;
|
||||
BitNodeMultipliers.HackExpGain = dec;
|
||||
BitNodeMultipliers.CrimeExpGain = dec;
|
||||
|
||||
BitNodeMultipliers.FactionWorkRepGain = dec;
|
||||
BitNodeMultipliers.FactionPassiveRepGain = dec;
|
||||
BitNodeMultipliers.RepToDonateToFaction = inc;
|
||||
|
||||
BitNodeMultipliers.AugmentationRepCost = inc;
|
||||
BitNodeMultipliers.AugmentationMoneyCost = inc;
|
||||
|
||||
BitNodeMultipliers.InfiltrationMoney = dec;
|
||||
BitNodeMultipliers.InfiltrationRep = dec;
|
||||
|
||||
BitNodeMultipliers.CorporationValuation = dec;
|
||||
default:
|
||||
console.log("WARNING: Player.bitNodeN invalid");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
export {initBitNodes, BitNode, BitNodes, BitNodeMultipliers, initBitNodeMultipliers};
|
||||
export {initBitNodes,
|
||||
BitNode,
|
||||
BitNodes,
|
||||
BitNodeMultipliers,
|
||||
initBitNodeMultipliers};
|
||||
|
@ -1,10 +1,11 @@
|
||||
import {Augmentations, AugmentationNames} from "./Augmentations.js";
|
||||
import {CONSTANTS} from "./Constants.js";
|
||||
import {Engine} from "./engine.js";
|
||||
import {Faction, Factions, factionExists,
|
||||
joinFaction, displayFactionContent} from "./Faction.js";
|
||||
import {Locations} from "./Location.js";
|
||||
import {Player} from "./Player.js";
|
||||
import {hackWorldDaemon} from "./RedPill.js";
|
||||
import {hackWorldDaemon, redPillFlag} from "./RedPill.js";
|
||||
import {KEY} from "./Terminal.js";
|
||||
|
||||
import {dialogBoxCreate} from "../utils/DialogBox.js";
|
||||
@ -15,7 +16,7 @@ import {getRandomInt, addOffset, clearObject,
|
||||
createProgressBarText} from "../utils/HelperFunctions.js";
|
||||
import {Reviver, Generic_toJSON,
|
||||
Generic_fromJSON} from "../utils/JSONReviver.js";
|
||||
import numeral from "../utils/numeral.min.js";
|
||||
import numeral from "numeral/min/numeral.min";
|
||||
import {formatNumber} from "../utils/StringHelperFunctions.js";
|
||||
|
||||
|
||||
@ -29,10 +30,16 @@ var MaxStaminaToGainFactor = 70000; //Max Stamina is divided by this to get
|
||||
|
||||
var DifficultyToTimeFactor = 10; //Action Difficulty divided by this to get base action time
|
||||
|
||||
//The difficulty multiplier affects stamina loss and hp loss of an action. Its formula is:
|
||||
//The difficulty multiplier affects stamina loss and hp loss of an action. Also affects
|
||||
//experience gain. Its formula is:
|
||||
//difficulty ^ exponentialFactor + difficulty / linearFactor
|
||||
var DiffMultExponentialFactor = 0.28;
|
||||
var DiffMultLinearFactor = 670;
|
||||
var DiffMultLinearFactor = 650;
|
||||
|
||||
var EffAgiLinearFactor = 90e3;
|
||||
var EffDexLinearFactor = 90e3;
|
||||
var EffAgiExponentialFactor = 0.031;
|
||||
var EffDexExponentialFactor = 0.03;
|
||||
|
||||
var BaseRecruitmentTimeNeeded = 300; //Base time needed (s) to complete a Recruitment action
|
||||
|
||||
@ -45,13 +52,14 @@ var BaseIntGain = 0.001; //Base intelligence stat gain
|
||||
var ActionCountGrowthPeriod = 300; //Time (s) it takes for action count to grow by its specified value
|
||||
|
||||
var RankToFactionRepFactor = 2; //Delta Faction Rep = this * Delta Rank
|
||||
var RankNeededForFaction = 25;
|
||||
|
||||
var ContractSuccessesPerLevel = 15; //How many successes you need to level up a contract
|
||||
var OperationSuccessesPerLevel = 10; //How many successes you need to level up an op
|
||||
var ContractSuccessesPerLevel = 3; //How many successes you need to level up a contract
|
||||
var OperationSuccessesPerLevel = 2.5; //How many successes you need to level up an op
|
||||
|
||||
var RanksPerSkillPoint = 4; //How many ranks needed to get 1 Skill Point
|
||||
|
||||
var ContractBaseMoneyGain = 5e3; //Base Money Gained per contract
|
||||
var ContractBaseMoneyGain = 10e3; //Base Money Gained per contract
|
||||
|
||||
//DOM related variables
|
||||
var ActiveActionCssClass = "bladeburner-active-action";
|
||||
@ -518,7 +526,10 @@ Action.prototype.getActionTime = function(inst) {
|
||||
|
||||
var effAgility = Player.agility * inst.skillMultipliers.effAgi;
|
||||
var effDexterity = Player.dexterity * inst.skillMultipliers.effDex;
|
||||
var statFac = 0.5 * (Math.pow(effAgility, 0.03) + Math.pow(effDexterity, 0.03)); //Always > 1
|
||||
var statFac = 0.5 * (Math.pow(effAgility, EffAgiExponentialFactor) +
|
||||
Math.pow(effDexterity, EffDexExponentialFactor) +
|
||||
(effAgility / EffAgiLinearFactor) +
|
||||
(effDexterity / EffDexLinearFactor)); //Always > 1
|
||||
|
||||
baseTime = Math.max(1, baseTime * skillFac / statFac);
|
||||
|
||||
@ -533,6 +544,16 @@ Action.prototype.getActionTime = function(inst) {
|
||||
}
|
||||
}
|
||||
|
||||
Action.prototype.getSuccessesNeededForNextLevel = function(baseSuccessesPerLevel) {
|
||||
return Math.ceil((0.5) * (this.maxLevel) * (2 * baseSuccessesPerLevel + (this.maxLevel-1)));
|
||||
}
|
||||
|
||||
Action.prototype.setMaxLevel = function(baseSuccessesPerLevel) {
|
||||
if (this.successes >= this.getSuccessesNeededForNextLevel(baseSuccessesPerLevel)) {
|
||||
++this.maxLevel;
|
||||
}
|
||||
}
|
||||
|
||||
Action.prototype.toJSON = function() {
|
||||
return Generic_toJSON("Action", this);
|
||||
}
|
||||
@ -684,6 +705,14 @@ function Bladeburner(params={}) {
|
||||
if (params.new) {this.create();}
|
||||
}
|
||||
|
||||
Bladeburner.prototype.prestige = function() {
|
||||
this.resetAction();
|
||||
var bladeburnerFac = Factions["Bladeburners"];
|
||||
if (this.rank >= RankNeededForFaction) {
|
||||
joinFaction(bladeburnerFac);
|
||||
}
|
||||
}
|
||||
|
||||
Bladeburner.prototype.create = function() {
|
||||
this.contracts["Tracking"] = new Contract({
|
||||
name:"Tracking",
|
||||
@ -804,8 +833,13 @@ Bladeburner.prototype.storeCycles = function(numCycles=1) {
|
||||
}
|
||||
|
||||
Bladeburner.prototype.process = function() {
|
||||
//Extreme condition...if Operation Daedalus is complete trigger the BitNode
|
||||
if (redPillFlag === false && this.blackops.hasOwnProperty("Operation Daedalus")) {
|
||||
return hackWorldDaemon(Player.bitNodeN);
|
||||
}
|
||||
|
||||
//If the Player starts doing some other actions, set action to idle and alert
|
||||
if (Player.isWorking) {
|
||||
if (Augmentations[AugmentationNames.BladesSimulacrum].owned === false && Player.isWorking) {
|
||||
if (this.action.type !== ActionTypes["Idle"]) {
|
||||
dialogBoxCreate("Your Bladeburner action was cancelled because you started " +
|
||||
"doing something else");
|
||||
@ -909,7 +943,8 @@ Bladeburner.prototype.changeRank = function(change) {
|
||||
throw new Error("Could not properly get Bladeburner Faction object in Bladeburner UI Overview Faction button");
|
||||
}
|
||||
if (bladeburnerFac.isMember) {
|
||||
bladeburnerFac.playerReputation += (RankToFactionRepFactor * change * Player.faction_rep_mult);
|
||||
var favorBonus = 1 + (bladeburnerFac.favor / 100);
|
||||
bladeburnerFac.playerReputation += (RankToFactionRepFactor * change * Player.faction_rep_mult * favorBonus);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1021,6 +1056,7 @@ Bladeburner.prototype.resetAction = function() {
|
||||
}
|
||||
|
||||
Bladeburner.prototype.startAction = function(actionId) {
|
||||
if (actionId == null) {return;}
|
||||
this.action = actionId;
|
||||
this.actionTimeCurrent = 0;
|
||||
switch (actionId.type) {
|
||||
@ -1067,10 +1103,7 @@ Bladeburner.prototype.startAction = function(actionId) {
|
||||
this.actionTimeToComplete = 30;
|
||||
break;
|
||||
case ActionTypes["Recruitment"]:
|
||||
var effCharisma = Player.charisma * this.skillMultipliers.effCha;
|
||||
var charismaFactor = Math.pow(effCharisma, 0.81) + effCharisma / 90;
|
||||
var time = Math.max(10, Math.round(BaseRecruitmentTimeNeeded - charismaFactor));
|
||||
this.actionTimeToComplete = time;
|
||||
this.actionTimeToComplete = this.getRecruitmentTime();
|
||||
break;
|
||||
case ActionTypes["FieldAnalysis"]:
|
||||
case ActionTypes["Field Analysis"]:
|
||||
@ -1130,9 +1163,9 @@ Bladeburner.prototype.completeAction = function() {
|
||||
}
|
||||
|
||||
if (isOperation) {
|
||||
action.maxLevel = Math.floor(action.successes / OperationSuccessesPerLevel) + 1;
|
||||
action.setMaxLevel(OperationSuccessesPerLevel);
|
||||
} else {
|
||||
action.maxLevel = Math.floor(action.successes / ContractSuccessesPerLevel) + 1;
|
||||
action.setMaxLevel(ContractSuccessesPerLevel);
|
||||
}
|
||||
if (action.rankGain) {
|
||||
var gain = addOffset(action.rankGain * rewardMultiplier, 10);
|
||||
@ -1301,7 +1334,7 @@ Bladeburner.prototype.completeAction = function() {
|
||||
this.startAction(this.action); //Repeat action
|
||||
break;
|
||||
case ActionTypes["Recruitment"]:
|
||||
var successChance = Math.pow(Player.charisma, 0.45) / (this.teamSize + 1);
|
||||
var successChance = this.getRecruitmentSuccessChance();
|
||||
console.log("Bladeburner recruitment success chance: " + successChance);
|
||||
if (Math.random() < successChance) {
|
||||
var expGain = 2 * BaseStatGain * this.actionTimeToComplete;
|
||||
@ -1437,6 +1470,16 @@ Bladeburner.prototype.completeOperation = function(success) {
|
||||
}
|
||||
}
|
||||
|
||||
Bladeburner.prototype.getRecruitmentTime = function() {
|
||||
var effCharisma = Player.charisma * this.skillMultipliers.effCha;
|
||||
var charismaFactor = Math.pow(effCharisma, 0.81) + effCharisma / 90;
|
||||
return Math.max(10, Math.round(BaseRecruitmentTimeNeeded - charismaFactor));
|
||||
}
|
||||
|
||||
Bladeburner.prototype.getRecruitmentSuccessChance = function() {
|
||||
return Math.pow(Player.charisma, 0.45) / (this.teamSize + 1);
|
||||
}
|
||||
|
||||
//Process stat gains from Contracts, Operations, and Black Operations
|
||||
//@action(Action obj) - Derived action class
|
||||
//@success(bool) - Whether action was successful
|
||||
@ -1445,7 +1488,7 @@ Bladeburner.prototype.gainActionStats = function(action, success) {
|
||||
|
||||
//Gain multiplier based on difficulty. If this changes then the
|
||||
//same variable calculated in completeAction() needs to change too
|
||||
var difficultyMult = Math.pow(difficulty, 0.21);
|
||||
var difficultyMult = Math.pow(difficulty, DiffMultExponentialFactor) + difficulty / DiffMultLinearFactor;
|
||||
|
||||
var time = this.actionTimeToComplete;
|
||||
var successMult = success ? 1 : 0.5;
|
||||
@ -1621,6 +1664,7 @@ Bladeburner.prototype.initializeDomElementRefs = function() {
|
||||
operations: {},
|
||||
blackops: {},
|
||||
skills: {},
|
||||
skillPointsDisplay: null,
|
||||
};
|
||||
}
|
||||
|
||||
@ -1682,6 +1726,7 @@ Bladeburner.prototype.createContent = function() {
|
||||
document.getElementById("entire-game-container").appendChild(DomElems.bladeburnerDiv);
|
||||
|
||||
this.postToConsole("Bladeburner Console BETA");
|
||||
this.postToConsole("Type 'help' to see console commands");
|
||||
DomElems.consoleInput.focus();
|
||||
}
|
||||
|
||||
@ -1836,7 +1881,7 @@ Bladeburner.prototype.createOverviewContent = function() {
|
||||
}));
|
||||
|
||||
//Faction button
|
||||
var bladeburnersFactionName = "Bladeburners";
|
||||
const bladeburnersFactionName = "Bladeburners";
|
||||
if (factionExists(bladeburnersFactionName)) {
|
||||
var bladeburnerFac = Factions[bladeburnersFactionName];
|
||||
if (!(bladeburnerFac instanceof Faction)) {
|
||||
@ -1850,7 +1895,7 @@ Bladeburner.prototype.createOverviewContent = function() {
|
||||
Engine.loadFactionContent();
|
||||
displayFactionContent(bladeburnersFactionName);
|
||||
} else {
|
||||
if (this.rank >= 25) {
|
||||
if (this.rank >= RankNeededForFaction) {
|
||||
joinFaction(bladeburnerFac);
|
||||
dialogBoxCreate("Congratulations! You were accepted into the Bladeburners faction");
|
||||
removeChildrenFromElement(DomElems.overviewDiv);
|
||||
@ -2112,9 +2157,10 @@ Bladeburner.prototype.createSkillsContent = function() {
|
||||
}
|
||||
|
||||
//Skill Points
|
||||
DomElems.actionAndSkillsDiv.appendChild(createElement("p", {
|
||||
DomElems.skillPointsDisplay = createElement("p", {
|
||||
innerHTML:"<br><strong>Skill Points: " + formatNumber(this.skillPoints, 0) + "</strong>"
|
||||
}));
|
||||
});
|
||||
DomElems.actionAndSkillsDiv.appendChild(DomElems.skillPointsDisplay);
|
||||
|
||||
//UI Element for each skill
|
||||
for (var skillName in Skills) {
|
||||
@ -2226,6 +2272,8 @@ Bladeburner.prototype.updateActionAndSkillsContent = function() {
|
||||
}
|
||||
break;
|
||||
case "skills":
|
||||
DomElems.skillPointsDisplay.innerHTML = "<br><strong>Skill Points: " + formatNumber(this.skillPoints, 0) + "</strong>";
|
||||
|
||||
var skillElems = Object.keys(DomElems.skills);
|
||||
for (var i = 0; i < skillElems.length; ++i) {
|
||||
var skillElem = DomElems.skills[skillElems[i]];
|
||||
@ -2321,7 +2369,9 @@ Bladeburner.prototype.updateContractsUIElement = function(el, action) {
|
||||
appendLineBreaks(el, 2);
|
||||
el.appendChild(createElement("pre", {
|
||||
display:"inline-block",
|
||||
innerText:"Level: " + action.level + " / " + action.maxLevel
|
||||
innerText:"Level: " + action.level + " / " + action.maxLevel,
|
||||
tooltip:action.getSuccessesNeededForNextLevel(ContractSuccessesPerLevel) + " successes " +
|
||||
"needed for next level"
|
||||
}));
|
||||
el.appendChild(createElement("a", {
|
||||
class: maxLevel ? "a-link-button-inactive" : "a-link-button", innerHTML:"↑",
|
||||
@ -2453,7 +2503,9 @@ Bladeburner.prototype.updateOperationsUIElement = function(el, action) {
|
||||
appendLineBreaks(el, 2);
|
||||
el.appendChild(createElement("pre", {
|
||||
display:"inline-block",
|
||||
innerText:"Level: " + action.level + " / " + action.maxLevel
|
||||
innerText:"Level: " + action.level + " / " + action.maxLevel,
|
||||
tooltip:action.getSuccessesNeededForNextLevel(OperationSuccessesPerLevel) + " successes " +
|
||||
"needed for next level"
|
||||
}));
|
||||
el.appendChild(createElement("a", {
|
||||
class: maxLevel ? "a-link-button-inactive" : "a-link-button", innerHTML:"↑",
|
||||
@ -2632,6 +2684,7 @@ Bladeburner.prototype.updateSkillsUIElement = function(el, skill) {
|
||||
class: canLevel && !maxLvl ? "a-link-button" : "a-link-button-inactive",
|
||||
margin:"3px", padding:"3px",
|
||||
clickListener:()=>{
|
||||
if (this.skillPoints < pointCost) {return;}
|
||||
this.skillPoints -= pointCost;
|
||||
this.upgradeSkill(skill);
|
||||
this.createActionAndSkillsContent();
|
||||
@ -3142,6 +3195,397 @@ Bladeburner.prototype.executeStartConsoleCommand = function(args) {
|
||||
}
|
||||
}
|
||||
|
||||
Bladeburner.prototype.getActionIdFromTypeAndName = function(type="", name="") {
|
||||
if (type === "" || name === "") {return null;}
|
||||
var action = new ActionIdentifier();
|
||||
var convertedType = type.toLowerCase().trim();
|
||||
var convertedName = name.toLowerCase().trim();
|
||||
switch (convertedType) {
|
||||
case "contract":
|
||||
case "contracts":
|
||||
action.type = ActionTypes["Contract"];
|
||||
if (this.contracts.hasOwnProperty(name)) {
|
||||
action.name = name;
|
||||
return action;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
case "operation":
|
||||
case "operations":
|
||||
case "op":
|
||||
case "ops":
|
||||
action.type = ActionTypes["Operation"];
|
||||
if (this.operations.hasOwnProperty(name)) {
|
||||
action.name = name;
|
||||
return action;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
case "blackoperation":
|
||||
case "black operation":
|
||||
case "black operations":
|
||||
case "black op":
|
||||
case "black ops":
|
||||
case "blackop":
|
||||
case "blackops":
|
||||
action.type = ActionTypes["BlackOp"];
|
||||
if (BlackOperations.hasOwnProperty(name)) {
|
||||
action.name = name;
|
||||
return action;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
case "general":
|
||||
case "general action":
|
||||
case "gen":
|
||||
break;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
if (convertedType.startsWith("gen")) {
|
||||
switch (convertedName) {
|
||||
case "training":
|
||||
action.type = ActionTypes["Training"];
|
||||
break;
|
||||
case "recruitment":
|
||||
case "recruit":
|
||||
action.type = ActionTypes["Recruitment"];
|
||||
break;
|
||||
case "field analysis":
|
||||
case "fieldanalysis":
|
||||
action.type = ActionTypes["Field Analysis"];
|
||||
break;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
return action;
|
||||
}
|
||||
}
|
||||
|
||||
Bladeburner.prototype.isContractNameNetscriptFn = function(name) {
|
||||
return this.contracts.hasOwnProperty(name);
|
||||
}
|
||||
|
||||
Bladeburner.prototype.isOperationNameNetscriptFn = function(name) {
|
||||
return this.operations.hasOwnProperty(name);
|
||||
}
|
||||
|
||||
Bladeburner.prototype.isBlackOpNameNetscriptFn = function(name) {
|
||||
return BlackOperations.hasOwnProperty(name);
|
||||
}
|
||||
|
||||
Bladeburner.prototype.isGeneralActionNameNetscriptFn = function(name) {
|
||||
return GeneralActions.hasOwnProperty(name);
|
||||
}
|
||||
|
||||
Bladeburner.prototype.isSkillNameNetscriptFn = function(name) {
|
||||
return Skills.hasOwnProperty(name);
|
||||
}
|
||||
|
||||
Bladeburner.prototype.startActionNetscriptFn = function(type, name, workerScript) {
|
||||
var errorLogText = "ERROR: Bladeburner.startAction() failed due to an invalid action specified. " +
|
||||
"Type: " + type + ", Name: " + name + ". Note that for contracts and operations, the " +
|
||||
"name of the operation is case-sensitive.";
|
||||
var actionId = this.getActionIdFromTypeAndName(type, name);
|
||||
if (actionId == null) {
|
||||
workerScript.log(errorLogText);
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
this.startAction(actionId);
|
||||
if (workerScript.shouldLog("startAction")) {
|
||||
workerScript.scriptRef.log("Starting Bladeburner action with type " + type + " and name " + name);
|
||||
}
|
||||
return true;
|
||||
} catch(e) {
|
||||
this.resetAction();
|
||||
workerScript.scriptRef.log("ERROR: Bladeburner.startAction() failed to start action of type " + type + " due to invalid name: " + name +
|
||||
"Note that this name is case-sensitive and whitespace-sensitive");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Bladeburner.prototype.getActionTimeNetscriptFn = function(type, name, workerScript) {
|
||||
var errorLogText = "ERROR: Bladeburner.getActionTime() failed due to an invalid action specified. " +
|
||||
"Type: " + type + ", Name: " + name + ". Note that for contracts and operations, the " +
|
||||
"name of the operation is case-sensitive.";
|
||||
var actionId = this.getActionIdFromTypeAndName(type, name);
|
||||
if (actionId == null) {
|
||||
workerScript.log(errorLogText);
|
||||
return -1;
|
||||
}
|
||||
|
||||
var actionObj = this.getActionObject(actionId);
|
||||
if (actionObj == null) {
|
||||
workerScript.log(errorLogText);
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (actionId.type) {
|
||||
case ActionTypes["Contract"]:
|
||||
case ActionTypes["Operation"]:
|
||||
case ActionTypes["BlackOp"]:
|
||||
case ActionTypes["BlackOperation"]:
|
||||
return actionObj.getActionTime(this);
|
||||
case ActionTypes["Training"]:
|
||||
case ActionTypes["Field Analysis"]:
|
||||
case ActionTypes["FieldAnalysis"]:
|
||||
return 30;
|
||||
case ActionTypes["Recruitment"]:
|
||||
return this.getRecruitmentTime();
|
||||
default:
|
||||
workerScript.log(errorLogText);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
Bladeburner.prototype.getActionEstimatedSuccessChanceNetscriptFn = function(type, name, workerScript) {
|
||||
var errorLogText = "ERROR: Bladeburner.getActionEstimatedSuccessChance() failed due to an invalid action specified. " +
|
||||
"Type: " + type + ", Name: " + name + ". Note that for contracts and operations, the " +
|
||||
"name of the operation is case-sensitive.";
|
||||
var actionId = this.getActionIdFromTypeAndName(type, name);
|
||||
if (actionId == null) {
|
||||
workerScript.log(errorLogText);
|
||||
return -1;
|
||||
}
|
||||
|
||||
var actionObj = this.getActionObject(actionId);
|
||||
if (actionObj == null) {
|
||||
workerScript.log(errorLogText);
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (actionId.type) {
|
||||
case ActionTypes["Contract"]:
|
||||
case ActionTypes["Operation"]:
|
||||
case ActionTypes["BlackOp"]:
|
||||
case ActionTypes["BlackOperation"]:
|
||||
return actionObj.getSuccessChance(this);
|
||||
case ActionTypes["Training"]:
|
||||
case ActionTypes["Field Analysis"]:
|
||||
case ActionTypes["FieldAnalysis"]:
|
||||
return 1;
|
||||
case ActionTypes["Recruitment"]:
|
||||
return this.getRecruitmentSuccessChance();
|
||||
default:
|
||||
workerScript.log(errorLogText);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
Bladeburner.prototype.getActionCountRemainingNetscriptFn = function(type, name, workerScript) {
|
||||
var errorLogText = "ERROR: Bladeburner.getActionCountRemaining() failed due to an invalid action specified. " +
|
||||
"Type: " + type + ", Name: " + name + ". Note that for contracts and operations, the " +
|
||||
"name of the operation is case-sensitive.";
|
||||
var actionId = this.getActionIdFromTypeAndName(type, name);
|
||||
if (actionId == null) {
|
||||
workerScript.log(errorLogText);
|
||||
return -1;
|
||||
}
|
||||
|
||||
var actionObj = this.getActionObject(actionId);
|
||||
if (actionObj == null) {
|
||||
workerScript.log(errorLogText);
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (actionId.type) {
|
||||
case ActionTypes["Contract"]:
|
||||
case ActionTypes["Operation"]:
|
||||
case ActionTypes["BlackOp"]:
|
||||
case ActionTypes["BlackOperation"]:
|
||||
return actionObj.count;
|
||||
case ActionTypes["Training"]:
|
||||
case ActionTypes["Field Analysis"]:
|
||||
case ActionTypes["FieldAnalysis"]:
|
||||
return Infinity;
|
||||
default:
|
||||
workerScript.log(errorLogText);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
Bladeburner.prototype.getSkillLevelNetscriptFn = function(skillName, workerScript) {
|
||||
var errorLogText = "ERROR: Bladeburner.getSkillLevel() failed due to an invalid skill specified: " +
|
||||
skillName + ". Note that the name of the skill is case-sensitive";
|
||||
|
||||
if (skillName === "") {
|
||||
//If skill name isn't specified, return an object with all of the player's skill levels
|
||||
let copy = Object.assign({}, this.Skills);
|
||||
return copy;
|
||||
}
|
||||
|
||||
if (!Skills.hasOwnProperty(skillName)) {
|
||||
workerScript.log(errorLogText);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return Skills[skillName];
|
||||
}
|
||||
|
||||
Bladeburner.prototype.upgradeSkillNetscriptFn = function(skillName, workerScript) {
|
||||
var errorLogText = "ERROR: Bladeburner.upgradeSkill() failed due to an invalid skill specified: " +
|
||||
skillName + ". Note that the name of the skill is case-sensitive";
|
||||
if (!Skills.hasOwnProperty(skillName)) {
|
||||
workerScript.log(errorLogText);
|
||||
return false;
|
||||
}
|
||||
|
||||
var skill = Skills[skillName];
|
||||
var currentLevel = 0;
|
||||
if (this.skills[skillName] && !isNaN(this.skills[skillName])) {
|
||||
currentLevel = this.skills[skillName];
|
||||
}
|
||||
var cost = skill.baseCost + (currentLevel * skill.costInc);
|
||||
|
||||
if (this.skillPoints < cost) {
|
||||
if (workerScript.shouldLog("upgradeSkill")) {
|
||||
workerScript.log("Bladeburner.upgradeSkill() failed because you do not have enough " +
|
||||
"skill points to upgrade " + skillName + " (You have " +
|
||||
this.skillPoints + ", you need " + cost + ")");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
this.skillPoints -= cost;
|
||||
this.upgradeSkill(skill);
|
||||
if (Engine.currentPage === Engine.Page.Bladeburner && DomElems.currentTab.toLowerCase() === "skills") {
|
||||
this.createActionAndSkillsContent();
|
||||
}
|
||||
if (workerScript.shouldLog("upgradeSkill")) {
|
||||
workerScript.log(skillName + " successfully upgraded to level " + this.skills[skillName]);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Bladeburner.prototype.getTeamSizeNetscriptFn = function(type, name, workerScript) {
|
||||
if (type === "" && name === "") {
|
||||
return this.teamSize;
|
||||
}
|
||||
|
||||
var errorLogText = "ERROR: Bladeburner.getTeamSize() failed due to an invalid action specified. " +
|
||||
"Type: " + type + ", Name: " + name + ". Note that for contracts and operations, the " +
|
||||
"name of the operation is case-sensitive.";
|
||||
|
||||
var actionId = this.getActionIdFromTypeAndName(type, name);
|
||||
if (actionId == null) {
|
||||
workerScript.log(errorLogText);
|
||||
return -1;
|
||||
}
|
||||
|
||||
var actionObj = this.getActionObject(actionId);
|
||||
if (actionObj == null) {
|
||||
workerScript.log(errorLogText);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (actionId.type === ActionTypes["Operation"] ||
|
||||
actionId.type === ActionTypes["BlackOp"] ||
|
||||
actionId.type === ActionTypes["BlackOperation"]) {
|
||||
return actionObj.teamCount;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
Bladeburner.prototype.setTeamSizeNetscriptFn = function(type, name, size, workerScript) {
|
||||
var errorLogText = "ERROR: Bladeburner.setTeamSize() failed due to an invalid action specified. " +
|
||||
"Type: " + type + ", Name: " + name + ". Note that for contracts and operations, the " +
|
||||
"name of the operation is case-sensitive.";
|
||||
var actionId = this.getActionIdFromTypeAndName(type, name);
|
||||
if (actionId == null) {
|
||||
workerScript.log(errorLogText);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (actionId.type !== ActionTypes["Operation"] ||
|
||||
actionId.type !== ActionTypes["BlackOp"] ||
|
||||
actionId.type !== ActionTypes["BlackOperation"]) {
|
||||
workerScript.log("ERROR: Bladeburner.setTeamSize() failed. This function " +
|
||||
"only works for Operations and BlackOps");
|
||||
return -1;
|
||||
}
|
||||
|
||||
var actionObj = this.getActionObject(actionId);
|
||||
if (actionObj == null) {
|
||||
workerScript.log(errorLogText);
|
||||
return -1;
|
||||
}
|
||||
|
||||
var sanitizedSize = Math.round(size);
|
||||
if (isNaN(sanitizedSize)) {
|
||||
workerScript.log("ERROR: Bladeburner.setTeamSize() failed due to an invalid 'size' argument: " + size);
|
||||
return -1;
|
||||
}
|
||||
if (this.teamSize < sanitizedSize) {sanitizedSize = this.teamSize;}
|
||||
actionObj.teamCount = sanitizedSize;
|
||||
if (workerScript.shouldLog("setTeamSize")) {
|
||||
workerScript.log("Team size for " + name + " set to " + sanitizedSize);
|
||||
}
|
||||
return sanitizedSize;
|
||||
}
|
||||
|
||||
Bladeburner.prototype.getCityEstimatedPopulationNetscriptFn = function(cityName, workerScript) {
|
||||
if (!this.cities.hasOwnProperty(cityName)) {
|
||||
workerScript.log("ERROR: Bladeburner.getCityEstimatedPopulation() failed because the specified " +
|
||||
"city was invalid: " + cityName + ". Note that this city argument is case-sensitive");
|
||||
return -1;
|
||||
}
|
||||
return this.cities[cityName].popEst;
|
||||
}
|
||||
|
||||
Bladeburner.prototype.getCityEstimatedCommunitiesNetscriptFn = function(cityName, workerScript) {
|
||||
if (!this.cities.hasOwnProperty(cityName)) {
|
||||
workerScript.log("ERROR: Bladeburner.getCityEstimatedCommunities() failed because the specified " +
|
||||
"city was invalid: " + cityName + ". Note that this city argument is case-sensitive");
|
||||
return -1;
|
||||
}
|
||||
return this.cities[cityName].commsEst;
|
||||
}
|
||||
|
||||
Bladeburner.prototype.getCityChaosNetscriptFn = function(cityName, workerScript) {
|
||||
if (!this.cities.hasOwnProperty(cityName)) {
|
||||
workerScript.log("ERROR: Bladeburner.getCityChaos() failed because the specified " +
|
||||
"city was invalid: " + cityName + ". Note that this city argument is case-sensitive");
|
||||
return -1;
|
||||
}
|
||||
return this.cities[cityName].chaos;
|
||||
}
|
||||
|
||||
Bladeburner.prototype.switchCityNetscriptFn = function(cityName, workerScript) {
|
||||
if (!this.cities.hasOwnProperty(cityName)) {
|
||||
workerScript.log("ERROR: Bladeburner.switchCity() failed because the specified " +
|
||||
"city was invalid: " + cityName + ". Note that this city argument is case-sensitive");
|
||||
return false;
|
||||
}
|
||||
this.city = cityName;
|
||||
return true;
|
||||
}
|
||||
|
||||
Bladeburner.prototype.joinBladeburnerFactionNetscriptFn = function(workerScript) {
|
||||
var bladeburnerFac = Factions["Bladeburners"];
|
||||
if (bladeburnerFac.isMember) {
|
||||
return true;
|
||||
} else if (this.rank >= RankNeededForFaction) {
|
||||
joinFaction(bladeburnerFac);
|
||||
if (workerScript.shouldLog("joinBladeburnerFaction")) {
|
||||
workerScript.log("Joined Bladeburners Faction");
|
||||
}
|
||||
if (Engine.currentPage === Engine.Page.Bladeburner) {
|
||||
removeChildrenFromElement(DomElems.overviewDiv);
|
||||
this.createOverviewContent();
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
if (workerScript.shouldLog("joinBladeburnerFaction")) {
|
||||
workerScript.log("Failed to join Bladeburners Faction because " +
|
||||
"you do not have the required " + RankNeededForFaction + " rank");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Bladeburner.prototype.toJSON = function() {
|
||||
return Generic_toJSON("Bladeburner", this);
|
||||
@ -3271,7 +3715,7 @@ function initBladeburner() {
|
||||
"Zenyatta and RedWater by any means necessary. After the task " +
|
||||
"is completed, the actions must be covered up from the general public.",
|
||||
baseDifficulty:2000, reqdRank:2.5e3,
|
||||
rankGain:25, rankLoss:10, hpLoss:100,
|
||||
rankGain:50, rankLoss:10, hpLoss:100,
|
||||
weights:{hack:0.1,str:0.2,def:0.2,dex:0.2,agi:0.2,cha:0, int:0.1},
|
||||
decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75},
|
||||
isKill:true
|
||||
@ -3288,7 +3732,7 @@ function initBladeburner() {
|
||||
"fabricated as a last resort. Be warned that AeroCorp has some of " +
|
||||
"the most advanced security measures in the world.",
|
||||
baseDifficulty:2500, reqdRank:5e3,
|
||||
rankGain:30, rankLoss:15, hpLoss:50,
|
||||
rankGain:60, rankLoss:15, hpLoss:50,
|
||||
weights:{hack:0.2,str:0.15,def:0.15,dex:0.2,agi:0.2,cha:0, int:0.1},
|
||||
decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75},
|
||||
isStealth:true
|
||||
@ -3307,7 +3751,7 @@ function initBladeburner() {
|
||||
"investigate the sewer systems, and eliminate Samizdat. They must " +
|
||||
"never publish anything again.",
|
||||
baseDifficulty:3000, reqdRank:7.5e3,
|
||||
rankGain:30, rankLoss:15, hpLoss:100,
|
||||
rankGain:75, rankLoss:15, hpLoss:100,
|
||||
weights:{hack:0.1,str:0.2,def:0.2,dex:0.2,agi:0.2,cha:0, int:0.1},
|
||||
decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75},
|
||||
isKill:true
|
||||
@ -3325,7 +3769,7 @@ function initBladeburner() {
|
||||
"also to destroy any information or research at the facility that " +
|
||||
"is relevant to the Synthoids and their goals.",
|
||||
baseDifficulty:4000, reqdRank:10e3,
|
||||
rankGain:40, rankLoss:20, hpLoss:100,
|
||||
rankGain:100, rankLoss:20, hpLoss:100,
|
||||
weights:{hack:0.1,str:0.2,def:0.2,dex:0.2,agi:0.2,cha:0, int:0.1},
|
||||
decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75},
|
||||
isKill:true
|
||||
@ -3339,7 +3783,7 @@ function initBladeburner() {
|
||||
"that this deal does not happen.<br><br>" +
|
||||
"Your task is to intercept the deal. Leave no survivors.",
|
||||
baseDifficulty:5000, reqdRank:12.5e3,
|
||||
rankGain:40, rankLoss:20, hpLoss:200,
|
||||
rankGain:125, rankLoss:20, hpLoss:200,
|
||||
weights:{hack:0,str:0.25,def:0.25,dex:0.25,agi:0.25,cha:0, int:0},
|
||||
decays:{hack:0,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75},
|
||||
isKill:true
|
||||
@ -3354,7 +3798,7 @@ function initBladeburner() {
|
||||
"the Red Rabbit brothel. Try to limit the number of other casualties, " +
|
||||
"but do what you must to complete the mission.",
|
||||
baseDifficulty:7500, reqdRank:15e3,
|
||||
rankGain:50, rankLoss:20, hpLoss:25,
|
||||
rankGain:200, rankLoss:20, hpLoss:25,
|
||||
weights:{hack:0,str:0.2,def:0.2,dex:0.3,agi:0.3,cha:0, int:0},
|
||||
decays:{hack:0,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75},
|
||||
isKill:true,
|
||||
@ -3371,7 +3815,7 @@ function initBladeburner() {
|
||||
"have thus enlisted our help.<br><br>" +
|
||||
"Your mission is to eradicate Juggernaut and his followers.",
|
||||
baseDifficulty:10e3, reqdRank:20e3,
|
||||
rankGain:75, rankLoss:40, hpLoss:300,
|
||||
rankGain:300, rankLoss:40, hpLoss:300,
|
||||
weights:{hack:0,str:0.25,def:0.25,dex:0.25,agi:0.25,cha:0, int:0},
|
||||
decays:{hack:0,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75},
|
||||
isKill:true,
|
||||
@ -3387,7 +3831,7 @@ function initBladeburner() {
|
||||
"in Los Angeles. Intelligence tells us that their base houses " +
|
||||
"one of their Synthoid manufacturing units.",
|
||||
baseDifficulty:12.5e3, reqdRank:25e3,
|
||||
rankGain:100, rankLoss:50, hpLoss:500,
|
||||
rankGain:500, rankLoss:50, hpLoss:500,
|
||||
weights:{hack:0.05,str:0.2,def:0.2,dex:0.25,agi:0.25,cha:0, int:0.05},
|
||||
decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75},
|
||||
isKill:true,
|
||||
@ -3407,7 +3851,7 @@ function initBladeburner() {
|
||||
"operation. Your goal is to destroy this technology and eliminate" +
|
||||
"anyone who was involved in its creation.",
|
||||
baseDifficulty:15e3, reqdRank:30e3,
|
||||
rankGain:120, rankLoss:60, hpLoss:1000,
|
||||
rankGain:750, rankLoss:60, hpLoss:1000,
|
||||
weights:{hack:0.05,str:0.2,def:0.2,dex:0.25,agi:0.25,cha:0, int:0.05},
|
||||
decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75},
|
||||
isKill:true
|
||||
@ -3422,7 +3866,7 @@ function initBladeburner() {
|
||||
"The goal of Operation Deckard is to hunt down these Synthoids and retire " +
|
||||
"them. I don't need to tell you how critical this mission is.",
|
||||
baseDifficulty:20e3, reqdRank:40e3,
|
||||
rankGain:150, rankLoss:75, hpLoss:200,
|
||||
rankGain:1e3, rankLoss:75, hpLoss:200,
|
||||
weights:{hack:0,str:0.24,def:0.24,dex:0.24,agi:0.24,cha:0, int:0.04},
|
||||
decays:{hack:0,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75},
|
||||
isKill:true,
|
||||
@ -3438,7 +3882,7 @@ function initBladeburner() {
|
||||
"with Augmentations. Your task is to hunt down the associated Dark Army " +
|
||||
"members and eliminate them.",
|
||||
baseDifficulty:25e3, reqdRank:50e3,
|
||||
rankGain:200, rankLoss:100, hpLoss:500,
|
||||
rankGain:1.5e3, rankLoss:100, hpLoss:500,
|
||||
weights:{hack:0.1,str:0.2,def:0.2,dex:0.2,agi:0.2,cha:0, int:0.1},
|
||||
decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75},
|
||||
isKill:true,
|
||||
@ -3457,7 +3901,7 @@ function initBladeburner() {
|
||||
"The goal of Operation Wallace is to destroy the Dark Army and " +
|
||||
"Syndicate factions in Aevum immediately. Leave no survivors.",
|
||||
baseDifficulty:30e3, reqdRank:75e3,
|
||||
rankGain:500, rankLoss:150, hpLoss:1500,
|
||||
rankGain:2e3, rankLoss:150, hpLoss:1500,
|
||||
weights:{hack:0,str:0.24,def:0.24,dex:0.24,agi:0.24,cha:0, int:0.04},
|
||||
decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75},
|
||||
isKill:true
|
||||
@ -3473,7 +3917,7 @@ function initBladeburner() {
|
||||
"successfully return. In the event of failure, all of the operation's " +
|
||||
"team members must not let themselves be captured alive.",
|
||||
baseDifficulty:35e3, reqdRank:100e3,
|
||||
rankGain:1e3, rankLoss:500, hpLoss:1500,
|
||||
rankGain:2.5e3, rankLoss:500, hpLoss:1500,
|
||||
weights:{hack:0.1,str:0.2,def:0.2,dex:0.2,agi:0.2,cha:0, int:0.1},
|
||||
decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75},
|
||||
isStealth:true
|
||||
@ -3495,7 +3939,7 @@ function initBladeburner() {
|
||||
"Infiltrate the compound, delete and destroy the work, and then find and kill the " +
|
||||
"project lead.",
|
||||
baseDifficulty:40e3, reqdRank:125e3,
|
||||
rankGain:2e3, rankLoss:1e3, hpLoss:500,
|
||||
rankGain:3e3, rankLoss:1e3, hpLoss:500,
|
||||
weights:{hack:0.1,str:0.2,def:0.2,dex:0.2,agi:0.2,cha:0, int:0.1},
|
||||
decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75},
|
||||
isKill:true
|
||||
@ -3512,7 +3956,7 @@ function initBladeburner() {
|
||||
"The mission is to destroy this broadcast tower. Speed and " +
|
||||
"stealth are of the upmost important for this.",
|
||||
baseDifficulty:45e3, reqdRank:150e3,
|
||||
rankGain:5e3, rankLoss:1e3, hpLoss:100,
|
||||
rankGain:4e3, rankLoss:1e3, hpLoss:100,
|
||||
weights:{hack:0.05,str:0.15,def:0.15,dex:0.3,agi:0.3,cha:0, int:0.05},
|
||||
decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75},
|
||||
isStealth:true
|
||||
@ -3541,7 +3985,7 @@ function initBladeburner() {
|
||||
"'The Covenant'. We have no prior intelligence about this " +
|
||||
"organization, so you are going in blind.",
|
||||
baseDifficulty:55e3, reqdRank:200e3,
|
||||
rankGain:5e3, rankLoss:1e3, hpLoss:10e3,
|
||||
rankGain:7.5e3, rankLoss:1e3, hpLoss:10e3,
|
||||
weights:{hack:0,str:0.24,def:0.24,dex:0.24,agi:0.24,cha:0, int:0.04},
|
||||
decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75},
|
||||
isKill:true
|
||||
|
@ -13,7 +13,7 @@ import {getRandomInt, removeElementById,
|
||||
clearSelector} from "../utils/HelperFunctions.js";
|
||||
import {Reviver, Generic_toJSON,
|
||||
Generic_fromJSON} from "../utils/JSONReviver.js";
|
||||
import numeral from "../utils/numeral.min.js";
|
||||
import numeral from "numeral/min/numeral.min";
|
||||
import {formatNumber, isString, generateRandomString} from "../utils/StringHelperFunctions.js";
|
||||
import {yesNoBoxCreate, yesNoTxtInpBoxCreate,
|
||||
yesNoBoxGetYesButton, yesNoBoxGetNoButton,
|
||||
|
@ -1,5 +1,5 @@
|
||||
let CONSTANTS = {
|
||||
Version: "0.37.2",
|
||||
Version: "0.38.0",
|
||||
|
||||
//Max level for any skill, assuming no multipliers. Determined by max numerical value in javascript for experience
|
||||
//and the skill level formula in Player.js. Note that all this means it that when experience hits MAX_INT, then
|
||||
@ -14,6 +14,8 @@ let CONSTANTS = {
|
||||
BaseCostFor1GBOfRamServer: 55000, //1 GB of RAM
|
||||
BaseCostFor1GBOfRamHacknetNode: 30000,
|
||||
|
||||
TravelCost: 200000,
|
||||
|
||||
BaseCostForHacknetNode: 1000,
|
||||
BaseCostForHacknetNodeCore: 500000,
|
||||
|
||||
@ -79,6 +81,8 @@ let CONSTANTS = {
|
||||
ScriptSingularityFn2RamCost: 2,
|
||||
ScriptSingularityFn3RamCost: 3,
|
||||
|
||||
ScriptBladeburnerApiBaseRamCost: 4,
|
||||
|
||||
MultithreadingRAMCost: 1,
|
||||
|
||||
NumNetscriptPorts: 20,
|
||||
@ -484,13 +488,20 @@ let CONSTANTS = {
|
||||
"World Stock Exchange account and TIX API Access<br>",
|
||||
|
||||
LatestUpdate:
|
||||
"v0.37.2<br>" +
|
||||
"* After joining the Bladeburners division, there is now a button to go to the Bladeburner content " +
|
||||
"in the 'City' page<br>" +
|
||||
"* You now start with $250m in BitNode-8 (increased from $100m)<br>" +
|
||||
"* Bug Fix: You can now no longer directly edit Hacknet Node values through NetscriptJS (hopefully)<br>" +
|
||||
"* Bug Fix: Bladeburners is no longer accessible in BN-8<br>" +
|
||||
"* Bug Fix: getBitNodeMultipliers() Netscript function now returns a copy rather than the original object<br>"
|
||||
"v0.38.0<br>" +
|
||||
"* New BitNode: BN-12 The Recursion - Implemented by Github user hydroflame<br>" +
|
||||
"* Bladeburner Changes:<br>" +
|
||||
"*** Bladeburner progress is no longer reset when installing Augmentations<br>" +
|
||||
"*** The number of successess needed to increase a Contract/Operation's max level now scales with the current max level (gradually gets harder)<br>" +
|
||||
"*** All Bladeburner Augmentations are now slightly more expensive and require more reputation<br>" +
|
||||
"*** Black Operations now give higher rank rewards<br>" +
|
||||
"*** Doubled the base amount of money gained from Contracts<br>" +
|
||||
"*** Increased the amount of experience gained from Contracts/Actions<br>" +
|
||||
"*** Added a new Augmentation: The Blade's Simulacrum<br>" +
|
||||
"*** Bladeburner faction reputation gain is now properly affected by favor<br>" +
|
||||
"* Hacking is now slightly less profitable in BitNode-3<br>" +
|
||||
"* Updated Hacknet Nodes UI - Implemented by Github user kopelli<br>" +
|
||||
"* Bug Fix: Fixed an exploit that allowed calling any Netscript function without incurring any RAM Cost in NetscriptJS<br>"
|
||||
}
|
||||
|
||||
export {CONSTANTS};
|
||||
|
494
src/Crimes.js
494
src/Crimes.js
@ -2,146 +2,235 @@ import {CONSTANTS} from "./Constants.js";
|
||||
import {Player} from "./Player.js";
|
||||
import {dialogBoxCreate} from "../utils/DialogBox.js";
|
||||
|
||||
/* Crimes.js */
|
||||
function commitShopliftCrime(div=1, singParams=null) {
|
||||
if (div <= 0) {div = 1;}
|
||||
Player.crimeType = CONSTANTS.CrimeShoplift;
|
||||
var time = 2000;
|
||||
Player.startCrime(0, 0, 0, 2/div, 2/div, 0, 15000/div, time, singParams); //$7500/s, 1 exp/s
|
||||
return time;
|
||||
|
||||
function Crime(name, type, time, money, difficulty, karma, params) {
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.time = time;
|
||||
this.money = money;
|
||||
this.difficulty = difficulty;
|
||||
this.karma = karma;
|
||||
|
||||
this.hacking_success_weight = params.hacking_success_weight ? params.hacking_success_weight : 0;
|
||||
this.strength_success_weight = params.strength_success_weight ? params.strength_success_weight : 0;
|
||||
this.defense_success_weight = params.defense_success_weight ? params.defense_success_weight : 0;
|
||||
this.dexterity_success_weight = params.dexterity_success_weight ? params.dexterity_success_weight : 0;
|
||||
this.agility_success_weight = params.agility_success_weight ? params.agility_success_weight : 0;
|
||||
this.charisma_success_weight = params.charisma_success_weight ? params.charisma_success_weight : 0;
|
||||
|
||||
this.hacking_exp = params.hacking_exp ? params.hacking_exp : 0;
|
||||
this.strength_exp = params.strength_exp ? params.strength_exp : 0;
|
||||
this.defense_exp = params.defense_exp ? params.defense_exp : 0;
|
||||
this.dexterity_exp = params.dexterity_exp ? params.dexterity_exp : 0;
|
||||
this.agility_exp = params.agility_exp ? params.agility_exp : 0;
|
||||
this.charisma_exp = params.charisma_exp ? params.charisma_exp : 0;
|
||||
this.intelligence_exp = params.intelligence_exp ? params.intelligence_exp : 0;
|
||||
|
||||
this.kills = params.kills ? params.kills : 0;
|
||||
}
|
||||
|
||||
function commitRobStoreCrime(div=1, singParams=null) {
|
||||
if (div <= 0) {div = 1;}
|
||||
Player.crimeType = CONSTANTS.CrimeRobStore;
|
||||
var time = 60000;
|
||||
Player.startCrime(30/div, 0, 0, 45/div, 45/div, 0, 400000/div, time, singParams); //$6666,6/2, 0.5exp/s, 0.75exp/s
|
||||
return time;
|
||||
Crime.prototype.commit = function(div=1, singParams=null) {
|
||||
if (div <= 0) {div = 1;}
|
||||
Player.crimeType = this.type;
|
||||
Player.startCrime(
|
||||
this.hacking_exp/div,
|
||||
this.strength_exp/div,
|
||||
this.defense_exp/div,
|
||||
this.dexterity_exp/div,
|
||||
this.agility_exp/div,
|
||||
this.charisma_exp/div,
|
||||
this.money/div, this.time, singParams);
|
||||
return this.time;
|
||||
}
|
||||
|
||||
function commitMugCrime(div=1, singParams=null) {
|
||||
if (div <= 0) {div = 1;}
|
||||
Player.crimeType = CONSTANTS.CrimeMug;
|
||||
var time = 4000;
|
||||
Player.startCrime(0, 3/div, 3/div, 3/div, 3/div, 0, 36000/div, time, singParams); //$9000/s, .66 exp/s
|
||||
return time;
|
||||
Crime.prototype.successRate = function() {
|
||||
var chance = (this.hacking_success_weight * Player.hacking_skill +
|
||||
this.strength_success_weight * Player.strength +
|
||||
this.defense_success_weight * Player.defense +
|
||||
this.dexterity_success_weight * Player.dexterity +
|
||||
this.agility_success_weight * Player.agility +
|
||||
this.charisma_success_weight * Player.charisma +
|
||||
CONSTANTS.IntelligenceCrimeWeight * Player.intelligence);
|
||||
chance /= CONSTANTS.MaxSkillLevel;
|
||||
chance /= this.difficulty;
|
||||
chance *= Player.crime_success_mult;
|
||||
return Math.min(chance, 1);
|
||||
}
|
||||
|
||||
function commitLarcenyCrime(div=1, singParams=null) {
|
||||
if (div <= 0) {div = 1;}
|
||||
Player.crimeType = CONSTANTS.CrimeLarceny;
|
||||
var time = 90000;
|
||||
Player.startCrime(45/div, 0, 0, 60/div, 60/div, 0, 800000/div, time, singParams) // $8888.88/s, .5 exp/s, .66 exp/s
|
||||
return time;
|
||||
}
|
||||
const Crimes = {
|
||||
Shoplift: new Crime("Shoplift", CONSTANTS.CrimeShoplift, 2e3, 15e3, 1/20, 0.1, {
|
||||
dexterity_success_weight: 1,
|
||||
agility_success_weight: 1,
|
||||
|
||||
function commitDealDrugsCrime(div=1, singParams=null) {
|
||||
if (div <= 0) {div = 1;}
|
||||
Player.crimeType = CONSTANTS.CrimeDrugs;
|
||||
var time = 10000;
|
||||
Player.startCrime(0, 0, 0, 5/div, 5/div, 10/div, 120000/div, time, singParams); //$12000/s, .5 exp/s, 1 exp/s
|
||||
return time;
|
||||
}
|
||||
dexterity_exp: 2,
|
||||
agility_exp: 2,
|
||||
}),
|
||||
|
||||
function commitBondForgeryCrime(div=1, singParams=null) {
|
||||
if (div <= 0) {div = 1;}
|
||||
Player.crimeType = CONSTANTS.CrimeBondForgery;
|
||||
var time = 300000;
|
||||
Player.startCrime(100/div, 0, 0, 150/div, 0, 15/div, 4500000/div, time, singParams); //$15000/s, 0.33 hack exp/s, .5 dex exp/s, .05 cha exp
|
||||
return time;
|
||||
}
|
||||
RobStore: new Crime("Rob Store", CONSTANTS.CrimeRobStore, 60e3, 400e3, 1/5, 0.5, {
|
||||
hacking_exp: 30,
|
||||
dexterity_exp: 45,
|
||||
agility_exp: 45,
|
||||
|
||||
function commitTraffickArmsCrime(div=1, singParams=null) {
|
||||
if (div <= 0) {div = 1;}
|
||||
Player.crimeType = CONSTANTS.CrimeTraffickArms;
|
||||
var time = 40000;
|
||||
Player.startCrime(0, 20/div, 20/div, 20/div, 20/div, 40/div, 600000/div, time, singParams); //$15000/s, .5 combat exp/s, 1 cha exp/s
|
||||
return time;
|
||||
}
|
||||
hacking_success_weight: 0.5 ,
|
||||
dexterity_success_weight: 2,
|
||||
agility_success_weight: 1,
|
||||
|
||||
function commitHomicideCrime(div=1, singParams=null) {
|
||||
if (div <= 0) {div = 1;}
|
||||
Player.crimeType = CONSTANTS.CrimeHomicide;
|
||||
var time = 3000;
|
||||
Player.startCrime(0, 2/div, 2/div, 2/div, 2/div, 0, 45000/div, time, singParams); //$15000/s, 0.66 combat exp/s
|
||||
return time;
|
||||
}
|
||||
intelligence_exp: 0.25 * CONSTANTS.IntelligenceCrimeBaseExpGain,
|
||||
}),
|
||||
|
||||
function commitGrandTheftAutoCrime(div=1, singParams=null) {
|
||||
if (div <= 0) {div = 1;}
|
||||
Player.crimeType = CONSTANTS.CrimeGrandTheftAuto;
|
||||
var time = 80000;
|
||||
Player.startCrime(0, 20/div, 20/div, 20/div, 80/div, 40/div, 1600000/div, time, singParams); //$20000/s, .25 exp/s, 1 exp/s, .5 exp/s
|
||||
return time;
|
||||
}
|
||||
Mug: new Crime("Mug", CONSTANTS.CrimeMug, 4e3, 36e3, 1/5, 0.25, {
|
||||
strength_exp: 3,
|
||||
defense_exp: 3,
|
||||
dexterity_exp: 3,
|
||||
agility_exp: 3,
|
||||
|
||||
function commitKidnapCrime(div=1, singParams=null) {
|
||||
if (div <= 0) {div = 1;}
|
||||
Player.crimeType = CONSTANTS.CrimeKidnap;
|
||||
var time = 120000;
|
||||
Player.startCrime(0, 80/div, 80/div, 80/div, 80/div, 80/div, 3600000/div, time, singParams); //$30000/s. .66 exp/s
|
||||
return time;
|
||||
}
|
||||
strength_success_weight: 1.5,
|
||||
defense_success_weight: 0.5,
|
||||
dexterity_success_weight: 1.5,
|
||||
agility_success_weight: 0.5,
|
||||
}),
|
||||
|
||||
function commitAssassinationCrime(div=1, singParams=null) {
|
||||
if (div <= 0) {div = 1;}
|
||||
Player.crimeType = CONSTANTS.CrimeAssassination;
|
||||
var time = 300000;
|
||||
Player.startCrime(0, 300/div, 300/div, 300/div, 300/div, 0, 12000000/div, time, singParams); //$40000/s, 1 exp/s
|
||||
return time;
|
||||
}
|
||||
Larceny: new Crime("Larceny", CONSTANTS.CrimeLarceny, 90e3, 800e3, 1/3, 1.5, {
|
||||
hacking_exp: 45,
|
||||
dexterity_exp: 60,
|
||||
agility_exp: 60,
|
||||
|
||||
function commitHeistCrime(div=1, singParams=null) {
|
||||
if (div <= 0) {div = 1;}
|
||||
Player.crimeType = CONSTANTS.CrimeHeist;
|
||||
var time = 600000;
|
||||
Player.startCrime(450/div, 450/div, 450/div, 450/div, 450/div, 450/div, 120000000/div, time, singParams); //$200000/s, .75exp/s
|
||||
return time;
|
||||
}
|
||||
hacking_skill_success_weight: 0.5,
|
||||
dexterity_success_weight: 1,
|
||||
agility_success_weight: 1,
|
||||
|
||||
function determineCrimeSuccess(crime, moneyGained) {
|
||||
intelligence_exp: 0.5 * CONSTANTS.IntelligenceCrimeBaseExpGain,
|
||||
}),
|
||||
|
||||
DealDrugs: new Crime("Deal Drugs", CONSTANTS.CrimeDrugs, 10e3, 120e3, 1, 0.5, {
|
||||
dexterity_exp: 5,
|
||||
agility_exp: 5,
|
||||
charisma_exp: 10,
|
||||
|
||||
charisma_success_weight: 3,
|
||||
dexterity_success_weight: 2,
|
||||
agility_success_weight: 1,
|
||||
}),
|
||||
|
||||
BondForgery: new Crime("Bond Forgery", CONSTANTS.CrimeBondForgery, 300e3, 4.5e6, 1/2, 0.1, {
|
||||
hacking_exp: 100,
|
||||
dexterity_exp: 150,
|
||||
charisma_exp: 15,
|
||||
|
||||
hacking_skill_success_weight: 0.05,
|
||||
dexterity_success_weight: 1.25,
|
||||
|
||||
intelligence_exp: 2 * CONSTANTS.IntelligenceCrimeBaseExpGain,
|
||||
}),
|
||||
|
||||
TraffickArms: new Crime("Traffick Arms", CONSTANTS.CrimeTraffickArms, 40e3, 600e3, 2, 1, {
|
||||
strength_exp: 20,
|
||||
defense_exp: 20,
|
||||
dexterity_exp: 20,
|
||||
agility_exp: 20,
|
||||
charisma_exp: 40,
|
||||
|
||||
charisma_success_weight: 1,
|
||||
strength_success_weight: 1,
|
||||
defense_success_weight: 1,
|
||||
dexterity_success_weight: 1,
|
||||
agility_success_weight: 1,
|
||||
}),
|
||||
|
||||
Homicide: new Crime("Homicide", CONSTANTS.CrimeHomicide, 3e3, 45e3, 1, 3, {
|
||||
strength_exp: 2,
|
||||
defense_exp: 2,
|
||||
dexterity_exp: 2,
|
||||
agility_exp: 2,
|
||||
|
||||
strength_success_weight: 2,
|
||||
defense_success_weight: 2,
|
||||
dexterity_success_weight: 0.5,
|
||||
agility_success_weight: 0.5,
|
||||
|
||||
kills: 1,
|
||||
}),
|
||||
|
||||
GrandTheftAuto: new Crime("Grand Theft Auto", CONSTANTS.CrimeGrandTheftAuto, 80e3, 1.6e6, 8, 5, {
|
||||
strength_exp: 20,
|
||||
defense_exp: 20,
|
||||
dexterity_exp: 20,
|
||||
agility_exp: 80,
|
||||
charisma_exp: 40,
|
||||
|
||||
hacking_skill_success_weight: 1,
|
||||
strength_success_weight: 1,
|
||||
dexterity_success_weight: 4,
|
||||
agility_success_weight: 2,
|
||||
charisma_success_weight: 2,
|
||||
|
||||
intelligence_exp: CONSTANTS.IntelligenceCrimeBaseExpGain,
|
||||
}),
|
||||
|
||||
Kidnap: new Crime("Kidnap", CONSTANTS.CrimeKidnap, 120e3, 3.6e6, 5, 6, {
|
||||
strength_exp: 80,
|
||||
defense_exp: 80,
|
||||
dexterity_exp: 80,
|
||||
agility_exp: 80,
|
||||
charisma_exp: 80,
|
||||
|
||||
charisma_success_weight: 1,
|
||||
strength_success_weight: 1,
|
||||
dexterity_success_weight: 1,
|
||||
agility_success_weight: 1,
|
||||
|
||||
intelligence_exp: 2 * CONSTANTS.IntelligenceCrimeBaseExpGain,
|
||||
}),
|
||||
|
||||
Assassination: new Crime("Assassination", CONSTANTS.CrimeAssassination, 300e3, 12e6, 8, 10, {
|
||||
strength_exp: 300,
|
||||
defense_exp: 300,
|
||||
dexterity_exp: 300,
|
||||
agility_exp: 300,
|
||||
|
||||
strength_success_weight: 1,
|
||||
dexterity_success_weight: 2,
|
||||
agility_success_weight: 1,
|
||||
|
||||
intelligence_exp: 5 * CONSTANTS.IntelligenceCrimeBaseExpGain,
|
||||
|
||||
kills: 1,
|
||||
}),
|
||||
|
||||
Heist: new Crime("Heist", CONSTANTS.CrimeHeist, 600e3, 120e6, 18, 15, {
|
||||
hacking_exp: 450,
|
||||
strength_exp: 450,
|
||||
defense_exp: 450,
|
||||
dexterity_exp: 450,
|
||||
agility_exp: 450,
|
||||
charisma_exp: 450,
|
||||
|
||||
hacking_skill_success_weight: 1,
|
||||
strength_success_weight: 1,
|
||||
defense_success_weight: 1,
|
||||
dexterity_success_weight: 1,
|
||||
agility_success_weight: 1,
|
||||
charisma_success_weight: 1,
|
||||
|
||||
intelligence_exp: 10 * CONSTANTS.IntelligenceCrimeBaseExpGain,
|
||||
}),
|
||||
};
|
||||
|
||||
function determineCrimeSuccess(type, moneyGained) {
|
||||
var chance = 0;
|
||||
switch (crime) {
|
||||
case CONSTANTS.CrimeShoplift:
|
||||
chance = determineCrimeChanceShoplift();
|
||||
break;
|
||||
case CONSTANTS.CrimeRobStore:
|
||||
chance = determineCrimeChanceRobStore();
|
||||
break;
|
||||
case CONSTANTS.CrimeMug:
|
||||
chance = determineCrimeChanceMug();
|
||||
break;
|
||||
case CONSTANTS.CrimeLarceny:
|
||||
chance = determineCrimeChanceLarceny();
|
||||
break;
|
||||
case CONSTANTS.CrimeDrugs:
|
||||
chance = determineCrimeChanceDealDrugs();
|
||||
break;
|
||||
case CONSTANTS.CrimeBondForgery:
|
||||
chance = determineCrimeChanceBondForgery();
|
||||
break;
|
||||
case CONSTANTS.CrimeTraffickArms:
|
||||
chance = determineCrimeChanceTraffickArms();
|
||||
break;
|
||||
case CONSTANTS.CrimeHomicide:
|
||||
chance = determineCrimeChanceHomicide();
|
||||
break;
|
||||
case CONSTANTS.CrimeGrandTheftAuto:
|
||||
chance = determineCrimeChanceGrandTheftAuto();
|
||||
break;
|
||||
case CONSTANTS.CrimeKidnap:
|
||||
chance = determineCrimeChanceKidnap();
|
||||
break;
|
||||
case CONSTANTS.CrimeAssassination:
|
||||
chance = determineCrimeChanceAssassination();
|
||||
break;
|
||||
case CONSTANTS.CrimeHeist:
|
||||
chance = determineCrimeChanceHeist();
|
||||
break;
|
||||
default:
|
||||
console.log(crime);
|
||||
dialogBoxCreate("ERR: Unrecognized crime type. This is probably a bug please contact the developer");
|
||||
return;
|
||||
var found = false;
|
||||
for(const i in Crimes) {
|
||||
const crime = Crimes[i];
|
||||
if(crime.type == type) {
|
||||
chance = crime.successRate();
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!found) {
|
||||
console.log(crime);
|
||||
dialogBoxCreate("ERR: Unrecognized crime type. This is probably a bug please contact the developer");
|
||||
return;
|
||||
}
|
||||
|
||||
if (Math.random() <= chance) {
|
||||
@ -154,134 +243,33 @@ function determineCrimeSuccess(crime, moneyGained) {
|
||||
}
|
||||
}
|
||||
|
||||
let intWgt = CONSTANTS.IntelligenceCrimeWeight;
|
||||
let maxLvl = CONSTANTS.MaxSkillLevel;
|
||||
|
||||
function determineCrimeChanceShoplift() {
|
||||
var chance = (Player.dexterity / maxLvl +
|
||||
Player.agility / maxLvl +
|
||||
intWgt * Player.intelligence / maxLvl) * 20;
|
||||
chance *= Player.crime_success_mult;
|
||||
return Math.min(chance, 1);
|
||||
function findCrime(roughName) {
|
||||
if (roughName.includes("shoplift")) {
|
||||
return Crimes.Shoplift;
|
||||
} else if (roughName.includes("rob") && roughName.includes("store")) {
|
||||
return Crimes.RobStore;
|
||||
} else if (roughName.includes("mug")) {
|
||||
return Crimes.Mug;
|
||||
} else if (roughName.includes("larceny")) {
|
||||
return Crimes.Larceny;
|
||||
} else if (roughName.includes("drugs")) {
|
||||
return Crimes.DealDrugs;
|
||||
} else if (roughName.includes("bond") && roughName.includes("forge")) {
|
||||
return Crimes.BondForgery;
|
||||
} else if (roughName.includes("traffick") && roughName.includes("arms")) {
|
||||
return Crimes.TraffickArms;
|
||||
} else if (roughName.includes("homicide")) {
|
||||
return Crimes.Homicide;
|
||||
} else if (roughName.includes("grand") && roughName.includes("auto")) {
|
||||
return Crimes.GrandTheftAuto;
|
||||
} else if (roughName.includes("kidnap")) {
|
||||
return Crimes.Kidnap;
|
||||
} else if (roughName.includes("assassinate")) {
|
||||
return Crimes.Assassination;
|
||||
} else if (roughName.includes("heist")) {
|
||||
return Crimes.Heist;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function determineCrimeChanceRobStore() {
|
||||
var chance = (0.5 * Player.hacking_skill / maxLvl +
|
||||
2 * Player.dexterity / maxLvl +
|
||||
1 * Player.agility / maxLvl +
|
||||
intWgt * Player.intelligence / maxLvl) * 5;
|
||||
chance *= Player.crime_success_mult;
|
||||
return Math.min(chance, 1);
|
||||
}
|
||||
|
||||
function determineCrimeChanceMug() {
|
||||
var chance = (1.5 * Player.strength / maxLvl +
|
||||
0.5 * Player.defense / maxLvl +
|
||||
1.5 * Player.dexterity / maxLvl +
|
||||
0.5 * Player.agility / maxLvl +
|
||||
intWgt * Player.intelligence / maxLvl) * 5;
|
||||
chance *= Player.crime_success_mult;
|
||||
return Math.min(chance, 1);
|
||||
}
|
||||
|
||||
function determineCrimeChanceLarceny() {
|
||||
var chance = (0.5 * Player.hacking_skill / maxLvl +
|
||||
Player.dexterity / maxLvl +
|
||||
Player.agility / maxLvl +
|
||||
intWgt * Player.intelligence / maxLvl) * 3;
|
||||
chance *= Player.crime_success_mult;
|
||||
return Math.min(chance, 1);
|
||||
}
|
||||
|
||||
function determineCrimeChanceDealDrugs() {
|
||||
var chance = (3*Player.charisma / maxLvl +
|
||||
2*Player.dexterity / maxLvl +
|
||||
Player.agility / maxLvl +
|
||||
intWgt * Player.intelligence / maxLvl);
|
||||
chance *= Player.crime_success_mult;
|
||||
return Math.min(chance, 1);
|
||||
}
|
||||
|
||||
function determineCrimeChanceBondForgery() {
|
||||
var chance = (0.1*Player.hacking_skill / maxLvl +
|
||||
2.5*Player.dexterity / maxLvl +
|
||||
2*intWgt*Player.intelligence / maxLvl);
|
||||
chance *= Player.crime_success_mult;
|
||||
return Math.min(chance, 1);
|
||||
}
|
||||
|
||||
function determineCrimeChanceTraffickArms() {
|
||||
var chance = (Player.charisma / maxLvl +
|
||||
Player.strength / maxLvl +
|
||||
Player.defense / maxLvl +
|
||||
Player.dexterity / maxLvl +
|
||||
Player.agility / maxLvl +
|
||||
intWgt * Player.intelligence / maxLvl) / 2;
|
||||
chance *= Player.crime_success_mult;
|
||||
return Math.min(chance, 1);
|
||||
}
|
||||
|
||||
function determineCrimeChanceHomicide() {
|
||||
var chance = (2 * Player.strength / maxLvl +
|
||||
2 * Player.defense / maxLvl +
|
||||
0.5 * Player.dexterity / maxLvl +
|
||||
0.5 * Player.agility / maxLvl +
|
||||
intWgt * Player.intelligence / maxLvl);
|
||||
chance *= Player.crime_success_mult;
|
||||
return Math.min(chance, 1);
|
||||
}
|
||||
|
||||
function determineCrimeChanceGrandTheftAuto() {
|
||||
var chance = (Player.hacking_skill / maxLvl +
|
||||
Player.strength / maxLvl +
|
||||
4 * Player.dexterity / maxLvl +
|
||||
2 * Player.agility / maxLvl +
|
||||
2 * Player.charisma / maxLvl +
|
||||
intWgt * Player.intelligence / maxLvl) / 8;
|
||||
chance *= Player.crime_success_mult;
|
||||
return Math.min(chance, 1);
|
||||
}
|
||||
|
||||
function determineCrimeChanceKidnap() {
|
||||
var chance = (Player.charisma / maxLvl +
|
||||
Player.strength / maxLvl +
|
||||
Player.dexterity / maxLvl +
|
||||
Player.agility / maxLvl +
|
||||
intWgt * Player.intelligence / maxLvl) / 5;
|
||||
chance *= Player.crime_success_mult;
|
||||
return Math.min(chance, 1);
|
||||
}
|
||||
|
||||
function determineCrimeChanceAssassination() {
|
||||
var chance = (Player.strength / maxLvl +
|
||||
2 * Player.dexterity / maxLvl +
|
||||
Player.agility / maxLvl +
|
||||
intWgt * Player.intelligence / maxLvl) / 8;
|
||||
chance *= Player.crime_success_mult;
|
||||
return Math.min(chance, 1);
|
||||
}
|
||||
|
||||
function determineCrimeChanceHeist() {
|
||||
var chance = (Player.hacking_skill / maxLvl +
|
||||
Player.strength / maxLvl +
|
||||
Player.defense / maxLvl +
|
||||
Player.dexterity / maxLvl +
|
||||
Player.agility / maxLvl +
|
||||
Player.charisma / maxLvl +
|
||||
intWgt * Player.intelligence / maxLvl) / 18;
|
||||
chance *= Player.crime_success_mult;
|
||||
return Math.min(chance, 1);
|
||||
}
|
||||
|
||||
export {commitShopliftCrime, commitRobStoreCrime, commitMugCrime,
|
||||
commitLarcenyCrime, commitDealDrugsCrime, commitBondForgeryCrime,
|
||||
commitTraffickArmsCrime,
|
||||
commitHomicideCrime, commitGrandTheftAutoCrime, commitKidnapCrime,
|
||||
commitAssassinationCrime, commitHeistCrime, determineCrimeSuccess,
|
||||
determineCrimeChanceShoplift, determineCrimeChanceRobStore,
|
||||
determineCrimeChanceMug, determineCrimeChanceLarceny,
|
||||
determineCrimeChanceDealDrugs, determineCrimeChanceBondForgery,
|
||||
determineCrimeChanceTraffickArms,
|
||||
determineCrimeChanceHomicide, determineCrimeChanceGrandTheftAuto,
|
||||
determineCrimeChanceKidnap, determineCrimeChanceAssassination,
|
||||
determineCrimeChanceHeist};
|
||||
export {determineCrimeSuccess,findCrime,Crimes};
|
||||
|
432
src/Faction.js
432
src/Faction.js
@ -3,7 +3,7 @@ import {Augmentations, AugmentationNames,
|
||||
import {BitNodeMultipliers} from "./BitNode.js";
|
||||
import {CONSTANTS} from "./Constants.js";
|
||||
import {Engine} from "./engine.js";
|
||||
import {FactionInfo} from "./FactionInfo.js";
|
||||
import {FactionInfos} from "./FactionInfo.js";
|
||||
import {Locations} from "./Location.js";
|
||||
import {HackingMission, setInMission} from "./Missions.js";
|
||||
import {Player} from "./Player.js";
|
||||
@ -15,7 +15,7 @@ import {clearEventListeners, createElement,
|
||||
removeChildrenFromElement} from "../utils/HelperFunctions.js";
|
||||
import {Reviver, Generic_toJSON,
|
||||
Generic_fromJSON} from "../utils/JSONReviver.js";
|
||||
import numeral from "../utils/numeral.min.js";
|
||||
import numeral from "numeral/min/numeral.min";
|
||||
import {formatNumber} from "../utils/StringHelperFunctions.js";
|
||||
import {yesNoBoxCreate, yesNoBoxGetYesButton,
|
||||
yesNoBoxGetNoButton, yesNoBoxClose} from "../utils/YesNoBox.js";
|
||||
@ -23,7 +23,6 @@ import {yesNoBoxCreate, yesNoBoxGetYesButton,
|
||||
function Faction(name="") {
|
||||
this.name = name;
|
||||
this.augmentations = []; //Name of augmentation only
|
||||
this.info = ""; //Introductory/informational text about the faction
|
||||
|
||||
//Player-related properties for faction
|
||||
this.isMember = false; //Whether player is member
|
||||
@ -31,22 +30,17 @@ function Faction(name="") {
|
||||
this.playerReputation = 0; //"Reputation" within faction
|
||||
this.alreadyInvited = false;
|
||||
|
||||
//Multipliers for unlocking and purchasing augmentations
|
||||
this.augmentationPriceMult = 1;
|
||||
this.augmentationRepRequirementMult = 1;
|
||||
|
||||
//Faction favor
|
||||
this.favor = 0;
|
||||
this.rolloverRep = 0;
|
||||
};
|
||||
|
||||
Faction.prototype.setAugmentationMultipliers = function(price, rep) {
|
||||
this.augmentationPriceMult = price;
|
||||
this.augmentationRepRequirementMult = rep;
|
||||
}
|
||||
|
||||
Faction.prototype.setInfo = function(inf) {
|
||||
this.info = inf;
|
||||
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() {
|
||||
@ -119,142 +113,9 @@ function factionExists(name) {
|
||||
//TODO Augmentation price and rep requirement mult are 1 for everything right now,
|
||||
// This might change in the future for balance
|
||||
function initFactions() {
|
||||
//Endgame
|
||||
var Illuminati = new Faction("Illuminati");
|
||||
Illuminati.setInfo(FactionInfo.IlluminatiInfo);
|
||||
resetFaction(Illuminati);
|
||||
|
||||
var Daedalus = new Faction("Daedalus");
|
||||
Daedalus.setInfo(FactionInfo.DaedalusInfo);
|
||||
resetFaction(Daedalus);
|
||||
|
||||
var Covenant = new Faction("The Covenant");
|
||||
Covenant.setInfo(FactionInfo.CovenantInfo);
|
||||
resetFaction(Covenant);
|
||||
|
||||
//Megacorporations, each forms its own faction
|
||||
var ECorp = new Faction("ECorp");
|
||||
ECorp.setInfo(FactionInfo.ECorpInfo);
|
||||
resetFaction(ECorp);
|
||||
|
||||
var MegaCorp = new Faction("MegaCorp");
|
||||
MegaCorp.setInfo(FactionInfo.MegaCorpInfo);
|
||||
resetFaction(MegaCorp);
|
||||
|
||||
var BachmanAndAssociates = new Faction("Bachman & Associates");
|
||||
BachmanAndAssociates.setInfo(FactionInfo.BachmanAndAssociatesInfo);
|
||||
resetFaction(BachmanAndAssociates);
|
||||
|
||||
var BladeIndustries = new Faction("Blade Industries");
|
||||
BladeIndustries.setInfo(FactionInfo.BladeIndustriesInfo);
|
||||
resetFaction(BladeIndustries);
|
||||
|
||||
var NWO = new Faction("NWO");
|
||||
NWO.setInfo(FactionInfo.NWOInfo);
|
||||
resetFaction(NWO);
|
||||
|
||||
var ClarkeIncorporated = new Faction("Clarke Incorporated");
|
||||
ClarkeIncorporated.setInfo(FactionInfo.ClarkeIncorporatedInfo);
|
||||
resetFaction(ClarkeIncorporated);
|
||||
|
||||
var OmniTekIncorporated = new Faction("OmniTek Incorporated");
|
||||
OmniTekIncorporated.setInfo(FactionInfo.OmniTekIncorporatedInfo);
|
||||
resetFaction(OmniTekIncorporated);
|
||||
|
||||
var FourSigma = new Faction("Four Sigma");
|
||||
FourSigma.setInfo(FactionInfo.FourSigmaInfo);
|
||||
resetFaction(FourSigma);
|
||||
|
||||
var KuaiGongInternational = new Faction("KuaiGong International");
|
||||
KuaiGongInternational.setInfo(FactionInfo.KuaiGongInternationalInfo);
|
||||
resetFaction(KuaiGongInternational);
|
||||
|
||||
//Other corporations
|
||||
var FulcrumTechnologies = new Faction("Fulcrum Secret Technologies");
|
||||
FulcrumTechnologies.setInfo(FactionInfo.FulcrumSecretTechnologiesInfo);
|
||||
resetFaction(FulcrumTechnologies);
|
||||
|
||||
//Hacker groups
|
||||
var BitRunners = new Faction("BitRunners");
|
||||
BitRunners.setInfo(FactionInfo.BitRunnersInfo);
|
||||
resetFaction(BitRunners);
|
||||
|
||||
var BlackHand = new Faction("The Black Hand");
|
||||
BlackHand.setInfo(FactionInfo.BlackHandInfo);
|
||||
resetFaction(BlackHand);
|
||||
|
||||
var NiteSec = new Faction("NiteSec");
|
||||
NiteSec.setInfo(FactionInfo.NiteSecInfo);
|
||||
resetFaction(NiteSec);
|
||||
|
||||
//City factions, essentially governments
|
||||
var Chongqing = new Faction("Chongqing");
|
||||
Chongqing.setInfo(FactionInfo.ChongqingInfo);
|
||||
resetFaction(Chongqing);
|
||||
|
||||
var Sector12 = new Faction("Sector-12");
|
||||
Sector12.setInfo(FactionInfo.Sector12Info);
|
||||
resetFaction(Sector12);
|
||||
|
||||
var NewTokyo = new Faction("New Tokyo");
|
||||
NewTokyo.setInfo(FactionInfo.NewTokyoInfo);
|
||||
resetFaction(NewTokyo);
|
||||
|
||||
var Aevum = new Faction("Aevum");
|
||||
Aevum.setInfo(FactionInfo.AevumInfo);
|
||||
resetFaction(Aevum);
|
||||
|
||||
var Ishima = new Faction("Ishima");
|
||||
Ishima.setInfo(FactionInfo.Ishima);
|
||||
resetFaction(Ishima);
|
||||
|
||||
var Volhaven = new Faction("Volhaven");
|
||||
Volhaven.setInfo(FactionInfo.VolhavenInfo);
|
||||
resetFaction(Volhaven);
|
||||
|
||||
//Criminal Organizations/Gangs
|
||||
var SpeakersForTheDead = new Faction("Speakers for the Dead");
|
||||
SpeakersForTheDead.setInfo(FactionInfo.SpeakersForTheDeadInfo);
|
||||
resetFaction(SpeakersForTheDead);
|
||||
|
||||
var DarkArmy = new Faction("The Dark Army");
|
||||
DarkArmy.setInfo(FactionInfo.DarkArmyInfo);
|
||||
resetFaction(DarkArmy);
|
||||
|
||||
var TheSyndicate = new Faction("The Syndicate");
|
||||
TheSyndicate.setInfo(FactionInfo.TheSyndicateInfo);
|
||||
resetFaction(TheSyndicate);
|
||||
|
||||
var Silhouette = new Faction("Silhouette");
|
||||
Silhouette.setInfo(FactionInfo.SilhouetteInfo);
|
||||
resetFaction(Silhouette);
|
||||
|
||||
var Tetrads = new Faction("Tetrads"); //Low-medium level asian crime gang
|
||||
Tetrads.setInfo(FactionInfo.TetradsInfo);
|
||||
resetFaction(Tetrads);
|
||||
|
||||
var SlumSnakes = new Faction("Slum Snakes"); //Low level crime gang
|
||||
SlumSnakes.setInfo(FactionInfo.SlumSnakesInfo);
|
||||
resetFaction(SlumSnakes);
|
||||
|
||||
//Earlygame factions - factions the player will prestige with early on that don't
|
||||
//belong in other categories
|
||||
var Netburners = new Faction("Netburners");
|
||||
Netburners.setInfo(FactionInfo.NetburnersInfo);
|
||||
resetFaction(Netburners);
|
||||
|
||||
var TianDiHui = new Faction("Tian Di Hui"); //Society of the Heaven and Earth
|
||||
TianDiHui.setInfo(FactionInfo.TianDiHuiInfo);
|
||||
resetFaction(TianDiHui);
|
||||
|
||||
var CyberSec = new Faction("CyberSec");
|
||||
CyberSec.setInfo(FactionInfo.CyberSecInfo);
|
||||
resetFaction(CyberSec);
|
||||
|
||||
//Special Factions
|
||||
var Bladeburners = new Faction("Bladeburners");
|
||||
Bladeburners.setInfo(FactionInfo.BladeburnersInfo);
|
||||
resetFaction(Bladeburners);
|
||||
for(const name in FactionInfos) {
|
||||
resetFaction(new Faction(name));
|
||||
}
|
||||
}
|
||||
|
||||
//Resets a faction during (re-)initialization. Saves the favor in the new
|
||||
@ -287,36 +148,12 @@ function inviteToFaction(faction) {
|
||||
function joinFaction(faction) {
|
||||
faction.isMember = true;
|
||||
Player.factions.push(faction.name);
|
||||
const factionInfo = faction.getInfo();
|
||||
|
||||
//Determine what factions you are banned from now that you have joined this faction
|
||||
if (faction.name == "Chongqing") {
|
||||
Factions["Sector-12"].isBanned = true;
|
||||
Factions["Aevum"].isBanned = true;
|
||||
Factions["Volhaven"].isBanned = true;
|
||||
} else if (faction.name == "Sector-12") {
|
||||
Factions["Chongqing"].isBanned = true;
|
||||
Factions["New Tokyo"].isBanned = true;
|
||||
Factions["Ishima"].isBanned = true;
|
||||
Factions["Volhaven"].isBanned = true;
|
||||
} else if (faction.name == "New Tokyo") {
|
||||
Factions["Sector-12"].isBanned = true;
|
||||
Factions["Aevum"].isBanned = true;
|
||||
Factions["Volhaven"].isBanned = true;
|
||||
} else if (faction.name == "Aevum") {
|
||||
Factions["Chongqing"].isBanned = true;
|
||||
Factions["New Tokyo"].isBanned = true;
|
||||
Factions["Ishima"].isBanned = true;
|
||||
Factions["Volhaven"].isBanned = true;
|
||||
} else if (faction.name == "Ishima") {
|
||||
Factions["Sector-12"].isBanned = true;
|
||||
Factions["Aevum"].isBanned = true;
|
||||
Factions["Volhaven"].isBanned = true;
|
||||
} else if (faction.name == "Volhaven") {
|
||||
Factions["Chongqing"].isBanned = true;
|
||||
Factions["Sector-12"].isBanned = true;
|
||||
Factions["New Tokyo"].isBanned = true;
|
||||
Factions["Aevum"].isBanned = true;
|
||||
Factions["Ishima"].isBanned = true;
|
||||
for(const i in factionInfo.enemies) {
|
||||
const enemy = factionInfo.enemies[i];
|
||||
Factions[enemy].isBanned = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -326,6 +163,8 @@ function displayFactionContent(factionName) {
|
||||
if (faction == null) {
|
||||
throw new Error("Invalid factionName passed into displayFactionContent: " + factionName);
|
||||
}
|
||||
var factionInfo = faction.getInfo();
|
||||
|
||||
removeChildrenFromElement(Engine.Display.factionContent);
|
||||
var elements = [];
|
||||
|
||||
@ -334,7 +173,7 @@ function displayFactionContent(factionName) {
|
||||
innerText:factionName
|
||||
}));
|
||||
elements.push(createElement("pre", {
|
||||
innerHTML:"<i>" + faction.info + "</i>"
|
||||
innerHTML:"<i>" + factionInfo.infoText + "</i>"
|
||||
}));
|
||||
elements.push(createElement("p", {
|
||||
innerText:"---------------",
|
||||
@ -346,14 +185,14 @@ function displayFactionContent(factionName) {
|
||||
favorGain = favorGain[0];
|
||||
elements.push(createElement("p", {
|
||||
innerText: "Reputation: " + formatNumber(faction.playerReputation, 4),
|
||||
tooltip:"You will earn " + formatNumber(favorGain, 4) +
|
||||
tooltip:"You will earn " + formatNumber(favorGain, 0) +
|
||||
" faction favor upon resetting after installing an Augmentation"
|
||||
}))
|
||||
elements.push(createElement("p", {
|
||||
innerText:"---------------",
|
||||
}));
|
||||
elements.push(createElement("p", {
|
||||
innerText:"Faction Favor: " + formatNumber(faction.favor, 4),
|
||||
innerText:"Faction Favor: " + formatNumber(faction.favor, 0),
|
||||
tooltip:"Faction favor increases the rate at which " +
|
||||
"you earn reputation for this faction by 1% per favor. Faction favor " +
|
||||
"is gained whenever you reset after installing an Augmentation. The amount of " +
|
||||
@ -583,214 +422,17 @@ function displayFactionContent(factionName) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (faction.isMember) {
|
||||
if (faction.favor >= (150 * BitNodeMultipliers.RepToDonateToFaction)) {
|
||||
donateDiv.style.display = "inline";
|
||||
} else {
|
||||
donateDiv.style.display = "none";
|
||||
}
|
||||
|
||||
switch(faction.name) {
|
||||
case "Illuminati":
|
||||
hackMissionDiv.style.display = "inline";
|
||||
hackDiv.style.display = "inline";
|
||||
fieldWorkDiv.style.display = "inline";
|
||||
securityWorkDiv.style.display = "none";
|
||||
break;
|
||||
case "Daedalus":
|
||||
hackMissionDiv.style.display = "inline";
|
||||
hackDiv.style.display = "inline";
|
||||
fieldWorkDiv.style.display = "inline";
|
||||
securityWorkDiv.style.display = "none";
|
||||
break;
|
||||
case "The Covenant":
|
||||
hackMissionDiv.style.display = "inline";
|
||||
hackDiv.style.display = "inline";
|
||||
fieldWorkDiv.style.display = "inline";
|
||||
securityWorkDiv.style.display = "none";
|
||||
break;
|
||||
case "ECorp":
|
||||
hackMissionDiv.style.display = "inline";
|
||||
hackDiv.style.display = "inline";
|
||||
fieldWorkDiv.style.display = "inline";
|
||||
securityWorkDiv.style.display = "inline";
|
||||
break;
|
||||
case "MegaCorp":
|
||||
hackMissionDiv.style.display = "inline";
|
||||
hackDiv.style.display = "inline";
|
||||
fieldWorkDiv.style.display = "inline";
|
||||
securityWorkDiv.style.display = "inline";
|
||||
break;
|
||||
case "Bachman & Associates":
|
||||
hackMissionDiv.style.display = "inline";
|
||||
hackDiv.style.display = "inline";
|
||||
fieldWorkDiv.style.display = "inline";
|
||||
securityWorkDiv.style.display = "inline";
|
||||
break;
|
||||
case "Blade Industries":
|
||||
hackMissionDiv.style.display = "inline";
|
||||
hackDiv.style.display = "inline";
|
||||
fieldWorkDiv.style.display = "inline";
|
||||
securityWorkDiv.style.display = "inline";
|
||||
break;
|
||||
case "NWO":
|
||||
hackMissionDiv.style.display = "inline";
|
||||
hackDiv.style.display = "inline";
|
||||
fieldWorkDiv.style.display = "inline";
|
||||
securityWorkDiv.style.display = "inline";
|
||||
break;
|
||||
case "Clarke Incorporated":
|
||||
hackMissionDiv.style.display = "inline";
|
||||
hackDiv.style.display = "inline";
|
||||
fieldWorkDiv.style.display = "inline";
|
||||
securityWorkDiv.style.display = "inline";
|
||||
break;
|
||||
case "OmniTek Incorporated":
|
||||
hackMissionDiv.style.display = "inline";
|
||||
hackDiv.style.display = "inline";
|
||||
fieldWorkDiv.style.display = "inline";
|
||||
securityWorkDiv.style.display = "inline";
|
||||
break;
|
||||
case "Four Sigma":
|
||||
hackMissionDiv.style.display = "inline";
|
||||
hackDiv.style.display = "inline";
|
||||
fieldWorkDiv.style.display = "inline";
|
||||
securityWorkDiv.style.display = "inline";
|
||||
break;
|
||||
case "KuaiGong International":
|
||||
hackMissionDiv.style.display = "inline";
|
||||
hackDiv.style.display = "inline";
|
||||
fieldWorkDiv.style.display = "inline";
|
||||
securityWorkDiv.style.display = "inline";
|
||||
break;
|
||||
case "Fulcrum Secret Technologies":
|
||||
hackMissionDiv.style.display = "inline";
|
||||
hackDiv.style.display = "inline";
|
||||
fieldWorkDiv.style.display = "none";
|
||||
securityWorkDiv.style.display = "inline";
|
||||
break;
|
||||
case "BitRunners":
|
||||
hackMissionDiv.style.display = "inline";
|
||||
hackDiv.style.display = "inline";
|
||||
fieldWorkDiv.style.display = "none";
|
||||
securityWorkDiv.style.display = "none";
|
||||
break;
|
||||
case "The Black Hand":
|
||||
hackMissionDiv.style.display = "inline";
|
||||
hackDiv.style.display = "inline";
|
||||
fieldWorkDiv.style.display = "inline";
|
||||
securityWorkDiv.style.display = "none";
|
||||
break;
|
||||
case "NiteSec":
|
||||
hackMissionDiv.style.display = "inline";
|
||||
hackDiv.style.display = "inline";
|
||||
fieldWorkDiv.style.display = "none";
|
||||
securityWorkDiv.style.display = "none";
|
||||
break;
|
||||
case "Chongqing":
|
||||
hackMissionDiv.style.display = "inline";
|
||||
hackDiv.style.display = "inline";
|
||||
fieldWorkDiv.style.display = "inline";
|
||||
securityWorkDiv.style.display = "inline";
|
||||
break;
|
||||
case "Sector-12":
|
||||
hackMissionDiv.style.display = "inline";
|
||||
hackDiv.style.display = "inline";
|
||||
fieldWorkDiv.style.display = "inline";
|
||||
securityWorkDiv.style.display = "inline";
|
||||
break;
|
||||
case "New Tokyo":
|
||||
hackMissionDiv.style.display = "inline";
|
||||
hackDiv.style.display = "inline";
|
||||
fieldWorkDiv.style.display = "inline";
|
||||
securityWorkDiv.style.display = "inline";
|
||||
break;
|
||||
case "Aevum":
|
||||
hackMissionDiv.style.display = "inline";
|
||||
hackDiv.style.display = "inline";
|
||||
fieldWorkDiv.style.display = "inline";
|
||||
securityWorkDiv.style.display = "inline";
|
||||
break;
|
||||
case "Ishima":
|
||||
hackMissionDiv.style.display = "inline";
|
||||
hackDiv.style.display = "inline";
|
||||
fieldWorkDiv.style.display = "inline";
|
||||
securityWorkDiv.style.display = "inline";
|
||||
break;
|
||||
case "Volhaven":
|
||||
hackMissionDiv.style.display = "inline";
|
||||
hackDiv.style.display = "inline";
|
||||
fieldWorkDiv.style.display = "inline";
|
||||
securityWorkDiv.style.display = "inline";
|
||||
break;
|
||||
case "Speakers for the Dead":
|
||||
hackMissionDiv.style.display = "inline";
|
||||
hackDiv.style.display = "inline";
|
||||
fieldWorkDiv.style.display = "inline";
|
||||
securityWorkDiv.style.display = "inline";
|
||||
break;
|
||||
case "The Dark Army":
|
||||
hackMissionDiv.style.display = "inline";
|
||||
hackDiv.style.display = "inline";
|
||||
fieldWorkDiv.style.display = "inline";
|
||||
securityWorkDiv.style.display = "none";
|
||||
break;
|
||||
case "The Syndicate":
|
||||
hackMissionDiv.style.display = "inline";
|
||||
hackDiv.style.display = "inline";
|
||||
fieldWorkDiv.style.display = "inline";
|
||||
securityWorkDiv.style.display = "inline";
|
||||
break;
|
||||
case "Silhouette":
|
||||
hackMissionDiv.style.display = "inline";
|
||||
hackDiv.style.display = "inline";
|
||||
fieldWorkDiv.style.display = "inline";
|
||||
securityWorkDiv.style.display = "none";
|
||||
break;
|
||||
case "Tetrads":
|
||||
hackMissionDiv.style.display = "none";
|
||||
hackDiv.style.display = "none";
|
||||
fieldWorkDiv.style.display = "inline";
|
||||
securityWorkDiv.style.display = "inline";
|
||||
break;
|
||||
case "Slum Snakes":
|
||||
hackMissionDiv.style.display = "none";
|
||||
hackDiv.style.display = "none";
|
||||
fieldWorkDiv.style.display = "inline";
|
||||
securityWorkDiv.style.display = "inline";
|
||||
break;
|
||||
case "Netburners":
|
||||
hackMissionDiv.style.display = "inline";
|
||||
hackDiv.style.display = "inline";
|
||||
fieldWorkDiv.style.display = "none";
|
||||
securityWorkDiv.style.display = "none";
|
||||
break;
|
||||
case "Tian Di Hui":
|
||||
hackMissionDiv.style.display = "inline";
|
||||
hackDiv.style.display = "inline";
|
||||
fieldWorkDiv.style.display = "none";
|
||||
securityWorkDiv.style.display = "inline";
|
||||
break;
|
||||
case "CyberSec":
|
||||
hackMissionDiv.style.display = "inline";
|
||||
hackDiv.style.display = "inline";
|
||||
fieldWorkDiv.style.display = "none";
|
||||
securityWorkDiv.style.display = "none";
|
||||
break;
|
||||
case "Bladeburners":
|
||||
hackMissionDiv.style.display = "none";
|
||||
hackDiv.style.display = "none";
|
||||
fieldWorkDiv.style.display = "none";
|
||||
securityWorkDiv.style.display = "none";
|
||||
break;
|
||||
default:
|
||||
console.log("Faction does not exist");
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (!faction.isMember) {
|
||||
throw new Error("Not a member of this faction, cannot display faction information");
|
||||
}
|
||||
|
||||
donateDiv.style.display = faction.favor >= (150 * BitNodeMultipliers.RepToDonateToFaction) ? "inline" : "none";
|
||||
|
||||
hackMissionDiv.style.display = factionInfo.offerHackingMission ? "inline": "none";
|
||||
hackDiv.style.display = factionInfo.offerHackingWork ? "inline" : "none";
|
||||
fieldWorkDiv.style.display = factionInfo.offerFieldWork ? "inline" : "none";
|
||||
securityWorkDiv.style.display = factionInfo.offerSecurityWork ? "inline" : "none";
|
||||
|
||||
//Display all elements
|
||||
for (var i = 0; i < elements.length; ++i) {
|
||||
Engine.Display.factionContent.appendChild(elements[i]);
|
||||
@ -915,6 +557,8 @@ function displayFactionAugmentations(factionName) {
|
||||
// @augs Array of Aug names
|
||||
// @faction Faction for which to display Augmentations
|
||||
function createFactionAugmentationDisplayElements(augmentationsList, augs, faction) {
|
||||
const factionInfo = faction.getInfo();
|
||||
|
||||
for (var i = 0; i < augs.length; ++i) {
|
||||
(function () {
|
||||
var aug = Augmentations[augs[i]];
|
||||
@ -955,7 +599,7 @@ function createFactionAugmentationDisplayElements(augmentationsList, augs, facti
|
||||
var pElem = createElement("p", {
|
||||
display:"inline",
|
||||
})
|
||||
var req = aug.baseRepRequirement * faction.augmentationRepRequirementMult;
|
||||
var req = aug.baseRepRequirement * factionInfo.augmentationRepRequirementMult;
|
||||
var hasPrereqs = hasAugmentationPrereqs(aug);
|
||||
if (!hasPrereqs) {
|
||||
aElem.setAttribute("class", "a-link-button-inactive");
|
||||
@ -966,10 +610,10 @@ function createFactionAugmentationDisplayElements(augmentationsList, augs, facti
|
||||
pElem.innerHTML = "ALREADY OWNED";
|
||||
} else if (faction.playerReputation >= req) {
|
||||
aElem.setAttribute("class", "a-link-button");
|
||||
pElem.innerHTML = "UNLOCKED - " + numeral(aug.baseCost * faction.augmentationPriceMult).format("$0.000a");
|
||||
pElem.innerHTML = "UNLOCKED - " + numeral(aug.baseCost * factionInfo.augmentationPriceMult).format("$0.000a");
|
||||
} else {
|
||||
aElem.setAttribute("class", "a-link-button-inactive");
|
||||
pElem.innerHTML = "LOCKED (Requires " + formatNumber(req, 1) + " faction reputation) - " + numeral(aug.baseCost * faction.augmentationPriceMult).format("$0.000a");
|
||||
pElem.innerHTML = "LOCKED (Requires " + formatNumber(req, 1) + " faction reputation) - " + numeral(aug.baseCost * factionInfo.augmentationPriceMult).format("$0.000a");
|
||||
pElem.style.color = "red";
|
||||
}
|
||||
aDiv.appendChild(aElem);
|
||||
@ -982,6 +626,7 @@ function createFactionAugmentationDisplayElements(augmentationsList, augs, facti
|
||||
}
|
||||
|
||||
function purchaseAugmentationBoxCreate(aug, fac) {
|
||||
const factionInfo = fac.getInfo();
|
||||
var yesBtn = yesNoBoxGetYesButton(), noBtn = yesNoBoxGetNoButton();
|
||||
yesBtn.innerHTML = "Purchase";
|
||||
noBtn.innerHTML = "Cancel";
|
||||
@ -995,7 +640,7 @@ function purchaseAugmentationBoxCreate(aug, fac) {
|
||||
yesNoBoxCreate("<h2>" + aug.name + "</h2><br>" +
|
||||
aug.info + "<br><br>" +
|
||||
"<br>Would you like to purchase the " + aug.name + " Augmentation for $" +
|
||||
formatNumber(aug.baseCost * fac.augmentationPriceMult, 2) + "?");
|
||||
formatNumber(aug.baseCost * factionInfo.augmentationPriceMult, 2) + "?");
|
||||
}
|
||||
|
||||
//Returns a boolean indicating whether the player has the prerequisites for the
|
||||
@ -1026,12 +671,13 @@ function hasAugmentationPrereqs(aug) {
|
||||
}
|
||||
|
||||
function purchaseAugmentation(aug, fac, sing=false) {
|
||||
const factionInfo = fac.getInfo();
|
||||
var hasPrereqs = hasAugmentationPrereqs(aug);
|
||||
if (!hasPrereqs) {
|
||||
var txt = "You must first purchase or install " + aug.prereqs.join(",") + " before you can " +
|
||||
"purchase this one.";
|
||||
if (sing) {return txt;} else {dialogBoxCreate(txt);}
|
||||
} else if (Player.money.lt(aug.baseCost * fac.augmentationPriceMult)) {
|
||||
} else if (Player.money.lt(aug.baseCost * factionInfo.augmentationPriceMult)) {
|
||||
let txt = "You don't have enough money to purchase " + aug.name;
|
||||
if (sing) {return txt;}
|
||||
dialogBoxCreate(txt);
|
||||
@ -1039,7 +685,7 @@ function purchaseAugmentation(aug, fac, sing=false) {
|
||||
let txt = "You don't have enough faction reputation to purchase " + aug.name;
|
||||
if (sing) {return txt;}
|
||||
dialogBoxCreate(txt);
|
||||
} else if (Player.money.gte(aug.baseCost * fac.augmentationPriceMult)) {
|
||||
} else if (Player.money.gte(aug.baseCost * factionInfo.augmentationPriceMult)) {
|
||||
if (Player.firstAugPurchased === false) {
|
||||
Player.firstAugPurchased = true;
|
||||
document.getElementById("augmentations-tab").style.display = "list-item";
|
||||
@ -1053,7 +699,7 @@ function purchaseAugmentation(aug, fac, sing=false) {
|
||||
}
|
||||
Player.queuedAugmentations.push(queuedAugmentation);
|
||||
|
||||
Player.loseMoney((aug.baseCost * fac.augmentationPriceMult));
|
||||
Player.loseMoney((aug.baseCost * factionInfo.augmentationPriceMult));
|
||||
|
||||
//If you just purchased Neuroflux Governor, recalculate the cost
|
||||
if (aug.name == AugmentationNames.NeuroFluxGovernor) {
|
||||
|
@ -1,68 +1,81 @@
|
||||
//Contains the "information" property for all the Factions, which is just a description
|
||||
//of each faction
|
||||
let FactionInfo = {
|
||||
function FactionInfo(infoText, enemies, offerHackingMission, offerHackingWork, offerFieldWork, offerSecurityWork) {
|
||||
this.infoText = infoText;
|
||||
this.enemies = enemies;
|
||||
this.offerHackingMission = offerHackingMission;
|
||||
this.offerHackingWork = offerHackingWork;
|
||||
this.offerFieldWork = offerFieldWork;
|
||||
this.offerSecurityWork = offerSecurityWork;
|
||||
|
||||
// these are always all 1 for now.
|
||||
this.augmentationPriceMult = 1;
|
||||
this.augmentationRepRequirementMult = 1;
|
||||
}
|
||||
|
||||
const FactionInfos = {
|
||||
//Endgame
|
||||
IlluminatiInfo: "Humanity never changes. No matter how civilized society becomes, it will eventually fall back " +
|
||||
"into chaos. And from this chaos, we are the Invisible hand that guides them to order. ",
|
||||
"Illuminati": new FactionInfo("Humanity never changes. No matter how civilized society becomes, it will eventually fall back " +
|
||||
"into chaos. And from this chaos, we are the Invisible hand that guides them to order. ", [], true, true, true, false),
|
||||
|
||||
DaedalusInfo: "Yesterday we obeyed kings and bent our necks to emperors. Today we kneel only to truth.",
|
||||
"Daedalus": new FactionInfo("Yesterday we obeyed kings and bent our necks to emperors. Today we kneel only to truth.", [], true, true, true, false),
|
||||
|
||||
CovenantInfo: "Surrender yourself. Give up your empty individuality to become part of something great, something eternal. " +
|
||||
"The Covenant": new FactionInfo("Surrender yourself. Give up your empty individuality to become part of something great, something eternal. " +
|
||||
"Become a slave. Submit your mind, body, and soul. Only then can you set yourself free.<br><br> " +
|
||||
"Only then can you discover immortality.",
|
||||
"Only then can you discover immortality.", [], true, true, true, false),
|
||||
|
||||
//Megacorporations, each forms its own faction
|
||||
ECorpInfo: "ECorp's mission is simple: to connect the world of today with the technology of tomorrow. " +
|
||||
"ECorp": new FactionInfo("ECorp's mission is simple: to connect the world of today with the technology of tomorrow. " +
|
||||
"With our wide range of Internet-related software and commercial hardware, ECorp makes the world's " +
|
||||
"information universally accessible.",
|
||||
"information universally accessible.", [], true, true, true, true),
|
||||
|
||||
MegaCorpInfo: "MegaCorp does things that others don't. We imagine. We create. We invent. We build things that " +
|
||||
"MegaCorp": new FactionInfo("MegaCorp does things that others don't. We imagine. We create. We invent. We build things that " +
|
||||
"others have never even dreamed of. Our work fills the world's needs for food, water, power, and " +
|
||||
"transporation on an unprecendented scale, in ways that no other company can.<br><br>" +
|
||||
"In our labs and factories and on the ground with customers, MegaCorp is ushering in a new era for the world.",
|
||||
"In our labs and factories and on the ground with customers, MegaCorp is ushering in a new era for the world.", [], true, true, true, true),
|
||||
|
||||
BachmanAndAssociatesInfo: "Where Law and Business meet - thats where we are. <br><br>" +
|
||||
"Legal Insight - Business Instinct - Experience Innovation",
|
||||
"Bachman & Associates": new FactionInfo("Where Law and Business meet - thats where we are. <br><br>" +
|
||||
"Legal Insight - Business Instinct - Experience Innovation", [], true, true, true, true),
|
||||
|
||||
BladeIndustriesInfo: "Augmentation is salvation",
|
||||
"Blade Industries": new FactionInfo("Augmentation is salvation", [], true, true, true, true),
|
||||
|
||||
NWOInfo: "The human being does not truly desire freedom. It wants " +
|
||||
"NWO": new FactionInfo("The human being does not truly desire freedom. It wants " +
|
||||
"to be observed, understood, and judged. It wants to be given purpose and " +
|
||||
"direction in its life. That is why humans created God. " +
|
||||
"And that is why humans created civilization - " +
|
||||
"not because of willingness, " +
|
||||
"but because of a need to be incorporated into higher orders of structure and meaning.",
|
||||
"but because of a need to be incorporated into higher orders of structure and meaning.", [], true, true, true, true),
|
||||
|
||||
ClarkeIncorporatedInfo: "Unlocking the power of the genome",
|
||||
"Clarke Incorporated": new FactionInfo("Unlocking the power of the genome", [], true, true, true, true),
|
||||
|
||||
OmniTekIncorporatedInfo: "Simply put, our mission is to design and build robots that make a difference",
|
||||
"OmniTek Incorporated": new FactionInfo("Simply put, our mission is to design and build robots that make a difference", [], true, true, true, true),
|
||||
|
||||
FourSigmaInfo: "The scientific method is the best way to approach investing. Big strategies backed up with big data. Driven by " +
|
||||
"deep learning and innovative ideas. And improved by iteration. That's Four Sigma.",
|
||||
"Four Sigma": new FactionInfo("The scientific method is the best way to approach investing. Big strategies backed up with big data. Driven by " +
|
||||
"deep learning and innovative ideas. And improved by iteration. That's Four Sigma.", [], true, true, true, true),
|
||||
|
||||
KuaiGongInternationalInfo: "Dream big. Work hard. Make history.",
|
||||
"KuaiGong International": new FactionInfo("Dream big. Work hard. Make history.", [], true, true, true, true),
|
||||
|
||||
//Other Corporations
|
||||
FulcrumSecretTechnologiesInfo: "The human organism has an innate desire to worship. " +
|
||||
"Fulcrum Secret Technologies": new FactionInfo("The human organism has an innate desire to worship. " +
|
||||
"That is why they created gods. If there were no gods, " +
|
||||
"it would be necessary to create them. And now we can.",
|
||||
"it would be necessary to create them. And now we can.", [], true, true, false, true),
|
||||
|
||||
//Hacker groups
|
||||
BitRunnersInfo: "Our entire lives are controlled by bits. All of our actions, our thoughts, our personal information. "+
|
||||
"BitRunners": new FactionInfo("Our entire lives are controlled by bits. All of our actions, our thoughts, our personal information. "+
|
||||
"It's all transformed into bits, stored in bits, communicated through bits. It’s impossible for any person " +
|
||||
"to move, to live, to operate at any level without the use of bits. " +
|
||||
"And when a person moves, lives, and operates, they leave behind their bits, mere traces of seemingly " +
|
||||
"meaningless fragments of information. But these bits can be reconstructed. Transformed. Used.<br><br>" +
|
||||
"Those who run the bits, run the world",
|
||||
"Those who run the bits, run the world", [], true, true, false, false),
|
||||
|
||||
|
||||
BlackHandInfo: "The world, so afraid of strong government, now has no government. Only power - Digital power. Financial power. " +
|
||||
"The Black Hand": new FactionInfo("The world, so afraid of strong government, now has no government. Only power - Digital power. Financial power. " +
|
||||
"Technological power. " +
|
||||
"And those at the top rule with an invisible hand. They built a society where the rich get richer, " +
|
||||
"and everyone else suffers.<br><br>" +
|
||||
"So much pain. So many lives. Their darkness must end.",
|
||||
"So much pain. So many lives. Their darkness must end.", [], true, true, true, false),
|
||||
|
||||
NiteSecInfo:
|
||||
"NiteSec": new FactionInfo(
|
||||
" __..__ <br>" +
|
||||
" _.nITESECNIt. <br>" +
|
||||
" .-'NITESECNITESEc. <br>" +
|
||||
@ -97,47 +110,47 @@ let FactionInfo = {
|
||||
" / .d$$$$; , ; <br>" +
|
||||
" d .dNITESEC $ | <br>" +
|
||||
" :bp.__.gNITESEC$$ :$ ; <br>" +
|
||||
" NITESECNITESECNIT $$b : <br>",
|
||||
" NITESECNITESECNIT $$b : <br>", [], true, true, false, false),
|
||||
|
||||
//City factions, essentially governments
|
||||
ChongqingInfo: "Serve the people",
|
||||
Sector12Info: "The City of the Future",
|
||||
HongKongInfo: "Asia's World City",
|
||||
AevumInfo: "The Silicon City",
|
||||
IshimaInfo: "The East Asian Order of the Future",
|
||||
VolhavenInfo: "Benefit, Honour, and Glory",
|
||||
"Chongqing": new FactionInfo("Serve the people", ["Sector-12", "Aevum", "Volhaven"], true, true, true, true),
|
||||
"Sector-12": new FactionInfo("The City of the Future", ["Chongqing", "New Tokyo", "Ishima", "Volhaven"], true, true, true, true),
|
||||
"New Tokyo": new FactionInfo("Asia's World City", ["Sector-12", "Aevum", "Volhaven"], true, true, true, true),
|
||||
"Aevum": new FactionInfo("The Silicon City", ["Chongqing", "New Tokyo", "Ishima", "Volhaven"], true, true, true, true),
|
||||
"Ishima": new FactionInfo("The East Asian Order of the Future", ["Sector-12", "Aevum", "Volhaven"], true, true, true, true),
|
||||
"Volhaven": new FactionInfo("Benefit, Honour, and Glory", ["Chongqing", "Sector-12", "New Tokyo", "Aevum", "Ishima"], true, true, true, true),
|
||||
|
||||
//Criminal Organizations/Gangs
|
||||
SpeakersForTheDeadInfo: "It is better to reign in hell than to serve in heaven.",
|
||||
"Speakers for the Dead": new FactionInfo("It is better to reign in hell than to serve in heaven.", [], true, true, true, true),
|
||||
|
||||
DarkArmyInfo: "The World doesn't care about right or wrong. It's all about power.",
|
||||
"The Dark Army": new FactionInfo("The World doesn't care about right or wrong. It's all about power.", [], true, true, true, false),
|
||||
|
||||
TheSyndicateInfo: "Honor holds you back",
|
||||
"The Syndicate": new FactionInfo("Honor holds you back", [], true, true, true, true),
|
||||
|
||||
SilhouetteInfo: "Corporations have filled the void of power left behind by the collapse of Western government. The issue is they've become so big " +
|
||||
"Silhouette": new FactionInfo("Corporations have filled the void of power left behind by the collapse of Western government. The issue is they've become so big " +
|
||||
"that you don't know who they're working for. And if you're employed at one of these corporations, you don't even know who you're working " +
|
||||
"for.\n\n" +
|
||||
"That's terror. Terror, fear, and corruption. All born into the system, all propagated by the system.",
|
||||
"That's terror. Terror, fear, and corruption. All born into the system, all propagated by the system.", [], true, true, true, false),
|
||||
|
||||
TetradsInfo: "Following the Mandate of Heaven and Carrying out the Way",
|
||||
"Tetrads": new FactionInfo("Following the Mandate of Heaven and Carrying out the Way", [], false, false, true, true),
|
||||
|
||||
SlumSnakesInfo: "Slum Snakes rule!",
|
||||
"Slum Snakes": new FactionInfo("Slum Snakes rule!", [], false, false, true, true),
|
||||
|
||||
//Earlygame factions - factions the player will prestige with early on that don't
|
||||
//belong in other categories
|
||||
NetburnersInfo: "~~//*>H4CK|\|3T 8URN3R5**>?>\\~~",
|
||||
"Netburners": new FactionInfo("~~//*>H4CK|\|3T 8URN3R5**>?>\\~~", [], true, true, false, false),
|
||||
|
||||
TianDiHuiInfo: "Obey Heaven and Work Righteousness",
|
||||
"Tian Di Hui": new FactionInfo("Obey Heaven and Work Righteousness", [], true, true, false, true),
|
||||
|
||||
CyberSecInfo: "The Internet is the first thing that humanity has built that humanity doesn’t understand, " +
|
||||
"CyberSec": new FactionInfo("The Internet is the first thing that humanity has built that humanity doesn’t understand, " +
|
||||
"the largest experiment in anarchy that we have ever had. And as the world becomes increasingly " +
|
||||
"dominated by the internet, society approaches the brink of total chaos. " +
|
||||
"We serve only to protect society, to protect humanity, to protect the world from its imminent collapse.",
|
||||
"We serve only to protect society, to protect humanity, to protect the world from its imminent collapse.", [], true, true, false, false),
|
||||
|
||||
//Special Factions
|
||||
BladeburnersInfo: "It's too bad they won't live. But then again, who does?<br><br>" +
|
||||
"Bladeburners": new FactionInfo("It's too bad they won't live. But then again, who does?<br><br>" +
|
||||
"Note that for this faction, reputation can only be gained through Bladeburner actions. Completing " +
|
||||
"Bladeburner contracts/operations will increase your reputation.",
|
||||
"Bladeburner contracts/operations will increase your reputation.", [], false, false, false, false),
|
||||
}
|
||||
|
||||
export {FactionInfo};
|
||||
export {FactionInfos};
|
||||
|
@ -10,7 +10,7 @@ import {getRandomInt, createElement,
|
||||
removeChildrenFromElement,
|
||||
createAccordionElement, createPopup,
|
||||
removeElementById, removeElement} from "../utils/HelperFunctions.js";
|
||||
import numeral from "../utils/numeral.min.js";
|
||||
import numeral from "numeral/min/numeral.min";
|
||||
import {formatNumber} from "../utils/StringHelperFunctions.js";
|
||||
import {yesNoBoxCreate, yesNoTxtInpBoxCreate,
|
||||
yesNoBoxGetYesButton, yesNoBoxGetNoButton,
|
||||
|
@ -5,42 +5,48 @@ import {iTutorialSteps, iTutorialNextStep,
|
||||
iTutorialIsRunning, currITutorialStep} from "./InteractiveTutorial.js";
|
||||
import {Player} from "./Player.js";
|
||||
import {dialogBoxCreate} from "../utils/DialogBox.js";
|
||||
import {clearEventListeners} from "../utils/HelperFunctions.js";
|
||||
import {clearEventListeners, createElement,
|
||||
getElementById} from "../utils/HelperFunctions.js";
|
||||
import {Reviver, Generic_toJSON,
|
||||
Generic_fromJSON} from "../utils/JSONReviver.js";
|
||||
import {formatNumber} from "../utils/StringHelperFunctions.js";
|
||||
|
||||
/**
|
||||
* Overwrites the inner text of the specified HTML element if it is different from what currently exists.
|
||||
* @param {string} elementId The HTML ID to find the first instance of.
|
||||
* @param {string} text The inner text that should be set.
|
||||
*/
|
||||
function updateText(elementId, text) {
|
||||
var el = getElementById(elementId);
|
||||
if (el.innerText != text) {
|
||||
el.innerText = text;
|
||||
}
|
||||
};
|
||||
|
||||
/* HacknetNode.js */
|
||||
function hacknetNodesInit() {
|
||||
var mult1x = document.getElementById("hacknet-nodes-1x-multiplier");
|
||||
mult1x.addEventListener("click", function() {
|
||||
hacknetNodePurchaseMultiplier = 1;
|
||||
updateHacknetNodesMultiplierButtons();
|
||||
updateHacknetNodesContent();
|
||||
return false;
|
||||
});
|
||||
var mult5x = document.getElementById("hacknet-nodes-5x-multiplier");
|
||||
mult5x.addEventListener("click", function() {
|
||||
hacknetNodePurchaseMultiplier = 5;
|
||||
updateHacknetNodesMultiplierButtons();
|
||||
updateHacknetNodesContent();
|
||||
return false;
|
||||
});
|
||||
var mult10x = document.getElementById("hacknet-nodes-10x-multiplier");
|
||||
mult10x.addEventListener("click", function() {
|
||||
hacknetNodePurchaseMultiplier = 10;
|
||||
updateHacknetNodesMultiplierButtons();
|
||||
updateHacknetNodesContent();
|
||||
return false;
|
||||
});
|
||||
var multMax = document.getElementById("hacknet-nodes-max-multiplier");
|
||||
multMax.addEventListener("click", function() {
|
||||
hacknetNodePurchaseMultiplier = 0;
|
||||
updateHacknetNodesMultiplierButtons();
|
||||
updateHacknetNodesContent();
|
||||
return false;
|
||||
});
|
||||
var performMapping = function(x) {
|
||||
getElementById("hacknet-nodes-" + x.id + "-multiplier")
|
||||
.addEventListener("click", function() {
|
||||
hacknetNodePurchaseMultiplier = x.multiplier;
|
||||
updateHacknetNodesMultiplierButtons();
|
||||
updateHacknetNodesContent();
|
||||
return false;
|
||||
});
|
||||
};
|
||||
|
||||
var mappings = [
|
||||
{ id: "1x", multiplier: 1 },
|
||||
{ id: "5x", multiplier: 5 },
|
||||
{ id: "10x", multiplier: 10 },
|
||||
{ id: "max", multiplier: 0 }
|
||||
];
|
||||
for (var elem of mappings) {
|
||||
// Encapsulate in a function so that the appropriate scope is kept in the click handler.
|
||||
performMapping(elem);
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", hacknetNodesInit, false);
|
||||
|
||||
function HacknetNode(name) {
|
||||
@ -76,7 +82,10 @@ HacknetNode.prototype.updateMoneyGainRate = function() {
|
||||
|
||||
HacknetNode.prototype.calculateLevelUpgradeCost = function(levels=1) {
|
||||
levels = Math.round(levels);
|
||||
if (isNaN(levels) || levels < 1) {return 0;}
|
||||
if (isNaN(levels) || levels < 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
var mult = CONSTANTS.HacknetNodeUpgradeLevelMult;
|
||||
var totalMultiplier = 0; //Summed
|
||||
var currLevel = this.level;
|
||||
@ -84,6 +93,7 @@ HacknetNode.prototype.calculateLevelUpgradeCost = function(levels=1) {
|
||||
totalMultiplier += Math.pow(mult, currLevel);
|
||||
++currLevel;
|
||||
}
|
||||
|
||||
return CONSTANTS.BaseCostForHacknetNode / 2 * totalMultiplier * Player.hacknet_node_level_cost_mult;
|
||||
}
|
||||
|
||||
@ -95,12 +105,19 @@ HacknetNode.prototype.getLevelUpgradeCost = function(levels=1) {
|
||||
HacknetNode.prototype.purchaseLevelUpgrade = function(levels=1) {
|
||||
levels = Math.round(levels);
|
||||
var cost = this.calculateLevelUpgradeCost(levels);
|
||||
if (isNaN(cost) || levels < 0) {return false;}
|
||||
if (isNaN(cost) || levels < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.level + levels > CONSTANTS.HacknetNodeMaxLevel) {
|
||||
var diff = Math.max(0, CONSTANTS.HacknetNodeMaxLevel - this.level);
|
||||
return this.purchaseLevelUpgrade(diff);
|
||||
}
|
||||
if (Player.money.lt(cost)) {return false;}
|
||||
|
||||
if (Player.money.lt(cost)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Player.loseMoney(cost);
|
||||
this.level += levels;
|
||||
this.updateMoneyGainRate();
|
||||
@ -109,7 +126,9 @@ HacknetNode.prototype.purchaseLevelUpgrade = function(levels=1) {
|
||||
|
||||
//Wrapper function for Netscript
|
||||
HacknetNode.prototype.upgradeLevel = function(levels=1) {
|
||||
return this.purchaseLevelUpgrade(levels);
|
||||
let res = this.purchaseLevelUpgrade(levels);
|
||||
createPlayerHacknetNodeWrappers();
|
||||
return res;
|
||||
}
|
||||
|
||||
HacknetNode.prototype.calculateRamUpgradeCost = function() {
|
||||
@ -129,9 +148,18 @@ HacknetNode.prototype.getRamUpgradeCost = function() {
|
||||
|
||||
HacknetNode.prototype.purchaseRamUpgrade = function() {
|
||||
var cost = this.calculateRamUpgradeCost();
|
||||
if (isNaN(cost)) {return false;}
|
||||
if (Player.money.lt(cost)) {return false;}
|
||||
if (this.ram >= CONSTANTS.HacknetNodeMaxRam) {return false;}
|
||||
if (isNaN(cost)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Player.money.lt(cost)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.ram >= CONSTANTS.HacknetNodeMaxRam) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Player.loseMoney(cost);
|
||||
this.ram *= 2; //Ram is always doubled
|
||||
this.updateMoneyGainRate();
|
||||
@ -140,25 +168,38 @@ HacknetNode.prototype.purchaseRamUpgrade = function() {
|
||||
|
||||
//Wrapper function for Netscript
|
||||
HacknetNode.prototype.upgradeRam = function() {
|
||||
return this.purchaseRamUpgrade();
|
||||
let res = this.purchaseRamUpgrade();
|
||||
createPlayerHacknetNodeWrappers();
|
||||
return res;
|
||||
}
|
||||
|
||||
HacknetNode.prototype.calculateCoreUpgradeCost = function() {
|
||||
var coreBaseCost = CONSTANTS.BaseCostForHacknetNodeCore;
|
||||
var mult = CONSTANTS.HacknetNodeUpgradeCoreMult;
|
||||
return coreBaseCost * Math.pow(mult, this.cores-1) * Player.hacknet_node_core_cost_mult;
|
||||
return coreBaseCost * Math.pow(mult, this.cores - 1) * Player.hacknet_node_core_cost_mult;
|
||||
}
|
||||
|
||||
//Wrapper function for Netscript
|
||||
HacknetNode.prototype.getCoreUpgradeCost = function() {
|
||||
return this.calculateCoreUpgradeCost();
|
||||
let res = this.calculateCoreUpgradeCost();
|
||||
createPlayerHacknetNodeWrappers();
|
||||
return res;
|
||||
}
|
||||
|
||||
HacknetNode.prototype.purchaseCoreUpgrade = function() {
|
||||
var cost = this.calculateCoreUpgradeCost();
|
||||
if (isNaN(cost)) {return false;}
|
||||
if (Player.money.lt(cost)) {return false;}
|
||||
if (this.cores >= CONSTANTS.HacknetNodeMaxCores) {return false;}
|
||||
if (isNaN(cost)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Player.money.lt(cost)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.cores >= CONSTANTS.HacknetNodeMaxCores) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Player.loseMoney(cost);
|
||||
++this.cores;
|
||||
this.updateMoneyGainRate();
|
||||
@ -225,7 +266,10 @@ function purchaseHacknet() {
|
||||
/* END INTERACTIVE TUTORIAL */
|
||||
|
||||
var cost = getCostOfNextHacknetNode();
|
||||
if (isNaN(cost)) {throw new Error("Cost is NaN"); return;}
|
||||
if (isNaN(cost)) {
|
||||
throw new Error("Cost is NaN");
|
||||
}
|
||||
|
||||
if (Player.money.lt(cost)) {
|
||||
//dialogBoxCreate("You cannot afford to purchase a Hacknet Node!");
|
||||
return false;
|
||||
@ -240,7 +284,10 @@ function purchaseHacknet() {
|
||||
Player.loseMoney(cost);
|
||||
Player.hacknetNodes.push(node);
|
||||
|
||||
displayHacknetNodesContent();
|
||||
if (Engine.currentPage === Engine.Page.HacknetNodes) {
|
||||
displayHacknetNodesContent();
|
||||
}
|
||||
createPlayerHacknetNodeWrappers();
|
||||
updateTotalHacknetProduction();
|
||||
return numOwned;
|
||||
}
|
||||
@ -290,9 +337,12 @@ function updateHacknetNodesMultiplierButtons() {
|
||||
//Calculate the maximum number of times the Player can afford to upgrade
|
||||
//a Hacknet Node's level"
|
||||
function getMaxNumberLevelUpgrades(nodeObj) {
|
||||
if (Player.money.lt(nodeObj.calculateLevelUpgradeCost(1))) {return 0;}
|
||||
if (Player.money.lt(nodeObj.calculateLevelUpgradeCost(1))) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
var min = 1;
|
||||
var max = CONSTANTS.HacknetNodeMaxLevel-1;
|
||||
var max = CONSTANTS.HacknetNodeMaxLevel - 1;
|
||||
var levelsToMax = CONSTANTS.HacknetNodeMaxLevel - nodeObj.level;
|
||||
if (Player.money.gt(nodeObj.calculateLevelUpgradeCost(levelsToMax))) {
|
||||
return levelsToMax;
|
||||
@ -302,7 +352,7 @@ function getMaxNumberLevelUpgrades(nodeObj) {
|
||||
var curr = (min + max) / 2 | 0;
|
||||
if (curr != CONSTANTS.HacknetNodeMaxLevel &&
|
||||
Player.money.gt(nodeObj.calculateLevelUpgradeCost(curr)) &&
|
||||
Player.money.lt(nodeObj.calculateLevelUpgradeCost(curr+1))) {
|
||||
Player.money.lt(nodeObj.calculateLevelUpgradeCost(curr + 1))) {
|
||||
return Math.min(levelsToMax, curr);
|
||||
} else if (Player.money.lt(nodeObj.calculateLevelUpgradeCost(curr))) {
|
||||
max = curr - 1;
|
||||
@ -329,7 +379,7 @@ function displayHacknetNodesContent() {
|
||||
|
||||
//Remove all old hacknet Node DOM elements
|
||||
var hacknetNodesList = document.getElementById("hacknet-nodes-list");
|
||||
while (hacknetNodesList.firstChild) {
|
||||
while (hacknetNodesList.firstChild) {
|
||||
hacknetNodesList.removeChild(hacknetNodesList.firstChild);
|
||||
}
|
||||
|
||||
@ -337,6 +387,7 @@ function displayHacknetNodesContent() {
|
||||
for (var i = 0; i < Player.hacknetNodes.length; ++i) {
|
||||
createHacknetNodeDomElement(Player.hacknetNodes[i]);
|
||||
}
|
||||
|
||||
updateHacknetNodesContent();
|
||||
}
|
||||
|
||||
@ -344,8 +395,11 @@ function displayHacknetNodesContent() {
|
||||
function updateHacknetNodesContent() {
|
||||
//Set purchase button to inactive if not enough money, and update its price display
|
||||
var cost = getCostOfNextHacknetNode();
|
||||
var purchaseButton = document.getElementById("hacknet-nodes-purchase-button");
|
||||
purchaseButton.innerHTML = "Purchase Hacknet Node - $" + formatNumber(cost, 2);
|
||||
var purchaseButton = getElementById("hacknet-nodes-purchase-button");
|
||||
var formattedCost = formatNumber(cost, 2);
|
||||
|
||||
updateText("hacknet-nodes-purchase-button", "Purchase Hacknet Node - $" + formattedCost);
|
||||
|
||||
if (Player.money.lt(cost)) {
|
||||
purchaseButton.setAttribute("class", "a-link-button-inactive");
|
||||
} else {
|
||||
@ -353,9 +407,8 @@ function updateHacknetNodesContent() {
|
||||
}
|
||||
|
||||
//Update player's money
|
||||
var moneyElem = document.getElementById("hacknet-nodes-money");
|
||||
moneyElem.innerHTML = "Money: $" + formatNumber(Player.money.toNumber(), 2) + "<br>" +
|
||||
"Total production from all Hacknet Nodes: $" + formatNumber(Player.totalHacknetNodeProduction, 2) + " / second";
|
||||
updateText("hacknet-nodes-player-money", "$" + formatNumber(Player.money.toNumber(), 2));
|
||||
updateText("hacknet-nodes-total-production", "$" + formatNumber(Player.totalHacknetNodeProduction, 2) + " / second");
|
||||
|
||||
//Update information in each owned hacknet node
|
||||
for (var i = 0; i < Player.hacknetNodes.length; ++i) {
|
||||
@ -367,61 +420,75 @@ function updateHacknetNodesContent() {
|
||||
function createHacknetNodeDomElement(nodeObj) {
|
||||
var nodeName = nodeObj.name;
|
||||
|
||||
var listItem = document.createElement("li");
|
||||
listItem.setAttribute("class", "hacknet-node");
|
||||
var nodeLevelContainer = createElement("div", {
|
||||
class: "hacknet-node-level-container row",
|
||||
innerHTML: "<p>Level:</p><span class=\"text upgradable-info\" id=\"hacknet-node-level-" + nodeName + "\"></span>"
|
||||
});
|
||||
|
||||
var span = document.createElement("span");
|
||||
span.style.display = "inline";
|
||||
var nodeRamContainer = createElement("div", {
|
||||
class: "hacknet-node-ram-container row",
|
||||
innerHTML: "<p>RAM:</p><span class=\"text upgradable-info\" id=\"hacknet-node-ram-" + nodeName + "\"></span>"
|
||||
});
|
||||
|
||||
var buttonDiv = document.createElement("div");
|
||||
buttonDiv.setAttribute("class", "hacknet-node-button-div");
|
||||
var nodeCoresContainer = createElement("div", {
|
||||
class: "hacknet-node-cores-container row",
|
||||
innerHTML: "<p>Cores:</p><span class=\"text upgradable-info\" id=\"hacknet-node-cores-" + nodeName + "\"><span>"
|
||||
})
|
||||
var containingDiv = createElement("div", {
|
||||
class: "hacknet-node-container",
|
||||
innerHTML: "<div class=\"hacknet-node-name-container row\">" +
|
||||
"<p>Node name:</p>" +
|
||||
"<span class=\"text\" id=\"hacknet-node-name-" + nodeName + "\"></span>" +
|
||||
"</div>" +
|
||||
"<div class=\"hacknet-node-production-container row\">" +
|
||||
"<p>Production:</p>" +
|
||||
"<span class=\"text\" id=\"hacknet-node-total-production-" + nodeName + "\"></span>" +
|
||||
"<span class=\"text\" id=\"hacknet-node-production-rate-" + nodeName + "\"></span>" +
|
||||
"</div>"
|
||||
});
|
||||
containingDiv.appendChild(nodeLevelContainer);
|
||||
containingDiv.appendChild(nodeRamContainer);
|
||||
containingDiv.appendChild(nodeCoresContainer);
|
||||
|
||||
//Text
|
||||
var txt = document.createElement("p");
|
||||
//txt.setAttribute("id", "hacknet-node-text-" + nodeName);
|
||||
txt.id = "hacknet-node-text-" + nodeName;
|
||||
var listItem = createElement("li", {
|
||||
class: "hacknet-node"
|
||||
});
|
||||
listItem.appendChild(containingDiv);
|
||||
|
||||
//Upgrade buttons
|
||||
var upgradeLevelButton = document.createElement("a");
|
||||
var upgradeRamButton = document.createElement("a");
|
||||
var upgradeCoreButton = document.createElement("a");
|
||||
|
||||
//upgradeLevelButton.setAttribute("id", "hacknet-node-upgrade-level-" + nodeName);
|
||||
upgradeLevelButton.id = "hacknet-node-upgrade-level-" + nodeName;
|
||||
upgradeLevelButton.setAttribute("class", "a-link-button-inactive");
|
||||
upgradeLevelButton.addEventListener("click", function() {
|
||||
var numUpgrades = hacknetNodePurchaseMultiplier;
|
||||
if (hacknetNodePurchaseMultiplier == 0) {
|
||||
numUpgrades = getMaxNumberLevelUpgrades(nodeObj);
|
||||
nodeLevelContainer.appendChild(createElement("a", {
|
||||
id: "hacknet-node-upgrade-level-" + nodeName,
|
||||
class: "a-link-button-inactive",
|
||||
clickListener: function() {
|
||||
var numUpgrades = hacknetNodePurchaseMultiplier;
|
||||
if (hacknetNodePurchaseMultiplier == 0) {
|
||||
numUpgrades = getMaxNumberLevelUpgrades(nodeObj);
|
||||
}
|
||||
nodeObj.purchaseLevelUpgrade(numUpgrades);
|
||||
updateHacknetNodesContent();
|
||||
return false;
|
||||
}
|
||||
nodeObj.purchaseLevelUpgrade(numUpgrades);
|
||||
updateHacknetNodesContent();
|
||||
return false;
|
||||
});
|
||||
//upgradeRamButton.setAttribute("id", "hacknet-node-upgrade-ram-" + nodeName);
|
||||
upgradeRamButton.id = "hacknet-node-upgrade-ram-" + nodeName;
|
||||
upgradeRamButton.setAttribute("class", "a-link-button-inactive");
|
||||
upgradeRamButton.addEventListener("click", function() {
|
||||
nodeObj.purchaseRamUpgrade();
|
||||
updateHacknetNodesContent();
|
||||
return false;
|
||||
});
|
||||
//upgradeCoreButton.setAttribute("id", "hacknet-node-upgrade-core-" + nodeName);
|
||||
upgradeCoreButton.id = "hacknet-node-upgrade-core-" + nodeName;
|
||||
upgradeCoreButton.setAttribute("class", "a-link-button-inactive");
|
||||
upgradeCoreButton.addEventListener("click", function() {
|
||||
nodeObj.purchaseCoreUpgrade();
|
||||
updateHacknetNodesContent();
|
||||
return false;
|
||||
});
|
||||
}));
|
||||
|
||||
//Put all the components together in the li element
|
||||
span.appendChild(txt);
|
||||
buttonDiv.appendChild(upgradeLevelButton);
|
||||
buttonDiv.appendChild(upgradeRamButton);
|
||||
buttonDiv.appendChild(upgradeCoreButton);
|
||||
span.appendChild(buttonDiv);
|
||||
listItem.appendChild(span);
|
||||
nodeRamContainer.appendChild(createElement("a", {
|
||||
id: "hacknet-node-upgrade-ram-" + nodeName,
|
||||
class: "a-link-button-inactive",
|
||||
clickListener: function() {
|
||||
nodeObj.purchaseRamUpgrade();
|
||||
updateHacknetNodesContent();
|
||||
return false;
|
||||
}
|
||||
}));
|
||||
|
||||
nodeCoresContainer.appendChild(createElement("a", {
|
||||
id: "hacknet-node-upgrade-core-" + nodeName,
|
||||
class: "a-link-button-inactive",
|
||||
clickListener: function() {
|
||||
nodeObj.purchaseCoreUpgrade();
|
||||
updateHacknetNodesContent();
|
||||
return false;
|
||||
}
|
||||
}));
|
||||
|
||||
document.getElementById("hacknet-nodes-list").appendChild(listItem);
|
||||
|
||||
@ -432,20 +499,19 @@ function createHacknetNodeDomElement(nodeObj) {
|
||||
//Updates information on a single hacknet node DOM element
|
||||
function updateHacknetNodeDomElement(nodeObj) {
|
||||
var nodeName = nodeObj.name;
|
||||
var txt = document.getElementById("hacknet-node-text-" + nodeName);
|
||||
if (txt == null) {throw new Error("Cannot find text element");}
|
||||
txt.innerHTML = "Node name: " + nodeName + "<br>" +
|
||||
"Production: $" + formatNumber(nodeObj.totalMoneyGenerated, 2) +
|
||||
" ($" + formatNumber(nodeObj.moneyGainRatePerSecond, 2) + " / second) <br>" +
|
||||
"Level: " + nodeObj.level + "<br>" +
|
||||
"RAM: " + nodeObj.ram + "GB<br>" +
|
||||
"Cores: " + nodeObj.cores;
|
||||
|
||||
updateText("hacknet-node-name-" + nodeName, nodeName);
|
||||
updateText("hacknet-node-total-production-" + nodeName, "$" + formatNumber(nodeObj.totalMoneyGenerated, 2));
|
||||
updateText("hacknet-node-production-rate-" + nodeName, "($" + formatNumber(nodeObj.moneyGainRatePerSecond, 2) + " / second)");
|
||||
updateText("hacknet-node-level-" + nodeName, nodeObj.level);
|
||||
updateText("hacknet-node-ram-" + nodeName, nodeObj.ram + "GB");
|
||||
updateText("hacknet-node-cores-" + nodeName, nodeObj.cores);
|
||||
|
||||
//Upgrade level
|
||||
var upgradeLevelButton = document.getElementById("hacknet-node-upgrade-level-" + nodeName);
|
||||
if (upgradeLevelButton == null) {throw new Error("Cannot find upgrade level button element");}
|
||||
var upgradeLevelButton = getElementById("hacknet-node-upgrade-level-" + nodeName);
|
||||
|
||||
if (nodeObj.level >= CONSTANTS.HacknetNodeMaxLevel) {
|
||||
upgradeLevelButton.innerHTML = "MAX LEVEL";
|
||||
updateText("hacknet-node-upgrade-level-" + nodeName, "MAX LEVEL");
|
||||
upgradeLevelButton.setAttribute("class", "a-link-button-inactive");
|
||||
} else {
|
||||
var multiplier = 0;
|
||||
@ -458,8 +524,7 @@ function updateHacknetNodeDomElement(nodeObj) {
|
||||
}
|
||||
|
||||
var upgradeLevelCost = nodeObj.calculateLevelUpgradeCost(multiplier);
|
||||
upgradeLevelButton.innerHTML = "Upgrade Hacknet Node Level x" + multiplier +
|
||||
" - $" + formatNumber(upgradeLevelCost, 2);
|
||||
updateText("hacknet-node-upgrade-level-" + nodeName, "Upgrade x" + multiplier + " - $" + formatNumber(upgradeLevelCost, 2))
|
||||
if (Player.money.lt(upgradeLevelCost)) {
|
||||
upgradeLevelButton.setAttribute("class", "a-link-button-inactive");
|
||||
} else {
|
||||
@ -468,14 +533,14 @@ function updateHacknetNodeDomElement(nodeObj) {
|
||||
}
|
||||
|
||||
//Upgrade RAM
|
||||
var upgradeRamButton = document.getElementById("hacknet-node-upgrade-ram-" + nodeName);
|
||||
if (upgradeRamButton == null) {throw new Error("Cannot find upgrade ram button element");}
|
||||
var upgradeRamButton = getElementById("hacknet-node-upgrade-ram-" + nodeName);
|
||||
|
||||
if (nodeObj.ram >= CONSTANTS.HacknetNodeMaxRam) {
|
||||
upgradeRamButton.innerHTML = "MAX RAM";
|
||||
updateText("hacknet-node-upgrade-ram-" + nodeName, "MAX RAM");
|
||||
upgradeRamButton.setAttribute("class", "a-link-button-inactive");
|
||||
} else {
|
||||
var upgradeRamCost = nodeObj.calculateRamUpgradeCost();
|
||||
upgradeRamButton.innerHTML = "Upgrade Hacknet Node RAM - $" + formatNumber(upgradeRamCost, 2);
|
||||
updateText("hacknet-node-upgrade-ram-" + nodeName, "Upgrade - $" + formatNumber(upgradeRamCost, 2));
|
||||
if (Player.money.lt(upgradeRamCost)) {
|
||||
upgradeRamButton.setAttribute("class", "a-link-button-inactive");
|
||||
} else {
|
||||
@ -484,14 +549,14 @@ function updateHacknetNodeDomElement(nodeObj) {
|
||||
}
|
||||
|
||||
//Upgrade Cores
|
||||
var upgradeCoreButton = document.getElementById("hacknet-node-upgrade-core-" + nodeName);
|
||||
if (upgradeCoreButton == null) {throw new Error("Cannot find upgrade cores button element");}
|
||||
var upgradeCoreButton = getElementById("hacknet-node-upgrade-core-" + nodeName);
|
||||
|
||||
if (nodeObj.cores >= CONSTANTS.HacknetNodeMaxCores) {
|
||||
upgradeCoreButton.innerHTML = "MAX CORES";
|
||||
updateText("hacknet-node-upgrade-core-" + nodeName, "MAX CORES");
|
||||
upgradeCoreButton.setAttribute("class", "a-link-button-inactive");
|
||||
} else {
|
||||
var upgradeCoreCost = nodeObj.calculateCoreUpgradeCost();
|
||||
upgradeCoreButton.innerHTML = "Purchase additional CPU Core - $" + formatNumber(upgradeCoreCost, 2);
|
||||
updateText("hacknet-node-upgrade-core-" + nodeName, "Upgrade - $" + formatNumber(upgradeCoreCost, 2));
|
||||
if (Player.money.lt(upgradeCoreCost)) {
|
||||
upgradeCoreButton.setAttribute("class", "a-link-button-inactive");
|
||||
} else {
|
||||
@ -511,8 +576,12 @@ function updatePlayerHacknetNodeWrappers() {
|
||||
if (Player.hacknetNodeWrappers.length !== Player.hacknetNodes.length) {
|
||||
return createPlayerHacknetNodeWrappers();
|
||||
}
|
||||
|
||||
for (var i = 0; i < Player.hacknetNodeWrappers.length; ++i) {
|
||||
if (!(Player.hacknetNodeWrappers[i] instanceof HacknetNodeWrapper)) {return createPlayerHacknetNodeWrappers();}
|
||||
if (!(Player.hacknetNodeWrappers[i] instanceof HacknetNodeWrapper)) {
|
||||
return createPlayerHacknetNodeWrappers();
|
||||
}
|
||||
|
||||
Player.hacknetNodeWrappers[i].level = Player.hacknetNodes[i].level;
|
||||
Player.hacknetNodeWrappers[i].ram = Player.hacknetNodes[i].ram;
|
||||
Player.hacknetNodeWrappers[i].cores = Player.hacknetNodes[i].cores;
|
||||
@ -528,6 +597,7 @@ function processAllHacknetNodeEarnings(numCycles) {
|
||||
for (var i = 0; i < Player.hacknetNodes.length; ++i) {
|
||||
total += processSingleHacknetNodeEarnings(numCycles, Player.hacknetNodes[i]);
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
@ -535,9 +605,10 @@ function processSingleHacknetNodeEarnings(numCycles, nodeObj) {
|
||||
var cyclesPerSecond = 1000 / Engine._idleSpeed;
|
||||
var earningPerCycle = nodeObj.moneyGainRatePerSecond / cyclesPerSecond;
|
||||
if (isNaN(earningPerCycle)) {
|
||||
console.log("ERROR: Hacknet Node Calculated earnings is NaN");
|
||||
console.error("Hacknet Node '" + nodeObj.name + "' Calculated earnings is NaN");
|
||||
earningPerCycle = 0;
|
||||
}
|
||||
|
||||
var totalEarnings = numCycles * earningPerCycle;
|
||||
nodeObj.totalMoneyGenerated += totalEarnings;
|
||||
nodeObj.onlineTimeSeconds += (numCycles * (Engine._idleSpeed / 1000));
|
||||
@ -551,10 +622,21 @@ function getHacknetNode(name) {
|
||||
return Player.hacknetNodes[i];
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
export {hacknetNodesInit, HacknetNode, purchaseHacknet, updateTotalHacknetProduction,
|
||||
getCostOfNextHacknetNode, updateHacknetNodesMultiplierButtons, getMaxNumberLevelUpgrades,
|
||||
displayHacknetNodesContent, updateHacknetNodesContent, processAllHacknetNodeEarnings,
|
||||
getHacknetNode, createPlayerHacknetNodeWrappers};
|
||||
export {
|
||||
HacknetNode,
|
||||
createPlayerHacknetNodeWrappers,
|
||||
displayHacknetNodesContent,
|
||||
getCostOfNextHacknetNode,
|
||||
getHacknetNode,
|
||||
getMaxNumberLevelUpgrades,
|
||||
hacknetNodesInit,
|
||||
processAllHacknetNodeEarnings,
|
||||
purchaseHacknet,
|
||||
updateHacknetNodesContent,
|
||||
updateHacknetNodesMultiplierButtons,
|
||||
updateTotalHacknetProduction
|
||||
};
|
||||
|
@ -3,18 +3,7 @@ import {CompanyPositions, initCompanies,
|
||||
Companies, getJobRequirementText} from "./Company.js";
|
||||
import {Corporation} from "./CompanyManagement.js";
|
||||
import {CONSTANTS} from "./Constants.js";
|
||||
import {commitShopliftCrime, commitRobStoreCrime, commitMugCrime,
|
||||
commitLarcenyCrime, commitDealDrugsCrime, commitBondForgeryCrime,
|
||||
commitTraffickArmsCrime,
|
||||
commitHomicideCrime, commitGrandTheftAutoCrime, commitKidnapCrime,
|
||||
commitAssassinationCrime, commitHeistCrime, determineCrimeSuccess,
|
||||
determineCrimeChanceShoplift, determineCrimeChanceRobStore,
|
||||
determineCrimeChanceMug, determineCrimeChanceLarceny,
|
||||
determineCrimeChanceDealDrugs, determineCrimeChanceBondForgery,
|
||||
determineCrimeChanceTraffickArms,
|
||||
determineCrimeChanceHomicide, determineCrimeChanceGrandTheftAuto,
|
||||
determineCrimeChanceKidnap, determineCrimeChanceAssassination,
|
||||
determineCrimeChanceHeist} from "./Crimes.js";
|
||||
import {Crimes} from "./Crimes.js";
|
||||
import {Engine} from "./engine.js";
|
||||
import {beginInfiltration} from "./Infiltration.js";
|
||||
import {hasBladeburnerSF} from "./NetscriptFunctions.js";
|
||||
@ -27,7 +16,7 @@ import {SpecialServerNames, SpecialServerIps} from "./SpecialServerIps.js";
|
||||
import {dialogBoxCreate} from "../utils/DialogBox.js";
|
||||
import {clearEventListeners, createElement} from "../utils/HelperFunctions.js";
|
||||
import {createRandomIp} from "../utils/IPAddress.js";
|
||||
import numeral from "../utils/numeral.min.js";
|
||||
import numeral from "numeral/min/numeral.min";
|
||||
import {formatNumber} from "../utils/StringHelperFunctions.js";
|
||||
import {yesNoBoxCreate, yesNoTxtInpBoxCreate,
|
||||
yesNoBoxGetYesButton, yesNoBoxGetNoButton,
|
||||
@ -1058,18 +1047,18 @@ function displayLocationContent() {
|
||||
case Locations.NewTokyoSlums:
|
||||
case Locations.IshimaSlums:
|
||||
case Locations.VolhavenSlums:
|
||||
var shopliftChance = determineCrimeChanceShoplift();
|
||||
var robStoreChance = determineCrimeChanceRobStore();
|
||||
var mugChance = determineCrimeChanceMug();
|
||||
var larcenyChance = determineCrimeChanceLarceny();
|
||||
var drugsChance = determineCrimeChanceDealDrugs();
|
||||
var bondChance = determineCrimeChanceBondForgery();
|
||||
var armsChance = determineCrimeChanceTraffickArms();
|
||||
var homicideChance = determineCrimeChanceHomicide();
|
||||
var gtaChance = determineCrimeChanceGrandTheftAuto();
|
||||
var kidnapChance = determineCrimeChanceKidnap();
|
||||
var assassinateChance = determineCrimeChanceAssassination();
|
||||
var heistChance = determineCrimeChanceHeist();
|
||||
var shopliftChance = Crimes.Shoplift.successRate();
|
||||
var robStoreChance = Crimes.RobStore.successRate();
|
||||
var mugChance = Crimes.Mug.successRate();
|
||||
var larcenyChance = Crimes.Larceny.successRate();
|
||||
var drugsChance = Crimes.DealDrugs.successRate();
|
||||
var bondChance = Crimes.BondForgery.successRate();
|
||||
var armsChance = Crimes.TraffickArms.successRate();
|
||||
var homicideChance = Crimes.Homicide.successRate();
|
||||
var gtaChance = Crimes.GrandTheftAuto.successRate();
|
||||
var kidnapChance = Crimes.Kidnap.successRate();
|
||||
var assassinateChance = Crimes.Assassination.successRate();
|
||||
var heistChance = Crimes.Heist.successRate();
|
||||
|
||||
slumsDescText.style.display = "block";
|
||||
slumsShoplift.style.display = "block";
|
||||
@ -1772,16 +1761,8 @@ function initLocationButtons() {
|
||||
});
|
||||
|
||||
purchaseHomeRam.addEventListener("click", function() {
|
||||
//Calculate how many times ram has been upgraded (doubled)
|
||||
var currentRam = Player.getHomeComputer().maxRam;
|
||||
var newRam = currentRam * 2;
|
||||
var numUpgrades = Math.log2(currentRam);
|
||||
|
||||
//Calculate cost
|
||||
//Have cost increase by some percentage each time RAM has been upgraded
|
||||
var cost = currentRam * CONSTANTS.BaseCostFor1GBOfRamHome;
|
||||
var mult = Math.pow(1.58, numUpgrades);
|
||||
cost = cost * mult;
|
||||
const cost = Player.getUpgradeHomeRamCost();
|
||||
const ram = Player.getHomeComputer().maxRam;
|
||||
|
||||
var yesBtn = yesNoBoxGetYesButton(), noBtn = yesNoBoxGetNoButton();
|
||||
yesBtn.innerHTML = "Purchase"; noBtn.innerHTML = "Cancel";
|
||||
@ -1793,8 +1774,8 @@ function initLocationButtons() {
|
||||
yesNoBoxClose();
|
||||
});
|
||||
yesNoBoxCreate("Would you like to purchase additional RAM for your home computer? <br><br>" +
|
||||
"This will upgrade your RAM from " + currentRam + "GB to " + newRam + "GB. <br><br>" +
|
||||
"This will cost $" + formatNumber(cost, 2));
|
||||
"This will upgrade your RAM from " + ram + "GB to " + ram*2 + "GB. <br><br>" +
|
||||
"This will cost " + numeral(cost).format('$0.000a'));
|
||||
});
|
||||
|
||||
purchaseHomeCores.addEventListener("click", function() {
|
||||
@ -1834,92 +1815,92 @@ function initLocationButtons() {
|
||||
});
|
||||
|
||||
travelToAevum.addEventListener("click", function() {
|
||||
travelBoxCreate(Locations.Aevum, 200000);
|
||||
travelBoxCreate(Locations.Aevum, CONSTANTS.TravelCost);
|
||||
return false;
|
||||
});
|
||||
|
||||
travelToChongqing.addEventListener("click", function() {
|
||||
travelBoxCreate(Locations.Chongqing, 200000);
|
||||
travelBoxCreate(Locations.Chongqing, CONSTANTS.TravelCost);
|
||||
return false;
|
||||
});
|
||||
|
||||
travelToSector12.addEventListener("click", function() {
|
||||
travelBoxCreate(Locations.Sector12, 200000);
|
||||
travelBoxCreate(Locations.Sector12, CONSTANTS.TravelCost);
|
||||
return false;
|
||||
});
|
||||
|
||||
travelToNewTokyo.addEventListener("click", function() {
|
||||
travelBoxCreate(Locations.NewTokyo, 200000);
|
||||
travelBoxCreate(Locations.NewTokyo, CONSTANTS.TravelCost);
|
||||
return false;
|
||||
});
|
||||
|
||||
travelToIshima.addEventListener("click", function() {
|
||||
travelBoxCreate(Locations.Ishima, 200000);
|
||||
travelBoxCreate(Locations.Ishima, CONSTANTS.TravelCost);
|
||||
return false;
|
||||
});
|
||||
|
||||
travelToVolhaven.addEventListener("click", function() {
|
||||
travelBoxCreate(Locations.Volhaven, 200000);
|
||||
travelBoxCreate(Locations.Volhaven, CONSTANTS.TravelCost);
|
||||
return false;
|
||||
});
|
||||
|
||||
slumsShoplift.addEventListener("click", function() {
|
||||
commitShopliftCrime();
|
||||
Crimes.Shoplift.commit();
|
||||
return false;
|
||||
});
|
||||
|
||||
slumsRobStore.addEventListener("click", function() {
|
||||
commitRobStoreCrime();
|
||||
Crimes.RobStore.commit();
|
||||
return false;
|
||||
});
|
||||
|
||||
slumsMug.addEventListener("click", function() {
|
||||
commitMugCrime();
|
||||
Crimes.Mug.commit();
|
||||
return false;
|
||||
});
|
||||
|
||||
slumsLarceny.addEventListener("click", function() {
|
||||
commitLarcenyCrime();
|
||||
Crimes.Larceny.commit();
|
||||
return false;
|
||||
});
|
||||
|
||||
slumsDealDrugs.addEventListener("click", function() {
|
||||
commitDealDrugsCrime();
|
||||
Crimes.DealDrugs.commit();
|
||||
return false;
|
||||
});
|
||||
|
||||
slumsBondForgery.addEventListener("click", function() {
|
||||
commitBondForgeryCrime();
|
||||
Crimes.BondForgery.commit();
|
||||
return false;
|
||||
});
|
||||
|
||||
slumsTrafficArms.addEventListener("click", function() {
|
||||
commitTraffickArmsCrime();
|
||||
Crimes.TraffickArms.commit();
|
||||
return false;
|
||||
});
|
||||
|
||||
slumsHomicide.addEventListener("click", function() {
|
||||
commitHomicideCrime();
|
||||
Crimes.Homicide.commit();
|
||||
return false;
|
||||
});
|
||||
|
||||
slumsGta.addEventListener("click", function() {
|
||||
commitGrandTheftAutoCrime();
|
||||
Crimes.GrandTheftAuto.commit();
|
||||
return false;
|
||||
});
|
||||
|
||||
slumsKidnap.addEventListener("click", function() {
|
||||
commitKidnapCrime();
|
||||
Crimes.Kidnap.commit();
|
||||
return false;
|
||||
});
|
||||
|
||||
slumsAssassinate.addEventListener("click", function() {
|
||||
commitAssassinationCrime();
|
||||
Crimes.Assassination.commit();
|
||||
return false;
|
||||
});
|
||||
|
||||
slumsHeist.addEventListener("click", function() {
|
||||
commitHeistCrime();
|
||||
Crimes.Heist.commit();
|
||||
return false;
|
||||
});
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -31,8 +31,12 @@ function WorkerScript(runningScriptObj) {
|
||||
this.delay = null;
|
||||
this.fnWorker = null; //Workerscript for a function call
|
||||
this.checkingRam = false;
|
||||
this.loadedFns = {}; //Stores names of fns that are "loaded" by this script, thus using RAM
|
||||
this.loadedFns = {}; //Stores names of fns that are "loaded" by this script, thus using RAM. Used for static RAM evaluation
|
||||
this.disableLogs = {}; //Stores names of fns that should have logs disabled
|
||||
|
||||
//Properties used for dynamic RAM evaluation
|
||||
this.dynamicRamUsage = 1.4;
|
||||
this.dynamicLoadedFns = {};
|
||||
}
|
||||
|
||||
//Returns the server on which the workerScript is running
|
||||
@ -52,6 +56,14 @@ WorkerScript.prototype.getScript = function() {
|
||||
return null;
|
||||
}
|
||||
|
||||
WorkerScript.prototype.shouldLog = function(fn) {
|
||||
return (this.disableLogs.ALL == null && this.disableLogs[fn] == null);
|
||||
}
|
||||
|
||||
WorkerScript.prototype.log = function(txt) {
|
||||
this.scriptRef.log(txt);
|
||||
}
|
||||
|
||||
//Array containing all scripts that are running across all servers, to easily run them all
|
||||
let workerScripts = [];
|
||||
|
||||
|
@ -8,7 +8,7 @@ import {Company, Companies, getNextCompanyPosition,
|
||||
import {CONSTANTS} from "./Constants.js";
|
||||
import {Corporation} from "./CompanyManagement.js";
|
||||
import {Programs} from "./CreateProgram.js";
|
||||
import {determineCrimeSuccess} from "./Crimes.js";
|
||||
import {determineCrimeSuccess, Crimes} from "./Crimes.js";
|
||||
import {Engine} from "./engine.js";
|
||||
import {Factions, Faction,
|
||||
displayFactionContent} from "./Faction.js";
|
||||
@ -25,7 +25,7 @@ import {clearEventListeners} from "../utils/HelperFunctions.j
|
||||
import {createRandomIp} from "../utils/IPAddress.js";
|
||||
import {Reviver, Generic_toJSON,
|
||||
Generic_fromJSON} from "../utils/JSONReviver.js";
|
||||
import numeral from "../utils/numeral.min.js";
|
||||
import numeral from "numeral/min/numeral.min";
|
||||
import {formatNumber,
|
||||
convertTimeMsToTimeElapsedString} from "../utils/StringHelperFunctions.js";
|
||||
|
||||
@ -299,8 +299,6 @@ PlayerObject.prototype.prestigeAugmentation = function() {
|
||||
|
||||
this.hacknetNodes.length = 0;
|
||||
this.totalHacknetNodeProduction = 0;
|
||||
|
||||
this.bladeburner = 0;
|
||||
}
|
||||
|
||||
PlayerObject.prototype.prestigeSourceFile = function() {
|
||||
@ -391,8 +389,6 @@ PlayerObject.prototype.prestigeSourceFile = function() {
|
||||
if (this.bitNodeN === 3) {this.money = new Decimal(150e9);}
|
||||
this.corporation = 0;
|
||||
|
||||
this.bladeburner = 0;
|
||||
|
||||
this.playtimeSinceLastAug = 0;
|
||||
this.scriptProdSinceLastAug = 0;
|
||||
}
|
||||
@ -405,6 +401,18 @@ PlayerObject.prototype.getHomeComputer = function() {
|
||||
return AllServers[this.homeComputer];
|
||||
}
|
||||
|
||||
PlayerObject.prototype.getUpgradeHomeRamCost = function() {
|
||||
//Calculate how many times ram has been upgraded (doubled)
|
||||
const currentRam = Player.getHomeComputer().maxRam;
|
||||
const numUpgrades = Math.log2(currentRam);
|
||||
|
||||
//Calculate cost
|
||||
//Have cost increase by some percentage each time RAM has been upgraded
|
||||
const mult = Math.pow(1.58, numUpgrades);
|
||||
var cost = currentRam * CONSTANTS.BaseCostFor1GBOfRamHome * mult;
|
||||
return cost;
|
||||
}
|
||||
|
||||
//Calculates skill level based on experience. The same formula will be used for every skill
|
||||
PlayerObject.prototype.calculateSkill = function(exp) {
|
||||
return Math.max(Math.floor(32 * Math.log(exp + 534.5) - 200), 1);
|
||||
@ -1518,56 +1526,21 @@ PlayerObject.prototype.finishCrime = function(cancelled) {
|
||||
var statusText = ""; //TODO, unique message for each crime when you succeed
|
||||
if (determineCrimeSuccess(this.crimeType, this.workMoneyGained)) {
|
||||
//Handle Karma and crime statistics
|
||||
switch(this.crimeType) {
|
||||
case CONSTANTS.CrimeShoplift:
|
||||
this.karma -= 0.1;
|
||||
let crime = null;
|
||||
for(const i in Crimes) {
|
||||
if(Crimes[i].type == this.crimeType) {
|
||||
crime = Crimes[i];
|
||||
break;
|
||||
case CONSTANTS.CrimeRobStore:
|
||||
this.karma -= 0.5;
|
||||
this.gainIntelligenceExp(0.25 * CONSTANTS.IntelligenceCrimeBaseExpGain);
|
||||
break;
|
||||
case CONSTANTS.CrimeMug:
|
||||
this.karma -= 0.25;
|
||||
break;
|
||||
case CONSTANTS.CrimeLarceny:
|
||||
this.karma -= 1.5;
|
||||
this.gainIntelligenceExp(0.5 * CONSTANTS.IntelligenceCrimeBaseExpGain);
|
||||
break;
|
||||
case CONSTANTS.CrimeDrugs:
|
||||
this.karma -= 0.5;
|
||||
break;
|
||||
case CONSTANTS.CrimeBondForgery:
|
||||
this.karma -= 0.1;
|
||||
this.gainIntelligenceExp(2 * CONSTANTS.IntelligenceCrimeBaseExpGain);
|
||||
break;
|
||||
case CONSTANTS.CrimeTraffickArms:
|
||||
this.karma -= 1;
|
||||
break;
|
||||
case CONSTANTS.CrimeHomicide:
|
||||
++this.numPeopleKilled;
|
||||
this.karma -= 3;
|
||||
break;
|
||||
case CONSTANTS.CrimeGrandTheftAuto:
|
||||
this.karma -= 5;
|
||||
this.gainIntelligenceExp(CONSTANTS.IntelligenceCrimeBaseExpGain);
|
||||
break;
|
||||
case CONSTANTS.CrimeKidnap:
|
||||
this.karma -= 6;
|
||||
this.gainIntelligenceExp(2 * CONSTANTS.IntelligenceCrimeBaseExpGain);
|
||||
break;
|
||||
case CONSTANTS.CrimeAssassination:
|
||||
++this.numPeopleKilled;
|
||||
this.karma -= 10;
|
||||
this.gainIntelligenceExp(5 * CONSTANTS.IntelligenceCrimeBaseExpGain);
|
||||
break;
|
||||
case CONSTANTS.CrimeHeist:
|
||||
this.karma -= 15;
|
||||
this.gainIntelligenceExp(10 * CONSTANTS.IntelligenceCrimeBaseExpGain);
|
||||
break;
|
||||
default:
|
||||
console.log(this.crimeType);
|
||||
dialogBoxCreate("ERR: Unrecognized crime type. This is probably a bug please contact the developer");
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(crime == null) {
|
||||
console.log(this.crimeType);
|
||||
dialogBoxCreate("ERR: Unrecognized crime type. This is probably a bug please contact the developer");
|
||||
}
|
||||
this.karma -= crime.karma;
|
||||
this.numPeopleKilled += crime.kills;
|
||||
if(crime.intelligence_exp > 0) {
|
||||
this.gainIntelligenceExp(crime.intelligence_exp);
|
||||
}
|
||||
|
||||
//On a crime success, gain 2x exp
|
||||
|
@ -2,6 +2,7 @@ import {deleteActiveScriptsItem} from "./ActiveScriptsUI.js";
|
||||
import {Augmentations, augmentationExists,
|
||||
initAugmentations, AugmentationNames} from "./Augmentations.js";
|
||||
import {initBitNodeMultipliers} from "./BitNode.js";
|
||||
import {Bladeburner} from "./Bladeburner.js";
|
||||
import {writeCinematicText} from "./CinematicText.js";
|
||||
import {Companies, Company, initCompanies} from "./Company.js";
|
||||
import {Programs} from "./CreateProgram.js";
|
||||
@ -125,8 +126,10 @@ function prestigeAugmentation() {
|
||||
}
|
||||
}
|
||||
|
||||
//Reset Bladeburner
|
||||
Player.bladeburner = null;
|
||||
//Cancel Bladeburner action
|
||||
if (Player.bladeburner instanceof Bladeburner) {
|
||||
Player.bladeburner.prestige();
|
||||
}
|
||||
|
||||
//BitNode 8: Ghost of Wall Street
|
||||
if (Player.bitNodeN === 8) {Player.money = new Decimal(BitNode8StartingMoney);}
|
||||
|
@ -113,7 +113,7 @@ function giveSourceFile(bitNodeNumber) {
|
||||
}
|
||||
|
||||
if (alreadyOwned && ownedSourceFile) {
|
||||
if (ownedSourceFile.lvl >= 3) {
|
||||
if (ownedSourceFile.lvl >= 3 && ownedSourceFile.n !== 12) {
|
||||
dialogBoxCreate("The Source-File for the BitNode you just destroyed, " + sourceFile.name + ", " +
|
||||
"is already at max level!");
|
||||
} else {
|
||||
@ -208,7 +208,7 @@ function loadBitVerse(destroyedBitNodeNum, flume=false) {
|
||||
var elemId = "bitnode-" + i.toString();
|
||||
var elem = clearEventListeners(elemId);
|
||||
if (elem == null) {return;}
|
||||
if (i === 1 || i === 2 || i === 3 || i === 4 || i === 5 || i === 6 || i === 8 || i === 11) {
|
||||
if (i === 1 || i === 2 || i === 3 || i === 4 || i === 5 || i === 6 || i === 8 || i === 11 || i === 12) {
|
||||
elem.addEventListener("click", function() {
|
||||
var bitNodeKey = "BitNode" + i;
|
||||
var bitNode = BitNodes[bitNodeKey];
|
||||
|
@ -66,7 +66,7 @@ function initSourceFiles() {
|
||||
"Level 1: 24%<br>" +
|
||||
"Level 2: 36%<br>" +
|
||||
"Level 3: 42%<br>");
|
||||
SourceFiles["SourceFile12"] = new SourceFile(12);
|
||||
SourceFiles["SourceFile12"] = new SourceFile(12, "This Source-File increases all your multipliers by 1% per level");
|
||||
}
|
||||
|
||||
function PlayerOwnedSourceFile(number, level) {
|
||||
@ -181,6 +181,42 @@ function applySourceFile(srcFile) {
|
||||
Player.work_money_mult *= incMult;
|
||||
Player.company_rep_mult *= incMult;
|
||||
break;
|
||||
case 12: //The testing ground
|
||||
const inc = Math.pow(1.01, srcFile.lvl);
|
||||
const dec = Math.pow(0.99, srcFile.lvl);
|
||||
|
||||
Player.hacking_chance_mult *= inc;
|
||||
Player.hacking_speed_mult *= inc;
|
||||
Player.hacking_money_mult *= inc;
|
||||
Player.hacking_grow_mult *= inc;
|
||||
Player.hacking_mult *= inc;
|
||||
|
||||
Player.strength_mult *= inc;
|
||||
Player.defense_mult *= inc;
|
||||
Player.dexterity_mult *= inc;
|
||||
Player.agility_mult *= inc;
|
||||
Player.charisma_mult *= inc;
|
||||
|
||||
Player.hacking_exp_mult *= inc;
|
||||
Player.strength_exp_mult *= inc;
|
||||
Player.defense_exp_mult *= inc;
|
||||
Player.dexterity_exp_mult *= inc;
|
||||
Player.agility_exp_mult *= inc;
|
||||
Player.charisma_exp_mult *= inc;
|
||||
|
||||
Player.company_rep_mult *= inc;
|
||||
Player.faction_rep_mult *= inc;
|
||||
|
||||
Player.crime_money_mult *= inc;
|
||||
Player.crime_success_mult *= inc;
|
||||
|
||||
Player.hacknet_node_money_mult *= inc;
|
||||
Player.hacknet_node_purchase_cost_mult *= dec;
|
||||
Player.hacknet_node_ram_cost_mult *= dec;
|
||||
Player.hacknet_node_core_cost_mult *= dec;
|
||||
Player.hacknet_node_level_cost_mult *= dec;
|
||||
|
||||
Player.work_money_mult *= inc;
|
||||
default:
|
||||
console.log("ERROR: Invalid source file number: " + srcFile.n);
|
||||
break;
|
||||
|
@ -11,7 +11,7 @@ import {clearEventListeners, getRandomInt,
|
||||
clearEventListenersEl} from "../utils/HelperFunctions.js";
|
||||
import {Reviver, Generic_toJSON,
|
||||
Generic_fromJSON} from "../utils/JSONReviver.js";
|
||||
import numeral from "../utils/numeral.min.js";
|
||||
import numeral from "numeral/min/numeral.min";
|
||||
import {formatNumber} from "../utils/StringHelperFunctions.js";
|
||||
import {yesNoBoxCreate, yesNoTxtInpBoxCreate,
|
||||
yesNoBoxGetYesButton, yesNoBoxGetNoButton,
|
||||
|
@ -3,7 +3,7 @@ import {gameOptionsBoxOpen, gameOptionsBoxClose}from "../utils/GameOptions.js";
|
||||
import {clearEventListeners, createElement,
|
||||
removeChildrenFromElement,
|
||||
exceptionAlert} from "../utils/HelperFunctions.js";
|
||||
import numeral from "../utils/numeral.min.js";
|
||||
import numeral from "numeral/min/numeral.min";
|
||||
import {formatNumber,
|
||||
convertTimeMsToTimeElapsedString} from "../utils/StringHelperFunctions.js";
|
||||
import {loxBoxCreate, logBoxUpdateText,
|
||||
|
@ -1,4 +1,5 @@
|
||||
import {executeJSScript} from "../src/NetscriptJSEvaluator.js";
|
||||
import {WorkerScript} from "../src/NetscriptWorker.js";
|
||||
|
||||
const chai = require("chai");
|
||||
const chaiAsPromised = require("chai-as-promised");
|
||||
@ -9,17 +10,19 @@ console.info('asdf');
|
||||
|
||||
describe('NSJS ScriptStore', function() {
|
||||
it('should run an imported function', async function() {
|
||||
const s = { filename: "", code: "export function main() { return 2; }" };
|
||||
chai.expect(await executeJSScript(s)).to.equal(2);
|
||||
const s = { filename: "", code: "export function main() { return 2; }", args:[]};
|
||||
const worker = new WorkerScript(s);
|
||||
chai.expect(await executeJSScript([], s)).to.equal(2);
|
||||
});
|
||||
|
||||
/*
|
||||
it('should handle recursive imports', async function() {
|
||||
const s1 = { filename: "s1.js", code: "export function iAmRecursiveImport(x) { return x + 2; }" };
|
||||
const s2 = { filename: "", code: `
|
||||
import {iAmRecursiveImport} from \"s1.js\";
|
||||
export function main() { return iAmRecursiveImport(3);
|
||||
}`};
|
||||
chai.expect(await executeJSScript(s2, [s1, s2])).to.equal(5);
|
||||
chai.expect(await executeJSScript([s1, s2], s2)).to.equal(5);
|
||||
});
|
||||
|
||||
it (`should correctly reference the passed global env`, async function() {
|
||||
@ -45,5 +48,5 @@ describe('NSJS ScriptStore', function() {
|
||||
export function main() {}
|
||||
`}
|
||||
executeJSScript(s2, [s1, s2]).should.eventually.throw();
|
||||
});
|
||||
});
|
||||
});*/
|
||||
});
|
||||
|
@ -11,7 +11,7 @@
|
||||
<script src="https://unpkg.com/mocha@4.0.1/mocha.js"></script>
|
||||
|
||||
<script>mocha.setup('bdd')</script>
|
||||
<script type="module" src="../dist/tests.bundle.js"></script>
|
||||
<script type="module" src="tests.bundle.js"></script>
|
||||
<script type="module">
|
||||
mocha.checkLeaks();
|
||||
mocha.run();
|
||||
|
File diff suppressed because it is too large
Load Diff
1
tests/tests.bundle.js.map
Normal file
1
tests/tests.bundle.js.map
Normal file
File diff suppressed because one or more lines are too long
@ -74,6 +74,21 @@ function removeChildrenFromElement(el) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a reference to the first object with the specified value of the ID or NAME attribute, throwing an error if it is unable to find it.
|
||||
* @param {string} elementId The HTML ID to retrieve the element by.
|
||||
* @returns {HTMLElement} The single element.
|
||||
* @throws {Error} When the 'idString' cannot be found.
|
||||
*/
|
||||
function getElementById(elementId) {
|
||||
var el = document.getElementById(elementId);
|
||||
if (el == null) {
|
||||
throw new Error("Unable to find element with id '" + elementId + "'");
|
||||
}
|
||||
|
||||
return el;
|
||||
}
|
||||
|
||||
function createElement(type, params={}) {
|
||||
var el = document.createElement(type);
|
||||
if (params.id) {el.id = params.id;}
|
||||
@ -260,4 +275,4 @@ export {sizeOfObject, clearObject, addOffset, clearEventListeners, getRandomInt,
|
||||
removeElementById, removeElement, createElement, createAccordionElement,
|
||||
appendLineBreaks,
|
||||
removeChildrenFromElement, createPopup, clearSelector, exceptionAlert,
|
||||
createProgressBarText};
|
||||
createProgressBarText, getElementById};
|
||||
|
7
utils/jsplumb.min.js
vendored
7
utils/jsplumb.min.js
vendored
File diff suppressed because one or more lines are too long
8
utils/numeral.min.js
vendored
8
utils/numeral.min.js
vendored
File diff suppressed because one or more lines are too long
@ -16,14 +16,13 @@ module.exports = {
|
||||
],
|
||||
target: "web",
|
||||
entry: {
|
||||
engine: "./src/engine.js",
|
||||
tests: "./tests/index.js",
|
||||
"dist/engine": "./src/engine.js",
|
||||
"tests/tests": "./tests/index.js",
|
||||
},
|
||||
devtool: "nosources-source-map",
|
||||
devtool: "source-map",
|
||||
output: {
|
||||
path: path.resolve(__dirname, "dist"),
|
||||
filename: "[name].bundle.js",
|
||||
devtoolModuleFilenameTemplate: "[id]"
|
||||
path: path.resolve(__dirname, "./"),
|
||||
filename: "[name].bundle.js"
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
|
Loading…
Reference in New Issue
Block a user