mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2026-04-23 01:32:55 +02:00
Merge branch 'dev' into improvement/work-in-progress-ui
This commit is contained in:
@@ -18,7 +18,7 @@ export class GraftableAugmentation {
|
||||
}
|
||||
|
||||
get cost(): number {
|
||||
return this.augmentation.startingCost * CONSTANTS.AugmentationGraftingCostMult;
|
||||
return this.augmentation.baseCost * CONSTANTS.AugmentationGraftingCostMult;
|
||||
}
|
||||
|
||||
get time(): number {
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { Augmentations } from "../../Augmentation/Augmentations";
|
||||
import { StaticAugmentations } from "../../Augmentation/StaticAugmentations";
|
||||
import { GraftableAugmentation } from "./GraftableAugmentation";
|
||||
import { IPlayer } from "../IPlayer";
|
||||
|
||||
export const getGraftingAvailableAugs = (player: IPlayer): string[] => {
|
||||
const augs: string[] = [];
|
||||
|
||||
for (const [augName, aug] of Object.entries(Augmentations)) {
|
||||
for (const [augName, aug] of Object.entries(StaticAugmentations)) {
|
||||
if (aug.isSpecial) continue;
|
||||
augs.push(augName);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ import { Construction, CheckBox, CheckBoxOutlineBlank } from "@mui/icons-materia
|
||||
import { Box, Button, Container, List, ListItemButton, Paper, Typography } from "@mui/material";
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { Augmentation } from "../../../Augmentation/Augmentation";
|
||||
import { Augmentations } from "../../../Augmentation/Augmentations";
|
||||
import { StaticAugmentations } from "../../../Augmentation/StaticAugmentations";
|
||||
import { AugmentationNames } from "../../../Augmentation/data/AugmentationNames";
|
||||
import { CONSTANTS } from "../../../Constants";
|
||||
import { hasAugmentationPrereqs } from "../../../Faction/FactionHelpers";
|
||||
@@ -54,7 +54,7 @@ export const GraftingRoot = (): React.ReactElement => {
|
||||
const player = use.Player();
|
||||
const router = use.Router();
|
||||
|
||||
for (const aug of Object.values(Augmentations)) {
|
||||
for (const aug of Object.values(StaticAugmentations)) {
|
||||
const name = aug.name;
|
||||
const graftableAug = new GraftableAugmentation(aug);
|
||||
GraftableAugmentations[name] = graftableAug;
|
||||
@@ -62,6 +62,7 @@ export const GraftingRoot = (): React.ReactElement => {
|
||||
|
||||
const [selectedAug, setSelectedAug] = useState(getGraftingAvailableAugs(player)[0]);
|
||||
const [graftOpen, setGraftOpen] = useState(false);
|
||||
const selectedAugmentation = StaticAugmentations[selectedAug];
|
||||
|
||||
const setRerender = useState(false)[1];
|
||||
function rerender(): void {
|
||||
@@ -148,22 +149,26 @@ export const GraftingRoot = (): React.ReactElement => {
|
||||
{/* Use formula so the displayed creation time is accurate to player bonus */}
|
||||
</Typography>
|
||||
|
||||
{Augmentations[selectedAug].prereqs.length > 0 && (
|
||||
<AugPreReqsChecklist player={player} aug={Augmentations[selectedAug]} />
|
||||
{selectedAugmentation.prereqs.length > 0 && (
|
||||
<AugPreReqsChecklist player={player} aug={selectedAugmentation} />
|
||||
)}
|
||||
|
||||
<br />
|
||||
|
||||
<Typography>
|
||||
{(() => {
|
||||
const aug = Augmentations[selectedAug];
|
||||
|
||||
const info = typeof aug.info === "string" ? <span>{aug.info}</span> : aug.info;
|
||||
const info =
|
||||
typeof selectedAugmentation.info === "string" ? (
|
||||
<span>{selectedAugmentation.info}</span>
|
||||
) : (
|
||||
selectedAugmentation.info
|
||||
);
|
||||
const tooltip = (
|
||||
<>
|
||||
{info}
|
||||
<br />
|
||||
<br />
|
||||
{aug.stats}
|
||||
{selectedAugmentation.stats}
|
||||
</>
|
||||
);
|
||||
return tooltip;
|
||||
|
||||
@@ -248,7 +248,7 @@ export interface IPlayer {
|
||||
queryStatFromString(str: string): number;
|
||||
getIntelligenceBonus(weight: number): number;
|
||||
getCasinoWinnings(): number;
|
||||
quitJob(company: string): void;
|
||||
quitJob(company: string, sing?: boolean): void;
|
||||
hasJob(): boolean;
|
||||
createHacknetServer(): HacknetServer;
|
||||
startCreateProgramWork(programName: string, time: number, reqLevel: number): void;
|
||||
@@ -291,6 +291,6 @@ export interface IPlayer {
|
||||
sourceFileLvl(n: number): number;
|
||||
startGraftAugmentationWork(augmentationName: string, time: number): void;
|
||||
graftAugmentationWork(numCycles: number): boolean;
|
||||
finishGraftAugmentationWork(cancelled: boolean): string;
|
||||
finishGraftAugmentationWork(cancelled: boolean, singularity?: boolean): string;
|
||||
applyEntropy(stacks?: number): void;
|
||||
}
|
||||
|
||||
@@ -258,7 +258,7 @@ export class PlayerObject implements IPlayer {
|
||||
queryStatFromString: (str: string) => number;
|
||||
getIntelligenceBonus: (weight: number) => number;
|
||||
getCasinoWinnings: () => number;
|
||||
quitJob: (company: string) => void;
|
||||
quitJob: (company: string, sing?: boolean) => void;
|
||||
hasJob: () => boolean;
|
||||
process: (router: IRouter, numCycles?: number) => void;
|
||||
createHacknetServer: () => HacknetServer;
|
||||
@@ -302,7 +302,7 @@ export class PlayerObject implements IPlayer {
|
||||
sourceFileLvl: (n: number) => number;
|
||||
startGraftAugmentationWork: (augmentationName: string, time: number) => void;
|
||||
graftAugmentationWork: (numCycles: number) => boolean;
|
||||
finishGraftAugmentationWork: (cancelled: boolean) => string;
|
||||
finishGraftAugmentationWork: (cancelled: boolean, singularity?: boolean) => string;
|
||||
applyEntropy: (stacks?: number) => void;
|
||||
|
||||
constructor() {
|
||||
@@ -463,12 +463,12 @@ export class PlayerObject implements IPlayer {
|
||||
this.bladeburner = null;
|
||||
this.bladeburner_max_stamina_mult = 1;
|
||||
this.bladeburner_stamina_gain_mult = 1;
|
||||
this.bladeburner_analysis_mult = 1; //Field Analysis Onl;
|
||||
this.bladeburner_analysis_mult = 1; //Field Analysis Only
|
||||
this.bladeburner_success_chance_mult = 1;
|
||||
|
||||
// Sleeves & Re-sleeving
|
||||
this.sleeves = [];
|
||||
this.sleevesFromCovenant = 0; // # of Duplicate sleeves purchased from the covenan;
|
||||
this.sleevesFromCovenant = 0; // # of Duplicate sleeves purchased from the covenant
|
||||
//bitnode
|
||||
this.bitNodeN = 1;
|
||||
|
||||
@@ -483,8 +483,8 @@ export class PlayerObject implements IPlayer {
|
||||
this.playtimeSinceLastBitnode = 0;
|
||||
|
||||
// Keep track of where money comes from
|
||||
this.moneySourceA = new MoneySourceTracker(); // Where money comes from since last-installed Augmentatio;
|
||||
this.moneySourceB = new MoneySourceTracker(); // Where money comes from for this entire BitNode ru;
|
||||
this.moneySourceA = new MoneySourceTracker(); // Where money comes from since last-installed Augmentation
|
||||
this.moneySourceB = new MoneySourceTracker(); // Where money comes from for this entire BitNode run
|
||||
// Production since last Augmentation installation
|
||||
this.scriptProdSinceLastAug = 0;
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { IPlayer } from "../IPlayer";
|
||||
import { PlayerObject } from "./PlayerObject";
|
||||
import { Augmentations } from "../../Augmentation/Augmentations";
|
||||
import { applyAugmentation } from "../../Augmentation/AugmentationHelpers";
|
||||
import { PlayerOwnedAugmentation } from "../../Augmentation/PlayerOwnedAugmentation";
|
||||
import { AugmentationNames } from "../../Augmentation/data/AugmentationNames";
|
||||
@@ -1364,10 +1363,10 @@ export function craftAugmentationWork(this: IPlayer, numCycles: number): boolean
|
||||
return false;
|
||||
}
|
||||
|
||||
export function finishGraftAugmentationWork(this: IPlayer, cancelled: boolean): string {
|
||||
export function finishGraftAugmentationWork(this: IPlayer, cancelled: boolean, singularity = false): string {
|
||||
const augName = this.graftAugmentationName;
|
||||
if (cancelled === false) {
|
||||
applyAugmentation(Augmentations[augName]);
|
||||
applyAugmentation({ name: augName, level: 1 });
|
||||
|
||||
if (!this.hasAugmentation(AugmentationNames.CongruityImplant)) {
|
||||
this.entropy += 1;
|
||||
@@ -1378,7 +1377,7 @@ export function finishGraftAugmentationWork(this: IPlayer, cancelled: boolean):
|
||||
`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 {
|
||||
} else if (cancelled && singularity === false) {
|
||||
dialogBoxCreate(`You cancelled the grafting of ${augName}.<br>Your money was not returned to you.`);
|
||||
}
|
||||
|
||||
@@ -1700,6 +1699,9 @@ export function singularityStopWork(this: IPlayer): string {
|
||||
case CONSTANTS.WorkTypeCrime:
|
||||
res = this.finishCrime(true);
|
||||
break;
|
||||
case CONSTANTS.WorkTypeGraftAugmentation:
|
||||
res = this.finishGraftAugmentationWork(true, true);
|
||||
break;
|
||||
default:
|
||||
console.error(`Unrecognized work type (${this.workType})`);
|
||||
return "";
|
||||
@@ -1748,14 +1750,6 @@ export function hospitalize(this: IPlayer): number {
|
||||
//The 'sing' argument designates whether or not this is being called from
|
||||
//the applyToCompany() Netscript Singularity function
|
||||
export function applyForJob(this: IPlayer, entryPosType: CompanyPosition, sing = false): boolean {
|
||||
// Get current company and job
|
||||
let currCompany = null;
|
||||
if (this.companyName !== "") {
|
||||
currCompany = Companies[this.companyName];
|
||||
}
|
||||
const currPositionName = this.jobs[this.companyName];
|
||||
|
||||
// Get company that's being applied to
|
||||
const company = Companies[this.location]; //Company being applied to
|
||||
if (!(company instanceof Company)) {
|
||||
console.error(`Could not find company that matches the location: ${this.location}. Player.applyToCompany() failed`);
|
||||
@@ -1765,66 +1759,44 @@ export function applyForJob(this: IPlayer, entryPosType: CompanyPosition, sing =
|
||||
let pos = entryPosType;
|
||||
|
||||
if (!this.isQualified(company, pos)) {
|
||||
const reqText = getJobRequirementText(company, pos);
|
||||
if (!sing) {
|
||||
dialogBoxCreate("Unfortunately, you do not qualify for this position<br>" + reqText);
|
||||
dialogBoxCreate("Unfortunately, you do not qualify for this position<br>" + getJobRequirementText(company, pos));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if this company has the position
|
||||
if (!company.hasPosition(pos)) {
|
||||
console.error(`Company ${company.name} does not have position ${pos}. Player.applyToCompany() failed`);
|
||||
return false;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
const newPos = getNextCompanyPositionHelper(pos);
|
||||
if (newPos == null) {
|
||||
break;
|
||||
}
|
||||
|
||||
//Check if this company has this position
|
||||
if (company.hasPosition(newPos)) {
|
||||
if (!this.isQualified(company, newPos)) {
|
||||
//If player not qualified for next job, break loop so player will be given current job
|
||||
break;
|
||||
}
|
||||
pos = newPos;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
const nextPos = getNextCompanyPositionHelper(pos);
|
||||
if (nextPos == null) break;
|
||||
if (company.hasPosition(nextPos) && this.isQualified(company, nextPos)) {
|
||||
pos = nextPos;
|
||||
} else break;
|
||||
}
|
||||
|
||||
//Check if the determined job is the same as the player's current job
|
||||
if (currCompany != null) {
|
||||
if (currCompany.name == company.name && pos.name == currPositionName) {
|
||||
//Check if player already has the assigned job
|
||||
if (this.jobs[company.name] === pos.name) {
|
||||
if (!sing) {
|
||||
const nextPos = getNextCompanyPositionHelper(pos);
|
||||
if (nextPos == null) {
|
||||
if (!sing) {
|
||||
dialogBoxCreate("You are already at the highest position for your field! No promotion available");
|
||||
}
|
||||
return false;
|
||||
} else if (company.hasPosition(nextPos)) {
|
||||
if (!sing) {
|
||||
const reqText = getJobRequirementText(company, nextPos);
|
||||
dialogBoxCreate("Unfortunately, you do not qualify for a promotion<br>" + reqText);
|
||||
}
|
||||
return false;
|
||||
if (nextPos == null || !company.hasPosition(nextPos)) {
|
||||
dialogBoxCreate("You are already at the highest position for your field! No promotion available");
|
||||
} else {
|
||||
if (!sing) {
|
||||
dialogBoxCreate("You are already at the highest position for your field! No promotion available");
|
||||
}
|
||||
return false;
|
||||
const reqText = getJobRequirementText(company, nextPos);
|
||||
dialogBoxCreate("Unfortunately, you do not qualify for a promotion<br>" + reqText);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
this.jobs[company.name] = pos.name;
|
||||
if (!this.focus && this.isWorking && this.companyName !== this.location) this.resetWorkStatus();
|
||||
this.companyName = this.location;
|
||||
if (!this.isWorking || !this.workType.includes("Working for Company")) this.companyName = company.name;
|
||||
|
||||
if (!sing) {
|
||||
dialogBoxCreate("Congratulations! You were offered a new job at " + this.companyName + " as a " + pos.name + "!");
|
||||
dialogBoxCreate("Congratulations! You were offered a new job at " + company.name + " as a " + pos.name + "!");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -1869,7 +1841,7 @@ export function getNextCompanyPosition(
|
||||
return entryPosType;
|
||||
}
|
||||
|
||||
export function quitJob(this: IPlayer, company: string): void {
|
||||
export function quitJob(this: IPlayer, company: string, _sing = false): void {
|
||||
if (this.isWorking == true && this.workType.includes("Working for Company") && this.companyName == company) {
|
||||
this.finishWork(true);
|
||||
}
|
||||
|
||||
@@ -686,7 +686,7 @@ export class Sleeve extends Person {
|
||||
}
|
||||
|
||||
tryBuyAugmentation(p: IPlayer, aug: Augmentation): boolean {
|
||||
if (!p.canAfford(aug.startingCost)) {
|
||||
if (!p.canAfford(aug.baseCost)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -695,7 +695,7 @@ export class Sleeve extends Person {
|
||||
return false;
|
||||
}
|
||||
|
||||
p.loseMoney(aug.startingCost, "sleeves");
|
||||
p.loseMoney(aug.baseCost, "sleeves");
|
||||
this.installAugmentation(aug);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import { Sleeve } from "./Sleeve";
|
||||
import { IPlayer } from "../IPlayer";
|
||||
|
||||
import { Augmentation } from "../../Augmentation/Augmentation";
|
||||
import { Augmentations } from "../../Augmentation/Augmentations";
|
||||
import { StaticAugmentations } from "../../Augmentation/StaticAugmentations";
|
||||
import { Faction } from "../../Faction/Faction";
|
||||
import { Factions } from "../../Faction/Factions";
|
||||
|
||||
@@ -64,13 +64,13 @@ export function findSleevePurchasableAugs(sleeve: Sleeve, p: IPlayer): Augmentat
|
||||
if (p.inGang()) {
|
||||
const fac = p.getGangFaction();
|
||||
|
||||
for (const augName of Object.keys(Augmentations)) {
|
||||
const aug = Augmentations[augName];
|
||||
for (const augName of Object.keys(StaticAugmentations)) {
|
||||
const aug = StaticAugmentations[augName];
|
||||
if (!isAvailableForSleeve(aug)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (fac.playerReputation > aug.baseRepRequirement) {
|
||||
if (fac.playerReputation > aug.getCost(p).repCost) {
|
||||
availableAugs.push(aug);
|
||||
}
|
||||
}
|
||||
@@ -89,12 +89,12 @@ export function findSleevePurchasableAugs(sleeve: Sleeve, p: IPlayer): Augmentat
|
||||
}
|
||||
|
||||
for (const augName of fac.augmentations) {
|
||||
const aug: Augmentation = Augmentations[augName];
|
||||
const aug: Augmentation = StaticAugmentations[augName];
|
||||
if (!isAvailableForSleeve(aug)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (fac.playerReputation > aug.baseRepRequirement) {
|
||||
if (fac.playerReputation > aug.getCost(p).repCost) {
|
||||
availableAugs.push(aug);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ export function SleeveAugmentationsModal(props: IProps): React.ReactElement {
|
||||
ownedAugNames={ownedAugNames}
|
||||
player={player}
|
||||
canPurchase={(player, aug) => {
|
||||
return player.money > aug.startingCost;
|
||||
return player.money > aug.baseCost;
|
||||
}}
|
||||
purchaseAugmentation={(player, aug, _showModal) => {
|
||||
props.sleeve.tryBuyAugmentation(player, aug);
|
||||
|
||||
@@ -77,7 +77,9 @@ function possibleFactions(player: IPlayer, sleeve: Sleeve): string[] {
|
||||
}
|
||||
|
||||
return factions.filter((faction) => {
|
||||
const facInfo = Factions[faction].getInfo();
|
||||
const factionObj = Factions[faction];
|
||||
if (!factionObj) return false;
|
||||
const facInfo = factionObj.getInfo();
|
||||
return facInfo.offerHackingWork || facInfo.offerFieldWork || facInfo.offerSecurityWork;
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user