Merge pull request #1356 from danielyxie/dev

can buy trp
This commit is contained in:
hydroflame 2021-09-22 11:00:31 -04:00 committed by GitHub
commit 1ba0332c53
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 450 additions and 376 deletions

24
dist/vendor.bundle.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -13,6 +13,7 @@ export interface IConstructorParams {
expMultiplier: number;
salaryMultiplier: number;
jobStatReqOffset: number;
isMegacorp?: boolean;
}
const DefaultConstructorParams: IConstructorParams = {
@ -35,6 +36,11 @@ export class Company {
*/
info: string;
/**
* Has faction associated.
*/
isMegacorp: boolean;
/**
* Object that holds all available positions in this Company.
* Position names are held in keys.
@ -79,6 +85,8 @@ export class Company {
this.playerReputation = 1;
this.favor = 0;
this.rolloverRep = 0;
this.isMegacorp = false;
if (p.isMegacorp) this.isMegacorp = true;
}
hasPosition(pos: CompanyPosition | string): boolean {

@ -45,6 +45,11 @@ export class FactionInfo {
*/
offerSecurityWork: boolean;
/**
* Keep faction on install.
*/
keep: boolean;
constructor(
infoText: JSX.Element,
enemies: string[],
@ -52,6 +57,7 @@ export class FactionInfo {
offerHackingWork: boolean,
offerFieldWork: boolean,
offerSecurityWork: boolean,
keep: boolean,
) {
this.infoText = infoText;
this.enemies = enemies;
@ -63,6 +69,7 @@ export class FactionInfo {
// These are always all 1 for now.
this.augmentationPriceMult = 1;
this.augmentationRepRequirementMult = 1;
this.keep = keep;
}
offersWork(): boolean {
@ -88,6 +95,7 @@ export const FactionInfos: IMap<FactionInfo> = {
true,
true,
false,
false,
),
Daedalus: new FactionInfo(
@ -97,6 +105,7 @@ export const FactionInfos: IMap<FactionInfo> = {
true,
true,
false,
false,
),
"The Covenant": new FactionInfo(
@ -114,6 +123,7 @@ export const FactionInfos: IMap<FactionInfo> = {
true,
true,
false,
false,
),
// Megacorporations, each forms its own faction
@ -129,6 +139,7 @@ export const FactionInfos: IMap<FactionInfo> = {
true,
true,
true,
true,
),
MegaCorp: new FactionInfo(
@ -147,6 +158,7 @@ export const FactionInfos: IMap<FactionInfo> = {
true,
true,
true,
true,
),
"Bachman & Associates": new FactionInfo(
@ -163,9 +175,10 @@ export const FactionInfos: IMap<FactionInfo> = {
true,
true,
true,
true,
),
"Blade Industries": new FactionInfo(<>Augmentation is Salvation.</>, [], true, true, true, true),
"Blade Industries": new FactionInfo(<>Augmentation is Salvation.</>, [], true, true, true, true, true),
NWO: new FactionInfo(
(
@ -180,9 +193,10 @@ export const FactionInfos: IMap<FactionInfo> = {
true,
true,
true,
true,
),
"Clarke Incorporated": new FactionInfo(<>The Power of the Genome - Unlocked.</>, [], true, true, true, true),
"Clarke Incorporated": new FactionInfo(<>The Power of the Genome - Unlocked.</>, [], true, true, true, true, true),
"OmniTek Incorporated": new FactionInfo(
<>Simply put, our mission is to design and build robots that make a difference.</>,
@ -191,6 +205,7 @@ export const FactionInfos: IMap<FactionInfo> = {
true,
true,
true,
true,
),
"Four Sigma": new FactionInfo(
@ -205,9 +220,10 @@ export const FactionInfos: IMap<FactionInfo> = {
true,
true,
true,
true,
),
"KuaiGong International": new FactionInfo(<>Dream big. Work hard. Make history.</>, [], true, true, true, true),
"KuaiGong International": new FactionInfo(<>Dream big. Work hard. Make history.</>, [], true, true, true, true, true),
// Other Corporations
"Fulcrum Secret Technologies": new FactionInfo(
@ -222,6 +238,7 @@ export const FactionInfos: IMap<FactionInfo> = {
true,
false,
true,
true,
),
// Hacker groups
@ -243,6 +260,7 @@ export const FactionInfos: IMap<FactionInfo> = {
true,
false,
false,
false,
),
"The Black Hand": new FactionInfo(
@ -261,6 +279,7 @@ export const FactionInfos: IMap<FactionInfo> = {
true,
true,
false,
false,
),
// prettier-ignore
@ -305,6 +324,7 @@ export const FactionInfos: IMap<FactionInfo> = {
true,
false,
false,
false,
),
// City factions, essentially governments
@ -315,8 +335,9 @@ export const FactionInfos: IMap<FactionInfo> = {
true,
true,
true,
false,
),
Chongqing: new FactionInfo(<>Serve the People.</>, ["Sector-12", "Aevum", "Volhaven"], true, true, true, true),
Chongqing: new FactionInfo(<>Serve the People.</>, ["Sector-12", "Aevum", "Volhaven"], true, true, true, true, false),
Ishima: new FactionInfo(
<>The East Asian Order of the Future.</>,
["Sector-12", "Aevum", "Volhaven"],
@ -324,8 +345,17 @@ export const FactionInfos: IMap<FactionInfo> = {
true,
true,
true,
false,
),
"New Tokyo": new FactionInfo(
<>Asia's World City.</>,
["Sector-12", "Aevum", "Volhaven"],
true,
true,
true,
true,
false,
),
"New Tokyo": new FactionInfo(<>Asia's World City.</>, ["Sector-12", "Aevum", "Volhaven"], true, true, true, true),
"Sector-12": new FactionInfo(
<>The City of the Future.</>,
["Chongqing", "New Tokyo", "Ishima", "Volhaven"],
@ -333,6 +363,7 @@ export const FactionInfos: IMap<FactionInfo> = {
true,
true,
true,
false,
),
Volhaven: new FactionInfo(
<>Benefit, Honor, and Glory.</>,
@ -341,6 +372,7 @@ export const FactionInfos: IMap<FactionInfo> = {
true,
true,
true,
false,
),
// Criminal Organizations/Gangs
@ -351,6 +383,7 @@ export const FactionInfos: IMap<FactionInfo> = {
true,
true,
true,
false,
),
"The Dark Army": new FactionInfo(
@ -360,9 +393,10 @@ export const FactionInfos: IMap<FactionInfo> = {
true,
true,
false,
false,
),
"The Syndicate": new FactionInfo(<>Honor holds you back.</>, [], true, true, true, true),
"The Syndicate": new FactionInfo(<>Honor holds you back.</>, [], true, true, true, true, false),
Silhouette: new FactionInfo(
(
@ -380,6 +414,7 @@ export const FactionInfos: IMap<FactionInfo> = {
true,
true,
false,
false,
),
Tetrads: new FactionInfo(
@ -389,14 +424,15 @@ export const FactionInfos: IMap<FactionInfo> = {
false,
true,
true,
false,
),
"Slum Snakes": new FactionInfo(<>Slum Snakes rule!</>, [], false, false, true, true),
"Slum Snakes": new FactionInfo(<>Slum Snakes rule!</>, [], false, false, true, true, false),
// Earlygame factions - factions the player will prestige with early on that don't belong in other categories.
Netburners: new FactionInfo(<>{"~~//*>H4CK||3T 8URN3R5**>?>\\~~"}</>, [], true, true, false, false),
Netburners: new FactionInfo(<>{"~~//*>H4CK||3T 8URN3R5**>?>\\~~"}</>, [], true, true, false, false, false),
"Tian Di Hui": new FactionInfo(<>Obey Heaven and work righteously.</>, [], true, true, false, true),
"Tian Di Hui": new FactionInfo(<>Obey Heaven and work righteously.</>, [], true, true, false, true, false),
CyberSec: new FactionInfo(
(
@ -411,6 +447,7 @@ export const FactionInfos: IMap<FactionInfo> = {
true,
false,
false,
false,
),
// Special Factions
@ -429,5 +466,6 @@ export const FactionInfos: IMap<FactionInfo> = {
false,
false,
false,
false,
),
};

@ -10,6 +10,7 @@ import { AugmentationNames } from "../../Augmentation/data/AugmentationNames";
import { Faction } from "../../Faction/Faction";
import { PurchaseAugmentationsOrderSetting } from "../../Settings/SettingEnums";
import { Settings } from "../../Settings/Settings";
import { hasAugmentationPrereqs } from "../FactionHelpers";
import { StdButton } from "../../ui/React/StdButton";
import { use } from "../../ui/Context";
@ -59,6 +60,9 @@ export function AugmentationsPage(props: IProps): React.ReactElement {
case PurchaseAugmentationsOrderSetting.Reputation: {
return getAugsSortedByReputation();
}
case PurchaseAugmentationsOrderSetting.Purchasable: {
return getAugsSortedByPurchasable();
}
default:
return getAugsSortedByDefault();
}
@ -79,6 +83,41 @@ export function AugmentationsPage(props: IProps): React.ReactElement {
return augs;
}
function getAugsSortedByPurchasable(): string[] {
const augs = getAugs();
function canBuy(augName: string): boolean {
const aug = Augmentations[augName];
const moneyCost = aug.baseCost * props.faction.getInfo().augmentationPriceMult;
const repCost = aug.baseRepRequirement * props.faction.getInfo().augmentationRepRequirementMult;
const hasReq = props.faction.playerReputation >= repCost;
const hasRep = hasAugmentationPrereqs(aug);
const hasCost =
aug.baseCost !== 0 && player.money.gt(aug.baseCost * props.faction.getInfo().augmentationPriceMult);
return hasCost && hasReq && hasRep;
}
const buy = augs.filter(canBuy).sort((augName1, augName2) => {
const aug1 = Augmentations[augName1],
aug2 = Augmentations[augName2];
if (aug1 == null || aug2 == null) {
throw new Error("Invalid Augmentation Names");
}
return aug1.baseCost - aug2.baseCost;
});
const cantBuy = augs
.filter((aug) => !canBuy(aug))
.sort((augName1, augName2) => {
const aug1 = Augmentations[augName1],
aug2 = Augmentations[augName2];
if (aug1 == null || aug2 == null) {
throw new Error("Invalid Augmentation Names");
}
return aug1.baseRepRequirement - aug2.baseRepRequirement;
});
return buy.concat(cantBuy);
}
function getAugsSortedByReputation(): string[] {
const augs = getAugs();
augs.sort((augName1, augName2) => {
@ -148,6 +187,9 @@ export function AugmentationsPage(props: IProps): React.ReactElement {
<Button onClick={() => switchSortOrder(PurchaseAugmentationsOrderSetting.Cost)}>Sort by Cost</Button>
<Button onClick={() => switchSortOrder(PurchaseAugmentationsOrderSetting.Reputation)}>Sort by Reputation</Button>
<Button onClick={() => switchSortOrder(PurchaseAugmentationsOrderSetting.Default)}>Sort by Default Order</Button>
<Button onClick={() => switchSortOrder(PurchaseAugmentationsOrderSetting.Purchasable)}>
Sort by Purchasable
</Button>
<br />
<Table size="small" padding="none">

@ -55,12 +55,14 @@ function Requirements(props: IReqProps): React.ReactElement {
return (
<React.Fragment key="f">
<TableCell key={1}>
<Typography color={color}>
<Typography>
<Money money={props.cost} player={props.p} />
</Typography>
</TableCell>
<TableCell key={2}>
<Typography color={color}>Requires {Reputation(props.rep)} faction reputation</Typography>
<Typography color={props.hasRep ? "primary" : "error"}>
Requires {Reputation(props.rep)} faction reputation
</Typography>
</TableCell>
</React.Fragment>
);
@ -78,24 +80,6 @@ export function PurchaseableAugmentation(props: IProps): React.ReactElement {
const aug = Augmentations[props.augName];
if (aug == null) throw new Error(`aug ${props.augName} does not exists`);
function getMoneyCost(): number {
return aug.baseCost * props.faction.getInfo().augmentationPriceMult;
}
function getRepCost(): number {
return aug.baseRepRequirement * props.faction.getInfo().augmentationRepRequirementMult;
}
// Whether the player has the prerequisite Augmentations
function hasPrereqs(): boolean {
return hasAugmentationPrereqs(aug);
}
// Whether the player has enough rep for this Augmentation
function hasReputation(): boolean {
return props.faction.playerReputation >= getRepCost();
}
// Whether the player has this augmentations (purchased OR installed)
function owned(): boolean {
let owned = false;
@ -123,11 +107,11 @@ export function PurchaseableAugmentation(props: IProps): React.ReactElement {
return <></>;
}
const moneyCost = getMoneyCost();
const repCost = getRepCost();
const hasReq = hasPrereqs();
const hasRep = hasReputation();
const hasCost = aug.baseCost !== 0 && props.p.money.gt(aug.baseCost * props.faction.getInfo().augmentationPriceMult);
const moneyCost = aug.baseCost * props.faction.getInfo().augmentationPriceMult;
const repCost = aug.baseRepRequirement * props.faction.getInfo().augmentationRepRequirementMult;
const hasReq = hasAugmentationPrereqs(aug);
const hasRep = props.faction.playerReputation >= repCost;
const hasCost = aug.baseCost === 0 || props.p.money.gt(aug.baseCost * props.faction.getInfo().augmentationPriceMult);
// Determine UI properties
const color: "error" | "primary" = !hasReq || !hasRep || !hasCost ? "error" : "primary";

@ -3,6 +3,9 @@ import { Milestones } from "../Milestones";
import { Milestone } from "../Milestone";
import * as React from "react";
import Typography from "@mui/material/Typography";
import Box from "@mui/material/Box";
interface IProps {
player: IPlayer;
}
@ -21,25 +24,25 @@ export function MilestonesRoot(props: IProps): JSX.Element {
const milestones = Milestones.map((milestone: Milestone, i: number) => {
if (i <= n + 1) {
return (
<ul key={i}>
<p>
[{milestone.fulfilled(props.player) ? "x" : " "}] {milestone.title}
</p>
</ul>
<Typography key={i}>
[{milestone.fulfilled(props.player) ? "x" : " "}] {milestone.title}
</Typography>
);
}
});
return (
<div className="milestones-container">
<h1>Milestones</h1>
<p>
Milestones don't reward you for completing them. They are here to guide you if you're lost. They will reset when
you install Augmentations.
</p>
<br />
<>
<Typography variant="h4">Milestones</Typography>
<Box mx={2}>
<Typography>
Milestones don't reward you for completing them. They are here to guide you if you're lost. They will reset
when you install Augmentations.
</Typography>
<br />
<h2>Completing fl1ght.exe</h2>
<li>{milestones}</li>
</div>
<Typography>Completing fl1ght.exe</Typography>
{milestones}
</Box>
</>
);
}

@ -34,21 +34,8 @@ const BitNode8StartingMoney = 250e6;
function prestigeAugmentation() {
initBitNodeMultipliers(Player);
const megaCorpFactions = [
"ECorp",
"MegaCorp",
"Bachman & Associates",
"Blade Industries",
"NWO",
"Clarke Incorporated",
"OmniTek Incorporated",
"Four Sigma",
"KuaiGong International",
"Fulcrum Secret Technologies",
];
const maintainMembership = Player.factions.filter(function (faction) {
return megaCorpFactions.includes(faction);
return Factions[faction].getInfo().keep;
});
Player.prestigeAugmentation();

@ -96,6 +96,7 @@ export enum PurchaseAugmentationsOrderSetting {
Cost,
Default,
Reputation,
Purchasable,
}
/**

@ -1,99 +1,93 @@
import React from "react";
import Typography from "@mui/material/Typography";
import Link from "@mui/material/Link";
import Box from "@mui/material/Box";
export function TutorialRoot(): React.ReactElement {
return (
<>
<h1>Tutorial (AKA Links to Documentation)</h1>
<a
id="tutorial-getting-started-link"
className="a-link-button"
target="_blank"
href="https://bitburner.readthedocs.io/en/latest/guidesandtips/gettingstartedguideforbeginnerprogrammers.html"
>
Getting Started
</a>
<br />
<br />
<a
className="a-link-button"
target="_blank"
href="https://bitburner.readthedocs.io/en/latest/basicgameplay/servers.html"
>
Servers & Networking
</a>
<br />
<br />
<a
className="a-link-button"
target="_blank"
href="https://bitburner.readthedocs.io/en/latest/basicgameplay/hacking.html"
>
Hacking
</a>
<br />
<br />
<a
className="a-link-button"
target="_blank"
href="https://bitburner.readthedocs.io/en/latest/basicgameplay/scripts.html"
>
Scripts
</a>
<br />
<br />
<a className="a-link-button" target="_blank" href="https://bitburner.readthedocs.io/en/latest/netscript.html">
Netscript Programming Language
</a>
<br />
<br />
<a
className="a-link-button"
target="_blank"
href="https://bitburner.readthedocs.io/en/latest/basicgameplay/world.html"
>
Traveling
</a>
<br />
<br />
<a
className="a-link-button"
target="_blank"
href="https://bitburner.readthedocs.io/en/latest/basicgameplay/companies.html"
>
Companies
</a>
<br />
<br />
<a
className="a-link-button"
target="_blank"
href="https://bitburner.readthedocs.io/en/latest/basicgameplay/infiltration.html"
>
Infiltration
</a>
<br />
<br />
<a
className="a-link-button"
target="_blank"
href="https://bitburner.readthedocs.io/en/latest/basicgameplay/factions.html"
>
Factions
</a>
<br />
<br />
<a
className="a-link-button"
target="_blank"
href="https://bitburner.readthedocs.io/en/latest/basicgameplay/augmentations.html"
>
Augmentations
</a>
<br />
<br />
<a className="a-link-button" target="_blank" href="https://bitburner.readthedocs.io/en/latest/shortcuts.html">
Keyboard Shortcuts
</a>
<Typography variant="h4">Tutorial (AKA Links to Documentation)</Typography>
<Box m={2}>
<Link
color="primary"
target="_blank"
href="https://bitburner.readthedocs.io/en/latest/guidesandtips/gettingstartedguideforbeginnerprogrammers.html"
>
<Typography>Getting Started</Typography>
</Link>
<br />
<Link
color="primary"
target="_blank"
href="https://bitburner.readthedocs.io/en/latest/basicgameplay/servers.html"
>
<Typography>Servers & Networking</Typography>
</Link>
<br />
<Link
color="primary"
target="_blank"
href="https://bitburner.readthedocs.io/en/latest/basicgameplay/hacking.html"
>
<Typography>Hacking</Typography>
</Link>
<br />
<Link
color="primary"
target="_blank"
href="https://bitburner.readthedocs.io/en/latest/basicgameplay/scripts.html"
>
<Typography>Scripts</Typography>
</Link>
<br />
<Link color="primary" target="_blank" href="https://bitburner.readthedocs.io/en/latest/netscript.html">
<Typography>Netscript Programming Language</Typography>
</Link>
<br />
<Link
color="primary"
target="_blank"
href="https://bitburner.readthedocs.io/en/latest/basicgameplay/world.html"
>
<Typography>Traveling</Typography>
</Link>
<br />
<Link
color="primary"
target="_blank"
href="https://bitburner.readthedocs.io/en/latest/basicgameplay/companies.html"
>
<Typography>Companies</Typography>
</Link>
<br />
<Link
color="primary"
target="_blank"
href="https://bitburner.readthedocs.io/en/latest/basicgameplay/infiltration.html"
>
<Typography>Infiltration</Typography>
</Link>
<br />
<Link
color="primary"
target="_blank"
href="https://bitburner.readthedocs.io/en/latest/basicgameplay/factions.html"
>
<Typography>Factions</Typography>
</Link>
<br />
<Link
color="primary"
target="_blank"
href="https://bitburner.readthedocs.io/en/latest/basicgameplay/augmentations.html"
>
<Typography>Augmentations</Typography>
</Link>
<br />
<Link color="primary" target="_blank" href="https://bitburner.readthedocs.io/en/latest/shortcuts.html">
<Typography>Keyboard Shortcuts</Typography>
</Link>
</Box>
</>
);
}

@ -13,6 +13,10 @@ import { Companies } from "../Company/Companies";
import { Locations } from "../Locations/Locations";
import { LocationName } from "../Locations/data/LocationNames";
import Typography from "@mui/material/Typography";
import Grid from "@mui/material/Grid";
import Button from "@mui/material/Button";
import { createProgressBarText } from "../../utils/helpers/createProgressBarText";
const CYCLES_PER_SEC = 1000 / CONSTANTS.MilliPerCycle;
@ -40,49 +44,50 @@ export function WorkInProgressRoot(): React.ReactElement {
player.stopFocusing();
}
return (
<div>
<p>
You are currently {player.currentWorkFactionDescription} for your faction {faction.name}
<br />
(Current Faction Reputation: {Reputation(faction.playerReputation)}). <br />
You have been doing this for {convertTimeMsToTimeElapsedString(player.timeWorked)}
<br />
<br />
You have earned: <br />
<br />
<Money money={player.workMoneyGained} /> (<MoneyRate money={player.workMoneyGainRate * CYCLES_PER_SEC} />){" "}
<br />
<br />
{Reputation(player.workRepGained)} ({ReputationRate(player.workRepGainRate * CYCLES_PER_SEC)}) reputation for
this faction <br />
<br />
{numeralWrapper.formatExp(player.workHackExpGained)} (
{numeralWrapper.formatExp(player.workHackExpGainRate * CYCLES_PER_SEC)} / sec) hacking exp <br />
<br />
{numeralWrapper.formatExp(player.workStrExpGained)} (
{numeralWrapper.formatExp(player.workStrExpGainRate * CYCLES_PER_SEC)} / sec) strength exp <br />
{numeralWrapper.formatExp(player.workDefExpGained)} (
{numeralWrapper.formatExp(player.workDefExpGainRate * CYCLES_PER_SEC)} / sec) defense exp <br />
{numeralWrapper.formatExp(player.workDexExpGained)} (
{numeralWrapper.formatExp(player.workDexExpGainRate * CYCLES_PER_SEC)} / sec) dexterity exp <br />
{numeralWrapper.formatExp(player.workAgiExpGained)} (
{numeralWrapper.formatExp(player.workAgiExpGainRate * CYCLES_PER_SEC)} / sec) agility exp <br />
<br />
{numeralWrapper.formatExp(player.workChaExpGained)} (
{numeralWrapper.formatExp(player.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.
</p>
<button onClick={cancel} className="work-button">
Stop Faction Work
</button>
<button onClick={unfocus} className="work-button">
Do something else simultaneously
</button>
</div>
<Grid container direction="column" justifyContent="center" alignItems="center" style={{ minHeight: "100vh" }}>
<Grid item>
<Typography>
You are currently {player.currentWorkFactionDescription} for your faction {faction.name}
<br />
(Current Faction Reputation: {Reputation(faction.playerReputation)}). <br />
You have been doing this for {convertTimeMsToTimeElapsedString(player.timeWorked)}
<br />
<br />
You have earned: <br />
<br />
<Money money={player.workMoneyGained} /> (<MoneyRate money={player.workMoneyGainRate * CYCLES_PER_SEC} />){" "}
<br />
<br />
{Reputation(player.workRepGained)} ({ReputationRate(player.workRepGainRate * CYCLES_PER_SEC)}) reputation
for this faction <br />
<br />
{numeralWrapper.formatExp(player.workHackExpGained)} (
{numeralWrapper.formatExp(player.workHackExpGainRate * CYCLES_PER_SEC)} / sec) hacking exp <br />
<br />
{numeralWrapper.formatExp(player.workStrExpGained)} (
{numeralWrapper.formatExp(player.workStrExpGainRate * CYCLES_PER_SEC)} / sec) strength exp <br />
{numeralWrapper.formatExp(player.workDefExpGained)} (
{numeralWrapper.formatExp(player.workDefExpGainRate * CYCLES_PER_SEC)} / sec) defense exp <br />
{numeralWrapper.formatExp(player.workDexExpGained)} (
{numeralWrapper.formatExp(player.workDexExpGainRate * CYCLES_PER_SEC)} / sec) dexterity exp <br />
{numeralWrapper.formatExp(player.workAgiExpGained)} (
{numeralWrapper.formatExp(player.workAgiExpGainRate * CYCLES_PER_SEC)} / sec) agility exp <br />
<br />
{numeralWrapper.formatExp(player.workChaExpGained)} (
{numeralWrapper.formatExp(player.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.
</Typography>
</Grid>
<Grid item>
<Button sx={{ mx: 2 }} onClick={cancel}>
Stop Faction Work
</Button>
<Button onClick={unfocus}>Do something else simultaneously</Button>
</Grid>
</Grid>
);
}
@ -110,35 +115,36 @@ export function WorkInProgressRoot(): React.ReactElement {
}
return (
<div>
<p>
You have been {className} for {convertTimeMsToTimeElapsedString(player.timeWorked)}
<br />
<br />
This has cost you: <br />
<Money money={-player.workMoneyGained} /> (<MoneyRate money={player.workMoneyLossRate * CYCLES_PER_SEC} />){" "}
<br />
<br />
You have gained: <br />
{numeralWrapper.formatExp(player.workHackExpGained)} (
{numeralWrapper.formatExp(player.workHackExpGainRate * CYCLES_PER_SEC)} / sec) hacking exp <br />
{numeralWrapper.formatExp(player.workStrExpGained)} (
{numeralWrapper.formatExp(player.workStrExpGainRate * CYCLES_PER_SEC)} / sec) strength exp <br />
{numeralWrapper.formatExp(player.workDefExpGained)} (
{numeralWrapper.formatExp(player.workDefExpGainRate * CYCLES_PER_SEC)} / sec) defense exp <br />
{numeralWrapper.formatExp(player.workDexExpGained)} (
{numeralWrapper.formatExp(player.workDexExpGainRate * CYCLES_PER_SEC)} / sec) dexterity exp <br />
{numeralWrapper.formatExp(player.workAgiExpGained)} (
{numeralWrapper.formatExp(player.workAgiExpGainRate * CYCLES_PER_SEC)} / sec) agility exp <br />
{numeralWrapper.formatExp(player.workChaExpGained)} (
{numeralWrapper.formatExp(player.workChaExpGainRate * CYCLES_PER_SEC)} / sec) charisma exp <br />
You may cancel at any time
</p>
<button onClick={cancel} className="work-button">
{stopText}
</button>
</div>
<Grid container direction="column" justifyContent="center" alignItems="center" style={{ minHeight: "100vh" }}>
<Grid item>
<Typography>
You have been {className} for {convertTimeMsToTimeElapsedString(player.timeWorked)}
<br />
<br />
This has cost you: <br />
<Money money={-player.workMoneyGained} /> (<MoneyRate money={player.workMoneyLossRate * CYCLES_PER_SEC} />){" "}
<br />
<br />
You have gained: <br />
{numeralWrapper.formatExp(player.workHackExpGained)} (
{numeralWrapper.formatExp(player.workHackExpGainRate * CYCLES_PER_SEC)} / sec) hacking exp <br />
{numeralWrapper.formatExp(player.workStrExpGained)} (
{numeralWrapper.formatExp(player.workStrExpGainRate * CYCLES_PER_SEC)} / sec) strength exp <br />
{numeralWrapper.formatExp(player.workDefExpGained)} (
{numeralWrapper.formatExp(player.workDefExpGainRate * CYCLES_PER_SEC)} / sec) defense exp <br />
{numeralWrapper.formatExp(player.workDexExpGained)} (
{numeralWrapper.formatExp(player.workDexExpGainRate * CYCLES_PER_SEC)} / sec) dexterity exp <br />
{numeralWrapper.formatExp(player.workAgiExpGained)} (
{numeralWrapper.formatExp(player.workAgiExpGainRate * CYCLES_PER_SEC)} / sec) agility exp <br />
{numeralWrapper.formatExp(player.workChaExpGained)} (
{numeralWrapper.formatExp(player.workChaExpGainRate * CYCLES_PER_SEC)} / sec) charisma exp <br />
You may cancel at any time
</Typography>
</Grid>
<Grid item>
<Button onClick={cancel}>{stopText}</Button>
</Grid>
</Grid>
);
}
@ -165,54 +171,55 @@ export function WorkInProgressRoot(): React.ReactElement {
const penaltyString = penalty === 0.5 ? "half" : "three-quarters";
return (
<div>
<p>
You are currently working as a {position} at {player.companyName} (Current Company Reputation:{" "}
{Reputation(companyRep)})<br />
<br />
You have been working for {convertTimeMsToTimeElapsedString(player.timeWorked)}
<br />
<br />
You have earned: <br />
<br />
<Money money={player.workMoneyGained} /> (<MoneyRate money={player.workMoneyGainRate * CYCLES_PER_SEC} />){" "}
<br />
<br />
{Reputation(player.workRepGained)} ({ReputationRate(player.workRepGainRate * CYCLES_PER_SEC)}) reputation for
this company <br />
<br />
{numeralWrapper.formatExp(player.workHackExpGained)} (
{`${numeralWrapper.formatExp(player.workHackExpGainRate * CYCLES_PER_SEC)} / sec`}
) hacking exp <br />
<br />
{numeralWrapper.formatExp(player.workStrExpGained)} (
{`${numeralWrapper.formatExp(player.workStrExpGainRate * CYCLES_PER_SEC)} / sec`}
) strength exp <br />
{numeralWrapper.formatExp(player.workDefExpGained)} (
{`${numeralWrapper.formatExp(player.workDefExpGainRate * CYCLES_PER_SEC)} / sec`}
) defense exp <br />
{numeralWrapper.formatExp(player.workDexExpGained)} (
{`${numeralWrapper.formatExp(player.workDexExpGainRate * CYCLES_PER_SEC)} / sec`}
) dexterity exp <br />
{numeralWrapper.formatExp(player.workAgiExpGained)} (
{`${numeralWrapper.formatExp(player.workAgiExpGainRate * CYCLES_PER_SEC)} / sec`}
) agility exp <br />
<br />
{numeralWrapper.formatExp(player.workChaExpGained)} (
{`${numeralWrapper.formatExp(player.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.
</p>
<button onClick={cancel} className="work-button">
Stop Working
</button>
<button onClick={unfocus} className="work-button">
Do something else simultaneously
</button>
</div>
<Grid container direction="column" justifyContent="center" alignItems="center" style={{ minHeight: "100vh" }}>
<Grid item>
<Typography>
You are currently working as a {position} at {player.companyName} (Current Company Reputation:{" "}
{Reputation(companyRep)})<br />
<br />
You have been working for {convertTimeMsToTimeElapsedString(player.timeWorked)}
<br />
<br />
You have earned: <br />
<br />
<Money money={player.workMoneyGained} /> (<MoneyRate money={player.workMoneyGainRate * CYCLES_PER_SEC} />){" "}
<br />
<br />
{Reputation(player.workRepGained)} ({ReputationRate(player.workRepGainRate * CYCLES_PER_SEC)}) reputation
for this company <br />
<br />
{numeralWrapper.formatExp(player.workHackExpGained)} (
{`${numeralWrapper.formatExp(player.workHackExpGainRate * CYCLES_PER_SEC)} / sec`}
) hacking exp <br />
<br />
{numeralWrapper.formatExp(player.workStrExpGained)} (
{`${numeralWrapper.formatExp(player.workStrExpGainRate * CYCLES_PER_SEC)} / sec`}
) strength exp <br />
{numeralWrapper.formatExp(player.workDefExpGained)} (
{`${numeralWrapper.formatExp(player.workDefExpGainRate * CYCLES_PER_SEC)} / sec`}
) defense exp <br />
{numeralWrapper.formatExp(player.workDexExpGained)} (
{`${numeralWrapper.formatExp(player.workDexExpGainRate * CYCLES_PER_SEC)} / sec`}
) dexterity exp <br />
{numeralWrapper.formatExp(player.workAgiExpGained)} (
{`${numeralWrapper.formatExp(player.workAgiExpGainRate * CYCLES_PER_SEC)} / sec`}
) agility exp <br />
<br />
{numeralWrapper.formatExp(player.workChaExpGained)} (
{`${numeralWrapper.formatExp(player.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.
</Typography>
</Grid>
<Grid item>
<Button sx={{ mx: 2 }} onClick={cancel}>
Stop Working
</Button>
<Button onClick={unfocus}>Do something else simultaneously</Button>
</Grid>
</Grid>
);
}
@ -234,55 +241,56 @@ export function WorkInProgressRoot(): React.ReactElement {
const position = player.jobs[player.companyName];
return (
<div>
<p>
You are currently working as a {position} at {player.companyName} (Current Company Reputation:{" "}
{Reputation(companyRep)})<br />
<br />
You have been working for {convertTimeMsToTimeElapsedString(player.timeWorked)}
<br />
<br />
You have earned: <br />
<br />
<Money money={player.workMoneyGained} /> (<MoneyRate money={player.workMoneyGainRate * CYCLES_PER_SEC} />){" "}
<br />
<br />
{Reputation(player.workRepGained)} (
{Reputation(`${numeralWrapper.formatExp(player.workRepGainRate * CYCLES_PER_SEC)} / sec`)}
) reputation for this company <br />
<br />
{numeralWrapper.formatExp(player.workHackExpGained)} (
{`${numeralWrapper.formatExp(player.workHackExpGainRate * CYCLES_PER_SEC)} / sec`}
) hacking exp <br />
<br />
{numeralWrapper.formatExp(player.workStrExpGained)} (
{`${numeralWrapper.formatExp(player.workStrExpGainRate * CYCLES_PER_SEC)} / sec`}
) strength exp <br />
{numeralWrapper.formatExp(player.workDefExpGained)} (
{`${numeralWrapper.formatExp(player.workDefExpGainRate * CYCLES_PER_SEC)} / sec`}
) defense exp <br />
{numeralWrapper.formatExp(player.workDexExpGained)} (
{`${numeralWrapper.formatExp(player.workDexExpGainRate * CYCLES_PER_SEC)} / sec`}
) dexterity exp <br />
{numeralWrapper.formatExp(player.workAgiExpGained)} (
{`${numeralWrapper.formatExp(player.workAgiExpGainRate * CYCLES_PER_SEC)} / sec`}
) agility exp <br />
<br />
{numeralWrapper.formatExp(player.workChaExpGained)} (
{`${numeralWrapper.formatExp(player.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.
</p>
<button onClick={cancel} className="work-button">
Stop Working
</button>
<button onClick={unfocus} className="work-button">
Do something else simultaneously
</button>
</div>
<Grid container direction="column" justifyContent="center" alignItems="center" style={{ minHeight: "100vh" }}>
<Grid item>
<Typography>
You are currently working as a {position} at {player.companyName} (Current Company Reputation:{" "}
{Reputation(companyRep)})<br />
<br />
You have been working for {convertTimeMsToTimeElapsedString(player.timeWorked)}
<br />
<br />
You have earned: <br />
<br />
<Money money={player.workMoneyGained} /> (<MoneyRate money={player.workMoneyGainRate * CYCLES_PER_SEC} />){" "}
<br />
<br />
{Reputation(player.workRepGained)} (
{Reputation(`${numeralWrapper.formatExp(player.workRepGainRate * CYCLES_PER_SEC)} / sec`)}
) reputation for this company <br />
<br />
{numeralWrapper.formatExp(player.workHackExpGained)} (
{`${numeralWrapper.formatExp(player.workHackExpGainRate * CYCLES_PER_SEC)} / sec`}
) hacking exp <br />
<br />
{numeralWrapper.formatExp(player.workStrExpGained)} (
{`${numeralWrapper.formatExp(player.workStrExpGainRate * CYCLES_PER_SEC)} / sec`}
) strength exp <br />
{numeralWrapper.formatExp(player.workDefExpGained)} (
{`${numeralWrapper.formatExp(player.workDefExpGainRate * CYCLES_PER_SEC)} / sec`}
) defense exp <br />
{numeralWrapper.formatExp(player.workDexExpGained)} (
{`${numeralWrapper.formatExp(player.workDexExpGainRate * CYCLES_PER_SEC)} / sec`}
) dexterity exp <br />
{numeralWrapper.formatExp(player.workAgiExpGained)} (
{`${numeralWrapper.formatExp(player.workAgiExpGainRate * CYCLES_PER_SEC)} / sec`}
) agility exp <br />
<br />
{numeralWrapper.formatExp(player.workChaExpGained)} (
{`${numeralWrapper.formatExp(player.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.
</Typography>
</Grid>
<Grid item>
<Button sx={{ mx: 2 }} onClick={cancel}>
Stop Working
</Button>
<Button onClick={unfocus}>Do something else simultaneously</Button>
</Grid>
</Grid>
);
}
@ -299,51 +307,60 @@ export function WorkInProgressRoot(): React.ReactElement {
const progressBar = createProgressBarText({ progress: (numBars + 1) / 20, totalTicks: 20 });
return (
<div>
<p>You are attempting to {player.crimeType}.</p>
<br />
<Grid container direction="column" justifyContent="center" alignItems="center" style={{ minHeight: "100vh" }}>
<Grid item>
<Typography>
<p>You are attempting to {player.crimeType}.</p>
<br />
<p>Time remaining: {convertTimeMsToTimeElapsedString(player.timeNeededToCompleteWork - player.timeWorked)}</p>
<p>
Time remaining: {convertTimeMsToTimeElapsedString(player.timeNeededToCompleteWork - player.timeWorked)}
</p>
<br />
<pre>{progressBar}</pre>
<button
className="work-button"
onClick={() => {
router.toLocation(Locations[LocationName.Slums]);
player.finishCrime(true);
}}
>
Cancel crime
</button>
</div>
<br />
<pre>{progressBar}</pre>
</Typography>
</Grid>
<Grid item>
<Button
onClick={() => {
router.toLocation(Locations[LocationName.Slums]);
player.finishCrime(true);
}}
>
Cancel crime
</Button>
</Grid>
</Grid>
);
}
if (player.createProgramName !== "") {
return (
<div>
<p>
You are currently working on coding {player.createProgramName}.<br />
<br />
You have been working for {convertTimeMsToTimeElapsedString(player.timeWorked)}
<br />
<br />
The program is {((player.timeWorkedCreateProgram / player.timeNeededToCompleteWork) * 100).toFixed(2)}
% complete. <br />
If you cancel, your work will be saved and you can come back to complete the program later.
</p>
<button
className="work-button"
onClick={() => {
player.finishCreateProgramWork(true);
router.toTerminal();
}}
>
Cancel work on creating program
</button>
</div>
<Grid container direction="column" justifyContent="center" alignItems="center" style={{ minHeight: "100vh" }}>
<Grid item>
<Typography>
You are currently working on coding {player.createProgramName}.<br />
<br />
You have been working for {convertTimeMsToTimeElapsedString(player.timeWorked)}
<br />
<br />
The program is {((player.timeWorkedCreateProgram / player.timeNeededToCompleteWork) * 100).toFixed(2)}
% complete. <br />
If you cancel, your work will be saved and you can come back to complete the program later.
</Typography>
</Grid>
<Grid item>
<Button
onClick={() => {
player.finishCreateProgramWork(true);
router.toTerminal();
}}
>
Cancel work on creating program
</Button>
</Grid>
</Grid>
);
}