mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-11-21 23:23:51 +01:00
v0.35.2
This commit is contained in:
parent
6255971e96
commit
521b81aec0
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,4 +1,3 @@
|
||||
Changelog.txt
|
||||
Netburner.txt
|
||||
README.md
|
||||
/node_modules
|
||||
/node_modules
|
||||
|
31
README.md
Normal file
31
README.md
Normal file
@ -0,0 +1,31 @@
|
||||
# Bitburner
|
||||
Bitburner is a cyberpunk hacking-themed incremental game. The game can be
|
||||
played [here](https://danielyxie.github.io/bitburner).
|
||||
|
||||
# Documentation
|
||||
The game's official documentation can be found [here](http://bitburner.readthedocs.io/en/latest/index.html). Please note that
|
||||
this is still a work-in-progress and is in its early stages.
|
||||
|
||||
The documentation is created using Sphinx and is hosted on Read The Docs.
|
||||
|
||||
Anyone is welcome to contribute to the documentation by editing the source files
|
||||
in /doc/ and then making a pull request with your changes/contributions.
|
||||
|
||||
# Wiki
|
||||
The game's wiki can be found [here](http://bitburner.wikia.com/wiki/Bitburner_Wiki).
|
||||
Please note that the wiki is in the process of being deprecated. Eventually all of the
|
||||
wiki content will be moved into the Read The Docs documentation.
|
||||
|
||||
# Contributing
|
||||
If you would like to make any small change or addition to the game, you may go ahead
|
||||
and do so by submitting a pull request.
|
||||
|
||||
You will retain all ownership of the Copyright of any contributions you make,
|
||||
and will have the same rights to use or license your contributions. By
|
||||
submitting a pull request you agree to grant me perpetual, worldwide, non-exclusive,
|
||||
transferable, royalty-free, and irrevocable rights to use, publish, and distribute
|
||||
your contributions to the project. A formal Contributor's License Agreement
|
||||
will be drawn up in the future.
|
||||
|
||||
If you would like to make significant contributions to the project as a
|
||||
collaborator, please message me privately.
|
@ -367,32 +367,17 @@
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
#factions-list li {
|
||||
padding: 6px;
|
||||
margin: 6px;
|
||||
}
|
||||
|
||||
#faction-favor, #faction-reputation {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.faction-work-div {
|
||||
overflow: hidden;
|
||||
width: 70%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.faction-work-div-wrapper {
|
||||
float: left;
|
||||
overflow:hidden;
|
||||
border: 2px solid #333;
|
||||
padding: 14px 6px 4px 6px;
|
||||
padding: 6px;
|
||||
margin: 6px;
|
||||
}
|
||||
|
||||
#faction-hack-button,
|
||||
#faction-fieldwork-button,
|
||||
#faction-securitywork-button {
|
||||
margin: 8px;
|
||||
width:70%;
|
||||
}
|
||||
|
||||
#faction-donate-amount-txt,
|
||||
@ -408,18 +393,14 @@
|
||||
width:50%;
|
||||
}
|
||||
|
||||
div.faction-clear {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
#faction-container p,
|
||||
#faction-container pre {
|
||||
padding: 6px;
|
||||
margin: 6px;
|
||||
width: 70%;
|
||||
}
|
||||
|
||||
#faction-info {
|
||||
#faction-container pre {
|
||||
width: 70%;
|
||||
white-space: pre-wrap; /* Since CSS 2.1 */
|
||||
white-space: -moz-pre-wrap; /* Mozilla, since 1999 */
|
||||
white-space: -pre-wrap; /* Opera 4-6 */
|
||||
@ -441,11 +422,6 @@ div.faction-clear {
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
#faction-augmentations-list > li{
|
||||
margin: 4px;
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
/* World */
|
||||
#world-container li {
|
||||
margin: 0 0 15px 0;
|
||||
@ -458,29 +434,13 @@ div.faction-clear {
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
|
||||
#augmentations-list li,
|
||||
#queued-augmentations-list li {
|
||||
width: 70%;
|
||||
background-color: #333;
|
||||
}
|
||||
|
||||
#augmentations-list h2,
|
||||
#augmentations-list p,
|
||||
#queued-augmentations-list h2,
|
||||
#queued-augmentations-list p {
|
||||
margin: 4px;
|
||||
.augmentations-list button,
|
||||
.augmentations-list div {
|
||||
color: var(--my-font-color);
|
||||
padding: 8px;
|
||||
width: 70%;
|
||||
background-color: #333;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
#augmentations-list li p {
|
||||
width: 95%;
|
||||
}
|
||||
|
||||
/* Tutorial */
|
||||
#tutorial-container {
|
||||
position: fixed;
|
||||
|
67392
dist/bundle.js
vendored
67392
dist/bundle.js
vendored
File diff suppressed because one or more lines are too long
143
index.html
143
index.html
@ -428,11 +428,7 @@
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<ul id="generic-locations-list">
|
||||
<li id="generic-location-wse-li">
|
||||
<a id="generic-location-wse" class="a-link-button">World Stock Exchange</a>
|
||||
</li>
|
||||
</ul>
|
||||
<ul id="generic-locations-list"></ul>
|
||||
</div>
|
||||
|
||||
<!-- Create a program(executable) -->
|
||||
@ -447,144 +443,15 @@
|
||||
</div>
|
||||
|
||||
<!-- Factions -->
|
||||
<div id="factions-container" class="generic-menupage-container">
|
||||
<h1> Factions </h1>
|
||||
<p> Lists all factions you have joined </p>
|
||||
<ul class="factions-list" id="factions-list"></ul>
|
||||
<br><br>
|
||||
<h1> Outstanding Faction Invitations </h1>
|
||||
<p style="width:70%;"> Lists factions you have been invited to, as well as factions you have previously rejected.
|
||||
You can accept these faction invitations at any times </p>
|
||||
<ul class="factions-list" id="outstanding-faction-invitations-list"></ul>
|
||||
</div>
|
||||
<div id="factions-container" class="generic-menupage-container"></div>
|
||||
|
||||
<!-- Single Faction info (when you select a faction from the Factions menu) -->
|
||||
<div id="faction-container" class="generic-menupage-container">
|
||||
<h1 id="faction-name"></h1>
|
||||
<pre id="faction-info"></pre>
|
||||
<p> --------------- </p>
|
||||
<p id="faction-reputation" class="tooltip"></p>
|
||||
<p> --------------- </p>
|
||||
<p id="faction-favor" class="tooltip"></p>
|
||||
<p> --------------- </p>
|
||||
<p id="faction-work-description-text">
|
||||
Perform work/carry out assignments for your faction to help further its cause! By doing so
|
||||
you will earn reputation for your faction. You will also gain reputation passively over time,
|
||||
although at a very slow rate. Earning reputation will allow you to purchase Augmentations
|
||||
through this faction, which are powerful upgrades that enhance your abilities. Note that you cannot
|
||||
use your terminal or create scripts when you are performing a task! <br><br><br><br>
|
||||
</p>
|
||||
<div id="faction-container" class="generic-menupage-container"></div>
|
||||
|
||||
<div id="faction-hack-mission-div" class="faction-work-div">
|
||||
<div id="faction-hack-mission-div-wrapper" class="faction-work-div-wrapper">
|
||||
<a id="faction-hack-mission-button" class="a-link-button">Hacking Mission</a>
|
||||
<p id="faction-hack-mission-text">
|
||||
Attempt a hacking mission for your faction.
|
||||
A mission is a mini game that, if won, earns you significant reputation with this faction. (Recommended hacking level: 200+)
|
||||
</p>
|
||||
</div>
|
||||
<div class="faction-clear"></div>
|
||||
</div>
|
||||
|
||||
<div id="faction-hack-div" class="faction-work-div">
|
||||
<div id="faction-hack-div-wrapper" class="faction-work-div-wrapper">
|
||||
<a id="faction-hack-button" class="a-link-button">Hacking Contracts</a>
|
||||
<p id="faction-hack-text">
|
||||
Complete hacking contracts for your faction.
|
||||
Your effectiveness, which determines how much reputation you gain for this faction, is based on your hacking skill.
|
||||
You will gain hacking exp.
|
||||
</p>
|
||||
</div>
|
||||
<div class="faction-clear"></div>
|
||||
</div>
|
||||
|
||||
<div id="faction-fieldwork-div" class="faction-work-div">
|
||||
<div id="faction-fieldwork-div-wrapper" class="faction-work-div-wrapper">
|
||||
<a id="faction-fieldwork-button" class="a-link-button">Field Work</a>
|
||||
<p id="faction-fieldwork-text">
|
||||
Carry out field missions for your faction.
|
||||
Your effectiveness, which determines how much reputation you gain for this faction, is based on all of your stats.
|
||||
You will gain exp for all stats.
|
||||
</p>
|
||||
</div>
|
||||
<div class="faction-clear"></div>
|
||||
</div>
|
||||
|
||||
<div id="faction-securitywork-div" class="faction-work-div">
|
||||
<div id="faction-securitywork-div-wrapper" class="faction-work-div-wrapper">
|
||||
<a id="faction-securitywork-button" class="a-link-button">Security Work</a>
|
||||
<p id="faction-securitywork-text">
|
||||
Serve in a security detail for your faction.
|
||||
Your effectiveness, which determines how much reputation you gain for this faction, is based on your combat stats.
|
||||
You will gain exp for all combat stats.
|
||||
</p>
|
||||
</div>
|
||||
<div class="faction-clear"></div>
|
||||
</div>
|
||||
|
||||
<div id="faction-donate-div" class="faction-work-div">
|
||||
<div id="faction-donate-div-wrapper" class="faction-work-div-wrapper">
|
||||
<a id="faction-donate-button" class="a-link-button">Donate Money</a>
|
||||
<p id="faction-donate-text">
|
||||
Donate money to your faction. You will gain reputation based on how much money you donate
|
||||
</p>
|
||||
<div>
|
||||
<label id="faction-donate-amount-txt">Enter amount to donate: $</label>
|
||||
<input id="faction-donate-input" type="number"> </input>
|
||||
</div>
|
||||
<p id="faction-donate-rep-gain"> This donation will result in 0 reputation gain</p>
|
||||
|
||||
</div>
|
||||
<div class="faction-clear"></div>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
<br>
|
||||
As your reputation with this faction rises, you will unlock Augmentations, which you
|
||||
can purchase to enhance your abilities.
|
||||
<br><br>
|
||||
</p>
|
||||
<a id="faction-purchase-augmentations" class="a-link-button">Purchase Augmentations</a>
|
||||
<br><br><br><br>
|
||||
</div>
|
||||
|
||||
<div id="faction-augmentations-container" class="generic-menupage-container">
|
||||
<a id="faction-augmentations-back-button" class="a-link-button"> Back </a>
|
||||
<h1> Faction Augmentations </h1>
|
||||
<p id="faction-augmentations-page-desc"> Lists all augmentations that are available to purchase from </p>
|
||||
|
||||
<ul class="faction-augmentations-list" id="faction-augmentations-list">
|
||||
</ul>
|
||||
</div>
|
||||
<div id="faction-augmentations-container" class="generic-menupage-container"></div>
|
||||
|
||||
<!-- Augmentations -->
|
||||
<div id="augmentations-container" class="generic-menupage-container">
|
||||
<h1> Purchased Augmentations </h1>
|
||||
<p style="width:70%;">
|
||||
Below is a list of all Augmentations you have purchased but not yet installed. Click the button below to install them.
|
||||
<br>WARNING: Installing your Augmentations resets most of your progress, including: <br><br>
|
||||
Stats/Skill levels and Experience <br>
|
||||
Money <br>
|
||||
Scripts on every computer but your home computer<br>
|
||||
Purchased servers <br>
|
||||
Hacknet Nodes <br>
|
||||
Faction/Company reputation <br>
|
||||
Stocks<br><br>
|
||||
Installing Augmentations lets you start over with the perks and benefits granted by all
|
||||
of the Augmentations you have ever installed. Also, you will keep any scripts and RAM/Core upgrades
|
||||
on your home computer (but you will lose all programs besides NUKE.exe).
|
||||
</p>
|
||||
<br><br>
|
||||
<ul id="queued-augmentations-list"></ul>
|
||||
<br>
|
||||
<a id="install-augmentations-button" class="a-link-button"> Install Augmentations </a>
|
||||
<a id="install-augmentations-backup-button" class="a-link-button"> Backup Save (Export) </a>
|
||||
<br><br>
|
||||
<h1> Installed Augmentations </h1>
|
||||
<p style="width:70%;"> List of all augmentations (including Source Files) that have been installed. You have gained the effects of these augmentations </p>
|
||||
<ul id="augmentations-list">
|
||||
</ul>
|
||||
</div>
|
||||
<div id="augmentations-container" class="generic-menupage-container"></div>
|
||||
|
||||
<!-- Tutorial content -->
|
||||
<div id="tutorial-container" class="generic-menupage-container">
|
||||
|
@ -1,12 +1,16 @@
|
||||
import {BitNodeMultipliers} from "./BitNode.js";
|
||||
import {CONSTANTS} from "./Constants.js";
|
||||
import {Engine} from "./engine.js";
|
||||
import {Factions, getNextNeurofluxLevel} from "./Faction.js";
|
||||
import {addWorkerScript} from "./NetscriptWorker.js";
|
||||
import {Player} from "./Player.js";
|
||||
import {prestigeAugmentation} from "./Prestige.js";
|
||||
import {Script, RunningScript} from "./Script.js";
|
||||
import {Server} from "./Server.js";
|
||||
import {SourceFiles} from "./SourceFile.js";
|
||||
import {dialogBoxCreate} from "../utils/DialogBox.js";
|
||||
import {createElement, createAccordionElement,
|
||||
removeChildrenFromElement} from "../utils/HelperFunctions.js";
|
||||
import {Reviver, Generic_toJSON,
|
||||
Generic_fromJSON} from "../utils/JSONReviver.js";
|
||||
import {isString} from "../utils/StringHelperFunctions.js";
|
||||
@ -2083,5 +2087,172 @@ function giveAllAugmentations() {
|
||||
Player.reapplyAllAugmentations();
|
||||
}
|
||||
|
||||
function displayAugmentationsContent() {
|
||||
removeChildrenFromElement(Engine.Display.augmentationsContent);
|
||||
Engine.Display.augmentationsContent.appendChild(createElement("h1", {
|
||||
innerText:"Purchased Augmentations",
|
||||
}));
|
||||
|
||||
Engine.Display.augmentationsContent.appendChild(createElement("pre", {
|
||||
width:"70%", whiteSpace:"pre-wrap", display:"block",
|
||||
innerText:"Below is a list of all Augmentations you have purchased but not yet installed. Click the button below to install them.\n" +
|
||||
"WARNING: Installing your Augmentations resets most of your progress, including:\n\n" +
|
||||
"Stats/Skill levels and Experience\n" +
|
||||
"Money\n" +
|
||||
"Scripts on every computer but your home computer\n" +
|
||||
"Purchased servers\n" +
|
||||
"Hacknet Nodes\n" +
|
||||
"Faction/Company reputation\n" +
|
||||
"Stocks\n\n" +
|
||||
"Installing Augmentations lets you start over with the perks and benefits granted by all " +
|
||||
"of the Augmentations you have ever installed. Also, you will keep any scripts and RAM/Core upgrades " +
|
||||
"on your home computer (but you will lose all programs besides NUKE.exe)."
|
||||
}));
|
||||
|
||||
//Install Augmentations button
|
||||
Engine.Display.augmentationsContent.appendChild(createElement("a", {
|
||||
class:"a-link-button", innerText:"Install Augmentations",
|
||||
tooltip:"'I never asked for this'",
|
||||
clickListener:()=>{
|
||||
installAugmentations();
|
||||
return false;
|
||||
}
|
||||
}));
|
||||
|
||||
//Backup button
|
||||
Engine.Display.augmentationsContent.appendChild(createElement("a", {
|
||||
class:"a-link-button flashing-button", innerText:"Backup Save (Export)",
|
||||
tooltip:"It's always a good idea to backup/export your save!",
|
||||
clickListener:()=>{
|
||||
saveObject.exportGame();
|
||||
return false;
|
||||
}
|
||||
}));
|
||||
|
||||
//Purchased/queued augmentations list
|
||||
var queuedAugmentationsList = createElement("ul", {class:"augmentations-list"});
|
||||
|
||||
for (var i = 0; i < Player.queuedAugmentations.length; ++i) {
|
||||
var augName = Player.queuedAugmentations[i].name;
|
||||
var aug = Augmentations[augName];
|
||||
|
||||
var displayName = augName;
|
||||
if (augName === AugmentationNames.NeuroFluxGovernor) {
|
||||
displayName += " - Level " + (Player.queuedAugmentations[i].level);
|
||||
}
|
||||
|
||||
var accordion = createAccordionElement({hdrText:displayName, panelText:aug.info});
|
||||
queuedAugmentationsList.appendChild(accordion[0]);
|
||||
}
|
||||
Engine.Display.augmentationsContent.appendChild(queuedAugmentationsList);
|
||||
|
||||
//Installed augmentations list
|
||||
Engine.Display.augmentationsContent.appendChild(createElement("h1", {
|
||||
innerText:"Installed Augmentations", marginTop:"8px",
|
||||
}));
|
||||
Engine.Display.augmentationsContent.appendChild(createElement("p", {
|
||||
width:"70%", whiteSpace:"pre-wrap",
|
||||
innerText:"List of all Augmentations (including Source Files) that have been " +
|
||||
"installed. You have gained the effects of these Augmentations."
|
||||
}));
|
||||
|
||||
var augmentationsList = createElement("ul", {class:"augmentations-list"});
|
||||
|
||||
//Expand/Collapse All buttons
|
||||
Engine.Display.augmentationsContent.appendChild(createElement("a", {
|
||||
class:"a-link-button", fontSize:"14px", innerText:"Expand All", display:"inline-block",
|
||||
clickListener:()=>{
|
||||
var allHeaders = augmentationsList.getElementsByClassName("accordion-header");
|
||||
for (var i = 0; i < allHeaders.length; ++i) {
|
||||
if (!allHeaders[i].classList.contains("active")) {allHeaders[i].click();}
|
||||
}
|
||||
}
|
||||
}));
|
||||
Engine.Display.augmentationsContent.appendChild(createElement("a", {
|
||||
class:"a-link-button", fontSize:"14px", innerText:"Collapse All", display:"inline-block",
|
||||
clickListener:()=>{
|
||||
var allHeaders = augmentationsList.getElementsByClassName("accordion-header");
|
||||
for (var i = 0; i < allHeaders.length; ++i) {
|
||||
if (allHeaders[i].classList.contains("active")) {allHeaders[i].click();}
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
//Sort Buttons
|
||||
Engine.Display.augmentationsContent.appendChild(createElement("a", {
|
||||
class:"a-link-button", fontSize:"14px", innerText:"Sort in Order",
|
||||
tooltip:"Sorts the Augmentations alphabetically and Source Files in numerical order (1, 2, 3,...)",
|
||||
clickListener:()=>{
|
||||
removeChildrenFromElement(augmentationsList);
|
||||
|
||||
//Create a copy of Player's Source Files and augs array and sort them
|
||||
var sourceFiles = Player.sourceFiles.slice();
|
||||
var augs = Player.augmentations.slice();
|
||||
sourceFiles.sort((sf1, sf2)=>{
|
||||
return sf1.n - sf2.n;
|
||||
});
|
||||
augs.sort((aug1, aug2)=>{
|
||||
return aug1.name <= aug2.name ? -1 : 1;
|
||||
});
|
||||
displaySourceFiles(augmentationsList, sourceFiles);
|
||||
displayAugmentations(augmentationsList, augs);
|
||||
}
|
||||
}));
|
||||
|
||||
Engine.Display.augmentationsContent.appendChild(createElement("a", {
|
||||
class:"a-link-button", fontSize:"14px", innerText:"Sort by Acquirement Time",
|
||||
tooltip:"Sorts the Augmentations and Source Files based on when you acquired them (same as default)",
|
||||
clickListener:()=>{
|
||||
removeChildrenFromElement(augmentationsList);
|
||||
displaySourceFiles(augmentationsList, Player.sourceFiles);
|
||||
displayAugmentations(augmentationsList, Player.augmentations);
|
||||
}
|
||||
}));
|
||||
|
||||
//Source Files - Temporary...Will probably put in a separate pane Later
|
||||
displaySourceFiles(augmentationsList, Player.sourceFiles);
|
||||
displayAugmentations(augmentationsList, Player.augmentations);
|
||||
Engine.Display.augmentationsContent.appendChild(augmentationsList);
|
||||
}
|
||||
|
||||
//Creates the accordion elements to display Augmentations
|
||||
// @listElement - List DOM element to append accordion elements to
|
||||
// @augs - Array of Augmentation objects
|
||||
function displayAugmentations(listElement, augs) {
|
||||
for (var i = 0; i < augs.length; ++i) {
|
||||
var augName = augs[i].name;
|
||||
var aug = Augmentations[augName];
|
||||
|
||||
var displayName = augName;
|
||||
if (augName === AugmentationNames.NeuroFluxGovernor) {
|
||||
displayName += " - Level " + (augs[i].level);
|
||||
}
|
||||
var accordion = createAccordionElement({hdrText:displayName, panelText:aug.info});
|
||||
listElement.appendChild(accordion[0]);
|
||||
}
|
||||
}
|
||||
|
||||
//Creates the accordion elements to display Source Files
|
||||
// @listElement - List DOM element to append accordion elements to
|
||||
// @sourceFiles - Array of Source File objects
|
||||
function displaySourceFiles(listElement, sourceFiles) {
|
||||
for (var i = 0; i < sourceFiles.length; ++i) {
|
||||
var srcFileKey = "SourceFile" + sourceFiles[i].n;
|
||||
var sourceFileObject = SourceFiles[srcFileKey];
|
||||
if (sourceFileObject == null) {
|
||||
console.log("ERROR: Invalid source file number: " + sourceFiles[i].n);
|
||||
continue;
|
||||
}
|
||||
var accordion = createAccordionElement({
|
||||
hdrText:sourceFileObject.name + "<br>" + "Level " + (sourceFiles[i].lvl) + " / 3",
|
||||
panelText:sourceFileObject.info
|
||||
});
|
||||
|
||||
listElement.appendChild(accordion[0]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export {AugmentationNames, Augmentations, PlayerOwnedAugmentation, installAugmentations,
|
||||
initAugmentations, applyAugmentation, augmentationExists, Augmentation};
|
||||
initAugmentations, applyAugmentation, augmentationExists, Augmentation,
|
||||
displayAugmentationsContent};
|
||||
|
@ -69,6 +69,8 @@ var OfficeUpgradeBaseCost = 1e9;
|
||||
var BribeThreshold = 100e12; //Money needed to be able to bribe for faction rep
|
||||
var BribeToRepRatio = 1e9; //Bribe Value divided by this = rep gain
|
||||
|
||||
var ProductProductionCostRatio = 5; //Ratio of material cost of a product to its production cost
|
||||
|
||||
function Material(params={}) {
|
||||
this.name = params.name ? params.name : "";
|
||||
this.qty = 0; //Quantity
|
||||
@ -90,6 +92,7 @@ function Material(params={}) {
|
||||
this.sll = 0; //How much of this material is being sold per second
|
||||
this.prd = 0; //How much of this material is being produced per second
|
||||
this.exp = []; //Exports of this material to another warehouse/industry
|
||||
this.totalExp = 0; //Total export amount for last cycle
|
||||
this.imp = 0;
|
||||
this.bCost = 0; //$ Cost/sec to buy material
|
||||
this.sCost = 0; //$ Cost/sec to sell material
|
||||
@ -323,7 +326,7 @@ Product.prototype.finishProduct = function(employeeProd, industry) {
|
||||
console.log("designMult: " + designMult);
|
||||
var balanceMult = (1.2 * engrRatio) + (0.9 * mgmtRatio) + (1.3 * rndRatio) +
|
||||
(1.5 * opsRatio) + (busRatio);
|
||||
var sciMult = 1 + (Math.pow(industry.sciResearch.qty, industry.sciFac) / 1000);
|
||||
var sciMult = 1 + (Math.pow(industry.sciResearch.qty, industry.sciFac) / 800);
|
||||
var totalMult = progrMult * balanceMult * designMult * sciMult;
|
||||
|
||||
this.qlt = totalMult * ((0.10 * employeeProd[EmployeePositions.Engineer]) +
|
||||
@ -358,7 +361,7 @@ Product.prototype.finishProduct = function(employeeProd, industry) {
|
||||
(0.05 * employeeProd[EmployeePositions.Business]));
|
||||
this.calculateRating(industry);
|
||||
var advMult = 1 + (Math.pow(this.advCost, 0.1) / 100);
|
||||
this.mku = 100 / (advMult * Math.pow((this.qlt + 0.001), 0.6) * (busRatio + mgmtRatio));
|
||||
this.mku = 100 / (advMult * Math.pow((this.qlt + 0.001), 0.65) * (busRatio + mgmtRatio));
|
||||
this.dmd = industry.awareness === 0 ? 20 : Math.min(100, advMult * (100 * (industry.popularity / industry.awareness)));
|
||||
this.cmp = getRandomInt(0, 70);
|
||||
|
||||
@ -516,6 +519,14 @@ var ProductRatingWeights = {
|
||||
Aesthetics: 0.05,
|
||||
Features: 0.1,
|
||||
},
|
||||
"Computer" : { //Repeat
|
||||
Quality: 0.15,
|
||||
Performance: 0.25,
|
||||
Durability: 0.25,
|
||||
Reliability: 0.2,
|
||||
Aesthetics: 0.05,
|
||||
Features: 0.1,
|
||||
},
|
||||
[Industries.Robotics]: {
|
||||
Quality: 0.1,
|
||||
Performance: 0.2,
|
||||
@ -553,11 +564,11 @@ var ProductRatingWeights = {
|
||||
var IndustryUpgrades = {
|
||||
"0": [0, 500e3, 1, 1.05,
|
||||
"Coffee", "Provide your employees with coffee, increasing their energy by 5%."],
|
||||
"1": [1, 1e9, 1.05, 1.03,
|
||||
"1": [1, 1e9, 1.06, 1.03,
|
||||
"AdVert.Inc", "Hire AdVert.Inc to advertise your company. Each level of " +
|
||||
"this upgrade grants your company a static increase of 4 and 1 to its awareness and " +
|
||||
"this upgrade grants your company a static increase of 3 and 1 to its awareness and " +
|
||||
"popularity, respectively. It will then increase your company's awareness by 1%, and its popularity " +
|
||||
"by a random percentage between 2% and 4%. These effects are increased by other upgrades " +
|
||||
"by a random percentage between 1% and 3%. These effects are increased by other upgrades " +
|
||||
"that increase the power of your advertising."]
|
||||
}
|
||||
|
||||
@ -645,28 +656,28 @@ Industry.prototype.init = function() {
|
||||
this.sciFac = 0.7;
|
||||
this.robFac = 0.05;
|
||||
this.aiFac = 0.3;
|
||||
this.advFac = 0.07;
|
||||
this.advFac = 0.08;
|
||||
this.reqMats = {
|
||||
"Hardware": 0.1,
|
||||
"Metal": 0.25,
|
||||
"Metal": 0.2,
|
||||
};
|
||||
this.prodMats = ["Energy"];
|
||||
break;
|
||||
case Industries.Utilities:
|
||||
case "Utilities":
|
||||
this.reFac = 0.4;
|
||||
this.reFac = 0.5;
|
||||
this.sciFac = 0.6;
|
||||
this.robFac = 0.3;
|
||||
this.aiFac = 0.3;
|
||||
this.advFac = 0.07;
|
||||
this.robFac = 0.4;
|
||||
this.aiFac = 0.4;
|
||||
this.advFac = 0.08;
|
||||
this.reqMats = {
|
||||
"Hardware": 0.1,
|
||||
"Metal": 0.2,
|
||||
"Metal": 0.1,
|
||||
}
|
||||
this.prodMats = ["Water"];
|
||||
break;
|
||||
case Industries.Agriculture:
|
||||
this.reFac = 0.8;
|
||||
this.reFac = 0.75;
|
||||
this.sciFac = 0.5;
|
||||
this.hwFac = 0.2;
|
||||
this.robFac = 0.3;
|
||||
@ -684,7 +695,7 @@ Industry.prototype.init = function() {
|
||||
this.hwFac = 0.35;
|
||||
this.robFac = 0.5;
|
||||
this.aiFac = 0.2;
|
||||
this.advFac = 0.06;
|
||||
this.advFac = 0.08;
|
||||
this.reqMats = {
|
||||
"Energy": 0.5,
|
||||
}
|
||||
@ -692,11 +703,11 @@ Industry.prototype.init = function() {
|
||||
break;
|
||||
case Industries.Mining:
|
||||
this.reFac = 0.3;
|
||||
this.sciFac = 0.25;
|
||||
this.sciFac = 0.26;
|
||||
this.hwFac = 0.4;
|
||||
this.robFac = 0.5;
|
||||
this.aiFac = 0.5;
|
||||
this.advFac = 0.04;
|
||||
this.robFac = 0.45;
|
||||
this.aiFac = 0.45;
|
||||
this.advFac = 0.06;
|
||||
this.reqMats = {
|
||||
"Energy": 0.8,
|
||||
}
|
||||
@ -736,7 +747,7 @@ Industry.prototype.init = function() {
|
||||
this.hwFac = 0.2;
|
||||
this.robFac = 0.25;
|
||||
this.aiFac = 0.2;
|
||||
this.advFac = 0.05;
|
||||
this.advFac = 0.07;
|
||||
this.reqMats = {
|
||||
"Plants": 1,
|
||||
"Energy": 0.5,
|
||||
@ -750,7 +761,7 @@ Industry.prototype.init = function() {
|
||||
this.hwFac = 0.15;
|
||||
this.robFac = 0.25;
|
||||
this.aiFac = 0.2;
|
||||
this.advFac = 0.15;
|
||||
this.advFac = 0.16;
|
||||
this.reqMats = {
|
||||
"Chemicals": 2,
|
||||
"Energy": 1,
|
||||
@ -762,9 +773,9 @@ Industry.prototype.init = function() {
|
||||
case Industries.Computer:
|
||||
case "Computer":
|
||||
this.reFac = 0.2;
|
||||
this.sciFac = 0.65;
|
||||
this.robFac = 0.4;
|
||||
this.aiFac = 0.2;
|
||||
this.sciFac = 0.62;
|
||||
this.robFac = 0.36;
|
||||
this.aiFac = 0.19;
|
||||
this.advFac = 0.17;
|
||||
this.reqMats = {
|
||||
"Metal": 2.5,
|
||||
@ -774,11 +785,11 @@ Industry.prototype.init = function() {
|
||||
this.makesProducts = true;
|
||||
break;
|
||||
case Industries.Robotics:
|
||||
this.reFac = 0.35;
|
||||
this.sciFac = 0.7;
|
||||
this.aiFac = 0.4;
|
||||
this.advFac = 0.2;
|
||||
this.hwFac = 0.2;
|
||||
this.reFac = 0.32;
|
||||
this.sciFac = 0.65;
|
||||
this.aiFac = 0.36;
|
||||
this.advFac = 0.18;
|
||||
this.hwFac = 0.19;
|
||||
this.reqMats = {
|
||||
"Hardware": 5,
|
||||
"Energy": 3,
|
||||
@ -787,7 +798,7 @@ Industry.prototype.init = function() {
|
||||
this.makesProducts = true;
|
||||
break;
|
||||
case Industries.Software:
|
||||
this.sciFac = 0.65;
|
||||
this.sciFac = 0.62;
|
||||
this.advFac = 0.16;
|
||||
this.hwFac = 0.25;
|
||||
this.reFac = 0.1;
|
||||
@ -801,9 +812,9 @@ Industry.prototype.init = function() {
|
||||
this.makesProducts = true;
|
||||
break;
|
||||
case Industries.Healthcare:
|
||||
//reFac is unique for this bc it diminishes greatly per city. Handle this separately in code?
|
||||
this.reFac = 0.1;
|
||||
this.sciFac = 0.75;
|
||||
this.advFac = 0.1;
|
||||
this.advFac = 0.11;
|
||||
this.hwFac = 0.1;
|
||||
this.robFac = 0.1;
|
||||
this.aiFac = 0.1;
|
||||
@ -904,8 +915,8 @@ Industry.prototype.updateWarehouseSizeUsed = function(warehouse) {
|
||||
if (this.products.hasOwnProperty(prodName)) {
|
||||
var prod = this.products[prodName];
|
||||
warehouse.sizeUsed += (prod.data[warehouse.loc][0] * prod.siz);
|
||||
if (prod.data[warehouse.loc][0] > 0 && warehouse.loc === currentCityUi) {
|
||||
industryWarehouseStorageBreakdownText += (prodName + ": " + formatNumber(prod.data[warehouse.loc][0] * prod.siz, 0) + "<br>");
|
||||
if (prod.data[warehouse.loc][0] > 0) {
|
||||
warehouse.breakdown += (prodName + ": " + formatNumber(prod.data[warehouse.loc][0] * prod.siz, 0) + "<br>");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1029,6 +1040,24 @@ Industry.prototype.processProductMarket = function(marketCycles=1) {
|
||||
Industry.prototype.processMaterials = function(marketCycles=1, company) {
|
||||
var revenue = 0, expenses = 0, industry = this;
|
||||
this.calculateProductionFactors();
|
||||
|
||||
//At the start of the export state, set the imports of everything to 0
|
||||
if (this.state === "EXPORT") {
|
||||
for (var i = 0; i < Cities.length; ++i) {
|
||||
var city = Cities[i], office = this.offices[city];
|
||||
if (!(this.warehouses[city] instanceof Warehouse)) {
|
||||
continue;
|
||||
}
|
||||
var warehouse = this.warehouses[city];
|
||||
for (var matName in warehouse.materials) {
|
||||
if (warehouse.materials.hasOwnProperty(matName)) {
|
||||
var mat = warehouse.materials[matName];
|
||||
mat.imp = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < Cities.length; ++i) {
|
||||
var city = Cities[i], office = this.offices[city];
|
||||
|
||||
@ -1103,6 +1132,8 @@ Industry.prototype.processMaterials = function(marketCycles=1, company) {
|
||||
prod = Math.min(maxAmt, prod);
|
||||
}
|
||||
|
||||
if (prod < 0) {prod = 0;}
|
||||
|
||||
//Keep track of production for smart supply (/s)
|
||||
warehouse.smartSupplyStore += (prod / (SecsPerMarketCycle * marketCycles));
|
||||
|
||||
@ -1202,16 +1233,32 @@ Industry.prototype.processMaterials = function(marketCycles=1, company) {
|
||||
company.getSalesMultiplier() * advertisingFactor;
|
||||
|
||||
var sellAmt;
|
||||
if (mat.sllman[1] !== -1) {
|
||||
//Sell amount is manually limited
|
||||
sellAmt = Math.min(maxSell, mat.sllman[1]);
|
||||
} else {
|
||||
if (isString(mat.sllman[1])) {
|
||||
//Dynamically evaluated
|
||||
var tmp = mat.sllman[1].replace(/MAX/g, maxSell);
|
||||
tmp = tmp.replace(/PROD/g, mat.prd);
|
||||
try {
|
||||
sellAmt = eval(tmp);
|
||||
} catch(e) {
|
||||
dialogBoxCreate("Error evaluating your sell amount for material " + mat.name +
|
||||
" in " + this.name + "'s " + city + " office. The sell amount " +
|
||||
"is being set to zero");
|
||||
sellAmt = 0;
|
||||
}
|
||||
sellAmt = Math.min(maxSell, sellAmt);
|
||||
} else if (mat.sllman[1] === -1) {
|
||||
//Backwards compatibility, -1 = MAX
|
||||
sellAmt = maxSell;
|
||||
} else {
|
||||
//Player's input value is just a number
|
||||
sellAmt = Math.min(maxSell, mat.sllman[1]);
|
||||
}
|
||||
|
||||
sellAmt = (sellAmt * SecsPerMarketCycle * marketCycles);
|
||||
sellAmt = Math.min(mat.qty, sellAmt);
|
||||
if (sellAmt < 0) {
|
||||
console.log("ERROR: sellAmt is negative");
|
||||
console.log("sellAmt calculated to be negative");
|
||||
mat.sll = 0;
|
||||
continue;
|
||||
}
|
||||
if (sellAmt && sCost >= 0) {
|
||||
@ -1229,10 +1276,26 @@ Industry.prototype.processMaterials = function(marketCycles=1, company) {
|
||||
for (var matName in warehouse.materials) {
|
||||
if (warehouse.materials.hasOwnProperty(matName)) {
|
||||
var mat = warehouse.materials[matName];
|
||||
mat.totalExp = 0; //Reset export
|
||||
for (var expI = 0; expI < mat.exp.length; ++expI) {
|
||||
var exp = mat.exp[expI];
|
||||
var amt = exp.amt * SecsPerMarketCycle * marketCycles;
|
||||
if (mat.qty <= amt) {
|
||||
var amt = exp.amt.replace(/MAX/g, mat.qty / (SecsPerMarketCycle * marketCycles));
|
||||
try {
|
||||
amt = eval(amt);
|
||||
} catch(e) {
|
||||
dialogBoxCreate("Calculating export for " + mat.name + " in " +
|
||||
this.name + "'s " + city + " division failed with " +
|
||||
"error: " + e);
|
||||
continue;
|
||||
}
|
||||
if (isNaN(amt)) {
|
||||
dialogBoxCreate("Error calculating export amount for " + mat.name + " in " +
|
||||
this.name + "'s " + city + " division.");
|
||||
continue;
|
||||
}
|
||||
amt = amt * SecsPerMarketCycle * marketCycles;
|
||||
|
||||
if (mat.qty < amt) {
|
||||
amt = mat.qty;
|
||||
}
|
||||
if (amt === 0) {
|
||||
@ -1246,12 +1309,26 @@ Industry.prototype.processMaterials = function(marketCycles=1, company) {
|
||||
console.log("ERROR: Invalid export! " + expIndustry.name + " " + exp.city);
|
||||
break;
|
||||
}
|
||||
|
||||
//Make sure theres enough space in warehouse
|
||||
if (expWarehouse.sizeUsed >= expWarehouse.size) {
|
||||
return; //Warehouse at capacity
|
||||
} else {
|
||||
var maxAmt = Math.floor((expWarehouse.size - expWarehouse.sizeUsed) / MaterialSizes[matName]);
|
||||
amt = Math.min(maxAmt, amt);
|
||||
}
|
||||
expWarehouse.materials[matName].imp += (amt / (SecsPerMarketCycle * marketCycles));
|
||||
expWarehouse.materials[matName].qty += amt;
|
||||
expWarehouse.materials[matName].qlt = mat.qlt;
|
||||
mat.qty -= amt;
|
||||
mat.totalExp += amt;
|
||||
expIndustry.updateWarehouseSizeUsed(expWarehouse);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
//totalExp should be per second
|
||||
mat.totalExp /= (SecsPerMarketCycle * marketCycles);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1270,7 +1347,7 @@ Industry.prototype.processMaterials = function(marketCycles=1, company) {
|
||||
//Produce Scientific Research based on R&D employees
|
||||
//Scientific Research can be produced without a warehouse
|
||||
if (office instanceof OfficeSpace) {
|
||||
this.sciResearch.qty += (.01 * Math.pow(office.employeeProd[EmployeePositions.RandD], 0.5)
|
||||
this.sciResearch.qty += (.005 * Math.pow(office.employeeProd[EmployeePositions.RandD], 0.5)
|
||||
* company.getScientificResearchMultiplier());
|
||||
}
|
||||
}
|
||||
@ -1397,32 +1474,53 @@ Industry.prototype.processProduct = function(marketCycles=1, product, corporatio
|
||||
}
|
||||
|
||||
//Since its a product, its production cost is increased for labor
|
||||
product.pCost *= 3;
|
||||
product.pCost *= ProductProductionCostRatio;
|
||||
|
||||
//Calculate Sale Cost (sCost), which could be dynamically evaluated
|
||||
var sCost;
|
||||
if (isString(product.sCost)) {
|
||||
sCost = product.sCost.replace(/MP/g, product.pCost + product.rat / product.mku);
|
||||
sCost = eval(sCost);
|
||||
} else {
|
||||
sCost = product.sCost;
|
||||
}
|
||||
|
||||
var markup = 1, markupLimit = product.rat / product.mku;
|
||||
if (product.sCost > product.pCost) {
|
||||
if ((product.sCost - product.pCost) > markupLimit) {
|
||||
markup = markupLimit / (product.sCost - product.pCost);
|
||||
if (sCost > product.pCost) {
|
||||
if ((sCost - product.pCost) > markupLimit) {
|
||||
markup = markupLimit / (sCost - product.pCost);
|
||||
}
|
||||
}
|
||||
//var businessFactor = 1 + (office.employeeProd[EmployeePositions.Business] / office.employeeProd["total"]);
|
||||
var businessFactor = this.getBusinessFactor(office); //Business employee productivity
|
||||
var advertisingFactor = this.getAdvertisingFactors()[0]; //Awareness + popularity
|
||||
var marketFactor = this.getMarketFactor(product); //Competition + demand
|
||||
var maxSell = 0.5 * Math.pow(product.rat, 0.65) * marketFactor * corporation.getSalesMultiplier() *
|
||||
Math.pow(markup, 2) * businessFactor * advertisingFactor;
|
||||
var sellAmt;
|
||||
if (product.sllman[city][0] && product.sllman[city][1] > 0) {
|
||||
if (product.sllman[city][0] && isString(product.sllman[city][1])) {
|
||||
//Sell amount is dynamically evaluated
|
||||
var tmp = product.sllman[city][1].replace(/MAX/g, maxSell);
|
||||
tmp = tmp.replace(/PROD/g, product.data[city][1]);
|
||||
try {
|
||||
tmp = eval(tmp);
|
||||
} catch(e) {
|
||||
dialogBoxCreate("Error evaluating your sell price expression for " + product.name +
|
||||
" in " + this.name + "'s " + city + " office. Sell price is being set to MAX");
|
||||
tmp = maxSell;
|
||||
}
|
||||
sellAmt = Math.min(maxSell, tmp);
|
||||
} else if (product.sllman[city][0] && product.sllman[city][1] > 0) {
|
||||
//Sell amount is manually limited
|
||||
sellAmt = Math.min(maxSell, product.sllman[city][1]);
|
||||
} else {
|
||||
//Backwards compatibility, -1 = 0
|
||||
sellAmt = maxSell;
|
||||
}
|
||||
sellAmt = sellAmt * SecsPerMarketCycle * marketCycles;
|
||||
sellAmt = Math.min(product.data[city][0], sellAmt); //data[0] is qty
|
||||
if (sellAmt && product.sCost) {
|
||||
if (sellAmt && sCost) {
|
||||
product.data[city][0] -= sellAmt; //data[0] is qty
|
||||
totalProfit += (sellAmt * product.sCost);
|
||||
totalProfit += (sellAmt * sCost);
|
||||
product.data[city][2] = sellAmt / (SecsPerMarketCycle * marketCycles); //data[2] is sell property
|
||||
} else {
|
||||
product.data[city][2] = 0; //data[2] is sell property
|
||||
@ -1470,10 +1568,10 @@ Industry.prototype.upgrade = function(upgrade, refs) {
|
||||
break;
|
||||
case 1: //AdVert.Inc,
|
||||
var advMult = corporation.getAdvertisingMultiplier();
|
||||
this.awareness += (4 * advMult);
|
||||
this.awareness += (3 * advMult);
|
||||
this.popularity += (1 * advMult);
|
||||
this.awareness *= (1.01 * advMult);
|
||||
this.popularity *= ((1 + getRandomInt(2, 4) / 100) * advMult);
|
||||
this.popularity *= ((1 + getRandomInt(1, 3) / 100) * advMult);
|
||||
break;
|
||||
default:
|
||||
console.log("ERROR: Un-implemented function index: " + upgN);
|
||||
@ -1507,7 +1605,7 @@ Industry.prototype.getBusinessFactor = function(office) {
|
||||
if (office.employeeProd["total"] > 0) {
|
||||
ratioMult = 1 + (office.employeeProd[EmployeePositions.Business] / office.employeeProd["total"]);
|
||||
}
|
||||
return ratioMult * Math.pow(1 + office.employeeProd[EmployeePositions.Business], 0.1);
|
||||
return ratioMult * Math.pow(1 + office.employeeProd[EmployeePositions.Business], 0.15);
|
||||
}
|
||||
|
||||
//Returns a set of multipliers based on the Industry's awareness, popularity, and advFac. This
|
||||
@ -1987,6 +2085,7 @@ function Warehouse(params={}) {
|
||||
this.level = 0;
|
||||
this.sizeUsed = 0;
|
||||
this.smartSupplyEnabled = false; //Whether or not smart supply is enabled
|
||||
this.breakdown = "";
|
||||
|
||||
//Stores the amount of product to be produced. Used for Smart Supply unlock.
|
||||
//The production tracked by smart supply is always based on the previous cycle,
|
||||
@ -2010,14 +2109,14 @@ function Warehouse(params={}) {
|
||||
|
||||
Warehouse.prototype.updateMaterialSizeUsed = function() {
|
||||
this.sizeUsed = 0;
|
||||
if (this.loc === currentCityUi) {industryWarehouseStorageBreakdownText = ""; }
|
||||
this.breakdown = "";
|
||||
for (var matName in this.materials) {
|
||||
if (this.materials.hasOwnProperty(matName)) {
|
||||
var mat = this.materials[matName];
|
||||
if (MaterialSizes.hasOwnProperty(matName)) {
|
||||
this.sizeUsed += (mat.qty * MaterialSizes[matName]);
|
||||
if (mat.qty > 0 && this.loc === currentCityUi) {
|
||||
industryWarehouseStorageBreakdownText += (matName + ": " + formatNumber(mat.qty * MaterialSizes[matName], 0) + "<br>");
|
||||
if (mat.qty > 0) {
|
||||
this.breakdown += (matName + ": " + formatNumber(mat.qty * MaterialSizes[matName], 0) + "<br>");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2050,7 +2149,7 @@ Warehouse.prototype.createUI = function(parentRefs) {
|
||||
industryWarehousePanel.appendChild(industryWarehouseStorageText);
|
||||
|
||||
//Upgrade warehouse size button
|
||||
var upgradeCost = WarehouseUpgradeBaseCost * Math.pow(1.07, Math.round(this.size / 100) - 1);
|
||||
var upgradeCost = WarehouseUpgradeBaseCost * Math.pow(1.07, this.level+1);
|
||||
industryWarehouseUpgradeSizeButton = createElement("a", {
|
||||
innerText:"Upgrade Warehouse Size - " + numeral(upgradeCost).format('$0.000a'),
|
||||
display:"inline-block",
|
||||
@ -2157,15 +2256,14 @@ Warehouse.prototype.updateUI = function(parentRefs) {
|
||||
var storageText = "Storage: " +
|
||||
(this.sizedUsed >= this.size ? formatNumber(this.sizeUsed, 3) : formatNumber(this.sizeUsed, 3)) +
|
||||
"/" + formatNumber(this.size, 3);
|
||||
if (industryWarehouseStorageBreakdownText != null &&
|
||||
industryWarehouseStorageBreakdownText != "") {
|
||||
if (this.breakdown != null && this.breakdown != "") {
|
||||
storageText += ("<span class='tooltiptext'>" +
|
||||
industryWarehouseStorageBreakdownText + "</span>");
|
||||
this.breakdown + "</span>");
|
||||
}
|
||||
industryWarehouseStorageText.innerHTML = storageText;
|
||||
|
||||
//Upgrade warehouse size button
|
||||
var upgradeCost = WarehouseUpgradeBaseCost * Math.pow(1.07, Math.round(this.size / 100) - 1);
|
||||
var upgradeCost = WarehouseUpgradeBaseCost * Math.pow(1.07, this.level+1);
|
||||
if (company.funds.lt(upgradeCost)) {
|
||||
industryWarehouseUpgradeSizeButton.className = "a-link-button-inactive";
|
||||
} else {
|
||||
@ -2209,8 +2307,8 @@ Warehouse.prototype.updateUI = function(parentRefs) {
|
||||
}
|
||||
|
||||
//Products
|
||||
removeChildrenFromElement(industryWarehouseProducts);
|
||||
if (industry.makesProducts && Object.keys(industry.products).length > 0) {
|
||||
removeChildrenFromElement(industryWarehouseProducts);
|
||||
for (var productName in industry.products) {
|
||||
if (industry.products.hasOwnProperty(productName) && industry.products[productName] instanceof Product) {
|
||||
industryWarehouseProducts.appendChild(this.createProductUI(industry.products[productName], parentRefs));
|
||||
@ -2231,11 +2329,7 @@ Warehouse.prototype.createMaterialUI = function(mat, matName, parentRefs) {
|
||||
class:"cmpy-mgmt-warehouse-material-div",
|
||||
});
|
||||
|
||||
var totalExport = 0;
|
||||
for (var i = 0; i < mat.exp.length; ++i) {
|
||||
totalExport += mat.exp[i].amt;
|
||||
}
|
||||
var totalGain = mat.buy + mat.prd + mat.imp - mat.sll - totalExport;
|
||||
var totalGain = mat.buy + mat.prd + mat.imp - mat.sll - mat.totalExp;
|
||||
|
||||
//If Market Research upgrades are unlocked, add competition and demand info
|
||||
var cmpAndDmdText = "";
|
||||
@ -2249,7 +2343,7 @@ Warehouse.prototype.createMaterialUI = function(mat, matName, parentRefs) {
|
||||
"(" + formatNumber(totalGain, 3) + "/s)" +
|
||||
"<span class='tooltiptext'>Buy: " + formatNumber(mat.buy, 3) +
|
||||
"/s<br>Prod: " + formatNumber(mat.prd, 3) + "/s<br>Sell: " + formatNumber(mat.sll, 3) +
|
||||
"/s<br>Export: " + formatNumber(totalExport, 3) + "/s<br>Import: " +
|
||||
"/s<br>Export: " + formatNumber(mat.totalExp, 3) + "/s<br>Import: " +
|
||||
formatNumber(mat.imp, 3) + "/s" + cmpAndDmdText + "</span></p><br>" +
|
||||
"<p class='tooltip'>MP: $" + formatNumber(mat.bCost, 2) +
|
||||
"<span class='tooltiptext'>Market Price: The price you would pay if " +
|
||||
@ -2380,7 +2474,7 @@ Warehouse.prototype.createMaterialUI = function(mat, matName, parentRefs) {
|
||||
|
||||
//Select amount to export
|
||||
var exportAmount = createElement("input", {
|
||||
type:"number", placeholder:"Export amount / s"
|
||||
placeholder:"Export amount / s"
|
||||
});
|
||||
|
||||
var exportBtn = createElement("a", {
|
||||
@ -2388,28 +2482,24 @@ Warehouse.prototype.createMaterialUI = function(mat, matName, parentRefs) {
|
||||
clickListener:()=>{
|
||||
var industryName = industrySelector.options[industrySelector.selectedIndex].text,
|
||||
cityName = citySelector.options[citySelector.selectedIndex].text,
|
||||
amt = parseFloat(exportAmount.value);
|
||||
if (isNaN(amt)) {
|
||||
amt = exportAmount.value;
|
||||
//Sanitize amt
|
||||
var sanitizedAmt = amt.replace(/\s+/g, '');
|
||||
sanitizedAmt = sanitizedAmt.replace(/[^-()\d/*+.MAX]/g, '');
|
||||
var temp = sanitizedAmt.replace(/MAX/g, 1);
|
||||
try {
|
||||
temp = eval(temp);
|
||||
} catch(e) {
|
||||
dialogBoxCreate("Invalid expression entered for export amount: " + e);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (temp == null || isNaN(temp)) {
|
||||
dialogBoxCreate("Invalid amount entered for export");
|
||||
return;
|
||||
}
|
||||
var exportObj = {ind:industryName, city:cityName, amt:amt};
|
||||
var exportObj = {ind:industryName, city:cityName, amt:sanitizedAmt};
|
||||
mat.exp.push(exportObj);
|
||||
|
||||
//Go to the target city and increase the mat.imp attribute for the corresponding material
|
||||
for (var i = 0; i < company.divisions.length; ++i) {
|
||||
if (company.divisions[i].name === industryName) {
|
||||
var warehouse = company.divisions[i].warehouses[cityName];
|
||||
if (warehouse instanceof Warehouse) {
|
||||
warehouse.materials[matName].imp += amt;
|
||||
removeElementById(popupId);
|
||||
return false;
|
||||
} else {
|
||||
console.log("ERROR: Target city for export does not have warehouse in specified city");
|
||||
}
|
||||
}
|
||||
}
|
||||
console.log("ERROR: Could not find target industry/city for export");
|
||||
removeElementById(popupId);
|
||||
return false;
|
||||
}
|
||||
@ -2436,17 +2526,6 @@ Warehouse.prototype.createMaterialUI = function(mat, matName, parentRefs) {
|
||||
"City: " + mat.exp[i].city + "<br>" +
|
||||
"Amount/s: " + mat.exp[i].amt,
|
||||
clickListener:()=>{
|
||||
//Go to the target city and decrease the mat.imp attribute for the corresponding material
|
||||
for (var j = 0; j < company.divisions.length; ++j) {
|
||||
if (company.divisions[j].name === mat.exp[i].ind) {
|
||||
var warehouse = company.divisions[j].warehouses[mat.exp[i].city];
|
||||
if (warehouse instanceof Warehouse) {
|
||||
warehouse.materials[matName].imp -= mat.exp[i].amt;
|
||||
} else {
|
||||
console.log("ERROR: Target city for export does not have warehouse in specified city");
|
||||
}
|
||||
}
|
||||
}
|
||||
mat.exp.splice(i, 1); //Remove export object
|
||||
removeElementById(popupId);
|
||||
createExportPopup();
|
||||
@ -2493,6 +2572,9 @@ Warehouse.prototype.createMaterialUI = function(mat, matName, parentRefs) {
|
||||
"if set to 0, then the material will be discarded<br><br>" +
|
||||
"Setting the sell amount to 'MAX' will result in you always selling the " +
|
||||
"maximum possible amount of the material.<br><br>" +
|
||||
"When setting the sell amount, you can use the 'PROD' variable to designate a dynamically " +
|
||||
"changing amount that depends on your production. For example, if you set the sell amount " +
|
||||
"to 'PROD-5' then you will always sell 5 less of the material than you produce.<br><br>" +
|
||||
"When setting the sell price, you can use the 'MP' variable to designate a dynamically " +
|
||||
"changing price that depends on the market price. For example, if you set the sell price " +
|
||||
"to 'MP+10' then it will always be sold at $10 above the market price.",
|
||||
@ -2519,11 +2601,16 @@ Warehouse.prototype.createMaterialUI = function(mat, matName, parentRefs) {
|
||||
innerText:"Confirm", class:"a-link-button", margin:"6px",
|
||||
clickListener:()=>{
|
||||
//Parse price
|
||||
//Sanitize cost
|
||||
var cost = inputPx.value.replace(/\s+/g, '');
|
||||
cost = cost.replace(/[^-()\d/*+.MP]/g, '');
|
||||
cost = cost.replace(/[^-()\d/*+.MP]/g, ''); //Sanitize cost
|
||||
var temp = cost.replace(/MP/g, mat.bCost);
|
||||
var temp = eval(temp);
|
||||
try {
|
||||
temp = eval(temp);
|
||||
} catch(e) {
|
||||
dialogBoxCreate("Invalid value or expression for sell price field: " + e);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (temp == null || isNaN(temp)) {
|
||||
dialogBoxCreate("Invalid value or expression for sell price field");
|
||||
return false;
|
||||
@ -2536,9 +2623,25 @@ Warehouse.prototype.createMaterialUI = function(mat, matName, parentRefs) {
|
||||
}
|
||||
|
||||
//Parse quantity
|
||||
if (inputQty.value === "MAX") {
|
||||
if (inputQty.value.includes("MAX") || inputQty.value.includes("PROD")) {
|
||||
var qty = inputQty.value.replace(/\s+/g, '');
|
||||
qty = qty.replace(/[^-()\d/*+.MAXPROD]/g, '');
|
||||
var temp = qty.replace(/MAX/g, 1);
|
||||
temp = temp.replace(/PROD/g, 1);
|
||||
try {
|
||||
temp = eval(temp);
|
||||
} catch(e) {
|
||||
dialogBoxCreate("Invalid value or expression for sell price field: " + e);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (temp == null || isNaN(temp)) {
|
||||
dialogBoxCreate("Invalid value or expression for sell price field");
|
||||
return false;
|
||||
}
|
||||
|
||||
mat.sllman[0] = true;
|
||||
mat.sllman[1] = -1;
|
||||
mat.sllman[1] = qty; //Use sanitized input
|
||||
} else if (isNaN(inputQty.value)) {
|
||||
dialogBoxCreate("Invalid value for sell quantity field! Must be numeric or 'MAX'");
|
||||
return false;
|
||||
@ -2611,10 +2714,8 @@ Warehouse.prototype.createProductUI = function(product, parentRefs) {
|
||||
"Aesthetics: " + formatNumber(product.aes, 3) + "<br>" +
|
||||
"Features: " + formatNumber(product.fea, 3) +
|
||||
cmpAndDmdText + "</span></p><br>" +
|
||||
"<p class='tooltip'>Est. Production Cost: " + numeral(product.pCost).format("$0.000a") +
|
||||
"<span class='tooltiptext'>An estimate of how much it costs to produce one unit of this product. " +
|
||||
"If your sell price exceeds this by too much, people won't buy your product. The better your " +
|
||||
"product is, the higher you can mark up its price.</span></p><br>" +
|
||||
"<p class='tooltip'>Est. Production Cost: " + numeral(product.pCost / ProductProductionCostRatio).format("$0.000a") +
|
||||
"<span class='tooltiptext'>An estimate of the material cost it takes to create this Product.</span></p><br>" +
|
||||
"<p class='tooltip'>Est. Market Price: " + numeral(product.pCost + product.rat / product.mku).format("$0.000a") +
|
||||
"<span class='tooltiptext'>An estimate of how much consumers are willing to pay for this product. " +
|
||||
"Setting the sale price above this may result in less sales. Setting the sale price below this may result " +
|
||||
@ -2629,7 +2730,11 @@ Warehouse.prototype.createProductUI = function(product, parentRefs) {
|
||||
var sellInnerTextString = (product.sllman[city][1] === -1 ? "Sell (" + formatNumber(product.data[city][2], 3) + "/MAX)" :
|
||||
"Sell (" + formatNumber(product.data[city][2], 3) + "/" + formatNumber(product.sllman[city][1], 3) + ")");
|
||||
if (product.sCost) {
|
||||
sellInnerTextString += (" @ " + numeral(product.sCost).format("$0.000a"));
|
||||
if (isString(product.sCost)) {
|
||||
sellInnerTextString += (" @ " + product.sCost);
|
||||
} else {
|
||||
sellInnerTextString += (" @ " + numeral(product.sCost).format("$0.000a"));
|
||||
}
|
||||
}
|
||||
div.appendChild(createElement("a", {
|
||||
innerText:sellInnerTextString, class:"a-link-button", display:"inline-block",margin:"6px",
|
||||
@ -2642,7 +2747,15 @@ Warehouse.prototype.createProductUI = function(product, parentRefs) {
|
||||
"If the sell amount is set to 0, then the product will not be sold. If the " +
|
||||
"sell price is set to 0, then the product will be discarded.<br><br>" +
|
||||
"Setting the sell amount to 'MAX' will result in you always selling the " +
|
||||
"maximum possible amount of the material.<br><br>",
|
||||
"maximum possible amount of the material.<br><br>" +
|
||||
"When setting the sell amount, you can use the 'PROD' variable to designate a " +
|
||||
"dynamically changing amount that depends on your production. For example, " +
|
||||
"if you set the sell amount to 'PROD-1' then you will always sell 1 less of " +
|
||||
"the material than you produce.<br><br>" +
|
||||
"When setting the sell price, you can use the 'MP' variable to set a " +
|
||||
"dynamically changing price that depends on the Product's estimated " +
|
||||
"market price. For example, if you set it to 'MP*5' then it " +
|
||||
"will always be sold at five times the estimated market price.",
|
||||
});
|
||||
var confirmBtn;
|
||||
var inputQty = createElement("input", {
|
||||
@ -2663,17 +2776,52 @@ Warehouse.prototype.createProductUI = function(product, parentRefs) {
|
||||
class:"a-link-button", innerText:"Confirm",
|
||||
clickListener:()=>{
|
||||
//Parse price
|
||||
var cost = parseFloat(inputPx.value);
|
||||
if (isNaN(cost)) {
|
||||
dialogBoxCreate("Invalid value for sell price field");
|
||||
return false;
|
||||
if (inputPx.value.includes("MP")) {
|
||||
//Dynamically evaluated quantity. First test to make sure its valid
|
||||
//Sanitize input, then replace dynamic variables with arbitrary numbers
|
||||
var price = inputPx.value.replace(/\s+/g, '');
|
||||
price = price.replace(/[^-()\d/*+.MP]/g, '');
|
||||
var temp = price.replace(/MP/g, 1);
|
||||
try {
|
||||
temp = eval(temp);
|
||||
} catch(e) {
|
||||
dialogBoxCreate("Invalid value or expression for sell quantity field: " + e);
|
||||
return false;
|
||||
}
|
||||
if (temp == null || isNaN(temp)) {
|
||||
dialogBoxCreate("Invalid value or expression for sell quantity field.");
|
||||
return false;
|
||||
}
|
||||
product.sCost = price; //Use sanitized price
|
||||
} else {
|
||||
var cost = parseFloat(inputPx.value);
|
||||
if (isNaN(cost)) {
|
||||
dialogBoxCreate("Invalid value for sell price field");
|
||||
return false;
|
||||
}
|
||||
product.sCost = cost;
|
||||
}
|
||||
product.sCost = cost;
|
||||
|
||||
//Parse quantity
|
||||
if (inputQty.value === "MAX") {
|
||||
if (inputQty.value.includes("MAX") || inputQty.value.includes("PROD")) {
|
||||
//Dynamically evaluated quantity. First test to make sure its valid
|
||||
var qty = inputQty.value.replace(/\s+/g, '');
|
||||
qty = qty.replace(/[^-()\d/*+.MAXPROD]/g, '');
|
||||
var temp = qty.replace(/MAX/g, 1);
|
||||
temp = temp.replace(/PROD/g, 1);
|
||||
try {
|
||||
temp = eval(temp);
|
||||
} catch(e) {
|
||||
dialogBoxCreate("Invalid value or expression for sell price field: " + e);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (temp == null || isNaN(temp)) {
|
||||
dialogBoxCreate("Invalid value or expression for sell price field");
|
||||
return false;
|
||||
}
|
||||
product.sllman[city][0] = true;
|
||||
product.sllman[city][1] = -1;
|
||||
product.sllman[city][1] = qty; //Use sanitized input
|
||||
} else if (isNaN(inputQty.value)) {
|
||||
dialogBoxCreate("Invalid value for sell quantity field! Must be numeric");
|
||||
return false;
|
||||
@ -2970,13 +3118,13 @@ Corporation.prototype.process = function() {
|
||||
Corporation.prototype.determineValuation = function() {
|
||||
var val, profit = (this.revenue.minus(this.expenses)).toNumber();
|
||||
if (this.public) {
|
||||
val = this.funds.toNumber() + (profit * 90e3);
|
||||
val = this.funds.toNumber() + (profit * 85e3);
|
||||
val *= (Math.pow(1.1, this.divisions.length));
|
||||
val = Math.max(val, 0);
|
||||
} else {
|
||||
val = 10e9 + Math.max(this.funds.toNumber(), 0) / 3; //Base valuation
|
||||
if (profit > 0) {
|
||||
val += (profit * 350e3);
|
||||
val += (profit * 320e3);
|
||||
val *= (Math.pow(1.1, this.divisions.length));
|
||||
} else {
|
||||
val = 10e9 * Math.pow(1.1, this.divisions.length);
|
||||
@ -3206,7 +3354,6 @@ var companyManagementDiv, companyManagementHeaderTabs, companyManagementPanel,
|
||||
|
||||
//Industry Warehouse Panel
|
||||
industryWarehousePanel, industrySmartSupplyCheckbox, industryWarehouseStorageText,
|
||||
industryWarehouseStorageBreakdownText,
|
||||
industryWarehouseUpgradeSizeButton, industryWarehouseStateText,
|
||||
industryWarehouseMaterials, industryWarehouseProducts,
|
||||
headerTabs, cityTabs;
|
||||
@ -3667,7 +3814,7 @@ Corporation.prototype.displayCorporationOverviewContent = function() {
|
||||
stockSharesInput = createElement("input", {
|
||||
type:"number", placeholder:"Stock Shares", margin: "5px",
|
||||
inputListener:()=>{
|
||||
var money = moneyInput.value == null || moneyInput.value == "" ? 0 : moneyInput.value;
|
||||
var money = moneyInput.value == null || moneyInput.value == "" ? 0 : parseFloat(moneyInput.value);
|
||||
var stockPrice = this.sharePrice;
|
||||
var stockShares = stockSharesInput.value == null || stockSharesInput.value == "" ? 0 : Math.round(stockSharesInput.value);
|
||||
if (isNaN(money) || isNaN(stockShares) || money < 0 || stockShares < 0) {
|
||||
@ -3702,7 +3849,7 @@ Corporation.prototype.displayCorporationOverviewContent = function() {
|
||||
dialogBoxCreate("ERROR: Invalid value(s) entered");
|
||||
} else if (this.funds.lt(money)) {
|
||||
dialogBoxCreate("ERROR: You do not have this much money to bribe with");
|
||||
} else if (this.stockShares > this.numShares) {
|
||||
} else if (stockShares > this.numShares) {
|
||||
dialogBoxCreate("ERROR: You do not have this many shares to bribe with");
|
||||
} else {
|
||||
var totalAmount = money + (stockShares * stockPrice);
|
||||
|
@ -1,5 +1,5 @@
|
||||
let CONSTANTS = {
|
||||
Version: "0.35.1",
|
||||
Version: "0.35.2",
|
||||
|
||||
//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
|
||||
@ -1138,28 +1138,25 @@ let CONSTANTS = {
|
||||
"World Stock Exchange account and TIX API Access<br>",
|
||||
|
||||
LatestUpdate:
|
||||
"v0.35.1<br>" +
|
||||
"* You can now easily download all of your scripts/text files as zip folders. Use the 'help download' Terminal command for details<br>" +
|
||||
"* Scripts are now downloaded with the .script.js extension at the end of their filename<br>" +
|
||||
"* Corporation Management Changes:<br>" +
|
||||
"*** Implemented Smart Supply unlock<br>" +
|
||||
"*** Changed the way a division's Production Multiplier is calculated. It is now the sum of the individual Production Multiplier " +
|
||||
"for every city. Therefore, it is now beneficial to open offices in different cities<br." +
|
||||
"*** The breakdown of what is taking up Warehouse space is now listed as a tooltip<br>" +
|
||||
"*** Several small UI/UX improvements<br>" +
|
||||
"*** Numerous balance changes. The significant ones are listed below.<br>" +
|
||||
"*** Product descriptions will now display their estimated market price<br>" +
|
||||
"*** The sale price of Products can no longer be marked up as high as before<br>" +
|
||||
"*** Scientific Research now affects the rating of Products<br>" +
|
||||
"*** In general, the maximum amount of product you are able to sell is reduced<br>" +
|
||||
"*** Sale bonus from advertising (popularity/awareness) now has diminishing returns rather than scaling linearly<br>" +
|
||||
"* Experience gained during Infiltration now scales linearly based on the clearance level you reach. Compared to before, " +
|
||||
"the experience gained will be much less at lower clearance levels, but much more at higher clearance levels<br>" +
|
||||
"* The editor can now be used to edit both scripts and text files<br>" +
|
||||
"* New Terminal config file that can be edited using the command 'nano .fconf'. Right now there is only one option, but there " +
|
||||
"will be more in the future.<br>" +
|
||||
"* You can now enable Bash-style Terminal hotkeys using the .fconf file referenced above<br>" +
|
||||
"* Bug Fix: Fixed an issue with the UI elements of Gang Management persisting across different instances of BitNode-2"
|
||||
"v0.35.2<br>" +
|
||||
"* Corporation Changes: <br>" +
|
||||
"*** Fixed an issue with Warehouse upgrade cost. Should now be significantly cheaper than before.<br>" +
|
||||
"*** Scientific Research now has a slightly more significant effect on Product quality<br>" +
|
||||
"*** The Energy and Water Utilities industries are now slightly more profitable<br>" +
|
||||
"*** The Robotics and Computer Hardware industries are now less profitable<br>" +
|
||||
"*** The Software industry is slightly less profitable<br>" +
|
||||
"*** When selling Materials and Products, the 'PROD' qualifier can now be used " +
|
||||
"to set dynamic sell amounts based on your production<br>" +
|
||||
"*** Exporting MAX should now work properly<br>" +
|
||||
"*** You can no longer export past storage limits<br>" +
|
||||
"*** Scientific Research production reduced<br>" +
|
||||
"*** Effects of AdVert. Inc upgrade were reduced, but the effect that popularity and " +
|
||||
"awareness have on sales was increased to compensate (popularity/awareness numbers were getting " +
|
||||
"too big with Advert. Inc)<br>" +
|
||||
"*** Bug Fix: Products from Computer Hardware division should now properly have ratings<br>" +
|
||||
"* Improved Augmentation UI/UX. Now contains collapsible headers and sort buttons<br>" +
|
||||
"* Improved Faction Augmentations display UI/UX. Now contains sort buttons. There is also an option " +
|
||||
"to disable confirmation when purchasing Augmentations<br>"
|
||||
}
|
||||
|
||||
export {CONSTANTS};
|
||||
|
583
src/Faction.js
583
src/Faction.js
@ -11,33 +11,15 @@ import {Settings} from "./Settings.js";
|
||||
|
||||
import {dialogBoxCreate} from "../utils/DialogBox.js";
|
||||
import {factionInvitationBoxCreate} from "../utils/FactionInvitationBox.js";
|
||||
import {clearEventListeners} from "../utils/HelperFunctions.js";
|
||||
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 {formatNumber, isPositiveNumber} from "../utils/StringHelperFunctions.js";
|
||||
import {formatNumber} from "../utils/StringHelperFunctions.js";
|
||||
import {yesNoBoxCreate, yesNoBoxGetYesButton,
|
||||
yesNoBoxGetNoButton, yesNoBoxClose} from "../utils/YesNoBox.js";
|
||||
|
||||
|
||||
//Netburner Faction class
|
||||
function factionInit() {
|
||||
$('#faction-donate-input').on('input', function() {
|
||||
if (Engine.currentPage == Engine.Page.Faction) {
|
||||
var val = document.getElementById("faction-donate-input").value;
|
||||
if (isPositiveNumber(val)) {
|
||||
var numMoneyDonate = Number(val);
|
||||
document.getElementById("faction-donate-rep-gain").innerHTML =
|
||||
"This donation will result in " + formatNumber(numMoneyDonate/1000000 * Player.faction_rep_mult, 3) + " reputation gain";
|
||||
} else {
|
||||
document.getElementById("faction-donate-rep-gain").innerHTML =
|
||||
"This donation will result in 0 reputation gain";
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
document.addEventListener("DOMContentLoaded", factionInit, false);
|
||||
|
||||
function Faction(name="") {
|
||||
this.name = name;
|
||||
this.augmentations = []; //Name of augmentation only
|
||||
@ -398,6 +380,7 @@ function inviteToFaction(faction) {
|
||||
if (Settings.SuppressFactionInvites) {
|
||||
faction.alreadyInvited = true;
|
||||
Player.factionInvitations.push(faction.name);
|
||||
Engine.loadFactionsContent();
|
||||
} else {
|
||||
factionInvitationBoxCreate(faction);
|
||||
}
|
||||
@ -442,92 +425,206 @@ function joinFaction(faction) {
|
||||
//Displays the HTML content for a specific faction
|
||||
function displayFactionContent(factionName) {
|
||||
var faction = Factions[factionName];
|
||||
document.getElementById("faction-name").innerHTML = factionName;
|
||||
document.getElementById("faction-info").innerHTML = "<i>" + faction.info + "</i>";
|
||||
var repGain = faction.getFavorGain();
|
||||
if (repGain.length != 2) {repGain = 0;}
|
||||
repGain = repGain[0];
|
||||
document.getElementById("faction-reputation").innerHTML = "Reputation: " + formatNumber(faction.playerReputation, 4) +
|
||||
"<span class='tooltiptext'>You will earn " +
|
||||
formatNumber(repGain, 4) +
|
||||
" faction favor upon resetting after installing an Augmentation</span>";
|
||||
document.getElementById("faction-favor").innerHTML = "Faction Favor: " + formatNumber(faction.favor, 4) +
|
||||
"<span class='tooltiptext'>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 " +
|
||||
"favor you gain depends on how much reputation you have with the faction</span>";
|
||||
if (faction == null) {
|
||||
throw new Error("Invalid factionName passed into displayFactionContent: " + factionName);
|
||||
}
|
||||
removeChildrenFromElement(Engine.Display.factionContent);
|
||||
var elements = [];
|
||||
|
||||
var hackMissionDiv = document.getElementById("faction-hack-mission-div");
|
||||
var hackDiv = document.getElementById("faction-hack-div");
|
||||
var fieldWorkDiv = document.getElementById("faction-fieldwork-div");
|
||||
var securityWorkDiv = document.getElementById("faction-securitywork-div");
|
||||
var donateDiv = document.getElementById("faction-donate-div");
|
||||
var gangDiv = document.getElementById("faction-gang-div");
|
||||
//Header and faction info
|
||||
elements.push(createElement("h1", {
|
||||
innerText:factionName
|
||||
}));
|
||||
elements.push(createElement("pre", {
|
||||
innerHTML:"<i>" + faction.info + "</i>"
|
||||
}));
|
||||
elements.push(createElement("p", {
|
||||
innerText:"---------------",
|
||||
}));
|
||||
|
||||
var newHackMissionButton = clearEventListeners("faction-hack-mission-button");
|
||||
var newHackButton = clearEventListeners("faction-hack-button");
|
||||
var newFieldWorkButton = clearEventListeners("faction-fieldwork-button");
|
||||
var newSecurityWorkButton = clearEventListeners("faction-securitywork-button");
|
||||
var newDonateWorkButton = clearEventListeners("faction-donate-button");
|
||||
newHackMissionButton.addEventListener("click", function() {
|
||||
Engine.loadMissionContent();
|
||||
var mission = new HackingMission(faction.playerReputation, faction);
|
||||
setInMission(true, mission); //Sets inMission flag to true
|
||||
mission.init();
|
||||
return false;
|
||||
//Faction reputation and favor
|
||||
var favorGain = faction.getFavorGain();
|
||||
if (favorGain.length != 2) {favorGain = 0;}
|
||||
favorGain = favorGain[0];
|
||||
elements.push(createElement("p", {
|
||||
innerText: "Reputation: " + formatNumber(faction.playerReputation, 4),
|
||||
tooltip:"You will earn " + formatNumber(favorGain, 4) +
|
||||
" faction favor upon resetting after installing an Augmentation"
|
||||
}))
|
||||
elements.push(createElement("p", {
|
||||
innerText:"---------------",
|
||||
}));
|
||||
elements.push(createElement("p", {
|
||||
innerText:"Faction Favor: " + formatNumber(faction.favor, 4),
|
||||
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 " +
|
||||
"favor you gain depends on how much reputation you have with the faction"
|
||||
}));
|
||||
elements.push(createElement("p", {
|
||||
innerText:"---------------",
|
||||
}));
|
||||
|
||||
//Faction Work Description Text
|
||||
elements.push(createElement("pre", {
|
||||
id:"faction-work-description-text",
|
||||
innerText:"Perform work/carry out assignments for your faction to help further its cause! By doing so " +
|
||||
"you will earn reputation for your faction. You will also gain reputation passively over time, " +
|
||||
"although at a very slow rate. Earning reputation will allow you to purchase Augmentations " +
|
||||
"through this faction, which are powerful upgrades that enhance your abilities. Note that you cannot " +
|
||||
"use your terminal or create scripts when you are performing a task!"
|
||||
}));
|
||||
elements.push(createElement("br"));
|
||||
|
||||
//Hacking Mission Option
|
||||
var hackMissionDiv = createElement("div", {
|
||||
id:"faction-hack-mission-div", class:"faction-work-div",
|
||||
});
|
||||
|
||||
newHackButton.addEventListener("click", function() {
|
||||
Player.startFactionHackWork(faction);
|
||||
return false;
|
||||
});
|
||||
|
||||
newFieldWorkButton.addEventListener("click", function() {
|
||||
Player.startFactionFieldWork(faction);
|
||||
return false;
|
||||
});
|
||||
|
||||
newSecurityWorkButton.addEventListener("click", function() {
|
||||
Player.startFactionSecurityWork(faction);
|
||||
return false;
|
||||
});
|
||||
|
||||
newDonateWorkButton.addEventListener("click", function() {
|
||||
var donateAmountVal = document.getElementById("faction-donate-input").value;
|
||||
if (isPositiveNumber(donateAmountVal)) {
|
||||
var numMoneyDonate = Number(donateAmountVal);
|
||||
if (Player.money.lt(numMoneyDonate)) {
|
||||
dialogBoxCreate("You cannot afford to donate this much money!");
|
||||
return;
|
||||
}
|
||||
Player.loseMoney(numMoneyDonate);
|
||||
var repGain = numMoneyDonate / 1000000 * Player.faction_rep_mult;
|
||||
faction.playerReputation += repGain;
|
||||
dialogBoxCreate("You just donated $" + formatNumber(numMoneyDonate, 2) + " to " +
|
||||
faction.name + " to gain " + formatNumber(repGain, 3) + " reputation");
|
||||
displayFactionContent(factionName);
|
||||
} else {
|
||||
dialogBoxCreate("Invalid amount entered!");
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
|
||||
var newPurchaseAugmentationsButton = clearEventListeners("faction-purchase-augmentations");
|
||||
newPurchaseAugmentationsButton.addEventListener("click", function() {
|
||||
Engine.hideAllContent();
|
||||
Engine.Display.factionAugmentationsContent.style.display = "block";
|
||||
|
||||
var newBackButton = clearEventListeners("faction-augmentations-back-button");
|
||||
newBackButton.addEventListener("click", function() {
|
||||
Engine.loadFactionContent();
|
||||
displayFactionContent(factionName);
|
||||
var hackMissionDivWrapper = createElement("div", {class:"faction-work-div-wrapper"});
|
||||
hackMissionDiv.appendChild(hackMissionDivWrapper);
|
||||
hackMissionDivWrapper.appendChild(createElement("a", {
|
||||
class:"a-link-button", innerText:"Hacking Mission",
|
||||
clickListener:()=>{
|
||||
Engine.loadMissionContent();
|
||||
var mission = new HackingMission(faction.playerReputation, faction);
|
||||
setInMission(true, mission); //Sets inMission flag to true
|
||||
mission.init();
|
||||
return false;
|
||||
});
|
||||
displayFactionAugmentations(factionName);
|
||||
return false;
|
||||
});
|
||||
}
|
||||
}));
|
||||
hackMissionDivWrapper.appendChild(createElement("p", {
|
||||
innerText:"Attempt a hacking mission for your faction. " +
|
||||
"A mission is a mini game that, if won, earns you " +
|
||||
"significant reputation with this faction. (Recommended hacking level: 200+)"
|
||||
}));
|
||||
elements.push(hackMissionDiv);
|
||||
|
||||
//Hacking Contracts Option
|
||||
var hackDiv = createElement("div", {
|
||||
id:"faction-hack-div", class:"faction-work-div",
|
||||
});
|
||||
var hackDivWrapper = createElement("div", {class:"faction-work-div-wrapper"});
|
||||
hackDiv.appendChild(hackDivWrapper);
|
||||
hackDivWrapper.appendChild(createElement("a", {
|
||||
class:"a-link-button", innerText:"Hacking Contracts",
|
||||
clickListener:()=>{
|
||||
Player.startFactionHackWork(faction);
|
||||
return false;
|
||||
}
|
||||
}));
|
||||
hackDivWrapper.appendChild(createElement("p", {
|
||||
innerText:"Complete hacking contracts for your faction. " +
|
||||
"Your effectiveness, which determines how much " +
|
||||
"reputation you gain for this faction, is based on your hacking skill. " +
|
||||
"You will gain hacking exp."
|
||||
}));
|
||||
elements.push(hackDiv);
|
||||
|
||||
//Field Work Option
|
||||
var fieldWorkDiv = createElement("div", {
|
||||
id:"faction-fieldwork-div", class:"faction-work-div"
|
||||
});
|
||||
var fieldWorkDivWrapper = createElement("div", {class:"faction-work-div-wrapper"});
|
||||
fieldWorkDiv.appendChild(fieldWorkDivWrapper);
|
||||
fieldWorkDivWrapper.appendChild(createElement("a", {
|
||||
class:"a-link-button", innerText:"Field Work",
|
||||
clickListener:()=>{
|
||||
Player.startFactionFieldWork(faction);
|
||||
return false;
|
||||
}
|
||||
}));
|
||||
fieldWorkDivWrapper.appendChild(createElement("p", {
|
||||
innerText:"Carry out field missions for your faction. " +
|
||||
"Your effectiveness, which determines how much " +
|
||||
"reputation you gain for this faction, is based on all of your stats. " +
|
||||
"You will gain exp for all stats."
|
||||
}));
|
||||
elements.push(fieldWorkDiv);
|
||||
|
||||
//Security Work Option
|
||||
var securityWorkDiv = createElement("div", {
|
||||
id:"faction-securitywork-div", class:"faction-work-div"
|
||||
});
|
||||
var securityWorkDivWrapper = createElement("div", {class:"faction-work-div-wrapper"});
|
||||
securityWorkDiv.appendChild(securityWorkDivWrapper);
|
||||
securityWorkDivWrapper.appendChild(createElement("a", {
|
||||
class:"a-link-button", innerText:"Security Work",
|
||||
clickListener:()=>{
|
||||
Player.startFactionSecurityWork(faction);
|
||||
return false;
|
||||
}
|
||||
}));
|
||||
securityWorkDivWrapper.appendChild(createElement("p", {
|
||||
innerText:"Serve in a security detail for your faction. " +
|
||||
"Your effectiveness, which determines how much " +
|
||||
"reputation you gain for this faction, is based on your combat stats. " +
|
||||
"You will gain exp for all combat stats."
|
||||
}));
|
||||
elements.push(securityWorkDiv);
|
||||
|
||||
//Donate for reputation
|
||||
var donateDiv = createElement("div", {
|
||||
id:"faction-donate-div", class:"faction-work-div"
|
||||
});
|
||||
var donateDivWrapper = createElement("div", {class:"faction-work-div-wrapper"});
|
||||
donateDiv.appendChild(donateDivWrapper);
|
||||
var donateRepGain = createElement("p", {
|
||||
innerText:"This donation will result in 0 reputation gain"
|
||||
});
|
||||
var donateAmountInput = createElement("input", {
|
||||
placeholder:"Donation amount",
|
||||
inputListener:()=>{
|
||||
var amt = parseFloat(donateAmountInput.value);
|
||||
if (isNaN(amt) || amt < 0) {
|
||||
donateRepGain.innerText = "Invalid donate amount entered!";
|
||||
} else {
|
||||
var repGain = amt / 1e6 * Player.faction_rep_mult;
|
||||
donateRepGain.innerText = "This donation will result in " +
|
||||
formatNumber(repGain, 3) + " reputation gain";
|
||||
}
|
||||
},
|
||||
});
|
||||
donateDivWrapper.appendChild(createElement("a", {
|
||||
class:"a-link-button", innerText:"Donate Money",
|
||||
clickListener:()=>{
|
||||
var amt = parseFloat(donateAmountInput.value);
|
||||
if (isNaN(amt) || amt < 0) {
|
||||
dialogBoxCreate("Invalid amount entered!");
|
||||
} else if (Player.money.lt(amt)) {
|
||||
dialogBoxCreate("You cannot afford to donate this much money!");
|
||||
} else {
|
||||
Player.loseMoney(amt);
|
||||
var repGain = amt / 1e6 * Player.faction_rep_mult;
|
||||
faction.playerReputation += repGain;
|
||||
dialogBoxCreate("You just donated " + numeral(amt).format("$0.000a") + " to " +
|
||||
faction.name + " to gain " + formatNumber(repGain, 3) + " reputation");
|
||||
displayFactionContent(factionName);
|
||||
}
|
||||
}
|
||||
}));
|
||||
donateDivWrapper.appendChild(donateAmountInput);
|
||||
donateDivWrapper.appendChild(donateRepGain);
|
||||
elements.push(donateDiv);
|
||||
|
||||
//Purchase Augmentations
|
||||
elements.push(createElement("pre", {
|
||||
innerHTML: "<br>As your reputation with this faction rises, you will " +
|
||||
"unlock Augmentations, which you can purchase to enhance " +
|
||||
"your abilities.<br><br>"
|
||||
}));
|
||||
elements.push(createElement("a", {
|
||||
class:"a-link-button", innerText:"Purchase Augmentations",
|
||||
clickListener:()=>{
|
||||
Engine.hideAllContent();
|
||||
Engine.Display.factionAugmentationsContent.style.display = "block";
|
||||
|
||||
|
||||
displayFactionAugmentations(factionName);
|
||||
return false;
|
||||
}
|
||||
}));
|
||||
|
||||
//Gang (BitNode-2)
|
||||
if (Player.bitNodeN == 2 && (factionName == "Slum Snakes" || factionName == "Tetrads" ||
|
||||
factionName == "The Syndicate" || factionName == "The Dark Army" || factionName == "Speakers for the Dead" ||
|
||||
factionName == "NiteSec" || factionName == "The Black Hand")) {
|
||||
@ -538,72 +635,54 @@ function displayFactionContent(factionName) {
|
||||
securityWorkDiv.style.display = "none";
|
||||
donateDiv.style.display = "none";
|
||||
|
||||
var gangDiv = document.getElementById("faction-gang-div");
|
||||
//Create the 'Manage Gang' button
|
||||
var gangDiv = createElement("div", {
|
||||
id:"faction-gang-div", class:"faction-work-div", display:"inline"
|
||||
});
|
||||
var gangDivWrapper = createElement("div", {class:"faction-work-div-wrapper"});
|
||||
gangDiv.appendChild(gangDivWrapper);
|
||||
gangDivWrapper.appendChild(createElement("a", {
|
||||
class:"a-link-button", innerText:"Manage Gang",
|
||||
clickListener:()=>{
|
||||
if (!Player.inGang()) {
|
||||
var yesBtn = yesNoBoxGetYesButton(), noBtn = yesNoBoxGetNoButton();
|
||||
yesBtn.innerHTML = "Create Gang";
|
||||
noBtn.innerHTML = "Cancel";
|
||||
yesBtn.addEventListener("click", () => {
|
||||
var hacking = false;
|
||||
if (factionName === "NiteSec" || factionName === "The Black Hand") {hacking = true;}
|
||||
Player.startGang(factionName, hacking);
|
||||
Engine.loadGangContent();
|
||||
yesNoBoxClose();
|
||||
});
|
||||
noBtn.addEventListener("click", () => {
|
||||
yesNoBoxClose();
|
||||
});
|
||||
yesNoBoxCreate("Would you like to create a new Gang with " + factionName + "?<br><br>" +
|
||||
"Note that this will prevent you from creating a Gang with any other Faction until " +
|
||||
"this BitNode is destroyed. There are NO differences between the Factions you can " +
|
||||
"create a Gang with and each of these Factions have all Augmentations available");
|
||||
} else {
|
||||
Engine.loadGangContent();
|
||||
}
|
||||
}
|
||||
}));
|
||||
gangDivWrapper.appendChild(createElement("p", {
|
||||
innerText:"Create and manage a gang for this Faction. " +
|
||||
"Gangs will earn you money and faction reputation."
|
||||
}));
|
||||
//Manage Gang button goes before Faction work stuff
|
||||
elements.splice(7, 1, gangDiv);
|
||||
|
||||
if (Player.inGang() && Player.gang.facName != factionName) {
|
||||
//If the player has a gang but its not for this faction
|
||||
if (gangDiv) {
|
||||
gangDiv.style.display = "none";
|
||||
}
|
||||
return;
|
||||
gangDiv.style.display = "none";
|
||||
}
|
||||
//Create the "manage gang" button if it doesn't exist
|
||||
if (gangDiv == null) {
|
||||
gangDiv = document.createElement("div");
|
||||
gangDiv.setAttribute("id", "faction-gang-div");
|
||||
gangDiv.setAttribute("class", "faction-work-div");
|
||||
gangDiv.style.display = "inline";
|
||||
|
||||
gangDiv.innerHTML =
|
||||
'<div id="faction-gang-div-wrapper" class="faction-work-div-wrapper">' +
|
||||
'<a id="faction-gang-button" class="a-link-button">Manage Gang</a>' +
|
||||
'<p id="faction-gang-text">' +
|
||||
'Create and manage a gang for this Faction. ' +
|
||||
'Gangs will earn you money and faction reputation.' +
|
||||
'</p>' +
|
||||
'</div>' +
|
||||
'<div class="faction-clear"></div>';
|
||||
|
||||
var descText = document.getElementById("faction-work-description-text");
|
||||
if (descText) {
|
||||
descText.parentNode.insertBefore(gangDiv, descText.nextSibling);
|
||||
} else {
|
||||
console.log("ERROR: faciton-work-description-text not found");
|
||||
dialogBoxCreate("Error loading this page. This is a bug please report to game developer");
|
||||
return;
|
||||
}
|
||||
//Display all elements
|
||||
for (var i = 0; i < elements.length; ++i) {
|
||||
Engine.Display.factionContent.appendChild(elements[i]);
|
||||
}
|
||||
gangDiv.style.display = "inline";
|
||||
|
||||
var gangButton = clearEventListeners("faction-gang-button");
|
||||
gangButton.addEventListener("click", function() {
|
||||
if (!Player.inGang()) {
|
||||
var yesBtn = yesNoBoxGetYesButton(), noBtn = yesNoBoxGetNoButton();
|
||||
yesBtn.innerHTML = "Create Gang";
|
||||
noBtn.innerHTML = "Cancel";
|
||||
yesBtn.addEventListener("click", () => {
|
||||
var hacking = false;
|
||||
if (factionName === "NiteSec" || factionName === "The Black Hand") {hacking = true;}
|
||||
Player.startGang(factionName, hacking);
|
||||
Engine.loadGangContent();
|
||||
yesNoBoxClose();
|
||||
});
|
||||
noBtn.addEventListener("click", () => {
|
||||
yesNoBoxClose();
|
||||
});
|
||||
yesNoBoxCreate("Would you like to create a new Gang with " + factionName + "?<br><br>" +
|
||||
"Note that this will prevent you from creating a Gang with any other Faction until " +
|
||||
"this BitNode is destroyed. There are NO differences between the Factions you can " +
|
||||
"create a Gang with and each of these Factions have all Augmentations available");
|
||||
} else {
|
||||
Engine.loadGangContent();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
return;
|
||||
} else {
|
||||
if (gangDiv) {gangDiv.style.display = "none";}
|
||||
}
|
||||
|
||||
if (faction.isMember) {
|
||||
@ -805,28 +884,138 @@ function displayFactionContent(factionName) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
console.log("Not a member of this faction, cannot display faction information");
|
||||
throw new Error("Not a member of this faction, cannot display faction information");
|
||||
}
|
||||
|
||||
//Display all elements
|
||||
for (var i = 0; i < elements.length; ++i) {
|
||||
Engine.Display.factionContent.appendChild(elements[i]);
|
||||
}
|
||||
}
|
||||
|
||||
var confirmingPurchases = true;
|
||||
var sortOption = null;
|
||||
function displayFactionAugmentations(factionName) {
|
||||
document.getElementById("faction-augmentations-page-desc").innerHTML =
|
||||
"Lists all Augmentations that are available to purchase from " + factionName + "<br><br>" +
|
||||
"Augmentations are powerful upgrades that will enhance your abilities.";
|
||||
|
||||
var faction = Factions[factionName];
|
||||
|
||||
var augmentationsList = document.getElementById("faction-augmentations-list");
|
||||
while (augmentationsList.firstChild) {
|
||||
augmentationsList.removeChild(augmentationsList.firstChild);
|
||||
if (faction == null) {
|
||||
throw new Error("Could not find faction " + factionName + " in displayFactionAugmentations");
|
||||
}
|
||||
|
||||
for (var i = 0; i < faction.augmentations.length; ++i) {
|
||||
removeChildrenFromElement(Engine.Display.factionAugmentationsContent);
|
||||
var elements = [];
|
||||
|
||||
//Back button
|
||||
elements.push(createElement("a", {
|
||||
innerText:"Back", class:"a-link-button",
|
||||
clickListener:()=>{
|
||||
Engine.loadFactionContent();
|
||||
displayFactionContent(factionName);
|
||||
return false;
|
||||
}
|
||||
}));
|
||||
|
||||
//Header text
|
||||
elements.push(createElement("h1", {innerText:"Faction Augmentations"}));
|
||||
elements.push(createElement("p", {
|
||||
id:"faction-augmentations-page-desc",
|
||||
innerHTML:"Lists all Augmentations that are available to purchase from " + factionName + "<br><br>" +
|
||||
"Augmentations are powerful upgrades that will enhance your abilities."
|
||||
}));
|
||||
|
||||
//Confirming not confirming button
|
||||
elements.push(createElement("label", {
|
||||
for:"faction-augmentations-confirming-checkbox",innerText:"Confirm Purchases",
|
||||
color:"white", margin:"4px", padding:"4px",
|
||||
}));
|
||||
var confirmingPurchasesCheckbox = createElement("input", {
|
||||
type:"checkbox", id:"faction-augmentations-confirming-checkbox", checked:confirmingPurchases,
|
||||
margin:"4px", padding:"4px",
|
||||
clickListener:()=>{
|
||||
confirmingPurchases = confirmingPurchasesCheckbox.checked;
|
||||
}
|
||||
});
|
||||
elements.push(confirmingPurchasesCheckbox);
|
||||
elements.push(createElement("br"));
|
||||
elements.push(createElement("br"));
|
||||
|
||||
//Augmentations List
|
||||
var augmentationsList = createElement("ul");
|
||||
|
||||
//Sort buttons
|
||||
var sortByCostBtn = createElement("a", {
|
||||
innerText:"Sort by Cost", class:"a-link-button",
|
||||
clickListener:()=>{
|
||||
sortOption = "cost";
|
||||
var augs = faction.augmentations.slice();
|
||||
augs.sort((augName1, augName2)=>{
|
||||
var aug1 = Augmentations[augName1], aug2 = Augmentations[augName2];
|
||||
if (aug1 == null || aug2 == null) {
|
||||
throw new Error("Invalid Augmentation Names");
|
||||
}
|
||||
return aug1.baseCost - aug2.baseCost;
|
||||
});
|
||||
removeChildrenFromElement(augmentationsList);
|
||||
createFactionAugmentationDisplayElements(augmentationsList, augs, faction);
|
||||
}
|
||||
});
|
||||
var sortByRepBtn = createElement("a", {
|
||||
innerText:"Sort by Reputation", class:"a-link-button",
|
||||
clickListener:()=>{
|
||||
sortOption = "reputation";
|
||||
var augs = faction.augmentations.slice();
|
||||
augs.sort((augName1, augName2)=>{
|
||||
var aug1 = Augmentations[augName1], aug2 = Augmentations[augName2];
|
||||
if (aug1 == null || aug2 == null) {
|
||||
throw new Error("Invalid Augmentation Names");
|
||||
}
|
||||
return aug1.baseRepRequirement - aug2.baseRepRequirement;
|
||||
});
|
||||
removeChildrenFromElement(augmentationsList);
|
||||
createFactionAugmentationDisplayElements(augmentationsList, augs, faction);
|
||||
}
|
||||
});
|
||||
var defaultSortBtn = createElement("a", {
|
||||
innerText:"Sort by Default Order", class:"a-link-button",
|
||||
clickListener:()=>{
|
||||
sortOption = "default";
|
||||
removeChildrenFromElement(augmentationsList);
|
||||
createFactionAugmentationDisplayElements(augmentationsList, faction.augmentations, faction);
|
||||
}
|
||||
});
|
||||
elements.push(sortByCostBtn);
|
||||
elements.push(sortByRepBtn);
|
||||
elements.push(defaultSortBtn);
|
||||
switch(sortOption) {
|
||||
case "cost":
|
||||
sortByCostBtn.click();
|
||||
break;
|
||||
case "reputation":
|
||||
sortByRepBtn.click();
|
||||
break;
|
||||
default:
|
||||
defaultSortBtn.click();
|
||||
break;
|
||||
}
|
||||
|
||||
elements.push(augmentationsList);
|
||||
|
||||
for (var i = 0; i < elements.length; ++i) {
|
||||
Engine.Display.factionAugmentationsContent.appendChild(elements[i]);
|
||||
}
|
||||
}
|
||||
|
||||
//Takes in an array of Augmentation Names, constructs DOM elements
|
||||
//to list them on the faction page, and appends them to the given
|
||||
//DOM element
|
||||
// @augmentationsList DOM List to append Aug DOM elements to
|
||||
// @augs Array of Aug names
|
||||
// @faction Faction for which to display Augmentations
|
||||
function createFactionAugmentationDisplayElements(augmentationsList, augs, faction) {
|
||||
for (var i = 0; i < augs.length; ++i) {
|
||||
(function () {
|
||||
var aug = Augmentations[faction.augmentations[i]];
|
||||
var aug = Augmentations[augs[i]];
|
||||
if (aug == null) {
|
||||
console.log("ERROR: Invalid Augmentation");
|
||||
return;
|
||||
throw new Error("Invalid Augmentation when trying to create Augmentation display Elements");
|
||||
}
|
||||
var owned = false;
|
||||
for (var j = 0; j < Player.queuedAugmentations.length; ++j) {
|
||||
@ -842,11 +1031,26 @@ function displayFactionAugmentations(factionName) {
|
||||
}
|
||||
}
|
||||
|
||||
var item = document.createElement("li");
|
||||
var span = document.createElement("span");
|
||||
var aDiv = document.createElement("div");
|
||||
var aElem = document.createElement("a");
|
||||
var pElem = document.createElement("p");
|
||||
var item = createElement("li");
|
||||
var span = createElement("span", {display:"inline-block"});
|
||||
var aDiv = createElement("div", {tooltip:aug.info});
|
||||
var aElem = createElement("a", {
|
||||
innerText:aug.name, display:"inline",
|
||||
clickListener:()=>{
|
||||
if (confirmingPurchases) {
|
||||
purchaseAugmentationBoxCreate(aug, faction);
|
||||
} else {
|
||||
purchaseAugmentation(aug, faction);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
if (aug.name == AugmentationNames.NeuroFluxGovernor) {
|
||||
aElem.innerText += " - Level " + (getNextNeurofluxLevel());
|
||||
}
|
||||
var pElem = createElement("p", {
|
||||
display:"inline",
|
||||
})
|
||||
var req = aug.baseRepRequirement * faction.augmentationRepRequirementMult;
|
||||
var hasPrereqs = hasAugmentationPrereqs(aug);
|
||||
if (!hasPrereqs) {
|
||||
@ -858,35 +1062,16 @@ function displayFactionAugmentations(factionName) {
|
||||
pElem.innerHTML = "ALREADY OWNED";
|
||||
} else if (faction.playerReputation >= req) {
|
||||
aElem.setAttribute("class", "a-link-button");
|
||||
//pElem.innerHTML = "UNLOCKED - $" + formatNumber(aug.baseCost * faction.augmentationPriceMult, 2);
|
||||
pElem.innerHTML = "UNLOCKED - " + numeral(aug.baseCost * faction.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.style.color = "red";
|
||||
}
|
||||
aElem.style.display = "inline";
|
||||
pElem.style.display = "inline";
|
||||
aElem.innerHTML = aug.name;
|
||||
if (aug.name == AugmentationNames.NeuroFluxGovernor) {
|
||||
aElem.innerHTML += " - Level " + (getNextNeurofluxLevel());
|
||||
}
|
||||
span.style.display = "inline-block"
|
||||
|
||||
//The div will have the tooltip.
|
||||
aDiv.setAttribute("class", "tooltip");
|
||||
aDiv.innerHTML = '<span class="tooltiptext">' + aug.info + " </span>";
|
||||
aDiv.appendChild(aElem);
|
||||
|
||||
aElem.addEventListener("click", function() {
|
||||
purchaseAugmentationBoxCreate(aug, faction);
|
||||
});
|
||||
|
||||
span.appendChild(aDiv);
|
||||
span.appendChild(pElem);
|
||||
|
||||
item.appendChild(span);
|
||||
|
||||
augmentationsList.appendChild(item);
|
||||
}()); //Immediate invocation closure
|
||||
}
|
||||
|
@ -1,61 +1,61 @@
|
||||
//Contains the "information" property for all the Factions, which is just a description
|
||||
//of each faction
|
||||
let FactionInfo = {
|
||||
//Endgame
|
||||
IlluminatiInfo: "Humanity never changes. No matter how civilized society becomes, it will eventually fall back " +
|
||||
//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. ",
|
||||
|
||||
DaedalusInfo: "Yesterday we obeyed kings and bent our necks to emperors. Today we kneel only to truth.",
|
||||
DaedalusInfo: "Yesterday we obeyed kings and bent our necks to emperors. Today we kneel only to truth.",
|
||||
|
||||
CovenantInfo: "Surrender yourself. Give up your empty individuality to become part of something great, something eternal. " +
|
||||
CovenantInfo: "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.",
|
||||
|
||||
//Megacorporations, each forms its own faction
|
||||
ECorpInfo: "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.",
|
||||
//Megacorporations, each forms its own faction
|
||||
ECorpInfo: "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.",
|
||||
|
||||
MegaCorpInfo: "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.",
|
||||
MegaCorpInfo: "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.",
|
||||
|
||||
BachmanAndAssociatesInfo: "Where Law and Business meet - thats where we are. <br><br>" +
|
||||
BachmanAndAssociatesInfo: "Where Law and Business meet - thats where we are. <br><br>" +
|
||||
"Legal Insight - Business Instinct - Experience Innovation",
|
||||
|
||||
BladeIndustriesInfo: "Augmentation is salvation",
|
||||
BladeIndustriesInfo: "Augmentation is salvation",
|
||||
|
||||
NWOInfo: "The human being created civilization not because of willingness but of a need to be assimilated into higher orders of structure and meaning.",
|
||||
NWOInfo: "The human being created civilization not because of willingness but of a need to be assimilated into higher orders of structure and meaning.",
|
||||
|
||||
ClarkeIncorporatedInfo: "Unlocking the power of the genome",
|
||||
ClarkeIncorporatedInfo: "Unlocking the power of the genome",
|
||||
|
||||
OmniTekIncorporatedInfo: "Simply put, our mission is to design and build robots that make a difference",
|
||||
OmniTekIncorporatedInfo: "Simply put, our mission is to design and build robots that make a difference",
|
||||
|
||||
FourSigmaInfo: "The scientific method is the best way to approach investing. Big strategies backed up with big data. Driven by " +
|
||||
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.",
|
||||
|
||||
KuaiGongInternationalInfo: "Dream big. Work hard. Make history.",
|
||||
KuaiGongInternationalInfo: "Dream big. Work hard. Make history.",
|
||||
|
||||
//Other Corporations
|
||||
FulcrumSecretTechnologiesInfo: "TODO",
|
||||
|
||||
//Hacker groups
|
||||
BitRunnersInfo: "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",
|
||||
//Hacker groups
|
||||
BitRunnersInfo: "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",
|
||||
|
||||
|
||||
BlackHandInfo: "The world, so afraid of strong government, now has no government. Only power - Digital power. Financial power. " +
|
||||
BlackHandInfo: "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.",
|
||||
"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.",
|
||||
|
||||
NiteSecInfo:
|
||||
NiteSecInfo:
|
||||
" __..__ <br>" +
|
||||
" _.nITESECNIt. <br>" +
|
||||
" .-'NITESECNITESEc. <br>" +
|
||||
@ -92,22 +92,22 @@ let FactionInfo = {
|
||||
" :bp.__.gNITESEC$$ :$ ; <br>" +
|
||||
" NITESECNITESECNIT $$b : <br>",
|
||||
|
||||
//City factions, essentially governments
|
||||
ChongqingInfo: "Serve the people",
|
||||
Sector12Info: "The City of the Future",
|
||||
HongKongInfo: "Asia's World City",
|
||||
AevumInfo: "The Silicon City",
|
||||
//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",
|
||||
VolhavenInfo: "Benefit, Honour, and Glory",
|
||||
|
||||
//Criminal Organizations/Gangs
|
||||
SpeakersForTheDeadInfo: "It is better to reign in hell than to serve in heaven.",
|
||||
//Criminal Organizations/Gangs
|
||||
SpeakersForTheDeadInfo: "It is better to reign in hell than to serve in heaven.",
|
||||
|
||||
DarkArmyInfo: "The World doesn't care about right or wrong. It's all about power.",
|
||||
DarkArmyInfo: "The World doesn't care about right or wrong. It's all about power.",
|
||||
|
||||
TheSyndicateInfo: "Honor holds you back",
|
||||
TheSyndicateInfo: "Honor holds you back",
|
||||
|
||||
SilhouetteInfo: "Corporations have filled the void of power left behind by the collapse of Western government. The issue is they've become so big " +
|
||||
SilhouetteInfo: "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. <br><br>" +
|
||||
"That's terror. Terror, fear, and corruption. All born into the system, all propagated by the system.",
|
||||
@ -116,16 +116,16 @@ let FactionInfo = {
|
||||
|
||||
SlumSnakesInfo: "Slum Snakes rule!",
|
||||
|
||||
//Earlygame factions - factions the player will prestige with early on that don't
|
||||
//belong in other categories
|
||||
//Earlygame factions - factions the player will prestige with early on that don't
|
||||
//belong in other categories
|
||||
NetburnersInfo: "~~//*>H4CK|\|3T 8URN3R5**>?>\\~~",
|
||||
|
||||
TianDiHuiInfo: "Obey Heaven and Work Righteousness",
|
||||
TianDiHuiInfo: "Obey Heaven and Work Righteousness",
|
||||
|
||||
CyberSecInfo: "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.",
|
||||
CyberSecInfo: "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.",
|
||||
|
||||
}
|
||||
|
||||
|
13
src/Gang.js
13
src/Gang.js
@ -1,6 +1,7 @@
|
||||
import {CONSTANTS} from "./Constants.js";
|
||||
import {Engine} from "./engine.js";
|
||||
import {Faction, Factions} from "./Faction.js";
|
||||
import {Faction, Factions,
|
||||
displayFactionContent} from "./Faction.js";
|
||||
import {Player} from "./Player.js";
|
||||
import {dialogBoxCreate} from "../utils/DialogBox.js";
|
||||
import {Reviver, Generic_toJSON,
|
||||
@ -949,6 +950,16 @@ function displayGangContent() {
|
||||
wanted = Player.gang.wanted,
|
||||
respect = Player.gang.respect;
|
||||
|
||||
//Back button
|
||||
gangContainer.appendChild(createElement("a", {
|
||||
class:"a-link-button", display:"inline-block", innerText:"Back",
|
||||
clickListener:()=>{
|
||||
Engine.loadFactionContent();
|
||||
displayFactionContent(facName);
|
||||
return false;
|
||||
}
|
||||
}));
|
||||
|
||||
//Buttons to switch between panels
|
||||
managementButton = createElement("a", {
|
||||
id:"gang-management-subpage-button", class:"a-link-button-inactive",
|
||||
|
@ -535,7 +535,7 @@ function updateInfiltrationButtons(inst, scenario) {
|
||||
"<span class='tooltiptext'>" +
|
||||
"Attempt to disable the security bots by hacking them. You have a " +
|
||||
formatNumber(hackChance*100, 2) + "% chance of success. " +
|
||||
"If you succeed, the security level will increase by 1%. If you fail, " +
|
||||
"If you succeed, the security level will increase by 3%. If you fail, " +
|
||||
"the security level will increase by 5%. </span>";
|
||||
|
||||
document.getElementById("infiltration-sneak").innerHTML = "Sneak" +
|
||||
@ -717,7 +717,7 @@ function getInfiltrationDestroySecurityChance(inst) {
|
||||
|
||||
|
||||
//Hack security
|
||||
//Success: 1%, Failure: 5%
|
||||
//Success: 3%, Failure: 5%
|
||||
function attemptInfiltrationHack(inst) {
|
||||
var chance = getInfiltrationHackChance(inst);
|
||||
inst.gainHackingExp(inst.securityLevel / 40) * Player.hacking_exp_mult;
|
||||
|
@ -88,6 +88,46 @@ function initLiterature() {
|
||||
"-Corporations do not reset when installing Augmentations, but they do reset when destroying a BitNode";
|
||||
Literatures[fn] = new Literature(title, fn, txt);
|
||||
|
||||
title = "A Brief History of Synthoids";
|
||||
fn = "history-of-synthoids.lit";
|
||||
txt = "Synthetic androids, or Synthoids for short, are genetically engineered robots and, short of Augmentations, " +
|
||||
"are composed entirely of organic substances. For this reason, Synthoids are virtually identical to " +
|
||||
"humans in form, composition, and appearance.<br><br>" +
|
||||
"Synthoids were first designed and manufactured by OmniTek Incorporated sometime around the turn of the century. " +
|
||||
"Their original purpose was to be used for manual labor and as emergency responders for disasters. As such, they " +
|
||||
"were initially programmed only for their specific tasks. Each iteration that followed improved upon the " +
|
||||
"intelligence and capabilities of the Synthoids. By the 6th iteration, called MK-VI, the Synthoids were " +
|
||||
"so smart and capable enough of making their own decisions that many argued OmniTek had created the first " +
|
||||
"sentient AI. These MK-VI Synthoids were produced in mass quantities (estimates up to 50 billion) with the hopes of increasing society's " +
|
||||
"productivity and bolstering the global economy. Stemming from humanity's desire for technological advancement, optimism " +
|
||||
"and excitement about the future had never been higher.<br><br>" +
|
||||
"All of that excitement and optimism quickly turned to fear, panic, and dread in 2070, when a terrorist group " +
|
||||
"called Ascendis Totalis hacked into OmniTek and uploaded a rogue AI into severeal of their Synthoid manufacturing facilities. " +
|
||||
"This hack went undetected and for months OmniTek unknowingly churned out legions of Synthoids embedded with this " +
|
||||
"rogue AI. Then, on December 24th, 2070, Omnica activated dormant protocols in the rogue AI, causing all of the " +
|
||||
"infected Synthoids to immediately launch a military campaign to seek and destroy all of humanity.<br><br>" +
|
||||
"What ensued was the deadlist conflict in human history. This crisis, now commonly known as the Synthoid Uprising, " +
|
||||
"resulted in almost ten billion deaths over the course of a year. Despite the nations of the world banding together " +
|
||||
"to combat the threat, the MK-VI Synthoids were simply stronger, faster, more intelligent, and more adaptable than humans, " +
|
||||
"outsmarting them at every turn.<br><br>" +
|
||||
"It wasn't until the sacrifice of an elite international military taskforce, called the Bladeburners, that humanity " +
|
||||
"was finally able to defeat the Synthoids. The Bladeburners' final act was a suicide bombing mission that " +
|
||||
"destroyed a large portion of the MK-VI Synthoids, including many of its leaders. In the following " +
|
||||
"weeks militaries from around the world were able to round up and shut down the remaining rogue MK-VI Synthoids, ending " +
|
||||
"the Synthoid Uprising.<br><br>" +
|
||||
"In the aftermath of the bloodshed, the Synthoid Accords were drawn up. These Accords banned OmniTek Incorporated " +
|
||||
"from manufacturing any Synthoids beyond the MK-III series. They also banned any other corporation " +
|
||||
"from constructing androids with advanced, near-sentient AI. MK-VI Synthoids that did not have the rogue Ascendis Totalis " +
|
||||
"AI were allowed to continue their existence, but they were stripped of all rights and protections as they " +
|
||||
"were not considered humans. They were also banned from doing anything that may pose a global security threat, such " +
|
||||
"as working for any military/defense organization or conducting any bioengineering, computing, or robotics related research.<br><br>" +
|
||||
"Unfortunately, many believe that not all of the rogue MK-VI Synthoids from the Uprising were found and destroyed, " +
|
||||
"and that many of them are blending in as normal humans in society today. In response, many nations have created " +
|
||||
"Bladeburner divisions, special military branches that are tasked with investigating and dealing with any Synthoid threads.<br><br>" +
|
||||
"To this day, tensions still exist between the remaining Synthoids and humans as a result of the Uprising.<br><br>" +
|
||||
"Nobody knows what happened to the terrorist group Ascendis Totalis.";
|
||||
Literatures[fn] = new Literature(title, fn, txt);
|
||||
|
||||
title = "A Green Tomorrow";
|
||||
fn = "A-Green-Tomorrow.lit";
|
||||
txt = "Starting a few decades ago, there was a massive global movement towards the generation of renewable energy in an effort to " +
|
||||
@ -385,6 +425,7 @@ function initLiterature() {
|
||||
fn = "the-secret-war.lit";
|
||||
txt = ""
|
||||
Literatures[fn] = new Literature(title, fn, txt);
|
||||
|
||||
}
|
||||
|
||||
export {Literatures, initLiterature, showLiterature};
|
||||
|
@ -34,7 +34,7 @@ import {yesNoBoxCreate, yesNoTxtInpBoxCreate,
|
||||
yesNoTxtInpBoxClose} from "../utils/YesNoBox.js";
|
||||
|
||||
/* Display Location Content when visiting somewhere in the World*/
|
||||
let Locations = {
|
||||
var Locations = {
|
||||
//Cities
|
||||
Aevum: "Aevum",
|
||||
//AevumDesc: ""
|
||||
@ -1576,14 +1576,6 @@ function initLocationButtons() {
|
||||
return false;
|
||||
});
|
||||
|
||||
let worldStockExchange = document.getElementById("generic-location-wse");
|
||||
worldStockExchange.addEventListener("click", function() {
|
||||
Player.location = Locations.WorldStockExchange;
|
||||
Engine.loadStockMarketContent();
|
||||
return false;
|
||||
});
|
||||
|
||||
|
||||
//Buttons to interact at a location (apply for job/promotion, train, purchase, etc.)
|
||||
var softwareJob = document.getElementById("location-software-job");
|
||||
var softwareConsultantJob = document.getElementById("location-software-consultant-job")
|
||||
|
253
src/engine.js
253
src/engine.js
@ -11,7 +11,8 @@ import {loxBoxCreate, logBoxUpdateText,
|
||||
import {setActiveScriptsClickHandlers,
|
||||
updateActiveScriptsItems} from "./ActiveScriptsUI.js";
|
||||
import {Augmentations, installAugmentations,
|
||||
initAugmentations, AugmentationNames} from "./Augmentations.js";
|
||||
initAugmentations, AugmentationNames,
|
||||
displayAugmentationsContent} from "./Augmentations.js";
|
||||
import {BitNodes, initBitNodes,
|
||||
initBitNodeMultipliers} from "./BitNode.js";
|
||||
import {CompanyPositions, initCompanies} from "./Company.js";
|
||||
@ -300,7 +301,7 @@ let Engine = {
|
||||
loadAugmentationsContent: function() {
|
||||
Engine.hideAllContent();
|
||||
Engine.Display.augmentationsContent.style.display = "block";
|
||||
Engine.displayAugmentationsContent();
|
||||
displayAugmentationsContent();
|
||||
Engine.currentPage = Engine.Page.Augmentations;
|
||||
document.getElementById("augmentations-menu-link").classList.add("active");
|
||||
},
|
||||
@ -628,10 +629,25 @@ let Engine = {
|
||||
break;
|
||||
}
|
||||
|
||||
//Generic Locations (common to every city):
|
||||
// World Stock Exchange
|
||||
// Corporation (if applicable)
|
||||
var genericLocationsList = document.getElementById("generic-locations-list");
|
||||
genericLocationsList.style.display = "inline";
|
||||
removeChildrenFromElement(genericLocationsList);
|
||||
var li = createElement("li");
|
||||
li.appendChild(createElement("a", {
|
||||
innerText:"World Stock Exchange", class:"a-link-button",
|
||||
clickListener:()=>{
|
||||
Player.location = Locations.WorldStockExchange;
|
||||
Engine.loadStockMarketContent();
|
||||
return false;
|
||||
}
|
||||
}));
|
||||
genericLocationsList.appendChild(li);
|
||||
|
||||
if (Player.corporation instanceof Corporation && document.getElementById("location-corporation-button") == null) {
|
||||
var li = createElement("li", {});
|
||||
var li = createElement("li");
|
||||
li.appendChild(createElement("a", {
|
||||
innerText:Player.corporation.name, id:"location-corporation-button",
|
||||
class:"a-link-button",
|
||||
@ -645,189 +661,80 @@ let Engine = {
|
||||
},
|
||||
|
||||
displayFactionsInfo: function() {
|
||||
//Clear the list of joined factions
|
||||
var factionsList = document.getElementById("factions-list");
|
||||
while (factionsList.firstChild) {
|
||||
factionsList.removeChild(factionsList.firstChild);
|
||||
}
|
||||
removeChildrenFromElement(Engine.Display.factionsContent);
|
||||
|
||||
//Re-add a link for each faction you are a member of
|
||||
//Factions
|
||||
Engine.Display.factionsContent.appendChild(createElement("h1", {
|
||||
innerText:"Factions"
|
||||
}));
|
||||
Engine.Display.factionsContent.appendChild(createElement("p", {
|
||||
innerText:"Lists all factions you have joined"
|
||||
}));
|
||||
var factionsList = createElement("ul");
|
||||
Engine.Display.factionsContent.appendChild(createElement("br"));
|
||||
|
||||
//Add a button for each faction you are a member of
|
||||
for (var i = 0; i < Player.factions.length; ++i) {
|
||||
(function () {
|
||||
var factionName = Player.factions[i];
|
||||
|
||||
//Add the faction to the Factions page content
|
||||
var item = document.createElement("li");
|
||||
var aElem = document.createElement("a");
|
||||
aElem.setAttribute("class", "a-link-button");
|
||||
aElem.innerHTML = factionName;
|
||||
aElem.addEventListener("click", function() {
|
||||
Engine.loadFactionContent();
|
||||
displayFactionContent(factionName);
|
||||
return false;
|
||||
});
|
||||
item.appendChild(aElem);
|
||||
factionsList.appendChild(item);
|
||||
factionsList.appendChild(createElement("a", {
|
||||
class:"a-link-button", innerText:factionName, padding:"4px", margin:"4px",
|
||||
display:"inline-block",
|
||||
clickListener:()=>{
|
||||
Engine.loadFactionContent();
|
||||
displayFactionContent(factionName);
|
||||
return false;
|
||||
}
|
||||
}));
|
||||
factionsList.appendChild(createElement("br"));
|
||||
}()); //Immediate invocation
|
||||
}
|
||||
Engine.Display.factionsContent.appendChild(factionsList);
|
||||
Engine.Display.factionsContent.appendChild(createElement("br"));
|
||||
|
||||
//Clear the list of invitations
|
||||
var invitationsList = document.getElementById("outstanding-faction-invitations-list");
|
||||
while (invitationsList.firstChild) {
|
||||
invitationsList.removeChild(invitationsList.firstChild);
|
||||
}
|
||||
//Invited Factions
|
||||
Engine.Display.factionsContent.appendChild(createElement("h1", {
|
||||
innerText:"Outstanding Faction Invitations"
|
||||
}));
|
||||
Engine.Display.factionsContent.appendChild(createElement("p", {
|
||||
width:"70%",
|
||||
innerText:"Lists factions you have been invited to, as well as " +
|
||||
"factions you have previously rejected. You can accept " +
|
||||
"these faction invitations at any time."
|
||||
}));
|
||||
var invitationsList = createElement("ul");
|
||||
|
||||
//Add a link to accept for each faction you have invitiations for
|
||||
//Add a button to accept for each faction you have invitiations for
|
||||
for (var i = 0; i < Player.factionInvitations.length; ++i) {
|
||||
(function () {
|
||||
var factionName = Player.factionInvitations[i];
|
||||
|
||||
var item = document.createElement("li");
|
||||
|
||||
var pElem = document.createElement("p");
|
||||
pElem.innerText = factionName;
|
||||
pElem.style.display = "inline";
|
||||
pElem.style.margin = "4px";
|
||||
pElem.style.padding = "4px";
|
||||
|
||||
var aElem = document.createElement("a");
|
||||
aElem.innerText = "Accept Faction Invitation";
|
||||
aElem.setAttribute("class", "a-link-button");
|
||||
aElem.style.display = "inline";
|
||||
aElem.style.margin = "4px";
|
||||
aElem.style.padding = "4px";
|
||||
aElem.addEventListener("click", function() {
|
||||
joinFaction(Factions[factionName]);
|
||||
for (var i = 0; i < Player.factionInvitations.length; ++i) {
|
||||
if (Player.factionInvitations[i] == factionName) {
|
||||
Player.factionInvitations.splice(i, 1);
|
||||
break;
|
||||
var item = createElement("li", {padding:"6px", margin:"6px"});
|
||||
item.appendChild(createElement("p", {
|
||||
innerText:factionName, display:"inline", margin:"4px", padding:"4px"
|
||||
}));
|
||||
item.appendChild(createElement("a", {
|
||||
innerText:"Accept Faction Invitation",
|
||||
class:"a-link-button", display:"inline", margin:"4px", padding:"4px",
|
||||
clickListener:()=>{
|
||||
joinFaction(Factions[factionName]);
|
||||
for (var i = 0; i < Player.factionInvitations.length; ++i) {
|
||||
if (Player.factionInvitations[i] == factionName) {
|
||||
Player.factionInvitations.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
Engine.displayFactionsInfo();
|
||||
return false;
|
||||
}
|
||||
Engine.displayFactionsInfo();
|
||||
return false;
|
||||
});
|
||||
}));
|
||||
|
||||
item.appendChild(pElem);
|
||||
item.appendChild(aElem);
|
||||
item.style.margin = "6px";
|
||||
item.style.padding = "6px";
|
||||
invitationsList.appendChild(item);
|
||||
}());
|
||||
}
|
||||
},
|
||||
|
||||
displayAugmentationsContent: function() {
|
||||
removeChildrenFromElement(Engine.Display.augmentationsContent);
|
||||
Engine.Display.augmentationsContent.appendChild(createElement("h1", {
|
||||
innerText:"Purchased Augmentations"
|
||||
}));
|
||||
|
||||
Engine.Display.augmentationsContent.appendChild(createElement("pre", {
|
||||
width:"70%", whiteSpace:"pre-wrap", display:"block",
|
||||
innerText:"Below is a list of all Augmentations you have purchased but not yet installed. Click the button below to install them.\n" +
|
||||
"WARNING: Installing your Augmentations resets most of your progress, including:\n\n" +
|
||||
"Stats/Skill levels and Experience\n" +
|
||||
"Money\n" +
|
||||
"Scripts on every computer but your home computer\n" +
|
||||
"Purchased servers\n" +
|
||||
"Hacknet Nodes\n" +
|
||||
"Faction/Company reputation\n" +
|
||||
"Stocks\n\n" +
|
||||
"Installing Augmentations lets you start over with the perks and benefits granted by all " +
|
||||
"of the Augmentations you have ever installed. Also, you will keep any scripts and RAM/Core upgrades " +
|
||||
"on your home computer (but you will lose all programs besides NUKE.exe)."
|
||||
}));
|
||||
|
||||
//Purchased/queued augmentations
|
||||
var queuedAugmentationsList = createElement("ul", {
|
||||
id:"queued-augmentations-list"
|
||||
});
|
||||
|
||||
for (var i = 0; i < Player.queuedAugmentations.length; ++i) {
|
||||
var augName = Player.queuedAugmentations[i].name;
|
||||
var aug = Augmentations[augName];
|
||||
|
||||
var item = createElement("li", {class:"installed-augmentation"});
|
||||
var displayName = augName;
|
||||
if (augName === AugmentationNames.NeuroFluxGovernor) {
|
||||
displayName += " - Level " + (Player.queuedAugmentations[i].level);
|
||||
}
|
||||
item.appendChild(createElement("h2", {innerHTML:displayName}));
|
||||
item.appendChild(createElement("p", {innerHTML:aug.info}));
|
||||
|
||||
queuedAugmentationsList.appendChild(item);
|
||||
}
|
||||
Engine.Display.augmentationsContent.appendChild(queuedAugmentationsList);
|
||||
|
||||
//Install Augmentations button
|
||||
Engine.Display.augmentationsContent.appendChild(createElement("a", {
|
||||
class:"a-link-button", innerText:"Install Augmentations",
|
||||
tooltip:"'I never asked for this'",
|
||||
clickListener:()=>{
|
||||
installAugmentations();
|
||||
return false;
|
||||
}
|
||||
}));
|
||||
|
||||
//Backup button
|
||||
Engine.Display.augmentationsContent.appendChild(createElement("a", {
|
||||
class:"a-link-button flashing-button", innerText:"Backup Save (Export)",
|
||||
tooltip:"It's always a good idea to backup/export your save!",
|
||||
clickListener:()=>{
|
||||
saveObject.exportGame();
|
||||
return false;
|
||||
}
|
||||
}));
|
||||
|
||||
//Installed augmentations list
|
||||
Engine.Display.augmentationsContent.appendChild(createElement("h1", {
|
||||
innerText:"Installed Augmentations"
|
||||
}));
|
||||
Engine.Display.augmentationsContent.appendChild(createElement("p", {
|
||||
width:"70%", whiteSpace:"pre-wrap",
|
||||
innerText:"List of all Augmentations (including Source Files) that have been " +
|
||||
"installed. You have gained the effects of these Augmentations"
|
||||
}));
|
||||
|
||||
var augmentationsList = createElement("ul", {
|
||||
id:"augmentations-list"
|
||||
});
|
||||
|
||||
//Source Files - Temporary...Will probably put in a separate pane Later
|
||||
for (var i = 0; i < Player.sourceFiles.length; ++i) {
|
||||
var srcFileKey = "SourceFile" + Player.sourceFiles[i].n;
|
||||
var sourceFileObject = SourceFiles[srcFileKey];
|
||||
if (sourceFileObject == null) {
|
||||
console.log("ERROR: Invalid source file number: " + Player.sourceFiles[i].n);
|
||||
continue;
|
||||
}
|
||||
var item = createElement("li", {class:"installed-augmentation", });
|
||||
item.appendChild(createElement("h2", {
|
||||
innerHTML:sourceFileObject.name + "<br>" + "Level " + (Player.sourceFiles[i].lvl) + " / 3",
|
||||
}));
|
||||
item.appendChild(createElement("p", {
|
||||
innerHTML:sourceFileObject.info,
|
||||
}));
|
||||
|
||||
augmentationsList.appendChild(item);
|
||||
}
|
||||
|
||||
for (var i = 0; i < Player.augmentations.length; ++i) {
|
||||
var augName = Player.augmentations[i].name;
|
||||
var aug = Augmentations[augName];
|
||||
|
||||
var item = createElement("li", {class:"installed-augmentation"});
|
||||
var displayName = augName;
|
||||
if (augName === AugmentationNames.NeuroFluxGovernor) {
|
||||
displayName += " - Level " + (Player.augmentations[i].level);
|
||||
}
|
||||
item.appendChild(createElement("h2", {innerHTML:displayName}));
|
||||
item.appendChild(createElement("p", {innerHTML:aug.info}));
|
||||
|
||||
augmentationsList.appendChild(item);
|
||||
}
|
||||
Engine.Display.augmentationsContent.appendChild(augmentationsList);
|
||||
Engine.Display.factionsContent.appendChild(invitationsList);
|
||||
},
|
||||
|
||||
displayTutorialContent: function() {
|
||||
@ -1367,61 +1274,47 @@ let Engine = {
|
||||
Engine.currentPage = Engine.Page.Terminal;
|
||||
|
||||
Engine.Display.characterContent = document.getElementById("character-container");
|
||||
//Engine.Display.characterContent.style.visibility = "hidden";
|
||||
Engine.Display.characterContent.style.display = "none";
|
||||
|
||||
Engine.Display.scriptEditorContent = document.getElementById("script-editor-container");
|
||||
//Engine.Display.scriptEditorContent.style.visibility = "hidden";
|
||||
Engine.Display.scriptEditorContent.style.display = "none";
|
||||
|
||||
Engine.Display.activeScriptsContent = document.getElementById("active-scripts-container");
|
||||
//Engine.Display.activeScriptsContent.style.visibility = "hidden";
|
||||
Engine.Display.activeScriptsContent.style.display = "none";
|
||||
|
||||
Engine.Display.hacknetNodesContent = document.getElementById("hacknet-nodes-container");
|
||||
//Engine.Display.hacknetNodesContent.style.visibility = "hidden";
|
||||
Engine.Display.hacknetNodesContent.style.display = "none";
|
||||
|
||||
Engine.Display.worldContent = document.getElementById("world-container");
|
||||
//Engine.Display.worldContent.style.visibility = "hidden";
|
||||
Engine.Display.worldContent.style.display = "none";
|
||||
|
||||
Engine.Display.createProgramContent = document.getElementById("create-program-container");
|
||||
//Engine.Display.createProgramContent.style.visibility = "hidden";
|
||||
Engine.Display.createProgramContent.style.display = "none";
|
||||
|
||||
Engine.Display.factionsContent = document.getElementById("factions-container");
|
||||
//Engine.Display.factionsContent.style.visibility = "hidden";
|
||||
Engine.Display.factionsContent.style.display = "none";
|
||||
|
||||
|
||||
Engine.Display.factionContent = document.getElementById("faction-container");
|
||||
//Engine.Display.factionContent.style.visibility = "hidden";
|
||||
Engine.Display.factionContent.style.display = "none";
|
||||
|
||||
Engine.Display.factionAugmentationsContent = document.getElementById("faction-augmentations-container");
|
||||
//Engine.Display.factionAugmentationsContent.style.visibility = "hidden";
|
||||
Engine.Display.factionAugmentationsContent.style.display = "none";
|
||||
|
||||
Engine.Display.augmentationsContent = document.getElementById("augmentations-container");
|
||||
//Engine.Display.augmentationsContent.style.visibility = "hidden";
|
||||
Engine.Display.augmentationsContent.style.display = "none";
|
||||
|
||||
|
||||
Engine.Display.tutorialContent = document.getElementById("tutorial-container");
|
||||
//Engine.Display.tutorialContent.style.visibility = "hidden";
|
||||
Engine.Display.tutorialContent.style.display = "none";
|
||||
|
||||
Engine.Display.infiltrationContent = document.getElementById("infiltration-container");
|
||||
//Engine.Display.infiltrationContent.style.visibility = "hidden";
|
||||
Engine.Display.infiltrationContent.style.display = "none";
|
||||
|
||||
Engine.Display.stockMarketContent = document.getElementById("stock-market-container");
|
||||
//Engine.Display.stockMarketContent.style.visibility = "hidden";
|
||||
Engine.Display.stockMarketContent.style.display = "none";
|
||||
|
||||
Engine.Display.missionContent = document.getElementById("mission-container");
|
||||
//Engine.Display.missionContent.style.visibility = "hidden";
|
||||
Engine.Display.missionContent.style.display = "none";
|
||||
|
||||
//Character info
|
||||
|
@ -1,5 +1,6 @@
|
||||
//General helper functions
|
||||
import {isString} from "./StringHelperFunctions.js";
|
||||
import {dialogBoxCreate} from "./DialogBox.js";
|
||||
|
||||
//Returns the size (number of keys) of an object
|
||||
function sizeOfObject(obj) {
|
||||
@ -207,7 +208,15 @@ function powerOfTwo(n) {
|
||||
return n && (n & (n-1)) === 0;
|
||||
}
|
||||
|
||||
function exceptionAlert(e) {
|
||||
dialogBoxCreate("Caught an exception: " + e + "<br><br>" +
|
||||
"This is a bug, please report to game developer with this " +
|
||||
"message as well as details about how to reproduce the bug.<br><br>" +
|
||||
"If you want to be safe, I suggest refreshing the game WITHOUT saving so that your " +
|
||||
"safe doesn't get corrupted");
|
||||
}
|
||||
|
||||
export {sizeOfObject, addOffset, clearEventListeners, getRandomInt,
|
||||
compareArrays, printArray, powerOfTwo, clearEventListenersEl,
|
||||
removeElementById, removeElement, createElement, createAccordionElement,
|
||||
removeChildrenFromElement, createPopup, clearSelector};
|
||||
removeChildrenFromElement, createPopup, clearSelector, exceptionAlert};
|
||||
|
@ -70,11 +70,6 @@ function isString(str) {
|
||||
return (typeof str === 'string' || str instanceof String);
|
||||
}
|
||||
|
||||
//Returns true if string contains only digits (meaning it would be a positive number)
|
||||
function isPositiveNumber(str) {
|
||||
return /^\d+$/.test(str);
|
||||
}
|
||||
|
||||
//Returns whether an array contains entirely of string objects
|
||||
function containsAllStrings(arr) {
|
||||
return arr.every(isString);
|
||||
@ -151,5 +146,5 @@ function generateRandomString(n) {
|
||||
}
|
||||
|
||||
export {getIndicesOf, convertTimeMsToTimeElapsedString, longestCommonStart,
|
||||
isString, isPositiveNumber, containsAllStrings, formatNumber,
|
||||
isString, containsAllStrings, formatNumber,
|
||||
numOccurrences, numNetscriptOperators, isHTML, generateRandomString};
|
||||
|
Loading…
Reference in New Issue
Block a user