diff --git a/gci-radar/Models/gci-tower.ac b/gci-radar/Models/gci-tower.ac new file mode 100644 index 0000000..a1fcafc --- /dev/null +++ b/gci-radar/Models/gci-tower.ac @@ -0,0 +1,2173 @@ +AC3Db +MATERIAL "base" rgb 0.800 0.507 0.327 amb 1.000 1.000 1.000 emis 0.000 0.000 0.000 spec 0.500 0.467 0.481 shi 14 trans 0.000 +MATERIAL "sphere" rgb 0.982 1.000 0.907 amb 1.000 1.000 1.000 emis 0.000 0.000 0.000 spec 0.500 0.500 0.500 shi 67 trans 0.000 +OBJECT world +name "Blender_exporter_v2.25__gci-tower.ac" +kids 2 +OBJECT poly +name "Cylinder" +data 8 +Cylinder +crease 30.0 +numvert 90 +0 -0.78813 -16.62572 +0 9.96837 -16.62572 +5.68633 -0.78813 -15.62307 +5.68633 9.96837 -15.62307 +10.68681 -0.78813 -12.73604 +10.68681 9.96837 -12.73604 +14.3983 -0.78813 -8.31286 +14.3983 9.96837 -8.31286 +16.37314 -0.78813 -2.88702 +16.37314 9.96837 -2.88702 +16.37314 -0.78813 2.88703 +16.37314 9.96837 2.88703 +14.3983 -0.78813 8.31286 +14.3983 9.96837 8.31286 +10.68681 -0.78813 12.73604 +10.68681 9.96837 12.73604 +5.68633 -0.78813 15.62307 +5.68633 9.96837 15.62307 +0 -0.78813 16.62572 +0 9.96837 16.62572 +-5.68633 -0.78813 15.62307 +-5.68633 9.96837 15.62307 +-10.6868 -0.78813 12.73604 +-10.6868 9.96837 12.73604 +-14.39829 -0.78813 8.31287 +-14.39829 9.96837 8.31287 +-16.37314 -0.78813 2.88703 +-16.37314 9.96837 2.88703 +-16.37314 -0.78813 -2.88702 +-16.37314 9.96837 -2.88702 +-14.3983 -0.78813 -8.31285 +-14.3983 9.96837 -8.31285 +-10.68682 -0.78813 -12.73603 +-10.68682 9.96837 -12.73603 +-5.68634 -0.78813 -15.62306 +-5.68634 9.96837 -15.62306 +0 11.56955 -18.90299 +6.46521 11.56955 -17.763 +12.15061 11.56955 -14.48053 +16.37047 11.56955 -9.4515 +18.61581 11.56955 -3.28247 +18.61581 11.56955 3.28247 +16.37047 11.56955 9.4515 +12.15061 11.56955 14.48053 +6.46521 11.56955 17.763 +0 11.56955 18.90299 +-6.4652 11.56955 17.76301 +-12.15061 11.56955 14.48054 +-16.37047 11.56955 9.4515 +-18.61581 11.56955 3.28248 +-18.61582 11.56955 -3.28246 +-16.37048 11.56955 -9.45149 +-12.15062 11.56955 -14.48053 +-6.46522 11.56955 -17.763 +0 11.56955 -16.61378 +5.68225 11.56955 -15.61184 +10.67913 11.56955 -12.72689 +14.38795 11.56955 -8.30689 +16.36137 11.56955 -2.88495 +14.38795 11.56955 8.30689 +10.67913 11.56955 12.72689 +5.68225 11.56955 15.61184 +-5.68224 11.56955 15.61185 +-10.67913 11.56955 12.72689 +-14.38795 11.56955 8.30689 +-16.36138 11.56955 2.88496 +-16.36138 11.56955 -2.88494 +-14.38796 11.56955 -8.30688 +-10.67914 11.56955 -12.72688 +-5.68226 11.56955 -15.61184 +14.3983 14.11183 8.31286 +-5.68633 14.11183 15.62307 +-16.37314 14.11183 2.88703 +-5.68634 14.11183 -15.62306 +14.3983 14.11183 -8.31286 +10.68681 14.11183 12.73604 +5.68633 14.11183 15.62307 +0 14.11183 16.62572 +16.37314 14.11183 -2.88702 +16.37314 14.11183 2.88703 +-10.6868 14.11183 12.73604 +-14.39829 14.11183 8.31287 +-16.37314 14.11183 -2.88702 +-14.3983 14.11183 -8.31285 +-10.68682 14.11183 -12.73603 +0 14.11183 -16.62572 +5.68633 14.11183 -15.62307 +10.68681 14.11183 -12.73604 +0 11.57222 16.62572 +16.37314 11.57222 2.88703 +numsurf 72 +SURF 0X10 +mat 0 +refs 4 +0 0 0 +1 0 0 +3 0 0 +2 0 0 +SURF 0X10 +mat 0 +refs 4 +2 0 0 +3 0 0 +5 0 0 +4 0 0 +SURF 0X10 +mat 0 +refs 4 +4 0 0 +5 0 0 +7 0 0 +6 0 0 +SURF 0X10 +mat 0 +refs 4 +6 0 0 +7 0 0 +9 0 0 +8 0 0 +SURF 0X10 +mat 0 +refs 4 +8 0 0 +9 0 0 +11 0 0 +10 0 0 +SURF 0X10 +mat 0 +refs 4 +10 0 0 +11 0 0 +13 0 0 +12 0 0 +SURF 0X10 +mat 0 +refs 4 +12 0 0 +13 0 0 +15 0 0 +14 0 0 +SURF 0X10 +mat 0 +refs 4 +14 0 0 +15 0 0 +17 0 0 +16 0 0 +SURF 0X10 +mat 0 +refs 4 +16 0 0 +17 0 0 +19 0 0 +18 0 0 +SURF 0X10 +mat 0 +refs 4 +18 0 0 +19 0 0 +21 0 0 +20 0 0 +SURF 0X10 +mat 0 +refs 4 +20 0 0 +21 0 0 +23 0 0 +22 0 0 +SURF 0X10 +mat 0 +refs 4 +22 0 0 +23 0 0 +25 0 0 +24 0 0 +SURF 0X10 +mat 0 +refs 4 +24 0 0 +25 0 0 +27 0 0 +26 0 0 +SURF 0X10 +mat 0 +refs 4 +26 0 0 +27 0 0 +29 0 0 +28 0 0 +SURF 0X10 +mat 0 +refs 4 +28 0 0 +29 0 0 +31 0 0 +30 0 0 +SURF 0X10 +mat 0 +refs 4 +30 0 0 +31 0 0 +33 0 0 +32 0 0 +SURF 0X10 +mat 0 +refs 4 +9 0 0 +7 0 0 +39 0 0 +40 0 0 +SURF 0X10 +mat 0 +refs 4 +32 0 0 +33 0 0 +35 0 0 +34 0 0 +SURF 0X10 +mat 0 +refs 4 +34 0 0 +35 0 0 +1 0 0 +0 0 0 +SURF 0X10 +mat 0 +refs 4 +19 0 0 +17 0 0 +44 0 0 +45 0 0 +SURF 0X10 +mat 0 +refs 4 +29 0 0 +27 0 0 +49 0 0 +50 0 0 +SURF 0X10 +mat 0 +refs 4 +5 0 0 +3 0 0 +37 0 0 +38 0 0 +SURF 0X10 +mat 0 +refs 4 +15 0 0 +13 0 0 +42 0 0 +43 0 0 +SURF 0X10 +mat 0 +refs 4 +25 0 0 +23 0 0 +47 0 0 +48 0 0 +SURF 0X10 +mat 0 +refs 4 +35 0 0 +33 0 0 +52 0 0 +53 0 0 +SURF 0X10 +mat 0 +refs 4 +11 0 0 +9 0 0 +40 0 0 +41 0 0 +SURF 0X10 +mat 0 +refs 4 +21 0 0 +19 0 0 +45 0 0 +46 0 0 +SURF 0X10 +mat 0 +refs 4 +31 0 0 +29 0 0 +50 0 0 +51 0 0 +SURF 0X10 +mat 0 +refs 4 +7 0 0 +5 0 0 +38 0 0 +39 0 0 +SURF 0X10 +mat 0 +refs 4 +17 0 0 +15 0 0 +43 0 0 +44 0 0 +SURF 0X10 +mat 0 +refs 4 +3 0 0 +1 0 0 +36 0 0 +37 0 0 +SURF 0X10 +mat 0 +refs 4 +27 0 0 +25 0 0 +48 0 0 +49 0 0 +SURF 0X10 +mat 0 +refs 4 +1 0 0 +35 0 0 +53 0 0 +36 0 0 +SURF 0X10 +mat 0 +refs 4 +13 0 0 +11 0 0 +41 0 0 +42 0 0 +SURF 0X10 +mat 0 +refs 4 +23 0 0 +21 0 0 +46 0 0 +47 0 0 +SURF 0X10 +mat 0 +refs 4 +33 0 0 +31 0 0 +51 0 0 +52 0 0 +SURF 0X10 +mat 0 +refs 4 +38 0 0 +37 0 0 +55 0 0 +56 0 0 +SURF 0X10 +mat 0 +refs 4 +53 0 0 +52 0 0 +68 0 0 +69 0 0 +SURF 0X10 +mat 0 +refs 4 +46 0 0 +45 0 0 +88 0 0 +62 0 0 +SURF 0X10 +mat 0 +refs 4 +39 0 0 +38 0 0 +56 0 0 +57 0 0 +SURF 0X10 +mat 0 +refs 4 +36 0 0 +53 0 0 +69 0 0 +54 0 0 +SURF 0X10 +mat 0 +refs 4 +47 0 0 +46 0 0 +62 0 0 +63 0 0 +SURF 0X10 +mat 0 +refs 4 +40 0 0 +39 0 0 +57 0 0 +58 0 0 +SURF 0X10 +mat 0 +refs 4 +48 0 0 +47 0 0 +63 0 0 +64 0 0 +SURF 0X10 +mat 0 +refs 4 +41 0 0 +40 0 0 +58 0 0 +89 0 0 +SURF 0X10 +mat 0 +refs 4 +49 0 0 +48 0 0 +64 0 0 +65 0 0 +SURF 0X10 +mat 0 +refs 4 +42 0 0 +41 0 0 +89 0 0 +59 0 0 +SURF 0X10 +mat 0 +refs 4 +50 0 0 +49 0 0 +65 0 0 +66 0 0 +SURF 0X10 +mat 0 +refs 4 +43 0 0 +42 0 0 +59 0 0 +60 0 0 +SURF 0X10 +mat 0 +refs 4 +51 0 0 +50 0 0 +66 0 0 +67 0 0 +SURF 0X10 +mat 0 +refs 4 +44 0 0 +43 0 0 +60 0 0 +61 0 0 +SURF 0X10 +mat 0 +refs 4 +37 0 0 +36 0 0 +54 0 0 +55 0 0 +SURF 0X10 +mat 0 +refs 4 +52 0 0 +51 0 0 +67 0 0 +68 0 0 +SURF 0X10 +mat 0 +refs 4 +45 0 0 +44 0 0 +61 0 0 +88 0 0 +SURF 0X10 +mat 0 +refs 4 +70 0 0 +75 0 0 +60 0 0 +59 0 0 +SURF 0X10 +mat 0 +refs 4 +82 0 0 +83 0 0 +67 0 0 +66 0 0 +SURF 0X10 +mat 0 +refs 4 +75 0 0 +76 0 0 +61 0 0 +60 0 0 +SURF 0X10 +mat 0 +refs 4 +83 0 0 +84 0 0 +68 0 0 +67 0 0 +SURF 0X10 +mat 0 +refs 4 +76 0 0 +77 0 0 +88 0 0 +61 0 0 +SURF 0X10 +mat 0 +refs 4 +73 0 0 +85 0 0 +54 0 0 +69 0 0 +SURF 0X10 +mat 0 +refs 4 +74 0 0 +78 0 0 +58 0 0 +57 0 0 +SURF 0X10 +mat 0 +refs 4 +85 0 0 +86 0 0 +55 0 0 +54 0 0 +SURF 0X10 +mat 0 +refs 4 +78 0 0 +79 0 0 +89 0 0 +58 0 0 +SURF 0X10 +mat 0 +refs 4 +77 0 0 +71 0 0 +62 0 0 +88 0 0 +SURF 0X10 +mat 0 +refs 4 +86 0 0 +87 0 0 +56 0 0 +55 0 0 +SURF 0X10 +mat 0 +refs 4 +71 0 0 +80 0 0 +63 0 0 +62 0 0 +SURF 0X10 +mat 0 +refs 4 +84 0 0 +73 0 0 +69 0 0 +68 0 0 +SURF 0X10 +mat 0 +refs 4 +81 0 0 +72 0 0 +65 0 0 +64 0 0 +SURF 0X10 +mat 0 +refs 4 +80 0 0 +81 0 0 +64 0 0 +63 0 0 +SURF 0X10 +mat 0 +refs 4 +87 0 0 +74 0 0 +57 0 0 +56 0 0 +SURF 0X10 +mat 0 +refs 4 +79 0 0 +70 0 0 +59 0 0 +89 0 0 +SURF 0X10 +mat 0 +refs 4 +72 0 0 +82 0 0 +66 0 0 +65 0 0 +kids 0 +OBJECT poly +name "Icosphere" +data 13 +Icosphere.001 +crease 40.0 +numvert 129 +14.3983 14.11183 8.31286 +-5.68633 14.11183 15.62307 +-16.37314 14.11183 2.88703 +-5.68634 14.11183 -15.62306 +14.3983 14.11183 -8.31286 +5.52776 33.95286 17.01298 +-14.47215 33.95285 10.51451 +-14.47215 33.95285 -10.51451 +5.52776 33.95286 -17.01298 +17.88852 33.95277 0 +0 45.00846 0 +10.68681 14.11183 12.73604 +5.68633 14.11183 15.62307 +0 14.11183 16.62572 +16.37314 14.11183 -2.88702 +16.37314 14.11183 2.88703 +-10.6868 14.11183 12.73604 +-14.39829 14.11183 8.31287 +-16.37314 14.11183 -2.88702 +-14.3983 14.11183 -8.31285 +-10.68682 14.11183 -12.73603 +0 14.11183 -16.62572 +5.68633 14.11183 -15.62307 +10.68681 14.11183 -12.73604 +19.13251 30.03145 2.95237 +19.02116 25.00846 6.18025 +17.21395 19.98545 8.85715 +17.21395 19.98545 -8.85715 +19.02116 25.00846 -6.18025 +19.13251 30.03145 -2.95237 +3.1043 30.03149 19.10844 +0 25.00846 20 +-3.1043 19.98543 19.10844 +13.74317 19.98542 13.63431 +11.75571 25.00846 16.18034 +8.72014 30.0315 17.28376 +-17.21395 30.03148 8.85715 +-19.02116 25.00846 6.18025 +-19.13251 19.98547 2.95237 +-8.72014 19.98542 17.28376 +-11.75571 25.00846 16.18033 +-13.74317 30.0315 13.63431 +-13.74317 30.0315 -13.63431 +-11.75571 25.00846 -16.18034 +-8.72014 19.98542 -17.28376 +-19.13251 19.98547 -2.95237 +-19.02116 25.00846 -6.18025 +-17.21395 30.03148 -8.85715 +8.72014 30.03151 -17.28376 +11.75571 25.00846 -16.18033 +13.74317 19.98542 -13.63431 +-3.1043 19.98543 -19.10844 +0 25.00846 -20 +3.1043 30.03149 -19.10844 +16.62101 35.05444 4.77707 +13.76379 35.52319 9.99994 +9.67943 35.0545 14.33129 +0.59278 35.0545 17.28368 +-5.25738 35.52322 16.18023 +-10.63882 35.0545 13.63425 +-16.25458 35.05447 5.90475 +-17.01296 35.52318 0 +-16.25458 35.05447 -5.90475 +-10.63882 35.0545 -13.63425 +-5.25738 35.52322 -16.18023 +0.59279 35.0545 -17.28368 +9.67943 35.0545 -14.33129 +13.76379 35.52319 -9.99994 +16.62101 35.05444 -4.77707 +1.55213 44.36746 4.77706 +3.24911 42.02155 9.99991 +4.65643 38.15884 14.33126 +15.06883 38.15876 0 +10.5146 42.02149 0 +5.02294 44.36744 0 +-4.06362 44.36745 2.95236 +-8.50645 42.02155 6.18023 +-12.19093 38.15884 8.85713 +-4.06362 44.36745 -2.95236 +-8.50645 42.02155 -6.18023 +-12.19093 38.15884 -8.85713 +1.55213 44.36746 -4.77706 +3.24911 42.02155 -9.99991 +4.65643 38.15884 -14.33126 +7.23601 42.89705 -5.25726 +12.76387 39.48067 -5.25728 +8.94418 39.4807 -10.51456 +-2.76395 42.89706 -8.50639 +-1.05579 39.48071 -13.7637 +-7.23607 39.48071 -11.75557 +-8.9442 42.89704 0 +-13.41633 39.48068 -3.24914 +-13.41633 39.48068 3.24914 +-2.76395 42.89706 8.50639 +-7.23607 39.48071 11.75557 +-1.05579 39.48071 13.7637 +7.23601 42.89705 5.25726 +8.94418 39.4807 10.51456 +12.76387 39.48066 5.25728 +17.23609 30.53639 -8.50644 +16.18039 25.00846 -11.75564 +13.41641 30.53641 -13.76378 +-2.76397 30.5364 -19.0211 +-6.18033 25.00845 -19.02113 +-8.9443 30.53641 -17.01297 +-18.94426 30.53638 -3.24915 +-20 25.00848 0.00001 +-18.94426 30.53639 3.24916 +-8.94432 30.5364 17.01297 +-6.18034 25.00845 19.02113 +-2.76399 30.5364 19.0211 +13.41641 30.53638 13.7638 +16.18037 25.00842 11.75566 +17.23608 30.53635 8.50646 +6.18034 25.00846 -19.02113 +8.94431 19.48051 -17.01297 +2.76398 19.48051 -19.0211 +-16.18037 25.00846 -11.75566 +-13.41638 19.48052 -13.76381 +-17.23606 19.48054 -8.50648 +-16.18037 25.00846 11.75566 +-17.23606 19.48054 8.50648 +-13.41638 19.48052 13.76381 +6.18034 25.00846 19.02113 +2.76398 19.48051 19.0211 +8.94431 19.48051 17.01297 +20 25.00846 0 +18.94426 19.48054 3.24915 +18.94426 19.48054 -3.24915 +numsurf 238 +SURF 0X0 +mat 1 +refs 3 +1 0 0 +13 0 0 +32 0 0 +SURF 0X0 +mat 1 +refs 3 +3 0 0 +20 0 0 +44 0 0 +SURF 0X0 +mat 1 +refs 3 +4 0 0 +23 0 0 +50 0 0 +SURF 0X0 +mat 1 +refs 3 +0 0 0 +26 0 0 +33 0 0 +SURF 0X0 +mat 1 +refs 3 +1 0 0 +32 0 0 +39 0 0 +SURF 0X0 +mat 1 +refs 3 +2 0 0 +38 0 0 +45 0 0 +SURF 0X0 +mat 1 +refs 3 +3 0 0 +44 0 0 +51 0 0 +SURF 0X0 +mat 1 +refs 3 +4 0 0 +50 0 0 +27 0 0 +SURF 0X0 +mat 1 +refs 3 +5 0 0 +56 0 0 +71 0 0 +SURF 0X0 +mat 1 +refs 3 +6 0 0 +59 0 0 +77 0 0 +SURF 0X0 +mat 1 +refs 3 +7 0 0 +62 0 0 +80 0 0 +SURF 0X0 +mat 1 +refs 3 +8 0 0 +65 0 0 +83 0 0 +SURF 0X0 +mat 1 +refs 3 +9 0 0 +68 0 0 +72 0 0 +SURF 0X0 +mat 1 +refs 3 +74 0 0 +81 0 0 +10 0 0 +SURF 0X0 +mat 1 +refs 3 +73 0 0 +84 0 0 +74 0 0 +SURF 0X0 +mat 1 +refs 3 +72 0 0 +85 0 0 +73 0 0 +SURF 0X0 +mat 1 +refs 3 +74 0 0 +84 0 0 +81 0 0 +SURF 0X0 +mat 1 +refs 3 +84 0 0 +82 0 0 +81 0 0 +SURF 0X0 +mat 1 +refs 3 +73 0 0 +85 0 0 +84 0 0 +SURF 0X0 +mat 1 +refs 3 +85 0 0 +86 0 0 +84 0 0 +SURF 0X0 +mat 1 +refs 3 +84 0 0 +86 0 0 +82 0 0 +SURF 0X0 +mat 1 +refs 3 +86 0 0 +83 0 0 +82 0 0 +SURF 0X0 +mat 1 +refs 3 +72 0 0 +68 0 0 +85 0 0 +SURF 0X0 +mat 1 +refs 3 +68 0 0 +67 0 0 +85 0 0 +SURF 0X0 +mat 1 +refs 3 +85 0 0 +67 0 0 +86 0 0 +SURF 0X0 +mat 1 +refs 3 +67 0 0 +66 0 0 +86 0 0 +SURF 0X0 +mat 1 +refs 3 +86 0 0 +66 0 0 +83 0 0 +SURF 0X0 +mat 1 +refs 3 +66 0 0 +8 0 0 +83 0 0 +SURF 0X0 +mat 1 +refs 3 +81 0 0 +78 0 0 +10 0 0 +SURF 0X0 +mat 1 +refs 3 +82 0 0 +87 0 0 +81 0 0 +SURF 0X0 +mat 1 +refs 3 +83 0 0 +88 0 0 +82 0 0 +SURF 0X0 +mat 1 +refs 3 +81 0 0 +87 0 0 +78 0 0 +SURF 0X0 +mat 1 +refs 3 +87 0 0 +79 0 0 +78 0 0 +SURF 0X0 +mat 1 +refs 3 +82 0 0 +88 0 0 +87 0 0 +SURF 0X0 +mat 1 +refs 3 +88 0 0 +89 0 0 +87 0 0 +SURF 0X0 +mat 1 +refs 3 +87 0 0 +89 0 0 +79 0 0 +SURF 0X0 +mat 1 +refs 3 +89 0 0 +80 0 0 +79 0 0 +SURF 0X0 +mat 1 +refs 3 +83 0 0 +65 0 0 +88 0 0 +SURF 0X0 +mat 1 +refs 3 +65 0 0 +64 0 0 +88 0 0 +SURF 0X0 +mat 1 +refs 3 +88 0 0 +64 0 0 +89 0 0 +SURF 0X0 +mat 1 +refs 3 +64 0 0 +63 0 0 +89 0 0 +SURF 0X0 +mat 1 +refs 3 +89 0 0 +63 0 0 +80 0 0 +SURF 0X0 +mat 1 +refs 3 +63 0 0 +7 0 0 +80 0 0 +SURF 0X0 +mat 1 +refs 3 +78 0 0 +75 0 0 +10 0 0 +SURF 0X0 +mat 1 +refs 3 +79 0 0 +90 0 0 +78 0 0 +SURF 0X0 +mat 1 +refs 3 +80 0 0 +91 0 0 +79 0 0 +SURF 0X0 +mat 1 +refs 3 +78 0 0 +90 0 0 +75 0 0 +SURF 0X0 +mat 1 +refs 3 +90 0 0 +76 0 0 +75 0 0 +SURF 0X0 +mat 1 +refs 3 +79 0 0 +91 0 0 +90 0 0 +SURF 0X0 +mat 1 +refs 3 +91 0 0 +92 0 0 +90 0 0 +SURF 0X0 +mat 1 +refs 3 +90 0 0 +92 0 0 +76 0 0 +SURF 0X0 +mat 1 +refs 3 +92 0 0 +77 0 0 +76 0 0 +SURF 0X0 +mat 1 +refs 3 +80 0 0 +62 0 0 +91 0 0 +SURF 0X0 +mat 1 +refs 3 +62 0 0 +61 0 0 +91 0 0 +SURF 0X0 +mat 1 +refs 3 +91 0 0 +61 0 0 +92 0 0 +SURF 0X0 +mat 1 +refs 3 +61 0 0 +60 0 0 +92 0 0 +SURF 0X0 +mat 1 +refs 3 +92 0 0 +60 0 0 +77 0 0 +SURF 0X0 +mat 1 +refs 3 +60 0 0 +6 0 0 +77 0 0 +SURF 0X0 +mat 1 +refs 3 +75 0 0 +69 0 0 +10 0 0 +SURF 0X0 +mat 1 +refs 3 +76 0 0 +93 0 0 +75 0 0 +SURF 0X0 +mat 1 +refs 3 +77 0 0 +94 0 0 +76 0 0 +SURF 0X0 +mat 1 +refs 3 +75 0 0 +93 0 0 +69 0 0 +SURF 0X0 +mat 1 +refs 3 +93 0 0 +70 0 0 +69 0 0 +SURF 0X0 +mat 1 +refs 3 +76 0 0 +94 0 0 +93 0 0 +SURF 0X0 +mat 1 +refs 3 +94 0 0 +95 0 0 +93 0 0 +SURF 0X0 +mat 1 +refs 3 +93 0 0 +95 0 0 +70 0 0 +SURF 0X0 +mat 1 +refs 3 +95 0 0 +71 0 0 +70 0 0 +SURF 0X0 +mat 1 +refs 3 +77 0 0 +59 0 0 +94 0 0 +SURF 0X0 +mat 1 +refs 3 +59 0 0 +58 0 0 +94 0 0 +SURF 0X0 +mat 1 +refs 3 +94 0 0 +58 0 0 +95 0 0 +SURF 0X0 +mat 1 +refs 3 +58 0 0 +57 0 0 +95 0 0 +SURF 0X0 +mat 1 +refs 3 +95 0 0 +57 0 0 +71 0 0 +SURF 0X0 +mat 1 +refs 3 +57 0 0 +5 0 0 +71 0 0 +SURF 0X0 +mat 1 +refs 3 +69 0 0 +74 0 0 +10 0 0 +SURF 0X0 +mat 1 +refs 3 +70 0 0 +96 0 0 +69 0 0 +SURF 0X0 +mat 1 +refs 3 +71 0 0 +97 0 0 +70 0 0 +SURF 0X0 +mat 1 +refs 3 +69 0 0 +96 0 0 +74 0 0 +SURF 0X0 +mat 1 +refs 3 +96 0 0 +73 0 0 +74 0 0 +SURF 0X0 +mat 1 +refs 3 +70 0 0 +97 0 0 +96 0 0 +SURF 0X0 +mat 1 +refs 3 +97 0 0 +98 0 0 +96 0 0 +SURF 0X0 +mat 1 +refs 3 +96 0 0 +98 0 0 +73 0 0 +SURF 0X0 +mat 1 +refs 3 +98 0 0 +72 0 0 +73 0 0 +SURF 0X0 +mat 1 +refs 3 +71 0 0 +56 0 0 +97 0 0 +SURF 0X0 +mat 1 +refs 3 +56 0 0 +55 0 0 +97 0 0 +SURF 0X0 +mat 1 +refs 3 +97 0 0 +55 0 0 +98 0 0 +SURF 0X0 +mat 1 +refs 3 +55 0 0 +54 0 0 +98 0 0 +SURF 0X0 +mat 1 +refs 3 +98 0 0 +54 0 0 +72 0 0 +SURF 0X0 +mat 1 +refs 3 +54 0 0 +9 0 0 +72 0 0 +SURF 0X0 +mat 1 +refs 3 +29 0 0 +68 0 0 +9 0 0 +SURF 0X0 +mat 1 +refs 3 +28 0 0 +99 0 0 +29 0 0 +SURF 0X0 +mat 1 +refs 3 +27 0 0 +100 0 0 +28 0 0 +SURF 0X0 +mat 1 +refs 3 +29 0 0 +99 0 0 +68 0 0 +SURF 0X0 +mat 1 +refs 3 +99 0 0 +67 0 0 +68 0 0 +SURF 0X0 +mat 1 +refs 3 +28 0 0 +100 0 0 +99 0 0 +SURF 0X0 +mat 1 +refs 3 +100 0 0 +101 0 0 +99 0 0 +SURF 0X0 +mat 1 +refs 3 +99 0 0 +101 0 0 +67 0 0 +SURF 0X0 +mat 1 +refs 3 +101 0 0 +66 0 0 +67 0 0 +SURF 0X0 +mat 1 +refs 3 +27 0 0 +50 0 0 +100 0 0 +SURF 0X0 +mat 1 +refs 3 +50 0 0 +49 0 0 +100 0 0 +SURF 0X0 +mat 1 +refs 3 +100 0 0 +49 0 0 +101 0 0 +SURF 0X0 +mat 1 +refs 3 +49 0 0 +48 0 0 +101 0 0 +SURF 0X0 +mat 1 +refs 3 +101 0 0 +48 0 0 +66 0 0 +SURF 0X0 +mat 1 +refs 3 +48 0 0 +8 0 0 +66 0 0 +SURF 0X0 +mat 1 +refs 3 +53 0 0 +65 0 0 +8 0 0 +SURF 0X0 +mat 1 +refs 3 +52 0 0 +102 0 0 +53 0 0 +SURF 0X0 +mat 1 +refs 3 +51 0 0 +103 0 0 +52 0 0 +SURF 0X0 +mat 1 +refs 3 +53 0 0 +102 0 0 +65 0 0 +SURF 0X0 +mat 1 +refs 3 +102 0 0 +64 0 0 +65 0 0 +SURF 0X0 +mat 1 +refs 3 +52 0 0 +103 0 0 +102 0 0 +SURF 0X0 +mat 1 +refs 3 +103 0 0 +104 0 0 +102 0 0 +SURF 0X0 +mat 1 +refs 3 +102 0 0 +104 0 0 +64 0 0 +SURF 0X0 +mat 1 +refs 3 +104 0 0 +63 0 0 +64 0 0 +SURF 0X0 +mat 1 +refs 3 +51 0 0 +44 0 0 +103 0 0 +SURF 0X0 +mat 1 +refs 3 +44 0 0 +43 0 0 +103 0 0 +SURF 0X0 +mat 1 +refs 3 +103 0 0 +43 0 0 +104 0 0 +SURF 0X0 +mat 1 +refs 3 +43 0 0 +42 0 0 +104 0 0 +SURF 0X0 +mat 1 +refs 3 +104 0 0 +42 0 0 +63 0 0 +SURF 0X0 +mat 1 +refs 3 +42 0 0 +7 0 0 +63 0 0 +SURF 0X0 +mat 1 +refs 3 +47 0 0 +62 0 0 +7 0 0 +SURF 0X0 +mat 1 +refs 3 +46 0 0 +105 0 0 +47 0 0 +SURF 0X0 +mat 1 +refs 3 +45 0 0 +106 0 0 +46 0 0 +SURF 0X0 +mat 1 +refs 3 +47 0 0 +105 0 0 +62 0 0 +SURF 0X0 +mat 1 +refs 3 +105 0 0 +61 0 0 +62 0 0 +SURF 0X0 +mat 1 +refs 3 +46 0 0 +106 0 0 +105 0 0 +SURF 0X0 +mat 1 +refs 3 +106 0 0 +107 0 0 +105 0 0 +SURF 0X0 +mat 1 +refs 3 +105 0 0 +107 0 0 +61 0 0 +SURF 0X0 +mat 1 +refs 3 +107 0 0 +60 0 0 +61 0 0 +SURF 0X0 +mat 1 +refs 3 +45 0 0 +38 0 0 +106 0 0 +SURF 0X0 +mat 1 +refs 3 +38 0 0 +37 0 0 +106 0 0 +SURF 0X0 +mat 1 +refs 3 +106 0 0 +37 0 0 +107 0 0 +SURF 0X0 +mat 1 +refs 3 +37 0 0 +36 0 0 +107 0 0 +SURF 0X0 +mat 1 +refs 3 +107 0 0 +36 0 0 +60 0 0 +SURF 0X0 +mat 1 +refs 3 +36 0 0 +6 0 0 +60 0 0 +SURF 0X0 +mat 1 +refs 3 +41 0 0 +59 0 0 +6 0 0 +SURF 0X0 +mat 1 +refs 3 +40 0 0 +108 0 0 +41 0 0 +SURF 0X0 +mat 1 +refs 3 +39 0 0 +109 0 0 +40 0 0 +SURF 0X0 +mat 1 +refs 3 +41 0 0 +108 0 0 +59 0 0 +SURF 0X0 +mat 1 +refs 3 +108 0 0 +58 0 0 +59 0 0 +SURF 0X0 +mat 1 +refs 3 +40 0 0 +109 0 0 +108 0 0 +SURF 0X0 +mat 1 +refs 3 +109 0 0 +110 0 0 +108 0 0 +SURF 0X0 +mat 1 +refs 3 +108 0 0 +110 0 0 +58 0 0 +SURF 0X0 +mat 1 +refs 3 +110 0 0 +57 0 0 +58 0 0 +SURF 0X0 +mat 1 +refs 3 +39 0 0 +32 0 0 +109 0 0 +SURF 0X0 +mat 1 +refs 3 +32 0 0 +31 0 0 +109 0 0 +SURF 0X0 +mat 1 +refs 3 +109 0 0 +31 0 0 +110 0 0 +SURF 0X0 +mat 1 +refs 3 +31 0 0 +30 0 0 +110 0 0 +SURF 0X0 +mat 1 +refs 3 +110 0 0 +30 0 0 +57 0 0 +SURF 0X0 +mat 1 +refs 3 +30 0 0 +5 0 0 +57 0 0 +SURF 0X0 +mat 1 +refs 3 +35 0 0 +56 0 0 +5 0 0 +SURF 0X0 +mat 1 +refs 3 +34 0 0 +111 0 0 +35 0 0 +SURF 0X0 +mat 1 +refs 3 +33 0 0 +112 0 0 +34 0 0 +SURF 0X0 +mat 1 +refs 3 +35 0 0 +111 0 0 +56 0 0 +SURF 0X0 +mat 1 +refs 3 +111 0 0 +55 0 0 +56 0 0 +SURF 0X0 +mat 1 +refs 3 +34 0 0 +112 0 0 +111 0 0 +SURF 0X0 +mat 1 +refs 3 +112 0 0 +113 0 0 +111 0 0 +SURF 0X0 +mat 1 +refs 3 +111 0 0 +113 0 0 +55 0 0 +SURF 0X0 +mat 1 +refs 3 +113 0 0 +54 0 0 +55 0 0 +SURF 0X0 +mat 1 +refs 3 +33 0 0 +26 0 0 +112 0 0 +SURF 0X0 +mat 1 +refs 3 +26 0 0 +25 0 0 +112 0 0 +SURF 0X0 +mat 1 +refs 3 +112 0 0 +25 0 0 +113 0 0 +SURF 0X0 +mat 1 +refs 3 +25 0 0 +24 0 0 +113 0 0 +SURF 0X0 +mat 1 +refs 3 +113 0 0 +24 0 0 +54 0 0 +SURF 0X0 +mat 1 +refs 3 +24 0 0 +9 0 0 +54 0 0 +SURF 0X0 +mat 1 +refs 3 +48 0 0 +53 0 0 +8 0 0 +SURF 0X0 +mat 1 +refs 3 +49 0 0 +114 0 0 +48 0 0 +SURF 0X0 +mat 1 +refs 3 +50 0 0 +115 0 0 +49 0 0 +SURF 0X0 +mat 1 +refs 3 +48 0 0 +114 0 0 +53 0 0 +SURF 0X0 +mat 1 +refs 3 +114 0 0 +52 0 0 +53 0 0 +SURF 0X0 +mat 1 +refs 3 +49 0 0 +115 0 0 +114 0 0 +SURF 0X0 +mat 1 +refs 3 +115 0 0 +116 0 0 +114 0 0 +SURF 0X0 +mat 1 +refs 3 +114 0 0 +116 0 0 +52 0 0 +SURF 0X0 +mat 1 +refs 3 +116 0 0 +51 0 0 +52 0 0 +SURF 0X0 +mat 1 +refs 3 +50 0 0 +23 0 0 +115 0 0 +SURF 0X0 +mat 1 +refs 3 +23 0 0 +22 0 0 +115 0 0 +SURF 0X0 +mat 1 +refs 3 +115 0 0 +22 0 0 +116 0 0 +SURF 0X0 +mat 1 +refs 3 +22 0 0 +21 0 0 +116 0 0 +SURF 0X0 +mat 1 +refs 3 +116 0 0 +21 0 0 +51 0 0 +SURF 0X0 +mat 1 +refs 3 +21 0 0 +3 0 0 +51 0 0 +SURF 0X0 +mat 1 +refs 3 +42 0 0 +47 0 0 +7 0 0 +SURF 0X0 +mat 1 +refs 3 +43 0 0 +117 0 0 +42 0 0 +SURF 0X0 +mat 1 +refs 3 +44 0 0 +118 0 0 +43 0 0 +SURF 0X0 +mat 1 +refs 3 +42 0 0 +117 0 0 +47 0 0 +SURF 0X0 +mat 1 +refs 3 +117 0 0 +46 0 0 +47 0 0 +SURF 0X0 +mat 1 +refs 3 +43 0 0 +118 0 0 +117 0 0 +SURF 0X0 +mat 1 +refs 3 +118 0 0 +119 0 0 +117 0 0 +SURF 0X0 +mat 1 +refs 3 +117 0 0 +119 0 0 +46 0 0 +SURF 0X0 +mat 1 +refs 3 +119 0 0 +45 0 0 +46 0 0 +SURF 0X0 +mat 1 +refs 3 +44 0 0 +20 0 0 +118 0 0 +SURF 0X0 +mat 1 +refs 3 +20 0 0 +19 0 0 +118 0 0 +SURF 0X0 +mat 1 +refs 3 +118 0 0 +19 0 0 +119 0 0 +SURF 0X0 +mat 1 +refs 3 +19 0 0 +18 0 0 +119 0 0 +SURF 0X0 +mat 1 +refs 3 +119 0 0 +18 0 0 +45 0 0 +SURF 0X0 +mat 1 +refs 3 +18 0 0 +2 0 0 +45 0 0 +SURF 0X0 +mat 1 +refs 3 +36 0 0 +41 0 0 +6 0 0 +SURF 0X0 +mat 1 +refs 3 +37 0 0 +120 0 0 +36 0 0 +SURF 0X0 +mat 1 +refs 3 +38 0 0 +121 0 0 +37 0 0 +SURF 0X0 +mat 1 +refs 3 +36 0 0 +120 0 0 +41 0 0 +SURF 0X0 +mat 1 +refs 3 +120 0 0 +40 0 0 +41 0 0 +SURF 0X0 +mat 1 +refs 3 +37 0 0 +121 0 0 +120 0 0 +SURF 0X0 +mat 1 +refs 3 +121 0 0 +122 0 0 +120 0 0 +SURF 0X0 +mat 1 +refs 3 +120 0 0 +122 0 0 +40 0 0 +SURF 0X0 +mat 1 +refs 3 +122 0 0 +39 0 0 +40 0 0 +SURF 0X0 +mat 1 +refs 3 +38 0 0 +2 0 0 +121 0 0 +SURF 0X0 +mat 1 +refs 3 +2 0 0 +17 0 0 +121 0 0 +SURF 0X0 +mat 1 +refs 3 +121 0 0 +17 0 0 +122 0 0 +SURF 0X0 +mat 1 +refs 3 +17 0 0 +16 0 0 +122 0 0 +SURF 0X0 +mat 1 +refs 3 +122 0 0 +16 0 0 +39 0 0 +SURF 0X0 +mat 1 +refs 3 +16 0 0 +1 0 0 +39 0 0 +SURF 0X0 +mat 1 +refs 3 +30 0 0 +35 0 0 +5 0 0 +SURF 0X0 +mat 1 +refs 3 +31 0 0 +123 0 0 +30 0 0 +SURF 0X0 +mat 1 +refs 3 +32 0 0 +124 0 0 +31 0 0 +SURF 0X0 +mat 1 +refs 3 +30 0 0 +123 0 0 +35 0 0 +SURF 0X0 +mat 1 +refs 3 +123 0 0 +34 0 0 +35 0 0 +SURF 0X0 +mat 1 +refs 3 +31 0 0 +124 0 0 +123 0 0 +SURF 0X0 +mat 1 +refs 3 +124 0 0 +125 0 0 +123 0 0 +SURF 0X0 +mat 1 +refs 3 +123 0 0 +125 0 0 +34 0 0 +SURF 0X0 +mat 1 +refs 3 +125 0 0 +33 0 0 +34 0 0 +SURF 0X0 +mat 1 +refs 3 +32 0 0 +13 0 0 +124 0 0 +SURF 0X0 +mat 1 +refs 3 +13 0 0 +12 0 0 +124 0 0 +SURF 0X0 +mat 1 +refs 3 +124 0 0 +12 0 0 +125 0 0 +SURF 0X0 +mat 1 +refs 3 +12 0 0 +11 0 0 +125 0 0 +SURF 0X0 +mat 1 +refs 3 +125 0 0 +11 0 0 +33 0 0 +SURF 0X0 +mat 1 +refs 3 +11 0 0 +0 0 0 +33 0 0 +SURF 0X0 +mat 1 +refs 3 +24 0 0 +29 0 0 +9 0 0 +SURF 0X0 +mat 1 +refs 3 +25 0 0 +126 0 0 +24 0 0 +SURF 0X0 +mat 1 +refs 3 +26 0 0 +127 0 0 +25 0 0 +SURF 0X0 +mat 1 +refs 3 +24 0 0 +126 0 0 +29 0 0 +SURF 0X0 +mat 1 +refs 3 +126 0 0 +28 0 0 +29 0 0 +SURF 0X0 +mat 1 +refs 3 +25 0 0 +127 0 0 +126 0 0 +SURF 0X0 +mat 1 +refs 3 +127 0 0 +128 0 0 +126 0 0 +SURF 0X0 +mat 1 +refs 3 +126 0 0 +128 0 0 +28 0 0 +SURF 0X0 +mat 1 +refs 3 +128 0 0 +27 0 0 +28 0 0 +SURF 0X0 +mat 1 +refs 3 +26 0 0 +0 0 0 +127 0 0 +SURF 0X0 +mat 1 +refs 3 +0 0 0 +15 0 0 +127 0 0 +SURF 0X0 +mat 1 +refs 3 +127 0 0 +15 0 0 +128 0 0 +SURF 0X0 +mat 1 +refs 3 +15 0 0 +14 0 0 +128 0 0 +SURF 0X0 +mat 1 +refs 3 +128 0 0 +14 0 0 +27 0 0 +SURF 0X0 +mat 1 +refs 3 +14 0 0 +4 0 0 +27 0 0 +kids 0 diff --git a/tower/Models/tower.xml b/gci-radar/Models/gci.xml similarity index 84% rename from tower/Models/tower.xml rename to gci-radar/Models/gci.xml index fec0288..84af8cf 100644 --- a/tower/Models/tower.xml +++ b/gci-radar/Models/gci.xml @@ -2,7 +2,7 @@ - towerSnowy1.ac + gci-tower.ac Aircraft/tower/Models/smoke.xml diff --git a/tower/Models/smoke.png b/gci-radar/Models/smoke.png similarity index 100% rename from tower/Models/smoke.png rename to gci-radar/Models/smoke.png diff --git a/tower/Models/smoke.xml b/gci-radar/Models/smoke.xml similarity index 100% rename from tower/Models/smoke.xml rename to gci-radar/Models/smoke.xml diff --git a/gci-radar/Nasal/damage.nas b/gci-radar/Nasal/damage.nas new file mode 100644 index 0000000..ad8f6b5 --- /dev/null +++ b/gci-radar/Nasal/damage.nas @@ -0,0 +1,285 @@ +var clamp = func(v, min, max) { v < min ? min : v > max ? max : v } + +var TRUE = 1; +var FALSE = 0; + +var hp = 80; +var hp_max = hp; + + +var cannon_types = { + " M70 rocket hit": 0.25, #135mm + " M55 cannon shell hit": 0.10, # 30mm + " KCA cannon shell hit": 0.10, # 30mm + " Gun Splash On ": 0.10, # 30mm + " M61A1 shell hit": 0.05, # 20mm + " GAU-8/A hit": 0.10, # 30mm + " BK27 cannon hit": 0.07, # 27mm + " GSh-30 hit": 0.10, # 30mm + " GSh-23 hit": 0.065,# 23mm + " 7.62 hit": 0.005,# 7.62mm + " 50 BMG hit": 0.015,# 12.7mm + " S-5 rocket hit": 0.20, #55mm +}; + + + +var warhead_lbs = { + "AGM-65": 126.00, + "AGM-84": 488.00, + "AGM-88": 146.00, + "AGM65": 200.00, + "ALARM": 450.00, + "AM39-Exocet": 364.00, + "AS-37-Martel": 330.00, + "AS30L": 529.00, + "Exocet": 364.00, + "FAB-100": 92.59, + "FAB-250": 202.85, + "FAB-500": 564.38, + "GBU-12": 190.00, + "GBU-24": 945.00, + "GBU-31": 945.00, + "GBU12": 190.00, + "GBU16": 450.00, + "HVAR": 7.50,#P51 + "KAB-500": 564.38, + "Kh-25MP": 197.53, + "Kh-66": 244.71, + "KN-06": 315.00, + "LAU-68": 10.00, + "M317": 145.00, + "M71": 200.00, + "M71R": 200.00, + "M90": 500.00, + "MK-82": 192.00, + "MK-83": 445.00, + "MK-84": 945.00, + "OFAB-100": 92.59, + "RB-04E": 661.00, + "RB-05A": 353.00, + "RB-15F": 440.92, + "RB-75": 126.00, + "RN-14T": 800.00, #fictional, thermobaeric replacement for the RN-24 nuclear bomb + "RN-18T": 1200.00, #fictional, thermobaeric replacement for the RN-28 nuclear bomb + "RS-2US": 28.66, + "S-21": 245.00, + "S-24": 271.00, + "S530D": 66.00, + "SCALP": 992.00, + "Sea Eagle": 505.00, + "SeaEagle": 505.00, + "STORMSHADOW": 850.00, + "ZB-250": 236.99, + "ZB-500": 473.99, +}; + +var incoming_listener = func { + var history = getprop("/sim/multiplay/chat-history"); + var hist_vector = split("\n", history); + if (size(hist_vector) > 0) { + var last = hist_vector[size(hist_vector)-1]; + var last_vector = split(":", last); + var author = last_vector[0]; + var callsign = getprop("sim/multiplay/callsign"); + if (size(last_vector) > 1 and author != callsign) { + # not myself + #print("not me"); + var m2000 = FALSE; + if (find(" at " ~ callsign ~ ". Release ", last_vector[1]) != -1) { + # a m2000 is firing at us + m2000 = TRUE; + } + if (last_vector[1] == " FOX2 at" or last_vector[1] == " aim7 at" or last_vector[1] == " aim9 at" + or last_vector[1] == " aim120 at" or last_vector[1] == " RB-24J fired at" or last_vector[1] == " RB-74 fired at" + or last_vector[1] == " RB-71 fired at" or last_vector[1] == " RB-15F fired at" + or last_vector[1] == " RB-99 fired at" or m2000 == TRUE) { + # air2air being fired + if (size(last_vector) > 2 or m2000 == TRUE) { + #print("Missile launch detected at"~last_vector[2]~" from "~author); + if (m2000 == TRUE or last_vector[2] == " "~callsign) { + # its being fired at me + #print("Incoming!"); + var enemy = getCallsign(author); + if (enemy != nil) { + #print("enemy identified"); + var bearingNode = enemy.getNode("radar/bearing-deg"); + if (bearingNode != nil) { + #print("bearing to enemy found"); + var bearing = bearingNode.getValue(); + var heading = getprop("orientation/heading-deg"); + var clock = bearing - heading; + while(clock < 0) { + clock = clock + 360; + } + while(clock > 360) { + clock = clock - 360; + } + #print("incoming from "~clock); + if (clock >= 345 or clock < 15) { + playIncomingSound("12"); + } elsif (clock >= 15 and clock < 45) { + playIncomingSound("1"); + } elsif (clock >= 45 and clock < 75) { + playIncomingSound("2"); + } elsif (clock >= 75 and clock < 105) { + playIncomingSound("3"); + } elsif (clock >= 105 and clock < 135) { + playIncomingSound("4"); + } elsif (clock >= 135 and clock < 165) { + playIncomingSound("5"); + } elsif (clock >= 165 and clock < 195) { + playIncomingSound("6"); + } elsif (clock >= 195 and clock < 225) { + playIncomingSound("7"); + } elsif (clock >= 225 and clock < 255) { + playIncomingSound("8"); + } elsif (clock >= 255 and clock < 285) { + playIncomingSound("9"); + } elsif (clock >= 285 and clock < 315) { + playIncomingSound("10"); + } elsif (clock >= 315 and clock < 345) { + playIncomingSound("11"); + } else { + playIncomingSound(""); + } + return; + } + } + } + } + } elsif (1 == 1) { # mirage: getprop("/controls/armament/mp-messaging") + # latest version of failure manager and taking damage enabled + #print("damage enabled"); + var last1 = split(" ", last_vector[1]); + if(size(last1) > 2 and last1[size(last1)-1] == "exploded" ) { + #print("missile hitting someone"); + if (size(last_vector) > 3 and last_vector[3] == " "~callsign) { + #print("that someone is me!"); + var type = last1[1]; + if (type == "Matra" or type == "Sea") { + for (var i = 2; i < size(last1)-1; i += 1) { + type = type~" "~last1[i]; + } + } + var number = split(" ", last_vector[2]); + var distance = num(number[1]); + #print(type~"|"); + if(distance != nil) { + var dist = distance; + + #check distance w/ if statement here + + if (contains(warhead_lbs, type)) { + #maxDist = maxDamageDistFromWarhead(warhead_lbs[type]); + } else { + return; + } + + if (type == "M90" and distance < 300) { + var failed = fail_systems(warhead_lbs[type]/2); + return; + } elsif (distance < 150) { + var prob = 1; + if ( distance > 50 ) { + distance = distance - 50; + prob = 1 - (distance/100); + } + } + + + var failed = fail_systems(warhead_lbs[type] * prob); + #ar percent = 100 * probability; + #printf("Took %.1f%% damage from %s missile at %0.1f meters. %s systems was hit", percent,type,dist,failed); + } + } + } elsif (cannon_types[last_vector[1]] != nil) { + # cannon hitting someone + print("cannon"); + if (size(last_vector) > 2 and last_vector[2] == " "~callsign) { + print("cannon hit us"); + var last3 = split(" ", last_vector[3]); + #print("last3[2]: " ~ last3[2]); + #print("last3[1]: " ~ last3[1]); + if(size(last3) > 2) { + if ( last3[2] == "hits" ) { + var hit_count = num(last3[1]); + } + } else { + var hit_count = 4; + } + var damaged_sys = 0; + var probability = cannon_types[last_vector[1]]; + for (var i = 1; i <= hit_count; i = i + 1) { + var failed = fail_systems(probability); + damaged_sys = damaged_sys + failed; + } + # that someone is me! + #print("hitting me"); + + printf("Took %.1f%% damage from cannon! %s systems was hit.", probability*hit_count*100, damaged_sys); + } + } + } + } + } +} + +var maxDamageDistFromWarhead = func (lbs) { + # very simple + var dist = 7*math.sqrt(lbs); + + return dist; +} + +var fail_systems = func (damage) { + hp = hp - damage; + print("HP: " ~ hp ~ "/" ~ hp_max); + + if ( hp < 0 ) { + setprop("/carrier/sunk/",1); + setprop("/sim/multiplay/generic/int[0]",1); + } +}; + +var playIncomingSound = func (clock) { + setprop("sound/incoming"~clock, 1); + settimer(func {stopIncomingSound(clock);},3); +} + +var stopIncomingSound = func (clock) { + setprop("sound/incoming"~clock, 0); +} + +var callsign_struct = {}; +var getCallsign = func (callsign) { + var node = callsign_struct[callsign]; + return node; +} + +var processCallsigns = func () { + callsign_struct = {}; + var players = props.globals.getNode("ai/models").getChildren(); + foreach (var player; players) { + if(player.getChild("valid") != nil and player.getChild("valid").getValue() == TRUE and player.getChild("callsign") != nil and player.getChild("callsign").getValue() != "" and player.getChild("callsign").getValue() != nil) { + var callsign = player.getChild("callsign").getValue(); + callsign_struct[callsign] = player; + } + } + settimer(processCallsigns, 1.5); +} + +processCallsigns(); + +var logTime = func{ + #log time and date for outputing ucsv files for converting into KML files for google earth. + if (getprop("logging/log[0]/enabled") == TRUE and getprop("sim/time/utc/year") != nil) { + var date = getprop("sim/time/utc/year")~"/"~getprop("sim/time/utc/month")~"/"~getprop("sim/time/utc/day"); + var time = getprop("sim/time/utc/hour")~":"~getprop("sim/time/utc/minute")~":"~getprop("sim/time/utc/second"); + + setprop("logging/date-log", date); + setprop("logging/time-log", time); + } +} + +setlistener("/sim/multiplay/chat-history", incoming_listener, 0, 0); \ No newline at end of file diff --git a/gci-radar/Nasal/gci.nas b/gci-radar/Nasal/gci.nas new file mode 100644 index 0000000..46ef60d --- /dev/null +++ b/gci-radar/Nasal/gci.nas @@ -0,0 +1,498 @@ +# (c) 2018 pinto +# license: gplv2+ + +# v0.1 - just a very basic proof of concept at this point. +# will only report the closest bad guy, does no threat assessment. +# todo: +# test +# toggle radar on/off +# all the other requests that a gci can do (only handles BRAA right now) + +########################################## +### Variables +########################################## + +# prop_watch is a mp[x] boolean property set by that aircraft designer. the plane sets this to 1 when it wants to receive BRAA +# if the plane is not on the enemy list, and is one of the first ~10 to +# request a BRAA, then it will receive it. +var damage_prop = props.globals.getNode("/carrier/sunk"); +var prop_watch = { + "MiG-21bis": [0,1,2], + "MiG-21MF-75": [0,1,2], + "QF-4E": [0,1,2] +}; + +var radar_stations = [ + "gci", + "frigate", +]; + +var update_rate = 10; #how often the message should update in seconds +var hostile_radius = 300000; #max distance to check against, in meters + +var true = 1; +var false = 0; + +# request types +var NONE = 0; +var PICTURE = 1; +var BOGEYDOPE = 2; +var CUTOFF = 3; + +var PENDING = 0; +var SENDING = 1; +var SENT = 2; + +var output_prop = 0; +var radar_tx_output_prop = 11; +var enemy_node = props.globals.getNode("/enemies"); +var player_node = props.globals.getNode("/ai/models"); +var opfor_switch = props.globals.getNode("/enemies/opfor-switch"); # targets all non-opfor +var friend_switch = props.globals.getNode("/enemies/friend-switch"); # targets all opfor +########################################## +### Objects +########################################## + +var gci_contact = { + new: func(c, class) { + var m = {parents:[gci_contact]}; + m.time_from_last_message = 0; + m.node = c; + m.model = remove_suffix(remove_suffix(split(".", split("/", c.getNode("sim/model/path").getValue())[-1])[0], "-model"), "-anim"); + m.valid = c.getNode("valid"); + m.callsign = c.getNode("callsign").getValue(); + if ( contains(prop_watch, m.model) ) { + m.picture_node = c.getNode("sim/multiplay/generic/bool["~prop_watch[m.model][0]~"]"); + m.bogeydope_node = c.getNode("sim/multiplay/generic/bool["~prop_watch[m.model][1]~"]"); + m.cutoff_node = c.getNode("sim/multiplay/generic/bool["~prop_watch[m.model][2]~"]"); + } else { + m.picture_node = -1; + m.bogeydope_node = -1; + m.cutoff_node = -1; + } + m.is_radar_station = find_match(m.model,radar_stations); + m.contact = radar_logic.Contact.new(c,class); + m.foe = false; + m.match = false; + m.request = NONE; + m.last_request = NONE; + m.request_status = PENDING; + m.msg_queue = []; + if (m.is_radar_station) { + m.radar_station_process_send(); + } else { + m.process_send(); + } + return m; + }, + getValid: func() { + if (me.valid.getNode() == 0 and me.callsign != me.node.getNode("callsign").getValue()) { + return 0; + } else { + return 1; + } + }, + check_foe: func() { + me.foe = false; + if (opfor_switch.getValue() == true ) { + if (left(string.lc(me.callsign),5) != "opfor") { + me.foe = true; + } + } elsif (friend_switch.getValue() == true) { + if (left(string.lc(me.callsign),5) == "opfor") { + me.foe = true; + } + } else { + foreach (var cs; enemy_node.getChildren()) { + if (me.callsign == cs.getValue()) { + me.foe = true; + break; + } + } + } + return me.foe; + }, + update_request: func() { + if (me.picture_node == -1) { + return; + } + #print("updating info"); + if (me.picture_node.getValue() == true) { + me.request = PICTURE; + } elsif (me.bogeydope_node.getValue() == true) { + me.request = BOGEYDOPE; + } elsif (me.cutoff_node.getValue() == true) { + me.request = CUTOFF; + } else { + me.request = NONE; + } + }, + check_node: func() { + #print('checking node'); + if (me.picture_node == -1){ + #print('watch node is -1'); + return false; + } elsif (me.check_foe() == true) { + #print('check_foe is true'); + return false; + } elsif (me.request == NONE) { + #print('node is false'); + return false; + } elsif (systime() - me.time_from_last_message < update_rate) { + #print("update failed"); + return false; + } elsif (me.request_status == SENT) { + return false; + } else { + me.time_from_last_message = systime(); + return true; + } + }, + process_send: func() { + # messages are first in, first out order + # updates every 1.5 seconds + #print('in process_send()'); + if (damage_prop.getValue() == 0) { + + me.update_request(); + + #print('rqst: ' ~ me.request); + #print('last: ' ~ me.last_request); + #print('stat: ' ~ me.request_status); + #print('queue size: ' ~ size(me.msg_queue)); + + if (me.request == NONE) { + #print('setting request to none'); + me.request_status = PENDING; + } elsif (me.request != NONE and me.request_status == PENDING and me.request_status != SENT and size(me.msg_queue) > 0) { + #print('setting status to sending'); + me.request_status = SENDING; + } elsif (me.request_status == SENDING and size(me.msg_queue) == 0) { + #print('setting status to sent'); + me.request_status = SENT; + } + + if (me.request == NONE or me.request_status == SENT) { + #print('emptying queue'); + me.msg_queue = []; + } + + if (me.request != me.last_request) { + #print('setting status to pending and emptying queue'); + me.request_status = PENDING; + me.msg_queue = []; + } + + me.last_request = me.request; + + if (size(me.msg_queue) > 0 and me.request_status == SENDING) { + #print("msg_queue: " ~ debug.dump(me.msg_queue)); + setprop("/sim/multiplay/generic/string["~output_prop~"]",me.msg_queue[0]); + output_prop = output_prop > 9 ? 0 : output_prop + 1; + me.msg_queue = purge_from_vector(me.msg_queue,0); + } + } + + settimer(func(){me.process_send();},1.3); + }, + radar_station_process_send: func() { + # messages are first in, first out order + # updates every 1.5 seconds + #print('in process_send()'); + + if (size(me.msg_queue) > 0 and damage_prop.getValue() == 0) { + #print("msg_queue: " ~ debug.dump(me.msg_queue)); + setprop("/sim/multiplay/generic/string["~radar_tx_output_prop~"]",me.msg_queue[0]); + radar_tx_output_prop = radar_tx_output_prop >= 16 ? 11 : radar_tx_output_prop + 1; + me.msg_queue = purge_from_vector(me.msg_queue,0); + } + + settimer(func(){me.radar_station_process_send();},1.3); + }, +}; + +########################################## +### Functions +########################################## + +# gather up all contacts, so we can iterate over them + +var cx_master_list = []; + +var gather_contacts = func() { + # first we need to clean the contact list + for (var i = 0; i < size(cx_master_list); i = i + 1) { + if (cx_master_list[i] == nil) { break; } + if (!cx_master_list[i].getValid()) { + cx_master_list = purge_from_vector(cx_master_list, i); + } + } + var matching = false; + foreach(var mp; player_node.getChildren("multiplayer")) { + if (mp.getNode("valid").getValue() == 1) { + matching = false; + foreach(var cx; cx_master_list) { + if ( mp.getPath() == cx.contact.getNode().getPath() ) { + matching = true; + break; + } + } + if (matching == false) { + cx = gci_contact.new(mp,0); + print("adding contact: " ~ cx.contact.get_Callsign()); + append(cx_master_list,cx); + } + } + } +} + +var check_requests = func(){ + foreach (var cx; cx_master_list) { + if (cx.check_foe() == true or cx.check_node() == false) { continue; } + if (size(cx.msg_queue) > 0) { continue; } # msg queue should be reset or emptied when request changes. + if (cx.request == NONE) { + #print('reqest is none in check_requests'); + continue; + } elsif (cx.request == PICTURE) { + var blue_coords = []; + var opfor_coords = []; + var match = false; + append(blue_coords, cx.contact.get_Coord()); + foreach (var check; cx_master_list) { + if (!check_visible(check)) { continue; } + match = false; + if (check.check_foe()) { + foreach (var coord; opfor_coords) { + if (coord.distance_to(check.contact.get_Coord()) < 3 * NM2M) { + match = true; + break; + } + } + if (!match) { append(opfor_coords,check.contact.get_Coord()); } + } else { + foreach (var coord; blue_coords) { + if (coord.distance_to(check.contact.get_Coord()) < 3 * NM2M) { + match = true; + break; + } + } + if (!match) { append(blue_coords,check.contact.get_Coord()); } + } + + if (!match) { + #send message + var bearing = math.round(cx.contact.get_Coord().course_to(check.contact.get_Coord()),1); + var range = math.round(check.contact.get_Coord().distance_to(cx.contact.get_Coord())); + var altitude = math.round(check.contact.get_altitude(),1); + # requestor-callsign:unique-message-id:2:bearing:range:altitude:[BLUFOR=0|OPFOR=1] + append(cx.msg_queue, cx.callsign ~ ":" ~ get_random() ~ ":2:" ~ bearing ~ ":" ~ range ~ ":" ~ altitude ~ ":" ~ check.check_foe()); + } + } + if (size(cx.msg_queue) == 0) { + append(cx.msg_queue, cx.callsign ~ ":" ~ get_random() ~ ":1:n:n:n:n"); + } else { + append(cx.msg_queue, cx.callsign ~ ":" ~ get_random() ~ ":0:d:d:d:d"); + } + + } elsif (cx.request == BOGEYDOPE) { + min_dist = hostile_radius; + closest = nil; + #print('checking bogey dope'); + foreach (var check; cx_master_list) { + if (!check.check_foe()) { continue; } + var dist = cx.contact.get_Coord().distance_to(check.contact.get_Coord()); + if ( dist > min_dist) { continue; } + if (!check_visible(check)) { continue; } + min_dist = dist; + closest = check; + } + if (closest != nil) { + var bearing = math.round(cx.contact.get_Coord().course_to(closest.contact.get_Coord()),1); + var range = math.round(closest.contact.get_Coord().distance_to(cx.contact.get_Coord())); + var altitude = math.round(closest.contact.get_altitude(),1); + var aspect = math.round(math.periodic(-180,180,closest.contact.get_heading() - closest.contact.get_Coord().course_to(cx.contact.get_Coord()))); + append(cx.msg_queue, cx.callsign ~ ":" ~ get_random() ~ ":3:" ~ bearing ~ ":" ~ range ~ ":" ~ altitude ~ ":" ~ aspect); + } else { + append(cx.msg_queue, cx.callsign ~ ":" ~ get_random() ~ ":1:n:n:n:n"); + } + + } elsif (cx.request == CUTOFF) { + min_dist = hostile_radius; + closest = nil; + foreach (var check; cx_master_list) { + if (!check.check_foe()) { continue; } + var dist = cx.contact.get_Coord().distance_to(check.contact.get_Coord()); + if ( dist > min_dist) { continue; } + if (!check_visible(check)) { continue; } + min_dist = dist; + closest = check; + } + if (closest != nil) { + var bogey_speed = closest.contact.speed.getValue(); + var cx_speed = cx.contact.speed.getValue(); + var bogey_heading = closest.contact.heading.getValue(); + var bearing = cx.contact.get_Coord().course_to(closest.contact.get_Coord()); + var range = closest.contact.get_Coord().distance_to(cx.contact.get_Coord()); + var altitude = math.round(closest.contact.get_altitude(),1); + var aspect = math.round(math.periodic(-180,180,closest.contact.get_heading() - closest.contact.get_Coord().course_to(cx.contact.get_Coord()))); + # get_intercept(bearing, dist_m, runnerHeading, runnerSpeed, chaserSpeed) + var info = get_intercept(bearing, range, bogey_heading, bogey_speed * KT2MPS, cx_speed * KT2MPS); + if (info == nil) { + append(cx.msg_queue, cx.callsign ~ ":" ~ get_random() ~ ":1:n:n:n:n"); + } else { + append(cx.msg_queue, cx.callsign ~ ":" ~ get_random() ~ ":4:" ~ int(info[1]) ~ ":" ~ int(info[0]) ~ ":" ~ altitude ~ ":" ~ aspect); + } + } else { + append(cx.msg_queue, cx.callsign ~ ":" ~ get_random() ~ ":1:n:n:n:n"); + } + } + } +} + +var cx_data_transmit = func(){ + #print('transmitting'); + foreach (var cx; cx_master_list) { + if (!cx.is_radar_station) { continue; } + if (size(cx.msg_queue) > 0) { continue; } + if (cx.check_foe()) { continue; } + foreach (var tx; cx_master_list) { + if (tx != cx) { + append(cx.msg_queue,cx.callsign ~ ":" ~ get_random() ~ ":" ~ tx.callsign); + } + } + } +} + +var data_receive_callsigns = []; +var cx_data_receive = func() { + # clean out old data (15 seconds) + var time = systime(); + var new_vec = []; + foreach (var rx; data_receive_callsigns){ + if (time - rx[1] < 15) { + append(new_vec,rx); + } + } + data_receive_callsigns = new_vec; + foreach (var cx; cx_master_list) { + for (var i = 11; i <= 15; i = i + 1) { + var msg = getprop(cx.node.getPath() ~ "/sim/multiplay/generic/string["~i~"]"); + if (msg == "") { continue; } + if (msg == nil) { continue; } + msg = split(":",msg); + if (msg[0] != getprop("/sim/multiplay/callsign")) { continue; }; + if (find_match(msg[2], data_receive_callsigns)) { continue; } + #print("adding cs to received list"); + append(data_receive_callsigns,[msg[2],systime()]); + } + } +} + +var check_visible = func(check) { + foreach(var rx; data_receive_callsigns) { + if (rx[0] == check.callsign) { + return true; + } + } + if (radar_logic.isNotBehindTerrain(check.node) == false){ return false; } + + var target_heading = check.contact.heading.getValue(); + var relative_bearing = math.abs(geo.normdeg180(check.contact.get_Coord().course_to(geo.aircraft_position()) - target_heading)); + var target_radial_airspeed = (-1 * ( ( relative_bearing / 90 ) - 1 ) ) * check.node.getNode("velocities/true-airspeed-kt").getValue(); + if ( math.abs(target_radial_airspeed) < 20 ) { return false; } # i.e. notching, landed aircraft + return true; +} + +var iter = 0; +var main_loop = func() { + #print("looping"); + if (getprop("/carrier/sunk/") == 0) { + if (iter == 0) { + gather_contacts(); + cx_data_transmit(); + } + cx_data_receive(); + check_requests(); + } + iter = iter >= 7 ? 0 : iter + 1; + settimer(func(){main_loop();},1); +} + + +var get_intercept = func(bearing, dist_m, runnerHeading, runnerSpeed, chaserSpeed) { + # from Leto + # needs: bearing, dist_m, runnerHeading, runnerSpeed, chaserSpeed + # dist_m > 0 and chaserSpeed > 0 + + #var bearing = 184;var dist_m=31000;var runnerHeading=186;var runnerSpeed= 200;var chaserSpeed=250; + + var trigAngle = 90-bearing; + var RunnerPosition = [dist_m*math.cos(trigAngle*D2R), dist_m*math.sin(trigAngle*D2R),0]; + var ChaserPosition = [0,0,0]; + + var VectorFromRunner = vector.Math.minus(ChaserPosition, RunnerPosition); + var runner_heading = 90-runnerHeading; + var RunnerVelocity = [runnerSpeed*math.cos(runner_heading*D2R), runnerSpeed*math.sin(runner_heading*D2R),0]; + + var a = chaserSpeed * chaserSpeed - runnerSpeed * runnerSpeed; + var b = 2 * vector.Math.dotProduct(VectorFromRunner, RunnerVelocity); + var c = -dist_m * dist_m; + + if ((b*b-4*a*c)<0) { + # intercept not possible + return nil; + } + var t1 = (-b+math.sqrt(b*b-4*a*c))/(2*a); + var t2 = (-b-math.sqrt(b*b-4*a*c))/(2*a); + + var timeToIntercept = 0; + if (t1 > 0 and t2 > 0) { + timeToIntercept = math.min(t1, t2); + } else { + timeToIntercept = math.max(t1, t2); + } + var InterceptPosition = vector.Math.plus(RunnerPosition, vector.Math.product(timeToIntercept, RunnerVelocity)); + + var ChaserVelocity = vector.Math.product(1/timeToIntercept, vector.Math.minus(InterceptPosition, ChaserPosition)); + + var interceptAngle = vector.Math.angleBetweenVectors([0,1,0], ChaserVelocity); + var interceptHeading = geo.normdeg(ChaserVelocity[0]<0?-interceptAngle:interceptAngle); + #print("output:"); + #print("time: " ~ timeToIntercept); + #print("heading: " ~ interceptHeading); + return [timeToIntercept, interceptHeading]; +} + +var purge_from_vector = func(vec, idx = nil, val = nil) { + if (idx == nil and val == nil) { return vec; } + var new_vec = []; + for (var i = 0; i < size(vec); i = i + 1) { + if ((idx != nil and i == idx) or (val != nil and val == vec[i])) { continue; } + append(new_vec, vec[i]); + } + return new_vec; +} + +var get_random = func() { + return int(rand() * 9999) +} + +var find_match = func(val,vec) { + if (size(vec) == 0) { + return 0; + } + foreach (var a; vec) { + #print(a); + if (a == val) { return 1; } + } + return 0; +} + +var remove_suffix = func(s, x) { + var len = size(x); + if (substr(s, -len) == x) + return substr(s, 0, size(s) - len); + return s; +} + +main_loop(); diff --git a/gci-radar/Nasal/radar-logic.nas b/gci-radar/Nasal/radar-logic.nas new file mode 100644 index 0000000..0e46e0a --- /dev/null +++ b/gci-radar/Nasal/radar-logic.nas @@ -0,0 +1,450 @@ +var clamp = func(v, min, max) { v < min ? min : v > max ? max : v } +var encode3bits = func(first, second, third) { + var integer = first; + integer = integer + 2 * second; + integer = integer + 4 * third; + return integer; +} +var versionString = getprop("sim/version/flightgear"); +var version = split(".", versionString); +var major = num(version[0]); +var minor = num(version[1]); +var pica = num(version[2]); +var pickingMethod = 0; +if ((major == 2017 and minor == 2 and pica >= 1) or (major == 2017 and minor > 2) or major > 2017) { + pickingMethod = 1; +} + +var FALSE = 0; +var TRUE = 1; + +var AIR = 0; +var MARINE = 1; +var SURFACE = 2; +var ORDNANCE = 3; + +var Contact = { + # For now only used in guided missiles, to make it compatible with Mirage 2000-5. + new: func(c, class) { + var obj = { parents : [Contact]}; +#debug.benchmark("radar process1", func { + obj.rdrProp = c.getNode("radar"); + obj.oriProp = c.getNode("orientation"); + obj.velProp = c.getNode("velocities"); + obj.posProp = c.getNode("position"); + obj.heading = obj.oriProp.getNode("true-heading-deg"); +#}); +#debug.benchmark("radar process2", func { + obj.alt = obj.posProp.getNode("altitude-ft"); + obj.lat = obj.posProp.getNode("latitude-deg"); + obj.lon = obj.posProp.getNode("longitude-deg"); +#}); +#debug.benchmark("radar process3", func { + #As it is a geo.Coord object, we have to update lat/lon/alt ->and alt is in meters + obj.coord = geo.Coord.new(); + obj.coord.set_latlon(obj.lat.getValue(), obj.lon.getValue(), obj.alt.getValue() * FT2M); +#}); +#debug.benchmark("radar process4", func { + obj.pitch = obj.oriProp.getNode("pitch-deg"); + obj.roll = obj.oriProp.getNode("roll-deg"); + obj.speed = obj.velProp.getNode("true-airspeed-kt"); + obj.vSpeed = obj.velProp.getNode("vertical-speed-fps"); + obj.callsign = c.getNode("callsign", 1); + obj.shorter = c.getNode("model-shorter"); + obj.orig_callsign = obj.callsign.getValue(); + obj.name = c.getNode("name"); + obj.sign = c.getNode("sign",1); + obj.valid = c.getNode("valid"); + obj.painted = c.getNode("painted"); + obj.unique = c.getNode("unique"); + obj.validTree = 0; +#}); +#debug.benchmark("radar process5", func { + #obj.transponderID = c.getNode("instrumentation/transponder/transmitted-id"); +#}); +#debug.benchmark("radar process6", func { + obj.acType = c.getNode("sim/model/ac-type"); + obj.type = c.getName(); + obj.index = c.getIndex(); + obj.string = "ai/models/" ~ obj.type ~ "[" ~ obj.index ~ "]"; + obj.shortString = obj.type ~ "[" ~ obj.index ~ "]"; +#}); +#debug.benchmark("radar process7", func { + obj.range = obj.rdrProp.getNode("range-nm"); + obj.bearing = obj.rdrProp.getNode("bearing-deg"); + obj.elevation = obj.rdrProp.getNode("elevation-deg"); +#}); + obj.deviation = nil; + + obj.node = c; + obj.class = class; + + obj.polar = [0,0]; + obj.cartesian = [0,0]; + + return obj; + }, + + isValid: func () { + var valid = me.valid.getValue(); + if (valid == nil) { + valid = FALSE; + } + if (me.callsign.getValue() != me.orig_callsign) { + valid = FALSE; + } + return valid; + }, + + isPainted: func () { + if (me.painted == nil) { + me.painted = me.node.getNode("painted"); + } + if (me.painted == nil) { + return nil; + } + var p = me.painted.getValue(); + return p; + }, + + getUnique: func () { + if (me.unique == nil) { + me.unique = me.node.getNode("unique"); + } + if (me.unique == nil) { + return nil; + } + var u = me.unique.getValue(); + return u; + }, + + getElevation: func() { + var e = 0; + e = me.elevation.getValue(); + if(e == nil or e == 0) { + # AI/MP has no radar properties + var self = geo.aircraft_position(); + me.get_Coord(); + var angleInv = clamp(self.distance_to(me.coord)/self.direct_distance_to(me.coord), -1, 1); + e = (self.alt()>me.coord.alt()?-1:1)*math.acos(angleInv)*R2D; + } + return e; + }, + + getNode: func () { + return me.node; + }, + + getFlareNode: func () { + return me.node.getNode("rotors/main/blade[3]/flap-deg"); + }, + + getChaffNode: func () { + return me.node.getNode("rotors/main/blade[3]/position-deg"); + }, + + setPolar: func(dist, angle) { + me.polar = [dist,angle]; + }, + + setCartesian: func(x, y) { + me.cartesian = [x,y]; + }, + + remove: func(){ + if(me.validTree != 0){ + me.validTree.setValue(0); + } + }, + + get_Coord: func(){ + me.coord.set_latlon(me.lat.getValue(), me.lon.getValue(), me.alt.getValue() * FT2M); + var TgTCoord = geo.Coord.new(me.coord); + return TgTCoord; + }, + + get_Callsign: func(){ + var n = me.callsign.getValue(); + if(n != "" and n != nil) { + return n; + } + if (me.name == nil) { + me.name = me.getNode().getNode("name"); + } + if (me.name == nil) { + n = ""; + } else { + n = me.name.getValue(); + } + if(n != "" and n != nil) { + return n; + } + n = me.sign.getValue(); + if(n != "" and n != nil) { + return n; + } + return "UFO"; + }, + + get_model: func(){ + var n = ""; + if (me.shorter == nil) { + me.shorter = me.node.getNode("model-shorter"); + } + if (me.shorter != nil) { + n = me.shorter.getValue(); + } + if(n != "" and n != nil) { + return n; + } + n = me.sign.getValue(); + if(n != "" and n != nil) { + return n; + } + if (me.name == nil) { + me.name = me.getNode().getNode("name"); + } + if (me.name == nil) { + n = ""; + } else { + n = me.name.getValue(); + } + if(n != "" and n != nil) { + return n; + } + return me.get_Callsign(); + }, + + get_Speed: func(){ + # return true airspeed + var n = me.speed.getValue(); + return n; + }, + + get_Longitude: func(){ + var n = me.lon.getValue(); + return n; + }, + + get_Latitude: func(){ + var n = me.lat.getValue(); + return n; + }, + + get_Pitch: func(){ + var n = me.pitch.getValue(); + return n; + }, + + isVirtual: func(){ + return 0; + }, + + get_Roll: func(){ + var n = me.roll.getValue(); + return n; + }, + + get_heading : func(){ + var n = me.heading.getValue(); + if(n == nil) + { + n = 0; + } + return n; + }, + + get_bearing: func(){ + var n = 0; + n = me.bearing.getValue(); + if(n == nil or n == 0) { + # AI/MP has no radar properties + n = me.get_bearing_from_Coord(geo.aircraft_position()); + } + return n; + }, + + get_bearing_from_Coord: func(MyAircraftCoord){ + me.get_Coord(); + var myBearing = 0; + if(me.coord.is_defined()) { + myBearing = MyAircraftCoord.course_to(me.coord); + } + return myBearing; + }, + + get_reciprocal_bearing: func(){ + return geo.normdeg(me.get_bearing() + 180); + }, + + get_deviation: func(true_heading_ref, coord){ + me.deviation = - deviation_normdeg(true_heading_ref, me.get_bearing_from_Coord(coord)); + return me.deviation; + }, + + get_altitude: func(){ + #Return Alt in feet + return me.alt.getValue(); + }, + + get_Elevation_from_Coord: func(MyAircraftCoord) { + me.get_Coord(); + var value = (me.coord.alt() - MyAircraftCoord.alt()) / me.coord.direct_distance_to(MyAircraftCoord); + if (math.abs(value) > 1) { + # warning this else will fail if logged in as observer and see aircraft on other side of globe + return 0; + } + var myPitch = math.asin(value) * R2D; + return myPitch; + }, + + get_total_elevation_from_Coord: func(own_pitch, MyAircraftCoord){ + var myTotalElevation = - deviation_normdeg(own_pitch, me.get_Elevation_from_Coord(MyAircraftCoord)); + return myTotalElevation; + }, + + get_total_elevation: func(own_pitch) { + me.deviation = - deviation_normdeg(own_pitch, me.getElevation()); + return me.deviation; + }, + + get_range: func() { + var r = 0; + if(me.range == nil or me.range.getValue() == nil or me.range.getValue() == 0) { + # AI/MP has no radar properties + me.get_Coord(); + r = me.coord.direct_distance_to(geo.aircraft_position()) * M2NM; + } else { + r = me.range.getValue(); + } + return r; + }, + + get_range_from_Coord: func(MyAircraftCoord) { + var myCoord = me.get_Coord(); + var myDistance = 0; + if(myCoord.is_defined()) { + myDistance = MyAircraftCoord.direct_distance_to(myCoord) * M2NM; + } + return myDistance; + }, + + get_type: func () { + return me.class; + }, + + get_cartesian: func() { + return me.cartesian; + }, + + get_polar: func() { + return me.polar; + }, +}; + +var isNotBehindTerrain = func( mp ) { + +########### + var pos = mp.getNode("position"); + var alt = pos.getNode("altitude-ft").getValue(); + var lat = pos.getNode("latitude-deg").getValue(); + var lon = pos.getNode("longitude-deg").getValue(); + if(alt == nil or lat == nil or lon == nil) { + return isVisible = 0; + } + var aircraftPos = geo.Coord.new().set_latlon(lat, lon, alt*0.3048); +################# + if (pickingMethod == 1) { + var myPos = geo.aircraft_position(); + myPos.set_latlon(myPos.lat(),myPos.lon(),myPos.alt()+50); + var xyz = {"x":myPos.x(), "y":myPos.y(), "z":myPos.z()}; + var dir = {"x":aircraftPos.x()-myPos.x(), "y":aircraftPos.y()-myPos.y(), "z":aircraftPos.z()-myPos.z()}; + + # Check for terrain between own aircraft and other: + v = get_cart_ground_intersection(xyz, dir); + if (v == nil) { + return 1; + #printf("No terrain, planes has clear view of each other"); + } else { + var terrain = geo.Coord.new(); + terrain.set_latlon(v.lat, v.lon, v.elevation); + var maxDist = myPos.direct_distance_to(aircraftPos); + var terrainDist = myPos.direct_distance_to(terrain); + if (terrainDist < maxDist) { + #printf("terrain found between SAM and aircraft %.1f meter away.", terrainDist); + return 0; + } else { + #print("The planes has clear view of each other"); + return 1; + } + } + } else { + var isVisible = 0; + var MyCoord = geo.aircraft_position(); + + # Because there is no terrain on earth that can be between these 2 + if(MyCoord.alt() < 8900 and aircraftPos.alt() < 8900) + { + # Temporary variable + # A (our plane) coord in meters + var a = MyCoord.x(); + var b = MyCoord.y(); + var c = MyCoord.z(); + # B (target) coord in meters + var d = aircraftPos.x(); + var e = aircraftPos.y(); + var f = aircraftPos.z(); + var difa = d - a; + var difb = e - b; + var difc = f - c; + # direct Distance in meters + var myDistance = math.sqrt( math.pow((d-a),2) + math.pow((e-b),2) + math.pow((f-c),2)); #calculating distance ourselves to avoid another call to geo.nas (read: speed, probably). + var Aprime = geo.Coord.new(); + + # Here is to limit FPS drop on very long distance + var L = 500; + if(myDistance > 50000) + { + L = myDistance / 15; + } + var step = L; + var maxLoops = int(myDistance / L); + + isVisible = 1; + # This loop will make travel a point between us and the target and check if there is terrain + for(var i = 1 ; i <= maxLoops ; i += 1) + { + #calculate intermediate step + #basically dividing the line into maxLoops number of steps, and checking at each step + #to ascii-art explain it: + # |us|----------|step 1|-----------|step 2|--------|step 3|----------|them| + #there will be as many steps as there is i + #every step will be equidistant + + #also, if i == 0 then the first step will be our plane + + var x = ((difa/(maxLoops+1))*i)+a; + var y = ((difb/(maxLoops+1))*i)+b; + var z = ((difc/(maxLoops+1))*i)+c; + #print("i:" ~ i ~ "|x,y,z | " ~ x ~ "," ~ y ~ "," ~ z); + Aprime.set_xyz(x,y,z); + var AprimeTerrainAlt = geo.elevation(Aprime.lat(), Aprime.lon()); + if(AprimeTerrainAlt == nil) + { + AprimeTerrainAlt = 0; + } + + if(AprimeTerrainAlt > Aprime.alt()) + { + #print("behind terrain"); + return 0; + } + } + } + else + { + isVisible = 1; + } + return isVisible; + } +} \ No newline at end of file diff --git a/gci-radar/Nasal/vector.nas b/gci-radar/Nasal/vector.nas new file mode 100644 index 0000000..8e0bff6 --- /dev/null +++ b/gci-radar/Nasal/vector.nas @@ -0,0 +1,303 @@ +var Math = { + # + # Author: Nikolai V. Chr. + # + # Version 1.6 + # + # When doing euler coords. to cartesian: +x = forw, +y = left, +z = up. + # FG struct. coords: +x = back, +y = right, +z = up. + # + # When doing euler angles (from pilots point of view): yaw = yaw left, pitch = rotate up, roll = roll right. + # FG rotations: heading = yaw right, pitch = rotate up, roll = roll right. + # + clamp: func(v, min, max) { v < min ? min : v > max ? max : v }, + + convertCoords: func (x,y,z) { + return [-x, -y, z]; + }, + + convertAngles: func (heading,pitch,roll) { + return [-heading, pitch, roll]; + }, + + # angle between 2 vectors. Returns 0-180 degrees. + angleBetweenVectors: func (a,b) { + a = me.normalize(a); + b = me.normalize(b); + me.value = me.clamp((me.dotProduct(a,b)/me.magnitudeVector(a))/me.magnitudeVector(b),-1,1);#just to be safe in case some floating point error makes it out of bounds + return R2D * math.acos(me.value); + }, + + # length of vector + magnitudeVector: func (a) { + return math.sqrt(math.pow(a[0],2)+math.pow(a[1],2)+math.pow(a[2],2)); + }, + + # dot product of 2 vectors + dotProduct: func (a,b) { + return a[0]*b[0]+a[1]*b[1]+a[2]*b[2]; + }, + + # rotate a vector. Order: roll, pitch, yaw + rollPitchYawVector: func (roll, pitch, yaw, vector) { + me.rollM = me.rollMatrix(roll); + me.pitchM = me.pitchMatrix(pitch); + me.yawM = me.yawMatrix(yaw); + me.rotation = me.multiplyMatrices(me.multiplyMatrices(me.yawM, me.pitchM), me.rollM); + return me.multiplyMatrixWithVector(me.rotation, vector); + }, + + # rotate a vector. Order: yaw, pitch, roll (like an aircraft) + yawPitchRollVector: func (yaw, pitch, roll, vector) { + me.rollM = me.rollMatrix(roll); + me.pitchM = me.pitchMatrix(pitch); + me.yawM = me.yawMatrix(yaw); + me.rotation = me.multiplyMatrices(me.multiplyMatrices(me.rollM, me.pitchM), me.yawM); + return me.multiplyMatrixWithVector(me.rotation, vector); + }, + + # multiply 3x3 matrix with vector + multiplyMatrixWithVector: func (matrix, vector) { + return [matrix[0]*vector[0]+matrix[1]*vector[1]+matrix[2]*vector[2], + matrix[3]*vector[0]+matrix[4]*vector[1]+matrix[5]*vector[2], + matrix[6]*vector[0]+matrix[7]*vector[1]+matrix[8]*vector[2]]; + }, + + # multiply 2 3x3 matrices + multiplyMatrices: func (a,b) { + return [a[0]*b[0]+a[1]*b[3]+a[2]*b[6], a[0]*b[1]+a[1]*b[4]+a[2]*b[7], a[0]*b[2]+a[1]*b[5]+a[2]*b[8], + a[3]*b[0]+a[4]*b[3]+a[5]*b[6], a[3]*b[1]+a[4]*b[4]+a[5]*b[7], a[3]*b[2]+a[4]*b[5]+a[5]*b[8], + a[6]*b[0]+a[7]*b[3]+a[8]*b[6], a[6]*b[1]+a[7]*b[4]+a[8]*b[7], a[6]*b[2]+a[7]*b[5]+a[8]*b[8]]; + }, + + # matrix for rolling + rollMatrix: func (roll) { + roll = roll * D2R; + return [1,0,0, + 0,math.cos(roll),-math.sin(roll), + 0,math.sin(roll), math.cos(roll)]; + }, + + # matrix for pitching + pitchMatrix: func (pitch) { + pitch = pitch * D2R; + return [math.cos(pitch),0,-math.sin(pitch), + 0,1,0, + math.sin(pitch),0,math.cos(pitch)]; + }, + + # matrix for yawing + yawMatrix: func (yaw) { + yaw = yaw * D2R; + return [math.cos(yaw),-math.sin(yaw),0, + math.sin(yaw),math.cos(yaw),0, + 0,0,1]; + }, + + # vector to heading/pitch + cartesianToEuler: func (vector) { + me.horz = math.sqrt(vector[0]*vector[0]+vector[1]*vector[1]); + if (me.horz != 0) { + me.pitch = math.atan2(vector[2],me.horz)*R2D; + me.hdg = math.asin(-vector[1]/me.horz)*R2D; + + if (vector[0] < 0) { + # south + if (me.hdg >= 0) { + me.hdg = 180-me.hdg; + } else { + me.hdg = -180-me.hdg; + } + } + me.hdg = geo.normdeg(me.hdg); + } else { + me.pitch = vector[2]>=0?90:-90; + me.hdg = nil; + } + return [me.hdg, me.pitch]; + }, + + # gives an vector that points up from fuselage + eulerToCartesian3Z: func (yaw_deg, pitch_deg, roll_deg) { + me.yaw = yaw_deg * D2R; + me.pitch = pitch_deg * D2R; + me.roll = roll_deg * D2R; + me.x = -math.cos(me.yaw)*math.sin(me.pitch)*math.cos(me.roll) + math.sin(me.yaw)*math.sin(me.roll); + me.y = -math.sin(me.yaw)*math.sin(me.pitch)*math.cos(me.roll) - math.cos(me.yaw)*math.sin(me.roll); + me.z = math.cos(me.pitch)*math.cos(me.roll);#roll changed from sin to cos, since the rotation matrix is wrong + return [me.x,me.y,me.z]; + }, + + # gives an vector that points forward from fuselage + eulerToCartesian3X: func (yaw_deg, pitch_deg, roll_deg) { + me.yaw = yaw_deg * D2R; + me.pitch = pitch_deg * D2R; + me.roll = roll_deg * D2R; + me.x = math.cos(me.yaw)*math.cos(me.pitch); + me.y = math.sin(me.yaw)*math.cos(me.pitch); + me.z = math.sin(me.pitch); + return [me.x,me.y,me.z]; + }, + + # gives an vector that points left from fuselage + eulerToCartesian3Y: func (yaw_deg, pitch_deg, roll_deg) { + me.yaw = yaw_deg * D2R; + me.pitch = pitch_deg * D2R; + me.roll = roll_deg * D2R; + me.x = -math.cos(me.yaw)*math.sin(me.pitch)*math.sin(me.roll) - math.sin(me.yaw)*math.cos(me.roll); + me.y = -math.sin(me.yaw)*math.sin(me.pitch)*math.sin(me.roll) + math.cos(me.yaw)*math.cos(me.roll); + me.z = math.cos(me.pitch)*math.sin(me.roll); + return [me.x,me.y,me.z]; + }, + + # same as eulerToCartesian3X, except it needs no roll + eulerToCartesian2: func (yaw_deg, pitch_deg) { + me.yaw = yaw_deg * D2R; + me.pitch = pitch_deg * D2R; + me.x = math.cos(me.pitch) * math.cos(me.yaw); + me.y = math.cos(me.pitch) * math.sin(me.yaw); + me.z = math.sin(me.pitch); + return [me.x,me.y,me.z]; + }, + + #pitch from coord1 to coord2 in degrees (takes curvature of earth into effect.) + getPitch: func (coord1, coord2) { + if (coord1.lat() == coord2.lat() and coord1.lon() == coord2.lon()) { + if (coord2.alt() > coord1.alt()) { + return 90; + } elsif (coord2.alt() < coord1.alt()) { + return -90; + } else { + return 0; + } + } + if (coord1.alt() != coord2.alt()) { + me.d12 = coord1.direct_distance_to(coord2); + me.coord3 = geo.Coord.new(coord1); + me.coord3.set_alt(coord1.alt()-me.d12*0.5);# this will increase the area of the triangle so that rounding errors dont get in the way. + me.d13 = coord1.alt()-me.coord3.alt(); + if (me.d12 == 0) { + # on top of each other, maybe rounding error.. + return 0; + } + me.d32 = me.coord3.direct_distance_to(coord2); + if (math.abs(me.d13)+me.d32 < me.d12) { + # rounding errors somewhere..one triangle side is longer than other 2 sides combined. + return 0; + } + # standard formula for a triangle where all 3 side lengths are known: + me.len = (math.pow(me.d12, 2)+math.pow(me.d13,2)-math.pow(me.d32, 2))/(2 * me.d12 * math.abs(me.d13)); + if (me.len < -1 or me.len > 1) { + # something went wrong, maybe rounding error.. + return 0; + } + me.angle = R2D * math.acos(me.len); + me.pitch = -1* (90 - me.angle); + #printf("d12 %.4f d32 %.4f d13 %.4f len %.4f pitch %.4f angle %.4f", me.d12, me.d32, me.d13, me.len, me.pitch, me.angle); + return me.pitch; + } else { + # same altitude + me.nc = geo.Coord.new(); + me.nc.set_xyz(0,0,0); # center of earth + me.radiusEarth = coord1.direct_distance_to(me.nc);# current distance to earth center + me.d12 = coord1.direct_distance_to(coord2); + # standard formula for a triangle where all 3 side lengths are known: + me.len = (math.pow(me.d12, 2)+math.pow(me.radiusEarth,2)-math.pow(me.radiusEarth, 2))/(2 * me.d12 * me.radiusEarth); + if (me.len < -1 or me.len > 1) { + # something went wrong, maybe rounding error.. + return 0; + } + me.angle = R2D * math.acos(me.len); + me.pitch = -1* (90 - me.angle); + return me.pitch; + } + }, + + # supply a normal to the plane, and a vector. The vector will be projected onto the plane, and that projection is returned as a vector. + projVectorOnPlane: func (planeNormal, vector) { + return me.minus(vector, me.product(me.dotProduct(vector,planeNormal)/math.pow(me.magnitudeVector(planeNormal),2), planeNormal)); + }, + + # vector a - vector b + minus: func (a, b) { + return [a[0]-b[0], a[1]-b[1], a[2]-b[2]]; + }, + + # vector a + vector b + plus: func (a, b) { + return [a[0]+b[0], a[1]+b[1], a[2]+b[2]]; + }, + + # float * vector + product: func (scalar, vector) { + return [scalar*vector[0], scalar*vector[1], scalar*vector[2]] + }, + + # print vector to console + format: func (v) { + return sprintf("(%.1f, %.1f, %.1f)",v[0],v[1],v[2]); + }, + + # make vector length 1.0 + normalize: func (v) { + me.mag = me.magnitudeVector(v); + return [v[0]/me.mag, v[1]/me.mag, v[2]/me.mag]; + }, + +# rotation matrices +# +# +#| 1 0 0 | +#| 0 cos(roll) -sin(roll) | +#| 0 sin(roll) cos(roll) | +# +#| cos(pitch) 0 -sin(pitch) | +#| 0 1 0 | +#| sin(pitch) 0 cos(pitch) | +# +#| cos(yaw) -sin(yaw) 0 | +#| sin(yaw) cos(yaw) 0 | +#| 0 0 1 | +# +# combined matrix from yaw, pitch, roll: +# +#| cos(yaw)cos(pitch) -cos(yaw)sin(pitch)sin(roll)-sin(yaw)cos(roll) -cos(yaw)sin(pitch)cos(roll)+sin(yaw)sin(roll)| +#| sin(yaw)cos(pitch) -sin(yaw)sin(pitch)sin(roll)+cos(yaw)cos(roll) -sin(yaw)sin(pitch)cos(roll)-cos(yaw)sin(roll)| +#| sin(pitch) cos(pitch)sin(roll) cos(pitch)cos(roll)| +# +# + +}; + +# Fix for geo.Coord: (not needed in FG 2017.4+) +geo.Coord.set_x = func(x) { me._cupdate(); me._pdirty = 1; me._x = x; me }; +geo.Coord.set_y = func(y) { me._cupdate(); me._pdirty = 1; me._y = y; me }; +geo.Coord.set_z = func(z) { me._cupdate(); me._pdirty = 1; me._z = z; me }; +geo.Coord.set_lat = func(lat) { me._pupdate(); me._cdirty = 1; me._lat = lat * D2R; me }; +geo.Coord.set_lon = func(lon) { me._pupdate(); me._cdirty = 1; me._lon = lon * D2R; me }; +geo.Coord.set_alt = func(alt) { me._pupdate(); me._cdirty = 1; me._alt = alt; me }; +geo.Coord.apply_course_distance2 = func(course, dist) {# this method in geo is not bad, just wanted to see if this way of doing it worked better. + me._pupdate(); + course *= D2R; + var nc = geo.Coord.new(); + nc.set_xyz(0,0,0); # center of earth + dist /= me.direct_distance_to(nc);# current distance to earth center + + if (dist < 0.0) { + dist = abs(dist); + course = course - math.pi; + } + + me._lat2 = math.asin(math.sin(me._lat) * math.cos(dist) + math.cos(me._lat) * math.sin(dist) * math.cos(course)); + + me._lon = me._lon + math.atan2(math.sin(course)*math.sin(dist)*math.cos(me._lat),math.cos(dist)-math.sin(me._lat)*math.sin(me._lat2)); + + while (me._lon <= -math.pi) + me._lon += math.pi*2; + while (me._lon > math.pi) + me._lon -= math.pi*2; + + me._lat = me._lat2; + me._cdirty = 1; + me; + }; \ No newline at end of file diff --git a/tower/Sounds/sound.xml b/gci-radar/Sounds/sound.xml similarity index 100% rename from tower/Sounds/sound.xml rename to gci-radar/Sounds/sound.xml diff --git a/tower/Systems/fbw.xml b/gci-radar/Systems/fbw.xml similarity index 100% rename from tower/Systems/fbw.xml rename to gci-radar/Systems/fbw.xml diff --git a/tower/Systems/fdm.xml b/gci-radar/Systems/fdm.xml similarity index 100% rename from tower/Systems/fdm.xml rename to gci-radar/Systems/fdm.xml diff --git a/gci-radar/gci-set.xml b/gci-radar/gci-set.xml new file mode 100644 index 0000000..d92b5d2 --- /dev/null +++ b/gci-radar/gci-set.xml @@ -0,0 +1,112 @@ + + + + + + false + + + + pinto + gci + alpha + 0.1 + + null + + + + + + Aircraft/gci-radar/Models/gci.xml + true + + + + true + + + + + + + true + + + enemies + + dialog-show + enemies + + + + + + + + Leto + swamp + pinto + fb237 + Wilco-1 + Kokos + J-Mav16 + S + Raider1 + Slobb + 5H1N0B1 + SNOWY1 + false + false + + + + + enemies/e1 + enemies/e2 + enemies/e3 + enemies/e4 + enemies/e5 + enemies/e6 + enemies/e7 + enemies/e8 + enemies/e9 + enemies/e10 + enemies/e11 + enemies/e12 + enemies/opfor-switch + enemies/friend-switch + + + + Aircraft/gci-radar/splash1.png + + + + 0.0 + 0.0 + + 100.0 + 2000.0 + + + + + 0 + + 500 + + + + + false + + + + Aircraft/gci-radar/Nasal/damage.nas + Aircraft/gci-radar/Nasal/radar-logic.nas + Aircraft/gci-radar/Nasal/gci.nas + Aircraft/gci-radar/Nasal/vector.nas + + + diff --git a/gci-radar/gui/1.png b/gci-radar/gui/1.png new file mode 100644 index 0000000..6448d28 Binary files /dev/null and b/gci-radar/gui/1.png differ diff --git a/gci-radar/gui/2.png b/gci-radar/gui/2.png new file mode 100644 index 0000000..4367ab7 Binary files /dev/null and b/gci-radar/gui/2.png differ diff --git a/gci-radar/gui/dialogs/enemies.xml b/gci-radar/gui/dialogs/enemies.xml new file mode 100644 index 0000000..67f39af --- /dev/null +++ b/gci-radar/gui/dialogs/enemies.xml @@ -0,0 +1,348 @@ + + + enemies + false + vbox + true + true + 250 + 550 + + + hbox + 1 + + + + + + 1 + + + + + + + 25 + + + + 250 + 25 + + enemies/e1 + true + left + + dialog-apply + + + 1 + 0.5 + 0.5 + + + + enemies/opfor-switch + + + enemies/friend-switch + + + + + 250 + 25 + + enemies/e2 + true + left + + dialog-apply + + + 1 + 0.5 + 0.5 + + + + enemies/opfor-switch + + + enemies/friend-switch + + + + + 250 + 25 + + enemies/e3 + true + left + + dialog-apply + + + 1 + 0.5 + 0.5 + + + + enemies/opfor-switch + + + enemies/friend-switch + + + + + 250 + 25 + + enemies/e4 + true + left + + dialog-apply + + + 1 + 0.5 + 0.5 + + + + enemies/opfor-switch + + + enemies/friend-switch + + + + + 250 + 25 + + enemies/e5 + true + left + + dialog-apply + + + 1 + 0.5 + 0.5 + + + + enemies/opfor-switch + + + enemies/friend-switch + + + + + 250 + 25 + + enemies/e6 + true + left + + dialog-apply + + + 1 + 0.5 + 0.5 + + + + enemies/opfor-switch + + + enemies/friend-switch + + + + + 250 + 25 + + enemies/e7 + true + left + + dialog-apply + + + 1 + 0.5 + 0.5 + + + + enemies/opfor-switch + + + enemies/friend-switch + + + + + 250 + 25 + + enemies/e8 + true + left + + dialog-apply + + + 1 + 0.5 + 0.5 + + + + enemies/opfor-switch + + + enemies/friend-switch + + + + + 250 + 25 + + enemies/e9 + true + left + + dialog-apply + + + 1 + 0.5 + 0.5 + + + + enemies/opfor-switch + + + enemies/friend-switch + + + + + 250 + 25 + + enemies/e10 + true + left + + dialog-apply + + + 1 + 0.5 + 0.5 + + + + enemies/opfor-switch + + + enemies/friend-switch + + + + + 250 + 25 + + enemies/e11 + true + left + + dialog-apply + + + 1 + 0.5 + 0.5 + + + + enemies/opfor-switch + + + enemies/friend-switch + + + + + 250 + 25 + + enemies/e12 + true + left + + dialog-apply + + + 1 + 0.5 + 0.5 + + + + enemies/opfor-switch + + + enemies/friend-switch + + + + + 12 + 12 + /enemies/opfor-switch + + + dialog-apply + + + + 12 + 12 + /enemies/friend-switch + + + dialog-apply + + + \ No newline at end of file diff --git a/tower/splash1.png b/gci-radar/splash1.png similarity index 100% rename from tower/splash1.png rename to gci-radar/splash1.png diff --git a/tower/Dialogs/control-panel.xml b/tower/Dialogs/control-panel.xml deleted file mode 100644 index e6a5f9e..0000000 --- a/tower/Dialogs/control-panel.xml +++ /dev/null @@ -1,330 +0,0 @@ - - - - - - - control-panel - vbox - 250 - false - - - hbox - - true - - - - true - - - - - - - - vbox - 6 - - - - - - table - - - - 0 - 1 - - - - - - - - - - 2 - 1 - - - - - - - - - - 4 - 0 - - - - - 4 - 1 - - - - - - - - - - - - - - - - - vbox - 6 - - - - - - vbox - - - left - - /controls/lighting/deck-lights - true - - dialog-apply - - - property-toggle - - - - - left - - /carrier/antennas/enabled - true - - dialog-apply - - - property-toggle - - - - - - - - - vbox - 6 - - - - - - vbox - - - left - - /carrier/fdm/settings/movement - true - - dialog-apply - - - property-toggle - - - - - left - - /carrier/phalanx/settings/show-debug-aim - true - - dialog-apply - - - property-toggle - - - - - - - - - hbox - 6 - - true - - - - - diff --git a/tower/Dialogs/menu.xml b/tower/Dialogs/menu.xml deleted file mode 100644 index a34d397..0000000 --- a/tower/Dialogs/menu.xml +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - - - - - true - - - - - dialog-show - control-panel - - - - - - - diff --git a/tower/Models/towerSnowy1.ac b/tower/Models/towerSnowy1.ac deleted file mode 100644 index 423ec0d..0000000 --- a/tower/Models/towerSnowy1.ac +++ /dev/null @@ -1,563 +0,0 @@ -AC3Db -MATERIAL "Color_M07" rgb 0.227 0.227 0.227 amb 1.000 1.000 1.000 emis 0.000 0.000 0.000 spec 0.500 0.500 0.500 shi 12 trans 0.000 -MATERIAL "Color_M03" rgb 0.667 0.667 0.667 amb 1.000 1.000 1.000 emis 0.000 0.000 0.000 spec 0.500 0.500 0.500 shi 12 trans 0.000 -MATERIAL "Translucent_Glass_Blue" rgb 0.392 0.584 0.929 amb 1.000 1.000 1.000 emis 0.000 0.000 0.000 spec 0.500 0.500 0.500 shi 12 trans 0.502 -OBJECT world -name "Blender_exporter_v2.17__towerSnowy1.ac" -kids 5 -OBJECT poly -name "door" -data 4 -ID11 -crease 40.0 -numvert 4 -2 2 0 -1 0 0 -2 0 0 -1 2 0 -numsurf 2 -SURF 0X10 -mat 0 -refs 3 -0 0 0 -1 0 0 -2 0 0 -SURF 0X10 -mat 0 -refs 3 -1 0 0 -0 0 0 -3 0 0 -kids 0 -OBJECT poly -name "floor" -data 4 -ID33 -crease 40.0 -numvert 32 -3.75 13 -7.25 -4 12 -3 -3.75 13 -2.75 -4 12 -7 -4 12 -7 -3.75 13 -7.25 -4 12 -3 -3.75 13 -2.75 -8.25 13 -2.75 -4 12 -3 -8 12 -3 -3.75 13 -2.75 -3.75 13 -2.75 -8.25 13 -2.75 -4 12 -3 -8 12 -3 -3.75 13 -7.25 -8 12 -7 -4 12 -7 -8.25 13 -7.25 -8.25 13 -7.25 -3.75 13 -7.25 -8 12 -7 -4 12 -7 -8 12 -3 -8.25 13 -7.25 -8.25 13 -2.75 -8 12 -7 -8 12 -7 -8 12 -3 -8.25 13 -7.25 -8.25 13 -2.75 -numsurf 16 -SURF 0X10 -mat 1 -refs 3 -0 0 0 -1 0 0 -2 0 0 -SURF 0X10 -mat 1 -refs 3 -1 0 0 -0 0 0 -3 0 0 -SURF 0X10 -mat 1 -refs 3 -4 0 0 -5 0 0 -6 0 0 -SURF 0X10 -mat 1 -refs 3 -7 0 0 -6 0 0 -5 0 0 -SURF 0X10 -mat 1 -refs 3 -8 0 0 -9 0 0 -10 0 0 -SURF 0X10 -mat 1 -refs 3 -9 0 0 -8 0 0 -11 0 0 -SURF 0X10 -mat 1 -refs 3 -12 0 0 -13 0 0 -14 0 0 -SURF 0X10 -mat 1 -refs 3 -15 0 0 -14 0 0 -13 0 0 -SURF 0X10 -mat 1 -refs 3 -16 0 0 -17 0 0 -18 0 0 -SURF 0X10 -mat 1 -refs 3 -17 0 0 -16 0 0 -19 0 0 -SURF 0X10 -mat 1 -refs 3 -20 0 0 -21 0 0 -22 0 0 -SURF 0X10 -mat 1 -refs 3 -23 0 0 -22 0 0 -21 0 0 -SURF 0X10 -mat 1 -refs 3 -24 0 0 -25 0 0 -26 0 0 -SURF 0X10 -mat 1 -refs 3 -25 0 0 -24 0 0 -27 0 0 -SURF 0X10 -mat 1 -refs 3 -28 0 0 -29 0 0 -30 0 0 -SURF 0X10 -mat 1 -refs 3 -31 0 0 -30 0 0 -29 0 0 -kids 0 -OBJECT poly -name "glass" -data 4 -ID19 -crease 40.0 -numvert 32 -3 16 -8 -8.25 13 -7.25 -3.75 13 -7.25 -9 16 -8 -9 16 -8 -3 16 -8 -8.25 13 -7.25 -3.75 13 -7.25 -8.25 13 -2.75 -9 16 -8 -9 16 -2 -8.25 13 -7.25 -8.25 13 -7.25 -8.25 13 -2.75 -9 16 -8 -9 16 -2 -3 16 -8 -3.75 13 -2.75 -3 16 -2 -3.75 13 -7.25 -3.75 13 -7.25 -3 16 -8 -3.75 13 -2.75 -3 16 -2 -9 16 -2 -3.75 13 -2.75 -8.25 13 -2.75 -3 16 -2 -3 16 -2 -9 16 -2 -3.75 13 -2.75 -8.25 13 -2.75 -numsurf 16 -SURF 0X10 -mat 2 -refs 3 -0 0 0 -1 0 0 -2 0 0 -SURF 0X10 -mat 2 -refs 3 -1 0 0 -0 0 0 -3 0 0 -SURF 0X10 -mat 2 -refs 3 -4 0 0 -5 0 0 -6 0 0 -SURF 0X10 -mat 2 -refs 3 -7 0 0 -6 0 0 -5 0 0 -SURF 0X10 -mat 2 -refs 3 -8 0 0 -9 0 0 -10 0 0 -SURF 0X10 -mat 2 -refs 3 -9 0 0 -8 0 0 -11 0 0 -SURF 0X10 -mat 2 -refs 3 -12 0 0 -13 0 0 -14 0 0 -SURF 0X10 -mat 2 -refs 3 -15 0 0 -14 0 0 -13 0 0 -SURF 0X10 -mat 2 -refs 3 -16 0 0 -17 0 0 -18 0 0 -SURF 0X10 -mat 2 -refs 3 -17 0 0 -16 0 0 -19 0 0 -SURF 0X10 -mat 2 -refs 3 -20 0 0 -21 0 0 -22 0 0 -SURF 0X10 -mat 2 -refs 3 -23 0 0 -22 0 0 -21 0 0 -SURF 0X10 -mat 2 -refs 3 -24 0 0 -25 0 0 -26 0 0 -SURF 0X10 -mat 2 -refs 3 -25 0 0 -24 0 0 -27 0 0 -SURF 0X10 -mat 2 -refs 3 -28 0 0 -29 0 0 -30 0 0 -SURF 0X10 -mat 2 -refs 3 -31 0 0 -30 0 0 -29 0 0 -kids 0 -OBJECT poly -name "roof" -data 4 -ID27 -crease 40.0 -numvert 4 -9 16 -2 -3 16 -8 -3 16 -2 -9 16 -8 -numsurf 2 -SURF 0X10 -mat 1 -refs 3 -0 0 0 -1 0 0 -2 0 0 -SURF 0X10 -mat 1 -refs 3 -1 0 0 -0 0 0 -3 0 0 -kids 0 -OBJECT poly -name "structure" -data 3 -ID3 -crease 40.0 -numvert 48 -8 0 -7 -0 0 0 -0 0 -7 -1 0 0 -2 0 0 -8 0 0 -8 3 0 -2 0 0 -8 0 0 -2 2 0 -1 2 0 -0 0 0 -1 0 0 -0 3 0 -0 3 -7 -0 0 0 -0 3 0 -0 0 -7 -0 3 -7 -8 0 -7 -0 0 -7 -4 3 -7 -8 12 -7 -4 12 -7 -8 0 -7 -8 3 0 -8 0 0 -8 3 -3 -8 12 -3 -8 12 -7 -0 3 0 -4 3 -3 -0 3 -7 -8 3 0 -8 3 -3 -4 3 -7 -4 12 -7 -4 3 -3 -4 12 -3 -4 3 -7 -8 12 -3 -4 12 -7 -4 12 -3 -8 12 -7 -8 12 -3 -4 3 -3 -8 3 -3 -4 12 -3 -numsurf 30 -SURF 0X10 -mat 1 -refs 3 -0 0 0 -1 0 0 -2 0 0 -SURF 0X10 -mat 1 -refs 3 -1 0 0 -0 0 0 -3 0 0 -SURF 0X10 -mat 1 -refs 3 -3 0 0 -0 0 0 -4 0 0 -SURF 0X10 -mat 1 -refs 3 -4 0 0 -0 0 0 -5 0 0 -SURF 0X10 -mat 1 -refs 3 -6 0 0 -7 0 0 -8 0 0 -SURF 0X10 -mat 1 -refs 3 -7 0 0 -6 0 0 -9 0 0 -SURF 0X10 -mat 1 -refs 3 -9 0 0 -6 0 0 -10 0 0 -SURF 0X10 -mat 1 -refs 3 -10 0 0 -11 0 0 -12 0 0 -SURF 0X10 -mat 1 -refs 3 -11 0 0 -10 0 0 -13 0 0 -SURF 0X10 -mat 1 -refs 3 -13 0 0 -10 0 0 -6 0 0 -SURF 0X10 -mat 1 -refs 3 -14 0 0 -15 0 0 -16 0 0 -SURF 0X10 -mat 1 -refs 3 -15 0 0 -14 0 0 -17 0 0 -SURF 0X10 -mat 1 -refs 3 -18 0 0 -19 0 0 -20 0 0 -SURF 0X10 -mat 1 -refs 3 -19 0 0 -18 0 0 -21 0 0 -SURF 0X10 -mat 1 -refs 3 -19 0 0 -21 0 0 -22 0 0 -SURF 0X10 -mat 1 -refs 3 -22 0 0 -21 0 0 -23 0 0 -SURF 0X10 -mat 1 -refs 3 -24 0 0 -25 0 0 -26 0 0 -SURF 0X10 -mat 1 -refs 3 -25 0 0 -24 0 0 -27 0 0 -SURF 0X10 -mat 1 -refs 3 -27 0 0 -24 0 0 -28 0 0 -SURF 0X10 -mat 1 -refs 3 -28 0 0 -24 0 0 -29 0 0 -SURF 0X10 -mat 1 -refs 3 -30 0 0 -31 0 0 -32 0 0 -SURF 0X10 -mat 1 -refs 3 -31 0 0 -30 0 0 -33 0 0 -SURF 0X10 -mat 1 -refs 3 -31 0 0 -33 0 0 -34 0 0 -SURF 0X10 -mat 1 -refs 3 -35 0 0 -32 0 0 -31 0 0 -SURF 0X10 -mat 1 -refs 3 -36 0 0 -37 0 0 -38 0 0 -SURF 0X10 -mat 1 -refs 3 -37 0 0 -36 0 0 -39 0 0 -SURF 0X10 -mat 1 -refs 3 -40 0 0 -41 0 0 -42 0 0 -SURF 0X10 -mat 1 -refs 3 -41 0 0 -40 0 0 -43 0 0 -SURF 0X10 -mat 1 -refs 3 -44 0 0 -45 0 0 -46 0 0 -SURF 0X10 -mat 1 -refs 3 -45 0 0 -44 0 0 -47 0 0 -kids 0 diff --git a/tower/Nasal/damage.nas b/tower/Nasal/damage.nas deleted file mode 100644 index 848eaaf..0000000 --- a/tower/Nasal/damage.nas +++ /dev/null @@ -1,126 +0,0 @@ -var clamp = func(v, min, max) { v < min ? min : v > max ? max : v } - -var TRUE = 1; -var FALSE = 0; - -# -# Install: Include this code into an aircraft to make it damagable. (remember to add it to the -set file) -# -# Author: Nikolai V. Chr. (with some improvement by Onox and Pinto) -# -# - -var cannon_types = { - " M70 rocket hit": 0.25, #135mm - " M55 cannon shell hit": 0.10, # 30mm - " KCA cannon shell hit": 0.10, # 30mm - " Gun Splash On ": 0.10, # 30mm - " M61A1 shell hit": 0.05, # 20mm - " GAU-8/A hit": 0.10, # 30mm - " BK27 cannon hit": 0.07, # 27mm - " GSh-30 hit": 0.10, # 30mm - " 7.62 hit": 0.30, #UH-1 - " 50 BMG hit": 0.20, #p-47 -}; - -var players = { - "pinto": 1, - "OPFOR77": 2, - "Leto": 1, - "swamp": 2, -}; - -var incoming_listener = func { - var history = getprop("/sim/multiplay/chat-history"); - var hist_vector = split("\n", history); - if (size(hist_vector) > 0) { - var last = hist_vector[size(hist_vector)-1]; - var last_vector = split(":", last); - var author = last_vector[0]; - var callsign = getprop("sim/multiplay/callsign"); - if (size(last_vector) > 1 and author != callsign) { - # not myself - #print("not me"); - if (1==1) { # mirage: getprop("/controls/armament/mp-messaging") - # latest version of failure manager and taking damage enabled - #print("damage enabled"); - var last1 = split(" ", last_vector[1]); - if (cannon_types[last_vector[1]] != nil) { - # cannon hitting someone - print("cannon"); - if (size(last_vector) > 2 and last_vector[2] == " "~callsign) { - print("cannon hit us"); - process_hit(author); - } - } - } - } - } -} - -var last_update_time = "/aa_tower/last-update-time"; -var owning_team = "/aa_tower/owning_team"; -var score_team_1 = "/aa_tower/score-team-1"; -var score_team_2 = "/aa_tower/score-team-2"; -setprop(last_update_time, -1); -setprop(owning_team, 0); -setprop(score_team_1, 0); -setprop(score_team_2, 0); - -var process_hit = func (perp) { - print("processing hit by: " ~ perp); - if ( players[perp] != nil ) { - if ( players[perp] != getprop(owning_team) ) { - setprop(last_update_time,systime()); - setprop(owning_team, players[perp]); - setprop("/aa_tower/score-team-" ~ players[perp], getprop("/aa_tower/score-team-" ~ players[perp]) + 1); - setprop("/sim/multiplay/chat","Ownership transferred to team: " ~ players[perp]); - write_xml(); - } - } -} - -var update = func () { - var o_t = getprop(owning_team); - if(o_t > 0) { - if(systime() > getprop(last_update_time) + 300) { - print("Adding point to team: " ~ o_t); - setprop("/sim/multiplay/chat","Adding point to team: " ~ o_t); - setprop("/aa_tower/score-team-" ~ o_t, getprop("/aa_tower/score-team-" ~ o_t) + 1); - setprop(last_update_time, systime()); - write_xml(); - } - } - settimer(func(){update();},10); -} - -update(); - -var twr_base = "/aa_tower/"; -var filename_base = getprop("/sim/fg-home") ~ "/Export/tower-"; -var write_xml = func() { - io.write_properties( path: filename_base ~ rand() ~ ".xml", prop: twr_base ); -} - -var callsign_struct = {}; -var getCallsign = func (callsign) { - var node = callsign_struct[callsign]; - return node; -} - -var processCallsigns = func () { - callsign_struct = {}; - var players = props.globals.getNode("ai/models").getChildren(); - foreach (var player; players) { - if(player.getChild("valid") != nil and player.getChild("valid").getValue() == TRUE and player.getChild("callsign") != nil and player.getChild("callsign").getValue() != "" and player.getChild("callsign").getValue() != nil) { - var callsign = player.getChild("callsign").getValue(); - callsign_struct[callsign] = player; - } - } - settimer(processCallsigns, 1.5); -} - -processCallsigns(); - - -setlistener("/sim/multiplay/chat-history", incoming_listener, 0, 0); \ No newline at end of file diff --git a/tower/Nasal/fdm.nas b/tower/Nasal/fdm.nas deleted file mode 100644 index 1ae09d0..0000000 --- a/tower/Nasal/fdm.nas +++ /dev/null @@ -1,44 +0,0 @@ -# Copyright (C) 2015 onox -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -#io.include("Aircraft/ExpansionPack/Nasal/init.nas"); - -#with("updateloop"); - -# Number of iterations per second -var frequency = 60.0; - -# Change in heading per second at full rudder deflection -var heading_ps = 0.5; - -time_last = 0; -sim_speed = 1; - -setprop("/carrier/pitch-deg",0); -setprop("/carrier/pitch-offset",0); -setprop("/carrier/roll-deg",0); -setprop("/carrier/roll-offset",0); -setprop("/carrier/sunk",0); - -var PositionUpdater = func () { - - # does a building need an FDM? - # nawwwwwww - - settimer( PositionUpdater, 1/frequency ); - -}; - -PositionUpdater(); \ No newline at end of file diff --git a/tower/tower-set.xml b/tower/tower-set.xml deleted file mode 100644 index a47d77c..0000000 --- a/tower/tower-set.xml +++ /dev/null @@ -1,125 +0,0 @@ - - - - - - - - false - - - - - - - 15.0 - - - 0.5 - 4.0 - - - 0.32 - 0.45 - - - 30.0 - - - 20.0 - - true - - - - - - pinto - tower - alpha - 0.1 - - null - - KPN-D - KPN - - - Aircraft/tower/Models/tower.xml - - - true - - - - Sounds/sound.xml - - - - true - - - - Aircraft/tower/splash1.png - - - - true - - 0.0 - 0.0 - false - - 100.0 - 2000.0 - - - - - Systems/fbw.xml - - - Systems/fdm.xml - - - - - 0 - - - - - - - Aircraft/tower/Nasal/fdm.nas - - - Aircraft/tower/Nasal/damage.nas - - - -