mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2026-04-26 19:14:32 +02:00
merge dev
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { StaticAugmentations } from "../../Augmentation/StaticAugmentations";
|
||||
import { AugmentationNames } from "../../Augmentation/data/AugmentationNames";
|
||||
import { GraftableAugmentation } from "./GraftableAugmentation";
|
||||
import { IPlayer } from "../IPlayer";
|
||||
|
||||
export const getGraftingAvailableAugs = (player: IPlayer): string[] => {
|
||||
@@ -13,3 +14,12 @@ export const getGraftingAvailableAugs = (player: IPlayer): string[] => {
|
||||
|
||||
return augs.filter((augmentation: string) => !player.hasAugmentation(augmentation));
|
||||
};
|
||||
|
||||
export const graftingIntBonus = (player: IPlayer): number => {
|
||||
return 1 + (player.getIntelligenceBonus(3) - 1) / 3;
|
||||
};
|
||||
|
||||
export const calculateGraftingTimeWithBonus = (player: IPlayer, aug: GraftableAugmentation): number => {
|
||||
const baseTime = aug.time;
|
||||
return baseTime / graftingIntBonus(player);
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Construction, CheckBox, CheckBoxOutlineBlank } from "@mui/icons-material";
|
||||
import { Box, Button, Container, List, ListItemButton, Paper, Typography } from "@mui/material";
|
||||
import React, { useState } from "react";
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { Augmentation } from "../../../Augmentation/Augmentation";
|
||||
import { StaticAugmentations } from "../../../Augmentation/StaticAugmentations";
|
||||
import { AugmentationNames } from "../../../Augmentation/data/AugmentationNames";
|
||||
@@ -15,7 +15,7 @@ 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 { getGraftingAvailableAugs, calculateGraftingTimeWithBonus } from "../GraftingHelpers";
|
||||
import { GraftableAugmentation } from "../GraftableAugmentation";
|
||||
|
||||
const GraftableAugmentations: IMap<GraftableAugmentation> = {};
|
||||
@@ -63,6 +63,17 @@ 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 {
|
||||
setRerender((old) => !old);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const id = setInterval(rerender, 200);
|
||||
return () => clearInterval(id);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Container disableGutters maxWidth="lg" sx={{ mx: 0 }}>
|
||||
<Button onClick={() => router.toLocation(Locations[LocationName.NewTokyoVitaLife])}>Back</Button>
|
||||
@@ -132,7 +143,7 @@ export const GraftingRoot = (): React.ReactElement => {
|
||||
<Typography color={Settings.theme.info}>
|
||||
<b>Time to Graft:</b>{" "}
|
||||
{convertTimeMsToTimeElapsedString(
|
||||
GraftableAugmentations[selectedAug].time / (1 + (player.getIntelligenceBonus(3) - 1) / 3),
|
||||
calculateGraftingTimeWithBonus(player, GraftableAugmentations[selectedAug]),
|
||||
)}
|
||||
{/* Use formula so the displayed creation time is accurate to player bonus */}
|
||||
</Typography>
|
||||
|
||||
@@ -208,6 +208,7 @@ export interface IPlayer {
|
||||
hasProgram(program: string): boolean;
|
||||
inBladeburner(): boolean;
|
||||
inGang(): boolean;
|
||||
isAwareOfGang(): boolean;
|
||||
isQualified(company: Company, position: CompanyPosition): boolean;
|
||||
loseMoney(money: number, source: string): void;
|
||||
process(router: IRouter, numCycles?: number): void;
|
||||
|
||||
@@ -218,6 +218,7 @@ export class PlayerObject implements IPlayer {
|
||||
hasProgram: (program: string) => boolean;
|
||||
inBladeburner: () => boolean;
|
||||
inGang: () => boolean;
|
||||
isAwareOfGang: () => boolean;
|
||||
isQualified: (company: Company, position: CompanyPosition) => boolean;
|
||||
loseMoney: (money: number, source: string) => void;
|
||||
reapplyAllAugmentations: (resetMultipliers?: boolean) => void;
|
||||
@@ -604,6 +605,7 @@ export class PlayerObject implements IPlayer {
|
||||
this.hasCorporation = corporationMethods.hasCorporation;
|
||||
this.startCorporation = corporationMethods.startCorporation;
|
||||
this.canAccessGang = gangMethods.canAccessGang;
|
||||
this.isAwareOfGang = gangMethods.isAwareOfGang;
|
||||
this.getGangFaction = gangMethods.getGangFaction;
|
||||
this.getGangName = gangMethods.getGangName;
|
||||
this.hasGangWith = gangMethods.hasGangWith;
|
||||
|
||||
@@ -2,9 +2,9 @@ import { Factions } from "../../Faction/Factions";
|
||||
import { Faction } from "../../Faction/Faction";
|
||||
import { Gang } from "../../Gang/Gang";
|
||||
import { IPlayer } from "../IPlayer";
|
||||
import { GangConstants } from "../../Gang/data/Constants"
|
||||
|
||||
|
||||
// Amount of negative karma needed to manage a gang in BitNodes other than 2
|
||||
const GangKarmaRequirement = -54000;
|
||||
|
||||
export function canAccessGang(this: IPlayer): boolean {
|
||||
if (this.bitNodeN === 2) {
|
||||
@@ -14,7 +14,11 @@ export function canAccessGang(this: IPlayer): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
return this.karma <= GangKarmaRequirement;
|
||||
return this.karma <= GangConstants.GangKarmaRequirement;
|
||||
}
|
||||
|
||||
export function isAwareOfGang(this: IPlayer): boolean {
|
||||
return this.bitNodeN === 2 || this.sourceFileLvl(2) >= 1;
|
||||
}
|
||||
|
||||
export function getGangFaction(this: IPlayer): Faction {
|
||||
|
||||
@@ -64,6 +64,7 @@ import { SnackbarEvents, ToastVariant } from "../../ui/React/Snackbar";
|
||||
import { calculateClassEarnings } from "../formulas/work";
|
||||
import { achievements } from "../../Achievements/Achievements";
|
||||
import { FactionNames } from "../../Faction/data/FactionNames";
|
||||
import { graftingIntBonus } from "../Grafting/GraftingHelpers";
|
||||
|
||||
export function init(this: IPlayer): void {
|
||||
/* Initialize Player's home computer */
|
||||
@@ -1349,7 +1350,7 @@ export function craftAugmentationWork(this: IPlayer, numCycles: number): boolean
|
||||
focusBonus = this.focus ? 1 : CONSTANTS.BaseFocusBonus;
|
||||
}
|
||||
|
||||
let skillMult = 1 + (this.getIntelligenceBonus(3) - 1) / 3;
|
||||
let skillMult = graftingIntBonus(this);
|
||||
skillMult *= focusBonus;
|
||||
|
||||
this.timeWorked += CONSTANTS._idleSpeed * numCycles;
|
||||
|
||||
@@ -519,6 +519,14 @@ export class Sleeve extends Person {
|
||||
break;
|
||||
}
|
||||
|
||||
// If the player has a gang with the faction the sleeve is working
|
||||
// for, we need to reset the sleeve's task
|
||||
if (p.gang) {
|
||||
if (fac.name === p.gang.facName) {
|
||||
this.resetTaskStatus();
|
||||
}
|
||||
}
|
||||
|
||||
fac.playerReputation += this.getRepGain(p) * cyclesUsed;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -110,6 +110,8 @@ const tasks: {
|
||||
first: factions,
|
||||
second: (s1: string) => {
|
||||
const faction = Factions[s1];
|
||||
if (!faction) return ["------"];
|
||||
|
||||
const facInfo = faction.getInfo();
|
||||
const options: string[] = [];
|
||||
if (facInfo.offerHackingWork) {
|
||||
@@ -260,7 +262,7 @@ export function TaskSelector(props: IProps): React.ReactElement {
|
||||
const detailsF = tasks[n];
|
||||
if (detailsF === undefined) throw new Error(`No function for task '${s0}'`);
|
||||
const details = detailsF(props.player, props.sleeve);
|
||||
const details2 = details.second(details.first[0]);
|
||||
const details2 = details.second(details.first[0]) ?? ["------"];
|
||||
setS2(details2[0]);
|
||||
setS1(details.first[0]);
|
||||
setS0(n);
|
||||
|
||||
Reference in New Issue
Block a user