This commit is contained in:
rderfler
2022-04-14 11:41:02 -04:00
200 changed files with 4527 additions and 3249 deletions
@@ -1383,8 +1383,11 @@ export function finishGraftAugmentationWork(this: IPlayer, cancelled: boolean):
);
applyAugmentation(Augmentations[augName]);
this.entropy += 1;
this.applyEntropy(this.entropy);
if (!this.hasAugmentation(AugmentationNames.CongruityImplant)) {
this.entropy += 1;
this.applyEntropy(this.entropy);
}
} else {
dialogBoxCreate(`You cancelled the crafting of ${augName}.<br>Your money was not returned to you.`);
}
+1 -1
View File
@@ -936,7 +936,7 @@ export class Sleeve extends Person {
* Returns boolean indicating success
*/
workForFaction(p: IPlayer, factionName: string, workType: string): boolean {
const faction = Factions[factionName]
const faction = Factions[factionName];
if (factionName === "" || !faction || !(faction instanceof Faction) || !p.factions.includes(factionName)) {
return false;
}
+1 -1
View File
@@ -1,4 +1,4 @@
import { FactionNames } from '../../Faction/data/FactionNames';
import { FactionNames } from "../../Faction/data/FactionNames";
import { Sleeve } from "./Sleeve";
import { IPlayer } from "../IPlayer";
+4 -3
View File
@@ -91,7 +91,8 @@ export function FAQModal({ open, onClose }: IProps): React.ReactElement {
<Typography variant="h4">Why can't I buy the X Augmentation for my sleeve?</Typography>
<br />
<Typography>
Certain Augmentations, like {FactionNames.Bladeburners}-specific ones and NeuroFlux Governor, are not available for sleeves.
Certain Augmentations, like {FactionNames.Bladeburners}-specific ones and NeuroFlux Governor, are not
available for sleeves.
</Typography>
<br />
<br />
@@ -110,8 +111,8 @@ export function FAQModal({ open, onClose }: IProps): React.ReactElement {
<br />
<br />
<Typography>
Memory can only be increased by purchasing upgrades from {FactionNames.TheCovenant}. It is a persistent stat, meaning it
never gets resets back to 1. The maximum possible value for a sleeve's memory is 100.
Memory can only be increased by purchasing upgrades from {FactionNames.TheCovenant}. It is a persistent stat,
meaning it never gets resets back to 1. The maximum possible value for a sleeve's memory is 100.
</Typography>
</>
</Modal>
@@ -91,11 +91,18 @@ export function SleeveAugmentationsModal(props: IProps): React.ReactElement {
{ownedAugNames.length > 0 && (
<>
<Typography sx={{ mx: 1 }}>Owned Augmentations:</Typography>
<Box display="grid" sx={{ gridTemplateColumns: 'repeat(5, 1fr)', m: 1 }}>
<Box display="grid" sx={{ gridTemplateColumns: "repeat(5, 1fr)", m: 1 }}>
{ownedAugNames.map((augName) => {
const aug = Augmentations[augName];
const info = typeof aug.info === "string" ? <span>{aug.info}</span> : aug.info
const tooltip = (<>{info}<br /><br />{aug.stats}</>);
const info = typeof aug.info === "string" ? <span>{aug.info}</span> : aug.info;
const tooltip = (
<>
{info}
<br />
<br />
{aug.stats}
</>
);
return (
<Tooltip key={augName} title={<Typography>{tooltip}</Typography>}>
+13 -15
View File
@@ -1,12 +1,6 @@
import React, { useState } from "react";
import {
Box,
Paper,
Typography,
Button,
Tooltip
} from "@mui/material";
import { Box, Paper, Typography, Button, Tooltip } from "@mui/material";
import { CONSTANTS } from "../../../Constants";
import { Crimes } from "../../../Crime/Crimes";
@@ -147,12 +141,12 @@ export function SleeveElem(props: IProps): React.ReactElement {
}
return (
<Box component={Paper} sx={{ width: 'auto' }}>
<Box component={Paper} sx={{ width: "auto" }}>
<Box sx={{ m: 1 }}>
<Box display="grid" sx={{ gridTemplateColumns: '1fr 1fr', width: '100%', gap: 1 }}>
<Box display="grid" sx={{ gridTemplateColumns: "1fr 1fr", width: "100%", gap: 1 }}>
<Box>
<StatsElement sleeve={props.sleeve} />
<Box display="grid" sx={{ gridTemplateColumns: '1fr 1fr', width: '100%' }}>
<Box display="grid" sx={{ gridTemplateColumns: "1fr 1fr", width: "100%" }}>
<Button onClick={() => setStatsOpen(true)}>More Stats</Button>
<Button onClick={() => setEarningsOpen(true)}>More Earnings Info</Button>
<Tooltip title={player.money < CONSTANTS.TravelCost ? <Typography>Insufficient funds</Typography> : ""}>
@@ -160,20 +154,22 @@ export function SleeveElem(props: IProps): React.ReactElement {
<Button
onClick={() => setTravelOpen(true)}
disabled={player.money < CONSTANTS.TravelCost}
sx={{ width: '100%', height: '100%' }}
sx={{ width: "100%", height: "100%" }}
>
Travel
</Button>
</span>
</Tooltip>
<Tooltip
title={props.sleeve.shock < 100 ? <Typography>Unlocked when sleeve has fully recovered</Typography> : ""}
title={
props.sleeve.shock < 100 ? <Typography>Unlocked when sleeve has fully recovered</Typography> : ""
}
>
<span>
<Button
onClick={() => setAugmentationsOpen(true)}
disabled={props.sleeve.shock < 100}
sx={{ width: '100%', height: '100%' }}
sx={{ width: "100%", height: "100%" }}
>
Manage Augmentations
</Button>
@@ -185,7 +181,9 @@ export function SleeveElem(props: IProps): React.ReactElement {
<EarningsElement sleeve={props.sleeve} />
<Box>
<TaskSelector player={player} sleeve={props.sleeve} setABC={setABC} />
<Button onClick={setTask} sx={{ width: '100%' }}>Set Task</Button>
<Button onClick={setTask} sx={{ width: "100%" }}>
Set Task
</Button>
<Typography>{desc}</Typography>
<Typography>
{(props.sleeve.currentTask === SleeveTaskType.Crime
@@ -213,6 +211,6 @@ export function SleeveElem(props: IProps): React.ReactElement {
/>
</Box>
</Box>
</Box >
</Box>
);
}
+6 -9
View File
@@ -1,11 +1,6 @@
import React, { useState, useEffect } from "react";
import {
Box,
Typography,
Button,
Container
} from "@mui/material";
import { Box, Typography, Button, Container } from "@mui/material";
import { use } from "../../../ui/Context";
@@ -38,14 +33,16 @@ export function SleeveRoot(): React.ReactElement {
<br />
<br />
</Typography>
</Container>
<Button onClick={() => setFAQOpen(true)}>FAQ</Button>
<Button href="https://bitburner.readthedocs.io/en/latest/advancedgameplay/sleeves.html#duplicate-sleeves" target="_blank">
<Button
href="https://bitburner.readthedocs.io/en/latest/advancedgameplay/sleeves.html#duplicate-sleeves"
target="_blank"
>
Wiki Documentation
</Button>
<Box display="grid" sx={{ gridTemplateColumns: 'repeat(2, 1fr)', mt: 1 }}>
<Box display="grid" sx={{ gridTemplateColumns: "repeat(2, 1fr)", mt: 1 }}>
{player.sleeves.map((sleeve, i) => (
<SleeveElem key={i} rerender={rerender} sleeve={sleeve} />
))}
+63 -26
View File
@@ -1,12 +1,6 @@
import React from "react";
import {
Typography,
Table,
TableBody,
TableCell,
TableRow,
} from "@mui/material";
import { Typography, Table, TableBody, TableCell, TableRow } from "@mui/material";
import { numeralWrapper } from "../../../ui/numeralFormat";
import { Settings } from "../../../Settings/Settings";
@@ -28,29 +22,69 @@ export function StatsElement(props: IProps): React.ReactElement {
const classes = useStyles();
return (
<Table sx={{ display: 'table', mb: 1, width: '100%' }}>
<Table sx={{ display: "table", mb: 1, width: "100%" }}>
<TableBody>
<StatsRow name="City" color={Settings.theme.primary} data={{ content: props.sleeve.city }} />
<StatsRow name="HP" color={Settings.theme.hp}
data={{ content: `${numeralWrapper.formatHp(props.sleeve.hp)} / ${numeralWrapper.formatHp(props.sleeve.max_hp)}` }}
<StatsRow
name="HP"
color={Settings.theme.hp}
data={{
content: `${numeralWrapper.formatHp(props.sleeve.hp)} / ${numeralWrapper.formatHp(props.sleeve.max_hp)}`,
}}
/>
<StatsRow
name="Hacking"
color={Settings.theme.hack}
data={{ level: props.sleeve.hacking, exp: props.sleeve.hacking_exp }}
/>
<StatsRow
name="Strength"
color={Settings.theme.combat}
data={{ level: props.sleeve.strength, exp: props.sleeve.strength_exp }}
/>
<StatsRow
name="Defense"
color={Settings.theme.combat}
data={{ level: props.sleeve.defense, exp: props.sleeve.defense_exp }}
/>
<StatsRow
name="Dexterity"
color={Settings.theme.combat}
data={{ level: props.sleeve.dexterity, exp: props.sleeve.dexterity_exp }}
/>
<StatsRow
name="Agility"
color={Settings.theme.combat}
data={{ level: props.sleeve.agility, exp: props.sleeve.agility_exp }}
/>
<StatsRow
name="Charisma"
color={Settings.theme.cha}
data={{ level: props.sleeve.charisma, exp: props.sleeve.charisma_exp }}
/>
<StatsRow name="Hacking" color={Settings.theme.hack} data={{ level: props.sleeve.hacking, exp: props.sleeve.hacking_exp }} />
<StatsRow name="Strength" color={Settings.theme.combat} data={{ level: props.sleeve.strength, exp: props.sleeve.strength_exp }} />
<StatsRow name="Defense" color={Settings.theme.combat} data={{ level: props.sleeve.defense, exp: props.sleeve.defense_exp }} />
<StatsRow name="Dexterity" color={Settings.theme.combat} data={{ level: props.sleeve.dexterity, exp: props.sleeve.dexterity_exp }} />
<StatsRow name="Agility" color={Settings.theme.combat} data={{ level: props.sleeve.agility, exp: props.sleeve.agility_exp }} />
<StatsRow name="Charisma" color={Settings.theme.cha} data={{ level: props.sleeve.charisma, exp: props.sleeve.charisma_exp }} />
<TableRow>
<TableCell classes={{ root: classes.cellNone }}>
<br />
</TableCell>
</TableRow>
<StatsRow name="Shock" color={Settings.theme.primary} data={{ content: numeralWrapper.formatSleeveShock(100 - props.sleeve.shock) }} />
<StatsRow name="Sync" color={Settings.theme.primary} data={{ content: numeralWrapper.formatSleeveSynchro(props.sleeve.sync) }} />
<StatsRow name="Memory" color={Settings.theme.primary} data={{ content: numeralWrapper.formatSleeveMemory(props.sleeve.memory) }} />
<StatsRow
name="Shock"
color={Settings.theme.primary}
data={{ content: numeralWrapper.formatSleeveShock(100 - props.sleeve.shock) }}
/>
<StatsRow
name="Sync"
color={Settings.theme.primary}
data={{ content: numeralWrapper.formatSleeveSynchro(props.sleeve.sync) }}
/>
<StatsRow
name="Memory"
color={Settings.theme.primary}
data={{ content: numeralWrapper.formatSleeveMemory(props.sleeve.memory) }}
/>
</TableBody>
</Table>
)
);
}
export function EarningsElement(props: IProps): React.ReactElement {
@@ -60,7 +94,12 @@ export function EarningsElement(props: IProps): React.ReactElement {
let data: any[][] = [];
if (props.sleeve.currentTask === SleeveTaskType.Crime) {
data = [
[`Money`, <><Money money={parseFloat(props.sleeve.currentTaskLocation)} /> (on success)</>],
[
`Money`,
<>
<Money money={parseFloat(props.sleeve.currentTaskLocation)} /> (on success)
</>,
],
[`Hacking Exp`, `${numeralWrapper.formatExp(props.sleeve.gainRatesForTask.hack)} (2x on success)`],
[`Strength Exp`, `${numeralWrapper.formatExp(props.sleeve.gainRatesForTask.str)} (2x on success)`],
[`Defense Exp`, `${numeralWrapper.formatExp(props.sleeve.gainRatesForTask.def)} (2x on success)`],
@@ -85,13 +124,11 @@ export function EarningsElement(props: IProps): React.ReactElement {
}
return (
<Table sx={{ display: 'table', mb: 1, width: '100%', lineHeight: 0 }}>
<Table sx={{ display: "table", mb: 1, width: "100%", lineHeight: 0 }}>
<TableBody>
<TableRow>
<TableCell classes={{ root: classes.cellNone }}>
<Typography variant='h6'>
Earnings
</Typography>
<Typography variant="h6">Earnings</Typography>
</TableCell>
</TableRow>
{data.map(([a, b]) => (
@@ -106,5 +143,5 @@ export function EarningsElement(props: IProps): React.ReactElement {
))}
</TableBody>
</Table>
)
);
}
+5 -5
View File
@@ -79,9 +79,9 @@ function possibleFactions(player: IPlayer, sleeve: Sleeve): string[] {
}
}
return factions.filter(faction => {
return factions.filter((faction) => {
const facInfo = Factions[faction].getInfo();
return facInfo.offerHackingWork || facInfo.offerFieldWork || facInfo.offerSecurityWork
return facInfo.offerHackingWork || facInfo.offerFieldWork || facInfo.offerSecurityWork;
});
}
@@ -319,7 +319,7 @@ export function TaskSelector(props: IProps): React.ReactElement {
return (
<>
<Select onChange={onS0Change} value={s0} sx={{ width: '100%' }}>
<Select onChange={onS0Change} value={s0} sx={{ width: "100%" }}>
{validActions.map((task) => (
<MenuItem key={task} value={task}>
{task}
@@ -328,7 +328,7 @@ export function TaskSelector(props: IProps): React.ReactElement {
</Select>
{!(details.first.length === 1 && details.first[0] === "------") && (
<>
<Select onChange={onS1Change} value={s1} sx={{ width: '100%' }}>
<Select onChange={onS1Change} value={s1} sx={{ width: "100%" }}>
{details.first.map((detail) => (
<MenuItem key={detail} value={detail}>
{detail}
@@ -339,7 +339,7 @@ export function TaskSelector(props: IProps): React.ReactElement {
)}
{!(details2.length === 1 && details2[0] === "------") && (
<>
<Select onChange={onS2Change} value={s2} sx={{ width: '100%' }}>
<Select onChange={onS2Change} value={s2} sx={{ width: "100%" }}>
{details2.map((detail) => (
<MenuItem key={detail} value={detail}>
{detail}
+11 -9
View File
@@ -24,20 +24,22 @@ export function getHackingWorkRepGain(p: IPlayer, f: Faction): number {
export function getFactionSecurityWorkRepGain(p: IPlayer, f: Faction): number {
const t =
(0.9 *
(p.strength + p.defense + p.dexterity + p.agility +
(p.hacking + p.intelligence) * CalculateShareMult()
)
) / CONSTANTS.MaxSkillLevel / 4.5;
(0.9 * (p.strength + p.defense + p.dexterity + p.agility + (p.hacking + p.intelligence) * CalculateShareMult())) /
CONSTANTS.MaxSkillLevel /
4.5;
return t * p.faction_rep_mult * mult(f) * p.getIntelligenceBonus(1);
}
export function getFactionFieldWorkRepGain(p: IPlayer, f: Faction): number {
const t =
(0.9 *
(p.strength + p.defense + p.dexterity + p.agility + p.charisma +
(p.hacking + p.intelligence) * CalculateShareMult()
)
) / CONSTANTS.MaxSkillLevel / 5.5;
(p.strength +
p.defense +
p.dexterity +
p.agility +
p.charisma +
(p.hacking + p.intelligence) * CalculateShareMult())) /
CONSTANTS.MaxSkillLevel /
5.5;
return t * p.faction_rep_mult * mult(f) * p.getIntelligenceBonus(1);
}
+12 -8
View File
@@ -13,14 +13,14 @@ export function calculateSkillProgress(exp: number, mult = 1): ISkillProgress {
let baseExperience = calculateExp(currentSkill, mult);
if (baseExperience < 0) baseExperience = 0;
let nextExperience = calculateExp(nextSkill, mult)
let nextExperience = calculateExp(nextSkill, mult);
if (nextExperience < 0) nextExperience = 0;
const normalize = (value: number): number => ((value - baseExperience) * 100) / (nextExperience - baseExperience);
let progress = (nextExperience - baseExperience !== 0) ? normalize(exp) : 99.99;
let progress = nextExperience - baseExperience !== 0 ? normalize(exp) : 99.99;
// Clamp progress: When sleeves are working out, the player gets way too much progress
if (progress < 0) progress = 0
if (progress < 0) progress = 0;
if (progress > 100) progress = 100;
// Clamp floating point imprecisions
@@ -37,8 +37,8 @@ export function calculateSkillProgress(exp: number, mult = 1): ISkillProgress {
nextExperience,
currentExperience,
remainingExperience,
progress
}
progress,
};
}
export interface ISkillProgress {
@@ -54,9 +54,13 @@ export interface ISkillProgress {
export function getEmptySkillProgress(): ISkillProgress {
return {
currentSkill: 0, nextSkill: 0,
baseExperience: 0, experience: 0, nextExperience: 0,
currentExperience: 0, remainingExperience: 0,
currentSkill: 0,
nextSkill: 0,
baseExperience: 0,
experience: 0,
nextExperience: 0,
currentExperience: 0,
remainingExperience: 0,
progress: 0,
};
}