mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-08-15 10:47:21 +00:00
Compare commits
823 Commits
v0.2.2-alp
...
v1.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b81bc550ec | ||
|
|
f725866ef4 | ||
|
|
842aa878ad | ||
|
|
bbc9ddf9a3 | ||
|
|
bf5dce5b5f | ||
|
|
c9a3740ac7 | ||
|
|
942ae18290 | ||
|
|
a8d4e5e5e6 | ||
|
|
1ec21942af | ||
|
|
b75c1a92ad | ||
|
|
ba1a08920f | ||
|
|
edaa5112a1 | ||
|
|
d6afb5e6e7 | ||
|
|
5d17cde83a | ||
|
|
83447468f8 | ||
|
|
1af9ad46b9 | ||
|
|
ef5f83034b | ||
|
|
1b6d241acc | ||
|
|
9bc84264ef | ||
|
|
c476c7df27 | ||
|
|
082e1d5e2e | ||
|
|
fbec9519ee | ||
|
|
336f1781a7 | ||
|
|
4861c46e0d | ||
|
|
9ea2221c33 | ||
|
|
f945018dfe | ||
|
|
45c7f72732 | ||
|
|
f3d5b17548 | ||
|
|
3789bf79c2 | ||
|
|
7f3a2fa8e1 | ||
|
|
7c7aa76fdd | ||
|
|
0a3db0034f | ||
|
|
72d6b2b769 | ||
|
|
36aac4162d | ||
|
|
8d65e6f05a | ||
|
|
d496b594ae | ||
|
|
5dec4b137b | ||
|
|
a0029fd0bd | ||
|
|
ad3baa1f0d | ||
|
|
9d23c4943c | ||
|
|
438a587927 | ||
|
|
b9bd76f387 | ||
|
|
316d7325bc | ||
|
|
d779fb4167 | ||
|
|
8edbb5ca23 | ||
|
|
e0254308d3 | ||
|
|
405c297cdf | ||
|
|
1f109c3935 | ||
|
|
1e143778bd | ||
|
|
389659df0c | ||
|
|
c9c3b11b14 | ||
|
|
0f7bc2b663 | ||
|
|
490f1b47c7 | ||
|
|
b8df0c433b | ||
|
|
e29d486dfb | ||
|
|
5f6deff3fa | ||
|
|
34cdfbad40 | ||
|
|
20215d105f | ||
|
|
152a3a789f | ||
|
|
f4b4a40d75 | ||
|
|
0b034f476d | ||
|
|
06409f6cd0 | ||
|
|
7b07c48ff8 | ||
|
|
604db7e53c | ||
|
|
3a5f4ccd55 | ||
|
|
35a2bb459c | ||
|
|
6fb5a88953 | ||
|
|
d0b0ce7483 | ||
|
|
d9e9ef887b | ||
|
|
e5457a906d | ||
|
|
33f064141f | ||
|
|
ede466c0bd | ||
|
|
e6e470e8d1 | ||
|
|
d7c2e0f900 | ||
|
|
b9b2caed65 | ||
|
|
e788bc928d | ||
|
|
bc863c157e | ||
|
|
5cae3a9600 | ||
|
|
b60526686f | ||
|
|
423c45489e | ||
|
|
beff62b864 | ||
|
|
748e5cc8f8 | ||
|
|
3473076814 | ||
|
|
fcf011a6f4 | ||
|
|
83d07017c3 | ||
|
|
84b5f2dd68 | ||
|
|
3776b57164 | ||
|
|
d1877ba300 | ||
|
|
a174fa5169 | ||
|
|
2f50854c74 | ||
|
|
c72354a914 | ||
|
|
843759193f | ||
|
|
247abe57f3 | ||
|
|
88943f9c96 | ||
|
|
19842bd7f0 | ||
|
|
a50b497840 | ||
|
|
bd9d831b49 | ||
|
|
ff48d20c40 | ||
|
|
4b65b944b3 | ||
|
|
1ac2dde262 | ||
|
|
b24c04f64e | ||
|
|
21ddf8f0c0 | ||
|
|
9cc04e31a1 | ||
|
|
17e3d51b56 | ||
|
|
085f7628fd | ||
|
|
d4d521b432 | ||
|
|
a24717e30e | ||
|
|
062d241c1c | ||
|
|
71730c5b70 | ||
|
|
895bff0121 | ||
|
|
90db41567d | ||
|
|
2f93e16566 | ||
|
|
099697f582 | ||
|
|
b917e604b5 | ||
|
|
4a89d4fc78 | ||
|
|
903d8dd628 | ||
|
|
dd310b48d4 | ||
|
|
63d443802b | ||
|
|
48e382d999 | ||
|
|
50f37d4dbe | ||
|
|
8c0adea841 | ||
|
|
7be632ced0 | ||
|
|
1d8d8b3e58 | ||
|
|
3685b9418a | ||
|
|
24c896b535 | ||
|
|
fa8fcfec89 | ||
|
|
4b1f0014ab | ||
|
|
f115ec87d4 | ||
|
|
20f8a98cf0 | ||
|
|
1441d035d7 | ||
|
|
3db8062583 | ||
|
|
154f729788 | ||
|
|
e9a4429f7a | ||
|
|
3f2b47b82d | ||
|
|
8fc7609932 | ||
|
|
c512eaad04 | ||
|
|
ec299132ad | ||
|
|
985070b5f8 | ||
|
|
93e7fab116 | ||
|
|
9f63184a5e | ||
|
|
7d3729e556 | ||
|
|
b9b829a09a | ||
|
|
f1755fc3a4 | ||
|
|
a9101750e5 | ||
|
|
a530cea326 | ||
|
|
0adf349066 | ||
|
|
8acfb79c0e | ||
|
|
e5c3f2070f | ||
|
|
a669ba5e5b | ||
|
|
7bb66c79aa | ||
|
|
f65cc1404a | ||
|
|
e088edcfbc | ||
|
|
52f4051901 | ||
|
|
be4d51237b | ||
|
|
ab345f5ad2 | ||
|
|
33af2b4f95 | ||
|
|
8d2404b1e5 | ||
|
|
8ba815a7ba | ||
|
|
dc71032f7d | ||
|
|
e41b72196b | ||
|
|
30c7fce430 | ||
|
|
e4ad046bbf | ||
|
|
2767026892 | ||
|
|
96516760ea | ||
|
|
2550638bb3 | ||
|
|
e723a66f62 | ||
|
|
273b5fc7e5 | ||
|
|
ac7dd8cb2f | ||
|
|
e00e3104ab | ||
|
|
3466f2d3b7 | ||
|
|
fd1ed374cf | ||
|
|
98a77e2856 | ||
|
|
0095e53b3a | ||
|
|
0cb456ef0c | ||
|
|
2a928765bb | ||
|
|
0c55d62763 | ||
|
|
81b04bdbfb | ||
|
|
d6ff4221e7 | ||
|
|
8a1765141a | ||
|
|
745e185f71 | ||
|
|
0109f011e8 | ||
|
|
d4497fbf5e | ||
|
|
faa64c9f4e | ||
|
|
956c71bbaa | ||
|
|
a54c3f975a | ||
|
|
553fab6b51 | ||
|
|
24de4655f6 | ||
|
|
fa97ba6ed7 | ||
|
|
ca8920a429 | ||
|
|
83f4b35bb3 | ||
|
|
77c706a3c6 | ||
|
|
bda23b2064 | ||
|
|
8f5dec1da8 | ||
|
|
4f6d81e0c8 | ||
|
|
0f278757de | ||
|
|
637e14798f | ||
|
|
312696a385 | ||
|
|
10c8e67e37 | ||
|
|
93bea9528d | ||
|
|
34037c3a8c | ||
|
|
9987b60c07 | ||
|
|
84a1fc1ac7 | ||
|
|
af37624d4f | ||
|
|
65f4902029 | ||
|
|
8f2f69d7b9 | ||
|
|
4b66d9db31 | ||
|
|
fcf31a4d50 | ||
|
|
cacbc6f40c | ||
|
|
e7d8aa528d | ||
|
|
4e069b389d | ||
|
|
c48129d647 | ||
|
|
d04b0ed82b | ||
|
|
6ce40d0bbd | ||
|
|
0a2cdf999d | ||
|
|
02fe5f6104 | ||
|
|
e0f2c6c9fb | ||
|
|
15fdb0fd45 | ||
|
|
b52dd7cf57 | ||
|
|
60e01b0d9c | ||
|
|
8eb76e0da2 | ||
|
|
45d124065b | ||
|
|
62930f39b1 | ||
|
|
c54c3f275f | ||
|
|
575626e44e | ||
|
|
9c81380b50 | ||
|
|
1206c51fe1 | ||
|
|
b9c85d4cb7 | ||
|
|
54becfe0b7 | ||
|
|
131d2dd4a4 | ||
|
|
4f6ed0c119 | ||
|
|
114517bb05 | ||
|
|
04c6d12247 | ||
|
|
6d4a7a21b9 | ||
|
|
b888a0e96a | ||
|
|
70a64e81a4 | ||
|
|
6d5655e56a | ||
|
|
e552e70e2a | ||
|
|
3f6487c410 | ||
|
|
25b7c49842 | ||
|
|
3dfbc9a0f9 | ||
|
|
3331c58e24 | ||
|
|
eae00a0cb8 | ||
|
|
cabedb65b7 | ||
|
|
f0e99225db | ||
|
|
f3d0f7233d | ||
|
|
8609cb50d3 | ||
|
|
54c3549bac | ||
|
|
8439708cca | ||
|
|
368b396b2a | ||
|
|
3e199fce90 | ||
|
|
60bb6de4a5 | ||
|
|
f5f59c4137 | ||
|
|
5bdad983ad | ||
|
|
f2f73ef71b | ||
|
|
cfca7dfc05 | ||
|
|
1acdfc1798 | ||
|
|
db7b91bb5f | ||
|
|
6716f2907b | ||
|
|
f0d0b07cc0 | ||
|
|
8a16507adb | ||
|
|
cbd26b631a | ||
|
|
792f006041 | ||
|
|
4f7fb7ef1d | ||
|
|
d274dc44e9 | ||
|
|
788e5dfa56 | ||
|
|
b4c7e9cacf | ||
|
|
2453fb6780 | ||
|
|
3cff3ed761 | ||
|
|
9258beffc8 | ||
|
|
899d076399 | ||
|
|
41ccfb35fc | ||
|
|
5adc72fdb9 | ||
|
|
de4edad449 | ||
|
|
ccc10e5233 | ||
|
|
51780b1d9b | ||
|
|
1f90c0c766 | ||
|
|
243f33764a | ||
|
|
196f85f07b | ||
|
|
c6dc68cf0a | ||
|
|
8c45629dde | ||
|
|
ffe3325080 | ||
|
|
fc100716e0 | ||
|
|
44332595a4 | ||
|
|
a5298a950f | ||
|
|
743609310b | ||
|
|
df0adff9f1 | ||
|
|
e60f686ec8 | ||
|
|
64092dbb2e | ||
|
|
640af3d964 | ||
|
|
3017f10906 | ||
|
|
29401e0c95 | ||
|
|
56a78f1f28 | ||
|
|
f79539965f | ||
|
|
6bd4442d84 | ||
|
|
ccbe79c00c | ||
|
|
048703a1e9 | ||
|
|
f080d4bac1 | ||
|
|
6856404126 | ||
|
|
335ef0d471 | ||
|
|
4a45923c15 | ||
|
|
a5bc67b328 | ||
|
|
416f201742 | ||
|
|
aa3a75350a | ||
|
|
d7e3d5fc79 | ||
|
|
54d0c20d5b | ||
|
|
7ad4db84bd | ||
|
|
80ed9fe3f8 | ||
|
|
13854370e4 | ||
|
|
4e1b06a50b | ||
|
|
a0cf14cd4f | ||
|
|
2f7dd91259 | ||
|
|
6601f2217a | ||
|
|
8daf37ce8f | ||
|
|
0ab77d24b0 | ||
|
|
cff0d8bb2b | ||
|
|
513839ceaa | ||
|
|
b1cb90d08d | ||
|
|
a65438f692 | ||
|
|
23a84bc1a9 | ||
|
|
cb993c4df5 | ||
|
|
dc3ce7226e | ||
|
|
6969e52f67 | ||
|
|
e2ec47a3f0 | ||
|
|
b21f1144fb | ||
|
|
5bdb7db268 | ||
|
|
f829892f64 | ||
|
|
9a4d31c82f | ||
|
|
5ef372eaa0 | ||
|
|
74bbd59dde | ||
|
|
9e84ae538f | ||
|
|
5e4ffdafc7 | ||
|
|
8af0b052c6 | ||
|
|
755eb9748b | ||
|
|
2de7726430 | ||
|
|
837796ed0b | ||
|
|
637b5113fa | ||
|
|
8749067b0a | ||
|
|
b0f614248c | ||
|
|
9e28fa9266 | ||
|
|
d2e24c39c4 | ||
|
|
b213896ae7 | ||
|
|
07f9cd2431 | ||
|
|
ba7d8787f8 | ||
|
|
19eb51d8a3 | ||
|
|
4b6edcceba | ||
|
|
2717617419 | ||
|
|
f9ffb4d592 | ||
|
|
ad0e048d15 | ||
|
|
8eaa6a39d9 | ||
|
|
0f8ed48183 | ||
|
|
ce0be4dcf7 | ||
|
|
59640e8df4 | ||
|
|
4c904309f6 | ||
|
|
7046f39ea4 | ||
|
|
23f164e5ad | ||
|
|
2e8fa76c0d | ||
|
|
23a039b58f | ||
|
|
e98d36e314 | ||
|
|
33f42351e4 | ||
|
|
995e21e200 | ||
|
|
d62acf421e | ||
|
|
74cee904cd | ||
|
|
ef120c7397 | ||
|
|
9e6fc16cce | ||
|
|
cf4adbd8d5 | ||
|
|
80f7269651 | ||
|
|
b65bdad54f | ||
|
|
51d8e2b7d8 | ||
|
|
63e46ad029 | ||
|
|
7f7570429a | ||
|
|
c966929933 | ||
|
|
104aa006e4 | ||
|
|
14d592b8b9 | ||
|
|
365034ad69 | ||
|
|
84e2361829 | ||
|
|
761053c95e | ||
|
|
02d4bbf3ff | ||
|
|
e98814e8d4 | ||
|
|
152c8a986d | ||
|
|
6c6b26e33e | ||
|
|
e5b386b9e5 | ||
|
|
15134d7f4e | ||
|
|
b81b483f0b | ||
|
|
24a6d37500 | ||
|
|
46aa9ddf65 | ||
|
|
038c10c4d4 | ||
|
|
2582e7a90a | ||
|
|
8cda04be45 | ||
|
|
7c73b232ae | ||
|
|
50e69e07fb | ||
|
|
618fdb8405 | ||
|
|
3b31fca7c0 | ||
|
|
d17a637515 | ||
|
|
a610b8b425 | ||
|
|
f840b6f836 | ||
|
|
0d8936bcb0 | ||
|
|
6d640c8416 | ||
|
|
2dc231eb9e | ||
|
|
22f6cb8ecb | ||
|
|
c8e8aecf34 | ||
|
|
b45f20579e | ||
|
|
3496550cb3 | ||
|
|
b72a1c5c6b | ||
|
|
4c8f920c61 | ||
|
|
5486a12c77 | ||
|
|
e46d7be91b | ||
|
|
0a4630bde6 | ||
|
|
dd162831fa | ||
|
|
931464dfec | ||
|
|
3319843888 | ||
|
|
8c85f9319d | ||
|
|
4034461488 | ||
|
|
62b476144a | ||
|
|
9c4b147b6b | ||
|
|
9ab3a2f74d | ||
|
|
54a861cc58 | ||
|
|
f9eb19e0f5 | ||
|
|
354a9333c6 | ||
|
|
a5e3deb272 | ||
|
|
522ba96ca1 | ||
|
|
c86b9d1822 | ||
|
|
2d3ee93d9e | ||
|
|
68e3472c49 | ||
|
|
28802ba276 | ||
|
|
c27b6efe12 | ||
|
|
35ac87109b | ||
|
|
20dca5088a | ||
|
|
4816cd2c57 | ||
|
|
2f4eb39156 | ||
|
|
07f6760039 | ||
|
|
1bd61837f2 | ||
|
|
764266d552 | ||
|
|
6239b6263c | ||
|
|
cd4d4af559 | ||
|
|
9126c8c0b2 | ||
|
|
dac29f6356 | ||
|
|
0edb083d5d | ||
|
|
167b0dd598 | ||
|
|
91d0507b4d | ||
|
|
a800531ea0 | ||
|
|
3861362ed9 | ||
|
|
0c15f92210 | ||
|
|
0bfac2d2ed | ||
|
|
7cda194f45 | ||
|
|
c000675471 | ||
|
|
58124c0709 | ||
|
|
be55fdde9a | ||
|
|
e59caac2c7 | ||
|
|
d47e3183e3 | ||
|
|
aa4a487256 | ||
|
|
5c8a99a412 | ||
|
|
fec2b39469 | ||
|
|
52e473204d | ||
|
|
619efb5c08 | ||
|
|
6741d978dd | ||
|
|
6c9842c691 | ||
|
|
cf9bbc9ba7 | ||
|
|
bdbb1ea018 | ||
|
|
851ccf0a45 | ||
|
|
9f37dde093 | ||
|
|
df90955347 | ||
|
|
152accb93d | ||
|
|
66e1b02898 | ||
|
|
7ec2d3425c | ||
|
|
d2efc61ddc | ||
|
|
bd62df4d28 | ||
|
|
b9a94271b2 | ||
|
|
92f1f08d5f | ||
|
|
e1610330f4 | ||
|
|
75ea07fea0 | ||
|
|
a95d4b6caf | ||
|
|
8ca74ee7db | ||
|
|
0c5e1db39c | ||
|
|
c6eff8b1ce | ||
|
|
9c5e132fab | ||
|
|
88e280fee3 | ||
|
|
2d17825268 | ||
|
|
0a5d2a38c5 | ||
|
|
70f8234cd7 | ||
|
|
50355778a8 | ||
|
|
26c01cba60 | ||
|
|
fe8418884f | ||
|
|
72a76ecfd6 | ||
|
|
6eaf03a903 | ||
|
|
6c85ac720b | ||
|
|
4abdfcafeb | ||
|
|
77909e10d2 | ||
|
|
70de346513 | ||
|
|
d42a06bf94 | ||
|
|
09d1acf2aa | ||
|
|
daef3e415f | ||
|
|
54ff64aa94 | ||
|
|
a6da2ba441 | ||
|
|
84ed412ed7 | ||
|
|
c10e293ff7 | ||
|
|
d878c46d56 | ||
|
|
906045a027 | ||
|
|
dc486be872 | ||
|
|
c7061e98d7 | ||
|
|
9cd45e7abe | ||
|
|
d005b5a048 | ||
|
|
509407e63c | ||
|
|
0a8d7a3fc5 | ||
|
|
3a872827d5 | ||
|
|
49bb059ee9 | ||
|
|
a466daf1aa | ||
|
|
a76ec08499 | ||
|
|
5f02b5f764 | ||
|
|
ea048ade54 | ||
|
|
195f62f518 | ||
|
|
e55a7716fb | ||
|
|
2befd34681 | ||
|
|
a4584a9185 | ||
|
|
ede7813a94 | ||
|
|
231b382df1 | ||
|
|
b283406274 | ||
|
|
cf8d105b33 | ||
|
|
a634fbb33c | ||
|
|
ebfb034170 | ||
|
|
a4fb512ad9 | ||
|
|
ce789b9703 | ||
|
|
eac2a0b798 | ||
|
|
70651777c5 | ||
|
|
a90098b30b | ||
|
|
2b421fc1f1 | ||
|
|
2a788ddaf2 | ||
|
|
2eeaf7b92d | ||
|
|
8e8fcef266 | ||
|
|
89727a00fb | ||
|
|
ffe8ef06d0 | ||
|
|
0c9162aca0 | ||
|
|
5919e9a3ab | ||
|
|
bee6e8d7c6 | ||
|
|
01d0cd71f1 | ||
|
|
5d88e449be | ||
|
|
38f18d7b28 | ||
|
|
0a9eb84264 | ||
|
|
6e370b6065 | ||
|
|
ffecff739b | ||
|
|
2bb4c41f62 | ||
|
|
5e77d30caa | ||
|
|
054da51d97 | ||
|
|
9b15ec1988 | ||
|
|
d5671a5f65 | ||
|
|
86b283c7f0 | ||
|
|
ce19e3bc03 | ||
|
|
ca50a0af29 | ||
|
|
2096c67330 | ||
|
|
947474eab0 | ||
|
|
99261765c4 | ||
|
|
def75889ad | ||
|
|
153ff7bd58 | ||
|
|
8a4b40303a | ||
|
|
17abcb7b7f | ||
|
|
40a9c1f7d1 | ||
|
|
e8a7200de7 | ||
|
|
9a4d9d059a | ||
|
|
11aef957b6 | ||
|
|
6a82b223f6 | ||
|
|
93d496a1b1 | ||
|
|
0c13744309 | ||
|
|
6ba6390b5d | ||
|
|
a4a2843f13 | ||
|
|
6f26394bcf | ||
|
|
8556ee5128 | ||
|
|
9493072293 | ||
|
|
dc35fc6653 | ||
|
|
e41d45e1eb | ||
|
|
348130c993 | ||
|
|
2faef0e85b | ||
|
|
85f07c0807 | ||
|
|
59446a012d | ||
|
|
ce553183c9 | ||
|
|
ab8c8dee4d | ||
|
|
b1f7d02f25 | ||
|
|
6a39f6f1e3 | ||
|
|
c5cc069e46 | ||
|
|
bba6aa8fb6 | ||
|
|
c26f5e2dbc | ||
|
|
e0314a4598 | ||
|
|
6f14927544 | ||
|
|
b12372c758 | ||
|
|
61d539b2d5 | ||
|
|
0938fc6d80 | ||
|
|
fd548484c9 | ||
|
|
6acc1cfcb6 | ||
|
|
5318597907 | ||
|
|
49dd2b6f2a | ||
|
|
50a770d755 | ||
|
|
d39f38b524 | ||
|
|
2218fdd0b2 | ||
|
|
06b2ba007e | ||
|
|
376b0d08a5 | ||
|
|
a9d54b7d02 | ||
|
|
093f12b57a | ||
|
|
d91ba031aa | ||
|
|
eda2794373 | ||
|
|
123dc13532 | ||
|
|
23ea389b8f | ||
|
|
4ac962a87a | ||
|
|
ae1aeac6ce | ||
|
|
d668b0a0f7 | ||
|
|
7b66589cca | ||
|
|
6b942590bd | ||
|
|
65391223d5 | ||
|
|
e2250dc92f | ||
|
|
7ab52025fd | ||
|
|
626b95fb46 | ||
|
|
eb863416ee | ||
|
|
27bb51e69c | ||
|
|
dc644df47e | ||
|
|
3a01fb76bf | ||
|
|
4056e5d66d | ||
|
|
1187e46e89 | ||
|
|
fefe5382af | ||
|
|
e842c7a042 | ||
|
|
9d7f196075 | ||
|
|
4a378129f1 | ||
|
|
d211bc084b | ||
|
|
c3da8ac008 | ||
|
|
8b57ab494b | ||
|
|
7985cafdc0 | ||
|
|
c581fe1551 | ||
|
|
a34c04e0f2 | ||
|
|
5e6043aeb3 | ||
|
|
b56210a03a | ||
|
|
e99458520a | ||
|
|
2b5140cec1 | ||
|
|
e014cfce51 | ||
|
|
7b8ef52ae0 | ||
|
|
9dcfe83ed8 | ||
|
|
8d12cc2a4d | ||
|
|
12186bf2b0 | ||
|
|
d43a15a977 | ||
|
|
062f34bd26 | ||
|
|
08116dab2c | ||
|
|
4bd4c6aa79 | ||
|
|
fdefd87e88 | ||
|
|
ca950e1599 | ||
|
|
c8443f8798 | ||
|
|
8a3cdc6b85 | ||
|
|
ad56973b01 | ||
|
|
64f964bf70 | ||
|
|
e0b32fe5d5 | ||
|
|
ffbc4a838e | ||
|
|
b2bd37edbc | ||
|
|
36b101fa6d | ||
|
|
325c20cb46 | ||
|
|
87313a9204 | ||
|
|
c211f4f603 | ||
|
|
396662657f | ||
|
|
8edfb49358 | ||
|
|
34e7015244 | ||
|
|
9ce7012c11 | ||
|
|
9b4bc1195c | ||
|
|
e5f17213e1 | ||
|
|
0ad7cbe2ea | ||
|
|
fe62197ba0 | ||
|
|
ddab549fe0 | ||
|
|
2a619c33ec | ||
|
|
cbbc4144e6 | ||
|
|
0500915d11 | ||
|
|
75277bd249 | ||
|
|
f2407e357a | ||
|
|
45140d6563 | ||
|
|
3253f31ed6 | ||
|
|
b376091347 | ||
|
|
5bd0595b35 | ||
|
|
37510ab647 | ||
|
|
91c5f467aa | ||
|
|
a57f28a248 | ||
|
|
d66a2ea429 | ||
|
|
af020b4b6e | ||
|
|
ff44c70ea4 | ||
|
|
998a325554 | ||
|
|
2657cc681f | ||
|
|
ef003f1423 | ||
|
|
8de64bc95a | ||
|
|
29652a0edb | ||
|
|
61f55b3bd8 | ||
|
|
32a179d0b6 | ||
|
|
d8adfd01d7 | ||
|
|
55167e99c7 | ||
|
|
85a419face | ||
|
|
dcce65edeb | ||
|
|
b335e99d5b | ||
|
|
bd81d16327 | ||
|
|
9e00b6e84b | ||
|
|
cb4d8bbde3 | ||
|
|
bff0c0bf4e | ||
|
|
a6baed5478 | ||
|
|
9e881530d8 | ||
|
|
a0250cfdc4 | ||
|
|
cf80a89af0 | ||
|
|
ce321c8cfe | ||
|
|
72baf7091b | ||
|
|
be8e76e7f1 | ||
|
|
5211f06cba | ||
|
|
ea318f3c75 | ||
|
|
e3ca5e32cb | ||
|
|
f7eef96c94 | ||
|
|
b925339f24 | ||
|
|
0dc9b2cf31 | ||
|
|
a8a87be9c4 | ||
|
|
0573ebb919 | ||
|
|
fb8ce07a43 | ||
|
|
fcfa91f700 | ||
|
|
92e9f57b66 | ||
|
|
afb71ecd26 | ||
|
|
3975aad967 | ||
|
|
444304e57e | ||
|
|
431ec0c236 | ||
|
|
2565939889 | ||
|
|
bf7422716c | ||
|
|
4de4983878 | ||
|
|
40d4ffda64 | ||
|
|
4fc1fee911 | ||
|
|
e82ba13b8b | ||
|
|
8777f516af | ||
|
|
0d42c1670e | ||
|
|
64f67e2ae0 | ||
|
|
d5867a1c8c | ||
|
|
d8790ad2f1 | ||
|
|
2ac9e76f5c | ||
|
|
8da59c4395 | ||
|
|
edb265948b | ||
|
|
99b90789e6 | ||
|
|
3723b95563 | ||
|
|
a34e4c68d0 | ||
|
|
ade8135b5a | ||
|
|
8b01579a42 | ||
|
|
ac1d9485cd | ||
|
|
69c11ca1c6 | ||
|
|
5b598818b4 | ||
|
|
41375f4491 | ||
|
|
f3b8835a16 | ||
|
|
3173dfb42a | ||
|
|
0438cabbb0 | ||
|
|
7efbd60b9e | ||
|
|
645d074a7d | ||
|
|
dc662849d4 | ||
|
|
6605682557 | ||
|
|
4064caa743 | ||
|
|
611741d7af | ||
|
|
7fa2a64347 | ||
|
|
8cdee7f611 | ||
|
|
ed9c1b2185 | ||
|
|
9afe0acd8d | ||
|
|
bed2a339a1 | ||
|
|
9cd55e6f2a | ||
|
|
df9b05c270 | ||
|
|
6a43e9da80 | ||
|
|
2a97df7ef9 | ||
|
|
4f1c0eaa8e | ||
|
|
90b902f3b3 | ||
|
|
070c893940 | ||
|
|
d1b8eda700 | ||
|
|
49e85a326c | ||
|
|
accc982ee1 | ||
|
|
b78187aaff | ||
|
|
7e375c4895 | ||
|
|
b086ef50f7 | ||
|
|
422e5b6eff | ||
|
|
498505b7b8 | ||
|
|
c50f98b8dd | ||
|
|
3e5836f9d4 | ||
|
|
27bdc65cd7 | ||
|
|
1cb97aca38 | ||
|
|
df783226cb | ||
|
|
62d04113d3 | ||
|
|
6a06632a5e | ||
|
|
83d5338b16 | ||
|
|
9b0879626f | ||
|
|
fe36e0ee2a | ||
|
|
d198da5ada | ||
|
|
2eb784abad | ||
|
|
cbcc9b411f | ||
|
|
1fef4793ca | ||
|
|
ff689b05be | ||
|
|
219f44e008 | ||
|
|
7a91bdff72 | ||
|
|
f20ba8985b | ||
|
|
75b2a668dd | ||
|
|
37c8bb5477 | ||
|
|
0a66cb6a59 | ||
|
|
bca06c1dbf | ||
|
|
128bb0cc2c | ||
|
|
fe8438648c | ||
|
|
d1b3de1940 | ||
|
|
6dd4bc638e | ||
|
|
971f5e9ca4 | ||
|
|
e486c80350 | ||
|
|
01531f0c73 | ||
|
|
4d40f28cf8 | ||
|
|
e71c02b885 | ||
|
|
15b189d747 | ||
|
|
5990650529 | ||
|
|
b836ca5fcd | ||
|
|
45cc120f76 | ||
|
|
db2cc49b85 | ||
|
|
37ec8c294f | ||
|
|
b7a2e8b278 | ||
|
|
4667e7c41c | ||
|
|
9f8bfa1603 | ||
|
|
812c4216c5 | ||
|
|
34d268b451 | ||
|
|
7e8090f772 | ||
|
|
bfb1bcc232 | ||
|
|
8ef6ef14dd | ||
|
|
3965c5e254 | ||
|
|
aaa3ab07e3 | ||
|
|
38244f10dd | ||
|
|
1949d69fa0 | ||
|
|
c68e4cd257 | ||
|
|
4704afdc6c | ||
|
|
979de8901c | ||
|
|
ad2c3ed83f | ||
|
|
bfeaa961f6 | ||
|
|
4adf5aa188 | ||
|
|
1d9da407b9 | ||
|
|
f981200409 | ||
|
|
f8a5ebdadb | ||
|
|
f95555732d |
4
.gitmodules
vendored
Normal file
4
.gitmodules
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
[submodule "Moose Development/Moose/Dcs"]
|
||||
path = Moose Development/Moose/Dcs
|
||||
url = https://github.com/FlightControl-Master/DCS-API.git
|
||||
branch = master
|
||||
4
DCS_Folder_Sync.bat
Normal file
4
DCS_Folder_Sync.bat
Normal file
@@ -0,0 +1,4 @@
|
||||
rem This script will pull the latest changes from the remote repository, and update the submodules accordingly.
|
||||
|
||||
C:\Program Files (x86)\Git\bin\git pull
|
||||
C:\Program Files (x86)\Git\bin\git submodule update --init
|
||||
@@ -1,54 +0,0 @@
|
||||
-------------------------------------------------------------------------------
|
||||
-- @module DCSAirbase
|
||||
|
||||
|
||||
--- Represents airbases: airdromes, helipads and ships with flying decks or landing pads.
|
||||
-- @type Airbase
|
||||
-- @extends DCSCoalitionObject#CoalitionObject
|
||||
-- @field #Airbase.ID ID Identifier of an airbase. It assigned to an airbase by the Mission Editor automatically. This identifier is used in AI tasks to refer an airbase that exists (spawned and not dead) or not.
|
||||
-- @field #Airbase.Category Category enum contains identifiers of airbase categories.
|
||||
-- @field #Airbase.Desc Desc Airbase descriptor. Airdromes are unique and their types are unique, but helipads and ships are not always unique and may have the same type.
|
||||
|
||||
--- Enum contains identifiers of airbase categories.
|
||||
-- @type Airbase.Category
|
||||
-- @field AIRDROME
|
||||
-- @field HELIPAD
|
||||
-- @field SHIP
|
||||
|
||||
--- Airbase descriptor. Airdromes are unique and their types are unique, but helipads and ships are not always unique and may have the same type.
|
||||
-- @type Airbase.Desc
|
||||
-- @extends #Desc
|
||||
-- @field #Airbase.Category category Category of the airbase type.
|
||||
|
||||
--- Returns airbase by its name. If no airbase found the function will return nil.
|
||||
-- @function [parent=#Airbase] getByName
|
||||
-- @param #string name
|
||||
-- @return #Airbase
|
||||
|
||||
--- Returns airbase descriptor by type name. If no descriptor is found the function will return nil.
|
||||
-- @function [parent=#Airbase] getDescByName
|
||||
-- @param #TypeName typeName Airbase type name.
|
||||
-- @return #Airbase.Desc
|
||||
|
||||
--- Returns Unit that is corresponded to the airbase. Works only for ships.
|
||||
-- @function [parent=#Airbase] getUnit
|
||||
-- @param self
|
||||
-- @return Unit#Unit
|
||||
|
||||
--- Returns identifier of the airbase.
|
||||
-- @function [parent=#Airbase] getID
|
||||
-- @param self
|
||||
-- @return #Airbase.ID
|
||||
|
||||
--- Returns the airbase's callsign - the localized string.
|
||||
-- @function [parent=#Airbase] getCallsign
|
||||
-- @param self
|
||||
-- @return #string
|
||||
|
||||
--- Returns descriptor of the airbase.
|
||||
-- @function [parent=#Airbase] getDesc
|
||||
-- @param self
|
||||
-- @return #Airbase.Desc
|
||||
|
||||
|
||||
Airbase = {} --#Airbase
|
||||
@@ -1,28 +0,0 @@
|
||||
-------------------------------------------------------------------------------
|
||||
-- @module DCSCoalitionObject
|
||||
|
||||
--- @type CoalitionObject
|
||||
-- @extends DCSObject#Object
|
||||
|
||||
--- @type coalition
|
||||
-- @field #coalition.side side
|
||||
|
||||
--- @type coalition.side
|
||||
-- @field NEUTRAL
|
||||
-- @field RED
|
||||
-- @field BLUE
|
||||
|
||||
coalition = {} --#coalition
|
||||
|
||||
--- Returns coalition of the object.
|
||||
-- @function [parent=#CoalitionObject] getCoalition
|
||||
-- @param #CoalitionObject self
|
||||
-- @return DCSTypes#coalition.side
|
||||
|
||||
--- Returns object country.
|
||||
-- @function [parent=#CoalitionObject] getCountry
|
||||
-- @param #CoalitionObject self
|
||||
-- @return #country.id
|
||||
|
||||
|
||||
CoalitionObject = {} --#CoalitionObject
|
||||
@@ -1,10 +0,0 @@
|
||||
--- @module DCSCommand
|
||||
|
||||
|
||||
--- @type Command
|
||||
-- @field #string id
|
||||
-- @field #Command.params params
|
||||
|
||||
--- @type Command.params
|
||||
|
||||
env.info( "Command defined" )
|
||||
@@ -1,115 +0,0 @@
|
||||
-------------------------------------------------------------------------------
|
||||
-- @module DCSController
|
||||
|
||||
--- Controller is an object that performs A.I.-routines. Other words controller is an instance of A.I.. Controller stores current main task, active enroute tasks and behavior options. Controller performs commands. Please, read DCS A-10C GUI Manual EN.pdf chapter "Task Planning for Unit Groups", page 91 to understand A.I. system of DCS:A-10C.
|
||||
--
|
||||
-- This class has 2 types of functions:
|
||||
--
|
||||
-- * Tasks
|
||||
-- * Commands: Commands are instant actions those required zero time to perform. Commands may be used both for control unit/group behavior and control game mechanics.
|
||||
-- @type Controller
|
||||
-- @field #Controller.Detection Detection Enum contains identifiers of surface types.
|
||||
|
||||
--- Enables and disables the controller.
|
||||
-- Note: Now it works only for ground / naval groups!
|
||||
-- @function [parent=#Controller] setOnOff
|
||||
-- @param self
|
||||
-- @param #boolean value Enable / Disable.
|
||||
|
||||
-- Tasks
|
||||
|
||||
--- Resets current task and then sets the task to the controller. Task is a table that contains task identifier and task parameters.
|
||||
-- @function [parent=#Controller] setTask
|
||||
-- @param self
|
||||
-- @param #Task task
|
||||
|
||||
--- Resets current task of the controller.
|
||||
-- @function [parent=#Controller] resetTask
|
||||
-- @param self
|
||||
|
||||
--- Pushes the task to the front of the queue and makes the task active. Further call of function Controller.setTask() function will stop current task, clear the queue and set the new task active. If the task queue is empty the function will work like function Controller.setTask() function.
|
||||
-- @function [parent=#Controller] pushTask
|
||||
-- @param self
|
||||
-- @param #Task task
|
||||
|
||||
--- Pops current (front) task from the queue and makes active next task in the queue (if exists). If no more tasks in the queue the function works like function Controller.resetTask() function. Does nothing if the queue is empty.
|
||||
-- @function [parent=#Controller] popTask
|
||||
-- @param self
|
||||
|
||||
--- Returns true if the controller has a task.
|
||||
-- @function [parent=#Controller] hasTask
|
||||
-- @param self
|
||||
-- @return #boolean
|
||||
|
||||
-- Commands
|
||||
|
||||
--TODO: describe #Command structure
|
||||
--- Sets the command to perform by controller.
|
||||
-- @function [parent=#Controller] setCommand
|
||||
-- @param self
|
||||
-- @param #Command command Table that contains command identifier and command parameters.
|
||||
|
||||
|
||||
-- Behaviours
|
||||
|
||||
--- Sets the option to the controller.
|
||||
-- Option is a pair of identifier and value. Behavior options are global parameters those affect controller behavior in all tasks it performs.
|
||||
-- Option identifiers and values are stored in table AI.Option in subtables Air, Ground and Naval.
|
||||
--
|
||||
-- OptionId = @{#AI.Option.Air.id} or @{#AI.Option.Ground.id} or @{#AI.Option.Naval.id}
|
||||
-- OptionValue = AI.Option.Air.val[optionName] or AI.Option.Ground.val[optionName] or AI.Option.Naval.val[optionName]
|
||||
--
|
||||
-- @function [parent=#Controller] setOption
|
||||
-- @param self
|
||||
-- @param #OptionId optionId Option identifier.
|
||||
-- @param #OptionValue optionValue Value of the option.
|
||||
|
||||
|
||||
-- Detection
|
||||
|
||||
--- Enum contains identifiers of surface types.
|
||||
-- @type Controller.Detection
|
||||
-- @field VISUAL
|
||||
-- @field OPTIC
|
||||
-- @field RADAR
|
||||
-- @field IRST
|
||||
-- @field RWR
|
||||
-- @field DLINK
|
||||
|
||||
--- Detected target.
|
||||
-- @type DetectedTarget
|
||||
-- @field Object#Object object The target
|
||||
-- @field #boolean visible The target is visible
|
||||
-- @field #boolean type The target type is known
|
||||
-- @field #boolean distance Distance to the target is known
|
||||
|
||||
|
||||
--- Checks if the target is detected or not. If one or more detection method is specified the function will return true if the target is detected by at least one of these methods. If no detection methods are specified the function will return true if the target is detected by any method.
|
||||
-- @function [parent=#Controller] isTargetDetected
|
||||
-- @param self
|
||||
-- @param Object#Object target Target to check
|
||||
-- @param #Controller.Detection detection Controller.Detection detection1, Controller.Detection detection2, ... Controller.Detection detectionN
|
||||
-- @return #boolean detected True if the target is detected.
|
||||
-- @return #boolean visible Has effect only if detected is true. True if the target is visible now.
|
||||
-- @return #ModelTime lastTime Has effect only if visible is false. Last time when target was seen.
|
||||
-- @return #boolean type Has effect only if detected is true. True if the target type is known.
|
||||
-- @return #boolean distance Has effect only if detected is true. True if the distance to the target is known.
|
||||
-- @return #Vec3 lastPos Has effect only if visible is false. Last position of the target when it was seen.
|
||||
-- @return #Vec3 lastVel Has effect only if visible is false. Last velocity of the target when it was seen.
|
||||
|
||||
|
||||
--- Returns list of detected targets. If one or more detection method is specified the function will return targets which were detected by at least one of these methods. If no detection methods are specified the function will return targets which were detected by any method.
|
||||
-- @function [parent=#Controller] getDetectedTargets
|
||||
-- @param self
|
||||
-- @param #Controller.Detection detection Controller.Detection detection1, Controller.Detection detection2, ... Controller.Detection detectionN
|
||||
-- @return #list<#DetectedTarget> array of DetectedTarget
|
||||
|
||||
--- Know a target.
|
||||
-- @function [parent=#Controller] knowTarget
|
||||
-- @param self
|
||||
-- @param Object#Object object The target.
|
||||
-- @param #boolean type Target type is known.
|
||||
-- @param #boolean distance Distance to target is known.
|
||||
|
||||
|
||||
Controller = {} --#Controller
|
||||
@@ -1,82 +0,0 @@
|
||||
-------------------------------------------------------------------------------
|
||||
-- @module DCSGroup
|
||||
|
||||
--- Represents group of Units.
|
||||
-- @type Group
|
||||
-- @field #ID ID Identifier of a group. It is assigned to a group by Mission Editor automatically.
|
||||
-- @field #Group.Category Category Enum contains identifiers of group types.
|
||||
|
||||
--- Enum contains identifiers of group types.
|
||||
-- @type Group.Category
|
||||
-- @field AIRPLANE
|
||||
-- @field HELICOPTER
|
||||
-- @field GROUND
|
||||
-- @field SHIP
|
||||
|
||||
-- Static Functions
|
||||
|
||||
--- Returns group by the name assigned to the group in Mission Editor.
|
||||
-- @function [parent=#Group] getByName
|
||||
-- @param #string name
|
||||
-- @return #Group
|
||||
|
||||
-- Member Functions
|
||||
|
||||
--- returns true if the group exist or false otherwise.
|
||||
-- @function [parent=#Group] isExist
|
||||
-- @param #Group self
|
||||
-- @return #boolean
|
||||
|
||||
--- Destroys the group and all of its units.
|
||||
-- @function [parent=#Group] destroy
|
||||
-- @param #Group self
|
||||
|
||||
--- Returns category of the group.
|
||||
-- @function [parent=#Group] getCategory
|
||||
-- @param #Group self
|
||||
-- @return #Group.Category
|
||||
|
||||
--TODO check coalition.side
|
||||
--- Returns coalition of the group.
|
||||
-- @function [parent=#Group] getCoalition
|
||||
-- @param #Group self
|
||||
-- @return #coalition.side
|
||||
|
||||
--- Returns the group's name. This is the same name assigned to the group in Mission Editor.
|
||||
-- @function [parent=#Group] getName
|
||||
-- @param #Group self
|
||||
-- @return #string
|
||||
|
||||
--- Returns the group identifier.
|
||||
-- @function [parent=#Group] getID
|
||||
-- @param #Group self
|
||||
-- @return #ID
|
||||
|
||||
--- Returns the unit with number unitNumber. If the unit is not exists the function will return nil.
|
||||
-- @function [parent=#Group] getUnit
|
||||
-- @param #Group self
|
||||
-- @param #number unitNumber
|
||||
-- @return DCSUnit#Unit
|
||||
|
||||
--- Returns current size of the group. If some of the units will be destroyed, As units are destroyed the size of the group will be changed.
|
||||
-- @function [parent=#Group] getSize
|
||||
-- @param #Group self
|
||||
-- @return #number
|
||||
|
||||
--- Returns initial size of the group. If some of the units will be destroyed, initial size of the group will not be changed. Initial size limits the unitNumber parameter for Group.getUnit() function.
|
||||
-- @function [parent=#Group] getInitialSize
|
||||
-- @param #Group self
|
||||
-- @return #number
|
||||
|
||||
--- Returns array of the units present in the group now. Destroyed units will not be enlisted at all.
|
||||
-- @function [parent=#Group] getUnits
|
||||
-- @param #Group self
|
||||
-- @return #list<DCSUnit#Unit> array of Units
|
||||
|
||||
--- Returns controller of the group.
|
||||
-- @function [parent=#Group] getController
|
||||
-- @param #Group self
|
||||
-- @return Controller#Controller
|
||||
|
||||
Group = {} --#Group
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
-------------------------------------------------------------------------------
|
||||
-- @module DCSObject
|
||||
|
||||
--- @type Object
|
||||
-- @field #Object.Category Category
|
||||
-- @field #Object.Desc Desc
|
||||
|
||||
--- @type Object.Category
|
||||
-- @field UNIT
|
||||
-- @field WEAPON
|
||||
-- @field STATIC
|
||||
-- @field SCENERY
|
||||
-- @field BASE
|
||||
|
||||
--- @type Object.Desc
|
||||
-- @extends #Desc
|
||||
-- @field #number life initial life level
|
||||
-- @field #Box3 box bounding box of collision geometry
|
||||
|
||||
--- @function [parent=#Object] isExist
|
||||
-- @param #Object self
|
||||
-- @return #boolean
|
||||
|
||||
--- @function [parent=#Object] destroy
|
||||
-- @param #Object self
|
||||
|
||||
--- @function [parent=#Object] getCategory
|
||||
-- @param #Object self
|
||||
-- @return #Object.Category
|
||||
|
||||
--- Returns type name of the Object.
|
||||
-- @function [parent=#Object] getTypeName
|
||||
-- @param #Object self
|
||||
-- @return #string
|
||||
|
||||
--- Returns object descriptor.
|
||||
-- @function [parent=#Object] getDesc
|
||||
-- @param #Object self
|
||||
-- @return #Object.Desc
|
||||
|
||||
--- Returns true if the object belongs to the category.
|
||||
-- @function [parent=#Object] hasAttribute
|
||||
-- @param #Object self
|
||||
-- @param #AttributeName attributeName Attribute name to check.
|
||||
-- @return #boolean
|
||||
|
||||
--- Returns name of the object. This is the name that is assigned to the object in the Mission Editor.
|
||||
-- @function [parent=#Object] getName
|
||||
-- @param #Object self
|
||||
-- @return #string
|
||||
|
||||
--- Returns object coordinates for current time.
|
||||
-- @function [parent=#Object] getPoint
|
||||
-- @param #Object self
|
||||
-- @return #Vec3
|
||||
|
||||
--- Returns object position for current time.
|
||||
-- @function [parent=#Object] getPosition
|
||||
-- @param #Object self
|
||||
-- @return #Position3
|
||||
|
||||
--- Returns the unit's velocity vector.
|
||||
-- @function [parent=#Object] getVelocity
|
||||
-- @param #Object self
|
||||
-- @return #Vec3
|
||||
|
||||
--- Returns true if the unit is in air.
|
||||
-- @function [parent=#Object] inAir
|
||||
-- @param #Object self
|
||||
-- @return #boolean
|
||||
|
||||
Object = {} --#Object
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
-------------------------------------------------------------------------------
|
||||
-- @module DCSStaticObject
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- @module StaticObject
|
||||
-- @extends CoalitionObject#CoalitionObject
|
||||
|
||||
--- Represents static object added in the Mission Editor.
|
||||
-- @type StaticObject
|
||||
-- @field #StaticObject.ID ID Identifier of a StaticObject. It assigned to an StaticObject by the Mission Editor automatically.
|
||||
-- @field #StaticObject.Desc Desc Descriptor of StaticObject and Unit are equal. StaticObject is just a passive variant of Unit.
|
||||
|
||||
--- StaticObject descriptor. Airdromes are unique and their types are unique, but helipads and ships are not always unique and may have the same type.
|
||||
-- @type StaticObject.Desc
|
||||
-- @extends Unit#Unit.Desc
|
||||
|
||||
--- Returns static object by its name. If no static object found nil will be returned.
|
||||
-- @function [parent=#StaticObject] getByName
|
||||
-- @param #string name Name of static object to find.
|
||||
-- @return #StaticObject
|
||||
|
||||
--- returns identifier of the static object.
|
||||
-- @function [parent=#StaticObject] getID
|
||||
-- @param #StaticObject self
|
||||
-- @return #StaticObject.ID
|
||||
|
||||
--- Returns descriptor of the StaticObject.
|
||||
-- @function [parent=#StaticObject] getDesc
|
||||
-- @param #StaticObject self
|
||||
-- @return #StaticObject.Desc
|
||||
|
||||
|
||||
StaticObject = {} --#StaticObject
|
||||
@@ -1,10 +0,0 @@
|
||||
--- @module DCSTask
|
||||
|
||||
|
||||
--- @type Task
|
||||
-- @field #string id
|
||||
-- @field #Task.param param
|
||||
|
||||
--- @type Task.param
|
||||
|
||||
env.info( "Task defined" )
|
||||
@@ -1,2 +0,0 @@
|
||||
-- @type ModelTime
|
||||
-- @extends #number
|
||||
236
Dcs/DCSTypes.lua
236
Dcs/DCSTypes.lua
@@ -1,236 +0,0 @@
|
||||
-------------------------------------------------------------------------------
|
||||
-- @module DCSTypes
|
||||
|
||||
|
||||
|
||||
--- Time is given in seconds.
|
||||
-- @type Time
|
||||
-- @extends #number
|
||||
|
||||
--- Model time is the time that drives the simulation. Model time may be stopped, accelerated and decelerated relative real time.
|
||||
-- @type ModelTime
|
||||
-- @extends #number
|
||||
|
||||
--- Mission time is a model time plus time of the mission start.
|
||||
-- @type MissionTime
|
||||
-- @extends #number
|
||||
|
||||
|
||||
--- Distance is given in meters.
|
||||
-- @type Distance
|
||||
-- @extends #number
|
||||
|
||||
--- Angle is given in radians.
|
||||
-- @type Angle
|
||||
-- @extends #number
|
||||
|
||||
--- Azimuth is an angle of rotation around world axis y counter-clockwise.
|
||||
-- @type Azimuth
|
||||
-- @extends #number
|
||||
|
||||
--- Mass is given in kilograms.
|
||||
-- @type Mass
|
||||
-- @extends #number
|
||||
|
||||
--- Vec3 type is a 3D-vector.
|
||||
-- DCS world has 3-dimensional coordinate system. DCS ground is an infinite plain.
|
||||
-- @type Vec3
|
||||
-- @field #Distance x is directed to the north
|
||||
-- @field #Distance z is directed to the east
|
||||
-- @field #Distance y is directed up
|
||||
|
||||
--- Vec2 is a 2D-vector for the ground plane as a reference plane.
|
||||
-- @type Vec2
|
||||
-- @field #Distance x Vec2.x = Vec3.x
|
||||
-- @field #Distance y Vec2.y = Vec3.z
|
||||
|
||||
--- Position is a composite structure. It consists of both coordinate vector and orientation matrix. Position3 (also known as "Pos3" for short) is a table that has following format:
|
||||
-- @type Position3
|
||||
-- @field #Vec3 p
|
||||
-- @field #Vec3 x
|
||||
-- @field #Vec3 y
|
||||
-- @field #Vec3 z
|
||||
|
||||
--- 3-dimensional box.
|
||||
-- @type Box3
|
||||
-- @field #Vec3 min
|
||||
-- @field #Vec3 max
|
||||
|
||||
--- Each object belongs to a type. Object type is a named couple of properties those independent of mission and common for all units of the same type. Name of unit type is a string. Samples of unit type: "Su-27", "KAMAZ" and "M2 Bradley".
|
||||
-- @type TypeName
|
||||
-- @extends #string
|
||||
|
||||
|
||||
--- @type AI
|
||||
-- @field #AI.Skill Skill
|
||||
-- @field #AI.Task Task
|
||||
-- @field #AI.Option Option
|
||||
|
||||
--- @type AI.Skill
|
||||
-- @field AVERAGE
|
||||
-- @field GOOD
|
||||
-- @field HIGH
|
||||
-- @field EXCELLENT
|
||||
-- @field PLAYER
|
||||
-- @field CLIENT
|
||||
|
||||
--- @type AI.Task
|
||||
-- @field #AI.Task.WeaponExpend WeaponExpend
|
||||
-- @field #AI.Task.OrbitPattern OrbitPattern
|
||||
-- @field #AI.Task.Designation Designation
|
||||
-- @field #AI.Task.WaypointType WaypointType
|
||||
-- @field #AI.Task.TurnMethod TurnMethod
|
||||
-- @field #AI.Task.AltitudeType AltitudeType
|
||||
-- @field #AI.Task.VehicleFormation VehicleFormation
|
||||
|
||||
--- @type AI.Task.WeaponExpend
|
||||
-- @field ONE
|
||||
-- @field TWO
|
||||
-- @field FOUR
|
||||
-- @field QUARTER
|
||||
-- @field HALF
|
||||
-- @field ALL
|
||||
|
||||
--- @type AI.Task.OrbitPattern
|
||||
-- @field CIRCLE
|
||||
-- @field RACE_TRACK
|
||||
|
||||
--- @type AI.Task.Designation
|
||||
-- @field NO
|
||||
-- @field AUTO
|
||||
-- @field WP
|
||||
-- @field IR_POINTER
|
||||
-- @field LASER
|
||||
|
||||
--- @type AI.Task.WaypointType
|
||||
-- @field TAKEOFF
|
||||
-- @field TAKEOFF_PARKING
|
||||
-- @field TURNING_POINT
|
||||
-- @field LAND
|
||||
|
||||
--- @type AI.Task.TurnMethod
|
||||
-- @field FLY_OVER_POINT
|
||||
-- @field FIN_POINT
|
||||
|
||||
--- @type AI.Task.AltitudeType
|
||||
-- @field BARO
|
||||
-- @field RADIO
|
||||
|
||||
--- @type AI.Task.VehicleFormation
|
||||
-- @field OFF_ROAD
|
||||
-- @field ON_ROAD
|
||||
-- @field RANK
|
||||
-- @field CONE
|
||||
-- @field DIAMOND
|
||||
-- @field VEE
|
||||
-- @field ECHELON_LEFT
|
||||
-- @field ECHELON_RIGHT
|
||||
|
||||
--- @type AI.Option
|
||||
-- @field #AI.Option.Air Air
|
||||
-- @field #AI.Option.Ground Ground
|
||||
-- @field #AI.Option.Naval Naval
|
||||
|
||||
--- @type AI.Option.Air
|
||||
-- @field #AI.Option.Air.id id
|
||||
-- @field #AI.Option.Air.val val
|
||||
|
||||
--- @type AI.Option.Ground
|
||||
-- @field #AI.Option.Ground.id id
|
||||
-- @field #AI.Option.Ground.val val
|
||||
|
||||
--- @type AI.Option.Naval
|
||||
-- @field #AI.Option.Naval.id id
|
||||
-- @field #AI.Option.Naval.val val
|
||||
|
||||
--TODO: work on formation
|
||||
--- @type AI.Option.Air.id
|
||||
-- @field NO_OPTION
|
||||
-- @field ROE
|
||||
-- @field REACTION_ON_THREAT
|
||||
-- @field RADAR_USING
|
||||
-- @field FLARE_USING
|
||||
-- @field FORMATION
|
||||
-- @field RTB_ON_BINGO
|
||||
-- @field SILENCE
|
||||
|
||||
--- @type AI.Option.Air.val
|
||||
-- @field #AI.Option.Air.val.ROE ROE
|
||||
-- @field #AI.Option.Air.val.REACTION_ON_THREAT REACTION_ON_THREAT
|
||||
-- @field #AI.Option.Air.val.RADAR_USING RADAR_USING
|
||||
-- @field #AI.Option.Air.val.FLARE_USING FLARE_USING
|
||||
|
||||
--- @type AI.Option.Air.val.ROE
|
||||
-- @field WEAPON_FREE
|
||||
-- @field OPEN_FIRE_WEAPON_FREE
|
||||
-- @field OPEN_FIRE
|
||||
-- @field RETURN_FIRE
|
||||
-- @field WEAPON_HOLD
|
||||
|
||||
--- @type AI.Option.Air.val.REACTION_ON_THREAT
|
||||
-- @field NO_REACTION
|
||||
-- @field PASSIVE_DEFENCE
|
||||
-- @field EVADE_FIRE
|
||||
-- @field BYPASS_AND_ESCAPE
|
||||
-- @field ALLOW_ABORT_MISSION
|
||||
|
||||
--- @type AI.Option.Air.val.RADAR_USING
|
||||
-- @field NEVER
|
||||
-- @field FOR_ATTACK_ONLY
|
||||
-- @field FOR_SEARCH_IF_REQUIRED
|
||||
-- @field FOR_CONTINUOUS_SEARCH
|
||||
|
||||
--- @type AI.Option.Air.val.FLARE_USING
|
||||
-- @field NEVER
|
||||
-- @field AGAINST_FIRED_MISSILE
|
||||
-- @field WHEN_FLYING_IN_SAM_WEZ
|
||||
-- @field WHEN_FLYING_NEAR_ENEMIES
|
||||
|
||||
--- @type AI.Option.Ground.id
|
||||
-- @field NO_OPTION
|
||||
-- @field ROE @{#AI.Option.Ground.val.ROE}
|
||||
-- @field DISPERSE_ON_ATTACK true or false
|
||||
-- @field ALARM_STATE @{#AI.Option.Ground.val.ALARM_STATE}
|
||||
|
||||
--- @type AI.Option.Ground.val
|
||||
-- @field #AI.Option.Ground.val.ROE ROE
|
||||
-- @field #AI.Option.Ground.val.ALARM_STATE ALARM_STATE
|
||||
|
||||
--- @type AI.Option.Ground.val.ROE
|
||||
-- @field OPEN_FIRE
|
||||
-- @field RETURN_FIRE
|
||||
-- @field WEAPON_HOLD
|
||||
|
||||
--- @type AI.Option.Ground.val.ALARM_STATE
|
||||
-- @field AUTO
|
||||
-- @field GREEN
|
||||
-- @field RED
|
||||
|
||||
--- @type AI.Option.Naval.id
|
||||
-- @field NO_OPTION
|
||||
-- @field ROE
|
||||
|
||||
--- @type AI.Option.Naval.val
|
||||
-- @field #AI.Option.Naval.val.ROE ROE
|
||||
|
||||
--- @type AI.Option.Naval.val.ROE
|
||||
-- @field OPEN_FIRE
|
||||
-- @field RETURN_FIRE
|
||||
-- @field WEAPON_HOLD
|
||||
|
||||
AI = {} --#AI
|
||||
|
||||
|
||||
--- @type Desc
|
||||
-- @field #TypeName typeName type name
|
||||
-- @field #string displayName localized display name
|
||||
-- @field #table attributes object type attributes
|
||||
|
||||
--- A distance type
|
||||
-- @type Distance
|
||||
|
||||
--- An angle type
|
||||
-- @type Angle
|
||||
|
||||
env.info( 'AI types created' )
|
||||
|
||||
241
Dcs/DCSUnit.lua
241
Dcs/DCSUnit.lua
@@ -1,241 +0,0 @@
|
||||
-------------------------------------------------------------------------------
|
||||
-- @module DCSUnit
|
||||
|
||||
--- @type Unit
|
||||
-- @extends DCSCoalitionObject#CoalitionObject
|
||||
-- @field ID Identifier of an unit. It assigned to an unit by the Mission Editor automatically.
|
||||
-- @field #Unit.Category Category
|
||||
-- @field #Unit.RefuelingSystem RefuelingSystem
|
||||
-- @field #Unit.SensorType SensorType
|
||||
-- @field #Unit.OpticType OpticType
|
||||
-- @field #Unit.RadarType RadarType
|
||||
-- @field #Unit.Desc Desc
|
||||
-- @field #Unit.DescAircraft DescAircraft
|
||||
-- @field #Unit.DescAirplane DescAirplane
|
||||
-- @field #Unit.DescHelicopter DescHelicopter
|
||||
-- @field #Unit.DescVehicle DescVehicle
|
||||
-- @field #Unit.DescShip DescShip
|
||||
-- @field #Unit.AmmoItem AmmoItem
|
||||
-- @field #list<#Unit.AmmoItem> Ammo
|
||||
-- @field #Unit.Sensor Sensor
|
||||
-- @field #Unit.Optic Optic
|
||||
-- @field #Unit.Radar Radar
|
||||
-- @field #Unit.IRST IRST
|
||||
|
||||
|
||||
--- Enum that stores unit categories.
|
||||
-- @type Unit.Category
|
||||
-- @field AIRPLANE
|
||||
-- @field HELICOPTER
|
||||
-- @field GROUND_UNIT
|
||||
-- @field SHIP
|
||||
-- @field STRUCTURE
|
||||
|
||||
--- Enum that stores aircraft refueling system types.
|
||||
-- @type Unit.RefuelingSystem
|
||||
-- @field BOOM_AND_RECEPTACLE
|
||||
-- @field PROBE_AND_DROGUE
|
||||
|
||||
--- Enum that stores sensor types.
|
||||
-- @type Unit.SensorType
|
||||
-- @field OPTIC
|
||||
-- @field RADAR
|
||||
-- @field IRST
|
||||
-- @field RWR
|
||||
|
||||
--- Enum that stores types of optic sensors.
|
||||
-- @type Unit.OpticType
|
||||
-- @field TV TV-sensor
|
||||
-- @field LLTV Low-level TV-sensor
|
||||
-- @field IR Infra-Red optic sensor
|
||||
|
||||
--- Enum that stores radar types.
|
||||
-- @type Unit.RadarType
|
||||
-- @field AS air search radar
|
||||
-- @field SS surface/land search radar
|
||||
|
||||
|
||||
--- A unit descriptor.
|
||||
-- @type Unit.Desc
|
||||
-- @extends Object#Object.Desc
|
||||
-- @field #Unit.Category category Unit Category
|
||||
-- @field #Mass massEmpty mass of empty unit
|
||||
-- @field #number speedMax istance / Time, --maximal velocity
|
||||
|
||||
--- An aircraft descriptor.
|
||||
-- @type Unit.DescAircraft
|
||||
-- @extends Unit#Unit.Desc
|
||||
-- @field #Mass fuelMassMax maximal inner fuel mass
|
||||
-- @field #Distance range Operational range
|
||||
-- @field #Distance Hmax Ceiling
|
||||
-- @field #number VyMax #Distance / #Time, --maximal climb rate
|
||||
-- @field #number NyMin minimal safe acceleration
|
||||
-- @field #number NyMax maximal safe acceleration
|
||||
-- @field #Unit.RefuelingSystem tankerType refueling system type
|
||||
|
||||
--- An airplane descriptor.
|
||||
-- @type Unit.DescAirplane
|
||||
-- @extends Unit#Unit.DescAircraft
|
||||
-- @field #number speedMax0 Distance / Time maximal TAS at ground level
|
||||
-- @field #number speedMax10K Distance / Time maximal TAS at altitude of 10 km
|
||||
|
||||
--- A helicopter descriptor.
|
||||
-- @type Unit.DescHelicopter
|
||||
-- @extends Unit#Unit.DescAircraft
|
||||
-- @field #Distance HmaxStat static ceiling
|
||||
|
||||
--- A vehicle descriptor.
|
||||
-- @type Unit.DescVehicle
|
||||
-- @extends Unit#Unit.Desc
|
||||
-- @field #Angle maxSlopeAngle maximal slope angle
|
||||
-- @field #boolean riverCrossing can the vehicle cross a rivers
|
||||
|
||||
--- A ship descriptor.
|
||||
-- @type Unit.DescShip
|
||||
-- @extends #Unit.Desc
|
||||
|
||||
--- ammunition item: "type-count" pair.
|
||||
-- @type Unit.AmmoItem
|
||||
-- @field #Weapon.Desc desc ammunition descriptor
|
||||
-- @field #number count ammunition count
|
||||
|
||||
--- A unit sensor.
|
||||
-- @type Unit.Sensor
|
||||
-- @field #TypeName typeName
|
||||
-- @field #Unit.SensorType type
|
||||
|
||||
--- An optic sensor.
|
||||
-- @type Unit.Optic
|
||||
-- @extends Unit#Unit.Sensor
|
||||
-- @field #Unit.OpticType opticType
|
||||
|
||||
--- A radar.
|
||||
-- @type Unit.Radar
|
||||
-- @extends Unit#Unit.Sensor
|
||||
-- @field #Distance detectionDistanceRBM detection distance for RCS=1m^2 in real-beam mapping mode, nil if radar doesn't support surface/land search
|
||||
-- @field #Distance detectionDistanceHRM detection distance for RCS=1m^2 in high-resolution mapping mode, nil if radar has no HRM
|
||||
-- @field #Unit.Radar.detectionDistanceAir detectionDistanceAir detection distance for RCS=1m^2 airborne target, nil if radar doesn't support air search
|
||||
|
||||
--- @type Unit.Radar.detectionDistanceAir
|
||||
-- @field #Unit.Radar.detectionDistanceAir.upperHemisphere upperHemisphere
|
||||
-- @field #Unit.Radar.detectionDistanceAir.lowerHemisphere lowerHemisphere
|
||||
|
||||
--- @type Unit.Radar.detectionDistanceAir.upperHemisphere
|
||||
-- @field #Distance headOn
|
||||
-- @field #Distance tailOn
|
||||
|
||||
--- @type Unit.Radar.detectionDistanceAir.lowerHemisphere
|
||||
-- @field #Distance headOn
|
||||
-- @field #Distance tailOn
|
||||
|
||||
--- An IRST.
|
||||
-- @type Unit#Unit.IRST
|
||||
-- @extends Unit.Sensor
|
||||
-- @field #Distance detectionDistanceIdle detection of tail-on target with heat signature = 1 in upper hemisphere, engines are in idle
|
||||
-- @field #Distance detectionDistanceMaximal ..., engines are in maximal mode
|
||||
-- @field #Distance detectionDistanceAfterburner ..., engines are in afterburner mode
|
||||
|
||||
--- An RWR.
|
||||
-- @type Unit.RWR
|
||||
-- @extends Unit#Unit.Sensor
|
||||
|
||||
--- table that stores all unit sensors.
|
||||
-- TODO @type Sensors
|
||||
--
|
||||
|
||||
|
||||
--- Returns unit object by the name assigned to the unit in Mission Editor. If there is unit with such name or the unit is destroyed the function will return nil. The function provides access to non-activated units too.
|
||||
-- @function [parent=#Unit] getByName
|
||||
-- @param #string name
|
||||
-- @return #Unit
|
||||
|
||||
--- Returns if the unit is activated.
|
||||
-- @function [parent=#Unit] isActive
|
||||
-- @param #Unit self
|
||||
-- @return #boolean
|
||||
|
||||
--- Returns name of the player that control the unit or nil if the unit is controlled by A.I.
|
||||
-- @function [parent=#Unit] getPlayerName
|
||||
-- @param #Unit self
|
||||
-- @return #string
|
||||
|
||||
--- returns the unit's unique identifier.
|
||||
-- @function [parent=#Unit] getID
|
||||
-- @param #Unit self
|
||||
-- @return #Unit.ID
|
||||
|
||||
|
||||
--- Returns the unit's number in the group. The number is the same number the unit has in ME. It may not be changed during the mission. If any unit in the group is destroyed, the numbers of another units will not be changed.
|
||||
-- @function [parent=#Unit] getNumber
|
||||
-- @param #Unit self
|
||||
-- @return #number
|
||||
|
||||
--- Returns controller of the unit if it exist and nil otherwise
|
||||
-- @function [parent=#Unit] getController
|
||||
-- @param #Unit self
|
||||
-- @return #Controller
|
||||
|
||||
--- Returns the unit's group if it exist and nil otherwise
|
||||
-- @function [parent=#Unit] getGroup
|
||||
-- @param #Unit self
|
||||
-- @return DCSGroup#Group
|
||||
|
||||
--- Returns the unit's callsign - the localized string.
|
||||
-- @function [parent=#Unit] getCallsign
|
||||
-- @param #Unit self
|
||||
-- @return #string
|
||||
|
||||
--- Returns the unit's health. Dead units has health <= 1.0
|
||||
-- @function [parent=#Unit] getLife
|
||||
-- @param #Unit self
|
||||
-- @return #number
|
||||
|
||||
--- returns the unit's initial health.
|
||||
-- @function [parent=#Unit] getLife0
|
||||
-- @param #Unit self
|
||||
-- @return #number
|
||||
|
||||
--- Returns relative amount of fuel (from 0.0 to 1.0) the unit has in its internal tanks. If there are additional fuel tanks the value may be greater than 1.0.
|
||||
-- @function [parent=#Unit] getFuel
|
||||
-- @param #Unit self
|
||||
-- @return #number
|
||||
|
||||
--- Returns the unit ammunition.
|
||||
-- @function [parent=#Unit] getAmmo
|
||||
-- @param #Unit self
|
||||
-- @return #Unit.Ammo
|
||||
|
||||
--- Returns the unit sensors.
|
||||
-- @function [parent=#Unit] getSensors
|
||||
-- @param #Unit self
|
||||
-- @return #Unit.Sensors
|
||||
|
||||
--- Returns true if the unit has specified types of sensors. This function is more preferable than Unit.getSensors() if you don't want to get information about all the unit's sensors, and just want to check if the unit has specified types of sensors.
|
||||
-- @function [parent=#Unit] hasSensors
|
||||
-- @param #Unit self
|
||||
-- @param #Unit.SensorType sensorType (= nil) Sensor type.
|
||||
-- @param ... Additional parameters.
|
||||
-- @return #boolean
|
||||
-- @usage
|
||||
-- If sensorType is Unit.SensorType.OPTIC, additional parameters are optic sensor types. Following example checks if the unit has LLTV or IR optics:
|
||||
-- unit:hasSensors(Unit.SensorType.OPTIC, Unit.OpticType.LLTV, Unit.OpticType.IR)
|
||||
-- If sensorType is Unit.SensorType.RADAR, additional parameters are radar types. Following example checks if the unit has air search radars:
|
||||
-- unit:hasSensors(Unit.SensorType.RADAR, Unit.RadarType.AS)
|
||||
-- If no additional parameters are specified the function returns true if the unit has at least one sensor of specified type.
|
||||
-- If sensor type is not specified the function returns true if the unit has at least one sensor of any type.
|
||||
--
|
||||
|
||||
--- returns two values:
|
||||
-- First value indicates if at least one of the unit's radar(s) is on.
|
||||
-- Second value is the object of the radar's interest. Not nil only if at least one radar of the unit is tracking a target.
|
||||
-- @function [parent=#Unit] getRadar
|
||||
-- @param #Unit self
|
||||
-- @return #boolean, Object#Object
|
||||
|
||||
--- Returns unit descriptor. Descriptor type depends on unit category.
|
||||
-- @function [parent=#Unit] getDesc
|
||||
-- @param #Unit self
|
||||
-- @return #Unit.Desc
|
||||
|
||||
|
||||
Unit = {} --#Unit
|
||||
@@ -1,27 +0,0 @@
|
||||
-------------------------------------------------------------------------------
|
||||
-- @module env
|
||||
|
||||
--- @type env
|
||||
|
||||
--- Add message to simulator log with caption "INFO". Message box is optional.
|
||||
-- @function [parent=#env] info
|
||||
-- @field #string message message string to add to log.
|
||||
-- @field #boolean showMessageBox If the parameter is true Message Box will appear. Optional.
|
||||
|
||||
--- Add message to simulator log with caption "WARNING". Message box is optional.
|
||||
-- @function [parent=#env] warning
|
||||
-- @field #string message message string to add to log.
|
||||
-- @field #boolean showMessageBox If the parameter is true Message Box will appear. Optional.
|
||||
|
||||
--- Add message to simulator log with caption "ERROR". Message box is optional.
|
||||
-- @function [parent=#env] error
|
||||
-- @field #string message message string to add to log.
|
||||
-- @field #boolean showMessageBox If the parameter is true Message Box will appear. Optional.
|
||||
|
||||
--- Enables/disables appearance of message box each time lua error occurs.
|
||||
-- @function [parent=#env] setErrorMessageBoxEnabled
|
||||
-- @field #boolean on if true message box appearance is enabled.
|
||||
|
||||
|
||||
|
||||
env = {} --#env
|
||||
@@ -1,20 +0,0 @@
|
||||
-------------------------------------------------------------------------------
|
||||
-- @module land
|
||||
|
||||
--- @type land
|
||||
-- @field #land.SurfaceType SurfaceType
|
||||
|
||||
|
||||
--- @type land.SurfaceType
|
||||
-- @field LAND
|
||||
-- @field SHALLOW_WATER
|
||||
-- @field WATER
|
||||
-- @field ROAD
|
||||
-- @field RUNWAY
|
||||
|
||||
--- Returns altitude MSL of the point.
|
||||
-- @function [parent=#land] getHeight
|
||||
-- @param #Vec2 point point on the ground.
|
||||
-- @return DCSTypes#Distance
|
||||
|
||||
land = {} --#land
|
||||
@@ -1,45 +0,0 @@
|
||||
-------------------------------------------------------------------------------
|
||||
-- @module DCStimer
|
||||
|
||||
--- @type timer
|
||||
|
||||
|
||||
--- Returns model time in seconds.
|
||||
-- @function [parent=#timer] getTime
|
||||
-- @return #Time
|
||||
|
||||
--- Returns mission time in seconds.
|
||||
-- @function [parent=#timer] getAbsTime
|
||||
-- @return #Time
|
||||
|
||||
--- Returns mission start time in seconds.
|
||||
-- @function [parent=#timer] getTime0
|
||||
-- @return #Time
|
||||
|
||||
--- Schedules function to call at desired model time.
|
||||
-- Time function FunctionToCall(any argument, Time time)
|
||||
--
|
||||
-- ...
|
||||
--
|
||||
-- return ...
|
||||
--
|
||||
-- end
|
||||
--
|
||||
-- Must return model time of next call or nil. Note that the DCS scheduler calls the function in protected mode and any Lua errors in the called function will be trapped and not reported. If the function triggers a Lua error then it will be terminated and not scheduled to run again.
|
||||
-- @function [parent=#timer] scheduleFunction
|
||||
-- @param #FunctionToCall functionToCall Lua-function to call. Must have prototype of FunctionToCall.
|
||||
-- @param functionArgument Function argument of any type to pass to functionToCall.
|
||||
-- @param #Time time Model time of the function call.
|
||||
-- @return functionId
|
||||
|
||||
--- Re-schedules function to call at another model time.
|
||||
-- @function [parent=#timer] setFunctionTime
|
||||
-- @param functionId Lua-function to call. Must have prototype of FunctionToCall.
|
||||
-- @param #Time time Model time of the function call.
|
||||
|
||||
|
||||
--- Removes the function from schedule.
|
||||
-- @function [parent=#timer] removeFunction
|
||||
-- @param functionId Function identifier to remove from schedule
|
||||
|
||||
timer = {} --#timer
|
||||
@@ -1,35 +0,0 @@
|
||||
-------------------------------------------------------------------------------
|
||||
-- @module DCSWorld
|
||||
|
||||
--- @type world
|
||||
-- @field #world.event event
|
||||
|
||||
|
||||
--- @type world.event
|
||||
-- @field S_EVENT_INVALID
|
||||
-- @field S_EVENT_SHOT
|
||||
-- @field S_EVENT_HIT
|
||||
-- @field S_EVENT_TAKEOFF
|
||||
-- @field S_EVENT_LAND
|
||||
-- @field S_EVENT_CRASH
|
||||
-- @field S_EVENT_EJECTION
|
||||
-- @field S_EVENT_REFUELING
|
||||
-- @field S_EVENT_DEAD
|
||||
-- @field S_EVENT_PILOT_DEAD
|
||||
-- @field S_EVENT_BASE_CAPTURED
|
||||
-- @field S_EVENT_MISSION_START
|
||||
-- @field S_EVENT_MISSION_END
|
||||
-- @field S_EVENT_TOOK_CONTROL
|
||||
-- @field S_EVENT_REFUELING_STOP
|
||||
-- @field S_EVENT_BIRTH
|
||||
-- @field S_EVENT_HUMAN_FAILURE
|
||||
-- @field S_EVENT_ENGINE_STARTUP
|
||||
-- @field S_EVENT_ENGINE_SHUTDOWN
|
||||
-- @field S_EVENT_PLAYER_ENTER_UNIT
|
||||
-- @field S_EVENT_PLAYER_LEAVE_UNIT
|
||||
-- @field S_EVENT_PLAYER_COMMENT
|
||||
-- @field S_EVENT_SHOOTING_START
|
||||
-- @field S_EVENT_SHOOTING_END
|
||||
-- @field S_EVENT_MAX
|
||||
|
||||
world = {} --#world
|
||||
@@ -1,967 +0,0 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" href="stylesheet.css" type="text/css"/>
|
||||
</head>
|
||||
<body>
|
||||
<div id="container">
|
||||
<div id="product">
|
||||
<div id="product_logo"></div>
|
||||
<div id="product_name"><big><b></b></big></div>
|
||||
<div id="product_description"></div>
|
||||
</div>
|
||||
<div id="main">
|
||||
<div id="navigation">
|
||||
<h2>Modules</h2>
|
||||
<ul><li>
|
||||
<a href="index.html">index</a>
|
||||
</li></ul>
|
||||
<ul>
|
||||
<li>Base</li>
|
||||
<li><a href="CARGO.html">CARGO</a></li>
|
||||
<li><a href="CleanUp.html">CleanUp</a></li>
|
||||
<li><a href="Client.html">Client</a></li>
|
||||
<li><a href="DCSAirbase.html">DCSAirbase</a></li>
|
||||
<li><a href="DCSCoalitionObject.html">DCSCoalitionObject</a></li>
|
||||
<li><a href="DCSCommand.html">DCSCommand</a></li>
|
||||
<li><a href="DCSController.html">DCSController</a></li>
|
||||
<li><a href="DCSGroup.html">DCSGroup</a></li>
|
||||
<li><a href="DCSObject.html">DCSObject</a></li>
|
||||
<li><a href="DCSTask.html">DCSTask</a></li>
|
||||
<li><a href="DCSTypes.html">DCSTypes</a></li>
|
||||
<li><a href="DCSUnit.html">DCSUnit</a></li>
|
||||
<li><a href="DCSWorld.html">DCSWorld</a></li>
|
||||
<li><a href="DCStimer.html">DCStimer</a></li>
|
||||
<li><a href="DEPLOYTASK.html">DEPLOYTASK</a></li>
|
||||
<li><a href="DESTROYBASETASK.html">DESTROYBASETASK</a></li>
|
||||
<li><a href="DESTROYGROUPSTASK.html">DESTROYGROUPSTASK</a></li>
|
||||
<li><a href="DESTROYRADARSTASK.html">DESTROYRADARSTASK</a></li>
|
||||
<li><a href="DESTROYUNITTYPESTASK.html">DESTROYUNITTYPESTASK</a></li>
|
||||
<li><a href="Database.html">Database</a></li>
|
||||
<li><a href="Escort.html">Escort</a></li>
|
||||
<li><a href="Event.html">Event</a></li>
|
||||
<li><a href="GOHOMETASK.html">GOHOMETASK</a></li>
|
||||
<li><a href="Group.html">Group</a></li>
|
||||
<li><a href="MISSION.html">MISSION</a></li>
|
||||
<li><a href="MOVEMENT.html">MOVEMENT</a></li>
|
||||
<li><a href="Menu.html">Menu</a></li>
|
||||
<li><a href="Message.html">Message</a></li>
|
||||
<li><a href="NOTASK.html">NOTASK</a></li>
|
||||
<li><a href="PICKUPTASK.html">PICKUPTASK</a></li>
|
||||
<li><a href="ROUTETASK.html">ROUTETASK</a></li>
|
||||
<li><a href="STAGE.html">STAGE</a></li>
|
||||
<li><a href="Scoring.html">Scoring</a></li>
|
||||
<li><a href="Sead.html">Sead</a></li>
|
||||
<li><a href="Spawn.html">Spawn</a></li>
|
||||
<li><a href="StaticObject.html">StaticObject</a></li>
|
||||
<li><a href="TASK.html">TASK</a></li>
|
||||
<li><a href="Unit.html">Unit</a></li>
|
||||
<li><a href="Zone.html">Zone</a></li>
|
||||
<li><a href="env.html">env</a></li>
|
||||
<li><a href="land.html">land</a></li>
|
||||
<li><a href="routines.html">routines</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="content">
|
||||
<h1>Module <code>Base</code></h1>
|
||||
|
||||
<p>BASE classes.</p>
|
||||
|
||||
|
||||
|
||||
<h1><a href="##(BASE)">#BASE</a> class</h1>
|
||||
<p>The <a href="##(BASE)">#BASE</a> class is the super class for most of the classes defined within MOOSE.</p>
|
||||
|
||||
<p>It handles:</p>
|
||||
|
||||
<ul>
|
||||
<li>The construction and inheritance of child classes.</li>
|
||||
<li>The tracing of objects during mission execution within the DCS.log file (under saved games folder).</li>
|
||||
</ul>
|
||||
|
||||
<p>Note: Normally you would not use the BASE class unless you are extending the MOOSE framework with new classes.</p>
|
||||
|
||||
<h1>BASE Trace functionality</h1>
|
||||
<p>The BASE class contains trace methods to trace progress within a mission execution of a certain object.
|
||||
Note that these trace methods are inherited by each MOOSE class interiting BASE.
|
||||
As such, each object created from derived class from BASE can use the tracing functions to trace its execution.</p>
|
||||
|
||||
<h2>Trace a function call</h2>
|
||||
<p>There are basically 3 types of tracing methods available within BASE:</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="##(BASE).F">BASE.F</a>: Trace the beginning of a function and its given parameters.</li>
|
||||
<li><a href="##(BASE).T">BASE.T</a>: Trace further logic within a function giving optional variables or parameters.</li>
|
||||
<li><a href="##(BASE).E">BASE.E</a>: Trace an execption within a function giving optional variables or parameters. An exception will always be traced.</li>
|
||||
</ul>
|
||||
|
||||
<h2>Tracing levels</h2>
|
||||
<p>There are 3 tracing levels within MOOSE. <br/>
|
||||
These tracing levels were defined to avoid bulks of tracing to be generated by lots of objects.</p>
|
||||
|
||||
<p>As such, the F and T methods have additional variants to trace level 2 and 3 respectively:</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="##(BASE).F2">BASE.F2</a>: Trace the beginning of a function and its given parameters with tracing level 2.</li>
|
||||
<li><a href="##(BASE).F3">BASE.F3</a>: Trace the beginning of a function and its given parameters with tracing level 3.</li>
|
||||
<li><a href="##(BASE).T2">BASE.T2</a>: Trace further logic within a function giving optional variables or parameters with tracing level 2.</li>
|
||||
<li><a href="##(BASE).T3">BASE.T3</a>: Trace further logic within a function giving optional variables or parameters with tracing level 3.</li>
|
||||
</ul>
|
||||
|
||||
<h1>BASE Inheritance support</h1>
|
||||
<p>The following methods are available to support inheritance:</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="##(BASE).Inherit">BASE.Inherit</a>: Inherits from a class.</li>
|
||||
<li><a href="##(BASE).Inherited">BASE.Inherited</a>: Returns the parent class from the class.</li>
|
||||
</ul>
|
||||
|
||||
<h1>Future</h1>
|
||||
<p>Further methods may be added to BASE whenever there is a need to make "overall" functions available within MOOSE.</p>
|
||||
|
||||
<hr/>
|
||||
|
||||
|
||||
<h2>Global(s)</h2>
|
||||
<table class="function_list">
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="#BASE">BASE</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="#FORMATION">FORMATION</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<h2><a id="#(BASE)">Type <code>BASE</code></a></h2>
|
||||
<table class="function_list">
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(BASE).AddEvent">BASE:AddEvent(Event, EventFunction)</a></td>
|
||||
<td class="summary">
|
||||
<p>Set a new listener for the class.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(BASE).ClassID">BASE.ClassID</a></td>
|
||||
<td class="summary">
|
||||
<p>The ID number of the class.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(BASE).ClassName">BASE.ClassName</a></td>
|
||||
<td class="summary">
|
||||
<p>The name of the class.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(BASE).CreateEventBirth">BASE:CreateEventBirth(EventTime, Initiator, IniUnitName, place, subplace)</a></td>
|
||||
<td class="summary">
|
||||
<p>Creation of a Birth Event.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(BASE).CreateEventCrash">BASE:CreateEventCrash(EventTime, Initiator)</a></td>
|
||||
<td class="summary">
|
||||
<p>Creation of a Crash Event.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(BASE).DisableEvents">BASE:DisableEvents()</a></td>
|
||||
<td class="summary">
|
||||
<p>Disable the event listeners for the class.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(BASE).E">BASE:E(Arguments)</a></td>
|
||||
<td class="summary">
|
||||
<p>Log an exception which will be traced always.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(BASE).EnableEvents">BASE:EnableEvents()</a></td>
|
||||
<td class="summary">
|
||||
<p>Enable the event listeners for the class.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(BASE).Event">BASE:Event()</a></td>
|
||||
<td class="summary">
|
||||
<p>Returns the event dispatcher</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(BASE).Events">BASE.Events</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(BASE).F">BASE:F(Arguments)</a></td>
|
||||
<td class="summary">
|
||||
<p>Trace a function call.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(BASE).F2">BASE:F2(Arguments)</a></td>
|
||||
<td class="summary">
|
||||
<p>Trace a function call level 2.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(BASE).F3">BASE:F3(Arguments)</a></td>
|
||||
<td class="summary">
|
||||
<p>Trace a function call level 3.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(BASE).GetClassID">BASE:GetClassID()</a></td>
|
||||
<td class="summary">
|
||||
<p>Get the ClassID of the class instance.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(BASE).GetClassName">BASE:GetClassName()</a></td>
|
||||
<td class="summary">
|
||||
<p>Get the ClassName of the class instance.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(BASE).GetClassNameAndID">BASE:GetClassNameAndID()</a></td>
|
||||
<td class="summary">
|
||||
<p>Get the ClassName + ClassID of the class instance.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(BASE).Inherit">BASE:Inherit(Child, Parent)</a></td>
|
||||
<td class="summary">
|
||||
<p>This is the worker method to inherit from a parent class.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(BASE).Inherited">BASE:Inherited(Child)</a></td>
|
||||
<td class="summary">
|
||||
<p>This is the worker method to retrieve the Parent class.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(BASE).New">BASE:New()</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(BASE).T">BASE:T(Arguments)</a></td>
|
||||
<td class="summary">
|
||||
<p>Trace a function logic.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(BASE).T2">BASE:T2(Arguments)</a></td>
|
||||
<td class="summary">
|
||||
<p>Trace a function logic level 2.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(BASE).T3">BASE:T3(Arguments)</a></td>
|
||||
<td class="summary">
|
||||
<p>Trace a function logic level 3.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(BASE).TraceClass">BASE:TraceClass(Class)</a></td>
|
||||
<td class="summary">
|
||||
<p>Set tracing for a class</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(BASE).TraceClassMethod">BASE:TraceClassMethod(Class, Method)</a></td>
|
||||
<td class="summary">
|
||||
<p>Set tracing for a specific method of class</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(BASE).TraceLevel">BASE:TraceLevel(Level)</a></td>
|
||||
<td class="summary">
|
||||
<p>Set trace level</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(BASE).onEvent">BASE:onEvent(event)</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2><a id="#(FORMATION)">Type <code>FORMATION</code></a></h2>
|
||||
<table class="function_list">
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(FORMATION).Cone">FORMATION.Cone</a></td>
|
||||
<td class="summary">
|
||||
<p>A cone formation.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2>Global(s)</h2>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em><a href="##(BASE)">#BASE</a></em>
|
||||
<a id="BASE" >
|
||||
<strong>BASE</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em><a href="##(FORMATION)">#FORMATION</a></em>
|
||||
<a id="FORMATION" >
|
||||
<strong>FORMATION</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<h2><a id="#(Base)" >Type <code>Base</code></a></h2>
|
||||
|
||||
<h2><a id="#(BASE)" >Type <code>BASE</code></a></h2>
|
||||
|
||||
<p>The BASE Class</p>
|
||||
|
||||
<h3>Field(s)</h3>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(BASE).AddEvent" >
|
||||
<strong>BASE:AddEvent(Event, EventFunction)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Set a new listener for the class.</p>
|
||||
|
||||
<h3>Parameters</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em><a href="DCSTypes.html##(Event)">DCSTypes#Event</a> Event </em></code>: </p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em>#function EventFunction </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
<h3>Return value</h3>
|
||||
|
||||
<p><em><a href="##(BASE)">#BASE</a>:</em></p>
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(BASE).ClassID" >
|
||||
<strong>BASE.ClassID</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>The ID number of the class.</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(BASE).ClassName" >
|
||||
<strong>BASE.ClassName</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>The name of the class.</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(BASE).CreateEventBirth" >
|
||||
<strong>BASE:CreateEventBirth(EventTime, Initiator, IniUnitName, place, subplace)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Creation of a Birth Event.</p>
|
||||
|
||||
<h3>Parameters</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em><a href="DCSTypes.html##(Time)">DCSTypes#Time</a> EventTime </em></code>:
|
||||
The time stamp of the event.</p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em><a href="DCSObject.html##(Object)">DCSObject#Object</a> Initiator </em></code>:
|
||||
The initiating object of the event.</p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em>#string IniUnitName </em></code>:
|
||||
The initiating unit name.</p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> place </em></code>: </p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> subplace </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(BASE).CreateEventCrash" >
|
||||
<strong>BASE:CreateEventCrash(EventTime, Initiator)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Creation of a Crash Event.</p>
|
||||
|
||||
<h3>Parameters</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em><a href="DCSTypes.html##(Time)">DCSTypes#Time</a> EventTime </em></code>:
|
||||
The time stamp of the event.</p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em><a href="DCSObject.html##(Object)">DCSObject#Object</a> Initiator </em></code>:
|
||||
The initiating object of the event.</p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(BASE).DisableEvents" >
|
||||
<strong>BASE:DisableEvents()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Disable the event listeners for the class.</p>
|
||||
|
||||
<h3>Return value</h3>
|
||||
|
||||
<p><em><a href="##(BASE)">#BASE</a>:</em></p>
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(BASE).E" >
|
||||
<strong>BASE:E(Arguments)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Log an exception which will be traced always.</p>
|
||||
|
||||
|
||||
<p>Can be anywhere within the function logic.</p>
|
||||
|
||||
<h3>Parameter</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em> Arguments </em></code>:
|
||||
A #table or any field.</p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(BASE).EnableEvents" >
|
||||
<strong>BASE:EnableEvents()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Enable the event listeners for the class.</p>
|
||||
|
||||
<h3>Return value</h3>
|
||||
|
||||
<p><em><a href="##(BASE)">#BASE</a>:</em></p>
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(BASE).Event" >
|
||||
<strong>BASE:Event()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Returns the event dispatcher</p>
|
||||
|
||||
<h3>Return value</h3>
|
||||
|
||||
<p><em><a href="Event.html##(EVENT)">Event#EVENT</a>:</em></p>
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em></em>
|
||||
<a id="#(BASE).Events" >
|
||||
<strong>BASE.Events</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(BASE).F" >
|
||||
<strong>BASE:F(Arguments)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Trace a function call.</p>
|
||||
|
||||
|
||||
<p>Must be at the beginning of the function logic.</p>
|
||||
|
||||
<h3>Parameter</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em> Arguments </em></code>:
|
||||
A #table or any field.</p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(BASE).F2" >
|
||||
<strong>BASE:F2(Arguments)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Trace a function call level 2.</p>
|
||||
|
||||
|
||||
<p>Must be at the beginning of the function logic.</p>
|
||||
|
||||
<h3>Parameter</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em> Arguments </em></code>:
|
||||
A #table or any field.</p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(BASE).F3" >
|
||||
<strong>BASE:F3(Arguments)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Trace a function call level 3.</p>
|
||||
|
||||
|
||||
<p>Must be at the beginning of the function logic.</p>
|
||||
|
||||
<h3>Parameter</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em> Arguments </em></code>:
|
||||
A #table or any field.</p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(BASE).GetClassID" >
|
||||
<strong>BASE:GetClassID()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Get the ClassID of the class instance.</p>
|
||||
|
||||
<h3>Return value</h3>
|
||||
|
||||
<p><em>#string:</em>
|
||||
The ClassID of the class instance.</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(BASE).GetClassName" >
|
||||
<strong>BASE:GetClassName()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Get the ClassName of the class instance.</p>
|
||||
|
||||
<h3>Return value</h3>
|
||||
|
||||
<p><em>#string:</em>
|
||||
The ClassName of the class instance.</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(BASE).GetClassNameAndID" >
|
||||
<strong>BASE:GetClassNameAndID()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Get the ClassName + ClassID of the class instance.</p>
|
||||
|
||||
|
||||
<p>The ClassName + ClassID is formatted as '%s#%09d'. </p>
|
||||
|
||||
<h3>Return value</h3>
|
||||
|
||||
<p><em>#string:</em>
|
||||
The ClassName + ClassID of the class instance.</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(BASE).Inherit" >
|
||||
<strong>BASE:Inherit(Child, Parent)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>This is the worker method to inherit from a parent class.</p>
|
||||
|
||||
<h3>Parameters</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em> Child </em></code>:
|
||||
is the Child class that inherits.</p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em><a href="##(BASE)">#BASE</a> Parent </em></code>:
|
||||
is the Parent class that the Child inherits from.</p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
<h3>Return value</h3>
|
||||
|
||||
<p><em><a href="##(BASE)">#BASE</a>:</em>
|
||||
Child</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(BASE).Inherited" >
|
||||
<strong>BASE:Inherited(Child)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>This is the worker method to retrieve the Parent class.</p>
|
||||
|
||||
<h3>Parameter</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em><a href="##(BASE)">#BASE</a> Child </em></code>:
|
||||
is the Child class from which the Parent class needs to be retrieved.</p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
<h3>Return value</h3>
|
||||
|
||||
<p><em><a href="##(BASE)">#BASE</a>:</em></p>
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(BASE).New" >
|
||||
<strong>BASE:New()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(BASE).T" >
|
||||
<strong>BASE:T(Arguments)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Trace a function logic.</p>
|
||||
|
||||
|
||||
<p>Can be anywhere within the function logic.</p>
|
||||
|
||||
<h3>Parameter</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em> Arguments </em></code>:
|
||||
A #table or any field.</p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(BASE).T2" >
|
||||
<strong>BASE:T2(Arguments)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Trace a function logic level 2.</p>
|
||||
|
||||
|
||||
<p>Can be anywhere within the function logic.</p>
|
||||
|
||||
<h3>Parameter</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em> Arguments </em></code>:
|
||||
A #table or any field.</p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(BASE).T3" >
|
||||
<strong>BASE:T3(Arguments)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Trace a function logic level 3.</p>
|
||||
|
||||
|
||||
<p>Can be anywhere within the function logic.</p>
|
||||
|
||||
<h3>Parameter</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em> Arguments </em></code>:
|
||||
A #table or any field.</p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(BASE).TraceClass" >
|
||||
<strong>BASE:TraceClass(Class)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Set tracing for a class</p>
|
||||
|
||||
<h3>Parameter</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em>#string Class </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(BASE).TraceClassMethod" >
|
||||
<strong>BASE:TraceClassMethod(Class, Method)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Set tracing for a specific method of class</p>
|
||||
|
||||
<h3>Parameters</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em>#string Class </em></code>: </p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em>#string Method </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(BASE).TraceLevel" >
|
||||
<strong>BASE:TraceLevel(Level)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Set trace level</p>
|
||||
|
||||
<h3>Parameter</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em>#number Level </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(BASE).onEvent" >
|
||||
<strong>BASE:onEvent(event)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
|
||||
<p> TODO: Complete DCSTypes#Event structure. <br/>
|
||||
- The main event handling function... This function captures all events generated for the class.
|
||||
@param #BASE self
|
||||
@param DCSTypes#Event event</p>
|
||||
|
||||
<h3>Parameter</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em> event </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<h2><a id="#(FORMATION)" >Type <code>FORMATION</code></a></h2>
|
||||
|
||||
<p>The Formation Class</p>
|
||||
|
||||
<h3>Field(s)</h3>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(FORMATION).Cone" >
|
||||
<strong>FORMATION.Cone</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>A cone formation.</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,220 +0,0 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" href="stylesheet.css" type="text/css"/>
|
||||
</head>
|
||||
<body>
|
||||
<div id="container">
|
||||
<div id="product">
|
||||
<div id="product_logo"></div>
|
||||
<div id="product_name"><big><b></b></big></div>
|
||||
<div id="product_description"></div>
|
||||
</div>
|
||||
<div id="main">
|
||||
<div id="navigation">
|
||||
<h2>Modules</h2>
|
||||
<ul><li>
|
||||
<a href="index.html">index</a>
|
||||
</li></ul>
|
||||
<ul>
|
||||
<li><a href="Base.html">Base</a></li>
|
||||
<li>CARGO</li>
|
||||
<li><a href="CleanUp.html">CleanUp</a></li>
|
||||
<li><a href="Client.html">Client</a></li>
|
||||
<li><a href="DCSAirbase.html">DCSAirbase</a></li>
|
||||
<li><a href="DCSCoalitionObject.html">DCSCoalitionObject</a></li>
|
||||
<li><a href="DCSCommand.html">DCSCommand</a></li>
|
||||
<li><a href="DCSController.html">DCSController</a></li>
|
||||
<li><a href="DCSGroup.html">DCSGroup</a></li>
|
||||
<li><a href="DCSObject.html">DCSObject</a></li>
|
||||
<li><a href="DCSTask.html">DCSTask</a></li>
|
||||
<li><a href="DCSTypes.html">DCSTypes</a></li>
|
||||
<li><a href="DCSUnit.html">DCSUnit</a></li>
|
||||
<li><a href="DCSWorld.html">DCSWorld</a></li>
|
||||
<li><a href="DCStimer.html">DCStimer</a></li>
|
||||
<li><a href="DEPLOYTASK.html">DEPLOYTASK</a></li>
|
||||
<li><a href="DESTROYBASETASK.html">DESTROYBASETASK</a></li>
|
||||
<li><a href="DESTROYGROUPSTASK.html">DESTROYGROUPSTASK</a></li>
|
||||
<li><a href="DESTROYRADARSTASK.html">DESTROYRADARSTASK</a></li>
|
||||
<li><a href="DESTROYUNITTYPESTASK.html">DESTROYUNITTYPESTASK</a></li>
|
||||
<li><a href="Database.html">Database</a></li>
|
||||
<li><a href="Escort.html">Escort</a></li>
|
||||
<li><a href="Event.html">Event</a></li>
|
||||
<li><a href="GOHOMETASK.html">GOHOMETASK</a></li>
|
||||
<li><a href="Group.html">Group</a></li>
|
||||
<li><a href="MISSION.html">MISSION</a></li>
|
||||
<li><a href="MOVEMENT.html">MOVEMENT</a></li>
|
||||
<li><a href="Menu.html">Menu</a></li>
|
||||
<li><a href="Message.html">Message</a></li>
|
||||
<li><a href="NOTASK.html">NOTASK</a></li>
|
||||
<li><a href="PICKUPTASK.html">PICKUPTASK</a></li>
|
||||
<li><a href="ROUTETASK.html">ROUTETASK</a></li>
|
||||
<li><a href="STAGE.html">STAGE</a></li>
|
||||
<li><a href="Scoring.html">Scoring</a></li>
|
||||
<li><a href="Sead.html">Sead</a></li>
|
||||
<li><a href="Spawn.html">Spawn</a></li>
|
||||
<li><a href="StaticObject.html">StaticObject</a></li>
|
||||
<li><a href="TASK.html">TASK</a></li>
|
||||
<li><a href="Unit.html">Unit</a></li>
|
||||
<li><a href="Zone.html">Zone</a></li>
|
||||
<li><a href="env.html">env</a></li>
|
||||
<li><a href="land.html">land</a></li>
|
||||
<li><a href="routines.html">routines</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="content">
|
||||
<h1>Module <code>CARGO</code></h1>
|
||||
|
||||
<p>CARGO Classes</p>
|
||||
|
||||
<h2>Global(s)</h2>
|
||||
<table class="function_list">
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="#CARGO">CARGO</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="#CARGOS">CARGOS</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="#CARGO_GROUP">CARGO_GROUP</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="#CARGO_PACKAGE">CARGO_PACKAGE</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="#CARGO_SLINGLOAD">CARGO_SLINGLOAD</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="#CARGO_ZONE">CARGO_ZONE</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="#CargoStatic">CargoStatic</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<h2>Global(s)</h2>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em></em>
|
||||
<a id="CARGO" >
|
||||
<strong>CARGO</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em></em>
|
||||
<a id="CARGOS" >
|
||||
<strong>CARGOS</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em></em>
|
||||
<a id="CARGO_GROUP" >
|
||||
<strong>CARGO_GROUP</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em></em>
|
||||
<a id="CARGO_PACKAGE" >
|
||||
<strong>CARGO_PACKAGE</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em></em>
|
||||
<a id="CARGO_SLINGLOAD" >
|
||||
<strong>CARGO_SLINGLOAD</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em></em>
|
||||
<a id="CARGO_ZONE" >
|
||||
<strong>CARGO_ZONE</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em></em>
|
||||
<a id="CargoStatic" >
|
||||
<strong>CargoStatic</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<h2><a id="#(CARGO)" >Type <code>CARGO</code></a></h2>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,384 +0,0 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" href="stylesheet.css" type="text/css"/>
|
||||
</head>
|
||||
<body>
|
||||
<div id="container">
|
||||
<div id="product">
|
||||
<div id="product_logo"></div>
|
||||
<div id="product_name"><big><b></b></big></div>
|
||||
<div id="product_description"></div>
|
||||
</div>
|
||||
<div id="main">
|
||||
<div id="navigation">
|
||||
<h2>Modules</h2>
|
||||
<ul><li>
|
||||
<a href="index.html">index</a>
|
||||
</li></ul>
|
||||
<ul>
|
||||
<li><a href="Base.html">Base</a></li>
|
||||
<li><a href="CARGO.html">CARGO</a></li>
|
||||
<li><a href="CleanUp.html">CleanUp</a></li>
|
||||
<li><a href="Client.html">Client</a></li>
|
||||
<li><a href="DCSAirbase.html">DCSAirbase</a></li>
|
||||
<li><a href="DCSCoalitionObject.html">DCSCoalitionObject</a></li>
|
||||
<li><a href="DCSCommand.html">DCSCommand</a></li>
|
||||
<li><a href="DCSController.html">DCSController</a></li>
|
||||
<li><a href="DCSGroup.html">DCSGroup</a></li>
|
||||
<li><a href="DCSObject.html">DCSObject</a></li>
|
||||
<li><a href="DCSTask.html">DCSTask</a></li>
|
||||
<li><a href="DCSTypes.html">DCSTypes</a></li>
|
||||
<li><a href="DCSUnit.html">DCSUnit</a></li>
|
||||
<li><a href="DCSWorld.html">DCSWorld</a></li>
|
||||
<li><a href="DCStimer.html">DCStimer</a></li>
|
||||
<li>DEPLOYTASK</li>
|
||||
<li><a href="DESTROYBASETASK.html">DESTROYBASETASK</a></li>
|
||||
<li><a href="DESTROYGROUPSTASK.html">DESTROYGROUPSTASK</a></li>
|
||||
<li><a href="DESTROYRADARSTASK.html">DESTROYRADARSTASK</a></li>
|
||||
<li><a href="DESTROYUNITTYPESTASK.html">DESTROYUNITTYPESTASK</a></li>
|
||||
<li><a href="Database.html">Database</a></li>
|
||||
<li><a href="Escort.html">Escort</a></li>
|
||||
<li><a href="Event.html">Event</a></li>
|
||||
<li><a href="GOHOMETASK.html">GOHOMETASK</a></li>
|
||||
<li><a href="Group.html">Group</a></li>
|
||||
<li><a href="MISSION.html">MISSION</a></li>
|
||||
<li><a href="MOVEMENT.html">MOVEMENT</a></li>
|
||||
<li><a href="Menu.html">Menu</a></li>
|
||||
<li><a href="Message.html">Message</a></li>
|
||||
<li><a href="NOTASK.html">NOTASK</a></li>
|
||||
<li><a href="PICKUPTASK.html">PICKUPTASK</a></li>
|
||||
<li><a href="ROUTETASK.html">ROUTETASK</a></li>
|
||||
<li><a href="STAGE.html">STAGE</a></li>
|
||||
<li><a href="Scoring.html">Scoring</a></li>
|
||||
<li><a href="Sead.html">Sead</a></li>
|
||||
<li><a href="Spawn.html">Spawn</a></li>
|
||||
<li><a href="StaticObject.html">StaticObject</a></li>
|
||||
<li><a href="TASK.html">TASK</a></li>
|
||||
<li><a href="Unit.html">Unit</a></li>
|
||||
<li><a href="Zone.html">Zone</a></li>
|
||||
<li><a href="env.html">env</a></li>
|
||||
<li><a href="land.html">land</a></li>
|
||||
<li><a href="routines.html">routines</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="content">
|
||||
<h1>Module <code>DEPLOYTASK</code></h1>
|
||||
|
||||
<p>A DEPLOYTASK orchestrates the deployment of CARGO within a specific landing zone.</p>
|
||||
|
||||
<h2>Global(s)</h2>
|
||||
<table class="function_list">
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="#DEPLOYTASK">DEPLOYTASK</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<h2><a id="#(DEPLOYTASK)" >Type <code>DEPLOYTASK</code></a></h2>
|
||||
<table class="function_list">
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(DEPLOYTASK).AddCargoMenus">DEPLOYTASK:AddCargoMenus(Client, Cargos, TransportRadius)</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(DEPLOYTASK).ClassName">DEPLOYTASK.ClassName</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(DEPLOYTASK).GoalVerb">DEPLOYTASK.GoalVerb</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(DEPLOYTASK).InitCargo">DEPLOYTASK:InitCargo(InitCargos)</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(DEPLOYTASK).LoadCargo">DEPLOYTASK:LoadCargo(LoadCargos)</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(DEPLOYTASK).New">DEPLOYTASK.New(CargoType)</a></td>
|
||||
<td class="summary">
|
||||
<p>Creates a new DEPLOYTASK object, which models the sequence of STAGEs to unload a cargo.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(DEPLOYTASK).RemoveCargoMenus">DEPLOYTASK:RemoveCargoMenus(Client)</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(DEPLOYTASK).SetCargoTargetZoneName">DEPLOYTASK.SetCargoTargetZoneName(string, self, TargetZoneName)</a></td>
|
||||
<td class="summary">
|
||||
<p>When the cargo is unloaded, it will move to the target zone name.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(DEPLOYTASK).TEXT">DEPLOYTASK.TEXT</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(DEPLOYTASK).ToZone">DEPLOYTASK:ToZone(LandingZone)</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2>Global(s)</h2>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em><a href="##(DEPLOYTASK)">#DEPLOYTASK</a></em>
|
||||
<a id="DEPLOYTASK" >
|
||||
<strong>DEPLOYTASK</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<h2><a id="#(DEPLOYTASK)" >Type <code>DEPLOYTASK</code></a></h2>
|
||||
|
||||
<p>A DeployTask</p>
|
||||
|
||||
<h3>Field(s)</h3>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(DEPLOYTASK).AddCargoMenus" >
|
||||
<strong>DEPLOYTASK:AddCargoMenus(Client, Cargos, TransportRadius)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
<h3>Parameters</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em> Client </em></code>: </p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> Cargos </em></code>: </p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> TransportRadius </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em>#string</em>
|
||||
<a id="#(DEPLOYTASK).ClassName" >
|
||||
<strong>DEPLOYTASK.ClassName</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em>#string</em>
|
||||
<a id="#(DEPLOYTASK).GoalVerb" >
|
||||
<strong>DEPLOYTASK.GoalVerb</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(DEPLOYTASK).InitCargo" >
|
||||
<strong>DEPLOYTASK:InitCargo(InitCargos)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
<h3>Parameter</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em> InitCargos </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(DEPLOYTASK).LoadCargo" >
|
||||
<strong>DEPLOYTASK:LoadCargo(LoadCargos)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
<h3>Parameter</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em> LoadCargos </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(DEPLOYTASK).New" >
|
||||
<strong>DEPLOYTASK.New(CargoType)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Creates a new DEPLOYTASK object, which models the sequence of STAGEs to unload a cargo.</p>
|
||||
|
||||
<h3>Parameter</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em>#string CargoType </em></code>:
|
||||
Type of the Cargo.</p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
<h3>Return value</h3>
|
||||
|
||||
<p><em><a href="##(DEPLOYTASK)">#DEPLOYTASK</a>:</em>
|
||||
The created DeployTask</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(DEPLOYTASK).RemoveCargoMenus" >
|
||||
<strong>DEPLOYTASK:RemoveCargoMenus(Client)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
<h3>Parameter</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em> Client </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(DEPLOYTASK).SetCargoTargetZoneName" >
|
||||
<strong>DEPLOYTASK.SetCargoTargetZoneName(string, self, TargetZoneName)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>When the cargo is unloaded, it will move to the target zone name.</p>
|
||||
|
||||
<h3>Parameters</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em> string </em></code>:
|
||||
TargetZoneName Name of the Zone to where the Cargo should move after unloading.</p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> self </em></code>: </p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> TargetZoneName </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em></em>
|
||||
<a id="#(DEPLOYTASK).TEXT" >
|
||||
<strong>DEPLOYTASK.TEXT</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(DEPLOYTASK).ToZone" >
|
||||
<strong>DEPLOYTASK:ToZone(LandingZone)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
<h3>Parameter</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em> LandingZone </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,318 +0,0 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" href="stylesheet.css" type="text/css"/>
|
||||
</head>
|
||||
<body>
|
||||
<div id="container">
|
||||
<div id="product">
|
||||
<div id="product_logo"></div>
|
||||
<div id="product_name"><big><b></b></big></div>
|
||||
<div id="product_description"></div>
|
||||
</div>
|
||||
<div id="main">
|
||||
<div id="navigation">
|
||||
<h2>Modules</h2>
|
||||
<ul><li>
|
||||
<a href="index.html">index</a>
|
||||
</li></ul>
|
||||
<ul>
|
||||
<li><a href="Base.html">Base</a></li>
|
||||
<li><a href="CARGO.html">CARGO</a></li>
|
||||
<li><a href="CleanUp.html">CleanUp</a></li>
|
||||
<li><a href="Client.html">Client</a></li>
|
||||
<li><a href="DCSAirbase.html">DCSAirbase</a></li>
|
||||
<li><a href="DCSCoalitionObject.html">DCSCoalitionObject</a></li>
|
||||
<li><a href="DCSCommand.html">DCSCommand</a></li>
|
||||
<li><a href="DCSController.html">DCSController</a></li>
|
||||
<li><a href="DCSGroup.html">DCSGroup</a></li>
|
||||
<li><a href="DCSObject.html">DCSObject</a></li>
|
||||
<li><a href="DCSTask.html">DCSTask</a></li>
|
||||
<li><a href="DCSTypes.html">DCSTypes</a></li>
|
||||
<li><a href="DCSUnit.html">DCSUnit</a></li>
|
||||
<li><a href="DCSWorld.html">DCSWorld</a></li>
|
||||
<li><a href="DCStimer.html">DCStimer</a></li>
|
||||
<li><a href="DEPLOYTASK.html">DEPLOYTASK</a></li>
|
||||
<li>DESTROYBASETASK</li>
|
||||
<li><a href="DESTROYGROUPSTASK.html">DESTROYGROUPSTASK</a></li>
|
||||
<li><a href="DESTROYRADARSTASK.html">DESTROYRADARSTASK</a></li>
|
||||
<li><a href="DESTROYUNITTYPESTASK.html">DESTROYUNITTYPESTASK</a></li>
|
||||
<li><a href="Database.html">Database</a></li>
|
||||
<li><a href="Escort.html">Escort</a></li>
|
||||
<li><a href="Event.html">Event</a></li>
|
||||
<li><a href="GOHOMETASK.html">GOHOMETASK</a></li>
|
||||
<li><a href="Group.html">Group</a></li>
|
||||
<li><a href="MISSION.html">MISSION</a></li>
|
||||
<li><a href="MOVEMENT.html">MOVEMENT</a></li>
|
||||
<li><a href="Menu.html">Menu</a></li>
|
||||
<li><a href="Message.html">Message</a></li>
|
||||
<li><a href="NOTASK.html">NOTASK</a></li>
|
||||
<li><a href="PICKUPTASK.html">PICKUPTASK</a></li>
|
||||
<li><a href="ROUTETASK.html">ROUTETASK</a></li>
|
||||
<li><a href="STAGE.html">STAGE</a></li>
|
||||
<li><a href="Scoring.html">Scoring</a></li>
|
||||
<li><a href="Sead.html">Sead</a></li>
|
||||
<li><a href="Spawn.html">Spawn</a></li>
|
||||
<li><a href="StaticObject.html">StaticObject</a></li>
|
||||
<li><a href="TASK.html">TASK</a></li>
|
||||
<li><a href="Unit.html">Unit</a></li>
|
||||
<li><a href="Zone.html">Zone</a></li>
|
||||
<li><a href="env.html">env</a></li>
|
||||
<li><a href="land.html">land</a></li>
|
||||
<li><a href="routines.html">routines</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="content">
|
||||
<h1>Module <code>DESTROYBASETASK</code></h1>
|
||||
|
||||
<p>A DESTROYBASETASK will monitor the destruction of Groups and Units.</p>
|
||||
|
||||
|
||||
<p>This is a BASE class, other classes are derived from this class.</p>
|
||||
|
||||
<h2>Global(s)</h2>
|
||||
<table class="function_list">
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="#DESTROYBASETASK">DESTROYBASETASK</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<h2><a id="#(DESTROYBASETASK)" >Type <code>DESTROYBASETASK</code></a></h2>
|
||||
<table class="function_list">
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(DESTROYBASETASK).ClassName">DESTROYBASETASK.ClassName</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(DESTROYBASETASK).DestroyPercentage">DESTROYBASETASK.DestroyPercentage</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(DESTROYBASETASK).Destroyed">DESTROYBASETASK.Destroyed</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(DESTROYBASETASK).EventDead">DESTROYBASETASK:EventDead(Event)</a></td>
|
||||
<td class="summary">
|
||||
<p>Handle the S<em>EVENT</em>DEAD events to validate the destruction of units for the task monitoring.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(DESTROYBASETASK).GoalVerb">DESTROYBASETASK.GoalVerb</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(DESTROYBASETASK).New">DESTROYBASETASK:New(DestroyGroupType, DestroyUnitType, <, DestroyPercentage, DestroyGroupPrefixes)</a></td>
|
||||
<td class="summary">
|
||||
<p>Creates a new DESTROYBASETASK.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(DESTROYBASETASK).ReportGoalProgress">DESTROYBASETASK.ReportGoalProgress(DestroyGroup, DestroyUnit, self)</a></td>
|
||||
<td class="summary">
|
||||
<p>Validate task completeness of DESTROYBASETASK.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2>Global(s)</h2>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em><a href="##(DESTROYBASETASK)">#DESTROYBASETASK</a></em>
|
||||
<a id="DESTROYBASETASK" >
|
||||
<strong>DESTROYBASETASK</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<h2><a id="#(DESTROYBASETASK)" >Type <code>DESTROYBASETASK</code></a></h2>
|
||||
|
||||
<p>The DESTROYBASETASK class</p>
|
||||
|
||||
<h3>Field(s)</h3>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em>#string</em>
|
||||
<a id="#(DESTROYBASETASK).ClassName" >
|
||||
<strong>DESTROYBASETASK.ClassName</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em>#number</em>
|
||||
<a id="#(DESTROYBASETASK).DestroyPercentage" >
|
||||
<strong>DESTROYBASETASK.DestroyPercentage</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em>#number</em>
|
||||
<a id="#(DESTROYBASETASK).Destroyed" >
|
||||
<strong>DESTROYBASETASK.Destroyed</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(DESTROYBASETASK).EventDead" >
|
||||
<strong>DESTROYBASETASK:EventDead(Event)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Handle the S<em>EVENT</em>DEAD events to validate the destruction of units for the task monitoring.</p>
|
||||
|
||||
<h3>Parameter</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em><a href="Event.html##(EVENTDATA)">Event#EVENTDATA</a> Event </em></code>:
|
||||
structure of MOOSE.</p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em>#string</em>
|
||||
<a id="#(DESTROYBASETASK).GoalVerb" >
|
||||
<strong>DESTROYBASETASK.GoalVerb</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(DESTROYBASETASK).New" >
|
||||
<strong>DESTROYBASETASK:New(DestroyGroupType, DestroyUnitType, <, DestroyPercentage, DestroyGroupPrefixes)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Creates a new DESTROYBASETASK.</p>
|
||||
|
||||
<h3>Parameters</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em>#string DestroyGroupType </em></code>:
|
||||
Text describing the group to be destroyed. f.e. "Radar Installations", "Ships", "Vehicles", "Command Centers".</p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em>#string DestroyUnitType </em></code>:
|
||||
Text describing the unit types to be destroyed. f.e. "SA-6", "Row Boats", "Tanks", "Tents".</p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em><a href="##(list)">#list</a> < </em></code>:
|
||||
string> DestroyGroupPrefixes Table of Prefixes of the Groups to be destroyed before task is completed.</p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em>#number DestroyPercentage </em></code>:
|
||||
defines the %-tage that needs to be destroyed to achieve mission success. eg. If in the Group there are 10 units, then a value of 75 would require 8 units to be destroyed from the Group to complete the <a href="TASK.html">TASK</a>.</p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> DestroyGroupPrefixes </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
<h3>Return value</h3>
|
||||
|
||||
|
||||
<p>DESTROYBASETASK</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(DESTROYBASETASK).ReportGoalProgress" >
|
||||
<strong>DESTROYBASETASK.ReportGoalProgress(DestroyGroup, DestroyUnit, self)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Validate task completeness of DESTROYBASETASK.</p>
|
||||
|
||||
<h3>Parameters</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em> DestroyGroup </em></code>: </p>
|
||||
<pre><code> Group structure describing the group to be evaluated.
|
||||
</code></pre>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> DestroyUnit </em></code>: </p>
|
||||
<pre><code> Unit structure describing the Unit to be evaluated.
|
||||
</code></pre>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> self </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<h2><a id="#(list)" >Type <code>list</code></a></h2>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,240 +0,0 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" href="stylesheet.css" type="text/css"/>
|
||||
</head>
|
||||
<body>
|
||||
<div id="container">
|
||||
<div id="product">
|
||||
<div id="product_logo"></div>
|
||||
<div id="product_name"><big><b></b></big></div>
|
||||
<div id="product_description"></div>
|
||||
</div>
|
||||
<div id="main">
|
||||
<div id="navigation">
|
||||
<h2>Modules</h2>
|
||||
<ul><li>
|
||||
<a href="index.html">index</a>
|
||||
</li></ul>
|
||||
<ul>
|
||||
<li><a href="Base.html">Base</a></li>
|
||||
<li><a href="CARGO.html">CARGO</a></li>
|
||||
<li><a href="CleanUp.html">CleanUp</a></li>
|
||||
<li><a href="Client.html">Client</a></li>
|
||||
<li><a href="DCSAirbase.html">DCSAirbase</a></li>
|
||||
<li><a href="DCSCoalitionObject.html">DCSCoalitionObject</a></li>
|
||||
<li><a href="DCSCommand.html">DCSCommand</a></li>
|
||||
<li><a href="DCSController.html">DCSController</a></li>
|
||||
<li><a href="DCSGroup.html">DCSGroup</a></li>
|
||||
<li><a href="DCSObject.html">DCSObject</a></li>
|
||||
<li><a href="DCSTask.html">DCSTask</a></li>
|
||||
<li><a href="DCSTypes.html">DCSTypes</a></li>
|
||||
<li><a href="DCSUnit.html">DCSUnit</a></li>
|
||||
<li><a href="DCSWorld.html">DCSWorld</a></li>
|
||||
<li><a href="DCStimer.html">DCStimer</a></li>
|
||||
<li><a href="DEPLOYTASK.html">DEPLOYTASK</a></li>
|
||||
<li><a href="DESTROYBASETASK.html">DESTROYBASETASK</a></li>
|
||||
<li>DESTROYGROUPSTASK</li>
|
||||
<li><a href="DESTROYRADARSTASK.html">DESTROYRADARSTASK</a></li>
|
||||
<li><a href="DESTROYUNITTYPESTASK.html">DESTROYUNITTYPESTASK</a></li>
|
||||
<li><a href="Database.html">Database</a></li>
|
||||
<li><a href="Escort.html">Escort</a></li>
|
||||
<li><a href="Event.html">Event</a></li>
|
||||
<li><a href="GOHOMETASK.html">GOHOMETASK</a></li>
|
||||
<li><a href="Group.html">Group</a></li>
|
||||
<li><a href="MISSION.html">MISSION</a></li>
|
||||
<li><a href="MOVEMENT.html">MOVEMENT</a></li>
|
||||
<li><a href="Menu.html">Menu</a></li>
|
||||
<li><a href="Message.html">Message</a></li>
|
||||
<li><a href="NOTASK.html">NOTASK</a></li>
|
||||
<li><a href="PICKUPTASK.html">PICKUPTASK</a></li>
|
||||
<li><a href="ROUTETASK.html">ROUTETASK</a></li>
|
||||
<li><a href="STAGE.html">STAGE</a></li>
|
||||
<li><a href="Scoring.html">Scoring</a></li>
|
||||
<li><a href="Sead.html">Sead</a></li>
|
||||
<li><a href="Spawn.html">Spawn</a></li>
|
||||
<li><a href="StaticObject.html">StaticObject</a></li>
|
||||
<li><a href="TASK.html">TASK</a></li>
|
||||
<li><a href="Unit.html">Unit</a></li>
|
||||
<li><a href="Zone.html">Zone</a></li>
|
||||
<li><a href="env.html">env</a></li>
|
||||
<li><a href="land.html">land</a></li>
|
||||
<li><a href="routines.html">routines</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="content">
|
||||
<h1>Module <code>DESTROYGROUPSTASK</code></h1>
|
||||
|
||||
<p>DESTROYGROUPSTASK</p>
|
||||
|
||||
<h2>Global(s)</h2>
|
||||
<table class="function_list">
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="#DESTROYGROUPSTASK">DESTROYGROUPSTASK</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<h2><a id="#(DESTROYGROUPSTASK)" >Type <code>DESTROYGROUPSTASK</code></a></h2>
|
||||
<table class="function_list">
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(DESTROYGROUPSTASK).ClassName">DESTROYGROUPSTASK.ClassName</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(DESTROYGROUPSTASK).GoalVerb">DESTROYGROUPSTASK.GoalVerb</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(DESTROYGROUPSTASK).New">DESTROYGROUPSTASK:New(DestroyGroupType, DestroyUnitType, <, DestroyPercentage, DestroyGroupNames)</a></td>
|
||||
<td class="summary">
|
||||
<p>Creates a new DESTROYGROUPSTASK.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(DESTROYGROUPSTASK).ReportGoalProgress">DESTROYGROUPSTASK:ReportGoalProgress(DestroyGroup, DestroyUnit)</a></td>
|
||||
<td class="summary">
|
||||
<p>Report Goal Progress.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2>Global(s)</h2>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em><a href="##(DESTROYGROUPSTASK)">#DESTROYGROUPSTASK</a></em>
|
||||
<a id="DESTROYGROUPSTASK" >
|
||||
<strong>DESTROYGROUPSTASK</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<h2><a id="#(DESTROYGROUPSTASK)" >Type <code>DESTROYGROUPSTASK</code></a></h2>
|
||||
<h3>Field(s)</h3>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em>#string</em>
|
||||
<a id="#(DESTROYGROUPSTASK).ClassName" >
|
||||
<strong>DESTROYGROUPSTASK.ClassName</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em>#string</em>
|
||||
<a id="#(DESTROYGROUPSTASK).GoalVerb" >
|
||||
<strong>DESTROYGROUPSTASK.GoalVerb</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(DESTROYGROUPSTASK).New" >
|
||||
<strong>DESTROYGROUPSTASK:New(DestroyGroupType, DestroyUnitType, <, DestroyPercentage, DestroyGroupNames)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Creates a new DESTROYGROUPSTASK.</p>
|
||||
|
||||
<h3>Parameters</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em>#string DestroyGroupType </em></code>: </p>
|
||||
<pre><code>String describing the group to be destroyed.
|
||||
</code></pre>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em>#string DestroyUnitType </em></code>: </p>
|
||||
<pre><code>String describing the unit to be destroyed.
|
||||
</code></pre>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em><a href="##(list)">#list</a> < </em></code>:
|
||||
string> DestroyGroupNames Table of string containing the name of the groups to be destroyed before task is completed.</p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em>#number DestroyPercentage </em></code>:
|
||||
defines the %-tage that needs to be destroyed to achieve mission success. eg. If in the Group there are 10 units, then a value of 75 would require 8 units to be destroyed from the Group to complete the <a href="TASK.html">TASK</a>.
|
||||
-@return DESTROYGROUPSTASK</p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> DestroyGroupNames </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(DESTROYGROUPSTASK).ReportGoalProgress" >
|
||||
<strong>DESTROYGROUPSTASK:ReportGoalProgress(DestroyGroup, DestroyUnit)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Report Goal Progress.</p>
|
||||
|
||||
<h3>Parameters</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em><a href="DCSGroup.html##(Group)">DCSGroup#Group</a> DestroyGroup </em></code>:
|
||||
Group structure describing the group to be evaluated.</p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em><a href="DCSUnit.html##(Unit)">DCSUnit#Unit</a> DestroyUnit </em></code>:
|
||||
Unit structure describing the Unit to be evaluated.</p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
<h3>Return value</h3>
|
||||
|
||||
<p><em>#number:</em>
|
||||
The DestroyCount reflecting the amount of units destroyed within the group.</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<h2><a id="#(list)" >Type <code>list</code></a></h2>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,237 +0,0 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" href="stylesheet.css" type="text/css"/>
|
||||
</head>
|
||||
<body>
|
||||
<div id="container">
|
||||
<div id="product">
|
||||
<div id="product_logo"></div>
|
||||
<div id="product_name"><big><b></b></big></div>
|
||||
<div id="product_description"></div>
|
||||
</div>
|
||||
<div id="main">
|
||||
<div id="navigation">
|
||||
<h2>Modules</h2>
|
||||
<ul><li>
|
||||
<a href="index.html">index</a>
|
||||
</li></ul>
|
||||
<ul>
|
||||
<li><a href="Base.html">Base</a></li>
|
||||
<li><a href="CARGO.html">CARGO</a></li>
|
||||
<li><a href="CleanUp.html">CleanUp</a></li>
|
||||
<li><a href="Client.html">Client</a></li>
|
||||
<li><a href="DCSAirbase.html">DCSAirbase</a></li>
|
||||
<li><a href="DCSCoalitionObject.html">DCSCoalitionObject</a></li>
|
||||
<li><a href="DCSCommand.html">DCSCommand</a></li>
|
||||
<li><a href="DCSController.html">DCSController</a></li>
|
||||
<li><a href="DCSGroup.html">DCSGroup</a></li>
|
||||
<li><a href="DCSObject.html">DCSObject</a></li>
|
||||
<li><a href="DCSTask.html">DCSTask</a></li>
|
||||
<li><a href="DCSTypes.html">DCSTypes</a></li>
|
||||
<li><a href="DCSUnit.html">DCSUnit</a></li>
|
||||
<li><a href="DCSWorld.html">DCSWorld</a></li>
|
||||
<li><a href="DCStimer.html">DCStimer</a></li>
|
||||
<li><a href="DEPLOYTASK.html">DEPLOYTASK</a></li>
|
||||
<li><a href="DESTROYBASETASK.html">DESTROYBASETASK</a></li>
|
||||
<li><a href="DESTROYGROUPSTASK.html">DESTROYGROUPSTASK</a></li>
|
||||
<li>DESTROYRADARSTASK</li>
|
||||
<li><a href="DESTROYUNITTYPESTASK.html">DESTROYUNITTYPESTASK</a></li>
|
||||
<li><a href="Database.html">Database</a></li>
|
||||
<li><a href="Escort.html">Escort</a></li>
|
||||
<li><a href="Event.html">Event</a></li>
|
||||
<li><a href="GOHOMETASK.html">GOHOMETASK</a></li>
|
||||
<li><a href="Group.html">Group</a></li>
|
||||
<li><a href="MISSION.html">MISSION</a></li>
|
||||
<li><a href="MOVEMENT.html">MOVEMENT</a></li>
|
||||
<li><a href="Menu.html">Menu</a></li>
|
||||
<li><a href="Message.html">Message</a></li>
|
||||
<li><a href="NOTASK.html">NOTASK</a></li>
|
||||
<li><a href="PICKUPTASK.html">PICKUPTASK</a></li>
|
||||
<li><a href="ROUTETASK.html">ROUTETASK</a></li>
|
||||
<li><a href="STAGE.html">STAGE</a></li>
|
||||
<li><a href="Scoring.html">Scoring</a></li>
|
||||
<li><a href="Sead.html">Sead</a></li>
|
||||
<li><a href="Spawn.html">Spawn</a></li>
|
||||
<li><a href="StaticObject.html">StaticObject</a></li>
|
||||
<li><a href="TASK.html">TASK</a></li>
|
||||
<li><a href="Unit.html">Unit</a></li>
|
||||
<li><a href="Zone.html">Zone</a></li>
|
||||
<li><a href="env.html">env</a></li>
|
||||
<li><a href="land.html">land</a></li>
|
||||
<li><a href="routines.html">routines</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="content">
|
||||
<h1>Module <code>DESTROYRADARSTASK</code></h1>
|
||||
|
||||
<p>Task class to destroy radar installations.</p>
|
||||
|
||||
<h2>Global(s)</h2>
|
||||
<table class="function_list">
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="#DESTROYRADARSTASK">DESTROYRADARSTASK</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<h2><a id="#(DESTROYRADARSTASK)" >Type <code>DESTROYRADARSTASK</code></a></h2>
|
||||
<table class="function_list">
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(DESTROYRADARSTASK).ClassName">DESTROYRADARSTASK.ClassName</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(DESTROYRADARSTASK).GoalVerb">DESTROYRADARSTASK.GoalVerb</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(DESTROYRADARSTASK).New">DESTROYRADARSTASK.New(table, self, DestroyGroupNames)</a></td>
|
||||
<td class="summary">
|
||||
<p>Creates a new DESTROYRADARSTASK.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(DESTROYRADARSTASK).ReportGoalProgress">DESTROYRADARSTASK.ReportGoalProgress(Group, Unit, self, DestroyGroup, DestroyUnit)</a></td>
|
||||
<td class="summary">
|
||||
<p>Report Goal Progress.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2>Global(s)</h2>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em><a href="##(DESTROYRADARSTASK)">#DESTROYRADARSTASK</a></em>
|
||||
<a id="DESTROYRADARSTASK" >
|
||||
<strong>DESTROYRADARSTASK</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<h2><a id="#(DESTROYRADARSTASK)" >Type <code>DESTROYRADARSTASK</code></a></h2>
|
||||
<h3>Field(s)</h3>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em>#string</em>
|
||||
<a id="#(DESTROYRADARSTASK).ClassName" >
|
||||
<strong>DESTROYRADARSTASK.ClassName</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em>#string</em>
|
||||
<a id="#(DESTROYRADARSTASK).GoalVerb" >
|
||||
<strong>DESTROYRADARSTASK.GoalVerb</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(DESTROYRADARSTASK).New" >
|
||||
<strong>DESTROYRADARSTASK.New(table, self, DestroyGroupNames)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Creates a new DESTROYRADARSTASK.</p>
|
||||
|
||||
<h3>Parameters</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em> table </em></code>:
|
||||
string,...} DestroyGroupNames Table of string containing the group names of which the radars are be destroyed.</p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> self </em></code>: </p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> DestroyGroupNames </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
<h3>Return value</h3>
|
||||
|
||||
|
||||
<p>DESTROYRADARSTASK</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(DESTROYRADARSTASK).ReportGoalProgress" >
|
||||
<strong>DESTROYRADARSTASK.ReportGoalProgress(Group, Unit, self, DestroyGroup, DestroyUnit)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Report Goal Progress.</p>
|
||||
|
||||
<h3>Parameters</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em> Group </em></code>:
|
||||
DestroyGroup Group structure describing the group to be evaluated.</p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> Unit </em></code>:
|
||||
DestroyUnit Unit structure describing the Unit to be evaluated.</p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> self </em></code>: </p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> DestroyGroup </em></code>: </p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> DestroyUnit </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,270 +0,0 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" href="stylesheet.css" type="text/css"/>
|
||||
</head>
|
||||
<body>
|
||||
<div id="container">
|
||||
<div id="product">
|
||||
<div id="product_logo"></div>
|
||||
<div id="product_name"><big><b></b></big></div>
|
||||
<div id="product_description"></div>
|
||||
</div>
|
||||
<div id="main">
|
||||
<div id="navigation">
|
||||
<h2>Modules</h2>
|
||||
<ul><li>
|
||||
<a href="index.html">index</a>
|
||||
</li></ul>
|
||||
<ul>
|
||||
<li><a href="Base.html">Base</a></li>
|
||||
<li><a href="CARGO.html">CARGO</a></li>
|
||||
<li><a href="CleanUp.html">CleanUp</a></li>
|
||||
<li><a href="Client.html">Client</a></li>
|
||||
<li><a href="DCSAirbase.html">DCSAirbase</a></li>
|
||||
<li><a href="DCSCoalitionObject.html">DCSCoalitionObject</a></li>
|
||||
<li><a href="DCSCommand.html">DCSCommand</a></li>
|
||||
<li><a href="DCSController.html">DCSController</a></li>
|
||||
<li><a href="DCSGroup.html">DCSGroup</a></li>
|
||||
<li><a href="DCSObject.html">DCSObject</a></li>
|
||||
<li><a href="DCSTask.html">DCSTask</a></li>
|
||||
<li><a href="DCSTypes.html">DCSTypes</a></li>
|
||||
<li><a href="DCSUnit.html">DCSUnit</a></li>
|
||||
<li><a href="DCSWorld.html">DCSWorld</a></li>
|
||||
<li><a href="DCStimer.html">DCStimer</a></li>
|
||||
<li><a href="DEPLOYTASK.html">DEPLOYTASK</a></li>
|
||||
<li><a href="DESTROYBASETASK.html">DESTROYBASETASK</a></li>
|
||||
<li><a href="DESTROYGROUPSTASK.html">DESTROYGROUPSTASK</a></li>
|
||||
<li><a href="DESTROYRADARSTASK.html">DESTROYRADARSTASK</a></li>
|
||||
<li>DESTROYUNITTYPESTASK</li>
|
||||
<li><a href="Database.html">Database</a></li>
|
||||
<li><a href="Escort.html">Escort</a></li>
|
||||
<li><a href="Event.html">Event</a></li>
|
||||
<li><a href="GOHOMETASK.html">GOHOMETASK</a></li>
|
||||
<li><a href="Group.html">Group</a></li>
|
||||
<li><a href="MISSION.html">MISSION</a></li>
|
||||
<li><a href="MOVEMENT.html">MOVEMENT</a></li>
|
||||
<li><a href="Menu.html">Menu</a></li>
|
||||
<li><a href="Message.html">Message</a></li>
|
||||
<li><a href="NOTASK.html">NOTASK</a></li>
|
||||
<li><a href="PICKUPTASK.html">PICKUPTASK</a></li>
|
||||
<li><a href="ROUTETASK.html">ROUTETASK</a></li>
|
||||
<li><a href="STAGE.html">STAGE</a></li>
|
||||
<li><a href="Scoring.html">Scoring</a></li>
|
||||
<li><a href="Sead.html">Sead</a></li>
|
||||
<li><a href="Spawn.html">Spawn</a></li>
|
||||
<li><a href="StaticObject.html">StaticObject</a></li>
|
||||
<li><a href="TASK.html">TASK</a></li>
|
||||
<li><a href="Unit.html">Unit</a></li>
|
||||
<li><a href="Zone.html">Zone</a></li>
|
||||
<li><a href="env.html">env</a></li>
|
||||
<li><a href="land.html">land</a></li>
|
||||
<li><a href="routines.html">routines</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="content">
|
||||
<h1>Module <code>DESTROYUNITTYPESTASK</code></h1>
|
||||
|
||||
<p>Set TASK to destroy certain unit types.</p>
|
||||
|
||||
<h2>Global(s)</h2>
|
||||
<table class="function_list">
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="#DESTROYUNITTYPESTASK">DESTROYUNITTYPESTASK</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<h2><a id="#(DESTROYUNITTYPESTASK)" >Type <code>DESTROYUNITTYPESTASK</code></a></h2>
|
||||
<table class="function_list">
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(DESTROYUNITTYPESTASK).ClassName">DESTROYUNITTYPESTASK.ClassName</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(DESTROYUNITTYPESTASK).GoalVerb">DESTROYUNITTYPESTASK.GoalVerb</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(DESTROYUNITTYPESTASK).New">DESTROYUNITTYPESTASK.New(string, string, table, string, self, DestroyGroupType, DestroyUnitType, DestroyGroupNames, DestroyUnitTypes)</a></td>
|
||||
<td class="summary">
|
||||
<p>Creates a new DESTROYUNITTYPESTASK.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(DESTROYUNITTYPESTASK).ReportGoalProgress">DESTROYUNITTYPESTASK.ReportGoalProgress(Group, Unit, self, DestroyGroup, DestroyUnit)</a></td>
|
||||
<td class="summary">
|
||||
<p>Report Goal Progress.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2>Global(s)</h2>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em><a href="##(DESTROYUNITTYPESTASK)">#DESTROYUNITTYPESTASK</a></em>
|
||||
<a id="DESTROYUNITTYPESTASK" >
|
||||
<strong>DESTROYUNITTYPESTASK</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<h2><a id="#(DESTROYUNITTYPESTASK)" >Type <code>DESTROYUNITTYPESTASK</code></a></h2>
|
||||
<h3>Field(s)</h3>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em>#string</em>
|
||||
<a id="#(DESTROYUNITTYPESTASK).ClassName" >
|
||||
<strong>DESTROYUNITTYPESTASK.ClassName</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em>#string</em>
|
||||
<a id="#(DESTROYUNITTYPESTASK).GoalVerb" >
|
||||
<strong>DESTROYUNITTYPESTASK.GoalVerb</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(DESTROYUNITTYPESTASK).New" >
|
||||
<strong>DESTROYUNITTYPESTASK.New(string, string, table, string, self, DestroyGroupType, DestroyUnitType, DestroyGroupNames, DestroyUnitTypes)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Creates a new DESTROYUNITTYPESTASK.</p>
|
||||
|
||||
<h3>Parameters</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em> string </em></code>:
|
||||
DestroyGroupType String describing the group to be destroyed. f.e. "Radar Installations", "Fleet", "Batallion", "Command Centers".</p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> string </em></code>:
|
||||
DestroyUnitType String describing the unit to be destroyed. f.e. "radars", "ships", "tanks", "centers".</p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> table </em></code>:
|
||||
string,...} DestroyGroupNames Table of string containing the group names of which the radars are be destroyed.</p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> string </em></code>:
|
||||
DestroyUnitTypes Table of string containing the type names of the units to achieve mission success.</p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> self </em></code>: </p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> DestroyGroupType </em></code>: </p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> DestroyUnitType </em></code>: </p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> DestroyGroupNames </em></code>: </p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> DestroyUnitTypes </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
<h3>Return value</h3>
|
||||
|
||||
|
||||
<p>DESTROYUNITTYPESTASK</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(DESTROYUNITTYPESTASK).ReportGoalProgress" >
|
||||
<strong>DESTROYUNITTYPESTASK.ReportGoalProgress(Group, Unit, self, DestroyGroup, DestroyUnit)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Report Goal Progress.</p>
|
||||
|
||||
<h3>Parameters</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em> Group </em></code>:
|
||||
DestroyGroup Group structure describing the group to be evaluated.</p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> Unit </em></code>:
|
||||
DestroyUnit Unit structure describing the Unit to be evaluated.</p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> self </em></code>: </p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> DestroyGroup </em></code>: </p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> DestroyUnit </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,168 +0,0 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" href="stylesheet.css" type="text/css"/>
|
||||
</head>
|
||||
<body>
|
||||
<div id="container">
|
||||
<div id="product">
|
||||
<div id="product_logo"></div>
|
||||
<div id="product_name"><big><b></b></big></div>
|
||||
<div id="product_description"></div>
|
||||
</div>
|
||||
<div id="main">
|
||||
<div id="navigation">
|
||||
<h2>Modules</h2>
|
||||
<ul><li>
|
||||
<a href="index.html">index</a>
|
||||
</li></ul>
|
||||
<ul>
|
||||
<li><a href="Base.html">Base</a></li>
|
||||
<li><a href="CARGO.html">CARGO</a></li>
|
||||
<li><a href="CleanUp.html">CleanUp</a></li>
|
||||
<li><a href="Client.html">Client</a></li>
|
||||
<li><a href="DCSAirbase.html">DCSAirbase</a></li>
|
||||
<li><a href="DCSCoalitionObject.html">DCSCoalitionObject</a></li>
|
||||
<li><a href="DCSCommand.html">DCSCommand</a></li>
|
||||
<li><a href="DCSController.html">DCSController</a></li>
|
||||
<li><a href="DCSGroup.html">DCSGroup</a></li>
|
||||
<li><a href="DCSObject.html">DCSObject</a></li>
|
||||
<li><a href="DCSTask.html">DCSTask</a></li>
|
||||
<li><a href="DCSTypes.html">DCSTypes</a></li>
|
||||
<li><a href="DCSUnit.html">DCSUnit</a></li>
|
||||
<li><a href="DCSWorld.html">DCSWorld</a></li>
|
||||
<li><a href="DCStimer.html">DCStimer</a></li>
|
||||
<li><a href="DEPLOYTASK.html">DEPLOYTASK</a></li>
|
||||
<li><a href="DESTROYBASETASK.html">DESTROYBASETASK</a></li>
|
||||
<li><a href="DESTROYGROUPSTASK.html">DESTROYGROUPSTASK</a></li>
|
||||
<li><a href="DESTROYRADARSTASK.html">DESTROYRADARSTASK</a></li>
|
||||
<li><a href="DESTROYUNITTYPESTASK.html">DESTROYUNITTYPESTASK</a></li>
|
||||
<li><a href="Database.html">Database</a></li>
|
||||
<li><a href="Escort.html">Escort</a></li>
|
||||
<li><a href="Event.html">Event</a></li>
|
||||
<li>GOHOMETASK</li>
|
||||
<li><a href="Group.html">Group</a></li>
|
||||
<li><a href="MISSION.html">MISSION</a></li>
|
||||
<li><a href="MOVEMENT.html">MOVEMENT</a></li>
|
||||
<li><a href="Menu.html">Menu</a></li>
|
||||
<li><a href="Message.html">Message</a></li>
|
||||
<li><a href="NOTASK.html">NOTASK</a></li>
|
||||
<li><a href="PICKUPTASK.html">PICKUPTASK</a></li>
|
||||
<li><a href="ROUTETASK.html">ROUTETASK</a></li>
|
||||
<li><a href="STAGE.html">STAGE</a></li>
|
||||
<li><a href="Scoring.html">Scoring</a></li>
|
||||
<li><a href="Sead.html">Sead</a></li>
|
||||
<li><a href="Spawn.html">Spawn</a></li>
|
||||
<li><a href="StaticObject.html">StaticObject</a></li>
|
||||
<li><a href="TASK.html">TASK</a></li>
|
||||
<li><a href="Unit.html">Unit</a></li>
|
||||
<li><a href="Zone.html">Zone</a></li>
|
||||
<li><a href="env.html">env</a></li>
|
||||
<li><a href="land.html">land</a></li>
|
||||
<li><a href="routines.html">routines</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="content">
|
||||
<h1>Module <code>GOHOMETASK</code></h1>
|
||||
|
||||
<p>A GOHOMETASK orchestrates the travel back to the home base, which is a specific zone defined within the ME.</p>
|
||||
|
||||
<h2>Global(s)</h2>
|
||||
<table class="function_list">
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="#GOHOMETASK">GOHOMETASK</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<h2><a id="#(GOHOMETASK)" >Type <code>GOHOMETASK</code></a></h2>
|
||||
<table class="function_list">
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(GOHOMETASK).ClassName">GOHOMETASK.ClassName</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(GOHOMETASK).New">GOHOMETASK.New(table, self, LandingZones)</a></td>
|
||||
<td class="summary">
|
||||
<p>Creates a new GOHOMETASK.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2>Global(s)</h2>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em><a href="##(GOHOMETASK)">#GOHOMETASK</a></em>
|
||||
<a id="GOHOMETASK" >
|
||||
<strong>GOHOMETASK</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<h2><a id="#(GOHOMETASK)" >Type <code>GOHOMETASK</code></a></h2>
|
||||
<h3>Field(s)</h3>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em>#string</em>
|
||||
<a id="#(GOHOMETASK).ClassName" >
|
||||
<strong>GOHOMETASK.ClassName</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(GOHOMETASK).New" >
|
||||
<strong>GOHOMETASK.New(table, self, LandingZones)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Creates a new GOHOMETASK.</p>
|
||||
|
||||
<h3>Parameters</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em> table </em></code>:
|
||||
string,...}|string LandingZones Table of Landing Zone names where Home(s) are located.</p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> self </em></code>: </p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> LandingZones </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
<h3>Return value</h3>
|
||||
|
||||
|
||||
<p>GOHOMETASK</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,701 +0,0 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" href="stylesheet.css" type="text/css"/>
|
||||
</head>
|
||||
<body>
|
||||
<div id="container">
|
||||
<div id="product">
|
||||
<div id="product_logo"></div>
|
||||
<div id="product_name"><big><b></b></big></div>
|
||||
<div id="product_description"></div>
|
||||
</div>
|
||||
<div id="main">
|
||||
<div id="navigation">
|
||||
<h2>Modules</h2>
|
||||
<ul><li>
|
||||
<a href="index.html">index</a>
|
||||
</li></ul>
|
||||
<ul>
|
||||
<li><a href="Base.html">Base</a></li>
|
||||
<li><a href="CARGO.html">CARGO</a></li>
|
||||
<li><a href="CleanUp.html">CleanUp</a></li>
|
||||
<li><a href="Client.html">Client</a></li>
|
||||
<li><a href="DCSAirbase.html">DCSAirbase</a></li>
|
||||
<li><a href="DCSCoalitionObject.html">DCSCoalitionObject</a></li>
|
||||
<li><a href="DCSCommand.html">DCSCommand</a></li>
|
||||
<li><a href="DCSController.html">DCSController</a></li>
|
||||
<li><a href="DCSGroup.html">DCSGroup</a></li>
|
||||
<li><a href="DCSObject.html">DCSObject</a></li>
|
||||
<li><a href="DCSTask.html">DCSTask</a></li>
|
||||
<li><a href="DCSTypes.html">DCSTypes</a></li>
|
||||
<li><a href="DCSUnit.html">DCSUnit</a></li>
|
||||
<li><a href="DCSWorld.html">DCSWorld</a></li>
|
||||
<li><a href="DCStimer.html">DCStimer</a></li>
|
||||
<li><a href="DEPLOYTASK.html">DEPLOYTASK</a></li>
|
||||
<li><a href="DESTROYBASETASK.html">DESTROYBASETASK</a></li>
|
||||
<li><a href="DESTROYGROUPSTASK.html">DESTROYGROUPSTASK</a></li>
|
||||
<li><a href="DESTROYRADARSTASK.html">DESTROYRADARSTASK</a></li>
|
||||
<li><a href="DESTROYUNITTYPESTASK.html">DESTROYUNITTYPESTASK</a></li>
|
||||
<li><a href="Database.html">Database</a></li>
|
||||
<li><a href="Escort.html">Escort</a></li>
|
||||
<li><a href="Event.html">Event</a></li>
|
||||
<li><a href="GOHOMETASK.html">GOHOMETASK</a></li>
|
||||
<li><a href="Group.html">Group</a></li>
|
||||
<li><a href="MISSION.html">MISSION</a></li>
|
||||
<li><a href="MOVEMENT.html">MOVEMENT</a></li>
|
||||
<li>Menu</li>
|
||||
<li><a href="Message.html">Message</a></li>
|
||||
<li><a href="NOTASK.html">NOTASK</a></li>
|
||||
<li><a href="PICKUPTASK.html">PICKUPTASK</a></li>
|
||||
<li><a href="ROUTETASK.html">ROUTETASK</a></li>
|
||||
<li><a href="STAGE.html">STAGE</a></li>
|
||||
<li><a href="Scoring.html">Scoring</a></li>
|
||||
<li><a href="Sead.html">Sead</a></li>
|
||||
<li><a href="Spawn.html">Spawn</a></li>
|
||||
<li><a href="StaticObject.html">StaticObject</a></li>
|
||||
<li><a href="TASK.html">TASK</a></li>
|
||||
<li><a href="Unit.html">Unit</a></li>
|
||||
<li><a href="Zone.html">Zone</a></li>
|
||||
<li><a href="env.html">env</a></li>
|
||||
<li><a href="land.html">land</a></li>
|
||||
<li><a href="routines.html">routines</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="content">
|
||||
<h1>Module <code>Menu</code></h1>
|
||||
|
||||
<p>Encapsulation of DCS World Menu system in a set of MENU classes.</p>
|
||||
|
||||
<h2>Global(s)</h2>
|
||||
<table class="function_list">
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="#COMMANDMENU">COMMANDMENU</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="#MENU">MENU</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="#MENU_CLIENT">MENU_CLIENT</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="#MENU_CLIENT_COMMAND">MENU_CLIENT_COMMAND</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="#SUBMENU">SUBMENU</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<h2><a id="#(COMMANDMENU)">Type <code>COMMANDMENU</code></a></h2>
|
||||
<table class="function_list">
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(COMMANDMENU).ClassName">COMMANDMENU.ClassName</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(COMMANDMENU).CommandMenuArgument">COMMANDMENU.CommandMenuArgument</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(COMMANDMENU).CommandMenuFunction">COMMANDMENU.CommandMenuFunction</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(COMMANDMENU).New">COMMANDMENU:New(MenuText, ParentMenu, CommandMenuFunction, CommandMenuArgument)</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2><a id="#(MENU)">Type <code>MENU</code></a></h2>
|
||||
<table class="function_list">
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(MENU).ClassName">MENU.ClassName</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(MENU).MenuParentPath">MENU.MenuParentPath</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(MENU).MenuPath">MENU.MenuPath</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(MENU).MenuText">MENU.MenuText</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(MENU).New">MENU:New(MenuText, MenuParentPath)</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2><a id="#(MENU_CLIENT)">Type <code>MENU_CLIENT</code></a></h2>
|
||||
<table class="function_list">
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(MENU_CLIENT).ClassName">MENU_CLIENT.ClassName</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(MENU_CLIENT).New">MENU_CLIENT:New(MenuClient, MenuText, ParentMenu)</a></td>
|
||||
<td class="summary">
|
||||
<p>Creates a new menu item for a group</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(MENU_CLIENT).Remove">MENU_CLIENT:Remove()</a></td>
|
||||
<td class="summary">
|
||||
<p>Removes the sub menus recursively of this MENU_CLIENT.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(MENU_CLIENT).RemoveSubMenus">MENU_CLIENT:RemoveSubMenus()</a></td>
|
||||
<td class="summary">
|
||||
<p>Removes the sub menus recursively of this MENU_CLIENT.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2><a id="#(MENU_CLIENT_COMMAND)">Type <code>MENU_CLIENT_COMMAND</code></a></h2>
|
||||
<table class="function_list">
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(MENU_CLIENT_COMMAND).ClassName">MENU_CLIENT_COMMAND.ClassName</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(MENU_CLIENT_COMMAND).New">MENU_CLIENT_COMMAND:New(MenuClient, MenuText, ParentMenu, CommandMenuFunction, CommandMenuArgument)</a></td>
|
||||
<td class="summary">
|
||||
<p>Creates a new radio command item for a group</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(MENU_CLIENT_COMMAND).Remove">MENU_CLIENT_COMMAND:Remove()</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2><a id="#(SUBMENU)">Type <code>SUBMENU</code></a></h2>
|
||||
<table class="function_list">
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(SUBMENU).ClassName">SUBMENU.ClassName</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(SUBMENU).New">SUBMENU:New(MenuText, ParentMenu)</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2>Global(s)</h2>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em><a href="##(COMMANDMENU)">#COMMANDMENU</a></em>
|
||||
<a id="COMMANDMENU" >
|
||||
<strong>COMMANDMENU</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em><a href="##(MENU)">#MENU</a></em>
|
||||
<a id="MENU" >
|
||||
<strong>MENU</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em><a href="##(MENU_CLIENT)">#MENU_CLIENT</a></em>
|
||||
<a id="MENU_CLIENT" >
|
||||
<strong>MENU_CLIENT</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em><a href="##(MENU_CLIENT_COMMAND)">#MENU_CLIENT_COMMAND</a></em>
|
||||
<a id="MENU_CLIENT_COMMAND" >
|
||||
<strong>MENU_CLIENT_COMMAND</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em><a href="##(SUBMENU)">#SUBMENU</a></em>
|
||||
<a id="SUBMENU" >
|
||||
<strong>SUBMENU</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<h2><a id="#(Menu)" >Type <code>Menu</code></a></h2>
|
||||
|
||||
<h2><a id="#(COMMANDMENU)" >Type <code>COMMANDMENU</code></a></h2>
|
||||
|
||||
<p>The COMMANDMENU class</p>
|
||||
|
||||
<h3>Field(s)</h3>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em>#string</em>
|
||||
<a id="#(COMMANDMENU).ClassName" >
|
||||
<strong>COMMANDMENU.ClassName</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(COMMANDMENU).CommandMenuArgument" >
|
||||
<strong>COMMANDMENU.CommandMenuArgument</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(COMMANDMENU).CommandMenuFunction" >
|
||||
<strong>COMMANDMENU.CommandMenuFunction</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(COMMANDMENU).New" >
|
||||
<strong>COMMANDMENU:New(MenuText, ParentMenu, CommandMenuFunction, CommandMenuArgument)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
<h3>Parameters</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em> MenuText </em></code>: </p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> ParentMenu </em></code>: </p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> CommandMenuFunction </em></code>: </p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> CommandMenuArgument </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<h2><a id="#(MENU)" >Type <code>MENU</code></a></h2>
|
||||
|
||||
<p>The MENU class</p>
|
||||
|
||||
<h3>Field(s)</h3>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em>#string</em>
|
||||
<a id="#(MENU).ClassName" >
|
||||
<strong>MENU.ClassName</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(MENU).MenuParentPath" >
|
||||
<strong>MENU.MenuParentPath</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(MENU).MenuPath" >
|
||||
<strong>MENU.MenuPath</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em>#string</em>
|
||||
<a id="#(MENU).MenuText" >
|
||||
<strong>MENU.MenuText</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(MENU).New" >
|
||||
<strong>MENU:New(MenuText, MenuParentPath)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
<h3>Parameters</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em> MenuText </em></code>: </p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> MenuParentPath </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<h2><a id="#(MENU_CLIENT)" >Type <code>MENU_CLIENT</code></a></h2>
|
||||
|
||||
<p>The MENU_CLIENT class</p>
|
||||
|
||||
<h3>Field(s)</h3>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em>#string</em>
|
||||
<a id="#(MENU_CLIENT).ClassName" >
|
||||
<strong>MENU_CLIENT.ClassName</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(MENU_CLIENT).New" >
|
||||
<strong>MENU_CLIENT:New(MenuClient, MenuText, ParentMenu)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Creates a new menu item for a group</p>
|
||||
|
||||
<h3>Parameters</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em><a href="Client.html##(CLIENT)">Client#CLIENT</a> MenuClient </em></code>:
|
||||
The Client owning the menu.</p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em>#string MenuText </em></code>:
|
||||
The text for the menu.</p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em>#table ParentMenu </em></code>:
|
||||
The parent menu.</p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
<h3>Return value</h3>
|
||||
|
||||
<p><em><a href="##(MENU_CLIENT)">#MENU_CLIENT</a>:</em>
|
||||
self</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(MENU_CLIENT).Remove" >
|
||||
<strong>MENU_CLIENT:Remove()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Removes the sub menus recursively of this MENU_CLIENT.</p>
|
||||
|
||||
<h3>Return value</h3>
|
||||
|
||||
<p><em><a href="##(MENU_CLIENT)">#MENU_CLIENT</a>:</em>
|
||||
self</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(MENU_CLIENT).RemoveSubMenus" >
|
||||
<strong>MENU_CLIENT:RemoveSubMenus()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Removes the sub menus recursively of this MENU_CLIENT.</p>
|
||||
|
||||
<h3>Return value</h3>
|
||||
|
||||
<p><em><a href="##(MENU_CLIENT)">#MENU_CLIENT</a>:</em>
|
||||
self</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<h2><a id="#(MENU_CLIENT_COMMAND)" >Type <code>MENU_CLIENT_COMMAND</code></a></h2>
|
||||
|
||||
<p>The MENU<em>CLIENT</em>COMMAND class</p>
|
||||
|
||||
<h3>Field(s)</h3>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em>#string</em>
|
||||
<a id="#(MENU_CLIENT_COMMAND).ClassName" >
|
||||
<strong>MENU_CLIENT_COMMAND.ClassName</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(MENU_CLIENT_COMMAND).New" >
|
||||
<strong>MENU_CLIENT_COMMAND:New(MenuClient, MenuText, ParentMenu, CommandMenuFunction, CommandMenuArgument)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Creates a new radio command item for a group</p>
|
||||
|
||||
<h3>Parameters</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em><a href="Client.html##(CLIENT)">Client#CLIENT</a> MenuClient </em></code>:
|
||||
The Client owning the menu.</p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> MenuText </em></code>:
|
||||
The text for the menu.</p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> ParentMenu </em></code>:
|
||||
The parent menu.</p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> CommandMenuFunction </em></code>:
|
||||
A function that is called when the menu key is pressed.</p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> CommandMenuArgument </em></code>:
|
||||
An argument for the function.</p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
<h3>Return value</h3>
|
||||
|
||||
<p><em><a href="Menu.html##(MENU_CLIENT_COMMAND)">Menu#MENU<em>CLIENT</em>COMMAND</a>:</em>
|
||||
self</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(MENU_CLIENT_COMMAND).Remove" >
|
||||
<strong>MENU_CLIENT_COMMAND:Remove()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<h2><a id="#(SUBMENU)" >Type <code>SUBMENU</code></a></h2>
|
||||
|
||||
<p>The SUBMENU class</p>
|
||||
|
||||
<h3>Field(s)</h3>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em>#string</em>
|
||||
<a id="#(SUBMENU).ClassName" >
|
||||
<strong>SUBMENU.ClassName</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(SUBMENU).New" >
|
||||
<strong>SUBMENU:New(MenuText, ParentMenu)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
<h3>Parameters</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em> MenuText </em></code>: </p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> ParentMenu </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,392 +0,0 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" href="stylesheet.css" type="text/css"/>
|
||||
</head>
|
||||
<body>
|
||||
<div id="container">
|
||||
<div id="product">
|
||||
<div id="product_logo"></div>
|
||||
<div id="product_name"><big><b></b></big></div>
|
||||
<div id="product_description"></div>
|
||||
</div>
|
||||
<div id="main">
|
||||
<div id="navigation">
|
||||
<h2>Modules</h2>
|
||||
<ul><li>
|
||||
<a href="index.html">index</a>
|
||||
</li></ul>
|
||||
<ul>
|
||||
<li><a href="Base.html">Base</a></li>
|
||||
<li><a href="CARGO.html">CARGO</a></li>
|
||||
<li><a href="CleanUp.html">CleanUp</a></li>
|
||||
<li><a href="Client.html">Client</a></li>
|
||||
<li><a href="DCSAirbase.html">DCSAirbase</a></li>
|
||||
<li><a href="DCSCoalitionObject.html">DCSCoalitionObject</a></li>
|
||||
<li><a href="DCSCommand.html">DCSCommand</a></li>
|
||||
<li><a href="DCSController.html">DCSController</a></li>
|
||||
<li><a href="DCSGroup.html">DCSGroup</a></li>
|
||||
<li><a href="DCSObject.html">DCSObject</a></li>
|
||||
<li><a href="DCSTask.html">DCSTask</a></li>
|
||||
<li><a href="DCSTypes.html">DCSTypes</a></li>
|
||||
<li><a href="DCSUnit.html">DCSUnit</a></li>
|
||||
<li><a href="DCSWorld.html">DCSWorld</a></li>
|
||||
<li><a href="DCStimer.html">DCStimer</a></li>
|
||||
<li><a href="DEPLOYTASK.html">DEPLOYTASK</a></li>
|
||||
<li><a href="DESTROYBASETASK.html">DESTROYBASETASK</a></li>
|
||||
<li><a href="DESTROYGROUPSTASK.html">DESTROYGROUPSTASK</a></li>
|
||||
<li><a href="DESTROYRADARSTASK.html">DESTROYRADARSTASK</a></li>
|
||||
<li><a href="DESTROYUNITTYPESTASK.html">DESTROYUNITTYPESTASK</a></li>
|
||||
<li><a href="Database.html">Database</a></li>
|
||||
<li><a href="Escort.html">Escort</a></li>
|
||||
<li><a href="Event.html">Event</a></li>
|
||||
<li><a href="GOHOMETASK.html">GOHOMETASK</a></li>
|
||||
<li><a href="Group.html">Group</a></li>
|
||||
<li><a href="MISSION.html">MISSION</a></li>
|
||||
<li><a href="MOVEMENT.html">MOVEMENT</a></li>
|
||||
<li><a href="Menu.html">Menu</a></li>
|
||||
<li><a href="Message.html">Message</a></li>
|
||||
<li><a href="NOTASK.html">NOTASK</a></li>
|
||||
<li>PICKUPTASK</li>
|
||||
<li><a href="ROUTETASK.html">ROUTETASK</a></li>
|
||||
<li><a href="STAGE.html">STAGE</a></li>
|
||||
<li><a href="Scoring.html">Scoring</a></li>
|
||||
<li><a href="Sead.html">Sead</a></li>
|
||||
<li><a href="Spawn.html">Spawn</a></li>
|
||||
<li><a href="StaticObject.html">StaticObject</a></li>
|
||||
<li><a href="TASK.html">TASK</a></li>
|
||||
<li><a href="Unit.html">Unit</a></li>
|
||||
<li><a href="Zone.html">Zone</a></li>
|
||||
<li><a href="env.html">env</a></li>
|
||||
<li><a href="land.html">land</a></li>
|
||||
<li><a href="routines.html">routines</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="content">
|
||||
<h1>Module <code>PICKUPTASK</code></h1>
|
||||
|
||||
<p>A PICKUPTASK orchestrates the loading of CARGO at a specific landing zone.</p>
|
||||
|
||||
<h2>Global(s)</h2>
|
||||
<table class="function_list">
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="#PICKUPTASK">PICKUPTASK</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<h2><a id="#(PICKUPTASK)" >Type <code>PICKUPTASK</code></a></h2>
|
||||
<table class="function_list">
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(PICKUPTASK).AddCargoMenus">PICKUPTASK:AddCargoMenus(Client, Cargos, TransportRadius)</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(PICKUPTASK).ClassName">PICKUPTASK.ClassName</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(PICKUPTASK).FromZone">PICKUPTASK:FromZone(LandingZone)</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(PICKUPTASK).GoalVerb">PICKUPTASK.GoalVerb</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(PICKUPTASK).HasFailed">PICKUPTASK:HasFailed(ClientDead)</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(PICKUPTASK).InitCargo">PICKUPTASK:InitCargo(InitCargos)</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(PICKUPTASK).LoadCargo">PICKUPTASK:LoadCargo(LoadCargos)</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(PICKUPTASK).New">PICKUPTASK.New(table, CARGO_TYPE, number, self, CargoType, OnBoardSide)</a></td>
|
||||
<td class="summary">
|
||||
<p>Creates a new PICKUPTASK.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(PICKUPTASK).RemoveCargoMenus">PICKUPTASK:RemoveCargoMenus(Client)</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(PICKUPTASK).TEXT">PICKUPTASK.TEXT</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2>Global(s)</h2>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em><a href="##(PICKUPTASK)">#PICKUPTASK</a></em>
|
||||
<a id="PICKUPTASK" >
|
||||
<strong>PICKUPTASK</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<h2><a id="#(PICKUPTASK)" >Type <code>PICKUPTASK</code></a></h2>
|
||||
<h3>Field(s)</h3>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(PICKUPTASK).AddCargoMenus" >
|
||||
<strong>PICKUPTASK:AddCargoMenus(Client, Cargos, TransportRadius)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
<h3>Parameters</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em> Client </em></code>: </p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> Cargos </em></code>: </p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> TransportRadius </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em>#string</em>
|
||||
<a id="#(PICKUPTASK).ClassName" >
|
||||
<strong>PICKUPTASK.ClassName</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(PICKUPTASK).FromZone" >
|
||||
<strong>PICKUPTASK:FromZone(LandingZone)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
<h3>Parameter</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em> LandingZone </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em>#string</em>
|
||||
<a id="#(PICKUPTASK).GoalVerb" >
|
||||
<strong>PICKUPTASK.GoalVerb</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(PICKUPTASK).HasFailed" >
|
||||
<strong>PICKUPTASK:HasFailed(ClientDead)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
<h3>Parameter</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em> ClientDead </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(PICKUPTASK).InitCargo" >
|
||||
<strong>PICKUPTASK:InitCargo(InitCargos)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
<h3>Parameter</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em> InitCargos </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(PICKUPTASK).LoadCargo" >
|
||||
<strong>PICKUPTASK:LoadCargo(LoadCargos)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
<h3>Parameter</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em> LoadCargos </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(PICKUPTASK).New" >
|
||||
<strong>PICKUPTASK.New(table, CARGO_TYPE, number, self, CargoType, OnBoardSide)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Creates a new PICKUPTASK.</p>
|
||||
|
||||
<h3>Parameters</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em> table </em></code>:
|
||||
string,...}|string LandingZones Table of Zone names where Cargo is to be loaded.</p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> CARGO_TYPE </em></code>:
|
||||
CargoType Type of the Cargo. The type must be of the following Enumeration:..</p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> number </em></code>:
|
||||
OnBoardSide Reflects from which side the cargo Group will be on-boarded on the Carrier.</p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> self </em></code>: </p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> CargoType </em></code>: </p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> OnBoardSide </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(PICKUPTASK).RemoveCargoMenus" >
|
||||
<strong>PICKUPTASK:RemoveCargoMenus(Client)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
<h3>Parameter</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em> Client </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em></em>
|
||||
<a id="#(PICKUPTASK).TEXT" >
|
||||
<strong>PICKUPTASK.TEXT</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,199 +0,0 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" href="stylesheet.css" type="text/css"/>
|
||||
</head>
|
||||
<body>
|
||||
<div id="container">
|
||||
<div id="product">
|
||||
<div id="product_logo"></div>
|
||||
<div id="product_name"><big><b></b></big></div>
|
||||
<div id="product_description"></div>
|
||||
</div>
|
||||
<div id="main">
|
||||
<div id="navigation">
|
||||
<h2>Modules</h2>
|
||||
<ul><li>
|
||||
<a href="index.html">index</a>
|
||||
</li></ul>
|
||||
<ul>
|
||||
<li><a href="Base.html">Base</a></li>
|
||||
<li><a href="CARGO.html">CARGO</a></li>
|
||||
<li><a href="CleanUp.html">CleanUp</a></li>
|
||||
<li><a href="Client.html">Client</a></li>
|
||||
<li><a href="DCSAirbase.html">DCSAirbase</a></li>
|
||||
<li><a href="DCSCoalitionObject.html">DCSCoalitionObject</a></li>
|
||||
<li><a href="DCSCommand.html">DCSCommand</a></li>
|
||||
<li><a href="DCSController.html">DCSController</a></li>
|
||||
<li><a href="DCSGroup.html">DCSGroup</a></li>
|
||||
<li><a href="DCSObject.html">DCSObject</a></li>
|
||||
<li><a href="DCSTask.html">DCSTask</a></li>
|
||||
<li><a href="DCSTypes.html">DCSTypes</a></li>
|
||||
<li><a href="DCSUnit.html">DCSUnit</a></li>
|
||||
<li><a href="DCSWorld.html">DCSWorld</a></li>
|
||||
<li><a href="DCStimer.html">DCStimer</a></li>
|
||||
<li><a href="DEPLOYTASK.html">DEPLOYTASK</a></li>
|
||||
<li><a href="DESTROYBASETASK.html">DESTROYBASETASK</a></li>
|
||||
<li><a href="DESTROYGROUPSTASK.html">DESTROYGROUPSTASK</a></li>
|
||||
<li><a href="DESTROYRADARSTASK.html">DESTROYRADARSTASK</a></li>
|
||||
<li><a href="DESTROYUNITTYPESTASK.html">DESTROYUNITTYPESTASK</a></li>
|
||||
<li><a href="Database.html">Database</a></li>
|
||||
<li><a href="Escort.html">Escort</a></li>
|
||||
<li><a href="Event.html">Event</a></li>
|
||||
<li><a href="GOHOMETASK.html">GOHOMETASK</a></li>
|
||||
<li><a href="Group.html">Group</a></li>
|
||||
<li><a href="MISSION.html">MISSION</a></li>
|
||||
<li><a href="MOVEMENT.html">MOVEMENT</a></li>
|
||||
<li><a href="Menu.html">Menu</a></li>
|
||||
<li><a href="Message.html">Message</a></li>
|
||||
<li><a href="NOTASK.html">NOTASK</a></li>
|
||||
<li><a href="PICKUPTASK.html">PICKUPTASK</a></li>
|
||||
<li>ROUTETASK</li>
|
||||
<li><a href="STAGE.html">STAGE</a></li>
|
||||
<li><a href="Scoring.html">Scoring</a></li>
|
||||
<li><a href="Sead.html">Sead</a></li>
|
||||
<li><a href="Spawn.html">Spawn</a></li>
|
||||
<li><a href="StaticObject.html">StaticObject</a></li>
|
||||
<li><a href="TASK.html">TASK</a></li>
|
||||
<li><a href="Unit.html">Unit</a></li>
|
||||
<li><a href="Zone.html">Zone</a></li>
|
||||
<li><a href="env.html">env</a></li>
|
||||
<li><a href="land.html">land</a></li>
|
||||
<li><a href="routines.html">routines</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="content">
|
||||
<h1>Module <code>ROUTETASK</code></h1>
|
||||
|
||||
<p>A ROUTETASK orchestrates the travel to a specific zone defined within the ME.</p>
|
||||
|
||||
<h2>Global(s)</h2>
|
||||
<table class="function_list">
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="#ROUTETASK">ROUTETASK</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<h2><a id="#(ROUTETASK)" >Type <code>ROUTETASK</code></a></h2>
|
||||
<table class="function_list">
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(ROUTETASK).ClassName">ROUTETASK.ClassName</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(ROUTETASK).GoalVerb">ROUTETASK.GoalVerb</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(ROUTETASK).New">ROUTETASK.New(table, string, self, LandingZones, TaskBriefing)</a></td>
|
||||
<td class="summary">
|
||||
<p>Creates a new ROUTETASK.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2>Global(s)</h2>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em><a href="##(ROUTETASK)">#ROUTETASK</a></em>
|
||||
<a id="ROUTETASK" >
|
||||
<strong>ROUTETASK</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<h2><a id="#(ROUTETASK)" >Type <code>ROUTETASK</code></a></h2>
|
||||
<h3>Field(s)</h3>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em>#string</em>
|
||||
<a id="#(ROUTETASK).ClassName" >
|
||||
<strong>ROUTETASK.ClassName</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em>#string</em>
|
||||
<a id="#(ROUTETASK).GoalVerb" >
|
||||
<strong>ROUTETASK.GoalVerb</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(ROUTETASK).New" >
|
||||
<strong>ROUTETASK.New(table, string, self, LandingZones, TaskBriefing)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Creates a new ROUTETASK.</p>
|
||||
|
||||
<h3>Parameters</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em> table </em></code>:
|
||||
sring,...}|string LandingZones Table of Zone Names where the target is located.</p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> string </em></code>:
|
||||
TaskBriefing (optional) Defines a text describing the briefing of the task.</p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> self </em></code>: </p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> LandingZones </em></code>: </p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> TaskBriefing </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
<h3>Return value</h3>
|
||||
|
||||
|
||||
<p>ROUTETASK</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,819 +0,0 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" href="stylesheet.css" type="text/css"/>
|
||||
</head>
|
||||
<body>
|
||||
<div id="container">
|
||||
<div id="product">
|
||||
<div id="product_logo"></div>
|
||||
<div id="product_name"><big><b></b></big></div>
|
||||
<div id="product_description"></div>
|
||||
</div>
|
||||
<div id="main">
|
||||
<div id="navigation">
|
||||
<h2>Modules</h2>
|
||||
<ul><li>
|
||||
<a href="index.html">index</a>
|
||||
</li></ul>
|
||||
<ul>
|
||||
<li><a href="Base.html">Base</a></li>
|
||||
<li><a href="CARGO.html">CARGO</a></li>
|
||||
<li><a href="CleanUp.html">CleanUp</a></li>
|
||||
<li><a href="Client.html">Client</a></li>
|
||||
<li><a href="DCSAirbase.html">DCSAirbase</a></li>
|
||||
<li><a href="DCSCoalitionObject.html">DCSCoalitionObject</a></li>
|
||||
<li><a href="DCSCommand.html">DCSCommand</a></li>
|
||||
<li><a href="DCSController.html">DCSController</a></li>
|
||||
<li><a href="DCSGroup.html">DCSGroup</a></li>
|
||||
<li><a href="DCSObject.html">DCSObject</a></li>
|
||||
<li><a href="DCSTask.html">DCSTask</a></li>
|
||||
<li><a href="DCSTypes.html">DCSTypes</a></li>
|
||||
<li><a href="DCSUnit.html">DCSUnit</a></li>
|
||||
<li><a href="DCSWorld.html">DCSWorld</a></li>
|
||||
<li><a href="DCStimer.html">DCStimer</a></li>
|
||||
<li><a href="DEPLOYTASK.html">DEPLOYTASK</a></li>
|
||||
<li><a href="DESTROYBASETASK.html">DESTROYBASETASK</a></li>
|
||||
<li><a href="DESTROYGROUPSTASK.html">DESTROYGROUPSTASK</a></li>
|
||||
<li><a href="DESTROYRADARSTASK.html">DESTROYRADARSTASK</a></li>
|
||||
<li><a href="DESTROYUNITTYPESTASK.html">DESTROYUNITTYPESTASK</a></li>
|
||||
<li><a href="Database.html">Database</a></li>
|
||||
<li><a href="Escort.html">Escort</a></li>
|
||||
<li><a href="Event.html">Event</a></li>
|
||||
<li><a href="GOHOMETASK.html">GOHOMETASK</a></li>
|
||||
<li><a href="Group.html">Group</a></li>
|
||||
<li><a href="MISSION.html">MISSION</a></li>
|
||||
<li><a href="MOVEMENT.html">MOVEMENT</a></li>
|
||||
<li><a href="Menu.html">Menu</a></li>
|
||||
<li><a href="Message.html">Message</a></li>
|
||||
<li><a href="NOTASK.html">NOTASK</a></li>
|
||||
<li><a href="PICKUPTASK.html">PICKUPTASK</a></li>
|
||||
<li><a href="ROUTETASK.html">ROUTETASK</a></li>
|
||||
<li>STAGE</li>
|
||||
<li><a href="Scoring.html">Scoring</a></li>
|
||||
<li><a href="Sead.html">Sead</a></li>
|
||||
<li><a href="Spawn.html">Spawn</a></li>
|
||||
<li><a href="StaticObject.html">StaticObject</a></li>
|
||||
<li><a href="TASK.html">TASK</a></li>
|
||||
<li><a href="Unit.html">Unit</a></li>
|
||||
<li><a href="Zone.html">Zone</a></li>
|
||||
<li><a href="env.html">env</a></li>
|
||||
<li><a href="land.html">land</a></li>
|
||||
<li><a href="routines.html">routines</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="content">
|
||||
<h1>Module <code>STAGE</code></h1>
|
||||
|
||||
<p>Stages within a <a href="TASK.html">TASK</a> within a <a href="MISSION.html">MISSION</a>.</p>
|
||||
|
||||
|
||||
<p>All of the STAGE functionality is considered internally administered and not to be used by any Mission designer.</p>
|
||||
|
||||
<h2>Global(s)</h2>
|
||||
<table class="function_list">
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="#CargoStatic">CargoStatic</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="#STAGE">STAGE</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="#STAGEARRIVE">STAGEARRIVE</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="#STAGEBRIEF">STAGEBRIEF</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="#STAGEDONE">STAGEDONE</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="#STAGEGROUPSDESTROYED">STAGEGROUPSDESTROYED</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="#STAGELANDED">STAGELANDED</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="#STAGELANDING">STAGELANDING</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="#STAGELOAD">STAGELOAD</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="#STAGEROUTE">STAGEROUTE</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="#STAGESTART">STAGESTART</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="#STAGEUNLOAD">STAGEUNLOAD</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="#STAGE_CARGO_INIT">STAGE_CARGO_INIT</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="#STAGE_CARGO_LOAD">STAGE_CARGO_LOAD</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="#_TransportStage">_TransportStage</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="#_TransportStageAction">_TransportStageAction</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="#_TransportStageTime">_TransportStageTime</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<h2><a id="#(STAGE)" >Type <code>STAGE</code></a></h2>
|
||||
<table class="function_list">
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(STAGE).ClassName">STAGE.ClassName</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(STAGE).Execute">STAGE:Execute(Mission, Client, Task)</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(STAGE).Executing">STAGE:Executing(Mission, Client, Task)</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(STAGE).FREQUENCY">STAGE.FREQUENCY</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(STAGE).Frequency">STAGE.Frequency</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(STAGE).MSG">STAGE.MSG</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(STAGE).MessageCount">STAGE.MessageCount</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(STAGE).MessageFlash">STAGE.MessageFlash</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(STAGE).MessageInterval">STAGE.MessageInterval</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(STAGE).MessageShow">STAGE.MessageShow</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(STAGE).MessageShown">STAGE.MessageShown</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(STAGE).Name">STAGE.Name</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(STAGE).New">STAGE:New()</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(STAGE).StageType">STAGE.StageType</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(STAGE).Validate">STAGE:Validate(Mission, Client, Task)</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(STAGE).WaitTime">STAGE.WaitTime</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2>Global(s)</h2>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em></em>
|
||||
<a id="CargoStatic" >
|
||||
<strong>CargoStatic</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em><a href="##(STAGE)">#STAGE</a></em>
|
||||
<a id="STAGE" >
|
||||
<strong>STAGE</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em></em>
|
||||
<a id="STAGEARRIVE" >
|
||||
<strong>STAGEARRIVE</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em></em>
|
||||
<a id="STAGEBRIEF" >
|
||||
<strong>STAGEBRIEF</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em></em>
|
||||
<a id="STAGEDONE" >
|
||||
<strong>STAGEDONE</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em></em>
|
||||
<a id="STAGEGROUPSDESTROYED" >
|
||||
<strong>STAGEGROUPSDESTROYED</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em></em>
|
||||
<a id="STAGELANDED" >
|
||||
<strong>STAGELANDED</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em></em>
|
||||
<a id="STAGELANDING" >
|
||||
<strong>STAGELANDING</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em></em>
|
||||
<a id="STAGELOAD" >
|
||||
<strong>STAGELOAD</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em></em>
|
||||
<a id="STAGEROUTE" >
|
||||
<strong>STAGEROUTE</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em></em>
|
||||
<a id="STAGESTART" >
|
||||
<strong>STAGESTART</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em></em>
|
||||
<a id="STAGEUNLOAD" >
|
||||
<strong>STAGEUNLOAD</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em></em>
|
||||
<a id="STAGE_CARGO_INIT" >
|
||||
<strong>STAGE_CARGO_INIT</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em></em>
|
||||
<a id="STAGE_CARGO_LOAD" >
|
||||
<strong>STAGE_CARGO_LOAD</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em></em>
|
||||
<a id="_TransportStage" >
|
||||
<strong>_TransportStage</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
|
||||
<p> _TransportStage: Defines the different stages of which of transport missions can be in. This table is internal and is used to control the sequence of messages, actions and flow.</p>
|
||||
|
||||
<ul>
|
||||
<li>_TransportStage.START</li>
|
||||
<li>_TransportStage.ROUTE</li>
|
||||
<li>_TransportStage.LAND</li>
|
||||
<li>_TransportStage.EXECUTE</li>
|
||||
<li>_TransportStage.DONE</li>
|
||||
<li>_TransportStage.REMOVE
|
||||
--</li>
|
||||
</ul>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em></em>
|
||||
<a id="_TransportStageAction" >
|
||||
<strong>_TransportStageAction</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em></em>
|
||||
<a id="_TransportStageTime" >
|
||||
<strong>_TransportStageTime</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<h2><a id="#(STAGE)" >Type <code>STAGE</code></a></h2>
|
||||
<h3>Field(s)</h3>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em>#string</em>
|
||||
<a id="#(STAGE).ClassName" >
|
||||
<strong>STAGE.ClassName</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(STAGE).Execute" >
|
||||
<strong>STAGE:Execute(Mission, Client, Task)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
<h3>Parameters</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em> Mission </em></code>: </p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> Client </em></code>: </p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> Task </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(STAGE).Executing" >
|
||||
<strong>STAGE:Executing(Mission, Client, Task)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
<h3>Parameters</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em> Mission </em></code>: </p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> Client </em></code>: </p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> Task </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em></em>
|
||||
<a id="#(STAGE).FREQUENCY" >
|
||||
<strong>STAGE.FREQUENCY</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em>#number</em>
|
||||
<a id="#(STAGE).Frequency" >
|
||||
<strong>STAGE.Frequency</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em></em>
|
||||
<a id="#(STAGE).MSG" >
|
||||
<strong>STAGE.MSG</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em>#number</em>
|
||||
<a id="#(STAGE).MessageCount" >
|
||||
<strong>STAGE.MessageCount</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em>#boolean</em>
|
||||
<a id="#(STAGE).MessageFlash" >
|
||||
<strong>STAGE.MessageFlash</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em>#number</em>
|
||||
<a id="#(STAGE).MessageInterval" >
|
||||
<strong>STAGE.MessageInterval</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em>#boolean</em>
|
||||
<a id="#(STAGE).MessageShow" >
|
||||
<strong>STAGE.MessageShow</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em></em>
|
||||
<a id="#(STAGE).MessageShown" >
|
||||
<strong>STAGE.MessageShown</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em>#string</em>
|
||||
<a id="#(STAGE).Name" >
|
||||
<strong>STAGE.Name</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(STAGE).New" >
|
||||
<strong>STAGE:New()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em>#string</em>
|
||||
<a id="#(STAGE).StageType" >
|
||||
<strong>STAGE.StageType</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(STAGE).Validate" >
|
||||
<strong>STAGE:Validate(Mission, Client, Task)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
<h3>Parameters</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em> Mission </em></code>: </p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> Client </em></code>: </p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> Task </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em>#number</em>
|
||||
<a id="#(STAGE).WaitTime" >
|
||||
<strong>STAGE.WaitTime</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<h2><a id="#(STAGEARRIVE)" >Type <code>STAGEARRIVE</code></a></h2>
|
||||
|
||||
<h2><a id="#(STAGELANDING)" >Type <code>STAGELANDING</code></a></h2>
|
||||
|
||||
<h2><a id="#(STAGEROUTE)" >Type <code>STAGEROUTE</code></a></h2>
|
||||
|
||||
<h2><a id="#(STAGEUNLOAD)" >Type <code>STAGEUNLOAD</code></a></h2>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,791 +0,0 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" href="stylesheet.css" type="text/css"/>
|
||||
</head>
|
||||
<body>
|
||||
<div id="container">
|
||||
<div id="product">
|
||||
<div id="product_logo"></div>
|
||||
<div id="product_name"><big><b></b></big></div>
|
||||
<div id="product_description"></div>
|
||||
</div>
|
||||
<div id="main">
|
||||
<div id="navigation">
|
||||
<h2>Modules</h2>
|
||||
<ul><li>
|
||||
<a href="index.html">index</a>
|
||||
</li></ul>
|
||||
<ul>
|
||||
<li><a href="Base.html">Base</a></li>
|
||||
<li><a href="CARGO.html">CARGO</a></li>
|
||||
<li><a href="CleanUp.html">CleanUp</a></li>
|
||||
<li><a href="Client.html">Client</a></li>
|
||||
<li><a href="DCSAirbase.html">DCSAirbase</a></li>
|
||||
<li><a href="DCSCoalitionObject.html">DCSCoalitionObject</a></li>
|
||||
<li><a href="DCSCommand.html">DCSCommand</a></li>
|
||||
<li><a href="DCSController.html">DCSController</a></li>
|
||||
<li><a href="DCSGroup.html">DCSGroup</a></li>
|
||||
<li><a href="DCSObject.html">DCSObject</a></li>
|
||||
<li><a href="DCSTask.html">DCSTask</a></li>
|
||||
<li><a href="DCSTypes.html">DCSTypes</a></li>
|
||||
<li><a href="DCSUnit.html">DCSUnit</a></li>
|
||||
<li><a href="DCSWorld.html">DCSWorld</a></li>
|
||||
<li><a href="DCStimer.html">DCStimer</a></li>
|
||||
<li><a href="DEPLOYTASK.html">DEPLOYTASK</a></li>
|
||||
<li><a href="DESTROYBASETASK.html">DESTROYBASETASK</a></li>
|
||||
<li><a href="DESTROYGROUPSTASK.html">DESTROYGROUPSTASK</a></li>
|
||||
<li><a href="DESTROYRADARSTASK.html">DESTROYRADARSTASK</a></li>
|
||||
<li><a href="DESTROYUNITTYPESTASK.html">DESTROYUNITTYPESTASK</a></li>
|
||||
<li><a href="Database.html">Database</a></li>
|
||||
<li><a href="Escort.html">Escort</a></li>
|
||||
<li><a href="Event.html">Event</a></li>
|
||||
<li><a href="GOHOMETASK.html">GOHOMETASK</a></li>
|
||||
<li><a href="Group.html">Group</a></li>
|
||||
<li><a href="MISSION.html">MISSION</a></li>
|
||||
<li><a href="MOVEMENT.html">MOVEMENT</a></li>
|
||||
<li><a href="Menu.html">Menu</a></li>
|
||||
<li><a href="Message.html">Message</a></li>
|
||||
<li><a href="NOTASK.html">NOTASK</a></li>
|
||||
<li><a href="PICKUPTASK.html">PICKUPTASK</a></li>
|
||||
<li><a href="ROUTETASK.html">ROUTETASK</a></li>
|
||||
<li><a href="STAGE.html">STAGE</a></li>
|
||||
<li>Scoring</li>
|
||||
<li><a href="Sead.html">Sead</a></li>
|
||||
<li><a href="Spawn.html">Spawn</a></li>
|
||||
<li><a href="StaticObject.html">StaticObject</a></li>
|
||||
<li><a href="TASK.html">TASK</a></li>
|
||||
<li><a href="Unit.html">Unit</a></li>
|
||||
<li><a href="Zone.html">Zone</a></li>
|
||||
<li><a href="env.html">env</a></li>
|
||||
<li><a href="land.html">land</a></li>
|
||||
<li><a href="routines.html">routines</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="content">
|
||||
<h1>Module <code>Scoring</code></h1>
|
||||
|
||||
<p>Scoring system for MOOSE.</p>
|
||||
|
||||
|
||||
<p>This scoring class calculates the hits and kills that players make within a simulation session.
|
||||
Scoring is calculated using a defined algorithm.
|
||||
With a small change in MissionScripting.lua, the scoring can also be logged in a CSV file, that can then be uploaded
|
||||
to a database or a BI tool to publish the scoring results to the player community.</p>
|
||||
|
||||
<h2>Global(s)</h2>
|
||||
<table class="function_list">
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="#ClientGroup">ClientGroup</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="#SCORING">SCORING</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="#nHours">nHours</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="#nMins">nMins</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="#nSecs">nSecs</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<h2><a id="#(SCORING)">Type <code>SCORING</code></a></h2>
|
||||
<table class="function_list">
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(SCORING).AllScoresMenu">SCORING.AllScoresMenu</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(SCORING).ClassID">SCORING.ClassID</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(SCORING).ClassName">SCORING.ClassName</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(SCORING).CloseCSV">SCORING:CloseCSV()</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(SCORING).Menu">SCORING.Menu</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(SCORING).New">SCORING:New(GameName)</a></td>
|
||||
<td class="summary">
|
||||
<p>Creates a new SCORING object to administer the scoring achieved by players.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(SCORING).OpenCSV">SCORING:OpenCSV(ScoringCSV)</a></td>
|
||||
<td class="summary">
|
||||
<p>Opens a score CSV file to log the scores.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(SCORING).Players">SCORING.Players</a></td>
|
||||
<td class="summary">
|
||||
<p>A collection of the current players that have joined the game.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(SCORING).ReportScoreAll">SCORING:ReportScoreAll()</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(SCORING).ReportScorePlayer">SCORING:ReportScorePlayer()</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(SCORING).RunTime">SCORING.RunTime</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(SCORING).ScoreCSV">SCORING:ScoreCSV(PlayerName, ScoreType, ScoreTimes, ScoreAmount, PlayerUnitName, PlayerUnitCoalition, PlayerUnitCategory, PlayerUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType)</a></td>
|
||||
<td class="summary">
|
||||
<p>Registers a score for a player.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(SCORING).ScoreMenu">SCORING:ScoreMenu()</a></td>
|
||||
<td class="summary">
|
||||
<p>Creates a score radio menu.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(SCORING).ScoringCSV">SCORING.ScoringCSV</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(SCORING).SecondsToClock">SCORING:SecondsToClock(sSeconds)</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(SCORING)._AddMissionScore">SCORING:_AddMissionScore(MissionName, Score)</a></td>
|
||||
<td class="summary">
|
||||
<p>Registers Mission Scores for possible multiple players that contributed in the Mission.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(SCORING)._AddMissionTaskScore">SCORING:_AddMissionTaskScore(PlayerUnit, MissionName, Score)</a></td>
|
||||
<td class="summary">
|
||||
<p>Registers Scores the players completing a Mission Task.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(SCORING)._AddPlayerFromUnit">SCORING:_AddPlayerFromUnit(UnitData)</a></td>
|
||||
<td class="summary">
|
||||
<p>Add a new player entering a Unit.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(SCORING)._EventOnDeadOrCrash">SCORING:_EventOnDeadOrCrash(Event)</a></td>
|
||||
<td class="summary">
|
||||
<p>Track DEAD or CRASH events for the scoring.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(SCORING)._EventOnHit">SCORING:_EventOnHit(Event)</a></td>
|
||||
<td class="summary">
|
||||
<p>Handles the OnHit event for the scoring.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(SCORING)._FollowPlayersScheduled">SCORING:_FollowPlayersScheduled()</a></td>
|
||||
<td class="summary">
|
||||
<p>Follows new players entering Clients within the DCSRTE.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2>Global(s)</h2>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em></em>
|
||||
<a id="ClientGroup" >
|
||||
<strong>ClientGroup</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em><a href="##(SCORING)">#SCORING</a></em>
|
||||
<a id="SCORING" >
|
||||
<strong>SCORING</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em></em>
|
||||
<a id="nHours" >
|
||||
<strong>nHours</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em></em>
|
||||
<a id="nMins" >
|
||||
<strong>nMins</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em></em>
|
||||
<a id="nSecs" >
|
||||
<strong>nSecs</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<h2><a id="#(Scoring)" >Type <code>Scoring</code></a></h2>
|
||||
|
||||
<h2><a id="#(SCORING)" >Type <code>SCORING</code></a></h2>
|
||||
|
||||
<p>The Scoring class</p>
|
||||
|
||||
<h3>Field(s)</h3>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em></em>
|
||||
<a id="#(SCORING).AllScoresMenu" >
|
||||
<strong>SCORING.AllScoresMenu</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em>#number</em>
|
||||
<a id="#(SCORING).ClassID" >
|
||||
<strong>SCORING.ClassID</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em>#string</em>
|
||||
<a id="#(SCORING).ClassName" >
|
||||
<strong>SCORING.ClassName</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(SCORING).CloseCSV" >
|
||||
<strong>SCORING:CloseCSV()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em></em>
|
||||
<a id="#(SCORING).Menu" >
|
||||
<strong>SCORING.Menu</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(SCORING).New" >
|
||||
<strong>SCORING:New(GameName)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Creates a new SCORING object to administer the scoring achieved by players.</p>
|
||||
|
||||
<h3>Parameter</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em>#string GameName </em></code>:
|
||||
The name of the game. This name is also logged in the CSV score file.</p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
<h3>Return value</h3>
|
||||
|
||||
<p><em><a href="##(SCORING)">#SCORING</a>:</em>
|
||||
self</p>
|
||||
|
||||
<h3>Usage:</h3>
|
||||
<pre class="example"><code>-- Define a new scoring object for the mission Gori Valley.
|
||||
ScoringObject = SCORING:New( "Gori Valley" )</code></pre>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(SCORING).OpenCSV" >
|
||||
<strong>SCORING:OpenCSV(ScoringCSV)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Opens a score CSV file to log the scores.</p>
|
||||
|
||||
<h3>Parameter</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em>#string ScoringCSV </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
<h3>Return value</h3>
|
||||
|
||||
<p><em><a href="##(SCORING)">#SCORING</a>:</em>
|
||||
self</p>
|
||||
|
||||
<h3>Usage:</h3>
|
||||
<pre class="example"><code>-- Open a new CSV file to log the scores of the game Gori Valley. Let the name of the CSV file begin with "Player Scores".
|
||||
ScoringObject = SCORING:New( "Gori Valley" )
|
||||
ScoringObject:OpenCSV( "Player Scores" )</code></pre>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(SCORING).Players" >
|
||||
<strong>SCORING.Players</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>A collection of the current players that have joined the game.</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(SCORING).ReportScoreAll" >
|
||||
<strong>SCORING:ReportScoreAll()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(SCORING).ReportScorePlayer" >
|
||||
<strong>SCORING:ReportScorePlayer()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em></em>
|
||||
<a id="#(SCORING).RunTime" >
|
||||
<strong>SCORING.RunTime</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(SCORING).ScoreCSV" >
|
||||
<strong>SCORING:ScoreCSV(PlayerName, ScoreType, ScoreTimes, ScoreAmount, PlayerUnitName, PlayerUnitCoalition, PlayerUnitCategory, PlayerUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Registers a score for a player.</p>
|
||||
|
||||
<h3>Parameters</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em>#string PlayerName </em></code>:
|
||||
The name of the player.</p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em>#string ScoreType </em></code>:
|
||||
The type of the score.</p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em>#string ScoreTimes </em></code>:
|
||||
The amount of scores achieved.</p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em>#string ScoreAmount </em></code>:
|
||||
The score given.</p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em>#string PlayerUnitName </em></code>:
|
||||
The unit name of the player.</p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em>#string PlayerUnitCoalition </em></code>:
|
||||
The coalition of the player unit.</p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em>#string PlayerUnitCategory </em></code>:
|
||||
The category of the player unit.</p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em>#string PlayerUnitType </em></code>:
|
||||
The type of the player unit.</p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em>#string TargetUnitName </em></code>:
|
||||
The name of the target unit.</p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em>#string TargetUnitCoalition </em></code>:
|
||||
The coalition of the target unit.</p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em>#string TargetUnitCategory </em></code>:
|
||||
The category of the target unit.</p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em>#string TargetUnitType </em></code>:
|
||||
The type of the target unit.</p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
<h3>Return value</h3>
|
||||
|
||||
<p><em><a href="##(SCORING)">#SCORING</a>:</em>
|
||||
self</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(SCORING).ScoreMenu" >
|
||||
<strong>SCORING:ScoreMenu()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Creates a score radio menu.</p>
|
||||
|
||||
|
||||
<p>Can be accessed using Radio -> F10.</p>
|
||||
|
||||
<h3>Return value</h3>
|
||||
|
||||
<p><em><a href="##(SCORING)">#SCORING</a>:</em>
|
||||
self</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em></em>
|
||||
<a id="#(SCORING).ScoringCSV" >
|
||||
<strong>SCORING.ScoringCSV</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(SCORING).SecondsToClock" >
|
||||
<strong>SCORING:SecondsToClock(sSeconds)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
<h3>Parameter</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em> sSeconds </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(SCORING)._AddMissionScore" >
|
||||
<strong>SCORING:_AddMissionScore(MissionName, Score)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Registers Mission Scores for possible multiple players that contributed in the Mission.</p>
|
||||
|
||||
<h3>Parameters</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em> MissionName </em></code>: </p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> Score </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(SCORING)._AddMissionTaskScore" >
|
||||
<strong>SCORING:_AddMissionTaskScore(PlayerUnit, MissionName, Score)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Registers Scores the players completing a Mission Task.</p>
|
||||
|
||||
<h3>Parameters</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em> PlayerUnit </em></code>: </p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> MissionName </em></code>: </p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> Score </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(SCORING)._AddPlayerFromUnit" >
|
||||
<strong>SCORING:_AddPlayerFromUnit(UnitData)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Add a new player entering a Unit.</p>
|
||||
|
||||
<h3>Parameter</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em> UnitData </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(SCORING)._EventOnDeadOrCrash" >
|
||||
<strong>SCORING:_EventOnDeadOrCrash(Event)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Track DEAD or CRASH events for the scoring.</p>
|
||||
|
||||
<h3>Parameter</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em><a href="Event.html##(EVENTDATA)">Event#EVENTDATA</a> Event </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(SCORING)._EventOnHit" >
|
||||
<strong>SCORING:_EventOnHit(Event)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Handles the OnHit event for the scoring.</p>
|
||||
|
||||
<h3>Parameter</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em><a href="Event.html##(EVENTDATA)">Event#EVENTDATA</a> Event </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(SCORING)._FollowPlayersScheduled" >
|
||||
<strong>SCORING:_FollowPlayersScheduled()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Follows new players entering Clients within the DCSRTE.</p>
|
||||
|
||||
|
||||
<p>TODO: Need to see if i can catch this also with an event. It will eliminate the schedule ...</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,887 +0,0 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" href="stylesheet.css" type="text/css"/>
|
||||
</head>
|
||||
<body>
|
||||
<div id="container">
|
||||
<div id="product">
|
||||
<div id="product_logo"></div>
|
||||
<div id="product_name"><big><b></b></big></div>
|
||||
<div id="product_description"></div>
|
||||
</div>
|
||||
<div id="main">
|
||||
<div id="navigation">
|
||||
<h2>Modules</h2>
|
||||
<ul><li>
|
||||
<a href="index.html">index</a>
|
||||
</li></ul>
|
||||
<ul>
|
||||
<li><a href="Base.html">Base</a></li>
|
||||
<li><a href="CARGO.html">CARGO</a></li>
|
||||
<li><a href="CleanUp.html">CleanUp</a></li>
|
||||
<li><a href="Client.html">Client</a></li>
|
||||
<li><a href="DCSAirbase.html">DCSAirbase</a></li>
|
||||
<li><a href="DCSCoalitionObject.html">DCSCoalitionObject</a></li>
|
||||
<li><a href="DCSCommand.html">DCSCommand</a></li>
|
||||
<li><a href="DCSController.html">DCSController</a></li>
|
||||
<li><a href="DCSGroup.html">DCSGroup</a></li>
|
||||
<li><a href="DCSObject.html">DCSObject</a></li>
|
||||
<li><a href="DCSTask.html">DCSTask</a></li>
|
||||
<li><a href="DCSTypes.html">DCSTypes</a></li>
|
||||
<li><a href="DCSUnit.html">DCSUnit</a></li>
|
||||
<li><a href="DCSWorld.html">DCSWorld</a></li>
|
||||
<li><a href="DCStimer.html">DCStimer</a></li>
|
||||
<li><a href="DEPLOYTASK.html">DEPLOYTASK</a></li>
|
||||
<li><a href="DESTROYBASETASK.html">DESTROYBASETASK</a></li>
|
||||
<li><a href="DESTROYGROUPSTASK.html">DESTROYGROUPSTASK</a></li>
|
||||
<li><a href="DESTROYRADARSTASK.html">DESTROYRADARSTASK</a></li>
|
||||
<li><a href="DESTROYUNITTYPESTASK.html">DESTROYUNITTYPESTASK</a></li>
|
||||
<li><a href="Database.html">Database</a></li>
|
||||
<li><a href="Escort.html">Escort</a></li>
|
||||
<li><a href="Event.html">Event</a></li>
|
||||
<li><a href="GOHOMETASK.html">GOHOMETASK</a></li>
|
||||
<li><a href="Group.html">Group</a></li>
|
||||
<li><a href="MISSION.html">MISSION</a></li>
|
||||
<li><a href="MOVEMENT.html">MOVEMENT</a></li>
|
||||
<li><a href="Menu.html">Menu</a></li>
|
||||
<li><a href="Message.html">Message</a></li>
|
||||
<li><a href="NOTASK.html">NOTASK</a></li>
|
||||
<li><a href="PICKUPTASK.html">PICKUPTASK</a></li>
|
||||
<li><a href="ROUTETASK.html">ROUTETASK</a></li>
|
||||
<li><a href="STAGE.html">STAGE</a></li>
|
||||
<li><a href="Scoring.html">Scoring</a></li>
|
||||
<li><a href="Sead.html">Sead</a></li>
|
||||
<li><a href="Spawn.html">Spawn</a></li>
|
||||
<li><a href="StaticObject.html">StaticObject</a></li>
|
||||
<li><a href="TASK.html">TASK</a></li>
|
||||
<li>Unit</li>
|
||||
<li><a href="Zone.html">Zone</a></li>
|
||||
<li><a href="env.html">env</a></li>
|
||||
<li><a href="land.html">land</a></li>
|
||||
<li><a href="routines.html">routines</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="content">
|
||||
<h1>Module <code>Unit</code></h1>
|
||||
|
||||
<p>UNIT Classes</p>
|
||||
|
||||
<h2>Global(s)</h2>
|
||||
<table class="function_list">
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="#UNIT">UNIT</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<h2><a id="#(UNIT)">Type <code>UNIT</code></a></h2>
|
||||
<table class="function_list">
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(UNIT).CategoryName">UNIT.CategoryName</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(UNIT).ClassName">UNIT.ClassName</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(UNIT).Flare">UNIT:Flare(FlareColor)</a></td>
|
||||
<td class="summary">
|
||||
<p>Signal a flare at the position of the UNIT.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(UNIT).FlareColor">UNIT.FlareColor</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(UNIT).FlareGreen">UNIT:FlareGreen()</a></td>
|
||||
<td class="summary">
|
||||
<p>Signal a green flare at the position of the UNIT.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(UNIT).FlareRed">UNIT:FlareRed()</a></td>
|
||||
<td class="summary">
|
||||
<p>Signal a red flare at the position of the UNIT.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(UNIT).FlareWhite">UNIT:FlareWhite()</a></td>
|
||||
<td class="summary">
|
||||
<p>Signal a white flare at the position of the UNIT.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(UNIT).FlareYellow">UNIT:FlareYellow()</a></td>
|
||||
<td class="summary">
|
||||
<p>Signal a yellow flare at the position of the UNIT.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(UNIT).GetCallSign">UNIT:GetCallSign()</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(UNIT).GetCategoryName">UNIT:GetCategoryName()</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(UNIT).GetDCSUnit">UNIT:GetDCSUnit()</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(UNIT).GetID">UNIT:GetID()</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(UNIT).GetName">UNIT:GetName()</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(UNIT).GetPointVec2">UNIT:GetPointVec2()</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(UNIT).GetPositionVec3">UNIT:GetPositionVec3()</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(UNIT).GetPrefix">UNIT:GetPrefix()</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(UNIT).GetTypeName">UNIT:GetTypeName()</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(UNIT).IsAir">UNIT:IsAir()</a></td>
|
||||
<td class="summary">
|
||||
<p>Returns if the unit is of an air category.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(UNIT).IsAlive">UNIT:IsAlive()</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(UNIT).New">UNIT:New(DCSUnit)</a></td>
|
||||
<td class="summary">
|
||||
<p>Create a new UNIT from DCSUnit.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(UNIT).OtherUnitInRadius">UNIT:OtherUnitInRadius(AwaitUnit, Radius)</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(UNIT).Smoke">UNIT:Smoke(SmokeColor)</a></td>
|
||||
<td class="summary">
|
||||
<p>Smoke the UNIT.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(UNIT).SmokeBlue">UNIT:SmokeBlue()</a></td>
|
||||
<td class="summary">
|
||||
<p>Smoke the UNIT Blue.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(UNIT).SmokeColor">UNIT.SmokeColor</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(UNIT).SmokeGreen">UNIT:SmokeGreen()</a></td>
|
||||
<td class="summary">
|
||||
<p>Smoke the UNIT Green.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(UNIT).SmokeOrange">UNIT:SmokeOrange()</a></td>
|
||||
<td class="summary">
|
||||
<p>Smoke the UNIT Orange.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(UNIT).SmokeRed">UNIT:SmokeRed()</a></td>
|
||||
<td class="summary">
|
||||
<p>Smoke the UNIT Red.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(UNIT).SmokeWhite">UNIT:SmokeWhite()</a></td>
|
||||
<td class="summary">
|
||||
<p>Smoke the UNIT White.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2><a id="#(UNIT.FlareColor)">Type <code>UNIT.FlareColor</code></a></h2>
|
||||
<table class="function_list">
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(UNIT.FlareColor).Green">UNIT.FlareColor.Green</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(UNIT.FlareColor).Red">UNIT.FlareColor.Red</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(UNIT.FlareColor).White">UNIT.FlareColor.White</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(UNIT.FlareColor).Yellow">UNIT.FlareColor.Yellow</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2><a id="#(UNIT.SmokeColor)">Type <code>UNIT.SmokeColor</code></a></h2>
|
||||
<table class="function_list">
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(UNIT.SmokeColor).Blue">UNIT.SmokeColor.Blue</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(UNIT.SmokeColor).Green">UNIT.SmokeColor.Green</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(UNIT.SmokeColor).Orange">UNIT.SmokeColor.Orange</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(UNIT.SmokeColor).Red">UNIT.SmokeColor.Red</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(UNIT.SmokeColor).White">UNIT.SmokeColor.White</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2>Global(s)</h2>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em><a href="##(UNIT)">#UNIT</a></em>
|
||||
<a id="UNIT" >
|
||||
<strong>UNIT</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<h2><a id="#(Unit)" >Type <code>Unit</code></a></h2>
|
||||
|
||||
<h2><a id="#(UNIT)" >Type <code>UNIT</code></a></h2>
|
||||
|
||||
<p>The UNIT class</p>
|
||||
|
||||
<h3>Field(s)</h3>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em></em>
|
||||
<a id="#(UNIT).CategoryName" >
|
||||
<strong>UNIT.CategoryName</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em>#string</em>
|
||||
<a id="#(UNIT).ClassName" >
|
||||
<strong>UNIT.ClassName</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(UNIT).Flare" >
|
||||
<strong>UNIT:Flare(FlareColor)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Signal a flare at the position of the UNIT.</p>
|
||||
|
||||
<h3>Parameter</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em> FlareColor </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em><a href="##(UNIT.FlareColor)">#UNIT.FlareColor</a></em>
|
||||
<a id="#(UNIT).FlareColor" >
|
||||
<strong>UNIT.FlareColor</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(UNIT).FlareGreen" >
|
||||
<strong>UNIT:FlareGreen()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Signal a green flare at the position of the UNIT.</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(UNIT).FlareRed" >
|
||||
<strong>UNIT:FlareRed()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Signal a red flare at the position of the UNIT.</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(UNIT).FlareWhite" >
|
||||
<strong>UNIT:FlareWhite()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Signal a white flare at the position of the UNIT.</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(UNIT).FlareYellow" >
|
||||
<strong>UNIT:FlareYellow()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Signal a yellow flare at the position of the UNIT.</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(UNIT).GetCallSign" >
|
||||
<strong>UNIT:GetCallSign()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(UNIT).GetCategoryName" >
|
||||
<strong>UNIT:GetCategoryName()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(UNIT).GetDCSUnit" >
|
||||
<strong>UNIT:GetDCSUnit()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(UNIT).GetID" >
|
||||
<strong>UNIT:GetID()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(UNIT).GetName" >
|
||||
<strong>UNIT:GetName()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(UNIT).GetPointVec2" >
|
||||
<strong>UNIT:GetPointVec2()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(UNIT).GetPositionVec3" >
|
||||
<strong>UNIT:GetPositionVec3()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(UNIT).GetPrefix" >
|
||||
<strong>UNIT:GetPrefix()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(UNIT).GetTypeName" >
|
||||
<strong>UNIT:GetTypeName()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(UNIT).IsAir" >
|
||||
<strong>UNIT:IsAir()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Returns if the unit is of an air category.</p>
|
||||
|
||||
|
||||
<p>If the unit is a helicopter or a plane, then this method will return true, otherwise false.</p>
|
||||
|
||||
<h3>Return value</h3>
|
||||
|
||||
<p><em>#boolean:</em>
|
||||
Air category evaluation result.</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(UNIT).IsAlive" >
|
||||
<strong>UNIT:IsAlive()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(UNIT).New" >
|
||||
<strong>UNIT:New(DCSUnit)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Create a new UNIT from DCSUnit.</p>
|
||||
|
||||
<h3>Parameter</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em><a href="DCSUnit.html##(Unit)">DCSUnit#Unit</a> DCSUnit </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
<h3>Return value</h3>
|
||||
|
||||
<p><em><a href="Unit.html##(UNIT)">Unit#UNIT</a>:</em></p>
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(UNIT).OtherUnitInRadius" >
|
||||
<strong>UNIT:OtherUnitInRadius(AwaitUnit, Radius)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
<h3>Parameters</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em> AwaitUnit </em></code>: </p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> Radius </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(UNIT).Smoke" >
|
||||
<strong>UNIT:Smoke(SmokeColor)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Smoke the UNIT.</p>
|
||||
|
||||
<h3>Parameter</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em> SmokeColor </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(UNIT).SmokeBlue" >
|
||||
<strong>UNIT:SmokeBlue()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Smoke the UNIT Blue.</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em><a href="##(UNIT.SmokeColor)">#UNIT.SmokeColor</a></em>
|
||||
<a id="#(UNIT).SmokeColor" >
|
||||
<strong>UNIT.SmokeColor</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(UNIT).SmokeGreen" >
|
||||
<strong>UNIT:SmokeGreen()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Smoke the UNIT Green.</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(UNIT).SmokeOrange" >
|
||||
<strong>UNIT:SmokeOrange()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Smoke the UNIT Orange.</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(UNIT).SmokeRed" >
|
||||
<strong>UNIT:SmokeRed()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Smoke the UNIT Red.</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(UNIT).SmokeWhite" >
|
||||
<strong>UNIT:SmokeWhite()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Smoke the UNIT White.</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<h2><a id="#(UNIT.FlareColor)" >Type <code>UNIT.FlareColor</code></a></h2>
|
||||
|
||||
<p>FlareColor</p>
|
||||
|
||||
<h3>Field(s)</h3>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(UNIT.FlareColor).Green" >
|
||||
<strong>UNIT.FlareColor.Green</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(UNIT.FlareColor).Red" >
|
||||
<strong>UNIT.FlareColor.Red</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(UNIT.FlareColor).White" >
|
||||
<strong>UNIT.FlareColor.White</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(UNIT.FlareColor).Yellow" >
|
||||
<strong>UNIT.FlareColor.Yellow</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<h2><a id="#(UNIT.SmokeColor)" >Type <code>UNIT.SmokeColor</code></a></h2>
|
||||
|
||||
<p>SmokeColor</p>
|
||||
|
||||
<h3>Field(s)</h3>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(UNIT.SmokeColor).Blue" >
|
||||
<strong>UNIT.SmokeColor.Blue</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(UNIT.SmokeColor).Green" >
|
||||
<strong>UNIT.SmokeColor.Green</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(UNIT.SmokeColor).Orange" >
|
||||
<strong>UNIT.SmokeColor.Orange</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(UNIT.SmokeColor).Red" >
|
||||
<strong>UNIT.SmokeColor.Red</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(UNIT.SmokeColor).White" >
|
||||
<strong>UNIT.SmokeColor.White</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,214 +0,0 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" href="stylesheet.css" type="text/css"/>
|
||||
</head>
|
||||
<body>
|
||||
<div id="container">
|
||||
<div id="product">
|
||||
<div id="product_logo"></div>
|
||||
<div id="product_name"><big><b></b></big></div>
|
||||
<div id="product_description"></div>
|
||||
</div>
|
||||
<div id="main">
|
||||
<div id="navigation">
|
||||
<h2>Modules</h2>
|
||||
<ul><li>
|
||||
<a href="index.html">index</a>
|
||||
</li></ul>
|
||||
<ul>
|
||||
<li><a href="Base.html">Base</a></li>
|
||||
<li><a href="CARGO.html">CARGO</a></li>
|
||||
<li><a href="CleanUp.html">CleanUp</a></li>
|
||||
<li><a href="Client.html">Client</a></li>
|
||||
<li><a href="DCSAirbase.html">DCSAirbase</a></li>
|
||||
<li><a href="DCSCoalitionObject.html">DCSCoalitionObject</a></li>
|
||||
<li><a href="DCSCommand.html">DCSCommand</a></li>
|
||||
<li><a href="DCSController.html">DCSController</a></li>
|
||||
<li><a href="DCSGroup.html">DCSGroup</a></li>
|
||||
<li><a href="DCSObject.html">DCSObject</a></li>
|
||||
<li><a href="DCSTask.html">DCSTask</a></li>
|
||||
<li><a href="DCSTypes.html">DCSTypes</a></li>
|
||||
<li><a href="DCSUnit.html">DCSUnit</a></li>
|
||||
<li><a href="DCSWorld.html">DCSWorld</a></li>
|
||||
<li><a href="DCStimer.html">DCStimer</a></li>
|
||||
<li><a href="DEPLOYTASK.html">DEPLOYTASK</a></li>
|
||||
<li><a href="DESTROYBASETASK.html">DESTROYBASETASK</a></li>
|
||||
<li><a href="DESTROYGROUPSTASK.html">DESTROYGROUPSTASK</a></li>
|
||||
<li><a href="DESTROYRADARSTASK.html">DESTROYRADARSTASK</a></li>
|
||||
<li><a href="DESTROYUNITTYPESTASK.html">DESTROYUNITTYPESTASK</a></li>
|
||||
<li><a href="Database.html">Database</a></li>
|
||||
<li><a href="Escort.html">Escort</a></li>
|
||||
<li><a href="Event.html">Event</a></li>
|
||||
<li><a href="GOHOMETASK.html">GOHOMETASK</a></li>
|
||||
<li><a href="Group.html">Group</a></li>
|
||||
<li><a href="MISSION.html">MISSION</a></li>
|
||||
<li><a href="MOVEMENT.html">MOVEMENT</a></li>
|
||||
<li><a href="Menu.html">Menu</a></li>
|
||||
<li><a href="Message.html">Message</a></li>
|
||||
<li><a href="NOTASK.html">NOTASK</a></li>
|
||||
<li><a href="PICKUPTASK.html">PICKUPTASK</a></li>
|
||||
<li><a href="ROUTETASK.html">ROUTETASK</a></li>
|
||||
<li><a href="STAGE.html">STAGE</a></li>
|
||||
<li><a href="Scoring.html">Scoring</a></li>
|
||||
<li><a href="Sead.html">Sead</a></li>
|
||||
<li><a href="Spawn.html">Spawn</a></li>
|
||||
<li><a href="StaticObject.html">StaticObject</a></li>
|
||||
<li><a href="TASK.html">TASK</a></li>
|
||||
<li><a href="Unit.html">Unit</a></li>
|
||||
<li>Zone</li>
|
||||
<li><a href="env.html">env</a></li>
|
||||
<li><a href="land.html">land</a></li>
|
||||
<li><a href="routines.html">routines</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="content">
|
||||
<h1>Module <code>Zone</code></h1>
|
||||
|
||||
<p>ZONE Classes</p>
|
||||
|
||||
<h2>Global(s)</h2>
|
||||
<table class="function_list">
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="#ZONE">ZONE</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<h2><a id="#(ZONE)">Type <code>ZONE</code></a></h2>
|
||||
<table class="function_list">
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(ZONE).ClassName">ZONE.ClassName</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(ZONE).GetPointVec2">ZONE:GetPointVec2()</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(ZONE).GetRadius">ZONE:GetRadius()</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(ZONE).GetRandomPointVec2">ZONE:GetRandomPointVec2()</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(ZONE).New">ZONE:New(ZoneName)</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2>Global(s)</h2>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em><a href="##(ZONE)">#ZONE</a></em>
|
||||
<a id="ZONE" >
|
||||
<strong>ZONE</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<h2><a id="#(Zone)" >Type <code>Zone</code></a></h2>
|
||||
|
||||
<h2><a id="#(ZONE)" >Type <code>ZONE</code></a></h2>
|
||||
|
||||
<p>The ZONE class</p>
|
||||
|
||||
<h3>Field(s)</h3>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em>#string</em>
|
||||
<a id="#(ZONE).ClassName" >
|
||||
<strong>ZONE.ClassName</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(ZONE).GetPointVec2" >
|
||||
<strong>ZONE:GetPointVec2()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(ZONE).GetRadius" >
|
||||
<strong>ZONE:GetRadius()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(ZONE).GetRandomPointVec2" >
|
||||
<strong>ZONE:GetRandomPointVec2()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(ZONE).New" >
|
||||
<strong>ZONE:New(ZoneName)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
<h3>Parameter</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em> ZoneName </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,331 +0,0 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" href="stylesheet.css" type="text/css"/>
|
||||
</head>
|
||||
<body>
|
||||
<div id="container">
|
||||
<div id="product">
|
||||
<div id="product_logo"></div>
|
||||
<div id="product_name"><big><b></b></big></div>
|
||||
<div id="product_description"></div>
|
||||
</div>
|
||||
<div id="main">
|
||||
<div id="navigation">
|
||||
<h2>Modules</h2>
|
||||
<ul><li>
|
||||
index
|
||||
</li></ul>
|
||||
<ul>
|
||||
<li><a href="Base.html">Base</a></li>
|
||||
<li><a href="CARGO.html">CARGO</a></li>
|
||||
<li><a href="CleanUp.html">CleanUp</a></li>
|
||||
<li><a href="Client.html">Client</a></li>
|
||||
<li><a href="DCSAirbase.html">DCSAirbase</a></li>
|
||||
<li><a href="DCSCoalitionObject.html">DCSCoalitionObject</a></li>
|
||||
<li><a href="DCSCommand.html">DCSCommand</a></li>
|
||||
<li><a href="DCSController.html">DCSController</a></li>
|
||||
<li><a href="DCSGroup.html">DCSGroup</a></li>
|
||||
<li><a href="DCSObject.html">DCSObject</a></li>
|
||||
<li><a href="DCSTask.html">DCSTask</a></li>
|
||||
<li><a href="DCSTypes.html">DCSTypes</a></li>
|
||||
<li><a href="DCSUnit.html">DCSUnit</a></li>
|
||||
<li><a href="DCSWorld.html">DCSWorld</a></li>
|
||||
<li><a href="DCStimer.html">DCStimer</a></li>
|
||||
<li><a href="DEPLOYTASK.html">DEPLOYTASK</a></li>
|
||||
<li><a href="DESTROYBASETASK.html">DESTROYBASETASK</a></li>
|
||||
<li><a href="DESTROYGROUPSTASK.html">DESTROYGROUPSTASK</a></li>
|
||||
<li><a href="DESTROYRADARSTASK.html">DESTROYRADARSTASK</a></li>
|
||||
<li><a href="DESTROYUNITTYPESTASK.html">DESTROYUNITTYPESTASK</a></li>
|
||||
<li><a href="Database.html">Database</a></li>
|
||||
<li><a href="Escort.html">Escort</a></li>
|
||||
<li><a href="Event.html">Event</a></li>
|
||||
<li><a href="GOHOMETASK.html">GOHOMETASK</a></li>
|
||||
<li><a href="Group.html">Group</a></li>
|
||||
<li><a href="MISSION.html">MISSION</a></li>
|
||||
<li><a href="MOVEMENT.html">MOVEMENT</a></li>
|
||||
<li><a href="Menu.html">Menu</a></li>
|
||||
<li><a href="Message.html">Message</a></li>
|
||||
<li><a href="NOTASK.html">NOTASK</a></li>
|
||||
<li><a href="PICKUPTASK.html">PICKUPTASK</a></li>
|
||||
<li><a href="ROUTETASK.html">ROUTETASK</a></li>
|
||||
<li><a href="STAGE.html">STAGE</a></li>
|
||||
<li><a href="Scoring.html">Scoring</a></li>
|
||||
<li><a href="Sead.html">Sead</a></li>
|
||||
<li><a href="Spawn.html">Spawn</a></li>
|
||||
<li><a href="StaticObject.html">StaticObject</a></li>
|
||||
<li><a href="TASK.html">TASK</a></li>
|
||||
<li><a href="Unit.html">Unit</a></li>
|
||||
<li><a href="Zone.html">Zone</a></li>
|
||||
<li><a href="env.html">env</a></li>
|
||||
<li><a href="land.html">land</a></li>
|
||||
<li><a href="routines.html">routines</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="content">
|
||||
<h2>Module</h2>
|
||||
<table class="module_list">
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="Base.html">Base</a></td>
|
||||
<td class="summary">
|
||||
<p>BASE classes.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="CARGO.html">CARGO</a></td>
|
||||
<td class="summary">
|
||||
<p>CARGO Classes</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="CleanUp.html">CleanUp</a></td>
|
||||
<td class="summary">
|
||||
<p>The CLEANUP class keeps an area clean of crashing or colliding airplanes.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="Client.html">Client</a></td>
|
||||
<td class="summary">
|
||||
<p>The CLIENT models client units in multi player missions.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="DCSAirbase.html">DCSAirbase</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="DCSCoalitionObject.html">DCSCoalitionObject</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="DCSCommand.html">DCSCommand</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="DCSController.html">DCSController</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="DCSGroup.html">DCSGroup</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="DCSObject.html">DCSObject</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="DCSTask.html">DCSTask</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="DCSTypes.html">DCSTypes</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="DCSUnit.html">DCSUnit</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="DCSWorld.html">DCSWorld</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="DCStimer.html">DCStimer</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="DEPLOYTASK.html">DEPLOYTASK</a></td>
|
||||
<td class="summary">
|
||||
<p>A DEPLOYTASK orchestrates the deployment of CARGO within a specific landing zone.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="DESTROYBASETASK.html">DESTROYBASETASK</a></td>
|
||||
<td class="summary">
|
||||
<p>A DESTROYBASETASK will monitor the destruction of Groups and Units.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="DESTROYGROUPSTASK.html">DESTROYGROUPSTASK</a></td>
|
||||
<td class="summary">
|
||||
<p>DESTROYGROUPSTASK</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="DESTROYRADARSTASK.html">DESTROYRADARSTASK</a></td>
|
||||
<td class="summary">
|
||||
<p>Task class to destroy radar installations.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="DESTROYUNITTYPESTASK.html">DESTROYUNITTYPESTASK</a></td>
|
||||
<td class="summary">
|
||||
<p>Set TASK to destroy certain unit types.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="Database.html">Database</a></td>
|
||||
<td class="summary">
|
||||
<p>Manage sets of units and groups.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="Escort.html">Escort</a></td>
|
||||
<td class="summary">
|
||||
<p>Taking the lead of AI escorting your flight.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="Event.html">Event</a></td>
|
||||
<td class="summary">
|
||||
<p>The EVENT class models an efficient event handling process between other classes and its units, weapons.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="GOHOMETASK.html">GOHOMETASK</a></td>
|
||||
<td class="summary">
|
||||
<p>A GOHOMETASK orchestrates the travel back to the home base, which is a specific zone defined within the ME.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="Group.html">Group</a></td>
|
||||
<td class="summary">
|
||||
<p>A GROUP class abstraction of a DCSGroup class.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="MISSION.html">MISSION</a></td>
|
||||
<td class="summary">
|
||||
<p>A MISSION is the main owner of a Mission orchestration within MOOSE .</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="MOVEMENT.html">MOVEMENT</a></td>
|
||||
<td class="summary">
|
||||
<p>Limit the simultaneous movement of Groups within a running Mission.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="Menu.html">Menu</a></td>
|
||||
<td class="summary">
|
||||
<p>Encapsulation of DCS World Menu system in a set of MENU classes.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="Message.html">Message</a></td>
|
||||
<td class="summary">
|
||||
<p>Message System to display Messages for Clients and Coalitions or All.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="NOTASK.html">NOTASK</a></td>
|
||||
<td class="summary">
|
||||
<p>A NOTASK is a dummy activity...</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="PICKUPTASK.html">PICKUPTASK</a></td>
|
||||
<td class="summary">
|
||||
<p>A PICKUPTASK orchestrates the loading of CARGO at a specific landing zone.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="ROUTETASK.html">ROUTETASK</a></td>
|
||||
<td class="summary">
|
||||
<p>A ROUTETASK orchestrates the travel to a specific zone defined within the ME.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="STAGE.html">STAGE</a></td>
|
||||
<td class="summary">
|
||||
<p>Stages within a <a href="TASK.html">TASK</a> within a <a href="MISSION.html">MISSION</a>.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="Scoring.html">Scoring</a></td>
|
||||
<td class="summary">
|
||||
<p>Scoring system for MOOSE.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="Sead.html">Sead</a></td>
|
||||
<td class="summary">
|
||||
<p>Provides defensive behaviour to a set of SAM sites within a running Mission.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="Spawn.html">Spawn</a></td>
|
||||
<td class="summary">
|
||||
<p>Dynamic spawning of groups (and units).</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="StaticObject.html">StaticObject</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="TASK.html">TASK</a></td>
|
||||
<td class="summary">
|
||||
<p>The TASK Classes define major end-to-end activities within a MISSION.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="Unit.html">Unit</a></td>
|
||||
<td class="summary">
|
||||
<p>UNIT Classes</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="Zone.html">Zone</a></td>
|
||||
<td class="summary">
|
||||
<p>ZONE Classes</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="env.html">env</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="land.html">land</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="routines.html">routines</a></td>
|
||||
<td class="summary">
|
||||
<p>Various routines</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,269 +0,0 @@
|
||||
html {
|
||||
color: #000;
|
||||
background: #FFF;
|
||||
}
|
||||
body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,button,textarea,p,blockquote,th,td {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
}
|
||||
fieldset,img {
|
||||
border: 0;
|
||||
}
|
||||
address,caption,cite,code,dfn,em,strong,th,var,optgroup {
|
||||
font-style: inherit;
|
||||
font-weight: inherit;
|
||||
}
|
||||
del,ins {
|
||||
text-decoration: none;
|
||||
}
|
||||
li {
|
||||
list-style: bullet;
|
||||
margin-left: 20px;
|
||||
}
|
||||
caption,th {
|
||||
text-align: left;
|
||||
}
|
||||
h1,h2,h3,h4,h5,h6 {
|
||||
font-size: 100%;
|
||||
font-weight: bold;
|
||||
}
|
||||
q:before,q:after {
|
||||
content: '';
|
||||
}
|
||||
abbr,acronym {
|
||||
border: 0;
|
||||
font-variant: normal;
|
||||
}
|
||||
sup {
|
||||
vertical-align: baseline;
|
||||
}
|
||||
sub {
|
||||
vertical-align: baseline;
|
||||
}
|
||||
legend {
|
||||
color: #000;
|
||||
}
|
||||
input,button,textarea,select,optgroup,option {
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
font-style: inherit;
|
||||
font-weight: inherit;
|
||||
}
|
||||
input,button,textarea,select {*font-size:100%;
|
||||
}
|
||||
/* END RESET */
|
||||
|
||||
body {
|
||||
margin-left: 1em;
|
||||
margin-right: 1em;
|
||||
font-family: arial, helvetica, geneva, sans-serif;
|
||||
background-color: #ffffff; margin: 0px;
|
||||
}
|
||||
|
||||
code, tt { font-family: monospace; }
|
||||
|
||||
body, p, td, th { font-size: .95em; line-height: 1.2em;}
|
||||
|
||||
p, ul { margin: 10px 0 0 10px;}
|
||||
|
||||
strong { font-weight: bold;}
|
||||
|
||||
em { font-style: italic;}
|
||||
|
||||
h1 {
|
||||
font-size: 1.5em;
|
||||
margin: 25px 0 20px 0;
|
||||
}
|
||||
h2, h3, h4 { margin: 15px 0 10px 0; }
|
||||
h2 { font-size: 1.25em; }
|
||||
h3 { font-size: 1.15em; }
|
||||
h4 { font-size: 1.06em; }
|
||||
|
||||
a:link { font-weight: bold; color: #004080; text-decoration: none; }
|
||||
a:visited { font-weight: bold; color: #006699; text-decoration: none; }
|
||||
a:link:hover { text-decoration: underline; }
|
||||
|
||||
hr {
|
||||
color:#cccccc;
|
||||
background: #00007f;
|
||||
height: 1px;
|
||||
}
|
||||
|
||||
blockquote { margin-left: 3em; }
|
||||
|
||||
ul { list-style-type: disc; }
|
||||
|
||||
p.name {
|
||||
font-family: "Andale Mono", monospace;
|
||||
padding-top: 1em;
|
||||
}
|
||||
|
||||
p:first-child {
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
pre.example {
|
||||
background-color: rgb(245, 245, 245);
|
||||
border: 1px solid silver;
|
||||
padding: 10px;
|
||||
margin: 10px 0 10px 0;
|
||||
font-family: "Andale Mono", monospace;
|
||||
font-size: .85em;
|
||||
}
|
||||
|
||||
pre {
|
||||
background-color: rgb(245, 245, 245);
|
||||
border: 1px solid silver;
|
||||
padding: 10px;
|
||||
margin: 10px 0 10px 0;
|
||||
font-family: "Andale Mono", monospace;
|
||||
}
|
||||
|
||||
|
||||
table.index { border: 1px #00007f; }
|
||||
table.index td { text-align: left; vertical-align: top; }
|
||||
|
||||
#container {
|
||||
margin-left: 1em;
|
||||
margin-right: 1em;
|
||||
background-color: #f0f0f0;
|
||||
}
|
||||
|
||||
#product {
|
||||
text-align: center;
|
||||
border-bottom: 1px solid #cccccc;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
#product big {
|
||||
font-size: 2em;
|
||||
}
|
||||
|
||||
#main {
|
||||
background-color: #f0f0f0;
|
||||
border-left: 2px solid #cccccc;
|
||||
}
|
||||
|
||||
#navigation {
|
||||
float: left;
|
||||
width: 18em;
|
||||
vertical-align: top;
|
||||
background-color: #f0f0f0;
|
||||
overflow: scroll;
|
||||
position: fixed;
|
||||
height:100%;
|
||||
}
|
||||
|
||||
#navigation h2 {
|
||||
background-color:#e7e7e7;
|
||||
font-size:1.1em;
|
||||
color:#000000;
|
||||
text-align: left;
|
||||
padding:0.2em;
|
||||
border-top:1px solid #dddddd;
|
||||
border-bottom:1px solid #dddddd;
|
||||
}
|
||||
|
||||
#navigation ul
|
||||
{
|
||||
font-size:1em;
|
||||
list-style-type: none;
|
||||
margin: 1px 1px 10px 1px;
|
||||
}
|
||||
|
||||
#navigation li {
|
||||
text-indent: -1em;
|
||||
display: block;
|
||||
margin: 3px 0px 0px 22px;
|
||||
}
|
||||
|
||||
#navigation li li a {
|
||||
margin: 0px 3px 0px -1em;
|
||||
}
|
||||
|
||||
#content {
|
||||
margin-left: 18em;
|
||||
padding: 1em;
|
||||
border-left: 2px solid #cccccc;
|
||||
border-right: 2px solid #cccccc;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
#about {
|
||||
clear: both;
|
||||
padding: 5px;
|
||||
border-top: 2px solid #cccccc;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
@media print {
|
||||
body {
|
||||
font: 12pt "Times New Roman", "TimeNR", Times, serif;
|
||||
}
|
||||
a { font-weight: bold; color: #004080; text-decoration: underline; }
|
||||
|
||||
#main {
|
||||
background-color: #ffffff;
|
||||
border-left: 0px;
|
||||
}
|
||||
|
||||
#container {
|
||||
margin-left: 2%;
|
||||
margin-right: 2%;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
#content {
|
||||
padding: 1em;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
#navigation {
|
||||
display: none;
|
||||
}
|
||||
pre.example {
|
||||
font-family: "Andale Mono", monospace;
|
||||
font-size: 10pt;
|
||||
page-break-inside: avoid;
|
||||
}
|
||||
}
|
||||
|
||||
table.module_list {
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
border-color: #cccccc;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
table.module_list td {
|
||||
border-width: 1px;
|
||||
padding: 3px;
|
||||
border-style: solid;
|
||||
border-color: #cccccc;
|
||||
}
|
||||
table.module_list td.name { background-color: #f0f0f0; }
|
||||
table.module_list td.summary { width: 100%; }
|
||||
|
||||
|
||||
table.function_list {
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
border-color: #cccccc;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
table.function_list td {
|
||||
border-width: 1px;
|
||||
padding: 3px;
|
||||
border-style: solid;
|
||||
border-color: #cccccc;
|
||||
}
|
||||
table.function_list td.name { background-color: #f0f0f0; }
|
||||
table.function_list td.summary { width: 100%; }
|
||||
|
||||
dl.table dt, dl.function dt {border-top: 1px solid #ccc; padding-top: 1em;}
|
||||
dl.table dd, dl.function dd {padding-bottom: 1em; margin: 10px 0 0 20px;}
|
||||
dl.table h3, dl.function h3 {font-size: .95em;}
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
del Moose_Embedded.lua
|
||||
|
||||
echo env.info( 'Moose Embedded' ) > Moose_Embedded.lua
|
||||
|
||||
copy /b Moose_Embedded.lua + ..\Moose\Routines.lua Moose_Embedded.lua
|
||||
copy /b Moose_Embedded.lua + ..\Moose\Base.lua Moose_Embedded.lua
|
||||
copy /b Moose_Embedded.lua + ..\Moose\Event.lua Moose_Embedded.lua
|
||||
copy /b Moose_Embedded.lua + ..\Moose\Group.lua Moose_Embedded.lua
|
||||
copy /b Moose_Embedded.lua + ..\Moose\Unit.lua Moose_Embedded.lua
|
||||
copy /b Moose_Embedded.lua + ..\Moose\Zone.lua Moose_Embedded.lua
|
||||
copy /b Moose_Embedded.lua + ..\Moose\Database.lua Moose_Embedded.lua
|
||||
copy /b Moose_Embedded.lua + ..\Moose\Moose.lua Moose_Embedded.lua
|
||||
copy /b Moose_Embedded.lua + ..\Moose\Scoring.lua Moose_Embedded.lua
|
||||
copy /b Moose_Embedded.lua + ..\Moose\Cargo.lua Moose_Embedded.lua
|
||||
copy /b Moose_Embedded.lua + ..\Moose\Client.lua Moose_Embedded.lua
|
||||
copy /b Moose_Embedded.lua + ..\Moose\Message.lua Moose_Embedded.lua
|
||||
copy /b Moose_Embedded.lua + ..\Moose\Stage.lua Moose_Embedded.lua
|
||||
copy /b Moose_Embedded.lua + ..\Moose\Task.lua Moose_Embedded.lua
|
||||
copy /b Moose_Embedded.lua + ..\Moose\GoHomeTask.lua Moose_Embedded.lua
|
||||
copy /b Moose_Embedded.lua + ..\Moose\DestroyBaseTask.lua Moose_Embedded.lua
|
||||
copy /b Moose_Embedded.lua + ..\Moose\DestroyGroupsTask.lua Moose_Embedded.lua
|
||||
copy /b Moose_Embedded.lua + ..\Moose\DestroyRadarsTask.lua Moose_Embedded.lua
|
||||
copy /b Moose_Embedded.lua + ..\Moose\DestroyUnitTypesTask.lua Moose_Embedded.lua
|
||||
copy /b Moose_Embedded.lua + ..\Moose\PickupTask.lua Moose_Embedded.lua
|
||||
copy /b Moose_Embedded.lua + ..\Moose\DeployTask.lua Moose_Embedded.lua
|
||||
copy /b Moose_Embedded.lua + ..\Moose\NoTask.lua Moose_Embedded.lua
|
||||
copy /b Moose_Embedded.lua + ..\Moose\RouteTask.lua Moose_Embedded.lua
|
||||
copy /b Moose_Embedded.lua + ..\Moose\Mission.lua Moose_Embedded.lua
|
||||
copy /b Moose_Embedded.lua + ..\Moose\CleanUp.lua Moose_Embedded.lua
|
||||
copy /b Moose_Embedded.lua + ..\Moose\Spawn.lua Moose_Embedded.lua
|
||||
copy /b Moose_Embedded.lua + ..\Moose\Movement.lua Moose_Embedded.lua
|
||||
copy /b Moose_Embedded.lua + ..\Moose\Sead.lua Moose_Embedded.lua
|
||||
copy /b Moose_Embedded.lua + ..\Moose\Escort.lua Moose_Embedded.lua
|
||||
File diff suppressed because it is too large
Load Diff
674
LICENSE
Normal file
674
LICENSE
Normal file
@@ -0,0 +1,674 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
{one line to give the program's name and a brief idea of what it does.}
|
||||
Copyright (C) {year} {name of author}
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
{project} Copyright (C) {year} {fullname}
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
||||
Binary file not shown.
Binary file not shown.
@@ -1,31 +0,0 @@
|
||||
rem Generate Moose_Embedded.lua
|
||||
|
||||
copy Trace.lua ^
|
||||
+ Routines.lua ^
|
||||
+ Base.lua ^
|
||||
+ Menu.lua ^
|
||||
+ Group.lua ^
|
||||
+ Unit.lua ^
|
||||
+ Zone.lua ^
|
||||
+ Database.lua ^
|
||||
+ Cargo.lua ^
|
||||
+ Client.lua ^
|
||||
+ Message.lua ^
|
||||
+ Stage.lua ^
|
||||
+ Task.lua ^
|
||||
+ GoHomeTask.lua ^
|
||||
+ DestroyBaseTask.lua ^
|
||||
+ DestroyGroupsTask.lua ^
|
||||
+ DestroyRadarsTask.lua ^
|
||||
+ DestroyUnitTypesTask.lua ^
|
||||
+ PickupTask.lua ^
|
||||
+ DeployTask.lua ^
|
||||
+ NoTask.lua ^
|
||||
+ RouteTask.lua ^
|
||||
+ Mission.lua ^
|
||||
+ CleanUp.lua ^
|
||||
+ Spawn.lua ^
|
||||
+ Movement.lua ^
|
||||
+ Sead.lua ^
|
||||
Moose_Embedded.lua
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
|
||||
local base = _G
|
||||
env.info("Loading MOOSE " .. base.timer.getAbsTime() )
|
||||
|
||||
Include = {}
|
||||
|
||||
Include.Path = function()
|
||||
local str = debug.getinfo(2, "S").source
|
||||
return str:match("(.*/)"):sub(1,-2):gsub("\\","/")
|
||||
end
|
||||
|
||||
Include.File = function( IncludeFile )
|
||||
if not Include.Files[ IncludeFile ] then
|
||||
Include.Files[IncludeFile] = IncludeFile
|
||||
env.info( "Include:" .. IncludeFile .. " from " .. Include.ProgramPath )
|
||||
local f = assert( base.loadfile( Include.ProgramPath .. IncludeFile .. ".lua" ) )
|
||||
if f == nil then
|
||||
env.info( "Include:" .. IncludeFile .. " from " .. Include.MissionPath )
|
||||
local f = assert( base.loadfile( Include.MissionPath .. IncludeFile .. ".lua" ) )
|
||||
if f == nil then
|
||||
error ("Could not load MOOSE file " .. IncludeFile .. ".lua" )
|
||||
else
|
||||
env.info( "Include:" .. IncludeFile .. " loaded from " .. Include.MissionPath )
|
||||
return f()
|
||||
end
|
||||
else
|
||||
env.info( "Include:" .. IncludeFile .. " loaded from " .. Include.ProgramPath )
|
||||
return f()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Include.ProgramPath = "Scripts/Moose/"
|
||||
Include.MissionPath = Include.Path()
|
||||
|
||||
env.info( "Include.ProgramPath = " .. Include.ProgramPath)
|
||||
env.info( "Include.MissionPath = " .. Include.MissionPath)
|
||||
|
||||
Include.Files = {}
|
||||
|
||||
Include.File( "Moose" )
|
||||
|
||||
env.info("Loaded MOOSE Include Engine")
|
||||
@@ -1,25 +0,0 @@
|
||||
|
||||
local base = _G
|
||||
env.info("Loading MOOSE " .. base.timer.getAbsTime() )
|
||||
|
||||
Include = {}
|
||||
|
||||
Include.Path = function()
|
||||
local str = debug.getinfo(2, "S").source
|
||||
return str:match("(.*/)"):sub(1,-2):gsub("\\","/")
|
||||
end
|
||||
|
||||
Include.File = function( IncludeFile )
|
||||
end
|
||||
|
||||
Include.ProgramPath = "Scripts/Moose/Moose/"
|
||||
Include.MissionPath = Include.Path()
|
||||
|
||||
env.info( "Include.ProgramPath = " .. Include.ProgramPath)
|
||||
env.info( "Include.MissionPath = " .. Include.MissionPath)
|
||||
|
||||
Include.Files = {}
|
||||
|
||||
Include.File( "Moose" )
|
||||
|
||||
env.info("Loaded MOOSE Include Engine")
|
||||
@@ -1,37 +0,0 @@
|
||||
--Initialization script for the Mission lua Environment (SSE)
|
||||
|
||||
dofile('Scripts/ScriptingSystem.lua')
|
||||
|
||||
Include = {}
|
||||
|
||||
Include.LoadPath = 'Scripts/MOOSE'
|
||||
Include.Files = {}
|
||||
|
||||
Include.File = function( IncludeFile )
|
||||
if not Include.Files[ IncludeFile ] then
|
||||
Include.Files[IncludeFile] = IncludeFile
|
||||
dofile( Include.LoadPath .. "/" .. IncludeFile .. ".lua" )
|
||||
env.info( "Include:" .. IncludeFile .. " loaded." )
|
||||
end
|
||||
end
|
||||
|
||||
Include.File( "Database" )
|
||||
--Include.File( "StatHandler" )
|
||||
|
||||
--Sanitize Mission Scripting environment
|
||||
--This makes unavailable some unsecure functions.
|
||||
--Mission downloaded from server to client may contain potentialy harmful lua code that may use these functions.
|
||||
--You can remove the code below and make availble these functions at your own risk.
|
||||
|
||||
local function sanitizeModule(name)
|
||||
_G[name] = nil
|
||||
package.loaded[name] = nil
|
||||
end
|
||||
|
||||
do
|
||||
--sanitizeModule('os')
|
||||
--sanitizeModule('io')
|
||||
sanitizeModule('lfs')
|
||||
require = nil
|
||||
loadlib = nil
|
||||
end
|
||||
BIN
Moose Development/Documentation/FAC_Detection logic.pdf
Normal file
BIN
Moose Development/Documentation/FAC_Detection logic.pdf
Normal file
Binary file not shown.
BIN
Moose Development/Maths/Bearing calculation.ggb
Normal file
BIN
Moose Development/Maths/Bearing calculation.ggb
Normal file
Binary file not shown.
BIN
Moose Development/Maths/Scoring.xlsx
Normal file
BIN
Moose Development/Maths/Scoring.xlsx
Normal file
Binary file not shown.
306
Moose Development/Moose/AI/AI_Balancer.lua
Normal file
306
Moose Development/Moose/AI/AI_Balancer.lua
Normal file
@@ -0,0 +1,306 @@
|
||||
--- Single-Player:**No** / Multi-Player:**Yes** / AI:**Yes** / Human:**No** / Types:**All** -- **AI Balancing will replace in multi player missions
|
||||
-- non-occupied human slots with AI groups, in order to provide an engaging simulation environment,
|
||||
-- even when there are hardly any players in the mission.**
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- # 1) @{AI_Balancer#AI_BALANCER} class, extends @{Fsm#FSM_SET}
|
||||
--
|
||||
-- The @{AI_Balancer#AI_BALANCER} class monitors and manages as many replacement AI groups as there are
|
||||
-- CLIENTS in a SET_CLIENT collection, which are not occupied by human players.
|
||||
-- In other words, use AI_BALANCER to simulate human behaviour by spawning in replacement AI in multi player missions.
|
||||
--
|
||||
-- The parent class @{Fsm#FSM_SET} manages the functionality to control the Finite State Machine (FSM).
|
||||
-- The mission designer can tailor the behaviour of the AI_BALANCER, by defining event and state transition methods.
|
||||
-- An explanation about state and event transition methods can be found in the @{FSM} module documentation.
|
||||
--
|
||||
-- The mission designer can tailor the AI_BALANCER behaviour, by implementing a state or event handling method for the following:
|
||||
--
|
||||
-- * **@{#AI_BALANCER.OnAfterSpawned}**( AISet, From, Event, To, AIGroup ): Define to add extra logic when an AI is spawned.
|
||||
--
|
||||
-- ## 1.1) AI_BALANCER construction
|
||||
--
|
||||
-- Create a new AI_BALANCER object with the @{#AI_BALANCER.New}() method:
|
||||
--
|
||||
-- ## 1.2) AI_BALANCER is a FSM
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- ### 1.2.1) AI_BALANCER States
|
||||
--
|
||||
-- * **Monitoring** ( Set ): Monitoring the Set if all AI is spawned for the Clients.
|
||||
-- * **Spawning** ( Set, ClientName ): There is a new AI group spawned with ClientName as the name of reference.
|
||||
-- * **Spawned** ( Set, AIGroup ): A new AI has been spawned. You can handle this event to customize the AI behaviour with other AI FSMs or own processes.
|
||||
-- * **Destroying** ( Set, AIGroup ): The AI is being destroyed.
|
||||
-- * **Returning** ( Set, AIGroup ): The AI is returning to the airbase specified by the ReturnToAirbase methods. Handle this state to customize the return behaviour of the AI, if any.
|
||||
--
|
||||
-- ### 1.2.2) AI_BALANCER Events
|
||||
--
|
||||
-- * **Monitor** ( Set ): Every 10 seconds, the Monitor event is triggered to monitor the Set.
|
||||
-- * **Spawn** ( Set, ClientName ): Triggers when there is a new AI group to be spawned with ClientName as the name of reference.
|
||||
-- * **Spawned** ( Set, AIGroup ): Triggers when a new AI has been spawned. You can handle this event to customize the AI behaviour with other AI FSMs or own processes.
|
||||
-- * **Destroy** ( Set, AIGroup ): The AI is being destroyed.
|
||||
-- * **Return** ( Set, AIGroup ): The AI is returning to the airbase specified by the ReturnToAirbase methods.
|
||||
--
|
||||
-- ## 1.3) AI_BALANCER spawn interval for replacement AI
|
||||
--
|
||||
-- Use the method @{#AI_BALANCER.InitSpawnInterval}() to set the earliest and latest interval in seconds that is waited until a new replacement AI is spawned.
|
||||
--
|
||||
-- ## 1.4) AI_BALANCER returns AI to Airbases
|
||||
--
|
||||
-- By default, When a human player joins a slot that is AI_BALANCED, the AI group will be destroyed by default.
|
||||
-- However, there are 2 additional options that you can use to customize the destroy behaviour.
|
||||
-- When a human player joins a slot, you can configure to let the AI return to:
|
||||
--
|
||||
-- * @{#AI_BALANCER.ReturnToHomeAirbase}: Returns the AI to the **home** @{Airbase#AIRBASE}.
|
||||
-- * @{#AI_BALANCER.ReturnToNearestAirbases}: Returns the AI to the **nearest friendly** @{Airbase#AIRBASE}.
|
||||
--
|
||||
-- Note that when AI returns to an airbase, the AI_BALANCER will trigger the **Return** event and the AI will return,
|
||||
-- otherwise the AI_BALANCER will trigger a **Destroy** event, and the AI will be destroyed.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- # **API CHANGE HISTORY**
|
||||
--
|
||||
-- The underlying change log documents the API changes. Please read this carefully. The following notation is used:
|
||||
--
|
||||
-- * **Added** parts are expressed in bold type face.
|
||||
-- * _Removed_ parts are expressed in italic type face.
|
||||
--
|
||||
-- Hereby the change log:
|
||||
--
|
||||
-- 2017-01-17: There is still a problem with AI being destroyed, but not respawned. Need to check further upon that.
|
||||
--
|
||||
-- 2017-01-08: AI_BALANCER:**InitSpawnInterval( Earliest, Latest )** added.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- # **AUTHORS and CONTRIBUTIONS**
|
||||
--
|
||||
-- ### Contributions:
|
||||
--
|
||||
-- * **[Dutch_Baron](https://forums.eagle.ru/member.php?u=112075)**: Working together with James has resulted in the creation of the AI_BALANCER class. James has shared his ideas on balancing AI with air units, and together we made a first design which you can use now :-)
|
||||
-- * **SNAFU**: Had a couple of mails with the guys to validate, if the same concept in the GCI/CAP script could be reworked within MOOSE. None of the script code has been used however within the new AI_BALANCER moose class.
|
||||
--
|
||||
-- ### Authors:
|
||||
--
|
||||
-- * FlightControl: Framework Design & Programming and Documentation.
|
||||
--
|
||||
-- @module AI_Balancer
|
||||
|
||||
--- AI_BALANCER class
|
||||
-- @type AI_BALANCER
|
||||
-- @field Core.Set#SET_CLIENT SetClient
|
||||
-- @field Functional.Spawn#SPAWN SpawnAI
|
||||
-- @field Wrapper.Group#GROUP Test
|
||||
-- @extends Core.Fsm#FSM_SET
|
||||
AI_BALANCER = {
|
||||
ClassName = "AI_BALANCER",
|
||||
PatrolZones = {},
|
||||
AIGroups = {},
|
||||
Earliest = 5, -- Earliest a new AI can be spawned is in 5 seconds.
|
||||
Latest = 60, -- Latest a new AI can be spawned is in 60 seconds.
|
||||
}
|
||||
|
||||
|
||||
|
||||
--- Creates a new AI_BALANCER object
|
||||
-- @param #AI_BALANCER self
|
||||
-- @param Core.Set#SET_CLIENT SetClient A SET\_CLIENT object that will contain the CLIENT objects to be monitored if they are alive or not (joined by a player).
|
||||
-- @param Functional.Spawn#SPAWN SpawnAI The default Spawn object to spawn new AI Groups when needed.
|
||||
-- @return #AI_BALANCER
|
||||
function AI_BALANCER:New( SetClient, SpawnAI )
|
||||
|
||||
-- Inherits from BASE
|
||||
local self = BASE:Inherit( self, FSM_SET:New( SET_GROUP:New() ) ) -- AI.AI_Balancer#AI_BALANCER
|
||||
|
||||
-- TODO: Define the OnAfterSpawned event
|
||||
self:SetStartState( "None" )
|
||||
self:AddTransition( "*", "Monitor", "Monitoring" )
|
||||
self:AddTransition( "*", "Spawn", "Spawning" )
|
||||
self:AddTransition( "Spawning", "Spawned", "Spawned" )
|
||||
self:AddTransition( "*", "Destroy", "Destroying" )
|
||||
self:AddTransition( "*", "Return", "Returning" )
|
||||
|
||||
self.SetClient = SetClient
|
||||
self.SetClient:FilterOnce()
|
||||
self.SpawnAI = SpawnAI
|
||||
|
||||
self.SpawnQueue = {}
|
||||
|
||||
self.ToNearestAirbase = false
|
||||
self.ToHomeAirbase = false
|
||||
|
||||
self:__Monitor( 1 )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Sets the earliest to the latest interval in seconds how long AI_BALANCER will wait to spawn a new AI.
|
||||
-- Provide 2 identical seconds if the interval should be a fixed amount of seconds.
|
||||
-- @param #AI_BALANCER self
|
||||
-- @param #number Earliest The earliest a new AI can be spawned in seconds.
|
||||
-- @param #number Latest The latest a new AI can be spawned in seconds.
|
||||
-- @return self
|
||||
function AI_BALANCER:InitSpawnInterval( Earliest, Latest )
|
||||
|
||||
self.Earliest = Earliest
|
||||
self.Latest = Latest
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Returns the AI to the nearest friendly @{Airbase#AIRBASE}.
|
||||
-- @param #AI_BALANCER self
|
||||
-- @param Dcs.DCSTypes#Distance ReturnTresholdRange If there is an enemy @{Client#CLIENT} within the ReturnTresholdRange given in meters, the AI will not return to the nearest @{Airbase#AIRBASE}.
|
||||
-- @param Core.Set#SET_AIRBASE ReturnAirbaseSet The SET of @{Set#SET_AIRBASE}s to evaluate where to return to.
|
||||
function AI_BALANCER:ReturnToNearestAirbases( ReturnTresholdRange, ReturnAirbaseSet )
|
||||
|
||||
self.ToNearestAirbase = true
|
||||
self.ReturnTresholdRange = ReturnTresholdRange
|
||||
self.ReturnAirbaseSet = ReturnAirbaseSet
|
||||
end
|
||||
|
||||
--- Returns the AI to the home @{Airbase#AIRBASE}.
|
||||
-- @param #AI_BALANCER self
|
||||
-- @param Dcs.DCSTypes#Distance ReturnTresholdRange If there is an enemy @{Client#CLIENT} within the ReturnTresholdRange given in meters, the AI will not return to the nearest @{Airbase#AIRBASE}.
|
||||
function AI_BALANCER:ReturnToHomeAirbase( ReturnTresholdRange )
|
||||
|
||||
self.ToHomeAirbase = true
|
||||
self.ReturnTresholdRange = ReturnTresholdRange
|
||||
end
|
||||
|
||||
--- @param #AI_BALANCER self
|
||||
-- @param Core.Set#SET_GROUP SetGroup
|
||||
-- @param #string ClientName
|
||||
-- @param Wrapper.Group#GROUP AIGroup
|
||||
function AI_BALANCER:onenterSpawning( SetGroup, From, Event, To, ClientName )
|
||||
|
||||
-- OK, Spawn a new group from the default SpawnAI object provided.
|
||||
local AIGroup = self.SpawnAI:Spawn() -- Wrapper.Group#GROUP
|
||||
if AIGroup then
|
||||
AIGroup:E( "Spawning new AIGroup" )
|
||||
--TODO: need to rework UnitName thing ...
|
||||
|
||||
SetGroup:Add( ClientName, AIGroup )
|
||||
self.SpawnQueue[ClientName] = nil
|
||||
|
||||
-- Fire the Spawned event. The first parameter is the AIGroup just Spawned.
|
||||
-- Mission designers can catch this event to bind further actions to the AIGroup.
|
||||
self:Spawned( AIGroup )
|
||||
end
|
||||
end
|
||||
|
||||
--- @param #AI_BALANCER self
|
||||
-- @param Core.Set#SET_GROUP SetGroup
|
||||
-- @param Wrapper.Group#GROUP AIGroup
|
||||
function AI_BALANCER:onenterDestroying( SetGroup, From, Event, To, ClientName, AIGroup )
|
||||
|
||||
AIGroup:Destroy()
|
||||
SetGroup:Flush()
|
||||
SetGroup:Remove( ClientName )
|
||||
SetGroup:Flush()
|
||||
end
|
||||
|
||||
--- @param #AI_BALANCER self
|
||||
-- @param Core.Set#SET_GROUP SetGroup
|
||||
-- @param Wrapper.Group#GROUP AIGroup
|
||||
function AI_BALANCER:onenterReturning( SetGroup, From, Event, To, AIGroup )
|
||||
|
||||
local AIGroupTemplate = AIGroup:GetTemplate()
|
||||
if self.ToHomeAirbase == true then
|
||||
local WayPointCount = #AIGroupTemplate.route.points
|
||||
local SwitchWayPointCommand = AIGroup:CommandSwitchWayPoint( 1, WayPointCount, 1 )
|
||||
AIGroup:SetCommand( SwitchWayPointCommand )
|
||||
AIGroup:MessageToRed( "Returning to home base ...", 30 )
|
||||
else
|
||||
-- Okay, we need to send this Group back to the nearest base of the Coalition of the AI.
|
||||
--TODO: i need to rework the POINT_VEC2 thing.
|
||||
local PointVec2 = POINT_VEC2:New( AIGroup:GetVec2().x, AIGroup:GetVec2().y )
|
||||
local ClosestAirbase = self.ReturnAirbaseSet:FindNearestAirbaseFromPointVec2( PointVec2 )
|
||||
self:T( ClosestAirbase.AirbaseName )
|
||||
AIGroup:MessageToRed( "Returning to " .. ClosestAirbase:GetName().. " ...", 30 )
|
||||
local RTBRoute = AIGroup:RouteReturnToAirbase( ClosestAirbase )
|
||||
AIGroupTemplate.route = RTBRoute
|
||||
AIGroup:Respawn( AIGroupTemplate )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
--- @param #AI_BALANCER self
|
||||
function AI_BALANCER:onenterMonitoring( SetGroup )
|
||||
|
||||
self:T2( { self.SetClient:Count() } )
|
||||
--self.SetClient:Flush()
|
||||
|
||||
self.SetClient:ForEachClient(
|
||||
--- @param Wrapper.Client#CLIENT Client
|
||||
function( Client )
|
||||
self:T3(Client.ClientName)
|
||||
|
||||
local AIGroup = self.Set:Get( Client.UnitName ) -- Wrapper.Group#GROUP
|
||||
if Client:IsAlive() then
|
||||
|
||||
if AIGroup and AIGroup:IsAlive() == true then
|
||||
|
||||
if self.ToNearestAirbase == false and self.ToHomeAirbase == false then
|
||||
self:Destroy( Client.UnitName, AIGroup )
|
||||
else
|
||||
-- We test if there is no other CLIENT within the self.ReturnTresholdRange of the first unit of the AI group.
|
||||
-- If there is a CLIENT, the AI stays engaged and will not return.
|
||||
-- If there is no CLIENT within the self.ReturnTresholdRange, then the unit will return to the Airbase return method selected.
|
||||
|
||||
local PlayerInRange = { Value = false }
|
||||
local RangeZone = ZONE_RADIUS:New( 'RangeZone', AIGroup:GetVec2(), self.ReturnTresholdRange )
|
||||
|
||||
self:T2( RangeZone )
|
||||
|
||||
_DATABASE:ForEachPlayer(
|
||||
--- @param Wrapper.Unit#UNIT RangeTestUnit
|
||||
function( RangeTestUnit, RangeZone, AIGroup, PlayerInRange )
|
||||
self:T2( { PlayerInRange, RangeTestUnit.UnitName, RangeZone.ZoneName } )
|
||||
if RangeTestUnit:IsInZone( RangeZone ) == true then
|
||||
self:T2( "in zone" )
|
||||
if RangeTestUnit:GetCoalition() ~= AIGroup:GetCoalition() then
|
||||
self:T2( "in range" )
|
||||
PlayerInRange.Value = true
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
--- @param Core.Zone#ZONE_RADIUS RangeZone
|
||||
-- @param Wrapper.Group#GROUP AIGroup
|
||||
function( RangeZone, AIGroup, PlayerInRange )
|
||||
if PlayerInRange.Value == false then
|
||||
self:Return( AIGroup )
|
||||
end
|
||||
end
|
||||
, RangeZone, AIGroup, PlayerInRange
|
||||
)
|
||||
|
||||
end
|
||||
self.Set:Remove( Client.UnitName )
|
||||
end
|
||||
else
|
||||
if not AIGroup or not AIGroup:IsAlive() == true then
|
||||
self:T( "Client " .. Client.UnitName .. " not alive." )
|
||||
if not self.SpawnQueue[Client.UnitName] then
|
||||
-- Spawn a new AI taking into account the spawn interval Earliest, Latest
|
||||
self:__Spawn( math.random( self.Earliest, self.Latest ), Client.UnitName )
|
||||
self.SpawnQueue[Client.UnitName] = true
|
||||
self:E( "New AI Spawned for Client " .. Client.UnitName )
|
||||
end
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
)
|
||||
|
||||
self:__Monitor( 10 )
|
||||
end
|
||||
|
||||
|
||||
|
||||
528
Moose Development/Moose/AI/AI_CAP.lua
Normal file
528
Moose Development/Moose/AI/AI_CAP.lua
Normal file
@@ -0,0 +1,528 @@
|
||||
--- Single-Player:**Yes** / Multi-Player:**Yes** / AI:**Yes** / Human:**No** / Types:**Air** -- **Execute Combat Air Patrol (CAP).**
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- # 1) @{#AI_CAP_ZONE} class, extends @{AI_CAP#AI_PATROL_ZONE}
|
||||
--
|
||||
-- The @{#AI_CAP_ZONE} class implements the core functions to patrol a @{Zone} by an AI @{Controllable} or @{Group}
|
||||
-- and automatically engage any airborne enemies that are within a certain range or within a certain zone.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- The AI_CAP_ZONE is assigned a @{Group} and this must be done before the AI_CAP_ZONE process can be started using the **Start** event.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- The AI will fly towards the random 3D point within the patrol zone, using a random speed within the given altitude and speed limits.
|
||||
-- Upon arrival at the 3D point, a new random 3D point will be selected within the patrol zone using the given limits.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- This cycle will continue.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- During the patrol, the AI will detect enemy targets, which are reported through the **Detected** event.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- When enemies are detected, the AI will automatically engage the enemy.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- Until a fuel or damage treshold has been reached by the AI, or when the AI is commanded to RTB.
|
||||
-- When the fuel treshold has been reached, the airplane will fly towards the nearest friendly airbase and will land.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- ## 1.1) AI_CAP_ZONE constructor
|
||||
--
|
||||
-- * @{#AI_CAP_ZONE.New}(): Creates a new AI_CAP_ZONE object.
|
||||
--
|
||||
-- ## 1.2) AI_CAP_ZONE is a FSM
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- ### 1.2.1) AI_CAP_ZONE States
|
||||
--
|
||||
-- * **None** ( Group ): The process is not started yet.
|
||||
-- * **Patrolling** ( Group ): The AI is patrolling the Patrol Zone.
|
||||
-- * **Engaging** ( Group ): The AI is engaging the bogeys.
|
||||
-- * **Returning** ( Group ): The AI is returning to Base..
|
||||
--
|
||||
-- ### 1.2.2) AI_CAP_ZONE Events
|
||||
--
|
||||
-- * **Start** ( Group ): Start the process.
|
||||
-- * **Route** ( Group ): Route the AI to a new random 3D point within the Patrol Zone.
|
||||
-- * **Engage** ( Group ): Let the AI engage the bogeys.
|
||||
-- * **RTB** ( Group ): Route the AI to the home base.
|
||||
-- * **Detect** ( Group ): The AI is detecting targets.
|
||||
-- * **Detected** ( Group ): The AI has detected new targets.
|
||||
-- * **Status** ( Group ): The AI is checking status (fuel and damage). When the tresholds have been reached, the AI will RTB.
|
||||
--
|
||||
-- ## 1.3) Set the Range of Engagement
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- An optional range can be set in meters,
|
||||
-- that will define when the AI will engage with the detected airborne enemy targets.
|
||||
-- The range can be beyond or smaller than the range of the Patrol Zone.
|
||||
-- The range is applied at the position of the AI.
|
||||
-- Use the method @{AI_CAP#AI_CAP_ZONE.SetEngageRange}() to define that range.
|
||||
--
|
||||
-- ## 1.4) Set the Zone of Engagement
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- An optional @{Zone} can be set,
|
||||
-- that will define when the AI will engage with the detected airborne enemy targets.
|
||||
-- Use the method @{AI_Cap#AI_CAP_ZONE.SetEngageZone}() to define that Zone.
|
||||
--
|
||||
-- ====
|
||||
--
|
||||
-- # **API CHANGE HISTORY**
|
||||
--
|
||||
-- The underlying change log documents the API changes. Please read this carefully. The following notation is used:
|
||||
--
|
||||
-- * **Added** parts are expressed in bold type face.
|
||||
-- * _Removed_ parts are expressed in italic type face.
|
||||
--
|
||||
-- Hereby the change log:
|
||||
--
|
||||
-- 2017-01-15: Initial class and API.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- # **AUTHORS and CONTRIBUTIONS**
|
||||
--
|
||||
-- ### Contributions:
|
||||
--
|
||||
-- * **[Quax](https://forums.eagle.ru/member.php?u=90530)**: Concept, Advice & Testing.
|
||||
-- * **[Pikey](https://forums.eagle.ru/member.php?u=62835)**: Concept, Advice & Testing.
|
||||
-- * **[Gunterlund](http://forums.eagle.ru:8080/member.php?u=75036)**: Test case revision.
|
||||
-- * **[Whisper](http://forums.eagle.ru/member.php?u=3829): Testing.
|
||||
-- * **[Delta99](https://forums.eagle.ru/member.php?u=125166): Testing.
|
||||
--
|
||||
-- ### Authors:
|
||||
--
|
||||
-- * **FlightControl**: Concept, Design & Programming.
|
||||
--
|
||||
-- @module AI_Cap
|
||||
|
||||
|
||||
--- AI_CAP_ZONE class
|
||||
-- @type AI_CAP_ZONE
|
||||
-- @field Wrapper.Controllable#CONTROLLABLE AIControllable The @{Controllable} patrolling.
|
||||
-- @field Core.Zone#ZONE_BASE TargetZone The @{Zone} where the patrol needs to be executed.
|
||||
-- @extends AI.AI_Patrol#AI_PATROL_ZONE
|
||||
AI_CAP_ZONE = {
|
||||
ClassName = "AI_CAP_ZONE",
|
||||
}
|
||||
|
||||
|
||||
|
||||
--- Creates a new AI_CAP_ZONE object
|
||||
-- @param #AI_CAP_ZONE self
|
||||
-- @param Core.Zone#ZONE_BASE PatrolZone The @{Zone} where the patrol needs to be executed.
|
||||
-- @param Dcs.DCSTypes#Altitude PatrolFloorAltitude The lowest altitude in meters where to execute the patrol.
|
||||
-- @param Dcs.DCSTypes#Altitude PatrolCeilingAltitude The highest altitude in meters where to execute the patrol.
|
||||
-- @param Dcs.DCSTypes#Speed PatrolMinSpeed The minimum speed of the @{Controllable} in km/h.
|
||||
-- @param Dcs.DCSTypes#Speed PatrolMaxSpeed The maximum speed of the @{Controllable} in km/h.
|
||||
-- @param Dcs.DCSTypes#AltitudeType PatrolAltType The altitude type ("RADIO"=="AGL", "BARO"=="ASL"). Defaults to RADIO
|
||||
-- @return #AI_CAP_ZONE self
|
||||
function AI_CAP_ZONE:New( PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed, PatrolAltType )
|
||||
|
||||
-- Inherits from BASE
|
||||
local self = BASE:Inherit( self, AI_PATROL_ZONE:New( PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed, PatrolAltType ) ) -- #AI_CAP_ZONE
|
||||
|
||||
self.Accomplished = false
|
||||
self.Engaging = false
|
||||
|
||||
self:AddTransition( { "Patrolling", "Engaging" }, "Engage", "Engaging" ) -- FSM_CONTROLLABLE Transition for type #AI_CAP_ZONE.
|
||||
|
||||
--- OnBefore Transition Handler for Event Engage.
|
||||
-- @function [parent=#AI_CAP_ZONE] OnBeforeEngage
|
||||
-- @param #AI_CAP_ZONE self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
||||
-- @param #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
-- @return #boolean Return false to cancel Transition.
|
||||
|
||||
--- OnAfter Transition Handler for Event Engage.
|
||||
-- @function [parent=#AI_CAP_ZONE] OnAfterEngage
|
||||
-- @param #AI_CAP_ZONE self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
||||
-- @param #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
|
||||
--- Synchronous Event Trigger for Event Engage.
|
||||
-- @function [parent=#AI_CAP_ZONE] Engage
|
||||
-- @param #AI_CAP_ZONE self
|
||||
|
||||
--- Asynchronous Event Trigger for Event Engage.
|
||||
-- @function [parent=#AI_CAP_ZONE] __Engage
|
||||
-- @param #AI_CAP_ZONE self
|
||||
-- @param #number Delay The delay in seconds.
|
||||
|
||||
--- OnLeave Transition Handler for State Engaging.
|
||||
-- @function [parent=#AI_CAP_ZONE] OnLeaveEngaging
|
||||
-- @param #AI_CAP_ZONE self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
||||
-- @param #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
-- @return #boolean Return false to cancel Transition.
|
||||
|
||||
--- OnEnter Transition Handler for State Engaging.
|
||||
-- @function [parent=#AI_CAP_ZONE] OnEnterEngaging
|
||||
-- @param #AI_CAP_ZONE self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
||||
-- @param #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
|
||||
self:AddTransition( "Engaging", "Fired", "Engaging" ) -- FSM_CONTROLLABLE Transition for type #AI_CAP_ZONE.
|
||||
|
||||
--- OnBefore Transition Handler for Event Fired.
|
||||
-- @function [parent=#AI_CAP_ZONE] OnBeforeFired
|
||||
-- @param #AI_CAP_ZONE self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
||||
-- @param #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
-- @return #boolean Return false to cancel Transition.
|
||||
|
||||
--- OnAfter Transition Handler for Event Fired.
|
||||
-- @function [parent=#AI_CAP_ZONE] OnAfterFired
|
||||
-- @param #AI_CAP_ZONE self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
||||
-- @param #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
|
||||
--- Synchronous Event Trigger for Event Fired.
|
||||
-- @function [parent=#AI_CAP_ZONE] Fired
|
||||
-- @param #AI_CAP_ZONE self
|
||||
|
||||
--- Asynchronous Event Trigger for Event Fired.
|
||||
-- @function [parent=#AI_CAP_ZONE] __Fired
|
||||
-- @param #AI_CAP_ZONE self
|
||||
-- @param #number Delay The delay in seconds.
|
||||
|
||||
self:AddTransition( "*", "Destroy", "*" ) -- FSM_CONTROLLABLE Transition for type #AI_CAP_ZONE.
|
||||
|
||||
--- OnBefore Transition Handler for Event Destroy.
|
||||
-- @function [parent=#AI_CAP_ZONE] OnBeforeDestroy
|
||||
-- @param #AI_CAP_ZONE self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
||||
-- @param #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
-- @return #boolean Return false to cancel Transition.
|
||||
|
||||
--- OnAfter Transition Handler for Event Destroy.
|
||||
-- @function [parent=#AI_CAP_ZONE] OnAfterDestroy
|
||||
-- @param #AI_CAP_ZONE self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
||||
-- @param #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
|
||||
--- Synchronous Event Trigger for Event Destroy.
|
||||
-- @function [parent=#AI_CAP_ZONE] Destroy
|
||||
-- @param #AI_CAP_ZONE self
|
||||
|
||||
--- Asynchronous Event Trigger for Event Destroy.
|
||||
-- @function [parent=#AI_CAP_ZONE] __Destroy
|
||||
-- @param #AI_CAP_ZONE self
|
||||
-- @param #number Delay The delay in seconds.
|
||||
|
||||
|
||||
self:AddTransition( "Engaging", "Abort", "Patrolling" ) -- FSM_CONTROLLABLE Transition for type #AI_CAP_ZONE.
|
||||
|
||||
--- OnBefore Transition Handler for Event Abort.
|
||||
-- @function [parent=#AI_CAP_ZONE] OnBeforeAbort
|
||||
-- @param #AI_CAP_ZONE self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
||||
-- @param #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
-- @return #boolean Return false to cancel Transition.
|
||||
|
||||
--- OnAfter Transition Handler for Event Abort.
|
||||
-- @function [parent=#AI_CAP_ZONE] OnAfterAbort
|
||||
-- @param #AI_CAP_ZONE self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
||||
-- @param #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
|
||||
--- Synchronous Event Trigger for Event Abort.
|
||||
-- @function [parent=#AI_CAP_ZONE] Abort
|
||||
-- @param #AI_CAP_ZONE self
|
||||
|
||||
--- Asynchronous Event Trigger for Event Abort.
|
||||
-- @function [parent=#AI_CAP_ZONE] __Abort
|
||||
-- @param #AI_CAP_ZONE self
|
||||
-- @param #number Delay The delay in seconds.
|
||||
|
||||
self:AddTransition( "Engaging", "Accomplish", "Patrolling" ) -- FSM_CONTROLLABLE Transition for type #AI_CAP_ZONE.
|
||||
|
||||
--- OnBefore Transition Handler for Event Accomplish.
|
||||
-- @function [parent=#AI_CAP_ZONE] OnBeforeAccomplish
|
||||
-- @param #AI_CAP_ZONE self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
||||
-- @param #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
-- @return #boolean Return false to cancel Transition.
|
||||
|
||||
--- OnAfter Transition Handler for Event Accomplish.
|
||||
-- @function [parent=#AI_CAP_ZONE] OnAfterAccomplish
|
||||
-- @param #AI_CAP_ZONE self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
||||
-- @param #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
|
||||
--- Synchronous Event Trigger for Event Accomplish.
|
||||
-- @function [parent=#AI_CAP_ZONE] Accomplish
|
||||
-- @param #AI_CAP_ZONE self
|
||||
|
||||
--- Asynchronous Event Trigger for Event Accomplish.
|
||||
-- @function [parent=#AI_CAP_ZONE] __Accomplish
|
||||
-- @param #AI_CAP_ZONE self
|
||||
-- @param #number Delay The delay in seconds.
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
--- Set the Engage Zone which defines where the AI will engage bogies.
|
||||
-- @param #AI_CAP_ZONE self
|
||||
-- @param Core.Zone#ZONE EngageZone The zone where the AI is performing CAP.
|
||||
-- @return #AI_CAP_ZONE self
|
||||
function AI_CAP_ZONE:SetEngageZone( EngageZone )
|
||||
self:F2()
|
||||
|
||||
if EngageZone then
|
||||
self.EngageZone = EngageZone
|
||||
else
|
||||
self.EngageZone = nil
|
||||
end
|
||||
end
|
||||
|
||||
--- Set the Engage Range when the AI will engage with airborne enemies.
|
||||
-- @param #AI_CAP_ZONE self
|
||||
-- @param #number EngageRange The Engage Range.
|
||||
-- @return #AI_CAP_ZONE self
|
||||
function AI_CAP_ZONE:SetEngageRange( EngageRange )
|
||||
self:F2()
|
||||
|
||||
if EngageRange then
|
||||
self.EngageRange = EngageRange
|
||||
else
|
||||
self.EngageRange = nil
|
||||
end
|
||||
end
|
||||
|
||||
--- onafter State Transition for Event Start.
|
||||
-- @param #AI_CAP_ZONE self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
||||
-- @param #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
function AI_CAP_ZONE:onafterStart( Controllable, From, Event, To )
|
||||
|
||||
-- Call the parent Start event handler
|
||||
self:GetParent(self).onafterStart( self, Controllable, From, Event, To )
|
||||
|
||||
end
|
||||
|
||||
--- @param Wrapper.Controllable#CONTROLLABLE AIControllable
|
||||
function _NewEngageCapRoute( AIControllable )
|
||||
|
||||
AIControllable:T( "NewEngageRoute" )
|
||||
local EngageZone = AIControllable:GetState( AIControllable, "EngageZone" ) -- AI.AI_Cap#AI_CAP_ZONE
|
||||
EngageZone:__Engage( 1 )
|
||||
end
|
||||
|
||||
--- @param #AI_CAP_ZONE self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
||||
-- @param #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
function AI_CAP_ZONE:onbeforeEngage( Controllable, From, Event, To )
|
||||
|
||||
if self.Accomplished == true then
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
--- @param #AI_CAP_ZONE self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
||||
-- @param #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
function AI_CAP_ZONE:onafterDetected( Controllable, From, Event, To )
|
||||
|
||||
if From ~= "Engaging" then
|
||||
|
||||
local Engage = false
|
||||
|
||||
for DetectedUnit, Detected in pairs( self.DetectedUnits ) do
|
||||
|
||||
local DetectedUnit = DetectedUnit -- Wrapper.Unit#UNIT
|
||||
self:T( DetectedUnit )
|
||||
if DetectedUnit:IsAlive() and DetectedUnit:IsAir() then
|
||||
Engage = true
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if Engage == true then
|
||||
self:E( 'Detected -> Engaging' )
|
||||
self:__Engage( 1 )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
--- @param #AI_CAP_ZONE self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
||||
-- @param #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
function AI_CAP_ZONE:onafterEngage( Controllable, From, Event, To )
|
||||
|
||||
if Controllable:IsAlive() then
|
||||
|
||||
local EngageRoute = {}
|
||||
|
||||
--- Calculate the current route point.
|
||||
local CurrentVec2 = self.Controllable:GetVec2()
|
||||
|
||||
--TODO: Create GetAltitude function for GROUP, and delete GetUnit(1).
|
||||
local CurrentAltitude = self.Controllable:GetUnit(1):GetAltitude()
|
||||
local CurrentPointVec3 = POINT_VEC3:New( CurrentVec2.x, CurrentAltitude, CurrentVec2.y )
|
||||
local ToEngageZoneSpeed = self.PatrolMaxSpeed
|
||||
local CurrentRoutePoint = CurrentPointVec3:RoutePointAir(
|
||||
self.PatrolAltType,
|
||||
POINT_VEC3.RoutePointType.TurningPoint,
|
||||
POINT_VEC3.RoutePointAction.TurningPoint,
|
||||
ToEngageZoneSpeed,
|
||||
true
|
||||
)
|
||||
|
||||
EngageRoute[#EngageRoute+1] = CurrentRoutePoint
|
||||
|
||||
|
||||
--- Find a random 2D point in PatrolZone.
|
||||
local ToTargetVec2 = self.PatrolZone:GetRandomVec2()
|
||||
self:T2( ToTargetVec2 )
|
||||
|
||||
--- Define Speed and Altitude.
|
||||
local ToTargetAltitude = math.random( self.EngageFloorAltitude, self.EngageCeilingAltitude )
|
||||
local ToTargetSpeed = math.random( self.PatrolMinSpeed, self.PatrolMaxSpeed )
|
||||
self:T2( { self.PatrolMinSpeed, self.PatrolMaxSpeed, ToTargetSpeed } )
|
||||
|
||||
--- Obtain a 3D @{Point} from the 2D point + altitude.
|
||||
local ToTargetPointVec3 = POINT_VEC3:New( ToTargetVec2.x, ToTargetAltitude, ToTargetVec2.y )
|
||||
|
||||
--- Create a route point of type air.
|
||||
local ToPatrolRoutePoint = ToTargetPointVec3:RoutePointAir(
|
||||
self.PatrolAltType,
|
||||
POINT_VEC3.RoutePointType.TurningPoint,
|
||||
POINT_VEC3.RoutePointAction.TurningPoint,
|
||||
ToTargetSpeed,
|
||||
true
|
||||
)
|
||||
|
||||
EngageRoute[#EngageRoute+1] = ToPatrolRoutePoint
|
||||
|
||||
Controllable:OptionROEOpenFire()
|
||||
Controllable:OptionROTPassiveDefense()
|
||||
|
||||
local AttackTasks = {}
|
||||
|
||||
for DetectedUnit, Detected in pairs( self.DetectedUnits ) do
|
||||
local DetectedUnit = DetectedUnit -- Wrapper.Unit#UNIT
|
||||
self:T( { DetectedUnit, DetectedUnit:IsAlive(), DetectedUnit:IsAir() } )
|
||||
if DetectedUnit:IsAlive() and DetectedUnit:IsAir() then
|
||||
if self.EngageZone then
|
||||
if DetectedUnit:IsInZone( self.EngageZone ) then
|
||||
self:E( {"Within Zone and Engaging ", DetectedUnit } )
|
||||
AttackTasks[#AttackTasks+1] = Controllable:TaskAttackUnit( DetectedUnit )
|
||||
end
|
||||
else
|
||||
if self.EngageRange then
|
||||
if DetectedUnit:GetPointVec3():Get2DDistance(Controllable:GetPointVec3() ) <= self.EngageRange then
|
||||
self:E( {"Within Range and Engaging", DetectedUnit } )
|
||||
AttackTasks[#AttackTasks+1] = Controllable:TaskAttackUnit( DetectedUnit )
|
||||
end
|
||||
else
|
||||
AttackTasks[#AttackTasks+1] = Controllable:TaskAttackUnit( DetectedUnit )
|
||||
end
|
||||
end
|
||||
else
|
||||
self.DetectedUnits[DetectedUnit] = nil
|
||||
end
|
||||
end
|
||||
|
||||
--- Now we're going to do something special, we're going to call a function from a waypoint action at the AIControllable...
|
||||
self.Controllable:WayPointInitialize( EngageRoute )
|
||||
|
||||
|
||||
if #AttackTasks == 0 then
|
||||
self:E("No targets found -> Going back to Patrolling")
|
||||
self:__Abort( 1 )
|
||||
self:__Route( 1 )
|
||||
self:SetDetectionActivated()
|
||||
else
|
||||
EngageRoute[1].task = Controllable:TaskCombo( AttackTasks )
|
||||
|
||||
--- Do a trick, link the NewEngageRoute function of the object to the AIControllable in a temporary variable ...
|
||||
self.Controllable:SetState( self.Controllable, "EngageZone", self )
|
||||
|
||||
self.Controllable:WayPointFunction( #EngageRoute, 1, "_NewEngageCapRoute" )
|
||||
|
||||
self:SetDetectionDeactivated()
|
||||
end
|
||||
|
||||
--- NOW ROUTE THE GROUP!
|
||||
self.Controllable:WayPointExecute( 1, 2 )
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
--- @param #AI_CAP_ZONE self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
||||
-- @param #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
-- @param Core.Event#EVENTDATA EventData
|
||||
function AI_CAP_ZONE:onafterDestroy( Controllable, From, Event, To, EventData )
|
||||
|
||||
if EventData.IniUnit then
|
||||
self.DetectedUnits[EventData.IniUnit] = nil
|
||||
end
|
||||
|
||||
Controllable:MessageToAll( "Destroyed a target", 15 , "Destroyed!" )
|
||||
end
|
||||
|
||||
--- @param #AI_CAP_ZONE self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
||||
-- @param #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
function AI_CAP_ZONE:onafterAccomplish( Controllable, From, Event, To )
|
||||
self.Accomplished = true
|
||||
self:SetDetectionOff()
|
||||
end
|
||||
|
||||
|
||||
572
Moose Development/Moose/AI/AI_CAS.lua
Normal file
572
Moose Development/Moose/AI/AI_CAS.lua
Normal file
@@ -0,0 +1,572 @@
|
||||
--- Single-Player:**Yes** / Multi-Player:**Yes** / AI:**Yes** / Human:**No** / Types:**Air** --
|
||||
-- **Provide Close Air Support to friendly ground troops.**
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- # 1) @{#AI_CAS_ZONE} class, extends @{AI_Patrol#AI_PATROL_ZONE}
|
||||
--
|
||||
-- @{#AI_CAS_ZONE} derives from the @{AI_Patrol#AI_PATROL_ZONE}, inheriting its methods and behaviour.
|
||||
--
|
||||
-- The @{#AI_CAS_ZONE} class implements the core functions to provide Close Air Support in an Engage @{Zone} by an AIR @{Controllable} or @{Group}.
|
||||
-- The AI_CAS_ZONE runs a process. It holds an AI in a Patrol Zone and when the AI is commanded to engage, it will fly to an Engage Zone.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- The AI_CAS_ZONE is assigned a @{Group} and this must be done before the AI_CAS_ZONE process can be started through the **Start** event.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- Upon started, The AI will **Route** itself towards the random 3D point within a patrol zone,
|
||||
-- using a random speed within the given altitude and speed limits.
|
||||
-- Upon arrival at the 3D point, a new random 3D point will be selected within the patrol zone using the given limits.
|
||||
-- This cycle will continue until a fuel or damage treshold has been reached by the AI, or when the AI is commanded to RTB.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- When the AI is commanded to provide Close Air Support (through the event **Engage**), the AI will fly towards the Engage Zone.
|
||||
-- Any target that is detected in the Engage Zone will be reported and will be destroyed by the AI.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- The AI will detect the targets and will only destroy the targets within the Engage Zone.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- Every target that is destroyed, is reported< by the AI.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- Note that the AI does not know when the Engage Zone is cleared, and therefore will keep circling in the zone.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- Until it is notified through the event **Accomplish**, which is to be triggered by an observing party:
|
||||
--
|
||||
-- * a FAC
|
||||
-- * a timed event
|
||||
-- * a menu option selected by a human
|
||||
-- * a condition
|
||||
-- * others ...
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- When the AI has accomplished the CAS, it will fly back to the Patrol Zone.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- It will keep patrolling there, until it is notified to RTB or move to another CAS Zone.
|
||||
-- It can be notified to go RTB through the **RTB** event.
|
||||
--
|
||||
-- When the fuel treshold has been reached, the airplane will fly towards the nearest friendly airbase and will land.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- # 1.1) AI_CAS_ZONE constructor
|
||||
--
|
||||
-- * @{#AI_CAS_ZONE.New}(): Creates a new AI_CAS_ZONE object.
|
||||
--
|
||||
-- ## 1.2) AI_CAS_ZONE is a FSM
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- ### 1.2.1) AI_CAS_ZONE States
|
||||
--
|
||||
-- * **None** ( Group ): The process is not started yet.
|
||||
-- * **Patrolling** ( Group ): The AI is patrolling the Patrol Zone.
|
||||
-- * **Engaging** ( Group ): The AI is engaging the targets in the Engage Zone, executing CAS.
|
||||
-- * **Returning** ( Group ): The AI is returning to Base..
|
||||
--
|
||||
-- ### 1.2.2) AI_CAS_ZONE Events
|
||||
--
|
||||
-- * **Start** ( Group ): Start the process.
|
||||
-- * **Route** ( Group ): Route the AI to a new random 3D point within the Patrol Zone.
|
||||
-- * **Engage** ( Group ): Engage the AI to provide CAS in the Engage Zone, destroying any target it finds.
|
||||
-- * **RTB** ( Group ): Route the AI to the home base.
|
||||
-- * **Detect** ( Group ): The AI is detecting targets.
|
||||
-- * **Detected** ( Group ): The AI has detected new targets.
|
||||
-- * **Status** ( Group ): The AI is checking status (fuel and damage). When the tresholds have been reached, the AI will RTB.
|
||||
--
|
||||
-- ====
|
||||
--
|
||||
-- # **API CHANGE HISTORY**
|
||||
--
|
||||
-- The underlying change log documents the API changes. Please read this carefully. The following notation is used:
|
||||
--
|
||||
-- * **Added** parts are expressed in bold type face.
|
||||
-- * _Removed_ parts are expressed in italic type face.
|
||||
--
|
||||
-- Hereby the change log:
|
||||
--
|
||||
-- 2017-01-15: Initial class and API.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- # **AUTHORS and CONTRIBUTIONS**
|
||||
--
|
||||
-- ### Contributions:
|
||||
--
|
||||
-- * **[Quax](https://forums.eagle.ru/member.php?u=90530)**: Concept, Advice & Testing.
|
||||
-- * **[Pikey](https://forums.eagle.ru/member.php?u=62835)**: Concept, Advice & Testing.
|
||||
-- * **[Gunterlund](http://forums.eagle.ru:8080/member.php?u=75036)**: Test case revision.
|
||||
--
|
||||
-- ### Authors:
|
||||
--
|
||||
-- * **FlightControl**: Concept, Design & Programming.
|
||||
--
|
||||
-- @module AI_Cas
|
||||
|
||||
|
||||
--- AI_CAS_ZONE class
|
||||
-- @type AI_CAS_ZONE
|
||||
-- @field Wrapper.Controllable#CONTROLLABLE AIControllable The @{Controllable} patrolling.
|
||||
-- @field Core.Zone#ZONE_BASE TargetZone The @{Zone} where the patrol needs to be executed.
|
||||
-- @extends AI.AI_Patrol#AI_PATROL_ZONE
|
||||
AI_CAS_ZONE = {
|
||||
ClassName = "AI_CAS_ZONE",
|
||||
}
|
||||
|
||||
|
||||
|
||||
--- Creates a new AI_CAS_ZONE object
|
||||
-- @param #AI_CAS_ZONE self
|
||||
-- @param Core.Zone#ZONE_BASE PatrolZone The @{Zone} where the patrol needs to be executed.
|
||||
-- @param Dcs.DCSTypes#Altitude PatrolFloorAltitude The lowest altitude in meters where to execute the patrol.
|
||||
-- @param Dcs.DCSTypes#Altitude PatrolCeilingAltitude The highest altitude in meters where to execute the patrol.
|
||||
-- @param Dcs.DCSTypes#Speed PatrolMinSpeed The minimum speed of the @{Controllable} in km/h.
|
||||
-- @param Dcs.DCSTypes#Speed PatrolMaxSpeed The maximum speed of the @{Controllable} in km/h.
|
||||
-- @param Core.Zone#ZONE_BASE EngageZone The zone where the engage will happen.
|
||||
-- @param Dcs.DCSTypes#AltitudeType PatrolAltType The altitude type ("RADIO"=="AGL", "BARO"=="ASL"). Defaults to RADIO
|
||||
-- @return #AI_CAS_ZONE self
|
||||
function AI_CAS_ZONE:New( PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed, EngageZone, PatrolAltType )
|
||||
|
||||
-- Inherits from BASE
|
||||
local self = BASE:Inherit( self, AI_PATROL_ZONE:New( PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed, PatrolAltType ) ) -- #AI_CAS_ZONE
|
||||
|
||||
self.EngageZone = EngageZone
|
||||
self.Accomplished = false
|
||||
|
||||
self:SetDetectionZone( self.EngageZone )
|
||||
|
||||
self:AddTransition( { "Patrolling", "Engaging" }, "Engage", "Engaging" ) -- FSM_CONTROLLABLE Transition for type #AI_CAS_ZONE.
|
||||
|
||||
--- OnBefore Transition Handler for Event Engage.
|
||||
-- @function [parent=#AI_CAS_ZONE] OnBeforeEngage
|
||||
-- @param #AI_CAS_ZONE self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
||||
-- @param #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
-- @param #number EngageSpeed (optional) The speed the Group will hold when engaging to the target zone.
|
||||
-- @param Dcs.DCSTypes#AI.Task.WeaponExpend EngageWeaponExpend (optional) Determines how much weapon will be released at each attack. If parameter is not defined the unit / controllable will choose expend on its own discretion.
|
||||
-- @param Dcs.DCSTypes#Distance EngageAltitude (optional) Desired altitude to perform the unit engagement.
|
||||
-- @param #number EngageAttackQty (optional) This parameter limits maximal quantity of attack. The aicraft/controllable will not make more attack than allowed even if the target controllable not destroyed and the aicraft/controllable still have ammo. If not defined the aircraft/controllable will attack target until it will be destroyed or until the aircraft/controllable will run out of ammo.
|
||||
-- @param Dcs.DCSTypes#Azimuth EngageDirection (optional) Desired ingress direction from the target to the attacking aircraft. Controllable/aircraft will make its attacks from the direction. Of course if there is no way to attack from the direction due the terrain controllable/aircraft will choose another direction.
|
||||
|
||||
-- @return #boolean Return false to cancel Transition.
|
||||
|
||||
--- OnAfter Transition Handler for Event Engage.
|
||||
-- @function [parent=#AI_CAS_ZONE] OnAfterEngage
|
||||
-- @param #AI_CAS_ZONE self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
||||
-- @param #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
-- @param #number EngageSpeed (optional) The speed the Group will hold when engaging to the target zone.
|
||||
-- @param Dcs.DCSTypes#AI.Task.WeaponExpend EngageWeaponExpend (optional) Determines how much weapon will be released at each attack. If parameter is not defined the unit / controllable will choose expend on its own discretion.
|
||||
-- @param Dcs.DCSTypes#Distance EngageAltitude (optional) Desired altitude to perform the unit engagement.
|
||||
-- @param #number EngageAttackQty (optional) This parameter limits maximal quantity of attack. The aicraft/controllable will not make more attack than allowed even if the target controllable not destroyed and the aicraft/controllable still have ammo. If not defined the aircraft/controllable will attack target until it will be destroyed or until the aircraft/controllable will run out of ammo.
|
||||
-- @param Dcs.DCSTypes#Azimuth EngageDirection (optional) Desired ingress direction from the target to the attacking aircraft. Controllable/aircraft will make its attacks from the direction. Of course if there is no way to attack from the direction due the terrain controllable/aircraft will choose another direction.
|
||||
|
||||
--- Synchronous Event Trigger for Event Engage.
|
||||
-- @function [parent=#AI_CAS_ZONE] Engage
|
||||
-- @param #AI_CAS_ZONE self
|
||||
|
||||
--- Asynchronous Event Trigger for Event Engage.
|
||||
-- @function [parent=#AI_CAS_ZONE] __Engage
|
||||
-- @param #AI_CAS_ZONE self
|
||||
-- @param #number Delay The delay in seconds.
|
||||
|
||||
--- OnLeave Transition Handler for State Engaging.
|
||||
-- @function [parent=#AI_CAS_ZONE] OnLeaveEngaging
|
||||
-- @param #AI_CAS_ZONE self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
||||
-- @param #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
-- @return #boolean Return false to cancel Transition.
|
||||
|
||||
--- OnEnter Transition Handler for State Engaging.
|
||||
-- @function [parent=#AI_CAS_ZONE] OnEnterEngaging
|
||||
-- @param #AI_CAS_ZONE self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
||||
-- @param #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
|
||||
self:AddTransition( "Engaging", "Target", "Engaging" ) -- FSM_CONTROLLABLE Transition for type #AI_CAS_ZONE.
|
||||
|
||||
self:AddTransition( "Engaging", "Fired", "Engaging" ) -- FSM_CONTROLLABLE Transition for type #AI_CAS_ZONE.
|
||||
|
||||
--- OnBefore Transition Handler for Event Fired.
|
||||
-- @function [parent=#AI_CAS_ZONE] OnBeforeFired
|
||||
-- @param #AI_CAS_ZONE self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
||||
-- @param #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
-- @return #boolean Return false to cancel Transition.
|
||||
|
||||
--- OnAfter Transition Handler for Event Fired.
|
||||
-- @function [parent=#AI_CAS_ZONE] OnAfterFired
|
||||
-- @param #AI_CAS_ZONE self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
||||
-- @param #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
|
||||
--- Synchronous Event Trigger for Event Fired.
|
||||
-- @function [parent=#AI_CAS_ZONE] Fired
|
||||
-- @param #AI_CAS_ZONE self
|
||||
|
||||
--- Asynchronous Event Trigger for Event Fired.
|
||||
-- @function [parent=#AI_CAS_ZONE] __Fired
|
||||
-- @param #AI_CAS_ZONE self
|
||||
-- @param #number Delay The delay in seconds.
|
||||
|
||||
self:AddTransition( "*", "Destroy", "*" ) -- FSM_CONTROLLABLE Transition for type #AI_CAS_ZONE.
|
||||
|
||||
--- OnBefore Transition Handler for Event Destroy.
|
||||
-- @function [parent=#AI_CAS_ZONE] OnBeforeDestroy
|
||||
-- @param #AI_CAS_ZONE self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
||||
-- @param #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
-- @return #boolean Return false to cancel Transition.
|
||||
|
||||
--- OnAfter Transition Handler for Event Destroy.
|
||||
-- @function [parent=#AI_CAS_ZONE] OnAfterDestroy
|
||||
-- @param #AI_CAS_ZONE self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
||||
-- @param #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
|
||||
--- Synchronous Event Trigger for Event Destroy.
|
||||
-- @function [parent=#AI_CAS_ZONE] Destroy
|
||||
-- @param #AI_CAS_ZONE self
|
||||
|
||||
--- Asynchronous Event Trigger for Event Destroy.
|
||||
-- @function [parent=#AI_CAS_ZONE] __Destroy
|
||||
-- @param #AI_CAS_ZONE self
|
||||
-- @param #number Delay The delay in seconds.
|
||||
|
||||
|
||||
self:AddTransition( "Engaging", "Abort", "Patrolling" ) -- FSM_CONTROLLABLE Transition for type #AI_CAS_ZONE.
|
||||
|
||||
--- OnBefore Transition Handler for Event Abort.
|
||||
-- @function [parent=#AI_CAS_ZONE] OnBeforeAbort
|
||||
-- @param #AI_CAS_ZONE self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
||||
-- @param #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
-- @return #boolean Return false to cancel Transition.
|
||||
|
||||
--- OnAfter Transition Handler for Event Abort.
|
||||
-- @function [parent=#AI_CAS_ZONE] OnAfterAbort
|
||||
-- @param #AI_CAS_ZONE self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
||||
-- @param #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
|
||||
--- Synchronous Event Trigger for Event Abort.
|
||||
-- @function [parent=#AI_CAS_ZONE] Abort
|
||||
-- @param #AI_CAS_ZONE self
|
||||
|
||||
--- Asynchronous Event Trigger for Event Abort.
|
||||
-- @function [parent=#AI_CAS_ZONE] __Abort
|
||||
-- @param #AI_CAS_ZONE self
|
||||
-- @param #number Delay The delay in seconds.
|
||||
|
||||
self:AddTransition( "Engaging", "Accomplish", "Patrolling" ) -- FSM_CONTROLLABLE Transition for type #AI_CAS_ZONE.
|
||||
|
||||
--- OnBefore Transition Handler for Event Accomplish.
|
||||
-- @function [parent=#AI_CAS_ZONE] OnBeforeAccomplish
|
||||
-- @param #AI_CAS_ZONE self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
||||
-- @param #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
-- @return #boolean Return false to cancel Transition.
|
||||
|
||||
--- OnAfter Transition Handler for Event Accomplish.
|
||||
-- @function [parent=#AI_CAS_ZONE] OnAfterAccomplish
|
||||
-- @param #AI_CAS_ZONE self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
||||
-- @param #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
|
||||
--- Synchronous Event Trigger for Event Accomplish.
|
||||
-- @function [parent=#AI_CAS_ZONE] Accomplish
|
||||
-- @param #AI_CAS_ZONE self
|
||||
|
||||
--- Asynchronous Event Trigger for Event Accomplish.
|
||||
-- @function [parent=#AI_CAS_ZONE] __Accomplish
|
||||
-- @param #AI_CAS_ZONE self
|
||||
-- @param #number Delay The delay in seconds.
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
--- Set the Engage Zone where the AI is performing CAS. Note that if the EngageZone is changed, the AI needs to re-detect targets.
|
||||
-- @param #AI_CAS_ZONE self
|
||||
-- @param Core.Zone#ZONE EngageZone The zone where the AI is performing CAS.
|
||||
-- @return #AI_CAS_ZONE self
|
||||
function AI_CAS_ZONE:SetEngageZone( EngageZone )
|
||||
self:F2()
|
||||
|
||||
if EngageZone then
|
||||
self.EngageZone = EngageZone
|
||||
else
|
||||
self.EngageZone = nil
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
--- onafter State Transition for Event Start.
|
||||
-- @param #AI_CAS_ZONE self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
||||
-- @param #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
function AI_CAS_ZONE:onafterStart( Controllable, From, Event, To )
|
||||
|
||||
-- Call the parent Start event handler
|
||||
self:GetParent(self).onafterStart( self, Controllable, From, Event, To )
|
||||
self:HandleEvent( EVENTS.Dead, self.OnDead )
|
||||
|
||||
self:SetDetectionDeactivated() -- When not engaging, set the detection off.
|
||||
end
|
||||
|
||||
--- @param Wrapper.Controllable#CONTROLLABLE AIControllable
|
||||
function _NewEngageRoute( AIControllable )
|
||||
|
||||
AIControllable:T( "NewEngageRoute" )
|
||||
local EngageZone = AIControllable:GetState( AIControllable, "EngageZone" ) -- AI.AI_Cas#AI_CAS_ZONE
|
||||
EngageZone:__Engage( 1 )
|
||||
end
|
||||
|
||||
--- @param #AI_CAS_ZONE self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
||||
-- @param #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
function AI_CAS_ZONE:onbeforeEngage( Controllable, From, Event, To )
|
||||
|
||||
if self.Accomplished == true then
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
--- @param #AI_CAS_ZONE self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
||||
-- @param #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
function AI_CAS_ZONE:onafterTarget( Controllable, From, Event, To )
|
||||
self:E("onafterTarget")
|
||||
|
||||
if Controllable:IsAlive() then
|
||||
|
||||
local AttackTasks = {}
|
||||
|
||||
for DetectedUnit, Detected in pairs( self.DetectedUnits ) do
|
||||
local DetectedUnit = DetectedUnit -- Wrapper.Unit#UNIT
|
||||
if DetectedUnit:IsAlive() then
|
||||
if DetectedUnit:IsInZone( self.EngageZone ) then
|
||||
if Detected == true then
|
||||
self:E( {"Target: ", DetectedUnit } )
|
||||
self.DetectedUnits[DetectedUnit] = false
|
||||
local AttackTask = Controllable:EnRouteTaskEngageUnit( DetectedUnit, 1, true, self.EngageWeaponExpend, self.EngageAttackQty, self.EngageDirection, self.EngageAltitude, nil )
|
||||
self.Controllable:PushTask( AttackTask, 1 )
|
||||
end
|
||||
end
|
||||
else
|
||||
self.DetectedUnits[DetectedUnit] = nil
|
||||
end
|
||||
end
|
||||
|
||||
self:__Target( -10 )
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
--- @param #AI_CAS_ZONE self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
||||
-- @param #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
-- @param #number EngageSpeed (optional) The speed the Group will hold when engaging to the target zone.
|
||||
-- @param Dcs.DCSTypes#AI.Task.WeaponExpend EngageWeaponExpend (optional) Determines how much weapon will be released at each attack. If parameter is not defined the unit / controllable will choose expend on its own discretion.
|
||||
-- @param Dcs.DCSTypes#Distance EngageAltitude (optional) Desired altitude to perform the unit engagement.
|
||||
-- @param #number EngageAttackQty (optional) This parameter limits maximal quantity of attack. The aicraft/controllable will not make more attack than allowed even if the target controllable not destroyed and the aicraft/controllable still have ammo. If not defined the aircraft/controllable will attack target until it will be destroyed or until the aircraft/controllable will run out of ammo.
|
||||
-- @param Dcs.DCSTypes#Azimuth EngageDirection (optional) Desired ingress direction from the target to the attacking aircraft. Controllable/aircraft will make its attacks from the direction. Of course if there is no way to attack from the direction due the terrain controllable/aircraft will choose another direction.
|
||||
function AI_CAS_ZONE:onafterEngage( Controllable, From, Event, To, EngageSpeed, EngageAltitude, EngageWeaponExpend, EngageAttackQty, EngageDirection )
|
||||
self:E("onafterEngage")
|
||||
|
||||
self.EngageSpeed = EngageSpeed or 400
|
||||
self.EngageAltitude = EngageAltitude or 2000
|
||||
self.EngageWeaponExpend = EngageWeaponExpend
|
||||
self.EngageAttackQty = EngageAttackQty
|
||||
self.EngageDirection = EngageDirection
|
||||
|
||||
if Controllable:IsAlive() then
|
||||
|
||||
|
||||
local EngageRoute = {}
|
||||
|
||||
--- Calculate the current route point.
|
||||
local CurrentVec2 = self.Controllable:GetVec2()
|
||||
|
||||
--TODO: Create GetAltitude function for GROUP, and delete GetUnit(1).
|
||||
local CurrentAltitude = self.Controllable:GetUnit(1):GetAltitude()
|
||||
local CurrentPointVec3 = POINT_VEC3:New( CurrentVec2.x, CurrentAltitude, CurrentVec2.y )
|
||||
local ToEngageZoneSpeed = self.PatrolMaxSpeed
|
||||
local CurrentRoutePoint = CurrentPointVec3:RoutePointAir(
|
||||
self.PatrolAltType,
|
||||
POINT_VEC3.RoutePointType.TurningPoint,
|
||||
POINT_VEC3.RoutePointAction.TurningPoint,
|
||||
self.EngageSpeed,
|
||||
true
|
||||
)
|
||||
|
||||
EngageRoute[#EngageRoute+1] = CurrentRoutePoint
|
||||
|
||||
|
||||
if self.Controllable:IsNotInZone( self.EngageZone ) then
|
||||
|
||||
-- Find a random 2D point in EngageZone.
|
||||
local ToEngageZoneVec2 = self.EngageZone:GetRandomVec2()
|
||||
self:T2( ToEngageZoneVec2 )
|
||||
|
||||
-- Obtain a 3D @{Point} from the 2D point + altitude.
|
||||
local ToEngageZonePointVec3 = POINT_VEC3:New( ToEngageZoneVec2.x, self.EngageAltitude, ToEngageZoneVec2.y )
|
||||
|
||||
-- Create a route point of type air.
|
||||
local ToEngageZoneRoutePoint = ToEngageZonePointVec3:RoutePointAir(
|
||||
self.PatrolAltType,
|
||||
POINT_VEC3.RoutePointType.TurningPoint,
|
||||
POINT_VEC3.RoutePointAction.TurningPoint,
|
||||
self.EngageSpeed,
|
||||
true
|
||||
)
|
||||
|
||||
EngageRoute[#EngageRoute+1] = ToEngageZoneRoutePoint
|
||||
|
||||
end
|
||||
|
||||
--- Define a random point in the @{Zone}. The AI will fly to that point within the zone.
|
||||
|
||||
--- Find a random 2D point in EngageZone.
|
||||
local ToTargetVec2 = self.EngageZone:GetRandomVec2()
|
||||
self:T2( ToTargetVec2 )
|
||||
|
||||
--- Obtain a 3D @{Point} from the 2D point + altitude.
|
||||
local ToTargetPointVec3 = POINT_VEC3:New( ToTargetVec2.x, self.EngageAltitude, ToTargetVec2.y )
|
||||
|
||||
--- Create a route point of type air.
|
||||
local ToTargetRoutePoint = ToTargetPointVec3:RoutePointAir(
|
||||
self.PatrolAltType,
|
||||
POINT_VEC3.RoutePointType.TurningPoint,
|
||||
POINT_VEC3.RoutePointAction.TurningPoint,
|
||||
self.EngageSpeed,
|
||||
true
|
||||
)
|
||||
|
||||
ToTargetPointVec3:SmokeBlue()
|
||||
|
||||
EngageRoute[#EngageRoute+1] = ToTargetRoutePoint
|
||||
|
||||
|
||||
Controllable:OptionROEOpenFire()
|
||||
Controllable:OptionROTVertical()
|
||||
|
||||
-- local AttackTasks = {}
|
||||
--
|
||||
-- for DetectedUnitID, DetectedUnit in pairs( self.DetectedUnits ) do
|
||||
-- local DetectedUnit = DetectedUnit -- Wrapper.Unit#UNIT
|
||||
-- self:T( DetectedUnit )
|
||||
-- if DetectedUnit:IsAlive() then
|
||||
-- if DetectedUnit:IsInZone( self.EngageZone ) then
|
||||
-- self:E( {"Engaging ", DetectedUnit } )
|
||||
-- AttackTasks[#AttackTasks+1] = Controllable:TaskAttackUnit( DetectedUnit )
|
||||
-- end
|
||||
-- else
|
||||
-- self.DetectedUnits[DetectedUnit] = nil
|
||||
-- end
|
||||
-- end
|
||||
--
|
||||
-- EngageRoute[1].task = Controllable:TaskCombo( AttackTasks )
|
||||
|
||||
--- Now we're going to do something special, we're going to call a function from a waypoint action at the AIControllable...
|
||||
self.Controllable:WayPointInitialize( EngageRoute )
|
||||
|
||||
--- Do a trick, link the NewEngageRoute function of the object to the AIControllable in a temporary variable ...
|
||||
self.Controllable:SetState( self.Controllable, "EngageZone", self )
|
||||
|
||||
self.Controllable:WayPointFunction( #EngageRoute, 1, "_NewEngageRoute" )
|
||||
|
||||
--- NOW ROUTE THE GROUP!
|
||||
self.Controllable:WayPointExecute( 1 )
|
||||
|
||||
self:SetDetectionInterval( 10 )
|
||||
self:SetDetectionActivated()
|
||||
self:__Target( -10 ) -- Start Targetting
|
||||
end
|
||||
end
|
||||
|
||||
--- @param #AI_CAS_ZONE self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
||||
-- @param #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
-- @param Core.Event#EVENTDATA EventData
|
||||
function AI_CAS_ZONE:onafterDestroy( Controllable, From, Event, To, EventData )
|
||||
|
||||
if EventData.IniUnit then
|
||||
self.DetectedUnits[EventData.IniUnit] = nil
|
||||
end
|
||||
|
||||
Controllable:MessageToAll( "Destroyed a target", 15 , "Destroyed!" )
|
||||
end
|
||||
|
||||
--- @param #AI_CAS_ZONE self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
||||
-- @param #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
function AI_CAS_ZONE:onafterAccomplish( Controllable, From, Event, To )
|
||||
self.Accomplished = true
|
||||
self:SetDetectionDeactivated()
|
||||
end
|
||||
|
||||
--- @param #AI_CAS_ZONE self
|
||||
-- @param Core.Event#EVENTDATA EventData
|
||||
function AI_CAS_ZONE:OnDead( EventData )
|
||||
self:T( { "EventDead", EventData } )
|
||||
|
||||
if EventData.IniDCSUnit then
|
||||
self:__Destroy( 1, EventData )
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
1028
Moose Development/Moose/AI/AI_Cargo.lua
Normal file
1028
Moose Development/Moose/AI/AI_Cargo.lua
Normal file
File diff suppressed because it is too large
Load Diff
891
Moose Development/Moose/AI/AI_Patrol.lua
Normal file
891
Moose Development/Moose/AI/AI_Patrol.lua
Normal file
@@ -0,0 +1,891 @@
|
||||
--- Single-Player:**Yes** / Multi-Player:**Yes** / AI:**Yes** / Human:**No** / Types:**Air** --
|
||||
-- **Air Patrolling or Staging.**
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- # 1) @{#AI_PATROL_ZONE} class, extends @{Fsm#FSM_CONTROLLABLE}
|
||||
--
|
||||
-- The @{#AI_PATROL_ZONE} class implements the core functions to patrol a @{Zone} by an AI @{Controllable} or @{Group}.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- The AI_PATROL_ZONE is assigned a @{Group} and this must be done before the AI_PATROL_ZONE process can be started using the **Start** event.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- The AI will fly towards the random 3D point within the patrol zone, using a random speed within the given altitude and speed limits.
|
||||
-- Upon arrival at the 3D point, a new random 3D point will be selected within the patrol zone using the given limits.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- This cycle will continue.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- During the patrol, the AI will detect enemy targets, which are reported through the **Detected** event.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
---- Note that the enemy is not engaged! To model enemy engagement, either tailor the **Detected** event, or
|
||||
-- use derived AI_ classes to model AI offensive or defensive behaviour.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- Until a fuel or damage treshold has been reached by the AI, or when the AI is commanded to RTB.
|
||||
-- When the fuel treshold has been reached, the airplane will fly towards the nearest friendly airbase and will land.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- ## 1.1) AI_PATROL_ZONE constructor
|
||||
--
|
||||
-- * @{#AI_PATROL_ZONE.New}(): Creates a new AI_PATROL_ZONE object.
|
||||
--
|
||||
-- ## 1.2) AI_PATROL_ZONE is a FSM
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- ### 1.2.1) AI_PATROL_ZONE States
|
||||
--
|
||||
-- * **None** ( Group ): The process is not started yet.
|
||||
-- * **Patrolling** ( Group ): The AI is patrolling the Patrol Zone.
|
||||
-- * **Returning** ( Group ): The AI is returning to Base..
|
||||
--
|
||||
-- ### 1.2.2) AI_PATROL_ZONE Events
|
||||
--
|
||||
-- * **Start** ( Group ): Start the process.
|
||||
-- * **Route** ( Group ): Route the AI to a new random 3D point within the Patrol Zone.
|
||||
-- * **RTB** ( Group ): Route the AI to the home base.
|
||||
-- * **Detect** ( Group ): The AI is detecting targets.
|
||||
-- * **Detected** ( Group ): The AI has detected new targets.
|
||||
-- * **Status** ( Group ): The AI is checking status (fuel and damage). When the tresholds have been reached, the AI will RTB.
|
||||
--
|
||||
-- ## 1.3) Set or Get the AI controllable
|
||||
--
|
||||
-- * @{#AI_PATROL_ZONE.SetControllable}(): Set the AIControllable.
|
||||
-- * @{#AI_PATROL_ZONE.GetControllable}(): Get the AIControllable.
|
||||
--
|
||||
-- ## 1.4) Set the Speed and Altitude boundaries of the AI controllable
|
||||
--
|
||||
-- * @{#AI_PATROL_ZONE.SetSpeed}(): Set the patrol speed boundaries of the AI, for the next patrol.
|
||||
-- * @{#AI_PATROL_ZONE.SetAltitude}(): Set altitude boundaries of the AI, for the next patrol.
|
||||
--
|
||||
-- ## 1.5) Manage the detection process of the AI controllable
|
||||
--
|
||||
-- The detection process of the AI controllable can be manipulated.
|
||||
-- Detection requires an amount of CPU power, which has an impact on your mission performance.
|
||||
-- Only put detection on when absolutely necessary, and the frequency of the detection can also be set.
|
||||
--
|
||||
-- * @{#AI_PATROL_ZONE.SetDetectionOn}(): Set the detection on. The AI will detect for targets.
|
||||
-- * @{#AI_PATROL_ZONE.SetDetectionOff}(): Set the detection off, the AI will not detect for targets. The existing target list will NOT be erased.
|
||||
--
|
||||
-- The detection frequency can be set with @{#AI_PATROL_ZONE.SetDetectionInterval}( seconds ), where the amount of seconds specify how much seconds will be waited before the next detection.
|
||||
-- Use the method @{#AI_PATROL_ZONE.GetDetectedUnits}() to obtain a list of the @{Unit}s detected by the AI.
|
||||
--
|
||||
-- The detection can be filtered to potential targets in a specific zone.
|
||||
-- Use the method @{#AI_PATROL_ZONE.SetDetectionZone}() to set the zone where targets need to be detected.
|
||||
-- Note that when the zone is too far away, or the AI is not heading towards the zone, or the AI is too high, no targets may be detected
|
||||
-- according the weather conditions.
|
||||
--
|
||||
-- ## 1.6) Manage the "out of fuel" in the AI_PATROL_ZONE
|
||||
--
|
||||
-- When the AI is out of fuel, it is required that a new AI is started, before the old AI can return to the home base.
|
||||
-- Therefore, with a parameter and a calculation of the distance to the home base, the fuel treshold is calculated.
|
||||
-- When the fuel treshold is reached, the AI will continue for a given time its patrol task in orbit,
|
||||
-- while a new AI is targetted to the AI_PATROL_ZONE.
|
||||
-- Once the time is finished, the old AI will return to the base.
|
||||
-- Use the method @{#AI_PATROL_ZONE.ManageFuel}() to have this proces in place.
|
||||
--
|
||||
-- ## 1.7) Manage "damage" behaviour of the AI in the AI_PATROL_ZONE
|
||||
--
|
||||
-- When the AI is damaged, it is required that a new AIControllable is started. However, damage cannon be foreseen early on.
|
||||
-- Therefore, when the damage treshold is reached, the AI will return immediately to the home base (RTB).
|
||||
-- Use the method @{#AI_PATROL_ZONE.ManageDamage}() to have this proces in place.
|
||||
--
|
||||
-- ====
|
||||
--
|
||||
-- # **OPEN ISSUES**
|
||||
--
|
||||
-- 2017-01-17: When Spawned AI is located at an airbase, it will be routed first back to the airbase after take-off.
|
||||
--
|
||||
-- 2016-01-17:
|
||||
-- -- Fixed problem with AI returning to base too early and unexpected.
|
||||
-- -- ReSpawning of AI will reset the AI_PATROL and derived classes.
|
||||
-- -- Checked the correct workings of SCHEDULER, and it DOES work correctly.
|
||||
--
|
||||
-- ====
|
||||
--
|
||||
-- # **API CHANGE HISTORY**
|
||||
--
|
||||
-- The underlying change log documents the API changes. Please read this carefully. The following notation is used:
|
||||
--
|
||||
-- * **Added** parts are expressed in bold type face.
|
||||
-- * _Removed_ parts are expressed in italic type face.
|
||||
--
|
||||
-- Hereby the change log:
|
||||
--
|
||||
-- 2017-01-17: Rename of class: **AI\_PATROL\_ZONE** is the new name for the old _AI\_PATROLZONE_.
|
||||
--
|
||||
-- 2017-01-15: Complete revision. AI_PATROL_ZONE is the base class for other AI_PATROL like classes.
|
||||
--
|
||||
-- 2016-09-01: Initial class and API.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- # **AUTHORS and CONTRIBUTIONS**
|
||||
--
|
||||
-- ### Contributions:
|
||||
--
|
||||
-- * **[Dutch_Baron](https://forums.eagle.ru/member.php?u=112075)**: Working together with James has resulted in the creation of the AI_BALANCER class. James has shared his ideas on balancing AI with air units, and together we made a first design which you can use now :-)
|
||||
-- * **[Pikey](https://forums.eagle.ru/member.php?u=62835)**: Testing and API concept review.
|
||||
--
|
||||
-- ### Authors:
|
||||
--
|
||||
-- * **FlightControl**: Design & Programming.
|
||||
--
|
||||
-- @module AI_Patrol
|
||||
|
||||
--- AI_PATROL_ZONE class
|
||||
-- @type AI_PATROL_ZONE
|
||||
-- @field Wrapper.Controllable#CONTROLLABLE AIControllable The @{Controllable} patrolling.
|
||||
-- @field Core.Zone#ZONE_BASE PatrolZone The @{Zone} where the patrol needs to be executed.
|
||||
-- @field Dcs.DCSTypes#Altitude PatrolFloorAltitude The lowest altitude in meters where to execute the patrol.
|
||||
-- @field Dcs.DCSTypes#Altitude PatrolCeilingAltitude The highest altitude in meters where to execute the patrol.
|
||||
-- @field Dcs.DCSTypes#Speed PatrolMinSpeed The minimum speed of the @{Controllable} in km/h.
|
||||
-- @field Dcs.DCSTypes#Speed PatrolMaxSpeed The maximum speed of the @{Controllable} in km/h.
|
||||
-- @field Functional.Spawn#SPAWN CoordTest
|
||||
-- @extends Core.Fsm#FSM_CONTROLLABLE
|
||||
AI_PATROL_ZONE = {
|
||||
ClassName = "AI_PATROL_ZONE",
|
||||
}
|
||||
|
||||
--- Creates a new AI_PATROL_ZONE object
|
||||
-- @param #AI_PATROL_ZONE self
|
||||
-- @param Core.Zone#ZONE_BASE PatrolZone The @{Zone} where the patrol needs to be executed.
|
||||
-- @param Dcs.DCSTypes#Altitude PatrolFloorAltitude The lowest altitude in meters where to execute the patrol.
|
||||
-- @param Dcs.DCSTypes#Altitude PatrolCeilingAltitude The highest altitude in meters where to execute the patrol.
|
||||
-- @param Dcs.DCSTypes#Speed PatrolMinSpeed The minimum speed of the @{Controllable} in km/h.
|
||||
-- @param Dcs.DCSTypes#Speed PatrolMaxSpeed The maximum speed of the @{Controllable} in km/h.
|
||||
-- @param Dcs.DCSTypes#AltitudeType PatrolAltType The altitude type ("RADIO"=="AGL", "BARO"=="ASL"). Defaults to RADIO
|
||||
-- @return #AI_PATROL_ZONE self
|
||||
-- @usage
|
||||
-- -- Define a new AI_PATROL_ZONE Object. This PatrolArea will patrol an AIControllable within PatrolZone between 3000 and 6000 meters, with a variying speed between 600 and 900 km/h.
|
||||
-- PatrolZone = ZONE:New( 'PatrolZone' )
|
||||
-- PatrolSpawn = SPAWN:New( 'Patrol Group' )
|
||||
-- PatrolArea = AI_PATROL_ZONE:New( PatrolZone, 3000, 6000, 600, 900 )
|
||||
function AI_PATROL_ZONE:New( PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed, PatrolAltType )
|
||||
|
||||
-- Inherits from BASE
|
||||
local self = BASE:Inherit( self, FSM_CONTROLLABLE:New() ) -- #AI_PATROL_ZONE
|
||||
|
||||
|
||||
self.PatrolZone = PatrolZone
|
||||
self.PatrolFloorAltitude = PatrolFloorAltitude
|
||||
self.PatrolCeilingAltitude = PatrolCeilingAltitude
|
||||
self.PatrolMinSpeed = PatrolMinSpeed
|
||||
self.PatrolMaxSpeed = PatrolMaxSpeed
|
||||
|
||||
-- defafult PatrolAltType to "RADIO" if not specified
|
||||
self.PatrolAltType = PatrolAltType or "RADIO"
|
||||
|
||||
self:SetDetectionInterval( 30 )
|
||||
|
||||
self.CheckStatus = true
|
||||
|
||||
self:ManageFuel( .2, 60 )
|
||||
self:ManageDamage( 1 )
|
||||
|
||||
|
||||
self.DetectedUnits = {} -- This table contains the targets detected during patrol.
|
||||
|
||||
self:SetStartState( "None" )
|
||||
|
||||
self:AddTransition( "None", "Start", "Patrolling" )
|
||||
|
||||
--- OnBefore Transition Handler for Event Start.
|
||||
-- @function [parent=#AI_PATROL_ZONE] OnBeforeStart
|
||||
-- @param #AI_PATROL_ZONE self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
||||
-- @param #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
-- @return #boolean Return false to cancel Transition.
|
||||
|
||||
--- OnAfter Transition Handler for Event Start.
|
||||
-- @function [parent=#AI_PATROL_ZONE] OnAfterStart
|
||||
-- @param #AI_PATROL_ZONE self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
||||
-- @param #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
|
||||
--- Synchronous Event Trigger for Event Start.
|
||||
-- @function [parent=#AI_PATROL_ZONE] Start
|
||||
-- @param #AI_PATROL_ZONE self
|
||||
|
||||
--- Asynchronous Event Trigger for Event Start.
|
||||
-- @function [parent=#AI_PATROL_ZONE] __Start
|
||||
-- @param #AI_PATROL_ZONE self
|
||||
-- @param #number Delay The delay in seconds.
|
||||
|
||||
--- OnLeave Transition Handler for State Patrolling.
|
||||
-- @function [parent=#AI_PATROL_ZONE] OnLeavePatrolling
|
||||
-- @param #AI_PATROL_ZONE self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
||||
-- @param #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
-- @return #boolean Return false to cancel Transition.
|
||||
|
||||
--- OnEnter Transition Handler for State Patrolling.
|
||||
-- @function [parent=#AI_PATROL_ZONE] OnEnterPatrolling
|
||||
-- @param #AI_PATROL_ZONE self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
||||
-- @param #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
|
||||
self:AddTransition( "Patrolling", "Route", "Patrolling" ) -- FSM_CONTROLLABLE Transition for type #AI_PATROL_ZONE.
|
||||
|
||||
--- OnBefore Transition Handler for Event Route.
|
||||
-- @function [parent=#AI_PATROL_ZONE] OnBeforeRoute
|
||||
-- @param #AI_PATROL_ZONE self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
||||
-- @param #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
-- @return #boolean Return false to cancel Transition.
|
||||
|
||||
--- OnAfter Transition Handler for Event Route.
|
||||
-- @function [parent=#AI_PATROL_ZONE] OnAfterRoute
|
||||
-- @param #AI_PATROL_ZONE self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
||||
-- @param #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
|
||||
--- Synchronous Event Trigger for Event Route.
|
||||
-- @function [parent=#AI_PATROL_ZONE] Route
|
||||
-- @param #AI_PATROL_ZONE self
|
||||
|
||||
--- Asynchronous Event Trigger for Event Route.
|
||||
-- @function [parent=#AI_PATROL_ZONE] __Route
|
||||
-- @param #AI_PATROL_ZONE self
|
||||
-- @param #number Delay The delay in seconds.
|
||||
|
||||
self:AddTransition( "*", "Status", "*" ) -- FSM_CONTROLLABLE Transition for type #AI_PATROL_ZONE.
|
||||
|
||||
--- OnBefore Transition Handler for Event Status.
|
||||
-- @function [parent=#AI_PATROL_ZONE] OnBeforeStatus
|
||||
-- @param #AI_PATROL_ZONE self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
||||
-- @param #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
-- @return #boolean Return false to cancel Transition.
|
||||
|
||||
--- OnAfter Transition Handler for Event Status.
|
||||
-- @function [parent=#AI_PATROL_ZONE] OnAfterStatus
|
||||
-- @param #AI_PATROL_ZONE self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
||||
-- @param #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
|
||||
--- Synchronous Event Trigger for Event Status.
|
||||
-- @function [parent=#AI_PATROL_ZONE] Status
|
||||
-- @param #AI_PATROL_ZONE self
|
||||
|
||||
--- Asynchronous Event Trigger for Event Status.
|
||||
-- @function [parent=#AI_PATROL_ZONE] __Status
|
||||
-- @param #AI_PATROL_ZONE self
|
||||
-- @param #number Delay The delay in seconds.
|
||||
|
||||
self:AddTransition( "*", "Detect", "*" ) -- FSM_CONTROLLABLE Transition for type #AI_PATROL_ZONE.
|
||||
|
||||
--- OnBefore Transition Handler for Event Detect.
|
||||
-- @function [parent=#AI_PATROL_ZONE] OnBeforeDetect
|
||||
-- @param #AI_PATROL_ZONE self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
||||
-- @param #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
-- @return #boolean Return false to cancel Transition.
|
||||
|
||||
--- OnAfter Transition Handler for Event Detect.
|
||||
-- @function [parent=#AI_PATROL_ZONE] OnAfterDetect
|
||||
-- @param #AI_PATROL_ZONE self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
||||
-- @param #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
|
||||
--- Synchronous Event Trigger for Event Detect.
|
||||
-- @function [parent=#AI_PATROL_ZONE] Detect
|
||||
-- @param #AI_PATROL_ZONE self
|
||||
|
||||
--- Asynchronous Event Trigger for Event Detect.
|
||||
-- @function [parent=#AI_PATROL_ZONE] __Detect
|
||||
-- @param #AI_PATROL_ZONE self
|
||||
-- @param #number Delay The delay in seconds.
|
||||
|
||||
self:AddTransition( "*", "Detected", "*" ) -- FSM_CONTROLLABLE Transition for type #AI_PATROL_ZONE.
|
||||
|
||||
--- OnBefore Transition Handler for Event Detected.
|
||||
-- @function [parent=#AI_PATROL_ZONE] OnBeforeDetected
|
||||
-- @param #AI_PATROL_ZONE self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
||||
-- @param #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
-- @return #boolean Return false to cancel Transition.
|
||||
|
||||
--- OnAfter Transition Handler for Event Detected.
|
||||
-- @function [parent=#AI_PATROL_ZONE] OnAfterDetected
|
||||
-- @param #AI_PATROL_ZONE self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
||||
-- @param #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
|
||||
--- Synchronous Event Trigger for Event Detected.
|
||||
-- @function [parent=#AI_PATROL_ZONE] Detected
|
||||
-- @param #AI_PATROL_ZONE self
|
||||
|
||||
--- Asynchronous Event Trigger for Event Detected.
|
||||
-- @function [parent=#AI_PATROL_ZONE] __Detected
|
||||
-- @param #AI_PATROL_ZONE self
|
||||
-- @param #number Delay The delay in seconds.
|
||||
|
||||
self:AddTransition( "*", "RTB", "Returning" ) -- FSM_CONTROLLABLE Transition for type #AI_PATROL_ZONE.
|
||||
|
||||
--- OnBefore Transition Handler for Event RTB.
|
||||
-- @function [parent=#AI_PATROL_ZONE] OnBeforeRTB
|
||||
-- @param #AI_PATROL_ZONE self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
||||
-- @param #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
-- @return #boolean Return false to cancel Transition.
|
||||
|
||||
--- OnAfter Transition Handler for Event RTB.
|
||||
-- @function [parent=#AI_PATROL_ZONE] OnAfterRTB
|
||||
-- @param #AI_PATROL_ZONE self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
||||
-- @param #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
|
||||
--- Synchronous Event Trigger for Event RTB.
|
||||
-- @function [parent=#AI_PATROL_ZONE] RTB
|
||||
-- @param #AI_PATROL_ZONE self
|
||||
|
||||
--- Asynchronous Event Trigger for Event RTB.
|
||||
-- @function [parent=#AI_PATROL_ZONE] __RTB
|
||||
-- @param #AI_PATROL_ZONE self
|
||||
-- @param #number Delay The delay in seconds.
|
||||
|
||||
--- OnLeave Transition Handler for State Returning.
|
||||
-- @function [parent=#AI_PATROL_ZONE] OnLeaveReturning
|
||||
-- @param #AI_PATROL_ZONE self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
||||
-- @param #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
-- @return #boolean Return false to cancel Transition.
|
||||
|
||||
--- OnEnter Transition Handler for State Returning.
|
||||
-- @function [parent=#AI_PATROL_ZONE] OnEnterReturning
|
||||
-- @param #AI_PATROL_ZONE self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
||||
-- @param #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
|
||||
self:AddTransition( "*", "Reset", "Patrolling" ) -- FSM_CONTROLLABLE Transition for type #AI_PATROL_ZONE.
|
||||
|
||||
self:AddTransition( "*", "Eject", "*" )
|
||||
self:AddTransition( "*", "Crash", "Crashed" )
|
||||
self:AddTransition( "*", "PilotDead", "*" )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
--- Sets (modifies) the minimum and maximum speed of the patrol.
|
||||
-- @param #AI_PATROL_ZONE self
|
||||
-- @param Dcs.DCSTypes#Speed PatrolMinSpeed The minimum speed of the @{Controllable} in km/h.
|
||||
-- @param Dcs.DCSTypes#Speed PatrolMaxSpeed The maximum speed of the @{Controllable} in km/h.
|
||||
-- @return #AI_PATROL_ZONE self
|
||||
function AI_PATROL_ZONE:SetSpeed( PatrolMinSpeed, PatrolMaxSpeed )
|
||||
self:F2( { PatrolMinSpeed, PatrolMaxSpeed } )
|
||||
|
||||
self.PatrolMinSpeed = PatrolMinSpeed
|
||||
self.PatrolMaxSpeed = PatrolMaxSpeed
|
||||
end
|
||||
|
||||
|
||||
|
||||
--- Sets the floor and ceiling altitude of the patrol.
|
||||
-- @param #AI_PATROL_ZONE self
|
||||
-- @param Dcs.DCSTypes#Altitude PatrolFloorAltitude The lowest altitude in meters where to execute the patrol.
|
||||
-- @param Dcs.DCSTypes#Altitude PatrolCeilingAltitude The highest altitude in meters where to execute the patrol.
|
||||
-- @return #AI_PATROL_ZONE self
|
||||
function AI_PATROL_ZONE:SetAltitude( PatrolFloorAltitude, PatrolCeilingAltitude )
|
||||
self:F2( { PatrolFloorAltitude, PatrolCeilingAltitude } )
|
||||
|
||||
self.PatrolFloorAltitude = PatrolFloorAltitude
|
||||
self.PatrolCeilingAltitude = PatrolCeilingAltitude
|
||||
end
|
||||
|
||||
-- * @{#AI_PATROL_ZONE.SetDetectionOn}(): Set the detection on. The AI will detect for targets.
|
||||
-- * @{#AI_PATROL_ZONE.SetDetectionOff}(): Set the detection off, the AI will not detect for targets. The existing target list will NOT be erased.
|
||||
|
||||
--- Set the detection on. The AI will detect for targets.
|
||||
-- @param #AI_PATROL_ZONE self
|
||||
-- @return #AI_PATROL_ZONE self
|
||||
function AI_PATROL_ZONE:SetDetectionOn()
|
||||
self:F2()
|
||||
|
||||
self.DetectOn = true
|
||||
end
|
||||
|
||||
--- Set the detection off. The AI will NOT detect for targets.
|
||||
-- However, the list of already detected targets will be kept and can be enquired!
|
||||
-- @param #AI_PATROL_ZONE self
|
||||
-- @return #AI_PATROL_ZONE self
|
||||
function AI_PATROL_ZONE:SetDetectionOff()
|
||||
self:F2()
|
||||
|
||||
self.DetectOn = false
|
||||
end
|
||||
|
||||
--- Set the status checking off.
|
||||
-- @param #AI_PATROL_ZONE self
|
||||
-- @return #AI_PATROL_ZONE self
|
||||
function AI_PATROL_ZONE:SetStatusOff()
|
||||
self:F2()
|
||||
|
||||
self.CheckStatus = false
|
||||
end
|
||||
|
||||
--- Activate the detection. The AI will detect for targets if the Detection is switched On.
|
||||
-- @param #AI_PATROL_ZONE self
|
||||
-- @return #AI_PATROL_ZONE self
|
||||
function AI_PATROL_ZONE:SetDetectionActivated()
|
||||
self:F2()
|
||||
|
||||
self:ClearDetectedUnits()
|
||||
self.DetectActivated = true
|
||||
self:__Detect( -self.DetectInterval )
|
||||
end
|
||||
|
||||
--- Deactivate the detection. The AI will NOT detect for targets.
|
||||
-- @param #AI_PATROL_ZONE self
|
||||
-- @return #AI_PATROL_ZONE self
|
||||
function AI_PATROL_ZONE:SetDetectionDeactivated()
|
||||
self:F2()
|
||||
|
||||
self:ClearDetectedUnits()
|
||||
self.DetectActivated = false
|
||||
end
|
||||
|
||||
--- Set the interval in seconds between each detection executed by the AI.
|
||||
-- The list of already detected targets will be kept and updated.
|
||||
-- Newly detected targets will be added, but already detected targets that were
|
||||
-- not detected in this cycle, will NOT be removed!
|
||||
-- The default interval is 30 seconds.
|
||||
-- @param #AI_PATROL_ZONE self
|
||||
-- @param #number Seconds The interval in seconds.
|
||||
-- @return #AI_PATROL_ZONE self
|
||||
function AI_PATROL_ZONE:SetDetectionInterval( Seconds )
|
||||
self:F2()
|
||||
|
||||
if Seconds then
|
||||
self.DetectInterval = Seconds
|
||||
else
|
||||
self.DetectInterval = 30
|
||||
end
|
||||
end
|
||||
|
||||
--- Set the detection zone where the AI is detecting targets.
|
||||
-- @param #AI_PATROL_ZONE self
|
||||
-- @param Core.Zone#ZONE DetectionZone The zone where to detect targets.
|
||||
-- @return #AI_PATROL_ZONE self
|
||||
function AI_PATROL_ZONE:SetDetectionZone( DetectionZone )
|
||||
self:F2()
|
||||
|
||||
if DetectionZone then
|
||||
self.DetectZone = DetectionZone
|
||||
else
|
||||
self.DetectZone = nil
|
||||
end
|
||||
end
|
||||
|
||||
--- Gets a list of @{Unit#UNIT}s that were detected by the AI.
|
||||
-- No filtering is applied, so, ANY detected UNIT can be in this list.
|
||||
-- It is up to the mission designer to use the @{Unit} class and methods to filter the targets.
|
||||
-- @param #AI_PATROL_ZONE self
|
||||
-- @return #table The list of @{Unit#UNIT}s
|
||||
function AI_PATROL_ZONE:GetDetectedUnits()
|
||||
self:F2()
|
||||
|
||||
return self.DetectedUnits
|
||||
end
|
||||
|
||||
--- Clears the list of @{Unit#UNIT}s that were detected by the AI.
|
||||
-- @param #AI_PATROL_ZONE self
|
||||
function AI_PATROL_ZONE:ClearDetectedUnits()
|
||||
self:F2()
|
||||
self.DetectedUnits = {}
|
||||
end
|
||||
|
||||
--- When the AI is out of fuel, it is required that a new AI is started, before the old AI can return to the home base.
|
||||
-- Therefore, with a parameter and a calculation of the distance to the home base, the fuel treshold is calculated.
|
||||
-- When the fuel treshold is reached, the AI will continue for a given time its patrol task in orbit, while a new AIControllable is targetted to the AI_PATROL_ZONE.
|
||||
-- Once the time is finished, the old AI will return to the base.
|
||||
-- @param #AI_PATROL_ZONE self
|
||||
-- @param #number PatrolFuelTresholdPercentage The treshold in percentage (between 0 and 1) when the AIControllable is considered to get out of fuel.
|
||||
-- @param #number PatrolOutOfFuelOrbitTime The amount of seconds the out of fuel AIControllable will orbit before returning to the base.
|
||||
-- @return #AI_PATROL_ZONE self
|
||||
function AI_PATROL_ZONE:ManageFuel( PatrolFuelTresholdPercentage, PatrolOutOfFuelOrbitTime )
|
||||
|
||||
self.PatrolManageFuel = true
|
||||
self.PatrolFuelTresholdPercentage = PatrolFuelTresholdPercentage
|
||||
self.PatrolOutOfFuelOrbitTime = PatrolOutOfFuelOrbitTime
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- When the AI is damaged beyond a certain treshold, it is required that the AI returns to the home base.
|
||||
-- However, damage cannot be foreseen early on.
|
||||
-- Therefore, when the damage treshold is reached,
|
||||
-- the AI will return immediately to the home base (RTB).
|
||||
-- Note that for groups, the average damage of the complete group will be calculated.
|
||||
-- So, in a group of 4 airplanes, 2 lost and 2 with damage 0.2, the damage treshold will be 0.25.
|
||||
-- @param #AI_PATROL_ZONE self
|
||||
-- @param #number PatrolDamageTreshold The treshold in percentage (between 0 and 1) when the AI is considered to be damaged.
|
||||
-- @return #AI_PATROL_ZONE self
|
||||
function AI_PATROL_ZONE:ManageDamage( PatrolDamageTreshold )
|
||||
|
||||
self.PatrolManageDamage = true
|
||||
self.PatrolDamageTreshold = PatrolDamageTreshold
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Defines a new patrol route using the @{Process_PatrolZone} parameters and settings.
|
||||
-- @param #AI_PATROL_ZONE self
|
||||
-- @return #AI_PATROL_ZONE self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
||||
-- @param #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
function AI_PATROL_ZONE:onafterStart( Controllable, From, Event, To )
|
||||
self:F2()
|
||||
|
||||
self:__Route( 1 ) -- Route to the patrol point. The asynchronous trigger is important, because a spawned group and units takes at least one second to come live.
|
||||
self:__Status( 60 ) -- Check status status every 30 seconds.
|
||||
self:SetDetectionActivated()
|
||||
|
||||
self:HandleEvent( EVENTS.PilotDead, self.OnPilotDead )
|
||||
self:HandleEvent( EVENTS.Crash, self.OnCrash )
|
||||
self:HandleEvent( EVENTS.Ejection, self.OnEjection )
|
||||
|
||||
Controllable:OptionROEHoldFire()
|
||||
Controllable:OptionROTVertical()
|
||||
|
||||
self.Controllable:OnReSpawn(
|
||||
function( PatrolGroup )
|
||||
self:E( "ReSpawn" )
|
||||
self:__Reset( 1 )
|
||||
self:__Route( 5 )
|
||||
end
|
||||
)
|
||||
|
||||
self:SetDetectionOn()
|
||||
|
||||
end
|
||||
|
||||
|
||||
--- @param #AI_PATROL_ZONE self
|
||||
--- @param Wrapper.Controllable#CONTROLLABLE Controllable
|
||||
function AI_PATROL_ZONE:onbeforeDetect( Controllable, From, Event, To )
|
||||
|
||||
return self.DetectOn and self.DetectActivated
|
||||
end
|
||||
|
||||
--- @param #AI_PATROL_ZONE self
|
||||
--- @param Wrapper.Controllable#CONTROLLABLE Controllable
|
||||
function AI_PATROL_ZONE:onafterDetect( Controllable, From, Event, To )
|
||||
|
||||
local Detected = false
|
||||
|
||||
local DetectedTargets = Controllable:GetDetectedTargets()
|
||||
for TargetID, Target in pairs( DetectedTargets or {} ) do
|
||||
local TargetObject = Target.object
|
||||
|
||||
if TargetObject and TargetObject:isExist() and TargetObject.id_ < 50000000 then
|
||||
|
||||
local TargetUnit = UNIT:Find( TargetObject )
|
||||
local TargetUnitName = TargetUnit:GetName()
|
||||
|
||||
if self.DetectionZone then
|
||||
if TargetUnit:IsInZone( self.DetectionZone ) then
|
||||
self:T( {"Detected ", TargetUnit } )
|
||||
if self.DetectedUnits[TargetUnit] == nil then
|
||||
self.DetectedUnits[TargetUnit] = true
|
||||
end
|
||||
Detected = true
|
||||
end
|
||||
else
|
||||
if self.DetectedUnits[TargetUnit] == nil then
|
||||
self.DetectedUnits[TargetUnit] = true
|
||||
end
|
||||
Detected = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
self:__Detect( -self.DetectInterval )
|
||||
|
||||
if Detected == true then
|
||||
self:__Detected( 1.5 )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--- @param Wrapper.Controllable#CONTROLLABLE AIControllable
|
||||
-- This statis method is called from the route path within the last task at the last waaypoint of the Controllable.
|
||||
-- Note that this method is required, as triggers the next route when patrolling for the Controllable.
|
||||
function AI_PATROL_ZONE:_NewPatrolRoute( AIControllable )
|
||||
|
||||
local PatrolZone = AIControllable:GetState( AIControllable, "PatrolZone" ) -- PatrolCore.Zone#AI_PATROL_ZONE
|
||||
PatrolZone:__Route( 1 )
|
||||
end
|
||||
|
||||
|
||||
--- Defines a new patrol route using the @{Process_PatrolZone} parameters and settings.
|
||||
-- @param #AI_PATROL_ZONE self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
||||
-- @param #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
function AI_PATROL_ZONE:onafterRoute( Controllable, From, Event, To )
|
||||
|
||||
self:F2()
|
||||
|
||||
-- When RTB, don't allow anymore the routing.
|
||||
if From == "RTB" then
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
if self.Controllable:IsAlive() then
|
||||
-- Determine if the AIControllable is within the PatrolZone.
|
||||
-- If not, make a waypoint within the to that the AIControllable will fly at maximum speed to that point.
|
||||
|
||||
local PatrolRoute = {}
|
||||
|
||||
-- Calculate the current route point of the controllable as the start point of the route.
|
||||
-- However, when the controllable is not in the air,
|
||||
-- the controllable current waypoint is probably the airbase...
|
||||
-- Thus, if we would take the current waypoint as the startpoint, upon take-off, the controllable flies
|
||||
-- immediately back to the airbase, and this is not correct.
|
||||
-- Therefore, when on a runway, get as the current route point a random point within the PatrolZone.
|
||||
-- This will make the plane fly immediately to the patrol zone.
|
||||
|
||||
if self.Controllable:InAir() == false then
|
||||
self:E( "Not in the air, finding route path within PatrolZone" )
|
||||
local CurrentVec2 = self.Controllable:GetVec2()
|
||||
--TODO: Create GetAltitude function for GROUP, and delete GetUnit(1).
|
||||
local CurrentAltitude = self.Controllable:GetUnit(1):GetAltitude()
|
||||
local CurrentPointVec3 = POINT_VEC3:New( CurrentVec2.x, CurrentAltitude, CurrentVec2.y )
|
||||
local ToPatrolZoneSpeed = self.PatrolMaxSpeed
|
||||
local CurrentRoutePoint = CurrentPointVec3:RoutePointAir(
|
||||
self.PatrolAltType,
|
||||
POINT_VEC3.RoutePointType.TakeOffParking,
|
||||
POINT_VEC3.RoutePointAction.FromParkingArea,
|
||||
ToPatrolZoneSpeed,
|
||||
true
|
||||
)
|
||||
PatrolRoute[#PatrolRoute+1] = CurrentRoutePoint
|
||||
else
|
||||
self:E( "In the air, finding route path within PatrolZone" )
|
||||
local CurrentVec2 = self.Controllable:GetVec2()
|
||||
--TODO: Create GetAltitude function for GROUP, and delete GetUnit(1).
|
||||
local CurrentAltitude = self.Controllable:GetUnit(1):GetAltitude()
|
||||
local CurrentPointVec3 = POINT_VEC3:New( CurrentVec2.x, CurrentAltitude, CurrentVec2.y )
|
||||
local ToPatrolZoneSpeed = self.PatrolMaxSpeed
|
||||
local CurrentRoutePoint = CurrentPointVec3:RoutePointAir(
|
||||
self.PatrolAltType,
|
||||
POINT_VEC3.RoutePointType.TurningPoint,
|
||||
POINT_VEC3.RoutePointAction.TurningPoint,
|
||||
ToPatrolZoneSpeed,
|
||||
true
|
||||
)
|
||||
PatrolRoute[#PatrolRoute+1] = CurrentRoutePoint
|
||||
end
|
||||
|
||||
|
||||
--- Define a random point in the @{Zone}. The AI will fly to that point within the zone.
|
||||
|
||||
--- Find a random 2D point in PatrolZone.
|
||||
local ToTargetVec2 = self.PatrolZone:GetRandomVec2()
|
||||
self:T2( ToTargetVec2 )
|
||||
|
||||
--- Define Speed and Altitude.
|
||||
local ToTargetAltitude = math.random( self.PatrolFloorAltitude, self.PatrolCeilingAltitude )
|
||||
local ToTargetSpeed = math.random( self.PatrolMinSpeed, self.PatrolMaxSpeed )
|
||||
self:T2( { self.PatrolMinSpeed, self.PatrolMaxSpeed, ToTargetSpeed } )
|
||||
|
||||
--- Obtain a 3D @{Point} from the 2D point + altitude.
|
||||
local ToTargetPointVec3 = POINT_VEC3:New( ToTargetVec2.x, ToTargetAltitude, ToTargetVec2.y )
|
||||
|
||||
--- Create a route point of type air.
|
||||
local ToTargetRoutePoint = ToTargetPointVec3:RoutePointAir(
|
||||
self.PatrolAltType,
|
||||
POINT_VEC3.RoutePointType.TurningPoint,
|
||||
POINT_VEC3.RoutePointAction.TurningPoint,
|
||||
ToTargetSpeed,
|
||||
true
|
||||
)
|
||||
|
||||
--self.CoordTest:SpawnFromVec3( ToTargetPointVec3:GetVec3() )
|
||||
|
||||
--ToTargetPointVec3:SmokeRed()
|
||||
|
||||
PatrolRoute[#PatrolRoute+1] = ToTargetRoutePoint
|
||||
|
||||
--- Now we're going to do something special, we're going to call a function from a waypoint action at the AIControllable...
|
||||
self.Controllable:WayPointInitialize( PatrolRoute )
|
||||
|
||||
--- Do a trick, link the NewPatrolRoute function of the PATROLGROUP object to the AIControllable in a temporary variable ...
|
||||
self.Controllable:SetState( self.Controllable, "PatrolZone", self )
|
||||
self.Controllable:WayPointFunction( #PatrolRoute, 1, "AI_PATROL_ZONE:_NewPatrolRoute" )
|
||||
|
||||
--- NOW ROUTE THE GROUP!
|
||||
self.Controllable:WayPointExecute( 1, 2 )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--- @param #AI_PATROL_ZONE self
|
||||
function AI_PATROL_ZONE:onbeforeStatus()
|
||||
|
||||
return self.CheckStatus
|
||||
end
|
||||
|
||||
--- @param #AI_PATROL_ZONE self
|
||||
function AI_PATROL_ZONE:onafterStatus()
|
||||
self:F2()
|
||||
|
||||
if self.Controllable and self.Controllable:IsAlive() then
|
||||
|
||||
local RTB = false
|
||||
|
||||
local Fuel = self.Controllable:GetUnit(1):GetFuel()
|
||||
if Fuel < self.PatrolFuelTresholdPercentage then
|
||||
self:E( self.Controllable:GetName() .. " is out of fuel:" .. Fuel .. ", RTB!" )
|
||||
local OldAIControllable = self.Controllable
|
||||
local AIControllableTemplate = self.Controllable:GetTemplate()
|
||||
|
||||
local OrbitTask = OldAIControllable:TaskOrbitCircle( math.random( self.PatrolFloorAltitude, self.PatrolCeilingAltitude ), self.PatrolMinSpeed )
|
||||
local TimedOrbitTask = OldAIControllable:TaskControlled( OrbitTask, OldAIControllable:TaskCondition(nil,nil,nil,nil,self.PatrolOutOfFuelOrbitTime,nil ) )
|
||||
OldAIControllable:SetTask( TimedOrbitTask, 10 )
|
||||
|
||||
RTB = true
|
||||
else
|
||||
end
|
||||
|
||||
-- TODO: Check GROUP damage function.
|
||||
local Damage = self.Controllable:GetLife()
|
||||
if Damage <= self.PatrolDamageTreshold then
|
||||
self:E( self.Controllable:GetName() .. " is damaged:" .. Damage .. ", RTB!" )
|
||||
RTB = true
|
||||
end
|
||||
|
||||
if RTB == true then
|
||||
self:RTB()
|
||||
else
|
||||
self:__Status( 60 ) -- Execute the Patrol event after 30 seconds.
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- @param #AI_PATROL_ZONE self
|
||||
function AI_PATROL_ZONE:onafterRTB()
|
||||
self:F2()
|
||||
|
||||
if self.Controllable and self.Controllable:IsAlive() then
|
||||
|
||||
self:SetDetectionOff()
|
||||
self.CheckStatus = false
|
||||
|
||||
local PatrolRoute = {}
|
||||
|
||||
--- Calculate the current route point.
|
||||
local CurrentVec2 = self.Controllable:GetVec2()
|
||||
|
||||
--TODO: Create GetAltitude function for GROUP, and delete GetUnit(1).
|
||||
local CurrentAltitude = self.Controllable:GetUnit(1):GetAltitude()
|
||||
local CurrentPointVec3 = POINT_VEC3:New( CurrentVec2.x, CurrentAltitude, CurrentVec2.y )
|
||||
local ToPatrolZoneSpeed = self.PatrolMaxSpeed
|
||||
local CurrentRoutePoint = CurrentPointVec3:RoutePointAir(
|
||||
self.PatrolAltType,
|
||||
POINT_VEC3.RoutePointType.TurningPoint,
|
||||
POINT_VEC3.RoutePointAction.TurningPoint,
|
||||
ToPatrolZoneSpeed,
|
||||
true
|
||||
)
|
||||
|
||||
PatrolRoute[#PatrolRoute+1] = CurrentRoutePoint
|
||||
|
||||
--- Now we're going to do something special, we're going to call a function from a waypoint action at the AIControllable...
|
||||
self.Controllable:WayPointInitialize( PatrolRoute )
|
||||
|
||||
--- NOW ROUTE THE GROUP!
|
||||
self.Controllable:WayPointExecute( 1, 1 )
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--- @param #AI_PATROL_ZONE self
|
||||
function AI_PATROL_ZONE:onafterDead()
|
||||
self:SetDetectionOff()
|
||||
self:SetStatusOff()
|
||||
end
|
||||
|
||||
--- @param #AI_PATROL_ZONE self
|
||||
-- @param Core.Event#EVENTDATA EventData
|
||||
function AI_PATROL_ZONE:OnCrash( EventData )
|
||||
|
||||
if self.Controllable:IsAlive() and EventData.IniDCSGroupName == self.Controllable:GetName() then
|
||||
self:E( self.Controllable:GetUnits() )
|
||||
if #self.Controllable:GetUnits() == 1 then
|
||||
self:__Crash( 1, EventData )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- @param #AI_PATROL_ZONE self
|
||||
-- @param Core.Event#EVENTDATA EventData
|
||||
function AI_PATROL_ZONE:OnEjection( EventData )
|
||||
|
||||
if self.Controllable:IsAlive() and EventData.IniDCSGroupName == self.Controllable:GetName() then
|
||||
self:__Eject( 1, EventData )
|
||||
end
|
||||
end
|
||||
|
||||
--- @param #AI_PATROL_ZONE self
|
||||
-- @param Core.Event#EVENTDATA EventData
|
||||
function AI_PATROL_ZONE:OnPilotDead( EventData )
|
||||
|
||||
if self.Controllable:IsAlive() and EventData.IniDCSGroupName == self.Controllable:GetName() then
|
||||
self:__PilotDead( 1, EventData )
|
||||
end
|
||||
end
|
||||
266
Moose Development/Moose/Actions/Act_Account.lua
Normal file
266
Moose Development/Moose/Actions/Act_Account.lua
Normal file
@@ -0,0 +1,266 @@
|
||||
--- (SP) (MP) (FSM) Account for (Detect, count and report) DCS events occuring on DCS objects (units).
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- # @{#ACT_ACCOUNT} FSM class, extends @{Fsm#FSM_PROCESS}
|
||||
--
|
||||
-- ## ACT_ACCOUNT state machine:
|
||||
--
|
||||
-- This class is a state machine: it manages a process that is triggered by events causing state transitions to occur.
|
||||
-- All derived classes from this class will start with the class name, followed by a \_. See the relevant derived class descriptions below.
|
||||
-- Each derived class follows exactly the same process, using the same events and following the same state transitions,
|
||||
-- but will have **different implementation behaviour** upon each event or state transition.
|
||||
--
|
||||
-- ### ACT_ACCOUNT **Events**:
|
||||
--
|
||||
-- These are the events defined in this class:
|
||||
--
|
||||
-- * **Start**: The process is started. The process will go into the Report state.
|
||||
-- * **Event**: A relevant event has occured that needs to be accounted for. The process will go into the Account state.
|
||||
-- * **Report**: The process is reporting to the player the accounting status of the DCS events.
|
||||
-- * **More**: There are more DCS events that need to be accounted for. The process will go back into the Report state.
|
||||
-- * **NoMore**: There are no more DCS events that need to be accounted for. The process will go into the Success state.
|
||||
--
|
||||
-- ### ACT_ACCOUNT **Event methods**:
|
||||
--
|
||||
-- Event methods are available (dynamically allocated by the state machine), that accomodate for state transitions occurring in the process.
|
||||
-- There are two types of event methods, which you can use to influence the normal mechanisms in the state machine:
|
||||
--
|
||||
-- * **Immediate**: The event method has exactly the name of the event.
|
||||
-- * **Delayed**: The event method starts with a __ + the name of the event. The first parameter of the event method is a number value, expressing the delay in seconds when the event will be executed.
|
||||
--
|
||||
-- ### ACT_ACCOUNT **States**:
|
||||
--
|
||||
-- * **Assigned**: The player is assigned to the task. This is the initialization state for the process.
|
||||
-- * **Waiting**: the process is waiting for a DCS event to occur within the simulator. This state is set automatically.
|
||||
-- * **Report**: The process is Reporting to the players in the group of the unit. This state is set automatically every 30 seconds.
|
||||
-- * **Account**: The relevant DCS event has occurred, and is accounted for.
|
||||
-- * **Success (*)**: All DCS events were accounted for.
|
||||
-- * **Failed (*)**: The process has failed.
|
||||
--
|
||||
-- (*) End states of the process.
|
||||
--
|
||||
-- ### ACT_ACCOUNT state transition methods:
|
||||
--
|
||||
-- State transition functions can be set **by the mission designer** customizing or improving the behaviour of the state.
|
||||
-- There are 2 moments when state transition methods will be called by the state machine:
|
||||
--
|
||||
-- * **Before** the state transition.
|
||||
-- The state transition method needs to start with the name **OnBefore + the name of the state**.
|
||||
-- If the state transition method returns false, then the processing of the state transition will not be done!
|
||||
-- If you want to change the behaviour of the AIControllable at this event, return false,
|
||||
-- but then you'll need to specify your own logic using the AIControllable!
|
||||
--
|
||||
-- * **After** the state transition.
|
||||
-- The state transition method needs to start with the name **OnAfter + the name of the state**.
|
||||
-- These state transition methods need to provide a return value, which is specified at the function description.
|
||||
--
|
||||
-- # 1) @{#ACT_ACCOUNT_DEADS} FSM class, extends @{Fsm.Account#ACT_ACCOUNT}
|
||||
--
|
||||
-- The ACT_ACCOUNT_DEADS class accounts (detects, counts and reports) successful kills of DCS units.
|
||||
-- The process is given a @{Set} of units that will be tracked upon successful destruction.
|
||||
-- The process will end after each target has been successfully destroyed.
|
||||
-- Each successful dead will trigger an Account state transition that can be scored, modified or administered.
|
||||
--
|
||||
--
|
||||
-- ## ACT_ACCOUNT_DEADS constructor:
|
||||
--
|
||||
-- * @{#ACT_ACCOUNT_DEADS.New}(): Creates a new ACT_ACCOUNT_DEADS object.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- @module Account
|
||||
|
||||
|
||||
do -- ACT_ACCOUNT
|
||||
|
||||
--- ACT_ACCOUNT class
|
||||
-- @type ACT_ACCOUNT
|
||||
-- @field Set#SET_UNIT TargetSetUnit
|
||||
-- @extends Core.Fsm#FSM_PROCESS
|
||||
ACT_ACCOUNT = {
|
||||
ClassName = "ACT_ACCOUNT",
|
||||
TargetSetUnit = nil,
|
||||
}
|
||||
|
||||
--- Creates a new DESTROY process.
|
||||
-- @param #ACT_ACCOUNT self
|
||||
-- @return #ACT_ACCOUNT
|
||||
function ACT_ACCOUNT:New()
|
||||
|
||||
-- Inherits from BASE
|
||||
local self = BASE:Inherit( self, FSM_PROCESS:New() ) -- Core.Fsm#FSM_PROCESS
|
||||
|
||||
self:AddTransition( "Assigned", "Start", "Waiting")
|
||||
self:AddTransition( "*", "Wait", "Waiting")
|
||||
self:AddTransition( "*", "Report", "Report")
|
||||
self:AddTransition( "*", "Event", "Account")
|
||||
self:AddTransition( "Account", "More", "Wait")
|
||||
self:AddTransition( "Account", "NoMore", "Accounted")
|
||||
self:AddTransition( "*", "Fail", "Failed")
|
||||
|
||||
self:AddEndState( "Accounted" )
|
||||
self:AddEndState( "Failed" )
|
||||
|
||||
self:SetStartState( "Assigned" )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Process Events
|
||||
|
||||
--- StateMachine callback function
|
||||
-- @param #ACT_ACCOUNT self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE ProcessUnit
|
||||
-- @param #string Event
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
function ACT_ACCOUNT:onafterStart( ProcessUnit, From, Event, To )
|
||||
|
||||
self:HandleEvent( EVENTS.Dead, self.onfuncEventDead )
|
||||
|
||||
self:__Wait( 1 )
|
||||
end
|
||||
|
||||
|
||||
--- StateMachine callback function
|
||||
-- @param #ACT_ACCOUNT self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE ProcessUnit
|
||||
-- @param #string Event
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
function ACT_ACCOUNT:onenterWaiting( ProcessUnit, From, Event, To )
|
||||
|
||||
if self.DisplayCount >= self.DisplayInterval then
|
||||
self:Report()
|
||||
self.DisplayCount = 1
|
||||
else
|
||||
self.DisplayCount = self.DisplayCount + 1
|
||||
end
|
||||
|
||||
return true -- Process always the event.
|
||||
end
|
||||
|
||||
--- StateMachine callback function
|
||||
-- @param #ACT_ACCOUNT self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE ProcessUnit
|
||||
-- @param #string Event
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
function ACT_ACCOUNT:onafterEvent( ProcessUnit, From, Event, To, Event )
|
||||
|
||||
self:__NoMore( 1 )
|
||||
end
|
||||
|
||||
end -- ACT_ACCOUNT
|
||||
|
||||
do -- ACT_ACCOUNT_DEADS
|
||||
|
||||
--- ACT_ACCOUNT_DEADS class
|
||||
-- @type ACT_ACCOUNT_DEADS
|
||||
-- @field Set#SET_UNIT TargetSetUnit
|
||||
-- @extends #ACT_ACCOUNT
|
||||
ACT_ACCOUNT_DEADS = {
|
||||
ClassName = "ACT_ACCOUNT_DEADS",
|
||||
TargetSetUnit = nil,
|
||||
}
|
||||
|
||||
|
||||
--- Creates a new DESTROY process.
|
||||
-- @param #ACT_ACCOUNT_DEADS self
|
||||
-- @param Set#SET_UNIT TargetSetUnit
|
||||
-- @param #string TaskName
|
||||
function ACT_ACCOUNT_DEADS:New( TargetSetUnit, TaskName )
|
||||
-- Inherits from BASE
|
||||
local self = BASE:Inherit( self, ACT_ACCOUNT:New() ) -- #ACT_ACCOUNT_DEADS
|
||||
|
||||
self.TargetSetUnit = TargetSetUnit
|
||||
self.TaskName = TaskName
|
||||
|
||||
self.DisplayInterval = 30
|
||||
self.DisplayCount = 30
|
||||
self.DisplayMessage = true
|
||||
self.DisplayTime = 10 -- 10 seconds is the default
|
||||
self.DisplayCategory = "HQ" -- Targets is the default display category
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function ACT_ACCOUNT_DEADS:Init( FsmAccount )
|
||||
|
||||
self.TargetSetUnit = FsmAccount.TargetSetUnit
|
||||
self.TaskName = FsmAccount.TaskName
|
||||
end
|
||||
|
||||
|
||||
|
||||
function ACT_ACCOUNT_DEADS:_Destructor()
|
||||
self:E("_Destructor")
|
||||
|
||||
self:EventRemoveAll()
|
||||
|
||||
end
|
||||
|
||||
--- Process Events
|
||||
|
||||
--- StateMachine callback function
|
||||
-- @param #ACT_ACCOUNT_DEADS self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE ProcessUnit
|
||||
-- @param #string Event
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
function ACT_ACCOUNT_DEADS:onenterReport( ProcessUnit, From, Event, To )
|
||||
self:E( { ProcessUnit, From, Event, To } )
|
||||
|
||||
self:Message( "Your group with assigned " .. self.TaskName .. " task has " .. self.TargetSetUnit:GetUnitTypesText() .. " targets left to be destroyed." )
|
||||
end
|
||||
|
||||
|
||||
--- StateMachine callback function
|
||||
-- @param #ACT_ACCOUNT_DEADS self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE ProcessUnit
|
||||
-- @param #string Event
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
function ACT_ACCOUNT_DEADS:onenterAccount( ProcessUnit, From, Event, To, EventData )
|
||||
self:T( { ProcessUnit, EventData, From, Event, To } )
|
||||
|
||||
self:T({self.Controllable})
|
||||
|
||||
self.TargetSetUnit:Flush()
|
||||
|
||||
if self.TargetSetUnit:FindUnit( EventData.IniUnitName ) then
|
||||
local TaskGroup = ProcessUnit:GetGroup()
|
||||
self.TargetSetUnit:RemoveUnitsByName( EventData.IniUnitName )
|
||||
self:Message( "You hit a target. Your group with assigned " .. self.TaskName .. " task has " .. self.TargetSetUnit:Count() .. " targets ( " .. self.TargetSetUnit:GetUnitTypesText() .. " ) left to be destroyed." )
|
||||
end
|
||||
end
|
||||
|
||||
--- StateMachine callback function
|
||||
-- @param #ACT_ACCOUNT_DEADS self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE ProcessUnit
|
||||
-- @param #string Event
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
function ACT_ACCOUNT_DEADS:onafterEvent( ProcessUnit, From, Event, To, EventData )
|
||||
|
||||
if self.TargetSetUnit:Count() > 0 then
|
||||
self:__More( 1 )
|
||||
else
|
||||
self:__NoMore( 1 )
|
||||
end
|
||||
end
|
||||
|
||||
--- DCS Events
|
||||
|
||||
--- @param #ACT_ACCOUNT_DEADS self
|
||||
-- @param Event#EVENTDATA EventData
|
||||
function ACT_ACCOUNT_DEADS:onfuncEventDead( EventData )
|
||||
self:T( { "EventDead", EventData } )
|
||||
|
||||
if EventData.IniDCSUnit then
|
||||
self:__Event( 1, EventData )
|
||||
end
|
||||
end
|
||||
|
||||
end -- ACT_ACCOUNT DEADS
|
||||
293
Moose Development/Moose/Actions/Act_Assign.lua
Normal file
293
Moose Development/Moose/Actions/Act_Assign.lua
Normal file
@@ -0,0 +1,293 @@
|
||||
--- (SP) (MP) (FSM) Accept or reject process for player (task) assignments.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- # @{#ACT_ASSIGN} FSM template class, extends @{Fsm#FSM_PROCESS}
|
||||
--
|
||||
-- ## ACT_ASSIGN state machine:
|
||||
--
|
||||
-- This class is a state machine: it manages a process that is triggered by events causing state transitions to occur.
|
||||
-- All derived classes from this class will start with the class name, followed by a \_. See the relevant derived class descriptions below.
|
||||
-- Each derived class follows exactly the same process, using the same events and following the same state transitions,
|
||||
-- but will have **different implementation behaviour** upon each event or state transition.
|
||||
--
|
||||
-- ### ACT_ASSIGN **Events**:
|
||||
--
|
||||
-- These are the events defined in this class:
|
||||
--
|
||||
-- * **Start**: Start the tasking acceptance process.
|
||||
-- * **Assign**: Assign the task.
|
||||
-- * **Reject**: Reject the task..
|
||||
--
|
||||
-- ### ACT_ASSIGN **Event methods**:
|
||||
--
|
||||
-- Event methods are available (dynamically allocated by the state machine), that accomodate for state transitions occurring in the process.
|
||||
-- There are two types of event methods, which you can use to influence the normal mechanisms in the state machine:
|
||||
--
|
||||
-- * **Immediate**: The event method has exactly the name of the event.
|
||||
-- * **Delayed**: The event method starts with a __ + the name of the event. The first parameter of the event method is a number value, expressing the delay in seconds when the event will be executed.
|
||||
--
|
||||
-- ### ACT_ASSIGN **States**:
|
||||
--
|
||||
-- * **UnAssigned**: The player has not accepted the task.
|
||||
-- * **Assigned (*)**: The player has accepted the task.
|
||||
-- * **Rejected (*)**: The player has not accepted the task.
|
||||
-- * **Waiting**: The process is awaiting player feedback.
|
||||
-- * **Failed (*)**: The process has failed.
|
||||
--
|
||||
-- (*) End states of the process.
|
||||
--
|
||||
-- ### ACT_ASSIGN state transition methods:
|
||||
--
|
||||
-- State transition functions can be set **by the mission designer** customizing or improving the behaviour of the state.
|
||||
-- There are 2 moments when state transition methods will be called by the state machine:
|
||||
--
|
||||
-- * **Before** the state transition.
|
||||
-- The state transition method needs to start with the name **OnBefore + the name of the state**.
|
||||
-- If the state transition method returns false, then the processing of the state transition will not be done!
|
||||
-- If you want to change the behaviour of the AIControllable at this event, return false,
|
||||
-- but then you'll need to specify your own logic using the AIControllable!
|
||||
--
|
||||
-- * **After** the state transition.
|
||||
-- The state transition method needs to start with the name **OnAfter + the name of the state**.
|
||||
-- These state transition methods need to provide a return value, which is specified at the function description.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- # 1) @{#ACT_ASSIGN_ACCEPT} class, extends @{Fsm.Assign#ACT_ASSIGN}
|
||||
--
|
||||
-- The ACT_ASSIGN_ACCEPT class accepts by default a task for a player. No player intervention is allowed to reject the task.
|
||||
--
|
||||
-- ## 1.1) ACT_ASSIGN_ACCEPT constructor:
|
||||
--
|
||||
-- * @{#ACT_ASSIGN_ACCEPT.New}(): Creates a new ACT_ASSIGN_ACCEPT object.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- # 2) @{#ACT_ASSIGN_MENU_ACCEPT} class, extends @{Fsm.Assign#ACT_ASSIGN}
|
||||
--
|
||||
-- The ACT_ASSIGN_MENU_ACCEPT class accepts a task when the player accepts the task through an added menu option.
|
||||
-- This assignment type is useful to conditionally allow the player to choose whether or not he would accept the task.
|
||||
-- The assignment type also allows to reject the task.
|
||||
--
|
||||
-- ## 2.1) ACT_ASSIGN_MENU_ACCEPT constructor:
|
||||
-- -----------------------------------------
|
||||
--
|
||||
-- * @{#ACT_ASSIGN_MENU_ACCEPT.New}(): Creates a new ACT_ASSIGN_MENU_ACCEPT object.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- @module Assign
|
||||
|
||||
|
||||
do -- ACT_ASSIGN
|
||||
|
||||
--- ACT_ASSIGN class
|
||||
-- @type ACT_ASSIGN
|
||||
-- @field Tasking.Task#TASK Task
|
||||
-- @field Wrapper.Unit#UNIT ProcessUnit
|
||||
-- @field Core.Zone#ZONE_BASE TargetZone
|
||||
-- @extends Core.Fsm#FSM_PROCESS
|
||||
ACT_ASSIGN = {
|
||||
ClassName = "ACT_ASSIGN",
|
||||
}
|
||||
|
||||
|
||||
--- Creates a new task assignment state machine. The process will accept the task by default, no player intervention accepted.
|
||||
-- @param #ACT_ASSIGN self
|
||||
-- @return #ACT_ASSIGN The task acceptance process.
|
||||
function ACT_ASSIGN:New()
|
||||
|
||||
-- Inherits from BASE
|
||||
local self = BASE:Inherit( self, FSM_PROCESS:New( "ACT_ASSIGN" ) ) -- Core.Fsm#FSM_PROCESS
|
||||
|
||||
self:AddTransition( "UnAssigned", "Start", "Waiting" )
|
||||
self:AddTransition( "Waiting", "Assign", "Assigned" )
|
||||
self:AddTransition( "Waiting", "Reject", "Rejected" )
|
||||
self:AddTransition( "*", "Fail", "Failed" )
|
||||
|
||||
self:AddEndState( "Assigned" )
|
||||
self:AddEndState( "Rejected" )
|
||||
self:AddEndState( "Failed" )
|
||||
|
||||
self:SetStartState( "UnAssigned" )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
end -- ACT_ASSIGN
|
||||
|
||||
|
||||
|
||||
do -- ACT_ASSIGN_ACCEPT
|
||||
|
||||
--- ACT_ASSIGN_ACCEPT class
|
||||
-- @type ACT_ASSIGN_ACCEPT
|
||||
-- @field Tasking.Task#TASK Task
|
||||
-- @field Wrapper.Unit#UNIT ProcessUnit
|
||||
-- @field Core.Zone#ZONE_BASE TargetZone
|
||||
-- @extends #ACT_ASSIGN
|
||||
ACT_ASSIGN_ACCEPT = {
|
||||
ClassName = "ACT_ASSIGN_ACCEPT",
|
||||
}
|
||||
|
||||
|
||||
--- Creates a new task assignment state machine. The process will accept the task by default, no player intervention accepted.
|
||||
-- @param #ACT_ASSIGN_ACCEPT self
|
||||
-- @param #string TaskBriefing
|
||||
function ACT_ASSIGN_ACCEPT:New( TaskBriefing )
|
||||
|
||||
local self = BASE:Inherit( self, ACT_ASSIGN:New() ) -- #ACT_ASSIGN_ACCEPT
|
||||
|
||||
self.TaskBriefing = TaskBriefing
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function ACT_ASSIGN_ACCEPT:Init( FsmAssign )
|
||||
|
||||
self.TaskBriefing = FsmAssign.TaskBriefing
|
||||
end
|
||||
|
||||
--- StateMachine callback function
|
||||
-- @param #ACT_ASSIGN_ACCEPT self
|
||||
-- @param Wrapper.Unit#UNIT ProcessUnit
|
||||
-- @param #string Event
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
function ACT_ASSIGN_ACCEPT:onafterStart( ProcessUnit, From, Event, To )
|
||||
self:E( { ProcessUnit, From, Event, To } )
|
||||
|
||||
self:__Assign( 1 )
|
||||
end
|
||||
|
||||
--- StateMachine callback function
|
||||
-- @param #ACT_ASSIGN_ACCEPT self
|
||||
-- @param Wrapper.Unit#UNIT ProcessUnit
|
||||
-- @param #string Event
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
function ACT_ASSIGN_ACCEPT:onenterAssigned( ProcessUnit, From, Event, To )
|
||||
env.info( "in here" )
|
||||
self:E( { ProcessUnit, From, Event, To } )
|
||||
|
||||
local ProcessGroup = ProcessUnit:GetGroup()
|
||||
|
||||
self:Message( "You are assigned to the task " .. self.Task:GetName() )
|
||||
|
||||
self.Task:Assign()
|
||||
end
|
||||
|
||||
end -- ACT_ASSIGN_ACCEPT
|
||||
|
||||
|
||||
do -- ACT_ASSIGN_MENU_ACCEPT
|
||||
|
||||
--- ACT_ASSIGN_MENU_ACCEPT class
|
||||
-- @type ACT_ASSIGN_MENU_ACCEPT
|
||||
-- @field Tasking.Task#TASK Task
|
||||
-- @field Wrapper.Unit#UNIT ProcessUnit
|
||||
-- @field Core.Zone#ZONE_BASE TargetZone
|
||||
-- @extends #ACT_ASSIGN
|
||||
ACT_ASSIGN_MENU_ACCEPT = {
|
||||
ClassName = "ACT_ASSIGN_MENU_ACCEPT",
|
||||
}
|
||||
|
||||
--- Init.
|
||||
-- @param #ACT_ASSIGN_MENU_ACCEPT self
|
||||
-- @param #string TaskName
|
||||
-- @param #string TaskBriefing
|
||||
-- @return #ACT_ASSIGN_MENU_ACCEPT self
|
||||
function ACT_ASSIGN_MENU_ACCEPT:New( TaskName, TaskBriefing )
|
||||
|
||||
-- Inherits from BASE
|
||||
local self = BASE:Inherit( self, ACT_ASSIGN:New() ) -- #ACT_ASSIGN_MENU_ACCEPT
|
||||
|
||||
self.TaskName = TaskName
|
||||
self.TaskBriefing = TaskBriefing
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function ACT_ASSIGN_MENU_ACCEPT:Init( FsmAssign )
|
||||
|
||||
self.TaskName = FsmAssign.TaskName
|
||||
self.TaskBriefing = FsmAssign.TaskBriefing
|
||||
end
|
||||
|
||||
|
||||
--- Creates a new task assignment state machine. The process will request from the menu if it accepts the task, if not, the unit is removed from the simulator.
|
||||
-- @param #ACT_ASSIGN_MENU_ACCEPT self
|
||||
-- @param #string TaskName
|
||||
-- @param #string TaskBriefing
|
||||
-- @return #ACT_ASSIGN_MENU_ACCEPT self
|
||||
function ACT_ASSIGN_MENU_ACCEPT:Init( TaskName, TaskBriefing )
|
||||
|
||||
self.TaskBriefing = TaskBriefing
|
||||
self.TaskName = TaskName
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- StateMachine callback function
|
||||
-- @param #ACT_ASSIGN_MENU_ACCEPT self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE ProcessUnit
|
||||
-- @param #string Event
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
function ACT_ASSIGN_MENU_ACCEPT:onafterStart( ProcessUnit, From, Event, To )
|
||||
self:E( { ProcessUnit, From, Event, To } )
|
||||
|
||||
self:Message( "Access the radio menu to accept the task. You have 30 seconds or the assignment will be cancelled." )
|
||||
|
||||
local ProcessGroup = ProcessUnit:GetGroup()
|
||||
|
||||
self.Menu = MENU_GROUP:New( ProcessGroup, "Task " .. self.TaskName .. " acceptance" )
|
||||
self.MenuAcceptTask = MENU_GROUP_COMMAND:New( ProcessGroup, "Accept task " .. self.TaskName, self.Menu, self.MenuAssign, self )
|
||||
self.MenuRejectTask = MENU_GROUP_COMMAND:New( ProcessGroup, "Reject task " .. self.TaskName, self.Menu, self.MenuReject, self )
|
||||
end
|
||||
|
||||
--- Menu function.
|
||||
-- @param #ACT_ASSIGN_MENU_ACCEPT self
|
||||
function ACT_ASSIGN_MENU_ACCEPT:MenuAssign()
|
||||
self:E( )
|
||||
|
||||
self:__Assign( 1 )
|
||||
end
|
||||
|
||||
--- Menu function.
|
||||
-- @param #ACT_ASSIGN_MENU_ACCEPT self
|
||||
function ACT_ASSIGN_MENU_ACCEPT:MenuReject()
|
||||
self:E( )
|
||||
|
||||
self:__Reject( 1 )
|
||||
end
|
||||
|
||||
--- StateMachine callback function
|
||||
-- @param #ACT_ASSIGN_MENU_ACCEPT self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE ProcessUnit
|
||||
-- @param #string Event
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
function ACT_ASSIGN_MENU_ACCEPT:onafterAssign( ProcessUnit, From, Event, To )
|
||||
self:E( { ProcessUnit.UnitNameFrom, Event, To } )
|
||||
|
||||
self.Menu:Remove()
|
||||
end
|
||||
|
||||
--- StateMachine callback function
|
||||
-- @param #ACT_ASSIGN_MENU_ACCEPT self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE ProcessUnit
|
||||
-- @param #string Event
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
function ACT_ASSIGN_MENU_ACCEPT:onafterReject( ProcessUnit, From, Event, To )
|
||||
self:E( { ProcessUnit.UnitName, From, Event, To } )
|
||||
|
||||
self.Menu:Remove()
|
||||
--TODO: need to resolve this problem ... it has to do with the events ...
|
||||
--self.Task:UnAssignFromUnit( ProcessUnit )needs to become a callback funtion call upon the event
|
||||
ProcessUnit:Destroy()
|
||||
end
|
||||
|
||||
end -- ACT_ASSIGN_MENU_ACCEPT
|
||||
206
Moose Development/Moose/Actions/Act_Assist.lua
Normal file
206
Moose Development/Moose/Actions/Act_Assist.lua
Normal file
@@ -0,0 +1,206 @@
|
||||
--- (SP) (MP) (FSM) Route AI or players through waypoints or to zones.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- # @{#ACT_ASSIST} FSM class, extends @{Fsm#FSM_PROCESS}
|
||||
--
|
||||
-- ## ACT_ASSIST state machine:
|
||||
--
|
||||
-- This class is a state machine: it manages a process that is triggered by events causing state transitions to occur.
|
||||
-- All derived classes from this class will start with the class name, followed by a \_. See the relevant derived class descriptions below.
|
||||
-- Each derived class follows exactly the same process, using the same events and following the same state transitions,
|
||||
-- but will have **different implementation behaviour** upon each event or state transition.
|
||||
--
|
||||
-- ### ACT_ASSIST **Events**:
|
||||
--
|
||||
-- These are the events defined in this class:
|
||||
--
|
||||
-- * **Start**: The process is started.
|
||||
-- * **Next**: The process is smoking the targets in the given zone.
|
||||
--
|
||||
-- ### ACT_ASSIST **Event methods**:
|
||||
--
|
||||
-- Event methods are available (dynamically allocated by the state machine), that accomodate for state transitions occurring in the process.
|
||||
-- There are two types of event methods, which you can use to influence the normal mechanisms in the state machine:
|
||||
--
|
||||
-- * **Immediate**: The event method has exactly the name of the event.
|
||||
-- * **Delayed**: The event method starts with a __ + the name of the event. The first parameter of the event method is a number value, expressing the delay in seconds when the event will be executed.
|
||||
--
|
||||
-- ### ACT_ASSIST **States**:
|
||||
--
|
||||
-- * **None**: The controllable did not receive route commands.
|
||||
-- * **AwaitSmoke (*)**: The process is awaiting to smoke the targets in the zone.
|
||||
-- * **Smoking (*)**: The process is smoking the targets in the zone.
|
||||
-- * **Failed (*)**: The process has failed.
|
||||
--
|
||||
-- (*) End states of the process.
|
||||
--
|
||||
-- ### ACT_ASSIST state transition methods:
|
||||
--
|
||||
-- State transition functions can be set **by the mission designer** customizing or improving the behaviour of the state.
|
||||
-- There are 2 moments when state transition methods will be called by the state machine:
|
||||
--
|
||||
-- * **Before** the state transition.
|
||||
-- The state transition method needs to start with the name **OnBefore + the name of the state**.
|
||||
-- If the state transition method returns false, then the processing of the state transition will not be done!
|
||||
-- If you want to change the behaviour of the AIControllable at this event, return false,
|
||||
-- but then you'll need to specify your own logic using the AIControllable!
|
||||
--
|
||||
-- * **After** the state transition.
|
||||
-- The state transition method needs to start with the name **OnAfter + the name of the state**.
|
||||
-- These state transition methods need to provide a return value, which is specified at the function description.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- # 1) @{#ACT_ASSIST_SMOKE_TARGETS_ZONE} class, extends @{Fsm.Route#ACT_ASSIST}
|
||||
--
|
||||
-- The ACT_ASSIST_SMOKE_TARGETS_ZONE class implements the core functions to smoke targets in a @{Zone}.
|
||||
-- The targets are smoked within a certain range around each target, simulating a realistic smoking behaviour.
|
||||
-- At random intervals, a new target is smoked.
|
||||
--
|
||||
-- # 1.1) ACT_ASSIST_SMOKE_TARGETS_ZONE constructor:
|
||||
--
|
||||
-- * @{#ACT_ASSIST_SMOKE_TARGETS_ZONE.New}(): Creates a new ACT_ASSIST_SMOKE_TARGETS_ZONE object.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- @module Smoke
|
||||
|
||||
do -- ACT_ASSIST
|
||||
|
||||
--- ACT_ASSIST class
|
||||
-- @type ACT_ASSIST
|
||||
-- @extends Core.Fsm#FSM_PROCESS
|
||||
ACT_ASSIST = {
|
||||
ClassName = "ACT_ASSIST",
|
||||
}
|
||||
|
||||
--- Creates a new target smoking state machine. The process will request from the menu if it accepts the task, if not, the unit is removed from the simulator.
|
||||
-- @param #ACT_ASSIST self
|
||||
-- @return #ACT_ASSIST
|
||||
function ACT_ASSIST:New()
|
||||
|
||||
-- Inherits from BASE
|
||||
local self = BASE:Inherit( self, FSM_PROCESS:New( "ACT_ASSIST" ) ) -- Core.Fsm#FSM_PROCESS
|
||||
|
||||
self:AddTransition( "None", "Start", "AwaitSmoke" )
|
||||
self:AddTransition( "AwaitSmoke", "Next", "Smoking" )
|
||||
self:AddTransition( "Smoking", "Next", "AwaitSmoke" )
|
||||
self:AddTransition( "*", "Stop", "Success" )
|
||||
self:AddTransition( "*", "Fail", "Failed" )
|
||||
|
||||
self:AddEndState( "Failed" )
|
||||
self:AddEndState( "Success" )
|
||||
|
||||
self:SetStartState( "None" )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Task Events
|
||||
|
||||
--- StateMachine callback function
|
||||
-- @param #ACT_ASSIST self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE ProcessUnit
|
||||
-- @param #string Event
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
function ACT_ASSIST:onafterStart( ProcessUnit, From, Event, To )
|
||||
|
||||
local ProcessGroup = ProcessUnit:GetGroup()
|
||||
local MissionMenu = self:GetMission():GetMissionMenu( ProcessGroup )
|
||||
|
||||
local function MenuSmoke( MenuParam )
|
||||
self:E( MenuParam )
|
||||
local self = MenuParam.self
|
||||
local SmokeColor = MenuParam.SmokeColor
|
||||
self.SmokeColor = SmokeColor
|
||||
self:__Next( 1 )
|
||||
end
|
||||
|
||||
self.Menu = MENU_GROUP:New( ProcessGroup, "Target acquisition", MissionMenu )
|
||||
self.MenuSmokeBlue = MENU_GROUP_COMMAND:New( ProcessGroup, "Drop blue smoke on targets", self.Menu, MenuSmoke, { self = self, SmokeColor = SMOKECOLOR.Blue } )
|
||||
self.MenuSmokeGreen = MENU_GROUP_COMMAND:New( ProcessGroup, "Drop green smoke on targets", self.Menu, MenuSmoke, { self = self, SmokeColor = SMOKECOLOR.Green } )
|
||||
self.MenuSmokeOrange = MENU_GROUP_COMMAND:New( ProcessGroup, "Drop Orange smoke on targets", self.Menu, MenuSmoke, { self = self, SmokeColor = SMOKECOLOR.Orange } )
|
||||
self.MenuSmokeRed = MENU_GROUP_COMMAND:New( ProcessGroup, "Drop Red smoke on targets", self.Menu, MenuSmoke, { self = self, SmokeColor = SMOKECOLOR.Red } )
|
||||
self.MenuSmokeWhite = MENU_GROUP_COMMAND:New( ProcessGroup, "Drop White smoke on targets", self.Menu, MenuSmoke, { self = self, SmokeColor = SMOKECOLOR.White } )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
do -- ACT_ASSIST_SMOKE_TARGETS_ZONE
|
||||
|
||||
--- ACT_ASSIST_SMOKE_TARGETS_ZONE class
|
||||
-- @type ACT_ASSIST_SMOKE_TARGETS_ZONE
|
||||
-- @field Set#SET_UNIT TargetSetUnit
|
||||
-- @field Core.Zone#ZONE_BASE TargetZone
|
||||
-- @extends #ACT_ASSIST
|
||||
ACT_ASSIST_SMOKE_TARGETS_ZONE = {
|
||||
ClassName = "ACT_ASSIST_SMOKE_TARGETS_ZONE",
|
||||
}
|
||||
|
||||
-- function ACT_ASSIST_SMOKE_TARGETS_ZONE:_Destructor()
|
||||
-- self:E("_Destructor")
|
||||
--
|
||||
-- self.Menu:Remove()
|
||||
-- self:EventRemoveAll()
|
||||
-- end
|
||||
|
||||
--- Creates a new target smoking state machine. The process will request from the menu if it accepts the task, if not, the unit is removed from the simulator.
|
||||
-- @param #ACT_ASSIST_SMOKE_TARGETS_ZONE self
|
||||
-- @param Set#SET_UNIT TargetSetUnit
|
||||
-- @param Core.Zone#ZONE_BASE TargetZone
|
||||
function ACT_ASSIST_SMOKE_TARGETS_ZONE:New( TargetSetUnit, TargetZone )
|
||||
local self = BASE:Inherit( self, ACT_ASSIST:New() ) -- #ACT_ASSIST
|
||||
|
||||
self.TargetSetUnit = TargetSetUnit
|
||||
self.TargetZone = TargetZone
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function ACT_ASSIST_SMOKE_TARGETS_ZONE:Init( FsmSmoke )
|
||||
|
||||
self.TargetSetUnit = FsmSmoke.TargetSetUnit
|
||||
self.TargetZone = FsmSmoke.TargetZone
|
||||
end
|
||||
|
||||
--- Creates a new target smoking state machine. The process will request from the menu if it accepts the task, if not, the unit is removed from the simulator.
|
||||
-- @param #ACT_ASSIST_SMOKE_TARGETS_ZONE self
|
||||
-- @param Set#SET_UNIT TargetSetUnit
|
||||
-- @param Core.Zone#ZONE_BASE TargetZone
|
||||
-- @return #ACT_ASSIST_SMOKE_TARGETS_ZONE self
|
||||
function ACT_ASSIST_SMOKE_TARGETS_ZONE:Init( TargetSetUnit, TargetZone )
|
||||
|
||||
self.TargetSetUnit = TargetSetUnit
|
||||
self.TargetZone = TargetZone
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- StateMachine callback function
|
||||
-- @param #ACT_ASSIST_SMOKE_TARGETS_ZONE self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE ProcessUnit
|
||||
-- @param #string Event
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
function ACT_ASSIST_SMOKE_TARGETS_ZONE:onenterSmoking( ProcessUnit, From, Event, To )
|
||||
|
||||
self.TargetSetUnit:ForEachUnit(
|
||||
--- @param Wrapper.Unit#UNIT SmokeUnit
|
||||
function( SmokeUnit )
|
||||
if math.random( 1, ( 100 * self.TargetSetUnit:Count() ) / 4 ) <= 100 then
|
||||
SCHEDULER:New( self,
|
||||
function()
|
||||
if SmokeUnit:IsAlive() then
|
||||
SmokeUnit:Smoke( self.SmokeColor, 150 )
|
||||
end
|
||||
end, {}, math.random( 10, 60 )
|
||||
)
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
199
Moose Development/Moose/Actions/Act_JTAC.lua
Normal file
199
Moose Development/Moose/Actions/Act_JTAC.lua
Normal file
@@ -0,0 +1,199 @@
|
||||
--- @module Process_JTAC
|
||||
|
||||
--- PROCESS_JTAC class
|
||||
-- @type PROCESS_JTAC
|
||||
-- @field Wrapper.Unit#UNIT ProcessUnit
|
||||
-- @field Core.Set#SET_UNIT TargetSetUnit
|
||||
-- @extends Core.Fsm#FSM_PROCESS
|
||||
PROCESS_JTAC = {
|
||||
ClassName = "PROCESS_JTAC",
|
||||
Fsm = {},
|
||||
TargetSetUnit = nil,
|
||||
}
|
||||
|
||||
|
||||
--- Creates a new DESTROY process.
|
||||
-- @param #PROCESS_JTAC self
|
||||
-- @param Tasking.Task#TASK Task
|
||||
-- @param Wrapper.Unit#UNIT ProcessUnit
|
||||
-- @param Core.Set#SET_UNIT TargetSetUnit
|
||||
-- @param Wrapper.Unit#UNIT FACUnit
|
||||
-- @return #PROCESS_JTAC self
|
||||
function PROCESS_JTAC:New( Task, ProcessUnit, TargetSetUnit, FACUnit )
|
||||
|
||||
-- Inherits from BASE
|
||||
local self = BASE:Inherit( self, PROCESS:New( "JTAC", Task, ProcessUnit ) ) -- #PROCESS_JTAC
|
||||
|
||||
self.TargetSetUnit = TargetSetUnit
|
||||
self.FACUnit = FACUnit
|
||||
|
||||
self.DisplayInterval = 60
|
||||
self.DisplayCount = 30
|
||||
self.DisplayMessage = true
|
||||
self.DisplayTime = 10 -- 10 seconds is the default
|
||||
self.DisplayCategory = "HQ" -- Targets is the default display category
|
||||
|
||||
|
||||
self.Fsm = FSM_PROCESS:New( self, {
|
||||
initial = 'Assigned',
|
||||
events = {
|
||||
{ name = 'Start', from = 'Assigned', to = 'CreatedMenu' },
|
||||
{ name = 'JTACMenuUpdate', from = 'CreatedMenu', to = 'AwaitingMenu' },
|
||||
{ name = 'JTACMenuAwait', from = 'AwaitingMenu', to = 'AwaitingMenu' },
|
||||
{ name = 'JTACMenuSpot', from = 'AwaitingMenu', to = 'AwaitingMenu' },
|
||||
{ name = 'JTACMenuCancel', from = 'AwaitingMenu', to = 'AwaitingMenu' },
|
||||
{ name = 'JTACStatus', from = 'AwaitingMenu', to = 'AwaitingMenu' },
|
||||
{ name = 'Fail', from = 'AwaitingMenu', to = 'Failed' },
|
||||
{ name = 'Fail', from = 'CreatedMenu', to = 'Failed' },
|
||||
},
|
||||
callbacks = {
|
||||
onStart = self.OnStart,
|
||||
onJTACMenuUpdate = self.OnJTACMenuUpdate,
|
||||
onJTACMenuAwait = self.OnJTACMenuAwait,
|
||||
onJTACMenuSpot = self.OnJTACMenuSpot,
|
||||
onJTACMenuCancel = self.OnJTACMenuCancel,
|
||||
},
|
||||
endstates = { 'Failed' }
|
||||
} )
|
||||
|
||||
|
||||
_EVENTDISPATCHER:OnDead( self.EventDead, self )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Process Events
|
||||
|
||||
--- StateMachine callback function for a PROCESS
|
||||
-- @param #PROCESS_JTAC self
|
||||
-- @param Core.Fsm#FSM_PROCESS Fsm
|
||||
-- @param #string Event
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
function PROCESS_JTAC:OnStart( Fsm, From, Event, To )
|
||||
|
||||
self:NextEvent( Fsm.JTACMenuUpdate )
|
||||
end
|
||||
|
||||
--- StateMachine callback function for a PROCESS
|
||||
-- @param #PROCESS_JTAC self
|
||||
-- @param Core.Fsm#FSM_PROCESS Fsm
|
||||
-- @param #string Event
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
function PROCESS_JTAC:OnJTACMenuUpdate( Fsm, From, Event, To )
|
||||
|
||||
local function JTACMenuSpot( MenuParam )
|
||||
self:E( MenuParam.TargetUnit.UnitName )
|
||||
local self = MenuParam.self
|
||||
local TargetUnit = MenuParam.TargetUnit
|
||||
|
||||
self:NextEvent( self.Fsm.JTACMenuSpot, TargetUnit )
|
||||
end
|
||||
|
||||
local function JTACMenuCancel( MenuParam )
|
||||
self:E( MenuParam )
|
||||
local self = MenuParam.self
|
||||
local TargetUnit = MenuParam.TargetUnit
|
||||
|
||||
self:NextEvent( self.Fsm.JTACMenuCancel, TargetUnit )
|
||||
end
|
||||
|
||||
|
||||
-- Loop each unit in the target set, and determine the threat levels map table.
|
||||
local UnitThreatLevels = self.TargetSetUnit:GetUnitThreatLevels()
|
||||
|
||||
self:E( {"UnitThreadLevels", UnitThreatLevels } )
|
||||
|
||||
local JTACMenu = self.ProcessGroup:GetState( self.ProcessGroup, "JTACMenu" )
|
||||
|
||||
if not JTACMenu then
|
||||
JTACMenu = MENU_GROUP:New( self.ProcessGroup, "JTAC", self.MissionMenu )
|
||||
for ThreatLevel, ThreatLevelTable in pairs( UnitThreatLevels ) do
|
||||
local JTACMenuThreatLevel = MENU_GROUP:New( self.ProcessGroup, ThreatLevelTable.UnitThreatLevelText, JTACMenu )
|
||||
for ThreatUnitName, ThreatUnit in pairs( ThreatLevelTable.Units ) do
|
||||
local JTACMenuUnit = MENU_GROUP:New( self.ProcessGroup, ThreatUnit:GetTypeName(), JTACMenuThreatLevel )
|
||||
MENU_GROUP_COMMAND:New( self.ProcessGroup, "Lase Target", JTACMenuUnit, JTACMenuSpot, { self = self, TargetUnit = ThreatUnit } )
|
||||
MENU_GROUP_COMMAND:New( self.ProcessGroup, "Cancel Target", JTACMenuUnit, JTACMenuCancel, { self = self, TargetUnit = ThreatUnit } )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--- StateMachine callback function for a PROCESS
|
||||
-- @param #PROCESS_JTAC self
|
||||
-- @param Core.Fsm#FSM_PROCESS Fsm
|
||||
-- @param #string Event
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
function PROCESS_JTAC:OnJTACMenuAwait( Fsm, From, Event, To )
|
||||
|
||||
if self.DisplayCount >= self.DisplayInterval then
|
||||
|
||||
local TaskJTAC = self.Task -- Tasking.Task#TASK_JTAC
|
||||
TaskJTAC.Spots = TaskJTAC.Spots or {}
|
||||
for TargetUnitName, SpotData in pairs( TaskJTAC.Spots) do
|
||||
local TargetUnit = UNIT:FindByName( TargetUnitName )
|
||||
self.FACUnit:MessageToGroup( "Lasing " .. TargetUnit:GetTypeName() .. " with laser code " .. SpotData:getCode(), 15, self.ProcessGroup )
|
||||
end
|
||||
self.DisplayCount = 1
|
||||
else
|
||||
self.DisplayCount = self.DisplayCount + 1
|
||||
end
|
||||
|
||||
self:NextEvent( Fsm.JTACMenuAwait )
|
||||
end
|
||||
|
||||
--- StateMachine callback function for a PROCESS
|
||||
-- @param #PROCESS_JTAC self
|
||||
-- @param Core.Fsm#FSM_PROCESS Fsm
|
||||
-- @param #string Event
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
-- @param Wrapper.Unit#UNIT TargetUnit
|
||||
function PROCESS_JTAC:OnJTACMenuSpot( Fsm, From, Event, To, TargetUnit )
|
||||
|
||||
local TargetUnitName = TargetUnit:GetName()
|
||||
|
||||
local TaskJTAC = self.Task -- Tasking.Task#TASK_JTAC
|
||||
|
||||
TaskJTAC.Spots = TaskJTAC.Spots or {}
|
||||
TaskJTAC.Spots[TargetUnitName] = TaskJTAC.Spots[TargetUnitName] or {}
|
||||
|
||||
local DCSFACObject = self.FACUnit:GetDCSObject()
|
||||
local TargetVec3 = TargetUnit:GetVec3()
|
||||
|
||||
TaskJTAC.Spots[TargetUnitName] = Spot.createInfraRed( self.FACUnit:GetDCSObject(), { x = 0, y = 1, z = 0 }, TargetUnit:GetVec3(), math.random( 1000, 9999 ) )
|
||||
|
||||
local SpotData = TaskJTAC.Spots[TargetUnitName]
|
||||
self.FACUnit:MessageToGroup( "Lasing " .. TargetUnit:GetTypeName() .. " with laser code " .. SpotData:getCode(), 15, self.ProcessGroup )
|
||||
|
||||
self:NextEvent( Fsm.JTACMenuAwait )
|
||||
end
|
||||
|
||||
--- StateMachine callback function for a PROCESS
|
||||
-- @param #PROCESS_JTAC self
|
||||
-- @param Core.Fsm#FSM_PROCESS Fsm
|
||||
-- @param #string Event
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
-- @param Wrapper.Unit#UNIT TargetUnit
|
||||
function PROCESS_JTAC:OnJTACMenuCancel( Fsm, From, Event, To, TargetUnit )
|
||||
|
||||
local TargetUnitName = TargetUnit:GetName()
|
||||
|
||||
local TaskJTAC = self.Task -- Tasking.Task#TASK_JTAC
|
||||
|
||||
TaskJTAC.Spots = TaskJTAC.Spots or {}
|
||||
if TaskJTAC.Spots[TargetUnitName] then
|
||||
TaskJTAC.Spots[TargetUnitName]:destroy() -- destroys the spot
|
||||
TaskJTAC.Spots[TargetUnitName] = nil
|
||||
end
|
||||
|
||||
self.FACUnit:MessageToGroup( "Stopped lasing " .. TargetUnit:GetTypeName(), 15, self.ProcessGroup )
|
||||
|
||||
self:NextEvent( Fsm.JTACMenuAwait )
|
||||
end
|
||||
|
||||
|
||||
173
Moose Development/Moose/Actions/Act_Pickup.lua
Normal file
173
Moose Development/Moose/Actions/Act_Pickup.lua
Normal file
@@ -0,0 +1,173 @@
|
||||
--- @module Process_Pickup
|
||||
|
||||
--- PROCESS_PICKUP class
|
||||
-- @type PROCESS_PICKUP
|
||||
-- @field Wrapper.Unit#UNIT ProcessUnit
|
||||
-- @field Core.Set#SET_UNIT TargetSetUnit
|
||||
-- @extends Core.Fsm#FSM_PROCESS
|
||||
PROCESS_PICKUP = {
|
||||
ClassName = "PROCESS_PICKUP",
|
||||
Fsm = {},
|
||||
TargetSetUnit = nil,
|
||||
}
|
||||
|
||||
|
||||
--- Creates a new DESTROY process.
|
||||
-- @param #PROCESS_PICKUP self
|
||||
-- @param Tasking.Task#TASK Task
|
||||
-- @param Wrapper.Unit#UNIT ProcessUnit
|
||||
-- @param Core.Set#SET_UNIT TargetSetUnit
|
||||
-- @return #PROCESS_PICKUP self
|
||||
function PROCESS_PICKUP:New( Task, ProcessName, ProcessUnit )
|
||||
|
||||
-- Inherits from BASE
|
||||
local self = BASE:Inherit( self, PROCESS:New( ProcessName, Task, ProcessUnit ) ) -- #PROCESS_PICKUP
|
||||
|
||||
self.DisplayInterval = 30
|
||||
self.DisplayCount = 30
|
||||
self.DisplayMessage = true
|
||||
self.DisplayTime = 10 -- 10 seconds is the default
|
||||
self.DisplayCategory = "HQ" -- Targets is the default display category
|
||||
|
||||
self.Fsm = FSM_PROCESS:New( self, {
|
||||
initial = 'Assigned',
|
||||
events = {
|
||||
{ name = 'Start', from = 'Assigned', to = 'Navigating' },
|
||||
{ name = 'Start', from = 'Navigating', to = 'Navigating' },
|
||||
{ name = 'Nearby', from = 'Navigating', to = 'Preparing' },
|
||||
{ name = 'Pickup', from = 'Preparing', to = 'Loading' },
|
||||
{ name = 'Load', from = 'Loading', to = 'Success' },
|
||||
{ name = 'Fail', from = 'Assigned', to = 'Failed' },
|
||||
{ name = 'Fail', from = 'Navigating', to = 'Failed' },
|
||||
{ name = 'Fail', from = 'Preparing', to = 'Failed' },
|
||||
},
|
||||
callbacks = {
|
||||
onStart = self.OnStart,
|
||||
onNearby = self.OnNearby,
|
||||
onPickup = self.OnPickup,
|
||||
onLoad = self.OnLoad,
|
||||
},
|
||||
endstates = { 'Success', 'Failed' }
|
||||
} )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Process Events
|
||||
|
||||
--- StateMachine callback function for a PROCESS
|
||||
-- @param #PROCESS_PICKUP self
|
||||
-- @param Core.Fsm#FSM_PROCESS Fsm
|
||||
-- @param #string Event
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
function PROCESS_PICKUP:OnStart( Fsm, From, Event, To )
|
||||
|
||||
self:NextEvent( Fsm.Start )
|
||||
end
|
||||
|
||||
--- StateMachine callback function for a PROCESS
|
||||
-- @param #PROCESS_PICKUP self
|
||||
-- @param Core.Fsm#FSM_PROCESS Fsm
|
||||
-- @param #string Event
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
function PROCESS_PICKUP:OnNavigating( Fsm, From, Event, To )
|
||||
|
||||
local TaskGroup = self.ProcessUnit:GetGroup()
|
||||
if self.DisplayCount >= self.DisplayInterval then
|
||||
MESSAGE:New( "Your group with assigned " .. self.Task:GetName() .. " task has " .. self.TargetSetUnit:GetUnitTypesText() .. " targets left to be destroyed.", 5, "HQ" ):ToGroup( TaskGroup )
|
||||
self.DisplayCount = 1
|
||||
else
|
||||
self.DisplayCount = self.DisplayCount + 1
|
||||
end
|
||||
|
||||
return true -- Process always the event.
|
||||
|
||||
end
|
||||
|
||||
|
||||
--- StateMachine callback function for a PROCESS
|
||||
-- @param #PROCESS_PICKUP self
|
||||
-- @param Core.Fsm#FSM_PROCESS Fsm
|
||||
-- @param #string Event
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
-- @param Core.Event#EVENTDATA Event
|
||||
function PROCESS_PICKUP:OnHitTarget( Fsm, From, Event, To, Event )
|
||||
|
||||
|
||||
self.TargetSetUnit:Flush()
|
||||
|
||||
if self.TargetSetUnit:FindUnit( Event.IniUnitName ) then
|
||||
self.TargetSetUnit:RemoveUnitsByName( Event.IniUnitName )
|
||||
local TaskGroup = self.ProcessUnit:GetGroup()
|
||||
MESSAGE:New( "You hit a target. Your group with assigned " .. self.Task:GetName() .. " task has " .. self.TargetSetUnit:Count() .. " targets ( " .. self.TargetSetUnit:GetUnitTypesText() .. " ) left to be destroyed.", 15, "HQ" ):ToGroup( TaskGroup )
|
||||
end
|
||||
|
||||
|
||||
if self.TargetSetUnit:Count() > 0 then
|
||||
self:NextEvent( Fsm.MoreTargets )
|
||||
else
|
||||
self:NextEvent( Fsm.Destroyed )
|
||||
end
|
||||
end
|
||||
|
||||
--- StateMachine callback function for a PROCESS
|
||||
-- @param #PROCESS_PICKUP self
|
||||
-- @param Core.Fsm#FSM_PROCESS Fsm
|
||||
-- @param #string Event
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
function PROCESS_PICKUP:OnMoreTargets( Fsm, From, Event, To )
|
||||
|
||||
|
||||
end
|
||||
|
||||
--- StateMachine callback function for a PROCESS
|
||||
-- @param #PROCESS_PICKUP self
|
||||
-- @param Core.Fsm#FSM_PROCESS Fsm
|
||||
-- @param #string Event
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
-- @param Core.Event#EVENTDATA DCSEvent
|
||||
function PROCESS_PICKUP:OnKilled( Fsm, From, Event, To )
|
||||
|
||||
self:NextEvent( Fsm.Restart )
|
||||
|
||||
end
|
||||
|
||||
--- StateMachine callback function for a PROCESS
|
||||
-- @param #PROCESS_PICKUP self
|
||||
-- @param Core.Fsm#FSM_PROCESS Fsm
|
||||
-- @param #string Event
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
function PROCESS_PICKUP:OnRestart( Fsm, From, Event, To )
|
||||
|
||||
self:NextEvent( Fsm.Menu )
|
||||
|
||||
end
|
||||
|
||||
--- StateMachine callback function for a PROCESS
|
||||
-- @param #PROCESS_PICKUP self
|
||||
-- @param Core.Fsm#FSM_PROCESS Fsm
|
||||
-- @param #string Event
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
function PROCESS_PICKUP:OnDestroyed( Fsm, From, Event, To )
|
||||
|
||||
end
|
||||
|
||||
--- DCS Events
|
||||
|
||||
--- @param #PROCESS_PICKUP self
|
||||
-- @param Core.Event#EVENTDATA Event
|
||||
function PROCESS_PICKUP:EventDead( Event )
|
||||
|
||||
if Event.IniDCSUnit then
|
||||
self:NextEvent( self.Fsm.HitTarget, Event )
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
252
Moose Development/Moose/Actions/Act_Route.lua
Normal file
252
Moose Development/Moose/Actions/Act_Route.lua
Normal file
@@ -0,0 +1,252 @@
|
||||
--- (SP) (MP) (FSM) Route AI or players through waypoints or to zones.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- # @{#ACT_ROUTE} FSM class, extends @{Fsm#FSM_PROCESS}
|
||||
--
|
||||
-- ## ACT_ROUTE state machine:
|
||||
--
|
||||
-- This class is a state machine: it manages a process that is triggered by events causing state transitions to occur.
|
||||
-- All derived classes from this class will start with the class name, followed by a \_. See the relevant derived class descriptions below.
|
||||
-- Each derived class follows exactly the same process, using the same events and following the same state transitions,
|
||||
-- but will have **different implementation behaviour** upon each event or state transition.
|
||||
--
|
||||
-- ### ACT_ROUTE **Events**:
|
||||
--
|
||||
-- These are the events defined in this class:
|
||||
--
|
||||
-- * **Start**: The process is started. The process will go into the Report state.
|
||||
-- * **Report**: The process is reporting to the player the route to be followed.
|
||||
-- * **Route**: The process is routing the controllable.
|
||||
-- * **Pause**: The process is pausing the route of the controllable.
|
||||
-- * **Arrive**: The controllable has arrived at a route point.
|
||||
-- * **More**: There are more route points that need to be followed. The process will go back into the Report state.
|
||||
-- * **NoMore**: There are no more route points that need to be followed. The process will go into the Success state.
|
||||
--
|
||||
-- ### ACT_ROUTE **Event methods**:
|
||||
--
|
||||
-- Event methods are available (dynamically allocated by the state machine), that accomodate for state transitions occurring in the process.
|
||||
-- There are two types of event methods, which you can use to influence the normal mechanisms in the state machine:
|
||||
--
|
||||
-- * **Immediate**: The event method has exactly the name of the event.
|
||||
-- * **Delayed**: The event method starts with a __ + the name of the event. The first parameter of the event method is a number value, expressing the delay in seconds when the event will be executed.
|
||||
--
|
||||
-- ### ACT_ROUTE **States**:
|
||||
--
|
||||
-- * **None**: The controllable did not receive route commands.
|
||||
-- * **Arrived (*)**: The controllable has arrived at a route point.
|
||||
-- * **Aborted (*)**: The controllable has aborted the route path.
|
||||
-- * **Routing**: The controllable is understay to the route point.
|
||||
-- * **Pausing**: The process is pausing the routing. AI air will go into hover, AI ground will stop moving. Players can fly around.
|
||||
-- * **Success (*)**: All route points were reached.
|
||||
-- * **Failed (*)**: The process has failed.
|
||||
--
|
||||
-- (*) End states of the process.
|
||||
--
|
||||
-- ### ACT_ROUTE state transition methods:
|
||||
--
|
||||
-- State transition functions can be set **by the mission designer** customizing or improving the behaviour of the state.
|
||||
-- There are 2 moments when state transition methods will be called by the state machine:
|
||||
--
|
||||
-- * **Before** the state transition.
|
||||
-- The state transition method needs to start with the name **OnBefore + the name of the state**.
|
||||
-- If the state transition method returns false, then the processing of the state transition will not be done!
|
||||
-- If you want to change the behaviour of the AIControllable at this event, return false,
|
||||
-- but then you'll need to specify your own logic using the AIControllable!
|
||||
--
|
||||
-- * **After** the state transition.
|
||||
-- The state transition method needs to start with the name **OnAfter + the name of the state**.
|
||||
-- These state transition methods need to provide a return value, which is specified at the function description.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- # 1) @{#ACT_ROUTE_ZONE} class, extends @{Fsm.Route#ACT_ROUTE}
|
||||
--
|
||||
-- The ACT_ROUTE_ZONE class implements the core functions to route an AIR @{Controllable} player @{Unit} to a @{Zone}.
|
||||
-- The player receives on perioding times messages with the coordinates of the route to follow.
|
||||
-- Upon arrival at the zone, a confirmation of arrival is sent, and the process will be ended.
|
||||
--
|
||||
-- # 1.1) ACT_ROUTE_ZONE constructor:
|
||||
--
|
||||
-- * @{#ACT_ROUTE_ZONE.New}(): Creates a new ACT_ROUTE_ZONE object.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- @module Route
|
||||
|
||||
|
||||
do -- ACT_ROUTE
|
||||
|
||||
--- ACT_ROUTE class
|
||||
-- @type ACT_ROUTE
|
||||
-- @field Tasking.Task#TASK TASK
|
||||
-- @field Wrapper.Unit#UNIT ProcessUnit
|
||||
-- @field Core.Zone#ZONE_BASE TargetZone
|
||||
-- @extends Core.Fsm#FSM_PROCESS
|
||||
ACT_ROUTE = {
|
||||
ClassName = "ACT_ROUTE",
|
||||
}
|
||||
|
||||
|
||||
--- Creates a new routing state machine. The process will route a CLIENT to a ZONE until the CLIENT is within that ZONE.
|
||||
-- @param #ACT_ROUTE self
|
||||
-- @return #ACT_ROUTE self
|
||||
function ACT_ROUTE:New()
|
||||
|
||||
-- Inherits from BASE
|
||||
local self = BASE:Inherit( self, FSM_PROCESS:New( "ACT_ROUTE" ) ) -- Core.Fsm#FSM_PROCESS
|
||||
|
||||
self:AddTransition( "None", "Start", "Routing" )
|
||||
self:AddTransition( "*", "Report", "Reporting" )
|
||||
self:AddTransition( "*", "Route", "Routing" )
|
||||
self:AddTransition( "Routing", "Pause", "Pausing" )
|
||||
self:AddTransition( "*", "Abort", "Aborted" )
|
||||
self:AddTransition( "Routing", "Arrive", "Arrived" )
|
||||
self:AddTransition( "Arrived", "Success", "Success" )
|
||||
self:AddTransition( "*", "Fail", "Failed" )
|
||||
self:AddTransition( "", "", "" )
|
||||
self:AddTransition( "", "", "" )
|
||||
|
||||
self:AddEndState( "Arrived" )
|
||||
self:AddEndState( "Failed" )
|
||||
|
||||
self:SetStartState( "None" )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Task Events
|
||||
|
||||
--- StateMachine callback function
|
||||
-- @param #ACT_ROUTE self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE ProcessUnit
|
||||
-- @param #string Event
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
function ACT_ROUTE:onafterStart( ProcessUnit, From, Event, To )
|
||||
|
||||
|
||||
self:__Route( 1 )
|
||||
end
|
||||
|
||||
--- Check if the controllable has arrived.
|
||||
-- @param #ACT_ROUTE self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE ProcessUnit
|
||||
-- @return #boolean
|
||||
function ACT_ROUTE:onfuncHasArrived( ProcessUnit )
|
||||
return false
|
||||
end
|
||||
|
||||
--- StateMachine callback function
|
||||
-- @param #ACT_ROUTE self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE ProcessUnit
|
||||
-- @param #string Event
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
function ACT_ROUTE:onbeforeRoute( ProcessUnit, From, Event, To )
|
||||
self:F( { "BeforeRoute 1", self.DisplayCount, self.DisplayInterval } )
|
||||
|
||||
if ProcessUnit:IsAlive() then
|
||||
self:F( "BeforeRoute 2" )
|
||||
local HasArrived = self:onfuncHasArrived( ProcessUnit ) -- Polymorphic
|
||||
if self.DisplayCount >= self.DisplayInterval then
|
||||
self:T( { HasArrived = HasArrived } )
|
||||
if not HasArrived then
|
||||
self:Report()
|
||||
end
|
||||
self.DisplayCount = 1
|
||||
else
|
||||
self.DisplayCount = self.DisplayCount + 1
|
||||
end
|
||||
|
||||
self:T( { DisplayCount = self.DisplayCount } )
|
||||
|
||||
if HasArrived then
|
||||
self:__Arrive( 1 )
|
||||
else
|
||||
self:__Route( 1 )
|
||||
end
|
||||
|
||||
return HasArrived -- if false, then the event will not be executed...
|
||||
end
|
||||
|
||||
return false
|
||||
|
||||
end
|
||||
|
||||
end -- ACT_ROUTE
|
||||
|
||||
|
||||
|
||||
do -- ACT_ROUTE_ZONE
|
||||
|
||||
--- ACT_ROUTE_ZONE class
|
||||
-- @type ACT_ROUTE_ZONE
|
||||
-- @field Tasking.Task#TASK TASK
|
||||
-- @field Wrapper.Unit#UNIT ProcessUnit
|
||||
-- @field Core.Zone#ZONE_BASE TargetZone
|
||||
-- @extends #ACT_ROUTE
|
||||
ACT_ROUTE_ZONE = {
|
||||
ClassName = "ACT_ROUTE_ZONE",
|
||||
}
|
||||
|
||||
|
||||
--- Creates a new routing state machine. The task will route a controllable to a ZONE until the controllable is within that ZONE.
|
||||
-- @param #ACT_ROUTE_ZONE self
|
||||
-- @param Core.Zone#ZONE_BASE TargetZone
|
||||
function ACT_ROUTE_ZONE:New( TargetZone )
|
||||
local self = BASE:Inherit( self, ACT_ROUTE:New() ) -- #ACT_ROUTE_ZONE
|
||||
|
||||
self.TargetZone = TargetZone
|
||||
|
||||
self.DisplayInterval = 30
|
||||
self.DisplayCount = 30
|
||||
self.DisplayMessage = true
|
||||
self.DisplayTime = 10 -- 10 seconds is the default
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function ACT_ROUTE_ZONE:Init( FsmRoute )
|
||||
|
||||
self.TargetZone = FsmRoute.TargetZone
|
||||
|
||||
self.DisplayInterval = 30
|
||||
self.DisplayCount = 30
|
||||
self.DisplayMessage = true
|
||||
self.DisplayTime = 10 -- 10 seconds is the default
|
||||
end
|
||||
|
||||
--- Method override to check if the controllable has arrived.
|
||||
-- @param #ACT_ROUTE self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE ProcessUnit
|
||||
-- @return #boolean
|
||||
function ACT_ROUTE_ZONE:onfuncHasArrived( ProcessUnit )
|
||||
|
||||
if ProcessUnit:IsInZone( self.TargetZone ) then
|
||||
local RouteText = "You have arrived within the zone."
|
||||
self:Message( RouteText )
|
||||
end
|
||||
|
||||
return ProcessUnit:IsInZone( self.TargetZone )
|
||||
end
|
||||
|
||||
--- Task Events
|
||||
|
||||
--- StateMachine callback function
|
||||
-- @param #ACT_ROUTE_ZONE self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE ProcessUnit
|
||||
-- @param #string Event
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
function ACT_ROUTE_ZONE:onenterReporting( ProcessUnit, From, Event, To )
|
||||
|
||||
local ZoneVec2 = self.TargetZone:GetVec2()
|
||||
local ZonePointVec2 = POINT_VEC2:New( ZoneVec2.x, ZoneVec2.y )
|
||||
local TaskUnitVec2 = ProcessUnit:GetVec2()
|
||||
local TaskUnitPointVec2 = POINT_VEC2:New( TaskUnitVec2.x, TaskUnitVec2.y )
|
||||
local RouteText = "Route to " .. TaskUnitPointVec2:GetBRText( ZonePointVec2 ) .. " km to target."
|
||||
self:Message( RouteText )
|
||||
end
|
||||
|
||||
end -- ACT_ROUTE_ZONE
|
||||
856
Moose Development/Moose/Core/Base.lua
Normal file
856
Moose Development/Moose/Core/Base.lua
Normal file
@@ -0,0 +1,856 @@
|
||||
--- This module contains the BASE class.
|
||||
--
|
||||
-- 1) @{#BASE} class
|
||||
-- =================
|
||||
-- The @{#BASE} class is the super class for all the classes defined within MOOSE.
|
||||
--
|
||||
-- It handles:
|
||||
--
|
||||
-- * The construction and inheritance of child classes.
|
||||
-- * The tracing of objects during mission execution within the **DCS.log** file, under the **"Saved Games\DCS\Logs"** folder.
|
||||
--
|
||||
-- Note: Normally you would not use the BASE class unless you are extending the MOOSE framework with new classes.
|
||||
--
|
||||
-- ## 1.1) BASE constructor
|
||||
--
|
||||
-- Any class derived from BASE, must use the @{Base#BASE.New) constructor within the @{Base#BASE.Inherit) method.
|
||||
-- See an example at the @{Base#BASE.New} method how this is done.
|
||||
--
|
||||
-- ## 1.2) BASE Trace functionality
|
||||
--
|
||||
-- The BASE class contains trace methods to trace progress within a mission execution of a certain object.
|
||||
-- Note that these trace methods are inherited by each MOOSE class interiting BASE.
|
||||
-- As such, each object created from derived class from BASE can use the tracing functions to trace its execution.
|
||||
--
|
||||
-- ### 1.2.1) Tracing functions
|
||||
--
|
||||
-- There are basically 3 types of tracing methods available within BASE:
|
||||
--
|
||||
-- * @{#BASE.F}: Trace the beginning of a function and its given parameters. An F is indicated at column 44 in the DCS.log file.
|
||||
-- * @{#BASE.T}: Trace further logic within a function giving optional variables or parameters. A T is indicated at column 44 in the DCS.log file.
|
||||
-- * @{#BASE.E}: Trace an exception within a function giving optional variables or parameters. An E is indicated at column 44 in the DCS.log file. An exception will always be traced.
|
||||
--
|
||||
-- ### 1.2.2) Tracing levels
|
||||
--
|
||||
-- There are 3 tracing levels within MOOSE.
|
||||
-- These tracing levels were defined to avoid bulks of tracing to be generated by lots of objects.
|
||||
--
|
||||
-- As such, the F and T methods have additional variants to trace level 2 and 3 respectively:
|
||||
--
|
||||
-- * @{#BASE.F2}: Trace the beginning of a function and its given parameters with tracing level 2.
|
||||
-- * @{#BASE.F3}: Trace the beginning of a function and its given parameters with tracing level 3.
|
||||
-- * @{#BASE.T2}: Trace further logic within a function giving optional variables or parameters with tracing level 2.
|
||||
-- * @{#BASE.T3}: Trace further logic within a function giving optional variables or parameters with tracing level 3.
|
||||
--
|
||||
-- ### 1.2.3) Trace activation.
|
||||
--
|
||||
-- Tracing can be activated in several ways:
|
||||
--
|
||||
-- * Switch tracing on or off through the @{#BASE.TraceOnOff}() method.
|
||||
-- * Activate all tracing through the @{#BASE.TraceAll}() method.
|
||||
-- * Activate only the tracing of a certain class (name) through the @{#BASE.TraceClass}() method.
|
||||
-- * Activate only the tracing of a certain method of a certain class through the @{#BASE.TraceClassMethod}() method.
|
||||
-- * Activate only the tracing of a certain level through the @{#BASE.TraceLevel}() method.
|
||||
-- ### 1.2.4) Check if tracing is on.
|
||||
--
|
||||
-- The method @{#BASE.IsTrace}() will validate if tracing is activated or not.
|
||||
--
|
||||
-- ## 1.3 DCS simulator Event Handling
|
||||
--
|
||||
-- The BASE class provides methods to catch DCS Events. These are events that are triggered from within the DCS simulator,
|
||||
-- and handled through lua scripting. MOOSE provides an encapsulation to handle these events more efficiently.
|
||||
--
|
||||
-- ### 1.3.1 Subscribe / Unsubscribe to DCS Events
|
||||
--
|
||||
-- At first, the mission designer will need to **Subscribe** to a specific DCS event for the class.
|
||||
-- So, when the DCS event occurs, the class will be notified of that event.
|
||||
-- There are two functions which you use to subscribe to or unsubscribe from an event.
|
||||
--
|
||||
-- * @{#BASE.HandleEvent}(): Subscribe to a DCS Event.
|
||||
-- * @{#BASE.UnHandleEvent}(): Unsubscribe from a DCS Event.
|
||||
--
|
||||
-- ### 1.3.2 Event Handling of DCS Events
|
||||
--
|
||||
-- Once the class is subscribed to the event, an **Event Handling** method on the object or class needs to be written that will be called
|
||||
-- when the DCS event occurs. The Event Handling method receives an @{Event#EVENTDATA} structure, which contains a lot of information
|
||||
-- about the event that occurred.
|
||||
--
|
||||
-- Find below an example of the prototype how to write an event handling function for two units:
|
||||
--
|
||||
-- local Tank1 = UNIT:FindByName( "Tank A" )
|
||||
-- local Tank2 = UNIT:FindByName( "Tank B" )
|
||||
--
|
||||
-- -- Here we subscribe to the Dead events. So, if one of these tanks dies, the Tank1 or Tank2 objects will be notified.
|
||||
-- Tank1:HandleEvent( EVENTS.Dead )
|
||||
-- Tank2:HandleEvent( EVENTS.Dead )
|
||||
--
|
||||
-- --- This function is an Event Handling function that will be called when Tank1 is Dead.
|
||||
-- -- @param Wrapper.Unit#UNIT self
|
||||
-- -- @param Core.Event#EVENTDATA EventData
|
||||
-- function Tank1:OnEventDead( EventData )
|
||||
--
|
||||
-- self:SmokeGreen()
|
||||
-- end
|
||||
--
|
||||
-- --- This function is an Event Handling function that will be called when Tank2 is Dead.
|
||||
-- -- @param Wrapper.Unit#UNIT self
|
||||
-- -- @param Core.Event#EVENTDATA EventData
|
||||
-- function Tank2:OnEventDead( EventData )
|
||||
--
|
||||
-- self:SmokeBlue()
|
||||
-- end
|
||||
--
|
||||
--
|
||||
--
|
||||
-- See the @{Event} module for more information about event handling.
|
||||
--
|
||||
-- ## 1.4) Class identification methods
|
||||
--
|
||||
-- BASE provides methods to get more information of each object:
|
||||
--
|
||||
-- * @{#BASE.GetClassID}(): Gets the ID (number) of the object. Each object created is assigned a number, that is incremented by one.
|
||||
-- * @{#BASE.GetClassName}(): Gets the name of the object, which is the name of the class the object was instantiated from.
|
||||
-- * @{#BASE.GetClassNameAndID}(): Gets the name and ID of the object.
|
||||
--
|
||||
-- ## 1.5) All objects derived from BASE can have "States"
|
||||
--
|
||||
-- A mechanism is in place in MOOSE, that allows to let the objects administer **states**.
|
||||
-- States are essentially properties of objects, which are identified by a **Key** and a **Value**.
|
||||
-- The method @{#BASE.SetState}() can be used to set a Value with a reference Key to the object.
|
||||
-- To **read or retrieve** a state Value based on a Key, use the @{#BASE.GetState} method.
|
||||
-- These two methods provide a very handy way to keep state at long lasting processes.
|
||||
-- Values can be stored within the objects, and later retrieved or changed when needed.
|
||||
-- There is one other important thing to note, the @{#BASE.SetState}() and @{#BASE.GetState} methods
|
||||
-- receive as the **first parameter the object for which the state needs to be set**.
|
||||
-- Thus, if the state is to be set for the same object as the object for which the method is used, then provide the same
|
||||
-- object name to the method.
|
||||
--
|
||||
-- ## 1.10) BASE Inheritance (tree) support
|
||||
--
|
||||
-- The following methods are available to support inheritance:
|
||||
--
|
||||
-- * @{#BASE.Inherit}: Inherits from a class.
|
||||
-- * @{#BASE.GetParent}: Returns the parent object from the object it is handling, or nil if there is no parent object.
|
||||
--
|
||||
-- ====
|
||||
--
|
||||
-- # **API CHANGE HISTORY**
|
||||
--
|
||||
-- The underlying change log documents the API changes. Please read this carefully. The following notation is used:
|
||||
--
|
||||
-- * **Added** parts are expressed in bold type face.
|
||||
-- * _Removed_ parts are expressed in italic type face.
|
||||
--
|
||||
-- YYYY-MM-DD: CLASS:**NewFunction**( Params ) replaces CLASS:_OldFunction_( Params )
|
||||
-- YYYY-MM-DD: CLASS:**NewFunction( Params )** added
|
||||
--
|
||||
-- Hereby the change log:
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- # **AUTHORS and CONTRIBUTIONS**
|
||||
--
|
||||
-- ### Contributions:
|
||||
--
|
||||
-- * None.
|
||||
--
|
||||
-- ### Authors:
|
||||
--
|
||||
-- * **FlightControl**: Design & Programming
|
||||
--
|
||||
-- @module Base
|
||||
|
||||
|
||||
|
||||
local _TraceOnOff = true
|
||||
local _TraceLevel = 1
|
||||
local _TraceAll = false
|
||||
local _TraceClass = {}
|
||||
local _TraceClassMethod = {}
|
||||
|
||||
local _ClassID = 0
|
||||
|
||||
--- The BASE Class
|
||||
-- @type BASE
|
||||
-- @field ClassName The name of the class.
|
||||
-- @field ClassID The ID number of the class.
|
||||
-- @field ClassNameAndID The name of the class concatenated with the ID number of the class.
|
||||
BASE = {
|
||||
ClassName = "BASE",
|
||||
ClassID = 0,
|
||||
_Private = {},
|
||||
Events = {},
|
||||
States = {}
|
||||
}
|
||||
|
||||
--- The Formation Class
|
||||
-- @type FORMATION
|
||||
-- @field Cone A cone formation.
|
||||
FORMATION = {
|
||||
Cone = "Cone"
|
||||
}
|
||||
|
||||
|
||||
|
||||
-- @todo need to investigate if the deepCopy is really needed... Don't think so.
|
||||
function BASE:New()
|
||||
local self = routines.utils.deepCopy( self ) -- Create a new self instance
|
||||
local MetaTable = {}
|
||||
setmetatable( self, MetaTable )
|
||||
self.__index = self
|
||||
_ClassID = _ClassID + 1
|
||||
self.ClassID = _ClassID
|
||||
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function BASE:_Destructor()
|
||||
--self:E("_Destructor")
|
||||
|
||||
--self:EventRemoveAll()
|
||||
end
|
||||
|
||||
function BASE:_SetDestructor()
|
||||
|
||||
-- TODO: Okay, this is really technical...
|
||||
-- When you set a proxy to a table to catch __gc, weak tables don't behave like weak...
|
||||
-- Therefore, I am parking this logic until I've properly discussed all this with the community.
|
||||
--[[
|
||||
local proxy = newproxy(true)
|
||||
local proxyMeta = getmetatable(proxy)
|
||||
|
||||
proxyMeta.__gc = function ()
|
||||
env.info("In __gc for " .. self:GetClassNameAndID() )
|
||||
if self._Destructor then
|
||||
self:_Destructor()
|
||||
end
|
||||
end
|
||||
|
||||
-- keep the userdata from newproxy reachable until the object
|
||||
-- table is about to be garbage-collected - then the __gc hook
|
||||
-- will be invoked and the destructor called
|
||||
rawset( self, '__proxy', proxy )
|
||||
--]]
|
||||
end
|
||||
|
||||
--- This is the worker method to inherit from a parent class.
|
||||
-- @param #BASE self
|
||||
-- @param Child is the Child class that inherits.
|
||||
-- @param #BASE Parent is the Parent class that the Child inherits from.
|
||||
-- @return #BASE Child
|
||||
function BASE:Inherit( Child, Parent )
|
||||
local Child = routines.utils.deepCopy( Child )
|
||||
--local Parent = routines.utils.deepCopy( Parent )
|
||||
--local Parent = Parent
|
||||
if Child ~= nil then
|
||||
setmetatable( Child, Parent )
|
||||
Child.__index = Child
|
||||
|
||||
Child:_SetDestructor()
|
||||
end
|
||||
--self:T( 'Inherited from ' .. Parent.ClassName )
|
||||
return Child
|
||||
end
|
||||
|
||||
--- This is the worker method to retrieve the Parent class.
|
||||
-- @param #BASE self
|
||||
-- @param #BASE Child is the Child class from which the Parent class needs to be retrieved.
|
||||
-- @return #BASE
|
||||
function BASE:GetParent( Child )
|
||||
local Parent = getmetatable( Child )
|
||||
-- env.info('Inherited class of ' .. Child.ClassName .. ' is ' .. Parent.ClassName )
|
||||
return Parent
|
||||
end
|
||||
|
||||
--- Get the ClassName + ClassID of the class instance.
|
||||
-- The ClassName + ClassID is formatted as '%s#%09d'.
|
||||
-- @param #BASE self
|
||||
-- @return #string The ClassName + ClassID of the class instance.
|
||||
function BASE:GetClassNameAndID()
|
||||
return string.format( '%s#%09d', self.ClassName, self.ClassID )
|
||||
end
|
||||
|
||||
--- Get the ClassName of the class instance.
|
||||
-- @param #BASE self
|
||||
-- @return #string The ClassName of the class instance.
|
||||
function BASE:GetClassName()
|
||||
return self.ClassName
|
||||
end
|
||||
|
||||
--- Get the ClassID of the class instance.
|
||||
-- @param #BASE self
|
||||
-- @return #string The ClassID of the class instance.
|
||||
function BASE:GetClassID()
|
||||
return self.ClassID
|
||||
end
|
||||
|
||||
do -- Event Handling
|
||||
|
||||
--- Returns the event dispatcher
|
||||
-- @param #BASE self
|
||||
-- @return Core.Event#EVENT
|
||||
function BASE:EventDispatcher()
|
||||
|
||||
return _EVENTDISPATCHER
|
||||
end
|
||||
|
||||
|
||||
--- Get the Class @{Event} processing Priority.
|
||||
-- The Event processing Priority is a number from 1 to 10,
|
||||
-- reflecting the order of the classes subscribed to the Event to be processed.
|
||||
-- @param #BASE self
|
||||
-- @return #number The @{Event} processing Priority.
|
||||
function BASE:GetEventPriority()
|
||||
return self._Private.EventPriority or 5
|
||||
end
|
||||
|
||||
--- Set the Class @{Event} processing Priority.
|
||||
-- The Event processing Priority is a number from 1 to 10,
|
||||
-- reflecting the order of the classes subscribed to the Event to be processed.
|
||||
-- @param #BASE self
|
||||
-- @param #number EventPriority The @{Event} processing Priority.
|
||||
-- @return self
|
||||
function BASE:SetEventPriority( EventPriority )
|
||||
self._Private.EventPriority = EventPriority
|
||||
end
|
||||
|
||||
--- Remove all subscribed events
|
||||
-- @param #BASE self
|
||||
-- @return #BASE
|
||||
function BASE:EventRemoveAll()
|
||||
|
||||
self:EventDispatcher():RemoveAll( self )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Subscribe to a DCS Event.
|
||||
-- @param #BASE self
|
||||
-- @param Core.Event#EVENTS Event
|
||||
-- @param #function EventFunction (optional) The function to be called when the event occurs for the unit.
|
||||
-- @return #BASE
|
||||
function BASE:HandleEvent( Event, EventFunction )
|
||||
|
||||
self:EventDispatcher():OnEventGeneric( EventFunction, self, Event )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- UnSubscribe to a DCS event.
|
||||
-- @param #BASE self
|
||||
-- @param Core.Event#EVENTS Event
|
||||
-- @return #BASE
|
||||
function BASE:UnHandleEvent( Event )
|
||||
|
||||
self:EventDispatcher():Remove( self, Event )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
-- Event handling function prototypes
|
||||
|
||||
--- Occurs whenever any unit in a mission fires a weapon. But not any machine gun or autocannon based weapon, those are handled by EVENT.ShootingStart.
|
||||
-- @function [parent=#BASE] OnEventShot
|
||||
-- @param #BASE self
|
||||
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
||||
|
||||
--- Occurs whenever an object is hit by a weapon.
|
||||
-- initiator : The unit object the fired the weapon
|
||||
-- weapon: Weapon object that hit the target
|
||||
-- target: The Object that was hit.
|
||||
-- @function [parent=#BASE] OnEventHit
|
||||
-- @param #BASE self
|
||||
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
||||
|
||||
--- Occurs when an aircraft takes off from an airbase, farp, or ship.
|
||||
-- initiator : The unit that tookoff
|
||||
-- place: Object from where the AI took-off from. Can be an Airbase Object, FARP, or Ships
|
||||
-- @function [parent=#BASE] OnEventTakeoff
|
||||
-- @param #BASE self
|
||||
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
||||
|
||||
--- Occurs when an aircraft lands at an airbase, farp or ship
|
||||
-- initiator : The unit that has landed
|
||||
-- place: Object that the unit landed on. Can be an Airbase Object, FARP, or Ships
|
||||
-- @function [parent=#BASE] OnEventLand
|
||||
-- @param #BASE self
|
||||
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
||||
|
||||
--- Occurs when any aircraft crashes into the ground and is completely destroyed.
|
||||
-- initiator : The unit that has crashed
|
||||
-- @function [parent=#BASE] OnEventCrash
|
||||
-- @param #BASE self
|
||||
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
||||
|
||||
--- Occurs when a pilot ejects from an aircraft
|
||||
-- initiator : The unit that has ejected
|
||||
-- @function [parent=#BASE] OnEventEjection
|
||||
-- @param #BASE self
|
||||
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
||||
|
||||
--- Occurs when an aircraft connects with a tanker and begins taking on fuel.
|
||||
-- initiator : The unit that is receiving fuel.
|
||||
-- @function [parent=#BASE] OnEventRefueling
|
||||
-- @param #BASE self
|
||||
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
||||
|
||||
--- Occurs when an object is completely destroyed.
|
||||
-- initiator : The unit that is was destroyed.
|
||||
-- @function [parent=#BASE] OnEvent
|
||||
-- @param #BASE self
|
||||
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
||||
|
||||
--- Occurs when the pilot of an aircraft is killed. Can occur either if the player is alive and crashes or if a weapon kills the pilot without completely destroying the plane.
|
||||
-- initiator : The unit that the pilot has died in.
|
||||
-- @function [parent=#BASE] OnEventPilotDead
|
||||
-- @param #BASE self
|
||||
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
||||
|
||||
--- Occurs when a ground unit captures either an airbase or a farp.
|
||||
-- initiator : The unit that captured the base
|
||||
-- place: The airbase that was captured, can be a FARP or Airbase. When calling place:getCoalition() the faction will already be the new owning faction.
|
||||
-- @function [parent=#BASE] OnEventBaseCaptured
|
||||
-- @param #BASE self
|
||||
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
||||
|
||||
--- Occurs when a mission starts
|
||||
-- @function [parent=#BASE] OnEventMissionStart
|
||||
-- @param #BASE self
|
||||
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
||||
|
||||
--- Occurs when a mission ends
|
||||
-- @function [parent=#BASE] OnEventMissionEnd
|
||||
-- @param #BASE self
|
||||
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
||||
|
||||
--- Occurs when an aircraft is finished taking fuel.
|
||||
-- initiator : The unit that was receiving fuel.
|
||||
-- @function [parent=#BASE] OnEventRefuelingStop
|
||||
-- @param #BASE self
|
||||
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
||||
|
||||
--- Occurs when any object is spawned into the mission.
|
||||
-- initiator : The unit that was spawned
|
||||
-- @function [parent=#BASE] OnEventBirth
|
||||
-- @param #BASE self
|
||||
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
||||
|
||||
--- Occurs when any system fails on a human controlled aircraft.
|
||||
-- initiator : The unit that had the failure
|
||||
-- @function [parent=#BASE] OnEventHumanFailure
|
||||
-- @param #BASE self
|
||||
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
||||
|
||||
--- Occurs when any aircraft starts its engines.
|
||||
-- initiator : The unit that is starting its engines.
|
||||
-- @function [parent=#BASE] OnEventEngineStartup
|
||||
-- @param #BASE self
|
||||
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
||||
|
||||
--- Occurs when any aircraft shuts down its engines.
|
||||
-- initiator : The unit that is stopping its engines.
|
||||
-- @function [parent=#BASE] OnEventEngineShutdown
|
||||
-- @param #BASE self
|
||||
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
||||
|
||||
--- Occurs when any player assumes direct control of a unit.
|
||||
-- initiator : The unit that is being taken control of.
|
||||
-- @function [parent=#BASE] OnEventPlayerEnterUnit
|
||||
-- @param #BASE self
|
||||
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
||||
|
||||
--- Occurs when any player relieves control of a unit to the AI.
|
||||
-- initiator : The unit that the player left.
|
||||
-- @function [parent=#BASE] OnEventPlayerLeaveUnit
|
||||
-- @param #BASE self
|
||||
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
||||
|
||||
--- Occurs when any unit begins firing a weapon that has a high rate of fire. Most common with aircraft cannons (GAU-8), autocannons, and machine guns.
|
||||
-- initiator : The unit that is doing the shooing.
|
||||
-- target: The unit that is being targeted.
|
||||
-- @function [parent=#BASE] OnEventShootingStart
|
||||
-- @param #BASE self
|
||||
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
||||
|
||||
--- Occurs when any unit stops firing its weapon. Event will always correspond with a shooting start event.
|
||||
-- initiator : The unit that was doing the shooing.
|
||||
-- @function [parent=#BASE] OnEventShootingEnd
|
||||
-- @param #BASE self
|
||||
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
||||
|
||||
end
|
||||
|
||||
|
||||
--- Creation of a Birth Event.
|
||||
-- @param #BASE self
|
||||
-- @param Dcs.DCSTypes#Time EventTime The time stamp of the event.
|
||||
-- @param Dcs.DCSWrapper.Object#Object Initiator The initiating object of the event.
|
||||
-- @param #string IniUnitName The initiating unit name.
|
||||
-- @param place
|
||||
-- @param subplace
|
||||
function BASE:CreateEventBirth( EventTime, Initiator, IniUnitName, place, subplace )
|
||||
self:F( { EventTime, Initiator, IniUnitName, place, subplace } )
|
||||
|
||||
local Event = {
|
||||
id = world.event.S_EVENT_BIRTH,
|
||||
time = EventTime,
|
||||
initiator = Initiator,
|
||||
IniUnitName = IniUnitName,
|
||||
place = place,
|
||||
subplace = subplace
|
||||
}
|
||||
|
||||
world.onEvent( Event )
|
||||
end
|
||||
|
||||
--- Creation of a Crash Event.
|
||||
-- @param #BASE self
|
||||
-- @param Dcs.DCSTypes#Time EventTime The time stamp of the event.
|
||||
-- @param Dcs.DCSWrapper.Object#Object Initiator The initiating object of the event.
|
||||
function BASE:CreateEventCrash( EventTime, Initiator )
|
||||
self:F( { EventTime, Initiator } )
|
||||
|
||||
local Event = {
|
||||
id = world.event.S_EVENT_CRASH,
|
||||
time = EventTime,
|
||||
initiator = Initiator,
|
||||
}
|
||||
|
||||
world.onEvent( Event )
|
||||
end
|
||||
|
||||
-- TODO: Complete Dcs.DCSTypes#Event structure.
|
||||
--- The main event handling function... This function captures all events generated for the class.
|
||||
-- @param #BASE self
|
||||
-- @param Dcs.DCSTypes#Event event
|
||||
function BASE:onEvent(event)
|
||||
--self:F( { BaseEventCodes[event.id], event } )
|
||||
|
||||
if self then
|
||||
for EventID, EventObject in pairs( self.Events ) do
|
||||
if EventObject.EventEnabled then
|
||||
--env.info( 'onEvent Table EventObject.Self = ' .. tostring(EventObject.Self) )
|
||||
--env.info( 'onEvent event.id = ' .. tostring(event.id) )
|
||||
--env.info( 'onEvent EventObject.Event = ' .. tostring(EventObject.Event) )
|
||||
if event.id == EventObject.Event then
|
||||
if self == EventObject.Self then
|
||||
if event.initiator and event.initiator:isExist() then
|
||||
event.IniUnitName = event.initiator:getName()
|
||||
end
|
||||
if event.target and event.target:isExist() then
|
||||
event.TgtUnitName = event.target:getName()
|
||||
end
|
||||
--self:T( { BaseEventCodes[event.id], event } )
|
||||
--EventObject.EventFunction( self, event )
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- Set a state or property of the Object given a Key and a Value.
|
||||
-- Note that if the Object is destroyed, nillified or garbage collected, then the Values and Keys will also be gone.
|
||||
-- @param #BASE self
|
||||
-- @param Object The object that will hold the Value set by the Key.
|
||||
-- @param Key The key that is used as a reference of the value. Note that the key can be a #string, but it can also be any other type!
|
||||
-- @param Value The value to is stored in the object.
|
||||
-- @return The Value set.
|
||||
-- @return #nil The Key was not found and thus the Value could not be retrieved.
|
||||
function BASE:SetState( Object, Key, Value )
|
||||
|
||||
local ClassNameAndID = Object:GetClassNameAndID()
|
||||
|
||||
self.States[ClassNameAndID] = self.States[ClassNameAndID] or {}
|
||||
self.States[ClassNameAndID][Key] = Value
|
||||
self:T2( { ClassNameAndID, Key, Value } )
|
||||
|
||||
return self.States[ClassNameAndID][Key]
|
||||
end
|
||||
|
||||
|
||||
--- Get a Value given a Key from the Object.
|
||||
-- Note that if the Object is destroyed, nillified or garbage collected, then the Values and Keys will also be gone.
|
||||
-- @param #BASE self
|
||||
-- @param Object The object that holds the Value set by the Key.
|
||||
-- @param Key The key that is used to retrieve the value. Note that the key can be a #string, but it can also be any other type!
|
||||
-- @param Value The value to is stored in the Object.
|
||||
-- @return The Value retrieved.
|
||||
function BASE:GetState( Object, Key )
|
||||
|
||||
local ClassNameAndID = Object:GetClassNameAndID()
|
||||
|
||||
if self.States[ClassNameAndID] then
|
||||
local Value = self.States[ClassNameAndID][Key] or false
|
||||
self:T2( { ClassNameAndID, Key, Value } )
|
||||
return Value
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
function BASE:ClearState( Object, StateName )
|
||||
|
||||
local ClassNameAndID = Object:GetClassNameAndID()
|
||||
if self.States[ClassNameAndID] then
|
||||
self.States[ClassNameAndID][StateName] = nil
|
||||
end
|
||||
end
|
||||
|
||||
-- Trace section
|
||||
|
||||
-- Log a trace (only shown when trace is on)
|
||||
-- TODO: Make trace function using variable parameters.
|
||||
|
||||
--- Set trace on or off
|
||||
-- Note that when trace is off, no debug statement is performed, increasing performance!
|
||||
-- When Moose is loaded statically, (as one file), tracing is switched off by default.
|
||||
-- So tracing must be switched on manually in your mission if you are using Moose statically.
|
||||
-- When moose is loading dynamically (for moose class development), tracing is switched on by default.
|
||||
-- @param #BASE self
|
||||
-- @param #boolean TraceOnOff Switch the tracing on or off.
|
||||
-- @usage
|
||||
-- -- Switch the tracing On
|
||||
-- BASE:TraceOnOff( true )
|
||||
--
|
||||
-- -- Switch the tracing Off
|
||||
-- BASE:TraceOnOff( false )
|
||||
function BASE:TraceOnOff( TraceOnOff )
|
||||
_TraceOnOff = TraceOnOff
|
||||
end
|
||||
|
||||
|
||||
--- Enquires if tracing is on (for the class).
|
||||
-- @param #BASE self
|
||||
-- @return #boolean
|
||||
function BASE:IsTrace()
|
||||
|
||||
if debug and ( _TraceAll == true ) or ( _TraceClass[self.ClassName] or _TraceClassMethod[self.ClassName] ) then
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
--- Set trace level
|
||||
-- @param #BASE self
|
||||
-- @param #number Level
|
||||
function BASE:TraceLevel( Level )
|
||||
_TraceLevel = Level
|
||||
self:E( "Tracing level " .. Level )
|
||||
end
|
||||
|
||||
--- Trace all methods in MOOSE
|
||||
-- @param #BASE self
|
||||
-- @param #boolean TraceAll true = trace all methods in MOOSE.
|
||||
function BASE:TraceAll( TraceAll )
|
||||
|
||||
_TraceAll = TraceAll
|
||||
|
||||
if _TraceAll then
|
||||
self:E( "Tracing all methods in MOOSE " )
|
||||
else
|
||||
self:E( "Switched off tracing all methods in MOOSE" )
|
||||
end
|
||||
end
|
||||
|
||||
--- Set tracing for a class
|
||||
-- @param #BASE self
|
||||
-- @param #string Class
|
||||
function BASE:TraceClass( Class )
|
||||
_TraceClass[Class] = true
|
||||
_TraceClassMethod[Class] = {}
|
||||
self:E( "Tracing class " .. Class )
|
||||
end
|
||||
|
||||
--- Set tracing for a specific method of class
|
||||
-- @param #BASE self
|
||||
-- @param #string Class
|
||||
-- @param #string Method
|
||||
function BASE:TraceClassMethod( Class, Method )
|
||||
if not _TraceClassMethod[Class] then
|
||||
_TraceClassMethod[Class] = {}
|
||||
_TraceClassMethod[Class].Method = {}
|
||||
end
|
||||
_TraceClassMethod[Class].Method[Method] = true
|
||||
self:E( "Tracing method " .. Method .. " of class " .. Class )
|
||||
end
|
||||
|
||||
--- Trace a function call. This function is private.
|
||||
-- @param #BASE self
|
||||
-- @param Arguments A #table or any field.
|
||||
function BASE:_F( Arguments, DebugInfoCurrentParam, DebugInfoFromParam )
|
||||
|
||||
if debug and ( _TraceAll == true ) or ( _TraceClass[self.ClassName] or _TraceClassMethod[self.ClassName] ) then
|
||||
|
||||
local DebugInfoCurrent = DebugInfoCurrentParam and DebugInfoCurrentParam or debug.getinfo( 2, "nl" )
|
||||
local DebugInfoFrom = DebugInfoFromParam and DebugInfoFromParam or debug.getinfo( 3, "l" )
|
||||
|
||||
local Function = "function"
|
||||
if DebugInfoCurrent.name then
|
||||
Function = DebugInfoCurrent.name
|
||||
end
|
||||
|
||||
if _TraceAll == true or _TraceClass[self.ClassName] or _TraceClassMethod[self.ClassName].Method[Function] then
|
||||
local LineCurrent = 0
|
||||
if DebugInfoCurrent.currentline then
|
||||
LineCurrent = DebugInfoCurrent.currentline
|
||||
end
|
||||
local LineFrom = 0
|
||||
if DebugInfoFrom then
|
||||
LineFrom = DebugInfoFrom.currentline
|
||||
end
|
||||
env.info( string.format( "%6d(%6d)/%1s:%20s%05d.%s(%s)" , LineCurrent, LineFrom, "F", self.ClassName, self.ClassID, Function, routines.utils.oneLineSerialize( Arguments ) ) )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- Trace a function call. Must be at the beginning of the function logic.
|
||||
-- @param #BASE self
|
||||
-- @param Arguments A #table or any field.
|
||||
function BASE:F( Arguments )
|
||||
|
||||
if debug and _TraceOnOff then
|
||||
local DebugInfoCurrent = debug.getinfo( 2, "nl" )
|
||||
local DebugInfoFrom = debug.getinfo( 3, "l" )
|
||||
|
||||
if _TraceLevel >= 1 then
|
||||
self:_F( Arguments, DebugInfoCurrent, DebugInfoFrom )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--- Trace a function call level 2. Must be at the beginning of the function logic.
|
||||
-- @param #BASE self
|
||||
-- @param Arguments A #table or any field.
|
||||
function BASE:F2( Arguments )
|
||||
|
||||
if debug and _TraceOnOff then
|
||||
local DebugInfoCurrent = debug.getinfo( 2, "nl" )
|
||||
local DebugInfoFrom = debug.getinfo( 3, "l" )
|
||||
|
||||
if _TraceLevel >= 2 then
|
||||
self:_F( Arguments, DebugInfoCurrent, DebugInfoFrom )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- Trace a function call level 3. Must be at the beginning of the function logic.
|
||||
-- @param #BASE self
|
||||
-- @param Arguments A #table or any field.
|
||||
function BASE:F3( Arguments )
|
||||
|
||||
if debug and _TraceOnOff then
|
||||
local DebugInfoCurrent = debug.getinfo( 2, "nl" )
|
||||
local DebugInfoFrom = debug.getinfo( 3, "l" )
|
||||
|
||||
if _TraceLevel >= 3 then
|
||||
self:_F( Arguments, DebugInfoCurrent, DebugInfoFrom )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- Trace a function logic.
|
||||
-- @param #BASE self
|
||||
-- @param Arguments A #table or any field.
|
||||
function BASE:_T( Arguments, DebugInfoCurrentParam, DebugInfoFromParam )
|
||||
|
||||
if debug and ( _TraceAll == true ) or ( _TraceClass[self.ClassName] or _TraceClassMethod[self.ClassName] ) then
|
||||
|
||||
local DebugInfoCurrent = DebugInfoCurrentParam and DebugInfoCurrentParam or debug.getinfo( 2, "nl" )
|
||||
local DebugInfoFrom = DebugInfoFromParam and DebugInfoFromParam or debug.getinfo( 3, "l" )
|
||||
|
||||
local Function = "function"
|
||||
if DebugInfoCurrent.name then
|
||||
Function = DebugInfoCurrent.name
|
||||
end
|
||||
|
||||
if _TraceAll == true or _TraceClass[self.ClassName] or _TraceClassMethod[self.ClassName].Method[Function] then
|
||||
local LineCurrent = 0
|
||||
if DebugInfoCurrent.currentline then
|
||||
LineCurrent = DebugInfoCurrent.currentline
|
||||
end
|
||||
local LineFrom = 0
|
||||
if DebugInfoFrom then
|
||||
LineFrom = DebugInfoFrom.currentline
|
||||
end
|
||||
env.info( string.format( "%6d(%6d)/%1s:%20s%05d.%s" , LineCurrent, LineFrom, "T", self.ClassName, self.ClassID, routines.utils.oneLineSerialize( Arguments ) ) )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- Trace a function logic level 1. Can be anywhere within the function logic.
|
||||
-- @param #BASE self
|
||||
-- @param Arguments A #table or any field.
|
||||
function BASE:T( Arguments )
|
||||
|
||||
if debug and _TraceOnOff then
|
||||
local DebugInfoCurrent = debug.getinfo( 2, "nl" )
|
||||
local DebugInfoFrom = debug.getinfo( 3, "l" )
|
||||
|
||||
if _TraceLevel >= 1 then
|
||||
self:_T( Arguments, DebugInfoCurrent, DebugInfoFrom )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--- Trace a function logic level 2. Can be anywhere within the function logic.
|
||||
-- @param #BASE self
|
||||
-- @param Arguments A #table or any field.
|
||||
function BASE:T2( Arguments )
|
||||
|
||||
if debug and _TraceOnOff then
|
||||
local DebugInfoCurrent = debug.getinfo( 2, "nl" )
|
||||
local DebugInfoFrom = debug.getinfo( 3, "l" )
|
||||
|
||||
if _TraceLevel >= 2 then
|
||||
self:_T( Arguments, DebugInfoCurrent, DebugInfoFrom )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- Trace a function logic level 3. Can be anywhere within the function logic.
|
||||
-- @param #BASE self
|
||||
-- @param Arguments A #table or any field.
|
||||
function BASE:T3( Arguments )
|
||||
|
||||
if debug and _TraceOnOff then
|
||||
local DebugInfoCurrent = debug.getinfo( 2, "nl" )
|
||||
local DebugInfoFrom = debug.getinfo( 3, "l" )
|
||||
|
||||
if _TraceLevel >= 3 then
|
||||
self:_T( Arguments, DebugInfoCurrent, DebugInfoFrom )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- Log an exception which will be traced always. Can be anywhere within the function logic.
|
||||
-- @param #BASE self
|
||||
-- @param Arguments A #table or any field.
|
||||
function BASE:E( Arguments )
|
||||
|
||||
if debug then
|
||||
local DebugInfoCurrent = debug.getinfo( 2, "nl" )
|
||||
local DebugInfoFrom = debug.getinfo( 3, "l" )
|
||||
|
||||
local Function = "function"
|
||||
if DebugInfoCurrent.name then
|
||||
Function = DebugInfoCurrent.name
|
||||
end
|
||||
|
||||
local LineCurrent = DebugInfoCurrent.currentline
|
||||
local LineFrom = -1
|
||||
if DebugInfoFrom then
|
||||
LineFrom = DebugInfoFrom.currentline
|
||||
end
|
||||
|
||||
env.info( string.format( "%6d(%6d)/%1s:%20s%05d.%s(%s)" , LineCurrent, LineFrom, "E", self.ClassName, self.ClassID, Function, routines.utils.oneLineSerialize( Arguments ) ) )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
787
Moose Development/Moose/Core/Database.lua
Normal file
787
Moose Development/Moose/Core/Database.lua
Normal file
@@ -0,0 +1,787 @@
|
||||
--- This module contains the DATABASE class, managing the database of mission objects.
|
||||
--
|
||||
-- ====
|
||||
--
|
||||
-- 1) @{#DATABASE} class, extends @{Base#BASE}
|
||||
-- ===================================================
|
||||
-- Mission designers can use the DATABASE class to refer to:
|
||||
--
|
||||
-- * UNITS
|
||||
-- * GROUPS
|
||||
-- * CLIENTS
|
||||
-- * AIRPORTS
|
||||
-- * PLAYERSJOINED
|
||||
-- * PLAYERS
|
||||
--
|
||||
-- On top, for internal MOOSE administration purposes, the DATBASE administers the Unit and Group TEMPLATES as defined within the Mission Editor.
|
||||
--
|
||||
-- Moose will automatically create one instance of the DATABASE class into the **global** object _DATABASE.
|
||||
-- Moose refers to _DATABASE within the framework extensively, but you can also refer to the _DATABASE object within your missions if required.
|
||||
--
|
||||
-- 1.1) DATABASE iterators
|
||||
-- -----------------------
|
||||
-- You can iterate the database with the available iterator methods.
|
||||
-- The iterator methods will walk the DATABASE set, and call for each element within the set a function that you provide.
|
||||
-- The following iterator methods are currently available within the DATABASE:
|
||||
--
|
||||
-- * @{#DATABASE.ForEachUnit}: Calls a function for each @{UNIT} it finds within the DATABASE.
|
||||
-- * @{#DATABASE.ForEachGroup}: Calls a function for each @{GROUP} it finds within the DATABASE.
|
||||
-- * @{#DATABASE.ForEachPlayer}: Calls a function for each alive player it finds within the DATABASE.
|
||||
-- * @{#DATABASE.ForEachPlayerJoined}: Calls a function for each joined player it finds within the DATABASE.
|
||||
-- * @{#DATABASE.ForEachClient}: Calls a function for each @{CLIENT} it finds within the DATABASE.
|
||||
-- * @{#DATABASE.ForEachClientAlive}: Calls a function for each alive @{CLIENT} it finds within the DATABASE.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- @module Database
|
||||
-- @author FlightControl
|
||||
|
||||
--- DATABASE class
|
||||
-- @type DATABASE
|
||||
-- @extends Core.Base#BASE
|
||||
DATABASE = {
|
||||
ClassName = "DATABASE",
|
||||
Templates = {
|
||||
Units = {},
|
||||
Groups = {},
|
||||
ClientsByName = {},
|
||||
ClientsByID = {},
|
||||
},
|
||||
UNITS = {},
|
||||
STATICS = {},
|
||||
GROUPS = {},
|
||||
PLAYERS = {},
|
||||
PLAYERSJOINED = {},
|
||||
CLIENTS = {},
|
||||
AIRBASES = {},
|
||||
NavPoints = {},
|
||||
}
|
||||
|
||||
local _DATABASECoalition =
|
||||
{
|
||||
[1] = "Red",
|
||||
[2] = "Blue",
|
||||
}
|
||||
|
||||
local _DATABASECategory =
|
||||
{
|
||||
["plane"] = Unit.Category.AIRPLANE,
|
||||
["helicopter"] = Unit.Category.HELICOPTER,
|
||||
["vehicle"] = Unit.Category.GROUND_UNIT,
|
||||
["ship"] = Unit.Category.SHIP,
|
||||
["static"] = Unit.Category.STRUCTURE,
|
||||
}
|
||||
|
||||
|
||||
--- Creates a new DATABASE object, building a set of units belonging to a coalitions, categories, countries, types or with defined prefix names.
|
||||
-- @param #DATABASE self
|
||||
-- @return #DATABASE
|
||||
-- @usage
|
||||
-- -- Define a new DATABASE Object. This DBObject will contain a reference to all Group and Unit Templates defined within the ME and the DCSRTE.
|
||||
-- DBObject = DATABASE:New()
|
||||
function DATABASE:New()
|
||||
|
||||
-- Inherits from BASE
|
||||
local self = BASE:Inherit( self, BASE:New() )
|
||||
|
||||
self:SetEventPriority( 1 )
|
||||
|
||||
self:HandleEvent( EVENTS.Birth, self._EventOnBirth )
|
||||
self:HandleEvent( EVENTS.Dead, self._EventOnDeadOrCrash )
|
||||
self:HandleEvent( EVENTS.Crash, self._EventOnDeadOrCrash )
|
||||
|
||||
-- Follow alive players and clients
|
||||
self:HandleEvent( EVENTS.PlayerEnterUnit, self._EventOnPlayerEnterUnit )
|
||||
self:HandleEvent( EVENTS.PlayerLeaveUnit, self._EventOnPlayerLeaveUnit )
|
||||
|
||||
self:_RegisterTemplates()
|
||||
self:_RegisterGroupsAndUnits()
|
||||
self:_RegisterClients()
|
||||
self:_RegisterStatics()
|
||||
self:_RegisterPlayers()
|
||||
self:_RegisterAirbases()
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Finds a Unit based on the Unit Name.
|
||||
-- @param #DATABASE self
|
||||
-- @param #string UnitName
|
||||
-- @return Wrapper.Unit#UNIT The found Unit.
|
||||
function DATABASE:FindUnit( UnitName )
|
||||
|
||||
local UnitFound = self.UNITS[UnitName]
|
||||
return UnitFound
|
||||
end
|
||||
|
||||
|
||||
--- Adds a Unit based on the Unit Name in the DATABASE.
|
||||
-- @param #DATABASE self
|
||||
function DATABASE:AddUnit( DCSUnitName )
|
||||
|
||||
if not self.UNITS[DCSUnitName] then
|
||||
local UnitRegister = UNIT:Register( DCSUnitName )
|
||||
self.UNITS[DCSUnitName] = UNIT:Register( DCSUnitName )
|
||||
end
|
||||
|
||||
return self.UNITS[DCSUnitName]
|
||||
end
|
||||
|
||||
|
||||
--- Deletes a Unit from the DATABASE based on the Unit Name.
|
||||
-- @param #DATABASE self
|
||||
function DATABASE:DeleteUnit( DCSUnitName )
|
||||
|
||||
--self.UNITS[DCSUnitName] = nil
|
||||
end
|
||||
|
||||
--- Adds a Static based on the Static Name in the DATABASE.
|
||||
-- @param #DATABASE self
|
||||
function DATABASE:AddStatic( DCSStaticName )
|
||||
|
||||
if not self.STATICS[DCSStaticName] then
|
||||
self.STATICS[DCSStaticName] = STATIC:Register( DCSStaticName )
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--- Deletes a Static from the DATABASE based on the Static Name.
|
||||
-- @param #DATABASE self
|
||||
function DATABASE:DeleteStatic( DCSStaticName )
|
||||
|
||||
--self.STATICS[DCSStaticName] = nil
|
||||
end
|
||||
|
||||
--- Finds a STATIC based on the StaticName.
|
||||
-- @param #DATABASE self
|
||||
-- @param #string StaticName
|
||||
-- @return Wrapper.Static#STATIC The found STATIC.
|
||||
function DATABASE:FindStatic( StaticName )
|
||||
|
||||
local StaticFound = self.STATICS[StaticName]
|
||||
return StaticFound
|
||||
end
|
||||
|
||||
--- Adds a Airbase based on the Airbase Name in the DATABASE.
|
||||
-- @param #DATABASE self
|
||||
function DATABASE:AddAirbase( DCSAirbaseName )
|
||||
|
||||
if not self.AIRBASES[DCSAirbaseName] then
|
||||
self.AIRBASES[DCSAirbaseName] = AIRBASE:Register( DCSAirbaseName )
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--- Deletes a Airbase from the DATABASE based on the Airbase Name.
|
||||
-- @param #DATABASE self
|
||||
function DATABASE:DeleteAirbase( DCSAirbaseName )
|
||||
|
||||
--self.AIRBASES[DCSAirbaseName] = nil
|
||||
end
|
||||
|
||||
--- Finds a AIRBASE based on the AirbaseName.
|
||||
-- @param #DATABASE self
|
||||
-- @param #string AirbaseName
|
||||
-- @return Wrapper.Airbase#AIRBASE The found AIRBASE.
|
||||
function DATABASE:FindAirbase( AirbaseName )
|
||||
|
||||
local AirbaseFound = self.AIRBASES[AirbaseName]
|
||||
return AirbaseFound
|
||||
end
|
||||
|
||||
|
||||
--- Finds a CLIENT based on the ClientName.
|
||||
-- @param #DATABASE self
|
||||
-- @param #string ClientName
|
||||
-- @return Wrapper.Client#CLIENT The found CLIENT.
|
||||
function DATABASE:FindClient( ClientName )
|
||||
|
||||
local ClientFound = self.CLIENTS[ClientName]
|
||||
return ClientFound
|
||||
end
|
||||
|
||||
|
||||
--- Adds a CLIENT based on the ClientName in the DATABASE.
|
||||
-- @param #DATABASE self
|
||||
function DATABASE:AddClient( ClientName )
|
||||
|
||||
if not self.CLIENTS[ClientName] then
|
||||
self.CLIENTS[ClientName] = CLIENT:Register( ClientName )
|
||||
end
|
||||
|
||||
return self.CLIENTS[ClientName]
|
||||
end
|
||||
|
||||
|
||||
--- Finds a GROUP based on the GroupName.
|
||||
-- @param #DATABASE self
|
||||
-- @param #string GroupName
|
||||
-- @return Wrapper.Group#GROUP The found GROUP.
|
||||
function DATABASE:FindGroup( GroupName )
|
||||
|
||||
local GroupFound = self.GROUPS[GroupName]
|
||||
return GroupFound
|
||||
end
|
||||
|
||||
|
||||
--- Adds a GROUP based on the GroupName in the DATABASE.
|
||||
-- @param #DATABASE self
|
||||
function DATABASE:AddGroup( GroupName )
|
||||
|
||||
if not self.GROUPS[GroupName] then
|
||||
self:E( { "Add GROUP:", GroupName } )
|
||||
self.GROUPS[GroupName] = GROUP:Register( GroupName )
|
||||
end
|
||||
|
||||
return self.GROUPS[GroupName]
|
||||
end
|
||||
|
||||
--- Adds a player based on the Player Name in the DATABASE.
|
||||
-- @param #DATABASE self
|
||||
function DATABASE:AddPlayer( UnitName, PlayerName )
|
||||
|
||||
if PlayerName then
|
||||
self:E( { "Add player for unit:", UnitName, PlayerName } )
|
||||
self.PLAYERS[PlayerName] = self:FindUnit( UnitName )
|
||||
self.PLAYERSJOINED[PlayerName] = PlayerName
|
||||
end
|
||||
end
|
||||
|
||||
--- Deletes a player from the DATABASE based on the Player Name.
|
||||
-- @param #DATABASE self
|
||||
function DATABASE:DeletePlayer( PlayerName )
|
||||
|
||||
if PlayerName then
|
||||
self:E( { "Clean player:", PlayerName } )
|
||||
self.PLAYERS[PlayerName] = nil
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--- Instantiate new Groups within the DCSRTE.
|
||||
-- This method expects EXACTLY the same structure as a structure within the ME, and needs 2 additional fields defined:
|
||||
-- SpawnCountryID, SpawnCategoryID
|
||||
-- This method is used by the SPAWN class.
|
||||
-- @param #DATABASE self
|
||||
-- @param #table SpawnTemplate
|
||||
-- @return #DATABASE self
|
||||
function DATABASE:Spawn( SpawnTemplate )
|
||||
self:F( SpawnTemplate.name )
|
||||
|
||||
self:T( { SpawnTemplate.SpawnCountryID, SpawnTemplate.SpawnCategoryID } )
|
||||
|
||||
-- Copy the spawn variables of the template in temporary storage, nullify, and restore the spawn variables.
|
||||
local SpawnCoalitionID = SpawnTemplate.CoalitionID
|
||||
local SpawnCountryID = SpawnTemplate.CountryID
|
||||
local SpawnCategoryID = SpawnTemplate.CategoryID
|
||||
|
||||
-- Nullify
|
||||
SpawnTemplate.CoalitionID = nil
|
||||
SpawnTemplate.CountryID = nil
|
||||
SpawnTemplate.CategoryID = nil
|
||||
|
||||
self:_RegisterTemplate( SpawnTemplate, SpawnCoalitionID, SpawnCategoryID, SpawnCountryID )
|
||||
|
||||
self:T3( SpawnTemplate )
|
||||
coalition.addGroup( SpawnCountryID, SpawnCategoryID, SpawnTemplate )
|
||||
|
||||
-- Restore
|
||||
SpawnTemplate.CoalitionID = SpawnCoalitionID
|
||||
SpawnTemplate.CountryID = SpawnCountryID
|
||||
SpawnTemplate.CategoryID = SpawnCategoryID
|
||||
|
||||
local SpawnGroup = self:AddGroup( SpawnTemplate.name )
|
||||
return SpawnGroup
|
||||
end
|
||||
|
||||
--- Set a status to a Group within the Database, this to check crossing events for example.
|
||||
function DATABASE:SetStatusGroup( GroupName, Status )
|
||||
self:F2( Status )
|
||||
|
||||
self.Templates.Groups[GroupName].Status = Status
|
||||
end
|
||||
|
||||
--- Get a status to a Group within the Database, this to check crossing events for example.
|
||||
function DATABASE:GetStatusGroup( GroupName )
|
||||
self:F2( Status )
|
||||
|
||||
if self.Templates.Groups[GroupName] then
|
||||
return self.Templates.Groups[GroupName].Status
|
||||
else
|
||||
return ""
|
||||
end
|
||||
end
|
||||
|
||||
--- Private method that registers new Group Templates within the DATABASE Object.
|
||||
-- @param #DATABASE self
|
||||
-- @param #table GroupTemplate
|
||||
-- @return #DATABASE self
|
||||
function DATABASE:_RegisterTemplate( GroupTemplate, CoalitionID, CategoryID, CountryID )
|
||||
|
||||
local GroupTemplateName = env.getValueDictByKey(GroupTemplate.name)
|
||||
|
||||
local TraceTable = {}
|
||||
|
||||
if not self.Templates.Groups[GroupTemplateName] then
|
||||
self.Templates.Groups[GroupTemplateName] = {}
|
||||
self.Templates.Groups[GroupTemplateName].Status = nil
|
||||
end
|
||||
|
||||
-- Delete the spans from the route, it is not needed and takes memory.
|
||||
if GroupTemplate.route and GroupTemplate.route.spans then
|
||||
GroupTemplate.route.spans = nil
|
||||
end
|
||||
|
||||
GroupTemplate.CategoryID = CategoryID
|
||||
GroupTemplate.CoalitionID = CoalitionID
|
||||
GroupTemplate.CountryID = CountryID
|
||||
|
||||
self.Templates.Groups[GroupTemplateName].GroupName = GroupTemplateName
|
||||
self.Templates.Groups[GroupTemplateName].Template = GroupTemplate
|
||||
self.Templates.Groups[GroupTemplateName].groupId = GroupTemplate.groupId
|
||||
self.Templates.Groups[GroupTemplateName].UnitCount = #GroupTemplate.units
|
||||
self.Templates.Groups[GroupTemplateName].Units = GroupTemplate.units
|
||||
self.Templates.Groups[GroupTemplateName].CategoryID = CategoryID
|
||||
self.Templates.Groups[GroupTemplateName].CoalitionID = CoalitionID
|
||||
self.Templates.Groups[GroupTemplateName].CountryID = CountryID
|
||||
|
||||
|
||||
TraceTable[#TraceTable+1] = "Group"
|
||||
TraceTable[#TraceTable+1] = self.Templates.Groups[GroupTemplateName].GroupName
|
||||
|
||||
TraceTable[#TraceTable+1] = "Coalition"
|
||||
TraceTable[#TraceTable+1] = self.Templates.Groups[GroupTemplateName].CoalitionID
|
||||
TraceTable[#TraceTable+1] = "Category"
|
||||
TraceTable[#TraceTable+1] = self.Templates.Groups[GroupTemplateName].CategoryID
|
||||
TraceTable[#TraceTable+1] = "Country"
|
||||
TraceTable[#TraceTable+1] = self.Templates.Groups[GroupTemplateName].CountryID
|
||||
|
||||
TraceTable[#TraceTable+1] = "Units"
|
||||
|
||||
for unit_num, UnitTemplate in pairs( GroupTemplate.units ) do
|
||||
|
||||
UnitTemplate.name = env.getValueDictByKey(UnitTemplate.name)
|
||||
|
||||
self.Templates.Units[UnitTemplate.name] = {}
|
||||
self.Templates.Units[UnitTemplate.name].UnitName = UnitTemplate.name
|
||||
self.Templates.Units[UnitTemplate.name].Template = UnitTemplate
|
||||
self.Templates.Units[UnitTemplate.name].GroupName = GroupTemplateName
|
||||
self.Templates.Units[UnitTemplate.name].GroupTemplate = GroupTemplate
|
||||
self.Templates.Units[UnitTemplate.name].GroupId = GroupTemplate.groupId
|
||||
self.Templates.Units[UnitTemplate.name].CategoryID = CategoryID
|
||||
self.Templates.Units[UnitTemplate.name].CoalitionID = CoalitionID
|
||||
self.Templates.Units[UnitTemplate.name].CountryID = CountryID
|
||||
|
||||
if UnitTemplate.skill and (UnitTemplate.skill == "Client" or UnitTemplate.skill == "Player") then
|
||||
self.Templates.ClientsByName[UnitTemplate.name] = UnitTemplate
|
||||
self.Templates.ClientsByName[UnitTemplate.name].CategoryID = CategoryID
|
||||
self.Templates.ClientsByName[UnitTemplate.name].CoalitionID = CoalitionID
|
||||
self.Templates.ClientsByName[UnitTemplate.name].CountryID = CountryID
|
||||
self.Templates.ClientsByID[UnitTemplate.unitId] = UnitTemplate
|
||||
end
|
||||
|
||||
TraceTable[#TraceTable+1] = self.Templates.Units[UnitTemplate.name].UnitName
|
||||
end
|
||||
|
||||
self:E( TraceTable )
|
||||
end
|
||||
|
||||
function DATABASE:GetGroupTemplate( GroupName )
|
||||
local GroupTemplate = self.Templates.Groups[GroupName].Template
|
||||
GroupTemplate.SpawnCoalitionID = self.Templates.Groups[GroupName].CoalitionID
|
||||
GroupTemplate.SpawnCategoryID = self.Templates.Groups[GroupName].CategoryID
|
||||
GroupTemplate.SpawnCountryID = self.Templates.Groups[GroupName].CountryID
|
||||
return GroupTemplate
|
||||
end
|
||||
|
||||
function DATABASE:GetGroupNameFromUnitName( UnitName )
|
||||
return self.Templates.Units[UnitName].GroupName
|
||||
end
|
||||
|
||||
function DATABASE:GetGroupTemplateFromUnitName( UnitName )
|
||||
return self.Templates.Units[UnitName].GroupTemplate
|
||||
end
|
||||
|
||||
function DATABASE:GetCoalitionFromClientTemplate( ClientName )
|
||||
return self.Templates.ClientsByName[ClientName].CoalitionID
|
||||
end
|
||||
|
||||
function DATABASE:GetCategoryFromClientTemplate( ClientName )
|
||||
return self.Templates.ClientsByName[ClientName].CategoryID
|
||||
end
|
||||
|
||||
function DATABASE:GetCountryFromClientTemplate( ClientName )
|
||||
return self.Templates.ClientsByName[ClientName].CountryID
|
||||
end
|
||||
|
||||
--- Airbase
|
||||
|
||||
function DATABASE:GetCoalitionFromAirbase( AirbaseName )
|
||||
return self.AIRBASES[AirbaseName]:GetCoalition()
|
||||
end
|
||||
|
||||
function DATABASE:GetCategoryFromAirbase( AirbaseName )
|
||||
return self.AIRBASES[AirbaseName]:GetCategory()
|
||||
end
|
||||
|
||||
|
||||
|
||||
--- Private method that registers all alive players in the mission.
|
||||
-- @param #DATABASE self
|
||||
-- @return #DATABASE self
|
||||
function DATABASE:_RegisterPlayers()
|
||||
|
||||
local CoalitionsData = { AlivePlayersRed = coalition.getPlayers( coalition.side.RED ), AlivePlayersBlue = coalition.getPlayers( coalition.side.BLUE ) }
|
||||
for CoalitionId, CoalitionData in pairs( CoalitionsData ) do
|
||||
for UnitId, UnitData in pairs( CoalitionData ) do
|
||||
self:T3( { "UnitData:", UnitData } )
|
||||
if UnitData and UnitData:isExist() then
|
||||
local UnitName = UnitData:getName()
|
||||
local PlayerName = UnitData:getPlayerName()
|
||||
if not self.PLAYERS[PlayerName] then
|
||||
self:E( { "Add player for unit:", UnitName, PlayerName } )
|
||||
self:AddPlayer( UnitName, PlayerName )
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
--- Private method that registers all Groups and Units within in the mission.
|
||||
-- @param #DATABASE self
|
||||
-- @return #DATABASE self
|
||||
function DATABASE:_RegisterGroupsAndUnits()
|
||||
|
||||
local CoalitionsData = { GroupsRed = coalition.getGroups( coalition.side.RED ), GroupsBlue = coalition.getGroups( coalition.side.BLUE ) }
|
||||
for CoalitionId, CoalitionData in pairs( CoalitionsData ) do
|
||||
for DCSGroupId, DCSGroup in pairs( CoalitionData ) do
|
||||
|
||||
if DCSGroup:isExist() then
|
||||
local DCSGroupName = DCSGroup:getName()
|
||||
|
||||
self:E( { "Register Group:", DCSGroupName } )
|
||||
self:AddGroup( DCSGroupName )
|
||||
|
||||
for DCSUnitId, DCSUnit in pairs( DCSGroup:getUnits() ) do
|
||||
|
||||
local DCSUnitName = DCSUnit:getName()
|
||||
self:E( { "Register Unit:", DCSUnitName } )
|
||||
self:AddUnit( DCSUnitName )
|
||||
end
|
||||
else
|
||||
self:E( { "Group does not exist: ", DCSGroup } )
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Private method that registers all Units of skill Client or Player within in the mission.
|
||||
-- @param #DATABASE self
|
||||
-- @return #DATABASE self
|
||||
function DATABASE:_RegisterClients()
|
||||
|
||||
for ClientName, ClientTemplate in pairs( self.Templates.ClientsByName ) do
|
||||
self:E( { "Register Client:", ClientName } )
|
||||
self:AddClient( ClientName )
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- @param #DATABASE self
|
||||
function DATABASE:_RegisterStatics()
|
||||
|
||||
local CoalitionsData = { GroupsRed = coalition.getStaticObjects( coalition.side.RED ), GroupsBlue = coalition.getStaticObjects( coalition.side.BLUE ) }
|
||||
for CoalitionId, CoalitionData in pairs( CoalitionsData ) do
|
||||
for DCSStaticId, DCSStatic in pairs( CoalitionData ) do
|
||||
|
||||
if DCSStatic:isExist() then
|
||||
local DCSStaticName = DCSStatic:getName()
|
||||
|
||||
self:E( { "Register Static:", DCSStaticName } )
|
||||
self:AddStatic( DCSStaticName )
|
||||
else
|
||||
self:E( { "Static does not exist: ", DCSStatic } )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- @param #DATABASE self
|
||||
function DATABASE:_RegisterAirbases()
|
||||
|
||||
local CoalitionsData = { AirbasesRed = coalition.getAirbases( coalition.side.RED ), AirbasesBlue = coalition.getAirbases( coalition.side.BLUE ), AirbasesNeutral = coalition.getAirbases( coalition.side.NEUTRAL ) }
|
||||
for CoalitionId, CoalitionData in pairs( CoalitionsData ) do
|
||||
for DCSAirbaseId, DCSAirbase in pairs( CoalitionData ) do
|
||||
|
||||
local DCSAirbaseName = DCSAirbase:getName()
|
||||
|
||||
self:E( { "Register Airbase:", DCSAirbaseName } )
|
||||
self:AddAirbase( DCSAirbaseName )
|
||||
end
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
--- Events
|
||||
|
||||
--- Handles the OnBirth event for the alive units set.
|
||||
-- @param #DATABASE self
|
||||
-- @param Core.Event#EVENTDATA Event
|
||||
function DATABASE:_EventOnBirth( Event )
|
||||
self:F2( { Event } )
|
||||
|
||||
if Event.IniDCSUnit then
|
||||
self:AddUnit( Event.IniDCSUnitName )
|
||||
self:AddGroup( Event.IniDCSGroupName )
|
||||
self:_EventOnPlayerEnterUnit( Event )
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--- Handles the OnDead or OnCrash event for alive units set.
|
||||
-- @param #DATABASE self
|
||||
-- @param Core.Event#EVENTDATA Event
|
||||
function DATABASE:_EventOnDeadOrCrash( Event )
|
||||
self:F2( { Event } )
|
||||
|
||||
if Event.IniDCSUnit then
|
||||
if self.UNITS[Event.IniDCSUnitName] then
|
||||
self:DeleteUnit( Event.IniDCSUnitName )
|
||||
-- add logic to correctly remove a group once all units are destroyed...
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--- Handles the OnPlayerEnterUnit event to fill the active players table (with the unit filter applied).
|
||||
-- @param #DATABASE self
|
||||
-- @param Core.Event#EVENTDATA Event
|
||||
function DATABASE:_EventOnPlayerEnterUnit( Event )
|
||||
self:F2( { Event } )
|
||||
|
||||
if Event.IniUnit then
|
||||
self:AddUnit( Event.IniDCSUnitName )
|
||||
self:AddGroup( Event.IniDCSGroupName )
|
||||
local PlayerName = Event.IniUnit:GetPlayerName()
|
||||
if not self.PLAYERS[PlayerName] then
|
||||
self:AddPlayer( Event.IniUnitName, PlayerName )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--- Handles the OnPlayerLeaveUnit event to clean the active players table.
|
||||
-- @param #DATABASE self
|
||||
-- @param Core.Event#EVENTDATA Event
|
||||
function DATABASE:_EventOnPlayerLeaveUnit( Event )
|
||||
self:F2( { Event } )
|
||||
|
||||
if Event.IniUnit then
|
||||
local PlayerName = Event.IniUnit:GetPlayerName()
|
||||
if self.PLAYERS[PlayerName] then
|
||||
self:DeletePlayer( PlayerName )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- Iterators
|
||||
|
||||
--- Iterate the DATABASE and call an iterator function for the given set, providing the Object for each element within the set and optional parameters.
|
||||
-- @param #DATABASE self
|
||||
-- @param #function IteratorFunction The function that will be called when there is an alive player in the database.
|
||||
-- @return #DATABASE self
|
||||
function DATABASE:ForEach( IteratorFunction, FinalizeFunction, arg, Set )
|
||||
self:F2( arg )
|
||||
|
||||
local function CoRoutine()
|
||||
local Count = 0
|
||||
for ObjectID, Object in pairs( Set ) do
|
||||
self:T2( Object )
|
||||
IteratorFunction( Object, unpack( arg ) )
|
||||
Count = Count + 1
|
||||
-- if Count % 100 == 0 then
|
||||
-- coroutine.yield( false )
|
||||
-- end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
-- local co = coroutine.create( CoRoutine )
|
||||
local co = CoRoutine
|
||||
|
||||
local function Schedule()
|
||||
|
||||
-- local status, res = coroutine.resume( co )
|
||||
local status, res = co()
|
||||
self:T3( { status, res } )
|
||||
|
||||
if status == false then
|
||||
error( res )
|
||||
end
|
||||
if res == false then
|
||||
return true -- resume next time the loop
|
||||
end
|
||||
if FinalizeFunction then
|
||||
FinalizeFunction( unpack( arg ) )
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local Scheduler = SCHEDULER:New( self, Schedule, {}, 0.001, 0.001, 0 )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
--- Iterate the DATABASE and call an iterator function for each **alive** UNIT, providing the UNIT and optional parameters.
|
||||
-- @param #DATABASE self
|
||||
-- @param #function IteratorFunction The function that will be called when there is an alive UNIT in the database. The function needs to accept a UNIT parameter.
|
||||
-- @return #DATABASE self
|
||||
function DATABASE:ForEachUnit( IteratorFunction, FinalizeFunction, ... )
|
||||
self:F2( arg )
|
||||
|
||||
self:ForEach( IteratorFunction, FinalizeFunction, arg, self.UNITS )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Iterate the DATABASE and call an iterator function for each **alive** GROUP, providing the GROUP and optional parameters.
|
||||
-- @param #DATABASE self
|
||||
-- @param #function IteratorFunction The function that will be called when there is an alive GROUP in the database. The function needs to accept a GROUP parameter.
|
||||
-- @return #DATABASE self
|
||||
function DATABASE:ForEachGroup( IteratorFunction, ... )
|
||||
self:F2( arg )
|
||||
|
||||
self:ForEach( IteratorFunction, arg, self.GROUPS )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
--- Iterate the DATABASE and call an iterator function for each **ALIVE** player, providing the player name and optional parameters.
|
||||
-- @param #DATABASE self
|
||||
-- @param #function IteratorFunction The function that will be called when there is an player in the database. The function needs to accept the player name.
|
||||
-- @return #DATABASE self
|
||||
function DATABASE:ForEachPlayer( IteratorFunction, ... )
|
||||
self:F2( arg )
|
||||
|
||||
self:ForEach( IteratorFunction, arg, self.PLAYERS )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
--- Iterate the DATABASE and call an iterator function for each player who has joined the mission, providing the Unit of the player and optional parameters.
|
||||
-- @param #DATABASE self
|
||||
-- @param #function IteratorFunction The function that will be called when there is was a player in the database. The function needs to accept a UNIT parameter.
|
||||
-- @return #DATABASE self
|
||||
function DATABASE:ForEachPlayerJoined( IteratorFunction, ... )
|
||||
self:F2( arg )
|
||||
|
||||
self:ForEach( IteratorFunction, arg, self.PLAYERSJOINED )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Iterate the DATABASE and call an iterator function for each CLIENT, providing the CLIENT to the function and optional parameters.
|
||||
-- @param #DATABASE self
|
||||
-- @param #function IteratorFunction The function that will be called when there is an alive player in the database. The function needs to accept a CLIENT parameter.
|
||||
-- @return #DATABASE self
|
||||
function DATABASE:ForEachClient( IteratorFunction, ... )
|
||||
self:F2( arg )
|
||||
|
||||
self:ForEach( IteratorFunction, arg, self.CLIENTS )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
function DATABASE:_RegisterTemplates()
|
||||
self:F2()
|
||||
|
||||
self.Navpoints = {}
|
||||
self.UNITS = {}
|
||||
--Build routines.db.units and self.Navpoints
|
||||
for CoalitionName, coa_data in pairs(env.mission.coalition) do
|
||||
|
||||
if (CoalitionName == 'red' or CoalitionName == 'blue') and type(coa_data) == 'table' then
|
||||
--self.Units[coa_name] = {}
|
||||
|
||||
local CoalitionSide = coalition.side[string.upper(CoalitionName)]
|
||||
|
||||
----------------------------------------------
|
||||
-- build nav points DB
|
||||
self.Navpoints[CoalitionName] = {}
|
||||
if coa_data.nav_points then --navpoints
|
||||
for nav_ind, nav_data in pairs(coa_data.nav_points) do
|
||||
|
||||
if type(nav_data) == 'table' then
|
||||
self.Navpoints[CoalitionName][nav_ind] = routines.utils.deepCopy(nav_data)
|
||||
|
||||
self.Navpoints[CoalitionName][nav_ind]['name'] = nav_data.callsignStr -- name is a little bit more self-explanatory.
|
||||
self.Navpoints[CoalitionName][nav_ind]['point'] = {} -- point is used by SSE, support it.
|
||||
self.Navpoints[CoalitionName][nav_ind]['point']['x'] = nav_data.x
|
||||
self.Navpoints[CoalitionName][nav_ind]['point']['y'] = 0
|
||||
self.Navpoints[CoalitionName][nav_ind]['point']['z'] = nav_data.y
|
||||
end
|
||||
end
|
||||
end
|
||||
-------------------------------------------------
|
||||
if coa_data.country then --there is a country table
|
||||
for cntry_id, cntry_data in pairs(coa_data.country) do
|
||||
|
||||
local CountryName = string.upper(cntry_data.name)
|
||||
local CountryID = cntry_data.id
|
||||
|
||||
--self.Units[coa_name][countryName] = {}
|
||||
--self.Units[coa_name][countryName]["countryId"] = cntry_data.id
|
||||
|
||||
if type(cntry_data) == 'table' then --just making sure
|
||||
|
||||
for obj_type_name, obj_type_data in pairs(cntry_data) do
|
||||
|
||||
if obj_type_name == "helicopter" or obj_type_name == "ship" or obj_type_name == "plane" or obj_type_name == "vehicle" or obj_type_name == "static" then --should be an unncessary check
|
||||
|
||||
local CategoryName = obj_type_name
|
||||
|
||||
if ((type(obj_type_data) == 'table') and obj_type_data.group and (type(obj_type_data.group) == 'table') and (#obj_type_data.group > 0)) then --there's a group!
|
||||
|
||||
--self.Units[coa_name][countryName][category] = {}
|
||||
|
||||
for group_num, GroupTemplate in pairs(obj_type_data.group) do
|
||||
|
||||
if GroupTemplate and GroupTemplate.units and type(GroupTemplate.units) == 'table' then --making sure again- this is a valid group
|
||||
self:_RegisterTemplate(
|
||||
GroupTemplate,
|
||||
CoalitionSide,
|
||||
_DATABASECategory[string.lower(CategoryName)],
|
||||
CountryID
|
||||
)
|
||||
end --if GroupTemplate and GroupTemplate.units then
|
||||
end --for group_num, GroupTemplate in pairs(obj_type_data.group) do
|
||||
end --if ((type(obj_type_data) == 'table') and obj_type_data.group and (type(obj_type_data.group) == 'table') and (#obj_type_data.group > 0)) then
|
||||
end --if obj_type_name == "helicopter" or obj_type_name == "ship" or obj_type_name == "plane" or obj_type_name == "vehicle" or obj_type_name == "static" then
|
||||
end --for obj_type_name, obj_type_data in pairs(cntry_data) do
|
||||
end --if type(cntry_data) == 'table' then
|
||||
end --for cntry_id, cntry_data in pairs(coa_data.country) do
|
||||
end --if coa_data.country then --there is a country table
|
||||
end --if coa_name == 'red' or coa_name == 'blue' and type(coa_data) == 'table' then
|
||||
end --for coa_name, coa_data in pairs(mission.coalition) do
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
1266
Moose Development/Moose/Core/Event.lua
Normal file
1266
Moose Development/Moose/Core/Event.lua
Normal file
File diff suppressed because it is too large
Load Diff
1052
Moose Development/Moose/Core/Fsm.lua
Normal file
1052
Moose Development/Moose/Core/Fsm.lua
Normal file
File diff suppressed because it is too large
Load Diff
892
Moose Development/Moose/Core/Menu.lua
Normal file
892
Moose Development/Moose/Core/Menu.lua
Normal file
@@ -0,0 +1,892 @@
|
||||
--- This module contains the MENU classes.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- DCS Menus can be managed using the MENU classes.
|
||||
-- The advantage of using MENU classes is that it hides the complexity of dealing with menu management in more advanced scanerios where you need to
|
||||
-- set menus and later remove them, and later set them again. You'll find while using use normal DCS scripting functions, that setting and removing
|
||||
-- menus is not a easy feat if you have complex menu hierarchies defined.
|
||||
-- Using the MOOSE menu classes, the removal and refreshing of menus are nicely being handled within these classes, and becomes much more easy.
|
||||
-- On top, MOOSE implements **variable parameter** passing for command menus.
|
||||
--
|
||||
-- There are basically two different MENU class types that you need to use:
|
||||
--
|
||||
-- ### To manage **main menus**, the classes begin with **MENU_**:
|
||||
--
|
||||
-- * @{Menu#MENU_MISSION}: Manages main menus for whole mission file.
|
||||
-- * @{Menu#MENU_COALITION}: Manages main menus for whole coalition.
|
||||
-- * @{Menu#MENU_GROUP}: Manages main menus for GROUPs.
|
||||
-- * @{Menu#MENU_CLIENT}: Manages main menus for CLIENTs. This manages menus for units with the skill level "Client".
|
||||
--
|
||||
-- ### To manage **command menus**, which are menus that allow the player to issue **functions**, the classes begin with **MENU_COMMAND_**:
|
||||
--
|
||||
-- * @{Menu#MENU_MISSION_COMMAND}: Manages command menus for whole mission file.
|
||||
-- * @{Menu#MENU_COALITION_COMMAND}: Manages command menus for whole coalition.
|
||||
-- * @{Menu#MENU_GROUP_COMMAND}: Manages command menus for GROUPs.
|
||||
-- * @{Menu#MENU_CLIENT_COMMAND}: Manages command menus for CLIENTs. This manages menus for units with the skill level "Client".
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- The above menus classes **are derived** from 2 main **abstract** classes defined within the MOOSE framework (so don't use these):
|
||||
--
|
||||
-- 1) MENU_ BASE abstract base classes (don't use them)
|
||||
-- ====================================================
|
||||
-- The underlying base menu classes are **NOT** to be used within your missions.
|
||||
-- These are simply abstract base classes defining a couple of fields that are used by the
|
||||
-- derived MENU_ classes to manage menus.
|
||||
--
|
||||
-- 1.1) @{#MENU_BASE} class, extends @{Base#BASE}
|
||||
-- --------------------------------------------------
|
||||
-- The @{#MENU_BASE} class defines the main MENU class where other MENU classes are derived from.
|
||||
--
|
||||
-- 1.2) @{#MENU_COMMAND_BASE} class, extends @{Base#BASE}
|
||||
-- ----------------------------------------------------------
|
||||
-- The @{#MENU_COMMAND_BASE} class defines the main MENU class where other MENU COMMAND_ classes are derived from, in order to set commands.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- **The next menus define the MENU classes that you can use within your missions.**
|
||||
--
|
||||
-- 2) MENU MISSION classes
|
||||
-- ======================
|
||||
-- The underlying classes manage the menus for a complete mission file.
|
||||
--
|
||||
-- 2.1) @{#MENU_MISSION} class, extends @{Menu#MENU_BASE}
|
||||
-- ---------------------------------------------------------
|
||||
-- The @{Menu#MENU_MISSION} class manages the main menus for a complete mission.
|
||||
-- You can add menus with the @{#MENU_MISSION.New} method, which constructs a MENU_MISSION object and returns you the object reference.
|
||||
-- Using this object reference, you can then remove ALL the menus and submenus underlying automatically with @{#MENU_MISSION.Remove}.
|
||||
--
|
||||
-- 2.2) @{#MENU_MISSION_COMMAND} class, extends @{Menu#MENU_COMMAND_BASE}
|
||||
-- -------------------------------------------------------------------------
|
||||
-- The @{Menu#MENU_MISSION_COMMAND} class manages the command menus for a complete mission, which allow players to execute functions during mission execution.
|
||||
-- You can add menus with the @{#MENU_MISSION_COMMAND.New} method, which constructs a MENU_MISSION_COMMAND object and returns you the object reference.
|
||||
-- Using this object reference, you can then remove ALL the menus and submenus underlying automatically with @{#MENU_MISSION_COMMAND.Remove}.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- 3) MENU COALITION classes
|
||||
-- =========================
|
||||
-- The underlying classes manage the menus for whole coalitions.
|
||||
--
|
||||
-- 3.1) @{#MENU_COALITION} class, extends @{Menu#MENU_BASE}
|
||||
-- ------------------------------------------------------------
|
||||
-- The @{Menu#MENU_COALITION} class manages the main menus for coalitions.
|
||||
-- You can add menus with the @{#MENU_COALITION.New} method, which constructs a MENU_COALITION object and returns you the object reference.
|
||||
-- Using this object reference, you can then remove ALL the menus and submenus underlying automatically with @{#MENU_COALITION.Remove}.
|
||||
--
|
||||
-- 3.2) @{Menu#MENU_COALITION_COMMAND} class, extends @{Menu#MENU_COMMAND_BASE}
|
||||
-- ----------------------------------------------------------------------------
|
||||
-- The @{Menu#MENU_COALITION_COMMAND} class manages the command menus for coalitions, which allow players to execute functions during mission execution.
|
||||
-- You can add menus with the @{#MENU_COALITION_COMMAND.New} method, which constructs a MENU_COALITION_COMMAND object and returns you the object reference.
|
||||
-- Using this object reference, you can then remove ALL the menus and submenus underlying automatically with @{#MENU_COALITION_COMMAND.Remove}.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- 4) MENU GROUP classes
|
||||
-- =====================
|
||||
-- The underlying classes manage the menus for groups. Note that groups can be inactive, alive or can be destroyed.
|
||||
--
|
||||
-- 4.1) @{Menu#MENU_GROUP} class, extends @{Menu#MENU_BASE}
|
||||
-- --------------------------------------------------------
|
||||
-- The @{Menu#MENU_GROUP} class manages the main menus for coalitions.
|
||||
-- You can add menus with the @{#MENU_GROUP.New} method, which constructs a MENU_GROUP object and returns you the object reference.
|
||||
-- Using this object reference, you can then remove ALL the menus and submenus underlying automatically with @{#MENU_GROUP.Remove}.
|
||||
--
|
||||
-- 4.2) @{Menu#MENU_GROUP_COMMAND} class, extends @{Menu#MENU_COMMAND_BASE}
|
||||
-- ------------------------------------------------------------------------
|
||||
-- The @{Menu#MENU_GROUP_COMMAND} class manages the command menus for coalitions, which allow players to execute functions during mission execution.
|
||||
-- You can add menus with the @{#MENU_GROUP_COMMAND.New} method, which constructs a MENU_GROUP_COMMAND object and returns you the object reference.
|
||||
-- Using this object reference, you can then remove ALL the menus and submenus underlying automatically with @{#MENU_GROUP_COMMAND.Remove}.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- 5) MENU CLIENT classes
|
||||
-- ======================
|
||||
-- The underlying classes manage the menus for units with skill level client or player.
|
||||
--
|
||||
-- 5.1) @{Menu#MENU_CLIENT} class, extends @{Menu#MENU_BASE}
|
||||
-- ---------------------------------------------------------
|
||||
-- The @{Menu#MENU_CLIENT} class manages the main menus for coalitions.
|
||||
-- You can add menus with the @{#MENU_CLIENT.New} method, which constructs a MENU_CLIENT object and returns you the object reference.
|
||||
-- Using this object reference, you can then remove ALL the menus and submenus underlying automatically with @{#MENU_CLIENT.Remove}.
|
||||
--
|
||||
-- 5.2) @{Menu#MENU_CLIENT_COMMAND} class, extends @{Menu#MENU_COMMAND_BASE}
|
||||
-- -------------------------------------------------------------------------
|
||||
-- The @{Menu#MENU_CLIENT_COMMAND} class manages the command menus for coalitions, which allow players to execute functions during mission execution.
|
||||
-- You can add menus with the @{#MENU_CLIENT_COMMAND.New} method, which constructs a MENU_CLIENT_COMMAND object and returns you the object reference.
|
||||
-- Using this object reference, you can then remove ALL the menus and submenus underlying automatically with @{#MENU_CLIENT_COMMAND.Remove}.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- ### Contributions: -
|
||||
-- ### Authors: FlightControl : Design & Programming
|
||||
--
|
||||
-- @module Menu
|
||||
|
||||
|
||||
do -- MENU_BASE
|
||||
|
||||
--- The MENU_BASE class
|
||||
-- @type MENU_BASE
|
||||
-- @extends Base#BASE
|
||||
MENU_BASE = {
|
||||
ClassName = "MENU_BASE",
|
||||
MenuPath = nil,
|
||||
MenuText = "",
|
||||
MenuParentPath = nil
|
||||
}
|
||||
|
||||
--- Consructor
|
||||
function MENU_BASE:New( MenuText, ParentMenu )
|
||||
|
||||
local MenuParentPath = {}
|
||||
if ParentMenu ~= nil then
|
||||
MenuParentPath = ParentMenu.MenuPath
|
||||
end
|
||||
|
||||
local self = BASE:Inherit( self, BASE:New() )
|
||||
|
||||
self.MenuPath = nil
|
||||
self.MenuText = MenuText
|
||||
self.MenuParentPath = MenuParentPath
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
do -- MENU_COMMAND_BASE
|
||||
|
||||
--- The MENU_COMMAND_BASE class
|
||||
-- @type MENU_COMMAND_BASE
|
||||
-- @field #function MenuCallHandler
|
||||
-- @extends Menu#MENU_BASE
|
||||
MENU_COMMAND_BASE = {
|
||||
ClassName = "MENU_COMMAND_BASE",
|
||||
CommandMenuFunction = nil,
|
||||
CommandMenuArgument = nil,
|
||||
MenuCallHandler = nil,
|
||||
}
|
||||
|
||||
--- Constructor
|
||||
function MENU_COMMAND_BASE:New( MenuText, ParentMenu, CommandMenuFunction, CommandMenuArguments )
|
||||
|
||||
local self = BASE:Inherit( self, MENU_BASE:New( MenuText, ParentMenu ) )
|
||||
|
||||
self.CommandMenuFunction = CommandMenuFunction
|
||||
self.MenuCallHandler = function( CommandMenuArguments )
|
||||
self.CommandMenuFunction( unpack( CommandMenuArguments ) )
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
do -- MENU_MISSION
|
||||
|
||||
--- The MENU_MISSION class
|
||||
-- @type MENU_MISSION
|
||||
-- @extends Menu#MENU_BASE
|
||||
MENU_MISSION = {
|
||||
ClassName = "MENU_MISSION"
|
||||
}
|
||||
|
||||
--- MENU_MISSION constructor. Creates a new MENU_MISSION object and creates the menu for a complete mission file.
|
||||
-- @param #MENU_MISSION self
|
||||
-- @param #string MenuText The text for the menu.
|
||||
-- @param #table ParentMenu The parent menu. This parameter can be ignored if you want the menu to be located at the perent menu of DCS world (under F10 other).
|
||||
-- @return #MENU_MISSION self
|
||||
function MENU_MISSION:New( MenuText, ParentMenu )
|
||||
|
||||
local self = BASE:Inherit( self, MENU_BASE:New( MenuText, ParentMenu ) )
|
||||
|
||||
self:F( { MenuText, ParentMenu } )
|
||||
|
||||
self.MenuText = MenuText
|
||||
self.ParentMenu = ParentMenu
|
||||
|
||||
self.Menus = {}
|
||||
|
||||
self:T( { MenuText } )
|
||||
|
||||
self.MenuPath = missionCommands.addSubMenu( MenuText, self.MenuParentPath )
|
||||
|
||||
self:T( { self.MenuPath } )
|
||||
|
||||
if ParentMenu and ParentMenu.Menus then
|
||||
ParentMenu.Menus[self.MenuPath] = self
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Removes the sub menus recursively of this MENU_MISSION. Note that the main menu is kept!
|
||||
-- @param #MENU_MISSION self
|
||||
-- @return #MENU_MISSION self
|
||||
function MENU_MISSION:RemoveSubMenus()
|
||||
self:F( self.MenuPath )
|
||||
|
||||
for MenuID, Menu in pairs( self.Menus ) do
|
||||
Menu:Remove()
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--- Removes the main menu and the sub menus recursively of this MENU_MISSION.
|
||||
-- @param #MENU_MISSION self
|
||||
-- @return #nil
|
||||
function MENU_MISSION:Remove()
|
||||
self:F( self.MenuPath )
|
||||
|
||||
self:RemoveSubMenus()
|
||||
missionCommands.removeItem( self.MenuPath )
|
||||
if self.ParentMenu then
|
||||
self.ParentMenu.Menus[self.MenuPath] = nil
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
do -- MENU_MISSION_COMMAND
|
||||
|
||||
--- The MENU_MISSION_COMMAND class
|
||||
-- @type MENU_MISSION_COMMAND
|
||||
-- @extends Menu#MENU_COMMAND_BASE
|
||||
MENU_MISSION_COMMAND = {
|
||||
ClassName = "MENU_MISSION_COMMAND"
|
||||
}
|
||||
|
||||
--- MENU_MISSION constructor. Creates a new radio command item for a complete mission file, which can invoke a function with parameters.
|
||||
-- @param #MENU_MISSION_COMMAND self
|
||||
-- @param #string MenuText The text for the menu.
|
||||
-- @param Menu#MENU_MISSION ParentMenu The parent menu.
|
||||
-- @param CommandMenuFunction A function that is called when the menu key is pressed.
|
||||
-- @param CommandMenuArgument An argument for the function. There can only be ONE argument given. So multiple arguments must be wrapped into a table. See the below example how to do this.
|
||||
-- @return #MENU_MISSION_COMMAND self
|
||||
function MENU_MISSION_COMMAND:New( MenuText, ParentMenu, CommandMenuFunction, ... )
|
||||
|
||||
local self = BASE:Inherit( self, MENU_COMMAND_BASE:New( MenuText, ParentMenu, CommandMenuFunction, arg ) )
|
||||
|
||||
self.MenuText = MenuText
|
||||
self.ParentMenu = ParentMenu
|
||||
|
||||
self:T( { MenuText, CommandMenuFunction, arg } )
|
||||
|
||||
|
||||
self.MenuPath = missionCommands.addCommand( MenuText, self.MenuParentPath, self.MenuCallHandler, arg )
|
||||
|
||||
ParentMenu.Menus[self.MenuPath] = self
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Removes a radio command item for a coalition
|
||||
-- @param #MENU_MISSION_COMMAND self
|
||||
-- @return #nil
|
||||
function MENU_MISSION_COMMAND:Remove()
|
||||
self:F( self.MenuPath )
|
||||
|
||||
missionCommands.removeItem( self.MenuPath )
|
||||
if self.ParentMenu then
|
||||
self.ParentMenu.Menus[self.MenuPath] = nil
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
do -- MENU_COALITION
|
||||
|
||||
--- The MENU_COALITION class
|
||||
-- @type MENU_COALITION
|
||||
-- @extends Menu#MENU_BASE
|
||||
-- @usage
|
||||
-- -- This demo creates a menu structure for the planes within the red coalition.
|
||||
-- -- To test, join the planes, then look at the other radio menus (Option F10).
|
||||
-- -- Then switch planes and check if the menu is still there.
|
||||
--
|
||||
-- local Plane1 = CLIENT:FindByName( "Plane 1" )
|
||||
-- local Plane2 = CLIENT:FindByName( "Plane 2" )
|
||||
--
|
||||
--
|
||||
-- -- This would create a menu for the red coalition under the main DCS "Others" menu.
|
||||
-- local MenuCoalitionRed = MENU_COALITION:New( coalition.side.RED, "Manage Menus" )
|
||||
--
|
||||
--
|
||||
-- local function ShowStatus( StatusText, Coalition )
|
||||
--
|
||||
-- MESSAGE:New( Coalition, 15 ):ToRed()
|
||||
-- Plane1:Message( StatusText, 15 )
|
||||
-- Plane2:Message( StatusText, 15 )
|
||||
-- end
|
||||
--
|
||||
-- local MenuStatus -- Menu#MENU_COALITION
|
||||
-- local MenuStatusShow -- Menu#MENU_COALITION_COMMAND
|
||||
--
|
||||
-- local function RemoveStatusMenu()
|
||||
-- MenuStatus:Remove()
|
||||
-- end
|
||||
--
|
||||
-- local function AddStatusMenu()
|
||||
--
|
||||
-- -- This would create a menu for the red coalition under the MenuCoalitionRed menu object.
|
||||
-- MenuStatus = MENU_COALITION:New( coalition.side.RED, "Status for Planes" )
|
||||
-- MenuStatusShow = MENU_COALITION_COMMAND:New( coalition.side.RED, "Show Status", MenuStatus, ShowStatus, "Status of planes is ok!", "Message to Red Coalition" )
|
||||
-- end
|
||||
--
|
||||
-- local MenuAdd = MENU_COALITION_COMMAND:New( coalition.side.RED, "Add Status Menu", MenuCoalitionRed, AddStatusMenu )
|
||||
-- local MenuRemove = MENU_COALITION_COMMAND:New( coalition.side.RED, "Remove Status Menu", MenuCoalitionRed, RemoveStatusMenu )
|
||||
MENU_COALITION = {
|
||||
ClassName = "MENU_COALITION"
|
||||
}
|
||||
|
||||
--- MENU_COALITION constructor. Creates a new MENU_COALITION object and creates the menu for a complete coalition.
|
||||
-- @param #MENU_COALITION self
|
||||
-- @param Dcs.DCSCoalition#coalition.side Coalition The coalition owning the menu.
|
||||
-- @param #string MenuText The text for the menu.
|
||||
-- @param #table ParentMenu The parent menu. This parameter can be ignored if you want the menu to be located at the perent menu of DCS world (under F10 other).
|
||||
-- @return #MENU_COALITION self
|
||||
function MENU_COALITION:New( Coalition, MenuText, ParentMenu )
|
||||
|
||||
local self = BASE:Inherit( self, MENU_BASE:New( MenuText, ParentMenu ) )
|
||||
|
||||
self:F( { Coalition, MenuText, ParentMenu } )
|
||||
|
||||
self.Coalition = Coalition
|
||||
self.MenuText = MenuText
|
||||
self.ParentMenu = ParentMenu
|
||||
|
||||
self.Menus = {}
|
||||
|
||||
self:T( { MenuText } )
|
||||
|
||||
self.MenuPath = missionCommands.addSubMenuForCoalition( Coalition, MenuText, self.MenuParentPath )
|
||||
|
||||
self:T( { self.MenuPath } )
|
||||
|
||||
if ParentMenu and ParentMenu.Menus then
|
||||
ParentMenu.Menus[self.MenuPath] = self
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Removes the sub menus recursively of this MENU_COALITION. Note that the main menu is kept!
|
||||
-- @param #MENU_COALITION self
|
||||
-- @return #MENU_COALITION self
|
||||
function MENU_COALITION:RemoveSubMenus()
|
||||
self:F( self.MenuPath )
|
||||
|
||||
for MenuID, Menu in pairs( self.Menus ) do
|
||||
Menu:Remove()
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--- Removes the main menu and the sub menus recursively of this MENU_COALITION.
|
||||
-- @param #MENU_COALITION self
|
||||
-- @return #nil
|
||||
function MENU_COALITION:Remove()
|
||||
self:F( self.MenuPath )
|
||||
|
||||
self:RemoveSubMenus()
|
||||
missionCommands.removeItemForCoalition( self.Coalition, self.MenuPath )
|
||||
if self.ParentMenu then
|
||||
self.ParentMenu.Menus[self.MenuPath] = nil
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
do -- MENU_COALITION_COMMAND
|
||||
|
||||
--- The MENU_COALITION_COMMAND class
|
||||
-- @type MENU_COALITION_COMMAND
|
||||
-- @extends Menu#MENU_COMMAND_BASE
|
||||
MENU_COALITION_COMMAND = {
|
||||
ClassName = "MENU_COALITION_COMMAND"
|
||||
}
|
||||
|
||||
--- MENU_COALITION constructor. Creates a new radio command item for a coalition, which can invoke a function with parameters.
|
||||
-- @param #MENU_COALITION_COMMAND self
|
||||
-- @param Dcs.DCSCoalition#coalition.side Coalition The coalition owning the menu.
|
||||
-- @param #string MenuText The text for the menu.
|
||||
-- @param Menu#MENU_COALITION ParentMenu The parent menu.
|
||||
-- @param CommandMenuFunction A function that is called when the menu key is pressed.
|
||||
-- @param CommandMenuArgument An argument for the function. There can only be ONE argument given. So multiple arguments must be wrapped into a table. See the below example how to do this.
|
||||
-- @return #MENU_COALITION_COMMAND self
|
||||
function MENU_COALITION_COMMAND:New( Coalition, MenuText, ParentMenu, CommandMenuFunction, ... )
|
||||
|
||||
local self = BASE:Inherit( self, MENU_COMMAND_BASE:New( MenuText, ParentMenu, CommandMenuFunction, arg ) )
|
||||
|
||||
self.MenuCoalition = Coalition
|
||||
self.MenuText = MenuText
|
||||
self.ParentMenu = ParentMenu
|
||||
|
||||
self:T( { MenuText, CommandMenuFunction, arg } )
|
||||
|
||||
|
||||
self.MenuPath = missionCommands.addCommandForCoalition( self.MenuCoalition, MenuText, self.MenuParentPath, self.MenuCallHandler, arg )
|
||||
|
||||
ParentMenu.Menus[self.MenuPath] = self
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Removes a radio command item for a coalition
|
||||
-- @param #MENU_COALITION_COMMAND self
|
||||
-- @return #nil
|
||||
function MENU_COALITION_COMMAND:Remove()
|
||||
self:F( self.MenuPath )
|
||||
|
||||
missionCommands.removeItemForCoalition( self.MenuCoalition, self.MenuPath )
|
||||
if self.ParentMenu then
|
||||
self.ParentMenu.Menus[self.MenuPath] = nil
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
do -- MENU_CLIENT
|
||||
|
||||
-- This local variable is used to cache the menus registered under clients.
|
||||
-- Menus don't dissapear when clients are destroyed and restarted.
|
||||
-- So every menu for a client created must be tracked so that program logic accidentally does not create
|
||||
-- the same menus twice during initialization logic.
|
||||
-- These menu classes are handling this logic with this variable.
|
||||
local _MENUCLIENTS = {}
|
||||
|
||||
--- MENU_COALITION constructor. Creates a new radio command item for a coalition, which can invoke a function with parameters.
|
||||
-- @type MENU_CLIENT
|
||||
-- @extends Menu#MENU_BASE
|
||||
-- @usage
|
||||
-- -- This demo creates a menu structure for the two clients of planes.
|
||||
-- -- Each client will receive a different menu structure.
|
||||
-- -- To test, join the planes, then look at the other radio menus (Option F10).
|
||||
-- -- Then switch planes and check if the menu is still there.
|
||||
-- -- And play with the Add and Remove menu options.
|
||||
--
|
||||
-- -- Note that in multi player, this will only work after the DCS clients bug is solved.
|
||||
--
|
||||
-- local function ShowStatus( PlaneClient, StatusText, Coalition )
|
||||
--
|
||||
-- MESSAGE:New( Coalition, 15 ):ToRed()
|
||||
-- PlaneClient:Message( StatusText, 15 )
|
||||
-- end
|
||||
--
|
||||
-- local MenuStatus = {}
|
||||
--
|
||||
-- local function RemoveStatusMenu( MenuClient )
|
||||
-- local MenuClientName = MenuClient:GetName()
|
||||
-- MenuStatus[MenuClientName]:Remove()
|
||||
-- end
|
||||
--
|
||||
-- --- @param Wrapper.Client#CLIENT MenuClient
|
||||
-- local function AddStatusMenu( MenuClient )
|
||||
-- local MenuClientName = MenuClient:GetName()
|
||||
-- -- This would create a menu for the red coalition under the MenuCoalitionRed menu object.
|
||||
-- MenuStatus[MenuClientName] = MENU_CLIENT:New( MenuClient, "Status for Planes" )
|
||||
-- MENU_CLIENT_COMMAND:New( MenuClient, "Show Status", MenuStatus[MenuClientName], ShowStatus, MenuClient, "Status of planes is ok!", "Message to Red Coalition" )
|
||||
-- end
|
||||
--
|
||||
-- SCHEDULER:New( nil,
|
||||
-- function()
|
||||
-- local PlaneClient = CLIENT:FindByName( "Plane 1" )
|
||||
-- if PlaneClient and PlaneClient:IsAlive() then
|
||||
-- local MenuManage = MENU_CLIENT:New( PlaneClient, "Manage Menus" )
|
||||
-- MENU_CLIENT_COMMAND:New( PlaneClient, "Add Status Menu Plane 1", MenuManage, AddStatusMenu, PlaneClient )
|
||||
-- MENU_CLIENT_COMMAND:New( PlaneClient, "Remove Status Menu Plane 1", MenuManage, RemoveStatusMenu, PlaneClient )
|
||||
-- end
|
||||
-- end, {}, 10, 10 )
|
||||
--
|
||||
-- SCHEDULER:New( nil,
|
||||
-- function()
|
||||
-- local PlaneClient = CLIENT:FindByName( "Plane 2" )
|
||||
-- if PlaneClient and PlaneClient:IsAlive() then
|
||||
-- local MenuManage = MENU_CLIENT:New( PlaneClient, "Manage Menus" )
|
||||
-- MENU_CLIENT_COMMAND:New( PlaneClient, "Add Status Menu Plane 2", MenuManage, AddStatusMenu, PlaneClient )
|
||||
-- MENU_CLIENT_COMMAND:New( PlaneClient, "Remove Status Menu Plane 2", MenuManage, RemoveStatusMenu, PlaneClient )
|
||||
-- end
|
||||
-- end, {}, 10, 10 )
|
||||
MENU_CLIENT = {
|
||||
ClassName = "MENU_CLIENT"
|
||||
}
|
||||
|
||||
--- MENU_CLIENT constructor. Creates a new radio menu item for a client.
|
||||
-- @param #MENU_CLIENT self
|
||||
-- @param Wrapper.Client#CLIENT Client The Client owning the menu.
|
||||
-- @param #string MenuText The text for the menu.
|
||||
-- @param #table ParentMenu The parent menu.
|
||||
-- @return #MENU_CLIENT self
|
||||
function MENU_CLIENT:New( Client, MenuText, ParentMenu )
|
||||
|
||||
-- Arrange meta tables
|
||||
local MenuParentPath = {}
|
||||
if ParentMenu ~= nil then
|
||||
MenuParentPath = ParentMenu.MenuPath
|
||||
end
|
||||
|
||||
local self = BASE:Inherit( self, MENU_BASE:New( MenuText, MenuParentPath ) )
|
||||
self:F( { Client, MenuText, ParentMenu } )
|
||||
|
||||
self.MenuClient = Client
|
||||
self.MenuClientGroupID = Client:GetClientGroupID()
|
||||
self.MenuParentPath = MenuParentPath
|
||||
self.MenuText = MenuText
|
||||
self.ParentMenu = ParentMenu
|
||||
|
||||
self.Menus = {}
|
||||
|
||||
if not _MENUCLIENTS[self.MenuClientGroupID] then
|
||||
_MENUCLIENTS[self.MenuClientGroupID] = {}
|
||||
end
|
||||
|
||||
local MenuPath = _MENUCLIENTS[self.MenuClientGroupID]
|
||||
|
||||
self:T( { Client:GetClientGroupName(), MenuPath[table.concat(MenuParentPath)], MenuParentPath, MenuText } )
|
||||
|
||||
local MenuPathID = table.concat(MenuParentPath) .. "/" .. MenuText
|
||||
if MenuPath[MenuPathID] then
|
||||
missionCommands.removeItemForGroup( self.MenuClient:GetClientGroupID(), MenuPath[MenuPathID] )
|
||||
end
|
||||
|
||||
self.MenuPath = missionCommands.addSubMenuForGroup( self.MenuClient:GetClientGroupID(), MenuText, MenuParentPath )
|
||||
MenuPath[MenuPathID] = self.MenuPath
|
||||
|
||||
self:T( { Client:GetClientGroupName(), self.MenuPath } )
|
||||
|
||||
if ParentMenu and ParentMenu.Menus then
|
||||
ParentMenu.Menus[self.MenuPath] = self
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
--- Removes the sub menus recursively of this @{#MENU_CLIENT}.
|
||||
-- @param #MENU_CLIENT self
|
||||
-- @return #MENU_CLIENT self
|
||||
function MENU_CLIENT:RemoveSubMenus()
|
||||
self:F( self.MenuPath )
|
||||
|
||||
for MenuID, Menu in pairs( self.Menus ) do
|
||||
Menu:Remove()
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--- Removes the sub menus recursively of this MENU_CLIENT.
|
||||
-- @param #MENU_CLIENT self
|
||||
-- @return #nil
|
||||
function MENU_CLIENT:Remove()
|
||||
self:F( self.MenuPath )
|
||||
|
||||
self:RemoveSubMenus()
|
||||
|
||||
if not _MENUCLIENTS[self.MenuClientGroupID] then
|
||||
_MENUCLIENTS[self.MenuClientGroupID] = {}
|
||||
end
|
||||
|
||||
local MenuPath = _MENUCLIENTS[self.MenuClientGroupID]
|
||||
|
||||
if MenuPath[table.concat(self.MenuParentPath) .. "/" .. self.MenuText] then
|
||||
MenuPath[table.concat(self.MenuParentPath) .. "/" .. self.MenuText] = nil
|
||||
end
|
||||
|
||||
missionCommands.removeItemForGroup( self.MenuClient:GetClientGroupID(), self.MenuPath )
|
||||
self.ParentMenu.Menus[self.MenuPath] = nil
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
--- The MENU_CLIENT_COMMAND class
|
||||
-- @type MENU_CLIENT_COMMAND
|
||||
-- @extends Menu#MENU_COMMAND
|
||||
MENU_CLIENT_COMMAND = {
|
||||
ClassName = "MENU_CLIENT_COMMAND"
|
||||
}
|
||||
|
||||
--- MENU_CLIENT_COMMAND constructor. Creates a new radio command item for a client, which can invoke a function with parameters.
|
||||
-- @param #MENU_CLIENT_COMMAND self
|
||||
-- @param Wrapper.Client#CLIENT Client The Client owning the menu.
|
||||
-- @param #string MenuText The text for the menu.
|
||||
-- @param #MENU_BASE ParentMenu The parent menu.
|
||||
-- @param CommandMenuFunction A function that is called when the menu key is pressed.
|
||||
-- @return Menu#MENU_CLIENT_COMMAND self
|
||||
function MENU_CLIENT_COMMAND:New( Client, MenuText, ParentMenu, CommandMenuFunction, ... )
|
||||
|
||||
-- Arrange meta tables
|
||||
|
||||
local MenuParentPath = {}
|
||||
if ParentMenu ~= nil then
|
||||
MenuParentPath = ParentMenu.MenuPath
|
||||
end
|
||||
|
||||
local self = BASE:Inherit( self, MENU_COMMAND_BASE:New( MenuText, MenuParentPath, CommandMenuFunction, arg ) ) -- Menu#MENU_CLIENT_COMMAND
|
||||
|
||||
self.MenuClient = Client
|
||||
self.MenuClientGroupID = Client:GetClientGroupID()
|
||||
self.MenuParentPath = MenuParentPath
|
||||
self.MenuText = MenuText
|
||||
self.ParentMenu = ParentMenu
|
||||
|
||||
if not _MENUCLIENTS[self.MenuClientGroupID] then
|
||||
_MENUCLIENTS[self.MenuClientGroupID] = {}
|
||||
end
|
||||
|
||||
local MenuPath = _MENUCLIENTS[self.MenuClientGroupID]
|
||||
|
||||
self:T( { Client:GetClientGroupName(), MenuPath[table.concat(MenuParentPath)], MenuParentPath, MenuText, CommandMenuFunction, arg } )
|
||||
|
||||
local MenuPathID = table.concat(MenuParentPath) .. "/" .. MenuText
|
||||
if MenuPath[MenuPathID] then
|
||||
missionCommands.removeItemForGroup( self.MenuClient:GetClientGroupID(), MenuPath[MenuPathID] )
|
||||
end
|
||||
|
||||
self.MenuPath = missionCommands.addCommandForGroup( self.MenuClient:GetClientGroupID(), MenuText, MenuParentPath, self.MenuCallHandler, arg )
|
||||
MenuPath[MenuPathID] = self.MenuPath
|
||||
|
||||
if ParentMenu and ParentMenu.Menus then
|
||||
ParentMenu.Menus[self.MenuPath] = self
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Removes a menu structure for a client.
|
||||
-- @param #MENU_CLIENT_COMMAND self
|
||||
-- @return #nil
|
||||
function MENU_CLIENT_COMMAND:Remove()
|
||||
self:F( self.MenuPath )
|
||||
|
||||
if not _MENUCLIENTS[self.MenuClientGroupID] then
|
||||
_MENUCLIENTS[self.MenuClientGroupID] = {}
|
||||
end
|
||||
|
||||
local MenuPath = _MENUCLIENTS[self.MenuClientGroupID]
|
||||
|
||||
if MenuPath[table.concat(self.MenuParentPath) .. "/" .. self.MenuText] then
|
||||
MenuPath[table.concat(self.MenuParentPath) .. "/" .. self.MenuText] = nil
|
||||
end
|
||||
|
||||
missionCommands.removeItemForGroup( self.MenuClient:GetClientGroupID(), self.MenuPath )
|
||||
self.ParentMenu.Menus[self.MenuPath] = nil
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
--- MENU_GROUP
|
||||
|
||||
do
|
||||
-- This local variable is used to cache the menus registered under groups.
|
||||
-- Menus don't dissapear when groups for players are destroyed and restarted.
|
||||
-- So every menu for a client created must be tracked so that program logic accidentally does not create.
|
||||
-- the same menus twice during initialization logic.
|
||||
-- These menu classes are handling this logic with this variable.
|
||||
local _MENUGROUPS = {}
|
||||
|
||||
--- The MENU_GROUP class
|
||||
-- @type MENU_GROUP
|
||||
-- @extends Menu#MENU_BASE
|
||||
-- @usage
|
||||
-- -- This demo creates a menu structure for the two groups of planes.
|
||||
-- -- Each group will receive a different menu structure.
|
||||
-- -- To test, join the planes, then look at the other radio menus (Option F10).
|
||||
-- -- Then switch planes and check if the menu is still there.
|
||||
-- -- And play with the Add and Remove menu options.
|
||||
--
|
||||
-- -- Note that in multi player, this will only work after the DCS groups bug is solved.
|
||||
--
|
||||
-- local function ShowStatus( PlaneGroup, StatusText, Coalition )
|
||||
--
|
||||
-- MESSAGE:New( Coalition, 15 ):ToRed()
|
||||
-- PlaneGroup:Message( StatusText, 15 )
|
||||
-- end
|
||||
--
|
||||
-- local MenuStatus = {}
|
||||
--
|
||||
-- local function RemoveStatusMenu( MenuGroup )
|
||||
-- local MenuGroupName = MenuGroup:GetName()
|
||||
-- MenuStatus[MenuGroupName]:Remove()
|
||||
-- end
|
||||
--
|
||||
-- --- @param Wrapper.Group#GROUP MenuGroup
|
||||
-- local function AddStatusMenu( MenuGroup )
|
||||
-- local MenuGroupName = MenuGroup:GetName()
|
||||
-- -- This would create a menu for the red coalition under the MenuCoalitionRed menu object.
|
||||
-- MenuStatus[MenuGroupName] = MENU_GROUP:New( MenuGroup, "Status for Planes" )
|
||||
-- MENU_GROUP_COMMAND:New( MenuGroup, "Show Status", MenuStatus[MenuGroupName], ShowStatus, MenuGroup, "Status of planes is ok!", "Message to Red Coalition" )
|
||||
-- end
|
||||
--
|
||||
-- SCHEDULER:New( nil,
|
||||
-- function()
|
||||
-- local PlaneGroup = GROUP:FindByName( "Plane 1" )
|
||||
-- if PlaneGroup and PlaneGroup:IsAlive() then
|
||||
-- local MenuManage = MENU_GROUP:New( PlaneGroup, "Manage Menus" )
|
||||
-- MENU_GROUP_COMMAND:New( PlaneGroup, "Add Status Menu Plane 1", MenuManage, AddStatusMenu, PlaneGroup )
|
||||
-- MENU_GROUP_COMMAND:New( PlaneGroup, "Remove Status Menu Plane 1", MenuManage, RemoveStatusMenu, PlaneGroup )
|
||||
-- end
|
||||
-- end, {}, 10, 10 )
|
||||
--
|
||||
-- SCHEDULER:New( nil,
|
||||
-- function()
|
||||
-- local PlaneGroup = GROUP:FindByName( "Plane 2" )
|
||||
-- if PlaneGroup and PlaneGroup:IsAlive() then
|
||||
-- local MenuManage = MENU_GROUP:New( PlaneGroup, "Manage Menus" )
|
||||
-- MENU_GROUP_COMMAND:New( PlaneGroup, "Add Status Menu Plane 2", MenuManage, AddStatusMenu, PlaneGroup )
|
||||
-- MENU_GROUP_COMMAND:New( PlaneGroup, "Remove Status Menu Plane 2", MenuManage, RemoveStatusMenu, PlaneGroup )
|
||||
-- end
|
||||
-- end, {}, 10, 10 )
|
||||
--
|
||||
MENU_GROUP = {
|
||||
ClassName = "MENU_GROUP"
|
||||
}
|
||||
|
||||
--- MENU_GROUP constructor. Creates a new radio menu item for a group.
|
||||
-- @param #MENU_GROUP self
|
||||
-- @param Wrapper.Group#GROUP MenuGroup The Group owning the menu.
|
||||
-- @param #string MenuText The text for the menu.
|
||||
-- @param #table ParentMenu The parent menu.
|
||||
-- @return #MENU_GROUP self
|
||||
function MENU_GROUP:New( MenuGroup, MenuText, ParentMenu )
|
||||
|
||||
-- Determine if the menu was not already created and already visible at the group.
|
||||
-- If it is visible, then return the cached self, otherwise, create self and cache it.
|
||||
|
||||
MenuGroup._Menus = MenuGroup._Menus or {}
|
||||
local Path = ( ParentMenu and ( table.concat( ParentMenu.MenuPath or {}, "@" ) .. "@" .. MenuText ) ) or MenuText
|
||||
if MenuGroup._Menus[Path] then
|
||||
self = MenuGroup._Menus[Path]
|
||||
else
|
||||
self = BASE:Inherit( self, MENU_BASE:New( MenuText, ParentMenu ) )
|
||||
MenuGroup._Menus[Path] = self
|
||||
|
||||
self.Menus = {}
|
||||
|
||||
self.MenuGroup = MenuGroup
|
||||
self.Path = Path
|
||||
self.MenuGroupID = MenuGroup:GetID()
|
||||
self.MenuText = MenuText
|
||||
self.ParentMenu = ParentMenu
|
||||
|
||||
self:T( { "Adding Menu ", MenuText, self.MenuParentPath } )
|
||||
self.MenuPath = missionCommands.addSubMenuForGroup( self.MenuGroupID, MenuText, self.MenuParentPath )
|
||||
|
||||
if ParentMenu and ParentMenu.Menus then
|
||||
ParentMenu.Menus[self.MenuPath] = self
|
||||
end
|
||||
end
|
||||
|
||||
--self:F( { MenuGroup:GetName(), MenuText, ParentMenu.MenuPath } )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Removes the sub menus recursively of this MENU_GROUP.
|
||||
-- @param #MENU_GROUP self
|
||||
-- @return #MENU_GROUP self
|
||||
function MENU_GROUP:RemoveSubMenus()
|
||||
self:F( self.MenuPath )
|
||||
|
||||
for MenuID, Menu in pairs( self.Menus ) do
|
||||
Menu:Remove()
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--- Removes the main menu and sub menus recursively of this MENU_GROUP.
|
||||
-- @param #MENU_GROUP self
|
||||
-- @return #nil
|
||||
function MENU_GROUP:Remove()
|
||||
self:F( { self.MenuGroupID, self.MenuPath } )
|
||||
|
||||
self:RemoveSubMenus()
|
||||
|
||||
if self.MenuGroup._Menus[self.Path] then
|
||||
self = self.MenuGroup._Menus[self.Path]
|
||||
|
||||
missionCommands.removeItemForGroup( self.MenuGroupID, self.MenuPath )
|
||||
if self.ParentMenu then
|
||||
self.ParentMenu.Menus[self.MenuPath] = nil
|
||||
end
|
||||
self:E( self.MenuGroup._Menus[self.Path] )
|
||||
self.MenuGroup._Menus[self.Path] = nil
|
||||
self = nil
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
--- The MENU_GROUP_COMMAND class
|
||||
-- @type MENU_GROUP_COMMAND
|
||||
-- @extends Menu#MENU_BASE
|
||||
MENU_GROUP_COMMAND = {
|
||||
ClassName = "MENU_GROUP_COMMAND"
|
||||
}
|
||||
|
||||
--- Creates a new radio command item for a group
|
||||
-- @param #MENU_GROUP_COMMAND self
|
||||
-- @param Wrapper.Group#GROUP MenuGroup The Group owning the menu.
|
||||
-- @param MenuText The text for the menu.
|
||||
-- @param ParentMenu The parent menu.
|
||||
-- @param CommandMenuFunction A function that is called when the menu key is pressed.
|
||||
-- @param CommandMenuArgument An argument for the function.
|
||||
-- @return Menu#MENU_GROUP_COMMAND self
|
||||
function MENU_GROUP_COMMAND:New( MenuGroup, MenuText, ParentMenu, CommandMenuFunction, ... )
|
||||
|
||||
MenuGroup._Menus = MenuGroup._Menus or {}
|
||||
local Path = ( ParentMenu and ( table.concat( ParentMenu.MenuPath or {}, "@" ) .. "@" .. MenuText ) ) or MenuText
|
||||
if MenuGroup._Menus[Path] then
|
||||
self = MenuGroup._Menus[Path]
|
||||
else
|
||||
self = BASE:Inherit( self, MENU_COMMAND_BASE:New( MenuText, ParentMenu, CommandMenuFunction, arg ) )
|
||||
MenuGroup._Menus[Path] = self
|
||||
|
||||
self.Path = Path
|
||||
self.MenuGroup = MenuGroup
|
||||
self.MenuGroupID = MenuGroup:GetID()
|
||||
self.MenuText = MenuText
|
||||
self.ParentMenu = ParentMenu
|
||||
|
||||
self:T( { "Adding Command Menu ", MenuText, self.MenuParentPath } )
|
||||
self.MenuPath = missionCommands.addCommandForGroup( self.MenuGroupID, MenuText, self.MenuParentPath, self.MenuCallHandler, arg )
|
||||
|
||||
if ParentMenu and ParentMenu.Menus then
|
||||
ParentMenu.Menus[self.MenuPath] = self
|
||||
end
|
||||
end
|
||||
|
||||
--self:F( { MenuGroup:GetName(), MenuText, ParentMenu.MenuPath } )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Removes a menu structure for a group.
|
||||
-- @param #MENU_GROUP_COMMAND self
|
||||
-- @return #nil
|
||||
function MENU_GROUP_COMMAND:Remove()
|
||||
self:F( { self.MenuGroupID, self.MenuPath } )
|
||||
|
||||
if self.MenuGroup._Menus[self.Path] then
|
||||
self = self.MenuGroup._Menus[self.Path]
|
||||
|
||||
missionCommands.removeItemForGroup( self.MenuGroupID, self.MenuPath )
|
||||
self.ParentMenu.Menus[self.MenuPath] = nil
|
||||
self:E( self.MenuGroup._Menus[self.Path] )
|
||||
self.MenuGroup._Menus[self.Path] = nil
|
||||
self = nil
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -1,17 +1,30 @@
|
||||
--- Message System to display Messages for Clients and Coalitions or All.
|
||||
-- Messages are grouped on the display panel per Category to improve readability for the players.
|
||||
--- This module contains the MESSAGE class.
|
||||
--
|
||||
-- 1) @{Message#MESSAGE} class, extends @{Base#BASE}
|
||||
-- =================================================
|
||||
-- Message System to display Messages to Clients, Coalitions or All.
|
||||
-- Messages are shown on the display panel for an amount of seconds, and will then disappear.
|
||||
-- Messages are identified by an ID. The messages with the same ID belonging to the same category will be overwritten if they were still being displayed on the display panel.
|
||||
-- Messages are created with MESSAGE:@{New}().
|
||||
-- Messages are sent to Clients with MESSAGE:@{ToClient}().
|
||||
-- Messages are sent to Coalitions with MESSAGE:@{ToCoalition}().
|
||||
-- Messages are sent to All Players with MESSAGE:@{ToAll}().
|
||||
-- Messages can contain a category which is indicating the category of the message.
|
||||
--
|
||||
-- 1.1) MESSAGE construction methods
|
||||
-- ---------------------------------
|
||||
-- Messages are created with @{Message#MESSAGE.New}. Note that when the MESSAGE object is created, no message is sent yet.
|
||||
-- To send messages, you need to use the To functions.
|
||||
--
|
||||
-- 1.2) Send messages with MESSAGE To methods
|
||||
-- ------------------------------------------
|
||||
-- Messages are sent to:
|
||||
--
|
||||
-- * Clients with @{Message#MESSAGE.ToClient}.
|
||||
-- * Coalitions with @{Message#MESSAGE.ToCoalition}.
|
||||
-- * All Players with @{Message#MESSAGE.ToAll}.
|
||||
--
|
||||
-- @module Message
|
||||
|
||||
Include.File( "Base" )
|
||||
-- @author FlightControl
|
||||
|
||||
--- The MESSAGE class
|
||||
-- @type MESSAGE
|
||||
-- @extends Core.Base#BASE
|
||||
MESSAGE = {
|
||||
ClassName = "MESSAGE",
|
||||
MessageCategory = 0,
|
||||
@@ -22,9 +35,8 @@ MESSAGE = {
|
||||
--- Creates a new MESSAGE object. Note that these MESSAGE objects are not yet displayed on the display panel. You must use the functions @{ToClient} or @{ToCoalition} or @{ToAll} to send these Messages to the respective recipients.
|
||||
-- @param self
|
||||
-- @param #string MessageText is the text of the Message.
|
||||
-- @param #string MessageCategory is a string expressing the Category of the Message. Messages are grouped on the display panel per Category to improve readability.
|
||||
-- @param #number MessageDuration is a number in seconds of how long the MESSAGE should be shown on the display panel.
|
||||
-- @param #string MessageID is a string expressing the ID of the Message.
|
||||
-- @param #string MessageCategory (optional) is a string expressing the "category" of the Message. The category will be shown as the first text in the message followed by a ": ".
|
||||
-- @return #MESSAGE
|
||||
-- @usage
|
||||
-- -- Create a series of new Messages.
|
||||
@@ -32,23 +44,26 @@ MESSAGE = {
|
||||
-- -- MessageRED is meant to be sent to the RED players only, for 10 seconds, and is classified as "End of Mission", with ID "Win".
|
||||
-- -- MessageClient1 is meant to be sent to a Client, for 25 seconds, and is classified as "Score", with ID "Score".
|
||||
-- -- MessageClient1 is meant to be sent to a Client, for 25 seconds, and is classified as "Score", with ID "Score".
|
||||
-- MessageAll = MESSAGE:New( "To all Players: BLUE has won! Each player of BLUE wins 50 points!", "End of Mission", 25, "Win" )
|
||||
-- MessageRED = MESSAGE:New( "To the RED Players: You receive a penalty because you've killed one of your own units", "Penalty", 25, "Score" )
|
||||
-- MessageClient1 = MESSAGE:New( "Congratulations, you've just hit a target", "Score", 25, "Score" )
|
||||
-- MessageClient2 = MESSAGE:New( "Congratulations, you've just killed a target", "Score", 25, "Score" )
|
||||
function MESSAGE:New( MessageText, MessageCategory, MessageDuration, MessageID )
|
||||
-- MessageAll = MESSAGE:New( "To all Players: BLUE has won! Each player of BLUE wins 50 points!", 25, "End of Mission" )
|
||||
-- MessageRED = MESSAGE:New( "To the RED Players: You receive a penalty because you've killed one of your own units", 25, "Penalty" )
|
||||
-- MessageClient1 = MESSAGE:New( "Congratulations, you've just hit a target", 25, "Score" )
|
||||
-- MessageClient2 = MESSAGE:New( "Congratulations, you've just killed a target", 25, "Score")
|
||||
function MESSAGE:New( MessageText, MessageDuration, MessageCategory )
|
||||
local self = BASE:Inherit( self, BASE:New() )
|
||||
self:F( { MessageText, MessageCategory, MessageDuration, MessageID } )
|
||||
self:F( { MessageText, MessageDuration, MessageCategory } )
|
||||
|
||||
-- When no messagecategory is given, we don't show it as a title...
|
||||
-- When no MessageCategory is given, we don't show it as a title...
|
||||
if MessageCategory and MessageCategory ~= "" then
|
||||
self.MessageCategory = MessageCategory .. ": "
|
||||
if MessageCategory:sub(-1) ~= "\n" then
|
||||
self.MessageCategory = MessageCategory .. ": "
|
||||
else
|
||||
self.MessageCategory = MessageCategory:sub( 1, -2 ) .. ":\n"
|
||||
end
|
||||
else
|
||||
self.MessageCategory = ""
|
||||
end
|
||||
|
||||
self.MessageDuration = MessageDuration
|
||||
self.MessageID = MessageID
|
||||
self.MessageDuration = MessageDuration or 5
|
||||
self.MessageTime = timer.getTime()
|
||||
self.MessageText = MessageText
|
||||
|
||||
@@ -61,7 +76,7 @@ end
|
||||
|
||||
--- Sends a MESSAGE to a Client Group. Note that the Group needs to be defined within the ME with the skillset "Client" or "Player".
|
||||
-- @param #MESSAGE self
|
||||
-- @param Client#CLIENT Client is the Group of the Client.
|
||||
-- @param Wrapper.Client#CLIENT Client is the Group of the Client.
|
||||
-- @return #MESSAGE
|
||||
-- @usage
|
||||
-- -- Send the 2 messages created with the @{New} method to the Client Group.
|
||||
@@ -91,6 +106,21 @@ function MESSAGE:ToClient( Client )
|
||||
return self
|
||||
end
|
||||
|
||||
--- Sends a MESSAGE to a Group.
|
||||
-- @param #MESSAGE self
|
||||
-- @param Wrapper.Group#GROUP Group is the Group.
|
||||
-- @return #MESSAGE
|
||||
function MESSAGE:ToGroup( Group )
|
||||
self:F( Group.GroupName )
|
||||
|
||||
if Group then
|
||||
|
||||
self:T( self.MessageCategory .. self.MessageText:gsub("\n$",""):gsub("\n$","") .. " / " .. self.MessageDuration )
|
||||
trigger.action.outTextForGroup( Group:GetID(), self.MessageCategory .. self.MessageText:gsub("\n$",""):gsub("\n$",""), self.MessageDuration )
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
--- Sends a MESSAGE to the Blue coalition.
|
||||
-- @param #MESSAGE self
|
||||
-- @return #MESSAGE
|
||||
@@ -152,6 +182,20 @@ function MESSAGE:ToCoalition( CoalitionSide )
|
||||
return self
|
||||
end
|
||||
|
||||
--- Sends a MESSAGE to a Coalition if the given Condition is true.
|
||||
-- @param #MESSAGE self
|
||||
-- @param CoalitionSide needs to be filled out by the defined structure of the standard scripting engine @{coalition.side}.
|
||||
-- @return #MESSAGE
|
||||
function MESSAGE:ToCoalitionIf( CoalitionSide, Condition )
|
||||
self:F( CoalitionSide )
|
||||
|
||||
if Condition and Condition == true then
|
||||
self:ToCoalition( CoalitionSide )
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Sends a MESSAGE to all players.
|
||||
-- @param #MESSAGE self
|
||||
-- @return #MESSAGE
|
||||
@@ -164,84 +208,101 @@ end
|
||||
-- MessageAll = MESSAGE:New( "To all Players: BLUE has won! Each player of BLUE wins 50 points!", "End of Mission", 25, "Win" )
|
||||
-- MessageAll:ToAll()
|
||||
function MESSAGE:ToAll()
|
||||
self:F()
|
||||
self:F()
|
||||
|
||||
self:ToCoalition( coalition.side.RED )
|
||||
self:ToCoalition( coalition.side.BLUE )
|
||||
self:ToCoalition( coalition.side.RED )
|
||||
self:ToCoalition( coalition.side.BLUE )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
--- Sends a MESSAGE to all players if the given Condition is true.
|
||||
-- @param #MESSAGE self
|
||||
-- @return #MESSAGE
|
||||
function MESSAGE:ToAllIf( Condition )
|
||||
|
||||
if Condition and Condition == true then
|
||||
self:ToCoalition( coalition.side.RED )
|
||||
self:ToCoalition( coalition.side.BLUE )
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
|
||||
--- The MESSAGEQUEUE class
|
||||
-- @type MESSAGEQUEUE
|
||||
MESSAGEQUEUE = {
|
||||
ClientGroups = {},
|
||||
CoalitionSides = {}
|
||||
}
|
||||
|
||||
function MESSAGEQUEUE:New( RefreshInterval )
|
||||
local self = BASE:Inherit( self, BASE:New() )
|
||||
self:F( { RefreshInterval } )
|
||||
|
||||
self.RefreshInterval = RefreshInterval
|
||||
|
||||
self.DisplayFunction = routines.scheduleFunction( self._DisplayMessages, { self }, 0, RefreshInterval )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- This function is called automatically by the MESSAGEQUEUE scheduler.
|
||||
function MESSAGEQUEUE:_DisplayMessages()
|
||||
|
||||
-- First we display all messages that a coalition needs to receive... Also those who are not in a client (CA module clients...).
|
||||
for CoalitionSideID, CoalitionSideData in pairs( self.CoalitionSides ) do
|
||||
for MessageID, MessageData in pairs( CoalitionSideData.Messages ) do
|
||||
if MessageData.MessageSent == false then
|
||||
--trigger.action.outTextForCoalition( CoalitionSideID, MessageData.MessageCategory .. '\n' .. MessageData.MessageText:gsub("\n$",""):gsub("\n$",""), MessageData.MessageDuration )
|
||||
MessageData.MessageSent = true
|
||||
end
|
||||
local MessageTimeLeft = ( MessageData.MessageTime + MessageData.MessageDuration ) - timer.getTime()
|
||||
if MessageTimeLeft <= 0 then
|
||||
MessageData = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Then we send the messages for each individual client, but also to be included are those Coalition messages for the Clients who belong to a coalition.
|
||||
-- Because the Client messages will overwrite the Coalition messages (for that Client).
|
||||
for ClientGroupName, ClientGroupData in pairs( self.ClientGroups ) do
|
||||
for MessageID, MessageData in pairs( ClientGroupData.Messages ) do
|
||||
if MessageData.MessageGroup == false then
|
||||
trigger.action.outTextForGroup( Group.getByName(ClientGroupName):getID(), MessageData.MessageCategory .. '\n' .. MessageData.MessageText:gsub("\n$",""):gsub("\n$",""), MessageData.MessageDuration )
|
||||
MessageData.MessageGroup = true
|
||||
end
|
||||
local MessageTimeLeft = ( MessageData.MessageTime + MessageData.MessageDuration ) - timer.getTime()
|
||||
if MessageTimeLeft <= 0 then
|
||||
MessageData = nil
|
||||
end
|
||||
end
|
||||
|
||||
-- Now check if the Client also has messages that belong to the Coalition of the Client...
|
||||
for CoalitionSideID, CoalitionSideData in pairs( self.CoalitionSides ) do
|
||||
for MessageID, MessageData in pairs( CoalitionSideData.Messages ) do
|
||||
local CoalitionGroup = Group.getByName( ClientGroupName )
|
||||
if CoalitionGroup and CoalitionGroup:getCoalition() == CoalitionSideID then
|
||||
if MessageData.MessageCoalition == false then
|
||||
trigger.action.outTextForGroup( Group.getByName(ClientGroupName):getID(), MessageData.MessageCategory .. '\n' .. MessageData.MessageText:gsub("\n$",""):gsub("\n$",""), MessageData.MessageDuration )
|
||||
MessageData.MessageCoalition = true
|
||||
end
|
||||
end
|
||||
local MessageTimeLeft = ( MessageData.MessageTime + MessageData.MessageDuration ) - timer.getTime()
|
||||
if MessageTimeLeft <= 0 then
|
||||
MessageData = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- The _MessageQueue object is created when the MESSAGE class module is loaded.
|
||||
--_MessageQueue = MESSAGEQUEUE:New( 0.5 )
|
||||
|
||||
----- The MESSAGEQUEUE class
|
||||
---- @type MESSAGEQUEUE
|
||||
--MESSAGEQUEUE = {
|
||||
-- ClientGroups = {},
|
||||
-- CoalitionSides = {}
|
||||
--}
|
||||
--
|
||||
--function MESSAGEQUEUE:New( RefreshInterval )
|
||||
-- local self = BASE:Inherit( self, BASE:New() )
|
||||
-- self:F( { RefreshInterval } )
|
||||
--
|
||||
-- self.RefreshInterval = RefreshInterval
|
||||
--
|
||||
-- --self.DisplayFunction = routines.scheduleFunction( self._DisplayMessages, { self }, 0, RefreshInterval )
|
||||
-- self.DisplayFunction = SCHEDULER:New( self, self._DisplayMessages, {}, 0, RefreshInterval )
|
||||
--
|
||||
-- return self
|
||||
--end
|
||||
--
|
||||
----- This function is called automatically by the MESSAGEQUEUE scheduler.
|
||||
--function MESSAGEQUEUE:_DisplayMessages()
|
||||
--
|
||||
-- -- First we display all messages that a coalition needs to receive... Also those who are not in a client (CA module clients...).
|
||||
-- for CoalitionSideID, CoalitionSideData in pairs( self.CoalitionSides ) do
|
||||
-- for MessageID, MessageData in pairs( CoalitionSideData.Messages ) do
|
||||
-- if MessageData.MessageSent == false then
|
||||
-- --trigger.action.outTextForCoalition( CoalitionSideID, MessageData.MessageCategory .. '\n' .. MessageData.MessageText:gsub("\n$",""):gsub("\n$",""), MessageData.MessageDuration )
|
||||
-- MessageData.MessageSent = true
|
||||
-- end
|
||||
-- local MessageTimeLeft = ( MessageData.MessageTime + MessageData.MessageDuration ) - timer.getTime()
|
||||
-- if MessageTimeLeft <= 0 then
|
||||
-- MessageData = nil
|
||||
-- end
|
||||
-- end
|
||||
-- end
|
||||
--
|
||||
-- -- Then we send the messages for each individual client, but also to be included are those Coalition messages for the Clients who belong to a coalition.
|
||||
-- -- Because the Client messages will overwrite the Coalition messages (for that Client).
|
||||
-- for ClientGroupName, ClientGroupData in pairs( self.ClientGroups ) do
|
||||
-- for MessageID, MessageData in pairs( ClientGroupData.Messages ) do
|
||||
-- if MessageData.MessageGroup == false then
|
||||
-- trigger.action.outTextForGroup( Group.getByName(ClientGroupName):getID(), MessageData.MessageCategory .. '\n' .. MessageData.MessageText:gsub("\n$",""):gsub("\n$",""), MessageData.MessageDuration )
|
||||
-- MessageData.MessageGroup = true
|
||||
-- end
|
||||
-- local MessageTimeLeft = ( MessageData.MessageTime + MessageData.MessageDuration ) - timer.getTime()
|
||||
-- if MessageTimeLeft <= 0 then
|
||||
-- MessageData = nil
|
||||
-- end
|
||||
-- end
|
||||
--
|
||||
-- -- Now check if the Client also has messages that belong to the Coalition of the Client...
|
||||
-- for CoalitionSideID, CoalitionSideData in pairs( self.CoalitionSides ) do
|
||||
-- for MessageID, MessageData in pairs( CoalitionSideData.Messages ) do
|
||||
-- local CoalitionGroup = Group.getByName( ClientGroupName )
|
||||
-- if CoalitionGroup and CoalitionGroup:getCoalition() == CoalitionSideID then
|
||||
-- if MessageData.MessageCoalition == false then
|
||||
-- trigger.action.outTextForGroup( Group.getByName(ClientGroupName):getID(), MessageData.MessageCategory .. '\n' .. MessageData.MessageText:gsub("\n$",""):gsub("\n$",""), MessageData.MessageDuration )
|
||||
-- MessageData.MessageCoalition = true
|
||||
-- end
|
||||
-- end
|
||||
-- local MessageTimeLeft = ( MessageData.MessageTime + MessageData.MessageDuration ) - timer.getTime()
|
||||
-- if MessageTimeLeft <= 0 then
|
||||
-- MessageData = nil
|
||||
-- end
|
||||
-- end
|
||||
-- end
|
||||
-- end
|
||||
--
|
||||
-- return true
|
||||
--end
|
||||
--
|
||||
----- The _MessageQueue object is created when the MESSAGE class module is loaded.
|
||||
----_MessageQueue = MESSAGEQUEUE:New( 0.5 )
|
||||
--
|
||||
885
Moose Development/Moose/Core/Point.lua
Normal file
885
Moose Development/Moose/Core/Point.lua
Normal file
@@ -0,0 +1,885 @@
|
||||
--- This module contains the POINT classes.
|
||||
--
|
||||
-- 1) @{Point#POINT_VEC3} class, extends @{Base#BASE}
|
||||
-- ==================================================
|
||||
-- The @{Point#POINT_VEC3} class defines a 3D point in the simulator.
|
||||
--
|
||||
-- **Important Note:** Most of the functions in this section were taken from MIST, and reworked to OO concepts.
|
||||
-- In order to keep the credibility of the the author, I want to emphasize that the of the MIST framework was created by Grimes, who you can find on the Eagle Dynamics Forums.
|
||||
--
|
||||
-- ## 1.1) POINT_VEC3 constructor
|
||||
--
|
||||
-- A new POINT_VEC3 instance can be created with:
|
||||
--
|
||||
-- * @{Point#POINT_VEC3.New}(): a 3D point.
|
||||
-- * @{Point#POINT_VEC3.NewFromVec3}(): a 3D point created from a @{DCSTypes#Vec3}.
|
||||
--
|
||||
-- ## 1.2) Manupulate the X, Y, Z coordinates of the point
|
||||
--
|
||||
-- A POINT_VEC3 class works in 3D space. It contains internally an X, Y, Z coordinate.
|
||||
-- Methods exist to manupulate these coordinates.
|
||||
--
|
||||
-- The current X, Y, Z axis can be retrieved with the methods @{#POINT_VEC3.GetX}(), @{#POINT_VEC3.GetY}(), @{#POINT_VEC3.GetZ}() respectively.
|
||||
-- The methods @{#POINT_VEC3.SetX}(), @{#POINT_VEC3.SetY}(), @{#POINT_VEC3.SetZ}() change the respective axis with a new value.
|
||||
-- The current axis values can be changed by using the methods @{#POINT_VEC3.AddX}(), @{#POINT_VEC3.AddY}(), @{#POINT_VEC3.AddZ}()
|
||||
-- to add or substract a value from the current respective axis value.
|
||||
-- Note that the Set and Add methods return the current POINT_VEC3 object, so these manipulation methods can be chained... For example:
|
||||
--
|
||||
-- local Vec3 = PointVec3:AddX( 100 ):AddZ( 150 ):GetVec3()
|
||||
--
|
||||
--
|
||||
-- ## 1.5) Smoke, flare, explode, illuminate
|
||||
--
|
||||
-- At the point a smoke, flare, explosion and illumination bomb can be triggered. Use the following methods:
|
||||
--
|
||||
-- ### 1.5.1) Smoke
|
||||
--
|
||||
-- * @{#POINT_VEC3.Smoke}(): To smoke the point in a certain color.
|
||||
-- * @{#POINT_VEC3.SmokeBlue}(): To smoke the point in blue.
|
||||
-- * @{#POINT_VEC3.SmokeRed}(): To smoke the point in red.
|
||||
-- * @{#POINT_VEC3.SmokeOrange}(): To smoke the point in orange.
|
||||
-- * @{#POINT_VEC3.SmokeWhite}(): To smoke the point in white.
|
||||
-- * @{#POINT_VEC3.SmokeGreen}(): To smoke the point in green.
|
||||
--
|
||||
-- ### 1.5.2) Flare
|
||||
--
|
||||
-- * @{#POINT_VEC3.Flare}(): To flare the point in a certain color.
|
||||
-- * @{#POINT_VEC3.FlareRed}(): To flare the point in red.
|
||||
-- * @{#POINT_VEC3.FlareYellow}(): To flare the point in yellow.
|
||||
-- * @{#POINT_VEC3.FlareWhite}(): To flare the point in white.
|
||||
-- * @{#POINT_VEC3.FlareGreen}(): To flare the point in green.
|
||||
--
|
||||
-- ### 1.5.3) Explode
|
||||
--
|
||||
-- * @{#POINT_VEC3.Explosion}(): To explode the point with a certain intensity.
|
||||
--
|
||||
-- ### 1.5.4) Illuminate
|
||||
--
|
||||
-- * @{#POINT_VEC3.IlluminationBomb}(): To illuminate the point.
|
||||
--
|
||||
--
|
||||
-- 2) @{Point#POINT_VEC2} class, extends @{Point#POINT_VEC3}
|
||||
-- =========================================================
|
||||
-- The @{Point#POINT_VEC2} class defines a 2D point in the simulator. The height coordinate (if needed) will be the land height + an optional added height specified.
|
||||
--
|
||||
-- 2.1) POINT_VEC2 constructor
|
||||
-- ---------------------------
|
||||
-- A new POINT_VEC2 instance can be created with:
|
||||
--
|
||||
-- * @{Point#POINT_VEC2.New}(): a 2D point, taking an additional height parameter.
|
||||
-- * @{Point#POINT_VEC2.NewFromVec2}(): a 2D point created from a @{DCSTypes#Vec2}.
|
||||
--
|
||||
-- ## 1.2) Manupulate the X, Altitude, Y coordinates of the 2D point
|
||||
--
|
||||
-- A POINT_VEC2 class works in 2D space, with an altitude setting. It contains internally an X, Altitude, Y coordinate.
|
||||
-- Methods exist to manupulate these coordinates.
|
||||
--
|
||||
-- The current X, Altitude, Y axis can be retrieved with the methods @{#POINT_VEC2.GetX}(), @{#POINT_VEC2.GetAlt}(), @{#POINT_VEC2.GetY}() respectively.
|
||||
-- The methods @{#POINT_VEC2.SetX}(), @{#POINT_VEC2.SetAlt}(), @{#POINT_VEC2.SetY}() change the respective axis with a new value.
|
||||
-- The current axis values can be changed by using the methods @{#POINT_VEC2.AddX}(), @{#POINT_VEC2.AddAlt}(), @{#POINT_VEC2.AddY}()
|
||||
-- to add or substract a value from the current respective axis value.
|
||||
-- Note that the Set and Add methods return the current POINT_VEC2 object, so these manipulation methods can be chained... For example:
|
||||
--
|
||||
-- local Vec2 = PointVec2:AddX( 100 ):AddY( 2000 ):GetVec2()
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- **API CHANGE HISTORY**
|
||||
-- ======================
|
||||
--
|
||||
-- The underlying change log documents the API changes. Please read this carefully. The following notation is used:
|
||||
--
|
||||
-- * **Added** parts are expressed in bold type face.
|
||||
-- * _Removed_ parts are expressed in italic type face.
|
||||
--
|
||||
-- Hereby the change log:
|
||||
--
|
||||
-- 2017-03-03: POINT\_VEC3:**Explosion( ExplosionIntensity )** added.
|
||||
-- 2017-03-03: POINT\_VEC3:**IlluminationBomb()** added.
|
||||
--
|
||||
-- 2017-02-18: POINT\_VEC3:**NewFromVec2( Vec2, LandHeightAdd )** added.
|
||||
--
|
||||
-- 2016-08-12: POINT\_VEC3:**Translate( Distance, Angle )** added.
|
||||
--
|
||||
-- 2016-08-06: Made PointVec3 and Vec3, PointVec2 and Vec2 terminology used in the code consistent.
|
||||
--
|
||||
-- * Replaced method _Point_Vec3() to **Vec3**() where the code manages a Vec3. Replaced all references to the method.
|
||||
-- * Replaced method _Point_Vec2() to **Vec2**() where the code manages a Vec2. Replaced all references to the method.
|
||||
-- * Replaced method Random_Point_Vec3() to **RandomVec3**() where the code manages a Vec3. Replaced all references to the method.
|
||||
-- .
|
||||
-- ===
|
||||
--
|
||||
-- ### Authors:
|
||||
--
|
||||
-- * FlightControl : Design & Programming
|
||||
--
|
||||
-- ### Contributions:
|
||||
--
|
||||
-- @module Point
|
||||
|
||||
--- The POINT_VEC3 class
|
||||
-- @type POINT_VEC3
|
||||
-- @extends Core.Base#BASE
|
||||
-- @field #number x The x coordinate in 3D space.
|
||||
-- @field #number y The y coordinate in 3D space.
|
||||
-- @field #number z The z coordiante in 3D space.
|
||||
-- @field Utilities.Utils#SMOKECOLOR SmokeColor
|
||||
-- @field Utilities.Utils#FLARECOLOR FlareColor
|
||||
-- @field #POINT_VEC3.RoutePointAltType RoutePointAltType
|
||||
-- @field #POINT_VEC3.RoutePointType RoutePointType
|
||||
-- @field #POINT_VEC3.RoutePointAction RoutePointAction
|
||||
POINT_VEC3 = {
|
||||
ClassName = "POINT_VEC3",
|
||||
Metric = true,
|
||||
RoutePointAltType = {
|
||||
BARO = "BARO",
|
||||
},
|
||||
RoutePointType = {
|
||||
TakeOffParking = "TakeOffParking",
|
||||
TurningPoint = "Turning Point",
|
||||
},
|
||||
RoutePointAction = {
|
||||
FromParkingArea = "From Parking Area",
|
||||
TurningPoint = "Turning Point",
|
||||
},
|
||||
}
|
||||
|
||||
--- The POINT_VEC2 class
|
||||
-- @type POINT_VEC2
|
||||
-- @extends #POINT_VEC3
|
||||
-- @field Dcs.DCSTypes#Distance x The x coordinate in meters.
|
||||
-- @field Dcs.DCSTypes#Distance y the y coordinate in meters.
|
||||
POINT_VEC2 = {
|
||||
ClassName = "POINT_VEC2",
|
||||
}
|
||||
|
||||
|
||||
do -- POINT_VEC3
|
||||
|
||||
--- RoutePoint AltTypes
|
||||
-- @type POINT_VEC3.RoutePointAltType
|
||||
-- @field BARO "BARO"
|
||||
|
||||
--- RoutePoint Types
|
||||
-- @type POINT_VEC3.RoutePointType
|
||||
-- @field TakeOffParking "TakeOffParking"
|
||||
-- @field TurningPoint "Turning Point"
|
||||
|
||||
--- RoutePoint Actions
|
||||
-- @type POINT_VEC3.RoutePointAction
|
||||
-- @field FromParkingArea "From Parking Area"
|
||||
-- @field TurningPoint "Turning Point"
|
||||
|
||||
-- Constructor.
|
||||
|
||||
--- Create a new POINT_VEC3 object.
|
||||
-- @param #POINT_VEC3 self
|
||||
-- @param Dcs.DCSTypes#Distance x The x coordinate of the Vec3 point, pointing to the North.
|
||||
-- @param Dcs.DCSTypes#Distance y The y coordinate of the Vec3 point, pointing Upwards.
|
||||
-- @param Dcs.DCSTypes#Distance z The z coordinate of the Vec3 point, pointing to the Right.
|
||||
-- @return Core.Point#POINT_VEC3 self
|
||||
function POINT_VEC3:New( x, y, z )
|
||||
|
||||
local self = BASE:Inherit( self, BASE:New() )
|
||||
self.x = x
|
||||
self.y = y
|
||||
self.z = z
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Create a new POINT_VEC3 object from Vec2 coordinates.
|
||||
-- @param #POINT_VEC3 self
|
||||
-- @param Dcs.DCSTypes#Vec2 Vec2 The Vec2 point.
|
||||
-- @return Core.Point#POINT_VEC3 self
|
||||
function POINT_VEC3:NewFromVec2( Vec2, LandHeightAdd )
|
||||
|
||||
local LandHeight = land.getHeight( Vec2 )
|
||||
|
||||
LandHeightAdd = LandHeightAdd or 0
|
||||
LandHeight = LandHeight + LandHeightAdd
|
||||
|
||||
self = self:New( Vec2.x, LandHeight, Vec2.y )
|
||||
|
||||
self:F2( self )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Create a new POINT_VEC3 object from Vec3 coordinates.
|
||||
-- @param #POINT_VEC3 self
|
||||
-- @param Dcs.DCSTypes#Vec3 Vec3 The Vec3 point.
|
||||
-- @return Core.Point#POINT_VEC3 self
|
||||
function POINT_VEC3:NewFromVec3( Vec3 )
|
||||
|
||||
self = self:New( Vec3.x, Vec3.y, Vec3.z )
|
||||
self:F2( self )
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
--- Return the coordinates of the POINT_VEC3 in Vec3 format.
|
||||
-- @param #POINT_VEC3 self
|
||||
-- @return Dcs.DCSTypes#Vec3 The Vec3 coodinate.
|
||||
function POINT_VEC3:GetVec3()
|
||||
return { x = self.x, y = self.y, z = self.z }
|
||||
end
|
||||
|
||||
--- Return the coordinates of the POINT_VEC3 in Vec2 format.
|
||||
-- @param #POINT_VEC3 self
|
||||
-- @return Dcs.DCSTypes#Vec2 The Vec2 coodinate.
|
||||
function POINT_VEC3:GetVec2()
|
||||
return { x = self.x, y = self.z }
|
||||
end
|
||||
|
||||
|
||||
--- Return the x coordinate of the POINT_VEC3.
|
||||
-- @param #POINT_VEC3 self
|
||||
-- @return #number The x coodinate.
|
||||
function POINT_VEC3:GetX()
|
||||
return self.x
|
||||
end
|
||||
|
||||
--- Return the y coordinate of the POINT_VEC3.
|
||||
-- @param #POINT_VEC3 self
|
||||
-- @return #number The y coodinate.
|
||||
function POINT_VEC3:GetY()
|
||||
return self.y
|
||||
end
|
||||
|
||||
--- Return the z coordinate of the POINT_VEC3.
|
||||
-- @param #POINT_VEC3 self
|
||||
-- @return #number The z coodinate.
|
||||
function POINT_VEC3:GetZ()
|
||||
return self.z
|
||||
end
|
||||
|
||||
--- Set the x coordinate of the POINT_VEC3.
|
||||
-- @param #POINT_VEC3 self
|
||||
-- @param #number x The x coordinate.
|
||||
-- @return #POINT_VEC3
|
||||
function POINT_VEC3:SetX( x )
|
||||
self.x = x
|
||||
return self
|
||||
end
|
||||
|
||||
--- Set the y coordinate of the POINT_VEC3.
|
||||
-- @param #POINT_VEC3 self
|
||||
-- @param #number y The y coordinate.
|
||||
-- @return #POINT_VEC3
|
||||
function POINT_VEC3:SetY( y )
|
||||
self.y = y
|
||||
return self
|
||||
end
|
||||
|
||||
--- Set the z coordinate of the POINT_VEC3.
|
||||
-- @param #POINT_VEC3 self
|
||||
-- @param #number z The z coordinate.
|
||||
-- @return #POINT_VEC3
|
||||
function POINT_VEC3:SetZ( z )
|
||||
self.z = z
|
||||
return self
|
||||
end
|
||||
|
||||
--- Add to the x coordinate of the POINT_VEC3.
|
||||
-- @param #POINT_VEC3 self
|
||||
-- @param #number x The x coordinate value to add to the current x coodinate.
|
||||
-- @return #POINT_VEC3
|
||||
function POINT_VEC3:AddX( x )
|
||||
self.x = self.x + x
|
||||
return self
|
||||
end
|
||||
|
||||
--- Add to the y coordinate of the POINT_VEC3.
|
||||
-- @param #POINT_VEC3 self
|
||||
-- @param #number y The y coordinate value to add to the current y coodinate.
|
||||
-- @return #POINT_VEC3
|
||||
function POINT_VEC3:AddY( y )
|
||||
self.y = self.y + y
|
||||
return self
|
||||
end
|
||||
|
||||
--- Add to the z coordinate of the POINT_VEC3.
|
||||
-- @param #POINT_VEC3 self
|
||||
-- @param #number z The z coordinate value to add to the current z coodinate.
|
||||
-- @return #POINT_VEC3
|
||||
function POINT_VEC3:AddZ( z )
|
||||
self.z = self.z +z
|
||||
return self
|
||||
end
|
||||
|
||||
--- Return a random Vec2 within an Outer Radius and optionally NOT within an Inner Radius of the POINT_VEC3.
|
||||
-- @param #POINT_VEC3 self
|
||||
-- @param Dcs.DCSTypes#Distance OuterRadius
|
||||
-- @param Dcs.DCSTypes#Distance InnerRadius
|
||||
-- @return Dcs.DCSTypes#Vec2 Vec2
|
||||
function POINT_VEC3:GetRandomVec2InRadius( OuterRadius, InnerRadius )
|
||||
self:F2( { OuterRadius, InnerRadius } )
|
||||
|
||||
local Theta = 2 * math.pi * math.random()
|
||||
local Radials = math.random() + math.random()
|
||||
if Radials > 1 then
|
||||
Radials = 2 - Radials
|
||||
end
|
||||
|
||||
local RadialMultiplier
|
||||
if InnerRadius and InnerRadius <= OuterRadius then
|
||||
RadialMultiplier = ( OuterRadius - InnerRadius ) * Radials + InnerRadius
|
||||
else
|
||||
RadialMultiplier = OuterRadius * Radials
|
||||
end
|
||||
|
||||
local RandomVec2
|
||||
if OuterRadius > 0 then
|
||||
RandomVec2 = { x = math.cos( Theta ) * RadialMultiplier + self:GetX(), y = math.sin( Theta ) * RadialMultiplier + self:GetZ() }
|
||||
else
|
||||
RandomVec2 = { x = self:GetX(), y = self:GetZ() }
|
||||
end
|
||||
|
||||
return RandomVec2
|
||||
end
|
||||
|
||||
--- Return a random POINT_VEC2 within an Outer Radius and optionally NOT within an Inner Radius of the POINT_VEC3.
|
||||
-- @param #POINT_VEC3 self
|
||||
-- @param Dcs.DCSTypes#Distance OuterRadius
|
||||
-- @param Dcs.DCSTypes#Distance InnerRadius
|
||||
-- @return #POINT_VEC2
|
||||
function POINT_VEC3:GetRandomPointVec2InRadius( OuterRadius, InnerRadius )
|
||||
self:F2( { OuterRadius, InnerRadius } )
|
||||
|
||||
return POINT_VEC2:NewFromVec2( self:GetRandomVec2InRadius( OuterRadius, InnerRadius ) )
|
||||
end
|
||||
|
||||
--- Return a random Vec3 within an Outer Radius and optionally NOT within an Inner Radius of the POINT_VEC3.
|
||||
-- @param #POINT_VEC3 self
|
||||
-- @param Dcs.DCSTypes#Distance OuterRadius
|
||||
-- @param Dcs.DCSTypes#Distance InnerRadius
|
||||
-- @return Dcs.DCSTypes#Vec3 Vec3
|
||||
function POINT_VEC3:GetRandomVec3InRadius( OuterRadius, InnerRadius )
|
||||
|
||||
local RandomVec2 = self:GetRandomVec2InRadius( OuterRadius, InnerRadius )
|
||||
local y = self:GetY() + math.random( InnerRadius, OuterRadius )
|
||||
local RandomVec3 = { x = RandomVec2.x, y = y, z = RandomVec2.z }
|
||||
|
||||
return RandomVec3
|
||||
end
|
||||
|
||||
--- Return a random POINT_VEC3 within an Outer Radius and optionally NOT within an Inner Radius of the POINT_VEC3.
|
||||
-- @param #POINT_VEC3 self
|
||||
-- @param Dcs.DCSTypes#Distance OuterRadius
|
||||
-- @param Dcs.DCSTypes#Distance InnerRadius
|
||||
-- @return #POINT_VEC3
|
||||
function POINT_VEC3:GetRandomPointVec3InRadius( OuterRadius, InnerRadius )
|
||||
|
||||
return POINT_VEC3:NewFromVec3( self:GetRandomVec3InRadius( OuterRadius, InnerRadius ) )
|
||||
end
|
||||
|
||||
|
||||
--- Return a direction vector Vec3 from POINT_VEC3 to the POINT_VEC3.
|
||||
-- @param #POINT_VEC3 self
|
||||
-- @param #POINT_VEC3 TargetPointVec3 The target POINT_VEC3.
|
||||
-- @return Dcs.DCSTypes#Vec3 DirectionVec3 The direction vector in Vec3 format.
|
||||
function POINT_VEC3:GetDirectionVec3( TargetPointVec3 )
|
||||
return { x = TargetPointVec3:GetX() - self:GetX(), y = TargetPointVec3:GetY() - self:GetY(), z = TargetPointVec3:GetZ() - self:GetZ() }
|
||||
end
|
||||
|
||||
--- Get a correction in radians of the real magnetic north of the POINT_VEC3.
|
||||
-- @param #POINT_VEC3 self
|
||||
-- @return #number CorrectionRadians The correction in radians.
|
||||
function POINT_VEC3:GetNorthCorrectionRadians()
|
||||
local TargetVec3 = self:GetVec3()
|
||||
local lat, lon = coord.LOtoLL(TargetVec3)
|
||||
local north_posit = coord.LLtoLO(lat + 1, lon)
|
||||
return math.atan2( north_posit.z - TargetVec3.z, north_posit.x - TargetVec3.x )
|
||||
end
|
||||
|
||||
|
||||
--- Return a direction in radians from the POINT_VEC3 using a direction vector in Vec3 format.
|
||||
-- @param #POINT_VEC3 self
|
||||
-- @param Dcs.DCSTypes#Vec3 DirectionVec3 The direction vector in Vec3 format.
|
||||
-- @return #number DirectionRadians The direction in radians.
|
||||
function POINT_VEC3:GetDirectionRadians( DirectionVec3 )
|
||||
local DirectionRadians = math.atan2( DirectionVec3.z, DirectionVec3.x )
|
||||
--DirectionRadians = DirectionRadians + self:GetNorthCorrectionRadians()
|
||||
if DirectionRadians < 0 then
|
||||
DirectionRadians = DirectionRadians + 2 * math.pi -- put dir in range of 0 to 2*pi ( the full circle )
|
||||
end
|
||||
return DirectionRadians
|
||||
end
|
||||
|
||||
--- Return the 2D distance in meters between the target POINT_VEC3 and the POINT_VEC3.
|
||||
-- @param #POINT_VEC3 self
|
||||
-- @param #POINT_VEC3 TargetPointVec3 The target POINT_VEC3.
|
||||
-- @return Dcs.DCSTypes#Distance Distance The distance in meters.
|
||||
function POINT_VEC3:Get2DDistance( TargetPointVec3 )
|
||||
local TargetVec3 = TargetPointVec3:GetVec3()
|
||||
local SourceVec3 = self:GetVec3()
|
||||
return ( ( TargetVec3.x - SourceVec3.x ) ^ 2 + ( TargetVec3.z - SourceVec3.z ) ^ 2 ) ^ 0.5
|
||||
end
|
||||
|
||||
--- Return the 3D distance in meters between the target POINT_VEC3 and the POINT_VEC3.
|
||||
-- @param #POINT_VEC3 self
|
||||
-- @param #POINT_VEC3 TargetPointVec3 The target POINT_VEC3.
|
||||
-- @return Dcs.DCSTypes#Distance Distance The distance in meters.
|
||||
function POINT_VEC3:Get3DDistance( TargetPointVec3 )
|
||||
local TargetVec3 = TargetPointVec3:GetVec3()
|
||||
local SourceVec3 = self:GetVec3()
|
||||
return ( ( TargetVec3.x - SourceVec3.x ) ^ 2 + ( TargetVec3.y - SourceVec3.y ) ^ 2 + ( TargetVec3.z - SourceVec3.z ) ^ 2 ) ^ 0.5
|
||||
end
|
||||
|
||||
--- Provides a Bearing / Range string
|
||||
-- @param #POINT_VEC3 self
|
||||
-- @param #number AngleRadians The angle in randians
|
||||
-- @param #number Distance The distance
|
||||
-- @return #string The BR Text
|
||||
function POINT_VEC3:ToStringBR( AngleRadians, Distance )
|
||||
|
||||
AngleRadians = UTILS.Round( UTILS.ToDegree( AngleRadians ), 0 )
|
||||
if self:IsMetric() then
|
||||
Distance = UTILS.Round( Distance / 1000, 2 )
|
||||
else
|
||||
Distance = UTILS.Round( UTILS.MetersToNM( Distance ), 2 )
|
||||
end
|
||||
|
||||
local s = string.format( '%03d', AngleRadians ) .. ' for ' .. Distance
|
||||
|
||||
s = s .. self:GetAltitudeText() -- When the POINT is a VEC2, there will be no altitude shown.
|
||||
|
||||
return s
|
||||
end
|
||||
|
||||
--- Provides a Bearing / Range string
|
||||
-- @param #POINT_VEC3 self
|
||||
-- @param #number AngleRadians The angle in randians
|
||||
-- @param #number Distance The distance
|
||||
-- @return #string The BR Text
|
||||
function POINT_VEC3:ToStringLL( acc, DMS )
|
||||
|
||||
acc = acc or 3
|
||||
local lat, lon = coord.LOtoLL( self:GetVec3() )
|
||||
return UTILS.tostringLL(lat, lon, acc, DMS)
|
||||
end
|
||||
|
||||
--- Return the altitude text of the POINT_VEC3.
|
||||
-- @param #POINT_VEC3 self
|
||||
-- @return #string Altitude text.
|
||||
function POINT_VEC3:GetAltitudeText()
|
||||
if self:IsMetric() then
|
||||
return ' at ' .. UTILS.Round( self:GetY(), 0 )
|
||||
else
|
||||
return ' at ' .. UTILS.Round( UTILS.MetersToFeet( self:GetY() ), 0 )
|
||||
end
|
||||
end
|
||||
|
||||
--- Return a BR string from a POINT_VEC3 to the POINT_VEC3.
|
||||
-- @param #POINT_VEC3 self
|
||||
-- @param #POINT_VEC3 TargetPointVec3 The target POINT_VEC3.
|
||||
-- @return #string The BR text.
|
||||
function POINT_VEC3:GetBRText( TargetPointVec3 )
|
||||
local DirectionVec3 = self:GetDirectionVec3( TargetPointVec3 )
|
||||
local AngleRadians = self:GetDirectionRadians( DirectionVec3 )
|
||||
local Distance = self:Get2DDistance( TargetPointVec3 )
|
||||
return self:ToStringBR( AngleRadians, Distance )
|
||||
end
|
||||
|
||||
--- Sets the POINT_VEC3 metric or NM.
|
||||
-- @param #POINT_VEC3 self
|
||||
-- @param #boolean Metric true means metric, false means NM.
|
||||
function POINT_VEC3:SetMetric( Metric )
|
||||
self.Metric = Metric
|
||||
end
|
||||
|
||||
--- Gets if the POINT_VEC3 is metric or NM.
|
||||
-- @param #POINT_VEC3 self
|
||||
-- @return #boolean Metric true means metric, false means NM.
|
||||
function POINT_VEC3:IsMetric()
|
||||
return self.Metric
|
||||
end
|
||||
|
||||
--- Add a Distance in meters from the POINT_VEC3 horizontal plane, with the given angle, and calculate the new POINT_VEC3.
|
||||
-- @param #POINT_VEC3 self
|
||||
-- @param Dcs.DCSTypes#Distance Distance The Distance to be added in meters.
|
||||
-- @param Dcs.DCSTypes#Angle Angle The Angle in degrees.
|
||||
-- @return #POINT_VEC3 The new calculated POINT_VEC3.
|
||||
function POINT_VEC3:Translate( Distance, Angle )
|
||||
local SX = self:GetX()
|
||||
local SZ = self:GetZ()
|
||||
local Radians = Angle / 180 * math.pi
|
||||
local TX = Distance * math.cos( Radians ) + SX
|
||||
local TZ = Distance * math.sin( Radians ) + SZ
|
||||
|
||||
return POINT_VEC3:New( TX, self:GetY(), TZ )
|
||||
end
|
||||
|
||||
|
||||
|
||||
--- Build an air type route point.
|
||||
-- @param #POINT_VEC3 self
|
||||
-- @param #POINT_VEC3.RoutePointAltType AltType The altitude type.
|
||||
-- @param #POINT_VEC3.RoutePointType Type The route point type.
|
||||
-- @param #POINT_VEC3.RoutePointAction Action The route point action.
|
||||
-- @param Dcs.DCSTypes#Speed Speed Airspeed in km/h.
|
||||
-- @param #boolean SpeedLocked true means the speed is locked.
|
||||
-- @return #table The route point.
|
||||
function POINT_VEC3:RoutePointAir( AltType, Type, Action, Speed, SpeedLocked )
|
||||
self:F2( { AltType, Type, Action, Speed, SpeedLocked } )
|
||||
|
||||
local RoutePoint = {}
|
||||
RoutePoint.x = self:GetX()
|
||||
RoutePoint.y = self:GetZ()
|
||||
RoutePoint.alt = self:GetY()
|
||||
RoutePoint.alt_type = AltType
|
||||
|
||||
RoutePoint.type = Type
|
||||
RoutePoint.action = Action
|
||||
|
||||
RoutePoint.speed = Speed / 3.6
|
||||
RoutePoint.speed_locked = true
|
||||
|
||||
-- ["task"] =
|
||||
-- {
|
||||
-- ["id"] = "ComboTask",
|
||||
-- ["params"] =
|
||||
-- {
|
||||
-- ["tasks"] =
|
||||
-- {
|
||||
-- }, -- end of ["tasks"]
|
||||
-- }, -- end of ["params"]
|
||||
-- }, -- end of ["task"]
|
||||
|
||||
|
||||
RoutePoint.task = {}
|
||||
RoutePoint.task.id = "ComboTask"
|
||||
RoutePoint.task.params = {}
|
||||
RoutePoint.task.params.tasks = {}
|
||||
|
||||
|
||||
return RoutePoint
|
||||
end
|
||||
|
||||
--- Build an ground type route point.
|
||||
-- @param #POINT_VEC3 self
|
||||
-- @param Dcs.DCSTypes#Speed Speed Speed in km/h.
|
||||
-- @param #POINT_VEC3.RoutePointAction Formation The route point Formation.
|
||||
-- @return #table The route point.
|
||||
function POINT_VEC3:RoutePointGround( Speed, Formation )
|
||||
self:F2( { Formation, Speed } )
|
||||
|
||||
local RoutePoint = {}
|
||||
RoutePoint.x = self:GetX()
|
||||
RoutePoint.y = self:GetZ()
|
||||
|
||||
RoutePoint.action = Formation or ""
|
||||
|
||||
|
||||
RoutePoint.speed = Speed / 3.6
|
||||
RoutePoint.speed_locked = true
|
||||
|
||||
-- ["task"] =
|
||||
-- {
|
||||
-- ["id"] = "ComboTask",
|
||||
-- ["params"] =
|
||||
-- {
|
||||
-- ["tasks"] =
|
||||
-- {
|
||||
-- }, -- end of ["tasks"]
|
||||
-- }, -- end of ["params"]
|
||||
-- }, -- end of ["task"]
|
||||
|
||||
|
||||
RoutePoint.task = {}
|
||||
RoutePoint.task.id = "ComboTask"
|
||||
RoutePoint.task.params = {}
|
||||
RoutePoint.task.params.tasks = {}
|
||||
|
||||
|
||||
return RoutePoint
|
||||
end
|
||||
|
||||
--- Creates an explosion at the point of a certain intensity.
|
||||
-- @param #POINT_VEC3 self
|
||||
-- @param #number ExplosionIntensity
|
||||
function POINT_VEC3:Explosion( ExplosionIntensity )
|
||||
self:F2( { ExplosionIntensity } )
|
||||
trigger.action.explosion( self:GetVec3(), ExplosionIntensity )
|
||||
end
|
||||
|
||||
--- Creates an illumination bomb at the point.
|
||||
-- @param #POINT_VEC3 self
|
||||
function POINT_VEC3:IlluminationBomb()
|
||||
self:F2()
|
||||
trigger.action.illuminationBomb( self:GetVec3() )
|
||||
end
|
||||
|
||||
|
||||
--- Smokes the point in a color.
|
||||
-- @param #POINT_VEC3 self
|
||||
-- @param Utilities.Utils#SMOKECOLOR SmokeColor
|
||||
function POINT_VEC3:Smoke( SmokeColor )
|
||||
self:F2( { SmokeColor } )
|
||||
trigger.action.smoke( self:GetVec3(), SmokeColor )
|
||||
end
|
||||
|
||||
--- Smoke the POINT_VEC3 Green.
|
||||
-- @param #POINT_VEC3 self
|
||||
function POINT_VEC3:SmokeGreen()
|
||||
self:F2()
|
||||
self:Smoke( SMOKECOLOR.Green )
|
||||
end
|
||||
|
||||
--- Smoke the POINT_VEC3 Red.
|
||||
-- @param #POINT_VEC3 self
|
||||
function POINT_VEC3:SmokeRed()
|
||||
self:F2()
|
||||
self:Smoke( SMOKECOLOR.Red )
|
||||
end
|
||||
|
||||
--- Smoke the POINT_VEC3 White.
|
||||
-- @param #POINT_VEC3 self
|
||||
function POINT_VEC3:SmokeWhite()
|
||||
self:F2()
|
||||
self:Smoke( SMOKECOLOR.White )
|
||||
end
|
||||
|
||||
--- Smoke the POINT_VEC3 Orange.
|
||||
-- @param #POINT_VEC3 self
|
||||
function POINT_VEC3:SmokeOrange()
|
||||
self:F2()
|
||||
self:Smoke( SMOKECOLOR.Orange )
|
||||
end
|
||||
|
||||
--- Smoke the POINT_VEC3 Blue.
|
||||
-- @param #POINT_VEC3 self
|
||||
function POINT_VEC3:SmokeBlue()
|
||||
self:F2()
|
||||
self:Smoke( SMOKECOLOR.Blue )
|
||||
end
|
||||
|
||||
--- Flares the point in a color.
|
||||
-- @param #POINT_VEC3 self
|
||||
-- @param Utilities.Utils#FLARECOLOR FlareColor
|
||||
-- @param Dcs.DCSTypes#Azimuth (optional) Azimuth The azimuth of the flare direction. The default azimuth is 0.
|
||||
function POINT_VEC3:Flare( FlareColor, Azimuth )
|
||||
self:F2( { FlareColor } )
|
||||
trigger.action.signalFlare( self:GetVec3(), FlareColor, Azimuth and Azimuth or 0 )
|
||||
end
|
||||
|
||||
--- Flare the POINT_VEC3 White.
|
||||
-- @param #POINT_VEC3 self
|
||||
-- @param Dcs.DCSTypes#Azimuth (optional) Azimuth The azimuth of the flare direction. The default azimuth is 0.
|
||||
function POINT_VEC3:FlareWhite( Azimuth )
|
||||
self:F2( Azimuth )
|
||||
self:Flare( FLARECOLOR.White, Azimuth )
|
||||
end
|
||||
|
||||
--- Flare the POINT_VEC3 Yellow.
|
||||
-- @param #POINT_VEC3 self
|
||||
-- @param Dcs.DCSTypes#Azimuth (optional) Azimuth The azimuth of the flare direction. The default azimuth is 0.
|
||||
function POINT_VEC3:FlareYellow( Azimuth )
|
||||
self:F2( Azimuth )
|
||||
self:Flare( FLARECOLOR.Yellow, Azimuth )
|
||||
end
|
||||
|
||||
--- Flare the POINT_VEC3 Green.
|
||||
-- @param #POINT_VEC3 self
|
||||
-- @param Dcs.DCSTypes#Azimuth (optional) Azimuth The azimuth of the flare direction. The default azimuth is 0.
|
||||
function POINT_VEC3:FlareGreen( Azimuth )
|
||||
self:F2( Azimuth )
|
||||
self:Flare( FLARECOLOR.Green, Azimuth )
|
||||
end
|
||||
|
||||
--- Flare the POINT_VEC3 Red.
|
||||
-- @param #POINT_VEC3 self
|
||||
function POINT_VEC3:FlareRed( Azimuth )
|
||||
self:F2( Azimuth )
|
||||
self:Flare( FLARECOLOR.Red, Azimuth )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
do -- POINT_VEC2
|
||||
|
||||
|
||||
|
||||
--- POINT_VEC2 constructor.
|
||||
-- @param #POINT_VEC2 self
|
||||
-- @param Dcs.DCSTypes#Distance x The x coordinate of the Vec3 point, pointing to the North.
|
||||
-- @param Dcs.DCSTypes#Distance y The y coordinate of the Vec3 point, pointing to the Right.
|
||||
-- @param Dcs.DCSTypes#Distance LandHeightAdd (optional) The default height if required to be evaluated will be the land height of the x, y coordinate. You can specify an extra height to be added to the land height.
|
||||
-- @return Core.Point#POINT_VEC2
|
||||
function POINT_VEC2:New( x, y, LandHeightAdd )
|
||||
|
||||
local LandHeight = land.getHeight( { ["x"] = x, ["y"] = y } )
|
||||
|
||||
LandHeightAdd = LandHeightAdd or 0
|
||||
LandHeight = LandHeight + LandHeightAdd
|
||||
|
||||
self = BASE:Inherit( self, POINT_VEC3:New( x, LandHeight, y ) )
|
||||
self:F2( self )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Create a new POINT_VEC2 object from Vec2 coordinates.
|
||||
-- @param #POINT_VEC2 self
|
||||
-- @param Dcs.DCSTypes#Vec2 Vec2 The Vec2 point.
|
||||
-- @return Core.Point#POINT_VEC2 self
|
||||
function POINT_VEC2:NewFromVec2( Vec2, LandHeightAdd )
|
||||
|
||||
local LandHeight = land.getHeight( Vec2 )
|
||||
|
||||
LandHeightAdd = LandHeightAdd or 0
|
||||
LandHeight = LandHeight + LandHeightAdd
|
||||
|
||||
self = BASE:Inherit( self, POINT_VEC3:New( Vec2.x, LandHeight, Vec2.y ) )
|
||||
self:F2( self )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Create a new POINT_VEC2 object from Vec3 coordinates.
|
||||
-- @param #POINT_VEC2 self
|
||||
-- @param Dcs.DCSTypes#Vec3 Vec3 The Vec3 point.
|
||||
-- @return Core.Point#POINT_VEC2 self
|
||||
function POINT_VEC2:NewFromVec3( Vec3 )
|
||||
|
||||
local self = BASE:Inherit( self, BASE:New() )
|
||||
local Vec2 = { x = Vec3.x, y = Vec3.z }
|
||||
|
||||
local LandHeight = land.getHeight( Vec2 )
|
||||
|
||||
self = BASE:Inherit( self, POINT_VEC3:New( Vec2.x, LandHeight, Vec2.y ) )
|
||||
self:F2( self )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Return the x coordinate of the POINT_VEC2.
|
||||
-- @param #POINT_VEC2 self
|
||||
-- @return #number The x coodinate.
|
||||
function POINT_VEC2:GetX()
|
||||
return self.x
|
||||
end
|
||||
|
||||
--- Return the y coordinate of the POINT_VEC2.
|
||||
-- @param #POINT_VEC2 self
|
||||
-- @return #number The y coodinate.
|
||||
function POINT_VEC2:GetY()
|
||||
return self.z
|
||||
end
|
||||
|
||||
--- Return the altitude of the land at the POINT_VEC2.
|
||||
-- @param #POINT_VEC2 self
|
||||
-- @return #number The land altitude.
|
||||
function POINT_VEC2:GetAlt()
|
||||
return land.getHeight( { x = self.x, y = self.z } )
|
||||
end
|
||||
|
||||
--- Set the x coordinate of the POINT_VEC2.
|
||||
-- @param #POINT_VEC2 self
|
||||
-- @param #number x The x coordinate.
|
||||
-- @return #POINT_VEC2
|
||||
function POINT_VEC2:SetX( x )
|
||||
self.x = x
|
||||
return self
|
||||
end
|
||||
|
||||
--- Set the y coordinate of the POINT_VEC2.
|
||||
-- @param #POINT_VEC2 self
|
||||
-- @param #number y The y coordinate.
|
||||
-- @return #POINT_VEC2
|
||||
function POINT_VEC2:SetY( y )
|
||||
self.z = y
|
||||
return self
|
||||
end
|
||||
|
||||
--- Set the altitude of the POINT_VEC2.
|
||||
-- @param #POINT_VEC2 self
|
||||
-- @param #number Altitude The land altitude. If nothing (nil) is given, then the current land altitude is set.
|
||||
-- @return #POINT_VEC2
|
||||
function POINT_VEC2:SetAlt( Altitude )
|
||||
self.y = Altitude or land.getHeight( { x = self.x, y = self.z } )
|
||||
return self
|
||||
end
|
||||
|
||||
--- Add to the x coordinate of the POINT_VEC2.
|
||||
-- @param #POINT_VEC2 self
|
||||
-- @param #number x The x coordinate.
|
||||
-- @return #POINT_VEC2
|
||||
function POINT_VEC2:AddX( x )
|
||||
self.x = self.x + x
|
||||
return self
|
||||
end
|
||||
|
||||
--- Add to the y coordinate of the POINT_VEC2.
|
||||
-- @param #POINT_VEC2 self
|
||||
-- @param #number y The y coordinate.
|
||||
-- @return #POINT_VEC2
|
||||
function POINT_VEC2:AddY( y )
|
||||
self.z = self.z + y
|
||||
return self
|
||||
end
|
||||
|
||||
--- Add to the current land height an altitude.
|
||||
-- @param #POINT_VEC2 self
|
||||
-- @param #number Altitude The Altitude to add. If nothing (nil) is given, then the current land altitude is set.
|
||||
-- @return #POINT_VEC2
|
||||
function POINT_VEC2:AddAlt( Altitude )
|
||||
self.y = land.getHeight( { x = self.x, y = self.z } ) + Altitude or 0
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
|
||||
--- Calculate the distance from a reference @{#POINT_VEC2}.
|
||||
-- @param #POINT_VEC2 self
|
||||
-- @param #POINT_VEC2 PointVec2Reference The reference @{#POINT_VEC2}.
|
||||
-- @return Dcs.DCSTypes#Distance The distance from the reference @{#POINT_VEC2} in meters.
|
||||
function POINT_VEC2:DistanceFromPointVec2( PointVec2Reference )
|
||||
self:F2( PointVec2Reference )
|
||||
|
||||
local Distance = ( ( PointVec2Reference:GetX() - self:GetX() ) ^ 2 + ( PointVec2Reference:GetY() - self:GetY() ) ^2 ) ^0.5
|
||||
|
||||
self:T2( Distance )
|
||||
return Distance
|
||||
end
|
||||
|
||||
--- Calculate the distance from a reference @{DCSTypes#Vec2}.
|
||||
-- @param #POINT_VEC2 self
|
||||
-- @param Dcs.DCSTypes#Vec2 Vec2Reference The reference @{DCSTypes#Vec2}.
|
||||
-- @return Dcs.DCSTypes#Distance The distance from the reference @{DCSTypes#Vec2} in meters.
|
||||
function POINT_VEC2:DistanceFromVec2( Vec2Reference )
|
||||
self:F2( Vec2Reference )
|
||||
|
||||
local Distance = ( ( Vec2Reference.x - self:GetX() ) ^ 2 + ( Vec2Reference.y - self:GetY() ) ^2 ) ^0.5
|
||||
|
||||
self:T2( Distance )
|
||||
return Distance
|
||||
end
|
||||
|
||||
|
||||
--- Return no text for the altitude of the POINT_VEC2.
|
||||
-- @param #POINT_VEC2 self
|
||||
-- @return #string Empty string.
|
||||
function POINT_VEC2:GetAltitudeText()
|
||||
return ''
|
||||
end
|
||||
|
||||
--- Add a Distance in meters from the POINT_VEC2 orthonormal plane, with the given angle, and calculate the new POINT_VEC2.
|
||||
-- @param #POINT_VEC2 self
|
||||
-- @param Dcs.DCSTypes#Distance Distance The Distance to be added in meters.
|
||||
-- @param Dcs.DCSTypes#Angle Angle The Angle in degrees.
|
||||
-- @return #POINT_VEC2 The new calculated POINT_VEC2.
|
||||
function POINT_VEC2:Translate( Distance, Angle )
|
||||
local SX = self:GetX()
|
||||
local SY = self:GetY()
|
||||
local Radians = Angle / 180 * math.pi
|
||||
local TX = Distance * math.cos( Radians ) + SX
|
||||
local TY = Distance * math.sin( Radians ) + SY
|
||||
|
||||
return POINT_VEC2:New( TX, TY )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
210
Moose Development/Moose/Core/ScheduleDispatcher.lua
Normal file
210
Moose Development/Moose/Core/ScheduleDispatcher.lua
Normal file
@@ -0,0 +1,210 @@
|
||||
--- This module defines the SCHEDULEDISPATCHER class, which is used by a central object called _SCHEDULEDISPATCHER.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- Takes care of the creation and dispatching of scheduled functions for SCHEDULER objects.
|
||||
--
|
||||
-- This class is tricky and needs some thorought explanation.
|
||||
-- SCHEDULE classes are used to schedule functions for objects, or as persistent objects.
|
||||
-- The SCHEDULEDISPATCHER class ensures that:
|
||||
--
|
||||
-- - Scheduled functions are planned according the SCHEDULER object parameters.
|
||||
-- - Scheduled functions are repeated when requested, according the SCHEDULER object parameters.
|
||||
-- - Scheduled functions are automatically removed when the schedule is finished, according the SCHEDULER object parameters.
|
||||
--
|
||||
-- The SCHEDULEDISPATCHER class will manage SCHEDULER object in memory during garbage collection:
|
||||
-- - When a SCHEDULER object is not attached to another object (that is, it's first :Schedule() parameter is nil), then the SCHEDULER
|
||||
-- object is _persistent_ within memory.
|
||||
-- - When a SCHEDULER object *is* attached to another object, then the SCHEDULER object is _not persistent_ within memory after a garbage collection!
|
||||
-- The none persistency of SCHEDULERS attached to objects is required to allow SCHEDULER objects to be garbage collectged, when the parent object is also desroyed or nillified and garbage collected.
|
||||
-- Even when there are pending timer scheduled functions to be executed for the SCHEDULER object,
|
||||
-- these will not be executed anymore when the SCHEDULER object has been destroyed.
|
||||
--
|
||||
-- The SCHEDULEDISPATCHER allows multiple scheduled functions to be planned and executed for one SCHEDULER object.
|
||||
-- The SCHEDULER object therefore keeps a table of "CallID's", which are returned after each planning of a new scheduled function by the SCHEDULEDISPATCHER.
|
||||
-- The SCHEDULER object plans new scheduled functions through the @{Scheduler#SCHEDULER.Schedule}() method.
|
||||
-- The Schedule() method returns the CallID that is the reference ID for each planned schedule.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- ### Contributions: -
|
||||
-- ### Authors: FlightControl : Design & Programming
|
||||
--
|
||||
-- @module ScheduleDispatcher
|
||||
|
||||
--- The SCHEDULEDISPATCHER structure
|
||||
-- @type SCHEDULEDISPATCHER
|
||||
SCHEDULEDISPATCHER = {
|
||||
ClassName = "SCHEDULEDISPATCHER",
|
||||
CallID = 0,
|
||||
}
|
||||
|
||||
function SCHEDULEDISPATCHER:New()
|
||||
local self = BASE:Inherit( self, BASE:New() )
|
||||
self:F3()
|
||||
return self
|
||||
end
|
||||
|
||||
--- Add a Schedule to the ScheduleDispatcher.
|
||||
-- The development of this method was really tidy.
|
||||
-- It is constructed as such that a garbage collection is executed on the weak tables, when the Scheduler is nillified.
|
||||
-- Nothing of this code should be modified without testing it thoroughly.
|
||||
-- @param #SCHEDULEDISPATCHER self
|
||||
-- @param Core.Scheduler#SCHEDULER Scheduler
|
||||
function SCHEDULEDISPATCHER:AddSchedule( Scheduler, ScheduleFunction, ScheduleArguments, Start, Repeat, Randomize, Stop )
|
||||
self:F2( { Scheduler, ScheduleFunction, ScheduleArguments, Start, Repeat, Randomize, Stop } )
|
||||
|
||||
self.CallID = self.CallID + 1
|
||||
|
||||
-- Initialize the ObjectSchedulers array, which is a weakly coupled table.
|
||||
-- If the object used as the key is nil, then the garbage collector will remove the item from the Functions array.
|
||||
self.PersistentSchedulers = self.PersistentSchedulers or {}
|
||||
|
||||
-- Initialize the ObjectSchedulers array, which is a weakly coupled table.
|
||||
-- If the object used as the key is nil, then the garbage collector will remove the item from the Functions array.
|
||||
self.ObjectSchedulers = self.ObjectSchedulers or {} -- setmetatable( {}, { __mode = "v" } )
|
||||
|
||||
if Scheduler.MasterObject then
|
||||
self.ObjectSchedulers[self.CallID] = Scheduler
|
||||
self:F3( { CallID = self.CallID, ObjectScheduler = tostring(self.ObjectSchedulers[self.CallID]), MasterObject = tostring(Scheduler.MasterObject) } )
|
||||
else
|
||||
self.PersistentSchedulers[self.CallID] = Scheduler
|
||||
self:F3( { CallID = self.CallID, PersistentScheduler = self.PersistentSchedulers[self.CallID] } )
|
||||
end
|
||||
|
||||
self.Schedule = self.Schedule or setmetatable( {}, { __mode = "k" } )
|
||||
self.Schedule[Scheduler] = self.Schedule[Scheduler] or {}
|
||||
self.Schedule[Scheduler][self.CallID] = {}
|
||||
self.Schedule[Scheduler][self.CallID].Function = ScheduleFunction
|
||||
self.Schedule[Scheduler][self.CallID].Arguments = ScheduleArguments
|
||||
self.Schedule[Scheduler][self.CallID].StartTime = timer.getTime() + ( Start or 0 )
|
||||
self.Schedule[Scheduler][self.CallID].Start = Start + .1
|
||||
self.Schedule[Scheduler][self.CallID].Repeat = Repeat
|
||||
self.Schedule[Scheduler][self.CallID].Randomize = Randomize
|
||||
self.Schedule[Scheduler][self.CallID].Stop = Stop
|
||||
|
||||
self:T3( self.Schedule[Scheduler][self.CallID] )
|
||||
|
||||
self.Schedule[Scheduler][self.CallID].CallHandler = function( CallID )
|
||||
self:F2( CallID )
|
||||
|
||||
local ErrorHandler = function( errmsg )
|
||||
env.info( "Error in timer function: " .. errmsg )
|
||||
if debug ~= nil then
|
||||
env.info( debug.traceback() )
|
||||
end
|
||||
return errmsg
|
||||
end
|
||||
|
||||
local Scheduler = self.ObjectSchedulers[CallID]
|
||||
if not Scheduler then
|
||||
Scheduler = self.PersistentSchedulers[CallID]
|
||||
end
|
||||
|
||||
self:T3( { Scheduler = Scheduler } )
|
||||
|
||||
if Scheduler then
|
||||
|
||||
local Schedule = self.Schedule[Scheduler][CallID]
|
||||
|
||||
self:T3( { Schedule = Schedule } )
|
||||
|
||||
local ScheduleObject = Scheduler.SchedulerObject
|
||||
--local ScheduleObjectName = Scheduler.SchedulerObject:GetNameAndClassID()
|
||||
local ScheduleFunction = Schedule.Function
|
||||
local ScheduleArguments = Schedule.Arguments
|
||||
local Start = Schedule.Start
|
||||
local Repeat = Schedule.Repeat or 0
|
||||
local Randomize = Schedule.Randomize or 0
|
||||
local Stop = Schedule.Stop or 0
|
||||
local ScheduleID = Schedule.ScheduleID
|
||||
|
||||
local Status, Result
|
||||
if ScheduleObject then
|
||||
local function Timer()
|
||||
return ScheduleFunction( ScheduleObject, unpack( ScheduleArguments ) )
|
||||
end
|
||||
Status, Result = xpcall( Timer, ErrorHandler )
|
||||
else
|
||||
local function Timer()
|
||||
return ScheduleFunction( unpack( ScheduleArguments ) )
|
||||
end
|
||||
Status, Result = xpcall( Timer, ErrorHandler )
|
||||
end
|
||||
|
||||
local CurrentTime = timer.getTime()
|
||||
local StartTime = CurrentTime + Start
|
||||
|
||||
if Status and (( Result == nil ) or ( Result and Result ~= false ) ) then
|
||||
if Repeat ~= 0 and ( Stop == 0 ) or ( Stop ~= 0 and CurrentTime <= StartTime + Stop ) then
|
||||
local ScheduleTime =
|
||||
CurrentTime +
|
||||
Repeat +
|
||||
math.random(
|
||||
- ( Randomize * Repeat / 2 ),
|
||||
( Randomize * Repeat / 2 )
|
||||
) +
|
||||
0.01
|
||||
self:T3( { Repeat = CallID, CurrentTime, ScheduleTime, ScheduleArguments } )
|
||||
return ScheduleTime -- returns the next time the function needs to be called.
|
||||
else
|
||||
self:Stop( Scheduler, CallID )
|
||||
end
|
||||
else
|
||||
self:Stop( Scheduler, CallID )
|
||||
end
|
||||
else
|
||||
self:E( "Scheduled obscolete call for CallID: " .. CallID )
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
self:Start( Scheduler, self.CallID )
|
||||
|
||||
return self.CallID
|
||||
end
|
||||
|
||||
function SCHEDULEDISPATCHER:RemoveSchedule( Scheduler, CallID )
|
||||
self:F2( { Remove = CallID, Scheduler = Scheduler } )
|
||||
|
||||
if CallID then
|
||||
self:Stop( Scheduler, CallID )
|
||||
self.Schedule[Scheduler][CallID] = nil
|
||||
end
|
||||
end
|
||||
|
||||
function SCHEDULEDISPATCHER:Start( Scheduler, CallID )
|
||||
self:F2( { Start = CallID, Scheduler = Scheduler } )
|
||||
|
||||
if CallID then
|
||||
local Schedule = self.Schedule[Scheduler]
|
||||
Schedule[CallID].ScheduleID = timer.scheduleFunction(
|
||||
Schedule[CallID].CallHandler,
|
||||
CallID,
|
||||
timer.getTime() + Schedule[CallID].Start
|
||||
)
|
||||
else
|
||||
for CallID, Schedule in pairs( self.Schedule[Scheduler] ) do
|
||||
self:Start( Scheduler, CallID ) -- Recursive
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function SCHEDULEDISPATCHER:Stop( Scheduler, CallID )
|
||||
self:F2( { Stop = CallID, Scheduler = Scheduler } )
|
||||
|
||||
if CallID then
|
||||
local Schedule = self.Schedule[Scheduler]
|
||||
timer.removeFunction( Schedule[CallID].ScheduleID )
|
||||
else
|
||||
for CallID, Schedule in pairs( self.Schedule[Scheduler] ) do
|
||||
self:Stop( Scheduler, CallID ) -- Recursive
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
163
Moose Development/Moose/Core/Scheduler.lua
Normal file
163
Moose Development/Moose/Core/Scheduler.lua
Normal file
@@ -0,0 +1,163 @@
|
||||
--- This module contains the SCHEDULER class.
|
||||
--
|
||||
-- # 1) @{Scheduler#SCHEDULER} class, extends @{Base#BASE}
|
||||
--
|
||||
-- The @{Scheduler#SCHEDULER} class creates schedule.
|
||||
--
|
||||
-- ## 1.1) SCHEDULER constructor
|
||||
--
|
||||
-- The SCHEDULER class is quite easy to use, but note that the New constructor has variable parameters:
|
||||
--
|
||||
-- * @{Scheduler#SCHEDULER.New}( nil ): Setup a new SCHEDULER object, which is persistently executed after garbage collection.
|
||||
-- * @{Scheduler#SCHEDULER.New}( Object ): Setup a new SCHEDULER object, which is linked to the Object. When the Object is nillified or destroyed, the SCHEDULER object will also be destroyed and stopped after garbage collection.
|
||||
-- * @{Scheduler#SCHEDULER.New}( nil, Function, FunctionArguments, Start, ... ): Setup a new persistent SCHEDULER object, and start a new schedule for the Function with the defined FunctionArguments according the Start and sequent parameters.
|
||||
-- * @{Scheduler#SCHEDULER.New}( Object, Function, FunctionArguments, Start, ... ): Setup a new SCHEDULER object, linked to Object, and start a new schedule for the Function with the defined FunctionArguments according the Start and sequent parameters.
|
||||
--
|
||||
-- ## 1.2) SCHEDULER timer stopping and (re-)starting.
|
||||
--
|
||||
-- The SCHEDULER can be stopped and restarted with the following methods:
|
||||
--
|
||||
-- * @{Scheduler#SCHEDULER.Start}(): (Re-)Start the schedules within the SCHEDULER object. If a CallID is provided to :Start(), only the schedule referenced by CallID will be (re-)started.
|
||||
-- * @{Scheduler#SCHEDULER.Stop}(): Stop the schedules within the SCHEDULER object. If a CallID is provided to :Stop(), then only the schedule referenced by CallID will be stopped.
|
||||
--
|
||||
-- ## 1.3) Create a new schedule
|
||||
--
|
||||
-- With @{Scheduler#SCHEDULER.Schedule}() a new time event can be scheduled. This function is used by the :New() constructor when a new schedule is planned.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- ### Contributions:
|
||||
--
|
||||
-- * FlightControl : Concept & Testing
|
||||
--
|
||||
-- ### Authors:
|
||||
--
|
||||
-- * FlightControl : Design & Programming
|
||||
--
|
||||
-- ### Test Missions:
|
||||
--
|
||||
-- * SCH - Scheduler
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- @module Scheduler
|
||||
|
||||
|
||||
--- The SCHEDULER class
|
||||
-- @type SCHEDULER
|
||||
-- @field #number ScheduleID the ID of the scheduler.
|
||||
-- @extends Core.Base#BASE
|
||||
SCHEDULER = {
|
||||
ClassName = "SCHEDULER",
|
||||
Schedules = {},
|
||||
}
|
||||
|
||||
--- SCHEDULER constructor.
|
||||
-- @param #SCHEDULER self
|
||||
-- @param #table SchedulerObject Specified for which Moose object the timer is setup. If a value of nil is provided, a scheduler will be setup without an object reference.
|
||||
-- @param #function SchedulerFunction The event function to be called when a timer event occurs. The event function needs to accept the parameters specified in SchedulerArguments.
|
||||
-- @param #table SchedulerArguments Optional arguments that can be given as part of scheduler. The arguments need to be given as a table { param1, param 2, ... }.
|
||||
-- @param #number Start Specifies the amount of seconds that will be waited before the scheduling is started, and the event function is called.
|
||||
-- @param #number Repeat Specifies the interval in seconds when the scheduler will call the event function.
|
||||
-- @param #number RandomizeFactor Specifies a randomization factor between 0 and 1 to randomize the Repeat.
|
||||
-- @param #number Stop Specifies the amount of seconds when the scheduler will be stopped.
|
||||
-- @return #SCHEDULER self.
|
||||
-- @return #number The ScheduleID of the planned schedule.
|
||||
function SCHEDULER:New( SchedulerObject, SchedulerFunction, SchedulerArguments, Start, Repeat, RandomizeFactor, Stop )
|
||||
local self = BASE:Inherit( self, BASE:New() )
|
||||
self:F2( { Start, Repeat, RandomizeFactor, Stop } )
|
||||
|
||||
local ScheduleID = nil
|
||||
|
||||
self.MasterObject = SchedulerObject
|
||||
|
||||
if SchedulerFunction then
|
||||
ScheduleID = self:Schedule( SchedulerObject, SchedulerFunction, SchedulerArguments, Start, Repeat, RandomizeFactor, Stop )
|
||||
end
|
||||
|
||||
return self, ScheduleID
|
||||
end
|
||||
|
||||
--function SCHEDULER:_Destructor()
|
||||
-- --self:E("_Destructor")
|
||||
--
|
||||
-- _SCHEDULEDISPATCHER:RemoveSchedule( self.CallID )
|
||||
--end
|
||||
|
||||
--- Schedule a new time event. Note that the schedule will only take place if the scheduler is *started*. Even for a single schedule event, the scheduler needs to be started also.
|
||||
-- @param #SCHEDULER self
|
||||
-- @param #table SchedulerObject Specified for which Moose object the timer is setup. If a value of nil is provided, a scheduler will be setup without an object reference.
|
||||
-- @param #function SchedulerFunction The event function to be called when a timer event occurs. The event function needs to accept the parameters specified in SchedulerArguments.
|
||||
-- @param #table SchedulerArguments Optional arguments that can be given as part of scheduler. The arguments need to be given as a table { param1, param 2, ... }.
|
||||
-- @param #number Start Specifies the amount of seconds that will be waited before the scheduling is started, and the event function is called.
|
||||
-- @param #number Repeat Specifies the interval in seconds when the scheduler will call the event function.
|
||||
-- @param #number RandomizeFactor Specifies a randomization factor between 0 and 1 to randomize the Repeat.
|
||||
-- @param #number Stop Specifies the amount of seconds when the scheduler will be stopped.
|
||||
-- @return #number The ScheduleID of the planned schedule.
|
||||
function SCHEDULER:Schedule( SchedulerObject, SchedulerFunction, SchedulerArguments, Start, Repeat, RandomizeFactor, Stop )
|
||||
self:F2( { Start, Repeat, RandomizeFactor, Stop } )
|
||||
self:T3( { SchedulerArguments } )
|
||||
|
||||
local ObjectName = "-"
|
||||
if SchedulerObject and SchedulerObject.ClassName and SchedulerObject.ClassID then
|
||||
ObjectName = SchedulerObject.ClassName .. SchedulerObject.ClassID
|
||||
end
|
||||
self:F3( { "Schedule :", ObjectName, tostring( SchedulerObject ), Start, Repeat, RandomizeFactor, Stop } )
|
||||
self.SchedulerObject = SchedulerObject
|
||||
|
||||
local ScheduleID = _SCHEDULEDISPATCHER:AddSchedule(
|
||||
self,
|
||||
SchedulerFunction,
|
||||
SchedulerArguments,
|
||||
Start,
|
||||
Repeat,
|
||||
RandomizeFactor,
|
||||
Stop
|
||||
)
|
||||
|
||||
self.Schedules[#self.Schedules+1] = ScheduleID
|
||||
|
||||
return ScheduleID
|
||||
end
|
||||
|
||||
--- (Re-)Starts the schedules or a specific schedule if a valid ScheduleID is provided.
|
||||
-- @param #SCHEDULER self
|
||||
-- @param #number ScheduleID (optional) The ScheduleID of the planned (repeating) schedule.
|
||||
function SCHEDULER:Start( ScheduleID )
|
||||
self:F3( { ScheduleID } )
|
||||
|
||||
_SCHEDULEDISPATCHER:Start( self, ScheduleID )
|
||||
end
|
||||
|
||||
--- Stops the schedules or a specific schedule if a valid ScheduleID is provided.
|
||||
-- @param #SCHEDULER self
|
||||
-- @param #number ScheduleID (optional) The ScheduleID of the planned (repeating) schedule.
|
||||
function SCHEDULER:Stop( ScheduleID )
|
||||
self:F3( { ScheduleID } )
|
||||
|
||||
_SCHEDULEDISPATCHER:Stop( self, ScheduleID )
|
||||
end
|
||||
|
||||
--- Removes a specific schedule if a valid ScheduleID is provided.
|
||||
-- @param #SCHEDULER self
|
||||
-- @param #number ScheduleID (optional) The ScheduleID of the planned (repeating) schedule.
|
||||
function SCHEDULER:Remove( ScheduleID )
|
||||
self:F3( { ScheduleID } )
|
||||
|
||||
_SCHEDULEDISPATCHER:Remove( self, ScheduleID )
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
2283
Moose Development/Moose/Core/Set.lua
Normal file
2283
Moose Development/Moose/Core/Set.lua
Normal file
File diff suppressed because it is too large
Load Diff
932
Moose Development/Moose/Core/Zone.lua
Normal file
932
Moose Development/Moose/Core/Zone.lua
Normal file
@@ -0,0 +1,932 @@
|
||||
--- This core module contains the ZONE classes, inherited from @{Zone#ZONE_BASE}.
|
||||
--
|
||||
-- There are essentially two core functions that zones accomodate:
|
||||
--
|
||||
-- * Test if an object is within the zone boundaries.
|
||||
-- * Provide the zone behaviour. Some zones are static, while others are moveable.
|
||||
--
|
||||
-- The object classes are using the zone classes to test the zone boundaries, which can take various forms:
|
||||
--
|
||||
-- * Test if completely within the zone.
|
||||
-- * Test if partly within the zone (for @{Group#GROUP} objects).
|
||||
-- * Test if not in the zone.
|
||||
-- * Distance to the nearest intersecting point of the zone.
|
||||
-- * Distance to the center of the zone.
|
||||
-- * ...
|
||||
--
|
||||
-- Each of these ZONE classes have a zone name, and specific parameters defining the zone type:
|
||||
--
|
||||
-- * @{Zone#ZONE_BASE}: The ZONE_BASE class defining the base for all other zone classes.
|
||||
-- * @{Zone#ZONE_RADIUS}: The ZONE_RADIUS class defined by a zone name, a location and a radius.
|
||||
-- * @{Zone#ZONE}: The ZONE class, defined by the zone name as defined within the Mission Editor.
|
||||
-- * @{Zone#ZONE_UNIT}: The ZONE_UNIT class defines by a zone around a @{Unit#UNIT} with a radius.
|
||||
-- * @{Zone#ZONE_GROUP}: The ZONE_GROUP class defines by a zone around a @{Group#GROUP} with a radius.
|
||||
-- * @{Zone#ZONE_POLYGON}: The ZONE_POLYGON class defines by a sequence of @{Group#GROUP} waypoints within the Mission Editor, forming a polygon.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- # 1) @{Zone#ZONE_BASE} class, extends @{Base#BASE}
|
||||
--
|
||||
-- This class is an abstract BASE class for derived classes, and is not meant to be instantiated.
|
||||
--
|
||||
-- ## 1.1) Each zone has a name:
|
||||
--
|
||||
-- * @{#ZONE_BASE.GetName}(): Returns the name of the zone.
|
||||
--
|
||||
-- ## 1.2) Each zone implements two polymorphic functions defined in @{Zone#ZONE_BASE}:
|
||||
--
|
||||
-- * @{#ZONE_BASE.IsVec2InZone}(): Returns if a Vec2 is within the zone.
|
||||
-- * @{#ZONE_BASE.IsVec3InZone}(): Returns if a Vec3 is within the zone.
|
||||
--
|
||||
-- ## 1.3) A zone has a probability factor that can be set to randomize a selection between zones:
|
||||
--
|
||||
-- * @{#ZONE_BASE.SetRandomizeProbability}(): Set the randomization probability of a zone to be selected, taking a value between 0 and 1 ( 0 = 0%, 1 = 100% )
|
||||
-- * @{#ZONE_BASE.GetRandomizeProbability}(): Get the randomization probability of a zone to be selected, passing a value between 0 and 1 ( 0 = 0%, 1 = 100% )
|
||||
-- * @{#ZONE_BASE.GetZoneMaybe}(): Get the zone taking into account the randomization probability. nil is returned if this zone is not a candidate.
|
||||
--
|
||||
-- ## 1.4) A zone manages Vectors:
|
||||
--
|
||||
-- * @{#ZONE_BASE.GetVec2}(): Returns the @{DCSTypes#Vec2} coordinate of the zone.
|
||||
-- * @{#ZONE_BASE.GetRandomVec2}(): Define a random @{DCSTypes#Vec2} within the zone.
|
||||
--
|
||||
-- ## 1.5) A zone has a bounding square:
|
||||
--
|
||||
-- * @{#ZONE_BASE.GetBoundingSquare}(): Get the outer most bounding square of the zone.
|
||||
--
|
||||
-- ## 1.6) A zone can be marked:
|
||||
--
|
||||
-- * @{#ZONE_BASE.SmokeZone}(): Smokes the zone boundaries in a color.
|
||||
-- * @{#ZONE_BASE.FlareZone}(): Flares the zone boundaries in a color.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- # 2) @{Zone#ZONE_RADIUS} class, extends @{Zone#ZONE_BASE}
|
||||
--
|
||||
-- The ZONE_RADIUS class defined by a zone name, a location and a radius.
|
||||
-- This class implements the inherited functions from Core.Zone#ZONE_BASE taking into account the own zone format and properties.
|
||||
--
|
||||
-- ## 2.1) @{Zone#ZONE_RADIUS} constructor
|
||||
--
|
||||
-- * @{#ZONE_RADIUS.New}(): Constructor.
|
||||
--
|
||||
-- ## 2.2) Manage the radius of the zone
|
||||
--
|
||||
-- * @{#ZONE_RADIUS.SetRadius}(): Sets the radius of the zone.
|
||||
-- * @{#ZONE_RADIUS.GetRadius}(): Returns the radius of the zone.
|
||||
--
|
||||
-- ## 2.3) Manage the location of the zone
|
||||
--
|
||||
-- * @{#ZONE_RADIUS.SetVec2}(): Sets the @{DCSTypes#Vec2} of the zone.
|
||||
-- * @{#ZONE_RADIUS.GetVec2}(): Returns the @{DCSTypes#Vec2} of the zone.
|
||||
-- * @{#ZONE_RADIUS.GetVec3}(): Returns the @{DCSTypes#Vec3} of the zone, taking an additional height parameter.
|
||||
--
|
||||
-- ## 2.4) Zone point randomization
|
||||
--
|
||||
-- Various functions exist to find random points within the zone.
|
||||
--
|
||||
-- * @{#ZONE_RADIUS.GetRandomVec2}(): Gets a random 2D point in the zone.
|
||||
-- * @{#ZONE_RADIUS.GetRandomPointVec2}(): Gets a @{Point#POINT_VEC2} object representing a random 2D point in the zone.
|
||||
-- * @{#ZONE_RADIUS.GetRandomPointVec3}(): Gets a @{Point#POINT_VEC3} object representing a random 3D point in the zone. Note that the height of the point is at landheight.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- # 3) @{Zone#ZONE} class, extends @{Zone#ZONE_RADIUS}
|
||||
--
|
||||
-- The ZONE class, defined by the zone name as defined within the Mission Editor.
|
||||
-- This class implements the inherited functions from {Core.Zone#ZONE_RADIUS} taking into account the own zone format and properties.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- # 4) @{Zone#ZONE_UNIT} class, extends @{Zone#ZONE_RADIUS}
|
||||
--
|
||||
-- The ZONE_UNIT class defined by a zone around a @{Unit#UNIT} with a radius.
|
||||
-- This class implements the inherited functions from @{Zone#ZONE_RADIUS} taking into account the own zone format and properties.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- # 5) @{Zone#ZONE_GROUP} class, extends @{Zone#ZONE_RADIUS}
|
||||
--
|
||||
-- The ZONE_GROUP class defines by a zone around a @{Group#GROUP} with a radius. The current leader of the group defines the center of the zone.
|
||||
-- This class implements the inherited functions from @{Zone#ZONE_RADIUS} taking into account the own zone format and properties.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- # 6) @{Zone#ZONE_POLYGON_BASE} class, extends @{Zone#ZONE_BASE}
|
||||
--
|
||||
-- The ZONE_POLYGON_BASE class defined by a sequence of @{Group#GROUP} waypoints within the Mission Editor, forming a polygon.
|
||||
-- This class implements the inherited functions from @{Zone#ZONE_RADIUS} taking into account the own zone format and properties.
|
||||
-- This class is an abstract BASE class for derived classes, and is not meant to be instantiated.
|
||||
--
|
||||
-- ## 6.1) Zone point randomization
|
||||
--
|
||||
-- Various functions exist to find random points within the zone.
|
||||
--
|
||||
-- * @{#ZONE_POLYGON_BASE.GetRandomVec2}(): Gets a random 2D point in the zone.
|
||||
-- * @{#ZONE_POLYGON_BASE.GetRandomPointVec2}(): Return a @{Point#POINT_VEC2} object representing a random 2D point within the zone.
|
||||
-- * @{#ZONE_POLYGON_BASE.GetRandomPointVec3}(): Return a @{Point#POINT_VEC3} object representing a random 3D point at landheight within the zone.
|
||||
--
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- # 7) @{Zone#ZONE_POLYGON} class, extends @{Zone#ZONE_POLYGON_BASE}
|
||||
--
|
||||
-- The ZONE_POLYGON class defined by a sequence of @{Group#GROUP} waypoints within the Mission Editor, forming a polygon.
|
||||
-- This class implements the inherited functions from @{Zone#ZONE_RADIUS} taking into account the own zone format and properties.
|
||||
--
|
||||
-- ====
|
||||
--
|
||||
-- **API CHANGE HISTORY**
|
||||
-- ======================
|
||||
--
|
||||
-- The underlying change log documents the API changes. Please read this carefully. The following notation is used:
|
||||
--
|
||||
-- * **Added** parts are expressed in bold type face.
|
||||
-- * _Removed_ parts are expressed in italic type face.
|
||||
--
|
||||
-- Hereby the change log:
|
||||
--
|
||||
-- 2017-02-28: ZONE\_BASE:**IsVec2InZone()** replaces ZONE\_BASE:_IsPointVec2InZone()_.
|
||||
-- 2017-02-28: ZONE\_BASE:**IsVec3InZone()** replaces ZONE\_BASE:_IsPointVec3InZone()_.
|
||||
-- 2017-02-28: ZONE\_RADIUS:**IsVec2InZone()** replaces ZONE\_RADIUS:_IsPointVec2InZone()_.
|
||||
-- 2017-02-28: ZONE\_RADIUS:**IsVec3InZone()** replaces ZONE\_RADIUS:_IsPointVec3InZone()_.
|
||||
-- 2017-02-28: ZONE\_POLYGON:**IsVec2InZone()** replaces ZONE\_POLYGON:_IsPointVec2InZone()_.
|
||||
-- 2017-02-28: ZONE\_POLYGON:**IsVec3InZone()** replaces ZONE\_POLYGON:_IsPointVec3InZone()_.
|
||||
--
|
||||
-- 2017-02-18: ZONE\_POLYGON_BASE:**GetRandomPointVec2()** added.
|
||||
--
|
||||
-- 2017-02-18: ZONE\_POLYGON_BASE:**GetRandomPointVec3()** added.
|
||||
--
|
||||
-- 2017-02-18: ZONE\_RADIUS:**GetRandomPointVec3( inner, outer )** added.
|
||||
--
|
||||
-- 2017-02-18: ZONE\_RADIUS:**GetRandomPointVec2( inner, outer )** added.
|
||||
--
|
||||
-- 2016-08-15: ZONE\_BASE:**GetName()** added.
|
||||
--
|
||||
-- 2016-08-15: ZONE\_BASE:**SetZoneProbability( ZoneProbability )** added.
|
||||
--
|
||||
-- 2016-08-15: ZONE\_BASE:**GetZoneProbability()** added.
|
||||
--
|
||||
-- 2016-08-15: ZONE\_BASE:**GetZoneMaybe()** added.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- @module Zone
|
||||
-- @author FlightControl
|
||||
|
||||
|
||||
--- The ZONE_BASE class
|
||||
-- @type ZONE_BASE
|
||||
-- @field #string ZoneName Name of the zone.
|
||||
-- @field #number ZoneProbability A value between 0 and 1. 0 = 0% and 1 = 100% probability.
|
||||
-- @extends Core.Base#BASE
|
||||
ZONE_BASE = {
|
||||
ClassName = "ZONE_BASE",
|
||||
ZoneName = "",
|
||||
ZoneProbability = 1,
|
||||
}
|
||||
|
||||
|
||||
--- The ZONE_BASE.BoundingSquare
|
||||
-- @type ZONE_BASE.BoundingSquare
|
||||
-- @field Dcs.DCSTypes#Distance x1 The lower x coordinate (left down)
|
||||
-- @field Dcs.DCSTypes#Distance y1 The lower y coordinate (left down)
|
||||
-- @field Dcs.DCSTypes#Distance x2 The higher x coordinate (right up)
|
||||
-- @field Dcs.DCSTypes#Distance y2 The higher y coordinate (right up)
|
||||
|
||||
|
||||
--- ZONE_BASE constructor
|
||||
-- @param #ZONE_BASE self
|
||||
-- @param #string ZoneName Name of the zone.
|
||||
-- @return #ZONE_BASE self
|
||||
function ZONE_BASE:New( ZoneName )
|
||||
local self = BASE:Inherit( self, BASE:New() )
|
||||
self:F( ZoneName )
|
||||
|
||||
self.ZoneName = ZoneName
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Returns the name of the zone.
|
||||
-- @param #ZONE_BASE self
|
||||
-- @return #string The name of the zone.
|
||||
function ZONE_BASE:GetName()
|
||||
self:F2()
|
||||
|
||||
return self.ZoneName
|
||||
end
|
||||
--- Returns if a location is within the zone.
|
||||
-- @param #ZONE_BASE self
|
||||
-- @param Dcs.DCSTypes#Vec2 Vec2 The location to test.
|
||||
-- @return #boolean true if the location is within the zone.
|
||||
function ZONE_BASE:IsVec2InZone( Vec2 )
|
||||
self:F2( Vec2 )
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
--- Returns if a point is within the zone.
|
||||
-- @param #ZONE_BASE self
|
||||
-- @param Dcs.DCSTypes#Vec3 Vec3 The point to test.
|
||||
-- @return #boolean true if the point is within the zone.
|
||||
function ZONE_BASE:IsVec3InZone( Vec3 )
|
||||
self:F2( Vec3 )
|
||||
|
||||
local InZone = self:IsVec2InZone( { x = Vec3.x, y = Vec3.z } )
|
||||
|
||||
return InZone
|
||||
end
|
||||
|
||||
--- Returns the @{DCSTypes#Vec2} coordinate of the zone.
|
||||
-- @param #ZONE_BASE self
|
||||
-- @return #nil.
|
||||
function ZONE_BASE:GetVec2()
|
||||
self:F2( self.ZoneName )
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Define a random @{DCSTypes#Vec2} within the zone.
|
||||
-- @param #ZONE_BASE self
|
||||
-- @return Dcs.DCSTypes#Vec2 The Vec2 coordinates.
|
||||
function ZONE_BASE:GetRandomVec2()
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Define a random @{Point#POINT_VEC2} within the zone.
|
||||
-- @param #ZONE_BASE self
|
||||
-- @return Core.Point#POINT_VEC2 The PointVec2 coordinates.
|
||||
function ZONE_BASE:GetRandomPointVec2()
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Get the bounding square the zone.
|
||||
-- @param #ZONE_BASE self
|
||||
-- @return #nil The bounding square.
|
||||
function ZONE_BASE:GetBoundingSquare()
|
||||
--return { x1 = 0, y1 = 0, x2 = 0, y2 = 0 }
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
--- Smokes the zone boundaries in a color.
|
||||
-- @param #ZONE_BASE self
|
||||
-- @param Utilities.Utils#SMOKECOLOR SmokeColor The smoke color.
|
||||
function ZONE_BASE:SmokeZone( SmokeColor )
|
||||
self:F2( SmokeColor )
|
||||
|
||||
end
|
||||
|
||||
--- Set the randomization probability of a zone to be selected.
|
||||
-- @param #ZONE_BASE self
|
||||
-- @param ZoneProbability A value between 0 and 1. 0 = 0% and 1 = 100% probability.
|
||||
function ZONE_BASE:SetZoneProbability( ZoneProbability )
|
||||
self:F2( ZoneProbability )
|
||||
|
||||
self.ZoneProbability = ZoneProbability or 1
|
||||
return self
|
||||
end
|
||||
|
||||
--- Get the randomization probability of a zone to be selected.
|
||||
-- @param #ZONE_BASE self
|
||||
-- @return #number A value between 0 and 1. 0 = 0% and 1 = 100% probability.
|
||||
function ZONE_BASE:GetZoneProbability()
|
||||
self:F2()
|
||||
|
||||
return self.ZoneProbability
|
||||
end
|
||||
|
||||
--- Get the zone taking into account the randomization probability of a zone to be selected.
|
||||
-- @param #ZONE_BASE self
|
||||
-- @return #ZONE_BASE The zone is selected taking into account the randomization probability factor.
|
||||
-- @return #nil The zone is not selected taking into account the randomization probability factor.
|
||||
function ZONE_BASE:GetZoneMaybe()
|
||||
self:F2()
|
||||
|
||||
local Randomization = math.random()
|
||||
if Randomization <= self.ZoneProbability then
|
||||
return self
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--- The ZONE_RADIUS class, defined by a zone name, a location and a radius.
|
||||
-- @type ZONE_RADIUS
|
||||
-- @field Dcs.DCSTypes#Vec2 Vec2 The current location of the zone.
|
||||
-- @field Dcs.DCSTypes#Distance Radius The radius of the zone.
|
||||
-- @extends Core.Zone#ZONE_BASE
|
||||
ZONE_RADIUS = {
|
||||
ClassName="ZONE_RADIUS",
|
||||
}
|
||||
|
||||
--- Constructor of @{#ZONE_RADIUS}, taking the zone name, the zone location and a radius.
|
||||
-- @param #ZONE_RADIUS self
|
||||
-- @param #string ZoneName Name of the zone.
|
||||
-- @param Dcs.DCSTypes#Vec2 Vec2 The location of the zone.
|
||||
-- @param Dcs.DCSTypes#Distance Radius The radius of the zone.
|
||||
-- @return #ZONE_RADIUS self
|
||||
function ZONE_RADIUS:New( ZoneName, Vec2, Radius )
|
||||
local self = BASE:Inherit( self, ZONE_BASE:New( ZoneName ) )
|
||||
self:F( { ZoneName, Vec2, Radius } )
|
||||
|
||||
self.Radius = Radius
|
||||
self.Vec2 = Vec2
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Smokes the zone boundaries in a color.
|
||||
-- @param #ZONE_RADIUS self
|
||||
-- @param Utilities.Utils#SMOKECOLOR SmokeColor The smoke color.
|
||||
-- @param #number Points (optional) The amount of points in the circle.
|
||||
-- @return #ZONE_RADIUS self
|
||||
function ZONE_RADIUS:SmokeZone( SmokeColor, Points )
|
||||
self:F2( SmokeColor )
|
||||
|
||||
local Point = {}
|
||||
local Vec2 = self:GetVec2()
|
||||
|
||||
Points = Points and Points or 360
|
||||
|
||||
local Angle
|
||||
local RadialBase = math.pi*2
|
||||
|
||||
for Angle = 0, 360, 360 / Points do
|
||||
local Radial = Angle * RadialBase / 360
|
||||
Point.x = Vec2.x + math.cos( Radial ) * self:GetRadius()
|
||||
Point.y = Vec2.y + math.sin( Radial ) * self:GetRadius()
|
||||
POINT_VEC2:New( Point.x, Point.y ):Smoke( SmokeColor )
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
--- Flares the zone boundaries in a color.
|
||||
-- @param #ZONE_RADIUS self
|
||||
-- @param Utilities.Utils#FLARECOLOR FlareColor The flare color.
|
||||
-- @param #number Points (optional) The amount of points in the circle.
|
||||
-- @param Dcs.DCSTypes#Azimuth Azimuth (optional) Azimuth The azimuth of the flare.
|
||||
-- @return #ZONE_RADIUS self
|
||||
function ZONE_RADIUS:FlareZone( FlareColor, Points, Azimuth )
|
||||
self:F2( { FlareColor, Azimuth } )
|
||||
|
||||
local Point = {}
|
||||
local Vec2 = self:GetVec2()
|
||||
|
||||
Points = Points and Points or 360
|
||||
|
||||
local Angle
|
||||
local RadialBase = math.pi*2
|
||||
|
||||
for Angle = 0, 360, 360 / Points do
|
||||
local Radial = Angle * RadialBase / 360
|
||||
Point.x = Vec2.x + math.cos( Radial ) * self:GetRadius()
|
||||
Point.y = Vec2.y + math.sin( Radial ) * self:GetRadius()
|
||||
POINT_VEC2:New( Point.x, Point.y ):Flare( FlareColor, Azimuth )
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Returns the radius of the zone.
|
||||
-- @param #ZONE_RADIUS self
|
||||
-- @return Dcs.DCSTypes#Distance The radius of the zone.
|
||||
function ZONE_RADIUS:GetRadius()
|
||||
self:F2( self.ZoneName )
|
||||
|
||||
self:T2( { self.Radius } )
|
||||
|
||||
return self.Radius
|
||||
end
|
||||
|
||||
--- Sets the radius of the zone.
|
||||
-- @param #ZONE_RADIUS self
|
||||
-- @param Dcs.DCSTypes#Distance Radius The radius of the zone.
|
||||
-- @return Dcs.DCSTypes#Distance The radius of the zone.
|
||||
function ZONE_RADIUS:SetRadius( Radius )
|
||||
self:F2( self.ZoneName )
|
||||
|
||||
self.Radius = Radius
|
||||
self:T2( { self.Radius } )
|
||||
|
||||
return self.Radius
|
||||
end
|
||||
|
||||
--- Returns the @{DCSTypes#Vec2} of the zone.
|
||||
-- @param #ZONE_RADIUS self
|
||||
-- @return Dcs.DCSTypes#Vec2 The location of the zone.
|
||||
function ZONE_RADIUS:GetVec2()
|
||||
self:F2( self.ZoneName )
|
||||
|
||||
self:T2( { self.Vec2 } )
|
||||
|
||||
return self.Vec2
|
||||
end
|
||||
|
||||
--- Sets the @{DCSTypes#Vec2} of the zone.
|
||||
-- @param #ZONE_RADIUS self
|
||||
-- @param Dcs.DCSTypes#Vec2 Vec2 The new location of the zone.
|
||||
-- @return Dcs.DCSTypes#Vec2 The new location of the zone.
|
||||
function ZONE_RADIUS:SetVec2( Vec2 )
|
||||
self:F2( self.ZoneName )
|
||||
|
||||
self.Vec2 = Vec2
|
||||
|
||||
self:T2( { self.Vec2 } )
|
||||
|
||||
return self.Vec2
|
||||
end
|
||||
|
||||
--- Returns the @{DCSTypes#Vec3} of the ZONE_RADIUS.
|
||||
-- @param #ZONE_RADIUS self
|
||||
-- @param Dcs.DCSTypes#Distance Height The height to add to the land height where the center of the zone is located.
|
||||
-- @return Dcs.DCSTypes#Vec3 The point of the zone.
|
||||
function ZONE_RADIUS:GetVec3( Height )
|
||||
self:F2( { self.ZoneName, Height } )
|
||||
|
||||
Height = Height or 0
|
||||
local Vec2 = self:GetVec2()
|
||||
|
||||
local Vec3 = { x = Vec2.x, y = land.getHeight( self:GetVec2() ) + Height, z = Vec2.y }
|
||||
|
||||
self:T2( { Vec3 } )
|
||||
|
||||
return Vec3
|
||||
end
|
||||
|
||||
|
||||
--- Returns if a location is within the zone.
|
||||
-- @param #ZONE_RADIUS self
|
||||
-- @param Dcs.DCSTypes#Vec2 Vec2 The location to test.
|
||||
-- @return #boolean true if the location is within the zone.
|
||||
function ZONE_RADIUS:IsVec2InZone( Vec2 )
|
||||
self:F2( Vec2 )
|
||||
|
||||
local ZoneVec2 = self:GetVec2()
|
||||
|
||||
if ZoneVec2 then
|
||||
if (( Vec2.x - ZoneVec2.x )^2 + ( Vec2.y - ZoneVec2.y ) ^2 ) ^ 0.5 <= self:GetRadius() then
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
--- Returns if a point is within the zone.
|
||||
-- @param #ZONE_RADIUS self
|
||||
-- @param Dcs.DCSTypes#Vec3 Vec3 The point to test.
|
||||
-- @return #boolean true if the point is within the zone.
|
||||
function ZONE_RADIUS:IsVec3InZone( Vec3 )
|
||||
self:F2( Vec3 )
|
||||
|
||||
local InZone = self:IsVec2InZone( { x = Vec3.x, y = Vec3.z } )
|
||||
|
||||
return InZone
|
||||
end
|
||||
|
||||
--- Returns a random Vec2 location within the zone.
|
||||
-- @param #ZONE_RADIUS self
|
||||
-- @param #number inner (optional) Minimal distance from the center of the zone. Default is 0.
|
||||
-- @param #number outer (optional) Maximal distance from the outer edge of the zone. Default is the radius of the zone.
|
||||
-- @return Dcs.DCSTypes#Vec2 The random location within the zone.
|
||||
function ZONE_RADIUS:GetRandomVec2( inner, outer )
|
||||
self:F( self.ZoneName, inner, outer )
|
||||
|
||||
local Point = {}
|
||||
local Vec2 = self:GetVec2()
|
||||
local _inner = inner or 0
|
||||
local _outer = outer or self:GetRadius()
|
||||
|
||||
local angle = math.random() * math.pi * 2;
|
||||
Point.x = Vec2.x + math.cos( angle ) * math.random(_inner, _outer);
|
||||
Point.y = Vec2.y + math.sin( angle ) * math.random(_inner, _outer);
|
||||
|
||||
self:T( { Point } )
|
||||
|
||||
return Point
|
||||
end
|
||||
|
||||
--- Returns a @{Point#POINT_VEC2} object reflecting a random 2D location within the zone.
|
||||
-- @param #ZONE_RADIUS self
|
||||
-- @param #number inner (optional) Minimal distance from the center of the zone. Default is 0.
|
||||
-- @param #number outer (optional) Maximal distance from the outer edge of the zone. Default is the radius of the zone.
|
||||
-- @return Core.Point#POINT_VEC2 The @{Point#POINT_VEC2} object reflecting the random 3D location within the zone.
|
||||
function ZONE_RADIUS:GetRandomPointVec2( inner, outer )
|
||||
self:F( self.ZoneName, inner, outer )
|
||||
|
||||
local PointVec2 = POINT_VEC2:NewFromVec2( self:GetRandomVec2() )
|
||||
|
||||
self:T3( { PointVec2 } )
|
||||
|
||||
return PointVec2
|
||||
end
|
||||
|
||||
--- Returns a @{Point#POINT_VEC3} object reflecting a random 3D location within the zone.
|
||||
-- @param #ZONE_RADIUS self
|
||||
-- @param #number inner (optional) Minimal distance from the center of the zone. Default is 0.
|
||||
-- @param #number outer (optional) Maximal distance from the outer edge of the zone. Default is the radius of the zone.
|
||||
-- @return Core.Point#POINT_VEC3 The @{Point#POINT_VEC3} object reflecting the random 3D location within the zone.
|
||||
function ZONE_RADIUS:GetRandomPointVec3( inner, outer )
|
||||
self:F( self.ZoneName, inner, outer )
|
||||
|
||||
local PointVec3 = POINT_VEC3:NewFromVec2( self:GetRandomVec2() )
|
||||
|
||||
self:T3( { PointVec3 } )
|
||||
|
||||
return PointVec3
|
||||
end
|
||||
|
||||
|
||||
|
||||
--- The ZONE class, defined by the zone name as defined within the Mission Editor. The location and the radius are automatically collected from the mission settings.
|
||||
-- @type ZONE
|
||||
-- @extends Core.Zone#ZONE_RADIUS
|
||||
ZONE = {
|
||||
ClassName="ZONE",
|
||||
}
|
||||
|
||||
|
||||
--- Constructor of ZONE, taking the zone name.
|
||||
-- @param #ZONE self
|
||||
-- @param #string ZoneName The name of the zone as defined within the mission editor.
|
||||
-- @return #ZONE
|
||||
function ZONE:New( ZoneName )
|
||||
|
||||
local Zone = trigger.misc.getZone( ZoneName )
|
||||
|
||||
if not Zone then
|
||||
error( "Zone " .. ZoneName .. " does not exist." )
|
||||
return nil
|
||||
end
|
||||
|
||||
local self = BASE:Inherit( self, ZONE_RADIUS:New( ZoneName, { x = Zone.point.x, y = Zone.point.z }, Zone.radius ) )
|
||||
self:F( ZoneName )
|
||||
|
||||
self.Zone = Zone
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
--- The ZONE_UNIT class defined by a zone around a @{Unit#UNIT} with a radius.
|
||||
-- @type ZONE_UNIT
|
||||
-- @field Wrapper.Unit#UNIT ZoneUNIT
|
||||
-- @extends Core.Zone#ZONE_RADIUS
|
||||
ZONE_UNIT = {
|
||||
ClassName="ZONE_UNIT",
|
||||
}
|
||||
|
||||
--- Constructor to create a ZONE_UNIT instance, taking the zone name, a zone unit and a radius.
|
||||
-- @param #ZONE_UNIT self
|
||||
-- @param #string ZoneName Name of the zone.
|
||||
-- @param Wrapper.Unit#UNIT ZoneUNIT The unit as the center of the zone.
|
||||
-- @param Dcs.DCSTypes#Distance Radius The radius of the zone.
|
||||
-- @return #ZONE_UNIT self
|
||||
function ZONE_UNIT:New( ZoneName, ZoneUNIT, Radius )
|
||||
local self = BASE:Inherit( self, ZONE_RADIUS:New( ZoneName, ZoneUNIT:GetVec2(), Radius ) )
|
||||
self:F( { ZoneName, ZoneUNIT:GetVec2(), Radius } )
|
||||
|
||||
self.ZoneUNIT = ZoneUNIT
|
||||
self.LastVec2 = ZoneUNIT:GetVec2()
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
--- Returns the current location of the @{Unit#UNIT}.
|
||||
-- @param #ZONE_UNIT self
|
||||
-- @return Dcs.DCSTypes#Vec2 The location of the zone based on the @{Unit#UNIT}location.
|
||||
function ZONE_UNIT:GetVec2()
|
||||
self:F( self.ZoneName )
|
||||
|
||||
local ZoneVec2 = self.ZoneUNIT:GetVec2()
|
||||
if ZoneVec2 then
|
||||
self.LastVec2 = ZoneVec2
|
||||
return ZoneVec2
|
||||
else
|
||||
return self.LastVec2
|
||||
end
|
||||
|
||||
self:T( { ZoneVec2 } )
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Returns a random location within the zone.
|
||||
-- @param #ZONE_UNIT self
|
||||
-- @return Dcs.DCSTypes#Vec2 The random location within the zone.
|
||||
function ZONE_UNIT:GetRandomVec2()
|
||||
self:F( self.ZoneName )
|
||||
|
||||
local RandomVec2 = {}
|
||||
local Vec2 = self.ZoneUNIT:GetVec2()
|
||||
|
||||
if not Vec2 then
|
||||
Vec2 = self.LastVec2
|
||||
end
|
||||
|
||||
local angle = math.random() * math.pi*2;
|
||||
RandomVec2.x = Vec2.x + math.cos( angle ) * math.random() * self:GetRadius();
|
||||
RandomVec2.y = Vec2.y + math.sin( angle ) * math.random() * self:GetRadius();
|
||||
|
||||
self:T( { RandomVec2 } )
|
||||
|
||||
return RandomVec2
|
||||
end
|
||||
|
||||
--- Returns the @{DCSTypes#Vec3} of the ZONE_UNIT.
|
||||
-- @param #ZONE_UNIT self
|
||||
-- @param Dcs.DCSTypes#Distance Height The height to add to the land height where the center of the zone is located.
|
||||
-- @return Dcs.DCSTypes#Vec3 The point of the zone.
|
||||
function ZONE_UNIT:GetVec3( Height )
|
||||
self:F2( self.ZoneName )
|
||||
|
||||
Height = Height or 0
|
||||
|
||||
local Vec2 = self:GetVec2()
|
||||
|
||||
local Vec3 = { x = Vec2.x, y = land.getHeight( self:GetVec2() ) + Height, z = Vec2.y }
|
||||
|
||||
self:T2( { Vec3 } )
|
||||
|
||||
return Vec3
|
||||
end
|
||||
|
||||
--- The ZONE_GROUP class defined by a zone around a @{Group}, taking the average center point of all the units within the Group, with a radius.
|
||||
-- @type ZONE_GROUP
|
||||
-- @field Wrapper.Group#GROUP ZoneGROUP
|
||||
-- @extends Core.Zone#ZONE_RADIUS
|
||||
ZONE_GROUP = {
|
||||
ClassName="ZONE_GROUP",
|
||||
}
|
||||
|
||||
--- Constructor to create a ZONE_GROUP instance, taking the zone name, a zone @{Group#GROUP} and a radius.
|
||||
-- @param #ZONE_GROUP self
|
||||
-- @param #string ZoneName Name of the zone.
|
||||
-- @param Wrapper.Group#GROUP ZoneGROUP The @{Group} as the center of the zone.
|
||||
-- @param Dcs.DCSTypes#Distance Radius The radius of the zone.
|
||||
-- @return #ZONE_GROUP self
|
||||
function ZONE_GROUP:New( ZoneName, ZoneGROUP, Radius )
|
||||
local self = BASE:Inherit( self, ZONE_RADIUS:New( ZoneName, ZoneGROUP:GetVec2(), Radius ) )
|
||||
self:F( { ZoneName, ZoneGROUP:GetVec2(), Radius } )
|
||||
|
||||
self.ZoneGROUP = ZoneGROUP
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
--- Returns the current location of the @{Group}.
|
||||
-- @param #ZONE_GROUP self
|
||||
-- @return Dcs.DCSTypes#Vec2 The location of the zone based on the @{Group} location.
|
||||
function ZONE_GROUP:GetVec2()
|
||||
self:F( self.ZoneName )
|
||||
|
||||
local ZoneVec2 = self.ZoneGROUP:GetVec2()
|
||||
|
||||
self:T( { ZoneVec2 } )
|
||||
|
||||
return ZoneVec2
|
||||
end
|
||||
|
||||
--- Returns a random location within the zone of the @{Group}.
|
||||
-- @param #ZONE_GROUP self
|
||||
-- @return Dcs.DCSTypes#Vec2 The random location of the zone based on the @{Group} location.
|
||||
function ZONE_GROUP:GetRandomVec2()
|
||||
self:F( self.ZoneName )
|
||||
|
||||
local Point = {}
|
||||
local Vec2 = self.ZoneGROUP:GetVec2()
|
||||
|
||||
local angle = math.random() * math.pi*2;
|
||||
Point.x = Vec2.x + math.cos( angle ) * math.random() * self:GetRadius();
|
||||
Point.y = Vec2.y + math.sin( angle ) * math.random() * self:GetRadius();
|
||||
|
||||
self:T( { Point } )
|
||||
|
||||
return Point
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- Polygons
|
||||
|
||||
--- The ZONE_POLYGON_BASE class defined by an array of @{DCSTypes#Vec2}, forming a polygon.
|
||||
-- @type ZONE_POLYGON_BASE
|
||||
-- @field #ZONE_POLYGON_BASE.ListVec2 Polygon The polygon defined by an array of @{DCSTypes#Vec2}.
|
||||
-- @extends Core.Zone#ZONE_BASE
|
||||
ZONE_POLYGON_BASE = {
|
||||
ClassName="ZONE_POLYGON_BASE",
|
||||
}
|
||||
|
||||
--- A points array.
|
||||
-- @type ZONE_POLYGON_BASE.ListVec2
|
||||
-- @list <Dcs.DCSTypes#Vec2>
|
||||
|
||||
--- Constructor to create a ZONE_POLYGON_BASE instance, taking the zone name and an array of @{DCSTypes#Vec2}, forming a polygon.
|
||||
-- The @{Group#GROUP} waypoints define the polygon corners. The first and the last point are automatically connected.
|
||||
-- @param #ZONE_POLYGON_BASE self
|
||||
-- @param #string ZoneName Name of the zone.
|
||||
-- @param #ZONE_POLYGON_BASE.ListVec2 PointsArray An array of @{DCSTypes#Vec2}, forming a polygon..
|
||||
-- @return #ZONE_POLYGON_BASE self
|
||||
function ZONE_POLYGON_BASE:New( ZoneName, PointsArray )
|
||||
local self = BASE:Inherit( self, ZONE_BASE:New( ZoneName ) )
|
||||
self:F( { ZoneName, PointsArray } )
|
||||
|
||||
local i = 0
|
||||
|
||||
self.Polygon = {}
|
||||
|
||||
for i = 1, #PointsArray do
|
||||
self.Polygon[i] = {}
|
||||
self.Polygon[i].x = PointsArray[i].x
|
||||
self.Polygon[i].y = PointsArray[i].y
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Flush polygon coordinates as a table in DCS.log.
|
||||
-- @param #ZONE_POLYGON_BASE self
|
||||
-- @return #ZONE_POLYGON_BASE self
|
||||
function ZONE_POLYGON_BASE:Flush()
|
||||
self:F2()
|
||||
|
||||
self:E( { Polygon = self.ZoneName, Coordinates = self.Polygon } )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
--- Smokes the zone boundaries in a color.
|
||||
-- @param #ZONE_POLYGON_BASE self
|
||||
-- @param Utilities.Utils#SMOKECOLOR SmokeColor The smoke color.
|
||||
-- @return #ZONE_POLYGON_BASE self
|
||||
function ZONE_POLYGON_BASE:SmokeZone( SmokeColor )
|
||||
self:F2( SmokeColor )
|
||||
|
||||
local i
|
||||
local j
|
||||
local Segments = 10
|
||||
|
||||
i = 1
|
||||
j = #self.Polygon
|
||||
|
||||
while i <= #self.Polygon do
|
||||
self:T( { i, j, self.Polygon[i], self.Polygon[j] } )
|
||||
|
||||
local DeltaX = self.Polygon[j].x - self.Polygon[i].x
|
||||
local DeltaY = self.Polygon[j].y - self.Polygon[i].y
|
||||
|
||||
for Segment = 0, Segments do -- We divide each line in 5 segments and smoke a point on the line.
|
||||
local PointX = self.Polygon[i].x + ( Segment * DeltaX / Segments )
|
||||
local PointY = self.Polygon[i].y + ( Segment * DeltaY / Segments )
|
||||
POINT_VEC2:New( PointX, PointY ):Smoke( SmokeColor )
|
||||
end
|
||||
j = i
|
||||
i = i + 1
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
--- Returns if a location is within the zone.
|
||||
-- Source learned and taken from: https://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
|
||||
-- @param #ZONE_POLYGON_BASE self
|
||||
-- @param Dcs.DCSTypes#Vec2 Vec2 The location to test.
|
||||
-- @return #boolean true if the location is within the zone.
|
||||
function ZONE_POLYGON_BASE:IsVec2InZone( Vec2 )
|
||||
self:F2( Vec2 )
|
||||
|
||||
local Next
|
||||
local Prev
|
||||
local InPolygon = false
|
||||
|
||||
Next = 1
|
||||
Prev = #self.Polygon
|
||||
|
||||
while Next <= #self.Polygon do
|
||||
self:T( { Next, Prev, self.Polygon[Next], self.Polygon[Prev] } )
|
||||
if ( ( ( self.Polygon[Next].y > Vec2.y ) ~= ( self.Polygon[Prev].y > Vec2.y ) ) and
|
||||
( Vec2.x < ( self.Polygon[Prev].x - self.Polygon[Next].x ) * ( Vec2.y - self.Polygon[Next].y ) / ( self.Polygon[Prev].y - self.Polygon[Next].y ) + self.Polygon[Next].x )
|
||||
) then
|
||||
InPolygon = not InPolygon
|
||||
end
|
||||
self:T2( { InPolygon = InPolygon } )
|
||||
Prev = Next
|
||||
Next = Next + 1
|
||||
end
|
||||
|
||||
self:T( { InPolygon = InPolygon } )
|
||||
return InPolygon
|
||||
end
|
||||
|
||||
--- Define a random @{DCSTypes#Vec2} within the zone.
|
||||
-- @param #ZONE_POLYGON_BASE self
|
||||
-- @return Dcs.DCSTypes#Vec2 The Vec2 coordinate.
|
||||
function ZONE_POLYGON_BASE:GetRandomVec2()
|
||||
self:F2()
|
||||
|
||||
--- It is a bit tricky to find a random point within a polygon. Right now i am doing it the dirty and inefficient way...
|
||||
local Vec2Found = false
|
||||
local Vec2
|
||||
local BS = self:GetBoundingSquare()
|
||||
|
||||
self:T2( BS )
|
||||
|
||||
while Vec2Found == false do
|
||||
Vec2 = { x = math.random( BS.x1, BS.x2 ), y = math.random( BS.y1, BS.y2 ) }
|
||||
self:T2( Vec2 )
|
||||
if self:IsVec2InZone( Vec2 ) then
|
||||
Vec2Found = true
|
||||
end
|
||||
end
|
||||
|
||||
self:T2( Vec2 )
|
||||
|
||||
return Vec2
|
||||
end
|
||||
|
||||
--- Return a @{Point#POINT_VEC2} object representing a random 2D point at landheight within the zone.
|
||||
-- @param #ZONE_POLYGON_BASE self
|
||||
-- @return @{Point#POINT_VEC2}
|
||||
function ZONE_POLYGON_BASE:GetRandomPointVec2()
|
||||
self:F2()
|
||||
|
||||
local PointVec2 = POINT_VEC2:NewFromVec2( self:GetRandomVec2() )
|
||||
|
||||
self:T2( PointVec2 )
|
||||
|
||||
return PointVec2
|
||||
end
|
||||
|
||||
--- Return a @{Point#POINT_VEC3} object representing a random 3D point at landheight within the zone.
|
||||
-- @param #ZONE_POLYGON_BASE self
|
||||
-- @return @{Point#POINT_VEC3}
|
||||
function ZONE_POLYGON_BASE:GetRandomPointVec3()
|
||||
self:F2()
|
||||
|
||||
local PointVec3 = POINT_VEC3:NewFromVec2( self:GetRandomVec2() )
|
||||
|
||||
self:T2( PointVec3 )
|
||||
|
||||
return PointVec3
|
||||
end
|
||||
|
||||
|
||||
--- Get the bounding square the zone.
|
||||
-- @param #ZONE_POLYGON_BASE self
|
||||
-- @return #ZONE_POLYGON_BASE.BoundingSquare The bounding square.
|
||||
function ZONE_POLYGON_BASE:GetBoundingSquare()
|
||||
|
||||
local x1 = self.Polygon[1].x
|
||||
local y1 = self.Polygon[1].y
|
||||
local x2 = self.Polygon[1].x
|
||||
local y2 = self.Polygon[1].y
|
||||
|
||||
for i = 2, #self.Polygon do
|
||||
self:T2( { self.Polygon[i], x1, y1, x2, y2 } )
|
||||
x1 = ( x1 > self.Polygon[i].x ) and self.Polygon[i].x or x1
|
||||
x2 = ( x2 < self.Polygon[i].x ) and self.Polygon[i].x or x2
|
||||
y1 = ( y1 > self.Polygon[i].y ) and self.Polygon[i].y or y1
|
||||
y2 = ( y2 < self.Polygon[i].y ) and self.Polygon[i].y or y2
|
||||
|
||||
end
|
||||
|
||||
return { x1 = x1, y1 = y1, x2 = x2, y2 = y2 }
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--- The ZONE_POLYGON class defined by a sequence of @{Group#GROUP} waypoints within the Mission Editor, forming a polygon.
|
||||
-- @type ZONE_POLYGON
|
||||
-- @extends Core.Zone#ZONE_POLYGON_BASE
|
||||
ZONE_POLYGON = {
|
||||
ClassName="ZONE_POLYGON",
|
||||
}
|
||||
|
||||
--- Constructor to create a ZONE_POLYGON instance, taking the zone name and the name of the @{Group#GROUP} defined within the Mission Editor.
|
||||
-- The @{Group#GROUP} waypoints define the polygon corners. The first and the last point are automatically connected by ZONE_POLYGON.
|
||||
-- @param #ZONE_POLYGON self
|
||||
-- @param #string ZoneName Name of the zone.
|
||||
-- @param Wrapper.Group#GROUP ZoneGroup The GROUP waypoints as defined within the Mission Editor define the polygon shape.
|
||||
-- @return #ZONE_POLYGON self
|
||||
function ZONE_POLYGON:New( ZoneName, ZoneGroup )
|
||||
|
||||
local GroupPoints = ZoneGroup:GetTaskRoute()
|
||||
|
||||
local self = BASE:Inherit( self, ZONE_POLYGON_BASE:New( ZoneName, GroupPoints ) )
|
||||
self:F( { ZoneName, ZoneGroup, self.Polygon } )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
1
Moose Development/Moose/Dcs
Submodule
1
Moose Development/Moose/Dcs
Submodule
Submodule Moose Development/Moose/Dcs added at 53f6e5cd52
1197
Moose Development/Moose/Functional/AirbasePolice.lua
Normal file
1197
Moose Development/Moose/Functional/AirbasePolice.lua
Normal file
File diff suppressed because it is too large
Load Diff
@@ -2,15 +2,15 @@
|
||||
-- @module CleanUp
|
||||
-- @author Flightcontrol
|
||||
|
||||
Include.File( "Routines" )
|
||||
Include.File( "Base" )
|
||||
Include.File( "Mission" )
|
||||
Include.File( "Client" )
|
||||
Include.File( "Task" )
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--- The CLEANUP class.
|
||||
-- @type CLEANUP
|
||||
-- @extends Base#BASE
|
||||
-- @extends Core.Base#BASE
|
||||
CLEANUP = {
|
||||
ClassName = "CLEANUP",
|
||||
ZoneNames = {},
|
||||
@@ -43,7 +43,7 @@ function CLEANUP:New( ZoneNames, TimeInterval ) local self = BASE:Inherit( self,
|
||||
|
||||
_EVENTDISPATCHER:OnBirth( self._OnEventBirth, self )
|
||||
|
||||
self.CleanUpScheduler = routines.scheduleFunction( self._CleanUpScheduler, { self }, timer.getTime() + 1, TimeInterval )
|
||||
self.CleanUpScheduler = SCHEDULER:New( self, self._CleanUpScheduler, {}, 1, TimeInterval )
|
||||
|
||||
return self
|
||||
end
|
||||
@@ -51,27 +51,25 @@ end
|
||||
|
||||
--- Destroys a group from the simulator, but checks first if it is still existing!
|
||||
-- @param #CLEANUP self
|
||||
-- @param DCSGroup#Group GroupObject The object to be destroyed.
|
||||
-- @param Dcs.DCSWrapper.Group#Group GroupObject The object to be destroyed.
|
||||
-- @param #string CleanUpGroupName The groupname...
|
||||
function CLEANUP:_DestroyGroup( GroupObject, CleanUpGroupName )
|
||||
self:F( { GroupObject, CleanUpGroupName } )
|
||||
|
||||
if GroupObject then -- and GroupObject:isExist() then
|
||||
--MESSAGE:New( "Destroy Group " .. CleanUpGroupName, CleanUpGroupName, 1, CleanUpGroupName ):ToAll()
|
||||
trigger.action.deactivateGroup(GroupObject)
|
||||
self:T( { "GroupObject Destroyed", GroupObject } )
|
||||
end
|
||||
end
|
||||
|
||||
--- Destroys a @{DCSUnit#Unit} from the simulator, but checks first if it is still existing!
|
||||
--- Destroys a @{DCSWrapper.Unit#Unit} from the simulator, but checks first if it is still existing!
|
||||
-- @param #CLEANUP self
|
||||
-- @param DCSUnit#Unit CleanUpUnit The object to be destroyed.
|
||||
-- @param Dcs.DCSWrapper.Unit#Unit CleanUpUnit The object to be destroyed.
|
||||
-- @param #string CleanUpUnitName The Unit name ...
|
||||
function CLEANUP:_DestroyUnit( CleanUpUnit, CleanUpUnitName )
|
||||
self:F( { CleanUpUnit, CleanUpUnitName } )
|
||||
|
||||
if CleanUpUnit then
|
||||
--MESSAGE:New( "Destroy " .. CleanUpUnitName, CleanUpUnitName, 1, CleanUpUnitName ):ToAll()
|
||||
local CleanUpGroup = Unit.getGroup(CleanUpUnit)
|
||||
-- TODO Client bug in 1.5.3
|
||||
if CleanUpGroup and CleanUpGroup:isExist() then
|
||||
@@ -91,10 +89,10 @@ function CLEANUP:_DestroyUnit( CleanUpUnit, CleanUpUnitName )
|
||||
end
|
||||
end
|
||||
|
||||
-- TODO check DCSTypes#Weapon
|
||||
-- TODO check Dcs.DCSTypes#Weapon
|
||||
--- Destroys a missile from the simulator, but checks first if it is still existing!
|
||||
-- @param #CLEANUP self
|
||||
-- @param DCSTypes#Weapon MissileObject
|
||||
-- @param Dcs.DCSTypes#Weapon MissileObject
|
||||
function CLEANUP:_DestroyMissile( MissileObject )
|
||||
self:F( { MissileObject } )
|
||||
|
||||
@@ -136,12 +134,11 @@ end
|
||||
--- Detects if a crash event occurs.
|
||||
-- Crashed units go into a CleanUpList for removal.
|
||||
-- @param #CLEANUP self
|
||||
-- @param DCSTypes#Event event
|
||||
-- @param Dcs.DCSTypes#Event event
|
||||
function CLEANUP:_EventCrash( Event )
|
||||
self:F( { Event } )
|
||||
|
||||
--TODO: This stuff is not working due to a DCS bug. Burning units cannot be destroyed.
|
||||
--MESSAGE:New( "Crash ", "Crash", 10, "Crash" ):ToAll()
|
||||
-- self:T("before getGroup")
|
||||
-- local _grp = Unit.getGroup(event.initiator)-- Identify the group that fired
|
||||
-- self:T("after getGroup")
|
||||
@@ -160,7 +157,7 @@ end
|
||||
--- Detects if a unit shoots a missile.
|
||||
-- If this occurs within one of the zones, then the weapon used must be destroyed.
|
||||
-- @param #CLEANUP self
|
||||
-- @param DCSTypes#Event event
|
||||
-- @param Dcs.DCSTypes#Event event
|
||||
function CLEANUP:_EventShot( Event )
|
||||
self:F( { Event } )
|
||||
|
||||
@@ -170,14 +167,14 @@ function CLEANUP:_EventShot( Event )
|
||||
if ( CurrentLandingZoneID ) then
|
||||
-- Okay, the missile was fired within the CLEANUP.ZoneNames, destroy the fired weapon.
|
||||
--_SEADmissile:destroy()
|
||||
routines.scheduleFunction( CLEANUP._DestroyMissile, { self, Event.Weapon }, timer.getTime() + 0.1)
|
||||
SCHEDULER:New( self, CLEANUP._DestroyMissile, { Event.Weapon }, 0.1 )
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--- Detects if the Unit has an S_EVENT_HIT within the given ZoneNames. If this is the case, destroy the unit.
|
||||
-- @param #CLEANUP self
|
||||
-- @param DCSTypes#Event event
|
||||
-- @param Dcs.DCSTypes#Event event
|
||||
function CLEANUP:_EventHitCleanUp( Event )
|
||||
self:F( { Event } )
|
||||
|
||||
@@ -186,7 +183,7 @@ function CLEANUP:_EventHitCleanUp( Event )
|
||||
self:T( { "Life: ", Event.IniDCSUnitName, ' = ', Event.IniDCSUnit:getLife(), "/", Event.IniDCSUnit:getLife0() } )
|
||||
if Event.IniDCSUnit:getLife() < Event.IniDCSUnit:getLife0() then
|
||||
self:T( "CleanUp: Destroy: " .. Event.IniDCSUnitName )
|
||||
routines.scheduleFunction( CLEANUP._DestroyUnit, { self, Event.IniDCSUnit }, timer.getTime() + 0.1)
|
||||
SCHEDULER:New( self, CLEANUP._DestroyUnit, { Event.IniDCSUnit }, 0.1 )
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -196,13 +193,13 @@ function CLEANUP:_EventHitCleanUp( Event )
|
||||
self:T( { "Life: ", Event.TgtDCSUnitName, ' = ', Event.TgtDCSUnit:getLife(), "/", Event.TgtDCSUnit:getLife0() } )
|
||||
if Event.TgtDCSUnit:getLife() < Event.TgtDCSUnit:getLife0() then
|
||||
self:T( "CleanUp: Destroy: " .. Event.TgtDCSUnitName )
|
||||
routines.scheduleFunction( CLEANUP._DestroyUnit, { self, Event.TgtDCSUnit }, timer.getTime() + 0.1 )
|
||||
SCHEDULER:New( self, CLEANUP._DestroyUnit, { Event.TgtDCSUnit }, 0.1 )
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- Add the @{DCSUnit#Unit} to the CleanUpList for CleanUp.
|
||||
--- Add the @{DCSWrapper.Unit#Unit} to the CleanUpList for CleanUp.
|
||||
function CLEANUP:_AddForCleanUp( CleanUpUnit, CleanUpUnitName )
|
||||
self:F( { CleanUpUnit, CleanUpUnitName } )
|
||||
|
||||
@@ -220,7 +217,7 @@ end
|
||||
|
||||
--- Detects if the Unit has an S_EVENT_ENGINE_SHUTDOWN or an S_EVENT_HIT within the given ZoneNames. If this is the case, add the Group to the CLEANUP List.
|
||||
-- @param #CLEANUP self
|
||||
-- @param DCSTypes#Event event
|
||||
-- @param Dcs.DCSTypes#Event event
|
||||
function CLEANUP:_EventAddForCleanUp( Event )
|
||||
|
||||
if Event.IniDCSUnit then
|
||||
@@ -273,7 +270,6 @@ function CLEANUP:_CleanUpScheduler()
|
||||
--self:T( CleanUpUnitVec2 )
|
||||
local CleanUpSurfaceType = land.getSurfaceType(CleanUpUnitVec2)
|
||||
--self:T( CleanUpSurfaceType )
|
||||
--MESSAGE:New( "Surface " .. CleanUpUnitName .. " = " .. CleanUpSurfaceTypeText[CleanUpSurfaceType], CleanUpUnitName, 10, CleanUpUnitName ):ToAll()
|
||||
|
||||
if CleanUpUnit and CleanUpUnit:getLife() <= CleanUpUnit:getLife0() * 0.95 then
|
||||
if CleanUpSurfaceType == land.SurfaceType.RUNWAY then
|
||||
@@ -305,7 +301,6 @@ function CLEANUP:_CleanUpScheduler()
|
||||
else
|
||||
UnitData.CleanUpTime = timer.getTime()
|
||||
UnitData.CleanUpMoved = true
|
||||
--MESSAGE:New( "Moved " .. CleanUpUnitName, CleanUpUnitName, 10, CleanUpUnitName ):ToAll()
|
||||
end
|
||||
end
|
||||
|
||||
@@ -319,5 +314,7 @@ function CLEANUP:_CleanUpScheduler()
|
||||
end
|
||||
end
|
||||
self:T(CleanUpCount)
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
985
Moose Development/Moose/Functional/Detection.lua
Normal file
985
Moose Development/Moose/Functional/Detection.lua
Normal file
@@ -0,0 +1,985 @@
|
||||
--- This module contains the DETECTION classes.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- 1) @{Detection#DETECTION_BASE} class, extends @{Base#BASE}
|
||||
-- ==========================================================
|
||||
-- The @{Detection#DETECTION_BASE} class defines the core functions to administer detected objects.
|
||||
-- The @{Detection#DETECTION_BASE} class will detect objects within the battle zone for a list of @{Group}s detecting targets following (a) detection method(s).
|
||||
--
|
||||
-- 1.1) DETECTION_BASE constructor
|
||||
-- -------------------------------
|
||||
-- Construct a new DETECTION_BASE instance using the @{Detection#DETECTION_BASE.New}() method.
|
||||
--
|
||||
-- 1.2) DETECTION_BASE initialization
|
||||
-- ----------------------------------
|
||||
-- By default, detection will return detected objects with all the detection sensors available.
|
||||
-- However, you can ask how the objects were found with specific detection methods.
|
||||
-- If you use one of the below methods, the detection will work with the detection method specified.
|
||||
-- You can specify to apply multiple detection methods.
|
||||
--
|
||||
-- Use the following functions to report the objects it detected using the methods Visual, Optical, Radar, IRST, RWR, DLINK:
|
||||
--
|
||||
-- * @{Detection#DETECTION_BASE.InitDetectVisual}(): Detected using Visual.
|
||||
-- * @{Detection#DETECTION_BASE.InitDetectOptical}(): Detected using Optical.
|
||||
-- * @{Detection#DETECTION_BASE.InitDetectRadar}(): Detected using Radar.
|
||||
-- * @{Detection#DETECTION_BASE.InitDetectIRST}(): Detected using IRST.
|
||||
-- * @{Detection#DETECTION_BASE.InitDetectRWR}(): Detected using RWR.
|
||||
-- * @{Detection#DETECTION_BASE.InitDetectDLINK}(): Detected using DLINK.
|
||||
--
|
||||
-- 1.3) Obtain objects detected by DETECTION_BASE
|
||||
-- ----------------------------------------------
|
||||
-- DETECTION_BASE builds @{Set}s of objects detected. These @{Set#SET_BASE}s can be retrieved using the method @{Detection#DETECTION_BASE.GetDetectedSets}().
|
||||
-- The method will return a list (table) of @{Set#SET_BASE} objects.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- 2) @{Detection#DETECTION_AREAS} class, extends @{Detection#DETECTION_BASE}
|
||||
-- ===============================================================================
|
||||
-- The @{Detection#DETECTION_AREAS} class will detect units within the battle zone for a list of @{Group}s detecting targets following (a) detection method(s),
|
||||
-- and will build a list (table) of @{Set#SET_UNIT}s containing the @{Unit#UNIT}s detected.
|
||||
-- The class is group the detected units within zones given a DetectedZoneRange parameter.
|
||||
-- A set with multiple detected zones will be created as there are groups of units detected.
|
||||
--
|
||||
-- 2.1) Retrieve the Detected Unit sets and Detected Zones
|
||||
-- -------------------------------------------------------
|
||||
-- The DetectedUnitSets methods are implemented in @{Detection#DECTECTION_BASE} and the DetectedZones methods is implemented in @{Detection#DETECTION_AREAS}.
|
||||
--
|
||||
-- Retrieve the DetectedUnitSets with the method @{Detection#DETECTION_BASE.GetDetectedSets}(). A table will be return of @{Set#SET_UNIT}s.
|
||||
-- To understand the amount of sets created, use the method @{Detection#DETECTION_BASE.GetDetectedSetCount}().
|
||||
-- If you want to obtain a specific set from the DetectedSets, use the method @{Detection#DETECTION_BASE.GetDetectedSet}() with a given index.
|
||||
--
|
||||
-- Retrieve the formed @{Zone@ZONE_UNIT}s as a result of the grouping the detected units within the DetectionZoneRange, use the method @{Detection#DETECTION_BASE.GetDetectionZones}().
|
||||
-- To understand the amount of zones created, use the method @{Detection#DETECTION_BASE.GetDetectionZoneCount}().
|
||||
-- If you want to obtain a specific zone from the DetectedZones, use the method @{Detection#DETECTION_BASE.GetDetectionZone}() with a given index.
|
||||
--
|
||||
-- 1.4) Flare or Smoke detected units
|
||||
-- ----------------------------------
|
||||
-- Use the methods @{Detection#DETECTION_AREAS.FlareDetectedUnits}() or @{Detection#DETECTION_AREAS.SmokeDetectedUnits}() to flare or smoke the detected units when a new detection has taken place.
|
||||
--
|
||||
-- 1.5) Flare or Smoke detected zones
|
||||
-- ----------------------------------
|
||||
-- Use the methods @{Detection#DETECTION_AREAS.FlareDetectedZones}() or @{Detection#DETECTION_AREAS.SmokeDetectedZones}() to flare or smoke the detected zones when a new detection has taken place.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- ### Contributions:
|
||||
--
|
||||
-- * Mechanist : Concept & Testing
|
||||
--
|
||||
-- ### Authors:
|
||||
--
|
||||
-- * FlightControl : Design & Programming
|
||||
--
|
||||
-- @module Detection
|
||||
|
||||
|
||||
|
||||
--- DETECTION_BASE class
|
||||
-- @type DETECTION_BASE
|
||||
-- @field Core.Set#SET_GROUP DetectionSetGroup The @{Set} of GROUPs in the Forward Air Controller role.
|
||||
-- @field Dcs.DCSTypes#Distance DetectionRange The range till which targets are accepted to be detected.
|
||||
-- @field #DETECTION_BASE.DetectedObjects DetectedObjects The list of detected objects.
|
||||
-- @field #table DetectedObjectsIdentified Map of the DetectedObjects identified.
|
||||
-- @field #number DetectionRun
|
||||
-- @extends Core.Base#BASE
|
||||
DETECTION_BASE = {
|
||||
ClassName = "DETECTION_BASE",
|
||||
DetectionSetGroup = nil,
|
||||
DetectionRange = nil,
|
||||
DetectedObjects = {},
|
||||
DetectionRun = 0,
|
||||
DetectedObjectsIdentified = {},
|
||||
}
|
||||
|
||||
--- @type DETECTION_BASE.DetectedObjects
|
||||
-- @list <#DETECTION_BASE.DetectedObject>
|
||||
|
||||
--- @type DETECTION_BASE.DetectedObject
|
||||
-- @field #string Name
|
||||
-- @field #boolean Visible
|
||||
-- @field #string Type
|
||||
-- @field #number Distance
|
||||
-- @field #boolean Identified
|
||||
|
||||
--- DETECTION constructor.
|
||||
-- @param #DETECTION_BASE self
|
||||
-- @param Core.Set#SET_GROUP DetectionSetGroup The @{Set} of GROUPs in the Forward Air Controller role.
|
||||
-- @param Dcs.DCSTypes#Distance DetectionRange The range till which targets are accepted to be detected.
|
||||
-- @return #DETECTION_BASE self
|
||||
function DETECTION_BASE:New( DetectionSetGroup, DetectionRange )
|
||||
|
||||
-- Inherits from BASE
|
||||
local self = BASE:Inherit( self, BASE:New() )
|
||||
|
||||
self.DetectionSetGroup = DetectionSetGroup
|
||||
self.DetectionRange = DetectionRange
|
||||
|
||||
self:InitDetectVisual( false )
|
||||
self:InitDetectOptical( false )
|
||||
self:InitDetectRadar( false )
|
||||
self:InitDetectRWR( false )
|
||||
self:InitDetectIRST( false )
|
||||
self:InitDetectDLINK( false )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Detect Visual.
|
||||
-- @param #DETECTION_BASE self
|
||||
-- @param #boolean DetectVisual
|
||||
-- @return #DETECTION_BASE self
|
||||
function DETECTION_BASE:InitDetectVisual( DetectVisual )
|
||||
|
||||
self.DetectVisual = DetectVisual
|
||||
end
|
||||
|
||||
--- Detect Optical.
|
||||
-- @param #DETECTION_BASE self
|
||||
-- @param #boolean DetectOptical
|
||||
-- @return #DETECTION_BASE self
|
||||
function DETECTION_BASE:InitDetectOptical( DetectOptical )
|
||||
self:F2()
|
||||
|
||||
self.DetectOptical = DetectOptical
|
||||
end
|
||||
|
||||
--- Detect Radar.
|
||||
-- @param #DETECTION_BASE self
|
||||
-- @param #boolean DetectRadar
|
||||
-- @return #DETECTION_BASE self
|
||||
function DETECTION_BASE:InitDetectRadar( DetectRadar )
|
||||
self:F2()
|
||||
|
||||
self.DetectRadar = DetectRadar
|
||||
end
|
||||
|
||||
--- Detect IRST.
|
||||
-- @param #DETECTION_BASE self
|
||||
-- @param #boolean DetectIRST
|
||||
-- @return #DETECTION_BASE self
|
||||
function DETECTION_BASE:InitDetectIRST( DetectIRST )
|
||||
self:F2()
|
||||
|
||||
self.DetectIRST = DetectIRST
|
||||
end
|
||||
|
||||
--- Detect RWR.
|
||||
-- @param #DETECTION_BASE self
|
||||
-- @param #boolean DetectRWR
|
||||
-- @return #DETECTION_BASE self
|
||||
function DETECTION_BASE:InitDetectRWR( DetectRWR )
|
||||
self:F2()
|
||||
|
||||
self.DetectRWR = DetectRWR
|
||||
end
|
||||
|
||||
--- Detect DLINK.
|
||||
-- @param #DETECTION_BASE self
|
||||
-- @param #boolean DetectDLINK
|
||||
-- @return #DETECTION_BASE self
|
||||
function DETECTION_BASE:InitDetectDLINK( DetectDLINK )
|
||||
self:F2()
|
||||
|
||||
self.DetectDLINK = DetectDLINK
|
||||
end
|
||||
|
||||
--- Determines if a detected object has already been identified during detection processing.
|
||||
-- @param #DETECTION_BASE self
|
||||
-- @param #DETECTION_BASE.DetectedObject DetectedObject
|
||||
-- @return #boolean true if already identified.
|
||||
function DETECTION_BASE:IsDetectedObjectIdentified( DetectedObject )
|
||||
self:F3( DetectedObject.Name )
|
||||
|
||||
local DetectedObjectName = DetectedObject.Name
|
||||
local DetectedObjectIdentified = self.DetectedObjectsIdentified[DetectedObjectName] == true
|
||||
self:T3( DetectedObjectIdentified )
|
||||
return DetectedObjectIdentified
|
||||
end
|
||||
|
||||
--- Identifies a detected object during detection processing.
|
||||
-- @param #DETECTION_BASE self
|
||||
-- @param #DETECTION_BASE.DetectedObject DetectedObject
|
||||
function DETECTION_BASE:IdentifyDetectedObject( DetectedObject )
|
||||
self:F( DetectedObject.Name )
|
||||
|
||||
local DetectedObjectName = DetectedObject.Name
|
||||
self.DetectedObjectsIdentified[DetectedObjectName] = true
|
||||
end
|
||||
|
||||
--- UnIdentify a detected object during detection processing.
|
||||
-- @param #DETECTION_BASE self
|
||||
-- @param #DETECTION_BASE.DetectedObject DetectedObject
|
||||
function DETECTION_BASE:UnIdentifyDetectedObject( DetectedObject )
|
||||
|
||||
local DetectedObjectName = DetectedObject.Name
|
||||
self.DetectedObjectsIdentified[DetectedObjectName] = false
|
||||
end
|
||||
|
||||
--- UnIdentify all detected objects during detection processing.
|
||||
-- @param #DETECTION_BASE self
|
||||
function DETECTION_BASE:UnIdentifyAllDetectedObjects()
|
||||
|
||||
self.DetectedObjectsIdentified = {} -- Table will be garbage collected.
|
||||
end
|
||||
|
||||
--- Gets a detected object with a given name.
|
||||
-- @param #DETECTION_BASE self
|
||||
-- @param #string ObjectName
|
||||
-- @return #DETECTION_BASE.DetectedObject
|
||||
function DETECTION_BASE:GetDetectedObject( ObjectName )
|
||||
self:F3( ObjectName )
|
||||
|
||||
if ObjectName then
|
||||
local DetectedObject = self.DetectedObjects[ObjectName]
|
||||
|
||||
-- Only return detected objects that are alive!
|
||||
local DetectedUnit = UNIT:FindByName( ObjectName )
|
||||
if DetectedUnit and DetectedUnit:IsAlive() then
|
||||
if self:IsDetectedObjectIdentified( DetectedObject ) == false then
|
||||
return DetectedObject
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Get the detected @{Set#SET_BASE}s.
|
||||
-- @param #DETECTION_BASE self
|
||||
-- @return #DETECTION_BASE.DetectedSets DetectedSets
|
||||
function DETECTION_BASE:GetDetectedSets()
|
||||
|
||||
local DetectionSets = self.DetectedSets
|
||||
return DetectionSets
|
||||
end
|
||||
|
||||
--- Get the amount of SETs with detected objects.
|
||||
-- @param #DETECTION_BASE self
|
||||
-- @return #number Count
|
||||
function DETECTION_BASE:GetDetectedSetCount()
|
||||
|
||||
local DetectionSetCount = #self.DetectedSets
|
||||
return DetectionSetCount
|
||||
end
|
||||
|
||||
--- Get a SET of detected objects using a given numeric index.
|
||||
-- @param #DETECTION_BASE self
|
||||
-- @param #number Index
|
||||
-- @return Core.Set#SET_BASE
|
||||
function DETECTION_BASE:GetDetectedSet( Index )
|
||||
|
||||
local DetectionSet = self.DetectedSets[Index]
|
||||
if DetectionSet then
|
||||
return DetectionSet
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Get the detection Groups.
|
||||
-- @param #DETECTION_BASE self
|
||||
-- @return Wrapper.Group#GROUP
|
||||
function DETECTION_BASE:GetDetectionSetGroup()
|
||||
|
||||
local DetectionSetGroup = self.DetectionSetGroup
|
||||
return DetectionSetGroup
|
||||
end
|
||||
|
||||
--- Make a DetectionSet table. This function will be overridden in the derived clsses.
|
||||
-- @param #DETECTION_BASE self
|
||||
-- @return #DETECTION_BASE self
|
||||
function DETECTION_BASE:CreateDetectionSets()
|
||||
self:F2()
|
||||
|
||||
self:E( "Error, in DETECTION_BASE class..." )
|
||||
|
||||
end
|
||||
|
||||
|
||||
--- Schedule the DETECTION construction.
|
||||
-- @param #DETECTION_BASE self
|
||||
-- @param #number DelayTime The delay in seconds to wait the reporting.
|
||||
-- @param #number RepeatInterval The repeat interval in seconds for the reporting to happen repeatedly.
|
||||
-- @return #DETECTION_BASE self
|
||||
function DETECTION_BASE:Schedule( DelayTime, RepeatInterval )
|
||||
self:F2()
|
||||
|
||||
self.ScheduleDelayTime = DelayTime
|
||||
self.ScheduleRepeatInterval = RepeatInterval
|
||||
|
||||
self.DetectionScheduler = SCHEDULER:New( self, self._DetectionScheduler, { self, "Detection" }, DelayTime, RepeatInterval )
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
--- Form @{Set}s of detected @{Unit#UNIT}s in an array of @{Set#SET_BASE}s.
|
||||
-- @param #DETECTION_BASE self
|
||||
function DETECTION_BASE:_DetectionScheduler( SchedulerName )
|
||||
self:F2( { SchedulerName } )
|
||||
|
||||
self.DetectionRun = self.DetectionRun + 1
|
||||
|
||||
self:UnIdentifyAllDetectedObjects() -- Resets the DetectedObjectsIdentified table
|
||||
|
||||
for DetectionGroupID, DetectionGroupData in pairs( self.DetectionSetGroup:GetSet() ) do
|
||||
local DetectionGroup = DetectionGroupData -- Wrapper.Group#GROUP
|
||||
|
||||
if DetectionGroup:IsAlive() then
|
||||
|
||||
local DetectionGroupName = DetectionGroup:GetName()
|
||||
|
||||
local DetectionDetectedTargets = DetectionGroup:GetDetectedTargets(
|
||||
self.DetectVisual,
|
||||
self.DetectOptical,
|
||||
self.DetectRadar,
|
||||
self.DetectIRST,
|
||||
self.DetectRWR,
|
||||
self.DetectDLINK
|
||||
)
|
||||
|
||||
for DetectionDetectedTargetID, DetectionDetectedTarget in pairs( DetectionDetectedTargets ) do
|
||||
local DetectionObject = DetectionDetectedTarget.object -- Dcs.DCSWrapper.Object#Object
|
||||
self:T2( DetectionObject )
|
||||
|
||||
if DetectionObject and DetectionObject:isExist() and DetectionObject.id_ < 50000000 then
|
||||
|
||||
local DetectionDetectedObjectName = DetectionObject:getName()
|
||||
|
||||
local DetectionDetectedObjectPositionVec3 = DetectionObject:getPoint()
|
||||
local DetectionGroupVec3 = DetectionGroup:GetVec3()
|
||||
|
||||
local Distance = ( ( DetectionDetectedObjectPositionVec3.x - DetectionGroupVec3.x )^2 +
|
||||
( DetectionDetectedObjectPositionVec3.y - DetectionGroupVec3.y )^2 +
|
||||
( DetectionDetectedObjectPositionVec3.z - DetectionGroupVec3.z )^2
|
||||
) ^ 0.5 / 1000
|
||||
|
||||
self:T2( { DetectionGroupName, DetectionDetectedObjectName, Distance } )
|
||||
|
||||
if Distance <= self.DetectionRange then
|
||||
|
||||
if not self.DetectedObjects[DetectionDetectedObjectName] then
|
||||
self.DetectedObjects[DetectionDetectedObjectName] = {}
|
||||
end
|
||||
self.DetectedObjects[DetectionDetectedObjectName].Name = DetectionDetectedObjectName
|
||||
self.DetectedObjects[DetectionDetectedObjectName].Visible = DetectionDetectedTarget.visible
|
||||
self.DetectedObjects[DetectionDetectedObjectName].Type = DetectionDetectedTarget.type
|
||||
self.DetectedObjects[DetectionDetectedObjectName].Distance = DetectionDetectedTarget.distance
|
||||
else
|
||||
-- if beyond the DetectionRange then nullify...
|
||||
if self.DetectedObjects[DetectionDetectedObjectName] then
|
||||
self.DetectedObjects[DetectionDetectedObjectName] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
self:T2( self.DetectedObjects )
|
||||
|
||||
-- okay, now we have a list of detected object names ...
|
||||
-- Sort the table based on distance ...
|
||||
table.sort( self.DetectedObjects, function( a, b ) return a.Distance < b.Distance end )
|
||||
end
|
||||
end
|
||||
|
||||
if self.DetectedObjects then
|
||||
self:CreateDetectionSets()
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
|
||||
--- DETECTION_AREAS class
|
||||
-- @type DETECTION_AREAS
|
||||
-- @field Dcs.DCSTypes#Distance DetectionZoneRange The range till which targets are grouped upon the first detected target.
|
||||
-- @field #DETECTION_AREAS.DetectedAreas DetectedAreas A list of areas containing the set of @{Unit}s, @{Zone}s, the center @{Unit} within the zone, and ID of each area that was detected within a DetectionZoneRange.
|
||||
-- @extends Functional.Detection#DETECTION_BASE
|
||||
DETECTION_AREAS = {
|
||||
ClassName = "DETECTION_AREAS",
|
||||
DetectedAreas = { n = 0 },
|
||||
DetectionZoneRange = nil,
|
||||
}
|
||||
|
||||
--- @type DETECTION_AREAS.DetectedAreas
|
||||
-- @list <#DETECTION_AREAS.DetectedArea>
|
||||
|
||||
--- @type DETECTION_AREAS.DetectedArea
|
||||
-- @field Core.Set#SET_UNIT Set -- The Set of Units in the detected area.
|
||||
-- @field Core.Zone#ZONE_UNIT Zone -- The Zone of the detected area.
|
||||
-- @field #boolean Changed Documents if the detected area has changes.
|
||||
-- @field #table Changes A list of the changes reported on the detected area. (It is up to the user of the detected area to consume those changes).
|
||||
-- @field #number AreaID -- The identifier of the detected area.
|
||||
-- @field #boolean FriendliesNearBy Indicates if there are friendlies within the detected area.
|
||||
-- @field Wrapper.Unit#UNIT NearestFAC The nearest FAC near the Area.
|
||||
|
||||
|
||||
--- DETECTION_AREAS constructor.
|
||||
-- @param Functional.Detection#DETECTION_AREAS self
|
||||
-- @param Core.Set#SET_GROUP DetectionSetGroup The @{Set} of GROUPs in the Forward Air Controller role.
|
||||
-- @param Dcs.DCSTypes#Distance DetectionRange The range till which targets are accepted to be detected.
|
||||
-- @param Dcs.DCSTypes#Distance DetectionZoneRange The range till which targets are grouped upon the first detected target.
|
||||
-- @return Functional.Detection#DETECTION_AREAS self
|
||||
function DETECTION_AREAS:New( DetectionSetGroup, DetectionRange, DetectionZoneRange )
|
||||
|
||||
-- Inherits from DETECTION_BASE
|
||||
local self = BASE:Inherit( self, DETECTION_BASE:New( DetectionSetGroup, DetectionRange ) )
|
||||
|
||||
self.DetectionZoneRange = DetectionZoneRange
|
||||
|
||||
self._SmokeDetectedUnits = false
|
||||
self._FlareDetectedUnits = false
|
||||
self._SmokeDetectedZones = false
|
||||
self._FlareDetectedZones = false
|
||||
|
||||
self:Schedule( 10, 10 )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Add a detected @{#DETECTION_AREAS.DetectedArea}.
|
||||
-- @param Core.Set#SET_UNIT Set -- The Set of Units in the detected area.
|
||||
-- @param Core.Zone#ZONE_UNIT Zone -- The Zone of the detected area.
|
||||
-- @return #DETECTION_AREAS.DetectedArea DetectedArea
|
||||
function DETECTION_AREAS:AddDetectedArea( Set, Zone )
|
||||
local DetectedAreas = self:GetDetectedAreas()
|
||||
DetectedAreas.n = self:GetDetectedAreaCount() + 1
|
||||
DetectedAreas[DetectedAreas.n] = {}
|
||||
local DetectedArea = DetectedAreas[DetectedAreas.n]
|
||||
DetectedArea.Set = Set
|
||||
DetectedArea.Zone = Zone
|
||||
DetectedArea.Removed = false
|
||||
DetectedArea.AreaID = DetectedAreas.n
|
||||
|
||||
return DetectedArea
|
||||
end
|
||||
|
||||
--- Remove a detected @{#DETECTION_AREAS.DetectedArea} with a given Index.
|
||||
-- @param #DETECTION_AREAS self
|
||||
-- @param #number Index The Index of the detection are to be removed.
|
||||
-- @return #nil
|
||||
function DETECTION_AREAS:RemoveDetectedArea( Index )
|
||||
local DetectedAreas = self:GetDetectedAreas()
|
||||
local DetectedAreaCount = self:GetDetectedAreaCount()
|
||||
local DetectedArea = DetectedAreas[Index]
|
||||
local DetectedAreaSet = DetectedArea.Set
|
||||
DetectedArea[Index] = nil
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
--- Get the detected @{#DETECTION_AREAS.DetectedAreas}.
|
||||
-- @param #DETECTION_AREAS self
|
||||
-- @return #DETECTION_AREAS.DetectedAreas DetectedAreas
|
||||
function DETECTION_AREAS:GetDetectedAreas()
|
||||
|
||||
local DetectedAreas = self.DetectedAreas
|
||||
return DetectedAreas
|
||||
end
|
||||
|
||||
--- Get the amount of @{#DETECTION_AREAS.DetectedAreas}.
|
||||
-- @param #DETECTION_AREAS self
|
||||
-- @return #number DetectedAreaCount
|
||||
function DETECTION_AREAS:GetDetectedAreaCount()
|
||||
|
||||
local DetectedAreaCount = self.DetectedAreas.n
|
||||
return DetectedAreaCount
|
||||
end
|
||||
|
||||
--- Get the @{Set#SET_UNIT} of a detecttion area using a given numeric index.
|
||||
-- @param #DETECTION_AREAS self
|
||||
-- @param #number Index
|
||||
-- @return Core.Set#SET_UNIT DetectedSet
|
||||
function DETECTION_AREAS:GetDetectedSet( Index )
|
||||
|
||||
local DetectedSetUnit = self.DetectedAreas[Index].Set
|
||||
if DetectedSetUnit then
|
||||
return DetectedSetUnit
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Get the @{Zone#ZONE_UNIT} of a detection area using a given numeric index.
|
||||
-- @param #DETECTION_AREAS self
|
||||
-- @param #number Index
|
||||
-- @return Core.Zone#ZONE_UNIT DetectedZone
|
||||
function DETECTION_AREAS:GetDetectedZone( Index )
|
||||
|
||||
local DetectedZone = self.DetectedAreas[Index].Zone
|
||||
if DetectedZone then
|
||||
return DetectedZone
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Background worker function to determine if there are friendlies nearby ...
|
||||
-- @param #DETECTION_AREAS self
|
||||
-- @param Wrapper.Unit#UNIT ReportUnit
|
||||
function DETECTION_AREAS:ReportFriendliesNearBy( ReportGroupData )
|
||||
self:F2()
|
||||
|
||||
local DetectedArea = ReportGroupData.DetectedArea -- Functional.Detection#DETECTION_AREAS.DetectedArea
|
||||
local DetectedSet = ReportGroupData.DetectedArea.Set
|
||||
local DetectedZone = ReportGroupData.DetectedArea.Zone
|
||||
local DetectedZoneUnit = DetectedZone.ZoneUNIT
|
||||
|
||||
DetectedArea.FriendliesNearBy = false
|
||||
|
||||
local SphereSearch = {
|
||||
id = world.VolumeType.SPHERE,
|
||||
params = {
|
||||
point = DetectedZoneUnit:GetVec3(),
|
||||
radius = 6000,
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
--- @param Dcs.DCSWrapper.Unit#Unit FoundDCSUnit
|
||||
-- @param Wrapper.Group#GROUP ReportGroup
|
||||
-- @param Set#SET_GROUP ReportSetGroup
|
||||
local FindNearByFriendlies = function( FoundDCSUnit, ReportGroupData )
|
||||
|
||||
local DetectedArea = ReportGroupData.DetectedArea -- Functional.Detection#DETECTION_AREAS.DetectedArea
|
||||
local DetectedSet = ReportGroupData.DetectedArea.Set
|
||||
local DetectedZone = ReportGroupData.DetectedArea.Zone
|
||||
local DetectedZoneUnit = DetectedZone.ZoneUNIT -- Wrapper.Unit#UNIT
|
||||
local ReportSetGroup = ReportGroupData.ReportSetGroup
|
||||
|
||||
local EnemyCoalition = DetectedZoneUnit:GetCoalition()
|
||||
|
||||
local FoundUnitCoalition = FoundDCSUnit:getCoalition()
|
||||
local FoundUnitName = FoundDCSUnit:getName()
|
||||
local FoundUnitGroupName = FoundDCSUnit:getGroup():getName()
|
||||
local EnemyUnitName = DetectedZoneUnit:GetName()
|
||||
local FoundUnitInReportSetGroup = ReportSetGroup:FindGroup( FoundUnitGroupName ) ~= nil
|
||||
|
||||
self:T3( { "Friendlies search:", FoundUnitName, FoundUnitCoalition, EnemyUnitName, EnemyCoalition, FoundUnitInReportSetGroup } )
|
||||
|
||||
if FoundUnitCoalition ~= EnemyCoalition and FoundUnitInReportSetGroup == false then
|
||||
DetectedArea.FriendliesNearBy = true
|
||||
return false
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
world.searchObjects( Object.Category.UNIT, SphereSearch, FindNearByFriendlies, ReportGroupData )
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
--- Returns if there are friendlies nearby the FAC units ...
|
||||
-- @param #DETECTION_AREAS self
|
||||
-- @return #boolean trhe if there are friendlies nearby
|
||||
function DETECTION_AREAS:IsFriendliesNearBy( DetectedArea )
|
||||
|
||||
self:T3( DetectedArea.FriendliesNearBy )
|
||||
return DetectedArea.FriendliesNearBy or false
|
||||
end
|
||||
|
||||
--- Calculate the maxium A2G threat level of the DetectedArea.
|
||||
-- @param #DETECTION_AREAS self
|
||||
-- @param #DETECTION_AREAS.DetectedArea DetectedArea
|
||||
function DETECTION_AREAS:CalculateThreatLevelA2G( DetectedArea )
|
||||
|
||||
local MaxThreatLevelA2G = 0
|
||||
for UnitName, UnitData in pairs( DetectedArea.Set:GetSet() ) do
|
||||
local ThreatUnit = UnitData -- Wrapper.Unit#UNIT
|
||||
local ThreatLevelA2G = ThreatUnit:GetThreatLevel()
|
||||
if ThreatLevelA2G > MaxThreatLevelA2G then
|
||||
MaxThreatLevelA2G = ThreatLevelA2G
|
||||
end
|
||||
end
|
||||
|
||||
self:T3( MaxThreatLevelA2G )
|
||||
DetectedArea.MaxThreatLevelA2G = MaxThreatLevelA2G
|
||||
|
||||
end
|
||||
|
||||
--- Find the nearest FAC of the DetectedArea.
|
||||
-- @param #DETECTION_AREAS self
|
||||
-- @param #DETECTION_AREAS.DetectedArea DetectedArea
|
||||
-- @return Wrapper.Unit#UNIT The nearest FAC unit
|
||||
function DETECTION_AREAS:NearestFAC( DetectedArea )
|
||||
|
||||
local NearestFAC = nil
|
||||
local MinDistance = 1000000000 -- Units are not further than 1000000 km away from an area :-)
|
||||
|
||||
for FACGroupName, FACGroupData in pairs( self.DetectionSetGroup:GetSet() ) do
|
||||
for FACUnit, FACUnitData in pairs( FACGroupData:GetUnits() ) do
|
||||
local FACUnit = FACUnitData -- Wrapper.Unit#UNIT
|
||||
if FACUnit:IsActive() then
|
||||
local Vec3 = FACUnit:GetVec3()
|
||||
local PointVec3 = POINT_VEC3:NewFromVec3( Vec3 )
|
||||
local Distance = PointVec3:Get2DDistance(POINT_VEC3:NewFromVec3( FACUnit:GetVec3() ) )
|
||||
if Distance < MinDistance then
|
||||
MinDistance = Distance
|
||||
NearestFAC = FACUnit
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
DetectedArea.NearestFAC = NearestFAC
|
||||
|
||||
end
|
||||
|
||||
--- Returns the A2G threat level of the units in the DetectedArea
|
||||
-- @param #DETECTION_AREAS self
|
||||
-- @param #DETECTION_AREAS.DetectedArea DetectedArea
|
||||
-- @return #number a scale from 0 to 10.
|
||||
function DETECTION_AREAS:GetTreatLevelA2G( DetectedArea )
|
||||
|
||||
self:T3( DetectedArea.MaxThreatLevelA2G )
|
||||
return DetectedArea.MaxThreatLevelA2G
|
||||
end
|
||||
|
||||
|
||||
|
||||
--- Smoke the detected units
|
||||
-- @param #DETECTION_AREAS self
|
||||
-- @return #DETECTION_AREAS self
|
||||
function DETECTION_AREAS:SmokeDetectedUnits()
|
||||
self:F2()
|
||||
|
||||
self._SmokeDetectedUnits = true
|
||||
return self
|
||||
end
|
||||
|
||||
--- Flare the detected units
|
||||
-- @param #DETECTION_AREAS self
|
||||
-- @return #DETECTION_AREAS self
|
||||
function DETECTION_AREAS:FlareDetectedUnits()
|
||||
self:F2()
|
||||
|
||||
self._FlareDetectedUnits = true
|
||||
return self
|
||||
end
|
||||
|
||||
--- Smoke the detected zones
|
||||
-- @param #DETECTION_AREAS self
|
||||
-- @return #DETECTION_AREAS self
|
||||
function DETECTION_AREAS:SmokeDetectedZones()
|
||||
self:F2()
|
||||
|
||||
self._SmokeDetectedZones = true
|
||||
return self
|
||||
end
|
||||
|
||||
--- Flare the detected zones
|
||||
-- @param #DETECTION_AREAS self
|
||||
-- @return #DETECTION_AREAS self
|
||||
function DETECTION_AREAS:FlareDetectedZones()
|
||||
self:F2()
|
||||
|
||||
self._FlareDetectedZones = true
|
||||
return self
|
||||
end
|
||||
|
||||
--- Add a change to the detected zone.
|
||||
-- @param #DETECTION_AREAS self
|
||||
-- @param #DETECTION_AREAS.DetectedArea DetectedArea
|
||||
-- @param #string ChangeCode
|
||||
-- @return #DETECTION_AREAS self
|
||||
function DETECTION_AREAS:AddChangeArea( DetectedArea, ChangeCode, AreaUnitType )
|
||||
|
||||
DetectedArea.Changed = true
|
||||
local AreaID = DetectedArea.AreaID
|
||||
|
||||
DetectedArea.Changes = DetectedArea.Changes or {}
|
||||
DetectedArea.Changes[ChangeCode] = DetectedArea.Changes[ChangeCode] or {}
|
||||
DetectedArea.Changes[ChangeCode].AreaID = AreaID
|
||||
DetectedArea.Changes[ChangeCode].AreaUnitType = AreaUnitType
|
||||
|
||||
self:T( { "Change on Detection Area:", DetectedArea.AreaID, ChangeCode, AreaUnitType } )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
--- Add a change to the detected zone.
|
||||
-- @param #DETECTION_AREAS self
|
||||
-- @param #DETECTION_AREAS.DetectedArea DetectedArea
|
||||
-- @param #string ChangeCode
|
||||
-- @param #string ChangeUnitType
|
||||
-- @return #DETECTION_AREAS self
|
||||
function DETECTION_AREAS:AddChangeUnit( DetectedArea, ChangeCode, ChangeUnitType )
|
||||
|
||||
DetectedArea.Changed = true
|
||||
local AreaID = DetectedArea.AreaID
|
||||
|
||||
DetectedArea.Changes = DetectedArea.Changes or {}
|
||||
DetectedArea.Changes[ChangeCode] = DetectedArea.Changes[ChangeCode] or {}
|
||||
DetectedArea.Changes[ChangeCode][ChangeUnitType] = DetectedArea.Changes[ChangeCode][ChangeUnitType] or 0
|
||||
DetectedArea.Changes[ChangeCode][ChangeUnitType] = DetectedArea.Changes[ChangeCode][ChangeUnitType] + 1
|
||||
DetectedArea.Changes[ChangeCode].AreaID = AreaID
|
||||
|
||||
self:T( { "Change on Detection Area:", DetectedArea.AreaID, ChangeCode, ChangeUnitType } )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Make text documenting the changes of the detected zone.
|
||||
-- @param #DETECTION_AREAS self
|
||||
-- @param #DETECTION_AREAS.DetectedArea DetectedArea
|
||||
-- @return #string The Changes text
|
||||
function DETECTION_AREAS:GetChangeText( DetectedArea )
|
||||
self:F( DetectedArea )
|
||||
|
||||
local MT = {}
|
||||
|
||||
for ChangeCode, ChangeData in pairs( DetectedArea.Changes ) do
|
||||
|
||||
if ChangeCode == "AA" then
|
||||
MT[#MT+1] = "Detected new area " .. ChangeData.AreaID .. ". The center target is a " .. ChangeData.AreaUnitType .. "."
|
||||
end
|
||||
|
||||
if ChangeCode == "RAU" then
|
||||
MT[#MT+1] = "Changed area " .. ChangeData.AreaID .. ". Removed the center target."
|
||||
end
|
||||
|
||||
if ChangeCode == "AAU" then
|
||||
MT[#MT+1] = "Changed area " .. ChangeData.AreaID .. ". The new center target is a " .. ChangeData.AreaUnitType "."
|
||||
end
|
||||
|
||||
if ChangeCode == "RA" then
|
||||
MT[#MT+1] = "Removed old area " .. ChangeData.AreaID .. ". No more targets in this area."
|
||||
end
|
||||
|
||||
if ChangeCode == "AU" then
|
||||
local MTUT = {}
|
||||
for ChangeUnitType, ChangeUnitCount in pairs( ChangeData ) do
|
||||
if ChangeUnitType ~= "AreaID" then
|
||||
MTUT[#MTUT+1] = ChangeUnitCount .. " of " .. ChangeUnitType
|
||||
end
|
||||
end
|
||||
MT[#MT+1] = "Detected for area " .. ChangeData.AreaID .. " new target(s) " .. table.concat( MTUT, ", " ) .. "."
|
||||
end
|
||||
|
||||
if ChangeCode == "RU" then
|
||||
local MTUT = {}
|
||||
for ChangeUnitType, ChangeUnitCount in pairs( ChangeData ) do
|
||||
if ChangeUnitType ~= "AreaID" then
|
||||
MTUT[#MTUT+1] = ChangeUnitCount .. " of " .. ChangeUnitType
|
||||
end
|
||||
end
|
||||
MT[#MT+1] = "Removed for area " .. ChangeData.AreaID .. " invisible or destroyed target(s) " .. table.concat( MTUT, ", " ) .. "."
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
return table.concat( MT, "\n" )
|
||||
|
||||
end
|
||||
|
||||
|
||||
--- Accepts changes from the detected zone.
|
||||
-- @param #DETECTION_AREAS self
|
||||
-- @param #DETECTION_AREAS.DetectedArea DetectedArea
|
||||
-- @return #DETECTION_AREAS self
|
||||
function DETECTION_AREAS:AcceptChanges( DetectedArea )
|
||||
|
||||
DetectedArea.Changed = false
|
||||
DetectedArea.Changes = {}
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
--- Make a DetectionSet table. This function will be overridden in the derived clsses.
|
||||
-- @param #DETECTION_AREAS self
|
||||
-- @return #DETECTION_AREAS self
|
||||
function DETECTION_AREAS:CreateDetectionSets()
|
||||
self:F2()
|
||||
|
||||
-- First go through all detected sets, and check if there are new detected units, match all existing detected units and identify undetected units.
|
||||
-- Regroup when needed, split groups when needed.
|
||||
for DetectedAreaID, DetectedAreaData in ipairs( self.DetectedAreas ) do
|
||||
|
||||
local DetectedArea = DetectedAreaData -- #DETECTION_AREAS.DetectedArea
|
||||
if DetectedArea then
|
||||
|
||||
local DetectedSet = DetectedArea.Set
|
||||
|
||||
local AreaExists = false -- This flag will determine of the detected area is still existing.
|
||||
|
||||
-- First test if the center unit is detected in the detection area.
|
||||
self:T3( DetectedArea.Zone.ZoneUNIT.UnitName )
|
||||
local DetectedZoneObject = self:GetDetectedObject( DetectedArea.Zone.ZoneUNIT.UnitName )
|
||||
self:T3( { "Detecting Zone Object", DetectedArea.AreaID, DetectedArea.Zone, DetectedZoneObject } )
|
||||
|
||||
if DetectedZoneObject then
|
||||
|
||||
--self:IdentifyDetectedObject( DetectedZoneObject )
|
||||
AreaExists = true
|
||||
|
||||
|
||||
|
||||
else
|
||||
-- The center object of the detected area has not been detected. Find an other unit of the set to become the center of the area.
|
||||
-- First remove the center unit from the set.
|
||||
DetectedSet:RemoveUnitsByName( DetectedArea.Zone.ZoneUNIT.UnitName )
|
||||
|
||||
self:AddChangeArea( DetectedArea, 'RAU', "Dummy" )
|
||||
|
||||
-- Then search for a new center area unit within the set. Note that the new area unit candidate must be within the area range.
|
||||
for DetectedUnitName, DetectedUnitData in pairs( DetectedSet:GetSet() ) do
|
||||
|
||||
local DetectedUnit = DetectedUnitData -- Wrapper.Unit#UNIT
|
||||
local DetectedObject = self:GetDetectedObject( DetectedUnit.UnitName )
|
||||
|
||||
-- The DetectedObject can be nil when the DetectedUnit is not alive anymore or it is not in the DetectedObjects map.
|
||||
-- If the DetectedUnit was already identified, DetectedObject will be nil.
|
||||
if DetectedObject then
|
||||
self:IdentifyDetectedObject( DetectedObject )
|
||||
AreaExists = true
|
||||
|
||||
-- Assign the Unit as the new center unit of the detected area.
|
||||
DetectedArea.Zone = ZONE_UNIT:New( DetectedUnit:GetName(), DetectedUnit, self.DetectionZoneRange )
|
||||
|
||||
self:AddChangeArea( DetectedArea, "AAU", DetectedArea.Zone.ZoneUNIT:GetTypeName() )
|
||||
|
||||
-- We don't need to add the DetectedObject to the area set, because it is already there ...
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Now we've determined the center unit of the area, now we can iterate the units in the detected area.
|
||||
-- Note that the position of the area may have moved due to the center unit repositioning.
|
||||
-- If no center unit was identified, then the detected area does not exist anymore and should be deleted, as there are no valid units that can be the center unit.
|
||||
if AreaExists then
|
||||
|
||||
-- ok, we found the center unit of the area, now iterate through the detected area set and see which units are still within the center unit zone ...
|
||||
-- Those units within the zone are flagged as Identified.
|
||||
-- If a unit was not found in the set, remove it from the set. This may be added later to other existing or new sets.
|
||||
for DetectedUnitName, DetectedUnitData in pairs( DetectedSet:GetSet() ) do
|
||||
|
||||
local DetectedUnit = DetectedUnitData -- Wrapper.Unit#UNIT
|
||||
local DetectedObject = nil
|
||||
if DetectedUnit:IsAlive() then
|
||||
--self:E(DetectedUnit:GetName())
|
||||
DetectedObject = self:GetDetectedObject( DetectedUnit:GetName() )
|
||||
end
|
||||
if DetectedObject then
|
||||
|
||||
-- Check if the DetectedUnit is within the DetectedArea.Zone
|
||||
if DetectedUnit:IsInZone( DetectedArea.Zone ) then
|
||||
|
||||
-- Yes, the DetectedUnit is within the DetectedArea.Zone, no changes, DetectedUnit can be kept within the Set.
|
||||
self:IdentifyDetectedObject( DetectedObject )
|
||||
|
||||
else
|
||||
-- No, the DetectedUnit is not within the DetectedArea.Zone, remove DetectedUnit from the Set.
|
||||
DetectedSet:Remove( DetectedUnitName )
|
||||
self:AddChangeUnit( DetectedArea, "RU", DetectedUnit:GetTypeName() )
|
||||
end
|
||||
|
||||
else
|
||||
-- There was no DetectedObject, remove DetectedUnit from the Set.
|
||||
self:AddChangeUnit( DetectedArea, "RU", "destroyed target" )
|
||||
DetectedSet:Remove( DetectedUnitName )
|
||||
|
||||
-- The DetectedObject has been identified, because it does not exist ...
|
||||
-- self:IdentifyDetectedObject( DetectedObject )
|
||||
end
|
||||
end
|
||||
else
|
||||
self:RemoveDetectedArea( DetectedAreaID )
|
||||
self:AddChangeArea( DetectedArea, "RA" )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- We iterated through the existing detection areas and:
|
||||
-- - We checked which units are still detected in each detection area. Those units were flagged as Identified.
|
||||
-- - We recentered the detection area to new center units where it was needed.
|
||||
--
|
||||
-- Now we need to loop through the unidentified detected units and see where they belong:
|
||||
-- - They can be added to a new detection area and become the new center unit.
|
||||
-- - They can be added to a new detection area.
|
||||
for DetectedUnitName, DetectedObjectData in pairs( self.DetectedObjects ) do
|
||||
|
||||
local DetectedObject = self:GetDetectedObject( DetectedUnitName )
|
||||
|
||||
if DetectedObject then
|
||||
|
||||
-- We found an unidentified unit outside of any existing detection area.
|
||||
local DetectedUnit = UNIT:FindByName( DetectedUnitName ) -- Wrapper.Unit#UNIT
|
||||
|
||||
local AddedToDetectionArea = false
|
||||
|
||||
for DetectedAreaID, DetectedAreaData in ipairs( self.DetectedAreas ) do
|
||||
|
||||
local DetectedArea = DetectedAreaData -- #DETECTION_AREAS.DetectedArea
|
||||
if DetectedArea then
|
||||
self:T( "Detection Area #" .. DetectedArea.AreaID )
|
||||
local DetectedSet = DetectedArea.Set
|
||||
if not self:IsDetectedObjectIdentified( DetectedObject ) and DetectedUnit:IsInZone( DetectedArea.Zone ) then
|
||||
self:IdentifyDetectedObject( DetectedObject )
|
||||
DetectedSet:AddUnit( DetectedUnit )
|
||||
AddedToDetectionArea = true
|
||||
self:AddChangeUnit( DetectedArea, "AU", DetectedUnit:GetTypeName() )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if AddedToDetectionArea == false then
|
||||
|
||||
-- New detection area
|
||||
local DetectedArea = self:AddDetectedArea(
|
||||
SET_UNIT:New(),
|
||||
ZONE_UNIT:New( DetectedUnitName, DetectedUnit, self.DetectionZoneRange )
|
||||
)
|
||||
--self:E( DetectedArea.Zone.ZoneUNIT.UnitName )
|
||||
DetectedArea.Set:AddUnit( DetectedUnit )
|
||||
self:AddChangeArea( DetectedArea, "AA", DetectedUnit:GetTypeName() )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Now all the tests should have been build, now make some smoke and flares...
|
||||
-- We also report here the friendlies within the detected areas.
|
||||
|
||||
for DetectedAreaID, DetectedAreaData in ipairs( self.DetectedAreas ) do
|
||||
|
||||
local DetectedArea = DetectedAreaData -- #DETECTION_AREAS.DetectedArea
|
||||
local DetectedSet = DetectedArea.Set
|
||||
local DetectedZone = DetectedArea.Zone
|
||||
|
||||
self:ReportFriendliesNearBy( { DetectedArea = DetectedArea, ReportSetGroup = self.DetectionSetGroup } ) -- Fill the Friendlies table
|
||||
self:CalculateThreatLevelA2G( DetectedArea ) -- Calculate A2G threat level
|
||||
self:NearestFAC( DetectedArea )
|
||||
|
||||
if DETECTION_AREAS._SmokeDetectedUnits or self._SmokeDetectedUnits then
|
||||
DetectedZone.ZoneUNIT:SmokeRed()
|
||||
end
|
||||
DetectedSet:ForEachUnit(
|
||||
--- @param Wrapper.Unit#UNIT DetectedUnit
|
||||
function( DetectedUnit )
|
||||
if DetectedUnit:IsAlive() then
|
||||
self:T( "Detected Set #" .. DetectedArea.AreaID .. ":" .. DetectedUnit:GetName() )
|
||||
if DETECTION_AREAS._FlareDetectedUnits or self._FlareDetectedUnits then
|
||||
DetectedUnit:FlareGreen()
|
||||
end
|
||||
if DETECTION_AREAS._SmokeDetectedUnits or self._SmokeDetectedUnits then
|
||||
DetectedUnit:SmokeGreen()
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
if DETECTION_AREAS._FlareDetectedZones or self._FlareDetectedZones then
|
||||
DetectedZone:FlareZone( SMOKECOLOR.White, 30, math.random( 0,90 ) )
|
||||
end
|
||||
if DETECTION_AREAS._SmokeDetectedZones or self._SmokeDetectedZones then
|
||||
DetectedZone:SmokeZone( SMOKECOLOR.White, 30 )
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
@@ -99,33 +99,41 @@
|
||||
-- * @{#ESCORT.MenuEvasion: Creates a menu structure to set the evasion techniques when the escort is under threat.
|
||||
-- * @{#ESCORT.MenuResumeMission}: Creates a menu structure so that the escort can resume from a waypoint.
|
||||
--
|
||||
--
|
||||
-- @usage
|
||||
-- -- Declare a new EscortPlanes object as follows:
|
||||
--
|
||||
-- -- First find the GROUP object and the CLIENT object.
|
||||
-- local EscortClient = CLIENT:FindByName( "Unit Name" ) -- The Unit Name is the name of the unit flagged with the skill Client in the mission editor.
|
||||
-- local EscortGroup = GROUP:FindByName( "Group Name" ) -- The Group Name is the name of the group that will escort the Escort Client.
|
||||
--
|
||||
-- -- Now use these 2 objects to construct the new EscortPlanes object.
|
||||
-- EscortPlanes = ESCORT:New( EscortClient, EscortGroup, "Desert", "Welcome to the mission. You are escorted by a plane with code name 'Desert', which can be instructed through the F10 radio menu." )
|
||||
--
|
||||
--
|
||||
--
|
||||
-- @module Escort
|
||||
-- @author FlightControl
|
||||
|
||||
Include.File( "Routines" )
|
||||
Include.File( "Base" )
|
||||
Include.File( "Database" )
|
||||
Include.File( "Group" )
|
||||
Include.File( "Zone" )
|
||||
|
||||
---
|
||||
--- ESCORT class
|
||||
-- @type ESCORT
|
||||
-- @extends Base#BASE
|
||||
-- @field Client#CLIENT EscortClient
|
||||
-- @field Group#GROUP EscortGroup
|
||||
-- @extends Core.Base#BASE
|
||||
-- @field Wrapper.Client#CLIENT EscortClient
|
||||
-- @field Wrapper.Group#GROUP EscortGroup
|
||||
-- @field #string EscortName
|
||||
-- @field #ESCORT.MODE EscortMode The mode the escort is in.
|
||||
-- @field #number FollowScheduler The id of the _FollowScheduler function.
|
||||
-- @field Core.Scheduler#SCHEDULER FollowScheduler The instance of the SCHEDULER class.
|
||||
-- @field #number FollowDistance The current follow distance.
|
||||
-- @field #boolean ReportTargets If true, nearby targets are reported.
|
||||
-- @Field DCSTypes#AI.Option.Air.val.ROE OptionROE Which ROE is set to the EscortGroup.
|
||||
-- @field DCSTypes#AI.Option.Air.val.REACTION_ON_THREAT OptionReactionOnThreat Which REACTION_ON_THREAT is set to the EscortGroup.
|
||||
-- @field Menu#MENU_CLIENT EscortMenuResumeMission
|
||||
-- @Field Dcs.DCSTypes#AI.Option.Air.val.ROE OptionROE Which ROE is set to the EscortGroup.
|
||||
-- @field Dcs.DCSTypes#AI.Option.Air.val.REACTION_ON_THREAT OptionReactionOnThreat Which REACTION_ON_THREAT is set to the EscortGroup.
|
||||
-- @field Core.Menu#MENU_CLIENT EscortMenuResumeMission
|
||||
ESCORT = {
|
||||
ClassName = "ESCORT",
|
||||
EscortName = nil, -- The Escort Name
|
||||
EscortClient = nil,
|
||||
EscortGroup = nil,
|
||||
EscortMode = nil,
|
||||
EscortMode = 1,
|
||||
MODE = {
|
||||
FOLLOW = 1,
|
||||
MISSION = 2,
|
||||
@@ -135,6 +143,7 @@ ESCORT = {
|
||||
ReportTargets = true,
|
||||
OptionROE = AI.Option.Air.val.ROE.OPEN_FIRE,
|
||||
OptionReactionOnThreat = AI.Option.Air.val.REACTION_ON_THREAT.ALLOW_ABORT_MISSION,
|
||||
SmokeDirectionVector = false,
|
||||
TaskPoints = {}
|
||||
}
|
||||
|
||||
@@ -152,21 +161,29 @@ ESCORT = {
|
||||
|
||||
--- ESCORT class constructor for an AI group
|
||||
-- @param #ESCORT self
|
||||
-- @param Client#CLIENT EscortClient The client escorted by the EscortGroup.
|
||||
-- @param Group#GROUP EscortGroup The group AI escorting the EscortClient.
|
||||
-- @param Wrapper.Client#CLIENT EscortClient The client escorted by the EscortGroup.
|
||||
-- @param Wrapper.Group#GROUP EscortGroup The group AI escorting the EscortClient.
|
||||
-- @param #string EscortName Name of the escort.
|
||||
-- @param #string EscortBriefing A text showing the ESCORT briefing to the player. Note that if no EscortBriefing is provided, the default briefing will be shown.
|
||||
-- @return #ESCORT self
|
||||
-- @usage
|
||||
-- -- Declare a new EscortPlanes object as follows:
|
||||
--
|
||||
-- -- First find the GROUP object and the CLIENT object.
|
||||
-- local EscortClient = CLIENT:FindByName( "Unit Name" ) -- The Unit Name is the name of the unit flagged with the skill Client in the mission editor.
|
||||
-- local EscortGroup = GROUP:FindByName( "Group Name" ) -- The Group Name is the name of the group that will escort the Escort Client.
|
||||
--
|
||||
-- -- Now use these 2 objects to construct the new EscortPlanes object.
|
||||
-- EscortPlanes = ESCORT:New( EscortClient, EscortGroup, "Desert", "Welcome to the mission. You are escorted by a plane with code name 'Desert', which can be instructed through the F10 radio menu." )
|
||||
function ESCORT:New( EscortClient, EscortGroup, EscortName, EscortBriefing )
|
||||
local self = BASE:Inherit( self, BASE:New() )
|
||||
self:F( { EscortClient, EscortGroup, EscortName } )
|
||||
|
||||
self.EscortClient = EscortClient -- Client#CLIENT
|
||||
self.EscortGroup = EscortGroup -- Group#GROUP
|
||||
self.EscortClient = EscortClient -- Wrapper.Client#CLIENT
|
||||
self.EscortGroup = EscortGroup -- Wrapper.Group#GROUP
|
||||
self.EscortName = EscortName
|
||||
self.EscortBriefing = EscortBriefing
|
||||
|
||||
self:T( EscortGroup:GetClassNameAndID() )
|
||||
|
||||
-- Set EscortGroup known at EscortClient.
|
||||
if not self.EscortClient._EscortGroups then
|
||||
self.EscortClient._EscortGroups = {}
|
||||
@@ -177,26 +194,45 @@ function ESCORT:New( EscortClient, EscortGroup, EscortName, EscortBriefing )
|
||||
self.EscortClient._EscortGroups[EscortGroup:GetName()].EscortGroup = self.EscortGroup
|
||||
self.EscortClient._EscortGroups[EscortGroup:GetName()].EscortName = self.EscortName
|
||||
self.EscortClient._EscortGroups[EscortGroup:GetName()].Targets = {}
|
||||
self.EscortMode = ESCORT.MODE.FOLLOW
|
||||
end
|
||||
|
||||
|
||||
self.EscortMenu = MENU_CLIENT:New( self.EscortClient, self.EscortName )
|
||||
|
||||
self.EscortGroup:WayPointInitialize(1)
|
||||
|
||||
self.EscortGroup:OptionROTVertical()
|
||||
self.EscortGroup:OptionROEOpenFire()
|
||||
|
||||
if not EscortBriefing then
|
||||
EscortGroup:MessageToClient( EscortGroup:GetCategoryName() .. " '" .. EscortName .. "' (" .. EscortGroup:GetCallsign() .. ") reporting! " ..
|
||||
"We're escorting your flight. " ..
|
||||
"Use the Radio Menu and F10 and use the options under + " .. EscortName .. "\n",
|
||||
60, EscortClient
|
||||
)
|
||||
else
|
||||
EscortGroup:MessageToClient( EscortGroup:GetCategoryName() .. " '" .. EscortName .. "' (" .. EscortGroup:GetCallsign() .. ") " .. EscortBriefing,
|
||||
60, EscortClient
|
||||
)
|
||||
end
|
||||
|
||||
EscortGroup:MessageToClient( EscortGroup:GetCategoryName() .. " '" .. EscortName .. "' (" .. EscortGroup:GetCallsign() .. ") reporting! " ..
|
||||
"We're escorting your flight. " ..
|
||||
"Use the Radio Menu and F10 and use the options under + " .. EscortName .. "\n",
|
||||
60, EscortClient
|
||||
)
|
||||
self.FollowDistance = 100
|
||||
self.CT1 = 0
|
||||
self.GT1 = 0
|
||||
self.FollowScheduler = SCHEDULER:New( self, self._FollowScheduler, {}, 1, .5, .01 )
|
||||
self.EscortMode = ESCORT.MODE.MISSION
|
||||
self.FollowScheduler:Stop()
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- This function is for test, it will put on the frequency of the FollowScheduler a red smoke at the direction vector calculated for the escort to fly to.
|
||||
-- This allows to visualize where the escort is flying to.
|
||||
-- @param #ESCORT self
|
||||
-- @param #boolean SmokeDirection If true, then the direction vector will be smoked.
|
||||
function ESCORT:TestSmokeDirectionVector( SmokeDirection )
|
||||
self.SmokeDirectionVector = ( SmokeDirection == true ) and true or false
|
||||
end
|
||||
|
||||
|
||||
--- Defines the default menus
|
||||
-- @param #ESCORT self
|
||||
@@ -223,6 +259,7 @@ function ESCORT:Menus()
|
||||
self:MenuEvasion()
|
||||
self:MenuResumeMission()
|
||||
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
@@ -231,7 +268,7 @@ end
|
||||
--- Defines a menu slot to let the escort Join and Follow you at a certain distance.
|
||||
-- This menu will appear under **Navigation**.
|
||||
-- @param #ESCORT self
|
||||
-- @param DCSTypes#Distance Distance The distance in meters that the escort needs to follow the client.
|
||||
-- @param Dcs.DCSTypes#Distance Distance The distance in meters that the escort needs to follow the client.
|
||||
-- @return #ESCORT
|
||||
function ESCORT:MenuFollowAt( Distance )
|
||||
self:F(Distance)
|
||||
@@ -256,8 +293,8 @@ end
|
||||
--- Defines a menu slot to let the escort hold at their current position and stay low with a specified height during a specified time in seconds.
|
||||
-- This menu will appear under **Hold position**.
|
||||
-- @param #ESCORT self
|
||||
-- @param DCSTypes#Distance Height Optional parameter that sets the height in meters to let the escort orbit at the current location. The default value is 30 meters.
|
||||
-- @param DCSTypes#Time Seconds Optional parameter that lets the escort orbit at the current position for a specified time. (not implemented yet). The default value is 0 seconds, meaning, that the escort will orbit forever until a sequent command is given.
|
||||
-- @param Dcs.DCSTypes#Distance Height Optional parameter that sets the height in meters to let the escort orbit at the current location. The default value is 30 meters.
|
||||
-- @param Dcs.DCSTypes#Time Seconds Optional parameter that lets the escort orbit at the current position for a specified time. (not implemented yet). The default value is 0 seconds, meaning, that the escort will orbit forever until a sequent command is given.
|
||||
-- @param #string MenuTextFormat Optional parameter that shows the menu option text. The text string is formatted, and should contain two %d tokens in the string. The first for the Height, the second for the Time (if given). If no text is given, the default text will be displayed.
|
||||
-- @return #ESCORT
|
||||
-- TODO: Implement Seconds parameter. Challenge is to first develop the "continue from last activity" function.
|
||||
@@ -318,8 +355,8 @@ end
|
||||
--- Defines a menu slot to let the escort hold at the client position and stay low with a specified height during a specified time in seconds.
|
||||
-- This menu will appear under **Navigation**.
|
||||
-- @param #ESCORT self
|
||||
-- @param DCSTypes#Distance Height Optional parameter that sets the height in meters to let the escort orbit at the current location. The default value is 30 meters.
|
||||
-- @param DCSTypes#Time Seconds Optional parameter that lets the escort orbit at the current position for a specified time. (not implemented yet). The default value is 0 seconds, meaning, that the escort will orbit forever until a sequent command is given.
|
||||
-- @param Dcs.DCSTypes#Distance Height Optional parameter that sets the height in meters to let the escort orbit at the current location. The default value is 30 meters.
|
||||
-- @param Dcs.DCSTypes#Time Seconds Optional parameter that lets the escort orbit at the current position for a specified time. (not implemented yet). The default value is 0 seconds, meaning, that the escort will orbit forever until a sequent command is given.
|
||||
-- @param #string MenuTextFormat Optional parameter that shows the menu option text. The text string is formatted, and should contain one or two %d tokens in the string. The first for the Height, the second for the Time (if given). If no text is given, the default text will be displayed.
|
||||
-- @return #ESCORT
|
||||
-- TODO: Implement Seconds parameter. Challenge is to first develop the "continue from last activity" function.
|
||||
@@ -379,8 +416,8 @@ end
|
||||
--- Defines a menu slot to let the escort scan for targets at a certain height for a certain time in seconds.
|
||||
-- This menu will appear under **Scan targets**.
|
||||
-- @param #ESCORT self
|
||||
-- @param DCSTypes#Distance Height Optional parameter that sets the height in meters to let the escort orbit at the current location. The default value is 30 meters.
|
||||
-- @param DCSTypes#Time Seconds Optional parameter that lets the escort orbit at the current position for a specified time. (not implemented yet). The default value is 0 seconds, meaning, that the escort will orbit forever until a sequent command is given.
|
||||
-- @param Dcs.DCSTypes#Distance Height Optional parameter that sets the height in meters to let the escort orbit at the current location. The default value is 30 meters.
|
||||
-- @param Dcs.DCSTypes#Time Seconds Optional parameter that lets the escort orbit at the current position for a specified time. (not implemented yet). The default value is 0 seconds, meaning, that the escort will orbit forever until a sequent command is given.
|
||||
-- @param #string MenuTextFormat Optional parameter that shows the menu option text. The text string is formatted, and should contain one or two %d tokens in the string. The first for the Height, the second for the Time (if given). If no text is given, the default text will be displayed.
|
||||
-- @return #ESCORT
|
||||
function ESCORT:MenuScanForTargets( Height, Seconds, MenuTextFormat )
|
||||
@@ -457,10 +494,10 @@ function ESCORT:MenuFlare( MenuTextFormat )
|
||||
|
||||
if not self.EscortMenuFlare then
|
||||
self.EscortMenuFlare = MENU_CLIENT:New( self.EscortClient, MenuText, self.EscortMenuReportNavigation, ESCORT._Flare, { ParamSelf = self } )
|
||||
self.EscortMenuFlareGreen = MENU_CLIENT_COMMAND:New( self.EscortClient, "Release green flare", self.EscortMenuFlare, ESCORT._Flare, { ParamSelf = self, ParamColor = UNIT.FlareColor.Green, ParamMessage = "Released a green flare!" } )
|
||||
self.EscortMenuFlareRed = MENU_CLIENT_COMMAND:New( self.EscortClient, "Release red flare", self.EscortMenuFlare, ESCORT._Flare, { ParamSelf = self, ParamColor = UNIT.FlareColor.Red, ParamMessage = "Released a red flare!" } )
|
||||
self.EscortMenuFlareWhite = MENU_CLIENT_COMMAND:New( self.EscortClient, "Release white flare", self.EscortMenuFlare, ESCORT._Flare, { ParamSelf = self, ParamColor = UNIT.FlareColor.White, ParamMessage = "Released a white flare!" } )
|
||||
self.EscortMenuFlareYellow = MENU_CLIENT_COMMAND:New( self.EscortClient, "Release yellow flare", self.EscortMenuFlare, ESCORT._Flare, { ParamSelf = self, ParamColor = UNIT.FlareColor.Yellow, ParamMessage = "Released a yellow flare!" } )
|
||||
self.EscortMenuFlareGreen = MENU_CLIENT_COMMAND:New( self.EscortClient, "Release green flare", self.EscortMenuFlare, ESCORT._Flare, { ParamSelf = self, ParamColor = FLARECOLOR.Green, ParamMessage = "Released a green flare!" } )
|
||||
self.EscortMenuFlareRed = MENU_CLIENT_COMMAND:New( self.EscortClient, "Release red flare", self.EscortMenuFlare, ESCORT._Flare, { ParamSelf = self, ParamColor = FLARECOLOR.Red, ParamMessage = "Released a red flare!" } )
|
||||
self.EscortMenuFlareWhite = MENU_CLIENT_COMMAND:New( self.EscortClient, "Release white flare", self.EscortMenuFlare, ESCORT._Flare, { ParamSelf = self, ParamColor = FLARECOLOR.White, ParamMessage = "Released a white flare!" } )
|
||||
self.EscortMenuFlareYellow = MENU_CLIENT_COMMAND:New( self.EscortClient, "Release yellow flare", self.EscortMenuFlare, ESCORT._Flare, { ParamSelf = self, ParamColor = FLARECOLOR.Yellow, ParamMessage = "Released a yellow flare!" } )
|
||||
end
|
||||
|
||||
return self
|
||||
@@ -505,7 +542,7 @@ end
|
||||
-- This menu will appear under **Report targets**.
|
||||
-- Note that if a report targets menu is not specified, no targets will be detected by the escort, and the attack and assisted attack menus will not be displayed.
|
||||
-- @param #ESCORT self
|
||||
-- @param DCSTypes#Time Seconds Optional parameter that lets the escort report their current detected targets after specified time interval in seconds. The default time is 30 seconds.
|
||||
-- @param Dcs.DCSTypes#Time Seconds Optional parameter that lets the escort report their current detected targets after specified time interval in seconds. The default time is 30 seconds.
|
||||
-- @return #ESCORT
|
||||
function ESCORT:MenuReportTargets( Seconds )
|
||||
self:F( { Seconds } )
|
||||
@@ -527,7 +564,7 @@ function ESCORT:MenuReportTargets( Seconds )
|
||||
self.EscortMenuAttackNearbyTargets = MENU_CLIENT:New( self.EscortClient, "Attack targets", self.EscortMenu )
|
||||
|
||||
|
||||
self.ReportTargetsScheduler = routines.scheduleFunction( self._ReportTargetsScheduler, { self }, timer.getTime() + 1, Seconds )
|
||||
self.ReportTargetsScheduler = SCHEDULER:New( self, self._ReportTargetsScheduler, {}, 1, Seconds )
|
||||
|
||||
return self
|
||||
end
|
||||
@@ -627,24 +664,24 @@ function ESCORT._HoldPosition( MenuParam )
|
||||
local EscortGroup = self.EscortGroup
|
||||
local EscortClient = self.EscortClient
|
||||
|
||||
local OrbitGroup = MenuParam.ParamOrbitGroup -- Group#GROUP
|
||||
local OrbitUnit = OrbitGroup:GetUnit(1) -- Unit#UNIT
|
||||
local OrbitGroup = MenuParam.ParamOrbitGroup -- Wrapper.Group#GROUP
|
||||
local OrbitUnit = OrbitGroup:GetUnit(1) -- Wrapper.Unit#UNIT
|
||||
local OrbitHeight = MenuParam.ParamHeight
|
||||
local OrbitSeconds = MenuParam.ParamSeconds -- Not implemented yet
|
||||
|
||||
routines.removeFunction( self.FollowScheduler )
|
||||
self.FollowScheduler:Stop()
|
||||
|
||||
local PointFrom = {}
|
||||
local GroupPoint = EscortGroup:GetUnit(1):GetPositionVec3()
|
||||
local GroupVec3 = EscortGroup:GetUnit(1):GetVec3()
|
||||
PointFrom = {}
|
||||
PointFrom.x = GroupPoint.x
|
||||
PointFrom.y = GroupPoint.z
|
||||
PointFrom.x = GroupVec3.x
|
||||
PointFrom.y = GroupVec3.z
|
||||
PointFrom.speed = 250
|
||||
PointFrom.type = AI.Task.WaypointType.TURNING_POINT
|
||||
PointFrom.alt = GroupPoint.y
|
||||
PointFrom.alt = GroupVec3.y
|
||||
PointFrom.alt_type = AI.Task.AltitudeType.BARO
|
||||
|
||||
local OrbitPoint = OrbitUnit:GetPointVec2()
|
||||
local OrbitPoint = OrbitUnit:GetVec2()
|
||||
local PointTo = {}
|
||||
PointTo.x = OrbitPoint.x
|
||||
PointTo.y = OrbitPoint.y
|
||||
@@ -661,6 +698,7 @@ function ESCORT._HoldPosition( MenuParam )
|
||||
|
||||
EscortGroup:SetTask( EscortGroup:TaskRoute( Points ) )
|
||||
EscortGroup:MessageToClient( "Orbiting at location.", 10, EscortClient )
|
||||
|
||||
end
|
||||
|
||||
--- @param #MENUPARAM MenuParam
|
||||
@@ -676,16 +714,14 @@ function ESCORT._JoinUpAndFollow( MenuParam )
|
||||
end
|
||||
|
||||
--- JoinsUp and Follows a CLIENT.
|
||||
-- @param Escort#ESCORT self
|
||||
-- @param Group#GROUP EscortGroup
|
||||
-- @param Client#CLIENT EscortClient
|
||||
-- @param DCSTypes#Distance Distance
|
||||
-- @param Functional.Escort#ESCORT self
|
||||
-- @param Wrapper.Group#GROUP EscortGroup
|
||||
-- @param Wrapper.Client#CLIENT EscortClient
|
||||
-- @param Dcs.DCSTypes#Distance Distance
|
||||
function ESCORT:JoinUpAndFollow( EscortGroup, EscortClient, Distance )
|
||||
self:F( { EscortGroup, EscortClient, Distance } )
|
||||
|
||||
if self.FollowScheduler then
|
||||
routines.removeFunction( self.FollowScheduler )
|
||||
end
|
||||
self.FollowScheduler:Stop()
|
||||
|
||||
EscortGroup:OptionROEHoldFire()
|
||||
EscortGroup:OptionROTPassiveDefense()
|
||||
@@ -694,7 +730,8 @@ function ESCORT:JoinUpAndFollow( EscortGroup, EscortClient, Distance )
|
||||
|
||||
self.CT1 = 0
|
||||
self.GT1 = 0
|
||||
self.FollowScheduler = routines.scheduleFunction( self._FollowScheduler, { self, Distance }, timer.getTime() + 1, .5 )
|
||||
self.FollowScheduler:Start()
|
||||
|
||||
EscortGroup:MessageToClient( "Rejoining and Following at " .. Distance .. "!", 30, EscortClient )
|
||||
end
|
||||
|
||||
@@ -748,7 +785,7 @@ function ESCORT._SwitchReportNearbyTargets( MenuParam )
|
||||
|
||||
if self.ReportTargets then
|
||||
if not self.ReportTargetsScheduler then
|
||||
self.ReportTargetsScheduler = routines.scheduleFunction( self._ReportTargetsScheduler, { self }, timer.getTime() + 1, 30 )
|
||||
self.ReportTargetsScheduler = SCHEDULER:New( self, self._ReportTargetsScheduler, {}, 1, 30 )
|
||||
end
|
||||
else
|
||||
routines.removeFunction( self.ReportTargetsScheduler )
|
||||
@@ -765,46 +802,41 @@ function ESCORT._ScanTargets( MenuParam )
|
||||
|
||||
local ScanDuration = MenuParam.ParamScanDuration
|
||||
|
||||
if self.FollowScheduler then
|
||||
routines.removeFunction( self.FollowScheduler )
|
||||
end
|
||||
|
||||
self:T( { "FollowScheduler after removefunction: ", self.FollowScheduler } )
|
||||
self.FollowScheduler:Stop()
|
||||
|
||||
if EscortGroup:IsHelicopter() then
|
||||
routines.scheduleFunction( EscortGroup.PushTask,
|
||||
{ EscortGroup,
|
||||
EscortGroup:TaskControlled(
|
||||
SCHEDULER:New( EscortGroup, EscortGroup.PushTask,
|
||||
{ EscortGroup:TaskControlled(
|
||||
EscortGroup:TaskOrbitCircle( 200, 20 ),
|
||||
EscortGroup:TaskCondition( nil, nil, nil, nil, ScanDuration, nil )
|
||||
)
|
||||
},
|
||||
timer.getTime() + 1
|
||||
1
|
||||
)
|
||||
elseif EscortGroup:IsAirPlane() then
|
||||
routines.scheduleFunction( EscortGroup.PushTask,
|
||||
{ EscortGroup,
|
||||
EscortGroup:TaskControlled(
|
||||
SCHEDULER:New( EscortGroup, EscortGroup.PushTask,
|
||||
{ EscortGroup:TaskControlled(
|
||||
EscortGroup:TaskOrbitCircle( 1000, 500 ),
|
||||
EscortGroup:TaskCondition( nil, nil, nil, nil, ScanDuration, nil )
|
||||
)
|
||||
},
|
||||
timer.getTime() + 1
|
||||
1
|
||||
)
|
||||
end
|
||||
|
||||
EscortGroup:MessageToClient( "Scanning targets for " .. ScanDuration .. " seconds.", ScanDuration, EscortClient )
|
||||
|
||||
if self.EscortMode == ESCORT.MODE.FOLLOW then
|
||||
self.FollowScheduler = routines.scheduleFunction( self._FollowScheduler, { self, Distance }, timer.getTime() + ScanDuration, 1 )
|
||||
self.FollowScheduler:Start()
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--- @param Wrapper.Group#GROUP EscortGroup
|
||||
function _Resume( EscortGroup )
|
||||
env.info( '_Resume' )
|
||||
|
||||
local Escort = EscortGroup.Escort -- #ESCORT
|
||||
local Escort = EscortGroup:GetState( EscortGroup, "Escort" )
|
||||
env.info( "EscortMode = " .. Escort.EscortMode )
|
||||
if Escort.EscortMode == ESCORT.MODE.FOLLOW then
|
||||
Escort:JoinUpAndFollow( EscortGroup, Escort.EscortClient, Escort.Distance )
|
||||
@@ -817,43 +849,40 @@ function ESCORT._AttackTarget( MenuParam )
|
||||
|
||||
local self = MenuParam.ParamSelf
|
||||
local EscortGroup = self.EscortGroup
|
||||
|
||||
local EscortClient = self.EscortClient
|
||||
local AttackUnit = MenuParam.ParamUnit -- Unit#UNIT
|
||||
local AttackUnit = MenuParam.ParamUnit -- Wrapper.Unit#UNIT
|
||||
|
||||
if self.FollowScheduler then
|
||||
routines.removeFunction( self.FollowScheduler )
|
||||
end
|
||||
self.FollowScheduler:Stop()
|
||||
|
||||
self:T( AttackUnit )
|
||||
|
||||
if EscortGroup:IsAir() then
|
||||
EscortGroup:OptionROEOpenFire()
|
||||
EscortGroup:OptionROTPassiveDefense()
|
||||
EscortGroup.Escort = self -- Need to do this trick to get the reference for the escort in the _Resume function.
|
||||
routines.scheduleFunction(
|
||||
EscortGroup:SetState( EscortGroup, "Escort", self )
|
||||
SCHEDULER:New( EscortGroup,
|
||||
EscortGroup.PushTask,
|
||||
{ EscortGroup,
|
||||
EscortGroup:TaskCombo(
|
||||
{ EscortGroup:TaskCombo(
|
||||
{ EscortGroup:TaskAttackUnit( AttackUnit ),
|
||||
EscortGroup:TaskFunction( 1, 2, "_Resume", {"''"} )
|
||||
EscortGroup:TaskFunction( 1, 2, "_Resume", { "''" } )
|
||||
}
|
||||
)
|
||||
}, timer.getTime() + 10
|
||||
}, 10
|
||||
)
|
||||
else
|
||||
routines.scheduleFunction(
|
||||
SCHEDULER:New( EscortGroup,
|
||||
EscortGroup.PushTask,
|
||||
{ EscortGroup,
|
||||
EscortGroup:TaskCombo(
|
||||
{ EscortGroup:TaskFireAtPoint( AttackUnit:GetPointVec2(), 50 )
|
||||
{ EscortGroup:TaskCombo(
|
||||
{ EscortGroup:TaskFireAtPoint( AttackUnit:GetVec2(), 50 )
|
||||
}
|
||||
)
|
||||
}, timer.getTime() + 10
|
||||
}, 10
|
||||
)
|
||||
end
|
||||
|
||||
EscortGroup:MessageToClient( "Engaging Designated Unit!", 10, EscortClient )
|
||||
|
||||
|
||||
end
|
||||
|
||||
--- @param #MENUPARAM MenuParam
|
||||
@@ -863,37 +892,32 @@ function ESCORT._AssistTarget( MenuParam )
|
||||
local EscortGroup = self.EscortGroup
|
||||
local EscortClient = self.EscortClient
|
||||
local EscortGroupAttack = MenuParam.ParamEscortGroup
|
||||
local AttackUnit = MenuParam.ParamUnit -- Unit#UNIT
|
||||
|
||||
if self.FollowScheduler then
|
||||
routines.removeFunction( self.FollowScheduler )
|
||||
end
|
||||
local AttackUnit = MenuParam.ParamUnit -- Wrapper.Unit#UNIT
|
||||
|
||||
self.FollowScheduler:Stop()
|
||||
|
||||
self:T( AttackUnit )
|
||||
|
||||
if EscortGroupAttack:IsAir() then
|
||||
EscortGroupAttack:OptionROEOpenFire()
|
||||
EscortGroupAttack:OptionROTVertical()
|
||||
routines.scheduleFunction(
|
||||
SCHDULER:New( EscortGroupAttack,
|
||||
EscortGroupAttack.PushTask,
|
||||
{ EscortGroupAttack,
|
||||
EscortGroupAttack:TaskCombo(
|
||||
{ EscortGroupAttack:TaskCombo(
|
||||
{ EscortGroupAttack:TaskAttackUnit( AttackUnit ),
|
||||
EscortGroupAttack:TaskOrbitCircle( 500, 350 )
|
||||
}
|
||||
)
|
||||
}, timer.getTime() + 10
|
||||
}, 10
|
||||
)
|
||||
else
|
||||
routines.scheduleFunction(
|
||||
SCHEDULER:New( EscortGroupAttack,
|
||||
EscortGroupAttack.PushTask,
|
||||
{ EscortGroupAttack,
|
||||
EscortGroupAttack:TaskCombo(
|
||||
{ EscortGroupAttack:TaskFireAtPoint( AttackUnit:GetPointVec2(), 50 )
|
||||
{ EscortGroupAttack:TaskCombo(
|
||||
{ EscortGroupAttack:TaskFireAtPoint( AttackUnit:GetVec2(), 50 )
|
||||
}
|
||||
)
|
||||
}, timer.getTime() + 10
|
||||
}, 10
|
||||
)
|
||||
end
|
||||
EscortGroupAttack:MessageToClient( "Assisting with the destroying the enemy unit!", 10, EscortClient )
|
||||
@@ -937,8 +961,7 @@ function ESCORT._ResumeMission( MenuParam )
|
||||
|
||||
local WayPoint = MenuParam.ParamWayPoint
|
||||
|
||||
routines.removeFunction( self.FollowScheduler )
|
||||
self.FollowScheduler = nil
|
||||
self.FollowScheduler:Stop()
|
||||
|
||||
local WayPoints = EscortGroup:GetTaskRoute()
|
||||
self:T( WayPoint, WayPoints )
|
||||
@@ -947,7 +970,7 @@ function ESCORT._ResumeMission( MenuParam )
|
||||
table.remove( WayPoints, 1 )
|
||||
end
|
||||
|
||||
routines.scheduleFunction( EscortGroup.SetTask, {EscortGroup, EscortGroup:TaskRoute( WayPoints ) }, timer.getTime() + 1 )
|
||||
SCHEDULER:New( EscortGroup, EscortGroup.SetTask, { EscortGroup:TaskRoute( WayPoints ) }, 1 )
|
||||
|
||||
EscortGroup:MessageToClient( "Resuming mission from waypoint " .. WayPoint .. ".", 10, EscortClient )
|
||||
end
|
||||
@@ -958,7 +981,7 @@ end
|
||||
function ESCORT:RegisterRoute()
|
||||
self:F()
|
||||
|
||||
local EscortGroup = self.EscortGroup -- Group#GROUP
|
||||
local EscortGroup = self.EscortGroup -- Wrapper.Group#GROUP
|
||||
|
||||
local TaskPoints = EscortGroup:GetTaskRoute()
|
||||
|
||||
@@ -967,25 +990,30 @@ function ESCORT:RegisterRoute()
|
||||
return TaskPoints
|
||||
end
|
||||
|
||||
--- @param Escort#ESCORT self
|
||||
function ESCORT:_FollowScheduler( FollowDistance )
|
||||
self:F( { FollowDistance })
|
||||
--- @param Functional.Escort#ESCORT self
|
||||
function ESCORT:_FollowScheduler()
|
||||
self:F( { self.FollowDistance } )
|
||||
|
||||
self:T( {self.EscortClient.UnitName, self.EscortGroup.GroupName } )
|
||||
if self.EscortGroup:IsAlive() and self.EscortClient:IsAlive() then
|
||||
|
||||
local ClientUnit = self.EscortClient:GetClientGroupUnit()
|
||||
local GroupUnit = self.EscortGroup:GetUnit( 1 )
|
||||
local FollowDistance = self.FollowDistance
|
||||
|
||||
self:T( {ClientUnit.UnitName, GroupUnit.UnitName } )
|
||||
|
||||
if self.CT1 == 0 and self.GT1 == 0 then
|
||||
self.CV1 = ClientUnit:GetPositionVec3()
|
||||
self.CV1 = ClientUnit:GetVec3()
|
||||
self:T( { "self.CV1", self.CV1 } )
|
||||
self.CT1 = timer.getTime()
|
||||
self.GV1 = GroupUnit:GetPositionVec3()
|
||||
self.GV1 = GroupUnit:GetVec3()
|
||||
self.GT1 = timer.getTime()
|
||||
else
|
||||
local CT1 = self.CT1
|
||||
local CT2 = timer.getTime()
|
||||
local CV1 = self.CV1
|
||||
local CV2 = ClientUnit:GetPositionVec3()
|
||||
local CV2 = ClientUnit:GetVec3()
|
||||
self.CT1 = CT2
|
||||
self.CV1 = CV2
|
||||
|
||||
@@ -999,7 +1027,7 @@ function ESCORT:_FollowScheduler( FollowDistance )
|
||||
local GT1 = self.GT1
|
||||
local GT2 = timer.getTime()
|
||||
local GV1 = self.GV1
|
||||
local GV2 = GroupUnit:GetPositionVec3()
|
||||
local GV2 = GroupUnit:GetVec3()
|
||||
self.GT1 = GT2
|
||||
self.GV1 = GV2
|
||||
|
||||
@@ -1036,6 +1064,11 @@ function ESCORT:_FollowScheduler( FollowDistance )
|
||||
|
||||
-- Now we can calculate the group destination vector GDV.
|
||||
local GDV = { x = DVu.x * CS * 8 + CVI.x, y = CVI.y, z = DVu.z * CS * 8 + CVI.z }
|
||||
|
||||
if self.SmokeDirectionVector == true then
|
||||
trigger.action.smoke( GDV, trigger.smokeColor.Red )
|
||||
end
|
||||
|
||||
self:T2( { "CV2:", CV2 } )
|
||||
self:T2( { "CVI:", CVI } )
|
||||
self:T2( { "GDV:", GDV } )
|
||||
@@ -1053,15 +1086,16 @@ function ESCORT:_FollowScheduler( FollowDistance )
|
||||
Speed = 0
|
||||
end
|
||||
|
||||
self:T( { "Client Speed, Escort Speed, Speed, FlyDistance, Time:", CS, GS, Speed, Distance, Time } )
|
||||
self:T( { "Client Speed, Escort Speed, Speed, FollowDistance, Time:", CS, GS, Speed, FollowDistance, Time } )
|
||||
|
||||
-- Now route the escort to the desired point with the desired speed.
|
||||
self.EscortGroup:TaskRouteToVec3( GDV, Speed / 3.6 ) -- DCS models speed in Mps (Miles per second)
|
||||
end
|
||||
else
|
||||
routines.removeFunction( self.FollowScheduler )
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
@@ -1082,7 +1116,7 @@ function ESCORT:_ReportTargetsScheduler()
|
||||
self:T( EscortObject )
|
||||
if EscortObject and EscortObject:isExist() and EscortObject.id_ < 50000000 then
|
||||
|
||||
local EscortTargetUnit = UNIT:New( EscortObject )
|
||||
local EscortTargetUnit = UNIT:Find( EscortObject )
|
||||
local EscortTargetUnitName = EscortTargetUnit:GetName()
|
||||
|
||||
|
||||
@@ -1105,11 +1139,11 @@ function ESCORT:_ReportTargetsScheduler()
|
||||
-- EscortTargetLastVelocity } )
|
||||
|
||||
|
||||
local EscortTargetUnitPositionVec3 = EscortTargetUnit:GetPositionVec3()
|
||||
local EscortPositionVec3 = self.EscortGroup:GetPositionVec3()
|
||||
local Distance = ( ( EscortTargetUnitPositionVec3.x - EscortPositionVec3.x )^2 +
|
||||
( EscortTargetUnitPositionVec3.y - EscortPositionVec3.y )^2 +
|
||||
( EscortTargetUnitPositionVec3.z - EscortPositionVec3.z )^2
|
||||
local EscortTargetUnitVec3 = EscortTargetUnit:GetVec3()
|
||||
local EscortVec3 = self.EscortGroup:GetVec3()
|
||||
local Distance = ( ( EscortTargetUnitVec3.x - EscortVec3.x )^2 +
|
||||
( EscortTargetUnitVec3.y - EscortVec3.y )^2 +
|
||||
( EscortTargetUnitVec3.z - EscortVec3.z )^2
|
||||
) ^ 0.5 / 1000
|
||||
|
||||
self:T( { self.EscortGroup:GetName(), EscortTargetUnit:GetName(), Distance, EscortTarget } )
|
||||
@@ -1164,11 +1198,11 @@ function ESCORT:_ReportTargetsScheduler()
|
||||
EscortTargetMessage = EscortTargetMessage .. "Unknown target at "
|
||||
end
|
||||
|
||||
local EscortTargetUnitPositionVec3 = ClientEscortTargetData.AttackUnit:GetPositionVec3()
|
||||
local EscortPositionVec3 = self.EscortGroup:GetPositionVec3()
|
||||
local Distance = ( ( EscortTargetUnitPositionVec3.x - EscortPositionVec3.x )^2 +
|
||||
( EscortTargetUnitPositionVec3.y - EscortPositionVec3.y )^2 +
|
||||
( EscortTargetUnitPositionVec3.z - EscortPositionVec3.z )^2
|
||||
local EscortTargetUnitVec3 = ClientEscortTargetData.AttackUnit:GetVec3()
|
||||
local EscortVec3 = self.EscortGroup:GetVec3()
|
||||
local Distance = ( ( EscortTargetUnitVec3.x - EscortVec3.x )^2 +
|
||||
( EscortTargetUnitVec3.y - EscortVec3.y )^2 +
|
||||
( EscortTargetUnitVec3.z - EscortVec3.z )^2
|
||||
) ^ 0.5 / 1000
|
||||
|
||||
self:T( { self.EscortGroup:GetName(), ClientEscortTargetData.AttackUnit:GetName(), Distance, ClientEscortTargetData.AttackUnit } )
|
||||
@@ -1232,16 +1266,16 @@ function ESCORT:_ReportTargetsScheduler()
|
||||
|
||||
local TaskPoints = self:RegisterRoute()
|
||||
for WayPointID, WayPoint in pairs( TaskPoints ) do
|
||||
local EscortPositionVec3 = self.EscortGroup:GetPositionVec3()
|
||||
local Distance = ( ( WayPoint.x - EscortPositionVec3.x )^2 +
|
||||
( WayPoint.y - EscortPositionVec3.z )^2
|
||||
local EscortVec3 = self.EscortGroup:GetVec3()
|
||||
local Distance = ( ( WayPoint.x - EscortVec3.x )^2 +
|
||||
( WayPoint.y - EscortVec3.z )^2
|
||||
) ^ 0.5 / 1000
|
||||
MENU_CLIENT_COMMAND:New( self.EscortClient, "Waypoint " .. WayPointID .. " at " .. string.format( "%.2f", Distance ).. "km", self.EscortMenuResumeMission, ESCORT._ResumeMission, { ParamSelf = self, ParamWayPoint = WayPointID } )
|
||||
end
|
||||
end
|
||||
|
||||
else
|
||||
routines.removeFunction( self.ReportTargetsScheduler )
|
||||
self.ReportTargetsScheduler = nil
|
||||
return true
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
706
Moose Development/Moose/Functional/MissileTrainer.lua
Normal file
706
Moose Development/Moose/Functional/MissileTrainer.lua
Normal file
@@ -0,0 +1,706 @@
|
||||
--- This module contains the MISSILETRAINER class.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- 1) @{MissileTrainer#MISSILETRAINER} class, extends @{Base#BASE}
|
||||
-- ===============================================================
|
||||
-- The @{#MISSILETRAINER} class uses the DCS world messaging system to be alerted of any missiles fired, and when a missile would hit your aircraft,
|
||||
-- the class will destroy the missile within a certain range, to avoid damage to your aircraft.
|
||||
-- It suports the following functionality:
|
||||
--
|
||||
-- * Track the missiles fired at you and other players, providing bearing and range information of the missiles towards the airplanes.
|
||||
-- * Provide alerts of missile launches, including detailed information of the units launching, including bearing, range <20>
|
||||
-- * Provide alerts when a missile would have killed your aircraft.
|
||||
-- * Provide alerts when the missile self destructs.
|
||||
-- * Enable / Disable and Configure the Missile Trainer using the various menu options.
|
||||
--
|
||||
-- When running a mission where MISSILETRAINER is used, the following radio menu structure ( 'Radio Menu' -> 'Other (F10)' -> 'MissileTrainer' ) options are available for the players:
|
||||
--
|
||||
-- * **Messages**: Menu to configure all messages.
|
||||
-- * **Messages On**: Show all messages.
|
||||
-- * **Messages Off**: Disable all messages.
|
||||
-- * **Tracking**: Menu to configure missile tracking messages.
|
||||
-- * **To All**: Shows missile tracking messages to all players.
|
||||
-- * **To Target**: Shows missile tracking messages only to the player where the missile is targetted at.
|
||||
-- * **Tracking On**: Show missile tracking messages.
|
||||
-- * **Tracking Off**: Disable missile tracking messages.
|
||||
-- * **Frequency Increase**: Increases the missile tracking message frequency with one second.
|
||||
-- * **Frequency Decrease**: Decreases the missile tracking message frequency with one second.
|
||||
-- * **Alerts**: Menu to configure alert messages.
|
||||
-- * **To All**: Shows alert messages to all players.
|
||||
-- * **To Target**: Shows alert messages only to the player where the missile is (was) targetted at.
|
||||
-- * **Hits On**: Show missile hit alert messages.
|
||||
-- * **Hits Off**: Disable missile hit alert messages.
|
||||
-- * **Launches On**: Show missile launch messages.
|
||||
-- * **Launches Off**: Disable missile launch messages.
|
||||
-- * **Details**: Menu to configure message details.
|
||||
-- * **Range On**: Shows range information when a missile is fired to a target.
|
||||
-- * **Range Off**: Disable range information when a missile is fired to a target.
|
||||
-- * **Bearing On**: Shows bearing information when a missile is fired to a target.
|
||||
-- * **Bearing Off**: Disable bearing information when a missile is fired to a target.
|
||||
-- * **Distance**: Menu to configure the distance when a missile needs to be destroyed when near to a player, during tracking. This will improve/influence hit calculation accuracy, but has the risk of damaging the aircraft when the missile reaches the aircraft before the distance is measured.
|
||||
-- * **50 meter**: Destroys the missile when the distance to the aircraft is below or equal to 50 meter.
|
||||
-- * **100 meter**: Destroys the missile when the distance to the aircraft is below or equal to 100 meter.
|
||||
-- * **150 meter**: Destroys the missile when the distance to the aircraft is below or equal to 150 meter.
|
||||
-- * **200 meter**: Destroys the missile when the distance to the aircraft is below or equal to 200 meter.
|
||||
--
|
||||
--
|
||||
-- 1.1) MISSILETRAINER construction methods:
|
||||
-- -----------------------------------------
|
||||
-- Create a new MISSILETRAINER object with the @{#MISSILETRAINER.New} method:
|
||||
--
|
||||
-- * @{#MISSILETRAINER.New}: Creates a new MISSILETRAINER object taking the maximum distance to your aircraft to evaluate when a missile needs to be destroyed.
|
||||
--
|
||||
-- MISSILETRAINER will collect each unit declared in the mission with a skill level "Client" and "Player", and will monitor the missiles shot at those.
|
||||
--
|
||||
-- 1.2) MISSILETRAINER initialization methods:
|
||||
-- -------------------------------------------
|
||||
-- A MISSILETRAINER object will behave differently based on the usage of initialization methods:
|
||||
--
|
||||
-- * @{#MISSILETRAINER.InitMessagesOnOff}: Sets by default the display of any message to be ON or OFF.
|
||||
-- * @{#MISSILETRAINER.InitTrackingToAll}: Sets by default the missile tracking report for all players or only for those missiles targetted to you.
|
||||
-- * @{#MISSILETRAINER.InitTrackingOnOff}: Sets by default the display of missile tracking report to be ON or OFF.
|
||||
-- * @{#MISSILETRAINER.InitTrackingFrequency}: Increases, decreases the missile tracking message display frequency with the provided time interval in seconds.
|
||||
-- * @{#MISSILETRAINER.InitAlertsToAll}: Sets by default the display of alerts to be shown to all players or only to you.
|
||||
-- * @{#MISSILETRAINER.InitAlertsHitsOnOff}: Sets by default the display of hit alerts ON or OFF.
|
||||
-- * @{#MISSILETRAINER.InitAlertsLaunchesOnOff}: Sets by default the display of launch alerts ON or OFF.
|
||||
-- * @{#MISSILETRAINER.InitRangeOnOff}: Sets by default the display of range information of missiles ON of OFF.
|
||||
-- * @{#MISSILETRAINER.InitBearingOnOff}: Sets by default the display of bearing information of missiles ON of OFF.
|
||||
-- * @{#MISSILETRAINER.InitMenusOnOff}: Allows to configure the options through the radio menu.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- CREDITS
|
||||
-- =======
|
||||
-- **Stuka (Danny)** Who you can search on the Eagle Dynamics Forums.
|
||||
-- Working together with Danny has resulted in the MISSILETRAINER class.
|
||||
-- Danny has shared his ideas and together we made a design.
|
||||
-- Together with the **476 virtual team**, we tested the MISSILETRAINER class, and got much positive feedback!
|
||||
--
|
||||
-- @module MissileTrainer
|
||||
-- @author FlightControl
|
||||
|
||||
|
||||
--- The MISSILETRAINER class
|
||||
-- @type MISSILETRAINER
|
||||
-- @field Core.Set#SET_CLIENT DBClients
|
||||
-- @extends Core.Base#BASE
|
||||
MISSILETRAINER = {
|
||||
ClassName = "MISSILETRAINER",
|
||||
TrackingMissiles = {},
|
||||
}
|
||||
|
||||
function MISSILETRAINER._Alive( Client, self )
|
||||
|
||||
if self.Briefing then
|
||||
Client:Message( self.Briefing, 15, "Trainer" )
|
||||
end
|
||||
|
||||
if self.MenusOnOff == true then
|
||||
Client:Message( "Use the 'Radio Menu' -> 'Other (F10)' -> 'Missile Trainer' menu options to change the Missile Trainer settings (for all players).", 15, "Trainer" )
|
||||
|
||||
Client.MainMenu = MENU_CLIENT:New( Client, "Missile Trainer", nil ) -- Menu#MENU_CLIENT
|
||||
|
||||
Client.MenuMessages = MENU_CLIENT:New( Client, "Messages", Client.MainMenu )
|
||||
Client.MenuOn = MENU_CLIENT_COMMAND:New( Client, "Messages On", Client.MenuMessages, self._MenuMessages, { MenuSelf = self, MessagesOnOff = true } )
|
||||
Client.MenuOff = MENU_CLIENT_COMMAND:New( Client, "Messages Off", Client.MenuMessages, self._MenuMessages, { MenuSelf = self, MessagesOnOff = false } )
|
||||
|
||||
Client.MenuTracking = MENU_CLIENT:New( Client, "Tracking", Client.MainMenu )
|
||||
Client.MenuTrackingToAll = MENU_CLIENT_COMMAND:New( Client, "To All", Client.MenuTracking, self._MenuMessages, { MenuSelf = self, TrackingToAll = true } )
|
||||
Client.MenuTrackingToTarget = MENU_CLIENT_COMMAND:New( Client, "To Target", Client.MenuTracking, self._MenuMessages, { MenuSelf = self, TrackingToAll = false } )
|
||||
Client.MenuTrackOn = MENU_CLIENT_COMMAND:New( Client, "Tracking On", Client.MenuTracking, self._MenuMessages, { MenuSelf = self, TrackingOnOff = true } )
|
||||
Client.MenuTrackOff = MENU_CLIENT_COMMAND:New( Client, "Tracking Off", Client.MenuTracking, self._MenuMessages, { MenuSelf = self, TrackingOnOff = false } )
|
||||
Client.MenuTrackIncrease = MENU_CLIENT_COMMAND:New( Client, "Frequency Increase", Client.MenuTracking, self._MenuMessages, { MenuSelf = self, TrackingFrequency = -1 } )
|
||||
Client.MenuTrackDecrease = MENU_CLIENT_COMMAND:New( Client, "Frequency Decrease", Client.MenuTracking, self._MenuMessages, { MenuSelf = self, TrackingFrequency = 1 } )
|
||||
|
||||
Client.MenuAlerts = MENU_CLIENT:New( Client, "Alerts", Client.MainMenu )
|
||||
Client.MenuAlertsToAll = MENU_CLIENT_COMMAND:New( Client, "To All", Client.MenuAlerts, self._MenuMessages, { MenuSelf = self, AlertsToAll = true } )
|
||||
Client.MenuAlertsToTarget = MENU_CLIENT_COMMAND:New( Client, "To Target", Client.MenuAlerts, self._MenuMessages, { MenuSelf = self, AlertsToAll = false } )
|
||||
Client.MenuHitsOn = MENU_CLIENT_COMMAND:New( Client, "Hits On", Client.MenuAlerts, self._MenuMessages, { MenuSelf = self, AlertsHitsOnOff = true } )
|
||||
Client.MenuHitsOff = MENU_CLIENT_COMMAND:New( Client, "Hits Off", Client.MenuAlerts, self._MenuMessages, { MenuSelf = self, AlertsHitsOnOff = false } )
|
||||
Client.MenuLaunchesOn = MENU_CLIENT_COMMAND:New( Client, "Launches On", Client.MenuAlerts, self._MenuMessages, { MenuSelf = self, AlertsLaunchesOnOff = true } )
|
||||
Client.MenuLaunchesOff = MENU_CLIENT_COMMAND:New( Client, "Launches Off", Client.MenuAlerts, self._MenuMessages, { MenuSelf = self, AlertsLaunchesOnOff = false } )
|
||||
|
||||
Client.MenuDetails = MENU_CLIENT:New( Client, "Details", Client.MainMenu )
|
||||
Client.MenuDetailsDistanceOn = MENU_CLIENT_COMMAND:New( Client, "Range On", Client.MenuDetails, self._MenuMessages, { MenuSelf = self, DetailsRangeOnOff = true } )
|
||||
Client.MenuDetailsDistanceOff = MENU_CLIENT_COMMAND:New( Client, "Range Off", Client.MenuDetails, self._MenuMessages, { MenuSelf = self, DetailsRangeOnOff = false } )
|
||||
Client.MenuDetailsBearingOn = MENU_CLIENT_COMMAND:New( Client, "Bearing On", Client.MenuDetails, self._MenuMessages, { MenuSelf = self, DetailsBearingOnOff = true } )
|
||||
Client.MenuDetailsBearingOff = MENU_CLIENT_COMMAND:New( Client, "Bearing Off", Client.MenuDetails, self._MenuMessages, { MenuSelf = self, DetailsBearingOnOff = false } )
|
||||
|
||||
Client.MenuDistance = MENU_CLIENT:New( Client, "Set distance to plane", Client.MainMenu )
|
||||
Client.MenuDistance50 = MENU_CLIENT_COMMAND:New( Client, "50 meter", Client.MenuDistance, self._MenuMessages, { MenuSelf = self, Distance = 50 / 1000 } )
|
||||
Client.MenuDistance100 = MENU_CLIENT_COMMAND:New( Client, "100 meter", Client.MenuDistance, self._MenuMessages, { MenuSelf = self, Distance = 100 / 1000 } )
|
||||
Client.MenuDistance150 = MENU_CLIENT_COMMAND:New( Client, "150 meter", Client.MenuDistance, self._MenuMessages, { MenuSelf = self, Distance = 150 / 1000 } )
|
||||
Client.MenuDistance200 = MENU_CLIENT_COMMAND:New( Client, "200 meter", Client.MenuDistance, self._MenuMessages, { MenuSelf = self, Distance = 200 / 1000 } )
|
||||
else
|
||||
if Client.MainMenu then
|
||||
Client.MainMenu:Remove()
|
||||
end
|
||||
end
|
||||
|
||||
local ClientID = Client:GetID()
|
||||
self:T( ClientID )
|
||||
if not self.TrackingMissiles[ClientID] then
|
||||
self.TrackingMissiles[ClientID] = {}
|
||||
end
|
||||
self.TrackingMissiles[ClientID].Client = Client
|
||||
if not self.TrackingMissiles[ClientID].MissileData then
|
||||
self.TrackingMissiles[ClientID].MissileData = {}
|
||||
end
|
||||
end
|
||||
|
||||
--- Creates the main object which is handling missile tracking.
|
||||
-- When a missile is fired a SCHEDULER is set off that follows the missile. When near a certain a client player, the missile will be destroyed.
|
||||
-- @param #MISSILETRAINER self
|
||||
-- @param #number Distance The distance in meters when a tracked missile needs to be destroyed when close to a player.
|
||||
-- @param #string Briefing (Optional) Will show a text to the players when starting their mission. Can be used for briefing purposes.
|
||||
-- @return #MISSILETRAINER
|
||||
function MISSILETRAINER:New( Distance, Briefing )
|
||||
local self = BASE:Inherit( self, BASE:New() )
|
||||
self:F( Distance )
|
||||
|
||||
if Briefing then
|
||||
self.Briefing = Briefing
|
||||
end
|
||||
|
||||
self.Schedulers = {}
|
||||
self.SchedulerID = 0
|
||||
|
||||
self.MessageInterval = 2
|
||||
self.MessageLastTime = timer.getTime()
|
||||
|
||||
self.Distance = Distance / 1000
|
||||
|
||||
_EVENTDISPATCHER:OnShot( self._EventShot, self )
|
||||
|
||||
self.DBClients = SET_CLIENT:New():FilterStart()
|
||||
|
||||
|
||||
-- for ClientID, Client in pairs( self.DBClients.Database ) do
|
||||
-- self:E( "ForEach:" .. Client.UnitName )
|
||||
-- Client:Alive( self._Alive, self )
|
||||
-- end
|
||||
--
|
||||
self.DBClients:ForEachClient(
|
||||
function( Client )
|
||||
self:E( "ForEach:" .. Client.UnitName )
|
||||
Client:Alive( self._Alive, self )
|
||||
end
|
||||
)
|
||||
|
||||
|
||||
|
||||
-- self.DB:ForEachClient(
|
||||
-- --- @param Wrapper.Client#CLIENT Client
|
||||
-- function( Client )
|
||||
--
|
||||
-- ... actions ...
|
||||
--
|
||||
-- end
|
||||
-- )
|
||||
|
||||
self.MessagesOnOff = true
|
||||
|
||||
self.TrackingToAll = false
|
||||
self.TrackingOnOff = true
|
||||
self.TrackingFrequency = 3
|
||||
|
||||
self.AlertsToAll = true
|
||||
self.AlertsHitsOnOff = true
|
||||
self.AlertsLaunchesOnOff = true
|
||||
|
||||
self.DetailsRangeOnOff = true
|
||||
self.DetailsBearingOnOff = true
|
||||
|
||||
self.MenusOnOff = true
|
||||
|
||||
self.TrackingMissiles = {}
|
||||
|
||||
self.TrackingScheduler = SCHEDULER:New( self, self._TrackMissiles, {}, 0.5, 0.05, 0 )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
-- Initialization methods.
|
||||
|
||||
|
||||
|
||||
--- Sets by default the display of any message to be ON or OFF.
|
||||
-- @param #MISSILETRAINER self
|
||||
-- @param #boolean MessagesOnOff true or false
|
||||
-- @return #MISSILETRAINER self
|
||||
function MISSILETRAINER:InitMessagesOnOff( MessagesOnOff )
|
||||
self:F( MessagesOnOff )
|
||||
|
||||
self.MessagesOnOff = MessagesOnOff
|
||||
if self.MessagesOnOff == true then
|
||||
MESSAGE:New( "Messages ON", 15, "Menu" ):ToAll()
|
||||
else
|
||||
MESSAGE:New( "Messages OFF", 15, "Menu" ):ToAll()
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Sets by default the missile tracking report for all players or only for those missiles targetted to you.
|
||||
-- @param #MISSILETRAINER self
|
||||
-- @param #boolean TrackingToAll true or false
|
||||
-- @return #MISSILETRAINER self
|
||||
function MISSILETRAINER:InitTrackingToAll( TrackingToAll )
|
||||
self:F( TrackingToAll )
|
||||
|
||||
self.TrackingToAll = TrackingToAll
|
||||
if self.TrackingToAll == true then
|
||||
MESSAGE:New( "Missile tracking to all players ON", 15, "Menu" ):ToAll()
|
||||
else
|
||||
MESSAGE:New( "Missile tracking to all players OFF", 15, "Menu" ):ToAll()
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Sets by default the display of missile tracking report to be ON or OFF.
|
||||
-- @param #MISSILETRAINER self
|
||||
-- @param #boolean TrackingOnOff true or false
|
||||
-- @return #MISSILETRAINER self
|
||||
function MISSILETRAINER:InitTrackingOnOff( TrackingOnOff )
|
||||
self:F( TrackingOnOff )
|
||||
|
||||
self.TrackingOnOff = TrackingOnOff
|
||||
if self.TrackingOnOff == true then
|
||||
MESSAGE:New( "Missile tracking ON", 15, "Menu" ):ToAll()
|
||||
else
|
||||
MESSAGE:New( "Missile tracking OFF", 15, "Menu" ):ToAll()
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Increases, decreases the missile tracking message display frequency with the provided time interval in seconds.
|
||||
-- The default frequency is a 3 second interval, so the Tracking Frequency parameter specifies the increase or decrease from the default 3 seconds or the last frequency update.
|
||||
-- @param #MISSILETRAINER self
|
||||
-- @param #number TrackingFrequency Provide a negative or positive value in seconds to incraese or decrease the display frequency.
|
||||
-- @return #MISSILETRAINER self
|
||||
function MISSILETRAINER:InitTrackingFrequency( TrackingFrequency )
|
||||
self:F( TrackingFrequency )
|
||||
|
||||
self.TrackingFrequency = self.TrackingFrequency + TrackingFrequency
|
||||
if self.TrackingFrequency < 0.5 then
|
||||
self.TrackingFrequency = 0.5
|
||||
end
|
||||
if self.TrackingFrequency then
|
||||
MESSAGE:New( "Missile tracking frequency is " .. self.TrackingFrequency .. " seconds.", 15, "Menu" ):ToAll()
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Sets by default the display of alerts to be shown to all players or only to you.
|
||||
-- @param #MISSILETRAINER self
|
||||
-- @param #boolean AlertsToAll true or false
|
||||
-- @return #MISSILETRAINER self
|
||||
function MISSILETRAINER:InitAlertsToAll( AlertsToAll )
|
||||
self:F( AlertsToAll )
|
||||
|
||||
self.AlertsToAll = AlertsToAll
|
||||
if self.AlertsToAll == true then
|
||||
MESSAGE:New( "Alerts to all players ON", 15, "Menu" ):ToAll()
|
||||
else
|
||||
MESSAGE:New( "Alerts to all players OFF", 15, "Menu" ):ToAll()
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Sets by default the display of hit alerts ON or OFF.
|
||||
-- @param #MISSILETRAINER self
|
||||
-- @param #boolean AlertsHitsOnOff true or false
|
||||
-- @return #MISSILETRAINER self
|
||||
function MISSILETRAINER:InitAlertsHitsOnOff( AlertsHitsOnOff )
|
||||
self:F( AlertsHitsOnOff )
|
||||
|
||||
self.AlertsHitsOnOff = AlertsHitsOnOff
|
||||
if self.AlertsHitsOnOff == true then
|
||||
MESSAGE:New( "Alerts Hits ON", 15, "Menu" ):ToAll()
|
||||
else
|
||||
MESSAGE:New( "Alerts Hits OFF", 15, "Menu" ):ToAll()
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Sets by default the display of launch alerts ON or OFF.
|
||||
-- @param #MISSILETRAINER self
|
||||
-- @param #boolean AlertsLaunchesOnOff true or false
|
||||
-- @return #MISSILETRAINER self
|
||||
function MISSILETRAINER:InitAlertsLaunchesOnOff( AlertsLaunchesOnOff )
|
||||
self:F( AlertsLaunchesOnOff )
|
||||
|
||||
self.AlertsLaunchesOnOff = AlertsLaunchesOnOff
|
||||
if self.AlertsLaunchesOnOff == true then
|
||||
MESSAGE:New( "Alerts Launches ON", 15, "Menu" ):ToAll()
|
||||
else
|
||||
MESSAGE:New( "Alerts Launches OFF", 15, "Menu" ):ToAll()
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Sets by default the display of range information of missiles ON of OFF.
|
||||
-- @param #MISSILETRAINER self
|
||||
-- @param #boolean DetailsRangeOnOff true or false
|
||||
-- @return #MISSILETRAINER self
|
||||
function MISSILETRAINER:InitRangeOnOff( DetailsRangeOnOff )
|
||||
self:F( DetailsRangeOnOff )
|
||||
|
||||
self.DetailsRangeOnOff = DetailsRangeOnOff
|
||||
if self.DetailsRangeOnOff == true then
|
||||
MESSAGE:New( "Range display ON", 15, "Menu" ):ToAll()
|
||||
else
|
||||
MESSAGE:New( "Range display OFF", 15, "Menu" ):ToAll()
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Sets by default the display of bearing information of missiles ON of OFF.
|
||||
-- @param #MISSILETRAINER self
|
||||
-- @param #boolean DetailsBearingOnOff true or false
|
||||
-- @return #MISSILETRAINER self
|
||||
function MISSILETRAINER:InitBearingOnOff( DetailsBearingOnOff )
|
||||
self:F( DetailsBearingOnOff )
|
||||
|
||||
self.DetailsBearingOnOff = DetailsBearingOnOff
|
||||
if self.DetailsBearingOnOff == true then
|
||||
MESSAGE:New( "Bearing display OFF", 15, "Menu" ):ToAll()
|
||||
else
|
||||
MESSAGE:New( "Bearing display OFF", 15, "Menu" ):ToAll()
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Enables / Disables the menus.
|
||||
-- @param #MISSILETRAINER self
|
||||
-- @param #boolean MenusOnOff true or false
|
||||
-- @return #MISSILETRAINER self
|
||||
function MISSILETRAINER:InitMenusOnOff( MenusOnOff )
|
||||
self:F( MenusOnOff )
|
||||
|
||||
self.MenusOnOff = MenusOnOff
|
||||
if self.MenusOnOff == true then
|
||||
MESSAGE:New( "Menus are ENABLED (only when a player rejoins a slot)", 15, "Menu" ):ToAll()
|
||||
else
|
||||
MESSAGE:New( "Menus are DISABLED", 15, "Menu" ):ToAll()
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
-- Menu functions
|
||||
|
||||
function MISSILETRAINER._MenuMessages( MenuParameters )
|
||||
|
||||
local self = MenuParameters.MenuSelf
|
||||
|
||||
if MenuParameters.MessagesOnOff ~= nil then
|
||||
self:InitMessagesOnOff( MenuParameters.MessagesOnOff )
|
||||
end
|
||||
|
||||
if MenuParameters.TrackingToAll ~= nil then
|
||||
self:InitTrackingToAll( MenuParameters.TrackingToAll )
|
||||
end
|
||||
|
||||
if MenuParameters.TrackingOnOff ~= nil then
|
||||
self:InitTrackingOnOff( MenuParameters.TrackingOnOff )
|
||||
end
|
||||
|
||||
if MenuParameters.TrackingFrequency ~= nil then
|
||||
self:InitTrackingFrequency( MenuParameters.TrackingFrequency )
|
||||
end
|
||||
|
||||
if MenuParameters.AlertsToAll ~= nil then
|
||||
self:InitAlertsToAll( MenuParameters.AlertsToAll )
|
||||
end
|
||||
|
||||
if MenuParameters.AlertsHitsOnOff ~= nil then
|
||||
self:InitAlertsHitsOnOff( MenuParameters.AlertsHitsOnOff )
|
||||
end
|
||||
|
||||
if MenuParameters.AlertsLaunchesOnOff ~= nil then
|
||||
self:InitAlertsLaunchesOnOff( MenuParameters.AlertsLaunchesOnOff )
|
||||
end
|
||||
|
||||
if MenuParameters.DetailsRangeOnOff ~= nil then
|
||||
self:InitRangeOnOff( MenuParameters.DetailsRangeOnOff )
|
||||
end
|
||||
|
||||
if MenuParameters.DetailsBearingOnOff ~= nil then
|
||||
self:InitBearingOnOff( MenuParameters.DetailsBearingOnOff )
|
||||
end
|
||||
|
||||
if MenuParameters.Distance ~= nil then
|
||||
self.Distance = MenuParameters.Distance
|
||||
MESSAGE:New( "Hit detection distance set to " .. self.Distance .. " meters", 15, "Menu" ):ToAll()
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--- Detects if an SA site was shot with an anti radiation missile. In this case, take evasive actions based on the skill level set within the ME.
|
||||
-- @param #MISSILETRAINER self
|
||||
-- @param Core.Event#EVENTDATA Event
|
||||
function MISSILETRAINER:_EventShot( Event )
|
||||
self:F( { Event } )
|
||||
|
||||
local TrainerSourceDCSUnit = Event.IniDCSUnit
|
||||
local TrainerSourceDCSUnitName = Event.IniDCSUnitName
|
||||
local TrainerWeapon = Event.Weapon -- Identify the weapon fired
|
||||
local TrainerWeaponName = Event.WeaponName -- return weapon type
|
||||
|
||||
self:T( "Missile Launched = " .. TrainerWeaponName )
|
||||
|
||||
local TrainerTargetDCSUnit = TrainerWeapon:getTarget() -- Identify target
|
||||
if TrainerTargetDCSUnit then
|
||||
local TrainerTargetDCSUnitName = Unit.getName( TrainerTargetDCSUnit )
|
||||
local TrainerTargetSkill = _DATABASE.Templates.Units[TrainerTargetDCSUnitName].Template.skill
|
||||
|
||||
self:T(TrainerTargetDCSUnitName )
|
||||
|
||||
local Client = self.DBClients:FindClient( TrainerTargetDCSUnitName )
|
||||
if Client then
|
||||
|
||||
local TrainerSourceUnit = UNIT:Find( TrainerSourceDCSUnit )
|
||||
local TrainerTargetUnit = UNIT:Find( TrainerTargetDCSUnit )
|
||||
|
||||
if self.MessagesOnOff == true and self.AlertsLaunchesOnOff == true then
|
||||
|
||||
local Message = MESSAGE:New(
|
||||
string.format( "%s launched a %s",
|
||||
TrainerSourceUnit:GetTypeName(),
|
||||
TrainerWeaponName
|
||||
) .. self:_AddRange( Client, TrainerWeapon ) .. self:_AddBearing( Client, TrainerWeapon ), 5, "Launch Alert" )
|
||||
|
||||
if self.AlertsToAll then
|
||||
Message:ToAll()
|
||||
else
|
||||
Message:ToClient( Client )
|
||||
end
|
||||
end
|
||||
|
||||
local ClientID = Client:GetID()
|
||||
self:T( ClientID )
|
||||
local MissileData = {}
|
||||
MissileData.TrainerSourceUnit = TrainerSourceUnit
|
||||
MissileData.TrainerWeapon = TrainerWeapon
|
||||
MissileData.TrainerTargetUnit = TrainerTargetUnit
|
||||
MissileData.TrainerWeaponTypeName = TrainerWeapon:getTypeName()
|
||||
MissileData.TrainerWeaponLaunched = true
|
||||
table.insert( self.TrackingMissiles[ClientID].MissileData, MissileData )
|
||||
--self:T( self.TrackingMissiles )
|
||||
end
|
||||
else
|
||||
-- TODO: some weapons don't know the target unit... Need to develop a workaround for this.
|
||||
if ( TrainerWeapon:getTypeName() == "9M311" ) then
|
||||
SCHEDULER:New( TrainerWeapon, TrainerWeapon.destroy, {}, 1 )
|
||||
else
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function MISSILETRAINER:_AddRange( Client, TrainerWeapon )
|
||||
|
||||
local RangeText = ""
|
||||
|
||||
if self.DetailsRangeOnOff then
|
||||
|
||||
local PositionMissile = TrainerWeapon:getPoint()
|
||||
local TargetVec3 = Client:GetVec3()
|
||||
|
||||
local Range = ( ( PositionMissile.x - TargetVec3.x )^2 +
|
||||
( PositionMissile.y - TargetVec3.y )^2 +
|
||||
( PositionMissile.z - TargetVec3.z )^2
|
||||
) ^ 0.5 / 1000
|
||||
|
||||
RangeText = string.format( ", at %4.2fkm", Range )
|
||||
end
|
||||
|
||||
return RangeText
|
||||
end
|
||||
|
||||
function MISSILETRAINER:_AddBearing( Client, TrainerWeapon )
|
||||
|
||||
local BearingText = ""
|
||||
|
||||
if self.DetailsBearingOnOff then
|
||||
|
||||
local PositionMissile = TrainerWeapon:getPoint()
|
||||
local TargetVec3 = Client:GetVec3()
|
||||
|
||||
self:T2( { TargetVec3, PositionMissile })
|
||||
|
||||
local DirectionVector = { x = PositionMissile.x - TargetVec3.x, y = PositionMissile.y - TargetVec3.y, z = PositionMissile.z - TargetVec3.z }
|
||||
local DirectionRadians = math.atan2( DirectionVector.z, DirectionVector.x )
|
||||
--DirectionRadians = DirectionRadians + routines.getNorthCorrection( PositionTarget )
|
||||
if DirectionRadians < 0 then
|
||||
DirectionRadians = DirectionRadians + 2 * math.pi
|
||||
end
|
||||
local DirectionDegrees = DirectionRadians * 180 / math.pi
|
||||
|
||||
BearingText = string.format( ", %d degrees", DirectionDegrees )
|
||||
end
|
||||
|
||||
return BearingText
|
||||
end
|
||||
|
||||
|
||||
function MISSILETRAINER:_TrackMissiles()
|
||||
self:F2()
|
||||
|
||||
|
||||
local ShowMessages = false
|
||||
if self.MessagesOnOff and self.MessageLastTime + self.TrackingFrequency <= timer.getTime() then
|
||||
self.MessageLastTime = timer.getTime()
|
||||
ShowMessages = true
|
||||
end
|
||||
|
||||
-- ALERTS PART
|
||||
|
||||
-- Loop for all Player Clients to check the alerts and deletion of missiles.
|
||||
for ClientDataID, ClientData in pairs( self.TrackingMissiles ) do
|
||||
|
||||
local Client = ClientData.Client
|
||||
self:T2( { Client:GetName() } )
|
||||
|
||||
for MissileDataID, MissileData in pairs( ClientData.MissileData ) do
|
||||
self:T3( MissileDataID )
|
||||
|
||||
local TrainerSourceUnit = MissileData.TrainerSourceUnit
|
||||
local TrainerWeapon = MissileData.TrainerWeapon
|
||||
local TrainerTargetUnit = MissileData.TrainerTargetUnit
|
||||
local TrainerWeaponTypeName = MissileData.TrainerWeaponTypeName
|
||||
local TrainerWeaponLaunched = MissileData.TrainerWeaponLaunched
|
||||
|
||||
if Client and Client:IsAlive() and TrainerSourceUnit and TrainerSourceUnit:IsAlive() and TrainerWeapon and TrainerWeapon:isExist() and TrainerTargetUnit and TrainerTargetUnit:IsAlive() then
|
||||
local PositionMissile = TrainerWeapon:getPosition().p
|
||||
local TargetVec3 = Client:GetVec3()
|
||||
|
||||
local Distance = ( ( PositionMissile.x - TargetVec3.x )^2 +
|
||||
( PositionMissile.y - TargetVec3.y )^2 +
|
||||
( PositionMissile.z - TargetVec3.z )^2
|
||||
) ^ 0.5 / 1000
|
||||
|
||||
if Distance <= self.Distance then
|
||||
-- Hit alert
|
||||
TrainerWeapon:destroy()
|
||||
if self.MessagesOnOff == true and self.AlertsHitsOnOff == true then
|
||||
|
||||
self:T( "killed" )
|
||||
|
||||
local Message = MESSAGE:New(
|
||||
string.format( "%s launched by %s killed %s",
|
||||
TrainerWeapon:getTypeName(),
|
||||
TrainerSourceUnit:GetTypeName(),
|
||||
TrainerTargetUnit:GetPlayerName()
|
||||
), 15, "Hit Alert" )
|
||||
|
||||
if self.AlertsToAll == true then
|
||||
Message:ToAll()
|
||||
else
|
||||
Message:ToClient( Client )
|
||||
end
|
||||
|
||||
MissileData = nil
|
||||
table.remove( ClientData.MissileData, MissileDataID )
|
||||
self:T(ClientData.MissileData)
|
||||
end
|
||||
end
|
||||
else
|
||||
if not ( TrainerWeapon and TrainerWeapon:isExist() ) then
|
||||
if self.MessagesOnOff == true and self.AlertsLaunchesOnOff == true then
|
||||
-- Weapon does not exist anymore. Delete from Table
|
||||
local Message = MESSAGE:New(
|
||||
string.format( "%s launched by %s self destructed!",
|
||||
TrainerWeaponTypeName,
|
||||
TrainerSourceUnit:GetTypeName()
|
||||
), 5, "Tracking" )
|
||||
|
||||
if self.AlertsToAll == true then
|
||||
Message:ToAll()
|
||||
else
|
||||
Message:ToClient( Client )
|
||||
end
|
||||
end
|
||||
MissileData = nil
|
||||
table.remove( ClientData.MissileData, MissileDataID )
|
||||
self:T( ClientData.MissileData )
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if ShowMessages == true and self.MessagesOnOff == true and self.TrackingOnOff == true then -- Only do this when tracking information needs to be displayed.
|
||||
|
||||
-- TRACKING PART
|
||||
|
||||
-- For the current client, the missile range and bearing details are displayed To the Player Client.
|
||||
-- For the other clients, the missile range and bearing details are displayed To the other Player Clients.
|
||||
-- To achieve this, a cross loop is done for each Player Client <-> Other Player Client missile information.
|
||||
|
||||
-- Main Player Client loop
|
||||
for ClientDataID, ClientData in pairs( self.TrackingMissiles ) do
|
||||
|
||||
local Client = ClientData.Client
|
||||
self:T2( { Client:GetName() } )
|
||||
|
||||
|
||||
ClientData.MessageToClient = ""
|
||||
ClientData.MessageToAll = ""
|
||||
|
||||
-- Other Players Client loop
|
||||
for TrackingDataID, TrackingData in pairs( self.TrackingMissiles ) do
|
||||
|
||||
for MissileDataID, MissileData in pairs( TrackingData.MissileData ) do
|
||||
self:T3( MissileDataID )
|
||||
|
||||
local TrainerSourceUnit = MissileData.TrainerSourceUnit
|
||||
local TrainerWeapon = MissileData.TrainerWeapon
|
||||
local TrainerTargetUnit = MissileData.TrainerTargetUnit
|
||||
local TrainerWeaponTypeName = MissileData.TrainerWeaponTypeName
|
||||
local TrainerWeaponLaunched = MissileData.TrainerWeaponLaunched
|
||||
|
||||
if Client and Client:IsAlive() and TrainerSourceUnit and TrainerSourceUnit:IsAlive() and TrainerWeapon and TrainerWeapon:isExist() and TrainerTargetUnit and TrainerTargetUnit:IsAlive() then
|
||||
|
||||
if ShowMessages == true then
|
||||
local TrackingTo
|
||||
TrackingTo = string.format( " -> %s",
|
||||
TrainerWeaponTypeName
|
||||
)
|
||||
|
||||
if ClientDataID == TrackingDataID then
|
||||
if ClientData.MessageToClient == "" then
|
||||
ClientData.MessageToClient = "Missiles to You:\n"
|
||||
end
|
||||
ClientData.MessageToClient = ClientData.MessageToClient .. TrackingTo .. self:_AddRange( ClientData.Client, TrainerWeapon ) .. self:_AddBearing( ClientData.Client, TrainerWeapon ) .. "\n"
|
||||
else
|
||||
if self.TrackingToAll == true then
|
||||
if ClientData.MessageToAll == "" then
|
||||
ClientData.MessageToAll = "Missiles to other Players:\n"
|
||||
end
|
||||
ClientData.MessageToAll = ClientData.MessageToAll .. TrackingTo .. self:_AddRange( ClientData.Client, TrainerWeapon ) .. self:_AddBearing( ClientData.Client, TrainerWeapon ) .. " ( " .. TrainerTargetUnit:GetPlayerName() .. " )\n"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Once the Player Client and the Other Player Client tracking messages are prepared, show them.
|
||||
if ClientData.MessageToClient ~= "" or ClientData.MessageToAll ~= "" then
|
||||
local Message = MESSAGE:New( ClientData.MessageToClient .. ClientData.MessageToAll, 1, "Tracking" ):ToClient( Client )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
@@ -5,8 +5,6 @@
|
||||
-- on defined intervals (currently every minute).
|
||||
-- @module MOVEMENT
|
||||
|
||||
Include.File( "Routines" )
|
||||
|
||||
--- the MOVEMENT class
|
||||
-- @type
|
||||
MOVEMENT = {
|
||||
@@ -49,7 +47,8 @@ end
|
||||
--- Call this function to start the MOVEMENT scheduling.
|
||||
function MOVEMENT:ScheduleStart()
|
||||
self:F()
|
||||
self.MoveFunction = routines.scheduleFunction( self._Scheduler, { self }, timer.getTime() + 1, 120 )
|
||||
--self.MoveFunction = routines.scheduleFunction( self._Scheduler, { self }, timer.getTime() + 1, 120 )
|
||||
self.MoveFunction = SCHEDULER:New( self, self._Scheduler, {}, 1, 120 )
|
||||
end
|
||||
|
||||
--- Call this function to stop the MOVEMENT scheduling.
|
||||
@@ -125,4 +124,5 @@ function MOVEMENT:_Scheduler()
|
||||
end
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
1628
Moose Development/Moose/Functional/Scoring.lua
Normal file
1628
Moose Development/Moose/Functional/Scoring.lua
Normal file
File diff suppressed because it is too large
Load Diff
@@ -3,16 +3,9 @@
|
||||
-- @author to be searched on the forum
|
||||
-- @author (co) Flightcontrol (Modified and enriched with functionality)
|
||||
|
||||
Include.File( "Routines" )
|
||||
Include.File( "Event" )
|
||||
Include.File( "Base" )
|
||||
Include.File( "Mission" )
|
||||
Include.File( "Client" )
|
||||
Include.File( "Task" )
|
||||
|
||||
--- The SEAD class
|
||||
-- @type SEAD
|
||||
-- @extends Base#BASE
|
||||
-- @extends Core.Base#BASE
|
||||
SEAD = {
|
||||
ClassName = "SEAD",
|
||||
TargetSkill = {
|
||||
@@ -57,7 +50,6 @@ function SEAD:EventShot( Event )
|
||||
local SEADUnitName = Event.IniDCSUnitName
|
||||
local SEADWeapon = Event.Weapon -- Identify the weapon fired
|
||||
local SEADWeaponName = Event.WeaponName -- return weapon type
|
||||
--trigger.action.outText( string.format("Alerte, depart missile " ..string.format(SEADWeaponName)), 20) --debug message
|
||||
-- Start of the 2nd loop
|
||||
self:T( "Missile Launched = " .. SEADWeaponName )
|
||||
if SEADWeaponName == "KH-58" or SEADWeaponName == "KH-25MPU" or SEADWeaponName == "AGM-88" or SEADWeaponName == "KH-31A" or SEADWeaponName == "KH-31P" then -- Check if the missile is a SEAD
|
||||
@@ -67,7 +59,7 @@ function SEAD:EventShot( Event )
|
||||
local _targetMimgroup = Unit.getGroup(Weapon.getTarget(SEADWeapon))
|
||||
local _targetMimgroupName = _targetMimgroup:getName()
|
||||
local _targetMimcont= _targetMimgroup:getController()
|
||||
local _targetskill = _DATABASE.Units[_targetMimname].Template.skill
|
||||
local _targetskill = _DATABASE.Templates.Units[_targetMimname].Template.skill
|
||||
self:T( self.SEADGroupPrefixes )
|
||||
self:T( _targetMimgroupName )
|
||||
local SEADGroupFound = false
|
||||
@@ -83,10 +75,10 @@ function SEAD:EventShot( Event )
|
||||
local Skills = { "Average", "Good", "High", "Excellent" }
|
||||
_targetskill = Skills[ math.random(1,4) ]
|
||||
end
|
||||
self:T( _targetskill ) -- debug message for skill check
|
||||
self:T( _targetskill )
|
||||
if self.TargetSkill[_targetskill] then
|
||||
if (_evade > self.TargetSkill[_targetskill].Evade) then
|
||||
self:T( string.format("Evading, target skill " ..string.format(_targetskill)) ) --debug message
|
||||
self:T( string.format("Evading, target skill " ..string.format(_targetskill)) )
|
||||
local _targetMim = Weapon.getTarget(SEADWeapon)
|
||||
local _targetMimname = Unit.getName(_targetMim)
|
||||
local _targetMimgroup = Unit.getGroup(Weapon.getTarget(SEADWeapon))
|
||||
File diff suppressed because it is too large
Load Diff
77
Moose Development/Moose/Moose.lua
Normal file
77
Moose Development/Moose/Moose.lua
Normal file
@@ -0,0 +1,77 @@
|
||||
--- The main include file for the MOOSE system.
|
||||
|
||||
--- Core Routines
|
||||
Include.File( "Utilities/Routines" )
|
||||
Include.File( "Utilities/Utils" )
|
||||
|
||||
--- Core Classes
|
||||
Include.File( "Core/Base" )
|
||||
Include.File( "Core/Scheduler" )
|
||||
Include.File( "Core/ScheduleDispatcher")
|
||||
Include.File( "Core/Event" )
|
||||
Include.File( "Core/Menu" )
|
||||
Include.File( "Core/Zone" )
|
||||
Include.File( "Core/Database" )
|
||||
Include.File( "Core/Set" )
|
||||
Include.File( "Core/Point" )
|
||||
Include.File( "Core/Message" )
|
||||
Include.File( "Core/Fsm" )
|
||||
|
||||
--- Wrapper Classes
|
||||
Include.File( "Wrapper/Object" )
|
||||
Include.File( "Wrapper/Identifiable" )
|
||||
Include.File( "Wrapper/Positionable" )
|
||||
Include.File( "Wrapper/Controllable" )
|
||||
Include.File( "Wrapper/Group" )
|
||||
Include.File( "Wrapper/Unit" )
|
||||
Include.File( "Wrapper/Client" )
|
||||
Include.File( "Wrapper/Static" )
|
||||
Include.File( "Wrapper/Airbase" )
|
||||
Include.File( "Wrapper/Scenery" )
|
||||
|
||||
--- Functional Classes
|
||||
Include.File( "Functional/Scoring" )
|
||||
Include.File( "Functional/CleanUp" )
|
||||
Include.File( "Functional/Spawn" )
|
||||
Include.File( "Functional/Movement" )
|
||||
Include.File( "Functional/Sead" )
|
||||
Include.File( "Functional/Escort" )
|
||||
Include.File( "Functional/MissileTrainer" )
|
||||
Include.File( "Functional/AirbasePolice" )
|
||||
Include.File( "Functional/Detection" )
|
||||
|
||||
--- AI Classes
|
||||
Include.File( "AI/AI_Balancer" )
|
||||
Include.File( "AI/AI_Patrol" )
|
||||
Include.File( "AI/AI_Cap" )
|
||||
Include.File( "AI/AI_Cas" )
|
||||
Include.File( "AI/AI_Cargo" )
|
||||
|
||||
--- Actions
|
||||
Include.File( "Actions/Act_Assign" )
|
||||
Include.File( "Actions/Act_Route" )
|
||||
Include.File( "Actions/Act_Account" )
|
||||
Include.File( "Actions/Act_Assist" )
|
||||
|
||||
--- Task Handling Classes
|
||||
Include.File( "Tasking/CommandCenter" )
|
||||
Include.File( "Tasking/Mission" )
|
||||
Include.File( "Tasking/Task" )
|
||||
Include.File( "Tasking/DetectionManager" )
|
||||
Include.File( "Tasking/Task_SEAD" )
|
||||
Include.File( "Tasking/Task_A2G" )
|
||||
|
||||
|
||||
-- The order of the declarations is important here. Don't touch it.
|
||||
|
||||
--- Declare the event dispatcher based on the EVENT class
|
||||
_EVENTDISPATCHER = EVENT:New() -- Core.Event#EVENT
|
||||
|
||||
--- Declare the timer dispatcher based on the SCHEDULEDISPATCHER class
|
||||
_SCHEDULEDISPATCHER = SCHEDULEDISPATCHER:New() -- Core.Timer#SCHEDULEDISPATCHER
|
||||
|
||||
--- Declare the main database object, which is used internally by the MOOSE classes.
|
||||
_DATABASE = DATABASE:New() -- Database#DATABASE
|
||||
|
||||
|
||||
|
||||
282
Moose Development/Moose/Tasking/CommandCenter.lua
Normal file
282
Moose Development/Moose/Tasking/CommandCenter.lua
Normal file
@@ -0,0 +1,282 @@
|
||||
--- A COMMANDCENTER is the owner of multiple missions within MOOSE.
|
||||
-- A COMMANDCENTER governs multiple missions, the tasking and the reporting.
|
||||
-- @module CommandCenter
|
||||
|
||||
|
||||
|
||||
--- The REPORT class
|
||||
-- @type REPORT
|
||||
-- @extends Core.Base#BASE
|
||||
REPORT = {
|
||||
ClassName = "REPORT",
|
||||
}
|
||||
|
||||
--- Create a new REPORT.
|
||||
-- @param #REPORT self
|
||||
-- @param #string Title
|
||||
-- @return #REPORT
|
||||
function REPORT:New( Title )
|
||||
|
||||
local self = BASE:Inherit( self, BASE:New() )
|
||||
|
||||
self.Report = {}
|
||||
self.Report[#self.Report+1] = Title
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Add a new line to a REPORT.
|
||||
-- @param #REPORT self
|
||||
-- @param #string Text
|
||||
-- @return #REPORT
|
||||
function REPORT:Add( Text )
|
||||
self.Report[#self.Report+1] = Text
|
||||
return self.Report[#self.Report+1]
|
||||
end
|
||||
|
||||
function REPORT:Text()
|
||||
return table.concat( self.Report, "\n" )
|
||||
end
|
||||
|
||||
--- The COMMANDCENTER class
|
||||
-- @type COMMANDCENTER
|
||||
-- @field Wrapper.Group#GROUP HQ
|
||||
-- @field Dcs.DCSCoalitionWrapper.Object#coalition CommandCenterCoalition
|
||||
-- @list<Tasking.Mission#MISSION> Missions
|
||||
-- @extends Core.Base#BASE
|
||||
COMMANDCENTER = {
|
||||
ClassName = "COMMANDCENTER",
|
||||
CommandCenterName = "",
|
||||
CommandCenterCoalition = nil,
|
||||
CommandCenterPositionable = nil,
|
||||
Name = "",
|
||||
}
|
||||
--- The constructor takes an IDENTIFIABLE as the HQ command center.
|
||||
-- @param #COMMANDCENTER self
|
||||
-- @param Wrapper.Positionable#POSITIONABLE CommandCenterPositionable
|
||||
-- @param #string CommandCenterName
|
||||
-- @return #COMMANDCENTER
|
||||
function COMMANDCENTER:New( CommandCenterPositionable, CommandCenterName )
|
||||
|
||||
local self = BASE:Inherit( self, BASE:New() )
|
||||
|
||||
self.CommandCenterPositionable = CommandCenterPositionable
|
||||
self.CommandCenterName = CommandCenterName or CommandCenterPositionable:GetName()
|
||||
self.CommandCenterCoalition = CommandCenterPositionable:GetCoalition()
|
||||
|
||||
self.Missions = {}
|
||||
|
||||
self:HandleEvent( EVENTS.Birth,
|
||||
--- @param #COMMANDCENTER self
|
||||
--- @param Core.Event#EVENTDATA EventData
|
||||
function( self, EventData )
|
||||
self:E( { EventData } )
|
||||
local EventGroup = GROUP:Find( EventData.IniDCSGroup )
|
||||
if EventGroup and self:HasGroup( EventGroup ) then
|
||||
local MenuReporting = MENU_GROUP:New( EventGroup, "Reporting", self.CommandCenterMenu )
|
||||
local MenuMissionsSummary = MENU_GROUP_COMMAND:New( EventGroup, "Missions Summary Report", MenuReporting, self.ReportSummary, self, EventGroup )
|
||||
local MenuMissionsDetails = MENU_GROUP_COMMAND:New( EventGroup, "Missions Details Report", MenuReporting, self.ReportDetails, self, EventGroup )
|
||||
self:ReportSummary( EventGroup )
|
||||
end
|
||||
local PlayerUnit = EventData.IniUnit
|
||||
for MissionID, Mission in pairs( self:GetMissions() ) do
|
||||
local Mission = Mission -- Tasking.Mission#MISSION
|
||||
local PlayerGroup = EventData.IniGroup -- The GROUP object should be filled!
|
||||
Mission:JoinUnit( PlayerUnit, PlayerGroup )
|
||||
Mission:ReportDetails()
|
||||
end
|
||||
|
||||
end
|
||||
)
|
||||
|
||||
-- When a player enters a client or a unit, the CommandCenter will check for each Mission and each Task in the Mission if the player has things to do.
|
||||
-- For these elements, it will=
|
||||
-- - Set the correct menu.
|
||||
-- - Assign the PlayerUnit to the Task if required.
|
||||
-- - Send a message to the other players in the group that this player has joined.
|
||||
self:HandleEvent( EVENTS.PlayerEnterUnit,
|
||||
--- @param #COMMANDCENTER self
|
||||
-- @param Core.Event#EVENTDATA EventData
|
||||
function( self, EventData )
|
||||
local PlayerUnit = EventData.IniUnit
|
||||
for MissionID, Mission in pairs( self:GetMissions() ) do
|
||||
local Mission = Mission -- Tasking.Mission#MISSION
|
||||
local PlayerGroup = EventData.IniGroup -- The GROUP object should be filled!
|
||||
Mission:JoinUnit( PlayerUnit, PlayerGroup )
|
||||
Mission:ReportDetails()
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
-- Handle when a player leaves a slot and goes back to spectators ...
|
||||
-- The PlayerUnit will be UnAssigned from the Task.
|
||||
-- When there is no Unit left running the Task, the Task goes into Abort...
|
||||
self:HandleEvent( EVENTS.PlayerLeaveUnit,
|
||||
--- @param #TASK self
|
||||
-- @param Core.Event#EVENTDATA EventData
|
||||
function( self, EventData )
|
||||
local PlayerUnit = EventData.IniUnit
|
||||
for MissionID, Mission in pairs( self:GetMissions() ) do
|
||||
local Mission = Mission -- Tasking.Mission#MISSION
|
||||
Mission:AbortUnit( PlayerUnit )
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
-- Handle when a player leaves a slot and goes back to spectators ...
|
||||
-- The PlayerUnit will be UnAssigned from the Task.
|
||||
-- When there is no Unit left running the Task, the Task goes into Abort...
|
||||
self:HandleEvent( EVENTS.Crash,
|
||||
--- @param #TASK self
|
||||
-- @param Core.Event#EVENTDATA EventData
|
||||
function( self, EventData )
|
||||
local PlayerUnit = EventData.IniUnit
|
||||
for MissionID, Mission in pairs( self:GetMissions() ) do
|
||||
Mission:CrashUnit( PlayerUnit )
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Gets the name of the HQ command center.
|
||||
-- @param #COMMANDCENTER self
|
||||
-- @return #string
|
||||
function COMMANDCENTER:GetName()
|
||||
|
||||
return self.CommandCenterName
|
||||
end
|
||||
|
||||
--- Gets the POSITIONABLE of the HQ command center.
|
||||
-- @param #COMMANDCENTER self
|
||||
-- @return Wrapper.Positionable#POSITIONABLE
|
||||
function COMMANDCENTER:GetPositionable()
|
||||
return self.CommandCenterPositionable
|
||||
end
|
||||
|
||||
--- Get the Missions governed by the HQ command center.
|
||||
-- @param #COMMANDCENTER self
|
||||
-- @return #list<Tasking.Mission#MISSION>
|
||||
function COMMANDCENTER:GetMissions()
|
||||
|
||||
return self.Missions
|
||||
end
|
||||
|
||||
--- Add a MISSION to be governed by the HQ command center.
|
||||
-- @param #COMMANDCENTER self
|
||||
-- @param Tasking.Mission#MISSION Mission
|
||||
-- @return Tasking.Mission#MISSION
|
||||
function COMMANDCENTER:AddMission( Mission )
|
||||
|
||||
self.Missions[Mission] = Mission
|
||||
|
||||
return Mission
|
||||
end
|
||||
|
||||
--- Removes a MISSION to be governed by the HQ command center.
|
||||
-- The given Mission is not nilified.
|
||||
-- @param #COMMANDCENTER self
|
||||
-- @param Tasking.Mission#MISSION Mission
|
||||
-- @return Tasking.Mission#MISSION
|
||||
function COMMANDCENTER:RemoveMission( Mission )
|
||||
|
||||
self.Missions[Mission] = nil
|
||||
|
||||
return Mission
|
||||
end
|
||||
|
||||
--- Sets the menu structure of the Missions governed by the HQ command center.
|
||||
-- @param #COMMANDCENTER self
|
||||
function COMMANDCENTER:SetMenu()
|
||||
self:F()
|
||||
|
||||
self.CommandCenterMenu = self.CommandCenterMenu or MENU_COALITION:New( self.CommandCenterCoalition, "Command Center (" .. self:GetName() .. ")" )
|
||||
|
||||
for MissionID, Mission in pairs( self:GetMissions() ) do
|
||||
local Mission = Mission -- Tasking.Mission#MISSION
|
||||
Mission:RemoveMenu()
|
||||
end
|
||||
|
||||
for MissionID, Mission in pairs( self:GetMissions() ) do
|
||||
local Mission = Mission -- Tasking.Mission#MISSION
|
||||
Mission:SetMenu()
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--- Checks of the COMMANDCENTER has a GROUP.
|
||||
-- @param #COMMANDCENTER self
|
||||
-- @param Wrapper.Group#GROUP
|
||||
-- @return #boolean
|
||||
function COMMANDCENTER:HasGroup( MissionGroup )
|
||||
|
||||
local Has = false
|
||||
|
||||
for MissionID, Mission in pairs( self.Missions ) do
|
||||
local Mission = Mission -- Tasking.Mission#MISSION
|
||||
if Mission:HasGroup( MissionGroup ) then
|
||||
Has = true
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
return Has
|
||||
end
|
||||
|
||||
--- Send a CC message to a GROUP.
|
||||
-- @param #COMMANDCENTER self
|
||||
-- @param #string Message
|
||||
-- @param Wrapper.Group#GROUP TaskGroup
|
||||
-- @param #sring Name (optional) The name of the Group used as a prefix for the message to the Group. If not provided, there will be nothing shown.
|
||||
function COMMANDCENTER:MessageToGroup( Message, TaskGroup, Name )
|
||||
|
||||
local Prefix = Name and "@ Group (" .. Name .. "): " or ''
|
||||
Message = Prefix .. Message
|
||||
self:GetPositionable():MessageToGroup( Message , 20, TaskGroup, self:GetName() )
|
||||
|
||||
end
|
||||
|
||||
--- Send a CC message to the coalition of the CC.
|
||||
-- @param #COMMANDCENTER self
|
||||
function COMMANDCENTER:MessageToCoalition( Message )
|
||||
|
||||
local CCCoalition = self:GetPositionable():GetCoalition()
|
||||
--TODO: Fix coalition bug!
|
||||
self:GetPositionable():MessageToCoalition( Message, 20, CCCoalition, self:GetName() )
|
||||
|
||||
end
|
||||
|
||||
--- Report the status of all MISSIONs to a GROUP.
|
||||
-- Each Mission is listed, with an indication how many Tasks are still to be completed.
|
||||
-- @param #COMMANDCENTER self
|
||||
function COMMANDCENTER:ReportSummary( ReportGroup )
|
||||
self:E( ReportGroup )
|
||||
|
||||
local Report = REPORT:New()
|
||||
|
||||
for MissionID, Mission in pairs( self.Missions ) do
|
||||
local Mission = Mission -- Tasking.Mission#MISSION
|
||||
Report:Add( " - " .. Mission:ReportOverview() )
|
||||
end
|
||||
|
||||
self:GetPositionable():MessageToGroup( Report:Text(), 30, ReportGroup )
|
||||
|
||||
end
|
||||
|
||||
--- Report the status of a Task to a Group.
|
||||
-- Report the details of a Mission, listing the Mission, and all the Task details.
|
||||
-- @param #COMMANDCENTER self
|
||||
function COMMANDCENTER:ReportDetails( ReportGroup, Task )
|
||||
self:E( ReportGroup )
|
||||
|
||||
local Report = REPORT:New()
|
||||
|
||||
for MissionID, Mission in pairs( self.Missions ) do
|
||||
local Mission = Mission -- Tasking.Mission#MISSION
|
||||
Report:Add( " - " .. Mission:ReportDetails() )
|
||||
end
|
||||
|
||||
self:GetPositionable():MessageToGroup( Report:Text(), 30, ReportGroup )
|
||||
end
|
||||
|
||||
508
Moose Development/Moose/Tasking/DetectionManager.lua
Normal file
508
Moose Development/Moose/Tasking/DetectionManager.lua
Normal file
@@ -0,0 +1,508 @@
|
||||
--- This module contains the DETECTION_MANAGER class and derived classes.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- 1) @{DetectionManager#DETECTION_MANAGER} class, extends @{Base#BASE}
|
||||
-- ====================================================================
|
||||
-- The @{DetectionManager#DETECTION_MANAGER} class defines the core functions to report detected objects to groups.
|
||||
-- Reportings can be done in several manners, and it is up to the derived classes if DETECTION_MANAGER to model the reporting behaviour.
|
||||
--
|
||||
-- 1.1) DETECTION_MANAGER constructor:
|
||||
-- -----------------------------------
|
||||
-- * @{DetectionManager#DETECTION_MANAGER.New}(): Create a new DETECTION_MANAGER instance.
|
||||
--
|
||||
-- 1.2) DETECTION_MANAGER reporting:
|
||||
-- ---------------------------------
|
||||
-- Derived DETECTION_MANAGER classes will reports detected units using the method @{DetectionManager#DETECTION_MANAGER.ReportDetected}(). This method implements polymorphic behaviour.
|
||||
--
|
||||
-- The time interval in seconds of the reporting can be changed using the methods @{DetectionManager#DETECTION_MANAGER.SetReportInterval}().
|
||||
-- To control how long a reporting message is displayed, use @{DetectionManager#DETECTION_MANAGER.SetReportDisplayTime}().
|
||||
-- Derived classes need to implement the method @{DetectionManager#DETECTION_MANAGER.GetReportDisplayTime}() to use the correct display time for displayed messages during a report.
|
||||
--
|
||||
-- Reporting can be started and stopped using the methods @{DetectionManager#DETECTION_MANAGER.StartReporting}() and @{DetectionManager#DETECTION_MANAGER.StopReporting}() respectively.
|
||||
-- If an ad-hoc report is requested, use the method @{DetectionManager#DETECTION_MANAGER#ReportNow}().
|
||||
--
|
||||
-- The default reporting interval is every 60 seconds. The reporting messages are displayed 15 seconds.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- 2) @{DetectionManager#DETECTION_REPORTING} class, extends @{DetectionManager#DETECTION_MANAGER}
|
||||
-- =========================================================================================
|
||||
-- The @{DetectionManager#DETECTION_REPORTING} class implements detected units reporting. Reporting can be controlled using the reporting methods available in the @{DetectionManager#DETECTION_MANAGER} class.
|
||||
--
|
||||
-- 2.1) DETECTION_REPORTING constructor:
|
||||
-- -------------------------------
|
||||
-- The @{DetectionManager#DETECTION_REPORTING.New}() method creates a new DETECTION_REPORTING instance.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- 3) @{#DETECTION_DISPATCHER} class, extends @{#DETECTION_MANAGER}
|
||||
-- ================================================================
|
||||
-- The @{#DETECTION_DISPATCHER} class implements the dynamic dispatching of tasks upon groups of detected units determined a @{Set} of FAC (groups).
|
||||
-- The FAC will detect units, will group them, and will dispatch @{Task}s to groups. Depending on the type of target detected, different tasks will be dispatched.
|
||||
-- Find a summary below describing for which situation a task type is created:
|
||||
--
|
||||
-- * **CAS Task**: Is created when there are enemy ground units within range of the FAC, while there are friendly units in the FAC perimeter.
|
||||
-- * **BAI Task**: Is created when there are enemy ground units within range of the FAC, while there are NO other friendly units within the FAC perimeter.
|
||||
-- * **SEAD Task**: Is created when there are enemy ground units wihtin range of the FAC, with air search radars.
|
||||
--
|
||||
-- Other task types will follow...
|
||||
--
|
||||
-- 3.1) DETECTION_DISPATCHER constructor:
|
||||
-- --------------------------------------
|
||||
-- The @{#DETECTION_DISPATCHER.New}() method creates a new DETECTION_DISPATCHER instance.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- ### Contributions: Mechanist, Prof_Hilactic, FlightControl - Concept & Testing
|
||||
-- ### Author: FlightControl - Framework Design & Programming
|
||||
--
|
||||
-- @module DetectionManager
|
||||
|
||||
do -- DETECTION MANAGER
|
||||
|
||||
--- DETECTION_MANAGER class.
|
||||
-- @type DETECTION_MANAGER
|
||||
-- @field Set#SET_GROUP SetGroup The groups to which the FAC will report to.
|
||||
-- @field Functional.Detection#DETECTION_BASE Detection The DETECTION_BASE object that is used to report the detected objects.
|
||||
-- @extends Base#BASE
|
||||
DETECTION_MANAGER = {
|
||||
ClassName = "DETECTION_MANAGER",
|
||||
SetGroup = nil,
|
||||
Detection = nil,
|
||||
}
|
||||
|
||||
--- FAC constructor.
|
||||
-- @param #DETECTION_MANAGER self
|
||||
-- @param Set#SET_GROUP SetGroup
|
||||
-- @param Functional.Detection#DETECTION_BASE Detection
|
||||
-- @return #DETECTION_MANAGER self
|
||||
function DETECTION_MANAGER:New( SetGroup, Detection )
|
||||
|
||||
-- Inherits from BASE
|
||||
local self = BASE:Inherit( self, BASE:New() ) -- Functional.Detection#DETECTION_MANAGER
|
||||
|
||||
self.SetGroup = SetGroup
|
||||
self.Detection = Detection
|
||||
|
||||
self:SetReportInterval( 30 )
|
||||
self:SetReportDisplayTime( 25 )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Set the reporting time interval.
|
||||
-- @param #DETECTION_MANAGER self
|
||||
-- @param #number ReportInterval The interval in seconds when a report needs to be done.
|
||||
-- @return #DETECTION_MANAGER self
|
||||
function DETECTION_MANAGER:SetReportInterval( ReportInterval )
|
||||
self:F2()
|
||||
|
||||
self._ReportInterval = ReportInterval
|
||||
end
|
||||
|
||||
|
||||
--- Set the reporting message display time.
|
||||
-- @param #DETECTION_MANAGER self
|
||||
-- @param #number ReportDisplayTime The display time in seconds when a report needs to be done.
|
||||
-- @return #DETECTION_MANAGER self
|
||||
function DETECTION_MANAGER:SetReportDisplayTime( ReportDisplayTime )
|
||||
self:F2()
|
||||
|
||||
self._ReportDisplayTime = ReportDisplayTime
|
||||
end
|
||||
|
||||
--- Get the reporting message display time.
|
||||
-- @param #DETECTION_MANAGER self
|
||||
-- @return #number ReportDisplayTime The display time in seconds when a report needs to be done.
|
||||
function DETECTION_MANAGER:GetReportDisplayTime()
|
||||
self:F2()
|
||||
|
||||
return self._ReportDisplayTime
|
||||
end
|
||||
|
||||
|
||||
|
||||
--- Reports the detected items to the @{Set#SET_GROUP}.
|
||||
-- @param #DETECTION_MANAGER self
|
||||
-- @param Functional.Detection#DETECTION_BASE Detection
|
||||
-- @return #DETECTION_MANAGER self
|
||||
function DETECTION_MANAGER:ReportDetected( Detection )
|
||||
self:F2()
|
||||
|
||||
end
|
||||
|
||||
--- Schedule the FAC reporting.
|
||||
-- @param #DETECTION_MANAGER self
|
||||
-- @param #number DelayTime The delay in seconds to wait the reporting.
|
||||
-- @param #number ReportInterval The repeat interval in seconds for the reporting to happen repeatedly.
|
||||
-- @return #DETECTION_MANAGER self
|
||||
function DETECTION_MANAGER:Schedule( DelayTime, ReportInterval )
|
||||
self:F2()
|
||||
|
||||
self._ScheduleDelayTime = DelayTime
|
||||
|
||||
self:SetReportInterval( ReportInterval )
|
||||
|
||||
self.FacScheduler = SCHEDULER:New(self, self._FacScheduler, { self, "DetectionManager" }, self._ScheduleDelayTime, self._ReportInterval )
|
||||
return self
|
||||
end
|
||||
|
||||
--- Report the detected @{Unit#UNIT}s detected within the @{Detection#DETECTION_BASE} object to the @{Set#SET_GROUP}s.
|
||||
-- @param #DETECTION_MANAGER self
|
||||
function DETECTION_MANAGER:_FacScheduler( SchedulerName )
|
||||
self:F2( { SchedulerName } )
|
||||
|
||||
return self:ProcessDetected( self.Detection )
|
||||
|
||||
-- self.SetGroup:ForEachGroup(
|
||||
-- --- @param Wrapper.Group#GROUP Group
|
||||
-- function( Group )
|
||||
-- if Group:IsAlive() then
|
||||
-- return self:ProcessDetected( self.Detection )
|
||||
-- end
|
||||
-- end
|
||||
-- )
|
||||
|
||||
-- return true
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
do -- DETECTION_REPORTING
|
||||
|
||||
--- DETECTION_REPORTING class.
|
||||
-- @type DETECTION_REPORTING
|
||||
-- @field Set#SET_GROUP SetGroup The groups to which the FAC will report to.
|
||||
-- @field Functional.Detection#DETECTION_BASE Detection The DETECTION_BASE object that is used to report the detected objects.
|
||||
-- @extends #DETECTION_MANAGER
|
||||
DETECTION_REPORTING = {
|
||||
ClassName = "DETECTION_REPORTING",
|
||||
}
|
||||
|
||||
|
||||
--- DETECTION_REPORTING constructor.
|
||||
-- @param #DETECTION_REPORTING self
|
||||
-- @param Set#SET_GROUP SetGroup
|
||||
-- @param Functional.Detection#DETECTION_AREAS Detection
|
||||
-- @return #DETECTION_REPORTING self
|
||||
function DETECTION_REPORTING:New( SetGroup, Detection )
|
||||
|
||||
-- Inherits from DETECTION_MANAGER
|
||||
local self = BASE:Inherit( self, DETECTION_MANAGER:New( SetGroup, Detection ) ) -- #DETECTION_REPORTING
|
||||
|
||||
self:Schedule( 1, 30 )
|
||||
return self
|
||||
end
|
||||
|
||||
--- Creates a string of the detected items in a @{Detection}.
|
||||
-- @param #DETECTION_MANAGER self
|
||||
-- @param Set#SET_UNIT DetectedSet The detected Set created by the @{Detection#DETECTION_BASE} object.
|
||||
-- @return #DETECTION_MANAGER self
|
||||
function DETECTION_REPORTING:GetDetectedItemsText( DetectedSet )
|
||||
self:F2()
|
||||
|
||||
local MT = {} -- Message Text
|
||||
local UnitTypes = {}
|
||||
|
||||
for DetectedUnitID, DetectedUnitData in pairs( DetectedSet:GetSet() ) do
|
||||
local DetectedUnit = DetectedUnitData -- Wrapper.Unit#UNIT
|
||||
if DetectedUnit:IsAlive() then
|
||||
local UnitType = DetectedUnit:GetTypeName()
|
||||
|
||||
if not UnitTypes[UnitType] then
|
||||
UnitTypes[UnitType] = 1
|
||||
else
|
||||
UnitTypes[UnitType] = UnitTypes[UnitType] + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for UnitTypeID, UnitType in pairs( UnitTypes ) do
|
||||
MT[#MT+1] = UnitType .. " of " .. UnitTypeID
|
||||
end
|
||||
|
||||
return table.concat( MT, ", " )
|
||||
end
|
||||
|
||||
|
||||
|
||||
--- Reports the detected items to the @{Set#SET_GROUP}.
|
||||
-- @param #DETECTION_REPORTING self
|
||||
-- @param Wrapper.Group#GROUP Group The @{Group} object to where the report needs to go.
|
||||
-- @param Functional.Detection#DETECTION_AREAS Detection The detection created by the @{Detection#DETECTION_BASE} object.
|
||||
-- @return #boolean Return true if you want the reporting to continue... false will cancel the reporting loop.
|
||||
function DETECTION_REPORTING:ProcessDetected( Group, Detection )
|
||||
self:F2( Group )
|
||||
|
||||
self:E( Group )
|
||||
local DetectedMsg = {}
|
||||
for DetectedAreaID, DetectedAreaData in pairs( Detection:GetDetectedAreas() ) do
|
||||
local DetectedArea = DetectedAreaData -- Functional.Detection#DETECTION_AREAS.DetectedArea
|
||||
DetectedMsg[#DetectedMsg+1] = " - Group #" .. DetectedAreaID .. ": " .. self:GetDetectedItemsText( DetectedArea.Set )
|
||||
end
|
||||
local FACGroup = Detection:GetDetectionGroups()
|
||||
FACGroup:MessageToGroup( "Reporting detected target groups:\n" .. table.concat( DetectedMsg, "\n" ), self:GetReportDisplayTime(), Group )
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
do -- DETECTION_DISPATCHER
|
||||
|
||||
--- DETECTION_DISPATCHER class.
|
||||
-- @type DETECTION_DISPATCHER
|
||||
-- @field Set#SET_GROUP SetGroup The groups to which the FAC will report to.
|
||||
-- @field Functional.Detection#DETECTION_BASE Detection The DETECTION_BASE object that is used to report the detected objects.
|
||||
-- @field Tasking.Mission#MISSION Mission
|
||||
-- @field Wrapper.Group#GROUP CommandCenter
|
||||
-- @extends Tasking.DetectionManager#DETECTION_MANAGER
|
||||
DETECTION_DISPATCHER = {
|
||||
ClassName = "DETECTION_DISPATCHER",
|
||||
Mission = nil,
|
||||
CommandCenter = nil,
|
||||
Detection = nil,
|
||||
}
|
||||
|
||||
|
||||
--- DETECTION_DISPATCHER constructor.
|
||||
-- @param #DETECTION_DISPATCHER self
|
||||
-- @param Set#SET_GROUP SetGroup
|
||||
-- @param Functional.Detection#DETECTION_BASE Detection
|
||||
-- @return #DETECTION_DISPATCHER self
|
||||
function DETECTION_DISPATCHER:New( Mission, CommandCenter, SetGroup, Detection )
|
||||
|
||||
-- Inherits from DETECTION_MANAGER
|
||||
local self = BASE:Inherit( self, DETECTION_MANAGER:New( SetGroup, Detection ) ) -- #DETECTION_DISPATCHER
|
||||
|
||||
self.Detection = Detection
|
||||
self.CommandCenter = CommandCenter
|
||||
self.Mission = Mission
|
||||
|
||||
self:Schedule( 30 )
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
--- Creates a SEAD task when there are targets for it.
|
||||
-- @param #DETECTION_DISPATCHER self
|
||||
-- @param Functional.Detection#DETECTION_AREAS.DetectedArea DetectedArea
|
||||
-- @return Set#SET_UNIT TargetSetUnit: The target set of units.
|
||||
-- @return #nil If there are no targets to be set.
|
||||
function DETECTION_DISPATCHER:EvaluateSEAD( DetectedArea )
|
||||
self:F( { DetectedArea.AreaID } )
|
||||
|
||||
local DetectedSet = DetectedArea.Set
|
||||
local DetectedZone = DetectedArea.Zone
|
||||
|
||||
-- Determine if the set has radar targets. If it does, construct a SEAD task.
|
||||
local RadarCount = DetectedSet:HasSEAD()
|
||||
|
||||
if RadarCount > 0 then
|
||||
|
||||
-- Here we're doing something advanced... We're copying the DetectedSet, but making a new Set only with SEADable Radar units in it.
|
||||
local TargetSetUnit = SET_UNIT:New()
|
||||
TargetSetUnit:SetDatabase( DetectedSet )
|
||||
TargetSetUnit:FilterHasSEAD()
|
||||
TargetSetUnit:FilterOnce() -- Filter but don't do any events!!! Elements are added manually upon each detection.
|
||||
|
||||
return TargetSetUnit
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Creates a CAS task when there are targets for it.
|
||||
-- @param #DETECTION_DISPATCHER self
|
||||
-- @param Functional.Detection#DETECTION_AREAS.DetectedArea DetectedArea
|
||||
-- @return Tasking.Task#TASK
|
||||
function DETECTION_DISPATCHER:EvaluateCAS( DetectedArea )
|
||||
self:F( { DetectedArea.AreaID } )
|
||||
|
||||
local DetectedSet = DetectedArea.Set
|
||||
local DetectedZone = DetectedArea.Zone
|
||||
|
||||
|
||||
-- Determine if the set has radar targets. If it does, construct a SEAD task.
|
||||
local GroundUnitCount = DetectedSet:HasGroundUnits()
|
||||
local FriendliesNearBy = self.Detection:IsFriendliesNearBy( DetectedArea )
|
||||
|
||||
if GroundUnitCount > 0 and FriendliesNearBy == true then
|
||||
|
||||
-- Copy the Set
|
||||
local TargetSetUnit = SET_UNIT:New()
|
||||
TargetSetUnit:SetDatabase( DetectedSet )
|
||||
TargetSetUnit:FilterOnce() -- Filter but don't do any events!!! Elements are added manually upon each detection.
|
||||
|
||||
return TargetSetUnit
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Creates a BAI task when there are targets for it.
|
||||
-- @param #DETECTION_DISPATCHER self
|
||||
-- @param Functional.Detection#DETECTION_AREAS.DetectedArea DetectedArea
|
||||
-- @return Tasking.Task#TASK
|
||||
function DETECTION_DISPATCHER:EvaluateBAI( DetectedArea, FriendlyCoalition )
|
||||
self:F( { DetectedArea.AreaID } )
|
||||
|
||||
local DetectedSet = DetectedArea.Set
|
||||
local DetectedZone = DetectedArea.Zone
|
||||
|
||||
|
||||
-- Determine if the set has radar targets. If it does, construct a SEAD task.
|
||||
local GroundUnitCount = DetectedSet:HasGroundUnits()
|
||||
local FriendliesNearBy = self.Detection:IsFriendliesNearBy( DetectedArea )
|
||||
|
||||
if GroundUnitCount > 0 and FriendliesNearBy == false then
|
||||
|
||||
-- Copy the Set
|
||||
local TargetSetUnit = SET_UNIT:New()
|
||||
TargetSetUnit:SetDatabase( DetectedSet )
|
||||
TargetSetUnit:FilterOnce() -- Filter but don't do any events!!! Elements are added manually upon each detection.
|
||||
|
||||
return TargetSetUnit
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Evaluates the removal of the Task from the Mission.
|
||||
-- Can only occur when the DetectedArea is Changed AND the state of the Task is "Planned".
|
||||
-- @param #DETECTION_DISPATCHER self
|
||||
-- @param Tasking.Mission#MISSION Mission
|
||||
-- @param Tasking.Task#TASK Task
|
||||
-- @param Functional.Detection#DETECTION_AREAS.DetectedArea DetectedArea
|
||||
-- @return Tasking.Task#TASK
|
||||
function DETECTION_DISPATCHER:EvaluateRemoveTask( Mission, Task, DetectedArea )
|
||||
|
||||
if Task then
|
||||
if Task:IsStatePlanned() and DetectedArea.Changed == true then
|
||||
self:E( "Removing Tasking: " .. Task:GetTaskName() )
|
||||
Task = Mission:RemoveTask( Task )
|
||||
end
|
||||
end
|
||||
|
||||
return Task
|
||||
end
|
||||
|
||||
|
||||
--- Assigns tasks in relation to the detected items to the @{Set#SET_GROUP}.
|
||||
-- @param #DETECTION_DISPATCHER self
|
||||
-- @param Functional.Detection#DETECTION_AREAS Detection The detection created by the @{Detection#DETECTION_AREAS} object.
|
||||
-- @return #boolean Return true if you want the task assigning to continue... false will cancel the loop.
|
||||
function DETECTION_DISPATCHER:ProcessDetected( Detection )
|
||||
self:F2()
|
||||
|
||||
local AreaMsg = {}
|
||||
local TaskMsg = {}
|
||||
local ChangeMsg = {}
|
||||
|
||||
local Mission = self.Mission
|
||||
|
||||
--- First we need to the detected targets.
|
||||
for DetectedAreaID, DetectedAreaData in ipairs( Detection:GetDetectedAreas() ) do
|
||||
|
||||
local DetectedArea = DetectedAreaData -- Functional.Detection#DETECTION_AREAS.DetectedArea
|
||||
local DetectedSet = DetectedArea.Set
|
||||
local DetectedZone = DetectedArea.Zone
|
||||
self:E( { "Targets in DetectedArea", DetectedArea.AreaID, DetectedSet:Count(), tostring( DetectedArea ) } )
|
||||
DetectedSet:Flush()
|
||||
|
||||
local AreaID = DetectedArea.AreaID
|
||||
|
||||
-- Evaluate SEAD Tasking
|
||||
local SEADTask = Mission:GetTask( "SEAD." .. AreaID )
|
||||
SEADTask = self:EvaluateRemoveTask( Mission, SEADTask, DetectedArea )
|
||||
if not SEADTask then
|
||||
local TargetSetUnit = self:EvaluateSEAD( DetectedArea ) -- Returns a SetUnit if there are targets to be SEADed...
|
||||
if TargetSetUnit then
|
||||
SEADTask = Mission:AddTask( TASK_SEAD:New( Mission, self.SetGroup, "SEAD." .. AreaID, TargetSetUnit , DetectedZone ) )
|
||||
end
|
||||
end
|
||||
if SEADTask and SEADTask:IsStatePlanned() then
|
||||
self:E( "Planned" )
|
||||
--SEADTask:SetPlannedMenu()
|
||||
TaskMsg[#TaskMsg+1] = " - " .. SEADTask:GetStateString() .. " SEAD " .. AreaID .. " - " .. SEADTask.TargetSetUnit:GetUnitTypesText()
|
||||
end
|
||||
|
||||
-- Evaluate CAS Tasking
|
||||
local CASTask = Mission:GetTask( "CAS." .. AreaID )
|
||||
CASTask = self:EvaluateRemoveTask( Mission, CASTask, DetectedArea )
|
||||
if not CASTask then
|
||||
local TargetSetUnit = self:EvaluateCAS( DetectedArea ) -- Returns a SetUnit if there are targets to be SEADed...
|
||||
if TargetSetUnit then
|
||||
CASTask = Mission:AddTask( TASK_A2G:New( Mission, self.SetGroup, "CAS." .. AreaID, "CAS", TargetSetUnit , DetectedZone, DetectedArea.NearestFAC ) )
|
||||
end
|
||||
end
|
||||
if CASTask and CASTask:IsStatePlanned() then
|
||||
--CASTask:SetPlannedMenu()
|
||||
TaskMsg[#TaskMsg+1] = " - " .. CASTask:GetStateString() .. " CAS " .. AreaID .. " - " .. CASTask.TargetSetUnit:GetUnitTypesText()
|
||||
end
|
||||
|
||||
-- Evaluate BAI Tasking
|
||||
local BAITask = Mission:GetTask( "BAI." .. AreaID )
|
||||
BAITask = self:EvaluateRemoveTask( Mission, BAITask, DetectedArea )
|
||||
if not BAITask then
|
||||
local TargetSetUnit = self:EvaluateBAI( DetectedArea, self.CommandCenter:GetCoalition() ) -- Returns a SetUnit if there are targets to be SEADed...
|
||||
if TargetSetUnit then
|
||||
BAITask = Mission:AddTask( TASK_A2G:New( Mission, self.SetGroup, "BAI." .. AreaID, "BAI", TargetSetUnit , DetectedZone, DetectedArea.NearestFAC ) )
|
||||
end
|
||||
end
|
||||
if BAITask and BAITask:IsStatePlanned() then
|
||||
--BAITask:SetPlannedMenu()
|
||||
TaskMsg[#TaskMsg+1] = " - " .. BAITask:GetStateString() .. " BAI " .. AreaID .. " - " .. BAITask.TargetSetUnit:GetUnitTypesText()
|
||||
end
|
||||
|
||||
if #TaskMsg > 0 then
|
||||
|
||||
local ThreatLevel = Detection:GetTreatLevelA2G( DetectedArea )
|
||||
|
||||
local DetectedAreaVec3 = DetectedZone:GetVec3()
|
||||
local DetectedAreaPointVec3 = POINT_VEC3:New( DetectedAreaVec3.x, DetectedAreaVec3.y, DetectedAreaVec3.z )
|
||||
local DetectedAreaPointLL = DetectedAreaPointVec3:ToStringLL( 3, true )
|
||||
AreaMsg[#AreaMsg+1] = string.format( " - Area #%d - %s - Threat Level [%s] (%2d)",
|
||||
DetectedAreaID,
|
||||
DetectedAreaPointLL,
|
||||
string.rep( "■", ThreatLevel ),
|
||||
ThreatLevel
|
||||
)
|
||||
|
||||
-- Loop through the changes ...
|
||||
local ChangeText = Detection:GetChangeText( DetectedArea )
|
||||
|
||||
if ChangeText ~= "" then
|
||||
ChangeMsg[#ChangeMsg+1] = string.gsub( string.gsub( ChangeText, "\n", "%1 - " ), "^.", " - %1" )
|
||||
end
|
||||
end
|
||||
|
||||
-- OK, so the tasking has been done, now delete the changes reported for the area.
|
||||
Detection:AcceptChanges( DetectedArea )
|
||||
|
||||
end
|
||||
|
||||
-- TODO set menus using the HQ coordinator
|
||||
Mission:GetCommandCenter():SetMenu()
|
||||
|
||||
if #AreaMsg > 0 then
|
||||
for TaskGroupID, TaskGroup in pairs( self.SetGroup:GetSet() ) do
|
||||
if not TaskGroup:GetState( TaskGroup, "Assigned" ) then
|
||||
self.CommandCenter:MessageToGroup(
|
||||
string.format( "HQ Reporting - Target areas for mission '%s':\nAreas:\n%s\n\nTasks:\n%s\n\nChanges:\n%s ",
|
||||
self.Mission:GetName(),
|
||||
table.concat( AreaMsg, "\n" ),
|
||||
table.concat( TaskMsg, "\n" ),
|
||||
table.concat( ChangeMsg, "\n" )
|
||||
), self:GetReportDisplayTime(), TaskGroup
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
end
|
||||
@@ -1,20 +1,21 @@
|
||||
--- A MISSION is the main owner of a Mission orchestration within MOOSE . The Mission framework orchestrates @{CLIENT}s, @{TASK}s, @{STAGE}s etc.
|
||||
-- A @{CLIENT} needs to be registered within the @{MISSION} through the function @{AddClient}. A @{TASK} needs to be registered within the @{MISSION} through the function @{AddTask}.
|
||||
-- @module MISSION
|
||||
|
||||
Include.File( "Routines" )
|
||||
Include.File( "Base" )
|
||||
Include.File( "Client" )
|
||||
Include.File( "Task" )
|
||||
-- @module Mission
|
||||
|
||||
--- The MISSION class
|
||||
-- @type
|
||||
-- @type MISSION
|
||||
-- @field #MISSION.Clients _Clients
|
||||
-- @field Core.Menu#MENU_COALITION MissionMenu
|
||||
-- @field #string MissionBriefing
|
||||
-- @extends Core.Fsm#FSM
|
||||
MISSION = {
|
||||
ClassName = "MISSION",
|
||||
Name = "",
|
||||
MissionStatus = "PENDING",
|
||||
_Clients = {},
|
||||
_Tasks = {},
|
||||
TaskMenus = {},
|
||||
TaskCategoryMenus = {},
|
||||
TaskTypeMenus = {},
|
||||
_ActiveTasks = {},
|
||||
GoalFunction = nil,
|
||||
MissionReportTrigger = 0,
|
||||
@@ -29,53 +30,330 @@ MISSION = {
|
||||
_GoalTasks = {}
|
||||
}
|
||||
|
||||
|
||||
function MISSION:Meta()
|
||||
|
||||
local self = BASE:Inherit( self, BASE:New() )
|
||||
self:F()
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- This is the main MISSION declaration method. Each Mission is like the master or a Mission orchestration between, Clients, Tasks, Stages etc.
|
||||
-- @param string MissionName is the name of the mission. This name will be used to reference the status of each mission by the players.
|
||||
-- @param string MissionPriority is a string indicating the "priority" of the Mission. f.e. "Primary", "Secondary" or "First", "Second". It is free format and up to the Mission designer to choose. There are no rules behind this field.
|
||||
-- @param string MissionBriefing is a string indicating the mission briefing to be shown when a player joins a @{CLIENT}.
|
||||
-- @param string MissionCoalition is a string indicating the coalition or party to which this mission belongs to. It is free format and can be chosen freely by the mission designer. Note that this field is not to be confused with the coalition concept of the ME. Examples of a Mission Coalition could be "NATO", "CCCP", "Intruders", "Terrorists"...
|
||||
-- @return MISSION
|
||||
-- @usage
|
||||
-- -- Declare a few missions.
|
||||
-- local Mission = MISSIONSCHEDULER.AddMission( 'Russia Transport Troops SA-6', 'Operational', 'Transport troops from the control center to one of the SA-6 SAM sites to activate their operation.', 'Russia' )
|
||||
-- local Mission = MISSIONSCHEDULER.AddMission( 'Patriots', 'Primary', 'Our intelligence reports that 3 Patriot SAM defense batteries are located near Ruisi, Kvarhiti and Gori.', 'Russia' )
|
||||
-- local Mission = MISSIONSCHEDULER.AddMission( 'Package Delivery', 'Operational', 'In order to be in full control of the situation, we need you to deliver a very important package at a secret location. Fly undetected through the NATO defenses and deliver the secret package. The secret agent is located at waypoint 4.', 'Russia' )
|
||||
-- local Mission = MISSIONSCHEDULER.AddMission( 'Rescue General', 'Tactical', 'Our intelligence has received a remote signal behind Gori. We believe it is a very important Russian General that was captured by Georgia. Go out there and rescue him! Ensure you stay out of the battle zone, keep south. Waypoint 4 is the location of our Russian General.', 'Russia' )
|
||||
-- local Mission = MISSIONSCHEDULER.AddMission( 'NATO Transport Troops', 'Operational', 'Transport 3 groups of air defense engineers from our barracks "Gold" and "Titan" to each patriot battery control center to activate our air defenses.', 'NATO' )
|
||||
-- local Mission = MISSIONSCHEDULER.AddMission( 'SA-6 SAMs', 'Primary', 'Our intelligence reports that 3 SA-6 SAM defense batteries are located near Didmukha, Khetagurov and Berula. Eliminate the Russian SAMs.', 'NATO' )
|
||||
-- local Mission = MISSIONSCHEDULER.AddMission( 'NATO Sling Load', 'Operational', 'Fly to the cargo pickup zone at Dzegvi or Kaspi, and sling the cargo to Soganlug airbase.', 'NATO' )
|
||||
-- local Mission = MISSIONSCHEDULER.AddMission( 'Rescue secret agent', 'Tactical', 'In order to be in full control of the situation, we need you to rescue a secret agent from the woods behind enemy lines. Avoid the Russian defenses and rescue the agent. Keep south until Khasuri, and keep your eyes open for any SAM presence. The agent is located at waypoint 4 on your kneeboard.', 'NATO' )
|
||||
function MISSION:New( MissionName, MissionPriority, MissionBriefing, MissionCoalition )
|
||||
-- @param #MISSION self
|
||||
-- @param Tasking.CommandCenter#COMMANDCENTER CommandCenter
|
||||
-- @param #string MissionName is the name of the mission. This name will be used to reference the status of each mission by the players.
|
||||
-- @param #string MissionPriority is a string indicating the "priority" of the Mission. f.e. "Primary", "Secondary" or "First", "Second". It is free format and up to the Mission designer to choose. There are no rules behind this field.
|
||||
-- @param #string MissionBriefing is a string indicating the mission briefing to be shown when a player joins a @{CLIENT}.
|
||||
-- @param Dcs.DCSCoalitionWrapper.Object#coalition MissionCoalition is a string indicating the coalition or party to which this mission belongs to. It is free format and can be chosen freely by the mission designer. Note that this field is not to be confused with the coalition concept of the ME. Examples of a Mission Coalition could be "NATO", "CCCP", "Intruders", "Terrorists"...
|
||||
-- @return #MISSION self
|
||||
function MISSION:New( CommandCenter, MissionName, MissionPriority, MissionBriefing, MissionCoalition )
|
||||
|
||||
self = MISSION:Meta()
|
||||
self:T({ MissionName, MissionPriority, MissionBriefing, MissionCoalition })
|
||||
local self = BASE:Inherit( self, FSM:New() ) -- Core.Fsm#FSM
|
||||
|
||||
self:SetStartState( "Idle" )
|
||||
|
||||
local Valid = true
|
||||
self:AddTransition( "Idle", "Start", "Ongoing" )
|
||||
self:AddTransition( "Ongoing", "Stop", "Idle" )
|
||||
self:AddTransition( "Ongoing", "Complete", "Completed" )
|
||||
self:AddTransition( "*", "Fail", "Failed" )
|
||||
|
||||
Valid = routines.ValidateString( MissionName, "MissionName", Valid )
|
||||
Valid = routines.ValidateString( MissionPriority, "MissionPriority", Valid )
|
||||
Valid = routines.ValidateString( MissionBriefing, "MissionBriefing", Valid )
|
||||
Valid = routines.ValidateString( MissionCoalition, "MissionCoalition", Valid )
|
||||
self:T( { MissionName, MissionPriority, MissionBriefing, MissionCoalition } )
|
||||
|
||||
if Valid then
|
||||
self.Name = MissionName
|
||||
self.MissionPriority = MissionPriority
|
||||
self.MissionBriefing = MissionBriefing
|
||||
self.MissionCoalition = MissionCoalition
|
||||
end
|
||||
self.CommandCenter = CommandCenter
|
||||
CommandCenter:AddMission( self )
|
||||
|
||||
self.Name = MissionName
|
||||
self.MissionPriority = MissionPriority
|
||||
self.MissionBriefing = MissionBriefing
|
||||
self.MissionCoalition = MissionCoalition
|
||||
|
||||
self.Tasks = {}
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- FSM function for a MISSION
|
||||
-- @param #MISSION self
|
||||
-- @param #string Event
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
function MISSION:onbeforeComplete( From, Event, To )
|
||||
|
||||
for TaskID, Task in pairs( self:GetTasks() ) do
|
||||
local Task = Task -- Tasking.Task#TASK
|
||||
if not Task:IsStateSuccess() and not Task:IsStateFailed() and not Task:IsStateAborted() and not Task:IsStateCancelled() then
|
||||
return false -- Mission cannot be completed. Other Tasks are still active.
|
||||
end
|
||||
end
|
||||
return true -- Allow Mission completion.
|
||||
end
|
||||
|
||||
--- FSM function for a MISSION
|
||||
-- @param #MISSION self
|
||||
-- @param #string Event
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
function MISSION:onenterCompleted( From, Event, To )
|
||||
|
||||
self:GetCommandCenter():MessageToCoalition( "Mission " .. self:GetName() .. " has been completed! Good job guys!" )
|
||||
end
|
||||
|
||||
--- Gets the mission name.
|
||||
-- @param #MISSION self
|
||||
-- @return #MISSION self
|
||||
function MISSION:GetName()
|
||||
return self.Name
|
||||
end
|
||||
|
||||
--- Add a Unit to join the Mission.
|
||||
-- For each Task within the Mission, the Unit is joined with the Task.
|
||||
-- If the Unit was not part of a Task in the Mission, false is returned.
|
||||
-- If the Unit is part of a Task in the Mission, true is returned.
|
||||
-- @param #MISSION self
|
||||
-- @param Wrapper.Unit#UNIT PlayerUnit The CLIENT or UNIT of the Player joining the Mission.
|
||||
-- @param Wrapper.Group#GROUP PlayerGroup The GROUP of the player joining the Mission.
|
||||
-- @return #boolean true if Unit is part of a Task in the Mission.
|
||||
function MISSION:JoinUnit( PlayerUnit, PlayerGroup )
|
||||
self:F( { PlayerUnit = PlayerUnit, PlayerGroup = PlayerGroup } )
|
||||
|
||||
local PlayerUnitAdded = false
|
||||
|
||||
for TaskID, Task in pairs( self:GetTasks() ) do
|
||||
local Task = Task -- Tasking.Task#TASK
|
||||
if Task:JoinUnit( PlayerUnit, PlayerGroup ) then
|
||||
PlayerUnitAdded = true
|
||||
end
|
||||
end
|
||||
|
||||
return PlayerUnitAdded
|
||||
end
|
||||
|
||||
--- Aborts a PlayerUnit from the Mission.
|
||||
-- For each Task within the Mission, the PlayerUnit is removed from Task where it is assigned.
|
||||
-- If the Unit was not part of a Task in the Mission, false is returned.
|
||||
-- If the Unit is part of a Task in the Mission, true is returned.
|
||||
-- @param #MISSION self
|
||||
-- @param Wrapper.Unit#UNIT PlayerUnit The CLIENT or UNIT of the Player joining the Mission.
|
||||
-- @return #boolean true if Unit is part of a Task in the Mission.
|
||||
function MISSION:AbortUnit( PlayerUnit )
|
||||
self:F( { PlayerUnit = PlayerUnit } )
|
||||
|
||||
local PlayerUnitRemoved = false
|
||||
|
||||
for TaskID, Task in pairs( self:GetTasks() ) do
|
||||
if Task:AbortUnit( PlayerUnit ) then
|
||||
PlayerUnitRemoved = true
|
||||
end
|
||||
end
|
||||
|
||||
return PlayerUnitRemoved
|
||||
end
|
||||
|
||||
--- Handles a crash of a PlayerUnit from the Mission.
|
||||
-- For each Task within the Mission, the PlayerUnit is removed from Task where it is assigned.
|
||||
-- If the Unit was not part of a Task in the Mission, false is returned.
|
||||
-- If the Unit is part of a Task in the Mission, true is returned.
|
||||
-- @param #MISSION self
|
||||
-- @param Wrapper.Unit#UNIT PlayerUnit The CLIENT or UNIT of the Player crashing.
|
||||
-- @return #boolean true if Unit is part of a Task in the Mission.
|
||||
function MISSION:CrashUnit( PlayerUnit )
|
||||
self:F( { PlayerUnit = PlayerUnit } )
|
||||
|
||||
local PlayerUnitRemoved = false
|
||||
|
||||
for TaskID, Task in pairs( self:GetTasks() ) do
|
||||
if Task:CrashUnit( PlayerUnit ) then
|
||||
PlayerUnitRemoved = true
|
||||
end
|
||||
end
|
||||
|
||||
return PlayerUnitRemoved
|
||||
end
|
||||
|
||||
--- Add a scoring to the mission.
|
||||
-- @param #MISSION self
|
||||
-- @return #MISSION self
|
||||
function MISSION:AddScoring( Scoring )
|
||||
self.Scoring = Scoring
|
||||
return self
|
||||
end
|
||||
|
||||
--- Get the scoring object of a mission.
|
||||
-- @param #MISSION self
|
||||
-- @return #SCORING Scoring
|
||||
function MISSION:GetScoring()
|
||||
return self.Scoring
|
||||
end
|
||||
|
||||
--- Get the groups for which TASKS are given in the mission
|
||||
-- @param #MISSION self
|
||||
-- @return Core.Set#SET_GROUP
|
||||
function MISSION:GetGroups()
|
||||
|
||||
local SetGroup = SET_GROUP:New()
|
||||
|
||||
for TaskID, Task in pairs( self:GetTasks() ) do
|
||||
local Task = Task -- Tasking.Task#TASK
|
||||
local GroupSet = Task:GetGroups()
|
||||
GroupSet:ForEachGroup(
|
||||
function( TaskGroup )
|
||||
SetGroup:Add( TaskGroup, TaskGroup )
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
return SetGroup
|
||||
|
||||
end
|
||||
|
||||
|
||||
--- Sets the Planned Task menu.
|
||||
-- @param #MISSION self
|
||||
function MISSION:SetMenu()
|
||||
self:F()
|
||||
|
||||
for _, Task in pairs( self:GetTasks() ) do
|
||||
local Task = Task -- Tasking.Task#TASK
|
||||
Task:SetMenu()
|
||||
end
|
||||
end
|
||||
|
||||
--- Removes the Planned Task menu.
|
||||
-- @param #MISSION self
|
||||
function MISSION:RemoveMenu()
|
||||
self:F()
|
||||
|
||||
for _, Task in pairs( self:GetTasks() ) do
|
||||
local Task = Task -- Tasking.Task#TASK
|
||||
Task:RemoveMenu()
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--- Gets the COMMANDCENTER.
|
||||
-- @param #MISSION self
|
||||
-- @return Tasking.CommandCenter#COMMANDCENTER
|
||||
function MISSION:GetCommandCenter()
|
||||
return self.CommandCenter
|
||||
end
|
||||
|
||||
--- Sets the Assigned Task menu.
|
||||
-- @param #MISSION self
|
||||
-- @param Tasking.Task#TASK Task
|
||||
-- @param #string MenuText The menu text.
|
||||
-- @return #MISSION self
|
||||
function MISSION:SetAssignedMenu( Task )
|
||||
|
||||
for _, Task in pairs( self.Tasks ) do
|
||||
local Task = Task -- Tasking.Task#TASK
|
||||
Task:RemoveMenu()
|
||||
Task:SetAssignedMenu()
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--- Removes a Task menu.
|
||||
-- @param #MISSION self
|
||||
-- @param Tasking.Task#TASK Task
|
||||
-- @return #MISSION self
|
||||
function MISSION:RemoveTaskMenu( Task )
|
||||
|
||||
Task:RemoveMenu()
|
||||
end
|
||||
|
||||
|
||||
--- Gets the mission menu for the coalition.
|
||||
-- @param #MISSION self
|
||||
-- @param Wrapper.Group#GROUP TaskGroup
|
||||
-- @return Core.Menu#MENU_COALITION self
|
||||
function MISSION:GetMissionMenu( TaskGroup )
|
||||
|
||||
local CommandCenter = self:GetCommandCenter()
|
||||
local CommandCenterMenu = CommandCenter.CommandCenterMenu
|
||||
|
||||
local MissionName = self:GetName()
|
||||
|
||||
local TaskGroupName = TaskGroup:GetName()
|
||||
local MissionMenu = MENU_GROUP:New( TaskGroup, MissionName, CommandCenterMenu )
|
||||
|
||||
return MissionMenu
|
||||
end
|
||||
|
||||
|
||||
--- Clears the mission menu for the coalition.
|
||||
-- @param #MISSION self
|
||||
-- @return #MISSION self
|
||||
function MISSION:ClearMissionMenu()
|
||||
self.MissionMenu:Remove()
|
||||
self.MissionMenu = nil
|
||||
end
|
||||
|
||||
--- Get the TASK identified by the TaskNumber from the Mission. This function is useful in GoalFunctions.
|
||||
-- @param #string TaskName The Name of the @{Task} within the @{Mission}.
|
||||
-- @return Tasking.Task#TASK The Task
|
||||
-- @return #nil Returns nil if no task was found.
|
||||
function MISSION:GetTask( TaskName )
|
||||
self:F( { TaskName } )
|
||||
|
||||
return self.Tasks[TaskName]
|
||||
end
|
||||
|
||||
|
||||
--- Register a @{Task} to be completed within the @{Mission}.
|
||||
-- Note that there can be multiple @{Task}s registered to be completed.
|
||||
-- Each Task can be set a certain Goals. The Mission will not be completed until all Goals are reached.
|
||||
-- @param #MISSION self
|
||||
-- @param Tasking.Task#TASK Task is the @{Task} object.
|
||||
-- @return Tasking.Task#TASK The task added.
|
||||
function MISSION:AddTask( Task )
|
||||
|
||||
local TaskName = Task:GetTaskName()
|
||||
self:F( TaskName )
|
||||
|
||||
self.Tasks[TaskName] = self.Tasks[TaskName] or { n = 0 }
|
||||
|
||||
self.Tasks[TaskName] = Task
|
||||
|
||||
self:GetCommandCenter():SetMenu()
|
||||
|
||||
return Task
|
||||
end
|
||||
|
||||
--- Removes a @{Task} to be completed within the @{Mission}.
|
||||
-- Note that there can be multiple @{Task}s registered to be completed.
|
||||
-- Each Task can be set a certain Goals. The Mission will not be completed until all Goals are reached.
|
||||
-- @param #MISSION self
|
||||
-- @param Tasking.Task#TASK Task is the @{Task} object.
|
||||
-- @return #nil The cleaned Task reference.
|
||||
function MISSION:RemoveTask( Task )
|
||||
|
||||
local TaskName = Task:GetTaskName()
|
||||
|
||||
self:F( TaskName )
|
||||
self.Tasks[TaskName] = self.Tasks[TaskName] or { n = 0 }
|
||||
|
||||
-- Ensure everything gets garbarge collected.
|
||||
self.Tasks[TaskName] = nil
|
||||
Task = nil
|
||||
|
||||
collectgarbage()
|
||||
|
||||
self:GetCommandCenter():SetMenu()
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Return the next @{Task} ID to be completed within the @{Mission}.
|
||||
-- @param #MISSION self
|
||||
-- @param Tasking.Task#TASK Task is the @{Task} object.
|
||||
-- @return Tasking.Task#TASK The task added.
|
||||
function MISSION:GetNextTaskID( Task )
|
||||
|
||||
local TaskName = Task:GetTaskName()
|
||||
self:F( TaskName )
|
||||
self.Tasks[TaskName] = self.Tasks[TaskName] or { n = 0 }
|
||||
|
||||
self.Tasks[TaskName].n = self.Tasks[TaskName].n + 1
|
||||
|
||||
return self.Tasks[TaskName].n
|
||||
end
|
||||
|
||||
|
||||
|
||||
--- old stuff
|
||||
|
||||
--- Returns if a Mission has completed.
|
||||
-- @return bool
|
||||
function MISSION:IsCompleted()
|
||||
@@ -137,30 +415,101 @@ function MISSION:StatusToClients()
|
||||
self:F()
|
||||
if self.MissionReportFlash then
|
||||
for ClientID, Client in pairs( self._Clients ) do
|
||||
Client:Message( self.MissionCoalition .. ' "' .. self.Name .. '": ' .. self.MissionStatus .. '! ( ' .. self.MissionPriority .. ' mission ) ', 10, self.Name .. '/Status', "Mission Command: Mission Status")
|
||||
Client:Message( self.MissionCoalition .. ' "' .. self.Name .. '": ' .. self.MissionStatus .. '! ( ' .. self.MissionPriority .. ' mission ) ', 10, "Mission Command: Mission Status")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- Handles the reporting. After certain time intervals, a MISSION report MESSAGE will be shown to All Players.
|
||||
function MISSION:ReportTrigger()
|
||||
self:F()
|
||||
function MISSION:HasGroup( TaskGroup )
|
||||
local Has = false
|
||||
|
||||
for TaskID, Task in pairs( self:GetTasks() ) do
|
||||
local Task = Task -- Tasking.Task#TASK
|
||||
if Task:HasGroup( TaskGroup ) then
|
||||
Has = true
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
return Has
|
||||
end
|
||||
|
||||
if self.MissionReportShow == true then
|
||||
self.MissionReportShow = false
|
||||
return true
|
||||
else
|
||||
if self.MissionReportFlash == true then
|
||||
if timer.getTime() >= self.MissionReportTrigger then
|
||||
self.MissionReportTrigger = timer.getTime() + self.MissionTimeInterval
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
--- Create a summary report of the Mission (one line).
|
||||
-- @param #MISSION self
|
||||
-- @return #string
|
||||
function MISSION:ReportSummary()
|
||||
|
||||
local Report = REPORT:New()
|
||||
|
||||
-- List the name of the mission.
|
||||
local Name = self:GetName()
|
||||
|
||||
-- Determine the status of the mission.
|
||||
local Status = self:GetState()
|
||||
|
||||
-- Determine how many tasks are remaining.
|
||||
local TasksRemaining = 0
|
||||
for TaskID, Task in pairs( self:GetTasks() ) do
|
||||
local Task = Task -- Tasking.Task#TASK
|
||||
if Task:IsStateSuccess() or Task:IsStateFailed() then
|
||||
else
|
||||
TasksRemaining = TasksRemaining + 1
|
||||
end
|
||||
end
|
||||
|
||||
Report:Add( "Mission " .. Name .. " - " .. Status .. " - " .. TasksRemaining .. " tasks remaining." )
|
||||
|
||||
return Report:Text()
|
||||
end
|
||||
|
||||
--- Create a overview report of the Mission (multiple lines).
|
||||
-- @param #MISSION self
|
||||
-- @return #string
|
||||
function MISSION:ReportOverview()
|
||||
|
||||
local Report = REPORT:New()
|
||||
|
||||
-- List the name of the mission.
|
||||
local Name = self:GetName()
|
||||
|
||||
-- Determine the status of the mission.
|
||||
local Status = self:GetState()
|
||||
|
||||
Report:Add( "Mission " .. Name .. " - State '" .. Status .. "'" )
|
||||
|
||||
-- Determine how many tasks are remaining.
|
||||
local TasksRemaining = 0
|
||||
for TaskID, Task in pairs( self:GetTasks() ) do
|
||||
local Task = Task -- Tasking.Task#TASK
|
||||
Report:Add( "- " .. Task:ReportSummary() )
|
||||
end
|
||||
|
||||
return Report:Text()
|
||||
end
|
||||
|
||||
--- Create a detailed report of the Mission, listing all the details of the Task.
|
||||
-- @param #MISSION self
|
||||
-- @return #string
|
||||
function MISSION:ReportDetails()
|
||||
|
||||
local Report = REPORT:New()
|
||||
|
||||
-- List the name of the mission.
|
||||
local Name = self:GetName()
|
||||
|
||||
-- Determine the status of the mission.
|
||||
local Status = self:GetState()
|
||||
|
||||
Report:Add( "Mission " .. Name .. " - State '" .. Status .. "'" )
|
||||
|
||||
-- Determine how many tasks are remaining.
|
||||
local TasksRemaining = 0
|
||||
for TaskID, Task in pairs( self:GetTasks() ) do
|
||||
local Task = Task -- Tasking.Task#TASK
|
||||
Report:Add( Task:ReportDetails() )
|
||||
end
|
||||
|
||||
return Report:Text()
|
||||
end
|
||||
|
||||
--- Report the status of all MISSIONs to all active Clients.
|
||||
@@ -186,7 +535,7 @@ function MISSION:ReportToAll()
|
||||
for TaskID, TaskData in pairs( Tasks ) do
|
||||
TaskText = TaskText .. " - Task " .. TaskID .. ": " .. TaskData.Name .. ": " .. TaskData:GetGoalProgress() .. "\n"
|
||||
end
|
||||
MESSAGE:New( self.MissionCoalition .. ' "' .. self.Name .. '": ' .. self.MissionStatus .. ' ( ' .. self.MissionPriority .. ' mission )' .. AlivePlayers .. "\n" .. TaskText:gsub("\n$",""), "Mission Command: Mission Report", 10, self.Name .. '/Status'):ToAll()
|
||||
MESSAGE:New( self.MissionCoalition .. ' "' .. self.Name .. '": ' .. self.MissionStatus .. ' ( ' .. self.MissionPriority .. ' mission )' .. AlivePlayers .. "\n" .. TaskText:gsub("\n$",""), 10, "Mission Command: Mission Report" ):ToAll()
|
||||
end
|
||||
|
||||
|
||||
@@ -231,34 +580,15 @@ function MISSION:AddGoalFunction( GoalFunction )
|
||||
self.GoalFunction = GoalFunction
|
||||
end
|
||||
|
||||
--- Show the briefing of the MISSION to the CLIENT.
|
||||
-- @param CLIENT Client to show briefing to.
|
||||
-- @return CLIENT
|
||||
function MISSION:ShowBriefing( Client )
|
||||
self:F( { Client.ClientName } )
|
||||
|
||||
if not Client.ClientBriefingShown then
|
||||
Client.ClientBriefingShown = true
|
||||
local Briefing = self.MissionBriefing
|
||||
if Client.ClientBriefing then
|
||||
Briefing = Briefing .. "\n" .. Client.ClientBriefing
|
||||
end
|
||||
Briefing = Briefing .. "\n (Press [LEFT ALT]+[B] to view the graphical documentation.)"
|
||||
Client:Message( Briefing, 30, self.Name .. '/MissionBriefing', "Command: Mission Briefing" )
|
||||
end
|
||||
|
||||
return Client
|
||||
end
|
||||
|
||||
--- Register a new @{CLIENT} to participate within the mission.
|
||||
-- @param CLIENT Client is the @{CLIENT} object. The object must have been instantiated with @{CLIENT:New}.
|
||||
-- @return CLIENT
|
||||
-- @usage
|
||||
-- Add a number of Client objects to the Mission.
|
||||
-- Mission:AddClient( CLIENT:New( 'US UH-1H*HOT-Deploy Troops 1', 'Transport 3 groups of air defense engineers from our barracks "Gold" and "Titan" to each patriot battery control center to activate our air defenses.' ):Transport() )
|
||||
-- Mission:AddClient( CLIENT:New( 'US UH-1H*RAMP-Deploy Troops 3', 'Transport 3 groups of air defense engineers from our barracks "Gold" and "Titan" to each patriot battery control center to activate our air defenses.' ):Transport() )
|
||||
-- Mission:AddClient( CLIENT:New( 'US UH-1H*HOT-Deploy Troops 2', 'Transport 3 groups of air defense engineers from our barracks "Gold" and "Titan" to each patriot battery control center to activate our air defenses.' ):Transport() )
|
||||
-- Mission:AddClient( CLIENT:New( 'US UH-1H*RAMP-Deploy Troops 4', 'Transport 3 groups of air defense engineers from our barracks "Gold" and "Titan" to each patriot battery control center to activate our air defenses.' ):Transport() )
|
||||
-- Mission:AddClient( CLIENT:FindByName( 'US UH-1H*HOT-Deploy Troops 1', 'Transport 3 groups of air defense engineers from our barracks "Gold" and "Titan" to each patriot battery control center to activate our air defenses.' ):Transport() )
|
||||
-- Mission:AddClient( CLIENT:FindByName( 'US UH-1H*RAMP-Deploy Troops 3', 'Transport 3 groups of air defense engineers from our barracks "Gold" and "Titan" to each patriot battery control center to activate our air defenses.' ):Transport() )
|
||||
-- Mission:AddClient( CLIENT:FindByName( 'US UH-1H*HOT-Deploy Troops 2', 'Transport 3 groups of air defense engineers from our barracks "Gold" and "Titan" to each patriot battery control center to activate our air defenses.' ):Transport() )
|
||||
-- Mission:AddClient( CLIENT:FindByName( 'US UH-1H*RAMP-Deploy Troops 4', 'Transport 3 groups of air defense engineers from our barracks "Gold" and "Titan" to each patriot battery control center to activate our air defenses.' ):Transport() )
|
||||
function MISSION:AddClient( Client )
|
||||
self:F( { Client } )
|
||||
|
||||
@@ -283,66 +613,6 @@ function MISSION:FindClient( ClientName )
|
||||
end
|
||||
|
||||
|
||||
--- Register a @{TASK} to be completed within the @{MISSION}. Note that there can be multiple @{TASK}s registered to be completed. Each TASK can be set a certain Goal. The MISSION will not be completed until all Goals are reached.
|
||||
-- @param TASK Task is the @{TASK} object. The object must have been instantiated with @{TASK:New} or any of its inherited @{TASK}s.
|
||||
-- @param number TaskNumber is the sequence number of the TASK within the MISSION. This number does have to be chronological.
|
||||
-- @return TASK
|
||||
-- @usage
|
||||
-- -- Define a few tasks for the Mission.
|
||||
-- PickupZones = { "NATO Gold Pickup Zone", "NATO Titan Pickup Zone" }
|
||||
-- PickupSignalUnits = { "NATO Gold Coordination Center", "NATO Titan Coordination Center" }
|
||||
--
|
||||
-- -- Assign the Pickup Task
|
||||
-- local PickupTask = PICKUPTASK:New( PickupZones, CARGO_TYPE.ENGINEERS, CLIENT.ONBOARDSIDE.LEFT )
|
||||
-- PickupTask:AddSmokeBlue( PickupSignalUnits )
|
||||
-- PickupTask:SetGoalTotal( 3 )
|
||||
-- Mission:AddTask( PickupTask, 1 )
|
||||
--
|
||||
-- -- Assign the Deploy Task
|
||||
-- local PatriotActivationZones = { "US Patriot Battery 1 Activation", "US Patriot Battery 2 Activation", "US Patriot Battery 3 Activation" }
|
||||
-- local PatriotActivationZonesSmokeUnits = { "US SAM Patriot - Battery 1 Control", "US SAM Patriot - Battery 2 Control", "US SAM Patriot - Battery 3 Control" }
|
||||
-- local DeployTask = DEPLOYTASK:New( PatriotActivationZones, CARGO_TYPE.ENGINEERS )
|
||||
-- --DeployTask:SetCargoTargetZoneName( 'US Troops Attack ' .. math.random(2) )
|
||||
-- DeployTask:AddSmokeBlue( PatriotActivationZonesSmokeUnits )
|
||||
-- DeployTask:SetGoalTotal( 3 )
|
||||
-- DeployTask:SetGoalTotal( 3, "Patriots activated" )
|
||||
-- Mission:AddTask( DeployTask, 2 )
|
||||
|
||||
function MISSION:AddTask( Task, TaskNumber )
|
||||
self:F()
|
||||
|
||||
self._Tasks[TaskNumber] = Task
|
||||
self._Tasks[TaskNumber]:EnableEvents()
|
||||
self._Tasks[TaskNumber].ID = TaskNumber
|
||||
|
||||
return Task
|
||||
end
|
||||
|
||||
--- Get the TASK idenified by the TaskNumber from the Mission. This function is useful in GoalFunctions.
|
||||
-- @param number TaskNumber is the number of the @{TASK} within the @{MISSION}.
|
||||
-- @return TASK
|
||||
-- @usage
|
||||
-- -- Get Task 2 from the Mission.
|
||||
-- Task2 = Mission:GetTask( 2 )
|
||||
|
||||
function MISSION:GetTask( TaskNumber )
|
||||
self:F()
|
||||
|
||||
local Valid = true
|
||||
|
||||
local Task = nil
|
||||
|
||||
if type(TaskNumber) ~= "number" then
|
||||
Valid = false
|
||||
end
|
||||
|
||||
if Valid then
|
||||
Task = self._Tasks[TaskNumber]
|
||||
end
|
||||
|
||||
return Task
|
||||
end
|
||||
|
||||
--- Get all the TASKs from the Mission. This function is useful in GoalFunctions.
|
||||
-- @return {TASK,...} Structure of TASKS with the @{TASK} number as the key.
|
||||
-- @usage
|
||||
@@ -352,7 +622,7 @@ end
|
||||
function MISSION:GetTasks()
|
||||
self:F()
|
||||
|
||||
return self._Tasks
|
||||
return self.Tasks
|
||||
end
|
||||
|
||||
|
||||
@@ -374,6 +644,7 @@ _TransportExecuteStage = {
|
||||
|
||||
--- The MISSIONSCHEDULER is an OBJECT and is the main scheduler of ALL active MISSIONs registered within this scheduler. It's workings are considered internal and is automatically created when the Mission.lua file is included.
|
||||
-- @type MISSIONSCHEDULER
|
||||
-- @field #MISSIONSCHEDULER.MISSIONS Missions
|
||||
MISSIONSCHEDULER = {
|
||||
Missions = {},
|
||||
MissionCount = 0,
|
||||
@@ -383,20 +654,28 @@ MISSIONSCHEDULER = {
|
||||
TimeShow = 5
|
||||
}
|
||||
|
||||
--- @type MISSIONSCHEDULER.MISSIONS
|
||||
-- @list <#MISSION> Mission
|
||||
|
||||
--- This is the main MISSIONSCHEDULER Scheduler function. It is considered internal and is automatically created when the Mission.lua file is included.
|
||||
function MISSIONSCHEDULER.Scheduler()
|
||||
|
||||
|
||||
-- loop through the missions in the TransportTasks
|
||||
for MissionName, Mission in pairs( MISSIONSCHEDULER.Missions ) do
|
||||
|
||||
for MissionName, MissionData in pairs( MISSIONSCHEDULER.Missions ) do
|
||||
|
||||
local Mission = MissionData -- #MISSION
|
||||
|
||||
if not Mission:IsCompleted() then
|
||||
|
||||
-- This flag will monitor if for this mission, there are clients alive. If this flag is still false at the end of the loop, the mission status will be set to Pending (if not Failed or Completed).
|
||||
local ClientsAlive = false
|
||||
|
||||
for ClientID, Client in pairs( Mission._Clients ) do
|
||||
for ClientID, ClientData in pairs( Mission._Clients ) do
|
||||
|
||||
local Client = ClientData -- Wrapper.Client#CLIENT
|
||||
|
||||
if Client:GetDCSGroup() then
|
||||
if Client:IsAlive() then
|
||||
|
||||
-- There is at least one Client that is alive... So the Mission status is set to Ongoing.
|
||||
ClientsAlive = true
|
||||
@@ -424,7 +703,7 @@ function MISSIONSCHEDULER.Scheduler()
|
||||
|
||||
-- For each Client, check for each Task the state and evolve the mission.
|
||||
-- This flag will indicate if the Task of the Client is Complete.
|
||||
TaskComplete = false
|
||||
local TaskComplete = false
|
||||
|
||||
for TaskNumber, Task in pairs( Client._Tasks ) do
|
||||
|
||||
@@ -474,7 +753,9 @@ function MISSIONSCHEDULER.Scheduler()
|
||||
if Mission.GoalFunction ~= nil then
|
||||
Mission.GoalFunction( Mission, Client )
|
||||
end
|
||||
_DATABASE:_AddMissionTaskScore( Client:GetClientGroupDCSUnit(), Mission.Name, 25 )
|
||||
if MISSIONSCHEDULER.Scoring then
|
||||
MISSIONSCHEDULER.Scoring:_AddMissionTaskScore( Client:GetClientGroupDCSUnit(), Mission.Name, 25 )
|
||||
end
|
||||
|
||||
-- if not Mission:IsCompleted() then
|
||||
-- end
|
||||
@@ -537,12 +818,15 @@ function MISSIONSCHEDULER.Scheduler()
|
||||
Mission:ReportToAll()
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
--- Start the MISSIONSCHEDULER.
|
||||
function MISSIONSCHEDULER.Start()
|
||||
if MISSIONSCHEDULER ~= nil then
|
||||
MISSIONSCHEDULER.SchedulerId = routines.scheduleFunction( MISSIONSCHEDULER.Scheduler, { }, 0, 2 )
|
||||
--MISSIONSCHEDULER.SchedulerId = routines.scheduleFunction( MISSIONSCHEDULER.Scheduler, { }, 0, 2 )
|
||||
MISSIONSCHEDULER.SchedulerId = SCHEDULER:New( nil, MISSIONSCHEDULER.Scheduler, { }, 0, 2 )
|
||||
end
|
||||
end
|
||||
|
||||
@@ -568,7 +852,7 @@ function MISSIONSCHEDULER.AddMission( Mission )
|
||||
MISSIONSCHEDULER.Missions[Mission.Name] = Mission
|
||||
MISSIONSCHEDULER.MissionCount = MISSIONSCHEDULER.MissionCount + 1
|
||||
-- Add an overall AI Client for the AI tasks... This AI Client will facilitate the Events in the background for each Task.
|
||||
--MissionAdd:AddClient( CLIENT:New( 'AI' ) )
|
||||
--MissionAdd:AddClient( CLIENT:Register( 'AI' ) )
|
||||
|
||||
return Mission
|
||||
end
|
||||
@@ -650,7 +934,7 @@ function MISSIONSCHEDULER:TimeShow()
|
||||
self.TimeIntervalCount = self.TimeIntervalCount + 1
|
||||
if self.TimeIntervalCount >= self.TimeTriggerShow then
|
||||
local TimeMsg = string.format("%00d", ( self.TimeSeconds / 60 ) - ( timer.getTime() / 60 )) .. ' minutes left until mission reload.'
|
||||
MESSAGE:New( TimeMsg, "Mission time", self.TimeShow, '/TimeMsg' ):ToAll()
|
||||
MESSAGE:New( TimeMsg, self.TimeShow, "Mission time" ):ToAll()
|
||||
self.TimeIntervalCount = 0
|
||||
end
|
||||
end
|
||||
1034
Moose Development/Moose/Tasking/Task.lua
Normal file
1034
Moose Development/Moose/Tasking/Task.lua
Normal file
File diff suppressed because it is too large
Load Diff
84
Moose Development/Moose/Tasking/Task_A2G.lua
Normal file
84
Moose Development/Moose/Tasking/Task_A2G.lua
Normal file
@@ -0,0 +1,84 @@
|
||||
--- (AI) (SP) (MP) Tasking for Air to Ground Processes.
|
||||
--
|
||||
-- 1) @{#TASK_A2G} class, extends @{Task#TASK}
|
||||
-- =================================================
|
||||
-- The @{#TASK_A2G} class defines a CAS or BAI task of a @{Set} of Target Units,
|
||||
-- located at a Target Zone, based on the tasking capabilities defined in @{Task#TASK}.
|
||||
-- The TASK_A2G is implemented using a @{Statemachine#FSM_TASK}, and has the following statuses:
|
||||
--
|
||||
-- * **None**: Start of the process
|
||||
-- * **Planned**: The SEAD task is planned. Upon Planned, the sub-process @{Process_Fsm.Assign#ACT_ASSIGN_ACCEPT} is started to accept the task.
|
||||
-- * **Assigned**: The SEAD task is assigned to a @{Group#GROUP}. Upon Assigned, the sub-process @{Process_Fsm.Route#ACT_ROUTE} is started to route the active Units in the Group to the attack zone.
|
||||
-- * **Success**: The SEAD task is successfully completed. Upon Success, the sub-process @{Process_SEAD#PROCESS_SEAD} is started to follow-up successful SEADing of the targets assigned in the task.
|
||||
-- * **Failed**: The SEAD task has failed. This will happen if the player exists the task early, without communicating a possible cancellation to HQ.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- ### Authors: FlightControl - Design and Programming
|
||||
--
|
||||
-- @module Task_A2G
|
||||
|
||||
|
||||
do -- TASK_A2G
|
||||
|
||||
--- The TASK_A2G class
|
||||
-- @type TASK_A2G
|
||||
-- @extends Tasking.Task#TASK
|
||||
TASK_A2G = {
|
||||
ClassName = "TASK_A2G",
|
||||
}
|
||||
|
||||
--- Instantiates a new TASK_A2G.
|
||||
-- @param #TASK_A2G self
|
||||
-- @param Tasking.Mission#MISSION Mission
|
||||
-- @param Set#SET_GROUP SetGroup The set of groups for which the Task can be assigned.
|
||||
-- @param #string TaskName The name of the Task.
|
||||
-- @param #string TaskType BAI or CAS
|
||||
-- @param Set#SET_UNIT UnitSetTargets
|
||||
-- @param Core.Zone#ZONE_BASE TargetZone
|
||||
-- @return #TASK_A2G self
|
||||
function TASK_A2G:New( Mission, SetGroup, TaskName, TaskType, TargetSetUnit, TargetZone, FACUnit )
|
||||
local self = BASE:Inherit( self, TASK:New( Mission, SetGroup, TaskName, TaskType ) )
|
||||
self:F()
|
||||
|
||||
self.TargetSetUnit = TargetSetUnit
|
||||
self.TargetZone = TargetZone
|
||||
self.FACUnit = FACUnit
|
||||
|
||||
local A2GUnitProcess = self:GetUnitProcess()
|
||||
|
||||
A2GUnitProcess:AddProcess ( "Planned", "Accept", ACT_ASSIGN_ACCEPT:New( "Attack the Area" ), { Assigned = "Route", Rejected = "Eject" } )
|
||||
A2GUnitProcess:AddProcess ( "Assigned", "Route", ACT_ROUTE_ZONE:New( self.TargetZone ), { Arrived = "Update" } )
|
||||
A2GUnitProcess:AddTransition( "Rejected", "Eject", "Planned" )
|
||||
A2GUnitProcess:AddTransition( "Arrived", "Update", "Updated" )
|
||||
A2GUnitProcess:AddProcess ( "Updated", "Account", ACT_ACCOUNT_DEADS:New( self.TargetSetUnit, "Attack" ), { Accounted = "Success" } )
|
||||
A2GUnitProcess:AddProcess ( "Updated", "Smoke", ACT_ASSIST_SMOKE_TARGETS_ZONE:New( self.TargetSetUnit, self.TargetZone ) )
|
||||
--Fsm:AddProcess ( "Updated", "JTAC", PROCESS_JTAC:New( self, TaskUnit, self.TargetSetUnit, self.FACUnit ) )
|
||||
A2GUnitProcess:AddTransition( "Accounted", "Success", "Success" )
|
||||
A2GUnitProcess:AddTransition( "Failed", "Fail", "Failed" )
|
||||
|
||||
function A2GUnitProcess:onenterUpdated( TaskUnit )
|
||||
self:E( { self } )
|
||||
self:Account()
|
||||
self:Smoke()
|
||||
end
|
||||
|
||||
|
||||
|
||||
--_EVENTDISPATCHER:OnPlayerLeaveUnit( self._EventPlayerLeaveUnit, self )
|
||||
--_EVENTDISPATCHER:OnDead( self._EventDead, self )
|
||||
--_EVENTDISPATCHER:OnCrash( self._EventDead, self )
|
||||
--_EVENTDISPATCHER:OnPilotDead( self._EventDead, self )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- @param #TASK_A2G self
|
||||
function TASK_A2G:GetPlannedMenuText()
|
||||
return self:GetStateString() .. " - " .. self:GetTaskName() .. " ( " .. self.TargetSetUnit:GetUnitTypesText() .. " )"
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
137
Moose Development/Moose/Tasking/Task_Pickup.lua
Normal file
137
Moose Development/Moose/Tasking/Task_Pickup.lua
Normal file
@@ -0,0 +1,137 @@
|
||||
--- This module contains the TASK_PICKUP classes.
|
||||
--
|
||||
-- 1) @{#TASK_PICKUP} class, extends @{Task#TASK}
|
||||
-- ===================================================
|
||||
-- The @{#TASK_PICKUP} class defines a pickup task of a @{Set} of @{CARGO} objects defined within the mission.
|
||||
-- based on the tasking capabilities defined in @{Task#TASK}.
|
||||
-- The TASK_PICKUP is implemented using a @{Statemachine#FSM_TASK}, and has the following statuses:
|
||||
--
|
||||
-- * **None**: Start of the process
|
||||
-- * **Planned**: The SEAD task is planned. Upon Planned, the sub-process @{Process_Fsm.Assign#ACT_ASSIGN_ACCEPT} is started to accept the task.
|
||||
-- * **Assigned**: The SEAD task is assigned to a @{Group#GROUP}. Upon Assigned, the sub-process @{Process_Fsm.Route#ACT_ROUTE} is started to route the active Units in the Group to the attack zone.
|
||||
-- * **Success**: The SEAD task is successfully completed. Upon Success, the sub-process @{Process_SEAD#PROCESS_SEAD} is started to follow-up successful SEADing of the targets assigned in the task.
|
||||
-- * **Failed**: The SEAD task has failed. This will happen if the player exists the task early, without communicating a possible cancellation to HQ.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- ### Authors: FlightControl - Design and Programming
|
||||
--
|
||||
-- @module Task_PICKUP
|
||||
|
||||
|
||||
do -- TASK_PICKUP
|
||||
|
||||
--- The TASK_PICKUP class
|
||||
-- @type TASK_PICKUP
|
||||
-- @extends Tasking.Task#TASK
|
||||
TASK_PICKUP = {
|
||||
ClassName = "TASK_PICKUP",
|
||||
}
|
||||
|
||||
--- Instantiates a new TASK_PICKUP.
|
||||
-- @param #TASK_PICKUP self
|
||||
-- @param Tasking.Mission#MISSION Mission
|
||||
-- @param Set#SET_GROUP AssignedSetGroup The set of groups for which the Task can be assigned.
|
||||
-- @param #string TaskName The name of the Task.
|
||||
-- @param #string TaskType BAI or CAS
|
||||
-- @param Set#SET_UNIT UnitSetTargets
|
||||
-- @param Core.Zone#ZONE_BASE TargetZone
|
||||
-- @return #TASK_PICKUP self
|
||||
function TASK_PICKUP:New( Mission, AssignedSetGroup, TaskName, TaskType )
|
||||
local self = BASE:Inherit( self, TASK:New( Mission, AssignedSetGroup, TaskName, TaskType, "PICKUP" ) )
|
||||
self:F()
|
||||
|
||||
_EVENTDISPATCHER:OnPlayerLeaveUnit( self._EventPlayerLeaveUnit, self )
|
||||
_EVENTDISPATCHER:OnDead( self._EventDead, self )
|
||||
_EVENTDISPATCHER:OnCrash( self._EventDead, self )
|
||||
_EVENTDISPATCHER:OnPilotDead( self._EventDead, self )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Removes a TASK_PICKUP.
|
||||
-- @param #TASK_PICKUP self
|
||||
-- @return #nil
|
||||
function TASK_PICKUP:CleanUp()
|
||||
|
||||
self:GetParent( self ):CleanUp()
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
--- Assign the @{Task} to a @{Unit}.
|
||||
-- @param #TASK_PICKUP self
|
||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||
-- @return #TASK_PICKUP self
|
||||
function TASK_PICKUP:AssignToUnit( TaskUnit )
|
||||
self:F( TaskUnit:GetName() )
|
||||
|
||||
local ProcessAssign = self:AddProcess( TaskUnit, ACT_ASSIGN_ACCEPT:New( self, TaskUnit, self.TaskBriefing ) )
|
||||
local ProcessPickup = self:AddProcess( TaskUnit, PROCESS_PICKUP:New( self, self.TaskType, TaskUnit ) )
|
||||
|
||||
local Process = self:AddStateMachine( TaskUnit, FSM_TASK:New( self, TaskUnit, {
|
||||
initial = 'None',
|
||||
events = {
|
||||
{ name = 'Next', from = 'None', to = 'Planned' },
|
||||
{ name = 'Next', from = 'Planned', to = 'Assigned' },
|
||||
{ name = 'Next', from = 'Assigned', to = 'Success' },
|
||||
{ name = 'Fail', from = 'Assigned', to = 'Failed' },
|
||||
},
|
||||
callbacks = {
|
||||
onNext = self.OnNext,
|
||||
},
|
||||
subs = {
|
||||
Assign = { onstateparent = 'Planned', oneventparent = 'Next', fsm = ProcessAssign.Fsm, event = 'Start', returnevents = { 'Next', 'Reject' } },
|
||||
Pickup = { onstateparent = 'Assigned', oneventparent = 'Next', fsm = ProcessDestroy.Fsm, event = 'Start', returnevents = { 'Next' } },
|
||||
}
|
||||
} ) )
|
||||
|
||||
ProcessRoute:AddScore( "Failed", "failed to destroy a ground unit", -100 )
|
||||
ProcessDestroy:AddScore( "Pickup", "Picked-Up a Cargo", 25 )
|
||||
ProcessDestroy:AddScore( "Failed", "failed to destroy a ground unit", -100 )
|
||||
|
||||
Process:Next()
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- StateMachine callback function for a TASK
|
||||
-- @param #TASK_PICKUP self
|
||||
-- @param Core.Fsm#FSM_TASK Fsm
|
||||
-- @param #string Event
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
-- @param Event#EVENTDATA Event
|
||||
function TASK_PICKUP:OnNext( Fsm, From, Event, To, Event )
|
||||
|
||||
self:SetState( self, "State", To )
|
||||
|
||||
end
|
||||
|
||||
--- @param #TASK_PICKUP self
|
||||
function TASK_PICKUP:GetPlannedMenuText()
|
||||
return self:GetStateString() .. " - " .. self:GetTaskName() .. " ( " .. self.TargetSetUnit:GetUnitTypesText() .. " )"
|
||||
end
|
||||
|
||||
|
||||
--- @param #TASK_PICKUP self
|
||||
function TASK_PICKUP:_Schedule()
|
||||
self:F2()
|
||||
|
||||
self.TaskScheduler = SCHEDULER:New( self, _Scheduler, {}, 15, 15 )
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
--- @param #TASK_PICKUP self
|
||||
function TASK_PICKUP._Scheduler()
|
||||
self:F2()
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
78
Moose Development/Moose/Tasking/Task_SEAD.lua
Normal file
78
Moose Development/Moose/Tasking/Task_SEAD.lua
Normal file
@@ -0,0 +1,78 @@
|
||||
--- This module contains the TASK_SEAD classes.
|
||||
--
|
||||
-- 1) @{#TASK_SEAD} class, extends @{Task#TASK}
|
||||
-- =================================================
|
||||
-- The @{#TASK_SEAD} class defines a SEAD task for a @{Set} of Target Units, located at a Target Zone,
|
||||
-- based on the tasking capabilities defined in @{Task#TASK}.
|
||||
-- The TASK_SEAD is implemented using a @{Statemachine#FSM_TASK}, and has the following statuses:
|
||||
--
|
||||
-- * **None**: Start of the process
|
||||
-- * **Planned**: The SEAD task is planned. Upon Planned, the sub-process @{Process_Fsm.Assign#ACT_ASSIGN_ACCEPT} is started to accept the task.
|
||||
-- * **Assigned**: The SEAD task is assigned to a @{Group#GROUP}. Upon Assigned, the sub-process @{Process_Fsm.Route#ACT_ROUTE} is started to route the active Units in the Group to the attack zone.
|
||||
-- * **Success**: The SEAD task is successfully completed. Upon Success, the sub-process @{Process_SEAD#PROCESS_SEAD} is started to follow-up successful SEADing of the targets assigned in the task.
|
||||
-- * **Failed**: The SEAD task has failed. This will happen if the player exists the task early, without communicating a possible cancellation to HQ.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- ### Authors: FlightControl - Design and Programming
|
||||
--
|
||||
-- @module Task_SEAD
|
||||
|
||||
|
||||
|
||||
do -- TASK_SEAD
|
||||
|
||||
--- The TASK_SEAD class
|
||||
-- @type TASK_SEAD
|
||||
-- @field Set#SET_UNIT TargetSetUnit
|
||||
-- @extends Tasking.Task#TASK
|
||||
TASK_SEAD = {
|
||||
ClassName = "TASK_SEAD",
|
||||
}
|
||||
|
||||
--- Instantiates a new TASK_SEAD.
|
||||
-- @param #TASK_SEAD self
|
||||
-- @param Tasking.Mission#MISSION Mission
|
||||
-- @param Set#SET_GROUP SetGroup The set of groups for which the Task can be assigned.
|
||||
-- @param #string TaskName The name of the Task.
|
||||
-- @param Set#SET_UNIT UnitSetTargets
|
||||
-- @param Core.Zone#ZONE_BASE TargetZone
|
||||
-- @return #TASK_SEAD self
|
||||
function TASK_SEAD:New( Mission, SetGroup, TaskName, TargetSetUnit, TargetZone )
|
||||
local self = BASE:Inherit( self, TASK:New( Mission, SetGroup, TaskName, "SEAD" ) ) -- Tasking.Task_SEAD#TASK_SEAD
|
||||
self:F()
|
||||
|
||||
self.TargetSetUnit = TargetSetUnit
|
||||
self.TargetZone = TargetZone
|
||||
|
||||
local Fsm = self:GetUnitProcess()
|
||||
|
||||
Fsm:AddProcess ( "Planned", "Accept", ACT_ASSIGN_ACCEPT:New( self.TaskBriefing ), { Assigned = "Route", Rejected = "Eject" } )
|
||||
Fsm:AddProcess ( "Assigned", "Route", ACT_ROUTE_ZONE:New( self.TargetZone ), { Arrived = "Update" } )
|
||||
Fsm:AddTransition( "Rejected", "Eject", "Planned" )
|
||||
Fsm:AddTransition( "Arrived", "Update", "Updated" )
|
||||
Fsm:AddProcess ( "Updated", "Account", ACT_ACCOUNT_DEADS:New( self.TargetSetUnit, "SEAD" ), { Accounted = "Success" } )
|
||||
Fsm:AddProcess ( "Updated", "Smoke", ACT_ASSIST_SMOKE_TARGETS_ZONE:New( self.TargetSetUnit, self.TargetZone ) )
|
||||
Fsm:AddTransition( "Accounted", "Success", "Success" )
|
||||
Fsm:AddTransition( "Failed", "Fail", "Failed" )
|
||||
|
||||
function Fsm:onenterUpdated( TaskUnit )
|
||||
self:E( { self } )
|
||||
self:Account()
|
||||
self:Smoke()
|
||||
end
|
||||
|
||||
-- _EVENTDISPATCHER:OnPlayerLeaveUnit( self._EventPlayerLeaveUnit, self )
|
||||
-- _EVENTDISPATCHER:OnDead( self._EventDead, self )
|
||||
-- _EVENTDISPATCHER:OnCrash( self._EventDead, self )
|
||||
-- _EVENTDISPATCHER:OnPilotDead( self._EventDead, self )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- @param #TASK_SEAD self
|
||||
function TASK_SEAD:GetPlannedMenuText()
|
||||
return self:GetStateString() .. " - " .. self:GetTaskName() .. " ( " .. self.TargetSetUnit:GetUnitTypesText() .. " )"
|
||||
end
|
||||
|
||||
end
|
||||
@@ -2,10 +2,6 @@
|
||||
-- @module routines
|
||||
-- @author Flightcontrol
|
||||
|
||||
--Include.File( "Trace" )
|
||||
--Include.File( "Message" )
|
||||
|
||||
|
||||
env.setErrorMessageBoxEnabled(false)
|
||||
|
||||
--- Extract of MIST functions.
|
||||
@@ -249,22 +245,6 @@ end
|
||||
|
||||
|
||||
|
||||
-- From http://lua-users.org/wiki/SimpleRound
|
||||
-- use negative idp for rounding ahead of decimal place, positive for rounding after decimal place
|
||||
routines.utils.round = function(num, idp)
|
||||
local mult = 10^(idp or 0)
|
||||
return math.floor(num * mult + 0.5) / mult
|
||||
end
|
||||
|
||||
-- porting in Slmod's dostring
|
||||
routines.utils.dostring = function(s)
|
||||
local f, err = loadstring(s)
|
||||
if f then
|
||||
return true, f()
|
||||
else
|
||||
return false, err
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--3D Vector manipulation
|
||||
@@ -445,118 +425,6 @@ routines.getNorthCorrection = function(point) --gets the correction needed for
|
||||
end
|
||||
|
||||
|
||||
-- the main area
|
||||
do
|
||||
-- THE MAIN FUNCTION -- Accessed 100 times/sec.
|
||||
routines.main = function()
|
||||
timer.scheduleFunction(routines.main, {}, timer.getTime() + 2) --reschedule first in case of Lua error
|
||||
----------------------------------------------------------------------------------------------------------
|
||||
--area to add new stuff in
|
||||
|
||||
routines.do_scheduled_functions()
|
||||
end -- end of routines.main
|
||||
|
||||
timer.scheduleFunction(routines.main, {}, timer.getTime() + 2)
|
||||
|
||||
end
|
||||
|
||||
|
||||
do
|
||||
local Tasks = {}
|
||||
local task_id = 0
|
||||
--[[ routines.scheduleFunction:
|
||||
int id = routines.schedule_task(f function, vars table, t number, rep number, st number)
|
||||
id - integer id of this function task
|
||||
f - function to run
|
||||
vars - table of vars for that function
|
||||
t - time to run function
|
||||
rep - time between repetitions of this function (OPTIONAL)
|
||||
st - time when repetitions of this function will stop automatically (OPTIONAL)
|
||||
]]
|
||||
|
||||
--- Schedule a function
|
||||
-- @param #function f
|
||||
-- @param #table parameters
|
||||
-- @param #Time t
|
||||
-- @param #Time rep seconds
|
||||
-- @param #Time st
|
||||
routines.scheduleFunction = function(f, vars, t, rep, st)
|
||||
--verify correct types
|
||||
assert(type(f) == 'function', 'variable 1, expected function, got ' .. type(f))
|
||||
assert(type(vars) == 'table' or vars == nil, 'variable 2, expected table or nil, got ' .. type(f))
|
||||
assert(type(t) == 'number', 'variable 3, expected number, got ' .. type(t))
|
||||
assert(type(rep) == 'number' or rep == nil, 'variable 4, expected number or nil, got ' .. type(rep))
|
||||
assert(type(st) == 'number' or st == nil, 'variable 5, expected number or nil, got ' .. type(st))
|
||||
if not vars then
|
||||
vars = {}
|
||||
end
|
||||
task_id = task_id + 1
|
||||
table.insert(Tasks, {f = f, vars = vars, t = t, rep = rep, st = st, id = task_id})
|
||||
return task_id
|
||||
end
|
||||
|
||||
-- removes a scheduled function based on the function's id. returns true if successful, false if not successful.
|
||||
routines.removeFunction = function(id)
|
||||
local i = 1
|
||||
while i <= #Tasks do
|
||||
if Tasks[i].id == id then
|
||||
table.remove(Tasks, i)
|
||||
else
|
||||
i = i + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
routines.errhandler = function(errmsg)
|
||||
|
||||
env.info( "Error in scheduled function:" .. errmsg )
|
||||
env.info( debug.traceback() )
|
||||
|
||||
return errmsg
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------------------------------------------
|
||||
-- not intended for users to use this function.
|
||||
routines.do_scheduled_functions = function()
|
||||
local i = 1
|
||||
while i <= #Tasks do
|
||||
if not Tasks[i].rep then -- not a repeated process
|
||||
if Tasks[i].t <= timer.getTime() then
|
||||
local Task = Tasks[i] -- local reference
|
||||
--env.info("do_scheduled_functions:call function " .. i )
|
||||
table.remove(Tasks, i)
|
||||
local err, errmsg = xpcall(function() Task.f( unpack(Task.vars, 1, table.maxn(Task.vars))) end, routines.errhandler )
|
||||
if not err then
|
||||
--env.info('routines.scheduleFunction, error in scheduled function: ' .. errmsg)
|
||||
end
|
||||
--Task.f(unpack(Task.vars, 1, table.maxn(Task.vars))) -- do the task, do not increment i
|
||||
else
|
||||
i = i + 1
|
||||
end
|
||||
else
|
||||
if Tasks[i].st and Tasks[i].st <= timer.getTime() then --if a stoptime was specified, and the stop time exceeded
|
||||
--env.info("do_scheduled_functions:remove repeated")
|
||||
table.remove(Tasks, i) -- stop time exceeded, do not execute, do not increment i
|
||||
elseif Tasks[i].t <= timer.getTime() then
|
||||
local Task = Tasks[i] -- local reference
|
||||
Task.t = timer.getTime() + Task.rep --schedule next run
|
||||
--env.info("do_scheduled_functions:call function " .. i )
|
||||
local err, errmsg = xpcall(function() Task.f( unpack(Task.vars, 1, table.maxn(Task.vars))) end, routines.errhandler )
|
||||
if not err then
|
||||
--env.info('routines.scheduleFunction, error in scheduled function: ' .. errmsg)
|
||||
end
|
||||
--Tasks[i].f(unpack(Tasks[i].vars, 1, table.maxn(Tasks[i].vars))) -- do the task
|
||||
i = i + 1
|
||||
else
|
||||
i = i + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
do
|
||||
local idNum = 0
|
||||
|
||||
@@ -1524,6 +1392,47 @@ function routines.IsUnitInZones( TransportUnit, LandingZones )
|
||||
end
|
||||
end
|
||||
|
||||
function routines.IsUnitNearZonesRadius( TransportUnit, LandingZones, ZoneRadius )
|
||||
--trace.f("", "routines.IsUnitInZones" )
|
||||
|
||||
local TransportZoneResult = nil
|
||||
local TransportZonePos = nil
|
||||
local TransportZone = nil
|
||||
|
||||
-- fill-up some local variables to support further calculations to determine location of units within the zone.
|
||||
if TransportUnit then
|
||||
local TransportUnitPos = TransportUnit:getPosition().p
|
||||
if type( LandingZones ) == "table" then
|
||||
for LandingZoneID, LandingZoneName in pairs( LandingZones ) do
|
||||
TransportZone = trigger.misc.getZone( LandingZoneName )
|
||||
if TransportZone then
|
||||
TransportZonePos = {radius = TransportZone.radius, x = TransportZone.point.x, y = TransportZone.point.y, z = TransportZone.point.z}
|
||||
if ((( TransportUnitPos.x - TransportZonePos.x)^2 + (TransportUnitPos.z - TransportZonePos.z)^2)^0.5 <= ZoneRadius ) then
|
||||
TransportZoneResult = LandingZoneID
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
TransportZone = trigger.misc.getZone( LandingZones )
|
||||
TransportZonePos = {radius = TransportZone.radius, x = TransportZone.point.x, y = TransportZone.point.y, z = TransportZone.point.z}
|
||||
if ((( TransportUnitPos.x - TransportZonePos.x)^2 + (TransportUnitPos.z - TransportZonePos.z)^2)^0.5 <= ZoneRadius ) then
|
||||
TransportZoneResult = 1
|
||||
end
|
||||
end
|
||||
if TransportZoneResult then
|
||||
--trace.i( "routines", "TransportZone:" .. TransportZoneResult )
|
||||
else
|
||||
--trace.i( "routines", "TransportZone:nil logic" )
|
||||
end
|
||||
return TransportZoneResult
|
||||
else
|
||||
--trace.i( "routines", "TransportZone:nil hard" )
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function routines.IsStaticInZones( TransportStatic, LandingZones )
|
||||
--trace.f()
|
||||
|
||||
@@ -1696,7 +1605,7 @@ function routines.getGroupRoute(groupIdent, task) -- same as getGroupPoints bu
|
||||
-- refactor to search by groupId and allow groupId and groupName as inputs
|
||||
local gpId = groupIdent
|
||||
if type(groupIdent) == 'string' and not tonumber(groupIdent) then
|
||||
gpId = _DATABASE.Groups[groupIdent].groupId
|
||||
gpId = _DATABASE.Templates.Groups[groupIdent].groupId
|
||||
end
|
||||
|
||||
for coa_name, coa_data in pairs(env.mission.coalition) do
|
||||
@@ -2365,19 +2274,19 @@ end
|
||||
function MessageToAll( MsgText, MsgTime, MsgName )
|
||||
--trace.f()
|
||||
|
||||
MESSAGE:New( MsgText, "Message", MsgTime, MsgName ):ToCoalition( coalition.side.RED ):ToCoalition( coalition.side.BLUE )
|
||||
MESSAGE:New( MsgText, MsgTime, "Message" ):ToCoalition( coalition.side.RED ):ToCoalition( coalition.side.BLUE )
|
||||
end
|
||||
|
||||
function MessageToRed( MsgText, MsgTime, MsgName )
|
||||
--trace.f()
|
||||
|
||||
MESSAGE:New( MsgText, "To Red Coalition", MsgTime, MsgName ):ToCoalition( coalition.side.RED )
|
||||
MESSAGE:New( MsgText, MsgTime, "To Red Coalition" ):ToCoalition( coalition.side.RED )
|
||||
end
|
||||
|
||||
function MessageToBlue( MsgText, MsgTime, MsgName )
|
||||
--trace.f()
|
||||
|
||||
MESSAGE:New( MsgText, "To Blue Coalition", MsgTime, MsgName ):ToCoalition( coalition.side.RED )
|
||||
MESSAGE:New( MsgText, MsgTime, "To Blue Coalition" ):ToCoalition( coalition.side.RED )
|
||||
end
|
||||
|
||||
function getCarrierHeight( CarrierGroup )
|
||||
@@ -1,7 +1,7 @@
|
||||
--- Provides a logging of statistics in a running DCS Mission.
|
||||
-- @script eStatHandler
|
||||
|
||||
Include.File( "Routines" )
|
||||
|
||||
|
||||
|
||||
--Handler table
|
||||
295
Moose Development/Moose/Utilities/Utils.lua
Normal file
295
Moose Development/Moose/Utilities/Utils.lua
Normal file
@@ -0,0 +1,295 @@
|
||||
--- This module contains derived utilities taken from the MIST framework,
|
||||
-- which are excellent tools to be reused in an OO environment!.
|
||||
--
|
||||
-- ### Authors:
|
||||
--
|
||||
-- * Grimes : Design & Programming of the MIST framework.
|
||||
--
|
||||
-- ### Contributions:
|
||||
--
|
||||
-- * FlightControl : Rework to OO framework
|
||||
--
|
||||
-- @module Utils
|
||||
|
||||
|
||||
--- @type SMOKECOLOR
|
||||
-- @field Green
|
||||
-- @field Red
|
||||
-- @field White
|
||||
-- @field Orange
|
||||
-- @field Blue
|
||||
|
||||
SMOKECOLOR = trigger.smokeColor -- #SMOKECOLOR
|
||||
|
||||
--- @type FLARECOLOR
|
||||
-- @field Green
|
||||
-- @field Red
|
||||
-- @field White
|
||||
-- @field Yellow
|
||||
|
||||
FLARECOLOR = trigger.flareColor -- #FLARECOLOR
|
||||
|
||||
--- Utilities static class.
|
||||
-- @type UTILS
|
||||
UTILS = {}
|
||||
|
||||
|
||||
--from http://lua-users.org/wiki/CopyTable
|
||||
UTILS.DeepCopy = function(object)
|
||||
local lookup_table = {}
|
||||
local function _copy(object)
|
||||
if type(object) ~= "table" then
|
||||
return object
|
||||
elseif lookup_table[object] then
|
||||
return lookup_table[object]
|
||||
end
|
||||
local new_table = {}
|
||||
lookup_table[object] = new_table
|
||||
for index, value in pairs(object) do
|
||||
new_table[_copy(index)] = _copy(value)
|
||||
end
|
||||
return setmetatable(new_table, getmetatable(object))
|
||||
end
|
||||
local objectreturn = _copy(object)
|
||||
return objectreturn
|
||||
end
|
||||
|
||||
|
||||
-- porting in Slmod's serialize_slmod2
|
||||
UTILS.OneLineSerialize = function( tbl ) -- serialization of a table all on a single line, no comments, made to replace old get_table_string function
|
||||
|
||||
lookup_table = {}
|
||||
|
||||
local function _Serialize( tbl )
|
||||
|
||||
if type(tbl) == 'table' then --function only works for tables!
|
||||
|
||||
if lookup_table[tbl] then
|
||||
return lookup_table[object]
|
||||
end
|
||||
|
||||
local tbl_str = {}
|
||||
|
||||
lookup_table[tbl] = tbl_str
|
||||
|
||||
tbl_str[#tbl_str + 1] = '{'
|
||||
|
||||
for ind,val in pairs(tbl) do -- serialize its fields
|
||||
local ind_str = {}
|
||||
if type(ind) == "number" then
|
||||
ind_str[#ind_str + 1] = '['
|
||||
ind_str[#ind_str + 1] = tostring(ind)
|
||||
ind_str[#ind_str + 1] = ']='
|
||||
else --must be a string
|
||||
ind_str[#ind_str + 1] = '['
|
||||
ind_str[#ind_str + 1] = routines.utils.basicSerialize(ind)
|
||||
ind_str[#ind_str + 1] = ']='
|
||||
end
|
||||
|
||||
local val_str = {}
|
||||
if ((type(val) == 'number') or (type(val) == 'boolean')) then
|
||||
val_str[#val_str + 1] = tostring(val)
|
||||
val_str[#val_str + 1] = ','
|
||||
tbl_str[#tbl_str + 1] = table.concat(ind_str)
|
||||
tbl_str[#tbl_str + 1] = table.concat(val_str)
|
||||
elseif type(val) == 'string' then
|
||||
val_str[#val_str + 1] = routines.utils.basicSerialize(val)
|
||||
val_str[#val_str + 1] = ','
|
||||
tbl_str[#tbl_str + 1] = table.concat(ind_str)
|
||||
tbl_str[#tbl_str + 1] = table.concat(val_str)
|
||||
elseif type(val) == 'nil' then -- won't ever happen, right?
|
||||
val_str[#val_str + 1] = 'nil,'
|
||||
tbl_str[#tbl_str + 1] = table.concat(ind_str)
|
||||
tbl_str[#tbl_str + 1] = table.concat(val_str)
|
||||
elseif type(val) == 'table' then
|
||||
if ind == "__index" then
|
||||
-- tbl_str[#tbl_str + 1] = "__index"
|
||||
-- tbl_str[#tbl_str + 1] = ',' --I think this is right, I just added it
|
||||
else
|
||||
|
||||
val_str[#val_str + 1] = _Serialize(val)
|
||||
val_str[#val_str + 1] = ',' --I think this is right, I just added it
|
||||
tbl_str[#tbl_str + 1] = table.concat(ind_str)
|
||||
tbl_str[#tbl_str + 1] = table.concat(val_str)
|
||||
end
|
||||
elseif type(val) == 'function' then
|
||||
tbl_str[#tbl_str + 1] = "f() " .. tostring(ind)
|
||||
tbl_str[#tbl_str + 1] = ',' --I think this is right, I just added it
|
||||
else
|
||||
env.info('unable to serialize value type ' .. routines.utils.basicSerialize(type(val)) .. ' at index ' .. tostring(ind))
|
||||
env.info( debug.traceback() )
|
||||
end
|
||||
|
||||
end
|
||||
tbl_str[#tbl_str + 1] = '}'
|
||||
return table.concat(tbl_str)
|
||||
else
|
||||
return tostring(tbl)
|
||||
end
|
||||
end
|
||||
|
||||
local objectreturn = _Serialize(tbl)
|
||||
return objectreturn
|
||||
end
|
||||
|
||||
--porting in Slmod's "safestring" basic serialize
|
||||
UTILS.BasicSerialize = function(s)
|
||||
if s == nil then
|
||||
return "\"\""
|
||||
else
|
||||
if ((type(s) == 'number') or (type(s) == 'boolean') or (type(s) == 'function') or (type(s) == 'table') or (type(s) == 'userdata') ) then
|
||||
return tostring(s)
|
||||
elseif type(s) == 'string' then
|
||||
s = string.format('%q', s)
|
||||
return s
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
UTILS.ToDegree = function(angle)
|
||||
return angle*180/math.pi
|
||||
end
|
||||
|
||||
UTILS.ToRadian = function(angle)
|
||||
return angle*math.pi/180
|
||||
end
|
||||
|
||||
UTILS.MetersToNM = function(meters)
|
||||
return meters/1852
|
||||
end
|
||||
|
||||
UTILS.MetersToFeet = function(meters)
|
||||
return meters/0.3048
|
||||
end
|
||||
|
||||
UTILS.NMToMeters = function(NM)
|
||||
return NM*1852
|
||||
end
|
||||
|
||||
UTILS.FeetToMeters = function(feet)
|
||||
return feet*0.3048
|
||||
end
|
||||
|
||||
UTILS.MpsToKnots = function(mps)
|
||||
return mps*3600/1852
|
||||
end
|
||||
|
||||
UTILS.MpsToKmph = function(mps)
|
||||
return mps*3.6
|
||||
end
|
||||
|
||||
UTILS.KnotsToMps = function(knots)
|
||||
return knots*1852/3600
|
||||
end
|
||||
|
||||
UTILS.KmphToMps = function(kmph)
|
||||
return kmph/3.6
|
||||
end
|
||||
|
||||
--[[acc:
|
||||
in DM: decimal point of minutes.
|
||||
In DMS: decimal point of seconds.
|
||||
position after the decimal of the least significant digit:
|
||||
So:
|
||||
42.32 - acc of 2.
|
||||
]]
|
||||
UTILS.tostringLL = function( lat, lon, acc, DMS)
|
||||
|
||||
local latHemi, lonHemi
|
||||
if lat > 0 then
|
||||
latHemi = 'N'
|
||||
else
|
||||
latHemi = 'S'
|
||||
end
|
||||
|
||||
if lon > 0 then
|
||||
lonHemi = 'E'
|
||||
else
|
||||
lonHemi = 'W'
|
||||
end
|
||||
|
||||
lat = math.abs(lat)
|
||||
lon = math.abs(lon)
|
||||
|
||||
local latDeg = math.floor(lat)
|
||||
local latMin = (lat - latDeg)*60
|
||||
|
||||
local lonDeg = math.floor(lon)
|
||||
local lonMin = (lon - lonDeg)*60
|
||||
|
||||
if DMS then -- degrees, minutes, and seconds.
|
||||
local oldLatMin = latMin
|
||||
latMin = math.floor(latMin)
|
||||
local latSec = UTILS.Round((oldLatMin - latMin)*60, acc)
|
||||
|
||||
local oldLonMin = lonMin
|
||||
lonMin = math.floor(lonMin)
|
||||
local lonSec = UTILS.Round((oldLonMin - lonMin)*60, acc)
|
||||
|
||||
if latSec == 60 then
|
||||
latSec = 0
|
||||
latMin = latMin + 1
|
||||
end
|
||||
|
||||
if lonSec == 60 then
|
||||
lonSec = 0
|
||||
lonMin = lonMin + 1
|
||||
end
|
||||
|
||||
local secFrmtStr -- create the formatting string for the seconds place
|
||||
if acc <= 0 then -- no decimal place.
|
||||
secFrmtStr = '%02d'
|
||||
else
|
||||
local width = 3 + acc -- 01.310 - that's a width of 6, for example.
|
||||
secFrmtStr = '%0' .. width .. '.' .. acc .. 'f'
|
||||
end
|
||||
|
||||
return string.format('%02d', latDeg) .. ' ' .. string.format('%02d', latMin) .. '\' ' .. string.format(secFrmtStr, latSec) .. '"' .. latHemi .. ' '
|
||||
.. string.format('%02d', lonDeg) .. ' ' .. string.format('%02d', lonMin) .. '\' ' .. string.format(secFrmtStr, lonSec) .. '"' .. lonHemi
|
||||
|
||||
else -- degrees, decimal minutes.
|
||||
latMin = UTILS.Round(latMin, acc)
|
||||
lonMin = UTILS.Round(lonMin, acc)
|
||||
|
||||
if latMin == 60 then
|
||||
latMin = 0
|
||||
latDeg = latDeg + 1
|
||||
end
|
||||
|
||||
if lonMin == 60 then
|
||||
lonMin = 0
|
||||
lonDeg = lonDeg + 1
|
||||
end
|
||||
|
||||
local minFrmtStr -- create the formatting string for the minutes place
|
||||
if acc <= 0 then -- no decimal place.
|
||||
minFrmtStr = '%02d'
|
||||
else
|
||||
local width = 3 + acc -- 01.310 - that's a width of 6, for example.
|
||||
minFrmtStr = '%0' .. width .. '.' .. acc .. 'f'
|
||||
end
|
||||
|
||||
return string.format('%02d', latDeg) .. ' ' .. string.format(minFrmtStr, latMin) .. '\'' .. latHemi .. ' '
|
||||
.. string.format('%02d', lonDeg) .. ' ' .. string.format(minFrmtStr, lonMin) .. '\'' .. lonHemi
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--- From http://lua-users.org/wiki/SimpleRound
|
||||
-- use negative idp for rounding ahead of decimal place, positive for rounding after decimal place
|
||||
function UTILS.Round( num, idp )
|
||||
local mult = 10 ^ ( idp or 0 )
|
||||
return math.floor( num * mult + 0.5 ) / mult
|
||||
end
|
||||
|
||||
-- porting in Slmod's dostring
|
||||
function UTILS.DoString( s )
|
||||
local f, err = loadstring( s )
|
||||
if f then
|
||||
return true, f()
|
||||
else
|
||||
return false, err
|
||||
end
|
||||
end
|
||||
109
Moose Development/Moose/Wrapper/Airbase.lua
Normal file
109
Moose Development/Moose/Wrapper/Airbase.lua
Normal file
@@ -0,0 +1,109 @@
|
||||
--- This module contains the AIRBASE classes.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- 1) @{Airbase#AIRBASE} class, extends @{Positionable#POSITIONABLE}
|
||||
-- =================================================================
|
||||
-- The @{AIRBASE} class is a wrapper class to handle the DCS Airbase objects:
|
||||
--
|
||||
-- * Support all DCS Airbase APIs.
|
||||
-- * Enhance with Airbase specific APIs not in the DCS Airbase API set.
|
||||
--
|
||||
--
|
||||
-- 1.1) AIRBASE reference methods
|
||||
-- ------------------------------
|
||||
-- For each DCS Airbase object alive within a running mission, a AIRBASE wrapper object (instance) will be created within the _@{DATABASE} object.
|
||||
-- This is done at the beginning of the mission (when the mission starts).
|
||||
--
|
||||
-- The AIRBASE class **does not contain a :New()** method, rather it provides **:Find()** methods to retrieve the object reference
|
||||
-- using the DCS Airbase or the DCS AirbaseName.
|
||||
--
|
||||
-- Another thing to know is that AIRBASE objects do not "contain" the DCS Airbase object.
|
||||
-- The AIRBASE methods will reference the DCS Airbase object by name when it is needed during API execution.
|
||||
-- If the DCS Airbase object does not exist or is nil, the AIRBASE methods will return nil and log an exception in the DCS.log file.
|
||||
--
|
||||
-- The AIRBASE class provides the following functions to retrieve quickly the relevant AIRBASE instance:
|
||||
--
|
||||
-- * @{#AIRBASE.Find}(): Find a AIRBASE instance from the _DATABASE object using a DCS Airbase object.
|
||||
-- * @{#AIRBASE.FindByName}(): Find a AIRBASE instance from the _DATABASE object using a DCS Airbase name.
|
||||
--
|
||||
-- IMPORTANT: ONE SHOULD NEVER SANATIZE these AIRBASE OBJECT REFERENCES! (make the AIRBASE object references nil).
|
||||
--
|
||||
-- 1.2) DCS AIRBASE APIs
|
||||
-- ---------------------
|
||||
-- The DCS Airbase APIs are used extensively within MOOSE. The AIRBASE class has for each DCS Airbase API a corresponding method.
|
||||
-- To be able to distinguish easily in your code the difference between a AIRBASE API call and a DCS Airbase API call,
|
||||
-- the first letter of the method is also capitalized. So, by example, the DCS Airbase method @{DCSWrapper.Airbase#Airbase.getName}()
|
||||
-- is implemented in the AIRBASE class as @{#AIRBASE.GetName}().
|
||||
--
|
||||
-- More functions will be added
|
||||
-- ----------------------------
|
||||
-- During the MOOSE development, more functions will be added.
|
||||
--
|
||||
-- @module Airbase
|
||||
-- @author FlightControl
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--- The AIRBASE class
|
||||
-- @type AIRBASE
|
||||
-- @extends Wrapper.Positionable#POSITIONABLE
|
||||
AIRBASE = {
|
||||
ClassName="AIRBASE",
|
||||
CategoryName = {
|
||||
[Airbase.Category.AIRDROME] = "Airdrome",
|
||||
[Airbase.Category.HELIPAD] = "Helipad",
|
||||
[Airbase.Category.SHIP] = "Ship",
|
||||
},
|
||||
}
|
||||
|
||||
-- Registration.
|
||||
|
||||
--- Create a new AIRBASE from DCSAirbase.
|
||||
-- @param #AIRBASE self
|
||||
-- @param #string AirbaseName The name of the airbase.
|
||||
-- @return Wrapper.Airbase#AIRBASE
|
||||
function AIRBASE:Register( AirbaseName )
|
||||
|
||||
local self = BASE:Inherit( self, POSITIONABLE:New( AirbaseName ) )
|
||||
self.AirbaseName = AirbaseName
|
||||
return self
|
||||
end
|
||||
|
||||
-- Reference methods.
|
||||
|
||||
--- Finds a AIRBASE from the _DATABASE using a DCSAirbase object.
|
||||
-- @param #AIRBASE self
|
||||
-- @param Dcs.DCSWrapper.Airbase#Airbase DCSAirbase An existing DCS Airbase object reference.
|
||||
-- @return Wrapper.Airbase#AIRBASE self
|
||||
function AIRBASE:Find( DCSAirbase )
|
||||
|
||||
local AirbaseName = DCSAirbase:getName()
|
||||
local AirbaseFound = _DATABASE:FindAirbase( AirbaseName )
|
||||
return AirbaseFound
|
||||
end
|
||||
|
||||
--- Find a AIRBASE in the _DATABASE using the name of an existing DCS Airbase.
|
||||
-- @param #AIRBASE self
|
||||
-- @param #string AirbaseName The Airbase Name.
|
||||
-- @return Wrapper.Airbase#AIRBASE self
|
||||
function AIRBASE:FindByName( AirbaseName )
|
||||
|
||||
local AirbaseFound = _DATABASE:FindAirbase( AirbaseName )
|
||||
return AirbaseFound
|
||||
end
|
||||
|
||||
function AIRBASE:GetDCSObject()
|
||||
local DCSAirbase = Airbase.getByName( self.AirbaseName )
|
||||
|
||||
if DCSAirbase then
|
||||
return DCSAirbase
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
|
||||
473
Moose Development/Moose/Wrapper/Client.lua
Normal file
473
Moose Development/Moose/Wrapper/Client.lua
Normal file
@@ -0,0 +1,473 @@
|
||||
--- This module contains the CLIENT class.
|
||||
--
|
||||
-- 1) @{Client#CLIENT} class, extends @{Unit#UNIT}
|
||||
-- ===============================================
|
||||
-- Clients are those **Units** defined within the Mission Editor that have the skillset defined as __Client__ or __Player__.
|
||||
-- Note that clients are NOT the same as Units, they are NOT necessarily alive.
|
||||
-- The @{Client#CLIENT} class is a wrapper class to handle the DCS Unit objects that have the skillset defined as __Client__ or __Player__:
|
||||
--
|
||||
-- * Wraps the DCS Unit objects with skill level set to Player or Client.
|
||||
-- * Support all DCS Unit APIs.
|
||||
-- * Enhance with Unit specific APIs not in the DCS Group API set.
|
||||
-- * When player joins Unit, execute alive init logic.
|
||||
-- * Handles messages to players.
|
||||
-- * Manage the "state" of the DCS Unit.
|
||||
--
|
||||
-- Clients are being used by the @{MISSION} class to follow players and register their successes.
|
||||
--
|
||||
-- 1.1) CLIENT reference methods
|
||||
-- -----------------------------
|
||||
-- For each DCS Unit having skill level Player or Client, a CLIENT wrapper object (instance) will be created within the _@{DATABASE} object.
|
||||
-- This is done at the beginning of the mission (when the mission starts).
|
||||
--
|
||||
-- The CLIENT class does not contain a :New() method, rather it provides :Find() methods to retrieve the object reference
|
||||
-- using the DCS Unit or the DCS UnitName.
|
||||
--
|
||||
-- Another thing to know is that CLIENT objects do not "contain" the DCS Unit object.
|
||||
-- The CLIENT methods will reference the DCS Unit object by name when it is needed during API execution.
|
||||
-- If the DCS Unit object does not exist or is nil, the CLIENT methods will return nil and log an exception in the DCS.log file.
|
||||
--
|
||||
-- The CLIENT class provides the following functions to retrieve quickly the relevant CLIENT instance:
|
||||
--
|
||||
-- * @{#CLIENT.Find}(): Find a CLIENT instance from the _DATABASE object using a DCS Unit object.
|
||||
-- * @{#CLIENT.FindByName}(): Find a CLIENT instance from the _DATABASE object using a DCS Unit name.
|
||||
--
|
||||
-- IMPORTANT: ONE SHOULD NEVER SANATIZE these CLIENT OBJECT REFERENCES! (make the CLIENT object references nil).
|
||||
--
|
||||
-- @module Client
|
||||
|
||||
--- The CLIENT class
|
||||
-- @type CLIENT
|
||||
-- @extends Wrapper.Unit#UNIT
|
||||
CLIENT = {
|
||||
ONBOARDSIDE = {
|
||||
NONE = 0,
|
||||
LEFT = 1,
|
||||
RIGHT = 2,
|
||||
BACK = 3,
|
||||
FRONT = 4
|
||||
},
|
||||
ClassName = "CLIENT",
|
||||
ClientName = nil,
|
||||
ClientAlive = false,
|
||||
ClientTransport = false,
|
||||
ClientBriefingShown = false,
|
||||
_Menus = {},
|
||||
_Tasks = {},
|
||||
Messages = {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
--- Finds a CLIENT from the _DATABASE using the relevant DCS Unit.
|
||||
-- @param #CLIENT self
|
||||
-- @param #string ClientName Name of the DCS **Unit** as defined within the Mission Editor.
|
||||
-- @param #string ClientBriefing Text that describes the briefing of the mission when a Player logs into the Client.
|
||||
-- @return #CLIENT
|
||||
-- @usage
|
||||
-- -- Create new Clients.
|
||||
-- local Mission = MISSIONSCHEDULER.AddMission( 'Russia Transport Troops SA-6', 'Operational', 'Transport troops from the control center to one of the SA-6 SAM sites to activate their operation.', 'Russia' )
|
||||
-- Mission:AddGoal( DeploySA6TroopsGoal )
|
||||
--
|
||||
-- Mission:AddClient( CLIENT:FindByName( 'RU MI-8MTV2*HOT-Deploy Troops 1' ):Transport() )
|
||||
-- Mission:AddClient( CLIENT:FindByName( 'RU MI-8MTV2*RAMP-Deploy Troops 3' ):Transport() )
|
||||
-- Mission:AddClient( CLIENT:FindByName( 'RU MI-8MTV2*HOT-Deploy Troops 2' ):Transport() )
|
||||
-- Mission:AddClient( CLIENT:FindByName( 'RU MI-8MTV2*RAMP-Deploy Troops 4' ):Transport() )
|
||||
function CLIENT:Find( DCSUnit )
|
||||
local ClientName = DCSUnit:getName()
|
||||
local ClientFound = _DATABASE:FindClient( ClientName )
|
||||
|
||||
if ClientFound then
|
||||
ClientFound:F( ClientName )
|
||||
return ClientFound
|
||||
end
|
||||
|
||||
error( "CLIENT not found for: " .. ClientName )
|
||||
end
|
||||
|
||||
|
||||
--- Finds a CLIENT from the _DATABASE using the relevant Client Unit Name.
|
||||
-- As an optional parameter, a briefing text can be given also.
|
||||
-- @param #CLIENT self
|
||||
-- @param #string ClientName Name of the DCS **Unit** as defined within the Mission Editor.
|
||||
-- @param #string ClientBriefing Text that describes the briefing of the mission when a Player logs into the Client.
|
||||
-- @param #boolean Error A flag that indicates whether an error should be raised if the CLIENT cannot be found. By default an error will be raised.
|
||||
-- @return #CLIENT
|
||||
-- @usage
|
||||
-- -- Create new Clients.
|
||||
-- local Mission = MISSIONSCHEDULER.AddMission( 'Russia Transport Troops SA-6', 'Operational', 'Transport troops from the control center to one of the SA-6 SAM sites to activate their operation.', 'Russia' )
|
||||
-- Mission:AddGoal( DeploySA6TroopsGoal )
|
||||
--
|
||||
-- Mission:AddClient( CLIENT:FindByName( 'RU MI-8MTV2*HOT-Deploy Troops 1' ):Transport() )
|
||||
-- Mission:AddClient( CLIENT:FindByName( 'RU MI-8MTV2*RAMP-Deploy Troops 3' ):Transport() )
|
||||
-- Mission:AddClient( CLIENT:FindByName( 'RU MI-8MTV2*HOT-Deploy Troops 2' ):Transport() )
|
||||
-- Mission:AddClient( CLIENT:FindByName( 'RU MI-8MTV2*RAMP-Deploy Troops 4' ):Transport() )
|
||||
function CLIENT:FindByName( ClientName, ClientBriefing, Error )
|
||||
local ClientFound = _DATABASE:FindClient( ClientName )
|
||||
|
||||
if ClientFound then
|
||||
ClientFound:F( { ClientName, ClientBriefing } )
|
||||
ClientFound:AddBriefing( ClientBriefing )
|
||||
ClientFound.MessageSwitch = true
|
||||
|
||||
return ClientFound
|
||||
end
|
||||
|
||||
if not Error then
|
||||
error( "CLIENT not found for: " .. ClientName )
|
||||
end
|
||||
end
|
||||
|
||||
function CLIENT:Register( ClientName )
|
||||
local self = BASE:Inherit( self, UNIT:Register( ClientName ) )
|
||||
|
||||
self:F( ClientName )
|
||||
self.ClientName = ClientName
|
||||
self.MessageSwitch = true
|
||||
self.ClientAlive2 = false
|
||||
|
||||
--self.AliveCheckScheduler = routines.scheduleFunction( self._AliveCheckScheduler, { self }, timer.getTime() + 1, 5 )
|
||||
self.AliveCheckScheduler = SCHEDULER:New( self, self._AliveCheckScheduler, { "Client Alive " .. ClientName }, 1, 5 )
|
||||
|
||||
self:E( self )
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
--- Transport defines that the Client is a Transport. Transports show cargo.
|
||||
-- @param #CLIENT self
|
||||
-- @return #CLIENT
|
||||
function CLIENT:Transport()
|
||||
self:F()
|
||||
|
||||
self.ClientTransport = true
|
||||
return self
|
||||
end
|
||||
|
||||
--- AddBriefing adds a briefing to a CLIENT when a player joins a mission.
|
||||
-- @param #CLIENT self
|
||||
-- @param #string ClientBriefing is the text defining the Mission briefing.
|
||||
-- @return #CLIENT self
|
||||
function CLIENT:AddBriefing( ClientBriefing )
|
||||
self:F( ClientBriefing )
|
||||
self.ClientBriefing = ClientBriefing
|
||||
self.ClientBriefingShown = false
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Show the briefing of a CLIENT.
|
||||
-- @param #CLIENT self
|
||||
-- @return #CLIENT self
|
||||
function CLIENT:ShowBriefing()
|
||||
self:F( { self.ClientName, self.ClientBriefingShown } )
|
||||
|
||||
if not self.ClientBriefingShown then
|
||||
self.ClientBriefingShown = true
|
||||
local Briefing = ""
|
||||
if self.ClientBriefing then
|
||||
Briefing = Briefing .. self.ClientBriefing
|
||||
end
|
||||
Briefing = Briefing .. " Press [LEFT ALT]+[B] to view the complete mission briefing."
|
||||
self:Message( Briefing, 60, "Briefing" )
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Show the mission briefing of a MISSION to the CLIENT.
|
||||
-- @param #CLIENT self
|
||||
-- @param #string MissionBriefing
|
||||
-- @return #CLIENT self
|
||||
function CLIENT:ShowMissionBriefing( MissionBriefing )
|
||||
self:F( { self.ClientName } )
|
||||
|
||||
if MissionBriefing then
|
||||
self:Message( MissionBriefing, 60, "Mission Briefing" )
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
|
||||
--- Resets a CLIENT.
|
||||
-- @param #CLIENT self
|
||||
-- @param #string ClientName Name of the Group as defined within the Mission Editor. The Group must have a Unit with the type Client.
|
||||
function CLIENT:Reset( ClientName )
|
||||
self:F()
|
||||
self._Menus = {}
|
||||
end
|
||||
|
||||
-- Is Functions
|
||||
|
||||
--- Checks if the CLIENT is a multi-seated UNIT.
|
||||
-- @param #CLIENT self
|
||||
-- @return #boolean true if multi-seated.
|
||||
function CLIENT:IsMultiSeated()
|
||||
self:F( self.ClientName )
|
||||
|
||||
local ClientMultiSeatedTypes = {
|
||||
["Mi-8MT"] = "Mi-8MT",
|
||||
["UH-1H"] = "UH-1H",
|
||||
["P-51B"] = "P-51B"
|
||||
}
|
||||
|
||||
if self:IsAlive() then
|
||||
local ClientTypeName = self:GetClientGroupUnit():GetTypeName()
|
||||
if ClientMultiSeatedTypes[ClientTypeName] then
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
--- Checks for a client alive event and calls a function on a continuous basis.
|
||||
-- @param #CLIENT self
|
||||
-- @param #function CallBackFunction Create a function that will be called when a player joins the slot.
|
||||
-- @return #CLIENT
|
||||
function CLIENT:Alive( CallBackFunction, ... )
|
||||
self:F()
|
||||
|
||||
self.ClientCallBack = CallBackFunction
|
||||
self.ClientParameters = arg
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- @param #CLIENT self
|
||||
function CLIENT:_AliveCheckScheduler( SchedulerName )
|
||||
self:F3( { SchedulerName, self.ClientName, self.ClientAlive2, self.ClientBriefingShown, self.ClientCallBack } )
|
||||
|
||||
if self:IsAlive() then
|
||||
if self.ClientAlive2 == false then
|
||||
self:ShowBriefing()
|
||||
if self.ClientCallBack then
|
||||
self:T("Calling Callback function")
|
||||
self.ClientCallBack( self, unpack( self.ClientParameters ) )
|
||||
end
|
||||
self.ClientAlive2 = true
|
||||
end
|
||||
else
|
||||
if self.ClientAlive2 == true then
|
||||
self.ClientAlive2 = false
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
--- Return the DCSGroup of a Client.
|
||||
-- This function is modified to deal with a couple of bugs in DCS 1.5.3
|
||||
-- @param #CLIENT self
|
||||
-- @return Dcs.DCSWrapper.Group#Group
|
||||
function CLIENT:GetDCSGroup()
|
||||
self:F3()
|
||||
|
||||
-- local ClientData = Group.getByName( self.ClientName )
|
||||
-- if ClientData and ClientData:isExist() then
|
||||
-- self:T( self.ClientName .. " : group found!" )
|
||||
-- return ClientData
|
||||
-- else
|
||||
-- return nil
|
||||
-- end
|
||||
|
||||
local ClientUnit = Unit.getByName( self.ClientName )
|
||||
|
||||
local CoalitionsData = { AlivePlayersRed = coalition.getPlayers( coalition.side.RED ), AlivePlayersBlue = coalition.getPlayers( coalition.side.BLUE ) }
|
||||
for CoalitionId, CoalitionData in pairs( CoalitionsData ) do
|
||||
self:T3( { "CoalitionData:", CoalitionData } )
|
||||
for UnitId, UnitData in pairs( CoalitionData ) do
|
||||
self:T3( { "UnitData:", UnitData } )
|
||||
if UnitData and UnitData:isExist() then
|
||||
|
||||
--self:E(self.ClientName)
|
||||
if ClientUnit then
|
||||
local ClientGroup = ClientUnit:getGroup()
|
||||
if ClientGroup then
|
||||
self:T3( "ClientGroup = " .. self.ClientName )
|
||||
if ClientGroup:isExist() and UnitData:getGroup():isExist() then
|
||||
if ClientGroup:getID() == UnitData:getGroup():getID() then
|
||||
self:T3( "Normal logic" )
|
||||
self:T3( self.ClientName .. " : group found!" )
|
||||
self.ClientGroupID = ClientGroup:getID()
|
||||
self.ClientGroupName = ClientGroup:getName()
|
||||
return ClientGroup
|
||||
end
|
||||
else
|
||||
-- Now we need to resolve the bugs in DCS 1.5 ...
|
||||
-- Consult the database for the units of the Client Group. (ClientGroup:getUnits() returns nil)
|
||||
self:T3( "Bug 1.5 logic" )
|
||||
local ClientGroupTemplate = _DATABASE.Templates.Units[self.ClientName].GroupTemplate
|
||||
self.ClientGroupID = ClientGroupTemplate.groupId
|
||||
self.ClientGroupName = _DATABASE.Templates.Units[self.ClientName].GroupName
|
||||
self:T3( self.ClientName .. " : group found in bug 1.5 resolvement logic!" )
|
||||
return ClientGroup
|
||||
end
|
||||
-- else
|
||||
-- error( "Client " .. self.ClientName .. " not found!" )
|
||||
end
|
||||
else
|
||||
--self:E( { "Client not found!", self.ClientName } )
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- For non player clients
|
||||
if ClientUnit then
|
||||
local ClientGroup = ClientUnit:getGroup()
|
||||
if ClientGroup then
|
||||
self:T3( "ClientGroup = " .. self.ClientName )
|
||||
if ClientGroup:isExist() then
|
||||
self:T3( "Normal logic" )
|
||||
self:T3( self.ClientName .. " : group found!" )
|
||||
return ClientGroup
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
self.ClientGroupID = nil
|
||||
self.ClientGroupUnit = nil
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
-- TODO: Check Dcs.DCSTypes#Group.ID
|
||||
--- Get the group ID of the client.
|
||||
-- @param #CLIENT self
|
||||
-- @return Dcs.DCSTypes#Group.ID
|
||||
function CLIENT:GetClientGroupID()
|
||||
|
||||
local ClientGroup = self:GetDCSGroup()
|
||||
|
||||
--self:E( self.ClientGroupID ) -- Determined in GetDCSGroup()
|
||||
return self.ClientGroupID
|
||||
end
|
||||
|
||||
|
||||
--- Get the name of the group of the client.
|
||||
-- @param #CLIENT self
|
||||
-- @return #string
|
||||
function CLIENT:GetClientGroupName()
|
||||
|
||||
local ClientGroup = self:GetDCSGroup()
|
||||
|
||||
self:T( self.ClientGroupName ) -- Determined in GetDCSGroup()
|
||||
return self.ClientGroupName
|
||||
end
|
||||
|
||||
--- Returns the UNIT of the CLIENT.
|
||||
-- @param #CLIENT self
|
||||
-- @return Wrapper.Unit#UNIT
|
||||
function CLIENT:GetClientGroupUnit()
|
||||
self:F2()
|
||||
|
||||
local ClientDCSUnit = Unit.getByName( self.ClientName )
|
||||
|
||||
self:T( self.ClientDCSUnit )
|
||||
if ClientDCSUnit and ClientDCSUnit:isExist() then
|
||||
local ClientUnit = _DATABASE:FindUnit( self.ClientName )
|
||||
self:T2( ClientUnit )
|
||||
return ClientUnit
|
||||
end
|
||||
end
|
||||
|
||||
--- Returns the DCSUnit of the CLIENT.
|
||||
-- @param #CLIENT self
|
||||
-- @return Dcs.DCSTypes#Unit
|
||||
function CLIENT:GetClientGroupDCSUnit()
|
||||
self:F2()
|
||||
|
||||
local ClientDCSUnit = Unit.getByName( self.ClientName )
|
||||
|
||||
if ClientDCSUnit and ClientDCSUnit:isExist() then
|
||||
self:T2( ClientDCSUnit )
|
||||
return ClientDCSUnit
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--- Evaluates if the CLIENT is a transport.
|
||||
-- @param #CLIENT self
|
||||
-- @return #boolean true is a transport.
|
||||
function CLIENT:IsTransport()
|
||||
self:F()
|
||||
return self.ClientTransport
|
||||
end
|
||||
|
||||
--- Shows the @{AI_Cargo#CARGO} contained within the CLIENT to the player as a message.
|
||||
-- The @{AI_Cargo#CARGO} is shown using the @{Message#MESSAGE} distribution system.
|
||||
-- @param #CLIENT self
|
||||
function CLIENT:ShowCargo()
|
||||
self:F()
|
||||
|
||||
local CargoMsg = ""
|
||||
|
||||
for CargoName, Cargo in pairs( CARGOS ) do
|
||||
if self == Cargo:IsLoadedInClient() then
|
||||
CargoMsg = CargoMsg .. Cargo.CargoName .. " Type:" .. Cargo.CargoType .. " Weight: " .. Cargo.CargoWeight .. "\n"
|
||||
end
|
||||
end
|
||||
|
||||
if CargoMsg == "" then
|
||||
CargoMsg = "empty"
|
||||
end
|
||||
|
||||
self:Message( CargoMsg, 15, "Co-Pilot: Cargo Status", 30 )
|
||||
|
||||
end
|
||||
|
||||
-- TODO (1) I urgently need to revise this.
|
||||
--- A local function called by the DCS World Menu system to switch off messages.
|
||||
function CLIENT.SwitchMessages( PrmTable )
|
||||
PrmTable[1].MessageSwitch = PrmTable[2]
|
||||
end
|
||||
|
||||
--- The main message driver for the CLIENT.
|
||||
-- This function displays various messages to the Player logged into the CLIENT through the DCS World Messaging system.
|
||||
-- @param #CLIENT self
|
||||
-- @param #string Message is the text describing the message.
|
||||
-- @param #number MessageDuration is the duration in seconds that the Message should be displayed.
|
||||
-- @param #string MessageCategory is the category of the message (the title).
|
||||
-- @param #number MessageInterval is the interval in seconds between the display of the @{Message#MESSAGE} when the CLIENT is in the air.
|
||||
-- @param #string MessageID is the identifier of the message when displayed with intervals.
|
||||
function CLIENT:Message( Message, MessageDuration, MessageCategory, MessageInterval, MessageID )
|
||||
self:F( { Message, MessageDuration, MessageCategory, MessageInterval } )
|
||||
|
||||
if self.MessageSwitch == true then
|
||||
if MessageCategory == nil then
|
||||
MessageCategory = "Messages"
|
||||
end
|
||||
if MessageID ~= nil then
|
||||
if self.Messages[MessageID] == nil then
|
||||
self.Messages[MessageID] = {}
|
||||
self.Messages[MessageID].MessageId = MessageID
|
||||
self.Messages[MessageID].MessageTime = timer.getTime()
|
||||
self.Messages[MessageID].MessageDuration = MessageDuration
|
||||
if MessageInterval == nil then
|
||||
self.Messages[MessageID].MessageInterval = 600
|
||||
else
|
||||
self.Messages[MessageID].MessageInterval = MessageInterval
|
||||
end
|
||||
MESSAGE:New( Message, MessageDuration, MessageCategory ):ToClient( self )
|
||||
else
|
||||
if self:GetClientGroupDCSUnit() and not self:GetClientGroupDCSUnit():inAir() then
|
||||
if timer.getTime() - self.Messages[MessageID].MessageTime >= self.Messages[MessageID].MessageDuration + 10 then
|
||||
MESSAGE:New( Message, MessageDuration , MessageCategory):ToClient( self )
|
||||
self.Messages[MessageID].MessageTime = timer.getTime()
|
||||
end
|
||||
else
|
||||
if timer.getTime() - self.Messages[MessageID].MessageTime >= self.Messages[MessageID].MessageDuration + self.Messages[MessageID].MessageInterval then
|
||||
MESSAGE:New( Message, MessageDuration, MessageCategory ):ToClient( self )
|
||||
self.Messages[MessageID].MessageTime = timer.getTime()
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
MESSAGE:New( Message, MessageDuration, MessageCategory ):ToClient( self )
|
||||
end
|
||||
end
|
||||
end
|
||||
2293
Moose Development/Moose/Wrapper/Controllable.lua
Normal file
2293
Moose Development/Moose/Wrapper/Controllable.lua
Normal file
File diff suppressed because it is too large
Load Diff
900
Moose Development/Moose/Wrapper/Group.lua
Normal file
900
Moose Development/Moose/Wrapper/Group.lua
Normal file
@@ -0,0 +1,900 @@
|
||||
--- This module contains the GROUP class.
|
||||
--
|
||||
-- 1) @{Group#GROUP} class, extends @{Controllable#CONTROLLABLE}
|
||||
-- =============================================================
|
||||
-- The @{Group#GROUP} class is a wrapper class to handle the DCS Group objects:
|
||||
--
|
||||
-- * Support all DCS Group APIs.
|
||||
-- * Enhance with Group specific APIs not in the DCS Group API set.
|
||||
-- * Handle local Group Controller.
|
||||
-- * Manage the "state" of the DCS Group.
|
||||
--
|
||||
-- **IMPORTANT: ONE SHOULD NEVER SANATIZE these GROUP OBJECT REFERENCES! (make the GROUP object references nil).**
|
||||
--
|
||||
-- 1.1) GROUP reference methods
|
||||
-- -----------------------
|
||||
-- For each DCS Group object alive within a running mission, a GROUP wrapper object (instance) will be created within the _@{DATABASE} object.
|
||||
-- This is done at the beginning of the mission (when the mission starts), and dynamically when new DCS Group objects are spawned (using the @{SPAWN} class).
|
||||
--
|
||||
-- The GROUP class does not contain a :New() method, rather it provides :Find() methods to retrieve the object reference
|
||||
-- using the DCS Group or the DCS GroupName.
|
||||
--
|
||||
-- Another thing to know is that GROUP objects do not "contain" the DCS Group object.
|
||||
-- The GROUP methods will reference the DCS Group object by name when it is needed during API execution.
|
||||
-- If the DCS Group object does not exist or is nil, the GROUP methods will return nil and log an exception in the DCS.log file.
|
||||
--
|
||||
-- The GROUP class provides the following functions to retrieve quickly the relevant GROUP instance:
|
||||
--
|
||||
-- * @{#GROUP.Find}(): Find a GROUP instance from the _DATABASE object using a DCS Group object.
|
||||
-- * @{#GROUP.FindByName}(): Find a GROUP instance from the _DATABASE object using a DCS Group name.
|
||||
--
|
||||
-- ## 1.2) GROUP task methods
|
||||
--
|
||||
-- A GROUP is a @{Controllable}. See the @{Controllable} task methods section for a description of the task methods.
|
||||
--
|
||||
-- ### 1.2.4) Obtain the mission from group templates
|
||||
--
|
||||
-- Group templates contain complete mission descriptions. Sometimes you want to copy a complete mission from a group and assign it to another:
|
||||
--
|
||||
-- * @{Controllable#CONTROLLABLE.TaskMission}: (AIR + GROUND) Return a mission task from a mission template.
|
||||
--
|
||||
-- ## 1.3) GROUP Command methods
|
||||
--
|
||||
-- A GROUP is a @{Controllable}. See the @{Controllable} command methods section for a description of the command methods.
|
||||
--
|
||||
-- ## 1.4) GROUP option methods
|
||||
--
|
||||
-- A GROUP is a @{Controllable}. See the @{Controllable} option methods section for a description of the option methods.
|
||||
--
|
||||
-- ## 1.5) GROUP Zone validation methods
|
||||
--
|
||||
-- The group can be validated whether it is completely, partly or not within a @{Zone}.
|
||||
-- Use the following Zone validation methods on the group:
|
||||
--
|
||||
-- * @{#GROUP.IsCompletelyInZone}: Returns true if all units of the group are within a @{Zone}.
|
||||
-- * @{#GROUP.IsPartlyInZone}: Returns true if some units of the group are within a @{Zone}.
|
||||
-- * @{#GROUP.IsNotInZone}: Returns true if none of the group units of the group are within a @{Zone}.
|
||||
--
|
||||
-- The zone can be of any @{Zone} class derived from @{Zone#ZONE_BASE}. So, these methods are polymorphic to the zones tested on.
|
||||
--
|
||||
-- ## 1.6) GROUP AI methods
|
||||
--
|
||||
-- A GROUP has AI methods to control the AI activation.
|
||||
--
|
||||
-- * @{#GROUP.SetAIOnOff}(): Turns the GROUP AI On or Off.
|
||||
-- * @{#GROUP.SetAIOn}(): Turns the GROUP AI On.
|
||||
-- * @{#GROUP.SetAIOff}(): Turns the GROUP AI Off.
|
||||
--
|
||||
-- ====
|
||||
--
|
||||
-- # **API CHANGE HISTORY**
|
||||
--
|
||||
-- The underlying change log documents the API changes. Please read this carefully. The following notation is used:
|
||||
--
|
||||
-- * **Added** parts are expressed in bold type face.
|
||||
-- * _Removed_ parts are expressed in italic type face.
|
||||
--
|
||||
-- Hereby the change log:
|
||||
--
|
||||
-- 2017-01-24: GROUP:**SetAIOnOff( AIOnOff )** added.
|
||||
--
|
||||
-- 2017-01-24: GROUP:**SetAIOn()** added.
|
||||
--
|
||||
-- 2017-01-24: GROUP:**SetAIOff()** added.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- # **AUTHORS and CONTRIBUTIONS**
|
||||
--
|
||||
-- ### Contributions:
|
||||
--
|
||||
-- * [**Entropy**](https://forums.eagle.ru/member.php?u=111471), **Afinegan**: Came up with the requirement for AIOnOff().
|
||||
--
|
||||
-- ### Authors:
|
||||
--
|
||||
-- * **FlightControl**: Design & Programming
|
||||
--
|
||||
-- @module Group
|
||||
-- @author FlightControl
|
||||
|
||||
--- The GROUP class
|
||||
-- @type GROUP
|
||||
-- @extends Wrapper.Controllable#CONTROLLABLE
|
||||
-- @field #string GroupName The name of the group.
|
||||
GROUP = {
|
||||
ClassName = "GROUP",
|
||||
}
|
||||
|
||||
--- Create a new GROUP from a DCSGroup
|
||||
-- @param #GROUP self
|
||||
-- @param Dcs.DCSWrapper.Group#Group GroupName The DCS Group name
|
||||
-- @return #GROUP self
|
||||
function GROUP:Register( GroupName )
|
||||
local self = BASE:Inherit( self, CONTROLLABLE:New( GroupName ) )
|
||||
self:F2( GroupName )
|
||||
self.GroupName = GroupName
|
||||
|
||||
self:SetEventPriority( 4 )
|
||||
return self
|
||||
end
|
||||
|
||||
-- Reference methods.
|
||||
|
||||
--- Find the GROUP wrapper class instance using the DCS Group.
|
||||
-- @param #GROUP self
|
||||
-- @param Dcs.DCSWrapper.Group#Group DCSGroup The DCS Group.
|
||||
-- @return #GROUP The GROUP.
|
||||
function GROUP:Find( DCSGroup )
|
||||
|
||||
local GroupName = DCSGroup:getName() -- Wrapper.Group#GROUP
|
||||
local GroupFound = _DATABASE:FindGroup( GroupName )
|
||||
return GroupFound
|
||||
end
|
||||
|
||||
--- Find the created GROUP using the DCS Group Name.
|
||||
-- @param #GROUP self
|
||||
-- @param #string GroupName The DCS Group Name.
|
||||
-- @return #GROUP The GROUP.
|
||||
function GROUP:FindByName( GroupName )
|
||||
|
||||
local GroupFound = _DATABASE:FindGroup( GroupName )
|
||||
return GroupFound
|
||||
end
|
||||
|
||||
-- DCS Group methods support.
|
||||
|
||||
--- Returns the DCS Group.
|
||||
-- @param #GROUP self
|
||||
-- @return Dcs.DCSWrapper.Group#Group The DCS Group.
|
||||
function GROUP:GetDCSObject()
|
||||
local DCSGroup = Group.getByName( self.GroupName )
|
||||
|
||||
if DCSGroup then
|
||||
return DCSGroup
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Returns the @{DCSTypes#Position3} position vectors indicating the point and direction vectors in 3D of the POSITIONABLE within the mission.
|
||||
-- @param Wrapper.Positionable#POSITIONABLE self
|
||||
-- @return Dcs.DCSTypes#Position The 3D position vectors of the POSITIONABLE.
|
||||
-- @return #nil The POSITIONABLE is not existing or alive.
|
||||
function GROUP:GetPositionVec3() -- Overridden from POSITIONABLE:GetPositionVec3()
|
||||
self:F2( self.PositionableName )
|
||||
|
||||
local DCSPositionable = self:GetDCSObject()
|
||||
|
||||
if DCSPositionable then
|
||||
local PositionablePosition = DCSPositionable:getUnits()[1]:getPosition().p
|
||||
self:T3( PositionablePosition )
|
||||
return PositionablePosition
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Returns if the DCS Group is alive.
|
||||
-- When the group exists at run-time, this method will return true, otherwise false.
|
||||
-- @param #GROUP self
|
||||
-- @return #boolean true if the DCS Group is alive.
|
||||
function GROUP:IsAlive()
|
||||
self:F2( self.GroupName )
|
||||
|
||||
local DCSGroup = self:GetDCSObject()
|
||||
|
||||
if DCSGroup then
|
||||
local GroupIsAlive = DCSGroup:isExist() and DCSGroup:getUnit(1) ~= nil
|
||||
self:T3( GroupIsAlive )
|
||||
return GroupIsAlive
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Destroys the DCS Group and all of its DCS Units.
|
||||
-- Note that this destroy method also raises a destroy event at run-time.
|
||||
-- So all event listeners will catch the destroy event of this DCS Group.
|
||||
-- @param #GROUP self
|
||||
function GROUP:Destroy()
|
||||
self:F2( self.GroupName )
|
||||
|
||||
local DCSGroup = self:GetDCSObject()
|
||||
|
||||
if DCSGroup then
|
||||
for Index, UnitData in pairs( DCSGroup:getUnits() ) do
|
||||
self:CreateEventCrash( timer.getTime(), UnitData )
|
||||
end
|
||||
DCSGroup:destroy()
|
||||
DCSGroup = nil
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Returns category of the DCS Group.
|
||||
-- @param #GROUP self
|
||||
-- @return Dcs.DCSWrapper.Group#Group.Category The category ID
|
||||
function GROUP:GetCategory()
|
||||
self:F2( self.GroupName )
|
||||
|
||||
local DCSGroup = self:GetDCSObject()
|
||||
if DCSGroup then
|
||||
local GroupCategory = DCSGroup:getCategory()
|
||||
self:T3( GroupCategory )
|
||||
return GroupCategory
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Returns the category name of the DCS Group.
|
||||
-- @param #GROUP self
|
||||
-- @return #string Category name = Helicopter, Airplane, Ground Unit, Ship
|
||||
function GROUP:GetCategoryName()
|
||||
self:F2( self.GroupName )
|
||||
|
||||
local DCSGroup = self:GetDCSObject()
|
||||
if DCSGroup then
|
||||
local CategoryNames = {
|
||||
[Group.Category.AIRPLANE] = "Airplane",
|
||||
[Group.Category.HELICOPTER] = "Helicopter",
|
||||
[Group.Category.GROUND] = "Ground Unit",
|
||||
[Group.Category.SHIP] = "Ship",
|
||||
}
|
||||
local GroupCategory = DCSGroup:getCategory()
|
||||
self:T3( GroupCategory )
|
||||
|
||||
return CategoryNames[GroupCategory]
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
--- Returns the coalition of the DCS Group.
|
||||
-- @param #GROUP self
|
||||
-- @return Dcs.DCSCoalitionWrapper.Object#coalition.side The coalition side of the DCS Group.
|
||||
function GROUP:GetCoalition()
|
||||
self:F2( self.GroupName )
|
||||
|
||||
local DCSGroup = self:GetDCSObject()
|
||||
if DCSGroup then
|
||||
local GroupCoalition = DCSGroup:getCoalition()
|
||||
self:T3( GroupCoalition )
|
||||
return GroupCoalition
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Returns the country of the DCS Group.
|
||||
-- @param #GROUP self
|
||||
-- @return Dcs.DCScountry#country.id The country identifier.
|
||||
-- @return #nil The DCS Group is not existing or alive.
|
||||
function GROUP:GetCountry()
|
||||
self:F2( self.GroupName )
|
||||
|
||||
local DCSGroup = self:GetDCSObject()
|
||||
if DCSGroup then
|
||||
local GroupCountry = DCSGroup:getUnit(1):getCountry()
|
||||
self:T3( GroupCountry )
|
||||
return GroupCountry
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Returns the UNIT wrapper class with number UnitNumber.
|
||||
-- If the underlying DCS Unit does not exist, the method will return nil. .
|
||||
-- @param #GROUP self
|
||||
-- @param #number UnitNumber The number of the UNIT wrapper class to be returned.
|
||||
-- @return Wrapper.Unit#UNIT The UNIT wrapper class.
|
||||
function GROUP:GetUnit( UnitNumber )
|
||||
self:F2( { self.GroupName, UnitNumber } )
|
||||
|
||||
local DCSGroup = self:GetDCSObject()
|
||||
|
||||
if DCSGroup then
|
||||
local UnitFound = UNIT:Find( DCSGroup:getUnit( UnitNumber ) )
|
||||
self:T2( UnitFound )
|
||||
return UnitFound
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Returns the DCS Unit with number UnitNumber.
|
||||
-- If the underlying DCS Unit does not exist, the method will return nil. .
|
||||
-- @param #GROUP self
|
||||
-- @param #number UnitNumber The number of the DCS Unit to be returned.
|
||||
-- @return Dcs.DCSWrapper.Unit#Unit The DCS Unit.
|
||||
function GROUP:GetDCSUnit( UnitNumber )
|
||||
self:F2( { self.GroupName, UnitNumber } )
|
||||
|
||||
local DCSGroup = self:GetDCSObject()
|
||||
|
||||
if DCSGroup then
|
||||
local DCSUnitFound = DCSGroup:getUnit( UnitNumber )
|
||||
self:T3( DCSUnitFound )
|
||||
return DCSUnitFound
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Returns current size of the DCS Group.
|
||||
-- If some of the DCS Units of the DCS Group are destroyed the size of the DCS Group is changed.
|
||||
-- @param #GROUP self
|
||||
-- @return #number The DCS Group size.
|
||||
function GROUP:GetSize()
|
||||
self:F2( { self.GroupName } )
|
||||
local DCSGroup = self:GetDCSObject()
|
||||
|
||||
if DCSGroup then
|
||||
local GroupSize = DCSGroup:getSize()
|
||||
self:T3( GroupSize )
|
||||
return GroupSize
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
---
|
||||
--- Returns the initial size of the DCS Group.
|
||||
-- If some of the DCS Units of the DCS Group are destroyed, the initial size of the DCS Group is unchanged.
|
||||
-- @param #GROUP self
|
||||
-- @return #number The DCS Group initial size.
|
||||
function GROUP:GetInitialSize()
|
||||
self:F2( { self.GroupName } )
|
||||
local DCSGroup = self:GetDCSObject()
|
||||
|
||||
if DCSGroup then
|
||||
local GroupInitialSize = DCSGroup:getInitialSize()
|
||||
self:T3( GroupInitialSize )
|
||||
return GroupInitialSize
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
--- Returns the DCS Units of the DCS Group.
|
||||
-- @param #GROUP self
|
||||
-- @return #table The DCS Units.
|
||||
function GROUP:GetDCSUnits()
|
||||
self:F2( { self.GroupName } )
|
||||
local DCSGroup = self:GetDCSObject()
|
||||
|
||||
if DCSGroup then
|
||||
local DCSUnits = DCSGroup:getUnits()
|
||||
self:T3( DCSUnits )
|
||||
return DCSUnits
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
--- Activates a GROUP.
|
||||
-- @param #GROUP self
|
||||
function GROUP:Activate()
|
||||
self:F2( { self.GroupName } )
|
||||
trigger.action.activateGroup( self:GetDCSObject() )
|
||||
return self:GetDCSObject()
|
||||
end
|
||||
|
||||
|
||||
--- Gets the type name of the group.
|
||||
-- @param #GROUP self
|
||||
-- @return #string The type name of the group.
|
||||
function GROUP:GetTypeName()
|
||||
self:F2( self.GroupName )
|
||||
|
||||
local DCSGroup = self:GetDCSObject()
|
||||
|
||||
if DCSGroup then
|
||||
local GroupTypeName = DCSGroup:getUnit(1):getTypeName()
|
||||
self:T3( GroupTypeName )
|
||||
return( GroupTypeName )
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Gets the CallSign of the first DCS Unit of the DCS Group.
|
||||
-- @param #GROUP self
|
||||
-- @return #string The CallSign of the first DCS Unit of the DCS Group.
|
||||
function GROUP:GetCallsign()
|
||||
self:F2( self.GroupName )
|
||||
|
||||
local DCSGroup = self:GetDCSObject()
|
||||
|
||||
if DCSGroup then
|
||||
local GroupCallSign = DCSGroup:getUnit(1):getCallsign()
|
||||
self:T3( GroupCallSign )
|
||||
return GroupCallSign
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Returns the current point (Vec2 vector) of the first DCS Unit in the DCS Group.
|
||||
-- @param #GROUP self
|
||||
-- @return Dcs.DCSTypes#Vec2 Current Vec2 point of the first DCS Unit of the DCS Group.
|
||||
function GROUP:GetVec2()
|
||||
self:F2( self.GroupName )
|
||||
|
||||
local UnitPoint = self:GetUnit(1)
|
||||
UnitPoint:GetVec2()
|
||||
local GroupPointVec2 = UnitPoint:GetVec2()
|
||||
self:T3( GroupPointVec2 )
|
||||
return GroupPointVec2
|
||||
end
|
||||
|
||||
--- Returns the current Vec3 vector of the first DCS Unit in the GROUP.
|
||||
-- @return Dcs.DCSTypes#Vec3 Current Vec3 of the first DCS Unit of the GROUP.
|
||||
function GROUP:GetVec3()
|
||||
self:F2( self.GroupName )
|
||||
|
||||
local GroupVec3 = self:GetUnit(1):GetVec3()
|
||||
self:T3( GroupVec3 )
|
||||
return GroupVec3
|
||||
end
|
||||
|
||||
|
||||
|
||||
do -- Is Zone methods
|
||||
|
||||
--- Returns true if all units of the group are within a @{Zone}.
|
||||
-- @param #GROUP self
|
||||
-- @param Core.Zone#ZONE_BASE Zone The zone to test.
|
||||
-- @return #boolean Returns true if the Group is completely within the @{Zone#ZONE_BASE}
|
||||
function GROUP:IsCompletelyInZone( Zone )
|
||||
self:F2( { self.GroupName, Zone } )
|
||||
|
||||
for UnitID, UnitData in pairs( self:GetUnits() ) do
|
||||
local Unit = UnitData -- Wrapper.Unit#UNIT
|
||||
if Zone:IsVec3InZone( Unit:GetVec3() ) then
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
--- Returns true if some units of the group are within a @{Zone}.
|
||||
-- @param #GROUP self
|
||||
-- @param Core.Zone#ZONE_BASE Zone The zone to test.
|
||||
-- @return #boolean Returns true if the Group is completely within the @{Zone#ZONE_BASE}
|
||||
function GROUP:IsPartlyInZone( Zone )
|
||||
self:F2( { self.GroupName, Zone } )
|
||||
|
||||
for UnitID, UnitData in pairs( self:GetUnits() ) do
|
||||
local Unit = UnitData -- Wrapper.Unit#UNIT
|
||||
if Zone:IsVec3InZone( Unit:GetVec3() ) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
--- Returns true if none of the group units of the group are within a @{Zone}.
|
||||
-- @param #GROUP self
|
||||
-- @param Core.Zone#ZONE_BASE Zone The zone to test.
|
||||
-- @return #boolean Returns true if the Group is completely within the @{Zone#ZONE_BASE}
|
||||
function GROUP:IsNotInZone( Zone )
|
||||
self:F2( { self.GroupName, Zone } )
|
||||
|
||||
for UnitID, UnitData in pairs( self:GetUnits() ) do
|
||||
local Unit = UnitData -- Wrapper.Unit#UNIT
|
||||
if Zone:IsVec3InZone( Unit:GetVec3() ) then
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
--- Returns if the group is of an air category.
|
||||
-- If the group is a helicopter or a plane, then this method will return true, otherwise false.
|
||||
-- @param #GROUP self
|
||||
-- @return #boolean Air category evaluation result.
|
||||
function GROUP:IsAir()
|
||||
self:F2( self.GroupName )
|
||||
|
||||
local DCSGroup = self:GetDCSObject()
|
||||
|
||||
if DCSGroup then
|
||||
local IsAirResult = DCSGroup:getCategory() == Group.Category.AIRPLANE or DCSGroup:getCategory() == Group.Category.HELICOPTER
|
||||
self:T3( IsAirResult )
|
||||
return IsAirResult
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Returns if the DCS Group contains Helicopters.
|
||||
-- @param #GROUP self
|
||||
-- @return #boolean true if DCS Group contains Helicopters.
|
||||
function GROUP:IsHelicopter()
|
||||
self:F2( self.GroupName )
|
||||
|
||||
local DCSGroup = self:GetDCSObject()
|
||||
|
||||
if DCSGroup then
|
||||
local GroupCategory = DCSGroup:getCategory()
|
||||
self:T2( GroupCategory )
|
||||
return GroupCategory == Group.Category.HELICOPTER
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Returns if the DCS Group contains AirPlanes.
|
||||
-- @param #GROUP self
|
||||
-- @return #boolean true if DCS Group contains AirPlanes.
|
||||
function GROUP:IsAirPlane()
|
||||
self:F2()
|
||||
|
||||
local DCSGroup = self:GetDCSObject()
|
||||
|
||||
if DCSGroup then
|
||||
local GroupCategory = DCSGroup:getCategory()
|
||||
self:T2( GroupCategory )
|
||||
return GroupCategory == Group.Category.AIRPLANE
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Returns if the DCS Group contains Ground troops.
|
||||
-- @param #GROUP self
|
||||
-- @return #boolean true if DCS Group contains Ground troops.
|
||||
function GROUP:IsGround()
|
||||
self:F2()
|
||||
|
||||
local DCSGroup = self:GetDCSObject()
|
||||
|
||||
if DCSGroup then
|
||||
local GroupCategory = DCSGroup:getCategory()
|
||||
self:T2( GroupCategory )
|
||||
return GroupCategory == Group.Category.GROUND
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Returns if the DCS Group contains Ships.
|
||||
-- @param #GROUP self
|
||||
-- @return #boolean true if DCS Group contains Ships.
|
||||
function GROUP:IsShip()
|
||||
self:F2()
|
||||
|
||||
local DCSGroup = self:GetDCSObject()
|
||||
|
||||
if DCSGroup then
|
||||
local GroupCategory = DCSGroup:getCategory()
|
||||
self:T2( GroupCategory )
|
||||
return GroupCategory == Group.Category.SHIP
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Returns if all units of the group are on the ground or landed.
|
||||
-- If all units of this group are on the ground, this function will return true, otherwise false.
|
||||
-- @param #GROUP self
|
||||
-- @return #boolean All units on the ground result.
|
||||
function GROUP:AllOnGround()
|
||||
self:F2()
|
||||
|
||||
local DCSGroup = self:GetDCSObject()
|
||||
|
||||
if DCSGroup then
|
||||
local AllOnGroundResult = true
|
||||
|
||||
for Index, UnitData in pairs( DCSGroup:getUnits() ) do
|
||||
if UnitData:inAir() then
|
||||
AllOnGroundResult = false
|
||||
end
|
||||
end
|
||||
|
||||
self:T3( AllOnGroundResult )
|
||||
return AllOnGroundResult
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
do -- AI methods
|
||||
|
||||
--- Turns the AI On or Off for the GROUP.
|
||||
-- @param #GROUP self
|
||||
-- @param #boolean AIOnOff The value true turns the AI On, the value false turns the AI Off.
|
||||
-- @return #GROUP The GROUP.
|
||||
function GROUP:SetAIOnOff( AIOnOff )
|
||||
|
||||
local DCSGroup = self:GetDCSObject() -- Dcs.DCSGroup#Group
|
||||
|
||||
if DCSGroup then
|
||||
local DCSController = DCSGroup:getController() -- Dcs.DCSController#Controller
|
||||
if DCSController then
|
||||
DCSController:setOnOff( AIOnOff )
|
||||
return self
|
||||
end
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Turns the AI On for the GROUP.
|
||||
-- @param #GROUP self
|
||||
-- @return #GROUP The GROUP.
|
||||
function GROUP:SetAIOn()
|
||||
|
||||
return self:SetAIOnOff( true )
|
||||
end
|
||||
|
||||
--- Turns the AI Off for the GROUP.
|
||||
-- @param #GROUP self
|
||||
-- @return #GROUP The GROUP.
|
||||
function GROUP:SetAIOff()
|
||||
|
||||
return self:SetAIOnOff( false )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
--- Returns the current maximum velocity of the group.
|
||||
-- Each unit within the group gets evaluated, and the maximum velocity (= the unit which is going the fastest) is returned.
|
||||
-- @param #GROUP self
|
||||
-- @return #number Maximum velocity found.
|
||||
function GROUP:GetMaxVelocity()
|
||||
self:F2()
|
||||
|
||||
local DCSGroup = self:GetDCSObject()
|
||||
|
||||
if DCSGroup then
|
||||
local GroupVelocityMax = 0
|
||||
|
||||
for Index, UnitData in pairs( DCSGroup:getUnits() ) do
|
||||
|
||||
local UnitVelocityVec3 = UnitData:getVelocity()
|
||||
local UnitVelocity = math.abs( UnitVelocityVec3.x ) + math.abs( UnitVelocityVec3.y ) + math.abs( UnitVelocityVec3.z )
|
||||
|
||||
if UnitVelocity > GroupVelocityMax then
|
||||
GroupVelocityMax = UnitVelocity
|
||||
end
|
||||
end
|
||||
|
||||
return GroupVelocityMax
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Returns the current minimum height of the group.
|
||||
-- Each unit within the group gets evaluated, and the minimum height (= the unit which is the lowest elevated) is returned.
|
||||
-- @param #GROUP self
|
||||
-- @return #number Minimum height found.
|
||||
function GROUP:GetMinHeight()
|
||||
self:F2()
|
||||
|
||||
end
|
||||
|
||||
--- Returns the current maximum height of the group.
|
||||
-- Each unit within the group gets evaluated, and the maximum height (= the unit which is the highest elevated) is returned.
|
||||
-- @param #GROUP self
|
||||
-- @return #number Maximum height found.
|
||||
function GROUP:GetMaxHeight()
|
||||
self:F2()
|
||||
|
||||
end
|
||||
|
||||
-- SPAWNING
|
||||
|
||||
--- Respawn the @{GROUP} using a (tweaked) template of the Group.
|
||||
-- The template must be retrieved with the @{Group#GROUP.GetTemplate}() function.
|
||||
-- The template contains all the definitions as declared within the mission file.
|
||||
-- To understand templates, do the following:
|
||||
--
|
||||
-- * unpack your .miz file into a directory using 7-zip.
|
||||
-- * browse in the directory created to the file **mission**.
|
||||
-- * open the file and search for the country group definitions.
|
||||
--
|
||||
-- Your group template will contain the fields as described within the mission file.
|
||||
--
|
||||
-- This function will:
|
||||
--
|
||||
-- * Get the current position and heading of the group.
|
||||
-- * When the group is alive, it will tweak the template x, y and heading coordinates of the group and the embedded units to the current units positions.
|
||||
-- * Then it will destroy the current alive group.
|
||||
-- * And it will respawn the group using your new template definition.
|
||||
-- @param Wrapper.Group#GROUP self
|
||||
-- @param #table Template The template of the Group retrieved with GROUP:GetTemplate()
|
||||
function GROUP:Respawn( Template )
|
||||
|
||||
local Vec3 = self:GetVec3()
|
||||
Template.x = Vec3.x
|
||||
Template.y = Vec3.z
|
||||
--Template.x = nil
|
||||
--Template.y = nil
|
||||
|
||||
self:E( #Template.units )
|
||||
for UnitID, UnitData in pairs( self:GetUnits() ) do
|
||||
local GroupUnit = UnitData -- Wrapper.Unit#UNIT
|
||||
self:E( GroupUnit:GetName() )
|
||||
if GroupUnit:IsAlive() then
|
||||
local GroupUnitVec3 = GroupUnit:GetVec3()
|
||||
local GroupUnitHeading = GroupUnit:GetHeading()
|
||||
Template.units[UnitID].alt = GroupUnitVec3.y
|
||||
Template.units[UnitID].x = GroupUnitVec3.x
|
||||
Template.units[UnitID].y = GroupUnitVec3.z
|
||||
Template.units[UnitID].heading = GroupUnitHeading
|
||||
self:E( { UnitID, Template.units[UnitID], Template.units[UnitID] } )
|
||||
end
|
||||
end
|
||||
|
||||
self:Destroy()
|
||||
_DATABASE:Spawn( Template )
|
||||
end
|
||||
|
||||
--- Returns the group template from the @{DATABASE} (_DATABASE object).
|
||||
-- @param #GROUP self
|
||||
-- @return #table
|
||||
function GROUP:GetTemplate()
|
||||
local GroupName = self:GetName()
|
||||
self:E( GroupName )
|
||||
return _DATABASE:GetGroupTemplate( GroupName )
|
||||
end
|
||||
|
||||
--- Sets the controlled status in a Template.
|
||||
-- @param #GROUP self
|
||||
-- @param #boolean Controlled true is controlled, false is uncontrolled.
|
||||
-- @return #table
|
||||
function GROUP:SetTemplateControlled( Template, Controlled )
|
||||
Template.uncontrolled = not Controlled
|
||||
return Template
|
||||
end
|
||||
|
||||
--- Sets the CountryID of the group in a Template.
|
||||
-- @param #GROUP self
|
||||
-- @param Dcs.DCScountry#country.id CountryID The country ID.
|
||||
-- @return #table
|
||||
function GROUP:SetTemplateCountry( Template, CountryID )
|
||||
Template.CountryID = CountryID
|
||||
return Template
|
||||
end
|
||||
|
||||
--- Sets the CoalitionID of the group in a Template.
|
||||
-- @param #GROUP self
|
||||
-- @param Dcs.DCSCoalitionWrapper.Object#coalition.side CoalitionID The coalition ID.
|
||||
-- @return #table
|
||||
function GROUP:SetTemplateCoalition( Template, CoalitionID )
|
||||
Template.CoalitionID = CoalitionID
|
||||
return Template
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
--- Return the mission template of the group.
|
||||
-- @param #GROUP self
|
||||
-- @return #table The MissionTemplate
|
||||
function GROUP:GetTaskMission()
|
||||
self:F2( self.GroupName )
|
||||
|
||||
return routines.utils.deepCopy( _DATABASE.Templates.Groups[self.GroupName].Template )
|
||||
end
|
||||
|
||||
--- Return the mission route of the group.
|
||||
-- @param #GROUP self
|
||||
-- @return #table The mission route defined by points.
|
||||
function GROUP:GetTaskRoute()
|
||||
self:F2( self.GroupName )
|
||||
|
||||
return routines.utils.deepCopy( _DATABASE.Templates.Groups[self.GroupName].Template.route.points )
|
||||
end
|
||||
|
||||
--- Return the route of a group by using the @{Database#DATABASE} class.
|
||||
-- @param #GROUP self
|
||||
-- @param #number Begin The route point from where the copy will start. The base route point is 0.
|
||||
-- @param #number End The route point where the copy will end. The End point is the last point - the End point. The last point has base 0.
|
||||
-- @param #boolean Randomize Randomization of the route, when true.
|
||||
-- @param #number Radius When randomization is on, the randomization is within the radius.
|
||||
function GROUP:CopyRoute( Begin, End, Randomize, Radius )
|
||||
self:F2( { Begin, End } )
|
||||
|
||||
local Points = {}
|
||||
|
||||
-- Could be a Spawned Group
|
||||
local GroupName = string.match( self:GetName(), ".*#" )
|
||||
if GroupName then
|
||||
GroupName = GroupName:sub( 1, -2 )
|
||||
else
|
||||
GroupName = self:GetName()
|
||||
end
|
||||
|
||||
self:T3( { GroupName } )
|
||||
|
||||
local Template = _DATABASE.Templates.Groups[GroupName].Template
|
||||
|
||||
if Template then
|
||||
if not Begin then
|
||||
Begin = 0
|
||||
end
|
||||
if not End then
|
||||
End = 0
|
||||
end
|
||||
|
||||
for TPointID = Begin + 1, #Template.route.points - End do
|
||||
if Template.route.points[TPointID] then
|
||||
Points[#Points+1] = routines.utils.deepCopy( Template.route.points[TPointID] )
|
||||
if Randomize then
|
||||
if not Radius then
|
||||
Radius = 500
|
||||
end
|
||||
Points[#Points].x = Points[#Points].x + math.random( Radius * -1, Radius )
|
||||
Points[#Points].y = Points[#Points].y + math.random( Radius * -1, Radius )
|
||||
end
|
||||
end
|
||||
end
|
||||
return Points
|
||||
else
|
||||
error( "Template not found for Group : " .. GroupName )
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Calculate the maxium A2G threat level of the Group.
|
||||
-- @param #GROUP self
|
||||
function GROUP:CalculateThreatLevelA2G()
|
||||
|
||||
local MaxThreatLevelA2G = 0
|
||||
for UnitName, UnitData in pairs( self:GetUnits() ) do
|
||||
local ThreatUnit = UnitData -- Wrapper.Unit#UNIT
|
||||
local ThreatLevelA2G = ThreatUnit:GetThreatLevel()
|
||||
if ThreatLevelA2G > MaxThreatLevelA2G then
|
||||
MaxThreatLevelA2G = ThreatLevelA2G
|
||||
end
|
||||
end
|
||||
|
||||
self:T3( MaxThreatLevelA2G )
|
||||
return MaxThreatLevelA2G
|
||||
end
|
||||
|
||||
--- Returns true if the first unit of the GROUP is in the air.
|
||||
-- @param Wrapper.Group#GROUP self
|
||||
-- @return #boolean true if in the first unit of the group is in the air.
|
||||
-- @return #nil The GROUP is not existing or not alive.
|
||||
function GROUP:InAir()
|
||||
self:F2( self.GroupName )
|
||||
|
||||
local DCSGroup = self:GetDCSObject()
|
||||
|
||||
if DCSGroup then
|
||||
local DCSUnit = DCSGroup:getUnit(1)
|
||||
if DCSUnit then
|
||||
local GroupInAir = DCSGroup:getUnit(1):inAir()
|
||||
self:T3( GroupInAir )
|
||||
return GroupInAir
|
||||
end
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
function GROUP:OnReSpawn( ReSpawnFunction )
|
||||
|
||||
self.ReSpawnFunction = ReSpawnFunction
|
||||
end
|
||||
|
||||
|
||||
223
Moose Development/Moose/Wrapper/Identifiable.lua
Normal file
223
Moose Development/Moose/Wrapper/Identifiable.lua
Normal file
@@ -0,0 +1,223 @@
|
||||
--- This module contains the IDENTIFIABLE class.
|
||||
--
|
||||
-- 1) @{#IDENTIFIABLE} class, extends @{Object#OBJECT}
|
||||
-- ===============================================================
|
||||
-- The @{#IDENTIFIABLE} class is a wrapper class to handle the DCS Identifiable objects:
|
||||
--
|
||||
-- * Support all DCS Identifiable APIs.
|
||||
-- * Enhance with Identifiable specific APIs not in the DCS Identifiable API set.
|
||||
-- * Manage the "state" of the DCS Identifiable.
|
||||
--
|
||||
-- 1.1) IDENTIFIABLE constructor:
|
||||
-- ------------------------------
|
||||
-- The IDENTIFIABLE class provides the following functions to construct a IDENTIFIABLE instance:
|
||||
--
|
||||
-- * @{#IDENTIFIABLE.New}(): Create a IDENTIFIABLE instance.
|
||||
--
|
||||
-- 1.2) IDENTIFIABLE methods:
|
||||
-- --------------------------
|
||||
-- The following methods can be used to identify an identifiable object:
|
||||
--
|
||||
-- * @{#IDENTIFIABLE.GetName}(): Returns the name of the Identifiable.
|
||||
-- * @{#IDENTIFIABLE.IsAlive}(): Returns if the Identifiable is alive.
|
||||
-- * @{#IDENTIFIABLE.GetTypeName}(): Returns the type name of the Identifiable.
|
||||
-- * @{#IDENTIFIABLE.GetCoalition}(): Returns the coalition of the Identifiable.
|
||||
-- * @{#IDENTIFIABLE.GetCountry}(): Returns the country of the Identifiable.
|
||||
-- * @{#IDENTIFIABLE.GetDesc}(): Returns the descriptor structure of the Identifiable.
|
||||
--
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- @module Identifiable
|
||||
|
||||
--- The IDENTIFIABLE class
|
||||
-- @type IDENTIFIABLE
|
||||
-- @extends Wrapper.Object#OBJECT
|
||||
-- @field #string IdentifiableName The name of the identifiable.
|
||||
IDENTIFIABLE = {
|
||||
ClassName = "IDENTIFIABLE",
|
||||
IdentifiableName = "",
|
||||
}
|
||||
|
||||
local _CategoryName = {
|
||||
[Unit.Category.AIRPLANE] = "Airplane",
|
||||
[Unit.Category.HELICOPTER] = "Helicoper",
|
||||
[Unit.Category.GROUND_UNIT] = "Ground Identifiable",
|
||||
[Unit.Category.SHIP] = "Ship",
|
||||
[Unit.Category.STRUCTURE] = "Structure",
|
||||
}
|
||||
|
||||
--- Create a new IDENTIFIABLE from a DCSIdentifiable
|
||||
-- @param #IDENTIFIABLE self
|
||||
-- @param Dcs.DCSWrapper.Identifiable#Identifiable IdentifiableName The DCS Identifiable name
|
||||
-- @return #IDENTIFIABLE self
|
||||
function IDENTIFIABLE:New( IdentifiableName )
|
||||
local self = BASE:Inherit( self, OBJECT:New( IdentifiableName ) )
|
||||
self:F2( IdentifiableName )
|
||||
self.IdentifiableName = IdentifiableName
|
||||
return self
|
||||
end
|
||||
|
||||
--- Returns if the Identifiable is alive.
|
||||
-- @param #IDENTIFIABLE self
|
||||
-- @return #boolean true if Identifiable is alive.
|
||||
-- @return #nil The DCS Identifiable is not existing or alive.
|
||||
function IDENTIFIABLE:IsAlive()
|
||||
self:F3( self.IdentifiableName )
|
||||
|
||||
local DCSIdentifiable = self:GetDCSObject()
|
||||
|
||||
if DCSIdentifiable then
|
||||
local IdentifiableIsAlive = DCSIdentifiable:isExist()
|
||||
return IdentifiableIsAlive
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
--- Returns DCS Identifiable object name.
|
||||
-- The function provides access to non-activated objects too.
|
||||
-- @param #IDENTIFIABLE self
|
||||
-- @return #string The name of the DCS Identifiable.
|
||||
-- @return #nil The DCS Identifiable is not existing or alive.
|
||||
function IDENTIFIABLE:GetName()
|
||||
self:F2( self.IdentifiableName )
|
||||
|
||||
local DCSIdentifiable = self:GetDCSObject()
|
||||
|
||||
if DCSIdentifiable then
|
||||
local IdentifiableName = self.IdentifiableName
|
||||
return IdentifiableName
|
||||
end
|
||||
|
||||
self:E( self.ClassName .. " " .. self.IdentifiableName .. " not found!" )
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
--- Returns the type name of the DCS Identifiable.
|
||||
-- @param #IDENTIFIABLE self
|
||||
-- @return #string The type name of the DCS Identifiable.
|
||||
-- @return #nil The DCS Identifiable is not existing or alive.
|
||||
function IDENTIFIABLE:GetTypeName()
|
||||
self:F2( self.IdentifiableName )
|
||||
|
||||
local DCSIdentifiable = self:GetDCSObject()
|
||||
|
||||
if DCSIdentifiable then
|
||||
local IdentifiableTypeName = DCSIdentifiable:getTypeName()
|
||||
self:T3( IdentifiableTypeName )
|
||||
return IdentifiableTypeName
|
||||
end
|
||||
|
||||
self:E( self.ClassName .. " " .. self.IdentifiableName .. " not found!" )
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
--- Returns category of the DCS Identifiable.
|
||||
-- @param #IDENTIFIABLE self
|
||||
-- @return Dcs.DCSWrapper.Object#Object.Category The category ID
|
||||
function IDENTIFIABLE:GetCategory()
|
||||
self:F2( self.ObjectName )
|
||||
|
||||
local DCSObject = self:GetDCSObject()
|
||||
if DCSObject then
|
||||
local ObjectCategory = DCSObject:getCategory()
|
||||
self:T3( ObjectCategory )
|
||||
return ObjectCategory
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
--- Returns the DCS Identifiable category name as defined within the DCS Identifiable Descriptor.
|
||||
-- @param #IDENTIFIABLE self
|
||||
-- @return #string The DCS Identifiable Category Name
|
||||
function IDENTIFIABLE:GetCategoryName()
|
||||
local DCSIdentifiable = self:GetDCSObject()
|
||||
|
||||
if DCSIdentifiable then
|
||||
local IdentifiableCategoryName = _CategoryName[ self:GetDesc().category ]
|
||||
return IdentifiableCategoryName
|
||||
end
|
||||
|
||||
self:E( self.ClassName .. " " .. self.IdentifiableName .. " not found!" )
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Returns coalition of the Identifiable.
|
||||
-- @param #IDENTIFIABLE self
|
||||
-- @return Dcs.DCSCoalitionWrapper.Object#coalition.side The side of the coalition.
|
||||
-- @return #nil The DCS Identifiable is not existing or alive.
|
||||
function IDENTIFIABLE:GetCoalition()
|
||||
self:F2( self.IdentifiableName )
|
||||
|
||||
local DCSIdentifiable = self:GetDCSObject()
|
||||
|
||||
if DCSIdentifiable then
|
||||
local IdentifiableCoalition = DCSIdentifiable:getCoalition()
|
||||
self:T3( IdentifiableCoalition )
|
||||
return IdentifiableCoalition
|
||||
end
|
||||
|
||||
self:E( self.ClassName .. " " .. self.IdentifiableName .. " not found!" )
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Returns country of the Identifiable.
|
||||
-- @param #IDENTIFIABLE self
|
||||
-- @return Dcs.DCScountry#country.id The country identifier.
|
||||
-- @return #nil The DCS Identifiable is not existing or alive.
|
||||
function IDENTIFIABLE:GetCountry()
|
||||
self:F2( self.IdentifiableName )
|
||||
|
||||
local DCSIdentifiable = self:GetDCSObject()
|
||||
|
||||
if DCSIdentifiable then
|
||||
local IdentifiableCountry = DCSIdentifiable:getCountry()
|
||||
self:T3( IdentifiableCountry )
|
||||
return IdentifiableCountry
|
||||
end
|
||||
|
||||
self:E( self.ClassName .. " " .. self.IdentifiableName .. " not found!" )
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
|
||||
--- Returns Identifiable descriptor. Descriptor type depends on Identifiable category.
|
||||
-- @param #IDENTIFIABLE self
|
||||
-- @return Dcs.DCSWrapper.Identifiable#Identifiable.Desc The Identifiable descriptor.
|
||||
-- @return #nil The DCS Identifiable is not existing or alive.
|
||||
function IDENTIFIABLE:GetDesc()
|
||||
self:F2( self.IdentifiableName )
|
||||
|
||||
local DCSIdentifiable = self:GetDCSObject()
|
||||
|
||||
if DCSIdentifiable then
|
||||
local IdentifiableDesc = DCSIdentifiable:getDesc()
|
||||
self:T2( IdentifiableDesc )
|
||||
return IdentifiableDesc
|
||||
end
|
||||
|
||||
self:E( self.ClassName .. " " .. self.IdentifiableName .. " not found!" )
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Gets the CallSign of the IDENTIFIABLE, which is a blank by default.
|
||||
-- @param #IDENTIFIABLE self
|
||||
-- @return #string The CallSign of the IDENTIFIABLE.
|
||||
function IDENTIFIABLE:GetCallsign()
|
||||
return ''
|
||||
end
|
||||
|
||||
|
||||
function IDENTIFIABLE:GetThreatLevel()
|
||||
|
||||
return 0, "Scenery"
|
||||
end
|
||||
88
Moose Development/Moose/Wrapper/Object.lua
Normal file
88
Moose Development/Moose/Wrapper/Object.lua
Normal file
@@ -0,0 +1,88 @@
|
||||
--- This module contains the OBJECT class.
|
||||
--
|
||||
-- 1) @{Object#OBJECT} class, extends @{Base#BASE}
|
||||
-- ===========================================================
|
||||
-- The @{Object#OBJECT} class is a wrapper class to handle the DCS Object objects:
|
||||
--
|
||||
-- * Support all DCS Object APIs.
|
||||
-- * Enhance with Object specific APIs not in the DCS Object API set.
|
||||
-- * Manage the "state" of the DCS Object.
|
||||
--
|
||||
-- 1.1) OBJECT constructor:
|
||||
-- ------------------------------
|
||||
-- The OBJECT class provides the following functions to construct a OBJECT instance:
|
||||
--
|
||||
-- * @{Object#OBJECT.New}(): Create a OBJECT instance.
|
||||
--
|
||||
-- 1.2) OBJECT methods:
|
||||
-- --------------------------
|
||||
-- The following methods can be used to identify an Object object:
|
||||
--
|
||||
-- * @{Object#OBJECT.GetID}(): Returns the ID of the Object object.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- @module Object
|
||||
|
||||
--- The OBJECT class
|
||||
-- @type OBJECT
|
||||
-- @extends Core.Base#BASE
|
||||
-- @field #string ObjectName The name of the Object.
|
||||
OBJECT = {
|
||||
ClassName = "OBJECT",
|
||||
ObjectName = "",
|
||||
}
|
||||
|
||||
--- A DCSObject
|
||||
-- @type DCSObject
|
||||
-- @field id_ The ID of the controllable in DCS
|
||||
|
||||
--- Create a new OBJECT from a DCSObject
|
||||
-- @param #OBJECT self
|
||||
-- @param Dcs.DCSWrapper.Object#Object ObjectName The Object name
|
||||
-- @return #OBJECT self
|
||||
function OBJECT:New( ObjectName, Test )
|
||||
local self = BASE:Inherit( self, BASE:New() )
|
||||
self:F2( ObjectName )
|
||||
self.ObjectName = ObjectName
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
--- Returns the unit's unique identifier.
|
||||
-- @param Wrapper.Object#OBJECT self
|
||||
-- @return Dcs.DCSWrapper.Object#Object.ID ObjectID
|
||||
-- @return #nil The DCS Object is not existing or alive.
|
||||
function OBJECT:GetID()
|
||||
self:F2( self.ObjectName )
|
||||
|
||||
local DCSObject = self:GetDCSObject()
|
||||
|
||||
if DCSObject then
|
||||
local ObjectID = DCSObject:getID()
|
||||
return ObjectID
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Destroys the OBJECT.
|
||||
-- @param #OBJECT self
|
||||
-- @return #nil The DCS Unit is not existing or alive.
|
||||
function OBJECT:Destroy()
|
||||
self:F2( self.ObjectName )
|
||||
|
||||
local DCSObject = self:GetDCSObject()
|
||||
|
||||
if DCSObject then
|
||||
|
||||
DCSObject:destroy()
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user