feat: added unit ranges on spawn menu

This commit is contained in:
Davide Passoni 2025-03-31 15:36:38 +02:00
parent c034c19176
commit de495cc71d
3 changed files with 76 additions and 8 deletions

View File

@ -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;
}
}

View File

@ -85,7 +85,7 @@ export function OlUnitSummary(props: { blueprint: UnitBlueprint; coalition: Coal
<div className="flex flex-row gap-1 px-2">
{props.blueprint.abilities?.split(" ").map((ability) => {
return (
<>
<div key={ability}>
{ability.replaceAll(" ", "") !== "" && (
<div
key={ability}
@ -97,7 +97,7 @@ export function OlUnitSummary(props: { blueprint: UnitBlueprint; coalition: Coal
{ability}
</div>
)}
</>
</div>
);
})}

View File

@ -346,6 +346,7 @@ export function UnitSpawnMenu(props: {
setSpawnLoadoutName("");
}}
className={`w-full`}
key={role}
>
{role}
</OlDropdownItem>
@ -380,6 +381,7 @@ export function UnitSpawnMenu(props: {
setSpawnLoadoutName(loadout.name);
}}
className={`w-full`}
key={loadout.name}
>
<span
className={`
@ -439,6 +441,7 @@ export function UnitSpawnMenu(props: {
setSpawnLiveryID(id);
}}
className={`w-full`}
key={id}
>
<span
className={`
@ -497,6 +500,7 @@ export function UnitSpawnMenu(props: {
setSpawnSkill(skill);
}}
className={`w-full`}
key={skill}
>
<span
className={`
@ -584,9 +588,9 @@ export function UnitSpawnMenu(props: {
open={openAccordion === OpenAccordion.LOADOUT}
title="Loadout"
>
{spawnLoadout.items.map((item) => {
{spawnLoadout.items.map((item, idx) => {
return (
<div className="flex content-center gap-2">
<div className="flex content-center gap-2" key={idx}>
<div
className={`
my-auto w-6 min-w-6 rounded-full py-0.5 text-center