Added area editing functions

This commit is contained in:
Pax1601 2023-06-19 17:14:53 +02:00
parent f9f02c3eb0
commit 635c487c2b
24 changed files with 685 additions and 169 deletions

View File

@ -38,6 +38,11 @@ body {
cursor: none !important;
}
.hidden-cursor * {
cursor: none !important;
pointer-events: none !important;
}
a {
text-decoration: none;
}
@ -623,39 +628,39 @@ nav.ol-panel> :last-child {
width: 28px;
}
#unit-visibility-control {
.ol-navbar-buttons-group {
align-items: center;
}
#unit-visibility-control button {
.ol-navbar-buttons-group button {
border: none;
height: 32px;
padding: 0px;
width: 32px;
}
#unit-visibility-control button svg {
.ol-navbar-buttons-group button svg {
height: 16px;
pointer-events: none;
width: 16px;
}
#unit-visibility-control button {
.ol-navbar-buttons-group button {
background-color: white;
border: 1px solid transparent;
}
#unit-visibility-control button.off {
.ol-navbar-buttons-group button.off {
background-color: transparent;
border: 1px solid white;
}
#unit-visibility-control button.off svg * {
.ol-navbar-buttons-group button.off svg * {
fill: white !important;
stroke: white !important;
}
#unit-visibility-control button svg * {
.ol-navbar-buttons-group button svg * {
fill: var(--background-steel) !important;
stroke: var(--background-steel) !important;
}
@ -666,10 +671,9 @@ nav.ol-panel> :last-child {
flex-direction: column;
}
#atc-navbar-control button {
background: #ffffff20;
border-radius: var(--border-radius-sm);
padding: 4px;
#atc-navbar-control button svg {
height: 24px;
width: 24px;
}
#roe-buttons-container button,
@ -876,6 +880,33 @@ nav.ol-panel> :last-child {
z-index: 9999;
}
.ol-draw-icon {
background-image: url("/resources/theme/images/markers/draw.svg");
height: 24px;
pointer-events: none;
width: 24px;
z-index: 9999;
}
.ol-coalitionarea-handle-icon,
.ol-coalitionarea-middle-handle-icon {
pointer-events: none;
z-index: 9999;
border-radius: 999px;
}
.ol-coalitionarea-handle-icon {
background-color: #FFFFFFEE;
width: 24px;
height: 24px;
}
.ol-coalitionarea-middle-handle-icon {
background-color: #FFFFFFAA;
width: 16px;
height: 16px;
}
dl.ol-data-grid {
align-items: center;
display: flex;
@ -1203,17 +1234,17 @@ input[type=number]::-webkit-outer-spin-button {
border-top-right-radius: var(--border-radius-sm);
}
[data-active-coalition="blue"].ol-contexmenu-button:hover,
[data-active-coalition="blue"].ol-contexmenu-button.is-open {
[data-coalition="blue"].ol-contexmenu-button:hover,
[data-coalition="blue"].ol-contexmenu-button.is-open {
background-color: var(--primary-blue)
}
[data-active-coalition="red"].ol-contexmenu-button:hover,
[data-active-coalition="red"].ol-contexmenu-button.is-open {
[data-coalition="red"].ol-contexmenu-button:hover,
[data-coalition="red"].ol-contexmenu-button.is-open {
background-color: var(--primary-red)
}
[data-active-coalition="neutral"].ol-contexmenu-button:hover,
[data-active-coalition="neutral"].ol-contexmenu-button.is-open {
[data-coalition="neutral"].ol-contexmenu-button:hover,
[data-coalition="neutral"].ol-contexmenu-button.is-open {
background-color: var(--primary-neutral)
}

View File

@ -66,54 +66,54 @@
background-size: 48px;
}
[data-active-coalition="blue"]#active-coalition-label,
[data-active-coalition="blue"].deploy-unit-button,
[data-active-coalition="blue"]#spawn-airbase-aircraft-button,
[data-active-coalition="blue"].create-iads-button {
[data-coalition="blue"]#active-coalition-label,
[data-coalition="blue"].deploy-unit-button,
[data-coalition="blue"]#spawn-airbase-aircraft-button,
[data-coalition="blue"].create-iads-button {
background-color: var(--primary-blue)
}
[data-active-coalition="red"]#active-coalition-label,
[data-active-coalition="red"].deploy-unit-button,
[data-active-coalition="red"]#spawn-airbase-aircraft-button,
[data-active-coalition="red"].create-iads-button {
[data-coalition="red"]#active-coalition-label,
[data-coalition="red"].deploy-unit-button,
[data-coalition="red"]#spawn-airbase-aircraft-button,
[data-coalition="red"].create-iads-button {
background-color: var(--primary-red)
}
[data-active-coalition="neutral"]#active-coalition-label,
[data-active-coalition="neutral"].deploy-unit-button,
[data-active-coalition="neutral"]#spawn-airbase-aircraft-button,
[data-active-coalition="neutral"].create-iads-button {
[data-coalition="neutral"]#active-coalition-label,
[data-coalition="neutral"].deploy-unit-button,
[data-coalition="neutral"]#spawn-airbase-aircraft-button,
[data-coalition="neutral"].create-iads-button {
background-color: var(--primary-neutral)
}
[data-active-coalition="blue"].deploy-unit-button:disabled {
[data-coalition="blue"].deploy-unit-button:disabled {
background-color: transparent;
border: 1px solid var(--primary-blue);
cursor: default;
}
[data-active-coalition="red"].deploy-unit-button:disabled {
[data-coalition="red"].deploy-unit-button:disabled {
background-color: transparent;
border: 1px solid var(--primary-red);
cursor: default;
}
[data-active-coalition="neutral"].deploy-unit-button:disabled {
[data-coalition="neutral"].deploy-unit-button:disabled {
background-color: transparent;
border: 1px solid var(--primary-neutral);
cursor: default;
}
[data-active-coalition="blue"]#active-coalition-label::after {
[data-coalition="blue"]#active-coalition-label::after {
content: "Create blue unit";
}
[data-active-coalition="red"]#active-coalition-label::after {
[data-coalition="red"]#active-coalition-label::after {
content: "Create red unit";
}
[data-active-coalition="neutral"]#active-coalition-label::after {
[data-coalition="neutral"]#active-coalition-label::after {
content: "Create neutral unit";
}
@ -361,10 +361,20 @@
}
#iads-button {
background-image: url("/resources/theme/images/buttons/spawn/sam.svg");
background-size: 48px;
}
#cap-button {
background-image: url("/resources/theme/images/buttons/spawn/aircraft.svg");
background-size: 48px;
}
#coalitionarea-delete-button {
background-image: url("/resources/theme/images/buttons/other/delete.svg");
background-size: 48px;
}
#coalition-area-contextmenu .ol-checkbox {
align-self: flex-start;
}

View File

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 32 32"
version="1.1"
id="svg1940"
sodipodi:docname="delete.svg"
width="32"
height="32"
inkscape:version="1.2.2 (732a01da63, 2022-12-09)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1944" />
<sodipodi:namedview
id="namedview1942"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
inkscape:zoom="13.078125"
inkscape:cx="27.794504"
inkscape:cy="19.192354"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="1912"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg1940" />
<!--! Font Awesome Pro 6.4.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. -->
<path
d="m 14.670468,9.3574565 -0.569725,0.8515865 h 4.347895 L 17.878913,9.3574565 C 17.833935,9.2914885 17.758972,9.2495089 17.678011,9.2495089 h -2.809639 c -0.08096,0 -0.155924,0.038981 -0.200903,0.1079476 z m 4.407864,-0.7976134 1.100466,1.6491999 h 0.413801 1.439301 0.239884 c 0.398807,0 0.719652,0.320845 0.719652,0.719652 0,0.398807 -0.320845,0.719651 -0.719652,0.719651 H 22.0319 v 9.115583 c 0,1.325358 -1.073479,2.398837 -2.398837,2.398837 h -6.716745 c -1.325357,0 -2.398838,-1.073479 -2.398838,-2.398837 v -9.115583 h -0.239884 c -0.3988062,0 -0.7196507,-0.320844 -0.7196507,-0.719651 0,-0.398807 0.3208445,-0.719652 0.7196507,-0.719652 h 0.239884 1.439303 0.413799 l 1.100467,-1.6521984 c 0.311849,-0.4647748 0.836595,-0.7466382 1.397323,-0.7466382 h 2.809639 c 0.560728,0 1.085474,0.2818634 1.397322,0.7466382 z m -7.121549,3.0885029 v 9.115583 c 0,0.530743 0.428792,0.959535 0.959535,0.959535 h 6.716745 c 0.530743,0 0.959536,-0.428792 0.959536,-0.959535 v -9.115583 z m 2.398837,1.919071 v 6.236977 c 0,0.263872 -0.215895,0.479767 -0.479767,0.479767 -0.263872,0 -0.479767,-0.215895 -0.479767,-0.479767 v -6.236977 c 0,-0.263873 0.215895,-0.479768 0.479767,-0.479768 0.263872,0 0.479767,0.215895 0.479767,0.479768 z m 2.398838,0 v 6.236977 c 0,0.263872 -0.215896,0.479767 -0.479767,0.479767 -0.263873,0 -0.479768,-0.215895 -0.479768,-0.479767 v -6.236977 c 0,-0.263873 0.215895,-0.479768 0.479768,-0.479768 0.263871,0 0.479767,0.215895 0.479767,0.479768 z m 2.398838,0 v 6.236977 c 0,0.263872 -0.215896,0.479767 -0.479768,0.479767 -0.263871,0 -0.479767,-0.215895 -0.479767,-0.479767 v -6.236977 c 0,-0.263873 0.215896,-0.479768 0.479767,-0.479768 0.263872,0 0.479768,0.215895 0.479768,0.479768 z"
id="path1938"
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.0299854;stroke-opacity:1" />
</svg>

After

Width:  |  Height:  |  Size: 3.0 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 10 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Pro 6.4.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M96 151.4V360.6c9.7 5.6 17.8 13.7 23.4 23.4H328.6c0-.1 .1-.2 .1-.3l-4.5-7.9-32-56 0 0c-1.4 .1-2.8 .1-4.2 .1c-35.3 0-64-28.7-64-64s28.7-64 64-64c1.4 0 2.8 0 4.2 .1l0 0 32-56 4.5-7.9-.1-.3H119.4c-5.6 9.7-13.7 17.8-23.4 23.4zM384.3 352c35.2 .2 63.7 28.7 63.7 64c0 35.3-28.7 64-64 64c-23.7 0-44.4-12.9-55.4-32H119.4c-11.1 19.1-31.7 32-55.4 32c-35.3 0-64-28.7-64-64c0-23.7 12.9-44.4 32-55.4V151.4C12.9 140.4 0 119.7 0 96C0 60.7 28.7 32 64 32c23.7 0 44.4 12.9 55.4 32H328.6c11.1-19.1 31.7-32 55.4-32c35.3 0 64 28.7 64 64c0 35.3-28.5 63.8-63.7 64l-4.5 7.9-32 56-2.3 4c4.2 8.5 6.5 18 6.5 28.1s-2.3 19.6-6.5 28.1l2.3 4 32 56 4.5 7.9z"/></svg>

After

Width:  |  Height:  |  Size: 872 B

View File

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 512 512"
version="1.1"
id="svg4"
sodipodi:docname="ground.svg"
inkscape:version="1.2.2 (732a01da63, 2022-12-09)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs8" />
<sodipodi:namedview
id="namedview6"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
inkscape:zoom="1.1559539"
inkscape:cx="432.97576"
inkscape:cy="301.91516"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="1912"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg4" />
<!--! Font Awesome Pro 6.4.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. -->
<path
d="m 130.61192,122.94993 c 4.83398,-2.4171 10.52734,-2.4171 15.36132,0 l 85.9375,42.97085 c 8.48633,4.24336 11.92383,14.55637 7.68066,23.04312 -3.00781,6.01593 -9.07714,9.5073 -15.36132,9.5073 v 42.97085 c 0,9.50729 -7.68066,17.18833 -17.1875,17.18833 h -2.63184 l 17.1875,103.13004 266.68729,0 c 9.50683,0 17.1875,7.68105 17.1875,17.18835 0,9.5073 -7.68067,17.18833 -17.1875,17.18833 l -280.97441,0 H 206.72031 69.86485 69.27404 17.98008 c -9.50683,0 -17.1875,-7.68103 -17.1875,-17.18833 0,-9.5073 7.68067,-17.18835 17.1875,-17.18835 h 37.00684 l 17.1875,-103.13004 h -2.63184 c -9.50684,0 -17.1875,-7.68104 -17.1875,-17.18833 V 198.4712 c -6.28418,0 -12.35351,-3.49137 -15.36132,-9.5073 -4.24317,-8.48675 -0.80567,-18.79976 7.68066,-23.04312 z m 39.10155,238.81049 -31.42089,-26.21222 -31.4209,26.21222 z m -62.68066,-103.13004 -2.52441,15.20096 33.78418,28.19961 33.78418,-28.19961 -2.52441,-15.20096 z m -7.46582,44.68969 -6.01561,35.98808 24.59961,-20.51857 z m 58.86718,15.46951 24.59961,20.46487 -6.01561,-35.98809 z M 95.32383,189.87702 c -4.72656,0 -8.59374,3.86738 -8.59374,8.59418 0,4.72679 3.86718,8.59417 8.59374,8.59417 h 85.9375 c 4.72656,0 8.59374,-3.86738 8.59374,-8.59417 0,-4.7268 -3.86718,-8.59418 -8.59374,-8.59418 z"
id="path2"
style="stroke-width:0.537122"
sodipodi:nodetypes="cccscssccsssccccsssccsscsccccccccccccccccccccsssssss" />
<path
d="m 398.88439,290.60444 -56.18308,-59.35032 c -4.82498,-5.06298 -11.50756,-7.93072 -18.4952,-7.84559 l -20.1384,0.17717 c -4.88076,0.0647 -7.83178,5.39609 -5.3158,9.5508 l 35.56198,58.63664 -43.41565,0.78856 -16.07612,-19.15941 c -2.39827,-2.87404 -5.9964,-4.54245 -9.73595,-4.48875 l -14.13363,0.13667 c -4.09068,0.0573 -7.05613,3.89607 -6.017,7.85435 l 11.10611,42.68377 c 0.92991,3.55548 3.36429,6.5345 6.64574,8.13577 l 48.58659,23.70886 c 1.76422,0.86089 3.69975,1.28114 5.63108,1.26246 l 119.77611,-1.14062 c 20.41896,-0.21499 40.00846,-8.13034 54.85055,-22.163 7.69088,-7.25597 5.74152,-20.00247 -3.78528,-24.65128 l -20.25324,-9.883 c -7.12743,-3.47798 -15.01076,-5.22788 -22.94599,-5.08091 z"
id="path1903"
sodipodi:nodetypes="ccccccccccccsscccsscc"
style="stroke-width:0.392612" />
</svg>

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 512 512"
version="1.1"
id="svg4"
sodipodi:docname="tower.svg"
inkscape:version="1.2.2 (732a01da63, 2022-12-09)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs8" />
<sodipodi:namedview
id="namedview6"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
inkscape:zoom="0.40869141"
inkscape:cx="532.18638"
inkscape:cy="298.51374"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="1912"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg4" />
<!--! Font Awesome Pro 6.4.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. -->
<path
d="m 130.61192,122.94993 c 4.83398,-2.4171 10.52734,-2.4171 15.36132,0 l 85.9375,42.97085 c 8.48633,4.24336 11.92383,14.55637 7.68066,23.04312 -3.00781,6.01593 -9.07714,9.5073 -15.36132,9.5073 v 42.97085 c 0,9.50729 -7.68066,17.18833 -17.1875,17.18833 h -2.63184 l 17.1875,103.13004 266.68729,0 c 9.50683,0 17.1875,7.68105 17.1875,17.18835 0,9.5073 -7.68067,17.18833 -17.1875,17.18833 l -280.97441,0 H 206.72031 69.86485 69.27404 17.98008 c -9.50683,0 -17.1875,-7.68103 -17.1875,-17.18833 0,-9.5073 7.68067,-17.18835 17.1875,-17.18835 h 37.00684 l 17.1875,-103.13004 h -2.63184 c -9.50684,0 -17.1875,-7.68104 -17.1875,-17.18833 V 198.4712 c -6.28418,0 -12.35351,-3.49137 -15.36132,-9.5073 -4.24317,-8.48675 -0.80567,-18.79976 7.68066,-23.04312 z m 39.10155,238.81049 -31.42089,-26.21222 -31.4209,26.21222 z m -62.68066,-103.13004 -2.52441,15.20096 33.78418,28.19961 33.78418,-28.19961 -2.52441,-15.20096 z m -7.46582,44.68969 -6.01561,35.98808 24.59961,-20.51857 z m 58.86718,15.46951 24.59961,20.46487 -6.01561,-35.98809 z M 95.32383,189.87702 c -4.72656,0 -8.59374,3.86738 -8.59374,8.59418 0,4.72679 3.86718,8.59417 8.59374,8.59417 h 85.9375 c 4.72656,0 8.59374,-3.86738 8.59374,-8.59417 0,-4.7268 -3.86718,-8.59418 -8.59374,-8.59418 z"
id="path2"
style="stroke-width:0.537122"
sodipodi:nodetypes="cccscssccsssccccsssccsscsccccccccccccccccccccsssssss" />
<path
d="m 387.14987,87.347348 -58.62532,-21.98825 c -5.0233,-1.86494 -10.58805,-1.59423 -15.37072,0.81215 l -13.80658,6.88825 c -3.33884,1.68446 -3.57948,6.34681 -0.45119,8.36215 l 44.18707,28.425312 -29.6285,15.13009 -17.50638,-7.79064 c -2.61694,-1.17311 -5.65498,-1.11295 -8.21176,0.18048 l -9.68566,4.84283 c -2.79741,1.41374 -3.5494,5.05338 -1.50398,7.42968 l 21.98825,25.65798 c 1.83486,2.13566 4.51196,3.36892 7.30937,3.36892 h 41.41973 c 1.50399,0 2.97789,-0.36095 4.3014,-1.02271 l 82.08748,-41.0287 c 13.98706,-7.00856 24.81575,-19.040442 30.32033,-33.689252 2.85757,-7.58008 -2.76733,-15.7016 -10.88885,-15.7016 h -17.26574 c -6.0761,0 -12.09204,1.44382 -17.50638,4.21116 z"
id="path1903"
sodipodi:nodetypes="ccccccccccccsscccsscc"
style="stroke-width:0.300797" />
</svg>

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 512 512"
version="1.1"
id="svg4"
sodipodi:docname="draw.svg"
inkscape:version="1.2.2 (732a01da63, 2022-12-09)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs8" />
<sodipodi:namedview
id="namedview6"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
inkscape:zoom="0.81738281"
inkscape:cx="159.65591"
inkscape:cy="402.50418"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="1912"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg4" />
<!--! Font Awesome Pro 6.4.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. -->
<path
d="m 352.44544,42.011059 -43.76337,43.76337 117.54624,117.546241 43.76337,-43.76337 c 22.60505,-22.60504 22.60505,-59.22522 0,-81.830267 L 434.36613,42.011059 c -22.60505,-22.605047 -59.22523,-22.605047 -81.83027,0 z M 288.2471,106.20939 77.477646,317.06927 c -9.4037,9.4037 -16.275634,21.0679 -20.073282,33.81715 L 25.395618,459.6619 c -2.260505,7.68572 -0.18084,15.91396 5.425211,21.52001 5.606052,5.60605 13.834289,7.68572 21.429585,5.51563 L 161.0259,454.68879 c 12.74925,-3.79764 24.41345,-10.66958 33.81715,-20.07328 l 210.9503,-210.85987 z"
id="path2"
style="stroke:#ffffff;stroke-width:45.7526;stroke-dasharray:none;stroke-opacity:1;fill:#247be2;fill-opacity:1" />
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -1,4 +1,4 @@
import { getUnitsManager } from "..";
import { getMap, getUnitsManager } from "..";
import { CoalitionArea } from "../map/coalitionarea";
import { ContextMenu } from "./contextmenu";
import { Dropdown } from "./dropdown";
@ -9,29 +9,39 @@ const unitRole = ["AAA", "MANPADS", "SAM Sites", "Radar"];
export class CoalitionAreaContextMenu extends ContextMenu {
#coalitionSwitch: Switch;
#coalitionArea: CoalitionArea|null = null;
#coalitionArea: CoalitionArea | null = null;
#iadsDensitySlider: Slider;
#iadsRoleDropdown: Dropdown;
//#iadsPeriodDropdown: Dropdown;
constructor(id: string) {
super(id);
this.#coalitionSwitch = new Switch("coalition-area-switch", (value: boolean) => this.#onSwitchClick(value));
this.#coalitionSwitch.setValue(false);
this.#iadsRoleDropdown = new Dropdown("iads-units-role-options", () => {});
this.#iadsRoleDropdown = new Dropdown("iads-units-role-options", () => { });
//this.#iadsPeriodDropdown = new Dropdown("iads-period-options", () => {});
this.#iadsDensitySlider = new Slider("iads-density-slider", 5, 100, "%", (value: number) => {});
this.#iadsDensitySlider = new Slider("iads-density-slider", 5, 100, "%", (value: number) => { });
this.#iadsDensitySlider.setIncrement(5);
this.#iadsDensitySlider.setValue(50);
this.#iadsDensitySlider.setActive(true);
document.addEventListener("coalitionAreaContextMenuShow", (e: any) => {
this.showSubMenu(e.detail.type);
if (this.getVisibleSubMenu() !== e.detail.type)
this.showSubMenu(e.detail.type);
else
this.hideSubMenus();
});
document.addEventListener("coalitionAreaDelete", (e: any) => {
if (this.#coalitionArea)
getMap().deleteCoalitionArea(this.#coalitionArea);
getMap().hideCoalitionAreaContextMenu();
});
document.addEventListener("contextMenuCreateIads", (e: any) => {
const values: {[key: string]: boolean} = {};
const values: { [key: string]: boolean } = {};
const element = this.#iadsRoleDropdown.getOptionElements();
for (let idx = 0; idx < element.length; idx++) {
const option = element.item(idx) as HTMLElement;
@ -70,6 +80,16 @@ export class CoalitionAreaContextMenu extends ContextMenu {
this.getContainer()?.querySelector("#iads-menu")?.classList.toggle("hide", type !== "iads");
this.getContainer()?.querySelector("#iads-button")?.classList.toggle("is-open", type === "iads");
this.clip();
this.setVisibleSubMenu(type);
}
hideSubMenus() {
this.getContainer()?.querySelector("#iads-menu")?.classList.toggle("hide", true);
this.getContainer()?.querySelector("#iads-button")?.classList.toggle("is-open", false);
this.clip();
this.setVisibleSubMenu(null);
}
getCoalitionArea() {
@ -78,9 +98,16 @@ export class CoalitionAreaContextMenu extends ContextMenu {
setCoalitionArea(coalitionArea: CoalitionArea) {
this.#coalitionArea = coalitionArea;
this.getContainer()?.querySelectorAll('[data-coalition]').forEach((element: any) => {
element.setAttribute("data-coalition", this.getCoalitionArea()?.getCoalition())
});
this.#coalitionSwitch.setValue(this.getCoalitionArea()?.getCoalition() === "red");
}
#onSwitchClick(value: boolean) {
this.getCoalitionArea()?.setCoalition(value? "red": "blue");
this.getCoalitionArea()?.setCoalition(value ? "red" : "blue");
this.getContainer()?.querySelectorAll('[data-coalition]').forEach((element: any) => {
element.setAttribute("data-coalition", this.getCoalitionArea()?.getCoalition())
});
}
}

View File

@ -5,6 +5,7 @@ export class ContextMenu {
#latlng: LatLng = new LatLng(0, 0);
#x: number = 0;
#y: number = 0;
#visibleSubMenu: string | null = null;
constructor(id: string) {
this.#container = document.getElementById(id);
@ -52,4 +53,12 @@ export class ContextMenu {
this.#container.style.top = window.innerHeight - this.#container.offsetHeight - 10 + "px";
}
}
setVisibleSubMenu(menu: string | null) {
this.#visibleSubMenu = menu;
}
getVisibleSubMenu() {
return this.#visibleSubMenu;
}
}

View File

@ -29,11 +29,11 @@ export class MapContextMenu extends ContextMenu {
#groundUnitRoleDropdown: Dropdown;
#groundUnitTypeDropdown: Dropdown;
#spawnOptions: SpawnOptions = { role: "", type: "", latlng: new LatLng(0, 0), loadout: null, coalition: "blue", airbaseName: null, altitude: ftToM(20000) };
constructor(id: string) {
super(id);
this.#coalitionSwitch = new Switch("coalition-switch", this.#onSwitchClick);
this.#coalitionSwitch = new Switch("coalition-switch", (value: boolean) => this.#onSwitchClick(value));
this.#coalitionSwitch.setValue(false);
this.#coalitionSwitch.getContainer()?.addEventListener("contextmenu", (e) => this.#onSwitchRightClick(e));
this.#aircraftRoleDropdown = new Dropdown("aircraft-role-options", (role: string) => this.#setAircraftRole(role));
@ -47,7 +47,10 @@ export class MapContextMenu extends ContextMenu {
this.#groundUnitTypeDropdown = new Dropdown("ground-unit-type-options", (type: string) => this.#setGroundUnitType(type));
document.addEventListener("mapContextMenuShow", (e: any) => {
this.showSubMenu(e.detail.type);
if (this.getVisibleSubMenu() !== e.detail.type)
this.showSubMenu(e.detail.type);
else
this.hideSubMenus();
});
document.addEventListener("contextMenuDeployAircraft", () => {
@ -104,8 +107,30 @@ export class MapContextMenu extends ContextMenu {
this.#resetGroundUnitRole();
this.#resetGroundUnitType();
this.clip();
this.setVisibleSubMenu(type);
}
hideSubMenus() {
this.getContainer()?.querySelector("#aircraft-spawn-menu")?.classList.toggle("hide", true);
this.getContainer()?.querySelector("#aircraft-spawn-button")?.classList.toggle("is-open", false);
this.getContainer()?.querySelector("#ground-unit-spawn-menu")?.classList.toggle("hide", true);
this.getContainer()?.querySelector("#ground-ol-contexmenu-button")?.classList.toggle("is-open", false);
this.getContainer()?.querySelector("#smoke-spawn-menu")?.classList.toggle("hide", true);
this.getContainer()?.querySelector("#smoke-spawn-button")?.classList.toggle("is-open", false);
this.getContainer()?.querySelector("#explosion-menu")?.classList.toggle("hide", true);
this.getContainer()?.querySelector("#explosion-spawn-button")?.classList.toggle("is-open", false);
this.#resetAircraftRole();
this.#resetAircraftType();
this.#resetGroundUnitRole();
this.#resetGroundUnitType();
this.clip();
this.setVisibleSubMenu(null);
}
showUpperBar() {
this.getContainer()?.querySelector("#upper-bar")?.classList.toggle("hide", false);
}
@ -124,6 +149,7 @@ export class MapContextMenu extends ContextMenu {
#onSwitchClick(value: boolean) {
value? setActiveCoalition("red"): setActiveCoalition("blue");
this.getContainer()?.querySelectorAll('[data-coalition]').forEach((element: any) => { element.setAttribute("data-coalition", getActiveCoalition()) });
}
#onSwitchRightClick(e: any) {

View File

@ -253,7 +253,6 @@ export function getHotgroupPanel() {
export function setActiveCoalition(newActiveCoalition: string) {
activeCoalition = newActiveCoalition;
document.querySelectorAll('[data-active-coalition]').forEach((element: any) => { element.setAttribute("data-active-coalition", activeCoalition) });
}
export function getActiveCoalition() {

View File

@ -1,40 +1,24 @@
import { LatLng, LatLngExpression, Polygon, PolylineOptions } from "leaflet";
import { LatLng, LatLngExpression, Map, Point, Polygon, PolylineOptions } from "leaflet";
import { getMap } from "..";
import { DRAW_POLYGON } from "./map";
import { CoalitionAreaHandle } from "./coalitionareahandle";
import { CoalitionAreaMiddleHandle } from "./coalitionareamiddlehandle";
export class CoalitionArea extends Polygon {
#coalition: string = "blue";
#selected: boolean = true;
#editing: boolean = true;
#handles: CoalitionAreaHandle[] = [];
#middleHandles: CoalitionAreaMiddleHandle[] = [];
#activeIndex: number = 0;
constructor(latlngs: LatLngExpression[] | LatLngExpression[][] | LatLngExpression[][][], options?: PolylineOptions) {
if (options === undefined)
if (options === undefined)
options = {};
options.bubblingMouseEvents = false;
super(latlngs, options);
this.on("click", (e: any) => {
if (!this.getSelected()) {
this.setSelected(true);
getMap().setState(DRAW_POLYGON);
}
else if (this.getEditing()) {
this.addLatLng(e.latlng);
this.addTemporaryLatLng(e.latlng);
}
});
this.on("contextmenu", (e: any) => {
if (!this.#editing)
getMap().showCoalitionAreaContextMenu(e, this);
else
this.setEditing(false);
});
this.#setColors();
this.#registerCallbacks();
}
setCoalition(coalition: string) {
@ -50,10 +34,15 @@ export class CoalitionArea extends Polygon {
this.#selected = selected;
this.#setColors();
this.#setHandles();
if (!selected)
if (!this.getSelected() && this.getEditing()) {
/* Remove the vertex we were working on */
var latlngs = this.getLatLngs()[0] as LatLng[];
latlngs.splice(this.#activeIndex, 1);
this.setLatLngs(latlngs);
this.setEditing(false);
}
}
getSelected() {
return this.#selected;
}
@ -61,6 +50,11 @@ export class CoalitionArea extends Polygon {
setEditing(editing: boolean) {
this.#editing = editing;
this.#setHandles();
var latlngs = this.getLatLngs()[0] as LatLng[];
/* Remove areas with less than 2 vertexes */
if (latlngs.length <= 2)
getMap().deleteCoalitionArea(this);
}
getEditing() {
@ -68,38 +62,92 @@ export class CoalitionArea extends Polygon {
}
addTemporaryLatLng(latlng: LatLng) {
this.addLatLng(latlng);
this.#activeIndex++;
var latlngs = this.getLatLngs()[0] as LatLng[];
latlngs.splice(this.#activeIndex, 0, latlng);
this.setLatLngs(latlngs);
this.#setHandles();
}
moveTemporaryLatLng(latlng: LatLng) {
var latlngs = this.getLatLngs()[0] as LatLng[];
latlngs[latlngs.length - 1] = latlng;
latlngs[this.#activeIndex] = latlng;
this.setLatLngs(latlngs);
}
addLatLng(latlng: LatLngExpression | LatLngExpression[], latlngs?: LatLng[] | undefined): this {
super.addLatLng(latlng, latlngs)
this.#setHandles();
return this;
}
#setColors() {
this.setStyle({color: this.getSelected()? "white": this.#coalition, fillColor: this.#coalition});
const coalitionColor = this.getCoalition() === "blue" ? "#247be2" : "#ff5858";
this.setStyle({ color: this.getSelected() ? "white" : coalitionColor, fillColor: coalitionColor });
}
#setHandles() {
this.#handles.forEach((handle: CoalitionAreaHandle) => handle.removeFrom(getMap()));
this.#handles = [];
var latlngs = this.getLatLngs()[0] as LatLng[];
latlngs.forEach((latlng: LatLng, idx: number) => {
const handle = new CoalitionAreaHandle(latlng);
handle.addTo(getMap());
handle.on("dragend", (e: any) => {
var latlngs = this.getLatLngs()[0] as LatLng[];
latlngs[idx] = e.latlng;
this.setLatLngs(latlngs);
if (this.getSelected()) {
var latlngs = this.getLatLngs()[0] as LatLng[];
latlngs.forEach((latlng: LatLng, idx: number) => {
/* Add the polygon vertex handle (for moving the vertex) */
const handle = new CoalitionAreaHandle(latlng);
handle.addTo(getMap());
handle.on("drag", (e: any) => {
var latlngs = this.getLatLngs()[0] as LatLng[];
latlngs[idx] = e.target.getLatLng();
this.setLatLngs(latlngs);
this.#setMiddleHandles();
});
this.#handles.push(handle);
});
this.#handles.push(handle);
}
this.#setMiddleHandles();
}
#setMiddleHandles() {
this.#middleHandles.forEach((handle: CoalitionAreaMiddleHandle) => handle.removeFrom(getMap()));
this.#middleHandles = [];
var latlngs = this.getLatLngs()[0] as LatLng[];
if (this.getSelected() && latlngs.length >= 2) {
var lastLatLng: LatLng | null = null;
latlngs.concat([latlngs[0]]).forEach((latlng: LatLng, idx: number) => {
/* Add the polygon middle point handle (for adding new vertexes) */
if (lastLatLng != null) {
const handle1Point = getMap().latLngToLayerPoint(latlng);
const handle2Point = getMap().latLngToLayerPoint(lastLatLng);
const middlePoint = new Point((handle1Point.x + handle2Point.x) / 2, (handle1Point.y + handle2Point.y) / 2);
const middleLatLng = getMap().layerPointToLatLng(middlePoint);
const middleHandle = new CoalitionAreaMiddleHandle(middleLatLng);
middleHandle.addTo(getMap());
middleHandle.on("click", (e: any) => {
this.#activeIndex = idx - 1;
this.addTemporaryLatLng(middleLatLng);
});
this.#middleHandles.push(middleHandle);
}
lastLatLng = latlng;
});
}
}
#registerCallbacks() {
this.on("click", (e: any) => {
getMap().deselectAllCoalitionAreas();
if (!this.getSelected()) {
this.setSelected(true);
}
});
this.on("contextmenu", (e: any) => {
if (this.getSelected() && !this.getEditing())
getMap().showCoalitionAreaContextMenu(e, this);
else
this.setEditing(false);
});
}
onRemove(map: Map): this {
super.onRemove(map);
this.#handles.concat(this.#middleHandles).forEach((handle: CoalitionAreaHandle | CoalitionAreaMiddleHandle) => handle.removeFrom(getMap()));
return this;
}
}

View File

@ -8,12 +8,12 @@ export class CoalitionAreaHandle extends CustomMarker {
createIcon() {
this.setIcon(new DivIcon({
iconSize: [52, 52],
iconAnchor: [26, 26],
className: "leaflet-target-marker",
iconSize: [24, 24],
iconAnchor: [12, 12],
className: "leaflet-coalitionarea-handle-marker",
}));
var el = document.createElement("div");
el.classList.add("ol-target-icon");
el.classList.add("ol-coalitionarea-handle-icon");
this.getElement()?.appendChild(el);
}
}

View File

@ -0,0 +1,19 @@
import { DivIcon, LatLng } from "leaflet";
import { CustomMarker } from "./custommarker";
export class CoalitionAreaMiddleHandle extends CustomMarker {
constructor(latlng: LatLng) {
super(latlng, {interactive: true, draggable: false});
}
createIcon() {
this.setIcon(new DivIcon({
iconSize: [16, 16],
iconAnchor: [8, 8],
className: "leaflet-coalitionarea-middle-handle-marker",
}));
var el = document.createElement("div");
el.classList.add("ol-coalitionarea-middle-handle-icon");
this.getElement()?.appendChild(el);
}
}

View File

@ -1,7 +1,12 @@
import { DivIcon } from "leaflet";
import { DivIcon, LatLngExpression, MarkerOptions } from "leaflet";
import { CustomMarker } from "./custommarker";
export class DestinationPreviewMarker extends CustomMarker {
constructor(latlng: LatLngExpression, options?: MarkerOptions) {
super(latlng, options);
this.setZIndexOffset(9999);
}
createIcon() {
this.setIcon(new DivIcon({
iconSize: [52, 52],

View File

@ -0,0 +1,20 @@
import { DivIcon, LatLng } from "leaflet";
import { CustomMarker } from "./custommarker";
export class DrawingCursor extends CustomMarker {
constructor() {
super(new LatLng(0, 0), {interactive: false})
this.setZIndexOffset(9999);
}
createIcon() {
this.setIcon(new DivIcon({
iconSize: [24, 24],
iconAnchor: [0, 24],
className: "leaflet-draw-marker",
}));
var el = document.createElement("div");
el.classList.add("ol-draw-icon");
this.getElement()?.appendChild(el);
}
}

View File

@ -16,6 +16,7 @@ import { layers as mapLayers, mapBounds, minimapBoundaries } from "../constants/
import { TargetMarker } from "./targetmarker";
import { CoalitionArea } from "./coalitionarea";
import { CoalitionAreaContextMenu } from "../controls/coalitionareacontextmenu";
import { DrawingCursor } from "./drawingmarker";
L.Map.addInitHook('addHandler', 'boxSelect', BoxSelect);
@ -29,7 +30,7 @@ export const MOVE_UNIT = "Move unit";
export const BOMBING = "Bombing";
export const CARPET_BOMBING = "Carpet bombing";
export const FIRE_AT_AREA = "Fire at area";
export const DRAW_POLYGON = "Draw polygon";
export const DRAW_COALITIONAREA_POLYGON = "Draw Coalition Area";
export const visibilityControls: string[] = ["human", "dcs", "aircraft", "groundunit-sam", "groundunit-other", "navyunit", "airbase"];
export const visibilityControlsTootlips: string[] = ["Toggle human players visibility", "Toggle DCS controlled units visibility", "Toggle aircrafts visibility", "Toggle SAM units visibility", "Toggle ground units (not SAM) visibility", "Toggle navy units visibility", "Toggle airbases visibility"];
@ -50,12 +51,15 @@ export class Map extends L.Map {
#miniMap: ClickableMiniMap | null = null;
#miniMapLayerGroup: L.LayerGroup;
#temporaryMarkers: TemporaryUnitMarker[] = [];
#destinationPreviewMarkers: DestinationPreviewMarker[] = [];
#targetMarker: TargetMarker;
#destinationGroupRotation: number = 0;
#computeDestinationRotation: boolean = false;
#destinationRotationCenter: L.LatLng | null = null;
#coalitionAreas: CoalitionArea[] = [];
#targetCursor: TargetMarker = new TargetMarker(new L.LatLng(0, 0), {interactive: false});
#destinationPreviewCursors: DestinationPreviewMarker[] = [];
#drawingCursor: DrawingCursor = new DrawingCursor();
#mapContextMenu: MapContextMenu = new MapContextMenu("map-contextmenu");
#unitContextMenu: UnitContextMenu = new UnitContextMenu("unit-contextmenu");
@ -102,8 +106,8 @@ export class Map extends L.Map {
this.on('mousedown', (e: any) => this.#onMouseDown(e));
this.on('mouseup', (e: any) => this.#onMouseUp(e));
this.on('mousemove', (e: any) => this.#onMouseMove(e));
this.on('keydown', (e: any) => this.#updateDestinationPreview(e));
this.on('keyup', (e: any) => this.#updateDestinationPreview(e));
this.on('keydown', (e: any) => this.#onKeyDown(e));
this.on('keyup', (e: any) => this.#onKeyUp(e));
/* Event listeners */
document.addEventListener("toggleCoalitionVisibility", (ev: CustomEventInit) => {
@ -120,9 +124,14 @@ export class Map extends L.Map {
Object.values(getUnitsManager().getUnits()).forEach((unit: Unit) => unit.updateVisibility());
});
document.addEventListener("toggleMapDraw", (ev: CustomEventInit) => {
document.addEventListener("toggleCoalitionAreaDraw", (ev: CustomEventInit) => {
const el = ev.detail._element;
document.addEventListener("mapStateChanged", () => el?.classList.toggle("off", !(this.getState() === DRAW_COALITIONAREA_POLYGON)));
if (ev.detail?.type == "polygon") {
this.setState(DRAW_POLYGON);
if (this.getState() !== DRAW_COALITIONAREA_POLYGON)
this.setState(DRAW_COALITIONAREA_POLYGON);
else
this.setState(IDLE);
}
})
@ -143,9 +152,6 @@ export class Map extends L.Map {
return this.#createOptionButton(option, `visibility/${option.toLowerCase()}.svg`, visibilityControlsTootlips[index], "toggleUnitVisibility", `{"type": "${option}"}`);
});
document.querySelector("#unit-visibility-control")?.append(...this.#optionButtons["visibility"]);
/* Markers */
this.#targetMarker = new TargetMarker(new L.LatLng(0, 0), {interactive: false});
}
setLayer(layerName: string) {
@ -172,30 +178,17 @@ export class Map extends L.Map {
/* State machine */
setState(state: string) {
this.#state = state;
this.#showCursor();
if (this.#state === IDLE) {
this.#resetDestinationMarkers();
this.#resetTargetMarker();
this.#deselectCoalitionAreas();
this.#showCursor();
}
else if (this.#state === MOVE_UNIT) {
this.#resetTargetMarker();
this.#deselectCoalitionAreas();
this.#createDestinationMarkers();
if (this.#destinationPreviewMarkers.length > 0)
this.#hideCursor();
}
else if ([BOMBING, CARPET_BOMBING, FIRE_AT_AREA].includes(this.#state)) {
this.#resetDestinationMarkers();
this.#deselectCoalitionAreas();
this.#createTargetMarker();
this.#hideCursor();
}
else if (this.#state === DRAW_POLYGON) {
this.#resetDestinationMarkers();
this.#resetTargetMarker();
this.#showCursor();
//@ts-ignore draggable option added by plugin
else if (this.#state === DRAW_COALITIONAREA_POLYGON) {
this.#coalitionAreas.push(new CoalitionArea([]));
this.#coalitionAreas[this.#coalitionAreas.length - 1].addTo(this);
}
@ -206,6 +199,17 @@ export class Map extends L.Map {
return this.#state;
}
deselectAllCoalitionAreas() {
this.#coalitionAreas.forEach((coalitionArea: CoalitionArea) => coalitionArea.setSelected(false));
}
deleteCoalitionArea(coalitionArea: CoalitionArea) {
if (this.#coalitionAreas.includes(coalitionArea))
this.#coalitionAreas.splice(this.#coalitionAreas.indexOf(coalitionArea), 1);
if (this.hasLayer(coalitionArea))
this.removeLayer(coalitionArea);
}
/* Context Menus */
hideAllContextMenus() {
this.hideMapContextMenu();
@ -393,7 +397,7 @@ export class Map extends L.Map {
});
if (closest) {
this.removeLayer(closest);
delete this.#temporaryMarkers[i];
this.#temporaryMarkers.splice(i, 1);
}
}
@ -406,16 +410,14 @@ export class Map extends L.Map {
if (!this.#preventLeftClick) {
this.hideAllContextMenus();
if (this.#state === IDLE) {
this.deselectAllCoalitionAreas();
}
else if (this.#state === DRAW_POLYGON) {
/* This gets only called to create the first point of the area. All other points are added by the area itself */
else if (this.#state === DRAW_COALITIONAREA_POLYGON) {
if (this.getSelectedCoalitionArea()?.getEditing()) {
this.getSelectedCoalitionArea()?.addLatLng(e.latlng);
this.getSelectedCoalitionArea()?.addTemporaryLatLng(e.latlng);
}
else {
this.getSelectedCoalitionArea()?.setSelected(false);
this.deselectAllCoalitionAreas();
}
}
else {
@ -426,7 +428,7 @@ export class Map extends L.Map {
}
#onDoubleClick(e: any) {
this.deselectAllCoalitionAreas();
}
#onContextMenu(e: any) {
@ -492,20 +494,34 @@ export class Map extends L.Map {
this.#lastMousePosition.x = e.originalEvent.x;
this.#lastMousePosition.y = e.originalEvent.y;
this.#showCursor(e);
if (this.#state === MOVE_UNIT){
if (this.#computeDestinationRotation && this.#destinationRotationCenter != null)
this.#destinationGroupRotation = -bearing(this.#destinationRotationCenter.lat, this.#destinationRotationCenter.lng, this.getMouseCoordinates().lat, this.getMouseCoordinates().lng);
this.#updateDestinationPreview(e);
}
else if ([BOMBING, CARPET_BOMBING, FIRE_AT_AREA].includes(this.#state)) {
this.#targetMarker.setLatLng(this.getMouseCoordinates());
this.#targetCursor.setLatLng(this.getMouseCoordinates());
}
else if (this.#state === DRAW_POLYGON) {
if (this.getSelectedCoalitionArea()?.getEditing())
else if (this.#state === DRAW_COALITIONAREA_POLYGON) {
if (this.getSelectedCoalitionArea()?.getEditing() && !e.originalEvent.ctrlKey){
this.#drawingCursor.setLatLng(e.latlng);
this.getSelectedCoalitionArea()?.moveTemporaryLatLng(e.latlng);
}
}
}
#onKeyDown(e: any) {
this.#updateDestinationPreview(e);
this.#showCursor(e);
}
#onKeyUp(e: any) {
this.#updateDestinationPreview(e);
this.#showCursor(e);
}
#onZoom(e: any) {
if (this.#centerUnit != null)
this.#panToUnit(this.#centerUnit);
@ -523,8 +539,8 @@ export class Map extends L.Map {
#updateDestinationPreview(e: any) {
Object.values(getUnitsManager().selectedUnitsComputeGroupDestination(this.#computeDestinationRotation && this.#destinationRotationCenter != null ? this.#destinationRotationCenter : this.getMouseCoordinates(), this.#destinationGroupRotation)).forEach((latlng: L.LatLng, idx: number) => {
if (idx < this.#destinationPreviewMarkers.length)
this.#destinationPreviewMarkers[idx].setLatLng(e.originalEvent.shiftKey ? latlng : this.getMouseCoordinates());
if (idx < this.#destinationPreviewCursors.length)
this.#destinationPreviewCursors[idx].setLatLng(e.originalEvent.shiftKey ? latlng : this.getMouseCoordinates());
})
}
@ -541,12 +557,12 @@ export class Map extends L.Map {
return button;
}
#createDestinationMarkers() {
this.#resetDestinationMarkers();
#showDestinationCursors() {
this.#hideDestinationCursors();
if (getUnitsManager().getSelectedUnits({ excludeHumans: true }).length > 0) {
/* Create the unit destination preview markers */
this.#destinationPreviewMarkers = getUnitsManager().getSelectedUnits({ excludeHumans: true, onlyOnePerGroup: true }).map((unit: Unit) => {
this.#destinationPreviewCursors = getUnitsManager().getSelectedUnits({ excludeHumans: true, onlyOnePerGroup: true }).map((unit: Unit) => {
var marker = new DestinationPreviewMarker(this.getMouseCoordinates(), {interactive: false});
marker.addTo(this);
return marker;
@ -554,38 +570,79 @@ export class Map extends L.Map {
}
}
#resetDestinationMarkers() {
#hideDestinationCursors() {
/* Remove all the destination preview markers */
this.#destinationPreviewMarkers.forEach((marker: L.Marker) => {
this.#destinationPreviewCursors.forEach((marker: L.Marker) => {
this.removeLayer(marker);
})
this.#destinationPreviewMarkers = [];
this.#destinationPreviewCursors = [];
this.#destinationGroupRotation = 0;
this.#computeDestinationRotation = false;
this.#destinationRotationCenter = null;
}
#createTargetMarker(){
this.#resetTargetMarker();
this.#targetMarker.addTo(this);
#showTargetCursor(){
this.#hideTargetCursor();
this.#targetCursor.addTo(this);
}
#resetTargetMarker() {
this.#targetMarker.setLatLng(new L.LatLng(0, 0));
this.removeLayer(this.#targetMarker);
#hideTargetCursor() {
this.#targetCursor.setLatLng(new L.LatLng(0, 0));
this.removeLayer(this.#targetCursor);
}
#deselectCoalitionAreas() {
this.getSelectedCoalitionArea()?.setSelected(false);
}
#showCursor() {
#showDefaultCursor() {
document.getElementById(this.#ID)?.classList.remove("hidden-cursor");
}
#hideCursor() {
#hideDefaultCursor() {
document.getElementById(this.#ID)?.classList.add("hidden-cursor");
}
#showDrawingCursor() {
this.#hideDefaultCursor();
if (!this.hasLayer(this.#drawingCursor))
this.#drawingCursor.addTo(this);
}
#hideDrawingCursor() {
if (this.hasLayer(this.#drawingCursor))
this.#drawingCursor.removeFrom(this);
}
#showCursor(e?: any) {
if (e?.originalEvent.ctrlKey) {
this.#hideDefaultCursor();
this.#hideDestinationCursors();
this.#hideTargetCursor();
this.#hideDrawingCursor();
this.#showDefaultCursor();
} else {
if (this.#state !== IDLE) this.#hideDefaultCursor();
if (this.#state !== MOVE_UNIT) this.#hideDestinationCursors();
if (![BOMBING, CARPET_BOMBING, FIRE_AT_AREA].includes(this.#state)) this.#hideTargetCursor();
if (this.#state !== DRAW_COALITIONAREA_POLYGON) this.#hideDrawingCursor();
if (this.#state === IDLE) this.#showDefaultCursor();
else if (this.#state === MOVE_UNIT) this.#showDestinationCursors();
else if ([BOMBING, CARPET_BOMBING, FIRE_AT_AREA].includes(this.#state)) this.#showTargetCursor();
else if (this.#state === DRAW_COALITIONAREA_POLYGON) {
if (this.getSelectedCoalitionArea()?.getEditing())
{
this.#hideDefaultCursor();
this.#showDrawingCursor();
}
else {
this.#hideDrawingCursor();
this.#showDefaultCursor();
}
}
}
}
}

View File

@ -1,8 +1,11 @@
import { DivIcon } from "leaflet";
import { DivIcon, LatLngExpression, MarkerOptions } from "leaflet";
import { CustomMarker } from "./custommarker";
export class TargetMarker extends CustomMarker {
#interactive: boolean = false;
constructor(latlng: LatLngExpression, options?: MarkerOptions) {
super(latlng, options);
this.setZIndexOffset(9999);
}
createIcon() {
this.setIcon(new DivIcon({
@ -12,7 +15,6 @@ export class TargetMarker extends CustomMarker {
}));
var el = document.createElement("div");
el.classList.add("ol-target-icon");
el.classList.toggle("ol-target-icon-interactive", this.#interactive)
this.getElement()?.appendChild(el);
}
}

View File

@ -45,7 +45,6 @@ export class MissionHandler {
}
}
if ("airbases" in data) {
for (let idx in data.airbases) {
var airbase = data.airbases[idx]

View File

@ -526,7 +526,8 @@ export class UnitsManager {
type: unitBlueprint.name,
coalition: coalitionArea.getCoalition(),
immediate: true
})
});
getMap().addTemporaryMarker(latlng);
}
}
}

View File

@ -1,14 +1,14 @@
<div id="map-contextmenu" class="ol-context-menu" oncontextmenu="return false;">
<div id="active-coalition-label" data-active-coalition="blue"></div>
<div id="active-coalition-label" data-coalition="blue"></div>
<div id="upper-bar" class="ol-panel">
<div id="coalition-switch" class="ol-switch ol-coalition-switch"></div>
<button data-active-coalition="blue" id="aircraft-spawn-button" title="Spawn aircraft" data-on-click="mapContextMenuShow"
<button data-coalition="blue" id="aircraft-spawn-button" title="Spawn aircraft" data-on-click="mapContextMenuShow"
data-on-click-params='{ "type": "aircraft" }' class="ol-contexmenu-button"></button>
<button data-active-coalition="blue" id="ground-ol-contexmenu-button" title="Spawn ground unit" data-on-click="mapContextMenuShow"
<button data-coalition="blue" id="ground-ol-contexmenu-button" title="Spawn ground unit" data-on-click="mapContextMenuShow"
data-on-click-params='{ "type": "ground-unit" }' class="ol-contexmenu-button"></button>
<button data-active-coalition="blue" id="smoke-spawn-button" title="Spawn smoke" data-on-click="mapContextMenuShow"
<button data-coalition="blue" id="smoke-spawn-button" title="Spawn smoke" data-on-click="mapContextMenuShow"
data-on-click-params='{ "type": "smoke" }' class="ol-contexmenu-button"></button>
<button data-active-coalition="blue" id="explosion-spawn-button" title="Explosion" data-on-click="mapContextMenuShow"
<button data-coalition="blue" id="explosion-spawn-button" title="Explosion" data-on-click="mapContextMenuShow"
data-on-click-params='{ "type": "explosion" }' class="ol-contexmenu-button"></button>
</div>
<div id="aircraft-spawn-menu" class="ol-contexmenu-panel ol-panel hide">
@ -54,7 +54,7 @@
<div id="loadout-list">
</div>
</div>
<button class="deploy-unit-button" title="" data-active-coalition="blue" data-on-click="contextMenuDeployAircraft" disabled>Deploy unit</button>
<button class="deploy-unit-button" title="" data-coalition="blue" data-on-click="contextMenuDeployAircraft" disabled>Deploy unit</button>
</div>
<div id="ground-unit-spawn-menu" class="ol-panel ol-contexmenu-panel hide">
<div class="ol-select-container">
@ -74,7 +74,7 @@
</div>
</div>
</div>
<button class="deploy-unit-button" title="" data-active-coalition="blue" data-on-click="contextMenuDeployGroundUnit" disabled>Deploy unit</button>
<button class="deploy-unit-button" title="" data-coalition="blue" data-on-click="contextMenuDeployGroundUnit" disabled>Deploy unit</button>
</div>
<div id="smoke-spawn-menu" class="ol-panel ol-contexmenu-panel hide">
<button class="smoke-button" title="" data-smoke-color="white" data-on-click="contextMenuDeploySmoke" data-on-click-params='{ "color": "white" }'>White smoke</button>
@ -104,16 +104,20 @@
<h4>Parking available:</h4>
<div id="airbase-parking"></div>
<button id="spawn-airbase-aircraft-button" data-active-coalition="red" title="Spawn aircraft" data-on-click="contextMenuSpawnAirbase" class="deploy-unit-button">Spawn</button>
<button id="spawn-airbase-aircraft-button" data-coalition="red" title="Spawn aircraft" data-on-click="contextMenuSpawnAirbase" class="deploy-unit-button">Spawn</button>
<button id="land-here-button" title="Land here" data-on-click="contextMenuLandAirbase" class="hide">Land here</button>
</div>
<div id="coalition-area-contextmenu" class="ol-context-menu" oncontextmenu="return false;">
<div id="area-coalition-label" data-active-coalition="blue"></div>
<div id="area-coalition-label" data-coalition="blue"></div>
<div id="upper-bar" class="ol-panel">
<div id="coalition-area-switch" class="ol-switch ol-coalition-switch"></div>
<button data-active-coalition="blue" id="iads-button" title="Create Integrated Air Defense System" data-on-click="coalitionAreaContextMenuShow"
<button data-coalition="blue" id="iads-button" title="Create Integrated Air Defense System" data-on-click="coalitionAreaContextMenuShow"
data-on-click-params='{ "type": "iads" }' class="ol-contexmenu-button"></button>
<button data-coalition="blue" id="cap-button" title="Create Combat Air Patrols" data-on-click="coalitionAreaContextMenuShow"
data-on-click-params='{ "type": "cap" }' class="ol-contexmenu-button"></button>
<button data-coalition="blue" id="coalitionarea-delete-button" title="Delete area" data-on-click="coalitionAreaDelete"
class="ol-contexmenu-button"></button>
</div>
<div id="iads-menu" class="ol-panel ol-contexmenu-panel hide">
<div id="iads-units-role-options" class="ol-select">
@ -147,6 +151,6 @@
</dl>
<input type="range" min="0" max="100" value="0" class="ol-slider">
</div>
<button class="create-iads-button" title="" data-active-coalition="blue" data-on-click="contextMenuCreateIads">Add units to IADS</button>
<button class="create-iads-button" title="" data-coalition="blue" data-on-click="contextMenuCreateIads">Add units to IADS</button>
</div>
</div>

View File

@ -29,7 +29,7 @@
</div>
</div>
<div id="unit-visibility-control" class="ol-group">
<div id="unit-visibility-control" class="ol-group ol-navbar-buttons-group">
<!-- Here the available visibility controls will be listed -->
</div>
@ -50,19 +50,20 @@
</div>
</div>
<div id="atc-navbar-control" class="ol-group-container" data-feature-switch="atc">
<div id="atc-navbar-control" class="ol-group-container ol-navbar-buttons-group" data-feature-switch="atc">
<div class="ol-group">
<button data-on-click="toggleElements"
data-on-click-params='{"selector": "#strip-board-ground"}'>GND</button>
data-on-click-params='{"selector": "#strip-board-ground"}' class="off"><img src="resources/theme/images/buttons/tools/ground.svg" inject-svg></button>
<button data-on-click="toggleElements"
data-on-click-params='{"selector": "#strip-board-tower"}'>TWR</button>
data-on-click-params='{"selector": "#strip-board-tower"}' class="off"><img src="resources/theme/images/buttons/tools/tower.svg" inject-svg></button>
</div>
</div>
<div id="map-drawer" class="ol-group-container">
<div id="map-tools" class="ol-group-container ol-navbar-buttons-group">
<div class="ol-group">
<button data-on-click="toggleMapDraw" data-on-click-params='{"type": "polygon"}'>Polygon</button>
<button title="Draw Coalition Areas on the map" data-on-click="toggleCoalitionAreaDraw" data-on-click-params='{"type": "polygon"}' class="off">
<img src="resources/theme/images/buttons/tools/draw-polygon-solid.svg" inject-svg>
</button>
</div>
</div>
</nav>

View File

@ -1047,7 +1047,7 @@
<dt>Open air</dt>
<dd>5</dd>
</dl>
<button id="spawn-airbase-aircraft-button" data-active-coalition="red" title="Spawn aircraft" data-on-click="contextMenuSpawnAirbase" class="deploy-unit-button">Spawn</button>
<button id="spawn-airbase-aircraft-button" data-coalition="red" title="Spawn aircraft" data-on-click="contextMenuSpawnAirbase" class="deploy-unit-button">Spawn</button>
<button id="land-here-button" title="Land here" data-on-click="contextMenuLandAirbase" class="hide">Land here</button>
</div>