diff --git a/css/characteroverview.scss b/css/characteroverview.scss
new file mode 100644
index 000000000..0fabea40f
--- /dev/null
+++ b/css/characteroverview.scss
@@ -0,0 +1,89 @@
+@import "mixins";
+@import "theme";
+
+/**
+ * Styling for the Character Overview Panel (top-right)
+ */
+
+#character-overview-wrapper {
+ position: relative;
+}
+
+#character-overview-container {
+ display: none;
+ position: absolute; /* Stay in place */
+ right: 0;
+ top: 0;
+ height: auto; /* Full height */
+ padding: 10px 2px;
+ border: 2px solid var(--my-highlight-color);
+ width: auto;
+ max-width: 280px;
+ overflow: auto; /* Enable scroll if needed */
+ background-color: rgba(57, 54, 54, 0.9); /* Fallback color */
+ z-index: 1;
+}
+
+#character-overview-text {
+ color: $my-stat-physical;
+
+ table {
+ border-collapse: collapse;
+ margin: auto;
+ }
+
+ td {
+ padding: 2px;
+ vertical-align: middle;
+ }
+}
+
+.character-stat-text {
+ color: #fff;
+ background-color: #444;
+}
+
+ .character-stat-cell {
+ text-align: right;
+ }
+
+#character-hack-wrapper td,
+#character-agi-wrapper td {
+ border-bottom: 1px #aaa solid;
+ padding-bottom: 10px;
+}
+
+#character-str-wrapper td,
+#character-cha-wrapper td {
+ padding-top: 10px;
+}
+
+#character-hp-wrapper { color: $my-stat-hp-color; }
+#character-money-wrapper { color: $my-stat-money-color; }
+#character-hack-wrapper { color: $my-stat-hack-color; }
+#character-cha-wrapper { color: $my-stat-cha-color; }
+#character-int-wrapper { color: $my-stat-int-color; }
+
+.character-overview-btn {
+ @include borderRadius(12px);
+ @include boxShadow(1px 1px 3px #000);
+ color: #cecece;
+ display: inline-block;
+ font-size: $defaultFontSize * 0.875;
+ font-weight: bold;
+ height: 25px;
+ background-color: #000;
+ padding: 5px 8px;
+}
+
+.character-quick-options {
+ margin-top: 10px;
+ text-align: center;
+}
+
+.character-overview-btn:hover,
+.character-overview-btn:focus {
+ color: #fff;
+ text-decoration: none;
+ cursor: pointer;
+}
diff --git a/css/styles.scss b/css/styles.scss
index 1dfb98033..79be765c7 100644
--- a/css/styles.scss
+++ b/css/styles.scss
@@ -296,93 +296,6 @@ a:visited {
width: auto;
}
-/* Character Overview */
-#character-overview-wrapper {
- position: relative;
-}
-
-#character-overview-container {
- display: none;
- position: absolute; /* Stay in place */
- right: 0;
- top: 0;
- height: auto; /* Full height */
- padding: 10px 2px;
- border: 2px solid var(--my-highlight-color);
- width: auto;
- max-width: 280px;
- overflow: auto; /* Enable scroll if needed */
- background-color: rgba(57, 54, 54, 0.9); /* Fallback color */
- z-index: 1;
-}
-
-#character-overview-text {
- color: $my-stat-physical;
-
- table {
- border-collapse: collapse;
- margin: auto;
- }
-
- td {
- padding: 2px;
- vertical-align: middle;
- }
-}
-
-.character-stat-text {
- color: #fff;
- background-color: #444;
-}
-
-.character-stat-cell {
- text-align: right;
-}
-
-#character-hack-wrapper td,
-#character-agi-wrapper td {
- border-bottom: 1px #aaa solid;
- padding-bottom: 10px;
-}
-
-#character-str-wrapper td,
-#character-cha-wrapper td {
- padding-top: 10px;
-}
-
-#character-hp-wrapper { color: $my-stat-hp-color; }
-#character-money-wrapper { color: $my-stat-money-color; }
-#character-hack-wrapper { color: $my-stat-hack-color; }
-#character-cha-wrapper { color: $my-stat-cha-color; }
-#character-int-wrapper { color: $my-stat-int-color; }
-
-#character-overview-save-button,
-#character-overview-options-button {
- @include borderRadius(12px);
- @include boxShadow(1px 1px 3px #000);
- color: #cecece;
- display: inline-block;
- font-size: $defaultFontSize * 0.875;
- font-weight: bold;
- height: 25px;
- background-color: #000;
- padding: 5px 8px;
-}
-
-.character-quick-options {
- margin-top: 10px;
- text-align: center;
-}
-
-#character-overview-save-button:hover,
-#character-overview-save-button:focus,
-#character-overview-options-button:hover,
-#character-overview-options-button:focus {
- color: #fff;
- text-decoration: none;
- cursor: pointer;
-}
-
/* Scan analyze links from AutoLink */
.scan-analyze-link {
cursor: pointer;
diff --git a/netscript.js b/netscript.js
index 2118a5a3c..31996d179 100644
--- a/netscript.js
+++ b/netscript.js
@@ -62,7 +62,7 @@ let NetscriptFunctions =
"hack|sleep|grow|weaken|print|tprint|scan|nuke|brutessh|ftpcrack|" + //Netscript functions
"clearLog|disableLog|enableLog|isLogEnabled|getScriptLogs|" +
"relaysmtp|httpworm|sqlinject|run|exec|spawn|kill|killall|exit|" +
- "scp|ls|hasRootAccess|" +
+ "scp|ls|ps|hasRootAccess|" +
"getIp|getHackingMultipliers|getBitNodeMultipliers|getStats|isBusy|" +
"getHacknetMultipliers|" +
"getHostname|getHackingLevel|getServerMoneyAvailable|getServerMaxMoney|" +
diff --git a/src/BitNode.js b/src/BitNode.js
index ffa5a0ca3..fa8c6f939 100644
--- a/src/BitNode.js
+++ b/src/BitNode.js
@@ -265,7 +265,7 @@ function initBitNodeMultipliers() {
BitNodeMultipliers.CorporationValuation = 0.5;
break;
case 6: //Bladeburner
- BitNodeMultipliers.HackingLevelMultiplier = 0.5;
+ BitNodeMultipliers.HackingLevelMultiplier = 0.4;
BitNodeMultipliers.ServerMaxMoney = 0.5;
BitNodeMultipliers.ServerStartingMoney = 0.5;
BitNodeMultipliers.ServerStartingSecurity = 1.5;
@@ -282,7 +282,7 @@ function initBitNodeMultipliers() {
BitNodeMultipliers.BladeburnerRank = 0.6;
BitNodeMultipliers.BladeburnerSkillCost = 2;
BitNodeMultipliers.AugmentationMoneyCost = 3;
- BitNodeMultipliers.HackingLevelMultiplier = 0.5;
+ BitNodeMultipliers.HackingLevelMultiplier = 0.4;
BitNodeMultipliers.ServerMaxMoney = 0.5;
BitNodeMultipliers.ServerStartingMoney = 0.5;
BitNodeMultipliers.ServerStartingSecurity = 1.5;
diff --git a/src/Bladeburner.js b/src/Bladeburner.js
index f96df7070..9483cf9b3 100644
--- a/src/Bladeburner.js
+++ b/src/Bladeburner.js
@@ -74,7 +74,6 @@ var ContractBaseMoneyGain = 50e3; //Base Money Gained per contract
var ActiveActionCssClass = "bladeburner-active-action";
//Console related stuff
-var consoleHistory = []; //Console command history
var consoleHistoryIndex = 0;
var consoleHelpText = {
helpList:"Use 'help [command]' to get more information about a particular Bladeburner console command.
" +
@@ -153,6 +152,7 @@ $(document).keydown(function(event) {
//}
if (!(Player.bladeburner instanceof Bladeburner)) {return;}
+ let consoleHistory = Player.bladeburner.consoleHistory;
//NOTE: Keycodes imported from Terminal.js
if (event.keyCode === KEY.ENTER) {
@@ -712,6 +712,9 @@ function Bladeburner(params={}) {
this.automateActionLow = 0;
this.automateThreshLow = 0; //Stamina Threshold
+ //Console command history
+ this.consoleHistory = [];
+
//Initialization
initBladeburner();
this.initializeDomElementRefs();
@@ -1740,6 +1743,9 @@ Bladeburner.prototype.createContent = function() {
this.postToConsole("Bladeburner Console BETA");
this.postToConsole("Type 'help' to see console commands");
+ for (let i = 0; i < this.consoleHistory.length; ++i) {
+ this.postToConsole(this.consoleHistory[i]);
+ }
DomElems.consoleInput.focus();
}
@@ -2764,13 +2770,13 @@ Bladeburner.prototype.log = function(input) {
Bladeburner.prototype.executeConsoleCommands = function(commands) {
try {
//Console History
- if (consoleHistory[consoleHistory.length-1] != commands) {
- consoleHistory.push(commands);
- if (consoleHistory.length > 50) {
- consoleHistory.splice(0, 1);
+ if (this.consoleHistory[this.consoleHistory.length-1] != commands) {
+ this.consoleHistory.push(commands);
+ if (this.consoleHistory.length > 50) {
+ this.consoleHistory.splice(0, 1);
}
}
- consoleHistoryIndex = consoleHistory.length;
+ consoleHistoryIndex = this.consoleHistory.length;
var arrayOfCommands = commands.split(";");
for (var i = 0; i < arrayOfCommands.length; ++i) {
diff --git a/src/Constants.js b/src/Constants.js
index 7b68332d4..7a49fbeff 100644
--- a/src/Constants.js
+++ b/src/Constants.js
@@ -503,15 +503,24 @@ let CONSTANTS = {
LatestUpdate:
`
v0.41.1
+ * IMPORTANT - Netscript Changes:
+ ** purchaseTor() now returns true if you already have a TOR router (it used to return false)
+ ** Added purchase4SMarketData() and purchase4SMarketDataTixApi() functions
+
* Stock Market changes:
- *** Stocks now have "maximum prices"
- *** If a stock reaches its "maximum price", it will most likely drop in value (although it might still rise)
- *** Each stock has its own, unique maximum price
- *** Maximum price for each stock are randomly generated and change during each 'reset'
- *** Stock Market cycles are now accumulated/stored, much like it is for Gangs and Bladeburners
- *** Accumulated/stored cycles cause stock prices to update up to 50% faster (from every 6 seconds to 4 seconds)
- ****** This means that after coming back from being offline, stock prices will update faster to make up for offline time
-
+ ** Stocks now have "maximum prices"
+ ** If a stock reaches its "maximum price", it will most likely drop in value (although it might still rise)
+ ** Each stock has its own, unique maximum price
+ ** Maximum price for each stock are randomly generated and change during each 'reset'
+ ** Stock Market cycles are now accumulated/stored, much like it is for Gangs and Bladeburners
+ ** Accumulated/stored cycles cause stock prices to update up to 50% faster (from every 6 seconds to 4 seconds)
+ *** This means that after coming back from being offline, stock prices will update faster to make up for offline time
+
+ * Decreased the Hacking Level multiplier for BitNodes 6 and 7 to 0.4 (from 0.5)
+ * Bladeburner console history is now saved and persists when switching screens or closing/reopening the game
+ * b1t_flum3.exe is no longer removed from your home computer upon reset
+ * Added main menu link for the Stock Market
+ * Job main menu link only appears if you actually have a job
`
}
diff --git a/src/Faction.js b/src/Faction.js
index bc4c1cea8..f0a04a9ba 100644
--- a/src/Faction.js
+++ b/src/Faction.js
@@ -394,7 +394,6 @@ function displayFactionContent(factionName) {
var hacking = false;
if (factionName === "NiteSec" || factionName === "The Black Hand") {hacking = true;}
Player.startGang(factionName, hacking);
- document.getElementById("gang-tab").style.display = "list-item";
document.getElementById("world-menu-header").click();
document.getElementById("world-menu-header").click();
Engine.loadGangContent();
diff --git a/src/Location.js b/src/Location.js
index d2404ec65..6a8f40d88 100644
--- a/src/Location.js
+++ b/src/Location.js
@@ -1953,7 +1953,6 @@ function initLocationButtons() {
name:companyName,
});
displayLocationContent();
- document.getElementById("corporation-tab").style.display = "list-item";
document.getElementById("world-menu-header").click();
document.getElementById("world-menu-header").click();
dialogBoxCreate("Congratulations! You just started your own corporation. You can visit " +
@@ -1983,7 +1982,6 @@ function initLocationButtons() {
Player.bladeburner = new Bladeburner({new:true});
dialogBoxCreate("You have been accepted into the Bladeburner division!");
displayLocationContent();
- document.getElementById("bladeburner-tab").style.display = "list-item";
document.getElementById("world-menu-header").click();
document.getElementById("world-menu-header").click();
} else {
diff --git a/src/NetscriptFunctions.js b/src/NetscriptFunctions.js
index bc9d7df18..fdc0b969c 100644
--- a/src/NetscriptFunctions.js
+++ b/src/NetscriptFunctions.js
@@ -106,11 +106,14 @@ var possibleLogs = {
getServerGrowth: true,
getServerNumPortsRequired: true,
getServerRam: true,
+
// TIX API
buyStock: true,
sellStock: true,
shortStock: true,
sellShort: true,
+ purchase4SMarketData: true,
+ purchase4SMarketDataTixApi: true,
// Singularity Functions
purchaseServer: true,
@@ -545,8 +548,14 @@ function NetscriptFunctions(workerScript) {
}
return workerScript.disableLogs[fn] ? false : true;
},
- getScriptLogs : function() {
+ getScriptLogs : function(fn, ip) {
if (workerScript.checkingRam) {return 0;}
+
+ if (fn != null && typeof fn === 'string') {
+ // Get Logs of another script
+ if (ip == null) { ip = workerScript.serverIp; }
+ }
+
return workerScript.scriptRef.logs.slice();
},
nuke : function(ip){
@@ -1696,6 +1705,68 @@ function NetscriptFunctions(workerScript) {
stock.b ? forecast += stock.otlkMag : forecast -= stock.otlkMag;
return forecast / 100; //Convert from percentage to decimal
},
+ purchase4SMarketData : function() {
+ if (workerScript.checkingRam) {
+ return updateStaticRam("purchase4SMarketData", CONSTANTS.ScriptBuySellStockRamCost);
+ }
+ updateDynamicRam("purchase4SMarketData", CONSTANTS.ScriptBuySellStockRamCost);
+
+ if (!Player.hasTixApiAccess) {
+ throw makeRuntimeRejectMsg(workerScript, "You don't have TIX API Access! Cannot use purchase4SMarketData()");
+ }
+
+ if (Player.Player.has4SData) {
+ if (workerScript.shouldLog("purchase4SMarketData")) {
+ workerScript.log("Already purchased 4S Market Data");
+ }
+ return true;
+ }
+
+ if (Player.money.lt(CONSTANTS.MarketData4SCost)) {
+ if (workerScript.shouldLog("purchase4SMarketData")) {
+ workerScript.log("Failed to purchase 4S Market Data - Not enough money");
+ }
+ return false;
+ }
+
+ Player.has4SData = true;
+ Player.loseMoney(CONSTANTS.MarketData4SCost);
+ if (workerScript.shouldLog("purchase4SMarketData")) {
+ workerScript.log("Purchased 4S Market Data");
+ }
+ return true;
+ },
+ purchase4SMarketDataTixApi : function() {
+ if (workerScript.checkingRam) {
+ return updateStaticRam("purchase4SMarketDataTixApi", CONSTANTS.ScriptBuySellStockRamCost);
+ }
+ updateDynamicRam("purchase4SMarketDataTixApi", CONSTANTS.ScriptBuySellStockRamCost);
+
+ if (!Player.hasTixApiAccess) {
+ throw makeRuntimeRejectMsg(workerScript, "You don't have TIX API Access! Cannot use purchase4SMarketDataTixApi()");
+ }
+
+ if (Player.has4SDataTixApi) {
+ if (workerScript.shouldLog("purchase4SMarketDataTixApi")) {
+ workerScript.log("Already purchased 4S Market Data TIX API");
+ }
+ return true;
+ }
+
+ if (Player.money.lt(CONSTANTS.MarketDataTixApi4SCost)) {
+ if (workerScript.shouldLog("purchase4SMarketDataTixApi")) {
+ workerScript.log("Failed to purchase 4S Market Data TIX API - Not enough money");
+ }
+ return false;
+ }
+
+ Player.has4SDataTixApi = true;
+ Player.loseMoney(CONSTANTS.MarketDataTixApi4SCost);
+ if (workerScript.shouldLog("purchase4SMarketDataTixApi")) {
+ workerScript.log("Purchased 4S Market Data TIX API");
+ }
+ return true;
+ },
getPurchasedServerLimit : function() {
if (workerScript.checkingRam) {
return updateStaticRam("getPurchasedServerLimit", CONSTANTS.ScriptGetPurchasedServerLimit);
diff --git a/src/Player.js b/src/Player.js
index 9edddb8ff..eedbbded1 100644
--- a/src/Player.js
+++ b/src/Player.js
@@ -191,7 +191,6 @@ function PlayerObject() {
//Flags for determining whether certain "thresholds" have been achieved
this.firstFacInvRecvd = false;
this.firstAugPurchased = false;
- this.firstJobRecvd = false;
this.firstTimeTraveled = false;
this.firstProgramAvailable = false;
@@ -1687,12 +1686,8 @@ PlayerObject.prototype.applyForJob = function(entryPosType, sing=false) {
this.companyName = company.companyName;
this.companyPosition = pos;
- if (this.firstJobRecvd === false) {
- this.firstJobRecvd = true;
- document.getElementById("job-tab").style.display = "list-item";
- document.getElementById("world-menu-header").click();
- document.getElementById("world-menu-header").click();
- }
+ document.getElementById("world-menu-header").click();
+ document.getElementById("world-menu-header").click();
if (leaveCompany) {
if (sing) {return true;}
@@ -1797,14 +1792,10 @@ PlayerObject.prototype.applyForAgentJob = function(sing=false) {
PlayerObject.prototype.applyForEmployeeJob = function(sing=false) {
var company = Companies[this.location]; //Company being applied to
if (this.isQualified(company, CompanyPositions.Employee)) {
- if (this.firstJobRecvd === false) {
- this.firstJobRecvd = true;
- document.getElementById("job-tab").style.display = "list-item";
- document.getElementById("world-menu-header").click();
- document.getElementById("world-menu-header").click();
- }
this.companyName = company.companyName;
this.companyPosition = CompanyPositions.Employee;
+ document.getElementById("world-menu-header").click();
+ document.getElementById("world-menu-header").click();
if (sing) {return true;}
dialogBoxCreate("Congratulations, you are now employed at " + this.companyName);
Engine.loadLocationContent();
@@ -1817,14 +1808,10 @@ PlayerObject.prototype.applyForEmployeeJob = function(sing=false) {
PlayerObject.prototype.applyForPartTimeEmployeeJob = function(sing=false) {
var company = Companies[this.location]; //Company being applied to
if (this.isQualified(company, CompanyPositions.PartTimeEmployee)) {
- if (this.firstJobRecvd === false) {
- this.firstJobRecvd = true;
- document.getElementById("job-tab").style.display = "list-item";
- document.getElementById("world-menu-header").click();
- document.getElementById("world-menu-header").click();
- }
this.companyName = company.companyName;
this.companyPosition = CompanyPositions.PartTimeEmployee;
+ document.getElementById("world-menu-header").click();
+ document.getElementById("world-menu-header").click();
if (sing) {return true;}
dialogBoxCreate("Congratulations, you are now employed part-time at " + this.companyName);
Engine.loadLocationContent();
@@ -1837,14 +1824,10 @@ PlayerObject.prototype.applyForPartTimeEmployeeJob = function(sing=false) {
PlayerObject.prototype.applyForWaiterJob = function(sing=false) {
var company = Companies[this.location]; //Company being applied to
if (this.isQualified(company, CompanyPositions.Waiter)) {
- if (this.firstJobRecvd === false) {
- this.firstJobRecvd = true;
- document.getElementById("job-tab").style.display = "list-item";
- document.getElementById("world-menu-header").click();
- document.getElementById("world-menu-header").click();
- }
this.companyName = company.companyName;
this.companyPosition = CompanyPositions.Waiter;
+ document.getElementById("world-menu-header").click();
+ document.getElementById("world-menu-header").click();
if (sing) {return true;}
dialogBoxCreate("Congratulations, you are now employed as a waiter at " + this.companyName);
Engine.loadLocationContent();
@@ -1857,14 +1840,10 @@ PlayerObject.prototype.applyForWaiterJob = function(sing=false) {
PlayerObject.prototype.applyForPartTimeWaiterJob = function(sing=false) {
var company = Companies[this.location]; //Company being applied to
if (this.isQualified(company, CompanyPositions.PartTimeWaiter)) {
- if (this.firstJobRecvd === false) {
- this.firstJobRecvd = true;
- document.getElementById("job-tab").style.display = "list-item";
- document.getElementById("world-menu-header").click();
- document.getElementById("world-menu-header").click();
- }
this.companyName = company.companyName;
this.companyPosition = CompanyPositions.PartTimeWaiter;
+ document.getElementById("world-menu-header").click();
+ document.getElementById("world-menu-header").click();
if (sing) {return true;}
dialogBoxCreate("Congratulations, you are now employed as a part-time waiter at " + this.companyName);
Engine.loadLocationContent();
diff --git a/src/Prestige.js b/src/Prestige.js
index 55f6b4058..9112a22b5 100755
--- a/src/Prestige.js
+++ b/src/Prestige.js
@@ -148,6 +148,10 @@ function prestigeAugmentation() {
Terminal.resetTerminalInput();
Engine.loadTerminalContent();
+ // Refresh Main Menu (the 'World' menu, specifically)
+ document.getElementById("world-menu-header").click();
+ document.getElementById("world-menu-header").click();
+
//Red Pill
if (augmentationExists(AugmentationNames.TheRedPill) &&
Augmentations[AugmentationNames.TheRedPill].owned) {
@@ -319,6 +323,10 @@ function prestigeSourceFile() {
Player.corporation = null;
Player.bladeburner = null;
+ // Refresh Main Menu (the 'World' menu, specifically)
+ document.getElementById("world-menu-header").click();
+ document.getElementById("world-menu-header").click();
+
//Gain int exp
Player.gainIntelligenceExp(5);
}
diff --git a/src/SaveObject.js b/src/SaveObject.js
index 965ab6792..36753dbdf 100755
--- a/src/SaveObject.js
+++ b/src/SaveObject.js
@@ -198,16 +198,12 @@ function loadGame(saveString) {
//that everything should be available
Player.firstFacInvRecvd = true;
Player.firstAugPurchased = true;
- Player.firstJobRecvd = true;
Player.firstTimeTraveled = true;
Player.firstProgramAvailable = true;
} else {
if (Player.factions.length > 0 || Player.factionInvitations.length > 0) {
Player.firstFacInvRecvd = true;
}
- if (Player.companyName !== "" || Player.companyPosition !== "") {
- Player.firstJobRecvd = true;
- }
if (Player.hacking_skill >= 25) {
Player.firstScriptAvailable = true;
}
@@ -417,16 +413,12 @@ function loadImportedGame(saveObj, saveString) {
//that everything should be available
Player.firstFacInvRecvd = true;
Player.firstAugPurchased = true;
- Player.firstJobRecvd = true;
Player.firstTimeTraveled = true;
Player.firstProgramAvailable = true;
} else {
if (Player.factions.length > 0 || Player.factionInvitations.length > 0) {
Player.firstFacInvRecvd = true;
}
- if (Player.companyName !== "" || Player.companyPosition !== "") {
- Player.firstJobRecvd = true;
- }
if (Player.hacking_skill >= 25) {
Player.firstScriptAvailable = true;
}
diff --git a/src/Server.js b/src/Server.js
index fa8e423a3..113e1004b 100644
--- a/src/Server.js
+++ b/src/Server.js
@@ -344,12 +344,15 @@ function processSingleServerGrowth(server, numCycles) {
}
function prestigeHomeComputer(homeComp) {
+ const hasBitflume = homeComp.programs.includes(Programs.BitFlume.name);
+
homeComp.programs.length = 0; //Remove programs
homeComp.runningScripts = [];
homeComp.serversOnNetwork = [];
homeComp.isConnectedTo = true;
homeComp.ramUsed = 0;
homeComp.programs.push(Programs.NukeProgram.name);
+ if (hasBitflume) { homeComp.programs.push(Programs.BitFlume.name); }
//Update RAM usage on all scripts
homeComp.scripts.forEach(function(script) {
diff --git a/src/StockMarket.js b/src/StockMarket.js
index 78d21dc67..22213d55a 100755
--- a/src/StockMarket.js
+++ b/src/StockMarket.js
@@ -743,6 +743,7 @@ function displayStockMarketContent() {
"Buy 4S Market Data Access - " + numeralWrapper.format(CONSTANTS.MarketData4SCost, '($0.000a)'),
"4S Market Data - Purchased");
marketDataButton.addEventListener("click", function() {
+ if (Player.money.lt(CONSTANTS.MarketData4SCost)) { return false; }
Player.has4SData = true;
Player.loseMoney(CONSTANTS.MarketData4SCost);
displayStockMarketContent();
@@ -782,6 +783,7 @@ function displayStockMarketContent() {
"4S Market Data TIX API - Purchased");
if (Player.hasTixApiAccess) {
marketDataTixButton.addEventListener("click", function() {
+ if (Player.money.lt(CONSTANTS.MarketDataTixApi4SCost)) { return false; }
Player.has4SDataTixApi = true;
Player.loseMoney(CONSTANTS.MarketDataTixApi4SCost);
displayStockMarketContent();
diff --git a/src/data/codingcontracttypes.ts b/src/data/codingcontracttypes.ts
index 8c44f9924..18e8fe455 100644
--- a/src/data/codingcontracttypes.ts
+++ b/src/data/codingcontracttypes.ts
@@ -105,7 +105,7 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [
" 2 + 2\n",
" 2 + 1 + 1\n",
" 1 + 1 + 1 + 1\n\n",
- `How many different ways can ${n} be written as a sum of at least`,
+ `How many different ways can the number ${n} be written as a sum of at least`,
"two positive integers?"].join(" ");
},
difficulty: 1.5,
@@ -387,8 +387,8 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [
},
{
desc: (data: number[]) => {
- return ["You are given the following array of stock prices where the i-th element",
- "represents the stock price on day i:\n\n",
+ return ["You are given the following array of stock prices (which are numbers)",
+ "where the i-th element represents the stock price on day i:\n\n",
`${data}\n\n`,
"Determine the maximum possible profit you can earn using at most",
"one transaction (i.e. you can only buy and sell the stock once). If no profit can be made",
@@ -421,8 +421,8 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [
},
{
desc: (data: number[]) => {
- return ["You are given the following array of stock prices where the i-th element",
- "represents the stock price on day i:\n\n",
+ return ["You are given the following array of stock prices (which are numbers)",
+ "where the i-th element represents the stock price on day i:\n\n",
`${data}\n\n`,
"Determine the maximum possible profit you can earn using as many",
"transactions as you'd like. A transaction is defined as buying",
@@ -455,8 +455,8 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [
},
{
desc: (data: number[]) => {
- return ["You are given the following array of stock prices where the i-th element",
- "represents the stock price on day i:\n\n",
+ return ["You are given the following array of stock prices (which are numbers)",
+ "where the i-th element represents the stock price on day i:\n\n",
`${data}\n\n`,
"Determine the maximum possible profit you can earn using at most",
"two transactions. A transaction is defined as buying",
diff --git a/src/engine.js b/src/engine.js
index 19364d6cb..19a2f165b 100644
--- a/src/engine.js
+++ b/src/engine.js
@@ -78,6 +78,7 @@ import 'normalize.css';
import "../css/styles.scss";
import "../css/buttons.scss";
import "../css/mainmenu.scss";
+import "../css/characteroverview.scss";
import "../css/terminal.scss";
import "../css/menupages.scss";
import "../css/workinprogress.scss";
@@ -172,6 +173,7 @@ const Engine = {
worldMainMenuButton: null,
travelMainMenuButton: null,
jobMainMenuButton: null,
+ stockmarketMainMenuButton: null,
createProgramMainMenuButton: null,
factionsMainMenuButton: null,
augmentationsMainMenuButton: null,
@@ -1186,6 +1188,7 @@ const Engine = {
var city = document.getElementById("city-tab");
var travel = document.getElementById("travel-tab");
var job = document.getElementById("job-tab");
+ var stockmarket = document.getElementById("stock-market-tab");
var bladeburner = document.getElementById("bladeburner-tab");
var corp = document.getElementById("corporation-tab");
var gang = document.getElementById("gang-tab");
@@ -1275,12 +1278,14 @@ const Engine = {
else {factions.style.display = "none";}
if (Player.firstAugPurchased) {visibleMenuTabs.push(augmentations);}
else {augmentations.style.display = "none";}
- if (Player.firstJobRecvd) {visibleMenuTabs.push(job);}
+ if (Player.companyPosition !== "") {visibleMenuTabs.push(job);}
else {job.style.display = "none";}
if (Player.firstTimeTraveled) {visibleMenuTabs.push(travel);}
else {travel.style.display = "none";}
if (Player.firstProgramAvailable) {visibleMenuTabs.push(createProgram);}
else {createProgram.style.display = "none";}
+ if (Player.hasWseAccount) {visibleMenuTabs.push(stockmarket);}
+ else {stockmarket.style.display = "none";}
if(Player.bladeburner instanceof Bladeburner) {visibleMenuTabs.push(bladeburner);}
else {bladeburner.style.display = "none";}
if(Player.corporation instanceof Corporation) {visibleMenuTabs.push(corp);}
@@ -1324,6 +1329,7 @@ const Engine = {
factions.style.display = "none";
augmentations.style.display = "none";
job.style.display = "none";
+ stockmarket.style.display = "none";
travel.style.display = "none";
createProgram.style.display = "none";
bladeburner.style.display = "none";
@@ -1540,28 +1546,38 @@ const Engine = {
}
worldHdr.onclick = function() {
- var city = document.getElementById("city-tab");
- var cityLink = document.getElementById("city-menu-link");
- var travel = document.getElementById("travel-tab");
- var travelLink = document.getElementById("travel-menu-link");
- var job = document.getElementById("job-tab");
- var jobLink = document.getElementById("job-menu-link");
- var bladeburner = document.getElementById("bladeburner-tab");
- var bladeburnerLink = document.getElementById("bladeburner-menu-link");
- var corporation = document.getElementById("corporation-tab");
- var corporationLink = document.getElementById("corporation-menu-link");
- var gang = document.getElementById("gang-tab");
- var gangLink = document.getElementById("gang-menu-link");
+ var city = document.getElementById("city-tab");
+ var cityLink = document.getElementById("city-menu-link");
+ var travel = document.getElementById("travel-tab");
+ var travelLink = document.getElementById("travel-menu-link");
+ var job = document.getElementById("job-tab");
+ var jobLink = document.getElementById("job-menu-link");
+ var stockmarket = document.getElementById("stock-market-tab");
+ var stockmarketLink = document.getElementById("stock-market-menu-link");
+ var bladeburner = document.getElementById("bladeburner-tab");
+ var bladeburnerLink = document.getElementById("bladeburner-menu-link");
+ var corporation = document.getElementById("corporation-tab");
+ var corporationLink = document.getElementById("corporation-menu-link");
+ var gang = document.getElementById("gang-tab");
+ var gangLink = document.getElementById("gang-menu-link");
+
+ // Determine whether certain links should show up
+ job.style.display = Player.companyPosition !== "" ? "list-item" : "none";
+ stockmarket.style.display = Player.hasWseAccount ? "list-item" : "none";
+ bladeburner.style.display = Player.bladeburner instanceof Bladeburner ? "list-item" : "none";
+ corporation.style.display = Player.corporation instanceof Corporation ? "list-item" : "none";
+ gang.style.display = Player.inGang() ? "list-item" : "none";
+
this.classList.toggle("opened");
if (city.style.maxHeight) {
Engine.toggleMainMenuHeader(false,
- [city, travel, job, bladeburner, corporation, gang],
- [cityLink, travelLink, jobLink, bladeburnerLink, corporationLink, gangLink]
+ [city, travel, job, stockmarket, bladeburner, corporation, gang],
+ [cityLink, travelLink, jobLink, stockmarketLink, bladeburnerLink, corporationLink, gangLink]
);
} else {
Engine.toggleMainMenuHeader(true,
- [city, travel, job, bladeburner, corporation, gang],
- [cityLink, travelLink, jobLink, bladeburnerLink, corporationLink, gangLink]
+ [city, travel, job, stockmarket, bladeburner, corporation, gang],
+ [cityLink, travelLink, jobLink, stockmarketLink, bladeburnerLink, corporationLink, gangLink]
);
}
}
@@ -1634,6 +1650,12 @@ const Engine = {
return false;
});
+ Engine.Clickables.stockmarketMainMenuButton = clearEventListeners("stock-market-menu-link");
+ Engine.Clickables.stockmarketMainMenuButton.addEventListener("click", function() {
+ Engine.loadStockMarketContent();
+ return false;
+ });
+
Engine.Clickables.createProgramMainMenuButton = clearEventListeners("create-program-menu-link");
Engine.Clickables.createProgramMainMenuButton.addEventListener("click", function() {
diff --git a/src/index.html b/src/index.html
index ffc3db652..8a35211e1 100644
--- a/src/index.html
+++ b/src/index.html
@@ -81,6 +81,9 @@ if (htmlWebpackPlugin.options.googleAnalytics.trackingId) { %>