mirror of
https://github.com/Pax1601/DCSOlympus.git
synced 2025-10-29 16:56:34 +00:00
feat: Created coalitionareamanager, fixed areas creation and management
This commit is contained in:
@@ -1,9 +1,8 @@
|
||||
import React, { useCallback, useEffect, useState } from "react";
|
||||
import { faFighterJet, faHandPointer, faJetFighter, faMap, IconDefinition } from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { MAP_OPTIONS_DEFAULTS, NO_SUBSTATE, OlympusState, OlympusSubState, SpawnSubState } from "../../constants/constants";
|
||||
import { DrawSubState, MAP_OPTIONS_DEFAULTS, NO_SUBSTATE, OlympusState, OlympusSubState, SpawnSubState } from "../../constants/constants";
|
||||
import { AppStateChangedEvent, ContextActionSetChangedEvent, MapOptionsChangedEvent, ShortcutsChangedEvent } from "../../events";
|
||||
import { ContextAction } from "../../unit/contextaction";
|
||||
import { ContextActionSet } from "../../unit/contextactionset";
|
||||
import { MapToolBar } from "./maptoolbar";
|
||||
|
||||
@@ -23,6 +22,8 @@ export function ControlsPanel(props: {}) {
|
||||
const [shortcuts, setShortcuts] = useState({});
|
||||
const [contextActionSet, setContextActionSet] = useState(null as null | ContextActionSet);
|
||||
|
||||
// TODO change constant references of "Shift with actual keybind"
|
||||
|
||||
useEffect(() => {
|
||||
AppStateChangedEvent.on((state, subState) => {
|
||||
setAppState(state);
|
||||
@@ -100,7 +101,7 @@ export function ControlsPanel(props: {}) {
|
||||
} else if (appState === OlympusState.SPAWN) {
|
||||
controls = [
|
||||
{
|
||||
actions: [touch ? faHandPointer : "LMB", 2],
|
||||
actions: [touch ? faHandPointer : "LMB"],
|
||||
text: appSubState === SpawnSubState.NO_SUBSTATE ? "Close spawn menu" : "Return to spawn menu",
|
||||
},
|
||||
{
|
||||
@@ -123,6 +124,64 @@ export function ControlsPanel(props: {}) {
|
||||
text: "Spawn effect",
|
||||
});
|
||||
}
|
||||
} else if (appState === OlympusState.DRAW) {
|
||||
controls = [
|
||||
{
|
||||
actions: [touch ? faHandPointer : "LMB", "Drag"],
|
||||
text: "Move map location",
|
||||
},
|
||||
];
|
||||
|
||||
if (appSubState === DrawSubState.NO_SUBSTATE) {
|
||||
controls.unshift({
|
||||
actions: [touch ? faHandPointer : "LMB"],
|
||||
text: "Close draw menu",
|
||||
});
|
||||
controls.unshift({
|
||||
actions: [touch ? faHandPointer : "LMB"],
|
||||
text: "Select drawing",
|
||||
});
|
||||
}
|
||||
|
||||
if (appSubState === DrawSubState.DRAW_CIRCLE) {
|
||||
controls.unshift({
|
||||
actions: [touch ? faHandPointer : "LMB"],
|
||||
text: "Add new circle",
|
||||
});
|
||||
controls.unshift({
|
||||
actions: [touch ? faHandPointer : "LMB", "Drag"],
|
||||
text: "Drag circle",
|
||||
});
|
||||
}
|
||||
|
||||
if (appSubState === DrawSubState.DRAW_POLYGON) {
|
||||
controls.unshift({
|
||||
actions: [touch ? faHandPointer : "LMB"],
|
||||
text: "Add point to polygon",
|
||||
});
|
||||
controls.unshift({
|
||||
actions: [touch ? faHandPointer : "LMB", "Drag"],
|
||||
text: "Drag polygon",
|
||||
});
|
||||
}
|
||||
|
||||
if (appSubState === DrawSubState.EDIT) {
|
||||
controls.unshift({
|
||||
actions: [touch ? faHandPointer : "LMB"],
|
||||
text: "Add/drag point",
|
||||
});
|
||||
controls.unshift({
|
||||
actions: [touch ? faHandPointer : "LMB", "Drag"],
|
||||
text: "Drag drawing",
|
||||
});
|
||||
}
|
||||
|
||||
if (appSubState !== DrawSubState.NO_SUBSTATE) {
|
||||
controls.push({
|
||||
actions: [touch ? faHandPointer : "LMB"],
|
||||
text: "Deselect drawing",
|
||||
});
|
||||
}
|
||||
} else {
|
||||
controls = baseControls;
|
||||
controls.push({
|
||||
@@ -167,14 +226,9 @@ export function ControlsPanel(props: {}) {
|
||||
return (
|
||||
<div key={idx} className="flex gap-1">
|
||||
<div>
|
||||
{typeof action === "string" || typeof action === "number" ? (
|
||||
action
|
||||
) : (
|
||||
<FontAwesomeIcon
|
||||
icon={action}
|
||||
className={`my-auto ml-auto`}
|
||||
/>
|
||||
)}
|
||||
{typeof action === "string" || typeof action === "number" ? action : <FontAwesomeIcon icon={action} className={`
|
||||
my-auto ml-auto
|
||||
`} />}
|
||||
</div>
|
||||
{idx < control.actions.length - 1 && typeof control.actions[idx + 1] === "string" && <div>+</div>}
|
||||
{idx < control.actions.length - 1 && typeof control.actions[idx + 1] === "number" && <div>x</div>}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { Menu } from "./components/menu";
|
||||
import { FaTrash } from "react-icons/fa";
|
||||
import { FaArrowDown, FaArrowUp, FaTrash } from "react-icons/fa";
|
||||
import { getApp } from "../../olympusapp";
|
||||
import { OlStateButton } from "../components/olstatebutton";
|
||||
import { faDrawPolygon } from "@fortawesome/free-solid-svg-icons";
|
||||
@@ -13,14 +13,14 @@ import { Coalition } from "../../types/types";
|
||||
import { OlRangeSlider } from "../components/olrangeslider";
|
||||
import { CoalitionCircle } from "../../map/coalitionarea/coalitioncircle";
|
||||
import { DrawSubState, ERAS_ORDER, IADSTypes, NO_SUBSTATE, OlympusState, OlympusSubState } from "../../constants/constants";
|
||||
import { AppStateChangedEvent, CoalitionAreaSelectedEvent } from "../../events";
|
||||
import { UnitBlueprint } from "../../interfaces";
|
||||
import { AppStateChangedEvent, CoalitionAreasChangedEvent, CoalitionAreaSelectedEvent } from "../../events";
|
||||
import { FaXmark } from "react-icons/fa6";
|
||||
|
||||
export function DrawingMenu(props: { open: boolean; onClose: () => void }) {
|
||||
const [appState, setAppState] = useState(OlympusState.NOT_INITIALIZED);
|
||||
const [appSubState, setAppSubState] = useState(NO_SUBSTATE as OlympusSubState);
|
||||
const [activeCoalitionArea, setActiveCoalitionArea] = useState(null as null | CoalitionPolygon | CoalitionCircle);
|
||||
const [areaCoalition, setAreaCoalition] = useState("blue" as Coalition);
|
||||
const [coalitionAreas, setCoalitionAreas] = useState([] as (CoalitionPolygon | CoalitionCircle)[]);
|
||||
const [IADSDensity, setIADSDensity] = useState(50);
|
||||
const [IADSDistribution, setIADSDistribution] = useState(50);
|
||||
const [forceCoalitionAppropriateUnits, setForceCoalitionApproriateUnits] = useState(false);
|
||||
@@ -38,27 +38,15 @@ export function DrawingMenu(props: { open: boolean; onClose: () => void }) {
|
||||
|
||||
/* Get all the unique types and eras for groundunits */
|
||||
let types = IADSTypes;
|
||||
let eras = getApp()?.getUnitsManager().getDatabase().getEras().sort((era1, era2) => ERAS_ORDER[era1] > ERAS_ORDER[era2] ? 1: -1 );
|
||||
|
||||
useEffect(() => {
|
||||
if (getApp()) {
|
||||
// TODO
|
||||
///* If we are not in polygon drawing mode, force the draw polygon button off */
|
||||
//if (drawingPolygon && getApp().getState() !== COALITIONAREA_DRAW_POLYGON) setDrawingPolygon(false);
|
||||
//
|
||||
///* If we are not in circle drawing mode, force the draw circle button off */
|
||||
//if (drawingCircle && getApp().getState() !== COALITIONAREA_DRAW_CIRCLE) setDrawingCircle(false);
|
||||
//
|
||||
///* If we are not in any drawing mode, force the map in edit mode */
|
||||
//if (props.open && !drawingPolygon && !drawingCircle) getApp().getMap().setState(COALITIONAREA_EDIT);
|
||||
//
|
||||
///* Align the state of the coalition toggle to the coalition of the area */
|
||||
//if (activeCoalitionArea && activeCoalitionArea?.getCoalition() !== areaCoalition) setAreaCoalition(activeCoalitionArea?.getCoalition());
|
||||
}
|
||||
});
|
||||
let eras = getApp()
|
||||
?.getUnitsManager()
|
||||
.getDatabase()
|
||||
.getEras()
|
||||
.sort((era1, era2) => (ERAS_ORDER[era1] > ERAS_ORDER[era2] ? 1 : -1));
|
||||
|
||||
useEffect(() => {
|
||||
CoalitionAreaSelectedEvent.on((coalitionArea) => setActiveCoalitionArea(coalitionArea));
|
||||
CoalitionAreasChangedEvent.on((coalitionAreas) => setCoalitionAreas([...coalitionAreas]));
|
||||
}, []);
|
||||
|
||||
return (
|
||||
@@ -67,43 +55,87 @@ export function DrawingMenu(props: { open: boolean; onClose: () => void }) {
|
||||
title="Draw"
|
||||
onClose={props.onClose}
|
||||
canBeHidden={true}
|
||||
showBackButton={activeCoalitionArea !== null}
|
||||
showBackButton={appSubState !== DrawSubState.NO_SUBSTATE}
|
||||
onBack={() => {
|
||||
getApp().getCoalitionAreasManager().setSelectedArea(null);
|
||||
getApp().setState(OlympusState.DRAW, DrawSubState.NO_SUBSTATE);
|
||||
}}
|
||||
>
|
||||
<>
|
||||
{appState === OlympusState.DRAW && appSubState !== DrawSubState.EDIT && (
|
||||
<div className="flex flex-col gap-2 p-6 text-sm text-gray-400">
|
||||
<OlStateButton
|
||||
className="!w-full"
|
||||
icon={faDrawPolygon}
|
||||
tooltip={"Add a new polygon"}
|
||||
checked={appSubState === DrawSubState.DRAW_POLYGON}
|
||||
onClick={() => {
|
||||
if (appSubState === DrawSubState.DRAW_POLYGON) getApp().setState(OlympusState.DRAW, DrawSubState.EDIT);
|
||||
else getApp().setState(OlympusState.DRAW, DrawSubState.DRAW_POLYGON);
|
||||
}}
|
||||
>
|
||||
<div className="text-sm">Add polygon</div>
|
||||
</OlStateButton>
|
||||
<OlStateButton
|
||||
className="!w-full"
|
||||
icon={faCircle}
|
||||
tooltip={"Add a new circle"}
|
||||
checked={appSubState === DrawSubState.DRAW_CIRCLE}
|
||||
onClick={() => {
|
||||
if (appSubState === DrawSubState.DRAW_CIRCLE) getApp().setState(OlympusState.DRAW);
|
||||
else getApp().setState(OlympusState.DRAW, DrawSubState.DRAW_CIRCLE);
|
||||
}}
|
||||
>
|
||||
<div className="text-sm">Add circle</div>
|
||||
</OlStateButton>
|
||||
{appState === OlympusState.DRAW && appSubState === DrawSubState.NO_SUBSTATE && (
|
||||
<div className="flex flex-col gap-2 text-sm text-gray-400">
|
||||
<div className="flex flex-col bg-olympus-200/30">
|
||||
{coalitionAreas.map((coalitionArea) => {
|
||||
return (
|
||||
<div
|
||||
data-coalition={coalitionArea.getCoalition()}
|
||||
className={`
|
||||
flex cursor-pointer content-center border-l-4 px-4
|
||||
text-base text-white
|
||||
data-[coalition="blue"]:border-blue-500
|
||||
data-[coalition="neutral"]:border-gray-500
|
||||
data-[coalition="red"]:border-red-500
|
||||
hover:bg-white/10
|
||||
`}
|
||||
onClick={() => {
|
||||
coalitionArea.setSelected(true);
|
||||
getApp().setState(OlympusState.DRAW, DrawSubState.EDIT);
|
||||
}}
|
||||
>
|
||||
<div className="py-3">{coalitionArea.getLabelText()}</div>
|
||||
<FaArrowUp
|
||||
onClick={(ev) => {
|
||||
ev.stopPropagation();
|
||||
getApp().getCoalitionAreasManager().moveAreaUp(coalitionArea);
|
||||
}}
|
||||
className={`
|
||||
my-auto ml-auto rounded-md p-2 text-3xl
|
||||
hover:bg-white/10
|
||||
`}
|
||||
/>
|
||||
<FaArrowDown
|
||||
onClick={(ev) => {
|
||||
ev.stopPropagation();
|
||||
getApp().getCoalitionAreasManager().moveCoalitionAreaDown(coalitionArea);
|
||||
}}
|
||||
className={`
|
||||
my-auto rounded-md p-2 text-3xl
|
||||
hover:bg-white/10
|
||||
`}
|
||||
/>
|
||||
<FaXmark
|
||||
onClick={(ev) => {
|
||||
ev.stopPropagation();
|
||||
getApp().getCoalitionAreasManager().deleteCoalitionArea(coalitionArea);
|
||||
}}
|
||||
className={`
|
||||
my-auto rounded-md p-2 text-3xl
|
||||
hover:bg-red-500/50
|
||||
`}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col gap-2 p-6">
|
||||
<OlStateButton
|
||||
className="!w-full"
|
||||
icon={faDrawPolygon}
|
||||
checked={false}
|
||||
onClick={() => getApp().setState(OlympusState.DRAW, DrawSubState.DRAW_POLYGON)}
|
||||
>
|
||||
<div className="text-sm">Add polygon</div>
|
||||
</OlStateButton>
|
||||
<OlStateButton className="!w-full" icon={faCircle} checked={false} onClick={() => getApp().setState(OlympusState.DRAW, DrawSubState.DRAW_CIRCLE)}>
|
||||
<div className="text-sm">Add circle</div>
|
||||
</OlStateButton>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
<div>
|
||||
{activeCoalitionArea !== null && appSubState === DrawSubState.EDIT && (
|
||||
{activeCoalitionArea !== null && (
|
||||
<div className={`flex flex-col gap-4 py-4`}>
|
||||
<div
|
||||
className={`
|
||||
@@ -114,9 +146,13 @@ export function DrawingMenu(props: { open: boolean; onClose: () => void }) {
|
||||
<div className="my-auto flex justify-between text-md">
|
||||
Area label
|
||||
<div
|
||||
className="rounded-md bg-red-800 p-2"
|
||||
className={`
|
||||
cursor-pointer rounded-md bg-red-600 p-2
|
||||
hover:bg-red-400
|
||||
`}
|
||||
onClick={() => {
|
||||
getApp().getMap().deleteCoalitionArea(activeCoalitionArea);
|
||||
getApp().getCoalitionAreasManager().deleteCoalitionArea(activeCoalitionArea);
|
||||
getApp().setState(OlympusState.DRAW);
|
||||
setActiveCoalitionArea(null);
|
||||
}}
|
||||
>
|
||||
@@ -144,13 +180,12 @@ export function DrawingMenu(props: { open: boolean; onClose: () => void }) {
|
||||
>
|
||||
<div className="my-auto text-md">Coalition: </div>
|
||||
<OlCoalitionToggle
|
||||
coalition={areaCoalition}
|
||||
coalition={activeCoalitionArea.getCoalition()}
|
||||
onClick={() => {
|
||||
let newCoalition = "";
|
||||
if (areaCoalition === "blue") newCoalition = "neutral";
|
||||
else if (areaCoalition === "neutral") newCoalition = "red";
|
||||
else if (areaCoalition === "red") newCoalition = "blue";
|
||||
setAreaCoalition(newCoalition as Coalition);
|
||||
if (activeCoalitionArea.getCoalition() === "blue") newCoalition = "neutral";
|
||||
else if (activeCoalitionArea.getCoalition() === "neutral") newCoalition = "red";
|
||||
else if (activeCoalitionArea.getCoalition() === "red") newCoalition = "blue";
|
||||
activeCoalitionArea.setCoalition(newCoalition as Coalition);
|
||||
}}
|
||||
></OlCoalitionToggle>
|
||||
@@ -161,9 +196,11 @@ export function DrawingMenu(props: { open: boolean; onClose: () => void }) {
|
||||
bg-olympus-600 p-5
|
||||
`}
|
||||
>
|
||||
<div className={`
|
||||
border-b-2 border-b-olympus-100 pb-4 text-gray-300
|
||||
`}>Automatic IADS generation</div>
|
||||
<div
|
||||
className={`border-b-2 border-b-olympus-100 pb-4 text-gray-300`}
|
||||
>
|
||||
Automatic IADS generation
|
||||
</div>
|
||||
<OlDropdown className="" label="Units types">
|
||||
{types.map((type, idx) => {
|
||||
if (!(type in typesSelection)) {
|
||||
|
||||
Reference in New Issue
Block a user