From fe4396ebcd5ef6e36b59216271a67b1c85f128a0 Mon Sep 17 00:00:00 2001 From: evan Date: Wed, 23 Apr 2025 13:46:19 -0700 Subject: [PATCH 1/3] show incoming tradeships as green in alternate view --- src/client/graphics/layers/UnitLayer.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/client/graphics/layers/UnitLayer.ts b/src/client/graphics/layers/UnitLayer.ts index 552470879..03bfd8b81 100644 --- a/src/client/graphics/layers/UnitLayer.ts +++ b/src/client/graphics/layers/UnitLayer.ts @@ -425,7 +425,13 @@ export class UnitLayer implements Layer { let alternateViewColor = null; if (this.alternateView) { - const rel = this.relationship(unit); + let rel = this.relationship(unit); + if (unit.type() == UnitType.TradeShip && unit.dstPortId() != null) { + const target = this.game.unit(unit.dstPortId())?.owner(); + if (this.game.myPlayer() != null && this.game.myPlayer() == target) { + rel = Relationship.Self; + } + } switch (rel) { case Relationship.Self: alternateViewColor = this.theme.selfColor(); From a2ba10bdbda6498a0a9c4d2dc43596a1a7ca01e6 Mon Sep 17 00:00:00 2001 From: evan Date: Wed, 23 Apr 2025 14:26:12 -0700 Subject: [PATCH 2/3] show density under player name --- resources/images/ShieldIconBlack.svg | 39 +++++++++++++++++++++++++ src/client/graphics/layers/NameLayer.ts | 37 ++++++++++++++++++++++- 2 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 resources/images/ShieldIconBlack.svg diff --git a/resources/images/ShieldIconBlack.svg b/resources/images/ShieldIconBlack.svg new file mode 100644 index 000000000..26bc34312 --- /dev/null +++ b/resources/images/ShieldIconBlack.svg @@ -0,0 +1,39 @@ + + diff --git a/src/client/graphics/layers/NameLayer.ts b/src/client/graphics/layers/NameLayer.ts index 1ecdfba02..58c49fff2 100644 --- a/src/client/graphics/layers/NameLayer.ts +++ b/src/client/graphics/layers/NameLayer.ts @@ -4,6 +4,7 @@ import crownIcon from "../../../../resources/images/CrownIcon.svg"; import embargoIcon from "../../../../resources/images/EmbargoIcon.svg"; import nukeRedIcon from "../../../../resources/images/NukeIconRed.svg"; import nukeWhiteIcon from "../../../../resources/images/NukeIconWhite.svg"; +import shieldIcon from "../../../../resources/images/ShieldIconBlack.svg"; import targetIcon from "../../../../resources/images/TargetIcon.svg"; import traitorIcon from "../../../../resources/images/TraitorIcon.svg"; import { PseudoRandom } from "../../../core/PseudoRandom"; @@ -11,7 +12,7 @@ import { ClientID } from "../../../core/Schemas"; import { Theme } from "../../../core/configuration/Config"; import { AllPlayers, Cell, nukeTypes } from "../../../core/game/Game"; import { GameView, PlayerView } from "../../../core/game/GameView"; -import { createCanvas, renderTroops } from "../../Utils"; +import { createCanvas, renderNumber, renderTroops } from "../../Utils"; import { TransformHandler } from "../TransformHandler"; import { Layer } from "./Layer"; @@ -44,6 +45,7 @@ export class NameLayer implements Layer { private embargoIconImage: HTMLImageElement; private nukeWhiteIconImage: HTMLImageElement; private nukeRedIconImage: HTMLImageElement; + private shieldIconImage: HTMLImageElement; private container: HTMLDivElement; private myPlayer: PlayerView | null = null; private firstPlace: PlayerView | null = null; @@ -70,6 +72,8 @@ export class NameLayer implements Layer { this.nukeWhiteIconImage.src = nukeWhiteIcon; this.nukeRedIconImage = new Image(); this.nukeRedIconImage.src = nukeRedIcon; + this.shieldIconImage = new Image(); + this.shieldIconImage.src = shieldIcon; } resizeCanvas() { @@ -210,6 +214,19 @@ export class NameLayer implements Layer { troopsDiv.style.marginTop = "-5%"; element.appendChild(troopsDiv); + const shieldDiv = document.createElement("div"); + shieldDiv.classList.add("player-shield"); + shieldDiv.style.zIndex = "3"; + shieldDiv.style.marginTop = "-5%"; + shieldDiv.style.display = "flex"; + shieldDiv.style.alignItems = "center"; + shieldDiv.style.gap = "0px"; + shieldDiv.innerHTML = ` + + 0 + `; + element.appendChild(shieldDiv); + // Start off invisible so it doesn't flash at 0,0 element.style.display = "none"; @@ -274,6 +291,24 @@ export class NameLayer implements Layer { troopsDiv.style.color = render.fontColor; troopsDiv.textContent = renderTroops(render.player.troops()); + const density = renderNumber( + render.player.troops() / render.player.numTilesOwned(), + ); + const shieldDiv = render.element.querySelector( + ".player-shield", + ) as HTMLDivElement; + const shieldImg = shieldDiv.querySelector("img"); + const shieldNumber = shieldDiv.querySelector("span"); + if (shieldImg) { + shieldImg.style.width = `${render.fontSize * 0.8}px`; + shieldImg.style.height = `${render.fontSize * 0.8}px`; + } + if (shieldNumber) { + shieldNumber.style.fontSize = `${render.fontSize * 0.6}px`; + shieldNumber.style.marginTop = `${-render.fontSize * 0.1}px`; + shieldNumber.textContent = density; + } + // Handle icons const iconsDiv = render.element.querySelector( ".player-icons", From 1f890396abb58139e4b2f5977fab40f4a4dd8228 Mon Sep 17 00:00:00 2001 From: evan Date: Wed, 23 Apr 2025 17:22:37 -0700 Subject: [PATCH 3/3] update ShellExecution to use AirPathFinder --- src/core/execution/ShellExecution.ts | 33 ++++++++++------------------ 1 file changed, 11 insertions(+), 22 deletions(-) diff --git a/src/core/execution/ShellExecution.ts b/src/core/execution/ShellExecution.ts index 4f0d306f7..0fc149e11 100644 --- a/src/core/execution/ShellExecution.ts +++ b/src/core/execution/ShellExecution.ts @@ -1,12 +1,11 @@ -import { consolex } from "../Consolex"; import { Execution, Game, Player, Unit, UnitType } from "../game/Game"; import { TileRef } from "../game/GameMap"; -import { PathFindResultType } from "../pathfinding/AStar"; -import { PathFinder } from "../pathfinding/PathFinding"; +import { AirPathFinder } from "../pathfinding/PathFinding"; +import { PseudoRandom } from "../PseudoRandom"; export class ShellExecution implements Execution { private active = true; - private pathFinder: PathFinder; + private pathFinder: AirPathFinder; private shell: Unit; private mg: Game; private destroyAtTick: number = -1; @@ -19,7 +18,7 @@ export class ShellExecution implements Execution { ) {} init(mg: Game, ticks: number): void { - this.pathFinder = PathFinder.Mini(mg, 2000, 10); + this.pathFinder = new AirPathFinder(mg, new PseudoRandom(mg.ticks())); this.mg = mg; } @@ -49,24 +48,14 @@ export class ShellExecution implements Execution { const result = this.pathFinder.nextTile( this.shell.tile(), this.target.tile(), - 3, ); - switch (result.type) { - case PathFindResultType.Completed: - this.active = false; - this.target.modifyHealth(-this.effectOnTarget()); - this.shell.delete(false); - return; - case PathFindResultType.NextTile: - this.shell.move(result.tile); - break; - case PathFindResultType.Pending: - return; - case PathFindResultType.PathNotFound: - consolex.log(`Shell ${this.shell} could not find target`); - this.active = false; - this.shell.delete(false); - return; + if (result === true) { + this.active = false; + this.target.modifyHealth(-this.effectOnTarget()); + this.shell.delete(false); + return; + } else { + this.shell.move(result); } } }