mirror of
https://github.com/Pax1601/DCSOlympus.git
synced 2025-10-29 16:56:34 +00:00
Merge branch 'main' into 343-add-ability-to-select-unit-nation-and-livery
This commit is contained in:
@@ -8,7 +8,7 @@ const DEMO_UNIT_DATA = {
|
||||
formationOffset: { x: 0, y: 0, z: 0 },
|
||||
targetID: 2,
|
||||
targetPosition: { lat: 0, lng: 0, alt: 0 },
|
||||
ROE: 2,
|
||||
ROE: 1,
|
||||
reactionToThreat: 1,
|
||||
emissionsCountermeasures: 1,
|
||||
TACAN: { isOn: false, XY: 'Y', callsign: 'TKR', channel: 40 },
|
||||
@@ -24,7 +24,7 @@ const DEMO_UNIT_DATA = {
|
||||
formationOffset: { x: 0, y: 0, z: 0 },
|
||||
targetID: 0,
|
||||
targetPosition: { lat: 0, lng: 0, alt: 0 },
|
||||
ROE: 2,
|
||||
ROE: 1,
|
||||
reactionToThreat: 1,
|
||||
emissionsCountermeasures: 1,
|
||||
TACAN: { isOn: false, XY: 'Y', callsign: 'TKR', channel: 40 },
|
||||
@@ -39,7 +39,7 @@ const DEMO_UNIT_DATA = {
|
||||
formationOffset: { x: 0, y: 0, z: 0 },
|
||||
targetID: 0,
|
||||
targetPosition: { lat: 0, lng: 0, alt: 0 },
|
||||
ROE: 2,
|
||||
ROE: 1,
|
||||
reactionToThreat: 1,
|
||||
emissionsCountermeasures: 1,
|
||||
TACAN: { isOn: false, XY: 'Y', callsign: 'TKR', channel: 40 },
|
||||
@@ -54,7 +54,7 @@ const DEMO_UNIT_DATA = {
|
||||
formationOffset: { x: 0, y: 0, z: 0 },
|
||||
targetID: 0,
|
||||
targetPosition: { lat: 0, lng: 0, alt: 0 },
|
||||
ROE: 2,
|
||||
ROE: 1,
|
||||
reactionToThreat: 1,
|
||||
emissionsCountermeasures: 1,
|
||||
TACAN: { isOn: false, XY: 'Y', callsign: 'TKR', channel: 40 },
|
||||
@@ -64,13 +64,13 @@ const DEMO_UNIT_DATA = {
|
||||
contacts: [{ID: 1001, detectionMethod: 16}],
|
||||
activePath: [ ],
|
||||
isLeader: true
|
||||
}, ["5"]:{ category: "GroundUnit", alive: true, human: false, controlled: true, coalition: 1, country: 0, name: "Gepard", unitName: "Cool guy 2-2", groupName: "Cool group 4", state: 1, task: "Being cool",
|
||||
}, ["5"]:{ category: "GroundUnit", alive: true, human: false, controlled: true, coalition: 1, country: 0, name: "S_75M_Volhov", unitName: "Cool guy 2-2", groupName: "Cool group 4", state: 1, task: "Being cool",
|
||||
hasTask: false, position: { lat: 37.21, lng: -116.1, alt: 1000 }, speed: 200, heading: 315 * Math.PI / 180, isTanker: false, isAWACS: false, onOff: true, followRoads: false, fuel: 50,
|
||||
desiredSpeed: 300, desiredSpeedType: 1, desiredAltitude: 1000, desiredAltitudeType: 1, leaderID: 0,
|
||||
formationOffset: { x: 0, y: 0, z: 0 },
|
||||
targetID: 0,
|
||||
targetPosition: { lat: 0, lng: 0, alt: 0 },
|
||||
ROE: 2,
|
||||
ROE: 1,
|
||||
reactionToThreat: 1,
|
||||
emissionsCountermeasures: 1,
|
||||
TACAN: { isOn: false, XY: 'Y', callsign: 'TKR', channel: 40 },
|
||||
@@ -99,9 +99,9 @@ class DemoDataGenerator {
|
||||
|
||||
app.use('/demo', basicAuth({
|
||||
users: {
|
||||
'admin': 'socks',
|
||||
'blue': 'bluesocks',
|
||||
'red': 'redsocks'
|
||||
'admin': 'password',
|
||||
'blue': 'bluepassword',
|
||||
'red': 'redpassword'
|
||||
},
|
||||
}))
|
||||
|
||||
|
||||
4
client/package-lock.json
generated
4
client/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "DCSOlympus",
|
||||
"version": "v0.4.1-alpha",
|
||||
"version": "v0.4.2-alpha",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "DCSOlympus",
|
||||
"version": "v0.4.1-alpha",
|
||||
"version": "v0.4.2-alpha",
|
||||
"dependencies": {
|
||||
"cookie-parser": "~1.4.4",
|
||||
"debug": "~2.6.9",
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"name": "DCSOlympus",
|
||||
"node-main": "./bin/www",
|
||||
"main": "http://localhost:3000",
|
||||
"version": "v0.4.1-alpha",
|
||||
"version": "v0.4.2-alpha",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"copy": "copy.bat",
|
||||
|
||||
@@ -691,6 +691,11 @@ nav.ol-panel> :last-child {
|
||||
width: 30px;
|
||||
}
|
||||
|
||||
#reaction-to-threat-buttons-container button:not(:first-child) svg {
|
||||
width: 150%;
|
||||
margin: -5px;
|
||||
}
|
||||
|
||||
#unit-control-panel .ol-option-button button.selected {
|
||||
background-color: white;
|
||||
border-color: white;
|
||||
@@ -700,6 +705,28 @@ nav.ol-panel> :last-child {
|
||||
fill: var(--background-steel);
|
||||
}
|
||||
|
||||
#rapid-controls {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
row-gap: 5px;
|
||||
position: absolute;
|
||||
height: fit-content;
|
||||
width: fit-content;
|
||||
left: calc(100% + 10px);
|
||||
top: 0px;
|
||||
}
|
||||
|
||||
#rapid-controls button {
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
#rapid-controls svg {
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
fill: white;
|
||||
stroke: white;
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
#splash-screen {
|
||||
background-image: url("/resources/theme/images/splash/1.png");
|
||||
@@ -959,6 +986,10 @@ nav.ol-panel> :last-child {
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
#command-mode-toolbar {
|
||||
min-width: fit-content ;
|
||||
}
|
||||
|
||||
#command-mode-toolbar .ol-button {
|
||||
border: 1px solid white;
|
||||
}
|
||||
|
||||
@@ -100,6 +100,10 @@ body.feature-forceShowUnitControlPanel #unit-control-panel {
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
#advanced-settings-dialog .ol-text-input input {
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
#general-settings-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
|
||||
40
client/public/themes/olympus/images/icons/climb.svg
Normal file
40
client/public/themes/olympus/images/icons/climb.svg
Normal file
@@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
viewBox="0 0 640 512"
|
||||
version="1.1"
|
||||
id="svg11515"
|
||||
sodipodi:docname="climb.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="defs11519" />
|
||||
<sodipodi:namedview
|
||||
id="namedview11517"
|
||||
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="184.69595"
|
||||
inkscape:cy="230.97808"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1017"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg11515" />
|
||||
<!--! Font Awesome Pro 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. -->
|
||||
<path
|
||||
d="m 0,480 c 0,17.7 14.3,32 32,32 h 576 c 17.7,0 32,-14.3 32,-32 0,-17.7 -14.3,-32 -32,-32 H 32 C 14.3,448 0,462.3 0,480 Z"
|
||||
id="path12003" />
|
||||
<path
|
||||
d="M 381,114.9 186.1,41.8 C 169.4,35.6 150.9,36.5 135,44.5 L 89.1,67.4 C 78,73 77.2,88.5 87.6,95.2 L 234.5,189.7 136,240 77.8,214.1 c -8.7,-3.9 -18.8,-3.7 -27.3,0.6 l -32.2,16.1 c -9.3,4.7 -11.8,16.8 -5,24.7 l 73.1,85.3 c 6.1,7.1 15,11.2 24.3,11.2 h 137.7 c 5,0 9.9,-1.2 14.3,-3.4 L 535.6,212.2 c 46.5,-23.3 82.5,-63.3 100.8,-112 C 645.9,75 627.2,48 600.2,48 h -57.4 c -20.2,0 -40.2,4.8 -58.2,14 z"
|
||||
id="path11513" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.8 KiB |
40
client/public/themes/olympus/images/icons/descent.svg
Normal file
40
client/public/themes/olympus/images/icons/descent.svg
Normal file
@@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
viewBox="0 0 640 512"
|
||||
version="1.1"
|
||||
id="svg11515"
|
||||
sodipodi:docname="descent.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="defs11519" />
|
||||
<sodipodi:namedview
|
||||
id="namedview11517"
|
||||
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="184.69595"
|
||||
inkscape:cy="230.97808"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1017"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg11515" />
|
||||
<!--! Font Awesome Pro 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. -->
|
||||
<path
|
||||
d="m 0,480 c 0,17.7 14.3,32 32,32 h 576 c 17.7,0 32,-14.3 32,-32 0,-17.7 -14.3,-32 -32,-32 H 32 C 14.3,448 0,462.3 0,480 Z"
|
||||
id="path12003" />
|
||||
<path
|
||||
d="M 390.60902,242.29848 295.63089,57.072198 C 287.44991,41.248114 273.15967,29.46469 256.01489,24.682806 L 206.65223,10.734745 C 194.67308,7.4076141 183.65093,18.33475 186.83528,30.289244 L 231.90676,199.04475 125.19723,169.9687 99.575041,111.64587 C 95.764001,102.90653 88.158361,96.257906 78.977251,93.718766 L 44.324506,83.959798 C 34.282459,81.178199 24.290763,88.44635 24.004651,98.865954 L 20.676595,211.15409 c -0.265566,9.35678 3.558834,18.37864 10.438121,24.63687 L 132.97255,328.4531 c 3.69854,3.36464 8.13062,5.77434 12.86578,7.10786 l 293.65372,82.74575 c 50.07565,14.05594 103.62226,8.693 149.9305,-15.01621 23.985,-12.24784 28.32151,-44.80371 8.34938,-62.97276 L 555.31268,301.69169 C 540.37057,288.09856 522.34635,278.1906 502.84067,272.88322 Z"
|
||||
id="path11513" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.1 KiB |
1
client/public/themes/olympus/images/icons/hand-solid.svg
Normal file
1
client/public/themes/olympus/images/icons/hand-solid.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Pro 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M288 32c0-17.7-14.3-32-32-32s-32 14.3-32 32V240c0 8.8-7.2 16-16 16s-16-7.2-16-16V64c0-17.7-14.3-32-32-32s-32 14.3-32 32V336c0 1.5 0 3.1 .1 4.6L67.6 283c-16-15.2-41.3-14.6-56.6 1.4s-14.6 41.3 1.4 56.6L124.8 448c43.1 41.1 100.4 64 160 64H304c97.2 0 176-78.8 176-176V128c0-17.7-14.3-32-32-32s-32 14.3-32 32V240c0 8.8-7.2 16-16 16s-16-7.2-16-16V64c0-17.7-14.3-32-32-32s-32 14.3-32 32V240c0 8.8-7.2 16-16 16s-16-7.2-16-16V32z"/></svg>
|
||||
|
After Width: | Height: | Size: 668 B |
57
client/public/themes/olympus/images/icons/speed-decrease.svg
Normal file
57
client/public/themes/olympus/images/icons/speed-decrease.svg
Normal file
@@ -0,0 +1,57 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
viewBox="0 0 512 512"
|
||||
version="1.1"
|
||||
id="svg4"
|
||||
sodipodi:docname="speed-decrease.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="362.74313"
|
||||
inkscape:cy="254.47073"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1017"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg4" />
|
||||
<!--! Font Awesome Pro 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. -->
|
||||
<path
|
||||
d="m 465.11867,284.79404 a 203.05733,202.96808 0 1 0 -406.11467,0 203.05733,202.96808 0 1 0 406.11467,0 z M 236.67916,157.939 a 25.382167,25.371011 0 1 1 50.76433,0 25.382167,25.371011 0 1 1 -50.76433,0 z m 25.38218,253.71009 c -27.99972,0 -50.76435,-22.75462 -50.76435,-50.74202 0,-13.79547 5.47304,-26.24313 14.3568,-35.36086 L 174.81014,210.02885 c -4.20393,-9.59341 0.15866,-20.85181 9.75626,-25.05387 9.59763,-4.2021 20.86097,0.1586 25.06489,9.75199 l 50.92297,115.43808 c 0.47592,0 1.03116,0 1.50708,0 27.99969,0 50.76433,22.75464 50.76433,50.74202 0,27.9874 -22.76464,50.74202 -50.76433,50.74202 z m 63.4554,-215.65359 a 25.38217,25.371013 0 1 1 50.76433,0 25.38217,25.371013 0 1 1 -50.76433,0 z m 63.45542,114.16955 a 25.382167,25.371011 0 1 1 0,-50.74201 25.382167,25.371011 0 1 1 0,50.74201 z M 109.76832,284.79404 a 25.38217,25.371013 0 1 1 50.76433,0 25.38217,25.371013 0 1 1 -50.76433,0 z"
|
||||
id="path2"
|
||||
style="stroke-width:0.627239" />
|
||||
<path
|
||||
style="fill:none;stroke-width:37.6403;stroke-linecap:round;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path1569"
|
||||
sodipodi:type="arc"
|
||||
sodipodi:cx="-261.46939"
|
||||
sodipodi:cy="284.48697"
|
||||
sodipodi:rx="250.99081"
|
||||
sodipodi:ry="250.88049"
|
||||
sodipodi:start="3.7594392"
|
||||
sodipodi:end="5.6635934"
|
||||
sodipodi:arc-type="arc"
|
||||
d="M -466.05898,139.15662 A 250.99081,250.88049 0 0 1 -261.68843,33.606571 250.99081,250.88049 0 0 1 -57.133877,138.79992"
|
||||
sodipodi:open="true"
|
||||
transform="scale(-1,1)" />
|
||||
<path
|
||||
style="fill:none;stroke-width:30;stroke-linecap:round;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 51.337,145.14023 47.06496,70.716358"
|
||||
id="path2580"
|
||||
sodipodi:nodetypes="cc" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.9 KiB |
56
client/public/themes/olympus/images/icons/speed-increase.svg
Normal file
56
client/public/themes/olympus/images/icons/speed-increase.svg
Normal file
@@ -0,0 +1,56 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
viewBox="0 0 512 512"
|
||||
version="1.1"
|
||||
id="svg4"
|
||||
sodipodi:docname="speed-increase.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="362.74313"
|
||||
inkscape:cy="254.47073"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1017"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg4" />
|
||||
<!--! Font Awesome Pro 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. -->
|
||||
<path
|
||||
d="m 51.825435,284.79404 a 203.05733,202.96808 0 1 1 406.114665,0 203.05733,202.96808 0 1 1 -406.114665,0 z M 280.26494,157.939 a 25.382167,25.371011 0 1 0 -50.76433,0 25.382167,25.371011 0 1 0 50.76433,0 z m -25.38218,253.71009 c 27.99972,0 50.76435,-22.75462 50.76435,-50.74202 0,-13.79547 -5.47304,-26.24313 -14.3568,-35.36086 l 50.84365,-115.51736 c 4.20393,-9.59341 -0.15866,-20.85181 -9.75626,-25.05387 -9.59763,-4.2021 -20.86097,0.1586 -25.06489,9.75199 l -50.92297,115.43808 c -0.47592,0 -1.03116,0 -1.50708,0 -27.99969,0 -50.76433,22.75464 -50.76433,50.74202 0,27.9874 22.76464,50.74202 50.76433,50.74202 z M 191.42736,195.9955 a 25.38217,25.371013 0 1 0 -50.76433,0 25.38217,25.371013 0 1 0 50.76433,0 z m -63.45542,114.16955 a 25.382167,25.371011 0 1 0 0,-50.74201 25.382167,25.371011 0 1 0 0,50.74201 z m 279.20384,-25.37101 a 25.38217,25.371013 0 1 0 -50.76433,0 25.38217,25.371013 0 1 0 50.76433,0 z"
|
||||
id="path2"
|
||||
style="stroke-width:0.627239" />
|
||||
<path
|
||||
style="fill:none;stroke-width:37.6403;stroke-linecap:round;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path1569"
|
||||
sodipodi:type="arc"
|
||||
sodipodi:cx="255.4747"
|
||||
sodipodi:cy="284.48697"
|
||||
sodipodi:rx="250.99081"
|
||||
sodipodi:ry="250.88049"
|
||||
sodipodi:start="3.7594392"
|
||||
sodipodi:end="5.6635934"
|
||||
sodipodi:arc-type="arc"
|
||||
d="M 50.885111,139.15662 A 250.99081,250.88049 0 0 1 255.25567,33.606571 250.99081,250.88049 0 0 1 459.81021,138.79992"
|
||||
sodipodi:open="true" />
|
||||
<path
|
||||
style="fill:none;stroke-width:30;stroke-linecap:round;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 465.6071,145.14023 4.27204,-74.423872"
|
||||
id="path2580"
|
||||
sodipodi:nodetypes="cc" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.9 KiB |
@@ -13,7 +13,7 @@ export const RWR = 16;
|
||||
export const DLINK = 32;
|
||||
|
||||
export const states: string[] = ["none", "idle", "reach-destination", "attack", "follow", "land", "refuel", "AWACS", "tanker", "bomb-point", "carpet-bomb", "bomb-building", "fire-at-area"];
|
||||
export const ROEs: string[] = ["free", "designated", "return", "hold"];
|
||||
export const ROEs: string[] = ["free", "designated", "", "return", "hold"];
|
||||
export const reactionsToThreat: string[] = ["none", "manoeuvre", "passive", "evade"];
|
||||
export const emissionsCountermeasures: string[] = ["silent", "attack", "defend", "free"];
|
||||
|
||||
|
||||
@@ -205,11 +205,13 @@ function setupEvents() {
|
||||
|
||||
document.querySelectorAll("[inject-svg]").forEach((el: Element) => {
|
||||
var img = el as HTMLImageElement;
|
||||
var isLoaded = img.complete && img.naturalHeight !== 0;
|
||||
var isLoaded = img.complete;
|
||||
if (isLoaded)
|
||||
SVGInjector(img);
|
||||
else
|
||||
img.onload = () => SVGInjector(img);
|
||||
img.addEventListener("load", () => {
|
||||
SVGInjector(img);
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import * as L from "leaflet"
|
||||
import { getUnitsManager } from "..";
|
||||
import { getMissionHandler, getUnitsManager } from "..";
|
||||
import { BoxSelect } from "./boxselect";
|
||||
import { MapContextMenu } from "../controls/mapcontextmenu";
|
||||
import { UnitContextMenu } from "../controls/unitcontextmenu";
|
||||
@@ -117,11 +117,20 @@ export class Map extends L.Map {
|
||||
Object.values(getUnitsManager().getUnits()).forEach((unit: Unit) => unit.updateVisibility());
|
||||
});
|
||||
|
||||
document.addEventListener("toggleUnitVisibility", (ev: CustomEventInit) => {
|
||||
document.addEventListener("toggleMarkerVisibility", (ev: CustomEventInit) => {
|
||||
const el = ev.detail._element;
|
||||
el?.classList.toggle("off");
|
||||
ev.detail.types.forEach((type: string) => getUnitsManager().setHiddenType(type, !el?.classList.contains("off")));
|
||||
Object.values(getUnitsManager().getUnits()).forEach((unit: Unit) => unit.updateVisibility());
|
||||
|
||||
if (ev.detail.types.includes("airbase")) {
|
||||
Object.values(getMissionHandler().getAirbases()).forEach((airbase: Airbase) => {
|
||||
if (el?.classList.contains("off"))
|
||||
airbase.removeFrom(this);
|
||||
else
|
||||
airbase.addTo(this);
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -150,7 +159,9 @@ export class Map extends L.Map {
|
||||
|
||||
/* Option buttons */
|
||||
this.#optionButtons["visibility"] = visibilityControls.map((option: string, index: number) => {
|
||||
return this.#createOptionButton(option, `visibility/${option.toLowerCase()}.svg`, visibilityControlsTootlips[index], "toggleUnitVisibility", `{"types": "${visibilityControlsTypes[index]}"}`);
|
||||
var typesArrayString = `"${visibilityControlsTypes[index][0]}"`;
|
||||
visibilityControlsTypes[index].forEach((type: string, idx: number) => {if (idx > 0) typesArrayString = `${typesArrayString}, "${type}"`});
|
||||
return this.#createOptionButton(option, `visibility/${option.toLowerCase()}.svg`, visibilityControlsTootlips[index], "toggleMarkerVisibility", `{"types": [${typesArrayString}]}`);
|
||||
});
|
||||
document.querySelector("#unit-visibility-control")?.append(...this.#optionButtons["visibility"]);
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ export class Airbase extends CustomMarker
|
||||
img.onload = () => SVGInjector(img);
|
||||
el.appendChild(img);
|
||||
this.getElement()?.appendChild(el);
|
||||
el.dataset.coalition = this.#coalition;
|
||||
}
|
||||
|
||||
setCoalition(coalition: string)
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { getMouseInfoPanel } from "..";
|
||||
import { Panel } from "./panel";
|
||||
|
||||
export class LogPanel extends Panel {
|
||||
@@ -23,8 +24,21 @@ export class LogPanel extends Panel {
|
||||
if (scrollEl) {
|
||||
scrollEl.addEventListener("scroll", () => {
|
||||
this.#scrolledDown = Math.abs(scrollEl.scrollHeight - scrollEl.scrollTop - scrollEl.clientHeight) < 1
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
window.addEventListener("resize", () => {
|
||||
this.#calculateHeight();
|
||||
});
|
||||
|
||||
|
||||
const mouseInfoPanel = getMouseInfoPanel();
|
||||
new ResizeObserver(() => this.#calculateHeight()).observe(mouseInfoPanel.getElement())
|
||||
}
|
||||
|
||||
show() {
|
||||
super.show();
|
||||
this.#calculateHeight();
|
||||
}
|
||||
|
||||
appendLogs(logs: {[key: string]: string}) {
|
||||
@@ -68,4 +82,9 @@ export class LogPanel extends Panel {
|
||||
scrollEl.scrollTop = scrollEl.scrollHeight - scrollEl.clientHeight;
|
||||
}
|
||||
}
|
||||
|
||||
#calculateHeight() {
|
||||
const mouseInfoPanel = getMouseInfoPanel();
|
||||
this.getElement().style.height = `${mouseInfoPanel.getElement().offsetTop - this.getElement().offsetTop - 10}px`;
|
||||
}
|
||||
}
|
||||
@@ -39,7 +39,7 @@ export class UnitControlPanel extends Panel {
|
||||
// Reversing the ROEs so that the least "aggressive" option is always on the left
|
||||
this.#optionButtons["ROE"] = ROEs.slice(0).reverse().map((option: string, index: number) => {
|
||||
return this.#createOptionButton(option, `roe/${option.toLowerCase()}.svg`, ROEDescriptions.slice(0).reverse()[index], () => { getUnitsManager().selectedUnitsSetROE(option); });
|
||||
});
|
||||
}).filter((button: HTMLButtonElement, index: number) => {return ROEs[index] !== "";});
|
||||
|
||||
this.#optionButtons["reactionToThreat"] = reactionsToThreat.map((option: string, index: number) => {
|
||||
return this.#createOptionButton(option, `threat/${option.toLowerCase()}.svg`, reactionsToThreatDescriptions[index],() => { getUnitsManager().selectedUnitsSetReactionToThreat(option); });
|
||||
|
||||
@@ -419,7 +419,7 @@ export function startUpdate() {
|
||||
getWeapons((buffer: ArrayBuffer) => {
|
||||
var time = getWeaponsManager()?.update(buffer);
|
||||
return time;
|
||||
}, false);
|
||||
}, true);
|
||||
}
|
||||
}, 5000);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Marker, LatLng, Polyline, Icon, DivIcon, CircleMarker, Map, Point } from 'leaflet';
|
||||
import { getMap, getMissionHandler, getUnitsManager } from '..';
|
||||
import { getMap, getMissionHandler, getUnitsManager, getWeaponsManager } from '..';
|
||||
import { enumToCoalition, enumToEmissioNCountermeasure, getMarkerCategoryByName, enumToROE, enumToReactionToThreat, enumToState, getUnitDatabaseByCategory, mToFt, msToKnots, rad2deg, bearing, deg2rad } from '../other/utils';
|
||||
import { addDestination, attackUnit, changeAltitude, changeSpeed, createFormation as setLeader, deleteUnit, landAt, setAltitude, setReactionToThreat, setROE, setSpeed, refuel, setAdvacedOptions, followUnit, setEmissionsCountermeasures, setSpeedType, setAltitudeType, setOnOff, setFollowRoads, bombPoint, carpetBomb, bombBuilding, fireAtArea } from '../server/server';
|
||||
import { CustomMarker } from '../map/custommarker';
|
||||
@@ -11,6 +11,7 @@ import { Ammo, Contact, GeneralSettings, Offset, Radio, TACAN, ObjectIconOptions
|
||||
import { DataExtractor } from '../server/dataextractor';
|
||||
import { groundUnitDatabase } from './groundunitdatabase';
|
||||
import { navyUnitDatabase } from './navyunitdatabase';
|
||||
import { Weapon } from '../weapon/weapon';
|
||||
|
||||
var pathIcon = new Icon({
|
||||
iconUrl: '/resources/theme/images/markers/marker-icon.png',
|
||||
@@ -153,7 +154,7 @@ export class Unit extends CustomMarker {
|
||||
this.on('click', (e) => this.#onClick(e));
|
||||
this.on('dblclick', (e) => this.#onDoubleClick(e));
|
||||
this.on('contextmenu', (e) => this.#onContextMenu(e));
|
||||
this.on('mouseover', () => { this.setHighlighted(true); })
|
||||
this.on('mouseover', () => { if (this.belongsToCommandedCoalition()) this.setHighlighted(true); })
|
||||
this.on('mouseout', () => { this.setHighlighted(false); })
|
||||
getMap().on("zoomend", () => {this.#onZoom();})
|
||||
|
||||
@@ -540,7 +541,7 @@ export class Unit extends CustomMarker {
|
||||
/* Force a redraw of the unit to reflect the new status of the detection methods */
|
||||
this.setHidden(true);
|
||||
this.#detectionMethods = newDetectionMethods;
|
||||
this.updateVisibility();
|
||||
this.#updateMarker();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -986,19 +987,25 @@ export class Unit extends CustomMarker {
|
||||
if (getMap().getVisibilityOptions()[SHOW_CONTACT_LINES]) {
|
||||
for (let index in this.#contacts) {
|
||||
var contactData = this.#contacts[index];
|
||||
var contact = getUnitsManager().getUnitByID(contactData.ID);
|
||||
var contact: Unit | Weapon | null;
|
||||
|
||||
if (contactData.ID in getUnitsManager().getUnits())
|
||||
contact = getUnitsManager().getUnitByID(contactData.ID);
|
||||
else
|
||||
contact = getWeaponsManager().getWeaponByID(contactData.ID);
|
||||
|
||||
if (contact != null && contact.getAlive()) {
|
||||
var startLatLng = new LatLng(this.#position.lat, this.#position.lng);
|
||||
var endLatLng: LatLng;
|
||||
if (contactData.detectionMethod === RWR) {
|
||||
var bearingToContact = bearing(this.#position.lat, this.#position.lng, contact.#position.lat, contact.#position.lng);
|
||||
var bearingToContact = bearing(this.#position.lat, this.#position.lng, contact.getPosition().lat, contact.getPosition().lng);
|
||||
var startXY = getMap().latLngToContainerPoint(startLatLng);
|
||||
var endX = startXY.x + 80 * Math.sin(deg2rad(bearingToContact));
|
||||
var endY = startXY.y - 80 * Math.cos(deg2rad(bearingToContact));
|
||||
endLatLng = getMap().containerPointToLatLng(new Point(endX, endY));
|
||||
}
|
||||
else
|
||||
endLatLng = new LatLng(contact.#position.lat, contact.#position.lng);
|
||||
endLatLng = new LatLng(contact.getPosition().lat, contact.getPosition().lng);
|
||||
|
||||
var color;
|
||||
if (contactData.detectionMethod === VISUAL || contactData.detectionMethod === OPTIC)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { LatLng, LatLngBounds } from "leaflet";
|
||||
import { getHotgroupPanel, getInfoPopup, getMap, getMissionHandler, getUnitsManager } from "..";
|
||||
import { getHotgroupPanel, getInfoPopup, getMap, getMissionHandler, getUnitsManager, getWeaponsManager } from "..";
|
||||
import { Unit } from "./unit";
|
||||
import { cloneUnit, deleteUnit, refreshAll, spawnAircrafts, spawnGroundUnits, spawnHelicopters, spawnNavyUnits } from "../server/server";
|
||||
import { bearingAndDistanceToLatLng, deg2rad, keyEventWasInInput, latLngToMercator, mToFt, mercatorToLatLng, msToKnots, polyContains, polygonArea, randomPointInPoly, randomUnitBlueprint } from "../other/utils";
|
||||
@@ -36,6 +36,8 @@ export class UnitsManager {
|
||||
document.addEventListener('importFromFile', () => this.importFromFile());
|
||||
document.addEventListener('contactsUpdated', (e: CustomEvent) => {this.#requestDetectionUpdate = true});
|
||||
document.addEventListener('commandModeOptionsChanged', () => {Object.values(this.#units).forEach((unit: Unit) => unit.updateVisibility())});
|
||||
document.addEventListener('selectedUnitsChangeSpeed', (e: any) => {this.selectedUnitsChangeSpeed(e.detail.type)});
|
||||
document.addEventListener('selectedUnitsChangeAltitude', (e: any) => {this.selectedUnitsChangeAltitude(e.detail.type)});
|
||||
}
|
||||
|
||||
getSelectableAircraft() {
|
||||
@@ -95,11 +97,11 @@ export class UnitsManager {
|
||||
if (this.#requestDetectionUpdate && getMissionHandler().getCommandModeOptions().commandMode != GAME_MASTER) {
|
||||
/* Create a dictionary of empty detection methods arrays */
|
||||
var detectionMethods: {[key: string]: number[]} = {};
|
||||
for (let ID in this.#units) {
|
||||
const unit = this.#units[ID];
|
||||
for (let ID in this.#units)
|
||||
detectionMethods[ID] = [];
|
||||
}
|
||||
|
||||
for (let ID in getWeaponsManager().getWeapons())
|
||||
detectionMethods[ID] = [];
|
||||
|
||||
/* Fill the array with the detection methods */
|
||||
for (let ID in this.#units) {
|
||||
const unit = this.#units[ID];
|
||||
@@ -107,7 +109,7 @@ export class UnitsManager {
|
||||
const contacts = unit.getContacts();
|
||||
contacts.forEach((contact: Contact) => {
|
||||
const contactID = contact.ID;
|
||||
if (!(detectionMethods[contactID].includes(contact.detectionMethod)))
|
||||
if (contactID in detectionMethods && !(detectionMethods[contactID].includes(contact.detectionMethod)))
|
||||
detectionMethods[contactID]?.push(contact.detectionMethod);
|
||||
})
|
||||
}
|
||||
@@ -116,7 +118,11 @@ export class UnitsManager {
|
||||
/* Set the detection methods for every unit */
|
||||
for (let ID in this.#units) {
|
||||
const unit = this.#units[ID];
|
||||
unit.setDetectionMethods(detectionMethods[ID]);
|
||||
unit?.setDetectionMethods(detectionMethods[ID]);
|
||||
}
|
||||
for (let ID in getWeaponsManager().getWeapons()) {
|
||||
const weapon = getWeaponsManager().getWeaponByID(parseInt(ID));
|
||||
weapon?.setDetectionMethods(detectionMethods[ID]);
|
||||
}
|
||||
|
||||
this.#requestDetectionUpdate = false;
|
||||
|
||||
@@ -202,7 +202,7 @@ export class Weapon extends CustomMarker {
|
||||
/* Force a redraw of the unit to reflect the new status of the detection methods */
|
||||
this.setHidden(true);
|
||||
this.#detectionMethods = newDetectionMethods;
|
||||
this.updateVisibility();
|
||||
this.#updateMarker();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,13 +6,11 @@ import { Contact } from "../@types/unit";
|
||||
|
||||
export class WeaponsManager {
|
||||
#weapons: { [ID: number]: Weapon };
|
||||
#requestDetectionUpdate: boolean = false;
|
||||
|
||||
constructor() {
|
||||
this.#weapons = {};
|
||||
|
||||
document.addEventListener("commandModeOptionsChanged", () => {Object.values(this.#weapons).forEach((weapon: Weapon) => weapon.updateVisibility())});
|
||||
document.addEventListener('contactsUpdated', (e: CustomEvent) => {this.#requestDetectionUpdate = true});
|
||||
}
|
||||
|
||||
getWeapons() {
|
||||
@@ -54,16 +52,6 @@ export class WeaponsManager {
|
||||
}
|
||||
this.#weapons[ID]?.setData(dataExtractor);
|
||||
}
|
||||
|
||||
if (this.#requestDetectionUpdate && getMissionHandler().getCommandModeOptions().commandMode != GAME_MASTER) {
|
||||
for (let ID in this.#weapons) {
|
||||
var weapon = this.#weapons[ID];
|
||||
if (!weapon.belongsToCommandedCoalition())
|
||||
weapon.setDetectionMethods(this.getWeaponDetectedMethods(weapon));
|
||||
}
|
||||
this.#requestDetectionUpdate = false;
|
||||
}
|
||||
|
||||
return updateTime;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<div id="app-summary">
|
||||
<h2>DCS Olympus</h2>
|
||||
<h4>Dynamic Unit Command</h4>
|
||||
<div class="app-version">Version <span class="app-version-number">v0.4.1-alpha</span></div>
|
||||
<div class="app-version">Version <span class="app-version-number">v0.4.2-alpha</span></div>
|
||||
</div>
|
||||
|
||||
<div id="authentication-form">
|
||||
|
||||
@@ -79,5 +79,13 @@
|
||||
<button class="ol-button-warning" data-on-click="deleteSelectedUnits"><img src="/resources/theme/images/icons/trash-can-regular.svg" inject-svg>Delete</button>
|
||||
<button class="ol-button-warning" data-on-click="explodeSelectedUnits"><img src="/resources/theme/images/icons/explosion-solid.svg" inject-svg></button>
|
||||
</div>
|
||||
|
||||
<div id="rapid-controls" class="ol-panel">
|
||||
<button title="Increase units altitude" class="ol-button" data-on-click="selectedUnitsChangeAltitude" data-on-click-params='{ "type": "climb" }'><img src="/resources/theme/images/icons/climb.svg" inject-svg></button>
|
||||
<button title="Descrease units altitude" class="ol-button" data-on-click="selectedUnitsChangeAltitude" data-on-click-params='{ "type": "descend" }'><img src="/resources/theme/images/icons/descent.svg" inject-svg></button>
|
||||
<button title="Increase units speed" class="ol-button" data-on-click="selectedUnitsChangeSpeed" data-on-click-params='{ "type": "fast" }'><img src="/resources/theme/images/icons/speed-increase.svg" inject-svg></button>
|
||||
<button title="Decrease units speed" class="ol-button" data-on-click="selectedUnitsChangeSpeed" data-on-click-params='{ "type": "slow" }'><img src="/resources/theme/images/icons/speed-decrease.svg" inject-svg></button>
|
||||
<button title="Stop unit and go back to idle state" class="ol-button" data-on-click="selectedUnitsChangeSpeed" data-on-click-params='{ "type": "stop" }'><img src="/resources/theme/images/icons/hand-solid.svg" inject-svg></button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -6,7 +6,7 @@
|
||||
<div class="ol-select-options">
|
||||
<div id="toolbar-summary">
|
||||
<h3>DCS Olympus</h3>
|
||||
<div class="accent-green app-version-number">version v0.4.1-alpha</div>
|
||||
<div class="accent-green app-version-number">version v0.4.2-alpha</div>
|
||||
</div>
|
||||
<div>
|
||||
<a href="https://www.discord.com" target="_blank">Discord</a>
|
||||
@@ -28,9 +28,7 @@
|
||||
|
||||
<div class="ol-group">
|
||||
<div id="map-type" class="ol-select">
|
||||
<div class="ol-select-value">
|
||||
<img src="resources/theme/images/icons/map-source.svg" inject-svg> ArcGIS Satellite
|
||||
</div>
|
||||
<div class="ol-select-value"><img src="resources/theme/images/icons/map-source.svg" inject-svg>ArcGIS Satellite</div>
|
||||
<div class="ol-select-options">
|
||||
<!-- Here the available map sources will be listed-->
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user