mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2026-04-25 10:42:51 +02:00
Merge pull request #3303 from danielyxie/dev
Re-add some gang augs at random.
This commit is contained in:
@@ -706,7 +706,7 @@ export const generalAugmentations = [
|
||||
"so that the brain doesn't have to.",
|
||||
hacking_speed_mult: 1.01,
|
||||
hacking_mult: 1.05,
|
||||
factions: [FactionNames.CyberSec],
|
||||
factions: [FactionNames.CyberSec, FactionNames.NiteSec],
|
||||
}),
|
||||
new Augmentation({
|
||||
name: AugmentationNames.CranialSignalProcessorsG2,
|
||||
|
||||
@@ -91,14 +91,12 @@ function updateNeuroFluxGovernorCosts(neuroFluxGovernorAugmentation: Augmentatio
|
||||
}
|
||||
|
||||
export function updateAugmentationCosts(): void {
|
||||
console.log(Player.queuedAugmentations);
|
||||
for (const name of Object.keys(Augmentations)) {
|
||||
if (Augmentations.hasOwnProperty(name)) {
|
||||
const augmentationToUpdate = Augmentations[name];
|
||||
if (augmentationToUpdate.name === AugmentationNames.NeuroFluxGovernor) {
|
||||
updateNeuroFluxGovernorCosts(augmentationToUpdate);
|
||||
} else {
|
||||
console.log(augmentationToUpdate.baseCost);
|
||||
augmentationToUpdate.baseCost = augmentationToUpdate.startingCost * getGenericAugmentationPriceMultiplier();
|
||||
}
|
||||
}
|
||||
|
||||
+41
-24
@@ -82,7 +82,9 @@ BitNodes["BitNode2"] = new BitNode(
|
||||
<br />
|
||||
The amount of money gained from crimes and Infiltration is tripled
|
||||
<br />
|
||||
Certain Factions ({FactionNames.SlumSnakes}, {FactionNames.Tetrads}, {FactionNames.TheSyndicate}, {FactionNames.TheDarkArmy}, {FactionNames.SpeakersForTheDead}, {FactionNames.NiteSec}, {FactionNames.TheBlackHand}) give the player the ability to form and manage their own gangs. These gangs will earn the player money and
|
||||
Certain Factions ({FactionNames.SlumSnakes}, {FactionNames.Tetrads}, {FactionNames.TheSyndicate},{" "}
|
||||
{FactionNames.TheDarkArmy}, {FactionNames.SpeakersForTheDead}, {FactionNames.NiteSec}, {FactionNames.TheBlackHand}
|
||||
) 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
|
||||
@@ -225,15 +227,15 @@ BitNodes["BitNode6"] = new BitNode(
|
||||
"Like Tears in Rain",
|
||||
(
|
||||
<>
|
||||
In the middle of the 21st century, {FactionNames.OmniTekIncorporated} began designing and manufacturing advanced synthetic
|
||||
androids, or Synthoids for short. They achieved a major technological breakthrough in the sixth generation of
|
||||
their Synthoid design, called MK-VI, by developing a hyperintelligent AI. Many argue that this was the first
|
||||
sentient AI ever created. This resulted in Synthoid models that were stronger, faster, and more intelligent than
|
||||
the humans that had created them.
|
||||
In the middle of the 21st century, {FactionNames.OmniTekIncorporated} began designing and manufacturing advanced
|
||||
synthetic androids, or Synthoids for short. They achieved a major technological breakthrough in the sixth
|
||||
generation of their Synthoid design, called MK-VI, by developing a hyperintelligent AI. Many argue that this was
|
||||
the first sentient AI ever created. This resulted in Synthoid models that were stronger, faster, and more
|
||||
intelligent than the humans that had created them.
|
||||
<br />
|
||||
<br />
|
||||
In this BitNode you will be able to access the {FactionNames.Bladeburners} Division at the NSA, which provides a new mechanic for
|
||||
progression. Furthermore:
|
||||
In this BitNode you will be able to access the {FactionNames.Bladeburners} Division at the NSA, which provides a
|
||||
new mechanic for progression. Furthermore:
|
||||
<br />
|
||||
<br />
|
||||
Hacking and Hacknet Nodes will be less profitable
|
||||
@@ -250,9 +252,9 @@ BitNodes["BitNode6"] = new BitNode(
|
||||
<br />
|
||||
<br />
|
||||
Destroying this BitNode will give you Source-File 6, or if you already have this Source-File it will upgrade its
|
||||
level up to a maximum of 3. This Source-File allows you to access the NSA's {FactionNames.Bladeburners} Division in other
|
||||
BitNodes. In addition, this Source-File will raise both the level and experience gain rate of all your combat
|
||||
stats by:
|
||||
level up to a maximum of 3. This Source-File allows you to access the NSA's {FactionNames.Bladeburners} Division
|
||||
in other BitNodes. In addition, this Source-File will raise both the level and experience gain rate of all your
|
||||
combat stats by:
|
||||
<br />
|
||||
<br />
|
||||
Level 1: 8%
|
||||
@@ -270,14 +272,15 @@ BitNodes["BitNode7"] = new BitNode(
|
||||
"More human than humans",
|
||||
(
|
||||
<>
|
||||
In the middle of the 21st century, you were doing cutting-edge work at {FactionNames.OmniTekIncorporated} as part of the AI
|
||||
design team for advanced synthetic androids, or Synthoids for short. You helped achieve a major technological
|
||||
breakthrough in the sixth generation of the company's Synthoid design, called MK-VI, by developing a
|
||||
In the middle of the 21st century, you were doing cutting-edge work at {FactionNames.OmniTekIncorporated} as part
|
||||
of the AI design team for advanced synthetic androids, or Synthoids for short. You helped achieve a major
|
||||
technological breakthrough in the sixth generation of the company's Synthoid design, called MK-VI, by developing a
|
||||
hyperintelligent AI. Many argue that this was the first sentient AI ever created. This resulted in Synthoid models
|
||||
that were stronger, faster, and more intelligent than the humans that had created them.
|
||||
<br />
|
||||
<br />
|
||||
In this BitNode you will be able to access the {FactionNames.Bladeburners} API, which allows you to access {FactionNames.Bladeburners}
|
||||
In this BitNode you will be able to access the {FactionNames.Bladeburners} API, which allows you to access{" "}
|
||||
{FactionNames.Bladeburners}
|
||||
functionality through Netscript. Furthermore: <br />
|
||||
<br />
|
||||
The rank you gain from {FactionNames.Bladeburners} contracts/operations is reduced by 40%
|
||||
@@ -300,8 +303,9 @@ BitNodes["BitNode7"] = new BitNode(
|
||||
<br />
|
||||
<br />
|
||||
Destroying this BitNode will give you Source-File 7, or if you already have this Source-File it will upgrade its
|
||||
level up to a maximum of 3. This Source-File allows you to access the {FactionNames.Bladeburners} Netscript API in other BitNodes.
|
||||
In addition, this Source-File will increase all of your {FactionNames.Bladeburners} multipliers by:
|
||||
level up to a maximum of 3. This Source-File allows you to access the {FactionNames.Bladeburners} Netscript API in
|
||||
other BitNodes. In addition, this Source-File will increase all of your {FactionNames.Bladeburners} multipliers
|
||||
by:
|
||||
<br />
|
||||
<br />
|
||||
Level 1: 8%
|
||||
@@ -364,10 +368,10 @@ BitNodes["BitNode9"] = new BitNode(
|
||||
"Hacknet Unleashed",
|
||||
(
|
||||
<>
|
||||
When {FactionNames.FulcrumSecretTechnologies} released their open-source Linux distro Chapeau, it quickly became the OS of choice for
|
||||
the underground hacking community. Chapeau became especially notorious for powering the Hacknet, a global,
|
||||
decentralized network used for nefarious purposes. {FactionNames.FulcrumSecretTechnologies} quickly abandoned the project and dissociated
|
||||
themselves from it.
|
||||
When {FactionNames.FulcrumSecretTechnologies} released their open-source Linux distro Chapeau, it quickly became
|
||||
the OS of choice for the underground hacking community. Chapeau became especially notorious for powering the
|
||||
Hacknet, a global, decentralized network used for nefarious purposes. {FactionNames.FulcrumSecretTechnologies}{" "}
|
||||
quickly abandoned the project and dissociated themselves from it.
|
||||
<br />
|
||||
<br />
|
||||
This BitNode unlocks the Hacknet Server, an upgraded version of the Hacknet Node. Hacknet Servers generate hashes,
|
||||
@@ -538,8 +542,8 @@ BitNodes["BitNode13"] = new BitNode(
|
||||
"1 step back, 2 steps forward",
|
||||
(
|
||||
<>
|
||||
With the invention of Augmentations in the 2040s a religious group known as the {FactionNames.ChurchOfTheMachineGod} has
|
||||
rallied far more support than anyone would have hoped.
|
||||
With the invention of Augmentations in the 2040s a religious group known as the{" "}
|
||||
{FactionNames.ChurchOfTheMachineGod} has rallied far more support than anyone would have hoped.
|
||||
<br />
|
||||
<br />
|
||||
Their leader, Allison "Mother" Stanek is said to have created her own Augmentation whose power goes beyond any
|
||||
@@ -555,7 +559,8 @@ BitNodes["BitNode13"] = new BitNode(
|
||||
<br />
|
||||
<br />
|
||||
Destroying this BitNode will give you Source-File 13, or if you already have this Source-File it will upgrade its
|
||||
level up to a maximum of 3. This Source-File lets the {FactionNames.ChurchOfTheMachineGod} appear in other BitNodes.
|
||||
level up to a maximum of 3. This Source-File lets the {FactionNames.ChurchOfTheMachineGod} appear in other
|
||||
BitNodes.
|
||||
<br />
|
||||
<br />
|
||||
Each level of this Source-File increases the size of Stanek's Gift.
|
||||
@@ -624,6 +629,7 @@ export function initBitNodeMultipliers(p: IPlayer): void {
|
||||
BitNodeMultipliers.PurchasedServerSoftcap = 1.3;
|
||||
BitNodeMultipliers.GangSoftcap = 0.9;
|
||||
BitNodeMultipliers.WorldDaemonDifficulty = 2;
|
||||
BitNodeMultipliers.GangUniqueAugs = 0.5;
|
||||
break;
|
||||
case 4: // The Singularity
|
||||
BitNodeMultipliers.ServerMaxMoney = 0.15;
|
||||
@@ -642,6 +648,7 @@ export function initBitNodeMultipliers(p: IPlayer): void {
|
||||
BitNodeMultipliers.StaneksGiftExtraSize = 0;
|
||||
BitNodeMultipliers.PurchasedServerSoftcap = 1.2;
|
||||
BitNodeMultipliers.WorldDaemonDifficulty = 3;
|
||||
BitNodeMultipliers.GangUniqueAugs = 0.5;
|
||||
break;
|
||||
case 5: // Artificial intelligence
|
||||
BitNodeMultipliers.ServerMaxMoney = 2;
|
||||
@@ -659,6 +666,7 @@ export function initBitNodeMultipliers(p: IPlayer): void {
|
||||
BitNodeMultipliers.StaneksGiftExtraSize = 0;
|
||||
BitNodeMultipliers.PurchasedServerSoftcap = 1.2;
|
||||
BitNodeMultipliers.WorldDaemonDifficulty = 1.5;
|
||||
BitNodeMultipliers.GangUniqueAugs = 0.5;
|
||||
break;
|
||||
case 6: // Bladeburner
|
||||
BitNodeMultipliers.HackingLevelMultiplier = 0.35;
|
||||
@@ -679,6 +687,7 @@ export function initBitNodeMultipliers(p: IPlayer): void {
|
||||
BitNodeMultipliers.GangSoftcap = 0.7;
|
||||
BitNodeMultipliers.CorporationSoftCap = 0.9;
|
||||
BitNodeMultipliers.WorldDaemonDifficulty = 2;
|
||||
BitNodeMultipliers.GangUniqueAugs = 0.2;
|
||||
break;
|
||||
case 7: // Bladeburner 2079
|
||||
BitNodeMultipliers.BladeburnerRank = 0.6;
|
||||
@@ -704,6 +713,7 @@ export function initBitNodeMultipliers(p: IPlayer): void {
|
||||
BitNodeMultipliers.GangSoftcap = 0.7;
|
||||
BitNodeMultipliers.CorporationSoftCap = 0.9;
|
||||
BitNodeMultipliers.WorldDaemonDifficulty = 2;
|
||||
BitNodeMultipliers.GangUniqueAugs = 0.2;
|
||||
break;
|
||||
case 8: // Ghost of Wall Street
|
||||
BitNodeMultipliers.ScriptHackMoney = 0.3;
|
||||
@@ -720,6 +730,7 @@ export function initBitNodeMultipliers(p: IPlayer): void {
|
||||
BitNodeMultipliers.PurchasedServerSoftcap = 4;
|
||||
BitNodeMultipliers.GangSoftcap = 0;
|
||||
BitNodeMultipliers.CorporationSoftCap = 0;
|
||||
BitNodeMultipliers.GangUniqueAugs = 0;
|
||||
break;
|
||||
case 9: // Hacktocracy
|
||||
BitNodeMultipliers.HackingLevelMultiplier = 0.5;
|
||||
@@ -746,6 +757,7 @@ export function initBitNodeMultipliers(p: IPlayer): void {
|
||||
BitNodeMultipliers.GangSoftcap = 0.8;
|
||||
BitNodeMultipliers.CorporationSoftCap = 0.7;
|
||||
BitNodeMultipliers.WorldDaemonDifficulty = 2;
|
||||
BitNodeMultipliers.GangUniqueAugs = 0.25;
|
||||
break;
|
||||
case 10: // Digital Carbon
|
||||
BitNodeMultipliers.HackingLevelMultiplier = 0.35;
|
||||
@@ -775,6 +787,7 @@ export function initBitNodeMultipliers(p: IPlayer): void {
|
||||
BitNodeMultipliers.GangSoftcap = 0.9;
|
||||
BitNodeMultipliers.CorporationSoftCap = 0.9;
|
||||
BitNodeMultipliers.WorldDaemonDifficulty = 2;
|
||||
BitNodeMultipliers.GangUniqueAugs = 0.25;
|
||||
break;
|
||||
case 11: //The Big Crash
|
||||
BitNodeMultipliers.HackingLevelMultiplier = 0.6;
|
||||
@@ -796,6 +809,7 @@ export function initBitNodeMultipliers(p: IPlayer): void {
|
||||
BitNodeMultipliers.PurchasedServerSoftcap = 2;
|
||||
BitNodeMultipliers.CorporationSoftCap = 0.9;
|
||||
BitNodeMultipliers.WorldDaemonDifficulty = 1.5;
|
||||
BitNodeMultipliers.GangUniqueAugs = 0.75;
|
||||
break;
|
||||
case 12: {
|
||||
//The Recursion
|
||||
@@ -870,6 +884,8 @@ export function initBitNodeMultipliers(p: IPlayer): void {
|
||||
BitNodeMultipliers.GangSoftcap = 0.8;
|
||||
BitNodeMultipliers.CorporationSoftCap = 0.8;
|
||||
BitNodeMultipliers.WorldDaemonDifficulty = inc;
|
||||
|
||||
BitNodeMultipliers.GangUniqueAugs = dec;
|
||||
break;
|
||||
}
|
||||
case 13: {
|
||||
@@ -912,6 +928,7 @@ export function initBitNodeMultipliers(p: IPlayer): void {
|
||||
BitNodeMultipliers.GangSoftcap = 0.3;
|
||||
BitNodeMultipliers.CorporationSoftCap = 0.3;
|
||||
BitNodeMultipliers.WorldDaemonDifficulty = 3;
|
||||
BitNodeMultipliers.GangUniqueAugs = 0.1;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
||||
@@ -114,6 +114,11 @@ interface IBitNodeMultipliers {
|
||||
*/
|
||||
GangSoftcap: number;
|
||||
|
||||
/**
|
||||
* Percentage of unique augs that the gang has.
|
||||
*/
|
||||
GangUniqueAugs: number;
|
||||
|
||||
/**
|
||||
* Influences the experienced gained when hacking a server.
|
||||
*/
|
||||
@@ -300,6 +305,7 @@ export const BitNodeMultipliers: IBitNodeMultipliers = {
|
||||
BladeburnerSkillCost: 1,
|
||||
|
||||
GangSoftcap: 1,
|
||||
GangUniqueAugs: 1,
|
||||
|
||||
DaedalusAugsRequirement: 1,
|
||||
|
||||
|
||||
@@ -61,3 +61,35 @@ export class WHRNG implements RNG {
|
||||
return (this.s1 / 30269.0 + this.s2 / 30307.0 + this.s3 / 30323.0) % 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
export function SFC32RNG(seed: string): () => number {
|
||||
let h = 1779033703 ^ seed.length;
|
||||
for (let i = 0; i < seed.length; i++) {
|
||||
h = Math.imul(h ^ seed.charCodeAt(i), 3432918353);
|
||||
h = (h << 13) | (h >>> 19);
|
||||
}
|
||||
const genSeed = (): number => {
|
||||
h = Math.imul(h ^ (h >>> 16), 2246822507);
|
||||
h = Math.imul(h ^ (h >>> 13), 3266489909);
|
||||
return (h ^= h >>> 16) >>> 0;
|
||||
};
|
||||
|
||||
let a = genSeed();
|
||||
let b = genSeed();
|
||||
let c = genSeed();
|
||||
let d = genSeed();
|
||||
return (): number => {
|
||||
a >>>= 0;
|
||||
b >>>= 0;
|
||||
c >>>= 0;
|
||||
d >>>= 0;
|
||||
let t = (a + b) | 0;
|
||||
a = b ^ (b >>> 9);
|
||||
b = (c + (c << 3)) | 0;
|
||||
c = (c << 21) | (c >>> 11);
|
||||
d = (d + 1) | 0;
|
||||
t = (t + d) | 0;
|
||||
c = (c + t) | 0;
|
||||
return (t >>> 0) / 4294967296;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import { CONSTANTS } from "../Constants";
|
||||
import { Faction } from "./Faction";
|
||||
import { Factions } from "./Factions";
|
||||
import { Player } from "../Player";
|
||||
import { IPlayer } from "../PersonObjects/IPlayer";
|
||||
import { Settings } from "../Settings/Settings";
|
||||
import {
|
||||
getHackingWorkRepGain,
|
||||
@@ -19,6 +20,7 @@ import { SourceFileFlags } from "../SourceFile/SourceFileFlags";
|
||||
import { dialogBoxCreate } from "../ui/React/DialogBox";
|
||||
import { InvitationEvent } from "./ui/InvitationModal";
|
||||
import { FactionNames } from "./data/FactionNames";
|
||||
import { SFC32RNG } from "../Casino/RNG";
|
||||
|
||||
export function inviteToFaction(faction: Faction): void {
|
||||
Player.receiveInvite(faction.name);
|
||||
@@ -32,9 +34,8 @@ export function joinFaction(faction: Faction): void {
|
||||
if (faction.isMember) return;
|
||||
faction.isMember = true;
|
||||
Player.factions.push(faction.name);
|
||||
const allFactions = Object.values(FactionNames).map(faction => faction as string)
|
||||
Player.factions.sort((a, b) =>
|
||||
allFactions.indexOf(a) - allFactions.indexOf(b));
|
||||
const allFactions = Object.values(FactionNames).map((faction) => faction as string);
|
||||
Player.factions.sort((a, b) => allFactions.indexOf(a) - allFactions.indexOf(b));
|
||||
const factionInfo = faction.getInfo();
|
||||
|
||||
//Determine what factions you are banned from now that you have joined this faction
|
||||
@@ -134,18 +135,18 @@ export function purchaseAugmentation(aug: Augmentation, fac: Faction, sing = fal
|
||||
} else if (!Settings.SuppressBuyAugmentationConfirmation) {
|
||||
dialogBoxCreate(
|
||||
"You purchased " +
|
||||
aug.name +
|
||||
". Its enhancements will not take " +
|
||||
"effect until they are installed. To install your augmentations, go to the " +
|
||||
"'Augmentations' tab on the left-hand navigation menu. Purchasing additional " +
|
||||
"augmentations will now be more expensive.",
|
||||
aug.name +
|
||||
". Its enhancements will not take " +
|
||||
"effect until they are installed. To install your augmentations, go to the " +
|
||||
"'Augmentations' tab on the left-hand navigation menu. Purchasing additional " +
|
||||
"augmentations will now be more expensive.",
|
||||
);
|
||||
}
|
||||
} else {
|
||||
dialogBoxCreate(
|
||||
"Hmm, something went wrong when trying to purchase an Augmentation. " +
|
||||
"Please report this to the game developer with an explanation of how to " +
|
||||
"reproduce this.",
|
||||
"Please report this to the game developer with an explanation of how to " +
|
||||
"reproduce this.",
|
||||
);
|
||||
}
|
||||
return "";
|
||||
@@ -193,3 +194,43 @@ export function processPassiveFactionRepGain(numCycles: number): void {
|
||||
faction.playerReputation += rate * numCycles * Player.faction_rep_mult * BitNodeMultipliers.FactionPassiveRepGain;
|
||||
}
|
||||
}
|
||||
|
||||
export const getFactionAugmentationsFiltered = (player: IPlayer, faction: Faction): string[] => {
|
||||
// If player has a gang with this faction, return (almost) all augmentations
|
||||
if (player.hasGangWith(faction.name)) {
|
||||
let augs = Object.values(Augmentations);
|
||||
|
||||
// Remove special augs
|
||||
augs = augs.filter((a) => !a.isSpecial);
|
||||
|
||||
const blacklist: string[] = [AugmentationNames.NeuroFluxGovernor];
|
||||
|
||||
if (player.bitNodeN !== 2) {
|
||||
// TRP is not available outside of BN2 for Gangs
|
||||
blacklist.push(AugmentationNames.TheRedPill);
|
||||
}
|
||||
|
||||
const rng = SFC32RNG(`BN${player.bitNodeN}.${player.sourceFileLvl(player.bitNodeN)}`);
|
||||
// Remove faction-unique augs that don't belong to this faction
|
||||
const uniqueFilter = (a: Augmentation): boolean => {
|
||||
// Keep all the non-unique one
|
||||
if (a.factions.length > 1) {
|
||||
return true;
|
||||
}
|
||||
// Keep all the ones that this faction has anyway.
|
||||
if (faction.augmentations.includes(a.name)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return rng() >= 1 - BitNodeMultipliers.GangUniqueAugs;
|
||||
};
|
||||
augs = augs.filter(uniqueFilter);
|
||||
|
||||
// Remove blacklisted augs
|
||||
augs = augs.filter((a) => !blacklist.includes(a.name));
|
||||
|
||||
return augs.map((a) => a.name);
|
||||
}
|
||||
|
||||
return faction.augmentations.slice();
|
||||
};
|
||||
|
||||
@@ -10,7 +10,7 @@ import { AugmentationNames } from "../../Augmentation/data/AugmentationNames";
|
||||
import { Faction } from "../Faction";
|
||||
import { PurchaseAugmentationsOrderSetting } from "../../Settings/SettingEnums";
|
||||
import { Settings } from "../../Settings/Settings";
|
||||
import { hasAugmentationPrereqs } from "../FactionHelpers";
|
||||
import { hasAugmentationPrereqs, getFactionAugmentationsFiltered } from "../FactionHelpers";
|
||||
|
||||
import { use } from "../../ui/Context";
|
||||
import { Reputation } from "../../ui/React/Reputation";
|
||||
@@ -42,28 +42,7 @@ export function AugmentationsPage(props: IProps): React.ReactElement {
|
||||
}
|
||||
|
||||
function getAugs(): string[] {
|
||||
if (isPlayersGang) {
|
||||
// TODO: this code is duplicated in getAugmentationsFromFaction DRY
|
||||
let augs = Object.values(Augmentations);
|
||||
|
||||
// Remove special augs.
|
||||
augs = augs.filter((a) => !a.isSpecial);
|
||||
|
||||
if (player.bitNodeN !== 2) {
|
||||
// Remove faction-unique augs outside BN2. (But keep the one for this faction.)
|
||||
augs = augs.filter((a) => a.factions.length > 1 || props.faction.augmentations.includes(a.name));
|
||||
|
||||
// Remove blacklisted augs.
|
||||
const blacklist = [AugmentationNames.NeuroFluxGovernor, AugmentationNames.TheRedPill].map(
|
||||
(augmentation) => augmentation as string,
|
||||
);
|
||||
augs = augs.filter((a) => !blacklist.includes(a.name));
|
||||
}
|
||||
|
||||
return augs.map((a) => a.name);
|
||||
} else {
|
||||
return props.faction.augmentations.slice();
|
||||
}
|
||||
return getFactionAugmentationsFiltered(player, props.faction);
|
||||
}
|
||||
|
||||
function getAugsSorted(): string[] {
|
||||
|
||||
@@ -9,7 +9,7 @@ import { Table, TableCell } from "../../ui/React/Table";
|
||||
import { IRouter } from "../../ui/Router";
|
||||
|
||||
import { Faction } from "../Faction";
|
||||
import { joinFaction } from "../FactionHelpers";
|
||||
import { joinFaction, getFactionAugmentationsFiltered } from "../FactionHelpers";
|
||||
import { Factions } from "../Factions";
|
||||
import { FactionNames } from "../data/FactionNames";
|
||||
|
||||
@@ -52,26 +52,7 @@ export function FactionsRoot(props: IProps): React.ReactElement {
|
||||
}
|
||||
|
||||
const getAugsLeft = (faction: Faction, player: IPlayer): number => {
|
||||
const isPlayersGang = player.inGang() && player.getGangName() === faction.name;
|
||||
let augs: string[] = [];
|
||||
|
||||
if (isPlayersGang) {
|
||||
for (const augName of Object.keys(Augmentations)) {
|
||||
const aug = Augmentations[augName];
|
||||
if (
|
||||
augName === AugmentationNames.NeuroFluxGovernor ||
|
||||
(augName === AugmentationNames.TheRedPill && player.bitNodeN !== 2) ||
|
||||
// Special augs (i.e. Bladeburner augs)
|
||||
aug.isSpecial ||
|
||||
// Exclusive augs (i.e. QLink)
|
||||
(aug.factions.length <= 1 && !faction.augmentations.includes(augName) && player.bitNodeN !== 2)
|
||||
)
|
||||
continue;
|
||||
augs.push(augName);
|
||||
}
|
||||
} else {
|
||||
augs = faction.augmentations.slice();
|
||||
}
|
||||
const augs = getFactionAugmentationsFiltered(player, faction);
|
||||
|
||||
return augs.filter((augmentation: string) => !player.hasAugmentation(augmentation)).length;
|
||||
};
|
||||
|
||||
@@ -63,7 +63,7 @@ export function WireCuttingGame(props: IMinigameProps): React.ReactElement {
|
||||
const [questions] = useState(generateQuestion(wires, difficulty));
|
||||
|
||||
function checkWire(wireNum: number): boolean {
|
||||
return questions.some((q) => q.shouldCut(wires[wireNum - 1], wireNum - 1));
|
||||
return !questions.some((q) => q.shouldCut(wires[wireNum - 1], wireNum - 1));
|
||||
}
|
||||
|
||||
function press(this: Document, event: KeyboardEvent): void {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { INetscriptHelper } from "./INetscriptHelper";
|
||||
import { WorkerScript } from "../Netscript/WorkerScript";
|
||||
import { IPlayer } from "../PersonObjects/IPlayer";
|
||||
import { purchaseAugmentation, joinFaction } from "../Faction/FactionHelpers";
|
||||
import { purchaseAugmentation, joinFaction, getFactionAugmentationsFiltered } from "../Faction/FactionHelpers";
|
||||
import { startWorkerScript } from "../NetscriptWorker";
|
||||
import { Augmentation } from "../Augmentation/Augmentation";
|
||||
import { Augmentations } from "../Augmentation/Augmentations";
|
||||
@@ -118,28 +118,7 @@ export function NetscriptSingularity(
|
||||
helper.checkSingularityAccess("getAugmentationsFromFaction");
|
||||
const faction = getFaction("getAugmentationsFromFaction", facName);
|
||||
|
||||
// If player has a gang with this faction, return all augmentations.
|
||||
if (player.hasGangWith(facName)) {
|
||||
let augs = Object.values(Augmentations);
|
||||
|
||||
// Remove special augs.
|
||||
augs = augs.filter((a) => !a.isSpecial);
|
||||
|
||||
if (player.bitNodeN !== 2) {
|
||||
// Remove faction-unique augs outside BN2. (But keep the one for this faction.)
|
||||
augs = augs.filter((a) => a.factions.length > 1 || Factions[facName].augmentations.includes(a.name));
|
||||
|
||||
// Remove blacklisted augs.
|
||||
const blacklist = [AugmentationNames.NeuroFluxGovernor, AugmentationNames.TheRedPill].map(
|
||||
(augmentation) => augmentation as string,
|
||||
);
|
||||
augs = augs.filter((a) => !blacklist.includes(a.name));
|
||||
}
|
||||
|
||||
return augs.map((a) => a.name);
|
||||
}
|
||||
|
||||
return faction.augmentations.slice();
|
||||
return getFactionAugmentationsFiltered(player, faction);
|
||||
},
|
||||
getAugmentationCost: function (_augName: unknown): [number, number] {
|
||||
const augName = helper.string("getAugmentationCost", "augName", _augName);
|
||||
@@ -184,24 +163,7 @@ export function NetscriptSingularity(
|
||||
const fac = getFaction("purchaseAugmentation", facName);
|
||||
const aug = getAugmentation("purchaseAugmentation", augName);
|
||||
|
||||
let augs = [];
|
||||
if (player.hasGangWith(facName)) {
|
||||
for (const augName of Object.keys(Augmentations)) {
|
||||
const aug = Augmentations[augName];
|
||||
if (
|
||||
augName === AugmentationNames.NeuroFluxGovernor ||
|
||||
(augName === AugmentationNames.TheRedPill && player.bitNodeN !== 2) ||
|
||||
// Special augs (i.e. Bladeburner augs)
|
||||
aug.isSpecial ||
|
||||
// Exclusive augs (i.e. QLink)
|
||||
(aug.factions.length <= 1 && !fac.augmentations.includes(augName) && player.bitNodeN !== 2)
|
||||
)
|
||||
continue;
|
||||
augs.push(augName);
|
||||
}
|
||||
} else {
|
||||
augs = fac.augmentations;
|
||||
}
|
||||
const augs = getFactionAugmentationsFiltered(player, fac);
|
||||
|
||||
if (!augs.includes(augName)) {
|
||||
workerScript.log(
|
||||
|
||||
@@ -64,74 +64,78 @@ export const GraftingRoot = (): React.ReactElement => {
|
||||
|
||||
<Box sx={{ my: 3 }}>
|
||||
<Typography variant="h5">Graft Augmentations</Typography>
|
||||
<Paper sx={{ my: 1, width: "fit-content", display: "grid", gridTemplateColumns: "1fr 3fr" }}>
|
||||
<List sx={{ maxHeight: 400, overflowY: "scroll", borderRight: `1px solid ${Settings.theme.welllight}` }}>
|
||||
{getAvailableAugs(player).map((k, i) => (
|
||||
<ListItemButton key={i + 1} onClick={() => setSelectedAug(k)} selected={selectedAug === k}>
|
||||
<Typography>{k}</Typography>
|
||||
</ListItemButton>
|
||||
))}
|
||||
</List>
|
||||
<Box sx={{ m: 1 }}>
|
||||
<Typography variant="h6" sx={{ display: "flex", alignItems: "center", flexWrap: "wrap" }}>
|
||||
<Construction sx={{ mr: 1 }} /> {selectedAug}
|
||||
</Typography>
|
||||
<Button
|
||||
onClick={() => setGraftOpen(true)}
|
||||
sx={{ width: "100%" }}
|
||||
disabled={player.money < GraftableAugmentations[selectedAug].cost}
|
||||
>
|
||||
Graft Augmentation (
|
||||
<Typography>
|
||||
<Money money={GraftableAugmentations[selectedAug].cost} player={player} />
|
||||
{getAvailableAugs(player).length > 0 ? (
|
||||
<Paper sx={{ my: 1, width: "fit-content", display: "grid", gridTemplateColumns: "1fr 3fr" }}>
|
||||
<List sx={{ maxHeight: 400, overflowY: "scroll", borderRight: `1px solid ${Settings.theme.welllight}` }}>
|
||||
{getAvailableAugs(player).map((k, i) => (
|
||||
<ListItemButton key={i + 1} onClick={() => setSelectedAug(k)} selected={selectedAug === k}>
|
||||
<Typography>{k}</Typography>
|
||||
</ListItemButton>
|
||||
))}
|
||||
</List>
|
||||
<Box sx={{ m: 1 }}>
|
||||
<Typography variant="h6" sx={{ display: "flex", alignItems: "center", flexWrap: "wrap" }}>
|
||||
<Construction sx={{ mr: 1 }} /> {selectedAug}
|
||||
</Typography>
|
||||
)
|
||||
</Button>
|
||||
<ConfirmationModal
|
||||
open={graftOpen}
|
||||
onClose={() => setGraftOpen(false)}
|
||||
onConfirm={() => {
|
||||
const graftableAug = GraftableAugmentations[selectedAug];
|
||||
player.loseMoney(graftableAug.cost, "augmentations");
|
||||
player.startGraftAugmentationWork(selectedAug, graftableAug.time);
|
||||
player.startFocusing();
|
||||
router.toWork();
|
||||
}}
|
||||
confirmationText={
|
||||
<>
|
||||
Cancelling grafting will <b>not</b> save grafting progress, and the money you spend will <b>not</b> be
|
||||
returned.
|
||||
<br />
|
||||
<br />
|
||||
Additionally, grafting an Augmentation will increase the potency of the Entropy virus.
|
||||
</>
|
||||
}
|
||||
/>
|
||||
<Typography color={Settings.theme.info}>
|
||||
<b>Time to Graft:</b>{" "}
|
||||
{convertTimeMsToTimeElapsedString(
|
||||
GraftableAugmentations[selectedAug].time / (1 + (player.getIntelligenceBonus(3) - 1) / 3),
|
||||
)}
|
||||
{/* Use formula so the displayed creation time is accurate to player bonus */}
|
||||
</Typography>
|
||||
<Typography sx={{ maxHeight: 305, overflowY: "scroll" }}>
|
||||
{(() => {
|
||||
const aug = Augmentations[selectedAug];
|
||||
|
||||
const info = typeof aug.info === "string" ? <span>{aug.info}</span> : aug.info;
|
||||
const tooltip = (
|
||||
<Button
|
||||
onClick={() => setGraftOpen(true)}
|
||||
sx={{ width: "100%" }}
|
||||
disabled={player.money < GraftableAugmentations[selectedAug].cost}
|
||||
>
|
||||
Graft Augmentation (
|
||||
<Typography>
|
||||
<Money money={GraftableAugmentations[selectedAug].cost} player={player} />
|
||||
</Typography>
|
||||
)
|
||||
</Button>
|
||||
<ConfirmationModal
|
||||
open={graftOpen}
|
||||
onClose={() => setGraftOpen(false)}
|
||||
onConfirm={() => {
|
||||
const graftableAug = GraftableAugmentations[selectedAug];
|
||||
player.loseMoney(graftableAug.cost, "augmentations");
|
||||
player.startGraftAugmentationWork(selectedAug, graftableAug.time);
|
||||
player.startFocusing();
|
||||
router.toWork();
|
||||
}}
|
||||
confirmationText={
|
||||
<>
|
||||
{info}
|
||||
Cancelling grafting will <b>not</b> save grafting progress, and the money you spend will <b>not</b>{" "}
|
||||
be returned.
|
||||
<br />
|
||||
<br />
|
||||
{aug.stats}
|
||||
Additionally, grafting an Augmentation will increase the potency of the Entropy virus.
|
||||
</>
|
||||
);
|
||||
return tooltip;
|
||||
})()}
|
||||
</Typography>
|
||||
</Box>
|
||||
</Paper>
|
||||
}
|
||||
/>
|
||||
<Typography color={Settings.theme.info}>
|
||||
<b>Time to Graft:</b>{" "}
|
||||
{convertTimeMsToTimeElapsedString(
|
||||
GraftableAugmentations[selectedAug].time / (1 + (player.getIntelligenceBonus(3) - 1) / 3),
|
||||
)}
|
||||
{/* Use formula so the displayed creation time is accurate to player bonus */}
|
||||
</Typography>
|
||||
<Typography sx={{ maxHeight: 305, overflowY: "scroll" }}>
|
||||
{(() => {
|
||||
const aug = Augmentations[selectedAug];
|
||||
|
||||
const info = typeof aug.info === "string" ? <span>{aug.info}</span> : aug.info;
|
||||
const tooltip = (
|
||||
<>
|
||||
{info}
|
||||
<br />
|
||||
<br />
|
||||
{aug.stats}
|
||||
</>
|
||||
);
|
||||
return tooltip;
|
||||
})()}
|
||||
</Typography>
|
||||
</Box>
|
||||
</Paper>
|
||||
) : (
|
||||
<Typography>All Augmentations owned</Typography>
|
||||
)}
|
||||
</Box>
|
||||
|
||||
<Box sx={{ my: 3 }}>
|
||||
|
||||
@@ -217,11 +217,19 @@ export function WorkInProgressRoot(): React.ReactElement {
|
||||
|
||||
if (player.workType == CONSTANTS.WorkTypeCompany) {
|
||||
const comp = Companies[player.companyName];
|
||||
let companyRep = 0;
|
||||
if (comp == null || !(comp instanceof Company)) {
|
||||
throw new Error(`Could not find Company: ${player.companyName}`);
|
||||
return (
|
||||
<>
|
||||
<Typography variant="h4" color="primary">
|
||||
You cannot work for {player.companyName || "(Company not found)"} at this time, please try again if you
|
||||
think this should have worked
|
||||
</Typography>
|
||||
<Button onClick={() => router.toTerminal()}>Back to Terminal</Button>
|
||||
</>
|
||||
);
|
||||
}
|
||||
companyRep = comp.playerReputation;
|
||||
|
||||
const companyRep = comp.playerReputation;
|
||||
|
||||
function cancel(): void {
|
||||
player.finishWork(true);
|
||||
|
||||
Reference in New Issue
Block a user