Fixed IADS creation and added livery/skill selection for units

This commit is contained in:
Davide Passoni 2024-11-14 17:23:16 +01:00
parent fa215142ad
commit c8e1f76b38
11 changed files with 278 additions and 200 deletions

View File

@ -68,28 +68,13 @@ export const ROEs: string[] = ["free", "designated", "", "return", "hold"];
export const reactionsToThreat: string[] = ["none", "manoeuvre", "passive", "evade"];
export const emissionsCountermeasures: string[] = ["silent", "attack", "defend", "free"];
export const ERAS = [
{
name: "Early Cold War",
chronologicalOrder: 2,
},
{
name: "Late Cold War",
chronologicalOrder: 4,
},
{
name: "Mid Cold War",
chronologicalOrder: 3,
},
{
name: "Modern",
chronologicalOrder: 5,
},
{
name: "WW2",
chronologicalOrder: 1,
},
];
export enum ERAS_ORDER {
"WW2",
"Early Cold War",
"Mid Cold War",
"Late Cold War",
"Modern"
};
export const ROEDescriptions: string[] = [
"Free (Attack anyone)",
@ -227,6 +212,14 @@ export const minimapBoundaries = {
new LatLng(34.312222, 36.897778),
new LatLng(34.312222, 28.523333),
],
Afghanistan: [
// Sinai
new LatLng(36.22, 61.21),
new LatLng(30.42, 61.21),
new LatLng(30.42, 68.05),
new LatLng(36.22, 68.05),
new LatLng(36.22, 61.21),
],
};
export const mapBounds = {
@ -259,6 +252,7 @@ export const mapBounds = {
bounds: new LatLngBounds([34.312222, 28.523333], [25.946944, 36.897778]),
zoom: 4,
},
Afghanistan: { bounds: new LatLngBounds([36.22, 61.21], [30.42, 68.05]), zoom: 5 },
};
export const defaultMapMirrors = {};
@ -277,7 +271,7 @@ export enum OlympusState {
OPTIONS = "Options",
AUDIO = "Audio",
AIRBASE = "Airbase",
GAME_MASTER = "Game master"
GAME_MASTER = "Game master",
}
export const NO_SUBSTATE = "No substate";
@ -308,12 +302,12 @@ export enum JTACSubState {
export enum SpawnSubState {
NO_SUBSTATE = "No substate",
SPAWN_UNIT = "Unit",
SPAWN_EFFECT = "Effect"
SPAWN_EFFECT = "Effect",
}
export enum OptionsSubstate {
NO_SUBSTATE = "No substate",
KEYBIND = "Keybind"
KEYBIND = "Keybind",
}
export type OlympusSubState = DrawSubState | JTACSubState | SpawnSubState | OptionsSubstate | string;
@ -341,7 +335,7 @@ export const MAP_OPTIONS_DEFAULTS: MapOptions = {
cameraPluginPort: 3003,
cameraPluginRatio: 1,
cameraPluginEnabled: false,
cameraPluginMode: 'map'
cameraPluginMode: "map",
};
export const MAP_HIDDEN_TYPES_DEFAULTS = {

View File

@ -380,7 +380,7 @@ export class MouseMovedEvent {
static dispatch(latlng: LatLng, elevation?: number) {
document.dispatchEvent(new CustomEvent(this.name, { detail: { latlng, elevation } }));
console.log(`Event ${this.name} dispatched`);
// Logging disabled since periodic
}
}
@ -463,6 +463,6 @@ export class BullseyesDataChanged {
static dispatch(bullseyes: { [name: string]: Bullseye } ) {
document.dispatchEvent(new CustomEvent(this.name, { detail: { bullseyes } }));
console.log(`Event ${this.name} dispatched`);
// Logging disabled since periodic
}
}

View File

@ -99,6 +99,7 @@ export interface SpawnRequestTable {
category: string;
coalition: string;
unit: UnitSpawnTable;
amount: number;
quickAccessName?: string
}

View File

@ -44,7 +44,7 @@ export class CoalitionPolygon extends Polygon {
});
this.on("remove", () => {
this.#label.removeFrom(this._map);
this.#label?.removeFrom(this._map);
});
}

View File

@ -1048,7 +1048,7 @@ export class Map extends L.Map {
.getUnitsManager()
.spawnUnits(
this.#spawnRequestTable.category,
[this.#spawnRequestTable.unit],
Array(this.#spawnRequestTable.amount).fill(this.#spawnRequestTable.unit),
this.#spawnRequestTable.coalition,
false,
undefined,

View File

@ -1,4 +1,4 @@
{
export const countryCodes = {
"AGGRESSORS": {
"flagCode": "RED",
"liveryCodes": ["RSO"]
@ -250,7 +250,7 @@
"SOUTH_AFRICA": {
"displayName": "South Africa",
"flagCode": "ZA",
"liveryCodes": []
"liveryCodes": null
},
"SPAIN": {
"flagCode": "ES",
@ -323,7 +323,7 @@
"SOUTH_OSETIA": {
"displayName": "South Ossetia",
"flagCode": "UNK",
"liveryCodes": []
"liveryCodes": null
},
"NORTH_KOREA": {
"displayName": "Democratic People's Republic of Korea",
@ -347,7 +347,7 @@
"USSR": {
"displayName": "USSR",
"flagCode": "USSR",
"liveryCodes": []
"liveryCodes": null
},
"ECUADOR": {
"flagCode": "EC",
@ -373,6 +373,6 @@
"THIRDREICH": {
"displayName": "Third Reich",
"flagCode": "THIRD",
"liveryCodes": []
"liveryCodes": null
}
}

View File

@ -12,7 +12,7 @@ import { OlCheckbox } from "../components/olcheckbox";
import { Coalition } from "../../types/types";
import { OlRangeSlider } from "../components/olrangeslider";
import { CoalitionCircle } from "../../map/coalitionarea/coalitioncircle";
import { DrawSubState, NO_SUBSTATE, OlympusState, OlympusSubState } from "../../constants/constants";
import { DrawSubState, ERAS_ORDER, IADSTypes, NO_SUBSTATE, OlympusState, OlympusSubState } from "../../constants/constants";
import { AppStateChangedEvent, CoalitionAreaSelectedEvent } from "../../events";
import { UnitBlueprint } from "../../interfaces";
@ -37,20 +37,8 @@ export function DrawingMenu(props: { open: boolean; onClose: () => void }) {
}, []);
/* Get all the unique types and eras for groundunits */
/* TODO move in effect */
const blueprints = getApp()?.getUnitsManager().getDatabase().getBlueprints();
let types: string[] = [];
let eras: string[] = [];
if (blueprints) {
types = blueprints
.filter((blueprint) => blueprint.category === "groundunit")
.map((blueprint) => blueprint.type)
.filter((type) => type !== undefined);
eras = blueprints
.filter((blueprint) => blueprint.category === "groundunit")
.map((blueprint) => blueprint.era)
.filter((era) => era !== undefined);
}
let types = IADSTypes;
let eras = getApp()?.getUnitsManager().getDatabase().getEras().sort((era1, era2) => ERAS_ORDER[era1] > ERAS_ORDER[era2] ? 1: -1 );
useEffect(() => {
if (getApp()) {
@ -105,7 +93,7 @@ export function DrawingMenu(props: { open: boolean; onClose: () => void }) {
tooltip={"Add a new circle"}
checked={appSubState === DrawSubState.DRAW_CIRCLE}
onClick={() => {
if (appSubState === DrawSubState.DRAW_CIRCLE) getApp().setState(OlympusState.DRAW, DrawSubState.EDIT);
if (appSubState === DrawSubState.DRAW_CIRCLE) getApp().setState(OlympusState.DRAW);
else getApp().setState(OlympusState.DRAW, DrawSubState.DRAW_CIRCLE);
}}
>

View File

@ -1,13 +1,11 @@
import React, { useEffect, useState } from "react";
import { Menu } from "./components/menu";
import { OlCheckbox } from "../components/olcheckbox";
import { OlRangeSlider } from "../components/olrangeslider";
import { OlNumberInput } from "../components/olnumberinput";
import { MapOptions } from "../../types/types";
import { getApp } from "../../olympusapp";
import { CommandModeOptions, ServerStatus } from "../../interfaces";
import { ServerStatus } from "../../interfaces";
import { CommandModeOptionsChangedEvent, ServerStatusUpdatedEvent } from "../../events";
import { BLUE_COMMANDER, COMMAND_MODE_OPTIONS_DEFAULTS, ERAS, GAME_MASTER, RED_COMMANDER } from "../../constants/constants";
import { BLUE_COMMANDER, COMMAND_MODE_OPTIONS_DEFAULTS, ERAS_ORDER, GAME_MASTER, RED_COMMANDER } from "../../constants/constants";
export function GameMasterMenu(props: { open: boolean; onClose: () => void; children?: JSX.Element | JSX.Element[] }) {
const [commandModeOptions, setCommandModeOptions] = useState(COMMAND_MODE_OPTIONS_DEFAULTS);
@ -40,12 +38,20 @@ export function GameMasterMenu(props: { open: boolean; onClose: () => void; chil
GAME MASTER
</div>
)}
{commandModeOptions.commandMode === BLUE_COMMANDER && <div className={`
w-full rounded-md bg-blue-600 p-2 text-center font-bold
`}>BLUE COMMANDER</div>}
{commandModeOptions.commandMode === RED_COMMANDER && <div className={`
w-full rounded-md bg-red-700 p-2 text-center font-bold
`}>RED COMMANDER</div>}
{commandModeOptions.commandMode === BLUE_COMMANDER && (
<div
className={`w-full rounded-md bg-blue-600 p-2 text-center font-bold`}
>
BLUE COMMANDER
</div>
)}
{commandModeOptions.commandMode === RED_COMMANDER && (
<div
className={`w-full rounded-md bg-red-700 p-2 text-center font-bold`}
>
RED COMMANDER
</div>
)}
{serverStatus.elapsedTime > currentSetupTime && (
<div
className={`
@ -112,36 +118,40 @@ export function GameMasterMenu(props: { open: boolean; onClose: () => void; chil
Restrict spawns to coalition
</span>
</div>
{ERAS.sort((a, b) => (a.chronologicalOrder > b.chronologicalOrder ? 1 : -1)).map((era) => {
return (
<div
className={`
group flex flex-row rounded-md justify-content cursor-pointer
gap-4 p-2
dark:hover:bg-olympus-400
`}
onClick={() => {
if (!commandModeOptions.restrictSpawns || commandModeOptions.commandMode !== GAME_MASTER) return;
const newCommandModeOptions = { ...commandModeOptions };
if (commandModeOptions.eras.includes(era.name)) newCommandModeOptions.eras.splice(newCommandModeOptions.eras.indexOf(era.name));
else newCommandModeOptions.eras.push(era.name);
setCommandModeOptions(newCommandModeOptions);
}}
>
<OlCheckbox
checked={commandModeOptions.eras.includes(era.name)}
onChange={() => {}}
disabled={!commandModeOptions.restrictSpawns || commandModeOptions.commandMode !== GAME_MASTER}
/>
<span
data-disabled={!commandModeOptions.restrictSpawns || commandModeOptions.commandMode !== GAME_MASTER}
className={`data-[disabled='true']:text-gray-400`}
{Object.keys(ERAS_ORDER)
.filter((item) => {
return isNaN(Number(item));
})
.map((era) => {
return (
<div
className={`
group flex flex-row rounded-md justify-content
cursor-pointer gap-4 p-2
dark:hover:bg-olympus-400
`}
onClick={() => {
if (!commandModeOptions.restrictSpawns || commandModeOptions.commandMode !== GAME_MASTER) return;
const newCommandModeOptions = { ...commandModeOptions };
if (commandModeOptions.eras.includes(era)) newCommandModeOptions.eras.splice(newCommandModeOptions.eras.indexOf(era));
else newCommandModeOptions.eras.push(era);
setCommandModeOptions(newCommandModeOptions);
}}
>
Allow {era.name} units
</span>
</div>
);
})}
<OlCheckbox
checked={commandModeOptions.eras.includes(era)}
onChange={() => {}}
disabled={!commandModeOptions.restrictSpawns || commandModeOptions.commandMode !== GAME_MASTER}
/>
<span
data-disabled={!commandModeOptions.restrictSpawns || commandModeOptions.commandMode !== GAME_MASTER}
className={`data-[disabled='true']:text-gray-400`}
>
Allow {era} units
</span>
</div>
);
})}
<div
className={`
@ -264,12 +274,9 @@ export function GameMasterMenu(props: { open: boolean; onClose: () => void; chil
group flex flex-row rounded-md justify-content gap-4 px-4 py-2
`}
>
<span className="mr-auto">Elapsed time (seconds)</span>{" "}
<span
className={`w-32 text-center`}
>
{serverStatus.elapsedTime?.toFixed()}
</span>
<span className="mr-auto">Elapsed time (seconds)</span> <span className={`
w-32 text-center
`}>{serverStatus.elapsedTime?.toFixed()}</span>
</div>
{commandModeOptions.commandMode === GAME_MASTER && (
<button

View File

@ -53,14 +53,12 @@ export function MiniMapPanel(props: {}) {
return (
<div
onClick={() => setShowMissionTime(!showMissionTime)}
className={`
absolute right-[10px]
${mapOptions.showMinimap ? `bottom-[188px]` : `bottom-[20px]`}
flex w-[288px] items-center justify-between
${mapOptions.showMinimap ? `rounded-t-lg` : `rounded-lg`}
cursor-pointer bg-gray-200 p-3 text-sm backdrop-blur-lg
backdrop-grayscale
bg-gray-200 p-3 text-sm backdrop-blur-lg backdrop-grayscale
dark:bg-olympus-800/90 dark:text-gray-200
`}
>
@ -88,16 +86,16 @@ export function MiniMapPanel(props: {}) {
{serverStatus.load}
</span>
</div>
<div className="flex gap-2 font-semibold">
<div className="flex cursor-pointer gap-2 font-semibold" onClick={() => setShowMissionTime(!showMissionTime)}>
{showMissionTime ? "MT" : "ET"}: {timeString}
</div>
<div className={`relative h-4 w-4 rounded-full bg-[#8BFF63]`}></div>
</>
)}
{mapOptions.showMinimap ? (
<FaChevronDown onClick={() => getApp().getMap().setOption("showMinimap", false)} />
<FaChevronDown className="cursor-pointer" onClick={() => getApp().getMap().setOption("showMinimap", false)} />
) : (
<FaChevronUp onClick={() => getApp().getMap().setOption("showMinimap", true)} />
<FaChevronUp className="cursor-pointer" onClick={() => getApp().getMap().setOption("showMinimap", true)} />
)}
</div>
);

View File

@ -15,8 +15,16 @@ import { Airbase } from "../../mission/airbase";
import { altitudeIncrements, groupUnitCount, maxAltitudeValues, minAltitudeValues, OlympusState, SpawnSubState } from "../../constants/constants";
import { faStar } from "@fortawesome/free-solid-svg-icons";
import { OlStringInput } from "../components/olstringinput";
import { countryCodes } from "../data/codes";
import { OlAccordion } from "../components/olaccordion";
export function UnitSpawnMenu(props: { starredSpawns: { [key: string]: SpawnRequestTable }, blueprint: UnitBlueprint; spawnAtLocation: boolean; airbase?: Airbase | null; coalition?: Coalition }) {
export function UnitSpawnMenu(props: {
starredSpawns: { [key: string]: SpawnRequestTable };
blueprint: UnitBlueprint;
spawnAtLocation: boolean;
airbase?: Airbase | null;
coalition?: Coalition;
}) {
/* Compute the min and max values depending on the unit type */
const minNumber = 1;
const maxNumber = groupUnitCount[props.blueprint.category];
@ -31,7 +39,10 @@ export function UnitSpawnMenu(props: { starredSpawns: { [key: string]: SpawnRequ
const [spawnLoadoutName, setSpawnLoadout] = useState("");
const [spawnAltitude, setSpawnAltitude] = useState((maxAltitude - minAltitude) / 2);
const [spawnAltitudeType, setSpawnAltitudeType] = useState(false);
const [spawnLiveryID, setSpawnLiveryID] = useState("");
const [spawnSkill, setSpawnSkill] = useState("High");
const [showLoadout, setShowLoadout] = useState(false);
const [quickAccessName, setQuickAccessName] = useState("No name");
const [key, setKey] = useState("");
const [spawnRequestTable, setSpawnRequestTable] = useState(null as null | SpawnRequestTable);
@ -61,8 +72,8 @@ export function UnitSpawnMenu(props: { starredSpawns: { [key: string]: SpawnRequ
if (key in props.starredSpawns && props.starredSpawns[key].quickAccessName) setQuickAccessName(props.starredSpawns[key].quickAccessName);
else setQuickAccessName("No name");
}
}, [props.starredSpawns, key])
useEffect(updateQuickAccessName, [key])
}, [props.starredSpawns, key]);
useEffect(updateQuickAccessName, [key]);
/* Callback and effect to update the spawn request table */
const updateSpawnRequestTable = useCallback(() => {
@ -72,16 +83,17 @@ export function UnitSpawnMenu(props: { starredSpawns: { [key: string]: SpawnRequ
unit: {
unitType: props.blueprint.name,
location: new LatLng(0, 0), // This will be filled when the user clicks on the map to spawn the unit
skill: "High",
liveryID: "",
skill: spawnSkill,
liveryID: spawnLiveryID,
altitude: ftToM(spawnAltitude),
loadout: props.blueprint.loadouts?.find((loadout) => loadout.name === spawnLoadoutName)?.code ?? "",
},
amount: spawnNumber,
coalition: spawnCoalition,
});
}
}, [props.blueprint, spawnAltitude, spawnLoadoutName, spawnCoalition]);
useEffect(updateSpawnRequestTable, [props.blueprint, spawnAltitude, spawnLoadoutName, spawnCoalition]);
}, [props.blueprint, spawnAltitude, spawnLoadoutName, spawnCoalition, spawnNumber, spawnLiveryID, spawnSkill]);
useEffect(updateSpawnRequestTable, [props.blueprint, spawnAltitude, spawnLoadoutName, spawnCoalition, spawnNumber, spawnLiveryID, spawnSkill]);
/* Effect to update the coalition if it is force externally */
useEffect(() => {
@ -115,6 +127,30 @@ export function UnitSpawnMenu(props: { starredSpawns: { [key: string]: SpawnRequ
<div className="flex flex-col">
<OlUnitSummary blueprint={props.blueprint} coalition={spawnCoalition} />
<div className="flex h-fit flex-col gap-5 px-5 pb-8 pt-6">
<div
className={`
inline-flex w-full flex-row content-center justify-between gap-2
`}
>
<div className="my-auto text-sm text-white">Quick access: </div>
<OlStringInput
onChange={(e) => {
setQuickAccessName(e.target.value);
}}
value={quickAccessName}
/>
<OlStateButton
onClick={() => {
if (spawnRequestTable)
key in props.starredSpawns
? getApp().getMap().removeStarredSpawnRequestTable(key)
: getApp().getMap().addStarredSpawnRequestTable(key, spawnRequestTable);
}}
tooltip="Save this spawn for quick access"
checked={key in props.starredSpawns}
icon={faStar}
></OlStateButton>
</div>
<div
className={`
inline-flex w-full flex-row content-center justify-between gap-2
@ -146,43 +182,7 @@ export function UnitSpawnMenu(props: { starredSpawns: { [key: string]: SpawnRequ
}}
/>
</div>
<div
className={`
inline-flex w-full flex-row content-center justify-between gap-2
`}
>
<div className="my-auto text-sm text-white">Quick access: </div>
<OlStringInput
onChange={(e) => {
setQuickAccessName(e.target.value);
}}
value={quickAccessName}
/>
<OlStateButton
onClick={() => {
key in props.starredSpawns
? getApp().getMap().removeStarredSpawnRequestTable(key)
: getApp()
.getMap()
.addStarredSpawnRequestTable(key, {
category: props.blueprint.category,
unit: {
unitType: props.blueprint.name,
location: new LatLng(0, 0), // This will be filled when the user clicks on the map to spawn the unit
skill: "High",
liveryID: "",
altitude: ftToM(spawnAltitude),
loadout: props.blueprint.loadouts?.find((loadout) => loadout.name === spawnLoadoutName)?.code ?? "",
},
coalition: spawnCoalition,
quickAccessName: quickAccessName,
});
}}
tooltip="Save this spawn for quick access"
checked={key in props.starredSpawns}
icon={faStar}
></OlStateButton>
</div>
{["aircraft", "helicopter"].includes(props.blueprint.category) && (
<>
{!props.airbase && (
@ -219,18 +219,16 @@ export function UnitSpawnMenu(props: { starredSpawns: { [key: string]: SpawnRequ
/>
</div>
)}
<div>
<div className="flex flex-row content-center justify-between">
<span
className={`
h-8 font-normal
dark:text-white
`}
>
Role
</span>
</div>
<OlDropdown label={spawnRole} className="w-full">
<div className="flex content-center justify-between gap-2">
<span
className={`
my-auto font-normal
dark:text-white
`}
>
Role
</span>
<OlDropdown label={spawnRole} className="w-64">
{roles.map((role) => {
return (
<OlDropdownItem
@ -246,18 +244,16 @@ export function UnitSpawnMenu(props: { starredSpawns: { [key: string]: SpawnRequ
})}
</OlDropdown>
</div>
<div>
<div className="flex flex-row content-center justify-between">
<span
className={`
h-8 font-normal
dark:text-white
`}
>
Weapons
</span>
</div>
<OlDropdown label={spawnLoadoutName} className={`w-full w-max-full`}>
<div className="flex content-center justify-between gap-2">
<span
className={`
my-auto font-normal
dark:text-white
`}
>
Weapons
</span>
<OlDropdown label={spawnLoadoutName} className={`w-64`}>
{loadouts.map((loadout) => {
return (
<OlDropdownItem
@ -281,37 +277,135 @@ export function UnitSpawnMenu(props: { starredSpawns: { [key: string]: SpawnRequ
</div>
</>
)}
<div className="flex content-center justify-between gap-2">
<span
className={`
my-auto font-normal
dark:text-white
`}
>
Livery
</span>
<OlDropdown
label={props.blueprint.liveries ? (props.blueprint.liveries[spawnLiveryID]?.name ?? "Default") : "No livery"}
className={`w-64`}
>
{props.blueprint.liveries &&
Object.keys(props.blueprint.liveries)
.sort((ida, idb) => {
if (props.blueprint.liveries) {
if (props.blueprint.liveries[ida].countries.length > 1) return 1;
return props.blueprint.liveries[ida].countries[0] > props.blueprint.liveries[idb].countries[0] ? 1 : -1;
} else return -1;
})
.map((id) => {
let country = Object.values(countryCodes).find((countryCode) => {
if (props.blueprint.liveries && countryCode.liveryCodes?.includes(props.blueprint.liveries[id].countries[0])) return true;
});
return (
<OlDropdownItem
onClick={() => {
setSpawnLiveryID(id);
}}
className={`w-full`}
>
<span
className={`
w-full content-center overflow-hidden text-ellipsis
text-nowrap text-left w-max-full flex gap-2
`}
>
{props.blueprint.liveries && props.blueprint.liveries[id].countries.length == 1 && (
<img src={`images/countries/${country?.flagCode.toLowerCase()}.svg`} className={`
h-6
`} />
)}
<div className="my-auto truncate">
<span
className={`
w-full overflow-hidden text-left w-max-full
`}
>
{props.blueprint.liveries ? props.blueprint.liveries[id].name : ""}
</span>
</div>
</span>
</OlDropdownItem>
);
})}
</OlDropdown>
</div>
<div className="flex content-center justify-between gap-2">
<span
className={`
my-auto font-normal
dark:text-white
`}
>
Skill
</span>
<OlDropdown label={spawnSkill} className={`w-64`}>
{["Average", "Good", "High", "Excellent"].map((skill) => {
return (
<OlDropdownItem
onClick={() => {
setSpawnSkill(skill);
}}
className={`w-full`}
>
<span
className={`
w-full content-center overflow-hidden text-ellipsis
text-nowrap text-left w-max-full flex gap-2
`}
>
<div className="my-auto">{skill}</div>
</span>
</OlDropdownItem>
);
})}
</OlDropdown>
</div>
</div>
{spawnLoadout && spawnLoadout.items.length > 0 && (
<div
className={`
flex h-fit flex-col gap-1 p-4
flex h-fit flex-col gap-1 px-4 py-2
dark:bg-olympus-200/30
`}
>
{spawnLoadout.items.map((item) => {
return (
<div className="flex content-center gap-2">
<div
className={`
my-auto w-6 min-w-6 rounded-full py-0.5 text-center text-sm
font-bold text-gray-500
dark:bg-[#17212D]
`}
>
{item.quantity}
<OlAccordion
onClick={() => {
setShowLoadout(!showLoadout);
}}
open={showLoadout}
title="Loadout"
>
{spawnLoadout.items.map((item) => {
return (
<div className="flex content-center gap-2">
<div
className={`
my-auto w-6 min-w-6 rounded-full py-0.5 text-center
text-sm font-bold text-gray-500
dark:bg-[#17212D]
`}
>
{item.quantity}
</div>
<div
className={`
my-auto overflow-hidden text-ellipsis text-nowrap text-sm
dark:text-gray-300
`}
>
{item.name}
</div>
</div>
<div
className={`
my-auto overflow-hidden text-ellipsis text-nowrap text-sm
dark:text-gray-300
`}
>
{item.name}
</div>
</div>
);
})}
);
})}
</OlAccordion>
</div>
)}
{!props.spawnAtLocation && (

View File

@ -6,7 +6,6 @@ import {
bearingAndDistanceToLatLng,
deg2rad,
getGroundElevation,
keyEventWasInInput,
latLngToMercator,
mToFt,
mercatorToLatLng,
@ -17,10 +16,7 @@ import { DELETE_CYCLE_TIME, DELETE_SLOW_THRESHOLD, DataIndexes, GAME_MASTER, IAD
import { DataExtractor } from "../server/dataextractor";
import { citiesDatabase } from "./databases/citiesdatabase";
import { TemporaryUnitMarker } from "../map/markers/temporaryunitmarker";
//import { Popup } from "../popups/popup";
//import { HotgroupPanel } from "../panels/hotgrouppanel";
import { Contact, UnitBlueprint, UnitData, UnitSpawnTable } from "../interfaces";
//import { Dialog } from "../dialog/dialog";
import { Group } from "./group";
import { UnitDataFileExport } from "./importexport/unitdatafileexport";
import { UnitDataFileImport } from "./importexport/unitdatafileimport";
@ -1357,7 +1353,7 @@ export class UnitsManager {
if (unitBlueprint)
this.spawnUnits(
"GroundUnit",
unitBlueprint.category,
[
{
unitType: unitBlueprint.name,
@ -1410,7 +1406,7 @@ export class UnitsManager {
if (unitBlueprint)
this.spawnUnits(
"GroundUnit",
unitBlueprint.category,
[
{
unitType: unitBlueprint.name,