From 11ae047e33247dc319b4ea7f629cbcdc892c2170 Mon Sep 17 00:00:00 2001 From: VariableVince <24507472+VariableVince@users.noreply.github.com> Date: Mon, 13 Oct 2025 20:14:03 +0200 Subject: [PATCH] Fix Boat hotkey (B) behaviour (#2179) ## Description: Fixes Issue #2177, land border required to send boat. And fixes boat not being sent for longer distances. - Boat Hotkey (B) (PR #1060) was implemented seemingly with a wrong assumption. Namely that it should do the same checks as the AUTO BOAT functionality (PR #540) before sending a transport ship. But it should have done the same checks as when sending a MANUAL transport ship, as if the Radial Menu was used. Basically the same checks as in RadialMenuElements line 508-532. Because of this it wrongly required: - there to be no land border with the other player (while boat from radial menu gets sent without bothering about this) - the tile clicked to be a Land tile (only makes sense in the context of auto-boating where user clicks to attack an enemy on their land, and only if there's no border will it then send a boat to that land if possible) - the distance to be short (since auto-boat was mainly meant to automatically cross rivers) Fixed this by removing canAttack check (for the unwanted land border requirement) and splitting up the auto boat and the manual boat checks. - canBoatAttack: moved out the parts which where only meant for auto-boating - shouldBoat: moved in the parts from canBoatAttack that where only meant for auto-boating. Renamed it to canAutoBoat for better discernability. Gave it early returns for tad better performance and consolidated returns in the bottom, while keeping the same functionality. ## Please complete the following: - [ ] I have added screenshots for all UI updates - [ ] I process any text displayed to the user through translateText() and I've added it to the en.json file - [ ] I have added relevant tests to the test directory - [x] I confirm I have thoroughly tested these changes and take full responsibility for any bugs introduced ## Please put your Discord username so you can be contacted if a bug or regression is found: tryout33 --- src/client/ClientGameRunner.ts | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/client/ClientGameRunner.ts b/src/client/ClientGameRunner.ts index c03820c2f..f4f6f119e 100644 --- a/src/client/ClientGameRunner.ts +++ b/src/client/ClientGameRunner.ts @@ -423,7 +423,7 @@ export class ClientGameRunner { this.myPlayer.troops() * this.renderer.uiState.attackRatio, ), ); - } else if (this.canBoatAttack(actions, tile)) { + } else if (this.canAutoBoat(actions, tile)) { this.sendBoatAttackIntent(tile); } @@ -519,7 +519,7 @@ export class ClientGameRunner { } this.myPlayer.actions(tile).then((actions) => { - if (!actions.canAttack && this.canBoatAttack(actions, tile)) { + if (this.canBoatAttack(actions) !== false) { this.sendBoatAttackIntent(tile); } }); @@ -567,7 +567,7 @@ export class ClientGameRunner { return this.gameView.ref(cell.x, cell.y); } - private canBoatAttack(actions: PlayerActions, tile: TileRef): boolean { + private canBoatAttack(actions: PlayerActions): false | TileRef { const bu = actions.buildableUnits.find( (bu) => bu.type === UnitType.TransportShip, ); @@ -575,11 +575,7 @@ export class ClientGameRunner { console.warn(`no transport ship buildable units`); return false; } - return ( - bu.canBuild !== false && - this.shouldBoat(tile, bu.canBuild) && - this.gameView.isLand(tile) - ); + return bu.canBuild; } private sendBoatAttackIntent(tile: TileRef) { @@ -598,16 +594,20 @@ export class ClientGameRunner { }); } - private shouldBoat(tile: TileRef, src: TileRef) { + private canAutoBoat(actions: PlayerActions, tile: TileRef): boolean { + if (!this.gameView.isLand(tile)) return false; + + const canBuild = this.canBoatAttack(actions); + if (canBuild === false) return false; + // TODO: Global enable flag // TODO: Global limit autoboat to nearby shore flag // if (!enableAutoBoat) return false; // if (!limitAutoBoatNear) return true; - const distanceSquared = this.gameView.euclideanDistSquared(tile, src); + const distanceSquared = this.gameView.euclideanDistSquared(tile, canBuild); const limit = 100; const limitSquared = limit * limit; - if (distanceSquared > limitSquared) return false; - return true; + return distanceSquared < limitSquared; } private onMouseMove(event: MouseMoveEvent) {