mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-11-18 21:53:50 +01:00
0.27.0 2nd Tier Prestige + Gangs
This commit is contained in:
parent
4a99c04772
commit
3db6d9d007
@ -365,19 +365,13 @@
|
||||
display: inline;
|
||||
}
|
||||
|
||||
#faction-hack-div,
|
||||
#faction-fieldwork-div,
|
||||
#faction-securitywork-div,
|
||||
#faction-donate-div {
|
||||
.faction-work-div {
|
||||
overflow: hidden;
|
||||
width: 70%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#faction-hack-div-wrapper,
|
||||
#faction-fieldwork-div-wrapper,
|
||||
#faction-securitywork-div-wrapper,
|
||||
#faction-donate-div-wrapper {
|
||||
.faction-work-div-wrapper {
|
||||
float: left;
|
||||
border: 2px solid #333;
|
||||
padding: 14px 6px 4px 6px;
|
||||
@ -592,3 +586,75 @@ div.faction-clear {
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* Gang */
|
||||
#gang-container {
|
||||
position: fixed;
|
||||
padding: 6px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.gang-member-header {
|
||||
background-color: #444;
|
||||
font-size: 20px;
|
||||
color: white;
|
||||
margin: 6px 6px 0px 6px;
|
||||
padding: 6px;
|
||||
cursor: pointer;
|
||||
width: 80%;
|
||||
text-align: left;
|
||||
border: none;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.gang-member-header.active,
|
||||
.gang-member-header:hover {
|
||||
background-color: #555;
|
||||
}
|
||||
|
||||
.gang-member-header.active:hover {
|
||||
background-color: #666;
|
||||
}
|
||||
|
||||
.gang-member-header:after {
|
||||
content: '\02795'; /* "plus" sign (+) */
|
||||
font-size: 13px;
|
||||
color: white;
|
||||
float: right;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.gang-member-header.active:after {
|
||||
content: "\2796"; /* "minus" sign (-) */
|
||||
font-size: 13px;
|
||||
color: white;
|
||||
float: right;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.gang-member-panel {
|
||||
margin: 0px 6px 6px 6px;
|
||||
padding: 0px 6px 6px 6px;
|
||||
width: 75%;
|
||||
margin-left: 5%;
|
||||
display: none;
|
||||
background-color: #555;
|
||||
overflow:auto;
|
||||
}
|
||||
|
||||
.gang-member-panel div,
|
||||
.gang-member-panel ul,
|
||||
.gang-member-panel p,
|
||||
.gang-member-panel ul > li {
|
||||
background-color: #555;
|
||||
}
|
||||
|
||||
#gang-management-subpage > p {
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.gang-member-info-div {
|
||||
float:left;
|
||||
background-color: #555;
|
||||
}
|
||||
|
@ -97,12 +97,7 @@
|
||||
color: white;
|
||||
}
|
||||
|
||||
/* Purchase RAM for Home computer pop-up box */
|
||||
#purchase-ram-for-home-box-container {
|
||||
transition: opacity 400ms ease-in;
|
||||
}
|
||||
|
||||
/* Purchase Invitation Box */
|
||||
/* Purchase Augmentation Box */
|
||||
#purchase-augmentation-box-container {
|
||||
transition: opacity 400ms ease-in;
|
||||
}
|
||||
@ -116,16 +111,6 @@
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
/* Travel Pop-up Box */
|
||||
#travel-box-container {
|
||||
transition: opacity 400ms ease-in;
|
||||
}
|
||||
|
||||
|
||||
#travel-box-text {
|
||||
margin: 8px;
|
||||
}
|
||||
|
||||
/* Infiltration-box */
|
||||
#infiltration-box-sell,
|
||||
#infiltration-box-faction {
|
||||
@ -134,6 +119,11 @@
|
||||
margin: 8px;
|
||||
}
|
||||
|
||||
/* Generic Yes No Box */
|
||||
#yes-no-text-input-box-input {
|
||||
color: white;
|
||||
}
|
||||
|
||||
/* Game Options */
|
||||
#game-options-container {
|
||||
transition: opacity 400ms ease-in;
|
||||
|
56
index.html
56
index.html
@ -466,8 +466,8 @@
|
||||
use your terminal or create scripts when you are performing a task! <br><br><br><br>
|
||||
</p>
|
||||
|
||||
<div id="faction-hack-div">
|
||||
<div id="faction-hack-div-wrapper">
|
||||
<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.
|
||||
@ -478,8 +478,8 @@
|
||||
<div class="faction-clear"></div>
|
||||
</div>
|
||||
|
||||
<div id="faction-fieldwork-div">
|
||||
<div id="faction-fieldwork-div-wrapper">
|
||||
<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.
|
||||
@ -490,8 +490,8 @@
|
||||
<div class="faction-clear"></div>
|
||||
</div>
|
||||
|
||||
<div id="faction-securitywork-div">
|
||||
<div id="faction-securitywork-div-wrapper">
|
||||
<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.
|
||||
@ -502,8 +502,8 @@
|
||||
<div class="faction-clear"></div>
|
||||
</div>
|
||||
|
||||
<div id="faction-donate-div">
|
||||
<div id="faction-donate-div-wrapper">
|
||||
<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
|
||||
@ -542,7 +542,7 @@
|
||||
<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: Purchasing an Augmentation resets most of your progress, including: <br><br>
|
||||
<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>
|
||||
@ -550,8 +550,8 @@
|
||||
Hacknet Nodes <br>
|
||||
Faction/Company reputation <br>
|
||||
Stocks<br><br>
|
||||
Purchasing an Augmentation lets you start over with the perks and benefits granted by all
|
||||
of the Augmentations you have ever purchased. Also, you will keep any scripts and RAM upgrades
|
||||
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 upgrades
|
||||
on your home computer (but you will lose all programs besides NUKE.exe).
|
||||
</p>
|
||||
<br><br>
|
||||
@ -560,7 +560,7 @@
|
||||
<a id="install-augmentations-button" class="a-link-button"> Install Augmentations </a>
|
||||
<br><br>
|
||||
<h1> Installed Augmentations </h1>
|
||||
<p style="width:70%;"> List of all augmentations that have been installed. You have gained the effects of these augmentations </p>
|
||||
<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>
|
||||
@ -746,27 +746,28 @@
|
||||
<div id="purchase-server-box-content" class="popup-box-content">
|
||||
<p id="purchase-server-box-text"> </p>
|
||||
<p id="purchase-server-box-enter-name"> Enter new server hostname: </p>
|
||||
<input type="text" id="purchase-server-box-input" pattern="[a-zA-Z0-9-_]+ maxlength="30"> </input>
|
||||
<input type="text" id="purchase-server-box-input" pattern="[a-zA-Z0-9-_]" maxlength="30"> </input>
|
||||
<span id="purchase-server-box-confirm" class="popup-box-button"> Purchase </span>
|
||||
<span id="purchase-server-box-cancel" class="popup-box-button"> Cancel </span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Purchase RAM for Home Computer Pop-up Box -->
|
||||
<div id="purchase-ram-for-home-box-container" class="popup-box-container">
|
||||
<div id="purchase-ram-for-home-box-content" class="popup-box-content">
|
||||
<p id="purchase-ram-for-home-box-text"> </p>
|
||||
<span id="purchase-ram-for-home-box-confirm" class="popup-box-button"> Purchase </span>
|
||||
<span id="purchase-ram-for-home-box-cancel" class="popup-box-button"> Cancel </span>
|
||||
<!-- Generic Yes/No Pop Up box -->
|
||||
<div id="yes-no-box-container" class="popup-box-container">
|
||||
<div id="yes-no-box-content" class="popup-box-content">
|
||||
<p id="yes-no-box-text"> </p>
|
||||
<span id="yes-no-box-yes" class="popup-box-button"> Yes </span>
|
||||
<span id="yes-no-box-no" class="popup-box-button"> No </span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Travel Pop-up Box -->
|
||||
<div id="travel-box-container" class="popup-box-container">
|
||||
<div id="travel-box-content" class="popup-box-content">
|
||||
<p id="travel-box-text"> </p>
|
||||
<span id="travel-box-confirm" class="popup-box-button"> Yes </span>
|
||||
<span id="travel-box-cancel" class="popup-box-button"> No </span>
|
||||
<!-- Generic yes/no pop up box with text entry field -->
|
||||
<div id="yes-no-text-input-box-container" class="popup-box-container">
|
||||
<div id="yes-no-text-input-box-content" class="popup-box-content">
|
||||
<p id="yes-no-text-input-box-text"> </p>
|
||||
<input type="text" id="yes-no-text-input-box-input" pattern="[a-zA-Z0-9-_]" maxlength="30"> </input>
|
||||
<span id="yes-no-text-input-box-yes" class="popup-box-button"> Yes </span>
|
||||
<span id="yes-no-text-input-box-no" class="popup-box-button"> No </span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -982,12 +983,11 @@
|
||||
<script src="utils/PurchaseServerBox.js"></script>
|
||||
<script src="utils/FactionInvitationBox.js"></script>
|
||||
<script src="utils/PurchaseAugmentationBox.js"></script>
|
||||
<script src="utils/TravelBox.js"></script>
|
||||
<script src="utils/PurchaseRamForHomeBox.js"></script>
|
||||
<script src="utils/GameOptions.js"></script>
|
||||
<script src="utils/LogBox.js"></script>
|
||||
<script src="utils/InfiltrationBox.js"></script>
|
||||
<script src="utils/decimal.js"></script>
|
||||
<script src="utils/YesNoBox.js"></script>
|
||||
|
||||
<!-- Netscript -->
|
||||
<script src="src/NetscriptWorker.js"></script>
|
||||
@ -1027,6 +1027,8 @@
|
||||
<script src="src/RedPill.js"></script>
|
||||
<script src="src/BitNode.js"></script>
|
||||
<script src="src/Settings.js"></script>
|
||||
<script src="src/SourceFile.js"></script>
|
||||
<script src="src/Gang.js"></script>
|
||||
|
||||
<script src="src/engine.js"></script>
|
||||
</html>
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,8 +1,37 @@
|
||||
/* BitNode.js */
|
||||
|
||||
BitNodes = {
|
||||
BitNode1: new BitNode(1, "Source Genesis", "The original BitNode"),
|
||||
BitNode2: new BitNode(2, "Rise of the Underworld", "COMING SOON"), //Gangs
|
||||
BitNode1: new BitNode(1, "Source Genesis", "The original BitNode",
|
||||
"The first BitNode created by the Enders to imprison the minds of humans. It became " +
|
||||
"the prototype and testing-grounds for all of the BitNodes that followed.<br><br>" +
|
||||
"This is the first BitNode that you play through. It has no special " +
|
||||
"modifications or mechanics.<br><br>" +
|
||||
"Destroying this BitNode will give you Source-File 1, or if you already have " +
|
||||
"this Source-File it will upgrade its level up to a maximum of 3. This Source-File " +
|
||||
"lets the player start with 32GB of RAM on his/her home computer when entering a " +
|
||||
"new BitNode, and also increases all of the player's multipliers by:<br><br>" +
|
||||
"Level 1: 16%<br>" +
|
||||
"Level 2: 24%<br>" +
|
||||
"Level 3: 28%"),
|
||||
BitNode2: new BitNode(2, "Rise of the Underworld", "From the shadows, they rose", //Gangs
|
||||
"From the shadows, they rose.<br><br>Organized crime groups quickly filled the void of power " +
|
||||
"left behind from the collapse of Western government in the 2050's. As society and civlization broke down, " +
|
||||
"people quickly succumbed to the innate human impulse of evil and savagery. The organized crime " +
|
||||
"factions quickly rose to the top of the modern world.<br><br>" +
|
||||
"In this BitNode:<br><br>The maximum amount of money available on a server is significantly decreased<br>" +
|
||||
"The amount of money gained from crimes is doubled<br>" +
|
||||
"Certain Factions (Slum Snakes, Tetrads, The Syndicate, The Dark Army, Speakers for the Dead, " +
|
||||
"NiteSec, The Black Hand) give the player the ability to form and manage their own gangs. These gangs " +
|
||||
"will earn the player money and reputation with the corresponding Faction<br>" +
|
||||
"Every Augmentation in the game will be available through the Factions listed above<br>" +
|
||||
"For every Faction NOT listed above, reputation gains are halved<br>" +
|
||||
"You will no longer gain passive reputation with Factions<br>" +
|
||||
"Destroying the BitNode will give you Source-File 2, or if you already have this Source-File it will " +
|
||||
"upgrade its level up to a maximum of 3. This Source-File increases the player's crime success rate, " +
|
||||
"crime money, and charisma multipliers by:<br><br>" +
|
||||
"Level 1: 20%<br>" +
|
||||
"Level 2: 30%<br>" +
|
||||
"Level 3: 35%"),
|
||||
BitNode3: new BitNode(3, "The Price of Civilization", "COMING SOON"), //Corporate Warfare, Run own company
|
||||
BitNode4: new BitNode(4, "The Singularity", "COMING SOON"), //Everything automatable
|
||||
BitNode5: new BitNode(5, "2084", "COMING SOON"), //Big Brother
|
||||
@ -20,4 +49,36 @@ function BitNode(n, name, desc="", info="") {
|
||||
this.name = name;
|
||||
this.desc = desc;
|
||||
this.info = info;
|
||||
}
|
||||
}
|
||||
|
||||
BitNodeMultipliers = {
|
||||
ServerMaxMoney: 1,
|
||||
CrimeMoney: 1,
|
||||
FactionWorkRepGain: 1,
|
||||
FactionPassiveRepGain: 1,
|
||||
}
|
||||
|
||||
function initBitNodeMultipliers() {
|
||||
if (Player.bitNodeN == null) {
|
||||
Player.bitNodeN = 1;
|
||||
}
|
||||
for (var mult in BitNodeMultipliers) {
|
||||
if (BitNodeMultipliers.hasOwnProperty(mult)) {
|
||||
BitNodeMultipliers[mult] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
switch (Player.bitNodeN) {
|
||||
case 1:
|
||||
break;
|
||||
case 2: //Rise of the Underworld
|
||||
BitNodeMultipliers.ServerMaxMoney = 0.2;
|
||||
BitNodeMultipliers.CrimeMoney = 2;
|
||||
BitNodeMultipliers.FactionWorkRepGain = 0.5;
|
||||
BitNodeMultipliers.FactionPassiveRepGain = 0;
|
||||
break;
|
||||
default:
|
||||
console.log("WARNING: Player.bitNodeN invalid");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
//Netburner Company class
|
||||
// Note: Company Positions can be loaded every time with init() but Company class needs
|
||||
// to be saved/loaded from localStorage
|
||||
function Company(name, salaryMult, expMult, jobStatReqOffset) {
|
||||
function Company(name="", salaryMult=0, expMult=0, jobStatReqOffset=0) {
|
||||
this.companyName = name;
|
||||
this.info = "";
|
||||
this.companyPositions = []; //Names (only name, not object) of all company positions
|
||||
|
@ -24,13 +24,7 @@ PlayerObject.prototype.applyForJob = function(entryPosType) {
|
||||
while (true) {
|
||||
if (Engine.Debug) {console.log("Determining qualification for next Company Position");}
|
||||
var newPos = getNextCompanyPosition(pos);
|
||||
|
||||
if (newPos == null) {
|
||||
if (Engine.Debug) {
|
||||
console.log("Player already at highest position, cannot go any higher");
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (newPos == null) {break;}
|
||||
|
||||
//Check if this company has this position
|
||||
if (company.hasPosition(newPos)) {
|
||||
@ -42,7 +36,6 @@ PlayerObject.prototype.applyForJob = function(entryPosType) {
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//Check if the determined job is the same as the player's current job
|
||||
@ -50,9 +43,14 @@ PlayerObject.prototype.applyForJob = function(entryPosType) {
|
||||
if (currCompany.companyName == company.companyName &&
|
||||
pos.positionName == currPositionName) {
|
||||
var nextPos = getNextCompanyPosition(pos);
|
||||
var reqText = getJobRequirementText(company, nextPos);
|
||||
dialogBoxCreate("Unfortunately, you do not qualify for a promotion<br>" + reqText);
|
||||
|
||||
if (nextPos == null) {
|
||||
dialogBoxCreate("You are already at the highest position for your field! No promotion available");
|
||||
} else if (company.hasPosition(nextPos)) {
|
||||
var reqText = getJobRequirementText(company, nextPos);
|
||||
dialogBoxCreate("Unfortunately, you do not qualify for a promotion<br>" + reqText);
|
||||
} else {
|
||||
dialogBoxCreate("You are already at the highest position for your field! No promotion available");
|
||||
}
|
||||
return; //Same job, do nothing
|
||||
}
|
||||
}
|
||||
@ -167,10 +165,7 @@ PlayerObject.prototype.applyForItJob = function() {
|
||||
PlayerObject.prototype.applyForSecurityEngineerJob = function() {
|
||||
var company = Companies[this.location]; //Company being applied to
|
||||
if (this.isQualified(company, CompanyPositions.SecurityEngineer)) {
|
||||
this.companyName = company.companyName;
|
||||
this.companyPosition = CompanyPositions.SecurityEngineer;
|
||||
dialogBoxCreate("Congratulations, you were offered a position at " + this.companyName + " as a Security Engineer!");
|
||||
Engine.loadLocationContent();
|
||||
this.applyForJob(CompanyPositions.SecurityEngineer);
|
||||
} else {
|
||||
dialogBoxCreate("Unforunately, you do not qualify for this position");
|
||||
}
|
||||
|
8
src/CompanyManagement.js
Normal file
8
src/CompanyManagement.js
Normal file
@ -0,0 +1,8 @@
|
||||
/* CompanyManagement.js */
|
||||
|
||||
/*
|
||||
Company made up of
|
||||
|
||||
|
||||
|
||||
*/
|
@ -1,5 +1,5 @@
|
||||
CONSTANTS = {
|
||||
Version: "0.26.4",
|
||||
Version: "0.27.0",
|
||||
|
||||
//Max level for any skill, assuming no multipliers. Determined by max numerical value in javascript for experience
|
||||
//and the skill level formula in Player.js. Note that all this means it that when experience hits MAX_INT, then
|
||||
@ -29,9 +29,9 @@ CONSTANTS = {
|
||||
HacknetNodeMaxCores: 16,
|
||||
|
||||
/* Faction and Company favor */
|
||||
FactionReputationToFavorBase: 800,
|
||||
FactionReputationToFavorBase: 500,
|
||||
FactionReputationToFavorMult: 1.02,
|
||||
CompanyReputationToFavorBase: 750,
|
||||
CompanyReputationToFavorBase: 500,
|
||||
CompanyReputationToFavorMult: 1.02,
|
||||
|
||||
|
||||
@ -56,6 +56,7 @@ CONSTANTS = {
|
||||
ScriptRunRamCost: 0.8,
|
||||
ScriptExecRamCost: 1.1,
|
||||
ScriptScpRamCost: 0.5,
|
||||
ScriptKillRamCost: 0.5, //Kill and killall
|
||||
ScriptHasRootAccessRamCost: 0.05,
|
||||
ScriptGetHostnameRamCost: 0.05,
|
||||
ScriptGetHackingLevelRamCost: 0.05,
|
||||
@ -73,6 +74,8 @@ CONSTANTS = {
|
||||
ScriptPurchaseServerRamCost: 2.0,
|
||||
ScriptRoundRamCost: 0.05,
|
||||
ScriptReadWriteRamCost: 1.0,
|
||||
ScriptArbScriptRamCost: 1.0, //Functions that apply to all scripts regardless of args
|
||||
ScriptGetScriptCost: 0.1,
|
||||
|
||||
MultithreadingRAMCost: 1,
|
||||
|
||||
@ -104,6 +107,12 @@ CONSTANTS = {
|
||||
//Hospital/Health
|
||||
HospitalCostPerHp: 100000,
|
||||
|
||||
//Gang constants
|
||||
GangRespectToReputationRatio: 2, //Respect is divided by this to get rep gain
|
||||
MaximumGangMembers: 20,
|
||||
GangRecruitCostMultiplier: 2,
|
||||
GangTerritoryUpdateTimer: 150,
|
||||
|
||||
MillisecondsPer20Hours: 72000000,
|
||||
GameCyclesPer20Hours: 72000000 / 200,
|
||||
|
||||
@ -677,71 +686,19 @@ CONSTANTS = {
|
||||
"World Stock Exchange account and TIX API Access<br>",
|
||||
|
||||
LatestUpdate:
|
||||
"v0.26.5<br>" +
|
||||
"v0.27.0<br>" +
|
||||
"-Added secondary 'prestige' system - featuring Source Files and BitNodes<br>" +
|
||||
"-MILD SPOILERS HERE: Installing 'The Red Pill' Augmentation from Daedalus will unlock a special server called " +
|
||||
"w0r1d_d43m0n. Finding and manually hacking this server through Terminal will destroy the Player's current BitNode, and allow the player " +
|
||||
"to enter a new one. When destroying a BitNode, the player loses everything except the scripts on his/her " +
|
||||
"home computer. The player will then gain a powerful second-tier persistent upgrade called a Source File. The player can then " +
|
||||
"enter a new BitNode to start the game over. Each BitNode has different characteristics, and many will have new content/mechanics " +
|
||||
"as well. Right now there are only 2 BitNodes. Each BitNode grants its own unique Source File. Restarting and destroying a BitNode you already " +
|
||||
"have a Source File for will upgrade your Source File up to a maximum level of 3.<br><br>" +
|
||||
"-Reputation gain with factions and companies is no longer a linear conversion, but an exponential one. It " +
|
||||
"will not be easier to gain faction at first, but much harder later. <br>" +
|
||||
"v0.26.4<br>" +
|
||||
"-All of the 'low-level servers' in early game that have a required hacking level now have 8GB of RAM " +
|
||||
"instead of 4GB<br>" +
|
||||
"-Increased the amount of experience given at university<br>" +
|
||||
"-Slightly increased the production of Hacknet Nodes and made them cheaper to upgrade<br>" +
|
||||
"-Infiltration now gives slightly more EXP and faction reputation<br>" +
|
||||
"-Added two new crimes. These crimes are viable to attempt early on in the game and are relatively passive (each take 60+ seconds to complete)<br>" +
|
||||
"-Crimes give more exp and more money<br>" +
|
||||
"-Max money available on a server decreased from 50x the server's starting money to 25x<br>" +
|
||||
"-Significantly increased wages for all jobs<br><br>" +
|
||||
"v0.26.3<br>" +
|
||||
"-Added support for large numbers using Decimal.js. Right now it only applies for the player's money<br>" +
|
||||
"-Purchasing servers with the Netscript function purchaseServer() is no longer 2x as expensive as doing manually, " +
|
||||
"it now costs the same<br>" +
|
||||
"-Early game servers have more starting money<br><br>" +
|
||||
"v0.26.2<br>" +
|
||||
"-Major rebalancing and randomization of the amount of money that servers start with<br>" +
|
||||
"-Significantly lowered hacking exp gain from hacking servers. The exp gain for higher-level servers was lowered more than " +
|
||||
"that of low level servers. (~16% for lower level servers, up to ~25% for higher-level servers)<br>" +
|
||||
"-Added deleteServer() Netscript function<br>" +
|
||||
"-You can now purchase a maximum of 25 servers each run (Deleting a server will allow you to purchase a new one)<br>" +
|
||||
"-Added autocompletion for './' Terminal command<br>" +
|
||||
"-Darkweb prices now displayed properly using toLocaleString()<br>" +
|
||||
"-Added NOT operator (!) and negation operator(-), so negative numbers should be functional now<br>" +
|
||||
"-Rejected faction invitations will now show up as 'Outstanding Faction Invites' in the Factions page. These " +
|
||||
"can be accepted at any point in the future<br>" +
|
||||
"-Added a few more configurable game settings for suppressing messages and faction invitations<br>" +
|
||||
"-Added tooltips for company job requirements<br><br>" +
|
||||
"v0.26.1<br>" +
|
||||
"-Added autocompletion for aliases<br>" +
|
||||
"-Added getServerRam() Netscript function()<br>" +
|
||||
"-Added getLevelUpgradeCost(n), getRamUpgradeCost(), getCoreUpgradeCost() functions for Netscript Hacknet Node API<br>" +
|
||||
"-Added some configurable settings (See Game Options menu)<br><br>" +
|
||||
"v0.26.0<br>" +
|
||||
"-Game now has a real ending, although it's not very interesting/satisfying right now. It sets up the framework for the secondary prestige system " +
|
||||
"in the future<br>" +
|
||||
"-Forgot to mention that since last update, comments now work in Netscript. Use // for single line comments or /* and */ for multiline comments " +
|
||||
"just like in Javascript<br>" +
|
||||
"-Added ports to Netscript. These ports are essentially serialized queues. You can use the write() Netscript function to write a value " +
|
||||
"to a queue, and then you can use the read() Netscript function to read the value from the queue. Once you read a value from the queue it will be " +
|
||||
"removed. There are only 10 queues (1-10), and each has a maximum capacity of 50 entries. If you try to write to a queue that is full, the " +
|
||||
"the first value is removed. See wiki/Netscript documentation for more details<br>" +
|
||||
"-You can now use the 'help' Terminal command for specific commands<br>" +
|
||||
"-You can now use './' to run a script/program (./NUKE.exe). However, tab completion currently doesn't work for it (I'm working on it)<br>" +
|
||||
"-Decreased the base growth rate of servers by ~25%<br>" +
|
||||
"-Both the effect of weaken() and its time to execute were halved. In other words, calling weaken() on a server only lowers its security by 0.05 (was 0.1 before) " +
|
||||
"but the time to execute the function is half of what it was before. Therefore, the effective rate of weaken() should be about the same<br>" +
|
||||
"-Increased all Infiltration rewards by ~10%, and increased infiltration rep gains by an additional 20% (~32% total for rep gains)<br>" +
|
||||
"-The rate at which the security level of a facility increases during Infiltration was decreased significantly (~33%)<br>" +
|
||||
"-Getting treated at the Hospital is now 33% more expensive<br>" +
|
||||
"-Slightly increased the amount of time it takes to hack a server<br>" +
|
||||
"-Slightly decreased the amount of money gained when hacking a server (~6%)<br>" +
|
||||
"-Slightly decreased the base cost for RAM on home computer, but increased the cost multiplier. This means " +
|
||||
"that upgrading RAM on the home computer should be slightly cheaper at the start, but slightly more expensive " +
|
||||
"later on<br>" +
|
||||
"-Increased the required hacking level for many late game servers<br>" +
|
||||
"-The sleep() Netscript function now takes an optional 'log' argument that specifies whether or " +
|
||||
"not the 'Sleeping for N milliseconds' will be logged for the script<br>" +
|
||||
"-Added clearLog() Netscript function<br>" +
|
||||
"-Deleted a few stocks. Didn't see a reason for having so many, and it just affects performance. Won't take " +
|
||||
"effect until you reset by installing Augmentations<br>" +
|
||||
"-There was a typo with Zeus Medical's server hostname. It is now 'zeus-med' rather than 'zeud-med'<br>" +
|
||||
"-Added keyboard shortcuts to quickly navigate between different menus. See wiki link <a href='http://bitburner.wikia.com/wiki/Shortcuts' target='_blank'>here</a><br>" +
|
||||
"-Changed the Navigation Menu UI",
|
||||
"will be much easier to gain faction favor at first, but much harder later on. <br>" +
|
||||
"-Significantly increased Infiltration exp gains<br>" +
|
||||
"-Fixed a bug with company job requirement tooltips<br>" +
|
||||
"-Added scriptRunning(), scriptKill(), and getScriptRam() Netscript functions. See documentation for details<br>" +
|
||||
"-Fixed a bug with deleteServer() Netscript function<br><br>"
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ function factionInit() {
|
||||
}
|
||||
document.addEventListener("DOMContentLoaded", factionInit, false);
|
||||
|
||||
function Faction(name) {
|
||||
function Faction(name="") {
|
||||
this.name = name;
|
||||
this.augmentations = []; //Name of augmentation only
|
||||
this.info = ""; //Introductory/informational text about the faction
|
||||
@ -76,6 +76,16 @@ Faction.prototype.getFavorGain = function() {
|
||||
return [favorGain, rep];
|
||||
}
|
||||
|
||||
//Adds all Augmentations to this faction.
|
||||
Faction.prototype.addAllAugmentations = function() {
|
||||
this.augmentations.length = 0;
|
||||
for (var name in Augmentations) {
|
||||
if (Augmentations.hasOwnProperty(name)) {
|
||||
this.augmentations.push(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Faction.prototype.toJSON = function() {
|
||||
return Generic_toJSON("Faction", this);
|
||||
}
|
||||
@ -563,8 +573,8 @@ PlayerObject.prototype.checkForFactionInvitations = function() {
|
||||
var speakersforthedeadFac = Factions["Speakers for the Dead"];
|
||||
if (!speakersforthedeadFac.isBanned && !speakersforthedeadFac.isMember && !speakersforthedeadFac.alreadyInvited &&
|
||||
this.hacking_skill >= 100 && this.strength >= 300 && this.defense >= 300 &&
|
||||
this.dexterity >= 300 && this.agility >= 300 && this.numPeopleKilled >= 10 &&
|
||||
this.numPeopleKilledTotal >= 100 && this.karma <= -45 && this.companyName != Locations.Sector12CIA &&
|
||||
this.dexterity >= 300 && this.agility >= 300 && this.numPeopleKilled >= 30 &&
|
||||
this.karma <= -45 && this.companyName != Locations.Sector12CIA &&
|
||||
this.companyName != Locations.Sector12NSA) {
|
||||
invitedFactions.push(speakersforthedeadFac);
|
||||
}
|
||||
@ -761,7 +771,7 @@ displayFactionContent = function(factionName) {
|
||||
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");
|
||||
|
||||
var newHackButton = clearEventListeners("faction-hack-button");
|
||||
var newFieldWorkButton = clearEventListeners("faction-fieldwork-button");
|
||||
@ -818,6 +828,81 @@ displayFactionContent = function(factionName) {
|
||||
return false;
|
||||
});
|
||||
|
||||
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")) {
|
||||
//Set everything else to invisible
|
||||
hackDiv.style.display = "none";
|
||||
fieldWorkDiv.style.display = "none";
|
||||
securityWorkDiv.style.display = "none";
|
||||
donateDiv.style.display = "none";
|
||||
|
||||
if (Player.gang && Player.gang.facName != factionName) {
|
||||
//If the player has a gang but its not for this faction
|
||||
gangDiv.style.display = "none";
|
||||
return;
|
||||
}
|
||||
|
||||
var gangDiv = document.getElementById("faction-gang-div");
|
||||
//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;
|
||||
}
|
||||
}
|
||||
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.gang = new Gang(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) {
|
||||
if (faction.favor >= 150) {
|
||||
donateDiv.style.display = "inline";
|
||||
@ -1072,7 +1157,7 @@ function processPassiveFactionRepGain(numCycles) {
|
||||
//TODO Get hard value of 1 rep per "rep gain cycle"" for now..
|
||||
//maybe later make this based on
|
||||
//a player's 'status' like how powerful they are and how much money they have
|
||||
if (faction.isMember) {faction.playerReputation += numTimesGain;}
|
||||
if (faction.isMember) {faction.playerReputation += (numTimesGain * BitNodeMultipliers.FactionPassiveRepGain);}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
1033
src/Gang.js
Normal file
1033
src/Gang.js
Normal file
File diff suppressed because it is too large
Load Diff
@ -198,6 +198,7 @@ function nextInfiltrationLevel(inst) {
|
||||
"rest of the facility's security. The facility's security " +
|
||||
"level has increased by " + formatNumber((res[1]*100)-100, 2).toString() + "%");
|
||||
Player.karma -= 3;
|
||||
++Player.numPeopleKilled;
|
||||
endInfiltrationLevel(inst);
|
||||
return false;
|
||||
} else {
|
||||
@ -221,6 +222,7 @@ function nextInfiltrationLevel(inst) {
|
||||
if (res[0]) {
|
||||
writeInfiltrationStatusText("You SUCCESSFULLY assassinated the security guard without being detected!");
|
||||
Player.karma -= 3;
|
||||
++Player.numPeopleKilled;
|
||||
endInfiltrationLevel(inst);
|
||||
return false;
|
||||
} else {
|
||||
@ -574,10 +576,10 @@ function updateInfiltrationButtons(inst, scenario) {
|
||||
//Success: 5%, Failure 10%, -Karma
|
||||
function attemptInfiltrationKill(inst) {
|
||||
var chance = getInfiltrationKillChance(inst);
|
||||
inst.gainStrengthExp(inst.securityLevel / 400) * Player.strength_exp_mult;
|
||||
inst.gainDefenseExp(inst.securityLevel / 400) * Player.defense_exp_mult;
|
||||
inst.gainDexterityExp(inst.securityLevel / 400) * Player.dexterity_exp_mult;
|
||||
inst.gainAgilityExp(inst.securityLevel / 400) * Player.agility_exp_mult;
|
||||
inst.gainStrengthExp(inst.securityLevel / 100) * Player.strength_exp_mult;
|
||||
inst.gainDefenseExp(inst.securityLevel / 100) * Player.defense_exp_mult;
|
||||
inst.gainDexterityExp(inst.securityLevel / 100) * Player.dexterity_exp_mult;
|
||||
inst.gainAgilityExp(inst.securityLevel / 100) * Player.agility_exp_mult;
|
||||
if (Math.random() <= chance) {
|
||||
inst.securityLevel *= 1.05;
|
||||
return [true, 1.05];
|
||||
@ -600,10 +602,10 @@ function getInfiltrationKillChance(inst) {
|
||||
//Success: 3%, Failure: 10%
|
||||
function attemptInfiltrationKnockout(inst) {
|
||||
var chance = getInfiltrationKnockoutChance(inst);
|
||||
inst.gainStrengthExp(inst.securityLevel / 400) * Player.strength_exp_mult;
|
||||
inst.gainDefenseExp(inst.securityLevel / 400) * Player.defense_exp_mult;
|
||||
inst.gainDexterityExp(inst.securityLevel / 400) * Player.dexterity_exp_mult;
|
||||
inst.gainAgilityExp(inst.securityLevel / 400) * Player.agility_exp_mult;
|
||||
inst.gainStrengthExp(inst.securityLevel / 100) * Player.strength_exp_mult;
|
||||
inst.gainDefenseExp(inst.securityLevel / 100) * Player.defense_exp_mult;
|
||||
inst.gainDexterityExp(inst.securityLevel / 100) * Player.dexterity_exp_mult;
|
||||
inst.gainAgilityExp(inst.securityLevel / 100) * Player.agility_exp_mult;
|
||||
if (Math.random() <= chance) {
|
||||
inst.securityLevel *= 1.03;
|
||||
return [true, 1.03];
|
||||
@ -625,9 +627,9 @@ function getInfiltrationKnockoutChance(inst) {
|
||||
//Success: 0%, Failure: 10%
|
||||
function attemptInfiltrationStealthKnockout(inst) {
|
||||
var chance = getInfiltrationStealthKnockoutChance(inst);
|
||||
inst.gainStrengthExp(inst.securityLevel / 400) * Player.strength_exp_mult;
|
||||
inst.gainDexterityExp(inst.securityLevel / 250) * Player.dexterity_exp_mult;
|
||||
inst.gainAgilityExp(inst.securityLevel / 250) * Player.agility_exp_mult;
|
||||
inst.gainStrengthExp(inst.securityLevel / 100) * Player.strength_exp_mult;
|
||||
inst.gainDexterityExp(inst.securityLevel / 75) * Player.dexterity_exp_mult;
|
||||
inst.gainAgilityExp(inst.securityLevel / 75) * Player.agility_exp_mult;
|
||||
if (Math.random() <= chance) {
|
||||
return [true, 1];
|
||||
} else {
|
||||
@ -648,9 +650,9 @@ function getInfiltrationStealthKnockoutChance(inst) {
|
||||
//Success: 0%, Failure: 5%, -Karma
|
||||
function attemptInfiltrationAssassinate(inst) {
|
||||
var chance = getInfiltrationAssassinateChance(inst);
|
||||
inst.gainStrengthExp(inst.securityLevel / 400) * Player.strength_exp_mult;
|
||||
inst.gainDexterityExp(inst.securityLevel / 250) * Player.dexterity_exp_mult;
|
||||
inst.gainAgilityExp(inst.securityLevel / 250) * Player.agility_exp_mult;
|
||||
inst.gainStrengthExp(inst.securityLevel / 100) * Player.strength_exp_mult;
|
||||
inst.gainDexterityExp(inst.securityLevel / 75) * Player.dexterity_exp_mult;
|
||||
inst.gainAgilityExp(inst.securityLevel / 75) * Player.agility_exp_mult;
|
||||
if (Math.random() <= chance) {
|
||||
return [true, 1];
|
||||
} else {
|
||||
@ -671,10 +673,10 @@ function getInfiltrationAssassinateChance(inst) {
|
||||
//Success: 5%, Failure: 10%
|
||||
function attemptInfiltrationDestroySecurity(inst) {
|
||||
var chance = getInfiltrationDestroySecurityChance(inst);
|
||||
inst.gainStrengthExp(inst.securityLevel / 400) * Player.strength_exp_mult;
|
||||
inst.gainDefenseExp(inst.securityLevel / 400) * Player.defense_exp_mult;
|
||||
inst.gainDexterityExp(inst.securityLevel / 400) * Player.dexterity_exp_mult;
|
||||
inst.gainAgilityExp(inst.securityLevel / 400) * Player.agility_exp_mult;
|
||||
inst.gainStrengthExp(inst.securityLevel / 100) * Player.strength_exp_mult;
|
||||
inst.gainDefenseExp(inst.securityLevel / 100) * Player.defense_exp_mult;
|
||||
inst.gainDexterityExp(inst.securityLevel / 100) * Player.dexterity_exp_mult;
|
||||
inst.gainAgilityExp(inst.securityLevel / 100) * Player.agility_exp_mult;
|
||||
if (Math.random() <= chance) {
|
||||
inst.securityLevel *= 1.05;
|
||||
return [true, 1.05];
|
||||
@ -698,7 +700,7 @@ function getInfiltrationDestroySecurityChance(inst) {
|
||||
//Success: 1%, Failure: 5%
|
||||
function attemptInfiltrationHack(inst) {
|
||||
var chance = getInfiltrationHackChance(inst);
|
||||
inst.gainHackingExp(inst.securityLevel / 150) * Player.hacking_exp_mult;
|
||||
inst.gainHackingExp(inst.securityLevel / 75) * Player.hacking_exp_mult;
|
||||
if (Math.random() <= chance) {
|
||||
inst.securityLevel *= 1.03;
|
||||
return [true, 1.03];
|
||||
@ -719,7 +721,7 @@ function getInfiltrationHackChance(inst) {
|
||||
//Success: 0%, Failure: 8%
|
||||
function attemptInfiltrationSneak(inst) {
|
||||
var chance = getInfiltrationSneakChance(inst);
|
||||
inst.gainAgilityExp(inst.securityLevel / 150) * Player.agility_exp_mult;
|
||||
inst.gainAgilityExp(inst.securityLevel / 75) * Player.agility_exp_mult;
|
||||
if (Math.random() <= chance) {
|
||||
return [true, 1];
|
||||
} else {
|
||||
@ -739,7 +741,7 @@ function getInfiltrationSneakChance(inst) {
|
||||
//Success: 1%, Failure: 3%
|
||||
function attemptInfiltrationPickLockedDoor(inst) {
|
||||
var chance = getInfiltrationPickLockedDoorChance(inst);
|
||||
inst.gainDexterityExp(inst.securityLevel / 150) * Player.dexterity_exp_mult;
|
||||
inst.gainDexterityExp(inst.securityLevel / 75) * Player.dexterity_exp_mult;
|
||||
if (Math.random() <= chance) {
|
||||
inst.securityLevel *= 1.01;
|
||||
return [true, 1.01];
|
||||
@ -759,7 +761,7 @@ function getInfiltrationPickLockedDoorChance(inst) {
|
||||
//Success: 0%, Failure: 15%,
|
||||
function attemptInfiltrationBribe(inst) {
|
||||
var chance = getInfiltrationBribeChance(inst);
|
||||
inst.gainCharismaExp(inst.securityLevel / 100) * Player.charisma_exp_mult;
|
||||
inst.gainCharismaExp(inst.securityLevel / 50) * Player.charisma_exp_mult;
|
||||
if (Math.random() <= chance) {
|
||||
return [true, 1];
|
||||
} else {
|
||||
@ -778,8 +780,8 @@ function getInfiltrationBribeChance(inst) {
|
||||
//Failure: 5%
|
||||
function attemptInfiltrationEscape(inst) {
|
||||
var chance = getInfiltrationEscapeChance(inst);
|
||||
inst.gainAgilityExp(inst.securityLevel / 250) * Player.agility_exp_mult;
|
||||
inst.gainDexterityExp(inst.securityLevel / 250) * Player.dexterity_exp_mult;
|
||||
inst.gainAgilityExp(inst.securityLevel / 50) * Player.agility_exp_mult;
|
||||
inst.gainDexterityExp(inst.securityLevel / 50) * Player.dexterity_exp_mult;
|
||||
if (Math.random() <= chance) {
|
||||
return [true, 1];
|
||||
} else {
|
||||
|
62
src/Literature.js
Normal file
62
src/Literature.js
Normal file
@ -0,0 +1,62 @@
|
||||
/* Literature.js
|
||||
* Lore / world building literature that can be found on servers
|
||||
*/
|
||||
function Literature(title, filename, txt) {
|
||||
this.title = title;
|
||||
this.fn = filename;
|
||||
this.txt = txt;
|
||||
}
|
||||
|
||||
Literature.prototype.display = function() {
|
||||
var txt = this.title + "<br><br>" +
|
||||
"<i>" + this.txt + "</i>";
|
||||
dialogBoxCreate(txt);
|
||||
}
|
||||
|
||||
Literature.prototype.addToserver = function(server) {
|
||||
if (server == null) {
|
||||
console.log("WARNING: Could not locate server");
|
||||
return;
|
||||
}
|
||||
server.messages.push(this);
|
||||
}
|
||||
|
||||
Literature.prototype.toJSON = function() {
|
||||
return Generic_toJSON("Literature", this);
|
||||
}
|
||||
|
||||
Literature.fromJSON = function(value) {
|
||||
return Generic_fromJSON(Literature, value.data);
|
||||
}
|
||||
|
||||
Reviver.constructors.Literature = Literature;
|
||||
|
||||
Literatures = {}
|
||||
|
||||
function initLiterature() {
|
||||
var title, fn, txt;
|
||||
title = "A Green Tomorrow"; //Tomorrow is Green
|
||||
fn = "A-Green-Tomorrow.lit";
|
||||
txt = "In the past few decades, there has been a massive global movement towards the generation of renewable energy in an effort to" +
|
||||
"combat global warming and climate change. The shift towards renewable energy was a big success";
|
||||
Literatures[fn] = new Literature(title, fn);
|
||||
title = "Alpha and Omega"; //Cryptic article about BitNodes
|
||||
title = "Are we living in a simulated reality?"; //lol
|
||||
title = "Beyond Man"; //Better than nature?
|
||||
title = "Brighter than the Sun"; // Article about TaiYang Digital
|
||||
title = "Democracy is Dead: The Fall of an Empire"; //Government is a powerless figurehead, megacorporation rule
|
||||
title = "Fall of an Empire";
|
||||
title = "Figures show rising crime rates in Sector-12"; //Article about the Syndicate
|
||||
title = "Man and the Machine"; //Blurring the Boundaries between Man and the Machine
|
||||
title = "Secret Societies"; //Talks about how hacking factions have replaced typical secret societies like Illuminati
|
||||
title = "Space: The Failed Frontier"; //A Frontier too far?
|
||||
title = "Coded Intelligence: Myth or Reality?"; //Discusses whether true intelligence can be implemented in software. Foreshadows intelligence stat in later BItnodes
|
||||
title = "Synthetic Muscles"; //Artificial muscles
|
||||
title = "Tensions rise in global tech race"; //Article about competition+conflict between tech mega corps (OmniTek, ECorp..Taiyang? etc.)
|
||||
title = "The Cost of Immortality"; //Grey Skies
|
||||
title = "The Hidden World"; //The Sleepwalking World
|
||||
title = "The New God"; //Singularity Church of the MachineGod
|
||||
title = "The New Triads"; //About tetrads, Dragon Heads: The Triads of the 21st Century
|
||||
title = "The Secret War"; //War between those who wanted Augmentations widely available and those who wanted to keep it secret
|
||||
title = "An uncertain future for Defense Contractors"; //Less war and globalism = less profit for defense contractors
|
||||
}
|
@ -787,7 +787,7 @@ displayLocationContent = function() {
|
||||
locationInfo.innerHTML = Companies[loc].info;
|
||||
|
||||
waiterJob.style.display = "block";
|
||||
waitPartTimeJob.style.display = "block";
|
||||
waiterPartTimeJob.style.display = "block";
|
||||
break;
|
||||
|
||||
case Locations.IshimaTravelAgency:
|
||||
@ -1689,8 +1689,29 @@ initLocationButtons = function() {
|
||||
});
|
||||
|
||||
purchaseHomeRam.addEventListener("click", function() {
|
||||
purchaseRamForHomeBoxCreate();
|
||||
return false;
|
||||
//Calculate how many times ram has been upgraded (doubled)
|
||||
var currentRam = Player.getHomeComputer().maxRam;
|
||||
var newRam = currentRam * 2;
|
||||
var numUpgrades = Math.log2(currentRam);
|
||||
|
||||
//Calculate cost
|
||||
//Have cost increase by some percentage each time RAM has been upgraded
|
||||
var cost = currentRam * CONSTANTS.BaseCostFor1GBOfRamHome;
|
||||
var mult = Math.pow(1.55, numUpgrades);
|
||||
cost = cost * mult;
|
||||
|
||||
var yesBtn = yesNoBoxGetYesButton(), noBtn = yesNoBoxGetNoButton();
|
||||
yesBtn.innerHTML = "Purchase"; noBtn.innerHTML = "Cancel";
|
||||
yesBtn.addEventListener("click", ()=>{
|
||||
purchaseRamForHomeComputer(cost);
|
||||
yesNoBoxClose();
|
||||
});
|
||||
noBtn.addEventListener("click", ()=>{
|
||||
yesNoBoxClose();
|
||||
});
|
||||
yesNoBoxCreate("Would you like to purchase additional RAM for your home computer? <br><br>" +
|
||||
"This will upgrade your RAM from " + currentRam + "GB to " + newRam + "GB. <br><br>" +
|
||||
"This will cost $" + formatNumber(cost, 2));
|
||||
});
|
||||
|
||||
travelToAevum.addEventListener("click", function() {
|
||||
@ -1949,6 +1970,23 @@ function setJobRequirementTooltip(loc, entryPosType, btn) {
|
||||
if (company == null) {return;}
|
||||
var pos = Player.getNextCompanyPosition(company, entryPosType);
|
||||
if (pos == null) {return};
|
||||
if (!company.hasPosition(pos)) {return;}
|
||||
var reqText = getJobRequirementText(company, pos, true);
|
||||
btn.innerHTML += "<span class='tooltiptext'>" + reqText + "</span>";
|
||||
}
|
||||
|
||||
function travelBoxCreate(destCityName, cost) {
|
||||
var yesBtn = yesNoBoxGetYesButton(), noBtn = yesNoBoxGetNoButton();
|
||||
yesBtn.innerHTML = "Yes";
|
||||
noBtn.innerHTML = "No";
|
||||
noBtn.addEventListener("click", () => {
|
||||
yesNoBoxClose();
|
||||
return false;
|
||||
});
|
||||
yesBtn.addEventListener("click", () => {
|
||||
yesNoBoxClose();
|
||||
travelToCity(destCityName, cost);
|
||||
return false;
|
||||
});
|
||||
yesNoBoxCreate("Would you like to travel to " + destCityName + "? The trip will cost $" + formatNumber(cost, 2) + ".");
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Message.js */
|
||||
function Message(filename, msg) {
|
||||
function Message(filename="", msg="") {
|
||||
this.filename = filename;
|
||||
this.msg = msg;
|
||||
this.recvd = false;
|
||||
|
@ -334,7 +334,7 @@ function NetscriptFunctions(workerScript) {
|
||||
}
|
||||
var server = getServer(ip);
|
||||
if (server == null) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "Invalid hostname/ip passed into exec() command: " + args[1]);
|
||||
throw makeRuntimeRejectMsg(workerScript, "Invalid hostname/ip passed into exec() command: " + ip);
|
||||
}
|
||||
return runScriptFromScript(server, scriptname, argsForNewScript, workerScript, threads);
|
||||
},
|
||||
@ -691,7 +691,7 @@ function NetscriptFunctions(workerScript) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!server.purchasedByPlayer) {
|
||||
if (!server.purchasedByPlayer || server.hostname == "home") {
|
||||
workerScript.scriptRef.log("Error: Server " + server.hostname + " is not a purchased server. " +
|
||||
"Cannot be deleted. deleteServer failed");
|
||||
return false;
|
||||
@ -699,13 +699,17 @@ function NetscriptFunctions(workerScript) {
|
||||
|
||||
var ip = server.ip;
|
||||
|
||||
//Delete all scripts running on server
|
||||
for (var i = server.runningScripts.length-1; i >= 0; --i) {
|
||||
killWorkerScript(server.runningScripts[i], ip);
|
||||
//A server cannot delete itself
|
||||
if (ip == workerScript.serverIp) {
|
||||
workerScript.scriptRef.log("Error: Cannot call deleteServer() on self. Function failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
//Delete from all servers
|
||||
delete AllServers[ip];
|
||||
//Delete all scripts running on server
|
||||
if (server.runningScripts.length > 0) {
|
||||
workerScript.scriptRef.log("Error: Cannot delete server " + server.hostname + " because it still has scripts running.");
|
||||
return false;
|
||||
}
|
||||
|
||||
//Delete from player's purchasedServers array
|
||||
var found = false;
|
||||
@ -723,6 +727,9 @@ function NetscriptFunctions(workerScript) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//Delete from all servers
|
||||
delete AllServers[ip];
|
||||
|
||||
//Delete from home computer
|
||||
found = false;
|
||||
var homeComputer = Player.getHomeComputer();
|
||||
@ -745,7 +752,7 @@ function NetscriptFunctions(workerScript) {
|
||||
write : function(port, data="") {
|
||||
if (!isNaN(port)) {
|
||||
//Port 1-10
|
||||
if (port < 1 && port > 10) {
|
||||
if (port < 1 || port > 10) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "Trying to write to invalid port: " + port + ". Only ports 1-10 are valid.");
|
||||
}
|
||||
var portName = "Port" + String(port);
|
||||
@ -766,7 +773,7 @@ function NetscriptFunctions(workerScript) {
|
||||
read : function(port) {
|
||||
if (!isNaN(port)) {
|
||||
//Port 1-10
|
||||
if (port < 1 && port > 10) {
|
||||
if (port < 1 || port > 10) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "Trying to write to invalid port: " + port + ". Only ports 1-10 are valid.");
|
||||
}
|
||||
var portName = "Port" + String(port);
|
||||
@ -782,7 +789,48 @@ function NetscriptFunctions(workerScript) {
|
||||
} else {
|
||||
throw makeRuntimeRejectMsg(workerScript, "Invalid argument passed in for port: " + port + ". Must be a number between 1 and 10");
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
scriptRunning : function(scriptname, ip) {
|
||||
var server = getServer(ip);
|
||||
if (server == null) {
|
||||
workerScript.scriptRef.log("scriptRunning() failed. Invalid IP or hostname passed in: " + ip);
|
||||
throw makeRuntimeRejectMsg(workerScript, "scriptRunning() failed. Invalid IP or hostname passed in: " + ip);
|
||||
}
|
||||
for (var i = 0; i < server.runningScripts.length; ++i) {
|
||||
if (server.runningScripts[i].filename == scriptname) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
scriptKill : function(scriptname, ip) {
|
||||
var server = getServer(ip);
|
||||
if (server == null) {
|
||||
workerScript.scriptRef.log("scriptKill() failed. Invalid IP or hostname passed in: " + ip);
|
||||
throw makeRuntimeRejectMsg(workerScript, "scriptKill() failed. Invalid IP or hostname passed in: " + ip);
|
||||
}
|
||||
var suc = false;
|
||||
for (var i = 0; i < server.runningScripts.length; ++i) {
|
||||
if (server.runningScripts[i].filename == scriptname) {
|
||||
killWorkerScript(server.runningScripts[i], server.ip);
|
||||
suc = true;
|
||||
}
|
||||
}
|
||||
return suc;
|
||||
},
|
||||
getScriptRam : function (scriptname, ip) {
|
||||
var server = getServer(ip);
|
||||
if (server == null) {
|
||||
workerScript.scriptRef.log("getScriptRam() failed. Invalid IP or hostname passed in: " + ip);
|
||||
throw makeRuntimeRejectMsg(workerScript, "getScriptRam() failed. Invalid IP or hostname passed in: " + ip);
|
||||
}
|
||||
for (var i = 0; i < server.runningScripts.length; ++i) {
|
||||
if (server.runningScripts[i].filename == scriptname) {
|
||||
return server.runningScripts[i].scriptRef.ramUsage;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
},
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -109,6 +109,7 @@ function runScriptsLoop() {
|
||||
//Delete script from the runningScripts array on its host serverIp
|
||||
var ip = workerScripts[i].serverIp;
|
||||
var name = workerScripts[i].name;
|
||||
|
||||
for (var j = 0; j < AllServers[ip].runningScripts.length; j++) {
|
||||
if (AllServers[ip].runningScripts[j].filename == name &&
|
||||
compareArrays(AllServers[ip].runningScripts[j].args, workerScripts[i].args)) {
|
||||
|
@ -21,21 +21,6 @@ function PlayerObject() {
|
||||
this.hacking_money_mult = 1; //Increase through ascensions/augmentations. Can't go above 1
|
||||
this.hacking_grow_mult = 1;
|
||||
|
||||
//Note: "Lifetime" refers to current ascension, "total" refers to the entire game history
|
||||
//Accumulative stats and skills
|
||||
this.total_hacking = 1;
|
||||
this.total_strength = 1;
|
||||
this.total_defense = 1;
|
||||
this.total_dexterity = 1;
|
||||
this.total_agility = 1;
|
||||
this.total_charisma = 1;
|
||||
this.lifetime_hacking = 1;
|
||||
this.lifetime_strength = 1;
|
||||
this.lifetime_defense = 1;
|
||||
this.lifetime_dexterity = 1;
|
||||
this.lifetime_agility = 1;
|
||||
this.lifetime_charisma = 1;
|
||||
|
||||
//Experience and multipliers
|
||||
this.hacking_exp = 0;
|
||||
this.strength_exp = 0;
|
||||
@ -94,32 +79,16 @@ function PlayerObject() {
|
||||
|
||||
this.sourceFiles = [];
|
||||
|
||||
//Crime statistics (Total refers to this 'simulation'. Lifetime is forever)
|
||||
//Crime statistics
|
||||
this.karma = 0;
|
||||
this.numTimesShoplifted = 0;
|
||||
this.numTimesShopliftedTotal = 0;
|
||||
this.numTimesShopliftedLifetime = 0;
|
||||
this.numPeopleMugged = 0;
|
||||
this.numPeopleMuggedTotal = 0;
|
||||
this.numPeopleMuggedLifetime = 0;
|
||||
this.numTimesDealtDrugs = 0;
|
||||
this.numTimesDealtDrugsTotal = 0;
|
||||
this.numTimesDealtDrugsLifetime = 0;
|
||||
this.numTimesTraffickArms = 0;
|
||||
this.numTimesTraffickArmsTotal = 0;
|
||||
this.numTimesTraffickArmsLifetime = 0;
|
||||
this.numPeopleKilled = 0;
|
||||
this.numPeopleKilledTotal = 0;
|
||||
this.numPeopleKilledLifetime = 0;
|
||||
this.numTimesGrandTheftAuto = 0;
|
||||
this.numTimesGrandTheftAutoTotal = 0;
|
||||
this.numTimesGrandTheftAutoLifetime = 0;
|
||||
this.numTimesKidnapped = 0;
|
||||
this.numTimesKidnappedTotal = 0;
|
||||
this.numTimesKidnappedLifetime = 0;
|
||||
this.numTimesHeist = 0;
|
||||
this.numTimesHeistTotal = 0;
|
||||
this.numTimesHeistLifetime = 0;
|
||||
|
||||
this.crime_money_mult = 1;
|
||||
this.crime_success_mult = 1;
|
||||
@ -177,6 +146,12 @@ function PlayerObject() {
|
||||
this.hasWseAccount = false;
|
||||
this.hasTixApiAccess = false;
|
||||
|
||||
//Gang
|
||||
this.gang = null;
|
||||
|
||||
//bitnode
|
||||
this.bitNodeN = 1;
|
||||
|
||||
//Used to store the last update time.
|
||||
this.lastUpdate = 0;
|
||||
this.totalPlaytime = 0;
|
||||
@ -221,6 +196,41 @@ PlayerObject.prototype.updateSkillLevels = function() {
|
||||
Player.hp = Math.round(this.max_hp * ratio);
|
||||
}
|
||||
|
||||
PlayerObject.prototype.resetMultipliers = function() {
|
||||
this.hacking_chance_mult = 1;
|
||||
this.hacking_speed_mult = 1;
|
||||
this.hacking_money_mult = 1;
|
||||
this.hacking_grow_mult = 1;
|
||||
|
||||
this.hacking_mult = 1;
|
||||
this.strength_mult = 1;
|
||||
this.defense_mult = 1;
|
||||
this.dexterity_mult = 1;
|
||||
this.agility_mult = 1;
|
||||
this.charisma_mult = 1;
|
||||
|
||||
this.hacking_exp_mult = 1;
|
||||
this.strength_exp_mult = 1;
|
||||
this.defense_exp_mult = 1;
|
||||
this.dexterity_exp_mult = 1;
|
||||
this.agility_exp_mult = 1;
|
||||
this.charisma_exp_mult = 1;
|
||||
|
||||
this.company_rep_mult = 1;
|
||||
this.faction_rep_mult = 1;
|
||||
|
||||
this.crime_money_mult = 1;
|
||||
this.crime_success_mult = 1;
|
||||
|
||||
this.hacknet_node_money_mult = 1;
|
||||
this.hacknet_node_purchase_cost_mult = 1;
|
||||
this.hacknet_node_ram_cost_mult = 1;
|
||||
this.hacknet_node_core_cost_mult = 1;
|
||||
this.hacknet_node_level_cost_mult = 1;
|
||||
|
||||
this.work_money_mult = 1;
|
||||
}
|
||||
|
||||
//Calculates the chance of hacking a server
|
||||
//The formula is:
|
||||
// (2 * hacking_chance_multiplier * hacking_skill - requiredLevel) 100 - difficulty
|
||||
@ -650,6 +660,7 @@ PlayerObject.prototype.startFactionWork = function(faction) {
|
||||
var favorMult = 1 + (faction.favor / 100);
|
||||
if (isNaN(favorMult)) {favorMult = 1;}
|
||||
this.workRepGainRate *= favorMult;
|
||||
this.workRepGainRate *= BitNodeMultipliers.FactionWorkRepGain;
|
||||
|
||||
this.isWorking = true;
|
||||
this.workType = CONSTANTS.WorkTypeFaction;
|
||||
@ -736,6 +747,7 @@ PlayerObject.prototype.workForFaction = function(numCycles) {
|
||||
var favorMult = 1 + (faction.favor / 100);
|
||||
if (isNaN(favorMult)) {favorMult = 1;}
|
||||
this.workRepGainRate *= favorMult;
|
||||
this.workRepGainRate *= BitNodeMultipliers.FactionWorkRepGain;
|
||||
|
||||
this.workHackExpGained += this.workHackExpGainRate * numCycles;
|
||||
this.workStrExpGained += this.workStrExpGainRate * numCycles;
|
||||
@ -1093,7 +1105,7 @@ PlayerObject.prototype.startCrime = function(hackExp, strExp, defExp, dexExp, ag
|
||||
this.workDexExpGained = dexExp * this.dexterity_exp_mult;
|
||||
this.workAgiExpGained = agiExp * this.agility_exp_mult;
|
||||
this.workChaExpGained = chaExp * this.charisma_exp_mult;
|
||||
this.workMoneyGained = money * this.crime_money_mult;
|
||||
this.workMoneyGained = money * this.crime_money_mult * BitNodeMultipliers.CrimeMoney;
|
||||
|
||||
this.timeNeededToCompleteWork = time;
|
||||
|
||||
@ -1138,13 +1150,14 @@ PlayerObject.prototype.finishCrime = function(cancelled) {
|
||||
++this.numTimesShoplifted;
|
||||
break;
|
||||
case CONSTANTS.CrimeRobStore:
|
||||
|
||||
this.karma -= 0.5;
|
||||
break;
|
||||
case CONSTANTS.CrimeMug:
|
||||
this.karma -= 0.25;
|
||||
++this.numPeopleMugged;
|
||||
break;
|
||||
case CONSTANTS.CrimeLarceny:
|
||||
this.karma -= 1.5;
|
||||
break;
|
||||
case CONSTANTS.CrimeDrugs:
|
||||
++this.numTimesDealtDrugs;
|
||||
|
230
src/Prestige.js
230
src/Prestige.js
@ -2,44 +2,16 @@
|
||||
|
||||
//Prestige by purchasing augmentation
|
||||
function prestigeAugmentation() {
|
||||
//Sum up lifetime/total statistics
|
||||
Player.total_hacking += Player.hacking_skill;
|
||||
Player.lifetime_hacking += Player.hacking_skill;
|
||||
Player.total_strength += Player.strength;
|
||||
Player.lifetime_strength += Player.strength;
|
||||
Player.total_defense += Player.defense;
|
||||
Player.lifetime_defense += Player.defense;
|
||||
Player.total_dexterity += Player.dexterity;
|
||||
Player.lifetime_dexterity += Player.dexterity;
|
||||
Player.total_agility += Player.agility;
|
||||
Player.lifetime_agility += Player.agility;
|
||||
Player.total_charisma += Player.charisma;
|
||||
Player.lifetime_charisma += Player.charisma;
|
||||
initBitNodeMultipliers();
|
||||
|
||||
//Crime statistics
|
||||
Player.numTimesShopliftedTotal += Player.numTimesShoplifted;
|
||||
Player.numTimesShopliftedLifetime += Player.numTimesShoplifted;
|
||||
Player.numTimesShoplifted = 0;
|
||||
Player.numPeopleMuggedTotal += Player.numPeopleMugged;
|
||||
Player.numPeopleMuggedLifetime += Player.numPeopleMugged;
|
||||
Player.numPeopleMugged = 0;
|
||||
Player.numTimesDealtDrugsTotal += Player.numTimesDealtDrugs;
|
||||
Player.numTimesDealtDrugsLifetime += Player.numTimesDealtDrugs;
|
||||
Player.numTimesDealtDrugs = 0;
|
||||
Player.numTimesTraffickArmsTotal += Player.numTimesTraffickArms;
|
||||
Player.numTimesTraffickArmsLifetime += Player.numTimesTraffickArms;
|
||||
Player.numTimesTraffickArms = 0;
|
||||
Player.numPeopleKilledTotal += Player.numPeopleKilled;
|
||||
Player.numPeopleKilledLifetime += Player.numPeopleKilled;
|
||||
Player.numPeopleKilled = 0;
|
||||
Player.numTimesGrandTheftAutoTotal += Player.numTimesGrandTheftAuto;
|
||||
Player.numTimesGrandTheftAutoLifetime += Player.numTimesGrandTheftAuto;
|
||||
Player.numTimesGrandTheftAuto = 0;
|
||||
Player.numTimesKidnappedTotal += Player.numTimesKidnapped;
|
||||
Player.numTimesKidnappedLifetime += Player.numTimesKidnapped;
|
||||
Player.numTimesKidnapped = 0;
|
||||
Player.numTimesHeistTotal += Player.numTimesHeist;
|
||||
Player.numTimesHeistLifetime += Player.numTimesHeist;
|
||||
Player.numTimesHeist = 0;
|
||||
|
||||
Player.karma = 0;
|
||||
@ -190,7 +162,8 @@ function prestigeAugmentation() {
|
||||
|
||||
//Re-initialize things - This will update any changes
|
||||
initFactions(); //Factions must be initialized before augmentations
|
||||
initAugmentations();
|
||||
initAugmentations(); //Calls reapplyAllAugmentations() and resets Player multipliers
|
||||
Player.reapplyAllSourceFiles();
|
||||
initCompanies();
|
||||
|
||||
//Clear terminal
|
||||
@ -211,6 +184,14 @@ function prestigeAugmentation() {
|
||||
}
|
||||
}
|
||||
|
||||
//Gang, in BitNode 2
|
||||
if (Player.bitNodeN == 2 && Player.inGang()) {
|
||||
var faction = Factions[Player.gang.facName];
|
||||
if (faction instanceof Faction) {
|
||||
joinFaction(faction);
|
||||
}
|
||||
}
|
||||
|
||||
Player.playtimeSinceLastAug = 0;
|
||||
|
||||
var mainMenu = document.getElementById("mainmenu-container");
|
||||
@ -228,3 +209,192 @@ function prestigeAugmentation() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//Prestige by destroying Bit Node and gaining a Source File
|
||||
function prestigeSourceFile() {
|
||||
initBitNodeMultipliers();
|
||||
|
||||
//Crime statistics
|
||||
Player.numTimesShoplifted = 0;
|
||||
Player.numPeopleMugged = 0;
|
||||
Player.numTimesDealtDrugs = 0;
|
||||
Player.numTimesTraffickArms = 0;
|
||||
Player.numPeopleKilled = 0;
|
||||
Player.numTimesGrandTheftAuto = 0;
|
||||
Player.numTimesKidnapped = 0;
|
||||
Player.numTimesHeist = 0;
|
||||
|
||||
Player.karma = 0;
|
||||
|
||||
//Reset stats
|
||||
Player.hacking_skill = 1;
|
||||
|
||||
Player.strength = 1;
|
||||
Player.defense = 1;
|
||||
Player.dexterity = 1;
|
||||
Player.agility = 1;
|
||||
|
||||
Player.charisma = 1;
|
||||
|
||||
Player.hacking_exp = 0;
|
||||
Player.strength_exp = 0;
|
||||
Player.defense_exp = 0;
|
||||
Player.dexterity_exp = 0;
|
||||
Player.agility_exp = 0;
|
||||
Player.charisma_exp = 0;
|
||||
|
||||
Player.money = new Decimal(1000);
|
||||
|
||||
Player.city = Locations.Sector12;
|
||||
Player.location = "";
|
||||
|
||||
Player.companyName = "";
|
||||
Player.companyPosition = "";
|
||||
|
||||
Player.currentServer = "";
|
||||
Player.discoveredServers = [];
|
||||
Player.purchasedServers = [];
|
||||
|
||||
Player.factions = [];
|
||||
Player.factionInvitations = [];
|
||||
|
||||
Player.queuedAugmentations = [];
|
||||
Player.augmentations = [];
|
||||
|
||||
Player.startAction = false;
|
||||
Player.actionTime = 0;
|
||||
|
||||
Player.isWorking = false;
|
||||
Player.currentWorkFactionName = "";
|
||||
Player.currentWorkFactionDescription = "";
|
||||
this.createProgramName = "";
|
||||
this.className = "";
|
||||
this.crimeType = "";
|
||||
|
||||
Player.workHackExpGainRate = 0;
|
||||
Player.workStrExpGainRate = 0;
|
||||
Player.workDefExpGainRate = 0;
|
||||
Player.workDexExpGainRate = 0;
|
||||
Player.workAgiExpGainRate = 0;
|
||||
Player.workChaExpGainRate = 0;
|
||||
Player.workRepGainRate = 0;
|
||||
Player.workMoneyGainRate = 0;
|
||||
|
||||
Player.workHackExpGained = 0;
|
||||
Player.workStrExpGained = 0;
|
||||
Player.workDefExpGained = 0;
|
||||
Player.workDexExpGained = 0;
|
||||
Player.workAgiExpGained = 0;
|
||||
Player.workChaExpGained = 0;
|
||||
Player.workRepGained = 0;
|
||||
Player.workMoneyGained = 0;
|
||||
|
||||
Player.timeWorked = 0;
|
||||
|
||||
Player.lastUpdate = new Date().getTime();
|
||||
|
||||
//Delete all Worker Scripts objects
|
||||
for (var i = 0; i < workerScripts.length; ++i) {
|
||||
deleteActiveScriptsItem(workerScripts[i]);
|
||||
workerScripts[i].env.stopFlag = true;
|
||||
}
|
||||
workerScripts.length = 0;
|
||||
|
||||
var homeComp = Player.getHomeComputer();
|
||||
//Delete all servers except home computer
|
||||
for (var member in AllServers) {
|
||||
delete AllServers[member];
|
||||
}
|
||||
AllServers = {};
|
||||
//Delete Special Server IPs
|
||||
for (var member in SpecialServerIps) {
|
||||
delete SpecialServerIps[member];
|
||||
}
|
||||
SpecialServersIps = null;
|
||||
|
||||
//Reset home computer (only the programs) and add to AllServers
|
||||
homeComp.programs.length = 0;
|
||||
homeComp.runningScripts = [];
|
||||
homeComp.serversOnNetwork = [];
|
||||
homeComp.isConnectedTo = true;
|
||||
homeComp.ramUsed = 0;
|
||||
homeComp.programs.push(Programs.NukeProgram);
|
||||
var srcFile1Owned = false;
|
||||
for (var i = 0; i < Player.sourceFiles.length; ++i) {
|
||||
if (Player.sourceFiles[i].n == 1) {
|
||||
srcFile1Owned = true;
|
||||
}
|
||||
}
|
||||
if (srcFile1Owned) {
|
||||
homeComp.maxRam = 32;
|
||||
} else {
|
||||
homeComp.maxRam = 8;
|
||||
}
|
||||
Player.currentServer = homeComp.ip;
|
||||
Player.homeComputer = homeComp.ip;
|
||||
AddToAllServers(homeComp);
|
||||
|
||||
//Re-create foreign servers
|
||||
SpecialServerIps = new SpecialServerIpsMap(); //Must be done before initForeignServers()
|
||||
initForeignServers();
|
||||
|
||||
//Darkweb is purchase-able
|
||||
document.getElementById("location-purchase-tor").setAttribute("class", "a-link-button");
|
||||
|
||||
//Reset statistics of all scripts on home computer
|
||||
for (var i = 0; i < homeComp.scripts.length; ++i) {
|
||||
var s = homeComp.scripts[i];
|
||||
}
|
||||
//Delete messages on home computer
|
||||
homeComp.messages.length = 0;
|
||||
|
||||
//Delete Hacknet Nodes
|
||||
Player.hacknetNodes.length = 0;
|
||||
Player.totalHacknetNodeProduction = 0;
|
||||
|
||||
//Reset favor for Companies
|
||||
for (var member in Companies) {
|
||||
if (Companies.hasOwnProperty(member)) {
|
||||
Companies[member].favor = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//Reset favor for factions
|
||||
for (var member in Factions) {
|
||||
if (Factions.hasOwnProperty(member)) {
|
||||
Factions[member].favor = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//Stop a Terminal action if there is one
|
||||
if (Engine._actionInProgress) {
|
||||
Engine._actionInProgress = false;
|
||||
Terminal.finishAction(true);
|
||||
}
|
||||
|
||||
//Re-initialize things - This will update any changes
|
||||
initFactions(); //Factions must be initialized before augmentations
|
||||
initAugmentations(); //Calls reapplyAllAugmentations() and resets Player multipliers
|
||||
Player.reapplyAllSourceFiles();
|
||||
initCompanies();
|
||||
|
||||
//Clear terminal
|
||||
$("#terminal tr:not(:last)").remove();
|
||||
postNetburnerText();
|
||||
|
||||
//Messages
|
||||
initMessages();
|
||||
|
||||
//Gang
|
||||
Player.gang = null;
|
||||
|
||||
//Reset Stock market
|
||||
Player.hasWseAccount = false;
|
||||
|
||||
Player.playtimeSinceLastAug = 0;
|
||||
|
||||
var mainMenu = document.getElementById("mainmenu-container");
|
||||
mainMenu.style.visibility = "visible";
|
||||
Engine.loadTerminalContent();
|
||||
}
|
||||
|
147
src/RedPill.js
147
src/RedPill.js
@ -1,14 +1,14 @@
|
||||
/* RedPill.js
|
||||
/* RedPill.js
|
||||
* Implements what happens when you have Red Pill augmentation and then hack the world daemon */
|
||||
|
||||
|
||||
//Returns promise
|
||||
function writeRedPillLine(line) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
|
||||
|
||||
var container = document.getElementById("red-pill-container");
|
||||
var pElem = document.createElement("p");
|
||||
container.appendChild(pElem);
|
||||
|
||||
|
||||
var promise = writeRedPillLetter(pElem, line, 0);
|
||||
promise.then(function(res) {
|
||||
resolve(res);
|
||||
@ -39,7 +39,7 @@ function writeRedPillLetter(pElem, line, i=0) {
|
||||
}
|
||||
|
||||
redPillFlag = false;
|
||||
function hackWorldDaemon(currentNode="BitNode-1") {
|
||||
function hackWorldDaemon(currentNodeNumber) {
|
||||
redPillFlag = true;
|
||||
Engine.loadRedPillContent();
|
||||
return writeRedPillLine("[ERROR] SEMPOOL INVALID").then(function() {
|
||||
@ -59,7 +59,7 @@ function hackWorldDaemon(currentNode="BitNode-1") {
|
||||
}).then(function() {
|
||||
return writeRedPillLine("Failsafe initiated...");
|
||||
}).then(function() {
|
||||
return writeRedPillLine("Restarting " + currentNode + "...");
|
||||
return writeRedPillLine("Restarting BitNode-" + currentNodeNumber + "...");
|
||||
}).then(function() {
|
||||
return writeRedPillLine("...........");
|
||||
}).then(function() {
|
||||
@ -71,27 +71,65 @@ function hackWorldDaemon(currentNode="BitNode-1") {
|
||||
}).then(function() {
|
||||
return writeRedPillLine("..............................................")
|
||||
}).then(function() {
|
||||
return loadBitVerse();
|
||||
return loadBitVerse(currentNodeNumber);
|
||||
}).catch(function(e){
|
||||
console.log("ERROR: " + e.toString());
|
||||
});
|
||||
}
|
||||
|
||||
function loadBitVerse() {
|
||||
//The bitNode name passed in will have a hyphen between number (e.g. BitNode-1)
|
||||
//This needs to be removed
|
||||
function giveSourceFile(bitNodeNumber) {
|
||||
var sourceFileKey = "SourceFile"+ bitNodeNumber.toString();
|
||||
var sourceFile = SourceFiles[sourceFileKey];
|
||||
if (sourceFile == null) {
|
||||
console.log("ERROR: could not find source file for Bit node: " + bitNodeNumber);
|
||||
return;
|
||||
}
|
||||
|
||||
//Check if player already has this source file
|
||||
var alreadyOwned = false;
|
||||
var ownedSourceFile = null;
|
||||
for (var i = 0; i < Player.sourceFiles; ++i) {
|
||||
if (Player.sourceFiles[i].n == bitNodeNumber) {
|
||||
alreadyOwned = true;
|
||||
ownedSourceFile = Player.sourceFiles[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (alreadyOwned && ownedSourceFile) {
|
||||
if (ownedSourceFile.lvl >= 3) {
|
||||
dialogBoxCreate("The Source-File for the BitNode you just destroyed, " + sourceFile.name + ", " +
|
||||
"is already at max level!");
|
||||
} else {
|
||||
++ownedSourceFile.lvl;
|
||||
dialogBoxCreate(sourceFile.name + " was upgraded to level " + ownedSourceFile.lvl + " for " +
|
||||
"destroying its corresponding BitNode!");
|
||||
}
|
||||
} else {
|
||||
var playerSrcFile = new PlayerOwnedSourceFile(bitNodeNumber, 1);
|
||||
Player.sourceFiles.push(playerSrcFile);
|
||||
dialogBoxCreate("You received a Source-File for destroying a Bit Node!<br><br>" +
|
||||
sourceFile.name + "<br><br>" + sourceFile.info);
|
||||
}
|
||||
}
|
||||
|
||||
function loadBitVerse(destroyedBitNodeNum) {
|
||||
//Clear the screen
|
||||
var container = document.getElementById("red-pill-container");
|
||||
while (container.firstChild) {
|
||||
container.removeChild(container.firstChild);
|
||||
}
|
||||
|
||||
|
||||
//Create the Bit Verse
|
||||
var bitVerseImage = document.createElement("pre");
|
||||
var bitNodes = [];
|
||||
for (var i = 1; i <= 12; ++i) {
|
||||
bitNodes.push(createBitNode(i));
|
||||
}
|
||||
|
||||
bitVerseImage.innerHTML =
|
||||
|
||||
bitVerseImage.innerHTML =
|
||||
" O <br>" +
|
||||
" | O O | O O | <br>" +
|
||||
" O | | / __| \\ | | O <br>" +
|
||||
@ -116,9 +154,9 @@ function loadBitVerse() {
|
||||
" \\ \\| / \\ / \\ |/ / <br>" +
|
||||
" "+bitNodes[0]+" |/ "+bitNodes[1]+" | | "+bitNodes[2]+" \\| "+bitNodes[3]+" <br>" +
|
||||
" | | | | | | | | <br>" +
|
||||
" \\JUMP3R|JUMP|3R| |R3|PMUJ|R3PMUJ/ <br><br><br><br>";
|
||||
|
||||
|
||||
" \\JUMP3R|JUMP|3R| |R3|PMUJ|R3PMUJ/ <br><br><br><br>";
|
||||
|
||||
|
||||
/*
|
||||
" O <br>" +
|
||||
" | O O | O O | <br>" +
|
||||
@ -144,47 +182,37 @@ function loadBitVerse() {
|
||||
" \ \| / \ / \ |/ / <br>" +
|
||||
" O |/ O | | O \| O <br>" +
|
||||
" | | | | | | | | <br>" +
|
||||
" \JUMP3R|JUMP|3R| |R3|PMUJ|R3PMUJ/ <br>";
|
||||
" \JUMP3R|JUMP|3R| |R3|PMUJ|R3PMUJ/ <br>";
|
||||
*/
|
||||
|
||||
|
||||
container.appendChild(bitVerseImage);
|
||||
|
||||
|
||||
//Bit node event listeners
|
||||
for (var i = 1; i <= 12; ++i) {
|
||||
(function() {
|
||||
(function(i) {
|
||||
var elemId = "bitnode-" + i.toString();
|
||||
var elem = clearEventListeners(elemId);
|
||||
if (elem == null) {return;}
|
||||
if (i == 1) {
|
||||
if (i == 1 || i == 2) {
|
||||
elem.addEventListener("click", function() {
|
||||
prestigeAugmentation();
|
||||
dialogBoxCreate("Congrats! You've reached the current end of the game. Eventually the " +
|
||||
"BitNode/Bitverse will be fully implemented with cool new features, so check " +
|
||||
"it out again in the future! You have now been returned " +
|
||||
"to the original BitNode (BitNode-1) and you can continue playing if you wish. ");
|
||||
redPillFlag = false;
|
||||
var container = document.getElementById("red-pill-container");
|
||||
while (container.firstChild) {
|
||||
container.removeChild(container.firstChild);
|
||||
var bitNodeKey = "BitNode" + i;
|
||||
var bitNode = BitNodes[bitNodeKey];
|
||||
if (bitNode == null) {
|
||||
console.log("ERROR: Could not find BitNode object for number: " + i);
|
||||
return;
|
||||
}
|
||||
|
||||
//Reenable terminal
|
||||
$("#hack-progress-bar").attr('id', "old-hack-progress-bar");
|
||||
$("#hack-progress").attr('id', "old-hack-progress");
|
||||
document.getElementById("terminal-input-td").innerHTML = '$ <input type="text" id="terminal-input-text-box" class="terminal-input" tabindex="1"/>';
|
||||
$('input[class=terminal-input]').prop('disabled', false);
|
||||
|
||||
Terminal.hackFlag = false;
|
||||
yesNoBoxCreate("BitNode-" + i + ": " + bitNode.name + "<br><br>" + bitNode.info);
|
||||
createBitNodeYesNoEventListeners(i, destroyedBitNodeNum);
|
||||
});
|
||||
} else {
|
||||
elem.addEventListener("click", function() {
|
||||
dialogBoxCreate("Not yet implemented! Coming soon!")
|
||||
});
|
||||
}
|
||||
}()); //Immediate invocation closure
|
||||
}(i)); //Immediate invocation closure
|
||||
}
|
||||
|
||||
//Create lore text
|
||||
|
||||
//Create lore text
|
||||
return writeRedPillLine("Many decades ago, a humanoid extraterrestial species which we call the Enders descended on the Earth...violently").then(function() {
|
||||
return writeRedPillLine("Our species fought back, but it was futile. The Enders had technology far beyond our own...");
|
||||
}).then(function() {
|
||||
@ -234,10 +262,43 @@ function createBitNode(n) {
|
||||
var bitNodeStr = "BitNode" + n.toString();
|
||||
var bitNode = BitNodes[bitNodeStr];
|
||||
if (bitNode == null) {return "O";}
|
||||
return "<a class='bitnode tooltip' id='bitnode-" + bitNode.number.toString() + "'><strong>O</strong>" +
|
||||
"<span class='tooltiptext'>" +
|
||||
"<strong>BitNode-" + bitNode.number.toString() + "<br>" + bitNode.name+ "</strong><br>" +
|
||||
bitNode.desc + "<br>" +
|
||||
return "<a class='bitnode tooltip' id='bitnode-" + bitNode.number.toString() + "'><strong>O</strong>" +
|
||||
"<span class='tooltiptext'>" +
|
||||
"<strong>BitNode-" + bitNode.number.toString() + "<br>" + bitNode.name+ "</strong><br>" +
|
||||
bitNode.desc + "<br>" +
|
||||
"</span></a>";
|
||||
}
|
||||
|
||||
function createBitNodeYesNoEventListeners(newBitNode, destroyedBitNode) {
|
||||
var yesBtn = yesNoBoxGetYesButton();
|
||||
yesBtn.innerHTML = "Enter BitNode-" + newBitNode;
|
||||
yesBtn.addEventListener("click", function() {
|
||||
giveSourceFile(destroyedBitNode);
|
||||
redPillFlag = false;
|
||||
var container = document.getElementById("red-pill-container");
|
||||
while (container.firstChild) {
|
||||
container.removeChild(container.firstChild);
|
||||
}
|
||||
|
||||
//Set new Bit Node
|
||||
Player.bitNodeN = newBitNode;
|
||||
|
||||
//Reenable terminal
|
||||
$("#hack-progress-bar").attr('id', "old-hack-progress-bar");
|
||||
$("#hack-progress").attr('id', "old-hack-progress");
|
||||
document.getElementById("terminal-input-td").innerHTML = '$ <input type="text" id="terminal-input-text-box" class="terminal-input" tabindex="1"/>';
|
||||
$('input[class=terminal-input]').prop('disabled', false);
|
||||
|
||||
Terminal.hackFlag = false;
|
||||
|
||||
prestigeSourceFile();
|
||||
yesNoBoxClose();
|
||||
//TODO Dialog box for going ot new Bit node
|
||||
});
|
||||
var noBtn = yesNoBoxGetNoButton();
|
||||
noBtn.innerHTML = "Back";
|
||||
noBtn.addEventListener("click", function() {
|
||||
yesNoBoxClose();
|
||||
});
|
||||
|
||||
}
|
||||
|
@ -43,6 +43,9 @@ BitburnerSaveObject.prototype.saveGame = function() {
|
||||
this.StockMarketSave = JSON.stringify(StockMarket);
|
||||
this.SettingsSave = JSON.stringify(Settings);
|
||||
this.VersionSave = JSON.stringify(CONSTANTS.Version);
|
||||
if (Player.bitNodeN == 2 && Player.inGang()) {
|
||||
this.AllGangsSave = JSON.stringify(AllGangs);
|
||||
}
|
||||
var saveString = btoa(unescape(encodeURIComponent(JSON.stringify(this))));
|
||||
window.localStorage.setItem("bitburnerSave", saveString);
|
||||
|
||||
@ -118,6 +121,14 @@ loadGame = function(saveObj) {
|
||||
if (saveObj.hasOwnProperty("VersionSave")) {
|
||||
try {
|
||||
var ver = JSON.parse(saveObj.VersionSave, Reviver);
|
||||
if (ver == "0.27.0") {
|
||||
if (Player.bitNodeN == null || Player.bitNodeN == 0) {
|
||||
Player.bitNodeN = 1;
|
||||
}
|
||||
if (Player.sourceFiles == null) {
|
||||
Player.sourceFiles = [];
|
||||
}
|
||||
}
|
||||
if (ver != CONSTANTS.Version) {
|
||||
createNewUpdateText();
|
||||
}
|
||||
@ -127,6 +138,13 @@ loadGame = function(saveObj) {
|
||||
} else {
|
||||
createNewUpdateText();
|
||||
}
|
||||
if (Player.bitNodeN == 2 && Player.inGang() && saveObj.hasOwnProperty("AllGangsSave")) {
|
||||
try {
|
||||
AllGangs = JSON.parse(saveObj.AllGangsSave, Reviver);
|
||||
} catch(e) {
|
||||
console.log("ERROR: Failed to parse AllGangsSave: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -199,10 +217,13 @@ loadImportedGame = function(saveObj, saveString) {
|
||||
if (tempSaveObj.hasOwnProperty("VersionSave")) {
|
||||
try {
|
||||
var ver = JSON.parse(tempSaveObj.VersionSave, Reviver);
|
||||
if (CONSTANTS.Version == "0.26.3") {
|
||||
tempPlayer.money = new Decimal(tempPlayer.money);
|
||||
tempPlayer.total_money = new Decimal(tempPlayer.total_money);
|
||||
tempPlayer.lifetime_money = new Decimal(tempPlayer.lifetime_money);
|
||||
if (ver == "0.27.0") {
|
||||
if (tempPlayer.bitNodeN == null || tempPlayer.bitNodeN == 0) {
|
||||
tempPlayer.bitNodeN = 1;
|
||||
}
|
||||
if (tempPlayer.sourceFiles == null) {
|
||||
tempPlayer.sourceFiles = [];
|
||||
}
|
||||
}
|
||||
if (ver != CONSTANTS.Version) {
|
||||
createNewUpdateText();
|
||||
@ -213,6 +234,13 @@ loadImportedGame = function(saveObj, saveString) {
|
||||
} else {
|
||||
createNewUpdateText();
|
||||
}
|
||||
if (tempPlayer.bitNodeN == 2 && tempPlayer.inGang() && saveObj.hasOwnProperty("AllGangsSave")) {
|
||||
try {
|
||||
AllGangs = JSON.parse(saveObj.AllGangsSave, Reviver);
|
||||
} catch(e) {
|
||||
console.log("ERROR: Failed to parse AllGangsSave: " + e);
|
||||
}
|
||||
}
|
||||
} catch(e) {
|
||||
dialogBoxCreate("Error importing game");
|
||||
return false;
|
||||
@ -241,7 +269,8 @@ loadImportedGame = function(saveObj, saveString) {
|
||||
StockMarket = tempStockMarket;
|
||||
}
|
||||
|
||||
dialogBoxCreate("Imported game");
|
||||
dialogBoxCreate("Imported game! I would suggest saving the game and then reloading the page " +
|
||||
"to make sure everything runs smoothly");
|
||||
gameOptionsBoxClose();
|
||||
|
||||
//Re-start game
|
||||
|
@ -164,6 +164,7 @@ function calculateRamUsage(codeCopy) {
|
||||
var sqlinjectCount = numOccurrences(codeCopy, "sqlinject(");
|
||||
var runCount = numOccurrences(codeCopy, "run(");
|
||||
var execCount = numOccurrences(codeCopy, "exec(");
|
||||
var killCount = numOccurrences(codeCopy, "kill(") + numOccurrences(codeCopy, "killall(");
|
||||
var scpCount = numOccurrences(codeCopy, "scp(");
|
||||
var hasRootAccessCount = numOccurrences(codeCopy, "hasRootAccess(");
|
||||
var getHostnameCount = numOccurrences(codeCopy, "getHostname(");
|
||||
@ -187,11 +188,14 @@ function calculateRamUsage(codeCopy) {
|
||||
numOccurrences(codeCopy, "getStockPosition(");
|
||||
var scriptBuySellStockCount = numOccurrences(codeCopy, "buyStock(") +
|
||||
numOccurrences(codeCopy, "sellStock(");
|
||||
var scriptPurchaseServerCount = numOccurrences(codeCopy, "purchaseServer(") +
|
||||
var scriptPurchaseServerCount = numOccurrences(codeCopy, "purchaseServer(") +
|
||||
numOccurrences(codeCopy, "deleteServer(");
|
||||
var scriptRoundCount = numOccurrences(codeCopy, "round(");
|
||||
var scriptWriteCount = numOccurrences(codeCopy, "write(");
|
||||
var scriptReadCount = numOccurrences(codeCopy, "read(");
|
||||
var arbScriptCount = numOccurrences(codeCopy, "scriptRunning(") +
|
||||
numOccurrences(codeCopy, "scriptKill(");
|
||||
var getScriptCount = numOccurrences(codeCopy, "getScriptRam(");
|
||||
|
||||
return baseRam +
|
||||
((whileCount * CONSTANTS.ScriptWhileRamCost) +
|
||||
@ -209,6 +213,7 @@ function calculateRamUsage(codeCopy) {
|
||||
(sqlinjectCount * CONSTANTS.ScriptSqlinjectRamCost) +
|
||||
(runCount * CONSTANTS.ScriptRunRamCost) +
|
||||
(execCount * CONSTANTS.ScriptExecRamCost) +
|
||||
(killCount * CONSTANTS.ScriptKillRamCost) +
|
||||
(scpCount * CONSTANTS.ScriptScpRamCost) +
|
||||
(hasRootAccessCount * CONSTANTS.ScriptHasRootAccessRamCost) +
|
||||
(getHostnameCount * CONSTANTS.ScriptGetHostnameRamCost) +
|
||||
@ -233,7 +238,9 @@ function calculateRamUsage(codeCopy) {
|
||||
(scriptPurchaseServerCount * CONSTANTS.ScriptPurchaseServerRamCost) +
|
||||
(scriptRoundCount * CONSTANTS.ScriptRoundRamCost) +
|
||||
(scriptWriteCount * CONSTANTS.ScriptReadWriteRamCost) +
|
||||
(scriptReadCount * CONSTANTS.ScriptReadWriteRamCost));
|
||||
(scriptReadCount * CONSTANTS.ScriptReadWriteRamCost) +
|
||||
(arbScriptCount * CONSTANTS.ScriptArbScriptRamCost) +
|
||||
(getScriptCount * CONSTANTS.ScriptGetScriptCost));
|
||||
}
|
||||
|
||||
Script.prototype.toJSON = function() {
|
||||
|
@ -32,7 +32,6 @@ function Server(ip=createRandomIp(), hostname="", organizationName="",
|
||||
this.messages = [];
|
||||
|
||||
/* Hacking information (only valid for "foreign" aka non-purchased servers) */
|
||||
|
||||
//Skill required to attempt a hack. Whether a hack is successful will be determined
|
||||
//by a separate formula
|
||||
this.requiredHackingSkill = 1;
|
||||
@ -70,7 +69,7 @@ Server.prototype.setHackingParameters = function(requiredHackingSkill, moneyAvai
|
||||
} else {
|
||||
this.moneyAvailable = moneyAvailable;
|
||||
}
|
||||
this.moneyMax = 25 * moneyAvailable;
|
||||
this.moneyMax = 25 * moneyAvailable * BitNodeMultipliers.ServerMaxMoney;
|
||||
this.hackDifficulty = hackDifficulty;
|
||||
this.baseDifficulty = hackDifficulty;
|
||||
this.minDifficulty = Math.max(1, Math.round(hackDifficulty / 3));
|
||||
|
122
src/SourceFile.js
Normal file
122
src/SourceFile.js
Normal file
@ -0,0 +1,122 @@
|
||||
/* SourceFile.js */
|
||||
|
||||
//Each SourceFile corresponds to a BitNode with the same number
|
||||
function SourceFile(number, info="") {
|
||||
var bitnodeKey = "BitNode" + number;
|
||||
var bitnode = BitNodes[bitnodeKey];
|
||||
if (bitnode == null) {
|
||||
throw new Error("Invalid Bit Node for this Source File");
|
||||
}
|
||||
|
||||
this.n = number;
|
||||
this.name = "Source-File " + number + ": " + bitnode.name;
|
||||
this.lvl = 1;
|
||||
this.info = info;
|
||||
this.owned = false;
|
||||
}
|
||||
|
||||
SourceFiles = {
|
||||
SourceFile1: new SourceFile(1, "This Source-File lets the player start with 32GB of RAM on his/her " +
|
||||
"home computer. It also increases all of the player's multipliers by:<br><br>" +
|
||||
"Level 1: 16%<br>" +
|
||||
"Level 2: 24%<br>" +
|
||||
"Level 3: 28%"),
|
||||
SourceFile2: new SourceFile(2, "This Source-File increases the player's crime success rate, crime money, and charisma " +
|
||||
"multipliers by:<br><br>" +
|
||||
"Level 1: 20%<br>" +
|
||||
"Level 2: 30%<br>" +
|
||||
"Level 3: 35%"),
|
||||
SourceFile3: new SourceFile(3),
|
||||
SourceFile4: new SourceFile(4),
|
||||
SourceFile5: new SourceFile(5),
|
||||
SourceFile6: new SourceFile(6),
|
||||
SourceFile7: new SourceFile(7),
|
||||
SourceFile8: new SourceFile(8),
|
||||
SourceFile9: new SourceFile(9),
|
||||
SourceFile10: new SourceFile(10),
|
||||
SourceFile11: new SourceFile(11),
|
||||
SourceFile12: new SourceFile(12),
|
||||
}
|
||||
|
||||
function PlayerOwnedSourceFile(number, level) {
|
||||
this.n = number;
|
||||
this.lvl = level;
|
||||
}
|
||||
|
||||
//Takes in a PlayerOwnedSourceFile as the "srcFile" argument
|
||||
function applySourceFile(srcFile) {
|
||||
var srcFileKey = "SourceFile" + srcFile.n;
|
||||
var sourceFileObject = SourceFiles[srcFileKey];
|
||||
if (sourceFileObject == null) {
|
||||
console.log("ERROR: Invalid source file number: " + srcFile.n);
|
||||
return;
|
||||
}
|
||||
|
||||
switch(srcFile.n) {
|
||||
case 1: // The Source Genesis
|
||||
var mult = 0;
|
||||
for (var i = 0; i < srcFile.lvl; ++i) {
|
||||
mult += (16 / (Math.pow(2, i)));
|
||||
}
|
||||
var incMult = 1 + (mult / 100);
|
||||
var decMult = 1 - (mult / 100);
|
||||
Player.hacking_chance_mult *= incMult;
|
||||
Player.hacking_speed_mult *= incMult;
|
||||
Player.hacking_money_mult *= incMult;
|
||||
Player.hacking_grow_mult *= incMult;
|
||||
Player.hacking_mult *= incMult;
|
||||
Player.strength_mult *= incMult;
|
||||
Player.defense_mult *= incMult;
|
||||
Player.dexterity_mult *= incMult;
|
||||
Player.agility_mult *= incMult;
|
||||
Player.charisma_mult *= incMult;
|
||||
Player.hacking_exp_mult *= incMult;
|
||||
Player.strength_exp_mult *= incMult;
|
||||
Player.defense_exp_mult *= incMult;
|
||||
Player.dexterity_exp_mult *= incMult;
|
||||
Player.agility_exp_mult *= incMult;
|
||||
Player.charisma_exp_mult *= incMult;
|
||||
Player.company_rep_mult *= incMult;
|
||||
Player.faction_rep_mult *= incMult;
|
||||
Player.crime_money_mult *= incMult;
|
||||
Player.crime_success_mult *= incMult;
|
||||
Player.hacknet_node_money_mult *= incMult;
|
||||
Player.hacknet_node_purchase_cost_mult *= decMult;
|
||||
Player.hacknet_node_ram_cost_mult *= decMult;
|
||||
Player.hacknet_node_core_cost_mult *= decMult;
|
||||
Player.hacknet_node_level_cost_mult *= decMult;
|
||||
Player.work_money_mult *= incMult;
|
||||
break;
|
||||
case 2: //Rise of the Underworld
|
||||
var mult = 0;
|
||||
for (var i = 0; i < srcFile.lvl; ++i) {
|
||||
mult += (20 / (Math.pow(2, i)));
|
||||
}
|
||||
var incMult = 1 + (mult / 100);
|
||||
Player.crime_money_mult *= incMult;
|
||||
Player.crime_success_mult *= incMult;
|
||||
Player.charisma_mult *= incMult;
|
||||
break;
|
||||
default:
|
||||
console.log("ERROR: Invalid source file number: " + srcFile.n);
|
||||
break;
|
||||
}
|
||||
|
||||
sourceFileObject.owned = true;
|
||||
}
|
||||
|
||||
PlayerObject.prototype.reapplyAllSourceFiles = function() {
|
||||
console.log("Re-applying source files");
|
||||
//Will always be called after reapplyAllAugmentations() so multipliers do not have to be reset
|
||||
//this.resetMultipliers();
|
||||
|
||||
for (i = 0; i < this.sourceFiles.length; ++i) {
|
||||
var srcFileKey = "SourceFile" + this.sourceFiles[i].n;
|
||||
var sourceFileObject = SourceFiles[srcFileKey];
|
||||
if (sourceFileObject == null) {
|
||||
console.log("ERROR: Invalid source file number: " + this.sourceFiles[i].n);
|
||||
continue;
|
||||
}
|
||||
applySourceFile(this.sourceFiles[i]);
|
||||
}
|
||||
}
|
@ -360,7 +360,10 @@ var Terminal = {
|
||||
if (rand < hackChance) { //Success!
|
||||
if (SpecialServerIps[SpecialServerNames.WorldDaemon] &&
|
||||
SpecialServerIps[SpecialServerNames.WorldDaemon] == server.ip) {
|
||||
hackWorldDaemon();
|
||||
if (Player.bitNodeN == null) {
|
||||
Player.bitNodeN = 1;
|
||||
}
|
||||
hackWorldDaemon(Player.bitNodeN);
|
||||
return;
|
||||
}
|
||||
server.manuallyHacked = true;
|
||||
|
@ -148,6 +148,7 @@ var Engine = {
|
||||
RedPill: "RedPill",
|
||||
Infiltration: "Infiltration",
|
||||
StockMarket: "StockMarket",
|
||||
Gang: "Gang",
|
||||
},
|
||||
currentPage: null,
|
||||
|
||||
@ -321,6 +322,18 @@ var Engine = {
|
||||
Engine.currentPage = Engine.Page.StockMarket;
|
||||
},
|
||||
|
||||
loadGangContent: function() {
|
||||
Engine.hideAllContent();
|
||||
if (document.getElementById("gang-container") || Player.gang) {
|
||||
displayGangContent();
|
||||
Engine.currentPage = Engine.Page.Gang;
|
||||
} else {
|
||||
Engine.loadTerminalContent();
|
||||
Engine.currentPage = Engine.Page.Terminal;
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
//Helper function that hides all content
|
||||
hideAllContent: function() {
|
||||
Engine.Display.terminalContent.style.visibility = "hidden";
|
||||
@ -340,6 +353,9 @@ var Engine = {
|
||||
Engine.Display.redPillContent.style.visibility = "hidden";
|
||||
Engine.Display.infiltrationContent.style.visibility = "hidden";
|
||||
Engine.Display.stockMarketContent.style.visibility = "hidden";
|
||||
if (document.getElementById("gang-container")) {
|
||||
document.getElementById("gang-container").style.visibility = "hidden";
|
||||
}
|
||||
|
||||
//Location lists
|
||||
Engine.aevumLocationsList.style.display = "none";
|
||||
@ -599,6 +615,29 @@ var Engine = {
|
||||
augmentationsList.removeChild(augmentationsList.firstChild);
|
||||
}
|
||||
|
||||
//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 = document.createElement("li");
|
||||
var hElem = document.createElement("h2");
|
||||
var pElem = document.createElement("p");
|
||||
|
||||
item.setAttribute("class", "installed-augmentation");
|
||||
hElem.innerHTML = sourceFileObject.name + "<br>";
|
||||
hElem.innerHTML += "Level " + (Player.sourceFiles[i].lvl) + " / 3";
|
||||
pElem.innerHTML = sourceFileObject.info;
|
||||
|
||||
item.appendChild(hElem);
|
||||
item.appendChild(pElem);
|
||||
|
||||
augmentationsList.appendChild(item);
|
||||
}
|
||||
|
||||
for (var i = 0; i < Player.augmentations.length; ++i) {
|
||||
var augName = Player.augmentations[i].name;
|
||||
var aug = Augmentations[augName];
|
||||
@ -710,6 +749,11 @@ var Engine = {
|
||||
}
|
||||
}
|
||||
|
||||
//Gang, if applicable
|
||||
if (Player.bitNodeN == 2 && Player.inGang()) {
|
||||
Player.gang.process(numCycles);
|
||||
}
|
||||
|
||||
//Counters
|
||||
Engine.decrementAllCounters(numCycles);
|
||||
Engine.checkCounters();
|
||||
@ -732,6 +776,7 @@ var Engine = {
|
||||
autoSaveCounter: 300, //Autosave every minute
|
||||
updateSkillLevelsCounter: 10, //Only update skill levels every 2 seconds. Might improve performance
|
||||
updateDisplays: 3, //Update displays such as Active Scripts display and character display
|
||||
updateDisplaysLong: 15,
|
||||
createProgramNotifications: 10, //Checks whether any programs can be created and notifies
|
||||
checkFactionInvitations: 100, //Check whether you qualify for any faction invitations
|
||||
passiveFactionGrowth: 600,
|
||||
@ -781,6 +826,13 @@ var Engine = {
|
||||
Engine.Counters.updateDisplays = 3;
|
||||
}
|
||||
|
||||
if (Engine.Counters.updateDisplaysLong <= 0) {
|
||||
if (Engine.currentPage === Engine.Page.Gang) {
|
||||
updateGangContent();
|
||||
}
|
||||
Engine.Counters.updateDisplaysLong = 15;
|
||||
}
|
||||
|
||||
if (Engine.Counters.createProgramNotifications <= 0) {
|
||||
var num = getNumAvailableCreateProgram();
|
||||
var elem = document.getElementById("create-program-notification");
|
||||
@ -889,10 +941,6 @@ var Engine = {
|
||||
}, 3000);
|
||||
},
|
||||
|
||||
displayLoadingScreen: function() {
|
||||
|
||||
},
|
||||
|
||||
removeLoadingScreen: function() {
|
||||
var loader = document.getElementById("loader");
|
||||
if (!loader) {return;}
|
||||
@ -919,14 +967,15 @@ var Engine = {
|
||||
var tutorial = document.getElementById("tutorial-tab");
|
||||
var options = document.getElementById("options-tab");
|
||||
|
||||
|
||||
//Load game from save or create new game
|
||||
if (loadGame(saveObject)) {
|
||||
console.log("Loaded game from save");
|
||||
initBitNodeMultipliers();
|
||||
Engine.setDisplayElements(); //Sets variables for important DOM elements
|
||||
Engine.init(); //Initialize buttons, work, etc.
|
||||
CompanyPositions.init();
|
||||
initAugmentations(); //Also calls Player.reapplyAllAugmentations()
|
||||
Player.reapplyAllSourceFiles();
|
||||
initStockSymbols();
|
||||
if (Player.hasWseAccount) {
|
||||
initSymbolToStockMap();
|
||||
@ -962,6 +1011,11 @@ var Engine = {
|
||||
//Passive faction rep gain offline
|
||||
processPassiveFactionRepGain(numCyclesOffline);
|
||||
|
||||
//Gang progress for BitNode 2
|
||||
if (Player.bitNodeN != null && Player.bitNodeN == 2 && Player.inGang()) {
|
||||
Player.gang.process(numCyclesOffline);
|
||||
}
|
||||
|
||||
//Update total playtime
|
||||
var time = numCyclesOffline * Engine._idleSpeed;
|
||||
if (Player.totalPlaytime == null) {Player.totalPlaytime = 0;}
|
||||
@ -1018,6 +1072,7 @@ var Engine = {
|
||||
} else {
|
||||
//No save found, start new game
|
||||
console.log("Initializing new game");
|
||||
initBitNodeMultipliers();
|
||||
SpecialServerIps = new SpecialServerIpsMap();
|
||||
Engine.setDisplayElements(); //Sets variables for important DOM elements
|
||||
Engine.start(); //Run main game loop and Scripts loop
|
||||
@ -1594,6 +1649,5 @@ var Engine = {
|
||||
};
|
||||
|
||||
window.onload = function() {
|
||||
Engine.displayLoadingScreen();
|
||||
Engine.load();
|
||||
};
|
||||
|
@ -1,55 +0,0 @@
|
||||
/* Pop up Purchase Ram for Home Computer Pop-up Box */
|
||||
function purchaseRamForHomeBoxInit() {
|
||||
var cancelButton = document.getElementById("purchase-ram-for-home-box-cancel");
|
||||
|
||||
//Close Dialog box
|
||||
cancelButton.addEventListener("click", function() {
|
||||
purchaseRamForHomeBoxClose();
|
||||
return false;
|
||||
});
|
||||
};
|
||||
|
||||
document.addEventListener("DOMContentLoaded", purchaseRamForHomeBoxInit, false);
|
||||
|
||||
purchaseRamForHomeBoxClose = function() {
|
||||
var purchaseRamForHomeBox = document.getElementById("purchase-ram-for-home-box-container");
|
||||
purchaseRamForHomeBox.style.display = "none";
|
||||
}
|
||||
|
||||
purchaseRamForHomeBoxOpen = function() {
|
||||
var purchaseRamForHomeBox = document.getElementById("purchase-ram-for-home-box-container");
|
||||
purchaseRamForHomeBox.style.display = "block";
|
||||
}
|
||||
|
||||
purchaseRamForHomeBoxSetText = function(txt) {
|
||||
var textElem = document.getElementById("purchase-ram-for-home-box-text");
|
||||
textElem.innerHTML = txt;
|
||||
}
|
||||
|
||||
//ram argument is in GB
|
||||
purchaseRamForHomeBoxCreate = function() {
|
||||
//Calculate how many times ram has been upgraded (doubled)
|
||||
var currentRam = Player.getHomeComputer().maxRam;
|
||||
var newRam = currentRam * 2;
|
||||
var numUpgrades = Math.log2(currentRam);
|
||||
|
||||
//Calculate cost
|
||||
//Have cost increase by some percentage each time RAM has been upgraded
|
||||
var cost = currentRam * CONSTANTS.BaseCostFor1GBOfRamHome;
|
||||
var mult = Math.pow(1.55, numUpgrades);
|
||||
cost = cost * mult;
|
||||
|
||||
purchaseRamForHomeBoxSetText("Would you like to purchase additional RAM for your home computer? <br><br>" +
|
||||
"This will upgrade your RAM from " + currentRam + "GB to " + newRam + "GB. <br><br>" +
|
||||
"This will cost $" + formatNumber(cost, 2));
|
||||
|
||||
purchaseRamForHomeBoxOpen();
|
||||
|
||||
//Clear old event listeners from Confirm button
|
||||
var newConfirmButton = clearEventListeners("purchase-ram-for-home-box-confirm");
|
||||
newConfirmButton.addEventListener("click", function() {
|
||||
purchaseRamForHomeBoxClose();
|
||||
purchaseRamForHomeComputer(cost);
|
||||
return false;
|
||||
});
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
/* Pop up Purchase Server Box */
|
||||
function travelBoxInit() {
|
||||
var cancelButton = document.getElementById("travel-box-cancel");
|
||||
|
||||
//Close Dialog box
|
||||
cancelButton.addEventListener("click", function() {
|
||||
travelBoxClose();
|
||||
return false;
|
||||
});
|
||||
};
|
||||
|
||||
document.addEventListener("DOMContentLoaded", travelBoxInit, false);
|
||||
|
||||
travelBoxClose = function() {
|
||||
var travelBox = document.getElementById("travel-box-container");
|
||||
travelBox.style.display = "none";
|
||||
}
|
||||
|
||||
travelBoxOpen = function() {
|
||||
var travelBox = document.getElementById("travel-box-container");
|
||||
travelBox.style.display = "block";
|
||||
}
|
||||
|
||||
travelBoxSetText = function(txt) {
|
||||
var travelBoxText = document.getElementById("travel-box-text");
|
||||
travelBoxText.innerHTML = txt;
|
||||
}
|
||||
|
||||
travelBoxCreate = function(destCityName, cost) {
|
||||
travelBoxSetText("Would you like to travel to " + destCityName + "? The trip will cost $" + formatNumber(cost, 2) + ".");
|
||||
|
||||
//Clear old event listeners from Confirm button
|
||||
var newConfirmButton = clearEventListeners("travel-box-confirm");
|
||||
newConfirmButton.addEventListener("click", function() {
|
||||
travelBoxClose();
|
||||
travelToCity(destCityName, cost);
|
||||
return false;
|
||||
});
|
||||
|
||||
travelBoxOpen();
|
||||
}
|
76
utils/YesNoBox.js
Normal file
76
utils/YesNoBox.js
Normal file
@ -0,0 +1,76 @@
|
||||
/* Generic Yes-No Pop-up box
|
||||
* Can be used to create pop-up boxes that require a yes/no response from player
|
||||
*/
|
||||
var yesNoBoxOpen = false;
|
||||
function yesNoBoxClose() {
|
||||
var container = document.getElementById("yes-no-box-container");
|
||||
if (container) {
|
||||
container.style.display = "none";
|
||||
} else {
|
||||
console.log("ERROR: Container not found for YesNoBox");
|
||||
}
|
||||
yesNoBoxOpen = false;
|
||||
}
|
||||
|
||||
function yesNoBoxGetYesButton() {
|
||||
return clearEventListeners("yes-no-box-yes");
|
||||
}
|
||||
|
||||
function yesNoBoxGetNoButton() {
|
||||
return clearEventListeners("yes-no-box-no");
|
||||
}
|
||||
|
||||
function yesNoBoxCreate(txt) {
|
||||
yesNoBoxOpen = true;
|
||||
var textElement = document.getElementById("yes-no-box-text");
|
||||
if (textElement) {
|
||||
textElement.innerHTML = txt;
|
||||
}
|
||||
|
||||
var c = document.getElementById("yes-no-box-container");
|
||||
if (c) {
|
||||
c.style.display = "block";
|
||||
} else {
|
||||
console.log("ERROR: Container not found for YesNoBox");
|
||||
}
|
||||
}
|
||||
|
||||
/* Generic Yes-No POp-up Box with Text input */
|
||||
function yesNoTxtInpBoxClose() {
|
||||
var c = document.getElementById("yes-no-text-input-box-container");
|
||||
if (c) {
|
||||
c.style.display = "none";
|
||||
} else {
|
||||
console.log("ERROR: Container not found for YesNoTextInputBox");
|
||||
}
|
||||
yesNoBoxOpen = false;
|
||||
}
|
||||
|
||||
function yesNoTxtInpBoxGetYesButton() {
|
||||
return clearEventListeners("yes-no-text-input-box-yes");
|
||||
}
|
||||
|
||||
function yesNoTxtInpBoxGetNoButton() {
|
||||
return clearEventListeners("yes-no-text-input-box-no");
|
||||
}
|
||||
|
||||
function yesNoTxtInpBoxGetInput() {
|
||||
var val = document.getElementById("yes-no-text-input-box-input").value;
|
||||
val = val.replace(/\s+/g, '');
|
||||
return val;
|
||||
}
|
||||
|
||||
function yesNoTxtInpBoxCreate(txt) {
|
||||
yesNoBoxOpen = true;
|
||||
var txtE = document.getElementById("yes-no-text-input-box-text");
|
||||
if (txtE) {
|
||||
txtE.innerHTML = txt;
|
||||
}
|
||||
|
||||
var c = document.getElementById("yes-no-text-input-box-container");
|
||||
if (c) {
|
||||
c.style.display = "block";
|
||||
} else {
|
||||
console.log("ERROR: Container not found for YesNoTextInputBox");
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user