From a12056a8987c0ebfffa70cd0a96669020559552a Mon Sep 17 00:00:00 2001 From: catloversg <152669316+catloversg@users.noreply.github.com> Date: Thu, 13 Jun 2024 09:21:23 +0700 Subject: [PATCH] BLADEBURNER: Add remaining time for actions (#1391) --- src/Bladeburner/ui/ActionHeader.tsx | 46 +++++++++++++++++++++++++---- src/Bladeburner/ui/Stats.tsx | 2 +- src/engine.tsx | 2 +- 3 files changed, 43 insertions(+), 7 deletions(-) diff --git a/src/Bladeburner/ui/ActionHeader.tsx b/src/Bladeburner/ui/ActionHeader.tsx index 51caf9733..6295ac930 100644 --- a/src/Bladeburner/ui/ActionHeader.tsx +++ b/src/Bladeburner/ui/ActionHeader.tsx @@ -11,18 +11,51 @@ import { TeamSizeButton } from "./TeamSizeButton"; import { formatNumberNoSuffix } from "../../ui/formatNumber"; import { BlackOperation, Operation } from "../Actions"; +import { BladeburnerConstants } from "../data/Constants"; +import { convertTimeMsToTimeElapsedString } from "../../utils/StringHelperFunctions"; 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 remainingSeconds = Math.max( + bladeburner.actionTimeToComplete - bladeburner.actionTimeCurrent + bladeburner.actionTimeOverflow, + 0, + ); + const remainingBonusSeconds = Math.floor(bladeburner.storedCycles / BladeburnerConstants.CyclesPerSecond); + /** + * Bladeburner is processed every second. Each time it's processed, we use (up to) 4 bonus seconds and process it as + * if (up to) 5 seconds passed. + * For example, with 20 bonus seconds, we need 5 seconds to use up all those bonus seconds. After 5 seconds, we used + * up 20 bonus seconds and processed Bladeburner as if 25 seconds had passed. + */ + const effectiveBonusSeconds = (remainingBonusSeconds / 4) * 5; + let eta; + if (remainingSeconds <= effectiveBonusSeconds) { + // If we have enough effectiveBonusSeconds, ETA is (remainingSeconds / 5). + eta = Math.floor(remainingSeconds / 5); + } else { + /** + * For example, let's say we start the "Training" action with 20 bonus seconds: remainingSeconds=30;remainingBonusSeconds=20. + * After 5 seconds (remainingBonusSeconds / 4), we processed Bladeburner as if 25 seconds (effectiveBonusSeconds) + * had passed. We still need 5 more seconds (30 - 25 = remainingTime - effectiveBonusSeconds) to complete the action + * at normal speed. + * + * ETA = remainingBonusSeconds / 4 + remainingTime - effectiveBonusSeconds + * = remainingBonusSeconds / 4 + remainingTime - ((remainingBonusSeconds / 4) * 5) + * = remainingTime - remainingBonusSeconds + */ + eta = remainingSeconds - remainingBonusSeconds; + } + const allowTeam = action instanceof Operation || action instanceof BlackOperation; if (isActive) { @@ -36,11 +69,14 @@ export function ActionHeader({ bladeburner, action, rerender }: ActionHeaderProp (IN PROGRESS - {formatNumberNoSuffix(computedActionTimeCurrent, 0)} /{" "} {formatNumberNoSuffix(bladeburner.actionTimeToComplete, 0)}) - - {createProgressBarText({ - progress: computedActionTimeCurrent / bladeburner.actionTimeToComplete, - })} - + + + {createProgressBarText({ + progress: computedActionTimeCurrent / bladeburner.actionTimeToComplete, + })} + + Remaining time: {convertTimeMsToTimeElapsedString(eta * 1000)} + ); } diff --git a/src/Bladeburner/ui/Stats.tsx b/src/Bladeburner/ui/Stats.tsx index a1bb51598..df7419f2d 100644 --- a/src/Bladeburner/ui/Stats.tsx +++ b/src/Bladeburner/ui/Stats.tsx @@ -130,7 +130,7 @@ export function Stats({ bladeburner }: StatsProps): React.ReactElement {
- {(bladeburner.storedCycles / BladeburnerConstants.CyclesPerSecond) * 1000 > 15000 && ( + {bladeburner.storedCycles / BladeburnerConstants.CyclesPerSecond > 3 && ( <>