From c6296c0bb168ca649ba5f03f64ff1c4f8a16a907 Mon Sep 17 00:00:00 2001 From: Katokoda <79760461+Katokoda@users.noreply.github.com> Date: Fri, 5 Jun 2026 22:42:52 +0200 Subject: [PATCH] Fix/warship freezing no path (#4151) **Add approved & assigned issue number here:** Resolves #4113 ## Description: Warships now reject the PatrolTile change when the new one is a different water component. Adds a test ensuring this behavior. ## Please complete the following: - [x] I have added screenshots for all UI updates There are none - [x] I process any text displayed to the user through translateText() and I've added it to the en.json file No texts - [x] I have added relevant tests to the test directory I also have tested in game and tested that the test does indeed fail if my fix is not present. ## Please put your Discord username so you can be contacted if a bug or regression is found: Katokoda --- src/core/execution/MoveWarshipExecution.ts | 6 ++++ tests/Warship.test.ts | 32 ++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/src/core/execution/MoveWarshipExecution.ts b/src/core/execution/MoveWarshipExecution.ts index fb21d8858..f8bbc0560 100644 --- a/src/core/execution/MoveWarshipExecution.ts +++ b/src/core/execution/MoveWarshipExecution.ts @@ -13,6 +13,8 @@ export class MoveWarshipExecution implements Execution { console.warn(`MoveWarshipExecution: position ${this.position} not valid`); return; } + // Get water component of new TargetTile for connectivity check + const newPatrolTileWaterComponent = mg.getWaterComponent(this.position); // Cache warship list and build a lookup map — avoids repeated iteration const warshipMap = new Map( this.owner.units(UnitType.Warship).map((u) => [u.id(), u]), @@ -28,6 +30,10 @@ export class MoveWarshipExecution implements Execution { console.warn(`MoveWarshipExecution: warship ${unitId} is not active`); continue; } + // Do not update the warship's patrolTile if it is in a different Water Component + if (!mg.hasWaterComponent(warship.tile(), newPatrolTileWaterComponent!)) { + continue; + } warship.updateWarshipState({ patrolTile: this.position, }); diff --git a/tests/Warship.test.ts b/tests/Warship.test.ts index 882084281..ea2dcd051 100644 --- a/tests/Warship.test.ts +++ b/tests/Warship.test.ts @@ -915,4 +915,36 @@ describe("Warship", () => { } expect(tradeShip.owner()).toBe(player1); }); + + test("Warship doesn't accept a new patrol tile if in a different water component", async () => { + const newPatrolTile = game.ref(coastX + 5, 15); + + const warship = player1.buildUnit( + UnitType.Warship, + game.ref(coastX + 1, 10), + { + patrolTile: game.ref(coastX + 1, 10), + }, + ); + + game.addExecution(new WarshipExecution(warship)); + + // Mock different water components + game.getWaterComponent = (tile: TileRef) => { + if (tile === newPatrolTile) return 1; + return 2; + }; + + game.hasWaterComponent = (tile: TileRef, component: number) => { + return game.getWaterComponent(tile) === component; + }; + + game.addExecution( + new MoveWarshipExecution(player1, [warship.id()], newPatrolTile), + ); + + executeTicks(game, 10); + + expect(warship.warshipState().patrolTile).toBe(game.ref(coastX + 1, 10)); + }); });