Merge remote-tracking branch 'upstream/dev' into dev

This commit is contained in:
rderfler
2022-04-25 13:32:38 -04:00
93 changed files with 3791 additions and 1904 deletions
@@ -1,5 +1,6 @@
import { Augmentations } from "../../Augmentation/Augmentations";
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);
};
+13 -3
View File
@@ -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 { Augmentations } from "../../../Augmentation/Augmentations";
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,16 @@ export const GraftingRoot = (): React.ReactElement => {
const [selectedAug, setSelectedAug] = useState(getGraftingAvailableAugs(player)[0]);
const [graftOpen, setGraftOpen] = useState(false);
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 +142,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>
+1
View File
@@ -202,6 +202,7 @@ export interface IPlayer extends IPerson {
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;
+25
View File
@@ -78,6 +78,13 @@ export abstract class Person implements IPerson {
bladeburner_analysis_mult;
bladeburner_success_chance_mult;
infiltration_base_rep_increase = 0;
infiltration_rep_mult = 1;
infiltration_trade_mult = 1;
infiltration_sell_mult = 1;
infiltration_timer_mult = 1;
infiltration_damage_reduction_mult = 1;
/**
* Augmentations
*/
@@ -279,6 +286,24 @@ export abstract class Person implements IPerson {
this.crime_success_mult = 1;
this.work_money_mult = 1;
this.hacknet_node_money_mult = 1;
this.hacknet_node_purchase_cost_mult = 1;
this.hacknet_node_ram_cost_mult = 1;
this.hacknet_node_core_cost_mult = 1;
this.hacknet_node_level_cost_mult = 1;
this.bladeburner_max_stamina_mult = 1;
this.bladeburner_stamina_gain_mult = 1;
this.bladeburner_analysis_mult = 1;
this.bladeburner_success_chance_mult = 1;
this.infiltration_base_rep_increase = 0;
this.infiltration_rep_mult = 1;
this.infiltration_trade_mult = 1;
this.infiltration_sell_mult = 1;
this.infiltration_timer_mult = 1;
this.infiltration_damage_reduction_mult = 1;
}
/**
+2
View File
@@ -220,6 +220,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;
@@ -607,6 +608,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;
@@ -7,7 +7,7 @@ import { Augmentation } from "../../Augmentation/Augmentation";
import { calculateEntropy } from "../Grafting/EntropyAccumulation";
export function hasAugmentation(this: IPlayer, aug: string | Augmentation, includeQueued = false): boolean {
export function hasAugmentation(this: IPlayer, aug: string | Augmentation, ignoreQueued = 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, inclu
}
}
if (!includeQueued) {
if (!ignoreQueued) {
for (const owned of this.queuedAugmentations) {
if (owned.name === augName) {
return true;
@@ -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 {
@@ -68,6 +68,7 @@ import { FactionNames } from "../../Faction/data/FactionNames";
import { ITaskTracker } from "../ITaskTracker";
import { IPerson } from "../IPerson";
import { use } from "../../ui/Context";
import { graftingIntBonus } from "../Grafting/GraftingHelpers";
export function init(this: IPlayer): void {
/* Initialize Player's home computer */
@@ -1364,7 +1365,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;
@@ -1884,13 +1885,12 @@ export function getNextCompanyPosition(
export function quitJob(this: IPlayer, company: string): void {
if (this.isWorking == true && this.workType.includes("Working for Company") && this.companyName == company) {
this.isWorking = false;
this.companyName = "";
}
if (this.companyName === company) {
this.companyName = "";
this.finishWork(true);
}
delete this.jobs[company];
if (this.companyName === company) {
this.companyName = this.hasJob() ? Object.keys(this.jobs)[0] : "";
}
}
/**
@@ -2181,7 +2181,7 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] {
!daedalusFac.isBanned &&
!daedalusFac.isMember &&
!daedalusFac.alreadyInvited &&
numAugmentations >= Math.round(30 * BitNodeMultipliers.DaedalusAugsRequirement) &&
numAugmentations >= BitNodeMultipliers.DaedalusAugsRequirement &&
this.money >= 100000000000 &&
(this.hacking >= 2500 ||
(this.strength >= 1500 && this.defense >= 1500 && this.dexterity >= 1500 && this.agility >= 1500))
+8
View File
@@ -586,6 +586,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;
}
+4 -2
View File
@@ -65,7 +65,7 @@ function possibleJobs(player: IPlayer, sleeve: Sleeve): string[] {
function possibleFactions(player: IPlayer, sleeve: Sleeve): string[] {
// Array of all factions that other sleeves are working for
const forbiddenFactions = [FactionNames.Bladeburners as string];
const forbiddenFactions = [FactionNames.Bladeburners as string, FactionNames.ShadowsOfAnarchy as string];
if (player.gang) {
forbiddenFactions.push(player.gang.facName);
}
@@ -140,6 +140,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) {
@@ -306,7 +308,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);