From 6ca06a6f6ff58dbf37a8927193575be89bb67dc0 Mon Sep 17 00:00:00 2001 From: TKTK123456 <103334266+TKTK123456@users.noreply.github.com> Date: Mon, 1 Jun 2026 20:39:52 -0400 Subject: [PATCH] Sam/factory radius ghost upgrade fix (#4104) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit > **Before opening a PR:** discuss new features on [Discord](https://discord.gg/K9zernJB5z) first, and file bugs or small improvements as [issues](https://github.com/openfrontio/OpenFrontIO/issues/new/choose). You must be assigned to an `approved` issue — unsolicited PRs will be auto-closed. **Add approved & assigned issue number here:** Resolves #4059 ## Description: Makes ghost radius centred on building being upgrading (if upgrading building) Screenshot from 2026-06-01
15-45-37 Screenshot from 2026-06-01
15-45-24 ## Please complete the following: - [x] I have added screenshots for all UI updates - [x] I process any text displayed to the user through translateText() and I've added it to the en.json file - [x] I have added relevant tests to the test directory ## Please put your Discord username so you can be contacted if a bug or regression is found: tktk123456 --- src/client/controllers/BuildPreviewController.ts | 12 ++++++++++++ src/client/render/gl/passes/RangeCirclePass.ts | 4 ++-- src/client/render/types/Renderer.ts | 2 ++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/client/controllers/BuildPreviewController.ts b/src/client/controllers/BuildPreviewController.ts index 3a9de6cdb..26a55b1b3 100644 --- a/src/client/controllers/BuildPreviewController.ts +++ b/src/client/controllers/BuildPreviewController.ts @@ -335,12 +335,24 @@ export class BuildPreviewController implements Controller { rangeRadius = this.game.config().defensePostRange(); break; } + let radiusTileX = this.game.x(tileRef); + let radiusTileY = this.game.y(tileRef); + if ( + rangeRadius > 0 && + u.canUpgrade !== false && + upgradeTargetTile !== null + ) { + radiusTileX = this.game.x(upgradeTargetTile); + radiusTileY = this.game.y(upgradeTargetTile); + } const cost = u.cost; return { ghostType: u.type, tileX: this.game.x(tileRef), tileY: this.game.y(tileRef), + radiusTileX, + radiusTileY, canBuild: u.canBuild !== false, canUpgrade: u.canUpgrade !== false, cost: Number(cost), diff --git a/src/client/render/gl/passes/RangeCirclePass.ts b/src/client/render/gl/passes/RangeCirclePass.ts index 8fbe41273..05351f95f 100644 --- a/src/client/render/gl/passes/RangeCirclePass.ts +++ b/src/client/render/gl/passes/RangeCirclePass.ts @@ -54,8 +54,8 @@ export class RangeCirclePass { updateGhostPreview(data: GhostPreviewData | null): void { if (data && data.rangeRadius > 0) { - this.centerX = data.tileX; - this.centerY = data.tileY; + this.centerX = data.radiusTileX; + this.centerY = data.radiusTileY; this.radius = data.rangeRadius; this.warning = data.rangeWarning; } else { diff --git a/src/client/render/types/Renderer.ts b/src/client/render/types/Renderer.ts index 652a5e338..355013ced 100644 --- a/src/client/render/types/Renderer.ts +++ b/src/client/render/types/Renderer.ts @@ -152,6 +152,8 @@ export interface GhostPreviewData { ghostType: string; // UnitType string ("City", "Port", etc.) tileX: number; // Hover tile X tileY: number; // Hover tile Y + radiusTileX: number; + radiusTileY: number; canBuild: boolean; // Valid placement? canUpgrade: boolean; // Upgrading existing structure? cost: number; // Gold cost