diff --git a/client/public/images/BEBlue.png b/client/public/images/BEBlue.png deleted file mode 100644 index 93338e8a..00000000 Binary files a/client/public/images/BEBlue.png and /dev/null differ diff --git a/client/public/images/BERed.png b/client/public/images/BERed.png deleted file mode 100644 index 367984f9..00000000 Binary files a/client/public/images/BERed.png and /dev/null differ diff --git a/client/public/images/banner.xcf b/client/public/images/banner.xcf deleted file mode 100644 index e6031764..00000000 Binary files a/client/public/images/banner.xcf and /dev/null differ diff --git a/client/public/images/buttons/ai-full.svg b/client/public/images/buttons/ai-full.svg deleted file mode 100644 index dc1537a2..00000000 --- a/client/public/images/buttons/ai-full.svg +++ /dev/null @@ -1,55 +0,0 @@ - - - - - - - - - diff --git a/client/public/images/buttons/ai-hidden.svg b/client/public/images/buttons/ai-hidden.svg deleted file mode 100644 index 41af77be..00000000 --- a/client/public/images/buttons/ai-hidden.svg +++ /dev/null @@ -1,47 +0,0 @@ - - - - - - - - diff --git a/client/public/images/buttons/ai-none.svg b/client/public/images/buttons/ai-none.svg deleted file mode 100644 index 71dccfeb..00000000 --- a/client/public/images/buttons/ai-none.svg +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - diff --git a/client/public/images/buttons/ai-partial.svg b/client/public/images/buttons/ai-partial.svg deleted file mode 100644 index 342f746c..00000000 --- a/client/public/images/buttons/ai-partial.svg +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - - - diff --git a/client/public/images/buttons/ai.svg b/client/public/images/buttons/ai.svg deleted file mode 100644 index 75075b45..00000000 --- a/client/public/images/buttons/ai.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/client/public/images/buttons/atc.svg b/client/public/images/buttons/atc.svg deleted file mode 100644 index 6bc33c3b..00000000 --- a/client/public/images/buttons/atc.svg +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - diff --git a/client/public/images/buttons/attack.png b/client/public/images/buttons/attack.png deleted file mode 100644 index c1a3e62a..00000000 Binary files a/client/public/images/buttons/attack.png and /dev/null differ diff --git a/client/public/images/buttons/climb.svg b/client/public/images/buttons/climb.svg deleted file mode 100644 index 234a1248..00000000 --- a/client/public/images/buttons/climb.svg +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - diff --git a/client/public/images/buttons/create.svg b/client/public/images/buttons/create.svg deleted file mode 100644 index bc76cb21..00000000 --- a/client/public/images/buttons/create.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/client/public/images/buttons/dead-hidden.svg b/client/public/images/buttons/dead-hidden.svg deleted file mode 100644 index 28299e3b..00000000 --- a/client/public/images/buttons/dead-hidden.svg +++ /dev/null @@ -1,47 +0,0 @@ - - - - - - - - diff --git a/client/public/images/buttons/dead.svg b/client/public/images/buttons/dead.svg deleted file mode 100644 index ae7e8e54..00000000 --- a/client/public/images/buttons/dead.svg +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - diff --git a/client/public/images/buttons/descend.svg b/client/public/images/buttons/descend.svg deleted file mode 100644 index dd8958c6..00000000 --- a/client/public/images/buttons/descend.svg +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - diff --git a/client/public/images/buttons/erase.svg b/client/public/images/buttons/erase.svg deleted file mode 100644 index f6588839..00000000 --- a/client/public/images/buttons/erase.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/client/public/images/buttons/fast.svg b/client/public/images/buttons/fast.svg deleted file mode 100644 index e62b23f0..00000000 --- a/client/public/images/buttons/fast.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/client/public/images/buttons/formation.png b/client/public/images/buttons/formation.png deleted file mode 100644 index e75ccea1..00000000 Binary files a/client/public/images/buttons/formation.png and /dev/null differ diff --git a/client/public/images/buttons/question-mark-circle.svg b/client/public/images/buttons/question-mark-circle.svg deleted file mode 100644 index 30dc78ec..00000000 --- a/client/public/images/buttons/question-mark-circle.svg +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - diff --git a/client/public/images/buttons/question-mark.svg b/client/public/images/buttons/question-mark.svg deleted file mode 100644 index 04520519..00000000 --- a/client/public/images/buttons/question-mark.svg +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - diff --git a/client/public/images/buttons/radar.svg b/client/public/images/buttons/radar.svg deleted file mode 100644 index 1d8f3dcd..00000000 --- a/client/public/images/buttons/radar.svg +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - diff --git a/client/public/images/buttons/rtb.png b/client/public/images/buttons/rtb.png deleted file mode 100644 index e35be5e8..00000000 Binary files a/client/public/images/buttons/rtb.png and /dev/null differ diff --git a/client/public/images/buttons/slow.svg b/client/public/images/buttons/slow.svg deleted file mode 100644 index 9579b19b..00000000 --- a/client/public/images/buttons/slow.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/client/public/images/buttons/spawnAWACS.png b/client/public/images/buttons/spawnAWACS.png deleted file mode 100644 index b325f4ad..00000000 Binary files a/client/public/images/buttons/spawnAWACS.png and /dev/null differ diff --git a/client/public/images/buttons/spawnAir.png b/client/public/images/buttons/spawnAir.png deleted file mode 100644 index 292ffe3e..00000000 Binary files a/client/public/images/buttons/spawnAir.png and /dev/null differ diff --git a/client/public/images/buttons/spawnCAP.png b/client/public/images/buttons/spawnCAP.png deleted file mode 100644 index ae78e677..00000000 Binary files a/client/public/images/buttons/spawnCAP.png and /dev/null differ diff --git a/client/public/images/buttons/spawnCAS.png b/client/public/images/buttons/spawnCAS.png deleted file mode 100644 index 315bd363..00000000 Binary files a/client/public/images/buttons/spawnCAS.png and /dev/null differ diff --git a/client/public/images/buttons/spawnDrone.png b/client/public/images/buttons/spawnDrone.png deleted file mode 100644 index 98beca17..00000000 Binary files a/client/public/images/buttons/spawnDrone.png and /dev/null differ diff --git a/client/public/images/buttons/spawnExplosion.png b/client/public/images/buttons/spawnExplosion.png deleted file mode 100644 index d61cdf53..00000000 Binary files a/client/public/images/buttons/spawnExplosion.png and /dev/null differ diff --git a/client/public/images/buttons/spawnGround.png b/client/public/images/buttons/spawnGround.png deleted file mode 100644 index 1c421d0f..00000000 Binary files a/client/public/images/buttons/spawnGround.png and /dev/null differ diff --git a/client/public/images/buttons/spawnHowitzer.png b/client/public/images/buttons/spawnHowitzer.png deleted file mode 100644 index 6197a0c6..00000000 Binary files a/client/public/images/buttons/spawnHowitzer.png and /dev/null differ diff --git a/client/public/images/buttons/spawnIFV.png b/client/public/images/buttons/spawnIFV.png deleted file mode 100644 index 77c89ad3..00000000 Binary files a/client/public/images/buttons/spawnIFV.png and /dev/null differ diff --git a/client/public/images/buttons/spawnMLRS.png b/client/public/images/buttons/spawnMLRS.png deleted file mode 100644 index 213befc7..00000000 Binary files a/client/public/images/buttons/spawnMLRS.png and /dev/null differ diff --git a/client/public/images/buttons/spawnRadar.png b/client/public/images/buttons/spawnRadar.png deleted file mode 100644 index d87470c3..00000000 Binary files a/client/public/images/buttons/spawnRadar.png and /dev/null differ diff --git a/client/public/images/buttons/spawnSAM.png b/client/public/images/buttons/spawnSAM.png deleted file mode 100644 index 9d7451e1..00000000 Binary files a/client/public/images/buttons/spawnSAM.png and /dev/null differ diff --git a/client/public/images/buttons/spawnSmoke.png b/client/public/images/buttons/spawnSmoke.png deleted file mode 100644 index 53d82f8f..00000000 Binary files a/client/public/images/buttons/spawnSmoke.png and /dev/null differ diff --git a/client/public/images/buttons/spawnStrike.png b/client/public/images/buttons/spawnStrike.png deleted file mode 100644 index 1cba2589..00000000 Binary files a/client/public/images/buttons/spawnStrike.png and /dev/null differ diff --git a/client/public/images/buttons/spawnTank.png b/client/public/images/buttons/spawnTank.png deleted file mode 100644 index f016b64e..00000000 Binary files a/client/public/images/buttons/spawnTank.png and /dev/null differ diff --git a/client/public/images/buttons/spawnTanker.png b/client/public/images/buttons/spawnTanker.png deleted file mode 100644 index 374fb248..00000000 Binary files a/client/public/images/buttons/spawnTanker.png and /dev/null differ diff --git a/client/public/images/buttons/spawnTransport.png b/client/public/images/buttons/spawnTransport.png deleted file mode 100644 index b5932d58..00000000 Binary files a/client/public/images/buttons/spawnTransport.png and /dev/null differ diff --git a/client/public/images/buttons/spawnUnarmed.png b/client/public/images/buttons/spawnUnarmed.png deleted file mode 100644 index 8aabc9e7..00000000 Binary files a/client/public/images/buttons/spawnUnarmed.png and /dev/null differ diff --git a/client/public/images/buttons/tanker.png b/client/public/images/buttons/tanker.png deleted file mode 100644 index 86677ffe..00000000 Binary files a/client/public/images/buttons/tanker.png and /dev/null differ diff --git a/client/public/images/buttons/user-full.svg b/client/public/images/buttons/user-full.svg deleted file mode 100644 index b629abe4..00000000 --- a/client/public/images/buttons/user-full.svg +++ /dev/null @@ -1,55 +0,0 @@ - - - - - - - - - diff --git a/client/public/images/buttons/user-hidden.svg b/client/public/images/buttons/user-hidden.svg deleted file mode 100644 index e2bcf458..00000000 --- a/client/public/images/buttons/user-hidden.svg +++ /dev/null @@ -1,47 +0,0 @@ - - - - - - - - diff --git a/client/public/images/buttons/user-none.svg b/client/public/images/buttons/user-none.svg deleted file mode 100644 index 55bc1337..00000000 --- a/client/public/images/buttons/user-none.svg +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - diff --git a/client/public/images/buttons/user-partial.svg b/client/public/images/buttons/user-partial.svg deleted file mode 100644 index 503b92e1..00000000 --- a/client/public/images/buttons/user-partial.svg +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - - - diff --git a/client/public/images/buttons/weapon-hidden.svg b/client/public/images/buttons/weapon-hidden.svg deleted file mode 100644 index 0bfa5905..00000000 --- a/client/public/images/buttons/weapon-hidden.svg +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - - - - - diff --git a/client/public/images/buttons/weapon-none.svg b/client/public/images/buttons/weapon-none.svg deleted file mode 100644 index ad4d9a98..00000000 --- a/client/public/images/buttons/weapon-none.svg +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - - - - diff --git a/client/public/images/buttons/weapon-partial.svg b/client/public/images/buttons/weapon-partial.svg deleted file mode 100644 index c925639b..00000000 --- a/client/public/images/buttons/weapon-partial.svg +++ /dev/null @@ -1,58 +0,0 @@ - - - - - - - - - - diff --git a/client/public/images/buttons/wheelButtons.xcf b/client/public/images/buttons/wheelButtons.xcf deleted file mode 100644 index 5ef9f1f3..00000000 Binary files a/client/public/images/buttons/wheelButtons.xcf and /dev/null differ diff --git a/client/public/images/icon.png b/client/public/images/icon.png new file mode 100644 index 00000000..dc5c994e Binary files /dev/null and b/client/public/images/icon.png differ diff --git a/client/public/images/patch.png b/client/public/images/patch.png deleted file mode 100644 index 46b43691..00000000 Binary files a/client/public/images/patch.png and /dev/null differ diff --git a/client/public/images/units/a-10.png b/client/public/images/units/a-10.png deleted file mode 100644 index 643dd5aa..00000000 Binary files a/client/public/images/units/a-10.png and /dev/null differ diff --git a/client/public/images/units/a-20.png b/client/public/images/units/a-20.png deleted file mode 100644 index 4981c90b..00000000 Binary files a/client/public/images/units/a-20.png and /dev/null differ diff --git a/client/public/images/units/a-29.png b/client/public/images/units/a-29.png deleted file mode 100644 index 91ad25f0..00000000 Binary files a/client/public/images/units/a-29.png and /dev/null differ diff --git a/client/public/images/units/a-4.png b/client/public/images/units/a-4.png deleted file mode 100644 index 499cc11e..00000000 Binary files a/client/public/images/units/a-4.png and /dev/null differ diff --git a/client/public/images/units/a-400.png b/client/public/images/units/a-400.png deleted file mode 100644 index e76ab232..00000000 Binary files a/client/public/images/units/a-400.png and /dev/null differ diff --git a/client/public/images/units/a-50.png b/client/public/images/units/a-50.png deleted file mode 100644 index f08e39a0..00000000 Binary files a/client/public/images/units/a-50.png and /dev/null differ diff --git a/client/public/images/units/a-6.png b/client/public/images/units/a-6.png deleted file mode 100644 index d5007ccd..00000000 Binary files a/client/public/images/units/a-6.png and /dev/null differ diff --git a/client/public/images/units/ah-1.png b/client/public/images/units/ah-1.png deleted file mode 100644 index 5da53ddd..00000000 Binary files a/client/public/images/units/ah-1.png and /dev/null differ diff --git a/client/public/images/units/ah-64.png b/client/public/images/units/ah-64.png deleted file mode 100644 index fa1c98b5..00000000 Binary files a/client/public/images/units/ah-64.png and /dev/null differ diff --git a/client/public/images/units/airUnit.png b/client/public/images/units/airUnit.png deleted file mode 100644 index 70c8db7e..00000000 Binary files a/client/public/images/units/airUnit.png and /dev/null differ diff --git a/client/public/images/units/airliner2engine.png b/client/public/images/units/airliner2engine.png deleted file mode 100644 index 3c8bd4de..00000000 Binary files a/client/public/images/units/airliner2engine.png and /dev/null differ diff --git a/client/public/images/units/an-26.png b/client/public/images/units/an-26.png deleted file mode 100644 index 8b4bd491..00000000 Binary files a/client/public/images/units/an-26.png and /dev/null differ diff --git a/client/public/images/units/av8bna.png b/client/public/images/units/av8bna.png deleted file mode 100644 index 0bb13672..00000000 Binary files a/client/public/images/units/av8bna.png and /dev/null differ diff --git a/client/public/images/units/b-1.png b/client/public/images/units/b-1.png deleted file mode 100644 index 05329ddf..00000000 Binary files a/client/public/images/units/b-1.png and /dev/null differ diff --git a/client/public/images/units/b-17.png b/client/public/images/units/b-17.png deleted file mode 100644 index 400dfbc5..00000000 Binary files a/client/public/images/units/b-17.png and /dev/null differ diff --git a/client/public/images/units/b-2.png b/client/public/images/units/b-2.png deleted file mode 100644 index 3b85f3af..00000000 Binary files a/client/public/images/units/b-2.png and /dev/null differ diff --git a/client/public/images/units/b-52.png b/client/public/images/units/b-52.png deleted file mode 100644 index 34d8840b..00000000 Binary files a/client/public/images/units/b-52.png and /dev/null differ diff --git a/client/public/images/units/b707.png b/client/public/images/units/b707.png deleted file mode 100644 index 3771fc63..00000000 Binary files a/client/public/images/units/b707.png and /dev/null differ diff --git a/client/public/images/units/bf109.png b/client/public/images/units/bf109.png deleted file mode 100644 index 40da1dfd..00000000 Binary files a/client/public/images/units/bf109.png and /dev/null differ diff --git a/client/public/images/units/bomb.png b/client/public/images/units/bomb.png deleted file mode 100644 index 81416cbb..00000000 Binary files a/client/public/images/units/bomb.png and /dev/null differ diff --git a/client/public/images/units/c-101.png b/client/public/images/units/c-101.png deleted file mode 100644 index 8b5468b8..00000000 Binary files a/client/public/images/units/c-101.png and /dev/null differ diff --git a/client/public/images/units/c-130.png b/client/public/images/units/c-130.png deleted file mode 100644 index f69cb0c2..00000000 Binary files a/client/public/images/units/c-130.png and /dev/null differ diff --git a/client/public/images/units/c-17.png b/client/public/images/units/c-17.png deleted file mode 100644 index c2b8855c..00000000 Binary files a/client/public/images/units/c-17.png and /dev/null differ diff --git a/client/public/images/units/c-5.png b/client/public/images/units/c-5.png deleted file mode 100644 index e2823289..00000000 Binary files a/client/public/images/units/c-5.png and /dev/null differ diff --git a/client/public/images/units/ch-47.png b/client/public/images/units/ch-47.png deleted file mode 100644 index 16f178ca..00000000 Binary files a/client/public/images/units/ch-47.png and /dev/null differ diff --git a/client/public/images/units/ch-53.png b/client/public/images/units/ch-53.png deleted file mode 100644 index e67f108c..00000000 Binary files a/client/public/images/units/ch-53.png and /dev/null differ diff --git a/client/public/images/units/christeneagleii.png b/client/public/images/units/christeneagleii.png deleted file mode 100644 index b1874dd2..00000000 Binary files a/client/public/images/units/christeneagleii.png and /dev/null differ diff --git a/client/public/images/units/e-2.png b/client/public/images/units/e-2.png deleted file mode 100644 index fc178272..00000000 Binary files a/client/public/images/units/e-2.png and /dev/null differ diff --git a/client/public/images/units/e-3.png b/client/public/images/units/e-3.png deleted file mode 100644 index bcce5b6c..00000000 Binary files a/client/public/images/units/e-3.png and /dev/null differ diff --git a/client/public/images/units/eurofighter.png b/client/public/images/units/eurofighter.png deleted file mode 100644 index cf39e7f8..00000000 Binary files a/client/public/images/units/eurofighter.png and /dev/null differ diff --git a/client/public/images/units/f-111.png b/client/public/images/units/f-111.png deleted file mode 100644 index ae06b171..00000000 Binary files a/client/public/images/units/f-111.png and /dev/null differ diff --git a/client/public/images/units/f-117.png b/client/public/images/units/f-117.png deleted file mode 100644 index 2f099b28..00000000 Binary files a/client/public/images/units/f-117.png and /dev/null differ diff --git a/client/public/images/units/f-14.png b/client/public/images/units/f-14.png deleted file mode 100644 index 662def75..00000000 Binary files a/client/public/images/units/f-14.png and /dev/null differ diff --git a/client/public/images/units/f-15.png b/client/public/images/units/f-15.png deleted file mode 100644 index a3b56c6c..00000000 Binary files a/client/public/images/units/f-15.png and /dev/null differ diff --git a/client/public/images/units/f-16.png b/client/public/images/units/f-16.png deleted file mode 100644 index 3adbba10..00000000 Binary files a/client/public/images/units/f-16.png and /dev/null differ diff --git a/client/public/images/units/f-18.png b/client/public/images/units/f-18.png deleted file mode 100644 index b1f28359..00000000 Binary files a/client/public/images/units/f-18.png and /dev/null differ diff --git a/client/public/images/units/f-22.png b/client/public/images/units/f-22.png deleted file mode 100644 index af909ad4..00000000 Binary files a/client/public/images/units/f-22.png and /dev/null differ diff --git a/client/public/images/units/f-35.png b/client/public/images/units/f-35.png deleted file mode 100644 index 6c9d0909..00000000 Binary files a/client/public/images/units/f-35.png and /dev/null differ diff --git a/client/public/images/units/f-4.png b/client/public/images/units/f-4.png deleted file mode 100644 index 21cfc750..00000000 Binary files a/client/public/images/units/f-4.png and /dev/null differ diff --git a/client/public/images/units/f-5.png b/client/public/images/units/f-5.png deleted file mode 100644 index ef276090..00000000 Binary files a/client/public/images/units/f-5.png and /dev/null differ diff --git a/client/public/images/units/f-86.png b/client/public/images/units/f-86.png deleted file mode 100644 index 198a968a..00000000 Binary files a/client/public/images/units/f-86.png and /dev/null differ diff --git a/client/public/images/units/fw190.png b/client/public/images/units/fw190.png deleted file mode 100644 index 0020b176..00000000 Binary files a/client/public/images/units/fw190.png and /dev/null differ diff --git a/client/public/images/units/general1.png b/client/public/images/units/general1.png deleted file mode 100644 index bf8bf272..00000000 Binary files a/client/public/images/units/general1.png and /dev/null differ diff --git a/client/public/images/units/gripen.png b/client/public/images/units/gripen.png deleted file mode 100644 index bd58818e..00000000 Binary files a/client/public/images/units/gripen.png and /dev/null differ diff --git a/client/public/images/units/groundUnit.png b/client/public/images/units/groundUnit.png deleted file mode 100644 index 8c6ef4ad..00000000 Binary files a/client/public/images/units/groundUnit.png and /dev/null differ diff --git a/client/public/images/units/h-6.png b/client/public/images/units/h-6.png deleted file mode 100644 index d73b5e3a..00000000 Binary files a/client/public/images/units/h-6.png and /dev/null differ diff --git a/client/public/images/units/hawk.png b/client/public/images/units/hawk.png deleted file mode 100644 index c1fdd943..00000000 Binary files a/client/public/images/units/hawk.png and /dev/null differ diff --git a/client/public/images/units/helicopter1.png b/client/public/images/units/helicopter1.png deleted file mode 100644 index 316d3ad9..00000000 Binary files a/client/public/images/units/helicopter1.png and /dev/null differ diff --git a/client/public/images/units/i-16.png b/client/public/images/units/i-16.png deleted file mode 100644 index 53335809..00000000 Binary files a/client/public/images/units/i-16.png and /dev/null differ diff --git a/client/public/images/units/il-76.png b/client/public/images/units/il-76.png deleted file mode 100644 index bcb145a2..00000000 Binary files a/client/public/images/units/il-76.png and /dev/null differ diff --git a/client/public/images/units/j-10.png b/client/public/images/units/j-10.png deleted file mode 100644 index 1521dbb7..00000000 Binary files a/client/public/images/units/j-10.png and /dev/null differ diff --git a/client/public/images/units/j-20.png b/client/public/images/units/j-20.png deleted file mode 100644 index df0b9498..00000000 Binary files a/client/public/images/units/j-20.png and /dev/null differ diff --git a/client/public/images/units/j-7.png b/client/public/images/units/j-7.png deleted file mode 100644 index bbf8040a..00000000 Binary files a/client/public/images/units/j-7.png and /dev/null differ diff --git a/client/public/images/units/jf-17.png b/client/public/images/units/jf-17.png deleted file mode 100644 index 3e2e6fab..00000000 Binary files a/client/public/images/units/jf-17.png and /dev/null differ diff --git a/client/public/images/units/ju-88.png b/client/public/images/units/ju-88.png deleted file mode 100644 index 287ca2ce..00000000 Binary files a/client/public/images/units/ju-88.png and /dev/null differ diff --git a/client/public/images/units/ka-27.png b/client/public/images/units/ka-27.png deleted file mode 100644 index d0ad1c12..00000000 Binary files a/client/public/images/units/ka-27.png and /dev/null differ diff --git a/client/public/images/units/ka-50.png b/client/public/images/units/ka-50.png deleted file mode 100644 index a75983e9..00000000 Binary files a/client/public/images/units/ka-50.png and /dev/null differ diff --git a/client/public/images/units/kc-10.png b/client/public/images/units/kc-10.png deleted file mode 100644 index 7d9e4db9..00000000 Binary files a/client/public/images/units/kc-10.png and /dev/null differ diff --git a/client/public/images/units/kc-135.png b/client/public/images/units/kc-135.png deleted file mode 100644 index bbf5ff5b..00000000 Binary files a/client/public/images/units/kc-135.png and /dev/null differ diff --git a/client/public/images/units/l-159.png b/client/public/images/units/l-159.png deleted file mode 100644 index ba6461f9..00000000 Binary files a/client/public/images/units/l-159.png and /dev/null differ diff --git a/client/public/images/units/l-39.png b/client/public/images/units/l-39.png deleted file mode 100644 index c2ef1d07..00000000 Binary files a/client/public/images/units/l-39.png and /dev/null differ diff --git a/client/public/images/units/listNames.py b/client/public/images/units/listNames.py deleted file mode 100644 index 8f23620a..00000000 --- a/client/public/images/units/listNames.py +++ /dev/null @@ -1,5 +0,0 @@ -from os import listdir -from os.path import isfile, join -onlyfiles = [f for f in listdir(".") if isfile(join(".", f))] - -print(onlyfiles) \ No newline at end of file diff --git a/client/public/images/units/m2000.png b/client/public/images/units/m2000.png deleted file mode 100644 index 8a9ffd48..00000000 Binary files a/client/public/images/units/m2000.png and /dev/null differ diff --git a/client/public/images/units/mi-24.png b/client/public/images/units/mi-24.png deleted file mode 100644 index 9a148550..00000000 Binary files a/client/public/images/units/mi-24.png and /dev/null differ diff --git a/client/public/images/units/mi-26.png b/client/public/images/units/mi-26.png deleted file mode 100644 index b59c9b8d..00000000 Binary files a/client/public/images/units/mi-26.png and /dev/null differ diff --git a/client/public/images/units/mi-28.png b/client/public/images/units/mi-28.png deleted file mode 100644 index 9e5db2ca..00000000 Binary files a/client/public/images/units/mi-28.png and /dev/null differ diff --git a/client/public/images/units/mi-8.png b/client/public/images/units/mi-8.png deleted file mode 100644 index f42706e7..00000000 Binary files a/client/public/images/units/mi-8.png and /dev/null differ diff --git a/client/public/images/units/mig-15.png b/client/public/images/units/mig-15.png deleted file mode 100644 index b97ef8c9..00000000 Binary files a/client/public/images/units/mig-15.png and /dev/null differ diff --git a/client/public/images/units/mig-19.png b/client/public/images/units/mig-19.png deleted file mode 100644 index 046e6a0f..00000000 Binary files a/client/public/images/units/mig-19.png and /dev/null differ diff --git a/client/public/images/units/mig-21.png b/client/public/images/units/mig-21.png deleted file mode 100644 index 12056218..00000000 Binary files a/client/public/images/units/mig-21.png and /dev/null differ diff --git a/client/public/images/units/mig-23.png b/client/public/images/units/mig-23.png deleted file mode 100644 index 6fabd9c3..00000000 Binary files a/client/public/images/units/mig-23.png and /dev/null differ diff --git a/client/public/images/units/mig-25.png b/client/public/images/units/mig-25.png deleted file mode 100644 index cf8c46ca..00000000 Binary files a/client/public/images/units/mig-25.png and /dev/null differ diff --git a/client/public/images/units/mig-29.png b/client/public/images/units/mig-29.png deleted file mode 100644 index 634cbcc7..00000000 Binary files a/client/public/images/units/mig-29.png and /dev/null differ diff --git a/client/public/images/units/missile.png b/client/public/images/units/missile.png deleted file mode 100644 index ef547853..00000000 Binary files a/client/public/images/units/missile.png and /dev/null differ diff --git a/client/public/images/units/mosquito.png b/client/public/images/units/mosquito.png deleted file mode 100644 index 5d1ed6d0..00000000 Binary files a/client/public/images/units/mosquito.png and /dev/null differ diff --git a/client/public/images/units/multiengine.png b/client/public/images/units/multiengine.png deleted file mode 100644 index 34eab23a..00000000 Binary files a/client/public/images/units/multiengine.png and /dev/null differ diff --git a/client/public/images/units/navyUnit.png b/client/public/images/units/navyUnit.png deleted file mode 100644 index 8c6ef4ad..00000000 Binary files a/client/public/images/units/navyUnit.png and /dev/null differ diff --git a/client/public/images/units/oh-58.png b/client/public/images/units/oh-58.png deleted file mode 100644 index 50af43c7..00000000 Binary files a/client/public/images/units/oh-58.png and /dev/null differ diff --git a/client/public/images/units/p-47.png b/client/public/images/units/p-47.png deleted file mode 100644 index 1b5ae7d4..00000000 Binary files a/client/public/images/units/p-47.png and /dev/null differ diff --git a/client/public/images/units/p-51.png b/client/public/images/units/p-51.png deleted file mode 100644 index 4c7f4986..00000000 Binary files a/client/public/images/units/p-51.png and /dev/null differ diff --git a/client/public/images/units/rafale.png b/client/public/images/units/rafale.png deleted file mode 100644 index 367190f4..00000000 Binary files a/client/public/images/units/rafale.png and /dev/null differ diff --git a/client/public/images/units/rq-1.png b/client/public/images/units/rq-1.png deleted file mode 100644 index 6f45ed10..00000000 Binary files a/client/public/images/units/rq-1.png and /dev/null differ diff --git a/client/public/images/units/rq-4.png b/client/public/images/units/rq-4.png deleted file mode 100644 index 210862ab..00000000 Binary files a/client/public/images/units/rq-4.png and /dev/null differ diff --git a/client/public/images/units/s-3.png b/client/public/images/units/s-3.png deleted file mode 100644 index 7a6feb8d..00000000 Binary files a/client/public/images/units/s-3.png and /dev/null differ diff --git a/client/public/images/units/sa-342.png b/client/public/images/units/sa-342.png deleted file mode 100644 index f258c184..00000000 Binary files a/client/public/images/units/sa-342.png and /dev/null differ diff --git a/client/public/images/units/spitfire.png b/client/public/images/units/spitfire.png deleted file mode 100644 index 70e9e082..00000000 Binary files a/client/public/images/units/spitfire.png and /dev/null differ diff --git a/client/public/images/units/su-17.png b/client/public/images/units/su-17.png deleted file mode 100644 index 2c27b28b..00000000 Binary files a/client/public/images/units/su-17.png and /dev/null differ diff --git a/client/public/images/units/su-24.png b/client/public/images/units/su-24.png deleted file mode 100644 index 134650ec..00000000 Binary files a/client/public/images/units/su-24.png and /dev/null differ diff --git a/client/public/images/units/su-25.png b/client/public/images/units/su-25.png deleted file mode 100644 index a45fa129..00000000 Binary files a/client/public/images/units/su-25.png and /dev/null differ diff --git a/client/public/images/units/su-27.png b/client/public/images/units/su-27.png deleted file mode 100644 index 81a2ede8..00000000 Binary files a/client/public/images/units/su-27.png and /dev/null differ diff --git a/client/public/images/units/su-34.png b/client/public/images/units/su-34.png deleted file mode 100644 index 44bdc779..00000000 Binary files a/client/public/images/units/su-34.png and /dev/null differ diff --git a/client/public/images/units/su-57.png b/client/public/images/units/su-57.png deleted file mode 100644 index 02dc88a0..00000000 Binary files a/client/public/images/units/su-57.png and /dev/null differ diff --git a/client/public/images/units/tornado.png b/client/public/images/units/tornado.png deleted file mode 100644 index 54ded406..00000000 Binary files a/client/public/images/units/tornado.png and /dev/null differ diff --git a/client/public/images/units/tu-160.png b/client/public/images/units/tu-160.png deleted file mode 100644 index d0292504..00000000 Binary files a/client/public/images/units/tu-160.png and /dev/null differ diff --git a/client/public/images/units/tu-22.png b/client/public/images/units/tu-22.png deleted file mode 100644 index 61e15edd..00000000 Binary files a/client/public/images/units/tu-22.png and /dev/null differ diff --git a/client/public/images/units/tu-95.png b/client/public/images/units/tu-95.png deleted file mode 100644 index 7ce802b4..00000000 Binary files a/client/public/images/units/tu-95.png and /dev/null differ diff --git a/client/public/images/units/u-28.png b/client/public/images/units/u-28.png deleted file mode 100644 index e31aedb7..00000000 Binary files a/client/public/images/units/u-28.png and /dev/null differ diff --git a/client/public/images/units/uh-1.png b/client/public/images/units/uh-1.png deleted file mode 100644 index 163cac89..00000000 Binary files a/client/public/images/units/uh-1.png and /dev/null differ diff --git a/client/public/images/units/uh-60.png b/client/public/images/units/uh-60.png deleted file mode 100644 index 7d436c8a..00000000 Binary files a/client/public/images/units/uh-60.png and /dev/null differ diff --git a/client/public/images/units/unit.png b/client/public/images/units/unit.png deleted file mode 100644 index 8c6ef4ad..00000000 Binary files a/client/public/images/units/unit.png and /dev/null differ diff --git a/client/public/images/units/viggen.png b/client/public/images/units/viggen.png deleted file mode 100644 index 47708c3f..00000000 Binary files a/client/public/images/units/viggen.png and /dev/null differ diff --git a/client/public/images/units/yak-40.png b/client/public/images/units/yak-40.png deleted file mode 100644 index b562fe59..00000000 Binary files a/client/public/images/units/yak-40.png and /dev/null differ diff --git a/client/public/images/units/yak-52.png b/client/public/images/units/yak-52.png deleted file mode 100644 index 5728f6e8..00000000 Binary files a/client/public/images/units/yak-52.png and /dev/null differ diff --git a/client/public/stylesheets/button.css b/client/public/stylesheets/button.css deleted file mode 100644 index d5910387..00000000 --- a/client/public/stylesheets/button.css +++ /dev/null @@ -1,17 +0,0 @@ -.ol-button { - width: 24px; - height: 24px; - background-color: transparent; - cursor: pointer; - display: flex; - align-items: center; -} - -.ol-button img { - width: 24px; - height: 24px; -} - -.ol-button:hover {} - -.ol-button:active {} \ No newline at end of file diff --git a/client/public/stylesheets/connectionstatuspanel.css b/client/public/stylesheets/connectionstatuspanel.css deleted file mode 100644 index 6acc1021..00000000 --- a/client/public/stylesheets/connectionstatuspanel.css +++ /dev/null @@ -1,33 +0,0 @@ -#connection-status-panel { - display: flex; - align-items: center; - padding-left: 15px; - padding-right: 4px; -} - -#status-string { - font-size: 14px; - color: white; -} - -.ol-status-disconnected::after { - content: ""; - position: absolute; - right: 5px; - top: 5px; - border-radius: 50%; - width: 20px; - height: 20px; - background-color: red; -} - -.ol-status-connected::after { - content: ""; - position: absolute; - right: 5px; - top: 5px; - border-radius: 50%; - width: 20px; - height: 20px; - background-color: 00FF00; -} \ No newline at end of file diff --git a/client/public/stylesheets/contextmenu.css b/client/public/stylesheets/contextmenu.css index 2073d2de..92508bc9 100644 --- a/client/public/stylesheets/contextmenu.css +++ b/client/public/stylesheets/contextmenu.css @@ -1,119 +1,55 @@ -.ol-selection-scroll-container { +#contextmenu { position: absolute; - font-size: 12px; - border-radius: 5px; - width: 220px; - height: fit-content; - z-index: 2000; - padding: 8px; +} + +.ol-contextmenu { display: flex; flex-direction: column; row-gap: 5px; - align-items: center; + width: 200px; + height: fit-content; + z-index: 1000; } -#ol-selection-scroll-top-bar { - color: white; - font-size: 14px; - opacity: 1; - border-radius: 5px; - padding: 5px; - background-color: #333D; - width: 100%; - text-align: center; +.ol-contextmenu>div:first-child{ display: flex; - align-items: center; + flex-direction: row; justify-content: space-between; - height: 40px; - padding-left: 15px; - padding-right: 15px; + align-items: center; } -.ol-selection-scroll { +.ol-contextmenu>ul{ + max-height: 200px; overflow-x: hidden; overflow-y: auto; - height: 100%; - width: 100%; - max-height: 400px; } -.ol-selection-scroll::-webkit-scrollbar { +.ol-contextmenu .ol-panel { + width: 100%; + border-radius: var(--border-radius-sm); +} + +.ol-contextmenu ul { + margin: 0px; +} + +.ol-contextmenu button { + width: 100%; + text-align: left; +} + +.ol-contextmenu>ul::-webkit-scrollbar { width: 10px; } -.ol-selection-scroll::-webkit-scrollbar-track { +.ol-contextmenu>ul::-webkit-scrollbar-track { background-color: transparent; border-radius: 100px; } -.ol-selection-scroll::-webkit-scrollbar-thumb { +.ol-contextmenu>ul::-webkit-scrollbar-thumb { background-color: white; border-radius: 100px; opacity: 0.8; margin-top: 10px; } - -.ol-selection-scroll-element { - border-bottom: 1px solid #FFF5; - color: white; - cursor: pointer; - font-size: 13px; - opacity: 1; - padding-top: 10px; - padding-bottom: 10px; - padding-left: 15px; - background-color: var(--background-color-dark); - font-weight: 600; -} - -.ol-selection-scroll:last-child { - border-radius: 5px; - border-bottom: 0px transparent !important; -} - -.ol-selection-scroll-container label { - display: inline-block; - width: 40px; - height: 24px; -} - -.ol-selection-scroll-container input { - display: inline-block; - width: 0; - height: 0; - margin: 0px; -} - -.ol-selection-scroll-switch { - position: relative; - display: inline-block; - width: 40px; - height: 24px; - background-color: var(--active-coalition-color); - border-radius: 999px; - cursor: pointer; -} - -.ol-selection-scroll-switch:before { - position: absolute; - content: ""; - height: 16px; - width: 16px; - left: 4px; - bottom: 4px; - background-color: white; - -webkit-transition: 0.2s; - transition: 0.2s; - border-radius: 999px; -} - -input:checked+.ol-selection-scroll-switch:before { - -webkit-transform: translateX(16px); - -ms-transform: translateX(16px); - transform: translateX(16px); -} - -.ol-selection-scroll-title { - font-size: 11px; - font-weight: 600; -} \ No newline at end of file diff --git a/client/public/stylesheets/dropdown.css b/client/public/stylesheets/dropdown.css deleted file mode 100644 index ca735077..00000000 --- a/client/public/stylesheets/dropdown.css +++ /dev/null @@ -1,90 +0,0 @@ -.ol-dropdown { - width: 100%; - min-width: 100px; - height: 30px; - position: relative; - background-color: #DDDD; - z-index: 1000; - border-radius: 15px; - font-family: Verdana, Geneva, Tahoma, sans-serif; - color: var(--background-color-dark); - padding-left: 5px; - align-items: center; - cursor: pointer; - font-size: 13px; - display: flex; - text-shadow: none; - box-shadow: 0px 2px 5px #000A; - padding-left: 15px; -} - -.ol-dropdown::before { - content: ""; - position: absolute; - height: 30px; - width: 30px; - top: 0px; - right: 0px; - background-color: var(--background-color-dark); - z-index: 1000; - border-top-right-radius: 15px; - border-bottom-right-radius: 15px; -} - -.ol-dropdown-open { - border-bottom-left-radius: 0px; -} - -.ol-dropdown-open::after { - content: ""; - position: absolute; - top: 13px; - right: 11px; - height: 1px; - width: 1px; - border: solid white; - border-width: 0 3px 3px 0; - padding: 3px; - z-index: 1000; - transform: rotate(-135deg); - -webkit-transform: rotate(-135deg); -} - -.ol-dropdown-closed::after { - content: ""; - position: absolute; - top: 9px; - right: 11px; - height: 1px; - width: 1px; - border: solid white; - border-width: 0 3px 3px 0; - padding: 3px; - z-index: 1000; - transform: rotate(45deg); - -webkit-transform: rotate(45deg); -} - -.ol-dropdown-content { - position: fixed; - /*overflow: visible; - overflow-y: scroll;*/ - background-color: #DDDD; - z-index: 2000; - border-bottom-left-radius: 4px; - border-bottom-right-radius: 4px; -} - -.ol-dropdown-element { - margin: 2px; - font-family: Verdana, Geneva, Tahoma, sans-serif; - color: var(--background-color-dark); - cursor: pointer; - opacity: 1; - font-size: 13px; - padding-left: 5px; -} - -.ol-dropdown-element:hover { - background-color: var(--highlight-color); -} \ No newline at end of file diff --git a/client/public/stylesheets/elements.css b/client/public/stylesheets/elements.css deleted file mode 100644 index 570c8c95..00000000 --- a/client/public/stylesheets/elements.css +++ /dev/null @@ -1,14 +0,0 @@ -.ol-element-1 { - background-color: #247be2; - height: 28; - border-radius: 14px; - display: flex; - align-items: center; - justify-content: center; - color: white; - font-size: 14px; -} - -.bottom-separator { - border-bottom: 1px solid gray; -} \ No newline at end of file diff --git a/client/public/stylesheets/layout.css b/client/public/stylesheets/layout.css index 92fb41e8..4a617991 100644 --- a/client/public/stylesheets/layout.css +++ b/client/public/stylesheets/layout.css @@ -1,5 +1,16 @@ /* Page style */ +* { + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; +} + + +html { + font-family: 'Open Sans', sans-serif; +} + body { display:grid; margin: 0; @@ -20,49 +31,21 @@ body { #unit-info-panel { position: fixed; - height: 160px; - width: 800px; left: 10px; bottom: 10px; z-index: 1000; } -#map-source-dropdown { +#settings-panel { position: absolute; left: 10px; - top: 10px; - width: 200px; - color: black; -} - -#scenario-dropdown { - position: absolute; - left: 220px; - top: 10px; - width: 200px; -} - -#visibility-control-panel { - position: absolute; - left: 230px; - height: 30px; + height: fit-content; width: fit-content; top: 10px; z-index: 1000; display: flex; - justify-content: space-between; align-items: center; - padding-left: 10px; - padding-right: 10px; -} - -#unit-control-buttons { - position: fixed; - top: 10px; - height: fit-content; - width: fit-content; - right: 270px; - z-index: 1000; + column-gap: 10px; } #unit-control-panel { @@ -100,20 +83,3 @@ body { left: 10px; z-index: 1000; } - -@media only screen and (max-width: 1000px) { - #unit-control-buttons { - top: 50px; - } - - #unit-control-panel { - top: 50px; - } -} - - - - -.hide { - display:none !important; -} \ No newline at end of file diff --git a/client/public/stylesheets/logpanel.css b/client/public/stylesheets/logpanel.css deleted file mode 100644 index 209a60b9..00000000 --- a/client/public/stylesheets/logpanel.css +++ /dev/null @@ -1,23 +0,0 @@ -#log-panel { - overflow-y: scroll; - padding: 10px; - display: flex; - flex-direction: column; - row-gap: 2px; -} - -.ol-log-element { - font-size: 12px; - color: white; - text-shadow: 1px 1px 0px black, 1px -1px 0px black, -1px 1px 0px black, -1px -1px 0px black; - font-weight: 600; - width: 100%; -} - -#log-panel { - -ms-overflow-style: none; /* Internet Explorer 10+ */ - scrollbar-width: none; /* Firefox */ -} -#log-panel::-webkit-scrollbar { - display: none; /* Safari and Chrome */ -} \ No newline at end of file diff --git a/client/public/stylesheets/airbasemarker.css b/client/public/stylesheets/markers/airbase.css similarity index 100% rename from client/public/stylesheets/airbasemarker.css rename to client/public/stylesheets/markers/airbase.css diff --git a/client/public/stylesheets/markers/unit.css b/client/public/stylesheets/markers/unit.css new file mode 100644 index 00000000..9687f48e --- /dev/null +++ b/client/public/stylesheets/markers/unit.css @@ -0,0 +1,233 @@ +svg.unit { + height: var(--unit-marker-height); + width: var(--unit-marker-width); +} + +svg.unit .unit-vvi { + fill: black; + height: 4px; + transform-box: fill-box; + transform-origin: top; + translate: var(--unit-marker-centre-x) calc(var(--unit-marker-centre-y) - 2px); + width: 4px; +} + +svg.unit rect.unit-hotgroup { + display: none; + fill: var(--secondary-neutral); + height: var(--unit-marker-hotgroup-height); + transform: rotate(-45deg); + transform-origin: center; + translate: calc(var(--unit-marker-centre-x) + (var(--unit-marker-hotgroup-width) / 2)) -44px; + width: var(--unit-marker-hotgroup-height); +} + +svg.unit text.unit-hotgroup-id { + font-weight: bolder; + display: none; + fill: white; + font-size: 9px; +} + +svg.unit[data-is-in-hotgroup="true"] rect.unit-hotgroup, +svg.unit[data-is-in-hotgroup="true"] text.unit-hotgroup-id { + display: block; +} + +svg.unit rect.unit-selected-border { + fill: transparent; + height: calc(var(--unit-marker-air-height) + (var(--unit-marker-stroke-width) * 2)); + rx: var(--unit-marker-stroke-width); + stroke: var(white); + stroke-width: var(--unit-marker-stroke-width); + width: calc(var(--unit-marker-air-width) + (var(--unit-marker-stroke-width) * 2)); + x: calc(var(--unit-marker-air-label-x) - 3px); + y: calc(var(--unit-marker-air-label-y) - 3px); +} + +svg.unit rect.unit-marker { + fill: var(--primary-grey); + height: calc(var(--unit-marker-air-height) - var(--unit-marker-stroke-width)); + rx: var(--unit-marker-stroke-width); + ry: var(--unit-marker-stroke-width); + stroke: var(--secondary-neutral); + stroke-linejoin: round; + stroke-width: var(--unit-marker-stroke-width); + width: calc(var(--unit-marker-air-width) - var(--unit-marker-stroke-width)); + x: var(--unit-marker-air-label-x); + y: var(--unit-marker-air-label-y); +} + + +svg.unit text.unit-short-label { + fill: var(--secondary-neutral); + font-size: var(--unit-marker-font-size); + font-weight: var(--unit-marker-font-weight); + text-anchor: middle; +} + + +svg.unit rect.unit-fuel, +svg.unit rect.unit-fuel-level { + height: var(--unit-marker-air-fuel-height); + width: var(--unit-marker-air-fuel-width); + x: var(--unit-marker-air-fuel-x); + y: var(--unit-marker-air-fuel-y); +} + + +svg.unit rect.unit-fuel { + display: none; + fill: white; + rx: var(--unit-marker-stroke-width); + ry: var(--unit-marker-stroke-width); + stroke: var(--secondary-gunmetal-grey); + stroke-linejoin: round; + stroke-width: var(--unit-marker-stroke-width); + y: var(--unit-marker-air-fuel-y); +} + +svg.unit rect.unit-fuel-level { + display: none; + fill: var(--secondary-light-grey); + height: calc(var(--unit-marker-air-fuel-height) - var(--unit-marker-stroke-width)); + y: calc(var(--unit-marker-air-fuel-y) + (var(--unit-marker-stroke-width) / 2)); +} + + +svg.unit circle.unit-ammo { + cy: var(--unit-marker-air-ammo-y); + display: none; + fill: white; + r: var(--unit-marker-air-ammo-radius); + stroke: var(--secondary-neutral); + stroke-width: var(--unit-marker-stroke-width); +} + +svg.unit circle.unit-ammo-fox-1 { + cx: calc(var(--unit-marker-centre-x) - ((var(--unit-marker-air-ammo-radius) * 3) + (var(--unit-marker-air-ammo-gap) * 1.5))); +} + +svg.unit circle.unit-ammo-fox-2 { + cx: calc(var(--unit-marker-centre-x) - (var(--unit-marker-air-ammo-radius) + (var(--unit-marker-air-ammo-gap) / 2))); +} + +svg.unit circle.unit-ammo-fox-3 { + cx: calc(var(--unit-marker-centre-x) + var(--unit-marker-air-ammo-radius) + (var(--unit-marker-air-ammo-gap) / 2)); +} + +svg.unit circle.unit-ammo-other { + cx: calc(var(--unit-marker-centre-x) + (var(--unit-marker-air-ammo-radius) * 3) + (var(--unit-marker-air-ammo-gap) * 1.5)); +} + +svg.unit[data-has-fox-1="true"] circle.unit-ammo-fox-1, +svg.unit[data-has-fox-2="true"] circle.unit-ammo-fox-2, +svg.unit[data-has-fox-3="true"] circle.unit-ammo-fox-3, +svg.unit[data-has-other-ammo="true"] circle.unit-ammo-other { + fill: var(--secondary-gunmetal-grey); +} + +svg.unit .unit-summary text { + fill: white; + font-size: 10px; + paint-order: stroke; + stroke: black; + stroke-width: 2px; +} + + + +/*** Default style **/ + +svg.unit[data-coalition="blue"] rect.unit-marker { + fill: var(--primary-blue); + stroke: var(--secondary-blue-outline); +} + +svg.unit[data-coalition="blue"] rect.unit-hotgroup, +svg.unit[data-coalition="blue"] text.unit-short-label { + fill: var(--secondary-blue-outline); +} + +svg.unit[data-coalition="blue"] rect.unit-fuel { + stroke: var(--secondary-blue-outline); +} + +svg.unit[data-coalition="blue"] rect.unit-fuel-level { + fill: var(--primary-blue); +} + + +svg.unit[data-coalition="red"] rect.unit-marker { + fill: var(--primary-red); + stroke: var(--secondary-red-outline); +} + +svg.unit[data-coalition="red"] rect.unit-hotgroup, +svg.unit[data-coalition="red"] text.unit-short-label { + fill: var(--secondary-red-outline); +} + +svg.unit[data-coalition="red"] rect.unit-fuel { + stroke: var(--secondary-red-outline); +} + +svg.unit[data-coalition="red"] rect.unit-fuel-level { + fill: var(--primary-red); +} + + + +/*** Selected style **/ + + +svg.unit[data-is-selected="true"] .unit-spotlight { + cx: 50%; + cy: 50%; + fill: var(--unit-marker-spotlight-fill); + r: var(--unit-marker-spotlight-radius); +} + +svg.unit[data-is-selected="true"] rect.unit-selected-border, +svg.unit[data-is-selected="true"] rect.unit-marker { + fill: white; +} + + + +svg.unit[data-pilot="ai"][data-is-selected="true"] rect.unit-fuel, +svg.unit[data-pilot="ai"][data-is-selected="true"] rect.unit-fuel-level, +svg.unit[data-pilot="ai"][data-is-selected="true"] circle.unit-ammo { + display: block; +} + +@keyframes pulse { + 50% { + opacity: 0; + } +} + +svg.unit[data-pilot="ai"][data-is-selected="true"][data-has-low-fuel="true"] rect.unit-fuel, +svg.unit[data-pilot="ai"][data-is-selected="true"][data-has-low-fuel="true"] rect.unit-fuel-level { + animation: pulse 1.5s linear infinite; +} + + + + +svg.unit[data-coalition="blue"][data-is-selected="true"] text.unit-short-label, +svg.unit[data-coalition="blue"][data-has-fox-1="true"] circle.unit-ammo-fox-1, +svg.unit[data-coalition="blue"][data-has-fox-2="true"] circle.unit-ammo-fox-2, +svg.unit[data-coalition="blue"][data-has-fox-3="true"] circle.unit-ammo-fox-3, +svg.unit[data-coalition="blue"][data-has-other-ammo="true"] circle.unit-ammo-other { + fill: var(--primary-blue); +} + + +svg.unit[data-coalition="red"][data-is-selected="true"] text.unit-short-label, +svg.unit[data-coalition="red"][data-has-fox-1="true"] circle.unit-ammo-fox-1, +svg.unit[data-coalition="red"][data-has-fox-2="true"] circle.unit-ammo-fox-2, +svg.unit[data-coalition="red"][data-has-fox-3="true"] circle.unit-ammo-fox-3, +svg.unit[data-coalition="red"][data-has-other-ammo="true"] circle.unit-ammo-other { + fill: var(--primary-red); +} \ No newline at end of file diff --git a/client/public/stylesheets/mouseinfopanel.css b/client/public/stylesheets/mouseinfopanel.css deleted file mode 100644 index 80e5c09a..00000000 --- a/client/public/stylesheets/mouseinfopanel.css +++ /dev/null @@ -1,31 +0,0 @@ -#mouse-info-panel { - display: flex; - flex-direction: column; - padding: 10px; - row-gap: 5px; -} - -#mouse-info-panel .ol-rectangular-container{ - width: 100%; - font-weight: 600; - font-size: 12px; - display: flex; - align-items: center; - justify-content: space-between; - padding-left: 10px; - padding-right: 10px; - border-radius: 10px; - background-color: #FFF3; -} - -#mouse-info-panel img { - height: 24px; -} - -#measure-position-container{ - display: none; -} - -#unit-position-container{ - display: none; -} \ No newline at end of file diff --git a/client/public/stylesheets/olympus.css b/client/public/stylesheets/olympus.css index 9849cf36..6e930ec0 100644 --- a/client/public/stylesheets/olympus.css +++ b/client/public/stylesheets/olympus.css @@ -1,133 +1,134 @@ +@import url("layout.css"); + +@import url("contextmenu.css"); + +@import url("markers/unit.css"); +@import url("markers/airbase.css"); + /* Variables definitions */ :root { - --accent-green : #8bff63; - --accent-light-blue : #5ca7ff; - --background-grey : #3d4651; - --background-offwhite : #f2f2f3; - --background-steel : #202831; - --primary-blue : #247be2; - --primary-grey : #CFD9E8; - --primary-red : #ff5858; - --secondary-blue-outline : #082e44; - --secondary-dark-steel : #181e25; - --secondary-gunmetal-grey : #2f2f2f; - --secondary-light-grey : #797e83; - --secondary-neutral : #111111; - --secondary-red-outline : #262222; - --secondary-yellow : #ffd46893; - --nav-text : #ECECEC; + --accent-green: #8bff63; + --accent-light-blue: #5ca7ff; + --background-grey: #3d4651; + --background-offwhite: #f2f2f3; + --background-steel: #202831; + --primary-blue: #247be2; + --primary-grey: #CFD9E8; + --primary-red: #ff5858; + --secondary-blue-outline: #082e44; + --secondary-dark-steel: #181e25; + --secondary-gunmetal-grey: #2f2f2f; + --secondary-light-grey: #797e83; + --secondary-neutral: #111111; + --secondary-red-outline: #262222; + --secondary-yellow: #ffd46893; + --nav-text: #ECECEC; - - --border-radius-xs : 2px; - --border-radius-sm : 5px; - --border-radius-md : 10px; - --border-radius-lg : 15px; - - --font-weight-bolder : 600; + + --border-radius-xs: 2px; + --border-radius-sm: 5px; + --border-radius-md: 10px; + --border-radius-lg: 15px; + + --font-weight-bolder: 600; /* Generic marker settings */ --unit-marker-border-radius: 3px; - --unit-marker-centre-x: calc( var( --unit-marker-width ) / 2 ); - --unit-marker-centre-y: calc( var( --unit-marker-height ) / 2 ); + --unit-marker-centre-x: calc(var(--unit-marker-width) / 2); + --unit-marker-centre-y: calc(var(--unit-marker-height) / 2); --unit-marker-font-size: 12px; --unit-marker-font-weight: bold; --unit-marker-height: 100px; - --unit-marker-spotlight-fill: var( --secondary-yellow ); + --unit-marker-spotlight-fill: var(--secondary-yellow); --unit-marker-spotlight-opacity: 68%; --unit-marker-spotlight-radius: 28px; --unit-marker-stroke-width: 2px; --unit-marker-width: 150px; --unit-marker-hotgroup-height: 12px; - --unit-marker-hotgroup-width: var( --unit-marker-hotgroup-height ); + --unit-marker-hotgroup-width: var(--unit-marker-hotgroup-height); /* Air units' marker settings */ - --unit-marker-air-ammo-gap: calc( 2px + var( --unit-marker-stroke-width ) ); + --unit-marker-air-ammo-gap: calc(2px + var(--unit-marker-stroke-width)); --unit-marker-air-ammo-radius: 3px; - --unit-marker-air-ammo-y: calc( var( --unit-marker-height ) - 8px ); + --unit-marker-air-ammo-y: calc(var(--unit-marker-height) - 8px); --unit-marker-air-fuel-height: 6px; --unit-marker-air-fuel-width: 36px; - --unit-marker-air-fuel-x: calc( var( --unit-marker-centre-x ) - ( var( --unit-marker-air-fuel-width ) / 2 ) ); - --unit-marker-air-fuel-y: calc( var( --unit-marker-height ) - 21px ); + --unit-marker-air-fuel-x: calc(var(--unit-marker-centre-x) - (var(--unit-marker-air-fuel-width) / 2)); + --unit-marker-air-fuel-y: calc(var(--unit-marker-height) - 21px); --unit-marker-air-height: 28px; --unit-marker-air-vvi-rotation-offset: -180deg; - --unit-marker-air-width: var( --unit-marker-air-height ); - --unit-marker-air-label-x: calc( var( --unit-marker-centre-x ) - ( var( --unit-marker-air-width ) / 2 ) + ( var( --unit-marker-stroke-width ) / 2 ) ); - --unit-marker-air-label-y: calc( var( --unit-marker-centre-y ) - ( var( --unit-marker-air-height ) / 2 ) + ( var( --unit-marker-stroke-width ) / 2 ) ); + --unit-marker-air-width: var(--unit-marker-air-height); + --unit-marker-air-label-x: calc(var(--unit-marker-centre-x) - (var(--unit-marker-air-width) / 2) + (var(--unit-marker-stroke-width) / 2)); + --unit-marker-air-label-y: calc(var(--unit-marker-centre-y) - (var(--unit-marker-air-height) / 2) + (var(--unit-marker-stroke-width) / 2)); } - -* { - -moz-box-sizing: border-box; - -webkit-box-sizing: border-box; - box-sizing: border-box; -} - - -html { - font-family: 'Open Sans', sans-serif; -} - - button { - background-color:var(--background-steel); - border:1px solid var( --background-steel ); - border-radius: var( --border-radius-sm ); - color:whitesmoke; - cursor:pointer; - font-weight: var( --font-weight-bolder ); - padding:8px; + background-color: var(--background-steel); + border: 1px solid var(--background-steel); + border-radius: var(--border-radius-sm); + color: whitesmoke; + cursor: pointer; + font-weight: var(--font-weight-bolder); + padding: 8px; } button[disabled="disabled"] { - color: var( --highlight-color ); - cursor:not-allowed; + color: var(--highlight-color); + cursor: not-allowed; } - .pill { - border-radius: var( --border-radius-sm ); - display:inline-block; - padding:6px; + border-radius: var(--border-radius-sm); + display: inline-block; + padding: 6px; } - - -nav, .ol-panel { +.ol-panel { background-color: var(--background-steel); border-radius: 15px; box-shadow: 0px 2px 5px #000A; - color:white; + color: white; + font-size: 12px; + height: fit-content; + padding: 10px; + width: fit-content; +} + +nav { + border-radius: 15px; + color: white; font-size: 12px; - height:fit-content; - padding:10px; - width:fit-content; } nav .ol-select { - color: var( --nav-text ); + color: var(--nav-text); +} + +.ol-select-options { + position: fixed; } nav .ol-select .ol-select-value { align-content: center; - background-color: var( --background-grey ); - border-radius: var( --border-radius-sm ); - display:flex; + background-color: var(--background-grey); + border-radius: var(--border-radius-sm); + display: flex; justify-content: left; - padding:1em; + padding: 1em; text-align: center; } nav .ol-select .ol-select-options { - background-color: var( --background-grey ); - border-radius: var( --border-radius-sm ); - display:none; + background-color: var(--background-grey); + border-radius: var(--border-radius-sm); + display: none; list-style: none; - padding:.5em 0; - position: relative; + padding: .5em 0; + margin: 0px; } nav .ol-select:hover .ol-select-options { @@ -135,334 +136,197 @@ nav .ol-select:hover .ol-select-options { } nav .ol-select .ol-select-options li { - background-color: var( --background-grey ); - display:flex; + background-color: var(--background-grey); + display: flex; justify-content: left; } nav .ol-select .ol-select-options li.hr { - border-bottom:1px solid var( --nav-text ); - margin:8px; + border-bottom: 1px solid var(--nav-text); + margin: 8px; } nav .ol-select .ol-select-options li button { - background-color: var( --background-grey ); - border:none; - font-size:14px; + background-color: var(--background-grey); + border: none; + font-size: 14px; font-weight: normal; text-align: left; - width:100%; + width: 100%; } .ol-panel-list { - border-radius: var( --border-radius-sm ); + border-radius: var(--border-radius-sm); display: flex; flex-direction: column; - height: fit-content; + height: fit-content; row-gap: 5px; - text-align: center; - width: fit-content; + text-align: center; + width: fit-content; } .ol-panel-list .list-item { - border-radius: var( --border-radius-md ); - display:flex; + border-radius: var(--border-radius-md); + display: flex; justify-content: space-between; - padding: 6px 10px; + padding: 6px 10px; } -.ol-panel-list.sortable > .sortable-item { +.ol-panel-list.sortable>.sortable-item { align-items: center; column-gap: 5px; - display:flex; + display: flex; flex-direction: row; } -.ol-panel-list.sortable > .sortable-item > .handle { - cursor:grab; - filter:invert(100); +.ol-panel-list.sortable>.sortable-item>.handle { + cursor: grab; + filter: invert(100); } -.ol-panel-list.sortable > .sortable-item > .handle img { +.ol-panel-list.sortable>.sortable-item>.handle img { max-width: 16px; } .ol-panel-board { - display:flex; + display: flex; flex-direction: row; justify-content: space-evenly; } -.ol-panel-board > .panel-section { +.ol-panel-board>.panel-section { border-right: 1px solid #555; - padding:10px; + padding: 10px; } -.ol-panel-board > .panel-section:last-of-type { +.ol-panel-board>.panel-section:last-of-type { border-right-width: 0; } -.ol-panel-board h1, .ol-panel-board h2 { - font-size:18px; - font-weight: var( --font-weight-bolder ); - margin: 0; - padding:0 0 5px 0; +.ol-panel-board h1, +.ol-panel-board h2 { + font-size: 18px; + font-weight: var(--font-weight-bolder); + padding: 0 0 5px 0; } .ol-panel-board h2 { - font-size:14px; + font-size: 14px; } - +.ol-panel h1, +.ol-panel h2, +.ol-panel h3, +.ol-panel h4, +.ol-panel h5, +.ol-panel h6 { + margin: 0px; +} .highlight-primary { - background-color: var(--secondary-light-grey); + background-color: var(--secondary-light-grey); } .highlight-bluefor { - background-color: var(--primary-blue); - color: var(--background-steel ) + background-color: var(--primary-blue); + color: var(--background-steel) } .highlight-redfor { - background-color: var(--primary-red); + background-color: var(--primary-red); } .highlight-neutral { - background-color: var(--primary-grey); + background-color: var(--primary-grey); color: var(--secondary-gunmetal-grey) } - - -svg.unit { - height: var( --unit-marker-height ); - width: var( --unit-marker-width ); -} - -svg.unit .unit-vvi { - fill:black; - height: 4px; - transform-box: fill-box; - transform-origin:top; - translate: var( --unit-marker-centre-x ) calc( var( --unit-marker-centre-y ) - 2px ); - width:4px; -} - -svg.unit rect.unit-hotgroup { - display:none; - fill: var( --secondary-neutral ); - height: var( --unit-marker-hotgroup-height ); - transform: rotate( -45deg ); - transform-origin: center; - translate: calc( var( --unit-marker-centre-x ) + ( var( --unit-marker-hotgroup-width ) / 2 ) ) -44px; - width: var( --unit-marker-hotgroup-height ); -} - -svg.unit text.unit-hotgroup-id { - font-weight: bolder; - display:none; - fill:white; - font-size:9px; -} - -svg.unit[data-is-in-hotgroup="true"] rect.unit-hotgroup, svg.unit[data-is-in-hotgroup="true"] text.unit-hotgroup-id { - display:block; -} - -svg.unit rect.unit-selected-border { - fill:transparent; - height: calc( var( --unit-marker-air-height ) + ( var( --unit-marker-stroke-width ) * 2 ) ); - rx: var( --unit-marker-stroke-width ); - stroke: var( white ); - stroke-width: var( --unit-marker-stroke-width ); - width: calc( var( --unit-marker-air-width ) + ( var( --unit-marker-stroke-width ) * 2 ) ); - x: calc( var(--unit-marker-air-label-x) - 3px ); - y: calc( var(--unit-marker-air-label-y) - 3px ); -} - -svg.unit rect.unit-marker { - fill: var( --primary-grey ); - height: calc( var( --unit-marker-air-height ) - var( --unit-marker-stroke-width ) ); - rx: var( --unit-marker-stroke-width ); - ry: var( --unit-marker-stroke-width ); - stroke: var( --secondary-neutral ); - stroke-linejoin: round; - stroke-width: var( --unit-marker-stroke-width ); - width: calc( var( --unit-marker-air-width ) - var( --unit-marker-stroke-width ) ); - x: var(--unit-marker-air-label-x); - y: var(--unit-marker-air-label-y); -} - - -svg.unit text.unit-short-label { - fill: var( --secondary-neutral ); - font-size: var( --unit-marker-font-size ); - font-weight: var( --unit-marker-font-weight ); - text-anchor: middle; -} - - -svg.unit rect.unit-fuel, svg.unit rect.unit-fuel-level { - height: var( --unit-marker-air-fuel-height ); - width: var( --unit-marker-air-fuel-width ); - x: var( --unit-marker-air-fuel-x ); - y: var( --unit-marker-air-fuel-y ); -} - - -svg.unit rect.unit-fuel { - display:none; - fill: white; - rx: var( --unit-marker-stroke-width ); - ry: var( --unit-marker-stroke-width ); - stroke: var( --secondary-gunmetal-grey ); - stroke-linejoin: round; - stroke-width: var( --unit-marker-stroke-width ); - y: var( --unit-marker-air-fuel-y ); -} - -svg.unit rect.unit-fuel-level { - display:none; - fill: var( --secondary-light-grey ); - height: calc( var( --unit-marker-air-fuel-height ) - var( --unit-marker-stroke-width ) ); - y: calc( var( --unit-marker-air-fuel-y ) + ( var( --unit-marker-stroke-width ) / 2 ) ); -} - - -svg.unit circle.unit-ammo { - cy: var( --unit-marker-air-ammo-y ); +.hide { display: none; - fill: white; - r: var( --unit-marker-air-ammo-radius ); - stroke: var( --secondary-neutral ); - stroke-width: var( --unit-marker-stroke-width ); } -svg.unit circle.unit-ammo-fox-1 { - cx: calc( var( --unit-marker-centre-x ) - ( ( var( --unit-marker-air-ammo-radius ) * 3 ) + ( var( --unit-marker-air-ammo-gap ) * 1.5 ) ) ); +.icon-small { + width: 20px; + padding: 2px; + filter: invert(100%); } -svg.unit circle.unit-ammo-fox-2 { - cx: calc( var( --unit-marker-centre-x ) - ( var( --unit-marker-air-ammo-radius ) + ( var( --unit-marker-air-ammo-gap ) / 2 ) ) ); +.data-grid { + display: flex; + flex-direction: column; } -svg.unit circle.unit-ammo-fox-3 { - cx: calc( var( --unit-marker-centre-x ) + var( --unit-marker-air-ammo-radius ) + ( var( --unit-marker-air-ammo-gap ) / 2 ) ); +.data-row { + display: flex; + flex-direction: row; + align-items: center; + justify-content: space-between; + column-gap: 2px; } -svg.unit circle.unit-ammo-other { - cx: calc( var( --unit-marker-centre-x ) + ( var( --unit-marker-air-ammo-radius ) * 3 ) + ( var( --unit-marker-air-ammo-gap ) * 1.5 ) ); +.data-row>*:nth-child(2){ + width: 100px; } -svg.unit[data-has-fox-1="true"] circle.unit-ammo-fox-1, -svg.unit[data-has-fox-2="true"] circle.unit-ammo-fox-2, -svg.unit[data-has-fox-3="true"] circle.unit-ammo-fox-3, -svg.unit[data-has-other-ammo="true"] circle.unit-ammo-other { - fill: var( --secondary-gunmetal-grey ); +.data-row>*:last-child{ + width: 30px; + text-align: right; } -svg.unit .unit-summary text { - fill:white; - font-size:10px; - paint-order: stroke; - stroke: black; - stroke-width: 2px; +.data-row>.icon-small{ + margin: 2px; } - - -/*** Default style **/ - -svg.unit[data-coalition="blue"] rect.unit-marker { - fill: var( --primary-blue ); - stroke: var( --secondary-blue-outline ); +.slider-container { + width: 100%; } -svg.unit[data-coalition="blue"] rect.unit-hotgroup, -svg.unit[data-coalition="blue"] text.unit-short-label { - fill: var( --secondary-blue-outline ); +.slider { + width: 100%; + -webkit-appearance: none; + appearance: none; + height: 2px; + background: #d3d3d3; + outline: none; + opacity: 0.7; + -webkit-transition: .2s; + transition: opacity .2s; + margin-top: 10px; + margin-bottom: 10px; } -svg.unit[data-coalition="blue"] rect.unit-fuel { - stroke: var( --secondary-blue-outline ); +.slider:hover { + opacity: 1; } -svg.unit[data-coalition="blue"] rect.unit-fuel-level { - fill: var( --primary-blue ); +.slider::-webkit-slider-thumb { + -webkit-appearance: none; + appearance: none; + width: 20px; + height: 20px; + background: gray; + cursor: pointer; + border-radius: 999px; } - -svg.unit[data-coalition="red"] rect.unit-marker { - fill: var( --primary-red ); - stroke: var( --secondary-red-outline ); +.active .slider::-webkit-slider-thumb { + background: #5ca7ff; } -svg.unit[data-coalition="red"] rect.unit-hotgroup, -svg.unit[data-coalition="red"] text.unit-short-label { - fill: var( --secondary-red-outline ); +.slider::-moz-range-thumb { + width: 20px; + height: 20px; + background: gray; + cursor: pointer; + border-radius: 999px; } -svg.unit[data-coalition="red"] rect.unit-fuel { - stroke: var( --secondary-red-outline ); +.active .slider::-moz-range-thumb { + background: #5ca7ff; } -svg.unit[data-coalition="red"] rect.unit-fuel-level { - fill: var( --primary-red ); -} - - - -/*** Selected style **/ - - -svg.unit[data-is-selected="true"] .unit-spotlight { - cx:50%; - cy:50%; - fill:var( --unit-marker-spotlight-fill ); - r: var( --unit-marker-spotlight-radius ); -} - -svg.unit[data-is-selected="true"] rect.unit-selected-border, -svg.unit[data-is-selected="true"] rect.unit-marker { - fill:white; -} - - - -svg.unit[data-pilot="ai"][data-is-selected="true"] rect.unit-fuel, -svg.unit[data-pilot="ai"][data-is-selected="true"] rect.unit-fuel-level, -svg.unit[data-pilot="ai"][data-is-selected="true"] circle.unit-ammo { - display:block; -} - -@keyframes pulse { - 50% { - opacity: 0; - } -} -svg.unit[data-pilot="ai"][data-is-selected="true"][data-has-low-fuel="true"] rect.unit-fuel, -svg.unit[data-pilot="ai"][data-is-selected="true"][data-has-low-fuel="true"] rect.unit-fuel-level { - animation: pulse 1.5s linear infinite; -} - - - - -svg.unit[data-coalition="blue"][data-is-selected="true"] text.unit-short-label, -svg.unit[data-coalition="blue"][data-has-fox-1="true"] circle.unit-ammo-fox-1, -svg.unit[data-coalition="blue"][data-has-fox-2="true"] circle.unit-ammo-fox-2, -svg.unit[data-coalition="blue"][data-has-fox-3="true"] circle.unit-ammo-fox-3, -svg.unit[data-coalition="blue"][data-has-other-ammo="true"] circle.unit-ammo-other { - fill: var( --primary-blue ); -} - - -svg.unit[data-coalition="red"][data-is-selected="true"] text.unit-short-label, -svg.unit[data-coalition="red"][data-has-fox-1="true"] circle.unit-ammo-fox-1, -svg.unit[data-coalition="red"][data-has-fox-2="true"] circle.unit-ammo-fox-2, -svg.unit[data-coalition="red"][data-has-fox-3="true"] circle.unit-ammo-fox-3, -svg.unit[data-coalition="red"][data-has-other-ammo="true"] circle.unit-ammo-other { - fill: var( --primary-red ); +.main-logo { + width: 40px; + height: 40px; } \ No newline at end of file diff --git a/client/public/stylesheets/panels.css b/client/public/stylesheets/panels.css deleted file mode 100644 index e754028e..00000000 --- a/client/public/stylesheets/panels.css +++ /dev/null @@ -1,14 +0,0 @@ -/* Panels style */ -.ol-panel { - background-color: var(--background-color-dark); - font-size: 12px; - border-radius: 15px; - box-shadow: 0px 2px 5px #000A; -} - -.ol-panel-transparent { - background-color: transparent; - font-size: 12px; - box-shadow: 0px 0px 0px transparent; - border-radius: 0px; -} diff --git a/client/public/stylesheets/slider.css b/client/public/stylesheets/slider.css deleted file mode 100644 index cddd49ad..00000000 --- a/client/public/stylesheets/slider.css +++ /dev/null @@ -1,47 +0,0 @@ -.slider-container { - width: 100%; -} - -.slider { - width: 100%; - -webkit-appearance: none; - appearance: none; - height: 2px; - background: #d3d3d3; - outline: none; - opacity: 0.7; - -webkit-transition: .2s; - transition: opacity .2s; - margin-top: 10px; - margin-bottom: 10px; -} - -.slider:hover { - opacity: 1; -} - -.slider::-webkit-slider-thumb { - -webkit-appearance: none; - appearance: none; - width: 20px; - height: 20px; - background: gray; - cursor: pointer; - border-radius: 999px; -} - -.active .slider::-webkit-slider-thumb { - background: #5ca7ff; -} - -.slider::-moz-range-thumb { - width: 20px; - height: 20px; - background: gray; - cursor: pointer; - border-radius: 999px; -} - -.active .slider::-moz-range-thumb { - background: #5ca7ff; -} \ No newline at end of file diff --git a/client/public/stylesheets/style.css b/client/public/stylesheets/style.css deleted file mode 100644 index 610963b3..00000000 --- a/client/public/stylesheets/style.css +++ /dev/null @@ -1,234 +0,0 @@ -@import url("button.css"); -@import url("slider.css"); -@import url("dropdown.css"); - -@import url("selectionwheel.css"); -@import url("contextmenu.css"); - -@import url("unitmarker.css"); -@import url("airbasemarker.css"); - -@import url("panels.css"); -@import url("connectionstatuspanel.css"); -@import url("unitcontrolpanel.css"); -@import url("visibilitycontrolpanel.css"); -@import url("unitinfopanel.css"); -@import url("mouseinfopanel.css"); -@import url("logpanel.css"); - -@import url( "aic.css" ); -@import url( "atc.css" ); - -@import url("layout.css"); - - -/* Variables definitions */ -:root { - --accent-green: #8bff63; - --accent-light-blue: #5ca7ff; - --background-grey: #3d4651; - --background-offwhite: #f2f2f3; - --background-steel: #202831; - --primary-blue: #247be2; - --primary-grey: #CFD9E8; - --primary-red: #ff5858; - --secondary-blue-outline: #082e44; - --secondary-dark-steel: #181e25; - --secondary-gunmetal-grey: #2f2f2f; - --secondary-light-grey: #797e83; - --secondary-red-outline: #262222; - --secondary-yellow: #ffd46893; - - - --border-radius-xs: 2px; - --border-radius-sm: 5px; - --border-radius-md: 10px; - --border-radius-lg: 15px; - - --font-weight-bolder: 600; - - - --background-color-dark: #202831; - --background-color-light: #AAA; - --title-color: #d3e9ff; - --text-color: white; - --blue-coalition-color: #247be2; - --red-coalition-color: #f32121; - --neutral-coalition-color: #202831; - --active-coalition-color: var(--blue-coalition-color); - --highlight-color: #FFF5; -} - -* { - -moz-box-sizing: border-box; - -webkit-box-sizing: border-box; - box-sizing: border-box; -} - -html { - font-family: 'Open Sans', sans-serif; -} - -.leaflet-container.crosshair-cursor-enabled { - cursor:crosshair; -} - -.ol-rectangular-container { - padding: 0.5em; - background-color: gray; - border-radius: 5px; - width: fit-content; - height: fit-content; - text-align: center; - color: white; - font-size: 12px; -} - -.ol-rectangular-container-dark { - padding-left: 0.5em; - padding-right: 0.5em; - padding-top: 0.2em; - padding-bottom: 0.2em; - background-color: #151b20; - border-radius: 5px; - width: fit-content; - height: fit-content; - text-align: center; - color: white; - font-size: 12px; -} - -.ol-rounded-container { - position: relative; - padding: 0.5em; - width: fit-content; - height: fit-content; - text-align: center; - color: white; - font-size: 12px; - border-radius: 9999px; - background-color: gray; -} - -.ol-rounded-container.blue { - background-color: var(--blue-coalition-color); - border: 1px solid var(--blue-coalition-color); -} - -.ol-rounded-container.red { - background-color: var(--red-coalition-color); - border: 1px solid var(--red-coalition-color); -} - -.ol-rounded-container.neutral { - background-color: var(--neutral-coalition-color); -} - -.ol-rounded-container-small { - padding: 0.2em; - width: fit-content; - height: fit-content; - text-align: center; - color: black; - font-weight: 600; - background-color: #FFFA; - font-size: 11px; - border-radius: 9999px; - padding-left: 5px; - padding-right: 5px; -} - -.ol-rectangular-button { - position: relative; - padding: 0.5em; - width: fit-content; - height: fit-content; - text-align: center; - color: var(--highlight-color); - font-size: 12px; - border-radius: 5px; - background-color: transparent; - border: 1px solid var(--highlight-color); - cursor: pointer; - font-weight: 600; - display: flex; - align-items: center; - column-gap: 5px; -} - -.ol-rectangular-button.blue { - border: 1px solid var(--blue-coalition-color); - color: var(--blue-coalition-color); -} - -.ol-rectangular-button.red { - border: 1px solid var(--red-coalition-color); - color: var(--red-coalition-color); -} - -.ol-rectangular-button.white { - border: 1px solid white; - color: white; -} - -.ol-rectangular-button.white>img { - filter: invert(100%); -} - -.ol-rectangular-button>img { - display: inline-block; - height: 18px; - width: 18px; -} - -.ol-rectangular-button.red { - border: 1px solid var(--red-coalition-color); -} - -.ol-vl { - border-left: 1px solid #555; - width: 1px !important; - display: inline-block; -} - -.ol-hl { - border-top: 1px solid #555; - height: 1px !important; - display: inline-block; -} - -.ol-measure-box { - position: absolute; - padding-left: 0.5em; - padding-right: 0.5em; - padding-top: 0.2em; - padding-bottom: 0.2em; - background-color: #151b20; - border-radius: 5px; - width: fit-content; - height: fit-content; - text-align: center; - color: white; - font-size: 12px; - z-index: 2000; - font-weight: 600; -} - -.ol-scrollable { - overflow-y: auto; -} - -.ol-scrollable::-webkit-scrollbar { - width: 10px; -} - -.ol-scrollable::-webkit-scrollbar-track { - background-color: transparent; - border-radius: 100px; -} - -.ol-scrollable::-webkit-scrollbar-thumb { - background-color: white; - border-radius: 100px; - opacity: 0.8; -} \ No newline at end of file diff --git a/client/public/stylesheets/uikit.css b/client/public/stylesheets/uikit.css index 44052611..d9c731dd 100644 --- a/client/public/stylesheets/uikit.css +++ b/client/public/stylesheets/uikit.css @@ -18,8 +18,6 @@ section { flex-wrap: wrap; } - - .content { background:white; border-radius: 10px; diff --git a/client/public/stylesheets/unitcontrolpanel.css b/client/public/stylesheets/unitcontrolpanel.css deleted file mode 100644 index 57f257cf..00000000 --- a/client/public/stylesheets/unitcontrolpanel.css +++ /dev/null @@ -1,133 +0,0 @@ -#unit-control-buttons { - display: flex; - flex-direction: column; - row-gap: 5px; - padding: 10px; - border-radius: 999px; -} - -#unit-control-buttons>div { - filter: invert(100%); - opacity: 0.8; -} - -#unit-control-panel { - display: flex; - flex-direction: column; - flex-wrap: wrap; - justify-content: space-between; - align-content: flex-start; - row-gap: 10px; - padding-left: 30px; - padding-right: 30px; - padding-top: 20px; - padding-bottom: 20px; -} - -#selected-units-container { - display: flex; - flex-direction: column; - row-gap: 5px; - width: 100%; - height: fit-content; - max-height: 200px; - padding-top: 10px; - padding-bottom: 10px; -} - -#formation-buttons-container { - display: flex; - flex-direction: row; - flex-wrap: wrap; - row-gap: 5px; - column-gap: 5px; - width: 100%; - height: 100%; -} - -#roe-buttons-container { - display: flex; - flex-direction: row; - flex-wrap: wrap; - row-gap: 5px; - column-gap: 5px; - width: 100%; - height: 100%; -} - -#reaction-to-threat-buttons-container { - display: flex; - flex-direction: row; - flex-wrap: wrap; - row-gap: 5px; - column-gap: 5px; - width: 100%; - height: 100%; -} - -#selected-units-container .ol-rounded-container { - width: calc(100% - 25px); - cursor: pointer; - margin-left: 25px; -} - -#selected-units-container .ol-rounded-container.not-selected { - background-color: transparent; -} - -#selected-units-container .ol-rounded-container .ol-rounded-container-small { - display: inline-block; - position: absolute; - left: 5px; - top: 5px; -} - -#selected-units-container img { - height: calc(100% + 6px); - display: inline-block; - position: absolute; - left: -32px; - top: -3px; -} - -#selected-units-container img.blue { - filter: invert(81%) sepia(6%) saturate(1685%) hue-rotate(181deg) brightness(103%) contrast(92%); -} - -#selected-units-container img.red { - filter: invert(93%) sepia(97%) saturate(1174%) hue-rotate(291deg) brightness(105%) contrast(97%); -} - -#unit-control-panel .ol-title-label { - color: white; - font-size: 14px; - width: 100%; - font-weight: 600; -} - -#unit-control-panel #section-label { - color: white; - font-size: 13px; - width: 100%; -} - -.flight-control-slider { - display: flex; - flex-wrap: wrap; - justify-content: space-between; -} - -.flight-control-title { - font-size: 13px; - color: white; -} - -.flight-control-value { - font-size: 14px; - font-weight: 600; - color: gray; -} - -.active .flight-control-value { - color: #5ca7ff; -} diff --git a/client/public/stylesheets/unitinfopanel.css b/client/public/stylesheets/unitinfopanel.css deleted file mode 100644 index dc478257..00000000 --- a/client/public/stylesheets/unitinfopanel.css +++ /dev/null @@ -1,130 +0,0 @@ - -/* Panel properties */ -#unit-info-panel { - display: flex; - flex-direction: row; - padding-left: 30px; - padding-right: 30px; - padding-top: 20px; - padding-bottom: 20px; -} - -/* Common */ -#unit-info-panel>div { - height: 100%; - width: 100%; -} - -#unit-info-panel>.ol-vl { - margin-left: 30px; - margin-right: 30px; -} - -/* Sections */ -#unit-info-panel #general { - display: flex; - flex-flow: row; - flex-wrap: wrap; - justify-content: flex-start; - column-gap: 5px; - row-gap: 5px; - align-content: flex-start; -} - -#unit-info-panel #flight-data { - display: flex; - flex-flow: row; - flex-wrap: wrap; - justify-content: space-between; - align-content: center; - align-items: center; - align-content: space-between; -} - -#unit-info-panel #loadout-data { - display: flex; - flex-flow: row; - flex-wrap: wrap; - align-content: flex-start; - justify-content: flex-start; - row-gap: 5px; -} - -/* General section */ -#general #unit-name { - color: white; - font-size: 18px; - width: 100%; - padding-bottom: 5px; - font-weight: 600; -} - -#general #task { - width: 100%; -} - -/* Flight data section */ -#flight-data #flight-data-label { - color: white; - font-size: 14px; - width: 100%; - font-weight: 600; -} - -#flight-data #latitude { - width: 50%; - color: white; - font-size: 13px; - text-align: center; - font-weight: 600; - color: #8bff63; -} - -#flight-data #longitude { - width: 50%; - color: white; - font-size: 13px; - text-align: center; - font-weight: 600; - color: #5ca7ff; -} - -.flight-data-label, .flight-data-value { - color: white; - font-size: 12px; - padding-left: 10px; -} - -.flight-data-icon { - width: 10%; - padding: 2px; - filter: invert(100%); -} - -.flight-data-label { - width: 58%; -} - -.flight-data-value { - width: 30%; - font-weight: 600; - text-align: right; -} - -/* Loadout section */ -#loadout-data #loadout-label { - color: white; - font-size: 14px; - width: 100%; - font-weight: 600; -} - -#loadout-container { - display: flex; - flex-direction: row; - flex-wrap: wrap; - column-gap: 2px; - row-gap: 2px; - min-height: 0px; - max-height: 70px; /* TODO: fix me, magic number */ -} diff --git a/client/public/stylesheets/unitmarker.css b/client/public/stylesheets/unitmarker.css deleted file mode 100644 index 82ce2564..00000000 --- a/client/public/stylesheets/unitmarker.css +++ /dev/null @@ -1,314 +0,0 @@ - -.unit { - border-radius: var(--border-radius-xs); - display: grid; - height: fit-content; - position: relative; - width: fit-content; - font-family: 'Open Sans'; -} - -.unit .unit-id { - align-items: center; - background: var(--primary-grey); - border: 3px solid var(--background-steel); - border-radius: var(--border-radius-xs); - color: var(--background-steel); - display: flex; - font-weight: bold; - height: 32px; - justify-content: center; - padding: 4px; - position: relative; - text-align: center; - width: 32px; - z-index: 100; -} - -.unit .unit-spotlight { - border-radius: 50%; - align-items: center; - display: flex; - height: fit-content; - justify-items: center; - padding: 9px; - width: fit-content; -} - -.unit .unit-hotgroup { - align-self: flex-start; - background: black; - color: white; - display: none; - height: fit-content; - justify-content: center; - justify-self: center; - line-height: 14px; - position: absolute; - text-align: center; - top: -8px; - transform: rotate(45deg); - width: 14px; -} - -.unit .unit-hotgroup-id { - font-size: 11px; - transform: rotate(-45deg); -} - -.unit .unit-vvi { - display: flex; - position: absolute; - left: 50%; - transform: rotate(-90deg); - transform-origin: 0 50%; - top: 50%; - z-index: 0; -} - -.unit .unit-vvi-heading { - border: 1px solid var(--secondary-dark-steel); - padding-left: 14px; - transform: rotate(90deg); - transform-origin: 0 50%; - width: 30px; -} - - -.unit .unit-selected-border { - border: 2px solid transparent; - border-radius: var(--border-radius-xs); - position: relative; - z-index: 1; -} - - -.unit .unit-fuel { - background: white; - border: 2px solid var(--secondary-dark-steel); - border-radius: var(--border-radius-xs); - display: none; - margin: 0 auto; - position: relative; - top: -6px; - width: calc(100% - 16px); -} - -.unit .unit-fuel-empty { - align-self: center; - background: white; - border-radius: 50%; - color: red; - display: none; - font-weight: bold; - justify-self: center; - padding: 1px; - position: absolute; -} - -.unit[data-fuel-level="0"] .unit-fuel-empty { - display: flex; -} - -@keyframes blinker { - 50% { - opacity: 0; - } -} - -.unit[data-fuel-level="10"] .unit-fuel, -.unit[data-fuel-level="20"] .unit-fuel, -.unit[data-fuel-level="30"] .unit-fuel { - animation: blinker 1.5s linear infinite; -} - -.unit .unit-fuel-level { - background-color: var(--secondary-light-grey); - display: flex; - height: 4px; - visibility: hidden; - width: 100%; -} - -.unit[data-fuel-level="10"] .unit-fuel-level, -.unit[data-fuel-level="20"] .unit-fuel-level, -.unit[data-fuel-level="30"] .unit-fuel-level, -.unit[data-fuel-level="40"] .unit-fuel-level, -.unit[data-fuel-level="50"] .unit-fuel-level, -.unit[data-fuel-level="60"] .unit-fuel-level, -.unit[data-fuel-level="70"] .unit-fuel-level, -.unit[data-fuel-level="80"] .unit-fuel-level, -.unit[data-fuel-level="90"] .unit-fuel-level, -.unit[data-fuel-level="100"] .unit-fuel-level { - visibility: visible; -} - -.unit[data-fuel-level="10"] .unit-fuel-level { - width: 10%; -} - -.unit[data-fuel-level="20"] .unit-fuel-level { - width: 20%; -} - -.unit[data-fuel-level="30"] .unit-fuel-level { - width: 30%; -} - -.unit[data-fuel-level="40"] .unit-fuel-level { - width: 40%; -} - -.unit[data-fuel-level="50"] .unit-fuel-level { - width: 50%; -} - -.unit[data-fuel-level="60"] .unit-fuel-level { - width: 60%; -} - -.unit[data-fuel-level="70"] .unit-fuel-level { - width: 70%; -} - -.unit[data-fuel-level="80"] .unit-fuel-level { - width: 80%; -} - -.unit[data-fuel-level="90"] .unit-fuel-level { - width: 90%; -} - -.unit[data-fuel-level="100"] .unit-fuel-level { - width: 100%; -} - -.unit-ammo { - column-gap: 2px; - display: none; - flex-direction: row; - flex-wrap: nowrap; - height: fit-content; - justify-content: center; - position: relative; - top: -2px; - width: 100%; -} - -.unit-ammo>[data-ammo-type] { - background: white; - border: 2px solid var(--secondary-dark-steel); - border-radius: 50%; - padding: 3px; -} - -.unit[data-has-fox-1="true"] .unit-ammo>[data-ammo-type="fox-1"], -.unit[data-has-fox-2="true"] .unit-ammo>[data-ammo-type="fox-2"], -.unit[data-has-fox-3="true"] .unit-ammo>[data-ammo-type="fox-3"], -.unit[data-has-other-ammo="true"] .unit-ammo>[data-ammo-type="other"] { - background-color: var(--secondary-light-grey); -} - - -/*** BLUEFOR ***/ - -.unit[data-coalition="blue"] .unit-hotgroup { - background-color: var(--secondary-blue-outline); -} - -.unit[data-coalition="blue"] .unit-id, -.unit[data-coalition="blue"][data-has-fox-1="true"] .unit-ammo>[data-ammo-type="fox-1"], -.unit[data-coalition="blue"][data-has-fox-2="true"] .unit-ammo>[data-ammo-type="fox-2"], -.unit[data-coalition="blue"][data-has-fox-3="true"] .unit-ammo>[data-ammo-type="fox-3"], -.unit[data-coalition="blue"][data-has-other-ammo="true"] .unit-ammo>[data-ammo-type="other"], -.unit[data-coalition="blue"] .unit-fuel-level, -.unit[data-coalition="blue"] .unit-vvi-heading { - background: var(--primary-blue); - border-color: var(--secondary-blue-outline); - color: var(--secondary-blue-outline); -} - -.unit[data-coalition="blue"][data-is-selected="true"] .unit-id { - border-color: var(--secondary-blue-outline); - color: var(--primary-blue); -} - -.unit[data-coalition="blue"] .unit-ammo { - border-color: var(--secondary-blue-outline); -} - -/*** REDFOR ***/ - -.unit[data-coalition="red"] .unit-hotgroup { - background-color: var(--secondary-red-outline); -} - -.unit[data-coalition="red"] .unit-id, -.unit[data-coalition="red"][data-has-fox-1="true"] .unit-ammo>[data-ammo-type="fox-1"], -.unit[data-coalition="red"][data-has-fox-2="true"] .unit-ammo>[data-ammo-type="fox-2"], -.unit[data-coalition="red"][data-has-fox-3="true"] .unit-ammo>[data-ammo-type="fox-3"], -.unit[data-coalition="red"][data-has-other-ammo="true"] .unit-ammo>[data-ammo-type="other"], -.unit[data-coalition="red"] .unit-fuel-level, -.unit[data-coalition="red"] .unit-vvi-heading { - background: var(--primary-red); - border-color: var(--secondary-red-outline); - color: var(--secondary-red-outline); -} - -.unit[data-coalition="red"][data-is-selected="true"] .unit-id { - color: var(--primary-red); -} - -.unit[data-coalition="red"] .unit-ammo { - border-color: var(--secondary-red-outline); -} - -/**************/ - -.unit[data-is-selected="true"] .unit-spotlight { - background: var(--secondary-yellow); -} - -.unit[data-is-in-hotgroup="true"] .unit-hotgroup { - display: flex -} - -.unit[data-is-selected="true"] .unit-id { - background: white; -} - -.unit[data-is-selected="true"] .unit-selected-border { - border-color: white; -} - -.unit[data-is-selected="true"] .unit-fuel { - display: grid; -} - -.unit[data-is-selected="true"] .unit-ammo { - display: flex; -} - - -.unit[data-pilot="human"] .unit-hotgroup, -.unit[data-pilot="human"] .unit-fuel, -.unit[data-pilot="human"] .unit-ammo { - display: none; -} - -.unit .unit-summary { - align-self: center; - column-gap: 8px; - color: white; - display: flex; - flex-flow: wrap; - font-size: 12px; - justify-content: flex-end; - justify-self: flex-end; - left: -62px; - position: absolute; - row-gap: 2px; - text-shadow: -1px -1px 1px #000, 1px -1px 1px #000, -1px 1px 1px #000, 1px 1px 1px #000; - white-space: nowrap; - width: min-content; -} \ No newline at end of file diff --git a/client/public/stylesheets/visibilitycontrolpanel.css b/client/public/stylesheets/visibilitycontrolpanel.css deleted file mode 100644 index d2e77fae..00000000 --- a/client/public/stylesheets/visibilitycontrolpanel.css +++ /dev/null @@ -1,16 +0,0 @@ -#visibility-control-panel -{ - display: flex; - column-gap: 10px; -} - -#visibility-control-panel .label { - color: white; - font-size: 12px; - font-weight: 600; -} - -#visibility-control-panel .ol-vl { - height: 60%; -} - diff --git a/client/public/uikit.html b/client/public/uikit.html index 12d1ca8c..22a40189 100644 --- a/client/public/uikit.html +++ b/client/public/uikit.html @@ -14,6 +14,7 @@
Typeography
Navbar
+
Context menu
Buttons
Ground Units
Planes
@@ -99,6 +100,46 @@ +
+ +
+ +
Context menu
+
+ +
+ +
+
+
Title
+
+ +
+
+
    +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
+
+ +
+ +
+ +
+ +
+
@@ -119,7 +160,7 @@
- +
diff --git a/client/src/@types/dom.d.ts b/client/src/@types/dom.d.ts index 5f363bfb..ddeaba8d 100644 --- a/client/src/@types/dom.d.ts +++ b/client/src/@types/dom.d.ts @@ -26,4 +26,10 @@ declare global { } } +export interface ContextMenuOption { + tooltip: string; + src: string; + callback: CallableFunction; +} + export { }; \ No newline at end of file diff --git a/client/src/@types/unitdatabase.d.ts b/client/src/@types/unitdatabase.d.ts new file mode 100644 index 00000000..1df4b955 --- /dev/null +++ b/client/src/@types/unitdatabase.d.ts @@ -0,0 +1,19 @@ +interface LoadoutItemBlueprint { + name: string; + quantity: number; +} + +interface LoadoutBlueprint { + fuel: number; + items: LoadoutItemBlueprint[]; + roles: string[]; + code: string; + name: string; +} + +interface UnitBlueprint { + name: string; + label: string; + shortLabel: string; + loadouts: LoadoutBlueprint[]; +} diff --git a/client/src/controls/button.ts b/client/src/controls/button.ts deleted file mode 100644 index bb602838..00000000 --- a/client/src/controls/button.ts +++ /dev/null @@ -1,38 +0,0 @@ -export class Button { - #container: HTMLElement | null; - #srcs: string[]; - #callback: CallableFunction; - #img: any; - #state: number = 0; - - constructor(ID: string, srcs: string[], callback: CallableFunction) { - this.#container = document.getElementById(ID); - this.#srcs = srcs; - this.#callback = callback; - if (this.#container != null) { - this.#img = document.createElement("img"); - this.#img.src = this.#srcs[this.#state]; - this.#container.appendChild(this.#img); - this.#container.addEventListener("click", () => this.#onClick()); - } - } - - setState(state: number) { - if (state < this.#srcs.length) { - this.#state = state; - this.#img.src = this.#srcs[this.#state]; - } - } - - getState() { - return this.#state; - } - - #onClick() { - if (this.#img != null) { - this.setState(this.#state < this.#srcs.length - 1 ? this.#state + 1 : 0); - if (this.#callback) - this.#callback(this.#state); - } - } -} \ No newline at end of file diff --git a/client/src/controls/contextmenu.ts b/client/src/controls/contextmenu.ts index a2ed287a..ab51f0bd 100644 --- a/client/src/controls/contextmenu.ts +++ b/client/src/controls/contextmenu.ts @@ -1,61 +1,33 @@ -import { LatLng } from "leaflet"; import { getActiveCoalition, setActiveCoalition } from ".."; +import { ContextMenuOption } from "../@types/dom"; export class ContextMenu { #container: HTMLElement | null; - #display: string; constructor(id: string,) { this.#container = document.getElementById(id); - this.#display = ''; - if (this.#container != null) { - this.#container.querySelector("#coalition-switch")?.addEventListener('change', (e) => this.#onSwitch(e)) - this.#display = this.#container.style.display; - this.hide(); - } + this.#container?.querySelector("#switch")?.addEventListener('change', (e) => this.#onSwitch(e)) + this.hide(); } - show(x: number, y: number, title: string, options: any, callback: CallableFunction, showCoalition: boolean) { - /* Hide to remove buttons, if present */ - this.hide(); + show(x: number, y: number, title: string, options: ContextMenuOption[], showCoalition: boolean) { + this.#container?.classList.toggle("hide", false); + this.#container?.querySelector("#list")?.replaceChildren(...options.map((option: ContextMenuOption) => { + var li = document.createElement("li"); + var button = document.createElement("button"); + button.textContent = option.tooltip; + li.appendChild(button); + button.addEventListener("click", (e: MouseEvent) => option.callback((e.target as HTMLButtonElement).innerText)); + return button; + })); + + this.#container?.querySelector("#switch")?.classList.toggle("hide", !showCoalition); + if (this.#container != null && options.length >= 1) { - var titleDiv = this.#container.querySelector("#ol-selection-scroll-top-bar")?.querySelector(".ol-selection-scroll-title"); + var titleDiv = this.#container.querySelector("#title"); if (titleDiv) - titleDiv.innerHTML = title; - this.#container.style.display = this.#display; - - var scroll = this.#container.querySelector(".ol-selection-scroll"); - if (scroll != null) - { - for (let optionID in options) { - var node = document.createElement("div"); - node.classList.add("ol-selection-scroll-element"); - if (typeof options[optionID] === 'string' || options[optionID] instanceof String){ - node.appendChild(document.createTextNode(options[optionID])); - node.addEventListener('click', () => callback(options[optionID])); - } - else { - node.appendChild(document.createTextNode(options[optionID].tooltip)); - node.addEventListener('click', () => options[optionID].callback()); - } - scroll.appendChild(node); - } - } - - /* Hide the coalition switch if required */ - var switchContainer = this.#container.querySelector("#ol-selection-scroll-top-bar")?.querySelector("#coalition-switch-container"); - if (showCoalition == false) { - switchContainer.style.display = "none"; - document.documentElement.style.setProperty('--active-coalition-color', getComputedStyle(this.#container).getPropertyValue("--neutral-coalition-color")); - } - else { - switchContainer.style.display = "block"; - if (getActiveCoalition() == "blue") - document.documentElement.style.setProperty('--active-coalition-color', getComputedStyle(this.#container).getPropertyValue("--blue-coalition-color")); - else - document.documentElement.style.setProperty('--active-coalition-color', getComputedStyle(this.#container).getPropertyValue("--red-coalition-color")); - } + titleDiv.textContent = title; if (x - this.#container.offsetWidth / 2 + this.#container.offsetWidth < window.innerWidth) this.#container.style.left = x - this.#container.offsetWidth / 2 + "px"; @@ -66,34 +38,19 @@ export class ContextMenu { this.#container.style.top = y - 20 + "px"; else this.#container.style.top = window.innerHeight - this.#container.offsetHeight + "px"; - } } hide() { - if (this.#container != null) { - this.#container.style.display = "none"; - var buttons = this.#container.querySelectorAll(".ol-selection-scroll-element"); - var scroll = this.#container.querySelector(".ol-selection-scroll"); - if (scroll != null) - { - for (let child of buttons) { - scroll.removeChild(child); - } - } - } + this.#container?.classList.toggle("hide", true); } #onSwitch(e: any) { if (this.#container != null) { - if (e.currentTarget.checked) { - document.documentElement.style.setProperty('--active-coalition-color', getComputedStyle(this.#container).getPropertyValue("--red-coalition-color")); + if (e.currentTarget.checked) setActiveCoalition("red"); - } - else { - document.documentElement.style.setProperty('--active-coalition-color', getComputedStyle(this.#container).getPropertyValue("--blue-coalition-color")); + else setActiveCoalition("blue"); - } } } } \ No newline at end of file diff --git a/client/src/controls/dropdown.ts b/client/src/controls/dropdown.ts deleted file mode 100644 index f4dd66a1..00000000 --- a/client/src/controls/dropdown.ts +++ /dev/null @@ -1,61 +0,0 @@ -export class Dropdown { - #container: HTMLElement | null; - #options: string[]; - #open?: boolean; - #content?: HTMLElement; - #callback?: CallableFunction; - - constructor(ID: string, options: string[], callback: CallableFunction) { - this.#container = document.getElementById(ID); - this.#options = options; - this.#callback = callback; - this.close() - this.#container?.addEventListener("click", () => { - this.#open ? this.close() : this.open(); - }) - if (this.#container != null && this.#options.length > 0) - this.#container.innerHTML = this.#options[0]; - } - - open() { - if (this.#container != null) { - this.#open = true; - this.#container.classList.add("ol-dropdown-open"); - this.#container.classList.remove("ol-dropdown-closed"); - this.#content = document.createElement("div"); - this.#content.classList.add("ol-dropdown-content"); - this.#content.style.width = (this.#container.offsetWidth - this.#container.offsetHeight) + "px"; - - this.#content.style.left = this.#container.offsetLeft + "px"; - this.#content.style.top = this.#container.offsetTop + this.#container.offsetHeight + "px"; - document.body.appendChild(this.#content); - - var height = 2; - for (let optionID in this.#options) { - var node = document.createElement("div"); - node.classList.add("ol-dropdown-element"); - node.appendChild(document.createTextNode(this.#options[optionID])); - this.#content.appendChild(node); - height += node.offsetHeight + 2; - node.addEventListener('click', () => { - this.close(); - if (this.#container != null) - this.#container.innerHTML = this.#options[optionID]; - if (this.#callback != null) - this.#callback(this.#options[optionID]) - }) - } - this.#content.style.height = height + "px"; - } - } - - close() { - if (this.#container != null) { - this.#open = false; - this.#container?.classList.remove("ol-dropdown-open"); - this.#container?.classList.add("ol-dropdown-closed"); - if (this.#content != null) - document.body.removeChild(this.#content); - } - } -} \ No newline at end of file diff --git a/client/src/controls/slider.ts b/client/src/controls/slider.ts index 38b2a49e..b1564e9a 100644 --- a/client/src/controls/slider.ts +++ b/client/src/controls/slider.ts @@ -64,7 +64,7 @@ export class Slider { { this.#container.classList.toggle("active", newActive); if (!newActive && this.#value != null) - this.#value.innerHTML = "Mixed values" + this.#value.innerText = "Mixed values"; } } diff --git a/client/src/index.ts b/client/src/index.ts index f78464c7..bd2432c5 100644 --- a/client/src/index.ts +++ b/client/src/index.ts @@ -3,19 +3,14 @@ import { getDataFromDCS } from "./server/server" import { UnitsManager } from "./units/unitsmanager"; import { UnitInfoPanel } from "./panels/unitinfopanel"; import { ContextMenu } from "./controls/contextmenu"; -import { Dropdown } from "./controls/dropdown"; import { ConnectionStatusPanel } from "./panels/connectionstatuspanel"; import { MissionData } from "./missiondata/missiondata"; import { UnitControlPanel } from "./panels/unitcontrolpanel"; import { MouseInfoPanel } from "./panels/mouseinfopanel"; -import { Slider } from "./controls/slider"; import { AIC } from "./aic/aic"; - -import { VisibilityControlPanel } from "./panels/visibilitycontrolpanel"; import { ATC } from "./atc/ATC"; import { FeatureSwitches } from "./FeatureSwitches"; import { LogPanel } from "./panels/logpanel"; -import { Button } from "./controls/button"; var map: Map; var contextMenu: ContextMenu; @@ -23,24 +18,18 @@ var contextMenu: ContextMenu; var unitsManager: UnitsManager; var missionData: MissionData; +var aic: AIC; +var atc: ATC; + var unitInfoPanel: UnitInfoPanel; var connectionStatusPanel: ConnectionStatusPanel; var unitControlPanel: UnitControlPanel; var mouseInfoPanel: MouseInfoPanel; -var visibilityControlPanel: VisibilityControlPanel; var logPanel: LogPanel; -var mapSourceDropdown: Dropdown; - -var aic: AIC; -var aicToggleButton: Button; -var aicHelpButton: Button; - -var atc: ATC; -var atcToggleButton: Button; - -var connected: boolean; -var activeCoalition: string; +var connected: boolean = false; +var activeCoalition: string = "blue"; +var refreshData: boolean = true; var featureSwitches; @@ -53,86 +42,57 @@ function setup() { unitsManager = new UnitsManager(); missionData = new MissionData(); - contextMenu = new ContextMenu("selection-scroll"); + contextMenu = new ContextMenu("contextmenu"); unitInfoPanel = new UnitInfoPanel("unit-info-panel"); unitControlPanel = new UnitControlPanel("unit-control-panel"); - mapSourceDropdown = new Dropdown("map-source-dropdown", map.getLayers(), (option: string) => map.setLayer(option)); connectionStatusPanel = new ConnectionStatusPanel("connection-status-panel"); mouseInfoPanel = new MouseInfoPanel("mouse-info-panel"); - visibilityControlPanel = new VisibilityControlPanel("visibility-control-panel"); - logPanel = new LogPanel("log-panel"); + //logPanel = new LogPanel("log-panel"); missionData = new MissionData(); /* AIC */ - let aicFeatureSwitch = featureSwitches.getSwitch( "aic" ); - if ( aicFeatureSwitch?.isEnabled() ) { aic = new AIC(); - - aicToggleButton = new Button( "toggle-aic-button", ["images/buttons/radar.svg"], () => { - aic.toggleStatus(); - }); - - aicHelpButton = new Button( "aic-help-button", [ "images/buttons/question-mark.svg" ], () => { - aic.toggleHelp(); - }); + // TODO: add back buttons } - /* Generic clicks */ - document.addEventListener( "click", ( ev ) => { - if ( ev instanceof PointerEvent && ev.target instanceof HTMLElement ) { - if ( ev.target.classList.contains( "olympus-dialog-close" ) ) { ev.target.closest( "div.olympus-dialog" )?.classList.add( "hide" ); } - } - }); - - /*** ATC ***/ - + /* ATC */ let atcFeatureSwitch = featureSwitches.getSwitch( "atc" ); - if ( atcFeatureSwitch?.isEnabled() ) { - atc = new ATC(); - - atcToggleButton = new Button( "atc-toggle-button", [ "images/buttons/atc.svg" ], () => { - atc.toggleStatus(); - } ); - + // TODO: add back buttons } - mapSourceDropdown = new Dropdown("map-source-dropdown", map.getLayers(), (option: string) => map.setLayer(option)); - - /* Default values */ - activeCoalition = "blue"; - connected = false; - + /* On the first connection, force request of full data */ requestUpdate(); + refreshData = false; } function requestUpdate() { - getDataFromDCS(update); - + getDataFromDCS(refreshData, update); + /* Main update rate = 250ms is minimum time, equal to server update time. */ setTimeout(() => requestUpdate(), getConnected() ? 250 : 1000); - connectionStatusPanel.update(getConnected()); + getConnectionStatusPanel()?.update(getConnected()); } export function update(data: ServerData) { - unitsManager.update(data); - missionData.update(data); - logPanel.update(data); + getUnitsManager()?.update(data); + getMissionData()?.update(data); + getLogPanel()?.update(data); } export function getMap() { @@ -163,6 +123,14 @@ export function getMouseInfoPanel() { return mouseInfoPanel; } +export function getLogPanel() { + return logPanel; +} + +export function getConnectionStatusPanel() { + return connectionStatusPanel; +} + export function setActiveCoalition(newActiveCoalition: string) { activeCoalition = newActiveCoalition; } diff --git a/client/src/map/map.ts b/client/src/map/map.ts index 966e6404..1368d825 100644 --- a/client/src/map/map.ts +++ b/client/src/map/map.ts @@ -5,6 +5,7 @@ import { bearing, distance, zeroAppend } from "../other/utils"; import { aircraftDatabase } from "../units/aircraftdatabase"; import { unitTypes } from "../units/unittypes"; import { BoxSelect } from "./boxselect"; +import { ContextMenuOption } from "../@types/dom"; L.Map.addInitHook('addHandler', 'boxSelect', BoxSelect); @@ -126,16 +127,16 @@ export class Map extends L.Map { return this.#state; } - /* Selection scroll */ - showContextMenu(e: ClickEvent | SpawnEvent, title: string, options: any, callback: CallableFunction, showCoalition: boolean = false) { + /* Context Menu */ + showContextMenu(e: ClickEvent | SpawnEvent, title: string, options: ContextMenuOption[], showCoalition: boolean = false) { var x = e.x; var y = e.y; - getContextMenu().show(x, y, title, options, callback, showCoalition); + getContextMenu()?.show(x, y, title, options, showCoalition); document.dispatchEvent(new CustomEvent("mapContextMenu")); } hideContextMenu() { - getContextMenu().hide(); + getContextMenu()?.hide(); document.dispatchEvent(new CustomEvent("mapContextMenu")); } @@ -195,7 +196,7 @@ export class Map extends L.Map { { "tooltip": "Smoke", "src": "spawnSmoke.png", "callback": () => this.#smokeSpawnMenu(spawnEvent) }, //{ "tooltip": "Explosion", "src": "spawnExplosion.png", "callback": () => this.#explosionSpawnMenu(e) } ] - this.showContextMenu(spawnEvent, "Action", options, () => {}, false); + this.showContextMenu(spawnEvent, "Action", options, false); } } else if (this.#state === "MOVE_UNIT") { @@ -240,7 +241,7 @@ export class Map extends L.Map { { selectedUnitPosition = new L.LatLng(selectedUnits[0].getFlightData().latitude, selectedUnits[0].getFlightData().longitude); } - getMouseInfoPanel().update(e.latlng, this.#measurePoint, selectedUnitPosition); + getMouseInfoPanel()?.update(e.latlng, this.#measurePoint, selectedUnitPosition); this.#lastMousePosition.x = e.originalEvent.x; this.#lastMousePosition.y = e.originalEvent.y; @@ -272,9 +273,9 @@ export class Map extends L.Map { { 'coalition': true, 'tooltip': 'Transport', 'src': 'spawnTransport.png', 'callback': () => this.#selectAircraft(e, "transport") }, ] if (e.airbaseName != null) - this.showContextMenu(e, "Spawn at " + e.airbaseName, options, () => {}, true); + this.showContextMenu(e, "Spawn at " + e.airbaseName, options, true); else - this.showContextMenu(e, "Spawn air unit", options, () => {}, true); + this.showContextMenu(e, "Spawn air unit", options, true); } #groundUnitSpawnMenu(e: SpawnEvent) { @@ -287,7 +288,7 @@ export class Map extends L.Map { {'coalition': true, 'tooltip': 'Radar', 'src': 'spawnRadar.png', 'callback': () => this.#selectGroundUnit(e, "Radar")}, {'coalition': true, 'tooltip': 'Unarmed', 'src': 'spawnUnarmed.png', 'callback': () => this.#selectGroundUnit(e, "Unarmed")} ] - this.showContextMenu(e, "Spawn ground unit", options, () => {}, true); + this.showContextMenu(e, "Spawn ground unit", options, true); } #smokeSpawnMenu(e: SpawnEvent) { @@ -299,7 +300,7 @@ export class Map extends L.Map { {'tooltip': 'Green smoke', 'src': 'spawnSmoke.png', 'callback': () => {this.hideContextMenu(); spawnSmoke('green', e.latlng)}, 'tint': 'green'}, {'tooltip': 'Orange smoke', 'src': 'spawnSmoke.png', 'callback': () => {this.hideContextMenu(); spawnSmoke('orange', e.latlng)}, 'tint': 'orange'}, ] - this.showContextMenu(e, "Spawn smoke", options, () => {}, false); + this.showContextMenu(e, "Spawn smoke", options, false); } #explosionSpawnMenu(e: SpawnEvent) { @@ -310,12 +311,14 @@ export class Map extends L.Map { #selectAircraft(e: SpawnEvent, role: string) { this.hideContextMenu(); var options = aircraftDatabase.getLabelsByRole(role); - this.showContextMenu(e, "Select aircraft", options, (label: string) => { - this.hideContextMenu(); - var name = aircraftDatabase.getNameByLabel(label); - if (name != null) - this.#unitSelectPayload(e, name, role); - }, true); + this.showContextMenu(e, "Select aircraft", + options.map((option: string) => { + return {tooltip: option, src: "", callback: (label: string) => { + this.hideContextMenu(); + var name = aircraftDatabase.getNameByLabel(label); + if (name != null) + this.#unitSelectPayload(e, name, role); + }}}), true); } /* Show weapon selection for air units */ @@ -325,11 +328,13 @@ export class Map extends L.Map { //options = payloadNames[unitType] if (options != undefined && options.length > 0) { options.sort(); - this.showContextMenu({x: e.x, y: e.y, latlng: e.latlng}, "Select loadout", options, (loadoutName: string) => { - this.hideContextMenu(); - var loadout = aircraftDatabase.getLoadoutsByName(unitType, loadoutName); - spawnAircraft(unitType, e.latlng, getActiveCoalition(), loadout != null? loadout.code: "", e.airbaseName); - }, true); + this.showContextMenu({x: e.x, y: e.y, latlng: e.latlng}, "Select loadout", + options.map((option: string) => { + return {tooltip: option, src: "", callback: (loadoutName: string) => { + this.hideContextMenu(); + var loadout = aircraftDatabase.getLoadoutsByName(unitType, loadoutName); + spawnAircraft(unitType, e.latlng, getActiveCoalition(), loadout != null? loadout.code: "", e.airbaseName); + }}}), true); } else { spawnAircraft(unitType, e.latlng, getActiveCoalition()); @@ -342,10 +347,12 @@ export class Map extends L.Map { this.hideContextMenu(); var options = unitTypes.vehicles[group]; options.sort(); - this.showContextMenu(e, "Select ground unit", options, (unitType: string) => { - this.hideContextMenu(); - spawnGroundUnit(unitType, e.latlng, getActiveCoalition()); - }, true); + this.showContextMenu(e, "Select ground unit", + options.map((option: string) => { + return {tooltip: option, src: "", callback: (unitType: string) => { + this.hideContextMenu(); + spawnGroundUnit(unitType, e.latlng, getActiveCoalition()); + }}}), true); } #drawMeasureLine() diff --git a/client/src/missiondata/airbasemarker.ts b/client/src/missiondata/airbase.ts similarity index 97% rename from client/src/missiondata/airbasemarker.ts rename to client/src/missiondata/airbase.ts index 36bd867a..593312df 100644 --- a/client/src/missiondata/airbasemarker.ts +++ b/client/src/missiondata/airbase.ts @@ -7,7 +7,7 @@ export interface AirbaseOptions src: string } -export class AirbaseMarker extends L.Marker +export class Airbase extends L.Marker { #name: string = ""; #coalitionID: number = -1; diff --git a/client/src/missiondata/missiondata.ts b/client/src/missiondata/missiondata.ts index c1a018a3..1320c71c 100644 --- a/client/src/missiondata/missiondata.ts +++ b/client/src/missiondata/missiondata.ts @@ -1,7 +1,7 @@ import { Marker, LatLng, Icon } from "leaflet"; import { getMap, getUnitsManager } from ".."; import { SpawnEvent } from "../map/map"; -import { AirbaseMarker } from "./airbasemarker"; +import { Airbase } from "./airbase"; var bullseyeIcons = [ new Icon({ iconUrl: 'images/bullseye0.png', iconAnchor: [30, 30]}), @@ -14,7 +14,7 @@ export class MissionData #bullseyes : any; //TODO declare interface #bullseyeMarkers: any; #airbases : any; //TODO declare interface - #airbasesMarkers: {[name: string]: AirbaseMarker}; + #airbasesMarkers: {[name: string]: Airbase}; constructor() { @@ -59,7 +59,7 @@ export class MissionData var airbase = this.#airbases[idx] if (this.#airbasesMarkers[idx] === undefined) { - this.#airbasesMarkers[idx] = new AirbaseMarker({ + this.#airbasesMarkers[idx] = new Airbase({ position: new LatLng(airbase.lat, airbase.lng), name: airbase.callsign, src: "images/airbase.png"}).addTo(getMap()); @@ -79,8 +79,10 @@ export class MissionData options = ["Spawn unit", "Land here"]; else options = ["Spawn unit"]; - getMap().showContextMenu(e.originalEvent, e.sourceTarget.getName(), options, (option: string) => this.#onAirbaseOptionSelection(e, option), false); - + + getMap().showContextMenu(e.originalEvent, e.sourceTarget.getName(), + options.map((option) => {return {tooltip: option, src: "", callback: (label: string) => {this.#onAirbaseOptionSelection(e, label)}}}, false) + ) } #onAirbaseOptionSelection(e: any, option: string) { diff --git a/client/src/panels/panel.ts b/client/src/panels/panel.ts index acb8e5c0..c88c5ad0 100644 --- a/client/src/panels/panel.ts +++ b/client/src/panels/panel.ts @@ -1,19 +1,16 @@ export class Panel { #element: HTMLElement - #display: string; constructor(ID: string) { this.#element = document.getElementById(ID); - this.#display = ''; - this.#display = this.#element.style.display; } show() { - this.#element.style.display = this.#display; + this.#element.classList.toggle("hide", false); } hide() { - this.#element.style.display = "none"; + this.#element.classList.toggle("hide", true); } getElement() { diff --git a/client/src/panels/toppanel.ts b/client/src/panels/toppanel.ts new file mode 100644 index 00000000..e69de29b diff --git a/client/src/panels/unitcontrolpanel.ts b/client/src/panels/unitcontrolpanel.ts index 4c7e2b07..6ffcc274 100644 --- a/client/src/panels/unitcontrolpanel.ts +++ b/client/src/panels/unitcontrolpanel.ts @@ -3,66 +3,42 @@ import { Slider } from "../controls/slider"; import { Aircraft, AirUnit, GroundUnit, Helicopter, NavyUnit, Unit } from "../units/unit"; import { Panel } from "./panel"; -interface Button { - id: string, - value: string, - element: null | HTMLElement -} +var ROEs: string[] = ["Free", "Designated free", "Designated", "Return", "Hold"]; +var reactionsToThreat: string[] = [ "None", "Passive", "Evade", "Escape", "Abort"]; +var minSpeedValues: {[key: string]: number} = {Aircraft: 100, Helicopter: 0, NavyUnit: 0, GroundUnit: 0}; +var maxSpeedValues: {[key: string]: number} = {Aircraft: 800, Helicopter: 300, NavyUnit: 60, GroundUnit: 60}; +var minAltitudeValues: {[key: string]: number} = {Aircraft: 500, Helicopter: 0, NavyUnit: 0, GroundUnit: 0}; +var maxAltitudeValues: {[key: string]: number} = {Aircraft: 50000, Helicopter: 10000, NavyUnit: 60, GroundUnit: 60}; export class UnitControlPanel extends Panel { #altitudeSlider: Slider; #airspeedSlider: Slider; - #formationCreationContainer: HTMLElement; - #ROEButtonsContainer: HTMLElement; - #reactionToThreatButtonsContainer: HTMLElement; - #selectedUnitsContainer: HTMLElement; - #ROEButtons: Button[] = [ - {id: "#free", value: "Free", element: null}, - {id: "#designated-free", value: "Designated free", element: null}, - {id: "#designated", value: "Designated", element: null}, - {id: "#return", value: "Return", element: null}, - {id: "#hold", value: "Hold", element: null} - ] - #reactionToThreatButtons: Button[] = [ - {id: "#none", value: "None", element: null}, - {id: "#passive", value: "Passive", element: null}, - {id: "#evade", value: "Evade", element: null}, - {id: "#escape", value: "Escape", element: null}, - {id: "#abort", value: "Abort", element: null} - ] - + #optionButtons: {[key: string]: HTMLButtonElement[]} = {} + constructor(ID: string) { super(ID); - /* Selected units container */ - this.#selectedUnitsContainer = (this.getElement().querySelector("#selected-units-container")); - /* Unit control sliders */ this.#altitudeSlider = new Slider("altitude-slider", 0, 100, "ft", (value: number) => getUnitsManager().selectedUnitsSetAltitude(value * 0.3048)); this.#airspeedSlider = new Slider("airspeed-slider", 0, 100, "kts", (value: number) => getUnitsManager().selectedUnitsSetSpeed(value / 1.94384)); - /* Formation control buttons */ - this.#formationCreationContainer = (this.getElement().querySelector("#formation-creation-container")); - //var createButton = this.#formationCreationContainer.querySelector("#create-formation"); - //createButton?.addEventListener("click", () => getUnitsManager().selectedUnitsCreateFormation()); - //var undoButton = this.#formationCreationContainer.querySelector("#undo-formation"); - //undoButton?.addEventListener("click", () => getUnitsManager().selectedUnitsUndoFormation()); - - /* ROE buttons */ - this.#ROEButtonsContainer = (this.getElement().querySelector("#roe-buttons-container")); - for (let button of this.#ROEButtons) - { - button.element = (this.#ROEButtonsContainer.querySelector(button.id)); - button.element?.addEventListener("click", () => getUnitsManager().selectedUnitsSetROE(button.value)); - } - - /* Reaction to threat buttons */ - this.#reactionToThreatButtonsContainer = (this.getElement().querySelector("#reaction-to-threat-buttons-container")); - for (let button of this.#reactionToThreatButtons) - { - button.element = (this.#reactionToThreatButtonsContainer.querySelector(button.id)); - button.element?.addEventListener("click", () => getUnitsManager().selectedUnitsSetReactionToThreat(button.value)); - } + /* Option buttons */ + this.#optionButtons["ROE"] = ROEs.map((option: string) => { + var button = document.createElement("button"); + button.innerText = option; + button.addEventListener("click", () => getUnitsManager().selectedUnitsSetROE(button.value)); + return button; + }) + + this.#optionButtons["reactionToThreat"] = reactionsToThreat.map((option: string) => { + var button = document.createElement("button"); + button.innerText = option; + button.addEventListener("click", () => getUnitsManager().selectedUnitsSetROE(button.value)); + return button; + }) + + this.getElement().querySelector("#roe-buttons-container")?.append(...this.#optionButtons["ROE"]); + this.getElement().querySelector("#reaction-to-threat-buttons-container")?.append(...this.#optionButtons["reactionToThreat"]); this.hide(); } @@ -70,16 +46,22 @@ export class UnitControlPanel extends Panel { update(units: Unit[]) { if (this.getElement() != null) { - this.#addUnitsButtons(units); - //this.#showFormationButtons(units); - this.#showFlightControlSliders(units); + this.getElement().querySelector("#selected-units-container")?.replaceChildren(...units.map((unit: Unit) => + { + var button = document.createElement("button"); + button.innerText = unit.getData().unitName; + button.addEventListener("click", () => getUnitsManager().selectUnit(unit.ID, true)); + return (button); + })); - for (let button of this.#ROEButtons) - button.element?.classList.toggle("white", this.#getROE(units) === button.value); - - for (let button of this.#reactionToThreatButtons) - button.element?.classList.toggle("white", this.#getReactionToThreat(units) === button.value); + this.#optionButtons["ROE"].forEach((button: HTMLButtonElement) => { + button.classList.toggle("active", units.every((unit: Unit) => unit.getOptionsData().ROE === button.value)) + }); + + this.#optionButtons["reactionToThreat"].forEach((button: HTMLButtonElement) => { + button.classList.toggle("active", units.every((unit: Unit) => unit.getOptionsData().reactionToThreat === button.value)) + }); } } @@ -88,263 +70,18 @@ export class UnitControlPanel extends Panel { this.#airspeedSlider.show(); this.#altitudeSlider.show(); - if (this.#checkAllUnitsAircraft(units)) - { - this.#airspeedSlider.setMinMax(100, 600); - this.#altitudeSlider.setMinMax(0, 50000); - } - else if (this.#checkAllUnitsHelicopter(units)) - { - this.#airspeedSlider.setMinMax(0, 200); - this.#altitudeSlider.setMinMax(0, 10000); - } - else if (this.#checkAllUnitsGroundUnit(units)) - { - this.#airspeedSlider.setMinMax(0, 60); - this.#altitudeSlider.hide(); - } - else if (this.#checkAllUnitsNavyUnit(units)) - { - this.#airspeedSlider.setMinMax(0, 60); - this.#altitudeSlider.hide(); - } - else { - this.#airspeedSlider.hide(); - this.#altitudeSlider.hide(); - } + var unitsType = getUnitsManager().getSelectedUnitsType(); + var targetAltitude = getUnitsManager().getSelectedUnitsTargetAltitude(); + var targetSpeed = getUnitsManager().getSelectedUnitsTargetSpeed(); - var targetSpeed = this.#getTargetAirspeed(units); - if (targetSpeed != null) - { - this.#airspeedSlider.setActive(true); - this.#airspeedSlider.setValue(targetSpeed * 1.94384); - } - else - { - this.#airspeedSlider.setActive(false); - } + if (["GroundUnit", "NavyUnit"].includes(unitsType)) + this.#altitudeSlider.hide() - var targetAltitude = this.#getTargetAltitude(units); - if (targetAltitude != null) - { - this.#altitudeSlider.setActive(true); - this.#altitudeSlider.setValue(targetAltitude / 0.3048); - } - else - { - this.#altitudeSlider.setActive(false); - } - } - - #addUnitsButtons(units: Unit[]) - { - /* Remove any pre-existing unit button */ - var elements = this.#selectedUnitsContainer.getElementsByClassName("js-unit-container"); - while (elements.length > 0) - this.#selectedUnitsContainer.removeChild(elements[0]) - - /* Create all the units buttons */ - for (let unit of units) - { - this.#addUnitButton(unit, this.#selectedUnitsContainer); - if (unit.getFormationData().isLeader) - for (let wingman of unit.getWingmen()) - this.#addUnitButton(wingman, this.#selectedUnitsContainer); - } - } - - #addUnitButton(unit: Unit, container: HTMLElement) - { - var el = document.createElement("div"); - - /* Unit name (actually type, but DCS calls it name for some reason) */ - var nameDiv = document.createElement("div"); - nameDiv.classList.add("ol-rounded-container-small"); - if (unit.getData().name.length >= 7) - nameDiv.innerHTML = `${unit.getData().name.substring(0, 4)} ...`; - else - nameDiv.innerHTML = `${unit.getData().name}`; - - /* Unit icon */ - var icon = document.createElement("img"); - if (unit.getFormationData().isLeader) - icon.src = "images/icons/formation.png" - else if (unit.getFormationData().isWingman) - { - var wingmen = unit.getLeader()?.getWingmen(); - if (wingmen && wingmen.lastIndexOf(unit) == wingmen.length - 1) - icon.src = "images/icons/formation-end.svg" - else - icon.src = "images/icons/formation-middle.svg" - } - - else - icon.src = "images/icons/singleton.png" - - el.innerHTML = unit.getData().unitName; - - el.prepend(nameDiv); - - /* Show the icon only for air units */ - if ((unit instanceof AirUnit)) - el.append(icon); - - el.classList.add("ol-rounded-container", "js-unit-container"); - - if (!unit.getSelected()) - el.classList.add("not-selected") - - /* Set background color */ - el.classList.toggle("red", unit.getMissionData().coalition === "red"); - icon.classList.toggle("red", unit.getMissionData().coalition === "red"); - el.classList.toggle("blue", unit.getMissionData().coalition === "blue"); - icon.classList.toggle("blue", unit.getMissionData().coalition === "blue"); - el.classList.toggle("neutral", unit.getMissionData().coalition === "neutral"); - icon.classList.toggle("neutral", unit.getMissionData().coalition === "neutral"); - - el.addEventListener("click", () => getUnitsManager().selectUnit(unit.ID)); - container.appendChild(el); - } - - #showFormationButtons(units: Unit[]) - { - var createButton = this.#formationCreationContainer.querySelector("#create-formation"); - var undoButton = this.#formationCreationContainer.querySelector("#undo-formation"); - if (createButton && undoButton && this.#checkAllUnitsAir(units)) - { - if (!this.#checkUnitsAlreadyInFormation(units)) - { - createButton.style.display = ''; - undoButton.style.display = 'none'; - } - else if (this.#checkUnitsAlreadyInFormation(units) && this.#checkAllUnitsSameFormation(units)) - { - createButton.style.display = 'none'; - undoButton.style.display = ''; - } - else - { - createButton.style.display = 'none'; - undoButton.style.display = 'none'; - } - } - } - - #checkAllUnitsAir(units: Unit[]) - { - for (let unit of units) - if (!(unit instanceof AirUnit)) - return false - return true - } - - #checkAllUnitsAircraft(units: Unit[]) - { - for (let unit of units) - if (!(unit instanceof Aircraft)) - return false - return true - } - - #checkAllUnitsHelicopter(units: Unit[]) - { - for (let unit of units) - if (!(unit instanceof Helicopter)) - return false - return true - } - - #checkAllUnitsGroundUnit(units: Unit[]) - { - for (let unit of units) - if (!(unit instanceof GroundUnit)) - return false - return true - } - - #checkAllUnitsNavyUnit(units: Unit[]) - { - for (let unit of units) - if (!(unit instanceof NavyUnit)) - return false - return true - } - - #checkAllUnitsSameFormation(units: Unit[]) - { - var leaderFound = false; - for (let unit of units) - { - if (unit.getFormationData().isLeader) - { - if (leaderFound) - return false - else - leaderFound = true; - } - if (!unit.getFormationData().isLeader) - return false - } - return true - } - - #checkUnitsAlreadyInFormation(units: Unit[]) - { - for (let unit of units) - if (unit.getFormationData().isLeader) - return true - return false - } - - #getTargetAirspeed(units: Unit[]) - { - var airspeed = null; - for (let unit of units) - { - if (unit.getTaskData().targetSpeed != airspeed && airspeed != null) - return null - else - airspeed = unit.getTaskData().targetSpeed; - } - return airspeed; - } - - #getTargetAltitude(units: Unit[]) - { - var altitude = null; - for (let unit of units) - { - if (unit.getTaskData().targetAltitude != altitude && altitude != null) - return null - else - altitude = unit.getTaskData().targetAltitude; - } - return altitude; - } - - #getROE(units: Unit[]) - { - var ROE = null; - for (let unit of units) - { - if (unit.getOptionsData().ROE !== ROE && ROE != null) - return null - else - ROE = unit.getOptionsData().ROE; - } - return ROE; - } - - #getReactionToThreat(units: Unit[]) - { - var reactionToThreat = null; - for (let unit of units) - { - if (unit.getOptionsData().reactionToThreat !== reactionToThreat && reactionToThreat != null) - return null - else - reactionToThreat = unit.getOptionsData().reactionToThreat; - } - return reactionToThreat; + this.#airspeedSlider.setMinMax(minSpeedValues[unitsType], maxSpeedValues[unitsType]); + this.#altitudeSlider.setMinMax(minAltitudeValues[unitsType], maxAltitudeValues[unitsType]); + this.#airspeedSlider.setActive(targetSpeed != undefined); + this.#airspeedSlider.setValue(targetSpeed * 1.94384); + this.#altitudeSlider.setActive(targetAltitude != undefined); + this.#altitudeSlider.setValue(targetAltitude / 0.3048); } } \ No newline at end of file diff --git a/client/src/panels/unitinfopanel.ts b/client/src/panels/unitinfopanel.ts index 80c2d2fc..b6024861 100644 --- a/client/src/panels/unitinfopanel.ts +++ b/client/src/panels/unitinfopanel.ts @@ -36,16 +36,16 @@ export class UnitInfoPanel extends Panel { update(unit: Unit) { if (this.getElement() != null) { /* Set the unit info */ - this.#unitName.innerHTML = unit.getData().unitName; - this.#groupName.innerHTML = unit.getData().groupName; - this.#name.innerHTML = unit.getData().name; - this.#heading.innerHTML = String(Math.floor(rad2deg(unit.getFlightData().heading)) + " °"); - this.#altitude.innerHTML = String(Math.floor(unit.getFlightData().altitude / 0.3048) + " ft"); - this.#groundSpeed.innerHTML = String(Math.floor(unit.getFlightData().speed * 1.94384) + " kts"); - this.#fuel.innerHTML = String(unit.getMissionData().fuel + "%"); - this.#latitude.innerHTML = ConvertDDToDMS(unit.getFlightData().latitude, false); - this.#longitude.innerHTML = ConvertDDToDMS(unit.getFlightData().longitude, true); - this.#task.innerHTML = unit.getTaskData().currentTask !== ""? unit.getTaskData().currentTask: "No task"; + this.#unitName.innerText = unit.getData().unitName; + this.#groupName.innerText = unit.getData().groupName; + this.#name.innerText = unit.getData().name; + this.#heading.innerText = String(Math.floor(rad2deg(unit.getFlightData().heading)) + " °"); + this.#altitude.innerText = String(Math.floor(unit.getFlightData().altitude / 0.3048) + " ft"); + this.#groundSpeed.innerText = String(Math.floor(unit.getFlightData().speed * 1.94384) + " kts"); + this.#fuel.innerText = String(unit.getMissionData().fuel + "%"); + this.#latitude.innerText = ConvertDDToDMS(unit.getFlightData().latitude, false); + this.#longitude.innerText = ConvertDDToDMS(unit.getFlightData().longitude, true); + this.#task.innerText = unit.getTaskData().currentTask !== ""? unit.getTaskData().currentTask: "No task"; /* Set the class of the task container */ this.#task.classList.toggle("red", unit.getMissionData().coalition === "red"); @@ -69,7 +69,7 @@ export class UnitInfoPanel extends Panel { var amount = ammo.count; var el = document.createElement("div") el.classList.add("js-loadout-element", "ol-rectangular-container-dark") - el.innerHTML = amount + "x" + displayName; + el.innerText = amount + "x" + displayName; this.#loadoutContainer.appendChild(el); } } \ No newline at end of file diff --git a/client/src/panels/visibilitycontrolpanel.ts b/client/src/panels/visibilitycontrolpanel.ts deleted file mode 100644 index 8f12ed15..00000000 --- a/client/src/panels/visibilitycontrolpanel.ts +++ /dev/null @@ -1,80 +0,0 @@ -import { AirUnit, GroundUnit, NavyUnit, Weapon } from "../units/unit"; - -export class VisibilityControlPanel { - #element: HTMLElement - - constructor(ID: string) { - this.#element = document.getElementById(ID); - - if (this.#element != null) - { - var airVisibilityCheckbox = this.#element.querySelector("#air-visibility"); - var groundVisibilityCheckbox = this.#element.querySelector("#ground-visibility"); - var navyVisibilityCheckbox = this.#element.querySelector("#navy-visibility"); - var weaponVisibilityCheckbox = this.#element.querySelector("#weapon-visibility"); - - airVisibilityCheckbox?.addEventListener("change", () => this.#onChange()); - groundVisibilityCheckbox?.addEventListener("change", () => this.#onChange()); - navyVisibilityCheckbox?.addEventListener("change", () => this.#onChange()); - weaponVisibilityCheckbox?.addEventListener("change", () => this.#onChange()); - - var fullVisibilitySelection = this.#element.querySelector("#full-visibility"); - var partialVisibilitySelection = this.#element.querySelector("#partial-visibility"); - var minimalVisibilitySelection = this.#element.querySelector("#minimal-visibility"); - - fullVisibilitySelection?.addEventListener("change", () => this.#onChange()); - partialVisibilitySelection?.addEventListener("change", () => this.#onChange()); - minimalVisibilitySelection?.addEventListener("change", () => this.#onChange()); - - var uncontrolledVisibilityCheckbox = this.#element.querySelector("#uncontrolled-visibility"); - uncontrolledVisibilityCheckbox?.addEventListener("change", () => this.#onChange()); - } - } - - #onChange(){ - if (this.#element != null) - { - var fullVisibilitySelection = this.#element.querySelector("#full-visibility"); - var partialVisibilitySelection = this.#element.querySelector("#partial-visibility"); - var minimalVisibilitySelection = this.#element.querySelector("#minimal-visibility"); - - var activeVisibility = ""; - if (fullVisibilitySelection.checked) - activeVisibility = "full"; - else if (partialVisibilitySelection.checked) - activeVisibility = "partial"; - else if (minimalVisibilitySelection.checked) - activeVisibility = "minimal"; - - var uncontrolledVisibilityCheckbox = this.#element.querySelector("#uncontrolled-visibility"); - var uncontrolledVisibility = !uncontrolledVisibilityCheckbox.checked; - - //var airVisibilityCheckbox = this.#element.querySelector("#air-visibility"); - //if (airVisibilityCheckbox.checked) - // AirUnit.setVisibility({human: "full", AI: activeVisibility, uncontrolled: uncontrolledVisibility? activeVisibility: "hidden", dead: "hidden"}); - //else - // AirUnit.setVisibility({human: "hidden", AI: "hidden", uncontrolled: "hidden", dead: "hidden"}); -// - //var groundVisibilityCheckbox = this.#element.querySelector("#ground-visibility"); - //if (groundVisibilityCheckbox.checked) - // GroundUnit.setVisibility({human: activeVisibility, AI: activeVisibility, uncontrolled: uncontrolledVisibility? activeVisibility: "hidden", dead: "hidden"}); - //else - // GroundUnit.setVisibility({human: "hidden", AI: "hidden", uncontrolled: "hidden", dead: "hidden"}); -// - //var navyVisibilityCheckbox = this.#element.querySelector("#navy-visibility"); - //if (navyVisibilityCheckbox.checked) - // NavyUnit.setVisibility({human: activeVisibility, AI: activeVisibility, uncontrolled: uncontrolledVisibility? activeVisibility: "hidden", dead: "hidden"}); - //else - // NavyUnit.setVisibility({human: "hidden", AI: "hidden", uncontrolled: "hidden", dead: "hidden"}); -// - //var weaponVisibilityCheckbox = this.#element.querySelector("#weapon-visibility"); - //if (weaponVisibilityCheckbox.checked) - // Weapon.setVisibility({human: activeVisibility, AI: activeVisibility, uncontrolled: uncontrolledVisibility? activeVisibility: "hidden", dead: "hidden"}); - //else - // Weapon.setVisibility({human: "hidden", AI: "hidden", uncontrolled: "hidden", dead: "hidden"}); - } - - } - - -} \ No newline at end of file diff --git a/client/src/server/server.ts b/client/src/server/server.ts index 23688cf5..7c6675f9 100644 --- a/client/src/server/server.ts +++ b/client/src/server/server.ts @@ -1,11 +1,16 @@ import * as L from 'leaflet' -import { getUnitsManager, setConnected } from '..'; -import { ConvertDDToDMS } from '../other/utils'; +import { setConnected } from '..'; /* Edit here to change server address */ -var RESTaddress = "http://localhost:30000/restdemo"; +const RESTaddress = "http://localhost:30000/olympus"; +const UNITS_URI = "units"; +const FULL_UPDATE_URI = "full"; +const PARTIAL_UPDATE_URI = "partial"; +const LOGS_URI = "logs"; +const AIRBASES_URI = "airbases"; +const BULLSEYE_URI = "bullseye"; -export function getDataFromDCS(callback: CallableFunction) { +export function getDataFromDCS(refresh: boolean, callback: CallableFunction) { /* Request the updated unit data from the server */ var xmlHttp = new XMLHttpRequest(); xmlHttp.open("GET", RESTaddress, true); @@ -20,7 +25,9 @@ export function getDataFromDCS(callback: CallableFunction) { console.error("An error occurred during the XMLHttpRequest"); setConnected(false); }; - xmlHttp.send(null); + + var request = { "refresh": refresh } + xmlHttp.send(JSON.stringify(request)); } export function addDestination(ID: number, path: any) { diff --git a/client/src/units/unit.ts b/client/src/units/unit.ts index d91ad4b1..a351d08b 100644 --- a/client/src/units/unit.ts +++ b/client/src/units/unit.ts @@ -49,37 +49,28 @@ export class Unit extends Marker { this.on('contextmenu', (e) => this.#onContextMenu(e)); var icon = new DivIcon({ - html: `
-
-
-
-
-
-
${aircraftDatabase.getShortLabelByName(this.getData().name)}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
${this.getData().unitName}
-
-
-
-
`, + html: ` + + + + 3 + + + ${aircraftDatabase.getShortLabelByName(this.getData().name)} + + + + + + + + ${this.getData().unitName} + + + + `, className: 'ol-unit-marker', - iconAnchor: [30, 30] + iconAnchor: [60, 60] }); this.setIcon(icon); @@ -88,19 +79,19 @@ export class Unit extends Marker { this.#targetsPolylines = []; } - update(response: UnitData) { + setData(data: UnitData) { var updateMarker = true; - //if (this.#data.flightData.latitude != response.flightData.latitude || - // this.#data.flightData.longitude != response.flightData.longitude || - // this.#data.alive != response.alive || + //if (this.getFlightData().latitude != response.flightData.latitude || + // this.getFlightData().longitude != response.flightData.longitude || + // this.getData().alive != response.alive || // this.#forceUpdate || // !getMap().hasLayer(this.#marker)) // updateMarker = true; - this.#data = response; + this.#data = data; /* Dead units can't be selected */ - this.setSelected(this.getSelected() && this.#data.alive) + this.setSelected(this.getSelected() && this.getData().alive) if (updateMarker) this.#updateMarker(); @@ -114,9 +105,33 @@ export class Unit extends Marker { this.#clearPath(); } + getData() { + return this.#data; + } + + getFlightData() { + return this.getData().flightData; + } + + getTaskData() { + return this.getData().taskData; + } + + getMissionData() { + return this.getData().missionData; + } + + getFormationData() { + return this.getData().formationData; + } + + getOptionsData() { + return this.getData().optionsData; + } + setSelected(selected: boolean) { /* Only alive units can be selected. Some units are not selectable (weapons) */ - if ((this.#data.alive || !selected) && this.#selectable && this.#selected != selected) { + if ((this.getData().alive || !selected) && this.#selectable && this.#selected != selected) { this.#selected = selected; this.getElement()?.querySelector(".unit")?.setAttribute("data-is-selected", String(this.getSelected())); document.dispatchEvent(new CustomEvent("unitSelection", { detail: this })); @@ -137,8 +152,8 @@ export class Unit extends Marker { addDestination(latlng: L.LatLng) { var path: any = {}; - if (this.#data.taskData.activePath != null) { - path = this.#data.taskData.activePath; + if (this.getTaskData().activePath != null) { + path = this.getTaskData().activePath; path[(Object.keys(path).length + 1).toString()] = latlng; } else { @@ -148,7 +163,7 @@ export class Unit extends Marker { } clearDestinations() { - this.#data.taskData.activePath = null; + this.getTaskData().activePath = null; } getHidden() { @@ -156,7 +171,7 @@ export class Unit extends Marker { } getLeader() { - return getUnitsManager().getUnitByID(this.#data.formationData.leaderID); + return getUnitsManager().getUnitByID(this.getFormationData().leaderID); } getFormation() { @@ -165,8 +180,8 @@ export class Unit extends Marker { getWingmen() { var wingmen: Unit[] = []; - if (this.#data.formationData.wingmenIDs != null) { - for (let ID of this.#data.formationData.wingmenIDs) { + if (this.getFormationData().wingmenIDs != null) { + for (let ID of this.getFormationData().wingmenIDs) { var unit = getUnitsManager().getUnitByID(ID) if (unit) wingmen.push(unit); @@ -179,30 +194,6 @@ export class Unit extends Marker { this.#forceUpdate = true; } - getData() { - return this.#data; - } - - getFlightData() { - return this.#data.flightData; - } - - getTaskData() { - return this.#data.taskData; - } - - getMissionData() { - return this.#data.missionData; - } - - getFormationData() { - return this.#data.formationData; - } - - getOptionsData() { - return this.#data.optionsData; - } - attackUnit(targetID: number) { /* Call DCS attackUnit function */ if (this.ID != targetID) { @@ -241,20 +232,14 @@ export class Unit extends Marker { setReactionToThreat(this.ID, reactionToThreat); } - delete() { - deleteUnit(this.ID); - } - - /* - setformation(formation) - { - } - */ - setLeader(isLeader: boolean, wingmenIDs: number[] = []) { setLeader(this.ID, isLeader, wingmenIDs); } + delete() { + deleteUnit(this.ID); + } + #onClick(e: any) { this.#timer = setTimeout(() => { if (!this.#preventClick) { @@ -279,8 +264,7 @@ export class Unit extends Marker { 'Attack', 'Follow' ] - - getMap().showContextMenu(e.originalEvent, "Action: " + this.#data.unitName, options, (action: string) => this.#executeAction(action)); + getMap().showContextMenu(e.originalEvent, "Action: " + this.getData().unitName, options.map((option: string) => {return {tooltip: option, src: "", callback: (action: string) => this.#executeAction(action)}})); } #executeAction(action: string) { @@ -300,49 +284,48 @@ export class Unit extends Marker { getMap().removeLayer(this); } else { - this.setLatLng(new LatLng(this.#data.flightData.latitude, this.#data.flightData.longitude)); + this.setLatLng(new LatLng(this.getFlightData().latitude, this.getFlightData().longitude)); var element = this.getElement(); - if (element != null) - { - element.querySelector(".unit-vvi-heading")?.setAttribute("style",`transform: rotate(${rad2deg(this.getFlightData().heading)}deg); width: ${15 + this.getFlightData().speed / 5}px`); + if (element != null) { + element.querySelector(".unit-vvi")?.setAttribute("style", `transform:rotate( calc( var( --unit-marker-air-vvi-rotation-offset ) + ${rad2deg(this.getFlightData().heading)}deg ) ); height:calc( ( var( --unit-marker-air-height ) / 2 ) + ${this.getFlightData().speed / 5}px );`); element.querySelector(".unit")?.setAttribute("data-fuel-level", "20"); element.querySelector(".unit")?.setAttribute("data-has-fox-1", "true"); - + var unitHeadingDiv = element.querySelector(".unit-heading"); if (unitHeadingDiv != null) unitHeadingDiv.innerHTML = String(Math.floor(rad2deg(this.getFlightData().heading))); - + var unitAltitudeDiv = element.querySelector(".unit-altitude"); if (unitAltitudeDiv != null) unitAltitudeDiv.innerHTML = String(Math.floor(this.getFlightData().altitude / 0.3048 / 1000)); } var pos = getMap().latLngToLayerPoint(this.getLatLng()).round(); - this.setZIndexOffset(Math.floor(this.getFlightData().altitude) - pos.y); + this.setZIndexOffset(Math.floor(this.getFlightData().altitude) - pos.y); } this.#forceUpdate = false; } #drawPath() { - if (this.#data.taskData.activePath != null) { + if (this.getTaskData().activePath != null) { var points = []; - points.push(new LatLng(this.#data.flightData.latitude, this.#data.flightData.longitude)); + points.push(new LatLng(this.getFlightData().latitude, this.getFlightData().longitude)); /* Add markers if missing */ - while (this.#pathMarkers.length < Object.keys(this.#data.taskData.activePath).length) { + while (this.#pathMarkers.length < Object.keys(this.getTaskData().activePath).length) { var marker = new Marker([0, 0], { icon: pathIcon }).addTo(getMap()); this.#pathMarkers.push(marker); } /* Remove markers if too many */ - while (this.#pathMarkers.length > Object.keys(this.#data.taskData.activePath).length) { + while (this.#pathMarkers.length > Object.keys(this.getTaskData().activePath).length) { getMap().removeLayer(this.#pathMarkers[this.#pathMarkers.length - 1]); this.#pathMarkers.splice(this.#pathMarkers.length - 1, 1) } /* Update the position of the existing markers (to avoid creating markers uselessly) */ - for (let WP in this.#data.taskData.activePath) { - var destination = this.#data.taskData.activePath[WP]; + for (let WP in this.getTaskData().activePath) { + var destination = this.getTaskData().activePath[WP]; this.#pathMarkers[parseInt(WP) - 1].setLatLng([destination.lat, destination.lng]); points.push(new LatLng(destination.lat, destination.lng)); this.#pathPolyline.setLatLngs(points); @@ -364,7 +347,7 @@ export class Unit extends Marker { var targetData = this.getMissionData().targets[typeIndex][index]; var target = getUnitsManager().getUnitByID(targetData.object["id_"]) if (target != null) { - var startLatLng = new LatLng(this.#data.flightData.latitude, this.#data.flightData.longitude) + var startLatLng = new LatLng(this.getFlightData().latitude, this.getFlightData().longitude) var endLatLng = new LatLng(target.getFlightData().latitude, target.getFlightData().longitude) var color; @@ -393,7 +376,7 @@ export class Unit extends Marker { export class AirUnit extends Unit { getHidden() { - return false; + return false; } } diff --git a/client/src/units/unitdatabase.ts b/client/src/units/unitdatabase.ts index 6f606cf9..1359d491 100644 --- a/client/src/units/unitdatabase.ts +++ b/client/src/units/unitdatabase.ts @@ -1,23 +1,3 @@ -export interface LoadoutItemBlueprint { - name: string; - quantity: number; -} - -export interface LoadoutBlueprint { - fuel: number; - items: LoadoutItemBlueprint[]; - roles: string[]; - code: string; - name: string; -} - -export interface UnitBlueprint { - name: string; - label: string; - shortLabel: string; - loadouts: LoadoutBlueprint[]; -} - export class UnitDatabase { units: {[key: string]: UnitBlueprint} = {}; diff --git a/client/src/units/unitmarker.ts b/client/src/units/unitmarker.ts deleted file mode 100644 index be78bf1b..00000000 --- a/client/src/units/unitmarker.ts +++ /dev/null @@ -1,148 +0,0 @@ -import * as L from 'leaflet' -import { getMap } from '..' -import { rad2deg } from '../other/utils' - -export interface MarkerOptions { - unitName: string, - name: string, - human: boolean, - coalition: string, - AI: boolean -} - -export interface MarkerData { - heading: number, - speed: number, - altitude: number, - alive: boolean -} - -export class UnitMarker extends L.Marker { - #options: MarkerOptions; - #data: MarkerData; - #selected: boolean = false - - constructor(options: MarkerOptions) { - super(new L.LatLng(0, 0), { riseOnHover: true }); - - this.#options = options; - this.#data = {heading: 0, speed: 0, altitude: 0, alive: true}; - - var icon = new L.DivIcon({ - html: `
-
-
-
-
-
-
${this.#options.name}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
${this.#options.unitName}
-
-
-
-
`, - className: 'ol-unit-marker', - iconAnchor: [30, 30] - }); - this.setIcon(icon); - } - - onAdd(map: L.Map): this { - super.onAdd(map); - this.addEventListener('mouseover', function (e: any) { e.target?.setHovered(true); }); - this.addEventListener('mouseout', function (e: any) { e.target?.setHovered(false); }); - return this - } - - draw(data: MarkerData) { - this.#data; - - var element = this.getElement(); - if (element != null) - { - element.querySelector(".unit-vvi-heading")?.setAttribute("style",`transform: rotate(${rad2deg(data.heading)}deg); width: ${15 + data.speed / 5}px`); - element.querySelector(".unit")?.setAttribute("data-fuel-level", "20"); - element.querySelector(".unit")?.setAttribute("data-has-fox-1", "true"); - - var unitHeadingDiv = element.querySelector(".unit-heading"); - if (unitHeadingDiv != null) - unitHeadingDiv.innerHTML = String(Math.floor(rad2deg(data.heading))); - - var unitAltitudeDiv = element.querySelector(".unit-altitude"); - if (unitAltitudeDiv != null) - unitAltitudeDiv.innerHTML = String(Math.floor(data.altitude / 0.3048 / 1000)); - } - var pos = getMap().latLngToLayerPoint(this.getLatLng()).round(); - this.setZIndexOffset(Math.floor(data.altitude) - pos.y); - } - - setSelected(selected: boolean) { - this.#selected = selected; - this.getElement()?.querySelector(".unit")?.setAttribute("data-is-selected", String(this.getSelected())); - } - - getSelected() { - return this.#selected; - } - - setHovered(hovered: boolean) { - this.getElement()?.querySelector("#icon")?.classList.toggle("ol-unit-marker-hovered", hovered && this.#data.alive); - } - - getData() { - return this.#data; - } - - getOptions() { - return this.#options; - } -} - -export class AirUnitMarker extends UnitMarker { - -} - -export class AircraftMarker extends AirUnitMarker { - -} - -export class HelicopterMarker extends AirUnitMarker { - -} - -export class GroundUnitMarker extends UnitMarker { - -} - -export class NavyUnitMarker extends UnitMarker { - -} - -export class WeaponMarker extends UnitMarker { - -} - -export class BombMarker extends WeaponMarker { - -} - -export class MissileMarker extends WeaponMarker { - -} \ No newline at end of file diff --git a/client/src/units/unitsmanager.ts b/client/src/units/unitsmanager.ts index 524d44d3..83ebe814 100644 --- a/client/src/units/unitsmanager.ts +++ b/client/src/units/unitsmanager.ts @@ -17,37 +17,10 @@ export class UnitsManager { document.addEventListener('keydown', (event) => this.#onKeyDown(event)); } - #updateUnitControlPanel() { - /* Update the unit control panel */ - if (this.getSelectedUnits().length > 0) { - getUnitControlPanel().show(); - getUnitControlPanel().update(this.getSelectedLeaders().concat(this.getSelectedSingletons())); - } - else { - getUnitControlPanel().hide(); - } - } - - #onKeyDown(event: KeyboardEvent) - { - if (event.key === "Delete") - { - this.selectedUnitsDelete(); - } - } - getUnits() { return this.#units; } - addUnit(ID: number, data: UnitData) { - /* The name of the unit category is exactly the same as the constructor name */ - var constructor = Unit.getConstructor(data.category); - if (constructor != undefined) { - this.#units[ID] = new constructor(ID, data); - } - } - getUnitByID(ID: number) { if (ID in this.#units) return this.#units[ID]; @@ -55,21 +28,17 @@ export class UnitsManager { return null; } - removeUnit(ID: number) { - - } - - deselectAllUnits() { - for (let ID in this.#units) { - this.#units[ID].setSelected(false); + addUnit(ID: number, data: UnitData) { + /* The name of the unit category is exactly the same as the constructor name */ + var constructor = Unit.getConstructor(data.category); + if (constructor != undefined) { + this.#units[ID] = new constructor(ID, data); } } + + + removeUnit(ID: number) { - selectUnit(ID: number, deselectAllUnits: boolean = true) - { - if (deselectAllUnits) - this.deselectAllUnits(); - this.#units[ID]?.setSelected(true); } update(data: ServerData) { @@ -78,16 +47,16 @@ export class UnitsManager { if (!(ID in this.#units)) { this.addUnit(parseInt(ID), data.units[ID]); } - this.#units[parseInt(ID)].update(data.units[ID]); + this.#units[parseInt(ID)].setData(data.units[ID]); } /* Update the unit info panel */ if (this.getSelectedUnits().length == 1) { - getUnitInfoPanel().show(); - getUnitInfoPanel().update(this.getSelectedUnits()[0]); + getUnitInfoPanel()?.show(); + getUnitInfoPanel()?.update(this.getSelectedUnits()[0]); } else { - getUnitInfoPanel().hide(); + getUnitInfoPanel()?.hide(); } } @@ -97,6 +66,13 @@ export class UnitsManager { } } + selectUnit(ID: number, deselectAllUnits: boolean = true) + { + if (deselectAllUnits) + this.deselectAllUnits(); + this.#units[ID]?.setSelected(true); + } + onUnitSelection() { if (this.getSelectedUnits().length > 0) { getMap().setState("MOVE_UNIT"); @@ -135,6 +111,12 @@ export class UnitsManager { return selectedUnits; } + deselectAllUnits() { + for (let ID in this.#units) { + this.#units[ID].setSelected(false); + } + } + getSelectedLeaders() { var leaders: Unit[] = []; for (let idx in this.getSelectedUnits()) @@ -163,14 +145,34 @@ export class UnitsManager { return singletons; } + getSelectedUnitsType () { + return this.getSelectedUnits().map((unit: Unit) => { + return unit.constructor.name + }).reduce((a: any, b: any) => { + return a == b? a: undefined + }); + }; + + getSelectedUnitsTargetSpeed () { + return this.getSelectedUnits().map((unit: Unit) => { + return unit.getTaskData().targetSpeed + }).reduce((a: any, b: any) => { + return a == b? a: undefined + }); + }; + + getSelectedUnitsTargetAltitude () { + return this.getSelectedUnits().map((unit: Unit) => { + return unit.getTaskData().targetAltitude + }).reduce((a: any, b: any) => { + return a == b? a: undefined + }); + }; + selectedUnitsAddDestination(latlng: L.LatLng) { var selectedUnits = this.getSelectedUnits(); for (let idx in selectedUnits) { var commandedUnit = selectedUnits[idx]; - //if (selectedUnits[idx].wingman) - //{ - // commandedUnit = this.getLeader(selectedUnits[idx].ID); - //} commandedUnit.addDestination(latlng); } } @@ -179,10 +181,6 @@ export class UnitsManager { var selectedUnits = this.getSelectedUnits(); for (let idx in selectedUnits) { var commandedUnit = selectedUnits[idx]; - //if (selectedUnits[idx].wingman) - //{ - // commandedUnit = this.getLeader(selectedUnits[idx].ID); - //} commandedUnit.clearDestinations(); } } @@ -327,6 +325,15 @@ export class UnitsManager { setTimeout(() => this.#updateUnitControlPanel(), 300); // TODO find better method, may fail } + selectedUnitsDelete() + { + var selectedUnits = this.getSelectedUnits(); + for (let idx in selectedUnits) + { + selectedUnits[idx].delete(); + } + } + copyUnits() { this.#copiedUnits = this.getSelectedUnits(); @@ -341,12 +348,22 @@ export class UnitsManager { } } - selectedUnitsDelete() + #updateUnitControlPanel() { + /* Update the unit control panel */ + if (this.getSelectedUnits().length > 0) { + getUnitControlPanel()?.show(); + getUnitControlPanel()?.update(this.getSelectedLeaders().concat(this.getSelectedSingletons())); + } + else { + getUnitControlPanel()?.hide(); + } + } + + #onKeyDown(event: KeyboardEvent) { - var selectedUnits = this.getSelectedUnits(); - for (let idx in selectedUnits) + if (event.key === "Delete") { - selectedUnits[idx].delete(); + this.selectedUnitsDelete(); } } } \ No newline at end of file diff --git a/client/views/aicformationpanel.ejs b/client/views/aic.ejs similarity index 52% rename from client/views/aicformationpanel.ejs rename to client/views/aic.ejs index 1f248c2c..229a5a82 100644 --- a/client/views/aicformationpanel.ejs +++ b/client/views/aic.ejs @@ -1,3 +1,22 @@ +
+
+
+
+ +
+
×
+
AIC Help
+
+

How to be a good AIC and get people to do stuff good, too.

+
+
[DCS with Volvo video]
+
+
+
+ +
+
@@ -9,7 +28,7 @@
- +

Control

@@ -21,13 +40,13 @@
- +
- +

Formations

- +
- +
-
+
\ No newline at end of file diff --git a/client/views/aiccontrolpanel.ejs b/client/views/aiccontrolpanel.ejs deleted file mode 100644 index a1486db4..00000000 --- a/client/views/aiccontrolpanel.ejs +++ /dev/null @@ -1,17 +0,0 @@ -
-
-
-
- -
-
×
-
AIC Help
-
-

How to be a good AIC and get people to do stuff good, too.

-
-
[DCS with Volvo video]
-
-
-
- -
\ No newline at end of file diff --git a/client/views/atc.ejs b/client/views/atc.ejs index 87f727e3..ee082b92 100644 --- a/client/views/atc.ejs +++ b/client/views/atc.ejs @@ -102,4 +102,5 @@
- \ No newline at end of file + + diff --git a/client/views/connectionstatuspanel.ejs b/client/views/connectionstatuspanel.ejs deleted file mode 100644 index ad74ea88..00000000 --- a/client/views/connectionstatuspanel.ejs +++ /dev/null @@ -1,3 +0,0 @@ -
-
Connected
-
\ No newline at end of file diff --git a/client/views/contextmenu.ejs b/client/views/contextmenu.ejs index 581a4f97..cb9864db 100644 --- a/client/views/contextmenu.ejs +++ b/client/views/contextmenu.ejs @@ -1,11 +1,10 @@ -
-
-
- -
-
+
+
+
Title
+
+ +
+
    +
\ No newline at end of file diff --git a/client/views/index.ejs b/client/views/index.ejs index f5acfa44..966be9d7 100644 --- a/client/views/index.ejs +++ b/client/views/index.ejs @@ -2,7 +2,7 @@ Olympus client - + @@ -14,7 +14,6 @@ window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); - gtag('config', 'G-Z4L2TC3YX0'); @@ -22,21 +21,17 @@
+ <%- include('aic.ejs') %> + <%- include('atc.ejs') %> + <%- include('contextmenu.ejs') %> -
- - <%- include('unitinfopanel.ejs') %> - <%- include('unitcontrolpanel.ejs') %> - <%- include('visibilitycontrolpanel.ejs') %> - <%- include('connectionstatuspanel.ejs') %> - <%- include('mouseinfopanel.ejs') %> - - <%- include('aiccontrolpanel.ejs') %> - <%- include('aicformationpanel.ejs') %> - - <%- include( 'atc.ejs' ) %> - - <%- include('logpanel.ejs') %> + <%- include('unitcontrol.ejs') %> + <%- include('settings.ejs') %> + <%- include('mouseinfo.ejs') %> + + <% /* %> + <%- include('log.ejs') %> + <% */ %> diff --git a/client/views/log.ejs b/client/views/log.ejs new file mode 100644 index 00000000..d92ecd2d --- /dev/null +++ b/client/views/log.ejs @@ -0,0 +1,3 @@ +
+ +
\ No newline at end of file diff --git a/client/views/logpanel.ejs b/client/views/logpanel.ejs deleted file mode 100644 index baccbec1..00000000 --- a/client/views/logpanel.ejs +++ /dev/null @@ -1,3 +0,0 @@ -
- -
\ No newline at end of file diff --git a/client/views/mouseinfo.ejs b/client/views/mouseinfo.ejs new file mode 100644 index 00000000..3b029240 --- /dev/null +++ b/client/views/mouseinfo.ejs @@ -0,0 +1,6 @@ +
+
---° / --- NM
+
---° / --- NM
+
---° / --- NM
+
---° / --- NM
+
\ No newline at end of file diff --git a/client/views/mouseinfopanel.ejs b/client/views/mouseinfopanel.ejs deleted file mode 100644 index 3a798661..00000000 --- a/client/views/mouseinfopanel.ejs +++ /dev/null @@ -1,6 +0,0 @@ -
-
---° / --- NM
-
---° / --- NM
-
---° / --- NM
-
---° / --- NM
-
\ No newline at end of file diff --git a/client/views/settings.ejs b/client/views/settings.ejs new file mode 100644 index 00000000..8c64112d --- /dev/null +++ b/client/views/settings.ejs @@ -0,0 +1,38 @@ +
+ + + + + + + + + + + +
View BLUEFOR
+
View REDFOR
+
View NEUTRAL
+
+ +
+

Connected

+
\ No newline at end of file diff --git a/client/views/unitcontrol.ejs b/client/views/unitcontrol.ejs new file mode 100644 index 00000000..5aa18176 --- /dev/null +++ b/client/views/unitcontrol.ejs @@ -0,0 +1,64 @@ +
+

Selected units

+
+ +
+ +

Controls

+
+
+
Altitude
+
+ +
+
+
Speed
+
+ +
+
+ +

Formation

+
+ +
+ +

Rules of engagement

+
+ +
+ +

Reaction to threat

+
+ +
+
+ +
+
+
+

Olympus 1-1

+
Name
+
Group
+
Task
+
+
+

Flight data

+
+
+
+
Ground Speed

12

+
Altitude

+
Heading

+
+
+
+

Loadout

+
+
Fuel

+
+
+
+
+
+
\ No newline at end of file diff --git a/client/views/unitcontrolpanel.ejs b/client/views/unitcontrolpanel.ejs deleted file mode 100644 index c9f5dd6e..00000000 --- a/client/views/unitcontrolpanel.ejs +++ /dev/null @@ -1,65 +0,0 @@ -
- - - - -
Controls
-
-
-
Altitude
-
- -
-
-
Speed
-
- -
-
- - - -
- -
Rules of engagement
-
-
Free
-
Designated free
-
Designated
-
Return
-
Hold
-
- -
- -
Reaction to threat
-
-
None
-
Passive
-
Evade
-
Escape
-
Abort
-
- -
\ No newline at end of file diff --git a/client/views/unitinfopanel.ejs b/client/views/unitinfopanel.ejs deleted file mode 100644 index 578ef8b6..00000000 --- a/client/views/unitinfopanel.ejs +++ /dev/null @@ -1,33 +0,0 @@ -
-
-
-
-
-
-
-
-
-
Flight data
-
-
- -
Ground Speed
-
- -
Altitude
-
- -
Heading
-
-
-
-
-
Loadout
- -
Fuel
-
-
- -
-
-
\ No newline at end of file diff --git a/client/views/visibilitycontrolpanel.ejs b/client/views/visibilitycontrolpanel.ejs deleted file mode 100644 index fb9f747b..00000000 --- a/client/views/visibilitycontrolpanel.ejs +++ /dev/null @@ -1,44 +0,0 @@ -
-
Air:
-
- -
- -
Ground:
-
- -
- -
Navy:
-
- -
- -
Weapons:
-
- -
- -
- -
Full:
-
- -
- -
Partial:
-
- -
- -
Minimal:
-
- -
- -
-
Olympus only:
-
- -
-
\ No newline at end of file diff --git a/img/icon-38x38.png b/img/icon-38x38.png deleted file mode 100644 index 9ddcb4b9..00000000 Binary files a/img/icon-38x38.png and /dev/null differ diff --git a/img/icon.png b/img/icon.png index d4b60c09..dc5c994e 100644 Binary files a/img/icon.png and b/img/icon.png differ diff --git a/img/icon.xcf b/img/icon.xcf deleted file mode 100644 index c33dd3ed..00000000 Binary files a/img/icon.xcf and /dev/null differ diff --git a/img/icon_284.png b/img/icon_284.png new file mode 100644 index 00000000..b11172d3 Binary files /dev/null and b/img/icon_284.png differ diff --git a/img/icon_active.png b/img/icon_active.png new file mode 100644 index 00000000..56f59ba4 Binary files /dev/null and b/img/icon_active.png differ diff --git a/img/icon_select.png b/img/icon_select.png new file mode 100644 index 00000000..5771d3b5 Binary files /dev/null and b/img/icon_select.png differ diff --git a/img/incon_active.png b/img/incon_active.png deleted file mode 100644 index 3b69985d..00000000 Binary files a/img/incon_active.png and /dev/null differ diff --git a/mod/Theme/icon.png b/mod/Theme/icon.png index d4b60c09..dc5c994e 100644 Binary files a/mod/Theme/icon.png and b/mod/Theme/icon.png differ diff --git a/mod/Theme/icon_284.png b/mod/Theme/icon_284.png new file mode 100644 index 00000000..b11172d3 Binary files /dev/null and b/mod/Theme/icon_284.png differ diff --git a/mod/Theme/icon_active.png b/mod/Theme/icon_active.png index 3b69985d..56f59ba4 100644 Binary files a/mod/Theme/icon_active.png and b/mod/Theme/icon_active.png differ diff --git a/mod/Theme/icon_select.png b/mod/Theme/icon_select.png index 3b69985d..5771d3b5 100644 Binary files a/mod/Theme/icon_select.png and b/mod/Theme/icon_select.png differ diff --git a/src/core/include/Unit.h b/src/core/include/Unit.h index 4b0a30b2..8a0d229a 100644 --- a/src/core/include/Unit.h +++ b/src/core/include/Unit.h @@ -16,7 +16,7 @@ public: void updateExportData(json::value json); void updateMissionData(json::value json); - json::value json(); + json::value json(bool fullRefresh); virtual void setState(int newState) { state = newState; }; void resetTask(); diff --git a/src/core/include/server.h b/src/core/include/server.h index d55e5174..f77cba5b 100644 --- a/src/core/include/server.h +++ b/src/core/include/server.h @@ -18,7 +18,6 @@ public: private: std::thread* serverThread; - json::value answer; void handle_options(http_request request); void handle_get(http_request request); diff --git a/src/core/include/unitsmanager.h b/src/core/include/unitsmanager.h index 1864c8ad..b73c791f 100644 --- a/src/core/include/unitsmanager.h +++ b/src/core/include/unitsmanager.h @@ -13,7 +13,7 @@ public: Unit* getUnit(int ID); void updateExportData(lua_State* L); void updateMissionData(json::value missionData); - void updateAnswer(json::value& answer); + void updateAnswer(json::value& answer, bool fullRefresh); void deleteUnit(int ID); private: diff --git a/src/core/src/Unit.cpp b/src/core/src/Unit.cpp index ea25899b..f2849807 100644 --- a/src/core/src/Unit.cpp +++ b/src/core/src/Unit.cpp @@ -34,7 +34,6 @@ void Unit::updateExportData(json::value json) } oldPosition = Coords(latitude, longitude, altitude); - /* Update all the internal fields from the input json file */ if (json.has_string_field(L"Name")) name = json[L"Name"].as_string(); if (json.has_string_field(L"UnitName")) @@ -80,17 +79,71 @@ void Unit::updateMissionData(json::value json) hasTask = json[L"hasTask"].as_bool(); } -json::value Unit::json() +json::value Unit::json(bool fullRefresh) { auto json = json::value::object(); - /********** Base data **********/ - json[L"AI"] = AI; - json[L"name"] = json::value::string(name); - json[L"unitName"] = json::value::string(unitName); - json[L"groupName"] = json::value::string(groupName); - json[L"alive"] = alive; - json[L"category"] = json::value::string(getCategory()); + if (fullRefresh) + { + /********** Base data **********/ + json[L"AI"] = AI; + json[L"name"] = json::value::string(name); + json[L"unitName"] = json::value::string(unitName); + json[L"groupName"] = json::value::string(groupName); + json[L"alive"] = alive; + json[L"category"] = json::value::string(getCategory()); + + /********** Mission data **********/ + json[L"missionData"] = json::value::object(); + json[L"missionData"][L"fuel"] = fuel; + json[L"missionData"][L"ammo"] = ammo; + json[L"missionData"][L"targets"] = targets; + json[L"missionData"][L"hasTask"] = hasTask; + if (coalitionID == 0) + json[L"missionData"][L"coalition"] = json::value::string(L"neutral"); + else if (coalitionID == 1) + json[L"missionData"][L"coalition"] = json::value::string(L"red"); + else + json[L"missionData"][L"coalition"] = json::value::string(L"blue"); + json[L"missionData"][L"flags"] = flags; + + /********** Formation data **********/ + json[L"formationData"] = json::value::object(); + json[L"formationData"][L"isLeader"] = isLeader; + json[L"formationData"][L"isWingman"] = isWingman; + json[L"formationData"][L"formation"] = json::value::string(formation); + int i = 0; + for (auto itr = wingmen.begin(); itr != wingmen.end(); itr++) + json[L"formationData"][L"wingmenIDs"][i++] = (*itr)->getID(); + + if (leader != nullptr) + json[L"formationData"][L"leaderID"] = leader->getID(); + + /********** Task data **********/ + json[L"taskData"] = json::value::object(); + json[L"taskData"][L"currentTask"] = json::value::string(getCurrentTask()); + json[L"taskData"][L"targetSpeed"] = getTargetSpeed(); + json[L"taskData"][L"targetAltitude"] = getTargetAltitude(); + /* Send the active path as a json object */ + auto path = json::value::object(); + if (activePath.size() > 0) { + int count = 1; + for (auto& destination : activePath) + { + auto json = json::value::object(); + json[L"lat"] = destination.lat; + json[L"lng"] = destination.lng; + json[L"alt"] = destination.alt; + path[to_wstring(count++)] = json; + } + } + json[L"taskData"][L"activePath"] = path; + + /********** Options data **********/ + json[L"optionsData"] = json::value::object(); + json[L"optionsData"][L"ROE"] = json::value::string(ROE); + json[L"optionsData"][L"reactionToThreat"] = json::value::string(reactionToThreat); + } /********** Flight data **********/ json[L"flightData"] = json::value::object(); @@ -100,57 +153,6 @@ json::value Unit::json() json[L"flightData"][L"speed"] = speed; json[L"flightData"][L"heading"] = heading; - /********** Mission data **********/ - json[L"missionData"] = json::value::object(); - json[L"missionData"][L"fuel"] = fuel; - json[L"missionData"][L"ammo"] = ammo; - json[L"missionData"][L"targets"] = targets; - json[L"missionData"][L"hasTask"] = hasTask; - if (coalitionID == 0) - json[L"missionData"][L"coalition"] = json::value::string(L"neutral"); - else if (coalitionID == 1) - json[L"missionData"][L"coalition"] = json::value::string(L"red"); - else - json[L"missionData"][L"coalition"] = json::value::string(L"blue"); - json[L"missionData"][L"flags"] = flags; - - /********** Formation data **********/ - json[L"formationData"] = json::value::object(); - json[L"formationData"][L"isLeader"] = isLeader; - json[L"formationData"][L"isWingman"] = isWingman; - json[L"formationData"][L"formation"] = json::value::string(formation); - int i = 0; - for (auto itr = wingmen.begin(); itr != wingmen.end(); itr++) - json[L"formationData"][L"wingmenIDs"][i++] = (*itr)->getID(); - - if (leader != nullptr) - json[L"formationData"][L"leaderID"] = leader->getID(); - - /********** Task data **********/ - json[L"taskData"] = json::value::object(); - json[L"taskData"][L"currentTask"] = json::value::string(getCurrentTask()); - json[L"taskData"][L"targetSpeed"] = getTargetSpeed(); - json[L"taskData"][L"targetAltitude"] = getTargetAltitude(); - /* Send the active path as a json object */ - auto path = json::value::object(); - if (activePath.size() > 0) { - int count = 1; - for (auto& destination : activePath) - { - auto json = json::value::object(); - json[L"lat"] = destination.lat; - json[L"lng"] = destination.lng; - json[L"alt"] = destination.alt; - path[to_wstring(count++)] = json; - } - } - json[L"taskData"][L"activePath"] = path; - - /********** Options data **********/ - json[L"optionsData"] = json::value::object(); - json[L"optionsData"][L"ROE"] = json::value::string(ROE); - json[L"optionsData"][L"reactionToThreat"] = json::value::string(reactionToThreat); - return json; } diff --git a/src/core/src/server.cpp b/src/core/src/server.cpp index 32fbd5b4..f4d77970 100644 --- a/src/core/src/server.cpp +++ b/src/core/src/server.cpp @@ -32,7 +32,6 @@ Server::Server(lua_State* L): } - void Server::start(lua_State* L) { log("Starting RESTServer"); @@ -71,15 +70,28 @@ void Server::handle_get(http_request request) std::exception_ptr eptr; try { - unitsManager->updateAnswer(answer); + auto answer = json::value::object(); + wstring requestUri = request.request_uri().to_string(); + log(requestUri); + if (requestUri.compare(L"/" + wstring(REST_URI) + L"/" + wstring(UNITS_URI) + L"/" + wstring(PARTIAL_REFRESH_URI)) == 0) + unitsManager->updateAnswer(answer, false); + + if (requestUri.compare(L"/" + wstring(REST_URI) + L"/" + wstring(UNITS_URI) + L"/" + wstring(FULL_REFRESH_URI)) == 0) + unitsManager->updateAnswer(answer, true); /* Get the logs from the logger */ - auto logs = json::value::object(); - getLogsJSON(logs); // By reference, for thread safety + if (requestUri.compare(L"/" + wstring(REST_URI) + L"/" + wstring(LOGS_URI)) == 0) + { + auto logs = json::value::object(); + getLogsJSON(logs); // By reference, for thread safety + answer[L"logs"] = logs; + } - answer[L"airbases"] = airbasesData; - answer[L"bullseye"] = bullseyeData; - answer[L"logs"] = logs; + if (requestUri.compare(L"/" + wstring(REST_URI) + L"/" + wstring(AIRBASES_URI)) == 0) + answer[L"airbases"] = airbasesData; + + if (requestUri.compare(L"/" + wstring(REST_URI) + L"/" + wstring(BULLSEYE_URI)) == 0) + answer[L"bullseye"] = bullseyeData; response.set_body(answer); } @@ -94,7 +106,6 @@ void Server::handle_get(http_request request) void Server::handle_request(http_request request, function action) { auto answer = json::value::object(); - request.extract_json().then([&answer, &action](pplx::task task) { try @@ -148,7 +159,7 @@ void Server::handle_put(http_request request) void Server::task() { - http_listener listener(REST_ADDRESS); + http_listener listener(wstring(REST_ADDRESS) + L"/" + wstring(REST_URI)); std::function handle_options = std::bind(&Server::handle_options, this, std::placeholders::_1); std::function handle_get = std::bind(&Server::handle_get, this, std::placeholders::_1); diff --git a/src/core/src/unitsmanager.cpp b/src/core/src/unitsmanager.cpp index d3aca042..101eb523 100644 --- a/src/core/src/unitsmanager.cpp +++ b/src/core/src/unitsmanager.cpp @@ -48,32 +48,20 @@ void UnitsManager::updateExportData(lua_State* L) if (type[L"level1"].as_number().to_int32() == 1) { if (type[L"level2"].as_number().to_int32() == 1) - { units[ID] = dynamic_cast(new Aircraft(p.second, ID)); - } else if (type[L"level2"].as_number().to_int32() == 2) - { units[ID] = dynamic_cast(new Helicopter(p.second, ID)); - } } else if (type[L"level1"].as_number().to_int32() == 2) - { units[ID] = dynamic_cast(new GroundUnit(p.second, ID)); - } else if (type[L"level1"].as_number().to_int32() == 3) - { units[ID] = dynamic_cast(new NavyUnit(p.second, ID)); - } else if (type[L"level1"].as_number().to_int32() == 4) { if (type[L"level2"].as_number().to_int32() == 4) - { units[ID] = dynamic_cast(new Missile(p.second, ID)); - } else if (type[L"level2"].as_number().to_int32() == 5) - { units[ID] = dynamic_cast(new Bomb(p.second, ID)); - } } } } @@ -87,10 +75,7 @@ void UnitsManager::updateExportData(lua_State* L) /* Set the units that are not present in the JSON as dead (probably have been destroyed) */ for (auto const& unit : units) { - if (unitJSONs.find(unit.first) == unitJSONs.end()) - { - unit.second->setAlive(false); - } + unit.second->setAlive(unitJSONs.find(unit.first) != unitJSONs.end()); } } @@ -107,16 +92,13 @@ void UnitsManager::updateMissionData(json::value missionData) } } -void UnitsManager::updateAnswer(json::value& answer) +void UnitsManager::updateAnswer(json::value& answer, bool fullRefresh) { - // TODO THREAT SAFEY! auto unitsJson = json::value::object(); - for (auto const& p : units) { - unitsJson[to_wstring(p.first)] = p.second->json(); + unitsJson[to_wstring(p.first)] = p.second->json(fullRefresh); } - answer[L"units"] = unitsJson; } diff --git a/src/shared/include/defines.h b/src/shared/include/defines.h index ae844c49..6a214075 100644 --- a/src/shared/include/defines.h +++ b/src/shared/include/defines.h @@ -2,6 +2,13 @@ #define VERSION "v0.0.1" #define LOG_NAME "Olympus_log.txt" -#define REST_ADDRESS L"http://localhost:30000/restdemo" +#define REST_ADDRESS L"http://localhost:30000" +#define REST_URI L"olympus" +#define UNITS_URI L"units" +#define PARTIAL_REFRESH_URI L"partial" +#define FULL_REFRESH_URI L"full" +#define LOGS_URI L"logs" +#define AIRBASES_URI L"airbases" +#define BULLSEYE_URI L"bullseye" #define UPDATE_TIME_INTERVAL 0.25 \ No newline at end of file