mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-11-28 10:33:47 +01:00
commit
f359fe661e
@ -6,7 +6,6 @@
|
|||||||
|
|
||||||
.active-scripts-container {
|
.active-scripts-container {
|
||||||
> p {
|
> p {
|
||||||
width: 70%;
|
|
||||||
margin: 6px;
|
margin: 6px;
|
||||||
padding: 4px;
|
padding: 4px;
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
.augmentations-content {
|
.augmentations-content {
|
||||||
> p {
|
> p {
|
||||||
font-size: $defaultFontSize * 0.875;
|
font-size: $defaultFontSize * 0.875;
|
||||||
width: 70%;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,6 @@
|
|||||||
|
|
||||||
.hacknet-general-info {
|
.hacknet-general-info {
|
||||||
margin: 10px;
|
margin: 10px;
|
||||||
width: 70vw;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#hacknet-nodes-container li {
|
#hacknet-nodes-container li {
|
||||||
|
1
src/Augmentation/AugmentationHelpers.d.ts
vendored
1
src/Augmentation/AugmentationHelpers.d.ts
vendored
@ -1 +1,2 @@
|
|||||||
export declare function isRepeatableAug(aug: Augmentation): boolean;
|
export declare function isRepeatableAug(aug: Augmentation): boolean;
|
||||||
|
export declare function installAugmentations(): void;
|
||||||
|
@ -1,16 +1,17 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { hackWorldDaemon } from "../../RedPill";
|
|
||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||||
|
import { IRouter } from "../../ui/Router";
|
||||||
import { removePopup } from "../../ui/React/createPopup";
|
import { removePopup } from "../../ui/React/createPopup";
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
player: IPlayer;
|
player: IPlayer;
|
||||||
|
router: IRouter;
|
||||||
popupId: string;
|
popupId: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function BitFlumePopup(props: IProps): React.ReactElement {
|
export function BitFlumePopup(props: IProps): React.ReactElement {
|
||||||
function flume(): void {
|
function flume(): void {
|
||||||
hackWorldDaemon(props.player.bitNodeN, true, false);
|
props.router.toBitVerse(true, false);
|
||||||
removePopup(props.popupId);
|
removePopup(props.popupId);
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
|
@ -1,18 +1,22 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { SourceFileFlags } from "../../SourceFile/SourceFileFlags";
|
import { SourceFileFlags } from "../../SourceFile/SourceFileFlags";
|
||||||
|
import { IRouter } from "../../ui/Router";
|
||||||
import { BitNodes } from "../BitNode";
|
import { BitNodes } from "../BitNode";
|
||||||
|
import { enterBitNode } from "../../RedPill";
|
||||||
import { PortalPopup } from "./PortalPopup";
|
import { PortalPopup } from "./PortalPopup";
|
||||||
import { createPopup } from "../../ui/React/createPopup";
|
import { createPopup } from "../../ui/React/createPopup";
|
||||||
import { CinematicText } from "../../ui/React/CinematicText";
|
import { CinematicText } from "../../ui/React/CinematicText";
|
||||||
|
import { use } from "../../ui/Context";
|
||||||
|
|
||||||
interface IPortalProps {
|
interface IPortalProps {
|
||||||
n: number;
|
n: number;
|
||||||
level: number;
|
level: number;
|
||||||
destroyedBitNode: number;
|
destroyedBitNode: number;
|
||||||
flume: boolean;
|
flume: boolean;
|
||||||
enter: (flume: boolean, destroyedBitNode: number, newBitNode: number) => void;
|
enter: (router: IRouter, flume: boolean, destroyedBitNode: number, newBitNode: number) => void;
|
||||||
}
|
}
|
||||||
function BitNodePortal(props: IPortalProps): React.ReactElement {
|
function BitNodePortal(props: IPortalProps): React.ReactElement {
|
||||||
|
const router = use.Router();
|
||||||
const bitNode = BitNodes[`BitNode${props.n}`];
|
const bitNode = BitNodes[`BitNode${props.n}`];
|
||||||
if (bitNode == null) {
|
if (bitNode == null) {
|
||||||
return <>O</>;
|
return <>O</>;
|
||||||
@ -32,6 +36,7 @@ function BitNodePortal(props: IPortalProps): React.ReactElement {
|
|||||||
n: props.n,
|
n: props.n,
|
||||||
level: props.level,
|
level: props.level,
|
||||||
enter: props.enter,
|
enter: props.enter,
|
||||||
|
router: router,
|
||||||
destroyedBitNode: props.destroyedBitNode,
|
destroyedBitNode: props.destroyedBitNode,
|
||||||
flume: props.flume,
|
flume: props.flume,
|
||||||
popupId: popupId,
|
popupId: popupId,
|
||||||
@ -57,18 +62,20 @@ function BitNodePortal(props: IPortalProps): React.ReactElement {
|
|||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
flume: boolean;
|
flume: boolean;
|
||||||
destroyedBitNodeNum: number;
|
|
||||||
quick: boolean;
|
quick: boolean;
|
||||||
enter: (flume: boolean, destroyedBitNode: number, newBitNode: number) => void;
|
enter: (router: IRouter, flume: boolean, destroyedBitNode: number, newBitNode: number) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function BitverseRoot(props: IProps): React.ReactElement {
|
export function BitverseRoot(props: IProps): React.ReactElement {
|
||||||
|
const player = use.Player();
|
||||||
|
const enter = enterBitNode;
|
||||||
|
const destroyed = player.bitNodeN;
|
||||||
const [destroySequence, setDestroySequence] = useState(true && !props.quick);
|
const [destroySequence, setDestroySequence] = useState(true && !props.quick);
|
||||||
|
|
||||||
// Update NextSourceFileFlags
|
// Update NextSourceFileFlags
|
||||||
const nextSourceFileFlags = SourceFileFlags.slice();
|
const nextSourceFileFlags = SourceFileFlags.slice();
|
||||||
if (!props.flume) {
|
if (!props.flume) {
|
||||||
if (nextSourceFileFlags[props.destroyedBitNodeNum] < 3) ++nextSourceFileFlags[props.destroyedBitNodeNum];
|
if (nextSourceFileFlags[destroyed] < 3) ++nextSourceFileFlags[destroyed];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (destroySequence) {
|
if (destroySequence) {
|
||||||
@ -84,7 +91,7 @@ export function BitverseRoot(props: IProps): React.ReactElement {
|
|||||||
"0020 7124696B 0000FF69 74652E6F FFFF1111",
|
"0020 7124696B 0000FF69 74652E6F FFFF1111",
|
||||||
"----------------------------------------",
|
"----------------------------------------",
|
||||||
"Failsafe initiated...",
|
"Failsafe initiated...",
|
||||||
`Restarting BitNode-${props.destroyedBitNodeNum}...`,
|
`Restarting BitNode-${destroyed}...`,
|
||||||
"...........",
|
"...........",
|
||||||
"...........",
|
"...........",
|
||||||
"[ERROR] FAILED TO AUTOMATICALLY REBOOT BITNODE",
|
"[ERROR] FAILED TO AUTOMATICALLY REBOOT BITNODE",
|
||||||
@ -96,6 +103,7 @@ export function BitverseRoot(props: IProps): React.ReactElement {
|
|||||||
"..............................................",
|
"..............................................",
|
||||||
]}
|
]}
|
||||||
onDone={() => setDestroySequence(false)}
|
onDone={() => setDestroySequence(false)}
|
||||||
|
auto={true}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -116,16 +124,16 @@ export function BitverseRoot(props: IProps): React.ReactElement {
|
|||||||
<pre> \| O | |_/ |\| \ O \__| \_| | O |/ </pre>
|
<pre> \| O | |_/ |\| \ O \__| \_| | O |/ </pre>
|
||||||
<pre> | | |_/ | | \| / | \_| | | </pre>
|
<pre> | | |_/ | | \| / | \_| | | </pre>
|
||||||
<pre> \| / \| | / / \ |/ </pre>
|
<pre> \| / \| | / / \ |/ </pre>
|
||||||
<pre> | <BitNodePortal n={10} level={nextSourceFileFlags[10]} enter={props.enter} flume={props.flume} destroyedBitNode={props.destroyedBitNodeNum} /> | | / | <BitNodePortal n={11} level={nextSourceFileFlags[11]} enter={props.enter} flume={props.flume} destroyedBitNode={props.destroyedBitNodeNum} /> | </pre>
|
<pre> | <BitNodePortal n={10} level={nextSourceFileFlags[10]} enter={enter} flume={props.flume} destroyedBitNode={destroyed} /> | | / | <BitNodePortal n={11} level={nextSourceFileFlags[11]} enter={enter} flume={props.flume} destroyedBitNode={destroyed} /> | </pre>
|
||||||
<pre> <BitNodePortal n={9} level={nextSourceFileFlags[9]} enter={props.enter} flume={props.flume} destroyedBitNode={props.destroyedBitNodeNum} /> | | | | | | | <BitNodePortal n={12} level={nextSourceFileFlags[12]} enter={props.enter} flume={props.flume} destroyedBitNode={props.destroyedBitNodeNum} /> </pre>
|
<pre> <BitNodePortal n={9} level={nextSourceFileFlags[9]} enter={enter} flume={props.flume} destroyedBitNode={destroyed} /> | | | | | | | <BitNodePortal n={12} level={nextSourceFileFlags[12]} enter={enter} flume={props.flume} destroyedBitNode={destroyed} /> </pre>
|
||||||
<pre> | | | / / \ \ | | | </pre>
|
<pre> | | | / / \ \ | | | </pre>
|
||||||
<pre> \| | / <BitNodePortal n={7} level={nextSourceFileFlags[7]} enter={props.enter} flume={props.flume} destroyedBitNode={props.destroyedBitNodeNum} /> / \ <BitNodePortal n={8} level={nextSourceFileFlags[8]} enter={props.enter} flume={props.flume} destroyedBitNode={props.destroyedBitNodeNum} /> \ | |/ </pre>
|
<pre> \| | / <BitNodePortal n={7} level={nextSourceFileFlags[7]} enter={enter} flume={props.flume} destroyedBitNode={destroyed} /> / \ <BitNodePortal n={8} level={nextSourceFileFlags[8]} enter={enter} flume={props.flume} destroyedBitNode={destroyed} /> \ | |/ </pre>
|
||||||
<pre> \ | / / | | \ \ | / </pre>
|
<pre> \ | / / | | \ \ | / </pre>
|
||||||
<pre> \ \JUMP <BitNodePortal n={5} level={nextSourceFileFlags[5]} enter={props.enter} flume={props.flume} destroyedBitNode={props.destroyedBitNodeNum} />3R | | | | | | R3<BitNodePortal n={6} level={nextSourceFileFlags[6]} enter={props.enter} flume={props.flume} destroyedBitNode={props.destroyedBitNodeNum} /> PMUJ/ / </pre>
|
<pre> \ \JUMP <BitNodePortal n={5} level={nextSourceFileFlags[5]} enter={enter} flume={props.flume} destroyedBitNode={destroyed} />3R | | | | | | R3<BitNodePortal n={6} level={nextSourceFileFlags[6]} enter={enter} flume={props.flume} destroyedBitNode={destroyed} /> PMUJ/ / </pre>
|
||||||
<pre> \|| | | | | | | | | ||/ </pre>
|
<pre> \|| | | | | | | | | ||/ </pre>
|
||||||
<pre> \| \_ | | | | | | _/ |/ </pre>
|
<pre> \| \_ | | | | | | _/ |/ </pre>
|
||||||
<pre> \ \| / \ / \ |/ / </pre>
|
<pre> \ \| / \ / \ |/ / </pre>
|
||||||
<pre> <BitNodePortal n={1} level={nextSourceFileFlags[1]} enter={props.enter} flume={props.flume} destroyedBitNode={props.destroyedBitNodeNum} /> |/ <BitNodePortal n={2} level={nextSourceFileFlags[2]} enter={props.enter} flume={props.flume} destroyedBitNode={props.destroyedBitNodeNum} /> | | <BitNodePortal n={3} level={nextSourceFileFlags[3]} enter={props.enter} flume={props.flume} destroyedBitNode={props.destroyedBitNodeNum} /> \| <BitNodePortal n={4} level={nextSourceFileFlags[4]} enter={props.enter} flume={props.flume} destroyedBitNode={props.destroyedBitNodeNum} /> </pre>
|
<pre> <BitNodePortal n={1} level={nextSourceFileFlags[1]} enter={enter} flume={props.flume} destroyedBitNode={destroyed} /> |/ <BitNodePortal n={2} level={nextSourceFileFlags[2]} enter={enter} flume={props.flume} destroyedBitNode={destroyed} /> | | <BitNodePortal n={3} level={nextSourceFileFlags[3]} enter={enter} flume={props.flume} destroyedBitNode={destroyed} /> \| <BitNodePortal n={4} level={nextSourceFileFlags[4]} enter={enter} flume={props.flume} destroyedBitNode={destroyed} /> </pre>
|
||||||
<pre> | | | | | | | | </pre>
|
<pre> | | | | | | | | </pre>
|
||||||
<pre> \JUMP3R|JUMP|3R| |R3|PMUJ|R3PMUJ/ </pre>
|
<pre> \JUMP3R|JUMP|3R| |R3|PMUJ|R3PMUJ/ </pre>
|
||||||
<br />
|
<br />
|
||||||
|
@ -1,13 +1,15 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
import { BitNodes } from "../BitNode";
|
import { BitNodes } from "../BitNode";
|
||||||
|
import { IRouter } from "../../ui/Router";
|
||||||
import { removePopup } from "../../ui/React/createPopup";
|
import { removePopup } from "../../ui/React/createPopup";
|
||||||
interface IProps {
|
interface IProps {
|
||||||
n: number;
|
n: number;
|
||||||
level: number;
|
level: number;
|
||||||
destroyedBitNode: number;
|
destroyedBitNode: number;
|
||||||
flume: boolean;
|
flume: boolean;
|
||||||
enter: (flume: boolean, destroyedBitNode: number, newBitNode: number) => void;
|
router: IRouter;
|
||||||
|
enter: (router: IRouter, flume: boolean, destroyedBitNode: number, newBitNode: number) => void;
|
||||||
popupId: string;
|
popupId: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,7 +35,7 @@ export function PortalPopup(props: IProps): React.ReactElement {
|
|||||||
<button
|
<button
|
||||||
className="std-button"
|
className="std-button"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
props.enter(props.flume, props.destroyedBitNode, props.n);
|
props.enter(props.router, props.flume, props.destroyedBitNode, props.n);
|
||||||
removePopup(props.popupId);
|
removePopup(props.popupId);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
@ -15,6 +15,7 @@ import { Skill } from "./Skill";
|
|||||||
import { City } from "./City";
|
import { City } from "./City";
|
||||||
import { IAction } from "./IAction";
|
import { IAction } from "./IAction";
|
||||||
import { IPlayer } from "../PersonObjects/IPlayer";
|
import { IPlayer } from "../PersonObjects/IPlayer";
|
||||||
|
import { IRouter } from "../ui/Router";
|
||||||
import { ConsoleHelpText } from "./data/Help";
|
import { ConsoleHelpText } from "./data/Help";
|
||||||
import { exceptionAlert } from "../../utils/helpers/exceptionAlert";
|
import { exceptionAlert } from "../../utils/helpers/exceptionAlert";
|
||||||
import { getRandomInt } from "../../utils/helpers/getRandomInt";
|
import { getRandomInt } from "../../utils/helpers/getRandomInt";
|
||||||
@ -25,7 +26,7 @@ import { addOffset } from "../../utils/helpers/addOffset";
|
|||||||
import { Faction } from "../Faction/Faction";
|
import { Faction } from "../Faction/Faction";
|
||||||
import { Factions, factionExists } from "../Faction/Factions";
|
import { Factions, factionExists } from "../Faction/Factions";
|
||||||
import { calculateHospitalizationCost } from "../Hospital/Hospital";
|
import { calculateHospitalizationCost } from "../Hospital/Hospital";
|
||||||
import { hackWorldDaemon, redPillFlag } from "../RedPill";
|
import { redPillFlag } from "../RedPill";
|
||||||
import { dialogBoxCreate } from "../../utils/DialogBox";
|
import { dialogBoxCreate } from "../../utils/DialogBox";
|
||||||
import { Settings } from "../Settings/Settings";
|
import { Settings } from "../Settings/Settings";
|
||||||
import { Augmentations } from "../Augmentation/Augmentations";
|
import { Augmentations } from "../Augmentation/Augmentations";
|
||||||
@ -1203,7 +1204,7 @@ export class Bladeburner implements IBladeburner {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
completeAction(player: IPlayer): void {
|
completeAction(router: IRouter, player: IPlayer): void {
|
||||||
switch (this.action.type) {
|
switch (this.action.type) {
|
||||||
case ActionTypes["Contract"]:
|
case ActionTypes["Contract"]:
|
||||||
case ActionTypes["Operation"]: {
|
case ActionTypes["Operation"]: {
|
||||||
@ -1338,7 +1339,7 @@ export class Bladeburner implements IBladeburner {
|
|||||||
// Operation Daedalus
|
// Operation Daedalus
|
||||||
if (action.name === "Operation Daedalus") {
|
if (action.name === "Operation Daedalus") {
|
||||||
this.resetAction();
|
this.resetAction();
|
||||||
return hackWorldDaemon(player.bitNodeN);
|
return router.toBitVerse(false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.logging.blackops) {
|
if (this.logging.blackops) {
|
||||||
@ -1540,7 +1541,7 @@ export class Bladeburner implements IBladeburner {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
processAction(player: IPlayer, seconds: number): void {
|
processAction(router: IRouter, player: IPlayer, seconds: number): void {
|
||||||
if (this.action.type === ActionTypes["Idle"]) return;
|
if (this.action.type === ActionTypes["Idle"]) return;
|
||||||
if (this.actionTimeToComplete <= 0) {
|
if (this.actionTimeToComplete <= 0) {
|
||||||
throw new Error(`Invalid actionTimeToComplete value: ${this.actionTimeToComplete}, type; ${this.action.type}`);
|
throw new Error(`Invalid actionTimeToComplete value: ${this.actionTimeToComplete}, type; ${this.action.type}`);
|
||||||
@ -1555,7 +1556,7 @@ export class Bladeburner implements IBladeburner {
|
|||||||
this.actionTimeOverflow = 0;
|
this.actionTimeOverflow = 0;
|
||||||
if (this.actionTimeCurrent >= this.actionTimeToComplete) {
|
if (this.actionTimeCurrent >= this.actionTimeToComplete) {
|
||||||
this.actionTimeOverflow = this.actionTimeCurrent - this.actionTimeToComplete;
|
this.actionTimeOverflow = this.actionTimeCurrent - this.actionTimeToComplete;
|
||||||
return this.completeAction(player);
|
return this.completeAction(router, player);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1888,10 +1889,10 @@ export class Bladeburner implements IBladeburner {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
process(player: IPlayer): void {
|
process(router: IRouter, player: IPlayer): void {
|
||||||
// Edge case condition...if Operation Daedalus is complete trigger the BitNode
|
// Edge case condition...if Operation Daedalus is complete trigger the BitNode
|
||||||
if (redPillFlag === false && this.blackops.hasOwnProperty("Operation Daedalus")) {
|
if (redPillFlag === false && this.blackops.hasOwnProperty("Operation Daedalus")) {
|
||||||
return hackWorldDaemon(player.bitNodeN);
|
return router.toBitVerse(false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the Player starts doing some other actions, set action to idle and alert
|
// If the Player starts doing some other actions, set action to idle and alert
|
||||||
@ -1958,7 +1959,7 @@ export class Bladeburner implements IBladeburner {
|
|||||||
this.randomEventCounter += getRandomInt(240, 600);
|
this.randomEventCounter += getRandomInt(240, 600);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.processAction(player, seconds);
|
this.processAction(router, player, seconds);
|
||||||
|
|
||||||
// Automation
|
// Automation
|
||||||
if (this.automateEnabled) {
|
if (this.automateEnabled) {
|
||||||
|
@ -3,6 +3,7 @@ import { City } from "./City";
|
|||||||
import { Skill } from "./Skill";
|
import { Skill } from "./Skill";
|
||||||
import { IAction } from "./IAction";
|
import { IAction } from "./IAction";
|
||||||
import { IPlayer } from "../PersonObjects/IPlayer";
|
import { IPlayer } from "../PersonObjects/IPlayer";
|
||||||
|
import { IRouter } from "../ui/Router";
|
||||||
import { WorkerScript } from "../Netscript/WorkerScript";
|
import { WorkerScript } from "../Netscript/WorkerScript";
|
||||||
|
|
||||||
export interface IBladeburner {
|
export interface IBladeburner {
|
||||||
@ -103,11 +104,11 @@ export interface IBladeburner {
|
|||||||
completeOperation(success: boolean): void;
|
completeOperation(success: boolean): void;
|
||||||
getActionObject(actionId: IActionIdentifier): IAction | null;
|
getActionObject(actionId: IActionIdentifier): IAction | null;
|
||||||
completeContract(success: boolean): void;
|
completeContract(success: boolean): void;
|
||||||
completeAction(player: IPlayer): void;
|
completeAction(router: IRouter, player: IPlayer): void;
|
||||||
changeRank(player: IPlayer, change: number): void;
|
changeRank(player: IPlayer, change: number): void;
|
||||||
processAction(player: IPlayer, seconds: number): void;
|
processAction(router: IRouter, player: IPlayer, seconds: number): void;
|
||||||
calculateStaminaGainPerSecond(player: IPlayer): number;
|
calculateStaminaGainPerSecond(player: IPlayer): number;
|
||||||
calculateMaxStamina(player: IPlayer): void;
|
calculateMaxStamina(player: IPlayer): void;
|
||||||
create(): void;
|
create(): void;
|
||||||
process(player: IPlayer): void;
|
process(router: IRouter, player: IPlayer): void;
|
||||||
}
|
}
|
||||||
|
42
src/Bladeburner/ui/BladeburnerCinematic.tsx
Normal file
42
src/Bladeburner/ui/BladeburnerCinematic.tsx
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
import React from "react";
|
||||||
|
import { use } from "../../ui/Context";
|
||||||
|
import { CinematicText } from "../../ui/React/CinematicText";
|
||||||
|
import { dialogBoxCreate } from "../../../utils/DialogBox";
|
||||||
|
|
||||||
|
export function BladeburnerCinematic(): React.ReactElement {
|
||||||
|
const router = use.Router();
|
||||||
|
return (
|
||||||
|
<CinematicText
|
||||||
|
lines={[
|
||||||
|
"In the middle of the 21st century, OmniTek Incorporated advanced robot evolution ",
|
||||||
|
"with their Synthoids (synthetic androids), a being virtually identical to a human.",
|
||||||
|
"------",
|
||||||
|
"Their sixth-generation Synthoids, called MK-VI, were stronger, faster, and more ",
|
||||||
|
"intelligent than humans. Many argued that the MK-VI Synthoids were the first ",
|
||||||
|
"example of sentient AI.",
|
||||||
|
"------",
|
||||||
|
"Unfortunately, in 2070 a terrorist group called Ascendis Totalis hacked into OmniTek and ",
|
||||||
|
"uploaded a rogue AI into their Synthoid manufacturing facilities.",
|
||||||
|
"------",
|
||||||
|
"The MK-VI Synthoids infected by the rogue AI turned hostile toward humanity, initiating ",
|
||||||
|
"the deadliest conflict in human history. This dark chapter is now known as the Synthoid Uprising.",
|
||||||
|
"------",
|
||||||
|
"In the aftermath of the Uprising, further manufacturing of Synthoids with advanced AI ",
|
||||||
|
"was banned. MK-VI Synthoids that did not have the rogue Ascendis Totalis AI were ",
|
||||||
|
"allowed to continue their existence.",
|
||||||
|
"------",
|
||||||
|
"The intelligence community believes that not all of the rogue MK-VI Synthoids from the Uprising were ",
|
||||||
|
"found and destroyed, and that many of them are blending in as normal humans in society today. ",
|
||||||
|
"As a result, many nations have created Bladeburner divisions, special units that are tasked with ",
|
||||||
|
"investigating and dealing with Synthoid threats.",
|
||||||
|
]}
|
||||||
|
onDone={() => {
|
||||||
|
router.toTerminal();
|
||||||
|
dialogBoxCreate(
|
||||||
|
"Visit the National Security Agency (NSA) to apply for their Bladeburner " +
|
||||||
|
"division! You will need 100 of each combat stat before doing this.",
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
@ -3,17 +3,16 @@ import { Stats } from "./Stats";
|
|||||||
import { Console } from "./Console";
|
import { Console } from "./Console";
|
||||||
import { AllPages } from "./AllPages";
|
import { AllPages } from "./AllPages";
|
||||||
|
|
||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
import { use } from "../../ui/Context";
|
||||||
import { IEngine } from "../../IEngine";
|
|
||||||
import { IBladeburner } from "../IBladeburner";
|
import { IBladeburner } from "../IBladeburner";
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
bladeburner: IBladeburner;
|
bladeburner: IBladeburner;
|
||||||
engine: IEngine;
|
|
||||||
player: IPlayer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function Root(props: IProps): React.ReactElement {
|
export function BladeburnerRoot(props: IProps): React.ReactElement {
|
||||||
|
const player = use.Player();
|
||||||
|
const router = use.Router();
|
||||||
return (
|
return (
|
||||||
<div className="bladeburner-container">
|
<div className="bladeburner-container">
|
||||||
<div style={{ height: "60%", display: "block", position: "relative" }}>
|
<div style={{ height: "60%", display: "block", position: "relative" }}>
|
||||||
@ -25,9 +24,9 @@ export function Root(props: IProps): React.ReactElement {
|
|||||||
border: "1px solid white",
|
border: "1px solid white",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Stats bladeburner={props.bladeburner} player={props.player} engine={props.engine} />
|
<Stats bladeburner={props.bladeburner} player={player} router={router} />
|
||||||
</div>
|
</div>
|
||||||
<Console bladeburner={props.bladeburner} player={props.player} />
|
<Console bladeburner={props.bladeburner} player={player} />
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
@ -39,7 +38,7 @@ export function Root(props: IProps): React.ReactElement {
|
|||||||
position: "relative",
|
position: "relative",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<AllPages bladeburner={props.bladeburner} player={props.player} />
|
<AllPages bladeburner={props.bladeburner} player={player} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
@ -2,21 +2,21 @@ import React, { useState, useEffect } from "react";
|
|||||||
import { formatNumber, convertTimeMsToTimeElapsedString } from "../../../utils/StringHelperFunctions";
|
import { formatNumber, convertTimeMsToTimeElapsedString } from "../../../utils/StringHelperFunctions";
|
||||||
import { BladeburnerConstants } from "../data/Constants";
|
import { BladeburnerConstants } from "../data/Constants";
|
||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||||
import { IEngine } from "../../IEngine";
|
|
||||||
import { Money } from "../../ui/React/Money";
|
import { Money } from "../../ui/React/Money";
|
||||||
import { StatsTable } from "../../ui/React/StatsTable";
|
import { StatsTable } from "../../ui/React/StatsTable";
|
||||||
import { numeralWrapper } from "../../ui/numeralFormat";
|
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||||
import { dialogBoxCreate } from "../../../utils/DialogBox";
|
import { dialogBoxCreate } from "../../../utils/DialogBox";
|
||||||
import { createPopup } from "../../ui/React/createPopup";
|
import { createPopup } from "../../ui/React/createPopup";
|
||||||
import { Factions } from "../../Faction/Factions";
|
import { Factions } from "../../Faction/Factions";
|
||||||
import { joinFaction, displayFactionContent } from "../../Faction/FactionHelpers";
|
import { IRouter } from "../../ui/Router";
|
||||||
|
import { joinFaction } from "../../Faction/FactionHelpers";
|
||||||
import { IBladeburner } from "../IBladeburner";
|
import { IBladeburner } from "../IBladeburner";
|
||||||
|
|
||||||
import { TravelPopup } from "./TravelPopup";
|
import { TravelPopup } from "./TravelPopup";
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
bladeburner: IBladeburner;
|
bladeburner: IBladeburner;
|
||||||
engine: IEngine;
|
router: IRouter;
|
||||||
player: IPlayer;
|
player: IPlayer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,8 +72,7 @@ export function Stats(props: IProps): React.ReactElement {
|
|||||||
function openFaction(): void {
|
function openFaction(): void {
|
||||||
const faction = Factions["Bladeburners"];
|
const faction = Factions["Bladeburners"];
|
||||||
if (faction.isMember) {
|
if (faction.isMember) {
|
||||||
props.engine.loadFactionContent();
|
props.router.toFaction(faction);
|
||||||
displayFactionContent("Bladeburners");
|
|
||||||
} else {
|
} else {
|
||||||
if (props.bladeburner.rank >= BladeburnerConstants.RankNeededForFaction) {
|
if (props.bladeburner.rank >= BladeburnerConstants.RankNeededForFaction) {
|
||||||
joinFaction(faction);
|
joinFaction(faction);
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { IPlayer } from "./PersonObjects/IPlayer";
|
import { IPlayer } from "./PersonObjects/IPlayer";
|
||||||
import { Bladeburner } from "./Bladeburner/Bladeburner";
|
import { Bladeburner } from "./Bladeburner/Bladeburner";
|
||||||
import { IEngine } from "./IEngine";
|
import { IEngine } from "./IEngine";
|
||||||
|
import { IRouter } from "./ui/Router";
|
||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { TTheme as Theme } from "./ui/React/Theme";
|
import { TTheme as Theme } from "./ui/React/Theme";
|
||||||
@ -24,6 +25,7 @@ import { TimeSkip } from "./DevMenu/ui/TimeSkip";
|
|||||||
interface IProps {
|
interface IProps {
|
||||||
player: IPlayer;
|
player: IPlayer;
|
||||||
engine: IEngine;
|
engine: IEngine;
|
||||||
|
router: IRouter;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function DevMenuRoot(props: IProps): React.ReactElement {
|
export function DevMenuRoot(props: IProps): React.ReactElement {
|
||||||
@ -31,7 +33,7 @@ export function DevMenuRoot(props: IProps): React.ReactElement {
|
|||||||
<Theme>
|
<Theme>
|
||||||
<>
|
<>
|
||||||
<h1>Development Menu - Only meant to be used for testing/debugging</h1>
|
<h1>Development Menu - Only meant to be used for testing/debugging</h1>
|
||||||
<General player={props.player} />
|
<General player={props.player} router={props.router} />
|
||||||
<Stats player={props.player} />
|
<Stats player={props.player} />
|
||||||
<Factions player={props.player} />
|
<Factions player={props.player} />
|
||||||
<Augmentations player={props.player} />
|
<Augmentations player={props.player} />
|
||||||
|
@ -8,10 +8,11 @@ import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
|
|||||||
import Button from "@mui/material/Button";
|
import Button from "@mui/material/Button";
|
||||||
import { Money } from "../../ui/React/Money";
|
import { Money } from "../../ui/React/Money";
|
||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||||
import { hackWorldDaemon } from "../../RedPill";
|
import { IRouter } from "../../ui/Router";
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
player: IPlayer;
|
player: IPlayer;
|
||||||
|
router: IRouter;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function General(props: IProps): React.ReactElement {
|
export function General(props: IProps): React.ReactElement {
|
||||||
@ -26,19 +27,19 @@ export function General(props: IProps): React.ReactElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function quickB1tFlum3(): void {
|
function quickB1tFlum3(): void {
|
||||||
hackWorldDaemon(props.player.bitNodeN, true, true);
|
props.router.toBitVerse(true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
function b1tflum3(): void {
|
function b1tflum3(): void {
|
||||||
hackWorldDaemon(props.player.bitNodeN, true);
|
props.router.toBitVerse(true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
function quickHackW0r1dD43m0n(): void {
|
function quickHackW0r1dD43m0n(): void {
|
||||||
hackWorldDaemon(props.player.bitNodeN, false, true);
|
props.router.toBitVerse(false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
function hackW0r1dD43m0n(): void {
|
function hackW0r1dD43m0n(): void {
|
||||||
hackWorldDaemon(props.player.bitNodeN);
|
props.router.toBitVerse(false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -30,7 +30,7 @@ export function TimeSkip(props: IProps): React.ReactElement {
|
|||||||
return (
|
return (
|
||||||
<Accordion>
|
<Accordion>
|
||||||
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
|
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
|
||||||
<h2>Sleeves</h2>
|
<h2>Time skip</h2>
|
||||||
</AccordionSummary>
|
</AccordionSummary>
|
||||||
<AccordionDetails>
|
<AccordionDetails>
|
||||||
<Button onClick={timeskip(60 * 1000)}>1 minute</Button>
|
<Button onClick={timeskip(60 * 1000)}>1 minute</Button>
|
||||||
|
2
src/Faction/FactionHelpers.d.ts
vendored
2
src/Faction/FactionHelpers.d.ts
vendored
@ -4,5 +4,5 @@ import { Faction } from "../Faction/Faction";
|
|||||||
export declare function getNextNeurofluxLevel(): number;
|
export declare function getNextNeurofluxLevel(): number;
|
||||||
export declare function hasAugmentationPrereqs(aug: Augmentation): boolean;
|
export declare function hasAugmentationPrereqs(aug: Augmentation): boolean;
|
||||||
export declare function purchaseAugmentation(aug: Augmentation, fac: Faction, sing?: boolean): void;
|
export declare function purchaseAugmentation(aug: Augmentation, fac: Faction, sing?: boolean): void;
|
||||||
export declare function displayFactionContent(factionName: string, initiallyOnAugmentationsPage: boolean = false);
|
|
||||||
export declare function joinFaction(faction: Faction): void;
|
export declare function joinFaction(faction: Faction): void;
|
||||||
|
export declare function startHackingMission(faction: Faction): void;
|
||||||
|
@ -1,14 +1,9 @@
|
|||||||
import React from "react";
|
|
||||||
import ReactDOM from "react-dom";
|
|
||||||
|
|
||||||
import { FactionRoot } from "./ui/Root";
|
|
||||||
|
|
||||||
import { Augmentations } from "../Augmentation/Augmentations";
|
import { Augmentations } from "../Augmentation/Augmentations";
|
||||||
import { PlayerOwnedAugmentation } from "../Augmentation/PlayerOwnedAugmentation";
|
import { PlayerOwnedAugmentation } from "../Augmentation/PlayerOwnedAugmentation";
|
||||||
import { AugmentationNames } from "../Augmentation/data/AugmentationNames";
|
import { AugmentationNames } from "../Augmentation/data/AugmentationNames";
|
||||||
import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers";
|
import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers";
|
||||||
import { CONSTANTS } from "../Constants";
|
import { CONSTANTS } from "../Constants";
|
||||||
import { Engine } from "../engine";
|
|
||||||
import { Faction } from "./Faction";
|
import { Faction } from "./Faction";
|
||||||
import { Factions } from "./Factions";
|
import { Factions } from "./Factions";
|
||||||
import { HackingMission, setInMission } from "../Missions";
|
import { HackingMission, setInMission } from "../Missions";
|
||||||
@ -65,29 +60,6 @@ export function startHackingMission(faction) {
|
|||||||
mission.init();
|
mission.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
//Displays the HTML content for a specific faction
|
|
||||||
export function displayFactionContent(factionName, initiallyOnAugmentationsPage = false) {
|
|
||||||
const faction = Factions[factionName];
|
|
||||||
if (faction == null) {
|
|
||||||
throw new Error(`Invalid factionName passed into displayFactionContent(): ${factionName}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!faction.isMember) {
|
|
||||||
throw new Error(`Not a member of this faction. Cannot display faction information`);
|
|
||||||
}
|
|
||||||
|
|
||||||
ReactDOM.render(
|
|
||||||
<FactionRoot
|
|
||||||
engine={Engine}
|
|
||||||
initiallyOnAugmentationsPage={initiallyOnAugmentationsPage}
|
|
||||||
faction={faction}
|
|
||||||
p={Player}
|
|
||||||
startHackingMissionFn={startHackingMission}
|
|
||||||
/>,
|
|
||||||
Engine.Display.content,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Returns a boolean indicating whether the player has the prerequisites for the
|
//Returns a boolean indicating whether the player has the prerequisites for the
|
||||||
//specified Augmentation
|
//specified Augmentation
|
||||||
export function hasAugmentationPrereqs(aug) {
|
export function hasAugmentationPrereqs(aug) {
|
||||||
@ -187,9 +159,6 @@ export function purchaseAugmentation(aug, fac, sing = false) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Force a rerender of the Augmentations page
|
|
||||||
displayFactionContent(fac.name, true);
|
|
||||||
} else {
|
} else {
|
||||||
dialogBoxCreate(
|
dialogBoxCreate(
|
||||||
"Hmm, something went wrong when trying to purchase an Augmentation. " +
|
"Hmm, something went wrong when trying to purchase an Augmentation. " +
|
||||||
|
@ -1,52 +1,37 @@
|
|||||||
/**
|
/**
|
||||||
* Root React Component for displaying a faction's "Purchase Augmentations" page
|
* Root React Component for displaying a faction's "Purchase Augmentations" page
|
||||||
*/
|
*/
|
||||||
import * as React from "react";
|
import React, { useState } from "react";
|
||||||
|
|
||||||
import { PurchaseableAugmentation } from "./PurchaseableAugmentation";
|
import { PurchaseableAugmentation } from "./PurchaseableAugmentation";
|
||||||
|
|
||||||
import { Augmentations } from "../../Augmentation/Augmentations";
|
import { Augmentations } from "../../Augmentation/Augmentations";
|
||||||
import { AugmentationNames } from "../../Augmentation/data/AugmentationNames";
|
import { AugmentationNames } from "../../Augmentation/data/AugmentationNames";
|
||||||
import { Faction } from "../../Faction/Faction";
|
import { Faction } from "../../Faction/Faction";
|
||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
|
||||||
import { PurchaseAugmentationsOrderSetting } from "../../Settings/SettingEnums";
|
import { PurchaseAugmentationsOrderSetting } from "../../Settings/SettingEnums";
|
||||||
import { Settings } from "../../Settings/Settings";
|
import { Settings } from "../../Settings/Settings";
|
||||||
|
|
||||||
import { StdButton } from "../../ui/React/StdButton";
|
import { StdButton } from "../../ui/React/StdButton";
|
||||||
|
import { use } from "../../ui/Context";
|
||||||
|
|
||||||
type IProps = {
|
type IProps = {
|
||||||
faction: Faction;
|
faction: Faction;
|
||||||
p: IPlayer;
|
|
||||||
routeToMainPage: () => void;
|
routeToMainPage: () => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
type IState = {
|
export function AugmentationsPage(props: IProps): React.ReactElement {
|
||||||
rerenderFlag: boolean;
|
const player = use.Player();
|
||||||
sortOrder: PurchaseAugmentationsOrderSetting;
|
|
||||||
};
|
|
||||||
|
|
||||||
const infoStyleMarkup = {
|
|
||||||
width: "70%",
|
|
||||||
};
|
|
||||||
|
|
||||||
export class AugmentationsPage extends React.Component<IProps, IState> {
|
|
||||||
// Flag for whether the player has a gang with this faction
|
// Flag for whether the player has a gang with this faction
|
||||||
isPlayersGang: boolean;
|
const isPlayersGang = player.inGang() && player.getGangName() === props.faction.name;
|
||||||
constructor(props: IProps) {
|
|
||||||
super(props);
|
|
||||||
|
|
||||||
this.isPlayersGang = props.p.inGang() && props.p.getGangName() === props.faction.name;
|
const setRerender = useState(false)[1];
|
||||||
|
|
||||||
this.state = {
|
function rerender(): void {
|
||||||
rerenderFlag: false,
|
setRerender((old) => !old);
|
||||||
sortOrder: PurchaseAugmentationsOrderSetting.Default,
|
|
||||||
};
|
|
||||||
|
|
||||||
this.rerender = this.rerender.bind(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getAugs(): string[] {
|
function getAugs(): string[] {
|
||||||
if (this.isPlayersGang) {
|
if (isPlayersGang) {
|
||||||
const augs: string[] = [];
|
const augs: string[] = [];
|
||||||
for (const augName in Augmentations) {
|
for (const augName in Augmentations) {
|
||||||
const aug = Augmentations[augName];
|
const aug = Augmentations[augName];
|
||||||
@ -57,25 +42,25 @@ export class AugmentationsPage extends React.Component<IProps, IState> {
|
|||||||
|
|
||||||
return augs;
|
return augs;
|
||||||
} else {
|
} else {
|
||||||
return this.props.faction.augmentations.slice();
|
return props.faction.augmentations.slice();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getAugsSorted(): string[] {
|
function getAugsSorted(): string[] {
|
||||||
switch (Settings.PurchaseAugmentationsOrder) {
|
switch (Settings.PurchaseAugmentationsOrder) {
|
||||||
case PurchaseAugmentationsOrderSetting.Cost: {
|
case PurchaseAugmentationsOrderSetting.Cost: {
|
||||||
return this.getAugsSortedByCost();
|
return getAugsSortedByCost();
|
||||||
}
|
}
|
||||||
case PurchaseAugmentationsOrderSetting.Reputation: {
|
case PurchaseAugmentationsOrderSetting.Reputation: {
|
||||||
return this.getAugsSortedByReputation();
|
return getAugsSortedByReputation();
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return this.getAugsSortedByDefault();
|
return getAugsSortedByDefault();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getAugsSortedByCost(): string[] {
|
function getAugsSortedByCost(): string[] {
|
||||||
const augs = this.getAugs();
|
const augs = getAugs();
|
||||||
augs.sort((augName1, augName2) => {
|
augs.sort((augName1, augName2) => {
|
||||||
const aug1 = Augmentations[augName1],
|
const aug1 = Augmentations[augName1],
|
||||||
aug2 = Augmentations[augName2];
|
aug2 = Augmentations[augName2];
|
||||||
@ -89,8 +74,8 @@ export class AugmentationsPage extends React.Component<IProps, IState> {
|
|||||||
return augs;
|
return augs;
|
||||||
}
|
}
|
||||||
|
|
||||||
getAugsSortedByReputation(): string[] {
|
function getAugsSortedByReputation(): string[] {
|
||||||
const augs = this.getAugs();
|
const augs = getAugs();
|
||||||
augs.sort((augName1, augName2) => {
|
augs.sort((augName1, augName2) => {
|
||||||
const aug1 = Augmentations[augName1],
|
const aug1 = Augmentations[augName1],
|
||||||
aug2 = Augmentations[augName2];
|
aug2 = Augmentations[augName2];
|
||||||
@ -103,88 +88,70 @@ export class AugmentationsPage extends React.Component<IProps, IState> {
|
|||||||
return augs;
|
return augs;
|
||||||
}
|
}
|
||||||
|
|
||||||
getAugsSortedByDefault(): string[] {
|
function getAugsSortedByDefault(): string[] {
|
||||||
return this.getAugs();
|
return getAugs();
|
||||||
}
|
}
|
||||||
|
|
||||||
switchSortOrder(newOrder: PurchaseAugmentationsOrderSetting): void {
|
function switchSortOrder(newOrder: PurchaseAugmentationsOrderSetting): void {
|
||||||
Settings.PurchaseAugmentationsOrder = newOrder;
|
Settings.PurchaseAugmentationsOrder = newOrder;
|
||||||
this.rerender();
|
rerender();
|
||||||
}
|
}
|
||||||
|
|
||||||
rerender(): void {
|
const augs = getAugsSorted();
|
||||||
this.setState((prevState) => {
|
const purchasable = augs.filter(
|
||||||
return {
|
(aug: string) =>
|
||||||
rerenderFlag: !prevState.rerenderFlag,
|
aug === AugmentationNames.NeuroFluxGovernor ||
|
||||||
};
|
(!player.augmentations.some((a) => a.name === aug) && !player.queuedAugmentations.some((a) => a.name === aug)),
|
||||||
});
|
);
|
||||||
}
|
|
||||||
|
|
||||||
render(): React.ReactNode {
|
const purchaseableAugmentation = (aug: string): React.ReactNode => {
|
||||||
const augs = this.getAugsSorted();
|
return <PurchaseableAugmentation augName={aug} faction={props.faction} key={aug} p={player} rerender={rerender} />;
|
||||||
const purchasable = augs.filter(
|
};
|
||||||
(aug: string) => aug === AugmentationNames.NeuroFluxGovernor ||
|
|
||||||
(!this.props.p.augmentations.some((a) => a.name === aug) &&
|
|
||||||
!this.props.p.queuedAugmentations.some((a) => a.name === aug)),
|
|
||||||
);
|
|
||||||
|
|
||||||
const purchaseableAugmentation = (aug: string): React.ReactNode => {
|
const augListElems = purchasable.map((aug) => purchaseableAugmentation(aug));
|
||||||
return (
|
|
||||||
<PurchaseableAugmentation
|
|
||||||
augName={aug}
|
|
||||||
faction={this.props.faction}
|
|
||||||
key={aug}
|
|
||||||
p={this.props.p}
|
|
||||||
rerender={this.rerender}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const augListElems = purchasable.map((aug) => purchaseableAugmentation(aug));
|
let ownedElem = <></>;
|
||||||
|
const owned = augs.filter((aug: string) => !purchasable.includes(aug));
|
||||||
let ownedElem = <></>;
|
if (owned.length !== 0) {
|
||||||
const owned = augs.filter((aug: string) => !purchasable.includes(aug));
|
ownedElem = (
|
||||||
if (owned.length !== 0) {
|
<>
|
||||||
ownedElem = (
|
|
||||||
<>
|
|
||||||
<br />
|
|
||||||
<h2>Purchased Augmentations</h2>
|
|
||||||
<p style={infoStyleMarkup}>This factions also offers these augmentations but you already own them.</p>
|
|
||||||
{owned.map((aug) => purchaseableAugmentation(aug))}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<StdButton onClick={this.props.routeToMainPage} text={"Back"} />
|
|
||||||
<h1>Faction Augmentations</h1>
|
|
||||||
<p style={infoStyleMarkup}>
|
|
||||||
These are all of the Augmentations that are available to purchase from {this.props.faction.name}.
|
|
||||||
Augmentations are powerful upgrades that will enhance your abilities.
|
|
||||||
</p>
|
|
||||||
<StdButton onClick={() => this.switchSortOrder(PurchaseAugmentationsOrderSetting.Cost)} text={"Sort by Cost"} />
|
|
||||||
<StdButton
|
|
||||||
onClick={() => this.switchSortOrder(PurchaseAugmentationsOrderSetting.Reputation)}
|
|
||||||
text={"Sort by Reputation"}
|
|
||||||
/>
|
|
||||||
<StdButton
|
|
||||||
onClick={() => this.switchSortOrder(PurchaseAugmentationsOrderSetting.Default)}
|
|
||||||
text={"Sort by Default Order"}
|
|
||||||
/>
|
|
||||||
<br />
|
<br />
|
||||||
{augListElems}
|
<h2>Purchased Augmentations</h2>
|
||||||
{ownedElem}
|
<p>This factions also offers these augmentations but you already own them.</p>
|
||||||
<br />
|
{owned.map((aug) => purchaseableAugmentation(aug))}
|
||||||
<br />
|
</>
|
||||||
<br />
|
|
||||||
<br />
|
|
||||||
<br />
|
|
||||||
<br />
|
|
||||||
<br />
|
|
||||||
<br />
|
|
||||||
<br />
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<StdButton onClick={props.routeToMainPage} text={"Back"} />
|
||||||
|
<h1>Faction Augmentations</h1>
|
||||||
|
<p>
|
||||||
|
These are all of the Augmentations that are available to purchase from {props.faction.name}. Augmentations are
|
||||||
|
powerful upgrades that will enhance your abilities.
|
||||||
|
</p>
|
||||||
|
<StdButton onClick={() => switchSortOrder(PurchaseAugmentationsOrderSetting.Cost)} text={"Sort by Cost"} />
|
||||||
|
<StdButton
|
||||||
|
onClick={() => switchSortOrder(PurchaseAugmentationsOrderSetting.Reputation)}
|
||||||
|
text={"Sort by Reputation"}
|
||||||
|
/>
|
||||||
|
<StdButton
|
||||||
|
onClick={() => switchSortOrder(PurchaseAugmentationsOrderSetting.Default)}
|
||||||
|
text={"Sort by Default Order"}
|
||||||
|
/>
|
||||||
|
<br />
|
||||||
|
{augListElems}
|
||||||
|
{ownedElem}
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,58 +1,66 @@
|
|||||||
/**
|
/**
|
||||||
* React Component for the popup used to create a new gang.
|
* React Component for the popup used to create a new gang.
|
||||||
*/
|
*/
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { removePopup } from "../../ui/React/createPopup";
|
import { removePopup } from "../../ui/React/createPopup";
|
||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
import { StdButton } from "../../ui/React/StdButton";
|
||||||
import { StdButton } from "../../ui/React/StdButton";
|
import { use } from "../../ui/Context";
|
||||||
import { IEngine } from "../../IEngine";
|
|
||||||
|
|
||||||
interface ICreateGangPopupProps {
|
interface ICreateGangPopupProps {
|
||||||
popupId: string;
|
popupId: string;
|
||||||
facName: string;
|
facName: string;
|
||||||
p: IPlayer;
|
}
|
||||||
engine: IEngine;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function CreateGangPopup(props: ICreateGangPopupProps): React.ReactElement {
|
export function CreateGangPopup(props: ICreateGangPopupProps): React.ReactElement {
|
||||||
|
const player = use.Player();
|
||||||
const combatGangText = "This is a COMBAT gang. Members in this gang will have different tasks than HACKING gangs. " +
|
const router = use.Router();
|
||||||
|
const combatGangText =
|
||||||
|
"This is a COMBAT gang. Members in this gang will have different tasks than HACKING gangs. " +
|
||||||
"Compared to hacking gangs, progression with combat gangs can be more difficult as territory management " +
|
"Compared to hacking gangs, progression with combat gangs can be more difficult as territory management " +
|
||||||
"is more important. However, well-managed combat gangs can progress faster than hacking ones.";
|
"is more important. However, well-managed combat gangs can progress faster than hacking ones.";
|
||||||
|
|
||||||
const hackingGangText = "This is a HACKING gang. Members in this gang will have different tasks than COMBAT gangs. " +
|
const hackingGangText =
|
||||||
|
"This is a HACKING gang. Members in this gang will have different tasks than COMBAT gangs. " +
|
||||||
"Compared to combat gangs, progression with hacking gangs is more straightforward as territory warfare " +
|
"Compared to combat gangs, progression with hacking gangs is more straightforward as territory warfare " +
|
||||||
"is not as important.";
|
"is not as important.";
|
||||||
|
|
||||||
function isHacking(): boolean {
|
function isHacking(): boolean {
|
||||||
return ["NiteSec", "The Black Hand"].includes(props.facName);
|
return ["NiteSec", "The Black Hand"].includes(props.facName);
|
||||||
}
|
}
|
||||||
|
|
||||||
function createGang(): void {
|
function createGang(): void {
|
||||||
props.p.startGang(props.facName, isHacking());
|
player.startGang(props.facName, isHacking());
|
||||||
removePopup(props.popupId);
|
removePopup(props.popupId);
|
||||||
props.engine.loadGangContent();
|
router.toGang();
|
||||||
}
|
}
|
||||||
|
|
||||||
function onKeyUp(event: React.KeyboardEvent): void {
|
function onKeyUp(event: React.KeyboardEvent): void {
|
||||||
if (event.keyCode === 13) createGang();
|
if (event.keyCode === 13) createGang();
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
Would you like to create a new Gang with {props.facName}?
|
Would you like to create a new Gang with {props.facName}?
|
||||||
<br/>
|
<br />
|
||||||
<br/>
|
<br />
|
||||||
Note that this will prevent you from creating a Gang with any other Faction until this BitNode is destroyed. It also resets your reputation with this faction.
|
Note that this will prevent you from creating a Gang with any other Faction until this BitNode is destroyed. It
|
||||||
<br/>
|
also resets your reputation with this faction.
|
||||||
<br/>
|
<br />
|
||||||
{ (isHacking()) ? hackingGangText : combatGangText }
|
<br />
|
||||||
<br/>
|
{isHacking() ? hackingGangText : combatGangText}
|
||||||
<br/>
|
<br />
|
||||||
Other than hacking vs combat, there are NO differences between the Factions you can create a Gang with, and each of these Factions have all Augmentations available.
|
<br />
|
||||||
<div className="popup-box-input-div" >
|
Other than hacking vs combat, there are NO differences between the Factions you can create a Gang with, and each
|
||||||
<StdButton onClick={createGang} onKeyUp={onKeyUp} text="Create Gang" style={{float: "right"}} autoFocus={true}/>
|
of these Factions have all Augmentations available.
|
||||||
</div>
|
<div className="popup-box-input-div">
|
||||||
</>
|
<StdButton
|
||||||
);
|
onClick={createGang}
|
||||||
}
|
onKeyUp={onKeyUp}
|
||||||
|
text="Create Gang"
|
||||||
|
style={{ float: "right" }}
|
||||||
|
autoFocus={true}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* This is the component for displaying a single faction's UI, not the list of all
|
* This is the component for displaying a single faction's UI, not the list of all
|
||||||
* accessible factions
|
* accessible factions
|
||||||
*/
|
*/
|
||||||
import * as React from "react";
|
import React, { useState } from "react";
|
||||||
|
|
||||||
import { AugmentationsPage } from "./AugmentationsPage";
|
import { AugmentationsPage } from "./AugmentationsPage";
|
||||||
import { DonateOption } from "./DonateOption";
|
import { DonateOption } from "./DonateOption";
|
||||||
@ -11,30 +11,21 @@ import { Info } from "./Info";
|
|||||||
import { Option } from "./Option";
|
import { Option } from "./Option";
|
||||||
|
|
||||||
import { CONSTANTS } from "../../Constants";
|
import { CONSTANTS } from "../../Constants";
|
||||||
import { IEngine } from "../../IEngine";
|
|
||||||
|
|
||||||
import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers";
|
import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers";
|
||||||
import { Faction } from "../../Faction/Faction";
|
import { Faction } from "../../Faction/Faction";
|
||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
|
||||||
import { createSleevePurchasesFromCovenantPopup } from "../../PersonObjects/Sleeve/SleeveCovenantPurchases";
|
import { createSleevePurchasesFromCovenantPopup } from "../../PersonObjects/Sleeve/SleeveCovenantPurchases";
|
||||||
import { SourceFileFlags } from "../../SourceFile/SourceFileFlags";
|
import { SourceFileFlags } from "../../SourceFile/SourceFileFlags";
|
||||||
|
|
||||||
import { createPopup } from "../../ui/React/createPopup";
|
import { createPopup } from "../../ui/React/createPopup";
|
||||||
|
import { use } from "../../ui/Context";
|
||||||
import { CreateGangPopup } from "./CreateGangPopup";
|
import { CreateGangPopup } from "./CreateGangPopup";
|
||||||
|
|
||||||
type IProps = {
|
type IProps = {
|
||||||
engine: IEngine;
|
faction: Faction | null;
|
||||||
initiallyOnAugmentationsPage?: boolean;
|
|
||||||
faction: Faction;
|
|
||||||
p: IPlayer;
|
|
||||||
startHackingMissionFn: (faction: Faction) => void;
|
startHackingMissionFn: (faction: Faction) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
type IState = {
|
|
||||||
rerenderFlag: boolean;
|
|
||||||
purchasingAugs: boolean;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Info text for all options on the UI
|
// Info text for all options on the UI
|
||||||
const gangInfo = "Create and manage a gang for this Faction. Gangs will earn you money and " + "faction reputation";
|
const gangInfo = "Create and manage a gang for this Faction. Gangs will earn you money and " + "faction reputation";
|
||||||
const hackingMissionInfo =
|
const hackingMissionInfo =
|
||||||
@ -72,89 +63,68 @@ const GangNames = [
|
|||||||
"The Black Hand",
|
"The Black Hand",
|
||||||
];
|
];
|
||||||
|
|
||||||
export class FactionRoot extends React.Component<IProps, IState> {
|
export function FactionRoot(props: IProps): React.ReactElement {
|
||||||
constructor(props: IProps) {
|
const faction = props.faction;
|
||||||
super(props);
|
if (faction === null) throw new Error("Trying to render the Faction page with null faction");
|
||||||
|
|
||||||
this.state = {
|
const player = use.Player();
|
||||||
rerenderFlag: false,
|
const router = use.Router();
|
||||||
purchasingAugs: props.initiallyOnAugmentationsPage ? props.initiallyOnAugmentationsPage : false,
|
const [, setRerenderFlag] = useState(false);
|
||||||
};
|
const [purchasingAugs, setPurchasingAugs] = useState(false);
|
||||||
|
|
||||||
this.manageGang = this.manageGang.bind(this);
|
function manageGang(faction: Faction): void {
|
||||||
this.rerender = this.rerender.bind(this);
|
|
||||||
this.routeToMain = this.routeToMain.bind(this);
|
|
||||||
this.routeToPurchaseAugs = this.routeToPurchaseAugs.bind(this);
|
|
||||||
this.sleevePurchases = this.sleevePurchases.bind(this);
|
|
||||||
this.startFieldWork = this.startFieldWork.bind(this);
|
|
||||||
this.startHackingContracts = this.startHackingContracts.bind(this);
|
|
||||||
this.startHackingMission = this.startHackingMission.bind(this);
|
|
||||||
this.startSecurityWork = this.startSecurityWork.bind(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
manageGang(): void {
|
|
||||||
// If player already has a gang, just go to the gang UI
|
// If player already has a gang, just go to the gang UI
|
||||||
if (this.props.p.inGang()) {
|
if (player.inGang()) {
|
||||||
return this.props.engine.loadGangContent();
|
return router.toGang();
|
||||||
}
|
}
|
||||||
|
|
||||||
const popupId = "create-gang-popup";
|
const popupId = "create-gang-popup";
|
||||||
createPopup(popupId, CreateGangPopup, {
|
createPopup(popupId, CreateGangPopup, {
|
||||||
popupId: popupId,
|
popupId: popupId,
|
||||||
facName: this.props.faction.name,
|
facName: faction.name,
|
||||||
p: this.props.p,
|
|
||||||
engine: this.props.engine,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
rerender(): void {
|
function rerender(): void {
|
||||||
this.setState((prevState) => {
|
setRerenderFlag((old) => !old);
|
||||||
return {
|
|
||||||
rerenderFlag: !prevState.rerenderFlag,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Route to the main faction page
|
// Route to the main faction page
|
||||||
routeToMain(): void {
|
function routeToMain(): void {
|
||||||
this.setState({ purchasingAugs: false });
|
setPurchasingAugs(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Route to the purchase augmentation UI for this faction
|
// Route to the purchase augmentation UI for this faction
|
||||||
routeToPurchaseAugs(): void {
|
function routeToPurchaseAugs(): void {
|
||||||
this.setState({ purchasingAugs: true });
|
setPurchasingAugs(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
sleevePurchases(): void {
|
function sleevePurchases(): void {
|
||||||
createSleevePurchasesFromCovenantPopup(this.props.p);
|
createSleevePurchasesFromCovenantPopup(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
startFieldWork(): void {
|
function startFieldWork(faction: Faction): void {
|
||||||
this.props.p.startFactionFieldWork(this.props.faction);
|
player.startFactionFieldWork(faction);
|
||||||
|
router.toWork();
|
||||||
}
|
}
|
||||||
|
|
||||||
startHackingContracts(): void {
|
function startHackingContracts(faction: Faction): void {
|
||||||
this.props.p.startFactionHackWork(this.props.faction);
|
player.startFactionHackWork(faction);
|
||||||
|
router.toWork();
|
||||||
}
|
}
|
||||||
|
|
||||||
startHackingMission(): void {
|
function startHackingMission(faction: Faction): void {
|
||||||
const fac = this.props.faction;
|
player.singularityStopWork();
|
||||||
this.props.p.singularityStopWork();
|
props.startHackingMissionFn(faction);
|
||||||
this.props.engine.loadMissionContent();
|
|
||||||
this.props.startHackingMissionFn(fac);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
startSecurityWork(): void {
|
function startSecurityWork(faction: Faction): void {
|
||||||
this.props.p.startFactionSecurityWork(this.props.faction);
|
player.startFactionSecurityWork(faction);
|
||||||
|
router.toWork();
|
||||||
}
|
}
|
||||||
|
|
||||||
render(): React.ReactNode {
|
function MainPage({ faction }: { faction: Faction }): React.ReactElement {
|
||||||
return this.state.purchasingAugs ? this.renderAugmentationsPage() : this.renderMainPage();
|
const p = player;
|
||||||
}
|
|
||||||
|
|
||||||
renderMainPage(): React.ReactNode {
|
|
||||||
const p = this.props.p;
|
|
||||||
const faction = this.props.faction;
|
|
||||||
const factionInfo = faction.getInfo();
|
const factionInfo = faction.getInfo();
|
||||||
|
|
||||||
// We have a special flag for whether the player this faction is the player's
|
// We have a special flag for whether the player this faction is the player's
|
||||||
@ -181,49 +151,51 @@ export class FactionRoot extends React.Component<IProps, IState> {
|
|||||||
<div className="faction-container">
|
<div className="faction-container">
|
||||||
<h1>{faction.name}</h1>
|
<h1>{faction.name}</h1>
|
||||||
<Info faction={faction} factionInfo={factionInfo} />
|
<Info faction={faction} factionInfo={factionInfo} />
|
||||||
{canAccessGang && <Option buttonText={"Manage Gang"} infoText={gangInfo} onClick={this.manageGang} />}
|
{canAccessGang && <Option buttonText={"Manage Gang"} infoText={gangInfo} onClick={() => manageGang(faction)} />}
|
||||||
{!isPlayersGang && factionInfo.offerHackingMission && (
|
{!isPlayersGang && factionInfo.offerHackingMission && (
|
||||||
<Option buttonText={"Hacking Mission"} infoText={hackingMissionInfo} onClick={this.startHackingMission} />
|
<Option
|
||||||
|
buttonText={"Hacking Mission"}
|
||||||
|
infoText={hackingMissionInfo}
|
||||||
|
onClick={() => startHackingMission(faction)}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
{!isPlayersGang && factionInfo.offerHackingWork && (
|
{!isPlayersGang && factionInfo.offerHackingWork && (
|
||||||
<Option
|
<Option
|
||||||
buttonText={"Hacking Contracts"}
|
buttonText={"Hacking Contracts"}
|
||||||
infoText={hackingContractsInfo}
|
infoText={hackingContractsInfo}
|
||||||
onClick={this.startHackingContracts}
|
onClick={() => startHackingContracts(faction)}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{!isPlayersGang && factionInfo.offerFieldWork && (
|
{!isPlayersGang && factionInfo.offerFieldWork && (
|
||||||
<Option buttonText={"Field Work"} infoText={fieldWorkInfo} onClick={this.startFieldWork} />
|
<Option buttonText={"Field Work"} infoText={fieldWorkInfo} onClick={() => startFieldWork(faction)} />
|
||||||
)}
|
)}
|
||||||
{!isPlayersGang && factionInfo.offerSecurityWork && (
|
{!isPlayersGang && factionInfo.offerSecurityWork && (
|
||||||
<Option buttonText={"Security Work"} infoText={securityWorkInfo} onClick={this.startSecurityWork} />
|
<Option buttonText={"Security Work"} infoText={securityWorkInfo} onClick={() => startSecurityWork(faction)} />
|
||||||
)}
|
)}
|
||||||
{!isPlayersGang && factionInfo.offersWork() && (
|
{!isPlayersGang && factionInfo.offersWork() && (
|
||||||
<DonateOption
|
<DonateOption
|
||||||
faction={this.props.faction}
|
faction={faction}
|
||||||
p={this.props.p}
|
p={player}
|
||||||
rerender={this.rerender}
|
rerender={rerender}
|
||||||
favorToDonate={favorToDonate}
|
favorToDonate={favorToDonate}
|
||||||
disabled={!canDonate}
|
disabled={!canDonate}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<Option buttonText={"Purchase Augmentations"} infoText={augmentationsInfo} onClick={this.routeToPurchaseAugs} />
|
<Option buttonText={"Purchase Augmentations"} infoText={augmentationsInfo} onClick={routeToPurchaseAugs} />
|
||||||
{canPurchaseSleeves && (
|
{canPurchaseSleeves && (
|
||||||
<Option
|
<Option
|
||||||
buttonText={"Purchase & Upgrade Duplicate Sleeves"}
|
buttonText={"Purchase & Upgrade Duplicate Sleeves"}
|
||||||
infoText={sleevePurchasesInfo}
|
infoText={sleevePurchasesInfo}
|
||||||
onClick={this.sleevePurchases}
|
onClick={sleevePurchases}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderAugmentationsPage(): React.ReactNode {
|
return purchasingAugs ? (
|
||||||
return (
|
<AugmentationsPage faction={faction} routeToMainPage={routeToMain} />
|
||||||
<>
|
) : (
|
||||||
<AugmentationsPage faction={this.props.faction} p={this.props.p} routeToMainPage={this.routeToMain} />
|
<MainPage faction={faction} />
|
||||||
</>
|
);
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -1,20 +1,20 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||||
import { IEngine } from "../../IEngine";
|
import { IRouter } from "../../ui/Router";
|
||||||
import { Factions } from "../Factions";
|
import { Factions } from "../Factions";
|
||||||
import { displayFactionContent, joinFaction } from "../FactionHelpers";
|
import { Faction } from "../Faction";
|
||||||
|
import { joinFaction } from "../FactionHelpers";
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
player: IPlayer;
|
player: IPlayer;
|
||||||
engine: IEngine;
|
router: IRouter;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function FactionList(props: IProps): React.ReactElement {
|
export function FactionsRoot(props: IProps): React.ReactElement {
|
||||||
const setRerender = useState(false)[1];
|
const setRerender = useState(false)[1];
|
||||||
|
|
||||||
function openFaction(faction: string): void {
|
function openFaction(faction: Faction): void {
|
||||||
props.engine.loadFactionContent();
|
props.router.toFaction(faction);
|
||||||
displayFactionContent(faction);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function acceptInvitation(event: React.MouseEvent<HTMLElement>, faction: string): void {
|
function acceptInvitation(event: React.MouseEvent<HTMLElement>, faction: string): void {
|
||||||
@ -33,7 +33,7 @@ export function FactionList(props: IProps): React.ReactElement {
|
|||||||
<li key={faction}>
|
<li key={faction}>
|
||||||
<a
|
<a
|
||||||
className="a-link-button"
|
className="a-link-button"
|
||||||
onClick={() => openFaction(faction)}
|
onClick={() => openFaction(Factions[faction])}
|
||||||
style={{ padding: "4px", margin: "4px", display: "inline-block" }}
|
style={{ padding: "4px", margin: "4px", display: "inline-block" }}
|
||||||
>
|
>
|
||||||
{faction}
|
{faction}
|
@ -12,6 +12,7 @@ interface IProps {
|
|||||||
player: IPlayer;
|
player: IPlayer;
|
||||||
faction: Faction;
|
faction: Faction;
|
||||||
aug: Augmentation;
|
aug: Augmentation;
|
||||||
|
rerender: () => void;
|
||||||
popupId: string;
|
popupId: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -24,6 +25,7 @@ export function PurchaseAugmentationPopup(props: IProps): React.ReactElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
purchaseAugmentation(props.aug, props.faction);
|
purchaseAugmentation(props.aug, props.faction);
|
||||||
|
props.rerender();
|
||||||
removePopup(props.popupId);
|
removePopup(props.popupId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,6 @@ import * as React from "react";
|
|||||||
import { getNextNeurofluxLevel, hasAugmentationPrereqs, purchaseAugmentation } from "../FactionHelpers";
|
import { getNextNeurofluxLevel, hasAugmentationPrereqs, purchaseAugmentation } from "../FactionHelpers";
|
||||||
import { PurchaseAugmentationPopup } from "./PurchaseAugmentationPopup";
|
import { PurchaseAugmentationPopup } from "./PurchaseAugmentationPopup";
|
||||||
|
|
||||||
import { Augmentation } from "../../Augmentation/Augmentation";
|
|
||||||
import { Augmentations } from "../../Augmentation/Augmentations";
|
import { Augmentations } from "../../Augmentation/Augmentations";
|
||||||
import { AugmentationNames } from "../../Augmentation/data/AugmentationNames";
|
import { AugmentationNames } from "../../Augmentation/data/AugmentationNames";
|
||||||
import { Faction } from "../../Faction/Faction";
|
import { Faction } from "../../Faction/Faction";
|
||||||
@ -28,63 +27,56 @@ type IProps = {
|
|||||||
rerender: () => void;
|
rerender: () => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export class PurchaseableAugmentation extends React.Component<IProps, any> {
|
export function PurchaseableAugmentation(props: IProps): React.ReactElement {
|
||||||
aug: Augmentation;
|
const aug = Augmentations[props.augName];
|
||||||
|
if (aug == null) throw new Error(`aug ${props.augName} does not exists`);
|
||||||
|
|
||||||
constructor(props: IProps) {
|
function getMoneyCost(): number {
|
||||||
super(props);
|
return aug.baseCost * props.faction.getInfo().augmentationPriceMult;
|
||||||
|
|
||||||
const aug = Augmentations[this.props.augName];
|
|
||||||
if (aug == null) throw new Error(`aug ${this.props.augName} does not exists`);
|
|
||||||
this.aug = aug;
|
|
||||||
|
|
||||||
this.handleClick = this.handleClick.bind(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getMoneyCost(): number {
|
function getRepCost(): number {
|
||||||
return this.aug.baseCost * this.props.faction.getInfo().augmentationPriceMult;
|
return aug.baseRepRequirement * props.faction.getInfo().augmentationRepRequirementMult;
|
||||||
}
|
}
|
||||||
|
|
||||||
getRepCost(): number {
|
function handleClick(): void {
|
||||||
return this.aug.baseRepRequirement * this.props.faction.getInfo().augmentationRepRequirementMult;
|
|
||||||
}
|
|
||||||
|
|
||||||
handleClick(): void {
|
|
||||||
if (!Settings.SuppressBuyAugmentationConfirmation) {
|
if (!Settings.SuppressBuyAugmentationConfirmation) {
|
||||||
const popupId = "purchase-augmentation-popup";
|
const popupId = "purchase-augmentation-popup";
|
||||||
createPopup(popupId, PurchaseAugmentationPopup, {
|
createPopup(popupId, PurchaseAugmentationPopup, {
|
||||||
aug: this.aug,
|
aug: aug,
|
||||||
faction: this.props.faction,
|
faction: props.faction,
|
||||||
player: this.props.p,
|
player: props.p,
|
||||||
|
rerender: props.rerender,
|
||||||
popupId: popupId,
|
popupId: popupId,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
purchaseAugmentation(this.aug, this.props.faction);
|
purchaseAugmentation(aug, props.faction);
|
||||||
|
props.rerender();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Whether the player has the prerequisite Augmentations
|
// Whether the player has the prerequisite Augmentations
|
||||||
hasPrereqs(): boolean {
|
function hasPrereqs(): boolean {
|
||||||
return hasAugmentationPrereqs(this.aug);
|
return hasAugmentationPrereqs(aug);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Whether the player has enough rep for this Augmentation
|
// Whether the player has enough rep for this Augmentation
|
||||||
hasReputation(): boolean {
|
function hasReputation(): boolean {
|
||||||
return this.props.faction.playerReputation >= this.getRepCost();
|
return props.faction.playerReputation >= getRepCost();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Whether the player has this augmentations (purchased OR installed)
|
// Whether the player has this augmentations (purchased OR installed)
|
||||||
owned(): boolean {
|
function owned(): boolean {
|
||||||
let owned = false;
|
let owned = false;
|
||||||
for (const queuedAug of this.props.p.queuedAugmentations) {
|
for (const queuedAug of props.p.queuedAugmentations) {
|
||||||
if (queuedAug.name === this.props.augName) {
|
if (queuedAug.name === props.augName) {
|
||||||
owned = true;
|
owned = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const installedAug of this.props.p.augmentations) {
|
for (const installedAug of props.p.augmentations) {
|
||||||
if (installedAug.name === this.props.augName) {
|
if (installedAug.name === props.augName) {
|
||||||
owned = true;
|
owned = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -93,96 +85,94 @@ export class PurchaseableAugmentation extends React.Component<IProps, any> {
|
|||||||
return owned;
|
return owned;
|
||||||
}
|
}
|
||||||
|
|
||||||
render(): React.ReactNode {
|
if (aug == null) {
|
||||||
if (this.aug == null) {
|
console.error(
|
||||||
console.error(
|
`Invalid Augmentation when trying to create PurchaseableAugmentation display element: ${props.augName}`,
|
||||||
`Invalid Augmentation when trying to create PurchaseableAugmentation display element: ${this.props.augName}`,
|
|
||||||
);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const moneyCost = this.getMoneyCost();
|
|
||||||
const repCost = this.getRepCost();
|
|
||||||
|
|
||||||
// Determine UI properties
|
|
||||||
let disabled = false;
|
|
||||||
let status: JSX.Element = <></>;
|
|
||||||
let color = "";
|
|
||||||
if (!this.hasPrereqs()) {
|
|
||||||
disabled = true;
|
|
||||||
status = <>LOCKED (Requires {this.aug.prereqs.map((aug) => AugFormat(aug))} as prerequisite)</>;
|
|
||||||
color = "red";
|
|
||||||
} else if (this.aug.name !== AugmentationNames.NeuroFluxGovernor && (this.aug.owned || this.owned())) {
|
|
||||||
disabled = true;
|
|
||||||
} else if (this.hasReputation()) {
|
|
||||||
status = (
|
|
||||||
<>
|
|
||||||
UNLOCKED (at {Reputation(repCost)} faction reputation) - <Money money={moneyCost} player={this.props.p} />
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
disabled = true;
|
|
||||||
status = (
|
|
||||||
<>
|
|
||||||
LOCKED (Requires {Reputation(repCost)} faction reputation - <Money money={moneyCost} player={this.props.p} />)
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
color = "red";
|
|
||||||
}
|
|
||||||
|
|
||||||
const txtStyle: IMap<string> = {
|
|
||||||
display: "inline-block",
|
|
||||||
};
|
|
||||||
if (color !== "") {
|
|
||||||
txtStyle.color = color;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Determine button txt
|
|
||||||
let btnTxt = this.aug.name;
|
|
||||||
if (this.aug.name === AugmentationNames.NeuroFluxGovernor) {
|
|
||||||
btnTxt += ` - Level ${getNextNeurofluxLevel()}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
let tooltip = <></>;
|
|
||||||
if (typeof this.aug.info === "string")
|
|
||||||
tooltip = (
|
|
||||||
<>
|
|
||||||
<span dangerouslySetInnerHTML={{ __html: this.aug.info }} />
|
|
||||||
<br />
|
|
||||||
<br />
|
|
||||||
{this.aug.stats}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
else
|
|
||||||
tooltip = (
|
|
||||||
<>
|
|
||||||
{this.aug.info}
|
|
||||||
<br />
|
|
||||||
<br />
|
|
||||||
{this.aug.stats}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<li key={this.aug.name}>
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
margin: "4px",
|
|
||||||
padding: "4px",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<StdButton
|
|
||||||
disabled={disabled}
|
|
||||||
onClick={this.handleClick}
|
|
||||||
style={{
|
|
||||||
display: "inline-block",
|
|
||||||
}}
|
|
||||||
text={btnTxt}
|
|
||||||
tooltip={tooltip}
|
|
||||||
/>
|
|
||||||
<p style={txtStyle}>{status}</p>
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
);
|
);
|
||||||
|
return <></>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const moneyCost = getMoneyCost();
|
||||||
|
const repCost = getRepCost();
|
||||||
|
|
||||||
|
// Determine UI properties
|
||||||
|
let disabled = false;
|
||||||
|
let status: JSX.Element = <></>;
|
||||||
|
let color = "";
|
||||||
|
if (!hasPrereqs()) {
|
||||||
|
disabled = true;
|
||||||
|
status = <>LOCKED (Requires {aug.prereqs.map((aug) => AugFormat(aug))} as prerequisite)</>;
|
||||||
|
color = "red";
|
||||||
|
} else if (aug.name !== AugmentationNames.NeuroFluxGovernor && (aug.owned || owned())) {
|
||||||
|
disabled = true;
|
||||||
|
} else if (hasReputation()) {
|
||||||
|
status = (
|
||||||
|
<>
|
||||||
|
UNLOCKED (at {Reputation(repCost)} faction reputation) - <Money money={moneyCost} player={props.p} />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
disabled = true;
|
||||||
|
status = (
|
||||||
|
<>
|
||||||
|
LOCKED (Requires {Reputation(repCost)} faction reputation - <Money money={moneyCost} player={props.p} />)
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
color = "red";
|
||||||
|
}
|
||||||
|
|
||||||
|
const txtStyle: IMap<string> = {
|
||||||
|
display: "inline-block",
|
||||||
|
};
|
||||||
|
if (color !== "") {
|
||||||
|
txtStyle.color = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine button txt
|
||||||
|
let btnTxt = aug.name;
|
||||||
|
if (aug.name === AugmentationNames.NeuroFluxGovernor) {
|
||||||
|
btnTxt += ` - Level ${getNextNeurofluxLevel()}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
let tooltip = <></>;
|
||||||
|
if (typeof aug.info === "string")
|
||||||
|
tooltip = (
|
||||||
|
<>
|
||||||
|
<span dangerouslySetInnerHTML={{ __html: aug.info }} />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
{aug.stats}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
else
|
||||||
|
tooltip = (
|
||||||
|
<>
|
||||||
|
{aug.info}
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
{aug.stats}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<li key={aug.name}>
|
||||||
|
<span
|
||||||
|
style={{
|
||||||
|
margin: "4px",
|
||||||
|
padding: "4px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<StdButton
|
||||||
|
disabled={disabled}
|
||||||
|
onClick={handleClick}
|
||||||
|
style={{
|
||||||
|
display: "inline-block",
|
||||||
|
}}
|
||||||
|
text={btnTxt}
|
||||||
|
tooltip={tooltip}
|
||||||
|
/>
|
||||||
|
<p style={txtStyle}>{status}</p>
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ import { GangMemberUpgrade } from "./GangMemberUpgrade";
|
|||||||
import { GangMember } from "./GangMember";
|
import { GangMember } from "./GangMember";
|
||||||
import { WorkerScript } from "../Netscript/WorkerScript";
|
import { WorkerScript } from "../Netscript/WorkerScript";
|
||||||
import { IPlayer } from "../PersonObjects/IPlayer";
|
import { IPlayer } from "../PersonObjects/IPlayer";
|
||||||
|
import { IAscensionResult } from "./IAscensionResult";
|
||||||
|
|
||||||
export interface IGang {
|
export interface IGang {
|
||||||
facName: string;
|
facName: string;
|
||||||
@ -37,8 +38,9 @@ export interface IGang {
|
|||||||
getWantedPenalty(): number;
|
getWantedPenalty(): number;
|
||||||
calculatePower(): number;
|
calculatePower(): number;
|
||||||
killMember(member: GangMember): void;
|
killMember(member: GangMember): void;
|
||||||
ascendMember(member: GangMember, workerScript: WorkerScript): void;
|
ascendMember(member: GangMember, workerScript: WorkerScript): IAscensionResult;
|
||||||
getDiscount(): number;
|
getDiscount(): number;
|
||||||
getAllTaskNames(): string[];
|
getAllTaskNames(): string[];
|
||||||
getUpgradeCost(upg: GangMemberUpgrade): number;
|
getUpgradeCost(upg: GangMemberUpgrade): number;
|
||||||
|
toJSON(): any;
|
||||||
}
|
}
|
||||||
|
@ -2,20 +2,19 @@
|
|||||||
* React Component for all the gang stuff.
|
* React Component for all the gang stuff.
|
||||||
*/
|
*/
|
||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
|
||||||
import { ManagementSubpage } from "./ManagementSubpage";
|
import { ManagementSubpage } from "./ManagementSubpage";
|
||||||
import { TerritorySubpage } from "./TerritorySubpage";
|
import { TerritorySubpage } from "./TerritorySubpage";
|
||||||
import { IEngine } from "../../IEngine";
|
import { use } from "../../ui/Context";
|
||||||
|
import { Factions } from "../../Faction/Factions";
|
||||||
import { Gang } from "../Gang";
|
import { Gang } from "../Gang";
|
||||||
import { displayFactionContent } from "../../Faction/FactionHelpers";
|
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
gang: Gang;
|
gang: Gang;
|
||||||
player: IPlayer;
|
|
||||||
engine: IEngine;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function Root(props: IProps): React.ReactElement {
|
export function GangRoot(props: IProps): React.ReactElement {
|
||||||
|
const player = use.Player();
|
||||||
|
const router = use.Router();
|
||||||
const [management, setManagement] = useState(true);
|
const [management, setManagement] = useState(true);
|
||||||
const setRerender = useState(false)[1];
|
const setRerender = useState(false)[1];
|
||||||
|
|
||||||
@ -25,8 +24,7 @@ export function Root(props: IProps): React.ReactElement {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
function back(): void {
|
function back(): void {
|
||||||
props.engine.loadFactionContent();
|
router.toFaction(Factions[props.gang.facName]);
|
||||||
displayFactionContent(props.gang.facName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -48,11 +46,7 @@ export function Root(props: IProps): React.ReactElement {
|
|||||||
>
|
>
|
||||||
Gang Territory
|
Gang Territory
|
||||||
</a>
|
</a>
|
||||||
{management ? (
|
{management ? <ManagementSubpage gang={props.gang} player={player} /> : <TerritorySubpage gang={props.gang} />}
|
||||||
<ManagementSubpage gang={props.gang} player={props.player} />
|
|
||||||
) : (
|
|
||||||
<TerritorySubpage gang={props.gang} />
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
@ -1,51 +0,0 @@
|
|||||||
import { Page, routing } from ".././ui/navigationTracking";
|
|
||||||
import { Root } from "./ui/Root";
|
|
||||||
import { IPlayer } from "../PersonObjects/IPlayer";
|
|
||||||
import { IEngine } from "../IEngine";
|
|
||||||
import * as React from "react";
|
|
||||||
import * as ReactDOM from "react-dom";
|
|
||||||
|
|
||||||
let container: HTMLElement;
|
|
||||||
|
|
||||||
(function () {
|
|
||||||
function setContainer(): void {
|
|
||||||
const c = document.getElementById("infiltration-container");
|
|
||||||
if (c === null) throw new Error("huh?");
|
|
||||||
container = c;
|
|
||||||
document.removeEventListener("DOMContentLoaded", setContainer);
|
|
||||||
}
|
|
||||||
|
|
||||||
document.addEventListener("DOMContentLoaded", setContainer);
|
|
||||||
})();
|
|
||||||
|
|
||||||
function calcDifficulty(player: IPlayer, startingDifficulty: number): number {
|
|
||||||
const totalStats = player.strength + player.defense + player.dexterity + player.agility + player.charisma;
|
|
||||||
const difficulty = startingDifficulty - Math.pow(totalStats, 0.9) / 250 - player.intelligence / 1600;
|
|
||||||
if (difficulty < 0) return 0;
|
|
||||||
if (difficulty > 3) return 3;
|
|
||||||
return difficulty;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function displayInfiltrationContent(
|
|
||||||
engine: IEngine,
|
|
||||||
player: IPlayer,
|
|
||||||
location: string,
|
|
||||||
startingDifficulty: number,
|
|
||||||
maxLevel: number,
|
|
||||||
): void {
|
|
||||||
if (!routing.isOn(Page.Infiltration)) return;
|
|
||||||
|
|
||||||
const difficulty = calcDifficulty(player, startingDifficulty);
|
|
||||||
|
|
||||||
ReactDOM.render(
|
|
||||||
<Root
|
|
||||||
Engine={engine}
|
|
||||||
Player={player}
|
|
||||||
Location={location}
|
|
||||||
StartingDifficulty={startingDifficulty}
|
|
||||||
Difficulty={difficulty}
|
|
||||||
MaxLevel={maxLevel}
|
|
||||||
/>,
|
|
||||||
container,
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,5 +1,4 @@
|
|||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
import { use } from "../../ui/Context";
|
||||||
import { IEngine } from "../../IEngine";
|
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import Grid from "@mui/material/Grid";
|
import Grid from "@mui/material/Grid";
|
||||||
import { Countdown } from "./Countdown";
|
import { Countdown } from "./Countdown";
|
||||||
@ -14,8 +13,6 @@ import { WireCuttingGame } from "./WireCuttingGame";
|
|||||||
import { Victory } from "./Victory";
|
import { Victory } from "./Victory";
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
Player: IPlayer;
|
|
||||||
Engine: IEngine;
|
|
||||||
StartingDifficulty: number;
|
StartingDifficulty: number;
|
||||||
Difficulty: number;
|
Difficulty: number;
|
||||||
MaxLevel: number;
|
MaxLevel: number;
|
||||||
@ -40,6 +37,8 @@ const minigames = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
export function Game(props: IProps): React.ReactElement {
|
export function Game(props: IProps): React.ReactElement {
|
||||||
|
const player = use.Player();
|
||||||
|
const router = use.Router();
|
||||||
const [level, setLevel] = useState(1);
|
const [level, setLevel] = useState(1);
|
||||||
const [stage, setStage] = useState(Stage.Countdown);
|
const [stage, setStage] = useState(Stage.Countdown);
|
||||||
const [results, setResults] = useState("");
|
const [results, setResults] = useState("");
|
||||||
@ -89,12 +88,10 @@ export function Game(props: IProps): React.ReactElement {
|
|||||||
pushResult(false);
|
pushResult(false);
|
||||||
// Kill the player immediately if they use automation, so
|
// Kill the player immediately if they use automation, so
|
||||||
// it's clear they're not meant to
|
// it's clear they're not meant to
|
||||||
const damage = options?.automated ? props.Player.hp : props.StartingDifficulty * 3;
|
const damage = options?.automated ? player.hp : props.StartingDifficulty * 3;
|
||||||
if (props.Player.takeDamage(damage)) {
|
if (player.takeDamage(damage)) {
|
||||||
const menu = document.getElementById("mainmenu-container");
|
router.toCity();
|
||||||
if (menu === null) throw new Error("mainmenu-container not found");
|
return;
|
||||||
menu.style.visibility = "visible";
|
|
||||||
props.Engine.loadLocationContent();
|
|
||||||
}
|
}
|
||||||
setupNextGame();
|
setupNextGame();
|
||||||
}
|
}
|
||||||
@ -112,8 +109,6 @@ export function Game(props: IProps): React.ReactElement {
|
|||||||
case Stage.Sell:
|
case Stage.Sell:
|
||||||
stageComponent = (
|
stageComponent = (
|
||||||
<Victory
|
<Victory
|
||||||
Player={props.Player}
|
|
||||||
Engine={props.Engine}
|
|
||||||
StartingDifficulty={props.StartingDifficulty}
|
StartingDifficulty={props.StartingDifficulty}
|
||||||
Difficulty={props.Difficulty}
|
Difficulty={props.Difficulty}
|
||||||
MaxLevel={props.MaxLevel}
|
MaxLevel={props.MaxLevel}
|
||||||
|
53
src/Infiltration/ui/InfiltrationRoot.tsx
Normal file
53
src/Infiltration/ui/InfiltrationRoot.tsx
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import { Intro } from "./Intro";
|
||||||
|
import { Game } from "./Game";
|
||||||
|
import { LocationName } from "../../Locations/data/LocationNames";
|
||||||
|
import { Locations } from "../../Locations/Locations";
|
||||||
|
import { use } from "../../ui/Context";
|
||||||
|
|
||||||
|
interface IProps {
|
||||||
|
location: LocationName;
|
||||||
|
}
|
||||||
|
function calcDifficulty(player: IPlayer, startingDifficulty: number): number {
|
||||||
|
const totalStats = player.strength + player.defense + player.dexterity + player.agility + player.charisma;
|
||||||
|
const difficulty = startingDifficulty - Math.pow(totalStats, 0.9) / 250 - player.intelligence / 1600;
|
||||||
|
if (difficulty < 0) return 0;
|
||||||
|
if (difficulty > 3) return 3;
|
||||||
|
return difficulty;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function InfiltrationRoot(props: IProps): React.ReactElement {
|
||||||
|
const player = use.Player();
|
||||||
|
const router = use.Router();
|
||||||
|
const [start, setStart] = useState(false);
|
||||||
|
|
||||||
|
const loc = Locations[props.location];
|
||||||
|
if (loc.infiltrationData === undefined) throw new Error("Trying to do infiltration on invalid location.");
|
||||||
|
const startingDifficulty = loc.infiltrationData.startingSecurityLevel;
|
||||||
|
const difficulty = calcDifficulty(player, startingDifficulty);
|
||||||
|
|
||||||
|
function cancel(): void {
|
||||||
|
router.toCity();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!start) {
|
||||||
|
return (
|
||||||
|
<Intro
|
||||||
|
Location={props.location}
|
||||||
|
Difficulty={difficulty}
|
||||||
|
MaxLevel={loc.infiltrationData.maxClearanceLevel}
|
||||||
|
start={() => setStart(true)}
|
||||||
|
cancel={cancel}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Game
|
||||||
|
StartingDifficulty={startingDifficulty}
|
||||||
|
Difficulty={difficulty}
|
||||||
|
MaxLevel={loc.infiltrationData.maxClearanceLevel}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
@ -1,12 +1,8 @@
|
|||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
|
||||||
import { IEngine } from "../../IEngine";
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { StdButton } from "../../ui/React/StdButton";
|
import { StdButton } from "../../ui/React/StdButton";
|
||||||
import Grid from "@mui/material/Grid";
|
import Grid from "@mui/material/Grid";
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
Player: IPlayer;
|
|
||||||
Engine: IEngine;
|
|
||||||
Location: string;
|
Location: string;
|
||||||
Difficulty: number;
|
Difficulty: number;
|
||||||
MaxLevel: number;
|
MaxLevel: number;
|
||||||
|
@ -1,49 +0,0 @@
|
|||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
|
||||||
import { IEngine } from "../../IEngine";
|
|
||||||
import React, { useState } from "react";
|
|
||||||
import { Intro } from "./Intro";
|
|
||||||
import { Game } from "./Game";
|
|
||||||
|
|
||||||
interface IProps {
|
|
||||||
Player: IPlayer;
|
|
||||||
Engine: IEngine;
|
|
||||||
Location: string;
|
|
||||||
StartingDifficulty: number;
|
|
||||||
Difficulty: number;
|
|
||||||
MaxLevel: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function Root(props: IProps): React.ReactElement {
|
|
||||||
const [start, setStart] = useState(false);
|
|
||||||
|
|
||||||
function cancel(): void {
|
|
||||||
const menu = document.getElementById("mainmenu-container");
|
|
||||||
if (menu === null) throw new Error("mainmenu-container not found");
|
|
||||||
menu.style.visibility = "visible";
|
|
||||||
props.Engine.loadLocationContent();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!start) {
|
|
||||||
return (
|
|
||||||
<Intro
|
|
||||||
Player={props.Player}
|
|
||||||
Engine={props.Engine}
|
|
||||||
Location={props.Location}
|
|
||||||
Difficulty={props.Difficulty}
|
|
||||||
MaxLevel={props.MaxLevel}
|
|
||||||
start={() => setStart(true)}
|
|
||||||
cancel={cancel}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Game
|
|
||||||
Player={props.Player}
|
|
||||||
Engine={props.Engine}
|
|
||||||
StartingDifficulty={props.StartingDifficulty}
|
|
||||||
Difficulty={props.Difficulty}
|
|
||||||
MaxLevel={props.MaxLevel}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,5 +1,3 @@
|
|||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
|
||||||
import { IEngine } from "../../IEngine";
|
|
||||||
import { Factions } from "../../Faction/Factions";
|
import { Factions } from "../../Faction/Factions";
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { StdButton } from "../../ui/React/StdButton";
|
import { StdButton } from "../../ui/React/StdButton";
|
||||||
@ -7,23 +5,21 @@ import Grid from "@mui/material/Grid";
|
|||||||
import { Money } from "../../ui/React/Money";
|
import { Money } from "../../ui/React/Money";
|
||||||
import { Reputation } from "../../ui/React/Reputation";
|
import { Reputation } from "../../ui/React/Reputation";
|
||||||
import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers";
|
import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers";
|
||||||
|
import { use } from "../../ui/Context";
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
Player: IPlayer;
|
|
||||||
Engine: IEngine;
|
|
||||||
StartingDifficulty: number;
|
StartingDifficulty: number;
|
||||||
Difficulty: number;
|
Difficulty: number;
|
||||||
MaxLevel: number;
|
MaxLevel: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function Victory(props: IProps): React.ReactElement {
|
export function Victory(props: IProps): React.ReactElement {
|
||||||
|
const player = use.Player();
|
||||||
|
const router = use.Router();
|
||||||
const [faction, setFaction] = useState("none");
|
const [faction, setFaction] = useState("none");
|
||||||
|
|
||||||
function quitInfiltration(): void {
|
function quitInfiltration(): void {
|
||||||
const menu = document.getElementById("mainmenu-container");
|
router.toCity();
|
||||||
if (!menu) throw new Error("mainmenu-container somehow null");
|
|
||||||
menu.style.visibility = "visible";
|
|
||||||
props.Engine.loadLocationContent();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const levelBonus = props.MaxLevel * Math.pow(1.01, props.MaxLevel);
|
const levelBonus = props.MaxLevel * Math.pow(1.01, props.MaxLevel);
|
||||||
@ -43,8 +39,8 @@ export function Victory(props: IProps): React.ReactElement {
|
|||||||
BitNodeMultipliers.InfiltrationMoney;
|
BitNodeMultipliers.InfiltrationMoney;
|
||||||
|
|
||||||
function sell(): void {
|
function sell(): void {
|
||||||
props.Player.gainMoney(moneyGain);
|
player.gainMoney(moneyGain);
|
||||||
props.Player.recordMoneySource(moneyGain, "infiltration");
|
player.recordMoneySource(moneyGain, "infiltration");
|
||||||
quitInfiltration();
|
quitInfiltration();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,7 +66,7 @@ export function Victory(props: IProps): React.ReactElement {
|
|||||||
<option key={"none"} value={"none"}>
|
<option key={"none"} value={"none"}>
|
||||||
{"none"}
|
{"none"}
|
||||||
</option>
|
</option>
|
||||||
{props.Player.factions
|
{player.factions
|
||||||
.filter((f) => Factions[f].getInfo().offersWork())
|
.filter((f) => Factions[f].getInfo().offersWork())
|
||||||
.map((f) => (
|
.map((f) => (
|
||||||
<option key={f} value={f}>
|
<option key={f} value={f}>
|
||||||
|
@ -63,8 +63,6 @@ function iTutorialStart() {
|
|||||||
ITutorial.stepIsDone[i] = false;
|
ITutorial.stepIsDone[i] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Engine.loadTerminalContent();
|
|
||||||
|
|
||||||
// Don't autosave during this interactive tutorial
|
// Don't autosave during this interactive tutorial
|
||||||
Engine.Counters.autoSaveCounter = Infinity;
|
Engine.Counters.autoSaveCounter = Infinity;
|
||||||
ITutorial.currStep = 0;
|
ITutorial.currStep = 0;
|
||||||
@ -120,7 +118,6 @@ function iTutorialEvaluateStep() {
|
|||||||
|
|
||||||
switch (ITutorial.currStep) {
|
switch (ITutorial.currStep) {
|
||||||
case iTutorialSteps.Start:
|
case iTutorialSteps.Start:
|
||||||
Engine.loadTerminalContent();
|
|
||||||
iTutorialSetText(
|
iTutorialSetText(
|
||||||
"Welcome to Bitburner, a cyberpunk-themed incremental RPG! " +
|
"Welcome to Bitburner, a cyberpunk-themed incremental RPG! " +
|
||||||
"The game takes place in a dark, dystopian future... The year is 2077...<br><br>" +
|
"The game takes place in a dark, dystopian future... The year is 2077...<br><br>" +
|
||||||
@ -130,7 +127,6 @@ function iTutorialEvaluateStep() {
|
|||||||
nextBtn.style.display = "inline-block";
|
nextBtn.style.display = "inline-block";
|
||||||
break;
|
break;
|
||||||
case iTutorialSteps.GoToCharacterPage:
|
case iTutorialSteps.GoToCharacterPage:
|
||||||
Engine.loadTerminalContent();
|
|
||||||
iTutorialSetText(
|
iTutorialSetText(
|
||||||
"Let's start by heading to the Stats page. Click the <code class='interactive-tutorial-tab flashing-button'>Stats</code> tab on " +
|
"Let's start by heading to the Stats page. Click the <code class='interactive-tutorial-tab flashing-button'>Stats</code> tab on " +
|
||||||
"the main navigation menu (left-hand side of the screen)",
|
"the main navigation menu (left-hand side of the screen)",
|
||||||
@ -138,7 +134,6 @@ function iTutorialEvaluateStep() {
|
|||||||
nextBtn.style.display = "none";
|
nextBtn.style.display = "none";
|
||||||
break;
|
break;
|
||||||
case iTutorialSteps.CharacterPage:
|
case iTutorialSteps.CharacterPage:
|
||||||
Engine.loadCharacterContent();
|
|
||||||
iTutorialSetText(
|
iTutorialSetText(
|
||||||
"The <code class='interactive-tutorial-tab'>Stats</code> page shows a lot of important information about your progress, " +
|
"The <code class='interactive-tutorial-tab'>Stats</code> page shows a lot of important information about your progress, " +
|
||||||
"such as your skills, money, and bonuses. ",
|
"such as your skills, money, and bonuses. ",
|
||||||
@ -146,7 +141,6 @@ function iTutorialEvaluateStep() {
|
|||||||
nextBtn.style.display = "inline-block";
|
nextBtn.style.display = "inline-block";
|
||||||
break;
|
break;
|
||||||
case iTutorialSteps.CharacterGoToTerminalPage:
|
case iTutorialSteps.CharacterGoToTerminalPage:
|
||||||
Engine.loadCharacterContent();
|
|
||||||
iTutorialSetText(
|
iTutorialSetText(
|
||||||
"Let's head to your computer's terminal by clicking the <code class='interactive-tutorial-tab flashing-button'>Terminal</code> tab on the " +
|
"Let's head to your computer's terminal by clicking the <code class='interactive-tutorial-tab flashing-button'>Terminal</code> tab on the " +
|
||||||
"main navigation menu.",
|
"main navigation menu.",
|
||||||
@ -154,7 +148,6 @@ function iTutorialEvaluateStep() {
|
|||||||
nextBtn.style.display = "none";
|
nextBtn.style.display = "none";
|
||||||
break;
|
break;
|
||||||
case iTutorialSteps.TerminalIntro:
|
case iTutorialSteps.TerminalIntro:
|
||||||
Engine.loadTerminalContent();
|
|
||||||
iTutorialSetText(
|
iTutorialSetText(
|
||||||
"The <code class='interactive-tutorial-tab'>Terminal</code> is used to interface with your home computer as well as " +
|
"The <code class='interactive-tutorial-tab'>Terminal</code> is used to interface with your home computer as well as " +
|
||||||
"all of the other machines around the world.",
|
"all of the other machines around the world.",
|
||||||
@ -162,7 +155,6 @@ function iTutorialEvaluateStep() {
|
|||||||
nextBtn.style.display = "inline-block";
|
nextBtn.style.display = "inline-block";
|
||||||
break;
|
break;
|
||||||
case iTutorialSteps.TerminalHelp:
|
case iTutorialSteps.TerminalHelp:
|
||||||
Engine.loadTerminalContent();
|
|
||||||
iTutorialSetText(
|
iTutorialSetText(
|
||||||
"Let's try it out. Start by entering the <code class='interactive-tutorial-command'>help</code> command into the <code class='interactive-tutorial-tab'>Terminal</code> " +
|
"Let's try it out. Start by entering the <code class='interactive-tutorial-command'>help</code> command into the <code class='interactive-tutorial-tab'>Terminal</code> " +
|
||||||
"(Don't forget to press Enter after typing the command)",
|
"(Don't forget to press Enter after typing the command)",
|
||||||
@ -170,7 +162,6 @@ function iTutorialEvaluateStep() {
|
|||||||
nextBtn.style.display = "none"; // next step triggered by terminal command
|
nextBtn.style.display = "none"; // next step triggered by terminal command
|
||||||
break;
|
break;
|
||||||
case iTutorialSteps.TerminalLs:
|
case iTutorialSteps.TerminalLs:
|
||||||
Engine.loadTerminalContent();
|
|
||||||
iTutorialSetText(
|
iTutorialSetText(
|
||||||
"The <code class='interactive-tutorial-command'>help</code> command displays a list of all available <code class='interactive-tutorial-tab'>Terminal</code> commands, how to use them, " +
|
"The <code class='interactive-tutorial-command'>help</code> command displays a list of all available <code class='interactive-tutorial-tab'>Terminal</code> commands, how to use them, " +
|
||||||
"and a description of what they do. <br><br>Let's try another command. Enter the <code class='interactive-tutorial-command'>ls</code> command.",
|
"and a description of what they do. <br><br>Let's try another command. Enter the <code class='interactive-tutorial-command'>ls</code> command.",
|
||||||
@ -178,7 +169,6 @@ function iTutorialEvaluateStep() {
|
|||||||
nextBtn.style.display = "none"; // next step triggered by terminal command
|
nextBtn.style.display = "none"; // next step triggered by terminal command
|
||||||
break;
|
break;
|
||||||
case iTutorialSteps.TerminalScan:
|
case iTutorialSteps.TerminalScan:
|
||||||
Engine.loadTerminalContent();
|
|
||||||
iTutorialSetText(
|
iTutorialSetText(
|
||||||
" <code class='interactive-tutorial-command'>ls</code> is a basic command that shows files " +
|
" <code class='interactive-tutorial-command'>ls</code> is a basic command that shows files " +
|
||||||
"on the computer. Right now, it shows that you have a program called <code class='interactive-tutorial-command'>NUKE.exe</code> on your computer. " +
|
"on the computer. Right now, it shows that you have a program called <code class='interactive-tutorial-command'>NUKE.exe</code> on your computer. " +
|
||||||
@ -189,7 +179,6 @@ function iTutorialEvaluateStep() {
|
|||||||
nextBtn.style.display = "none"; // next step triggered by terminal command
|
nextBtn.style.display = "none"; // next step triggered by terminal command
|
||||||
break;
|
break;
|
||||||
case iTutorialSteps.TerminalScanAnalyze1:
|
case iTutorialSteps.TerminalScanAnalyze1:
|
||||||
Engine.loadTerminalContent();
|
|
||||||
iTutorialSetText(
|
iTutorialSetText(
|
||||||
"The <code class='interactive-tutorial-command'>scan</code> command shows all available network connections. In other words, " +
|
"The <code class='interactive-tutorial-command'>scan</code> command shows all available network connections. In other words, " +
|
||||||
"it displays a list of all servers that can be connected to from your " +
|
"it displays a list of all servers that can be connected to from your " +
|
||||||
@ -201,7 +190,6 @@ function iTutorialEvaluateStep() {
|
|||||||
nextBtn.style.display = "none"; // next step triggered by terminal command
|
nextBtn.style.display = "none"; // next step triggered by terminal command
|
||||||
break;
|
break;
|
||||||
case iTutorialSteps.TerminalScanAnalyze2:
|
case iTutorialSteps.TerminalScanAnalyze2:
|
||||||
Engine.loadTerminalContent();
|
|
||||||
iTutorialSetText(
|
iTutorialSetText(
|
||||||
"You just ran <code class='interactive-tutorial-command'>scan-analyze</code> with a depth of one. This command shows more detailed " +
|
"You just ran <code class='interactive-tutorial-command'>scan-analyze</code> with a depth of one. This command shows more detailed " +
|
||||||
"information about each server that you can connect to (servers that are a distance of " +
|
"information about each server that you can connect to (servers that are a distance of " +
|
||||||
@ -211,7 +199,6 @@ function iTutorialEvaluateStep() {
|
|||||||
nextBtn.style.display = "none"; // next step triggered by terminal command
|
nextBtn.style.display = "none"; // next step triggered by terminal command
|
||||||
break;
|
break;
|
||||||
case iTutorialSteps.TerminalConnect:
|
case iTutorialSteps.TerminalConnect:
|
||||||
Engine.loadTerminalContent();
|
|
||||||
iTutorialSetText(
|
iTutorialSetText(
|
||||||
"Now you can see information about all servers that are up to two nodes away, as well " +
|
"Now you can see information about all servers that are up to two nodes away, as well " +
|
||||||
"as figure out how to navigate to those servers through the network. You can only connect to " +
|
"as figure out how to navigate to those servers through the network. You can only connect to " +
|
||||||
@ -222,7 +209,6 @@ function iTutorialEvaluateStep() {
|
|||||||
nextBtn.style.display = "none"; // next step triggered by terminal command
|
nextBtn.style.display = "none"; // next step triggered by terminal command
|
||||||
break;
|
break;
|
||||||
case iTutorialSteps.TerminalAnalyze:
|
case iTutorialSteps.TerminalAnalyze:
|
||||||
Engine.loadTerminalContent();
|
|
||||||
iTutorialSetText(
|
iTutorialSetText(
|
||||||
"You are now connected to another machine! What can you do now? You can hack it!<br><br> In the year 2077, currency has " +
|
"You are now connected to another machine! What can you do now? You can hack it!<br><br> In the year 2077, currency has " +
|
||||||
"become digital and decentralized. People and corporations store their money " +
|
"become digital and decentralized. People and corporations store their money " +
|
||||||
@ -233,7 +219,6 @@ function iTutorialEvaluateStep() {
|
|||||||
nextBtn.style.display = "none"; // next step triggered by terminal command
|
nextBtn.style.display = "none"; // next step triggered by terminal command
|
||||||
break;
|
break;
|
||||||
case iTutorialSteps.TerminalNuke:
|
case iTutorialSteps.TerminalNuke:
|
||||||
Engine.loadTerminalContent();
|
|
||||||
iTutorialSetText(
|
iTutorialSetText(
|
||||||
"When the <code class='interactive-tutorial-command'>analyze</code> command finishes running it will show useful information " +
|
"When the <code class='interactive-tutorial-command'>analyze</code> command finishes running it will show useful information " +
|
||||||
"about hacking the server. <br><br> For this server, the required hacking skill is only <span class='character-hack-cell'>1</span>, " +
|
"about hacking the server. <br><br> For this server, the required hacking skill is only <span class='character-hack-cell'>1</span>, " +
|
||||||
@ -247,7 +232,6 @@ function iTutorialEvaluateStep() {
|
|||||||
nextBtn.style.display = "none"; // next step triggered by terminal command
|
nextBtn.style.display = "none"; // next step triggered by terminal command
|
||||||
break;
|
break;
|
||||||
case iTutorialSteps.TerminalManualHack:
|
case iTutorialSteps.TerminalManualHack:
|
||||||
Engine.loadTerminalContent();
|
|
||||||
iTutorialSetText(
|
iTutorialSetText(
|
||||||
"You now have root access! You can hack the server using the <code class='interactive-tutorial-command'>hack</code> command. " +
|
"You now have root access! You can hack the server using the <code class='interactive-tutorial-command'>hack</code> command. " +
|
||||||
"Try doing that now.",
|
"Try doing that now.",
|
||||||
@ -255,7 +239,6 @@ function iTutorialEvaluateStep() {
|
|||||||
nextBtn.style.display = "none"; // next step triggered by terminal command
|
nextBtn.style.display = "none"; // next step triggered by terminal command
|
||||||
break;
|
break;
|
||||||
case iTutorialSteps.TerminalHackingMechanics:
|
case iTutorialSteps.TerminalHackingMechanics:
|
||||||
Engine.loadTerminalContent();
|
|
||||||
iTutorialSetText(
|
iTutorialSetText(
|
||||||
"You are now attempting to hack the server. Performing a hack takes time and " +
|
"You are now attempting to hack the server. Performing a hack takes time and " +
|
||||||
"only has a certain percentage chance " +
|
"only has a certain percentage chance " +
|
||||||
@ -270,7 +253,6 @@ function iTutorialEvaluateStep() {
|
|||||||
nextBtn.style.display = "inline-block";
|
nextBtn.style.display = "inline-block";
|
||||||
break;
|
break;
|
||||||
case iTutorialSteps.TerminalCreateScript:
|
case iTutorialSteps.TerminalCreateScript:
|
||||||
Engine.loadTerminalContent();
|
|
||||||
iTutorialSetText(
|
iTutorialSetText(
|
||||||
"Hacking is the core mechanic of the game and is necessary for progressing. However, " +
|
"Hacking is the core mechanic of the game and is necessary for progressing. However, " +
|
||||||
"you don't want to be hacking manually the entire time. You can automate your hacking " +
|
"you don't want to be hacking manually the entire time. You can automate your hacking " +
|
||||||
@ -282,7 +264,6 @@ function iTutorialEvaluateStep() {
|
|||||||
nextBtn.style.display = "none"; // next step triggered by terminal command
|
nextBtn.style.display = "none"; // next step triggered by terminal command
|
||||||
break;
|
break;
|
||||||
case iTutorialSteps.TerminalTypeScript:
|
case iTutorialSteps.TerminalTypeScript:
|
||||||
Engine.loadScriptEditorContent("n00dles.script", "");
|
|
||||||
iTutorialSetText(
|
iTutorialSetText(
|
||||||
"This is the script editor. You can use it to program your scripts. Scripts are " +
|
"This is the script editor. You can use it to program your scripts. Scripts are " +
|
||||||
"written in a simplified version of javascript. Copy and paste the following code into the script editor: <br><br>" +
|
"written in a simplified version of javascript. Copy and paste the following code into the script editor: <br><br>" +
|
||||||
@ -297,7 +278,6 @@ function iTutorialEvaluateStep() {
|
|||||||
nextBtn.style.display = "none"; // next step triggered in saveAndCloseScriptEditor() (Script.js)
|
nextBtn.style.display = "none"; // next step triggered in saveAndCloseScriptEditor() (Script.js)
|
||||||
break;
|
break;
|
||||||
case iTutorialSteps.TerminalFree:
|
case iTutorialSteps.TerminalFree:
|
||||||
Engine.loadTerminalContent();
|
|
||||||
iTutorialSetText(
|
iTutorialSetText(
|
||||||
"Now we'll run the script. Scripts require a certain amount of RAM to run, and can be " +
|
"Now we'll run the script. Scripts require a certain amount of RAM to run, and can be " +
|
||||||
"run on any machine which you have root access to. Different servers have different " +
|
"run on any machine which you have root access to. Different servers have different " +
|
||||||
@ -307,7 +287,6 @@ function iTutorialEvaluateStep() {
|
|||||||
nextBtn.style.display = "none"; // next step triggered by terminal commmand
|
nextBtn.style.display = "none"; // next step triggered by terminal commmand
|
||||||
break;
|
break;
|
||||||
case iTutorialSteps.TerminalRunScript:
|
case iTutorialSteps.TerminalRunScript:
|
||||||
Engine.loadTerminalContent();
|
|
||||||
iTutorialSetText(
|
iTutorialSetText(
|
||||||
"We have 4GB of free RAM on this machine, which is enough to run our " +
|
"We have 4GB of free RAM on this machine, which is enough to run our " +
|
||||||
"script. Let's run our script using <code class='interactive-tutorial-command'>run n00dles.script</code>.",
|
"script. Let's run our script using <code class='interactive-tutorial-command'>run n00dles.script</code>.",
|
||||||
@ -315,7 +294,6 @@ function iTutorialEvaluateStep() {
|
|||||||
nextBtn.style.display = "none"; // next step triggered by terminal commmand
|
nextBtn.style.display = "none"; // next step triggered by terminal commmand
|
||||||
break;
|
break;
|
||||||
case iTutorialSteps.TerminalGoToActiveScriptsPage:
|
case iTutorialSteps.TerminalGoToActiveScriptsPage:
|
||||||
Engine.loadTerminalContent();
|
|
||||||
iTutorialSetText(
|
iTutorialSetText(
|
||||||
"Your script is now running! " +
|
"Your script is now running! " +
|
||||||
"It will continuously run in the background and will automatically stop if " +
|
"It will continuously run in the background and will automatically stop if " +
|
||||||
@ -329,7 +307,6 @@ function iTutorialEvaluateStep() {
|
|||||||
nextBtn.style.display = "none";
|
nextBtn.style.display = "none";
|
||||||
break;
|
break;
|
||||||
case iTutorialSteps.ActiveScriptsPage:
|
case iTutorialSteps.ActiveScriptsPage:
|
||||||
Engine.loadActiveScriptsContent();
|
|
||||||
iTutorialSetText(
|
iTutorialSetText(
|
||||||
"This page displays information about all of your scripts that are " +
|
"This page displays information about all of your scripts that are " +
|
||||||
"running across every server. You can use this to gauge how well " +
|
"running across every server. You can use this to gauge how well " +
|
||||||
@ -338,7 +315,6 @@ function iTutorialEvaluateStep() {
|
|||||||
nextBtn.style.display = "none";
|
nextBtn.style.display = "none";
|
||||||
break;
|
break;
|
||||||
case iTutorialSteps.ActiveScriptsToTerminal:
|
case iTutorialSteps.ActiveScriptsToTerminal:
|
||||||
Engine.loadTerminalContent();
|
|
||||||
iTutorialSetText(
|
iTutorialSetText(
|
||||||
"One last thing about scripts, each active script contains logs that detail " +
|
"One last thing about scripts, each active script contains logs that detail " +
|
||||||
"what it's doing. We can check these logs using the <code class='interactive-tutorial-command'>tail</code> command. Do that " +
|
"what it's doing. We can check these logs using the <code class='interactive-tutorial-command'>tail</code> command. Do that " +
|
||||||
@ -347,7 +323,6 @@ function iTutorialEvaluateStep() {
|
|||||||
nextBtn.style.display = "none"; // next step triggered by terminal command
|
nextBtn.style.display = "none"; // next step triggered by terminal command
|
||||||
break;
|
break;
|
||||||
case iTutorialSteps.TerminalTailScript:
|
case iTutorialSteps.TerminalTailScript:
|
||||||
Engine.loadTerminalContent();
|
|
||||||
iTutorialSetText(
|
iTutorialSetText(
|
||||||
"The log for this script won't show much right now (it might show nothing at all) because it " +
|
"The log for this script won't show much right now (it might show nothing at all) because it " +
|
||||||
"just started running...but check back again in a few minutes! <br><br>" +
|
"just started running...but check back again in a few minutes! <br><br>" +
|
||||||
@ -361,7 +336,6 @@ function iTutorialEvaluateStep() {
|
|||||||
nextBtn.style.display = "inline-block";
|
nextBtn.style.display = "inline-block";
|
||||||
break;
|
break;
|
||||||
case iTutorialSteps.GoToHacknetNodesPage:
|
case iTutorialSteps.GoToHacknetNodesPage:
|
||||||
Engine.loadTerminalContent();
|
|
||||||
iTutorialSetText(
|
iTutorialSetText(
|
||||||
"Hacking is not the only way to earn money. One other way to passively " +
|
"Hacking is not the only way to earn money. One other way to passively " +
|
||||||
"earn money is by purchasing and upgrading Hacknet Nodes. Let's go to " +
|
"earn money is by purchasing and upgrading Hacknet Nodes. Let's go to " +
|
||||||
@ -370,14 +344,12 @@ function iTutorialEvaluateStep() {
|
|||||||
nextBtn.style.display = "none";
|
nextBtn.style.display = "none";
|
||||||
break;
|
break;
|
||||||
case iTutorialSteps.HacknetNodesIntroduction:
|
case iTutorialSteps.HacknetNodesIntroduction:
|
||||||
Engine.loadHacknetNodesContent();
|
|
||||||
iTutorialSetText(
|
iTutorialSetText(
|
||||||
"here you can purchase new Hacknet Nodes and upgrade your " + "existing ones. Let's purchase a new one now.",
|
"here you can purchase new Hacknet Nodes and upgrade your " + "existing ones. Let's purchase a new one now.",
|
||||||
);
|
);
|
||||||
nextBtn.style.display = "none"; // Next step triggered by purchaseHacknet() (HacknetNode.js)
|
nextBtn.style.display = "none"; // Next step triggered by purchaseHacknet() (HacknetNode.js)
|
||||||
break;
|
break;
|
||||||
case iTutorialSteps.HacknetNodesGoToWorldPage:
|
case iTutorialSteps.HacknetNodesGoToWorldPage:
|
||||||
Engine.loadHacknetNodesContent();
|
|
||||||
iTutorialSetText(
|
iTutorialSetText(
|
||||||
"You just purchased a Hacknet Node! This Hacknet Node will passively " +
|
"You just purchased a Hacknet Node! This Hacknet Node will passively " +
|
||||||
"earn you money over time, both online and offline. When you get enough " +
|
"earn you money over time, both online and offline. When you get enough " +
|
||||||
@ -388,7 +360,6 @@ function iTutorialEvaluateStep() {
|
|||||||
nextBtn.style.display = "none";
|
nextBtn.style.display = "none";
|
||||||
break;
|
break;
|
||||||
case iTutorialSteps.WorldDescription:
|
case iTutorialSteps.WorldDescription:
|
||||||
Engine.loadLocationContent();
|
|
||||||
iTutorialSetText(
|
iTutorialSetText(
|
||||||
"This page lists all of the different locations you can currently " +
|
"This page lists all of the different locations you can currently " +
|
||||||
"travel to. Each location has something that you can do. " +
|
"travel to. Each location has something that you can do. " +
|
||||||
@ -399,7 +370,6 @@ function iTutorialEvaluateStep() {
|
|||||||
nextBtn.style.display = "none";
|
nextBtn.style.display = "none";
|
||||||
break;
|
break;
|
||||||
case iTutorialSteps.TutorialPageInfo:
|
case iTutorialSteps.TutorialPageInfo:
|
||||||
Engine.loadTutorialContent();
|
|
||||||
iTutorialSetText(
|
iTutorialSetText(
|
||||||
"This page contains a lot of different documentation about the game's " +
|
"This page contains a lot of different documentation about the game's " +
|
||||||
"content and mechanics. <strong style='background-color:#444;'> I know it's a lot, but I highly suggest you read " +
|
"content and mechanics. <strong style='background-color:#444;'> I know it's a lot, but I highly suggest you read " +
|
||||||
|
@ -3,418 +3,347 @@
|
|||||||
*
|
*
|
||||||
* This subcomponent renders all of the buttons for applying to jobs at a company
|
* This subcomponent renders all of the buttons for applying to jobs at a company
|
||||||
*/
|
*/
|
||||||
import * as React from "react";
|
import React, { useState } from "react";
|
||||||
|
|
||||||
import { ApplyToJobButton } from "./ApplyToJobButton";
|
import { ApplyToJobButton } from "./ApplyToJobButton";
|
||||||
|
|
||||||
import { Location } from "../Location";
|
|
||||||
import { Locations } from "../Locations";
|
import { Locations } from "../Locations";
|
||||||
import { LocationName } from "../data/LocationNames";
|
import { LocationName } from "../data/LocationNames";
|
||||||
|
|
||||||
import { IEngine } from "../../IEngine";
|
|
||||||
|
|
||||||
import { Companies } from "../../Company/Companies";
|
import { Companies } from "../../Company/Companies";
|
||||||
import { Company } from "../../Company/Company";
|
|
||||||
import { CompanyPosition } from "../../Company/CompanyPosition";
|
import { CompanyPosition } from "../../Company/CompanyPosition";
|
||||||
import { CompanyPositions } from "../../Company/CompanyPositions";
|
import { CompanyPositions } from "../../Company/CompanyPositions";
|
||||||
import * as posNames from "../../Company/data/companypositionnames";
|
import * as posNames from "../../Company/data/companypositionnames";
|
||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
|
||||||
|
|
||||||
import { StdButton } from "../../ui/React/StdButton";
|
import { StdButton } from "../../ui/React/StdButton";
|
||||||
import { Reputation } from "../../ui/React/Reputation";
|
import { Reputation } from "../../ui/React/Reputation";
|
||||||
import { Favor } from "../../ui/React/Favor";
|
import { Favor } from "../../ui/React/Favor";
|
||||||
import { createPopup } from "../../ui/React/createPopup";
|
import { createPopup } from "../../ui/React/createPopup";
|
||||||
|
import { use } from "../../ui/Context";
|
||||||
import { QuitJobPopup } from "../../Company/ui/QuitJobPopup";
|
import { QuitJobPopup } from "../../Company/ui/QuitJobPopup";
|
||||||
|
|
||||||
type IProps = {
|
type IProps = {
|
||||||
engine: IEngine;
|
|
||||||
locName: LocationName;
|
locName: LocationName;
|
||||||
p: IPlayer;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
type IState = {
|
export function CompanyLocation(props: IProps): React.ReactElement {
|
||||||
employedHere: boolean;
|
const p = use.Player();
|
||||||
};
|
const router = use.Router();
|
||||||
|
const setRerender = useState(false)[1];
|
||||||
const blockStyleMarkup = {
|
function rerender(): void {
|
||||||
display: "block",
|
setRerender((old) => !old);
|
||||||
};
|
}
|
||||||
|
|
||||||
export class CompanyLocation extends React.Component<IProps, IState> {
|
|
||||||
/**
|
/**
|
||||||
* We'll keep a reference to the Company that this component is being rendered for,
|
* We'll keep a reference to the Company that this component is being rendered for,
|
||||||
* so we don't have to look it up every time
|
* so we don't have to look it up every time
|
||||||
*/
|
*/
|
||||||
company: Company;
|
const company = Companies[props.locName];
|
||||||
|
if (company == null) throw new Error(`CompanyLocation component constructed with invalid company: ${props.locName}`);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reference to the Location that this component is being rendered for
|
||||||
|
*/
|
||||||
|
const location = Locations[props.locName];
|
||||||
|
if (location == null) {
|
||||||
|
throw new Error(`CompanyLocation component constructed with invalid location: ${props.locName}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Name of company position that player holds, if applicable
|
||||||
|
*/
|
||||||
|
const jobTitle = p.jobs[props.locName] ? p.jobs[props.locName] : null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CompanyPosition object for the job that the player holds at this company
|
* CompanyPosition object for the job that the player holds at this company
|
||||||
* (if he has one)
|
* (if he has one)
|
||||||
*/
|
*/
|
||||||
companyPosition: CompanyPosition | null = null;
|
const companyPosition = jobTitle ? CompanyPositions[jobTitle] : null;
|
||||||
|
|
||||||
/**
|
p.location = props.locName;
|
||||||
* Stores button styling that sets them all to block display
|
|
||||||
*/
|
|
||||||
btnStyle: any;
|
|
||||||
|
|
||||||
/**
|
function applyForAgentJob(e: React.MouseEvent<HTMLElement>): void {
|
||||||
* Reference to the Location that this component is being rendered for
|
|
||||||
*/
|
|
||||||
location: Location;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Name of company position that player holds, if applicable
|
|
||||||
*/
|
|
||||||
jobTitle: string | null = null;
|
|
||||||
|
|
||||||
constructor(props: IProps) {
|
|
||||||
super(props);
|
|
||||||
|
|
||||||
this.btnStyle = { display: "block" };
|
|
||||||
|
|
||||||
this.quit = this.quit.bind(this);
|
|
||||||
this.applyForAgentJob = this.applyForAgentJob.bind(this);
|
|
||||||
this.applyForBusinessConsultantJob = this.applyForBusinessConsultantJob.bind(this);
|
|
||||||
this.applyForBusinessJob = this.applyForBusinessJob.bind(this);
|
|
||||||
this.applyForEmployeeJob = this.applyForEmployeeJob.bind(this);
|
|
||||||
this.applyForItJob = this.applyForItJob.bind(this);
|
|
||||||
this.applyForPartTimeEmployeeJob = this.applyForPartTimeEmployeeJob.bind(this);
|
|
||||||
this.applyForPartTimeWaiterJob = this.applyForPartTimeWaiterJob.bind(this);
|
|
||||||
this.applyForSecurityJob = this.applyForSecurityJob.bind(this);
|
|
||||||
this.applyForSoftwareConsultantJob = this.applyForSoftwareConsultantJob.bind(this);
|
|
||||||
this.applyForSoftwareJob = this.applyForSoftwareJob.bind(this);
|
|
||||||
this.applyForWaiterJob = this.applyForWaiterJob.bind(this);
|
|
||||||
this.startInfiltration = this.startInfiltration.bind(this);
|
|
||||||
this.work = this.work.bind(this);
|
|
||||||
|
|
||||||
this.location = Locations[props.locName];
|
|
||||||
if (this.location == null) {
|
|
||||||
throw new Error(`CompanyLocation component constructed with invalid location: ${props.locName}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.company = Companies[props.locName];
|
|
||||||
if (this.company == null) {
|
|
||||||
throw new Error(`CompanyLocation component constructed with invalid company: ${props.locName}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.state = {
|
|
||||||
employedHere: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
this.props.p.location = props.locName;
|
|
||||||
|
|
||||||
this.checkIfEmployedHere(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
applyForAgentJob(e: React.MouseEvent<HTMLElement>): void {
|
|
||||||
if (!e.isTrusted) {
|
if (!e.isTrusted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.props.p.applyForAgentJob();
|
p.applyForAgentJob();
|
||||||
this.checkIfEmployedHere(true);
|
rerender();
|
||||||
}
|
}
|
||||||
|
|
||||||
applyForBusinessConsultantJob(e: React.MouseEvent<HTMLElement>): void {
|
function applyForBusinessConsultantJob(e: React.MouseEvent<HTMLElement>): void {
|
||||||
if (!e.isTrusted) {
|
if (!e.isTrusted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.props.p.applyForBusinessConsultantJob();
|
p.applyForBusinessConsultantJob();
|
||||||
this.checkIfEmployedHere(true);
|
rerender();
|
||||||
}
|
}
|
||||||
|
|
||||||
applyForBusinessJob(e: React.MouseEvent<HTMLElement>): void {
|
function applyForBusinessJob(e: React.MouseEvent<HTMLElement>): void {
|
||||||
if (!e.isTrusted) {
|
if (!e.isTrusted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.props.p.applyForBusinessJob();
|
p.applyForBusinessJob();
|
||||||
this.checkIfEmployedHere(true);
|
rerender();
|
||||||
}
|
}
|
||||||
|
|
||||||
applyForEmployeeJob(e: React.MouseEvent<HTMLElement>): void {
|
function applyForEmployeeJob(e: React.MouseEvent<HTMLElement>): void {
|
||||||
if (!e.isTrusted) {
|
if (!e.isTrusted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.props.p.applyForEmployeeJob();
|
p.applyForEmployeeJob();
|
||||||
this.checkIfEmployedHere(true);
|
rerender();
|
||||||
}
|
}
|
||||||
|
|
||||||
applyForItJob(e: React.MouseEvent<HTMLElement>): void {
|
function applyForItJob(e: React.MouseEvent<HTMLElement>): void {
|
||||||
if (!e.isTrusted) {
|
if (!e.isTrusted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.props.p.applyForItJob();
|
p.applyForItJob();
|
||||||
this.checkIfEmployedHere(true);
|
rerender();
|
||||||
}
|
}
|
||||||
|
|
||||||
applyForPartTimeEmployeeJob(e: React.MouseEvent<HTMLElement>): void {
|
function applyForPartTimeEmployeeJob(e: React.MouseEvent<HTMLElement>): void {
|
||||||
if (!e.isTrusted) {
|
if (!e.isTrusted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.props.p.applyForPartTimeEmployeeJob();
|
p.applyForPartTimeEmployeeJob();
|
||||||
this.checkIfEmployedHere(true);
|
rerender();
|
||||||
}
|
}
|
||||||
|
|
||||||
applyForPartTimeWaiterJob(e: React.MouseEvent<HTMLElement>): void {
|
function applyForPartTimeWaiterJob(e: React.MouseEvent<HTMLElement>): void {
|
||||||
if (!e.isTrusted) {
|
if (!e.isTrusted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.props.p.applyForPartTimeWaiterJob();
|
p.applyForPartTimeWaiterJob();
|
||||||
this.checkIfEmployedHere(true);
|
rerender();
|
||||||
}
|
}
|
||||||
|
|
||||||
applyForSecurityJob(e: React.MouseEvent<HTMLElement>): void {
|
function applyForSecurityJob(e: React.MouseEvent<HTMLElement>): void {
|
||||||
if (!e.isTrusted) {
|
if (!e.isTrusted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.props.p.applyForSecurityJob();
|
p.applyForSecurityJob();
|
||||||
this.checkIfEmployedHere(true);
|
rerender();
|
||||||
}
|
}
|
||||||
|
|
||||||
applyForSoftwareConsultantJob(e: React.MouseEvent<HTMLElement>): void {
|
function applyForSoftwareConsultantJob(e: React.MouseEvent<HTMLElement>): void {
|
||||||
if (!e.isTrusted) {
|
if (!e.isTrusted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.props.p.applyForSoftwareConsultantJob();
|
p.applyForSoftwareConsultantJob();
|
||||||
this.checkIfEmployedHere(true);
|
rerender();
|
||||||
}
|
}
|
||||||
|
|
||||||
applyForSoftwareJob(e: React.MouseEvent<HTMLElement>): void {
|
function applyForSoftwareJob(e: React.MouseEvent<HTMLElement>): void {
|
||||||
if (!e.isTrusted) {
|
if (!e.isTrusted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.props.p.applyForSoftwareJob();
|
p.applyForSoftwareJob();
|
||||||
this.checkIfEmployedHere(true);
|
rerender();
|
||||||
}
|
}
|
||||||
|
|
||||||
applyForWaiterJob(e: React.MouseEvent<HTMLElement>): void {
|
function applyForWaiterJob(e: React.MouseEvent<HTMLElement>): void {
|
||||||
if (!e.isTrusted) {
|
if (!e.isTrusted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.props.p.applyForWaiterJob();
|
p.applyForWaiterJob();
|
||||||
this.checkIfEmployedHere(true);
|
rerender();
|
||||||
}
|
}
|
||||||
|
|
||||||
checkIfEmployedHere(updateState = false): void {
|
function startInfiltration(e: React.MouseEvent<HTMLElement>): void {
|
||||||
this.jobTitle = this.props.p.jobs[this.props.locName];
|
|
||||||
if (this.jobTitle != null) {
|
|
||||||
this.companyPosition = CompanyPositions[this.jobTitle];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (updateState) {
|
|
||||||
this.setState({
|
|
||||||
employedHere: this.jobTitle != null,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
startInfiltration(e: React.MouseEvent<HTMLElement>): void {
|
|
||||||
if (!e.isTrusted) {
|
if (!e.isTrusted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const loc = this.location;
|
const loc = location;
|
||||||
if (!loc.infiltrationData) {
|
if (!loc.infiltrationData)
|
||||||
console.error(`trying to start infiltration at ${this.props.locName} but the infiltrationData is null`);
|
throw new Error(`trying to start infiltration at ${props.locName} but the infiltrationData is null`);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.props.engine.loadInfiltrationContent(
|
router.toInfiltration(props.locName);
|
||||||
this.props.locName,
|
|
||||||
loc.infiltrationData.startingSecurityLevel,
|
|
||||||
loc.infiltrationData.maxClearanceLevel,
|
|
||||||
);
|
|
||||||
|
|
||||||
const data = loc.infiltrationData;
|
|
||||||
if (data == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
work(e: React.MouseEvent<HTMLElement>): void {
|
function work(e: React.MouseEvent<HTMLElement>): void {
|
||||||
if (!e.isTrusted) {
|
if (!e.isTrusted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const pos = this.companyPosition;
|
const pos = companyPosition;
|
||||||
if (pos instanceof CompanyPosition) {
|
if (pos instanceof CompanyPosition) {
|
||||||
if (pos.isPartTimeJob() || pos.isSoftwareConsultantJob() || pos.isBusinessConsultantJob()) {
|
if (pos.isPartTimeJob() || pos.isSoftwareConsultantJob() || pos.isBusinessConsultantJob()) {
|
||||||
this.props.p.startWorkPartTime(this.props.locName);
|
p.startWorkPartTime(props.locName);
|
||||||
} else {
|
} else {
|
||||||
this.props.p.startWork(this.props.locName);
|
p.startWork(props.locName);
|
||||||
}
|
}
|
||||||
|
router.toWork();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
quit(e: React.MouseEvent<HTMLElement>): void {
|
function quit(e: React.MouseEvent<HTMLElement>): void {
|
||||||
if (!e.isTrusted) return;
|
if (!e.isTrusted) return;
|
||||||
const popupId = `quit-job-popup`;
|
const popupId = `quit-job-popup`;
|
||||||
createPopup(popupId, QuitJobPopup, {
|
createPopup(popupId, QuitJobPopup, {
|
||||||
locName: this.props.locName,
|
locName: props.locName,
|
||||||
company: this.company,
|
company: company,
|
||||||
player: this.props.p,
|
player: p,
|
||||||
onQuit: () => this.checkIfEmployedHere(true),
|
onQuit: rerender,
|
||||||
popupId: popupId,
|
popupId: popupId,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
render(): React.ReactNode {
|
const isEmployedHere = jobTitle != null;
|
||||||
const isEmployedHere = this.jobTitle != null;
|
const favorGain = company.getFavorGain();
|
||||||
const favorGain = this.company.getFavorGain();
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{isEmployedHere && (
|
{isEmployedHere && (
|
||||||
<div>
|
<div>
|
||||||
<p>Job Title: {this.jobTitle}</p>
|
<p>Job Title: {jobTitle}</p>
|
||||||
<br />
|
<br />
|
||||||
<p style={blockStyleMarkup}>-------------------------</p>
|
<p style={{ display: "block" }}>-------------------------</p>
|
||||||
<br />
|
<br />
|
||||||
<p className={"tooltip"}>
|
<p className={"tooltip"}>
|
||||||
Company reputation: {Reputation(this.company.playerReputation)}
|
Company reputation: {Reputation(company.playerReputation)}
|
||||||
<span className={"tooltiptext"}>
|
<span className={"tooltiptext"}>
|
||||||
You will earn {Favor(favorGain[0])} company favor upon resetting after installing Augmentations
|
You will earn {Favor(favorGain[0])} company favor upon resetting after installing Augmentations
|
||||||
</span>
|
</span>
|
||||||
</p>
|
</p>
|
||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
<p style={blockStyleMarkup}>-------------------------</p>
|
<p style={{ display: "block" }}>-------------------------</p>
|
||||||
<br />
|
<br />
|
||||||
<p className={"tooltip"}>
|
<p className={"tooltip"}>
|
||||||
Company Favor: {Favor(this.company.favor)}
|
Company Favor: {Favor(company.favor)}
|
||||||
<span className={"tooltiptext"}>
|
<span className={"tooltiptext"}>
|
||||||
Company favor increases the rate at which you earn reputation for this company by 1% per favor. Company
|
Company favor increases the rate at which you earn reputation for this company by 1% per favor. Company
|
||||||
favor is gained whenever you reset after installing Augmentations. The amount of favor you gain depends
|
favor is gained whenever you reset after installing Augmentations. The amount of favor you gain depends on
|
||||||
on how much reputation you have with the comapny.
|
how much reputation you have with the comapny.
|
||||||
</span>
|
</span>
|
||||||
</p>
|
</p>
|
||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
<p style={blockStyleMarkup}>-------------------------</p>
|
<p style={{ display: "block" }}>-------------------------</p>
|
||||||
<br />
|
<br />
|
||||||
<StdButton onClick={this.work} text={"Work"} />
|
<StdButton onClick={work} text={"Work"} />
|
||||||
|
|
||||||
<StdButton onClick={this.quit} text={"Quit"} />
|
<StdButton onClick={quit} text={"Quit"} />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{this.company.hasAgentPositions() && (
|
{company.hasAgentPositions() && (
|
||||||
<ApplyToJobButton
|
<ApplyToJobButton
|
||||||
company={this.company}
|
company={company}
|
||||||
entryPosType={CompanyPositions[posNames.AgentCompanyPositions[0]]}
|
entryPosType={CompanyPositions[posNames.AgentCompanyPositions[0]]}
|
||||||
onClick={this.applyForAgentJob}
|
onClick={applyForAgentJob}
|
||||||
p={this.props.p}
|
p={p}
|
||||||
style={this.btnStyle}
|
style={{ display: "block" }}
|
||||||
text={"Apply for Agent Job"}
|
text={"Apply for Agent Job"}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{this.company.hasBusinessConsultantPositions() && (
|
{company.hasBusinessConsultantPositions() && (
|
||||||
<ApplyToJobButton
|
<ApplyToJobButton
|
||||||
company={this.company}
|
company={company}
|
||||||
entryPosType={CompanyPositions[posNames.BusinessConsultantCompanyPositions[0]]}
|
entryPosType={CompanyPositions[posNames.BusinessConsultantCompanyPositions[0]]}
|
||||||
onClick={this.applyForBusinessConsultantJob}
|
onClick={applyForBusinessConsultantJob}
|
||||||
p={this.props.p}
|
p={p}
|
||||||
style={this.btnStyle}
|
style={{ display: "block" }}
|
||||||
text={"Apply for Business Consultant Job"}
|
text={"Apply for Business Consultant Job"}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{this.company.hasBusinessPositions() && (
|
{company.hasBusinessPositions() && (
|
||||||
<ApplyToJobButton
|
<ApplyToJobButton
|
||||||
company={this.company}
|
company={company}
|
||||||
entryPosType={CompanyPositions[posNames.BusinessCompanyPositions[0]]}
|
entryPosType={CompanyPositions[posNames.BusinessCompanyPositions[0]]}
|
||||||
onClick={this.applyForBusinessJob}
|
onClick={applyForBusinessJob}
|
||||||
p={this.props.p}
|
p={p}
|
||||||
style={this.btnStyle}
|
style={{ display: "block" }}
|
||||||
text={"Apply for Business Job"}
|
text={"Apply for Business Job"}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{this.company.hasEmployeePositions() && (
|
{company.hasEmployeePositions() && (
|
||||||
<ApplyToJobButton
|
<ApplyToJobButton
|
||||||
company={this.company}
|
company={company}
|
||||||
entryPosType={CompanyPositions[posNames.MiscCompanyPositions[1]]}
|
entryPosType={CompanyPositions[posNames.MiscCompanyPositions[1]]}
|
||||||
onClick={this.applyForEmployeeJob}
|
onClick={applyForEmployeeJob}
|
||||||
p={this.props.p}
|
p={p}
|
||||||
style={this.btnStyle}
|
style={{ display: "block" }}
|
||||||
text={"Apply to be an Employee"}
|
text={"Apply to be an Employee"}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{this.company.hasEmployeePositions() && (
|
{company.hasEmployeePositions() && (
|
||||||
<ApplyToJobButton
|
<ApplyToJobButton
|
||||||
company={this.company}
|
company={company}
|
||||||
entryPosType={CompanyPositions[posNames.PartTimeCompanyPositions[1]]}
|
entryPosType={CompanyPositions[posNames.PartTimeCompanyPositions[1]]}
|
||||||
onClick={this.applyForPartTimeEmployeeJob}
|
onClick={applyForPartTimeEmployeeJob}
|
||||||
p={this.props.p}
|
p={p}
|
||||||
style={this.btnStyle}
|
style={{ display: "block" }}
|
||||||
text={"Apply to be a part-time Employee"}
|
text={"Apply to be a part-time Employee"}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{this.company.hasITPositions() && (
|
{company.hasITPositions() && (
|
||||||
<ApplyToJobButton
|
<ApplyToJobButton
|
||||||
company={this.company}
|
company={company}
|
||||||
entryPosType={CompanyPositions[posNames.ITCompanyPositions[0]]}
|
entryPosType={CompanyPositions[posNames.ITCompanyPositions[0]]}
|
||||||
onClick={this.applyForItJob}
|
onClick={applyForItJob}
|
||||||
p={this.props.p}
|
p={p}
|
||||||
style={this.btnStyle}
|
style={{ display: "block" }}
|
||||||
text={"Apply for IT Job"}
|
text={"Apply for IT Job"}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{this.company.hasSecurityPositions() && (
|
{company.hasSecurityPositions() && (
|
||||||
<ApplyToJobButton
|
<ApplyToJobButton
|
||||||
company={this.company}
|
company={company}
|
||||||
entryPosType={CompanyPositions[posNames.SecurityCompanyPositions[2]]}
|
entryPosType={CompanyPositions[posNames.SecurityCompanyPositions[2]]}
|
||||||
onClick={this.applyForSecurityJob}
|
onClick={applyForSecurityJob}
|
||||||
p={this.props.p}
|
p={p}
|
||||||
style={this.btnStyle}
|
style={{ display: "block" }}
|
||||||
text={"Apply for Security Job"}
|
text={"Apply for Security Job"}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{this.company.hasSoftwareConsultantPositions() && (
|
{company.hasSoftwareConsultantPositions() && (
|
||||||
<ApplyToJobButton
|
<ApplyToJobButton
|
||||||
company={this.company}
|
company={company}
|
||||||
entryPosType={CompanyPositions[posNames.SoftwareConsultantCompanyPositions[0]]}
|
entryPosType={CompanyPositions[posNames.SoftwareConsultantCompanyPositions[0]]}
|
||||||
onClick={this.applyForSoftwareConsultantJob}
|
onClick={applyForSoftwareConsultantJob}
|
||||||
p={this.props.p}
|
p={p}
|
||||||
style={this.btnStyle}
|
style={{ display: "block" }}
|
||||||
text={"Apply for Software Consultant Job"}
|
text={"Apply for Software Consultant Job"}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{this.company.hasSoftwarePositions() && (
|
{company.hasSoftwarePositions() && (
|
||||||
<ApplyToJobButton
|
<ApplyToJobButton
|
||||||
company={this.company}
|
company={company}
|
||||||
entryPosType={CompanyPositions[posNames.SoftwareCompanyPositions[0]]}
|
entryPosType={CompanyPositions[posNames.SoftwareCompanyPositions[0]]}
|
||||||
onClick={this.applyForSoftwareJob}
|
onClick={applyForSoftwareJob}
|
||||||
p={this.props.p}
|
p={p}
|
||||||
style={this.btnStyle}
|
style={{ display: "block" }}
|
||||||
text={"Apply for Software Job"}
|
text={"Apply for Software Job"}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{this.company.hasWaiterPositions() && (
|
{company.hasWaiterPositions() && (
|
||||||
<ApplyToJobButton
|
<ApplyToJobButton
|
||||||
company={this.company}
|
company={company}
|
||||||
entryPosType={CompanyPositions[posNames.MiscCompanyPositions[0]]}
|
entryPosType={CompanyPositions[posNames.MiscCompanyPositions[0]]}
|
||||||
onClick={this.applyForWaiterJob}
|
onClick={applyForWaiterJob}
|
||||||
p={this.props.p}
|
p={p}
|
||||||
style={this.btnStyle}
|
style={{ display: "block" }}
|
||||||
text={"Apply to be a Waiter"}
|
text={"Apply to be a Waiter"}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{this.company.hasWaiterPositions() && (
|
{company.hasWaiterPositions() && (
|
||||||
<ApplyToJobButton
|
<ApplyToJobButton
|
||||||
company={this.company}
|
company={company}
|
||||||
entryPosType={CompanyPositions[posNames.PartTimeCompanyPositions[0]]}
|
entryPosType={CompanyPositions[posNames.PartTimeCompanyPositions[0]]}
|
||||||
onClick={this.applyForPartTimeWaiterJob}
|
onClick={applyForPartTimeWaiterJob}
|
||||||
p={this.props.p}
|
p={p}
|
||||||
style={this.btnStyle}
|
style={{ display: "block" }}
|
||||||
text={"Apply to be a part-time Waiter"}
|
text={"Apply to be a part-time Waiter"}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{this.location.infiltrationData != null && (
|
{location.infiltrationData != null && (
|
||||||
<StdButton onClick={this.startInfiltration} style={this.btnStyle} text={"Infiltrate Company"} />
|
<StdButton onClick={startInfiltration} style={{ display: "block" }} text={"Infiltrate Company"} />
|
||||||
)}
|
)}
|
||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ import { HospitalLocation } from "./HospitalLocation";
|
|||||||
import { SlumsLocation } from "./SlumsLocation";
|
import { SlumsLocation } from "./SlumsLocation";
|
||||||
import { SpecialLocation } from "./SpecialLocation";
|
import { SpecialLocation } from "./SpecialLocation";
|
||||||
import { TechVendorLocation } from "./TechVendorLocation";
|
import { TechVendorLocation } from "./TechVendorLocation";
|
||||||
import { TravelAgencyLocation } from "./TravelAgencyLocation";
|
import { TravelAgencyRoot } from "./TravelAgencyRoot";
|
||||||
import { UniversityLocation } from "./UniversityLocation";
|
import { UniversityLocation } from "./UniversityLocation";
|
||||||
import { CasinoLocation } from "./CasinoLocation";
|
import { CasinoLocation } from "./CasinoLocation";
|
||||||
|
|
||||||
@ -21,6 +21,7 @@ import { LocationType } from "../LocationTypeEnum";
|
|||||||
import { CityName } from "../data/CityNames";
|
import { CityName } from "../data/CityNames";
|
||||||
|
|
||||||
import { IEngine } from "../../IEngine";
|
import { IEngine } from "../../IEngine";
|
||||||
|
import { IRouter } from "../../ui/Router";
|
||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||||
import { Settings } from "../../Settings/Settings";
|
import { Settings } from "../../Settings/Settings";
|
||||||
|
|
||||||
@ -32,6 +33,7 @@ import { CorruptableText } from "../../ui/React/CorruptableText";
|
|||||||
|
|
||||||
type IProps = {
|
type IProps = {
|
||||||
engine: IEngine;
|
engine: IEngine;
|
||||||
|
router: IRouter;
|
||||||
loc: Location;
|
loc: Location;
|
||||||
p: IPlayer;
|
p: IPlayer;
|
||||||
returnToCity: () => void;
|
returnToCity: () => void;
|
||||||
@ -58,14 +60,7 @@ export class GenericLocation extends React.Component<IProps, any> {
|
|||||||
const content: React.ReactNode[] = [];
|
const content: React.ReactNode[] = [];
|
||||||
|
|
||||||
if (this.props.loc.types.includes(LocationType.Company)) {
|
if (this.props.loc.types.includes(LocationType.Company)) {
|
||||||
content.push(
|
content.push(<CompanyLocation key={"companylocation"} locName={this.props.loc.name} />);
|
||||||
<CompanyLocation
|
|
||||||
engine={this.props.engine}
|
|
||||||
key={"companylocation"}
|
|
||||||
locName={this.props.loc.name}
|
|
||||||
p={this.props.p}
|
|
||||||
/>,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.props.loc.types.includes(LocationType.Gym)) {
|
if (this.props.loc.types.includes(LocationType.Gym)) {
|
||||||
@ -77,7 +72,7 @@ export class GenericLocation extends React.Component<IProps, any> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this.props.loc.types.includes(LocationType.Slums)) {
|
if (this.props.loc.types.includes(LocationType.Slums)) {
|
||||||
content.push(<SlumsLocation key={"slumslocation"} p={this.props.p} />);
|
content.push(<SlumsLocation key={"slumslocation"} />);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.props.loc.types.includes(LocationType.Special)) {
|
if (this.props.loc.types.includes(LocationType.Special)) {
|
||||||
@ -91,11 +86,11 @@ export class GenericLocation extends React.Component<IProps, any> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this.props.loc.types.includes(LocationType.TravelAgency)) {
|
if (this.props.loc.types.includes(LocationType.TravelAgency)) {
|
||||||
content.push(<TravelAgencyLocation key={"travelagencylocation"} p={this.props.p} travel={this.props.travel} />);
|
content.push(<TravelAgencyRoot key={"travelagencylocation"} p={this.props.p} router={this.props.router} />);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.props.loc.types.includes(LocationType.University)) {
|
if (this.props.loc.types.includes(LocationType.University)) {
|
||||||
content.push(<UniversityLocation key={"universitylocation"} loc={this.props.loc} p={this.props.p} />);
|
content.push(<UniversityLocation key={"universitylocation"} loc={this.props.loc} />);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.props.loc.types.includes(LocationType.Casino)) {
|
if (this.props.loc.types.includes(LocationType.Casino)) {
|
||||||
|
@ -15,6 +15,7 @@ import { LocationName } from "../data/LocationNames";
|
|||||||
|
|
||||||
import { CONSTANTS } from "../../Constants";
|
import { CONSTANTS } from "../../Constants";
|
||||||
import { IEngine } from "../../IEngine";
|
import { IEngine } from "../../IEngine";
|
||||||
|
import { IRouter } from "../../ui/Router";
|
||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||||
|
|
||||||
import { dialogBoxCreate } from "../../../utils/DialogBox";
|
import { dialogBoxCreate } from "../../../utils/DialogBox";
|
||||||
@ -22,6 +23,7 @@ import { dialogBoxCreate } from "../../../utils/DialogBox";
|
|||||||
type IProps = {
|
type IProps = {
|
||||||
initiallyInCity?: boolean;
|
initiallyInCity?: boolean;
|
||||||
engine: IEngine;
|
engine: IEngine;
|
||||||
|
router: IRouter;
|
||||||
p: IPlayer;
|
p: IPlayer;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -47,6 +49,10 @@ export class LocationRoot extends React.Component<IProps, IState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
enterLocation(to: LocationName): void {
|
enterLocation(to: LocationName): void {
|
||||||
|
if (to == LocationName.TravelAgency) {
|
||||||
|
this.props.router.toTravel();
|
||||||
|
return;
|
||||||
|
}
|
||||||
this.props.p.gotoLocation(to);
|
this.props.p.gotoLocation(to);
|
||||||
this.setState({
|
this.setState({
|
||||||
inCity: false,
|
inCity: false,
|
||||||
@ -98,6 +104,7 @@ export class LocationRoot extends React.Component<IProps, IState> {
|
|||||||
return (
|
return (
|
||||||
<GenericLocation
|
<GenericLocation
|
||||||
engine={this.props.engine}
|
engine={this.props.engine}
|
||||||
|
router={this.props.router}
|
||||||
loc={loc}
|
loc={loc}
|
||||||
p={this.props.p}
|
p={this.props.p}
|
||||||
returnToCity={this.returnToCity}
|
returnToCity={this.returnToCity}
|
||||||
|
@ -6,225 +6,209 @@
|
|||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
|
|
||||||
import { Crimes } from "../../Crime/Crimes";
|
import { Crimes } from "../../Crime/Crimes";
|
||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
|
||||||
|
|
||||||
import { numeralWrapper } from "../../ui/numeralFormat";
|
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||||
import { AutoupdatingStdButton } from "../../ui/React/AutoupdatingStdButton";
|
import { AutoupdatingStdButton } from "../../ui/React/AutoupdatingStdButton";
|
||||||
|
import { use } from "../../ui/Context";
|
||||||
|
|
||||||
type IProps = {
|
export function SlumsLocation(): React.ReactElement {
|
||||||
p: IPlayer;
|
const player = use.Player();
|
||||||
};
|
const router = use.Router();
|
||||||
|
function shoplift(e: React.MouseEvent<HTMLElement>): void {
|
||||||
export class SlumsLocation extends React.Component<IProps, any> {
|
|
||||||
/**
|
|
||||||
* Stores button styling that sets them all to block display
|
|
||||||
*/
|
|
||||||
btnStyle: any;
|
|
||||||
|
|
||||||
constructor(props: IProps) {
|
|
||||||
super(props);
|
|
||||||
|
|
||||||
this.btnStyle = { display: "block" };
|
|
||||||
|
|
||||||
this.shoplift = this.shoplift.bind(this);
|
|
||||||
this.robStore = this.robStore.bind(this);
|
|
||||||
this.mug = this.mug.bind(this);
|
|
||||||
this.larceny = this.larceny.bind(this);
|
|
||||||
this.dealDrugs = this.dealDrugs.bind(this);
|
|
||||||
this.bondForgery = this.bondForgery.bind(this);
|
|
||||||
this.traffickArms = this.traffickArms.bind(this);
|
|
||||||
this.homicide = this.homicide.bind(this);
|
|
||||||
this.grandTheftAuto = this.grandTheftAuto.bind(this);
|
|
||||||
this.kidnap = this.kidnap.bind(this);
|
|
||||||
this.assassinate = this.assassinate.bind(this);
|
|
||||||
this.heist = this.heist.bind(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
shoplift(e: React.MouseEvent<HTMLElement>): void {
|
|
||||||
if (!e.isTrusted) {
|
if (!e.isTrusted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Crimes.Shoplift.commit(this.props.p);
|
Crimes.Shoplift.commit(player);
|
||||||
|
router.toWork();
|
||||||
}
|
}
|
||||||
|
|
||||||
robStore(e: React.MouseEvent<HTMLElement>): void {
|
function robStore(e: React.MouseEvent<HTMLElement>): void {
|
||||||
if (!e.isTrusted) {
|
if (!e.isTrusted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Crimes.RobStore.commit(this.props.p);
|
Crimes.RobStore.commit(player);
|
||||||
|
router.toWork();
|
||||||
}
|
}
|
||||||
|
|
||||||
mug(e: React.MouseEvent<HTMLElement>): void {
|
function mug(e: React.MouseEvent<HTMLElement>): void {
|
||||||
if (!e.isTrusted) {
|
if (!e.isTrusted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Crimes.Mug.commit(this.props.p);
|
Crimes.Mug.commit(player);
|
||||||
|
router.toWork();
|
||||||
}
|
}
|
||||||
|
|
||||||
larceny(e: React.MouseEvent<HTMLElement>): void {
|
function larceny(e: React.MouseEvent<HTMLElement>): void {
|
||||||
if (!e.isTrusted) {
|
if (!e.isTrusted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Crimes.Larceny.commit(this.props.p);
|
Crimes.Larceny.commit(player);
|
||||||
|
router.toWork();
|
||||||
}
|
}
|
||||||
|
|
||||||
dealDrugs(e: React.MouseEvent<HTMLElement>): void {
|
function dealDrugs(e: React.MouseEvent<HTMLElement>): void {
|
||||||
if (!e.isTrusted) {
|
if (!e.isTrusted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Crimes.DealDrugs.commit(this.props.p);
|
Crimes.DealDrugs.commit(player);
|
||||||
|
router.toWork();
|
||||||
}
|
}
|
||||||
|
|
||||||
bondForgery(e: React.MouseEvent<HTMLElement>): void {
|
function bondForgery(e: React.MouseEvent<HTMLElement>): void {
|
||||||
if (!e.isTrusted) {
|
if (!e.isTrusted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Crimes.BondForgery.commit(this.props.p);
|
Crimes.BondForgery.commit(player);
|
||||||
|
router.toWork();
|
||||||
}
|
}
|
||||||
|
|
||||||
traffickArms(e: React.MouseEvent<HTMLElement>): void {
|
function traffickArms(e: React.MouseEvent<HTMLElement>): void {
|
||||||
if (!e.isTrusted) {
|
if (!e.isTrusted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Crimes.TraffickArms.commit(this.props.p);
|
Crimes.TraffickArms.commit(player);
|
||||||
|
router.toWork();
|
||||||
}
|
}
|
||||||
|
|
||||||
homicide(e: React.MouseEvent<HTMLElement>): void {
|
function homicide(e: React.MouseEvent<HTMLElement>): void {
|
||||||
if (!e.isTrusted) {
|
if (!e.isTrusted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Crimes.Homicide.commit(this.props.p);
|
Crimes.Homicide.commit(player);
|
||||||
|
router.toWork();
|
||||||
}
|
}
|
||||||
|
|
||||||
grandTheftAuto(e: React.MouseEvent<HTMLElement>): void {
|
function grandTheftAuto(e: React.MouseEvent<HTMLElement>): void {
|
||||||
if (!e.isTrusted) {
|
if (!e.isTrusted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Crimes.GrandTheftAuto.commit(this.props.p);
|
Crimes.GrandTheftAuto.commit(player);
|
||||||
|
router.toWork();
|
||||||
}
|
}
|
||||||
|
|
||||||
kidnap(e: React.MouseEvent<HTMLElement>): void {
|
function kidnap(e: React.MouseEvent<HTMLElement>): void {
|
||||||
if (!e.isTrusted) {
|
if (!e.isTrusted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Crimes.Kidnap.commit(this.props.p);
|
Crimes.Kidnap.commit(player);
|
||||||
|
router.toWork();
|
||||||
}
|
}
|
||||||
|
|
||||||
assassinate(e: React.MouseEvent<HTMLElement>): void {
|
function assassinate(e: React.MouseEvent<HTMLElement>): void {
|
||||||
if (!e.isTrusted) {
|
if (!e.isTrusted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Crimes.Assassination.commit(this.props.p);
|
Crimes.Assassination.commit(player);
|
||||||
|
router.toWork();
|
||||||
}
|
}
|
||||||
|
|
||||||
heist(e: React.MouseEvent<HTMLElement>): void {
|
function heist(e: React.MouseEvent<HTMLElement>): void {
|
||||||
if (!e.isTrusted) {
|
if (!e.isTrusted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Crimes.Heist.commit(this.props.p);
|
Crimes.Heist.commit(player);
|
||||||
|
router.toWork();
|
||||||
}
|
}
|
||||||
|
|
||||||
render(): React.ReactNode {
|
const shopliftChance = Crimes.Shoplift.successRate(player);
|
||||||
const shopliftChance = Crimes.Shoplift.successRate(this.props.p);
|
const robStoreChance = Crimes.RobStore.successRate(player);
|
||||||
const robStoreChance = Crimes.RobStore.successRate(this.props.p);
|
const mugChance = Crimes.Mug.successRate(player);
|
||||||
const mugChance = Crimes.Mug.successRate(this.props.p);
|
const larcenyChance = Crimes.Larceny.successRate(player);
|
||||||
const larcenyChance = Crimes.Larceny.successRate(this.props.p);
|
const drugsChance = Crimes.DealDrugs.successRate(player);
|
||||||
const drugsChance = Crimes.DealDrugs.successRate(this.props.p);
|
const bondChance = Crimes.BondForgery.successRate(player);
|
||||||
const bondChance = Crimes.BondForgery.successRate(this.props.p);
|
const armsChance = Crimes.TraffickArms.successRate(player);
|
||||||
const armsChance = Crimes.TraffickArms.successRate(this.props.p);
|
const homicideChance = Crimes.Homicide.successRate(player);
|
||||||
const homicideChance = Crimes.Homicide.successRate(this.props.p);
|
const gtaChance = Crimes.GrandTheftAuto.successRate(player);
|
||||||
const gtaChance = Crimes.GrandTheftAuto.successRate(this.props.p);
|
const kidnapChance = Crimes.Kidnap.successRate(player);
|
||||||
const kidnapChance = Crimes.Kidnap.successRate(this.props.p);
|
const assassinateChance = Crimes.Assassination.successRate(player);
|
||||||
const assassinateChance = Crimes.Assassination.successRate(this.props.p);
|
const heistChance = Crimes.Heist.successRate(player);
|
||||||
const heistChance = Crimes.Heist.successRate(this.props.p);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<AutoupdatingStdButton
|
<AutoupdatingStdButton
|
||||||
intervalTime={5e3}
|
intervalTime={5e3}
|
||||||
onClick={this.shoplift}
|
onClick={shoplift}
|
||||||
style={this.btnStyle}
|
style={{ display: "block" }}
|
||||||
text={`Shoplift (${numeralWrapper.formatPercentage(shopliftChance)} chance of success)`}
|
text={`Shoplift (${numeralWrapper.formatPercentage(shopliftChance)} chance of success)`}
|
||||||
tooltip={"Attempt to shoplift from a low-end retailer"}
|
tooltip={"Attempt to shoplift from a low-end retailer"}
|
||||||
/>
|
/>
|
||||||
<AutoupdatingStdButton
|
<AutoupdatingStdButton
|
||||||
intervalTime={5e3}
|
intervalTime={5e3}
|
||||||
onClick={this.robStore}
|
onClick={robStore}
|
||||||
style={this.btnStyle}
|
style={{ display: "block" }}
|
||||||
text={`Rob store (${numeralWrapper.formatPercentage(robStoreChance)} chance of success)`}
|
text={`Rob store (${numeralWrapper.formatPercentage(robStoreChance)} chance of success)`}
|
||||||
tooltip={"Attempt to commit armed robbery on a high-end store"}
|
tooltip={"Attempt to commit armed robbery on a high-end store"}
|
||||||
/>
|
/>
|
||||||
<AutoupdatingStdButton
|
<AutoupdatingStdButton
|
||||||
intervalTime={5e3}
|
intervalTime={5e3}
|
||||||
onClick={this.mug}
|
onClick={mug}
|
||||||
style={this.btnStyle}
|
style={{ display: "block" }}
|
||||||
text={`Mug someone (${numeralWrapper.formatPercentage(mugChance)} chance of success)`}
|
text={`Mug someone (${numeralWrapper.formatPercentage(mugChance)} chance of success)`}
|
||||||
tooltip={"Attempt to mug a random person on the street"}
|
tooltip={"Attempt to mug a random person on the street"}
|
||||||
/>
|
/>
|
||||||
<AutoupdatingStdButton
|
<AutoupdatingStdButton
|
||||||
intervalTime={5e3}
|
intervalTime={5e3}
|
||||||
onClick={this.larceny}
|
onClick={larceny}
|
||||||
style={this.btnStyle}
|
style={{ display: "block" }}
|
||||||
text={`Larceny (${numeralWrapper.formatPercentage(larcenyChance)} chance of success)`}
|
text={`Larceny (${numeralWrapper.formatPercentage(larcenyChance)} chance of success)`}
|
||||||
tooltip={"Attempt to rob property from someone's house"}
|
tooltip={"Attempt to rob property from someone's house"}
|
||||||
/>
|
/>
|
||||||
<AutoupdatingStdButton
|
<AutoupdatingStdButton
|
||||||
intervalTime={5e3}
|
intervalTime={5e3}
|
||||||
onClick={this.dealDrugs}
|
onClick={dealDrugs}
|
||||||
style={this.btnStyle}
|
style={{ display: "block" }}
|
||||||
text={`Deal Drugs (${numeralWrapper.formatPercentage(drugsChance)} chance of success)`}
|
text={`Deal Drugs (${numeralWrapper.formatPercentage(drugsChance)} chance of success)`}
|
||||||
tooltip={"Attempt to deal drugs"}
|
tooltip={"Attempt to deal drugs"}
|
||||||
/>
|
/>
|
||||||
<AutoupdatingStdButton
|
<AutoupdatingStdButton
|
||||||
intervalTime={5e3}
|
intervalTime={5e3}
|
||||||
onClick={this.bondForgery}
|
onClick={bondForgery}
|
||||||
style={this.btnStyle}
|
style={{ display: "block" }}
|
||||||
text={`Bond Forgery (${numeralWrapper.formatPercentage(bondChance)} chance of success)`}
|
text={`Bond Forgery (${numeralWrapper.formatPercentage(bondChance)} chance of success)`}
|
||||||
tooltip={"Attempt to forge corporate bonds"}
|
tooltip={"Attempt to forge corporate bonds"}
|
||||||
/>
|
/>
|
||||||
<AutoupdatingStdButton
|
<AutoupdatingStdButton
|
||||||
intervalTime={5e3}
|
intervalTime={5e3}
|
||||||
onClick={this.traffickArms}
|
onClick={traffickArms}
|
||||||
style={this.btnStyle}
|
style={{ display: "block" }}
|
||||||
text={`Traffick illegal Arms (${numeralWrapper.formatPercentage(armsChance)} chance of success)`}
|
text={`Traffick illegal Arms (${numeralWrapper.formatPercentage(armsChance)} chance of success)`}
|
||||||
tooltip={"Attempt to smuggle illegal arms into the city"}
|
tooltip={"Attempt to smuggle illegal arms into the city"}
|
||||||
/>
|
/>
|
||||||
<AutoupdatingStdButton
|
<AutoupdatingStdButton
|
||||||
intervalTime={5e3}
|
intervalTime={5e3}
|
||||||
onClick={this.homicide}
|
onClick={homicide}
|
||||||
style={this.btnStyle}
|
style={{ display: "block" }}
|
||||||
text={`Homicide (${numeralWrapper.formatPercentage(homicideChance)} chance of success)`}
|
text={`Homicide (${numeralWrapper.formatPercentage(homicideChance)} chance of success)`}
|
||||||
tooltip={"Attempt to murder a random person on the street"}
|
tooltip={"Attempt to murder a random person on the street"}
|
||||||
/>
|
/>
|
||||||
<AutoupdatingStdButton
|
<AutoupdatingStdButton
|
||||||
intervalTime={5e3}
|
intervalTime={5e3}
|
||||||
onClick={this.grandTheftAuto}
|
onClick={grandTheftAuto}
|
||||||
style={this.btnStyle}
|
style={{ display: "block" }}
|
||||||
text={`Grand theft Auto (${numeralWrapper.formatPercentage(gtaChance)} chance of success)`}
|
text={`Grand theft Auto (${numeralWrapper.formatPercentage(gtaChance)} chance of success)`}
|
||||||
tooltip={"Attempt to commit grand theft auto"}
|
tooltip={"Attempt to commit grand theft auto"}
|
||||||
/>
|
/>
|
||||||
<AutoupdatingStdButton
|
<AutoupdatingStdButton
|
||||||
intervalTime={5e3}
|
intervalTime={5e3}
|
||||||
onClick={this.kidnap}
|
onClick={kidnap}
|
||||||
style={this.btnStyle}
|
style={{ display: "block" }}
|
||||||
text={`Kidnap and Ransom (${numeralWrapper.formatPercentage(kidnapChance)} chance of success)`}
|
text={`Kidnap and Ransom (${numeralWrapper.formatPercentage(kidnapChance)} chance of success)`}
|
||||||
tooltip={"Attempt to kidnap and ransom a high-profile-target"}
|
tooltip={"Attempt to kidnap and ransom a high-profile-target"}
|
||||||
/>
|
/>
|
||||||
<AutoupdatingStdButton
|
<AutoupdatingStdButton
|
||||||
intervalTime={5e3}
|
intervalTime={5e3}
|
||||||
onClick={this.assassinate}
|
onClick={assassinate}
|
||||||
style={this.btnStyle}
|
style={{ display: "block" }}
|
||||||
text={`Assassinate (${numeralWrapper.formatPercentage(assassinateChance)} chance of success)`}
|
text={`Assassinate (${numeralWrapper.formatPercentage(assassinateChance)} chance of success)`}
|
||||||
tooltip={"Attempt to assassinate a high-profile target"}
|
tooltip={"Attempt to assassinate a high-profile target"}
|
||||||
/>
|
/>
|
||||||
<AutoupdatingStdButton
|
<AutoupdatingStdButton
|
||||||
intervalTime={5e3}
|
intervalTime={5e3}
|
||||||
onClick={this.heist}
|
onClick={heist}
|
||||||
style={this.btnStyle}
|
style={{ display: "block" }}
|
||||||
text={`Heist (${numeralWrapper.formatPercentage(heistChance)} chance of success)`}
|
text={`Heist (${numeralWrapper.formatPercentage(heistChance)} chance of success)`}
|
||||||
tooltip={"Attempt to pull off the ultimate heist"}
|
tooltip={"Attempt to pull off the ultimate heist"}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -10,28 +10,43 @@ import { TravelConfirmationPopup } from "./TravelConfirmationPopup";
|
|||||||
|
|
||||||
import { CONSTANTS } from "../../Constants";
|
import { CONSTANTS } from "../../Constants";
|
||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||||
|
import { IRouter } from "../../ui/Router";
|
||||||
import { Settings } from "../../Settings/Settings";
|
import { Settings } from "../../Settings/Settings";
|
||||||
|
|
||||||
import { StdButton } from "../../ui/React/StdButton";
|
import { StdButton } from "../../ui/React/StdButton";
|
||||||
import { createPopup } from "../../ui/React/createPopup";
|
import { createPopup } from "../../ui/React/createPopup";
|
||||||
import { Money } from "../../ui/React/Money";
|
import { Money } from "../../ui/React/Money";
|
||||||
import { WorldMap } from "../../ui/React/WorldMap";
|
import { WorldMap } from "../../ui/React/WorldMap";
|
||||||
|
import { dialogBoxCreate } from "../../../utils/DialogBox";
|
||||||
|
|
||||||
type IProps = {
|
type IProps = {
|
||||||
p: IPlayer;
|
p: IPlayer;
|
||||||
travel: (to: CityName) => void;
|
router: IRouter;
|
||||||
};
|
};
|
||||||
|
|
||||||
function createTravelPopup(p: IPlayer, city: string, travel: () => void): void {
|
function travel(p: IPlayer, router: IRouter, to: CityName): void {
|
||||||
|
const cost = CONSTANTS.TravelCost;
|
||||||
|
if (!p.canAfford(cost)) {
|
||||||
|
dialogBoxCreate(`You cannot afford to travel to ${to}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
p.loseMoney(cost);
|
||||||
|
p.travel(to);
|
||||||
|
dialogBoxCreate(<span className="noselect">You are now in {to}!</span>);
|
||||||
|
router.toCity();
|
||||||
|
}
|
||||||
|
|
||||||
|
function createTravelPopup(p: IPlayer, router: IRouter, city: CityName): void {
|
||||||
if (Settings.SuppressTravelConfirmation) {
|
if (Settings.SuppressTravelConfirmation) {
|
||||||
travel();
|
travel(p, router, city);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const popupId = `travel-confirmation`;
|
const popupId = `travel-confirmation`;
|
||||||
createPopup(popupId, TravelConfirmationPopup, {
|
createPopup(popupId, TravelConfirmationPopup, {
|
||||||
player: p,
|
player: p,
|
||||||
city: city,
|
city: city,
|
||||||
travel: travel,
|
travel: () => travel(p, router, city),
|
||||||
popupId: popupId,
|
popupId: popupId,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -45,7 +60,7 @@ function ASCIIWorldMap(props: IProps): React.ReactElement {
|
|||||||
</p>
|
</p>
|
||||||
<WorldMap
|
<WorldMap
|
||||||
currentCity={props.p.city}
|
currentCity={props.p.city}
|
||||||
onTravel={(city: CityName) => createTravelPopup(props.p, city, () => props.travel(city))}
|
onTravel={(city: CityName) => createTravelPopup(props.p, props.router, city)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@ -66,7 +81,7 @@ function ListWorldMap(props: IProps): React.ReactElement {
|
|||||||
return (
|
return (
|
||||||
<StdButton
|
<StdButton
|
||||||
key={city}
|
key={city}
|
||||||
onClick={() => createTravelPopup(props.p, city, () => props.travel(match[1]))}
|
onClick={() => createTravelPopup(props.p, props.router, city as CityName)}
|
||||||
style={{ display: "block" }}
|
style={{ display: "block" }}
|
||||||
text={`Travel to ${city}`}
|
text={`Travel to ${city}`}
|
||||||
/>
|
/>
|
||||||
@ -76,10 +91,15 @@ function ListWorldMap(props: IProps): React.ReactElement {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function TravelAgencyLocation(props: IProps): React.ReactElement {
|
export function TravelAgencyRoot(props: IProps): React.ReactElement {
|
||||||
if (Settings.DisableASCIIArt) {
|
return (
|
||||||
return <ListWorldMap p={props.p} travel={props.travel} />;
|
<>
|
||||||
} else {
|
<h1>Travel Agency</h1>
|
||||||
return <ASCIIWorldMap p={props.p} travel={props.travel} />;
|
{Settings.DisableASCIIArt ? (
|
||||||
}
|
<ListWorldMap p={props.p} router={props.router} />
|
||||||
|
) : (
|
||||||
|
<ASCIIWorldMap p={props.p} router={props.router} />
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
}
|
}
|
@ -8,154 +8,134 @@ import * as React from "react";
|
|||||||
import { Location } from "../Location";
|
import { Location } from "../Location";
|
||||||
|
|
||||||
import { CONSTANTS } from "../../Constants";
|
import { CONSTANTS } from "../../Constants";
|
||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
|
||||||
import { getServer } from "../../Server/ServerHelpers";
|
import { getServer } from "../../Server/ServerHelpers";
|
||||||
import { Server } from "../../Server/Server";
|
import { Server } from "../../Server/Server";
|
||||||
import { SpecialServerIps } from "../../Server/SpecialServerIps";
|
import { SpecialServerIps } from "../../Server/SpecialServerIps";
|
||||||
|
|
||||||
import { StdButton } from "../../ui/React/StdButton";
|
import { StdButton } from "../../ui/React/StdButton";
|
||||||
import { Money } from "../../ui/React/Money";
|
import { Money } from "../../ui/React/Money";
|
||||||
|
import { use } from "../../ui/Context";
|
||||||
|
|
||||||
type IProps = {
|
type IProps = {
|
||||||
loc: Location;
|
loc: Location;
|
||||||
p: IPlayer;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export class UniversityLocation extends React.Component<IProps, any> {
|
export function UniversityLocation(props: IProps): React.ReactElement {
|
||||||
/**
|
const player = use.Player();
|
||||||
* Stores button styling that sets them all to block display
|
const router = use.Router();
|
||||||
*/
|
|
||||||
btnStyle: any;
|
|
||||||
|
|
||||||
constructor(props: IProps) {
|
function calculateCost(): number {
|
||||||
super(props);
|
const ip = SpecialServerIps.getIp(props.loc.name);
|
||||||
|
|
||||||
this.btnStyle = { display: "block" };
|
|
||||||
|
|
||||||
this.take = this.take.bind(this);
|
|
||||||
this.study = this.study.bind(this);
|
|
||||||
this.dataStructures = this.dataStructures.bind(this);
|
|
||||||
this.networks = this.networks.bind(this);
|
|
||||||
this.algorithms = this.algorithms.bind(this);
|
|
||||||
this.management = this.management.bind(this);
|
|
||||||
this.leadership = this.leadership.bind(this);
|
|
||||||
|
|
||||||
this.calculateCost = this.calculateCost.bind(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
calculateCost(): number {
|
|
||||||
const ip = SpecialServerIps.getIp(this.props.loc.name);
|
|
||||||
const server = getServer(ip);
|
const server = getServer(ip);
|
||||||
if (server == null || !server.hasOwnProperty("backdoorInstalled")) return this.props.loc.costMult;
|
if (server == null || !server.hasOwnProperty("backdoorInstalled")) return props.loc.costMult;
|
||||||
const discount = (server as Server).backdoorInstalled ? 0.9 : 1;
|
const discount = (server as Server).backdoorInstalled ? 0.9 : 1;
|
||||||
return this.props.loc.costMult * discount;
|
return props.loc.costMult * discount;
|
||||||
}
|
}
|
||||||
|
|
||||||
take(stat: string): void {
|
function take(stat: string): void {
|
||||||
const loc = this.props.loc;
|
const loc = props.loc;
|
||||||
this.props.p.startClass(this.calculateCost(), loc.expMult, stat);
|
player.startClass(calculateCost(), loc.expMult, stat);
|
||||||
|
router.toWork();
|
||||||
}
|
}
|
||||||
|
|
||||||
study(): void {
|
function study(): void {
|
||||||
this.take(CONSTANTS.ClassStudyComputerScience);
|
take(CONSTANTS.ClassStudyComputerScience);
|
||||||
}
|
}
|
||||||
|
|
||||||
dataStructures(): void {
|
function dataStructures(): void {
|
||||||
this.take(CONSTANTS.ClassDataStructures);
|
take(CONSTANTS.ClassDataStructures);
|
||||||
}
|
}
|
||||||
|
|
||||||
networks(): void {
|
function networks(): void {
|
||||||
this.take(CONSTANTS.ClassNetworks);
|
take(CONSTANTS.ClassNetworks);
|
||||||
}
|
}
|
||||||
|
|
||||||
algorithms(): void {
|
function algorithms(): void {
|
||||||
this.take(CONSTANTS.ClassAlgorithms);
|
take(CONSTANTS.ClassAlgorithms);
|
||||||
}
|
}
|
||||||
|
|
||||||
management(): void {
|
function management(): void {
|
||||||
this.take(CONSTANTS.ClassManagement);
|
take(CONSTANTS.ClassManagement);
|
||||||
}
|
}
|
||||||
|
|
||||||
leadership(): void {
|
function leadership(): void {
|
||||||
this.take(CONSTANTS.ClassLeadership);
|
take(CONSTANTS.ClassLeadership);
|
||||||
}
|
}
|
||||||
|
|
||||||
render(): React.ReactNode {
|
const costMult: number = calculateCost();
|
||||||
const costMult: number = this.calculateCost();
|
|
||||||
|
|
||||||
const dataStructuresCost = CONSTANTS.ClassDataStructuresBaseCost * costMult;
|
const dataStructuresCost = CONSTANTS.ClassDataStructuresBaseCost * costMult;
|
||||||
const networksCost = CONSTANTS.ClassNetworksBaseCost * costMult;
|
const networksCost = CONSTANTS.ClassNetworksBaseCost * costMult;
|
||||||
const algorithmsCost = CONSTANTS.ClassAlgorithmsBaseCost * costMult;
|
const algorithmsCost = CONSTANTS.ClassAlgorithmsBaseCost * costMult;
|
||||||
const managementCost = CONSTANTS.ClassManagementBaseCost * costMult;
|
const managementCost = CONSTANTS.ClassManagementBaseCost * costMult;
|
||||||
const leadershipCost = CONSTANTS.ClassLeadershipBaseCost * costMult;
|
const leadershipCost = CONSTANTS.ClassLeadershipBaseCost * costMult;
|
||||||
|
|
||||||
const earnHackingExpTooltip = `Gain hacking experience!`;
|
const earnHackingExpTooltip = `Gain hacking experience!`;
|
||||||
const earnCharismaExpTooltip = `Gain charisma experience!`;
|
const earnCharismaExpTooltip = `Gain charisma experience!`;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<StdButton
|
<StdButton
|
||||||
onClick={this.study}
|
onClick={study}
|
||||||
style={this.btnStyle}
|
style={{ display: "block" }}
|
||||||
text={`Study Computer Science (free)`}
|
text={`Study Computer Science (free)`}
|
||||||
tooltip={earnHackingExpTooltip}
|
tooltip={earnHackingExpTooltip}
|
||||||
/>
|
/>
|
||||||
<StdButton
|
<StdButton
|
||||||
onClick={this.dataStructures}
|
onClick={dataStructures}
|
||||||
style={this.btnStyle}
|
style={{ display: "block" }}
|
||||||
text={
|
text={
|
||||||
<>
|
<>
|
||||||
Take Data Structures course (
|
Take Data Structures course (
|
||||||
<Money money={dataStructuresCost} player={this.props.p} /> / sec)
|
<Money money={dataStructuresCost} player={player} /> / sec)
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
tooltip={earnHackingExpTooltip}
|
tooltip={earnHackingExpTooltip}
|
||||||
/>
|
/>
|
||||||
<StdButton
|
<StdButton
|
||||||
onClick={this.networks}
|
onClick={networks}
|
||||||
style={this.btnStyle}
|
style={{ display: "block" }}
|
||||||
text={
|
text={
|
||||||
<>
|
<>
|
||||||
Take Networks course (
|
Take Networks course (
|
||||||
<Money money={networksCost} player={this.props.p} /> / sec)
|
<Money money={networksCost} player={player} /> / sec)
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
tooltip={earnHackingExpTooltip}
|
tooltip={earnHackingExpTooltip}
|
||||||
/>
|
/>
|
||||||
<StdButton
|
<StdButton
|
||||||
onClick={this.algorithms}
|
onClick={algorithms}
|
||||||
style={this.btnStyle}
|
style={{ display: "block" }}
|
||||||
text={
|
text={
|
||||||
<>
|
<>
|
||||||
Take Algorithms course (
|
Take Algorithms course (
|
||||||
<Money money={algorithmsCost} player={this.props.p} /> / sec)
|
<Money money={algorithmsCost} player={player} /> / sec)
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
tooltip={earnHackingExpTooltip}
|
tooltip={earnHackingExpTooltip}
|
||||||
/>
|
/>
|
||||||
<StdButton
|
<StdButton
|
||||||
onClick={this.management}
|
onClick={management}
|
||||||
style={this.btnStyle}
|
style={{ display: "block" }}
|
||||||
text={
|
text={
|
||||||
<>
|
<>
|
||||||
Take Management course (
|
Take Management course (
|
||||||
<Money money={managementCost} player={this.props.p} /> / sec)
|
<Money money={managementCost} player={player} /> / sec)
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
tooltip={earnCharismaExpTooltip}
|
tooltip={earnCharismaExpTooltip}
|
||||||
/>
|
/>
|
||||||
<StdButton
|
<StdButton
|
||||||
onClick={this.leadership}
|
onClick={leadership}
|
||||||
style={this.btnStyle}
|
style={{ display: "block" }}
|
||||||
text={
|
text={
|
||||||
<>
|
<>
|
||||||
Take Leadership course (
|
Take Leadership course (
|
||||||
<Money money={leadershipCost} player={this.props.p} /> / sec)
|
<Money money={leadershipCost} player={player} /> / sec)
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
tooltip={earnCharismaExpTooltip}
|
tooltip={earnCharismaExpTooltip}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
import { CONSTANTS } from "./Constants";
|
import { CONSTANTS } from "./Constants";
|
||||||
import { Engine } from "./engine";
|
|
||||||
import { displayFactionContent } from "./Faction/FactionHelpers";
|
|
||||||
import { Player } from "./Player";
|
import { Player } from "./Player";
|
||||||
|
|
||||||
import { dialogBoxCreate } from "../utils/DialogBox";
|
import { dialogBoxCreate } from "../utils/DialogBox";
|
||||||
@ -1187,7 +1185,7 @@ HackingMission.prototype.process = function (numCycles = 1) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Update timer and check if player lost
|
// Update timer and check if player lost
|
||||||
this.time -= storedCycles * Engine._idleSpeed;
|
this.time -= storedCycles * CONSTANTS._idleSpeed;
|
||||||
if (this.time <= 0) {
|
if (this.time <= 0) {
|
||||||
this.finishMission(false);
|
this.finishMission(false);
|
||||||
return;
|
return;
|
||||||
@ -1595,18 +1593,6 @@ HackingMission.prototype.finishMission = function (win) {
|
|||||||
} else {
|
} else {
|
||||||
dialogBoxCreate("Mission lost/forfeited! You did not gain any faction reputation.");
|
dialogBoxCreate("Mission lost/forfeited! You did not gain any faction reputation.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear mission container
|
|
||||||
var container = document.getElementById("mission-container");
|
|
||||||
while (container.firstChild) {
|
|
||||||
container.removeChild(container.firstChild);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return to Faction page
|
|
||||||
document.getElementById("mainmenu-container").style.visibility = "visible";
|
|
||||||
document.getElementById("character-overview").style.visibility = "visible";
|
|
||||||
Engine.loadFactionContent();
|
|
||||||
displayFactionContent(this.faction.name);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export { HackingMission, inMission, setInMission, currMission };
|
export { HackingMission, inMission, setInMission, currMission };
|
||||||
|
@ -119,13 +119,7 @@ import { SpecialServerIps } from "./Server/SpecialServerIps";
|
|||||||
import { SourceFileFlags } from "./SourceFile/SourceFileFlags";
|
import { SourceFileFlags } from "./SourceFile/SourceFileFlags";
|
||||||
import { buyStock, sellStock, shortStock, sellShort } from "./StockMarket/BuyingAndSelling";
|
import { buyStock, sellStock, shortStock, sellShort } from "./StockMarket/BuyingAndSelling";
|
||||||
import { influenceStockThroughServerHack, influenceStockThroughServerGrow } from "./StockMarket/PlayerInfluencing";
|
import { influenceStockThroughServerHack, influenceStockThroughServerGrow } from "./StockMarket/PlayerInfluencing";
|
||||||
import {
|
import { StockMarket, SymbolToStockMap, placeOrder, cancelOrder } from "./StockMarket/StockMarket";
|
||||||
StockMarket,
|
|
||||||
SymbolToStockMap,
|
|
||||||
placeOrder,
|
|
||||||
cancelOrder,
|
|
||||||
displayStockMarketContent,
|
|
||||||
} from "./StockMarket/StockMarket";
|
|
||||||
import { getBuyTransactionCost, getSellTransactionGain } from "./StockMarket/StockMarketHelpers";
|
import { getBuyTransactionCost, getSellTransactionGain } from "./StockMarket/StockMarketHelpers";
|
||||||
import { OrderTypes } from "./StockMarket/data/OrderTypes";
|
import { OrderTypes } from "./StockMarket/data/OrderTypes";
|
||||||
import { PositionTypes } from "./StockMarket/data/PositionTypes";
|
import { PositionTypes } from "./StockMarket/data/PositionTypes";
|
||||||
@ -1964,18 +1958,14 @@ function NetscriptFunctions(workerScript) {
|
|||||||
updateDynamicRam("buyStock", getRamCost("buyStock"));
|
updateDynamicRam("buyStock", getRamCost("buyStock"));
|
||||||
checkTixApiAccess("buyStock");
|
checkTixApiAccess("buyStock");
|
||||||
const stock = getStockFromSymbol(symbol, "buyStock");
|
const stock = getStockFromSymbol(symbol, "buyStock");
|
||||||
const res = buyStock(stock, shares, workerScript, {
|
const res = buyStock(stock, shares, workerScript, {});
|
||||||
rerenderFn: displayStockMarketContent,
|
|
||||||
});
|
|
||||||
return res ? stock.price : 0;
|
return res ? stock.price : 0;
|
||||||
},
|
},
|
||||||
sellStock: function (symbol, shares) {
|
sellStock: function (symbol, shares) {
|
||||||
updateDynamicRam("sellStock", getRamCost("sellStock"));
|
updateDynamicRam("sellStock", getRamCost("sellStock"));
|
||||||
checkTixApiAccess("sellStock");
|
checkTixApiAccess("sellStock");
|
||||||
const stock = getStockFromSymbol(symbol, "sellStock");
|
const stock = getStockFromSymbol(symbol, "sellStock");
|
||||||
const res = sellStock(stock, shares, workerScript, {
|
const res = sellStock(stock, shares, workerScript, {});
|
||||||
rerenderFn: displayStockMarketContent,
|
|
||||||
});
|
|
||||||
|
|
||||||
return res ? stock.price : 0;
|
return res ? stock.price : 0;
|
||||||
},
|
},
|
||||||
@ -1991,9 +1981,7 @@ function NetscriptFunctions(workerScript) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
const stock = getStockFromSymbol(symbol, "shortStock");
|
const stock = getStockFromSymbol(symbol, "shortStock");
|
||||||
const res = shortStock(stock, shares, workerScript, {
|
const res = shortStock(stock, shares, workerScript, {});
|
||||||
rerenderFn: displayStockMarketContent,
|
|
||||||
});
|
|
||||||
|
|
||||||
return res ? stock.price : 0;
|
return res ? stock.price : 0;
|
||||||
},
|
},
|
||||||
@ -2009,9 +1997,7 @@ function NetscriptFunctions(workerScript) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
const stock = getStockFromSymbol(symbol, "sellShort");
|
const stock = getStockFromSymbol(symbol, "sellShort");
|
||||||
const res = sellShort(stock, shares, workerScript, {
|
const res = sellShort(stock, shares, workerScript, {});
|
||||||
rerenderFn: displayStockMarketContent,
|
|
||||||
});
|
|
||||||
|
|
||||||
return res ? stock.price : 0;
|
return res ? stock.price : 0;
|
||||||
},
|
},
|
||||||
@ -2168,7 +2154,6 @@ function NetscriptFunctions(workerScript) {
|
|||||||
Player.has4SData = true;
|
Player.has4SData = true;
|
||||||
Player.loseMoney(getStockMarket4SDataCost());
|
Player.loseMoney(getStockMarket4SDataCost());
|
||||||
workerScript.log("purchase4SMarketData", "Purchased 4S Market Data");
|
workerScript.log("purchase4SMarketData", "Purchased 4S Market Data");
|
||||||
displayStockMarketContent();
|
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
purchase4SMarketDataTixApi: function () {
|
purchase4SMarketDataTixApi: function () {
|
||||||
@ -2188,7 +2173,6 @@ function NetscriptFunctions(workerScript) {
|
|||||||
Player.has4SDataTixApi = true;
|
Player.has4SDataTixApi = true;
|
||||||
Player.loseMoney(getStockMarket4STixApiCost());
|
Player.loseMoney(getStockMarket4STixApiCost());
|
||||||
workerScript.log("purchase4SMarketDataTixApi", "Purchased 4S Market Data TIX API");
|
workerScript.log("purchase4SMarketDataTixApi", "Purchased 4S Market Data TIX API");
|
||||||
displayStockMarketContent();
|
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
getPurchasedServerLimit: function () {
|
getPurchasedServerLimit: function () {
|
||||||
|
@ -121,8 +121,33 @@ export interface IPlayer {
|
|||||||
bladeburner_analysis_mult: number;
|
bladeburner_analysis_mult: number;
|
||||||
bladeburner_success_chance_mult: number;
|
bladeburner_success_chance_mult: number;
|
||||||
|
|
||||||
workRepGained: number;
|
createProgramName: string;
|
||||||
|
timeWorkedCreateProgram: number;
|
||||||
|
crimeType: string;
|
||||||
|
timeNeededToCompleteWork: number;
|
||||||
focus: boolean;
|
focus: boolean;
|
||||||
|
className: string;
|
||||||
|
currentWorkFactionName: string;
|
||||||
|
workType: string;
|
||||||
|
currentWorkFactionDescription: string;
|
||||||
|
timeWorked: number;
|
||||||
|
workMoneyGained: number;
|
||||||
|
workMoneyGainRate: number;
|
||||||
|
workRepGained: number;
|
||||||
|
workRepGainRate: number;
|
||||||
|
workHackExpGained: number;
|
||||||
|
workHackExpGainRate: number;
|
||||||
|
workStrExpGained: number;
|
||||||
|
workStrExpGainRate: number;
|
||||||
|
workDefExpGained: number;
|
||||||
|
workDefExpGainRate: number;
|
||||||
|
workDexExpGained: number;
|
||||||
|
workDexExpGainRate: number;
|
||||||
|
workAgiExpGained: number;
|
||||||
|
workAgiExpGainRate: number;
|
||||||
|
workChaExpGained: number;
|
||||||
|
workChaExpGainRate: number;
|
||||||
|
workMoneyLossRate: number;
|
||||||
|
|
||||||
// Methods
|
// Methods
|
||||||
applyForAgentJob(sing?: boolean): boolean | void;
|
applyForAgentJob(sing?: boolean): boolean | void;
|
||||||
@ -209,4 +234,12 @@ export interface IPlayer {
|
|||||||
receiveInvite(factionName: string): void;
|
receiveInvite(factionName: string): void;
|
||||||
updateSkillLevels(): void;
|
updateSkillLevels(): void;
|
||||||
gainCodingContractReward(reward: ICodingContractReward, difficulty?: number): string;
|
gainCodingContractReward(reward: ICodingContractReward, difficulty?: number): string;
|
||||||
|
stopFocusing(): void;
|
||||||
|
finishFactionWork(cancelled: boolean, sing?: boolean): void;
|
||||||
|
finishClass(sing?: boolean): void;
|
||||||
|
finishWork(cancelled: boolean, sing?: boolean): void;
|
||||||
|
cancelationPenalty(): number;
|
||||||
|
finishWorkPartTime(sing?: boolean): void;
|
||||||
|
finishCrime(cancelled: boolean): void;
|
||||||
|
finishCreateProgramWork(cancelled: boolean): void;
|
||||||
}
|
}
|
||||||
|
@ -14,10 +14,8 @@ import { CONSTANTS } from "../../Constants";
|
|||||||
import { Programs } from "../../Programs/Programs";
|
import { Programs } from "../../Programs/Programs";
|
||||||
import { determineCrimeSuccess } from "../../Crime/CrimeHelpers";
|
import { determineCrimeSuccess } from "../../Crime/CrimeHelpers";
|
||||||
import { Crimes } from "../../Crime/Crimes";
|
import { Crimes } from "../../Crime/Crimes";
|
||||||
import { Engine } from "../../engine";
|
|
||||||
import { Faction } from "../../Faction/Faction";
|
import { Faction } from "../../Faction/Faction";
|
||||||
import { Factions } from "../../Faction/Factions";
|
import { Factions } from "../../Faction/Factions";
|
||||||
import { displayFactionContent } from "../../Faction/FactionHelpers";
|
|
||||||
import { resetGangs } from "../../Gang/AllGangs";
|
import { resetGangs } from "../../Gang/AllGangs";
|
||||||
import { hasHacknetServers } from "../../Hacknet/HacknetHelpers";
|
import { hasHacknetServers } from "../../Hacknet/HacknetHelpers";
|
||||||
import { Cities } from "../../Locations/Cities";
|
import { Cities } from "../../Locations/Cities";
|
||||||
@ -48,18 +46,12 @@ import Decimal from "decimal.js";
|
|||||||
import { numeralWrapper } from "../../ui/numeralFormat";
|
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||||
import { MoneySourceTracker } from "../../utils/MoneySourceTracker";
|
import { MoneySourceTracker } from "../../utils/MoneySourceTracker";
|
||||||
import { dialogBoxCreate } from "../../../utils/DialogBox";
|
import { dialogBoxCreate } from "../../../utils/DialogBox";
|
||||||
import { clearEventListeners } from "../../../utils/uiHelpers/clearEventListeners";
|
|
||||||
import { convertTimeMsToTimeElapsedString } from "../../../utils/StringHelperFunctions";
|
import { convertTimeMsToTimeElapsedString } from "../../../utils/StringHelperFunctions";
|
||||||
|
|
||||||
import { Reputation } from "../../ui/React/Reputation";
|
import { Reputation } from "../../ui/React/Reputation";
|
||||||
import { Money } from "../../ui/React/Money";
|
import { Money } from "../../ui/React/Money";
|
||||||
import { MoneyRate } from "../../ui/React/MoneyRate";
|
|
||||||
import { ReputationRate } from "../../ui/React/ReputationRate";
|
|
||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import ReactDOM from "react-dom";
|
|
||||||
|
|
||||||
const CYCLES_PER_SEC = 1000 / CONSTANTS.MilliPerCycle;
|
|
||||||
|
|
||||||
export function init() {
|
export function init() {
|
||||||
/* Initialize Player's home computer */
|
/* Initialize Player's home computer */
|
||||||
@ -518,8 +510,6 @@ export function resetWorkStatus(generalType, group, workType) {
|
|||||||
this.currentWorkFactionDescription = "";
|
this.currentWorkFactionDescription = "";
|
||||||
this.createProgramName = "";
|
this.createProgramName = "";
|
||||||
this.className = "";
|
this.className = "";
|
||||||
|
|
||||||
ReactDOM.unmountComponentAtNode(document.getElementById("work-in-progress-text"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function processWorkEarnings(numCycles = 1) {
|
export function processWorkEarnings(numCycles = 1) {
|
||||||
@ -573,25 +563,6 @@ export function startWork(companyName) {
|
|||||||
this.workMoneyGainRate = this.getWorkMoneyGain();
|
this.workMoneyGainRate = this.getWorkMoneyGain();
|
||||||
|
|
||||||
this.timeNeededToCompleteWork = CONSTANTS.MillisecondsPer8Hours;
|
this.timeNeededToCompleteWork = CONSTANTS.MillisecondsPer8Hours;
|
||||||
|
|
||||||
//Remove all old event listeners from Cancel button
|
|
||||||
var newCancelButton = clearEventListeners("work-in-progress-cancel-button");
|
|
||||||
newCancelButton.innerHTML = "Cancel Work";
|
|
||||||
newCancelButton.addEventListener("click", () => {
|
|
||||||
this.finishWork(true);
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
const focusButton = clearEventListeners("work-in-progress-something-else-button");
|
|
||||||
focusButton.style.visibility = "visible";
|
|
||||||
focusButton.innerHTML = "Do something else simultaneously";
|
|
||||||
focusButton.addEventListener("click", () => {
|
|
||||||
this.stopFocusing();
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
//Display Work In Progress Screen
|
|
||||||
Engine.loadWorkInProgressContent();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function cancelationPenalty() {
|
export function cancelationPenalty() {
|
||||||
@ -607,11 +578,11 @@ export function work(numCycles) {
|
|||||||
// Cap the number of cycles being processed to whatever would put you at
|
// Cap the number of cycles being processed to whatever would put you at
|
||||||
// the work time limit (8 hours)
|
// the work time limit (8 hours)
|
||||||
var overMax = false;
|
var overMax = false;
|
||||||
if (this.timeWorked + Engine._idleSpeed * numCycles >= CONSTANTS.MillisecondsPer8Hours) {
|
if (this.timeWorked + CONSTANTS._idleSpeed * numCycles >= CONSTANTS.MillisecondsPer8Hours) {
|
||||||
overMax = true;
|
overMax = true;
|
||||||
numCycles = Math.round((CONSTANTS.MillisecondsPer8Hours - this.timeWorked) / Engine._idleSpeed);
|
numCycles = Math.round((CONSTANTS.MillisecondsPer8Hours - this.timeWorked) / CONSTANTS._idleSpeed);
|
||||||
}
|
}
|
||||||
this.timeWorked += Engine._idleSpeed * numCycles;
|
this.timeWorked += CONSTANTS._idleSpeed * numCycles;
|
||||||
|
|
||||||
this.workRepGainRate = this.getWorkRepGain();
|
this.workRepGainRate = this.getWorkRepGain();
|
||||||
this.processWorkEarnings(numCycles);
|
this.processWorkEarnings(numCycles);
|
||||||
@ -622,63 +593,7 @@ export function work(numCycles) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const comp = Companies[this.companyName];
|
const comp = Companies[this.companyName];
|
||||||
let companyRep = "0";
|
|
||||||
if (comp == null || !(comp instanceof Company)) {
|
|
||||||
console.error(`Could not find Company: ${this.companyName}`);
|
|
||||||
} else {
|
|
||||||
companyRep = comp.playerReputation;
|
|
||||||
}
|
|
||||||
|
|
||||||
influenceStockThroughCompanyWork(comp, this.workRepGainRate, numCycles);
|
influenceStockThroughCompanyWork(comp, this.workRepGainRate, numCycles);
|
||||||
|
|
||||||
const position = this.jobs[this.companyName];
|
|
||||||
|
|
||||||
const penalty = this.cancelationPenalty();
|
|
||||||
|
|
||||||
const penaltyString = penalty === 0.5 ? "half" : "three-quarters";
|
|
||||||
|
|
||||||
var elem = document.getElementById("work-in-progress-text");
|
|
||||||
ReactDOM.render(
|
|
||||||
<>
|
|
||||||
You are currently working as a {position} at {this.companyName} (Current Company Reputation:{" "}
|
|
||||||
{Reputation(companyRep)})<br />
|
|
||||||
<br />
|
|
||||||
You have been working for {convertTimeMsToTimeElapsedString(this.timeWorked)}
|
|
||||||
<br />
|
|
||||||
<br />
|
|
||||||
You have earned: <br />
|
|
||||||
<br />
|
|
||||||
<Money money={this.workMoneyGained} /> ({MoneyRate(this.workMoneyGainRate * CYCLES_PER_SEC)}) <br />
|
|
||||||
<br />
|
|
||||||
{Reputation(this.workRepGained)} ({ReputationRate(this.workRepGainRate * CYCLES_PER_SEC)}) reputation for this
|
|
||||||
company <br />
|
|
||||||
<br />
|
|
||||||
{numeralWrapper.formatExp(this.workHackExpGained)} (
|
|
||||||
{`${numeralWrapper.formatExp(this.workHackExpGainRate * CYCLES_PER_SEC)} / sec`}
|
|
||||||
) hacking exp <br />
|
|
||||||
<br />
|
|
||||||
{numeralWrapper.formatExp(this.workStrExpGained)} (
|
|
||||||
{`${numeralWrapper.formatExp(this.workStrExpGainRate * CYCLES_PER_SEC)} / sec`}
|
|
||||||
) strength exp <br />
|
|
||||||
{numeralWrapper.formatExp(this.workDefExpGained)} (
|
|
||||||
{`${numeralWrapper.formatExp(this.workDefExpGainRate * CYCLES_PER_SEC)} / sec`}
|
|
||||||
) defense exp <br />
|
|
||||||
{numeralWrapper.formatExp(this.workDexExpGained)} (
|
|
||||||
{`${numeralWrapper.formatExp(this.workDexExpGainRate * CYCLES_PER_SEC)} / sec`}
|
|
||||||
) dexterity exp <br />
|
|
||||||
{numeralWrapper.formatExp(this.workAgiExpGained)} (
|
|
||||||
{`${numeralWrapper.formatExp(this.workAgiExpGainRate * CYCLES_PER_SEC)} / sec`}
|
|
||||||
) agility exp <br />
|
|
||||||
<br />
|
|
||||||
{numeralWrapper.formatExp(this.workChaExpGained)} (
|
|
||||||
{`${numeralWrapper.formatExp(this.workChaExpGainRate * CYCLES_PER_SEC)} / sec`}
|
|
||||||
) charisma exp <br />
|
|
||||||
<br />
|
|
||||||
You will automatically finish after working for 8 hours. You can cancel earlier if you wish, but you will only
|
|
||||||
gain {penaltyString} of the reputation you've earned so far.
|
|
||||||
</>,
|
|
||||||
elem,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function finishWork(cancelled, sing = false) {
|
export function finishWork(cancelled, sing = false) {
|
||||||
@ -731,10 +646,7 @@ export function finishWork(cancelled, sing = false) {
|
|||||||
dialogBoxCreate(content);
|
dialogBoxCreate(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
var mainMenu = document.getElementById("mainmenu-container");
|
|
||||||
mainMenu.style.visibility = "visible";
|
|
||||||
this.isWorking = false;
|
this.isWorking = false;
|
||||||
Engine.loadLocationContent(false);
|
|
||||||
|
|
||||||
if (sing) {
|
if (sing) {
|
||||||
var res =
|
var res =
|
||||||
@ -781,27 +693,17 @@ export function startWorkPartTime(companyName) {
|
|||||||
this.workMoneyGainRate = this.getWorkMoneyGain();
|
this.workMoneyGainRate = this.getWorkMoneyGain();
|
||||||
|
|
||||||
this.timeNeededToCompleteWork = CONSTANTS.MillisecondsPer8Hours;
|
this.timeNeededToCompleteWork = CONSTANTS.MillisecondsPer8Hours;
|
||||||
|
|
||||||
var newCancelButton = clearEventListeners("work-in-progress-cancel-button");
|
|
||||||
newCancelButton.innerHTML = "Stop Working";
|
|
||||||
newCancelButton.addEventListener("click", () => {
|
|
||||||
this.finishWorkPartTime();
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
//Display Work In Progress Screen
|
|
||||||
Engine.loadWorkInProgressContent();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function workPartTime(numCycles) {
|
export function workPartTime(numCycles) {
|
||||||
//Cap the number of cycles being processed to whatever would put you at the
|
//Cap the number of cycles being processed to whatever would put you at the
|
||||||
//work time limit (8 hours)
|
//work time limit (8 hours)
|
||||||
var overMax = false;
|
var overMax = false;
|
||||||
if (this.timeWorked + Engine._idleSpeed * numCycles >= CONSTANTS.MillisecondsPer8Hours) {
|
if (this.timeWorked + CONSTANTS._idleSpeed * numCycles >= CONSTANTS.MillisecondsPer8Hours) {
|
||||||
overMax = true;
|
overMax = true;
|
||||||
numCycles = Math.round((CONSTANTS.MillisecondsPer8Hours - this.timeWorked) / Engine._idleSpeed);
|
numCycles = Math.round((CONSTANTS.MillisecondsPer8Hours - this.timeWorked) / CONSTANTS._idleSpeed);
|
||||||
}
|
}
|
||||||
this.timeWorked += Engine._idleSpeed * numCycles;
|
this.timeWorked += CONSTANTS._idleSpeed * numCycles;
|
||||||
|
|
||||||
this.workRepGainRate = this.getWorkRepGain();
|
this.workRepGainRate = this.getWorkRepGain();
|
||||||
this.processWorkEarnings(numCycles);
|
this.processWorkEarnings(numCycles);
|
||||||
@ -810,60 +712,6 @@ export function workPartTime(numCycles) {
|
|||||||
if (overMax || this.timeWorked >= CONSTANTS.MillisecondsPer8Hours) {
|
if (overMax || this.timeWorked >= CONSTANTS.MillisecondsPer8Hours) {
|
||||||
return this.finishWorkPartTime();
|
return this.finishWorkPartTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
var comp = Companies[this.companyName],
|
|
||||||
companyRep = "0";
|
|
||||||
if (comp == null || !(comp instanceof Company)) {
|
|
||||||
console.error(`Could not find Company: ${this.companyName}`);
|
|
||||||
} else {
|
|
||||||
companyRep = comp.playerReputation;
|
|
||||||
}
|
|
||||||
|
|
||||||
const position = this.jobs[this.companyName];
|
|
||||||
|
|
||||||
const elem = document.getElementById("work-in-progress-text");
|
|
||||||
ReactDOM.render(
|
|
||||||
<>
|
|
||||||
You are currently working as a {position} at {this.companyName} (Current Company Reputation:{" "}
|
|
||||||
{Reputation(companyRep)})<br />
|
|
||||||
<br />
|
|
||||||
You have been working for {convertTimeMsToTimeElapsedString(this.timeWorked)}
|
|
||||||
<br />
|
|
||||||
<br />
|
|
||||||
You have earned: <br />
|
|
||||||
<br />
|
|
||||||
<Money money={this.workMoneyGained} /> ({MoneyRate(this.workMoneyGainRate * CYCLES_PER_SEC)}) <br />
|
|
||||||
<br />
|
|
||||||
{Reputation(this.workRepGained)} (
|
|
||||||
{Reputation(`${numeralWrapper.formatExp(this.workRepGainRate * CYCLES_PER_SEC)} / sec`)}
|
|
||||||
) reputation for this company <br />
|
|
||||||
<br />
|
|
||||||
{numeralWrapper.formatExp(this.workHackExpGained)} (
|
|
||||||
{`${numeralWrapper.formatExp(this.workHackExpGainRate * CYCLES_PER_SEC)} / sec`}
|
|
||||||
) hacking exp <br />
|
|
||||||
<br />
|
|
||||||
{numeralWrapper.formatExp(this.workStrExpGained)} (
|
|
||||||
{`${numeralWrapper.formatExp(this.workStrExpGainRate * CYCLES_PER_SEC)} / sec`}
|
|
||||||
) strength exp <br />
|
|
||||||
{numeralWrapper.formatExp(this.workDefExpGained)} (
|
|
||||||
{`${numeralWrapper.formatExp(this.workDefExpGainRate * CYCLES_PER_SEC)} / sec`}
|
|
||||||
) defense exp <br />
|
|
||||||
{numeralWrapper.formatExp(this.workDexExpGained)} (
|
|
||||||
{`${numeralWrapper.formatExp(this.workDexExpGainRate * CYCLES_PER_SEC)} / sec`}
|
|
||||||
) dexterity exp <br />
|
|
||||||
{numeralWrapper.formatExp(this.workAgiExpGained)} (
|
|
||||||
{`${numeralWrapper.formatExp(this.workAgiExpGainRate * CYCLES_PER_SEC)} / sec`}
|
|
||||||
) agility exp <br />
|
|
||||||
<br />
|
|
||||||
{numeralWrapper.formatExp(this.workChaExpGained)} (
|
|
||||||
{`${numeralWrapper.formatExp(this.workChaExpGainRate * CYCLES_PER_SEC)} / sec`}
|
|
||||||
) charisma exp <br />
|
|
||||||
<br />
|
|
||||||
You will automatically finish after working for 8 hours. You can cancel earlier if you wish, and there will be no
|
|
||||||
penalty because this is a part-time job.
|
|
||||||
</>,
|
|
||||||
elem,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function finishWorkPartTime(sing = false) {
|
export function finishWorkPartTime(sing = false) {
|
||||||
@ -894,10 +742,7 @@ export function finishWorkPartTime(sing = false) {
|
|||||||
dialogBoxCreate(content);
|
dialogBoxCreate(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
var mainMenu = document.getElementById("mainmenu-container");
|
|
||||||
mainMenu.style.visibility = "visible";
|
|
||||||
this.isWorking = false;
|
this.isWorking = false;
|
||||||
Engine.loadLocationContent(false);
|
|
||||||
if (sing) {
|
if (sing) {
|
||||||
var res =
|
var res =
|
||||||
"You worked for " +
|
"You worked for " +
|
||||||
@ -928,17 +773,11 @@ export function finishWorkPartTime(sing = false) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function startFocusing() {
|
export function startFocusing() {
|
||||||
const mainMenu = document.getElementById("mainmenu-container");
|
|
||||||
mainMenu.style.visibility = "hidden";
|
|
||||||
this.focus = true;
|
this.focus = true;
|
||||||
Engine.loadWorkInProgressContent();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function stopFocusing() {
|
export function stopFocusing() {
|
||||||
const mainMenu = document.getElementById("mainmenu-container");
|
|
||||||
mainMenu.style.visibility = "visible";
|
|
||||||
this.focus = false;
|
this.focus = false;
|
||||||
Engine.loadTerminalContent();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Working for Faction */
|
/* Working for Faction */
|
||||||
@ -957,24 +796,6 @@ export function startFactionWork(faction) {
|
|||||||
this.currentWorkFactionName = faction.name;
|
this.currentWorkFactionName = faction.name;
|
||||||
|
|
||||||
this.timeNeededToCompleteWork = CONSTANTS.MillisecondsPer20Hours;
|
this.timeNeededToCompleteWork = CONSTANTS.MillisecondsPer20Hours;
|
||||||
|
|
||||||
const cancelButton = clearEventListeners("work-in-progress-cancel-button");
|
|
||||||
cancelButton.innerHTML = "Stop Faction Work";
|
|
||||||
cancelButton.addEventListener("click", () => {
|
|
||||||
this.finishFactionWork(true);
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
const focusButton = clearEventListeners("work-in-progress-something-else-button");
|
|
||||||
focusButton.style.visibility = "visible";
|
|
||||||
focusButton.innerHTML = "Do something else simultaneously";
|
|
||||||
focusButton.addEventListener("click", () => {
|
|
||||||
this.stopFocusing();
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
//Display Work In Progress Screen
|
|
||||||
Engine.loadWorkInProgressContent();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function startFactionHackWork(faction) {
|
export function startFactionHackWork(faction) {
|
||||||
@ -1046,11 +867,11 @@ export function workForFaction(numCycles) {
|
|||||||
|
|
||||||
//Cap the number of cycles being processed to whatever would put you at limit (20 hours)
|
//Cap the number of cycles being processed to whatever would put you at limit (20 hours)
|
||||||
var overMax = false;
|
var overMax = false;
|
||||||
if (this.timeWorked + Engine._idleSpeed * numCycles >= CONSTANTS.MillisecondsPer20Hours) {
|
if (this.timeWorked + CONSTANTS._idleSpeed * numCycles >= CONSTANTS.MillisecondsPer20Hours) {
|
||||||
overMax = true;
|
overMax = true;
|
||||||
numCycles = Math.round((CONSTANTS.MillisecondsPer20Hours - this.timeWorked) / Engine._idleSpeed);
|
numCycles = Math.round((CONSTANTS.MillisecondsPer20Hours - this.timeWorked) / CONSTANTS._idleSpeed);
|
||||||
}
|
}
|
||||||
this.timeWorked += Engine._idleSpeed * numCycles;
|
this.timeWorked += CONSTANTS._idleSpeed * numCycles;
|
||||||
|
|
||||||
this.processWorkEarnings(numCycles);
|
this.processWorkEarnings(numCycles);
|
||||||
|
|
||||||
@ -1058,44 +879,6 @@ export function workForFaction(numCycles) {
|
|||||||
if (overMax || this.timeWorked >= CONSTANTS.MillisecondsPer20Hours) {
|
if (overMax || this.timeWorked >= CONSTANTS.MillisecondsPer20Hours) {
|
||||||
return this.finishFactionWork(false);
|
return this.finishFactionWork(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
const elem = document.getElementById("work-in-progress-text");
|
|
||||||
ReactDOM.render(
|
|
||||||
<>
|
|
||||||
You are currently {this.currentWorkFactionDescription} for your faction {faction.name}
|
|
||||||
<br />
|
|
||||||
(Current Faction Reputation: {Reputation(faction.playerReputation)}). <br />
|
|
||||||
You have been doing this for {convertTimeMsToTimeElapsedString(this.timeWorked)}
|
|
||||||
<br />
|
|
||||||
<br />
|
|
||||||
You have earned: <br />
|
|
||||||
<br />
|
|
||||||
<Money money={this.workMoneyGained} /> ({MoneyRate(this.workMoneyGainRate * CYCLES_PER_SEC)}) <br />
|
|
||||||
<br />
|
|
||||||
{Reputation(this.workRepGained)} ({ReputationRate(this.workRepGainRate * CYCLES_PER_SEC)}) reputation for this
|
|
||||||
faction <br />
|
|
||||||
<br />
|
|
||||||
{numeralWrapper.formatExp(this.workHackExpGained)} (
|
|
||||||
{numeralWrapper.formatExp(this.workHackExpGainRate * CYCLES_PER_SEC)} / sec) hacking exp <br />
|
|
||||||
<br />
|
|
||||||
{numeralWrapper.formatExp(this.workStrExpGained)} (
|
|
||||||
{numeralWrapper.formatExp(this.workStrExpGainRate * CYCLES_PER_SEC)} / sec) strength exp <br />
|
|
||||||
{numeralWrapper.formatExp(this.workDefExpGained)} (
|
|
||||||
{numeralWrapper.formatExp(this.workDefExpGainRate * CYCLES_PER_SEC)} / sec) defense exp <br />
|
|
||||||
{numeralWrapper.formatExp(this.workDexExpGained)} (
|
|
||||||
{numeralWrapper.formatExp(this.workDexExpGainRate * CYCLES_PER_SEC)} / sec) dexterity exp <br />
|
|
||||||
{numeralWrapper.formatExp(this.workAgiExpGained)} (
|
|
||||||
{numeralWrapper.formatExp(this.workAgiExpGainRate * CYCLES_PER_SEC)} / sec) agility exp <br />
|
|
||||||
<br />
|
|
||||||
{numeralWrapper.formatExp(this.workChaExpGained)} (
|
|
||||||
{numeralWrapper.formatExp(this.workChaExpGainRate * CYCLES_PER_SEC)} / sec) charisma exp <br />
|
|
||||||
<br />
|
|
||||||
You will automatically finish after working for 20 hours. You can cancel earlier if you wish.
|
|
||||||
<br />
|
|
||||||
There is no penalty for cancelling earlier.
|
|
||||||
</>,
|
|
||||||
elem,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function finishFactionWork(cancelled, sing = false) {
|
export function finishFactionWork(cancelled, sing = false) {
|
||||||
@ -1125,13 +908,8 @@ export function finishFactionWork(cancelled, sing = false) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
var mainMenu = document.getElementById("mainmenu-container");
|
|
||||||
mainMenu.style.visibility = "visible";
|
|
||||||
|
|
||||||
this.isWorking = false;
|
this.isWorking = false;
|
||||||
|
|
||||||
Engine.loadFactionContent();
|
|
||||||
displayFactionContent(faction.name);
|
|
||||||
if (sing) {
|
if (sing) {
|
||||||
var res =
|
var res =
|
||||||
"You worked for your faction " +
|
"You worked for your faction " +
|
||||||
@ -1419,19 +1197,6 @@ export function startCreateProgramWork(programName, time, reqLevel) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.createProgramName = programName;
|
this.createProgramName = programName;
|
||||||
|
|
||||||
var cancelButton = clearEventListeners("work-in-progress-cancel-button");
|
|
||||||
cancelButton.innerHTML = "Cancel work on creating program";
|
|
||||||
cancelButton.addEventListener("click", () => {
|
|
||||||
this.finishCreateProgramWork(true);
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
const focusButton = clearEventListeners("work-in-progress-something-else-button");
|
|
||||||
focusButton.style.visibility = "hidden";
|
|
||||||
|
|
||||||
//Display Work In Progress Screen
|
|
||||||
Engine.loadWorkInProgressContent();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createProgramWork(numCycles) {
|
export function createProgramWork(numCycles) {
|
||||||
@ -1441,28 +1206,12 @@ export function createProgramWork(numCycles) {
|
|||||||
skillMult = 1 + (skillMult - 1) / 5; //The divider constant can be adjusted as necessary
|
skillMult = 1 + (skillMult - 1) / 5; //The divider constant can be adjusted as necessary
|
||||||
|
|
||||||
//Skill multiplier directly applied to "time worked"
|
//Skill multiplier directly applied to "time worked"
|
||||||
this.timeWorked += Engine._idleSpeed * numCycles;
|
this.timeWorked += CONSTANTS._idleSpeed * numCycles;
|
||||||
this.timeWorkedCreateProgram += Engine._idleSpeed * numCycles * skillMult;
|
this.timeWorkedCreateProgram += CONSTANTS._idleSpeed * numCycles * skillMult;
|
||||||
var programName = this.createProgramName;
|
|
||||||
|
|
||||||
if (this.timeWorkedCreateProgram >= this.timeNeededToCompleteWork) {
|
if (this.timeWorkedCreateProgram >= this.timeNeededToCompleteWork) {
|
||||||
this.finishCreateProgramWork(false);
|
this.finishCreateProgramWork(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
const elem = document.getElementById("work-in-progress-text");
|
|
||||||
ReactDOM.render(
|
|
||||||
<>
|
|
||||||
You are currently working on coding {programName}.<br />
|
|
||||||
<br />
|
|
||||||
You have been working for {convertTimeMsToTimeElapsedString(this.timeWorked)}
|
|
||||||
<br />
|
|
||||||
<br />
|
|
||||||
The program is {((this.timeWorkedCreateProgram / this.timeNeededToCompleteWork) * 100).toFixed(2)}
|
|
||||||
% complete. <br />
|
|
||||||
If you cancel, your work will be saved and you can come back to complete the program later.
|
|
||||||
</>,
|
|
||||||
elem,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function finishCreateProgramWork(cancelled) {
|
export function finishCreateProgramWork(cancelled) {
|
||||||
@ -1483,12 +1232,8 @@ export function finishCreateProgramWork(cancelled) {
|
|||||||
this.gainIntelligenceExp(this.createProgramReqLvl / CONSTANTS.IntelligenceProgramBaseExpGain);
|
this.gainIntelligenceExp(this.createProgramReqLvl / CONSTANTS.IntelligenceProgramBaseExpGain);
|
||||||
}
|
}
|
||||||
|
|
||||||
var mainMenu = document.getElementById("mainmenu-container");
|
|
||||||
mainMenu.style.visibility = "visible";
|
|
||||||
|
|
||||||
this.isWorking = false;
|
this.isWorking = false;
|
||||||
|
|
||||||
Engine.loadTerminalContent();
|
|
||||||
this.resetWorkStatus();
|
this.resetWorkStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1501,7 +1246,7 @@ export function startClass(costMult, expMult, className) {
|
|||||||
|
|
||||||
this.className = className;
|
this.className = className;
|
||||||
|
|
||||||
const gameCPS = 1000 / Engine._idleSpeed;
|
const gameCPS = 1000 / CONSTANTS._idleSpeed;
|
||||||
|
|
||||||
//Find cost and exp gain per game cycle
|
//Find cost and exp gain per game cycle
|
||||||
var cost = 0;
|
var cost = 0;
|
||||||
@ -1564,62 +1309,11 @@ export function startClass(costMult, expMult, className) {
|
|||||||
this.workDexExpGainRate = dexExp * this.dexterity_exp_mult * BitNodeMultipliers.ClassGymExpGain;
|
this.workDexExpGainRate = dexExp * this.dexterity_exp_mult * BitNodeMultipliers.ClassGymExpGain;
|
||||||
this.workAgiExpGainRate = agiExp * this.agility_exp_mult * BitNodeMultipliers.ClassGymExpGain;
|
this.workAgiExpGainRate = agiExp * this.agility_exp_mult * BitNodeMultipliers.ClassGymExpGain;
|
||||||
this.workChaExpGainRate = chaExp * this.charisma_exp_mult * BitNodeMultipliers.ClassGymExpGain;
|
this.workChaExpGainRate = chaExp * this.charisma_exp_mult * BitNodeMultipliers.ClassGymExpGain;
|
||||||
|
|
||||||
var cancelButton = clearEventListeners("work-in-progress-cancel-button");
|
|
||||||
if (
|
|
||||||
className == CONSTANTS.ClassGymStrength ||
|
|
||||||
className == CONSTANTS.ClassGymDefense ||
|
|
||||||
className == CONSTANTS.ClassGymDexterity ||
|
|
||||||
className == CONSTANTS.ClassGymAgility
|
|
||||||
) {
|
|
||||||
cancelButton.innerHTML = "Stop training at gym";
|
|
||||||
} else {
|
|
||||||
cancelButton.innerHTML = "Stop taking course";
|
|
||||||
}
|
|
||||||
cancelButton.addEventListener("click", () => {
|
|
||||||
this.finishClass();
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
const focusButton = clearEventListeners("work-in-progress-something-else-button");
|
|
||||||
focusButton.style.visibility = "hidden";
|
|
||||||
|
|
||||||
//Display Work In Progress Screen
|
|
||||||
Engine.loadWorkInProgressContent();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function takeClass(numCycles) {
|
export function takeClass(numCycles) {
|
||||||
this.timeWorked += Engine._idleSpeed * numCycles;
|
this.timeWorked += CONSTANTS._idleSpeed * numCycles;
|
||||||
var className = this.className;
|
|
||||||
|
|
||||||
this.processWorkEarnings(numCycles);
|
this.processWorkEarnings(numCycles);
|
||||||
|
|
||||||
const elem = document.getElementById("work-in-progress-text");
|
|
||||||
ReactDOM.render(
|
|
||||||
<>
|
|
||||||
You have been {className} for {convertTimeMsToTimeElapsedString(this.timeWorked)}
|
|
||||||
<br />
|
|
||||||
<br />
|
|
||||||
This has cost you: <br />
|
|
||||||
<Money money={-this.workMoneyGained} /> ({MoneyRate(this.workMoneyLossRate * CYCLES_PER_SEC)}) <br />
|
|
||||||
<br />
|
|
||||||
You have gained: <br />
|
|
||||||
{numeralWrapper.formatExp(this.workHackExpGained)} (
|
|
||||||
{numeralWrapper.formatExp(this.workHackExpGainRate * CYCLES_PER_SEC)} / sec) hacking exp <br />
|
|
||||||
{numeralWrapper.formatExp(this.workStrExpGained)} (
|
|
||||||
{numeralWrapper.formatExp(this.workStrExpGainRate * CYCLES_PER_SEC)} / sec) strength exp <br />
|
|
||||||
{numeralWrapper.formatExp(this.workDefExpGained)} (
|
|
||||||
{numeralWrapper.formatExp(this.workDefExpGainRate * CYCLES_PER_SEC)} / sec) defense exp <br />
|
|
||||||
{numeralWrapper.formatExp(this.workDexExpGained)} (
|
|
||||||
{numeralWrapper.formatExp(this.workDexExpGainRate * CYCLES_PER_SEC)} / sec) dexterity exp <br />
|
|
||||||
{numeralWrapper.formatExp(this.workAgiExpGained)} (
|
|
||||||
{numeralWrapper.formatExp(this.workAgiExpGainRate * CYCLES_PER_SEC)} / sec) agility exp <br />
|
|
||||||
{numeralWrapper.formatExp(this.workChaExpGained)} (
|
|
||||||
{numeralWrapper.formatExp(this.workChaExpGainRate * CYCLES_PER_SEC)} / sec) charisma exp <br />
|
|
||||||
You may cancel at any time
|
|
||||||
</>,
|
|
||||||
elem,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//The 'sing' argument defines whether or not this function was called
|
//The 'sing' argument defines whether or not this function was called
|
||||||
@ -1650,12 +1344,8 @@ export function finishClass(sing = false) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
var mainMenu = document.getElementById("mainmenu-container");
|
|
||||||
mainMenu.style.visibility = "visible";
|
|
||||||
|
|
||||||
this.isWorking = false;
|
this.isWorking = false;
|
||||||
|
|
||||||
Engine.loadLocationContent(false);
|
|
||||||
if (sing) {
|
if (sing) {
|
||||||
var res =
|
var res =
|
||||||
"After " +
|
"After " +
|
||||||
@ -1708,49 +1398,12 @@ export function startCrime(crimeType, hackExp, strExp, defExp, dexExp, agiExp, c
|
|||||||
this.workMoneyGained = money * this.crime_money_mult * BitNodeMultipliers.CrimeMoney;
|
this.workMoneyGained = money * this.crime_money_mult * BitNodeMultipliers.CrimeMoney;
|
||||||
|
|
||||||
this.timeNeededToCompleteWork = time;
|
this.timeNeededToCompleteWork = time;
|
||||||
|
|
||||||
//Remove all old event listeners from Cancel button
|
|
||||||
const newCancelButton = clearEventListeners("work-in-progress-cancel-button");
|
|
||||||
newCancelButton.innerHTML = "Cancel crime";
|
|
||||||
newCancelButton.addEventListener("click", () => {
|
|
||||||
this.finishCrime(true);
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
const focusButton = clearEventListeners("work-in-progress-something-else-button");
|
|
||||||
focusButton.style.visibility = "hidden";
|
|
||||||
|
|
||||||
//Display Work In Progress Screen
|
|
||||||
Engine.loadWorkInProgressContent();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function commitCrime(numCycles) {
|
export function commitCrime(numCycles) {
|
||||||
this.timeWorked += Engine._idleSpeed * numCycles;
|
this.timeWorked += CONSTANTS._idleSpeed * numCycles;
|
||||||
|
|
||||||
if (this.timeWorked >= this.timeNeededToCompleteWork) {
|
if (this.timeWorked >= this.timeNeededToCompleteWork) this.finishCrime(false);
|
||||||
this.finishCrime(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var percent = Math.round((this.timeWorked / this.timeNeededToCompleteWork) * 100);
|
|
||||||
var numBars = Math.round(percent / 5);
|
|
||||||
if (numBars < 0) {
|
|
||||||
numBars = 0;
|
|
||||||
}
|
|
||||||
if (numBars > 20) {
|
|
||||||
numBars = 20;
|
|
||||||
}
|
|
||||||
var progressBar = "[" + Array(numBars + 1).join("|") + Array(20 - numBars + 1).join(" ") + "]";
|
|
||||||
|
|
||||||
var txt = document.getElementById("work-in-progress-text");
|
|
||||||
txt.innerHTML =
|
|
||||||
"You are attempting to " +
|
|
||||||
this.crimeType +
|
|
||||||
".<br>" +
|
|
||||||
"Time remaining: " +
|
|
||||||
convertTimeMsToTimeElapsedString(this.timeNeededToCompleteWork - this.timeWorked) +
|
|
||||||
"<br>" +
|
|
||||||
progressBar.replace(/ /g, " ");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function finishCrime(cancelled) {
|
export function finishCrime(cancelled) {
|
||||||
@ -1892,11 +1545,9 @@ export function finishCrime(cancelled) {
|
|||||||
}
|
}
|
||||||
this.committingCrimeThruSingFn = false;
|
this.committingCrimeThruSingFn = false;
|
||||||
this.singFnCrimeWorkerScript = null;
|
this.singFnCrimeWorkerScript = null;
|
||||||
var mainMenu = document.getElementById("mainmenu-container");
|
|
||||||
mainMenu.style.visibility = "visible";
|
|
||||||
this.isWorking = false;
|
this.isWorking = false;
|
||||||
|
this.crimeType = "";
|
||||||
this.resetWorkStatus();
|
this.resetWorkStatus();
|
||||||
Engine.loadLocationContent(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Cancels the player's current "work" assignment and gives the proper rewards
|
//Cancels the player's current "work" assignment and gives the proper rewards
|
||||||
|
@ -20,7 +20,7 @@ export function SleeveRoot(props: IProps): React.ReactElement {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ width: "70%" }}>
|
<>
|
||||||
<h1>Sleeves</h1>
|
<h1>Sleeves</h1>
|
||||||
<p>
|
<p>
|
||||||
Duplicate Sleeves are MK-V Synthoids (synthetic androids) into which your consciousness has been copied. In
|
Duplicate Sleeves are MK-V Synthoids (synthetic androids) into which your consciousness has been copied. In
|
||||||
@ -50,6 +50,6 @@ export function SleeveRoot(props: IProps): React.ReactElement {
|
|||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
2
src/Prestige.d.ts
vendored
Normal file
2
src/Prestige.d.ts
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
export declare function prestigeAugmentation(): void;
|
||||||
|
export declare function prestigeSourceFile(flume: boolean): void;
|
@ -3,7 +3,6 @@ import { augmentationExists, initAugmentations } from "./Augmentation/Augmentati
|
|||||||
import { AugmentationNames } from "./Augmentation/data/AugmentationNames";
|
import { AugmentationNames } from "./Augmentation/data/AugmentationNames";
|
||||||
import { initBitNodeMultipliers } from "./BitNode/BitNode";
|
import { initBitNodeMultipliers } from "./BitNode/BitNode";
|
||||||
import { Bladeburner } from "./Bladeburner/Bladeburner";
|
import { Bladeburner } from "./Bladeburner/Bladeburner";
|
||||||
import { writeCinematicText } from "./CinematicText";
|
|
||||||
import { Companies, initCompanies } from "./Company/Companies";
|
import { Companies, initCompanies } from "./Company/Companies";
|
||||||
import { resetIndustryResearchTrees } from "./Corporation/IndustryData";
|
import { resetIndustryResearchTrees } from "./Corporation/IndustryData";
|
||||||
import { Programs } from "./Programs/Programs";
|
import { Programs } from "./Programs/Programs";
|
||||||
@ -25,13 +24,7 @@ import { SpecialServerIps, prestigeSpecialServerIps, SpecialServerNames } from "
|
|||||||
import { deleteStockMarket, initStockMarket, initSymbolToStockMap } from "./StockMarket/StockMarket";
|
import { deleteStockMarket, initStockMarket, initSymbolToStockMap } from "./StockMarket/StockMarket";
|
||||||
import { Terminal } from "./Terminal";
|
import { Terminal } from "./Terminal";
|
||||||
|
|
||||||
import { Page, routing } from "./ui/navigationTracking";
|
|
||||||
|
|
||||||
import { dialogBoxCreate } from "../utils/DialogBox";
|
import { dialogBoxCreate } from "../utils/DialogBox";
|
||||||
import { exceptionAlert } from "../utils/helpers/exceptionAlert";
|
|
||||||
import { removeElementById } from "../utils/uiHelpers/removeElementById";
|
|
||||||
import { createElement } from "../utils/uiHelpers/createElement";
|
|
||||||
import { createPopup } from "../utils/uiHelpers/createPopup";
|
|
||||||
|
|
||||||
import Decimal from "decimal.js";
|
import Decimal from "decimal.js";
|
||||||
|
|
||||||
@ -39,9 +32,6 @@ const BitNode8StartingMoney = 250e6;
|
|||||||
|
|
||||||
// Prestige by purchasing augmentation
|
// Prestige by purchasing augmentation
|
||||||
function prestigeAugmentation() {
|
function prestigeAugmentation() {
|
||||||
// Set Navigation to Terminal screen, for any logic that depends on it
|
|
||||||
routing.navigateTo(Page.Terminal);
|
|
||||||
|
|
||||||
initBitNodeMultipliers(Player);
|
initBitNodeMultipliers(Player);
|
||||||
|
|
||||||
const megaCorpFactions = [
|
const megaCorpFactions = [
|
||||||
@ -62,9 +52,6 @@ function prestigeAugmentation() {
|
|||||||
});
|
});
|
||||||
Player.prestigeAugmentation();
|
Player.prestigeAugmentation();
|
||||||
|
|
||||||
Terminal.clear();
|
|
||||||
Engine.loadTerminalContent();
|
|
||||||
|
|
||||||
// Delete all Worker Scripts objects
|
// Delete all Worker Scripts objects
|
||||||
prestigeWorkerScripts();
|
prestigeWorkerScripts();
|
||||||
|
|
||||||
@ -244,11 +231,6 @@ function prestigeSourceFile(flume) {
|
|||||||
// Messages
|
// Messages
|
||||||
initMessages();
|
initMessages();
|
||||||
|
|
||||||
var mainMenu = document.getElementById("mainmenu-container");
|
|
||||||
mainMenu.style.visibility = "visible";
|
|
||||||
Terminal.clear();
|
|
||||||
Engine.loadTerminalContent();
|
|
||||||
|
|
||||||
// BitNode 3: Corporatocracy
|
// BitNode 3: Corporatocracy
|
||||||
if (Player.bitNodeN === 3) {
|
if (Player.bitNodeN === 3) {
|
||||||
homeComp.messages.push(LiteratureNames.CorporationManagementHandbook);
|
homeComp.messages.push(LiteratureNames.CorporationManagementHandbook);
|
||||||
@ -258,56 +240,6 @@ function prestigeSourceFile(flume) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// BitNode 6: Bladeburner
|
|
||||||
if (Player.bitNodeN === 6) {
|
|
||||||
var cinematicText = [
|
|
||||||
"In the middle of the 21st century, OmniTek Incorporated advanced robot evolution " +
|
|
||||||
"with their Synthoids (synthetic androids), a being virtually identical to a human.",
|
|
||||||
"------",
|
|
||||||
"Their sixth-generation Synthoids, called MK-VI, were stronger, faster, and more " +
|
|
||||||
"intelligent than humans. Many argued that the MK-VI Synthoids were the first " +
|
|
||||||
"example of sentient AI.",
|
|
||||||
"------",
|
|
||||||
"Unfortunately, in 2070 a terrorist group called Ascendis Totalis hacked into OmniTek and " +
|
|
||||||
"uploaded a rogue AI into their Synthoid manufacturing facilities.",
|
|
||||||
"------",
|
|
||||||
"The MK-VI Synthoids infected by the rogue AI turned hostile toward humanity, initiating " +
|
|
||||||
"the deadliest conflict in human history. This dark chapter is now known as the Synthoid Uprising.",
|
|
||||||
"------",
|
|
||||||
"In the aftermath of the Uprising, further manufacturing of Synthoids with advanced AI " +
|
|
||||||
"was banned. MK-VI Synthoids that did not have the rogue Ascendis Totalis AI were " +
|
|
||||||
"allowed to continue their existence.",
|
|
||||||
"------",
|
|
||||||
"The intelligence community believes that not all of the rogue MK-VI Synthoids from the Uprising were " +
|
|
||||||
"found and destroyed, and that many of them are blending in as normal humans in society today. " +
|
|
||||||
"As a result, many nations have created Bladeburner divisions, special units that are tasked with " +
|
|
||||||
"investigating and dealing with Synthoid threats.",
|
|
||||||
];
|
|
||||||
writeCinematicText(cinematicText)
|
|
||||||
.then(function () {
|
|
||||||
var popupId = "bladeburner-bitnode-start-nsa-notification";
|
|
||||||
var txt = createElement("p", {
|
|
||||||
innerText:
|
|
||||||
"Visit the National Security Agency (NSA) to apply for their Bladeburner " +
|
|
||||||
"division! You will need 100 of each combat stat before doing this.",
|
|
||||||
});
|
|
||||||
var brEl = createElement("br");
|
|
||||||
var okBtn = createElement("a", {
|
|
||||||
class: "a-link-button",
|
|
||||||
innerText: "Got it!",
|
|
||||||
padding: "8px",
|
|
||||||
clickListener: () => {
|
|
||||||
removeElementById(popupId);
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
});
|
|
||||||
createPopup(popupId, [txt, brEl, okBtn]);
|
|
||||||
})
|
|
||||||
.catch(function (e) {
|
|
||||||
exceptionAlert(e);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// BitNode 8: Ghost of Wall Street
|
// BitNode 8: Ghost of Wall Street
|
||||||
if (Player.bitNodeN === 8) {
|
if (Player.bitNodeN === 8) {
|
||||||
Player.money = new Decimal(BitNode8StartingMoney);
|
Player.money = new Decimal(BitNode8StartingMoney);
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { BaseServer } from "../Server/BaseServer";
|
import { BaseServer } from "../Server/BaseServer";
|
||||||
import { ITerminal } from "../Terminal/ITerminal";
|
import { ITerminal } from "../Terminal/ITerminal";
|
||||||
import { IPlayer } from "../PersonObjects/IPlayer";
|
import { IPlayer } from "../PersonObjects/IPlayer";
|
||||||
|
import { IRouter } from "../ui/Router";
|
||||||
|
|
||||||
export interface IProgramCreate {
|
export interface IProgramCreate {
|
||||||
level: number;
|
level: number;
|
||||||
@ -12,12 +13,12 @@ export interface IProgramCreate {
|
|||||||
export class Program {
|
export class Program {
|
||||||
name = "";
|
name = "";
|
||||||
create: IProgramCreate | null;
|
create: IProgramCreate | null;
|
||||||
run: (terminal: ITerminal, player: IPlayer, server: BaseServer, args: string[]) => void;
|
run: (router: IRouter, terminal: ITerminal, player: IPlayer, server: BaseServer, args: string[]) => void;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
name: string,
|
name: string,
|
||||||
create: IProgramCreate | null,
|
create: IProgramCreate | null,
|
||||||
run: (terminal: ITerminal, player: IPlayer, server: BaseServer, args: string[]) => void,
|
run: (router: IRouter, terminal: ITerminal, player: IPlayer, server: BaseServer, args: string[]) => void,
|
||||||
) {
|
) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.create = create;
|
this.create = create;
|
||||||
|
@ -3,6 +3,7 @@ import { CONSTANTS } from "../../Constants";
|
|||||||
import { BaseServer } from "../../Server/BaseServer";
|
import { BaseServer } from "../../Server/BaseServer";
|
||||||
import { Server } from "../../Server/Server";
|
import { Server } from "../../Server/Server";
|
||||||
import { ITerminal } from "../../Terminal/ITerminal";
|
import { ITerminal } from "../../Terminal/ITerminal";
|
||||||
|
import { IRouter } from "../../ui/Router";
|
||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||||
import { HacknetServer } from "../../Hacknet/HacknetServer";
|
import { HacknetServer } from "../../Hacknet/HacknetServer";
|
||||||
import { convertTimeMsToTimeElapsedString } from "../../../utils/StringHelperFunctions";
|
import { convertTimeMsToTimeElapsedString } from "../../../utils/StringHelperFunctions";
|
||||||
@ -30,7 +31,7 @@ export interface IProgramCreationParams {
|
|||||||
key: string;
|
key: string;
|
||||||
name: string;
|
name: string;
|
||||||
create: IProgramCreate | null;
|
create: IProgramCreate | null;
|
||||||
run: (terminal: ITerminal, player: IPlayer, server: BaseServer, args: string[]) => void;
|
run: (router: IRouter, terminal: ITerminal, player: IPlayer, server: BaseServer, args: string[]) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const programsMetadata: IProgramCreationParams[] = [
|
export const programsMetadata: IProgramCreationParams[] = [
|
||||||
@ -43,7 +44,7 @@ export const programsMetadata: IProgramCreationParams[] = [
|
|||||||
req: requireHackingLevel(1),
|
req: requireHackingLevel(1),
|
||||||
time: CONSTANTS.MillisecondsPerFiveMinutes,
|
time: CONSTANTS.MillisecondsPerFiveMinutes,
|
||||||
},
|
},
|
||||||
run: (terminal: ITerminal, player: IPlayer, server: BaseServer): void => {
|
run: (router: IRouter, terminal: ITerminal, player: IPlayer, server: BaseServer): void => {
|
||||||
if (!(server instanceof Server)) {
|
if (!(server instanceof Server)) {
|
||||||
terminal.error("Cannot nuke this kind of server.");
|
terminal.error("Cannot nuke this kind of server.");
|
||||||
return;
|
return;
|
||||||
@ -72,7 +73,7 @@ export const programsMetadata: IProgramCreationParams[] = [
|
|||||||
req: requireHackingLevel(50),
|
req: requireHackingLevel(50),
|
||||||
time: CONSTANTS.MillisecondsPerFiveMinutes * 2,
|
time: CONSTANTS.MillisecondsPerFiveMinutes * 2,
|
||||||
},
|
},
|
||||||
run: (terminal: ITerminal, player: IPlayer, server: BaseServer): void => {
|
run: (router: IRouter, terminal: ITerminal, player: IPlayer, server: BaseServer): void => {
|
||||||
if (!(server instanceof Server)) {
|
if (!(server instanceof Server)) {
|
||||||
terminal.error("Cannot run BruteSSH.exe on this kind of server.");
|
terminal.error("Cannot run BruteSSH.exe on this kind of server.");
|
||||||
return;
|
return;
|
||||||
@ -96,7 +97,7 @@ export const programsMetadata: IProgramCreationParams[] = [
|
|||||||
req: requireHackingLevel(100),
|
req: requireHackingLevel(100),
|
||||||
time: CONSTANTS.MillisecondsPerHalfHour,
|
time: CONSTANTS.MillisecondsPerHalfHour,
|
||||||
},
|
},
|
||||||
run: (terminal: ITerminal, player: IPlayer, server: BaseServer): void => {
|
run: (router: IRouter, terminal: ITerminal, player: IPlayer, server: BaseServer): void => {
|
||||||
if (!(server instanceof Server)) {
|
if (!(server instanceof Server)) {
|
||||||
terminal.error("Cannot run FTPCrack.exe on this kind of server.");
|
terminal.error("Cannot run FTPCrack.exe on this kind of server.");
|
||||||
return;
|
return;
|
||||||
@ -120,7 +121,7 @@ export const programsMetadata: IProgramCreationParams[] = [
|
|||||||
req: requireHackingLevel(250),
|
req: requireHackingLevel(250),
|
||||||
time: CONSTANTS.MillisecondsPer2Hours,
|
time: CONSTANTS.MillisecondsPer2Hours,
|
||||||
},
|
},
|
||||||
run: (terminal: ITerminal, player: IPlayer, server: BaseServer): void => {
|
run: (router: IRouter, terminal: ITerminal, player: IPlayer, server: BaseServer): void => {
|
||||||
if (!(server instanceof Server)) {
|
if (!(server instanceof Server)) {
|
||||||
terminal.error("Cannot run relaySMTP.exe on this kind of server.");
|
terminal.error("Cannot run relaySMTP.exe on this kind of server.");
|
||||||
return;
|
return;
|
||||||
@ -144,7 +145,7 @@ export const programsMetadata: IProgramCreationParams[] = [
|
|||||||
req: requireHackingLevel(500),
|
req: requireHackingLevel(500),
|
||||||
time: CONSTANTS.MillisecondsPer4Hours,
|
time: CONSTANTS.MillisecondsPer4Hours,
|
||||||
},
|
},
|
||||||
run: (terminal: ITerminal, player: IPlayer, server: BaseServer): void => {
|
run: (router: IRouter, terminal: ITerminal, player: IPlayer, server: BaseServer): void => {
|
||||||
if (!(server instanceof Server)) {
|
if (!(server instanceof Server)) {
|
||||||
terminal.error("Cannot run HTTPWorm.exe on this kind of server.");
|
terminal.error("Cannot run HTTPWorm.exe on this kind of server.");
|
||||||
return;
|
return;
|
||||||
@ -168,7 +169,7 @@ export const programsMetadata: IProgramCreationParams[] = [
|
|||||||
req: requireHackingLevel(750),
|
req: requireHackingLevel(750),
|
||||||
time: CONSTANTS.MillisecondsPer8Hours,
|
time: CONSTANTS.MillisecondsPer8Hours,
|
||||||
},
|
},
|
||||||
run: (terminal: ITerminal, player: IPlayer, server: BaseServer): void => {
|
run: (router: IRouter, terminal: ITerminal, player: IPlayer, server: BaseServer): void => {
|
||||||
if (!(server instanceof Server)) {
|
if (!(server instanceof Server)) {
|
||||||
terminal.error("Cannot run SQLInject.exe on this kind of server.");
|
terminal.error("Cannot run SQLInject.exe on this kind of server.");
|
||||||
return;
|
return;
|
||||||
@ -192,7 +193,7 @@ export const programsMetadata: IProgramCreationParams[] = [
|
|||||||
req: requireHackingLevel(75),
|
req: requireHackingLevel(75),
|
||||||
time: CONSTANTS.MillisecondsPerQuarterHour,
|
time: CONSTANTS.MillisecondsPerQuarterHour,
|
||||||
},
|
},
|
||||||
run: (terminal: ITerminal): void => {
|
run: (router: IRouter, terminal: ITerminal): void => {
|
||||||
terminal.print("This executable cannot be run.");
|
terminal.print("This executable cannot be run.");
|
||||||
terminal.print("DeepscanV1.exe lets you run 'scan-analyze' with a depth up to 5.");
|
terminal.print("DeepscanV1.exe lets you run 'scan-analyze' with a depth up to 5.");
|
||||||
},
|
},
|
||||||
@ -206,7 +207,7 @@ export const programsMetadata: IProgramCreationParams[] = [
|
|||||||
req: requireHackingLevel(400),
|
req: requireHackingLevel(400),
|
||||||
time: CONSTANTS.MillisecondsPer2Hours,
|
time: CONSTANTS.MillisecondsPer2Hours,
|
||||||
},
|
},
|
||||||
run: (terminal: ITerminal): void => {
|
run: (router: IRouter, terminal: ITerminal): void => {
|
||||||
terminal.print("This executable cannot be run.");
|
terminal.print("This executable cannot be run.");
|
||||||
terminal.print("DeepscanV2.exe lets you run 'scan-analyze' with a depth up to 10.");
|
terminal.print("DeepscanV2.exe lets you run 'scan-analyze' with a depth up to 10.");
|
||||||
},
|
},
|
||||||
@ -220,7 +221,7 @@ export const programsMetadata: IProgramCreationParams[] = [
|
|||||||
req: requireHackingLevel(75),
|
req: requireHackingLevel(75),
|
||||||
time: CONSTANTS.MillisecondsPerHalfHour,
|
time: CONSTANTS.MillisecondsPerHalfHour,
|
||||||
},
|
},
|
||||||
run: (terminal: ITerminal, player: IPlayer, server: BaseServer, args: string[]): void => {
|
run: (router: IRouter, terminal: ITerminal, player: IPlayer, server: BaseServer, args: string[]): void => {
|
||||||
if (args.length !== 1) {
|
if (args.length !== 1) {
|
||||||
terminal.print("Must pass a server hostname or IP as an argument for ServerProfiler.exe");
|
terminal.print("Must pass a server hostname or IP as an argument for ServerProfiler.exe");
|
||||||
return;
|
return;
|
||||||
@ -270,7 +271,7 @@ export const programsMetadata: IProgramCreationParams[] = [
|
|||||||
req: requireHackingLevel(25),
|
req: requireHackingLevel(25),
|
||||||
time: CONSTANTS.MillisecondsPerQuarterHour,
|
time: CONSTANTS.MillisecondsPerQuarterHour,
|
||||||
},
|
},
|
||||||
run: (terminal: ITerminal): void => {
|
run: (router: IRouter, terminal: ITerminal): void => {
|
||||||
terminal.print("This executable cannot be run.");
|
terminal.print("This executable cannot be run.");
|
||||||
terminal.print("AutoLink.exe lets you automatically connect to other servers when using 'scan-analyze'.");
|
terminal.print("AutoLink.exe lets you automatically connect to other servers when using 'scan-analyze'.");
|
||||||
terminal.print("When using scan-analyze, click on a server's hostname to connect to it.");
|
terminal.print("When using scan-analyze, click on a server's hostname to connect to it.");
|
||||||
@ -285,10 +286,11 @@ export const programsMetadata: IProgramCreationParams[] = [
|
|||||||
req: bitFlumeRequirements(),
|
req: bitFlumeRequirements(),
|
||||||
time: CONSTANTS.MillisecondsPerFiveMinutes / 20,
|
time: CONSTANTS.MillisecondsPerFiveMinutes / 20,
|
||||||
},
|
},
|
||||||
run: (terminal: ITerminal, player: IPlayer): void => {
|
run: (router: IRouter, terminal: ITerminal, player: IPlayer): void => {
|
||||||
const popupId = "bitflume-popup";
|
const popupId = "bitflume-popup";
|
||||||
createPopup(popupId, BitFlumePopup, {
|
createPopup(popupId, BitFlumePopup, {
|
||||||
player: player,
|
player: player,
|
||||||
|
router: router,
|
||||||
popupId: popupId,
|
popupId: popupId,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -297,7 +299,7 @@ export const programsMetadata: IProgramCreationParams[] = [
|
|||||||
key: "Flight",
|
key: "Flight",
|
||||||
name: "fl1ght.exe",
|
name: "fl1ght.exe",
|
||||||
create: null,
|
create: null,
|
||||||
run: (terminal: ITerminal, player: IPlayer): void => {
|
run: (router: IRouter, terminal: ITerminal, player: IPlayer): void => {
|
||||||
const numAugReq = Math.round(BitNodeMultipliers.DaedalusAugsRequirement * 30);
|
const numAugReq = Math.round(BitNodeMultipliers.DaedalusAugsRequirement * 30);
|
||||||
const fulfilled =
|
const fulfilled =
|
||||||
player.augmentations.length >= numAugReq && player.money.gt(1e11) && player.hacking_skill >= 2500;
|
player.augmentations.length >= numAugReq && player.money.gt(1e11) && player.hacking_skill >= 2500;
|
||||||
|
@ -1,15 +1,13 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
import { use } from "../../ui/Context";
|
||||||
import { getAvailableCreatePrograms } from "../ProgramHelpers";
|
import { getAvailableCreatePrograms } from "../ProgramHelpers";
|
||||||
|
|
||||||
import { Box, ButtonGroup, Tooltip, Typography } from "@mui/material";
|
import { Box, ButtonGroup, Tooltip, Typography } from "@mui/material";
|
||||||
import Button from "@mui/material/Button";
|
import Button from "@mui/material/Button";
|
||||||
|
|
||||||
interface IProps {
|
export function ProgramsRoot(): React.ReactElement {
|
||||||
player: IPlayer;
|
const player = use.Player();
|
||||||
}
|
const router = use.Router();
|
||||||
|
|
||||||
export function ProgramsRoot(props: IProps): React.ReactElement {
|
|
||||||
const setRerender = useState(false)[1];
|
const setRerender = useState(false)[1];
|
||||||
function rerender(): void {
|
function rerender(): void {
|
||||||
setRerender((old) => !old);
|
setRerender((old) => !old);
|
||||||
@ -25,26 +23,31 @@ export function ProgramsRoot(props: IProps): React.ReactElement {
|
|||||||
<div>
|
<div>
|
||||||
<Box>
|
<Box>
|
||||||
<Typography>
|
<Typography>
|
||||||
This page displays any programs that you are able to create. Writing the code for a program takes time, which
|
This page displays any programs that you are able to create. Writing the code for a program takes time,
|
||||||
can vary based on how complex the program is. If you are working on creating a program you can cancel at any
|
which can vary based on how complex the program is. If you are working on creating a program you can cancel
|
||||||
time. Your progress will be saved and you can continue later.
|
at any time. Your progress will be saved and you can continue later.
|
||||||
</Typography>
|
</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
<ButtonGroup>
|
<ButtonGroup>
|
||||||
{getAvailableCreatePrograms(props.player).map((program) => {
|
{getAvailableCreatePrograms(player).map((program) => {
|
||||||
const create = program.create;
|
const create = program.create;
|
||||||
if (create === null) return <></>;
|
if (create === null) return <></>;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tooltip title={create.tooltip}>
|
<Tooltip key={program.name} title={create.tooltip}>
|
||||||
<Button onClick={() => props.player.startCreateProgramWork(program.name, create.time, create.level)}>
|
<Button
|
||||||
{program.name}
|
onClick={() => {
|
||||||
|
player.startCreateProgramWork(program.name, create.time, create.level);
|
||||||
|
router.toWork();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{program.name}
|
||||||
</Button>
|
</Button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
)
|
);
|
||||||
})}
|
})}
|
||||||
</ButtonGroup>
|
</ButtonGroup>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
6
src/RedPill.d.ts
vendored
6
src/RedPill.d.ts
vendored
@ -1,6 +1,2 @@
|
|||||||
export declare let redPillFlag: boolean;
|
export declare let redPillFlag: boolean;
|
||||||
export declare function hackWorldDaemon(
|
export declare function enterBitNode(router: IRouter, flume: boolean, destroyedBitNode: number, newBitNode: number);
|
||||||
currentNodeNumber: number,
|
|
||||||
flume: boolean = false,
|
|
||||||
quick: boolean = false,
|
|
||||||
): void;
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* Implementation for what happens when you destroy a BitNode
|
* Implementation for what happens when you destroy a BitNode
|
||||||
*/
|
*/
|
||||||
import { Engine } from "./engine";
|
|
||||||
import { Player } from "./Player";
|
import { Player } from "./Player";
|
||||||
import { prestigeSourceFile } from "./Prestige";
|
import { prestigeSourceFile } from "./Prestige";
|
||||||
import { PlayerOwnedSourceFile } from "./SourceFile/PlayerOwnedSourceFile";
|
import { PlayerOwnedSourceFile } from "./SourceFile/PlayerOwnedSourceFile";
|
||||||
@ -9,20 +8,10 @@ import { SourceFileFlags } from "./SourceFile/SourceFileFlags";
|
|||||||
import { SourceFiles } from "./SourceFile/SourceFiles";
|
import { SourceFiles } from "./SourceFile/SourceFiles";
|
||||||
|
|
||||||
import { dialogBoxCreate } from "../utils/DialogBox";
|
import { dialogBoxCreate } from "../utils/DialogBox";
|
||||||
import { BitverseRoot } from "./BitNode/ui/BitverseRoot";
|
|
||||||
import React from "react";
|
|
||||||
import ReactDOM from "react-dom";
|
|
||||||
|
|
||||||
let redPillFlag = false;
|
let redPillFlag = false;
|
||||||
function hackWorldDaemon(currentNodeNumber, flume = false, quick = false) {
|
function hackWorldDaemon(router, flume = false, quick = false) {
|
||||||
// Clear the screen
|
router.toBitVerse(flume, quick);
|
||||||
const container = document.getElementById("red-pill-container");
|
|
||||||
ReactDOM.unmountComponentAtNode(container);
|
|
||||||
Engine.loadRedPillContent();
|
|
||||||
ReactDOM.render(
|
|
||||||
<BitverseRoot destroyedBitNodeNum={currentNodeNumber} flume={flume} enter={enterBitNode} quick={quick} />,
|
|
||||||
container,
|
|
||||||
);
|
|
||||||
redPillFlag = true;
|
redPillFlag = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,12 +57,12 @@ function giveSourceFile(bitNodeNumber) {
|
|||||||
Player.intelligence = 1;
|
Player.intelligence = 1;
|
||||||
}
|
}
|
||||||
dialogBoxCreate(
|
dialogBoxCreate(
|
||||||
"You received a Source-File for destroying a Bit Node!<br><br>" + sourceFile.name + "<br><br>" + sourceFile.info,
|
"You received a Source-File for destroying a BitNode!<br><br>" + sourceFile.name + "<br><br>" + sourceFile.info,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function enterBitNode(flume, destroyedBitNode, newBitNode) {
|
export function enterBitNode(router, flume, destroyedBitNode, newBitNode) {
|
||||||
if (!flume) {
|
if (!flume) {
|
||||||
giveSourceFile(destroyedBitNode);
|
giveSourceFile(destroyedBitNode);
|
||||||
} else {
|
} else {
|
||||||
@ -86,12 +75,14 @@ function enterBitNode(flume, destroyedBitNode, newBitNode) {
|
|||||||
Player.intelligence = 1;
|
Player.intelligence = 1;
|
||||||
}
|
}
|
||||||
redPillFlag = false;
|
redPillFlag = false;
|
||||||
const container = document.getElementById("red-pill-container");
|
|
||||||
ReactDOM.unmountComponentAtNode(container);
|
|
||||||
|
|
||||||
// Set new Bit Node
|
// Set new Bit Node
|
||||||
Player.bitNodeN = newBitNode;
|
Player.bitNodeN = newBitNode;
|
||||||
|
|
||||||
|
if (newBitNode === 6) {
|
||||||
|
router.toBladeburnerCinematic();
|
||||||
|
} else {
|
||||||
|
router.toTerminal();
|
||||||
|
}
|
||||||
prestigeSourceFile(flume);
|
prestigeSourceFile(flume);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
*/
|
*/
|
||||||
import { calculateRamUsage } from "./RamCalculations";
|
import { calculateRamUsage } from "./RamCalculations";
|
||||||
import { ScriptUrl } from "./ScriptUrl";
|
import { ScriptUrl } from "./ScriptUrl";
|
||||||
import { Page, routing } from "../ui/navigationTracking";
|
|
||||||
|
|
||||||
import { setTimeoutRef } from "../utils/SetTimeoutRef";
|
import { setTimeoutRef } from "../utils/SetTimeoutRef";
|
||||||
import { Generic_fromJSON, Generic_toJSON, Reviver } from "../../utils/JSONReviver";
|
import { Generic_fromJSON, Generic_toJSON, Reviver } from "../../utils/JSONReviver";
|
||||||
@ -93,22 +92,18 @@ export class Script {
|
|||||||
* @param {Script[]} otherScripts - Other scripts on the server. Used to process imports
|
* @param {Script[]} otherScripts - Other scripts on the server. Used to process imports
|
||||||
*/
|
*/
|
||||||
saveScript(code: string, serverIp: string, otherScripts: Script[]): void {
|
saveScript(code: string, serverIp: string, otherScripts: Script[]): void {
|
||||||
if (routing.isOn(Page.ScriptEditor)) {
|
// Update code and filename
|
||||||
// Update code and filename
|
this.code = code.replace(/^\s+|\s+$/g, "");
|
||||||
this.code = code.replace(/^\s+|\s+$/g, "");
|
|
||||||
|
|
||||||
const filenameElem: HTMLInputElement | null = document.getElementById(
|
const filenameElem: HTMLInputElement | null = document.getElementById("script-editor-filename") as HTMLInputElement;
|
||||||
"script-editor-filename",
|
if (filenameElem == null) {
|
||||||
) as HTMLInputElement;
|
console.error(`Failed to get Script filename DOM element`);
|
||||||
if (filenameElem == null) {
|
return;
|
||||||
console.error(`Failed to get Script filename DOM element`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.filename = filenameElem.value;
|
|
||||||
this.server = serverIp;
|
|
||||||
this.updateRamUsage(otherScripts);
|
|
||||||
this.markUpdated();
|
|
||||||
}
|
}
|
||||||
|
this.filename = filenameElem.value;
|
||||||
|
this.server = serverIp;
|
||||||
|
this.updateRamUsage(otherScripts);
|
||||||
|
this.markUpdated();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -9,7 +9,7 @@ import { Options } from "./Options";
|
|||||||
import { js_beautify as beautifyCode } from "js-beautify";
|
import { js_beautify as beautifyCode } from "js-beautify";
|
||||||
import { isValidFilePath } from "../../Terminal/DirectoryHelpers";
|
import { isValidFilePath } from "../../Terminal/DirectoryHelpers";
|
||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||||
import { IEngine } from "../../IEngine";
|
import { IRouter } from "../../ui/Router";
|
||||||
import { dialogBoxCreate } from "../../../utils/DialogBox";
|
import { dialogBoxCreate } from "../../../utils/DialogBox";
|
||||||
import { parseFconfSettings } from "../../Fconf/Fconf";
|
import { parseFconfSettings } from "../../Fconf/Fconf";
|
||||||
import { isScriptFilename } from "../../Script/ScriptHelpersTS";
|
import { isScriptFilename } from "../../Script/ScriptHelpersTS";
|
||||||
@ -53,7 +53,7 @@ interface IProps {
|
|||||||
filename: string;
|
filename: string;
|
||||||
code: string;
|
code: string;
|
||||||
player: IPlayer;
|
player: IPlayer;
|
||||||
engine: IEngine;
|
router: IRouter;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -103,7 +103,6 @@ export function Root(props: IProps): React.ReactElement {
|
|||||||
}
|
}
|
||||||
lastPosition = null;
|
lastPosition = null;
|
||||||
|
|
||||||
// TODO(hydroflame): re-enable the tutorial.
|
|
||||||
if (ITutorial.isRunning && ITutorial.currStep === iTutorialSteps.TerminalTypeScript) {
|
if (ITutorial.isRunning && ITutorial.currStep === iTutorialSteps.TerminalTypeScript) {
|
||||||
//Make sure filename + code properly follow tutorial
|
//Make sure filename + code properly follow tutorial
|
||||||
if (filename !== "n00dles.script") {
|
if (filename !== "n00dles.script") {
|
||||||
@ -121,7 +120,7 @@ export function Root(props: IProps): React.ReactElement {
|
|||||||
for (let i = 0; i < server.scripts.length; i++) {
|
for (let i = 0; i < server.scripts.length; i++) {
|
||||||
if (filename == server.scripts[i].filename) {
|
if (filename == server.scripts[i].filename) {
|
||||||
server.scripts[i].saveScript(code, props.player.currentServer, server.scripts);
|
server.scripts[i].saveScript(code, props.player.currentServer, server.scripts);
|
||||||
props.engine.loadTerminalContent();
|
props.router.toTerminal();
|
||||||
return iTutorialNextStep();
|
return iTutorialNextStep();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -160,7 +159,7 @@ export function Root(props: IProps): React.ReactElement {
|
|||||||
for (let i = 0; i < server.scripts.length; i++) {
|
for (let i = 0; i < server.scripts.length; i++) {
|
||||||
if (filename == server.scripts[i].filename) {
|
if (filename == server.scripts[i].filename) {
|
||||||
server.scripts[i].saveScript(code, props.player.currentServer, server.scripts);
|
server.scripts[i].saveScript(code, props.player.currentServer, server.scripts);
|
||||||
props.engine.loadTerminalContent();
|
props.router.toTerminal();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -173,7 +172,7 @@ export function Root(props: IProps): React.ReactElement {
|
|||||||
for (let i = 0; i < server.textFiles.length; ++i) {
|
for (let i = 0; i < server.textFiles.length; ++i) {
|
||||||
if (server.textFiles[i].fn === filename) {
|
if (server.textFiles[i].fn === filename) {
|
||||||
server.textFiles[i].write(code);
|
server.textFiles[i].write(code);
|
||||||
props.engine.loadTerminalContent();
|
props.router.toTerminal();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -183,7 +182,7 @@ export function Root(props: IProps): React.ReactElement {
|
|||||||
dialogBoxCreate("Invalid filename. Must be either a script (.script, .js, or .ns) or " + " or text file (.txt)");
|
dialogBoxCreate("Invalid filename. Must be either a script (.script, .js, or .ns) or " + " or text file (.txt)");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
props.engine.loadTerminalContent();
|
props.router.toTerminal();
|
||||||
}
|
}
|
||||||
|
|
||||||
function beautify(): void {
|
function beautify(): void {
|
||||||
@ -308,7 +307,7 @@ export function Root(props: IProps): React.ReactElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="script-editor-wrapper">
|
<>
|
||||||
<div id="script-editor-filename-wrapper">
|
<div id="script-editor-filename-wrapper">
|
||||||
<p id="script-editor-filename-tag" className="noselect">
|
<p id="script-editor-filename-tag" className="noselect">
|
||||||
{" "}
|
{" "}
|
||||||
@ -328,7 +327,7 @@ export function Root(props: IProps): React.ReactElement {
|
|||||||
beforeMount={beforeMount}
|
beforeMount={beforeMount}
|
||||||
onMount={onMount}
|
onMount={onMount}
|
||||||
loading={<p>Loading script editor!</p>}
|
loading={<p>Loading script editor!</p>}
|
||||||
height="80%"
|
height="90%"
|
||||||
defaultLanguage="javascript"
|
defaultLanguage="javascript"
|
||||||
defaultValue={code}
|
defaultValue={code}
|
||||||
onChange={updateCode}
|
onChange={updateCode}
|
||||||
@ -352,6 +351,6 @@ export function Root(props: IProps): React.ReactElement {
|
|||||||
Netscript Documentation
|
Netscript Documentation
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
import { styled, useTheme, Theme, CSSObject } from "@mui/material/styles";
|
import { styled, Theme, CSSObject } from "@mui/material/styles";
|
||||||
import createStyles from "@mui/styles/createStyles";
|
import createStyles from "@mui/styles/createStyles";
|
||||||
import makeStyles from "@mui/styles/makeStyles";
|
import makeStyles from "@mui/styles/makeStyles";
|
||||||
import MuiDrawer from "@mui/material/Drawer";
|
import MuiDrawer from "@mui/material/Drawer";
|
||||||
@ -15,8 +15,6 @@ import Typography from "@mui/material/Typography";
|
|||||||
import Collapse from "@mui/material/Collapse";
|
import Collapse from "@mui/material/Collapse";
|
||||||
import Badge from "@mui/material/Badge";
|
import Badge from "@mui/material/Badge";
|
||||||
|
|
||||||
import { TTheme as BBTheme, colors } from "../../ui/React/Theme";
|
|
||||||
|
|
||||||
import ComputerIcon from "@mui/icons-material/Computer";
|
import ComputerIcon from "@mui/icons-material/Computer";
|
||||||
import LastPageIcon from "@mui/icons-material/LastPage"; // Terminal
|
import LastPageIcon from "@mui/icons-material/LastPage"; // Terminal
|
||||||
import CreateIcon from "@mui/icons-material/Create"; // Create Script
|
import CreateIcon from "@mui/icons-material/Create"; // Create Script
|
||||||
@ -44,7 +42,7 @@ import LiveHelpIcon from "@mui/icons-material/LiveHelp";
|
|||||||
import ExpandLessIcon from "@mui/icons-material/ExpandLess";
|
import ExpandLessIcon from "@mui/icons-material/ExpandLess";
|
||||||
import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
|
import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
|
||||||
|
|
||||||
import { IEngine } from "../../IEngine";
|
import { IRouter, Page } from "../../ui/Router";
|
||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||||
import { CONSTANTS } from "../../Constants";
|
import { CONSTANTS } from "../../Constants";
|
||||||
import { iTutorialSteps, iTutorialNextStep, ITutorial } from "../../InteractiveTutorial";
|
import { iTutorialSteps, iTutorialNextStep, ITutorial } from "../../InteractiveTutorial";
|
||||||
@ -56,9 +54,6 @@ import { inMission } from "../../Missions";
|
|||||||
import { cinematicTextFlag } from "../../CinematicText";
|
import { cinematicTextFlag } from "../../CinematicText";
|
||||||
import { KEY } from "../../../utils/helpers/keyCodes";
|
import { KEY } from "../../../utils/helpers/keyCodes";
|
||||||
import { FconfSettings } from "../../Fconf/FconfSettings";
|
import { FconfSettings } from "../../Fconf/FconfSettings";
|
||||||
import { Page, routing } from "../../ui/navigationTracking";
|
|
||||||
|
|
||||||
const drawerWidth = 240;
|
|
||||||
|
|
||||||
const openedMixin = (theme: Theme): CSSObject => ({
|
const openedMixin = (theme: Theme): CSSObject => ({
|
||||||
width: theme.spacing(31),
|
width: theme.spacing(31),
|
||||||
@ -83,7 +78,6 @@ const closedMixin = (theme: Theme): CSSObject => ({
|
|||||||
|
|
||||||
const Drawer = styled(MuiDrawer, { shouldForwardProp: (prop) => prop !== "open" })(({ theme, open }) => ({
|
const Drawer = styled(MuiDrawer, { shouldForwardProp: (prop) => prop !== "open" })(({ theme, open }) => ({
|
||||||
width: theme.spacing(31),
|
width: theme.spacing(31),
|
||||||
flexShrink: 0,
|
|
||||||
whiteSpace: "nowrap",
|
whiteSpace: "nowrap",
|
||||||
boxSizing: "border-box",
|
boxSizing: "border-box",
|
||||||
...(open && {
|
...(open && {
|
||||||
@ -99,7 +93,7 @@ const Drawer = styled(MuiDrawer, { shouldForwardProp: (prop) => prop !== "open"
|
|||||||
const useStyles = makeStyles((theme: Theme) =>
|
const useStyles = makeStyles((theme: Theme) =>
|
||||||
createStyles({
|
createStyles({
|
||||||
active: {
|
active: {
|
||||||
borderLeft: "3px solid " + colors.primary,
|
borderLeft: "3px solid " + theme.palette.primary.main,
|
||||||
},
|
},
|
||||||
listitem: {},
|
listitem: {},
|
||||||
}),
|
}),
|
||||||
@ -107,7 +101,8 @@ const useStyles = makeStyles((theme: Theme) =>
|
|||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
player: IPlayer;
|
player: IPlayer;
|
||||||
engine: IEngine;
|
router: IRouter;
|
||||||
|
page: Page;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function SidebarRoot(props: IProps): React.ReactElement {
|
export function SidebarRoot(props: IProps): React.ReactElement {
|
||||||
@ -121,7 +116,6 @@ export function SidebarRoot(props: IProps): React.ReactElement {
|
|||||||
return () => clearInterval(id);
|
return () => clearInterval(id);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const [activeTab, setActiveTab] = useState("Terminal");
|
|
||||||
const [hackingOpen, setHackingOpen] = useState(true);
|
const [hackingOpen, setHackingOpen] = useState(true);
|
||||||
const [characterOpen, setCharacterOpen] = useState(true);
|
const [characterOpen, setCharacterOpen] = useState(true);
|
||||||
const [worldOpen, setWorldOpen] = useState(true);
|
const [worldOpen, setWorldOpen] = useState(true);
|
||||||
@ -173,108 +167,88 @@ export function SidebarRoot(props: IProps): React.ReactElement {
|
|||||||
const canBladeburner = !!(props.player.bladeburner as any);
|
const canBladeburner = !!(props.player.bladeburner as any);
|
||||||
|
|
||||||
function clickTerminal(): void {
|
function clickTerminal(): void {
|
||||||
setActiveTab("Terminal");
|
props.router.toTerminal();
|
||||||
props.engine.loadTerminalContent();
|
|
||||||
if (flashTerminal) iTutorialNextStep();
|
if (flashTerminal) iTutorialNextStep();
|
||||||
}
|
}
|
||||||
|
|
||||||
function clickCreateScripts(): void {
|
function clickCreateScripts(): void {
|
||||||
setActiveTab("CreateScripts");
|
props.router.toScriptEditor();
|
||||||
props.engine.loadScriptEditorContent();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function clickStats(): void {
|
function clickStats(): void {
|
||||||
setActiveTab("Stats");
|
props.router.toCharacterInfo();
|
||||||
props.engine.loadCharacterContent();
|
|
||||||
if (flashStats) iTutorialNextStep();
|
if (flashStats) iTutorialNextStep();
|
||||||
}
|
}
|
||||||
|
|
||||||
function clickActiveScripts(): void {
|
function clickActiveScripts(): void {
|
||||||
setActiveTab("ActiveScripts");
|
props.router.toActiveScripts();
|
||||||
props.engine.loadActiveScriptsContent();
|
|
||||||
if (flashActiveScripts) iTutorialNextStep();
|
if (flashActiveScripts) iTutorialNextStep();
|
||||||
}
|
}
|
||||||
|
|
||||||
function clickCreateProgram(): void {
|
function clickCreateProgram(): void {
|
||||||
setActiveTab("CreateProgram");
|
props.router.toCreateProgram();
|
||||||
props.engine.loadCreateProgramContent();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function clickFactions(): void {
|
function clickFactions(): void {
|
||||||
setActiveTab("Factions");
|
props.router.toFactions();
|
||||||
props.engine.loadFactionsContent();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function clickAugmentations(): void {
|
function clickAugmentations(): void {
|
||||||
setActiveTab("Augmentations");
|
props.router.toAugmentations();
|
||||||
props.engine.loadAugmentationsContent();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function clickSleeves(): void {
|
function clickSleeves(): void {
|
||||||
setActiveTab("Sleeves");
|
props.router.toSleeves();
|
||||||
props.engine.loadSleevesContent();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function clickHacknet(): void {
|
function clickHacknet(): void {
|
||||||
setActiveTab("Hacknet");
|
props.router.toHacknetNodes();
|
||||||
props.engine.loadHacknetNodesContent();
|
|
||||||
if (flashHacknet) iTutorialNextStep();
|
if (flashHacknet) iTutorialNextStep();
|
||||||
}
|
}
|
||||||
|
|
||||||
function clickCity(): void {
|
function clickCity(): void {
|
||||||
setActiveTab("City");
|
props.router.toCity();
|
||||||
props.engine.loadLocationContent();
|
|
||||||
if (flashCity) iTutorialNextStep();
|
if (flashCity) iTutorialNextStep();
|
||||||
}
|
}
|
||||||
|
|
||||||
function clickTravel(): void {
|
function clickTravel(): void {
|
||||||
setActiveTab("Travel");
|
props.router.toTravel();
|
||||||
props.engine.loadTravelContent();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function clickJob(): void {
|
function clickJob(): void {
|
||||||
setActiveTab("Job");
|
props.router.toJob();
|
||||||
props.engine.loadJobContent();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function clickStockMarket(): void {
|
function clickStockMarket(): void {
|
||||||
setActiveTab("StockMarket");
|
props.router.toStockMarket();
|
||||||
props.engine.loadStockMarketContent();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function clickBladeburner(): void {
|
function clickBladeburner(): void {
|
||||||
setActiveTab("Bladeburner");
|
props.router.toBladeburner();
|
||||||
props.engine.loadBladeburnerContent();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function clickCorp(): void {
|
function clickCorp(): void {
|
||||||
setActiveTab("Corp");
|
props.router.toCorporation();
|
||||||
props.engine.loadCorporationContent();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function clickGang(): void {
|
function clickGang(): void {
|
||||||
setActiveTab("Gang");
|
props.router.toGang();
|
||||||
props.engine.loadGangContent();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function clickTutorial(): void {
|
function clickTutorial(): void {
|
||||||
setActiveTab("Tutorial");
|
props.router.toTutorial();
|
||||||
props.engine.loadTutorialContent();
|
|
||||||
if (flashTutorial) iTutorialNextStep();
|
if (flashTutorial) iTutorialNextStep();
|
||||||
}
|
}
|
||||||
|
|
||||||
function clickMilestones(): void {
|
function clickMilestones(): void {
|
||||||
setActiveTab("Milestones");
|
props.router.toMilestones();
|
||||||
props.engine.loadMilestonesContent();
|
|
||||||
}
|
}
|
||||||
function clickOptions(): void {
|
function clickOptions(): void {
|
||||||
setActiveTab("Options");
|
props.router.toGameOptions();
|
||||||
props.engine.loadGameOptionsContent();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function clickDev(): void {
|
function clickDev(): void {
|
||||||
setActiveTab("Dev");
|
props.router.toDevMenu();
|
||||||
props.engine.loadDevMenuContent();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -324,7 +298,7 @@ export function SidebarRoot(props: IProps): React.ReactElement {
|
|||||||
clickCreateProgram();
|
clickCreateProgram();
|
||||||
} else if (event.keyCode === KEY.F && event.altKey) {
|
} else if (event.keyCode === KEY.F && event.altKey) {
|
||||||
// Overriden by Fconf
|
// Overriden by Fconf
|
||||||
if (routing.isOn(Page.Terminal) && FconfSettings.ENABLE_BASH_HOTKEYS) {
|
if (props.page == Page.Terminal && FconfSettings.ENABLE_BASH_HOTKEYS) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
@ -356,421 +330,427 @@ export function SidebarRoot(props: IProps): React.ReactElement {
|
|||||||
const [open, setOpen] = useState(true);
|
const [open, setOpen] = useState(true);
|
||||||
const toggleDrawer = (): void => setOpen((old) => !old);
|
const toggleDrawer = (): void => setOpen((old) => !old);
|
||||||
return (
|
return (
|
||||||
<BBTheme>
|
<Drawer open={open} anchor="left" variant="permanent">
|
||||||
<Drawer open={open} anchor="left" variant="permanent">
|
<ListItem classes={{ root: classes.listitem }} button onClick={toggleDrawer}>
|
||||||
<ListItem classes={{ root: classes.listitem }} button onClick={toggleDrawer}>
|
<ListItemIcon>
|
||||||
|
{!open ? <ChevronRightIcon color={"primary"} /> : <ChevronLeftIcon color={"primary"} />}
|
||||||
|
</ListItemIcon>
|
||||||
|
<ListItemText primary={<Typography color="primary">Bitburner v{CONSTANTS.Version}</Typography>} />
|
||||||
|
</ListItem>
|
||||||
|
<Divider />
|
||||||
|
<List>
|
||||||
|
<ListItem classes={{ root: classes.listitem }} button onClick={() => setHackingOpen((old) => !old)}>
|
||||||
<ListItemIcon>
|
<ListItemIcon>
|
||||||
{!open ? <ChevronRightIcon color={"primary"} /> : <ChevronLeftIcon color={"primary"} />}
|
<ComputerIcon color={"primary"} />
|
||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
<ListItemText primary={<Typography color="primary">Bitburner v{CONSTANTS.Version}</Typography>} />
|
<ListItemText primary={<Typography color="primary">Hacking</Typography>} />
|
||||||
|
{hackingOpen ? <ExpandLessIcon color={"primary"} /> : <ExpandMoreIcon color={"primary"} />}
|
||||||
</ListItem>
|
</ListItem>
|
||||||
<Divider />
|
<Collapse in={hackingOpen} timeout="auto" unmountOnExit>
|
||||||
<List>
|
<List>
|
||||||
<ListItem classes={{ root: classes.listitem }} button onClick={() => setHackingOpen((old) => !old)}>
|
<ListItem
|
||||||
<ListItemIcon>
|
classes={{ root: classes.listitem }}
|
||||||
<ComputerIcon color={"primary"} />
|
button
|
||||||
</ListItemIcon>
|
key={"Terminal"}
|
||||||
<ListItemText primary={<Typography color="primary">Hacking</Typography>} />
|
className={clsx({
|
||||||
{hackingOpen ? <ExpandLessIcon color={"primary"} /> : <ExpandMoreIcon color={"primary"} />}
|
[classes.active]: props.page === Page.Terminal,
|
||||||
</ListItem>
|
})}
|
||||||
<Collapse in={hackingOpen} timeout="auto" unmountOnExit>
|
onClick={clickTerminal}
|
||||||
<List>
|
>
|
||||||
<ListItem
|
<ListItemIcon>
|
||||||
classes={{ root: classes.listitem }}
|
<LastPageIcon
|
||||||
button
|
color={flashTerminal ? "error" : props.page !== Page.Terminal ? "secondary" : "primary"}
|
||||||
key={"Terminal"}
|
/>
|
||||||
className={clsx({
|
</ListItemIcon>
|
||||||
[classes.active]: activeTab === "Terminal",
|
<ListItemText>
|
||||||
})}
|
<Typography color={flashTerminal ? "error" : props.page !== Page.Terminal ? "secondary" : "primary"}>
|
||||||
onClick={clickTerminal}
|
Terminal
|
||||||
>
|
</Typography>
|
||||||
<ListItemIcon>
|
</ListItemText>
|
||||||
<LastPageIcon color={flashTerminal ? "error" : activeTab !== "Terminal" ? "secondary" : "primary"} />
|
</ListItem>
|
||||||
</ListItemIcon>
|
<ListItem
|
||||||
<ListItemText>
|
classes={{ root: classes.listitem }}
|
||||||
<Typography color={flashTerminal ? "error" : activeTab !== "Terminal" ? "secondary" : "primary"}>
|
button
|
||||||
Terminal
|
key={"Create Scripts"}
|
||||||
</Typography>
|
className={clsx({
|
||||||
</ListItemText>
|
[classes.active]: props.page === Page.CreateScript,
|
||||||
</ListItem>
|
})}
|
||||||
<ListItem
|
onClick={clickCreateScripts}
|
||||||
classes={{ root: classes.listitem }}
|
>
|
||||||
button
|
<ListItemIcon>
|
||||||
key={"Create Scripts"}
|
<CreateIcon color={props.page !== Page.CreateScript ? "secondary" : "primary"} />
|
||||||
className={clsx({
|
</ListItemIcon>
|
||||||
[classes.active]: activeTab === "CreateScripts",
|
<ListItemText>
|
||||||
})}
|
<Typography color={props.page !== Page.CreateScript ? "secondary" : "primary"}>
|
||||||
onClick={clickCreateScripts}
|
Create Script
|
||||||
>
|
</Typography>
|
||||||
<ListItemIcon>
|
</ListItemText>
|
||||||
<CreateIcon color={activeTab !== "CreateScripts" ? "secondary" : "primary"} />
|
</ListItem>
|
||||||
</ListItemIcon>
|
<ListItem
|
||||||
<ListItemText>
|
classes={{ root: classes.listitem }}
|
||||||
<Typography color={activeTab !== "CreateScripts" ? "secondary" : "primary"}>Create Script</Typography>
|
button
|
||||||
</ListItemText>
|
key={"Active Scripts"}
|
||||||
</ListItem>
|
className={clsx({
|
||||||
<ListItem
|
[classes.active]: props.page === Page.ActiveScripts,
|
||||||
classes={{ root: classes.listitem }}
|
})}
|
||||||
button
|
onClick={clickActiveScripts}
|
||||||
key={"Active Scripts"}
|
>
|
||||||
className={clsx({
|
<ListItemIcon>
|
||||||
[classes.active]: activeTab === "ActiveScripts",
|
<StorageIcon
|
||||||
})}
|
color={flashActiveScripts ? "error" : props.page !== Page.ActiveScripts ? "secondary" : "primary"}
|
||||||
onClick={clickActiveScripts}
|
/>
|
||||||
>
|
</ListItemIcon>
|
||||||
<ListItemIcon>
|
<ListItemText>
|
||||||
<StorageIcon
|
<Typography
|
||||||
color={flashActiveScripts ? "error" : activeTab !== "ActiveScripts" ? "secondary" : "primary"}
|
color={flashActiveScripts ? "error" : props.page !== Page.ActiveScripts ? "secondary" : "primary"}
|
||||||
/>
|
|
||||||
</ListItemIcon>
|
|
||||||
<ListItemText>
|
|
||||||
<Typography
|
|
||||||
color={flashActiveScripts ? "error" : activeTab !== "ActiveScripts" ? "secondary" : "primary"}
|
|
||||||
>
|
|
||||||
Active Scripts
|
|
||||||
</Typography>
|
|
||||||
</ListItemText>
|
|
||||||
</ListItem>
|
|
||||||
{canCreateProgram && (
|
|
||||||
<ListItem
|
|
||||||
button
|
|
||||||
key={"Create Program"}
|
|
||||||
className={clsx({
|
|
||||||
[classes.active]: activeTab === "CreateProgram",
|
|
||||||
})}
|
|
||||||
onClick={clickCreateProgram}
|
|
||||||
>
|
>
|
||||||
<ListItemIcon>
|
Active Scripts
|
||||||
<Badge badgeContent={programCount > 0 ? programCount : undefined} color="error">
|
|
||||||
<BugReportIcon color={activeTab !== "CreateProgram" ? "secondary" : "primary"} />
|
|
||||||
</Badge>
|
|
||||||
</ListItemIcon>
|
|
||||||
<ListItemText>
|
|
||||||
<Typography color={activeTab !== "CreateProgram" ? "secondary" : "primary"}>
|
|
||||||
Create Program
|
|
||||||
</Typography>
|
|
||||||
</ListItemText>
|
|
||||||
</ListItem>
|
|
||||||
)}
|
|
||||||
</List>
|
|
||||||
</Collapse>
|
|
||||||
|
|
||||||
<Divider />
|
|
||||||
<ListItem classes={{ root: classes.listitem }} button onClick={() => setCharacterOpen((old) => !old)}>
|
|
||||||
<ListItemIcon>
|
|
||||||
<AccountBoxIcon color={"primary"} />
|
|
||||||
</ListItemIcon>
|
|
||||||
<ListItemText primary={<Typography color="primary">Character</Typography>} />
|
|
||||||
{characterOpen ? <ExpandLessIcon color={"primary"} /> : <ExpandMoreIcon color={"primary"} />}
|
|
||||||
</ListItem>
|
|
||||||
<Collapse in={characterOpen} timeout="auto" unmountOnExit>
|
|
||||||
<ListItem
|
|
||||||
button
|
|
||||||
key={"Stats"}
|
|
||||||
className={clsx({
|
|
||||||
[classes.active]: activeTab === "Stats",
|
|
||||||
})}
|
|
||||||
onClick={clickStats}
|
|
||||||
>
|
|
||||||
<ListItemIcon>
|
|
||||||
<EqualizerIcon color={flashStats ? "error" : activeTab !== "Stats" ? "secondary" : "primary"} />
|
|
||||||
</ListItemIcon>
|
|
||||||
<ListItemText>
|
|
||||||
<Typography color={flashStats ? "error" : activeTab !== "Stats" ? "secondary" : "primary"}>
|
|
||||||
Stats
|
|
||||||
</Typography>
|
</Typography>
|
||||||
</ListItemText>
|
</ListItemText>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
{canOpenFactions && (
|
{canCreateProgram && (
|
||||||
<ListItem
|
<ListItem
|
||||||
classes={{ root: classes.listitem }}
|
|
||||||
button
|
button
|
||||||
key={"Factions"}
|
key={"Create Program"}
|
||||||
className={clsx({
|
className={clsx({
|
||||||
[classes.active]: activeTab === "Factions",
|
[classes.active]: props.page === Page.CreateProgram,
|
||||||
})}
|
})}
|
||||||
onClick={clickFactions}
|
onClick={clickCreateProgram}
|
||||||
>
|
>
|
||||||
<ListItemIcon>
|
<ListItemIcon>
|
||||||
<Badge badgeContent={invitationsCount !== 0 ? invitationsCount : undefined} color="error">
|
<Badge badgeContent={programCount > 0 ? programCount : undefined} color="error">
|
||||||
<ContactsIcon color={activeTab !== "Factions" ? "secondary" : "primary"} />
|
<BugReportIcon color={props.page !== Page.CreateProgram ? "secondary" : "primary"} />
|
||||||
</Badge>
|
</Badge>
|
||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
<ListItemText>
|
<ListItemText>
|
||||||
<Typography color={activeTab !== "Factions" ? "secondary" : "primary"}>Factions</Typography>
|
<Typography color={props.page !== Page.CreateProgram ? "secondary" : "primary"}>
|
||||||
|
Create Program
|
||||||
|
</Typography>
|
||||||
</ListItemText>
|
</ListItemText>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
)}
|
)}
|
||||||
{canOpenAugmentations && (
|
</List>
|
||||||
<ListItem
|
</Collapse>
|
||||||
classes={{ root: classes.listitem }}
|
|
||||||
button
|
|
||||||
key={"Augmentations"}
|
|
||||||
className={clsx({
|
|
||||||
[classes.active]: activeTab === "Augmentations",
|
|
||||||
})}
|
|
||||||
onClick={clickAugmentations}
|
|
||||||
>
|
|
||||||
<ListItemIcon>
|
|
||||||
<Badge badgeContent={augmentationCount !== 0 ? augmentationCount : undefined} color="error">
|
|
||||||
<DoubleArrowIcon
|
|
||||||
style={{ transform: "rotate(-90deg)" }}
|
|
||||||
color={activeTab !== "Augmentations" ? "secondary" : "primary"}
|
|
||||||
/>
|
|
||||||
</Badge>
|
|
||||||
</ListItemIcon>
|
|
||||||
<ListItemText>
|
|
||||||
<Typography color={activeTab !== "Augmentations" ? "secondary" : "primary"}>Augmentations</Typography>
|
|
||||||
</ListItemText>
|
|
||||||
</ListItem>
|
|
||||||
)}
|
|
||||||
<ListItem
|
|
||||||
button
|
|
||||||
key={"Hacknet"}
|
|
||||||
className={clsx({
|
|
||||||
[classes.active]: activeTab === "Hacknet",
|
|
||||||
})}
|
|
||||||
onClick={clickHacknet}
|
|
||||||
>
|
|
||||||
<ListItemIcon>
|
|
||||||
<AccountTreeIcon color={flashHacknet ? "error" : activeTab !== "Hacknet" ? "secondary" : "primary"} />
|
|
||||||
</ListItemIcon>
|
|
||||||
<ListItemText>
|
|
||||||
<Typography color={flashHacknet ? "error" : activeTab !== "Hacknet" ? "secondary" : "primary"}>
|
|
||||||
Hacknet
|
|
||||||
</Typography>
|
|
||||||
</ListItemText>
|
|
||||||
</ListItem>
|
|
||||||
{canOpenSleeves && (
|
|
||||||
<ListItem
|
|
||||||
classes={{ root: classes.listitem }}
|
|
||||||
button
|
|
||||||
key={"Sleeves"}
|
|
||||||
className={clsx({
|
|
||||||
[classes.active]: activeTab === "Sleeves",
|
|
||||||
})}
|
|
||||||
onClick={clickSleeves}
|
|
||||||
>
|
|
||||||
<ListItemIcon>
|
|
||||||
<PeopleAltIcon color={activeTab !== "Sleeves" ? "secondary" : "primary"} />
|
|
||||||
</ListItemIcon>
|
|
||||||
<ListItemText>
|
|
||||||
<Typography color={activeTab !== "Sleeves" ? "secondary" : "primary"}>Sleeves</Typography>
|
|
||||||
</ListItemText>
|
|
||||||
</ListItem>
|
|
||||||
)}
|
|
||||||
</Collapse>
|
|
||||||
|
|
||||||
<Divider />
|
<Divider />
|
||||||
<ListItem classes={{ root: classes.listitem }} button onClick={() => setWorldOpen((old) => !old)}>
|
<ListItem classes={{ root: classes.listitem }} button onClick={() => setCharacterOpen((old) => !old)}>
|
||||||
|
<ListItemIcon>
|
||||||
|
<AccountBoxIcon color={"primary"} />
|
||||||
|
</ListItemIcon>
|
||||||
|
<ListItemText primary={<Typography color="primary">Character</Typography>} />
|
||||||
|
{characterOpen ? <ExpandLessIcon color={"primary"} /> : <ExpandMoreIcon color={"primary"} />}
|
||||||
|
</ListItem>
|
||||||
|
<Collapse in={characterOpen} timeout="auto" unmountOnExit>
|
||||||
|
<ListItem
|
||||||
|
button
|
||||||
|
key={"Stats"}
|
||||||
|
className={clsx({
|
||||||
|
[classes.active]: props.page === Page.Stats,
|
||||||
|
})}
|
||||||
|
onClick={clickStats}
|
||||||
|
>
|
||||||
<ListItemIcon>
|
<ListItemIcon>
|
||||||
<PublicIcon color={"primary"} />
|
<EqualizerIcon color={flashStats ? "error" : props.page !== Page.Stats ? "secondary" : "primary"} />
|
||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
<ListItemText primary={<Typography color="primary">World</Typography>} />
|
<ListItemText>
|
||||||
{worldOpen ? <ExpandLessIcon color={"primary"} /> : <ExpandMoreIcon color={"primary"} />}
|
<Typography color={flashStats ? "error" : props.page !== Page.Stats ? "secondary" : "primary"}>
|
||||||
|
Stats
|
||||||
|
</Typography>
|
||||||
|
</ListItemText>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
<Collapse in={worldOpen} timeout="auto" unmountOnExit>
|
{canOpenFactions && (
|
||||||
<ListItem
|
<ListItem
|
||||||
|
classes={{ root: classes.listitem }}
|
||||||
button
|
button
|
||||||
key={"City"}
|
key={"Factions"}
|
||||||
className={clsx({
|
className={clsx({
|
||||||
[classes.active]: activeTab === "City",
|
[classes.active]: [Page.Factions, Page.Faction].includes(props.page),
|
||||||
})}
|
})}
|
||||||
onClick={clickCity}
|
onClick={clickFactions}
|
||||||
>
|
>
|
||||||
<ListItemIcon>
|
<ListItemIcon>
|
||||||
<LocationCityIcon color={flashCity ? "error" : activeTab !== "City" ? "secondary" : "primary"} />
|
<Badge badgeContent={invitationsCount !== 0 ? invitationsCount : undefined} color="error">
|
||||||
|
<ContactsIcon color={![Page.Factions, Page.Faction].includes(props.page) ? "secondary" : "primary"} />
|
||||||
|
</Badge>
|
||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
<ListItemText>
|
<ListItemText>
|
||||||
<Typography color={flashCity ? "error" : activeTab !== "City" ? "secondary" : "primary"}>
|
<Typography color={![Page.Factions, Page.Faction].includes(props.page) ? "secondary" : "primary"}>
|
||||||
City
|
Factions
|
||||||
</Typography>
|
</Typography>
|
||||||
</ListItemText>
|
</ListItemText>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
|
)}
|
||||||
|
{canOpenAugmentations && (
|
||||||
<ListItem
|
<ListItem
|
||||||
|
classes={{ root: classes.listitem }}
|
||||||
button
|
button
|
||||||
key={"Travel"}
|
key={"Augmentations"}
|
||||||
className={clsx({
|
className={clsx({
|
||||||
[classes.active]: activeTab === "Travel",
|
[classes.active]: props.page === Page.Augmentations,
|
||||||
})}
|
})}
|
||||||
onClick={clickTravel}
|
onClick={clickAugmentations}
|
||||||
>
|
>
|
||||||
<ListItemIcon>
|
<ListItemIcon>
|
||||||
<AirplanemodeActiveIcon color={activeTab !== "Travel" ? "secondary" : "primary"} />
|
<Badge badgeContent={augmentationCount !== 0 ? augmentationCount : undefined} color="error">
|
||||||
|
<DoubleArrowIcon
|
||||||
|
style={{ transform: "rotate(-90deg)" }}
|
||||||
|
color={props.page !== Page.Augmentations ? "secondary" : "primary"}
|
||||||
|
/>
|
||||||
|
</Badge>
|
||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
<ListItemText>
|
<ListItemText>
|
||||||
<Typography color={activeTab !== "Travel" ? "secondary" : "primary"}>Travel</Typography>
|
<Typography color={props.page !== Page.Augmentations ? "secondary" : "primary"}>
|
||||||
|
Augmentations
|
||||||
|
</Typography>
|
||||||
</ListItemText>
|
</ListItemText>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
{canJob && (
|
)}
|
||||||
<ListItem
|
<ListItem
|
||||||
classes={{ root: classes.listitem }}
|
button
|
||||||
button
|
key={"Hacknet"}
|
||||||
key={"Job"}
|
className={clsx({
|
||||||
className={clsx({
|
[classes.active]: props.page === Page.Hacknet,
|
||||||
[classes.active]: activeTab === "Job",
|
})}
|
||||||
})}
|
onClick={clickHacknet}
|
||||||
onClick={clickJob}
|
>
|
||||||
>
|
<ListItemIcon>
|
||||||
<ListItemIcon>
|
<AccountTreeIcon color={flashHacknet ? "error" : props.page !== Page.Hacknet ? "secondary" : "primary"} />
|
||||||
<WorkIcon color={activeTab !== "Job" ? "secondary" : "primary"} />
|
</ListItemIcon>
|
||||||
</ListItemIcon>
|
<ListItemText>
|
||||||
<ListItemText>
|
<Typography color={flashHacknet ? "error" : props.page !== Page.Hacknet ? "secondary" : "primary"}>
|
||||||
<Typography color={activeTab !== "Job" ? "secondary" : "primary"}>Job</Typography>
|
Hacknet
|
||||||
</ListItemText>
|
</Typography>
|
||||||
</ListItem>
|
</ListItemText>
|
||||||
)}
|
</ListItem>
|
||||||
{canStockMarket && (
|
{canOpenSleeves && (
|
||||||
<ListItem
|
<ListItem
|
||||||
classes={{ root: classes.listitem }}
|
classes={{ root: classes.listitem }}
|
||||||
button
|
button
|
||||||
key={"Stock Market"}
|
key={"Sleeves"}
|
||||||
className={clsx({
|
className={clsx({
|
||||||
[classes.active]: activeTab === "StockMarket",
|
[classes.active]: props.page === Page.Sleeves,
|
||||||
})}
|
})}
|
||||||
onClick={clickStockMarket}
|
onClick={clickSleeves}
|
||||||
>
|
>
|
||||||
<ListItemIcon>
|
<ListItemIcon>
|
||||||
<TrendingUpIcon color={activeTab !== "StockMarket" ? "secondary" : "primary"} />
|
<PeopleAltIcon color={props.page !== Page.Sleeves ? "secondary" : "primary"} />
|
||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
<ListItemText>
|
<ListItemText>
|
||||||
<Typography color={activeTab !== "StockMarket" ? "secondary" : "primary"}>Stock Market</Typography>
|
<Typography color={props.page !== Page.Sleeves ? "secondary" : "primary"}>Sleeves</Typography>
|
||||||
</ListItemText>
|
</ListItemText>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
)}
|
)}
|
||||||
{canBladeburner && (
|
</Collapse>
|
||||||
<ListItem
|
|
||||||
classes={{ root: classes.listitem }}
|
|
||||||
button
|
|
||||||
key={"Bladeburner"}
|
|
||||||
className={clsx({
|
|
||||||
[classes.active]: activeTab === "Bladeburner",
|
|
||||||
})}
|
|
||||||
onClick={clickBladeburner}
|
|
||||||
>
|
|
||||||
<ListItemIcon>
|
|
||||||
<FormatBoldIcon color={activeTab !== "Bladeburner" ? "secondary" : "primary"} />
|
|
||||||
</ListItemIcon>
|
|
||||||
<ListItemText>
|
|
||||||
<Typography color={activeTab !== "Bladeburner" ? "secondary" : "primary"}>Bladeburner</Typography>
|
|
||||||
</ListItemText>
|
|
||||||
</ListItem>
|
|
||||||
)}
|
|
||||||
{canCorporation && (
|
|
||||||
<ListItem
|
|
||||||
classes={{ root: classes.listitem }}
|
|
||||||
button
|
|
||||||
key={"Corp"}
|
|
||||||
className={clsx({
|
|
||||||
[classes.active]: activeTab === "Corp",
|
|
||||||
})}
|
|
||||||
onClick={clickCorp}
|
|
||||||
>
|
|
||||||
<ListItemIcon>
|
|
||||||
<BusinessIcon color={activeTab !== "Corp" ? "secondary" : "primary"} />
|
|
||||||
</ListItemIcon>
|
|
||||||
<ListItemText>
|
|
||||||
<Typography color={activeTab !== "Corp" ? "secondary" : "primary"}>Corp</Typography>
|
|
||||||
</ListItemText>
|
|
||||||
</ListItem>
|
|
||||||
)}
|
|
||||||
{canGang && (
|
|
||||||
<ListItem
|
|
||||||
classes={{ root: classes.listitem }}
|
|
||||||
button
|
|
||||||
key={"Gang"}
|
|
||||||
className={clsx({
|
|
||||||
[classes.active]: activeTab === "Gang",
|
|
||||||
})}
|
|
||||||
onClick={clickGang}
|
|
||||||
>
|
|
||||||
<ListItemIcon>
|
|
||||||
<SportsMmaIcon color={activeTab !== "Gang" ? "secondary" : "primary"} />
|
|
||||||
</ListItemIcon>
|
|
||||||
<ListItemText>
|
|
||||||
<Typography color={activeTab !== "Gang" ? "secondary" : "primary"}>Gang</Typography>
|
|
||||||
</ListItemText>
|
|
||||||
</ListItem>
|
|
||||||
)}
|
|
||||||
</Collapse>
|
|
||||||
|
|
||||||
<Divider />
|
<Divider />
|
||||||
<ListItem classes={{ root: classes.listitem }} button onClick={() => setHelpOpen((old) => !old)}>
|
<ListItem classes={{ root: classes.listitem }} button onClick={() => setWorldOpen((old) => !old)}>
|
||||||
|
<ListItemIcon>
|
||||||
|
<PublicIcon color={"primary"} />
|
||||||
|
</ListItemIcon>
|
||||||
|
<ListItemText primary={<Typography color="primary">World</Typography>} />
|
||||||
|
{worldOpen ? <ExpandLessIcon color={"primary"} /> : <ExpandMoreIcon color={"primary"} />}
|
||||||
|
</ListItem>
|
||||||
|
<Collapse in={worldOpen} timeout="auto" unmountOnExit>
|
||||||
|
<ListItem
|
||||||
|
button
|
||||||
|
key={"City"}
|
||||||
|
className={clsx({
|
||||||
|
[classes.active]: props.page === Page.City,
|
||||||
|
})}
|
||||||
|
onClick={clickCity}
|
||||||
|
>
|
||||||
<ListItemIcon>
|
<ListItemIcon>
|
||||||
<LiveHelpIcon color={"primary"} />
|
<LocationCityIcon color={flashCity ? "error" : props.page !== Page.City ? "secondary" : "primary"} />
|
||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
<ListItemText primary={<Typography color="primary">Help</Typography>} />
|
<ListItemText>
|
||||||
{helpOpen ? <ExpandLessIcon color={"primary"} /> : <ExpandMoreIcon color={"primary"} />}
|
<Typography color={flashCity ? "error" : props.page !== Page.City ? "secondary" : "primary"}>
|
||||||
|
City
|
||||||
|
</Typography>
|
||||||
|
</ListItemText>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
<Collapse in={helpOpen} timeout="auto" unmountOnExit>
|
<ListItem
|
||||||
|
button
|
||||||
|
key={"Travel"}
|
||||||
|
className={clsx({
|
||||||
|
[classes.active]: props.page === Page.Travel,
|
||||||
|
})}
|
||||||
|
onClick={clickTravel}
|
||||||
|
>
|
||||||
|
<ListItemIcon>
|
||||||
|
<AirplanemodeActiveIcon color={props.page !== Page.Travel ? "secondary" : "primary"} />
|
||||||
|
</ListItemIcon>
|
||||||
|
<ListItemText>
|
||||||
|
<Typography color={props.page !== Page.Travel ? "secondary" : "primary"}>Travel</Typography>
|
||||||
|
</ListItemText>
|
||||||
|
</ListItem>
|
||||||
|
{canJob && (
|
||||||
<ListItem
|
<ListItem
|
||||||
|
classes={{ root: classes.listitem }}
|
||||||
button
|
button
|
||||||
key={"Milestones"}
|
key={"Job"}
|
||||||
className={clsx({
|
className={clsx({
|
||||||
[classes.active]: activeTab === "Milestones",
|
[classes.active]: props.page === Page.Job,
|
||||||
})}
|
})}
|
||||||
onClick={clickMilestones}
|
onClick={clickJob}
|
||||||
>
|
>
|
||||||
<ListItemIcon>
|
<ListItemIcon>
|
||||||
<CheckIcon color={activeTab !== "Milestones" ? "secondary" : "primary"} />
|
<WorkIcon color={props.page !== Page.Job ? "secondary" : "primary"} />
|
||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
<ListItemText>
|
<ListItemText>
|
||||||
<Typography color={activeTab !== "Milestones" ? "secondary" : "primary"}>Milestones</Typography>
|
<Typography color={props.page !== Page.Job ? "secondary" : "primary"}>Job</Typography>
|
||||||
</ListItemText>
|
</ListItemText>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
|
)}
|
||||||
|
{canStockMarket && (
|
||||||
<ListItem
|
<ListItem
|
||||||
|
classes={{ root: classes.listitem }}
|
||||||
button
|
button
|
||||||
key={"Tutorial"}
|
key={"Stock Market"}
|
||||||
className={clsx({
|
className={clsx({
|
||||||
[classes.active]: activeTab === "Tutorial",
|
[classes.active]: props.page === Page.StockMarket,
|
||||||
})}
|
})}
|
||||||
onClick={clickTutorial}
|
onClick={clickStockMarket}
|
||||||
>
|
>
|
||||||
<ListItemIcon>
|
<ListItemIcon>
|
||||||
<HelpIcon color={flashTutorial ? "error" : activeTab !== "Tutorial" ? "secondary" : "primary"} />
|
<TrendingUpIcon color={props.page !== Page.StockMarket ? "secondary" : "primary"} />
|
||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
<ListItemText>
|
<ListItemText>
|
||||||
<Typography color={flashTutorial ? "error" : activeTab !== "Tutorial" ? "secondary" : "primary"}>
|
<Typography color={props.page !== Page.StockMarket ? "secondary" : "primary"}>Stock Market</Typography>
|
||||||
Tutorial
|
|
||||||
</Typography>
|
|
||||||
</ListItemText>
|
</ListItemText>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
|
)}
|
||||||
|
{canBladeburner && (
|
||||||
<ListItem
|
<ListItem
|
||||||
|
classes={{ root: classes.listitem }}
|
||||||
button
|
button
|
||||||
key={"Options"}
|
key={"Bladeburner"}
|
||||||
className={clsx({
|
className={clsx({
|
||||||
[classes.active]: activeTab === "Options",
|
[classes.active]: props.page === Page.Bladeburner,
|
||||||
})}
|
})}
|
||||||
onClick={clickOptions}
|
onClick={clickBladeburner}
|
||||||
>
|
>
|
||||||
<ListItemIcon>
|
<ListItemIcon>
|
||||||
<SettingsIcon color={activeTab !== "Options" ? "secondary" : "primary"} />
|
<FormatBoldIcon color={props.page !== Page.Bladeburner ? "secondary" : "primary"} />
|
||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
<ListItemText>
|
<ListItemText>
|
||||||
<Typography color={activeTab !== "Options" ? "secondary" : "primary"}>Options</Typography>
|
<Typography color={props.page !== Page.Bladeburner ? "secondary" : "primary"}>Bladeburner</Typography>
|
||||||
</ListItemText>
|
</ListItemText>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
{process.env.NODE_ENV === "development" && (
|
)}
|
||||||
<ListItem
|
{canCorporation && (
|
||||||
classes={{ root: classes.listitem }}
|
<ListItem
|
||||||
button
|
classes={{ root: classes.listitem }}
|
||||||
key={"Dev"}
|
button
|
||||||
className={clsx({
|
key={"Corp"}
|
||||||
[classes.active]: activeTab === "Dev",
|
className={clsx({
|
||||||
})}
|
[classes.active]: props.page === Page.Corporation,
|
||||||
onClick={clickDev}
|
})}
|
||||||
>
|
onClick={clickCorp}
|
||||||
<ListItemIcon>
|
>
|
||||||
<DeveloperBoardIcon color={activeTab !== "Dev" ? "secondary" : "primary"} />
|
<ListItemIcon>
|
||||||
</ListItemIcon>
|
<BusinessIcon color={props.page !== Page.Corporation ? "secondary" : "primary"} />
|
||||||
<ListItemText>
|
</ListItemIcon>
|
||||||
<Typography color={activeTab !== "Dev" ? "secondary" : "primary"}>Dev</Typography>
|
<ListItemText>
|
||||||
</ListItemText>
|
<Typography color={props.page !== Page.Corporation ? "secondary" : "primary"}>Corp</Typography>
|
||||||
</ListItem>
|
</ListItemText>
|
||||||
)}
|
</ListItem>
|
||||||
</Collapse>
|
)}
|
||||||
</List>
|
{canGang && (
|
||||||
</Drawer>
|
<ListItem
|
||||||
</BBTheme>
|
classes={{ root: classes.listitem }}
|
||||||
|
button
|
||||||
|
key={"Gang"}
|
||||||
|
className={clsx({
|
||||||
|
[classes.active]: props.page === Page.Gang,
|
||||||
|
})}
|
||||||
|
onClick={clickGang}
|
||||||
|
>
|
||||||
|
<ListItemIcon>
|
||||||
|
<SportsMmaIcon color={props.page !== Page.Gang ? "secondary" : "primary"} />
|
||||||
|
</ListItemIcon>
|
||||||
|
<ListItemText>
|
||||||
|
<Typography color={props.page !== Page.Gang ? "secondary" : "primary"}>Gang</Typography>
|
||||||
|
</ListItemText>
|
||||||
|
</ListItem>
|
||||||
|
)}
|
||||||
|
</Collapse>
|
||||||
|
|
||||||
|
<Divider />
|
||||||
|
<ListItem classes={{ root: classes.listitem }} button onClick={() => setHelpOpen((old) => !old)}>
|
||||||
|
<ListItemIcon>
|
||||||
|
<LiveHelpIcon color={"primary"} />
|
||||||
|
</ListItemIcon>
|
||||||
|
<ListItemText primary={<Typography color="primary">Help</Typography>} />
|
||||||
|
{helpOpen ? <ExpandLessIcon color={"primary"} /> : <ExpandMoreIcon color={"primary"} />}
|
||||||
|
</ListItem>
|
||||||
|
<Collapse in={helpOpen} timeout="auto" unmountOnExit>
|
||||||
|
<ListItem
|
||||||
|
button
|
||||||
|
key={"Milestones"}
|
||||||
|
className={clsx({
|
||||||
|
[classes.active]: props.page === Page.Milestones,
|
||||||
|
})}
|
||||||
|
onClick={clickMilestones}
|
||||||
|
>
|
||||||
|
<ListItemIcon>
|
||||||
|
<CheckIcon color={props.page !== Page.Milestones ? "secondary" : "primary"} />
|
||||||
|
</ListItemIcon>
|
||||||
|
<ListItemText>
|
||||||
|
<Typography color={props.page !== Page.Milestones ? "secondary" : "primary"}>Milestones</Typography>
|
||||||
|
</ListItemText>
|
||||||
|
</ListItem>
|
||||||
|
<ListItem
|
||||||
|
button
|
||||||
|
key={"Tutorial"}
|
||||||
|
className={clsx({
|
||||||
|
[classes.active]: props.page === Page.Tutorial,
|
||||||
|
})}
|
||||||
|
onClick={clickTutorial}
|
||||||
|
>
|
||||||
|
<ListItemIcon>
|
||||||
|
<HelpIcon color={flashTutorial ? "error" : props.page !== Page.Tutorial ? "secondary" : "primary"} />
|
||||||
|
</ListItemIcon>
|
||||||
|
<ListItemText>
|
||||||
|
<Typography color={flashTutorial ? "error" : props.page !== Page.Tutorial ? "secondary" : "primary"}>
|
||||||
|
Tutorial
|
||||||
|
</Typography>
|
||||||
|
</ListItemText>
|
||||||
|
</ListItem>
|
||||||
|
<ListItem
|
||||||
|
button
|
||||||
|
key={"Options"}
|
||||||
|
className={clsx({
|
||||||
|
[classes.active]: props.page === Page.Options,
|
||||||
|
})}
|
||||||
|
onClick={clickOptions}
|
||||||
|
>
|
||||||
|
<ListItemIcon>
|
||||||
|
<SettingsIcon color={props.page !== Page.Options ? "secondary" : "primary"} />
|
||||||
|
</ListItemIcon>
|
||||||
|
<ListItemText>
|
||||||
|
<Typography color={props.page !== Page.Options ? "secondary" : "primary"}>Options</Typography>
|
||||||
|
</ListItemText>
|
||||||
|
</ListItem>
|
||||||
|
{process.env.NODE_ENV === "development" && (
|
||||||
|
<ListItem
|
||||||
|
classes={{ root: classes.listitem }}
|
||||||
|
button
|
||||||
|
key={"Dev"}
|
||||||
|
className={clsx({
|
||||||
|
[classes.active]: props.page === Page.DevMenu,
|
||||||
|
})}
|
||||||
|
onClick={clickDev}
|
||||||
|
>
|
||||||
|
<ListItemIcon>
|
||||||
|
<DeveloperBoardIcon color={props.page !== Page.DevMenu ? "secondary" : "primary"} />
|
||||||
|
</ListItemIcon>
|
||||||
|
<ListItemText>
|
||||||
|
<Typography color={props.page !== Page.DevMenu ? "secondary" : "primary"}>Dev</Typography>
|
||||||
|
</ListItemText>
|
||||||
|
</ListItem>
|
||||||
|
)}
|
||||||
|
</Collapse>
|
||||||
|
</List>
|
||||||
|
</Drawer>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,6 @@ import { dialogBoxCreate } from "../../utils/DialogBox";
|
|||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
|
|
||||||
export interface IProcessOrderRefs {
|
export interface IProcessOrderRefs {
|
||||||
rerenderFn: () => void;
|
|
||||||
stockMarket: IStockMarket;
|
stockMarket: IStockMarket;
|
||||||
symbolToStockMap: IMap<Stock>;
|
symbolToStockMap: IMap<Stock>;
|
||||||
}
|
}
|
||||||
@ -116,7 +115,6 @@ function executeOrder(order: Order, refs: IProcessOrderRefs): void {
|
|||||||
// When orders are executed, the buying and selling functions shouldn't
|
// When orders are executed, the buying and selling functions shouldn't
|
||||||
// emit popup dialog boxes. This options object configures the functions for that
|
// emit popup dialog boxes. This options object configures the functions for that
|
||||||
const opts = {
|
const opts = {
|
||||||
rerenderFn: refs.rerenderFn,
|
|
||||||
suppressDialog: true,
|
suppressDialog: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -158,7 +156,6 @@ function executeOrder(order: Order, refs: IProcessOrderRefs): void {
|
|||||||
{numeralWrapper.formatShares(Math.round(order.shares))} shares)
|
{numeralWrapper.formatShares(Math.round(order.shares))} shares)
|
||||||
</>,
|
</>,
|
||||||
);
|
);
|
||||||
refs.rerenderFn();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import { buyStock, sellStock, shortStock, sellShort } from "./BuyingAndSelling";
|
|
||||||
import { IOrderBook } from "./IOrderBook";
|
import { IOrderBook } from "./IOrderBook";
|
||||||
import { IStockMarket } from "./IStockMarket";
|
import { IStockMarket } from "./IStockMarket";
|
||||||
import { Order } from "./Order";
|
import { Order } from "./Order";
|
||||||
@ -9,24 +8,23 @@ import { InitStockMetadata } from "./data/InitStockMetadata";
|
|||||||
import { OrderTypes } from "./data/OrderTypes";
|
import { OrderTypes } from "./data/OrderTypes";
|
||||||
import { PositionTypes } from "./data/PositionTypes";
|
import { PositionTypes } from "./data/PositionTypes";
|
||||||
import { StockSymbols } from "./data/StockSymbols";
|
import { StockSymbols } from "./data/StockSymbols";
|
||||||
import { StockMarketRoot } from "./ui/Root";
|
|
||||||
|
|
||||||
import { CONSTANTS } from "../Constants";
|
import { CONSTANTS } from "../Constants";
|
||||||
import { WorkerScript } from "../Netscript/WorkerScript";
|
import { WorkerScript } from "../Netscript/WorkerScript";
|
||||||
import { Player } from "../Player";
|
|
||||||
import { IMap } from "../types";
|
import { IMap } from "../types";
|
||||||
import { EventEmitter } from "../utils/EventEmitter";
|
import { EventEmitter } from "../utils/EventEmitter";
|
||||||
|
|
||||||
import { Page, routing } from ".././ui/navigationTracking";
|
|
||||||
import { numeralWrapper } from ".././ui/numeralFormat";
|
import { numeralWrapper } from ".././ui/numeralFormat";
|
||||||
|
|
||||||
import { dialogBoxCreate } from "../../utils/DialogBox";
|
import { dialogBoxCreate } from "../../utils/DialogBox";
|
||||||
import { Reviver } from "../../utils/JSONReviver";
|
import { Reviver } from "../../utils/JSONReviver";
|
||||||
|
|
||||||
import * as React from "react";
|
export let StockMarket: IStockMarket = {
|
||||||
import * as ReactDOM from "react-dom";
|
lastUpdate: 0,
|
||||||
|
Orders: {},
|
||||||
export let StockMarket: IStockMarket | IMap<any> = {}; // Maps full stock name -> Stock object
|
storedCycles: 0,
|
||||||
|
ticksUntilCycle: 0,
|
||||||
|
} as IStockMarket; // Maps full stock name -> Stock object
|
||||||
export const SymbolToStockMap: IMap<Stock> = {}; // Maps symbol -> Stock object
|
export const SymbolToStockMap: IMap<Stock> = {}; // Maps symbol -> Stock object
|
||||||
|
|
||||||
export function placeOrder(
|
export function placeOrder(
|
||||||
@ -70,12 +68,10 @@ export function placeOrder(
|
|||||||
|
|
||||||
// Process to see if it should be executed immediately
|
// Process to see if it should be executed immediately
|
||||||
const processOrderRefs = {
|
const processOrderRefs = {
|
||||||
rerenderFn: displayStockMarketContent,
|
|
||||||
stockMarket: StockMarket as IStockMarket,
|
stockMarket: StockMarket as IStockMarket,
|
||||||
symbolToStockMap: SymbolToStockMap,
|
symbolToStockMap: SymbolToStockMap,
|
||||||
};
|
};
|
||||||
processOrders(stock, order.type, order.pos, processOrderRefs);
|
processOrders(stock, order.type, order.pos, processOrderRefs);
|
||||||
displayStockMarketContent();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -100,7 +96,6 @@ export function cancelOrder(params: ICancelOrderParams, workerScript: WorkerScri
|
|||||||
for (let i = 0; i < stockOrders.length; ++i) {
|
for (let i = 0; i < stockOrders.length; ++i) {
|
||||||
if (order == stockOrders[i]) {
|
if (order == stockOrders[i]) {
|
||||||
stockOrders.splice(i, 1);
|
stockOrders.splice(i, 1);
|
||||||
displayStockMarketContent();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -125,7 +120,6 @@ export function cancelOrder(params: ICancelOrderParams, workerScript: WorkerScri
|
|||||||
params.pos === order.pos
|
params.pos === order.pos
|
||||||
) {
|
) {
|
||||||
stockOrders.splice(i, 1);
|
stockOrders.splice(i, 1);
|
||||||
displayStockMarketContent();
|
|
||||||
if (workerScript) {
|
if (workerScript) {
|
||||||
workerScript.scriptRef.log("Successfully cancelled order: " + orderTxt);
|
workerScript.scriptRef.log("Successfully cancelled order: " + orderTxt);
|
||||||
}
|
}
|
||||||
@ -142,14 +136,24 @@ export function cancelOrder(params: ICancelOrderParams, workerScript: WorkerScri
|
|||||||
|
|
||||||
export function loadStockMarket(saveString: string): void {
|
export function loadStockMarket(saveString: string): void {
|
||||||
if (saveString === "") {
|
if (saveString === "") {
|
||||||
StockMarket = {};
|
StockMarket = {
|
||||||
|
lastUpdate: 0,
|
||||||
|
Orders: {},
|
||||||
|
storedCycles: 0,
|
||||||
|
ticksUntilCycle: 0,
|
||||||
|
} as IStockMarket;
|
||||||
} else {
|
} else {
|
||||||
StockMarket = JSON.parse(saveString, Reviver);
|
StockMarket = JSON.parse(saveString, Reviver);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function deleteStockMarket(): void {
|
export function deleteStockMarket(): void {
|
||||||
StockMarket = {};
|
StockMarket = {
|
||||||
|
lastUpdate: 0,
|
||||||
|
Orders: {},
|
||||||
|
storedCycles: 0,
|
||||||
|
ticksUntilCycle: 0,
|
||||||
|
} as IStockMarket;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function initStockMarket(): void {
|
export function initStockMarket(): void {
|
||||||
@ -269,8 +273,7 @@ export function processStockPrices(numCycles = 1): void {
|
|||||||
|
|
||||||
const c = Math.random();
|
const c = Math.random();
|
||||||
const processOrderRefs = {
|
const processOrderRefs = {
|
||||||
rerenderFn: displayStockMarketContent,
|
stockMarket: StockMarket,
|
||||||
stockMarket: StockMarket as IStockMarket,
|
|
||||||
symbolToStockMap: SymbolToStockMap,
|
symbolToStockMap: SymbolToStockMap,
|
||||||
};
|
};
|
||||||
if (c < chc) {
|
if (c < chc) {
|
||||||
@ -301,48 +304,11 @@ export function processStockPrices(numCycles = 1): void {
|
|||||||
// Shares required for price movement gradually approaches max over time
|
// Shares required for price movement gradually approaches max over time
|
||||||
stock.shareTxUntilMovement = Math.min(stock.shareTxUntilMovement + 10, stock.shareTxForMovement);
|
stock.shareTxUntilMovement = Math.min(stock.shareTxUntilMovement + 10, stock.shareTxForMovement);
|
||||||
}
|
}
|
||||||
|
|
||||||
displayStockMarketContent();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let stockMarketContainer: HTMLElement | null = null;
|
export function initStockMarketFnForReact(): void {
|
||||||
function setStockMarketContainer(): void {
|
|
||||||
stockMarketContainer = document.getElementById("generic-react-container");
|
|
||||||
document.removeEventListener("DOMContentLoaded", setStockMarketContainer);
|
|
||||||
}
|
|
||||||
|
|
||||||
document.addEventListener("DOMContentLoaded", setStockMarketContainer);
|
|
||||||
|
|
||||||
function initStockMarketFnForReact(): void {
|
|
||||||
initStockMarket();
|
initStockMarket();
|
||||||
initSymbolToStockMap();
|
initSymbolToStockMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
const eventEmitterForUiReset = new EventEmitter();
|
export const eventEmitterForUiReset = new EventEmitter();
|
||||||
|
|
||||||
export function displayStockMarketContent(): void {
|
|
||||||
if (!routing.isOn(Page.StockMarket)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
eventEmitterForUiReset.emitEvent();
|
|
||||||
|
|
||||||
if (stockMarketContainer instanceof HTMLElement) {
|
|
||||||
const castedStockMarket = StockMarket as IStockMarket;
|
|
||||||
ReactDOM.render(
|
|
||||||
<StockMarketRoot
|
|
||||||
buyStockLong={buyStock}
|
|
||||||
buyStockShort={shortStock}
|
|
||||||
cancelOrder={cancelOrder}
|
|
||||||
eventEmitterForReset={eventEmitterForUiReset}
|
|
||||||
initStockMarket={initStockMarketFnForReact}
|
|
||||||
p={Player}
|
|
||||||
placeOrder={placeOrder}
|
|
||||||
sellStockLong={sellStock}
|
|
||||||
sellStockShort={sellShort}
|
|
||||||
stockMarket={castedStockMarket}
|
|
||||||
/>,
|
|
||||||
stockMarketContainer,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1,82 +0,0 @@
|
|||||||
/**
|
|
||||||
* Root React component for the Stock Market UI
|
|
||||||
*/
|
|
||||||
import * as React from "react";
|
|
||||||
|
|
||||||
import { InfoAndPurchases } from "./InfoAndPurchases";
|
|
||||||
import { StockTickers } from "./StockTickers";
|
|
||||||
|
|
||||||
import { IStockMarket } from "../IStockMarket";
|
|
||||||
import { Stock } from "../Stock";
|
|
||||||
import { OrderTypes } from "../data/OrderTypes";
|
|
||||||
import { PositionTypes } from "../data/PositionTypes";
|
|
||||||
|
|
||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
|
||||||
import { EventEmitter } from "../../utils/EventEmitter";
|
|
||||||
|
|
||||||
type txFn = (stock: Stock, shares: number) => boolean;
|
|
||||||
export type placeOrderFn = (
|
|
||||||
stock: Stock,
|
|
||||||
shares: number,
|
|
||||||
price: number,
|
|
||||||
ordType: OrderTypes,
|
|
||||||
posType: PositionTypes,
|
|
||||||
) => boolean;
|
|
||||||
|
|
||||||
type IProps = {
|
|
||||||
buyStockLong: txFn;
|
|
||||||
buyStockShort: txFn;
|
|
||||||
cancelOrder: (params: any) => void;
|
|
||||||
eventEmitterForReset?: EventEmitter;
|
|
||||||
initStockMarket: () => void;
|
|
||||||
p: IPlayer;
|
|
||||||
placeOrder: placeOrderFn;
|
|
||||||
sellStockLong: txFn;
|
|
||||||
sellStockShort: txFn;
|
|
||||||
stockMarket: IStockMarket;
|
|
||||||
};
|
|
||||||
|
|
||||||
type IState = {
|
|
||||||
rerenderFlag: boolean;
|
|
||||||
};
|
|
||||||
|
|
||||||
export class StockMarketRoot extends React.Component<IProps, IState> {
|
|
||||||
constructor(props: IProps) {
|
|
||||||
super(props);
|
|
||||||
|
|
||||||
this.state = {
|
|
||||||
rerenderFlag: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
this.rerender = this.rerender.bind(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
rerender(): void {
|
|
||||||
this.setState((prevState) => {
|
|
||||||
return {
|
|
||||||
rerenderFlag: !prevState.rerenderFlag,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
render(): React.ReactNode {
|
|
||||||
return (
|
|
||||||
<div className="stock-market-container">
|
|
||||||
<InfoAndPurchases initStockMarket={this.props.initStockMarket} p={this.props.p} rerender={this.rerender} />
|
|
||||||
{this.props.p.hasWseAccount && (
|
|
||||||
<StockTickers
|
|
||||||
buyStockLong={this.props.buyStockLong}
|
|
||||||
buyStockShort={this.props.buyStockShort}
|
|
||||||
cancelOrder={this.props.cancelOrder}
|
|
||||||
eventEmitterForReset={this.props.eventEmitterForReset}
|
|
||||||
p={this.props.p}
|
|
||||||
placeOrder={this.props.placeOrder}
|
|
||||||
sellStockLong={this.props.sellStockLong}
|
|
||||||
sellStockShort={this.props.sellStockShort}
|
|
||||||
stockMarket={this.props.stockMarket}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
67
src/StockMarket/ui/StockMarketRoot.tsx
Normal file
67
src/StockMarket/ui/StockMarketRoot.tsx
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
/**
|
||||||
|
* Root React component for the Stock Market UI
|
||||||
|
*/
|
||||||
|
import React, { useState, useEffect } from "react";
|
||||||
|
|
||||||
|
import { InfoAndPurchases } from "./InfoAndPurchases";
|
||||||
|
import { StockTickers } from "./StockTickers";
|
||||||
|
|
||||||
|
import { IStockMarket } from "../IStockMarket";
|
||||||
|
import { Stock } from "../Stock";
|
||||||
|
import { OrderTypes } from "../data/OrderTypes";
|
||||||
|
import { PositionTypes } from "../data/PositionTypes";
|
||||||
|
|
||||||
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||||
|
import { EventEmitter } from "../../utils/EventEmitter";
|
||||||
|
|
||||||
|
type txFn = (stock: Stock, shares: number) => boolean;
|
||||||
|
export type placeOrderFn = (
|
||||||
|
stock: Stock,
|
||||||
|
shares: number,
|
||||||
|
price: number,
|
||||||
|
ordType: OrderTypes,
|
||||||
|
posType: PositionTypes,
|
||||||
|
) => boolean;
|
||||||
|
|
||||||
|
type IProps = {
|
||||||
|
buyStockLong: txFn;
|
||||||
|
buyStockShort: txFn;
|
||||||
|
cancelOrder: (params: any) => void;
|
||||||
|
eventEmitterForReset?: EventEmitter;
|
||||||
|
initStockMarket: () => void;
|
||||||
|
p: IPlayer;
|
||||||
|
placeOrder: placeOrderFn;
|
||||||
|
sellStockLong: txFn;
|
||||||
|
sellStockShort: txFn;
|
||||||
|
stockMarket: IStockMarket;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function StockMarketRoot(props: IProps): React.ReactElement {
|
||||||
|
const setRerender = useState(false)[1];
|
||||||
|
function rerender(): void {
|
||||||
|
setRerender((old) => !old);
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const id = setInterval(rerender, 200);
|
||||||
|
return () => clearInterval(id);
|
||||||
|
}, []);
|
||||||
|
return (
|
||||||
|
<div className="stock-market-container">
|
||||||
|
<InfoAndPurchases initStockMarket={props.initStockMarket} p={props.p} rerender={rerender} />
|
||||||
|
{props.p.hasWseAccount && (
|
||||||
|
<StockTickers
|
||||||
|
buyStockLong={props.buyStockLong}
|
||||||
|
buyStockShort={props.buyStockShort}
|
||||||
|
cancelOrder={props.cancelOrder}
|
||||||
|
eventEmitterForReset={props.eventEmitterForReset}
|
||||||
|
p={props.p}
|
||||||
|
placeOrder={props.placeOrder}
|
||||||
|
sellStockLong={props.sellStockLong}
|
||||||
|
sellStockShort={props.sellStockShort}
|
||||||
|
stockMarket={props.stockMarket}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
import { TextFile } from "../TextFile";
|
import { TextFile } from "../TextFile";
|
||||||
import { Script } from "../Script/Script";
|
import { Script } from "../Script/Script";
|
||||||
import { IPlayer } from "../PersonObjects/IPlayer";
|
import { IPlayer } from "../PersonObjects/IPlayer";
|
||||||
import { IEngine } from "../IEngine";
|
import { IRouter } from "../ui/Router";
|
||||||
|
|
||||||
export class Output {
|
export class Output {
|
||||||
text: string;
|
text: string;
|
||||||
@ -56,10 +56,10 @@ export interface ITerminal {
|
|||||||
startAnalyze(): void;
|
startAnalyze(): void;
|
||||||
startBackdoor(player: IPlayer): void;
|
startBackdoor(player: IPlayer): void;
|
||||||
startHack(player: IPlayer): void;
|
startHack(player: IPlayer): void;
|
||||||
finishHack(player: IPlayer, cancelled?: boolean): void;
|
finishHack(router: IRouter, player: IPlayer, cancelled?: boolean): void;
|
||||||
finishBackdoor(player: IPlayer, cancelled?: boolean): void;
|
finishBackdoor(router: IRouter, player: IPlayer, cancelled?: boolean): void;
|
||||||
finishAnalyze(player: IPlayer, cancelled?: boolean): void;
|
finishAnalyze(player: IPlayer, cancelled?: boolean): void;
|
||||||
finishAction(player: IPlayer, cancelled?: boolean): void;
|
finishAction(router: IRouter, player: IPlayer, cancelled?: boolean): void;
|
||||||
getFilepath(filename: string): string;
|
getFilepath(filename: string): string;
|
||||||
getFile(player: IPlayer, filename: string): Script | TextFile | string | null;
|
getFile(player: IPlayer, filename: string): Script | TextFile | string | null;
|
||||||
getScript(player: IPlayer, filename: string): Script | null;
|
getScript(player: IPlayer, filename: string): Script | null;
|
||||||
@ -70,11 +70,11 @@ export interface ITerminal {
|
|||||||
runContract(player: IPlayer, name: string): void;
|
runContract(player: IPlayer, name: string): void;
|
||||||
executeScanAnalyzeCommand(player: IPlayer, depth?: number, all?: boolean): void;
|
executeScanAnalyzeCommand(player: IPlayer, depth?: number, all?: boolean): void;
|
||||||
connectToServer(player: IPlayer, server: string): void;
|
connectToServer(player: IPlayer, server: string): void;
|
||||||
executeCommand(engine: IEngine, player: IPlayer, command: string): void;
|
executeCommand(router: IRouter, player: IPlayer, command: string): void;
|
||||||
executeCommands(engine: IEngine, player: IPlayer, commands: string): void;
|
executeCommands(router: IRouter, player: IPlayer, commands: string): void;
|
||||||
// If there was any changes, will return true, once.
|
// If there was any changes, will return true, once.
|
||||||
pollChanges(): boolean;
|
pollChanges(): boolean;
|
||||||
process(player: IPlayer, cycles: number): void;
|
process(router: IRouter, player: IPlayer, cycles: number): void;
|
||||||
prestige(): void;
|
prestige(): void;
|
||||||
getProgressText(): string;
|
getProgressText(): string;
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
import { ITerminal, Output, Link, TTimer } from "./ITerminal";
|
import { ITerminal, Output, Link, TTimer } from "./ITerminal";
|
||||||
import { IEngine } from "../IEngine";
|
import { IRouter } from "../ui/Router";
|
||||||
import { IPlayer } from "../PersonObjects/IPlayer";
|
import { IPlayer } from "../PersonObjects/IPlayer";
|
||||||
import { HacknetServer } from "../Hacknet/HacknetServer";
|
import { HacknetServer } from "../Hacknet/HacknetServer";
|
||||||
import { BaseServer } from "../Server/BaseServer";
|
import { BaseServer } from "../Server/BaseServer";
|
||||||
import { hackWorldDaemon } from "../RedPill";
|
|
||||||
import { Programs } from "../Programs/Programs";
|
import { Programs } from "../Programs/Programs";
|
||||||
import { CodingContractResult } from "../CodingContracts";
|
import { CodingContractResult } from "../CodingContracts";
|
||||||
|
|
||||||
@ -86,11 +85,11 @@ export class Terminal implements ITerminal {
|
|||||||
// Excludes the trailing forward slash
|
// Excludes the trailing forward slash
|
||||||
currDir = "/";
|
currDir = "/";
|
||||||
|
|
||||||
process(player: IPlayer, cycles: number): void {
|
process(router: IRouter, player: IPlayer, cycles: number): void {
|
||||||
if (this.action === null) return;
|
if (this.action === null) return;
|
||||||
this.action.timeLeft -= (CONSTANTS._idleSpeed * cycles) / 1000;
|
this.action.timeLeft -= (CONSTANTS._idleSpeed * cycles) / 1000;
|
||||||
this.hasChanges = true;
|
this.hasChanges = true;
|
||||||
if (this.action.timeLeft < 0) this.finishAction(player, false);
|
if (this.action.timeLeft < 0) this.finishAction(router, player, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
pollChanges(): boolean {
|
pollChanges(): boolean {
|
||||||
@ -138,7 +137,7 @@ export class Terminal implements ITerminal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Complete the hack/analyze command
|
// Complete the hack/analyze command
|
||||||
finishHack(player: IPlayer, cancelled = false): void {
|
finishHack(router: IRouter, player: IPlayer, cancelled = false): void {
|
||||||
if (cancelled) return;
|
if (cancelled) return;
|
||||||
const server = player.getCurrentServer();
|
const server = player.getCurrentServer();
|
||||||
|
|
||||||
@ -156,7 +155,7 @@ export class Terminal implements ITerminal {
|
|||||||
if (player.bitNodeN == null) {
|
if (player.bitNodeN == null) {
|
||||||
player.bitNodeN = 1;
|
player.bitNodeN = 1;
|
||||||
}
|
}
|
||||||
hackWorldDaemon(player.bitNodeN);
|
router.toBitVerse(false, false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
server.backdoorInstalled = true;
|
server.backdoorInstalled = true;
|
||||||
@ -190,7 +189,7 @@ export class Terminal implements ITerminal {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
finishBackdoor(player: IPlayer, cancelled = false): void {
|
finishBackdoor(router: IRouter, player: IPlayer, cancelled = false): void {
|
||||||
if (!cancelled) {
|
if (!cancelled) {
|
||||||
const server = player.getCurrentServer();
|
const server = player.getCurrentServer();
|
||||||
if (
|
if (
|
||||||
@ -200,7 +199,7 @@ export class Terminal implements ITerminal {
|
|||||||
if (player.bitNodeN == null) {
|
if (player.bitNodeN == null) {
|
||||||
player.bitNodeN = 1;
|
player.bitNodeN = 1;
|
||||||
}
|
}
|
||||||
hackWorldDaemon(player.bitNodeN);
|
router.toBitVerse(false, false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
server.backdoorInstalled = true;
|
server.backdoorInstalled = true;
|
||||||
@ -238,16 +237,16 @@ export class Terminal implements ITerminal {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
finishAction(player: IPlayer, cancelled = false): void {
|
finishAction(router: IRouter, player: IPlayer, cancelled = false): void {
|
||||||
if (this.action === null) {
|
if (this.action === null) {
|
||||||
if (!cancelled) throw new Error("Finish action called when there was no action");
|
if (!cancelled) throw new Error("Finish action called when there was no action");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.print(this.getProgressText());
|
this.print(this.getProgressText());
|
||||||
if (this.action.action === "h") {
|
if (this.action.action === "h") {
|
||||||
this.finishHack(player, cancelled);
|
this.finishHack(router, player, cancelled);
|
||||||
} else if (this.action.action === "b") {
|
} else if (this.action.action === "b") {
|
||||||
this.finishBackdoor(player, cancelled);
|
this.finishBackdoor(router, player, cancelled);
|
||||||
} else if (this.action.action === "a") {
|
} else if (this.action.action === "a") {
|
||||||
this.finishAnalyze(player, cancelled);
|
this.finishAnalyze(player, cancelled);
|
||||||
}
|
}
|
||||||
@ -468,7 +467,7 @@ export class Terminal implements ITerminal {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
executeCommands(engine: IEngine, player: IPlayer, commands: string): void {
|
executeCommands(router: IRouter, player: IPlayer, commands: string): void {
|
||||||
// Sanitize input
|
// Sanitize input
|
||||||
commands = commands.trim();
|
commands = commands.trim();
|
||||||
commands = commands.replace(/\s\s+/g, " "); // Replace all extra whitespace in command with a single space
|
commands = commands.replace(/\s\s+/g, " "); // Replace all extra whitespace in command with a single space
|
||||||
@ -484,7 +483,7 @@ export class Terminal implements ITerminal {
|
|||||||
const allCommands = ParseCommands(commands);
|
const allCommands = ParseCommands(commands);
|
||||||
|
|
||||||
for (let i = 0; i < allCommands.length; i++) {
|
for (let i = 0; i < allCommands.length; i++) {
|
||||||
this.executeCommand(engine, player, allCommands[i]);
|
this.executeCommand(router, player, allCommands[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -499,7 +498,7 @@ export class Terminal implements ITerminal {
|
|||||||
this.clear();
|
this.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
executeCommand(engine: IEngine, player: IPlayer, command: string): void {
|
executeCommand(router: IRouter, player: IPlayer, command: string): void {
|
||||||
if (this.action !== null) {
|
if (this.action !== null) {
|
||||||
this.error(`Cannot execute command (${command}) while an action is in progress`);
|
this.error(`Cannot execute command (${command}) while an action is in progress`);
|
||||||
return;
|
return;
|
||||||
@ -532,7 +531,7 @@ export class Terminal implements ITerminal {
|
|||||||
break;
|
break;
|
||||||
case iTutorialSteps.TerminalLs:
|
case iTutorialSteps.TerminalLs:
|
||||||
if (commandArray.length === 1 && commandArray[0] == "ls") {
|
if (commandArray.length === 1 && commandArray[0] == "ls") {
|
||||||
ls(this, engine, player, s, commandArray.slice(1));
|
ls(this, router, player, s, commandArray.slice(1));
|
||||||
iTutorialNextStep();
|
iTutorialNextStep();
|
||||||
} else {
|
} else {
|
||||||
this.print("Bad command. Please follow the tutorial");
|
this.print("Bad command. Please follow the tutorial");
|
||||||
@ -540,7 +539,7 @@ export class Terminal implements ITerminal {
|
|||||||
break;
|
break;
|
||||||
case iTutorialSteps.TerminalScan:
|
case iTutorialSteps.TerminalScan:
|
||||||
if (commandArray.length === 1 && commandArray[0] == "scan") {
|
if (commandArray.length === 1 && commandArray[0] == "scan") {
|
||||||
scan(this, engine, player, s, commandArray.slice(1));
|
scan(this, router, player, s, commandArray.slice(1));
|
||||||
iTutorialNextStep();
|
iTutorialNextStep();
|
||||||
} else {
|
} else {
|
||||||
this.print("Bad command. Please follow the tutorial");
|
this.print("Bad command. Please follow the tutorial");
|
||||||
@ -609,7 +608,7 @@ export class Terminal implements ITerminal {
|
|||||||
break;
|
break;
|
||||||
case iTutorialSteps.TerminalCreateScript:
|
case iTutorialSteps.TerminalCreateScript:
|
||||||
if (commandArray.length == 2 && commandArray[0] == "nano" && commandArray[1] == "n00dles.script") {
|
if (commandArray.length == 2 && commandArray[0] == "nano" && commandArray[1] == "n00dles.script") {
|
||||||
engine.loadScriptEditorContent("n00dles.script", "");
|
router.toScriptEditor("n00dles.script", "");
|
||||||
iTutorialNextStep();
|
iTutorialNextStep();
|
||||||
} else {
|
} else {
|
||||||
this.print("Bad command. Please follow the tutorial");
|
this.print("Bad command. Please follow the tutorial");
|
||||||
@ -617,7 +616,7 @@ export class Terminal implements ITerminal {
|
|||||||
break;
|
break;
|
||||||
case iTutorialSteps.TerminalFree:
|
case iTutorialSteps.TerminalFree:
|
||||||
if (commandArray.length == 1 && commandArray[0] == "free") {
|
if (commandArray.length == 1 && commandArray[0] == "free") {
|
||||||
free(this, engine, player, s, commandArray.slice(1));
|
free(this, router, player, s, commandArray.slice(1));
|
||||||
iTutorialNextStep();
|
iTutorialNextStep();
|
||||||
} else {
|
} else {
|
||||||
this.print("Bad command. Please follow the tutorial");
|
this.print("Bad command. Please follow the tutorial");
|
||||||
@ -625,7 +624,7 @@ export class Terminal implements ITerminal {
|
|||||||
break;
|
break;
|
||||||
case iTutorialSteps.TerminalRunScript:
|
case iTutorialSteps.TerminalRunScript:
|
||||||
if (commandArray.length == 2 && commandArray[0] == "run" && commandArray[1] == "n00dles.script") {
|
if (commandArray.length == 2 && commandArray[0] == "run" && commandArray[1] == "n00dles.script") {
|
||||||
run(this, engine, player, s, commandArray.slice(1));
|
run(this, router, player, s, commandArray.slice(1));
|
||||||
iTutorialNextStep();
|
iTutorialNextStep();
|
||||||
} else {
|
} else {
|
||||||
this.print("Bad command. Please follow the tutorial");
|
this.print("Bad command. Please follow the tutorial");
|
||||||
@ -662,7 +661,7 @@ export class Terminal implements ITerminal {
|
|||||||
const commands: {
|
const commands: {
|
||||||
[key: string]: (
|
[key: string]: (
|
||||||
terminal: ITerminal,
|
terminal: ITerminal,
|
||||||
engine: IEngine,
|
router: IRouter,
|
||||||
player: IPlayer,
|
player: IPlayer,
|
||||||
server: BaseServer,
|
server: BaseServer,
|
||||||
args: (string | number)[],
|
args: (string | number)[],
|
||||||
@ -713,7 +712,7 @@ export class Terminal implements ITerminal {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
f(this, engine, player, s, commandArray.slice(1));
|
f(this, router, player, s, commandArray.slice(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
getProgressText(): string {
|
getProgressText(): string {
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import { ITerminal } from "../ITerminal";
|
import { ITerminal } from "../ITerminal";
|
||||||
import { IEngine } from "../../IEngine";
|
import { IRouter } from "../../ui/Router";
|
||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||||
import { BaseServer } from "../../Server/BaseServer";
|
import { BaseServer } from "../../Server/BaseServer";
|
||||||
import { parseAliasDeclaration, printAliases } from "../../Alias";
|
import { parseAliasDeclaration, printAliases } from "../../Alias";
|
||||||
|
|
||||||
export function alias(
|
export function alias(
|
||||||
terminal: ITerminal,
|
terminal: ITerminal,
|
||||||
engine: IEngine,
|
router: IRouter,
|
||||||
player: IPlayer,
|
player: IPlayer,
|
||||||
server: BaseServer,
|
server: BaseServer,
|
||||||
args: (string | number)[],
|
args: (string | number)[],
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import { ITerminal } from "../ITerminal";
|
import { ITerminal } from "../ITerminal";
|
||||||
import { IEngine } from "../../IEngine";
|
import { IRouter } from "../../ui/Router";
|
||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||||
import { BaseServer } from "../../Server/BaseServer";
|
import { BaseServer } from "../../Server/BaseServer";
|
||||||
|
|
||||||
export function analyze(
|
export function analyze(
|
||||||
terminal: ITerminal,
|
terminal: ITerminal,
|
||||||
engine: IEngine,
|
router: IRouter,
|
||||||
player: IPlayer,
|
player: IPlayer,
|
||||||
server: BaseServer,
|
server: BaseServer,
|
||||||
args: (string | number)[],
|
args: (string | number)[],
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { ITerminal } from "../ITerminal";
|
import { ITerminal } from "../ITerminal";
|
||||||
import { IEngine } from "../../IEngine";
|
import { IRouter } from "../../ui/Router";
|
||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||||
import { BaseServer } from "../../Server/BaseServer";
|
import { BaseServer } from "../../Server/BaseServer";
|
||||||
import { Server } from "../../Server/Server";
|
import { Server } from "../../Server/Server";
|
||||||
@ -7,7 +7,7 @@ import { HacknetServer } from "../../Hacknet/HacknetServer";
|
|||||||
|
|
||||||
export function backdoor(
|
export function backdoor(
|
||||||
terminal: ITerminal,
|
terminal: ITerminal,
|
||||||
engine: IEngine,
|
router: IRouter,
|
||||||
player: IPlayer,
|
player: IPlayer,
|
||||||
server: BaseServer,
|
server: BaseServer,
|
||||||
args: (string | number)[],
|
args: (string | number)[],
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { ITerminal } from "../ITerminal";
|
import { ITerminal } from "../ITerminal";
|
||||||
import { IEngine } from "../../IEngine";
|
import { IRouter } from "../../ui/Router";
|
||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||||
import { BaseServer } from "../../Server/BaseServer";
|
import { BaseServer } from "../../Server/BaseServer";
|
||||||
import { listAllDarkwebItems, buyDarkwebItem } from "../../DarkWeb/DarkWeb";
|
import { listAllDarkwebItems, buyDarkwebItem } from "../../DarkWeb/DarkWeb";
|
||||||
@ -7,7 +7,7 @@ import { SpecialServerIps } from "../../Server/SpecialServerIps";
|
|||||||
|
|
||||||
export function buy(
|
export function buy(
|
||||||
terminal: ITerminal,
|
terminal: ITerminal,
|
||||||
engine: IEngine,
|
router: IRouter,
|
||||||
player: IPlayer,
|
player: IPlayer,
|
||||||
server: BaseServer,
|
server: BaseServer,
|
||||||
args: (string | number)[],
|
args: (string | number)[],
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { ITerminal } from "../ITerminal";
|
import { ITerminal } from "../ITerminal";
|
||||||
import { IEngine } from "../../IEngine";
|
import { IRouter } from "../../ui/Router";
|
||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||||
import { BaseServer } from "../../Server/BaseServer";
|
import { BaseServer } from "../../Server/BaseServer";
|
||||||
import { showMessage } from "../../Message/MessageHelpers";
|
import { showMessage } from "../../Message/MessageHelpers";
|
||||||
@ -8,7 +8,7 @@ import { showLiterature } from "../../Literature/LiteratureHelpers";
|
|||||||
|
|
||||||
export function cat(
|
export function cat(
|
||||||
terminal: ITerminal,
|
terminal: ITerminal,
|
||||||
engine: IEngine,
|
router: IRouter,
|
||||||
player: IPlayer,
|
player: IPlayer,
|
||||||
server: BaseServer,
|
server: BaseServer,
|
||||||
args: (string | number)[],
|
args: (string | number)[],
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { ITerminal } from "../ITerminal";
|
import { ITerminal } from "../ITerminal";
|
||||||
import { IEngine } from "../../IEngine";
|
import { IRouter } from "../../ui/Router";
|
||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||||
import { BaseServer } from "../../Server/BaseServer";
|
import { BaseServer } from "../../Server/BaseServer";
|
||||||
|
|
||||||
@ -7,7 +7,7 @@ import { evaluateDirectoryPath, removeTrailingSlash } from "../DirectoryHelpers"
|
|||||||
|
|
||||||
export function cd(
|
export function cd(
|
||||||
terminal: ITerminal,
|
terminal: ITerminal,
|
||||||
engine: IEngine,
|
router: IRouter,
|
||||||
player: IPlayer,
|
player: IPlayer,
|
||||||
server: BaseServer,
|
server: BaseServer,
|
||||||
args: (string | number)[],
|
args: (string | number)[],
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { ITerminal } from "../ITerminal";
|
import { ITerminal } from "../ITerminal";
|
||||||
import { IEngine } from "../../IEngine";
|
import { IRouter } from "../../ui/Router";
|
||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||||
import { BaseServer } from "../../Server/BaseServer";
|
import { BaseServer } from "../../Server/BaseServer";
|
||||||
import { findRunningScript } from "../../Script/ScriptHelpers";
|
import { findRunningScript } from "../../Script/ScriptHelpers";
|
||||||
@ -7,7 +7,7 @@ import { isScriptFilename } from "../../Script/ScriptHelpersTS";
|
|||||||
|
|
||||||
export function check(
|
export function check(
|
||||||
terminal: ITerminal,
|
terminal: ITerminal,
|
||||||
engine: IEngine,
|
router: IRouter,
|
||||||
player: IPlayer,
|
player: IPlayer,
|
||||||
server: BaseServer,
|
server: BaseServer,
|
||||||
args: (string | number)[],
|
args: (string | number)[],
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import { ITerminal } from "../ITerminal";
|
import { ITerminal } from "../ITerminal";
|
||||||
import { IEngine } from "../../IEngine";
|
import { IRouter } from "../../ui/Router";
|
||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||||
import { BaseServer } from "../../Server/BaseServer";
|
import { BaseServer } from "../../Server/BaseServer";
|
||||||
import { getServerOnNetwork } from "../../Server/ServerHelpers";
|
import { getServerOnNetwork } from "../../Server/ServerHelpers";
|
||||||
|
|
||||||
export function connect(
|
export function connect(
|
||||||
terminal: ITerminal,
|
terminal: ITerminal,
|
||||||
engine: IEngine,
|
router: IRouter,
|
||||||
player: IPlayer,
|
player: IPlayer,
|
||||||
server: BaseServer,
|
server: BaseServer,
|
||||||
args: (string | number)[],
|
args: (string | number)[],
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { ITerminal } from "../ITerminal";
|
import { ITerminal } from "../ITerminal";
|
||||||
import { IEngine } from "../../IEngine";
|
import { IRouter } from "../../ui/Router";
|
||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||||
import { BaseServer } from "../../Server/BaseServer";
|
import { BaseServer } from "../../Server/BaseServer";
|
||||||
import { isScriptFilename } from "../../Script/ScriptHelpersTS";
|
import { isScriptFilename } from "../../Script/ScriptHelpersTS";
|
||||||
@ -8,7 +8,7 @@ import JSZip from "jszip";
|
|||||||
|
|
||||||
export function download(
|
export function download(
|
||||||
terminal: ITerminal,
|
terminal: ITerminal,
|
||||||
engine: IEngine,
|
router: IRouter,
|
||||||
player: IPlayer,
|
player: IPlayer,
|
||||||
server: BaseServer,
|
server: BaseServer,
|
||||||
args: (string | number)[],
|
args: (string | number)[],
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import { ITerminal } from "../ITerminal";
|
import { ITerminal } from "../ITerminal";
|
||||||
import { IEngine } from "../../IEngine";
|
import { IRouter } from "../../ui/Router";
|
||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||||
import { BaseServer } from "../../Server/BaseServer";
|
import { BaseServer } from "../../Server/BaseServer";
|
||||||
|
|
||||||
export function expr(
|
export function expr(
|
||||||
terminal: ITerminal,
|
terminal: ITerminal,
|
||||||
engine: IEngine,
|
router: IRouter,
|
||||||
player: IPlayer,
|
player: IPlayer,
|
||||||
server: BaseServer,
|
server: BaseServer,
|
||||||
args: (string | number)[],
|
args: (string | number)[],
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import { ITerminal } from "../ITerminal";
|
import { ITerminal } from "../ITerminal";
|
||||||
import { IEngine } from "../../IEngine";
|
import { IRouter } from "../../ui/Router";
|
||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||||
import { BaseServer } from "../../Server/BaseServer";
|
import { BaseServer } from "../../Server/BaseServer";
|
||||||
import { numeralWrapper } from "../../ui/numeralFormat";
|
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||||
|
|
||||||
export function free(
|
export function free(
|
||||||
terminal: ITerminal,
|
terminal: ITerminal,
|
||||||
engine: IEngine,
|
router: IRouter,
|
||||||
player: IPlayer,
|
player: IPlayer,
|
||||||
server: BaseServer,
|
server: BaseServer,
|
||||||
args: (string | number)[],
|
args: (string | number)[],
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import { ITerminal } from "../ITerminal";
|
import { ITerminal } from "../ITerminal";
|
||||||
import { IEngine } from "../../IEngine";
|
import { IRouter } from "../../ui/Router";
|
||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||||
import { BaseServer } from "../../Server/BaseServer";
|
import { BaseServer } from "../../Server/BaseServer";
|
||||||
import { Server } from "../../Server/Server";
|
import { Server } from "../../Server/Server";
|
||||||
|
|
||||||
export function hack(
|
export function hack(
|
||||||
terminal: ITerminal,
|
terminal: ITerminal,
|
||||||
engine: IEngine,
|
router: IRouter,
|
||||||
player: IPlayer,
|
player: IPlayer,
|
||||||
server: BaseServer,
|
server: BaseServer,
|
||||||
args: (string | number)[],
|
args: (string | number)[],
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import { ITerminal } from "../ITerminal";
|
import { ITerminal } from "../ITerminal";
|
||||||
import { IEngine } from "../../IEngine";
|
import { IRouter } from "../../ui/Router";
|
||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||||
import { BaseServer } from "../../Server/BaseServer";
|
import { BaseServer } from "../../Server/BaseServer";
|
||||||
import { TerminalHelpText, HelpTexts } from "../HelpText";
|
import { TerminalHelpText, HelpTexts } from "../HelpText";
|
||||||
|
|
||||||
export function help(
|
export function help(
|
||||||
terminal: ITerminal,
|
terminal: ITerminal,
|
||||||
engine: IEngine,
|
router: IRouter,
|
||||||
player: IPlayer,
|
player: IPlayer,
|
||||||
server: BaseServer,
|
server: BaseServer,
|
||||||
args: (string | number)[],
|
args: (string | number)[],
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import { ITerminal } from "../ITerminal";
|
import { ITerminal } from "../ITerminal";
|
||||||
import { IEngine } from "../../IEngine";
|
import { IRouter } from "../../ui/Router";
|
||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||||
import { BaseServer } from "../../Server/BaseServer";
|
import { BaseServer } from "../../Server/BaseServer";
|
||||||
|
|
||||||
export function home(
|
export function home(
|
||||||
terminal: ITerminal,
|
terminal: ITerminal,
|
||||||
engine: IEngine,
|
router: IRouter,
|
||||||
player: IPlayer,
|
player: IPlayer,
|
||||||
server: BaseServer,
|
server: BaseServer,
|
||||||
args: (string | number)[],
|
args: (string | number)[],
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import { ITerminal } from "../ITerminal";
|
import { ITerminal } from "../ITerminal";
|
||||||
import { IEngine } from "../../IEngine";
|
import { IRouter } from "../../ui/Router";
|
||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||||
import { BaseServer } from "../../Server/BaseServer";
|
import { BaseServer } from "../../Server/BaseServer";
|
||||||
|
|
||||||
export function hostname(
|
export function hostname(
|
||||||
terminal: ITerminal,
|
terminal: ITerminal,
|
||||||
engine: IEngine,
|
router: IRouter,
|
||||||
player: IPlayer,
|
player: IPlayer,
|
||||||
server: BaseServer,
|
server: BaseServer,
|
||||||
args: (string | number)[],
|
args: (string | number)[],
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import { ITerminal } from "../ITerminal";
|
import { ITerminal } from "../ITerminal";
|
||||||
import { IEngine } from "../../IEngine";
|
import { IRouter } from "../../ui/Router";
|
||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||||
import { BaseServer } from "../../Server/BaseServer";
|
import { BaseServer } from "../../Server/BaseServer";
|
||||||
|
|
||||||
export function ifconfig(
|
export function ifconfig(
|
||||||
terminal: ITerminal,
|
terminal: ITerminal,
|
||||||
engine: IEngine,
|
router: IRouter,
|
||||||
player: IPlayer,
|
player: IPlayer,
|
||||||
server: BaseServer,
|
server: BaseServer,
|
||||||
args: (string | number)[],
|
args: (string | number)[],
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import { ITerminal } from "../ITerminal";
|
import { ITerminal } from "../ITerminal";
|
||||||
import { IEngine } from "../../IEngine";
|
import { IRouter } from "../../ui/Router";
|
||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||||
import { BaseServer } from "../../Server/BaseServer";
|
import { BaseServer } from "../../Server/BaseServer";
|
||||||
import { killWorkerScript } from "../../Netscript/killWorkerScript";
|
import { killWorkerScript } from "../../Netscript/killWorkerScript";
|
||||||
|
|
||||||
export function kill(
|
export function kill(
|
||||||
terminal: ITerminal,
|
terminal: ITerminal,
|
||||||
engine: IEngine,
|
router: IRouter,
|
||||||
player: IPlayer,
|
player: IPlayer,
|
||||||
server: BaseServer,
|
server: BaseServer,
|
||||||
args: (string | number)[],
|
args: (string | number)[],
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import { ITerminal } from "../ITerminal";
|
import { ITerminal } from "../ITerminal";
|
||||||
import { IEngine } from "../../IEngine";
|
import { IRouter } from "../../ui/Router";
|
||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||||
import { BaseServer } from "../../Server/BaseServer";
|
import { BaseServer } from "../../Server/BaseServer";
|
||||||
import { killWorkerScript } from "../../Netscript/killWorkerScript";
|
import { killWorkerScript } from "../../Netscript/killWorkerScript";
|
||||||
import { WorkerScriptStartStopEventEmitter } from "../../Netscript/WorkerScriptStartStopEventEmitter";
|
import { WorkerScriptStartStopEventEmitter } from "../../Netscript/WorkerScriptStartStopEventEmitter";
|
||||||
|
|
||||||
export function killall(terminal: ITerminal, engine: IEngine, player: IPlayer, server: BaseServer): void {
|
export function killall(terminal: ITerminal, router: IRouter, player: IPlayer, server: BaseServer): void {
|
||||||
for (let i = server.runningScripts.length - 1; i >= 0; --i) {
|
for (let i = server.runningScripts.length - 1; i >= 0; --i) {
|
||||||
killWorkerScript(server.runningScripts[i], server.ip, false);
|
killWorkerScript(server.runningScripts[i], server.ip, false);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { ITerminal } from "../ITerminal";
|
import { ITerminal } from "../ITerminal";
|
||||||
import { IEngine } from "../../IEngine";
|
import { IRouter } from "../../ui/Router";
|
||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||||
import { BaseServer } from "../../Server/BaseServer";
|
import { BaseServer } from "../../Server/BaseServer";
|
||||||
import { Message } from "../../Message/Message";
|
import { Message } from "../../Message/Message";
|
||||||
@ -7,7 +7,7 @@ import { getFirstParentDirectory, isValidDirectoryPath, evaluateDirectoryPath }
|
|||||||
|
|
||||||
export function ls(
|
export function ls(
|
||||||
terminal: ITerminal,
|
terminal: ITerminal,
|
||||||
engine: IEngine,
|
router: IRouter,
|
||||||
player: IPlayer,
|
player: IPlayer,
|
||||||
server: BaseServer,
|
server: BaseServer,
|
||||||
args: (string | number)[],
|
args: (string | number)[],
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { ITerminal } from "../ITerminal";
|
import { ITerminal } from "../ITerminal";
|
||||||
import { IEngine } from "../../IEngine";
|
import { IRouter } from "../../ui/Router";
|
||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||||
|
|
||||||
export function lscpu(terminal: ITerminal, engine: IEngine, player: IPlayer): void {
|
export function lscpu(terminal: ITerminal, router: IRouter, player: IPlayer): void {
|
||||||
terminal.print(player.getCurrentServer().cpuCores + " Core(s)");
|
terminal.print(player.getCurrentServer().cpuCores + " Core(s)");
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import { ITerminal } from "../ITerminal";
|
import { ITerminal } from "../ITerminal";
|
||||||
import { IEngine } from "../../IEngine";
|
import { IRouter } from "../../ui/Router";
|
||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||||
import { BaseServer } from "../../Server/BaseServer";
|
import { BaseServer } from "../../Server/BaseServer";
|
||||||
import { numeralWrapper } from "../../ui/numeralFormat";
|
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||||
|
|
||||||
export function mem(
|
export function mem(
|
||||||
terminal: ITerminal,
|
terminal: ITerminal,
|
||||||
engine: IEngine,
|
router: IRouter,
|
||||||
player: IPlayer,
|
player: IPlayer,
|
||||||
server: BaseServer,
|
server: BaseServer,
|
||||||
args: (string | number)[],
|
args: (string | number)[],
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { ITerminal } from "../ITerminal";
|
import { ITerminal } from "../ITerminal";
|
||||||
import { IEngine } from "../../IEngine";
|
import { IRouter } from "../../ui/Router";
|
||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||||
import { BaseServer } from "../../Server/BaseServer";
|
import { BaseServer } from "../../Server/BaseServer";
|
||||||
import { isScriptFilename } from "../../Script/ScriptHelpersTS";
|
import { isScriptFilename } from "../../Script/ScriptHelpersTS";
|
||||||
@ -8,7 +8,7 @@ import { Script } from "../../Script/Script";
|
|||||||
|
|
||||||
export function mv(
|
export function mv(
|
||||||
terminal: ITerminal,
|
terminal: ITerminal,
|
||||||
engine: IEngine,
|
router: IRouter,
|
||||||
player: IPlayer,
|
player: IPlayer,
|
||||||
server: BaseServer,
|
server: BaseServer,
|
||||||
args: (string | number)[],
|
args: (string | number)[],
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { ITerminal } from "../ITerminal";
|
import { ITerminal } from "../ITerminal";
|
||||||
import { IEngine } from "../../IEngine";
|
import { IRouter } from "../../ui/Router";
|
||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||||
import { BaseServer } from "../../Server/BaseServer";
|
import { BaseServer } from "../../Server/BaseServer";
|
||||||
import { isScriptFilename } from "../../Script/ScriptHelpersTS";
|
import { isScriptFilename } from "../../Script/ScriptHelpersTS";
|
||||||
@ -7,7 +7,7 @@ import { createFconf } from "../../Fconf/Fconf";
|
|||||||
|
|
||||||
export function nano(
|
export function nano(
|
||||||
terminal: ITerminal,
|
terminal: ITerminal,
|
||||||
engine: IEngine,
|
router: IRouter,
|
||||||
player: IPlayer,
|
player: IPlayer,
|
||||||
server: BaseServer,
|
server: BaseServer,
|
||||||
args: (string | number)[],
|
args: (string | number)[],
|
||||||
@ -21,7 +21,7 @@ export function nano(
|
|||||||
const filename = args[0] + "";
|
const filename = args[0] + "";
|
||||||
if (filename === ".fconf") {
|
if (filename === ".fconf") {
|
||||||
const text = createFconf();
|
const text = createFconf();
|
||||||
engine.loadScriptEditorContent(filename, text);
|
router.toScriptEditor(filename, text);
|
||||||
return;
|
return;
|
||||||
} else if (isScriptFilename(filename)) {
|
} else if (isScriptFilename(filename)) {
|
||||||
const filepath = terminal.getFilepath(filename);
|
const filepath = terminal.getFilepath(filename);
|
||||||
@ -33,17 +33,17 @@ export function nano(
|
|||||||
|
|
||||||
}`;
|
}`;
|
||||||
}
|
}
|
||||||
engine.loadScriptEditorContent(filepath, code);
|
router.toScriptEditor(filepath, code);
|
||||||
} else {
|
} else {
|
||||||
engine.loadScriptEditorContent(filepath, script.code);
|
router.toScriptEditor(filepath, script.code);
|
||||||
}
|
}
|
||||||
} else if (filename.endsWith(".txt")) {
|
} else if (filename.endsWith(".txt")) {
|
||||||
const filepath = terminal.getFilepath(filename);
|
const filepath = terminal.getFilepath(filename);
|
||||||
const txt = terminal.getTextFile(player, filename);
|
const txt = terminal.getTextFile(player, filename);
|
||||||
if (txt == null) {
|
if (txt == null) {
|
||||||
engine.loadScriptEditorContent(filepath);
|
router.toScriptEditor(filepath);
|
||||||
} else {
|
} else {
|
||||||
engine.loadScriptEditorContent(filepath, txt.text);
|
router.toScriptEditor(filepath, txt.text);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
terminal.error(
|
terminal.error(
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import { ITerminal } from "../ITerminal";
|
import { ITerminal } from "../ITerminal";
|
||||||
import { IEngine } from "../../IEngine";
|
import { IRouter } from "../../ui/Router";
|
||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||||
import { BaseServer } from "../../Server/BaseServer";
|
import { BaseServer } from "../../Server/BaseServer";
|
||||||
|
|
||||||
export function ps(
|
export function ps(
|
||||||
terminal: ITerminal,
|
terminal: ITerminal,
|
||||||
engine: IEngine,
|
router: IRouter,
|
||||||
player: IPlayer,
|
player: IPlayer,
|
||||||
server: BaseServer,
|
server: BaseServer,
|
||||||
args: (string | number)[],
|
args: (string | number)[],
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import { ITerminal } from "../ITerminal";
|
import { ITerminal } from "../ITerminal";
|
||||||
import { IEngine } from "../../IEngine";
|
import { IRouter } from "../../ui/Router";
|
||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||||
import { BaseServer } from "../../Server/BaseServer";
|
import { BaseServer } from "../../Server/BaseServer";
|
||||||
import { IReturnStatus } from "../../types";
|
import { IReturnStatus } from "../../types";
|
||||||
|
|
||||||
export function rm(
|
export function rm(
|
||||||
terminal: ITerminal,
|
terminal: ITerminal,
|
||||||
engine: IEngine,
|
router: IRouter,
|
||||||
player: IPlayer,
|
player: IPlayer,
|
||||||
server: BaseServer,
|
server: BaseServer,
|
||||||
args: (string | number)[],
|
args: (string | number)[],
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { ITerminal } from "../ITerminal";
|
import { ITerminal } from "../ITerminal";
|
||||||
import { IEngine } from "../../IEngine";
|
import { IRouter } from "../../ui/Router";
|
||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||||
import { BaseServer } from "../../Server/BaseServer";
|
import { BaseServer } from "../../Server/BaseServer";
|
||||||
import { isScriptFilename } from "../../Script/ScriptHelpersTS";
|
import { isScriptFilename } from "../../Script/ScriptHelpersTS";
|
||||||
@ -8,7 +8,7 @@ import { runProgram } from "./runProgram";
|
|||||||
|
|
||||||
export function run(
|
export function run(
|
||||||
terminal: ITerminal,
|
terminal: ITerminal,
|
||||||
engine: IEngine,
|
router: IRouter,
|
||||||
player: IPlayer,
|
player: IPlayer,
|
||||||
server: BaseServer,
|
server: BaseServer,
|
||||||
args: (string | number)[],
|
args: (string | number)[],
|
||||||
@ -30,11 +30,11 @@ export function run(
|
|||||||
|
|
||||||
// Check if its a script or just a program/executable
|
// Check if its a script or just a program/executable
|
||||||
if (isScriptFilename(executableName)) {
|
if (isScriptFilename(executableName)) {
|
||||||
runScript(terminal, engine, player, server, args);
|
runScript(terminal, router, player, server, args);
|
||||||
} else if (executableName.endsWith(".cct")) {
|
} else if (executableName.endsWith(".cct")) {
|
||||||
terminal.runContract(player, executableName);
|
terminal.runContract(player, executableName);
|
||||||
} else {
|
} else {
|
||||||
runProgram(terminal, engine, player, server, args);
|
runProgram(terminal, router, player, server, args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import { ITerminal } from "../ITerminal";
|
import { ITerminal } from "../ITerminal";
|
||||||
import { IEngine } from "../../IEngine";
|
import { IRouter } from "../../ui/Router";
|
||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||||
import { BaseServer } from "../../Server/BaseServer";
|
import { BaseServer } from "../../Server/BaseServer";
|
||||||
import { Programs } from "../../Programs/Programs";
|
import { Programs } from "../../Programs/Programs";
|
||||||
|
|
||||||
export function runProgram(
|
export function runProgram(
|
||||||
terminal: ITerminal,
|
terminal: ITerminal,
|
||||||
engine: IEngine,
|
router: IRouter,
|
||||||
player: IPlayer,
|
player: IPlayer,
|
||||||
server: BaseServer,
|
server: BaseServer,
|
||||||
args: (string | number)[],
|
args: (string | number)[],
|
||||||
@ -31,6 +31,7 @@ export function runProgram(
|
|||||||
for (const program of Object.values(Programs)) {
|
for (const program of Object.values(Programs)) {
|
||||||
if (program.name === programName) {
|
if (program.name === programName) {
|
||||||
program.run(
|
program.run(
|
||||||
|
router,
|
||||||
terminal,
|
terminal,
|
||||||
player,
|
player,
|
||||||
server,
|
server,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { ITerminal } from "../ITerminal";
|
import { ITerminal } from "../ITerminal";
|
||||||
import { IEngine } from "../../IEngine";
|
import { IRouter } from "../../ui/Router";
|
||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||||
import { BaseServer } from "../../Server/BaseServer";
|
import { BaseServer } from "../../Server/BaseServer";
|
||||||
import { logBoxCreate } from "../../../utils/LogBox";
|
import { logBoxCreate } from "../../../utils/LogBox";
|
||||||
@ -10,7 +10,7 @@ import * as libarg from "arg";
|
|||||||
|
|
||||||
export function runScript(
|
export function runScript(
|
||||||
terminal: ITerminal,
|
terminal: ITerminal,
|
||||||
engine: IEngine,
|
router: IRouter,
|
||||||
player: IPlayer,
|
player: IPlayer,
|
||||||
server: BaseServer,
|
server: BaseServer,
|
||||||
commandArgs: (string | number)[],
|
commandArgs: (string | number)[],
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import { ITerminal } from "../ITerminal";
|
import { ITerminal } from "../ITerminal";
|
||||||
import { IEngine } from "../../IEngine";
|
import { IRouter } from "../../ui/Router";
|
||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||||
import { BaseServer } from "../../Server/BaseServer";
|
import { BaseServer } from "../../Server/BaseServer";
|
||||||
import { getServerOnNetwork } from "../../Server/ServerHelpers";
|
import { getServerOnNetwork } from "../../Server/ServerHelpers";
|
||||||
|
|
||||||
export function scan(
|
export function scan(
|
||||||
terminal: ITerminal,
|
terminal: ITerminal,
|
||||||
engine: IEngine,
|
router: IRouter,
|
||||||
player: IPlayer,
|
player: IPlayer,
|
||||||
server: BaseServer,
|
server: BaseServer,
|
||||||
args: (string | number)[],
|
args: (string | number)[],
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import { ITerminal } from "../ITerminal";
|
import { ITerminal } from "../ITerminal";
|
||||||
import { IEngine } from "../../IEngine";
|
import { IRouter } from "../../ui/Router";
|
||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||||
import { BaseServer } from "../../Server/BaseServer";
|
import { BaseServer } from "../../Server/BaseServer";
|
||||||
import { Programs } from "../../Programs/Programs";
|
import { Programs } from "../../Programs/Programs";
|
||||||
|
|
||||||
export function scananalyze(
|
export function scananalyze(
|
||||||
terminal: ITerminal,
|
terminal: ITerminal,
|
||||||
engine: IEngine,
|
router: IRouter,
|
||||||
player: IPlayer,
|
player: IPlayer,
|
||||||
server: BaseServer,
|
server: BaseServer,
|
||||||
args: (string | number)[],
|
args: (string | number)[],
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { ITerminal } from "../ITerminal";
|
import { ITerminal } from "../ITerminal";
|
||||||
import { IEngine } from "../../IEngine";
|
import { IRouter } from "../../ui/Router";
|
||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||||
import { BaseServer } from "../../Server/BaseServer";
|
import { BaseServer } from "../../Server/BaseServer";
|
||||||
import { Message } from "../../Message/Message";
|
import { Message } from "../../Message/Message";
|
||||||
@ -8,7 +8,7 @@ import { isScriptFilename } from "../../Script/ScriptHelpersTS";
|
|||||||
|
|
||||||
export function scp(
|
export function scp(
|
||||||
terminal: ITerminal,
|
terminal: ITerminal,
|
||||||
engine: IEngine,
|
router: IRouter,
|
||||||
player: IPlayer,
|
player: IPlayer,
|
||||||
server: BaseServer,
|
server: BaseServer,
|
||||||
args: (string | number)[],
|
args: (string | number)[],
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import { ITerminal } from "../ITerminal";
|
import { ITerminal } from "../ITerminal";
|
||||||
import { IEngine } from "../../IEngine";
|
import { IRouter } from "../../ui/Router";
|
||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||||
import { BaseServer } from "../../Server/BaseServer";
|
import { BaseServer } from "../../Server/BaseServer";
|
||||||
|
|
||||||
export function sudov(
|
export function sudov(
|
||||||
terminal: ITerminal,
|
terminal: ITerminal,
|
||||||
engine: IEngine,
|
router: IRouter,
|
||||||
player: IPlayer,
|
player: IPlayer,
|
||||||
server: BaseServer,
|
server: BaseServer,
|
||||||
args: (string | number)[],
|
args: (string | number)[],
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { ITerminal } from "../ITerminal";
|
import { ITerminal } from "../ITerminal";
|
||||||
import { IEngine } from "../../IEngine";
|
import { IRouter } from "../../ui/Router";
|
||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||||
import { BaseServer } from "../../Server/BaseServer";
|
import { BaseServer } from "../../Server/BaseServer";
|
||||||
import { logBoxCreate } from "../../../utils/LogBox";
|
import { logBoxCreate } from "../../../utils/LogBox";
|
||||||
@ -9,7 +9,7 @@ import { isScriptFilename } from "../../Script/ScriptHelpersTS";
|
|||||||
|
|
||||||
export function tail(
|
export function tail(
|
||||||
terminal: ITerminal,
|
terminal: ITerminal,
|
||||||
engine: IEngine,
|
router: IRouter,
|
||||||
player: IPlayer,
|
player: IPlayer,
|
||||||
server: BaseServer,
|
server: BaseServer,
|
||||||
commandArray: (string | number)[],
|
commandArray: (string | number)[],
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import { ITerminal } from "../ITerminal";
|
import { ITerminal } from "../ITerminal";
|
||||||
import { IEngine } from "../../IEngine";
|
import { IRouter } from "../../ui/Router";
|
||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||||
import { BaseServer } from "../../Server/BaseServer";
|
import { BaseServer } from "../../Server/BaseServer";
|
||||||
import { FconfSettings } from "../../Fconf/FconfSettings";
|
import { FconfSettings } from "../../Fconf/FconfSettings";
|
||||||
|
|
||||||
export function theme(
|
export function theme(
|
||||||
terminal: ITerminal,
|
terminal: ITerminal,
|
||||||
engine: IEngine,
|
router: IRouter,
|
||||||
player: IPlayer,
|
player: IPlayer,
|
||||||
server: BaseServer,
|
server: BaseServer,
|
||||||
args: (string | number)[],
|
args: (string | number)[],
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { ITerminal } from "../ITerminal";
|
import { ITerminal } from "../ITerminal";
|
||||||
import { IEngine } from "../../IEngine";
|
import { IRouter } from "../../ui/Router";
|
||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||||
import { BaseServer } from "../../Server/BaseServer";
|
import { BaseServer } from "../../Server/BaseServer";
|
||||||
import { getRamUsageFromRunningScript } from "../../Script/RunningScriptHelpers";
|
import { getRamUsageFromRunningScript } from "../../Script/RunningScriptHelpers";
|
||||||
@ -7,7 +7,7 @@ import { numeralWrapper } from "../../ui/numeralFormat";
|
|||||||
|
|
||||||
export function top(
|
export function top(
|
||||||
terminal: ITerminal,
|
terminal: ITerminal,
|
||||||
engine: IEngine,
|
router: IRouter,
|
||||||
player: IPlayer,
|
player: IPlayer,
|
||||||
server: BaseServer,
|
server: BaseServer,
|
||||||
args: (string | number)[],
|
args: (string | number)[],
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import { ITerminal } from "../ITerminal";
|
import { ITerminal } from "../ITerminal";
|
||||||
import { IEngine } from "../../IEngine";
|
import { IRouter } from "../../ui/Router";
|
||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||||
import { BaseServer } from "../../Server/BaseServer";
|
import { BaseServer } from "../../Server/BaseServer";
|
||||||
import { removeAlias } from "../../Alias";
|
import { removeAlias } from "../../Alias";
|
||||||
|
|
||||||
export function unalias(
|
export function unalias(
|
||||||
terminal: ITerminal,
|
terminal: ITerminal,
|
||||||
engine: IEngine,
|
router: IRouter,
|
||||||
player: IPlayer,
|
player: IPlayer,
|
||||||
server: BaseServer,
|
server: BaseServer,
|
||||||
args: (string | number)[],
|
args: (string | number)[],
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import { ITerminal } from "../ITerminal";
|
import { ITerminal } from "../ITerminal";
|
||||||
import { IEngine } from "../../IEngine";
|
import { IRouter } from "../../ui/Router";
|
||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||||
import { BaseServer } from "../../Server/BaseServer";
|
import { BaseServer } from "../../Server/BaseServer";
|
||||||
import { isScriptFilename } from "../../Script/ScriptHelpersTS";
|
import { isScriptFilename } from "../../Script/ScriptHelpersTS";
|
||||||
|
|
||||||
export function wget(
|
export function wget(
|
||||||
terminal: ITerminal,
|
terminal: ITerminal,
|
||||||
engine: IEngine,
|
router: IRouter,
|
||||||
player: IPlayer,
|
player: IPlayer,
|
||||||
server: BaseServer,
|
server: BaseServer,
|
||||||
args: (string | number)[],
|
args: (string | number)[],
|
||||||
|
@ -8,7 +8,7 @@ import Paper from "@mui/material/Paper";
|
|||||||
|
|
||||||
import { KEY } from "../../../utils/helpers/keyCodes";
|
import { KEY } from "../../../utils/helpers/keyCodes";
|
||||||
import { ITerminal } from "../ITerminal";
|
import { ITerminal } from "../ITerminal";
|
||||||
import { IEngine } from "../../IEngine";
|
import { IRouter } from "../../ui/Router";
|
||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||||
import { determineAllPossibilitiesForTabCompletion } from "../determineAllPossibilitiesForTabCompletion";
|
import { determineAllPossibilitiesForTabCompletion } from "../determineAllPossibilitiesForTabCompletion";
|
||||||
import { tabCompletion } from "../tabCompletion";
|
import { tabCompletion } from "../tabCompletion";
|
||||||
@ -17,21 +17,21 @@ import { FconfSettings } from "../../Fconf/FconfSettings";
|
|||||||
const useStyles = makeStyles((theme: Theme) =>
|
const useStyles = makeStyles((theme: Theme) =>
|
||||||
createStyles({
|
createStyles({
|
||||||
textfield: {
|
textfield: {
|
||||||
margin: 0,
|
margin: theme.spacing(0),
|
||||||
width: "100%",
|
width: "100%",
|
||||||
},
|
},
|
||||||
input: {
|
input: {
|
||||||
backgroundColor: "#000",
|
backgroundColor: "#000",
|
||||||
},
|
},
|
||||||
nopadding: {
|
nopadding: {
|
||||||
padding: 0,
|
padding: theme.spacing(0),
|
||||||
},
|
},
|
||||||
preformatted: {
|
preformatted: {
|
||||||
whiteSpace: "pre-wrap",
|
whiteSpace: "pre-wrap",
|
||||||
margin: 0,
|
margin: theme.spacing(0),
|
||||||
},
|
},
|
||||||
list: {
|
list: {
|
||||||
padding: 0,
|
padding: theme.spacing(0),
|
||||||
height: "100%",
|
height: "100%",
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
@ -39,11 +39,11 @@ const useStyles = makeStyles((theme: Theme) =>
|
|||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
terminal: ITerminal;
|
terminal: ITerminal;
|
||||||
engine: IEngine;
|
router: IRouter;
|
||||||
player: IPlayer;
|
player: IPlayer;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function TerminalInput({ terminal, engine, player }: IProps): React.ReactElement {
|
export function TerminalInput({ terminal, router, player }: IProps): React.ReactElement {
|
||||||
const terminalInput = useRef<HTMLInputElement>(null);
|
const terminalInput = useRef<HTMLInputElement>(null);
|
||||||
|
|
||||||
const [value, setValue] = useState("");
|
const [value, setValue] = useState("");
|
||||||
@ -147,7 +147,7 @@ export function TerminalInput({ terminal, engine, player }: IProps): React.React
|
|||||||
if (ref) ref.focus();
|
if (ref) ref.focus();
|
||||||
// Cancel action
|
// Cancel action
|
||||||
if (event.keyCode === KEY.C && event.ctrlKey) {
|
if (event.keyCode === KEY.C && event.ctrlKey) {
|
||||||
terminal.finishAction(player, true);
|
terminal.finishAction(router, player, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
document.addEventListener("keydown", keyDown);
|
document.addEventListener("keydown", keyDown);
|
||||||
@ -159,7 +159,7 @@ export function TerminalInput({ terminal, engine, player }: IProps): React.React
|
|||||||
if (event.keyCode === KEY.ENTER && value !== "") {
|
if (event.keyCode === KEY.ENTER && value !== "") {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
terminal.print(`[${player.getCurrentServer().hostname} ~${terminal.cwd()}]> ${value}`);
|
terminal.print(`[${player.getCurrentServer().hostname} ~${terminal.cwd()}]> ${value}`);
|
||||||
terminal.executeCommands(engine, player, value);
|
terminal.executeCommands(router, player, value);
|
||||||
setValue("");
|
setValue("");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ import makeStyles from "@mui/styles/makeStyles";
|
|||||||
import createStyles from "@mui/styles/createStyles";
|
import createStyles from "@mui/styles/createStyles";
|
||||||
import Box from "@mui/material/Box";
|
import Box from "@mui/material/Box";
|
||||||
import { ITerminal, Output, Link } from "../ITerminal";
|
import { ITerminal, Output, Link } from "../ITerminal";
|
||||||
import { IEngine } from "../../IEngine";
|
import { IRouter } from "../../ui/Router";
|
||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||||
import { TerminalInput } from "./TerminalInput";
|
import { TerminalInput } from "./TerminalInput";
|
||||||
|
|
||||||
@ -42,11 +42,11 @@ const useStyles = makeStyles((theme: Theme) =>
|
|||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
terminal: ITerminal;
|
terminal: ITerminal;
|
||||||
engine: IEngine;
|
router: IRouter;
|
||||||
player: IPlayer;
|
player: IPlayer;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function TerminalRoot({ terminal, engine, player }: IProps): React.ReactElement {
|
export function TerminalRoot({ terminal, router, player }: IProps): React.ReactElement {
|
||||||
const scrollHook = useRef<HTMLDivElement>(null);
|
const scrollHook = useRef<HTMLDivElement>(null);
|
||||||
const setRerender = useState(false)[1];
|
const setRerender = useState(false)[1];
|
||||||
function rerender(): void {
|
function rerender(): void {
|
||||||
@ -76,7 +76,7 @@ export function TerminalRoot({ terminal, engine, player }: IProps): React.ReactE
|
|||||||
const classes = useStyles();
|
const classes = useStyles();
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Box width="100%" minHeight="100vh" px={1} display={"flex"} alignItems={"flex-end"}>
|
<Box width="100%" minHeight="100vh" display={"flex"} alignItems={"flex-end"}>
|
||||||
<List classes={{ root: classes.list }}>
|
<List classes={{ root: classes.list }}>
|
||||||
{terminal.outputHistory.map((item, i) => {
|
{terminal.outputHistory.map((item, i) => {
|
||||||
if (item instanceof Output)
|
if (item instanceof Output)
|
||||||
@ -110,8 +110,8 @@ export function TerminalRoot({ terminal, engine, player }: IProps): React.ReactE
|
|||||||
</List>
|
</List>
|
||||||
<div ref={scrollHook}></div>
|
<div ref={scrollHook}></div>
|
||||||
</Box>
|
</Box>
|
||||||
<Box position="sticky" bottom={0} width="100%" px={1}>
|
<Box position="sticky" bottom={0} width="100%" px={0}>
|
||||||
<TerminalInput player={player} engine={engine} terminal={terminal} />
|
<TerminalInput player={player} router={router} terminal={terminal} />
|
||||||
</Box>
|
</Box>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
510
src/engine.jsx
510
src/engine.jsx
@ -1,73 +1,44 @@
|
|||||||
/**
|
/**
|
||||||
* Game engine. Handles the main game loop as well as the main UI pages
|
* Game engine. Handles the main game loop.
|
||||||
*
|
|
||||||
* TODO: Separate UI functionality into its own component
|
|
||||||
*/
|
*/
|
||||||
import { convertTimeMsToTimeElapsedString } from "../utils/StringHelperFunctions";
|
import { convertTimeMsToTimeElapsedString } from "../utils/StringHelperFunctions";
|
||||||
import { Augmentations } from "./Augmentation/Augmentations";
|
import { Augmentations } from "./Augmentation/Augmentations";
|
||||||
import { initAugmentations, installAugmentations } from "./Augmentation/AugmentationHelpers";
|
import { initAugmentations } from "./Augmentation/AugmentationHelpers";
|
||||||
import { onExport } from "./ExportBonus";
|
|
||||||
import { AugmentationsRoot } from "./Augmentation/ui/Root";
|
|
||||||
import { AugmentationNames } from "./Augmentation/data/AugmentationNames";
|
import { AugmentationNames } from "./Augmentation/data/AugmentationNames";
|
||||||
import { initBitNodeMultipliers } from "./BitNode/BitNode";
|
import { initBitNodeMultipliers } from "./BitNode/BitNode";
|
||||||
import { Bladeburner } from "./Bladeburner/Bladeburner";
|
import { Bladeburner } from "./Bladeburner/Bladeburner";
|
||||||
import { CharacterOverview } from "./ui/React/CharacterOverview";
|
|
||||||
import { generateRandomContract } from "./CodingContractGenerator";
|
import { generateRandomContract } from "./CodingContractGenerator";
|
||||||
import { initCompanies } from "./Company/Companies";
|
import { initCompanies } from "./Company/Companies";
|
||||||
import { Corporation } from "./Corporation/Corporation";
|
import { Corporation } from "./Corporation/Corporation";
|
||||||
import { CONSTANTS } from "./Constants";
|
import { CONSTANTS } from "./Constants";
|
||||||
import { DevMenuRoot } from "./DevMenu";
|
|
||||||
import { Factions, initFactions } from "./Faction/Factions";
|
import { Factions, initFactions } from "./Faction/Factions";
|
||||||
import { processPassiveFactionRepGain, inviteToFaction } from "./Faction/FactionHelpers";
|
import { processPassiveFactionRepGain, inviteToFaction } from "./Faction/FactionHelpers";
|
||||||
import { FactionList } from "./Faction/ui/FactionList";
|
import { GameRoot, Router } from "./ui/GameRoot";
|
||||||
import { Root as BladeburnerRoot } from "./Bladeburner/ui/Root";
|
|
||||||
import { Root as GangRoot } from "./Gang/ui/Root";
|
|
||||||
import { SidebarRoot } from "./Sidebar/ui/SidebarRoot";
|
|
||||||
import { CorporationRoot } from "./Corporation/ui/CorporationRoot";
|
|
||||||
import { ResleeveRoot } from "./PersonObjects/Resleeving/ui/ResleeveRoot";
|
|
||||||
import { GameOptionsRoot } from "./ui/React/GameOptionsRoot";
|
|
||||||
import { TTheme as Theme } from "./ui/React/Theme";
|
import { TTheme as Theme } from "./ui/React/Theme";
|
||||||
import { SleeveRoot } from "./PersonObjects/Sleeve/ui/SleeveRoot";
|
|
||||||
import { displayInfiltrationContent } from "./Infiltration/Helper";
|
|
||||||
import {
|
import {
|
||||||
getHackingWorkRepGain,
|
getHackingWorkRepGain,
|
||||||
getFactionSecurityWorkRepGain,
|
getFactionSecurityWorkRepGain,
|
||||||
getFactionFieldWorkRepGain,
|
getFactionFieldWorkRepGain,
|
||||||
} from "./PersonObjects/formulas/reputation";
|
} from "./PersonObjects/formulas/reputation";
|
||||||
import { hasHacknetServers, processHacknetEarnings } from "./Hacknet/HacknetHelpers";
|
import { hasHacknetServers, processHacknetEarnings } from "./Hacknet/HacknetHelpers";
|
||||||
import { HacknetRoot } from "./Hacknet/ui/HacknetRoot";
|
|
||||||
import { iTutorialStart } from "./InteractiveTutorial";
|
import { iTutorialStart } from "./InteractiveTutorial";
|
||||||
import { LocationName } from "./Locations/data/LocationNames";
|
|
||||||
import { LocationRoot } from "./Locations/ui/Root";
|
|
||||||
import { checkForMessagesToSend, initMessages } from "./Message/MessageHelpers";
|
import { checkForMessagesToSend, initMessages } from "./Message/MessageHelpers";
|
||||||
import { inMission, currMission } from "./Missions";
|
import { inMission, currMission } from "./Missions";
|
||||||
import { workerScripts } from "./Netscript/WorkerScripts";
|
|
||||||
import { loadAllRunningScripts, updateOnlineScriptTimes } from "./NetscriptWorker";
|
import { loadAllRunningScripts, updateOnlineScriptTimes } from "./NetscriptWorker";
|
||||||
import { Player } from "./Player";
|
import { Player } from "./Player";
|
||||||
import { prestigeAugmentation } from "./Prestige";
|
|
||||||
import { ProgramsRoot } from "./Programs/ui/ProgramsRoot";
|
|
||||||
import { saveObject, loadGame } from "./SaveObject";
|
import { saveObject, loadGame } from "./SaveObject";
|
||||||
import { Root as ScriptEditorRoot } from "./ScriptEditor/ui/Root";
|
import { initForeignServers } from "./Server/AllServers";
|
||||||
import { initForeignServers, AllServers } from "./Server/AllServers";
|
|
||||||
import { Settings } from "./Settings/Settings";
|
import { Settings } from "./Settings/Settings";
|
||||||
import { updateSourceFileFlags } from "./SourceFile/SourceFileFlags";
|
import { updateSourceFileFlags } from "./SourceFile/SourceFileFlags";
|
||||||
import { initSpecialServerIps } from "./Server/SpecialServerIps";
|
import { initSpecialServerIps } from "./Server/SpecialServerIps";
|
||||||
import { initSymbolToStockMap, processStockPrices, displayStockMarketContent } from "./StockMarket/StockMarket";
|
import { initSymbolToStockMap, processStockPrices } from "./StockMarket/StockMarket";
|
||||||
import { MilestonesRoot } from "./Milestones/ui/MilestonesRoot";
|
|
||||||
import { TerminalRoot } from "./Terminal/ui/TerminalRoot";
|
|
||||||
import { Terminal } from "./Terminal";
|
import { Terminal } from "./Terminal";
|
||||||
import { TutorialRoot } from "./Tutorial/ui/TutorialRoot";
|
|
||||||
import { Sleeve } from "./PersonObjects/Sleeve/Sleeve";
|
import { Sleeve } from "./PersonObjects/Sleeve/Sleeve";
|
||||||
|
|
||||||
import { CharacterInfo } from "./ui/CharacterInfo";
|
|
||||||
import { Page, routing } from "./ui/navigationTracking";
|
|
||||||
import { Money } from "./ui/React/Money";
|
import { Money } from "./ui/React/Money";
|
||||||
import { Hashes } from "./ui/React/Hashes";
|
import { Hashes } from "./ui/React/Hashes";
|
||||||
import { Reputation } from "./ui/React/Reputation";
|
import { Reputation } from "./ui/React/Reputation";
|
||||||
|
|
||||||
import { ActiveScriptsRoot } from "./ui/ActiveScripts/Root";
|
|
||||||
import { MainMenuLinks } from "./ui/MainMenu/Links";
|
|
||||||
|
|
||||||
import { dialogBoxCreate } from "../utils/DialogBox";
|
import { dialogBoxCreate } from "../utils/DialogBox";
|
||||||
import { exceptionAlert } from "../utils/helpers/exceptionAlert";
|
import { exceptionAlert } from "../utils/helpers/exceptionAlert";
|
||||||
import { removeLoadingScreen } from "../utils/uiHelpers/removeLoadingScreen";
|
import { removeLoadingScreen } from "../utils/uiHelpers/removeLoadingScreen";
|
||||||
@ -78,367 +49,19 @@ import React from "react";
|
|||||||
import ReactDOM from "react-dom";
|
import ReactDOM from "react-dom";
|
||||||
|
|
||||||
const Engine = {
|
const Engine = {
|
||||||
// Clickable objects
|
|
||||||
Clickables: {
|
|
||||||
// Main menu buttons
|
|
||||||
saveMainMenuButton: null,
|
|
||||||
deleteMainMenuButton: null,
|
|
||||||
},
|
|
||||||
|
|
||||||
// Display objects
|
// Display objects
|
||||||
// TODO-Refactor this into its own component
|
// TODO-Refactor this into its own component
|
||||||
Display: {
|
Display: {
|
||||||
// Generic page that most react loads into.
|
|
||||||
content: null,
|
|
||||||
// Main menu content
|
|
||||||
infiltrationContent: null,
|
|
||||||
workInProgressContent: null,
|
|
||||||
redPillContent: null,
|
|
||||||
cinematicTextContent: null,
|
|
||||||
missionContent: null,
|
missionContent: null,
|
||||||
overview: null,
|
|
||||||
},
|
},
|
||||||
|
|
||||||
indexedDb: undefined,
|
indexedDb: undefined,
|
||||||
|
|
||||||
// Time variables (milliseconds unix epoch time)
|
// Time variables (milliseconds unix epoch time)
|
||||||
_lastUpdate: new Date().getTime(),
|
_lastUpdate: new Date().getTime(),
|
||||||
_idleSpeed: 200, // Speed (in ms) at which the main loop is updated
|
|
||||||
|
|
||||||
loadTerminalContent: function () {
|
|
||||||
Engine.hideAllContent();
|
|
||||||
Engine.Display.content.style.display = "block";
|
|
||||||
routing.navigateTo(Page.CharacterInfo);
|
|
||||||
ReactDOM.render(
|
|
||||||
<Theme>
|
|
||||||
<TerminalRoot terminal={Terminal} engine={this} player={Player} />
|
|
||||||
</Theme>,
|
|
||||||
Engine.Display.content,
|
|
||||||
);
|
|
||||||
MainMenuLinks.Stats.classList.add("active");
|
|
||||||
},
|
|
||||||
|
|
||||||
loadCharacterContent: function () {
|
|
||||||
Engine.hideAllContent();
|
|
||||||
Engine.Display.content.style.display = "block";
|
|
||||||
routing.navigateTo(Page.CharacterInfo);
|
|
||||||
ReactDOM.render(<CharacterInfo player={Player} />, Engine.Display.content);
|
|
||||||
MainMenuLinks.Stats.classList.add("active");
|
|
||||||
},
|
|
||||||
|
|
||||||
loadScriptEditorContent: function (filename = "", code = "") {
|
|
||||||
Engine.hideAllContent();
|
|
||||||
Engine.Display.content.style.display = "block";
|
|
||||||
routing.navigateTo(Page.ScriptEditor);
|
|
||||||
MainMenuLinks.ScriptEditor.classList.add("active");
|
|
||||||
ReactDOM.render(
|
|
||||||
<ScriptEditorRoot filename={filename} code={code} player={Player} engine={this} />,
|
|
||||||
Engine.Display.content,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
|
|
||||||
loadActiveScriptsContent: function () {
|
|
||||||
Engine.hideAllContent();
|
|
||||||
Engine.Display.content.style.display = "block";
|
|
||||||
routing.navigateTo(Page.ActiveScripts);
|
|
||||||
MainMenuLinks.ActiveScripts.classList.add("active");
|
|
||||||
ReactDOM.render(<ActiveScriptsRoot p={Player} workerScripts={workerScripts} />, Engine.Display.content);
|
|
||||||
},
|
|
||||||
|
|
||||||
loadHacknetNodesContent: function () {
|
|
||||||
Engine.hideAllContent();
|
|
||||||
Engine.Display.content.style.display = "block";
|
|
||||||
routing.navigateTo(Page.HacknetNodes);
|
|
||||||
MainMenuLinks.HacknetNodes.classList.add("active");
|
|
||||||
ReactDOM.render(<HacknetRoot player={Player} />, Engine.Display.content);
|
|
||||||
},
|
|
||||||
|
|
||||||
loadCreateProgramContent: function () {
|
|
||||||
Engine.hideAllContent();
|
|
||||||
Engine.Display.content.style.display = "block";
|
|
||||||
routing.navigateTo(Page.CreateProgram);
|
|
||||||
MainMenuLinks.CreateProgram.classList.add("active");
|
|
||||||
ReactDOM.render(
|
|
||||||
<Theme>
|
|
||||||
<ProgramsRoot player={Player} />
|
|
||||||
</Theme>,
|
|
||||||
Engine.Display.content,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
|
|
||||||
loadFactionsContent: function () {
|
|
||||||
Engine.hideAllContent();
|
|
||||||
Engine.Display.content.style.display = "block";
|
|
||||||
routing.navigateTo(Page.Factions);
|
|
||||||
MainMenuLinks.Factions.classList.add("active");
|
|
||||||
ReactDOM.render(<FactionList player={Player} engine={this} />, Engine.Display.content);
|
|
||||||
},
|
|
||||||
|
|
||||||
// TODO reactify
|
|
||||||
loadFactionContent: function () {
|
|
||||||
Engine.hideAllContent();
|
|
||||||
Engine.Display.content.style.display = "block";
|
|
||||||
routing.navigateTo(Page.Faction);
|
|
||||||
},
|
|
||||||
|
|
||||||
loadAugmentationsContent: function () {
|
|
||||||
Engine.hideAllContent();
|
|
||||||
Engine.Display.content.style.display = "block";
|
|
||||||
routing.navigateTo(Page.Augmentations);
|
|
||||||
MainMenuLinks.Augmentations.classList.add("active");
|
|
||||||
|
|
||||||
function backup() {
|
|
||||||
saveObject.exportGame();
|
|
||||||
onExport(Player);
|
|
||||||
}
|
|
||||||
|
|
||||||
ReactDOM.render(
|
|
||||||
<AugmentationsRoot exportGameFn={backup} installAugmentationsFn={installAugmentations} />,
|
|
||||||
Engine.Display.content,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
|
|
||||||
loadMilestonesContent: function () {
|
|
||||||
Engine.hideAllContent();
|
|
||||||
Engine.Display.content.style.display = "block";
|
|
||||||
routing.navigateTo(Page.Milestones);
|
|
||||||
MainMenuLinks.Milestones.classList.add("active");
|
|
||||||
ReactDOM.render(<MilestonesRoot player={Player} />, Engine.Display.content);
|
|
||||||
},
|
|
||||||
|
|
||||||
loadTutorialContent: function () {
|
|
||||||
Engine.hideAllContent();
|
|
||||||
Engine.Display.content.style.display = "block";
|
|
||||||
routing.navigateTo(Page.Tutorial);
|
|
||||||
MainMenuLinks.Tutorial.classList.add("active");
|
|
||||||
ReactDOM.render(<TutorialRoot />, Engine.Display.content);
|
|
||||||
},
|
|
||||||
|
|
||||||
loadDevMenuContent: function () {
|
|
||||||
Engine.hideAllContent();
|
|
||||||
if (process.env.NODE_ENV !== "development") {
|
|
||||||
throw new Error("Cannot create Dev Menu because you are not in a dev build");
|
|
||||||
}
|
|
||||||
Engine.Display.content.style.display = "block";
|
|
||||||
ReactDOM.render(<DevMenuRoot player={Player} engine={this} />, Engine.Display.content);
|
|
||||||
routing.navigateTo(Page.DevMenu);
|
|
||||||
MainMenuLinks.DevMenu.classList.add("active");
|
|
||||||
},
|
|
||||||
|
|
||||||
loadLocationContent: function (initiallyInCity = true) {
|
|
||||||
Engine.hideAllContent();
|
|
||||||
Engine.Display.content.style.display = "block";
|
|
||||||
routing.navigateTo(Page.Location);
|
|
||||||
MainMenuLinks.City.classList.add("active");
|
|
||||||
ReactDOM.render(
|
|
||||||
<LocationRoot initiallyInCity={initiallyInCity} engine={Engine} p={Player} />,
|
|
||||||
Engine.Display.content,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
|
|
||||||
loadTravelContent: function () {
|
|
||||||
// Same as loadLocationContent() except first set the location to the travel agency,
|
|
||||||
// and make sure that the 'City' main menu link doesnt become 'active'
|
|
||||||
Engine.hideAllContent();
|
|
||||||
Player.gotoLocation(LocationName.TravelAgency);
|
|
||||||
Engine.Display.content.style.display = "block";
|
|
||||||
routing.navigateTo(Page.Location);
|
|
||||||
MainMenuLinks.Travel.classList.add("active");
|
|
||||||
ReactDOM.render(<LocationRoot initiallyInCity={false} engine={Engine} p={Player} />, Engine.Display.content);
|
|
||||||
},
|
|
||||||
|
|
||||||
loadJobContent: function () {
|
|
||||||
// Same as loadLocationContent(), except first set the location to the job.
|
|
||||||
// Make sure that the 'City' main menu link doesnt become 'active'
|
|
||||||
if (Player.companyName == "") {
|
|
||||||
dialogBoxCreate(
|
|
||||||
"You do not currently have a job! You can visit various companies " + "in the city and try to find a job.",
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Engine.hideAllContent();
|
|
||||||
Player.gotoLocation(Player.companyName);
|
|
||||||
Engine.Display.content.style.display = "block";
|
|
||||||
routing.navigateTo(Page.Location);
|
|
||||||
MainMenuLinks.Job.classList.add("active");
|
|
||||||
ReactDOM.render(<LocationRoot initiallyInCity={false} engine={Engine} p={Player} />, Engine.Display.content);
|
|
||||||
},
|
|
||||||
|
|
||||||
// TODO reactify
|
|
||||||
loadWorkInProgressContent: function () {
|
|
||||||
Engine.hideAllContent();
|
|
||||||
const mainMenu = document.getElementById("mainmenu-container");
|
|
||||||
console.log("hiding loadWorkInProgressContent");
|
|
||||||
mainMenu.style.visibility = "hidden";
|
|
||||||
Engine.Display.workInProgressContent.style.display = "block";
|
|
||||||
console.log(Engine.Display.workInProgressContent);
|
|
||||||
routing.navigateTo(Page.WorkInProgress);
|
|
||||||
},
|
|
||||||
|
|
||||||
loadRedPillContent: function () {
|
|
||||||
Engine.hideAllContent();
|
|
||||||
const mainMenu = document.getElementById("mainmenu-container");
|
|
||||||
mainMenu.style.visibility = "hidden";
|
|
||||||
Engine.Display.redPillContent.style.display = "block";
|
|
||||||
routing.navigateTo(Page.RedPill);
|
|
||||||
},
|
|
||||||
|
|
||||||
// TODO reactify
|
|
||||||
loadCinematicTextContent: function () {
|
|
||||||
Engine.hideAllContent();
|
|
||||||
var mainMenu = document.getElementById("mainmenu-container");
|
|
||||||
mainMenu.style.visibility = "hidden";
|
|
||||||
Engine.Display.cinematicTextContent.style.display = "block";
|
|
||||||
routing.navigateTo(Page.CinematicText);
|
|
||||||
},
|
|
||||||
|
|
||||||
// TODO reactify
|
|
||||||
loadInfiltrationContent: function (name, difficulty, maxLevel) {
|
|
||||||
Engine.hideAllContent();
|
|
||||||
const mainMenu = document.getElementById("mainmenu-container");
|
|
||||||
mainMenu.style.visibility = "hidden";
|
|
||||||
Engine.Display.infiltrationContent.style.display = "block";
|
|
||||||
routing.navigateTo(Page.Infiltration);
|
|
||||||
displayInfiltrationContent(this, Player, name, difficulty, maxLevel);
|
|
||||||
},
|
|
||||||
|
|
||||||
loadStockMarketContent: function () {
|
|
||||||
Engine.hideAllContent();
|
|
||||||
Engine.Display.content.style.display = "block";
|
|
||||||
routing.navigateTo(Page.StockMarket);
|
|
||||||
MainMenuLinks.StockMarket.classList.add("active");
|
|
||||||
displayStockMarketContent();
|
|
||||||
},
|
|
||||||
|
|
||||||
loadGangContent: function () {
|
|
||||||
if (!Player.inGang()) return;
|
|
||||||
Engine.hideAllContent();
|
|
||||||
Engine.Display.content.style.display = "block";
|
|
||||||
routing.navigateTo(Page.Gang);
|
|
||||||
MainMenuLinks.Gang.classList.add("active");
|
|
||||||
ReactDOM.render(<GangRoot engine={this} gang={Player.gang} player={Player} />, Engine.Display.content);
|
|
||||||
},
|
|
||||||
|
|
||||||
loadMissionContent: function () {
|
|
||||||
Engine.hideAllContent();
|
|
||||||
document.getElementById("mainmenu-container").style.visibility = "hidden";
|
|
||||||
document.getElementById("character-overview").style.visibility = "hidden";
|
|
||||||
Engine.Display.missionContent.style.display = "block";
|
|
||||||
routing.navigateTo(Page.Mission);
|
|
||||||
},
|
|
||||||
|
|
||||||
loadCorporationContent: function () {
|
|
||||||
if (!(Player.corporation instanceof Corporation)) return;
|
|
||||||
Engine.hideAllContent();
|
|
||||||
Engine.Display.content.style.display = "block";
|
|
||||||
routing.navigateTo(Page.Corporation);
|
|
||||||
MainMenuLinks.Corporation.classList.add("active");
|
|
||||||
ReactDOM.render(<CorporationRoot corp={Player.corporation} player={Player} />, Engine.Display.content);
|
|
||||||
},
|
|
||||||
|
|
||||||
loadBladeburnerContent: function () {
|
|
||||||
if (!(Player.bladeburner instanceof Bladeburner)) return;
|
|
||||||
Engine.hideAllContent();
|
|
||||||
Engine.Display.content.style.display = "block";
|
|
||||||
routing.navigateTo(Page.Bladeburner);
|
|
||||||
MainMenuLinks.Bladeburner.classList.add("active");
|
|
||||||
ReactDOM.render(
|
|
||||||
<BladeburnerRoot bladeburner={Player.bladeburner} player={Player} engine={this} />,
|
|
||||||
Engine.Display.content,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
|
|
||||||
loadSleevesContent: function () {
|
|
||||||
Engine.hideAllContent();
|
|
||||||
Engine.Display.content.style.display = "block";
|
|
||||||
routing.navigateTo(Page.Sleeves);
|
|
||||||
ReactDOM.render(<SleeveRoot player={Player} />, Engine.Display.content);
|
|
||||||
},
|
|
||||||
|
|
||||||
loadResleevingContent: function () {
|
|
||||||
Engine.hideAllContent();
|
|
||||||
routing.navigateTo(Page.Resleeves);
|
|
||||||
Engine.Display.content.style.display = "block";
|
|
||||||
MainMenuLinks.City.classList.add("active");
|
|
||||||
ReactDOM.render(<ResleeveRoot player={Player} />, Engine.Display.content);
|
|
||||||
},
|
|
||||||
|
|
||||||
loadGameOptionsContent: function () {
|
|
||||||
Engine.hideAllContent();
|
|
||||||
routing.navigateTo(Page.GameOptions);
|
|
||||||
Engine.Display.content.style.display = "block";
|
|
||||||
MainMenuLinks.City.classList.add("active");
|
|
||||||
ReactDOM.render(
|
|
||||||
<Theme>
|
|
||||||
<GameOptionsRoot
|
|
||||||
player={Player}
|
|
||||||
save={() => saveObject.saveGame(Engine.indexedDb)}
|
|
||||||
delete={() => saveObject.deleteGame(Engine.indexedDb)}
|
|
||||||
export={() => saveObject.exportGame()}
|
|
||||||
import={() => saveObject.importGame()}
|
|
||||||
forceKill={() => {
|
|
||||||
for (const hostname of Object.keys(AllServers)) {
|
|
||||||
AllServers[hostname].runningScripts = [];
|
|
||||||
}
|
|
||||||
dialogBoxCreate("Forcefully deleted all running scripts. Please save and refresh page.");
|
|
||||||
}}
|
|
||||||
softReset={() => {
|
|
||||||
dialogBoxCreate("Soft Reset!");
|
|
||||||
prestigeAugmentation();
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Theme>,
|
|
||||||
Engine.Display.content,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
|
|
||||||
// Helper function that hides all content
|
|
||||||
hideAllContent: function () {
|
|
||||||
Engine.Display.content.style.display = "none";
|
|
||||||
Engine.Display.content.scrollTop = 0;
|
|
||||||
ReactDOM.unmountComponentAtNode(Engine.Display.content);
|
|
||||||
|
|
||||||
Engine.Display.infiltrationContent.style.display = "none";
|
|
||||||
ReactDOM.unmountComponentAtNode(Engine.Display.infiltrationContent);
|
|
||||||
|
|
||||||
Engine.Display.workInProgressContent.style.display = "none";
|
|
||||||
Engine.Display.redPillContent.style.display = "none";
|
|
||||||
Engine.Display.cinematicTextContent.style.display = "none";
|
|
||||||
Engine.Display.missionContent.style.display = "none";
|
|
||||||
},
|
|
||||||
|
|
||||||
displayCharacterOverviewInfo: function () {
|
|
||||||
console.log("rendering");
|
|
||||||
ReactDOM.render(
|
|
||||||
<Theme>
|
|
||||||
<CharacterOverview player={Player} save={() => saveObject.saveGame(Engine.indexedDb)} />
|
|
||||||
</Theme>,
|
|
||||||
document.getElementById("character-overview"),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
|
|
||||||
// Main Game Loop
|
|
||||||
idleTimer: function () {
|
|
||||||
// Get time difference
|
|
||||||
const _thisUpdate = new Date().getTime();
|
|
||||||
let diff = _thisUpdate - Engine._lastUpdate;
|
|
||||||
const offset = diff % Engine._idleSpeed;
|
|
||||||
|
|
||||||
// Divide this by cycle time to determine how many cycles have elapsed since last update
|
|
||||||
diff = Math.floor(diff / Engine._idleSpeed);
|
|
||||||
|
|
||||||
if (diff > 0) {
|
|
||||||
// Update the game engine by the calculated number of cycles
|
|
||||||
Engine._lastUpdate = _thisUpdate - offset;
|
|
||||||
Player.lastUpdate = _thisUpdate - offset;
|
|
||||||
Engine.updateGame(diff);
|
|
||||||
}
|
|
||||||
|
|
||||||
window.requestAnimationFrame(Engine.idleTimer);
|
|
||||||
},
|
|
||||||
|
|
||||||
updateGame: function (numCycles = 1) {
|
updateGame: function (numCycles = 1) {
|
||||||
const time = numCycles * Engine._idleSpeed;
|
const time = numCycles * CONSTANTS._idleSpeed;
|
||||||
if (Player.totalPlaytime == null) {
|
if (Player.totalPlaytime == null) {
|
||||||
Player.totalPlaytime = 0;
|
Player.totalPlaytime = 0;
|
||||||
}
|
}
|
||||||
@ -452,7 +75,7 @@ const Engine = {
|
|||||||
Player.playtimeSinceLastAug += time;
|
Player.playtimeSinceLastAug += time;
|
||||||
Player.playtimeSinceLastBitnode += time;
|
Player.playtimeSinceLastBitnode += time;
|
||||||
|
|
||||||
Terminal.process(Player, numCycles);
|
Terminal.process(Router, Player, numCycles);
|
||||||
|
|
||||||
// Working
|
// Working
|
||||||
if (Player.isWorking) {
|
if (Player.isWorking) {
|
||||||
@ -600,7 +223,7 @@ const Engine = {
|
|||||||
}
|
}
|
||||||
if (Player.bladeburner instanceof Bladeburner) {
|
if (Player.bladeburner instanceof Bladeburner) {
|
||||||
try {
|
try {
|
||||||
Player.bladeburner.process(Player);
|
Player.bladeburner.process(Router, Player);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
exceptionAlert("Exception caught in Bladeburner.process(): " + e);
|
exceptionAlert("Exception caught in Bladeburner.process(): " + e);
|
||||||
}
|
}
|
||||||
@ -617,42 +240,11 @@ const Engine = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* Used in game when clicking on a main menu header (NOT used for initialization)
|
|
||||||
* @param open {boolean} Whether header is being opened or closed
|
|
||||||
* @param elems {HTMLElement[]} li Elements under header
|
|
||||||
* @param links {HTMLElement[]} a elements under header
|
|
||||||
*/
|
|
||||||
toggleMainMenuHeader: function (open, elems, links) {
|
|
||||||
for (var i = 0; i < elems.length; ++i) {
|
|
||||||
if (open) {
|
|
||||||
elems[i].style.opacity = 1;
|
|
||||||
elems[i].style.maxHeight = elems[i].scrollHeight + "px";
|
|
||||||
} else {
|
|
||||||
elems[i].style.opacity = 0;
|
|
||||||
elems[i].style.maxHeight = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var i = 0; i < links.length; ++i) {
|
|
||||||
if (open) {
|
|
||||||
links[i].style.opacity = 1;
|
|
||||||
links[i].style.maxHeight = links[i].scrollHeight + "px";
|
|
||||||
links[i].style.pointerEvents = "auto";
|
|
||||||
} else {
|
|
||||||
links[i].style.opacity = 0;
|
|
||||||
links[i].style.maxHeight = null;
|
|
||||||
links[i].style.pointerEvents = "none";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
load: function (saveString) {
|
load: function (saveString) {
|
||||||
// Load game from save or create new game
|
// Load game from save or create new game
|
||||||
if (loadGame(saveString)) {
|
if (loadGame(saveString)) {
|
||||||
initBitNodeMultipliers(Player);
|
initBitNodeMultipliers(Player);
|
||||||
Engine.setDisplayElements(); // Sets variables for important DOM elements
|
Engine.setDisplayElements(); // Sets variables for important DOM elements
|
||||||
Engine.init(); // Initialize buttons, work, etc.
|
|
||||||
updateSourceFileFlags(Player);
|
updateSourceFileFlags(Player);
|
||||||
initAugmentations(); // Also calls Player.reapplyAllAugmentations()
|
initAugmentations(); // Also calls Player.reapplyAllAugmentations()
|
||||||
Player.reapplyAllSourceFiles();
|
Player.reapplyAllSourceFiles();
|
||||||
@ -664,7 +256,7 @@ const Engine = {
|
|||||||
Engine._lastUpdate = new Date().getTime();
|
Engine._lastUpdate = new Date().getTime();
|
||||||
const lastUpdate = Player.lastUpdate;
|
const lastUpdate = Player.lastUpdate;
|
||||||
const timeOffline = Engine._lastUpdate - lastUpdate;
|
const timeOffline = Engine._lastUpdate - lastUpdate;
|
||||||
const numCyclesOffline = Math.floor(timeOffline / Engine._idleSpeed);
|
const numCyclesOffline = Math.floor(timeOffline / CONSTANTS._idleSpeed);
|
||||||
|
|
||||||
let offlineReputation = 0;
|
let offlineReputation = 0;
|
||||||
const offlineHackingIncome = (Player.moneySourceA.hacking / Player.playtimeSinceLastAug) * timeOffline * 0.75;
|
const offlineHackingIncome = (Player.moneySourceA.hacking / Player.playtimeSinceLastAug) * timeOffline * 0.75;
|
||||||
@ -686,6 +278,7 @@ const Engine = {
|
|||||||
} else {
|
} else {
|
||||||
Player.work(numCyclesOffline);
|
Player.work(numCyclesOffline);
|
||||||
}
|
}
|
||||||
|
Player.focus = false;
|
||||||
} else {
|
} else {
|
||||||
for (let i = 0; i < Player.factions.length; i++) {
|
for (let i = 0; i < Player.factions.length; i++) {
|
||||||
const facName = Player.factions[i];
|
const facName = Player.factions[i];
|
||||||
@ -760,7 +353,7 @@ const Engine = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update total playtime
|
// Update total playtime
|
||||||
var time = numCyclesOffline * Engine._idleSpeed;
|
var time = numCyclesOffline * CONSTANTS._idleSpeed;
|
||||||
if (Player.totalPlaytime == null) {
|
if (Player.totalPlaytime == null) {
|
||||||
Player.totalPlaytime = 0;
|
Player.totalPlaytime = 0;
|
||||||
}
|
}
|
||||||
@ -806,79 +399,34 @@ const Engine = {
|
|||||||
|
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
<Theme>
|
<Theme>
|
||||||
<SidebarRoot engine={this} player={Player} />
|
<GameRoot terminal={Terminal} engine={this} player={Player} />
|
||||||
</Theme>,
|
</Theme>,
|
||||||
document.getElementById("sidebar"),
|
document.getElementById("mainmenu-container"),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
setDisplayElements: function () {
|
setDisplayElements: function () {
|
||||||
Engine.Display.content = document.getElementById("generic-react-container");
|
|
||||||
Engine.Display.content.style.display = "none";
|
|
||||||
|
|
||||||
Engine.Display.missionContent = document.getElementById("mission-container");
|
Engine.Display.missionContent = document.getElementById("mission-container");
|
||||||
Engine.Display.missionContent.style.display = "none";
|
Engine.Display.missionContent.style.display = "none";
|
||||||
|
|
||||||
// Work In Progress
|
|
||||||
Engine.Display.workInProgressContent = document.getElementById("work-in-progress-container");
|
|
||||||
Engine.Display.workInProgressContent.style.display = "none";
|
|
||||||
|
|
||||||
// Red Pill / Hack World Daemon
|
|
||||||
Engine.Display.redPillContent = document.getElementById("red-pill-container");
|
|
||||||
Engine.Display.redPillContent.style.display = "none";
|
|
||||||
|
|
||||||
Engine.Display.infiltrationContent = document.getElementById("infiltration-container");
|
|
||||||
Engine.Display.infiltrationContent.style.display = "none";
|
|
||||||
|
|
||||||
// Cinematic Text
|
|
||||||
Engine.Display.cinematicTextContent = document.getElementById("cinematic-text-container");
|
|
||||||
Engine.Display.cinematicTextContent.style.display = "none";
|
|
||||||
|
|
||||||
Engine.Display.overview = document.getElementById("character-overview");
|
|
||||||
},
|
|
||||||
|
|
||||||
// Initialization
|
|
||||||
init: function () {
|
|
||||||
// Player was working cancel button
|
|
||||||
|
|
||||||
Engine.displayCharacterOverviewInfo();
|
|
||||||
if (Player.isWorking) {
|
|
||||||
var cancelButton = document.getElementById("work-in-progress-cancel-button");
|
|
||||||
cancelButton.addEventListener("click", function () {
|
|
||||||
if (Player.workType == CONSTANTS.WorkTypeFaction) {
|
|
||||||
Player.finishFactionWork(true);
|
|
||||||
} else if (Player.workType == CONSTANTS.WorkTypeCreateProgram) {
|
|
||||||
Player.finishCreateProgramWork(true);
|
|
||||||
} else if (Player.workType == CONSTANTS.WorkTypeStudyClass) {
|
|
||||||
Player.finishClass();
|
|
||||||
} else if (Player.workType == CONSTANTS.WorkTypeCrime) {
|
|
||||||
Player.finishCrime(true);
|
|
||||||
} else if (Player.workType == CONSTANTS.WorkTypeCompanyPartTime) {
|
|
||||||
Player.finishWorkPartTime();
|
|
||||||
} else {
|
|
||||||
Player.finishWork(true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const focusButton = document.getElementById("work-in-progress-something-else-button");
|
|
||||||
focusButton.style.visibility = "hidden";
|
|
||||||
const focusable = [CONSTANTS.WorkTypeFaction, CONSTANTS.WorkTypeCompanyPartTime, CONSTANTS.WorkTypeCompany];
|
|
||||||
if (focusable.includes(Player.workType)) {
|
|
||||||
focusButton.style.visibility = "visible";
|
|
||||||
focusButton.addEventListener("click", function () {
|
|
||||||
Player.stopFocusing();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Engine.loadWorkInProgressContent();
|
|
||||||
} else {
|
|
||||||
Engine.loadTerminalContent();
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
start: function () {
|
start: function () {
|
||||||
// Run main loop
|
// Get time difference
|
||||||
Engine.idleTimer();
|
const _thisUpdate = new Date().getTime();
|
||||||
|
let diff = _thisUpdate - Engine._lastUpdate;
|
||||||
|
const offset = diff % CONSTANTS._idleSpeed;
|
||||||
|
|
||||||
|
// Divide this by cycle time to determine how many cycles have elapsed since last update
|
||||||
|
diff = Math.floor(diff / CONSTANTS._idleSpeed);
|
||||||
|
|
||||||
|
if (diff > 0) {
|
||||||
|
// Update the game engine by the calculated number of cycles
|
||||||
|
Engine._lastUpdate = _thisUpdate - offset;
|
||||||
|
Player.lastUpdate = _thisUpdate - offset;
|
||||||
|
Engine.updateGame(diff);
|
||||||
|
}
|
||||||
|
|
||||||
|
window.requestAnimationFrame(Engine.start);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user