diff --git a/src/BitNode/BitNode.tsx b/src/BitNode/BitNode.tsx
index 0cf5f392f..1d197899c 100644
--- a/src/BitNode/BitNode.tsx
+++ b/src/BitNode/BitNode.tsx
@@ -583,6 +583,8 @@ export function initBitNodeMultipliers(p: IPlayer): void {
BitNodeMultipliers[mult] = 1;
}
}
+ // Special case.
+ BitNodeMultipliers.StaneksGiftExtraSize = 0;
switch (p.bitNodeN) {
case 1: // Source Genesis (every multiplier is 1)
@@ -860,6 +862,8 @@ export function initBitNodeMultipliers(p: IPlayer): void {
BitNodeMultipliers.BladeburnerRank = 0.1;
BitNodeMultipliers.BladeburnerSkillCost = 5;
BitNodeMultipliers.GangKarmaRequirement = 20;
+ BitNodeMultipliers.StaneksGiftPowerMultiplier = 2;
+ BitNodeMultipliers.StaneksGiftExtraSize = 1;
break;
}
default:
diff --git a/src/BitNode/BitNodeMultipliers.ts b/src/BitNode/BitNodeMultipliers.ts
index ac1a9610e..945fce3d9 100644
--- a/src/BitNode/BitNodeMultipliers.ts
+++ b/src/BitNode/BitNodeMultipliers.ts
@@ -212,6 +212,16 @@ interface IBitNodeMultipliers {
*/
StrengthLevelMultiplier: number;
+ /**
+ * Influences the power of the gift.
+ */
+ StaneksGiftPowerMultiplier: number;
+
+ /**
+ * Influences the size of the gift.
+ */
+ StaneksGiftExtraSize: number;
+
// Index signature
[key: string]: number;
}
@@ -274,4 +284,7 @@ export const BitNodeMultipliers: IBitNodeMultipliers = {
DaedalusAugsRequirement: 1,
GangKarmaRequirement: 1,
+
+ StaneksGiftPowerMultiplier: 1,
+ StaneksGiftExtraSize: 0,
};
diff --git a/src/CotMG/IStaneksGift.ts b/src/CotMG/IStaneksGift.ts
index 7eca8831f..08a9e5249 100644
--- a/src/CotMG/IStaneksGift.ts
+++ b/src/CotMG/IStaneksGift.ts
@@ -3,6 +3,7 @@ import { Fragment } from "./Fragment";
import { IPlayer } from "../PersonObjects/IPlayer";
export interface IStaneksGift {
+ storedCycles: number;
fragments: ActiveFragment[];
width(): number;
height(): number;
@@ -15,4 +16,7 @@ export interface IStaneksGift {
deleteAt(worldX: number, worldY: number): boolean;
clear(): void;
count(fragment: Fragment): number;
+ inBonus(): boolean;
+ prestigeAugmentation(): void;
+ prestigeSourceFile(): void;
}
diff --git a/src/CotMG/StaneksGift.ts b/src/CotMG/StaneksGift.ts
index 7dcc606dc..19267a66d 100644
--- a/src/CotMG/StaneksGift.ts
+++ b/src/CotMG/StaneksGift.ts
@@ -6,16 +6,26 @@ import { IPlayer } from "../PersonObjects/IPlayer";
import { Factions } from "../Faction/Factions";
import { CalculateEffect } from "./formulas/effect";
import { CalculateCharge } from "./formulas/charge";
+import { StaneksGiftEvents } from "./StaneksGiftEvents";
import { Generic_fromJSON, Generic_toJSON, Reviver } from "../utils/JSONReviver";
+import { CONSTANTS } from "../Constants";
+import { StanekConstants } from "./data/Constants";
+import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers";
+import { Player } from "../Player";
export class StaneksGift implements IStaneksGift {
+ storedCycles = 0;
fragments: ActiveFragment[] = [];
+ baseSize(): number {
+ return StanekConstants.BaseSize + BitNodeMultipliers.StaneksGiftExtraSize + Player.sourceFileLvl(13);
+ }
+
width(): number {
- return 7;
+ return Math.floor(this.baseSize() / 2 + 1);
}
height(): number {
- return 6;
+ return Math.floor(this.baseSize() / 2 + 0.6);
}
charge(worldX: number, worldY: number, ram: number): number {
@@ -30,8 +40,16 @@ export class StaneksGift implements IStaneksGift {
return ram;
}
- process(p: IPlayer, numCycles: number): void {
+ inBonus(): boolean {
+ return (this.storedCycles * CONSTANTS._idleSpeed) / 1000 > 1;
+ }
+
+ process(p: IPlayer, numCycles = 1): void {
+ this.storedCycles += numCycles;
+ this.storedCycles -= 5;
+ this.storedCycles = Math.max(0, this.storedCycles);
this.updateMults(p);
+ StaneksGiftEvents.emit();
}
effect(fragment: ActiveFragment): number {
@@ -177,6 +195,14 @@ export class StaneksGift implements IStaneksGift {
}
}
+ prestigeAugmentation(): void {
+ this.clear();
+ }
+
+ prestigeSourceFile(): void {
+ this.clear();
+ }
+
/**
* Serialize Staneks Gift to a JSON save state.
*/
diff --git a/src/CotMG/StaneksGiftEvents.ts b/src/CotMG/StaneksGiftEvents.ts
new file mode 100644
index 000000000..85f66bc29
--- /dev/null
+++ b/src/CotMG/StaneksGiftEvents.ts
@@ -0,0 +1,2 @@
+import { EventEmitter } from "../utils/EventEmitter";
+export const StaneksGiftEvents = new EventEmitter<[]>();
diff --git a/src/CotMG/data/Constants.ts b/src/CotMG/data/Constants.ts
index bc28249e7..2ce02b93e 100644
--- a/src/CotMG/data/Constants.ts
+++ b/src/CotMG/data/Constants.ts
@@ -1,5 +1,7 @@
export const StanekConstants: {
RAMBonus: number;
+ BaseSize: number;
} = {
RAMBonus: 0.1,
+ BaseSize: 12,
};
diff --git a/src/CotMG/ui/StaneksGiftRoot.tsx b/src/CotMG/ui/StaneksGiftRoot.tsx
index c9e211254..c9fed9f29 100644
--- a/src/CotMG/ui/StaneksGiftRoot.tsx
+++ b/src/CotMG/ui/StaneksGiftRoot.tsx
@@ -1,4 +1,7 @@
-import React from "react";
+import React, { useState, useEffect } from "react";
+import { convertTimeMsToTimeElapsedString } from "../../utils/StringHelperFunctions";
+import { CONSTANTS } from "../../Constants";
+import { StaneksGiftEvents } from "../StaneksGiftEvents";
import { Grid } from "./Grid";
import { IStaneksGift } from "../IStaneksGift";
import Typography from "@mui/material/Typography";
@@ -8,6 +11,11 @@ type IProps = {
};
export function StaneksGiftRoot({ staneksGift }: IProps): React.ReactElement {
+ const setRerender = useState(true)[1];
+ function rerender(): void {
+ setRerender((o) => !o);
+ }
+ useEffect(() => StaneksGiftEvents.subscribe(rerender), []);
return (
<>
Stanek's Gift
@@ -17,6 +25,11 @@ export function StaneksGiftRoot({ staneksGift }: IProps): React.ReactElement {
in order to become useful. The other kind of fragment is called booster fragments. They increase the efficiency
of the charged happening on fragments neighboring them (no diagonal)
+ {staneksGift.storedCycles > 5 && (
+
+ Bonus time: {convertTimeMsToTimeElapsedString(CONSTANTS._idleSpeed * staneksGift.storedCycles)}
+
+ )}
>
);
diff --git a/src/DevMenu.tsx b/src/DevMenu.tsx
index 5811a5c73..146ae3985 100644
--- a/src/DevMenu.tsx
+++ b/src/DevMenu.tsx
@@ -2,6 +2,7 @@ import { IPlayer } from "./PersonObjects/IPlayer";
import { Bladeburner } from "./Bladeburner/Bladeburner";
import { IEngine } from "./IEngine";
import { IRouter } from "./ui/Router";
+import { AugmentationNames } from "./Augmentation/data/AugmentationNames";
import React from "react";
@@ -19,6 +20,7 @@ import { Corporation } from "./DevMenu/ui/Corporation";
import { CodingContracts } from "./DevMenu/ui/CodingContracts";
import { StockMarket } from "./DevMenu/ui/StockMarket";
import { Sleeves } from "./DevMenu/ui/Sleeves";
+import { Stanek } from "./DevMenu/ui/Stanek";
import { TimeSkip } from "./DevMenu/ui/TimeSkip";
import Typography from "@mui/material/Typography";
@@ -52,6 +54,7 @@ export function DevMenuRoot(props: IProps): React.ReactElement {
{props.player.hasWseAccount && }
{props.player.sleeves.length > 0 && }
+ {props.player.augmentations.some((aug) => aug.name === AugmentationNames.StaneksGift1) && }
>
diff --git a/src/DevMenu/ui/Stanek.tsx b/src/DevMenu/ui/Stanek.tsx
new file mode 100644
index 000000000..8257f2fa0
--- /dev/null
+++ b/src/DevMenu/ui/Stanek.tsx
@@ -0,0 +1,79 @@
+import React from "react";
+
+import { staneksGift } from "../../CotMG/Helper";
+
+import Accordion from "@mui/material/Accordion";
+import AccordionSummary from "@mui/material/AccordionSummary";
+import AccordionDetails from "@mui/material/AccordionDetails";
+import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
+
+import Typography from "@mui/material/Typography";
+import { Adjuster } from "./Adjuster";
+
+export function Stanek(): React.ReactElement {
+ function addCycles(): void {
+ staneksGift.storedCycles = 1e6;
+ }
+
+ function modCycles(modify: number): (x: number) => void {
+ return function (cycles: number): void {
+ staneksGift.storedCycles += cycles * modify;
+ };
+ }
+
+ function resetCycles(): void {
+ staneksGift.storedCycles = 0;
+ }
+
+ function addCharge(): void {
+ staneksGift.fragments.forEach((f) => (f.charge = 1e21));
+ }
+
+ function modCharge(modify: number): (x: number) => void {
+ return function (cycles: number): void {
+ staneksGift.fragments.forEach((f) => (f.charge += cycles * modify));
+ };
+ }
+
+ function resetCharge(): void {
+ staneksGift.fragments.forEach((f) => (f.charge = 0));
+ }
+
+ return (
+
+ }>
+ Stanek's Gift
+
+
+
+
+
+ |
+
+ |
+
+
+ |
+
+ |
+
+
+
+
+
+ );
+}
diff --git a/src/NetscriptFunctions/Stanek.ts b/src/NetscriptFunctions/Stanek.ts
index 488860e7d..f3816421d 100644
--- a/src/NetscriptFunctions/Stanek.ts
+++ b/src/NetscriptFunctions/Stanek.ts
@@ -29,7 +29,8 @@ export function NetscriptStanek(
//checkStanekAPIAccess("charge");
const fragment = staneksGift.fragmentAt(worldX, worldY);
if (!fragment) throw helper.makeRuntimeErrorMsg("stanek.charge", `No fragment at (${worldX}, ${worldY})`);
- return netscriptDelay(1000, workerScript).then(function () {
+ const time = staneksGift.inBonus() ? 200 : 1000;
+ return netscriptDelay(time, workerScript).then(function () {
if (workerScript.env.stopFlag) {
return Promise.reject(workerScript);
}
diff --git a/src/PersonObjects/IPlayer.ts b/src/PersonObjects/IPlayer.ts
index 30a6f8876..ed7548672 100644
--- a/src/PersonObjects/IPlayer.ts
+++ b/src/PersonObjects/IPlayer.ts
@@ -276,4 +276,5 @@ export interface IPlayer {
setMult(name: string, mult: number): void;
canAccessCotMG(): boolean;
+ sourceFileLvl(n: number): number;
}
diff --git a/src/PersonObjects/Player/PlayerObject.ts b/src/PersonObjects/Player/PlayerObject.ts
index aa367d1d3..622828bfd 100644
--- a/src/PersonObjects/Player/PlayerObject.ts
+++ b/src/PersonObjects/Player/PlayerObject.ts
@@ -282,6 +282,7 @@ export class PlayerObject implements IPlayer {
getMult: (name: string) => number;
setMult: (name: string, mult: number) => void;
canAccessCotMG: () => boolean;
+ sourceFileLvl: (n: number) => number;
constructor() {
//Skills and stats
@@ -575,6 +576,7 @@ export class PlayerObject implements IPlayer {
this.setMult = generalMethods.setMult;
this.canAccessCotMG = generalMethods.canAccessCotMG;
+ this.sourceFileLvl = generalMethods.sourceFileLvl;
}
/**
diff --git a/src/PersonObjects/Player/PlayerObjectGeneralMethods.tsx b/src/PersonObjects/Player/PlayerObjectGeneralMethods.tsx
index 3a41306ad..2bd5c55dd 100644
--- a/src/PersonObjects/Player/PlayerObjectGeneralMethods.tsx
+++ b/src/PersonObjects/Player/PlayerObjectGeneralMethods.tsx
@@ -2627,3 +2627,9 @@ export function setMult(this: IPlayer, name: string, mult: number): void {
export function canAccessCotMG(this: IPlayer): boolean {
return this.bitNodeN === 13 || SourceFileFlags[13] > 0;
}
+
+export function sourceFileLvl(this: IPlayer, n: number): number {
+ const sf = this.sourceFiles.find((sf) => sf.n === n);
+ if (!sf) return 0;
+ return sf.lvl;
+}
diff --git a/src/SourceFile/SourceFiles.tsx b/src/SourceFile/SourceFiles.tsx
index 8d4b87a39..db0980b26 100644
--- a/src/SourceFile/SourceFiles.tsx
+++ b/src/SourceFile/SourceFiles.tsx
@@ -205,6 +205,6 @@ SourceFiles["SourceFile12"] = new SourceFile(
<>This Source-File lets the player start with Neuroflux Governor equal to the level of this Source-File.>,
);
SourceFiles["SourceFile13"] = new SourceFile(
- 12,
+ 13,
<>Each level of this Source-File increases the size of Stanek's Gift.>,
);
diff --git a/src/SourceFile/applySourceFile.ts b/src/SourceFile/applySourceFile.ts
index 9b5e22195..8e6a5672f 100644
--- a/src/SourceFile/applySourceFile.ts
+++ b/src/SourceFile/applySourceFile.ts
@@ -163,7 +163,10 @@ export function applySourceFile(srcFile: PlayerOwnedSourceFile): void {
break;
}
case 12: // The Recursion
- // No effects, grants neuroflux.
+ // Grants neuroflux.
+ break;
+ case 13: // They're Lunatics
+ // Grants more space on Stanek's Gift.
break;
default:
console.error(`Invalid source file number: ${srcFile.n}`);
diff --git a/src/engine.tsx b/src/engine.tsx
index b7ac249c8..c94402ea1 100644
--- a/src/engine.tsx
+++ b/src/engine.tsx
@@ -362,6 +362,8 @@ const Engine: {
Player.bladeburner.storeCycles(numCyclesOffline);
}
+ staneksGift.process(Player, numCyclesOffline);
+
// Sleeves offline progress
for (let i = 0; i < Player.sleeves.length; ++i) {
if (Player.sleeves[i] instanceof Sleeve) {