mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2026-04-17 06:48:42 +02:00
Added growthAnalyze() NS function. Fixed GH issue #492. In Gang mechanic, added new hacking augs/upgrades. Also rebalanced defense upgrades. Added new 'compact' main menu configuration
This commit is contained in:
@@ -39,6 +39,19 @@
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.mainmenu.compact > li a,
|
||||
.mainmenu.compact > li button {
|
||||
display: block;
|
||||
color: #e6e6e6;
|
||||
background-color: #555;
|
||||
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
/* Hovering makes them lighter */
|
||||
.mainmenu > li a:hover,
|
||||
.mainmenu > li a:hover:not(.active),
|
||||
@@ -73,7 +86,8 @@
|
||||
}
|
||||
|
||||
/* Accordion Outline */
|
||||
.mainmenu-accordion-header {
|
||||
.mainmenu-accordion-header,
|
||||
.mainmenu-accordion-header-compact {
|
||||
outline: 2px solid #fff !important;
|
||||
}
|
||||
|
||||
@@ -83,7 +97,8 @@
|
||||
}
|
||||
|
||||
/* Plus and minus signs */
|
||||
.mainmenu-accordion-header:after {
|
||||
.mainmenu-accordion-header:after,
|
||||
.mainmenu-accordion-header-compact:after {
|
||||
content: '\02795';
|
||||
float: right;
|
||||
font-size: $defaultFontSize * 0.8125;
|
||||
@@ -103,8 +118,9 @@
|
||||
}
|
||||
|
||||
.mainmenu-accordion-header.opened,
|
||||
.mainmenu-accordion-header-classic.opened {
|
||||
background-color: #222;
|
||||
.mainmenu-accordion-header-classic.opened,
|
||||
.mainmenu-accordion-header-compact.opened {
|
||||
background-color: #222 !important;
|
||||
|
||||
&:after {
|
||||
content: "\2796";
|
||||
|
||||
@@ -56,7 +56,7 @@ weaken
|
||||
|
||||
.. js:function:: weaken(hostname/ip)
|
||||
|
||||
:param string hostname.ip: IP or hostname of the target server to weaken
|
||||
:param string hostname/ip: IP or hostname of the target server to weaken
|
||||
:returns: The amount by which the target server's security level was decreased. This is equivalent to 0.05 multiplied
|
||||
by the number of script threads
|
||||
:RAM cost: 0.15 GB
|
||||
@@ -72,6 +72,31 @@ weaken
|
||||
|
||||
weaken("foodnstuff");
|
||||
|
||||
growthAnalyze
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
.. js:function:: growthAnalyze(hostname/ip, growthAmount)
|
||||
|
||||
:param string hostname/ip: IP or hostname of server to analyze
|
||||
:param number growthAmount: Multiplicative factor by which the server is grown. Decimal form.
|
||||
:returns: The amount of grow() calls needed to grow the specified server by the specified amount
|
||||
:RAM cost: 1 GB
|
||||
|
||||
This function returns the number of "growths" needed in order to increase the amount
|
||||
of money available on the specified server by the specified amount.
|
||||
|
||||
The specified amount is multiplicative and is in decimal form, not percentage.
|
||||
|
||||
For example, if you want to determine how many `grow()` calls you need
|
||||
to double the amount of money on `foodnstuff`, you would use::
|
||||
|
||||
growthAnalyze("foodnstuff", 2);
|
||||
|
||||
If this returns 100, then this means you need to call `grow()` 100 times
|
||||
in order to double the money (or once with 100 threads).
|
||||
|
||||
**Warning**: The value returned by this function isn't necessarily a whole number.
|
||||
|
||||
sleep
|
||||
^^^^^
|
||||
|
||||
|
||||
@@ -187,6 +187,23 @@ getEquipmentCost
|
||||
:returns: Cost to purchase the specified Equipment/Augmentation (number). Infinity
|
||||
for invalid arguments
|
||||
|
||||
getEquipmentType
|
||||
----------------
|
||||
|
||||
.. js:function:: getEquipmentType(equipName)
|
||||
|
||||
:param string equipName: Name of equipment
|
||||
|
||||
Get the specified equipment type, which can be one of the following:
|
||||
|
||||
* Weapon
|
||||
* Armor
|
||||
* Vehicle
|
||||
* Rootkit
|
||||
* Augmentation
|
||||
|
||||
:returns: A string stating the type of the equipment
|
||||
|
||||
purchaseEquipment
|
||||
-----------------
|
||||
|
||||
|
||||
@@ -59,7 +59,8 @@ var TextHighlightRules = acequire("./text_highlight_rules").TextHighlightRules;
|
||||
var identifierRe = "[a-zA-Z\\$_\u00a1-\uffff][a-zA-Z\\d\\$_\u00a1-\uffff]*";
|
||||
|
||||
let NetscriptFunctions =
|
||||
"hack|sleep|grow|weaken|print|tprint|scan|nuke|brutessh|ftpcrack|" + //Netscript functions
|
||||
"hack|sleep|grow|weaken|growthAnalyze|print|tprint|scan|nuke|brutessh|" +
|
||||
"ftpcrack|" +
|
||||
"clearLog|disableLog|enableLog|isLogEnabled|getScriptLogs|" +
|
||||
"relaysmtp|httpworm|sqlinject|run|exec|spawn|kill|killall|exit|" +
|
||||
"scp|ls|ps|hasRootAccess|" +
|
||||
@@ -106,7 +107,8 @@ let NetscriptFunctions =
|
||||
"gang|" +
|
||||
"getMemberNames|getGangInformation|getMemberInformation|canRecruitMember|" +
|
||||
"recruitMember|getTaskNames|setMemberTask|getEquipmentNames|" +
|
||||
"getEquipmentCost|purchaseEquipment|ascendMember|setTerritoryWarfare|" +
|
||||
"getEquipmentCost|getEquipmentType|purchaseEquipment|ascendMember|" +
|
||||
"setTerritoryWarfare|" +
|
||||
"getChanceToWinClash|getBonusTime|" +
|
||||
|
||||
// Bladeburner API
|
||||
|
||||
@@ -34,7 +34,7 @@ CharacterOverview.prototype.update = function() {
|
||||
|
||||
let changed = false;
|
||||
changed = replaceAndChanged(this.hp, Player.hp + " / " + Player.max_hp) || changed;
|
||||
changed = replaceAndChanged(this.money, numeralWrapper.format(Player.money.toNumber(), '($0.000a)')) || changed;
|
||||
changed = replaceAndChanged(this.money, numeralWrapper.format(Player.money.toNumber(), '$0.000a')) || changed;
|
||||
changed = replaceAndChanged(this.hack, (Player.hacking_skill).toLocaleString()) || changed;
|
||||
changed = replaceAndChanged(this.str, (Player.strength).toLocaleString()) || changed;
|
||||
changed = replaceAndChanged(this.def, (Player.defense).toLocaleString()) || changed;
|
||||
|
||||
@@ -56,6 +56,7 @@ export let CONSTANTS: IMap<any> = {
|
||||
ScriptIfRamCost: 0,
|
||||
ScriptHackRamCost: 0.1,
|
||||
ScriptGrowRamCost: 0.15,
|
||||
ScriptGrowthAnalyzeRamCost: 1,
|
||||
ScriptWeakenRamCost: 0.15,
|
||||
ScriptScanRamCost: 0.2,
|
||||
ScriptPortProgramRamCost: 0.05,
|
||||
@@ -507,17 +508,23 @@ export let CONSTANTS: IMap<any> = {
|
||||
v0.41.2
|
||||
* IMPORTANT - Netscript Changes:
|
||||
** rm() now takes an optional parameter that lets you specify on which server to delete the file
|
||||
** Added growthAnalyze() Netscript function
|
||||
|
||||
* Gang Changes:
|
||||
** UI now displays your chance to win a clash with other gangs
|
||||
** Added getChanceToWinClash() function to the Gang API
|
||||
** Added several new hacking-based equipment and Augmentations
|
||||
** Rebalanced several equipment/upgrades to give less defense
|
||||
|
||||
* Added new Main Menu configuration in .fconf: "compact"
|
||||
* Added the terminal command 'expr', which can be used to evaluate simple mathematical expressions
|
||||
* Bug Fix: scp() should no longer throw errors when used with 2-arguments and an array of files
|
||||
* Bug Fix: Coding Contracts no longer give money in BitNode-8
|
||||
* Bug Fix: In Bladeburner, you can no longer start a BlackOp through the Netscript API if it has already been completed
|
||||
* Bug Fix: In Bladeburner, fixed a bug which caused the configured 'automate' actions to occasionally be switched to other actions
|
||||
* Bug Fix: 'Return to World' button at locations no longer accumulates event listeners
|
||||
* Bug Fix: Working & taking classes now continuously add/subtract money during the action, instead of doing it only at completion
|
||||
* Bug Fix: Top-right overview panel now displays negative money using '-' instead of '()'
|
||||
`
|
||||
|
||||
}
|
||||
|
||||
@@ -385,14 +385,17 @@ function displayFactionContent(factionName) {
|
||||
gangDiv.appendChild(gangDivWrapper);
|
||||
gangDivWrapper.appendChild(createElement("a", {
|
||||
class:"a-link-button", innerText:"Manage Gang",
|
||||
clickListener:()=>{
|
||||
clickListener: () => {
|
||||
if (!Player.inGang()) {
|
||||
// Determine whether this is a hacking gang
|
||||
let hacking = false;
|
||||
if (factionName === "NiteSec" || factionName === "The Black Hand") { hacking = true; }
|
||||
|
||||
// Configure Yes/No buttons for the pop-up
|
||||
var yesBtn = yesNoBoxGetYesButton(), noBtn = yesNoBoxGetNoButton();
|
||||
yesBtn.innerHTML = "Create Gang";
|
||||
noBtn.innerHTML = "Cancel";
|
||||
yesBtn.addEventListener("click", () => {
|
||||
var hacking = false;
|
||||
if (factionName === "NiteSec" || factionName === "The Black Hand") {hacking = true;}
|
||||
Player.startGang(factionName, hacking);
|
||||
document.getElementById("world-menu-header").click();
|
||||
document.getElementById("world-menu-header").click();
|
||||
@@ -402,10 +405,24 @@ function displayFactionContent(factionName) {
|
||||
noBtn.addEventListener("click", () => {
|
||||
yesNoBoxClose();
|
||||
});
|
||||
yesNoBoxCreate("Would you like to create a new Gang with " + factionName + "?<br><br>" +
|
||||
|
||||
// Pop-up text
|
||||
let gangTypeText = "";
|
||||
if (hacking) {
|
||||
gangTypeText = "This is a HACKING gang. Members in this gang will have different tasks than COMBAT gangs. " +
|
||||
"Compared to combat gangs, progression with hacking gangs is more straightforward as territory warfare " +
|
||||
"is not as important.<br><br>";
|
||||
} else {
|
||||
gangTypeText = "This is a COMBAT gang. Members in this gang will have different tasks than HACKING gangs. " +
|
||||
"Compared to hacking gangs, progression with combat gangs can be more difficult as territory management " +
|
||||
"is more important. However, well-managed combat gangs can progress faster than hacking ones.<br><br>";
|
||||
}
|
||||
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");
|
||||
"this BitNode is destroyed.<br><br>" +
|
||||
gangTypeText +
|
||||
"Other than hacking vs combat, 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();
|
||||
}
|
||||
|
||||
12
src/Fconf.js
12
src/Fconf.js
@@ -23,7 +23,7 @@ var FconfComments = {
|
||||
ENABLE_TIMESTAMPS: "Terminal commands and log entries will be timestamped. The timestamp\n" +
|
||||
"will have the format: M/D h:m",
|
||||
MAIN_MENU_STYLE: "Customize the main navigation menu on the left-hand side. Current options:\n\n" +
|
||||
"default, classic",
|
||||
"default, classic, compact",
|
||||
THEME_BACKGROUND_COLOR: "Sets the background color for not only the Terminal, but also for\n" +
|
||||
"most of the game's UI.\n\n" +
|
||||
"The color must be specified as a pound sign (#) followed by a \n" +
|
||||
@@ -46,7 +46,7 @@ var FconfComments = {
|
||||
"before its effect takes place.",
|
||||
}
|
||||
|
||||
const MainMenuStyleOptions = ["default", "classic"];
|
||||
const MainMenuStyleOptions = ["default", "classic", "compact"];
|
||||
|
||||
//Parse Fconf settings from the config text
|
||||
//Throws an exception if parsing fails
|
||||
@@ -231,12 +231,18 @@ function setMainMenuStyle() {
|
||||
if (FconfSettings["MAIN_MENU_STYLE"] === "default") {
|
||||
removeAllAccordionHeaderClasses();
|
||||
mainMenu.classList.remove("classic");
|
||||
mainMenu.classList.remove("compact");
|
||||
addClassToAllAccordionHeaders("mainmenu-accordion-header");
|
||||
|
||||
} else if (FconfSettings["MAIN_MENU_STYLE"] === "classic") {
|
||||
removeAllAccordionHeaderClasses();
|
||||
mainMenu.classList.remove("compact");
|
||||
mainMenu.classList.add("classic");
|
||||
addClassToAllAccordionHeaders("mainmenu-accordion-header-classic");
|
||||
} else if (FconfSettings["MAIN_MENU_STYLE"] === "compact") {
|
||||
removeAllAccordionHeaderClasses();
|
||||
mainMenu.classList.remove("classic");
|
||||
mainMenu.classList.add("compact");
|
||||
addClassToAllAccordionHeaders("mainmenu-accordion-header-compact");
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
40
src/Gang.js
40
src/Gang.js
@@ -533,6 +533,27 @@ Gang.prototype.getUpgradeCost = function(upgName) {
|
||||
return GangMemberUpgrades[upgName].getCost(this);
|
||||
}
|
||||
|
||||
// Returns a player-friendly string stating the type of the specified upgrade
|
||||
Gang.prototype.getUpgradeType = function(upgName) {
|
||||
const upg = GangMemberUpgrades[upgName];
|
||||
if (upg == null) { return ""; }
|
||||
|
||||
switch (upg.type) {
|
||||
case "w":
|
||||
return "Weapon";
|
||||
case "a":
|
||||
return "Armor";
|
||||
case "v":
|
||||
return "Vehicle";
|
||||
case "r":
|
||||
return "Rootkit";
|
||||
case "g":
|
||||
return "Augmentation";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
Gang.prototype.toJSON = function() {
|
||||
return Generic_toJSON("Gang", this);
|
||||
}
|
||||
@@ -1858,6 +1879,25 @@ Gang.prototype.updateGangMemberDisplayElement = function(memberObj) {
|
||||
`Wanted Level: ${formatNumber(5*memberObj.calculateWantedLevelGain(this), 6)} / sec`,
|
||||
`Total Respect Earned: ${formatNumber(memberObj.earnedRespect, 6)}`].join("<br>");
|
||||
}
|
||||
|
||||
// Update selector to have the correct task
|
||||
const taskSelector = document.getElementById(name + "gang-member-task-selector");
|
||||
if (taskSelector) {
|
||||
let tasks = this.getAllTaskNames();
|
||||
tasks.unshift("---");
|
||||
|
||||
if (GangMemberTasks.hasOwnProperty(memberObj.task)) {
|
||||
const taskName = memberObj.task;
|
||||
let taskIndex = 0;
|
||||
for (let i = 0; i < tasks.length; ++i) {
|
||||
if (taskName === tasks[i]) {
|
||||
taskIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
taskSelector.selectedIndex = taskIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Gang.prototype.setGangMemberTaskDescription = function(memberObj, taskName) {
|
||||
|
||||
@@ -33,7 +33,7 @@ import {Script, findRunningScript, RunningScript,
|
||||
isScriptFilename} from "./Script";
|
||||
import {Server, getServer, AddToAllServers,
|
||||
AllServers, processSingleServerGrowth,
|
||||
GetServerByHostname} from "./Server";
|
||||
GetServerByHostname, numCycleForGrowth} from "./Server";
|
||||
import {Settings} from "./Settings";
|
||||
import {SpecialServerIps} from "./SpecialServerIps";
|
||||
import {Stock} from "./Stock";
|
||||
@@ -463,7 +463,21 @@ function NetscriptFunctions(workerScript) {
|
||||
return Promise.resolve(moneyAfter/moneyBefore);
|
||||
});
|
||||
},
|
||||
weaken : function(ip){
|
||||
growthAnalyze : function(ip, growth) {
|
||||
if (workerScript.checkingRam) {
|
||||
return updateStaticRam("growthAnalyze", CONSTANTS.ScriptGrowthAnalyzeRamCost);
|
||||
}
|
||||
updateDynamicRam("growthAnalyze", CONSTANTS.ScriptGrowthAnalyzeRamCost);
|
||||
|
||||
// Check argument validity
|
||||
const server = safeGetServer(ip, 'growthAnalyze');
|
||||
if (isNaN(growth)) {
|
||||
throw makeRuntimeRejectMsg(workerScript, `Invalid growth argument passed into growthAnalyze: ${growth}. Must be numeric`);
|
||||
}
|
||||
|
||||
return numCycleForGrowth(server, Number(growth));
|
||||
},
|
||||
weaken : function(ip) {
|
||||
if (workerScript.checkingRam) {
|
||||
return updateStaticRam("weaken", CONSTANTS.ScriptWeakenRamCost);
|
||||
}
|
||||
@@ -3869,6 +3883,19 @@ function NetscriptFunctions(workerScript) {
|
||||
throw makeRuntimeRejectMsg(workerScript, nsGang.unknownGangApiExceptionMessage("getEquipmentCost", e));
|
||||
}
|
||||
},
|
||||
getEquipmentType : function(equipName) {
|
||||
if (workerScript.checkingRam) {
|
||||
return updateStaticRam("getEquipmentType", CONSTANTS.ScriptGangApiBaseRamCost / 2);
|
||||
}
|
||||
updateDynamicRam("getEquipmentType", CONSTANTS.ScriptGangApiBaseRamCost / 2);
|
||||
nsGang.checkGangApiAccess(workerScript, "getEquipmentType");
|
||||
|
||||
try {
|
||||
return Player.gang.getUpgradeType(equipName);
|
||||
} catch(e) {
|
||||
throw makeRuntimeRejectMsg(workerScript, nsGang.unknownGangApiExceptionMessage("getEquipmentType", e));
|
||||
}
|
||||
},
|
||||
purchaseEquipment : function(memberName, equipName) {
|
||||
if (workerScript.checkingRam) {
|
||||
return updateStaticRam("purchaseEquipment", CONSTANTS.ScriptGangApiBaseRamCost);
|
||||
|
||||
@@ -639,12 +639,13 @@ PlayerObject.prototype.resetWorkStatus = function() {
|
||||
}
|
||||
|
||||
PlayerObject.prototype.processWorkEarnings = function(numCycles=1) {
|
||||
var hackExpGain = this.workHackExpGainRate * numCycles;
|
||||
var strExpGain = this.workStrExpGainRate * numCycles;
|
||||
var defExpGain = this.workDefExpGainRate * numCycles;
|
||||
var dexExpGain = this.workDexExpGainRate * numCycles;
|
||||
var agiExpGain = this.workAgiExpGainRate * numCycles;
|
||||
var chaExpGain = this.workChaExpGainRate * numCycles;
|
||||
const hackExpGain = this.workHackExpGainRate * numCycles;
|
||||
const strExpGain = this.workStrExpGainRate * numCycles;
|
||||
const defExpGain = this.workDefExpGainRate * numCycles;
|
||||
const dexExpGain = this.workDexExpGainRate * numCycles;
|
||||
const agiExpGain = this.workAgiExpGainRate * numCycles;
|
||||
const chaExpGain = this.workChaExpGainRate * numCycles;
|
||||
const moneyGain = (this.workMoneyGainRate - this.workMoneyLossRate) * numCycles;
|
||||
|
||||
this.gainHackingExp(hackExpGain);
|
||||
this.gainStrengthExp(strExpGain);
|
||||
@@ -652,6 +653,7 @@ PlayerObject.prototype.processWorkEarnings = function(numCycles=1) {
|
||||
this.gainDexterityExp(dexExpGain);
|
||||
this.gainAgilityExp(agiExpGain);
|
||||
this.gainCharismaExp(chaExpGain);
|
||||
this.gainMoney(moneyGain);
|
||||
this.workHackExpGained += hackExpGain;
|
||||
this.workStrExpGained += strExpGain;
|
||||
this.workDefExpGained += defExpGain;
|
||||
@@ -744,8 +746,6 @@ PlayerObject.prototype.finishWork = function(cancelled, sing=false) {
|
||||
var company = Companies[this.companyName];
|
||||
company.playerReputation += (this.workRepGained);
|
||||
|
||||
this.gainMoney(this.workMoneyGained);
|
||||
|
||||
this.updateSkillLevels();
|
||||
|
||||
var txt = "You earned a total of: <br>" +
|
||||
@@ -862,8 +862,6 @@ PlayerObject.prototype.finishWorkPartTime = function(sing=false) {
|
||||
var company = Companies[this.companyName];
|
||||
company.playerReputation += (this.workRepGained);
|
||||
|
||||
this.gainMoney(this.workMoneyGained);
|
||||
|
||||
this.updateSkillLevels();
|
||||
|
||||
var txt = "You earned a total of: <br>" +
|
||||
@@ -1031,8 +1029,6 @@ PlayerObject.prototype.finishFactionWork = function(cancelled, sing=false) {
|
||||
var faction = Factions[this.currentWorkFactionName];
|
||||
faction.playerReputation += (this.workRepGained);
|
||||
|
||||
this.gainMoney(this.workMoneyGained);
|
||||
|
||||
this.updateSkillLevels();
|
||||
|
||||
var txt = "You worked for your faction " + faction.name + " for a total of " + convertTimeMsToTimeElapsedString(this.timeWorked) + " <br><br> " +
|
||||
@@ -1424,7 +1420,6 @@ PlayerObject.prototype.finishClass = function(sing=false) {
|
||||
if (this.workMoneyGained > 0) {
|
||||
throw new Error("ERR: Somehow gained money while taking class");
|
||||
}
|
||||
this.loseMoney(this.workMoneyGained * -1);
|
||||
|
||||
this.updateSkillLevels();
|
||||
var txt = "After " + this.className + " for " + convertTimeMsToTimeElapsedString(this.timeWorked) + ", <br>" +
|
||||
|
||||
@@ -206,7 +206,7 @@ Server.fromJSON = function(value) {
|
||||
|
||||
Reviver.constructors.Server = Server;
|
||||
|
||||
function initForeignServers() {
|
||||
export function initForeignServers() {
|
||||
/* Create a randomized network for all the foreign servers */
|
||||
//Groupings for creating a randomized network
|
||||
const networkLayers = [];
|
||||
@@ -287,7 +287,9 @@ function initForeignServers() {
|
||||
}
|
||||
}
|
||||
|
||||
function numCycleForGrowth(server, growth) {
|
||||
// Returns the number of cycles needed to grow the specified server by the
|
||||
// specified amount. 'growth' parameter is in decimal form, not percentage
|
||||
export function numCycleForGrowth(server, growth) {
|
||||
let ajdGrowthRate = 1 + (CONSTANTS.ServerBaseGrowthRate - 1) / server.hackDifficulty;
|
||||
if(ajdGrowthRate > CONSTANTS.ServerMaxGrowthRate) {
|
||||
ajdGrowthRate = CONSTANTS.ServerMaxGrowthRate;
|
||||
@@ -300,7 +302,7 @@ function numCycleForGrowth(server, growth) {
|
||||
}
|
||||
|
||||
//Applied server growth for a single server. Returns the percentage growth
|
||||
function processSingleServerGrowth(server, numCycles) {
|
||||
export function processSingleServerGrowth(server, numCycles) {
|
||||
//Server growth processed once every 450 game cycles
|
||||
const numServerGrowthCycles = Math.max(Math.floor(numCycles / 450), 0);
|
||||
|
||||
@@ -334,7 +336,7 @@ function processSingleServerGrowth(server, numCycles) {
|
||||
}
|
||||
|
||||
// if there was any growth at all, increase security
|
||||
if(oldMoneyAvailable !== server.moneyAvailable) {
|
||||
if (oldMoneyAvailable !== server.moneyAvailable) {
|
||||
//Growing increases server security twice as much as hacking
|
||||
let usedCycles = numCycleForGrowth(server, server.moneyAvailable / oldMoneyAvailable);
|
||||
usedCycles = Math.max(0, usedCycles);
|
||||
@@ -343,7 +345,7 @@ function processSingleServerGrowth(server, numCycles) {
|
||||
return server.moneyAvailable / oldMoneyAvailable;
|
||||
}
|
||||
|
||||
function prestigeHomeComputer(homeComp) {
|
||||
export function prestigeHomeComputer(homeComp) {
|
||||
const hasBitflume = homeComp.programs.includes(Programs.BitFlume.name);
|
||||
|
||||
homeComp.programs.length = 0; //Remove programs
|
||||
@@ -366,14 +368,14 @@ function prestigeHomeComputer(homeComp) {
|
||||
//List of all servers that exist in the game, indexed by their ip
|
||||
let AllServers = {};
|
||||
|
||||
function prestigeAllServers() {
|
||||
export function prestigeAllServers() {
|
||||
for (var member in AllServers) {
|
||||
delete AllServers[member];
|
||||
}
|
||||
AllServers = {};
|
||||
}
|
||||
|
||||
function loadAllServers(saveString) {
|
||||
export function loadAllServers(saveString) {
|
||||
AllServers = JSON.parse(saveString, Reviver);
|
||||
}
|
||||
|
||||
@@ -386,7 +388,7 @@ function SizeOfAllServers() {
|
||||
}
|
||||
|
||||
//Add a server onto the map of all servers in the game
|
||||
function AddToAllServers(server) {
|
||||
export function AddToAllServers(server) {
|
||||
var serverIp = server.ip;
|
||||
if (ipExists(serverIp)) {
|
||||
console.log("IP of server that's being added: " + serverIp);
|
||||
@@ -400,7 +402,7 @@ function AddToAllServers(server) {
|
||||
|
||||
//Returns server object with corresponding hostname
|
||||
// Relatively slow, would rather not use this a lot
|
||||
function GetServerByHostname(hostname) {
|
||||
export function GetServerByHostname(hostname) {
|
||||
for (var ip in AllServers) {
|
||||
if (AllServers.hasOwnProperty(ip)) {
|
||||
if (AllServers[ip].hostname == hostname) {
|
||||
@@ -412,7 +414,7 @@ function GetServerByHostname(hostname) {
|
||||
}
|
||||
|
||||
//Get server by IP or hostname. Returns null if invalid
|
||||
function getServer(s) {
|
||||
export function getServer(s) {
|
||||
if (!isValidIPAddress(s)) {
|
||||
return GetServerByHostname(s);
|
||||
}
|
||||
@@ -459,6 +461,4 @@ Directory.prototype.getPath = function(name) {
|
||||
return res.join("");
|
||||
}
|
||||
|
||||
export {Server, AllServers, getServer, GetServerByHostname, loadAllServers,
|
||||
AddToAllServers, processSingleServerGrowth, initForeignServers,
|
||||
prestigeAllServers, prestigeHomeComputer};
|
||||
export {Server, AllServers};
|
||||
|
||||
@@ -34,31 +34,31 @@ export const gangMemberUpgradesMetadata: IGangMemberUpgradeMetadata[] = [
|
||||
},
|
||||
{
|
||||
cost: 50e6,
|
||||
mults: {str: 1.12, def: 1.12, agi: 1.1},
|
||||
mults: {str: 1.12, def: 1.1, agi: 1.1},
|
||||
name: "P90C",
|
||||
upgType: "w",
|
||||
},
|
||||
{
|
||||
cost: 60e6,
|
||||
mults: {str: 1.2, def: 1.2},
|
||||
mults: {str: 1.2, def: 1.15},
|
||||
name: "Steyr AUG",
|
||||
upgType: "w",
|
||||
},
|
||||
{
|
||||
cost: 100e6,
|
||||
mults: {str: 1.25, def: 1.25},
|
||||
mults: {str: 1.25, def: 1.2},
|
||||
name: "AK-47",
|
||||
upgType: "w",
|
||||
},
|
||||
{
|
||||
cost: 150e6,
|
||||
mults: {str: 1.3, def: 1.3},
|
||||
mults: {str: 1.3, def: 1.25},
|
||||
name: "M15A10 Assault Rifle",
|
||||
upgType: "w",
|
||||
},
|
||||
{
|
||||
cost: 225e6,
|
||||
mults: {str: 1.3, dex: 1.3, agi: 1.3},
|
||||
mults: {str: 1.3, dex: 1.25, agi: 1.3},
|
||||
name: "AWM Sniper Rifle",
|
||||
upgType: "w",
|
||||
},
|
||||
@@ -117,17 +117,29 @@ export const gangMemberUpgradesMetadata: IGangMemberUpgradeMetadata[] = [
|
||||
upgType: "r",
|
||||
},
|
||||
{
|
||||
cost: 15e6,
|
||||
cost: 25e6,
|
||||
mults: {hack: 1.1},
|
||||
name: "Soulstealer Rootkit",
|
||||
upgType: "r",
|
||||
},
|
||||
{
|
||||
cost: 50e6,
|
||||
cost: 75e6,
|
||||
mults: {hack: 1.15},
|
||||
name: "Demon Rootkit",
|
||||
upgType: "r",
|
||||
},
|
||||
{
|
||||
cost: 40e6,
|
||||
mults: {hack: 1.12},
|
||||
name: "Hmap Node",
|
||||
upgType: "r",
|
||||
},
|
||||
{
|
||||
cost: 75e6,
|
||||
mults: {hack: 1.15},
|
||||
name: "Jack the Ripper",
|
||||
upgType: "r",
|
||||
},
|
||||
{
|
||||
cost: 10e9,
|
||||
mults: {str: 1.3, dex: 1.3},
|
||||
@@ -182,6 +194,12 @@ export const gangMemberUpgradesMetadata: IGangMemberUpgradeMetadata[] = [
|
||||
name: "Neuralstimulator",
|
||||
upgType: "g",
|
||||
},
|
||||
{
|
||||
cost: 7.5e9,
|
||||
mults: {hack: 1.1},
|
||||
name: "DataJack",
|
||||
upgType: "g",
|
||||
},
|
||||
{
|
||||
cost: 50e9,
|
||||
mults: {str: 1.7, def: 1.7},
|
||||
|
||||
Reference in New Issue
Block a user