mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2026-04-17 14:59:16 +02:00
Added hackAnalyze() functions. Fixed bug with gymWorkout() and Millenium Fitness Gym. Updated documentation for new functions
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
import { BitNodeMultipliers } from "./BitNodeMultipliers";
|
||||
import { CONSTANTS } from "./Constants";
|
||||
import { Engine } from "./engine";
|
||||
import { Factions,
|
||||
factionExists } from "./Faction/Factions";
|
||||
import { hasBladeburnerSF } from "./NetscriptFunctions";
|
||||
@@ -18,6 +17,7 @@ import { dialogBoxCreate } from "../utils/DialogBox";
|
||||
import { createAccordionElement } from "../utils/uiHelpers/createAccordionElement";
|
||||
import { Reviver, Generic_toJSON,
|
||||
Generic_fromJSON } from "../utils/JSONReviver";
|
||||
import { formatNumber } from "../utils/StringHelperFunctions";
|
||||
import { clearObject } from "../utils/helpers/clearObject";
|
||||
import { createElement } from "../utils/uiHelpers/createElement";
|
||||
import { isString } from "../utils/helpers/isString";
|
||||
@@ -2475,9 +2475,9 @@ function giveAllAugmentations() {
|
||||
Player.reapplyAllAugmentations();
|
||||
}
|
||||
|
||||
function displayAugmentationsContent() {
|
||||
removeChildrenFromElement(Engine.Display.augmentationsContent);
|
||||
Engine.Display.augmentationsContent.appendChild(createElement("h1", {
|
||||
function displayAugmentationsContent(contentEl) {
|
||||
removeChildrenFromElement(contentEl);
|
||||
contentEl.appendChild(createElement("h1", {
|
||||
innerText:"Purchased Augmentations",
|
||||
}));
|
||||
|
||||
@@ -2487,7 +2487,7 @@ function displayAugmentationsContent() {
|
||||
bladeburnerText = "Bladeburner Progress\n\n";
|
||||
}
|
||||
|
||||
Engine.Display.augmentationsContent.appendChild(createElement("pre", {
|
||||
contentEl.appendChild(createElement("pre", {
|
||||
width:"70%", whiteSpace:"pre-wrap", display:"block",
|
||||
innerText:"Below is a list of all Augmentations you have purchased but not yet installed. Click the button below to install them.\n" +
|
||||
"WARNING: Installing your Augmentations resets most of your progress, including:\n\n" +
|
||||
@@ -2505,7 +2505,7 @@ function displayAugmentationsContent() {
|
||||
}));
|
||||
|
||||
//Install Augmentations button
|
||||
Engine.Display.augmentationsContent.appendChild(createElement("a", {
|
||||
contentEl.appendChild(createElement("a", {
|
||||
class:"a-link-button", innerText:"Install Augmentations",
|
||||
tooltip:"'I never asked for this'",
|
||||
clickListener:()=>{
|
||||
@@ -2515,7 +2515,7 @@ function displayAugmentationsContent() {
|
||||
}));
|
||||
|
||||
//Backup button
|
||||
Engine.Display.augmentationsContent.appendChild(createElement("a", {
|
||||
contentEl.appendChild(createElement("a", {
|
||||
class:"a-link-button flashing-button", innerText:"Backup Save (Export)",
|
||||
tooltip:"It's always a good idea to backup/export your save!",
|
||||
clickListener:()=>{
|
||||
@@ -2539,13 +2539,13 @@ function displayAugmentationsContent() {
|
||||
var accordion = createAccordionElement({hdrText:displayName, panelText:aug.info});
|
||||
queuedAugmentationsList.appendChild(accordion[0]);
|
||||
}
|
||||
Engine.Display.augmentationsContent.appendChild(queuedAugmentationsList);
|
||||
contentEl.appendChild(queuedAugmentationsList);
|
||||
|
||||
//Installed augmentations list
|
||||
Engine.Display.augmentationsContent.appendChild(createElement("h1", {
|
||||
contentEl.appendChild(createElement("h1", {
|
||||
innerText:"Installed Augmentations", marginTop:"8px",
|
||||
}));
|
||||
Engine.Display.augmentationsContent.appendChild(createElement("p", {
|
||||
contentEl.appendChild(createElement("p", {
|
||||
width:"70%", whiteSpace:"pre-wrap",
|
||||
innerText:"List of all Augmentations (including Source Files) that have been " +
|
||||
"installed. You have gained the effects of these Augmentations."
|
||||
@@ -2554,7 +2554,7 @@ function displayAugmentationsContent() {
|
||||
var augmentationsList = createElement("ul", {class:"augmentations-list"});
|
||||
|
||||
//Expand/Collapse All buttons
|
||||
Engine.Display.augmentationsContent.appendChild(createElement("a", {
|
||||
contentEl.appendChild(createElement("a", {
|
||||
class:"a-link-button", fontSize:"14px", innerText:"Expand All", display:"inline-block",
|
||||
clickListener:()=>{
|
||||
var allHeaders = augmentationsList.getElementsByClassName("accordion-header");
|
||||
@@ -2563,7 +2563,7 @@ function displayAugmentationsContent() {
|
||||
}
|
||||
}
|
||||
}));
|
||||
Engine.Display.augmentationsContent.appendChild(createElement("a", {
|
||||
contentEl.appendChild(createElement("a", {
|
||||
class:"a-link-button", fontSize:"14px", innerText:"Collapse All", display:"inline-block",
|
||||
clickListener:()=>{
|
||||
var allHeaders = augmentationsList.getElementsByClassName("accordion-header");
|
||||
@@ -2595,7 +2595,7 @@ function displayAugmentationsContent() {
|
||||
Settings.OwnedAugmentationsOrder = OwnedAugmentationsOrderSetting.Alphabetically;
|
||||
}
|
||||
});
|
||||
Engine.Display.augmentationsContent.appendChild(sortInOrderButton);
|
||||
contentEl.appendChild(sortInOrderButton);
|
||||
|
||||
const sortByAcquirementTimeButton = createElement("a", {
|
||||
class:"a-link-button", fontSize:"14px", innerText:"Sort by Acquirement Time",
|
||||
@@ -2608,15 +2608,47 @@ function displayAugmentationsContent() {
|
||||
Settings.OwnedAugmentationsOrder = OwnedAugmentationsOrderSetting.AcquirementTime;
|
||||
}
|
||||
});
|
||||
Engine.Display.augmentationsContent.appendChild(sortByAcquirementTimeButton);
|
||||
contentEl.appendChild(sortByAcquirementTimeButton);
|
||||
|
||||
//Source Files - Temporary...Will probably put in a separate pane Later
|
||||
if (Settings.OwnedAugmentationsOrder === OwnedAugmentationsOrderSetting.Alphabetically) {
|
||||
sortInOrderButton.click();
|
||||
} else {
|
||||
sortByAcquirementTimeButton.click();
|
||||
}
|
||||
Engine.Display.augmentationsContent.appendChild(augmentationsList);
|
||||
contentEl.appendChild(augmentationsList);
|
||||
|
||||
// Display multiplier information at the bottom
|
||||
contentEl.appendChild(createElement("p", {
|
||||
display: "block",
|
||||
innerHTML:
|
||||
`<br><br><strong><u>Total Multipliers:</u></strong><br>` +
|
||||
'Hacking Chance multiplier: ' + formatNumber(Player.hacking_chance_mult * 100, 2) + '%<br>' +
|
||||
'Hacking Speed multiplier: ' + formatNumber(Player.hacking_speed_mult * 100, 2) + '%<br>' +
|
||||
'Hacking Money multiplier: ' + formatNumber(Player.hacking_money_mult * 100, 2) + '%<br>' +
|
||||
'Hacking Growth multiplier: ' + formatNumber(Player.hacking_grow_mult * 100, 2) + '%<br><br>' +
|
||||
'Hacking Level multiplier: ' + formatNumber(Player.hacking_mult * 100, 2) + '%<br>' +
|
||||
'Hacking Experience multiplier: ' + formatNumber(Player.hacking_exp_mult * 100, 2) + '%<br><br>' +
|
||||
'Strength Level multiplier: ' + formatNumber(Player.strength_mult * 100, 2) + '%<br>' +
|
||||
'Strength Experience multiplier: ' + formatNumber(Player.strength_exp_mult * 100, 2) + '%<br><br>' +
|
||||
'Defense Level multiplier: ' + formatNumber(Player.defense_mult * 100, 2) + '%<br>' +
|
||||
'Defense Experience multiplier: ' + formatNumber(Player.defense_exp_mult * 100, 2) + '%<br><br>' +
|
||||
'Dexterity Level multiplier: ' + formatNumber(Player.dexterity_mult * 100, 2) + '%<br>' +
|
||||
'Dexterity Experience multiplier: ' + formatNumber(Player.dexterity_exp_mult * 100, 2) + '%<br><br>' +
|
||||
'Agility Level multiplier: ' + formatNumber(Player.agility_mult * 100, 2) + '%<br>' +
|
||||
'Agility Experience multiplier: ' + formatNumber(Player.agility_exp_mult * 100, 2) + '%<br><br>' +
|
||||
'Charisma Level multiplier: ' + formatNumber(Player.charisma_mult * 100, 2) + '%<br>' +
|
||||
'Charisma Experience multiplier: ' + formatNumber(Player.charisma_exp_mult * 100, 2) + '%<br><br>' +
|
||||
'Hacknet Node production multiplier: ' + formatNumber(Player.hacknet_node_money_mult * 100, 2) + '%<br>' +
|
||||
'Hacknet Node purchase cost multiplier: ' + formatNumber(Player.hacknet_node_purchase_cost_mult * 100, 2) + '%<br>' +
|
||||
'Hacknet Node RAM upgrade cost multiplier: ' + formatNumber(Player.hacknet_node_ram_cost_mult * 100, 2) + '%<br>' +
|
||||
'Hacknet Node Core purchase cost multiplier: ' + formatNumber(Player.hacknet_node_core_cost_mult * 100, 2) + '%<br>' +
|
||||
'Hacknet Node level upgrade cost multiplier: ' + formatNumber(Player.hacknet_node_level_cost_mult * 100, 2) + '%<br><br>' +
|
||||
'Company reputation gain multiplier: ' + formatNumber(Player.company_rep_mult * 100, 2) + '%<br>' +
|
||||
'Faction reputation gain multiplier: ' + formatNumber(Player.faction_rep_mult * 100, 2) + '%<br>' +
|
||||
'Salary multiplier: ' + formatNumber(Player.work_money_mult * 100, 2) + '%<br>' +
|
||||
'Crime success multiplier: ' + formatNumber(Player.crime_success_mult * 100, 2) + '%<br>' +
|
||||
'Crime money multiplier: ' + formatNumber(Player.crime_money_mult * 100, 2) + '%<br><br><br>',
|
||||
}))
|
||||
}
|
||||
|
||||
//Creates the accordion elements to display Augmentations
|
||||
|
||||
@@ -55,6 +55,7 @@ export let CONSTANTS: IMap<any> = {
|
||||
ScriptForRamCost: 0,
|
||||
ScriptIfRamCost: 0,
|
||||
ScriptHackRamCost: 0.1,
|
||||
ScriptHackAnalyzeRamCost: 1,
|
||||
ScriptGrowRamCost: 0.15,
|
||||
ScriptGrowthAnalyzeRamCost: 1,
|
||||
ScriptWeakenRamCost: 0.15,
|
||||
@@ -520,11 +521,16 @@ export let CONSTANTS: IMap<any> = {
|
||||
|
||||
* Added getOrders() Netscript function to the TIX API
|
||||
* Added getAugmentationPrereq() Singularity function (by havocmayhem)
|
||||
* Added hackAnalyzePercent() and hackAnalyzeThreads() Netscript functions
|
||||
* Stock Market, Travel, and Corporation main menu links are now properly styled
|
||||
* Many pop-up/dialog boxes now support the 'Enter' and 'Esc' hotkeys. If you find a pop-up/dialog box that doesnt support this, let me know specifically which one ('Enter' for the default option, 'Esc' for cancelling and closing the pop-up box)
|
||||
* Added "brace_style = preserve_inline" configuration to Script Editor Beautifier
|
||||
* ServerProfiler.exe can now be purchased from the Dark Web
|
||||
* Added an option to copy save data to clipboard
|
||||
* Added total multiplier information on the "Augmentations" page
|
||||
* Bug Fix: gymWorkout() Singularity function should now work properly with Millenium Fitness Gym
|
||||
* Began migrating gameplay information to the ReadTheDocs documentation
|
||||
*
|
||||
`
|
||||
|
||||
}
|
||||
|
||||
@@ -1265,6 +1265,11 @@ Industry.prototype.createResearchBox = function() {
|
||||
// Add Event Listeners for all Nodes
|
||||
const allResearch = researchTree.getAllNodes();
|
||||
for (let i = 0; i < allResearch.length; ++i) {
|
||||
// If this is already Researched, skip it
|
||||
if (this.researched[allResearch[i]] === true) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get the Research object
|
||||
const research = ResearchMap[allResearch[i]];
|
||||
|
||||
@@ -3842,11 +3847,12 @@ Corporation.prototype.updateCorporationOverviewContent = function() {
|
||||
const dividendsPerShare = totalDividends / TOTALSHARES;
|
||||
const playerEarnings = this.numShares * dividendsPerShare;
|
||||
|
||||
dividendStr = `Retained Profits (after dividends): ${numeralWrapper.format(retainedEarnings, "$0.000a")} / s<br>` +
|
||||
dividendStr = `Dividend Percentage: ${numeralWrapper.format(this.dividendPercentage / 100, "0%")}<br>` +
|
||||
`Retained Profits (after dividends): ${numeralWrapper.format(retainedEarnings, "$0.000a")} / s<br>` +
|
||||
`Dividends per share: ${numeralWrapper.format(dividendsPerShare, "$0.000a")} / s<br>` +
|
||||
`Your earnings (Pre-Tax): ${numeralWrapper.format(playerEarnings, "$0.000a")} / s<br>` +
|
||||
`Your earnings as a shareholder (Pre-Tax): ${numeralWrapper.format(playerEarnings, "$0.000a")} / s<br>` +
|
||||
`Dividend Tax Rate: ${this.dividendTaxPercentage}%<br>` +
|
||||
`Your earnings (Post-Tax): ${numeralWrapper.format(playerEarnings * (this.dividendTaxPercentage / 100), "$0.000a")} / s<br>`;
|
||||
`Your earnings as a shareholder (Post-Tax): ${numeralWrapper.format(playerEarnings * (this.dividendTaxPercentage / 100), "$0.000a")} / s<br>`;
|
||||
}
|
||||
|
||||
var txt = "Total Funds: " + numeralWrapper.format(this.funds.toNumber(), '$0.000a') + "<br>" +
|
||||
@@ -4186,9 +4192,6 @@ Corporation.prototype.displayDivisionContent = function(division, city) {
|
||||
id: "cmpy-mgmt-employee-p",
|
||||
display:"block",
|
||||
innerHTML: "<h1>Office Space</h1><br>" +
|
||||
"Type: " + office.tier + "<br>" +
|
||||
"Comfort: " + office.comf + "<br>" +
|
||||
"Beauty: " + office.beau + "<br>" +
|
||||
"Size: " + office.employees.length + " / " + office.size + " employees",
|
||||
});
|
||||
industryEmployeePanel.appendChild(industryEmployeeText);
|
||||
@@ -4640,9 +4643,6 @@ Corporation.prototype.updateDivisionContent = function(division) {
|
||||
var office = division.offices[currentCityUi];
|
||||
industryEmployeeText.innerHTML =
|
||||
"<h1>Office Space</h1><br>" +
|
||||
"Type: " + office.tier + "<br>" +
|
||||
"Comfort: " + office.comf + "<br>" +
|
||||
"Beauty: " + office.beau + "<br>" +
|
||||
"Size: " + office.employees.length + " / " + office.size + " employees";
|
||||
if (office.employees.length >= office.size) {
|
||||
industryEmployeeHireButton.className = "a-link-button-inactive";
|
||||
@@ -4657,12 +4657,13 @@ Corporation.prototype.updateDivisionContent = function(division) {
|
||||
|
||||
//Employee Overview stats
|
||||
//Calculate average morale, happiness, and energy
|
||||
var totalMorale = 0, totalHappiness = 0, totalEnergy = 0,
|
||||
var totalMorale = 0, totalHappiness = 0, totalEnergy = 0, totalSalary = 0,
|
||||
avgMorale = 0, avgHappiness = 0, avgEnergy = 0;
|
||||
for (var i = 0; i < office.employees.length; ++i) {
|
||||
for (let i = 0; i < office.employees.length; ++i) {
|
||||
totalMorale += office.employees[i].mor;
|
||||
totalHappiness += office.employees[i].hap;
|
||||
totalEnergy += office.employees[i].ene;
|
||||
totalSalary += office.employees[i].sal;
|
||||
}
|
||||
if (office.employees.length > 0) {
|
||||
avgMorale = totalMorale / office.employees.length;
|
||||
@@ -4672,7 +4673,8 @@ Corporation.prototype.updateDivisionContent = function(division) {
|
||||
industryEmployeeInfo.innerHTML =
|
||||
"Avg Employee Morale: " + formatNumber(avgMorale, 3) + "<br>" +
|
||||
"Avg Employee Happiness: " + formatNumber(avgHappiness, 3) + "<br>" +
|
||||
"Avg Employee Energy: " + formatNumber(avgEnergy, 3);
|
||||
"Avg Employee Energy: " + formatNumber(avgEnergy, 3) + "<br>" +
|
||||
"Total Employee Salary: " + numeralWrapper.format(totalSalary, "$0.000a");
|
||||
if (vechain) { //VeChain - Statistics
|
||||
industryEmployeeInfo.appendChild(createElement("br", {}));
|
||||
industryEmployeeInfo.appendChild(createElement("p", {
|
||||
|
||||
@@ -408,6 +408,46 @@ function NetscriptFunctions(workerScript) {
|
||||
}
|
||||
});
|
||||
},
|
||||
hackAnalyzeThreads : function(ip, hackAmount) {
|
||||
if (workerScript.checkingRam) {
|
||||
return updateStaticRam("hackAnalyzeThreads", CONSTANTS.ScriptHackAnalyzeRamCost);
|
||||
}
|
||||
updateDynamicRam("hackAnalyzeThreads", CONSTANTS.ScriptHackAnalyzeRamCost);
|
||||
|
||||
// Check argument validity
|
||||
const server = safeGetServer(ip, 'hackAnalyzeThreads');
|
||||
if (isNaN(hackAmount)) {
|
||||
throw makeRuntimeRejectMsg(workerScript, `Invalid growth argument passed into growthAnalyze: ${hackAmount}. Must be numeric`);
|
||||
}
|
||||
|
||||
if (hackAmount < 0 || hackAmount > server.moneyAvailable) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
const percentHacked = calculatePercentMoneyHacked(server);
|
||||
|
||||
return hackAmount / Math.floor(server.moneyAvailable * percentHacked);
|
||||
},
|
||||
hackAnalyzePercent : function(ip) {
|
||||
if (workerScript.checkingRam) {
|
||||
return updateStaticRam("hackAnalyzePercent", CONSTANTS.ScriptHackAnalyzeRamCost);
|
||||
}
|
||||
updateDynamicRam("hackAnalyzePercent", CONSTANTS.ScriptHackAnalyzeRamCost);
|
||||
|
||||
const server = safeGetServer(ip, 'hackAnalyzePercent');
|
||||
|
||||
return calculatePercentMoneyHacked(server) * 100;
|
||||
},
|
||||
hackChance : function(ip) {
|
||||
if (workerScript.checkingRam) {
|
||||
return updateStaticRam("hackChance", CONSTANTS.ScriptHackAnalyzeRamCost);
|
||||
}
|
||||
updateDynamicRam("hackChance", CONSTANTS.ScriptHackAnalyzeRamCost);
|
||||
|
||||
const server = safeGetServer(ip, 'hackChance');
|
||||
|
||||
return calculateHackingChance(server);
|
||||
},
|
||||
sleep : function(time){
|
||||
if (workerScript.checkingRam) {return 0;}
|
||||
if (time === undefined) {
|
||||
@@ -2626,7 +2666,7 @@ function NetscriptFunctions(workerScript) {
|
||||
costMult = 20;
|
||||
expMult = 10;
|
||||
break;
|
||||
case Locations.VolhavenMilleniumFitnessGym:
|
||||
case Locations.VolhavenMilleniumFitnessGym.toLowerCase():
|
||||
if (Player.city != Locations.Volhaven) {
|
||||
workerScript.scriptRef.log("ERROR: You cannot workout at Millenium Fitness Gym because you are not in Volhaven. gymWorkout() failed");
|
||||
return false;
|
||||
|
||||
@@ -325,7 +325,7 @@ const Engine = {
|
||||
loadAugmentationsContent: function() {
|
||||
Engine.hideAllContent();
|
||||
Engine.Display.augmentationsContent.style.display = "block";
|
||||
displayAugmentationsContent();
|
||||
displayAugmentationsContent(Engine.Display.augmentationsContent);
|
||||
routing.navigateTo(Page.Augmentations);
|
||||
document.getElementById("augmentations-menu-link").classList.add("active");
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user