From de495cc71da249d759ee37de2f50223b9a0127f8 Mon Sep 17 00:00:00 2001 From: Davide Passoni Date: Mon, 31 Mar 2025 15:36:38 +0200 Subject: [PATCH] feat: added unit ranges on spawn menu --- .../src/map/markers/temporaryunitmarker.ts | 72 +++++++++++++++++-- .../react/src/ui/components/olunitsummary.tsx | 4 +- .../react/src/ui/panels/unitspawnmenu.tsx | 8 ++- 3 files changed, 76 insertions(+), 8 deletions(-) diff --git a/frontend/react/src/map/markers/temporaryunitmarker.ts b/frontend/react/src/map/markers/temporaryunitmarker.ts index 7d093645..a56ea45b 100644 --- a/frontend/react/src/map/markers/temporaryunitmarker.ts +++ b/frontend/react/src/map/markers/temporaryunitmarker.ts @@ -2,9 +2,11 @@ import { CustomMarker } from "./custommarker"; import { DivIcon, LatLng } from "leaflet"; import { SVGInjector } from "@tanem/svg-injector"; import { getApp } from "../../olympusapp"; -import { UnitBlueprint } from "../../interfaces"; -import { deg2rad, normalizeAngle, rad2deg } from "../../other/utils"; +import { adjustBrightness, normalizeAngle, rad2deg } from "../../other/utils"; import { SpawnHeadingChangedEvent } from "../../events"; +import { RangeCircle } from "../rangecircle"; +import { Map } from "../map"; +import { colors } from "../../constants/constants"; export class TemporaryUnitMarker extends CustomMarker { #name: string; @@ -12,6 +14,8 @@ export class TemporaryUnitMarker extends CustomMarker { #commandHash: string | undefined = undefined; #timer: number = 0; #headingHandle: boolean; + #acquisitionCircle: RangeCircle | undefined = undefined; + #engagementCircle: RangeCircle | undefined = undefined; constructor(latlng: LatLng, name: string, coalition: string, headingHandle: boolean, commandHash?: string) { super(latlng, { interactive: false }); @@ -51,6 +55,58 @@ export class TemporaryUnitMarker extends CustomMarker { }); this.setIcon(icon); + if (blueprint.acquisitionRange) { + this.#acquisitionCircle = new RangeCircle(this.getLatLng(), { + radius: blueprint.acquisitionRange, + weight: 2, + opacity: 1, + fillOpacity: 0, + dashArray: "8 12", + interactive: false, + bubblingMouseEvents: false, + }); + + switch (this.#coalition) { + case "red": + this.#acquisitionCircle.options.color = adjustBrightness(colors.RED_COALITION, -20); + break; + case "blue": + this.#acquisitionCircle.options.color = adjustBrightness(colors.BLUE_COALITION, -20); + break; + default: + this.#acquisitionCircle.options.color = adjustBrightness(colors.NEUTRAL_COALITION, -20); + break; + } + + getApp().getMap().addLayer(this.#acquisitionCircle); + } + + if (blueprint.engagementRange) { + this.#engagementCircle = new RangeCircle(this.getLatLng(), { + radius: blueprint.engagementRange, + weight: 4, + opacity: 1, + fillOpacity: 0, + dashArray: "4 8", + interactive: false, + bubblingMouseEvents: false, + }); + + switch (this.#coalition) { + case "red": + this.#engagementCircle.options.color = colors.RED_COALITION; + break; + case "blue": + this.#engagementCircle.options.color = colors.BLUE_COALITION + break; + default: + this.#engagementCircle.options.color = colors.NEUTRAL_COALITION; + break; + } + + getApp().getMap().addLayer(this.#engagementCircle); + } + var el = document.createElement("div"); el.classList.add("unit"); el.setAttribute("data-object", `unit-${blueprint.category}`); @@ -89,8 +145,7 @@ export class TemporaryUnitMarker extends CustomMarker { const rotateHandle = (heading) => { el.style.transform = `rotate(${heading}deg)`; unitIcon.style.transform = `rotate(-${heading}deg)`; - if (shortLabel) - shortLabel.style.transform = `rotate(-${heading}deg)`; + if (shortLabel) shortLabel.style.transform = `rotate(-${heading}deg)`; }; SpawnHeadingChangedEvent.on((heading) => rotateHandle(heading)); @@ -124,4 +179,13 @@ export class TemporaryUnitMarker extends CustomMarker { this.getElement()?.classList.add("ol-temporary-marker"); } } + + onRemove(map: Map): this { + super.onRemove(map); + + if (this.#acquisitionCircle) map.removeLayer(this.#acquisitionCircle); + if (this.#engagementCircle) map.removeLayer(this.#engagementCircle); + + return this; + } } diff --git a/frontend/react/src/ui/components/olunitsummary.tsx b/frontend/react/src/ui/components/olunitsummary.tsx index e597c984..04ea6f6e 100644 --- a/frontend/react/src/ui/components/olunitsummary.tsx +++ b/frontend/react/src/ui/components/olunitsummary.tsx @@ -85,7 +85,7 @@ export function OlUnitSummary(props: { blueprint: UnitBlueprint; coalition: Coal
{props.blueprint.abilities?.split(" ").map((ability) => { return ( - <> +
{ability.replaceAll(" ", "") !== "" && (
)} - +
); })} diff --git a/frontend/react/src/ui/panels/unitspawnmenu.tsx b/frontend/react/src/ui/panels/unitspawnmenu.tsx index 34ff937d..ec9b8ba1 100644 --- a/frontend/react/src/ui/panels/unitspawnmenu.tsx +++ b/frontend/react/src/ui/panels/unitspawnmenu.tsx @@ -346,6 +346,7 @@ export function UnitSpawnMenu(props: { setSpawnLoadoutName(""); }} className={`w-full`} + key={role} > {role} @@ -380,6 +381,7 @@ export function UnitSpawnMenu(props: { setSpawnLoadoutName(loadout.name); }} className={`w-full`} + key={loadout.name} > - {spawnLoadout.items.map((item) => { + {spawnLoadout.items.map((item, idx) => { return ( -
+