mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2026-05-04 14:47:53 +02:00
Merge branch 'dev' of https://github.com/rderfler/bitburner into dev
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
import { Augmentations } from "../../Augmentation/Augmentations";
|
||||
import { AugmentationNames } from "../../Augmentation/data/AugmentationNames";
|
||||
import { IPlayer } from "../IPlayer";
|
||||
|
||||
export const getGraftingAvailableAugs = (player: IPlayer): string[] => {
|
||||
const augs: string[] = [];
|
||||
|
||||
for (const [augName, aug] of Object.entries(Augmentations)) {
|
||||
if (augName === AugmentationNames.NeuroFluxGovernor || augName === AugmentationNames.TheRedPill || aug.isSpecial)
|
||||
continue;
|
||||
augs.push(augName);
|
||||
}
|
||||
|
||||
return augs.filter((augmentation: string) => !player.hasAugmentation(augmentation));
|
||||
};
|
||||
@@ -15,22 +15,11 @@ import { ConfirmationModal } from "../../../ui/React/ConfirmationModal";
|
||||
import { Money } from "../../../ui/React/Money";
|
||||
import { convertTimeMsToTimeElapsedString, formatNumber } from "../../../utils/StringHelperFunctions";
|
||||
import { IPlayer } from "../../IPlayer";
|
||||
import { getGraftingAvailableAugs } from "../GraftingHelpers";
|
||||
import { GraftableAugmentation } from "../GraftableAugmentation";
|
||||
|
||||
const GraftableAugmentations: IMap<GraftableAugmentation> = {};
|
||||
|
||||
export const getAvailableAugs = (player: IPlayer): string[] => {
|
||||
const augs: string[] = [];
|
||||
|
||||
for (const [augName, aug] of Object.entries(Augmentations)) {
|
||||
if (augName === AugmentationNames.NeuroFluxGovernor || augName === AugmentationNames.TheRedPill || aug.isSpecial)
|
||||
continue;
|
||||
augs.push(augName);
|
||||
}
|
||||
|
||||
return augs.filter((augmentation: string) => !player.hasAugmentation(augmentation));
|
||||
};
|
||||
|
||||
const canGraft = (player: IPlayer, aug: GraftableAugmentation): boolean => {
|
||||
if (player.money < aug.cost) {
|
||||
return false;
|
||||
@@ -71,7 +60,7 @@ export const GraftingRoot = (): React.ReactElement => {
|
||||
GraftableAugmentations[name] = graftableAug;
|
||||
}
|
||||
|
||||
const [selectedAug, setSelectedAug] = useState(getAvailableAugs(player)[0]);
|
||||
const [selectedAug, setSelectedAug] = useState(getGraftingAvailableAugs(player)[0]);
|
||||
const [graftOpen, setGraftOpen] = useState(false);
|
||||
|
||||
return (
|
||||
@@ -92,10 +81,10 @@ export const GraftingRoot = (): React.ReactElement => {
|
||||
|
||||
<Box sx={{ my: 3 }}>
|
||||
<Typography variant="h5">Graft Augmentations</Typography>
|
||||
{getAvailableAugs(player).length > 0 ? (
|
||||
{getGraftingAvailableAugs(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) => (
|
||||
<List sx={{ height: 400, overflowY: "scroll", borderRight: `1px solid ${Settings.theme.welllight}` }}>
|
||||
{getGraftingAvailableAugs(player).map((k, i) => (
|
||||
<ListItemButton key={i + 1} onClick={() => setSelectedAug(k)} selected={selectedAug === k}>
|
||||
<Typography>{k}</Typography>
|
||||
</ListItemButton>
|
||||
@@ -130,9 +119,13 @@ export const GraftingRoot = (): React.ReactElement => {
|
||||
<>
|
||||
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.
|
||||
{!player.hasAugmentation(AugmentationNames.CongruityImplant) && (
|
||||
<>
|
||||
<br />
|
||||
<br />
|
||||
Additionally, grafting an Augmentation will increase the potency of the Entropy virus.
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
}
|
||||
/>
|
||||
|
||||
@@ -7,7 +7,7 @@ import { Augmentation } from "../../Augmentation/Augmentation";
|
||||
|
||||
import { calculateEntropy } from "../Grafting/EntropyAccumulation";
|
||||
|
||||
export function hasAugmentation(this: IPlayer, aug: string | Augmentation, installed = false): boolean {
|
||||
export function hasAugmentation(this: IPlayer, aug: string | Augmentation, includeQueued = false): boolean {
|
||||
const augName: string = aug instanceof Augmentation ? aug.name : aug;
|
||||
|
||||
for (const owned of this.augmentations) {
|
||||
@@ -16,7 +16,7 @@ export function hasAugmentation(this: IPlayer, aug: string | Augmentation, insta
|
||||
}
|
||||
}
|
||||
|
||||
if (!installed) {
|
||||
if (!includeQueued) {
|
||||
for (const owned of this.queuedAugmentations) {
|
||||
if (owned.name === augName) {
|
||||
return true;
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { Bladeburner } from "../../Bladeburner/Bladeburner";
|
||||
import { SourceFileFlags } from "../../SourceFile/SourceFileFlags";
|
||||
import { IPlayer } from "../IPlayer";
|
||||
|
||||
export function canAccessBladeburner(this: IPlayer): boolean {
|
||||
@@ -7,7 +6,7 @@ export function canAccessBladeburner(this: IPlayer): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
return this.bitNodeN === 6 || this.bitNodeN === 7 || SourceFileFlags[6] > 0 || SourceFileFlags[7] > 0;
|
||||
return this.bitNodeN === 6 || this.bitNodeN === 7 || this.sourceFileLvl(6) > 0 || this.sourceFileLvl(7) > 0;
|
||||
}
|
||||
|
||||
export function inBladeburner(this: IPlayer): boolean {
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import { Corporation } from "../../Corporation/Corporation";
|
||||
import { CorporationUnlockUpgrades } from "../../Corporation/data/CorporationUnlockUpgrades";
|
||||
import { SourceFileFlags } from "../../SourceFile/SourceFileFlags";
|
||||
import {
|
||||
CorporationUnlockUpgradeIndex,
|
||||
CorporationUnlockUpgrades,
|
||||
} from "../../Corporation/data/CorporationUnlockUpgrades";
|
||||
import { IPlayer } from "../IPlayer";
|
||||
|
||||
export function canAccessCorporation(this: IPlayer): boolean {
|
||||
return this.bitNodeN === 3 || SourceFileFlags[3] > 0;
|
||||
return this.bitNodeN === 3 || this.sourceFileLvl(3) > 0;
|
||||
}
|
||||
|
||||
export function hasCorporation(this: IPlayer): boolean {
|
||||
@@ -19,9 +21,9 @@ export function startCorporation(this: IPlayer, corpName: string, additionalShar
|
||||
name: corpName,
|
||||
});
|
||||
|
||||
if (SourceFileFlags[3] === 3) {
|
||||
const warehouseApi = CorporationUnlockUpgrades["7"][0];
|
||||
const OfficeApi = CorporationUnlockUpgrades["8"][0];
|
||||
if (this.sourceFileLvl(3) === 3) {
|
||||
const warehouseApi = CorporationUnlockUpgrades[CorporationUnlockUpgradeIndex.WarehouseAPI].index;
|
||||
const OfficeApi = CorporationUnlockUpgrades[CorporationUnlockUpgradeIndex.OfficeAPI].index;
|
||||
|
||||
this.corporation.unlockUpgrades[warehouseApi] = 1;
|
||||
this.corporation.unlockUpgrades[OfficeApi] = 1;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { Factions } from "../../Faction/Factions";
|
||||
import { Faction } from "../../Faction/Faction";
|
||||
import { Gang } from "../../Gang/Gang";
|
||||
import { SourceFileFlags } from "../../SourceFile/SourceFileFlags";
|
||||
import { IPlayer } from "../IPlayer";
|
||||
|
||||
// Amount of negative karma needed to manage a gang in BitNodes other than 2
|
||||
@@ -11,7 +10,7 @@ export function canAccessGang(this: IPlayer): boolean {
|
||||
if (this.bitNodeN === 2) {
|
||||
return true;
|
||||
}
|
||||
if (SourceFileFlags[2] <= 0) {
|
||||
if (this.sourceFileLvl(2) <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -45,7 +45,6 @@ import { SpecialServers } from "../../Server/data/SpecialServers";
|
||||
import { applySourceFile } from "../../SourceFile/applySourceFile";
|
||||
import { applyExploit } from "../../Exploits/applyExploits";
|
||||
import { SourceFiles } from "../../SourceFile/SourceFiles";
|
||||
import { SourceFileFlags } from "../../SourceFile/SourceFileFlags";
|
||||
import { influenceStockThroughCompanyWork } from "../../StockMarket/PlayerInfluencing";
|
||||
import { getHospitalizationCost } from "../../Hospital/Hospital";
|
||||
import { WorkerScript } from "../../Netscript/WorkerScript";
|
||||
@@ -62,7 +61,7 @@ import { Money } from "../../ui/React/Money";
|
||||
|
||||
import React from "react";
|
||||
import { serverMetadata } from "../../Server/data/servers";
|
||||
import { SnackbarEvents } from "../../ui/React/Snackbar";
|
||||
import { SnackbarEvents, ToastVariant } from "../../ui/React/Snackbar";
|
||||
import { calculateClassEarnings } from "../formulas/work";
|
||||
import { achievements } from "../../Achievements/Achievements";
|
||||
import { FactionNames } from "../../Faction/data/FactionNames";
|
||||
@@ -123,7 +122,7 @@ export function prestigeAugmentation(this: PlayerObject): void {
|
||||
|
||||
this.queuedAugmentations = [];
|
||||
|
||||
const numSleeves = Math.min(3, SourceFileFlags[10] + (this.bitNodeN === 10 ? 1 : 0)) + this.sleevesFromCovenant;
|
||||
const numSleeves = Math.min(3, this.sourceFileLvl(10) + (this.bitNodeN === 10 ? 1 : 0)) + this.sleevesFromCovenant;
|
||||
if (this.sleeves.length > numSleeves) this.sleeves.length = numSleeves;
|
||||
for (let i = this.sleeves.length; i < numSleeves; i++) {
|
||||
this.sleeves.push(new Sleeve(this));
|
||||
@@ -469,7 +468,7 @@ export function gainIntelligenceExp(this: IPerson, exp: number): void {
|
||||
console.error("ERROR: NaN passed into Player.gainIntelligenceExp()");
|
||||
return;
|
||||
}
|
||||
if (SourceFileFlags[5] > 0 || this.intelligence > 0) {
|
||||
if (this.sourceFileLvl(5) > 0 || this.intelligence > 0) {
|
||||
this.intelligence_exp += exp;
|
||||
this.intelligence = Math.floor(this.calculateSkill(this.intelligence_exp, 1));
|
||||
}
|
||||
@@ -1049,7 +1048,7 @@ export function getWorkMoneyGain(this: IPlayer): number {
|
||||
// If player has SF-11, calculate salary multiplier from favor
|
||||
let bn11Mult = 1;
|
||||
const company = Companies[this.companyName];
|
||||
if (SourceFileFlags[11] > 0) {
|
||||
if (this.sourceFileLvl(11) > 0) {
|
||||
bn11Mult = 1 + company.favor / 100;
|
||||
}
|
||||
|
||||
@@ -1327,20 +1326,21 @@ export function createProgramWork(this: IPlayer, numCycles: number): boolean {
|
||||
|
||||
export function finishCreateProgramWork(this: IPlayer, cancelled: boolean): string {
|
||||
const programName = this.createProgramName;
|
||||
if (cancelled === false) {
|
||||
if (!cancelled) {
|
||||
//Complete case
|
||||
this.gainIntelligenceExp((CONSTANTS.IntelligenceProgramBaseExpGain * this.timeWorked) / 1000);
|
||||
dialogBoxCreate(`You've finished creating ${programName}!<br>The new program can be found on your home computer.`);
|
||||
|
||||
this.getHomeComputer().programs.push(programName);
|
||||
} else {
|
||||
if (!this.getHomeComputer().programs.includes(programName)) {
|
||||
this.getHomeComputer().programs.push(programName);
|
||||
}
|
||||
} else if (!this.getHomeComputer().programs.includes(programName)) {
|
||||
//Incomplete case
|
||||
const perc = (Math.floor((this.timeWorkedCreateProgram / this.timeNeededToCompleteWork) * 10000) / 100).toString();
|
||||
const incompleteName = programName + "-" + perc + "%-INC";
|
||||
this.getHomeComputer().programs.push(incompleteName);
|
||||
}
|
||||
|
||||
if (!cancelled) {
|
||||
this.gainIntelligenceExp((CONSTANTS.IntelligenceProgramBaseExpGain * this.timeWorked) / 1000);
|
||||
}
|
||||
|
||||
this.isWorking = false;
|
||||
|
||||
this.resetWorkStatus();
|
||||
@@ -1378,18 +1378,19 @@ export function craftAugmentationWork(this: IPlayer, numCycles: number): boolean
|
||||
export function finishGraftAugmentationWork(this: IPlayer, cancelled: boolean): string {
|
||||
const augName = this.graftAugmentationName;
|
||||
if (cancelled === false) {
|
||||
dialogBoxCreate(
|
||||
`You've finished crafting ${augName}.<br>The augmentation has been grafted to your body, but you feel a bit off.`,
|
||||
);
|
||||
|
||||
applyAugmentation(Augmentations[augName]);
|
||||
|
||||
if (!this.hasAugmentation(AugmentationNames.CongruityImplant)) {
|
||||
this.entropy += 1;
|
||||
this.applyEntropy(this.entropy);
|
||||
}
|
||||
|
||||
dialogBoxCreate(
|
||||
`You've finished grafting ${augName}.<br>The augmentation has been applied to your body` +
|
||||
(this.hasAugmentation(AugmentationNames.CongruityImplant) ? "." : ", but you feel a bit off."),
|
||||
);
|
||||
} else {
|
||||
dialogBoxCreate(`You cancelled the crafting of ${augName}.<br>Your money was not returned to you.`);
|
||||
dialogBoxCreate(`You cancelled the grafting of ${augName}.<br>Your money was not returned to you.`);
|
||||
}
|
||||
|
||||
// Intelligence gain
|
||||
@@ -1746,7 +1747,7 @@ export function regenerateHp(this: IPerson, amt: number): void {
|
||||
|
||||
export function hospitalize(this: IPlayer): number {
|
||||
const cost = getHospitalizationCost(this);
|
||||
SnackbarEvents.emit(`You've been Hospitalized for ${numeralWrapper.formatMoney(cost)}`, "warning", 2000);
|
||||
SnackbarEvents.emit(`You've been Hospitalized for ${numeralWrapper.formatMoney(cost)}`, ToastVariant.WARNING, 2000);
|
||||
|
||||
this.loseMoney(cost, "hospitalization");
|
||||
this.hp = this.max_hp;
|
||||
@@ -2095,12 +2096,7 @@ export function reapplyAllAugmentations(this: IPlayer, resetMultipliers = true):
|
||||
|
||||
const playerAug = this.augmentations[i];
|
||||
const augName = playerAug.name;
|
||||
const aug = Augmentations[augName];
|
||||
if (aug == null) {
|
||||
console.warn(`Invalid augmentation name in Player.reapplyAllAugmentations(). Aug ${augName} will be skipped`);
|
||||
continue;
|
||||
}
|
||||
aug.owned = true;
|
||||
|
||||
if (augName == AugmentationNames.NeuroFluxGovernor) {
|
||||
for (let j = 0; j < playerAug.level; ++j) {
|
||||
applyAugmentation(this.augmentations[i], true);
|
||||
@@ -2715,13 +2711,13 @@ export function gotoLocation(this: IPlayer, to: LocationName): boolean {
|
||||
}
|
||||
|
||||
export function canAccessGrafting(this: IPlayer): boolean {
|
||||
return this.bitNodeN === 10 || SourceFileFlags[10] > 0;
|
||||
return this.bitNodeN === 10 || this.sourceFileLvl(10) > 0;
|
||||
}
|
||||
|
||||
export function giveExploit(this: IPlayer, exploit: Exploit): void {
|
||||
if (!this.exploits.includes(exploit)) {
|
||||
this.exploits.push(exploit);
|
||||
SnackbarEvents.emit("SF -1 acquired!", "success", 2000);
|
||||
SnackbarEvents.emit("SF -1 acquired!", ToastVariant.SUCCESS, 2000);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2730,7 +2726,7 @@ export function giveAchievement(this: IPlayer, achievementId: string): void {
|
||||
if (!achievement) return;
|
||||
if (!this.achievements.map((a) => a.ID).includes(achievementId)) {
|
||||
this.achievements.push({ ID: achievementId, unlockedOn: new Date().getTime() });
|
||||
SnackbarEvents.emit(`Unlocked Achievement: "${achievement.Name}"`, "success", 2000);
|
||||
SnackbarEvents.emit(`Unlocked Achievement: "${achievement.Name}"`, ToastVariant.SUCCESS, 2000);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2753,7 +2749,7 @@ export function setMult(this: IPlayer, name: string, mult: number): void {
|
||||
}
|
||||
|
||||
export function canAccessCotMG(this: IPlayer): boolean {
|
||||
return this.bitNodeN === 13 || SourceFileFlags[13] > 0;
|
||||
return this.bitNodeN === 13 || this.sourceFileLvl(13) > 0;
|
||||
}
|
||||
|
||||
export function sourceFileLvl(this: IPlayer, n: number): number {
|
||||
|
||||
Reference in New Issue
Block a user