mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-08-15 10:47:21 +00:00
Compare commits
407 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d792061df8 | ||
|
|
689f9fd8e9 | ||
|
|
b415039947 | ||
|
|
9de6993a4c | ||
|
|
b3facc6e88 | ||
|
|
10ebc0b1e7 | ||
|
|
f03807207d | ||
|
|
6c26f2cd69 | ||
|
|
cf6b7365af | ||
|
|
747777b297 | ||
|
|
20594ad294 | ||
|
|
e22e7f2c58 | ||
|
|
08cc4e3530 | ||
|
|
fa92615f5d | ||
|
|
bd4ad42fcf | ||
|
|
c4ff6d7bfd | ||
|
|
25659647a6 | ||
|
|
e2ffbba04d | ||
|
|
4bc1cd1b51 | ||
|
|
95eb88e67e | ||
|
|
089306b36d | ||
|
|
c59ed155e6 | ||
|
|
0d8f3d25e9 | ||
|
|
cbb800de02 | ||
|
|
52d783a0b7 | ||
|
|
7a4a3217df | ||
|
|
af2299d392 | ||
|
|
24a3298f2e | ||
|
|
5188c40701 | ||
|
|
e01a4fa18c | ||
|
|
de5a283e50 | ||
|
|
89e6672db1 | ||
|
|
fa15d170f7 | ||
|
|
2baa42e2bc | ||
|
|
44160dfa29 | ||
|
|
a283290c06 | ||
|
|
706aea01ca | ||
|
|
fc7e15521d | ||
|
|
7a5c8d54e7 | ||
|
|
136a7c2a5b | ||
|
|
eebd247fdd | ||
|
|
284a1853ff | ||
|
|
2b89a4b5b1 | ||
|
|
8c6482632b | ||
|
|
51c233956c | ||
|
|
c2e575ef20 | ||
|
|
7c2c6daf3e | ||
|
|
9d100e9bc1 | ||
|
|
7b5136eabf | ||
|
|
af7a87e5a0 | ||
|
|
a18d432141 | ||
|
|
011a5b94fd | ||
|
|
d672983c11 | ||
|
|
9be9277a08 | ||
|
|
5976b92281 | ||
|
|
0f18b29144 | ||
|
|
533689826e | ||
|
|
62eb36c456 | ||
|
|
34265720cc | ||
|
|
38d267b2bc | ||
|
|
251302839e | ||
|
|
285c05b6ba | ||
|
|
bdc66058ab | ||
|
|
df6bc598a4 | ||
|
|
c5c437fa50 | ||
|
|
650f16084b | ||
|
|
949178d698 | ||
|
|
e57d05fc91 | ||
|
|
92d4bad63f | ||
|
|
58b2802f3a | ||
|
|
e16eb38764 | ||
|
|
f5a2183808 | ||
|
|
2bc7a8c126 | ||
|
|
03ba031153 | ||
|
|
7fe333cc35 | ||
|
|
6f1e483fd7 | ||
|
|
01c18278fc | ||
|
|
5120088b66 | ||
|
|
f82a0c092a | ||
|
|
296d1dbc2b | ||
|
|
825f4f2fac | ||
|
|
53980423a9 | ||
|
|
fe01c03037 | ||
|
|
96ca3eeb44 | ||
|
|
309ba285b1 | ||
|
|
f2cb750aa2 | ||
|
|
3544f07169 | ||
|
|
75f5cf9ac5 | ||
|
|
a780f6635f | ||
|
|
ae2e99a560 | ||
|
|
34592a53be | ||
|
|
370278e643 | ||
|
|
778ab58eee | ||
|
|
bf9d6cbd75 | ||
|
|
6bcbffb37f | ||
|
|
68c701afc6 | ||
|
|
d11de24866 | ||
|
|
5c7caadab7 | ||
|
|
8bbff46efd | ||
|
|
0865390284 | ||
|
|
6dfba37fe9 | ||
|
|
0147c3a17c | ||
|
|
03c38356ce | ||
|
|
5e5dab99eb | ||
|
|
9f17382145 | ||
|
|
43336ae431 | ||
|
|
fed937c7b7 | ||
|
|
734f624a9e | ||
|
|
a518af1200 | ||
|
|
d3fc84fe8c | ||
|
|
a5e2309409 | ||
|
|
760bdd2016 | ||
|
|
733b4940f8 | ||
|
|
2620927146 | ||
|
|
96216494bb | ||
|
|
67b5d0ca1c | ||
|
|
296b06e0b0 | ||
|
|
4e28ed3ee6 | ||
|
|
08ad1a0bce | ||
|
|
d935cbaea2 | ||
|
|
f7a5fc7d92 | ||
|
|
6329ac9262 | ||
|
|
4649e2f823 | ||
|
|
06df068d6b | ||
|
|
0dd4676879 | ||
|
|
17fc554beb | ||
|
|
510cef1d59 | ||
|
|
dc8d9ddfdd | ||
|
|
ed0f84da61 | ||
|
|
e0aa16dbd5 | ||
|
|
7ff664b05d | ||
|
|
930768e2e3 | ||
|
|
c1278993aa | ||
|
|
7145fef233 | ||
|
|
0a118cf264 | ||
|
|
344871d727 | ||
|
|
43b2f8c3ff | ||
|
|
85f0fe758b | ||
|
|
bb2a1a82a8 | ||
|
|
b2a7c994bc | ||
|
|
83044af064 | ||
|
|
abcbbdfb79 | ||
|
|
dc75002723 | ||
|
|
3ce5d71fc9 | ||
|
|
0764affd49 | ||
|
|
8507a85915 | ||
|
|
0dcd414c24 | ||
|
|
5ab050b237 | ||
|
|
7eedd7cbf1 | ||
|
|
0e0b1f470b | ||
|
|
beba6ee751 | ||
|
|
2d1409dedb | ||
|
|
85cb0b40f8 | ||
|
|
eb9fc7589f | ||
|
|
a334511601 | ||
|
|
646958cc1a | ||
|
|
cd414a8129 | ||
|
|
857ebfab44 | ||
|
|
039491a3e1 | ||
|
|
051733ac97 | ||
|
|
f2774dbf71 | ||
|
|
6f6db6d26f | ||
|
|
f69f666deb | ||
|
|
5134de9f28 | ||
|
|
b3267c00e9 | ||
|
|
282bf8bd07 | ||
|
|
b52b5b78c9 | ||
|
|
9bca76ddcf | ||
|
|
77cddfaeb4 | ||
|
|
ee6a553b6b | ||
|
|
2e195e6dca | ||
|
|
f615d2c50a | ||
|
|
e54fad6c53 | ||
|
|
7b0c0a0c8b | ||
|
|
4efe03b07b | ||
|
|
030bd92148 | ||
|
|
0f4b3e0d88 | ||
|
|
abf0de49d1 | ||
|
|
e7d48f335c | ||
|
|
ee4f7e843d | ||
|
|
4157ede997 | ||
|
|
54450c9933 | ||
|
|
f545d5d31f | ||
|
|
8332ba5112 | ||
|
|
f35d78c11c | ||
|
|
93f03a1e8b | ||
|
|
c018a6e13f | ||
|
|
b8c1135b3b | ||
|
|
abbb59efb9 | ||
|
|
ce61e8d859 | ||
|
|
ee698722a6 | ||
|
|
be0856c9e1 | ||
|
|
e04b434fcb | ||
|
|
95112e8818 | ||
|
|
09d02e18cf | ||
|
|
2ce1057d71 | ||
|
|
e048ea995e | ||
|
|
d66b7b8c20 | ||
|
|
37dc49c14f | ||
|
|
ef1290015e | ||
|
|
02c671bd63 | ||
|
|
18a15332fe | ||
|
|
d733221317 | ||
|
|
e036ec0adf | ||
|
|
f18b18187b | ||
|
|
3135639557 | ||
|
|
5eeafd2fba | ||
|
|
0577e7ee70 | ||
|
|
d9a4c63011 | ||
|
|
7fd2500db4 | ||
|
|
822920e77e | ||
|
|
85e2811c79 | ||
|
|
757b2cb6a2 | ||
|
|
15c09d9880 | ||
|
|
64b6f52a2d | ||
|
|
27159c4234 | ||
|
|
d38c2540c2 | ||
|
|
901f460907 | ||
|
|
a2fa2c4fa2 | ||
|
|
76ea635b63 | ||
|
|
d2a7cc77cc | ||
|
|
c81e9e5a5e | ||
|
|
92c4507a55 | ||
|
|
967d608b94 | ||
|
|
14c075abfc | ||
|
|
ce449c37b1 | ||
|
|
09f5421612 | ||
|
|
3c8244b2aa | ||
|
|
057e528947 | ||
|
|
e9fe11e9b3 | ||
|
|
b7183023c9 | ||
|
|
dd58838983 | ||
|
|
ef5d69032a | ||
|
|
6dcbbec087 | ||
|
|
6c98cf3a09 | ||
|
|
5f6981d309 | ||
|
|
49d3e4e7da | ||
|
|
060a1b219f | ||
|
|
4db18a4846 | ||
|
|
42a9e4c60d | ||
|
|
f3bd097e6f | ||
|
|
1848e117aa | ||
|
|
131db74630 | ||
|
|
46e76a3833 | ||
|
|
7ff06b5ef8 | ||
|
|
f65238efe6 | ||
|
|
0a819f254a | ||
|
|
7c7722efe6 | ||
|
|
e229e2e381 | ||
|
|
ac0d2fa92c | ||
|
|
e9837acda3 | ||
|
|
2e049ccfd4 | ||
|
|
73a1c56532 | ||
|
|
5686f97565 | ||
|
|
c1910646e2 | ||
|
|
dab20a3b88 | ||
|
|
f82d07ebc0 | ||
|
|
e625aaf28c | ||
|
|
7bc0f103d9 | ||
|
|
6a0294e22b | ||
|
|
82fa9ae8b3 | ||
|
|
0c70a34561 | ||
|
|
4618e81039 | ||
|
|
84fee06196 | ||
|
|
f6f2695808 | ||
|
|
cbf0112bd7 | ||
|
|
97be67bae9 | ||
|
|
58a6c43c41 | ||
|
|
d564b0161c | ||
|
|
6e47fd0c46 | ||
|
|
9a90225d40 | ||
|
|
43b5926b74 | ||
|
|
86c7e64018 | ||
|
|
c66117464a | ||
|
|
6f0a254929 | ||
|
|
c495d0e5e9 | ||
|
|
bdf5c1e960 | ||
|
|
86ad985e0b | ||
|
|
abf84e121f | ||
|
|
212c674443 | ||
|
|
9965d8284e | ||
|
|
3ac649d6e8 | ||
|
|
0e4a5c02d5 | ||
|
|
8a4a37ac11 | ||
|
|
74951f4237 | ||
|
|
8aa14428dc | ||
|
|
8002febf09 | ||
|
|
7da932e048 | ||
|
|
6923cfe143 | ||
|
|
06283ad9e3 | ||
|
|
f4a0b83619 | ||
|
|
70e5ce30bb | ||
|
|
3b3017aa1d | ||
|
|
6c5dcb068b | ||
|
|
ea7d4e4ab8 | ||
|
|
a8c5ccd4ad | ||
|
|
e41b038730 | ||
|
|
172e51307c | ||
|
|
ccb4d7f7b5 | ||
|
|
140f81b695 | ||
|
|
81d724d881 | ||
|
|
b7528dad2e | ||
|
|
63ba44dca2 | ||
|
|
8ea8702140 | ||
|
|
b923159298 | ||
|
|
79afc5a856 | ||
|
|
4d8179ec70 | ||
|
|
224f0694d8 | ||
|
|
57b4838a5a | ||
|
|
a204dd2f4b | ||
|
|
7cab0ca22a | ||
|
|
3e16e5fa51 | ||
|
|
210ad2154c | ||
|
|
bce2e3b922 | ||
|
|
a8e77bddd4 | ||
|
|
d8eb7ce097 | ||
|
|
d0107d5cee | ||
|
|
a82be92577 | ||
|
|
730cd92d51 | ||
|
|
d3b5c77e5c | ||
|
|
f1b7ae7643 | ||
|
|
f952cd4bb5 | ||
|
|
32e61da588 | ||
|
|
c27197500c | ||
|
|
b5fbe6d55e | ||
|
|
291df87beb | ||
|
|
a661c6e711 | ||
|
|
e1d12cbd8e | ||
|
|
1e2a84608f | ||
|
|
88260ae4f3 | ||
|
|
3a8c1f97f1 | ||
|
|
0cc36b5ee2 | ||
|
|
d5c7d0028b | ||
|
|
3a0f60adc9 | ||
|
|
a575dfea7d | ||
|
|
515cf70295 | ||
|
|
fbabc54e03 | ||
|
|
059754fc28 | ||
|
|
cbc0579c79 | ||
|
|
da0bf650fa | ||
|
|
4de8bc742f | ||
|
|
93ba003e5b | ||
|
|
da476b29a6 | ||
|
|
5ee9633dc6 | ||
|
|
6d2e8d34fb | ||
|
|
a35e95a7dc | ||
|
|
126810a273 | ||
|
|
58e3e5293e | ||
|
|
8eff6493ec | ||
|
|
0227549207 | ||
|
|
ddf45d8485 | ||
|
|
6f151a6c5d | ||
|
|
9bfca83804 | ||
|
|
4b74d1b724 | ||
|
|
1067f16ce4 | ||
|
|
5896ebe9ca | ||
|
|
305cb3092e | ||
|
|
04c2a545f2 | ||
|
|
09fd43a3c9 | ||
|
|
d0c6a9756c | ||
|
|
b72f649b91 | ||
|
|
a78275814d | ||
|
|
c4fbdb32c4 | ||
|
|
4be4482957 | ||
|
|
8542823692 | ||
|
|
712b77b590 | ||
|
|
57cb31c86b | ||
|
|
7f04c98d61 | ||
|
|
15ea0bc63a | ||
|
|
50aaeb1465 | ||
|
|
a515385ae0 | ||
|
|
399021502f | ||
|
|
020f097584 | ||
|
|
5c56e75a60 | ||
|
|
f2afd524ef | ||
|
|
ea8ba2f9aa | ||
|
|
421541e88e | ||
|
|
7c26e88345 | ||
|
|
84ddb3e380 | ||
|
|
ffc1c5d6ad | ||
|
|
0a325efeaf | ||
|
|
cd83a0b488 | ||
|
|
fe47783bfa | ||
|
|
6061883194 | ||
|
|
2d6b74ee9e | ||
|
|
feef4c148e | ||
|
|
6952401238 | ||
|
|
454c0e5543 | ||
|
|
1f5030fcbc | ||
|
|
78f4f532f7 | ||
|
|
18de424352 | ||
|
|
36a9295197 | ||
|
|
ca77e2d029 | ||
|
|
93d5327811 | ||
|
|
2224cc7593 | ||
|
|
d5e9c47bad | ||
|
|
5aad27edfc | ||
|
|
0b5d97bf3f | ||
|
|
e1aef42df8 | ||
|
|
f115630546 | ||
|
|
c6e86c494d | ||
|
|
cafcbfde90 | ||
|
|
632ce65bf5 | ||
|
|
b84d08f052 | ||
|
|
57eeefcf06 | ||
|
|
9227bbdfca | ||
|
|
a021967295 |
85
.appveyor/appveyor.yml
Normal file
85
.appveyor/appveyor.yml
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
version: 3.9.1.{build}
|
||||||
|
shallow_clone: true
|
||||||
|
skip_branch_with_pr: false
|
||||||
|
skip_commits:
|
||||||
|
message: /!nobuild/
|
||||||
|
skip_tags: false
|
||||||
|
|
||||||
|
environment:
|
||||||
|
access_token_documentation:
|
||||||
|
secure: JVBVVL8uJUcLXN+48eRdELEeCGOGCCaMzCqutsUqNuaZ/KblG5ZTt7+LV4UKv/0f
|
||||||
|
LUAROCKS_VER: 2.4.1
|
||||||
|
LUA_VER: 5.1.5
|
||||||
|
LUA: lua5.3
|
||||||
|
matrix:
|
||||||
|
- LUA_VER: 5.1.5
|
||||||
|
|
||||||
|
platform:
|
||||||
|
- x64
|
||||||
|
|
||||||
|
init:
|
||||||
|
- ps: if ($env:APPVEYOR_PULL_REQUEST_NUMBER -and $env:APPVEYOR_BUILD_NUMBER -ne ((Invoke-RestMethod `
|
||||||
|
https://ci.appveyor.com/api/projects/$env:APPVEYOR_ACCOUNT_NAME/$env:APPVEYOR_PROJECT_SLUG/history?recordsNumber=50).builds | `
|
||||||
|
Where-Object pullRequestId -eq $env:APPVEYOR_PULL_REQUEST_NUMBER)[0].buildNumber) { `
|
||||||
|
throw "There are newer queued builds for this pull request, failing early." }
|
||||||
|
# - ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
|
||||||
|
|
||||||
|
install:
|
||||||
|
# Outcomment if lua environment invalidates and needs to be reinstalled, otherwise all will run from the cache.
|
||||||
|
# - call choco install 7zip.commandline
|
||||||
|
# - call choco install lua51
|
||||||
|
# - call choco install luarocks
|
||||||
|
# - call refreshenv
|
||||||
|
# - call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat"
|
||||||
|
# - cmd: PATH = %PATH%;C:\ProgramData\chocolatey\lib\luarocks\luarocks-2.4.3-win32\systree\bin
|
||||||
|
# - cmd: set LUA_PATH = %LUA_PATH%;C:\ProgramData\chocolatey\lib\luarocks\luarocks-2.4.3-win32\systree\share\lua\5.1\?.lua;C:\ProgramData\chocolatey\lib\luarocks\luarocks-2.4.3-win32\systree\share\lua\5.1\?\init.lua
|
||||||
|
# - cmd: set LUA_CPATH = %LUA_CPATH%;C:\ProgramData\chocolatey\lib\luarocks\luarocks-2.4.3-win32\systree\lib\lua\5.1\?.dll
|
||||||
|
# - call luarocks install luasrcdiet
|
||||||
|
# - call luarocks install checks
|
||||||
|
# - call luarocks install luadocumentor
|
||||||
|
# - call luarocks install luacheck
|
||||||
|
|
||||||
|
|
||||||
|
#cache:
|
||||||
|
# - C:\ProgramData\chocolatey\lib
|
||||||
|
# - C:\ProgramData\chocolatey\bin
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
build_script:
|
||||||
|
- ps: |
|
||||||
|
if( $env:appveyor_repo_branch -eq 'master' )
|
||||||
|
{
|
||||||
|
$apiUrl = 'https://ci.appveyor.com/api'
|
||||||
|
$token = 'qts80b5kpq0ooj4x6vvw'
|
||||||
|
$headers = @{
|
||||||
|
"Authorization" = "Bearer $token"
|
||||||
|
"Content-type" = "application/json"
|
||||||
|
}
|
||||||
|
$RequestBody = @{ accountName = 'FlightControl-Master'; projectSlug = 'moose-include'; branch = 'master'; environmentVariables = @{} } | ConvertTo-Json
|
||||||
|
# get project with last build details
|
||||||
|
$project = Invoke-RestMethod -method Post -Uri "$apiUrl/builds" -Headers $headers -Body $RequestBody
|
||||||
|
}
|
||||||
|
- ps: |
|
||||||
|
if( $env:appveyor_repo_branch -eq 'master' )
|
||||||
|
{
|
||||||
|
$apiUrl = 'https://ci.appveyor.com/api'
|
||||||
|
$token = 'qts80b5kpq0ooj4x6vvw'
|
||||||
|
$headers = @{
|
||||||
|
"Authorization" = "Bearer $token"
|
||||||
|
"Content-type" = "application/json"
|
||||||
|
}
|
||||||
|
$RequestBody = @{ accountName = 'FlightControl-Master'; projectSlug = 'moose-docs'; branch = 'master'; environmentVariables = @{} } | ConvertTo-Json
|
||||||
|
# get project with last build details
|
||||||
|
$project = Invoke-RestMethod -method Post -Uri "$apiUrl/builds" -Headers $headers -Body $RequestBody
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
test: off
|
||||||
|
# test_script:
|
||||||
|
# - cmd: luacheck "Moose Development\Moose\moose.lua" "Moose Mission Setup\moose.lua"
|
||||||
|
|
||||||
|
|
||||||
|
on_finish:
|
||||||
|
# - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
|
||||||
4
.gitmodules
vendored
4
.gitmodules
vendored
@@ -1,4 +0,0 @@
|
|||||||
[submodule "Moose Development/Moose/Dcs"]
|
|
||||||
path = Moose Development/Moose/Dcs
|
|
||||||
url = https://github.com/FlightControl-Master/DCS-API.git
|
|
||||||
branch = master
|
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
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
|
|
||||||
37
Moose Development/Debugger/MissionScripting.lua
Normal file
37
Moose Development/Debugger/MissionScripting.lua
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
--Initialization script for the Mission lua Environment (SSE)
|
||||||
|
|
||||||
|
dofile('Scripts/ScriptingSystem.lua')
|
||||||
|
|
||||||
|
-- Add LuaSocket to the LUAPATH, so that it can be found.
|
||||||
|
package.path = package.path..";.\\LuaSocket\\?.lua;"
|
||||||
|
|
||||||
|
-- Connect to the debugger, first require it.
|
||||||
|
local initconnection = require("debugger")
|
||||||
|
|
||||||
|
-- Now make the connection..
|
||||||
|
-- "127.0.0.1" is the localhost.
|
||||||
|
-- 10000 is the port. If you wanna use another port in LDT, change this number too!
|
||||||
|
-- "dcsserver" is the name of the server. If you wanna use another name, change the name here too!
|
||||||
|
-- nil (is for transport protocol, but not using this)
|
||||||
|
-- "win" don't touch. But is important to indicate that we are in a windows environment to the debugger script.
|
||||||
|
initconnection( "127.0.0.1", 10000, "dcsserver", nil, "win", "" )
|
||||||
|
|
||||||
|
|
||||||
|
--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
|
||||||
56
Moose Development/Debugger/READ.ME
Normal file
56
Moose Development/Debugger/READ.ME
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
|
||||||
|
-- If you want to use the debugger, add 3 lines of extra code into MissionScripting.lua of DCS world.
|
||||||
|
-- De-sanitize the io module. The debugger needs it.
|
||||||
|
|
||||||
|
|
||||||
|
---------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- MissionScripting.lua modifications
|
||||||
|
---------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
-- --Initialization script for the Mission lua Environment (SSE)
|
||||||
|
--
|
||||||
|
-- dofile('Scripts/ScriptingSystem.lua')
|
||||||
|
--
|
||||||
|
-- package.path = package.path..";.\\LuaSocket\\?.lua;"
|
||||||
|
-- local initconnection = require("debugger")
|
||||||
|
-- initconnection( "127.0.0.1", 10000, "dcsserver", nil, "win", "" )
|
||||||
|
--
|
||||||
|
-- --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
|
||||||
|
|
||||||
|
---------------------------------------------------------------------------------------------------------------------------
|
||||||
|
---------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- So for clarity, these are the three lines of code that matter!
|
||||||
|
|
||||||
|
-- Add LuaSocket to the LUAPATH, so that it can be found.
|
||||||
|
package.path = package.path..";.\\LuaSocket\\?.lua;"
|
||||||
|
|
||||||
|
-- Connect to the debugger, first require it.
|
||||||
|
local initconnection = require("debugger")
|
||||||
|
|
||||||
|
-- Now make the connection..
|
||||||
|
-- "127.0.0.1" is the localhost.
|
||||||
|
-- 10000 is the port. If you wanna use another port in LDT, change this number too!
|
||||||
|
-- "dcsserver" is the name of the server. Ensure the same name is used at the Debug Configuration panel!
|
||||||
|
-- nil (is for transport protocol, but not using this)
|
||||||
|
-- "win" don't touch. But is important to indicate that we are in a windows environment to the debugger script.
|
||||||
|
initconnection( "127.0.0.1", 10000, "dcsserver", nil, "win", "" )
|
||||||
|
|
||||||
3482
Moose Development/Debugger/debugger.lua
Normal file
3482
Moose Development/Debugger/debugger.lua
Normal file
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -1,9 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<launchConfiguration type="org.eclipse.ui.externaltools.ProgramLaunchConfigurationType">
|
|
||||||
<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
|
|
||||||
<listEntry value="org.eclipse.ui.externaltools.launchGroup"/>
|
|
||||||
</listAttribute>
|
|
||||||
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${workspace_loc:/Moose_Framework/Utils/GenerateDocumentations.bat}"/>
|
|
||||||
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS" value="*.lua"/>
|
|
||||||
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_WORKING_DIRECTORY" value="${workspace_loc:/Moose_Framework/Utils}"/>
|
|
||||||
</launchConfiguration>
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<launchConfiguration type="org.eclipse.ui.externaltools.ProgramLaunchConfigurationType">
|
|
||||||
<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
|
|
||||||
<listEntry value="org.eclipse.ui.externaltools.launchGroup"/>
|
|
||||||
</listAttribute>
|
|
||||||
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${workspace_loc:/Moose_Framework/Utils/Generate_Moose.bat}"/>
|
|
||||||
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS" value=""Moose_Create.lua" "D" "${current_date}" "${workspace_loc:/Moose_Framework//Moose Development/Moose}" "${workspace_loc:/Moose_Framework/Moose Mission Setup}""/>
|
|
||||||
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_WORKING_DIRECTORY" value="${workspace_loc:/Moose_Framework/Moose Mission Setup}"/>
|
|
||||||
</launchConfiguration>
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<launchConfiguration type="org.eclipse.ui.externaltools.ProgramLaunchConfigurationType">
|
|
||||||
<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
|
|
||||||
<listEntry value="org.eclipse.ui.externaltools.launchGroup"/>
|
|
||||||
</listAttribute>
|
|
||||||
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${workspace_loc:/Moose_Framework/Utils/Generate_Moose.bat}"/>
|
|
||||||
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS" value=""Moose_Create.lua" "S" "${current_date}" "${workspace_loc:/Moose_Framework//Moose Development/Moose}" "${workspace_loc:/Moose_Framework/Moose Mission Setup}""/>
|
|
||||||
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_WORKING_DIRECTORY" value="${workspace_loc:/Moose_Framework/Moose Mission Setup}"/>
|
|
||||||
</launchConfiguration>
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<launchConfiguration type="org.eclipse.ui.externaltools.ProgramLaunchConfigurationType">
|
|
||||||
<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
|
|
||||||
<listEntry value="org.eclipse.ui.externaltools.launchGroup"/>
|
|
||||||
</listAttribute>
|
|
||||||
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${workspace_loc:/Moose_Framework/Moose Mission Setup/Moose Mission Update/Moose_Update_Missions.bat}"/>
|
|
||||||
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_WORKING_DIRECTORY" value="${workspace_loc:/Moose_Missions}"/>
|
|
||||||
</launchConfiguration>
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<launchConfiguration type="org.eclipse.ui.externaltools.ProgramLaunchConfigurationType">
|
|
||||||
<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
|
|
||||||
<listEntry value="org.eclipse.ui.externaltools.launchGroup"/>
|
|
||||||
</listAttribute>
|
|
||||||
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${workspace_loc:/Moose_Framework/Moose Mission Setup/Moose Mission Update/Moose_Update_Missions.bat}"/>
|
|
||||||
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS" value=""${selected_resource_loc}""/>
|
|
||||||
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_WORKING_DIRECTORY" value="${workspace_loc:/Moose_Framework/Moose Mission Setup/Moose Mission Update}"/>
|
|
||||||
</launchConfiguration>
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,14 +1,12 @@
|
|||||||
--- **AI** -- **AI A2A Air Patrolling or Staging.**
|
--- **AI** -- (R2.2) - Models the process of air operations for airplanes.
|
||||||
--
|
--
|
||||||
-- ====
|
-- This is a class used in the @{AI_A2A_Dispatcher}.
|
||||||
--
|
--
|
||||||
-- ### Author: **Sven Van de Velde (FlightControl)**
|
-- ===
|
||||||
-- ### 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 :-)
|
-- ### Author: **FlightControl**
|
||||||
-- * **[Pikey](https://forums.eagle.ru/member.php?u=62835)**: Testing and API concept review.
|
|
||||||
--
|
--
|
||||||
-- ====
|
-- ===
|
||||||
--
|
--
|
||||||
-- @module AI_A2A
|
-- @module AI_A2A
|
||||||
|
|
||||||
|
|||||||
@@ -1,28 +1,12 @@
|
|||||||
--- **AI** -- **Execute Combat Air Patrol (CAP).**
|
--- **AI** -- (R2.2) - Models the process of Combat Air Patrol (CAP) for airplanes.
|
||||||
|
--
|
||||||
|
-- This is a class used in the @{AI_A2A_Dispatcher}.
|
||||||
--
|
--
|
||||||
-- 
|
|
||||||
--
|
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
-- AI CAP classes makes AI Controllables execute a Combat Air Patrol.
|
-- ### Author: **FlightControl**
|
||||||
--
|
--
|
||||||
-- There are the following types of CAP classes defined:
|
-- ===
|
||||||
--
|
|
||||||
-- * @{#AI_A2A_CAP}: Perform a CAP in a zone.
|
|
||||||
--
|
|
||||||
-- ====
|
|
||||||
--
|
|
||||||
-- ### Author: **Sven Van de Velde (FlightControl)**
|
|
||||||
--
|
|
||||||
-- ### 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.
|
|
||||||
--
|
|
||||||
-- ====
|
|
||||||
--
|
--
|
||||||
-- @module AI_A2A_Cap
|
-- @module AI_A2A_Cap
|
||||||
|
|
||||||
@@ -34,7 +18,7 @@
|
|||||||
|
|
||||||
--- # AI_A2A_CAP class, extends @{AI_CAP#AI_PATROL_ZONE}
|
--- # AI_A2A_CAP class, extends @{AI_CAP#AI_PATROL_ZONE}
|
||||||
--
|
--
|
||||||
-- The AI_A2A_CAP class implements the core functions to patrol a @{Zone} by an AI @{Controllable} or @{Group}
|
-- The AI_A2A_CAP class implements the core functions to patrol a @{Zone} by an AI @{Group} or @{Group}
|
||||||
-- and automatically engage any airborne enemies that are within a certain range or within a certain zone.
|
-- and automatically engage any airborne enemies that are within a certain range or within a certain zone.
|
||||||
--
|
--
|
||||||
-- 
|
-- 
|
||||||
@@ -120,20 +104,20 @@ AI_A2A_CAP = {
|
|||||||
|
|
||||||
--- Creates a new AI_A2A_CAP object
|
--- Creates a new AI_A2A_CAP object
|
||||||
-- @param #AI_A2A_CAP self
|
-- @param #AI_A2A_CAP self
|
||||||
-- @param Wrapper.Group#GROUP AIGroup
|
-- @param Wrapper.Group#GROUP AICap
|
||||||
-- @param Core.Zone#ZONE_BASE PatrolZone The @{Zone} where the patrol needs to be executed.
|
-- @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 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#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 PatrolMinSpeed The minimum speed of the @{Group} in km/h.
|
||||||
-- @param Dcs.DCSTypes#Speed PatrolMaxSpeed The maximum speed of the @{Controllable} in km/h.
|
-- @param Dcs.DCSTypes#Speed PatrolMaxSpeed The maximum speed of the @{Group} in km/h.
|
||||||
-- @param Dcs.DCSTypes#Speed EngageMinSpeed The minimum speed of the @{Controllable} in km/h when engaging a target.
|
-- @param Dcs.DCSTypes#Speed EngageMinSpeed The minimum speed of the @{Group} in km/h when engaging a target.
|
||||||
-- @param Dcs.DCSTypes#Speed EngageMaxSpeed The maximum speed of the @{Controllable} in km/h when engaging a target.
|
-- @param Dcs.DCSTypes#Speed EngageMaxSpeed The maximum speed of the @{Group} in km/h when engaging a target.
|
||||||
-- @param Dcs.DCSTypes#AltitudeType PatrolAltType The altitude type ("RADIO"=="AGL", "BARO"=="ASL"). Defaults to RADIO
|
-- @param Dcs.DCSTypes#AltitudeType PatrolAltType The altitude type ("RADIO"=="AGL", "BARO"=="ASL"). Defaults to RADIO
|
||||||
-- @return #AI_A2A_CAP
|
-- @return #AI_A2A_CAP
|
||||||
function AI_A2A_CAP:New( AIGroup, PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed, EngageMinSpeed, EngageMaxSpeed, PatrolAltType )
|
function AI_A2A_CAP:New( AICap, PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed, EngageMinSpeed, EngageMaxSpeed, PatrolAltType )
|
||||||
|
|
||||||
-- Inherits from BASE
|
-- Inherits from BASE
|
||||||
local self = BASE:Inherit( self, AI_A2A_PATROL:New( AIGroup, PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed, PatrolAltType ) ) -- #AI_A2A_CAP
|
local self = BASE:Inherit( self, AI_A2A_PATROL:New( AICap, PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed, PatrolAltType ) ) -- #AI_A2A_CAP
|
||||||
|
|
||||||
self.Accomplished = false
|
self.Accomplished = false
|
||||||
self.Engaging = false
|
self.Engaging = false
|
||||||
@@ -146,7 +130,7 @@ function AI_A2A_CAP:New( AIGroup, PatrolZone, PatrolFloorAltitude, PatrolCeiling
|
|||||||
--- OnBefore Transition Handler for Event Engage.
|
--- OnBefore Transition Handler for Event Engage.
|
||||||
-- @function [parent=#AI_A2A_CAP] OnBeforeEngage
|
-- @function [parent=#AI_A2A_CAP] OnBeforeEngage
|
||||||
-- @param #AI_A2A_CAP self
|
-- @param #AI_A2A_CAP self
|
||||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
-- @param Wrapper.Group#GROUP AICap The Group Object managed by the FSM.
|
||||||
-- @param #string From The From State string.
|
-- @param #string From The From State string.
|
||||||
-- @param #string Event The Event string.
|
-- @param #string Event The Event string.
|
||||||
-- @param #string To The To State string.
|
-- @param #string To The To State string.
|
||||||
@@ -155,7 +139,7 @@ function AI_A2A_CAP:New( AIGroup, PatrolZone, PatrolFloorAltitude, PatrolCeiling
|
|||||||
--- OnAfter Transition Handler for Event Engage.
|
--- OnAfter Transition Handler for Event Engage.
|
||||||
-- @function [parent=#AI_A2A_CAP] OnAfterEngage
|
-- @function [parent=#AI_A2A_CAP] OnAfterEngage
|
||||||
-- @param #AI_A2A_CAP self
|
-- @param #AI_A2A_CAP self
|
||||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
-- @param Wrapper.Group#GROUP AICap The Group Object managed by the FSM.
|
||||||
-- @param #string From The From State string.
|
-- @param #string From The From State string.
|
||||||
-- @param #string Event The Event string.
|
-- @param #string Event The Event string.
|
||||||
-- @param #string To The To State string.
|
-- @param #string To The To State string.
|
||||||
@@ -172,7 +156,7 @@ function AI_A2A_CAP:New( AIGroup, PatrolZone, PatrolFloorAltitude, PatrolCeiling
|
|||||||
--- OnLeave Transition Handler for State Engaging.
|
--- OnLeave Transition Handler for State Engaging.
|
||||||
-- @function [parent=#AI_A2A_CAP] OnLeaveEngaging
|
-- @function [parent=#AI_A2A_CAP] OnLeaveEngaging
|
||||||
-- @param #AI_A2A_CAP self
|
-- @param #AI_A2A_CAP self
|
||||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
-- @param Wrapper.Group#GROUP AICap The Group Object managed by the FSM.
|
||||||
-- @param #string From The From State string.
|
-- @param #string From The From State string.
|
||||||
-- @param #string Event The Event string.
|
-- @param #string Event The Event string.
|
||||||
-- @param #string To The To State string.
|
-- @param #string To The To State string.
|
||||||
@@ -181,7 +165,7 @@ function AI_A2A_CAP:New( AIGroup, PatrolZone, PatrolFloorAltitude, PatrolCeiling
|
|||||||
--- OnEnter Transition Handler for State Engaging.
|
--- OnEnter Transition Handler for State Engaging.
|
||||||
-- @function [parent=#AI_A2A_CAP] OnEnterEngaging
|
-- @function [parent=#AI_A2A_CAP] OnEnterEngaging
|
||||||
-- @param #AI_A2A_CAP self
|
-- @param #AI_A2A_CAP self
|
||||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
-- @param Wrapper.Group#GROUP AICap The Group Object managed by the FSM.
|
||||||
-- @param #string From The From State string.
|
-- @param #string From The From State string.
|
||||||
-- @param #string Event The Event string.
|
-- @param #string Event The Event string.
|
||||||
-- @param #string To The To State string.
|
-- @param #string To The To State string.
|
||||||
@@ -191,7 +175,7 @@ function AI_A2A_CAP:New( AIGroup, PatrolZone, PatrolFloorAltitude, PatrolCeiling
|
|||||||
--- OnBefore Transition Handler for Event Fired.
|
--- OnBefore Transition Handler for Event Fired.
|
||||||
-- @function [parent=#AI_A2A_CAP] OnBeforeFired
|
-- @function [parent=#AI_A2A_CAP] OnBeforeFired
|
||||||
-- @param #AI_A2A_CAP self
|
-- @param #AI_A2A_CAP self
|
||||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
-- @param Wrapper.Group#GROUP AICap The Group Object managed by the FSM.
|
||||||
-- @param #string From The From State string.
|
-- @param #string From The From State string.
|
||||||
-- @param #string Event The Event string.
|
-- @param #string Event The Event string.
|
||||||
-- @param #string To The To State string.
|
-- @param #string To The To State string.
|
||||||
@@ -200,7 +184,7 @@ function AI_A2A_CAP:New( AIGroup, PatrolZone, PatrolFloorAltitude, PatrolCeiling
|
|||||||
--- OnAfter Transition Handler for Event Fired.
|
--- OnAfter Transition Handler for Event Fired.
|
||||||
-- @function [parent=#AI_A2A_CAP] OnAfterFired
|
-- @function [parent=#AI_A2A_CAP] OnAfterFired
|
||||||
-- @param #AI_A2A_CAP self
|
-- @param #AI_A2A_CAP self
|
||||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
-- @param Wrapper.Group#GROUP AICap The Group Object managed by the FSM.
|
||||||
-- @param #string From The From State string.
|
-- @param #string From The From State string.
|
||||||
-- @param #string Event The Event string.
|
-- @param #string Event The Event string.
|
||||||
-- @param #string To The To State string.
|
-- @param #string To The To State string.
|
||||||
@@ -219,7 +203,7 @@ function AI_A2A_CAP:New( AIGroup, PatrolZone, PatrolFloorAltitude, PatrolCeiling
|
|||||||
--- OnBefore Transition Handler for Event Destroy.
|
--- OnBefore Transition Handler for Event Destroy.
|
||||||
-- @function [parent=#AI_A2A_CAP] OnBeforeDestroy
|
-- @function [parent=#AI_A2A_CAP] OnBeforeDestroy
|
||||||
-- @param #AI_A2A_CAP self
|
-- @param #AI_A2A_CAP self
|
||||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
-- @param Wrapper.Group#GROUP AICap The Group Object managed by the FSM.
|
||||||
-- @param #string From The From State string.
|
-- @param #string From The From State string.
|
||||||
-- @param #string Event The Event string.
|
-- @param #string Event The Event string.
|
||||||
-- @param #string To The To State string.
|
-- @param #string To The To State string.
|
||||||
@@ -228,7 +212,7 @@ function AI_A2A_CAP:New( AIGroup, PatrolZone, PatrolFloorAltitude, PatrolCeiling
|
|||||||
--- OnAfter Transition Handler for Event Destroy.
|
--- OnAfter Transition Handler for Event Destroy.
|
||||||
-- @function [parent=#AI_A2A_CAP] OnAfterDestroy
|
-- @function [parent=#AI_A2A_CAP] OnAfterDestroy
|
||||||
-- @param #AI_A2A_CAP self
|
-- @param #AI_A2A_CAP self
|
||||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
-- @param Wrapper.Group#GROUP AICap The Group Object managed by the FSM.
|
||||||
-- @param #string From The From State string.
|
-- @param #string From The From State string.
|
||||||
-- @param #string Event The Event string.
|
-- @param #string Event The Event string.
|
||||||
-- @param #string To The To State string.
|
-- @param #string To The To State string.
|
||||||
@@ -248,7 +232,7 @@ function AI_A2A_CAP:New( AIGroup, PatrolZone, PatrolFloorAltitude, PatrolCeiling
|
|||||||
--- OnBefore Transition Handler for Event Abort.
|
--- OnBefore Transition Handler for Event Abort.
|
||||||
-- @function [parent=#AI_A2A_CAP] OnBeforeAbort
|
-- @function [parent=#AI_A2A_CAP] OnBeforeAbort
|
||||||
-- @param #AI_A2A_CAP self
|
-- @param #AI_A2A_CAP self
|
||||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
-- @param Wrapper.Group#GROUP AICap The Group Object managed by the FSM.
|
||||||
-- @param #string From The From State string.
|
-- @param #string From The From State string.
|
||||||
-- @param #string Event The Event string.
|
-- @param #string Event The Event string.
|
||||||
-- @param #string To The To State string.
|
-- @param #string To The To State string.
|
||||||
@@ -257,7 +241,7 @@ function AI_A2A_CAP:New( AIGroup, PatrolZone, PatrolFloorAltitude, PatrolCeiling
|
|||||||
--- OnAfter Transition Handler for Event Abort.
|
--- OnAfter Transition Handler for Event Abort.
|
||||||
-- @function [parent=#AI_A2A_CAP] OnAfterAbort
|
-- @function [parent=#AI_A2A_CAP] OnAfterAbort
|
||||||
-- @param #AI_A2A_CAP self
|
-- @param #AI_A2A_CAP self
|
||||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
-- @param Wrapper.Group#GROUP AICap The Group Object managed by the FSM.
|
||||||
-- @param #string From The From State string.
|
-- @param #string From The From State string.
|
||||||
-- @param #string Event The Event string.
|
-- @param #string Event The Event string.
|
||||||
-- @param #string To The To State string.
|
-- @param #string To The To State string.
|
||||||
@@ -276,7 +260,7 @@ function AI_A2A_CAP:New( AIGroup, PatrolZone, PatrolFloorAltitude, PatrolCeiling
|
|||||||
--- OnBefore Transition Handler for Event Accomplish.
|
--- OnBefore Transition Handler for Event Accomplish.
|
||||||
-- @function [parent=#AI_A2A_CAP] OnBeforeAccomplish
|
-- @function [parent=#AI_A2A_CAP] OnBeforeAccomplish
|
||||||
-- @param #AI_A2A_CAP self
|
-- @param #AI_A2A_CAP self
|
||||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
-- @param Wrapper.Group#GROUP AICap The Group Object managed by the FSM.
|
||||||
-- @param #string From The From State string.
|
-- @param #string From The From State string.
|
||||||
-- @param #string Event The Event string.
|
-- @param #string Event The Event string.
|
||||||
-- @param #string To The To State string.
|
-- @param #string To The To State string.
|
||||||
@@ -285,7 +269,7 @@ function AI_A2A_CAP:New( AIGroup, PatrolZone, PatrolFloorAltitude, PatrolCeiling
|
|||||||
--- OnAfter Transition Handler for Event Accomplish.
|
--- OnAfter Transition Handler for Event Accomplish.
|
||||||
-- @function [parent=#AI_A2A_CAP] OnAfterAccomplish
|
-- @function [parent=#AI_A2A_CAP] OnAfterAccomplish
|
||||||
-- @param #AI_A2A_CAP self
|
-- @param #AI_A2A_CAP self
|
||||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
-- @param Wrapper.Group#GROUP AICap The Group Object managed by the FSM.
|
||||||
-- @param #string From The From State string.
|
-- @param #string From The From State string.
|
||||||
-- @param #string Event The Event string.
|
-- @param #string Event The Event string.
|
||||||
-- @param #string To The To State string.
|
-- @param #string To The To State string.
|
||||||
@@ -304,13 +288,13 @@ end
|
|||||||
|
|
||||||
--- onafter State Transition for Event Patrol.
|
--- onafter State Transition for Event Patrol.
|
||||||
-- @param #AI_A2A_GCI self
|
-- @param #AI_A2A_GCI self
|
||||||
-- @param Wrapper.Group#GROUP AIGroup The AI Group managed by the FSM.
|
-- @param Wrapper.Group#GROUP AICap The AI Group managed by the FSM.
|
||||||
-- @param #string From The From State string.
|
-- @param #string From The From State string.
|
||||||
-- @param #string Event The Event string.
|
-- @param #string Event The Event string.
|
||||||
-- @param #string To The To State string.
|
-- @param #string To The To State string.
|
||||||
function AI_A2A_CAP:onafterStart( AIGroup, From, Event, To )
|
function AI_A2A_CAP:onafterStart( AICap, From, Event, To )
|
||||||
|
|
||||||
AIGroup:HandleEvent( EVENTS.Takeoff, nil, self )
|
AICap:HandleEvent( EVENTS.Takeoff, nil, self )
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -344,36 +328,36 @@ end
|
|||||||
|
|
||||||
--- onafter State Transition for Event Patrol.
|
--- onafter State Transition for Event Patrol.
|
||||||
-- @param #AI_A2A_CAP self
|
-- @param #AI_A2A_CAP self
|
||||||
-- @param Wrapper.Controllable#CONTROLLABLE AIGroup The AI Group managed by the FSM.
|
-- @param Wrapper.Group#GROUP AICap The AI Group managed by the FSM.
|
||||||
-- @param #string From The From State string.
|
-- @param #string From The From State string.
|
||||||
-- @param #string Event The Event string.
|
-- @param #string Event The Event string.
|
||||||
-- @param #string To The To State string.
|
-- @param #string To The To State string.
|
||||||
function AI_A2A_CAP:onafterPatrol( AIGroup, From, Event, To )
|
function AI_A2A_CAP:onafterPatrol( AICap, From, Event, To )
|
||||||
|
|
||||||
-- Call the parent Start event handler
|
-- Call the parent Start event handler
|
||||||
self:GetParent(self).onafterPatrol( self, AIGroup, From, Event, To )
|
self:GetParent(self).onafterPatrol( self, AICap, From, Event, To )
|
||||||
self:HandleEvent( EVENTS.Dead )
|
self:HandleEvent( EVENTS.Dead )
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- todo: need to fix this global function
|
-- todo: need to fix this global function
|
||||||
|
|
||||||
--- @param Wrapper.Group#GROUP AIGroup
|
--- @param Wrapper.Group#GROUP AICap
|
||||||
function AI_A2A_CAP.AttackRoute( AIGroup, Fsm )
|
function AI_A2A_CAP.AttackRoute( AICap, Fsm )
|
||||||
|
|
||||||
AIGroup:F( { "AI_A2A_CAP.AttackRoute:", AIGroup:GetName() } )
|
AICap:F( { "AI_A2A_CAP.AttackRoute:", AICap:GetName() } )
|
||||||
|
|
||||||
if AIGroup:IsAlive() then
|
if AICap:IsAlive() then
|
||||||
Fsm:__Engage( 0.5 )
|
Fsm:__Engage( 0.5 )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--- @param #AI_A2A_CAP self
|
--- @param #AI_A2A_CAP self
|
||||||
-- @param Wrapper.Controllable#CONTROLLABLE AIGroup The Controllable Object managed by the FSM.
|
-- @param Wrapper.Group#GROUP AICap The Group Object managed by the FSM.
|
||||||
-- @param #string From The From State string.
|
-- @param #string From The From State string.
|
||||||
-- @param #string Event The Event string.
|
-- @param #string Event The Event string.
|
||||||
-- @param #string To The To State string.
|
-- @param #string To The To State string.
|
||||||
function AI_A2A_CAP:onbeforeEngage( AIGroup, From, Event, To )
|
function AI_A2A_CAP:onbeforeEngage( AICap, From, Event, To )
|
||||||
|
|
||||||
if self.Accomplished == true then
|
if self.Accomplished == true then
|
||||||
return false
|
return false
|
||||||
@@ -381,24 +365,24 @@ function AI_A2A_CAP:onbeforeEngage( AIGroup, From, Event, To )
|
|||||||
end
|
end
|
||||||
|
|
||||||
--- @param #AI_A2A_CAP self
|
--- @param #AI_A2A_CAP self
|
||||||
-- @param Wrapper.Controllable#CONTROLLABLE AIGroup The AI Group managed by the FSM.
|
-- @param Wrapper.Group#GROUP AICap The AI Group managed by the FSM.
|
||||||
-- @param #string From The From State string.
|
-- @param #string From The From State string.
|
||||||
-- @param #string Event The Event string.
|
-- @param #string Event The Event string.
|
||||||
-- @param #string To The To State string.
|
-- @param #string To The To State string.
|
||||||
function AI_A2A_CAP:onafterAbort( AIGroup, From, Event, To )
|
function AI_A2A_CAP:onafterAbort( AICap, From, Event, To )
|
||||||
AIGroup:ClearTasks()
|
AICap:ClearTasks()
|
||||||
self:__Route( 0.5 )
|
self:__Route( 0.5 )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- @param #AI_A2A_CAP self
|
--- @param #AI_A2A_CAP self
|
||||||
-- @param Wrapper.Controllable#CONTROLLABLE AIGroup The Controllable Object managed by the FSM.
|
-- @param Wrapper.Group#GROUP AICap The AICap Object managed by the FSM.
|
||||||
-- @param #string From The From State string.
|
-- @param #string From The From State string.
|
||||||
-- @param #string Event The Event string.
|
-- @param #string Event The Event string.
|
||||||
-- @param #string To The To State string.
|
-- @param #string To The To State string.
|
||||||
function AI_A2A_CAP:onafterEngage( AIGroup, From, Event, To, AttackSetUnit )
|
function AI_A2A_CAP:onafterEngage( AICap, From, Event, To, AttackSetUnit )
|
||||||
|
|
||||||
self:F( { AIGroup, From, Event, To, AttackSetUnit} )
|
self:F( { AICap, From, Event, To, AttackSetUnit} )
|
||||||
|
|
||||||
self.AttackSetUnit = AttackSetUnit or self.AttackSetUnit -- Core.Set#SET_UNIT
|
self.AttackSetUnit = AttackSetUnit or self.AttackSetUnit -- Core.Set#SET_UNIT
|
||||||
|
|
||||||
@@ -406,12 +390,12 @@ function AI_A2A_CAP:onafterEngage( AIGroup, From, Event, To, AttackSetUnit )
|
|||||||
|
|
||||||
if FirstAttackUnit and FirstAttackUnit:IsAlive() then -- If there is no attacker anymore, stop the engagement.
|
if FirstAttackUnit and FirstAttackUnit:IsAlive() then -- If there is no attacker anymore, stop the engagement.
|
||||||
|
|
||||||
if AIGroup:IsAlive() then
|
if AICap:IsAlive() then
|
||||||
|
|
||||||
local EngageRoute = {}
|
local EngageRoute = {}
|
||||||
|
|
||||||
--- Calculate the target route point.
|
--- Calculate the target route point.
|
||||||
local CurrentCoord = AIGroup:GetCoordinate()
|
local CurrentCoord = AICap:GetCoordinate()
|
||||||
local ToTargetCoord = self.AttackSetUnit:GetFirst():GetCoordinate()
|
local ToTargetCoord = self.AttackSetUnit:GetFirst():GetCoordinate()
|
||||||
local ToTargetSpeed = math.random( self.EngageMinSpeed, self.EngageMaxSpeed )
|
local ToTargetSpeed = math.random( self.EngageMinSpeed, self.EngageMaxSpeed )
|
||||||
local ToInterceptAngle = CurrentCoord:GetAngleDegrees( CurrentCoord:GetDirectionVec3( ToTargetCoord ) )
|
local ToInterceptAngle = CurrentCoord:GetAngleDegrees( CurrentCoord:GetDirectionVec3( ToTargetCoord ) )
|
||||||
@@ -437,7 +421,7 @@ function AI_A2A_CAP:onafterEngage( AIGroup, From, Event, To, AttackSetUnit )
|
|||||||
local AttackUnit = AttackUnit -- Wrapper.Unit#UNIT
|
local AttackUnit = AttackUnit -- Wrapper.Unit#UNIT
|
||||||
self:T( { "Attacking Unit:", AttackUnit:GetName(), AttackUnit:IsAlive(), AttackUnit:IsAir() } )
|
self:T( { "Attacking Unit:", AttackUnit:GetName(), AttackUnit:IsAlive(), AttackUnit:IsAir() } )
|
||||||
if AttackUnit:IsAlive() and AttackUnit:IsAir() then
|
if AttackUnit:IsAlive() and AttackUnit:IsAir() then
|
||||||
AttackTasks[#AttackTasks+1] = AIGroup:TaskAttackUnit( AttackUnit )
|
AttackTasks[#AttackTasks+1] = AICap:TaskAttackUnit( AttackUnit )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -445,14 +429,14 @@ function AI_A2A_CAP:onafterEngage( AIGroup, From, Event, To, AttackSetUnit )
|
|||||||
self:E("No targets found -> Going back to Patrolling")
|
self:E("No targets found -> Going back to Patrolling")
|
||||||
self:__Abort( 0.5 )
|
self:__Abort( 0.5 )
|
||||||
else
|
else
|
||||||
AIGroup:OptionROEOpenFire()
|
AICap:OptionROEOpenFire()
|
||||||
AIGroup:OptionROTPassiveDefense()
|
AICap:OptionROTEvadeFire()
|
||||||
|
|
||||||
AttackTasks[#AttackTasks+1] = AIGroup:TaskFunction( "AI_A2A_CAP.AttackRoute", self )
|
AttackTasks[#AttackTasks+1] = AICap:TaskFunction( "AI_A2A_CAP.AttackRoute", self )
|
||||||
EngageRoute[#EngageRoute].task = AIGroup:TaskCombo( AttackTasks )
|
EngageRoute[#EngageRoute].task = AICap:TaskCombo( AttackTasks )
|
||||||
end
|
end
|
||||||
|
|
||||||
AIGroup:Route( EngageRoute, 0.5 )
|
AICap:Route( EngageRoute, 0.5 )
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
self:E("No targets found -> Going back to Patrolling")
|
self:E("No targets found -> Going back to Patrolling")
|
||||||
@@ -461,22 +445,22 @@ function AI_A2A_CAP:onafterEngage( AIGroup, From, Event, To, AttackSetUnit )
|
|||||||
end
|
end
|
||||||
|
|
||||||
--- @param #AI_A2A_CAP self
|
--- @param #AI_A2A_CAP self
|
||||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
-- @param Wrapper.Group#GROUP AICap The Group Object managed by the FSM.
|
||||||
-- @param #string From The From State string.
|
-- @param #string From The From State string.
|
||||||
-- @param #string Event The Event string.
|
-- @param #string Event The Event string.
|
||||||
-- @param #string To The To State string.
|
-- @param #string To The To State string.
|
||||||
function AI_A2A_CAP:onafterAccomplish( Controllable, From, Event, To )
|
function AI_A2A_CAP:onafterAccomplish( AICap, From, Event, To )
|
||||||
self.Accomplished = true
|
self.Accomplished = true
|
||||||
self:SetDetectionOff()
|
self:SetDetectionOff()
|
||||||
end
|
end
|
||||||
|
|
||||||
--- @param #AI_A2A_CAP self
|
--- @param #AI_A2A_CAP self
|
||||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
-- @param Wrapper.Group#GROUP AICap The Group Object managed by the FSM.
|
||||||
-- @param #string From The From State string.
|
-- @param #string From The From State string.
|
||||||
-- @param #string Event The Event string.
|
-- @param #string Event The Event string.
|
||||||
-- @param #string To The To State string.
|
-- @param #string To The To State string.
|
||||||
-- @param Core.Event#EVENTDATA EventData
|
-- @param Core.Event#EVENTDATA EventData
|
||||||
function AI_A2A_CAP:onafterDestroy( Controllable, From, Event, To, EventData )
|
function AI_A2A_CAP:onafterDestroy( AICap, From, Event, To, EventData )
|
||||||
|
|
||||||
if EventData.IniUnit then
|
if EventData.IniUnit then
|
||||||
self.AttackUnits[EventData.IniUnit] = nil
|
self.AttackUnits[EventData.IniUnit] = nil
|
||||||
@@ -495,12 +479,12 @@ function AI_A2A_CAP:OnEventDead( EventData )
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--- @param Wrapper.Group#GROUP AIGroup
|
--- @param Wrapper.Group#GROUP AICap
|
||||||
function AI_A2A_CAP.Resume( AIGroup )
|
function AI_A2A_CAP.Resume( AICap )
|
||||||
|
|
||||||
AIGroup:F( { "AI_A2A_CAP.Resume:", AIGroup:GetName() } )
|
AICap:F( { "AI_A2A_CAP.Resume:", AICap:GetName() } )
|
||||||
if AIGroup:IsAlive() then
|
if AICap:IsAlive() then
|
||||||
local _AI_A2A = AIGroup:GetState( AIGroup, "AI_A2A" ) -- #AI_A2A
|
local _AI_A2A = AICap:GetState( AICap, "AI_A2A" ) -- #AI_A2A
|
||||||
_AI_A2A:__Reset( 1 )
|
_AI_A2A:__Reset( 1 )
|
||||||
_AI_A2A:__Route( 5 )
|
_AI_A2A:__Route( 5 )
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
--- **AI** - The AI_A2A_DISPATCHER creates an automatic A2A defense system based on an EWR network targets and coordinating CAP and GCI.
|
--- **AI** - (R2.2) - Manages the process of an automatic A2A defense system based on an EWR network targets and coordinating CAP and GCI.
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
--
|
--
|
||||||
-- 
|
-- 
|
||||||
--
|
--
|
||||||
-- ====
|
-- ===
|
||||||
--
|
--
|
||||||
-- # QUICK START GUIDE
|
-- # QUICK START GUIDE
|
||||||
--
|
--
|
||||||
@@ -150,7 +152,7 @@
|
|||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
-- ### Authors: **Sven Van de Velde (FlightControl)** rework of GCICAP + introduction of new concepts (squadrons).
|
-- ### Authors: **FlightControl** rework of GCICAP + introduction of new concepts (squadrons).
|
||||||
-- ### Authors: **Stonehouse**, **SNAFU** in terms of the advice, documentation, and the original GCICAP script.
|
-- ### Authors: **Stonehouse**, **SNAFU** in terms of the advice, documentation, and the original GCICAP script.
|
||||||
--
|
--
|
||||||
-- @module AI_A2A_Dispatcher
|
-- @module AI_A2A_Dispatcher
|
||||||
@@ -169,13 +171,13 @@ do -- AI_A2A_DISPATCHER
|
|||||||
--
|
--
|
||||||
-- The @{#AI_A2A_DISPATCHER} class is designed to create an automatic air defence system for a coalition.
|
-- The @{#AI_A2A_DISPATCHER} class is designed to create an automatic air defence system for a coalition.
|
||||||
--
|
--
|
||||||
-- ====
|
-- ===
|
||||||
--
|
--
|
||||||
-- # Demo Missions
|
-- # Demo Missions
|
||||||
--
|
--
|
||||||
-- ### [AI\_A2A\_DISPATCHER Demo Missions](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/release-2-2-pre/AID%20-%20AI%20Dispatching)
|
-- ### [AI\_A2A\_DISPATCHER Demo Missions](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/release-2-2-pre/AID%20-%20AI%20Dispatching)
|
||||||
--
|
--
|
||||||
-- ====
|
-- ===
|
||||||
--
|
--
|
||||||
-- # YouTube Channel
|
-- # YouTube Channel
|
||||||
--
|
--
|
||||||
@@ -1001,7 +1003,7 @@ do -- AI_A2A_DISPATCHER
|
|||||||
--- @param #AI_A2A_DISPATCHER self
|
--- @param #AI_A2A_DISPATCHER self
|
||||||
-- @param Core.Event#EVENTDATA EventData
|
-- @param Core.Event#EVENTDATA EventData
|
||||||
function AI_A2A_DISPATCHER:OnEventLand( EventData )
|
function AI_A2A_DISPATCHER:OnEventLand( EventData )
|
||||||
self:E( "Landed" )
|
self:F( "Landed" )
|
||||||
local DefenderUnit = EventData.IniUnit
|
local DefenderUnit = EventData.IniUnit
|
||||||
local Defender = EventData.IniGroup
|
local Defender = EventData.IniGroup
|
||||||
local Squadron = self:GetSquadronFromDefender( Defender )
|
local Squadron = self:GetSquadronFromDefender( Defender )
|
||||||
@@ -1488,7 +1490,7 @@ do -- AI_A2A_DISPATCHER
|
|||||||
DefenderSquadron.Resources = Resources
|
DefenderSquadron.Resources = Resources
|
||||||
DefenderSquadron.TemplatePrefixes = TemplatePrefixes
|
DefenderSquadron.TemplatePrefixes = TemplatePrefixes
|
||||||
|
|
||||||
self:E( { Squadron = {SquadronName, AirbaseName, TemplatePrefixes, Resources } } )
|
self:F( { Squadron = {SquadronName, AirbaseName, TemplatePrefixes, Resources } } )
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
@@ -1554,7 +1556,7 @@ do -- AI_A2A_DISPATCHER
|
|||||||
|
|
||||||
self:SetSquadronCapInterval( SquadronName, self.DefenderDefault.CapLimit, self.DefenderDefault.CapMinSeconds, self.DefenderDefault.CapMaxSeconds, 1 )
|
self:SetSquadronCapInterval( SquadronName, self.DefenderDefault.CapLimit, self.DefenderDefault.CapMinSeconds, self.DefenderDefault.CapMaxSeconds, 1 )
|
||||||
|
|
||||||
self:E( { CAP = { SquadronName, Zone, FloorAltitude, CeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed, EngageMinSpeed, EngageMaxSpeed, AltType } } )
|
self:F( { CAP = { SquadronName, Zone, FloorAltitude, CeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed, EngageMinSpeed, EngageMaxSpeed, AltType } } )
|
||||||
|
|
||||||
-- Add the CAP to the EWR network.
|
-- Add the CAP to the EWR network.
|
||||||
|
|
||||||
@@ -1658,7 +1660,7 @@ do -- AI_A2A_DISPATCHER
|
|||||||
local Cap = DefenderSquadron.Cap
|
local Cap = DefenderSquadron.Cap
|
||||||
if Cap then
|
if Cap then
|
||||||
local CapCount = self:CountCapAirborne( SquadronName )
|
local CapCount = self:CountCapAirborne( SquadronName )
|
||||||
self:E( { CapCount = CapCount } )
|
self:F( { CapCount = CapCount } )
|
||||||
if CapCount < Cap.CapLimit then
|
if CapCount < Cap.CapLimit then
|
||||||
local Probability = math.random()
|
local Probability = math.random()
|
||||||
if Probability <= Cap.Probability then
|
if Probability <= Cap.Probability then
|
||||||
@@ -1716,7 +1718,7 @@ do -- AI_A2A_DISPATCHER
|
|||||||
Intercept.EngageMinSpeed = EngageMinSpeed
|
Intercept.EngageMinSpeed = EngageMinSpeed
|
||||||
Intercept.EngageMaxSpeed = EngageMaxSpeed
|
Intercept.EngageMaxSpeed = EngageMaxSpeed
|
||||||
|
|
||||||
self:E( { GCI = { SquadronName, EngageMinSpeed, EngageMaxSpeed } } )
|
self:F( { GCI = { SquadronName, EngageMinSpeed, EngageMaxSpeed } } )
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Defines the default amount of extra planes that will take-off as part of the defense system.
|
--- Defines the default amount of extra planes that will take-off as part of the defense system.
|
||||||
@@ -2443,7 +2445,7 @@ do -- AI_A2A_DISPATCHER
|
|||||||
if Squadron.Resources then
|
if Squadron.Resources then
|
||||||
Squadron.Resources = Squadron.Resources - Size
|
Squadron.Resources = Squadron.Resources - Size
|
||||||
end
|
end
|
||||||
self:E( { DefenderName = DefenderName, SquadronResources = Squadron.Resources } )
|
self:F( { DefenderName = DefenderName, SquadronResources = Squadron.Resources } )
|
||||||
end
|
end
|
||||||
|
|
||||||
--- @param #AI_A2A_DISPATCHER self
|
--- @param #AI_A2A_DISPATCHER self
|
||||||
@@ -2504,7 +2506,8 @@ do -- AI_A2A_DISPATCHER
|
|||||||
if AIGroup:IsAlive() then
|
if AIGroup:IsAlive() then
|
||||||
-- Check if the CAP is patrolling or engaging. If not, this is not a valid CAP, even if it is alive!
|
-- Check if the CAP is patrolling or engaging. If not, this is not a valid CAP, even if it is alive!
|
||||||
-- The CAP could be damaged, lost control, or out of fuel!
|
-- The CAP could be damaged, lost control, or out of fuel!
|
||||||
if DefenderTask.Fsm:Is( "Patrolling" ) or DefenderTask.Fsm:Is( "Engaging" ) or DefenderTask.Fsm:Is( "Refuelling" )then
|
if DefenderTask.Fsm:Is( "Patrolling" ) or DefenderTask.Fsm:Is( "Engaging" ) or DefenderTask.Fsm:Is( "Refuelling" )
|
||||||
|
or DefenderTask.Fsm:Is( "Started" ) then
|
||||||
CapCount = CapCount + 1
|
CapCount = CapCount + 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -2524,9 +2527,8 @@ do -- AI_A2A_DISPATCHER
|
|||||||
-- First, count the active AIGroups Units, targetting the DetectedSet
|
-- First, count the active AIGroups Units, targetting the DetectedSet
|
||||||
local DefenderCount = 0
|
local DefenderCount = 0
|
||||||
|
|
||||||
self:E( "Counting Defenders Engaged for Attacker:" )
|
|
||||||
local DetectedSet = AttackerDetection.Set
|
local DetectedSet = AttackerDetection.Set
|
||||||
DetectedSet:Flush()
|
--DetectedSet:Flush()
|
||||||
|
|
||||||
local DefenderTasks = self:GetDefenderTasks()
|
local DefenderTasks = self:GetDefenderTasks()
|
||||||
for DefenderGroup, DefenderTask in pairs( DefenderTasks ) do
|
for DefenderGroup, DefenderTask in pairs( DefenderTasks ) do
|
||||||
@@ -2610,7 +2612,7 @@ do -- AI_A2A_DISPATCHER
|
|||||||
|
|
||||||
if Cap then
|
if Cap then
|
||||||
|
|
||||||
local Spawn = DefenderSquadron.Spawn[ math.random( 1, #DefenderSquadron.Spawn ) ] -- Functional.Spawn#SPAWN
|
local Spawn = DefenderSquadron.Spawn[ math.random( 1, #DefenderSquadron.Spawn ) ] -- Core.Spawn#SPAWN
|
||||||
local DefenderGrouping = DefenderSquadron.Grouping or self.DefenderDefault.Grouping
|
local DefenderGrouping = DefenderSquadron.Grouping or self.DefenderDefault.Grouping
|
||||||
Spawn:InitGrouping( DefenderGrouping )
|
Spawn:InitGrouping( DefenderGrouping )
|
||||||
|
|
||||||
@@ -2652,7 +2654,7 @@ do -- AI_A2A_DISPATCHER
|
|||||||
|
|
||||||
--- @param #AI_A2A_DISPATCHER self
|
--- @param #AI_A2A_DISPATCHER self
|
||||||
function Fsm:onafterHome( Defender, From, Event, To, Action )
|
function Fsm:onafterHome( Defender, From, Event, To, Action )
|
||||||
self:E({"CAP Home", Defender:GetName()})
|
self:F({"CAP Home", Defender:GetName()})
|
||||||
self:GetParent(self).onafterHome( self, Defender, From, Event, To )
|
self:GetParent(self).onafterHome( self, Defender, From, Event, To )
|
||||||
|
|
||||||
local Dispatcher = self:GetDispatcher() -- #AI_A2A_DISPATCHER
|
local Dispatcher = self:GetDispatcher() -- #AI_A2A_DISPATCHER
|
||||||
@@ -2783,7 +2785,7 @@ do -- AI_A2A_DISPATCHER
|
|||||||
|
|
||||||
while ( DefendersNeeded > 0 ) do
|
while ( DefendersNeeded > 0 ) do
|
||||||
|
|
||||||
local Spawn = DefenderSquadron.Spawn[ math.random( 1, #DefenderSquadron.Spawn ) ] -- Functional.Spawn#SPAWN
|
local Spawn = DefenderSquadron.Spawn[ math.random( 1, #DefenderSquadron.Spawn ) ] -- Core.Spawn#SPAWN
|
||||||
local DefenderGrouping = ( DefenderGrouping < DefendersNeeded ) and DefenderGrouping or DefendersNeeded
|
local DefenderGrouping = ( DefenderGrouping < DefendersNeeded ) and DefenderGrouping or DefendersNeeded
|
||||||
if DefenderGrouping then
|
if DefenderGrouping then
|
||||||
Spawn:InitGrouping( DefenderGrouping )
|
Spawn:InitGrouping( DefenderGrouping )
|
||||||
@@ -2793,7 +2795,7 @@ do -- AI_A2A_DISPATCHER
|
|||||||
|
|
||||||
local TakeoffMethod = self:GetSquadronTakeoff( ClosestDefenderSquadronName )
|
local TakeoffMethod = self:GetSquadronTakeoff( ClosestDefenderSquadronName )
|
||||||
local DefenderGCI = Spawn:SpawnAtAirbase( DefenderSquadron.Airbase, TakeoffMethod, DefenderSquadron.TakeoffAltitude or self.DefenderDefault.TakeoffAltitude ) -- Wrapper.Group#GROUP
|
local DefenderGCI = Spawn:SpawnAtAirbase( DefenderSquadron.Airbase, TakeoffMethod, DefenderSquadron.TakeoffAltitude or self.DefenderDefault.TakeoffAltitude ) -- Wrapper.Group#GROUP
|
||||||
self:E( { GCIDefender = DefenderGCI:GetName() } )
|
self:F( { GCIDefender = DefenderGCI:GetName() } )
|
||||||
|
|
||||||
DefendersNeeded = DefendersNeeded - DefenderGrouping
|
DefendersNeeded = DefendersNeeded - DefenderGrouping
|
||||||
|
|
||||||
@@ -2957,13 +2959,13 @@ do -- AI_A2A_DISPATCHER
|
|||||||
local AIGroup = AIGroup -- Wrapper.Group#GROUP
|
local AIGroup = AIGroup -- Wrapper.Group#GROUP
|
||||||
if not AIGroup:IsAlive() then
|
if not AIGroup:IsAlive() then
|
||||||
local DefenderTaskFsm = self:GetDefenderTaskFsm( AIGroup )
|
local DefenderTaskFsm = self:GetDefenderTaskFsm( AIGroup )
|
||||||
self:E( { Defender = AIGroup:GetName(), DefenderState = DefenderTaskFsm:GetState() } )
|
self:F( { Defender = AIGroup:GetName(), DefenderState = DefenderTaskFsm:GetState() } )
|
||||||
if not DefenderTaskFsm:Is( "Started" ) then
|
if not DefenderTaskFsm:Is( "Started" ) then
|
||||||
self:ClearDefenderTask( AIGroup )
|
self:ClearDefenderTask( AIGroup )
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
if DefenderTask.Target then
|
if DefenderTask.Target then
|
||||||
local AttackerItem = Detection:GetDetectedItem( DefenderTask.Target.Index )
|
local AttackerItem = Detection:GetDetectedItemByIndex( DefenderTask.Target.Index )
|
||||||
if not AttackerItem then
|
if not AttackerItem then
|
||||||
self:F( { "Removing obsolete Target:", DefenderTask.Target.Index } )
|
self:F( { "Removing obsolete Target:", DefenderTask.Target.Index } )
|
||||||
self:ClearDefenderTaskTarget( AIGroup )
|
self:ClearDefenderTaskTarget( AIGroup )
|
||||||
@@ -2991,7 +2993,7 @@ do -- AI_A2A_DISPATCHER
|
|||||||
local DetectedZone = DetectedItem.Zone
|
local DetectedZone = DetectedItem.Zone
|
||||||
|
|
||||||
self:F( { "Target ID", DetectedItem.ItemID } )
|
self:F( { "Target ID", DetectedItem.ItemID } )
|
||||||
DetectedSet:Flush()
|
DetectedSet:Flush( self )
|
||||||
|
|
||||||
local DetectedID = DetectedItem.ID
|
local DetectedID = DetectedItem.ID
|
||||||
local DetectionIndex = DetectedItem.Index
|
local DetectionIndex = DetectedItem.Index
|
||||||
@@ -3007,7 +3009,7 @@ do -- AI_A2A_DISPATCHER
|
|||||||
|
|
||||||
do
|
do
|
||||||
local DefendersMissing, Friendlies = self:EvaluateGCI( DetectedItem )
|
local DefendersMissing, Friendlies = self:EvaluateGCI( DetectedItem )
|
||||||
if DefendersMissing then
|
if DefendersMissing and DefendersMissing > 0 then
|
||||||
self:F( { DefendersMissing = DefendersMissing } )
|
self:F( { DefendersMissing = DefendersMissing } )
|
||||||
self:GCI( DetectedItem, DefendersMissing, Friendlies )
|
self:GCI( DetectedItem, DefendersMissing, Friendlies )
|
||||||
end
|
end
|
||||||
@@ -3056,7 +3058,7 @@ do -- AI_A2A_DISPATCHER
|
|||||||
end
|
end
|
||||||
Report:Add( string.format( "\n - %d Tasks", TaskCount ) )
|
Report:Add( string.format( "\n - %d Tasks", TaskCount ) )
|
||||||
|
|
||||||
self:E( Report:Text( "\n" ) )
|
self:F( Report:Text( "\n" ) )
|
||||||
trigger.action.outText( Report:Text( "\n" ), 25 )
|
trigger.action.outText( Report:Text( "\n" ), 25 )
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -3084,7 +3086,7 @@ do
|
|||||||
for PlayerUnitName, PlayerUnitData in pairs( PlayersNearBy ) do
|
for PlayerUnitName, PlayerUnitData in pairs( PlayersNearBy ) do
|
||||||
local PlayerUnit = PlayerUnitData -- Wrapper.Unit#UNIT
|
local PlayerUnit = PlayerUnitData -- Wrapper.Unit#UNIT
|
||||||
local PlayerName = PlayerUnit:GetPlayerName()
|
local PlayerName = PlayerUnit:GetPlayerName()
|
||||||
--self:E( { PlayerName = PlayerName, PlayerUnit = PlayerUnit } )
|
--self:F( { PlayerName = PlayerName, PlayerUnit = PlayerUnit } )
|
||||||
if PlayerUnit:IsAirPlane() and PlayerName ~= nil then
|
if PlayerUnit:IsAirPlane() and PlayerName ~= nil then
|
||||||
local FriendlyUnitThreatLevel = PlayerUnit:GetThreatLevel()
|
local FriendlyUnitThreatLevel = PlayerUnit:GetThreatLevel()
|
||||||
PlayersCount = PlayersCount + 1
|
PlayersCount = PlayersCount + 1
|
||||||
@@ -3097,7 +3099,7 @@ do
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--self:E( { PlayersCount = PlayersCount } )
|
--self:F( { PlayersCount = PlayersCount } )
|
||||||
|
|
||||||
local PlayerTypesReport = REPORT:New()
|
local PlayerTypesReport = REPORT:New()
|
||||||
|
|
||||||
@@ -3141,7 +3143,7 @@ do
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--self:E( { FriendliesCount = FriendliesCount } )
|
--self:F( { FriendliesCount = FriendliesCount } )
|
||||||
|
|
||||||
local FriendlyTypesReport = REPORT:New()
|
local FriendlyTypesReport = REPORT:New()
|
||||||
|
|
||||||
@@ -3178,7 +3180,7 @@ do
|
|||||||
-- The AI_A2A_GCICAP class is designed to create an automatic air defence system for a coalition setting up GCI and CAP air defenses.
|
-- The AI_A2A_GCICAP class is designed to create an automatic air defence system for a coalition setting up GCI and CAP air defenses.
|
||||||
-- The class derives from @{AI#AI_A2A_DISPATCHER} and thus, all the methods that are defined in the @{AI#AI_A2A_DISPATCHER} class, can be used also in AI\_A2A\_GCICAP.
|
-- The class derives from @{AI#AI_A2A_DISPATCHER} and thus, all the methods that are defined in the @{AI#AI_A2A_DISPATCHER} class, can be used also in AI\_A2A\_GCICAP.
|
||||||
--
|
--
|
||||||
-- ====
|
-- ===
|
||||||
--
|
--
|
||||||
-- # Demo Missions
|
-- # Demo Missions
|
||||||
--
|
--
|
||||||
@@ -3188,7 +3190,7 @@ do
|
|||||||
--
|
--
|
||||||
-- ### [AI\_A2A\_GCICAP for beta testers](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/AID%20-%20AI%20Dispatching)
|
-- ### [AI\_A2A\_GCICAP for beta testers](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/AID%20-%20AI%20Dispatching)
|
||||||
--
|
--
|
||||||
-- ====
|
-- ===
|
||||||
--
|
--
|
||||||
-- # YouTube Channel
|
-- # YouTube Channel
|
||||||
--
|
--
|
||||||
@@ -3218,7 +3220,7 @@ do
|
|||||||
--
|
--
|
||||||
-- In short it is a plug in very flexible and configurable air defence module for DCS World.
|
-- In short it is a plug in very flexible and configurable air defence module for DCS World.
|
||||||
--
|
--
|
||||||
-- ====
|
-- ===
|
||||||
--
|
--
|
||||||
-- # The following actions need to be followed when using AI\_A2A\_GCICAP in your mission:
|
-- # The following actions need to be followed when using AI\_A2A\_GCICAP in your mission:
|
||||||
--
|
--
|
||||||
@@ -3552,21 +3554,22 @@ do
|
|||||||
-- Setup squadrons
|
-- Setup squadrons
|
||||||
|
|
||||||
self:F( { Airbases = AirbaseNames } )
|
self:F( { Airbases = AirbaseNames } )
|
||||||
self.Templates:Flush()
|
|
||||||
|
self:F( "Defining Templates for Airbases ..." )
|
||||||
for AirbaseID, AirbaseName in pairs( AirbaseNames ) do
|
for AirbaseID, AirbaseName in pairs( AirbaseNames ) do
|
||||||
local Airbase = _DATABASE:FindAirbase( AirbaseName ) -- Wrapper.Airbase#AIRBASE
|
local Airbase = _DATABASE:FindAirbase( AirbaseName ) -- Wrapper.Airbase#AIRBASE
|
||||||
local AirbaseName = Airbase:GetName()
|
local AirbaseName = Airbase:GetName()
|
||||||
local AirbaseCoord = Airbase:GetCoordinate()
|
local AirbaseCoord = Airbase:GetCoordinate()
|
||||||
local AirbaseZone = ZONE_RADIUS:New( "Airbase", AirbaseCoord:GetVec2(), 3000 )
|
local AirbaseZone = ZONE_RADIUS:New( "Airbase", AirbaseCoord:GetVec2(), 3000 )
|
||||||
local Templates = nil
|
local Templates = nil
|
||||||
|
self:F( { Airbase = AirbaseName } )
|
||||||
for TemplateID, Template in pairs( self.Templates:GetSet() ) do
|
for TemplateID, Template in pairs( self.Templates:GetSet() ) do
|
||||||
local Template = Template -- Wrapper.Group#GROUP
|
local Template = Template -- Wrapper.Group#GROUP
|
||||||
self:F( { Template = Template:GetName() } )
|
|
||||||
local TemplateCoord = Template:GetCoordinate()
|
local TemplateCoord = Template:GetCoordinate()
|
||||||
if AirbaseZone:IsVec2InZone( TemplateCoord:GetVec2() ) then
|
if AirbaseZone:IsVec2InZone( TemplateCoord:GetVec2() ) then
|
||||||
Templates = Templates or {}
|
Templates = Templates or {}
|
||||||
table.insert( Templates, Template:GetName() )
|
table.insert( Templates, Template:GetName() )
|
||||||
|
self:F( { Template = Template:GetName() } )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if Templates then
|
if Templates then
|
||||||
@@ -3582,11 +3585,13 @@ do
|
|||||||
self.CAPTemplates:FilterPrefixes( CapPrefixes )
|
self.CAPTemplates:FilterPrefixes( CapPrefixes )
|
||||||
self.CAPTemplates:FilterOnce()
|
self.CAPTemplates:FilterOnce()
|
||||||
|
|
||||||
|
self:F( "Setting up CAP ..." )
|
||||||
for CAPID, CAPTemplate in pairs( self.CAPTemplates:GetSet() ) do
|
for CAPID, CAPTemplate in pairs( self.CAPTemplates:GetSet() ) do
|
||||||
local CAPZone = ZONE_POLYGON:New( CAPTemplate:GetName(), CAPTemplate )
|
local CAPZone = ZONE_POLYGON:New( CAPTemplate:GetName(), CAPTemplate )
|
||||||
-- Now find the closest airbase from the ZONE (start or center)
|
-- Now find the closest airbase from the ZONE (start or center)
|
||||||
local AirbaseDistance = 99999999
|
local AirbaseDistance = 99999999
|
||||||
local AirbaseClosest = nil -- Wrapper.Airbase#AIRBASE
|
local AirbaseClosest = nil -- Wrapper.Airbase#AIRBASE
|
||||||
|
self:F( { CAPZoneGroup = CAPID } )
|
||||||
for AirbaseID, AirbaseName in pairs( AirbaseNames ) do
|
for AirbaseID, AirbaseName in pairs( AirbaseNames ) do
|
||||||
local Airbase = _DATABASE:FindAirbase( AirbaseName ) -- Wrapper.Airbase#AIRBASE
|
local Airbase = _DATABASE:FindAirbase( AirbaseName ) -- Wrapper.Airbase#AIRBASE
|
||||||
local AirbaseName = Airbase:GetName()
|
local AirbaseName = Airbase:GetName()
|
||||||
@@ -3594,6 +3599,7 @@ do
|
|||||||
local Squadron = self.DefenderSquadrons[AirbaseName]
|
local Squadron = self.DefenderSquadrons[AirbaseName]
|
||||||
if Squadron then
|
if Squadron then
|
||||||
local Distance = AirbaseCoord:Get2DDistance( CAPZone:GetCoordinate() )
|
local Distance = AirbaseCoord:Get2DDistance( CAPZone:GetCoordinate() )
|
||||||
|
self:F( { AirbaseDistance = Distance } )
|
||||||
if Distance < AirbaseDistance then
|
if Distance < AirbaseDistance then
|
||||||
AirbaseDistance = Distance
|
AirbaseDistance = Distance
|
||||||
AirbaseClosest = Airbase
|
AirbaseClosest = Airbase
|
||||||
@@ -3601,6 +3607,7 @@ do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
if AirbaseClosest then
|
if AirbaseClosest then
|
||||||
|
self:F( { CAPAirbase = AirbaseClosest:GetName() } )
|
||||||
self:SetSquadronCap( AirbaseClosest:GetName(), CAPZone, 6000, 10000, 500, 800, 800, 1200, "RADIO" )
|
self:SetSquadronCap( AirbaseClosest:GetName(), CAPZone, 6000, 10000, 500, 800, 800, 1200, "RADIO" )
|
||||||
self:SetSquadronCapInterval( AirbaseClosest:GetName(), CapLimit, 300, 600, 1 )
|
self:SetSquadronCapInterval( AirbaseClosest:GetName(), CapLimit, 300, 600, 1 )
|
||||||
end
|
end
|
||||||
@@ -3608,11 +3615,14 @@ do
|
|||||||
|
|
||||||
-- Setup GCI.
|
-- Setup GCI.
|
||||||
-- GCI is setup for all Squadrons.
|
-- GCI is setup for all Squadrons.
|
||||||
|
self:F( "Setting up GCI ..." )
|
||||||
for AirbaseID, AirbaseName in pairs( AirbaseNames ) do
|
for AirbaseID, AirbaseName in pairs( AirbaseNames ) do
|
||||||
local Airbase = _DATABASE:FindAirbase( AirbaseName ) -- Wrapper.Airbase#AIRBASE
|
local Airbase = _DATABASE:FindAirbase( AirbaseName ) -- Wrapper.Airbase#AIRBASE
|
||||||
local AirbaseName = Airbase:GetName()
|
local AirbaseName = Airbase:GetName()
|
||||||
local Squadron = self.DefenderSquadrons[AirbaseName]
|
local Squadron = self.DefenderSquadrons[AirbaseName]
|
||||||
|
self:F( { Airbase = AirbaseName } )
|
||||||
if Squadron then
|
if Squadron then
|
||||||
|
self:F( { GCIAirbase = AirbaseName } )
|
||||||
self:SetSquadronGci( AirbaseName, 800, 1200 )
|
self:SetSquadronGci( AirbaseName, 800, 1200 )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,28 +1,16 @@
|
|||||||
--- **AI** -- **Execute Ground Controlled Interception (GCI).**
|
--- **AI** -- (R2.2) - Models the process of Ground Controlled Interception (GCI) for airplanes.
|
||||||
--
|
--
|
||||||
-- 
|
-- This is a class used in the @{AI_A2A_Dispatcher}.
|
||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
-- AI A2A_INTEREPT class makes AI Groups execute an Intercept.
|
-- ### Author: **FlightControl**
|
||||||
--
|
--
|
||||||
-- There are the following types of GCI classes defined:
|
-- ===
|
||||||
--
|
|
||||||
-- * @{#AI_A2A_GCI}: Perform a GCI in a zone.
|
|
||||||
--
|
|
||||||
-- ====
|
|
||||||
--
|
|
||||||
-- ### Author: **Sven Van de Velde (FlightControl)**
|
|
||||||
--
|
|
||||||
-- ### Contributions:
|
|
||||||
--
|
|
||||||
-- ====
|
|
||||||
--
|
--
|
||||||
-- @module AI_A2A_GCI
|
-- @module AI_A2A_GCI
|
||||||
|
|
||||||
|
|
||||||
--BASE:TraceClass("AI_A2A_GCI")
|
|
||||||
|
|
||||||
|
|
||||||
--- @type AI_A2A_GCI
|
--- @type AI_A2A_GCI
|
||||||
-- @extends AI.AI_A2A#AI_A2A
|
-- @extends AI.AI_A2A#AI_A2A
|
||||||
@@ -117,12 +105,12 @@ AI_A2A_GCI = {
|
|||||||
|
|
||||||
--- Creates a new AI_A2A_GCI object
|
--- Creates a new AI_A2A_GCI object
|
||||||
-- @param #AI_A2A_GCI self
|
-- @param #AI_A2A_GCI self
|
||||||
-- @param Wrapper.Group#GROUP AIGroup
|
-- @param Wrapper.Group#GROUP AIIntercept
|
||||||
-- @return #AI_A2A_GCI
|
-- @return #AI_A2A_GCI
|
||||||
function AI_A2A_GCI:New( AIGroup, EngageMinSpeed, EngageMaxSpeed )
|
function AI_A2A_GCI:New( AIIntercept, EngageMinSpeed, EngageMaxSpeed )
|
||||||
|
|
||||||
-- Inherits from BASE
|
-- Inherits from BASE
|
||||||
local self = BASE:Inherit( self, AI_A2A:New( AIGroup ) ) -- #AI_A2A_GCI
|
local self = BASE:Inherit( self, AI_A2A:New( AIIntercept ) ) -- #AI_A2A_GCI
|
||||||
|
|
||||||
self.Accomplished = false
|
self.Accomplished = false
|
||||||
self.Engaging = false
|
self.Engaging = false
|
||||||
@@ -139,7 +127,7 @@ function AI_A2A_GCI:New( AIGroup, EngageMinSpeed, EngageMaxSpeed )
|
|||||||
--- OnBefore Transition Handler for Event Engage.
|
--- OnBefore Transition Handler for Event Engage.
|
||||||
-- @function [parent=#AI_A2A_GCI] OnBeforeEngage
|
-- @function [parent=#AI_A2A_GCI] OnBeforeEngage
|
||||||
-- @param #AI_A2A_GCI self
|
-- @param #AI_A2A_GCI self
|
||||||
-- @param Wrapper.Group#GROUP AIGroup The AIGroup Object managed by the FSM.
|
-- @param Wrapper.Group#GROUP AIIntercept The Group Object managed by the FSM.
|
||||||
-- @param #string From The From State string.
|
-- @param #string From The From State string.
|
||||||
-- @param #string Event The Event string.
|
-- @param #string Event The Event string.
|
||||||
-- @param #string To The To State string.
|
-- @param #string To The To State string.
|
||||||
@@ -148,7 +136,7 @@ function AI_A2A_GCI:New( AIGroup, EngageMinSpeed, EngageMaxSpeed )
|
|||||||
--- OnAfter Transition Handler for Event Engage.
|
--- OnAfter Transition Handler for Event Engage.
|
||||||
-- @function [parent=#AI_A2A_GCI] OnAfterEngage
|
-- @function [parent=#AI_A2A_GCI] OnAfterEngage
|
||||||
-- @param #AI_A2A_GCI self
|
-- @param #AI_A2A_GCI self
|
||||||
-- @param Wrapper.Group#GROUP AIGroup The AIGroup Object managed by the FSM.
|
-- @param Wrapper.Group#GROUP AIIntercept The Group Object managed by the FSM.
|
||||||
-- @param #string From The From State string.
|
-- @param #string From The From State string.
|
||||||
-- @param #string Event The Event string.
|
-- @param #string Event The Event string.
|
||||||
-- @param #string To The To State string.
|
-- @param #string To The To State string.
|
||||||
@@ -165,7 +153,7 @@ function AI_A2A_GCI:New( AIGroup, EngageMinSpeed, EngageMaxSpeed )
|
|||||||
--- OnLeave Transition Handler for State Engaging.
|
--- OnLeave Transition Handler for State Engaging.
|
||||||
-- @function [parent=#AI_A2A_GCI] OnLeaveEngaging
|
-- @function [parent=#AI_A2A_GCI] OnLeaveEngaging
|
||||||
-- @param #AI_A2A_GCI self
|
-- @param #AI_A2A_GCI self
|
||||||
-- @param Wrapper.Group#GROUP AIGroup The AIGroup Object managed by the FSM.
|
-- @param Wrapper.Group#GROUP AIIntercept The Group Object managed by the FSM.
|
||||||
-- @param #string From The From State string.
|
-- @param #string From The From State string.
|
||||||
-- @param #string Event The Event string.
|
-- @param #string Event The Event string.
|
||||||
-- @param #string To The To State string.
|
-- @param #string To The To State string.
|
||||||
@@ -174,7 +162,7 @@ function AI_A2A_GCI:New( AIGroup, EngageMinSpeed, EngageMaxSpeed )
|
|||||||
--- OnEnter Transition Handler for State Engaging.
|
--- OnEnter Transition Handler for State Engaging.
|
||||||
-- @function [parent=#AI_A2A_GCI] OnEnterEngaging
|
-- @function [parent=#AI_A2A_GCI] OnEnterEngaging
|
||||||
-- @param #AI_A2A_GCI self
|
-- @param #AI_A2A_GCI self
|
||||||
-- @param Wrapper.Group#GROUP AIGroup The AIGroup Object managed by the FSM.
|
-- @param Wrapper.Group#GROUP AIIntercept The Group Object managed by the FSM.
|
||||||
-- @param #string From The From State string.
|
-- @param #string From The From State string.
|
||||||
-- @param #string Event The Event string.
|
-- @param #string Event The Event string.
|
||||||
-- @param #string To The To State string.
|
-- @param #string To The To State string.
|
||||||
@@ -184,7 +172,7 @@ function AI_A2A_GCI:New( AIGroup, EngageMinSpeed, EngageMaxSpeed )
|
|||||||
--- OnBefore Transition Handler for Event Fired.
|
--- OnBefore Transition Handler for Event Fired.
|
||||||
-- @function [parent=#AI_A2A_GCI] OnBeforeFired
|
-- @function [parent=#AI_A2A_GCI] OnBeforeFired
|
||||||
-- @param #AI_A2A_GCI self
|
-- @param #AI_A2A_GCI self
|
||||||
-- @param Wrapper.Group#GROUP AIGroup The AIGroup Object managed by the FSM.
|
-- @param Wrapper.Group#GROUP AIIntercept The Group Object managed by the FSM.
|
||||||
-- @param #string From The From State string.
|
-- @param #string From The From State string.
|
||||||
-- @param #string Event The Event string.
|
-- @param #string Event The Event string.
|
||||||
-- @param #string To The To State string.
|
-- @param #string To The To State string.
|
||||||
@@ -193,7 +181,7 @@ function AI_A2A_GCI:New( AIGroup, EngageMinSpeed, EngageMaxSpeed )
|
|||||||
--- OnAfter Transition Handler for Event Fired.
|
--- OnAfter Transition Handler for Event Fired.
|
||||||
-- @function [parent=#AI_A2A_GCI] OnAfterFired
|
-- @function [parent=#AI_A2A_GCI] OnAfterFired
|
||||||
-- @param #AI_A2A_GCI self
|
-- @param #AI_A2A_GCI self
|
||||||
-- @param Wrapper.Group#GROUP AIGroup The AIGroup Object managed by the FSM.
|
-- @param Wrapper.Group#GROUP AIIntercept The Group Object managed by the FSM.
|
||||||
-- @param #string From The From State string.
|
-- @param #string From The From State string.
|
||||||
-- @param #string Event The Event string.
|
-- @param #string Event The Event string.
|
||||||
-- @param #string To The To State string.
|
-- @param #string To The To State string.
|
||||||
@@ -212,7 +200,7 @@ function AI_A2A_GCI:New( AIGroup, EngageMinSpeed, EngageMaxSpeed )
|
|||||||
--- OnBefore Transition Handler for Event Destroy.
|
--- OnBefore Transition Handler for Event Destroy.
|
||||||
-- @function [parent=#AI_A2A_GCI] OnBeforeDestroy
|
-- @function [parent=#AI_A2A_GCI] OnBeforeDestroy
|
||||||
-- @param #AI_A2A_GCI self
|
-- @param #AI_A2A_GCI self
|
||||||
-- @param Wrapper.Group#GROUP AIGroup The AIGroup Object managed by the FSM.
|
-- @param Wrapper.Group#GROUP AIIntercept The Group Object managed by the FSM.
|
||||||
-- @param #string From The From State string.
|
-- @param #string From The From State string.
|
||||||
-- @param #string Event The Event string.
|
-- @param #string Event The Event string.
|
||||||
-- @param #string To The To State string.
|
-- @param #string To The To State string.
|
||||||
@@ -221,7 +209,7 @@ function AI_A2A_GCI:New( AIGroup, EngageMinSpeed, EngageMaxSpeed )
|
|||||||
--- OnAfter Transition Handler for Event Destroy.
|
--- OnAfter Transition Handler for Event Destroy.
|
||||||
-- @function [parent=#AI_A2A_GCI] OnAfterDestroy
|
-- @function [parent=#AI_A2A_GCI] OnAfterDestroy
|
||||||
-- @param #AI_A2A_GCI self
|
-- @param #AI_A2A_GCI self
|
||||||
-- @param Wrapper.Group#GROUP AIGroup The AIGroup Object managed by the FSM.
|
-- @param Wrapper.Group#GROUP AIIntercept The Group Object managed by the FSM.
|
||||||
-- @param #string From The From State string.
|
-- @param #string From The From State string.
|
||||||
-- @param #string Event The Event string.
|
-- @param #string Event The Event string.
|
||||||
-- @param #string To The To State string.
|
-- @param #string To The To State string.
|
||||||
@@ -241,7 +229,7 @@ function AI_A2A_GCI:New( AIGroup, EngageMinSpeed, EngageMaxSpeed )
|
|||||||
--- OnBefore Transition Handler for Event Abort.
|
--- OnBefore Transition Handler for Event Abort.
|
||||||
-- @function [parent=#AI_A2A_GCI] OnBeforeAbort
|
-- @function [parent=#AI_A2A_GCI] OnBeforeAbort
|
||||||
-- @param #AI_A2A_GCI self
|
-- @param #AI_A2A_GCI self
|
||||||
-- @param Wrapper.Group#GROUP AIGroup The AIGroup Object managed by the FSM.
|
-- @param Wrapper.Group#GROUP AIIntercept The Group Object managed by the FSM.
|
||||||
-- @param #string From The From State string.
|
-- @param #string From The From State string.
|
||||||
-- @param #string Event The Event string.
|
-- @param #string Event The Event string.
|
||||||
-- @param #string To The To State string.
|
-- @param #string To The To State string.
|
||||||
@@ -250,7 +238,7 @@ function AI_A2A_GCI:New( AIGroup, EngageMinSpeed, EngageMaxSpeed )
|
|||||||
--- OnAfter Transition Handler for Event Abort.
|
--- OnAfter Transition Handler for Event Abort.
|
||||||
-- @function [parent=#AI_A2A_GCI] OnAfterAbort
|
-- @function [parent=#AI_A2A_GCI] OnAfterAbort
|
||||||
-- @param #AI_A2A_GCI self
|
-- @param #AI_A2A_GCI self
|
||||||
-- @param Wrapper.Group#GROUP AIGroup The AIGroup Object managed by the FSM.
|
-- @param Wrapper.Group#GROUP AIIntercept The Group Object managed by the FSM.
|
||||||
-- @param #string From The From State string.
|
-- @param #string From The From State string.
|
||||||
-- @param #string Event The Event string.
|
-- @param #string Event The Event string.
|
||||||
-- @param #string To The To State string.
|
-- @param #string To The To State string.
|
||||||
@@ -269,7 +257,7 @@ function AI_A2A_GCI:New( AIGroup, EngageMinSpeed, EngageMaxSpeed )
|
|||||||
--- OnBefore Transition Handler for Event Accomplish.
|
--- OnBefore Transition Handler for Event Accomplish.
|
||||||
-- @function [parent=#AI_A2A_GCI] OnBeforeAccomplish
|
-- @function [parent=#AI_A2A_GCI] OnBeforeAccomplish
|
||||||
-- @param #AI_A2A_GCI self
|
-- @param #AI_A2A_GCI self
|
||||||
-- @param Wrapper.Group#GROUP AIGroup The AIGroup Object managed by the FSM.
|
-- @param Wrapper.Group#GROUP AIIntercept The Group Object managed by the FSM.
|
||||||
-- @param #string From The From State string.
|
-- @param #string From The From State string.
|
||||||
-- @param #string Event The Event string.
|
-- @param #string Event The Event string.
|
||||||
-- @param #string To The To State string.
|
-- @param #string To The To State string.
|
||||||
@@ -278,7 +266,7 @@ function AI_A2A_GCI:New( AIGroup, EngageMinSpeed, EngageMaxSpeed )
|
|||||||
--- OnAfter Transition Handler for Event Accomplish.
|
--- OnAfter Transition Handler for Event Accomplish.
|
||||||
-- @function [parent=#AI_A2A_GCI] OnAfterAccomplish
|
-- @function [parent=#AI_A2A_GCI] OnAfterAccomplish
|
||||||
-- @param #AI_A2A_GCI self
|
-- @param #AI_A2A_GCI self
|
||||||
-- @param Wrapper.Group#GROUP AIGroup The AIGroup Object managed by the FSM.
|
-- @param Wrapper.Group#GROUP AIIntercept The Group Object managed by the FSM.
|
||||||
-- @param #string From The From State string.
|
-- @param #string From The From State string.
|
||||||
-- @param #string Event The Event string.
|
-- @param #string Event The Event string.
|
||||||
-- @param #string To The To State string.
|
-- @param #string To The To State string.
|
||||||
@@ -297,13 +285,13 @@ end
|
|||||||
|
|
||||||
--- onafter State Transition for Event Patrol.
|
--- onafter State Transition for Event Patrol.
|
||||||
-- @param #AI_A2A_GCI self
|
-- @param #AI_A2A_GCI self
|
||||||
-- @param Wrapper.Group#GROUP AIGroup The AI Group managed by the FSM.
|
-- @param Wrapper.Group#GROUP AIIntercept The AI Group managed by the FSM.
|
||||||
-- @param #string From The From State string.
|
-- @param #string From The From State string.
|
||||||
-- @param #string Event The Event string.
|
-- @param #string Event The Event string.
|
||||||
-- @param #string To The To State string.
|
-- @param #string To The To State string.
|
||||||
function AI_A2A_GCI:onafterStart( AIGroup, From, Event, To )
|
function AI_A2A_GCI:onafterStart( AIIntercept, From, Event, To )
|
||||||
|
|
||||||
AIGroup:HandleEvent( EVENTS.Takeoff, nil, self )
|
AIIntercept:HandleEvent( EVENTS.Takeoff, nil, self )
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -311,11 +299,11 @@ end
|
|||||||
|
|
||||||
--- onafter State Transition for Event Patrol.
|
--- onafter State Transition for Event Patrol.
|
||||||
-- @param #AI_A2A_GCI self
|
-- @param #AI_A2A_GCI self
|
||||||
-- @param Wrapper.Group#GROUP AIGroup The AI Group managed by the FSM.
|
-- @param Wrapper.Group#GROUP AIIntercept The AI Group managed by the FSM.
|
||||||
-- @param #string From The From State string.
|
-- @param #string From The From State string.
|
||||||
-- @param #string Event The Event string.
|
-- @param #string Event The Event string.
|
||||||
-- @param #string To The To State string.
|
-- @param #string To The To State string.
|
||||||
function AI_A2A_GCI:onafterEngage( AIGroup, From, Event, To )
|
function AI_A2A_GCI:onafterEngage( AIIntercept, From, Event, To )
|
||||||
|
|
||||||
self:HandleEvent( EVENTS.Dead )
|
self:HandleEvent( EVENTS.Dead )
|
||||||
|
|
||||||
@@ -324,24 +312,24 @@ end
|
|||||||
-- todo: need to fix this global function
|
-- todo: need to fix this global function
|
||||||
|
|
||||||
--- @param Wrapper.Group#GROUP AIControllable
|
--- @param Wrapper.Group#GROUP AIControllable
|
||||||
function AI_A2A_GCI.InterceptRoute( AIGroup, Fsm )
|
function AI_A2A_GCI.InterceptRoute( AIIntercept, Fsm )
|
||||||
|
|
||||||
AIGroup:F( { "AI_A2A_GCI.InterceptRoute:", AIGroup:GetName() } )
|
AIIntercept:F( { "AI_A2A_GCI.InterceptRoute:", AIIntercept:GetName() } )
|
||||||
|
|
||||||
if AIGroup:IsAlive() then
|
if AIIntercept:IsAlive() then
|
||||||
Fsm:__Engage( 0.5 )
|
Fsm:__Engage( 0.5 )
|
||||||
|
|
||||||
--local Task = AIGroup:TaskOrbitCircle( 4000, 400 )
|
--local Task = AIIntercept:TaskOrbitCircle( 4000, 400 )
|
||||||
--AIGroup:SetTask( Task )
|
--AIIntercept:SetTask( Task )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--- @param #AI_A2A_GCI self
|
--- @param #AI_A2A_GCI self
|
||||||
-- @param Wrapper.Group#GROUP AIGroup The AIGroup Object managed by the FSM.
|
-- @param Wrapper.Group#GROUP AIIntercept The Group Object managed by the FSM.
|
||||||
-- @param #string From The From State string.
|
-- @param #string From The From State string.
|
||||||
-- @param #string Event The Event string.
|
-- @param #string Event The Event string.
|
||||||
-- @param #string To The To State string.
|
-- @param #string To The To State string.
|
||||||
function AI_A2A_GCI:onbeforeEngage( AIGroup, From, Event, To )
|
function AI_A2A_GCI:onbeforeEngage( AIIntercept, From, Event, To )
|
||||||
|
|
||||||
if self.Accomplished == true then
|
if self.Accomplished == true then
|
||||||
return false
|
return false
|
||||||
@@ -349,25 +337,25 @@ function AI_A2A_GCI:onbeforeEngage( AIGroup, From, Event, To )
|
|||||||
end
|
end
|
||||||
|
|
||||||
--- @param #AI_A2A_GCI self
|
--- @param #AI_A2A_GCI self
|
||||||
-- @param Wrapper.Group#GROUP AIGroup The AI Group managed by the FSM.
|
-- @param Wrapper.Group#GROUP AIIntercept The AI Group managed by the FSM.
|
||||||
-- @param #string From The From State string.
|
-- @param #string From The From State string.
|
||||||
-- @param #string Event The Event string.
|
-- @param #string Event The Event string.
|
||||||
-- @param #string To The To State string.
|
-- @param #string To The To State string.
|
||||||
function AI_A2A_GCI:onafterAbort( AIGroup, From, Event, To )
|
function AI_A2A_GCI:onafterAbort( AIIntercept, From, Event, To )
|
||||||
AIGroup:ClearTasks()
|
AIIntercept:ClearTasks()
|
||||||
self:Return()
|
self:Return()
|
||||||
self:__RTB( 0.5 )
|
self:__RTB( 0.5 )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- @param #AI_A2A_GCI self
|
--- @param #AI_A2A_GCI self
|
||||||
-- @param Wrapper.Group#GROUP AIGroup The AIGroup Object managed by the FSM.
|
-- @param Wrapper.Group#GROUP AIIntercept The GroupGroup managed by the FSM.
|
||||||
-- @param #string From The From State string.
|
-- @param #string From The From State string.
|
||||||
-- @param #string Event The Event string.
|
-- @param #string Event The Event string.
|
||||||
-- @param #string To The To State string.
|
-- @param #string To The To State string.
|
||||||
function AI_A2A_GCI:onafterEngage( AIGroup, From, Event, To, AttackSetUnit )
|
function AI_A2A_GCI:onafterEngage( AIIntercept, From, Event, To, AttackSetUnit )
|
||||||
|
|
||||||
self:F( { AIGroup, From, Event, To, AttackSetUnit} )
|
self:F( { AIIntercept, From, Event, To, AttackSetUnit} )
|
||||||
|
|
||||||
self.AttackSetUnit = AttackSetUnit or self.AttackSetUnit -- Core.Set#SET_UNIT
|
self.AttackSetUnit = AttackSetUnit or self.AttackSetUnit -- Core.Set#SET_UNIT
|
||||||
|
|
||||||
@@ -375,15 +363,15 @@ function AI_A2A_GCI:onafterEngage( AIGroup, From, Event, To, AttackSetUnit )
|
|||||||
|
|
||||||
if FirstAttackUnit and FirstAttackUnit:IsAlive() then
|
if FirstAttackUnit and FirstAttackUnit:IsAlive() then
|
||||||
|
|
||||||
if AIGroup:IsAlive() then
|
if AIIntercept:IsAlive() then
|
||||||
|
|
||||||
local EngageRoute = {}
|
local EngageRoute = {}
|
||||||
|
|
||||||
local CurrentCoord = AIGroup:GetCoordinate()
|
local CurrentCoord = AIIntercept:GetCoordinate()
|
||||||
|
|
||||||
--- Calculate the target route point.
|
--- Calculate the target route point.
|
||||||
|
|
||||||
local CurrentCoord = AIGroup:GetCoordinate()
|
local CurrentCoord = AIIntercept:GetCoordinate()
|
||||||
|
|
||||||
local ToTargetCoord = self.AttackSetUnit:GetFirst():GetCoordinate()
|
local ToTargetCoord = self.AttackSetUnit:GetFirst():GetCoordinate()
|
||||||
self:SetTargetDistance( ToTargetCoord ) -- For RTB status check
|
self:SetTargetDistance( ToTargetCoord ) -- For RTB status check
|
||||||
@@ -412,7 +400,7 @@ function AI_A2A_GCI:onafterEngage( AIGroup, From, Event, To, AttackSetUnit )
|
|||||||
local AttackUnit = AttackUnit -- Wrapper.Unit#UNIT
|
local AttackUnit = AttackUnit -- Wrapper.Unit#UNIT
|
||||||
if AttackUnit:IsAlive() and AttackUnit:IsAir() then
|
if AttackUnit:IsAlive() and AttackUnit:IsAir() then
|
||||||
self:T( { "Intercepting Unit:", AttackUnit:GetName(), AttackUnit:IsAlive(), AttackUnit:IsAir() } )
|
self:T( { "Intercepting Unit:", AttackUnit:GetName(), AttackUnit:IsAlive(), AttackUnit:IsAir() } )
|
||||||
AttackTasks[#AttackTasks+1] = AIGroup:TaskAttackUnit( AttackUnit )
|
AttackTasks[#AttackTasks+1] = AIIntercept:TaskAttackUnit( AttackUnit )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -421,14 +409,14 @@ function AI_A2A_GCI:onafterEngage( AIGroup, From, Event, To, AttackSetUnit )
|
|||||||
self:Return()
|
self:Return()
|
||||||
self:__RTB( 0.5 )
|
self:__RTB( 0.5 )
|
||||||
else
|
else
|
||||||
AIGroup:OptionROEOpenFire()
|
AIIntercept:OptionROEOpenFire()
|
||||||
AIGroup:OptionROTPassiveDefense()
|
AIIntercept:OptionROTEvadeFire()
|
||||||
|
|
||||||
AttackTasks[#AttackTasks+1] = AIGroup:TaskFunction( "AI_A2A_GCI.InterceptRoute", self )
|
AttackTasks[#AttackTasks+1] = AIIntercept:TaskFunction( "AI_A2A_GCI.InterceptRoute", self )
|
||||||
EngageRoute[#EngageRoute].task = AIGroup:TaskCombo( AttackTasks )
|
EngageRoute[#EngageRoute].task = AIIntercept:TaskCombo( AttackTasks )
|
||||||
end
|
end
|
||||||
|
|
||||||
AIGroup:Route( EngageRoute, 0.5 )
|
AIIntercept:Route( EngageRoute, 0.5 )
|
||||||
|
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
@@ -439,22 +427,22 @@ function AI_A2A_GCI:onafterEngage( AIGroup, From, Event, To, AttackSetUnit )
|
|||||||
end
|
end
|
||||||
|
|
||||||
--- @param #AI_A2A_GCI self
|
--- @param #AI_A2A_GCI self
|
||||||
-- @param Wrapper.Group#GROUP AIGroup The AIGroup Object managed by the FSM.
|
-- @param Wrapper.Group#GROUP AIIntercept The Group Object managed by the FSM.
|
||||||
-- @param #string From The From State string.
|
-- @param #string From The From State string.
|
||||||
-- @param #string Event The Event string.
|
-- @param #string Event The Event string.
|
||||||
-- @param #string To The To State string.
|
-- @param #string To The To State string.
|
||||||
function AI_A2A_GCI:onafterAccomplish( AIGroup, From, Event, To )
|
function AI_A2A_GCI:onafterAccomplish( AIIntercept, From, Event, To )
|
||||||
self.Accomplished = true
|
self.Accomplished = true
|
||||||
self:SetDetectionOff()
|
self:SetDetectionOff()
|
||||||
end
|
end
|
||||||
|
|
||||||
--- @param #AI_A2A_GCI self
|
--- @param #AI_A2A_GCI self
|
||||||
-- @param Wrapper.Group#GROUP AIGroup The AIGroup Object managed by the FSM.
|
-- @param Wrapper.Group#GROUP AIIntercept The Group Object managed by the FSM.
|
||||||
-- @param #string From The From State string.
|
-- @param #string From The From State string.
|
||||||
-- @param #string Event The Event string.
|
-- @param #string Event The Event string.
|
||||||
-- @param #string To The To State string.
|
-- @param #string To The To State string.
|
||||||
-- @param Core.Event#EVENTDATA EventData
|
-- @param Core.Event#EVENTDATA EventData
|
||||||
function AI_A2A_GCI:onafterDestroy( AIGroup, From, Event, To, EventData )
|
function AI_A2A_GCI:onafterDestroy( AIIntercept, From, Event, To, EventData )
|
||||||
|
|
||||||
if EventData.IniUnit then
|
if EventData.IniUnit then
|
||||||
self.AttackUnits[EventData.IniUnit] = nil
|
self.AttackUnits[EventData.IniUnit] = nil
|
||||||
|
|||||||
@@ -1,40 +1,12 @@
|
|||||||
--- **AI** -- **Air Patrolling or Staging.**
|
--- **AI** -- (R2.2) - Models the process of air patrol of airplanes.
|
||||||
--
|
--
|
||||||
-- 
|
-- This is a class used in the @{AI_A2A_Dispatcher}.
|
||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
-- AI PATROL classes makes AI Controllables execute an Patrol.
|
-- ### Author: **FlightControl**
|
||||||
--
|
--
|
||||||
-- There are the following types of PATROL classes defined:
|
-- ===
|
||||||
--
|
|
||||||
-- * @{#AI_A2A_PATROL}: Perform a PATROL in a zone.
|
|
||||||
--
|
|
||||||
-- ====
|
|
||||||
--
|
|
||||||
-- # Demo Missions
|
|
||||||
--
|
|
||||||
-- ### [AI_PATROL Demo Missions source code](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master-release/PAT%20-%20Patrolling)
|
|
||||||
--
|
|
||||||
-- ### [AI_PATROL Demo Missions, only for beta testers](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/PAT%20-%20Patrolling)
|
|
||||||
--
|
|
||||||
-- ### [ALL Demo Missions pack of the last release](https://github.com/FlightControl-Master/MOOSE_MISSIONS/releases)
|
|
||||||
--
|
|
||||||
-- ====
|
|
||||||
--
|
|
||||||
-- # YouTube Channel
|
|
||||||
--
|
|
||||||
-- ### [AI_PATROL YouTube Channel](https://www.youtube.com/playlist?list=PL7ZUrU4zZUl35HvYZKA6G22WMt7iI3zky)
|
|
||||||
--
|
|
||||||
-- ====
|
|
||||||
--
|
|
||||||
-- ### Author: **Sven Van de Velde (FlightControl)**
|
|
||||||
-- ### 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.
|
|
||||||
--
|
|
||||||
-- ====
|
|
||||||
--
|
--
|
||||||
-- @module AI_A2A_Patrol
|
-- @module AI_A2A_Patrol
|
||||||
|
|
||||||
@@ -44,7 +16,7 @@
|
|||||||
|
|
||||||
--- # AI_A2A_PATROL class, extends @{Fsm#FSM_CONTROLLABLE}
|
--- # AI_A2A_PATROL class, extends @{Fsm#FSM_CONTROLLABLE}
|
||||||
--
|
--
|
||||||
-- The AI_A2A_PATROL class implements the core functions to patrol a @{Zone} by an AI @{Controllable} or @{Group}.
|
-- The AI_A2A_PATROL class implements the core functions to patrol a @{Zone} by an AI @{Group} or @{Group}.
|
||||||
--
|
--
|
||||||
-- 
|
-- 
|
||||||
--
|
--
|
||||||
@@ -139,7 +111,7 @@
|
|||||||
--
|
--
|
||||||
-- ## 7. Manage "damage" behaviour of the AI in the AI_A2A_PATROL
|
-- ## 7. Manage "damage" behaviour of the AI in the AI_A2A_PATROL
|
||||||
--
|
--
|
||||||
-- When the AI is damaged, it is required that a new AIControllable is started. However, damage cannon be foreseen early on.
|
-- When the AI is damaged, it is required that a new Patrol 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).
|
-- Therefore, when the damage treshold is reached, the AI will return immediately to the home base (RTB).
|
||||||
-- Use the method @{#AI_A2A_PATROL.ManageDamage}() to have this proces in place.
|
-- Use the method @{#AI_A2A_PATROL.ManageDamage}() to have this proces in place.
|
||||||
--
|
--
|
||||||
@@ -152,23 +124,23 @@ AI_A2A_PATROL = {
|
|||||||
|
|
||||||
--- Creates a new AI_A2A_PATROL object
|
--- Creates a new AI_A2A_PATROL object
|
||||||
-- @param #AI_A2A_PATROL self
|
-- @param #AI_A2A_PATROL self
|
||||||
-- @param Wrapper.Group#GROUP AIGroup
|
-- @param Wrapper.Group#GROUP AIPatrol
|
||||||
-- @param Core.Zone#ZONE_BASE PatrolZone The @{Zone} where the patrol needs to be executed.
|
-- @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 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#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 PatrolMinSpeed The minimum speed of the @{Group} in km/h.
|
||||||
-- @param Dcs.DCSTypes#Speed PatrolMaxSpeed The maximum speed of the @{Controllable} in km/h.
|
-- @param Dcs.DCSTypes#Speed PatrolMaxSpeed The maximum speed of the @{Group} in km/h.
|
||||||
-- @param Dcs.DCSTypes#AltitudeType PatrolAltType The altitude type ("RADIO"=="AGL", "BARO"=="ASL"). Defaults to RADIO
|
-- @param Dcs.DCSTypes#AltitudeType PatrolAltType The altitude type ("RADIO"=="AGL", "BARO"=="ASL"). Defaults to RADIO
|
||||||
-- @return #AI_A2A_PATROL self
|
-- @return #AI_A2A_PATROL self
|
||||||
-- @usage
|
-- @usage
|
||||||
-- -- Define a new AI_A2A_PATROL Object. This PatrolArea will patrol an AIControllable within PatrolZone between 3000 and 6000 meters, with a variying speed between 600 and 900 km/h.
|
-- -- Define a new AI_A2A_PATROL Object. This PatrolArea will patrol a Group within PatrolZone between 3000 and 6000 meters, with a variying speed between 600 and 900 km/h.
|
||||||
-- PatrolZone = ZONE:New( 'PatrolZone' )
|
-- PatrolZone = ZONE:New( 'PatrolZone' )
|
||||||
-- PatrolSpawn = SPAWN:New( 'Patrol Group' )
|
-- PatrolSpawn = SPAWN:New( 'Patrol Group' )
|
||||||
-- PatrolArea = AI_A2A_PATROL:New( PatrolZone, 3000, 6000, 600, 900 )
|
-- PatrolArea = AI_A2A_PATROL:New( PatrolZone, 3000, 6000, 600, 900 )
|
||||||
function AI_A2A_PATROL:New( AIGroup, PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed, PatrolAltType )
|
function AI_A2A_PATROL:New( AIPatrol, PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed, PatrolAltType )
|
||||||
|
|
||||||
-- Inherits from BASE
|
-- Inherits from BASE
|
||||||
local self = BASE:Inherit( self, AI_A2A:New( AIGroup ) ) -- #AI_A2A_PATROL
|
local self = BASE:Inherit( self, AI_A2A:New( AIPatrol ) ) -- #AI_A2A_PATROL
|
||||||
|
|
||||||
self.PatrolZone = PatrolZone
|
self.PatrolZone = PatrolZone
|
||||||
self.PatrolFloorAltitude = PatrolFloorAltitude
|
self.PatrolFloorAltitude = PatrolFloorAltitude
|
||||||
@@ -184,7 +156,7 @@ function AI_A2A_PATROL:New( AIGroup, PatrolZone, PatrolFloorAltitude, PatrolCeil
|
|||||||
--- OnBefore Transition Handler for Event Patrol.
|
--- OnBefore Transition Handler for Event Patrol.
|
||||||
-- @function [parent=#AI_A2A_PATROL] OnBeforePatrol
|
-- @function [parent=#AI_A2A_PATROL] OnBeforePatrol
|
||||||
-- @param #AI_A2A_PATROL self
|
-- @param #AI_A2A_PATROL self
|
||||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
-- @param Wrapper.Group#GROUP AIPatrol The Group Object managed by the FSM.
|
||||||
-- @param #string From The From State string.
|
-- @param #string From The From State string.
|
||||||
-- @param #string Event The Event string.
|
-- @param #string Event The Event string.
|
||||||
-- @param #string To The To State string.
|
-- @param #string To The To State string.
|
||||||
@@ -193,7 +165,7 @@ function AI_A2A_PATROL:New( AIGroup, PatrolZone, PatrolFloorAltitude, PatrolCeil
|
|||||||
--- OnAfter Transition Handler for Event Patrol.
|
--- OnAfter Transition Handler for Event Patrol.
|
||||||
-- @function [parent=#AI_A2A_PATROL] OnAfterPatrol
|
-- @function [parent=#AI_A2A_PATROL] OnAfterPatrol
|
||||||
-- @param #AI_A2A_PATROL self
|
-- @param #AI_A2A_PATROL self
|
||||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
-- @param Wrapper.Group#GROUP AIPatrol The Group Object managed by the FSM.
|
||||||
-- @param #string From The From State string.
|
-- @param #string From The From State string.
|
||||||
-- @param #string Event The Event string.
|
-- @param #string Event The Event string.
|
||||||
-- @param #string To The To State string.
|
-- @param #string To The To State string.
|
||||||
@@ -210,7 +182,7 @@ function AI_A2A_PATROL:New( AIGroup, PatrolZone, PatrolFloorAltitude, PatrolCeil
|
|||||||
--- OnLeave Transition Handler for State Patrolling.
|
--- OnLeave Transition Handler for State Patrolling.
|
||||||
-- @function [parent=#AI_A2A_PATROL] OnLeavePatrolling
|
-- @function [parent=#AI_A2A_PATROL] OnLeavePatrolling
|
||||||
-- @param #AI_A2A_PATROL self
|
-- @param #AI_A2A_PATROL self
|
||||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
-- @param Wrapper.Group#GROUP AIPatrol The Group Object managed by the FSM.
|
||||||
-- @param #string From The From State string.
|
-- @param #string From The From State string.
|
||||||
-- @param #string Event The Event string.
|
-- @param #string Event The Event string.
|
||||||
-- @param #string To The To State string.
|
-- @param #string To The To State string.
|
||||||
@@ -219,7 +191,7 @@ function AI_A2A_PATROL:New( AIGroup, PatrolZone, PatrolFloorAltitude, PatrolCeil
|
|||||||
--- OnEnter Transition Handler for State Patrolling.
|
--- OnEnter Transition Handler for State Patrolling.
|
||||||
-- @function [parent=#AI_A2A_PATROL] OnEnterPatrolling
|
-- @function [parent=#AI_A2A_PATROL] OnEnterPatrolling
|
||||||
-- @param #AI_A2A_PATROL self
|
-- @param #AI_A2A_PATROL self
|
||||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
-- @param Wrapper.Group#GROUP AIPatrol The Group Object managed by the FSM.
|
||||||
-- @param #string From The From State string.
|
-- @param #string From The From State string.
|
||||||
-- @param #string Event The Event string.
|
-- @param #string Event The Event string.
|
||||||
-- @param #string To The To State string.
|
-- @param #string To The To State string.
|
||||||
@@ -229,7 +201,7 @@ function AI_A2A_PATROL:New( AIGroup, PatrolZone, PatrolFloorAltitude, PatrolCeil
|
|||||||
--- OnBefore Transition Handler for Event Route.
|
--- OnBefore Transition Handler for Event Route.
|
||||||
-- @function [parent=#AI_A2A_PATROL] OnBeforeRoute
|
-- @function [parent=#AI_A2A_PATROL] OnBeforeRoute
|
||||||
-- @param #AI_A2A_PATROL self
|
-- @param #AI_A2A_PATROL self
|
||||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
-- @param Wrapper.Group#GROUP AIPatrol The Group Object managed by the FSM.
|
||||||
-- @param #string From The From State string.
|
-- @param #string From The From State string.
|
||||||
-- @param #string Event The Event string.
|
-- @param #string Event The Event string.
|
||||||
-- @param #string To The To State string.
|
-- @param #string To The To State string.
|
||||||
@@ -238,7 +210,7 @@ function AI_A2A_PATROL:New( AIGroup, PatrolZone, PatrolFloorAltitude, PatrolCeil
|
|||||||
--- OnAfter Transition Handler for Event Route.
|
--- OnAfter Transition Handler for Event Route.
|
||||||
-- @function [parent=#AI_A2A_PATROL] OnAfterRoute
|
-- @function [parent=#AI_A2A_PATROL] OnAfterRoute
|
||||||
-- @param #AI_A2A_PATROL self
|
-- @param #AI_A2A_PATROL self
|
||||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
-- @param Wrapper.Group#GROUP AIPatrol The Group Object managed by the FSM.
|
||||||
-- @param #string From The From State string.
|
-- @param #string From The From State string.
|
||||||
-- @param #string Event The Event string.
|
-- @param #string Event The Event string.
|
||||||
-- @param #string To The To State string.
|
-- @param #string To The To State string.
|
||||||
@@ -264,8 +236,8 @@ end
|
|||||||
|
|
||||||
--- Sets (modifies) the minimum and maximum speed of the patrol.
|
--- Sets (modifies) the minimum and maximum speed of the patrol.
|
||||||
-- @param #AI_A2A_PATROL self
|
-- @param #AI_A2A_PATROL self
|
||||||
-- @param Dcs.DCSTypes#Speed PatrolMinSpeed The minimum speed of the @{Controllable} in km/h.
|
-- @param Dcs.DCSTypes#Speed PatrolMinSpeed The minimum speed of the @{Group} in km/h.
|
||||||
-- @param Dcs.DCSTypes#Speed PatrolMaxSpeed The maximum speed of the @{Controllable} in km/h.
|
-- @param Dcs.DCSTypes#Speed PatrolMaxSpeed The maximum speed of the @{Group} in km/h.
|
||||||
-- @return #AI_A2A_PATROL self
|
-- @return #AI_A2A_PATROL self
|
||||||
function AI_A2A_PATROL:SetSpeed( PatrolMinSpeed, PatrolMaxSpeed )
|
function AI_A2A_PATROL:SetSpeed( PatrolMinSpeed, PatrolMaxSpeed )
|
||||||
self:F2( { PatrolMinSpeed, PatrolMaxSpeed } )
|
self:F2( { PatrolMinSpeed, PatrolMaxSpeed } )
|
||||||
@@ -292,20 +264,19 @@ end
|
|||||||
--- Defines a new patrol route using the @{Process_PatrolZone} parameters and settings.
|
--- Defines a new patrol route using the @{Process_PatrolZone} parameters and settings.
|
||||||
-- @param #AI_A2A_PATROL self
|
-- @param #AI_A2A_PATROL self
|
||||||
-- @return #AI_A2A_PATROL self
|
-- @return #AI_A2A_PATROL self
|
||||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
|
-- @param Wrapper.Group#GROUP AIPatrol The Group Object managed by the FSM.
|
||||||
-- @param #string From The From State string.
|
-- @param #string From The From State string.
|
||||||
-- @param #string Event The Event string.
|
-- @param #string Event The Event string.
|
||||||
-- @param #string To The To State string.
|
-- @param #string To The To State string.
|
||||||
function AI_A2A_PATROL:onafterPatrol( Controllable, From, Event, To )
|
function AI_A2A_PATROL:onafterPatrol( AIPatrol, From, Event, To )
|
||||||
self:F2()
|
self:F2()
|
||||||
|
|
||||||
self:ClearTargetDistance()
|
self:ClearTargetDistance()
|
||||||
|
|
||||||
self:__Route( 1 )
|
self:__Route( 1 )
|
||||||
|
|
||||||
self.Controllable:OnReSpawn(
|
AIPatrol:OnReSpawn(
|
||||||
function( PatrolGroup )
|
function( PatrolGroup )
|
||||||
self:E( "ReSpawn" )
|
|
||||||
self:__Reset( 1 )
|
self:__Reset( 1 )
|
||||||
self:__Route( 5 )
|
self:__Route( 5 )
|
||||||
end
|
end
|
||||||
@@ -314,14 +285,14 @@ end
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
--- @param Wrapper.Group#GROUP AIGroup
|
--- @param Wrapper.Group#GROUP AIPatrol
|
||||||
-- This statis method is called from the route path within the last task at the last waaypoint of the Controllable.
|
-- This statis method is called from the route path within the last task at the last waaypoint of the AIPatrol.
|
||||||
-- Note that this method is required, as triggers the next route when patrolling for the Controllable.
|
-- Note that this method is required, as triggers the next route when patrolling for the AIPatrol.
|
||||||
function AI_A2A_PATROL.PatrolRoute( AIGroup, Fsm )
|
function AI_A2A_PATROL.PatrolRoute( AIPatrol, Fsm )
|
||||||
|
|
||||||
AIGroup:F( { "AI_A2A_PATROL.PatrolRoute:", AIGroup:GetName() } )
|
AIPatrol:F( { "AI_A2A_PATROL.PatrolRoute:", AIPatrol:GetName() } )
|
||||||
|
|
||||||
if AIGroup:IsAlive() then
|
if AIPatrol:IsAlive() then
|
||||||
Fsm:Route()
|
Fsm:Route()
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -330,11 +301,11 @@ end
|
|||||||
|
|
||||||
--- Defines a new patrol route using the @{Process_PatrolZone} parameters and settings.
|
--- Defines a new patrol route using the @{Process_PatrolZone} parameters and settings.
|
||||||
-- @param #AI_A2A_PATROL self
|
-- @param #AI_A2A_PATROL self
|
||||||
-- @param Wrapper.Group#GROUP AIGroup The AIGroup managed by the FSM.
|
-- @param Wrapper.Group#GROUP AIPatrol The Group managed by the FSM.
|
||||||
-- @param #string From The From State string.
|
-- @param #string From The From State string.
|
||||||
-- @param #string Event The Event string.
|
-- @param #string Event The Event string.
|
||||||
-- @param #string To The To State string.
|
-- @param #string To The To State string.
|
||||||
function AI_A2A_PATROL:onafterRoute( AIGroup, From, Event, To )
|
function AI_A2A_PATROL:onafterRoute( AIPatrol, From, Event, To )
|
||||||
|
|
||||||
self:F2()
|
self:F2()
|
||||||
|
|
||||||
@@ -344,13 +315,13 @@ function AI_A2A_PATROL:onafterRoute( AIGroup, From, Event, To )
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
if AIGroup:IsAlive() then
|
if AIPatrol:IsAlive() then
|
||||||
|
|
||||||
local PatrolRoute = {}
|
local PatrolRoute = {}
|
||||||
|
|
||||||
--- Calculate the target route point.
|
--- Calculate the target route point.
|
||||||
|
|
||||||
local CurrentCoord = AIGroup:GetCoordinate()
|
local CurrentCoord = AIPatrol:GetCoordinate()
|
||||||
|
|
||||||
local ToTargetCoord = self.PatrolZone:GetRandomPointVec2()
|
local ToTargetCoord = self.PatrolZone:GetRandomPointVec2()
|
||||||
ToTargetCoord:SetAlt( math.random( self.PatrolFloorAltitude, self.PatrolCeilingAltitude ) )
|
ToTargetCoord:SetAlt( math.random( self.PatrolFloorAltitude, self.PatrolCeilingAltitude ) )
|
||||||
@@ -371,23 +342,23 @@ function AI_A2A_PATROL:onafterRoute( AIGroup, From, Event, To )
|
|||||||
PatrolRoute[#PatrolRoute+1] = ToPatrolRoutePoint
|
PatrolRoute[#PatrolRoute+1] = ToPatrolRoutePoint
|
||||||
|
|
||||||
local Tasks = {}
|
local Tasks = {}
|
||||||
Tasks[#Tasks+1] = AIGroup:TaskFunction( "AI_A2A_PATROL.PatrolRoute", self )
|
Tasks[#Tasks+1] = AIPatrol:TaskFunction( "AI_A2A_PATROL.PatrolRoute", self )
|
||||||
PatrolRoute[#PatrolRoute].task = AIGroup:TaskCombo( Tasks )
|
PatrolRoute[#PatrolRoute].task = AIPatrol:TaskCombo( Tasks )
|
||||||
|
|
||||||
AIGroup:OptionROEReturnFire()
|
AIPatrol:OptionROEReturnFire()
|
||||||
AIGroup:OptionROTPassiveDefense()
|
AIPatrol:OptionROTEvadeFire()
|
||||||
|
|
||||||
AIGroup:Route( PatrolRoute, 0.5 )
|
AIPatrol:Route( PatrolRoute, 0.5 )
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--- @param Wrapper.Group#GROUP AIGroup
|
--- @param Wrapper.Group#GROUP AIPatrol
|
||||||
function AI_A2A_PATROL.Resume( AIGroup )
|
function AI_A2A_PATROL.Resume( AIPatrol )
|
||||||
|
|
||||||
AIGroup:F( { "AI_A2A_PATROL.Resume:", AIGroup:GetName() } )
|
AIPatrol:F( { "AI_A2A_PATROL.Resume:", AIPatrol:GetName() } )
|
||||||
if AIGroup:IsAlive() then
|
if AIPatrol:IsAlive() then
|
||||||
local _AI_A2A = AIGroup:GetState( AIGroup, "AI_A2A" ) -- #AI_A2A
|
local _AI_A2A = AIPatrol:GetState( AIPatrol, "AI_A2A" ) -- #AI_A2A
|
||||||
_AI_A2A:__Reset( 1 )
|
_AI_A2A:__Reset( 1 )
|
||||||
_AI_A2A:__Route( 5 )
|
_AI_A2A:__Route( 5 )
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,40 +1,25 @@
|
|||||||
--- **AI** -- **Provide Battlefield Air Interdiction (bombing).**
|
--- **AI** -- (R2.1) - Manages the independent process of Battlefield Air Interdiction (bombing) for airplanes.
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
--
|
--
|
||||||
-- 
|
-- 
|
||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
-- AI_BAI classes makes AI Controllables execute bombing tasks.
|
-- ### [Demo Missions](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/BAI%20-%20Battlefield%20Air%20Interdiction)
|
||||||
--
|
--
|
||||||
-- There are the following types of BAI classes defined:
|
-- ===
|
||||||
--
|
--
|
||||||
-- * @{#AI_BAI_ZONE}: Perform a BAI in a zone.
|
-- ### [YouTube Playlist]()
|
||||||
--
|
|
||||||
-- ====
|
|
||||||
--
|
--
|
||||||
-- # Demo Missions
|
-- ===
|
||||||
--
|
|
||||||
-- ### [AI_BAI Demo Missions source code](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master-release/BOMB%20-%20Close%20Air%20Support)
|
|
||||||
--
|
|
||||||
-- ### [AI_BAI Demo Missions, only for beta testers](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/BOMB%20-%20Close%20Air%20Support)
|
|
||||||
--
|
|
||||||
-- ### [ALL Demo Missions pack of the last release](https://github.com/FlightControl-Master/MOOSE_MISSIONS/releases)
|
|
||||||
--
|
|
||||||
-- ====
|
|
||||||
--
|
|
||||||
-- # YouTube Channel
|
|
||||||
--
|
|
||||||
-- ### [AI_BAI YouTube Channel](https://www.youtube.com/playlist?list=PL7ZUrU4zZUl3JBO1WDqqpyYRRmIkR2ir2)
|
|
||||||
--
|
|
||||||
-- ====
|
|
||||||
--
|
|
||||||
-- ### Author: **Sven Van de Velde (FlightControl)**
|
|
||||||
--
|
--
|
||||||
|
-- ### Author: **FlightControl**
|
||||||
-- ### Contributions:
|
-- ### Contributions:
|
||||||
--
|
--
|
||||||
-- * **[Gunterlund](http://forums.eagle.ru:8080/member.php?u=75036)**: Test case revision.
|
-- * **[Gunterlund](http://forums.eagle.ru:8080/member.php?u=75036)**: Test case revision.
|
||||||
--
|
--
|
||||||
-- ====
|
-- ===
|
||||||
--
|
--
|
||||||
-- @module AI_Bai
|
-- @module AI_Bai
|
||||||
|
|
||||||
|
|||||||
@@ -1,39 +1,31 @@
|
|||||||
--- **AI** -- **AI Balancing will replace in multi player missions
|
--- **AI** -- (2.1) - Balance player slots with AI to create an engaging simulation environment, independent of the amount of players.
|
||||||
-- 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.**
|
-- ===
|
||||||
--
|
--
|
||||||
-- 
|
-- 
|
||||||
--
|
|
||||||
-- ====
|
|
||||||
--
|
--
|
||||||
-- # Demo Missions
|
-- ===
|
||||||
--
|
--
|
||||||
-- ### [AI_BALANCER Demo Missions source code](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master-release/AIB%20-%20AI%20Balancing)
|
-- ### [Demo Missions](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master-release/AIB%20-%20AI%20Balancing)
|
||||||
--
|
--
|
||||||
-- ### [AI_BALANCER Demo Missions, only for beta testers](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/AIB%20-%20AI%20Balancing)
|
-- ===
|
||||||
--
|
|
||||||
-- ### [ALL Demo Missions pack of the last release](https://github.com/FlightControl-Master/MOOSE_MISSIONS/releases)
|
|
||||||
--
|
--
|
||||||
-- ====
|
-- ### [YouTube Playlist](https://www.youtube.com/playlist?list=PL7ZUrU4zZUl2CJVIrL1TdAumuVS8n64B7)
|
||||||
--
|
--
|
||||||
-- # YouTube Channel
|
-- ===
|
||||||
--
|
--
|
||||||
-- ### [AI_BALANCER YouTube Channel](https://www.youtube.com/playlist?list=PL7ZUrU4zZUl2CJVIrL1TdAumuVS8n64B7)
|
-- ### Author: **FlightControl**
|
||||||
--
|
|
||||||
-- ====
|
|
||||||
--
|
|
||||||
-- ### Author: **Sven Van de Velde (FlightControl)**
|
|
||||||
-- ### 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 :-)
|
-- * **[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 :-)
|
||||||
--
|
--
|
||||||
-- ====
|
-- ===
|
||||||
--
|
--
|
||||||
-- @module AI_Balancer
|
-- @module AI_Balancer
|
||||||
|
|
||||||
--- @type AI_BALANCER
|
--- @type AI_BALANCER
|
||||||
-- @field Core.Set#SET_CLIENT SetClient
|
-- @field Core.Set#SET_CLIENT SetClient
|
||||||
-- @field Functional.Spawn#SPAWN SpawnAI
|
-- @field Core.Spawn#SPAWN SpawnAI
|
||||||
-- @field Wrapper.Group#GROUP Test
|
-- @field Wrapper.Group#GROUP Test
|
||||||
-- @extends Core.Fsm#FSM_SET
|
-- @extends Core.Fsm#FSM_SET
|
||||||
|
|
||||||
@@ -106,7 +98,7 @@ AI_BALANCER = {
|
|||||||
--- Creates a new AI_BALANCER object
|
--- Creates a new AI_BALANCER object
|
||||||
-- @param #AI_BALANCER self
|
-- @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 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.
|
-- @param Core.Spawn#SPAWN SpawnAI The default Spawn object to spawn new AI Groups when needed.
|
||||||
-- @return #AI_BALANCER
|
-- @return #AI_BALANCER
|
||||||
function AI_BALANCER:New( SetClient, SpawnAI )
|
function AI_BALANCER:New( SetClient, SpawnAI )
|
||||||
|
|
||||||
@@ -178,9 +170,10 @@ function AI_BALANCER:onenterSpawning( SetGroup, From, Event, To, ClientName )
|
|||||||
-- OK, Spawn a new group from the default SpawnAI object provided.
|
-- OK, Spawn a new group from the default SpawnAI object provided.
|
||||||
local AIGroup = self.SpawnAI:Spawn() -- Wrapper.Group#GROUP
|
local AIGroup = self.SpawnAI:Spawn() -- Wrapper.Group#GROUP
|
||||||
if AIGroup then
|
if AIGroup then
|
||||||
AIGroup:E( "Spawning new AIGroup" )
|
AIGroup:T( { "Spawning new AIGroup", ClientName = ClientName } )
|
||||||
--TODO: need to rework UnitName thing ...
|
--TODO: need to rework UnitName thing ...
|
||||||
|
|
||||||
|
SetGroup:Remove( ClientName ) -- Ensure that the previously allocated AIGroup to ClientName is removed in the Set.
|
||||||
SetGroup:Add( ClientName, AIGroup )
|
SetGroup:Add( ClientName, AIGroup )
|
||||||
self.SpawnQueue[ClientName] = nil
|
self.SpawnQueue[ClientName] = nil
|
||||||
|
|
||||||
@@ -196,9 +189,9 @@ end
|
|||||||
function AI_BALANCER:onenterDestroying( SetGroup, From, Event, To, ClientName, AIGroup )
|
function AI_BALANCER:onenterDestroying( SetGroup, From, Event, To, ClientName, AIGroup )
|
||||||
|
|
||||||
AIGroup:Destroy()
|
AIGroup:Destroy()
|
||||||
SetGroup:Flush()
|
SetGroup:Flush( self )
|
||||||
SetGroup:Remove( ClientName )
|
SetGroup:Remove( ClientName )
|
||||||
SetGroup:Flush()
|
SetGroup:Flush( self )
|
||||||
end
|
end
|
||||||
|
|
||||||
--- @param #AI_BALANCER self
|
--- @param #AI_BALANCER self
|
||||||
@@ -239,7 +232,8 @@ function AI_BALANCER:onenterMonitoring( SetGroup )
|
|||||||
self:T3(Client.ClientName)
|
self:T3(Client.ClientName)
|
||||||
|
|
||||||
local AIGroup = self.Set:Get( Client.UnitName ) -- Wrapper.Group#GROUP
|
local AIGroup = self.Set:Get( Client.UnitName ) -- Wrapper.Group#GROUP
|
||||||
if Client:IsAlive() then
|
if AIGroup then self:T( { AIGroup = AIGroup:GetName(), IsAlive = AIGroup:IsAlive() } ) end
|
||||||
|
if Client:IsAlive() == true then
|
||||||
|
|
||||||
if AIGroup and AIGroup:IsAlive() == true then
|
if AIGroup and AIGroup:IsAlive() == true then
|
||||||
|
|
||||||
@@ -255,7 +249,7 @@ function AI_BALANCER:onenterMonitoring( SetGroup )
|
|||||||
|
|
||||||
self:T2( RangeZone )
|
self:T2( RangeZone )
|
||||||
|
|
||||||
_DATABASE:ForEachPlayer(
|
_DATABASE:ForEachPlayerUnit(
|
||||||
--- @param Wrapper.Unit#UNIT RangeTestUnit
|
--- @param Wrapper.Unit#UNIT RangeTestUnit
|
||||||
function( RangeTestUnit, RangeZone, AIGroup, PlayerInRange )
|
function( RangeTestUnit, RangeZone, AIGroup, PlayerInRange )
|
||||||
self:T2( { PlayerInRange, RangeTestUnit.UnitName, RangeZone.ZoneName } )
|
self:T2( { PlayerInRange, RangeTestUnit.UnitName, RangeZone.ZoneName } )
|
||||||
@@ -284,11 +278,12 @@ function AI_BALANCER:onenterMonitoring( SetGroup )
|
|||||||
else
|
else
|
||||||
if not AIGroup or not AIGroup:IsAlive() == true then
|
if not AIGroup or not AIGroup:IsAlive() == true then
|
||||||
self:T( "Client " .. Client.UnitName .. " not alive." )
|
self:T( "Client " .. Client.UnitName .. " not alive." )
|
||||||
|
self:T( { Queue = self.SpawnQueue[Client.UnitName] } )
|
||||||
if not self.SpawnQueue[Client.UnitName] then
|
if not self.SpawnQueue[Client.UnitName] then
|
||||||
-- Spawn a new AI taking into account the spawn interval Earliest, Latest
|
-- Spawn a new AI taking into account the spawn interval Earliest, Latest
|
||||||
self:__Spawn( math.random( self.Earliest, self.Latest ), Client.UnitName )
|
self:__Spawn( math.random( self.Earliest, self.Latest ), Client.UnitName )
|
||||||
self.SpawnQueue[Client.UnitName] = true
|
self.SpawnQueue[Client.UnitName] = true
|
||||||
self:E( "New AI Spawned for Client " .. Client.UnitName )
|
self:T( "New AI Spawned for Client " .. Client.UnitName )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,35 +1,20 @@
|
|||||||
--- **AI** -- **Execute Combat Air Patrol (CAP).**
|
--- **AI** -- (R2.1) - Manages the independent process of Combat Air Patrol (CAP) for airplanes.
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
--
|
--
|
||||||
-- 
|
-- 
|
||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
-- AI CAP classes makes AI Controllables execute a Combat Air Patrol.
|
-- ### [Demo Missions](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master-release/CAP%20-%20Combat%20Air%20Patrol)
|
||||||
--
|
--
|
||||||
-- There are the following types of CAP classes defined:
|
-- ===
|
||||||
--
|
--
|
||||||
-- * @{#AI_CAP_ZONE}: Perform a CAP in a zone.
|
-- ### [YouTube Playlist](https://www.youtube.com/playlist?list=PL7ZUrU4zZUl1YCyPxJgoZn-CfhwyeW65L)
|
||||||
--
|
|
||||||
-- ====
|
|
||||||
--
|
--
|
||||||
-- # Demo Missions
|
-- ===
|
||||||
--
|
|
||||||
-- ### [AI_CAP Demo Missions source code](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master-release/CAP%20-%20Combat%20Air%20Patrol)
|
|
||||||
--
|
|
||||||
-- ### [AI_CAP Demo Missions, only for beta testers](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/CAP%20-%20Combat%20Air%20Patrol)
|
|
||||||
--
|
|
||||||
-- ### [ALL Demo Missions pack of the last release](https://github.com/FlightControl-Master/MOOSE_MISSIONS/releases)
|
|
||||||
--
|
|
||||||
-- ====
|
|
||||||
--
|
|
||||||
-- # YouTube Channel
|
|
||||||
--
|
|
||||||
-- ### [AI_CAP YouTube Channel](https://www.youtube.com/playlist?list=PL7ZUrU4zZUl1YCyPxJgoZn-CfhwyeW65L)
|
|
||||||
--
|
|
||||||
-- ====
|
|
||||||
--
|
|
||||||
-- ### Author: **Sven Van de Velde (FlightControl)**
|
|
||||||
--
|
--
|
||||||
|
-- ### Author: **FlightControl**
|
||||||
-- ### Contributions:
|
-- ### Contributions:
|
||||||
--
|
--
|
||||||
-- * **[Quax](https://forums.eagle.ru/member.php?u=90530)**: Concept, Advice & Testing.
|
-- * **[Quax](https://forums.eagle.ru/member.php?u=90530)**: Concept, Advice & Testing.
|
||||||
@@ -38,7 +23,7 @@
|
|||||||
-- * **[Whisper](http://forums.eagle.ru/member.php?u=3829): Testing.
|
-- * **[Whisper](http://forums.eagle.ru/member.php?u=3829): Testing.
|
||||||
-- * **[Delta99](https://forums.eagle.ru/member.php?u=125166): Testing.
|
-- * **[Delta99](https://forums.eagle.ru/member.php?u=125166): Testing.
|
||||||
--
|
--
|
||||||
-- ====
|
-- ===
|
||||||
--
|
--
|
||||||
-- @module AI_Cap
|
-- @module AI_Cap
|
||||||
|
|
||||||
@@ -479,7 +464,7 @@ function AI_CAP_ZONE:onafterEngage( Controllable, From, Event, To )
|
|||||||
EngageRoute[#EngageRoute+1] = ToPatrolRoutePoint
|
EngageRoute[#EngageRoute+1] = ToPatrolRoutePoint
|
||||||
|
|
||||||
Controllable:OptionROEOpenFire()
|
Controllable:OptionROEOpenFire()
|
||||||
Controllable:OptionROTPassiveDefense()
|
Controllable:OptionROTEvadeFire()
|
||||||
|
|
||||||
local AttackTasks = {}
|
local AttackTasks = {}
|
||||||
|
|
||||||
|
|||||||
@@ -1,43 +1,27 @@
|
|||||||
--- **AI** -- **Provide Close Air Support to friendly ground troops.**
|
--- **AI** -- (R2.1) - Manages the independent process of Close Air Support for airplanes.
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
--
|
--
|
||||||
-- 
|
-- 
|
||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
-- AI CAS classes makes AI Controllables execute a Close Air Support.
|
-- ### [Demo Missions](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master-release/CAS%20-%20Close%20Air%20Support)
|
||||||
--
|
--
|
||||||
-- There are the following types of CAS classes defined:
|
-- ===
|
||||||
--
|
--
|
||||||
-- * @{#AI_CAS_ZONE}: Perform a CAS in a zone.
|
-- ### [YouTube Playlist](https://www.youtube.com/playlist?list=PL7ZUrU4zZUl3JBO1WDqqpyYRRmIkR2ir2)
|
||||||
--
|
|
||||||
-- ====
|
|
||||||
--
|
--
|
||||||
-- # Demo Missions
|
-- ===
|
||||||
--
|
|
||||||
-- ### [AI_CAS Demo Missions source code](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master-release/CAS%20-%20Close%20Air%20Support)
|
|
||||||
--
|
|
||||||
-- ### [AI_CAS Demo Missions, only for beta testers](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/CAS%20-%20Close%20Air%20Support)
|
|
||||||
--
|
|
||||||
-- ### [ALL Demo Missions pack of the last release](https://github.com/FlightControl-Master/MOOSE_MISSIONS/releases)
|
|
||||||
--
|
|
||||||
-- ====
|
|
||||||
--
|
|
||||||
-- # YouTube Channel
|
|
||||||
--
|
|
||||||
-- ### [AI_CAS YouTube Channel](https://www.youtube.com/playlist?list=PL7ZUrU4zZUl3JBO1WDqqpyYRRmIkR2ir2)
|
|
||||||
--
|
|
||||||
-- ====
|
|
||||||
--
|
|
||||||
--
|
|
||||||
-- ### Author: **Sven Van de Velde (FlightControl)**
|
|
||||||
--
|
--
|
||||||
|
-- ### Author: **FlightControl**
|
||||||
-- ### Contributions:
|
-- ### Contributions:
|
||||||
--
|
--
|
||||||
-- * **[Quax](https://forums.eagle.ru/member.php?u=90530)**: Concept, Advice & Testing.
|
-- * **[Quax](https://forums.eagle.ru/member.php?u=90530)**: Concept, Advice & Testing.
|
||||||
-- * **[Pikey](https://forums.eagle.ru/member.php?u=62835)**: 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.
|
-- * **[Gunterlund](http://forums.eagle.ru:8080/member.php?u=75036)**: Test case revision.
|
||||||
--
|
--
|
||||||
-- ====
|
-- ===
|
||||||
--
|
--
|
||||||
-- @module AI_Cas
|
-- @module AI_Cas
|
||||||
|
|
||||||
@@ -403,7 +387,6 @@ end
|
|||||||
-- @param #string Event The Event string.
|
-- @param #string Event The Event string.
|
||||||
-- @param #string To The To State string.
|
-- @param #string To The To State string.
|
||||||
function AI_CAS_ZONE:onafterTarget( Controllable, From, Event, To )
|
function AI_CAS_ZONE:onafterTarget( Controllable, From, Event, To )
|
||||||
self:E("onafterTarget")
|
|
||||||
|
|
||||||
if Controllable:IsAlive() then
|
if Controllable:IsAlive() then
|
||||||
|
|
||||||
@@ -414,7 +397,7 @@ function AI_CAS_ZONE:onafterTarget( Controllable, From, Event, To )
|
|||||||
if DetectedUnit:IsAlive() then
|
if DetectedUnit:IsAlive() then
|
||||||
if DetectedUnit:IsInZone( self.EngageZone ) then
|
if DetectedUnit:IsInZone( self.EngageZone ) then
|
||||||
if Detected == true then
|
if Detected == true then
|
||||||
self:E( {"Target: ", DetectedUnit } )
|
self:F( {"Target: ", DetectedUnit } )
|
||||||
self.DetectedUnits[DetectedUnit] = false
|
self.DetectedUnits[DetectedUnit] = false
|
||||||
local AttackTask = Controllable:TaskAttackUnit( DetectedUnit, false, self.EngageWeaponExpend, self.EngageAttackQty, self.EngageDirection, self.EngageAltitude, nil )
|
local AttackTask = Controllable:TaskAttackUnit( DetectedUnit, false, self.EngageWeaponExpend, self.EngageAttackQty, self.EngageDirection, self.EngageAltitude, nil )
|
||||||
self.Controllable:PushTask( AttackTask, 1 )
|
self.Controllable:PushTask( AttackTask, 1 )
|
||||||
@@ -496,7 +479,7 @@ function AI_CAS_ZONE:onafterEngage( Controllable, From, Event, To,
|
|||||||
self:T( DetectedUnit )
|
self:T( DetectedUnit )
|
||||||
if DetectedUnit:IsAlive() then
|
if DetectedUnit:IsAlive() then
|
||||||
if DetectedUnit:IsInZone( self.EngageZone ) then
|
if DetectedUnit:IsInZone( self.EngageZone ) then
|
||||||
self:E( {"Engaging ", DetectedUnit } )
|
self:F( {"Engaging ", DetectedUnit } )
|
||||||
AttackTasks[#AttackTasks+1] = Controllable:TaskAttackUnit( DetectedUnit,
|
AttackTasks[#AttackTasks+1] = Controllable:TaskAttackUnit( DetectedUnit,
|
||||||
true,
|
true,
|
||||||
EngageWeaponExpend,
|
EngageWeaponExpend,
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
--- **AI** -- Build large **formations** of AI @{Group}s flying together.
|
--- **AI** -- (R2.2) - Build large airborne formations of aircraft.
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
--
|
--
|
||||||
-- 
|
-- 
|
||||||
--
|
--
|
||||||
@@ -28,29 +30,20 @@
|
|||||||
--
|
--
|
||||||
-- * @{#AI_FORMATION}: Create a formation from several @{GROUP}s.
|
-- * @{#AI_FORMATION}: Create a formation from several @{GROUP}s.
|
||||||
--
|
--
|
||||||
-- ====
|
-- ===
|
||||||
--
|
--
|
||||||
-- # Demo Missions
|
-- ### [Demo Missions](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/FOR%20-%20Formation)
|
||||||
--
|
|
||||||
-- ### [AI_FORMATION Demo Missions source code]()
|
|
||||||
--
|
|
||||||
-- ### [AI_FORMATION Demo Missions, only for beta testers]()
|
|
||||||
--
|
|
||||||
-- ### [ALL Demo Missions pack of the last release]()
|
|
||||||
--
|
|
||||||
-- ====
|
|
||||||
--
|
|
||||||
-- # YouTube Channel
|
|
||||||
--
|
|
||||||
--- ### [AI_FORMATION YouTube Channel]()
|
|
||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
-- ### Author: **Sven Van de Velde (FlightControl)**
|
-- ### [YouTube Playlist](https://www.youtube.com/playlist?list=PL7ZUrU4zZUl0bFIJ9jIdYM22uaWmIN4oz)
|
||||||
--
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- ### Author: **FlightControl**
|
||||||
-- ### Contributions:
|
-- ### Contributions:
|
||||||
--
|
--
|
||||||
-- ====
|
-- ===
|
||||||
--
|
--
|
||||||
-- @module AI_Formation
|
-- @module AI_Formation
|
||||||
|
|
||||||
@@ -66,7 +59,6 @@
|
|||||||
-- @field #boolean ReportTargets If true, nearby targets are reported.
|
-- @field #boolean ReportTargets If true, nearby targets are reported.
|
||||||
-- @Field DCSTypes#AI.Option.Air.val.ROE OptionROE Which ROE is set to the FollowGroup.
|
-- @Field DCSTypes#AI.Option.Air.val.ROE OptionROE Which ROE is set to the FollowGroup.
|
||||||
-- @field DCSTypes#AI.Option.Air.val.REACTION_ON_THREAT OptionReactionOnThreat Which REACTION_ON_THREAT is set to the FollowGroup.
|
-- @field DCSTypes#AI.Option.Air.val.REACTION_ON_THREAT OptionReactionOnThreat Which REACTION_ON_THREAT is set to the FollowGroup.
|
||||||
-- @field Menu#MENU_CLIENT FollowMenuResumeMission
|
|
||||||
|
|
||||||
|
|
||||||
--- # AI_FORMATION class, extends @{Fsm#FSM_SET}
|
--- # AI_FORMATION class, extends @{Fsm#FSM_SET}
|
||||||
@@ -679,7 +671,7 @@ end
|
|||||||
function AI_FORMATION:onafterFormationLine( FollowGroupSet, From , Event , To, XStart, XSpace, YStart, YSpace, ZStart, ZSpace ) --R2.1
|
function AI_FORMATION:onafterFormationLine( FollowGroupSet, From , Event , To, XStart, XSpace, YStart, YSpace, ZStart, ZSpace ) --R2.1
|
||||||
self:F( { FollowGroupSet, From , Event ,To, XStart, XSpace, YStart, YSpace, ZStart, ZSpace } )
|
self:F( { FollowGroupSet, From , Event ,To, XStart, XSpace, YStart, YSpace, ZStart, ZSpace } )
|
||||||
|
|
||||||
FollowGroupSet:Flush()
|
FollowGroupSet:Flush( self )
|
||||||
|
|
||||||
local FollowSet = FollowGroupSet:GetSet()
|
local FollowSet = FollowGroupSet:GetSet()
|
||||||
|
|
||||||
@@ -958,7 +950,7 @@ function AI_FORMATION:onenterFollowing( FollowGroupSet ) --R2.1
|
|||||||
-- @param Wrapper.Unit#UNIT ClientUnit
|
-- @param Wrapper.Unit#UNIT ClientUnit
|
||||||
function( FollowGroup, Formation, ClientUnit, CT1, CV1, CT2, CV2 )
|
function( FollowGroup, Formation, ClientUnit, CT1, CV1, CT2, CV2 )
|
||||||
|
|
||||||
FollowGroup:OptionROTPassiveDefense()
|
FollowGroup:OptionROTEvadeFire()
|
||||||
FollowGroup:OptionROEReturnFire()
|
FollowGroup:OptionROEReturnFire()
|
||||||
|
|
||||||
local GroupUnit = FollowGroup:GetUnit( 1 )
|
local GroupUnit = FollowGroup:GetUnit( 1 )
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
--- **AI** -- **Air Patrolling or Staging.**
|
--- **AI** -- (R2.1) - Manages the independent process of Air Patrol for airplanes.
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
--
|
--
|
||||||
-- 
|
-- 
|
||||||
--
|
--
|
||||||
@@ -10,31 +12,23 @@
|
|||||||
--
|
--
|
||||||
-- * @{#AI_PATROL_ZONE}: Perform a PATROL in a zone.
|
-- * @{#AI_PATROL_ZONE}: Perform a PATROL in a zone.
|
||||||
--
|
--
|
||||||
-- ====
|
-- ===
|
||||||
--
|
--
|
||||||
-- # Demo Missions
|
-- ### [Demo Missions](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master-release/PAT%20-%20Patrolling)
|
||||||
--
|
--
|
||||||
-- ### [AI_PATROL Demo Missions source code](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master-release/PAT%20-%20Patrolling)
|
-- ===
|
||||||
--
|
--
|
||||||
-- ### [AI_PATROL Demo Missions, only for beta testers](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/PAT%20-%20Patrolling)
|
-- ### [YouTube Playlist](https://www.youtube.com/playlist?list=PL7ZUrU4zZUl35HvYZKA6G22WMt7iI3zky)
|
||||||
--
|
|
||||||
-- ### [ALL Demo Missions pack of the last release](https://github.com/FlightControl-Master/MOOSE_MISSIONS/releases)
|
|
||||||
--
|
--
|
||||||
-- ====
|
-- ===
|
||||||
--
|
--
|
||||||
-- # YouTube Channel
|
-- ### Author: **FlightControl**
|
||||||
--
|
|
||||||
-- ### [AI_PATROL YouTube Channel](https://www.youtube.com/playlist?list=PL7ZUrU4zZUl35HvYZKA6G22WMt7iI3zky)
|
|
||||||
--
|
|
||||||
-- ====
|
|
||||||
--
|
|
||||||
-- ### Author: **Sven Van de Velde (FlightControl)**
|
|
||||||
-- ### 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 :-)
|
-- * **[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.
|
-- * **[Pikey](https://forums.eagle.ru/member.php?u=62835)**: Testing and API concept review.
|
||||||
--
|
--
|
||||||
-- ====
|
-- ===
|
||||||
--
|
--
|
||||||
-- @module AI_Patrol
|
-- @module AI_Patrol
|
||||||
|
|
||||||
@@ -47,7 +41,7 @@
|
|||||||
-- @field Dcs.DCSTypes#Altitude PatrolCeilingAltitude The highest 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 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 Dcs.DCSTypes#Speed PatrolMaxSpeed The maximum speed of the @{Controllable} in km/h.
|
||||||
-- @field Functional.Spawn#SPAWN CoordTest
|
-- @field Core.Spawn#SPAWN CoordTest
|
||||||
-- @extends Core.Fsm#FSM_CONTROLLABLE
|
-- @extends Core.Fsm#FSM_CONTROLLABLE
|
||||||
|
|
||||||
--- # AI_PATROL_ZONE class, extends @{Fsm#FSM_CONTROLLABLE}
|
--- # AI_PATROL_ZONE class, extends @{Fsm#FSM_CONTROLLABLE}
|
||||||
|
|||||||
@@ -190,7 +190,6 @@ do -- ACT_ACCOUNT_DEADS
|
|||||||
-- @param #string From
|
-- @param #string From
|
||||||
-- @param #string To
|
-- @param #string To
|
||||||
function ACT_ACCOUNT_DEADS:onenterReport( ProcessUnit, Task, From, Event, To )
|
function ACT_ACCOUNT_DEADS:onenterReport( ProcessUnit, Task, From, Event, To )
|
||||||
self:E( { ProcessUnit, From, Event, To } )
|
|
||||||
|
|
||||||
local MessageText = "Your group with assigned " .. self.TaskName .. " task has " .. Task.TargetSetUnit:GetUnitTypesText() .. " targets left to be destroyed."
|
local MessageText = "Your group with assigned " .. self.TaskName .. " task has " .. Task.TargetSetUnit:GetUnitTypesText() .. " targets left to be destroyed."
|
||||||
self:GetCommandCenter():MessageTypeToGroup( MessageText, ProcessUnit:GetGroup(), MESSAGE.Type.Information )
|
self:GetCommandCenter():MessageTypeToGroup( MessageText, ProcessUnit:GetGroup(), MESSAGE.Type.Information )
|
||||||
|
|||||||
@@ -156,7 +156,7 @@ do -- ACT_ASSIGN_ACCEPT
|
|||||||
-- @param #string From
|
-- @param #string From
|
||||||
-- @param #string To
|
-- @param #string To
|
||||||
function ACT_ASSIGN_ACCEPT:onafterStart( ProcessUnit, From, Event, To )
|
function ACT_ASSIGN_ACCEPT:onafterStart( ProcessUnit, From, Event, To )
|
||||||
self:E( { ProcessUnit, From, Event, To } )
|
self:F( { ProcessUnit, From, Event, To } )
|
||||||
|
|
||||||
self:__Assign( 1 )
|
self:__Assign( 1 )
|
||||||
end
|
end
|
||||||
@@ -168,8 +168,7 @@ do -- ACT_ASSIGN_ACCEPT
|
|||||||
-- @param #string From
|
-- @param #string From
|
||||||
-- @param #string To
|
-- @param #string To
|
||||||
function ACT_ASSIGN_ACCEPT:onenterAssigned( ProcessUnit, From, Event, To )
|
function ACT_ASSIGN_ACCEPT:onenterAssigned( ProcessUnit, From, Event, To )
|
||||||
env.info( "in here" )
|
self:F( { ProcessUnit, From, Event, To } )
|
||||||
self:E( { ProcessUnit, From, Event, To } )
|
|
||||||
|
|
||||||
local ProcessGroup = ProcessUnit:GetGroup()
|
local ProcessGroup = ProcessUnit:GetGroup()
|
||||||
|
|
||||||
@@ -234,7 +233,7 @@ do -- ACT_ASSIGN_MENU_ACCEPT
|
|||||||
-- @param #string From
|
-- @param #string From
|
||||||
-- @param #string To
|
-- @param #string To
|
||||||
function ACT_ASSIGN_MENU_ACCEPT:onafterStart( ProcessUnit, From, Event, To )
|
function ACT_ASSIGN_MENU_ACCEPT:onafterStart( ProcessUnit, From, Event, To )
|
||||||
self:E( { ProcessUnit, From, Event, To } )
|
self:F( { ProcessUnit, From, Event, To } )
|
||||||
|
|
||||||
self:GetCommandCenter():MessageTypeToGroup( "Access the radio menu to accept the task. You have 30 seconds or the assignment will be cancelled.", ProcessUnit:GetGroup(), MESSAGE.Type.Information )
|
self:GetCommandCenter():MessageTypeToGroup( "Access the radio menu to accept the task. You have 30 seconds or the assignment will be cancelled.", ProcessUnit:GetGroup(), MESSAGE.Type.Information )
|
||||||
|
|
||||||
@@ -248,7 +247,6 @@ do -- ACT_ASSIGN_MENU_ACCEPT
|
|||||||
--- Menu function.
|
--- Menu function.
|
||||||
-- @param #ACT_ASSIGN_MENU_ACCEPT self
|
-- @param #ACT_ASSIGN_MENU_ACCEPT self
|
||||||
function ACT_ASSIGN_MENU_ACCEPT:MenuAssign()
|
function ACT_ASSIGN_MENU_ACCEPT:MenuAssign()
|
||||||
self:E( )
|
|
||||||
|
|
||||||
self:__Assign( 1 )
|
self:__Assign( 1 )
|
||||||
end
|
end
|
||||||
@@ -256,7 +254,6 @@ do -- ACT_ASSIGN_MENU_ACCEPT
|
|||||||
--- Menu function.
|
--- Menu function.
|
||||||
-- @param #ACT_ASSIGN_MENU_ACCEPT self
|
-- @param #ACT_ASSIGN_MENU_ACCEPT self
|
||||||
function ACT_ASSIGN_MENU_ACCEPT:MenuReject()
|
function ACT_ASSIGN_MENU_ACCEPT:MenuReject()
|
||||||
self:E( )
|
|
||||||
|
|
||||||
self:__Reject( 1 )
|
self:__Reject( 1 )
|
||||||
end
|
end
|
||||||
@@ -268,7 +265,7 @@ do -- ACT_ASSIGN_MENU_ACCEPT
|
|||||||
-- @param #string From
|
-- @param #string From
|
||||||
-- @param #string To
|
-- @param #string To
|
||||||
function ACT_ASSIGN_MENU_ACCEPT:onafterAssign( ProcessUnit, From, Event, To )
|
function ACT_ASSIGN_MENU_ACCEPT:onafterAssign( ProcessUnit, From, Event, To )
|
||||||
self:E( { ProcessUnit.UnitNameFrom, Event, To } )
|
self:F( { ProcessUnit.UnitNameFrom, Event, To } )
|
||||||
|
|
||||||
self.Menu:Remove()
|
self.Menu:Remove()
|
||||||
end
|
end
|
||||||
@@ -280,7 +277,7 @@ do -- ACT_ASSIGN_MENU_ACCEPT
|
|||||||
-- @param #string From
|
-- @param #string From
|
||||||
-- @param #string To
|
-- @param #string To
|
||||||
function ACT_ASSIGN_MENU_ACCEPT:onafterReject( ProcessUnit, From, Event, To )
|
function ACT_ASSIGN_MENU_ACCEPT:onafterReject( ProcessUnit, From, Event, To )
|
||||||
self:E( { ProcessUnit.UnitName, From, Event, To } )
|
self:F( { ProcessUnit.UnitName, From, Event, To } )
|
||||||
|
|
||||||
self.Menu:Remove()
|
self.Menu:Remove()
|
||||||
--TODO: need to resolve this problem ... it has to do with the events ...
|
--TODO: need to resolve this problem ... it has to do with the events ...
|
||||||
|
|||||||
@@ -111,7 +111,6 @@ do -- ACT_ASSIST
|
|||||||
local MissionMenu = self:GetMission():GetMenu( ProcessGroup )
|
local MissionMenu = self:GetMission():GetMenu( ProcessGroup )
|
||||||
|
|
||||||
local function MenuSmoke( MenuParam )
|
local function MenuSmoke( MenuParam )
|
||||||
self:E( MenuParam )
|
|
||||||
local self = MenuParam.self
|
local self = MenuParam.self
|
||||||
local SmokeColor = MenuParam.SmokeColor
|
local SmokeColor = MenuParam.SmokeColor
|
||||||
self.SmokeColor = SmokeColor
|
self.SmokeColor = SmokeColor
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ end
|
|||||||
function PROCESS_JTAC:OnJTACMenuUpdate( Fsm, From, Event, To )
|
function PROCESS_JTAC:OnJTACMenuUpdate( Fsm, From, Event, To )
|
||||||
|
|
||||||
local function JTACMenuSpot( MenuParam )
|
local function JTACMenuSpot( MenuParam )
|
||||||
self:E( MenuParam.TargetUnit.UnitName )
|
self:F( MenuParam.TargetUnit.UnitName )
|
||||||
local self = MenuParam.self
|
local self = MenuParam.self
|
||||||
local TargetUnit = MenuParam.TargetUnit
|
local TargetUnit = MenuParam.TargetUnit
|
||||||
|
|
||||||
@@ -91,7 +91,7 @@ function PROCESS_JTAC:OnJTACMenuUpdate( Fsm, From, Event, To )
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function JTACMenuCancel( MenuParam )
|
local function JTACMenuCancel( MenuParam )
|
||||||
self:E( MenuParam )
|
self:F( MenuParam )
|
||||||
local self = MenuParam.self
|
local self = MenuParam.self
|
||||||
local TargetUnit = MenuParam.TargetUnit
|
local TargetUnit = MenuParam.TargetUnit
|
||||||
|
|
||||||
@@ -102,7 +102,7 @@ function PROCESS_JTAC:OnJTACMenuUpdate( Fsm, From, Event, To )
|
|||||||
-- Loop each unit in the target set, and determine the threat levels map table.
|
-- Loop each unit in the target set, and determine the threat levels map table.
|
||||||
local UnitThreatLevels = self.TargetSetUnit:GetUnitThreatLevels()
|
local UnitThreatLevels = self.TargetSetUnit:GetUnitThreatLevels()
|
||||||
|
|
||||||
self:E( {"UnitThreadLevels", UnitThreatLevels } )
|
self:F( {"UnitThreadLevels", UnitThreatLevels } )
|
||||||
|
|
||||||
local JTACMenu = self.ProcessGroup:GetState( self.ProcessGroup, "JTACMenu" )
|
local JTACMenu = self.ProcessGroup:GetState( self.ProcessGroup, "JTACMenu" )
|
||||||
|
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ end
|
|||||||
function PROCESS_PICKUP:OnHitTarget( Fsm, From, Event, To, Event )
|
function PROCESS_PICKUP:OnHitTarget( Fsm, From, Event, To, Event )
|
||||||
|
|
||||||
|
|
||||||
self.TargetSetUnit:Flush()
|
self.TargetSetUnit:Flush( self )
|
||||||
|
|
||||||
if self.TargetSetUnit:FindUnit( Event.IniUnitName ) then
|
if self.TargetSetUnit:FindUnit( Event.IniUnitName ) then
|
||||||
self.TargetSetUnit:RemoveUnitsByName( Event.IniUnitName )
|
self.TargetSetUnit:RemoveUnitsByName( Event.IniUnitName )
|
||||||
|
|||||||
@@ -158,8 +158,6 @@ do -- ACT_ROUTE
|
|||||||
-- @return #string
|
-- @return #string
|
||||||
function ACT_ROUTE:GetRouteText( Controllable )
|
function ACT_ROUTE:GetRouteText( Controllable )
|
||||||
|
|
||||||
self:E()
|
|
||||||
|
|
||||||
local RouteText = ""
|
local RouteText = ""
|
||||||
|
|
||||||
local Coordinate = nil -- Core.Point#COORDINATE
|
local Coordinate = nil -- Core.Point#COORDINATE
|
||||||
@@ -182,13 +180,13 @@ do -- ACT_ROUTE
|
|||||||
local ShortestDistance = 0
|
local ShortestDistance = 0
|
||||||
local ShortestReferencePoint = nil
|
local ShortestReferencePoint = nil
|
||||||
local ShortestReferenceName = ""
|
local ShortestReferenceName = ""
|
||||||
self:E( { CC.ReferencePoints } )
|
self:F( { CC.ReferencePoints } )
|
||||||
for ZoneName, Zone in pairs( CC.ReferencePoints ) do
|
for ZoneName, Zone in pairs( CC.ReferencePoints ) do
|
||||||
self:E( { ZoneName = ZoneName } )
|
self:F( { ZoneName = ZoneName } )
|
||||||
local Zone = Zone -- Core.Zone#ZONE
|
local Zone = Zone -- Core.Zone#ZONE
|
||||||
local ZoneCoord = Zone:GetCoordinate()
|
local ZoneCoord = Zone:GetCoordinate()
|
||||||
local ZoneDistance = ZoneCoord:Get2DDistance( self.Coordinate )
|
local ZoneDistance = ZoneCoord:Get2DDistance( self.Coordinate )
|
||||||
self:E( { ShortestDistance, ShortestReferenceName } )
|
self:F( { ShortestDistance, ShortestReferenceName } )
|
||||||
if ShortestDistance == 0 or ZoneDistance < ShortestDistance then
|
if ShortestDistance == 0 or ZoneDistance < ShortestDistance then
|
||||||
ShortestDistance = ZoneDistance
|
ShortestDistance = ZoneDistance
|
||||||
ShortestReferencePoint = ZoneCoord
|
ShortestReferencePoint = ZoneCoord
|
||||||
@@ -467,7 +465,7 @@ do -- ACT_ROUTE_ZONE
|
|||||||
-- @param #string From
|
-- @param #string From
|
||||||
-- @param #string To
|
-- @param #string To
|
||||||
function ACT_ROUTE_ZONE:onafterReport( ProcessUnit, From, Event, To )
|
function ACT_ROUTE_ZONE:onafterReport( ProcessUnit, From, Event, To )
|
||||||
self:E( { ProcessUnit = ProcessUnit } )
|
self:F( { ProcessUnit = ProcessUnit } )
|
||||||
|
|
||||||
local RouteText = self:GetRouteText( ProcessUnit )
|
local RouteText = self:GetRouteText( ProcessUnit )
|
||||||
self:GetCommandCenter():MessageTypeToGroup( RouteText, ProcessUnit:GetGroup(), MESSAGE.Type.Update )
|
self:GetCommandCenter():MessageTypeToGroup( RouteText, ProcessUnit:GetGroup(), MESSAGE.Type.Update )
|
||||||
|
|||||||
@@ -4,10 +4,10 @@
|
|||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
-- ### Author: **Sven Van de Velde (FlightControl)**
|
-- ### Author: **FlightControl**
|
||||||
-- ### Contributions:
|
-- ### Contributions:
|
||||||
--
|
--
|
||||||
-- ====
|
-- ===
|
||||||
--
|
--
|
||||||
-- @module Base
|
-- @module Base
|
||||||
|
|
||||||
@@ -198,6 +198,8 @@ BASE = {
|
|||||||
ClassID = 0,
|
ClassID = 0,
|
||||||
Events = {},
|
Events = {},
|
||||||
States = {},
|
States = {},
|
||||||
|
Debug = debug,
|
||||||
|
Scheduler = nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -269,6 +271,23 @@ function BASE:Inherit( Child, Parent )
|
|||||||
return Child
|
return Child
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
local function getParent( Child )
|
||||||
|
local Parent = nil
|
||||||
|
|
||||||
|
if Child.ClassName == 'BASE' then
|
||||||
|
Parent = nil
|
||||||
|
else
|
||||||
|
if rawget( Child, "__" ) then
|
||||||
|
Parent = getmetatable( Child.__ ).__index
|
||||||
|
else
|
||||||
|
Parent = getmetatable( Child ).__index
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return Parent
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
--- This is the worker method to retrieve the Parent class.
|
--- This is the worker method to retrieve the Parent class.
|
||||||
-- Note that the Parent class must be passed to call the parent class method.
|
-- Note that the Parent class must be passed to call the parent class method.
|
||||||
--
|
--
|
||||||
@@ -278,17 +297,31 @@ end
|
|||||||
-- @param #BASE self
|
-- @param #BASE self
|
||||||
-- @param #BASE Child is the Child class from which the Parent class needs to be retrieved.
|
-- @param #BASE Child is the Child class from which the Parent class needs to be retrieved.
|
||||||
-- @return #BASE
|
-- @return #BASE
|
||||||
function BASE:GetParent( Child )
|
function BASE:GetParent( Child, FromClass )
|
||||||
|
|
||||||
|
|
||||||
local Parent
|
local Parent
|
||||||
-- BASE class has no parent
|
-- BASE class has no parent
|
||||||
if Child.ClassName == 'BASE' then
|
if Child.ClassName == 'BASE' then
|
||||||
Parent = nil
|
Parent = nil
|
||||||
elseif rawget( Child, "__" ) then
|
else
|
||||||
Parent = getmetatable( Child.__ ).__index
|
|
||||||
else
|
--self:E({FromClass = FromClass})
|
||||||
Parent = getmetatable( Child ).__index
|
--self:E({Child = Child.ClassName})
|
||||||
end
|
if FromClass then
|
||||||
return Parent
|
while( Child.ClassName ~= "BASE" and Child.ClassName ~= FromClass.ClassName ) do
|
||||||
|
Child = getParent( Child )
|
||||||
|
--self:E({Child.ClassName})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if Child.ClassName == 'BASE' then
|
||||||
|
Parent = nil
|
||||||
|
else
|
||||||
|
Parent = getParent( Child )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
--self:E({Parent.ClassName})
|
||||||
|
return Parent
|
||||||
end
|
end
|
||||||
|
|
||||||
--- This is the worker method to check if an object is an (sub)instance of a class.
|
--- This is the worker method to check if an object is an (sub)instance of a class.
|
||||||
@@ -334,7 +367,7 @@ function BASE:IsInstanceOf( ClassName )
|
|||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
local Parent = self:GetParent(self)
|
local Parent = getParent(self)
|
||||||
|
|
||||||
while Parent do
|
while Parent do
|
||||||
|
|
||||||
@@ -342,7 +375,7 @@ function BASE:IsInstanceOf( ClassName )
|
|||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
Parent = Parent:GetParent(Parent)
|
Parent = getParent( Parent )
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -674,7 +707,12 @@ do -- Scheduling
|
|||||||
ObjectName = self.ClassName .. self.ClassID
|
ObjectName = self.ClassName .. self.ClassID
|
||||||
|
|
||||||
self:F3( { "ScheduleOnce: ", ObjectName, Start } )
|
self:F3( { "ScheduleOnce: ", ObjectName, Start } )
|
||||||
self.SchedulerObject = self
|
|
||||||
|
if not self.Scheduler then
|
||||||
|
self.Scheduler = SCHEDULER:New( self )
|
||||||
|
end
|
||||||
|
|
||||||
|
self.Scheduler.SchedulerObject = self.Scheduler
|
||||||
|
|
||||||
local ScheduleID = _SCHEDULEDISPATCHER:AddSchedule(
|
local ScheduleID = _SCHEDULEDISPATCHER:AddSchedule(
|
||||||
self,
|
self,
|
||||||
@@ -686,9 +724,9 @@ do -- Scheduling
|
|||||||
nil
|
nil
|
||||||
)
|
)
|
||||||
|
|
||||||
self._.Schedules[#self.Schedules+1] = ScheduleID
|
self._.Schedules[#self._.Schedules+1] = ScheduleID
|
||||||
|
|
||||||
return self._.Schedules
|
return self._.Schedules[#self._.Schedules]
|
||||||
end
|
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.
|
--- 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.
|
||||||
@@ -708,7 +746,12 @@ do -- Scheduling
|
|||||||
ObjectName = self.ClassName .. self.ClassID
|
ObjectName = self.ClassName .. self.ClassID
|
||||||
|
|
||||||
self:F3( { "ScheduleRepeat: ", ObjectName, Start, Repeat, RandomizeFactor, Stop } )
|
self:F3( { "ScheduleRepeat: ", ObjectName, Start, Repeat, RandomizeFactor, Stop } )
|
||||||
self.SchedulerObject = self
|
|
||||||
|
if not self.Scheduler then
|
||||||
|
self.Scheduler = SCHEDULER:New( self )
|
||||||
|
end
|
||||||
|
|
||||||
|
self.Scheduler.SchedulerObject = self.Scheduler
|
||||||
|
|
||||||
local ScheduleID = _SCHEDULEDISPATCHER:AddSchedule(
|
local ScheduleID = _SCHEDULEDISPATCHER:AddSchedule(
|
||||||
self,
|
self,
|
||||||
@@ -720,9 +763,9 @@ do -- Scheduling
|
|||||||
Stop
|
Stop
|
||||||
)
|
)
|
||||||
|
|
||||||
self._.Schedules[SchedulerFunction] = ScheduleID
|
self._.Schedules[#self._.Schedules+1] = ScheduleID
|
||||||
|
|
||||||
return self._.Schedules
|
return self._.Schedules[#self._.Schedules]
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Stops the Schedule.
|
--- Stops the Schedule.
|
||||||
@@ -732,7 +775,7 @@ do -- Scheduling
|
|||||||
|
|
||||||
self:F3( { "ScheduleStop:" } )
|
self:F3( { "ScheduleStop:" } )
|
||||||
|
|
||||||
_SCHEDULEDISPATCHER:Stop( self, self._.Schedules[SchedulerFunction] )
|
_SCHEDULEDISPATCHER:Stop( self.Scheduler, self._.Schedules[SchedulerFunction] )
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -789,7 +832,7 @@ end
|
|||||||
-- TODO: Make trace function using variable parameters.
|
-- TODO: Make trace function using variable parameters.
|
||||||
|
|
||||||
--- Set trace on or off
|
--- Set trace on or off
|
||||||
-- Note that when trace is off, no debug statement is performed, increasing performance!
|
-- Note that when trace is off, no BASE.Debug statement is performed, increasing performance!
|
||||||
-- When Moose is loaded statically, (as one file), tracing is switched off by default.
|
-- 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.
|
-- 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.
|
-- When moose is loading dynamically (for moose class development), tracing is switched on by default.
|
||||||
@@ -811,7 +854,7 @@ end
|
|||||||
-- @return #boolean
|
-- @return #boolean
|
||||||
function BASE:IsTrace()
|
function BASE:IsTrace()
|
||||||
|
|
||||||
if debug and ( _TraceAll == true ) or ( _TraceClass[self.ClassName] or _TraceClassMethod[self.ClassName] ) then
|
if BASE.Debug and ( _TraceAll == true ) or ( _TraceClass[self.ClassName] or _TraceClassMethod[self.ClassName] ) then
|
||||||
return true
|
return true
|
||||||
else
|
else
|
||||||
return false
|
return false
|
||||||
@@ -867,10 +910,10 @@ end
|
|||||||
-- @param Arguments A #table or any field.
|
-- @param Arguments A #table or any field.
|
||||||
function BASE:_F( Arguments, DebugInfoCurrentParam, DebugInfoFromParam )
|
function BASE:_F( Arguments, DebugInfoCurrentParam, DebugInfoFromParam )
|
||||||
|
|
||||||
if debug and ( _TraceAll == true ) or ( _TraceClass[self.ClassName] or _TraceClassMethod[self.ClassName] ) then
|
if BASE.Debug and ( _TraceAll == true ) or ( _TraceClass[self.ClassName] or _TraceClassMethod[self.ClassName] ) then
|
||||||
|
|
||||||
local DebugInfoCurrent = DebugInfoCurrentParam and DebugInfoCurrentParam or debug.getinfo( 2, "nl" )
|
local DebugInfoCurrent = DebugInfoCurrentParam and DebugInfoCurrentParam or BASE.Debug.getinfo( 2, "nl" )
|
||||||
local DebugInfoFrom = DebugInfoFromParam and DebugInfoFromParam or debug.getinfo( 3, "l" )
|
local DebugInfoFrom = DebugInfoFromParam and DebugInfoFromParam or BASE.Debug.getinfo( 3, "l" )
|
||||||
|
|
||||||
local Function = "function"
|
local Function = "function"
|
||||||
if DebugInfoCurrent.name then
|
if DebugInfoCurrent.name then
|
||||||
@@ -896,9 +939,9 @@ end
|
|||||||
-- @param Arguments A #table or any field.
|
-- @param Arguments A #table or any field.
|
||||||
function BASE:F( Arguments )
|
function BASE:F( Arguments )
|
||||||
|
|
||||||
if debug and _TraceOnOff then
|
if BASE.Debug and _TraceOnOff then
|
||||||
local DebugInfoCurrent = debug.getinfo( 2, "nl" )
|
local DebugInfoCurrent = BASE.Debug.getinfo( 2, "nl" )
|
||||||
local DebugInfoFrom = debug.getinfo( 3, "l" )
|
local DebugInfoFrom = BASE.Debug.getinfo( 3, "l" )
|
||||||
|
|
||||||
if _TraceLevel >= 1 then
|
if _TraceLevel >= 1 then
|
||||||
self:_F( Arguments, DebugInfoCurrent, DebugInfoFrom )
|
self:_F( Arguments, DebugInfoCurrent, DebugInfoFrom )
|
||||||
@@ -912,9 +955,9 @@ end
|
|||||||
-- @param Arguments A #table or any field.
|
-- @param Arguments A #table or any field.
|
||||||
function BASE:F2( Arguments )
|
function BASE:F2( Arguments )
|
||||||
|
|
||||||
if debug and _TraceOnOff then
|
if BASE.Debug and _TraceOnOff then
|
||||||
local DebugInfoCurrent = debug.getinfo( 2, "nl" )
|
local DebugInfoCurrent = BASE.Debug.getinfo( 2, "nl" )
|
||||||
local DebugInfoFrom = debug.getinfo( 3, "l" )
|
local DebugInfoFrom = BASE.Debug.getinfo( 3, "l" )
|
||||||
|
|
||||||
if _TraceLevel >= 2 then
|
if _TraceLevel >= 2 then
|
||||||
self:_F( Arguments, DebugInfoCurrent, DebugInfoFrom )
|
self:_F( Arguments, DebugInfoCurrent, DebugInfoFrom )
|
||||||
@@ -927,9 +970,9 @@ end
|
|||||||
-- @param Arguments A #table or any field.
|
-- @param Arguments A #table or any field.
|
||||||
function BASE:F3( Arguments )
|
function BASE:F3( Arguments )
|
||||||
|
|
||||||
if debug and _TraceOnOff then
|
if BASE.Debug and _TraceOnOff then
|
||||||
local DebugInfoCurrent = debug.getinfo( 2, "nl" )
|
local DebugInfoCurrent = BASE.Debug.getinfo( 2, "nl" )
|
||||||
local DebugInfoFrom = debug.getinfo( 3, "l" )
|
local DebugInfoFrom = BASE.Debug.getinfo( 3, "l" )
|
||||||
|
|
||||||
if _TraceLevel >= 3 then
|
if _TraceLevel >= 3 then
|
||||||
self:_F( Arguments, DebugInfoCurrent, DebugInfoFrom )
|
self:_F( Arguments, DebugInfoCurrent, DebugInfoFrom )
|
||||||
@@ -942,10 +985,10 @@ end
|
|||||||
-- @param Arguments A #table or any field.
|
-- @param Arguments A #table or any field.
|
||||||
function BASE:_T( Arguments, DebugInfoCurrentParam, DebugInfoFromParam )
|
function BASE:_T( Arguments, DebugInfoCurrentParam, DebugInfoFromParam )
|
||||||
|
|
||||||
if debug and ( _TraceAll == true ) or ( _TraceClass[self.ClassName] or _TraceClassMethod[self.ClassName] ) then
|
if BASE.Debug and ( _TraceAll == true ) or ( _TraceClass[self.ClassName] or _TraceClassMethod[self.ClassName] ) then
|
||||||
|
|
||||||
local DebugInfoCurrent = DebugInfoCurrentParam and DebugInfoCurrentParam or debug.getinfo( 2, "nl" )
|
local DebugInfoCurrent = DebugInfoCurrentParam and DebugInfoCurrentParam or BASE.Debug.getinfo( 2, "nl" )
|
||||||
local DebugInfoFrom = DebugInfoFromParam and DebugInfoFromParam or debug.getinfo( 3, "l" )
|
local DebugInfoFrom = DebugInfoFromParam and DebugInfoFromParam or BASE.Debug.getinfo( 3, "l" )
|
||||||
|
|
||||||
local Function = "function"
|
local Function = "function"
|
||||||
if DebugInfoCurrent.name then
|
if DebugInfoCurrent.name then
|
||||||
@@ -971,9 +1014,9 @@ end
|
|||||||
-- @param Arguments A #table or any field.
|
-- @param Arguments A #table or any field.
|
||||||
function BASE:T( Arguments )
|
function BASE:T( Arguments )
|
||||||
|
|
||||||
if debug and _TraceOnOff then
|
if BASE.Debug and _TraceOnOff then
|
||||||
local DebugInfoCurrent = debug.getinfo( 2, "nl" )
|
local DebugInfoCurrent = BASE.Debug.getinfo( 2, "nl" )
|
||||||
local DebugInfoFrom = debug.getinfo( 3, "l" )
|
local DebugInfoFrom = BASE.Debug.getinfo( 3, "l" )
|
||||||
|
|
||||||
if _TraceLevel >= 1 then
|
if _TraceLevel >= 1 then
|
||||||
self:_T( Arguments, DebugInfoCurrent, DebugInfoFrom )
|
self:_T( Arguments, DebugInfoCurrent, DebugInfoFrom )
|
||||||
@@ -987,9 +1030,9 @@ end
|
|||||||
-- @param Arguments A #table or any field.
|
-- @param Arguments A #table or any field.
|
||||||
function BASE:T2( Arguments )
|
function BASE:T2( Arguments )
|
||||||
|
|
||||||
if debug and _TraceOnOff then
|
if BASE.Debug and _TraceOnOff then
|
||||||
local DebugInfoCurrent = debug.getinfo( 2, "nl" )
|
local DebugInfoCurrent = BASE.Debug.getinfo( 2, "nl" )
|
||||||
local DebugInfoFrom = debug.getinfo( 3, "l" )
|
local DebugInfoFrom = BASE.Debug.getinfo( 3, "l" )
|
||||||
|
|
||||||
if _TraceLevel >= 2 then
|
if _TraceLevel >= 2 then
|
||||||
self:_T( Arguments, DebugInfoCurrent, DebugInfoFrom )
|
self:_T( Arguments, DebugInfoCurrent, DebugInfoFrom )
|
||||||
@@ -1002,9 +1045,9 @@ end
|
|||||||
-- @param Arguments A #table or any field.
|
-- @param Arguments A #table or any field.
|
||||||
function BASE:T3( Arguments )
|
function BASE:T3( Arguments )
|
||||||
|
|
||||||
if debug and _TraceOnOff then
|
if BASE.Debug and _TraceOnOff then
|
||||||
local DebugInfoCurrent = debug.getinfo( 2, "nl" )
|
local DebugInfoCurrent = BASE.Debug.getinfo( 2, "nl" )
|
||||||
local DebugInfoFrom = debug.getinfo( 3, "l" )
|
local DebugInfoFrom = BASE.Debug.getinfo( 3, "l" )
|
||||||
|
|
||||||
if _TraceLevel >= 3 then
|
if _TraceLevel >= 3 then
|
||||||
self:_T( Arguments, DebugInfoCurrent, DebugInfoFrom )
|
self:_T( Arguments, DebugInfoCurrent, DebugInfoFrom )
|
||||||
@@ -1017,9 +1060,9 @@ end
|
|||||||
-- @param Arguments A #table or any field.
|
-- @param Arguments A #table or any field.
|
||||||
function BASE:E( Arguments )
|
function BASE:E( Arguments )
|
||||||
|
|
||||||
if debug then
|
if BASE.Debug then
|
||||||
local DebugInfoCurrent = debug.getinfo( 2, "nl" )
|
local DebugInfoCurrent = BASE.Debug.getinfo( 2, "nl" )
|
||||||
local DebugInfoFrom = debug.getinfo( 3, "l" )
|
local DebugInfoFrom = BASE.Debug.getinfo( 3, "l" )
|
||||||
|
|
||||||
local Function = "function"
|
local Function = "function"
|
||||||
if DebugInfoCurrent.name then
|
if DebugInfoCurrent.name then
|
||||||
@@ -1033,6 +1076,36 @@ function BASE:E( Arguments )
|
|||||||
end
|
end
|
||||||
|
|
||||||
env.info( string.format( "%6d(%6d)/%1s:%20s%05d.%s(%s)" , LineCurrent, LineFrom, "E", self.ClassName, self.ClassID, Function, routines.utils.oneLineSerialize( Arguments ) ) )
|
env.info( string.format( "%6d(%6d)/%1s:%20s%05d.%s(%s)" , LineCurrent, LineFrom, "E", self.ClassName, self.ClassID, Function, routines.utils.oneLineSerialize( Arguments ) ) )
|
||||||
|
else
|
||||||
|
env.info( string.format( "%1s:%20s%05d(%s)" , "E", self.ClassName, self.ClassID, routines.utils.oneLineSerialize( Arguments ) ) )
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Log an information which will be traced always. Can be anywhere within the function logic.
|
||||||
|
-- @param #BASE self
|
||||||
|
-- @param Arguments A #table or any field.
|
||||||
|
function BASE:I( Arguments )
|
||||||
|
|
||||||
|
if BASE.Debug then
|
||||||
|
local DebugInfoCurrent = BASE.Debug.getinfo( 2, "nl" )
|
||||||
|
local DebugInfoFrom = BASE.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, "I", self.ClassName, self.ClassID, Function, routines.utils.oneLineSerialize( Arguments ) ) )
|
||||||
|
else
|
||||||
|
env.info( string.format( "%1s:%20s%05d(%s)" , "I", self.ClassName, self.ClassID, routines.utils.oneLineSerialize( Arguments ) ) )
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
--
|
--
|
||||||
-- This module is still under construction, but is described above works already, and will keep working ...
|
-- This module is still under construction, but is described above works already, and will keep working ...
|
||||||
--
|
--
|
||||||
-- ====
|
-- ===
|
||||||
--
|
--
|
||||||
-- # Demo Missions
|
-- # Demo Missions
|
||||||
--
|
--
|
||||||
@@ -21,18 +21,18 @@
|
|||||||
--
|
--
|
||||||
-- ### [ALL Demo Missions pack of the last release](https://github.com/FlightControl-Master/MOOSE_MISSIONS/releases)
|
-- ### [ALL Demo Missions pack of the last release](https://github.com/FlightControl-Master/MOOSE_MISSIONS/releases)
|
||||||
--
|
--
|
||||||
-- ====
|
-- ===
|
||||||
--
|
--
|
||||||
-- # YouTube Channel
|
-- # YouTube Channel
|
||||||
--
|
--
|
||||||
-- ### [CARGO YouTube Channel](https://www.youtube.com/watch?v=tM00lTlkpYs&list=PL7ZUrU4zZUl2zUTuKrLW5RsO9zLMqUtbf)
|
-- ### [CARGO YouTube Channel](https://www.youtube.com/watch?v=tM00lTlkpYs&list=PL7ZUrU4zZUl2zUTuKrLW5RsO9zLMqUtbf)
|
||||||
--
|
--
|
||||||
-- ====
|
-- ===
|
||||||
--
|
--
|
||||||
-- ### Author: **Sven Van de Velde (FlightControl)**
|
-- ### Author: **FlightControl**
|
||||||
-- ### Contributions:
|
-- ### Contributions:
|
||||||
--
|
--
|
||||||
-- ====
|
-- ===
|
||||||
--
|
--
|
||||||
-- @module Cargo
|
-- @module Cargo
|
||||||
|
|
||||||
@@ -338,6 +338,13 @@ function CARGO:IsUnLoaded()
|
|||||||
return self:Is( "UnLoaded" )
|
return self:Is( "UnLoaded" )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Check if cargo is boarding.
|
||||||
|
-- @param #CARGO self
|
||||||
|
-- @return #boolean true if boarding
|
||||||
|
function CARGO:IsBoarding()
|
||||||
|
return self:Is( "Boarding" )
|
||||||
|
end
|
||||||
|
|
||||||
--- Check if cargo is alive.
|
--- Check if cargo is alive.
|
||||||
-- @param #CARGO self
|
-- @param #CARGO self
|
||||||
-- @return #boolean true if unloaded
|
-- @return #boolean true if unloaded
|
||||||
@@ -486,7 +493,8 @@ end
|
|||||||
function CARGO:IsNear( PointVec2, NearRadius )
|
function CARGO:IsNear( PointVec2, NearRadius )
|
||||||
self:F( { PointVec2, NearRadius } )
|
self:F( { PointVec2, NearRadius } )
|
||||||
|
|
||||||
local Distance = PointVec2:DistanceFromPointVec2( self.CargoObject:GetPointVec2() )
|
--local Distance = PointVec2:DistanceFromPointVec2( self.CargoObject:GetPointVec2() )
|
||||||
|
local Distance = PointVec2:Get2DDistance( self.CargoObject:GetPointVec2() )
|
||||||
self:T( Distance )
|
self:T( Distance )
|
||||||
|
|
||||||
if Distance <= NearRadius then
|
if Distance <= NearRadius then
|
||||||
@@ -528,7 +536,7 @@ do -- CARGO_REPRESENTABLE
|
|||||||
-- @extends #CARGO
|
-- @extends #CARGO
|
||||||
-- @field test
|
-- @field test
|
||||||
|
|
||||||
---
|
--- Models CARGO that is representable by a Unit.
|
||||||
-- @field #CARGO_REPRESENTABLE CARGO_REPRESENTABLE
|
-- @field #CARGO_REPRESENTABLE CARGO_REPRESENTABLE
|
||||||
CARGO_REPRESENTABLE = {
|
CARGO_REPRESENTABLE = {
|
||||||
ClassName = "CARGO_REPRESENTABLE"
|
ClassName = "CARGO_REPRESENTABLE"
|
||||||
@@ -548,6 +556,18 @@ do -- CARGO_REPRESENTABLE
|
|||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- CARGO_REPRESENTABLE Destructor.
|
||||||
|
-- @param #CARGO_REPRESENTABLE self
|
||||||
|
-- @return #CARGO_REPRESENTABLE
|
||||||
|
function CARGO_REPRESENTABLE:Destroy()
|
||||||
|
|
||||||
|
-- Cargo objects are deleted from the _DATABASE and SET_CARGO objects.
|
||||||
|
self:F( { CargoName = self:GetName() } )
|
||||||
|
_EVENTDISPATCHER:CreateEventDeleteCargo( self )
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
--- Route a cargo unit to a PointVec2.
|
--- Route a cargo unit to a PointVec2.
|
||||||
-- @param #CARGO_REPRESENTABLE self
|
-- @param #CARGO_REPRESENTABLE self
|
||||||
@@ -677,7 +697,7 @@ end
|
|||||||
|
|
||||||
do -- CARGO_UNIT
|
do -- CARGO_UNIT
|
||||||
|
|
||||||
--- Hello
|
--- Models CARGO in the form of units, which can be boarded, unboarded, loaded, unloaded.
|
||||||
-- @type CARGO_UNIT
|
-- @type CARGO_UNIT
|
||||||
-- @extends #CARGO_REPRESENTABLE
|
-- @extends #CARGO_REPRESENTABLE
|
||||||
|
|
||||||
@@ -694,346 +714,425 @@ do -- CARGO_UNIT
|
|||||||
ClassName = "CARGO_UNIT"
|
ClassName = "CARGO_UNIT"
|
||||||
}
|
}
|
||||||
|
|
||||||
--- CARGO_UNIT Constructor.
|
--- CARGO_UNIT Constructor.
|
||||||
-- @param #CARGO_UNIT self
|
-- @param #CARGO_UNIT self
|
||||||
-- @param Wrapper.Unit#UNIT CargoUnit
|
-- @param Wrapper.Unit#UNIT CargoUnit
|
||||||
-- @param #string Type
|
-- @param #string Type
|
||||||
-- @param #string Name
|
-- @param #string Name
|
||||||
-- @param #number Weight
|
-- @param #number Weight
|
||||||
-- @param #number ReportRadius (optional)
|
-- @param #number ReportRadius (optional)
|
||||||
-- @param #number NearRadius (optional)
|
-- @param #number NearRadius (optional)
|
||||||
-- @return #CARGO_UNIT
|
-- @return #CARGO_UNIT
|
||||||
function CARGO_UNIT:New( CargoUnit, Type, Name, Weight, NearRadius )
|
function CARGO_UNIT:New( CargoUnit, Type, Name, Weight, NearRadius )
|
||||||
local self = BASE:Inherit( self, CARGO_REPRESENTABLE:New( CargoUnit, Type, Name, Weight, NearRadius ) ) -- #CARGO_UNIT
|
local self = BASE:Inherit( self, CARGO_REPRESENTABLE:New( CargoUnit, Type, Name, Weight, NearRadius ) ) -- #CARGO_UNIT
|
||||||
self:F( { Type, Name, Weight, NearRadius } )
|
self:F( { Type, Name, Weight, NearRadius } )
|
||||||
|
|
||||||
self:T( CargoUnit )
|
|
||||||
self.CargoObject = CargoUnit
|
|
||||||
|
|
||||||
self:T( self.ClassName )
|
|
||||||
|
|
||||||
-- self:HandleEvent( EVENTS.Dead,
|
|
||||||
-- --- @param #CARGO Cargo
|
|
||||||
-- -- @param Core.Event#EVENTDATA EventData
|
|
||||||
-- function( Cargo, EventData )
|
|
||||||
-- if Cargo:GetObjectName() == EventData.IniUnit:GetName() then
|
|
||||||
-- self:E( { "Cargo destroyed", Cargo } )
|
|
||||||
-- Cargo:Destroyed()
|
|
||||||
-- end
|
|
||||||
-- end
|
|
||||||
-- )
|
|
||||||
|
|
||||||
self:SetEventPriority( 5 )
|
|
||||||
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
--- CARGO_UNIT Destructor.
|
|
||||||
-- @param #CARGO_UNIT self
|
|
||||||
-- @return #CARGO_UNIT
|
|
||||||
function CARGO_UNIT:Destroy()
|
|
||||||
|
|
||||||
-- Cargo objects are deleted from the _DATABASE and SET_CARGO objects.
|
|
||||||
self:F( { CargoName = self:GetName() } )
|
|
||||||
_EVENTDISPATCHER:CreateEventDeleteCargo( self )
|
|
||||||
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Enter UnBoarding State.
|
|
||||||
-- @param #CARGO_UNIT self
|
|
||||||
-- @param #string Event
|
|
||||||
-- @param #string From
|
|
||||||
-- @param #string To
|
|
||||||
-- @param Core.Point#POINT_VEC2 ToPointVec2
|
|
||||||
function CARGO_UNIT:onenterUnBoarding( From, Event, To, ToPointVec2, NearRadius )
|
|
||||||
self:F( { From, Event, To, ToPointVec2, NearRadius } )
|
|
||||||
|
|
||||||
NearRadius = NearRadius or 25
|
|
||||||
|
|
||||||
local Angle = 180
|
|
||||||
local Speed = 60
|
|
||||||
local DeployDistance = 9
|
|
||||||
local RouteDistance = 60
|
|
||||||
|
|
||||||
if From == "Loaded" then
|
|
||||||
|
|
||||||
local CargoCarrier = self.CargoCarrier -- Wrapper.Controllable#CONTROLLABLE
|
|
||||||
|
|
||||||
local CargoCarrierPointVec2 = CargoCarrier:GetPointVec2()
|
|
||||||
local CargoCarrierHeading = self.CargoCarrier:GetHeading() -- Get Heading of object in degrees.
|
|
||||||
local CargoDeployHeading = ( ( CargoCarrierHeading + Angle ) >= 360 ) and ( CargoCarrierHeading + Angle - 360 ) or ( CargoCarrierHeading + Angle )
|
|
||||||
|
|
||||||
|
|
||||||
local CargoRoutePointVec2 = CargoCarrierPointVec2:Translate( RouteDistance, CargoDeployHeading )
|
|
||||||
|
|
||||||
|
|
||||||
-- if there is no ToPointVec2 given, then use the CargoRoutePointVec2
|
|
||||||
ToPointVec2 = ToPointVec2 or CargoRoutePointVec2
|
|
||||||
local DirectionVec3 = CargoCarrierPointVec2:GetDirectionVec3(ToPointVec2)
|
|
||||||
local Angle = CargoCarrierPointVec2:GetAngleDegrees(DirectionVec3)
|
|
||||||
|
|
||||||
local CargoDeployPointVec2 = CargoCarrierPointVec2:Translate( DeployDistance, Angle )
|
|
||||||
|
|
||||||
local FromPointVec2 = CargoCarrierPointVec2
|
|
||||||
|
|
||||||
-- Respawn the group...
|
|
||||||
if self.CargoObject then
|
|
||||||
self.CargoObject:ReSpawn( CargoDeployPointVec2:GetVec3(), CargoDeployHeading )
|
|
||||||
self:F( { "CargoUnits:", self.CargoObject:GetGroup():GetName() } )
|
|
||||||
self.CargoCarrier = nil
|
|
||||||
|
|
||||||
local Points = {}
|
|
||||||
Points[#Points+1] = CargoCarrierPointVec2:WaypointGround( Speed )
|
|
||||||
|
|
||||||
Points[#Points+1] = ToPointVec2:WaypointGround( Speed )
|
|
||||||
|
|
||||||
local TaskRoute = self.CargoObject:TaskRoute( Points )
|
self:T( CargoUnit )
|
||||||
self.CargoObject:SetTask( TaskRoute, 1 )
|
self.CargoObject = CargoUnit
|
||||||
|
|
||||||
|
self:T( self.ClassName )
|
||||||
self:__UnBoarding( 1, ToPointVec2, NearRadius )
|
|
||||||
end
|
self:SetEventPriority( 5 )
|
||||||
end
|
|
||||||
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Leave UnBoarding State.
|
--- Enter UnBoarding State.
|
||||||
-- @param #CARGO_UNIT self
|
-- @param #CARGO_UNIT self
|
||||||
-- @param #string Event
|
-- @param #string Event
|
||||||
-- @param #string From
|
-- @param #string From
|
||||||
-- @param #string To
|
-- @param #string To
|
||||||
-- @param Core.Point#POINT_VEC2 ToPointVec2
|
-- @param Core.Point#POINT_VEC2 ToPointVec2
|
||||||
function CARGO_UNIT:onleaveUnBoarding( From, Event, To, ToPointVec2, NearRadius )
|
function CARGO_UNIT:onenterUnBoarding( From, Event, To, ToPointVec2, NearRadius )
|
||||||
self:F( { From, Event, To, ToPointVec2, NearRadius } )
|
self:F( { From, Event, To, ToPointVec2, NearRadius } )
|
||||||
|
|
||||||
NearRadius = NearRadius or 25
|
NearRadius = NearRadius or 25
|
||||||
|
|
||||||
local Angle = 180
|
local Angle = 180
|
||||||
local Speed = 10
|
local Speed = 60
|
||||||
local Distance = 5
|
local DeployDistance = 9
|
||||||
|
local RouteDistance = 60
|
||||||
if From == "UnBoarding" then
|
|
||||||
if self:IsNear( ToPointVec2, NearRadius ) then
|
if From == "Loaded" then
|
||||||
return true
|
|
||||||
else
|
local CargoCarrier = self.CargoCarrier -- Wrapper.Controllable#CONTROLLABLE
|
||||||
|
|
||||||
self:__UnBoarding( 1, ToPointVec2, NearRadius )
|
|
||||||
end
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
--- UnBoard Event.
|
|
||||||
-- @param #CARGO_UNIT self
|
|
||||||
-- @param #string Event
|
|
||||||
-- @param #string From
|
|
||||||
-- @param #string To
|
|
||||||
-- @param Core.Point#POINT_VEC2 ToPointVec2
|
|
||||||
function CARGO_UNIT:onafterUnBoarding( From, Event, To, ToPointVec2, NearRadius )
|
|
||||||
self:F( { From, Event, To, ToPointVec2, NearRadius } )
|
|
||||||
|
|
||||||
NearRadius = NearRadius or 25
|
|
||||||
|
|
||||||
self.CargoInAir = self.CargoObject:InAir()
|
|
||||||
|
|
||||||
self:T( self.CargoInAir )
|
|
||||||
|
|
||||||
-- Only unboard the cargo when the carrier is not in the air.
|
|
||||||
-- (eg. cargo can be on a oil derrick, moving the cargo on the oil derrick will drop the cargo on the sea).
|
|
||||||
if not self.CargoInAir then
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
self:__UnLoad( 1, ToPointVec2, NearRadius )
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--- Enter UnLoaded State.
|
|
||||||
-- @param #CARGO_UNIT self
|
|
||||||
-- @param #string Event
|
|
||||||
-- @param #string From
|
|
||||||
-- @param #string To
|
|
||||||
-- @param Core.Point#POINT_VEC2
|
|
||||||
function CARGO_UNIT:onenterUnLoaded( From, Event, To, ToPointVec2 )
|
|
||||||
self:F( { ToPointVec2, From, Event, To } )
|
|
||||||
|
|
||||||
local Angle = 180
|
|
||||||
local Speed = 10
|
|
||||||
local Distance = 5
|
|
||||||
|
|
||||||
if From == "Loaded" then
|
|
||||||
local StartPointVec2 = self.CargoCarrier:GetPointVec2()
|
|
||||||
local CargoCarrierHeading = self.CargoCarrier:GetHeading() -- Get Heading of object in degrees.
|
|
||||||
local CargoDeployHeading = ( ( CargoCarrierHeading + Angle ) >= 360 ) and ( CargoCarrierHeading + Angle - 360 ) or ( CargoCarrierHeading + Angle )
|
|
||||||
local CargoDeployPointVec2 = StartPointVec2:Translate( Distance, CargoDeployHeading )
|
|
||||||
|
|
||||||
ToPointVec2 = ToPointVec2 or POINT_VEC2:New( CargoDeployPointVec2:GetX(), CargoDeployPointVec2:GetY() )
|
|
||||||
|
|
||||||
-- Respawn the group...
|
|
||||||
if self.CargoObject then
|
|
||||||
self.CargoObject:ReSpawn( ToPointVec2:GetVec3(), 0 )
|
|
||||||
self.CargoCarrier = nil
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
if self.OnUnLoadedCallBack then
|
|
||||||
self.OnUnLoadedCallBack( self, unpack( self.OnUnLoadedParameters ) )
|
|
||||||
self.OnUnLoadedCallBack = nil
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Board Event.
|
|
||||||
-- @param #CARGO_UNIT self
|
|
||||||
-- @param #string Event
|
|
||||||
-- @param #string From
|
|
||||||
-- @param #string To
|
|
||||||
function CARGO_UNIT:onafterBoard( From, Event, To, CargoCarrier, NearRadius, ... )
|
|
||||||
self:F( { From, Event, To, CargoCarrier, NearRadius } )
|
|
||||||
|
|
||||||
local NearRadius = NearRadius or 25
|
|
||||||
|
|
||||||
self.CargoInAir = self.CargoObject:InAir()
|
|
||||||
|
|
||||||
self:T( self.CargoInAir )
|
|
||||||
|
|
||||||
-- Only move the group to the carrier when the cargo is not in the air
|
|
||||||
-- (eg. cargo can be on a oil derrick, moving the cargo on the oil derrick will drop the cargo on the sea).
|
|
||||||
if not self.CargoInAir then
|
|
||||||
if self:IsNear( CargoCarrier:GetPointVec2(), NearRadius ) then
|
|
||||||
self:Load( CargoCarrier, NearRadius, ... )
|
|
||||||
else
|
|
||||||
local Speed = 90
|
|
||||||
local Angle = 180
|
|
||||||
local Distance = 5
|
|
||||||
|
|
||||||
NearRadius = NearRadius or 25
|
|
||||||
|
|
||||||
local CargoCarrierPointVec2 = CargoCarrier:GetPointVec2()
|
local CargoCarrierPointVec2 = CargoCarrier:GetPointVec2()
|
||||||
local CargoCarrierHeading = CargoCarrier:GetHeading() -- Get Heading of object in degrees.
|
local CargoCarrierHeading = self.CargoCarrier:GetHeading() -- Get Heading of object in degrees.
|
||||||
local CargoDeployHeading = ( ( CargoCarrierHeading + Angle ) >= 360 ) and ( CargoCarrierHeading + Angle - 360 ) or ( CargoCarrierHeading + Angle )
|
local CargoDeployHeading = ( ( CargoCarrierHeading + Angle ) >= 360 ) and ( CargoCarrierHeading + Angle - 360 ) or ( CargoCarrierHeading + Angle )
|
||||||
local CargoDeployPointVec2 = CargoCarrierPointVec2:Translate( Distance, CargoDeployHeading )
|
|
||||||
|
|
||||||
|
local CargoRoutePointVec2 = CargoCarrierPointVec2:Translate( RouteDistance, CargoDeployHeading )
|
||||||
|
|
||||||
|
|
||||||
|
-- if there is no ToPointVec2 given, then use the CargoRoutePointVec2
|
||||||
|
ToPointVec2 = ToPointVec2 or CargoRoutePointVec2
|
||||||
|
local DirectionVec3 = CargoCarrierPointVec2:GetDirectionVec3(ToPointVec2)
|
||||||
|
local Angle = CargoCarrierPointVec2:GetAngleDegrees(DirectionVec3)
|
||||||
|
|
||||||
|
local CargoDeployPointVec2 = CargoCarrierPointVec2:Translate( DeployDistance, Angle )
|
||||||
|
|
||||||
|
local FromPointVec2 = CargoCarrierPointVec2
|
||||||
|
|
||||||
|
-- Respawn the group...
|
||||||
|
if self.CargoObject then
|
||||||
|
self.CargoObject:ReSpawn( CargoDeployPointVec2:GetVec3(), CargoDeployHeading )
|
||||||
|
self:F( { "CargoUnits:", self.CargoObject:GetGroup():GetName() } )
|
||||||
|
self.CargoCarrier = nil
|
||||||
|
|
||||||
|
local Points = {}
|
||||||
|
Points[#Points+1] = CargoCarrierPointVec2:WaypointGround( Speed )
|
||||||
|
|
||||||
|
Points[#Points+1] = ToPointVec2:WaypointGround( Speed )
|
||||||
|
|
||||||
local Points = {}
|
local TaskRoute = self.CargoObject:TaskRoute( Points )
|
||||||
|
self.CargoObject:SetTask( TaskRoute, 1 )
|
||||||
local PointStartVec2 = self.CargoObject:GetPointVec2()
|
|
||||||
|
|
||||||
Points[#Points+1] = PointStartVec2:WaypointGround( Speed )
|
self:__UnBoarding( 1, ToPointVec2, NearRadius )
|
||||||
Points[#Points+1] = CargoDeployPointVec2:WaypointGround( Speed )
|
end
|
||||||
|
|
||||||
local TaskRoute = self.CargoObject:TaskRoute( Points )
|
|
||||||
self.CargoObject:SetTask( TaskRoute, 2 )
|
|
||||||
self:__Boarding( -1, CargoCarrier, NearRadius )
|
|
||||||
self.RunCount = 0
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
--- Leave UnBoarding State.
|
||||||
|
-- @param #CARGO_UNIT self
|
||||||
|
-- @param #string Event
|
||||||
--- Boarding Event.
|
-- @param #string From
|
||||||
-- @param #CARGO_UNIT self
|
-- @param #string To
|
||||||
-- @param #string Event
|
-- @param Core.Point#POINT_VEC2 ToPointVec2
|
||||||
-- @param #string From
|
function CARGO_UNIT:onleaveUnBoarding( From, Event, To, ToPointVec2, NearRadius )
|
||||||
-- @param #string To
|
self:F( { From, Event, To, ToPointVec2, NearRadius } )
|
||||||
-- @param Wrapper.Unit#UNIT CargoCarrier
|
|
||||||
-- @param #number NearRadius
|
|
||||||
function CARGO_UNIT:onafterBoarding( From, Event, To, CargoCarrier, NearRadius, ... )
|
|
||||||
self:F( { From, Event, To, CargoCarrier.UnitName, NearRadius } )
|
|
||||||
|
|
||||||
|
NearRadius = NearRadius or 25
|
||||||
|
|
||||||
if CargoCarrier and CargoCarrier:IsAlive() then
|
local Angle = 180
|
||||||
if CargoCarrier:InAir() == false then
|
local Speed = 10
|
||||||
if self:IsNear( CargoCarrier:GetPointVec2(), NearRadius ) then
|
local Distance = 5
|
||||||
self:__Load( 1, CargoCarrier, ... )
|
|
||||||
|
if From == "UnBoarding" then
|
||||||
|
if self:IsNear( ToPointVec2, NearRadius ) then
|
||||||
|
return true
|
||||||
else
|
else
|
||||||
self:__Boarding( -1, CargoCarrier, NearRadius, ... )
|
|
||||||
self.RunCount = self.RunCount + 1
|
self:__UnBoarding( 1, ToPointVec2, NearRadius )
|
||||||
if self.RunCount >= 20 then
|
end
|
||||||
self.RunCount = 0
|
return false
|
||||||
local Speed = 90
|
end
|
||||||
local Angle = 180
|
|
||||||
local Distance = 5
|
end
|
||||||
|
|
||||||
|
--- UnBoard Event.
|
||||||
|
-- @param #CARGO_UNIT self
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string To
|
||||||
|
-- @param Core.Point#POINT_VEC2 ToPointVec2
|
||||||
|
function CARGO_UNIT:onafterUnBoarding( From, Event, To, ToPointVec2, NearRadius )
|
||||||
|
self:F( { From, Event, To, ToPointVec2, NearRadius } )
|
||||||
|
|
||||||
|
NearRadius = NearRadius or 25
|
||||||
|
|
||||||
|
self.CargoInAir = self.CargoObject:InAir()
|
||||||
|
|
||||||
|
self:T( self.CargoInAir )
|
||||||
|
|
||||||
|
-- Only unboard the cargo when the carrier is not in the air.
|
||||||
|
-- (eg. cargo can be on a oil derrick, moving the cargo on the oil derrick will drop the cargo on the sea).
|
||||||
|
if not self.CargoInAir then
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
self:__UnLoad( 1, ToPointVec2, NearRadius )
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--- Enter UnLoaded State.
|
||||||
|
-- @param #CARGO_UNIT self
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string To
|
||||||
|
-- @param Core.Point#POINT_VEC2
|
||||||
|
function CARGO_UNIT:onenterUnLoaded( From, Event, To, ToPointVec2 )
|
||||||
|
self:F( { ToPointVec2, From, Event, To } )
|
||||||
|
|
||||||
|
local Angle = 180
|
||||||
|
local Speed = 10
|
||||||
|
local Distance = 5
|
||||||
|
|
||||||
|
if From == "Loaded" then
|
||||||
|
local StartPointVec2 = self.CargoCarrier:GetPointVec2()
|
||||||
|
local CargoCarrierHeading = self.CargoCarrier:GetHeading() -- Get Heading of object in degrees.
|
||||||
|
local CargoDeployHeading = ( ( CargoCarrierHeading + Angle ) >= 360 ) and ( CargoCarrierHeading + Angle - 360 ) or ( CargoCarrierHeading + Angle )
|
||||||
|
local CargoDeployCoord = StartPointVec2:Translate( Distance, CargoDeployHeading )
|
||||||
|
|
||||||
|
ToPointVec2 = ToPointVec2 or COORDINATE:New( CargoDeployCoord.x, CargoDeployCoord.z )
|
||||||
|
|
||||||
|
-- Respawn the group...
|
||||||
|
if self.CargoObject then
|
||||||
|
self.CargoObject:ReSpawn( ToPointVec2:GetVec3(), 0 )
|
||||||
|
self.CargoCarrier = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.OnUnLoadedCallBack then
|
||||||
|
self.OnUnLoadedCallBack( self, unpack( self.OnUnLoadedParameters ) )
|
||||||
|
self.OnUnLoadedCallBack = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Board Event.
|
||||||
|
-- @param #CARGO_UNIT self
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string To
|
||||||
|
function CARGO_UNIT:onafterBoard( From, Event, To, CargoCarrier, NearRadius, ... )
|
||||||
|
self:F( { From, Event, To, CargoCarrier, NearRadius } )
|
||||||
|
|
||||||
|
local NearRadius = NearRadius or 25
|
||||||
|
|
||||||
|
self.CargoInAir = self.CargoObject:InAir()
|
||||||
|
|
||||||
|
self:T( self.CargoInAir )
|
||||||
|
|
||||||
|
-- Only move the group to the carrier when the cargo is not in the air
|
||||||
|
-- (eg. cargo can be on a oil derrick, moving the cargo on the oil derrick will drop the cargo on the sea).
|
||||||
|
if not self.CargoInAir then
|
||||||
|
if self:IsNear( CargoCarrier:GetPointVec2(), NearRadius ) then
|
||||||
|
self:Load( CargoCarrier, NearRadius, ... )
|
||||||
|
else
|
||||||
|
local Speed = 90
|
||||||
|
local Angle = 180
|
||||||
|
local Distance = 5
|
||||||
|
|
||||||
|
NearRadius = NearRadius or 25
|
||||||
|
|
||||||
|
local CargoCarrierPointVec2 = CargoCarrier:GetPointVec2()
|
||||||
|
local CargoCarrierHeading = CargoCarrier:GetHeading() -- Get Heading of object in degrees.
|
||||||
|
local CargoDeployHeading = ( ( CargoCarrierHeading + Angle ) >= 360 ) and ( CargoCarrierHeading + Angle - 360 ) or ( CargoCarrierHeading + Angle )
|
||||||
|
local CargoDeployPointVec2 = CargoCarrierPointVec2:Translate( Distance, CargoDeployHeading )
|
||||||
|
|
||||||
|
local Points = {}
|
||||||
|
|
||||||
|
local PointStartVec2 = self.CargoObject:GetPointVec2()
|
||||||
|
|
||||||
|
Points[#Points+1] = PointStartVec2:WaypointGround( Speed )
|
||||||
|
Points[#Points+1] = CargoDeployPointVec2:WaypointGround( Speed )
|
||||||
|
|
||||||
|
local TaskRoute = self.CargoObject:TaskRoute( Points )
|
||||||
|
self.CargoObject:SetTask( TaskRoute, 2 )
|
||||||
|
self:__Boarding( -1, CargoCarrier, NearRadius )
|
||||||
|
self.RunCount = 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Boarding Event.
|
||||||
|
-- @param #CARGO_UNIT self
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string To
|
||||||
|
-- @param Wrapper.Unit#UNIT CargoCarrier
|
||||||
|
-- @param #number NearRadius
|
||||||
|
function CARGO_UNIT:onafterBoarding( From, Event, To, CargoCarrier, NearRadius, ... )
|
||||||
|
self:F( { From, Event, To, CargoCarrier.UnitName, NearRadius } )
|
||||||
|
|
||||||
|
|
||||||
|
if CargoCarrier and CargoCarrier:IsAlive() then
|
||||||
|
if CargoCarrier:InAir() == false then
|
||||||
|
if self:IsNear( CargoCarrier:GetPointVec2(), NearRadius ) then
|
||||||
|
self:__Load( 1, CargoCarrier, ... )
|
||||||
|
else
|
||||||
|
self:__Boarding( -1, CargoCarrier, NearRadius, ... )
|
||||||
|
self.RunCount = self.RunCount + 1
|
||||||
|
if self.RunCount >= 60 then
|
||||||
|
self.RunCount = 0
|
||||||
|
local Speed = 90
|
||||||
|
local Angle = 180
|
||||||
|
local Distance = 5
|
||||||
|
|
||||||
|
NearRadius = NearRadius or 25
|
||||||
|
|
||||||
NearRadius = NearRadius or 25
|
local CargoCarrierPointVec2 = CargoCarrier:GetPointVec2()
|
||||||
|
local CargoCarrierHeading = CargoCarrier:GetHeading() -- Get Heading of object in degrees.
|
||||||
local CargoCarrierPointVec2 = CargoCarrier:GetPointVec2()
|
local CargoDeployHeading = ( ( CargoCarrierHeading + Angle ) >= 360 ) and ( CargoCarrierHeading + Angle - 360 ) or ( CargoCarrierHeading + Angle )
|
||||||
local CargoCarrierHeading = CargoCarrier:GetHeading() -- Get Heading of object in degrees.
|
local CargoDeployPointVec2 = CargoCarrierPointVec2:Translate( Distance, CargoDeployHeading )
|
||||||
local CargoDeployHeading = ( ( CargoCarrierHeading + Angle ) >= 360 ) and ( CargoCarrierHeading + Angle - 360 ) or ( CargoCarrierHeading + Angle )
|
|
||||||
local CargoDeployPointVec2 = CargoCarrierPointVec2:Translate( Distance, CargoDeployHeading )
|
local Points = {}
|
||||||
|
|
||||||
local Points = {}
|
local PointStartVec2 = self.CargoObject:GetPointVec2()
|
||||||
|
|
||||||
local PointStartVec2 = self.CargoObject:GetPointVec2()
|
Points[#Points+1] = PointStartVec2:WaypointGround( Speed )
|
||||||
|
Points[#Points+1] = CargoDeployPointVec2:WaypointGround( Speed )
|
||||||
Points[#Points+1] = PointStartVec2:WaypointGround( Speed )
|
|
||||||
Points[#Points+1] = CargoDeployPointVec2:WaypointGround( Speed )
|
local TaskRoute = self.CargoObject:TaskRoute( Points )
|
||||||
|
self.CargoObject:SetTask( TaskRoute, 0.2 )
|
||||||
local TaskRoute = self.CargoObject:TaskRoute( Points )
|
end
|
||||||
self.CargoObject:SetTask( TaskRoute, 0.2 )
|
|
||||||
end
|
end
|
||||||
|
else
|
||||||
|
self.CargoObject:MessageToGroup( "Cancelling Boarding... Get back on the ground!", 5, CargoCarrier:GetGroup(), self:GetName() )
|
||||||
|
self:CancelBoarding( CargoCarrier, NearRadius, ... )
|
||||||
|
self.CargoObject:SetCommand( self.CargoObject:CommandStopRoute( true ) )
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
self.CargoObject:MessageToGroup( "Cancelling Boarding... Get back on the ground!", 5, CargoCarrier:GetGroup(), self:GetName() )
|
self:E("Something is wrong")
|
||||||
self:CancelBoarding( CargoCarrier, NearRadius, ... )
|
|
||||||
self.CargoObject:SetCommand( self.CargoObject:CommandStopRoute( true ) )
|
|
||||||
end
|
end
|
||||||
else
|
|
||||||
self:E("Something is wrong")
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
--- Enter Boarding State.
|
|
||||||
-- @param #CARGO_UNIT self
|
|
||||||
-- @param #string Event
|
|
||||||
-- @param #string From
|
|
||||||
-- @param #string To
|
|
||||||
-- @param Wrapper.Unit#UNIT CargoCarrier
|
|
||||||
function CARGO_UNIT:onenterBoarding( From, Event, To, CargoCarrier, NearRadius, ... )
|
|
||||||
self:F( { From, Event, To, CargoCarrier.UnitName, NearRadius } )
|
|
||||||
|
|
||||||
local Speed = 90
|
--- Enter Boarding State.
|
||||||
local Angle = 180
|
-- @param #CARGO_UNIT self
|
||||||
local Distance = 5
|
-- @param #string Event
|
||||||
|
-- @param #string From
|
||||||
local NearRadius = NearRadius or 25
|
-- @param #string To
|
||||||
|
-- @param Wrapper.Unit#UNIT CargoCarrier
|
||||||
if From == "UnLoaded" or From == "Boarding" then
|
function CARGO_UNIT:onenterBoarding( From, Event, To, CargoCarrier, NearRadius, ... )
|
||||||
|
self:F( { From, Event, To, CargoCarrier.UnitName, NearRadius } )
|
||||||
|
|
||||||
|
local Speed = 90
|
||||||
|
local Angle = 180
|
||||||
|
local Distance = 5
|
||||||
|
|
||||||
|
local NearRadius = NearRadius or 25
|
||||||
|
|
||||||
|
if From == "UnLoaded" or From == "Boarding" then
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
--- Loaded State.
|
||||||
|
-- @param #CARGO_UNIT self
|
||||||
--- Loaded State.
|
-- @param #string Event
|
||||||
-- @param #CARGO_UNIT self
|
-- @param #string From
|
||||||
-- @param #string Event
|
-- @param #string To
|
||||||
-- @param #string From
|
-- @param Wrapper.Unit#UNIT CargoCarrier
|
||||||
-- @param #string To
|
function CARGO_UNIT:onenterLoaded( From, Event, To, CargoCarrier )
|
||||||
-- @param Wrapper.Unit#UNIT CargoCarrier
|
self:F( { From, Event, To, CargoCarrier } )
|
||||||
function CARGO_UNIT:onenterLoaded( From, Event, To, CargoCarrier )
|
|
||||||
self:F( { From, Event, To, CargoCarrier } )
|
|
||||||
|
|
||||||
self.CargoCarrier = CargoCarrier
|
|
||||||
|
|
||||||
-- Only destroy the CargoObject is if there is a CargoObject (packages don't have CargoObjects).
|
self.CargoCarrier = CargoCarrier
|
||||||
if self.CargoObject then
|
|
||||||
self:T("Destroying")
|
-- Only destroy the CargoObject is if there is a CargoObject (packages don't have CargoObjects).
|
||||||
self.CargoObject:Destroy()
|
if self.CargoObject then
|
||||||
|
self:T("Destroying")
|
||||||
|
self.CargoObject:Destroy()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end -- CARGO_UNIT
|
||||||
|
|
||||||
|
|
||||||
|
do -- CARGO_CRATE
|
||||||
|
|
||||||
|
--- Models the behaviour of cargo crates, which can be slingloaded and boarded on helicopters using the DCS menus.
|
||||||
|
-- @type CARGO_CRATE
|
||||||
|
-- @extends #CARGO_REPRESENTABLE
|
||||||
|
|
||||||
|
--- # CARGO\_CRATE class, extends @{#CARGO_REPRESENTABLE}
|
||||||
|
--
|
||||||
|
-- The CARGO\_CRATE class defines a cargo that is represented by a UNIT object within the simulator, and can be transported by a carrier.
|
||||||
|
-- Use the event functions as described above to Load, UnLoad, Board, UnBoard the CARGO\_CRATE objects to and from carriers.
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- @field #CARGO_CRATE
|
||||||
|
CARGO_CRATE = {
|
||||||
|
ClassName = "CARGO_CRATE"
|
||||||
|
}
|
||||||
|
|
||||||
|
--- CARGO_CRATE Constructor.
|
||||||
|
-- @param #CARGO_CRATE self
|
||||||
|
-- @param #string CrateName
|
||||||
|
-- @param #string Type
|
||||||
|
-- @param #string Name
|
||||||
|
-- @param #number Weight
|
||||||
|
-- @param #number ReportRadius (optional)
|
||||||
|
-- @param #number NearRadius (optional)
|
||||||
|
-- @return #CARGO_CRATE
|
||||||
|
function CARGO_CRATE:New( CargoCrateName, Type, Name, NearRadius )
|
||||||
|
local self = BASE:Inherit( self, CARGO_REPRESENTABLE:New( CargoCrateName, Type, Name, nil, NearRadius ) ) -- #CARGO_CRATE
|
||||||
|
self:F( { Type, Name, NearRadius } )
|
||||||
|
|
||||||
|
self:T( CargoCrateName )
|
||||||
|
_DATABASE:AddStatic( CargoCrateName )
|
||||||
|
|
||||||
|
self.CargoObject = STATIC:FindByName( CargoCrateName )
|
||||||
|
|
||||||
|
self:T( self.ClassName )
|
||||||
|
|
||||||
|
self:SetEventPriority( 5 )
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--- Enter UnLoaded State.
|
||||||
|
-- @param #CARGO_CRATE self
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string To
|
||||||
|
-- @param Core.Point#POINT_VEC2
|
||||||
|
function CARGO_CRATE:onenterUnLoaded( From, Event, To, ToPointVec2 )
|
||||||
|
self:F( { ToPointVec2, From, Event, To } )
|
||||||
|
|
||||||
|
local Angle = 180
|
||||||
|
local Speed = 10
|
||||||
|
local Distance = 10
|
||||||
|
|
||||||
|
if From == "Loaded" then
|
||||||
|
local StartCoordinate = self.CargoCarrier:GetCoordinate()
|
||||||
|
local CargoCarrierHeading = self.CargoCarrier:GetHeading() -- Get Heading of object in degrees.
|
||||||
|
local CargoDeployHeading = ( ( CargoCarrierHeading + Angle ) >= 360 ) and ( CargoCarrierHeading + Angle - 360 ) or ( CargoCarrierHeading + Angle )
|
||||||
|
local CargoDeployCoord = StartCoordinate:Translate( Distance, CargoDeployHeading )
|
||||||
|
|
||||||
|
ToPointVec2 = ToPointVec2 or COORDINATE:NewFromVec2( { x= CargoDeployCoord.x, y = CargoDeployCoord.z } )
|
||||||
|
|
||||||
|
-- Respawn the group...
|
||||||
|
if self.CargoObject then
|
||||||
|
self.CargoObject:ReSpawn( ToPointVec2, 0 )
|
||||||
|
self.CargoCarrier = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.OnUnLoadedCallBack then
|
||||||
|
self.OnUnLoadedCallBack( self, unpack( self.OnUnLoadedParameters ) )
|
||||||
|
self.OnUnLoadedCallBack = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Loaded State.
|
||||||
|
-- @param #CARGO_CRATE self
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string To
|
||||||
|
-- @param Wrapper.Unit#UNIT CargoCarrier
|
||||||
|
function CARGO_CRATE:onenterLoaded( From, Event, To, CargoCarrier )
|
||||||
|
self:F( { From, Event, To, CargoCarrier } )
|
||||||
|
|
||||||
|
self.CargoCarrier = CargoCarrier
|
||||||
|
|
||||||
|
-- Only destroy the CargoObject is if there is a CargoObject (packages don't have CargoObjects).
|
||||||
|
if self.CargoObject then
|
||||||
|
self:T("Destroying")
|
||||||
|
self.CargoObject:Destroy()
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
do -- CARGO_GROUP
|
do -- CARGO_GROUP
|
||||||
|
|
||||||
--- @type CARGO_GROUP
|
--- @type CARGO_GROUP
|
||||||
@@ -1190,7 +1289,10 @@ function CARGO_GROUP:onafterBoarding( From, Event, To, CargoCarrier, NearRadius,
|
|||||||
-- For each Cargo object within the CARGO_GROUP, route each object to the CargoLoadPointVec2
|
-- For each Cargo object within the CARGO_GROUP, route each object to the CargoLoadPointVec2
|
||||||
for CargoID, Cargo in pairs( self.CargoSet:GetSet() ) do
|
for CargoID, Cargo in pairs( self.CargoSet:GetSet() ) do
|
||||||
self:T( { Cargo:GetName(), Cargo.current } )
|
self:T( { Cargo:GetName(), Cargo.current } )
|
||||||
if not Cargo:is( "Loaded" ) then
|
|
||||||
|
|
||||||
|
if not Cargo:is( "Loaded" )
|
||||||
|
and (not Cargo:is( "Destroyed" )) then -- If one or more units of a group defined as CARGO_GROUP died, the CARGO_GROUP:Board() command does not trigger the CARGO_GRUOP:OnEnterLoaded() function.
|
||||||
Boarded = false
|
Boarded = false
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1330,7 +1432,9 @@ function CARGO_GROUP:onenterUnLoaded( From, Event, To, ToPointVec2, ... )
|
|||||||
-- For each Cargo object within the CARGO_GROUP, route each object to the CargoLoadPointVec2
|
-- For each Cargo object within the CARGO_GROUP, route each object to the CargoLoadPointVec2
|
||||||
self.CargoSet:ForEach(
|
self.CargoSet:ForEach(
|
||||||
function( Cargo )
|
function( Cargo )
|
||||||
Cargo:UnLoad( ToPointVec2 )
|
--Cargo:UnLoad( ToPointVec2 )
|
||||||
|
local RandomVec2=ToPointVec2:GetRandomPointVec2InRadius(10)
|
||||||
|
Cargo:UnLoad( RandomVec2 )
|
||||||
end
|
end
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,20 @@
|
|||||||
--- **Core** -- DATABASE manages the database of mission objects.
|
--- **Core** -- DATABASE manages the database of mission objects.
|
||||||
--
|
--
|
||||||
-- ====
|
-- ===
|
||||||
|
--
|
||||||
|
-- ### Author: **FlightControl**
|
||||||
|
-- ### Contributions:
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- @module Database
|
||||||
|
|
||||||
|
|
||||||
|
--- @type DATABASE
|
||||||
|
-- @extends Core.Base#BASE
|
||||||
|
|
||||||
|
--- # DATABASE class, extends @{Base#BASE}
|
||||||
--
|
--
|
||||||
-- 1) @{#DATABASE} class, extends @{Base#BASE}
|
|
||||||
-- ===================================================
|
|
||||||
-- Mission designers can use the DATABASE class to refer to:
|
-- Mission designers can use the DATABASE class to refer to:
|
||||||
--
|
--
|
||||||
-- * STATICS
|
-- * STATICS
|
||||||
@@ -17,35 +28,10 @@
|
|||||||
--
|
--
|
||||||
-- On top, for internal MOOSE administration purposes, the DATBASE administers the Unit and Group TEMPLATES as defined within the Mission Editor.
|
-- 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.
|
-- The singleton object **_DATABASE** is automatically created by MOOSE, that administers all objects within the mission.
|
||||||
-- Moose refers to _DATABASE within the framework extensively, but you can also refer to the _DATABASE object within your missions if required.
|
-- 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
|
-- @field #DATABASE
|
||||||
-- -----------------------
|
|
||||||
-- 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.
|
|
||||||
--
|
|
||||||
-- ===
|
|
||||||
--
|
|
||||||
--
|
|
||||||
-- ### Author: **Sven Van de Velde (FlightControl)**
|
|
||||||
-- ### Contributions:
|
|
||||||
--
|
|
||||||
-- ====
|
|
||||||
-- @module Database
|
|
||||||
|
|
||||||
|
|
||||||
--- DATABASE class
|
|
||||||
-- @type DATABASE
|
|
||||||
-- @extends Core.Base#BASE
|
|
||||||
DATABASE = {
|
DATABASE = {
|
||||||
ClassName = "DATABASE",
|
ClassName = "DATABASE",
|
||||||
Templates = {
|
Templates = {
|
||||||
@@ -70,6 +56,8 @@ DATABASE = {
|
|||||||
NavPoints = {},
|
NavPoints = {},
|
||||||
PLAYERSETTINGS = {},
|
PLAYERSETTINGS = {},
|
||||||
ZONENAMES = {},
|
ZONENAMES = {},
|
||||||
|
HITS = {},
|
||||||
|
DESTROYS = {},
|
||||||
}
|
}
|
||||||
|
|
||||||
local _DATABASECoalition =
|
local _DATABASECoalition =
|
||||||
@@ -104,11 +92,12 @@ function DATABASE:New()
|
|||||||
self:HandleEvent( EVENTS.Birth, self._EventOnBirth )
|
self:HandleEvent( EVENTS.Birth, self._EventOnBirth )
|
||||||
self:HandleEvent( EVENTS.Dead, self._EventOnDeadOrCrash )
|
self:HandleEvent( EVENTS.Dead, self._EventOnDeadOrCrash )
|
||||||
self:HandleEvent( EVENTS.Crash, self._EventOnDeadOrCrash )
|
self:HandleEvent( EVENTS.Crash, self._EventOnDeadOrCrash )
|
||||||
|
self:HandleEvent( EVENTS.Hit, self.AccountHits )
|
||||||
self:HandleEvent( EVENTS.NewCargo )
|
self:HandleEvent( EVENTS.NewCargo )
|
||||||
self:HandleEvent( EVENTS.DeleteCargo )
|
self:HandleEvent( EVENTS.DeleteCargo )
|
||||||
|
|
||||||
-- Follow alive players and clients
|
-- Follow alive players and clients
|
||||||
self:HandleEvent( EVENTS.PlayerEnterUnit, self._EventOnPlayerEnterUnit )
|
--self:HandleEvent( EVENTS.PlayerEnterUnit, self._EventOnPlayerEnterUnit ) -- This is not working anymore!, handling this through the birth event.
|
||||||
self:HandleEvent( EVENTS.PlayerLeaveUnit, self._EventOnPlayerLeaveUnit )
|
self:HandleEvent( EVENTS.PlayerLeaveUnit, self._EventOnPlayerLeaveUnit )
|
||||||
|
|
||||||
self:_RegisterTemplates()
|
self:_RegisterTemplates()
|
||||||
@@ -148,8 +137,8 @@ function DATABASE:New()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
self:E( "Scheduling" )
|
--self:E( "Scheduling" )
|
||||||
PlayerCheckSchedule = SCHEDULER:New( nil, CheckPlayers, { self }, 1, 1 )
|
--PlayerCheckSchedule = SCHEDULER:New( nil, CheckPlayers, { self }, 1, 1 )
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
@@ -336,7 +325,7 @@ function DATABASE:AddPlayer( UnitName, PlayerName )
|
|||||||
if PlayerName then
|
if PlayerName then
|
||||||
self:E( { "Add player for unit:", UnitName, PlayerName } )
|
self:E( { "Add player for unit:", UnitName, PlayerName } )
|
||||||
self.PLAYERS[PlayerName] = UnitName
|
self.PLAYERS[PlayerName] = UnitName
|
||||||
self.PLAYERUNITS[UnitName] = PlayerName
|
self.PLAYERUNITS[PlayerName] = self:FindUnit( UnitName )
|
||||||
self.PLAYERSJOINED[PlayerName] = PlayerName
|
self.PLAYERSJOINED[PlayerName] = PlayerName
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -348,10 +337,48 @@ function DATABASE:DeletePlayer( UnitName, PlayerName )
|
|||||||
if PlayerName then
|
if PlayerName then
|
||||||
self:E( { "Clean player:", PlayerName } )
|
self:E( { "Clean player:", PlayerName } )
|
||||||
self.PLAYERS[PlayerName] = nil
|
self.PLAYERS[PlayerName] = nil
|
||||||
self.PLAYERUNITS[UnitName] = PlayerName
|
self.PLAYERUNITS[PlayerName] = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Get the player table from the DATABASE.
|
||||||
|
-- The player table contains all unit names with the key the name of the player (PlayerName).
|
||||||
|
-- @param #DATABASE self
|
||||||
|
-- @usage
|
||||||
|
-- local Players = _DATABASE:GetPlayers()
|
||||||
|
-- for PlayerName, UnitName in pairs( Players ) do
|
||||||
|
-- ..
|
||||||
|
-- end
|
||||||
|
function DATABASE:GetPlayers()
|
||||||
|
return self.PLAYERS
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Get the player table from the DATABASE, which contains all UNIT objects.
|
||||||
|
-- The player table contains all UNIT objects of the player with the key the name of the player (PlayerName).
|
||||||
|
-- @param #DATABASE self
|
||||||
|
-- @usage
|
||||||
|
-- local PlayerUnits = _DATABASE:GetPlayerUnits()
|
||||||
|
-- for PlayerName, PlayerUnit in pairs( PlayerUnits ) do
|
||||||
|
-- ..
|
||||||
|
-- end
|
||||||
|
function DATABASE:GetPlayerUnits()
|
||||||
|
return self.PLAYERUNITS
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Get the player table from the DATABASE which have joined in the mission historically.
|
||||||
|
-- The player table contains all UNIT objects with the key the name of the player (PlayerName).
|
||||||
|
-- @param #DATABASE self
|
||||||
|
-- @usage
|
||||||
|
-- local PlayersJoined = _DATABASE:GetPlayersJoined()
|
||||||
|
-- for PlayerName, PlayerUnit in pairs( PlayersJoined ) do
|
||||||
|
-- ..
|
||||||
|
-- end
|
||||||
|
function DATABASE:GetPlayersJoined()
|
||||||
|
return self.PLAYERSJOINED
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Instantiate new Groups within the DCSRTE.
|
--- 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:
|
-- This method expects EXACTLY the same structure as a structure within the ME, and needs 2 additional fields defined:
|
||||||
@@ -415,10 +442,13 @@ end
|
|||||||
--- Private method that registers new Group Templates within the DATABASE Object.
|
--- Private method that registers new Group Templates within the DATABASE Object.
|
||||||
-- @param #DATABASE self
|
-- @param #DATABASE self
|
||||||
-- @param #table GroupTemplate
|
-- @param #table GroupTemplate
|
||||||
|
-- @param Dcs.DCScoalition#coalition.side CoalitionSide The coalition.side of the object.
|
||||||
|
-- @param Dcs.DCSObject#Object.Category CategoryID The Object.category of the object.
|
||||||
|
-- @param Dcs.DCScountry#country.id CountryID the country.id of the object
|
||||||
-- @return #DATABASE self
|
-- @return #DATABASE self
|
||||||
function DATABASE:_RegisterGroupTemplate( GroupTemplate, CoalitionID, CategoryID, CountryID )
|
function DATABASE:_RegisterGroupTemplate( GroupTemplate, CoalitionSide, CategoryID, CountryID, GroupName )
|
||||||
|
|
||||||
local GroupTemplateName = env.getValueDictByKey(GroupTemplate.name)
|
local GroupTemplateName = GroupName or env.getValueDictByKey( GroupTemplate.name )
|
||||||
|
|
||||||
local TraceTable = {}
|
local TraceTable = {}
|
||||||
|
|
||||||
@@ -433,7 +463,7 @@ function DATABASE:_RegisterGroupTemplate( GroupTemplate, CoalitionID, CategoryID
|
|||||||
end
|
end
|
||||||
|
|
||||||
GroupTemplate.CategoryID = CategoryID
|
GroupTemplate.CategoryID = CategoryID
|
||||||
GroupTemplate.CoalitionID = CoalitionID
|
GroupTemplate.CoalitionID = CoalitionSide
|
||||||
GroupTemplate.CountryID = CountryID
|
GroupTemplate.CountryID = CountryID
|
||||||
|
|
||||||
self.Templates.Groups[GroupTemplateName].GroupName = GroupTemplateName
|
self.Templates.Groups[GroupTemplateName].GroupName = GroupTemplateName
|
||||||
@@ -442,7 +472,7 @@ function DATABASE:_RegisterGroupTemplate( GroupTemplate, CoalitionID, CategoryID
|
|||||||
self.Templates.Groups[GroupTemplateName].UnitCount = #GroupTemplate.units
|
self.Templates.Groups[GroupTemplateName].UnitCount = #GroupTemplate.units
|
||||||
self.Templates.Groups[GroupTemplateName].Units = GroupTemplate.units
|
self.Templates.Groups[GroupTemplateName].Units = GroupTemplate.units
|
||||||
self.Templates.Groups[GroupTemplateName].CategoryID = CategoryID
|
self.Templates.Groups[GroupTemplateName].CategoryID = CategoryID
|
||||||
self.Templates.Groups[GroupTemplateName].CoalitionID = CoalitionID
|
self.Templates.Groups[GroupTemplateName].CoalitionID = CoalitionSide
|
||||||
self.Templates.Groups[GroupTemplateName].CountryID = CountryID
|
self.Templates.Groups[GroupTemplateName].CountryID = CountryID
|
||||||
|
|
||||||
|
|
||||||
@@ -469,13 +499,13 @@ function DATABASE:_RegisterGroupTemplate( GroupTemplate, CoalitionID, CategoryID
|
|||||||
self.Templates.Units[UnitTemplate.name].GroupTemplate = GroupTemplate
|
self.Templates.Units[UnitTemplate.name].GroupTemplate = GroupTemplate
|
||||||
self.Templates.Units[UnitTemplate.name].GroupId = GroupTemplate.groupId
|
self.Templates.Units[UnitTemplate.name].GroupId = GroupTemplate.groupId
|
||||||
self.Templates.Units[UnitTemplate.name].CategoryID = CategoryID
|
self.Templates.Units[UnitTemplate.name].CategoryID = CategoryID
|
||||||
self.Templates.Units[UnitTemplate.name].CoalitionID = CoalitionID
|
self.Templates.Units[UnitTemplate.name].CoalitionID = CoalitionSide
|
||||||
self.Templates.Units[UnitTemplate.name].CountryID = CountryID
|
self.Templates.Units[UnitTemplate.name].CountryID = CountryID
|
||||||
|
|
||||||
if UnitTemplate.skill and (UnitTemplate.skill == "Client" or UnitTemplate.skill == "Player") then
|
if UnitTemplate.skill and (UnitTemplate.skill == "Client" or UnitTemplate.skill == "Player") then
|
||||||
self.Templates.ClientsByName[UnitTemplate.name] = UnitTemplate
|
self.Templates.ClientsByName[UnitTemplate.name] = UnitTemplate
|
||||||
self.Templates.ClientsByName[UnitTemplate.name].CategoryID = CategoryID
|
self.Templates.ClientsByName[UnitTemplate.name].CategoryID = CategoryID
|
||||||
self.Templates.ClientsByName[UnitTemplate.name].CoalitionID = CoalitionID
|
self.Templates.ClientsByName[UnitTemplate.name].CoalitionID = CoalitionSide
|
||||||
self.Templates.ClientsByName[UnitTemplate.name].CountryID = CountryID
|
self.Templates.ClientsByName[UnitTemplate.name].CountryID = CountryID
|
||||||
self.Templates.ClientsByID[UnitTemplate.unitId] = UnitTemplate
|
self.Templates.ClientsByID[UnitTemplate.unitId] = UnitTemplate
|
||||||
end
|
end
|
||||||
@@ -519,7 +549,7 @@ function DATABASE:_RegisterStaticTemplate( StaticTemplate, CoalitionID, Category
|
|||||||
|
|
||||||
|
|
||||||
TraceTable[#TraceTable+1] = "Static"
|
TraceTable[#TraceTable+1] = "Static"
|
||||||
TraceTable[#TraceTable+1] = self.Templates.Statics[StaticTemplateName].GroupName
|
TraceTable[#TraceTable+1] = self.Templates.Statics[StaticTemplateName].StaticName
|
||||||
|
|
||||||
TraceTable[#TraceTable+1] = "Coalition"
|
TraceTable[#TraceTable+1] = "Coalition"
|
||||||
TraceTable[#TraceTable+1] = self.Templates.Statics[StaticTemplateName].CoalitionID
|
TraceTable[#TraceTable+1] = self.Templates.Statics[StaticTemplateName].CoalitionID
|
||||||
@@ -646,6 +676,7 @@ end
|
|||||||
function DATABASE:_RegisterStatics()
|
function DATABASE:_RegisterStatics()
|
||||||
|
|
||||||
local CoalitionsData = { GroupsRed = coalition.getStaticObjects( coalition.side.RED ), GroupsBlue = coalition.getStaticObjects( coalition.side.BLUE ) }
|
local CoalitionsData = { GroupsRed = coalition.getStaticObjects( coalition.side.RED ), GroupsBlue = coalition.getStaticObjects( coalition.side.BLUE ) }
|
||||||
|
self:E( { Statics = CoalitionsData } )
|
||||||
for CoalitionId, CoalitionData in pairs( CoalitionsData ) do
|
for CoalitionId, CoalitionData in pairs( CoalitionsData ) do
|
||||||
for DCSStaticId, DCSStatic in pairs( CoalitionData ) do
|
for DCSStaticId, DCSStatic in pairs( CoalitionData ) do
|
||||||
|
|
||||||
@@ -698,7 +729,21 @@ function DATABASE:_EventOnBirth( Event )
|
|||||||
self:AddGroup( Event.IniDCSGroupName )
|
self:AddGroup( Event.IniDCSGroupName )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
--self:_EventOnPlayerEnterUnit( Event )
|
if Event.IniObjectCategory == 1 then
|
||||||
|
Event.IniUnit = self:FindUnit( Event.IniDCSUnitName )
|
||||||
|
Event.IniGroup = self:FindGroup( Event.IniDCSGroupName )
|
||||||
|
local PlayerName = Event.IniUnit:GetPlayerName()
|
||||||
|
self:E( { "PlayerName:", PlayerName } )
|
||||||
|
if PlayerName ~= "" then
|
||||||
|
self:E( { "Player Joined:", PlayerName } )
|
||||||
|
if not self.PLAYERS[PlayerName] then
|
||||||
|
self:AddPlayer( Event.IniUnitName, PlayerName )
|
||||||
|
end
|
||||||
|
local Settings = SETTINGS:Set( PlayerName )
|
||||||
|
Settings:SetPlayerMenu( Event.IniUnit )
|
||||||
|
--MENU_INDEX:Refresh( Event.IniGroup )
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -722,6 +767,8 @@ function DATABASE:_EventOnDeadOrCrash( Event )
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
self:AccountDestroys( Event )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@@ -731,13 +778,14 @@ end
|
|||||||
function DATABASE:_EventOnPlayerEnterUnit( Event )
|
function DATABASE:_EventOnPlayerEnterUnit( Event )
|
||||||
self:F2( { Event } )
|
self:F2( { Event } )
|
||||||
|
|
||||||
if Event.IniUnit then
|
if Event.IniDCSUnit then
|
||||||
if Event.IniObjectCategory == 1 then
|
if Event.IniObjectCategory == 1 then
|
||||||
self:AddUnit( Event.IniDCSUnitName )
|
self:AddUnit( Event.IniDCSUnitName )
|
||||||
|
Event.IniUnit = self:FindUnit( Event.IniDCSUnitName )
|
||||||
self:AddGroup( Event.IniDCSGroupName )
|
self:AddGroup( Event.IniDCSGroupName )
|
||||||
local PlayerName = Event.IniUnit:GetPlayerName()
|
local PlayerName = Event.IniDCSUnit:getPlayerName()
|
||||||
if not self.PLAYERS[PlayerName] then
|
if not self.PLAYERS[PlayerName] then
|
||||||
self:AddPlayer( Event.IniUnitName, PlayerName )
|
self:AddPlayer( Event.IniDCSUnitName, PlayerName )
|
||||||
end
|
end
|
||||||
local Settings = SETTINGS:Set( PlayerName )
|
local Settings = SETTINGS:Set( PlayerName )
|
||||||
Settings:SetPlayerMenu( Event.IniUnit )
|
Settings:SetPlayerMenu( Event.IniUnit )
|
||||||
@@ -756,6 +804,7 @@ function DATABASE:_EventOnPlayerLeaveUnit( Event )
|
|||||||
if Event.IniObjectCategory == 1 then
|
if Event.IniObjectCategory == 1 then
|
||||||
local PlayerName = Event.IniUnit:GetPlayerName()
|
local PlayerName = Event.IniUnit:GetPlayerName()
|
||||||
if self.PLAYERS[PlayerName] then
|
if self.PLAYERS[PlayerName] then
|
||||||
|
self:E( { "Player Left:", PlayerName } )
|
||||||
local Settings = SETTINGS:Set( PlayerName )
|
local Settings = SETTINGS:Set( PlayerName )
|
||||||
Settings:RemovePlayerMenu( Event.IniUnit )
|
Settings:RemovePlayerMenu( Event.IniUnit )
|
||||||
self:DeletePlayer( Event.IniUnit, PlayerName )
|
self:DeletePlayer( Event.IniUnit, PlayerName )
|
||||||
@@ -1053,6 +1102,101 @@ function DATABASE:_RegisterTemplates()
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Account the Hits of the Players.
|
||||||
|
-- @param #DATABASE self
|
||||||
|
-- @param Core.Event#EVENTDATA Event
|
||||||
|
function DATABASE:AccountHits( Event )
|
||||||
|
self:F( { Event } )
|
||||||
|
|
||||||
|
if Event.IniPlayerName ~= nil then -- It is a player that is hitting something
|
||||||
|
self:T( "Hitting Something" )
|
||||||
|
|
||||||
|
-- What is he hitting?
|
||||||
|
if Event.TgtCategory then
|
||||||
|
|
||||||
|
-- A target got hit
|
||||||
|
self.HITS[Event.TgtUnitName] = self.HITS[Event.TgtUnitName] or {}
|
||||||
|
local Hit = self.HITS[Event.TgtUnitName]
|
||||||
|
|
||||||
|
Hit.Players = Hit.Players or {}
|
||||||
|
Hit.Players[Event.IniPlayerName] = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- It is a weapon initiated by a player, that is hitting something
|
||||||
|
-- This seems to occur only with scenery and static objects.
|
||||||
|
if Event.WeaponPlayerName ~= nil then
|
||||||
|
self:T( "Hitting Scenery" )
|
||||||
|
|
||||||
|
-- What is he hitting?
|
||||||
|
if Event.TgtCategory then
|
||||||
|
|
||||||
|
if Event.IniCoalition then -- A coalition object was hit, probably a static.
|
||||||
|
-- A target got hit
|
||||||
|
self.HITS[Event.TgtUnitName] = self.HITS[Event.TgtUnitName] or {}
|
||||||
|
local Hit = self.HITS[Event.TgtUnitName]
|
||||||
|
|
||||||
|
Hit.Players = Hit.Players or {}
|
||||||
|
Hit.Players[Event.WeaponPlayerName] = true
|
||||||
|
else -- A scenery object was hit.
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Account the destroys.
|
||||||
|
-- @param #DATABASE self
|
||||||
|
-- @param Core.Event#EVENTDATA Event
|
||||||
|
function DATABASE:AccountDestroys( Event )
|
||||||
|
self:F( { Event } )
|
||||||
|
|
||||||
|
local TargetUnit = nil
|
||||||
|
local TargetGroup = nil
|
||||||
|
local TargetUnitName = ""
|
||||||
|
local TargetGroupName = ""
|
||||||
|
local TargetPlayerName = ""
|
||||||
|
local TargetCoalition = nil
|
||||||
|
local TargetCategory = nil
|
||||||
|
local TargetType = nil
|
||||||
|
local TargetUnitCoalition = nil
|
||||||
|
local TargetUnitCategory = nil
|
||||||
|
local TargetUnitType = nil
|
||||||
|
|
||||||
|
if Event.IniDCSUnit then
|
||||||
|
|
||||||
|
TargetUnit = Event.IniUnit
|
||||||
|
TargetUnitName = Event.IniDCSUnitName
|
||||||
|
TargetGroup = Event.IniDCSGroup
|
||||||
|
TargetGroupName = Event.IniDCSGroupName
|
||||||
|
TargetPlayerName = Event.IniPlayerName
|
||||||
|
|
||||||
|
TargetCoalition = Event.IniCoalition
|
||||||
|
--TargetCategory = TargetUnit:getCategory()
|
||||||
|
--TargetCategory = TargetUnit:getDesc().category -- Workaround
|
||||||
|
TargetCategory = Event.IniCategory
|
||||||
|
TargetType = Event.IniTypeName
|
||||||
|
|
||||||
|
TargetUnitType = TargetType
|
||||||
|
|
||||||
|
self:T( { TargetUnitName, TargetGroupName, TargetPlayerName, TargetCoalition, TargetCategory, TargetType } )
|
||||||
|
end
|
||||||
|
|
||||||
|
self:T( "Something got destroyed" )
|
||||||
|
|
||||||
|
local Destroyed = false
|
||||||
|
|
||||||
|
-- What is the player destroying?
|
||||||
|
if self.HITS[Event.IniUnitName] then -- Was there a hit for this unit for this player before registered???
|
||||||
|
|
||||||
|
|
||||||
|
self.DESTROYS[Event.IniUnitName] = self.DESTROYS[Event.IniUnitName] or {}
|
||||||
|
|
||||||
|
self.DESTROYS[Event.IniUnitName] = true
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -159,10 +159,10 @@
|
|||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
-- ### Author: **Sven Van de Velde (FlightControl)**
|
-- ### Author: **FlightControl**
|
||||||
-- ### Contributions:
|
-- ### Contributions:
|
||||||
--
|
--
|
||||||
-- ====
|
-- ===
|
||||||
--
|
--
|
||||||
-- @module Event
|
-- @module Event
|
||||||
|
|
||||||
@@ -472,7 +472,7 @@ end
|
|||||||
-- @return #EVENT.Events
|
-- @return #EVENT.Events
|
||||||
function EVENT:Reset( EventObject ) --R2.1
|
function EVENT:Reset( EventObject ) --R2.1
|
||||||
|
|
||||||
self:E( { "Resetting subscriptions for class: ", EventObject:GetClassNameAndID() } )
|
self:F( { "Resetting subscriptions for class: ", EventObject:GetClassNameAndID() } )
|
||||||
|
|
||||||
local EventPriority = EventObject:GetEventPriority()
|
local EventPriority = EventObject:GetEventPriority()
|
||||||
for EventID, EventData in pairs( self.Events ) do
|
for EventID, EventData in pairs( self.Events ) do
|
||||||
@@ -562,7 +562,6 @@ end
|
|||||||
-- @param EventID
|
-- @param EventID
|
||||||
-- @return #EVENT
|
-- @return #EVENT
|
||||||
function EVENT:OnEventForGroup( GroupName, EventFunction, EventClass, EventID, ... )
|
function EVENT:OnEventForGroup( GroupName, EventFunction, EventClass, EventID, ... )
|
||||||
self:E( GroupName )
|
|
||||||
|
|
||||||
local Event = self:Init( EventID, EventClass )
|
local Event = self:Init( EventID, EventClass )
|
||||||
Event.EventGroup = true
|
Event.EventGroup = true
|
||||||
@@ -734,7 +733,7 @@ function EVENT:onEvent( Event )
|
|||||||
local ErrorHandler = function( errmsg )
|
local ErrorHandler = function( errmsg )
|
||||||
|
|
||||||
env.info( "Error in SCHEDULER function:" .. errmsg )
|
env.info( "Error in SCHEDULER function:" .. errmsg )
|
||||||
if debug ~= nil then
|
if BASE.Debug ~= nil then
|
||||||
env.info( debug.traceback() )
|
env.info( debug.traceback() )
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -744,13 +743,15 @@ function EVENT:onEvent( Event )
|
|||||||
|
|
||||||
local EventMeta = _EVENTMETA[Event.id]
|
local EventMeta = _EVENTMETA[Event.id]
|
||||||
|
|
||||||
|
--self:E( { EventMeta.Text, Event } ) -- Activate the see all incoming events ...
|
||||||
|
|
||||||
if self and
|
if self and
|
||||||
self.Events and
|
self.Events and
|
||||||
self.Events[Event.id] and
|
self.Events[Event.id] and
|
||||||
( Event.initiator ~= nil or ( Event.initiator == nil and Event.id ~= EVENTS.PlayerLeaveUnit ) ) then
|
( Event.initiator ~= nil or ( Event.initiator == nil and Event.id ~= EVENTS.PlayerLeaveUnit ) ) then
|
||||||
|
|
||||||
if Event.initiator then
|
if Event.initiator then
|
||||||
|
|
||||||
Event.IniObjectCategory = Event.initiator:getCategory()
|
Event.IniObjectCategory = Event.initiator:getCategory()
|
||||||
|
|
||||||
if Event.IniObjectCategory == Object.Category.UNIT then
|
if Event.IniObjectCategory == Object.Category.UNIT then
|
||||||
@@ -825,7 +826,7 @@ function EVENT:onEvent( Event )
|
|||||||
Event.TgtDCSUnit = Event.target
|
Event.TgtDCSUnit = Event.target
|
||||||
Event.TgtDCSUnitName = Event.TgtDCSUnit:getName()
|
Event.TgtDCSUnitName = Event.TgtDCSUnit:getName()
|
||||||
Event.TgtUnitName = Event.TgtDCSUnitName
|
Event.TgtUnitName = Event.TgtDCSUnitName
|
||||||
Event.TgtUnit = STATIC:FindByName( Event.TgtDCSUnitName )
|
Event.TgtUnit = STATIC:FindByName( Event.TgtDCSUnitName, false )
|
||||||
Event.TgtCoalition = Event.TgtDCSUnit:getCoalition()
|
Event.TgtCoalition = Event.TgtDCSUnit:getCoalition()
|
||||||
Event.TgtCategory = Event.TgtDCSUnit:getDesc().category
|
Event.TgtCategory = Event.TgtDCSUnit:getDesc().category
|
||||||
Event.TgtTypeName = Event.TgtDCSUnit:getTypeName()
|
Event.TgtTypeName = Event.TgtDCSUnit:getTypeName()
|
||||||
@@ -884,6 +885,7 @@ function EVENT:onEvent( Event )
|
|||||||
|
|
||||||
-- So now the EventClass must be a UNIT class!!! We check if it is still "Alive".
|
-- So now the EventClass must be a UNIT class!!! We check if it is still "Alive".
|
||||||
if EventClass:IsAlive() or
|
if EventClass:IsAlive() or
|
||||||
|
Event.id == EVENTS.PlayerEnterUnit or
|
||||||
Event.id == EVENTS.Crash or
|
Event.id == EVENTS.Crash or
|
||||||
Event.id == EVENTS.Dead then
|
Event.id == EVENTS.Dead then
|
||||||
|
|
||||||
@@ -896,7 +898,7 @@ function EVENT:onEvent( Event )
|
|||||||
if EventData.EventFunction then
|
if EventData.EventFunction then
|
||||||
|
|
||||||
if Event.IniObjectCategory ~= 3 then
|
if Event.IniObjectCategory ~= 3 then
|
||||||
self:E( { "Calling EventFunction for UNIT ", EventClass:GetClassNameAndID(), ", Unit ", Event.IniUnitName, EventPriority } )
|
self:F( { "Calling EventFunction for UNIT ", EventClass:GetClassNameAndID(), ", Unit ", Event.IniUnitName, EventPriority } )
|
||||||
end
|
end
|
||||||
|
|
||||||
local Result, Value = xpcall(
|
local Result, Value = xpcall(
|
||||||
@@ -912,7 +914,7 @@ function EVENT:onEvent( Event )
|
|||||||
|
|
||||||
-- Now call the default event function.
|
-- Now call the default event function.
|
||||||
if Event.IniObjectCategory ~= 3 then
|
if Event.IniObjectCategory ~= 3 then
|
||||||
self:E( { "Calling " .. EventMeta.Event .. " for Class ", EventClass:GetClassNameAndID(), EventPriority } )
|
self:F( { "Calling " .. EventMeta.Event .. " for Class ", EventClass:GetClassNameAndID(), EventPriority } )
|
||||||
end
|
end
|
||||||
|
|
||||||
local Result, Value = xpcall(
|
local Result, Value = xpcall(
|
||||||
@@ -933,6 +935,7 @@ function EVENT:onEvent( Event )
|
|||||||
|
|
||||||
-- So now the EventClass must be a GROUP class!!! We check if it is still "Alive".
|
-- So now the EventClass must be a GROUP class!!! We check if it is still "Alive".
|
||||||
if EventClass:IsAlive() or
|
if EventClass:IsAlive() or
|
||||||
|
Event.id == EVENTS.PlayerEnterUnit or
|
||||||
Event.id == EVENTS.Crash or
|
Event.id == EVENTS.Crash or
|
||||||
Event.id == EVENTS.Dead then
|
Event.id == EVENTS.Dead then
|
||||||
|
|
||||||
@@ -946,7 +949,7 @@ function EVENT:onEvent( Event )
|
|||||||
if EventData.EventFunction then
|
if EventData.EventFunction then
|
||||||
|
|
||||||
if Event.IniObjectCategory ~= 3 then
|
if Event.IniObjectCategory ~= 3 then
|
||||||
self:E( { "Calling EventFunction for GROUP ", EventClass:GetClassNameAndID(), ", Unit ", Event.IniUnitName, EventPriority } )
|
self:F( { "Calling EventFunction for GROUP ", EventClass:GetClassNameAndID(), ", Unit ", Event.IniUnitName, EventPriority } )
|
||||||
end
|
end
|
||||||
|
|
||||||
local Result, Value = xpcall(
|
local Result, Value = xpcall(
|
||||||
@@ -962,7 +965,7 @@ function EVENT:onEvent( Event )
|
|||||||
|
|
||||||
-- Now call the default event function.
|
-- Now call the default event function.
|
||||||
if Event.IniObjectCategory ~= 3 then
|
if Event.IniObjectCategory ~= 3 then
|
||||||
self:E( { "Calling " .. EventMeta.Event .. " for GROUP ", EventClass:GetClassNameAndID(), EventPriority } )
|
self:F( { "Calling " .. EventMeta.Event .. " for GROUP ", EventClass:GetClassNameAndID(), EventPriority } )
|
||||||
end
|
end
|
||||||
|
|
||||||
local Result, Value = xpcall(
|
local Result, Value = xpcall(
|
||||||
@@ -1019,7 +1022,7 @@ function EVENT:onEvent( Event )
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
self:E( { EventMeta.Text, Event } )
|
self:T( { EventMeta.Text, Event } )
|
||||||
end
|
end
|
||||||
|
|
||||||
Event = nil
|
Event = nil
|
||||||
|
|||||||
@@ -56,13 +56,13 @@
|
|||||||
-- * @{#FSM_SET}: Models Finite State Machines for @{Set}s. Note that these FSMs control multiple objects!!! So State concerns here
|
-- * @{#FSM_SET}: Models Finite State Machines for @{Set}s. Note that these FSMs control multiple objects!!! So State concerns here
|
||||||
-- for multiple objects or the position of the state machine in the process.
|
-- for multiple objects or the position of the state machine in the process.
|
||||||
--
|
--
|
||||||
-- ====
|
-- ===
|
||||||
--
|
--
|
||||||
--
|
--
|
||||||
-- ### Author: **Sven Van de Velde (FlightControl)**
|
-- ### Author: **FlightControl**
|
||||||
-- ### Contributions:
|
-- ### Contributions:
|
||||||
--
|
--
|
||||||
-- ====
|
-- ===
|
||||||
--
|
--
|
||||||
-- @module Fsm
|
-- @module Fsm
|
||||||
|
|
||||||
@@ -562,8 +562,8 @@ do -- FSM
|
|||||||
local ErrorHandler = function( errmsg )
|
local ErrorHandler = function( errmsg )
|
||||||
|
|
||||||
env.info( "Error in SCHEDULER function:" .. errmsg )
|
env.info( "Error in SCHEDULER function:" .. errmsg )
|
||||||
if debug ~= nil then
|
if BASE.Debug ~= nil then
|
||||||
env.info( debug.traceback() )
|
env.info( BASE.Debug.traceback() )
|
||||||
end
|
end
|
||||||
|
|
||||||
return errmsg
|
return errmsg
|
||||||
@@ -860,8 +860,8 @@ do -- FSM_CONTROLLABLE
|
|||||||
local ErrorHandler = function( errmsg )
|
local ErrorHandler = function( errmsg )
|
||||||
|
|
||||||
env.info( "Error in SCHEDULER function:" .. errmsg )
|
env.info( "Error in SCHEDULER function:" .. errmsg )
|
||||||
if debug ~= nil then
|
if BASE.Debug ~= nil then
|
||||||
env.info( debug.traceback() )
|
env.info( BASE.Debug.traceback() )
|
||||||
end
|
end
|
||||||
|
|
||||||
return errmsg
|
return errmsg
|
||||||
@@ -920,8 +920,8 @@ do -- FSM_PROCESS
|
|||||||
local ErrorHandler = function( errmsg )
|
local ErrorHandler = function( errmsg )
|
||||||
|
|
||||||
env.info( "Error in FSM_PROCESS call handler:" .. errmsg )
|
env.info( "Error in FSM_PROCESS call handler:" .. errmsg )
|
||||||
if debug ~= nil then
|
if BASE.Debug ~= nil then
|
||||||
env.info( debug.traceback() )
|
env.info( BASE.Debug.traceback() )
|
||||||
end
|
end
|
||||||
|
|
||||||
return errmsg
|
return errmsg
|
||||||
|
|||||||
146
Moose Development/Moose/Core/Goal.lua
Normal file
146
Moose Development/Moose/Core/Goal.lua
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
--- **Core (WIP)** -- Base class to allow the modeling of processes to achieve Goals.
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- GOAL models processes that have an objective with a defined achievement. Derived classes implement the ways how the achievements can be realized.
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- ### Author: **FlightControl**
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- @module Goal
|
||||||
|
|
||||||
|
do -- Goal
|
||||||
|
|
||||||
|
--- @type GOAL
|
||||||
|
-- @extends Core.Fsm#FSM
|
||||||
|
|
||||||
|
|
||||||
|
--- # GOAL class, extends @{Fsm#FSM}
|
||||||
|
--
|
||||||
|
-- GOAL models processes that have an objective with a defined achievement. Derived classes implement the ways how the achievements can be realized.
|
||||||
|
--
|
||||||
|
-- ## 1. GOAL constructor
|
||||||
|
--
|
||||||
|
-- * @{#GOAL.New}(): Creates a new GOAL object.
|
||||||
|
--
|
||||||
|
-- ## 2. GOAL is a finite state machine (FSM).
|
||||||
|
--
|
||||||
|
-- ### 2.1 GOAL States
|
||||||
|
--
|
||||||
|
-- * **Pending**: The goal object is in progress.
|
||||||
|
-- * **Achieved**: The goal objective is Achieved.
|
||||||
|
--
|
||||||
|
-- ### 2.2 GOAL Events
|
||||||
|
--
|
||||||
|
-- * **Achieved**: Set the goal objective to Achieved.
|
||||||
|
--
|
||||||
|
-- @field #GOAL
|
||||||
|
GOAL = {
|
||||||
|
ClassName = "GOAL",
|
||||||
|
}
|
||||||
|
|
||||||
|
--- @field #table GOAL.Players
|
||||||
|
GOAL.Players = {}
|
||||||
|
|
||||||
|
--- @field #number GOAL.TotalContributions
|
||||||
|
GOAL.TotalContributions = 0
|
||||||
|
|
||||||
|
--- GOAL Constructor.
|
||||||
|
-- @param #GOAL self
|
||||||
|
-- @return #GOAL
|
||||||
|
function GOAL:New()
|
||||||
|
|
||||||
|
local self = BASE:Inherit( self, FSM:New() ) -- #GOAL
|
||||||
|
self:F( {} )
|
||||||
|
|
||||||
|
--- Achieved State for GOAL
|
||||||
|
-- @field GOAL.Achieved
|
||||||
|
|
||||||
|
--- Achieved State Handler OnLeave for GOAL
|
||||||
|
-- @function [parent=#GOAL] OnLeaveAchieved
|
||||||
|
-- @param #GOAL self
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string To
|
||||||
|
-- @return #boolean
|
||||||
|
|
||||||
|
--- Achieved State Handler OnEnter for GOAL
|
||||||
|
-- @function [parent=#GOAL] OnEnterAchieved
|
||||||
|
-- @param #GOAL self
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string To
|
||||||
|
|
||||||
|
|
||||||
|
self:SetStartState( "Pending" )
|
||||||
|
self:AddTransition( "*", "Achieved", "Achieved" )
|
||||||
|
|
||||||
|
--- Achieved Handler OnBefore for GOAL
|
||||||
|
-- @function [parent=#GOAL] OnBeforeAchieved
|
||||||
|
-- @param #GOAL self
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string To
|
||||||
|
-- @return #boolean
|
||||||
|
|
||||||
|
--- Achieved Handler OnAfter for GOAL
|
||||||
|
-- @function [parent=#GOAL] OnAfterAchieved
|
||||||
|
-- @param #GOAL self
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string To
|
||||||
|
|
||||||
|
--- Achieved Trigger for GOAL
|
||||||
|
-- @function [parent=#GOAL] Achieved
|
||||||
|
-- @param #GOAL self
|
||||||
|
|
||||||
|
--- Achieved Asynchronous Trigger for GOAL
|
||||||
|
-- @function [parent=#GOAL] __Achieved
|
||||||
|
-- @param #GOAL self
|
||||||
|
-- @param #number Delay
|
||||||
|
|
||||||
|
self:SetEventPriority( 5 )
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- @param #GOAL self
|
||||||
|
-- @param #string PlayerName
|
||||||
|
function GOAL:AddPlayerContribution( PlayerName )
|
||||||
|
self.Players[PlayerName] = self.Players[PlayerName] or 0
|
||||||
|
self.Players[PlayerName] = self.Players[PlayerName] + 1
|
||||||
|
self.TotalContributions = self.TotalContributions + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- @param #GOAL self
|
||||||
|
-- @param #number Player contribution.
|
||||||
|
function GOAL:GetPlayerContribution( PlayerName )
|
||||||
|
return self.Players[PlayerName] or 0
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- @param #GOAL self
|
||||||
|
function GOAL:GetPlayerContributions()
|
||||||
|
return self.Players or {}
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- @param #GOAL self
|
||||||
|
function GOAL:GetTotalContributions()
|
||||||
|
return self.TotalContributions or 0
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--- @param #GOAL self
|
||||||
|
-- @return #boolean true if the goal is Achieved
|
||||||
|
function GOAL:IsAchieved()
|
||||||
|
return self:Is( "Achieved" )
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -39,12 +39,12 @@
|
|||||||
-- * To all players using @{Message#MESSAGE.ToAllIf}().
|
-- * To all players using @{Message#MESSAGE.ToAllIf}().
|
||||||
-- * To a coalition using @{Message#MESSAGE.ToCoalitionIf}().
|
-- * To a coalition using @{Message#MESSAGE.ToCoalitionIf}().
|
||||||
--
|
--
|
||||||
-- ====
|
-- ===
|
||||||
--
|
--
|
||||||
-- ### Author: **Sven Van de Velde (FlightControl)**
|
-- ### Author: **FlightControl**
|
||||||
-- ### Contributions:
|
-- ### Contributions:
|
||||||
--
|
--
|
||||||
-- ====
|
-- ===
|
||||||
--
|
--
|
||||||
-- @field #MESSAGE
|
-- @field #MESSAGE
|
||||||
MESSAGE = {
|
MESSAGE = {
|
||||||
@@ -167,7 +167,7 @@ function MESSAGE:ToClient( Client, Settings )
|
|||||||
if self.MessageType then
|
if self.MessageType then
|
||||||
local Settings = Settings or ( Client and _DATABASE:GetPlayerSettings( Client:GetPlayerName() ) ) or _SETTINGS -- Core.Settings#SETTINGS
|
local Settings = Settings or ( Client and _DATABASE:GetPlayerSettings( Client:GetPlayerName() ) ) or _SETTINGS -- Core.Settings#SETTINGS
|
||||||
self.MessageDuration = Settings:GetMessageTime( self.MessageType )
|
self.MessageDuration = Settings:GetMessageTime( self.MessageType )
|
||||||
self.MessageCategory = self.MessageType .. ": "
|
self.MessageCategory = "" -- self.MessageType .. ": "
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.MessageDuration ~= 0 then
|
if self.MessageDuration ~= 0 then
|
||||||
@@ -192,7 +192,7 @@ function MESSAGE:ToGroup( Group, Settings )
|
|||||||
if self.MessageType then
|
if self.MessageType then
|
||||||
local Settings = Settings or ( Group and _DATABASE:GetPlayerSettings( Group:GetPlayerName() ) ) or _SETTINGS -- Core.Settings#SETTINGS
|
local Settings = Settings or ( Group and _DATABASE:GetPlayerSettings( Group:GetPlayerName() ) ) or _SETTINGS -- Core.Settings#SETTINGS
|
||||||
self.MessageDuration = Settings:GetMessageTime( self.MessageType )
|
self.MessageDuration = Settings:GetMessageTime( self.MessageType )
|
||||||
self.MessageCategory = self.MessageType .. ": "
|
self.MessageCategory = "" -- self.MessageType .. ": "
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.MessageDuration ~= 0 then
|
if self.MessageDuration ~= 0 then
|
||||||
@@ -259,13 +259,13 @@ function MESSAGE:ToCoalition( CoalitionSide, Settings )
|
|||||||
if self.MessageType then
|
if self.MessageType then
|
||||||
local Settings = Settings or _SETTINGS -- Core.Settings#SETTINGS
|
local Settings = Settings or _SETTINGS -- Core.Settings#SETTINGS
|
||||||
self.MessageDuration = Settings:GetMessageTime( self.MessageType )
|
self.MessageDuration = Settings:GetMessageTime( self.MessageType )
|
||||||
self.MessageCategory = self.MessageType .. ": "
|
self.MessageCategory = "" -- self.MessageType .. ": "
|
||||||
end
|
end
|
||||||
|
|
||||||
if CoalitionSide then
|
if CoalitionSide then
|
||||||
if self.MessageDuration ~= 0 then
|
if self.MessageDuration ~= 0 then
|
||||||
self:T( self.MessageCategory .. self.MessageText:gsub("\n$",""):gsub("\n$","") .. " / " .. self.MessageDuration )
|
self:T( self.MessageCategory .. self.MessageText:gsub("\n$",""):gsub("\n$","") .. " / " .. self.MessageDuration )
|
||||||
trigger.action.outTextForCoalition( CoalitionSide, self.MessageCategory .. self.MessageText:gsub("\n$",""):gsub("\n$",""), self.MessageDuration )
|
trigger.action.outTextForCoalition( CoalitionSide, self.MessageText:gsub("\n$",""):gsub("\n$",""), self.MessageDuration )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -303,7 +303,7 @@ function MESSAGE:ToAll()
|
|||||||
if self.MessageType then
|
if self.MessageType then
|
||||||
local Settings = Settings or _SETTINGS -- Core.Settings#SETTINGS
|
local Settings = Settings or _SETTINGS -- Core.Settings#SETTINGS
|
||||||
self.MessageDuration = Settings:GetMessageTime( self.MessageType )
|
self.MessageDuration = Settings:GetMessageTime( self.MessageType )
|
||||||
self.MessageCategory = self.MessageType .. ": "
|
self.MessageCategory = "" -- self.MessageType .. ": "
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.MessageDuration ~= 0 then
|
if self.MessageDuration ~= 0 then
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
--
|
--
|
||||||
-- 
|
-- 
|
||||||
--
|
--
|
||||||
-- ====
|
-- ===
|
||||||
--
|
--
|
||||||
-- # Demo Missions
|
-- # Demo Missions
|
||||||
--
|
--
|
||||||
@@ -12,7 +12,7 @@
|
|||||||
--
|
--
|
||||||
-- ### [ALL Demo Missions pack of the last release](https://github.com/FlightControl-Master/MOOSE_MISSIONS/releases)
|
-- ### [ALL Demo Missions pack of the last release](https://github.com/FlightControl-Master/MOOSE_MISSIONS/releases)
|
||||||
--
|
--
|
||||||
-- ====
|
-- ===
|
||||||
--
|
--
|
||||||
-- # YouTube Channel
|
-- # YouTube Channel
|
||||||
--
|
--
|
||||||
@@ -150,6 +150,31 @@ do -- COORDINATE
|
|||||||
ClassName = "COORDINATE",
|
ClassName = "COORDINATE",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
--- @field COORDINATE.WaypointAltType
|
||||||
|
COORDINATE.WaypointAltType = {
|
||||||
|
BARO = "BARO",
|
||||||
|
RADIO = "RADIO",
|
||||||
|
}
|
||||||
|
|
||||||
|
--- @field COORDINATE.WaypointAction
|
||||||
|
COORDINATE.WaypointAction = {
|
||||||
|
TurningPoint = "Turning Point",
|
||||||
|
FlyoverPoint = "Fly Over Point",
|
||||||
|
FromParkingArea = "From Parking Area",
|
||||||
|
FromParkingAreaHot = "From Parking Area Hot",
|
||||||
|
FromRunway = "From Runway",
|
||||||
|
Landing = "Landing",
|
||||||
|
}
|
||||||
|
|
||||||
|
--- @field COORDINATE.WaypointType
|
||||||
|
COORDINATE.WaypointType = {
|
||||||
|
TakeOffParking = "TakeOffParking",
|
||||||
|
TakeOffParkingHot = "TakeOffParkingHot",
|
||||||
|
TakeOff = "TakeOffParkingHot",
|
||||||
|
TurningPoint = "Turning Point",
|
||||||
|
Land = "Land",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
--- COORDINATE constructor.
|
--- COORDINATE constructor.
|
||||||
-- @param #COORDINATE self
|
-- @param #COORDINATE self
|
||||||
@@ -395,7 +420,160 @@ do -- COORDINATE
|
|||||||
local SourceVec3 = self:GetVec3()
|
local SourceVec3 = self:GetVec3()
|
||||||
return ( ( TargetVec3.x - SourceVec3.x ) ^ 2 + ( TargetVec3.z - SourceVec3.z ) ^ 2 ) ^ 0.5
|
return ( ( TargetVec3.x - SourceVec3.x ) ^ 2 + ( TargetVec3.z - SourceVec3.z ) ^ 2 ) ^ 0.5
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Returns the temperature in Degrees Celsius.
|
||||||
|
-- @param #COORDINATE self
|
||||||
|
-- @param height (Optional) parameter specifying the height ASL.
|
||||||
|
-- @return Temperature in Degrees Celsius.
|
||||||
|
function COORDINATE:GetTemperature(height)
|
||||||
|
local y=height or self.y
|
||||||
|
env.info("FF height = "..y)
|
||||||
|
local point={x=self.x, y=height or self.y, z=self.z}
|
||||||
|
-- get temperature [K] and pressure [Pa] at point
|
||||||
|
local T,P=atmosphere.getTemperatureAndPressure(point)
|
||||||
|
-- Return Temperature in Deg C
|
||||||
|
return T-273.15
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Returns a text of the temperature according the measurement system @{Settings}.
|
||||||
|
-- The text will reflect the temperature like this:
|
||||||
|
--
|
||||||
|
-- - For Russian and European aircraft using the metric system - Degrees Celcius (°C)
|
||||||
|
-- - For Americain aircraft we link to the imperial system - Degrees Farenheit (°F)
|
||||||
|
--
|
||||||
|
-- A text containing a pressure will look like this:
|
||||||
|
--
|
||||||
|
-- - `Temperature: %n.d °C`
|
||||||
|
-- - `Temperature: %n.d °F`
|
||||||
|
--
|
||||||
|
-- @param #COORDINATE self
|
||||||
|
-- @param height (Optional) parameter specifying the height ASL.
|
||||||
|
-- @return #string Temperature according the measurement system @{Settings}.
|
||||||
|
function COORDINATE:GetTemperatureText( height, Settings )
|
||||||
|
|
||||||
|
local DegreesCelcius = self:GetTemperature( height )
|
||||||
|
|
||||||
|
local Settings = Settings or _SETTINGS
|
||||||
|
|
||||||
|
if DegreesCelcius then
|
||||||
|
if Settings:IsMetric() then
|
||||||
|
return string.format( " %-2.2f °C", DegreesCelcius )
|
||||||
|
else
|
||||||
|
return string.format( " %-2.2f °F", UTILS.CelciusToFarenheit( DegreesCelcius ) )
|
||||||
|
end
|
||||||
|
else
|
||||||
|
return " no temperature"
|
||||||
|
end
|
||||||
|
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Returns the pressure in hPa.
|
||||||
|
-- @param #COORDINATE self
|
||||||
|
-- @param height (Optional) parameter specifying the height ASL. E.g. set height=0 for QNH.
|
||||||
|
-- @return Pressure in hPa.
|
||||||
|
function COORDINATE:GetPressure(height)
|
||||||
|
local point={x=self.x, y=height or self.y, z=self.z}
|
||||||
|
-- get temperature [K] and pressure [Pa] at point
|
||||||
|
local T,P=atmosphere.getTemperatureAndPressure(point)
|
||||||
|
-- Return Pressure in hPa.
|
||||||
|
return P/100
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Returns a text of the pressure according the measurement system @{Settings}.
|
||||||
|
-- The text will contain always the pressure in hPa and:
|
||||||
|
--
|
||||||
|
-- - For Russian and European aircraft using the metric system - hPa and mmHg
|
||||||
|
-- - For Americain and European aircraft we link to the imperial system - hPa and inHg
|
||||||
|
--
|
||||||
|
-- A text containing a pressure will look like this:
|
||||||
|
--
|
||||||
|
-- - `QFE: x hPa (y mmHg)`
|
||||||
|
-- - `QFE: x hPa (y inHg)`
|
||||||
|
--
|
||||||
|
-- @param #COORDINATE self
|
||||||
|
-- @param height (Optional) parameter specifying the height ASL. E.g. set height=0 for QNH.
|
||||||
|
-- @return #string Pressure in hPa and mmHg or inHg depending on the measurement system @{Settings}.
|
||||||
|
function COORDINATE:GetPressureText( height, Settings )
|
||||||
|
|
||||||
|
local Pressure_hPa = self:GetPressure( height )
|
||||||
|
local Pressure_mmHg = Pressure_hPa * 0.7500615613030
|
||||||
|
local Pressure_inHg = Pressure_hPa * 0.0295299830714
|
||||||
|
|
||||||
|
local Settings = Settings or _SETTINGS
|
||||||
|
|
||||||
|
if Pressure_hPa then
|
||||||
|
if Settings:IsMetric() then
|
||||||
|
return string.format( " %4.1f hPa (%3.1f mmHg)", Pressure_hPa, Pressure_mmHg )
|
||||||
|
else
|
||||||
|
return string.format( " %4.1f hPa (%3.2f inHg)", Pressure_hPa, Pressure_inHg )
|
||||||
|
end
|
||||||
|
else
|
||||||
|
return " no pressure"
|
||||||
|
end
|
||||||
|
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Returns the wind direction (from) and strength.
|
||||||
|
-- @param #COORDINATE self
|
||||||
|
-- @param height (Optional) parameter specifying the height ASL. The minimum height will be always be the land height since the wind is zero below the ground.
|
||||||
|
-- @return Direction the wind is blowing from in degrees.
|
||||||
|
-- @return Wind strength in m/s.
|
||||||
|
function COORDINATE:GetWind(height)
|
||||||
|
local landheight=self:GetLandHeight()+0.1 -- we at 0.1 meters to be sure to be above ground since wind is zero below ground level.
|
||||||
|
local point={x=self.x, y=math.max(height or self.y, landheight), z=self.z}
|
||||||
|
-- get wind velocity vector
|
||||||
|
local wind = atmosphere.getWind(point)
|
||||||
|
local direction = math.deg(math.atan2(wind.z, wind.x))
|
||||||
|
if direction < 0 then
|
||||||
|
direction = 360 + direction
|
||||||
|
end
|
||||||
|
-- Convert to direction to from direction
|
||||||
|
if direction > 180 then
|
||||||
|
direction = direction-180
|
||||||
|
else
|
||||||
|
direction = direction+180
|
||||||
|
end
|
||||||
|
local strength=math.sqrt((wind.x)^2+(wind.z)^2)
|
||||||
|
-- Return wind direction and strength km/h.
|
||||||
|
return direction, strength
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Returns a text documenting the wind direction (from) and strength according the measurement system @{Settings}.
|
||||||
|
-- The text will reflect the wind like this:
|
||||||
|
--
|
||||||
|
-- - For Russian and European aircraft using the metric system - Wind direction in degrees (°) and wind speed in meters per second (mps).
|
||||||
|
-- - For Americain aircraft we link to the imperial system - Wind direction in degrees (°) and wind speed in knots per second (kps).
|
||||||
|
--
|
||||||
|
-- A text containing a pressure will look like this:
|
||||||
|
--
|
||||||
|
-- - `Wind: %n ° at n.d mps`
|
||||||
|
-- - `Wind: %n ° at n.d kps`
|
||||||
|
--
|
||||||
|
-- @param #COORDINATE self
|
||||||
|
-- @param height (Optional) parameter specifying the height ASL. The minimum height will be always be the land height since the wind is zero below the ground.
|
||||||
|
-- @return #string Wind direction and strength according the measurement system @{Settings}.
|
||||||
|
function COORDINATE:GetWindText( height, Settings )
|
||||||
|
|
||||||
|
local Direction, Strength = self:GetWind( height )
|
||||||
|
|
||||||
|
local Settings = Settings or _SETTINGS
|
||||||
|
|
||||||
|
if Direction and Strength then
|
||||||
|
if Settings:IsMetric() then
|
||||||
|
return string.format( " %d ° at %3.2f mps", Direction, UTILS.MpsToKmph( Strength ) )
|
||||||
|
else
|
||||||
|
return string.format( " %d ° at %3.2f kps", Direction, UTILS.MpsToKnots( Strength ) )
|
||||||
|
end
|
||||||
|
else
|
||||||
|
return " no wind"
|
||||||
|
end
|
||||||
|
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
--- Return the 3D distance in meters between the target COORDINATE and the COORDINATE.
|
--- Return the 3D distance in meters between the target COORDINATE and the COORDINATE.
|
||||||
-- @param #COORDINATE self
|
-- @param #COORDINATE self
|
||||||
@@ -553,9 +731,9 @@ do -- COORDINATE
|
|||||||
|
|
||||||
--- Build an air type route point.
|
--- Build an air type route point.
|
||||||
-- @param #COORDINATE self
|
-- @param #COORDINATE self
|
||||||
-- @param #COORDINATE.RoutePointAltType AltType The altitude type.
|
-- @param #COORDINATE.WaypointAltType AltType The altitude type.
|
||||||
-- @param #COORDINATE.RoutePointType Type The route point type.
|
-- @param #COORDINATE.WaypointType Type The route point type.
|
||||||
-- @param #COORDINATE.RoutePointAction Action The route point action.
|
-- @param #COORDINATE.WaypointAction Action The route point action.
|
||||||
-- @param Dcs.DCSTypes#Speed Speed Airspeed in km/h.
|
-- @param Dcs.DCSTypes#Speed Speed Airspeed in km/h.
|
||||||
-- @param #boolean SpeedLocked true means the speed is locked.
|
-- @param #boolean SpeedLocked true means the speed is locked.
|
||||||
-- @return #table The route point.
|
-- @return #table The route point.
|
||||||
@@ -595,6 +773,75 @@ do -- COORDINATE
|
|||||||
return RoutePoint
|
return RoutePoint
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Build a Waypoint Air "Turning Point".
|
||||||
|
-- @param #COORDINATE self
|
||||||
|
-- @param #COORDINATE.WaypointAltType AltType The altitude type.
|
||||||
|
-- @param Dcs.DCSTypes#Speed Speed Airspeed in km/h.
|
||||||
|
-- @return #table The route point.
|
||||||
|
function COORDINATE:WaypointAirTurningPoint( AltType, Speed )
|
||||||
|
return self:WaypointAir( AltType, COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.TurningPoint, Speed )
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Build a Waypoint Air "Fly Over Point".
|
||||||
|
-- @param #COORDINATE self
|
||||||
|
-- @param #COORDINATE.WaypointAltType AltType The altitude type.
|
||||||
|
-- @param Dcs.DCSTypes#Speed Speed Airspeed in km/h.
|
||||||
|
-- @return #table The route point.
|
||||||
|
function COORDINATE:WaypointAirFlyOverPoint( AltType, Speed )
|
||||||
|
return self:WaypointAir( AltType, COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.FlyoverPoint, Speed )
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Build a Waypoint Air "Take Off Parking Hot".
|
||||||
|
-- @param #COORDINATE self
|
||||||
|
-- @param #COORDINATE.WaypointAltType AltType The altitude type.
|
||||||
|
-- @param Dcs.DCSTypes#Speed Speed Airspeed in km/h.
|
||||||
|
-- @return #table The route point.
|
||||||
|
function COORDINATE:WaypointAirTakeOffParkingHot( AltType, Speed )
|
||||||
|
return self:WaypointAir( AltType, COORDINATE.WaypointType.TakeOffParkingHot, COORDINATE.WaypointAction.FromParkingAreaHot, Speed )
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Build a Waypoint Air "Take Off Parking".
|
||||||
|
-- @param #COORDINATE self
|
||||||
|
-- @param #COORDINATE.WaypointAltType AltType The altitude type.
|
||||||
|
-- @param Dcs.DCSTypes#Speed Speed Airspeed in km/h.
|
||||||
|
-- @return #table The route point.
|
||||||
|
function COORDINATE:WaypointAirTakeOffParking( AltType, Speed )
|
||||||
|
return self:WaypointAir( AltType, COORDINATE.WaypointType.TakeOffParking, COORDINATE.WaypointAction.FromParkingArea, Speed )
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Build a Waypoint Air "Take Off Runway".
|
||||||
|
-- @param #COORDINATE self
|
||||||
|
-- @param #COORDINATE.WaypointAltType AltType The altitude type.
|
||||||
|
-- @param Dcs.DCSTypes#Speed Speed Airspeed in km/h.
|
||||||
|
-- @return #table The route point.
|
||||||
|
function COORDINATE:WaypointAirTakeOffRunway( AltType, Speed )
|
||||||
|
return self:WaypointAir( AltType, COORDINATE.WaypointType.TakeOff, COORDINATE.WaypointAction.FromRunway, Speed )
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Build a Waypoint Air "Landing".
|
||||||
|
-- @param #COORDINATE self
|
||||||
|
-- @param Dcs.DCSTypes#Speed Speed Airspeed in km/h.
|
||||||
|
-- @return #table The route point.
|
||||||
|
-- @usage
|
||||||
|
--
|
||||||
|
-- LandingZone = ZONE:New( "LandingZone" )
|
||||||
|
-- LandingCoord = LandingZone:GetCoordinate()
|
||||||
|
-- LandingWaypoint = LandingCoord:WaypointAirLanding( 60 )
|
||||||
|
-- HeliGroup:Route( { LandWaypoint }, 1 ) -- Start landing the helicopter in one second.
|
||||||
|
--
|
||||||
|
function COORDINATE:WaypointAirLanding( Speed )
|
||||||
|
return self:WaypointAir( nil, COORDINATE.WaypointType.Land, COORDINATE.WaypointAction.Landing, Speed )
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--- Build an ground type route point.
|
--- Build an ground type route point.
|
||||||
-- @param #COORDINATE self
|
-- @param #COORDINATE self
|
||||||
-- @param #number Speed (optional) Speed in km/h. The default speed is 999 km/h.
|
-- @param #number Speed (optional) Speed in km/h. The default speed is 999 km/h.
|
||||||
@@ -610,7 +857,7 @@ do -- COORDINATE
|
|||||||
RoutePoint.action = Formation or ""
|
RoutePoint.action = Formation or ""
|
||||||
|
|
||||||
|
|
||||||
RoutePoint.speed = ( Speed or 999 ) / 3.6
|
RoutePoint.speed = ( Speed or 20 ) / 3.6
|
||||||
RoutePoint.speed_locked = true
|
RoutePoint.speed_locked = true
|
||||||
|
|
||||||
-- ["task"] =
|
-- ["task"] =
|
||||||
@@ -633,6 +880,30 @@ do -- COORDINATE
|
|||||||
|
|
||||||
return RoutePoint
|
return RoutePoint
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Gets the nearest coordinate to a road.
|
||||||
|
-- @param #COORDINATE self
|
||||||
|
-- @return #COORDINATE Coordinate of the nearest road.
|
||||||
|
function COORDINATE:GetClosestPointToRoad()
|
||||||
|
local x,y = land.getClosestPointOnRoads("roads", self.x, self.z)
|
||||||
|
local vec2={ x = x, y = y }
|
||||||
|
return COORDINATE:NewFromVec2(vec2)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Returns a table of coordinates to a destination.
|
||||||
|
-- @param #COORDINATE self
|
||||||
|
-- @param #COORDINATE ToCoord Coordinate of destination.
|
||||||
|
-- @return #table Table of coordinates on road.
|
||||||
|
function COORDINATE:GetPathOnRoad(ToCoord)
|
||||||
|
local Path={}
|
||||||
|
local path = land.findPathOnRoads("roads", self.x, self.z, ToCoord.x, ToCoord.z)
|
||||||
|
for i, v in ipairs(path) do
|
||||||
|
--self:E(v)
|
||||||
|
local coord=COORDINATE:NewFromVec2(v)
|
||||||
|
Path[#Path+1]=COORDINATE:NewFromVec2(v)
|
||||||
|
end
|
||||||
|
return Path
|
||||||
|
end
|
||||||
|
|
||||||
--- Creates an explosion at the point of a certain intensity.
|
--- Creates an explosion at the point of a certain intensity.
|
||||||
-- @param #COORDINATE self
|
-- @param #COORDINATE self
|
||||||
@@ -744,7 +1015,7 @@ do -- COORDINATE
|
|||||||
-- local MarkID = TargetCoord:MarkToAll( "This is a target for all players" )
|
-- local MarkID = TargetCoord:MarkToAll( "This is a target for all players" )
|
||||||
function COORDINATE:MarkToAll( MarkText )
|
function COORDINATE:MarkToAll( MarkText )
|
||||||
local MarkID = UTILS.GetMarkID()
|
local MarkID = UTILS.GetMarkID()
|
||||||
trigger.action.markToAll( MarkID, MarkText, self:GetVec3() )
|
trigger.action.markToAll( MarkID, MarkText, self:GetVec3(), false, "" )
|
||||||
return MarkID
|
return MarkID
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -758,7 +1029,7 @@ do -- COORDINATE
|
|||||||
-- local MarkID = TargetCoord:MarkToCoalition( "This is a target for the red coalition", coalition.side.RED )
|
-- local MarkID = TargetCoord:MarkToCoalition( "This is a target for the red coalition", coalition.side.RED )
|
||||||
function COORDINATE:MarkToCoalition( MarkText, Coalition )
|
function COORDINATE:MarkToCoalition( MarkText, Coalition )
|
||||||
local MarkID = UTILS.GetMarkID()
|
local MarkID = UTILS.GetMarkID()
|
||||||
trigger.action.markToCoalition( MarkID, MarkText, self:GetVec3(), Coalition )
|
trigger.action.markToCoalition( MarkID, MarkText, self:GetVec3(), Coalition, false, "" )
|
||||||
return MarkID
|
return MarkID
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -795,7 +1066,7 @@ do -- COORDINATE
|
|||||||
-- local MarkID = TargetCoord:MarkToGroup( "This is a target for the attack group", AttackGroup )
|
-- local MarkID = TargetCoord:MarkToGroup( "This is a target for the attack group", AttackGroup )
|
||||||
function COORDINATE:MarkToGroup( MarkText, MarkGroup )
|
function COORDINATE:MarkToGroup( MarkText, MarkGroup )
|
||||||
local MarkID = UTILS.GetMarkID()
|
local MarkID = UTILS.GetMarkID()
|
||||||
trigger.action.markToGroup( MarkID, MarkText, self:GetVec3(), MarkGroup:GetID() )
|
trigger.action.markToGroup( MarkID, MarkText, self:GetVec3(), MarkGroup:GetID(), false, "" )
|
||||||
return MarkID
|
return MarkID
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -890,15 +1161,15 @@ do -- COORDINATE
|
|||||||
return "BRA, " .. self:GetBRAText( AngleRadians, Distance, Settings )
|
return "BRA, " .. self:GetBRAText( AngleRadians, Distance, Settings )
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Return a BULLS string from a COORDINATE to the BULLS of the coalition.
|
--- Return a BULLS string out of the BULLS of the coalition to the COORDINATE.
|
||||||
-- @param #COORDINATE self
|
-- @param #COORDINATE self
|
||||||
-- @param Dcs.DCSCoalition#coalition.side Coalition The coalition.
|
-- @param Dcs.DCSCoalition#coalition.side Coalition The coalition.
|
||||||
-- @return #string The BR text.
|
-- @return #string The BR text.
|
||||||
function COORDINATE:ToStringBULLS( Coalition, Settings )
|
function COORDINATE:ToStringBULLS( Coalition, Settings )
|
||||||
local TargetCoordinate = COORDINATE:NewFromVec3( coalition.getMainRefPoint( Coalition ) )
|
local BullsCoordinate = COORDINATE:NewFromVec3( coalition.getMainRefPoint( Coalition ) )
|
||||||
local DirectionVec3 = self:GetDirectionVec3( TargetCoordinate )
|
local DirectionVec3 = BullsCoordinate:GetDirectionVec3( self )
|
||||||
local AngleRadians = self:GetAngleRadians( DirectionVec3 )
|
local AngleRadians = self:GetAngleRadians( DirectionVec3 )
|
||||||
local Distance = self:Get2DDistance( TargetCoordinate )
|
local Distance = self:Get2DDistance( BullsCoordinate )
|
||||||
local Altitude = self:GetAltitudeText()
|
local Altitude = self:GetAltitudeText()
|
||||||
return "BULLS, " .. self:GetBRText( AngleRadians, Distance, Settings )
|
return "BULLS, " .. self:GetBRText( AngleRadians, Distance, Settings )
|
||||||
end
|
end
|
||||||
@@ -973,7 +1244,7 @@ do -- COORDINATE
|
|||||||
-- @return #string The coordinate Text in the configured coordinate system.
|
-- @return #string The coordinate Text in the configured coordinate system.
|
||||||
function COORDINATE:ToStringFromRP( ReferenceCoord, ReferenceName, Controllable, Settings ) -- R2.2
|
function COORDINATE:ToStringFromRP( ReferenceCoord, ReferenceName, Controllable, Settings ) -- R2.2
|
||||||
|
|
||||||
self:E( { ReferenceCoord = ReferenceCoord, ReferenceName = ReferenceName } )
|
self:F( { ReferenceCoord = ReferenceCoord, ReferenceName = ReferenceName } )
|
||||||
|
|
||||||
local Settings = Settings or ( Controllable and _DATABASE:GetPlayerSettings( Controllable:GetPlayerName() ) ) or _SETTINGS
|
local Settings = Settings or ( Controllable and _DATABASE:GetPlayerSettings( Controllable:GetPlayerName() ) ) or _SETTINGS
|
||||||
|
|
||||||
@@ -1081,7 +1352,7 @@ do -- COORDINATE
|
|||||||
|
|
||||||
local Settings = Settings or ( Controllable and _DATABASE:GetPlayerSettings( Controllable:GetPlayerName() ) ) or _SETTINGS
|
local Settings = Settings or ( Controllable and _DATABASE:GetPlayerSettings( Controllable:GetPlayerName() ) ) or _SETTINGS
|
||||||
|
|
||||||
local ModeA2A = true
|
local ModeA2A = false
|
||||||
|
|
||||||
if Task then
|
if Task then
|
||||||
if Task:IsInstanceOf( TASK_A2A ) then
|
if Task:IsInstanceOf( TASK_A2A ) then
|
||||||
@@ -1092,6 +1363,8 @@ do -- COORDINATE
|
|||||||
else
|
else
|
||||||
if Task:IsInstanceOf( TASK_CARGO ) then
|
if Task:IsInstanceOf( TASK_CARGO ) then
|
||||||
ModeA2A = false
|
ModeA2A = false
|
||||||
|
else
|
||||||
|
ModeA2A = false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -1115,6 +1388,54 @@ do -- COORDINATE
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Provides a pressure string of the point, based on a measurement system:
|
||||||
|
-- * Uses default settings in COORDINATE.
|
||||||
|
-- * Can be overridden if for a GROUP containing x clients, a menu was selected to override the default.
|
||||||
|
-- @param #COORDINATE self
|
||||||
|
-- @param Wrapper.Controllable#CONTROLLABLE Controllable
|
||||||
|
-- @param Core.Settings#SETTINGS Settings
|
||||||
|
-- @return #string The pressure text in the configured measurement system.
|
||||||
|
function COORDINATE:ToStringPressure( Controllable, Settings ) -- R2.3
|
||||||
|
|
||||||
|
self:F( { Controllable = Controllable and Controllable:GetName() } )
|
||||||
|
|
||||||
|
local Settings = Settings or ( Controllable and _DATABASE:GetPlayerSettings( Controllable:GetPlayerName() ) ) or _SETTINGS
|
||||||
|
|
||||||
|
return self:GetPressureText( nil, Settings )
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Provides a wind string of the point, based on a measurement system:
|
||||||
|
-- * Uses default settings in COORDINATE.
|
||||||
|
-- * Can be overridden if for a GROUP containing x clients, a menu was selected to override the default.
|
||||||
|
-- @param #COORDINATE self
|
||||||
|
-- @param Wrapper.Controllable#CONTROLLABLE Controllable
|
||||||
|
-- @param Core.Settings#SETTINGS Settings
|
||||||
|
-- @return #string The wind text in the configured measurement system.
|
||||||
|
function COORDINATE:ToStringWind( Controllable, Settings ) -- R2.3
|
||||||
|
|
||||||
|
self:F( { Controllable = Controllable and Controllable:GetName() } )
|
||||||
|
|
||||||
|
local Settings = Settings or ( Controllable and _DATABASE:GetPlayerSettings( Controllable:GetPlayerName() ) ) or _SETTINGS
|
||||||
|
|
||||||
|
return self:GetWindText( nil, Settings )
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Provides a temperature string of the point, based on a measurement system:
|
||||||
|
-- * Uses default settings in COORDINATE.
|
||||||
|
-- * Can be overridden if for a GROUP containing x clients, a menu was selected to override the default.
|
||||||
|
-- @param #COORDINATE self
|
||||||
|
-- @param Wrapper.Controllable#CONTROLLABLE Controllable
|
||||||
|
-- @param Core.Settings#SETTINGS Settings
|
||||||
|
-- @return #string The temperature text in the configured measurement system.
|
||||||
|
function COORDINATE:ToStringTemperature( Controllable, Settings ) -- R2.3
|
||||||
|
|
||||||
|
self:F( { Controllable = Controllable and Controllable:GetName() } )
|
||||||
|
|
||||||
|
local Settings = Settings or ( Controllable and _DATABASE:GetPlayerSettings( Controllable:GetPlayerName() ) ) or _SETTINGS
|
||||||
|
|
||||||
|
return self:GetTemperatureText( nil, Settings )
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
do -- POINT_VEC3
|
do -- POINT_VEC3
|
||||||
|
|||||||
@@ -54,8 +54,8 @@ end
|
|||||||
-- @param #REPORT self
|
-- @param #REPORT self
|
||||||
-- @param #string Text
|
-- @param #string Text
|
||||||
-- @return #REPORT
|
-- @return #REPORT
|
||||||
function REPORT:AddIndent( Text ) --R2.1
|
function REPORT:AddIndent( Text, Separator ) --R2.1
|
||||||
self.Report[#self.Report+1] = string.rep(" ", self.Indent ) .. Text:gsub("\n","\n"..string.rep( " ", self.Indent ) )
|
self.Report[#self.Report+1] = ( ( Separator and Separator .. string.rep( " ", self.Indent - 1 ) ) or string.rep(" ", self.Indent ) ) .. Text:gsub("\n","\n"..string.rep( " ", self.Indent ) )
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -87,12 +87,12 @@ function SCHEDULEDISPATCHER:AddSchedule( Scheduler, ScheduleFunction, ScheduleAr
|
|||||||
self:T3( self.Schedule[Scheduler][CallID] )
|
self:T3( self.Schedule[Scheduler][CallID] )
|
||||||
|
|
||||||
self.Schedule[Scheduler][CallID].CallHandler = function( CallID )
|
self.Schedule[Scheduler][CallID].CallHandler = function( CallID )
|
||||||
self:F2( CallID )
|
--self:E( CallID )
|
||||||
|
|
||||||
local ErrorHandler = function( errmsg )
|
local ErrorHandler = function( errmsg )
|
||||||
env.info( "Error in timer function: " .. errmsg )
|
env.info( "Error in timer function: " .. errmsg )
|
||||||
if debug ~= nil then
|
if BASE.Debug ~= nil then
|
||||||
env.info( debug.traceback() )
|
env.info( BASE.Debug.traceback() )
|
||||||
end
|
end
|
||||||
return errmsg
|
return errmsg
|
||||||
end
|
end
|
||||||
@@ -111,7 +111,7 @@ function SCHEDULEDISPATCHER:AddSchedule( Scheduler, ScheduleFunction, ScheduleAr
|
|||||||
|
|
||||||
--self:T3( { Schedule = Schedule } )
|
--self:T3( { Schedule = Schedule } )
|
||||||
|
|
||||||
local ScheduleObject = Scheduler.SchedulerObject
|
local SchedulerObject = Scheduler.SchedulerObject
|
||||||
--local ScheduleObjectName = Scheduler.SchedulerObject:GetNameAndClassID()
|
--local ScheduleObjectName = Scheduler.SchedulerObject:GetNameAndClassID()
|
||||||
local ScheduleFunction = Schedule.Function
|
local ScheduleFunction = Schedule.Function
|
||||||
local ScheduleArguments = Schedule.Arguments
|
local ScheduleArguments = Schedule.Arguments
|
||||||
@@ -122,9 +122,10 @@ function SCHEDULEDISPATCHER:AddSchedule( Scheduler, ScheduleFunction, ScheduleAr
|
|||||||
local ScheduleID = Schedule.ScheduleID
|
local ScheduleID = Schedule.ScheduleID
|
||||||
|
|
||||||
local Status, Result
|
local Status, Result
|
||||||
if ScheduleObject then
|
--self:E( { SchedulerObject = SchedulerObject } )
|
||||||
|
if SchedulerObject then
|
||||||
local function Timer()
|
local function Timer()
|
||||||
return ScheduleFunction( ScheduleObject, unpack( ScheduleArguments ) )
|
return ScheduleFunction( SchedulerObject, unpack( ScheduleArguments ) )
|
||||||
end
|
end
|
||||||
Status, Result = xpcall( Timer, ErrorHandler )
|
Status, Result = xpcall( Timer, ErrorHandler )
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -21,13 +21,13 @@
|
|||||||
--
|
--
|
||||||
-- ### [ALL Demo Missions pack of the last release](https://github.com/FlightControl-Master/MOOSE_MISSIONS/releases)
|
-- ### [ALL Demo Missions pack of the last release](https://github.com/FlightControl-Master/MOOSE_MISSIONS/releases)
|
||||||
--
|
--
|
||||||
-- ====
|
-- ===
|
||||||
--
|
--
|
||||||
-- # YouTube Channel
|
-- # YouTube Channel
|
||||||
--
|
--
|
||||||
-- ### [SCHEDULER YouTube Channel (none)]()
|
-- ### [SCHEDULER YouTube Channel (none)]()
|
||||||
--
|
--
|
||||||
-- ====
|
-- ===
|
||||||
--
|
--
|
||||||
-- ### Contributions:
|
-- ### Contributions:
|
||||||
--
|
--
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,46 +1,199 @@
|
|||||||
--- **Core** -- **SETTINGS** classe defines the format settings management for measurement.
|
--- **Core** -- Manages various settings for MOOSE classes.
|
||||||
--
|
--
|
||||||
-- 
|
-- 
|
||||||
--
|
--
|
||||||
-- ====
|
|
||||||
--
|
|
||||||
-- # Demo Missions
|
|
||||||
--
|
|
||||||
-- ### [SETTINGS Demo Missions source code]()
|
|
||||||
--
|
|
||||||
-- ### [SETTINGS Demo Missions, only for beta testers]()
|
|
||||||
--
|
|
||||||
-- ### [ALL Demo Missions pack of the last release](https://github.com/FlightControl-Master/MOOSE_MISSIONS/releases)
|
|
||||||
--
|
|
||||||
-- ====
|
|
||||||
--
|
|
||||||
-- # YouTube Channel
|
|
||||||
--
|
|
||||||
-- ### [SETTINGS YouTube Channel]()
|
|
||||||
--
|
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
-- ### Author: **Sven Van de Velde (FlightControl)**
|
-- The documentation of the SETTINGS class can be found further in this document.
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- # **AUTHORS and CONTRIBUTIONS**
|
||||||
|
--
|
||||||
-- ### Contributions:
|
-- ### Contributions:
|
||||||
--
|
--
|
||||||
-- ====
|
-- ### Authors:
|
||||||
|
--
|
||||||
|
-- * **FlightControl**: Design & Programming
|
||||||
--
|
--
|
||||||
-- @module Settings
|
-- @module Settings
|
||||||
|
|
||||||
|
|
||||||
--- @type SETTINGS
|
--- @type SETTINGS
|
||||||
-- @field #number LL_Accuracy
|
|
||||||
-- @field #boolean LL_DMS
|
|
||||||
-- @field #number MGRS_Accuracy
|
|
||||||
-- @field #string A2GSystem
|
|
||||||
-- @field #string A2ASystem
|
|
||||||
-- @extends Core.Base#BASE
|
-- @extends Core.Base#BASE
|
||||||
|
|
||||||
--- # SETTINGS class, extends @{Base#BASE}
|
--- # SETTINGS class, extends @{Base#BASE}
|
||||||
|
-- The SETTINGS class takes care of various settings that influence the behaviour of certain functionalities and classes within the MOOSE framework.
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- 
|
||||||
--
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- The SETTINGS class takes care of various settings that influence the behaviour of certain functionalities and classes within the MOOSE framework.
|
||||||
|
-- SETTINGS can work on 2 levels:
|
||||||
|
--
|
||||||
|
-- - **Default settings**: A running mission has **Default settings**.
|
||||||
|
-- - **Player settings**: For each player its own **Player settings** can be defined, overriding the **Default settings**.
|
||||||
|
--
|
||||||
|
-- So, when there isn't any **Player setting** defined for a player for a specific setting, or, the player cannot be identified, the **Default setting** will be used instead.
|
||||||
|
--
|
||||||
|
-- ## 1. \_SETTINGS object
|
||||||
|
--
|
||||||
|
-- MOOSE defines by default a singleton object called **\_SETTINGS**. Use this object to modify all the **Default settings** for a running mission.
|
||||||
|
-- For each player, MOOSE will automatically allocate also a **player settings** object, and will expose a radio menu to allow the player to adapt the settings to his own preferences.
|
||||||
|
--
|
||||||
|
-- ## 2. SETTINGS Menu
|
||||||
|
--
|
||||||
|
-- Settings can be adapted by the Players and by the Mission Administrator through **radio menus, which are automatically available in the mission**.
|
||||||
|
-- These menus can be found **on level F10 under "Settings"**. There are two kinds of menus generated by the system.
|
||||||
|
--
|
||||||
|
-- ### 2.1. Default settings menu
|
||||||
|
--
|
||||||
|
-- A menu is created automatically per Command Center that allows to modify the **Default** settings.
|
||||||
|
-- So, when joining a CC unit, a menu will be available that allows to change the settings parameters **FOR ALL THE PLAYERS**!
|
||||||
|
-- Note that the **Default settings** will only be used when a player has not choosen its own settings.
|
||||||
|
--
|
||||||
|
-- ### 2.2. Player settings menu
|
||||||
|
--
|
||||||
|
-- A menu is created automatically per Player Slot (group) that allows to modify the **Player** settings.
|
||||||
|
-- So, when joining a slot, a menu wil be available that allows to change the settings parameters **FOR THE PLAYER ONLY**!
|
||||||
|
-- Note that when a player has not chosen a specific setting, the **Default settings** will be used.
|
||||||
|
--
|
||||||
|
-- ### 2.3. Show or Hide the Player Setting menus
|
||||||
|
--
|
||||||
|
-- Of course, it may be requried not to show any setting menus. In this case, a method is available on the **\_SETTINGS object**.
|
||||||
|
-- Use @{#SETTINGS.SetPlayerMenuOff}() to hide the player menus, and use @{#SETTINGS.SetPlayerMenuOn}() show the player menus.
|
||||||
|
-- Note that when this method is used, any player already in a slot will not have its menus visibility changed.
|
||||||
|
-- The option will only have effect when a player enters a new slot or changes a slot.
|
||||||
|
--
|
||||||
|
-- Example:
|
||||||
|
--
|
||||||
|
-- _SETTINGS:SetPlayerMenuOff() -- will disable the player menus.
|
||||||
|
-- _SETTINGS:SetPlayerMenuOn() -- will enable the player menus.
|
||||||
|
-- -- But only when a player exits and reenters the slot these settings will have effect!
|
||||||
|
--
|
||||||
|
--
|
||||||
|
-- ## 3. Settings
|
||||||
|
--
|
||||||
|
-- There are different settings that are managed and applied within the MOOSE framework.
|
||||||
|
-- See below a comprehensive description of each.
|
||||||
|
--
|
||||||
|
-- ### 3.1. **A2G coordinates** display formatting
|
||||||
|
--
|
||||||
|
-- #### 3.1.1. A2G coordinates setting **types**
|
||||||
|
--
|
||||||
|
-- Will customize which display format is used to indicate A2G coordinates in text as part of the Command Center communications.
|
||||||
|
--
|
||||||
|
-- - A2G BR: [Bearing Range](https://en.wikipedia.org/wiki/Bearing_(navigation)).
|
||||||
|
-- - A2G MGRS: The [Military Grid Reference System](https://en.wikipedia.org/wiki/Military_Grid_Reference_System). The accuracy can also be adapted.
|
||||||
|
-- - A2G LL DMS: Lattitude Longitude [Degrees Minutes Seconds](https://en.wikipedia.org/wiki/Geographic_coordinate_conversion). The accuracy can also be adapted.
|
||||||
|
-- - A2G LL DDM: Lattitude Longitude [Decimal Degrees Minutes](https://en.wikipedia.org/wiki/Decimal_degrees). The accuracy can also be adapted.
|
||||||
|
--
|
||||||
|
-- #### 3.1.2. A2G coordinates setting **menu**
|
||||||
|
--
|
||||||
|
-- The settings can be changed by using the **Default settings menu** on the Command Center or the **Player settings menu** on the Player Slot.
|
||||||
|
--
|
||||||
|
-- #### 3.1.3. A2G coordinates setting **methods**
|
||||||
|
--
|
||||||
|
-- There are different methods that can be used to change the **System settings** using the \_SETTINGS object.
|
||||||
|
--
|
||||||
|
-- - @{#SETTINGS.SetA2G_BR}(): Enable the BR display formatting by default.
|
||||||
|
-- - @{#SETTINGS.SetA2G_MGRS}(): Enable the MGRS display formatting by default. Use @{SETTINGS.SetMGRS_Accuracy}() to adapt the accuracy of the MGRS formatting.
|
||||||
|
-- - @{#SETTINGS.SetA2G_LL_DMS}(): Enable the LL DMS display formatting by default. Use @{SETTINGS.SetLL_Accuracy}() to adapt the accuracy of the Seconds formatting.
|
||||||
|
-- - @{#SETTINGS.SetA2G_LL_DDM}(): Enable the LL DDM display formatting by default. Use @{SETTINGS.SetLL_Accuracy}() to adapt the accuracy of the Seconds formatting.
|
||||||
|
--
|
||||||
|
-- #### 3.1.4. A2G coordinates setting - additional notes
|
||||||
|
--
|
||||||
|
-- One additional note on BR. In a situation when a BR coordinate should be given,
|
||||||
|
-- but there isn't any player context (no player unit to reference from), the MGRS formatting will be applied!
|
||||||
|
--
|
||||||
|
-- ### 3.2. **A2A coordinates** formatting
|
||||||
|
--
|
||||||
|
-- #### 3.2.1. A2A coordinates setting **types**
|
||||||
|
--
|
||||||
|
-- Will customize which display format is used to indicate A2A coordinates in text as part of the Command Center communications.
|
||||||
|
--
|
||||||
|
-- - A2A BRAA: [Bearing Range Altitude Aspect](https://en.wikipedia.org/wiki/Bearing_(navigation)).
|
||||||
|
-- - A2A MGRS: The [Military Grid Reference System](https://en.wikipedia.org/wiki/Military_Grid_Reference_System). The accuracy can also be adapted.
|
||||||
|
-- - A2A LL DMS: Lattitude Longitude [Degrees Minutes Seconds](https://en.wikipedia.org/wiki/Geographic_coordinate_conversion). The accuracy can also be adapted.
|
||||||
|
-- - A2A LL DDM: Lattitude Longitude [Decimal Degrees and Minutes](https://en.wikipedia.org/wiki/Decimal_degrees). The accuracy can also be adapted.
|
||||||
|
-- - A2A BULLS: [Bullseye](http://falcon4.wikidot.com/concepts:bullseye).
|
||||||
|
--
|
||||||
|
-- #### 3.2.2. A2A coordinates setting **menu**
|
||||||
|
--
|
||||||
|
-- The settings can be changed by using the **Default settings menu** on the Command Center or the **Player settings menu** on the Player Slot.
|
||||||
|
--
|
||||||
|
-- #### 3.2.3. A2A coordinates setting **methods**
|
||||||
|
--
|
||||||
|
-- There are different methods that can be used to change the **System settings** using the \_SETTINGS object.
|
||||||
|
--
|
||||||
|
-- - @{#SETTINGS.SetA2A_BRAA}(): Enable the BR display formatting by default.
|
||||||
|
-- - @{#SETTINGS.SetA2A_MGRS}(): Enable the MGRS display formatting by default. Use @{SETTINGS.SetMGRS_Accuracy}() to adapt the accuracy of the MGRS formatting.
|
||||||
|
-- - @{#SETTINGS.SetA2A_LL_DMS}(): Enable the LL DMS display formatting by default. Use @{SETTINGS.SetLL_Accuracy}() to adapt the accuracy of the Seconds formatting.
|
||||||
|
-- - @{#SETTINGS.SetA2A_LL_DDM}(): Enable the LL DDM display formatting by default. Use @{SETTINGS.SetLL_Accuracy}() to adapt the accuracy of the Seconds formatting.
|
||||||
|
-- - @{#SETTINGS.SetA2A_BULLS}(): Enable the BULLSeye display formatting by default.
|
||||||
|
--
|
||||||
|
-- #### 3.2.4. A2A coordinates settings - additional notes
|
||||||
|
--
|
||||||
|
-- One additional note on BRAA. In a situation when a BRAA coordinate should be given,
|
||||||
|
-- but there isn't any player context (no player unit to reference from), the MGRS formatting will be applied!
|
||||||
|
--
|
||||||
|
-- ### 3.3. **Measurements** formatting
|
||||||
|
--
|
||||||
|
-- #### 3.3.1. Measurements setting **types**
|
||||||
|
--
|
||||||
|
-- Will customize the measurements system being used as part as part of the Command Center communications.
|
||||||
|
--
|
||||||
|
-- - **Metrics** system: Applies the [Metrics system](https://en.wikipedia.org/wiki/Metric_system) ...
|
||||||
|
-- - **Imperial** system: Applies the [Imperial system](https://en.wikipedia.org/wiki/Imperial_units) ...
|
||||||
|
--
|
||||||
|
-- #### 3.3.2. Measurements setting **menu**
|
||||||
|
--
|
||||||
|
-- The settings can be changed by using the **Default settings menu** on the Command Center or the **Player settings menu** on the Player Slot.
|
||||||
|
--
|
||||||
|
-- #### 3.3.3. Measurements setting **methods**
|
||||||
|
--
|
||||||
|
-- There are different methods that can be used to change the **Default settings** using the \_SETTINGS object.
|
||||||
|
--
|
||||||
|
-- - @{#SETTINGS.SetMetric}(): Enable the Metric system.
|
||||||
|
-- - @{#SETTINGS.SetImperial}(): Enable the Imperial system.
|
||||||
|
--
|
||||||
|
-- ### 3.4. **Message** display times
|
||||||
|
--
|
||||||
|
-- #### 3.4.1. Message setting **types**
|
||||||
|
--
|
||||||
|
-- There are various **Message Types** that will influence the duration how long a message will appear as part of the Command Center communications.
|
||||||
|
--
|
||||||
|
-- - **Update** message: A short update message.
|
||||||
|
-- - **Information** message: Provides new information **while** executing a mission.
|
||||||
|
-- - **Briefing** message: Provides a complete briefing **before** executing a mission.
|
||||||
|
-- - **Overview report**: Provides a short report overview, the summary of the report.
|
||||||
|
-- - **Detailed report**: Provides a complete report.
|
||||||
|
--
|
||||||
|
-- #### 3.4.2. Message setting **menu**
|
||||||
|
--
|
||||||
|
-- The settings can be changed by using the **Default settings menu** on the Command Center or the **Player settings menu** on the Player Slot.
|
||||||
|
--
|
||||||
|
-- Each Message Type has specific timings that will be applied when the message is displayed.
|
||||||
|
-- The Settings Menu will provide for each Message Type a selection of proposed durations from which can be choosen.
|
||||||
|
-- So the player can choose its own amount of seconds how long a message should be displayed of a certain type.
|
||||||
|
-- Note that **Update** messages can be chosen not to be displayed at all!
|
||||||
|
--
|
||||||
|
-- #### 3.4.3. Message setting **methods**
|
||||||
|
--
|
||||||
|
-- There are different methods that can be used to change the **System settings** using the \_SETTINGS object.
|
||||||
|
--
|
||||||
|
-- - @{#SETTINGS.SetMessageTime}(): Define for a specific @{Message.MESSAGE.MessageType} the duration to be displayed in seconds.
|
||||||
|
-- - @{#SETTINGS.GetMessageTime}(): Retrieves for a specific @{Message.MESSAGE.MessageType} the duration to be displayed in seconds.
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
-- @field #SETTINGS
|
-- @field #SETTINGS
|
||||||
SETTINGS = {
|
SETTINGS = {
|
||||||
ClassName = "SETTINGS",
|
ClassName = "SETTINGS",
|
||||||
|
ShowPlayerMenu = true,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -411,152 +564,179 @@ do -- SETTINGS
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- @param #SETTINGS self
|
--- Sets the player menus on, so that the **Player setting menus** show up for the players.
|
||||||
-- @param RootMenu
|
-- But only when a player exits and reenters the slot these settings will have effect!
|
||||||
-- @param Wrapper.Client#CLIENT PlayerUnit
|
-- It is advised to use this method at the start of the mission.
|
||||||
-- @param #string MenuText
|
-- @param #SETTINGS self
|
||||||
-- @return #SETTINGS
|
-- @return #SETTINGS
|
||||||
|
-- @usage
|
||||||
|
-- _SETTINGS:SetPlayerMenuOn() -- will enable the player menus.
|
||||||
|
function SETTINGS:SetPlayerMenuOn()
|
||||||
|
self.ShowPlayerMenu = true
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Sets the player menus off, so that the **Player setting menus** won't show up for the players.
|
||||||
|
-- But only when a player exits and reenters the slot these settings will have effect!
|
||||||
|
-- It is advised to use this method at the start of the mission.
|
||||||
|
-- @param #SETTINGS self
|
||||||
|
-- @return #SETTINGS self
|
||||||
|
-- @usage
|
||||||
|
-- _SETTINGS:SetPlayerMenuOff() -- will disable the player menus.
|
||||||
|
function SETTINGS:SetPlayerMenuOff()
|
||||||
|
self.ShowPlayerMenu = false
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--- Updates the menu of the player seated in the PlayerUnit.
|
||||||
|
-- @param #SETTINGS self
|
||||||
|
-- @param Wrapper.Client#CLIENT PlayerUnit
|
||||||
|
-- @return #SETTINGS self
|
||||||
function SETTINGS:SetPlayerMenu( PlayerUnit )
|
function SETTINGS:SetPlayerMenu( PlayerUnit )
|
||||||
|
|
||||||
local PlayerGroup = PlayerUnit:GetGroup()
|
if _SETTINGS.ShowPlayerMenu == true then
|
||||||
local PlayerName = PlayerUnit:GetPlayerName()
|
|
||||||
local PlayerNames = PlayerGroup:GetPlayerNames()
|
|
||||||
|
|
||||||
local PlayerMenu = MENU_GROUP:New( PlayerGroup, 'Settings "' .. PlayerName .. '"' )
|
|
||||||
|
|
||||||
self.PlayerMenu = PlayerMenu
|
local PlayerGroup = PlayerUnit:GetGroup()
|
||||||
|
local PlayerName = PlayerUnit:GetPlayerName()
|
||||||
local A2GCoordinateMenu = MENU_GROUP:New( PlayerGroup, "A2G Coordinate System", PlayerMenu )
|
local PlayerNames = PlayerGroup:GetPlayerNames()
|
||||||
|
|
||||||
if not self:IsA2G_LL_DMS() then
|
local PlayerMenu = MENU_GROUP:New( PlayerGroup, 'Settings "' .. PlayerName .. '"' )
|
||||||
MENU_GROUP_COMMAND:New( PlayerGroup, "Lat/Lon Degree Min Sec (LL DMS)", A2GCoordinateMenu, self.MenuGroupA2GSystem, self, PlayerUnit, PlayerGroup, PlayerName, "LL DMS" )
|
|
||||||
end
|
self.PlayerMenu = PlayerMenu
|
||||||
|
|
||||||
if not self:IsA2G_LL_DDM() then
|
local A2GCoordinateMenu = MENU_GROUP:New( PlayerGroup, "A2G Coordinate System", PlayerMenu )
|
||||||
MENU_GROUP_COMMAND:New( PlayerGroup, "Lat/Lon Degree Dec Min (LL DDM)", A2GCoordinateMenu, self.MenuGroupA2GSystem, self, PlayerUnit, PlayerGroup, PlayerName, "LL DDM" )
|
|
||||||
end
|
if not self:IsA2G_LL_DMS() then
|
||||||
|
MENU_GROUP_COMMAND:New( PlayerGroup, "Lat/Lon Degree Min Sec (LL DMS)", A2GCoordinateMenu, self.MenuGroupA2GSystem, self, PlayerUnit, PlayerGroup, PlayerName, "LL DMS" )
|
||||||
|
end
|
||||||
|
|
||||||
|
if not self:IsA2G_LL_DDM() then
|
||||||
|
MENU_GROUP_COMMAND:New( PlayerGroup, "Lat/Lon Degree Dec Min (LL DDM)", A2GCoordinateMenu, self.MenuGroupA2GSystem, self, PlayerUnit, PlayerGroup, PlayerName, "LL DDM" )
|
||||||
|
end
|
||||||
|
|
||||||
|
if self:IsA2G_LL_DDM() then
|
||||||
|
MENU_GROUP_COMMAND:New( PlayerGroup, "LL DDM Accuracy 1", A2GCoordinateMenu, self.MenuGroupLL_DDM_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 1 )
|
||||||
|
MENU_GROUP_COMMAND:New( PlayerGroup, "LL DDM Accuracy 2", A2GCoordinateMenu, self.MenuGroupLL_DDM_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 2 )
|
||||||
|
MENU_GROUP_COMMAND:New( PlayerGroup, "LL DDM Accuracy 3", A2GCoordinateMenu, self.MenuGroupLL_DDM_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 3 )
|
||||||
|
end
|
||||||
|
|
||||||
|
if not self:IsA2G_BR() then
|
||||||
|
MENU_GROUP_COMMAND:New( PlayerGroup, "Bearing, Range (BR)", A2GCoordinateMenu, self.MenuGroupA2GSystem, self, PlayerUnit, PlayerGroup, PlayerName, "BR" )
|
||||||
|
end
|
||||||
|
|
||||||
|
if not self:IsA2G_MGRS() then
|
||||||
|
MENU_GROUP_COMMAND:New( PlayerGroup, "Military Grid (MGRS)", A2GCoordinateMenu, self.MenuGroupA2GSystem, self, PlayerUnit, PlayerGroup, PlayerName, "MGRS" )
|
||||||
|
end
|
||||||
|
|
||||||
if self:IsA2G_LL_DDM() then
|
if self:IsA2G_MGRS() then
|
||||||
MENU_GROUP_COMMAND:New( PlayerGroup, "LL DDM Accuracy 1", A2GCoordinateMenu, self.MenuGroupLL_DDM_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 1 )
|
MENU_GROUP_COMMAND:New( PlayerGroup, "MGRS Accuracy 1", A2GCoordinateMenu, self.MenuGroupMGRS_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 1 )
|
||||||
MENU_GROUP_COMMAND:New( PlayerGroup, "LL DDM Accuracy 2", A2GCoordinateMenu, self.MenuGroupLL_DDM_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 2 )
|
MENU_GROUP_COMMAND:New( PlayerGroup, "MGRS Accuracy 2", A2GCoordinateMenu, self.MenuGroupMGRS_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 2 )
|
||||||
MENU_GROUP_COMMAND:New( PlayerGroup, "LL DDM Accuracy 3", A2GCoordinateMenu, self.MenuGroupLL_DDM_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 3 )
|
MENU_GROUP_COMMAND:New( PlayerGroup, "MGRS Accuracy 3", A2GCoordinateMenu, self.MenuGroupMGRS_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 3 )
|
||||||
end
|
MENU_GROUP_COMMAND:New( PlayerGroup, "MGRS Accuracy 4", A2GCoordinateMenu, self.MenuGroupMGRS_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 4 )
|
||||||
|
MENU_GROUP_COMMAND:New( PlayerGroup, "MGRS Accuracy 5", A2GCoordinateMenu, self.MenuGroupMGRS_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 5 )
|
||||||
if not self:IsA2G_BR() then
|
end
|
||||||
MENU_GROUP_COMMAND:New( PlayerGroup, "Bearing, Range (BR)", A2GCoordinateMenu, self.MenuGroupA2GSystem, self, PlayerUnit, PlayerGroup, PlayerName, "BR" )
|
|
||||||
end
|
|
||||||
|
|
||||||
if not self:IsA2G_MGRS() then
|
|
||||||
MENU_GROUP_COMMAND:New( PlayerGroup, "Military Grid (MGRS)", A2GCoordinateMenu, self.MenuGroupA2GSystem, self, PlayerUnit, PlayerGroup, PlayerName, "MGRS" )
|
|
||||||
end
|
|
||||||
|
|
||||||
if self:IsA2G_MGRS() then
|
|
||||||
MENU_GROUP_COMMAND:New( PlayerGroup, "MGRS Accuracy 1", A2GCoordinateMenu, self.MenuGroupMGRS_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 1 )
|
|
||||||
MENU_GROUP_COMMAND:New( PlayerGroup, "MGRS Accuracy 2", A2GCoordinateMenu, self.MenuGroupMGRS_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 2 )
|
|
||||||
MENU_GROUP_COMMAND:New( PlayerGroup, "MGRS Accuracy 3", A2GCoordinateMenu, self.MenuGroupMGRS_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 3 )
|
|
||||||
MENU_GROUP_COMMAND:New( PlayerGroup, "MGRS Accuracy 4", A2GCoordinateMenu, self.MenuGroupMGRS_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 4 )
|
|
||||||
MENU_GROUP_COMMAND:New( PlayerGroup, "MGRS Accuracy 5", A2GCoordinateMenu, self.MenuGroupMGRS_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 5 )
|
|
||||||
end
|
|
||||||
|
|
||||||
local A2ACoordinateMenu = MENU_GROUP:New( PlayerGroup, "A2A Coordinate System", PlayerMenu )
|
|
||||||
|
|
||||||
|
|
||||||
if not self:IsA2A_LL_DMS() then
|
|
||||||
MENU_GROUP_COMMAND:New( PlayerGroup, "Lat/Lon Degree Min Sec (LL DMS)", A2GCoordinateMenu, self.MenuGroupA2GSystem, self, PlayerUnit, PlayerGroup, PlayerName, "LL DMS" )
|
|
||||||
end
|
|
||||||
|
|
||||||
if not self:IsA2A_LL_DDM() then
|
local A2ACoordinateMenu = MENU_GROUP:New( PlayerGroup, "A2A Coordinate System", PlayerMenu )
|
||||||
MENU_GROUP_COMMAND:New( PlayerGroup, "Lat/Lon Degree Dec Min (LL DDM)", A2GCoordinateMenu, self.MenuGroupA2GSystem, self, PlayerUnit, PlayerGroup, PlayerName, "LL DDM" )
|
|
||||||
end
|
|
||||||
|
|
||||||
if self:IsA2A_LL_DDM() then
|
|
||||||
MENU_GROUP_COMMAND:New( PlayerGroup, "LL DDM Accuracy 1", A2GCoordinateMenu, self.MenuGroupLL_DDM_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 1 )
|
if not self:IsA2A_LL_DMS() then
|
||||||
MENU_GROUP_COMMAND:New( PlayerGroup, "LL DDM Accuracy 2", A2GCoordinateMenu, self.MenuGroupLL_DDM_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 2 )
|
MENU_GROUP_COMMAND:New( PlayerGroup, "Lat/Lon Degree Min Sec (LL DMS)", A2GCoordinateMenu, self.MenuGroupA2GSystem, self, PlayerUnit, PlayerGroup, PlayerName, "LL DMS" )
|
||||||
MENU_GROUP_COMMAND:New( PlayerGroup, "LL DDM Accuracy 3", A2GCoordinateMenu, self.MenuGroupLL_DDM_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 3 )
|
end
|
||||||
end
|
|
||||||
|
|
||||||
if not self:IsA2A_BULLS() then
|
|
||||||
MENU_GROUP_COMMAND:New( PlayerGroup, "Bullseye (BULLS)", A2ACoordinateMenu, self.MenuGroupA2ASystem, self, PlayerUnit, PlayerGroup, PlayerName, "BULLS" )
|
|
||||||
end
|
|
||||||
|
|
||||||
if not self:IsA2A_BRAA() then
|
if not self:IsA2A_LL_DDM() then
|
||||||
MENU_GROUP_COMMAND:New( PlayerGroup, "Bearing Range Altitude Aspect (BRAA)", A2ACoordinateMenu, self.MenuGroupA2ASystem, self, PlayerUnit, PlayerGroup, PlayerName, "BRAA" )
|
MENU_GROUP_COMMAND:New( PlayerGroup, "Lat/Lon Degree Dec Min (LL DDM)", A2GCoordinateMenu, self.MenuGroupA2GSystem, self, PlayerUnit, PlayerGroup, PlayerName, "LL DDM" )
|
||||||
end
|
end
|
||||||
|
|
||||||
if not self:IsA2A_MGRS() then
|
if self:IsA2A_LL_DDM() then
|
||||||
MENU_GROUP_COMMAND:New( PlayerGroup, "Military Grid (MGRS)", A2ACoordinateMenu, self.MenuGroupA2ASystem, self, PlayerUnit, PlayerGroup, PlayerName, "MGRS" )
|
MENU_GROUP_COMMAND:New( PlayerGroup, "LL DDM Accuracy 1", A2GCoordinateMenu, self.MenuGroupLL_DDM_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 1 )
|
||||||
end
|
MENU_GROUP_COMMAND:New( PlayerGroup, "LL DDM Accuracy 2", A2GCoordinateMenu, self.MenuGroupLL_DDM_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 2 )
|
||||||
|
MENU_GROUP_COMMAND:New( PlayerGroup, "LL DDM Accuracy 3", A2GCoordinateMenu, self.MenuGroupLL_DDM_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 3 )
|
||||||
|
end
|
||||||
|
|
||||||
|
if not self:IsA2A_BULLS() then
|
||||||
|
MENU_GROUP_COMMAND:New( PlayerGroup, "Bullseye (BULLS)", A2ACoordinateMenu, self.MenuGroupA2ASystem, self, PlayerUnit, PlayerGroup, PlayerName, "BULLS" )
|
||||||
|
end
|
||||||
|
|
||||||
|
if not self:IsA2A_BRAA() then
|
||||||
|
MENU_GROUP_COMMAND:New( PlayerGroup, "Bearing Range Altitude Aspect (BRAA)", A2ACoordinateMenu, self.MenuGroupA2ASystem, self, PlayerUnit, PlayerGroup, PlayerName, "BRAA" )
|
||||||
|
end
|
||||||
|
|
||||||
|
if not self:IsA2A_MGRS() then
|
||||||
|
MENU_GROUP_COMMAND:New( PlayerGroup, "Military Grid (MGRS)", A2ACoordinateMenu, self.MenuGroupA2ASystem, self, PlayerUnit, PlayerGroup, PlayerName, "MGRS" )
|
||||||
|
end
|
||||||
|
|
||||||
|
if self:IsA2A_MGRS() then
|
||||||
|
MENU_GROUP_COMMAND:New( PlayerGroup, "Military Grid (MGRS) Accuracy 1", A2ACoordinateMenu, self.MenuGroupMGRS_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 1 )
|
||||||
|
MENU_GROUP_COMMAND:New( PlayerGroup, "Military Grid (MGRS) Accuracy 2", A2ACoordinateMenu, self.MenuGroupMGRS_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 2 )
|
||||||
|
MENU_GROUP_COMMAND:New( PlayerGroup, "Military Grid (MGRS) Accuracy 3", A2ACoordinateMenu, self.MenuGroupMGRS_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 3 )
|
||||||
|
MENU_GROUP_COMMAND:New( PlayerGroup, "Military Grid (MGRS) Accuracy 4", A2ACoordinateMenu, self.MenuGroupMGRS_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 4 )
|
||||||
|
MENU_GROUP_COMMAND:New( PlayerGroup, "Military Grid (MGRS) Accuracy 5", A2ACoordinateMenu, self.MenuGroupMGRS_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 5 )
|
||||||
|
end
|
||||||
|
|
||||||
|
local MetricsMenu = MENU_GROUP:New( PlayerGroup, "Measures and Weights System", PlayerMenu )
|
||||||
|
|
||||||
|
if self:IsMetric() then
|
||||||
|
MENU_GROUP_COMMAND:New( PlayerGroup, "Imperial (Miles,Feet)", MetricsMenu, self.MenuGroupMWSystem, self, PlayerUnit, PlayerGroup, PlayerName, false )
|
||||||
|
end
|
||||||
|
|
||||||
|
if self:IsImperial() then
|
||||||
|
MENU_GROUP_COMMAND:New( PlayerGroup, "Metric (Kilometers,Meters)", MetricsMenu, self.MenuGroupMWSystem, self, PlayerUnit, PlayerGroup, PlayerName, true )
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
local MessagesMenu = MENU_GROUP:New( PlayerGroup, "Messages and Reports", PlayerMenu )
|
||||||
|
|
||||||
|
local UpdateMessagesMenu = MENU_GROUP:New( PlayerGroup, "Update Messages", MessagesMenu )
|
||||||
|
MENU_GROUP_COMMAND:New( PlayerGroup, "Off", UpdateMessagesMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Update, 0 )
|
||||||
|
MENU_GROUP_COMMAND:New( PlayerGroup, "5 seconds", UpdateMessagesMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Update, 5 )
|
||||||
|
MENU_GROUP_COMMAND:New( PlayerGroup, "10 seconds", UpdateMessagesMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Update, 10 )
|
||||||
|
MENU_GROUP_COMMAND:New( PlayerGroup, "15 seconds", UpdateMessagesMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Update, 15 )
|
||||||
|
MENU_GROUP_COMMAND:New( PlayerGroup, "30 seconds", UpdateMessagesMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Update, 30 )
|
||||||
|
MENU_GROUP_COMMAND:New( PlayerGroup, "1 minute", UpdateMessagesMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Update, 60 )
|
||||||
|
|
||||||
|
local InformationMessagesMenu = MENU_GROUP:New( PlayerGroup, "Information Messages", MessagesMenu )
|
||||||
|
MENU_GROUP_COMMAND:New( PlayerGroup, "5 seconds", InformationMessagesMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Information, 5 )
|
||||||
|
MENU_GROUP_COMMAND:New( PlayerGroup, "10 seconds", InformationMessagesMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Information, 10 )
|
||||||
|
MENU_GROUP_COMMAND:New( PlayerGroup, "15 seconds", InformationMessagesMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Information, 15 )
|
||||||
|
MENU_GROUP_COMMAND:New( PlayerGroup, "30 seconds", InformationMessagesMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Information, 30 )
|
||||||
|
MENU_GROUP_COMMAND:New( PlayerGroup, "1 minute", InformationMessagesMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Information, 60 )
|
||||||
|
MENU_GROUP_COMMAND:New( PlayerGroup, "2 minutes", InformationMessagesMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Information, 120 )
|
||||||
|
|
||||||
|
local BriefingReportsMenu = MENU_GROUP:New( PlayerGroup, "Briefing Reports", MessagesMenu )
|
||||||
|
MENU_GROUP_COMMAND:New( PlayerGroup, "15 seconds", BriefingReportsMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Briefing, 15 )
|
||||||
|
MENU_GROUP_COMMAND:New( PlayerGroup, "30 seconds", BriefingReportsMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Briefing, 30 )
|
||||||
|
MENU_GROUP_COMMAND:New( PlayerGroup, "1 minute", BriefingReportsMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Briefing, 60 )
|
||||||
|
MENU_GROUP_COMMAND:New( PlayerGroup, "2 minutes", BriefingReportsMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Briefing, 120 )
|
||||||
|
MENU_GROUP_COMMAND:New( PlayerGroup, "3 minutes", BriefingReportsMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Briefing, 180 )
|
||||||
|
|
||||||
|
local OverviewReportsMenu = MENU_GROUP:New( PlayerGroup, "Overview Reports", MessagesMenu )
|
||||||
|
MENU_GROUP_COMMAND:New( PlayerGroup, "15 seconds", OverviewReportsMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Overview, 15 )
|
||||||
|
MENU_GROUP_COMMAND:New( PlayerGroup, "30 seconds", OverviewReportsMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Overview, 30 )
|
||||||
|
MENU_GROUP_COMMAND:New( PlayerGroup, "1 minute", OverviewReportsMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Overview, 60 )
|
||||||
|
MENU_GROUP_COMMAND:New( PlayerGroup, "2 minutes", OverviewReportsMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Overview, 120 )
|
||||||
|
MENU_GROUP_COMMAND:New( PlayerGroup, "3 minutes", OverviewReportsMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Overview, 180 )
|
||||||
|
|
||||||
|
local DetailedReportsMenu = MENU_GROUP:New( PlayerGroup, "Detailed Reports", MessagesMenu )
|
||||||
|
MENU_GROUP_COMMAND:New( PlayerGroup, "15 seconds", DetailedReportsMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.DetailedReportsMenu, 15 )
|
||||||
|
MENU_GROUP_COMMAND:New( PlayerGroup, "30 seconds", DetailedReportsMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.DetailedReportsMenu, 30 )
|
||||||
|
MENU_GROUP_COMMAND:New( PlayerGroup, "1 minute", DetailedReportsMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.DetailedReportsMenu, 60 )
|
||||||
|
MENU_GROUP_COMMAND:New( PlayerGroup, "2 minutes", DetailedReportsMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.DetailedReportsMenu, 120 )
|
||||||
|
MENU_GROUP_COMMAND:New( PlayerGroup, "3 minutes", DetailedReportsMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.DetailedReportsMenu, 180 )
|
||||||
|
|
||||||
if self:IsA2A_MGRS() then
|
end
|
||||||
MENU_GROUP_COMMAND:New( PlayerGroup, "Military Grid (MGRS) Accuracy 1", A2ACoordinateMenu, self.MenuGroupMGRS_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 1 )
|
|
||||||
MENU_GROUP_COMMAND:New( PlayerGroup, "Military Grid (MGRS) Accuracy 2", A2ACoordinateMenu, self.MenuGroupMGRS_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 2 )
|
|
||||||
MENU_GROUP_COMMAND:New( PlayerGroup, "Military Grid (MGRS) Accuracy 3", A2ACoordinateMenu, self.MenuGroupMGRS_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 3 )
|
|
||||||
MENU_GROUP_COMMAND:New( PlayerGroup, "Military Grid (MGRS) Accuracy 4", A2ACoordinateMenu, self.MenuGroupMGRS_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 4 )
|
|
||||||
MENU_GROUP_COMMAND:New( PlayerGroup, "Military Grid (MGRS) Accuracy 5", A2ACoordinateMenu, self.MenuGroupMGRS_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 5 )
|
|
||||||
end
|
|
||||||
|
|
||||||
local MetricsMenu = MENU_GROUP:New( PlayerGroup, "Measures and Weights System", PlayerMenu )
|
|
||||||
|
|
||||||
if self:IsMetric() then
|
|
||||||
MENU_GROUP_COMMAND:New( PlayerGroup, "Imperial (Miles,Feet)", MetricsMenu, self.MenuGroupMWSystem, self, PlayerUnit, PlayerGroup, PlayerName, false )
|
|
||||||
end
|
|
||||||
|
|
||||||
if self:IsImperial() then
|
|
||||||
MENU_GROUP_COMMAND:New( PlayerGroup, "Metric (Kilometers,Meters)", MetricsMenu, self.MenuGroupMWSystem, self, PlayerUnit, PlayerGroup, PlayerName, true )
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
local MessagesMenu = MENU_GROUP:New( PlayerGroup, "Messages and Reports", PlayerMenu )
|
|
||||||
|
|
||||||
local UpdateMessagesMenu = MENU_GROUP:New( PlayerGroup, "Update Messages", MessagesMenu )
|
|
||||||
MENU_GROUP_COMMAND:New( PlayerGroup, "Off", UpdateMessagesMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Update, 0 )
|
|
||||||
MENU_GROUP_COMMAND:New( PlayerGroup, "5 seconds", UpdateMessagesMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Update, 5 )
|
|
||||||
MENU_GROUP_COMMAND:New( PlayerGroup, "10 seconds", UpdateMessagesMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Update, 10 )
|
|
||||||
MENU_GROUP_COMMAND:New( PlayerGroup, "15 seconds", UpdateMessagesMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Update, 15 )
|
|
||||||
MENU_GROUP_COMMAND:New( PlayerGroup, "30 seconds", UpdateMessagesMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Update, 30 )
|
|
||||||
MENU_GROUP_COMMAND:New( PlayerGroup, "1 minute", UpdateMessagesMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Update, 60 )
|
|
||||||
|
|
||||||
local InformationMessagesMenu = MENU_GROUP:New( PlayerGroup, "Information Messages", MessagesMenu )
|
|
||||||
MENU_GROUP_COMMAND:New( PlayerGroup, "5 seconds", InformationMessagesMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Information, 5 )
|
|
||||||
MENU_GROUP_COMMAND:New( PlayerGroup, "10 seconds", InformationMessagesMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Information, 10 )
|
|
||||||
MENU_GROUP_COMMAND:New( PlayerGroup, "15 seconds", InformationMessagesMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Information, 15 )
|
|
||||||
MENU_GROUP_COMMAND:New( PlayerGroup, "30 seconds", InformationMessagesMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Information, 30 )
|
|
||||||
MENU_GROUP_COMMAND:New( PlayerGroup, "1 minute", InformationMessagesMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Information, 60 )
|
|
||||||
MENU_GROUP_COMMAND:New( PlayerGroup, "2 minutes", InformationMessagesMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Information, 120 )
|
|
||||||
|
|
||||||
local BriefingReportsMenu = MENU_GROUP:New( PlayerGroup, "Briefing Reports", MessagesMenu )
|
|
||||||
MENU_GROUP_COMMAND:New( PlayerGroup, "15 seconds", BriefingReportsMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Briefing, 15 )
|
|
||||||
MENU_GROUP_COMMAND:New( PlayerGroup, "30 seconds", BriefingReportsMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Briefing, 30 )
|
|
||||||
MENU_GROUP_COMMAND:New( PlayerGroup, "1 minute", BriefingReportsMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Briefing, 60 )
|
|
||||||
MENU_GROUP_COMMAND:New( PlayerGroup, "2 minutes", BriefingReportsMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Briefing, 120 )
|
|
||||||
MENU_GROUP_COMMAND:New( PlayerGroup, "3 minutes", BriefingReportsMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Briefing, 180 )
|
|
||||||
|
|
||||||
local OverviewReportsMenu = MENU_GROUP:New( PlayerGroup, "Overview Reports", MessagesMenu )
|
|
||||||
MENU_GROUP_COMMAND:New( PlayerGroup, "15 seconds", OverviewReportsMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Overview, 15 )
|
|
||||||
MENU_GROUP_COMMAND:New( PlayerGroup, "30 seconds", OverviewReportsMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Overview, 30 )
|
|
||||||
MENU_GROUP_COMMAND:New( PlayerGroup, "1 minute", OverviewReportsMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Overview, 60 )
|
|
||||||
MENU_GROUP_COMMAND:New( PlayerGroup, "2 minutes", OverviewReportsMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Overview, 120 )
|
|
||||||
MENU_GROUP_COMMAND:New( PlayerGroup, "3 minutes", OverviewReportsMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Overview, 180 )
|
|
||||||
|
|
||||||
local DetailedReportsMenu = MENU_GROUP:New( PlayerGroup, "Detailed Reports", MessagesMenu )
|
|
||||||
MENU_GROUP_COMMAND:New( PlayerGroup, "15 seconds", DetailedReportsMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.DetailedReportsMenu, 15 )
|
|
||||||
MENU_GROUP_COMMAND:New( PlayerGroup, "30 seconds", DetailedReportsMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.DetailedReportsMenu, 30 )
|
|
||||||
MENU_GROUP_COMMAND:New( PlayerGroup, "1 minute", DetailedReportsMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.DetailedReportsMenu, 60 )
|
|
||||||
MENU_GROUP_COMMAND:New( PlayerGroup, "2 minutes", DetailedReportsMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.DetailedReportsMenu, 120 )
|
|
||||||
MENU_GROUP_COMMAND:New( PlayerGroup, "3 minutes", DetailedReportsMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.DetailedReportsMenu, 180 )
|
|
||||||
|
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Removes the player menu from the PlayerUnit.
|
||||||
--- @param #SETTINGS self
|
--- @param #SETTINGS self
|
||||||
-- @param RootMenu
|
|
||||||
-- @param Wrapper.Client#CLIENT PlayerUnit
|
-- @param Wrapper.Client#CLIENT PlayerUnit
|
||||||
-- @return #SETTINGS
|
-- @return #SETTINGS self
|
||||||
function SETTINGS:RemovePlayerMenu( PlayerUnit )
|
function SETTINGS:RemovePlayerMenu( PlayerUnit )
|
||||||
|
|
||||||
if self.PlayerMenu then
|
if self.PlayerMenu then
|
||||||
self.PlayerMenu:Remove()
|
self.PlayerMenu:Remove()
|
||||||
|
self.PlayerMenu = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
return self
|
return self
|
||||||
|
|||||||
@@ -1,44 +1,28 @@
|
|||||||
--- **Functional** -- Spawn dynamically new GROUPs in your missions.
|
--- **Core** -- SPAWN class dynamically spawns new groups of units in your missions.
|
||||||
--
|
--
|
||||||
-- 
|
-- 
|
||||||
--
|
--
|
||||||
-- ====
|
-- ===
|
||||||
--
|
--
|
||||||
-- The documentation of the SPAWN class can be found further in this document.
|
-- The documentation of the SPAWN class can be found further in this document.
|
||||||
--
|
--
|
||||||
-- ====
|
-- ===
|
||||||
--
|
--
|
||||||
-- # Demo Missions
|
-- ### [Demo Missions](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master-release/SPA%20-%20Spawning)
|
||||||
--
|
|
||||||
-- ### [SPAWN Demo Missions source code](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master-release/SPA%20-%20Spawning)
|
|
||||||
--
|
|
||||||
-- ### [SPAWN Demo Missions, only for beta testers](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/SPA%20-%20Spawning)
|
|
||||||
--
|
|
||||||
-- ### [ALL Demo Missions pack of the last release](https://github.com/FlightControl-Master/MOOSE_MISSIONS/releases)
|
|
||||||
--
|
|
||||||
-- ====
|
|
||||||
--
|
|
||||||
-- # YouTube Channel
|
|
||||||
--
|
|
||||||
-- ### [SPAWN YouTube Channel](https://www.youtube.com/playlist?list=PL7ZUrU4zZUl1jirWIo4t4YxqN-HxjqRkL)
|
|
||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
-- # **AUTHORS and CONTRIBUTIONS**
|
-- ### [YouTube Playlist](https://www.youtube.com/playlist?list=PL7ZUrU4zZUl1jirWIo4t4YxqN-HxjqRkL)
|
||||||
--
|
--
|
||||||
-- ### Contributions:
|
-- ===
|
||||||
--
|
--
|
||||||
-- * **Aaron**: Posed the idea for Group position randomization at SpawnInZone and make the Unit randomization separate from the Group randomization.
|
-- ### Author: **FlightControl**
|
||||||
-- * [**Entropy**](https://forums.eagle.ru/member.php?u=111471), **Afinegan**: Came up with the requirement for AIOnOff().
|
-- ### Contributions: A lot of people within this community!
|
||||||
--
|
--
|
||||||
-- ### Authors:
|
-- ===
|
||||||
--
|
|
||||||
-- * **FlightControl**: Design & Programming
|
|
||||||
--
|
--
|
||||||
-- @module Spawn
|
-- @module Spawn
|
||||||
|
|
||||||
----BASE:TraceClass("SPAWN")
|
|
||||||
|
|
||||||
|
|
||||||
--- SPAWN Class
|
--- SPAWN Class
|
||||||
-- @type SPAWN
|
-- @type SPAWN
|
||||||
@@ -55,8 +39,12 @@
|
|||||||
|
|
||||||
--- # SPAWN class, extends @{Base#BASE}
|
--- # SPAWN class, extends @{Base#BASE}
|
||||||
--
|
--
|
||||||
|
-- -- 
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
-- The SPAWN class allows to spawn dynamically new groups.
|
-- The SPAWN class allows to spawn dynamically new groups.
|
||||||
-- Each SPAWN object needs to be have a related **template group** setup in the Mission Editor (ME),
|
-- Each SPAWN object needs to be have related **template groups** setup in the Mission Editor (ME),
|
||||||
-- which is a normal group with the **Late Activation** flag set.
|
-- which is a normal group with the **Late Activation** flag set.
|
||||||
-- This template group will never be activated in your mission.
|
-- This template group will never be activated in your mission.
|
||||||
-- SPAWN uses that **template group** to reference to all the characteristics
|
-- SPAWN uses that **template group** to reference to all the characteristics
|
||||||
@@ -271,8 +259,12 @@ SPAWN = {
|
|||||||
-- @extends Wrapper.Group#GROUP.Takeoff
|
-- @extends Wrapper.Group#GROUP.Takeoff
|
||||||
|
|
||||||
--- @field #SPAWN.Takeoff Takeoff
|
--- @field #SPAWN.Takeoff Takeoff
|
||||||
SPAWN.Takeoff = GROUP.Takeoff
|
SPAWN.Takeoff = {
|
||||||
|
Air = 1,
|
||||||
|
Runway = 2,
|
||||||
|
Hot = 3,
|
||||||
|
Cold = 4,
|
||||||
|
}
|
||||||
|
|
||||||
--- @type SPAWN.SpawnZoneTable
|
--- @type SPAWN.SpawnZoneTable
|
||||||
-- @list <Core.Zone#ZONE_BASE> SpawnZone
|
-- @list <Core.Zone#ZONE_BASE> SpawnZone
|
||||||
@@ -290,7 +282,7 @@ function SPAWN:New( SpawnTemplatePrefix )
|
|||||||
local self = BASE:Inherit( self, BASE:New() ) -- #SPAWN
|
local self = BASE:Inherit( self, BASE:New() ) -- #SPAWN
|
||||||
self:F( { SpawnTemplatePrefix } )
|
self:F( { SpawnTemplatePrefix } )
|
||||||
|
|
||||||
local TemplateGroup = Group.getByName( SpawnTemplatePrefix )
|
local TemplateGroup = GROUP:FindByName( SpawnTemplatePrefix )
|
||||||
if TemplateGroup then
|
if TemplateGroup then
|
||||||
self.SpawnTemplatePrefix = SpawnTemplatePrefix
|
self.SpawnTemplatePrefix = SpawnTemplatePrefix
|
||||||
self.SpawnIndex = 0
|
self.SpawnIndex = 0
|
||||||
@@ -317,6 +309,7 @@ function SPAWN:New( SpawnTemplatePrefix )
|
|||||||
end
|
end
|
||||||
|
|
||||||
self:SetEventPriority( 5 )
|
self:SetEventPriority( 5 )
|
||||||
|
self.SpawnHookScheduler = SCHEDULER:New( nil )
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
@@ -334,7 +327,7 @@ function SPAWN:NewWithAlias( SpawnTemplatePrefix, SpawnAliasPrefix )
|
|||||||
local self = BASE:Inherit( self, BASE:New() )
|
local self = BASE:Inherit( self, BASE:New() )
|
||||||
self:F( { SpawnTemplatePrefix, SpawnAliasPrefix } )
|
self:F( { SpawnTemplatePrefix, SpawnAliasPrefix } )
|
||||||
|
|
||||||
local TemplateGroup = Group.getByName( SpawnTemplatePrefix )
|
local TemplateGroup = GROUP:FindByName( SpawnTemplatePrefix )
|
||||||
if TemplateGroup then
|
if TemplateGroup then
|
||||||
self.SpawnTemplatePrefix = SpawnTemplatePrefix
|
self.SpawnTemplatePrefix = SpawnTemplatePrefix
|
||||||
self.SpawnAliasPrefix = SpawnAliasPrefix
|
self.SpawnAliasPrefix = SpawnAliasPrefix
|
||||||
@@ -362,6 +355,7 @@ function SPAWN:NewWithAlias( SpawnTemplatePrefix, SpawnAliasPrefix )
|
|||||||
end
|
end
|
||||||
|
|
||||||
self:SetEventPriority( 5 )
|
self:SetEventPriority( 5 )
|
||||||
|
self.SpawnHookScheduler = SCHEDULER:New( nil )
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
@@ -521,6 +515,73 @@ function SPAWN:InitRandomizeTemplate( SpawnTemplatePrefixTable )
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Randomize templates to be used as the unit representatives for the Spawned group, defined using a SET_GROUP object.
|
||||||
|
-- This method becomes useful when you need to spawn groups with random templates of groups defined within the mission editor,
|
||||||
|
-- but they will all follow the same Template route and have the same prefix name.
|
||||||
|
-- In other words, this method randomizes between a defined set of groups the template to be used for each new spawn of a group.
|
||||||
|
-- @param #SPAWN self
|
||||||
|
-- @param Core.Set#SET_GROUP SpawnTemplateSet A SET_GROUP object set, that contains the groups that are possible unit representatives of the group to be spawned.
|
||||||
|
-- @return #SPAWN
|
||||||
|
-- @usage
|
||||||
|
-- -- NATO Tank Platoons invading Gori.
|
||||||
|
--
|
||||||
|
-- -- Choose between different 'US Tank Platoon Template' configurations to be spawned for the
|
||||||
|
-- -- 'US Tank Platoon Left', 'US Tank Platoon Middle' and 'US Tank Platoon Right' SPAWN objects.
|
||||||
|
--
|
||||||
|
-- -- Each new SPAWN will randomize the route, with a defined time interval of 200 seconds with 40% time variation (randomization) and
|
||||||
|
-- -- with a limit set of maximum 12 Units alive simulteneously and 150 Groups to be spawned during the whole mission.
|
||||||
|
--
|
||||||
|
-- Spawn_US_PlatoonSet = SET_GROUP:New():FilterPrefixes( "US Tank Platoon Templates" ):FilterOnce()
|
||||||
|
--
|
||||||
|
-- --- Now use the Spawn_US_PlatoonSet to define the templates using InitRandomizeTemplateSet.
|
||||||
|
-- Spawn_US_Platoon_Left = SPAWN:New( 'US Tank Platoon Left' ):InitLimit( 12, 150 ):Schedule( 200, 0.4 ):InitRandomizeTemplateSet( Spawn_US_PlatoonSet ):InitRandomizeRoute( 3, 3, 2000 )
|
||||||
|
-- Spawn_US_Platoon_Middle = SPAWN:New( 'US Tank Platoon Middle' ):InitLimit( 12, 150 ):Schedule( 200, 0.4 ):InitRandomizeTemplateSet( Spawn_US_PlatoonSet ):InitRandomizeRoute( 3, 3, 2000 )
|
||||||
|
-- Spawn_US_Platoon_Right = SPAWN:New( 'US Tank Platoon Right' ):InitLimit( 12, 150 ):Schedule( 200, 0.4 ):InitRandomizeTemplateSet( Spawn_US_PlatoonSet ):InitRandomizeRoute( 3, 3, 2000 )
|
||||||
|
function SPAWN:InitRandomizeTemplateSet( SpawnTemplateSet ) -- R2.3
|
||||||
|
self:F( { self.SpawnTemplatePrefix } )
|
||||||
|
|
||||||
|
self.SpawnTemplatePrefixTable = SpawnTemplateSet:GetSetNames()
|
||||||
|
self.SpawnRandomizeTemplate = true
|
||||||
|
|
||||||
|
for SpawnGroupID = 1, self.SpawnMaxGroups do
|
||||||
|
self:_RandomizeTemplate( SpawnGroupID )
|
||||||
|
end
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Randomize templates to be used as the unit representatives for the Spawned group, defined by specifying the prefix names.
|
||||||
|
-- This method becomes useful when you need to spawn groups with random templates of groups defined within the mission editor,
|
||||||
|
-- but they will all follow the same Template route and have the same prefix name.
|
||||||
|
-- In other words, this method randomizes between a defined set of groups the template to be used for each new spawn of a group.
|
||||||
|
-- @param #SPAWN self
|
||||||
|
-- @param #string SpawnTemplatePrefixes A string or a list of string that contains the prefixes of the groups that are possible unit representatives of the group to be spawned.
|
||||||
|
-- @return #SPAWN
|
||||||
|
-- @usage
|
||||||
|
-- -- NATO Tank Platoons invading Gori.
|
||||||
|
--
|
||||||
|
-- -- Choose between different 'US Tank Platoon Templates' configurations to be spawned for the
|
||||||
|
-- -- 'US Tank Platoon Left', 'US Tank Platoon Middle' and 'US Tank Platoon Right' SPAWN objects.
|
||||||
|
--
|
||||||
|
-- -- Each new SPAWN will randomize the route, with a defined time interval of 200 seconds with 40% time variation (randomization) and
|
||||||
|
-- -- with a limit set of maximum 12 Units alive simulteneously and 150 Groups to be spawned during the whole mission.
|
||||||
|
--
|
||||||
|
-- Spawn_US_Platoon_Left = SPAWN:New( 'US Tank Platoon Left' ):InitLimit( 12, 150 ):Schedule( 200, 0.4 ):InitRandomizeTemplatePrefixes( "US Tank Platoon Templates" ):InitRandomizeRoute( 3, 3, 2000 )
|
||||||
|
-- Spawn_US_Platoon_Middle = SPAWN:New( 'US Tank Platoon Middle' ):InitLimit( 12, 150 ):Schedule( 200, 0.4 ):InitRandomizeTemplatePrefixes( "US Tank Platoon Templates" ):InitRandomizeRoute( 3, 3, 2000 )
|
||||||
|
-- Spawn_US_Platoon_Right = SPAWN:New( 'US Tank Platoon Right' ):InitLimit( 12, 150 ):Schedule( 200, 0.4 ):InitRandomizeTemplatePrefixes( "US Tank Platoon Templates" ):InitRandomizeRoute( 3, 3, 2000 )
|
||||||
|
function SPAWN:InitRandomizeTemplatePrefixes( SpawnTemplatePrefixes ) --R2.3
|
||||||
|
self:F( { self.SpawnTemplatePrefix } )
|
||||||
|
|
||||||
|
local SpawnTemplateSet = SET_GROUP:New():FilterPrefixes( SpawnTemplatePrefixes ):FilterOnce()
|
||||||
|
|
||||||
|
self:InitRandomizeTemplateSet( SpawnTemplateSet )
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
--- When spawning a new group, make the grouping of the units according the InitGrouping setting.
|
--- When spawning a new group, make the grouping of the units according the InitGrouping setting.
|
||||||
-- @param #SPAWN self
|
-- @param #SPAWN self
|
||||||
-- @param #number Grouping Indicates the maximum amount of units in the group.
|
-- @param #number Grouping Indicates the maximum amount of units in the group.
|
||||||
@@ -570,7 +631,13 @@ end
|
|||||||
-- @usage
|
-- @usage
|
||||||
-- -- RU Su-34 - AI Ship Attack
|
-- -- RU Su-34 - AI Ship Attack
|
||||||
-- -- Re-SPAWN the Group(s) after each landing and Engine Shut-Down automatically.
|
-- -- Re-SPAWN the Group(s) after each landing and Engine Shut-Down automatically.
|
||||||
-- SpawnRU_SU34 = SPAWN:New( 'TF1 RU Su-34 Krymsk@AI - Attack Ships' ):Schedule( 2, 3, 1800, 0.4 ):SpawnUncontrolled():InitRandomizeRoute( 1, 1, 3000 ):RepeatOnEngineShutDown()
|
-- SpawnRU_SU34 = SPAWN
|
||||||
|
-- :New( 'Su-34' )
|
||||||
|
-- :Schedule( 2, 3, 1800, 0.4 )
|
||||||
|
-- :SpawnUncontrolled()
|
||||||
|
-- :InitRandomizeRoute( 1, 1, 3000 )
|
||||||
|
-- :InitRepeatOnEngineShutDown()
|
||||||
|
--
|
||||||
function SPAWN:InitRepeat()
|
function SPAWN:InitRepeat()
|
||||||
self:F( { self.SpawnTemplatePrefix, self.SpawnIndex } )
|
self:F( { self.SpawnTemplatePrefix, self.SpawnIndex } )
|
||||||
|
|
||||||
@@ -584,6 +651,16 @@ end
|
|||||||
--- Respawn group after landing.
|
--- Respawn group after landing.
|
||||||
-- @param #SPAWN self
|
-- @param #SPAWN self
|
||||||
-- @return #SPAWN self
|
-- @return #SPAWN self
|
||||||
|
-- @usage
|
||||||
|
-- -- RU Su-34 - AI Ship Attack
|
||||||
|
-- -- Re-SPAWN the Group(s) after each landing and Engine Shut-Down automatically.
|
||||||
|
-- SpawnRU_SU34 = SPAWN
|
||||||
|
-- :New( 'Su-34' )
|
||||||
|
-- :Schedule( 2, 3, 1800, 0.4 )
|
||||||
|
-- :SpawnUncontrolled()
|
||||||
|
-- :InitRandomizeRoute( 1, 1, 3000 )
|
||||||
|
-- :InitRepeatOnLanding()
|
||||||
|
--
|
||||||
function SPAWN:InitRepeatOnLanding()
|
function SPAWN:InitRepeatOnLanding()
|
||||||
self:F( { self.SpawnTemplatePrefix } )
|
self:F( { self.SpawnTemplatePrefix } )
|
||||||
|
|
||||||
@@ -598,6 +675,16 @@ end
|
|||||||
--- Respawn after landing when its engines have shut down.
|
--- Respawn after landing when its engines have shut down.
|
||||||
-- @param #SPAWN self
|
-- @param #SPAWN self
|
||||||
-- @return #SPAWN self
|
-- @return #SPAWN self
|
||||||
|
-- @usage
|
||||||
|
-- -- RU Su-34 - AI Ship Attack
|
||||||
|
-- -- Re-SPAWN the Group(s) after each landing and Engine Shut-Down automatically.
|
||||||
|
-- SpawnRU_SU34 = SPAWN
|
||||||
|
-- :New( 'Su-34' )
|
||||||
|
-- :Schedule( 2, 3, 1800, 0.4 )
|
||||||
|
-- :SpawnUncontrolled()
|
||||||
|
-- :InitRandomizeRoute( 1, 1, 3000 )
|
||||||
|
-- :InitRepeatOnEngineShutDown()
|
||||||
|
--
|
||||||
function SPAWN:InitRepeatOnEngineShutDown()
|
function SPAWN:InitRepeatOnEngineShutDown()
|
||||||
self:F( { self.SpawnTemplatePrefix } )
|
self:F( { self.SpawnTemplatePrefix } )
|
||||||
|
|
||||||
@@ -614,7 +701,8 @@ end
|
|||||||
-- @param #SPAWN self
|
-- @param #SPAWN self
|
||||||
-- @param #string SpawnCleanUpInterval The interval to check for inactive groups within seconds.
|
-- @param #string SpawnCleanUpInterval The interval to check for inactive groups within seconds.
|
||||||
-- @return #SPAWN self
|
-- @return #SPAWN self
|
||||||
-- @usage Spawn_Helicopter:CleanUp( 20 ) -- CleanUp the spawning of the helicopters every 20 seconds when they become inactive.
|
-- @usage
|
||||||
|
-- Spawn_Helicopter:InitCleanUp( 20 ) -- CleanUp the spawning of the helicopters every 20 seconds when they become inactive.
|
||||||
function SPAWN:InitCleanUp( SpawnCleanUpInterval )
|
function SPAWN:InitCleanUp( SpawnCleanUpInterval )
|
||||||
self:F( { self.SpawnTemplatePrefix, SpawnCleanUpInterval } )
|
self:F( { self.SpawnTemplatePrefix, SpawnCleanUpInterval } )
|
||||||
|
|
||||||
@@ -641,7 +729,11 @@ end
|
|||||||
-- @return #SPAWN self
|
-- @return #SPAWN self
|
||||||
-- @usage
|
-- @usage
|
||||||
-- -- Define an array of Groups.
|
-- -- Define an array of Groups.
|
||||||
-- Spawn_BE_Ground = SPAWN:New( 'BE Ground' ):InitLimit( 2, 24 ):InitArray( 90, "Diamond", 10, 100, 50 )
|
-- Spawn_BE_Ground = SPAWN
|
||||||
|
-- :New( 'BE Ground' )
|
||||||
|
-- :InitLimit( 2, 24 )
|
||||||
|
-- :InitArray( 90, 10, 100, 50 )
|
||||||
|
--
|
||||||
function SPAWN:InitArray( SpawnAngle, SpawnWidth, SpawnDeltaX, SpawnDeltaY )
|
function SPAWN:InitArray( SpawnAngle, SpawnWidth, SpawnDeltaX, SpawnDeltaY )
|
||||||
self:F( { self.SpawnTemplatePrefix, SpawnAngle, SpawnWidth, SpawnDeltaX, SpawnDeltaY } )
|
self:F( { self.SpawnTemplatePrefix, SpawnAngle, SpawnWidth, SpawnDeltaX, SpawnDeltaY } )
|
||||||
|
|
||||||
@@ -882,9 +974,7 @@ function SPAWN:SpawnWithIndex( SpawnIndex )
|
|||||||
-- If there is a SpawnFunction hook defined, call it.
|
-- If there is a SpawnFunction hook defined, call it.
|
||||||
if self.SpawnFunctionHook then
|
if self.SpawnFunctionHook then
|
||||||
-- delay calling this for .1 seconds so that it hopefully comes after the BIRTH event of the group.
|
-- delay calling this for .1 seconds so that it hopefully comes after the BIRTH event of the group.
|
||||||
self.SpawnHookScheduler = SCHEDULER:New()
|
|
||||||
self.SpawnHookScheduler:Schedule( nil, self.SpawnFunctionHook, { self.SpawnGroups[self.SpawnIndex].Group, unpack( self.SpawnFunctionArguments)}, 0.1 )
|
self.SpawnHookScheduler:Schedule( nil, self.SpawnFunctionHook, { self.SpawnGroups[self.SpawnIndex].Group, unpack( self.SpawnFunctionArguments)}, 0.1 )
|
||||||
-- self.SpawnFunctionHook( self.SpawnGroups[self.SpawnIndex].Group, unpack( self.SpawnFunctionArguments ) )
|
|
||||||
end
|
end
|
||||||
-- TODO: Need to fix this by putting an "R" in the name of the group when the group repeats.
|
-- TODO: Need to fix this by putting an "R" in the name of the group when the group repeats.
|
||||||
--if self.Repeat then
|
--if self.Repeat then
|
||||||
@@ -1027,7 +1117,7 @@ end
|
|||||||
-- Spawn_Heli:SpawnAtAirbase( AIRBASE:FindByName( "Carrier" ), SPAWN.Takeoff.Cold )
|
-- Spawn_Heli:SpawnAtAirbase( AIRBASE:FindByName( "Carrier" ), SPAWN.Takeoff.Cold )
|
||||||
--
|
--
|
||||||
function SPAWN:SpawnAtAirbase( SpawnAirbase, Takeoff, TakeoffAltitude ) -- R2.2
|
function SPAWN:SpawnAtAirbase( SpawnAirbase, Takeoff, TakeoffAltitude ) -- R2.2
|
||||||
self:E( { self.SpawnTemplatePrefix, SpawnAirbase, Takeoff, TakeoffAltitude } )
|
self:F( { self.SpawnTemplatePrefix, SpawnAirbase, Takeoff, TakeoffAltitude } )
|
||||||
|
|
||||||
local PointVec3 = SpawnAirbase:GetPointVec3()
|
local PointVec3 = SpawnAirbase:GetPointVec3()
|
||||||
self:T2(PointVec3)
|
self:T2(PointVec3)
|
||||||
@@ -1156,6 +1246,8 @@ function SPAWN:SpawnFromVec3( Vec3, SpawnIndex )
|
|||||||
if SpawnTemplate then
|
if SpawnTemplate then
|
||||||
|
|
||||||
self:T( { "Current point of ", self.SpawnTemplatePrefix, Vec3 } )
|
self:T( { "Current point of ", self.SpawnTemplatePrefix, Vec3 } )
|
||||||
|
|
||||||
|
local TemplateHeight = SpawnTemplate.route.points[1].alt
|
||||||
|
|
||||||
-- Translate the position of the Group Template to the Vec3.
|
-- Translate the position of the Group Template to the Vec3.
|
||||||
for UnitID = 1, #SpawnTemplate.units do
|
for UnitID = 1, #SpawnTemplate.units do
|
||||||
@@ -1169,16 +1261,20 @@ function SPAWN:SpawnFromVec3( Vec3, SpawnIndex )
|
|||||||
local TY = Vec3.z + ( SY - BY )
|
local TY = Vec3.z + ( SY - BY )
|
||||||
SpawnTemplate.units[UnitID].x = TX
|
SpawnTemplate.units[UnitID].x = TX
|
||||||
SpawnTemplate.units[UnitID].y = TY
|
SpawnTemplate.units[UnitID].y = TY
|
||||||
SpawnTemplate.units[UnitID].alt = Vec3.y
|
if SpawnTemplate.CategoryID ~= Group.Category.SHIP then
|
||||||
|
SpawnTemplate.units[UnitID].alt = Vec3.y or TemplateHeight
|
||||||
|
end
|
||||||
self:T( 'After Translation SpawnTemplate.units['..UnitID..'].x = ' .. SpawnTemplate.units[UnitID].x .. ', SpawnTemplate.units['..UnitID..'].y = ' .. SpawnTemplate.units[UnitID].y )
|
self:T( 'After Translation SpawnTemplate.units['..UnitID..'].x = ' .. SpawnTemplate.units[UnitID].x .. ', SpawnTemplate.units['..UnitID..'].y = ' .. SpawnTemplate.units[UnitID].y )
|
||||||
end
|
end
|
||||||
|
|
||||||
SpawnTemplate.route.points[1].x = Vec3.x
|
SpawnTemplate.route.points[1].x = Vec3.x
|
||||||
SpawnTemplate.route.points[1].y = Vec3.z
|
SpawnTemplate.route.points[1].y = Vec3.z
|
||||||
SpawnTemplate.route.points[1].alt = Vec3.y
|
if SpawnTemplate.CategoryID ~= Group.Category.SHIP then
|
||||||
|
SpawnTemplate.route.points[1].alt = Vec3.y or TemplateHeight
|
||||||
|
end
|
||||||
SpawnTemplate.x = Vec3.x
|
SpawnTemplate.x = Vec3.x
|
||||||
SpawnTemplate.y = Vec3.z
|
SpawnTemplate.y = Vec3.z
|
||||||
|
SpawnTemplate.alt = Vec3.y or TemplateHeight
|
||||||
|
|
||||||
return self:SpawnWithIndex( self.SpawnIndex )
|
return self:SpawnWithIndex( self.SpawnIndex )
|
||||||
end
|
end
|
||||||
@@ -1193,14 +1289,31 @@ end
|
|||||||
-- You can use the returned group to further define the route to be followed.
|
-- You can use the returned group to further define the route to be followed.
|
||||||
-- @param #SPAWN self
|
-- @param #SPAWN self
|
||||||
-- @param Dcs.DCSTypes#Vec2 Vec2 The Vec2 coordinates where to spawn the group.
|
-- @param Dcs.DCSTypes#Vec2 Vec2 The Vec2 coordinates where to spawn the group.
|
||||||
|
-- @param #number MinHeight (optional) The minimum height to spawn an airborne group into the zone.
|
||||||
|
-- @param #number MaxHeight (optional) The maximum height to spawn an airborne group into the zone.
|
||||||
-- @param #number SpawnIndex (optional) The index which group to spawn within the given zone.
|
-- @param #number SpawnIndex (optional) The index which group to spawn within the given zone.
|
||||||
-- @return Wrapper.Group#GROUP that was spawned.
|
-- @return Wrapper.Group#GROUP that was spawned.
|
||||||
-- @return #nil Nothing was spawned.
|
-- @return #nil Nothing was spawned.
|
||||||
function SPAWN:SpawnFromVec2( Vec2, SpawnIndex )
|
-- @usage
|
||||||
self:F( { self.SpawnTemplatePrefix, Vec2, SpawnIndex } )
|
--
|
||||||
|
-- local SpawnVec2 = ZONE:New( ZoneName ):GetVec2()
|
||||||
|
--
|
||||||
|
-- -- Spawn at the zone center position at the height specified in the ME of the group template!
|
||||||
|
-- SpawnAirplanes:SpawnFromVec2( SpawnVec2 )
|
||||||
|
--
|
||||||
|
-- -- Spawn from the static position at the height randomized between 2000 and 4000 meters.
|
||||||
|
-- SpawnAirplanes:SpawnFromVec2( SpawnVec2, 2000, 4000 )
|
||||||
|
--
|
||||||
|
function SPAWN:SpawnFromVec2( Vec2, MinHeight, MaxHeight, SpawnIndex )
|
||||||
|
self:F( { self.SpawnTemplatePrefix, self.SpawnIndex, Vec2, MinHeight, MaxHeight, SpawnIndex } )
|
||||||
|
|
||||||
local PointVec2 = POINT_VEC2:NewFromVec2( Vec2 )
|
local Height = nil
|
||||||
return self:SpawnFromVec3( PointVec2:GetVec3(), SpawnIndex )
|
|
||||||
|
if MinHeight and MaxHeight then
|
||||||
|
Height = math.random( MinHeight, MaxHeight)
|
||||||
|
end
|
||||||
|
|
||||||
|
return self:SpawnFromVec3( { x = Vec2.x, y = Height, z = Vec2.y }, SpawnIndex ) -- y can be nil. In this case, spawn on the ground for vehicles, and in the template altitude for air.
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@@ -1209,14 +1322,26 @@ end
|
|||||||
-- You can use the returned group to further define the route to be followed.
|
-- You can use the returned group to further define the route to be followed.
|
||||||
-- @param #SPAWN self
|
-- @param #SPAWN self
|
||||||
-- @param Wrapper.Unit#UNIT HostUnit The air or ground unit dropping or unloading the group.
|
-- @param Wrapper.Unit#UNIT HostUnit The air or ground unit dropping or unloading the group.
|
||||||
|
-- @param #number MinHeight (optional) The minimum height to spawn an airborne group into the zone.
|
||||||
|
-- @param #number MaxHeight (optional) The maximum height to spawn an airborne group into the zone.
|
||||||
-- @param #number SpawnIndex (optional) The index which group to spawn within the given zone.
|
-- @param #number SpawnIndex (optional) The index which group to spawn within the given zone.
|
||||||
-- @return Wrapper.Group#GROUP that was spawned.
|
-- @return Wrapper.Group#GROUP that was spawned.
|
||||||
-- @return #nil Nothing was spawned.
|
-- @return #nil Nothing was spawned.
|
||||||
function SPAWN:SpawnFromUnit( HostUnit, SpawnIndex )
|
-- @usage
|
||||||
self:F( { self.SpawnTemplatePrefix, HostUnit, SpawnIndex } )
|
--
|
||||||
|
-- local SpawnStatic = STATIC:FindByName( StaticName )
|
||||||
|
--
|
||||||
|
-- -- Spawn from the static position at the height specified in the ME of the group template!
|
||||||
|
-- SpawnAirplanes:SpawnFromUnit( SpawnStatic )
|
||||||
|
--
|
||||||
|
-- -- Spawn from the static position at the height randomized between 2000 and 4000 meters.
|
||||||
|
-- SpawnAirplanes:SpawnFromUnit( SpawnStatic, 2000, 4000 )
|
||||||
|
--
|
||||||
|
function SPAWN:SpawnFromUnit( HostUnit, MinHeight, MaxHeight, SpawnIndex )
|
||||||
|
self:F( { self.SpawnTemplatePrefix, HostUnit, MinHeight, MaxHeight, SpawnIndex } )
|
||||||
|
|
||||||
if HostUnit and HostUnit:IsAlive() ~= nil then -- and HostUnit:getUnit(1):inAir() == false then
|
if HostUnit and HostUnit:IsAlive() ~= nil then -- and HostUnit:getUnit(1):inAir() == false then
|
||||||
return self:SpawnFromVec3( HostUnit:GetVec3(), SpawnIndex )
|
return self:SpawnFromVec2( HostUnit:GetVec2(), MinHeight, MaxHeight, SpawnIndex )
|
||||||
end
|
end
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@@ -1226,14 +1351,26 @@ end
|
|||||||
-- You can use the returned group to further define the route to be followed.
|
-- You can use the returned group to further define the route to be followed.
|
||||||
-- @param #SPAWN self
|
-- @param #SPAWN self
|
||||||
-- @param Wrapper.Static#STATIC HostStatic The static dropping or unloading the group.
|
-- @param Wrapper.Static#STATIC HostStatic The static dropping or unloading the group.
|
||||||
|
-- @param #number MinHeight (optional) The minimum height to spawn an airborne group into the zone.
|
||||||
|
-- @param #number MaxHeight (optional) The maximum height to spawn an airborne group into the zone.
|
||||||
-- @param #number SpawnIndex (optional) The index which group to spawn within the given zone.
|
-- @param #number SpawnIndex (optional) The index which group to spawn within the given zone.
|
||||||
-- @return Wrapper.Group#GROUP that was spawned.
|
-- @return Wrapper.Group#GROUP that was spawned.
|
||||||
-- @return #nil Nothing was spawned.
|
-- @return #nil Nothing was spawned.
|
||||||
function SPAWN:SpawnFromStatic( HostStatic, SpawnIndex )
|
-- @usage
|
||||||
self:F( { self.SpawnTemplatePrefix, HostStatic, SpawnIndex } )
|
--
|
||||||
|
-- local SpawnStatic = STATIC:FindByName( StaticName )
|
||||||
|
--
|
||||||
|
-- -- Spawn from the static position at the height specified in the ME of the group template!
|
||||||
|
-- SpawnAirplanes:SpawnFromStatic( SpawnStatic )
|
||||||
|
--
|
||||||
|
-- -- Spawn from the static position at the height randomized between 2000 and 4000 meters.
|
||||||
|
-- SpawnAirplanes:SpawnFromStatic( SpawnStatic, 2000, 4000 )
|
||||||
|
--
|
||||||
|
function SPAWN:SpawnFromStatic( HostStatic, MinHeight, MaxHeight, SpawnIndex )
|
||||||
|
self:F( { self.SpawnTemplatePrefix, HostStatic, MinHeight, MaxHeight, SpawnIndex } )
|
||||||
|
|
||||||
if HostStatic and HostStatic:IsAlive() then
|
if HostStatic and HostStatic:IsAlive() then
|
||||||
return self:SpawnFromVec3( HostStatic:GetVec3(), SpawnIndex )
|
return self:SpawnFromVec2( HostStatic:GetVec2(), MinHeight, MaxHeight, SpawnIndex )
|
||||||
end
|
end
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@@ -1246,17 +1383,38 @@ end
|
|||||||
-- @param #SPAWN self
|
-- @param #SPAWN self
|
||||||
-- @param Core.Zone#ZONE Zone The zone where the group is to be spawned.
|
-- @param Core.Zone#ZONE Zone The zone where the group is to be spawned.
|
||||||
-- @param #boolean RandomizeGroup (optional) Randomization of the @{Group} position in the zone.
|
-- @param #boolean RandomizeGroup (optional) Randomization of the @{Group} position in the zone.
|
||||||
|
-- @param #number MinHeight (optional) The minimum height to spawn an airborne group into the zone.
|
||||||
|
-- @param #number MaxHeight (optional) The maximum height to spawn an airborne group into the zone.
|
||||||
-- @param #number SpawnIndex (optional) The index which group to spawn within the given zone.
|
-- @param #number SpawnIndex (optional) The index which group to spawn within the given zone.
|
||||||
-- @return Wrapper.Group#GROUP that was spawned.
|
-- @return Wrapper.Group#GROUP that was spawned.
|
||||||
-- @return #nil when nothing was spawned.
|
-- @return #nil when nothing was spawned.
|
||||||
function SPAWN:SpawnInZone( Zone, RandomizeGroup, SpawnIndex )
|
-- @usage
|
||||||
self:F( { self.SpawnTemplatePrefix, Zone, RandomizeGroup, SpawnIndex } )
|
--
|
||||||
|
-- local SpawnZone = ZONE:New( ZoneName )
|
||||||
|
--
|
||||||
|
-- -- Spawn at the zone center position at the height specified in the ME of the group template!
|
||||||
|
-- SpawnAirplanes:SpawnInZone( SpawnZone )
|
||||||
|
--
|
||||||
|
-- -- Spawn in the zone at a random position at the height specified in the Me of the group template.
|
||||||
|
-- SpawnAirplanes:SpawnInZone( SpawnZone, true )
|
||||||
|
--
|
||||||
|
-- -- Spawn in the zone at a random position at the height randomized between 2000 and 4000 meters.
|
||||||
|
-- SpawnAirplanes:SpawnInZone( SpawnZone, true, 2000, 4000 )
|
||||||
|
--
|
||||||
|
-- -- Spawn at the zone center position at the height randomized between 2000 and 4000 meters.
|
||||||
|
-- SpawnAirplanes:SpawnInZone( SpawnZone, false, 2000, 4000 )
|
||||||
|
--
|
||||||
|
-- -- Spawn at the zone center position at the height randomized between 2000 and 4000 meters.
|
||||||
|
-- SpawnAirplanes:SpawnInZone( SpawnZone, nil, 2000, 4000 )
|
||||||
|
--
|
||||||
|
function SPAWN:SpawnInZone( Zone, RandomizeGroup, MinHeight, MaxHeight, SpawnIndex )
|
||||||
|
self:F( { self.SpawnTemplatePrefix, Zone, RandomizeGroup, MinHeight, MaxHeight, SpawnIndex } )
|
||||||
|
|
||||||
if Zone then
|
if Zone then
|
||||||
if RandomizeGroup then
|
if RandomizeGroup then
|
||||||
return self:SpawnFromVec2( Zone:GetRandomVec2(), SpawnIndex )
|
return self:SpawnFromVec2( Zone:GetRandomVec2(), MinHeight, MaxHeight, SpawnIndex )
|
||||||
else
|
else
|
||||||
return self:SpawnFromVec2( Zone:GetVec2(), SpawnIndex )
|
return self:SpawnFromVec2( Zone:GetVec2(), MinHeight, MaxHeight, SpawnIndex )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1769,6 +1927,7 @@ function SPAWN:_GetSpawnIndex( SpawnIndex )
|
|||||||
|
|
||||||
if ( self.SpawnMaxGroups == 0 ) or ( SpawnIndex <= self.SpawnMaxGroups ) then
|
if ( self.SpawnMaxGroups == 0 ) or ( SpawnIndex <= self.SpawnMaxGroups ) then
|
||||||
if ( self.SpawnMaxUnitsAlive == 0 ) or ( self.AliveUnits + #self.SpawnTemplate.units <= self.SpawnMaxUnitsAlive ) or self.UnControlled == true then
|
if ( self.SpawnMaxUnitsAlive == 0 ) or ( self.AliveUnits + #self.SpawnTemplate.units <= self.SpawnMaxUnitsAlive ) or self.UnControlled == true then
|
||||||
|
self:F( { SpawnCount = self.SpawnCount, SpawnIndex = SpawnIndex } )
|
||||||
if SpawnIndex and SpawnIndex >= self.SpawnCount + 1 then
|
if SpawnIndex and SpawnIndex >= self.SpawnCount + 1 then
|
||||||
self.SpawnCount = self.SpawnCount + 1
|
self.SpawnCount = self.SpawnCount + 1
|
||||||
SpawnIndex = self.SpawnCount
|
SpawnIndex = self.SpawnCount
|
||||||
@@ -2,11 +2,11 @@
|
|||||||
--
|
--
|
||||||
-- 
|
-- 
|
||||||
--
|
--
|
||||||
-- ====
|
-- ===
|
||||||
--
|
--
|
||||||
-- SPAWNSTATIC spawns static structures in your missions dynamically. See below the SPAWNSTATIC class documentation.
|
-- SPAWNSTATIC spawns static structures in your missions dynamically. See below the SPAWNSTATIC class documentation.
|
||||||
--
|
--
|
||||||
-- ====
|
-- ===
|
||||||
--
|
--
|
||||||
-- # Demo Missions
|
-- # Demo Missions
|
||||||
--
|
--
|
||||||
@@ -16,18 +16,18 @@
|
|||||||
--
|
--
|
||||||
-- ### [ALL Demo Missions pack of the last release](https://github.com/FlightControl-Master/MOOSE_MISSIONS/releases)
|
-- ### [ALL Demo Missions pack of the last release](https://github.com/FlightControl-Master/MOOSE_MISSIONS/releases)
|
||||||
--
|
--
|
||||||
-- ====
|
-- ===
|
||||||
--
|
--
|
||||||
-- # YouTube Channel
|
-- # YouTube Channel
|
||||||
--
|
--
|
||||||
-- ### [SPAWNSTATIC YouTube Channel]()
|
-- ### [SPAWNSTATIC YouTube Channel]()
|
||||||
--
|
--
|
||||||
-- ====
|
-- ===
|
||||||
--
|
--
|
||||||
-- ### Author: **Sven Van de Velde (FlightControl)**
|
-- ### Author: **FlightControl**
|
||||||
-- ### Contributions:
|
-- ### Contributions:
|
||||||
--
|
--
|
||||||
-- ====
|
-- ===
|
||||||
--
|
--
|
||||||
-- @module SpawnStatic
|
-- @module SpawnStatic
|
||||||
|
|
||||||
@@ -116,6 +116,33 @@ function SPAWNSTATIC:NewFromType( SpawnTypeName, SpawnShapeName, SpawnCategory,
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Creates a new @{Static} at the original position.
|
||||||
|
-- @param #SPAWNSTATIC self
|
||||||
|
-- @param #number Heading The heading of the static, which is a number in degrees from 0 to 360.
|
||||||
|
-- @param #string (optional) The name of the new static.
|
||||||
|
-- @return #SPAWNSTATIC
|
||||||
|
function SPAWNSTATIC:Spawn( Heading, NewName ) --R2.3
|
||||||
|
self:F( { Heading, NewName } )
|
||||||
|
|
||||||
|
local CountryName = _DATABASE.COUNTRY_NAME[self.CountryID]
|
||||||
|
|
||||||
|
local StaticTemplate = _DATABASE:GetStaticUnitTemplate( self.SpawnTemplatePrefix )
|
||||||
|
|
||||||
|
StaticTemplate.name = NewName or string.format("%s#%05d", self.SpawnTemplatePrefix, self.SpawnIndex )
|
||||||
|
StaticTemplate.heading = ( Heading / 180 ) * math.pi
|
||||||
|
|
||||||
|
StaticTemplate.CountryID = nil
|
||||||
|
StaticTemplate.CoalitionID = nil
|
||||||
|
StaticTemplate.CategoryID = nil
|
||||||
|
|
||||||
|
local Static = coalition.addStaticObject( self.CountryID, StaticTemplate )
|
||||||
|
|
||||||
|
self.SpawnIndex = self.SpawnIndex + 1
|
||||||
|
|
||||||
|
return Static
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--- Creates a new @{Static} from a POINT_VEC2.
|
--- Creates a new @{Static} from a POINT_VEC2.
|
||||||
-- @param #SPAWNSTATIC self
|
-- @param #SPAWNSTATIC self
|
||||||
@@ -130,8 +157,13 @@ function SPAWNSTATIC:SpawnFromPointVec2( PointVec2, Heading, NewName ) --R2.1
|
|||||||
|
|
||||||
local StaticTemplate = _DATABASE:GetStaticUnitTemplate( self.SpawnTemplatePrefix )
|
local StaticTemplate = _DATABASE:GetStaticUnitTemplate( self.SpawnTemplatePrefix )
|
||||||
|
|
||||||
StaticTemplate.x = PointVec2:GetLat()
|
StaticTemplate.x = PointVec2.x
|
||||||
StaticTemplate.y = PointVec2:GetLon()
|
StaticTemplate.y = PointVec2.z
|
||||||
|
|
||||||
|
StaticTemplate.units = nil
|
||||||
|
StaticTemplate.route = nil
|
||||||
|
StaticTemplate.groupId = nil
|
||||||
|
|
||||||
|
|
||||||
StaticTemplate.name = NewName or string.format("%s#%05d", self.SpawnTemplatePrefix, self.SpawnIndex )
|
StaticTemplate.name = NewName or string.format("%s#%05d", self.SpawnTemplatePrefix, self.SpawnIndex )
|
||||||
StaticTemplate.heading = ( Heading / 180 ) * math.pi
|
StaticTemplate.heading = ( Heading / 180 ) * math.pi
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
--
|
--
|
||||||
-- 
|
-- 
|
||||||
--
|
--
|
||||||
-- ====
|
-- ===
|
||||||
--
|
--
|
||||||
-- SPOT implements the DCS Spot class functionality, but adds additional luxury to be able to:
|
-- SPOT implements the DCS Spot class functionality, but adds additional luxury to be able to:
|
||||||
--
|
--
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
-- * Provide a @{Unit} as a target, instead of a point.
|
-- * Provide a @{Unit} as a target, instead of a point.
|
||||||
-- * Implement a status machine, LaseOn, LaseOff.
|
-- * Implement a status machine, LaseOn, LaseOff.
|
||||||
--
|
--
|
||||||
-- ====
|
-- ===
|
||||||
--
|
--
|
||||||
-- # Demo Missions
|
-- # Demo Missions
|
||||||
--
|
--
|
||||||
@@ -21,22 +21,22 @@
|
|||||||
--
|
--
|
||||||
-- ### [ALL Demo Missions pack of the last release](https://github.com/FlightControl-Master/MOOSE_MISSIONS/releases)
|
-- ### [ALL Demo Missions pack of the last release](https://github.com/FlightControl-Master/MOOSE_MISSIONS/releases)
|
||||||
--
|
--
|
||||||
-- ====
|
-- ===
|
||||||
--
|
--
|
||||||
-- # YouTube Channel
|
-- # YouTube Channel
|
||||||
--
|
--
|
||||||
-- ### [SPOT YouTube Channel]()
|
-- ### [SPOT YouTube Channel]()
|
||||||
--
|
--
|
||||||
-- ====
|
-- ===
|
||||||
--
|
--
|
||||||
-- ### Author: **Sven Van de Velde (FlightControl)**
|
-- ### Author: **FlightControl**
|
||||||
-- ### Contributions:
|
-- ### Contributions:
|
||||||
--
|
--
|
||||||
-- * [**Ciribob**](https://forums.eagle.ru/member.php?u=112175): Showing the way how to lase targets + how laser codes work!!! Explained the autolase script.
|
-- * [**Ciribob**](https://forums.eagle.ru/member.php?u=112175): Showing the way how to lase targets + how laser codes work!!! Explained the autolase script.
|
||||||
-- * [**EasyEB**](https://forums.eagle.ru/member.php?u=112055): Ideas and Beta Testing
|
-- * [**EasyEB**](https://forums.eagle.ru/member.php?u=112055): Ideas and Beta Testing
|
||||||
-- * [**Wingthor**](https://forums.eagle.ru/member.php?u=123698): Beta Testing
|
-- * [**Wingthor**](https://forums.eagle.ru/member.php?u=123698): Beta Testing
|
||||||
--
|
--
|
||||||
-- ====
|
-- ===
|
||||||
--
|
--
|
||||||
-- @module Spot
|
-- @module Spot
|
||||||
|
|
||||||
@@ -200,7 +200,7 @@ do
|
|||||||
-- @param #number LaserCode
|
-- @param #number LaserCode
|
||||||
-- @param #number Duration
|
-- @param #number Duration
|
||||||
function SPOT:onafterLaseOn( From, Event, To, Target, LaserCode, Duration )
|
function SPOT:onafterLaseOn( From, Event, To, Target, LaserCode, Duration )
|
||||||
self:E( { "LaseOn", Target, LaserCode, Duration } )
|
self:F( { "LaseOn", Target, LaserCode, Duration } )
|
||||||
|
|
||||||
local function StopLase( self )
|
local function StopLase( self )
|
||||||
self:LaseOff()
|
self:LaseOff()
|
||||||
@@ -228,10 +228,10 @@ do
|
|||||||
--- @param #SPOT self
|
--- @param #SPOT self
|
||||||
-- @param Core.Event#EVENTDATA EventData
|
-- @param Core.Event#EVENTDATA EventData
|
||||||
function SPOT:OnEventDead(EventData)
|
function SPOT:OnEventDead(EventData)
|
||||||
self:E( { Dead = EventData.IniDCSUnitName, Target = self.Target } )
|
self:F( { Dead = EventData.IniDCSUnitName, Target = self.Target } )
|
||||||
if self.Target then
|
if self.Target then
|
||||||
if EventData.IniDCSUnitName == self.Target:GetName() then
|
if EventData.IniDCSUnitName == self.Target:GetName() then
|
||||||
self:E( {"Target dead ", self.Target:GetName() } )
|
self:F( {"Target dead ", self.Target:GetName() } )
|
||||||
self:Destroyed()
|
self:Destroyed()
|
||||||
self:LaseOff()
|
self:LaseOff()
|
||||||
end
|
end
|
||||||
@@ -249,7 +249,7 @@ do
|
|||||||
self.SpotLaser:setPoint( self.Target:GetPointVec3():AddY(1):GetVec3() )
|
self.SpotLaser:setPoint( self.Target:GetPointVec3():AddY(1):GetVec3() )
|
||||||
self:__Lasing( -0.2 )
|
self:__Lasing( -0.2 )
|
||||||
else
|
else
|
||||||
self:E( { "Target is not alive", self.Target:IsAlive() } )
|
self:F( { "Target is not alive", self.Target:IsAlive() } )
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -261,7 +261,7 @@ do
|
|||||||
-- @return #SPOT
|
-- @return #SPOT
|
||||||
function SPOT:onafterLaseOff( From, Event, To )
|
function SPOT:onafterLaseOff( From, Event, To )
|
||||||
|
|
||||||
self:E( {"Stopped lasing for ", self.Target:GetName() , SpotIR = self.SportIR, SpotLaser = self.SpotLaser } )
|
self:F( {"Stopped lasing for ", self.Target:GetName() , SpotIR = self.SportIR, SpotLaser = self.SpotLaser } )
|
||||||
|
|
||||||
self.Lasing = false
|
self.Lasing = false
|
||||||
|
|
||||||
|
|||||||
95
Moose Development/Moose/Core/UserFlag.lua
Normal file
95
Moose Development/Moose/Core/UserFlag.lua
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
--- **Core (WIP)** -- Manage user flags.
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- Management of DCS User Flags.
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- ### Author: **FlightControl**
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- @module UserFlag
|
||||||
|
|
||||||
|
do -- UserFlag
|
||||||
|
|
||||||
|
--- @type USERFLAG
|
||||||
|
-- @extends Core.Base#BASE
|
||||||
|
|
||||||
|
|
||||||
|
--- # USERFLAG class, extends @{Base#BASE}
|
||||||
|
--
|
||||||
|
-- Management of DCS User Flags.
|
||||||
|
--
|
||||||
|
-- ## 1. USERFLAG constructor
|
||||||
|
--
|
||||||
|
-- * @{#USERFLAG.New}(): Creates a new USERFLAG object.
|
||||||
|
--
|
||||||
|
-- @field #USERFLAG
|
||||||
|
USERFLAG = {
|
||||||
|
ClassName = "USERFLAG",
|
||||||
|
}
|
||||||
|
|
||||||
|
--- USERFLAG Constructor.
|
||||||
|
-- @param #USERFLAG self
|
||||||
|
-- @param #string UserFlagName The name of the userflag, which is a free text string.
|
||||||
|
-- @return #USERFLAG
|
||||||
|
function USERFLAG:New( UserFlagName ) --R2.3
|
||||||
|
|
||||||
|
local self = BASE:Inherit( self, BASE:New() ) -- #USERFLAG
|
||||||
|
|
||||||
|
self.UserFlagName = UserFlagName
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Set the userflag to a given Number.
|
||||||
|
-- @param #USERFLAG self
|
||||||
|
-- @param #number Number The number value to be checked if it is the same as the userflag.
|
||||||
|
-- @return #USERFLAG The userflag instance.
|
||||||
|
-- @usage
|
||||||
|
-- local BlueVictory = USERFLAG:New( "VictoryBlue" )
|
||||||
|
-- BlueVictory:Set( 100 ) -- Set the UserFlag VictoryBlue to 100.
|
||||||
|
--
|
||||||
|
function USERFLAG:Set( Number ) --R2.3
|
||||||
|
|
||||||
|
self:F( { Number = Number } )
|
||||||
|
|
||||||
|
trigger.action.setUserFlag( self.UserFlagName, Number )
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Get the userflag Number.
|
||||||
|
-- @param #USERFLAG self
|
||||||
|
-- @return #number Number The number value to be checked if it is the same as the userflag.
|
||||||
|
-- @usage
|
||||||
|
-- local BlueVictory = USERFLAG:New( "VictoryBlue" )
|
||||||
|
-- local BlueVictoryValue = BlueVictory:Get() -- Get the UserFlag VictoryBlue value.
|
||||||
|
--
|
||||||
|
function USERFLAG:Get( Number ) --R2.3
|
||||||
|
|
||||||
|
return trigger.misc.getUserFlag( self.UserFlagName )
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--- Check if the userflag has a value of Number.
|
||||||
|
-- @param #USERFLAG self
|
||||||
|
-- @param #number Number The number value to be checked if it is the same as the userflag.
|
||||||
|
-- @return #boolean true if the Number is the value of the userflag.
|
||||||
|
-- @usage
|
||||||
|
-- local BlueVictory = USERFLAG:New( "VictoryBlue" )
|
||||||
|
-- if BlueVictory:Is( 1 ) then
|
||||||
|
-- return "Blue has won"
|
||||||
|
-- end
|
||||||
|
function USERFLAG:Is( Number ) --R2.3
|
||||||
|
|
||||||
|
return trigger.misc.getUserFlag( self.UserFlagName ) == Number
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
129
Moose Development/Moose/Core/UserSound.lua
Normal file
129
Moose Development/Moose/Core/UserSound.lua
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
--- **Core (WIP)** -- Manage user sound.
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- Management of DCS User Sound.
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- ### Author: **FlightControl**
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- @module UserSound
|
||||||
|
|
||||||
|
do -- UserSound
|
||||||
|
|
||||||
|
--- @type USERSOUND
|
||||||
|
-- @extends Core.Base#BASE
|
||||||
|
|
||||||
|
|
||||||
|
--- # USERSOUND class, extends @{Base#BASE}
|
||||||
|
--
|
||||||
|
-- Management of DCS User Sound.
|
||||||
|
--
|
||||||
|
-- ## 1. USERSOUND constructor
|
||||||
|
--
|
||||||
|
-- * @{#USERSOUND.New}(): Creates a new USERSOUND object.
|
||||||
|
--
|
||||||
|
-- @field #USERSOUND
|
||||||
|
USERSOUND = {
|
||||||
|
ClassName = "USERSOUND",
|
||||||
|
}
|
||||||
|
|
||||||
|
--- USERSOUND Constructor.
|
||||||
|
-- @param #USERSOUND self
|
||||||
|
-- @param #string UserSoundFileName The filename of the usersound.
|
||||||
|
-- @return #USERSOUND
|
||||||
|
function USERSOUND:New( UserSoundFileName ) --R2.3
|
||||||
|
|
||||||
|
local self = BASE:Inherit( self, BASE:New() ) -- #USERSOUND
|
||||||
|
|
||||||
|
self.UserSoundFileName = UserSoundFileName
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Set usersound filename.
|
||||||
|
-- @param #USERSOUND self
|
||||||
|
-- @param #string UserSoundFileName The filename of the usersound.
|
||||||
|
-- @return #USERSOUND The usersound instance.
|
||||||
|
-- @usage
|
||||||
|
-- local BlueVictory = USERSOUND:New( "BlueVictory.ogg" )
|
||||||
|
-- BlueVictory:SetFileName( "BlueVictoryLoud.ogg" ) -- Set the BlueVictory to change the file name to play a louder sound.
|
||||||
|
--
|
||||||
|
function USERSOUND:SetFileName( UserSoundFileName ) --R2.3
|
||||||
|
|
||||||
|
self.UserSoundFileName = UserSoundFileName
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--- Play the usersound to all players.
|
||||||
|
-- @param #USERSOUND self
|
||||||
|
-- @return #USERSOUND The usersound instance.
|
||||||
|
-- @usage
|
||||||
|
-- local BlueVictory = USERSOUND:New( "BlueVictory.ogg" )
|
||||||
|
-- BlueVictory:ToAll() -- Play the sound that Blue has won.
|
||||||
|
--
|
||||||
|
function USERSOUND:ToAll() --R2.3
|
||||||
|
|
||||||
|
trigger.action.outSound( self.UserSoundFileName )
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Play the usersound to the given coalition.
|
||||||
|
-- @param #USERSOUND self
|
||||||
|
-- @param Dcs.DCScoalition#coalition Coalition The coalition to play the usersound to.
|
||||||
|
-- @return #USERSOUND The usersound instance.
|
||||||
|
-- @usage
|
||||||
|
-- local BlueVictory = USERSOUND:New( "BlueVictory.ogg" )
|
||||||
|
-- BlueVictory:ToCoalition( coalition.side.BLUE ) -- Play the sound that Blue has won to the blue coalition.
|
||||||
|
--
|
||||||
|
function USERSOUND:ToCoalition( Coalition ) --R2.3
|
||||||
|
|
||||||
|
trigger.action.outSoundForCoalition(Coalition, self.UserSoundFileName )
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Play the usersound to the given country.
|
||||||
|
-- @param #USERSOUND self
|
||||||
|
-- @param Dcs.DCScountry#country Country The country to play the usersound to.
|
||||||
|
-- @return #USERSOUND The usersound instance.
|
||||||
|
-- @usage
|
||||||
|
-- local BlueVictory = USERSOUND:New( "BlueVictory.ogg" )
|
||||||
|
-- BlueVictory:ToCountry( country.id.USA ) -- Play the sound that Blue has won to the USA country.
|
||||||
|
--
|
||||||
|
function USERSOUND:ToCountry( Country ) --R2.3
|
||||||
|
|
||||||
|
trigger.action.outSoundForCountry( Country, self.UserSoundFileName )
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Play the usersound to the given @{Group}.
|
||||||
|
-- @param #USERSOUND self
|
||||||
|
-- @param Wrapper.Group#GROUP Group The @{Group} to play the usersound to.
|
||||||
|
-- @return #USERSOUND The usersound instance.
|
||||||
|
-- @usage
|
||||||
|
-- local BlueVictory = USERSOUND:New( "BlueVictory.ogg" )
|
||||||
|
-- local PlayerGroup = GROUP:FindByName( "PlayerGroup" ) -- Search for the active group named "PlayerGroup", that contains a human player.
|
||||||
|
-- BlueVictory:ToGroup( PlayerGroup ) -- Play the sound that Blue has won to the player group.
|
||||||
|
--
|
||||||
|
function USERSOUND:ToGroup( Group ) --R2.3
|
||||||
|
|
||||||
|
trigger.action.outSoundForGroup( Group:GetID(), self.UserSoundFileName )
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
184
Moose Development/Moose/Core/Velocity.lua
Normal file
184
Moose Development/Moose/Core/Velocity.lua
Normal file
@@ -0,0 +1,184 @@
|
|||||||
|
--- **Core** -- VELOCITY models a speed, which can be expressed in various formats according the Settings.
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- ### Author: **FlightControl**
|
||||||
|
-- ### Contributions:
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- @module Velocity
|
||||||
|
|
||||||
|
do -- Velocity
|
||||||
|
|
||||||
|
--- @type VELOCITY
|
||||||
|
-- @extends Core.Base#BASE
|
||||||
|
|
||||||
|
|
||||||
|
--- # VELOCITY class, extends @{Base#BASE}
|
||||||
|
--
|
||||||
|
-- VELOCITY models a speed, which can be expressed in various formats according the Settings.
|
||||||
|
--
|
||||||
|
-- ## 1. VELOCITY constructor
|
||||||
|
--
|
||||||
|
-- * @{#VELOCITY.New}(): Creates a new VELOCITY object.
|
||||||
|
--
|
||||||
|
-- @field #VELOCITY
|
||||||
|
VELOCITY = {
|
||||||
|
ClassName = "VELOCITY",
|
||||||
|
}
|
||||||
|
|
||||||
|
--- VELOCITY Constructor.
|
||||||
|
-- @param #VELOCITY self
|
||||||
|
-- @param #number VelocityMps The velocity in meters per second.
|
||||||
|
-- @return #VELOCITY
|
||||||
|
function VELOCITY:New( VelocityMps )
|
||||||
|
local self = BASE:Inherit( self, BASE:New() ) -- #VELOCITY
|
||||||
|
self:F( {} )
|
||||||
|
self.Velocity = VelocityMps
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Set the velocity in Mps (meters per second).
|
||||||
|
-- @param #VELOCITY self
|
||||||
|
-- @param #number VelocityMps The velocity in meters per second.
|
||||||
|
-- @return #VELOCITY
|
||||||
|
function VELOCITY:Set( VelocityMps )
|
||||||
|
self.Velocity = VelocityMps
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get the velocity in Mps (meters per second).
|
||||||
|
-- @param #VELOCITY self
|
||||||
|
-- @return #number The velocity in meters per second.
|
||||||
|
function VELOCITY:Get()
|
||||||
|
return self.Velocity
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Set the velocity in Kmph (kilometers per hour).
|
||||||
|
-- @param #VELOCITY self
|
||||||
|
-- @param #number VelocityKmph The velocity in kilometers per hour.
|
||||||
|
-- @return #VELOCITY
|
||||||
|
function VELOCITY:SetKmph( VelocityKmph )
|
||||||
|
self.Velocity = UTILS.KmphToMps( VelocityKmph )
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get the velocity in Kmph (kilometers per hour).
|
||||||
|
-- @param #VELOCITY self
|
||||||
|
-- @return #number The velocity in kilometers per hour.
|
||||||
|
function VELOCITY:GetKmph()
|
||||||
|
|
||||||
|
return UTILS.MpsToKmph( self.Velocity )
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Set the velocity in Miph (miles per hour).
|
||||||
|
-- @param #VELOCITY self
|
||||||
|
-- @param #number VelocityMiph The velocity in miles per hour.
|
||||||
|
-- @return #VELOCITY
|
||||||
|
function VELOCITY:SetMiph( VelocityMiph )
|
||||||
|
self.Velocity = UTILS.MiphToMps( VelocityMiph )
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get the velocity in Miph (miles per hour).
|
||||||
|
-- @param #VELOCITY self
|
||||||
|
-- @return #number The velocity in miles per hour.
|
||||||
|
function VELOCITY:GetMiph()
|
||||||
|
return UTILS.MpsToMiph( self.Velocity )
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Get the velocity in text, according the player @{Settings}.
|
||||||
|
-- @param #VELOCITY self
|
||||||
|
-- @param Core.Settings#SETTINGS Settings
|
||||||
|
-- @return #string The velocity in text.
|
||||||
|
function VELOCITY:GetText( Settings )
|
||||||
|
local Settings = Settings or _SETTINGS
|
||||||
|
if self.Velocity ~= 0 then
|
||||||
|
if Settings:IsMetric() then
|
||||||
|
return string.format( "%d km/h", UTILS.MpsToKmph( self.Velocity ) )
|
||||||
|
else
|
||||||
|
return string.format( "%d mi/h", UTILS.MpsToMiph( self.Velocity ) )
|
||||||
|
end
|
||||||
|
else
|
||||||
|
return "stationary"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get the velocity in text, according the player or default @{Settings}.
|
||||||
|
-- @param #VELOCITY self
|
||||||
|
-- @param Wrapper.Controllable#CONTROLLABLE Controllable
|
||||||
|
-- @param Core.Settings#SETTINGS Settings
|
||||||
|
-- @return #string The velocity in text according the player or default @{Settings}
|
||||||
|
function VELOCITY:ToString( VelocityGroup, Settings ) -- R2.3
|
||||||
|
self:F( { Group = VelocityGroup and VelocityGroup:GetName() } )
|
||||||
|
local Settings = Settings or ( VelocityGroup and _DATABASE:GetPlayerSettings( VelocityGroup:GetPlayerName() ) ) or _SETTINGS
|
||||||
|
return self:GetText( Settings )
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
do -- VELOCITY_POSITIONABLE
|
||||||
|
|
||||||
|
--- @type VELOCITY_POSITIONABLE
|
||||||
|
-- @extends Core.Base#BASE
|
||||||
|
|
||||||
|
|
||||||
|
--- # VELOCITY_POSITIONABLE class, extends @{Base#BASE}
|
||||||
|
--
|
||||||
|
-- VELOCITY_POSITIONABLE monitors the speed of an @{Positionable} in the simulation, which can be expressed in various formats according the Settings.
|
||||||
|
--
|
||||||
|
-- ## 1. VELOCITY_POSITIONABLE constructor
|
||||||
|
--
|
||||||
|
-- * @{#VELOCITY_POSITIONABLE.New}(): Creates a new VELOCITY_POSITIONABLE object.
|
||||||
|
--
|
||||||
|
-- @field #VELOCITY_POSITIONABLE
|
||||||
|
VELOCITY_POSITIONABLE = {
|
||||||
|
ClassName = "VELOCITY_POSITIONABLE",
|
||||||
|
}
|
||||||
|
|
||||||
|
--- VELOCITY_POSITIONABLE Constructor.
|
||||||
|
-- @param #VELOCITY_POSITIONABLE self
|
||||||
|
-- @param Wrapper.Positionable#POSITIONABLE Positionable The Positionable to monitor the speed.
|
||||||
|
-- @return #VELOCITY_POSITIONABLE
|
||||||
|
function VELOCITY_POSITIONABLE:New( Positionable )
|
||||||
|
local self = BASE:Inherit( self, VELOCITY:New() ) -- #VELOCITY_POSITIONABLE
|
||||||
|
self:F( {} )
|
||||||
|
self.Positionable = Positionable
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get the velocity in Mps (meters per second).
|
||||||
|
-- @param #VELOCITY_POSITIONABLE self
|
||||||
|
-- @return #number The velocity in meters per second.
|
||||||
|
function VELOCITY_POSITIONABLE:Get()
|
||||||
|
return self.Positionable:GetVelocityMPS() or 0
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get the velocity in Kmph (kilometers per hour).
|
||||||
|
-- @param #VELOCITY_POSITIONABLE self
|
||||||
|
-- @return #number The velocity in kilometers per hour.
|
||||||
|
function VELOCITY_POSITIONABLE:GetKmph()
|
||||||
|
|
||||||
|
return UTILS.MpsToKmph( self.Positionable:GetVelocityMPS() or 0)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get the velocity in Miph (miles per hour).
|
||||||
|
-- @param #VELOCITY_POSITIONABLE self
|
||||||
|
-- @return #number The velocity in miles per hour.
|
||||||
|
function VELOCITY_POSITIONABLE:GetMiph()
|
||||||
|
return UTILS.MpsToMiph( self.Positionable:GetVelocityMPS() or 0 )
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get the velocity in text, according the player or default @{Settings}.
|
||||||
|
-- @param #VELOCITY_POSITIONABLE self
|
||||||
|
-- @return #string The velocity in text according the player or default @{Settings}
|
||||||
|
function VELOCITY_POSITIONABLE:ToString() -- R2.3
|
||||||
|
self:F( { Group = self.Positionable and self.Positionable:GetName() } )
|
||||||
|
local Settings = Settings or ( self.Positionable and _DATABASE:GetPlayerSettings( self.Positionable:GetPlayerName() ) ) or _SETTINGS
|
||||||
|
self.Velocity = self.Positionable:GetVelocityMPS()
|
||||||
|
return self:GetText( Settings )
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
--
|
--
|
||||||
-- 
|
-- 
|
||||||
--
|
--
|
||||||
-- ====
|
-- ===
|
||||||
--
|
--
|
||||||
-- There are essentially two core functions that zones accomodate:
|
-- There are essentially two core functions that zones accomodate:
|
||||||
--
|
--
|
||||||
@@ -27,12 +27,12 @@
|
|||||||
-- * @{#ZONE_GROUP}: The ZONE_GROUP class defines by a zone around a @{Group#GROUP} with a radius.
|
-- * @{#ZONE_GROUP}: The ZONE_GROUP class defines by a zone around a @{Group#GROUP} with a radius.
|
||||||
-- * @{#ZONE_POLYGON}: The ZONE_POLYGON class defines by a sequence of @{Group#GROUP} waypoints within the Mission Editor, forming a polygon.
|
-- * @{#ZONE_POLYGON}: The ZONE_POLYGON class defines by a sequence of @{Group#GROUP} waypoints within the Mission Editor, forming a polygon.
|
||||||
--
|
--
|
||||||
-- ====
|
-- ===
|
||||||
--
|
--
|
||||||
-- ### Author: **Sven Van de Velde (FlightControl)**
|
-- ### Author: **FlightControl**
|
||||||
-- ### Contributions:
|
-- ### Contributions:
|
||||||
--
|
--
|
||||||
-- ====
|
-- ===
|
||||||
--
|
--
|
||||||
-- @module Zone
|
-- @module Zone
|
||||||
|
|
||||||
@@ -50,6 +50,8 @@
|
|||||||
-- ## Each zone has a name:
|
-- ## Each zone has a name:
|
||||||
--
|
--
|
||||||
-- * @{#ZONE_BASE.GetName}(): Returns the name of the zone.
|
-- * @{#ZONE_BASE.GetName}(): Returns the name of the zone.
|
||||||
|
-- * @{#ZONE_BASE.SetName}(): Sets the name of the zone.
|
||||||
|
--
|
||||||
--
|
--
|
||||||
-- ## Each zone implements two polymorphic functions defined in @{Zone#ZONE_BASE}:
|
-- ## Each zone implements two polymorphic functions defined in @{Zone#ZONE_BASE}:
|
||||||
--
|
--
|
||||||
@@ -121,6 +123,17 @@ function ZONE_BASE:GetName()
|
|||||||
return self.ZoneName
|
return self.ZoneName
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Sets the name of the zone.
|
||||||
|
-- @param #ZONE_BASE self
|
||||||
|
-- @param #string ZoneName The name of the zone.
|
||||||
|
-- @return #ZONE_BASE
|
||||||
|
function ZONE_BASE:SetName( ZoneName )
|
||||||
|
self:F2()
|
||||||
|
|
||||||
|
self.ZoneName = ZoneName
|
||||||
|
end
|
||||||
|
|
||||||
--- Returns if a Vec2 is within the zone.
|
--- Returns if a Vec2 is within the zone.
|
||||||
-- @param #ZONE_BASE self
|
-- @param #ZONE_BASE self
|
||||||
-- @param Dcs.DCSTypes#Vec2 Vec2 The Vec2 to test.
|
-- @param Dcs.DCSTypes#Vec2 Vec2 The Vec2 to test.
|
||||||
@@ -445,12 +458,17 @@ end
|
|||||||
-- @param #ZONE_RADIUS self
|
-- @param #ZONE_RADIUS self
|
||||||
-- @param Utilities.Utils#SMOKECOLOR SmokeColor The smoke color.
|
-- @param Utilities.Utils#SMOKECOLOR SmokeColor The smoke color.
|
||||||
-- @param #number Points (optional) The amount of points in the circle.
|
-- @param #number Points (optional) The amount of points in the circle.
|
||||||
|
-- @param #number AddHeight (optional) The height to be added for the smoke.
|
||||||
|
-- @param #number AddOffSet (optional) The angle to be added for the smoking start position.
|
||||||
-- @return #ZONE_RADIUS self
|
-- @return #ZONE_RADIUS self
|
||||||
function ZONE_RADIUS:SmokeZone( SmokeColor, Points )
|
function ZONE_RADIUS:SmokeZone( SmokeColor, Points, AddHeight, AngleOffset )
|
||||||
self:F2( SmokeColor )
|
self:F2( SmokeColor )
|
||||||
|
|
||||||
local Point = {}
|
local Point = {}
|
||||||
local Vec2 = self:GetVec2()
|
local Vec2 = self:GetVec2()
|
||||||
|
|
||||||
|
AddHeight = AddHeight or 0
|
||||||
|
AngleOffset = AngleOffset or 0
|
||||||
|
|
||||||
Points = Points and Points or 360
|
Points = Points and Points or 360
|
||||||
|
|
||||||
@@ -458,10 +476,10 @@ function ZONE_RADIUS:SmokeZone( SmokeColor, Points )
|
|||||||
local RadialBase = math.pi*2
|
local RadialBase = math.pi*2
|
||||||
|
|
||||||
for Angle = 0, 360, 360 / Points do
|
for Angle = 0, 360, 360 / Points do
|
||||||
local Radial = Angle * RadialBase / 360
|
local Radial = ( Angle + AngleOffset ) * RadialBase / 360
|
||||||
Point.x = Vec2.x + math.cos( Radial ) * self:GetRadius()
|
Point.x = Vec2.x + math.cos( Radial ) * self:GetRadius()
|
||||||
Point.y = Vec2.y + math.sin( Radial ) * self:GetRadius()
|
Point.y = Vec2.y + math.sin( Radial ) * self:GetRadius()
|
||||||
POINT_VEC2:New( Point.x, Point.y ):Smoke( SmokeColor )
|
POINT_VEC2:New( Point.x, Point.y, AddHeight ):Smoke( SmokeColor )
|
||||||
end
|
end
|
||||||
|
|
||||||
return self
|
return self
|
||||||
@@ -473,13 +491,16 @@ end
|
|||||||
-- @param Utilities.Utils#FLARECOLOR FlareColor The flare color.
|
-- @param Utilities.Utils#FLARECOLOR FlareColor The flare color.
|
||||||
-- @param #number Points (optional) The amount of points in the circle.
|
-- @param #number Points (optional) The amount of points in the circle.
|
||||||
-- @param Dcs.DCSTypes#Azimuth Azimuth (optional) Azimuth The azimuth of the flare.
|
-- @param Dcs.DCSTypes#Azimuth Azimuth (optional) Azimuth The azimuth of the flare.
|
||||||
|
-- @param #number AddHeight (optional) The height to be added for the smoke.
|
||||||
-- @return #ZONE_RADIUS self
|
-- @return #ZONE_RADIUS self
|
||||||
function ZONE_RADIUS:FlareZone( FlareColor, Points, Azimuth )
|
function ZONE_RADIUS:FlareZone( FlareColor, Points, Azimuth, AddHeight )
|
||||||
self:F2( { FlareColor, Azimuth } )
|
self:F2( { FlareColor, Azimuth } )
|
||||||
|
|
||||||
local Point = {}
|
local Point = {}
|
||||||
local Vec2 = self:GetVec2()
|
local Vec2 = self:GetVec2()
|
||||||
|
|
||||||
|
AddHeight = AddHeight or 0
|
||||||
|
|
||||||
Points = Points and Points or 360
|
Points = Points and Points or 360
|
||||||
|
|
||||||
local Angle
|
local Angle
|
||||||
@@ -489,7 +510,7 @@ function ZONE_RADIUS:FlareZone( FlareColor, Points, Azimuth )
|
|||||||
local Radial = Angle * RadialBase / 360
|
local Radial = Angle * RadialBase / 360
|
||||||
Point.x = Vec2.x + math.cos( Radial ) * self:GetRadius()
|
Point.x = Vec2.x + math.cos( Radial ) * self:GetRadius()
|
||||||
Point.y = Vec2.y + math.sin( Radial ) * self:GetRadius()
|
Point.y = Vec2.y + math.sin( Radial ) * self:GetRadius()
|
||||||
POINT_VEC2:New( Point.x, Point.y ):Flare( FlareColor, Azimuth )
|
POINT_VEC2:New( Point.x, Point.y, AddHeight ):Flare( FlareColor, Azimuth )
|
||||||
end
|
end
|
||||||
|
|
||||||
return self
|
return self
|
||||||
@@ -562,6 +583,225 @@ function ZONE_RADIUS:GetVec3( Height )
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Scan the zone for the presence of units of the given ObjectCategories.
|
||||||
|
-- Note that after a zone has been scanned, the zone can be evaluated by:
|
||||||
|
--
|
||||||
|
-- * @{ZONE_RADIUS.IsAllInZoneOfCoalition}(): Scan the presence of units in the zone of a coalition.
|
||||||
|
-- * @{ZONE_RADIUS.IsAllInZoneOfOtherCoalition}(): Scan the presence of units in the zone of an other coalition.
|
||||||
|
-- * @{ZONE_RADIUS.IsSomeInZoneOfCoalition}(): Scan if there is some presence of units in the zone of the given coalition.
|
||||||
|
-- * @{ZONE_RADIUS.IsNoneInZoneOfCoalition}(): Scan if there isn't any presence of units in the zone of an other coalition than the given one.
|
||||||
|
-- * @{ZONE_RADIUS.IsNoneInZone}(): Scan if the zone is empty.
|
||||||
|
-- @{#ZONE_RADIUS.
|
||||||
|
-- @param #ZONE_RADIUS self
|
||||||
|
-- @param ObjectCategories
|
||||||
|
-- @param Coalition
|
||||||
|
-- @usage
|
||||||
|
-- self.Zone:Scan()
|
||||||
|
-- local IsAttacked = self.Zone:IsSomeInZoneOfCoalition( self.Coalition )
|
||||||
|
function ZONE_RADIUS:Scan( ObjectCategories )
|
||||||
|
|
||||||
|
self.ScanData = {}
|
||||||
|
self.ScanData.Coalitions = {}
|
||||||
|
self.ScanData.Scenery = {}
|
||||||
|
|
||||||
|
local ZoneCoord = self:GetCoordinate()
|
||||||
|
local ZoneRadius = self:GetRadius()
|
||||||
|
|
||||||
|
self:F({ZoneCoord = ZoneCoord, ZoneRadius = ZoneRadius, ZoneCoordLL = ZoneCoord:ToStringLLDMS()})
|
||||||
|
|
||||||
|
local SphereSearch = {
|
||||||
|
id = world.VolumeType.SPHERE,
|
||||||
|
params = {
|
||||||
|
point = ZoneCoord:GetVec3(),
|
||||||
|
radius = ZoneRadius,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
local function EvaluateZone( ZoneObject )
|
||||||
|
--if ZoneObject:isExist() then --FF: isExist always returns false for SCENERY objects since DCS 2.2 and still in DCS 2.5
|
||||||
|
if ZoneObject then
|
||||||
|
local ObjectCategory = ZoneObject:getCategory()
|
||||||
|
if ( ObjectCategory == Object.Category.UNIT and ZoneObject:isExist() and ZoneObject:isActive() ) or
|
||||||
|
(ObjectCategory == Object.Category.STATIC and ZoneObject:isExist()) then
|
||||||
|
local CoalitionDCSUnit = ZoneObject:getCoalition()
|
||||||
|
self.ScanData.Coalitions[CoalitionDCSUnit] = true
|
||||||
|
self:F( { Name = ZoneObject:getName(), Coalition = CoalitionDCSUnit } )
|
||||||
|
end
|
||||||
|
if ObjectCategory == Object.Category.SCENERY then
|
||||||
|
local SceneryType = ZoneObject:getTypeName()
|
||||||
|
local SceneryName = ZoneObject:getName()
|
||||||
|
self.ScanData.Scenery[SceneryType] = self.ScanData.Scenery[SceneryType] or {}
|
||||||
|
self.ScanData.Scenery[SceneryType][SceneryName] = SCENERY:Register( SceneryName, ZoneObject )
|
||||||
|
self:F( { SCENERY = self.ScanData.Scenery[SceneryType][SceneryName] } )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
world.searchObjects( ObjectCategories, SphereSearch, EvaluateZone )
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function ZONE_RADIUS:CountScannedCoalitions()
|
||||||
|
|
||||||
|
local Count = 0
|
||||||
|
|
||||||
|
for CoalitionID, Coalition in pairs( self.ScanData.Coalitions ) do
|
||||||
|
Count = Count + 1
|
||||||
|
end
|
||||||
|
return Count
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Get Coalitions of the units in the Zone, or Check if there are units of the given Coalition in the Zone.
|
||||||
|
-- Returns nil if there are none ot two Coalitions in the zone!
|
||||||
|
-- Returns one Coalition if there are only Units of one Coalition in the Zone.
|
||||||
|
-- Returns the Coalition for the given Coalition if there are units of the Coalition in the Zone
|
||||||
|
-- @param #ZONE_RADIUS self
|
||||||
|
-- @return #table
|
||||||
|
function ZONE_RADIUS:GetScannedCoalition( Coalition )
|
||||||
|
|
||||||
|
if Coalition then
|
||||||
|
return self.ScanData.Coalitions[Coalition]
|
||||||
|
else
|
||||||
|
local Count = 0
|
||||||
|
local ReturnCoalition = nil
|
||||||
|
|
||||||
|
for CoalitionID, Coalition in pairs( self.ScanData.Coalitions ) do
|
||||||
|
Count = Count + 1
|
||||||
|
ReturnCoalition = CoalitionID
|
||||||
|
end
|
||||||
|
|
||||||
|
if Count ~= 1 then
|
||||||
|
ReturnCoalition = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
return ReturnCoalition
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function ZONE_RADIUS:GetScannedSceneryType( SceneryType )
|
||||||
|
return self.ScanData.Scenery[SceneryType]
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function ZONE_RADIUS:GetScannedScenery()
|
||||||
|
return self.ScanData.Scenery
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Is All in Zone of Coalition?
|
||||||
|
-- @param #ZONE_RADIUS self
|
||||||
|
-- @param Coalition
|
||||||
|
-- @return #boolean
|
||||||
|
-- @usage
|
||||||
|
-- self.Zone:Scan()
|
||||||
|
-- local IsGuarded = self.Zone:IsAllInZoneOfCoalition( self.Coalition )
|
||||||
|
function ZONE_RADIUS:IsAllInZoneOfCoalition( Coalition )
|
||||||
|
|
||||||
|
--self:E( { Coalitions = self.Coalitions, Count = self:CountScannedCoalitions() } )
|
||||||
|
return self:CountScannedCoalitions() == 1 and self:GetScannedCoalition( Coalition ) == true
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Is All in Zone of Other Coalition?
|
||||||
|
-- You first need to use the @{#ZONE_RADIUS.Scan} method to scan the zone before it can be evaluated!
|
||||||
|
-- Note that once a zone has been scanned, multiple evaluations can be done on the scan result set.
|
||||||
|
-- @param #ZONE_RADIUS self
|
||||||
|
-- @param Coalition
|
||||||
|
-- @return #boolean
|
||||||
|
-- @usage
|
||||||
|
-- self.Zone:Scan()
|
||||||
|
-- local IsCaptured = self.Zone:IsAllInZoneOfOtherCoalition( self.Coalition )
|
||||||
|
function ZONE_RADIUS:IsAllInZoneOfOtherCoalition( Coalition )
|
||||||
|
|
||||||
|
--self:E( { Coalitions = self.Coalitions, Count = self:CountScannedCoalitions() } )
|
||||||
|
return self:CountScannedCoalitions() == 1 and self:GetScannedCoalition( Coalition ) == nil
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Is Some in Zone of Coalition?
|
||||||
|
-- You first need to use the @{#ZONE_RADIUS.Scan} method to scan the zone before it can be evaluated!
|
||||||
|
-- Note that once a zone has been scanned, multiple evaluations can be done on the scan result set.
|
||||||
|
-- @param #ZONE_RADIUS self
|
||||||
|
-- @param Coalition
|
||||||
|
-- @return #boolean
|
||||||
|
-- @usage
|
||||||
|
-- self.Zone:Scan()
|
||||||
|
-- local IsAttacked = self.Zone:IsSomeInZoneOfCoalition( self.Coalition )
|
||||||
|
function ZONE_RADIUS:IsSomeInZoneOfCoalition( Coalition )
|
||||||
|
|
||||||
|
return self:CountScannedCoalitions() > 1 and self:GetScannedCoalition( Coalition ) == true
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Is None in Zone of Coalition?
|
||||||
|
-- You first need to use the @{#ZONE_RADIUS.Scan} method to scan the zone before it can be evaluated!
|
||||||
|
-- Note that once a zone has been scanned, multiple evaluations can be done on the scan result set.
|
||||||
|
-- @param #ZONE_RADIUS self
|
||||||
|
-- @param Coalition
|
||||||
|
-- @return #boolean
|
||||||
|
-- @usage
|
||||||
|
-- self.Zone:Scan()
|
||||||
|
-- local IsOccupied = self.Zone:IsNoneInZoneOfCoalition( self.Coalition )
|
||||||
|
function ZONE_RADIUS:IsNoneInZoneOfCoalition( Coalition )
|
||||||
|
|
||||||
|
return self:GetScannedCoalition( Coalition ) == nil
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Is None in Zone?
|
||||||
|
-- You first need to use the @{#ZONE_RADIUS.Scan} method to scan the zone before it can be evaluated!
|
||||||
|
-- Note that once a zone has been scanned, multiple evaluations can be done on the scan result set.
|
||||||
|
-- @param #ZONE_RADIUS self
|
||||||
|
-- @return #boolean
|
||||||
|
-- @usage
|
||||||
|
-- self.Zone:Scan()
|
||||||
|
-- local IsEmpty = self.Zone:IsNoneInZone()
|
||||||
|
function ZONE_RADIUS:IsNoneInZone()
|
||||||
|
|
||||||
|
return self:CountScannedCoalitions() == 0
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--- Searches the zone
|
||||||
|
-- @param #ZONE_RADIUS self
|
||||||
|
-- @param ObjectCategories A list of categories, which are members of Object.Category
|
||||||
|
-- @param EvaluateFunction
|
||||||
|
function ZONE_RADIUS:SearchZone( EvaluateFunction, ObjectCategories )
|
||||||
|
|
||||||
|
local SearchZoneResult = true
|
||||||
|
|
||||||
|
local ZoneCoord = self:GetCoordinate()
|
||||||
|
local ZoneRadius = self:GetRadius()
|
||||||
|
|
||||||
|
self:F({ZoneCoord = ZoneCoord, ZoneRadius = ZoneRadius, ZoneCoordLL = ZoneCoord:ToStringLLDMS()})
|
||||||
|
|
||||||
|
local SphereSearch = {
|
||||||
|
id = world.VolumeType.SPHERE,
|
||||||
|
params = {
|
||||||
|
point = ZoneCoord:GetVec3(),
|
||||||
|
radius = ZoneRadius / 2,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
local function EvaluateZone( ZoneDCSUnit )
|
||||||
|
|
||||||
|
env.info( ZoneDCSUnit:getName() )
|
||||||
|
|
||||||
|
local ZoneUnit = UNIT:Find( ZoneDCSUnit )
|
||||||
|
|
||||||
|
return EvaluateFunction( ZoneUnit )
|
||||||
|
end
|
||||||
|
|
||||||
|
world.searchObjects( Object.Category.UNIT, SphereSearch, EvaluateZone )
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
--- Returns if a location is within the zone.
|
--- Returns if a location is within the zone.
|
||||||
-- @param #ZONE_RADIUS self
|
-- @param #ZONE_RADIUS self
|
||||||
-- @param Dcs.DCSTypes#Vec2 Vec2 The location to test.
|
-- @param Dcs.DCSTypes#Vec2 Vec2 The location to test.
|
||||||
@@ -622,13 +862,29 @@ end
|
|||||||
function ZONE_RADIUS:GetRandomPointVec2( inner, outer )
|
function ZONE_RADIUS:GetRandomPointVec2( inner, outer )
|
||||||
self:F( self.ZoneName, inner, outer )
|
self:F( self.ZoneName, inner, outer )
|
||||||
|
|
||||||
local PointVec2 = POINT_VEC2:NewFromVec2( self:GetRandomVec2() )
|
local PointVec2 = POINT_VEC2:NewFromVec2( self:GetRandomVec2( inner, outer ) )
|
||||||
|
|
||||||
self:T3( { PointVec2 } )
|
self:T3( { PointVec2 } )
|
||||||
|
|
||||||
return PointVec2
|
return PointVec2
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Returns Returns a random Vec3 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#Vec3 The random location within the zone.
|
||||||
|
function ZONE_RADIUS:GetRandomVec3( inner, outer )
|
||||||
|
self:F( self.ZoneName, inner, outer )
|
||||||
|
|
||||||
|
local Vec2 = self:GetRandomVec2( inner, outer )
|
||||||
|
|
||||||
|
self:T3( { x = Vec2.x, y = self.y, z = Vec2.y } )
|
||||||
|
|
||||||
|
return { x = Vec2.x, y = self.y, z = Vec2.y }
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Returns a @{Point#POINT_VEC3} object reflecting a random 3D location within the zone.
|
--- Returns a @{Point#POINT_VEC3} object reflecting a random 3D location within the zone.
|
||||||
-- @param #ZONE_RADIUS self
|
-- @param #ZONE_RADIUS self
|
||||||
-- @param #number inner (optional) Minimal distance from the center of the zone. Default is 0.
|
-- @param #number inner (optional) Minimal distance from the center of the zone. Default is 0.
|
||||||
@@ -637,7 +893,7 @@ end
|
|||||||
function ZONE_RADIUS:GetRandomPointVec3( inner, outer )
|
function ZONE_RADIUS:GetRandomPointVec3( inner, outer )
|
||||||
self:F( self.ZoneName, inner, outer )
|
self:F( self.ZoneName, inner, outer )
|
||||||
|
|
||||||
local PointVec3 = POINT_VEC3:NewFromVec2( self:GetRandomVec2() )
|
local PointVec3 = POINT_VEC3:NewFromVec2( self:GetRandomVec2( inner, outer ) )
|
||||||
|
|
||||||
self:T3( { PointVec3 } )
|
self:T3( { PointVec3 } )
|
||||||
|
|
||||||
@@ -1158,7 +1414,7 @@ ZONE_POLYGON = {
|
|||||||
ClassName="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.
|
--- Constructor to create a ZONE_POLYGON instance, taking the zone name and 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.
|
-- 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 #ZONE_POLYGON self
|
||||||
-- @param #string ZoneName Name of the zone.
|
-- @param #string ZoneName Name of the zone.
|
||||||
@@ -1174,3 +1430,22 @@ function ZONE_POLYGON:New( ZoneName, ZoneGroup )
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- 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 #string GroupName The group name of the GROUP defining the waypoints within the Mission Editor to define the polygon shape.
|
||||||
|
-- @return #ZONE_POLYGON self
|
||||||
|
function ZONE_POLYGON:NewFromGroupName( GroupName )
|
||||||
|
|
||||||
|
local ZoneGroup = GROUP:FindByName( GroupName )
|
||||||
|
|
||||||
|
local GroupPoints = ZoneGroup:GetTaskRoute()
|
||||||
|
|
||||||
|
local self = BASE:Inherit( self, ZONE_POLYGON_BASE:New( GroupName, GroupPoints ) )
|
||||||
|
self:F( { GroupName, ZoneGroup, self._.Polygon } )
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|||||||
Submodule Moose Development/Moose/Dcs deleted from 53f6e5cd52
54
Moose Development/Moose/Dcs/DCSAirbase.lua
Normal file
54
Moose Development/Moose/Dcs/DCSAirbase.lua
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
-------------------------------------------------------------------------------
|
||||||
|
-- @module DCSAirbase
|
||||||
|
|
||||||
|
|
||||||
|
--- Represents airbases: airdromes, helipads and ships with flying decks or landing pads.
|
||||||
|
-- @type Airbase
|
||||||
|
-- @extends Dcs.DCSCoalitionWrapper.Object#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 Wrapper.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
|
||||||
20
Moose Development/Moose/Dcs/DCSCoalitionObject.lua
Normal file
20
Moose Development/Moose/Dcs/DCSCoalitionObject.lua
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
-------------------------------------------------------------------------------
|
||||||
|
-- @module DCSCoalitionObject
|
||||||
|
|
||||||
|
--- @type CoalitionObject
|
||||||
|
-- @extends Dcs.DCSWrapper.Object#Object
|
||||||
|
|
||||||
|
coalition = {} --#coalition
|
||||||
|
|
||||||
|
--- Returns coalition of the object.
|
||||||
|
-- @function [parent=#CoalitionObject] getCoalition
|
||||||
|
-- @param #CoalitionObject self
|
||||||
|
-- @return Dcs.DCSTypes#coalition.side
|
||||||
|
|
||||||
|
--- Returns object country.
|
||||||
|
-- @function [parent=#CoalitionObject] getCountry
|
||||||
|
-- @param #CoalitionObject self
|
||||||
|
-- @return #country.id
|
||||||
|
|
||||||
|
|
||||||
|
CoalitionObject = {} --#CoalitionObject
|
||||||
10
Moose Development/Moose/Dcs/DCSCommand.lua
Normal file
10
Moose Development/Moose/Dcs/DCSCommand.lua
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
--- @module DCSCommand
|
||||||
|
|
||||||
|
|
||||||
|
--- @type Command
|
||||||
|
-- @field #string id
|
||||||
|
-- @field #Command.params params
|
||||||
|
|
||||||
|
--- @type Command.params
|
||||||
|
|
||||||
|
env.info( "Command defined" )
|
||||||
115
Moose Development/Moose/Dcs/DCSController.lua
Normal file
115
Moose Development/Moose/Dcs/DCSController.lua
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
-------------------------------------------------------------------------------
|
||||||
|
-- @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 Wrapper.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 Wrapper.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 Wrapper.Object#Object object The target.
|
||||||
|
-- @param #boolean type Target type is known.
|
||||||
|
-- @param #boolean distance Distance to target is known.
|
||||||
|
|
||||||
|
|
||||||
|
Controller = {} --#Controller
|
||||||
83
Moose Development/Moose/Dcs/DCSGroup.lua
Normal file
83
Moose Development/Moose/Dcs/DCSGroup.lua
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
-------------------------------------------------------------------------------
|
||||||
|
-- @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 the coalition of the group.
|
||||||
|
-- @function [parent=#Group] getCoalition
|
||||||
|
-- @param #Group self
|
||||||
|
-- @return Dcs.DCSCoalitionWrapper.Object#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 Dcs.DCSWrapper.Unit#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<Dcs.DCSWrapper.Unit#Unit> array of Units
|
||||||
|
|
||||||
|
--- Returns controller of the group.
|
||||||
|
-- @function [parent=#Group] getController
|
||||||
|
-- @param #Group self
|
||||||
|
-- @return Controller#Controller
|
||||||
|
|
||||||
|
Group = {} --#Group
|
||||||
|
|
||||||
73
Moose Development/Moose/Dcs/DCSObject.lua
Normal file
73
Moose Development/Moose/Dcs/DCSObject.lua
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
-------------------------------------------------------------------------------
|
||||||
|
-- @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
|
||||||
|
|
||||||
34
Moose Development/Moose/Dcs/DCSStaticObject.lua
Normal file
34
Moose Development/Moose/Dcs/DCSStaticObject.lua
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
-------------------------------------------------------------------------------
|
||||||
|
-- @module DCSStaticObject
|
||||||
|
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
-- @module StaticObject
|
||||||
|
-- @extends CoalitionWrapper.Object#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 Wrapper.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
|
||||||
15
Moose Development/Moose/Dcs/DCSTask.lua
Normal file
15
Moose Development/Moose/Dcs/DCSTask.lua
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
--- @module DCSTask
|
||||||
|
|
||||||
|
|
||||||
|
--- A task descriptor (internal structure for DCS World)
|
||||||
|
-- @type Task
|
||||||
|
-- @field #string id
|
||||||
|
-- @field #Task.param param
|
||||||
|
|
||||||
|
--- @type Task.param
|
||||||
|
|
||||||
|
--- List of @{#Task}
|
||||||
|
-- @type TaskArray
|
||||||
|
-- @list <#Task>
|
||||||
|
|
||||||
|
env.info( "Task defined" )
|
||||||
8
Moose Development/Moose/Dcs/DCSTime.lua
Normal file
8
Moose Development/Moose/Dcs/DCSTime.lua
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
-------------------------------------------------------------------------------
|
||||||
|
-- @module DCSTime
|
||||||
|
|
||||||
|
--- @type ModelTime
|
||||||
|
-- @extends #number
|
||||||
|
|
||||||
|
--- @type Time
|
||||||
|
-- @extends #number
|
||||||
246
Moose Development/Moose/Dcs/DCSTypes.lua
Normal file
246
Moose Development/Moose/Dcs/DCSTypes.lua
Normal file
@@ -0,0 +1,246 @@
|
|||||||
|
-------------------------------------------------------------------------------
|
||||||
|
-- @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
|
||||||
|
|
||||||
|
--- AttributeName = string
|
||||||
|
-- Each object type may have attributes.
|
||||||
|
-- Attributes are enlisted in ./Scripts/Database/db_attributes.Lua.
|
||||||
|
-- To know what attributes the object type has, look for the unit type script in sub-directories planes/, helicopter/s, vehicles, navy/ of ./Scripts/Database/ directory.
|
||||||
|
-- @type AttributeName
|
||||||
|
-- @extends #string
|
||||||
|
|
||||||
|
--- List of @{#AttributeName}
|
||||||
|
-- @type AttributeNameArray
|
||||||
|
-- @list <#AttributeName>
|
||||||
|
|
||||||
|
--- @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
Moose Development/Moose/Dcs/DCSUnit.lua
Normal file
241
Moose Development/Moose/Dcs/DCSUnit.lua
Normal file
@@ -0,0 +1,241 @@
|
|||||||
|
-------------------------------------------------------------------------------
|
||||||
|
-- @module DCSUnit
|
||||||
|
|
||||||
|
--- @type Unit
|
||||||
|
-- @extends Dcs.DCSCoalitionWrapper.Object#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 Wrapper.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 Wrapper.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 Wrapper.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 Wrapper.Unit#Unit.DescAircraft
|
||||||
|
-- @field #Distance HmaxStat static ceiling
|
||||||
|
|
||||||
|
--- A vehicle descriptor.
|
||||||
|
-- @type Unit.DescVehicle
|
||||||
|
-- @extends Wrapper.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 Wrapper.Unit#Unit.Sensor
|
||||||
|
-- @field #Unit.OpticType opticType
|
||||||
|
|
||||||
|
--- A radar.
|
||||||
|
-- @type Unit.Radar
|
||||||
|
-- @extends Wrapper.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 Wrapper.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 Wrapper.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 Dcs.DCSWrapper.Group#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, Wrapper.Object#Object
|
||||||
|
|
||||||
|
--- Returns unit descriptor. Descriptor type depends on unit category.
|
||||||
|
-- @function [parent=#Unit] getDesc
|
||||||
|
-- @param #Unit self
|
||||||
|
-- @return #Unit.Desc
|
||||||
|
|
||||||
|
|
||||||
|
Unit = {} --#Unit
|
||||||
11
Moose Development/Moose/Dcs/DCSVec3.lua
Normal file
11
Moose Development/Moose/Dcs/DCSVec3.lua
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
-------------------------------------------------------------------------------
|
||||||
|
-- @module DCSVec3
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
-- @type Vec3
|
||||||
|
-- @field #number x
|
||||||
|
-- @field #number y
|
||||||
|
-- @field #number z
|
||||||
|
Vec3 = {}
|
||||||
10
Moose Development/Moose/Dcs/DCSZone.lua
Normal file
10
Moose Development/Moose/Dcs/DCSZone.lua
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
-------------------------------------------------------------------------------
|
||||||
|
-- @module DCSZone
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
-- @type Zone
|
||||||
|
-- @field DCSVec3#Vec3 point
|
||||||
|
-- @field #number radius
|
||||||
|
Zone = {}
|
||||||
14
Moose Development/Moose/Dcs/DCScoalition.lua
Normal file
14
Moose Development/Moose/Dcs/DCScoalition.lua
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
-------------------------------------------------------------------------------
|
||||||
|
-- @module DCScoalition
|
||||||
|
|
||||||
|
--- @type coalition
|
||||||
|
-- @field #coalition.side side
|
||||||
|
|
||||||
|
--- @type coalition.side
|
||||||
|
-- @field NEUTRAL
|
||||||
|
-- @field RED
|
||||||
|
-- @field BLUE
|
||||||
|
|
||||||
|
--- @function [parent=#coalition] getCountryCoalition
|
||||||
|
-- @param #number countryId
|
||||||
|
-- @return #number coalitionId
|
||||||
27
Moose Development/Moose/Dcs/DCScountry.lua
Normal file
27
Moose Development/Moose/Dcs/DCScountry.lua
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
-------------------------------------------------------------------------------
|
||||||
|
-- @module DCScountry
|
||||||
|
|
||||||
|
--- @type country
|
||||||
|
-- @field #country.id id
|
||||||
|
country = country -- #country
|
||||||
|
|
||||||
|
--- @type country.id
|
||||||
|
-- @field RUSSIA
|
||||||
|
-- @field UKRAINE
|
||||||
|
-- @field USA
|
||||||
|
-- @field TURKEY
|
||||||
|
-- @field UK
|
||||||
|
-- @field FRANCE
|
||||||
|
-- @field GERMANY
|
||||||
|
-- @field CANADA
|
||||||
|
-- @field SPAIN
|
||||||
|
-- @field THE_NETHERLANDS
|
||||||
|
-- @field BELGIUM
|
||||||
|
-- @field NORWAY
|
||||||
|
-- @field DENMARK
|
||||||
|
-- @field ISRAEL
|
||||||
|
-- @field GEORGIA
|
||||||
|
-- @field INSURGENTS
|
||||||
|
-- @field ABKHAZIA
|
||||||
|
-- @field SOUTH_OSETIA
|
||||||
|
-- @field ITALY
|
||||||
27
Moose Development/Moose/Dcs/DCSenv.lua
Normal file
27
Moose Development/Moose/Dcs/DCSenv.lua
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
-------------------------------------------------------------------------------
|
||||||
|
-- @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
|
||||||
26
Moose Development/Moose/Dcs/DCSland.lua
Normal file
26
Moose Development/Moose/Dcs/DCSland.lua
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
-------------------------------------------------------------------------------
|
||||||
|
-- @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 Dcs.DCSTypes#Distance
|
||||||
|
|
||||||
|
--- returns surface type at the given point.
|
||||||
|
-- @function [parent=#land] getSurfaceType
|
||||||
|
-- @param #Vec2 point Point on the land.
|
||||||
|
-- @return #land.SurfaceType
|
||||||
|
|
||||||
|
|
||||||
|
land = {} --#land
|
||||||
45
Moose Development/Moose/Dcs/DCStimer.lua
Normal file
45
Moose Development/Moose/Dcs/DCStimer.lua
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
-------------------------------------------------------------------------------
|
||||||
|
-- @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
|
||||||
8
Moose Development/Moose/Dcs/DCStrigger.lua
Normal file
8
Moose Development/Moose/Dcs/DCStrigger.lua
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
-------------------------------------------------------------------------------
|
||||||
|
-- @module DCStrigger
|
||||||
|
|
||||||
|
|
||||||
|
trigger = {} --#timer
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
35
Moose Development/Moose/Dcs/DCSworld.lua
Normal file
35
Moose Development/Moose/Dcs/DCSworld.lua
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
-------------------------------------------------------------------------------
|
||||||
|
-- @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
|
||||||
2311
Moose Development/Moose/Functional/ATC_Ground.lua
Normal file
2311
Moose Development/Moose/Functional/ATC_Ground.lua
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -2,10 +2,10 @@
|
|||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
-- ### Author: **Sven Van de Velde (FlightControl)**
|
-- ### Author: **FlightControl**
|
||||||
-- ### Contributions:
|
-- ### Contributions:
|
||||||
--
|
--
|
||||||
-- ====
|
-- ===
|
||||||
--
|
--
|
||||||
-- @module CleanUp
|
-- @module CleanUp
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
--- **Functional** -- Management of target **Designation**. Lase, smoke and illuminate targets.
|
--- **Functional** -- Management of target **Designation**. Lase, smoke and illuminate targets.
|
||||||
--
|
--
|
||||||
-- --
|
|
||||||
--
|
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
-- DESIGNATE is orchestrating the designation of potential targets executed by a Recce group,
|
-- DESIGNATE is orchestrating the designation of potential targets executed by a Recce group,
|
||||||
@@ -40,12 +38,9 @@ do -- DESIGNATE
|
|||||||
|
|
||||||
--- # DESIGNATE class, extends @{Fsm#FSM}
|
--- # DESIGNATE class, extends @{Fsm#FSM}
|
||||||
--
|
--
|
||||||
-- DESIGNATE is orchestrating the designation of potential targets executed by a Recce group,
|
-- DESIGNATE is managing the designation of detected targets.
|
||||||
-- and communicates these to a dedicated attacking group of players,
|
-- Targets detected by recce will be communicated to a group of attacking players.
|
||||||
-- so that following a dynamically generated menu system,
|
-- A menu system is made available that allows to:
|
||||||
-- each detected set of potential targets can be lased or smoked...
|
|
||||||
--
|
|
||||||
-- Targets can be:
|
|
||||||
--
|
--
|
||||||
-- * **Lased** for a period of time.
|
-- * **Lased** for a period of time.
|
||||||
-- * **Smoked**. Artillery or airplanes with Illuminatino ordonance need to be present. (WIP, but early demo ready.)
|
-- * **Smoked**. Artillery or airplanes with Illuminatino ordonance need to be present. (WIP, but early demo ready.)
|
||||||
@@ -55,8 +50,8 @@ do -- DESIGNATE
|
|||||||
--
|
--
|
||||||
-- * The **DesignateObject** is the object of the DESIGNATE class, which is this class explained in the document.
|
-- * The **DesignateObject** is the object of the DESIGNATE class, which is this class explained in the document.
|
||||||
-- * The **DetectionObject** is the object of a DETECTION_ class (DETECTION_TYPES, DETECTION_AREAS, DETECTION_UNITS), which is executing the detection and grouping of Targets into _DetectionItems_.
|
-- * The **DetectionObject** is the object of a DETECTION_ class (DETECTION_TYPES, DETECTION_AREAS, DETECTION_UNITS), which is executing the detection and grouping of Targets into _DetectionItems_.
|
||||||
-- * **DetectionItems** is the list of detected target groupings by the _DetectionObject_. Each _DetectionItem_ contains a _TargetSet_.
|
-- * **TargetGroups** is the list of detected target groupings by the _DetectionObject_. Each _TargetGroup_ contains a _TargetSet_.
|
||||||
-- * **DetectionItem** is one element of the _DetectionItems_ list, and contains a _TargetSet_.
|
-- * **TargetGroup** is one element of the __TargetGroups__ list, and contains a _TargetSet_.
|
||||||
-- * The **TargetSet** is a SET_UNITS collection of _Targets_, that have been detected by the _DetectionObject_.
|
-- * The **TargetSet** is a SET_UNITS collection of _Targets_, that have been detected by the _DetectionObject_.
|
||||||
-- * A **Target** is a detected UNIT object by the _DetectionObject_.
|
-- * A **Target** is a detected UNIT object by the _DetectionObject_.
|
||||||
-- * A **Threat Level** is a number from 0 to 10 that is calculated based on the threat of the Target in an Air to Ground battle scenario.
|
-- * A **Threat Level** is a number from 0 to 10 that is calculated based on the threat of the Target in an Air to Ground battle scenario.
|
||||||
@@ -67,39 +62,122 @@ do -- DESIGNATE
|
|||||||
-- * A **Player** is an active CLIENT object containing a human player.
|
-- * A **Player** is an active CLIENT object containing a human player.
|
||||||
-- * A **Designate Menu** is the menu that is dynamically created during the designation process for each _AttackGroup_.
|
-- * A **Designate Menu** is the menu that is dynamically created during the designation process for each _AttackGroup_.
|
||||||
--
|
--
|
||||||
-- The RecceSet is continuously detecting for potential Targets, executing its task as part of the DetectionObject.
|
-- ## 0. Player Manual
|
||||||
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
|
-- A typical mission setup would require Recce (a @{Set} of Recce) to be detecting potential targets.
|
||||||
|
-- The DetectionObject will group the detected targets based on the detection method being used.
|
||||||
|
-- Possible detection methods could be by Area, by Type or by Unit.
|
||||||
|
-- Each grouping will result in a **TargetGroup**, for terminology and clarity we will use this term throughout the document.
|
||||||
|
--
|
||||||
|
-- **Recce** require to have Line of Sight (LOS) towards the targets.
|
||||||
|
-- The **Recce** will report any detected targets to the Players (on the picture Observers).
|
||||||
|
-- When targets are detected, a menu will be made available that allows those **TargetGroups** to be designated.
|
||||||
|
-- Designation can be done by Lasing, Smoking and Illumination.
|
||||||
|
-- Smoking is useful during the day, while illumination is recommended to be used during the night.
|
||||||
|
-- Smoking can designate specific targets, but not very precise, while lasing is very accurate and allows to
|
||||||
|
-- players to attack the targets using laser guided bombs or rockets.
|
||||||
|
-- Illumination will lighten up the Target Area.
|
||||||
|
--
|
||||||
|
-- **Recce** can be ground based or airborne. Airborne **Recce** (AFAC) can be really useful to designate a large amount of targets
|
||||||
|
-- in a wide open area, as airborne **Recce** has a large LOS.
|
||||||
|
-- However, ground based **Recce** are very useful to smoke or illuminate targets, as they can be much closer
|
||||||
|
-- to the Target Area.
|
||||||
|
--
|
||||||
|
-- It is recommended to make the **Recce** invisible and immortal using the Mission Editor in DCS World.
|
||||||
|
-- This will ensure that the detection process won't be interrupted and that targets can be designated.
|
||||||
|
-- However, you don't have to, so to simulate a more real-word situation or simulation, **Recce can also be destroyed**!
|
||||||
|
--
|
||||||
|
-- ### 0.1. Player View (Observer)
|
||||||
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
|
-- The RecceSet is continuously detecting for potential Targets,
|
||||||
|
-- executing its task as part of the DetectionObject.
|
||||||
-- Once Targets have been detected, the DesignateObject will trigger the **Detect Event**.
|
-- Once Targets have been detected, the DesignateObject will trigger the **Detect Event**.
|
||||||
--
|
--
|
||||||
-- In order to prevent an overflow in the DesignateObject of detected targets, there is a maximum
|
-- In order to prevent an overflow in the DesignateObject of detected targets,
|
||||||
-- amount of DetectionItems that can be put in **scope** of the DesignateObject.
|
-- there is a maximum amount of TargetGroups
|
||||||
|
-- that can be put in **scope** of the DesignateObject.
|
||||||
-- We call this the **MaximumDesignations** term.
|
-- We call this the **MaximumDesignations** term.
|
||||||
--
|
--
|
||||||
-- As part of the Detect Event, the DetectionItems list is used by the DesignateObject to provide the Players with:
|
-- ### 0.2. Designate Menu
|
||||||
--
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
|
-- For each detected TargetGroup, there is:
|
||||||
|
--
|
||||||
|
-- * A **Designate Menu** are created and continuously refreshed, containing the **DesignationID** and the **Designation Status**.
|
||||||
-- * The RecceGroups are reporting to each AttackGroup, sending **Messages** containing the Threat Level and the TargetSet composition.
|
-- * The RecceGroups are reporting to each AttackGroup, sending **Messages** containing the Threat Level and the TargetSet composition.
|
||||||
-- * **Menu options** are created and updated for each AttackGroup, containing the Detection ID and the Coordinates.
|
|
||||||
--
|
--
|
||||||
-- A Player can then select an action from the Designate Menu.
|
-- A Player can then select an action from the **Designate Menu**.
|
||||||
|
-- The Designation Status is shown between the ( ).
|
||||||
--
|
--
|
||||||
-- **Note that each selected action will be executed for a TargetSet, thus the Target grouping done by the DetectionObject.**
|
-- It indicates for each TargetGroup the current active designation action applied:
|
||||||
--
|
--
|
||||||
-- Each **Menu Option** in the Designate Menu has two modes:
|
-- * An "I" for Illumnation designation.
|
||||||
|
-- * An "S" for Smoking designation.
|
||||||
|
-- * An "L" for Lasing designation.
|
||||||
|
--
|
||||||
|
-- Note that multiple designation methods can be active at the same time!
|
||||||
|
-- Note the **Auto Lase** option. When switched on, the available **Recce** will lase
|
||||||
|
-- Targets when detected.
|
||||||
--
|
--
|
||||||
-- 1. If the TargetSet **is not being designated**, then the **Designate Menu** option for the target Set will provide options to **Lase** or **Smoke** the targets.
|
-- Targets are designated per **Threat Level**.
|
||||||
-- 2. If the Target Set **is being designated**, then the **Designate Menu** option will provide an option to stop or cancel the designation.
|
-- The most threatening targets from an Air to Ground perspective, are designated first!
|
||||||
|
-- This is for all designation methods.
|
||||||
--
|
--
|
||||||
-- While designating, the RecceGroups will report any change in TargetSet composition or Target presence.
|
-- 
|
||||||
--
|
--
|
||||||
-- The following logic is executed when a TargetSet is selected to be *lased* from the Designation Menu:
|
-- Each Designate Menu has a sub menu structure, which allows specific actions to be triggered:
|
||||||
--
|
--
|
||||||
-- * The RecceSet is searched for any Recce that is within *designation distance* from a Target in the TargetSet that is currently not being designated.
|
-- * Lase Targets using a specific laser code.
|
||||||
|
-- * Smoke Targets using a specific smoke color.
|
||||||
|
-- * Illuminate areas.
|
||||||
|
--
|
||||||
|
-- ### 0.3. Lasing Targets
|
||||||
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
|
-- Lasing targets is done as expected. Each available Recce can lase only ONE target through!
|
||||||
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
|
-- Lasing can be done for specific laser codes. The Su-25T requires laser code 1113, while the A-10A requires laser code 1680.
|
||||||
|
-- For those, specific menu options can be made available for players to lase with these codes.
|
||||||
|
-- Auto Lase (as explained above), will ensure continuous lasing of available targets.
|
||||||
|
-- The status report shows which targets are being designated.
|
||||||
|
--
|
||||||
|
-- The following logic is executed when a TargetGroup is selected to be *lased* from the Designation Menu:
|
||||||
|
--
|
||||||
|
-- * The RecceSet is searched for any Recce that is within *designation distance* from a Target in the TargetGroup that is currently not being designated.
|
||||||
-- * If there is a Recce found that is currently no designating a target, and is within designation distance from the Target, then that Target will be designated.
|
-- * If there is a Recce found that is currently no designating a target, and is within designation distance from the Target, then that Target will be designated.
|
||||||
-- * During designation, any Recce that does not have Line of Sight (LOS) and is not within disignation distance from the Target, will stop designating the Target, and a report is given.
|
-- * During designation, any Recce that does not have Line of Sight (LOS) and is not within disignation distance from the Target, will stop designating the Target, and a report is given.
|
||||||
-- * When a Recce is designating a Target, and that Target is destroyed, then the Recce will stop designating the Target, and will report the event.
|
-- * When a Recce is designating a Target, and that Target is destroyed, then the Recce will stop designating the Target, and will report the event.
|
||||||
-- * When a Recce is designating a Target, and that Recce is destroyed, then the Recce will be removed from the RecceSet and designation will stop without reporting.
|
-- * When a Recce is designating a Target, and that Recce is destroyed, then the Recce will be removed from the RecceSet and designation will stop without reporting.
|
||||||
-- * When all RecceGroups are destroyed from the RecceSet, then the DesignationObject will stop functioning, and nothing will be reported.
|
-- * When all RecceGroups are destroyed from the RecceSet, then the DesignationObject will stop functioning, and nothing will be reported.
|
||||||
--
|
--
|
||||||
-- In this way, the DesignationObject assists players to designate ground targets for a coordinated attack!
|
-- In this way, DESIGNATE assists players to designate ground targets for a coordinated attack!
|
||||||
|
--
|
||||||
|
-- ### 0.4. Illuminating Targets
|
||||||
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
|
-- Illumination bombs are fired between 500 and 700 meters altitude and will burn about 2 minutes, while slowly decending.
|
||||||
|
-- Each available recce within range will fire an illumination bomb.
|
||||||
|
-- Illumination bombs can be fired in while lasing targets.
|
||||||
|
-- When illumination bombs are fired, it will take about 2 minutes until a sequent bomb run can be requested using the menus.
|
||||||
|
--
|
||||||
|
-- ### 0.5. Smoking Targets
|
||||||
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
|
-- Smoke will fire for 5 minutes.
|
||||||
|
-- Each available recce within range will smoke a target.
|
||||||
|
-- Smoking can be requested while lasing targets.
|
||||||
|
-- Smoke will appear “around” the targets, because of accuracy limitations.
|
||||||
|
--
|
||||||
--
|
--
|
||||||
-- Have FUN!
|
-- Have FUN!
|
||||||
--
|
--
|
||||||
@@ -109,7 +187,7 @@ do -- DESIGNATE
|
|||||||
--
|
--
|
||||||
-- ## 2. DESIGNATE is a FSM
|
-- ## 2. DESIGNATE is a FSM
|
||||||
--
|
--
|
||||||
-- 
|
-- Designate is a finite state machine, which allows for controlled transitions of states.
|
||||||
--
|
--
|
||||||
-- ### 2.1 DESIGNATE States
|
-- ### 2.1 DESIGNATE States
|
||||||
--
|
--
|
||||||
@@ -353,7 +431,8 @@ do -- DESIGNATE
|
|||||||
-- @param #DESIGNATE self
|
-- @param #DESIGNATE self
|
||||||
-- @param #number Delay
|
-- @param #number Delay
|
||||||
|
|
||||||
self:AddTransition( "*", "Done", "*" )
|
self:AddTransition( "*", "DoneSmoking", "*" )
|
||||||
|
self:AddTransition( "*", "DoneIlluminating", "*" )
|
||||||
|
|
||||||
self:AddTransition( "*", "Status", "*" )
|
self:AddTransition( "*", "Status", "*" )
|
||||||
--- Status Handler OnBefore for DESIGNATE
|
--- Status Handler OnBefore for DESIGNATE
|
||||||
@@ -391,6 +470,7 @@ do -- DESIGNATE
|
|||||||
self.LaseDuration = 60
|
self.LaseDuration = 60
|
||||||
|
|
||||||
self:SetFlashStatusMenu( false )
|
self:SetFlashStatusMenu( false )
|
||||||
|
self:SetFlashDetectionMessages( true )
|
||||||
self:SetMission( Mission )
|
self:SetMission( Mission )
|
||||||
|
|
||||||
self:SetLaserCodes( { 1688, 1130, 4785, 6547, 1465, 4578 } ) -- set self.LaserCodes
|
self:SetLaserCodes( { 1688, 1130, 4785, 6547, 1465, 4578 } ) -- set self.LaserCodes
|
||||||
@@ -398,7 +478,7 @@ do -- DESIGNATE
|
|||||||
|
|
||||||
self:SetThreatLevelPrioritization( false ) -- self.ThreatLevelPrioritization, default is threat level priorization off
|
self:SetThreatLevelPrioritization( false ) -- self.ThreatLevelPrioritization, default is threat level priorization off
|
||||||
self:SetMaximumDesignations( 5 ) -- Sets the maximum designations. The default is 5 designations.
|
self:SetMaximumDesignations( 5 ) -- Sets the maximum designations. The default is 5 designations.
|
||||||
self:SetMaximumDistanceDesignations( 12000 ) -- Sets the maximum distance on which designations can be accepted. The default is 8000 meters.
|
self:SetMaximumDistanceDesignations( 8000 ) -- Sets the maximum distance on which designations can be accepted. The default is 8000 meters.
|
||||||
self:SetMaximumMarkings( 2 ) -- Per target group, a maximum of 2 markings will be made by default.
|
self:SetMaximumMarkings( 2 ) -- Per target group, a maximum of 2 markings will be made by default.
|
||||||
|
|
||||||
self:SetDesignateMenu()
|
self:SetDesignateMenu()
|
||||||
@@ -416,17 +496,27 @@ do -- DESIGNATE
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Set the flashing of the status menu.
|
--- Set the flashing of the status menu for all AttackGroups.
|
||||||
-- @param #DESIGNATE self
|
-- @param #DESIGNATE self
|
||||||
-- @param #boolean FlashMenu true: the status menu will be flashed every detection run; false: no flashing of the menu.
|
-- @param #boolean FlashMenu true: the status menu will be flashed every detection run; false: no flashing of the menu.
|
||||||
-- @return #DESIGNATE
|
-- @return #DESIGNATE
|
||||||
|
-- @usage
|
||||||
|
--
|
||||||
|
-- -- Enable the designate status message flashing...
|
||||||
|
-- Designate:SetFlashStatusMenu( true )
|
||||||
|
--
|
||||||
|
-- -- Disable the designate statusmessage flashing...
|
||||||
|
-- Designate:SetFlashStatusMenu()
|
||||||
|
--
|
||||||
|
-- -- Disable the designate status message flashing...
|
||||||
|
-- Designate:SetFlashStatusMenu( false )
|
||||||
function DESIGNATE:SetFlashStatusMenu( FlashMenu ) --R2.1
|
function DESIGNATE:SetFlashStatusMenu( FlashMenu ) --R2.1
|
||||||
|
|
||||||
self.FlashStatusMenu = {}
|
self.FlashStatusMenu = {}
|
||||||
|
|
||||||
self.AttackSet:ForEachGroup(
|
self.AttackSet:ForEachGroupAlive(
|
||||||
|
|
||||||
--- @param Wrapper.Group#GROUP GroupReport
|
--- @param Wrapper.Group#GROUP AttackGroup
|
||||||
function( AttackGroup )
|
function( AttackGroup )
|
||||||
self.FlashStatusMenu[AttackGroup] = FlashMenu
|
self.FlashStatusMenu[AttackGroup] = FlashMenu
|
||||||
end
|
end
|
||||||
@@ -435,6 +525,35 @@ do -- DESIGNATE
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Set the flashing of the new detection messages.
|
||||||
|
-- @param #DESIGNATE self
|
||||||
|
-- @param #boolean FlashDetectionMessage true: The detection message will be flashed every time a new detection was done; false: no messages will be displayed.
|
||||||
|
-- @return #DESIGNATE
|
||||||
|
-- @usage
|
||||||
|
--
|
||||||
|
-- -- Enable the message flashing...
|
||||||
|
-- Designate:SetFlashDetectionMessages( true )
|
||||||
|
--
|
||||||
|
-- -- Disable the message flashing...
|
||||||
|
-- Designate:SetFlashDetectionMessages()
|
||||||
|
--
|
||||||
|
-- -- Disable the message flashing...
|
||||||
|
-- Designate:SetFlashDetectionMessages( false )
|
||||||
|
function DESIGNATE:SetFlashDetectionMessages( FlashDetectionMessage )
|
||||||
|
|
||||||
|
self.FlashDetectionMessage = {}
|
||||||
|
|
||||||
|
self.AttackSet:ForEachGroupAlive(
|
||||||
|
|
||||||
|
--- @param Wrapper.Group#GROUP AttackGroup
|
||||||
|
function( AttackGroup )
|
||||||
|
self.FlashDetectionMessage[AttackGroup] = FlashDetectionMessage
|
||||||
|
end
|
||||||
|
)
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Set the maximum amount of designations.
|
--- Set the maximum amount of designations.
|
||||||
-- @param #DESIGNATE self
|
-- @param #DESIGNATE self
|
||||||
@@ -494,7 +613,7 @@ do -- DESIGNATE
|
|||||||
function DESIGNATE:SetLaserCodes( LaserCodes ) --R2.1
|
function DESIGNATE:SetLaserCodes( LaserCodes ) --R2.1
|
||||||
|
|
||||||
self.LaserCodes = ( type( LaserCodes ) == "table" ) and LaserCodes or { LaserCodes }
|
self.LaserCodes = ( type( LaserCodes ) == "table" ) and LaserCodes or { LaserCodes }
|
||||||
self:E( { LaserCodes = self.LaserCodes } )
|
self:F( { LaserCodes = self.LaserCodes } )
|
||||||
|
|
||||||
self.LaserCodesUsed = {}
|
self.LaserCodesUsed = {}
|
||||||
|
|
||||||
@@ -674,24 +793,27 @@ do -- DESIGNATE
|
|||||||
-- @return #DESIGNATE
|
-- @return #DESIGNATE
|
||||||
function DESIGNATE:DesignationScope()
|
function DESIGNATE:DesignationScope()
|
||||||
|
|
||||||
local DetectedItems = self.Detection:GetDetectedItems()
|
local DetectedItems = self.Detection:GetDetectedItemsByIndex()
|
||||||
|
|
||||||
local DetectedItemCount = 0
|
local DetectedItemCount = 0
|
||||||
|
|
||||||
for DesignateIndex, Designating in pairs( self.Designating ) do
|
for DesignateIndex, Designating in pairs( self.Designating ) do
|
||||||
local DetectedItem = DetectedItems[DesignateIndex]
|
local DetectedItem = self.Detection:GetDetectedItemByIndex( DesignateIndex )
|
||||||
if DetectedItem then
|
if DetectedItem then
|
||||||
-- Check LOS...
|
-- Check LOS...
|
||||||
local IsDetected = self.Detection:IsDetectedItemDetected( DetectedItem )
|
local IsDetected = self.Detection:IsDetectedItemDetected( DetectedItem )
|
||||||
self:F({IsDetected = IsDetected, DetectedItem })
|
self:F({IsDetected = IsDetected })
|
||||||
if IsDetected == false then
|
if IsDetected == false then
|
||||||
self:F("Removing")
|
self:F("Removing")
|
||||||
-- This Detection is obsolete, remove from the designate scope
|
-- This Detection is obsolete, remove from the designate scope
|
||||||
self.Designating[DesignateIndex] = nil
|
self.Designating[DesignateIndex] = nil
|
||||||
self.AttackSet:ForEachGroup(
|
self.AttackSet:ForEachGroupAlive(
|
||||||
|
--- @param Wrapper.Group#GROUP AttackGroup
|
||||||
function( AttackGroup )
|
function( AttackGroup )
|
||||||
local DetectionText = self.Detection:DetectedItemReportSummary( DesignateIndex, AttackGroup ):Text( ", " )
|
if AttackGroup:IsAlive() == true then
|
||||||
self.CC:GetPositionable():MessageToGroup( "Targets out of LOS\n" .. DetectionText, 10, AttackGroup, self.DesignateName )
|
local DetectionText = self.Detection:DetectedItemReportSummary( DetectedItem, AttackGroup ):Text( ", " )
|
||||||
|
self.CC:GetPositionable():MessageToGroup( "Targets out of LOS\n" .. DetectionText, 10, AttackGroup, self.DesignateName )
|
||||||
|
end
|
||||||
end
|
end
|
||||||
)
|
)
|
||||||
else
|
else
|
||||||
@@ -711,13 +833,19 @@ do -- DESIGNATE
|
|||||||
if DetectedItem.DistanceRecce <= self.MaximumDistanceDesignations then
|
if DetectedItem.DistanceRecce <= self.MaximumDistanceDesignations then
|
||||||
if self.Designating[DesignateIndex] == nil then
|
if self.Designating[DesignateIndex] == nil then
|
||||||
-- ok, we added one item to the designate scope.
|
-- ok, we added one item to the designate scope.
|
||||||
self.AttackSet:ForEachGroup(
|
self.AttackSet:ForEachGroupAlive(
|
||||||
function( AttackGroup )
|
function( AttackGroup )
|
||||||
local DetectionText = self.Detection:DetectedItemReportSummary( DesignateIndex, AttackGroup ):Text( ", " )
|
if self.FlashDetectionMessage[AttackGroup] == true then
|
||||||
self.CC:GetPositionable():MessageToGroup( "Targets detected at \n" .. DetectionText, 10, AttackGroup, self.DesignateName )
|
local DetectionText = self.Detection:DetectedItemReportSummary( DetectedItem, AttackGroup ):Text( ", " )
|
||||||
|
self.CC:GetPositionable():MessageToGroup( "Targets detected at \n" .. DetectionText, 10, AttackGroup, self.DesignateName )
|
||||||
|
end
|
||||||
end
|
end
|
||||||
)
|
)
|
||||||
self.Designating[DesignateIndex] = ""
|
self.Designating[DesignateIndex] = ""
|
||||||
|
|
||||||
|
-- When we found an item for designation, we stop the loop.
|
||||||
|
-- So each iteration over the detected items, a new detected item will be selected to be designated.
|
||||||
|
-- Until all detected items were found or until there are about 5 designations allocated.
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -733,7 +861,7 @@ do -- DESIGNATE
|
|||||||
-- @return #DESIGNATE
|
-- @return #DESIGNATE
|
||||||
function DESIGNATE:CoordinateLase()
|
function DESIGNATE:CoordinateLase()
|
||||||
|
|
||||||
local DetectedItems = self.Detection:GetDetectedItems()
|
local DetectedItems = self.Detection:GetDetectedItemsByIndex()
|
||||||
|
|
||||||
for DesignateIndex, Designating in pairs( self.Designating ) do
|
for DesignateIndex, Designating in pairs( self.Designating ) do
|
||||||
local DetectedItem = DetectedItems[DesignateIndex]
|
local DetectedItem = DetectedItems[DesignateIndex]
|
||||||
@@ -753,11 +881,9 @@ do -- DESIGNATE
|
|||||||
-- @param Wrapper.Group#GROUP AttackGroup
|
-- @param Wrapper.Group#GROUP AttackGroup
|
||||||
-- @param #number Duration The time in seconds the report should be visible.
|
-- @param #number Duration The time in seconds the report should be visible.
|
||||||
-- @return #DESIGNATE
|
-- @return #DESIGNATE
|
||||||
function DESIGNATE:SendStatus( MenuAttackGroup, Duration )
|
function DESIGNATE:SendStatus( MenuAttackGroup )
|
||||||
|
|
||||||
Duration = Duration or 10
|
self.AttackSet:ForEachGroupAlive(
|
||||||
|
|
||||||
self.AttackSet:ForEachGroup(
|
|
||||||
|
|
||||||
--- @param Wrapper.Group#GROUP GroupReport
|
--- @param Wrapper.Group#GROUP GroupReport
|
||||||
function( AttackGroup )
|
function( AttackGroup )
|
||||||
@@ -765,24 +891,33 @@ do -- DESIGNATE
|
|||||||
if self.FlashStatusMenu[AttackGroup] or ( MenuAttackGroup and ( AttackGroup:GetName() == MenuAttackGroup:GetName() ) ) then
|
if self.FlashStatusMenu[AttackGroup] or ( MenuAttackGroup and ( AttackGroup:GetName() == MenuAttackGroup:GetName() ) ) then
|
||||||
|
|
||||||
local DetectedReport = REPORT:New( "Targets ready for Designation:" )
|
local DetectedReport = REPORT:New( "Targets ready for Designation:" )
|
||||||
local DetectedItems = self.Detection:GetDetectedItems()
|
local DetectedItems = self.Detection:GetDetectedItemsByIndex()
|
||||||
|
|
||||||
for DesignateIndex, Designating in pairs( self.Designating ) do
|
for DesignateIndex, Designating in pairs( self.Designating ) do
|
||||||
local DetectedItem = DetectedItems[DesignateIndex]
|
local DetectedItem = DetectedItems[DesignateIndex]
|
||||||
if DetectedItem then
|
if DetectedItem then
|
||||||
local Report = self.Detection:DetectedItemReportSummary( DesignateIndex, AttackGroup ):Text( ", " )
|
local Report = self.Detection:DetectedItemReportSummary( DetectedItem, AttackGroup ):Text( ", " )
|
||||||
DetectedReport:Add( string.rep( "-", 140 ) )
|
DetectedReport:Add( string.rep( "-", 140 ) )
|
||||||
DetectedReport:Add( " - " .. Report )
|
DetectedReport:Add( " - " .. Report )
|
||||||
|
if string.find( Designating, "L" ) then
|
||||||
|
DetectedReport:Add( " - " .. "Lasing Targets" )
|
||||||
|
end
|
||||||
|
if string.find( Designating, "S" ) then
|
||||||
|
DetectedReport:Add( " - " .. "Smoking Targets" )
|
||||||
|
end
|
||||||
|
if string.find( Designating, "I" ) then
|
||||||
|
DetectedReport:Add( " - " .. "Illuminating Area" )
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local CC = self.CC:GetPositionable()
|
local CC = self.CC:GetPositionable()
|
||||||
|
|
||||||
CC:MessageToGroup( DetectedReport:Text( "\n" ), Duration, AttackGroup, self.DesignateName )
|
CC:MessageTypeToGroup( DetectedReport:Text( "\n" ), MESSAGE.Type.Information, AttackGroup, self.DesignateName )
|
||||||
|
|
||||||
local DesignationReport = REPORT:New( "Marking Targets:\n" )
|
local DesignationReport = REPORT:New( "Marking Targets:" )
|
||||||
|
|
||||||
self.RecceSet:ForEachGroup(
|
self.RecceSet:ForEachGroupAlive(
|
||||||
function( RecceGroup )
|
function( RecceGroup )
|
||||||
local RecceUnits = RecceGroup:GetUnits()
|
local RecceUnits = RecceGroup:GetUnits()
|
||||||
for UnitID, RecceData in pairs( RecceUnits ) do
|
for UnitID, RecceData in pairs( RecceUnits ) do
|
||||||
@@ -794,7 +929,7 @@ do -- DESIGNATE
|
|||||||
end
|
end
|
||||||
)
|
)
|
||||||
|
|
||||||
CC:MessageToGroup( DesignationReport:Text(), Duration, AttackGroup, self.DesignateName )
|
CC:MessageTypeToGroup( DesignationReport:Text(), MESSAGE.Type.Information, AttackGroup, self.DesignateName )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
)
|
)
|
||||||
@@ -807,9 +942,9 @@ do -- DESIGNATE
|
|||||||
-- @return #DESIGNATE
|
-- @return #DESIGNATE
|
||||||
function DESIGNATE:SetDesignateMenu()
|
function DESIGNATE:SetDesignateMenu()
|
||||||
|
|
||||||
self.AttackSet:Flush()
|
self.AttackSet:Flush( self )
|
||||||
|
|
||||||
self.AttackSet:ForEachGroup(
|
self.AttackSet:ForEachGroupAlive(
|
||||||
|
|
||||||
--- @param Wrapper.Group#GROUP GroupReport
|
--- @param Wrapper.Group#GROUP GroupReport
|
||||||
function( AttackGroup )
|
function( AttackGroup )
|
||||||
@@ -823,69 +958,67 @@ do -- DESIGNATE
|
|||||||
|
|
||||||
local MenuTime = timer.getTime()
|
local MenuTime = timer.getTime()
|
||||||
|
|
||||||
self.MenuDesignate[AttackGroup] = MENU_GROUP:New( AttackGroup, self.DesignateName, MissionMenu ):SetTime( MenuTime ):SetTag( self.DesignateName )
|
self.MenuDesignate[AttackGroup] = MENU_GROUP_DELAYED:New( AttackGroup, self.DesignateName, MissionMenu ):SetTime( MenuTime ):SetTag( self.DesignateName )
|
||||||
local MenuDesignate = self.MenuDesignate[AttackGroup] -- Core.Menu#MENU_GROUP
|
local MenuDesignate = self.MenuDesignate[AttackGroup] -- Core.Menu#MENU_GROUP_DELAYED
|
||||||
|
|
||||||
-- Set Menu option for auto lase
|
-- Set Menu option for auto lase
|
||||||
|
|
||||||
if self.AutoLase then
|
if self.AutoLase then
|
||||||
MENU_GROUP_COMMAND:New( AttackGroup, "Auto Lase Off", MenuDesignate, self.MenuAutoLase, self, false ):SetTime( MenuTime ):SetTag( self.DesignateName )
|
MENU_GROUP_COMMAND_DELAYED:New( AttackGroup, "Auto Lase Off", MenuDesignate, self.MenuAutoLase, self, false ):SetTime( MenuTime ):SetTag( self.DesignateName )
|
||||||
else
|
else
|
||||||
MENU_GROUP_COMMAND:New( AttackGroup, "Auto Lase On", MenuDesignate, self.MenuAutoLase, self, true ):SetTime( MenuTime ):SetTag( self.DesignateName )
|
MENU_GROUP_COMMAND_DELAYED:New( AttackGroup, "Auto Lase On", MenuDesignate, self.MenuAutoLase, self, true ):SetTime( MenuTime ):SetTag( self.DesignateName )
|
||||||
end
|
end
|
||||||
|
|
||||||
local StatusMenu = MENU_GROUP:New( AttackGroup, "Status", MenuDesignate ):SetTime( MenuTime ):SetTag( self.DesignateName )
|
local StatusMenu = MENU_GROUP_DELAYED:New( AttackGroup, "Status", MenuDesignate ):SetTime( MenuTime ):SetTag( self.DesignateName )
|
||||||
MENU_GROUP_COMMAND:New( AttackGroup, "Report Status 15s", StatusMenu, self.MenuStatus, self, AttackGroup, 15 ):SetTime( MenuTime ):SetTag( self.DesignateName )
|
MENU_GROUP_COMMAND_DELAYED:New( AttackGroup, "Report Status", StatusMenu, self.MenuStatus, self, AttackGroup ):SetTime( MenuTime ):SetTag( self.DesignateName )
|
||||||
MENU_GROUP_COMMAND:New( AttackGroup, "Report Status 30s", StatusMenu, self.MenuStatus, self, AttackGroup, 30 ):SetTime( MenuTime ):SetTag( self.DesignateName )
|
|
||||||
MENU_GROUP_COMMAND:New( AttackGroup, "Report Status 60s", StatusMenu, self.MenuStatus, self, AttackGroup, 60 ):SetTime( MenuTime ):SetTag( self.DesignateName )
|
|
||||||
|
|
||||||
if self.FlashStatusMenu[AttackGroup] then
|
if self.FlashStatusMenu[AttackGroup] then
|
||||||
MENU_GROUP_COMMAND:New( AttackGroup, "Flash Status Report Off", StatusMenu, self.MenuFlashStatus, self, AttackGroup, false ):SetTime( MenuTime ):SetTag( self.DesignateName )
|
MENU_GROUP_COMMAND_DELAYED:New( AttackGroup, "Flash Status Report Off", StatusMenu, self.MenuFlashStatus, self, AttackGroup, false ):SetTime( MenuTime ):SetTag( self.DesignateName )
|
||||||
else
|
else
|
||||||
MENU_GROUP_COMMAND:New( AttackGroup, "Flash Status Report On", StatusMenu, self.MenuFlashStatus, self, AttackGroup, true ):SetTime( MenuTime ):SetTag( self.DesignateName )
|
MENU_GROUP_COMMAND_DELAYED:New( AttackGroup, "Flash Status Report On", StatusMenu, self.MenuFlashStatus, self, AttackGroup, true ):SetTime( MenuTime ):SetTag( self.DesignateName )
|
||||||
end
|
end
|
||||||
|
|
||||||
for DesignateIndex, Designating in pairs( self.Designating ) do
|
for DesignateIndex, Designating in pairs( self.Designating ) do
|
||||||
|
|
||||||
local DetectedItem = self.Detection:GetDetectedItem( DesignateIndex )
|
local DetectedItem = self.Detection:GetDetectedItemByIndex( DesignateIndex )
|
||||||
|
|
||||||
if DetectedItem then
|
if DetectedItem then
|
||||||
|
|
||||||
local Coord = self.Detection:GetDetectedItemCoordinate( DesignateIndex )
|
local Coord = self.Detection:GetDetectedItemCoordinate( DetectedItem )
|
||||||
local ID = self.Detection:GetDetectedItemID( DesignateIndex )
|
local ID = self.Detection:GetDetectedItemID( DetectedItem )
|
||||||
local MenuText = ID .. ", " .. Coord:ToStringA2G( AttackGroup )
|
local MenuText = ID --.. ", " .. Coord:ToStringA2G( AttackGroup )
|
||||||
|
|
||||||
if Designating == "" then
|
MenuText = string.format( "(%3s) %s", Designating, MenuText )
|
||||||
MenuText = "(-) " .. MenuText
|
local DetectedMenu = MENU_GROUP_DELAYED:New( AttackGroup, MenuText, MenuDesignate ):SetTime( MenuTime ):SetTag( self.DesignateName )
|
||||||
local DetectedMenu = MENU_GROUP:New( AttackGroup, MenuText, MenuDesignate ):SetTime( MenuTime ):SetTag( self.DesignateName )
|
|
||||||
MENU_GROUP_COMMAND:New( AttackGroup, "Search other target", DetectedMenu, self.MenuForget, self, DesignateIndex ):SetTime( MenuTime ):SetTag( self.DesignateName )
|
-- Build the Lasing menu.
|
||||||
|
if string.find( Designating, "L", 1, true ) == nil then
|
||||||
|
MENU_GROUP_COMMAND_DELAYED:New( AttackGroup, "Search other target", DetectedMenu, self.MenuForget, self, DesignateIndex ):SetTime( MenuTime ):SetTag( self.DesignateName )
|
||||||
for LaserCode, MenuText in pairs( self.MenuLaserCodes ) do
|
for LaserCode, MenuText in pairs( self.MenuLaserCodes ) do
|
||||||
MENU_GROUP_COMMAND:New( AttackGroup, string.format( MenuText, LaserCode ), DetectedMenu, self.MenuLaseCode, self, DesignateIndex, 60, LaserCode ):SetTime( MenuTime ):SetTag( self.DesignateName )
|
MENU_GROUP_COMMAND_DELAYED:New( AttackGroup, string.format( MenuText, LaserCode ), DetectedMenu, self.MenuLaseCode, self, DesignateIndex, 60, LaserCode ):SetTime( MenuTime ):SetTag( self.DesignateName )
|
||||||
end
|
end
|
||||||
MENU_GROUP_COMMAND:New( AttackGroup, "Lase with random laser code(s)", DetectedMenu, self.MenuLaseOn, self, DesignateIndex, 60 ):SetTime( MenuTime ):SetTag( self.DesignateName )
|
MENU_GROUP_COMMAND_DELAYED:New( AttackGroup, "Lase with random laser code(s)", DetectedMenu, self.MenuLaseOn, self, DesignateIndex, 60 ):SetTime( MenuTime ):SetTag( self.DesignateName )
|
||||||
MENU_GROUP_COMMAND:New( AttackGroup, "Smoke red", DetectedMenu, self.MenuSmoke, self, DesignateIndex, SMOKECOLOR.Red ):SetTime( MenuTime ):SetTag( self.DesignateName )
|
|
||||||
MENU_GROUP_COMMAND:New( AttackGroup, "Smoke blue", DetectedMenu, self.MenuSmoke, self, DesignateIndex, SMOKECOLOR.Blue ):SetTime( MenuTime ):SetTag( self.DesignateName )
|
|
||||||
MENU_GROUP_COMMAND:New( AttackGroup, "Smoke green", DetectedMenu, self.MenuSmoke, self, DesignateIndex, SMOKECOLOR.Green ):SetTime( MenuTime ):SetTag( self.DesignateName )
|
|
||||||
MENU_GROUP_COMMAND:New( AttackGroup, "Smoke white", DetectedMenu, self.MenuSmoke, self, DesignateIndex, SMOKECOLOR.White ):SetTime( MenuTime ):SetTag( self.DesignateName )
|
|
||||||
MENU_GROUP_COMMAND:New( AttackGroup, "Smoke orange", DetectedMenu, self.MenuSmoke, self, DesignateIndex, SMOKECOLOR.Orange ):SetTime( MenuTime ):SetTag( self.DesignateName )
|
|
||||||
MENU_GROUP_COMMAND:New( AttackGroup, "Illuminate", DetectedMenu, self.MenuIlluminate, self, DesignateIndex ):SetTime( MenuTime ):SetTag( self.DesignateName )
|
|
||||||
else
|
else
|
||||||
if Designating == "Laser" then
|
MENU_GROUP_COMMAND_DELAYED:New( AttackGroup, "Stop lasing", DetectedMenu, self.MenuLaseOff, self, DesignateIndex ):SetTime( MenuTime ):SetTag( self.DesignateName )
|
||||||
MenuText = "(L) " .. MenuText
|
end
|
||||||
elseif Designating == "Smoke" then
|
|
||||||
MenuText = "(S) " .. MenuText
|
-- Build the Smoking menu.
|
||||||
elseif Designating == "Illuminate" then
|
if string.find( Designating, "S", 1, true ) == nil then
|
||||||
MenuText = "(I) " .. MenuText
|
MENU_GROUP_COMMAND_DELAYED:New( AttackGroup, "Smoke red", DetectedMenu, self.MenuSmoke, self, DesignateIndex, SMOKECOLOR.Red ):SetTime( MenuTime ):SetTag( self.DesignateName )
|
||||||
end
|
MENU_GROUP_COMMAND_DELAYED:New( AttackGroup, "Smoke blue", DetectedMenu, self.MenuSmoke, self, DesignateIndex, SMOKECOLOR.Blue ):SetTime( MenuTime ):SetTag( self.DesignateName )
|
||||||
local DetectedMenu = MENU_GROUP:New( AttackGroup, MenuText, MenuDesignate ):SetTime( MenuTime ):SetTag( self.DesignateName )
|
MENU_GROUP_COMMAND_DELAYED:New( AttackGroup, "Smoke green", DetectedMenu, self.MenuSmoke, self, DesignateIndex, SMOKECOLOR.Green ):SetTime( MenuTime ):SetTag( self.DesignateName )
|
||||||
if Designating == "Laser" then
|
MENU_GROUP_COMMAND_DELAYED:New( AttackGroup, "Smoke white", DetectedMenu, self.MenuSmoke, self, DesignateIndex, SMOKECOLOR.White ):SetTime( MenuTime ):SetTag( self.DesignateName )
|
||||||
MENU_GROUP_COMMAND:New( AttackGroup, "Stop lasing", DetectedMenu, self.MenuLaseOff, self, DesignateIndex ):SetTime( MenuTime ):SetTag( self.DesignateName )
|
MENU_GROUP_COMMAND_DELAYED:New( AttackGroup, "Smoke orange", DetectedMenu, self.MenuSmoke, self, DesignateIndex, SMOKECOLOR.Orange ):SetTime( MenuTime ):SetTag( self.DesignateName )
|
||||||
else
|
end
|
||||||
end
|
|
||||||
|
-- Build the Illuminate menu.
|
||||||
|
if string.find( Designating, "I", 1, true ) == nil then
|
||||||
|
MENU_GROUP_COMMAND_DELAYED:New( AttackGroup, "Illuminate", DetectedMenu, self.MenuIlluminate, self, DesignateIndex ):SetTime( MenuTime ):SetTag( self.DesignateName )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
MenuDesignate:Remove( MenuTime, self.DesignateName )
|
MenuDesignate:Remove( MenuTime, self.DesignateName )
|
||||||
|
MenuDesignate:Set()
|
||||||
end
|
end
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -894,18 +1027,18 @@ do -- DESIGNATE
|
|||||||
|
|
||||||
---
|
---
|
||||||
-- @param #DESIGNATE self
|
-- @param #DESIGNATE self
|
||||||
function DESIGNATE:MenuStatus( AttackGroup, Duration )
|
function DESIGNATE:MenuStatus( AttackGroup )
|
||||||
|
|
||||||
self:E("Status")
|
self:F("Status")
|
||||||
|
|
||||||
self:SendStatus( AttackGroup, Duration )
|
self:SendStatus( AttackGroup )
|
||||||
end
|
end
|
||||||
|
|
||||||
---
|
---
|
||||||
-- @param #DESIGNATE self
|
-- @param #DESIGNATE self
|
||||||
function DESIGNATE:MenuFlashStatus( AttackGroup, Flash )
|
function DESIGNATE:MenuFlashStatus( AttackGroup, Flash )
|
||||||
|
|
||||||
self:E("Flash Status")
|
self:F("Flash Status")
|
||||||
|
|
||||||
self.FlashStatusMenu[AttackGroup] = Flash
|
self.FlashStatusMenu[AttackGroup] = Flash
|
||||||
self:SetDesignateMenu()
|
self:SetDesignateMenu()
|
||||||
@@ -916,9 +1049,9 @@ do -- DESIGNATE
|
|||||||
-- @param #DESIGNATE self
|
-- @param #DESIGNATE self
|
||||||
function DESIGNATE:MenuForget( Index )
|
function DESIGNATE:MenuForget( Index )
|
||||||
|
|
||||||
self:E("Forget")
|
self:F("Forget")
|
||||||
|
|
||||||
self.Designating[Index] = nil
|
self.Designating[Index] = ""
|
||||||
self:SetDesignateMenu()
|
self:SetDesignateMenu()
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -926,7 +1059,7 @@ do -- DESIGNATE
|
|||||||
-- @param #DESIGNATE self
|
-- @param #DESIGNATE self
|
||||||
function DESIGNATE:MenuAutoLase( AutoLase )
|
function DESIGNATE:MenuAutoLase( AutoLase )
|
||||||
|
|
||||||
self:E("AutoLase")
|
self:F("AutoLase")
|
||||||
|
|
||||||
self:SetAutoLase( AutoLase, true )
|
self:SetAutoLase( AutoLase, true )
|
||||||
end
|
end
|
||||||
@@ -935,28 +1068,34 @@ do -- DESIGNATE
|
|||||||
-- @param #DESIGNATE self
|
-- @param #DESIGNATE self
|
||||||
function DESIGNATE:MenuSmoke( Index, Color )
|
function DESIGNATE:MenuSmoke( Index, Color )
|
||||||
|
|
||||||
self:E("Designate through Smoke")
|
self:F("Designate through Smoke")
|
||||||
|
|
||||||
self.Designating[Index] = "Smoke"
|
if string.find( self.Designating[Index], "S" ) == nil then
|
||||||
|
self.Designating[Index] = self.Designating[Index] .. "S"
|
||||||
|
end
|
||||||
self:Smoke( Index, Color )
|
self:Smoke( Index, Color )
|
||||||
|
self:SetDesignateMenu()
|
||||||
end
|
end
|
||||||
|
|
||||||
---
|
---
|
||||||
-- @param #DESIGNATE self
|
-- @param #DESIGNATE self
|
||||||
function DESIGNATE:MenuIlluminate( Index )
|
function DESIGNATE:MenuIlluminate( Index )
|
||||||
|
|
||||||
self:E("Designate through Illumination")
|
self:F("Designate through Illumination")
|
||||||
|
|
||||||
self.Designating[Index] = "Illuminate"
|
if string.find( self.Designating[Index], "I", 1, true ) == nil then
|
||||||
|
self.Designating[Index] = self.Designating[Index] .. "I"
|
||||||
|
end
|
||||||
|
|
||||||
self:__Illuminate( 1, Index )
|
self:__Illuminate( 1, Index )
|
||||||
|
self:SetDesignateMenu()
|
||||||
end
|
end
|
||||||
|
|
||||||
---
|
---
|
||||||
-- @param #DESIGNATE self
|
-- @param #DESIGNATE self
|
||||||
function DESIGNATE:MenuLaseOn( Index, Duration )
|
function DESIGNATE:MenuLaseOn( Index, Duration )
|
||||||
|
|
||||||
self:E("Designate through Lase")
|
self:F("Designate through Lase")
|
||||||
|
|
||||||
self:__LaseOn( 1, Index, Duration )
|
self:__LaseOn( 1, Index, Duration )
|
||||||
self:SetDesignateMenu()
|
self:SetDesignateMenu()
|
||||||
@@ -967,7 +1106,7 @@ do -- DESIGNATE
|
|||||||
-- @param #DESIGNATE self
|
-- @param #DESIGNATE self
|
||||||
function DESIGNATE:MenuLaseCode( Index, Duration, LaserCode )
|
function DESIGNATE:MenuLaseCode( Index, Duration, LaserCode )
|
||||||
|
|
||||||
self:E( "Designate through Lase using " .. LaserCode )
|
self:F( "Designate through Lase using " .. LaserCode )
|
||||||
|
|
||||||
self:__LaseOn( 1, Index, Duration, LaserCode )
|
self:__LaseOn( 1, Index, Duration, LaserCode )
|
||||||
self:SetDesignateMenu()
|
self:SetDesignateMenu()
|
||||||
@@ -978,9 +1117,9 @@ do -- DESIGNATE
|
|||||||
-- @param #DESIGNATE self
|
-- @param #DESIGNATE self
|
||||||
function DESIGNATE:MenuLaseOff( Index, Duration )
|
function DESIGNATE:MenuLaseOff( Index, Duration )
|
||||||
|
|
||||||
self:E("Lasing off")
|
self:F("Lasing off")
|
||||||
|
|
||||||
self.Designating[Index] = ""
|
self.Designating[Index] = string.gsub( self.Designating[Index], "L", "" )
|
||||||
self:__LaseOff( 1, Index )
|
self:__LaseOff( 1, Index )
|
||||||
self:SetDesignateMenu()
|
self:SetDesignateMenu()
|
||||||
end
|
end
|
||||||
@@ -989,10 +1128,12 @@ do -- DESIGNATE
|
|||||||
-- @param #DESIGNATE self
|
-- @param #DESIGNATE self
|
||||||
function DESIGNATE:onafterLaseOn( From, Event, To, Index, Duration, LaserCode )
|
function DESIGNATE:onafterLaseOn( From, Event, To, Index, Duration, LaserCode )
|
||||||
|
|
||||||
self.Designating[Index] = "Laser"
|
if string.find( self.Designating[Index], "L", 1, true ) == nil then
|
||||||
|
self.Designating[Index] = self.Designating[Index] .. "L"
|
||||||
|
end
|
||||||
self.LaseStart = timer.getTime()
|
self.LaseStart = timer.getTime()
|
||||||
self.LaseDuration = Duration
|
self.LaseDuration = Duration
|
||||||
self:__Lasing( -1, Index, Duration, LaserCode )
|
self:Lasing( Index, Duration, LaserCode )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@@ -1002,14 +1143,15 @@ do -- DESIGNATE
|
|||||||
function DESIGNATE:onafterLasing( From, Event, To, Index, Duration, LaserCodeRequested )
|
function DESIGNATE:onafterLasing( From, Event, To, Index, Duration, LaserCodeRequested )
|
||||||
|
|
||||||
|
|
||||||
local TargetSetUnit = self.Detection:GetDetectedSet( Index )
|
local DetectedItem = self.Detection:GetDetectedItemByIndex( Index )
|
||||||
|
local TargetSetUnit = self.Detection:GetDetectedSet( DetectedItem )
|
||||||
|
|
||||||
local MarkingCount = 0
|
local MarkingCount = 0
|
||||||
local MarkedTypes = {}
|
local MarkedTypes = {}
|
||||||
local ReportTypes = REPORT:New()
|
local ReportTypes = REPORT:New()
|
||||||
local ReportLaserCodes = REPORT:New()
|
local ReportLaserCodes = REPORT:New()
|
||||||
|
|
||||||
TargetSetUnit:Flush()
|
TargetSetUnit:Flush( self )
|
||||||
|
|
||||||
--self:F( { Recces = self.Recces } )
|
--self:F( { Recces = self.Recces } )
|
||||||
for TargetUnit, RecceData in pairs( self.Recces ) do
|
for TargetUnit, RecceData in pairs( self.Recces ) do
|
||||||
@@ -1056,8 +1198,8 @@ do -- DESIGNATE
|
|||||||
|
|
||||||
if not Recce then
|
if not Recce then
|
||||||
|
|
||||||
self:E( "Lasing..." )
|
self:F( "Lasing..." )
|
||||||
self.RecceSet:Flush()
|
self.RecceSet:Flush( self)
|
||||||
|
|
||||||
for RecceGroupID, RecceGroup in pairs( self.RecceSet:GetSet() ) do
|
for RecceGroupID, RecceGroup in pairs( self.RecceSet:GetSet() ) do
|
||||||
for UnitID, UnitData in pairs( RecceGroup:GetUnits() or {} ) do
|
for UnitID, UnitData in pairs( RecceGroup:GetUnits() or {} ) do
|
||||||
@@ -1085,17 +1227,19 @@ do -- DESIGNATE
|
|||||||
self.LaserCodesUsed[LaserCode] = LaserCodeIndex
|
self.LaserCodesUsed[LaserCode] = LaserCodeIndex
|
||||||
local Spot = RecceUnit:LaseUnit( TargetUnit, LaserCode, Duration )
|
local Spot = RecceUnit:LaseUnit( TargetUnit, LaserCode, Duration )
|
||||||
local AttackSet = self.AttackSet
|
local AttackSet = self.AttackSet
|
||||||
|
local DesignateName = self.DesignateName
|
||||||
|
|
||||||
function Spot:OnAfterDestroyed( From, Event, To )
|
function Spot:OnAfterDestroyed( From, Event, To )
|
||||||
self:E( "Destroyed Message" )
|
self.Recce:MessageToSetGroup( "Target " .. TargetUnit:GetTypeName() .. " destroyed. " .. TargetSetUnit:Count() .. " targets left.",
|
||||||
self.Recce:ToSetGroup( "Target " .. TargetUnit:GetTypeName() .. " destroyed. " .. TargetSetUnit:Count() .. " targets left.", 5, AttackSet, self.DesignateName )
|
5, AttackSet, self.DesignateName )
|
||||||
end
|
end
|
||||||
|
|
||||||
self.Recces[TargetUnit] = RecceUnit
|
self.Recces[TargetUnit] = RecceUnit
|
||||||
RecceUnit:MessageToSetGroup( "Marking " .. TargetUnit:GetTypeName() .. " with laser " .. RecceUnit:GetSpot().LaserCode .. " for " .. Duration .. "s.", 5, self.AttackSet, self.DesignateName )
|
|
||||||
-- OK. We have assigned for the Recce a TargetUnit. We can exit the function.
|
-- OK. We have assigned for the Recce a TargetUnit. We can exit the function.
|
||||||
MarkingCount = MarkingCount + 1
|
MarkingCount = MarkingCount + 1
|
||||||
local TargetUnitType = TargetUnit:GetTypeName()
|
local TargetUnitType = TargetUnit:GetTypeName()
|
||||||
|
--RecceUnit:MessageToSetGroup( "Marking " .. TargetUnit:GetTypeName() .. " with laser " .. RecceUnit:GetSpot().LaserCode .. " for " .. Duration .. "s.",
|
||||||
|
-- 5, self.AttackSet, DesignateName )
|
||||||
if not MarkedTypes[TargetUnitType] then
|
if not MarkedTypes[TargetUnitType] then
|
||||||
MarkedTypes[TargetUnitType] = true
|
MarkedTypes[TargetUnitType] = true
|
||||||
ReportTypes:Add(TargetUnitType)
|
ReportTypes:Add(TargetUnitType)
|
||||||
@@ -1118,7 +1262,7 @@ do -- DESIGNATE
|
|||||||
Recce:MessageToSetGroup( "Target " .. TargetUnit:GetTypeName() "out of LOS. Cancelling lase!", 5, self.AttackSet, self.DesignateName )
|
Recce:MessageToSetGroup( "Target " .. TargetUnit:GetTypeName() "out of LOS. Cancelling lase!", 5, self.AttackSet, self.DesignateName )
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
MarkingCount = MarkingCount + 1
|
--MarkingCount = MarkingCount + 1
|
||||||
local TargetUnitType = TargetUnit:GetTypeName()
|
local TargetUnitType = TargetUnit:GetTypeName()
|
||||||
if not MarkedTypes[TargetUnitType] then
|
if not MarkedTypes[TargetUnitType] then
|
||||||
MarkedTypes[TargetUnitType] = true
|
MarkedTypes[TargetUnitType] = true
|
||||||
@@ -1146,16 +1290,14 @@ do -- DESIGNATE
|
|||||||
|
|
||||||
local MarkedTypesText = ReportTypes:Text(', ')
|
local MarkedTypesText = ReportTypes:Text(', ')
|
||||||
local MarkedLaserCodesText = ReportLaserCodes:Text(', ')
|
local MarkedLaserCodesText = ReportLaserCodes:Text(', ')
|
||||||
for MarkedType, MarketCount in pairs( MarkedTypes ) do
|
self.CC:GetPositionable():MessageToSetGroup( "Marking " .. MarkingCount .. " x " .. MarkedTypesText .. ", code " .. MarkedLaserCodesText .. ".", 5, self.AttackSet, self.DesignateName )
|
||||||
self.CC:GetPositionable():MessageToSetGroup( "Marking " .. MarkingCount .. " x " .. MarkedTypesText .. " with lasers " .. MarkedLaserCodesText .. ".", 5, self.AttackSet, self.DesignateName )
|
|
||||||
end
|
|
||||||
|
|
||||||
self:__Lasing( -30, Index, Duration, LaserCodeRequested )
|
self:__Lasing( -30, Index, Duration, LaserCodeRequested )
|
||||||
|
|
||||||
self:SetDesignateMenu()
|
self:SetDesignateMenu()
|
||||||
|
|
||||||
else
|
else
|
||||||
self:__LaseOff( 1 )
|
self:LaseOff( Index )
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -1171,7 +1313,8 @@ do -- DESIGNATE
|
|||||||
CC:MessageToSetGroup( "Stopped lasing.", 5, self.AttackSet, self.DesignateName )
|
CC:MessageToSetGroup( "Stopped lasing.", 5, self.AttackSet, self.DesignateName )
|
||||||
end
|
end
|
||||||
|
|
||||||
local TargetSetUnit = self.Detection:GetDetectedSet( Index )
|
local DetectedItem = self.Detection:GetDetectedItemByIndex( Index )
|
||||||
|
local TargetSetUnit = self.Detection:GetDetectedSet( DetectedItem )
|
||||||
|
|
||||||
local Recces = self.Recces
|
local Recces = self.Recces
|
||||||
|
|
||||||
@@ -1185,6 +1328,7 @@ do -- DESIGNATE
|
|||||||
self.Recces = {}
|
self.Recces = {}
|
||||||
self.LaserCodesUsed = {}
|
self.LaserCodesUsed = {}
|
||||||
|
|
||||||
|
self.Designating[Index] = string.gsub( self.Designating[Index], "L", "" )
|
||||||
self:SetDesignateMenu()
|
self:SetDesignateMenu()
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1194,7 +1338,8 @@ do -- DESIGNATE
|
|||||||
-- @return #DESIGNATE
|
-- @return #DESIGNATE
|
||||||
function DESIGNATE:onafterSmoke( From, Event, To, Index, Color )
|
function DESIGNATE:onafterSmoke( From, Event, To, Index, Color )
|
||||||
|
|
||||||
local TargetSetUnit = self.Detection:GetDetectedSet( Index )
|
local DetectedItem = self.Detection:GetDetectedItemByIndex( Index )
|
||||||
|
local TargetSetUnit = self.Detection:GetDetectedSet( DetectedItem )
|
||||||
local TargetSetUnitCount = TargetSetUnit:Count()
|
local TargetSetUnitCount = TargetSetUnit:Count()
|
||||||
|
|
||||||
local MarkedCount = 0
|
local MarkedCount = 0
|
||||||
@@ -1207,7 +1352,7 @@ do -- DESIGNATE
|
|||||||
|
|
||||||
MarkedCount = MarkedCount + 1
|
MarkedCount = MarkedCount + 1
|
||||||
|
|
||||||
self:E( "Smoking ..." )
|
self:F( "Smoking ..." )
|
||||||
|
|
||||||
local RecceGroup = self.RecceSet:FindNearestGroupFromPointVec2(SmokeUnit:GetPointVec2())
|
local RecceGroup = self.RecceSet:FindNearestGroupFromPointVec2(SmokeUnit:GetPointVec2())
|
||||||
local RecceUnit = RecceGroup:GetUnit( 1 )
|
local RecceUnit = RecceGroup:GetUnit( 1 )
|
||||||
@@ -1216,13 +1361,14 @@ do -- DESIGNATE
|
|||||||
|
|
||||||
RecceUnit:MessageToSetGroup( "Smoking " .. SmokeUnit:GetTypeName() .. ".", 5, self.AttackSet, self.DesignateName )
|
RecceUnit:MessageToSetGroup( "Smoking " .. SmokeUnit:GetTypeName() .. ".", 5, self.AttackSet, self.DesignateName )
|
||||||
|
|
||||||
|
if SmokeUnit:IsAlive() then
|
||||||
|
SmokeUnit:Smoke( Color, 50, 2 )
|
||||||
|
end
|
||||||
|
|
||||||
self.MarkScheduler:Schedule( self,
|
self.MarkScheduler:Schedule( self,
|
||||||
function()
|
function()
|
||||||
if SmokeUnit:IsAlive() then
|
self:DoneSmoking( Index )
|
||||||
SmokeUnit:Smoke( Color, 50, 2 )
|
end, {}, math.random( 180, 240 )
|
||||||
end
|
|
||||||
self:Done( Index )
|
|
||||||
end, {}, math.random( 5, 20 )
|
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -1237,7 +1383,8 @@ do -- DESIGNATE
|
|||||||
-- @return #DESIGNATE
|
-- @return #DESIGNATE
|
||||||
function DESIGNATE:onafterIlluminate( From, Event, To, Index )
|
function DESIGNATE:onafterIlluminate( From, Event, To, Index )
|
||||||
|
|
||||||
local TargetSetUnit = self.Detection:GetDetectedSet( Index )
|
local DetectedItem = self.Detection:GetDetectedItemByIndex( Index )
|
||||||
|
local TargetSetUnit = self.Detection:GetDetectedSet( DetectedItem )
|
||||||
local TargetUnit = TargetSetUnit:GetFirst()
|
local TargetUnit = TargetSetUnit:GetFirst()
|
||||||
|
|
||||||
if TargetUnit then
|
if TargetUnit then
|
||||||
@@ -1245,28 +1392,38 @@ do -- DESIGNATE
|
|||||||
local RecceUnit = RecceGroup:GetUnit( 1 )
|
local RecceUnit = RecceGroup:GetUnit( 1 )
|
||||||
if RecceUnit then
|
if RecceUnit then
|
||||||
RecceUnit:MessageToSetGroup( "Illuminating " .. TargetUnit:GetTypeName() .. ".", 5, self.AttackSet, self.DesignateName )
|
RecceUnit:MessageToSetGroup( "Illuminating " .. TargetUnit:GetTypeName() .. ".", 5, self.AttackSet, self.DesignateName )
|
||||||
|
if TargetUnit:IsAlive() then
|
||||||
|
-- Fire 2 illumination bombs at random locations.
|
||||||
|
TargetUnit:GetPointVec3():AddY(math.random( 350, 500) ):AddX(math.random(-50,50) ):AddZ(math.random(-50,50) ):IlluminationBomb()
|
||||||
|
TargetUnit:GetPointVec3():AddY(math.random( 350, 500) ):AddX(math.random(-50,50) ):AddZ(math.random(-50,50) ):IlluminationBomb()
|
||||||
|
end
|
||||||
self.MarkScheduler:Schedule( self,
|
self.MarkScheduler:Schedule( self,
|
||||||
function()
|
function()
|
||||||
if TargetUnit:IsAlive() then
|
self:DoneIlluminating( Index )
|
||||||
TargetUnit:GetPointVec3():AddY(300):IlluminationBomb()
|
end, {}, math.random( 60, 90 )
|
||||||
end
|
|
||||||
self:Done( Index )
|
|
||||||
end, {}, math.random( 5, 20 )
|
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Done
|
--- DoneSmoking
|
||||||
-- @param #DESIGNATE self
|
-- @param #DESIGNATE self
|
||||||
-- @return #DESIGNATE
|
-- @return #DESIGNATE
|
||||||
function DESIGNATE:onafterDone( From, Event, To, Index )
|
function DESIGNATE:onafterDoneSmoking( From, Event, To, Index )
|
||||||
|
|
||||||
self.Designating[Index] = nil
|
self.Designating[Index] = string.gsub( self.Designating[Index], "S", "" )
|
||||||
|
self:SetDesignateMenu()
|
||||||
|
end
|
||||||
|
|
||||||
|
--- DoneIlluminating
|
||||||
|
-- @param #DESIGNATE self
|
||||||
|
-- @return #DESIGNATE
|
||||||
|
function DESIGNATE:onafterDoneIlluminating( From, Event, To, Index )
|
||||||
|
|
||||||
|
self.Designating[Index] = string.gsub( self.Designating[Index], "I", "" )
|
||||||
self:SetDesignateMenu()
|
self:SetDesignateMenu()
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Help from Ciribob
|
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,9 +1,9 @@
|
|||||||
--- **Functional** -- Taking the lead of AI escorting your flight.
|
--- **Functional** -- Taking the lead of AI escorting your flight.
|
||||||
--
|
--
|
||||||
-- ====
|
-- ===
|
||||||
--
|
--
|
||||||
-- @{#ESCORT} class
|
-- @{#ESCORT} class
|
||||||
-- ================
|
-- ===
|
||||||
-- The @{#ESCORT} class allows you to interact with escorting AI on your flight and take the lead.
|
-- The @{#ESCORT} class allows you to interact with escorting AI on your flight and take the lead.
|
||||||
-- Each escorting group can be commanded with a whole set of radio commands (radio menu in your flight, and then F10).
|
-- Each escorting group can be commanded with a whole set of radio commands (radio menu in your flight, and then F10).
|
||||||
--
|
--
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
-- Ships and Ground troops will have a more limited set, but they can provide support through the bombing of targets designated by the other escorts.
|
-- Ships and Ground troops will have a more limited set, but they can provide support through the bombing of targets designated by the other escorts.
|
||||||
--
|
--
|
||||||
-- RADIO MENUs that can be created:
|
-- RADIO MENUs that can be created:
|
||||||
-- ================================
|
-- ===
|
||||||
-- Find a summary below of the current available commands:
|
-- Find a summary below of the current available commands:
|
||||||
--
|
--
|
||||||
-- Navigation ...:
|
-- Navigation ...:
|
||||||
@@ -79,13 +79,13 @@
|
|||||||
-- Note that this is really fantastic, as you now have the dynamic of taking control of the escort groups, and allowing them to resume their path or mission.
|
-- Note that this is really fantastic, as you now have the dynamic of taking control of the escort groups, and allowing them to resume their path or mission.
|
||||||
--
|
--
|
||||||
-- ESCORT construction methods.
|
-- ESCORT construction methods.
|
||||||
-- ============================
|
-- ===
|
||||||
-- Create a new SPAWN object with the @{#ESCORT.New} method:
|
-- Create a new SPAWN object with the @{#ESCORT.New} method:
|
||||||
--
|
--
|
||||||
-- * @{#ESCORT.New}: Creates a new ESCORT object from a @{Group#GROUP} for a @{Client#CLIENT}, with an optional briefing text.
|
-- * @{#ESCORT.New}: Creates a new ESCORT object from a @{Group#GROUP} for a @{Client#CLIENT}, with an optional briefing text.
|
||||||
--
|
--
|
||||||
-- ESCORT initialization methods.
|
-- ESCORT initialization methods.
|
||||||
-- ==============================
|
-- ===
|
||||||
-- The following menus are created within the RADIO MENU (F10) of an active unit hosted by a player:
|
-- The following menus are created within the RADIO MENU (F10) of an active unit hosted by a player:
|
||||||
--
|
--
|
||||||
-- * @{#ESCORT.MenuFollowAt}: Creates a menu to make the escort follow the client.
|
-- * @{#ESCORT.MenuFollowAt}: Creates a menu to make the escort follow the client.
|
||||||
@@ -129,8 +129,7 @@
|
|||||||
-- @field #boolean ReportTargets If true, nearby targets are reported.
|
-- @field #boolean ReportTargets If true, nearby targets are reported.
|
||||||
-- @Field Dcs.DCSTypes#AI.Option.Air.val.ROE OptionROE Which ROE is set to the EscortGroup.
|
-- @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 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
|
-- @field FunctionalMENU_GROUPDETECTION_BASE Detection
|
||||||
-- @field Functional.Detection#DETECTION_BASE Detection
|
|
||||||
ESCORT = {
|
ESCORT = {
|
||||||
ClassName = "ESCORT",
|
ClassName = "ESCORT",
|
||||||
EscortName = nil, -- The Escort Name
|
EscortName = nil, -- The Escort Name
|
||||||
@@ -207,7 +206,7 @@ function ESCORT:New( EscortClient, EscortGroup, EscortName, EscortBriefing )
|
|||||||
self.EscortClient._EscortGroups[EscortGroup:GetName()].Detection = self.EscortGroup.Detection
|
self.EscortClient._EscortGroups[EscortGroup:GetName()].Detection = self.EscortGroup.Detection
|
||||||
end
|
end
|
||||||
|
|
||||||
self.EscortMenu = MENU_CLIENT:New( self.EscortClient, self.EscortName )
|
self.EscortMenu = MENU_GROUP:New( self.EscortClient:GetGroup(), self.EscortName )
|
||||||
|
|
||||||
self.EscortGroup:WayPointInitialize(1)
|
self.EscortGroup:WayPointInitialize(1)
|
||||||
|
|
||||||
@@ -303,14 +302,14 @@ function ESCORT:MenuFollowAt( Distance )
|
|||||||
|
|
||||||
if self.EscortGroup:IsAir() then
|
if self.EscortGroup:IsAir() then
|
||||||
if not self.EscortMenuReportNavigation then
|
if not self.EscortMenuReportNavigation then
|
||||||
self.EscortMenuReportNavigation = MENU_CLIENT:New( self.EscortClient, "Navigation", self.EscortMenu )
|
self.EscortMenuReportNavigation = MENU_GROUP:New( self.EscortClient:GetGroup(), "Navigation", self.EscortMenu )
|
||||||
end
|
end
|
||||||
|
|
||||||
if not self.EscortMenuJoinUpAndFollow then
|
if not self.EscortMenuJoinUpAndFollow then
|
||||||
self.EscortMenuJoinUpAndFollow = {}
|
self.EscortMenuJoinUpAndFollow = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
self.EscortMenuJoinUpAndFollow[#self.EscortMenuJoinUpAndFollow+1] = MENU_CLIENT_COMMAND:New( self.EscortClient, "Join-Up and Follow at " .. Distance, self.EscortMenuReportNavigation, ESCORT._JoinUpAndFollow, self, Distance )
|
self.EscortMenuJoinUpAndFollow[#self.EscortMenuJoinUpAndFollow+1] = MENU_GROUP_COMMAND:New( self.EscortClient:GetGroup(), "Join-Up and Follow at " .. Distance, self.EscortMenuReportNavigation, ESCORT._JoinUpAndFollow, self, Distance )
|
||||||
|
|
||||||
self.EscortMode = ESCORT.MODE.FOLLOW
|
self.EscortMode = ESCORT.MODE.FOLLOW
|
||||||
end
|
end
|
||||||
@@ -332,7 +331,7 @@ function ESCORT:MenuHoldAtEscortPosition( Height, Seconds, MenuTextFormat )
|
|||||||
if self.EscortGroup:IsAir() then
|
if self.EscortGroup:IsAir() then
|
||||||
|
|
||||||
if not self.EscortMenuHold then
|
if not self.EscortMenuHold then
|
||||||
self.EscortMenuHold = MENU_CLIENT:New( self.EscortClient, "Hold position", self.EscortMenu )
|
self.EscortMenuHold = MENU_GROUP:New( self.EscortClient:GetGroup(), "Hold position", self.EscortMenu )
|
||||||
end
|
end
|
||||||
|
|
||||||
if not Height then
|
if not Height then
|
||||||
@@ -362,9 +361,9 @@ function ESCORT:MenuHoldAtEscortPosition( Height, Seconds, MenuTextFormat )
|
|||||||
self.EscortMenuHoldPosition = {}
|
self.EscortMenuHoldPosition = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
self.EscortMenuHoldPosition[#self.EscortMenuHoldPosition+1] = MENU_CLIENT_COMMAND
|
self.EscortMenuHoldPosition[#self.EscortMenuHoldPosition+1] = MENU_GROUP_COMMAND
|
||||||
:New(
|
:New(
|
||||||
self.EscortClient,
|
self.EscortClient:GetGroup(),
|
||||||
MenuText,
|
MenuText,
|
||||||
self.EscortMenuHold,
|
self.EscortMenuHold,
|
||||||
ESCORT._HoldPosition,
|
ESCORT._HoldPosition,
|
||||||
@@ -393,7 +392,7 @@ function ESCORT:MenuHoldAtLeaderPosition( Height, Seconds, MenuTextFormat )
|
|||||||
if self.EscortGroup:IsAir() then
|
if self.EscortGroup:IsAir() then
|
||||||
|
|
||||||
if not self.EscortMenuHold then
|
if not self.EscortMenuHold then
|
||||||
self.EscortMenuHold = MENU_CLIENT:New( self.EscortClient, "Hold position", self.EscortMenu )
|
self.EscortMenuHold = MENU_GROUP:New( self.EscortClient:GetGroup(), "Hold position", self.EscortMenu )
|
||||||
end
|
end
|
||||||
|
|
||||||
if not Height then
|
if not Height then
|
||||||
@@ -423,9 +422,9 @@ function ESCORT:MenuHoldAtLeaderPosition( Height, Seconds, MenuTextFormat )
|
|||||||
self.EscortMenuHoldAtLeaderPosition = {}
|
self.EscortMenuHoldAtLeaderPosition = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
self.EscortMenuHoldAtLeaderPosition[#self.EscortMenuHoldAtLeaderPosition+1] = MENU_CLIENT_COMMAND
|
self.EscortMenuHoldAtLeaderPosition[#self.EscortMenuHoldAtLeaderPosition+1] = MENU_GROUP_COMMAND
|
||||||
:New(
|
:New(
|
||||||
self.EscortClient,
|
self.EscortClient:GetGroup(),
|
||||||
MenuText,
|
MenuText,
|
||||||
self.EscortMenuHold,
|
self.EscortMenuHold,
|
||||||
ESCORT._HoldPosition,
|
ESCORT._HoldPosition,
|
||||||
@@ -452,7 +451,7 @@ function ESCORT:MenuScanForTargets( Height, Seconds, MenuTextFormat )
|
|||||||
|
|
||||||
if self.EscortGroup:IsAir() then
|
if self.EscortGroup:IsAir() then
|
||||||
if not self.EscortMenuScan then
|
if not self.EscortMenuScan then
|
||||||
self.EscortMenuScan = MENU_CLIENT:New( self.EscortClient, "Scan for targets", self.EscortMenu )
|
self.EscortMenuScan = MENU_GROUP:New( self.EscortClient:GetGroup(), "Scan for targets", self.EscortMenu )
|
||||||
end
|
end
|
||||||
|
|
||||||
if not Height then
|
if not Height then
|
||||||
@@ -482,9 +481,9 @@ function ESCORT:MenuScanForTargets( Height, Seconds, MenuTextFormat )
|
|||||||
self.EscortMenuScanForTargets = {}
|
self.EscortMenuScanForTargets = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
self.EscortMenuScanForTargets[#self.EscortMenuScanForTargets+1] = MENU_CLIENT_COMMAND
|
self.EscortMenuScanForTargets[#self.EscortMenuScanForTargets+1] = MENU_GROUP_COMMAND
|
||||||
:New(
|
:New(
|
||||||
self.EscortClient,
|
self.EscortClient:GetGroup(),
|
||||||
MenuText,
|
MenuText,
|
||||||
self.EscortMenuScan,
|
self.EscortMenuScan,
|
||||||
ESCORT._ScanTargets,
|
ESCORT._ScanTargets,
|
||||||
@@ -508,7 +507,7 @@ function ESCORT:MenuFlare( MenuTextFormat )
|
|||||||
self:F()
|
self:F()
|
||||||
|
|
||||||
if not self.EscortMenuReportNavigation then
|
if not self.EscortMenuReportNavigation then
|
||||||
self.EscortMenuReportNavigation = MENU_CLIENT:New( self.EscortClient, "Navigation", self.EscortMenu )
|
self.EscortMenuReportNavigation = MENU_GROUP:New( self.EscortClient:GetGroup(), "Navigation", self.EscortMenu )
|
||||||
end
|
end
|
||||||
|
|
||||||
local MenuText = ""
|
local MenuText = ""
|
||||||
@@ -519,11 +518,11 @@ function ESCORT:MenuFlare( MenuTextFormat )
|
|||||||
end
|
end
|
||||||
|
|
||||||
if not self.EscortMenuFlare then
|
if not self.EscortMenuFlare then
|
||||||
self.EscortMenuFlare = MENU_CLIENT:New( self.EscortClient, MenuText, self.EscortMenuReportNavigation, ESCORT._Flare, self )
|
self.EscortMenuFlare = MENU_GROUP:New( self.EscortClient:GetGroup(), MenuText, self.EscortMenuReportNavigation, ESCORT._Flare, self )
|
||||||
self.EscortMenuFlareGreen = MENU_CLIENT_COMMAND:New( self.EscortClient, "Release green flare", self.EscortMenuFlare, ESCORT._Flare, self, FLARECOLOR.Green, "Released a green flare!" )
|
self.EscortMenuFlareGreen = MENU_GROUP_COMMAND:New( self.EscortClient:GetGroup(), "Release green flare", self.EscortMenuFlare, ESCORT._Flare, self, FLARECOLOR.Green, "Released a green flare!" )
|
||||||
self.EscortMenuFlareRed = MENU_CLIENT_COMMAND:New( self.EscortClient, "Release red flare", self.EscortMenuFlare, ESCORT._Flare, self, FLARECOLOR.Red, "Released a red flare!" )
|
self.EscortMenuFlareRed = MENU_GROUP_COMMAND:New( self.EscortClient:GetGroup(), "Release red flare", self.EscortMenuFlare, ESCORT._Flare, self, FLARECOLOR.Red, "Released a red flare!" )
|
||||||
self.EscortMenuFlareWhite = MENU_CLIENT_COMMAND:New( self.EscortClient, "Release white flare", self.EscortMenuFlare, ESCORT._Flare, self, FLARECOLOR.White, "Released a white flare!" )
|
self.EscortMenuFlareWhite = MENU_GROUP_COMMAND:New( self.EscortClient:GetGroup(), "Release white flare", self.EscortMenuFlare, ESCORT._Flare, self, FLARECOLOR.White, "Released a white flare!" )
|
||||||
self.EscortMenuFlareYellow = MENU_CLIENT_COMMAND:New( self.EscortClient, "Release yellow flare", self.EscortMenuFlare, ESCORT._Flare, self, FLARECOLOR.Yellow, "Released a yellow flare!" )
|
self.EscortMenuFlareYellow = MENU_GROUP_COMMAND:New( self.EscortClient:GetGroup(), "Release yellow flare", self.EscortMenuFlare, ESCORT._Flare, self, FLARECOLOR.Yellow, "Released a yellow flare!" )
|
||||||
end
|
end
|
||||||
|
|
||||||
return self
|
return self
|
||||||
@@ -541,7 +540,7 @@ function ESCORT:MenuSmoke( MenuTextFormat )
|
|||||||
|
|
||||||
if not self.EscortGroup:IsAir() then
|
if not self.EscortGroup:IsAir() then
|
||||||
if not self.EscortMenuReportNavigation then
|
if not self.EscortMenuReportNavigation then
|
||||||
self.EscortMenuReportNavigation = MENU_CLIENT:New( self.EscortClient, "Navigation", self.EscortMenu )
|
self.EscortMenuReportNavigation = MENU_GROUP:New( self.EscortClient:GetGroup(), "Navigation", self.EscortMenu )
|
||||||
end
|
end
|
||||||
|
|
||||||
local MenuText = ""
|
local MenuText = ""
|
||||||
@@ -552,12 +551,12 @@ function ESCORT:MenuSmoke( MenuTextFormat )
|
|||||||
end
|
end
|
||||||
|
|
||||||
if not self.EscortMenuSmoke then
|
if not self.EscortMenuSmoke then
|
||||||
self.EscortMenuSmoke = MENU_CLIENT:New( self.EscortClient, "Smoke", self.EscortMenuReportNavigation, ESCORT._Smoke, self )
|
self.EscortMenuSmoke = MENU_GROUP:New( self.EscortClient:GetGroup(), "Smoke", self.EscortMenuReportNavigation, ESCORT._Smoke, self )
|
||||||
self.EscortMenuSmokeGreen = MENU_CLIENT_COMMAND:New( self.EscortClient, "Release green smoke", self.EscortMenuSmoke, ESCORT._Smoke, self, SMOKECOLOR.Green, "Releasing green smoke!" )
|
self.EscortMenuSmokeGreen = MENU_GROUP_COMMAND:New( self.EscortClient:GetGroup(), "Release green smoke", self.EscortMenuSmoke, ESCORT._Smoke, self, SMOKECOLOR.Green, "Releasing green smoke!" )
|
||||||
self.EscortMenuSmokeRed = MENU_CLIENT_COMMAND:New( self.EscortClient, "Release red smoke", self.EscortMenuSmoke, ESCORT._Smoke, self, SMOKECOLOR.Red, "Releasing red smoke!" )
|
self.EscortMenuSmokeRed = MENU_GROUP_COMMAND:New( self.EscortClient:GetGroup(), "Release red smoke", self.EscortMenuSmoke, ESCORT._Smoke, self, SMOKECOLOR.Red, "Releasing red smoke!" )
|
||||||
self.EscortMenuSmokeWhite = MENU_CLIENT_COMMAND:New( self.EscortClient, "Release white smoke", self.EscortMenuSmoke, ESCORT._Smoke, self, SMOKECOLOR.White, "Releasing white smoke!" )
|
self.EscortMenuSmokeWhite = MENU_GROUP_COMMAND:New( self.EscortClient:GetGroup(), "Release white smoke", self.EscortMenuSmoke, ESCORT._Smoke, self, SMOKECOLOR.White, "Releasing white smoke!" )
|
||||||
self.EscortMenuSmokeOrange = MENU_CLIENT_COMMAND:New( self.EscortClient, "Release orange smoke", self.EscortMenuSmoke, ESCORT._Smoke, self, SMOKECOLOR.Orange, "Releasing orange smoke!" )
|
self.EscortMenuSmokeOrange = MENU_GROUP_COMMAND:New( self.EscortClient:GetGroup(), "Release orange smoke", self.EscortMenuSmoke, ESCORT._Smoke, self, SMOKECOLOR.Orange, "Releasing orange smoke!" )
|
||||||
self.EscortMenuSmokeBlue = MENU_CLIENT_COMMAND:New( self.EscortClient, "Release blue smoke", self.EscortMenuSmoke, ESCORT._Smoke, self, SMOKECOLOR.Blue, "Releasing blue smoke!" )
|
self.EscortMenuSmokeBlue = MENU_GROUP_COMMAND:New( self.EscortClient:GetGroup(), "Release blue smoke", self.EscortMenuSmoke, ESCORT._Smoke, self, SMOKECOLOR.Blue, "Releasing blue smoke!" )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -574,7 +573,7 @@ function ESCORT:MenuReportTargets( Seconds )
|
|||||||
self:F( { Seconds } )
|
self:F( { Seconds } )
|
||||||
|
|
||||||
if not self.EscortMenuReportNearbyTargets then
|
if not self.EscortMenuReportNearbyTargets then
|
||||||
self.EscortMenuReportNearbyTargets = MENU_CLIENT:New( self.EscortClient, "Report targets", self.EscortMenu )
|
self.EscortMenuReportNearbyTargets = MENU_GROUP:New( self.EscortClient:GetGroup(), "Report targets", self.EscortMenu )
|
||||||
end
|
end
|
||||||
|
|
||||||
if not Seconds then
|
if not Seconds then
|
||||||
@@ -582,12 +581,12 @@ function ESCORT:MenuReportTargets( Seconds )
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Report Targets
|
-- Report Targets
|
||||||
self.EscortMenuReportNearbyTargetsNow = MENU_CLIENT_COMMAND:New( self.EscortClient, "Report targets now!", self.EscortMenuReportNearbyTargets, ESCORT._ReportNearbyTargetsNow, self )
|
self.EscortMenuReportNearbyTargetsNow = MENU_GROUP_COMMAND:New( self.EscortClient:GetGroup(), "Report targets now!", self.EscortMenuReportNearbyTargets, ESCORT._ReportNearbyTargetsNow, self )
|
||||||
self.EscortMenuReportNearbyTargetsOn = MENU_CLIENT_COMMAND:New( self.EscortClient, "Report targets on", self.EscortMenuReportNearbyTargets, ESCORT._SwitchReportNearbyTargets, self, true )
|
self.EscortMenuReportNearbyTargetsOn = MENU_GROUP_COMMAND:New( self.EscortClient:GetGroup(), "Report targets on", self.EscortMenuReportNearbyTargets, ESCORT._SwitchReportNearbyTargets, self, true )
|
||||||
self.EscortMenuReportNearbyTargetsOff = MENU_CLIENT_COMMAND:New( self.EscortClient, "Report targets off", self.EscortMenuReportNearbyTargets, ESCORT._SwitchReportNearbyTargets, self, false )
|
self.EscortMenuReportNearbyTargetsOff = MENU_GROUP_COMMAND:New( self.EscortClient:GetGroup(), "Report targets off", self.EscortMenuReportNearbyTargets, ESCORT._SwitchReportNearbyTargets, self, false )
|
||||||
|
|
||||||
-- Attack Targets
|
-- Attack Targets
|
||||||
self.EscortMenuAttackNearbyTargets = MENU_CLIENT:New( self.EscortClient, "Attack targets", self.EscortMenu )
|
self.EscortMenuAttackNearbyTargets = MENU_GROUP:New( self.EscortClient:GetGroup(), "Attack targets", self.EscortMenu )
|
||||||
|
|
||||||
|
|
||||||
self.ReportTargetsScheduler = SCHEDULER:New( self, self._ReportTargetsScheduler, {}, 1, Seconds )
|
self.ReportTargetsScheduler = SCHEDULER:New( self, self._ReportTargetsScheduler, {}, 1, Seconds )
|
||||||
@@ -605,7 +604,7 @@ function ESCORT:MenuAssistedAttack()
|
|||||||
|
|
||||||
-- Request assistance from other escorts.
|
-- Request assistance from other escorts.
|
||||||
-- This is very useful to let f.e. an escorting ship attack a target detected by an escorting plane...
|
-- This is very useful to let f.e. an escorting ship attack a target detected by an escorting plane...
|
||||||
self.EscortMenuTargetAssistance = MENU_CLIENT:New( self.EscortClient, "Request assistance from", self.EscortMenu )
|
self.EscortMenuTargetAssistance = MENU_GROUP:New( self.EscortClient:GetGroup(), "Request assistance from", self.EscortMenu )
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
@@ -619,18 +618,18 @@ function ESCORT:MenuROE( MenuTextFormat )
|
|||||||
|
|
||||||
if not self.EscortMenuROE then
|
if not self.EscortMenuROE then
|
||||||
-- Rules of Engagement
|
-- Rules of Engagement
|
||||||
self.EscortMenuROE = MENU_CLIENT:New( self.EscortClient, "ROE", self.EscortMenu )
|
self.EscortMenuROE = MENU_GROUP:New( self.EscortClient:GetGroup(), "ROE", self.EscortMenu )
|
||||||
if self.EscortGroup:OptionROEHoldFirePossible() then
|
if self.EscortGroup:OptionROEHoldFirePossible() then
|
||||||
self.EscortMenuROEHoldFire = MENU_CLIENT_COMMAND:New( self.EscortClient, "Hold Fire", self.EscortMenuROE, ESCORT._ROE, self, self.EscortGroup:OptionROEHoldFire(), "Holding weapons!" )
|
self.EscortMenuROEHoldFire = MENU_GROUP_COMMAND:New( self.EscortClient:GetGroup(), "Hold Fire", self.EscortMenuROE, ESCORT._ROE, self, self.EscortGroup:OptionROEHoldFire(), "Holding weapons!" )
|
||||||
end
|
end
|
||||||
if self.EscortGroup:OptionROEReturnFirePossible() then
|
if self.EscortGroup:OptionROEReturnFirePossible() then
|
||||||
self.EscortMenuROEReturnFire = MENU_CLIENT_COMMAND:New( self.EscortClient, "Return Fire", self.EscortMenuROE, ESCORT._ROE, self, self.EscortGroup:OptionROEReturnFire(), "Returning fire!" )
|
self.EscortMenuROEReturnFire = MENU_GROUP_COMMAND:New( self.EscortClient:GetGroup(), "Return Fire", self.EscortMenuROE, ESCORT._ROE, self, self.EscortGroup:OptionROEReturnFire(), "Returning fire!" )
|
||||||
end
|
end
|
||||||
if self.EscortGroup:OptionROEOpenFirePossible() then
|
if self.EscortGroup:OptionROEOpenFirePossible() then
|
||||||
self.EscortMenuROEOpenFire = MENU_CLIENT_COMMAND:New( self.EscortClient, "Open Fire", self.EscortMenuROE, ESCORT._ROE, self, self.EscortGroup:OptionROEOpenFire(), "Opening fire on designated targets!!" )
|
self.EscortMenuROEOpenFire = MENU_GROUP_COMMAND:New( self.EscortClient:GetGroup(), "Open Fire", self.EscortMenuROE, ESCORT._ROE, self, self.EscortGroup:OptionROEOpenFire(), "Opening fire on designated targets!!" )
|
||||||
end
|
end
|
||||||
if self.EscortGroup:OptionROEWeaponFreePossible() then
|
if self.EscortGroup:OptionROEWeaponFreePossible() then
|
||||||
self.EscortMenuROEWeaponFree = MENU_CLIENT_COMMAND:New( self.EscortClient, "Weapon Free", self.EscortMenuROE, ESCORT._ROE, self, self.EscortGroup:OptionROEWeaponFree(), "Opening fire on targets of opportunity!" )
|
self.EscortMenuROEWeaponFree = MENU_GROUP_COMMAND:New( self.EscortClient:GetGroup(), "Weapon Free", self.EscortMenuROE, ESCORT._ROE, self, self.EscortGroup:OptionROEWeaponFree(), "Opening fire on targets of opportunity!" )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -648,18 +647,18 @@ function ESCORT:MenuEvasion( MenuTextFormat )
|
|||||||
if self.EscortGroup:IsAir() then
|
if self.EscortGroup:IsAir() then
|
||||||
if not self.EscortMenuEvasion then
|
if not self.EscortMenuEvasion then
|
||||||
-- Reaction to Threats
|
-- Reaction to Threats
|
||||||
self.EscortMenuEvasion = MENU_CLIENT:New( self.EscortClient, "Evasion", self.EscortMenu )
|
self.EscortMenuEvasion = MENU_GROUP:New( self.EscortClient:GetGroup(), "Evasion", self.EscortMenu )
|
||||||
if self.EscortGroup:OptionROTNoReactionPossible() then
|
if self.EscortGroup:OptionROTNoReactionPossible() then
|
||||||
self.EscortMenuEvasionNoReaction = MENU_CLIENT_COMMAND:New( self.EscortClient, "Fight until death", self.EscortMenuEvasion, ESCORT._ROT, self, self.EscortGroup:OptionROTNoReaction(), "Fighting until death!" )
|
self.EscortMenuEvasionNoReaction = MENU_GROUP_COMMAND:New( self.EscortClient:GetGroup(), "Fight until death", self.EscortMenuEvasion, ESCORT._ROT, self, self.EscortGroup:OptionROTNoReaction(), "Fighting until death!" )
|
||||||
end
|
end
|
||||||
if self.EscortGroup:OptionROTPassiveDefensePossible() then
|
if self.EscortGroup:OptionROTPassiveDefensePossible() then
|
||||||
self.EscortMenuEvasionPassiveDefense = MENU_CLIENT_COMMAND:New( self.EscortClient, "Use flares, chaff and jammers", self.EscortMenuEvasion, ESCORT._ROT, self, self.EscortGroup:OptionROTPassiveDefense(), "Defending using jammers, chaff and flares!" )
|
self.EscortMenuEvasionPassiveDefense = MENU_GROUP_COMMAND:New( self.EscortClient:GetGroup(), "Use flares, chaff and jammers", self.EscortMenuEvasion, ESCORT._ROT, self, self.EscortGroup:OptionROTPassiveDefense(), "Defending using jammers, chaff and flares!" )
|
||||||
end
|
end
|
||||||
if self.EscortGroup:OptionROTEvadeFirePossible() then
|
if self.EscortGroup:OptionROTEvadeFirePossible() then
|
||||||
self.EscortMenuEvasionEvadeFire = MENU_CLIENT_COMMAND:New( self.EscortClient, "Evade enemy fire", self.EscortMenuEvasion, ESCORT._ROT, self, self.EscortGroup:OptionROTEvadeFire(), "Evading on enemy fire!" )
|
self.EscortMenuEvasionEvadeFire = MENU_GROUP_COMMAND:New( self.EscortClient:GetGroup(), "Evade enemy fire", self.EscortMenuEvasion, ESCORT._ROT, self, self.EscortGroup:OptionROTEvadeFire(), "Evading on enemy fire!" )
|
||||||
end
|
end
|
||||||
if self.EscortGroup:OptionROTVerticalPossible() then
|
if self.EscortGroup:OptionROTVerticalPossible() then
|
||||||
self.EscortMenuOptionEvasionVertical = MENU_CLIENT_COMMAND:New( self.EscortClient, "Go below radar and evade fire", self.EscortMenuEvasion, ESCORT._ROT, self, self.EscortGroup:OptionROTVertical(), "Evading on enemy fire with vertical manoeuvres!" )
|
self.EscortMenuOptionEvasionVertical = MENU_GROUP_COMMAND:New( self.EscortClient:GetGroup(), "Go below radar and evade fire", self.EscortMenuEvasion, ESCORT._ROT, self, self.EscortGroup:OptionROTVertical(), "Evading on enemy fire with vertical manoeuvres!" )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -676,7 +675,7 @@ function ESCORT:MenuResumeMission()
|
|||||||
|
|
||||||
if not self.EscortMenuResumeMission then
|
if not self.EscortMenuResumeMission then
|
||||||
-- Mission Resume Menu Root
|
-- Mission Resume Menu Root
|
||||||
self.EscortMenuResumeMission = MENU_CLIENT:New( self.EscortClient, "Resume mission from", self.EscortMenu )
|
self.EscortMenuResumeMission = MENU_GROUP:New( self.EscortClient:GetGroup(), "Resume mission from", self.EscortMenu )
|
||||||
end
|
end
|
||||||
|
|
||||||
return self
|
return self
|
||||||
@@ -847,11 +846,11 @@ function _Resume( EscortGroup )
|
|||||||
end
|
end
|
||||||
|
|
||||||
--- @param #ESCORT self
|
--- @param #ESCORT self
|
||||||
-- @param #number DetectedItemID
|
-- @param Functional.Detection#DETECTION_BASE.DetectedItem DetectedItem
|
||||||
function ESCORT:_AttackTarget( DetectedItemID )
|
function ESCORT:_AttackTarget( DetectedItem )
|
||||||
|
|
||||||
local EscortGroup = self.EscortGroup -- Wrapper.Group#GROUP
|
local EscortGroup = self.EscortGroup -- Wrapper.Group#GROUP
|
||||||
self:E( EscortGroup )
|
self:F( EscortGroup )
|
||||||
|
|
||||||
local EscortClient = self.EscortClient
|
local EscortClient = self.EscortClient
|
||||||
|
|
||||||
@@ -862,7 +861,7 @@ function ESCORT:_AttackTarget( DetectedItemID )
|
|||||||
EscortGroup:OptionROTPassiveDefense()
|
EscortGroup:OptionROTPassiveDefense()
|
||||||
EscortGroup:SetState( EscortGroup, "Escort", self )
|
EscortGroup:SetState( EscortGroup, "Escort", self )
|
||||||
|
|
||||||
local DetectedSet = self.Detection:GetDetectedSet( DetectedItemID )
|
local DetectedSet = self.Detection:GetDetectedSet( DetectedItem )
|
||||||
|
|
||||||
local Tasks = {}
|
local Tasks = {}
|
||||||
|
|
||||||
@@ -885,7 +884,7 @@ function ESCORT:_AttackTarget( DetectedItemID )
|
|||||||
|
|
||||||
else
|
else
|
||||||
|
|
||||||
local DetectedSet = self.Detection:GetDetectedSet( DetectedItemID )
|
local DetectedSet = self.Detection:GetDetectedSet( DetectedItem )
|
||||||
|
|
||||||
local Tasks = {}
|
local Tasks = {}
|
||||||
|
|
||||||
@@ -911,8 +910,9 @@ function ESCORT:_AttackTarget( DetectedItemID )
|
|||||||
end
|
end
|
||||||
|
|
||||||
---
|
---
|
||||||
-- @param #number DetectedItemID
|
--- @param #ESCORT self
|
||||||
function ESCORT:_AssistTarget( EscortGroupAttack, DetectedItemID )
|
-- @param Functional.Detection#DETECTION_BASE.DetectedItem DetectedItem
|
||||||
|
function ESCORT:_AssistTarget( EscortGroupAttack, DetectedItem )
|
||||||
|
|
||||||
local EscortGroup = self.EscortGroup
|
local EscortGroup = self.EscortGroup
|
||||||
local EscortClient = self.EscortClient
|
local EscortClient = self.EscortClient
|
||||||
@@ -923,7 +923,7 @@ function ESCORT:_AssistTarget( EscortGroupAttack, DetectedItemID )
|
|||||||
EscortGroupAttack:OptionROEOpenFire()
|
EscortGroupAttack:OptionROEOpenFire()
|
||||||
EscortGroupAttack:OptionROTVertical()
|
EscortGroupAttack:OptionROTVertical()
|
||||||
|
|
||||||
local DetectedSet = self.Detection:GetDetectedSet( DetectedItemID )
|
local DetectedSet = self.Detection:GetDetectedSet( DetectedItem )
|
||||||
|
|
||||||
local Tasks = {}
|
local Tasks = {}
|
||||||
|
|
||||||
@@ -945,7 +945,7 @@ function ESCORT:_AssistTarget( EscortGroupAttack, DetectedItemID )
|
|||||||
)
|
)
|
||||||
|
|
||||||
else
|
else
|
||||||
local DetectedSet = self.Detection:GetDetectedSet( DetectedItemID )
|
local DetectedSet = self.Detection:GetDetectedSet( DetectedItem )
|
||||||
|
|
||||||
local Tasks = {}
|
local Tasks = {}
|
||||||
|
|
||||||
@@ -1152,7 +1152,7 @@ function ESCORT:_ReportTargetsScheduler()
|
|||||||
end
|
end
|
||||||
|
|
||||||
local DetectedItems = self.Detection:GetDetectedItems()
|
local DetectedItems = self.Detection:GetDetectedItems()
|
||||||
self:E( DetectedItems )
|
self:F( DetectedItems )
|
||||||
|
|
||||||
local DetectedTargets = false
|
local DetectedTargets = false
|
||||||
|
|
||||||
@@ -1163,11 +1163,11 @@ function ESCORT:_ReportTargetsScheduler()
|
|||||||
local ClientEscortTargets = EscortGroupData.Detection
|
local ClientEscortTargets = EscortGroupData.Detection
|
||||||
--local EscortUnit = EscortGroupData:GetUnit( 1 )
|
--local EscortUnit = EscortGroupData:GetUnit( 1 )
|
||||||
|
|
||||||
for DetectedItemID, DetectedItem in pairs( DetectedItems ) do
|
for DetectedItemIndex, DetectedItem in pairs( DetectedItems ) do
|
||||||
self:E( { DetectedItemID, DetectedItem } )
|
self:F( { DetectedItemIndex, DetectedItem } )
|
||||||
-- Remove the sub menus of the Attack menu of the Escort for the EscortGroup.
|
-- Remove the sub menus of the Attack menu of the Escort for the EscortGroup.
|
||||||
|
|
||||||
local DetectedItemReportSummary = self.Detection:DetectedItemReportSummary( DetectedItemID, EscortGroupData.EscortGroup, _DATABASE:GetPlayerSettings( self.EscortClient:GetPlayerName() ) )
|
local DetectedItemReportSummary = self.Detection:DetectedItemReportSummary( DetectedItem, EscortGroupData.EscortGroup, _DATABASE:GetPlayerSettings( self.EscortClient:GetPlayerName() ) )
|
||||||
|
|
||||||
if ClientEscortGroupName == EscortGroupName then
|
if ClientEscortGroupName == EscortGroupName then
|
||||||
|
|
||||||
@@ -1176,12 +1176,12 @@ function ESCORT:_ReportTargetsScheduler()
|
|||||||
|
|
||||||
self:T( DetectedMsg )
|
self:T( DetectedMsg )
|
||||||
|
|
||||||
MENU_CLIENT_COMMAND:New( self.EscortClient,
|
MENU_GROUP_COMMAND:New( self.EscortClient:GetGroup(),
|
||||||
DetectedMsg,
|
DetectedMsg,
|
||||||
self.EscortMenuAttackNearbyTargets,
|
self.EscortMenuAttackNearbyTargets,
|
||||||
ESCORT._AttackTarget,
|
ESCORT._AttackTarget,
|
||||||
self,
|
self,
|
||||||
DetectedItemID
|
DetectedItem
|
||||||
)
|
)
|
||||||
else
|
else
|
||||||
if self.EscortMenuTargetAssistance then
|
if self.EscortMenuTargetAssistance then
|
||||||
@@ -1189,14 +1189,14 @@ function ESCORT:_ReportTargetsScheduler()
|
|||||||
local DetectedMsg = DetectedItemReportSummary:Text("\n")
|
local DetectedMsg = DetectedItemReportSummary:Text("\n")
|
||||||
self:T( DetectedMsg )
|
self:T( DetectedMsg )
|
||||||
|
|
||||||
local MenuTargetAssistance = MENU_CLIENT:New( self.EscortClient, EscortGroupData.EscortName, self.EscortMenuTargetAssistance )
|
local MenuTargetAssistance = MENU_GROUP:New( self.EscortClient:GetGroup(), EscortGroupData.EscortName, self.EscortMenuTargetAssistance )
|
||||||
MENU_CLIENT_COMMAND:New( self.EscortClient,
|
MENU_GROUP_COMMAND:New( self.EscortClient:GetGroup(),
|
||||||
DetectedMsg,
|
DetectedMsg,
|
||||||
MenuTargetAssistance,
|
MenuTargetAssistance,
|
||||||
ESCORT._AssistTarget,
|
ESCORT._AssistTarget,
|
||||||
self,
|
self,
|
||||||
EscortGroupData.EscortGroup,
|
EscortGroupData.EscortGroup,
|
||||||
DetectedItemID
|
DetectedItem
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -1205,7 +1205,7 @@ function ESCORT:_ReportTargetsScheduler()
|
|||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
self:E( DetectedMsgs )
|
self:F( DetectedMsgs )
|
||||||
if DetectedTargets then
|
if DetectedTargets then
|
||||||
self.EscortGroup:MessageToClient( "Reporting detected targets:\n" .. table.concat( DetectedMsgs, "\n" ), 20, self.EscortClient )
|
self.EscortGroup:MessageToClient( "Reporting detected targets:\n" .. table.concat( DetectedMsgs, "\n" ), 20, self.EscortClient )
|
||||||
else
|
else
|
||||||
@@ -1327,7 +1327,7 @@ function ESCORT:_ReportTargetsScheduler()
|
|||||||
--
|
--
|
||||||
-- if ClientEscortGroupName == EscortGroupName then
|
-- if ClientEscortGroupName == EscortGroupName then
|
||||||
--
|
--
|
||||||
-- MENU_CLIENT_COMMAND:New( self.EscortClient,
|
-- MENU_GROUP_COMMAND:New( self.EscortClient,
|
||||||
-- EscortTargetMessage,
|
-- EscortTargetMessage,
|
||||||
-- self.EscortMenuAttackNearbyTargets,
|
-- self.EscortMenuAttackNearbyTargets,
|
||||||
-- ESCORT._AttackTarget,
|
-- ESCORT._AttackTarget,
|
||||||
@@ -1338,8 +1338,8 @@ function ESCORT:_ReportTargetsScheduler()
|
|||||||
-- EscortTargetMessages = EscortTargetMessages .. "\n - " .. EscortTargetMessage
|
-- EscortTargetMessages = EscortTargetMessages .. "\n - " .. EscortTargetMessage
|
||||||
-- else
|
-- else
|
||||||
-- if self.EscortMenuTargetAssistance then
|
-- if self.EscortMenuTargetAssistance then
|
||||||
-- local MenuTargetAssistance = MENU_CLIENT:New( self.EscortClient, EscortGroupData.EscortName, self.EscortMenuTargetAssistance )
|
-- local MenuTargetAssistance = MENU_GROUP:New( self.EscortClient, EscortGroupData.EscortName, self.EscortMenuTargetAssistance )
|
||||||
-- MENU_CLIENT_COMMAND:New( self.EscortClient,
|
-- MENU_GROUP_COMMAND:New( self.EscortClient,
|
||||||
-- EscortTargetMessage,
|
-- EscortTargetMessage,
|
||||||
-- MenuTargetAssistance,
|
-- MenuTargetAssistance,
|
||||||
-- ESCORT._AssistTarget,
|
-- ESCORT._AssistTarget,
|
||||||
@@ -1378,7 +1378,7 @@ function ESCORT:_ReportTargetsScheduler()
|
|||||||
-- local Distance = ( ( WayPoint.x - EscortVec3.x )^2 +
|
-- local Distance = ( ( WayPoint.x - EscortVec3.x )^2 +
|
||||||
-- ( WayPoint.y - EscortVec3.z )^2
|
-- ( WayPoint.y - EscortVec3.z )^2
|
||||||
-- ) ^ 0.5 / 1000
|
-- ) ^ 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 } )
|
-- MENU_GROUP_COMMAND:New( self.EscortClient, "Waypoint " .. WayPointID .. " at " .. string.format( "%.2f", Distance ).. "km", self.EscortMenuResumeMission, ESCORT._ResumeMission, { ParamSelf = self, ParamWayPoint = WayPointID } )
|
||||||
-- end
|
-- end
|
||||||
-- end
|
-- end
|
||||||
--
|
--
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
-- 1) @{MissileTrainer#MISSILETRAINER} class, extends @{Base#BASE}
|
-- 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 @{#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.
|
-- the class will destroy the missile within a certain range, to avoid damage to your aircraft.
|
||||||
-- It suports the following functionality:
|
-- It suports the following functionality:
|
||||||
@@ -71,7 +71,7 @@
|
|||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
-- CREDITS
|
-- CREDITS
|
||||||
-- =======
|
-- ===
|
||||||
-- **Stuka (Danny)** Who you can search on the Eagle Dynamics Forums.
|
-- **Stuka (Danny)** Who you can search on the Eagle Dynamics Forums.
|
||||||
-- Working together with Danny has resulted in the MISSILETRAINER class.
|
-- Working together with Danny has resulted in the MISSILETRAINER class.
|
||||||
-- Danny has shared his ideas and together we made a design.
|
-- Danny has shared his ideas and together we made a design.
|
||||||
@@ -99,39 +99,39 @@ function MISSILETRAINER._Alive( Client, self )
|
|||||||
if self.MenusOnOff == true then
|
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: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.MainMenu = MENU_GROUP:New( Client:GetGroup(), "Missile Trainer", nil ) -- Menu#MENU_GROUP
|
||||||
|
|
||||||
Client.MenuMessages = MENU_CLIENT:New( Client, "Messages", Client.MainMenu )
|
Client.MenuMessages = MENU_GROUP:New( Client:GetGroup(), "Messages", Client.MainMenu )
|
||||||
Client.MenuOn = MENU_CLIENT_COMMAND:New( Client, "Messages On", Client.MenuMessages, self._MenuMessages, { MenuSelf = self, MessagesOnOff = true } )
|
Client.MenuOn = MENU_GROUP_COMMAND:New( Client:GetGroup(), "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.MenuOff = MENU_GROUP_COMMAND:New( Client:GetGroup(), "Messages Off", Client.MenuMessages, self._MenuMessages, { MenuSelf = self, MessagesOnOff = false } )
|
||||||
|
|
||||||
Client.MenuTracking = MENU_CLIENT:New( Client, "Tracking", Client.MainMenu )
|
Client.MenuTracking = MENU_GROUP:New( Client:GetGroup(), "Tracking", Client.MainMenu )
|
||||||
Client.MenuTrackingToAll = MENU_CLIENT_COMMAND:New( Client, "To All", Client.MenuTracking, self._MenuMessages, { MenuSelf = self, TrackingToAll = true } )
|
Client.MenuTrackingToAll = MENU_GROUP_COMMAND:New( Client:GetGroup(), "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.MenuTrackingToTarget = MENU_GROUP_COMMAND:New( Client:GetGroup(), "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.MenuTrackOn = MENU_GROUP_COMMAND:New( Client:GetGroup(), "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.MenuTrackOff = MENU_GROUP_COMMAND:New( Client:GetGroup(), "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.MenuTrackIncrease = MENU_GROUP_COMMAND:New( Client:GetGroup(), "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.MenuTrackDecrease = MENU_GROUP_COMMAND:New( Client:GetGroup(), "Frequency Decrease", Client.MenuTracking, self._MenuMessages, { MenuSelf = self, TrackingFrequency = 1 } )
|
||||||
|
|
||||||
Client.MenuAlerts = MENU_CLIENT:New( Client, "Alerts", Client.MainMenu )
|
Client.MenuAlerts = MENU_GROUP:New( Client:GetGroup(), "Alerts", Client.MainMenu )
|
||||||
Client.MenuAlertsToAll = MENU_CLIENT_COMMAND:New( Client, "To All", Client.MenuAlerts, self._MenuMessages, { MenuSelf = self, AlertsToAll = true } )
|
Client.MenuAlertsToAll = MENU_GROUP_COMMAND:New( Client:GetGroup(), "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.MenuAlertsToTarget = MENU_GROUP_COMMAND:New( Client:GetGroup(), "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.MenuHitsOn = MENU_GROUP_COMMAND:New( Client:GetGroup(), "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.MenuHitsOff = MENU_GROUP_COMMAND:New( Client:GetGroup(), "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.MenuLaunchesOn = MENU_GROUP_COMMAND:New( Client:GetGroup(), "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.MenuLaunchesOff = MENU_GROUP_COMMAND:New( Client:GetGroup(), "Launches Off", Client.MenuAlerts, self._MenuMessages, { MenuSelf = self, AlertsLaunchesOnOff = false } )
|
||||||
|
|
||||||
Client.MenuDetails = MENU_CLIENT:New( Client, "Details", Client.MainMenu )
|
Client.MenuDetails = MENU_GROUP:New( Client:GetGroup(), "Details", Client.MainMenu )
|
||||||
Client.MenuDetailsDistanceOn = MENU_CLIENT_COMMAND:New( Client, "Range On", Client.MenuDetails, self._MenuMessages, { MenuSelf = self, DetailsRangeOnOff = true } )
|
Client.MenuDetailsDistanceOn = MENU_GROUP_COMMAND:New( Client:GetGroup(), "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.MenuDetailsDistanceOff = MENU_GROUP_COMMAND:New( Client:GetGroup(), "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.MenuDetailsBearingOn = MENU_GROUP_COMMAND:New( Client:GetGroup(), "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.MenuDetailsBearingOff = MENU_GROUP_COMMAND:New( Client:GetGroup(), "Bearing Off", Client.MenuDetails, self._MenuMessages, { MenuSelf = self, DetailsBearingOnOff = false } )
|
||||||
|
|
||||||
Client.MenuDistance = MENU_CLIENT:New( Client, "Set distance to plane", Client.MainMenu )
|
Client.MenuDistance = MENU_GROUP:New( Client:GetGroup(), "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.MenuDistance50 = MENU_GROUP_COMMAND:New( Client:GetGroup(), "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.MenuDistance100 = MENU_GROUP_COMMAND:New( Client:GetGroup(), "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.MenuDistance150 = MENU_GROUP_COMMAND:New( Client:GetGroup(), "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 } )
|
Client.MenuDistance200 = MENU_GROUP_COMMAND:New( Client:GetGroup(), "200 meter", Client.MenuDistance, self._MenuMessages, { MenuSelf = self, Distance = 200 / 1000 } )
|
||||||
else
|
else
|
||||||
if Client.MainMenu then
|
if Client.MainMenu then
|
||||||
Client.MainMenu:Remove()
|
Client.MainMenu:Remove()
|
||||||
@@ -177,13 +177,13 @@ function MISSILETRAINER:New( Distance, Briefing )
|
|||||||
|
|
||||||
|
|
||||||
-- for ClientID, Client in pairs( self.DBClients.Database ) do
|
-- for ClientID, Client in pairs( self.DBClients.Database ) do
|
||||||
-- self:E( "ForEach:" .. Client.UnitName )
|
-- self:F( "ForEach:" .. Client.UnitName )
|
||||||
-- Client:Alive( self._Alive, self )
|
-- Client:Alive( self._Alive, self )
|
||||||
-- end
|
-- end
|
||||||
--
|
--
|
||||||
self.DBClients:ForEachClient(
|
self.DBClients:ForEachClient(
|
||||||
function( Client )
|
function( Client )
|
||||||
self:E( "ForEach:" .. Client.UnitName )
|
self:F( "ForEach:" .. Client.UnitName )
|
||||||
Client:Alive( self._Alive, self )
|
Client:Alive( self._Alive, self )
|
||||||
end
|
end
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
--- **Functional** -- Limit the MOVEMENT of simulaneous moving ground vehicles.
|
--- **Functional** -- Limit the MOVEMENT of simulaneous moving ground vehicles.
|
||||||
--
|
--
|
||||||
-- ====
|
-- ===
|
||||||
--
|
--
|
||||||
-- Limit the simultaneous movement of Groups within a running Mission.
|
-- Limit the simultaneous movement of Groups within a running Mission.
|
||||||
-- This module is defined to improve the performance in missions, and to bring additional realism for GROUND vehicles.
|
-- This module is defined to improve the performance in missions, and to bring additional realism for GROUND vehicles.
|
||||||
|
|||||||
305
Moose Development/Moose/Functional/Protect.lua
Normal file
305
Moose Development/Moose/Functional/Protect.lua
Normal file
@@ -0,0 +1,305 @@
|
|||||||
|
--- **Functional** -- The PROTECT class handles the protection of objects, which can be zones, units, scenery.
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- ### Author: **FlightControl**
|
||||||
|
-- ### Contributions: **MillerTime**
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- @module Protect
|
||||||
|
|
||||||
|
--- @type PROTECT.__ Methods which are not intended for mission designers, but which are used interally by the moose designer :-)
|
||||||
|
-- @extends Core.Fsm#FSM
|
||||||
|
|
||||||
|
--- @type PROTECT
|
||||||
|
-- @extends #PROTECT.__
|
||||||
|
|
||||||
|
--- # PROTECT, extends @{Base#BASE}
|
||||||
|
--
|
||||||
|
-- @field #PROTECT
|
||||||
|
PROTECT = {
|
||||||
|
ClassName = "PROTECT",
|
||||||
|
}
|
||||||
|
|
||||||
|
--- Get the ProtectZone
|
||||||
|
-- @param #PROTECT self
|
||||||
|
-- @return Core.Zone#ZONE_BASE
|
||||||
|
function PROTECT:GetProtectZone()
|
||||||
|
return self.ProtectZone
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Get the name of the ProtectZone
|
||||||
|
-- @param #PROTECT self
|
||||||
|
-- @return #string
|
||||||
|
function PROTECT:GetProtectZoneName()
|
||||||
|
return self.ProtectZone:GetName()
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Set the owning coalition of the zone.
|
||||||
|
-- @param #PROTECT self
|
||||||
|
-- @param DCSCoalition.DCSCoalition#coalition Coalition
|
||||||
|
function PROTECT:SetCoalition( Coalition )
|
||||||
|
self.Coalition = Coalition
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Get the owning coalition of the zone.
|
||||||
|
-- @param #PROTECT self
|
||||||
|
-- @return DCSCoalition.DCSCoalition#coalition Coalition.
|
||||||
|
function PROTECT:GetCoalition()
|
||||||
|
return self.Coalition
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Get the owning coalition name of the zone.
|
||||||
|
-- @param #PROTECT self
|
||||||
|
-- @return #string Coalition name.
|
||||||
|
function PROTECT:GetCoalitionName()
|
||||||
|
|
||||||
|
if self.Coalition == coalition.side.BLUE then
|
||||||
|
return "Blue"
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.Coalition == coalition.side.RED then
|
||||||
|
return "Red"
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.Coalition == coalition.side.NEUTRAL then
|
||||||
|
return "Neutral"
|
||||||
|
end
|
||||||
|
|
||||||
|
return ""
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function PROTECT:IsGuarded()
|
||||||
|
|
||||||
|
local IsGuarded = self.ProtectZone:IsAllInZoneOfCoalition( self.Coalition )
|
||||||
|
self:F( { IsGuarded = IsGuarded } )
|
||||||
|
return IsGuarded
|
||||||
|
end
|
||||||
|
|
||||||
|
function PROTECT:IsCaptured()
|
||||||
|
|
||||||
|
local IsCaptured = self.ProtectZone:IsAllInZoneOfOtherCoalition( self.Coalition )
|
||||||
|
self:F( { IsCaptured = IsCaptured } )
|
||||||
|
return IsCaptured
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function PROTECT:IsAttacked()
|
||||||
|
|
||||||
|
local IsAttacked = self.ProtectZone:IsSomeInZoneOfCoalition( self.Coalition )
|
||||||
|
self:F( { IsAttacked = IsAttacked } )
|
||||||
|
return IsAttacked
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function PROTECT:IsEmpty()
|
||||||
|
|
||||||
|
local IsEmpty = self.ProtectZone:IsNoneInZone()
|
||||||
|
self:F( { IsEmpty = IsEmpty } )
|
||||||
|
return IsEmpty
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Check if the units are still alive.
|
||||||
|
-- @param #PROTECT self
|
||||||
|
function PROTECT:AreProtectUnitsAlive()
|
||||||
|
|
||||||
|
local IsAlive = false
|
||||||
|
|
||||||
|
local UnitSet = self.ProtectUnitSet
|
||||||
|
UnitSet:Flush( self )
|
||||||
|
local UnitList = UnitSet:GetSet()
|
||||||
|
|
||||||
|
for UnitID, ProtectUnit in pairs( UnitList ) do
|
||||||
|
local IsUnitAlive = ProtectUnit:IsAlive()
|
||||||
|
if IsUnitAlive == true then
|
||||||
|
IsAlive = true
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return IsAlive
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Check if the statics are still alive.
|
||||||
|
-- @param #PROTECT self
|
||||||
|
function PROTECT:AreProtectStaticsAlive()
|
||||||
|
|
||||||
|
local IsAlive = false
|
||||||
|
|
||||||
|
local StaticSet = self.ProtectStaticSet
|
||||||
|
StaticSet:Flush( self )
|
||||||
|
local StaticList = StaticSet:GetSet()
|
||||||
|
|
||||||
|
for UnitID, ProtectStatic in pairs( StaticList ) do
|
||||||
|
local IsStaticAlive = ProtectStatic:IsAlive()
|
||||||
|
if IsStaticAlive == true then
|
||||||
|
IsAlive = true
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return IsAlive
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Check if there is a capture unit in the zone.
|
||||||
|
-- @param #PROTECT self
|
||||||
|
function PROTECT:IsCaptureUnitInZone()
|
||||||
|
|
||||||
|
local CaptureUnitSet = self.CaptureUnitSet
|
||||||
|
CaptureUnitSet:Flush( self )
|
||||||
|
|
||||||
|
local IsInZone = self.CaptureUnitSet:IsPartiallyInZone( self.ProtectZone )
|
||||||
|
|
||||||
|
self:F({IsInZone = IsInZone})
|
||||||
|
|
||||||
|
return IsInZone
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Smoke.
|
||||||
|
-- @param #PROTECT self
|
||||||
|
-- @param #SMOKECOLOR.Color SmokeColor
|
||||||
|
function PROTECT:Smoke( SmokeColor )
|
||||||
|
|
||||||
|
self.SmokeColor = SmokeColor
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Flare.
|
||||||
|
-- @param #PROTECT self
|
||||||
|
-- @param #SMOKECOLOR.Color FlareColor
|
||||||
|
function PROTECT:Flare( FlareColor )
|
||||||
|
self.ProtectZone:FlareZone( FlareColor, math.random( 1, 360 ) )
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Mark.
|
||||||
|
-- @param #PROTECT self
|
||||||
|
function PROTECT:Mark()
|
||||||
|
|
||||||
|
local Coord = self.ProtectZone:GetCoordinate()
|
||||||
|
local ZoneName = self:GetProtectZoneName()
|
||||||
|
local State = self:GetState()
|
||||||
|
|
||||||
|
if self.MarkRed and self.MarkBlue then
|
||||||
|
self:F( { MarkRed = self.MarkRed, MarkBlue = self.MarkBlue } )
|
||||||
|
Coord:RemoveMark( self.MarkRed )
|
||||||
|
Coord:RemoveMark( self.MarkBlue )
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.Coalition == coalition.side.BLUE then
|
||||||
|
self.MarkBlue = Coord:MarkToCoalitionBlue( "Guard Zone: " .. ZoneName .. "\nStatus: " .. State )
|
||||||
|
self.MarkRed = Coord:MarkToCoalitionRed( "Capture Zone: " .. ZoneName .. "\nStatus: " .. State )
|
||||||
|
else
|
||||||
|
self.MarkRed = Coord:MarkToCoalitionRed( "Guard Zone: " .. ZoneName .. "\nStatus: " .. State )
|
||||||
|
self.MarkBlue = Coord:MarkToCoalitionBlue( "Capture Zone: " .. ZoneName .. "\nStatus: " .. State )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Bound.
|
||||||
|
-- @param #PROTECT self
|
||||||
|
function PROTECT:onafterStart()
|
||||||
|
|
||||||
|
self:ScheduleRepeat( 5, 15, 0.1, nil, self.StatusCoalition, self )
|
||||||
|
self:ScheduleRepeat( 5, 15, 0.1, nil, self.StatusZone, self )
|
||||||
|
self:ScheduleRepeat( 10, 15, 0, nil, self.StatusSmoke, self )
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Bound.
|
||||||
|
-- @param #PROTECT self
|
||||||
|
function PROTECT:onenterGuarded()
|
||||||
|
|
||||||
|
|
||||||
|
if self.Coalition == coalition.side.BLUE then
|
||||||
|
--elf.ProtectZone:BoundZone( 12, country.id.USA )
|
||||||
|
else
|
||||||
|
--self.ProtectZone:BoundZone( 12, country.id.RUSSIA )
|
||||||
|
end
|
||||||
|
|
||||||
|
self:Mark()
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
function PROTECT:onenterCaptured()
|
||||||
|
|
||||||
|
local NewCoalition = self.ProtectZone:GetCoalition()
|
||||||
|
self:F( { NewCoalition = NewCoalition } )
|
||||||
|
self:SetCoalition( NewCoalition )
|
||||||
|
|
||||||
|
self:Mark()
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function PROTECT:onenterEmpty()
|
||||||
|
|
||||||
|
self:Mark()
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function PROTECT:onenterAttacked()
|
||||||
|
|
||||||
|
self:Mark()
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Check status Coalition ownership.
|
||||||
|
-- @param #PROTECT self
|
||||||
|
function PROTECT:StatusCoalition()
|
||||||
|
|
||||||
|
self:F( { State = self:GetState() } )
|
||||||
|
|
||||||
|
self.ProtectZone:Scan()
|
||||||
|
|
||||||
|
if self:IsGuarded() then
|
||||||
|
self:Guard()
|
||||||
|
else
|
||||||
|
if self:IsCaptured() then
|
||||||
|
self:Capture()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Check status Zone.
|
||||||
|
-- @param #PROTECT self
|
||||||
|
function PROTECT:StatusZone()
|
||||||
|
|
||||||
|
self:F( { State = self:GetState() } )
|
||||||
|
|
||||||
|
self.ProtectZone:Scan()
|
||||||
|
|
||||||
|
if self:IsAttacked() then
|
||||||
|
self:Attack()
|
||||||
|
else
|
||||||
|
if self:IsEmpty() then
|
||||||
|
self:Empty()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Check status Smoke.
|
||||||
|
-- @param #PROTECT self
|
||||||
|
function PROTECT:StatusSmoke()
|
||||||
|
|
||||||
|
local CurrentTime = timer.getTime()
|
||||||
|
|
||||||
|
if self.SmokeTime == nil or self.SmokeTime + 300 <= CurrentTime then
|
||||||
|
if self.SmokeColor then
|
||||||
|
self.ProtectZone:GetCoordinate():Smoke( self.SmokeColor )
|
||||||
|
--self.SmokeColor = nil
|
||||||
|
self.SmokeTime = CurrentTime
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
2359
Moose Development/Moose/Functional/Range.lua
Normal file
2359
Moose Development/Moose/Functional/Range.lua
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,6 @@
|
|||||||
--- **Functional** -- **Administer the SCORING of player achievements,
|
--- **Functional** -- (R2.0) - Administer the scoring of player achievements, and create a CSV file logging the scoring events for use at team or squadron websites.
|
||||||
-- and create a CSV file logging the scoring events for use at team or squadron websites.**
|
--
|
||||||
|
-- ===
|
||||||
--
|
--
|
||||||
-- 
|
-- 
|
||||||
--
|
--
|
||||||
@@ -102,7 +103,9 @@
|
|||||||
-- A mission has goals and achievements. The scoring system provides an API to set additional scores when a goal or achievement event happens.
|
-- A mission has goals and achievements. The scoring system provides an API to set additional scores when a goal or achievement event happens.
|
||||||
-- Use the method @{#SCORING.AddGoalScore}() to add a score for a Player at any time in your mission.
|
-- Use the method @{#SCORING.AddGoalScore}() to add a score for a Player at any time in your mission.
|
||||||
--
|
--
|
||||||
-- ## 1.5) Configure fratricide level.
|
-- ## 1.5) (Decommissioned) Configure fratricide level.
|
||||||
|
--
|
||||||
|
-- **This functionality is decomissioned until the DCS bug concerning Unit:destroy() not being functional in multi player for player units has been fixed by ED**.
|
||||||
--
|
--
|
||||||
-- When a player commits too much damage to friendlies, his penalty score will reach a certain level.
|
-- When a player commits too much damage to friendlies, his penalty score will reach a certain level.
|
||||||
-- Use the method @{#SCORING.SetFratricide}() to define the level when a player gets kicked.
|
-- Use the method @{#SCORING.SetFratricide}() to define the level when a player gets kicked.
|
||||||
@@ -176,7 +179,7 @@
|
|||||||
-- * @{#SCORING.SetMessagesToCoalition}(): Configure to send messages to only those players within the same coalition as the player.
|
-- * @{#SCORING.SetMessagesToCoalition}(): Configure to send messages to only those players within the same coalition as the player.
|
||||||
--
|
--
|
||||||
--
|
--
|
||||||
-- ====
|
-- ===
|
||||||
--
|
--
|
||||||
-- # **API CHANGE HISTORY**
|
-- # **API CHANGE HISTORY**
|
||||||
--
|
--
|
||||||
@@ -258,7 +261,7 @@ function SCORING:New( GameName )
|
|||||||
|
|
||||||
-- Configure Messages
|
-- Configure Messages
|
||||||
self:SetMessagesToAll()
|
self:SetMessagesToAll()
|
||||||
self:SetMessagesHit( true )
|
self:SetMessagesHit( false )
|
||||||
self:SetMessagesDestroy( true )
|
self:SetMessagesDestroy( true )
|
||||||
self:SetMessagesScore( true )
|
self:SetMessagesScore( true )
|
||||||
self:SetMessagesZone( true )
|
self:SetMessagesZone( true )
|
||||||
@@ -279,8 +282,22 @@ function SCORING:New( GameName )
|
|||||||
self:HandleEvent( EVENTS.Dead, self._EventOnDeadOrCrash )
|
self:HandleEvent( EVENTS.Dead, self._EventOnDeadOrCrash )
|
||||||
self:HandleEvent( EVENTS.Crash, self._EventOnDeadOrCrash )
|
self:HandleEvent( EVENTS.Crash, self._EventOnDeadOrCrash )
|
||||||
self:HandleEvent( EVENTS.Hit, self._EventOnHit )
|
self:HandleEvent( EVENTS.Hit, self._EventOnHit )
|
||||||
self:HandleEvent( EVENTS.PlayerEnterUnit )
|
self:HandleEvent( EVENTS.Birth )
|
||||||
|
--self:HandleEvent( EVENTS.PlayerEnterUnit )
|
||||||
self:HandleEvent( EVENTS.PlayerLeaveUnit )
|
self:HandleEvent( EVENTS.PlayerLeaveUnit )
|
||||||
|
|
||||||
|
-- During mission startup, especially for single player,
|
||||||
|
-- iterate the database for the player that has joined, and add him to the scoring, and set the menu.
|
||||||
|
-- But this can only be started one second after the mission has started, so i need to schedule this ...
|
||||||
|
self.ScoringPlayerScan = BASE:ScheduleOnce( 1,
|
||||||
|
function()
|
||||||
|
for PlayerName, PlayerUnit in pairs( _DATABASE:GetPlayerUnits() ) do
|
||||||
|
self:_AddPlayerFromUnit( PlayerUnit )
|
||||||
|
self:SetScoringMenu( PlayerUnit:GetGroup() )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
-- Create the CSV file.
|
-- Create the CSV file.
|
||||||
self:OpenCSV( GameName )
|
self:OpenCSV( GameName )
|
||||||
@@ -567,6 +584,19 @@ function SCORING:SetCoalitionChangePenalty( CoalitionChangePenalty )
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Sets the scoring menu.
|
||||||
|
-- @param #SCORING self
|
||||||
|
-- @return #SCORING
|
||||||
|
function SCORING:SetScoringMenu( ScoringGroup )
|
||||||
|
local Menu = MENU_GROUP:New( ScoringGroup, 'Scoring and Statistics' )
|
||||||
|
local ReportGroupSummary = MENU_GROUP_COMMAND:New( ScoringGroup, 'Summary report players in group', Menu, SCORING.ReportScoreGroupSummary, self, ScoringGroup )
|
||||||
|
local ReportGroupDetailed = MENU_GROUP_COMMAND:New( ScoringGroup, 'Detailed report players in group', Menu, SCORING.ReportScoreGroupDetailed, self, ScoringGroup )
|
||||||
|
local ReportToAllSummary = MENU_GROUP_COMMAND:New( ScoringGroup, 'Summary report all players', Menu, SCORING.ReportScoreAllSummary, self, ScoringGroup )
|
||||||
|
self:SetState( ScoringGroup, "ScoringMenu", Menu )
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Add a new player entering a Unit.
|
--- Add a new player entering a Unit.
|
||||||
-- @param #SCORING self
|
-- @param #SCORING self
|
||||||
-- @param Wrapper.Unit#UNIT UnitData
|
-- @param Wrapper.Unit#UNIT UnitData
|
||||||
@@ -616,6 +646,7 @@ function SCORING:_AddPlayerFromUnit( UnitData )
|
|||||||
UnitName, _SCORINGCoalition[UnitCoalition], _SCORINGCategory[UnitCategory], UnitData:GetTypeName() )
|
UnitName, _SCORINGCoalition[UnitCoalition], _SCORINGCategory[UnitCategory], UnitData:GetTypeName() )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
self.Players[PlayerName].UnitName = UnitName
|
self.Players[PlayerName].UnitName = UnitName
|
||||||
self.Players[PlayerName].UnitCoalition = UnitCoalition
|
self.Players[PlayerName].UnitCoalition = UnitCoalition
|
||||||
self.Players[PlayerName].UnitCategory = UnitCategory
|
self.Players[PlayerName].UnitCategory = UnitCategory
|
||||||
@@ -624,6 +655,8 @@ function SCORING:_AddPlayerFromUnit( UnitData )
|
|||||||
self.Players[PlayerName].ThreatLevel = UnitThreatLevel
|
self.Players[PlayerName].ThreatLevel = UnitThreatLevel
|
||||||
self.Players[PlayerName].ThreatType = UnitThreatType
|
self.Players[PlayerName].ThreatType = UnitThreatType
|
||||||
|
|
||||||
|
-- TODO: DCS bug concerning Units with skill level client don't get destroyed in multi player. This logic is deactivated until this bug gets fixed.
|
||||||
|
--[[
|
||||||
if self.Players[PlayerName].Penalty > self.Fratricide * 0.50 then
|
if self.Players[PlayerName].Penalty > self.Fratricide * 0.50 then
|
||||||
if self.Players[PlayerName].PenaltyWarning < 1 then
|
if self.Players[PlayerName].PenaltyWarning < 1 then
|
||||||
MESSAGE:NewType( self.DisplayMessagePrefix .. "Player '" .. PlayerName .. "': WARNING! If you continue to commit FRATRICIDE and have a PENALTY score higher than " .. self.Fratricide .. ", you will be COURT MARTIALED and DISMISSED from this mission! \nYour total penalty is: " .. self.Players[PlayerName].Penalty,
|
MESSAGE:NewType( self.DisplayMessagePrefix .. "Player '" .. PlayerName .. "': WARNING! If you continue to commit FRATRICIDE and have a PENALTY score higher than " .. self.Fratricide .. ", you will be COURT MARTIALED and DISMISSED from this mission! \nYour total penalty is: " .. self.Players[PlayerName].Penalty,
|
||||||
@@ -639,11 +672,42 @@ function SCORING:_AddPlayerFromUnit( UnitData )
|
|||||||
):ToAll()
|
):ToAll()
|
||||||
UnitData:GetGroup():Destroy()
|
UnitData:GetGroup():Destroy()
|
||||||
end
|
end
|
||||||
|
--]]
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Add a goal score for a player.
|
||||||
|
-- The method takes the Player name for which the Goal score needs to be set.
|
||||||
|
-- The GoalTag is a string or identifier that is taken into the CSV file scoring log to identify the goal.
|
||||||
|
-- A free text can be given that is shown to the players.
|
||||||
|
-- The Score can be both positive and negative.
|
||||||
|
-- @param #SCORING self
|
||||||
|
-- @param #string PlayerName The name of the Player.
|
||||||
|
-- @param #string GoalTag The string or identifier that is used in the CSV file to identify the goal (sort or group later in Excel).
|
||||||
|
-- @param #string Text A free text that is shown to the players.
|
||||||
|
-- @param #number Score The score can be both positive or negative ( Penalty ).
|
||||||
|
function SCORING:AddGoalScorePlayer( PlayerName, GoalTag, Text, Score )
|
||||||
|
|
||||||
|
self:F( { PlayerName, PlayerName, GoalTag, Text, Score } )
|
||||||
|
|
||||||
|
-- PlayerName can be nil, if the Unit with the player crashed or due to another reason.
|
||||||
|
if PlayerName then
|
||||||
|
local PlayerData = self.Players[PlayerName]
|
||||||
|
|
||||||
|
PlayerData.Goals[GoalTag] = PlayerData.Goals[GoalTag] or { Score = 0 }
|
||||||
|
PlayerData.Goals[GoalTag].Score = PlayerData.Goals[GoalTag].Score + Score
|
||||||
|
PlayerData.Score = PlayerData.Score + Score
|
||||||
|
|
||||||
|
MESSAGE:NewType( self.DisplayMessagePrefix .. Text, MESSAGE.Type.Information ):ToAll()
|
||||||
|
|
||||||
|
self:ScoreCSV( PlayerName, "", "GOAL_" .. string.upper( GoalTag ), 1, Score, nil )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--- Add a goal score for a player.
|
--- Add a goal score for a player.
|
||||||
-- The method takes the PlayerUnit for which the Goal score needs to be set.
|
-- The method takes the PlayerUnit for which the Goal score needs to be set.
|
||||||
-- The GoalTag is a string or identifier that is taken into the CSV file scoring log to identify the goal.
|
-- The GoalTag is a string or identifier that is taken into the CSV file scoring log to identify the goal.
|
||||||
@@ -658,7 +722,7 @@ function SCORING:AddGoalScore( PlayerUnit, GoalTag, Text, Score )
|
|||||||
|
|
||||||
local PlayerName = PlayerUnit:GetPlayerName()
|
local PlayerName = PlayerUnit:GetPlayerName()
|
||||||
|
|
||||||
self:E( { PlayerUnit.UnitName, PlayerName, GoalTag, Text, Score } )
|
self:F( { PlayerUnit.UnitName, PlayerName, GoalTag, Text, Score } )
|
||||||
|
|
||||||
-- PlayerName can be nil, if the Unit with the player crashed or due to another reason.
|
-- PlayerName can be nil, if the Unit with the player crashed or due to another reason.
|
||||||
if PlayerName then
|
if PlayerName then
|
||||||
@@ -686,7 +750,7 @@ function SCORING:_AddMissionTaskScore( Mission, PlayerUnit, Text, Score )
|
|||||||
local PlayerName = PlayerUnit:GetPlayerName()
|
local PlayerName = PlayerUnit:GetPlayerName()
|
||||||
local MissionName = Mission:GetName()
|
local MissionName = Mission:GetName()
|
||||||
|
|
||||||
self:E( { Mission:GetName(), PlayerUnit.UnitName, PlayerName, Text, Score } )
|
self:F( { Mission:GetName(), PlayerUnit.UnitName, PlayerName, Text, Score } )
|
||||||
|
|
||||||
-- PlayerName can be nil, if the Unit with the player crashed or due to another reason.
|
-- PlayerName can be nil, if the Unit with the player crashed or due to another reason.
|
||||||
if PlayerName then
|
if PlayerName then
|
||||||
@@ -704,12 +768,45 @@ function SCORING:_AddMissionTaskScore( Mission, PlayerUnit, Text, Score )
|
|||||||
PlayerData.Score = self.Players[PlayerName].Score + Score
|
PlayerData.Score = self.Players[PlayerName].Score + Score
|
||||||
PlayerData.Mission[MissionName].ScoreTask = self.Players[PlayerName].Mission[MissionName].ScoreTask + Score
|
PlayerData.Mission[MissionName].ScoreTask = self.Players[PlayerName].Mission[MissionName].ScoreTask + Score
|
||||||
|
|
||||||
MESSAGE:NewType( self.DisplayMessagePrefix .. MissionName .. " : " .. Text .. " Score: " .. Score, MESSAGE.Type.Information ):ToAll()
|
MESSAGE:NewType( self.DisplayMessagePrefix .. Mission:GetText() .. " : " .. Text .. " Score: " .. Score, MESSAGE.Type.Information ):ToAll()
|
||||||
|
|
||||||
self:ScoreCSV( PlayerName, "", "TASK_" .. MissionName:gsub( ' ', '_' ), 1, Score, PlayerUnit:GetName() )
|
self:ScoreCSV( PlayerName, "", "TASK_" .. MissionName:gsub( ' ', '_' ), 1, Score, PlayerUnit:GetName() )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Registers Scores the players completing a Mission Task.
|
||||||
|
-- @param #SCORING self
|
||||||
|
-- @param Tasking.Mission#MISSION Mission
|
||||||
|
-- @param #string PlayerName
|
||||||
|
-- @param #string Text
|
||||||
|
-- @param #number Score
|
||||||
|
function SCORING:_AddMissionGoalScore( Mission, PlayerName, Text, Score )
|
||||||
|
|
||||||
|
local MissionName = Mission:GetName()
|
||||||
|
|
||||||
|
self:F( { Mission:GetName(), PlayerName, Text, Score } )
|
||||||
|
|
||||||
|
-- PlayerName can be nil, if the Unit with the player crashed or due to another reason.
|
||||||
|
if PlayerName then
|
||||||
|
local PlayerData = self.Players[PlayerName]
|
||||||
|
|
||||||
|
if not PlayerData.Mission[MissionName] then
|
||||||
|
PlayerData.Mission[MissionName] = {}
|
||||||
|
PlayerData.Mission[MissionName].ScoreTask = 0
|
||||||
|
PlayerData.Mission[MissionName].ScoreMission = 0
|
||||||
|
end
|
||||||
|
|
||||||
|
self:T( PlayerName )
|
||||||
|
self:T( PlayerData.Mission[MissionName] )
|
||||||
|
|
||||||
|
PlayerData.Score = self.Players[PlayerName].Score + Score
|
||||||
|
PlayerData.Mission[MissionName].ScoreTask = self.Players[PlayerName].Mission[MissionName].ScoreTask + Score
|
||||||
|
|
||||||
|
MESSAGE:NewType( string.format( "%s%s: %s! Player %s receives %d score!", self.DisplayMessagePrefix, Mission:GetText(), Text, PlayerName, Score ), MESSAGE.Type.Information ):ToAll()
|
||||||
|
|
||||||
|
self:ScoreCSV( PlayerName, "", "TASK_" .. MissionName:gsub( ' ', '_' ), 1, Score )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
--- Registers Mission Scores for possible multiple players that contributed in the Mission.
|
--- Registers Mission Scores for possible multiple players that contributed in the Mission.
|
||||||
-- @param #SCORING self
|
-- @param #SCORING self
|
||||||
@@ -721,18 +818,18 @@ function SCORING:_AddMissionScore( Mission, Text, Score )
|
|||||||
|
|
||||||
local MissionName = Mission:GetName()
|
local MissionName = Mission:GetName()
|
||||||
|
|
||||||
self:E( { Mission, Text, Score } )
|
self:F( { Mission, Text, Score } )
|
||||||
self:E( self.Players )
|
self:F( self.Players )
|
||||||
|
|
||||||
for PlayerName, PlayerData in pairs( self.Players ) do
|
for PlayerName, PlayerData in pairs( self.Players ) do
|
||||||
|
|
||||||
self:E( PlayerData )
|
self:F( PlayerData )
|
||||||
if PlayerData.Mission[MissionName] then
|
if PlayerData.Mission[MissionName] then
|
||||||
|
|
||||||
PlayerData.Score = PlayerData.Score + Score
|
PlayerData.Score = PlayerData.Score + Score
|
||||||
PlayerData.Mission[MissionName].ScoreMission = PlayerData.Mission[MissionName].ScoreMission + Score
|
PlayerData.Mission[MissionName].ScoreMission = PlayerData.Mission[MissionName].ScoreMission + Score
|
||||||
|
|
||||||
MESSAGE:NewType( self.DisplayMessagePrefix .. "Player '" .. PlayerName .. "' has " .. Text .. " in Mission '" .. MissionName .. "'. " ..
|
MESSAGE:NewType( self.DisplayMessagePrefix .. "Player '" .. PlayerName .. "' has " .. Text .. " in " .. Mission:GetText() .. ". " ..
|
||||||
Score .. " mission score!",
|
Score .. " mission score!",
|
||||||
MESSAGE.Type.Information ):ToAll()
|
MESSAGE.Type.Information ):ToAll()
|
||||||
|
|
||||||
@@ -742,17 +839,30 @@ function SCORING:_AddMissionScore( Mission, Text, Score )
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--- Handles the OnPlayerEnterUnit event for the scoring.
|
--- Handles the OnPlayerEnterUnit event for the scoring.
|
||||||
-- @param #SCORING self
|
-- @param #SCORING self
|
||||||
-- @param Core.Event#EVENTDATA Event
|
-- @param Core.Event#EVENTDATA Event
|
||||||
function SCORING:OnEventPlayerEnterUnit( Event )
|
--function SCORING:OnEventPlayerEnterUnit( Event )
|
||||||
|
-- if Event.IniUnit then
|
||||||
|
-- self:_AddPlayerFromUnit( Event.IniUnit )
|
||||||
|
-- self:SetScoringMenu( Event.IniGroup )
|
||||||
|
-- end
|
||||||
|
--end
|
||||||
|
|
||||||
|
--- Handles the OnBirth event for the scoring.
|
||||||
|
-- @param #SCORING self
|
||||||
|
-- @param Core.Event#EVENTDATA Event
|
||||||
|
function SCORING:OnEventBirth( Event )
|
||||||
|
|
||||||
if Event.IniUnit then
|
if Event.IniUnit then
|
||||||
self:_AddPlayerFromUnit( Event.IniUnit )
|
if Event.IniObjectCategory == 1 then
|
||||||
local Menu = MENU_GROUP:New( Event.IniGroup, 'Scoring' )
|
local PlayerName = Event.IniUnit:GetPlayerName()
|
||||||
local ReportGroupSummary = MENU_GROUP_COMMAND:New( Event.IniGroup, 'Summary report players in group', Menu, SCORING.ReportScoreGroupSummary, self, Event.IniGroup )
|
if PlayerName ~= "" then
|
||||||
local ReportGroupDetailed = MENU_GROUP_COMMAND:New( Event.IniGroup, 'Detailed report players in group', Menu, SCORING.ReportScoreGroupDetailed, self, Event.IniGroup )
|
self:_AddPlayerFromUnit( Event.IniUnit )
|
||||||
local ReportToAllSummary = MENU_GROUP_COMMAND:New( Event.IniGroup, 'Summary report all players', Menu, SCORING.ReportScoreAllSummary, self, Event.IniGroup )
|
self:SetScoringMenu( Event.IniGroup )
|
||||||
self:SetState( Event.IniUnit, "ScoringMenu", Menu )
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -761,7 +871,7 @@ end
|
|||||||
-- @param Core.Event#EVENTDATA Event
|
-- @param Core.Event#EVENTDATA Event
|
||||||
function SCORING:OnEventPlayerLeaveUnit( Event )
|
function SCORING:OnEventPlayerLeaveUnit( Event )
|
||||||
if Event.IniUnit then
|
if Event.IniUnit then
|
||||||
local Menu = self:GetState( Event.IniUnit, "ScoringMenu" ) -- Core.Menu#MENU_GROUP
|
local Menu = self:GetState( Event.IniUnit:GetGroup(), "ScoringMenu" ) -- Core.Menu#MENU_GROUP
|
||||||
if Menu then
|
if Menu then
|
||||||
-- TODO: Check if this fixes #281.
|
-- TODO: Check if this fixes #281.
|
||||||
--Menu:Remove()
|
--Menu:Remove()
|
||||||
@@ -1123,7 +1233,7 @@ function SCORING:_EventOnDeadOrCrash( Event )
|
|||||||
local ThreatTypeTarget = TargetThreatType
|
local ThreatTypeTarget = TargetThreatType
|
||||||
local ThreatLevelPlayer = Player.ThreatLevel / 10 + 1
|
local ThreatLevelPlayer = Player.ThreatLevel / 10 + 1
|
||||||
local ThreatPenalty = math.ceil( ( ThreatLevelTarget / ThreatLevelPlayer ) * self.ScaleDestroyPenalty / 10 )
|
local ThreatPenalty = math.ceil( ( ThreatLevelTarget / ThreatLevelPlayer ) * self.ScaleDestroyPenalty / 10 )
|
||||||
self:E( { ThreatLevel = ThreatPenalty, ThreatLevelTarget = ThreatLevelTarget, ThreatTypeTarget = ThreatTypeTarget, ThreatLevelPlayer = ThreatLevelPlayer } )
|
self:F( { ThreatLevel = ThreatPenalty, ThreatLevelTarget = ThreatLevelTarget, ThreatTypeTarget = ThreatTypeTarget, ThreatLevelPlayer = ThreatLevelPlayer } )
|
||||||
|
|
||||||
Player.Penalty = Player.Penalty + ThreatPenalty
|
Player.Penalty = Player.Penalty + ThreatPenalty
|
||||||
TargetDestroy.Penalty = TargetDestroy.Penalty + ThreatPenalty
|
TargetDestroy.Penalty = TargetDestroy.Penalty + ThreatPenalty
|
||||||
@@ -1158,7 +1268,7 @@ function SCORING:_EventOnDeadOrCrash( Event )
|
|||||||
local ThreatLevelPlayer = Player.ThreatLevel / 10 + 1
|
local ThreatLevelPlayer = Player.ThreatLevel / 10 + 1
|
||||||
local ThreatScore = math.ceil( ( ThreatLevelTarget / ThreatLevelPlayer ) * self.ScaleDestroyScore / 10 )
|
local ThreatScore = math.ceil( ( ThreatLevelTarget / ThreatLevelPlayer ) * self.ScaleDestroyScore / 10 )
|
||||||
|
|
||||||
self:E( { ThreatLevel = ThreatScore, ThreatLevelTarget = ThreatLevelTarget, ThreatTypeTarget = ThreatTypeTarget, ThreatLevelPlayer = ThreatLevelPlayer } )
|
self:F( { ThreatLevel = ThreatScore, ThreatLevelTarget = ThreatLevelTarget, ThreatTypeTarget = ThreatTypeTarget, ThreatLevelPlayer = ThreatLevelPlayer } )
|
||||||
|
|
||||||
Player.Score = Player.Score + ThreatScore
|
Player.Score = Player.Score + ThreatScore
|
||||||
TargetDestroy.Score = TargetDestroy.Score + ThreatScore
|
TargetDestroy.Score = TargetDestroy.Score + ThreatScore
|
||||||
@@ -1203,7 +1313,7 @@ function SCORING:_EventOnDeadOrCrash( Event )
|
|||||||
|
|
||||||
-- Check if there are Zones where the destruction happened.
|
-- Check if there are Zones where the destruction happened.
|
||||||
for ZoneName, ScoreZoneData in pairs( self.ScoringZones ) do
|
for ZoneName, ScoreZoneData in pairs( self.ScoringZones ) do
|
||||||
self:E( { ScoringZone = ScoreZoneData } )
|
self:F( { ScoringZone = ScoreZoneData } )
|
||||||
local ScoreZone = ScoreZoneData.ScoreZone -- Core.Zone#ZONE_BASE
|
local ScoreZone = ScoreZoneData.ScoreZone -- Core.Zone#ZONE_BASE
|
||||||
local Score = ScoreZoneData.Score
|
local Score = ScoreZoneData.Score
|
||||||
if ScoreZone:IsVec2InZone( TargetUnit:GetVec2() ) then
|
if ScoreZone:IsVec2InZone( TargetUnit:GetVec2() ) then
|
||||||
@@ -1225,7 +1335,7 @@ function SCORING:_EventOnDeadOrCrash( Event )
|
|||||||
else
|
else
|
||||||
-- Check if there are Zones where the destruction happened.
|
-- Check if there are Zones where the destruction happened.
|
||||||
for ZoneName, ScoreZoneData in pairs( self.ScoringZones ) do
|
for ZoneName, ScoreZoneData in pairs( self.ScoringZones ) do
|
||||||
self:E( { ScoringZone = ScoreZoneData } )
|
self:F( { ScoringZone = ScoreZoneData } )
|
||||||
local ScoreZone = ScoreZoneData.ScoreZone -- Core.Zone#ZONE_BASE
|
local ScoreZone = ScoreZoneData.ScoreZone -- Core.Zone#ZONE_BASE
|
||||||
local Score = ScoreZoneData.Score
|
local Score = ScoreZoneData.Score
|
||||||
if ScoreZone:IsVec2InZone( TargetUnit:GetVec2() ) then
|
if ScoreZone:IsVec2InZone( TargetUnit:GetVec2() ) then
|
||||||
@@ -1340,7 +1450,7 @@ function SCORING:ReportDetailedPlayerDestroys( PlayerName )
|
|||||||
local PenaltyDestroy = 0
|
local PenaltyDestroy = 0
|
||||||
|
|
||||||
for UnitName, UnitData in pairs( PlayerData.Destroy[CategoryID] ) do
|
for UnitName, UnitData in pairs( PlayerData.Destroy[CategoryID] ) do
|
||||||
self:E( { UnitData = UnitData } )
|
self:F( { UnitData = UnitData } )
|
||||||
if UnitData ~= {} then
|
if UnitData ~= {} then
|
||||||
Score = Score + UnitData.Score
|
Score = Score + UnitData.Score
|
||||||
ScoreDestroy = ScoreDestroy + UnitData.ScoreDestroy
|
ScoreDestroy = ScoreDestroy + UnitData.ScoreDestroy
|
||||||
@@ -1494,23 +1604,23 @@ function SCORING:ReportScoreGroupSummary( PlayerGroup )
|
|||||||
|
|
||||||
local ReportHits, ScoreHits, PenaltyHits = self:ReportDetailedPlayerHits( PlayerName )
|
local ReportHits, ScoreHits, PenaltyHits = self:ReportDetailedPlayerHits( PlayerName )
|
||||||
ReportHits = ReportHits ~= "" and "\n- " .. ReportHits or ReportHits
|
ReportHits = ReportHits ~= "" and "\n- " .. ReportHits or ReportHits
|
||||||
self:E( { ReportHits, ScoreHits, PenaltyHits } )
|
self:F( { ReportHits, ScoreHits, PenaltyHits } )
|
||||||
|
|
||||||
local ReportDestroys, ScoreDestroys, PenaltyDestroys = self:ReportDetailedPlayerDestroys( PlayerName )
|
local ReportDestroys, ScoreDestroys, PenaltyDestroys = self:ReportDetailedPlayerDestroys( PlayerName )
|
||||||
ReportDestroys = ReportDestroys ~= "" and "\n- " .. ReportDestroys or ReportDestroys
|
ReportDestroys = ReportDestroys ~= "" and "\n- " .. ReportDestroys or ReportDestroys
|
||||||
self:E( { ReportDestroys, ScoreDestroys, PenaltyDestroys } )
|
self:F( { ReportDestroys, ScoreDestroys, PenaltyDestroys } )
|
||||||
|
|
||||||
local ReportCoalitionChanges, ScoreCoalitionChanges, PenaltyCoalitionChanges = self:ReportDetailedPlayerCoalitionChanges( PlayerName )
|
local ReportCoalitionChanges, ScoreCoalitionChanges, PenaltyCoalitionChanges = self:ReportDetailedPlayerCoalitionChanges( PlayerName )
|
||||||
ReportCoalitionChanges = ReportCoalitionChanges ~= "" and "\n- " .. ReportCoalitionChanges or ReportCoalitionChanges
|
ReportCoalitionChanges = ReportCoalitionChanges ~= "" and "\n- " .. ReportCoalitionChanges or ReportCoalitionChanges
|
||||||
self:E( { ReportCoalitionChanges, ScoreCoalitionChanges, PenaltyCoalitionChanges } )
|
self:F( { ReportCoalitionChanges, ScoreCoalitionChanges, PenaltyCoalitionChanges } )
|
||||||
|
|
||||||
local ReportGoals, ScoreGoals, PenaltyGoals = self:ReportDetailedPlayerGoals( PlayerName )
|
local ReportGoals, ScoreGoals, PenaltyGoals = self:ReportDetailedPlayerGoals( PlayerName )
|
||||||
ReportGoals = ReportGoals ~= "" and "\n- " .. ReportGoals or ReportGoals
|
ReportGoals = ReportGoals ~= "" and "\n- " .. ReportGoals or ReportGoals
|
||||||
self:E( { ReportGoals, ScoreGoals, PenaltyGoals } )
|
self:F( { ReportGoals, ScoreGoals, PenaltyGoals } )
|
||||||
|
|
||||||
local ReportMissions, ScoreMissions, PenaltyMissions = self:ReportDetailedPlayerMissions( PlayerName )
|
local ReportMissions, ScoreMissions, PenaltyMissions = self:ReportDetailedPlayerMissions( PlayerName )
|
||||||
ReportMissions = ReportMissions ~= "" and "\n- " .. ReportMissions or ReportMissions
|
ReportMissions = ReportMissions ~= "" and "\n- " .. ReportMissions or ReportMissions
|
||||||
self:E( { ReportMissions, ScoreMissions, PenaltyMissions } )
|
self:F( { ReportMissions, ScoreMissions, PenaltyMissions } )
|
||||||
|
|
||||||
local PlayerScore = ScoreHits + ScoreDestroys + ScoreCoalitionChanges + ScoreGoals + ScoreMissions
|
local PlayerScore = ScoreHits + ScoreDestroys + ScoreCoalitionChanges + ScoreGoals + ScoreMissions
|
||||||
local PlayerPenalty = PenaltyHits + PenaltyDestroys + PenaltyCoalitionChanges + ScoreGoals + PenaltyMissions
|
local PlayerPenalty = PenaltyHits + PenaltyDestroys + PenaltyCoalitionChanges + ScoreGoals + PenaltyMissions
|
||||||
@@ -1546,23 +1656,23 @@ function SCORING:ReportScoreGroupDetailed( PlayerGroup )
|
|||||||
|
|
||||||
local ReportHits, ScoreHits, PenaltyHits = self:ReportDetailedPlayerHits( PlayerName )
|
local ReportHits, ScoreHits, PenaltyHits = self:ReportDetailedPlayerHits( PlayerName )
|
||||||
ReportHits = ReportHits ~= "" and "\n- " .. ReportHits or ReportHits
|
ReportHits = ReportHits ~= "" and "\n- " .. ReportHits or ReportHits
|
||||||
self:E( { ReportHits, ScoreHits, PenaltyHits } )
|
self:F( { ReportHits, ScoreHits, PenaltyHits } )
|
||||||
|
|
||||||
local ReportDestroys, ScoreDestroys, PenaltyDestroys = self:ReportDetailedPlayerDestroys( PlayerName )
|
local ReportDestroys, ScoreDestroys, PenaltyDestroys = self:ReportDetailedPlayerDestroys( PlayerName )
|
||||||
ReportDestroys = ReportDestroys ~= "" and "\n- " .. ReportDestroys or ReportDestroys
|
ReportDestroys = ReportDestroys ~= "" and "\n- " .. ReportDestroys or ReportDestroys
|
||||||
self:E( { ReportDestroys, ScoreDestroys, PenaltyDestroys } )
|
self:F( { ReportDestroys, ScoreDestroys, PenaltyDestroys } )
|
||||||
|
|
||||||
local ReportCoalitionChanges, ScoreCoalitionChanges, PenaltyCoalitionChanges = self:ReportDetailedPlayerCoalitionChanges( PlayerName )
|
local ReportCoalitionChanges, ScoreCoalitionChanges, PenaltyCoalitionChanges = self:ReportDetailedPlayerCoalitionChanges( PlayerName )
|
||||||
ReportCoalitionChanges = ReportCoalitionChanges ~= "" and "\n- " .. ReportCoalitionChanges or ReportCoalitionChanges
|
ReportCoalitionChanges = ReportCoalitionChanges ~= "" and "\n- " .. ReportCoalitionChanges or ReportCoalitionChanges
|
||||||
self:E( { ReportCoalitionChanges, ScoreCoalitionChanges, PenaltyCoalitionChanges } )
|
self:F( { ReportCoalitionChanges, ScoreCoalitionChanges, PenaltyCoalitionChanges } )
|
||||||
|
|
||||||
local ReportGoals, ScoreGoals, PenaltyGoals = self:ReportDetailedPlayerGoals( PlayerName )
|
local ReportGoals, ScoreGoals, PenaltyGoals = self:ReportDetailedPlayerGoals( PlayerName )
|
||||||
ReportGoals = ReportGoals ~= "" and "\n- " .. ReportGoals or ReportGoals
|
ReportGoals = ReportGoals ~= "" and "\n- " .. ReportGoals or ReportGoals
|
||||||
self:E( { ReportGoals, ScoreGoals, PenaltyGoals } )
|
self:F( { ReportGoals, ScoreGoals, PenaltyGoals } )
|
||||||
|
|
||||||
local ReportMissions, ScoreMissions, PenaltyMissions = self:ReportDetailedPlayerMissions( PlayerName )
|
local ReportMissions, ScoreMissions, PenaltyMissions = self:ReportDetailedPlayerMissions( PlayerName )
|
||||||
ReportMissions = ReportMissions ~= "" and "\n- " .. ReportMissions or ReportMissions
|
ReportMissions = ReportMissions ~= "" and "\n- " .. ReportMissions or ReportMissions
|
||||||
self:E( { ReportMissions, ScoreMissions, PenaltyMissions } )
|
self:F( { ReportMissions, ScoreMissions, PenaltyMissions } )
|
||||||
|
|
||||||
local PlayerScore = ScoreHits + ScoreDestroys + ScoreCoalitionChanges + ScoreGoals + ScoreMissions
|
local PlayerScore = ScoreHits + ScoreDestroys + ScoreCoalitionChanges + ScoreGoals + ScoreMissions
|
||||||
local PlayerPenalty = PenaltyHits + PenaltyDestroys + PenaltyCoalitionChanges + ScoreGoals + PenaltyMissions
|
local PlayerPenalty = PenaltyHits + PenaltyDestroys + PenaltyCoalitionChanges + ScoreGoals + PenaltyMissions
|
||||||
@@ -1592,31 +1702,33 @@ function SCORING:ReportScoreAllSummary( PlayerGroup )
|
|||||||
|
|
||||||
local PlayerMessage = ""
|
local PlayerMessage = ""
|
||||||
|
|
||||||
self:T( "Report Score All Players" )
|
self:T( { "Summary Score Report of All Players", Players = self.Players } )
|
||||||
|
|
||||||
for PlayerName, PlayerData in pairs( self.Players ) do
|
for PlayerName, PlayerData in pairs( self.Players ) do
|
||||||
|
|
||||||
|
self:T( { PlayerName = PlayerName, PlayerGroup = PlayerGroup } )
|
||||||
|
|
||||||
if PlayerName then
|
if PlayerName then
|
||||||
|
|
||||||
local ReportHits, ScoreHits, PenaltyHits = self:ReportDetailedPlayerHits( PlayerName )
|
local ReportHits, ScoreHits, PenaltyHits = self:ReportDetailedPlayerHits( PlayerName )
|
||||||
ReportHits = ReportHits ~= "" and "\n- " .. ReportHits or ReportHits
|
ReportHits = ReportHits ~= "" and "\n- " .. ReportHits or ReportHits
|
||||||
self:E( { ReportHits, ScoreHits, PenaltyHits } )
|
self:F( { ReportHits, ScoreHits, PenaltyHits } )
|
||||||
|
|
||||||
local ReportDestroys, ScoreDestroys, PenaltyDestroys = self:ReportDetailedPlayerDestroys( PlayerName )
|
local ReportDestroys, ScoreDestroys, PenaltyDestroys = self:ReportDetailedPlayerDestroys( PlayerName )
|
||||||
ReportDestroys = ReportDestroys ~= "" and "\n- " .. ReportDestroys or ReportDestroys
|
ReportDestroys = ReportDestroys ~= "" and "\n- " .. ReportDestroys or ReportDestroys
|
||||||
self:E( { ReportDestroys, ScoreDestroys, PenaltyDestroys } )
|
self:F( { ReportDestroys, ScoreDestroys, PenaltyDestroys } )
|
||||||
|
|
||||||
local ReportCoalitionChanges, ScoreCoalitionChanges, PenaltyCoalitionChanges = self:ReportDetailedPlayerCoalitionChanges( PlayerName )
|
local ReportCoalitionChanges, ScoreCoalitionChanges, PenaltyCoalitionChanges = self:ReportDetailedPlayerCoalitionChanges( PlayerName )
|
||||||
ReportCoalitionChanges = ReportCoalitionChanges ~= "" and "\n- " .. ReportCoalitionChanges or ReportCoalitionChanges
|
ReportCoalitionChanges = ReportCoalitionChanges ~= "" and "\n- " .. ReportCoalitionChanges or ReportCoalitionChanges
|
||||||
self:E( { ReportCoalitionChanges, ScoreCoalitionChanges, PenaltyCoalitionChanges } )
|
self:F( { ReportCoalitionChanges, ScoreCoalitionChanges, PenaltyCoalitionChanges } )
|
||||||
|
|
||||||
local ReportGoals, ScoreGoals, PenaltyGoals = self:ReportDetailedPlayerGoals( PlayerName )
|
local ReportGoals, ScoreGoals, PenaltyGoals = self:ReportDetailedPlayerGoals( PlayerName )
|
||||||
ReportGoals = ReportGoals ~= "" and "\n- " .. ReportGoals or ReportGoals
|
ReportGoals = ReportGoals ~= "" and "\n- " .. ReportGoals or ReportGoals
|
||||||
self:E( { ReportGoals, ScoreGoals, PenaltyGoals } )
|
self:F( { ReportGoals, ScoreGoals, PenaltyGoals } )
|
||||||
|
|
||||||
local ReportMissions, ScoreMissions, PenaltyMissions = self:ReportDetailedPlayerMissions( PlayerName )
|
local ReportMissions, ScoreMissions, PenaltyMissions = self:ReportDetailedPlayerMissions( PlayerName )
|
||||||
ReportMissions = ReportMissions ~= "" and "\n- " .. ReportMissions or ReportMissions
|
ReportMissions = ReportMissions ~= "" and "\n- " .. ReportMissions or ReportMissions
|
||||||
self:E( { ReportMissions, ScoreMissions, PenaltyMissions } )
|
self:F( { ReportMissions, ScoreMissions, PenaltyMissions } )
|
||||||
|
|
||||||
local PlayerScore = ScoreHits + ScoreDestroys + ScoreCoalitionChanges + ScoreGoals + ScoreMissions
|
local PlayerScore = ScoreHits + ScoreDestroys + ScoreCoalitionChanges + ScoreGoals + ScoreMissions
|
||||||
local PlayerPenalty = PenaltyHits + PenaltyDestroys + PenaltyCoalitionChanges + ScoreGoals + PenaltyMissions
|
local PlayerPenalty = PenaltyHits + PenaltyDestroys + PenaltyCoalitionChanges + ScoreGoals + PenaltyMissions
|
||||||
@@ -1676,7 +1788,7 @@ function SCORING:OpenCSV( ScoringCSV )
|
|||||||
error( "A string containing the CSV file name must be given." )
|
error( "A string containing the CSV file name must be given." )
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
self:E( "The MissionScripting.lua file has not been changed to allow lfs, io and os modules to be used..." )
|
self:F( "The MissionScripting.lua file has not been changed to allow lfs, io and os modules to be used..." )
|
||||||
end
|
end
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
--- **Functional** -- Provides defensive behaviour to a set of SAM sites within a running Mission.
|
--- **Functional** -- Provides defensive behaviour to a set of SAM sites within a running Mission.
|
||||||
--
|
--
|
||||||
-- ====
|
-- ===
|
||||||
--
|
--
|
||||||
-- @module Sead
|
-- @module Sead
|
||||||
|
|
||||||
|
|||||||
763
Moose Development/Moose/Functional/ZoneCaptureCoalition.lua
Normal file
763
Moose Development/Moose/Functional/ZoneCaptureCoalition.lua
Normal file
@@ -0,0 +1,763 @@
|
|||||||
|
--- **Functional** -- (R2.3) Models the process to zone guarding and capturing.
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- ### [Demo Missions](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/CAZ - Capture Zones)
|
||||||
|
--
|
||||||
|
-- - CAZ-000 - Capture Zone: Demonstrates the basic concept of capturing a zone.
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- ### [YouTube Playlist](https://www.youtube.com/watch?v=0m6K6Yxa-os&list=PL7ZUrU4zZUl0qqJsfa8DPvZWDY-OyDumE)
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- ### Author: **FlightControl**
|
||||||
|
-- ### Contributions: **Millertime** - Concept
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- @module ZoneCaptureCoalition
|
||||||
|
|
||||||
|
do -- ZONE_CAPTURE_COALITION
|
||||||
|
|
||||||
|
--- @type ZONE_CAPTURE_COALITION
|
||||||
|
-- @extends Functional.ZoneGoalCoalition#ZONE_GOAL_COALITION
|
||||||
|
|
||||||
|
|
||||||
|
--- # ZONE\_CAPTURE\_COALITION class, extends @{ZoneGoalCoalition#ZONE_GOAL_COALITION}
|
||||||
|
--
|
||||||
|
-- Models the process to capture a Zone for a Coalition, which is guarded by another Coalition.
|
||||||
|
-- This is a powerful concept that allows to create very dynamic missions based on the different state transitions of various zones.
|
||||||
|
--
|
||||||
|
-- ---
|
||||||
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
|
-- ---
|
||||||
|
--
|
||||||
|
-- # 0. Player Experience
|
||||||
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
|
-- The above models the possible state transitions between the **Guarded**, **Attacked**, **Empty** and **Captured** states.
|
||||||
|
-- A zone has an __owning coalition__, that means that at a specific point in time, a zone can be owned by the red or blue coalition.
|
||||||
|
--
|
||||||
|
-- The Zone can be in the state **Guarded** by the __owning coalition__, which is the coalition that initially occupies the zone with units of its coalition.
|
||||||
|
-- Once units of an other coalition are entering the Zone, the state will change to **Attacked**. As long as these units remain in the zone, the state keeps set to Attacked.
|
||||||
|
-- When all units are destroyed in the Zone, the state will change to **Empty**, which expresses that the Zone is empty, and can be captured.
|
||||||
|
-- When units of the other coalition are in the Zone, and no other units of the owning coalition is in the Zone, the Zone is captured, and its state will change to **Captured**.
|
||||||
|
--
|
||||||
|
-- The zone needs to be monitored regularly for the presence of units to interprete the correct state transition required.
|
||||||
|
-- This monitoring process MUST be started using the @{#ZONE_CAPTURE_COALITION.Start}() method.
|
||||||
|
-- Otherwise no monitoring will be active and the zone will stay in the current state forever.
|
||||||
|
-- See further in chapter 3.3 for more information about this.
|
||||||
|
--
|
||||||
|
-- ## 1. ZONE\_CAPTURE\_COALITION constructor
|
||||||
|
--
|
||||||
|
-- * @{#ZONE_CAPTURE_COALITION.New}(): Creates a new ZONE\_CAPTURE\_COALITION object.
|
||||||
|
--
|
||||||
|
-- In order to use ZONE\_CAPTURE\_COALITION, you need to:
|
||||||
|
--
|
||||||
|
-- - Create a @{Zone} object from one of the ZONE\_ classes. Note that ZONE\_POLYGON\_ classes are not yet functional. The only functional ZONE\_ classses are those derived from a ZONE\_RADIUS.
|
||||||
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
|
-- Ensure that during the life cycle of the ZONE\_CAPTURE\_COALITION object, the object keeps alive.
|
||||||
|
-- It is best to declare the object globally within your script.
|
||||||
|
--
|
||||||
|
-- ## 2. ZONE\_CAPTURE\_COALITION is a finite state machine (FSM).
|
||||||
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
|
-- ### 2.1 ZONE\_CAPTURE\_COALITION States
|
||||||
|
--
|
||||||
|
-- * **Captured**: The Zone has been captured by an other coalition.
|
||||||
|
-- * **Attacked**: The Zone is currently intruded by an other coalition. There are units of the owning coalition and an other coalition in the Zone.
|
||||||
|
-- * **Guarded**: The Zone is guarded by the owning coalition. There is no other unit of an other coalition in the Zone.
|
||||||
|
-- * **Empty**: The Zone is empty. There is not valid unit in the Zone.
|
||||||
|
--
|
||||||
|
-- ### 2.2 ZONE\_CAPTURE\_COALITION Events
|
||||||
|
--
|
||||||
|
-- * **Capture**: The Zone has been captured by an other coalition.
|
||||||
|
-- * **Attack**: The Zone is currently intruded by an other coalition. There are units of the owning coalition and an other coalition in the Zone.
|
||||||
|
-- * **Guard**: The Zone is guarded by the owning coalition. There is no other unit of an other coalition in the Zone.
|
||||||
|
-- * **Empty**: The Zone is empty. There is not valid unit in the Zone.
|
||||||
|
--
|
||||||
|
-- ## 3. "Script It"
|
||||||
|
--
|
||||||
|
-- ZONE\_CAPTURE\_COALITION allows to take action on the various state transitions and add your custom code and logic.
|
||||||
|
--
|
||||||
|
-- ### 3.1. Take action using state- and event handlers.
|
||||||
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
|
-- The most important to understand is how states and events can be tailored.
|
||||||
|
-- Carefully study the diagram and the explanations.
|
||||||
|
--
|
||||||
|
-- **State Handlers** capture the moment:
|
||||||
|
--
|
||||||
|
-- - On Leave from the old state. Return false to cancel the transition.
|
||||||
|
-- - On Enter to the new state.
|
||||||
|
--
|
||||||
|
-- **Event Handlers** capture the moment:
|
||||||
|
--
|
||||||
|
-- - On Before the event is triggered. Return false to cancel the transition.
|
||||||
|
-- - On After the event is triggered.
|
||||||
|
--
|
||||||
|
--
|
||||||
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
|
-- Each handler can receive optionally 3 parameters:
|
||||||
|
--
|
||||||
|
-- - **From**: A string containing the From State.
|
||||||
|
-- - **Event**: A string containing the Event.
|
||||||
|
-- - **To**: A string containing the To State.
|
||||||
|
--
|
||||||
|
-- The mission designer can use these values to alter the logic.
|
||||||
|
-- For example:
|
||||||
|
--
|
||||||
|
-- --- @param Functional.ZoneCaptureCoalition#ZONE_CAPTURE_COALITION self
|
||||||
|
-- function ZoneCaptureCoalition:OnEnterGuarded( From, Event, To )
|
||||||
|
-- if From ~= "Empty" then
|
||||||
|
-- -- Display a message
|
||||||
|
-- end
|
||||||
|
-- end
|
||||||
|
--
|
||||||
|
-- This code checks that when the __Guarded__ state has been reached, that if the **From** state was __Empty__, then display a message.
|
||||||
|
--
|
||||||
|
-- ### 3.2. Example Event Handler.
|
||||||
|
--
|
||||||
|
-- --- @param Functional.ZoneCaptureCoalition#ZONE_CAPTURE_COALITION self
|
||||||
|
-- function ZoneCaptureCoalition:OnEnterGuarded( From, Event, To )
|
||||||
|
-- if From ~= To then
|
||||||
|
-- local Coalition = self:GetCoalition()
|
||||||
|
-- self:E( { Coalition = Coalition } )
|
||||||
|
-- if Coalition == coalition.side.BLUE then
|
||||||
|
-- ZoneCaptureCoalition:Smoke( SMOKECOLOR.Blue )
|
||||||
|
-- US_CC:MessageTypeToCoalition( string.format( "%s is under protection of the USA", ZoneCaptureCoalition:GetZoneName() ), MESSAGE.Type.Information )
|
||||||
|
-- RU_CC:MessageTypeToCoalition( string.format( "%s is under protection of the USA", ZoneCaptureCoalition:GetZoneName() ), MESSAGE.Type.Information )
|
||||||
|
-- else
|
||||||
|
-- ZoneCaptureCoalition:Smoke( SMOKECOLOR.Red )
|
||||||
|
-- RU_CC:MessageTypeToCoalition( string.format( "%s is under protection of Russia", ZoneCaptureCoalition:GetZoneName() ), MESSAGE.Type.Information )
|
||||||
|
-- US_CC:MessageTypeToCoalition( string.format( "%s is under protection of Russia", ZoneCaptureCoalition:GetZoneName() ), MESSAGE.Type.Information )
|
||||||
|
-- end
|
||||||
|
-- end
|
||||||
|
-- end
|
||||||
|
--
|
||||||
|
-- ### 3.3. Stop and Start the zone monitoring process.
|
||||||
|
--
|
||||||
|
-- At regular intervals, the state of the zone needs to be monitored.
|
||||||
|
-- The zone needs to be scanned for the presence of units within the zone boundaries.
|
||||||
|
-- Depending on the owning coalition of the zone and the presence of units (of the owning and/or other coalition(s)), the zone will transition to another state.
|
||||||
|
--
|
||||||
|
-- However, ... this scanning process is rather CPU intensive. Imagine you have 10 of these capture zone objects setup within your mission.
|
||||||
|
-- That would mean that your mission would check 10 capture zones simultaneously, each checking for the presence of units.
|
||||||
|
-- It would be highly **CPU inefficient**, as some of these zones are not required to be monitored (yet).
|
||||||
|
--
|
||||||
|
-- Therefore, the mission designer is given 2 methods that allow to take control of the CPU utilization efficiency:
|
||||||
|
--
|
||||||
|
-- - @{#ZONE_CAPTURE_COALITION.Start()}(): This starts the monitoring process.
|
||||||
|
-- - @{#ZONE_CAPTURE_COALITION.Stop()}(): This stops the monitoring process.
|
||||||
|
--
|
||||||
|
-- ### IMPORTANT
|
||||||
|
--
|
||||||
|
-- **Each capture zone object must have the monitoring process started specifically.
|
||||||
|
-- The monitoring process is NOT started by default!!!**
|
||||||
|
--
|
||||||
|
--
|
||||||
|
-- ## 4. Full Example
|
||||||
|
--
|
||||||
|
-- The following annotated code shows a real example of how ZONE\_CAPTURE\_COALITION can be applied.
|
||||||
|
--
|
||||||
|
-- The concept is simple.
|
||||||
|
--
|
||||||
|
-- The USA (US), blue coalition, needs to capture the Russian (RU), red coalition, zone, which is near groom lake.
|
||||||
|
--
|
||||||
|
-- A capture zone has been setup that guards the presence of the troops.
|
||||||
|
-- Troops are guarded by red forces. Blue is required to destroy the red forces and capture the zones.
|
||||||
|
--
|
||||||
|
-- At first, we setup the Command Centers
|
||||||
|
--
|
||||||
|
-- do
|
||||||
|
--
|
||||||
|
-- RU_CC = COMMANDCENTER:New( GROUP:FindByName( "REDHQ" ), "Russia HQ" )
|
||||||
|
-- US_CC = COMMANDCENTER:New( GROUP:FindByName( "BLUEHQ" ), "USA HQ" )
|
||||||
|
--
|
||||||
|
-- end
|
||||||
|
--
|
||||||
|
-- Next, we define the mission, and add some scoring to it.
|
||||||
|
--
|
||||||
|
-- do -- Missions
|
||||||
|
--
|
||||||
|
-- US_Mission_EchoBay = MISSION:New( US_CC, "Echo Bay", "Primary",
|
||||||
|
-- "Welcome trainee. The airport Groom Lake in Echo Bay needs to be captured.\n" ..
|
||||||
|
-- "There are five random capture zones located at the airbase.\n" ..
|
||||||
|
-- "Move to one of the capture zones, destroy the fuel tanks in the capture zone, " ..
|
||||||
|
-- "and occupy each capture zone with a platoon.\n " ..
|
||||||
|
-- "Your orders are to hold position until all capture zones are taken.\n" ..
|
||||||
|
-- "Use the map (F10) for a clear indication of the location of each capture zone.\n" ..
|
||||||
|
-- "Note that heavy resistance can be expected at the airbase!\n" ..
|
||||||
|
-- "Mission 'Echo Bay' is complete when all five capture zones are taken, and held for at least 5 minutes!"
|
||||||
|
-- , coalition.side.RED )
|
||||||
|
--
|
||||||
|
-- US_Mission_EchoBay:Start()
|
||||||
|
--
|
||||||
|
-- end
|
||||||
|
--
|
||||||
|
--
|
||||||
|
-- Now the real work starts.
|
||||||
|
-- We define a **CaptureZone** object, which is a ZONE object.
|
||||||
|
-- Within the mission, a trigger zone is created with the name __CaptureZone__, with the defined radius within the mission editor.
|
||||||
|
--
|
||||||
|
-- CaptureZone = ZONE:New( "CaptureZone" )
|
||||||
|
--
|
||||||
|
-- Next, we define the **ZoneCaptureCoalition** object, as explained above.
|
||||||
|
--
|
||||||
|
-- ZoneCaptureCoalition = ZONE_CAPTURE_COALITION:New( CaptureZone, coalition.side.RED )
|
||||||
|
--
|
||||||
|
-- Of course, we want to let the **ZoneCaptureCoalition** object do something when the state transitions.
|
||||||
|
-- Do accomodate this, it is very simple, as explained above.
|
||||||
|
-- We use **Event Handlers** to tailor the logic.
|
||||||
|
--
|
||||||
|
-- Here we place an Event Handler at the Guarded event. So when the **Guarded** event is triggered, then this method is called!
|
||||||
|
-- With the variables **From**, **Event**, **To**. Each of these variables containing a string.
|
||||||
|
--
|
||||||
|
-- We check if the previous state wasn't Guarded also.
|
||||||
|
-- If not, we retrieve the owning Coalition of the **ZoneCaptureCoalition**, using `self:GetCoalition()`.
|
||||||
|
-- So **Coalition** will contain the current owning coalition of the zone.
|
||||||
|
--
|
||||||
|
-- Depending on the zone ownership, different messages are sent.
|
||||||
|
-- Note the methods `ZoneCaptureCoalition:GetZoneName()`.
|
||||||
|
--
|
||||||
|
-- --- @param Functional.ZoneCaptureCoalition#ZONE_CAPTURE_COALITION self
|
||||||
|
-- function ZoneCaptureCoalition:OnEnterGuarded( From, Event, To )
|
||||||
|
-- if From ~= To then
|
||||||
|
-- local Coalition = self:GetCoalition()
|
||||||
|
-- self:E( { Coalition = Coalition } )
|
||||||
|
-- if Coalition == coalition.side.BLUE then
|
||||||
|
-- ZoneCaptureCoalition:Smoke( SMOKECOLOR.Blue )
|
||||||
|
-- US_CC:MessageTypeToCoalition( string.format( "%s is under protection of the USA", ZoneCaptureCoalition:GetZoneName() ), MESSAGE.Type.Information )
|
||||||
|
-- RU_CC:MessageTypeToCoalition( string.format( "%s is under protection of the USA", ZoneCaptureCoalition:GetZoneName() ), MESSAGE.Type.Information )
|
||||||
|
-- else
|
||||||
|
-- ZoneCaptureCoalition:Smoke( SMOKECOLOR.Red )
|
||||||
|
-- RU_CC:MessageTypeToCoalition( string.format( "%s is under protection of Russia", ZoneCaptureCoalition:GetZoneName() ), MESSAGE.Type.Information )
|
||||||
|
-- US_CC:MessageTypeToCoalition( string.format( "%s is under protection of Russia", ZoneCaptureCoalition:GetZoneName() ), MESSAGE.Type.Information )
|
||||||
|
-- end
|
||||||
|
-- end
|
||||||
|
-- end
|
||||||
|
--
|
||||||
|
-- As you can see, not a rocket science.
|
||||||
|
-- Next is the Event Handler when the **Empty** state transition is triggered.
|
||||||
|
-- Now we smoke the ZoneCaptureCoalition with a green color, using `self:Smoke( SMOKECOLOR.Green )`.
|
||||||
|
--
|
||||||
|
-- --- @param Functional.Protect#ZONE_CAPTURE_COALITION self
|
||||||
|
-- function ZoneCaptureCoalition:OnEnterEmpty()
|
||||||
|
-- self:Smoke( SMOKECOLOR.Green )
|
||||||
|
-- US_CC:MessageTypeToCoalition( string.format( "%s is unprotected, and can be captured!", ZoneCaptureCoalition:GetZoneName() ), MESSAGE.Type.Information )
|
||||||
|
-- RU_CC:MessageTypeToCoalition( string.format( "%s is unprotected, and can be captured!", ZoneCaptureCoalition:GetZoneName() ), MESSAGE.Type.Information )
|
||||||
|
-- end
|
||||||
|
--
|
||||||
|
-- The next Event Handlers speak for itself.
|
||||||
|
-- When the zone is Attacked, we smoke the zone white and send some messages to each coalition.
|
||||||
|
--
|
||||||
|
-- --- @param Functional.Protect#ZONE_CAPTURE_COALITION self
|
||||||
|
-- function ZoneCaptureCoalition:OnEnterAttacked()
|
||||||
|
-- ZoneCaptureCoalition:Smoke( SMOKECOLOR.White )
|
||||||
|
-- local Coalition = self:GetCoalition()
|
||||||
|
-- self:E({Coalition = Coalition})
|
||||||
|
-- if Coalition == coalition.side.BLUE then
|
||||||
|
-- US_CC:MessageTypeToCoalition( string.format( "%s is under attack by Russia", ZoneCaptureCoalition:GetZoneName() ), MESSAGE.Type.Information )
|
||||||
|
-- RU_CC:MessageTypeToCoalition( string.format( "We are attacking %s", ZoneCaptureCoalition:GetZoneName() ), MESSAGE.Type.Information )
|
||||||
|
-- else
|
||||||
|
-- RU_CC:MessageTypeToCoalition( string.format( "%s is under attack by the USA", ZoneCaptureCoalition:GetZoneName() ), MESSAGE.Type.Information )
|
||||||
|
-- US_CC:MessageTypeToCoalition( string.format( "We are attacking %s", ZoneCaptureCoalition:GetZoneName() ), MESSAGE.Type.Information )
|
||||||
|
-- end
|
||||||
|
-- end
|
||||||
|
--
|
||||||
|
-- When the zone is Captured, we send some victory or loss messages to the correct coalition.
|
||||||
|
-- And we add some score.
|
||||||
|
--
|
||||||
|
-- --- @param Functional.Protect#ZONE_CAPTURE_COALITION self
|
||||||
|
-- function ZoneCaptureCoalition:OnEnterCaptured()
|
||||||
|
-- local Coalition = self:GetCoalition()
|
||||||
|
-- self:E({Coalition = Coalition})
|
||||||
|
-- if Coalition == coalition.side.BLUE then
|
||||||
|
-- RU_CC:MessageTypeToCoalition( string.format( "%s is captured by the USA, we lost it!", ZoneCaptureCoalition:GetZoneName() ), MESSAGE.Type.Information )
|
||||||
|
-- US_CC:MessageTypeToCoalition( string.format( "We captured %s, Excellent job!", ZoneCaptureCoalition:GetZoneName() ), MESSAGE.Type.Information )
|
||||||
|
-- else
|
||||||
|
-- US_CC:MessageTypeToCoalition( string.format( "%s is captured by Russia, we lost it!", ZoneCaptureCoalition:GetZoneName() ), MESSAGE.Type.Information )
|
||||||
|
-- RU_CC:MessageTypeToCoalition( string.format( "We captured %s, Excellent job!", ZoneCaptureCoalition:GetZoneName() ), MESSAGE.Type.Information )
|
||||||
|
-- end
|
||||||
|
--
|
||||||
|
-- self:__Guard( 30 )
|
||||||
|
-- end
|
||||||
|
--
|
||||||
|
-- And this call is the most important of all!
|
||||||
|
-- In the context of the mission, we need to start the zone capture monitoring process.
|
||||||
|
-- Or nothing will be monitored and the zone won't change states.
|
||||||
|
-- We start the monitoring after 5 seconds, and will repeat every 30 seconds a check.
|
||||||
|
--
|
||||||
|
-- ZoneCaptureCoalition:Start( 5, 30 )
|
||||||
|
--
|
||||||
|
--
|
||||||
|
-- @field #ZONE_CAPTURE_COALITION
|
||||||
|
ZONE_CAPTURE_COALITION = {
|
||||||
|
ClassName = "ZONE_CAPTURE_COALITION",
|
||||||
|
}
|
||||||
|
|
||||||
|
--- @field #table ZONE_CAPTURE_COALITION.States
|
||||||
|
ZONE_CAPTURE_COALITION.States = {}
|
||||||
|
|
||||||
|
--- ZONE_CAPTURE_COALITION Constructor.
|
||||||
|
-- @param #ZONE_CAPTURE_COALITION self
|
||||||
|
-- @param Core.Zone#ZONE Zone A @{Zone} object with the goal to be achieved.
|
||||||
|
-- @param DCSCoalition.DCSCoalition#coalition Coalition The initial coalition owning the zone.
|
||||||
|
-- @return #ZONE_CAPTURE_COALITION
|
||||||
|
-- @usage
|
||||||
|
--
|
||||||
|
-- AttackZone = ZONE:New( "AttackZone" )
|
||||||
|
--
|
||||||
|
-- ZoneCaptureCoalition = ZONE_CAPTURE_COALITION:New( AttackZone, coalition.side.RED ) -- Create a new ZONE_CAPTURE_COALITION object of zone AttackZone with ownership RED coalition.
|
||||||
|
-- ZoneCaptureCoalition:__Guard( 1 ) -- Start the Guarding of the AttackZone.
|
||||||
|
--
|
||||||
|
function ZONE_CAPTURE_COALITION:New( Zone, Coalition )
|
||||||
|
|
||||||
|
local self = BASE:Inherit( self, ZONE_GOAL_COALITION:New( Zone, Coalition ) ) -- #ZONE_CAPTURE_COALITION
|
||||||
|
|
||||||
|
self:F( { Zone = Zone, Coalition = Coalition } )
|
||||||
|
|
||||||
|
do
|
||||||
|
|
||||||
|
--- Captured State Handler OnLeave for ZONE\_CAPTURE\_COALITION
|
||||||
|
-- @function [parent=#ZONE_CAPTURE_COALITION] OnLeaveCaptured
|
||||||
|
-- @param #ZONE_CAPTURE_COALITION self
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string To
|
||||||
|
-- @return #boolean
|
||||||
|
|
||||||
|
--- Captured State Handler OnEnter for ZONE\_CAPTURE\_COALITION
|
||||||
|
-- @function [parent=#ZONE_CAPTURE_COALITION] OnEnterCaptured
|
||||||
|
-- @param #ZONE_CAPTURE_COALITION self
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string To
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
do
|
||||||
|
|
||||||
|
--- Attacked State Handler OnLeave for ZONE\_CAPTURE\_COALITION
|
||||||
|
-- @function [parent=#ZONE_CAPTURE_COALITION] OnLeaveAttacked
|
||||||
|
-- @param #ZONE_CAPTURE_COALITION self
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string To
|
||||||
|
-- @return #boolean
|
||||||
|
|
||||||
|
--- Attacked State Handler OnEnter for ZONE\_CAPTURE\_COALITION
|
||||||
|
-- @function [parent=#ZONE_CAPTURE_COALITION] OnEnterAttacked
|
||||||
|
-- @param #ZONE_CAPTURE_COALITION self
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string To
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
|
||||||
|
--- Guarded State Handler OnLeave for ZONE\_CAPTURE\_COALITION
|
||||||
|
-- @function [parent=#ZONE_CAPTURE_COALITION] OnLeaveGuarded
|
||||||
|
-- @param #ZONE_CAPTURE_COALITION self
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string To
|
||||||
|
-- @return #boolean
|
||||||
|
|
||||||
|
--- Guarded State Handler OnEnter for ZONE\_CAPTURE\_COALITION
|
||||||
|
-- @function [parent=#ZONE_CAPTURE_COALITION] OnEnterGuarded
|
||||||
|
-- @param #ZONE_CAPTURE_COALITION self
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string To
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
do
|
||||||
|
|
||||||
|
--- Empty State Handler OnLeave for ZONE\_CAPTURE\_COALITION
|
||||||
|
-- @function [parent=#ZONE_CAPTURE_COALITION] OnLeaveEmpty
|
||||||
|
-- @param #ZONE_CAPTURE_COALITION self
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string To
|
||||||
|
-- @return #boolean
|
||||||
|
|
||||||
|
--- Empty State Handler OnEnter for ZONE\_CAPTURE\_COALITION
|
||||||
|
-- @function [parent=#ZONE_CAPTURE_COALITION] OnEnterEmpty
|
||||||
|
-- @param #ZONE_CAPTURE_COALITION self
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string To
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
self:AddTransition( "*", "Guard", "Guarded" )
|
||||||
|
|
||||||
|
--- Guard Handler OnBefore for ZONE\_CAPTURE\_COALITION
|
||||||
|
-- @function [parent=#ZONE_CAPTURE_COALITION] OnBeforeGuard
|
||||||
|
-- @param #ZONE_CAPTURE_COALITION self
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string To
|
||||||
|
-- @return #boolean
|
||||||
|
|
||||||
|
--- Guard Handler OnAfter for ZONE\_CAPTURE\_COALITION
|
||||||
|
-- @function [parent=#ZONE_CAPTURE_COALITION] OnAfterGuard
|
||||||
|
-- @param #ZONE_CAPTURE_COALITION self
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string To
|
||||||
|
|
||||||
|
--- Guard Trigger for ZONE\_CAPTURE\_COALITION
|
||||||
|
-- @function [parent=#ZONE_CAPTURE_COALITION] Guard
|
||||||
|
-- @param #ZONE_CAPTURE_COALITION self
|
||||||
|
|
||||||
|
--- Guard Asynchronous Trigger for ZONE\_CAPTURE\_COALITION
|
||||||
|
-- @function [parent=#ZONE_CAPTURE_COALITION] __Guard
|
||||||
|
-- @param #ZONE_CAPTURE_COALITION self
|
||||||
|
-- @param #number Delay
|
||||||
|
|
||||||
|
self:AddTransition( "*", "Empty", "Empty" )
|
||||||
|
|
||||||
|
--- Empty Handler OnBefore for ZONE\_CAPTURE\_COALITION
|
||||||
|
-- @function [parent=#ZONE_CAPTURE_COALITION] OnBeforeEmpty
|
||||||
|
-- @param #ZONE_CAPTURE_COALITION self
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string To
|
||||||
|
-- @return #boolean
|
||||||
|
|
||||||
|
--- Empty Handler OnAfter for ZONE\_CAPTURE\_COALITION
|
||||||
|
-- @function [parent=#ZONE_CAPTURE_COALITION] OnAfterEmpty
|
||||||
|
-- @param #ZONE_CAPTURE_COALITION self
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string To
|
||||||
|
|
||||||
|
--- Empty Trigger for ZONE\_CAPTURE\_COALITION
|
||||||
|
-- @function [parent=#ZONE_CAPTURE_COALITION] Empty
|
||||||
|
-- @param #ZONE_CAPTURE_COALITION self
|
||||||
|
|
||||||
|
--- Empty Asynchronous Trigger for ZONE\_CAPTURE\_COALITION
|
||||||
|
-- @function [parent=#ZONE_CAPTURE_COALITION] __Empty
|
||||||
|
-- @param #ZONE_CAPTURE_COALITION self
|
||||||
|
-- @param #number Delay
|
||||||
|
|
||||||
|
|
||||||
|
self:AddTransition( { "Guarded", "Empty" }, "Attack", "Attacked" )
|
||||||
|
|
||||||
|
--- Attack Handler OnBefore for ZONE\_CAPTURE\_COALITION
|
||||||
|
-- @function [parent=#ZONE_CAPTURE_COALITION] OnBeforeAttack
|
||||||
|
-- @param #ZONE_CAPTURE_COALITION self
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string To
|
||||||
|
-- @return #boolean
|
||||||
|
|
||||||
|
--- Attack Handler OnAfter for ZONE\_CAPTURE\_COALITION
|
||||||
|
-- @function [parent=#ZONE_CAPTURE_COALITION] OnAfterAttack
|
||||||
|
-- @param #ZONE_CAPTURE_COALITION self
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string To
|
||||||
|
|
||||||
|
--- Attack Trigger for ZONE\_CAPTURE\_COALITION
|
||||||
|
-- @function [parent=#ZONE_CAPTURE_COALITION] Attack
|
||||||
|
-- @param #ZONE_CAPTURE_COALITION self
|
||||||
|
|
||||||
|
--- Attack Asynchronous Trigger for ZONE\_CAPTURE\_COALITION
|
||||||
|
-- @function [parent=#ZONE_CAPTURE_COALITION] __Attack
|
||||||
|
-- @param #ZONE_CAPTURE_COALITION self
|
||||||
|
-- @param #number Delay
|
||||||
|
|
||||||
|
self:AddTransition( { "Guarded", "Attacked", "Empty" }, "Capture", "Captured" )
|
||||||
|
|
||||||
|
--- Capture Handler OnBefore for ZONE\_CAPTURE\_COALITION
|
||||||
|
-- @function [parent=#ZONE_CAPTURE_COALITION] OnBeforeCapture
|
||||||
|
-- @param #ZONE_CAPTURE_COALITION self
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string To
|
||||||
|
-- @return #boolean
|
||||||
|
|
||||||
|
--- Capture Handler OnAfter for ZONE\_CAPTURE\_COALITION
|
||||||
|
-- @function [parent=#ZONE_CAPTURE_COALITION] OnAfterCapture
|
||||||
|
-- @param #ZONE_CAPTURE_COALITION self
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string To
|
||||||
|
|
||||||
|
--- Capture Trigger for ZONE\_CAPTURE\_COALITION
|
||||||
|
-- @function [parent=#ZONE_CAPTURE_COALITION] Capture
|
||||||
|
-- @param #ZONE_CAPTURE_COALITION self
|
||||||
|
|
||||||
|
--- Capture Asynchronous Trigger for ZONE\_CAPTURE\_COALITION
|
||||||
|
-- @function [parent=#ZONE_CAPTURE_COALITION] __Capture
|
||||||
|
-- @param #ZONE_CAPTURE_COALITION self
|
||||||
|
-- @param #number Delay
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- @param #ZONE_CAPTURE_COALITION self
|
||||||
|
function ZONE_CAPTURE_COALITION:onenterCaptured()
|
||||||
|
|
||||||
|
self:GetParent( self, ZONE_CAPTURE_COALITION ).onenterCaptured( self )
|
||||||
|
|
||||||
|
self.Goal:Achieved()
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function ZONE_CAPTURE_COALITION:IsGuarded()
|
||||||
|
|
||||||
|
local IsGuarded = self.Zone:IsAllInZoneOfCoalition( self.Coalition )
|
||||||
|
self:F( { IsGuarded = IsGuarded } )
|
||||||
|
return IsGuarded
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function ZONE_CAPTURE_COALITION:IsEmpty()
|
||||||
|
|
||||||
|
local IsEmpty = self.Zone:IsNoneInZone()
|
||||||
|
self:F( { IsEmpty = IsEmpty } )
|
||||||
|
return IsEmpty
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function ZONE_CAPTURE_COALITION:IsCaptured()
|
||||||
|
|
||||||
|
local IsCaptured = self.Zone:IsAllInZoneOfOtherCoalition( self.Coalition )
|
||||||
|
self:F( { IsCaptured = IsCaptured } )
|
||||||
|
return IsCaptured
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function ZONE_CAPTURE_COALITION:IsAttacked()
|
||||||
|
|
||||||
|
local IsAttacked = self.Zone:IsSomeInZoneOfCoalition( self.Coalition )
|
||||||
|
self:F( { IsAttacked = IsAttacked } )
|
||||||
|
return IsAttacked
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--- Mark.
|
||||||
|
-- @param #ZONE_CAPTURE_COALITION self
|
||||||
|
function ZONE_CAPTURE_COALITION:Mark()
|
||||||
|
|
||||||
|
local Coord = self.Zone:GetCoordinate()
|
||||||
|
local ZoneName = self:GetZoneName()
|
||||||
|
local State = self:GetState()
|
||||||
|
|
||||||
|
if self.MarkRed and self.MarkBlue then
|
||||||
|
self:F( { MarkRed = self.MarkRed, MarkBlue = self.MarkBlue } )
|
||||||
|
Coord:RemoveMark( self.MarkRed )
|
||||||
|
Coord:RemoveMark( self.MarkBlue )
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.Coalition == coalition.side.BLUE then
|
||||||
|
self.MarkBlue = Coord:MarkToCoalitionBlue( "Coalition: Blue\nGuard Zone: " .. ZoneName .. "\nStatus: " .. State )
|
||||||
|
self.MarkRed = Coord:MarkToCoalitionRed( "Coalition: Blue\nCapture Zone: " .. ZoneName .. "\nStatus: " .. State )
|
||||||
|
else
|
||||||
|
self.MarkRed = Coord:MarkToCoalitionRed( "Coalition: Red\nGuard Zone: " .. ZoneName .. "\nStatus: " .. State )
|
||||||
|
self.MarkBlue = Coord:MarkToCoalitionBlue( "Coalition: Red\nCapture Zone: " .. ZoneName .. "\nStatus: " .. State )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Bound.
|
||||||
|
-- @param #ZONE_CAPTURE_COALITION self
|
||||||
|
function ZONE_CAPTURE_COALITION:onenterGuarded()
|
||||||
|
|
||||||
|
--self:GetParent( self ):onenterGuarded()
|
||||||
|
|
||||||
|
if self.Coalition == coalition.side.BLUE then
|
||||||
|
--elf.ProtectZone:BoundZone( 12, country.id.USA )
|
||||||
|
else
|
||||||
|
--self.ProtectZone:BoundZone( 12, country.id.RUSSIA )
|
||||||
|
end
|
||||||
|
|
||||||
|
self:Mark()
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
function ZONE_CAPTURE_COALITION:onenterCaptured()
|
||||||
|
|
||||||
|
--self:GetParent( self ):onenterCaptured()
|
||||||
|
|
||||||
|
local NewCoalition = self.Zone:GetScannedCoalition()
|
||||||
|
self:F( { NewCoalition = NewCoalition } )
|
||||||
|
self:SetCoalition( NewCoalition )
|
||||||
|
|
||||||
|
self:Mark()
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function ZONE_CAPTURE_COALITION:onenterEmpty()
|
||||||
|
|
||||||
|
--self:GetParent( self ):onenterEmpty()
|
||||||
|
|
||||||
|
self:Mark()
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function ZONE_CAPTURE_COALITION:onenterAttacked()
|
||||||
|
|
||||||
|
--self:GetParent( self ):onenterAttacked()
|
||||||
|
|
||||||
|
self:Mark()
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- When started, check the Coalition status.
|
||||||
|
-- @param #ZONE_CAPTURE_COALITION self
|
||||||
|
function ZONE_CAPTURE_COALITION:onafterGuard()
|
||||||
|
|
||||||
|
--self:F({BASE:GetParent( self )})
|
||||||
|
--BASE:GetParent( self ).onafterGuard( self )
|
||||||
|
|
||||||
|
if not self.SmokeScheduler then
|
||||||
|
self.SmokeScheduler = self:ScheduleRepeat( 1, 1, 0.1, nil, self.StatusSmoke, self )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function ZONE_CAPTURE_COALITION:IsCaptured()
|
||||||
|
|
||||||
|
local IsCaptured = self.Zone:IsAllInZoneOfOtherCoalition( self.Coalition )
|
||||||
|
self:F( { IsCaptured = IsCaptured } )
|
||||||
|
return IsCaptured
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function ZONE_CAPTURE_COALITION:IsAttacked()
|
||||||
|
|
||||||
|
local IsAttacked = self.Zone:IsSomeInZoneOfCoalition( self.Coalition )
|
||||||
|
self:F( { IsAttacked = IsAttacked } )
|
||||||
|
return IsAttacked
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Check status Coalition ownership.
|
||||||
|
-- @param #ZONE_CAPTURE_COALITION self
|
||||||
|
function ZONE_CAPTURE_COALITION:StatusZone()
|
||||||
|
|
||||||
|
local State = self:GetState()
|
||||||
|
self:F( { State = self:GetState() } )
|
||||||
|
|
||||||
|
self:GetParent( self, ZONE_CAPTURE_COALITION ).StatusZone( self )
|
||||||
|
|
||||||
|
if State ~= "Guarded" and self:IsGuarded() then
|
||||||
|
self:Guard()
|
||||||
|
end
|
||||||
|
|
||||||
|
if State ~= "Empty" and self:IsEmpty() then
|
||||||
|
self:Empty()
|
||||||
|
end
|
||||||
|
|
||||||
|
if State ~= "Attacked" and self:IsAttacked() then
|
||||||
|
self:Attack()
|
||||||
|
end
|
||||||
|
|
||||||
|
if State ~= "Captured" and self:IsCaptured() then
|
||||||
|
self:Capture()
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Starts the zone capturing monitoring process.
|
||||||
|
-- This process can be CPU intensive, ensure that you specify reasonable time intervals for the monitoring process.
|
||||||
|
-- Note that the monitoring process is NOT started automatically during the `:New()` constructor.
|
||||||
|
-- It is advised that the zone monitoring process is only started when the monitoring is of relevance in context of the current mission goals.
|
||||||
|
-- When the zone is of no relevance, it is advised NOT to start the monitoring process, or to stop the monitoring process to save CPU resources.
|
||||||
|
-- Therefore, the mission designer will need to use the `:Start()` method within his script to start the monitoring process specifically.
|
||||||
|
-- @param #ZONE_CAPTURE_COALITION self
|
||||||
|
-- @param #number StartInterval (optional) Specifies the start time interval in seconds when the zone state will be checked for the first time.
|
||||||
|
-- @param #number RepeatInterval (optional) Specifies the repeat time interval in seconds when the zone state will be checked repeatedly.
|
||||||
|
-- @usage
|
||||||
|
--
|
||||||
|
-- -- Setup the zone.
|
||||||
|
-- CaptureZone = ZONE:New( "CaptureZone" )
|
||||||
|
-- ZoneCaptureCoalition = ZONE_CAPTURE_COALITION:New( CaptureZone, coalition.side.RED )
|
||||||
|
--
|
||||||
|
-- -- This starts the monitoring process within 15 seconds, repeating every 15 seconds.
|
||||||
|
-- ZoneCaptureCoalition:Start()
|
||||||
|
--
|
||||||
|
-- -- This starts the monitoring process immediately, but repeats every 30 seconds.
|
||||||
|
-- ZoneCaptureCoalition:Start( 0, 30 )
|
||||||
|
--
|
||||||
|
function ZONE_CAPTURE_COALITION:Start( StartInterval, RepeatInterval )
|
||||||
|
|
||||||
|
StartInterval = StartInterval or 15
|
||||||
|
RepeatInterval = RepeatInterval or 15
|
||||||
|
|
||||||
|
if self.ScheduleStatusZone then
|
||||||
|
self:ScheduleStop( self.ScheduleStatusZone )
|
||||||
|
end
|
||||||
|
self.ScheduleStatusZone = self:ScheduleRepeat( StartInterval, RepeatInterval, 0.1, nil, self.StatusZone, self )
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Stops the zone capturing monitoring process.
|
||||||
|
-- When the zone capturing monitor process is stopped, there won't be any changes anymore in the state and the owning coalition of the zone.
|
||||||
|
-- This method becomes really useful when the zone is of no relevance anymore within a long lasting mission.
|
||||||
|
-- In this case, it is advised to stop the monitoring process, not to consume unnecessary the CPU intensive scanning of units presence within the zone.
|
||||||
|
-- @param #ZONE_CAPTURE_COALITION self
|
||||||
|
-- @usage
|
||||||
|
-- -- Setup the zone.
|
||||||
|
-- CaptureZone = ZONE:New( "CaptureZone" )
|
||||||
|
-- ZoneCaptureCoalition = ZONE_CAPTURE_COALITION:New( CaptureZone, coalition.side.RED )
|
||||||
|
--
|
||||||
|
-- -- This starts the monitoring process within 15 seconds, repeating every 15 seconds.
|
||||||
|
-- ZoneCaptureCoalition:Start()
|
||||||
|
--
|
||||||
|
-- -- When the zone capturing is of no relevance anymore, stop the monitoring!
|
||||||
|
-- ZoneCaptureCoalition:Stop()
|
||||||
|
--
|
||||||
|
-- @usage
|
||||||
|
-- -- For example, one could stop the monitoring when the zone was captured!
|
||||||
|
-- --- @param Functional.Protect#ZONE_CAPTURE_COALITION self
|
||||||
|
-- function ZoneCaptureCoalition:OnEnterCaptured()
|
||||||
|
-- local Coalition = self:GetCoalition()
|
||||||
|
-- self:E({Coalition = Coalition})
|
||||||
|
-- if Coalition == coalition.side.BLUE then
|
||||||
|
-- RU_CC:MessageTypeToCoalition( string.format( "%s is captured by the USA, we lost it!", ZoneCaptureCoalition:GetZoneName() ), MESSAGE.Type.Information )
|
||||||
|
-- US_CC:MessageTypeToCoalition( string.format( "We captured %s, Excellent job!", ZoneCaptureCoalition:GetZoneName() ), MESSAGE.Type.Information )
|
||||||
|
-- else
|
||||||
|
-- US_CC:MessageTypeToCoalition( string.format( "%s is captured by Russia, we lost it!", ZoneCaptureCoalition:GetZoneName() ), MESSAGE.Type.Information )
|
||||||
|
-- RU_CC:MessageTypeToCoalition( string.format( "We captured %s, Excellent job!", ZoneCaptureCoalition:GetZoneName() ), MESSAGE.Type.Information )
|
||||||
|
-- end
|
||||||
|
--
|
||||||
|
-- self:AddScore( "Captured", "Zone captured: Extra points granted.", 200 )
|
||||||
|
--
|
||||||
|
-- self:Stop()
|
||||||
|
-- end
|
||||||
|
--
|
||||||
|
function ZONE_CAPTURE_COALITION:Stop()
|
||||||
|
|
||||||
|
if self.ScheduleStatusZone then
|
||||||
|
self:ScheduleStop( self.ScheduleStatusZone )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
177
Moose Development/Moose/Functional/ZoneGoal.lua
Normal file
177
Moose Development/Moose/Functional/ZoneGoal.lua
Normal file
@@ -0,0 +1,177 @@
|
|||||||
|
--- **Functional (WIP)** -- Base class that models processes to achieve goals involving a Zone.
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- ZONE_GOAL models processes that have a Goal with a defined achievement involving a Zone.
|
||||||
|
-- Derived classes implement the ways how the achievements can be realized.
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- ### Author: **FlightControl**
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- @module ZoneGoal
|
||||||
|
|
||||||
|
do -- Zone
|
||||||
|
|
||||||
|
--- @type ZONE_GOAL
|
||||||
|
-- @extends Core.Fsm#FSM
|
||||||
|
|
||||||
|
|
||||||
|
--- # ZONE_GOAL class, extends @{Fsm#FSM}
|
||||||
|
--
|
||||||
|
-- ZONE_GOAL models processes that have a Goal with a defined achievement involving a Zone.
|
||||||
|
-- Derived classes implement the ways how the achievements can be realized.
|
||||||
|
--
|
||||||
|
-- ## 1. ZONE_GOAL constructor
|
||||||
|
--
|
||||||
|
-- * @{#ZONE_GOAL.New}(): Creates a new ZONE_GOAL object.
|
||||||
|
--
|
||||||
|
-- ## 2. ZONE_GOAL is a finite state machine (FSM).
|
||||||
|
--
|
||||||
|
-- ### 2.1 ZONE_GOAL States
|
||||||
|
--
|
||||||
|
-- * None: Initial State
|
||||||
|
--
|
||||||
|
-- ### 2.2 ZONE_GOAL Events
|
||||||
|
--
|
||||||
|
-- * DestroyedUnit: A @{Unit} is destroyed in the Zone. The event will only get triggered if the method @{#ZONE_GOAL.MonitorDestroyedUnits}() is used.
|
||||||
|
--
|
||||||
|
-- @field #ZONE_GOAL
|
||||||
|
ZONE_GOAL = {
|
||||||
|
ClassName = "ZONE_GOAL",
|
||||||
|
}
|
||||||
|
|
||||||
|
--- ZONE_GOAL Constructor.
|
||||||
|
-- @param #ZONE_GOAL self
|
||||||
|
-- @param Core.Zone#ZONE_BASE Zone A @{Zone} object with the goal to be achieved.
|
||||||
|
-- @return #ZONE_GOAL
|
||||||
|
function ZONE_GOAL:New( Zone )
|
||||||
|
|
||||||
|
local self = BASE:Inherit( self, FSM:New() ) -- #ZONE_GOAL
|
||||||
|
self:F( { Zone = Zone } )
|
||||||
|
|
||||||
|
self.Zone = Zone -- Core.Zone#ZONE_BASE
|
||||||
|
self.Goal = GOAL:New()
|
||||||
|
|
||||||
|
self.SmokeTime = nil
|
||||||
|
|
||||||
|
self:AddTransition( "*", "DestroyedUnit", "*" )
|
||||||
|
|
||||||
|
--- DestroyedUnit Handler OnAfter for ZONE_GOAL
|
||||||
|
-- @function [parent=#ZONE_GOAL] OnAfterDestroyedUnit
|
||||||
|
-- @param #ZONE_GOAL self
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string To
|
||||||
|
-- @param Wrapper.Unit#UNIT DestroyedUnit The destroyed unit.
|
||||||
|
-- @param #string PlayerName The name of the player.
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get the Zone
|
||||||
|
-- @param #ZONE_GOAL self
|
||||||
|
-- @return Core.Zone#ZONE_BASE
|
||||||
|
function ZONE_GOAL:GetZone()
|
||||||
|
return self.Zone
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Get the name of the ProtectZone
|
||||||
|
-- @param #ZONE_GOAL self
|
||||||
|
-- @return #string
|
||||||
|
function ZONE_GOAL:GetZoneName()
|
||||||
|
return self.Zone:GetName()
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Smoke the center of theh zone.
|
||||||
|
-- @param #ZONE_GOAL self
|
||||||
|
-- @param #SMOKECOLOR.Color SmokeColor
|
||||||
|
function ZONE_GOAL:Smoke( SmokeColor )
|
||||||
|
|
||||||
|
self:F( { SmokeColor = SmokeColor} )
|
||||||
|
|
||||||
|
self.SmokeColor = SmokeColor
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Flare the center of the zone.
|
||||||
|
-- @param #ZONE_GOAL self
|
||||||
|
-- @param #SMOKECOLOR.Color FlareColor
|
||||||
|
function ZONE_GOAL:Flare( FlareColor )
|
||||||
|
self.Zone:FlareZone( FlareColor, math.random( 1, 360 ) )
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- When started, check the Smoke and the Zone status.
|
||||||
|
-- @param #ZONE_GOAL self
|
||||||
|
function ZONE_GOAL:onafterGuard()
|
||||||
|
|
||||||
|
--self:GetParent( self ):onafterStart()
|
||||||
|
|
||||||
|
self:F("Guard")
|
||||||
|
|
||||||
|
--self:ScheduleRepeat( 15, 15, 0.1, nil, self.StatusZone, self )
|
||||||
|
if not self.SmokeScheduler then
|
||||||
|
self.SmokeScheduler = self:ScheduleRepeat( 1, 1, 0.1, nil, self.StatusSmoke, self )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Check status Smoke.
|
||||||
|
-- @param #ZONE_GOAL self
|
||||||
|
function ZONE_GOAL:StatusSmoke()
|
||||||
|
|
||||||
|
self:F({self.SmokeTime, self.SmokeColor})
|
||||||
|
|
||||||
|
local CurrentTime = timer.getTime()
|
||||||
|
|
||||||
|
if self.SmokeTime == nil or self.SmokeTime + 300 <= CurrentTime then
|
||||||
|
if self.SmokeColor then
|
||||||
|
self.Zone:GetCoordinate():Smoke( self.SmokeColor )
|
||||||
|
--self.SmokeColor = nil
|
||||||
|
self.SmokeTime = CurrentTime
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- @param #ZONE_GOAL self
|
||||||
|
-- @param Core.Event#EVENTDATA EventData
|
||||||
|
function ZONE_GOAL:__Destroyed( EventData )
|
||||||
|
self:F( { "EventDead", EventData } )
|
||||||
|
|
||||||
|
self:F( { EventData.IniUnit } )
|
||||||
|
|
||||||
|
local Vec3 = EventData.IniDCSUnit:getPosition().p
|
||||||
|
self:F( { Vec3 = Vec3 } )
|
||||||
|
local ZoneGoal = self:GetZone()
|
||||||
|
self:F({ZoneGoal})
|
||||||
|
|
||||||
|
if EventData.IniDCSUnit then
|
||||||
|
if ZoneGoal:IsVec3InZone(Vec3) then
|
||||||
|
local PlayerHits = _DATABASE.HITS[EventData.IniUnitName]
|
||||||
|
if PlayerHits then
|
||||||
|
for PlayerName, PlayerHit in pairs( PlayerHits.Players or {} ) do
|
||||||
|
self.Goal:AddPlayerContribution( PlayerName )
|
||||||
|
self:DestroyedUnit( EventData.IniUnitName, PlayerName )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Activate the event UnitDestroyed to be fired when a unit is destroyed in the zone.
|
||||||
|
-- @param #ZONE_GOAL self
|
||||||
|
function ZONE_GOAL:MonitorDestroyedUnits()
|
||||||
|
|
||||||
|
self:HandleEvent( EVENTS.Dead, self.__Destroyed )
|
||||||
|
self:HandleEvent( EVENTS.Crash, self.__Destroyed )
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
452
Moose Development/Moose/Functional/ZoneGoalCargo.lua
Normal file
452
Moose Development/Moose/Functional/ZoneGoalCargo.lua
Normal file
@@ -0,0 +1,452 @@
|
|||||||
|
--- **Functional (WIP)** -- Base class that models processes to achieve goals involving a Zone and Cargo.
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- ZONE_GOAL_CARGO models processes that have a Goal with a defined achievement involving a Zone and Cargo.
|
||||||
|
-- Derived classes implement the ways how the achievements can be realized.
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- ### Author: **FlightControl**
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- @module ZoneGoalCargo
|
||||||
|
|
||||||
|
do -- ZoneGoal
|
||||||
|
|
||||||
|
--- @type ZONE_GOAL_CARGO
|
||||||
|
-- @extends Functional.ZoneGoal#ZONE_GOAL
|
||||||
|
|
||||||
|
|
||||||
|
--- # ZONE_GOAL_CARGO class, extends @{ZoneGoal#ZONE_GOAL}
|
||||||
|
--
|
||||||
|
-- ZONE_GOAL_CARGO models processes that have a Goal with a defined achievement involving a Zone and Cargo.
|
||||||
|
-- Derived classes implement the ways how the achievements can be realized.
|
||||||
|
--
|
||||||
|
-- ## 1. ZONE_GOAL_CARGO constructor
|
||||||
|
--
|
||||||
|
-- * @{#ZONE_GOAL_CARGO.New}(): Creates a new ZONE_GOAL_CARGO object.
|
||||||
|
--
|
||||||
|
-- ## 2. ZONE_GOAL_CARGO is a finite state machine (FSM).
|
||||||
|
--
|
||||||
|
-- ### 2.1 ZONE_GOAL_CARGO States
|
||||||
|
--
|
||||||
|
-- * **Deployed**: The Zone has been captured by an other coalition.
|
||||||
|
-- * **Airborne**: The Zone is currently intruded by an other coalition. There are units of the owning coalition and an other coalition in the Zone.
|
||||||
|
-- * **Loaded**: The Zone is guarded by the owning coalition. There is no other unit of an other coalition in the Zone.
|
||||||
|
-- * **Empty**: The Zone is empty. There is not valid unit in the Zone.
|
||||||
|
--
|
||||||
|
-- ### 2.2 ZONE_GOAL_CARGO Events
|
||||||
|
--
|
||||||
|
-- * **Capture**: The Zone has been captured by an other coalition.
|
||||||
|
-- * **Attack**: The Zone is currently intruded by an other coalition. There are units of the owning coalition and an other coalition in the Zone.
|
||||||
|
-- * **Guard**: The Zone is guarded by the owning coalition. There is no other unit of an other coalition in the Zone.
|
||||||
|
-- * **Empty**: The Zone is empty. There is not valid unit in the Zone.
|
||||||
|
--
|
||||||
|
-- ### 2.3 ZONE_GOAL_CARGO State Machine
|
||||||
|
--
|
||||||
|
-- @field #ZONE_GOAL_CARGO
|
||||||
|
ZONE_GOAL_CARGO = {
|
||||||
|
ClassName = "ZONE_GOAL_CARGO",
|
||||||
|
}
|
||||||
|
|
||||||
|
--- @field #table ZONE_GOAL_CARGO.States
|
||||||
|
ZONE_GOAL_CARGO.States = {}
|
||||||
|
|
||||||
|
--- ZONE_GOAL_CARGO Constructor.
|
||||||
|
-- @param #ZONE_GOAL_CARGO self
|
||||||
|
-- @param Core.Zone#ZONE Zone A @{Zone} object with the goal to be achieved.
|
||||||
|
-- @param DCSCoalition.DCSCoalition#coalition Coalition The initial coalition owning the zone.
|
||||||
|
-- @return #ZONE_GOAL_CARGO
|
||||||
|
function ZONE_GOAL_CARGO:New( Zone, Coalition )
|
||||||
|
|
||||||
|
local self = BASE:Inherit( self, ZONE_GOAL:New( Zone ) ) -- #ZONE_GOAL_CARGO
|
||||||
|
self:F( { Zone = Zone, Coalition = Coalition } )
|
||||||
|
|
||||||
|
self:SetCoalition( Coalition )
|
||||||
|
|
||||||
|
do
|
||||||
|
|
||||||
|
--- Captured State Handler OnLeave for ZONE_GOAL_CARGO
|
||||||
|
-- @function [parent=#ZONE_GOAL_CARGO] OnLeaveCaptured
|
||||||
|
-- @param #ZONE_GOAL_CARGO self
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string To
|
||||||
|
-- @return #boolean
|
||||||
|
|
||||||
|
--- Captured State Handler OnEnter for ZONE_GOAL_CARGO
|
||||||
|
-- @function [parent=#ZONE_GOAL_CARGO] OnEnterCaptured
|
||||||
|
-- @param #ZONE_GOAL_CARGO self
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string To
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
do
|
||||||
|
|
||||||
|
--- Attacked State Handler OnLeave for ZONE_GOAL_CARGO
|
||||||
|
-- @function [parent=#ZONE_GOAL_CARGO] OnLeaveAttacked
|
||||||
|
-- @param #ZONE_GOAL_CARGO self
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string To
|
||||||
|
-- @return #boolean
|
||||||
|
|
||||||
|
--- Attacked State Handler OnEnter for ZONE_GOAL_CARGO
|
||||||
|
-- @function [parent=#ZONE_GOAL_CARGO] OnEnterAttacked
|
||||||
|
-- @param #ZONE_GOAL_CARGO self
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string To
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
|
||||||
|
--- Guarded State Handler OnLeave for ZONE_GOAL_CARGO
|
||||||
|
-- @function [parent=#ZONE_GOAL_CARGO] OnLeaveGuarded
|
||||||
|
-- @param #ZONE_GOAL_CARGO self
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string To
|
||||||
|
-- @return #boolean
|
||||||
|
|
||||||
|
--- Guarded State Handler OnEnter for ZONE_GOAL_CARGO
|
||||||
|
-- @function [parent=#ZONE_GOAL_CARGO] OnEnterGuarded
|
||||||
|
-- @param #ZONE_GOAL_CARGO self
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string To
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
do
|
||||||
|
|
||||||
|
--- Empty State Handler OnLeave for ZONE_GOAL_CARGO
|
||||||
|
-- @function [parent=#ZONE_GOAL_CARGO] OnLeaveEmpty
|
||||||
|
-- @param #ZONE_GOAL_CARGO self
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string To
|
||||||
|
-- @return #boolean
|
||||||
|
|
||||||
|
--- Empty State Handler OnEnter for ZONE_GOAL_CARGO
|
||||||
|
-- @function [parent=#ZONE_GOAL_CARGO] OnEnterEmpty
|
||||||
|
-- @param #ZONE_GOAL_CARGO self
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string To
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
self:AddTransition( "*", "Guard", "Guarded" )
|
||||||
|
|
||||||
|
--- Guard Handler OnBefore for ZONE_GOAL_CARGO
|
||||||
|
-- @function [parent=#ZONE_GOAL_CARGO] OnBeforeGuard
|
||||||
|
-- @param #ZONE_GOAL_CARGO self
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string To
|
||||||
|
-- @return #boolean
|
||||||
|
|
||||||
|
--- Guard Handler OnAfter for ZONE_GOAL_CARGO
|
||||||
|
-- @function [parent=#ZONE_GOAL_CARGO] OnAfterGuard
|
||||||
|
-- @param #ZONE_GOAL_CARGO self
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string To
|
||||||
|
|
||||||
|
--- Guard Trigger for ZONE_GOAL_CARGO
|
||||||
|
-- @function [parent=#ZONE_GOAL_CARGO] Guard
|
||||||
|
-- @param #ZONE_GOAL_CARGO self
|
||||||
|
|
||||||
|
--- Guard Asynchronous Trigger for ZONE_GOAL_CARGO
|
||||||
|
-- @function [parent=#ZONE_GOAL_CARGO] __Guard
|
||||||
|
-- @param #ZONE_GOAL_CARGO self
|
||||||
|
-- @param #number Delay
|
||||||
|
|
||||||
|
self:AddTransition( "*", "Empty", "Empty" )
|
||||||
|
|
||||||
|
--- Empty Handler OnBefore for ZONE_GOAL_CARGO
|
||||||
|
-- @function [parent=#ZONE_GOAL_CARGO] OnBeforeEmpty
|
||||||
|
-- @param #ZONE_GOAL_CARGO self
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string To
|
||||||
|
-- @return #boolean
|
||||||
|
|
||||||
|
--- Empty Handler OnAfter for ZONE_GOAL_CARGO
|
||||||
|
-- @function [parent=#ZONE_GOAL_CARGO] OnAfterEmpty
|
||||||
|
-- @param #ZONE_GOAL_CARGO self
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string To
|
||||||
|
|
||||||
|
--- Empty Trigger for ZONE_GOAL_CARGO
|
||||||
|
-- @function [parent=#ZONE_GOAL_CARGO] Empty
|
||||||
|
-- @param #ZONE_GOAL_CARGO self
|
||||||
|
|
||||||
|
--- Empty Asynchronous Trigger for ZONE_GOAL_CARGO
|
||||||
|
-- @function [parent=#ZONE_GOAL_CARGO] __Empty
|
||||||
|
-- @param #ZONE_GOAL_CARGO self
|
||||||
|
-- @param #number Delay
|
||||||
|
|
||||||
|
|
||||||
|
self:AddTransition( { "Guarded", "Empty" }, "Attack", "Attacked" )
|
||||||
|
|
||||||
|
--- Attack Handler OnBefore for ZONE_GOAL_CARGO
|
||||||
|
-- @function [parent=#ZONE_GOAL_CARGO] OnBeforeAttack
|
||||||
|
-- @param #ZONE_GOAL_CARGO self
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string To
|
||||||
|
-- @return #boolean
|
||||||
|
|
||||||
|
--- Attack Handler OnAfter for ZONE_GOAL_CARGO
|
||||||
|
-- @function [parent=#ZONE_GOAL_CARGO] OnAfterAttack
|
||||||
|
-- @param #ZONE_GOAL_CARGO self
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string To
|
||||||
|
|
||||||
|
--- Attack Trigger for ZONE_GOAL_CARGO
|
||||||
|
-- @function [parent=#ZONE_GOAL_CARGO] Attack
|
||||||
|
-- @param #ZONE_GOAL_CARGO self
|
||||||
|
|
||||||
|
--- Attack Asynchronous Trigger for ZONE_GOAL_CARGO
|
||||||
|
-- @function [parent=#ZONE_GOAL_CARGO] __Attack
|
||||||
|
-- @param #ZONE_GOAL_CARGO self
|
||||||
|
-- @param #number Delay
|
||||||
|
|
||||||
|
self:AddTransition( { "Guarded", "Attacked", "Empty" }, "Capture", "Captured" )
|
||||||
|
|
||||||
|
--- Capture Handler OnBefore for ZONE_GOAL_CARGO
|
||||||
|
-- @function [parent=#ZONE_GOAL_CARGO] OnBeforeCapture
|
||||||
|
-- @param #ZONE_GOAL_CARGO self
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string To
|
||||||
|
-- @return #boolean
|
||||||
|
|
||||||
|
--- Capture Handler OnAfter for ZONE_GOAL_CARGO
|
||||||
|
-- @function [parent=#ZONE_GOAL_CARGO] OnAfterCapture
|
||||||
|
-- @param #ZONE_GOAL_CARGO self
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string To
|
||||||
|
|
||||||
|
--- Capture Trigger for ZONE_GOAL_CARGO
|
||||||
|
-- @function [parent=#ZONE_GOAL_CARGO] Capture
|
||||||
|
-- @param #ZONE_GOAL_CARGO self
|
||||||
|
|
||||||
|
--- Capture Asynchronous Trigger for ZONE_GOAL_CARGO
|
||||||
|
-- @function [parent=#ZONE_GOAL_CARGO] __Capture
|
||||||
|
-- @param #ZONE_GOAL_CARGO self
|
||||||
|
-- @param #number Delay
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Set the owning coalition of the zone.
|
||||||
|
-- @param #ZONE_GOAL_CARGO self
|
||||||
|
-- @param DCSCoalition.DCSCoalition#coalition Coalition
|
||||||
|
function ZONE_GOAL_CARGO:SetCoalition( Coalition )
|
||||||
|
self.Coalition = Coalition
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Get the owning coalition of the zone.
|
||||||
|
-- @param #ZONE_GOAL_CARGO self
|
||||||
|
-- @return DCSCoalition.DCSCoalition#coalition Coalition.
|
||||||
|
function ZONE_GOAL_CARGO:GetCoalition()
|
||||||
|
return self.Coalition
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Get the owning coalition name of the zone.
|
||||||
|
-- @param #ZONE_GOAL_CARGO self
|
||||||
|
-- @return #string Coalition name.
|
||||||
|
function ZONE_GOAL_CARGO:GetCoalitionName()
|
||||||
|
|
||||||
|
if self.Coalition == coalition.side.BLUE then
|
||||||
|
return "Blue"
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.Coalition == coalition.side.RED then
|
||||||
|
return "Red"
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.Coalition == coalition.side.NEUTRAL then
|
||||||
|
return "Neutral"
|
||||||
|
end
|
||||||
|
|
||||||
|
return ""
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function ZONE_GOAL_CARGO:IsGuarded()
|
||||||
|
|
||||||
|
local IsGuarded = self.Zone:IsAllInZoneOfCoalition( self.Coalition )
|
||||||
|
self:F( { IsGuarded = IsGuarded } )
|
||||||
|
return IsGuarded
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function ZONE_GOAL_CARGO:IsEmpty()
|
||||||
|
|
||||||
|
local IsEmpty = self.Zone:IsNoneInZone()
|
||||||
|
self:F( { IsEmpty = IsEmpty } )
|
||||||
|
return IsEmpty
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function ZONE_GOAL_CARGO:IsCaptured()
|
||||||
|
|
||||||
|
local IsCaptured = self.Zone:IsAllInZoneOfOtherCoalition( self.Coalition )
|
||||||
|
self:F( { IsCaptured = IsCaptured } )
|
||||||
|
return IsCaptured
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function ZONE_GOAL_CARGO:IsAttacked()
|
||||||
|
|
||||||
|
local IsAttacked = self.Zone:IsSomeInZoneOfCoalition( self.Coalition )
|
||||||
|
self:F( { IsAttacked = IsAttacked } )
|
||||||
|
return IsAttacked
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--- Mark.
|
||||||
|
-- @param #ZONE_GOAL_CARGO self
|
||||||
|
function ZONE_GOAL_CARGO:Mark()
|
||||||
|
|
||||||
|
local Coord = self.Zone:GetCoordinate()
|
||||||
|
local ZoneName = self:GetZoneName()
|
||||||
|
local State = self:GetState()
|
||||||
|
|
||||||
|
if self.MarkRed and self.MarkBlue then
|
||||||
|
self:F( { MarkRed = self.MarkRed, MarkBlue = self.MarkBlue } )
|
||||||
|
Coord:RemoveMark( self.MarkRed )
|
||||||
|
Coord:RemoveMark( self.MarkBlue )
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.Coalition == coalition.side.BLUE then
|
||||||
|
self.MarkBlue = Coord:MarkToCoalitionBlue( "Guard Zone: " .. ZoneName .. "\nStatus: " .. State )
|
||||||
|
self.MarkRed = Coord:MarkToCoalitionRed( "Capture Zone: " .. ZoneName .. "\nStatus: " .. State )
|
||||||
|
else
|
||||||
|
self.MarkRed = Coord:MarkToCoalitionRed( "Guard Zone: " .. ZoneName .. "\nStatus: " .. State )
|
||||||
|
self.MarkBlue = Coord:MarkToCoalitionBlue( "Capture Zone: " .. ZoneName .. "\nStatus: " .. State )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Bound.
|
||||||
|
-- @param #ZONE_GOAL_CARGO self
|
||||||
|
function ZONE_GOAL_CARGO:onenterGuarded()
|
||||||
|
|
||||||
|
--self:GetParent( self ):onenterGuarded()
|
||||||
|
|
||||||
|
if self.Coalition == coalition.side.BLUE then
|
||||||
|
--elf.ProtectZone:BoundZone( 12, country.id.USA )
|
||||||
|
else
|
||||||
|
--self.ProtectZone:BoundZone( 12, country.id.RUSSIA )
|
||||||
|
end
|
||||||
|
|
||||||
|
self:Mark()
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
function ZONE_GOAL_CARGO:onenterCaptured()
|
||||||
|
|
||||||
|
--self:GetParent( self ):onenterCaptured()
|
||||||
|
|
||||||
|
local NewCoalition = self.Zone:GetCoalition()
|
||||||
|
self:F( { NewCoalition = NewCoalition } )
|
||||||
|
self:SetCoalition( NewCoalition )
|
||||||
|
|
||||||
|
self:Mark()
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function ZONE_GOAL_CARGO:onenterEmpty()
|
||||||
|
|
||||||
|
--self:GetParent( self ):onenterEmpty()
|
||||||
|
|
||||||
|
self:Mark()
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function ZONE_GOAL_CARGO:onenterAttacked()
|
||||||
|
|
||||||
|
--self:GetParent( self ):onenterAttacked()
|
||||||
|
|
||||||
|
self:Mark()
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- When started, check the Coalition status.
|
||||||
|
-- @param #ZONE_GOAL_CARGO self
|
||||||
|
function ZONE_GOAL_CARGO:onafterGuard()
|
||||||
|
|
||||||
|
--self:F({BASE:GetParent( self )})
|
||||||
|
--BASE:GetParent( self ).onafterGuard( self )
|
||||||
|
|
||||||
|
if not self.SmokeScheduler then
|
||||||
|
self.SmokeScheduler = self:ScheduleRepeat( 1, 1, 0.1, nil, self.StatusSmoke, self )
|
||||||
|
end
|
||||||
|
if not self.ScheduleStatusZone then
|
||||||
|
self.ScheduleStatusZone = self:ScheduleRepeat( 15, 15, 0.1, nil, self.StatusZone, self )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function ZONE_GOAL_CARGO:IsCaptured()
|
||||||
|
|
||||||
|
local IsCaptured = self.Zone:IsAllInZoneOfOtherCoalition( self.Coalition )
|
||||||
|
self:F( { IsCaptured = IsCaptured } )
|
||||||
|
return IsCaptured
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function ZONE_GOAL_CARGO:IsAttacked()
|
||||||
|
|
||||||
|
local IsAttacked = self.Zone:IsSomeInZoneOfCoalition( self.Coalition )
|
||||||
|
self:F( { IsAttacked = IsAttacked } )
|
||||||
|
return IsAttacked
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Check status Coalition ownership.
|
||||||
|
-- @param #ZONE_GOAL_CARGO self
|
||||||
|
function ZONE_GOAL_CARGO:StatusZone()
|
||||||
|
|
||||||
|
local State = self:GetState()
|
||||||
|
self:F( { State = self:GetState() } )
|
||||||
|
|
||||||
|
self.Zone:Scan()
|
||||||
|
|
||||||
|
if State ~= "Guarded" and self:IsGuarded() then
|
||||||
|
self:Guard()
|
||||||
|
end
|
||||||
|
|
||||||
|
if State ~= "Empty" and self:IsEmpty() then
|
||||||
|
self:Empty()
|
||||||
|
end
|
||||||
|
|
||||||
|
if State ~= "Attacked" and self:IsAttacked() then
|
||||||
|
self:Attack()
|
||||||
|
end
|
||||||
|
|
||||||
|
if State ~= "Captured" and self:IsCaptured() then
|
||||||
|
self:Capture()
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
113
Moose Development/Moose/Functional/ZoneGoalCoalition.lua
Normal file
113
Moose Development/Moose/Functional/ZoneGoalCoalition.lua
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
--- **Functional (WIP)** -- Base class that models processes to achieve goals involving a Zone for a Coalition.
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- ZONE_GOAL_COALITION models processes that have a Goal with a defined achievement involving a Zone for a Coalition.
|
||||||
|
-- Derived classes implement the ways how the achievements can be realized.
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- ### Author: **FlightControl**
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- @module ZoneGoalCoalition
|
||||||
|
|
||||||
|
do -- ZoneGoal
|
||||||
|
|
||||||
|
--- @type ZONE_GOAL_COALITION
|
||||||
|
-- @extends Functional.ZoneGoal#ZONE_GOAL
|
||||||
|
|
||||||
|
|
||||||
|
--- # ZONE_GOAL_COALITION class, extends @{ZoneGoal#ZONE_GOAL}
|
||||||
|
--
|
||||||
|
-- ZONE_GOAL_COALITION models processes that have a Goal with a defined achievement involving a Zone for a Coalition.
|
||||||
|
-- Derived classes implement the ways how the achievements can be realized.
|
||||||
|
--
|
||||||
|
-- ## 1. ZONE_GOAL_COALITION constructor
|
||||||
|
--
|
||||||
|
-- * @{#ZONE_GOAL_COALITION.New}(): Creates a new ZONE_GOAL_COALITION object.
|
||||||
|
--
|
||||||
|
-- ## 2. ZONE_GOAL_COALITION is a finite state machine (FSM).
|
||||||
|
--
|
||||||
|
-- ### 2.1 ZONE_GOAL_COALITION States
|
||||||
|
--
|
||||||
|
-- ### 2.2 ZONE_GOAL_COALITION Events
|
||||||
|
--
|
||||||
|
-- ### 2.3 ZONE_GOAL_COALITION State Machine
|
||||||
|
--
|
||||||
|
-- @field #ZONE_GOAL_COALITION
|
||||||
|
ZONE_GOAL_COALITION = {
|
||||||
|
ClassName = "ZONE_GOAL_COALITION",
|
||||||
|
}
|
||||||
|
|
||||||
|
--- @field #table ZONE_GOAL_COALITION.States
|
||||||
|
ZONE_GOAL_COALITION.States = {}
|
||||||
|
|
||||||
|
--- ZONE_GOAL_COALITION Constructor.
|
||||||
|
-- @param #ZONE_GOAL_COALITION self
|
||||||
|
-- @param Core.Zone#ZONE Zone A @{Zone} object with the goal to be achieved.
|
||||||
|
-- @param DCSCoalition.DCSCoalition#coalition Coalition The initial coalition owning the zone.
|
||||||
|
-- @return #ZONE_GOAL_COALITION
|
||||||
|
function ZONE_GOAL_COALITION:New( Zone, Coalition )
|
||||||
|
|
||||||
|
local self = BASE:Inherit( self, ZONE_GOAL:New( Zone ) ) -- #ZONE_GOAL_COALITION
|
||||||
|
self:F( { Zone = Zone, Coalition = Coalition } )
|
||||||
|
|
||||||
|
self:SetCoalition( Coalition )
|
||||||
|
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Set the owning coalition of the zone.
|
||||||
|
-- @param #ZONE_GOAL_COALITION self
|
||||||
|
-- @param DCSCoalition.DCSCoalition#coalition Coalition
|
||||||
|
function ZONE_GOAL_COALITION:SetCoalition( Coalition )
|
||||||
|
self.Coalition = Coalition
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Get the owning coalition of the zone.
|
||||||
|
-- @param #ZONE_GOAL_COALITION self
|
||||||
|
-- @return DCSCoalition.DCSCoalition#coalition Coalition.
|
||||||
|
function ZONE_GOAL_COALITION:GetCoalition()
|
||||||
|
return self.Coalition
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Get the owning coalition name of the zone.
|
||||||
|
-- @param #ZONE_GOAL_COALITION self
|
||||||
|
-- @return #string Coalition name.
|
||||||
|
function ZONE_GOAL_COALITION:GetCoalitionName()
|
||||||
|
|
||||||
|
if self.Coalition == coalition.side.BLUE then
|
||||||
|
return "Blue"
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.Coalition == coalition.side.RED then
|
||||||
|
return "Red"
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.Coalition == coalition.side.NEUTRAL then
|
||||||
|
return "Neutral"
|
||||||
|
end
|
||||||
|
|
||||||
|
return ""
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Check status Coalition ownership.
|
||||||
|
-- @param #ZONE_GOAL_COALITION self
|
||||||
|
function ZONE_GOAL_COALITION:StatusZone()
|
||||||
|
|
||||||
|
local State = self:GetState()
|
||||||
|
self:F( { State = self:GetState() } )
|
||||||
|
|
||||||
|
self.Zone:Scan( { Object.Category.UNIT, Object.Category.STATIC } )
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
-- The order of the declarations is important here. Don't touch it.
|
-- The order of the declarations is important here. Don't touch it.
|
||||||
|
|
||||||
|
|
||||||
--- Declare the event dispatcher based on the EVENT class
|
--- Declare the event dispatcher based on the EVENT class
|
||||||
_EVENTDISPATCHER = EVENT:New() -- Core.Event#EVENT
|
_EVENTDISPATCHER = EVENT:New() -- Core.Event#EVENT
|
||||||
|
|
||||||
@@ -10,4 +11,5 @@ _SCHEDULEDISPATCHER = SCHEDULEDISPATCHER:New() -- Core.Timer#SCHEDULEDISPATCHER
|
|||||||
_DATABASE = DATABASE:New() -- Core.Database#DATABASE
|
_DATABASE = DATABASE:New() -- Core.Database#DATABASE
|
||||||
|
|
||||||
_SETTINGS = SETTINGS:Set()
|
_SETTINGS = SETTINGS:Set()
|
||||||
|
_SETTINGS:SetPlayerMenuOn()
|
||||||
|
|
||||||
|
|||||||
@@ -3,11 +3,11 @@
|
|||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
-- ### Author: **Sven Van de Velde (FlightControl)**
|
-- ### Author: **FlightControl**
|
||||||
--
|
--
|
||||||
-- ### Contributions:
|
-- ### Contributions:
|
||||||
--
|
--
|
||||||
-- ====
|
-- ===
|
||||||
--
|
--
|
||||||
-- @module CommandCenter
|
-- @module CommandCenter
|
||||||
|
|
||||||
@@ -100,8 +100,10 @@ function COMMANDCENTER:New( CommandCenterPositionable, CommandCenterName )
|
|||||||
function( self, EventData )
|
function( self, EventData )
|
||||||
if EventData.IniObjectCategory == 1 then
|
if EventData.IniObjectCategory == 1 then
|
||||||
local EventGroup = GROUP:Find( EventData.IniDCSGroup )
|
local EventGroup = GROUP:Find( EventData.IniDCSGroup )
|
||||||
|
self:E( { CommandCenter = self:GetName(), EventGroup = EventGroup:GetName(), HasGroup = self:HasGroup( EventGroup ), EventData = EventData } )
|
||||||
if EventGroup and self:HasGroup( EventGroup ) then
|
if EventGroup and self:HasGroup( EventGroup ) then
|
||||||
local MenuReporting = MENU_GROUP:New( EventGroup, "Missions Reports", self.CommandCenterMenu )
|
local CommandCenterMenu = MENU_GROUP:New( EventGroup, self:GetText() )
|
||||||
|
local MenuReporting = MENU_GROUP:New( EventGroup, "Missions Reports", CommandCenterMenu )
|
||||||
local MenuMissionsSummary = MENU_GROUP_COMMAND:New( EventGroup, "Missions Status Report", MenuReporting, self.ReportMissionsStatus, self, EventGroup )
|
local MenuMissionsSummary = MENU_GROUP_COMMAND:New( EventGroup, "Missions Status Report", MenuReporting, self.ReportMissionsStatus, self, EventGroup )
|
||||||
local MenuMissionsDetails = MENU_GROUP_COMMAND:New( EventGroup, "Missions Players Report", MenuReporting, self.ReportMissionsPlayers, self, EventGroup )
|
local MenuMissionsDetails = MENU_GROUP_COMMAND:New( EventGroup, "Missions Players Report", MenuReporting, self.ReportMissionsPlayers, self, EventGroup )
|
||||||
self:ReportSummary( EventGroup )
|
self:ReportSummary( EventGroup )
|
||||||
@@ -112,31 +114,30 @@ function COMMANDCENTER:New( CommandCenterPositionable, CommandCenterName )
|
|||||||
Mission:JoinUnit( PlayerUnit, PlayerGroup )
|
Mission:JoinUnit( PlayerUnit, PlayerGroup )
|
||||||
end
|
end
|
||||||
self:SetMenu()
|
self:SetMenu()
|
||||||
_DATABASE:PlayerSettingsMenu( PlayerUnit )
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
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.
|
-- -- 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=
|
-- -- For these elements, it will=
|
||||||
-- - Set the correct menu.
|
-- -- - Set the correct menu.
|
||||||
-- - Assign the PlayerUnit to the Task if required.
|
-- -- - Assign the PlayerUnit to the Task if required.
|
||||||
-- - Send a message to the other players in the group that this player has joined.
|
-- -- - Send a message to the other players in the group that this player has joined.
|
||||||
self:HandleEvent( EVENTS.PlayerEnterUnit,
|
-- self:HandleEvent( EVENTS.PlayerEnterUnit,
|
||||||
--- @param #COMMANDCENTER self
|
-- --- @param #COMMANDCENTER self
|
||||||
-- @param Core.Event#EVENTDATA EventData
|
-- -- @param Core.Event#EVENTDATA EventData
|
||||||
function( self, EventData )
|
-- function( self, EventData )
|
||||||
local PlayerUnit = EventData.IniUnit
|
-- local PlayerUnit = EventData.IniUnit
|
||||||
for MissionID, Mission in pairs( self:GetMissions() ) do
|
-- for MissionID, Mission in pairs( self:GetMissions() ) do
|
||||||
local Mission = Mission -- Tasking.Mission#MISSION
|
-- local Mission = Mission -- Tasking.Mission#MISSION
|
||||||
local PlayerGroup = EventData.IniGroup -- The GROUP object should be filled!
|
-- local PlayerGroup = EventData.IniGroup -- The GROUP object should be filled!
|
||||||
Mission:JoinUnit( PlayerUnit, PlayerGroup )
|
-- Mission:JoinUnit( PlayerUnit, PlayerGroup )
|
||||||
end
|
-- end
|
||||||
self:SetMenu()
|
-- self:SetMenu()
|
||||||
end
|
-- end
|
||||||
)
|
-- )
|
||||||
|
|
||||||
-- Handle when a player leaves a slot and goes back to spectators ...
|
-- Handle when a player leaves a slot and goes back to spectators ...
|
||||||
-- The PlayerUnit will be UnAssigned from the Task.
|
-- The PlayerUnit will be UnAssigned from the Task.
|
||||||
@@ -202,6 +203,24 @@ function COMMANDCENTER:GetName()
|
|||||||
return self.CommandCenterName
|
return self.CommandCenterName
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Gets the text string of the HQ command center.
|
||||||
|
-- @param #COMMANDCENTER self
|
||||||
|
-- @return #string
|
||||||
|
function COMMANDCENTER:GetText()
|
||||||
|
|
||||||
|
return "Command Center [" .. self.CommandCenterName .. "]"
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Gets the short text string of the HQ command center.
|
||||||
|
-- @param #COMMANDCENTER self
|
||||||
|
-- @return #string
|
||||||
|
function COMMANDCENTER:GetShortText()
|
||||||
|
|
||||||
|
return "CC [" .. self.CommandCenterName .. "]"
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--- Gets the POSITIONABLE of the HQ command center.
|
--- Gets the POSITIONABLE of the HQ command center.
|
||||||
-- @param #COMMANDCENTER self
|
-- @param #COMMANDCENTER self
|
||||||
-- @return Wrapper.Positionable#POSITIONABLE
|
-- @return Wrapper.Positionable#POSITIONABLE
|
||||||
@@ -305,8 +324,6 @@ end
|
|||||||
function COMMANDCENTER:SetMenu()
|
function COMMANDCENTER:SetMenu()
|
||||||
self:F()
|
self:F()
|
||||||
|
|
||||||
self.CommandCenterMenu = self.CommandCenterMenu or MENU_COALITION:New( self.CommandCenterCoalition, "Command Center (" .. self:GetName() .. ")" )
|
|
||||||
|
|
||||||
local MenuTime = timer.getTime()
|
local MenuTime = timer.getTime()
|
||||||
for MissionID, Mission in pairs( self:GetMissions() or {} ) do
|
for MissionID, Mission in pairs( self:GetMissions() or {} ) do
|
||||||
local Mission = Mission -- Tasking.Mission#MISSION
|
local Mission = Mission -- Tasking.Mission#MISSION
|
||||||
@@ -360,7 +377,7 @@ end
|
|||||||
-- @param Wrapper.Group#GROUP TaskGroup
|
-- @param Wrapper.Group#GROUP TaskGroup
|
||||||
function COMMANDCENTER:MessageToGroup( Message, TaskGroup )
|
function COMMANDCENTER:MessageToGroup( Message, TaskGroup )
|
||||||
|
|
||||||
self:GetPositionable():MessageToGroup( Message, 15, TaskGroup, self:GetName() )
|
self:GetPositionable():MessageToGroup( Message, 15, TaskGroup, self:GetShortText() )
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -371,7 +388,7 @@ end
|
|||||||
-- @param Core.Message#MESSAGE.MessageType MessageType The type of the message, resulting in automatic time duration and prefix of the message.
|
-- @param Core.Message#MESSAGE.MessageType MessageType The type of the message, resulting in automatic time duration and prefix of the message.
|
||||||
function COMMANDCENTER:MessageTypeToGroup( Message, TaskGroup, MessageType )
|
function COMMANDCENTER:MessageTypeToGroup( Message, TaskGroup, MessageType )
|
||||||
|
|
||||||
self:GetPositionable():MessageTypeToGroup( Message, MessageType, TaskGroup, self:GetName() )
|
self:GetPositionable():MessageTypeToGroup( Message, MessageType, TaskGroup, self:GetShortText() )
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -404,16 +421,18 @@ end
|
|||||||
--- Report the status of all MISSIONs to a GROUP.
|
--- Report the status of all MISSIONs to a GROUP.
|
||||||
-- Each Mission is listed, with an indication how many Tasks are still to be completed.
|
-- Each Mission is listed, with an indication how many Tasks are still to be completed.
|
||||||
-- @param #COMMANDCENTER self
|
-- @param #COMMANDCENTER self
|
||||||
function COMMANDCENTER:ReportMissionsStatus( ReportGroup )
|
function COMMANDCENTER:ReportSummary( ReportGroup )
|
||||||
self:E( ReportGroup )
|
self:F( ReportGroup )
|
||||||
|
|
||||||
local Report = REPORT:New()
|
local Report = REPORT:New()
|
||||||
|
|
||||||
Report:Add( "Status report of all missions." )
|
-- List the name of the mission.
|
||||||
|
local Name = self:GetName()
|
||||||
|
Report:Add( string.format( '%s - Report Summary Missions', Name ) )
|
||||||
|
|
||||||
for MissionID, Mission in pairs( self.Missions ) do
|
for MissionID, Mission in pairs( self.Missions ) do
|
||||||
local Mission = Mission -- Tasking.Mission#MISSION
|
local Mission = Mission -- Tasking.Mission#MISSION
|
||||||
Report:Add( " - " .. Mission:ReportStatus() )
|
Report:Add( " - " .. Mission:ReportSummary() )
|
||||||
end
|
end
|
||||||
|
|
||||||
self:MessageToGroup( Report:Text(), ReportGroup )
|
self:MessageToGroup( Report:Text(), ReportGroup )
|
||||||
@@ -423,7 +442,7 @@ end
|
|||||||
-- Each Mission is listed, with an indication how many Tasks are still to be completed.
|
-- Each Mission is listed, with an indication how many Tasks are still to be completed.
|
||||||
-- @param #COMMANDCENTER self
|
-- @param #COMMANDCENTER self
|
||||||
function COMMANDCENTER:ReportMissionsPlayers( ReportGroup )
|
function COMMANDCENTER:ReportMissionsPlayers( ReportGroup )
|
||||||
self:E( ReportGroup )
|
self:F( ReportGroup )
|
||||||
|
|
||||||
local Report = REPORT:New()
|
local Report = REPORT:New()
|
||||||
|
|
||||||
@@ -441,7 +460,7 @@ end
|
|||||||
-- Report the details of a Mission, listing the Mission, and all the Task details.
|
-- Report the details of a Mission, listing the Mission, and all the Task details.
|
||||||
-- @param #COMMANDCENTER self
|
-- @param #COMMANDCENTER self
|
||||||
function COMMANDCENTER:ReportDetails( ReportGroup, Task )
|
function COMMANDCENTER:ReportDetails( ReportGroup, Task )
|
||||||
self:E( ReportGroup )
|
self:F( ReportGroup )
|
||||||
|
|
||||||
local Report = REPORT:New()
|
local Report = REPORT:New()
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
-- 1) @{DetectionManager#DETECTION_MANAGER} class, extends @{Fsm#FSM}
|
-- 1) @{DetectionManager#DETECTION_MANAGER} class, extends @{Fsm#FSM}
|
||||||
-- ====================================================================
|
-- ===
|
||||||
-- The @{DetectionManager#DETECTION_MANAGER} class defines the core functions to report detected objects to groups.
|
-- 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.
|
-- Reportings can be done in several manners, and it is up to the derived classes if DETECTION_MANAGER to model the reporting behaviour.
|
||||||
--
|
--
|
||||||
@@ -27,7 +27,7 @@
|
|||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
-- 2) @{DetectionManager#DETECTION_REPORTING} class, extends @{DetectionManager#DETECTION_MANAGER}
|
-- 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.
|
-- 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:
|
-- 2.1) DETECTION_REPORTING constructor:
|
||||||
@@ -129,7 +129,6 @@ do -- DETECTION MANAGER
|
|||||||
self:SetRefreshTimeInterval( 30 )
|
self:SetRefreshTimeInterval( 30 )
|
||||||
self:SetReportDisplayTime( 25 )
|
self:SetReportDisplayTime( 25 )
|
||||||
|
|
||||||
self:E( { Detection = Detection } )
|
|
||||||
Detection:__Start( 3 )
|
Detection:__Start( 3 )
|
||||||
|
|
||||||
return self
|
return self
|
||||||
@@ -141,8 +140,6 @@ do -- DETECTION MANAGER
|
|||||||
|
|
||||||
function DETECTION_MANAGER:onafterReport( From, Event, To )
|
function DETECTION_MANAGER:onafterReport( From, Event, To )
|
||||||
|
|
||||||
self:E( "onafterReport" )
|
|
||||||
|
|
||||||
self:__Report( -self._RefreshTimeInterval )
|
self:__Report( -self._RefreshTimeInterval )
|
||||||
|
|
||||||
self:ProcessDetected( self.Detection )
|
self:ProcessDetected( self.Detection )
|
||||||
@@ -256,7 +253,6 @@ do -- DETECTION_REPORTING
|
|||||||
function DETECTION_REPORTING:ProcessDetected( Group, Detection )
|
function DETECTION_REPORTING:ProcessDetected( Group, Detection )
|
||||||
self:F2( Group )
|
self:F2( Group )
|
||||||
|
|
||||||
self:E( Group )
|
|
||||||
local DetectedMsg = {}
|
local DetectedMsg = {}
|
||||||
for DetectedAreaID, DetectedAreaData in pairs( Detection:GetDetectedAreas() ) do
|
for DetectedAreaID, DetectedAreaData in pairs( Detection:GetDetectedAreas() ) do
|
||||||
local DetectedArea = DetectedAreaData -- Functional.Detection#DETECTION_AREAS.DetectedArea
|
local DetectedArea = DetectedAreaData -- Functional.Detection#DETECTION_AREAS.DetectedArea
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
--- **Tasking** -- A MISSION is the main owner of a Mission orchestration within MOOSE.
|
--- **Tasking** -- A MISSION is the main owner of a Mission orchestration within MOOSE.
|
||||||
--
|
--
|
||||||
-- ====
|
-- ===
|
||||||
--
|
--
|
||||||
-- ### Author: **Sven Van de Velde (FlightControl)**
|
-- ### Author: **FlightControl**
|
||||||
--
|
--
|
||||||
-- ### Contributions:
|
-- ### Contributions:
|
||||||
--
|
--
|
||||||
@@ -46,6 +46,7 @@ function MISSION:New( CommandCenter, MissionName, MissionPriority, MissionBriefi
|
|||||||
self.MissionCoalition = MissionCoalition
|
self.MissionCoalition = MissionCoalition
|
||||||
|
|
||||||
self.Tasks = {}
|
self.Tasks = {}
|
||||||
|
self.TaskNumber = 0
|
||||||
self.PlayerNames = {} -- These are the players that achieved progress in the mission.
|
self.PlayerNames = {} -- These are the players that achieved progress in the mission.
|
||||||
|
|
||||||
self:SetStartState( "IDLE" )
|
self:SetStartState( "IDLE" )
|
||||||
@@ -271,16 +272,33 @@ end
|
|||||||
-- @param #string To
|
-- @param #string To
|
||||||
function MISSION:onenterCOMPLETED( From, Event, To )
|
function MISSION:onenterCOMPLETED( From, Event, To )
|
||||||
|
|
||||||
self:GetCommandCenter():MessageTypeToCoalition( self:GetName() .. " has been completed! Good job guys!", MESSAGE.Type.Information )
|
self:GetCommandCenter():MessageTypeToCoalition( self:GetText() .. " has been completed! Good job guys!", MESSAGE.Type.Information )
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Gets the mission name.
|
--- Gets the mission name.
|
||||||
-- @param #MISSION self
|
-- @param #MISSION self
|
||||||
-- @return #MISSION self
|
-- @return #MISSION self
|
||||||
function MISSION:GetName()
|
function MISSION:GetName()
|
||||||
|
return self.Name
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Gets the mission text.
|
||||||
|
-- @param #MISSION self
|
||||||
|
-- @return #MISSION self
|
||||||
|
function MISSION:GetText()
|
||||||
return string.format( 'Mission "%s (%s)"', self.Name, self.MissionPriority )
|
return string.format( 'Mission "%s (%s)"', self.Name, self.MissionPriority )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Gets the short mission text.
|
||||||
|
-- @param #MISSION self
|
||||||
|
-- @return #MISSION self
|
||||||
|
function MISSION:GetShortText()
|
||||||
|
return string.format( 'Mission "%s"', self.Name )
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Add a Unit to join the Mission.
|
--- Add a Unit to join the Mission.
|
||||||
-- For each Task within the Mission, the Unit is joined with the Task.
|
-- 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 was not part of a Task in the Mission, false is returned.
|
||||||
@@ -290,7 +308,7 @@ end
|
|||||||
-- @param Wrapper.Group#GROUP PlayerGroup The GROUP 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.
|
-- @return #boolean true if Unit is part of a Task in the Mission.
|
||||||
function MISSION:JoinUnit( PlayerUnit, PlayerGroup )
|
function MISSION:JoinUnit( PlayerUnit, PlayerGroup )
|
||||||
self:F( { PlayerUnit = PlayerUnit, PlayerGroup = PlayerGroup } )
|
self:I( { Mission = self:GetName(), PlayerUnit = PlayerUnit, PlayerGroup = PlayerGroup } )
|
||||||
|
|
||||||
local PlayerUnitAdded = false
|
local PlayerUnitAdded = false
|
||||||
|
|
||||||
@@ -385,9 +403,16 @@ end
|
|||||||
function MISSION:SetMenu( MenuTime )
|
function MISSION:SetMenu( MenuTime )
|
||||||
self:F( { self:GetName(), MenuTime } )
|
self:F( { self:GetName(), MenuTime } )
|
||||||
|
|
||||||
for _, TaskData in pairs( self:GetTasks() ) do
|
local MenuCount = {}
|
||||||
local Task = TaskData -- Tasking.Task#TASK
|
--for TaskID, Task in UTILS.spairs( self:GetTasks(), function( t, a, b ) return t[a]:ReportOrder( ReportGroup ) < t[b]:ReportOrder( ReportGroup ) end ) do
|
||||||
Task:SetMenu( MenuTime )
|
for TaskID, Task in pairs( self:GetTasks() ) do
|
||||||
|
local Task = Task -- Tasking.Task#TASK
|
||||||
|
local TaskType = Task:GetType()
|
||||||
|
MenuCount[TaskType] = MenuCount[TaskType] or 1
|
||||||
|
if MenuCount[TaskType] <= 10 then
|
||||||
|
Task:SetMenu( MenuTime )
|
||||||
|
MenuCount[TaskType] = MenuCount[TaskType] + 1
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -435,7 +460,7 @@ do -- Group Assignment
|
|||||||
local MissionGroupName = MissionGroup:GetName()
|
local MissionGroupName = MissionGroup:GetName()
|
||||||
|
|
||||||
self.AssignedGroups[MissionGroupName] = MissionGroup
|
self.AssignedGroups[MissionGroupName] = MissionGroup
|
||||||
self:E( string.format( "Mission %s is assigned to %s", MissionName, MissionGroupName ) )
|
self:I( string.format( "Mission %s is assigned to %s", MissionName, MissionGroupName ) )
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
@@ -483,10 +508,10 @@ function MISSION:GetRootMenu( TaskGroup ) -- R2.2
|
|||||||
local CommandCenter = self:GetCommandCenter()
|
local CommandCenter = self:GetCommandCenter()
|
||||||
local CommandCenterMenu = CommandCenter:GetMenu()
|
local CommandCenterMenu = CommandCenter:GetMenu()
|
||||||
|
|
||||||
local MissionName = self:GetName()
|
local MissionName = self:GetText()
|
||||||
--local MissionMenu = CommandCenterMenu:GetMenu( MissionName )
|
--local MissionMenu = CommandCenterMenu:GetMenu( MissionName )
|
||||||
|
|
||||||
self.MissionMenu = self.MissionMenu or MENU_COALITION:New( self.MissionCoalition, self:GetName(), CommandCenterMenu )
|
self.MissionMenu = MENU_COALITION:New( self.MissionCoalition, MissionName, CommandCenterMenu )
|
||||||
|
|
||||||
return self.MissionMenu
|
return self.MissionMenu
|
||||||
end
|
end
|
||||||
@@ -499,7 +524,6 @@ function MISSION:GetMenu( TaskGroup ) -- R2.1 -- Changed Menu Structure
|
|||||||
local CommandCenter = self:GetCommandCenter()
|
local CommandCenter = self:GetCommandCenter()
|
||||||
local CommandCenterMenu = CommandCenter:GetMenu()
|
local CommandCenterMenu = CommandCenter:GetMenu()
|
||||||
|
|
||||||
local MissionName = self:GetName()
|
|
||||||
--local MissionMenu = CommandCenterMenu:GetMenu( MissionName )
|
--local MissionMenu = CommandCenterMenu:GetMenu( MissionName )
|
||||||
|
|
||||||
self.MissionGroupMenu = self.MissionGroupMenu or {}
|
self.MissionGroupMenu = self.MissionGroupMenu or {}
|
||||||
@@ -507,21 +531,26 @@ function MISSION:GetMenu( TaskGroup ) -- R2.1 -- Changed Menu Structure
|
|||||||
|
|
||||||
local GroupMenu = self.MissionGroupMenu[TaskGroup]
|
local GroupMenu = self.MissionGroupMenu[TaskGroup]
|
||||||
|
|
||||||
self.MissionMenu = self.MissionMenu or MENU_COALITION:New( self.MissionCoalition, self:GetName(), CommandCenterMenu )
|
local CommandCenterText = CommandCenter:GetText()
|
||||||
|
CommandCenterMenu = MENU_GROUP:New( TaskGroup, CommandCenterText )
|
||||||
|
|
||||||
GroupMenu.BriefingMenu = GroupMenu.BriefingMenu or MENU_GROUP_COMMAND:New( TaskGroup, "Mission Briefing", self.MissionMenu, self.MenuReportBriefing, self, TaskGroup )
|
local MissionText = self:GetText()
|
||||||
|
self.MissionMenu = MENU_GROUP:New( TaskGroup, MissionText, CommandCenterMenu )
|
||||||
|
|
||||||
|
GroupMenu.BriefingMenu = MENU_GROUP_COMMAND:New( TaskGroup, "Mission Briefing", self.MissionMenu, self.MenuReportBriefing, self, TaskGroup )
|
||||||
|
|
||||||
GroupMenu.TaskReportsMenu = GroupMenu.TaskReportsMenu or MENU_GROUP:New( TaskGroup, "Task Reports", self.MissionMenu )
|
GroupMenu.MarkTasks = MENU_GROUP_COMMAND:New( TaskGroup, "Mark Task Locations on Map", self.MissionMenu, self.MarkTargetLocations, self, TaskGroup )
|
||||||
GroupMenu.ReportTasksMenu = GroupMenu.ReportTasksMenu or MENU_GROUP_COMMAND:New( TaskGroup, "Report Tasks", GroupMenu.TaskReportsMenu, self.MenuReportTasksSummary, self, TaskGroup )
|
GroupMenu.TaskReportsMenu = MENU_GROUP:New( TaskGroup, "Task Reports", self.MissionMenu )
|
||||||
GroupMenu.ReportPlannedTasksMenu = GroupMenu.ReportPlannedTasksMenu or MENU_GROUP_COMMAND:New( TaskGroup, "Report Planned Tasks", GroupMenu.TaskReportsMenu, self.MenuReportTasksPerStatus, self, TaskGroup, "Planned" )
|
GroupMenu.ReportTasksMenu = MENU_GROUP_COMMAND:New( TaskGroup, "Report Tasks Summary", GroupMenu.TaskReportsMenu, self.MenuReportTasksSummary, self, TaskGroup )
|
||||||
GroupMenu.ReportAssignedTasksMenu = GroupMenu.ReportAssignedTasksMenu or MENU_GROUP_COMMAND:New( TaskGroup, "Report Assigned Tasks", GroupMenu.TaskReportsMenu, self.MenuReportTasksPerStatus, self, TaskGroup, "Assigned" )
|
GroupMenu.ReportPlannedTasksMenu = MENU_GROUP_COMMAND:New( TaskGroup, "Report Planned Tasks", GroupMenu.TaskReportsMenu, self.MenuReportTasksPerStatus, self, TaskGroup, "Planned" )
|
||||||
GroupMenu.ReportSuccessTasksMenu = GroupMenu.ReportSuccessTasksMenu or MENU_GROUP_COMMAND:New( TaskGroup, "Report Successful Tasks", GroupMenu.TaskReportsMenu, self.MenuReportTasksPerStatus, self, TaskGroup, "Success" )
|
GroupMenu.ReportAssignedTasksMenu = MENU_GROUP_COMMAND:New( TaskGroup, "Report Assigned Tasks", GroupMenu.TaskReportsMenu, self.MenuReportTasksPerStatus, self, TaskGroup, "Assigned" )
|
||||||
GroupMenu.ReportFailedTasksMenu = GroupMenu.ReportFailedTasksMenu or MENU_GROUP_COMMAND:New( TaskGroup, "Report Failed Tasks", GroupMenu.TaskReportsMenu, self.MenuReportTasksPerStatus, self, TaskGroup, "Failed" )
|
GroupMenu.ReportSuccessTasksMenu = MENU_GROUP_COMMAND:New( TaskGroup, "Report Successful Tasks", GroupMenu.TaskReportsMenu, self.MenuReportTasksPerStatus, self, TaskGroup, "Success" )
|
||||||
GroupMenu.ReportHeldTasksMenu = GroupMenu.ReportHeldTasksMenu or MENU_GROUP_COMMAND:New( TaskGroup, "Report Held Tasks", GroupMenu.TaskReportsMenu, self.MenuReportTasksPerStatus, self, TaskGroup, "Hold" )
|
GroupMenu.ReportFailedTasksMenu = MENU_GROUP_COMMAND:New( TaskGroup, "Report Failed Tasks", GroupMenu.TaskReportsMenu, self.MenuReportTasksPerStatus, self, TaskGroup, "Failed" )
|
||||||
|
GroupMenu.ReportHeldTasksMenu = MENU_GROUP_COMMAND:New( TaskGroup, "Report Held Tasks", GroupMenu.TaskReportsMenu, self.MenuReportTasksPerStatus, self, TaskGroup, "Hold" )
|
||||||
|
|
||||||
GroupMenu.PlayerReportsMenu = GroupMenu.PlayerReportsMenu or MENU_GROUP:New( TaskGroup, "Statistics Reports", self.MissionMenu )
|
GroupMenu.PlayerReportsMenu = MENU_GROUP:New( TaskGroup, "Statistics Reports", self.MissionMenu )
|
||||||
GroupMenu.ReportMissionHistory = GroupMenu.ReportPlayersHistory or MENU_GROUP_COMMAND:New( TaskGroup, "Report Mission Progress", GroupMenu.PlayerReportsMenu, self.MenuReportPlayersProgress, self, TaskGroup )
|
GroupMenu.ReportMissionHistory = MENU_GROUP_COMMAND:New( TaskGroup, "Report Mission Progress", GroupMenu.PlayerReportsMenu, self.MenuReportPlayersProgress, self, TaskGroup )
|
||||||
GroupMenu.ReportPlayersPerTaskMenu = GroupMenu.ReportPlayersPerTaskMenu or MENU_GROUP_COMMAND:New( TaskGroup, "Report Players per Task", GroupMenu.PlayerReportsMenu, self.MenuReportPlayersPerTask, self, TaskGroup )
|
GroupMenu.ReportPlayersPerTaskMenu = MENU_GROUP_COMMAND:New( TaskGroup, "Report Players per Task", GroupMenu.PlayerReportsMenu, self.MenuReportPlayersPerTask, self, TaskGroup )
|
||||||
|
|
||||||
return self.MissionMenu
|
return self.MissionMenu
|
||||||
end
|
end
|
||||||
@@ -540,6 +569,18 @@ function MISSION:GetTask( TaskName )
|
|||||||
end
|
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 )
|
||||||
|
|
||||||
|
self.TaskNumber = self.TaskNumber + 1
|
||||||
|
|
||||||
|
return self.TaskNumber
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Register a @{Task} to be completed within the @{Mission}.
|
--- Register a @{Task} to be completed within the @{Mission}.
|
||||||
-- Note that there can be multiple @{Task}s registered to be completed.
|
-- 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.
|
-- Each Task can be set a certain Goals. The Mission will not be completed until all Goals are reached.
|
||||||
@@ -549,9 +590,7 @@ end
|
|||||||
function MISSION:AddTask( Task )
|
function MISSION:AddTask( Task )
|
||||||
|
|
||||||
local TaskName = Task:GetTaskName()
|
local TaskName = Task:GetTaskName()
|
||||||
self:F( TaskName )
|
self:I( { "==> Adding TASK ", MissionName = self:GetName(), TaskName = TaskName } )
|
||||||
|
|
||||||
self.Tasks[TaskName] = self.Tasks[TaskName] or { n = 0 }
|
|
||||||
|
|
||||||
self.Tasks[TaskName] = Task
|
self.Tasks[TaskName] = Task
|
||||||
|
|
||||||
@@ -560,6 +599,7 @@ function MISSION:AddTask( Task )
|
|||||||
return Task
|
return Task
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Removes a @{Task} to be completed within the @{Mission}.
|
--- Removes a @{Task} to be completed within the @{Mission}.
|
||||||
-- Note that there can be multiple @{Task}s registered to be completed.
|
-- 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.
|
-- Each Task can be set a certain Goals. The Mission will not be completed until all Goals are reached.
|
||||||
@@ -569,6 +609,7 @@ end
|
|||||||
function MISSION:RemoveTask( Task )
|
function MISSION:RemoveTask( Task )
|
||||||
|
|
||||||
local TaskName = Task:GetTaskName()
|
local TaskName = Task:GetTaskName()
|
||||||
|
self:I( { "<== Removing TASK ", MissionName = self:GetName(), TaskName = TaskName } )
|
||||||
|
|
||||||
self:F( TaskName )
|
self:F( TaskName )
|
||||||
self.Tasks[TaskName] = self.Tasks[TaskName] or { n = 0 }
|
self.Tasks[TaskName] = self.Tasks[TaskName] or { n = 0 }
|
||||||
@@ -584,21 +625,6 @@ function MISSION:RemoveTask( Task )
|
|||||||
return nil
|
return nil
|
||||||
end
|
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
|
|
||||||
|
|
||||||
--- Is the @{Mission} **COMPLETED**.
|
--- Is the @{Mission} **COMPLETED**.
|
||||||
-- @param #MISSION self
|
-- @param #MISSION self
|
||||||
-- @return #boolean
|
-- @return #boolean
|
||||||
@@ -700,7 +726,7 @@ function MISSION:ReportBriefing()
|
|||||||
local Report = REPORT:New()
|
local Report = REPORT:New()
|
||||||
|
|
||||||
-- List the name of the mission.
|
-- List the name of the mission.
|
||||||
local Name = self:GetName()
|
local Name = self:GetText()
|
||||||
|
|
||||||
-- Determine the status of the mission.
|
-- Determine the status of the mission.
|
||||||
local Status = "<" .. self:GetState() .. ">"
|
local Status = "<" .. self:GetState() .. ">"
|
||||||
@@ -713,57 +739,57 @@ function MISSION:ReportBriefing()
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Create a status report of the Mission.
|
----- Create a status report of the Mission.
|
||||||
-- This reports provides a one liner of the mission status. It indicates how many players and how many Tasks.
|
---- This reports provides a one liner of the mission status. It indicates how many players and how many Tasks.
|
||||||
--
|
----
|
||||||
-- Mission "<MissionName>" - Status "<MissionStatus>"
|
---- Mission "<MissionName>" - Status "<MissionStatus>"
|
||||||
-- - Task Types: <TaskType>, <TaskType>
|
---- - Task Types: <TaskType>, <TaskType>
|
||||||
-- - <xx> Planned Tasks (xp)
|
---- - <xx> Planned Tasks (xp)
|
||||||
-- - <xx> Assigned Tasks(xp)
|
---- - <xx> Assigned Tasks(xp)
|
||||||
-- - <xx> Success Tasks (xp)
|
---- - <xx> Success Tasks (xp)
|
||||||
-- - <xx> Hold Tasks (xp)
|
---- - <xx> Hold Tasks (xp)
|
||||||
-- - <xx> Cancelled Tasks (xp)
|
---- - <xx> Cancelled Tasks (xp)
|
||||||
-- - <xx> Aborted Tasks (xp)
|
---- - <xx> Aborted Tasks (xp)
|
||||||
-- - <xx> Failed Tasks (xp)
|
---- - <xx> Failed Tasks (xp)
|
||||||
--
|
----
|
||||||
-- @param #MISSION self
|
---- @param #MISSION self
|
||||||
-- @return #string
|
---- @return #string
|
||||||
function MISSION:ReportStatus()
|
--function MISSION:ReportSummary()
|
||||||
|
--
|
||||||
local Report = REPORT:New()
|
-- local Report = REPORT:New()
|
||||||
|
--
|
||||||
-- List the name of the mission.
|
-- -- List the name of the mission.
|
||||||
local Name = self:GetName()
|
-- local Name = self:GetText()
|
||||||
|
--
|
||||||
-- Determine the status of the mission.
|
-- -- Determine the status of the mission.
|
||||||
local Status = "<" .. self:GetState() .. ">"
|
-- local Status = "<" .. self:GetState() .. ">"
|
||||||
|
--
|
||||||
Report:Add( string.format( '%s - Status "%s"', Name, Status ) )
|
-- Report:Add( string.format( '%s - Status "%s"', Name, Status ) )
|
||||||
|
--
|
||||||
local TaskTypes = self:GetTaskTypes()
|
-- local TaskTypes = self:GetTaskTypes()
|
||||||
|
--
|
||||||
Report:Add( string.format( " - Task Types: %s", table.concat(TaskTypes, ", " ) ) )
|
-- Report:Add( string.format( " - Task Types: %s", table.concat(TaskTypes, ", " ) ) )
|
||||||
|
--
|
||||||
local TaskStatusList = { "Planned", "Assigned", "Success", "Hold", "Cancelled", "Aborted", "Failed" }
|
-- local TaskStatusList = { "Planned", "Assigned", "Success", "Hold", "Cancelled", "Aborted", "Failed" }
|
||||||
|
--
|
||||||
for TaskStatusID, TaskStatus in pairs( TaskStatusList ) do
|
-- for TaskStatusID, TaskStatus in pairs( TaskStatusList ) do
|
||||||
local TaskCount = 0
|
-- local TaskCount = 0
|
||||||
local TaskPlayerCount = 0
|
-- local TaskPlayerCount = 0
|
||||||
-- Determine how many tasks are remaining.
|
-- -- Determine how many tasks are remaining.
|
||||||
for TaskID, Task in pairs( self:GetTasks() ) do
|
-- for TaskID, Task in pairs( self:GetTasks() ) do
|
||||||
local Task = Task -- Tasking.Task#TASK
|
-- local Task = Task -- Tasking.Task#TASK
|
||||||
if Task:Is( TaskStatus ) then
|
-- if Task:Is( TaskStatus ) then
|
||||||
TaskCount = TaskCount + 1
|
-- TaskCount = TaskCount + 1
|
||||||
TaskPlayerCount = TaskPlayerCount + Task:GetPlayerCount()
|
-- TaskPlayerCount = TaskPlayerCount + Task:GetPlayerCount()
|
||||||
end
|
-- end
|
||||||
end
|
-- end
|
||||||
if TaskCount > 0 then
|
-- if TaskCount > 0 then
|
||||||
Report:Add( string.format( " - %02d %s Tasks (%dp)", TaskCount, TaskStatus, TaskPlayerCount ) )
|
-- Report:Add( string.format( " - %02d %s Tasks (%dp)", TaskCount, TaskStatus, TaskPlayerCount ) )
|
||||||
end
|
-- end
|
||||||
end
|
-- end
|
||||||
|
--
|
||||||
return Report:Text()
|
-- return Report:Text()
|
||||||
end
|
--end
|
||||||
|
|
||||||
|
|
||||||
--- Create an active player report of the Mission.
|
--- Create an active player report of the Mission.
|
||||||
@@ -781,7 +807,7 @@ function MISSION:ReportPlayersPerTask( ReportGroup )
|
|||||||
local Report = REPORT:New()
|
local Report = REPORT:New()
|
||||||
|
|
||||||
-- List the name of the mission.
|
-- List the name of the mission.
|
||||||
local Name = self:GetName()
|
local Name = self:GetText()
|
||||||
|
|
||||||
-- Determine the status of the mission.
|
-- Determine the status of the mission.
|
||||||
local Status = "<" .. self:GetState() .. ">"
|
local Status = "<" .. self:GetState() .. ">"
|
||||||
@@ -822,7 +848,7 @@ function MISSION:ReportPlayersProgress( ReportGroup )
|
|||||||
local Report = REPORT:New()
|
local Report = REPORT:New()
|
||||||
|
|
||||||
-- List the name of the mission.
|
-- List the name of the mission.
|
||||||
local Name = self:GetName()
|
local Name = self:GetText()
|
||||||
|
|
||||||
-- Determine the status of the mission.
|
-- Determine the status of the mission.
|
||||||
local Status = "<" .. self:GetState() .. ">"
|
local Status = "<" .. self:GetState() .. ">"
|
||||||
@@ -858,6 +884,32 @@ function MISSION:ReportPlayersProgress( ReportGroup )
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Mark all the target locations on the Map.
|
||||||
|
-- @param #MISSION self
|
||||||
|
-- @param Wrapper.Group#GROUP ReportGroup
|
||||||
|
-- @return #string
|
||||||
|
function MISSION:MarkTargetLocations( ReportGroup )
|
||||||
|
|
||||||
|
local Report = REPORT:New()
|
||||||
|
|
||||||
|
-- List the name of the mission.
|
||||||
|
local Name = self:GetText()
|
||||||
|
|
||||||
|
-- Determine the status of the mission.
|
||||||
|
local Status = "<" .. self:GetState() .. ">"
|
||||||
|
|
||||||
|
Report:Add( string.format( '%s - %s - All Tasks are marked on the map. Select a Task from the Mission Menu and Join the Task!!!', Name, Status ) )
|
||||||
|
|
||||||
|
-- Determine how many tasks are remaining.
|
||||||
|
for TaskID, Task in UTILS.spairs( self:GetTasks(), function( t, a, b ) return t[a]:ReportOrder( ReportGroup ) < t[b]:ReportOrder( ReportGroup ) end ) do
|
||||||
|
local Task = Task -- Tasking.Task#TASK
|
||||||
|
Task:MenuMarkToGroup( ReportGroup )
|
||||||
|
end
|
||||||
|
|
||||||
|
return Report:Text()
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Create a summary report of the Mission (one line).
|
--- Create a summary report of the Mission (one line).
|
||||||
-- @param #MISSION self
|
-- @param #MISSION self
|
||||||
-- @param Wrapper.Group#GROUP ReportGroup
|
-- @param Wrapper.Group#GROUP ReportGroup
|
||||||
@@ -867,7 +919,7 @@ function MISSION:ReportSummary( ReportGroup )
|
|||||||
local Report = REPORT:New()
|
local Report = REPORT:New()
|
||||||
|
|
||||||
-- List the name of the mission.
|
-- List the name of the mission.
|
||||||
local Name = self:GetName()
|
local Name = self:GetText()
|
||||||
|
|
||||||
-- Determine the status of the mission.
|
-- Determine the status of the mission.
|
||||||
local Status = "<" .. self:GetState() .. ">"
|
local Status = "<" .. self:GetState() .. ">"
|
||||||
@@ -893,7 +945,7 @@ function MISSION:ReportOverview( ReportGroup, TaskStatus )
|
|||||||
local Report = REPORT:New()
|
local Report = REPORT:New()
|
||||||
|
|
||||||
-- List the name of the mission.
|
-- List the name of the mission.
|
||||||
local Name = self:GetName()
|
local Name = self:GetText()
|
||||||
|
|
||||||
-- Determine the status of the mission.
|
-- Determine the status of the mission.
|
||||||
local Status = "<" .. self:GetState() .. ">"
|
local Status = "<" .. self:GetState() .. ">"
|
||||||
@@ -906,7 +958,7 @@ function MISSION:ReportOverview( ReportGroup, TaskStatus )
|
|||||||
local Task = Task -- Tasking.Task#TASK
|
local Task = Task -- Tasking.Task#TASK
|
||||||
if Task:Is( TaskStatus ) then
|
if Task:Is( TaskStatus ) then
|
||||||
Report:Add( string.rep( "-", 140 ) )
|
Report:Add( string.rep( "-", 140 ) )
|
||||||
Report:Add( " - " .. Task:ReportOverview( ReportGroup ) )
|
Report:Add( Task:ReportOverview( ReportGroup ) )
|
||||||
end
|
end
|
||||||
Tasks = Tasks + 1
|
Tasks = Tasks + 1
|
||||||
if Tasks >= 8 then
|
if Tasks >= 8 then
|
||||||
@@ -925,7 +977,7 @@ function MISSION:ReportDetails( ReportGroup )
|
|||||||
local Report = REPORT:New()
|
local Report = REPORT:New()
|
||||||
|
|
||||||
-- List the name of the mission.
|
-- List the name of the mission.
|
||||||
local Name = self:GetName()
|
local Name = self:GetText()
|
||||||
|
|
||||||
-- Determine the status of the mission.
|
-- Determine the status of the mission.
|
||||||
local Status = "<" .. self:GetState() .. ">"
|
local Status = "<" .. self:GetState() .. ">"
|
||||||
@@ -936,6 +988,7 @@ function MISSION:ReportDetails( ReportGroup )
|
|||||||
local TasksRemaining = 0
|
local TasksRemaining = 0
|
||||||
for TaskID, Task in pairs( self:GetTasks() ) do
|
for TaskID, Task in pairs( self:GetTasks() ) do
|
||||||
local Task = Task -- Tasking.Task#TASK
|
local Task = Task -- Tasking.Task#TASK
|
||||||
|
Report:Add( string.rep( "-", 140 ) )
|
||||||
Report:Add( Task:ReportDetails( ReportGroup ) )
|
Report:Add( Task:ReportDetails( ReportGroup ) )
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -964,6 +1017,17 @@ function MISSION:MenuReportBriefing( ReportGroup )
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Mark all the targets of the Mission on the Map.
|
||||||
|
-- @param #MISSION self
|
||||||
|
-- @param Wrapper.Group#GROUP ReportGroup
|
||||||
|
function MISSION:MenuMarkTargetLocations( ReportGroup )
|
||||||
|
|
||||||
|
local Report = self:MarkTargetLocations( ReportGroup )
|
||||||
|
|
||||||
|
self:GetCommandCenter():MessageTypeToGroup( Report, ReportGroup, MESSAGE.Type.Overview )
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--- Report the task summary.
|
--- Report the task summary.
|
||||||
-- @param #MISSION self
|
-- @param #MISSION self
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
--- **Tasking** -- This module contains the TASK class, the main engine to run human taskings.
|
--- **Tasking** -- This module contains the TASK class, the main engine to run human taskings.
|
||||||
--
|
--
|
||||||
-- ====
|
-- ===
|
||||||
--
|
--
|
||||||
-- ### Author: **Sven Van de Velde (FlightControl)**
|
-- ### Author: **FlightControl**
|
||||||
--
|
--
|
||||||
-- ### Contributions:
|
-- ### Contributions:
|
||||||
--
|
--
|
||||||
-- ====
|
-- ===
|
||||||
--
|
--
|
||||||
-- @module Task
|
-- @module Task
|
||||||
|
|
||||||
@@ -17,6 +17,7 @@
|
|||||||
-- @field Core.Fsm#FSM_PROCESS FsmTemplate
|
-- @field Core.Fsm#FSM_PROCESS FsmTemplate
|
||||||
-- @field Tasking.Mission#MISSION Mission
|
-- @field Tasking.Mission#MISSION Mission
|
||||||
-- @field Tasking.CommandCenter#COMMANDCENTER CommandCenter
|
-- @field Tasking.CommandCenter#COMMANDCENTER CommandCenter
|
||||||
|
-- @field Tasking.TaskInfo#TASKINFO TaskInfo
|
||||||
-- @extends Core.Fsm#FSM_TASK
|
-- @extends Core.Fsm#FSM_TASK
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -175,28 +176,34 @@ function TASK:New( Mission, SetGroupAssign, TaskName, TaskType, TaskBriefing )
|
|||||||
--- Goal Handler OnBefore for TASK
|
--- Goal Handler OnBefore for TASK
|
||||||
-- @function [parent=#TASK] OnBeforeGoal
|
-- @function [parent=#TASK] OnBeforeGoal
|
||||||
-- @param #TASK self
|
-- @param #TASK self
|
||||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable
|
|
||||||
-- @param #string From
|
-- @param #string From
|
||||||
-- @param #string Event
|
-- @param #string Event
|
||||||
-- @param #string To
|
-- @param #string To
|
||||||
|
-- @param Wrapper.Unit#UNIT PlayerUnit The @{Unit} of the player.
|
||||||
|
-- @param #string PlayerName The name of the player.
|
||||||
-- @return #boolean
|
-- @return #boolean
|
||||||
|
|
||||||
--- Goal Handler OnAfter for TASK
|
--- Goal Handler OnAfter for TASK
|
||||||
-- @function [parent=#TASK] OnAfterGoal
|
-- @function [parent=#TASK] OnAfterGoal
|
||||||
-- @param #TASK self
|
-- @param #TASK self
|
||||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable
|
|
||||||
-- @param #string From
|
-- @param #string From
|
||||||
-- @param #string Event
|
-- @param #string Event
|
||||||
-- @param #string To
|
-- @param #string To
|
||||||
|
-- @param Wrapper.Unit#UNIT PlayerUnit The @{Unit} of the player.
|
||||||
|
-- @param #string PlayerName The name of the player.
|
||||||
|
|
||||||
--- Goal Trigger for TASK
|
--- Goal Trigger for TASK
|
||||||
-- @function [parent=#TASK] Goal
|
-- @function [parent=#TASK] Goal
|
||||||
-- @param #TASK self
|
-- @param #TASK self
|
||||||
|
-- @param Wrapper.Unit#UNIT PlayerUnit The @{Unit} of the player.
|
||||||
|
-- @param #string PlayerName The name of the player.
|
||||||
|
|
||||||
--- Goal Asynchronous Trigger for TASK
|
--- Goal Asynchronous Trigger for TASK
|
||||||
-- @function [parent=#TASK] __Goal
|
-- @function [parent=#TASK] __Goal
|
||||||
-- @param #TASK self
|
-- @param #TASK self
|
||||||
-- @param #number Delay
|
-- @param #number Delay
|
||||||
|
-- @param Wrapper.Unit#UNIT PlayerUnit The @{Unit} of the player.
|
||||||
|
-- @param #string PlayerName The name of the player.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -206,7 +213,7 @@ function TASK:New( Mission, SetGroupAssign, TaskName, TaskType, TaskBriefing )
|
|||||||
self:AddTransition( { "Failed", "Aborted", "Cancelled" }, "Replan", "Planned" )
|
self:AddTransition( { "Failed", "Aborted", "Cancelled" }, "Replan", "Planned" )
|
||||||
self:AddTransition( "*", "TimeOut", "Cancelled" )
|
self:AddTransition( "*", "TimeOut", "Cancelled" )
|
||||||
|
|
||||||
self:E( "New TASK " .. TaskName )
|
self:F( "New TASK " .. TaskName )
|
||||||
|
|
||||||
self.Processes = {}
|
self.Processes = {}
|
||||||
self.Fsm = {}
|
self.Fsm = {}
|
||||||
@@ -224,7 +231,7 @@ function TASK:New( Mission, SetGroupAssign, TaskName, TaskType, TaskBriefing )
|
|||||||
|
|
||||||
self.FsmTemplate = self.FsmTemplate or FSM_PROCESS:New()
|
self.FsmTemplate = self.FsmTemplate or FSM_PROCESS:New()
|
||||||
|
|
||||||
self.TaskInfo = {}
|
self.TaskInfo = TASKINFO:New( self )
|
||||||
|
|
||||||
self.TaskProgress = {}
|
self.TaskProgress = {}
|
||||||
|
|
||||||
@@ -277,7 +284,7 @@ function TASK:JoinUnit( PlayerUnit, PlayerGroup )
|
|||||||
end
|
end
|
||||||
if self:IsStateAssigned() then
|
if self:IsStateAssigned() then
|
||||||
local IsGroupAssigned = self:IsGroupAssigned( PlayerGroup )
|
local IsGroupAssigned = self:IsGroupAssigned( PlayerGroup )
|
||||||
self:E( { IsGroupAssigned = IsGroupAssigned } )
|
self:F( { IsGroupAssigned = IsGroupAssigned } )
|
||||||
if IsGroupAssigned then
|
if IsGroupAssigned then
|
||||||
self:AssignToUnit( PlayerUnit )
|
self:AssignToUnit( PlayerUnit )
|
||||||
self:MessageToGroups( PlayerUnit:GetPlayerName() .. " joined Task " .. self:GetName() )
|
self:MessageToGroups( PlayerUnit:GetPlayerName() .. " joined Task " .. self:GetName() )
|
||||||
@@ -306,7 +313,7 @@ function TASK:AbortGroup( PlayerGroup )
|
|||||||
-- If the PlayerUnit was the last unit of the PlayerGroup, the menu needs to be removed from the Group.
|
-- If the PlayerUnit was the last unit of the PlayerGroup, the menu needs to be removed from the Group.
|
||||||
if self:IsStateAssigned() then
|
if self:IsStateAssigned() then
|
||||||
local IsGroupAssigned = self:IsGroupAssigned( PlayerGroup )
|
local IsGroupAssigned = self:IsGroupAssigned( PlayerGroup )
|
||||||
self:E( { IsGroupAssigned = IsGroupAssigned } )
|
self:F( { IsGroupAssigned = IsGroupAssigned } )
|
||||||
if IsGroupAssigned then
|
if IsGroupAssigned then
|
||||||
local PlayerName = PlayerGroup:GetUnit(1):GetPlayerName()
|
local PlayerName = PlayerGroup:GetUnit(1):GetPlayerName()
|
||||||
--self:MessageToGroups( PlayerName .. " aborted Task " .. self:GetName() )
|
--self:MessageToGroups( PlayerName .. " aborted Task " .. self:GetName() )
|
||||||
@@ -316,7 +323,7 @@ function TASK:AbortGroup( PlayerGroup )
|
|||||||
-- Now check if the task needs to go to hold...
|
-- Now check if the task needs to go to hold...
|
||||||
-- It will go to hold, if there are no players in the mission...
|
-- It will go to hold, if there are no players in the mission...
|
||||||
|
|
||||||
PlayerGroups:Flush()
|
PlayerGroups:Flush( self )
|
||||||
local IsRemaining = false
|
local IsRemaining = false
|
||||||
for GroupName, AssignedGroup in pairs( PlayerGroups:GetSet() or {} ) do
|
for GroupName, AssignedGroup in pairs( PlayerGroups:GetSet() or {} ) do
|
||||||
if self:IsGroupAssigned( AssignedGroup ) == true then
|
if self:IsGroupAssigned( AssignedGroup ) == true then
|
||||||
@@ -358,7 +365,7 @@ function TASK:CrashGroup( PlayerGroup )
|
|||||||
-- If the PlayerUnit was the last unit of the PlayerGroup, the menu needs to be removed from the Group.
|
-- If the PlayerUnit was the last unit of the PlayerGroup, the menu needs to be removed from the Group.
|
||||||
if self:IsStateAssigned() then
|
if self:IsStateAssigned() then
|
||||||
local IsGroupAssigned = self:IsGroupAssigned( PlayerGroup )
|
local IsGroupAssigned = self:IsGroupAssigned( PlayerGroup )
|
||||||
self:E( { IsGroupAssigned = IsGroupAssigned } )
|
self:F( { IsGroupAssigned = IsGroupAssigned } )
|
||||||
if IsGroupAssigned then
|
if IsGroupAssigned then
|
||||||
local PlayerName = PlayerGroup:GetUnit(1):GetPlayerName()
|
local PlayerName = PlayerGroup:GetUnit(1):GetPlayerName()
|
||||||
self:MessageToGroups( PlayerName .. " crashed! " )
|
self:MessageToGroups( PlayerName .. " crashed! " )
|
||||||
@@ -367,7 +374,7 @@ function TASK:CrashGroup( PlayerGroup )
|
|||||||
-- Now check if the task needs to go to hold...
|
-- Now check if the task needs to go to hold...
|
||||||
-- It will go to hold, if there are no players in the mission...
|
-- It will go to hold, if there are no players in the mission...
|
||||||
|
|
||||||
PlayerGroups:Flush()
|
PlayerGroups:Flush( self )
|
||||||
local IsRemaining = false
|
local IsRemaining = false
|
||||||
for GroupName, AssignedGroup in pairs( PlayerGroups:GetSet() or {} ) do
|
for GroupName, AssignedGroup in pairs( PlayerGroups:GetSet() or {} ) do
|
||||||
if self:IsGroupAssigned( AssignedGroup ) == true then
|
if self:IsGroupAssigned( AssignedGroup ) == true then
|
||||||
@@ -420,11 +427,11 @@ do -- Group Assignment
|
|||||||
local TaskGroupName = TaskGroup:GetName()
|
local TaskGroupName = TaskGroup:GetName()
|
||||||
|
|
||||||
if self.AssignedGroups[TaskGroupName] then
|
if self.AssignedGroups[TaskGroupName] then
|
||||||
self:T( { "Task is assigned to:", TaskGroup:GetName() } )
|
--self:T( { "Task is assigned to:", TaskGroup:GetName() } )
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
self:T( { "Task is not assigned to:", TaskGroup:GetName() } )
|
--self:T( { "Task is not assigned to:", TaskGroup:GetName() } )
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -439,7 +446,7 @@ do -- Group Assignment
|
|||||||
local TaskGroupName = TaskGroup:GetName()
|
local TaskGroupName = TaskGroup:GetName()
|
||||||
|
|
||||||
self.AssignedGroups[TaskGroupName] = TaskGroup
|
self.AssignedGroups[TaskGroupName] = TaskGroup
|
||||||
self:E( string.format( "Task %s is assigned to %s", TaskName, TaskGroupName ) )
|
self:F( string.format( "Task %s is assigned to %s", TaskName, TaskGroupName ) )
|
||||||
|
|
||||||
-- Set the group to be assigned at mission level. This allows to decide the menu options on mission level for this group.
|
-- Set the group to be assigned at mission level. This allows to decide the menu options on mission level for this group.
|
||||||
self:GetMission():SetGroupAssigned( TaskGroup )
|
self:GetMission():SetGroupAssigned( TaskGroup )
|
||||||
@@ -469,7 +476,7 @@ do -- Group Assignment
|
|||||||
local TaskGroupName = TaskGroup:GetName()
|
local TaskGroupName = TaskGroup:GetName()
|
||||||
|
|
||||||
self.AssignedGroups[TaskGroupName] = nil
|
self.AssignedGroups[TaskGroupName] = nil
|
||||||
--self:E( string.format( "Task %s is unassigned to %s", TaskName, TaskGroupName ) )
|
--self:F( string.format( "Task %s is unassigned to %s", TaskName, TaskGroupName ) )
|
||||||
|
|
||||||
-- Set the group to be assigned at mission level. This allows to decide the menu options on mission level for this group.
|
-- Set the group to be assigned at mission level. This allows to decide the menu options on mission level for this group.
|
||||||
self:GetMission():ClearGroupAssignment( TaskGroup )
|
self:GetMission():ClearGroupAssignment( TaskGroup )
|
||||||
@@ -510,7 +517,7 @@ do -- Group Assignment
|
|||||||
for UnitID, UnitData in pairs( TaskUnits ) do
|
for UnitID, UnitData in pairs( TaskUnits ) do
|
||||||
local TaskUnit = UnitData -- Wrapper.Unit#UNIT
|
local TaskUnit = UnitData -- Wrapper.Unit#UNIT
|
||||||
local PlayerName = TaskUnit:GetPlayerName()
|
local PlayerName = TaskUnit:GetPlayerName()
|
||||||
self:E(PlayerName)
|
self:F(PlayerName)
|
||||||
if PlayerName ~= nil and PlayerName ~= "" then
|
if PlayerName ~= nil and PlayerName ~= "" then
|
||||||
self:AssignToUnit( TaskUnit )
|
self:AssignToUnit( TaskUnit )
|
||||||
CommandCenter:MessageToGroup(
|
CommandCenter:MessageToGroup(
|
||||||
@@ -559,7 +566,7 @@ end
|
|||||||
function TASK:HasGroup( FindGroup )
|
function TASK:HasGroup( FindGroup )
|
||||||
|
|
||||||
local SetAttackGroup = self:GetGroups()
|
local SetAttackGroup = self:GetGroups()
|
||||||
return SetAttackGroup:FindGroup(FindGroup)
|
return SetAttackGroup:FindGroup( FindGroup:GetName() )
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -613,7 +620,7 @@ function TASK:MessageToGroups( Message )
|
|||||||
local Mission = self:GetMission()
|
local Mission = self:GetMission()
|
||||||
local CC = Mission:GetCommandCenter()
|
local CC = Mission:GetCommandCenter()
|
||||||
|
|
||||||
for TaskGroupName, TaskGroup in pairs( self.SetGroup:GetSet() ) do
|
for TaskGroupName, TaskGroup in pairs( self.SetGroup:GetAliveSet() ) do
|
||||||
local TaskGroup = TaskGroup -- Wrapper.Group#GROUP
|
local TaskGroup = TaskGroup -- Wrapper.Group#GROUP
|
||||||
CC:MessageToGroup( Message, TaskGroup, TaskGroup:GetName() )
|
CC:MessageToGroup( Message, TaskGroup, TaskGroup:GetName() )
|
||||||
end
|
end
|
||||||
@@ -625,7 +632,7 @@ end
|
|||||||
function TASK:SendBriefingToAssignedGroups()
|
function TASK:SendBriefingToAssignedGroups()
|
||||||
self:F2()
|
self:F2()
|
||||||
|
|
||||||
for TaskGroupName, TaskGroup in pairs( self.SetGroup:GetSet() ) do
|
for TaskGroupName, TaskGroup in pairs( self.SetGroup:GetAliveSet() ) do
|
||||||
|
|
||||||
if self:IsGroupAssigned( TaskGroup ) then
|
if self:IsGroupAssigned( TaskGroup ) then
|
||||||
TaskGroup:Message( self.TaskBriefing, 60 )
|
TaskGroup:Message( self.TaskBriefing, 60 )
|
||||||
@@ -639,7 +646,7 @@ end
|
|||||||
function TASK:UnAssignFromGroups()
|
function TASK:UnAssignFromGroups()
|
||||||
self:F2()
|
self:F2()
|
||||||
|
|
||||||
for TaskGroupName, TaskGroup in pairs( self.SetGroup:GetSet() ) do
|
for TaskGroupName, TaskGroup in pairs( self.SetGroup:GetAliveSet() ) do
|
||||||
if self:IsGroupAssigned(TaskGroup) then
|
if self:IsGroupAssigned(TaskGroup) then
|
||||||
self:UnAssignFromGroup( TaskGroup )
|
self:UnAssignFromGroup( TaskGroup )
|
||||||
end
|
end
|
||||||
@@ -654,7 +661,7 @@ end
|
|||||||
function TASK:HasAliveUnits()
|
function TASK:HasAliveUnits()
|
||||||
self:F()
|
self:F()
|
||||||
|
|
||||||
for TaskGroupID, TaskGroup in pairs( self.SetGroup:GetSet() ) do
|
for TaskGroupID, TaskGroup in pairs( self.SetGroup:GetAliveSet() ) do
|
||||||
if self:IsStateAssigned() then
|
if self:IsStateAssigned() then
|
||||||
if self:IsGroupAssigned( TaskGroup ) then
|
if self:IsGroupAssigned( TaskGroup ) then
|
||||||
for TaskUnitID, TaskUnit in pairs( TaskGroup:GetUnits() ) do
|
for TaskUnitID, TaskUnit in pairs( TaskGroup:GetUnits() ) do
|
||||||
@@ -679,9 +686,9 @@ function TASK:SetMenu( MenuTime ) --R2.1 Mission Reports and Task Reports added.
|
|||||||
self:F( { self:GetName(), MenuTime } )
|
self:F( { self:GetName(), MenuTime } )
|
||||||
|
|
||||||
--self.SetGroup:Flush()
|
--self.SetGroup:Flush()
|
||||||
for TaskGroupID, TaskGroupData in pairs( self.SetGroup:GetSet() ) do
|
for TaskGroupID, TaskGroupData in pairs( self.SetGroup:GetAliveSet() ) do
|
||||||
local TaskGroup = TaskGroupData -- Wrapper.Group#GROUP
|
local TaskGroup = TaskGroupData -- Wrapper.Group#GROUP
|
||||||
if TaskGroup:IsAlive() and TaskGroup:GetPlayerNames() then
|
if TaskGroup:IsAlive() == true and TaskGroup:GetPlayerNames() then
|
||||||
|
|
||||||
-- Set Mission Menus
|
-- Set Mission Menus
|
||||||
|
|
||||||
@@ -726,11 +733,10 @@ function TASK:SetPlannedMenuForGroup( TaskGroup, MenuTime )
|
|||||||
local CommandCenterMenu = CommandCenter:GetMenu()
|
local CommandCenterMenu = CommandCenter:GetMenu()
|
||||||
|
|
||||||
local TaskType = self:GetType()
|
local TaskType = self:GetType()
|
||||||
-- local TaskThreatLevel = self.TaskInfo["ThreatLevel"]
|
|
||||||
-- local TaskThreatLevelString = TaskThreatLevel and " [" .. string.rep( "■", TaskThreatLevel ) .. "]" or " []"
|
|
||||||
local TaskPlayerCount = self:GetPlayerCount()
|
local TaskPlayerCount = self:GetPlayerCount()
|
||||||
local TaskPlayerString = string.format( " (%dp)", TaskPlayerCount )
|
local TaskPlayerString = string.format( " (%dp)", TaskPlayerCount )
|
||||||
local TaskText = string.format( "%s%s", self:GetName(), TaskPlayerString ) --, TaskThreatLevelString )
|
-- local TaskText = string.format( "%s%s", self:GetName(), TaskPlayerString ) --, TaskThreatLevelString )
|
||||||
|
local TaskText = string.format( "%s", self:GetName() )
|
||||||
local TaskName = string.format( "%s", self:GetName() )
|
local TaskName = string.format( "%s", self:GetName() )
|
||||||
|
|
||||||
local MissionMenu = Mission:GetMenu( TaskGroup )
|
local MissionMenu = Mission:GetMenu( TaskGroup )
|
||||||
@@ -739,16 +745,17 @@ function TASK:SetPlannedMenuForGroup( TaskGroup, MenuTime )
|
|||||||
--local MissionMenu = Mission:GetMenu( TaskGroup )
|
--local MissionMenu = Mission:GetMenu( TaskGroup )
|
||||||
|
|
||||||
self.MenuPlanned = self.MenuPlanned or {}
|
self.MenuPlanned = self.MenuPlanned or {}
|
||||||
self.MenuPlanned[TaskGroup] = MENU_GROUP:New( TaskGroup, "Join Planned Task", MissionMenu, Mission.MenuReportTasksPerStatus, Mission, TaskGroup, "Planned" ):SetTime( MenuTime ):SetTag( "Tasking" )
|
self.MenuPlanned[TaskGroup] = MENU_GROUP_DELAYED:New( TaskGroup, "Join Planned Task", MissionMenu, Mission.MenuReportTasksPerStatus, Mission, TaskGroup, "Planned" ):SetTime( MenuTime ):SetTag( "Tasking" )
|
||||||
local TaskTypeMenu = MENU_GROUP:New( TaskGroup, TaskType, self.MenuPlanned[TaskGroup] ):SetTime( MenuTime ):SetTag( "Tasking" ):SetRemoveParent( true )
|
local TaskTypeMenu = MENU_GROUP_DELAYED:New( TaskGroup, TaskType, self.MenuPlanned[TaskGroup] ):SetTime( MenuTime ):SetTag( "Tasking" )
|
||||||
local TaskTypeMenu = MENU_GROUP:New( TaskGroup, TaskText, TaskTypeMenu ):SetTime( MenuTime ):SetTag( "Tasking" ):SetRemoveParent( true )
|
local TaskTypeMenu = MENU_GROUP_DELAYED:New( TaskGroup, TaskText, TaskTypeMenu ):SetTime( MenuTime ):SetTag( "Tasking" )
|
||||||
local ReportTaskMenu = MENU_GROUP_COMMAND:New( TaskGroup, string.format( "Report Task Status" ), TaskTypeMenu, self.MenuTaskStatus, self, TaskGroup ):SetTime( MenuTime ):SetTag( "Tasking" ):SetRemoveParent( true )
|
|
||||||
|
|
||||||
if not Mission:IsGroupAssigned( TaskGroup ) then
|
if not Mission:IsGroupAssigned( TaskGroup ) then
|
||||||
self:F( { "Replacing Join Task menu" } )
|
--self:F( { "Replacing Join Task menu" } )
|
||||||
local JoinTaskMenu = MENU_GROUP_COMMAND:New( TaskGroup, string.format( "Join Task" ), TaskTypeMenu, self.MenuAssignToGroup, self, TaskGroup ):SetTime( MenuTime ):SetTag( "Tasking" ):SetRemoveParent( true )
|
local JoinTaskMenu = MENU_GROUP_COMMAND_DELAYED:New( TaskGroup, string.format( "Join Task" ), TaskTypeMenu, self.MenuAssignToGroup, self, TaskGroup ):SetTime( MenuTime ):SetTag( "Tasking" )
|
||||||
local MarkTaskMenu = MENU_GROUP_COMMAND:New( TaskGroup, string.format( "Mark Task on Map" ), TaskTypeMenu, self.MenuMarkToGroup, self, TaskGroup ):SetTime( MenuTime ):SetTag( "Tasking" ):SetRemoveParent( true )
|
local MarkTaskMenu = MENU_GROUP_COMMAND_DELAYED:New( TaskGroup, string.format( "Mark Task Location on Map" ), TaskTypeMenu, self.MenuMarkToGroup, self, TaskGroup ):SetTime( MenuTime ):SetTag( "Tasking" )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local ReportTaskMenu = MENU_GROUP_COMMAND_DELAYED:New( TaskGroup, string.format( "Report Task Details" ), TaskTypeMenu, self.MenuTaskStatus, self, TaskGroup ):SetTime( MenuTime ):SetTag( "Tasking" )
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
@@ -767,8 +774,6 @@ function TASK:SetAssignedMenuForGroup( TaskGroup, MenuTime )
|
|||||||
local CommandCenterMenu = CommandCenter:GetMenu()
|
local CommandCenterMenu = CommandCenter:GetMenu()
|
||||||
|
|
||||||
local TaskType = self:GetType()
|
local TaskType = self:GetType()
|
||||||
-- local TaskThreatLevel = self.TaskInfo["ThreatLevel"]
|
|
||||||
-- local TaskThreatLevelString = TaskThreatLevel and " [" .. string.rep( "■", TaskThreatLevel ) .. "]" or " []"
|
|
||||||
local TaskPlayerCount = self:GetPlayerCount()
|
local TaskPlayerCount = self:GetPlayerCount()
|
||||||
local TaskPlayerString = string.format( " (%dp)", TaskPlayerCount )
|
local TaskPlayerString = string.format( " (%dp)", TaskPlayerCount )
|
||||||
local TaskText = string.format( "%s%s", self:GetName(), TaskPlayerString ) --, TaskThreatLevelString )
|
local TaskText = string.format( "%s%s", self:GetName(), TaskPlayerString ) --, TaskThreatLevelString )
|
||||||
@@ -779,9 +784,10 @@ function TASK:SetAssignedMenuForGroup( TaskGroup, MenuTime )
|
|||||||
-- local MissionMenu = Mission:GetMenu( TaskGroup )
|
-- local MissionMenu = Mission:GetMenu( TaskGroup )
|
||||||
|
|
||||||
self.MenuAssigned = self.MenuAssigned or {}
|
self.MenuAssigned = self.MenuAssigned or {}
|
||||||
self.MenuAssigned[TaskGroup] = MENU_GROUP:New( TaskGroup, string.format( "Assigned Task %s", TaskName ), MissionMenu ):SetTime( MenuTime ):SetTag( "Tasking" )
|
self.MenuAssigned[TaskGroup] = MENU_GROUP_DELAYED:New( TaskGroup, string.format( "Assigned Task %s", TaskName ), MissionMenu ):SetTime( MenuTime ):SetTag( "Tasking" )
|
||||||
local TaskTypeMenu = MENU_GROUP_COMMAND:New( TaskGroup, string.format( "Report Task Status" ), self.MenuAssigned[TaskGroup], self.MenuTaskStatus, self, TaskGroup ):SetTime( MenuTime ):SetTag( "Tasking" ):SetRemoveParent( true )
|
local TaskMenu = MENU_GROUP_COMMAND_DELAYED:New( TaskGroup, string.format( "Abort Task" ), self.MenuAssigned[TaskGroup], self.MenuTaskAbort, self, TaskGroup ):SetTime( MenuTime ):SetTag( "Tasking" )
|
||||||
local TaskMenu = MENU_GROUP_COMMAND:New( TaskGroup, string.format( "Abort Group from Task" ), self.MenuAssigned[TaskGroup], self.MenuTaskAbort, self, TaskGroup ):SetTime( MenuTime ):SetTag( "Tasking" ):SetRemoveParent( true )
|
local MarkMenu = MENU_GROUP_COMMAND_DELAYED:New( TaskGroup, string.format( "Mark Task Location on Map" ), self.MenuAssigned[TaskGroup], self.MenuMarkToGroup, self, TaskGroup ):SetTime( MenuTime ):SetTag( "Tasking" )
|
||||||
|
local TaskTypeMenu = MENU_GROUP_COMMAND_DELAYED:New( TaskGroup, string.format( "Report Task Details" ), self.MenuAssigned[TaskGroup], self.MenuTaskStatus, self, TaskGroup ):SetTime( MenuTime ):SetTag( "Tasking" )
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
@@ -793,9 +799,11 @@ end
|
|||||||
function TASK:RemoveMenu( MenuTime )
|
function TASK:RemoveMenu( MenuTime )
|
||||||
self:F( { self:GetName(), MenuTime } )
|
self:F( { self:GetName(), MenuTime } )
|
||||||
|
|
||||||
for TaskGroupID, TaskGroup in pairs( self.SetGroup:GetSet() ) do
|
for TaskGroupID, TaskGroup in pairs( self.SetGroup:GetAliveSet() ) do
|
||||||
local TaskGroup = TaskGroup -- Wrapper.Group#GROUP
|
local TaskGroup = TaskGroup -- Wrapper.Group#GROUP
|
||||||
self:RefreshMenus( TaskGroup, MenuTime )
|
if TaskGroup:IsAlive() == true and TaskGroup:GetPlayerNames() then
|
||||||
|
self:RefreshMenus( TaskGroup, MenuTime )
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -823,11 +831,13 @@ function TASK:RefreshMenus( TaskGroup, MenuTime )
|
|||||||
local AssignedMenu = self.MenuAssigned[TaskGroup]
|
local AssignedMenu = self.MenuAssigned[TaskGroup]
|
||||||
|
|
||||||
if PlannedMenu then
|
if PlannedMenu then
|
||||||
PlannedMenu:Remove( MenuTime , "Tasking")
|
self.MenuPlanned[TaskGroup] = PlannedMenu:Remove( MenuTime , "Tasking" )
|
||||||
|
PlannedMenu:Set()
|
||||||
end
|
end
|
||||||
|
|
||||||
if AssignedMenu then
|
if AssignedMenu then
|
||||||
AssignedMenu:Remove( MenuTime, "Tasking" )
|
self.MenuAssigned[TaskGroup] = AssignedMenu:Remove( MenuTime, "Tasking" )
|
||||||
|
AssignedMenu:Set()
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -855,7 +865,7 @@ end
|
|||||||
-- @param Wrapper.Group#GROUP TaskGroup
|
-- @param Wrapper.Group#GROUP TaskGroup
|
||||||
function TASK:MenuAssignToGroup( TaskGroup )
|
function TASK:MenuAssignToGroup( TaskGroup )
|
||||||
|
|
||||||
self:E( "Join Task menu selected")
|
self:F( "Join Task menu selected")
|
||||||
|
|
||||||
self:AssignToGroup( TaskGroup )
|
self:AssignToGroup( TaskGroup )
|
||||||
end
|
end
|
||||||
@@ -863,51 +873,18 @@ end
|
|||||||
--- @param #TASK self
|
--- @param #TASK self
|
||||||
-- @param Wrapper.Group#GROUP TaskGroup
|
-- @param Wrapper.Group#GROUP TaskGroup
|
||||||
function TASK:MenuMarkToGroup( TaskGroup )
|
function TASK:MenuMarkToGroup( TaskGroup )
|
||||||
|
self:F()
|
||||||
|
|
||||||
self:E( "Mark Task menu selected")
|
self:UpdateTaskInfo( self.DetectedItem )
|
||||||
|
|
||||||
self:UpdateTaskInfo()
|
|
||||||
|
|
||||||
local Report = REPORT:New():SetIndent( 0 )
|
local Report = REPORT:New():SetIndent( 0 )
|
||||||
|
|
||||||
-- List the name of the Task.
|
self.TaskInfo:Report( Report, "M", TaskGroup )
|
||||||
local Name = self:GetName()
|
|
||||||
Report:Add( Name .. ": " .. self:GetTaskBriefing() )
|
|
||||||
|
|
||||||
for TaskInfoID, TaskInfo in pairs( self.TaskInfo, function( t, a, b ) return t[a].TaskInfoOrder < t[b].TaskInfoOrder end ) do
|
|
||||||
|
|
||||||
local TaskInfoIDText = "" --string.format( "%s: ", TaskInfoID )
|
|
||||||
|
|
||||||
if type( TaskInfo.TaskInfoText ) == "string" then
|
|
||||||
if TaskInfoID == "Targets" then
|
|
||||||
else
|
|
||||||
Report:Add( TaskInfoIDText .. TaskInfo.TaskInfoText )
|
|
||||||
end
|
|
||||||
elseif type( TaskInfo ) == "table" then
|
|
||||||
if TaskInfoID == "Coordinates" then
|
|
||||||
--local ToCoordinate = TaskInfo.TaskInfoText -- Core.Point#COORDINATE
|
|
||||||
--Report:Add( TaskInfoIDText .. ToCoordinate:ToString() )
|
|
||||||
else
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
local Coordinate = self:GetInfo( "Coordinates" ) -- Core.Point#COORDINATE
|
|
||||||
|
|
||||||
local Velocity = self.TargetSetUnit:GetVelocity()
|
|
||||||
local Heading = self.TargetSetUnit:GetHeading()
|
|
||||||
|
|
||||||
Coordinate:SetHeading( Heading )
|
|
||||||
Coordinate:SetVelocity( Velocity )
|
|
||||||
|
|
||||||
Report:Add( "Targets are" .. Coordinate:GetMovingText() .. "." )
|
|
||||||
|
|
||||||
|
local TargetCoordinate = self.TaskInfo:GetData( "Coordinate" ) -- Core.Point#COORDINATE
|
||||||
local MarkText = Report:Text( ", " )
|
local MarkText = Report:Text( ", " )
|
||||||
|
self:F( { Coordinate = TargetCoordinate, MarkText = MarkText } )
|
||||||
self:F( { Coordinate = Coordinate, MarkText = MarkText } )
|
TargetCoordinate:MarkToGroup( MarkText, TaskGroup )
|
||||||
|
|
||||||
Coordinate:MarkToGroup( MarkText, TaskGroup )
|
|
||||||
--Coordinate:MarkToAll( Briefing )
|
--Coordinate:MarkToAll( Briefing )
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1004,10 +981,10 @@ end
|
|||||||
function TASK:RemoveStateMachine( TaskUnit )
|
function TASK:RemoveStateMachine( TaskUnit )
|
||||||
self:F( { TaskUnit = TaskUnit:GetName(), HasFsm = ( self.Fsm[TaskUnit] ~= nil ) } )
|
self:F( { TaskUnit = TaskUnit:GetName(), HasFsm = ( self.Fsm[TaskUnit] ~= nil ) } )
|
||||||
|
|
||||||
--self:E( self.Fsm )
|
--self:F( self.Fsm )
|
||||||
--for TaskUnitT, Fsm in pairs( self.Fsm ) do
|
--for TaskUnitT, Fsm in pairs( self.Fsm ) do
|
||||||
--local Fsm = Fsm -- Core.Fsm#FSM_PROCESS
|
--local Fsm = Fsm -- Core.Fsm#FSM_PROCESS
|
||||||
--self:E( TaskUnitT )
|
--self:F( TaskUnitT )
|
||||||
--self.Fsm[TaskUnit] = nil
|
--self.Fsm[TaskUnit] = nil
|
||||||
--end
|
--end
|
||||||
|
|
||||||
@@ -1017,7 +994,7 @@ function TASK:RemoveStateMachine( TaskUnit )
|
|||||||
end
|
end
|
||||||
|
|
||||||
collectgarbage()
|
collectgarbage()
|
||||||
self:E( "Garbage Collected, Processes should be finalized now ...")
|
self:F( "Garbage Collected, Processes should be finalized now ...")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@@ -1072,30 +1049,6 @@ function TASK:SetType( TaskType )
|
|||||||
self.TaskType = TaskType
|
self.TaskType = TaskType
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Sets the Information on the Task
|
|
||||||
-- @param #TASK self
|
|
||||||
-- @param #string TaskInfo The key and title of the task information.
|
|
||||||
-- @param #string TaskInfoText The Task info text.
|
|
||||||
-- @param #number TaskInfoOrder The ordering, a number between 0 and 99.
|
|
||||||
function TASK:SetInfo( TaskInfo, TaskInfoText, TaskInfoOrder )
|
|
||||||
|
|
||||||
self.TaskInfo = self.TaskInfo or {}
|
|
||||||
self.TaskInfo[TaskInfo] = self.TaskInfo[TaskInfo] or {}
|
|
||||||
self.TaskInfo[TaskInfo].TaskInfoText = TaskInfoText
|
|
||||||
self.TaskInfo[TaskInfo].TaskInfoOrder = TaskInfoOrder
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Gets the Information of the Task
|
|
||||||
-- @param #TASK self
|
|
||||||
-- @param #string TaskInfo The key and title of the task information.
|
|
||||||
-- @return #string TaskInfoText The Task info text.
|
|
||||||
function TASK:GetInfo( TaskInfo )
|
|
||||||
|
|
||||||
self.TaskInfo = self.TaskInfo or {}
|
|
||||||
self.TaskInfo[TaskInfo] = self.TaskInfo[TaskInfo] or {}
|
|
||||||
return self.TaskInfo[TaskInfo].TaskInfoText
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Gets the Type of the Task
|
--- Gets the Type of the Task
|
||||||
-- @param #TASK self
|
-- @param #TASK self
|
||||||
-- @return #string TaskType
|
-- @return #string TaskType
|
||||||
@@ -1233,7 +1186,7 @@ end
|
|||||||
-- @param #string TaskBriefing
|
-- @param #string TaskBriefing
|
||||||
-- @return #TASK self
|
-- @return #TASK self
|
||||||
function TASK:SetBriefing( TaskBriefing )
|
function TASK:SetBriefing( TaskBriefing )
|
||||||
self:E(TaskBriefing)
|
self:F(TaskBriefing)
|
||||||
self.TaskBriefing = TaskBriefing
|
self.TaskBriefing = TaskBriefing
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
@@ -1255,10 +1208,9 @@ end
|
|||||||
-- @param #string To
|
-- @param #string To
|
||||||
function TASK:onenterAssigned( From, Event, To, PlayerUnit, PlayerName )
|
function TASK:onenterAssigned( From, Event, To, PlayerUnit, PlayerName )
|
||||||
|
|
||||||
|
|
||||||
--- This test is required, because the state transition will be fired also when the state does not change in case of an event.
|
--- This test is required, because the state transition will be fired also when the state does not change in case of an event.
|
||||||
if From ~= "Assigned" then
|
if From ~= "Assigned" then
|
||||||
self:E( { From, Event, To, PlayerUnit:GetName(), PlayerName } )
|
self:F( { From, Event, To, PlayerUnit:GetName(), PlayerName } )
|
||||||
|
|
||||||
self:GetMission():GetCommandCenter():MessageToCoalition( "Task " .. self:GetName() .. " is assigned." )
|
self:GetMission():GetCommandCenter():MessageToCoalition( "Task " .. self:GetName() .. " is assigned." )
|
||||||
|
|
||||||
@@ -1267,16 +1219,20 @@ function TASK:onenterAssigned( From, Event, To, PlayerUnit, PlayerName )
|
|||||||
self:SetGoalTotal() -- Polymorphic to set the initial goal total!
|
self:SetGoalTotal() -- Polymorphic to set the initial goal total!
|
||||||
|
|
||||||
if self.Dispatcher then
|
if self.Dispatcher then
|
||||||
self:E( "Firing Assign event " )
|
self:F( "Firing Assign event " )
|
||||||
self.Dispatcher:Assign( self, PlayerUnit, PlayerName )
|
self.Dispatcher:Assign( self, PlayerUnit, PlayerName )
|
||||||
end
|
end
|
||||||
|
|
||||||
self:GetMission():__Start( 1 )
|
self:GetMission():__Start( 1 )
|
||||||
|
|
||||||
-- When the task is assigned, the task goal needs to be checked of the derived classes.
|
-- When the task is assigned, the task goal needs to be checked of the derived classes.
|
||||||
self:__Goal( -10 ) -- Polymorphic
|
self:__Goal( -10, PlayerUnit, PlayerName ) -- Polymorphic
|
||||||
|
|
||||||
self:SetMenu()
|
self:SetMenu()
|
||||||
|
|
||||||
|
self:F( { "--> Task Assigned", TaskName = self:GetName(), Mission = self:GetMission():GetName() } )
|
||||||
|
self:F( { "--> Task Player Names", PlayerNames = self:GetPlayerNames() } )
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1288,7 +1244,8 @@ end
|
|||||||
-- @param #string To
|
-- @param #string To
|
||||||
function TASK:onenterSuccess( From, Event, To )
|
function TASK:onenterSuccess( From, Event, To )
|
||||||
|
|
||||||
self:E( "Task Success" )
|
self:F( { "<-> Task Replanned", TaskName = self:GetName(), Mission = self:GetMission():GetName() } )
|
||||||
|
self:F( { "<-> Task Player Names", PlayerNames = self:GetPlayerNames() } )
|
||||||
|
|
||||||
self:GetMission():GetCommandCenter():MessageToCoalition( "Task " .. self:GetName() .. " is successful! Good job!" )
|
self:GetMission():GetCommandCenter():MessageToCoalition( "Task " .. self:GetName() .. " is successful! Good job!" )
|
||||||
self:UnAssignFromGroups()
|
self:UnAssignFromGroups()
|
||||||
@@ -1305,7 +1262,8 @@ end
|
|||||||
-- @param #string To
|
-- @param #string To
|
||||||
function TASK:onenterAborted( From, Event, To )
|
function TASK:onenterAborted( From, Event, To )
|
||||||
|
|
||||||
self:E( "Task Aborted" )
|
self:F( { "<-- Task Aborted", TaskName = self:GetName(), Mission = self:GetMission():GetName() } )
|
||||||
|
self:F( { "<-- Task Player Names", PlayerNames = self:GetPlayerNames() } )
|
||||||
|
|
||||||
if From ~= "Aborted" then
|
if From ~= "Aborted" then
|
||||||
self:GetMission():GetCommandCenter():MessageToCoalition( "Task " .. self:GetName() .. " has been aborted! Task may be replanned." )
|
self:GetMission():GetCommandCenter():MessageToCoalition( "Task " .. self:GetName() .. " has been aborted! Task may be replanned." )
|
||||||
@@ -1322,7 +1280,8 @@ end
|
|||||||
-- @param #string To
|
-- @param #string To
|
||||||
function TASK:onenterCancelled( From, Event, To )
|
function TASK:onenterCancelled( From, Event, To )
|
||||||
|
|
||||||
self:E( "Task Cancelled" )
|
self:F( { "<-- Task Cancelled", TaskName = self:GetName(), Mission = self:GetMission():GetName() } )
|
||||||
|
self:F( { "<-- Player Names", PlayerNames = self:GetPlayerNames() } )
|
||||||
|
|
||||||
if From ~= "Cancelled" then
|
if From ~= "Cancelled" then
|
||||||
self:GetMission():GetCommandCenter():MessageToCoalition( "Task " .. self:GetName() .. " has been cancelled! The tactical situation has changed." )
|
self:GetMission():GetCommandCenter():MessageToCoalition( "Task " .. self:GetName() .. " has been cancelled! The tactical situation has changed." )
|
||||||
@@ -1339,7 +1298,8 @@ end
|
|||||||
-- @param #string To
|
-- @param #string To
|
||||||
function TASK:onafterReplan( From, Event, To )
|
function TASK:onafterReplan( From, Event, To )
|
||||||
|
|
||||||
self:E( "Task Replanned" )
|
self:F( { "Task Replanned", TaskName = self:GetName(), Mission = self:GetMission():GetName() } )
|
||||||
|
self:F( { "Task Player Names", PlayerNames = self:GetPlayerNames() } )
|
||||||
|
|
||||||
self:GetMission():GetCommandCenter():MessageToCoalition( "Replanning Task " .. self:GetName() .. "." )
|
self:GetMission():GetCommandCenter():MessageToCoalition( "Replanning Task " .. self:GetName() .. "." )
|
||||||
|
|
||||||
@@ -1354,7 +1314,8 @@ end
|
|||||||
-- @param #string To
|
-- @param #string To
|
||||||
function TASK:onenterFailed( From, Event, To )
|
function TASK:onenterFailed( From, Event, To )
|
||||||
|
|
||||||
self:E( "Task Failed" )
|
self:F( { "Task Failed", TaskName = self:GetName(), Mission = self:GetMission():GetName() } )
|
||||||
|
self:F( { "Task Player Names", PlayerNames = self:GetPlayerNames() } )
|
||||||
|
|
||||||
self:GetMission():GetCommandCenter():MessageToCoalition( "Task " .. self:GetName() .. " has failed!" )
|
self:GetMission():GetCommandCenter():MessageToCoalition( "Task " .. self:GetName() .. " has failed!" )
|
||||||
|
|
||||||
@@ -1375,7 +1336,7 @@ function TASK:onstatechange( From, Event, To )
|
|||||||
if self.Scores[To] then
|
if self.Scores[To] then
|
||||||
local Scoring = self:GetScoring()
|
local Scoring = self:GetScoring()
|
||||||
if Scoring then
|
if Scoring then
|
||||||
self:E( { self.Scores[To].ScoreText, self.Scores[To].Score } )
|
self:F( { self.Scores[To].ScoreText, self.Scores[To].Score } )
|
||||||
Scoring:_AddMissionScore( self.Mission, self.Scores[To].ScoreText, self.Scores[To].Score )
|
Scoring:_AddMissionScore( self.Mission, self.Scores[To].ScoreText, self.Scores[To].Score )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -1419,14 +1380,14 @@ do -- Links
|
|||||||
--- Set detection of a task
|
--- Set detection of a task
|
||||||
-- @param #TASK self
|
-- @param #TASK self
|
||||||
-- @param Function.Detection#DETECTION_BASE Detection
|
-- @param Function.Detection#DETECTION_BASE Detection
|
||||||
-- @param #number DetectedItemIndex
|
-- @param DetectedItem
|
||||||
-- @return #TASK
|
-- @return #TASK
|
||||||
function TASK:SetDetection( Detection, DetectedItemIndex )
|
function TASK:SetDetection( Detection, DetectedItem )
|
||||||
|
|
||||||
self:E({DetectedItemIndex,Detection})
|
self:F( { DetectedItem, Detection } )
|
||||||
|
|
||||||
self.Detection = Detection
|
self.Detection = Detection
|
||||||
self.DetectedItemIndex = DetectedItemIndex
|
self.DetectedItem = DetectedItem
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -1440,19 +1401,17 @@ do -- Reporting
|
|||||||
-- @return #string
|
-- @return #string
|
||||||
function TASK:ReportSummary( ReportGroup )
|
function TASK:ReportSummary( ReportGroup )
|
||||||
|
|
||||||
|
self:UpdateTaskInfo( self.DetectedItem )
|
||||||
|
|
||||||
local Report = REPORT:New()
|
local Report = REPORT:New()
|
||||||
|
|
||||||
-- List the name of the Task.
|
-- List the name of the Task.
|
||||||
Report:Add( self:GetName() )
|
Report:Add( "Task " .. self:GetName() )
|
||||||
|
|
||||||
-- Determine the status of the Task.
|
-- Determine the status of the Task.
|
||||||
Report:Add( "State: <" .. self:GetState() .. ">" )
|
Report:Add( "State: <" .. self:GetState() .. ">" )
|
||||||
|
|
||||||
if self.TaskInfo["Coordinates"] then
|
self.TaskInfo:Report( Report, "S", ReportGroup )
|
||||||
local TaskInfoIDText = string.format( "%s: ", "Coordinate" )
|
|
||||||
local TaskCoord = self.TaskInfo["Coordinates"].TaskInfoText -- Core.Point#COORDINATE
|
|
||||||
Report:Add( TaskInfoIDText .. TaskCoord:ToString( ReportGroup, nil, self ) )
|
|
||||||
end
|
|
||||||
|
|
||||||
return Report:Text( ', ' )
|
return Report:Text( ', ' )
|
||||||
end
|
end
|
||||||
@@ -1463,45 +1422,13 @@ end
|
|||||||
-- @return #string
|
-- @return #string
|
||||||
function TASK:ReportOverview( ReportGroup )
|
function TASK:ReportOverview( ReportGroup )
|
||||||
|
|
||||||
self:UpdateTaskInfo()
|
self:UpdateTaskInfo( self.DetectedItem )
|
||||||
|
|
||||||
-- List the name of the Task.
|
-- List the name of the Task.
|
||||||
local TaskName = self:GetName()
|
local TaskName = self:GetName()
|
||||||
local Report = REPORT:New()
|
local Report = REPORT:New()
|
||||||
|
|
||||||
local Line = 0
|
|
||||||
local LineReport = REPORT:New()
|
|
||||||
|
|
||||||
for TaskInfoID, TaskInfo in UTILS.spairs( self.TaskInfo, function( t, a, b ) return t[a].TaskInfoOrder < t[b].TaskInfoOrder end ) do
|
self.TaskInfo:Report( Report, "O", ReportGroup )
|
||||||
|
|
||||||
self:F( { TaskInfo = TaskInfo } )
|
|
||||||
|
|
||||||
if Line < math.floor( TaskInfo.TaskInfoOrder / 10 ) then
|
|
||||||
if Line ~= 0 then
|
|
||||||
Report:AddIndent( LineReport:Text( ", " ) )
|
|
||||||
else
|
|
||||||
Report:Add( TaskName .. ", " .. LineReport:Text( ", " ) )
|
|
||||||
end
|
|
||||||
LineReport = REPORT:New()
|
|
||||||
Line = math.floor( TaskInfo.TaskInfoOrder / 10 )
|
|
||||||
end
|
|
||||||
|
|
||||||
local TaskInfoIDText = string.format( "%s: ", TaskInfoID )
|
|
||||||
|
|
||||||
if type( TaskInfo.TaskInfoText ) == "string" then
|
|
||||||
LineReport:Add( TaskInfoIDText .. TaskInfo.TaskInfoText )
|
|
||||||
elseif type(TaskInfo) == "table" then
|
|
||||||
if TaskInfoID == "Coordinates" then
|
|
||||||
local ToCoordinate = TaskInfo.TaskInfoText -- Core.Point#COORDINATE
|
|
||||||
--Report:Add( TaskInfoIDText )
|
|
||||||
LineReport:Add( TaskInfoIDText .. ToCoordinate:ToString( ReportGroup, nil, self ) )
|
|
||||||
--Report:AddIndent( ToCoordinate:ToStringBULLS( ReportGroup:GetCoalition() ) )
|
|
||||||
else
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
Report:AddIndent( LineReport:Text( ", " ) )
|
|
||||||
|
|
||||||
return Report:Text()
|
return Report:Text()
|
||||||
end
|
end
|
||||||
@@ -1514,7 +1441,7 @@ function TASK:GetPlayerCount() --R2.1 Get a count of the players.
|
|||||||
local PlayerCount = 0
|
local PlayerCount = 0
|
||||||
|
|
||||||
-- Loop each Unit active in the Task, and find Player Names.
|
-- Loop each Unit active in the Task, and find Player Names.
|
||||||
for TaskGroupID, PlayerGroup in pairs( self:GetGroups():GetSet() ) do
|
for TaskGroupID, PlayerGroup in pairs( self:GetGroups():GetAliveSet() ) do
|
||||||
local PlayerGroup = PlayerGroup -- Wrapper.Group#GROUP
|
local PlayerGroup = PlayerGroup -- Wrapper.Group#GROUP
|
||||||
if self:IsGroupAssigned( PlayerGroup ) then
|
if self:IsGroupAssigned( PlayerGroup ) then
|
||||||
local PlayerNames = PlayerGroup:GetPlayerNames()
|
local PlayerNames = PlayerGroup:GetPlayerNames()
|
||||||
@@ -1534,7 +1461,7 @@ function TASK:GetPlayerNames() --R2.1 Get a map of the players.
|
|||||||
local PlayerNameMap = {}
|
local PlayerNameMap = {}
|
||||||
|
|
||||||
-- Loop each Unit active in the Task, and find Player Names.
|
-- Loop each Unit active in the Task, and find Player Names.
|
||||||
for TaskGroupID, PlayerGroup in pairs( self:GetGroups():GetSet() ) do
|
for TaskGroupID, PlayerGroup in pairs( self:GetGroups():GetAliveSet() ) do
|
||||||
local PlayerGroup = PlayerGroup -- Wrapper.Group#GROUP
|
local PlayerGroup = PlayerGroup -- Wrapper.Group#GROUP
|
||||||
if self:IsGroupAssigned( PlayerGroup ) then
|
if self:IsGroupAssigned( PlayerGroup ) then
|
||||||
local PlayerNames = PlayerGroup:GetPlayerNames()
|
local PlayerNames = PlayerGroup:GetPlayerNames()
|
||||||
@@ -1555,7 +1482,7 @@ end
|
|||||||
-- @return #string
|
-- @return #string
|
||||||
function TASK:ReportDetails( ReportGroup )
|
function TASK:ReportDetails( ReportGroup )
|
||||||
|
|
||||||
self:UpdateTaskInfo()
|
self:UpdateTaskInfo( self.DetectedItem )
|
||||||
|
|
||||||
local Report = REPORT:New():SetIndent( 3 )
|
local Report = REPORT:New():SetIndent( 3 )
|
||||||
|
|
||||||
@@ -1565,7 +1492,7 @@ function TASK:ReportDetails( ReportGroup )
|
|||||||
-- Determine the status of the Task.
|
-- Determine the status of the Task.
|
||||||
local Status = "<" .. self:GetState() .. ">"
|
local Status = "<" .. self:GetState() .. ">"
|
||||||
|
|
||||||
Report:Add( "Task: " .. Name .. " - " .. Status .. " - Detailed Report" )
|
Report:Add( "Task " .. Name .. " - " .. Status .. " - Detailed Report" )
|
||||||
|
|
||||||
-- Loop each Unit active in the Task, and find Player Names.
|
-- Loop each Unit active in the Task, and find Player Names.
|
||||||
local PlayerNames = self:GetPlayerNames()
|
local PlayerNames = self:GetPlayerNames()
|
||||||
@@ -1577,37 +1504,12 @@ function TASK:ReportDetails( ReportGroup )
|
|||||||
local Players = PlayerReport:Text()
|
local Players = PlayerReport:Text()
|
||||||
|
|
||||||
if Players ~= "" then
|
if Players ~= "" then
|
||||||
Report:Add( " - Players assigned:" )
|
Report:AddIndent( "Players assigned:", "-" )
|
||||||
Report:AddIndent( Players )
|
Report:AddIndent( Players )
|
||||||
end
|
end
|
||||||
|
|
||||||
for TaskInfoID, TaskInfo in pairs( self.TaskInfo, function( t, a, b ) return t[a].TaskInfoOrder < t[b].TaskInfoOrder end ) do
|
self.TaskInfo:Report( Report, "D", ReportGroup )
|
||||||
|
|
||||||
local TaskInfoIDText = string.format( " - %s: ", TaskInfoID )
|
|
||||||
|
|
||||||
if type( TaskInfo.TaskInfoText ) == "string" then
|
|
||||||
Report:Add( TaskInfoIDText .. TaskInfo.TaskInfoText )
|
|
||||||
elseif type(TaskInfo) == "table" then
|
|
||||||
if TaskInfoID == "Coordinates" then
|
|
||||||
local FromCoordinate = ReportGroup:GetUnit(1):GetCoordinate()
|
|
||||||
local ToCoordinate = TaskInfo.TaskInfoText -- Core.Point#COORDINATE
|
|
||||||
Report:Add( TaskInfoIDText .. ToCoordinate:ToString( ReportGroup:GetUnit(1), nil, self ) )
|
|
||||||
else
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
local Coordinate = self:GetInfo( "Coordinates" ) -- Core.Point#COORDINATE
|
|
||||||
|
|
||||||
local Velocity = self.TargetSetUnit:GetVelocity()
|
|
||||||
local Heading = self.TargetSetUnit:GetHeading()
|
|
||||||
|
|
||||||
Coordinate:SetHeading( Heading )
|
|
||||||
Coordinate:SetVelocity( Velocity )
|
|
||||||
|
|
||||||
Report:Add( "Targets are" .. Coordinate:GetMovingText() .. "." )
|
|
||||||
|
|
||||||
return Report:Text()
|
return Report:Text()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user