From 329fdc50fb1dcff9a7cbad2896fb0a30c75b4000 Mon Sep 17 00:00:00 2001 From: catloversg <152669316+catloversg@users.noreply.github.com> Date: Sun, 23 Nov 2025 14:08:15 +0700 Subject: [PATCH] CODEBASE: Follow-up of infil refactor #2316 (#2393) --- src/Infiltration/ui/GameTimer.tsx | 11 +++++++---- src/Infiltration/ui/InfiltrationRoot.tsx | 5 +++-- src/Infiltration/ui/Intro.tsx | 2 -- src/Infiltration/ui/MinesweeperGame.tsx | 2 +- src/Locations/ui/CompanyLocation.tsx | 2 +- src/PersonObjects/Player/PlayerObject.ts | 2 +- .../Player/PlayerObjectGeneralMethods.ts | 2 +- 7 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/Infiltration/ui/GameTimer.tsx b/src/Infiltration/ui/GameTimer.tsx index 894fe6111..e733ac8d0 100644 --- a/src/Infiltration/ui/GameTimer.tsx +++ b/src/Infiltration/ui/GameTimer.tsx @@ -1,5 +1,6 @@ import React, { useEffect, useRef, useMemo } from "react"; import { ProgressBar } from "../../ui/React/Progress"; +import { clampNumber } from "../../utils/helpers/clampNumber"; type GameTimerProps = { endTimestamp: number; @@ -14,7 +15,7 @@ export function GameTimer({ endTimestamp }: GameTimerProps): React.ReactElement // actually begin it until later. We're using a ref to keep this updated in // a very low-overhead way. const state = changeRef.current; - if (state?.endTimestamp !== endTimestamp) { + if (state.endTimestamp !== endTimestamp) { state.endTimestamp = endTimestamp; state.startTimestamp = performance.now(); } @@ -24,10 +25,12 @@ export function GameTimer({ endTimestamp }: GameTimerProps): React.ReactElement const ele = ref.current?.firstElementChild; const startTimestamp = changeRef.current.startTimestamp; if (!ele) return; - // The delay will be negative. This is because the animation starts - // partway completed, due to the time taken to invoke the effect. ele.animate([{ transform: "translateX(0%)" }, { transform: "translateX(-100%)" }], { - duration: endTimestamp - startTimestamp, + // If duration is negative, ele.animate will throw "TypeError: duration must be non-negative or auto". It may + // happen when the player uses the debugger. + duration: clampNumber(endTimestamp - startTimestamp, 0), + // The delay will be negative. This is because the animation starts + // partway completed, due to the time taken to invoke the effect. delay: startTimestamp - performance.now(), }); }, [endTimestamp]); diff --git a/src/Infiltration/ui/InfiltrationRoot.tsx b/src/Infiltration/ui/InfiltrationRoot.tsx index e1d6063ce..c2ebf208f 100644 --- a/src/Infiltration/ui/InfiltrationRoot.tsx +++ b/src/Infiltration/ui/InfiltrationRoot.tsx @@ -33,7 +33,7 @@ interface StageProps { } // The extra cast here is needed because otherwise it sees the more-specific -// types of the components, and gets grumpy that they are not interconvertable. +// types of the components, and gets grumpy that they are not interconvertible. const stages = new Map([ [IntroModel, Intro], [CountdownModel, Countdown], @@ -51,6 +51,7 @@ const stages = new Map([ function Progress({ results }: { results: string }): React.ReactElement { return ( + {/* Only show the last 14 results instead of the full history. */} {results.slice(-15, -1)} {results[results.length - 1]} @@ -106,7 +107,7 @@ export function InfiltrationRoot(): React.ReactElement { return (
{state.stage instanceof IntroModel ? ( - + ) : ( diff --git a/src/Infiltration/ui/Intro.tsx b/src/Infiltration/ui/Intro.tsx index 8d8242803..34bf4e842 100644 --- a/src/Infiltration/ui/Intro.tsx +++ b/src/Infiltration/ui/Intro.tsx @@ -4,7 +4,6 @@ import { Settings } from "../../Settings/Settings"; import { formatHp, formatMoney, formatNumberNoSuffix, formatPercent, formatReputation } from "../../ui/formatNumber"; import { Player } from "@player"; import type { Infiltration } from "../Infiltration"; -import type { IntroModel } from "../model/IntroModel"; import { calculateDamageAfterFailingInfiltration } from "../utils"; import { calculateInfiltratorsRepReward, @@ -18,7 +17,6 @@ import { useRerender } from "../../ui/React/hooks"; interface IProps { state: Infiltration; - stage: IntroModel; } function arrowPart(color: string, length: number): JSX.Element { diff --git a/src/Infiltration/ui/MinesweeperGame.tsx b/src/Infiltration/ui/MinesweeperGame.tsx index 8d61bd28c..24f54328b 100644 --- a/src/Infiltration/ui/MinesweeperGame.tsx +++ b/src/Infiltration/ui/MinesweeperGame.tsx @@ -18,7 +18,7 @@ export function MinesweeperGame({ stage }: IProps): React.ReactElement { const flatGrid: { flagged?: boolean; current?: boolean; marked?: boolean }[] = []; stage.minefield.map((line, y) => - line.map((cell, x) => { + line.map((_cell, x) => { if (stage.memoryPhase) { flatGrid.push({ flagged: Boolean(stage.minefield[y][x]) }); return; diff --git a/src/Locations/ui/CompanyLocation.tsx b/src/Locations/ui/CompanyLocation.tsx index 2b6b15556..2b220da43 100644 --- a/src/Locations/ui/CompanyLocation.tsx +++ b/src/Locations/ui/CompanyLocation.tsx @@ -63,7 +63,7 @@ export function CompanyLocation(props: IProps): React.ReactElement { return; } - Player.startInfiltration(location); + Player.initInfiltration(location); Router.toPage(Page.Infiltration); } diff --git a/src/PersonObjects/Player/PlayerObject.ts b/src/PersonObjects/Player/PlayerObject.ts index 70d18aaab..d99b244ce 100644 --- a/src/PersonObjects/Player/PlayerObject.ts +++ b/src/PersonObjects/Player/PlayerObject.ts @@ -152,7 +152,7 @@ export class PlayerObject extends Person implements IPlayer { activeSourceFileLvl = generalMethods.activeSourceFileLvl; applyEntropy = augmentationMethods.applyEntropy; focusPenalty = generalMethods.focusPenalty; - startInfiltration = generalMethods.startInfiltration; + initInfiltration = generalMethods.initInfiltration; constructor() { super(); diff --git a/src/PersonObjects/Player/PlayerObjectGeneralMethods.ts b/src/PersonObjects/Player/PlayerObjectGeneralMethods.ts index d87b0cc56..16619a3c0 100644 --- a/src/PersonObjects/Player/PlayerObjectGeneralMethods.ts +++ b/src/PersonObjects/Player/PlayerObjectGeneralMethods.ts @@ -603,7 +603,7 @@ export function focusPenalty(this: PlayerObject): number { } /** This doesn't change the current page; that is up to the caller. */ -export function startInfiltration(this: PlayerObject, location: Location): void { +export function initInfiltration(this: PlayerObject, location: Location): void { if (!location.infiltrationData) throw new Error(`trying to start infiltration at ${location.name} but the infiltrationData is null`); this.infiltration = new Infiltration(location);