BLADEBURNER: Add Stop button and refactor code (#1363)

This commit is contained in:
catloversg 2024-06-08 03:34:47 +07:00 committed by GitHub
parent d9efea0fe6
commit 8b3206e1c6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 104 additions and 158 deletions

@ -0,0 +1,55 @@
import type { Bladeburner } from "../Bladeburner";
import type { Action } from "../Types";
import React from "react";
import { Box, Typography } from "@mui/material";
import { CopyableText } from "../../ui/React/CopyableText";
import { createProgressBarText } from "../../utils/helpers/createProgressBarText";
import { StartButton } from "./StartButton";
import { StopButton } from "./StopButton";
import { TeamSizeButton } from "./TeamSizeButton";
import { formatNumberNoSuffix } from "../../ui/formatNumber";
import { BlackOperation, Operation } from "../Actions";
interface ActionHeaderProps {
bladeburner: Bladeburner;
action: Action;
rerender: () => void;
}
export function ActionHeader({ bladeburner, action, rerender }: ActionHeaderProps): React.ReactElement {
const isActive = action.name === bladeburner.action?.name;
const computedActionTimeCurrent = Math.min(
bladeburner.actionTimeCurrent + bladeburner.actionTimeOverflow,
bladeburner.actionTimeToComplete,
);
const allowTeam = action instanceof Operation || action instanceof BlackOperation;
if (isActive) {
return (
<>
<Box display="flex" flexDirection="row" alignItems="center">
<CopyableText value={action.name} />
<StopButton bladeburner={bladeburner} rerender={rerender} />
</Box>
<Typography>
(IN PROGRESS - {formatNumberNoSuffix(computedActionTimeCurrent, 0)} /{" "}
{formatNumberNoSuffix(bladeburner.actionTimeToComplete, 0)})
</Typography>
<Typography>
{createProgressBarText({
progress: computedActionTimeCurrent / bladeburner.actionTimeToComplete,
})}
</Typography>
</>
);
}
return (
<Box display="flex" flexDirection="row" alignItems="center">
<CopyableText value={action.name} />
<StartButton bladeburner={bladeburner} action={action} rerender={rerender} />
{allowTeam && <TeamSizeButton bladeburner={bladeburner} action={action} />}
</Box>
);
}

@ -7,72 +7,41 @@ import { Paper, Typography } from "@mui/material";
import { Player } from "@player";
import { formatNumberNoSuffix } from "../../ui/formatNumber";
import { convertTimeMsToTimeElapsedString } from "../../utils/StringHelperFunctions";
import { createProgressBarText } from "../../utils/helpers/createProgressBarText";
import { TeamSizeButton } from "./TeamSizeButton";
import { CopyableText } from "../../ui/React/CopyableText";
import { SuccessChance } from "./SuccessChance";
import { StartButton } from "./StartButton";
import { useRerender } from "../../ui/React/hooks";
import { ActionHeader } from "./ActionHeader";
interface BlackOpElemProps {
bladeburner: Bladeburner;
blackOp: BlackOperation;
action: BlackOperation;
}
export function BlackOpElem({ bladeburner, blackOp }: BlackOpElemProps): React.ReactElement {
export function BlackOpElem({ bladeburner, action }: BlackOpElemProps): React.ReactElement {
const rerender = useRerender();
const isCompleted = bladeburner.numBlackOpsComplete > blackOp.n;
const isCompleted = bladeburner.numBlackOpsComplete > action.n;
if (isCompleted) {
return (
<Paper sx={{ my: 1, p: 1 }}>
<Typography>{blackOp.name} (COMPLETED)</Typography>
<Typography>{action.name} (COMPLETED)</Typography>
</Paper>
);
}
const isActive = bladeburner.action?.name === blackOp.name;
const actionTime = blackOp.getActionTime(bladeburner, Player);
const hasReqdRank = bladeburner.rank >= blackOp.reqdRank;
const computedActionTimeCurrent = Math.min(
bladeburner.actionTimeCurrent + bladeburner.actionTimeOverflow,
bladeburner.actionTimeToComplete,
);
const actionTime = action.getActionTime(bladeburner, Player);
const hasRequiredRank = bladeburner.rank >= action.reqdRank;
return (
<Paper sx={{ my: 1, p: 1 }}>
{isActive ? (
<>
<CopyableText value={blackOp.name} />
<Typography>
(IN PROGRESS - {formatNumberNoSuffix(computedActionTimeCurrent, 0)} /{" "}
{formatNumberNoSuffix(bladeburner.actionTimeToComplete, 0)})
</Typography>
<Typography>
{createProgressBarText({
progress: computedActionTimeCurrent / bladeburner.actionTimeToComplete,
})}
</Typography>
</>
) : (
<>
<CopyableText value={blackOp.name} />
<StartButton bladeburner={bladeburner} action={blackOp} rerender={rerender} />
<TeamSizeButton action={blackOp} bladeburner={bladeburner} />
</>
)}
<ActionHeader bladeburner={bladeburner} action={action} rerender={rerender}></ActionHeader>
<br />
<Typography whiteSpace={"pre-wrap"}>{action.desc}</Typography>
<br />
<Typography whiteSpace={"pre-wrap"}>{blackOp.desc}</Typography>
<br />
<br />
<Typography color={hasReqdRank ? "primary" : "error"}>
Required Rank: {formatNumberNoSuffix(blackOp.reqdRank, 0)}
<Typography color={hasRequiredRank ? "primary" : "error"}>
Required Rank: {formatNumberNoSuffix(action.reqdRank, 0)}
</Typography>
<br />
<Typography>
<SuccessChance action={blackOp} bladeburner={bladeburner} />
<SuccessChance action={action} bladeburner={bladeburner} />
<br />
Time Required: {convertTimeMsToTimeElapsedString(actionTime * 1000)}
</Typography>

@ -1,6 +1,6 @@
import type { Bladeburner } from "../Bladeburner";
import * as React from "react";
import React from "react";
import { Button, Typography } from "@mui/material";
import { FactionName } from "@enums";
import { BlackOpElem } from "./BlackOpElem";
@ -14,7 +14,7 @@ interface BlackOpPageProps {
}
export function BlackOpPage({ bladeburner }: BlackOpPageProps): React.ReactElement {
const blackOps = blackOpsArray.slice(0, bladeburner.numBlackOpsComplete + 1).reverse();
const blackOperations = blackOpsArray.slice(0, bladeburner.numBlackOpsComplete + 1).reverse();
return (
<>
@ -38,8 +38,8 @@ export function BlackOpPage({ bladeburner }: BlackOpPageProps): React.ReactEleme
</Button>
) : (
<>
{blackOps.map((blackOp) => (
<BlackOpElem key={blackOp.name} bladeburner={bladeburner} blackOp={blackOp} />
{blackOperations.map((blackOperation) => (
<BlackOpElem key={blackOperation.name} bladeburner={bladeburner} action={blackOperation} />
))}
</>
)}

@ -2,18 +2,16 @@ import type { Bladeburner } from "../Bladeburner";
import type { Contract } from "../Actions/Contract";
import React from "react";
import { createProgressBarText } from "../../utils/helpers/createProgressBarText";
import { convertTimeMsToTimeElapsedString } from "../../utils/StringHelperFunctions";
import { Player } from "@player";
import { SuccessChance } from "./SuccessChance";
import { CopyableText } from "../../ui/React/CopyableText";
import { ActionLevel } from "./ActionLevel";
import { Autolevel } from "./Autolevel";
import { StartButton } from "./StartButton";
import { formatNumberNoSuffix, formatBigNumber } from "../../ui/formatNumber";
import { formatBigNumber } from "../../ui/formatNumber";
import { Paper, Typography } from "@mui/material";
import { useRerender } from "../../ui/React/hooks";
import { getEnumHelper } from "../../utils/EnumHelper";
import { ActionHeader } from "./ActionHeader";
interface ContractElemProps {
bladeburner: Bladeburner;
@ -25,38 +23,14 @@ export function ContractElem({ bladeburner, action }: ContractElemProps): React.
// Temp special return
if (!getEnumHelper("BladeContractName").isMember(action.name)) return <></>;
const isActive = action.name === bladeburner.action?.name;
const computedActionTimeCurrent = Math.min(
bladeburner.actionTimeCurrent + bladeburner.actionTimeOverflow,
bladeburner.actionTimeToComplete,
);
const actionTime = action.getActionTime(bladeburner, Player);
return (
<Paper sx={{ my: 1, p: 1 }}>
{isActive ? (
<>
<CopyableText value={action.name} />
<Typography>
(IN PROGRESS - {formatNumberNoSuffix(computedActionTimeCurrent, 0)} /{" "}
{formatNumberNoSuffix(bladeburner.actionTimeToComplete, 0)})
</Typography>
<Typography>
{createProgressBarText({
progress: computedActionTimeCurrent / bladeburner.actionTimeToComplete,
})}
</Typography>
</>
) : (
<>
<CopyableText value={action.name} />
<StartButton bladeburner={bladeburner} action={action} rerender={rerender} />
</>
)}
<br />
<ActionHeader bladeburner={bladeburner} action={action} rerender={rerender}></ActionHeader>
<br />
<ActionLevel action={action} bladeburner={bladeburner} isActive={isActive} rerender={rerender} />
<br />
<br />
<Typography whiteSpace={"pre-wrap"}>
{action.desc}
<br />

@ -2,15 +2,12 @@ import type { Bladeburner } from "../Bladeburner";
import type { GeneralAction } from "../Actions/GeneralAction";
import React from "react";
import { createProgressBarText } from "../../utils/helpers/createProgressBarText";
import { formatNumberNoSuffix } from "../../ui/formatNumber";
import { convertTimeMsToTimeElapsedString } from "../../utils/StringHelperFunctions";
import { Player } from "@player";
import { CopyableText } from "../../ui/React/CopyableText";
import { StartButton } from "./StartButton";
import { StopButton } from "./StopButton";
import { Box, Paper, Typography } from "@mui/material";
import { Paper, Typography } from "@mui/material";
import { useRerender } from "../../ui/React/hooks";
import { ActionHeader } from "./ActionHeader";
interface GeneralActionElemProps {
bladeburner: Bladeburner;
@ -19,44 +16,16 @@ interface GeneralActionElemProps {
export function GeneralActionElem({ bladeburner, action }: GeneralActionElemProps): React.ReactElement {
const rerender = useRerender();
const isActive = action.name === bladeburner.action?.name;
const computedActionTimeCurrent = Math.min(
bladeburner.actionTimeCurrent + bladeburner.actionTimeOverflow,
bladeburner.actionTimeToComplete,
);
const actionTime = action.getActionTime(bladeburner, Player);
const successChance =
action.name === "Recruitment" ? Math.max(0, Math.min(bladeburner.getRecruitmentSuccessChance(Player), 1)) : -1;
return (
<Paper sx={{ my: 1, p: 1 }}>
{isActive ? (
<>
<Box display="flex" flexDirection="row" alignItems="center">
<CopyableText value={action.name} />
<StopButton bladeburner={bladeburner} rerender={rerender} />
</Box>
<Typography>
(IN PROGRESS - {formatNumberNoSuffix(computedActionTimeCurrent, 0)} /{" "}
{formatNumberNoSuffix(bladeburner.actionTimeToComplete, 0)})
</Typography>
<Typography>
{createProgressBarText({
progress: computedActionTimeCurrent / bladeburner.actionTimeToComplete,
})}
</Typography>
</>
) : (
<Box display="flex" flexDirection="row" alignItems="center">
<CopyableText value={action.name} />
<StartButton bladeburner={bladeburner} action={action} rerender={rerender} />
</Box>
)}
<br />
<ActionHeader bladeburner={bladeburner} action={action} rerender={rerender}></ActionHeader>
<br />
<Typography>{action.desc}</Typography>
<br />
<br />
<Typography>
Time Required: {convertTimeMsToTimeElapsedString(actionTime * 1000)}
{successChance !== -1 && (

@ -5,76 +5,47 @@ import React from "react";
import { Paper, Typography } from "@mui/material";
import { Player } from "@player";
import { createProgressBarText } from "../../utils/helpers/createProgressBarText";
import { convertTimeMsToTimeElapsedString } from "../../utils/StringHelperFunctions";
import { SuccessChance } from "./SuccessChance";
import { ActionLevel } from "./ActionLevel";
import { Autolevel } from "./Autolevel";
import { StartButton } from "./StartButton";
import { TeamSizeButton } from "./TeamSizeButton";
import { CopyableText } from "../../ui/React/CopyableText";
import { formatNumberNoSuffix, formatBigNumber } from "../../ui/formatNumber";
import { formatBigNumber } from "../../ui/formatNumber";
import { useRerender } from "../../ui/React/hooks";
import { BladeActionType } from "@enums";
import { ActionHeader } from "./ActionHeader";
interface OperationElemProps {
bladeburner: Bladeburner;
operation: Operation;
action: Operation;
}
export function OperationElem({ bladeburner, operation }: OperationElemProps): React.ReactElement {
export function OperationElem({ bladeburner, action }: OperationElemProps): React.ReactElement {
const rerender = useRerender();
const isActive =
bladeburner.action?.type === BladeActionType.operation && operation.name === bladeburner.action?.name;
const computedActionTimeCurrent = Math.min(
bladeburner.actionTimeCurrent + bladeburner.actionTimeOverflow,
bladeburner.actionTimeToComplete,
);
const actionTime = operation.getActionTime(bladeburner, Player);
const isActive = bladeburner.action?.type === BladeActionType.operation && action.name === bladeburner.action?.name;
const actionTime = action.getActionTime(bladeburner, Player);
return (
<Paper sx={{ my: 1, p: 1 }}>
{isActive ? (
<>
<Typography>
<CopyableText value={operation.name} /> (IN PROGRESS - {formatNumberNoSuffix(computedActionTimeCurrent, 0)}{" "}
/ {formatNumberNoSuffix(bladeburner.actionTimeToComplete, 0)})
</Typography>
<Typography>
{createProgressBarText({
progress: computedActionTimeCurrent / bladeburner.actionTimeToComplete,
})}
</Typography>
</>
) : (
<>
<CopyableText value={operation.name} />
<StartButton bladeburner={bladeburner} action={operation} rerender={rerender} />
<TeamSizeButton action={operation} bladeburner={bladeburner} />
</>
)}
<br />
<br />
<ActionLevel action={operation} bladeburner={bladeburner} isActive={isActive} rerender={rerender} />
<ActionHeader bladeburner={bladeburner} action={action} rerender={rerender}></ActionHeader>
<br />
<ActionLevel action={action} bladeburner={bladeburner} isActive={isActive} rerender={rerender} />
<br />
<Typography whiteSpace={"pre-wrap"}>
{operation.desc}
{action.desc}
<br />
<br />
<SuccessChance action={operation} bladeburner={bladeburner} />
<SuccessChance action={action} bladeburner={bladeburner} />
<br />
Time Required: {convertTimeMsToTimeElapsedString(actionTime * 1000)}
<br />
Operations remaining: {formatBigNumber(Math.floor(operation.count))}
Operations remaining: {formatBigNumber(Math.floor(action.count))}
<br />
Successes: {formatBigNumber(operation.successes)}
Successes: {formatBigNumber(action.successes)}
<br />
Failures: {formatBigNumber(operation.failures)}
Failures: {formatBigNumber(action.failures)}
</Typography>
<br />
<Autolevel rerender={rerender} action={operation} />
<Autolevel rerender={rerender} action={action} />
</Paper>
);
}

@ -1,6 +1,6 @@
import type { Bladeburner } from "../Bladeburner";
import * as React from "react";
import React from "react";
import { OperationElem } from "./OperationElem";
import { Typography } from "@mui/material";
@ -30,7 +30,7 @@ export function OperationPage({ bladeburner }: OperationPageProps): React.ReactE
difficult, but grant more rank and experience.
</Typography>
{operations.map((operation) => (
<OperationElem key={operation.name} bladeburner={bladeburner} operation={operation} />
<OperationElem key={operation.name} bladeburner={bladeburner} action={operation} />
))}
</>
);

@ -20,7 +20,11 @@ export function StartButton({ bladeburner, action, rerender }: StartButtonProps)
}
return (
<ButtonWithTooltip disabledTooltip={disabledReason} onClick={onStart}>
<ButtonWithTooltip
buttonProps={{ style: { marginLeft: "1rem" } }}
disabledTooltip={disabledReason}
onClick={onStart}
>
Start
</ButtonWithTooltip>
);

@ -13,5 +13,9 @@ export function StopButton({ bladeburner, rerender }: StopButtonProps): React.Re
rerender();
}
return <Button onClick={onClick}>Stop</Button>;
return (
<Button style={{ marginLeft: "1rem" }} onClick={onClick}>
Stop
</Button>
);
}

@ -15,7 +15,7 @@ export function TeamSizeButton({ action, bladeburner }: TeamSizeButtonProps): Re
return (
<>
<Button disabled={bladeburner.teamSize === 0} onClick={() => setOpen(true)}>
<Button style={{ marginLeft: "1rem" }} disabled={bladeburner.teamSize === 0} onClick={() => setOpen(true)}>
Set Team Size (Curr Size: {formatNumberNoSuffix(action.teamCount, 0)})
</Button>
<TeamSizeModal open={open} onClose={() => setOpen(false)} action={action} bladeburner={bladeburner} />