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 && (
<>