From 0dd967369099ee9cef709c6a94b8a761148a0a85 Mon Sep 17 00:00:00 2001 From: Z8MB1E Date: Wed, 9 Sep 2026 18:55:00 -0400 Subject: [PATCH] fix(eod): unlock custom minefields after clearing two sectors --- .../frontend/minigames/eod/EodArena.tsx | 5 ++--- .../frontend/minigames/eod/MinesweeperBoard.tsx | 10 +++++++--- src/lib/minigames/custom/eod.ts | 8 ++------ tests/int/custom-minefields.int.spec.ts | 16 +++++++++++----- 4 files changed, 22 insertions(+), 17 deletions(-) diff --git a/src/components/frontend/minigames/eod/EodArena.tsx b/src/components/frontend/minigames/eod/EodArena.tsx index 7010802..be1a74c 100644 --- a/src/components/frontend/minigames/eod/EodArena.tsx +++ b/src/components/frontend/minigames/eod/EodArena.tsx @@ -34,7 +34,6 @@ export function EodArena({ const clearedSectors = [ initialStats.bestTrainingTime, initialStats.bestPerimeterTime, - initialStats.bestSupplyRoadTime, ].filter((time) => time > 0).length; useEffect(() => { @@ -55,8 +54,8 @@ export function EodArena({ {!customUnlocked && ( )} (null); const baseConfig: GameConfig = difficulty === "custom" ? customConfig : DIFFICULTIES[difficulty]; const config = isMobile ? getMobileConfig(baseConfig, isLandscape) : baseConfig; - const customUnlocked = - stats.bestTrainingTime > 0 && stats.bestPerimeterTime > 0 && stats.bestSupplyRoadTime > 0; + const customUnlocked = isEodUnlocked({ + bestTrainingTime: stats.bestTrainingTime, + bestPerimeterTime: stats.bestPerimeterTime, + bestSupplyRoadTime: stats.bestSupplyRoadTime, + }); const isLargeCustomGame = difficulty === "custom" && config.rows * config.cols > CUSTOM_FULLSCREEN_CELL_THRESHOLD; const flaggedCount = board.reduce((count, cell) => count + (cell.flagged ? 1 : 0), 0); @@ -812,7 +816,7 @@ export function MinesweeperBoard({ ) : !customUnlocked ? (

- Clear all three standard locations to unlock custom minefields. + Clear the Training Pad and FOB Perimeter to unlock custom minefields.

) : null} diff --git a/src/lib/minigames/custom/eod.ts b/src/lib/minigames/custom/eod.ts index 7e515c9..659770a 100644 --- a/src/lib/minigames/custom/eod.ts +++ b/src/lib/minigames/custom/eod.ts @@ -23,13 +23,9 @@ export interface EodUnlockStats { bestSupplyRoadTime: number; } -/** A player unlocks the custom minefield editor once they cleared all three standard difficulties. */ +/** A player unlocks the custom minefield editor once they cleared Training Pad and FOB Perimeter. */ export function isEodUnlocked(stats: EodUnlockStats): boolean { - return ( - stats.bestTrainingTime > 0 && - stats.bestPerimeterTime > 0 && - stats.bestSupplyRoadTime > 0 - ); + return stats.bestTrainingTime > 0 && stats.bestPerimeterTime > 0; } export function validateMinefieldName(name: unknown): { error?: string; name: string } { diff --git a/tests/int/custom-minefields.int.spec.ts b/tests/int/custom-minefields.int.spec.ts index 2dfec59..d1b903f 100644 --- a/tests/int/custom-minefields.int.spec.ts +++ b/tests/int/custom-minefields.int.spec.ts @@ -465,7 +465,7 @@ describe("Custom minefields", () => { // --------------------------------------------------------------------------- describe("Unlock gating", () => { - it("locks custom minefields until a win is recorded on all three difficulties", () => { + it("locks custom minefields until Training Pad and FOB Perimeter are cleared", () => { expect( isEodUnlocked({ bestTrainingTime: 0, bestPerimeterTime: 0, bestSupplyRoadTime: 0 }), ).toBe(false); @@ -473,18 +473,24 @@ describe("Custom minefields", () => { isEodUnlocked({ bestTrainingTime: 45, bestPerimeterTime: 0, bestSupplyRoadTime: 0 }), ).toBe(false); expect( - isEodUnlocked({ bestTrainingTime: 45, bestPerimeterTime: 60, bestSupplyRoadTime: 0 }), + isEodUnlocked({ bestTrainingTime: 0, bestPerimeterTime: 60, bestSupplyRoadTime: 0 }), ).toBe(false); }); - it("unlocks once every difficulty has a best time above zero", () => { + it("unlocks once Training Pad and FOB Perimeter have best times above zero", () => { expect( - isEodUnlocked({ bestTrainingTime: 1, bestPerimeterTime: 1, bestSupplyRoadTime: 1 }), + isEodUnlocked({ bestTrainingTime: 1, bestPerimeterTime: 1, bestSupplyRoadTime: 0 }), ).toBe(true); expect( - isEodUnlocked({ bestTrainingTime: 45, bestPerimeterTime: 60, bestSupplyRoadTime: 120 }), + isEodUnlocked({ bestTrainingTime: 45, bestPerimeterTime: 60, bestSupplyRoadTime: 0 }), ).toBe(true); }); + + it("does not let a Main Supply Road win substitute for the required sectors", () => { + expect( + isEodUnlocked({ bestTrainingTime: 0, bestPerimeterTime: 0, bestSupplyRoadTime: 120 }), + ).toBe(false); + }); }); // ---------------------------------------------------------------------------