mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2026-05-06 15:47:52 +02:00
Merge branch 'dev' into cityFix
This commit is contained in:
@@ -21,7 +21,7 @@ function constructLocation(p: IConstructorParams): Location {
|
||||
throw new Error(`Invalid constructor parameters for Location. No 'name' property`);
|
||||
}
|
||||
|
||||
if (Locations[p.name] instanceof Location) {
|
||||
if (Locations[p.name]) {
|
||||
console.warn(`Property with name ${p.name} already exists and is being overwritten`);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
/**
|
||||
* Location and traveling-related helper functions.
|
||||
* Mostly used for UI
|
||||
*/
|
||||
import { SpecialServers } from "../Server/data/SpecialServers";
|
||||
import { CONSTANTS } from "../Constants";
|
||||
|
||||
import { IPlayer } from "../PersonObjects/IPlayer";
|
||||
import { GetServer } from "../Server/AllServers";
|
||||
|
||||
import { dialogBoxCreate } from "../ui/React/DialogBox";
|
||||
|
||||
/**
|
||||
* Attempt to purchase a TOR router
|
||||
* @param {IPlayer} p - Player object
|
||||
*/
|
||||
export function purchaseTorRouter(p: IPlayer): void {
|
||||
if (p.hasTorRouter()) {
|
||||
dialogBoxCreate(`You already have a TOR Router!`);
|
||||
return;
|
||||
}
|
||||
if (!p.canAfford(CONSTANTS.TorRouterCost)) {
|
||||
dialogBoxCreate("You cannot afford to purchase the TOR router!");
|
||||
return;
|
||||
}
|
||||
p.loseMoney(CONSTANTS.TorRouterCost, "other");
|
||||
|
||||
const darkweb = GetServer(SpecialServers.DarkWeb);
|
||||
if (!darkweb) {
|
||||
throw new Error("Dark web is not a server.");
|
||||
}
|
||||
|
||||
p.getHomeComputer().serversOnNetwork.push(darkweb.hostname);
|
||||
darkweb.serversOnNetwork.push(p.getHomeComputer().hostname);
|
||||
dialogBoxCreate(
|
||||
"You have purchased a TOR router!<br>" +
|
||||
"You now have access to the dark web from your home computer.<br>" +
|
||||
"Use the scan/scan-analyze commands to search for the dark web connection.",
|
||||
);
|
||||
}
|
||||
@@ -7,7 +7,7 @@ import { Company } from "../../Company/Company";
|
||||
import { CompanyPosition } from "../../Company/CompanyPosition";
|
||||
import { getJobRequirementText } from "../../Company/GetJobRequirementText";
|
||||
|
||||
import { use } from "../../ui/Context";
|
||||
import { Player } from "../../Player";
|
||||
import Button from "@mui/material/Button";
|
||||
import Tooltip from "@mui/material/Tooltip";
|
||||
|
||||
@@ -19,10 +19,8 @@ type IProps = {
|
||||
};
|
||||
|
||||
export function ApplyToJobButton(props: IProps): React.ReactElement {
|
||||
const player = use.Player();
|
||||
|
||||
function getJobRequirementTooltip(): string {
|
||||
const pos = player.getNextCompanyPosition(props.company, props.entryPosType);
|
||||
const pos = Player.getNextCompanyPosition(props.company, props.entryPosType);
|
||||
if (pos == null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ import { Blackjack, DECK_COUNT } from "../../Casino/Blackjack";
|
||||
import { CoinFlip } from "../../Casino/CoinFlip";
|
||||
import { Roulette } from "../../Casino/Roulette";
|
||||
import { SlotMachine } from "../../Casino/SlotMachine";
|
||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||
import { Box } from "@mui/material";
|
||||
|
||||
enum GameType {
|
||||
@@ -20,11 +19,7 @@ enum GameType {
|
||||
Blackjack = "blackjack",
|
||||
}
|
||||
|
||||
type IProps = {
|
||||
p: IPlayer;
|
||||
};
|
||||
|
||||
export function CasinoLocation(props: IProps): React.ReactElement {
|
||||
export function CasinoLocation(): React.ReactElement {
|
||||
const [game, setGame] = useState(GameType.None);
|
||||
|
||||
function updateGame(game: GameType): void {
|
||||
@@ -44,10 +39,10 @@ export function CasinoLocation(props: IProps): React.ReactElement {
|
||||
{game !== GameType.None && (
|
||||
<>
|
||||
<Button onClick={() => updateGame(GameType.None)}>Stop playing</Button>
|
||||
{game === GameType.Coin && <CoinFlip p={props.p} />}
|
||||
{game === GameType.Slots && <SlotMachine p={props.p} />}
|
||||
{game === GameType.Roulette && <Roulette p={props.p} />}
|
||||
{game === GameType.Blackjack && <Blackjack p={props.p} />}
|
||||
{game === GameType.Coin && <CoinFlip />}
|
||||
{game === GameType.Slots && <SlotMachine />}
|
||||
{game === GameType.Roulette && <Roulette />}
|
||||
{game === GameType.Blackjack && <Blackjack />}
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
|
||||
@@ -12,8 +12,8 @@ import { Locations } from "../Locations";
|
||||
import { Location } from "../Location";
|
||||
import { Settings } from "../../Settings/Settings";
|
||||
|
||||
import { Router } from "../../ui/GameRoot";
|
||||
import { Player } from "../../Player";
|
||||
import { Router } from "../../ui/GameRoot";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import Button from "@mui/material/Button";
|
||||
import { LocationType } from "../LocationTypeEnum";
|
||||
|
||||
@@ -15,13 +15,13 @@ import { Locations } from "../Locations";
|
||||
import { LocationName } from "../data/LocationNames";
|
||||
|
||||
import { Companies } from "../../Company/Companies";
|
||||
import { CompanyPosition } from "../../Company/CompanyPosition";
|
||||
import { CompanyPositions } from "../../Company/CompanyPositions";
|
||||
import * as posNames from "../../Company/data/companypositionnames";
|
||||
|
||||
import { Reputation } from "../../ui/React/Reputation";
|
||||
import { Favor } from "../../ui/React/Favor";
|
||||
import { use } from "../../ui/Context";
|
||||
import { Router } from "../../ui/GameRoot";
|
||||
import { Player } from "../../Player";
|
||||
import { QuitJobModal } from "../../Company/ui/QuitJobModal";
|
||||
import { CompanyWork } from "../../Work/CompanyWork";
|
||||
|
||||
@@ -30,8 +30,6 @@ type IProps = {
|
||||
};
|
||||
|
||||
export function CompanyLocation(props: IProps): React.ReactElement {
|
||||
const p = use.Player();
|
||||
const router = use.Router();
|
||||
const [quitOpen, setQuitOpen] = useState(false);
|
||||
const setRerender = useState(false)[1];
|
||||
function rerender(): void {
|
||||
@@ -60,7 +58,7 @@ export function CompanyLocation(props: IProps): React.ReactElement {
|
||||
/**
|
||||
* Name of company position that player holds, if applicable
|
||||
*/
|
||||
const jobTitle = p.jobs[props.locName] ? p.jobs[props.locName] : null;
|
||||
const jobTitle = Player.jobs[props.locName] ? Player.jobs[props.locName] : null;
|
||||
|
||||
/**
|
||||
* CompanyPosition object for the job that the player holds at this company
|
||||
@@ -68,13 +66,13 @@ export function CompanyLocation(props: IProps): React.ReactElement {
|
||||
*/
|
||||
const companyPosition = jobTitle ? CompanyPositions[jobTitle] : null;
|
||||
|
||||
p.location = props.locName;
|
||||
Player.location = props.locName;
|
||||
|
||||
function applyForAgentJob(e: React.MouseEvent<HTMLElement>): void {
|
||||
if (!e.isTrusted) {
|
||||
return;
|
||||
}
|
||||
p.applyForAgentJob();
|
||||
Player.applyForAgentJob();
|
||||
rerender();
|
||||
}
|
||||
|
||||
@@ -82,7 +80,7 @@ export function CompanyLocation(props: IProps): React.ReactElement {
|
||||
if (!e.isTrusted) {
|
||||
return;
|
||||
}
|
||||
p.applyForBusinessConsultantJob();
|
||||
Player.applyForBusinessConsultantJob();
|
||||
rerender();
|
||||
}
|
||||
|
||||
@@ -90,7 +88,7 @@ export function CompanyLocation(props: IProps): React.ReactElement {
|
||||
if (!e.isTrusted) {
|
||||
return;
|
||||
}
|
||||
p.applyForBusinessJob();
|
||||
Player.applyForBusinessJob();
|
||||
rerender();
|
||||
}
|
||||
|
||||
@@ -98,7 +96,7 @@ export function CompanyLocation(props: IProps): React.ReactElement {
|
||||
if (!e.isTrusted) {
|
||||
return;
|
||||
}
|
||||
p.applyForEmployeeJob();
|
||||
Player.applyForEmployeeJob();
|
||||
rerender();
|
||||
}
|
||||
|
||||
@@ -106,7 +104,7 @@ export function CompanyLocation(props: IProps): React.ReactElement {
|
||||
if (!e.isTrusted) {
|
||||
return;
|
||||
}
|
||||
p.applyForItJob();
|
||||
Player.applyForItJob();
|
||||
rerender();
|
||||
}
|
||||
|
||||
@@ -114,7 +112,7 @@ export function CompanyLocation(props: IProps): React.ReactElement {
|
||||
if (!e.isTrusted) {
|
||||
return;
|
||||
}
|
||||
p.applyForPartTimeEmployeeJob();
|
||||
Player.applyForPartTimeEmployeeJob();
|
||||
rerender();
|
||||
}
|
||||
|
||||
@@ -122,7 +120,7 @@ export function CompanyLocation(props: IProps): React.ReactElement {
|
||||
if (!e.isTrusted) {
|
||||
return;
|
||||
}
|
||||
p.applyForPartTimeWaiterJob();
|
||||
Player.applyForPartTimeWaiterJob();
|
||||
rerender();
|
||||
}
|
||||
|
||||
@@ -130,7 +128,7 @@ export function CompanyLocation(props: IProps): React.ReactElement {
|
||||
if (!e.isTrusted) {
|
||||
return;
|
||||
}
|
||||
p.applyForSecurityJob();
|
||||
Player.applyForSecurityJob();
|
||||
rerender();
|
||||
}
|
||||
|
||||
@@ -138,7 +136,7 @@ export function CompanyLocation(props: IProps): React.ReactElement {
|
||||
if (!e.isTrusted) {
|
||||
return;
|
||||
}
|
||||
p.applyForSoftwareConsultantJob();
|
||||
Player.applyForSoftwareConsultantJob();
|
||||
rerender();
|
||||
}
|
||||
|
||||
@@ -146,7 +144,7 @@ export function CompanyLocation(props: IProps): React.ReactElement {
|
||||
if (!e.isTrusted) {
|
||||
return;
|
||||
}
|
||||
p.applyForSoftwareJob();
|
||||
Player.applyForSoftwareJob();
|
||||
rerender();
|
||||
}
|
||||
|
||||
@@ -154,7 +152,7 @@ export function CompanyLocation(props: IProps): React.ReactElement {
|
||||
if (!e.isTrusted) {
|
||||
return;
|
||||
}
|
||||
p.applyForWaiterJob();
|
||||
Player.applyForWaiterJob();
|
||||
rerender();
|
||||
}
|
||||
|
||||
@@ -166,7 +164,7 @@ export function CompanyLocation(props: IProps): React.ReactElement {
|
||||
if (!loc.infiltrationData)
|
||||
throw new Error(`trying to start infiltration at ${props.locName} but the infiltrationData is null`);
|
||||
|
||||
router.toInfiltration(loc);
|
||||
Router.toInfiltration(loc);
|
||||
}
|
||||
|
||||
function work(e: React.MouseEvent<HTMLElement>): void {
|
||||
@@ -175,15 +173,15 @@ export function CompanyLocation(props: IProps): React.ReactElement {
|
||||
}
|
||||
|
||||
const pos = companyPosition;
|
||||
if (pos instanceof CompanyPosition) {
|
||||
p.startWork(
|
||||
if (pos) {
|
||||
Player.startWork(
|
||||
new CompanyWork({
|
||||
singularity: false,
|
||||
companyName: props.locName,
|
||||
}),
|
||||
);
|
||||
p.startFocusing();
|
||||
router.toWork();
|
||||
Player.startFocusing();
|
||||
Router.toWork();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,29 +3,28 @@ import Button from "@mui/material/Button";
|
||||
import Tooltip from "@mui/material/Tooltip";
|
||||
import Typography from "@mui/material/Typography";
|
||||
|
||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||
import { Player } from "../../Player";
|
||||
|
||||
import { Money } from "../../ui/React/Money";
|
||||
import { MathJaxWrapper } from "../../MathJaxWrapper";
|
||||
|
||||
type IProps = {
|
||||
p: IPlayer;
|
||||
rerender: () => void;
|
||||
};
|
||||
|
||||
export function CoresButton(props: IProps): React.ReactElement {
|
||||
const homeComputer = props.p.getHomeComputer();
|
||||
const homeComputer = Player.getHomeComputer();
|
||||
const maxCores = homeComputer.cpuCores >= 8;
|
||||
if (maxCores) {
|
||||
return <Button>Upgrade 'home' cores - MAX</Button>;
|
||||
}
|
||||
|
||||
const cost = props.p.getUpgradeHomeCoresCost();
|
||||
const cost = Player.getUpgradeHomeCoresCost();
|
||||
|
||||
function buy(): void {
|
||||
if (maxCores) return;
|
||||
if (!props.p.canAfford(cost)) return;
|
||||
props.p.loseMoney(cost, "servers");
|
||||
if (!Player.canAfford(cost)) return;
|
||||
Player.loseMoney(cost, "servers");
|
||||
homeComputer.cpuCores++;
|
||||
props.rerender();
|
||||
}
|
||||
@@ -38,9 +37,9 @@ export function CoresButton(props: IProps): React.ReactElement {
|
||||
<i>"Cores increase the effectiveness of grow() and weaken() on 'home'"</i>
|
||||
</Typography>
|
||||
<br />
|
||||
<Button disabled={!props.p.canAfford(cost)} onClick={buy}>
|
||||
<Button disabled={!Player.canAfford(cost)} onClick={buy}>
|
||||
Upgrade 'home' cores ({homeComputer.cpuCores} -> {homeComputer.cpuCores + 1}) -
|
||||
<Money money={cost} player={props.p} />
|
||||
<Money money={cost} forPurchase={true} />
|
||||
</Button>
|
||||
</span>
|
||||
</Tooltip>
|
||||
|
||||
@@ -27,7 +27,7 @@ import { isBackdoorInstalled } from "../../Server/ServerHelpers";
|
||||
import { GetServer } from "../../Server/AllServers";
|
||||
|
||||
import { CorruptableText } from "../../ui/React/CorruptableText";
|
||||
import { use } from "../../ui/Context";
|
||||
import { Router } from "../../ui/GameRoot";
|
||||
import { serverMetadata } from "../../Server/data/servers";
|
||||
import { Tooltip } from "@mui/material";
|
||||
|
||||
@@ -36,8 +36,6 @@ type IProps = {
|
||||
};
|
||||
|
||||
export function GenericLocation({ loc }: IProps): React.ReactElement {
|
||||
const router = use.Router();
|
||||
const player = use.Player();
|
||||
/**
|
||||
* Determine what needs to be rendered for this location based on the locations
|
||||
* type. Returns an array of React components that should be rendered
|
||||
@@ -46,39 +44,39 @@ export function GenericLocation({ loc }: IProps): React.ReactElement {
|
||||
const content: React.ReactNode[] = [];
|
||||
|
||||
if (loc.types.includes(LocationType.Company)) {
|
||||
content.push(<CompanyLocation key={"companylocation"} locName={loc.name} />);
|
||||
content.push(<CompanyLocation locName={loc.name} />);
|
||||
}
|
||||
|
||||
if (loc.types.includes(LocationType.Gym)) {
|
||||
content.push(<GymLocation key={"gymlocation"} router={router} loc={loc} p={player} />);
|
||||
content.push(<GymLocation loc={loc} />);
|
||||
}
|
||||
|
||||
if (loc.types.includes(LocationType.Hospital)) {
|
||||
content.push(<HospitalLocation key={"hospitallocation"} p={player} />);
|
||||
content.push(<HospitalLocation />);
|
||||
}
|
||||
|
||||
if (loc.types.includes(LocationType.Slums)) {
|
||||
content.push(<SlumsLocation key={"slumslocation"} />);
|
||||
content.push(<SlumsLocation />);
|
||||
}
|
||||
|
||||
if (loc.types.includes(LocationType.Special)) {
|
||||
content.push(<SpecialLocation key={"speciallocation"} loc={loc} />);
|
||||
content.push(<SpecialLocation loc={loc} />);
|
||||
}
|
||||
|
||||
if (loc.types.includes(LocationType.TechVendor)) {
|
||||
content.push(<TechVendorLocation key={"techvendorlocation"} loc={loc} />);
|
||||
content.push(<TechVendorLocation loc={loc} />);
|
||||
}
|
||||
|
||||
if (loc.types.includes(LocationType.TravelAgency)) {
|
||||
content.push(<TravelAgencyRoot key={"travelagencylocation"} p={player} router={router} />);
|
||||
content.push(<TravelAgencyRoot />);
|
||||
}
|
||||
|
||||
if (loc.types.includes(LocationType.University)) {
|
||||
content.push(<UniversityLocation key={"universitylocation"} loc={loc} />);
|
||||
content.push(<UniversityLocation loc={loc} />);
|
||||
}
|
||||
|
||||
if (loc.types.includes(LocationType.Casino)) {
|
||||
content.push(<CasinoLocation key={"casinoLocation"} p={player} />);
|
||||
content.push(<CasinoLocation />);
|
||||
}
|
||||
|
||||
return content;
|
||||
@@ -92,7 +90,7 @@ export function GenericLocation({ loc }: IProps): React.ReactElement {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Button onClick={() => router.toCity()}>Return to World</Button>
|
||||
<Button onClick={() => Router.toCity()}>Return to World</Button>
|
||||
<Typography variant="h4" sx={{ mt: 1 }}>
|
||||
{backdoorInstalled && !Settings.DisableTextEffects ? (
|
||||
<Tooltip title={`Backdoor installed on ${loc.name}.`}>
|
||||
|
||||
@@ -8,31 +8,29 @@ import Button from "@mui/material/Button";
|
||||
|
||||
import { Location } from "../Location";
|
||||
|
||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||
import { Player } from "../../Player";
|
||||
|
||||
import { Money } from "../../ui/React/Money";
|
||||
import { IRouter } from "../../ui/Router";
|
||||
import { Router } from "../../ui/GameRoot";
|
||||
import { Box } from "@mui/material";
|
||||
import { ClassWork, ClassType, Classes } from "../../Work/ClassWork";
|
||||
import { calculateCost } from "../../Work/formulas/Class";
|
||||
|
||||
type IProps = {
|
||||
loc: Location;
|
||||
p: IPlayer;
|
||||
router: IRouter;
|
||||
};
|
||||
|
||||
export function GymLocation(props: IProps): React.ReactElement {
|
||||
function train(stat: ClassType): void {
|
||||
props.p.startWork(
|
||||
Player.startWork(
|
||||
new ClassWork({
|
||||
classType: stat,
|
||||
location: props.loc.name,
|
||||
singularity: false,
|
||||
}),
|
||||
);
|
||||
props.p.startFocusing();
|
||||
props.router.toWork();
|
||||
Player.startFocusing();
|
||||
Router.toWork();
|
||||
}
|
||||
|
||||
const cost = calculateCost(Classes[ClassType.GymStrength], props.loc);
|
||||
@@ -40,16 +38,16 @@ export function GymLocation(props: IProps): React.ReactElement {
|
||||
return (
|
||||
<Box sx={{ display: "grid", width: "fit-content" }}>
|
||||
<Button onClick={() => train(ClassType.GymStrength)}>
|
||||
Train Strength (<Money money={cost} player={props.p} /> / sec)
|
||||
Train Strength (<Money money={cost} forPurchase={true} /> / sec)
|
||||
</Button>
|
||||
<Button onClick={() => train(ClassType.GymDefense)}>
|
||||
Train Defense (<Money money={cost} player={props.p} /> / sec)
|
||||
Train Defense (<Money money={cost} forPurchase={true} /> / sec)
|
||||
</Button>
|
||||
<Button onClick={() => train(ClassType.GymDexterity)}>
|
||||
Train Dexterity (<Money money={cost} player={props.p} /> / sec)
|
||||
Train Dexterity (<Money money={cost} forPurchase={true} /> / sec)
|
||||
</Button>
|
||||
<Button onClick={() => train(ClassType.GymAgility)}>
|
||||
Train Agility (<Money money={cost} player={props.p} /> / sec)
|
||||
Train Agility (<Money money={cost} forPurchase={true} /> / sec)
|
||||
</Button>
|
||||
</Box>
|
||||
);
|
||||
|
||||
@@ -6,40 +6,34 @@
|
||||
import * as React from "react";
|
||||
import Button from "@mui/material/Button";
|
||||
|
||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||
import { Player } from "../../Player";
|
||||
import { getHospitalizationCost } from "../../Hospital/Hospital";
|
||||
|
||||
import { Money } from "../../ui/React/Money";
|
||||
|
||||
import { dialogBoxCreate } from "../../ui/React/DialogBox";
|
||||
|
||||
type IProps = {
|
||||
p: IPlayer;
|
||||
};
|
||||
|
||||
type IState = {
|
||||
currHp: number;
|
||||
};
|
||||
|
||||
export class HospitalLocation extends React.Component<IProps, IState> {
|
||||
//Todo: Make this a functional component
|
||||
export class HospitalLocation extends React.Component<Record<string, never>, IState> {
|
||||
/**
|
||||
* Stores button styling that sets them all to block display
|
||||
*/
|
||||
btnStyle = { display: "block" };
|
||||
|
||||
constructor(props: IProps) {
|
||||
super(props);
|
||||
|
||||
this.getCost = this.getCost.bind(this);
|
||||
this.getHealed = this.getHealed.bind(this);
|
||||
constructor() {
|
||||
super({});
|
||||
|
||||
this.state = {
|
||||
currHp: this.props.p.hp.current,
|
||||
currHp: Player.hp.current,
|
||||
};
|
||||
}
|
||||
|
||||
getCost(): number {
|
||||
return getHospitalizationCost(this.props.p);
|
||||
return getHospitalizationCost();
|
||||
}
|
||||
|
||||
getHealed(e: React.MouseEvent<HTMLElement>): void {
|
||||
@@ -47,20 +41,20 @@ export class HospitalLocation extends React.Component<IProps, IState> {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.props.p.hp.current < 0) {
|
||||
this.props.p.hp.current = 0;
|
||||
if (Player.hp.current < 0) {
|
||||
Player.hp.current = 0;
|
||||
}
|
||||
if (this.props.p.hp.current >= this.props.p.hp.max) {
|
||||
if (Player.hp.current >= Player.hp.max) {
|
||||
return;
|
||||
}
|
||||
|
||||
const cost = this.getCost();
|
||||
this.props.p.loseMoney(cost, "hospitalization");
|
||||
this.props.p.hp.current = this.props.p.hp.max;
|
||||
Player.loseMoney(cost, "hospitalization");
|
||||
Player.hp.current = Player.hp.max;
|
||||
|
||||
// This just forces a re-render to update the cost
|
||||
this.setState({
|
||||
currHp: this.props.p.hp.current,
|
||||
currHp: Player.hp.current,
|
||||
});
|
||||
|
||||
dialogBoxCreate(
|
||||
@@ -75,7 +69,7 @@ export class HospitalLocation extends React.Component<IProps, IState> {
|
||||
|
||||
return (
|
||||
<Button onClick={this.getHealed} style={this.btnStyle}>
|
||||
Get treatment for wounds - <Money money={cost} player={this.props.p} />
|
||||
Get treatment for wounds - <Money money={cost} forPurchase={true} />
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import { purchaseServer } from "../../Server/ServerPurchases";
|
||||
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||
import { Money } from "../../ui/React/Money";
|
||||
import { Modal } from "../../ui/React/Modal";
|
||||
import { use } from "../../ui/Context";
|
||||
import { Player } from "../../Player";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import TextField from "@mui/material/TextField";
|
||||
import Button from "@mui/material/Button";
|
||||
@@ -21,11 +21,10 @@ interface IProps {
|
||||
}
|
||||
|
||||
export function PurchaseServerModal(props: IProps): React.ReactElement {
|
||||
const player = use.Player();
|
||||
const [hostname, setHostname] = useState("");
|
||||
|
||||
function tryToPurchaseServer(): void {
|
||||
purchaseServer(hostname, props.ram, props.cost, player);
|
||||
purchaseServer(hostname, props.ram, props.cost);
|
||||
props.onClose();
|
||||
}
|
||||
|
||||
@@ -41,7 +40,7 @@ export function PurchaseServerModal(props: IProps): React.ReactElement {
|
||||
<Modal open={props.open} onClose={props.onClose}>
|
||||
<Typography>
|
||||
Would you like to purchase a new server with {numeralWrapper.formatRAM(props.ram)} of RAM for{" "}
|
||||
<Money money={props.cost} player={player} />?
|
||||
<Money money={props.cost} forPurchase={true} />?
|
||||
</Typography>
|
||||
<br />
|
||||
<br />
|
||||
@@ -56,7 +55,7 @@ export function PurchaseServerModal(props: IProps): React.ReactElement {
|
||||
placeholder="Unique Hostname"
|
||||
InputProps={{
|
||||
endAdornment: (
|
||||
<Button onClick={tryToPurchaseServer} disabled={!player.canAfford(props.cost) || hostname === ""}>
|
||||
<Button onClick={tryToPurchaseServer} disabled={!Player.canAfford(props.cost) || hostname === ""}>
|
||||
Buy
|
||||
</Button>
|
||||
),
|
||||
|
||||
@@ -4,7 +4,7 @@ import Tooltip from "@mui/material/Tooltip";
|
||||
import Typography from "@mui/material/Typography";
|
||||
|
||||
import { CONSTANTS } from "../../Constants";
|
||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||
import { Player } from "../../Player";
|
||||
import { purchaseRamForHomeComputer } from "../../Server/ServerPurchases";
|
||||
|
||||
import { Money } from "../../ui/React/Money";
|
||||
@@ -14,20 +14,19 @@ import { MathJaxWrapper } from "../../MathJaxWrapper";
|
||||
import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers";
|
||||
|
||||
type IProps = {
|
||||
p: IPlayer;
|
||||
rerender: () => void;
|
||||
};
|
||||
|
||||
export function RamButton(props: IProps): React.ReactElement {
|
||||
const homeComputer = props.p.getHomeComputer();
|
||||
const homeComputer = Player.getHomeComputer();
|
||||
if (homeComputer.maxRam >= CONSTANTS.HomeComputerMaxRam) {
|
||||
return <Button>Upgrade 'home' RAM - MAX</Button>;
|
||||
}
|
||||
|
||||
const cost = props.p.getUpgradeHomeRamCost();
|
||||
const cost = Player.getUpgradeHomeRamCost();
|
||||
|
||||
function buy(): void {
|
||||
purchaseRamForHomeComputer(props.p);
|
||||
purchaseRamForHomeComputer();
|
||||
props.rerender();
|
||||
}
|
||||
|
||||
@@ -45,10 +44,10 @@ export function RamButton(props: IProps): React.ReactElement {
|
||||
<i>"More RAM means more scripts on 'home'"</i>
|
||||
</Typography>
|
||||
<br />
|
||||
<Button disabled={!props.p.canAfford(cost)} onClick={buy}>
|
||||
<Button disabled={!Player.canAfford(cost)} onClick={buy}>
|
||||
Upgrade 'home' RAM ({numeralWrapper.formatRAM(homeComputer.maxRam)} ->
|
||||
{numeralWrapper.formatRAM(homeComputer.maxRam * 2)}) -
|
||||
<Money money={cost} player={props.p} />
|
||||
<Money money={cost} forPurchase={true} />
|
||||
</Button>
|
||||
</span>
|
||||
</Tooltip>
|
||||
|
||||
@@ -10,132 +10,131 @@ import Tooltip from "@mui/material/Tooltip";
|
||||
import { Crimes } from "../../Crime/Crimes";
|
||||
|
||||
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||
import { use } from "../../ui/Context";
|
||||
import { Router } from "../../ui/GameRoot";
|
||||
import { Player } from "../../Player";
|
||||
import { Box } from "@mui/material";
|
||||
|
||||
export function SlumsLocation(): React.ReactElement {
|
||||
const player = use.Player();
|
||||
const router = use.Router();
|
||||
function shoplift(e: React.MouseEvent<HTMLElement>): void {
|
||||
if (!e.isTrusted) {
|
||||
return;
|
||||
}
|
||||
Crimes.Shoplift.commit(player);
|
||||
router.toWork();
|
||||
player.focus = true;
|
||||
Crimes.Shoplift.commit();
|
||||
Router.toWork();
|
||||
Player.focus = true;
|
||||
}
|
||||
|
||||
function robStore(e: React.MouseEvent<HTMLElement>): void {
|
||||
if (!e.isTrusted) {
|
||||
return;
|
||||
}
|
||||
Crimes.RobStore.commit(player);
|
||||
router.toWork();
|
||||
player.focus = true;
|
||||
Crimes.RobStore.commit();
|
||||
Router.toWork();
|
||||
Player.focus = true;
|
||||
}
|
||||
|
||||
function mug(e: React.MouseEvent<HTMLElement>): void {
|
||||
if (!e.isTrusted) {
|
||||
return;
|
||||
}
|
||||
Crimes.Mug.commit(player);
|
||||
router.toWork();
|
||||
player.focus = true;
|
||||
Crimes.Mug.commit();
|
||||
Router.toWork();
|
||||
Player.focus = true;
|
||||
}
|
||||
|
||||
function larceny(e: React.MouseEvent<HTMLElement>): void {
|
||||
if (!e.isTrusted) {
|
||||
return;
|
||||
}
|
||||
Crimes.Larceny.commit(player);
|
||||
router.toWork();
|
||||
player.focus = true;
|
||||
Crimes.Larceny.commit();
|
||||
Router.toWork();
|
||||
Player.focus = true;
|
||||
}
|
||||
|
||||
function dealDrugs(e: React.MouseEvent<HTMLElement>): void {
|
||||
if (!e.isTrusted) {
|
||||
return;
|
||||
}
|
||||
Crimes.DealDrugs.commit(player);
|
||||
router.toWork();
|
||||
player.focus = true;
|
||||
Crimes.DealDrugs.commit();
|
||||
Router.toWork();
|
||||
Player.focus = true;
|
||||
}
|
||||
|
||||
function bondForgery(e: React.MouseEvent<HTMLElement>): void {
|
||||
if (!e.isTrusted) {
|
||||
return;
|
||||
}
|
||||
Crimes.BondForgery.commit(player);
|
||||
router.toWork();
|
||||
player.focus = true;
|
||||
Crimes.BondForgery.commit();
|
||||
Router.toWork();
|
||||
Player.focus = true;
|
||||
}
|
||||
|
||||
function traffickArms(e: React.MouseEvent<HTMLElement>): void {
|
||||
if (!e.isTrusted) {
|
||||
return;
|
||||
}
|
||||
Crimes.TraffickArms.commit(player);
|
||||
router.toWork();
|
||||
player.focus = true;
|
||||
Crimes.TraffickArms.commit();
|
||||
Router.toWork();
|
||||
Player.focus = true;
|
||||
}
|
||||
|
||||
function homicide(e: React.MouseEvent<HTMLElement>): void {
|
||||
if (!e.isTrusted) {
|
||||
return;
|
||||
}
|
||||
Crimes.Homicide.commit(player);
|
||||
router.toWork();
|
||||
player.focus = true;
|
||||
Crimes.Homicide.commit();
|
||||
Router.toWork();
|
||||
Player.focus = true;
|
||||
}
|
||||
|
||||
function grandTheftAuto(e: React.MouseEvent<HTMLElement>): void {
|
||||
if (!e.isTrusted) {
|
||||
return;
|
||||
}
|
||||
Crimes.GrandTheftAuto.commit(player);
|
||||
router.toWork();
|
||||
player.focus = true;
|
||||
Crimes.GrandTheftAuto.commit();
|
||||
Router.toWork();
|
||||
Player.focus = true;
|
||||
}
|
||||
|
||||
function kidnap(e: React.MouseEvent<HTMLElement>): void {
|
||||
if (!e.isTrusted) {
|
||||
return;
|
||||
}
|
||||
Crimes.Kidnap.commit(player);
|
||||
router.toWork();
|
||||
player.focus = true;
|
||||
Crimes.Kidnap.commit();
|
||||
Router.toWork();
|
||||
Player.focus = true;
|
||||
}
|
||||
|
||||
function assassinate(e: React.MouseEvent<HTMLElement>): void {
|
||||
if (!e.isTrusted) {
|
||||
return;
|
||||
}
|
||||
Crimes.Assassination.commit(player);
|
||||
router.toWork();
|
||||
player.focus = true;
|
||||
Crimes.Assassination.commit();
|
||||
Router.toWork();
|
||||
Player.focus = true;
|
||||
}
|
||||
|
||||
function heist(e: React.MouseEvent<HTMLElement>): void {
|
||||
if (!e.isTrusted) {
|
||||
return;
|
||||
}
|
||||
Crimes.Heist.commit(player);
|
||||
router.toWork();
|
||||
player.focus = true;
|
||||
Crimes.Heist.commit();
|
||||
Router.toWork();
|
||||
Player.focus = true;
|
||||
}
|
||||
|
||||
const shopliftChance = Crimes.Shoplift.successRate(player);
|
||||
const robStoreChance = Crimes.RobStore.successRate(player);
|
||||
const mugChance = Crimes.Mug.successRate(player);
|
||||
const larcenyChance = Crimes.Larceny.successRate(player);
|
||||
const drugsChance = Crimes.DealDrugs.successRate(player);
|
||||
const bondChance = Crimes.BondForgery.successRate(player);
|
||||
const armsChance = Crimes.TraffickArms.successRate(player);
|
||||
const homicideChance = Crimes.Homicide.successRate(player);
|
||||
const gtaChance = Crimes.GrandTheftAuto.successRate(player);
|
||||
const kidnapChance = Crimes.Kidnap.successRate(player);
|
||||
const assassinateChance = Crimes.Assassination.successRate(player);
|
||||
const heistChance = Crimes.Heist.successRate(player);
|
||||
const shopliftChance = Crimes.Shoplift.successRate(Player);
|
||||
const robStoreChance = Crimes.RobStore.successRate(Player);
|
||||
const mugChance = Crimes.Mug.successRate(Player);
|
||||
const larcenyChance = Crimes.Larceny.successRate(Player);
|
||||
const drugsChance = Crimes.DealDrugs.successRate(Player);
|
||||
const bondChance = Crimes.BondForgery.successRate(Player);
|
||||
const armsChance = Crimes.TraffickArms.successRate(Player);
|
||||
const homicideChance = Crimes.Homicide.successRate(Player);
|
||||
const gtaChance = Crimes.GrandTheftAuto.successRate(Player);
|
||||
const kidnapChance = Crimes.Kidnap.successRate(Player);
|
||||
const assassinateChance = Crimes.Assassination.successRate(Player);
|
||||
const heistChance = Crimes.Heist.successRate(Player);
|
||||
|
||||
return (
|
||||
<Box sx={{ display: "grid", width: "fit-content" }}>
|
||||
|
||||
@@ -21,7 +21,8 @@ import { AugmentationNames } from "../../Augmentation/data/AugmentationNames";
|
||||
import { Factions } from "../../Faction/Factions";
|
||||
import { joinFaction } from "../../Faction/FactionHelpers";
|
||||
|
||||
import { use } from "../../ui/Context";
|
||||
import { Router } from "../../ui/GameRoot";
|
||||
import { Player } from "../../Player";
|
||||
|
||||
import { dialogBoxCreate } from "../../ui/React/DialogBox";
|
||||
import { SnackbarEvents, ToastVariant } from "../../ui/React/Snackbar";
|
||||
@@ -41,27 +42,24 @@ type IProps = {
|
||||
};
|
||||
|
||||
export function SpecialLocation(props: IProps): React.ReactElement {
|
||||
const player = use.Player();
|
||||
const router = use.Router();
|
||||
const setRerender = useState(false)[1];
|
||||
const inBladeburner = player.inBladeburner();
|
||||
const inBladeburner = Player.inBladeburner();
|
||||
|
||||
/**
|
||||
* Click handler for Bladeburner button at Sector-12 NSA
|
||||
*/
|
||||
function handleBladeburner(): void {
|
||||
const p = player;
|
||||
if (p.inBladeburner()) {
|
||||
if (Player.inBladeburner()) {
|
||||
// Enter Bladeburner division
|
||||
router.toBladeburner();
|
||||
Router.toBladeburner();
|
||||
} else if (
|
||||
p.skills.strength >= 100 &&
|
||||
p.skills.defense >= 100 &&
|
||||
p.skills.dexterity >= 100 &&
|
||||
p.skills.agility >= 100
|
||||
Player.skills.strength >= 100 &&
|
||||
Player.skills.defense >= 100 &&
|
||||
Player.skills.dexterity >= 100 &&
|
||||
Player.skills.agility >= 100
|
||||
) {
|
||||
// Apply for Bladeburner division
|
||||
p.startBladeburner();
|
||||
Player.startBladeburner();
|
||||
dialogBoxCreate("You have been accepted into the Bladeburner division!");
|
||||
setRerender((old) => !old);
|
||||
|
||||
@@ -79,11 +77,11 @@ export function SpecialLocation(props: IProps): React.ReactElement {
|
||||
* Click handler for Resleeving button at New Tokyo VitaLife
|
||||
*/
|
||||
function handleGrafting(): void {
|
||||
router.toGrafting();
|
||||
Router.toGrafting();
|
||||
}
|
||||
|
||||
function renderBladeburner(): React.ReactElement {
|
||||
if (!player.canAccessBladeburner() || BitNodeMultipliers.BladeburnerRank === 0) {
|
||||
if (!Player.canAccessBladeburner() || BitNodeMultipliers.BladeburnerRank === 0) {
|
||||
return <></>;
|
||||
}
|
||||
const text = inBladeburner ? "Enter Bladeburner Headquarters" : "Apply to Bladeburner Division";
|
||||
@@ -99,32 +97,32 @@ export function SpecialLocation(props: IProps): React.ReactElement {
|
||||
function EatNoodles(): void {
|
||||
SnackbarEvents.emit("You ate some delicious noodles and feel refreshed", ToastVariant.SUCCESS, 2000);
|
||||
N00dles(); // This is the true power of the noodles.
|
||||
if (player.sourceFiles.length > 0) player.giveExploit(Exploit.N00dles);
|
||||
if (player.sourceFileLvl(5) > 0 || player.bitNodeN === 5) {
|
||||
player.exp.intelligence *= 1.0000000000000002;
|
||||
if (Player.sourceFiles.length > 0) Player.giveExploit(Exploit.N00dles);
|
||||
if (Player.sourceFileLvl(5) > 0 || Player.bitNodeN === 5) {
|
||||
Player.exp.intelligence *= 1.0000000000000002;
|
||||
}
|
||||
player.exp.hacking *= 1.0000000000000002;
|
||||
player.exp.strength *= 1.0000000000000002;
|
||||
player.exp.defense *= 1.0000000000000002;
|
||||
player.exp.agility *= 1.0000000000000002;
|
||||
player.exp.dexterity *= 1.0000000000000002;
|
||||
player.exp.charisma *= 1.0000000000000002;
|
||||
for (const node of player.hacknetNodes) {
|
||||
Player.exp.hacking *= 1.0000000000000002;
|
||||
Player.exp.strength *= 1.0000000000000002;
|
||||
Player.exp.defense *= 1.0000000000000002;
|
||||
Player.exp.agility *= 1.0000000000000002;
|
||||
Player.exp.dexterity *= 1.0000000000000002;
|
||||
Player.exp.charisma *= 1.0000000000000002;
|
||||
for (const node of Player.hacknetNodes) {
|
||||
if (node instanceof HacknetNode) {
|
||||
player.gainMoney(node.moneyGainRatePerSecond * 0.001, "other");
|
||||
Player.gainMoney(node.moneyGainRatePerSecond * 0.001, "other");
|
||||
} else {
|
||||
const server = GetServer(node);
|
||||
if (!(server instanceof HacknetServer)) throw new Error(`Server ${node} is not a hacknet server.`);
|
||||
player.hashManager.storeHashes(server.hashRate * 0.001);
|
||||
Player.hashManager.storeHashes(server.hashRate * 0.001);
|
||||
}
|
||||
}
|
||||
|
||||
if (player.bladeburner) {
|
||||
player.bladeburner.rank += 0.00001;
|
||||
if (Player.bladeburner) {
|
||||
Player.bladeburner.rank += 0.00001;
|
||||
}
|
||||
|
||||
if (player.corporation) {
|
||||
player.corporation.funds += player.corporation.revenue * 0.01;
|
||||
if (Player.corporation) {
|
||||
Player.corporation.funds += Player.corporation.revenue * 0.01;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,7 +136,7 @@ export function SpecialLocation(props: IProps): React.ReactElement {
|
||||
|
||||
function CreateCorporation(): React.ReactElement {
|
||||
const [open, setOpen] = useState(false);
|
||||
if (!player.canAccessCorporation()) {
|
||||
if (!Player.canAccessCorporation()) {
|
||||
return (
|
||||
<>
|
||||
<Typography>
|
||||
@@ -149,7 +147,7 @@ export function SpecialLocation(props: IProps): React.ReactElement {
|
||||
}
|
||||
return (
|
||||
<>
|
||||
<Button disabled={!player.canAccessCorporation() || player.hasCorporation()} onClick={() => setOpen(true)}>
|
||||
<Button disabled={!Player.canAccessCorporation() || Player.hasCorporation()} onClick={() => setOpen(true)}>
|
||||
Create a Corporation
|
||||
</Button>
|
||||
<CreateCorporationModal open={open} onClose={() => setOpen(false)} />
|
||||
@@ -158,7 +156,7 @@ export function SpecialLocation(props: IProps): React.ReactElement {
|
||||
}
|
||||
|
||||
function renderGrafting(): React.ReactElement {
|
||||
if (!player.canAccessGrafting()) {
|
||||
if (!Player.canAccessGrafting()) {
|
||||
return <></>;
|
||||
}
|
||||
return (
|
||||
@@ -170,21 +168,21 @@ export function SpecialLocation(props: IProps): React.ReactElement {
|
||||
|
||||
function handleCotMG(): void {
|
||||
const faction = Factions[FactionNames.ChurchOfTheMachineGod];
|
||||
if (!player.factions.includes(FactionNames.ChurchOfTheMachineGod)) {
|
||||
if (!Player.factions.includes(FactionNames.ChurchOfTheMachineGod)) {
|
||||
joinFaction(faction);
|
||||
}
|
||||
if (
|
||||
!player.augmentations.some((a) => a.name === AugmentationNames.StaneksGift1) &&
|
||||
!player.queuedAugmentations.some((a) => a.name === AugmentationNames.StaneksGift1)
|
||||
!Player.augmentations.some((a) => a.name === AugmentationNames.StaneksGift1) &&
|
||||
!Player.queuedAugmentations.some((a) => a.name === AugmentationNames.StaneksGift1)
|
||||
) {
|
||||
applyAugmentation({ name: AugmentationNames.StaneksGift1, level: 1 });
|
||||
}
|
||||
|
||||
router.toStaneksGift();
|
||||
Router.toStaneksGift();
|
||||
}
|
||||
|
||||
function renderCotMG(): React.ReactElement {
|
||||
const toStanek = <Button onClick={() => router.toStaneksGift()}>Open Stanek's Gift</Button>;
|
||||
const toStanek = <Button onClick={() => Router.toStaneksGift()}>Open Stanek's Gift</Button>;
|
||||
// prettier-ignore
|
||||
const symbol = <Typography sx={{ lineHeight: '1em', whiteSpace: 'pre' }}>
|
||||
{" `` "}<br />
|
||||
@@ -215,7 +213,7 @@ export function SpecialLocation(props: IProps): React.ReactElement {
|
||||
{" sNNo-.`.-omNy` "}<br />
|
||||
{" -smNNNNmdo- "}<br />
|
||||
{" `..` "}</Typography>
|
||||
if (player.hasAugmentation(AugmentationNames.StaneksGift3, true)) {
|
||||
if (Player.hasAugmentation(AugmentationNames.StaneksGift3, true)) {
|
||||
return (
|
||||
<>
|
||||
<Typography>
|
||||
@@ -232,7 +230,7 @@ export function SpecialLocation(props: IProps): React.ReactElement {
|
||||
</>
|
||||
);
|
||||
}
|
||||
if (player.hasAugmentation(AugmentationNames.StaneksGift2, true)) {
|
||||
if (Player.hasAugmentation(AugmentationNames.StaneksGift2, true)) {
|
||||
return (
|
||||
<>
|
||||
<Typography>
|
||||
@@ -249,7 +247,7 @@ export function SpecialLocation(props: IProps): React.ReactElement {
|
||||
</>
|
||||
);
|
||||
}
|
||||
if (player.factions.includes(FactionNames.ChurchOfTheMachineGod)) {
|
||||
if (Player.factions.includes(FactionNames.ChurchOfTheMachineGod)) {
|
||||
return (
|
||||
<>
|
||||
<Typography>
|
||||
@@ -263,7 +261,7 @@ export function SpecialLocation(props: IProps): React.ReactElement {
|
||||
);
|
||||
}
|
||||
|
||||
if (!player.canAccessCotMG()) {
|
||||
if (!Player.canAccessCotMG()) {
|
||||
return (
|
||||
<>
|
||||
<Typography>
|
||||
@@ -278,8 +276,8 @@ export function SpecialLocation(props: IProps): React.ReactElement {
|
||||
}
|
||||
|
||||
if (
|
||||
player.augmentations.filter((a) => a.name !== AugmentationNames.NeuroFluxGovernor).length > 0 ||
|
||||
player.queuedAugmentations.filter((a) => a.name !== AugmentationNames.NeuroFluxGovernor).length > 0
|
||||
Player.augmentations.filter((a) => a.name !== AugmentationNames.NeuroFluxGovernor).length > 0 ||
|
||||
Player.queuedAugmentations.filter((a) => a.name !== AugmentationNames.NeuroFluxGovernor).length > 0
|
||||
) {
|
||||
return (
|
||||
<>
|
||||
|
||||
@@ -15,7 +15,7 @@ import { CoresButton } from "./CoresButton";
|
||||
import { getPurchaseServerCost } from "../../Server/ServerPurchases";
|
||||
|
||||
import { Money } from "../../ui/React/Money";
|
||||
import { use } from "../../ui/Context";
|
||||
import { Player } from "../../Player";
|
||||
import { PurchaseServerModal } from "./PurchaseServerModal";
|
||||
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||
import { Box } from "@mui/material";
|
||||
@@ -27,13 +27,12 @@ interface IServerProps {
|
||||
|
||||
function ServerButton(props: IServerProps): React.ReactElement {
|
||||
const [open, setOpen] = useState(false);
|
||||
const player = use.Player();
|
||||
const cost = getPurchaseServerCost(props.ram);
|
||||
return (
|
||||
<>
|
||||
<Button onClick={() => setOpen(true)} disabled={!player.canAfford(cost)}>
|
||||
<Button onClick={() => setOpen(true)} disabled={!Player.canAfford(cost)}>
|
||||
Purchase {numeralWrapper.formatRAM(props.ram)} Server -
|
||||
<Money money={cost} player={player} />
|
||||
<Money money={cost} forPurchase={true} />
|
||||
</Button>
|
||||
<PurchaseServerModal
|
||||
open={open}
|
||||
@@ -51,7 +50,6 @@ type IProps = {
|
||||
};
|
||||
|
||||
export function TechVendorLocation(props: IProps): React.ReactElement {
|
||||
const player = use.Player();
|
||||
const setRerender = useState(false)[1];
|
||||
function rerender(): void {
|
||||
setRerender((old) => !old);
|
||||
@@ -76,11 +74,11 @@ export function TechVendorLocation(props: IProps): React.ReactElement {
|
||||
<i>"You can order bigger servers via scripts. We don't take custom orders in person."</i>
|
||||
</Typography>
|
||||
<br />
|
||||
<TorButton p={player} rerender={rerender} />
|
||||
<TorButton rerender={rerender} />
|
||||
<br />
|
||||
<RamButton p={player} rerender={rerender} />
|
||||
<RamButton rerender={rerender} />
|
||||
<br />
|
||||
<CoresButton p={player} rerender={rerender} />
|
||||
<CoresButton rerender={rerender} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,32 +1,61 @@
|
||||
import React from "react";
|
||||
import Button from "@mui/material/Button";
|
||||
|
||||
import { purchaseTorRouter } from "../LocationsHelpers";
|
||||
import { dialogBoxCreate } from "../../ui/React/DialogBox";
|
||||
import { GetServer } from "../../Server/AllServers";
|
||||
import { SpecialServers } from "../../Server/data/SpecialServers";
|
||||
|
||||
import { CONSTANTS } from "../../Constants";
|
||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||
import { Player } from "../../Player";
|
||||
|
||||
import { Money } from "../../ui/React/Money";
|
||||
|
||||
/**
|
||||
* Attempt to purchase a TOR router using the button.
|
||||
*/
|
||||
export function purchaseTorRouter(): void {
|
||||
if (Player.hasTorRouter()) {
|
||||
dialogBoxCreate(`You already have a TOR Router!`);
|
||||
return;
|
||||
}
|
||||
if (!Player.canAfford(CONSTANTS.TorRouterCost)) {
|
||||
dialogBoxCreate("You cannot afford to purchase the TOR router!");
|
||||
return;
|
||||
}
|
||||
Player.loseMoney(CONSTANTS.TorRouterCost, "other");
|
||||
|
||||
const darkweb = GetServer(SpecialServers.DarkWeb);
|
||||
if (!darkweb) {
|
||||
throw new Error("Dark web is not a server.");
|
||||
}
|
||||
|
||||
Player.getHomeComputer().serversOnNetwork.push(darkweb.hostname);
|
||||
darkweb.serversOnNetwork.push(Player.getHomeComputer().hostname);
|
||||
dialogBoxCreate(
|
||||
"You have purchased a TOR router!\n" +
|
||||
"You now have access to the dark web from your home computer.\n" +
|
||||
"Use the scan/scan-analyze commands to search for the dark web connection.",
|
||||
);
|
||||
}
|
||||
|
||||
type IProps = {
|
||||
p: IPlayer;
|
||||
rerender: () => void;
|
||||
};
|
||||
|
||||
export function TorButton(props: IProps): React.ReactElement {
|
||||
function buy(): void {
|
||||
purchaseTorRouter(props.p);
|
||||
purchaseTorRouter();
|
||||
props.rerender();
|
||||
}
|
||||
|
||||
if (props.p.hasTorRouter()) {
|
||||
if (Player.hasTorRouter()) {
|
||||
return <Button>TOR Router - Purchased</Button>;
|
||||
}
|
||||
|
||||
return (
|
||||
<Button disabled={!props.p.canAfford(CONSTANTS.TorRouterCost)} onClick={buy}>
|
||||
<Button disabled={!Player.canAfford(CONSTANTS.TorRouterCost)} onClick={buy}>
|
||||
Purchase TOR router -
|
||||
<Money money={CONSTANTS.TorRouterCost} player={props.p} />
|
||||
<Money money={CONSTANTS.TorRouterCost} forPurchase={true} />
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -9,11 +9,10 @@ import { CityName } from "../data/CityNames";
|
||||
import { TravelConfirmationModal } from "./TravelConfirmationModal";
|
||||
|
||||
import { CONSTANTS } from "../../Constants";
|
||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||
import { IRouter } from "../../ui/Router";
|
||||
import { Player } from "../../Player";
|
||||
import { Router } from "../../ui/GameRoot";
|
||||
import { Settings } from "../../Settings/Settings";
|
||||
|
||||
import { use } from "../../ui/Context";
|
||||
import { Money } from "../../ui/React/Money";
|
||||
import { WorldMap } from "../../ui/React/WorldMap";
|
||||
import { dialogBoxCreate } from "../../ui/React/DialogBox";
|
||||
@@ -22,26 +21,19 @@ import Typography from "@mui/material/Typography";
|
||||
import Box from "@mui/material/Box";
|
||||
import Button from "@mui/material/Button";
|
||||
|
||||
type IProps = {
|
||||
p: IPlayer;
|
||||
router: IRouter;
|
||||
};
|
||||
|
||||
function travel(p: IPlayer, router: IRouter, to: CityName): void {
|
||||
function travel(to: CityName): void {
|
||||
const cost = CONSTANTS.TravelCost;
|
||||
if (!p.canAfford(cost)) {
|
||||
if (!Player.canAfford(cost)) {
|
||||
return;
|
||||
}
|
||||
|
||||
p.loseMoney(cost, "other");
|
||||
p.travel(to);
|
||||
dialogBoxCreate(<>You are now in {to}!</>);
|
||||
router.toCity();
|
||||
Player.loseMoney(cost, "other");
|
||||
Player.travel(to);
|
||||
dialogBoxCreate(`You are now in ${to}!`);
|
||||
Router.toCity();
|
||||
}
|
||||
|
||||
export function TravelAgencyRoot(props: IProps): React.ReactElement {
|
||||
const player = use.Player();
|
||||
const router = use.Router();
|
||||
export function TravelAgencyRoot(): React.ReactElement {
|
||||
const setRerender = useState(false)[1];
|
||||
const [open, setOpen] = useState(false);
|
||||
const [destination, setDestination] = useState(CityName.Sector12);
|
||||
@@ -56,11 +48,11 @@ export function TravelAgencyRoot(props: IProps): React.ReactElement {
|
||||
|
||||
function startTravel(city: CityName): void {
|
||||
const cost = CONSTANTS.TravelCost;
|
||||
if (!player.canAfford(cost)) {
|
||||
if (!Player.canAfford(cost)) {
|
||||
return;
|
||||
}
|
||||
if (Settings.SuppressTravelConfirmation) {
|
||||
travel(player, router, city);
|
||||
travel(city);
|
||||
return;
|
||||
}
|
||||
setOpen(true);
|
||||
@@ -73,12 +65,12 @@ export function TravelAgencyRoot(props: IProps): React.ReactElement {
|
||||
<Box mx={2}>
|
||||
<Typography>
|
||||
From here, you can travel to any other city! A ticket costs{" "}
|
||||
<Money money={CONSTANTS.TravelCost} player={props.p} />.
|
||||
<Money money={CONSTANTS.TravelCost} forPurchase={true} />.
|
||||
</Typography>
|
||||
{Settings.DisableASCIIArt ? (
|
||||
<>
|
||||
{Object.values(CityName)
|
||||
.filter((city: string) => city != props.p.city)
|
||||
.filter((city: string) => city != Player.city)
|
||||
.map((city: string) => {
|
||||
const match = Object.entries(CityName).find((entry) => entry[1] === city);
|
||||
if (match === undefined) throw new Error(`could not find key for city '${city}'`);
|
||||
@@ -93,12 +85,12 @@ export function TravelAgencyRoot(props: IProps): React.ReactElement {
|
||||
})}
|
||||
</>
|
||||
) : (
|
||||
<WorldMap currentCity={props.p.city} onTravel={(city: CityName) => startTravel(city)} />
|
||||
<WorldMap currentCity={Player.city} onTravel={(city: CityName) => startTravel(city)} />
|
||||
)}
|
||||
</Box>
|
||||
<TravelConfirmationModal
|
||||
city={destination}
|
||||
travel={() => travel(player, router, destination)}
|
||||
travel={() => travel(destination)}
|
||||
open={open}
|
||||
onClose={() => setOpen(false)}
|
||||
/>
|
||||
|
||||
@@ -2,7 +2,6 @@ import React from "react";
|
||||
import { CONSTANTS } from "../../Constants";
|
||||
import { Money } from "../../ui/React/Money";
|
||||
import { Modal } from "../../ui/React/Modal";
|
||||
import { use } from "../../ui/Context";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import Button from "@mui/material/Button";
|
||||
|
||||
@@ -15,7 +14,6 @@ interface IProps {
|
||||
}
|
||||
|
||||
export function TravelConfirmationModal(props: IProps): React.ReactElement {
|
||||
const player = use.Player();
|
||||
const cost = CONSTANTS.TravelCost;
|
||||
function travel(): void {
|
||||
props.travel();
|
||||
@@ -24,7 +22,7 @@ export function TravelConfirmationModal(props: IProps): React.ReactElement {
|
||||
return (
|
||||
<Modal open={props.open} onClose={props.onClose}>
|
||||
<Typography>
|
||||
Would you like to travel to {props.city}? The trip will cost <Money money={cost} player={player} />.
|
||||
Would you like to travel to {props.city}? The trip will cost <Money money={cost} forPurchase={true} />.
|
||||
</Typography>
|
||||
<br />
|
||||
<br />
|
||||
|
||||
@@ -10,7 +10,8 @@ import Button from "@mui/material/Button";
|
||||
import { Location } from "../Location";
|
||||
|
||||
import { Money } from "../../ui/React/Money";
|
||||
import { use } from "../../ui/Context";
|
||||
import { Router } from "../../ui/GameRoot";
|
||||
import { Player } from "../../Player";
|
||||
import { Box } from "@mui/material";
|
||||
|
||||
import { ClassWork, ClassType, Classes } from "../../Work/ClassWork";
|
||||
@@ -21,19 +22,16 @@ type IProps = {
|
||||
};
|
||||
|
||||
export function UniversityLocation(props: IProps): React.ReactElement {
|
||||
const player = use.Player();
|
||||
const router = use.Router();
|
||||
|
||||
function take(classType: ClassType): void {
|
||||
player.startWork(
|
||||
Player.startWork(
|
||||
new ClassWork({
|
||||
classType: classType,
|
||||
location: props.loc.name,
|
||||
singularity: false,
|
||||
}),
|
||||
);
|
||||
player.startFocusing();
|
||||
router.toWork();
|
||||
Player.startFocusing();
|
||||
Router.toWork();
|
||||
}
|
||||
|
||||
const dataStructuresCost = calculateCost(Classes[ClassType.DataStructures], props.loc);
|
||||
@@ -53,31 +51,31 @@ export function UniversityLocation(props: IProps): React.ReactElement {
|
||||
<Tooltip title={earnHackingExpTooltip}>
|
||||
<Button onClick={() => take(ClassType.DataStructures)}>
|
||||
Take Data Structures course (
|
||||
<Money money={dataStructuresCost} player={player} /> / sec)
|
||||
<Money money={dataStructuresCost} forPurchase={true} /> / sec)
|
||||
</Button>
|
||||
</Tooltip>
|
||||
<Tooltip title={earnHackingExpTooltip}>
|
||||
<Button onClick={() => take(ClassType.Networks)}>
|
||||
Take Networks course (
|
||||
<Money money={networksCost} player={player} /> / sec)
|
||||
<Money money={networksCost} forPurchase={true} /> / sec)
|
||||
</Button>
|
||||
</Tooltip>
|
||||
<Tooltip title={earnHackingExpTooltip}>
|
||||
<Button onClick={() => take(ClassType.Algorithms)}>
|
||||
Take Algorithms course (
|
||||
<Money money={algorithmsCost} player={player} /> / sec)
|
||||
<Money money={algorithmsCost} forPurchase={true} /> / sec)
|
||||
</Button>
|
||||
</Tooltip>
|
||||
<Tooltip title={earnCharismaExpTooltip}>
|
||||
<Button onClick={() => take(ClassType.Management)}>
|
||||
Take Management course (
|
||||
<Money money={managementCost} player={player} /> / sec)
|
||||
<Money money={managementCost} forPurchase={true} /> / sec)
|
||||
</Button>
|
||||
</Tooltip>
|
||||
<Tooltip title={earnCharismaExpTooltip}>
|
||||
<Button onClick={() => take(ClassType.Leadership)}>
|
||||
Take Leadership course (
|
||||
<Money money={leadershipCost} player={player} /> / sec)
|
||||
<Money money={leadershipCost} forPurchase={true} /> / sec)
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</Box>
|
||||
|
||||
Reference in New Issue
Block a user