diff --git a/client/TODO.txt b/client/TODO.txt index 5b8b49aa..d4f06408 100644 --- a/client/TODO.txt +++ b/client/TODO.txt @@ -4,4 +4,4 @@ scenario dropdown explosion wrong name for ground units improve map zIndex -human symbol if user \ No newline at end of file +human symbol if user diff --git a/client/public/images/units/a-10.png b/client/public/images/units/a-10.png new file mode 100644 index 00000000..643dd5aa Binary files /dev/null and b/client/public/images/units/a-10.png differ diff --git a/client/public/images/units/a-20.png b/client/public/images/units/a-20.png new file mode 100644 index 00000000..4981c90b Binary files /dev/null and b/client/public/images/units/a-20.png differ diff --git a/client/public/images/units/a-29.png b/client/public/images/units/a-29.png new file mode 100644 index 00000000..91ad25f0 Binary files /dev/null and b/client/public/images/units/a-29.png differ diff --git a/client/public/images/units/a-4.png b/client/public/images/units/a-4.png new file mode 100644 index 00000000..499cc11e Binary files /dev/null and b/client/public/images/units/a-4.png differ diff --git a/client/public/images/units/a-400.png b/client/public/images/units/a-400.png new file mode 100644 index 00000000..e76ab232 Binary files /dev/null and b/client/public/images/units/a-400.png differ diff --git a/client/public/images/units/a-50.png b/client/public/images/units/a-50.png new file mode 100644 index 00000000..f08e39a0 Binary files /dev/null and b/client/public/images/units/a-50.png differ diff --git a/client/public/images/units/a-6.png b/client/public/images/units/a-6.png new file mode 100644 index 00000000..d5007ccd Binary files /dev/null and b/client/public/images/units/a-6.png differ diff --git a/client/public/images/units/ah-1.png b/client/public/images/units/ah-1.png new file mode 100644 index 00000000..5da53ddd Binary files /dev/null and b/client/public/images/units/ah-1.png differ diff --git a/client/public/images/units/ah-64.png b/client/public/images/units/ah-64.png new file mode 100644 index 00000000..fa1c98b5 Binary files /dev/null and b/client/public/images/units/ah-64.png differ diff --git a/client/public/images/units/aircraft.png b/client/public/images/units/airUnit.png similarity index 100% rename from client/public/images/units/aircraft.png rename to client/public/images/units/airUnit.png diff --git a/client/public/images/units/airliner2engine.png b/client/public/images/units/airliner2engine.png new file mode 100644 index 00000000..3c8bd4de Binary files /dev/null and b/client/public/images/units/airliner2engine.png differ diff --git a/client/public/images/units/an-26.png b/client/public/images/units/an-26.png new file mode 100644 index 00000000..8b4bd491 Binary files /dev/null and b/client/public/images/units/an-26.png differ diff --git a/client/public/images/units/av8bna.png b/client/public/images/units/av8bna.png new file mode 100644 index 00000000..0bb13672 Binary files /dev/null and b/client/public/images/units/av8bna.png differ diff --git a/client/public/images/units/b-1.png b/client/public/images/units/b-1.png new file mode 100644 index 00000000..05329ddf Binary files /dev/null and b/client/public/images/units/b-1.png differ diff --git a/client/public/images/units/b-17.png b/client/public/images/units/b-17.png new file mode 100644 index 00000000..400dfbc5 Binary files /dev/null and b/client/public/images/units/b-17.png differ diff --git a/client/public/images/units/b-2.png b/client/public/images/units/b-2.png new file mode 100644 index 00000000..3b85f3af Binary files /dev/null and b/client/public/images/units/b-2.png differ diff --git a/client/public/images/units/b-52.png b/client/public/images/units/b-52.png new file mode 100644 index 00000000..34d8840b Binary files /dev/null and b/client/public/images/units/b-52.png differ diff --git a/client/public/images/units/b707.png b/client/public/images/units/b707.png new file mode 100644 index 00000000..3771fc63 Binary files /dev/null and b/client/public/images/units/b707.png differ diff --git a/client/public/images/units/bf109.png b/client/public/images/units/bf109.png new file mode 100644 index 00000000..40da1dfd Binary files /dev/null and b/client/public/images/units/bf109.png differ diff --git a/client/public/images/units/c-101.png b/client/public/images/units/c-101.png new file mode 100644 index 00000000..8b5468b8 Binary files /dev/null and b/client/public/images/units/c-101.png differ diff --git a/client/public/images/units/c-130.png b/client/public/images/units/c-130.png new file mode 100644 index 00000000..f69cb0c2 Binary files /dev/null and b/client/public/images/units/c-130.png differ diff --git a/client/public/images/units/c-17.png b/client/public/images/units/c-17.png new file mode 100644 index 00000000..c2b8855c Binary files /dev/null and b/client/public/images/units/c-17.png differ diff --git a/client/public/images/units/c-5.png b/client/public/images/units/c-5.png new file mode 100644 index 00000000..e2823289 Binary files /dev/null and b/client/public/images/units/c-5.png differ diff --git a/client/public/images/units/ch-47.png b/client/public/images/units/ch-47.png new file mode 100644 index 00000000..16f178ca Binary files /dev/null and b/client/public/images/units/ch-47.png differ diff --git a/client/public/images/units/ch-53.png b/client/public/images/units/ch-53.png new file mode 100644 index 00000000..e67f108c Binary files /dev/null and b/client/public/images/units/ch-53.png differ diff --git a/client/public/images/units/christeneagleii.png b/client/public/images/units/christeneagleii.png new file mode 100644 index 00000000..b1874dd2 Binary files /dev/null and b/client/public/images/units/christeneagleii.png differ diff --git a/client/public/images/units/e-2.png b/client/public/images/units/e-2.png new file mode 100644 index 00000000..fc178272 Binary files /dev/null and b/client/public/images/units/e-2.png differ diff --git a/client/public/images/units/e-3.png b/client/public/images/units/e-3.png new file mode 100644 index 00000000..bcce5b6c Binary files /dev/null and b/client/public/images/units/e-3.png differ diff --git a/client/public/images/units/eurofighter.png b/client/public/images/units/eurofighter.png new file mode 100644 index 00000000..cf39e7f8 Binary files /dev/null and b/client/public/images/units/eurofighter.png differ diff --git a/client/public/images/units/f-111.png b/client/public/images/units/f-111.png new file mode 100644 index 00000000..ae06b171 Binary files /dev/null and b/client/public/images/units/f-111.png differ diff --git a/client/public/images/units/f-117.png b/client/public/images/units/f-117.png new file mode 100644 index 00000000..2f099b28 Binary files /dev/null and b/client/public/images/units/f-117.png differ diff --git a/client/public/images/units/f-14.png b/client/public/images/units/f-14.png new file mode 100644 index 00000000..662def75 Binary files /dev/null and b/client/public/images/units/f-14.png differ diff --git a/client/public/images/units/f-15.png b/client/public/images/units/f-15.png new file mode 100644 index 00000000..a3b56c6c Binary files /dev/null and b/client/public/images/units/f-15.png differ diff --git a/client/public/images/units/f-16.png b/client/public/images/units/f-16.png new file mode 100644 index 00000000..3adbba10 Binary files /dev/null and b/client/public/images/units/f-16.png differ diff --git a/client/public/images/units/f-18.png b/client/public/images/units/f-18.png new file mode 100644 index 00000000..b1f28359 Binary files /dev/null and b/client/public/images/units/f-18.png differ diff --git a/client/public/images/units/f-22.png b/client/public/images/units/f-22.png new file mode 100644 index 00000000..af909ad4 Binary files /dev/null and b/client/public/images/units/f-22.png differ diff --git a/client/public/images/units/f-35.png b/client/public/images/units/f-35.png new file mode 100644 index 00000000..6c9d0909 Binary files /dev/null and b/client/public/images/units/f-35.png differ diff --git a/client/public/images/units/f-4.png b/client/public/images/units/f-4.png new file mode 100644 index 00000000..21cfc750 Binary files /dev/null and b/client/public/images/units/f-4.png differ diff --git a/client/public/images/units/f-5.png b/client/public/images/units/f-5.png new file mode 100644 index 00000000..ef276090 Binary files /dev/null and b/client/public/images/units/f-5.png differ diff --git a/client/public/images/units/f-86.png b/client/public/images/units/f-86.png new file mode 100644 index 00000000..198a968a Binary files /dev/null and b/client/public/images/units/f-86.png differ diff --git a/client/public/images/units/fw190.png b/client/public/images/units/fw190.png new file mode 100644 index 00000000..0020b176 Binary files /dev/null and b/client/public/images/units/fw190.png differ diff --git a/client/public/images/units/general1.png b/client/public/images/units/general1.png new file mode 100644 index 00000000..bf8bf272 Binary files /dev/null and b/client/public/images/units/general1.png differ diff --git a/client/public/images/units/gripen.png b/client/public/images/units/gripen.png new file mode 100644 index 00000000..bd58818e Binary files /dev/null and b/client/public/images/units/gripen.png differ diff --git a/client/public/images/units/ground.png b/client/public/images/units/groundUnit.png similarity index 100% rename from client/public/images/units/ground.png rename to client/public/images/units/groundUnit.png diff --git a/client/public/images/units/h-6.png b/client/public/images/units/h-6.png new file mode 100644 index 00000000..d73b5e3a Binary files /dev/null and b/client/public/images/units/h-6.png differ diff --git a/client/public/images/units/hawk.png b/client/public/images/units/hawk.png new file mode 100644 index 00000000..c1fdd943 Binary files /dev/null and b/client/public/images/units/hawk.png differ diff --git a/client/public/images/units/helicopter1.png b/client/public/images/units/helicopter1.png new file mode 100644 index 00000000..316d3ad9 Binary files /dev/null and b/client/public/images/units/helicopter1.png differ diff --git a/client/public/images/units/i-16.png b/client/public/images/units/i-16.png new file mode 100644 index 00000000..53335809 Binary files /dev/null and b/client/public/images/units/i-16.png differ diff --git a/client/public/images/units/il-76.png b/client/public/images/units/il-76.png new file mode 100644 index 00000000..bcb145a2 Binary files /dev/null and b/client/public/images/units/il-76.png differ diff --git a/client/public/images/units/j-10.png b/client/public/images/units/j-10.png new file mode 100644 index 00000000..1521dbb7 Binary files /dev/null and b/client/public/images/units/j-10.png differ diff --git a/client/public/images/units/j-20.png b/client/public/images/units/j-20.png new file mode 100644 index 00000000..df0b9498 Binary files /dev/null and b/client/public/images/units/j-20.png differ diff --git a/client/public/images/units/j-7.png b/client/public/images/units/j-7.png new file mode 100644 index 00000000..bbf8040a Binary files /dev/null and b/client/public/images/units/j-7.png differ diff --git a/client/public/images/units/jf-17.png b/client/public/images/units/jf-17.png new file mode 100644 index 00000000..3e2e6fab Binary files /dev/null and b/client/public/images/units/jf-17.png differ diff --git a/client/public/images/units/ju-88.png b/client/public/images/units/ju-88.png new file mode 100644 index 00000000..287ca2ce Binary files /dev/null and b/client/public/images/units/ju-88.png differ diff --git a/client/public/images/units/ka-27.png b/client/public/images/units/ka-27.png new file mode 100644 index 00000000..d0ad1c12 Binary files /dev/null and b/client/public/images/units/ka-27.png differ diff --git a/client/public/images/units/ka-50.png b/client/public/images/units/ka-50.png new file mode 100644 index 00000000..a75983e9 Binary files /dev/null and b/client/public/images/units/ka-50.png differ diff --git a/client/public/images/units/kc-10.png b/client/public/images/units/kc-10.png new file mode 100644 index 00000000..7d9e4db9 Binary files /dev/null and b/client/public/images/units/kc-10.png differ diff --git a/client/public/images/units/kc-135.png b/client/public/images/units/kc-135.png new file mode 100644 index 00000000..bbf5ff5b Binary files /dev/null and b/client/public/images/units/kc-135.png differ diff --git a/client/public/images/units/l-159.png b/client/public/images/units/l-159.png new file mode 100644 index 00000000..ba6461f9 Binary files /dev/null and b/client/public/images/units/l-159.png differ diff --git a/client/public/images/units/l-39.png b/client/public/images/units/l-39.png new file mode 100644 index 00000000..c2ef1d07 Binary files /dev/null and b/client/public/images/units/l-39.png differ diff --git a/client/public/images/units/listNames.py b/client/public/images/units/listNames.py new file mode 100644 index 00000000..8f23620a --- /dev/null +++ b/client/public/images/units/listNames.py @@ -0,0 +1,5 @@ +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 new file mode 100644 index 00000000..8a9ffd48 Binary files /dev/null and b/client/public/images/units/m2000.png differ diff --git a/client/public/images/units/mi-24.png b/client/public/images/units/mi-24.png new file mode 100644 index 00000000..9a148550 Binary files /dev/null and b/client/public/images/units/mi-24.png differ diff --git a/client/public/images/units/mi-26.png b/client/public/images/units/mi-26.png new file mode 100644 index 00000000..b59c9b8d Binary files /dev/null and b/client/public/images/units/mi-26.png differ diff --git a/client/public/images/units/mi-28.png b/client/public/images/units/mi-28.png new file mode 100644 index 00000000..9e5db2ca Binary files /dev/null and b/client/public/images/units/mi-28.png differ diff --git a/client/public/images/units/mi-8.png b/client/public/images/units/mi-8.png new file mode 100644 index 00000000..f42706e7 Binary files /dev/null and b/client/public/images/units/mi-8.png differ diff --git a/client/public/images/units/mig-15.png b/client/public/images/units/mig-15.png new file mode 100644 index 00000000..b97ef8c9 Binary files /dev/null and b/client/public/images/units/mig-15.png differ diff --git a/client/public/images/units/mig-19.png b/client/public/images/units/mig-19.png new file mode 100644 index 00000000..046e6a0f Binary files /dev/null and b/client/public/images/units/mig-19.png differ diff --git a/client/public/images/units/mig-21.png b/client/public/images/units/mig-21.png new file mode 100644 index 00000000..12056218 Binary files /dev/null and b/client/public/images/units/mig-21.png differ diff --git a/client/public/images/units/mig-23.png b/client/public/images/units/mig-23.png new file mode 100644 index 00000000..6fabd9c3 Binary files /dev/null and b/client/public/images/units/mig-23.png differ diff --git a/client/public/images/units/mig-25.png b/client/public/images/units/mig-25.png new file mode 100644 index 00000000..cf8c46ca Binary files /dev/null and b/client/public/images/units/mig-25.png differ diff --git a/client/public/images/units/mig-29.png b/client/public/images/units/mig-29.png new file mode 100644 index 00000000..634cbcc7 Binary files /dev/null and b/client/public/images/units/mig-29.png differ diff --git a/client/public/images/units/mosquito.png b/client/public/images/units/mosquito.png new file mode 100644 index 00000000..5d1ed6d0 Binary files /dev/null and b/client/public/images/units/mosquito.png differ diff --git a/client/public/images/units/multiengine.png b/client/public/images/units/multiengine.png new file mode 100644 index 00000000..34eab23a Binary files /dev/null and b/client/public/images/units/multiengine.png differ diff --git a/client/public/images/units/navyUnit.png b/client/public/images/units/navyUnit.png new file mode 100644 index 00000000..8c6ef4ad Binary files /dev/null and b/client/public/images/units/navyUnit.png differ diff --git a/client/public/images/units/oh-58.png b/client/public/images/units/oh-58.png new file mode 100644 index 00000000..50af43c7 Binary files /dev/null and b/client/public/images/units/oh-58.png differ diff --git a/client/public/images/units/p-47.png b/client/public/images/units/p-47.png new file mode 100644 index 00000000..1b5ae7d4 Binary files /dev/null and b/client/public/images/units/p-47.png differ diff --git a/client/public/images/units/p-51.png b/client/public/images/units/p-51.png new file mode 100644 index 00000000..4c7f4986 Binary files /dev/null and b/client/public/images/units/p-51.png differ diff --git a/client/public/images/units/rafale.png b/client/public/images/units/rafale.png new file mode 100644 index 00000000..367190f4 Binary files /dev/null and b/client/public/images/units/rafale.png differ diff --git a/client/public/images/units/rq-1.png b/client/public/images/units/rq-1.png new file mode 100644 index 00000000..6f45ed10 Binary files /dev/null and b/client/public/images/units/rq-1.png differ diff --git a/client/public/images/units/rq-4.png b/client/public/images/units/rq-4.png new file mode 100644 index 00000000..210862ab Binary files /dev/null and b/client/public/images/units/rq-4.png differ diff --git a/client/public/images/units/s-3.png b/client/public/images/units/s-3.png new file mode 100644 index 00000000..7a6feb8d Binary files /dev/null and b/client/public/images/units/s-3.png differ diff --git a/client/public/images/units/sa-342.png b/client/public/images/units/sa-342.png new file mode 100644 index 00000000..f258c184 Binary files /dev/null and b/client/public/images/units/sa-342.png differ diff --git a/client/public/images/units/spitfire.png b/client/public/images/units/spitfire.png new file mode 100644 index 00000000..70e9e082 Binary files /dev/null and b/client/public/images/units/spitfire.png differ diff --git a/client/public/images/units/su-17.png b/client/public/images/units/su-17.png new file mode 100644 index 00000000..2c27b28b Binary files /dev/null and b/client/public/images/units/su-17.png differ diff --git a/client/public/images/units/su-24.png b/client/public/images/units/su-24.png new file mode 100644 index 00000000..134650ec Binary files /dev/null and b/client/public/images/units/su-24.png differ diff --git a/client/public/images/units/su-25.png b/client/public/images/units/su-25.png new file mode 100644 index 00000000..a45fa129 Binary files /dev/null and b/client/public/images/units/su-25.png differ diff --git a/client/public/images/units/su-27.png b/client/public/images/units/su-27.png new file mode 100644 index 00000000..81a2ede8 Binary files /dev/null and b/client/public/images/units/su-27.png differ diff --git a/client/public/images/units/su-34.png b/client/public/images/units/su-34.png new file mode 100644 index 00000000..44bdc779 Binary files /dev/null and b/client/public/images/units/su-34.png differ diff --git a/client/public/images/units/su-57.png b/client/public/images/units/su-57.png new file mode 100644 index 00000000..02dc88a0 Binary files /dev/null and b/client/public/images/units/su-57.png differ diff --git a/client/public/images/units/tornado.png b/client/public/images/units/tornado.png new file mode 100644 index 00000000..54ded406 Binary files /dev/null and b/client/public/images/units/tornado.png differ diff --git a/client/public/images/units/tu-160.png b/client/public/images/units/tu-160.png new file mode 100644 index 00000000..d0292504 Binary files /dev/null and b/client/public/images/units/tu-160.png differ diff --git a/client/public/images/units/tu-22.png b/client/public/images/units/tu-22.png new file mode 100644 index 00000000..61e15edd Binary files /dev/null and b/client/public/images/units/tu-22.png differ diff --git a/client/public/images/units/tu-95.png b/client/public/images/units/tu-95.png new file mode 100644 index 00000000..7ce802b4 Binary files /dev/null and b/client/public/images/units/tu-95.png differ diff --git a/client/public/images/units/u-28.png b/client/public/images/units/u-28.png new file mode 100644 index 00000000..e31aedb7 Binary files /dev/null and b/client/public/images/units/u-28.png differ diff --git a/client/public/images/units/uh-1.png b/client/public/images/units/uh-1.png new file mode 100644 index 00000000..163cac89 Binary files /dev/null and b/client/public/images/units/uh-1.png differ diff --git a/client/public/images/units/uh-60.png b/client/public/images/units/uh-60.png new file mode 100644 index 00000000..7d436c8a Binary files /dev/null and b/client/public/images/units/uh-60.png differ diff --git a/client/public/images/units/unit.png b/client/public/images/units/unit.png new file mode 100644 index 00000000..8c6ef4ad Binary files /dev/null and b/client/public/images/units/unit.png differ diff --git a/client/public/images/units/viggen.png b/client/public/images/units/viggen.png new file mode 100644 index 00000000..47708c3f Binary files /dev/null and b/client/public/images/units/viggen.png differ diff --git a/client/public/images/units/yak-40.png b/client/public/images/units/yak-40.png new file mode 100644 index 00000000..b562fe59 Binary files /dev/null and b/client/public/images/units/yak-40.png differ diff --git a/client/public/images/units/yak-52.png b/client/public/images/units/yak-52.png new file mode 100644 index 00000000..5728f6e8 Binary files /dev/null and b/client/public/images/units/yak-52.png differ diff --git a/client/public/stylesheets/airbasemarker.css b/client/public/stylesheets/airbasemarker.css index e102e3aa..eedff840 100644 --- a/client/public/stylesheets/airbasemarker.css +++ b/client/public/stylesheets/airbasemarker.css @@ -1,4 +1,4 @@ -.airbasemarker-container { +.airbase-marker-container { height: 60px; width: 60px; left: -30px; @@ -7,7 +7,7 @@ position: absolute; } -.airbasemarker-icon { +.airbase-marker-image { height: 60px; width: 60px; left: 0px; @@ -15,17 +15,22 @@ display: block; position: absolute; filter: drop-shadow(1px 1px 0 white) drop-shadow(1px -1px 0 white) drop-shadow(-1px 1px 0 white) drop-shadow(-1px -1px 0 white); + opacity: 0.8; } -.airbasemarker-icon-blue { - filter: invert(69%) sepia(84%) saturate(264%) hue-rotate(162deg) brightness(100%) contrast(102%) drop-shadow(0px 1px 0 #000A) drop-shadow(1px 0px 0 #000A) drop-shadow(-1px 0px 0 #000A) drop-shadow(0px -1px 0 #000A); +.blue.airbase-marker-image { + filter: invert(40%) sepia(94%) saturate(2477%) hue-rotate(197deg) brightness(92%) contrast(91%) drop-shadow(1px 1px #FFFA) drop-shadow(1px -1px #FFFA) drop-shadow(-1px 1px 0px #FFFA) drop-shadow(-1px -1px #FFFA); } -.airbasemarker-icon-red { - filter: invert(68%) sepia(85%) saturate(2385%) hue-rotate(313deg) brightness(108%) contrast(102%) drop-shadow(0px 1px 0 #000A) drop-shadow(1px 0px 0 #000A) drop-shadow(-1px 0px 0 #000A) drop-shadow(0px -1px 0 #000A); +.red.airbase-marker-image { + filter:invert(32%) sepia(91%) saturate(5128%) hue-rotate(349deg) brightness(97%) contrast(97%) drop-shadow(1px 1px #FFFA) drop-shadow(1px -1px #FFFA) drop-shadow(-1px 1px 0px #FFFA) drop-shadow(-1px -1px #FFFA); } -.airbasemarker-name { +.neutral.airbase-marker-image { + filter: invert(71%) sepia(12%) saturate(9%) hue-rotate(319deg) brightness(92%) contrast(96%) drop-shadow(1px 1px #000A) drop-shadow(1px -1px #000A) drop-shadow(-1px 1px 0px #000A) drop-shadow(-1px -1px #000A); +} + +.airbase-marker-name { bottom: -20px; position: absolute; text-align: center; diff --git a/client/public/stylesheets/layout.css b/client/public/stylesheets/layout.css index 6ed5313d..92fb41e8 100644 --- a/client/public/stylesheets/layout.css +++ b/client/public/stylesheets/layout.css @@ -78,7 +78,7 @@ body { position: absolute; height: 30px; width: 160px; - bottom: 10px; + bottom: 20px; right: 10px; z-index: 1000; } @@ -87,11 +87,20 @@ body { position: absolute; height: fit-content; width: 160px; - bottom: 50px; + bottom: 60px; right: 10px; z-index: 1000; } +#log-panel { + position: absolute; + height: 200px; + width: 400px; + top: 60px; + left: 10px; + z-index: 1000; +} + @media only screen and (max-width: 1000px) { #unit-control-buttons { top: 50px; diff --git a/client/public/stylesheets/logpanel.css b/client/public/stylesheets/logpanel.css new file mode 100644 index 00000000..209a60b9 --- /dev/null +++ b/client/public/stylesheets/logpanel.css @@ -0,0 +1,23 @@ +#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/mouseinfopanel.css b/client/public/stylesheets/mouseinfopanel.css index 3bf331ad..80e5c09a 100644 --- a/client/public/stylesheets/mouseinfopanel.css +++ b/client/public/stylesheets/mouseinfopanel.css @@ -5,7 +5,7 @@ row-gap: 5px; } -#mouse-info-panel .rectangular-container{ +#mouse-info-panel .ol-rectangular-container{ width: 100%; font-weight: 600; font-size: 12px; diff --git a/client/public/stylesheets/panels.css b/client/public/stylesheets/panels.css index 74153621..e754028e 100644 --- a/client/public/stylesheets/panels.css +++ b/client/public/stylesheets/panels.css @@ -2,7 +2,13 @@ .ol-panel { background-color: var(--background-color-dark); font-size: 12px; - transition: bottom 0.2s; 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/selectionscroll.css b/client/public/stylesheets/selectionscroll.css index b2913d86..2073d2de 100644 --- a/client/public/stylesheets/selectionscroll.css +++ b/client/public/stylesheets/selectionscroll.css @@ -5,7 +5,6 @@ width: 220px; height: fit-content; z-index: 2000; - max-height: 400px; padding: 8px; display: flex; flex-direction: column; @@ -35,6 +34,7 @@ overflow-y: auto; height: 100%; width: 100%; + max-height: 400px; } .ol-selection-scroll::-webkit-scrollbar { diff --git a/client/public/stylesheets/style.css b/client/public/stylesheets/style.css index 3a3a32c2..5b7d1539 100644 --- a/client/public/stylesheets/style.css +++ b/client/public/stylesheets/style.css @@ -14,6 +14,7 @@ @import url("visibilitycontrolpanel.css"); @import url("unitinfopanel.css"); @import url("mouseinfopanel.css"); +@import url("logpanel.css"); @import url( "aic.css" ); @import url( "atc.css" ); @@ -48,7 +49,7 @@ html { cursor:crosshair; } -.rectangular-container { +.ol-rectangular-container { padding: 0.5em; background-color: gray; border-radius: 5px; @@ -59,7 +60,7 @@ html { font-size: 12px; } -.rectangular-container-dark { +.ol-rectangular-container-dark { padding-left: 0.5em; padding-right: 0.5em; padding-top: 0.2em; @@ -73,7 +74,7 @@ html { font-size: 12px; } -.rounded-container { +.ol-rounded-container { position: relative; padding: 0.5em; width: fit-content; @@ -85,21 +86,21 @@ html { background-color: gray; } -.rounded-container.blue { +.ol-rounded-container.blue { background-color: var(--blue-coalition-color); border: 1px solid var(--blue-coalition-color); } -.rounded-container.red { +.ol-rounded-container.red { background-color: var(--red-coalition-color); border: 1px solid var(--red-coalition-color); } -.rounded-container.neutral { +.ol-rounded-container.neutral { background-color: var(--neutral-coalition-color); } -.rounded-container-small { +.ol-rounded-container-small { padding: 0.2em; width: fit-content; height: fit-content; @@ -113,7 +114,7 @@ html { padding-right: 5px; } -.rectangular-button { +.ol-rectangular-button { position: relative; padding: 0.5em; width: fit-content; @@ -131,48 +132,48 @@ html { column-gap: 5px; } -.rectangular-button.blue { +.ol-rectangular-button.blue { border: 1px solid var(--blue-coalition-color); color: var(--blue-coalition-color); } -.rectangular-button.red { +.ol-rectangular-button.red { border: 1px solid var(--red-coalition-color); color: var(--red-coalition-color); } -.rectangular-button.white { +.ol-rectangular-button.white { border: 1px solid white; color: white; } -.rectangular-button.white>img { +.ol-rectangular-button.white>img { filter: invert(100%); } -.rectangular-button>img { +.ol-rectangular-button>img { display: inline-block; height: 18px; width: 18px; } -.rectangular-button.red { +.ol-rectangular-button.red { border: 1px solid var(--red-coalition-color); } -.vl { +.ol-vl { border-left: 1px solid #555; width: 1px !important; display: inline-block; } -.hl { +.ol-hl { border-top: 1px solid #555; height: 1px !important; display: inline-block; } -.measure-box { +.ol-measure-box { position: absolute; padding-left: 0.5em; padding-right: 0.5em; diff --git a/client/public/stylesheets/unitcontrolpanel.css b/client/public/stylesheets/unitcontrolpanel.css index fc7c0eac..57f257cf 100644 --- a/client/public/stylesheets/unitcontrolpanel.css +++ b/client/public/stylesheets/unitcontrolpanel.css @@ -65,17 +65,17 @@ height: 100%; } -#selected-units-container .rounded-container { +#selected-units-container .ol-rounded-container { width: calc(100% - 25px); cursor: pointer; margin-left: 25px; } -#selected-units-container .rounded-container.not-selected { +#selected-units-container .ol-rounded-container.not-selected { background-color: transparent; } -#selected-units-container .rounded-container .rounded-container-small { +#selected-units-container .ol-rounded-container .ol-rounded-container-small { display: inline-block; position: absolute; left: 5px; @@ -98,7 +98,7 @@ filter: invert(93%) sepia(97%) saturate(1174%) hue-rotate(291deg) brightness(105%) contrast(97%); } -#unit-control-panel #title-label { +#unit-control-panel .ol-title-label { color: white; font-size: 14px; width: 100%; diff --git a/client/public/stylesheets/unitinfopanel.css b/client/public/stylesheets/unitinfopanel.css index ca311143..dc478257 100644 --- a/client/public/stylesheets/unitinfopanel.css +++ b/client/public/stylesheets/unitinfopanel.css @@ -15,7 +15,7 @@ width: 100%; } -#unit-info-panel>.vl { +#unit-info-panel>.ol-vl { margin-left: 30px; margin-right: 30px; } diff --git a/client/public/stylesheets/unitmarker.css b/client/public/stylesheets/unitmarker.css index babbb02b..5513f3e3 100644 --- a/client/public/stylesheets/unitmarker.css +++ b/client/public/stylesheets/unitmarker.css @@ -1,8 +1,8 @@ -.unit-marker-container { +.ol-unit-marker-container { height: 60px; width: 60px; - left: -30px; - top: -30px; + left: 0px; + top: 0px; border: 0px black solid; position: absolute; padding: 0; @@ -10,7 +10,7 @@ border-collapse: collapse; } -.unit-marker-icon { +.ol-unit-marker-icon { height: 60px; width: 60px; left: 0px; @@ -21,7 +21,24 @@ align-items: center; } -.unit-marker-selected { +.ol-unit-marker-image { + height: 60px; + width: 60px; +} + +.blue.ol-unit-marker-image { + filter: invert(40%) sepia(94%) saturate(2477%) hue-rotate(197deg) brightness(92%) contrast(91%) drop-shadow(1px 1px #0005) drop-shadow(1px -1px #0005) drop-shadow(-1px 1px 0px #0005) drop-shadow(-1px -1px #0005); +} + +.red.ol-unit-marker-image { + filter:invert(32%) sepia(91%) saturate(5128%) hue-rotate(349deg) brightness(97%) contrast(97%) drop-shadow(1px 1px #0005) drop-shadow(1px -1px #0005) drop-shadow(-1px 1px 0px #0005) drop-shadow(-1px -1px #0005); +} + +.neutral.ol-unit-marker-image { + filter: invert(71%) sepia(12%) saturate(9%) hue-rotate(319deg) brightness(92%) contrast(96%) drop-shadow(1px 1px #0005) drop-shadow(1px -1px #0005) drop-shadow(-1px 1px 0px #0005) drop-shadow(-1px -1px #0005); +} + +.ol-unit-marker-selected { width: 100%; height: 100%; border-radius: 50%; @@ -42,44 +59,43 @@ opacity: 0.2; } -.blue.unit-marker-selected { +.blue.ol-unit-marker-selected { background-color: var(--blue-coalition-color); } -.red.unit-marker-selected { +.red.ol-unit-marker-selected { background-color: var(--red-coalition-color); } - -.unit-marker-hovered { +.ol-unit-marker-hovered { filter: brightness(130%); } -.unit-marker-dead { +.ol-unit-marker-dead { filter: brightness(50%); } -.unit-marker-unitName { +.ol-unit-marker-unitName { top: -20px; position: absolute; text-align: center; - font: 800 16px Arial; - white-space: nowrap; - -webkit-text-fill-color: white; - -webkit-text-stroke: 1px; -} - -.unit-marker-name { - bottom: -20px; - position: absolute; - text-align: center; font: 800 14px Arial; white-space: nowrap; -webkit-text-fill-color: white; -webkit-text-stroke: 1px; } -.unit-marker-altitude { +.ol-unit-marker-name { + bottom: -12px; + position: absolute; + text-align: center; + font: 800 12px Arial; + white-space: nowrap; + -webkit-text-fill-color: white; + -webkit-text-stroke: 1px; +} + +.ol-unit-marker-altitude { width: 100%; left: 0px; top: 0px; @@ -91,7 +107,7 @@ -webkit-text-stroke: 1px; } -.unit-marker-speed { +.ol-unit-marker-speed { width: 100%; left: 0px; top: 0px; @@ -103,6 +119,6 @@ -webkit-text-stroke: 1px; } -.unit-marker-container-table-dead .unit-marker-name { +.ol-unit-marker-container-table-dead .ol-unit-marker-name { opacity: 0; } \ No newline at end of file diff --git a/client/public/stylesheets/visibilitycontrolpanel.css b/client/public/stylesheets/visibilitycontrolpanel.css index 5e637c0a..d2e77fae 100644 --- a/client/public/stylesheets/visibilitycontrolpanel.css +++ b/client/public/stylesheets/visibilitycontrolpanel.css @@ -10,7 +10,7 @@ font-weight: 600; } -#visibility-control-panel .vl { +#visibility-control-panel .ol-vl { height: 60%; } diff --git a/client/src/controls/dropdown.ts b/client/src/controls/dropdown.ts index aded3cd6..f4dd66a1 100644 --- a/client/src/controls/dropdown.ts +++ b/client/src/controls/dropdown.ts @@ -28,7 +28,6 @@ export class Dropdown { this.#content.style.left = this.#container.offsetLeft + "px"; this.#content.style.top = this.#container.offsetTop + this.#container.offsetHeight + "px"; - console.log(this.#container); document.body.appendChild(this.#content); var height = 2; diff --git a/client/src/controls/selectionscroll.ts b/client/src/controls/selectionscroll.ts index e4322e73..40f638d2 100644 --- a/client/src/controls/selectionscroll.ts +++ b/client/src/controls/selectionscroll.ts @@ -62,7 +62,6 @@ export class SelectionScroll { else this.#container.style.left = window.innerWidth - this.#container.offsetWidth + "px"; - console.log(y - 20 + this.#container.offsetHeight) if (y - 20 + this.#container.offsetHeight < window.innerHeight) this.#container.style.top = y - 20 + "px"; else diff --git a/client/src/dcs/dcs.ts b/client/src/dcs/dcs.ts index c9ae53f7..393bc198 100644 --- a/client/src/dcs/dcs.ts +++ b/client/src/dcs/dcs.ts @@ -41,7 +41,7 @@ export function spawnSmoke(color: string, latlng: L.LatLng) { xhr.setRequestHeader("Content-Type", "application/json"); xhr.onreadystatechange = () => { if (xhr.readyState === 4) { - console.log("Added " + color + " smoke at " + ConvertDDToDMS(latlng.lat, false) + " " + ConvertDDToDMS(latlng.lng, true)); + //console.log("Added " + color + " smoke at " + ConvertDDToDMS(latlng.lat, false) + " " + ConvertDDToDMS(latlng.lng, true)); } }; @@ -57,7 +57,7 @@ export function spawnGroundUnit(type: string, latlng: L.LatLng, coalition: strin xhr.setRequestHeader("Content-Type", "application/json"); xhr.onreadystatechange = () => { if (xhr.readyState === 4) { - console.log("Added " + coalition + " " + type + " at " + ConvertDDToDMS(latlng.lat, false) + " " + ConvertDDToDMS(latlng.lng, true)); + //console.log("Added " + coalition + " " + type + " at " + ConvertDDToDMS(latlng.lat, false) + " " + ConvertDDToDMS(latlng.lng, true)); } }; @@ -73,7 +73,7 @@ export function spawnAircraft(type: string, latlng: L.LatLng, coalition: string, xhr.setRequestHeader("Content-Type", "application/json"); xhr.onreadystatechange = () => { if (xhr.readyState === 4) { - console.log("Added " + coalition + " " + type + " at " + ConvertDDToDMS(latlng.lat, false) + " " + ConvertDDToDMS(latlng.lng, true)); + //console.log("Added " + coalition + " " + type + " at " + ConvertDDToDMS(latlng.lat, false) + " " + ConvertDDToDMS(latlng.lng, true)); } }; diff --git a/client/src/index.ts b/client/src/index.ts index 708986e7..67a1d00b 100644 --- a/client/src/index.ts +++ b/client/src/index.ts @@ -6,7 +6,6 @@ import { UnitInfoPanel } from "./panels/unitinfopanel"; import { SelectionScroll } from "./controls/selectionscroll"; import { Dropdown } from "./controls/dropdown"; import { ConnectionStatusPanel } from "./panels/connectionstatuspanel"; -import { Button } from "./controls/button"; import { MissionData } from "./missiondata/missiondata"; import { UnitControlPanel } from "./panels/unitcontrolpanel"; import { MouseInfoPanel } from "./panels/mouseInfoPanel"; @@ -16,6 +15,8 @@ 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"; /* TODO: should this be a class? */ var map: Map; @@ -30,8 +31,8 @@ var connectionStatusPanel: ConnectionStatusPanel; var unitControlPanel: UnitControlPanel; var mouseInfoPanel: MouseInfoPanel; var visibilityControlPanel: VisibilityControlPanel; +var logPanel: LogPanel; -var scenarioDropdown: Dropdown; var mapSourceDropdown: Dropdown; var slowButton: Button; @@ -62,17 +63,19 @@ function setup() { /* Initialize */ map = new Map('map-container'); unitsManager = new UnitsManager(); + missionData = new MissionData(); selectionWheel = new SelectionWheel("selection-wheel"); selectionScroll = new SelectionScroll("selection-scroll"); unitInfoPanel = new UnitInfoPanel("unit-info-panel"); unitControlPanel = new UnitControlPanel("unit-control-panel"); - scenarioDropdown = new Dropdown("scenario-dropdown", ["Caucasus", "Marianas", "Nevada", "South Atlantic", "Syria", "The Channel"], () => { }); + //scenarioDropdown = new Dropdown("scenario-dropdown", ["Caucasus", "Marianas", "Nevada", "South Atlantic", "Syria", "The Channel"], () => { }); 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"); missionData = new MissionData(); @@ -132,6 +135,7 @@ function setup() { } + mapSourceDropdown = new Dropdown("map-source-dropdown", map.getLayers(), (option: string) => map.setLayer(option)); /* Default values */ activeCoalition = "blue"; @@ -153,6 +157,7 @@ export function update(data: JSON) { console.log( data ); unitsManager.update(data); missionData.update(data); + logPanel.update(data); } export function getMap() { diff --git a/client/src/map/map.ts b/client/src/map/map.ts index 2d561432..91a0aa24 100644 --- a/client/src/map/map.ts +++ b/client/src/map/map.ts @@ -2,7 +2,7 @@ import * as L from "leaflet" import { getSelectionWheel, getSelectionScroll, getUnitsManager, getActiveCoalition, getMouseInfoPanel } from ".."; import { spawnAircraft, spawnGroundUnit, spawnSmoke } from "../dcs/dcs"; import { bearing, distance, zeroAppend } from "../other/utils"; -import { aircraftDatabase, getAircraftLabelsByRole, getLoadoutsByName, getLoadoutNamesByRole } from "../units/aircraftDatabase"; +import { aircraftDatabase, getAircraftLabelsByRole, getLoadoutsByName, getLoadoutNamesByRole, getAircraftNameByLabel } from "../units/aircraftDatabase"; import { unitTypes } from "../units/unitTypes"; import { BoxSelect } from "./boxselect"; @@ -46,7 +46,7 @@ export class Map extends L.Map { this.#measureIcon = new L.Icon({ iconUrl: 'images/pin.png', iconAnchor: [16, 32]}); this.#measureMarker = new L.Marker([0, 0], {icon: this.#measureIcon, interactive: false}); this.#measureLineDiv = document.createElement("div"); - this.#measureLineDiv.classList.add("measure-box"); + this.#measureLineDiv.classList.add("ol-measure-box"); this.#measureLineDiv.style.display = 'none'; document.body.appendChild(this.#measureLineDiv); @@ -120,12 +120,6 @@ export class Map extends L.Map { else if (this.#state === "MOVE_UNIT") { L.DomUtil.addClass(this.getContainer(),'crosshair-cursor-enabled'); } - else if (this.#state === "ATTACK") { - - } - else if (this.#state === "FORMATION") { - - } } getState() { @@ -330,10 +324,12 @@ export class Map extends L.Map { this.hideSelectionWheel(); this.hideSelectionScroll(); var options = getAircraftLabelsByRole(role); - this.showSelectionScroll(e, "Select aircraft", options, (unitType: string) => { + this.showSelectionScroll(e, "Select aircraft", options, (label: string) => { this.hideSelectionWheel(); this.hideSelectionScroll(); - this.#unitSelectPayload(e, unitType, role); + var name = getAircraftNameByLabel(label); + if (name != null) + this.#unitSelectPayload(e, name, role); }, true); } diff --git a/client/src/missiondata/airbasemarker.ts b/client/src/missiondata/airbasemarker.ts index 3f934418..36bd867a 100644 --- a/client/src/missiondata/airbasemarker.ts +++ b/client/src/missiondata/airbasemarker.ts @@ -19,11 +19,11 @@ export class AirbaseMarker extends L.Marker this.#name = options.name; var icon = new L.DivIcon({ - html: ` + html: `
- -
${options.name}
+ +
${options.name}
`, @@ -40,16 +40,9 @@ export class AirbaseMarker extends L.Marker var img = element.querySelector("#icon"); if (img != null) { - img.classList.remove("airbasemarker-icon-blue"); - img.classList.remove("airbasemarker-icon-red"); - if (this.#coalitionID == 2) - { - img.classList.add("airbasemarker-icon-blue"); - } - else if (this.#coalitionID == 1) - { - img.classList.add("airbasemarker-icon-red"); - } + img.classList.toggle("blue", this.#coalitionID == 2); + img.classList.toggle("red", this.#coalitionID == 1); + img.classList.toggle("neutral", this.#coalitionID == 0); } } } diff --git a/client/src/panels/connectionstatuspanel.ts b/client/src/panels/connectionstatuspanel.ts index 87525048..ccde1ba2 100644 --- a/client/src/panels/connectionstatuspanel.ts +++ b/client/src/panels/connectionstatuspanel.ts @@ -1,24 +1,22 @@ -export class ConnectionStatusPanel { - #element: HTMLElement +import { Panel } from "./panel"; +export class ConnectionStatusPanel extends Panel { constructor(ID: string) { - this.#element = document.getElementById(ID); + super(ID); } update(connected: boolean) { - if (this.#element != null) { - var div = this.#element.querySelector("#status-string"); - if (div != null) { - if (connected) { - div.innerHTML = "Connected"; - div.classList.add("ol-status-connected"); - div.classList.remove("ol-status-disconnected"); - } - else { - div.innerHTML = "Disconnected"; - div.classList.add("ol-status-disconnected"); - div.classList.remove("ol-status-connected"); - } + var div = this.getElement().querySelector("#status-string"); + if (div != null) { + if (connected) { + div.innerHTML = "Connected"; + div.classList.add("ol-status-connected"); + div.classList.remove("ol-status-disconnected"); + } + else { + div.innerHTML = "Disconnected"; + div.classList.add("ol-status-disconnected"); + div.classList.remove("ol-status-connected"); } } } diff --git a/client/src/panels/logpanel.ts b/client/src/panels/logpanel.ts new file mode 100644 index 00000000..44a8d5ea --- /dev/null +++ b/client/src/panels/logpanel.ts @@ -0,0 +1,28 @@ +import { Panel } from "./panel"; + +export class LogPanel extends Panel +{ + #logs: String[]; + + constructor(ID: string) + { + super(ID); + this.#logs = []; + } + + update(data: any) + { + var logs = data["logs"]; + for (let idx in logs) + { + if (parseInt(idx) >= this.#logs.length) { + this.#logs.push(logs[idx]); + var el = document.createElement("div"); + el.innerHTML = logs[idx]; + el.classList.add("js-log-element", "ol-log-element"); + this.getElement().appendChild(el); + this.getElement().scrollTop = this.getElement().scrollHeight; + } + } + } +} \ No newline at end of file diff --git a/client/src/panels/mouseInfoPanel.ts b/client/src/panels/mouseInfoPanel.ts index 74ed0a72..398d5609 100644 --- a/client/src/panels/mouseInfoPanel.ts +++ b/client/src/panels/mouseInfoPanel.ts @@ -1,28 +1,11 @@ import { LatLng } from "leaflet"; import { getMissionData } from ".."; import { distance, bearing, zeroPad, zeroAppend } from "../other/utils"; -import { Unit } from "../units/unit"; - -export class MouseInfoPanel { - #element: HTMLElement - #display: string; +import { Panel } from "./panel"; +export class MouseInfoPanel extends Panel { constructor(ID: string) { - this.#element = document.getElementById(ID); - this.#display = ''; - if (this.#element != null) { - this.#display = this.#element.style.display; - var el = this.#element.querySelector(`#measure-position`); - this.show(); - } - } - - show() { - this.#element.style.display = this.#display; - } - - hide() { - this.#element.style.display = "none"; + super(ID); } update(mousePosition: LatLng, measurePosition: LatLng | null, unitPosition: LatLng | null) { @@ -31,7 +14,7 @@ export class MouseInfoPanel { { var dist = distance(bullseyes[idx].lat, bullseyes[idx].lng, mousePosition.lat, mousePosition.lng); var bear = bearing(bullseyes[idx].lat, bullseyes[idx].lng, mousePosition.lat, mousePosition.lng); - var el = this.#element.querySelector(`#bullseye-${idx}`); + var el = this.getElement().querySelector(`#bullseye-${idx}`); if (el != null) el.innerHTML = `${zeroAppend(Math.floor(bear), 3)}° / ${zeroAppend(Math.floor(dist*0.000539957), 3)} NM` } @@ -39,16 +22,16 @@ export class MouseInfoPanel { if (measurePosition) { var dist = distance(measurePosition.lat, measurePosition.lng, mousePosition.lat, mousePosition.lng); var bear = bearing(measurePosition.lat, measurePosition.lng, mousePosition.lat, mousePosition.lng); - var el = this.#element.querySelector(`#measure-position`); + var el = this.getElement().querySelector(`#measure-position`); if (el != null) { el.innerHTML = `${zeroAppend(Math.floor(bear), 3)}° / ${zeroAppend(Math.floor(dist*0.000539957), 3)} NM` if (el.parentElement != null) - el.parentElement.style.display = 'flex'; //TODO: don't like that its hardcoded + el.parentElement.style.display = 'flex'; //TODO: don't like that it's hardcoded } } else { - var el = this.#element.querySelector(`#measure-position`); + var el = this.getElement().querySelector(`#measure-position`); if (el != null && el.parentElement != null) el.parentElement.style.display = 'none'; } @@ -56,7 +39,7 @@ export class MouseInfoPanel { if (unitPosition) { var dist = distance(unitPosition.lat, unitPosition.lng, mousePosition.lat, mousePosition.lng); var bear = bearing(unitPosition.lat, unitPosition.lng, mousePosition.lat, mousePosition.lng); - var el = this.#element.querySelector(`#unit-position`); + var el = this.getElement().querySelector(`#unit-position`); if (el != null) { el.innerHTML = `${zeroAppend(Math.floor(bear), 3)}° / ${zeroAppend(Math.floor(dist*0.000539957), 3)} NM` @@ -65,7 +48,7 @@ export class MouseInfoPanel { } } else { - var el = this.#element.querySelector(`#unit-position`); + var el = this.getElement().querySelector(`#unit-position`); if (el != null && el.parentElement != null) el.parentElement.style.display = 'none'; } diff --git a/client/src/panels/panel.ts b/client/src/panels/panel.ts new file mode 100644 index 00000000..acb8e5c0 --- /dev/null +++ b/client/src/panels/panel.ts @@ -0,0 +1,22 @@ +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; + } + + hide() { + this.#element.style.display = "none"; + } + + getElement() { + return this.#element; + } +} \ No newline at end of file diff --git a/client/src/panels/unitcontrolpanel.ts b/client/src/panels/unitcontrolpanel.ts index 9a143ffd..e4bc98b3 100644 --- a/client/src/panels/unitcontrolpanel.ts +++ b/client/src/panels/unitcontrolpanel.ts @@ -1,159 +1,155 @@ -import { imageOverlay } from "leaflet"; -import { getUnitControlSliders, getUnitsManager } from ".."; -import { ConvertDDToDMS, rad2deg } from "../other/utils"; +import { getUnitsManager } from ".."; +import { Slider } from "../controls/slider"; import { Aircraft, AirUnit, GroundUnit, Helicopter, NavyUnit, Unit } from "../units/unit"; +import { Panel } from "./panel"; -export class UnitControlPanel { - #element: HTMLElement - #display: string; +interface Button { + id: string, + value: string, + element: null | HTMLElement +} + +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} + ] constructor(ID: string) { - this.#element = document.getElementById(ID); - this.#display = ''; - if (this.#element != null) { - this.#display = this.#element.style.display; - var formationCreationContainer = (this.#element.querySelector("#formation-creation-container")); - if (formationCreationContainer != null) - { - var createButton = formationCreationContainer.querySelector("#create-formation"); - createButton?.addEventListener("click", () => getUnitsManager().selectedUnitsCreateFormation()); + super(ID); - var undoButton = formationCreationContainer.querySelector("#undo-formation"); - undoButton?.addEventListener("click", () => getUnitsManager().selectedUnitsUndoFormation()); - } - var ROEButtonsContainer = (this.#element.querySelector("#roe-buttons-container")); - if (ROEButtonsContainer != null) - { - (ROEButtonsContainer.querySelector("#free"))?.addEventListener("click", () => getUnitsManager().selectedUnitsSetROE("Free")); - (ROEButtonsContainer.querySelector("#designated-free"))?.addEventListener("click", () => getUnitsManager().selectedUnitsSetROE("Designated free")); - (ROEButtonsContainer.querySelector("#designated"))?.addEventListener("click", () => getUnitsManager().selectedUnitsSetROE("Designated")); - (ROEButtonsContainer.querySelector("#return"))?.addEventListener("click", () => getUnitsManager().selectedUnitsSetROE("Return")); - (ROEButtonsContainer.querySelector("#hold"))?.addEventListener("click", () => getUnitsManager().selectedUnitsSetROE("Hold")); - } + /* Selected units container */ + this.#selectedUnitsContainer = (this.getElement().querySelector("#selected-units-container")); - var reactionToThreatButtonsContainer = (this.#element.querySelector("#reaction-to-threat-buttons-container")); - if (reactionToThreatButtonsContainer != null) - { - (reactionToThreatButtonsContainer.querySelector("#none"))?.addEventListener("click", () => getUnitsManager().selectedUnitsSetReactionToThreat("None")); - (reactionToThreatButtonsContainer.querySelector("#passive"))?.addEventListener("click", () => getUnitsManager().selectedUnitsSetReactionToThreat("Passive")); - (reactionToThreatButtonsContainer.querySelector("#evade"))?.addEventListener("click", () => getUnitsManager().selectedUnitsSetReactionToThreat("Evade")); - (reactionToThreatButtonsContainer.querySelector("#escape"))?.addEventListener("click", () => getUnitsManager().selectedUnitsSetReactionToThreat("Escape")); - (reactionToThreatButtonsContainer.querySelector("#abort"))?.addEventListener("click", () => getUnitsManager().selectedUnitsSetReactionToThreat("Abort")); - } - this.hide(); + /* 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)); } - } - show() { - this.#element.style.display = this.#display; - } - - hide() { - this.#element.style.display = "none"; + this.hide(); } update(units: Unit[]) { - if (this.#element != null) + if (this.getElement() != null) { - var selectedUnitsContainer = (this.#element.querySelector("#selected-units-container")); - var formationCreationContainer = (this.#element.querySelector("#formation-creation-container")); - if (selectedUnitsContainer != null && formationCreationContainer != null) - { - this.#addUnitsButtons(units, selectedUnitsContainer); - this.#showFlightControlSliders(units); - this.#showFormationButtons(units, formationCreationContainer); - } + //this.#addUnitsButtons(units); + //this.#showFormationButtons(units); + + this.#showFlightControlSliders(units); - var ROEButtonsContainer = (this.#element.querySelector("#roe-buttons-container")); - if (ROEButtonsContainer != null) - { - (ROEButtonsContainer.querySelector("#free"))?.classList.toggle("white", this.#getROE(units) === "Free"); - (ROEButtonsContainer.querySelector("#designated-free"))?.classList.toggle("white", this.#getROE(units) === "Designated free"); - (ROEButtonsContainer.querySelector("#designated"))?.classList.toggle("white", this.#getROE(units) === "Designated"); - (ROEButtonsContainer.querySelector("#return"))?.classList.toggle("white", this.#getROE(units) === "Return"); - (ROEButtonsContainer.querySelector("#hold"))?.classList.toggle("white", this.#getROE(units) === "Hold"); - } - - var reactionToThreatButtonsContainer = (this.#element.querySelector("#reaction-to-threat-buttons-container")); - if (reactionToThreatButtonsContainer != null) - { - (reactionToThreatButtonsContainer.querySelector("#none"))?.classList.toggle("white", this.#getReactionToThreat(units) === "None"); - (reactionToThreatButtonsContainer.querySelector("#passive"))?.classList.toggle("white", this.#getReactionToThreat(units) === "Passive"); - (reactionToThreatButtonsContainer.querySelector("#evade"))?.classList.toggle("white", this.#getReactionToThreat(units) === "Evade"); - (reactionToThreatButtonsContainer.querySelector("#escape"))?.classList.toggle("white", this.#getReactionToThreat(units) === "Escape"); - (reactionToThreatButtonsContainer.querySelector("#abort"))?.classList.toggle("white", this.#getReactionToThreat(units) === "Abort"); - } + 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); } } #showFlightControlSliders(units: Unit[]) { - var sliders = getUnitControlSliders(); - sliders.airspeed.show(); - sliders.altitude.show(); + this.#airspeedSlider.show(); + this.#altitudeSlider.show(); if (this.#checkAllUnitsAircraft(units)) { - sliders.airspeed.setMinMax(100, 600); - sliders.altitude.setMinMax(0, 50000); + this.#airspeedSlider.setMinMax(100, 600); + this.#altitudeSlider.setMinMax(0, 50000); } else if (this.#checkAllUnitsHelicopter(units)) { - sliders.airspeed.setMinMax(0, 200); - sliders.altitude.setMinMax(0, 10000); + this.#airspeedSlider.setMinMax(0, 200); + this.#altitudeSlider.setMinMax(0, 10000); } else if (this.#checkAllUnitsGroundUnit(units)) { - sliders.airspeed.setMinMax(0, 60); - sliders.altitude.hide(); + this.#airspeedSlider.setMinMax(0, 60); + this.#altitudeSlider.hide(); } else if (this.#checkAllUnitsNavyUnit(units)) { - sliders.airspeed.setMinMax(0, 60); - sliders.altitude.hide(); + this.#airspeedSlider.setMinMax(0, 60); + this.#altitudeSlider.hide(); } else { - sliders.airspeed.hide(); - sliders.altitude.hide(); + this.#airspeedSlider.hide(); + this.#altitudeSlider.hide(); } var targetSpeed = this.#getTargetAirspeed(units); if (targetSpeed != null) { - sliders.airspeed.setActive(true); - sliders.airspeed.setValue(targetSpeed * 1.94384); + this.#airspeedSlider.setActive(true); + this.#airspeedSlider.setValue(targetSpeed * 1.94384); } else { - sliders.airspeed.setActive(false); + this.#airspeedSlider.setActive(false); } var targetAltitude = this.#getTargetAltitude(units); if (targetAltitude != null) { - sliders.altitude.setActive(true); - sliders.altitude.setValue(targetAltitude / 0.3048); + this.#altitudeSlider.setActive(true); + this.#altitudeSlider.setValue(targetAltitude / 0.3048); } else { - sliders.altitude.setActive(false); + this.#altitudeSlider.setActive(false); } } - #addUnitsButtons(units: Unit[], selectedUnitsContainer: HTMLElement) + #addUnitsButtons(units: Unit[]) { /* Remove any pre-existing unit button */ - var elements = selectedUnitsContainer.getElementsByClassName("js-unit-container"); + var elements = this.#selectedUnitsContainer.getElementsByClassName("js-unit-container"); while (elements.length > 0) - selectedUnitsContainer.removeChild(elements[0]) + this.#selectedUnitsContainer.removeChild(elements[0]) /* Create all the units buttons */ for (let unit of units) { - this.#addUnitButton(unit, selectedUnitsContainer); + this.#addUnitButton(unit, this.#selectedUnitsContainer); if (unit.isLeader) for (let wingman of unit.getWingmen()) - this.#addUnitButton(wingman, selectedUnitsContainer); + this.#addUnitButton(wingman, this.#selectedUnitsContainer); } } @@ -163,7 +159,7 @@ export class UnitControlPanel { /* Unit name (actually type, but DCS calls it name for some reason) */ var nameDiv = document.createElement("div"); - nameDiv.classList.add("rounded-container-small"); + nameDiv.classList.add("ol-rounded-container-small"); if (unit.name.length >= 7) nameDiv.innerHTML = `${unit.name.substring(0, 4)} ...`; else @@ -193,36 +189,27 @@ export class UnitControlPanel { if ((unit instanceof AirUnit)) el.append(icon); - el.classList.add("rounded-container", "js-unit-container"); + el.classList.add("ol-rounded-container", "js-unit-container"); if (!unit.getSelected()) el.classList.add("not-selected") /* Set background color */ - if (unit.coalitionID == 1) - { - el.classList.add("red"); - icon.classList.add("red"); - } - else if (unit.coalitionID == 2) - { - el.classList.add("blue"); - icon.classList.add("blue"); - } - else - { - el.classList.add("neutral"); - icon.classList.add("neutral"); - } - + el.classList.toggle("red", unit.coalitionID == 1); + icon.classList.toggle("red", unit.coalitionID == 1); + el.classList.toggle("blue", unit.coalitionID == 2); + icon.classList.toggle("blue", unit.coalitionID == 2); + el.classList.toggle("neutral", unit.coalitionID == 0); + icon.classList.toggle("neutral", unit.coalitionID == 0); + el.addEventListener("click", () => getUnitsManager().selectUnit(unit.ID)); container.appendChild(el); } - #showFormationButtons(units: Unit[], formationCreationContainer: HTMLElement) + #showFormationButtons(units: Unit[]) { - var createButton = formationCreationContainer.querySelector("#create-formation"); - var undoButton = formationCreationContainer.querySelector("#undo-formation"); + var createButton = this.#formationCreationContainer.querySelector("#create-formation"); + var undoButton = this.#formationCreationContainer.querySelector("#undo-formation"); if (createButton && undoButton && this.#checkAllUnitsAir(units)) { if (!this.#checkUnitsAlreadyInFormation(units)) diff --git a/client/src/panels/unitinfopanel.ts b/client/src/panels/unitinfopanel.ts index 2887c0ed..2e31759a 100644 --- a/client/src/panels/unitinfopanel.ts +++ b/client/src/panels/unitinfopanel.ts @@ -1,62 +1,75 @@ import { ConvertDDToDMS, rad2deg } from "../other/utils"; import { Unit } from "../units/unit"; +import { Panel } from "./panel"; -export class UnitInfoPanel { - #element: HTMLElement - #display: string; +export class UnitInfoPanel extends Panel { + #unitName: HTMLElement; + #groupName: HTMLElement; + #name: HTMLElement; + #heading: HTMLElement; + #altitude: HTMLElement; + #groundSpeed: HTMLElement; + #fuel: HTMLElement; + #latitude: HTMLElement; + #longitude: HTMLElement; + #task: HTMLElement; + #loadoutContainer: HTMLElement; constructor(ID: string) { - this.#element = document.getElementById(ID); - this.#display = ''; - if (this.#element != null) { - this.#display = this.#element.style.display; - this.hide(); - } - } + super(ID); - show() { - this.#element.style.display = this.#display; - } + this.#unitName = (this.getElement().querySelector("#unit-name")); + this.#groupName= (this.getElement().querySelector("#group-name")); + this.#name = (this.getElement().querySelector("#name")); + this.#heading = (this.getElement().querySelector("#heading")); + this.#altitude = (this.getElement().querySelector("#altitude")); + this.#groundSpeed = (this.getElement().querySelector("#ground-speed")); + this.#fuel = (this.getElement().querySelector("#fuel")); + this.#latitude = (this.getElement().querySelector("#latitude")); + this.#longitude = (this.getElement().querySelector("#longitude")); + this.#task = (this.getElement().querySelector("#task")); + this.#loadoutContainer = (this.getElement().querySelector("#loadout-container")); - hide() { - this.#element.style.display = "none"; + this.hide(); } - + update(unit: Unit) { - if (this.#element != null) { - var els = this.#element.getElementsByClassName("js-loadout-element"); - while (els.length > 0) - this.#element.querySelector("#loadout-container")?.removeChild(els[0]); - - for (let index in unit.ammo) { - var ammo = unit.ammo[index]; - var displayName = ammo.desc.displayName; - var amount = ammo.count; - var el = document.createElement("div") - el.classList.add("js-loadout-element", "rectangular-container-dark") - el.innerHTML = amount + "x" + displayName; - this.#element.querySelector("#loadout-container")?.appendChild(el); - } + if (this.getElement() != null) { + /* Set the unit info */ + this.#unitName.innerHTML = unit.unitName; + this.#groupName.innerHTML = unit.groupName; + this.#name.innerHTML = unit.name; + this.#heading.innerHTML = String(Math.floor(rad2deg(unit.heading)) + " °"); + this.#altitude.innerHTML = String(Math.floor(unit.altitude / 0.3048) + " ft"); + this.#groundSpeed.innerHTML = String(Math.floor(unit.speed * 1.94384) + " kts"); + this.#fuel.innerHTML = String(unit.fuel + "%"); + this.#latitude.innerHTML = ConvertDDToDMS(unit.latitude, false); + this.#longitude.innerHTML = ConvertDDToDMS(unit.longitude, true); + this.#task.innerHTML = unit.currentTask !== ""? unit.currentTask: "No task"; - this.#element.querySelector("#unit-name")!.innerHTML = unit.unitName; - this.#element.querySelector("#group-name")!.innerHTML = unit.groupName; - this.#element.querySelector("#name")!.innerHTML = unit.name; - this.#element.querySelector("#heading")!.innerHTML = String(Math.floor(rad2deg(unit.heading)) + " °"); - this.#element.querySelector("#altitude")!.innerHTML = String(Math.floor(unit.altitude / 0.3048) + " ft"); - this.#element.querySelector("#ground-speed")!.innerHTML = String(Math.floor(unit.speed * 1.94384) + " kts"); - this.#element.querySelector("#fuel")!.innerHTML = String(unit.fuel + "%"); - this.#element.querySelector("#latitude")!.innerHTML = ConvertDDToDMS(unit.latitude, false); - this.#element.querySelector("#longitude")!.innerHTML = ConvertDDToDMS(unit.longitude, true); - this.#element.querySelector("#task")!.innerHTML = unit.currentTask !== ""? unit.currentTask: "Not controlled"; - - this.#element.querySelector("#task")!.classList.remove("red", "blue", "neutral"); - if (unit.coalitionID == 1) - this.#element.querySelector("#task")!.classList.add("red"); - else if (unit.coalitionID == 2) - this.#element.querySelector("#task")!.classList.add("blue"); - else - this.#element.querySelector("#task")!.classList.add("neutral"); + /* Set the class of the task container */ + this.#task.classList.toggle("red", unit.coalitionID == 1); + this.#task.classList.toggle("blue", unit.coalitionID == 2); + this.#task.classList.toggle("neutral", unit.coalitionID == 0); + /* Add the loadout elements */ + var els = this.getElement().getElementsByClassName("js-loadout-element"); + while (els.length > 0) + this.#loadoutContainer.removeChild(els[0]); + + for (let index in unit.ammo) + this.#addLoadoutElement(unit, index); } } + + #addLoadoutElement(unit: Unit, index: string) + { + var ammo = unit.ammo[index]; + var displayName = ammo.desc.displayName; + var amount = ammo.count; + var el = document.createElement("div") + el.classList.add("js-loadout-element", "ol-rectangular-container-dark") + el.innerHTML = 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 index e4c6b402..46788bb0 100644 --- a/client/src/panels/visibilitycontrolpanel.ts +++ b/client/src/panels/visibilitycontrolpanel.ts @@ -51,7 +51,7 @@ export class VisibilityControlPanel { var airVisibilityCheckbox = this.#element.querySelector("#air-visibility"); if (airVisibilityCheckbox.checked) - AirUnit.setVisibility({human: activeVisibility, ai: activeVisibility, uncontrolled: uncontrolledVisibility? activeVisibility: "hidden", dead: "hidden"}); + AirUnit.setVisibility({human: "full", ai: activeVisibility, uncontrolled: uncontrolledVisibility? activeVisibility: "hidden", dead: "hidden"}); else AirUnit.setVisibility({human: "hidden", ai: "hidden", uncontrolled: "hidden", dead: "hidden"}); diff --git a/client/src/units/aircraftDatabase.ts b/client/src/units/aircraftDatabase.ts index 9b0eafa4..89f5e3d0 100644 --- a/client/src/units/aircraftDatabase.ts +++ b/client/src/units/aircraftDatabase.ts @@ -33,7 +33,7 @@ export function getLoadoutNamesByRole(aircraft: string, role: string) export function getLoadoutsByName(aircraft: string, loadoutName: string) { - //@ts-ignore + //@ts-ignore TODO for (let loadout of aircraftDatabase[aircraft]["loadouts"]) { if (loadout["name"] === loadoutName) @@ -44,6 +44,26 @@ export function getLoadoutsByName(aircraft: string, loadoutName: string) return null; } +export function getAircraftNameByLabel(label: string) +{ + for (let name in aircraftDatabase) + { + //@ts-ignore TODO + if (aircraftDatabase[name]["label"] === label) + { + return name; + } + } + return null; +} + + +export function getAircraftLabelByName(name: string) +{ + //@ts-ignore TODO + return aircraftDatabase[name] === undefined? name: aircraftDatabase[name].label; +} + export var aircraftDatabase = { "A-10C": { "name": "A-10C", @@ -512,8 +532,8 @@ export var aircraftDatabase = { ] }, - "F/A-18C": { - "name": "F/A-18C", + "FA-18C_hornet": { + "name": "FA-18C_hornet", "label": "F/A-18C", "loadouts": [ { @@ -1233,4 +1253,165 @@ export var aircraftDatabase = { } ] }, -} \ No newline at end of file +} + +export function getAircrafImage(name: string) +{ + var results = [] + for (let imageName of imageNames) { + var score = similarity(imageName, name); + results.push({score: score, imageName: imageName}); + } + + var bestResult = null; + for (let result of results) + { + if (bestResult == null) + bestResult = result; + else { + if (result.score > bestResult.score) + bestResult = result; + } + } + return bestResult?.imageName + ".png"; +} + +function similarity(s1: string, s2: string) { + var longer = s1; + var shorter = s2; + if (s1.length < s2.length) { + longer = s2; + shorter = s1; + } + var longerLength = longer.length; + if (longerLength == 0) { + return 1.0; + } + return (longerLength - editDistance(longer, shorter)) / longerLength; + } + +function editDistance(s1: string, s2: string) { + s1 = s1.toLowerCase(); + s2 = s2.toLowerCase(); + + var costs = new Array(); + for (var i = 0; i <= s1.length; i++) { + var lastValue = i; + for (var j = 0; j <= s2.length; j++) { + if (i == 0) + costs[j] = j; + else { + if (j > 0) { + var newValue = costs[j - 1]; + if (s1.charAt(i - 1) != s2.charAt(j - 1)) + newValue = Math.min(Math.min(newValue, lastValue), + costs[j]) + 1; + costs[j - 1] = lastValue; + lastValue = newValue; + } + } + } + if (i > 0) + costs[s2.length] = lastValue; + } + return costs[s2.length]; + } + +var imageNames = [ + 'a-10', + 'a-20', + 'a-29', + 'a-4', + 'a-400', + 'a-50', + 'a-6', + 'ah-1', + 'ah-64', + 'an-26', + 'av8bna', + 'b-1', + 'b-17', + 'b-2', + 'b-52', + 'b707', + 'bf109', + 'bomb', + 'c-101', + 'c-130', + 'c-17', + 'c-5', + 'ch-47', + 'ch-53', + 'christeneagleii', + 'e-2', + 'e-3', + 'eurofighter', + 'f-111', + 'f-117', + 'f-14', + 'f-15', + 'f-16', + 'f-18', + 'f-22', + 'f-35', + 'f-4', + 'f-5', + 'f-86', + 'fw190', + 'general1', + 'gripen', + 'h-6', + 'hawk', + 'helicopter1', + 'i-16', + 'il-76', + 'j-10', + 'j-20', + 'j-7', + 'jf-17', + 'ju-88', + 'ka-27', + 'ka-50', + 'kc-10', + 'kc-135', + 'l-159', + 'l-39', + 'm2000', + 'mi-24', + 'mi-26', + 'mi-28', + 'mi-8', + 'mig-15', + 'mig-19', + 'mig-21', + 'mig-23', + 'mig-25', + 'mig-29', + 'mosquito', + 'multiengine', + 'oh-58', + 'p-47', + 'p-51', + 'rafale', + 'rq-1', + 'rq-4', + 's-3', + 'sa-342', + 'spitfire', + 'su-17', + 'su-24', + 'su-25', + 'su-27', + 'su-34', + 'su-57', + 'tornado', + 'tu-160', + 'tu-22', + 'tu-95', + 'u-28', + 'uh-1', + 'uh-60', + 'viggen', + 'yak-40', + 'yak-52' +] \ No newline at end of file diff --git a/client/src/units/unit.ts b/client/src/units/unit.ts index 918967b6..38490982 100644 --- a/client/src/units/unit.ts +++ b/client/src/units/unit.ts @@ -1,9 +1,9 @@ import { Marker, LatLng, Polyline, Icon } from 'leaflet'; import { getMap, getUnitsManager} from '..'; -import { UnitMarker, MarkerOptions, AircraftMarker, HelicopterMarker, GroundUnitMarker, NavyUnitMarker, WeaponMarker } from './unitmarker'; +import { UnitMarker, MarkerOptions, AircraftMarker, HelicopterMarker, GroundUnitMarker, NavyUnitMarker, WeaponMarker, MissileMarker, BombMarker } from './unitmarker'; import { addDestination, attackUnit, changeAltitude, changeSpeed, createFormation as setLeader, landAt, setAltitude, setReactionToThreat, setROE, setSpeed } from '../dcs/dcs'; -interface visibilityOptions { +interface VisibilityOptions { dead: string; ai: string; uncontrolled: string; @@ -393,8 +393,8 @@ export class Unit { } export class AirUnit extends Unit { - static visibility: visibilityOptions = {dead: "hidden", ai: "partial", uncontrolled: "partial", human: "partial"} - static setVisibility(visibility: visibilityOptions) + static visibility: VisibilityOptions = {dead: "hidden", ai: "partial", uncontrolled: "partial", human: "full"} + static setVisibility(visibility: VisibilityOptions) { getUnitsManager().forceUpdate(); AirUnit.visibility = visibility; @@ -438,8 +438,8 @@ export class Helicopter extends AirUnit { } export class GroundUnit extends Unit { - static visibility: visibilityOptions = {dead: "hidden", ai: "partial", uncontrolled: "partial", human: "partial"} - static setVisibility(visibility: visibilityOptions) + static visibility: VisibilityOptions = {dead: "hidden", ai: "partial", uncontrolled: "partial", human: "partial"} + static setVisibility(visibility: VisibilityOptions) { getUnitsManager().forceUpdate(); GroundUnit.visibility = visibility; @@ -474,8 +474,8 @@ export class GroundUnit extends Unit { } export class NavyUnit extends Unit { - static visibility: visibilityOptions = {dead: "hidden", ai: "partial", uncontrolled: "partial", human: "partial"} - static setVisibility(visibility: visibilityOptions) + static visibility: VisibilityOptions = {dead: "hidden", ai: "partial", uncontrolled: "partial", human: "partial"} + static setVisibility(visibility: VisibilityOptions) { getUnitsManager().forceUpdate(); NavyUnit.visibility = visibility; @@ -507,8 +507,8 @@ export class NavyUnit extends Unit { } export class Weapon extends Unit { - static visibility: visibilityOptions = {dead: "hidden", ai: "partial", uncontrolled: "partial", human: "partial"} - static setVisibility(visibility: visibilityOptions) + static visibility: VisibilityOptions = {dead: "hidden", ai: "partial", uncontrolled: "partial", human: "partial"} + static setVisibility(visibility: VisibilityOptions) { getUnitsManager().forceUpdate(); Weapon.visibility = visibility; @@ -535,14 +535,14 @@ export class Weapon extends Unit { export class Missile extends Weapon { constructor(ID: number, options: MarkerOptions) { - var marker = new WeaponMarker(options); + var marker = new MissileMarker(options); super(ID, marker); } } export class Bomb extends Weapon { constructor(ID: number, options: MarkerOptions) { - var marker = new WeaponMarker(options); + var marker = new BombMarker(options); super(ID, marker); } } diff --git a/client/src/units/unitTypes.ts b/client/src/units/unitTypes.ts index fb0da5aa..7b10a96f 100644 --- a/client/src/units/unitTypes.ts +++ b/client/src/units/unitTypes.ts @@ -205,72 +205,3 @@ unitTypes.vehicles.Unarmed = [ "ZIL-131 KUNG", "ZIL-4331" ] - -/* AIRPLANES */ -unitTypes.air = {} - -unitTypes.air.CAP = [ - "F-4E", - "F/A-18C", - "MiG-29S", - "F-14A", - "Su-27", - "MiG-23MLD", - "Su-33", - "MiG-25RBT", - "Su-30", - "MiG-31", - "Mirage 2000-5", - "F-15C", - "F-5E", - "F-16C bl.52d", -] - -unitTypes.air.CAS = [ - "Tornado IDS", - "F-4E", - "F/A-18C", - "MiG-27K", - "A-10C", - "Su-25", - "Su-34", - "Su-17M4", - "F-15E", -] - -unitTypes.air.strike = [ - "Tu-22M3", - "B-52H", - "F-111F", - "Tu-95MS", - "Su-24M", - "Tu-160", - "F-117A", - "B-1B", - "Tu-142", -] - -unitTypes.air.tanker = [ - "S-3B Tanker", - "KC-135", - "IL-78M", -] - -unitTypes.air.awacs = [ - "A-50", - "E-3A", - "E-2D", -] - -unitTypes.air.drone = [ - "MQ-1A Predator", - "MQ-9 Reaper", -] - -unitTypes.air.transport = [ - "C-130", - "An-26B", - "An-30M", - "C-17A", - "IL-76MD", -] \ No newline at end of file diff --git a/client/src/units/unitmarker.ts b/client/src/units/unitmarker.ts index 55c2297a..43aa16aa 100644 --- a/client/src/units/unitmarker.ts +++ b/client/src/units/unitmarker.ts @@ -1,5 +1,6 @@ import * as L from 'leaflet' -import { Symbol } from 'milsymbol' +import { getMap } from '..' +import { getAircrafImage, getAircraftLabelByName } from './aircraftDatabase' import { AirUnit, GroundUnit, NavyUnit, Weapon } from './unit' export interface MarkerOptions { @@ -29,12 +30,11 @@ export class UnitMarker extends L.Marker { constructor(options: MarkerOptions) { super(new L.LatLng(0, 0), { riseOnHover: true }); this.#unitName = options.unitName; - this.#name = options.name; + this.#name = getAircraftLabelByName(options.name); this.#human = options.human; this.#AI = options.AI; - var symbol = new Symbol(this.#computeMarkerCode(options), { size: 25 }); - var img = symbol.asCanvas().toDataURL('image/png'); + var img = this.getUnitImage(); var coalition = ""; if (options.coalitionID == 1) @@ -45,20 +45,21 @@ export class UnitMarker extends L.Marker { coalition = "neutral" var icon = new L.DivIcon({ - html: ` + html: `
-
-
${this.#unitName}
-
-
-
${this.#name}
+
+
${this.#unitName}
+
+
+
${this.#name}
`, - className: 'unit-marker' + className: 'ol-unit-marker', + iconAnchor: [30, 30] }); this.setIcon(icon); } @@ -104,18 +105,21 @@ export class UnitMarker extends L.Marker { altitudeDiv.innerHTML = String(Math.round(data.altitude / 0.3048 / 100) / 10); speedDiv.innerHTML = String(Math.round(data.speed * 1.94384)); + var pos = getMap().latLngToLayerPoint(this.getLatLng()).round(); + this.setZIndexOffset(Math.floor(data.altitude) - pos.y); + if (!this.#alive) { - this.getElement()?.querySelector("#icon")?.classList.add("unit-marker-dead"); + this.getElement()?.querySelector("#icon")?.classList.add("ol-unit-marker-dead"); } } } setSelected(selected: boolean) { this.#selected = selected; - this.getElement()?.querySelector("#icon")?.classList.remove("unit-marker-hovered"); - this.getElement()?.querySelector("#ring")?.classList.toggle("unit-marker-selected", selected); - this.getElement()?.querySelector("#background")?.classList.toggle("unit-marker-selected", selected); + this.getElement()?.querySelector("#icon")?.classList.remove("ol-unit-marker-hovered"); + this.getElement()?.querySelector("#ring")?.classList.toggle("ol-unit-marker-selected", selected); + this.getElement()?.querySelector("#background")?.classList.toggle("ol-unit-marker-selected", selected); } getSelected() { @@ -123,7 +127,11 @@ export class UnitMarker extends L.Marker { } setHovered(hovered: boolean) { - this.getElement()?.querySelector("#icon")?.classList.toggle("unit-marker-hovered", hovered && this.#alive); + this.getElement()?.querySelector("#icon")?.classList.toggle("ol-unit-marker-hovered", hovered && this.#alive); + } + + getName() { + return this.#name; } getHuman() { @@ -142,85 +150,9 @@ export class UnitMarker extends L.Marker { return "full"; } - #computeMarkerCode(options: MarkerOptions) { - var identity = "00"; - var set = "00"; - var entity = "00"; - var entityType = "00"; - var entitySubtype = "00"; - var sectorOneModifier = "00"; - var sectorTwoModifier = "00"; - - /* Identity */ - if (options.coalitionID == 1) - identity = "06" /* Hostile */ - else if (options.coalitionID == 2) - identity = "03" /* Friendly */ - else - identity = "04" /* Neutral */ - - /* Air */ - if (options.type.level1 == 1) { - set = "01" - entity = "11" - if (options.type.level2 == 1) - entityType = "01" - else if (options.type.level2 == 1) - entityType = "02" - - if (options.type.level3 == 1) - entitySubtype = "04"; - else if (options.type.level3 == 2) - entitySubtype = "05"; - else if (options.type.level3 == 3) - entitySubtype = "04"; - else if (options.type.level3 == 4) - entitySubtype = "02"; - else if (options.type.level3 == 5) - entitySubtype = "00"; - else if (options.type.level3 == 6) - entitySubtype = "00"; - } - - /* Ground */ - else if (options.type.level1 == 2) - { - set = "10" - entity = "12" - entityType = "05" - } - /* Navy */ - else if (options.type.level1 == 3) - set = "30" - /* Weapon */ - else if (options.type.level1 == 4) - { - set = "02" - entity = "11" - if (options.type.level3 == 7) - { - sectorOneModifier = "01" - sectorTwoModifier = "01" - } - else if (options.type.level3 == 8) - { - sectorOneModifier = "01" - sectorTwoModifier = "02" - } - else if (options.type.level3 == 34) - { - sectorOneModifier = "02" - sectorTwoModifier = "01" - } - else if (options.type.level3 == 11) - { - sectorOneModifier = "02" - sectorTwoModifier = "02" - } - } - - return `10${identity}${set}0000${entity}${entityType}${entitySubtype}${sectorOneModifier}${sectorTwoModifier}` - } + getUnitImage() { + return new Image().src = "images/units/unit.png" + } } export class AirUnitMarker extends UnitMarker { @@ -242,9 +174,17 @@ export class AirUnitMarker extends UnitMarker { } export class AircraftMarker extends AirUnitMarker { + getUnitImage() + { + return new Image().src = "images/units/" + getAircrafImage(this.getName()); + } } export class HelicopterMarker extends AirUnitMarker { + getUnitImage() + { + return new Image().src = "images/units/airUnit.png" + } } export class GroundUnitMarker extends UnitMarker { @@ -264,6 +204,11 @@ export class GroundUnitMarker extends UnitMarker { else return "minimal"; } + + getUnitImage() + { + return new Image().src = "images/units/groundUnit.png" + } } export class NavyUnitMarker extends UnitMarker { @@ -282,6 +227,11 @@ export class NavyUnitMarker extends UnitMarker { else return "minimal"; } + + getUnitImage() + { + return new Image().src = "images/units/navyUnit.png" + } } export class WeaponMarker extends UnitMarker { @@ -300,4 +250,18 @@ export class WeaponMarker extends UnitMarker { else return "minimal"; } +} + +export class BombMarker extends WeaponMarker { + getUnitImage() + { + return new Image().src = "images/units/bomb.png" + } +} + +export class MissileMarker extends WeaponMarker { + getUnitImage() + { + return new Image().src = "images/units/missile.png" + } } \ No newline at end of file diff --git a/client/src/units/unitsmanager.ts b/client/src/units/unitsmanager.ts index fe6bec75..ea58ec74 100644 --- a/client/src/units/unitsmanager.ts +++ b/client/src/units/unitsmanager.ts @@ -37,7 +37,7 @@ export class UnitsManager { var options = { unitName: data.unitName, name: data.name, - human: data.human, + human: data.flags.Human, coalitionID: data.coalitionID, type: data.type, AI: data.AI @@ -298,12 +298,12 @@ export class UnitsManager { { if (selectedUnits[idx].isWingman) { - console.log(selectedUnits[idx].unitName + " is already in a formation."); + //console.log(selectedUnits[idx].unitName + " is already in a formation."); return; } else if (selectedUnits[idx].isLeader) { - console.log(selectedUnits[idx].unitName + " is already in a formation."); + //console.log(selectedUnits[idx].unitName + " is already in a formation."); return; } else @@ -326,7 +326,7 @@ export class UnitsManager { } else { - console.log("At least 2 units must be selected to create a formation."); + //console.log("At least 2 units must be selected to create a formation."); } } setTimeout(() => this.#updateUnitControlPanel(), 300); // TODO find better method, may fail diff --git a/client/views/index.ejs b/client/views/index.ejs index 0b89363c..0aa63c1a 100644 --- a/client/views/index.ejs +++ b/client/views/index.ejs @@ -37,6 +37,7 @@ <%- include( 'atc.ejs' ) %> + <%- include('logpanel.ejs') %> diff --git a/client/views/logpanel.ejs b/client/views/logpanel.ejs new file mode 100644 index 00000000..baccbec1 --- /dev/null +++ b/client/views/logpanel.ejs @@ -0,0 +1,3 @@ +
+ +
\ No newline at end of file diff --git a/client/views/mouseinfopanel.ejs b/client/views/mouseinfopanel.ejs index bfa98c02..3a798661 100644 --- a/client/views/mouseinfopanel.ejs +++ b/client/views/mouseinfopanel.ejs @@ -1,6 +1,6 @@
-
---° / --- NM
-
---° / --- NM
-
---° / --- NM
-
---° / --- NM
+
---° / --- NM
+
---° / --- NM
+
---° / --- NM
+
---° / --- NM
\ No newline at end of file diff --git a/client/views/unitcontrolpanel.ejs b/client/views/unitcontrolpanel.ejs index a8fa1a89..c9f5dd6e 100644 --- a/client/views/unitcontrolpanel.ejs +++ b/client/views/unitcontrolpanel.ejs @@ -1,24 +1,22 @@
-
-
-
-
-
-
- -
Selected units
+ + -
Controls
+
Controls
Altitude
@@ -32,34 +30,36 @@
-
Formation
-
-
Echelon
-
Fingertip
-
Trail
-
Line abreast
+ -
+
-
Rules of engagement
+
Rules of engagement
-
Free
-
Designated free
-
Designated
-
Return
-
Hold
+
Free
+
Designated free
+
Designated
+
Return
+
Hold
-
+
-
Reaction to threat
+
Reaction to threat
-
None
-
Passive
-
Evade
-
Escape
-
Abort
+
None
+
Passive
+
Evade
+
Escape
+
Abort
\ No newline at end of file diff --git a/client/views/unitinfopanel.ejs b/client/views/unitinfopanel.ejs index 345bbd77..578ef8b6 100644 --- a/client/views/unitinfopanel.ejs +++ b/client/views/unitinfopanel.ejs @@ -1,11 +1,11 @@
-
-
-
+
+
+
-
+
Flight data
@@ -20,7 +20,7 @@
Heading
-
+
Loadout
diff --git a/client/views/visibilitycontrolpanel.ejs b/client/views/visibilitycontrolpanel.ejs index 861028b9..fb9f747b 100644 --- a/client/views/visibilitycontrolpanel.ejs +++ b/client/views/visibilitycontrolpanel.ejs @@ -19,7 +19,7 @@
-
+
Full:
@@ -36,7 +36,7 @@
-
+
Olympus only:
diff --git a/img/icon.png b/img/icon.png new file mode 100644 index 00000000..d4b60c09 Binary files /dev/null and b/img/icon.png differ diff --git a/installer/DCSOlympus.iss b/installer/DCSOlympus.iss index 479b72a5..d017f71d 100644 --- a/installer/DCSOlympus.iss +++ b/installer/DCSOlympus.iss @@ -22,7 +22,7 @@ Source: "..\scripts\OlympusCommand.lua"; DestDir: "{app}\Mods\Services\Olympus\S Source: "..\scripts\unitPayloads.lua"; DestDir: "{app}\Mods\Services\Olympus\Scripts"; Flags: ignoreversion Source: "..\scripts\OlympusMission.lua"; DestDir: "{app}\Mods\Services\Olympus\Scripts"; Flags: ignoreversion Source: "..\scripts\mist_4_4_90.lua"; DestDir: "{app}\Mods\Services\Olympus\Scripts"; Flags: ignoreversion -Source: "..\mod\*.*"; DestDir: "{app}\Mods\Services\Olympus"; Flags: ignoreversion; +Source: "..\mod\*"; DestDir: "{app}\Mods\Services\Olympus"; Flags: ignoreversion recursesubdirs; Source: "..\bin\*.dll"; DestDir: "{app}\Mods\Services\Olympus\bin"; Flags: ignoreversion; Source: "..\client\bin\*"; DestDir: "{app}\Mods\Services\Olympus\client\bin"; Flags: ignoreversion; Source: "..\client\node_modules\*"; DestDir: "{app}\Mods\Services\Olympus\client\node_modules"; Flags: ignoreversion recursesubdirs; diff --git a/scripts/OlympusPatcher.exe b/scripts/OlympusPatcher.exe index ee35a74d..2c93d37e 100644 Binary files a/scripts/OlympusPatcher.exe and b/scripts/OlympusPatcher.exe differ diff --git a/scripts/OlympusPatcher.py b/scripts/OlympusPatcher.py index bcfc1ce1..1fb13784 100644 --- a/scripts/OlympusPatcher.py +++ b/scripts/OlympusPatcher.py @@ -1,8 +1,8 @@ import shutil import sys -START_STRING = "/* Olympus START */\n" -END_STRING = "/* Olympus END */\n" +START_STRING = "-- Olympus START\n" +END_STRING = "-- Olympus END\n" EXPORT_STRING = "local Olympuslfs=require('lfs');dofile(Olympuslfs.writedir()..'Scripts/OlympusExport.lua')\n" def main(flag): diff --git a/scripts/OlympusPatcher.spec b/scripts/OlympusPatcher.spec new file mode 100644 index 00000000..59ead9c4 --- /dev/null +++ b/scripts/OlympusPatcher.spec @@ -0,0 +1,44 @@ +# -*- mode: python ; coding: utf-8 -*- + + +block_cipher = None + + +a = Analysis( + ['OlympusPatcher.py'], + pathex=[], + binaries=[], + datas=[], + hiddenimports=[], + hookspath=[], + hooksconfig={}, + runtime_hooks=[], + excludes=[], + win_no_prefer_redirects=False, + win_private_assemblies=False, + cipher=block_cipher, + noarchive=False, +) +pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher) + +exe = EXE( + pyz, + a.scripts, + a.binaries, + a.zipfiles, + a.datas, + [], + name='OlympusPatcher', + debug=False, + bootloader_ignore_signals=False, + strip=False, + upx=True, + upx_exclude=[], + runtime_tmpdir=None, + console=True, + disable_windowed_traceback=False, + argv_emulation=False, + target_arch=None, + codesign_identity=None, + entitlements_file=None, +) diff --git a/src/core/core.vcxproj b/src/core/core.vcxproj index 781d4f5f..e3063bf5 100644 --- a/src/core/core.vcxproj +++ b/src/core/core.vcxproj @@ -43,7 +43,7 @@ - + @@ -58,7 +58,7 @@ - + diff --git a/src/core/core.vcxproj.filters b/src/core/core.vcxproj.filters index d0cc64a4..a50b8e11 100644 --- a/src/core/core.vcxproj.filters +++ b/src/core/core.vcxproj.filters @@ -39,7 +39,7 @@ Header Files - + Header Files @@ -80,7 +80,7 @@ Source Files - + Source Files diff --git a/src/core/include/server.h b/src/core/include/server.h index 39db7a60..1d87ccf2 100644 --- a/src/core/include/server.h +++ b/src/core/include/server.h @@ -5,7 +5,7 @@ using namespace web::http; using namespace web::http::experimental::listener; -class UnitsFactory; +class UnitsManager; class Scheduler; class Server diff --git a/src/core/include/unitsFactory.h b/src/core/include/unitsmanager.h similarity index 83% rename from src/core/include/unitsFactory.h rename to src/core/include/unitsmanager.h index 07b0d354..1864c8ad 100644 --- a/src/core/include/unitsFactory.h +++ b/src/core/include/unitsmanager.h @@ -4,11 +4,11 @@ class Unit; -class UnitsFactory +class UnitsManager { public: - UnitsFactory(lua_State* L); - ~UnitsFactory(); + UnitsManager(lua_State* L); + ~UnitsManager(); Unit* getUnit(int ID); void updateExportData(lua_State* L); diff --git a/src/core/src/Scheduler.cpp b/src/core/src/Scheduler.cpp index d855dbfa..390569e8 100644 --- a/src/core/src/Scheduler.cpp +++ b/src/core/src/Scheduler.cpp @@ -1,11 +1,11 @@ #include "scheduler.h" #include "logger.h" #include "dcstools.h" -#include "unitsFactory.h" +#include "unitsManager.h" #include "utils.h" #include "unit.h" -extern UnitsFactory* unitsFactory; +extern UnitsManager* unitsManager; Scheduler::Scheduler(lua_State* L) { @@ -36,9 +36,6 @@ void Scheduler::execute(lua_State* L) { log(L"Error executing command " + commandString); } - { - log(L"Command " + commandString + L" executed succesfully"); - } commands.remove(command); return; } @@ -55,7 +52,7 @@ void Scheduler::handleRequest(wstring key, json::value value) if (key.compare(L"setPath") == 0) { int ID = value[L"ID"].as_integer(); - Unit* unit = unitsFactory->getUnit(ID); + Unit* unit = unitsManager->getUnit(ID); if (unit != nullptr) { wstring unitName = unit->getUnitName(); @@ -71,7 +68,7 @@ void Scheduler::handleRequest(wstring key, json::value value) newPath.push_back(dest); } - Unit* unit = unitsFactory->getUnit(ID); + Unit* unit = unitsManager->getUnit(ID); if (unit != nullptr) { unit->setPath(newPath); @@ -118,8 +115,8 @@ void Scheduler::handleRequest(wstring key, json::value value) int ID = value[L"ID"].as_integer(); int targetID = value[L"targetID"].as_integer(); - Unit* unit = unitsFactory->getUnit(ID); - Unit* target = unitsFactory->getUnit(targetID); + Unit* unit = unitsManager->getUnit(ID); + Unit* target = unitsManager->getUnit(targetID); wstring unitName; wstring targetName; @@ -141,7 +138,7 @@ void Scheduler::handleRequest(wstring key, json::value value) else if (key.compare(L"stopAttack") == 0) { int ID = value[L"ID"].as_integer(); - Unit* unit = unitsFactory->getUnit(ID); + Unit* unit = unitsManager->getUnit(ID); if (unit != nullptr) unit->setState(State::REACH_DESTINATION); else @@ -150,28 +147,28 @@ void Scheduler::handleRequest(wstring key, json::value value) else if (key.compare(L"changeSpeed") == 0) { int ID = value[L"ID"].as_integer(); - Unit* unit = unitsFactory->getUnit(ID); + Unit* unit = unitsManager->getUnit(ID); if (unit != nullptr) unit->changeSpeed(value[L"change"].as_string()); } else if (key.compare(L"changeAltitude") == 0) { int ID = value[L"ID"].as_integer(); - Unit* unit = unitsFactory->getUnit(ID); + Unit* unit = unitsManager->getUnit(ID); if (unit != nullptr) unit->changeAltitude(value[L"change"].as_string()); } else if (key.compare(L"setSpeed") == 0) { int ID = value[L"ID"].as_integer(); - Unit* unit = unitsFactory->getUnit(ID); + Unit* unit = unitsManager->getUnit(ID); if (unit != nullptr) unit->setTargetSpeed(value[L"speed"].as_double()); } else if (key.compare(L"setAltitude") == 0) { int ID = value[L"ID"].as_integer(); - Unit* unit = unitsFactory->getUnit(ID); + Unit* unit = unitsManager->getUnit(ID); if (unit != nullptr) unit->setTargetAltitude(value[L"altitude"].as_double()); } @@ -187,7 +184,7 @@ void Scheduler::handleRequest(wstring key, json::value value) else if (key.compare(L"setLeader") == 0) { int ID = value[L"ID"].as_integer(); - Unit* unit = unitsFactory->getUnit(ID); + Unit* unit = unitsManager->getUnit(ID); bool isLeader = value[L"isLeader"].as_bool(); if (isLeader) { @@ -197,7 +194,7 @@ void Scheduler::handleRequest(wstring key, json::value value) { for (auto itr = wingmenIDs.as_array().begin(); itr != wingmenIDs.as_array().end(); itr++) { - Unit* wingman = unitsFactory->getUnit(itr->as_integer()); + Unit* wingman = unitsManager->getUnit(itr->as_integer()); if (wingman != nullptr) wingmen.push_back(wingman); } @@ -214,28 +211,28 @@ void Scheduler::handleRequest(wstring key, json::value value) else if (key.compare(L"setFormation") == 0) { int ID = value[L"ID"].as_integer(); - Unit* unit = unitsFactory->getUnit(ID); + Unit* unit = unitsManager->getUnit(ID); wstring formation = value[L"formation"].as_string(); unit->setFormation(formation); } else if (key.compare(L"setROE") == 0) { int ID = value[L"ID"].as_integer(); - Unit* unit = unitsFactory->getUnit(ID); + Unit* unit = unitsManager->getUnit(ID); wstring ROE = value[L"ROE"].as_string(); unit->setROE(ROE); } else if (key.compare(L"setReactionToThreat") == 0) { int ID = value[L"ID"].as_integer(); - Unit* unit = unitsFactory->getUnit(ID); + Unit* unit = unitsManager->getUnit(ID); wstring reactionToThreat = value[L"reactionToThreat"].as_string(); unit->setReactionToThreat(reactionToThreat); } else if (key.compare(L"landAt") == 0) { int ID = value[L"ID"].as_integer(); - Unit* unit = unitsFactory->getUnit(ID); + Unit* unit = unitsManager->getUnit(ID); double lat = value[L"location"][L"lat"].as_double(); double lng = value[L"location"][L"lng"].as_double(); Coords loc; loc.lat = lat; loc.lng = lng; @@ -244,7 +241,7 @@ void Scheduler::handleRequest(wstring key, json::value value) else if (key.compare(L"deleteUnit") == 0) { int ID = value[L"ID"].as_integer(); - unitsFactory->deleteUnit(ID); + unitsManager->deleteUnit(ID); } else { diff --git a/src/core/src/Unit.cpp b/src/core/src/Unit.cpp index 5b814869..298da092 100644 --- a/src/core/src/Unit.cpp +++ b/src/core/src/Unit.cpp @@ -4,13 +4,13 @@ #include "commands.h" #include "scheduler.h" #include "defines.h" -#include "unitsFactory.h" +#include "unitsManager.h" #include using namespace GeographicLib; extern Scheduler* scheduler; -extern UnitsFactory* unitsFactory; +extern UnitsManager* unitsManager; Unit::Unit(json::value json, int ID) : ID(ID) @@ -159,7 +159,7 @@ wstring Unit::getTarget() { if (isTargetAlive()) { - Unit* target = unitsFactory->getUnit(targetID); + Unit* target = unitsManager->getUnit(targetID); if (target != nullptr) return target->getUnitName(); } @@ -171,7 +171,7 @@ bool Unit::isTargetAlive() if (targetID == NULL) return false; - Unit* target = unitsFactory->getUnit(targetID); + Unit* target = unitsManager->getUnit(targetID); if (target != nullptr) return target->alive; else diff --git a/src/core/src/aircraft.cpp b/src/core/src/aircraft.cpp index b50d8abf..ae4f9dac 100644 --- a/src/core/src/aircraft.cpp +++ b/src/core/src/aircraft.cpp @@ -4,13 +4,13 @@ #include "commands.h" #include "scheduler.h" #include "defines.h" -#include "unitsFactory.h" +#include "unitsManager.h" #include using namespace GeographicLib; extern Scheduler* scheduler; -extern UnitsFactory* unitsFactory; +extern UnitsManager* unitsManager; /* Aircraft */ Aircraft::Aircraft(json::value json, int ID) : AirUnit(json, ID) diff --git a/src/core/src/airunit.cpp b/src/core/src/airunit.cpp index cb7ac8db..376b7a6d 100644 --- a/src/core/src/airunit.cpp +++ b/src/core/src/airunit.cpp @@ -4,13 +4,13 @@ #include "commands.h" #include "scheduler.h" #include "defines.h" -#include "unitsFactory.h" +#include "unitsManager.h" #include using namespace GeographicLib; extern Scheduler* scheduler; -extern UnitsFactory* unitsFactory; +extern UnitsManager* unitsManager; /* Air unit */ AirUnit::AirUnit(json::value json, int ID) : Unit(json, ID) @@ -59,7 +59,7 @@ void AirUnit::setState(int newState) } case State::ATTACK: { if (isTargetAlive()) { - Unit* target = unitsFactory->getUnit(targetID); + Unit* target = unitsManager->getUnit(targetID); Coords targetPosition = Coords(target->getLatitude(), target->getLongitude(), 0); activePath.clear(); activePath.push_front(targetPosition); diff --git a/src/core/src/core.cpp b/src/core/src/core.cpp index cd2740e1..5bc61a81 100644 --- a/src/core/src/core.cpp +++ b/src/core/src/core.cpp @@ -1,14 +1,14 @@ #include "dcstools.h" #include "logger.h" #include "defines.h" -#include "unitsFactory.h" +#include "unitsManager.h" #include "server.h" #include "scheduler.h" #include "scriptLoader.h" #include "luatools.h" auto before = std::chrono::system_clock::now(); -UnitsFactory* unitsFactory = nullptr; +UnitsManager* unitsManager = nullptr; Server* server = nullptr; Scheduler* scheduler = nullptr; json::value airbasesData; @@ -24,7 +24,7 @@ extern "C" DllExport int coreDeinit(lua_State* L) log("Olympus coreDeinit called successfully"); - delete unitsFactory; + delete unitsManager; delete server; delete scheduler; @@ -36,7 +36,7 @@ extern "C" DllExport int coreDeinit(lua_State* L) /* Called when DCS simulation starts. All singletons are instantiated, and the custom Lua functions are registered in the Lua state. */ extern "C" DllExport int coreInit(lua_State* L) { - unitsFactory = new UnitsFactory(L); + unitsManager = new UnitsManager(L); server = new Server(L); scheduler = new Scheduler(L); @@ -59,9 +59,9 @@ extern "C" DllExport int coreFrame(lua_State* L) // TODO make intervals editable if (duration.count() > UPDATE_TIME_INTERVAL) { - if (unitsFactory != nullptr) + if (unitsManager != nullptr) { - unitsFactory->updateExportData(L); + unitsManager->updateExportData(L); } // TODO allow for different intervals @@ -87,7 +87,7 @@ extern "C" DllExport int coreMissionData(lua_State * L) json::value missionData = luaTableToJSON(L, -1); if (missionData.has_object_field(L"unitsData")) - unitsFactory->updateMissionData(missionData[L"unitsData"]); + unitsManager->updateMissionData(missionData[L"unitsData"]); if (missionData.has_object_field(L"airbases")) airbasesData = missionData[L"airbases"]; if (missionData.has_object_field(L"bullseye")) diff --git a/src/core/src/groundunit.cpp b/src/core/src/groundunit.cpp index 463843d0..3020da5a 100644 --- a/src/core/src/groundunit.cpp +++ b/src/core/src/groundunit.cpp @@ -4,13 +4,13 @@ #include "commands.h" #include "scheduler.h" #include "defines.h" -#include "unitsFactory.h" +#include "unitsManager.h" #include using namespace GeographicLib; extern Scheduler* scheduler; -extern UnitsFactory* unitsFactory; +extern UnitsManager* unitsManager; /* Ground unit */ GroundUnit::GroundUnit(json::value json, int ID) : Unit(json, ID) diff --git a/src/core/src/helicopter.cpp b/src/core/src/helicopter.cpp index 7350e659..f7f59ccc 100644 --- a/src/core/src/helicopter.cpp +++ b/src/core/src/helicopter.cpp @@ -4,13 +4,13 @@ #include "commands.h" #include "scheduler.h" #include "defines.h" -#include "unitsFactory.h" +#include "unitsManager.h" #include using namespace GeographicLib; extern Scheduler* scheduler; -extern UnitsFactory* unitsFactory; +extern UnitsManager* unitsManager; /* Helicopter */ Helicopter::Helicopter(json::value json, int ID) : AirUnit(json, ID) diff --git a/src/core/src/navyunit.cpp b/src/core/src/navyunit.cpp index e9491d43..0a9c22c8 100644 --- a/src/core/src/navyunit.cpp +++ b/src/core/src/navyunit.cpp @@ -4,13 +4,13 @@ #include "commands.h" #include "scheduler.h" #include "defines.h" -#include "unitsFactory.h" +#include "unitsManager.h" #include using namespace GeographicLib; extern Scheduler* scheduler; -extern UnitsFactory* unitsFactory; +extern UnitsManager* unitsManager; /* Navy Unit */ NavyUnit::NavyUnit(json::value json, int ID) : Unit(json, ID) diff --git a/src/core/src/server.cpp b/src/core/src/server.cpp index a33e4eab..670daea5 100644 --- a/src/core/src/server.cpp +++ b/src/core/src/server.cpp @@ -1,13 +1,13 @@ #include "server.h" #include "logger.h" #include "defines.h" -#include "unitsFactory.h" +#include "unitsManager.h" #include "scheduler.h" #include "luatools.h" #include #include -extern UnitsFactory* unitsFactory; +extern UnitsManager* unitsManager; extern Scheduler* scheduler; extern json::value airbasesData; extern json::value bullseyeData; @@ -62,9 +62,15 @@ void Server::handle_get(http_request request) auto answer = json::value::object(); std::exception_ptr eptr; try { - unitsFactory->updateAnswer(answer); + unitsManager->updateAnswer(answer); answer[L"airbases"] = airbasesData; answer[L"bullseye"] = bullseyeData; + answer[L"logs"] = json::value::object(); + + int i = 0; + for (auto log : getLogs()) + answer[L"logs"][to_wstring(i++)] = json::value::string(to_wstring(log)); + response.set_body(answer); } catch (...) { diff --git a/src/core/src/unitsFactory.cpp b/src/core/src/unitsmanager.cpp similarity index 88% rename from src/core/src/unitsFactory.cpp rename to src/core/src/unitsmanager.cpp index 6a3104bf..d3aca042 100644 --- a/src/core/src/unitsFactory.cpp +++ b/src/core/src/unitsmanager.cpp @@ -1,5 +1,5 @@ #include "framework.h" -#include "unitsFactory.h" +#include "unitsManager.h" #include "logger.h" #include "unit.h" #include "aircraft.h" @@ -12,17 +12,17 @@ extern Scheduler* scheduler; -UnitsFactory::UnitsFactory(lua_State* L) +UnitsManager::UnitsManager(lua_State* L) { LogInfo(L, "Units Factory constructor called successfully"); } -UnitsFactory::~UnitsFactory() +UnitsManager::~UnitsManager() { } -Unit* UnitsFactory::getUnit(int ID) +Unit* UnitsManager::getUnit(int ID) { if (units.find(ID) == units.end()) { return nullptr; @@ -32,7 +32,7 @@ Unit* UnitsFactory::getUnit(int ID) } } -void UnitsFactory::updateExportData(lua_State* L) +void UnitsManager::updateExportData(lua_State* L) { map unitJSONs = getAllUnits(L); @@ -94,7 +94,7 @@ void UnitsFactory::updateExportData(lua_State* L) } } -void UnitsFactory::updateMissionData(json::value missionData) +void UnitsManager::updateMissionData(json::value missionData) { /* Update all units */ for (auto const& p : units) @@ -107,7 +107,7 @@ void UnitsFactory::updateMissionData(json::value missionData) } } -void UnitsFactory::updateAnswer(json::value& answer) +void UnitsManager::updateAnswer(json::value& answer) { // TODO THREAT SAFEY! auto unitsJson = json::value::object(); @@ -120,7 +120,7 @@ void UnitsFactory::updateAnswer(json::value& answer) answer[L"units"] = unitsJson; } -void UnitsFactory::deleteUnit(int ID) +void UnitsManager::deleteUnit(int ID) { if (getUnit(ID) != nullptr) { diff --git a/src/core/src/weapon.cpp b/src/core/src/weapon.cpp index 4025bb82..5907a9a9 100644 --- a/src/core/src/weapon.cpp +++ b/src/core/src/weapon.cpp @@ -4,13 +4,13 @@ #include "commands.h" #include "scheduler.h" #include "defines.h" -#include "unitsFactory.h" +#include "unitsmanager.h" #include using namespace GeographicLib; extern Scheduler* scheduler; -extern UnitsFactory* unitsFactory; +extern UnitsManager* unitsManager; /* Weapon */ Weapon::Weapon(json::value json, int ID) : Unit(json, ID) diff --git a/src/logger/include/interface.h b/src/logger/include/interface.h index f28155c5..f0ef79bc 100644 --- a/src/logger/include/interface.h +++ b/src/logger/include/interface.h @@ -3,3 +3,4 @@ void DllExport log(const std::string& sMessage); void DllExport log(const std::wstring& sMessage); +std::list DllExport getLogs(); diff --git a/src/logger/include/logger.h b/src/logger/include/logger.h index 1db3336d..96c126fb 100644 --- a/src/logger/include/logger.h +++ b/src/logger/include/logger.h @@ -7,6 +7,7 @@ class Logger public: void Log(const string& sMessage); void Log(const wstring& sMessage); + std::list getLogs() { return m_logs; }; static Logger* GetLogger(); private: @@ -17,6 +18,7 @@ private: static const string m_sFileName; static Logger* m_pThis; static ofstream m_Logfile; + static std::list m_logs; void Open(); void Close(); diff --git a/src/logger/src/interface.cpp b/src/logger/src/interface.cpp index 4589e508..5f1e714c 100644 --- a/src/logger/src/interface.cpp +++ b/src/logger/src/interface.cpp @@ -12,4 +12,9 @@ void log(const string& message) void log(const wstring& message) { LOGGER->Log(message); +} + +std::list getLogs() +{ + return LOGGER->getLogs(); } \ No newline at end of file diff --git a/src/logger/src/logger.cpp b/src/logger/src/logger.cpp index ef8d0981..5e286104 100644 --- a/src/logger/src/logger.cpp +++ b/src/logger/src/logger.cpp @@ -5,6 +5,7 @@ const string Logger::m_sFileName = LOG_NAME; Logger* Logger::m_pThis = NULL; ofstream Logger::m_Logfile; +std::list Logger::m_logs; Logger::Logger() { @@ -37,6 +38,7 @@ void Logger::Log(const string& message) Open(); m_Logfile << CurrentDateTime() << ":\t"; m_Logfile << message << "\n"; + m_logs.push_back(CurrentDateTime() + ": " + message); Close(); } @@ -45,5 +47,6 @@ void Logger::Log(const wstring& message) Open(); m_Logfile << CurrentDateTime() << ":\t"; m_Logfile << to_string(message) << "\n"; + m_logs.push_back(CurrentDateTime() + ": " + to_string(message)); Close(); }