mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-12-18 12:15:44 +01:00
post-grafting changes
This commit is contained in:
parent
fb1bce579f
commit
680081c548
@ -12,4 +12,5 @@ must be unlocked.
|
||||
Source-Files <advancedgameplay/sourcefiles>
|
||||
Intelligence <advancedgameplay/intelligence>
|
||||
Sleeves <advancedgameplay/sleeves>
|
||||
Grafting <advancedgameplay/grafting>
|
||||
Hacking algorithms <advancedgameplay/hackingalgorithms>
|
||||
|
18
doc/source/advancedgameplay/grafting.rst
Normal file
18
doc/source/advancedgameplay/grafting.rst
Normal file
@ -0,0 +1,18 @@
|
||||
.. _gameplay_grafting:
|
||||
|
||||
Grafting
|
||||
========
|
||||
Grafting is an experimental process through which you can obtain the benefits of
|
||||
Augmentations, without needing to reboot your body.
|
||||
|
||||
In order to graft, you must first purchase a blueprint for and craft the Augmentation.
|
||||
This can be done at VitaLife in New Tokyo, where you'll find a shady researcher with
|
||||
questionable connections. Once you purchase a blueprint, you will start crafting the
|
||||
Augmentation, and it will be grafted to your body once complete.
|
||||
|
||||
Be warned, some who have tested grafting have reported an unidentified malware. Dubbed
|
||||
"Entropy", this virus seems to grow in potency as more Augmentations are grafted,
|
||||
causing unpredictable affects to the victim.
|
||||
|
||||
Note that when crafting an Augmentation, cancelling will **not** save your progress,
|
||||
and the money spent will **not** be returned.
|
@ -16,4 +16,4 @@ Intelligence will boost your production for many actions in the game, including:
|
||||
* Crime success rate
|
||||
* Bladeburner
|
||||
* Reputation gain for companies & factions
|
||||
* Augmentation crafting speed
|
||||
* Augmentation grafting speed
|
||||
|
@ -91,20 +91,3 @@ and above, and is only available after defeating BitNode-10 at least once.
|
||||
|
||||
Memory is a persistent stat, meaning it never gets reset back to 1.
|
||||
The maximum possible value for a sleeve's memory is 100.
|
||||
|
||||
Grafting
|
||||
^^^^^^^^
|
||||
Grafting is an experimental process through which you can obtain the benefits of
|
||||
Augmentations, without needing to install them.
|
||||
|
||||
In order to graft, you must first purchase a blueprint for and craft the Augmentation.
|
||||
This can be done at VitaLife in New Tokyo, where you'll find a shady researcher with
|
||||
questionable connections. Once you purchase a blueprint, you will start crafting the
|
||||
Augmentation, and it will be grafted to your body once complete.
|
||||
|
||||
Be warned, some who have tested grafting have reported an unidentified malware. Dubbed
|
||||
"Entropy", this virus seems to grow in potency as more Augmentations are grafted,
|
||||
causing unpredictable affects to the victim.
|
||||
|
||||
Note that when crafting an Augmentation, cancelling will **not** save your progress,
|
||||
and the money spent will **not** be returned.
|
||||
|
@ -53,7 +53,7 @@ List of all Source-Files
|
||||
+-------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
|| BitNode-10: Digital Carbon || * Each level of this grants a Duplicate Sleeve. |
|
||||
|| || * Allows the player to access the `Sleeve API <https://github.com/danielyxie/bitburner/blob/dev/markdown/bitburner.sleeve.md>`_ in other BitNodes. |
|
||||
|| || * Grants the player access to the VitaLife grafting laboratory in other BitNodes. Also grants access to the Grafting API. |
|
||||
|| || * Grants the player access to the VitaLife secret laboratory in other BitNodes. Also grants access to the Grafting API. |
|
||||
+-------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
|| BitNode-11: The Big Crash || * Company favor increases both the player's salary and reputation gain at that |
|
||||
|| || company by 1% per favor (rather than just the reputation gain). |
|
||||
|
@ -59,7 +59,7 @@ export function InstalledAugmentations(): React.ReactElement {
|
||||
</Button>
|
||||
</Tooltip>
|
||||
<List dense>
|
||||
{player.entropyStacks > 0 &&
|
||||
{player.entropy > 0 &&
|
||||
(() => {
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
@ -69,7 +69,7 @@ export function InstalledAugmentations(): React.ReactElement {
|
||||
<ListItemText
|
||||
primary={
|
||||
<Typography color={Settings.theme.hp} style={{ whiteSpace: "pre-wrap" }}>
|
||||
Entropy ({player.entropyStacks} accumulated)
|
||||
Entropy virus - Level {player.entropy}
|
||||
</Typography>
|
||||
}
|
||||
/>
|
||||
@ -83,7 +83,7 @@ export function InstalledAugmentations(): React.ReactElement {
|
||||
<Box m={4}>
|
||||
<Typography color={Settings.theme.hp}>
|
||||
<b>All multipliers decreased by:</b>{" "}
|
||||
{formatNumber((1 - CONSTANTS.EntropyEffect ** player.entropyStacks) * 100, 3)}% (multiplicative)
|
||||
{formatNumber((1 - CONSTANTS.EntropyEffect ** player.entropy) * 100, 3)}% (multiplicative)
|
||||
</Typography>
|
||||
</Box>
|
||||
</Collapse>
|
||||
|
@ -41,7 +41,7 @@ export const CONSTANTS: {
|
||||
IntelligenceInfiltrationWeight: number;
|
||||
IntelligenceCrimeBaseExpGain: number;
|
||||
IntelligenceProgramBaseExpGain: number;
|
||||
IntelligenceCraftBaseExpGain: number;
|
||||
IntelligenceGraftBaseExpGain: number;
|
||||
IntelligenceTerminalHackBaseExpGain: number;
|
||||
IntelligenceSingFnBaseExpGain: number;
|
||||
IntelligenceClassBaseExpGain: number;
|
||||
@ -72,7 +72,7 @@ export const CONSTANTS: {
|
||||
WorkTypeCreateProgram: string;
|
||||
WorkTypeStudyClass: string;
|
||||
WorkTypeCrime: string;
|
||||
WorkTypeCraftAugmentation: string;
|
||||
WorkTypeGraftAugmentation: string;
|
||||
ClassStudyComputerScience: string;
|
||||
ClassDataStructures: string;
|
||||
ClassNetworks: string;
|
||||
@ -110,8 +110,8 @@ export const CONSTANTS: {
|
||||
CodingContractBaseFactionRepGain: number;
|
||||
CodingContractBaseCompanyRepGain: number;
|
||||
CodingContractBaseMoneyGain: number;
|
||||
AugmentationCraftingCostMult: number;
|
||||
AugmentationCraftingTimeBase: number;
|
||||
AugmentationGraftingCostMult: number;
|
||||
AugmentationGraftingTimeBase: number;
|
||||
EntropyEffect: number;
|
||||
TotalNumBitNodes: number;
|
||||
LatestUpdate: string;
|
||||
@ -185,7 +185,7 @@ export const CONSTANTS: {
|
||||
IntelligenceInfiltrationWeight: 0.1, // Weight for how much int affects infiltration success rates
|
||||
IntelligenceCrimeBaseExpGain: 0.05,
|
||||
IntelligenceProgramBaseExpGain: 0.1, // Program required hack level divided by this to determine int exp gain
|
||||
IntelligenceCraftBaseExpGain: 0.05,
|
||||
IntelligenceGraftBaseExpGain: 0.05,
|
||||
IntelligenceTerminalHackBaseExpGain: 200, // Hacking exp divided by this to determine int exp gain
|
||||
IntelligenceSingFnBaseExpGain: 1.5,
|
||||
IntelligenceClassBaseExpGain: 0.01,
|
||||
@ -230,7 +230,7 @@ export const CONSTANTS: {
|
||||
WorkTypeCreateProgram: "Working on Create a Program",
|
||||
WorkTypeStudyClass: "Studying or Taking a class at university",
|
||||
WorkTypeCrime: "Committing a crime",
|
||||
WorkTypeCraftAugmentation: "Crafting an Augmentation",
|
||||
WorkTypeGraftAugmentation: "Grafting an Augmentation",
|
||||
|
||||
ClassStudyComputerScience: "studying Computer Science",
|
||||
ClassDataStructures: "taking a Data Structures course",
|
||||
@ -277,11 +277,11 @@ export const CONSTANTS: {
|
||||
CodingContractBaseMoneyGain: 75e6,
|
||||
|
||||
// Augmentation crafting multipliers
|
||||
AugmentationCraftingCostMult: 1.2,
|
||||
AugmentationCraftingTimeBase: 3600000,
|
||||
AugmentationGraftingCostMult: 3,
|
||||
AugmentationGraftingTimeBase: 3600000,
|
||||
|
||||
// Value raised to the number of entropy stacks, then multiplied to player multipliers
|
||||
EntropyEffect: 0.99,
|
||||
EntropyEffect: 0.98,
|
||||
|
||||
// BitNode/Source-File related stuff
|
||||
TotalNumBitNodes: 24,
|
||||
|
@ -27,21 +27,21 @@ export function Entropy(props: IProps): React.ReactElement {
|
||||
<Adjuster
|
||||
label="Set entropy"
|
||||
placeholder="entropy"
|
||||
add={num => {
|
||||
props.player.entropyStacks += num;
|
||||
props.player.applyEntropy(props.player.entropyStacks);
|
||||
add={(num) => {
|
||||
props.player.entropy += num;
|
||||
props.player.applyEntropy(props.player.entropy);
|
||||
}}
|
||||
subtract={num => {
|
||||
props.player.entropyStacks -= num;
|
||||
props.player.applyEntropy(props.player.entropyStacks);
|
||||
subtract={(num) => {
|
||||
props.player.entropy -= num;
|
||||
props.player.applyEntropy(props.player.entropy);
|
||||
}}
|
||||
tons={() => {
|
||||
props.player.entropyStacks += 1e12;
|
||||
props.player.applyEntropy(props.player.entropyStacks);
|
||||
props.player.entropy += 1e12;
|
||||
props.player.applyEntropy(props.player.entropy);
|
||||
}}
|
||||
reset={() => {
|
||||
props.player.entropyStacks = 0;
|
||||
props.player.applyEntropy(props.player.entropyStacks);
|
||||
props.player.entropy = 0;
|
||||
props.player.applyEntropy(props.player.entropy);
|
||||
}}
|
||||
/>
|
||||
</AccordionDetails>
|
||||
|
@ -389,7 +389,7 @@ export const RamCosts: IMap<any> = {
|
||||
grafting: {
|
||||
getAugmentationCraftPrice: 3.75,
|
||||
getAugmentationCraftTime: 3.75,
|
||||
craftAugmentation: 7.5,
|
||||
graftAugmentation: 7.5,
|
||||
},
|
||||
|
||||
heart: {
|
||||
|
@ -2318,7 +2318,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
|
||||
tor: Player.hasTorRouter(),
|
||||
inBladeburner: Player.inBladeburner(),
|
||||
hasCorporation: Player.hasCorporation(),
|
||||
entropyStacks: Player.entropyStacks,
|
||||
entropy: Player.entropy,
|
||||
};
|
||||
Object.assign(data.jobs, Player.jobs);
|
||||
return data;
|
||||
|
@ -2,16 +2,15 @@ import { CityName } from "../Locations/data/CityNames";
|
||||
import { Augmentations } from "../Augmentation/Augmentations";
|
||||
import { getRamCost } from "../Netscript/RamCostGenerator";
|
||||
import { WorkerScript } from "../Netscript/WorkerScript";
|
||||
import { CraftableAugmentation } from "../PersonObjects/Grafting/CraftableAugmentation";
|
||||
import { GraftableAugmentation } from "../PersonObjects/Grafting/GraftableAugmentation";
|
||||
import { getAvailableAugs } from "../PersonObjects/Grafting/ui/GraftingRoot";
|
||||
import { IPlayer } from "../PersonObjects/IPlayer";
|
||||
import { Grafting as IGrafting } from "../ScriptEditor/NetscriptDefinitions";
|
||||
import { SourceFileFlags } from "../SourceFile/SourceFileFlags";
|
||||
import { Router } from "../ui/GameRoot";
|
||||
import { INetscriptHelper } from "./INetscriptHelper";
|
||||
|
||||
export function NetscriptGrafting(player: IPlayer, workerScript: WorkerScript, helper: INetscriptHelper): IGrafting {
|
||||
const checkGraftingAPIAccess = (func: any): void => {
|
||||
const checkGraftingAPIAccess = (func: string): void => {
|
||||
if (!player.canAccessGrafting()) {
|
||||
throw helper.makeRuntimeErrorMsg(
|
||||
`grafting.${func}`,
|
||||
@ -21,54 +20,58 @@ export function NetscriptGrafting(player: IPlayer, workerScript: WorkerScript, h
|
||||
};
|
||||
|
||||
return {
|
||||
getAugmentationCraftPrice: (augName: string): number => {
|
||||
helper.updateDynamicRam("getAugmentationCraftPrice", getRamCost(player, "grafting", "getAugmentationCraftPrice"));
|
||||
checkGraftingAPIAccess("getAugmentationCraftPrice");
|
||||
getAugmentationGraftPrice: (_augName: unknown): number => {
|
||||
const augName = helper.string("getAugmentationGraftPrice", "augName", _augName);
|
||||
helper.updateDynamicRam("getAugmentationGraftPrice", getRamCost(player, "grafting", "getAugmentationGraftPrice"));
|
||||
checkGraftingAPIAccess("getAugmentationGraftPrice");
|
||||
if (!Augmentations.hasOwnProperty(augName)) {
|
||||
throw helper.makeRuntimeErrorMsg("grafting.getAugmentationCraftPrice", `Invalid aug: ${augName}`);
|
||||
throw helper.makeRuntimeErrorMsg("grafting.getAugmentationGraftPrice", `Invalid aug: ${augName}`);
|
||||
}
|
||||
const craftableAug = new CraftableAugmentation(Augmentations[augName]);
|
||||
const craftableAug = new GraftableAugmentation(Augmentations[augName]);
|
||||
return craftableAug.cost;
|
||||
},
|
||||
|
||||
getAugmentationCraftTime: (augName: string): number => {
|
||||
helper.updateDynamicRam("getAugmentationCraftTime", getRamCost(player, "grafting", "getAugmentationCraftTime"));
|
||||
checkGraftingAPIAccess("getAugmentationCraftTime");
|
||||
getAugmentationGraftTime: (_augName: string): number => {
|
||||
const augName = helper.string("getAugmentationGraftTime", "augName", _augName);
|
||||
helper.updateDynamicRam("getAugmentationGraftTime", getRamCost(player, "grafting", "getAugmentationGraftTime"));
|
||||
checkGraftingAPIAccess("getAugmentationGraftTime");
|
||||
if (!Augmentations.hasOwnProperty(augName)) {
|
||||
throw helper.makeRuntimeErrorMsg("grafting.getAugmentationCraftTime", `Invalid aug: ${augName}`);
|
||||
throw helper.makeRuntimeErrorMsg("grafting.getAugmentationGraftTime", `Invalid aug: ${augName}`);
|
||||
}
|
||||
const craftableAug = new CraftableAugmentation(Augmentations[augName]);
|
||||
const craftableAug = new GraftableAugmentation(Augmentations[augName]);
|
||||
return craftableAug.time;
|
||||
},
|
||||
|
||||
craftAugmentation: (augName: string, focus = true): boolean => {
|
||||
helper.updateDynamicRam("craftAugmentation", getRamCost(player, "grafting", "craftAugmentation"));
|
||||
checkGraftingAPIAccess("craftAugmentation");
|
||||
graftAugmentation: (_augName: string, _focus: unknown = true): boolean => {
|
||||
const augName = helper.string("graftAugmentation", "augName", _augName);
|
||||
const focus = helper.boolean(_focus);
|
||||
helper.updateDynamicRam("graftAugmentation", getRamCost(player, "grafting", "graftAugmentation"));
|
||||
checkGraftingAPIAccess("graftAugmentation");
|
||||
if (player.city !== CityName.NewTokyo) {
|
||||
throw helper.makeRuntimeErrorMsg(
|
||||
"grafting.craftAugmentation",
|
||||
"grafting.graftAugmentation",
|
||||
"You must be in New Tokyo to begin crafting an Augmentation.",
|
||||
);
|
||||
}
|
||||
if (!getAvailableAugs(player).includes(augName)) {
|
||||
workerScript.log("grafting.craftAugmentation", () => `Invalid aug: ${augName}`);
|
||||
workerScript.log("grafting.graftAugmentation", () => `Invalid aug: ${augName}`);
|
||||
return false;
|
||||
}
|
||||
|
||||
const wasFocusing = player.focus;
|
||||
if (player.isWorking) {
|
||||
const txt = player.singularityStopWork();
|
||||
workerScript.log("craftAugmentation", () => txt);
|
||||
workerScript.log("graftAugmentation", () => txt);
|
||||
}
|
||||
|
||||
const craftableAug = new CraftableAugmentation(Augmentations[augName]);
|
||||
const craftableAug = new GraftableAugmentation(Augmentations[augName]);
|
||||
if (player.money < craftableAug.cost) {
|
||||
workerScript.log("grafting.craftAugmentation", () => `You don't have enough money to craft ${augName}`);
|
||||
workerScript.log("grafting.graftAugmentation", () => `You don't have enough money to craft ${augName}`);
|
||||
return false;
|
||||
}
|
||||
|
||||
player.loseMoney(craftableAug.cost, "augmentations");
|
||||
player.startCraftAugmentationWork(augName, craftableAug.time);
|
||||
player.startGraftAugmentationWork(augName, craftableAug.time);
|
||||
|
||||
if (focus) {
|
||||
player.startFocusing();
|
||||
@ -78,7 +81,7 @@ export function NetscriptGrafting(player: IPlayer, workerScript: WorkerScript, h
|
||||
Router.toTerminal();
|
||||
}
|
||||
|
||||
workerScript.log("grafting.craftAugmentation", () => `Began crafting Augmentation ${augName}.`);
|
||||
workerScript.log("grafting.graftAugmentation", () => `Began crafting Augmentation ${augName}.`);
|
||||
return true;
|
||||
},
|
||||
};
|
||||
|
@ -9,7 +9,7 @@ export interface IConstructorParams {
|
||||
readonly time: number;
|
||||
}
|
||||
|
||||
export class CraftableAugmentation {
|
||||
export class GraftableAugmentation {
|
||||
// The augmentation that this craftable corresponds to
|
||||
augmentation: Augmentation;
|
||||
|
||||
@ -18,7 +18,7 @@ export class CraftableAugmentation {
|
||||
}
|
||||
|
||||
get cost(): number {
|
||||
return this.augmentation.startingCost * CONSTANTS.AugmentationCraftingCostMult;
|
||||
return this.augmentation.startingCost * CONSTANTS.AugmentationGraftingCostMult;
|
||||
}
|
||||
|
||||
get time(): number {
|
||||
@ -26,6 +26,6 @@ export class CraftableAugmentation {
|
||||
const antiLog = Math.max(sum(Object.values(this.augmentation.mults)), 1);
|
||||
|
||||
const mult = Math.log2(antiLog);
|
||||
return CONSTANTS.AugmentationCraftingTimeBase * mult + CONSTANTS.MillisecondsPerHalfHour;
|
||||
return CONSTANTS.AugmentationGraftingTimeBase * mult + CONSTANTS.MillisecondsPerHalfHour;
|
||||
}
|
||||
}
|
@ -17,9 +17,9 @@ import { CONSTANTS } from "../../../Constants";
|
||||
|
||||
import { IPlayer } from "../../IPlayer";
|
||||
|
||||
import { CraftableAugmentation } from "../CraftableAugmentation";
|
||||
import { GraftableAugmentation } from "../GraftableAugmentation";
|
||||
|
||||
const CraftableAugmentations: IMap<CraftableAugmentation> = {};
|
||||
const GraftableAugmentations: IMap<GraftableAugmentation> = {};
|
||||
|
||||
export const getAvailableAugs = (player: IPlayer): string[] => {
|
||||
const augs: string[] = [];
|
||||
@ -39,12 +39,12 @@ export const GraftingRoot = (): React.ReactElement => {
|
||||
|
||||
for (const aug of Object.values(Augmentations)) {
|
||||
const name = aug.name;
|
||||
const craftableAug = new CraftableAugmentation(aug);
|
||||
CraftableAugmentations[name] = craftableAug;
|
||||
const graftableAug = new GraftableAugmentation(aug);
|
||||
GraftableAugmentations[name] = graftableAug;
|
||||
}
|
||||
|
||||
const [selectedAug, setSelectedAug] = useState(getAvailableAugs(player)[0]);
|
||||
const [craftOpen, setCraftOpen] = useState(false);
|
||||
const [graftOpen, setGraftOpen] = useState(false);
|
||||
|
||||
return (
|
||||
<Container disableGutters maxWidth="lg" sx={{ mx: 0 }}>
|
||||
@ -63,7 +63,7 @@ export const GraftingRoot = (): React.ReactElement => {
|
||||
</Typography>
|
||||
|
||||
<Box sx={{ my: 3 }}>
|
||||
<Typography variant="h5">Craft Augmentations</Typography>
|
||||
<Typography variant="h5">Graft Augmentations</Typography>
|
||||
<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) => (
|
||||
@ -77,29 +77,29 @@ export const GraftingRoot = (): React.ReactElement => {
|
||||
<Construction sx={{ mr: 1 }} /> {selectedAug}
|
||||
</Typography>
|
||||
<Button
|
||||
onClick={() => setCraftOpen(true)}
|
||||
onClick={() => setGraftOpen(true)}
|
||||
sx={{ width: "100%" }}
|
||||
disabled={player.money < CraftableAugmentations[selectedAug].cost}
|
||||
disabled={player.money < GraftableAugmentations[selectedAug].cost}
|
||||
>
|
||||
Craft Augmentation (
|
||||
<Typography color={Settings.theme.money}>
|
||||
<Money money={CraftableAugmentations[selectedAug].cost} player={player} />
|
||||
Graft Augmentation (
|
||||
<Typography>
|
||||
<Money money={GraftableAugmentations[selectedAug].cost} player={player} />
|
||||
</Typography>
|
||||
)
|
||||
</Button>
|
||||
<ConfirmationModal
|
||||
open={craftOpen}
|
||||
onClose={() => setCraftOpen(false)}
|
||||
open={graftOpen}
|
||||
onClose={() => setGraftOpen(false)}
|
||||
onConfirm={() => {
|
||||
const craftableAug = CraftableAugmentations[selectedAug];
|
||||
player.loseMoney(craftableAug.cost, "augmentations");
|
||||
player.startCraftAugmentationWork(selectedAug, craftableAug.time);
|
||||
const graftableAug = GraftableAugmentations[selectedAug];
|
||||
player.loseMoney(graftableAug.cost, "augmentations");
|
||||
player.startGraftAugmentationWork(selectedAug, graftableAug.time);
|
||||
player.startFocusing();
|
||||
router.toWork();
|
||||
}}
|
||||
confirmationText={
|
||||
<>
|
||||
Cancelling crafting will <b>not</b> save crafting progress, and the money you spend will <b>not</b> be
|
||||
Cancelling grafting will <b>not</b> save grafting progress, and the money you spend will <b>not</b> be
|
||||
returned.
|
||||
<br />
|
||||
<br />
|
||||
@ -108,9 +108,9 @@ export const GraftingRoot = (): React.ReactElement => {
|
||||
}
|
||||
/>
|
||||
<Typography color={Settings.theme.info}>
|
||||
<b>Time to Craft:</b>{" "}
|
||||
<b>Time to Graft:</b>{" "}
|
||||
{convertTimeMsToTimeElapsedString(
|
||||
CraftableAugmentations[selectedAug].time / (1 + (player.getIntelligenceBonus(3) - 1) / 3),
|
||||
GraftableAugmentations[selectedAug].time / (1 + (player.getIntelligenceBonus(3) - 1) / 3),
|
||||
)}
|
||||
{/* Use formula so the displayed creation time is accurate to player bonus */}
|
||||
</Typography>
|
||||
@ -135,14 +135,14 @@ export const GraftingRoot = (): React.ReactElement => {
|
||||
</Box>
|
||||
|
||||
<Box sx={{ my: 3 }}>
|
||||
<Typography variant="h5">Entropy Accumulation</Typography>
|
||||
<Typography variant="h5">Entropy virus</Typography>
|
||||
|
||||
<Paper sx={{ my: 1, p: 1, width: "fit-content" }}>
|
||||
<Typography>
|
||||
<b>Accumulated Entropy:</b> {player.entropyStacks}
|
||||
<b>Entropy strength:</b> {player.entropy}
|
||||
<br />
|
||||
<b>All multipliers decreased by:</b>{" "}
|
||||
{formatNumber((1 - CONSTANTS.EntropyEffect ** player.entropyStacks) * 100, 3)}% (multiplicative)
|
||||
{formatNumber((1 - CONSTANTS.EntropyEffect ** player.entropy) * 100, 3)}% (multiplicative)
|
||||
</Typography>
|
||||
</Paper>
|
||||
|
||||
|
@ -128,8 +128,8 @@ export interface IPlayer {
|
||||
factionWorkType: string;
|
||||
createProgramName: string;
|
||||
timeWorkedCreateProgram: number;
|
||||
craftAugmentationName: string;
|
||||
timeWorkedCraftAugmentation: number;
|
||||
graftAugmentationName: string;
|
||||
timeWorkedGraftAugmentation: number;
|
||||
crimeType: string;
|
||||
committingCrimeThruSingFn: boolean;
|
||||
singFnCrimeWorkerScript: WorkerScript | null;
|
||||
@ -160,7 +160,7 @@ export interface IPlayer {
|
||||
workChaExpGainRate: number;
|
||||
workMoneyLossRate: number;
|
||||
|
||||
entropyStacks: number;
|
||||
entropy: number;
|
||||
|
||||
// Methods
|
||||
work(numCycles: number): boolean;
|
||||
@ -288,8 +288,8 @@ export interface IPlayer {
|
||||
setMult(name: string, mult: number): void;
|
||||
canAccessCotMG(): boolean;
|
||||
sourceFileLvl(n: number): number;
|
||||
startCraftAugmentationWork(augmentationName: string, time: number): void;
|
||||
craftAugmentationWork(numCycles: number): boolean;
|
||||
finishCraftAugmentationWork(cancelled: boolean): string;
|
||||
startGraftAugmentationWork(augmentationName: string, time: number): void;
|
||||
graftAugmentationWork(numCycles: number): boolean;
|
||||
finishGraftAugmentationWork(cancelled: boolean): string;
|
||||
applyEntropy(stacks?: number): void;
|
||||
}
|
||||
|
@ -137,8 +137,8 @@ export class PlayerObject implements IPlayer {
|
||||
factionWorkType: string;
|
||||
createProgramName: string;
|
||||
timeWorkedCreateProgram: number;
|
||||
craftAugmentationName: string;
|
||||
timeWorkedCraftAugmentation: number;
|
||||
graftAugmentationName: string;
|
||||
timeWorkedGraftAugmentation: number;
|
||||
crimeType: string;
|
||||
committingCrimeThruSingFn: boolean;
|
||||
singFnCrimeWorkerScript: WorkerScript | null;
|
||||
@ -169,7 +169,7 @@ export class PlayerObject implements IPlayer {
|
||||
workChaExpGainRate: number;
|
||||
workMoneyLossRate: number;
|
||||
|
||||
entropyStacks: number;
|
||||
entropy: number;
|
||||
|
||||
// Methods
|
||||
work: (numCycles: number) => boolean;
|
||||
@ -298,9 +298,9 @@ export class PlayerObject implements IPlayer {
|
||||
setMult: (name: string, mult: number) => void;
|
||||
canAccessCotMG: () => boolean;
|
||||
sourceFileLvl: (n: number) => number;
|
||||
startCraftAugmentationWork: (augmentationName: string, time: number) => void;
|
||||
craftAugmentationWork: (numCycles: number) => boolean;
|
||||
finishCraftAugmentationWork: (cancelled: boolean) => string;
|
||||
startGraftAugmentationWork: (augmentationName: string, time: number) => void;
|
||||
graftAugmentationWork: (numCycles: number) => boolean;
|
||||
finishGraftAugmentationWork: (cancelled: boolean) => string;
|
||||
applyEntropy: (stacks?: number) => void;
|
||||
|
||||
constructor() {
|
||||
@ -425,8 +425,8 @@ export class PlayerObject implements IPlayer {
|
||||
this.createProgramName = "";
|
||||
this.createProgramReqLvl = 0;
|
||||
|
||||
this.craftAugmentationName = "";
|
||||
this.timeWorkedCraftAugmentation = 0;
|
||||
this.graftAugmentationName = "";
|
||||
this.timeWorkedGraftAugmentation = 0;
|
||||
|
||||
this.className = "";
|
||||
|
||||
@ -470,7 +470,7 @@ export class PlayerObject implements IPlayer {
|
||||
//bitnode
|
||||
this.bitNodeN = 1;
|
||||
|
||||
this.entropyStacks = 0;
|
||||
this.entropy = 0;
|
||||
|
||||
//Used to store the last update time.
|
||||
this.lastUpdate = 0;
|
||||
@ -493,11 +493,11 @@ export class PlayerObject implements IPlayer {
|
||||
// Let's get a hash of some semi-random stuff so we have something unique.
|
||||
this.identifier = cyrb53(
|
||||
"I-" +
|
||||
new Date().getTime() +
|
||||
navigator.userAgent +
|
||||
window.innerWidth +
|
||||
window.innerHeight +
|
||||
getRandomInt(100, 999),
|
||||
new Date().getTime() +
|
||||
navigator.userAgent +
|
||||
window.innerWidth +
|
||||
window.innerHeight +
|
||||
getRandomInt(100, 999),
|
||||
);
|
||||
|
||||
this.init = generalMethods.init;
|
||||
@ -551,9 +551,9 @@ export class PlayerObject implements IPlayer {
|
||||
this.startCreateProgramWork = generalMethods.startCreateProgramWork;
|
||||
this.createProgramWork = generalMethods.createProgramWork;
|
||||
this.finishCreateProgramWork = generalMethods.finishCreateProgramWork;
|
||||
this.startCraftAugmentationWork = generalMethods.startCraftAugmentationWork;
|
||||
this.craftAugmentationWork = generalMethods.craftAugmentationWork;
|
||||
this.finishCraftAugmentationWork = generalMethods.finishCraftAugmentationWork;
|
||||
this.startGraftAugmentationWork = generalMethods.startGraftAugmentationWork;
|
||||
this.graftAugmentationWork = generalMethods.craftAugmentationWork;
|
||||
this.finishGraftAugmentationWork = generalMethods.finishGraftAugmentationWork;
|
||||
this.startClass = generalMethods.startClass;
|
||||
this.takeClass = generalMethods.takeClass;
|
||||
this.finishClass = generalMethods.finishClass;
|
||||
|
@ -180,7 +180,7 @@ export function prestigeAugmentation(this: PlayerObject): void {
|
||||
}
|
||||
|
||||
export function prestigeSourceFile(this: IPlayer): void {
|
||||
this.entropyStacks = 0;
|
||||
this.entropy = 0;
|
||||
this.prestigeAugmentation();
|
||||
this.karma = 0;
|
||||
// Duplicate sleeves are reset to level 1 every Bit Node (but the number of sleeves you have persists)
|
||||
@ -528,12 +528,12 @@ export function resetWorkStatus(this: IPlayer, generalType?: string, group?: str
|
||||
|
||||
this.timeWorked = 0;
|
||||
this.timeWorkedCreateProgram = 0;
|
||||
this.timeWorkedCraftAugmentation = 0;
|
||||
this.timeWorkedGraftAugmentation = 0;
|
||||
|
||||
this.currentWorkFactionName = "";
|
||||
this.currentWorkFactionDescription = "";
|
||||
this.createProgramName = "";
|
||||
this.craftAugmentationName = "";
|
||||
this.graftAugmentationName = "";
|
||||
this.className = "";
|
||||
this.workType = "";
|
||||
}
|
||||
@ -610,8 +610,8 @@ export function process(this: IPlayer, router: IRouter, numCycles = 1): void {
|
||||
if (this.workPartTime(numCycles)) {
|
||||
router.toCity();
|
||||
}
|
||||
} else if (this.workType === CONSTANTS.WorkTypeCraftAugmentation) {
|
||||
if (this.craftAugmentationWork(numCycles)) {
|
||||
} else if (this.workType === CONSTANTS.WorkTypeGraftAugmentation) {
|
||||
if (this.graftAugmentationWork(numCycles)) {
|
||||
router.toGrafting();
|
||||
}
|
||||
} else if (this.work(numCycles)) {
|
||||
@ -1335,17 +1335,13 @@ export function finishCreateProgramWork(this: IPlayer, cancelled: boolean): stri
|
||||
return "You've finished creating " + programName + "! The new program can be found on your home computer.";
|
||||
}
|
||||
|
||||
export function startCraftAugmentationWork(
|
||||
this: IPlayer,
|
||||
augmentationName: string,
|
||||
time: number,
|
||||
): void {
|
||||
this.resetWorkStatus()
|
||||
export function startGraftAugmentationWork(this: IPlayer, augmentationName: string, time: number): void {
|
||||
this.resetWorkStatus();
|
||||
this.isWorking = true;
|
||||
this.workType = CONSTANTS.WorkTypeCraftAugmentation;
|
||||
this.workType = CONSTANTS.WorkTypeGraftAugmentation;
|
||||
|
||||
this.timeNeededToCompleteWork = time;
|
||||
this.craftAugmentationName = augmentationName;
|
||||
this.graftAugmentationName = augmentationName;
|
||||
}
|
||||
|
||||
export function craftAugmentationWork(this: IPlayer, numCycles: number): boolean {
|
||||
@ -1358,35 +1354,37 @@ export function craftAugmentationWork(this: IPlayer, numCycles: number): boolean
|
||||
skillMult *= focusBonus;
|
||||
|
||||
this.timeWorked += CONSTANTS._idleSpeed * numCycles;
|
||||
this.timeWorkedCraftAugmentation += CONSTANTS._idleSpeed * numCycles * skillMult;
|
||||
this.timeWorkedGraftAugmentation += CONSTANTS._idleSpeed * numCycles * skillMult;
|
||||
|
||||
if (this.timeWorkedCraftAugmentation >= this.timeNeededToCompleteWork) {
|
||||
this.finishCraftAugmentationWork(false);
|
||||
if (this.timeWorkedGraftAugmentation >= this.timeNeededToCompleteWork) {
|
||||
this.finishGraftAugmentationWork(false);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export function finishCraftAugmentationWork(this: IPlayer, cancelled: boolean): string {
|
||||
const augName = this.craftAugmentationName;
|
||||
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.`)
|
||||
dialogBoxCreate(
|
||||
`You've finished crafting ${augName}.<br>The augmentation has been grafted to your body, but you feel a bit off.`,
|
||||
);
|
||||
|
||||
applyAugmentation(Augmentations[augName]);
|
||||
this.entropyStacks += 1;
|
||||
this.applyEntropy(this.entropyStacks);
|
||||
this.entropy += 1;
|
||||
this.applyEntropy(this.entropy);
|
||||
} else {
|
||||
dialogBoxCreate(`You cancelled the crafting of ${augName}.<br>Your money was not returned to you.`)
|
||||
dialogBoxCreate(`You cancelled the crafting of ${augName}.<br>Your money was not returned to you.`);
|
||||
}
|
||||
|
||||
// Intelligence gain
|
||||
if (!cancelled) {
|
||||
this.gainIntelligenceExp((CONSTANTS.IntelligenceCraftBaseExpGain * this.timeWorked) / 10000);
|
||||
this.gainIntelligenceExp((CONSTANTS.IntelligenceGraftBaseExpGain * this.timeWorked) / 10000);
|
||||
}
|
||||
|
||||
this.isWorking = false;
|
||||
this.resetWorkStatus();
|
||||
return `Crafting of ${augName} has ended.`
|
||||
return `Grafting of ${augName} has ended.`;
|
||||
}
|
||||
|
||||
/* Studying/Taking Classes */
|
||||
@ -1567,20 +1565,20 @@ export function finishCrime(this: IPlayer, cancelled: boolean): string {
|
||||
if (ws.disableLogs.ALL == null && ws.disableLogs.commitCrime == null) {
|
||||
ws.scriptRef.log(
|
||||
"SUCCESS: Crime successful! Gained " +
|
||||
numeralWrapper.formatMoney(this.workMoneyGained) +
|
||||
", " +
|
||||
numeralWrapper.formatExp(this.workHackExpGained) +
|
||||
" hack exp, " +
|
||||
numeralWrapper.formatExp(this.workStrExpGained) +
|
||||
" str exp, " +
|
||||
numeralWrapper.formatExp(this.workDefExpGained) +
|
||||
" def exp, " +
|
||||
numeralWrapper.formatExp(this.workDexExpGained) +
|
||||
" dex exp, " +
|
||||
numeralWrapper.formatExp(this.workAgiExpGained) +
|
||||
" agi exp, " +
|
||||
numeralWrapper.formatExp(this.workChaExpGained) +
|
||||
" cha exp.",
|
||||
numeralWrapper.formatMoney(this.workMoneyGained) +
|
||||
", " +
|
||||
numeralWrapper.formatExp(this.workHackExpGained) +
|
||||
" hack exp, " +
|
||||
numeralWrapper.formatExp(this.workStrExpGained) +
|
||||
" str exp, " +
|
||||
numeralWrapper.formatExp(this.workDefExpGained) +
|
||||
" def exp, " +
|
||||
numeralWrapper.formatExp(this.workDexExpGained) +
|
||||
" dex exp, " +
|
||||
numeralWrapper.formatExp(this.workAgiExpGained) +
|
||||
" agi exp, " +
|
||||
numeralWrapper.formatExp(this.workChaExpGained) +
|
||||
" cha exp.",
|
||||
);
|
||||
}
|
||||
} else {
|
||||
@ -1619,18 +1617,18 @@ export function finishCrime(this: IPlayer, cancelled: boolean): string {
|
||||
if (ws.disableLogs.ALL == null && ws.disableLogs.commitCrime == null) {
|
||||
ws.scriptRef.log(
|
||||
"FAIL: Crime failed! Gained " +
|
||||
numeralWrapper.formatExp(this.workHackExpGained) +
|
||||
" hack exp, " +
|
||||
numeralWrapper.formatExp(this.workStrExpGained) +
|
||||
" str exp, " +
|
||||
numeralWrapper.formatExp(this.workDefExpGained) +
|
||||
" def exp, " +
|
||||
numeralWrapper.formatExp(this.workDexExpGained) +
|
||||
" dex exp, " +
|
||||
numeralWrapper.formatExp(this.workAgiExpGained) +
|
||||
" agi exp, " +
|
||||
numeralWrapper.formatExp(this.workChaExpGained) +
|
||||
" cha exp.",
|
||||
numeralWrapper.formatExp(this.workHackExpGained) +
|
||||
" hack exp, " +
|
||||
numeralWrapper.formatExp(this.workStrExpGained) +
|
||||
" str exp, " +
|
||||
numeralWrapper.formatExp(this.workDefExpGained) +
|
||||
" def exp, " +
|
||||
numeralWrapper.formatExp(this.workDexExpGained) +
|
||||
" dex exp, " +
|
||||
numeralWrapper.formatExp(this.workAgiExpGained) +
|
||||
" agi exp, " +
|
||||
numeralWrapper.formatExp(this.workChaExpGained) +
|
||||
" cha exp.",
|
||||
);
|
||||
}
|
||||
} else {
|
||||
|
@ -109,7 +109,7 @@ export function prestigeAugmentation(): void {
|
||||
initMessages();
|
||||
|
||||
// Apply entropy from grafting
|
||||
Player.applyEntropy(Player.entropyStacks);
|
||||
Player.applyEntropy(Player.entropy);
|
||||
|
||||
// Gang
|
||||
const gang = Player.gang;
|
||||
|
@ -393,6 +393,11 @@ function evaluateVersionCompatibility(ver: string | number): void {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ver < 12) {
|
||||
if (anyPlayer.resleeves !== undefined) {
|
||||
delete anyPlayer.resleeves;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
26
src/ScriptEditor/NetscriptDefinitions.d.ts
vendored
26
src/ScriptEditor/NetscriptDefinitions.d.ts
vendored
@ -95,7 +95,7 @@ interface Player {
|
||||
tor: boolean;
|
||||
hasCorporation: boolean;
|
||||
inBladeburner: boolean;
|
||||
entropyStacks: number;
|
||||
entropy: number;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -3722,39 +3722,39 @@ export interface Sleeve {
|
||||
|
||||
export interface Grafting {
|
||||
/**
|
||||
* Retrieve the crafting cost of an aug.
|
||||
* Retrieve the grafting cost of an aug.
|
||||
* @remarks
|
||||
* RAM cost: 3.75 GB
|
||||
*
|
||||
* @param augName - Name of the aug to check the price of. Must be an exact match.
|
||||
* @returns The cost required to craft the named augmentation.
|
||||
* @returns The cost required to graft the named augmentation.
|
||||
* @throws Will error if an invalid Augmentation name is provided.
|
||||
*/
|
||||
getAugmentationCraftPrice(augName: string): number;
|
||||
getAugmentationGraftPrice(augName: string): number;
|
||||
|
||||
/**
|
||||
* Retrieves the time required to craft an aug.
|
||||
* Retrieves the time required to graft an aug.
|
||||
* @remarks
|
||||
* RAM cost: 3.75 GB
|
||||
*
|
||||
* @param augName - Name of the aug to check the crafting time of. Must be an exact match.
|
||||
* @returns The time required, in millis, to craft the named augmentation.
|
||||
* @param augName - Name of the aug to check the grafting time of. Must be an exact match.
|
||||
* @returns The time required, in millis, to graft the named augmentation.
|
||||
* @throws Will error if an invalid Augmentation name is provided.
|
||||
*/
|
||||
getAugmentationCraftTime(augName: string): number;
|
||||
getAugmentationGraftTime(augName: string): number;
|
||||
|
||||
/**
|
||||
* Begins crafting the named aug. You must be in New Tokyo to use this.
|
||||
* Begins grafting the named aug. You must be in New Tokyo to use this.
|
||||
* @remarks
|
||||
* RAM cost: 7.5 GB
|
||||
*
|
||||
* @param augName - The name of the aug to begin crafting. Must be an exact match.
|
||||
* @param focus - Acquire player focus on this Augmentation crafting. Optional. Defaults to true.
|
||||
* @returns True if the aug successfully began crafting, false otherwise (e.g. not enough money, or
|
||||
* @param augName - The name of the aug to begin grafting. Must be an exact match.
|
||||
* @param focus - Acquire player focus on this Augmentation grafting. Optional. Defaults to true.
|
||||
* @returns True if the aug successfully began grafting, false otherwise (e.g. not enough money, or
|
||||
* invalid Augmentation name provided).
|
||||
* @throws Will error if called while you are not in New Tokyo.
|
||||
*/
|
||||
craftAugmentation(augName: string, focus?: boolean): boolean;
|
||||
graftAugmentation(augName: string, focus?: boolean): boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -264,7 +264,7 @@ const Engine: {
|
||||
}
|
||||
|
||||
// Apply penalty for entropy accumulation
|
||||
Player.applyEntropy(Player.entropyStacks);
|
||||
Player.applyEntropy(Player.entropy);
|
||||
|
||||
// Calculate the number of cycles have elapsed while offline
|
||||
Engine._lastUpdate = new Date().getTime();
|
||||
@ -305,8 +305,8 @@ const Engine: {
|
||||
Player.commitCrime(numCyclesOffline);
|
||||
} else if (Player.workType == CONSTANTS.WorkTypeCompanyPartTime) {
|
||||
Player.workPartTime(numCyclesOffline);
|
||||
} else if (Player.workType === CONSTANTS.WorkTypeCraftAugmentation) {
|
||||
Player.craftAugmentationWork(numCyclesOffline);
|
||||
} else if (Player.workType === CONSTANTS.WorkTypeGraftAugmentation) {
|
||||
Player.graftAugmentationWork(numCyclesOffline);
|
||||
} else {
|
||||
Player.work(numCyclesOffline);
|
||||
}
|
||||
|
@ -194,13 +194,13 @@ function Work(): React.ReactElement {
|
||||
</>
|
||||
);
|
||||
break;
|
||||
case CONSTANTS.WorkTypeCraftAugmentation:
|
||||
details = <>Crafting {player.craftAugmentationName}</>;
|
||||
header = <>Crafting an Augmentation</>;
|
||||
case CONSTANTS.WorkTypeGraftAugmentation:
|
||||
details = <>Grafting {player.graftAugmentationName}</>;
|
||||
header = <>Grafting an Augmentation</>;
|
||||
innerText = (
|
||||
<>
|
||||
<strong>{((player.timeWorkedCraftAugmentation / player.timeNeededToCompleteWork) * 100).toFixed(2)}%</strong>
|
||||
{" "}done
|
||||
<strong>{((player.timeWorkedGraftAugmentation / player.timeNeededToCompleteWork) * 100).toFixed(2)}%</strong>{" "}
|
||||
done
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
@ -483,9 +483,9 @@ export function WorkInProgressRoot(): React.ReactElement {
|
||||
);
|
||||
}
|
||||
|
||||
if (player.craftAugmentationName !== "") {
|
||||
if (player.graftAugmentationName !== "") {
|
||||
function cancel(): void {
|
||||
player.finishCraftAugmentationWork(true);
|
||||
player.finishGraftAugmentationWork(true);
|
||||
router.toTerminal();
|
||||
}
|
||||
function unfocus(): void {
|
||||
@ -496,14 +496,14 @@ export function WorkInProgressRoot(): React.ReactElement {
|
||||
<Grid container direction="column" justifyContent="center" alignItems="center" style={{ minHeight: "100vh" }}>
|
||||
<Grid item>
|
||||
<Typography>
|
||||
You are currently working on crafting {player.craftAugmentationName}.
|
||||
You are currently working on crafting {player.graftAugmentationName}.
|
||||
<br />
|
||||
<br />
|
||||
You have been working for {convertTimeMsToTimeElapsedString(player.timeWorked)}
|
||||
<br />
|
||||
<br />
|
||||
The augmentation is{" "}
|
||||
{((player.timeWorkedCraftAugmentation / player.timeNeededToCompleteWork) * 100).toFixed(2)}% done being
|
||||
{((player.timeWorkedGraftAugmentation / player.timeNeededToCompleteWork) * 100).toFixed(2)}% done being
|
||||
crafted.
|
||||
<br />
|
||||
If you cancel, your work will <b>not</b> be saved, and the money you spent will <b>not</b> be returned.
|
||||
|
Loading…
Reference in New Issue
Block a user