Compare commits

...

338 Commits

Author SHA1 Message Date
Frank a0c5466f7f Update Airbase.lua
- Updated TheChannel map airbase enums
- Fixed some Umlaute in the Germany map
2025-11-23 20:35:12 +01:00
Frank 2f002703ee Update Airbase.lua
- Updated Syria map airbase enums
2025-11-23 18:45:09 +01:00
Frank b0c6ed1d59 Update Airbase.lua
- Updated Sinai map airbase enums
2025-11-23 17:40:05 +01:00
Frank 950e97b6d7 Update Airbase.lua
- Updated Persian Gulf map airbase enums
2025-11-23 17:35:38 +01:00
Frank 6d54e5a47f Update Airbase.lua
- Updated Normand map airbase enums
2025-11-23 17:28:31 +01:00
Frank 35c8803f8b Update Airbase.lua
- Update Nevada map airbase enums
2025-11-23 17:19:18 +01:00
Frank d9c8542993 Update Airbase.lua
- Update of Mariana Island (WWII) airbase enums
2025-11-23 17:15:30 +01:00
Frank f3c38a4288 Update Airbase.lua
- Updated Kola map airbase enums
2025-11-23 16:46:23 +01:00
Frank 626b03c93a Update Airbase.lua
- Updated Iraq map airbase enums
2025-11-23 16:44:40 +01:00
Frank cf5c55209a Update Airbase
- Updated South Atlantic airbase enums
2025-11-23 16:36:20 +01:00
Frank 19921414cf Update Airbase.lua
- Update Caucasus Airbase Enums
2025-11-23 16:20:49 +01:00
Frank c4de2b6990 Update Airbase.lua
- Afghanistan Airbase Enums updated
2025-11-23 16:10:40 +01:00
Frank 7907e4b830 Airbase
- Added new Germany CW airbases
- Added function in UTILS to create airbase enums
2025-11-23 16:08:28 +01:00
Applevangelist 5955c2d61f #VARIOUS Small fixes 2025-11-22 15:17:26 +01:00
Applevangelist 26fbae8672 #AIRBOSS Added early F-14A 2025-11-15 16:48:05 +01:00
Applevangelist 5089e7df25 xx 2025-11-14 17:26:24 +01:00
Thomas 0c0d1cc794 Merge pull request #2445 from shaji-Dev/master
[ADDED] STATIC:GetVec2Cached() and STATIC:GetVec3Cached()
2025-11-14 13:45:22 +01:00
Shafik 21b968a9c6 [ADDED] STATIC:GetVec2Cached() and STATIC:GetVec3Cached() for statics considering respawns 2025-11-14 14:42:52 +02:00
Thomas 704bb8668f Merge pull request #2443 from FlightControl-Master/Applevangelist-DC-1
Update DynamicCargo.lua
2025-11-11 12:54:42 +01:00
Thomas 763bfb4bb1 Update DynamicCargo.lua
Added Destroy-Functionality
2025-11-11 12:41:30 +01:00
Applevangelist 046bd37fd5 xx 2025-11-09 17:19:29 +01:00
Applevangelist fbf83b3aed #SET - Rationalize FilterCoalitions() and allow values like coalition.side.BLUE 2025-11-09 16:53:10 +01:00
Applevangelist 22097987dc #CTLD, #DYNAMICCARGO - C-130j-30 additions 2025-11-09 14:43:11 +01:00
Thomas 98d02d7532 Merge pull request #2440 from leka1986/patch-2
Update CTLD.lua
2025-11-09 09:24:48 +01:00
leka1986 7b44e7a3f6 Update CTLD.lua
Removed quantity menu if there is only one set.
2025-11-09 02:16:02 +01:00
leka1986 aa4cf37aed Clean up comments in CTLD.lua
Removed unnecessary comment lines in CTLD.lua.
2025-11-08 02:52:23 +01:00
leka1986 caf2b4e736 Update CTLD.lua
Added ability to drop "Sets" from 2 and up will be sets, else it will be like before.

Changed _PackCratesNearby to handle all cargo within the range instead of the nearest.
2025-11-08 02:47:56 +01:00
Frank da516a0167 Merge pull request #2439 from shaji-Dev/master
[FIXED] `dcsgroup:getUnit(1)` nil pointer
2025-11-07 21:53:26 +01:00
Shafik 17d1cf673d [ADDED] IsRed, IsBlue and IsNeutral to IDENTIFIABLE 2025-11-06 12:23:13 +02:00
Shafik 1fcd70b0d0 Merge remote-tracking branch 'origin/master' 2025-11-05 12:36:03 +02:00
Shafik 832941494b [FIXED] dcsgroup:getUnit(1) nil pointer 2025-11-05 12:35:55 +02:00
Thomas 0e82cb977e Merge pull request #2437 from leka1986/patch-2
Update CTLD.lua
2025-11-05 06:22:03 +01:00
leka1986 e9237146a3 Update CTLD.lua
Fixed a bug. 

When dropping crates, while choosing "Drop and build" The first drop will put the crate into a crate that can be loaded but a second later, that crate will be cleaned up due to build. This makes sure that the crates are not in the "load crates" list.
2025-11-04 20:09:48 +01:00
Thomas b72899b500 Merge pull request #2436 from shaji-Dev/master
[ADDED] Complete list of DCS warehouse equipment
2025-11-04 13:24:09 +01:00
Shafik 2f39e38264 [ADDED] CTLD. option to load back crates from save file. 2025-11-04 11:32:24 +02:00
Shafik db54672fbd [ADDED] CTLD. option to load back crates from save file. 2025-11-04 11:30:59 +02:00
Shafik 30d9a7d703 [ADDED] Complete list of DCS warehouse equipment 2025-11-04 10:27:16 +02:00
Thomas 5a088a740e Merge pull request #2434 from nasgroup94/master
more T-45 AOA adjustments
2025-11-03 06:29:14 +01:00
nasgroup94 be220b6c1d more T-45 AOA adjustments 2025-11-02 19:48:16 -05:00
Thomas 645c4a4dbc Merge pull request #2432 from FlightControl-Master/Applevangelist-patch-1
Update CTLD.lua
2025-11-02 17:57:09 +01:00
Thomas c2a630dabd Update CTLD.lua
Cargo counters by @lekaa
2025-11-02 17:56:55 +01:00
Thomas 07a14bc176 Merge pull request #2425 from nasgroup94/master
added Tomcat AA grading adjustments and T45 AOA adjustments
2025-11-01 17:20:08 +01:00
Thomas 2047e818ef Merge pull request #2428 from shaji-Dev/master
[FIXED] SET_CLIENT:HandleCASlots()
2025-10-31 06:28:04 +01:00
Shafik 801b4f01b6 [FIXED] SET_CLIENT:HandleCASlots() 2025-10-30 23:10:17 +02:00
Thomas 6058160160 Merge pull request #2426 from FlightControl-Master/Applevangelist-patch-3-1
Update Positionable.lua
2025-10-29 07:02:10 +01:00
Thomas 479dfc28b9 Update Positionable.lua 2025-10-29 07:01:33 +01:00
Applevangelist 8392788cdb Minor fixes 2025-10-26 16:19:10 +01:00
nasgroup94 4a1b23c52a added Tomcat AA grading adjustments and T45 AOA adjustments 2025-10-26 09:43:17 -04:00
Thomas 55242edbde Merge pull request #2423 from nasgroup94/master
Minor Fixes
2025-10-26 07:27:37 +01:00
nasgroup94 2c5d9f043e fixed TIG bug causing NG Removed old into wind function 2025-10-25 12:42:09 -04:00
nasgroup94 2b2acbe244 Merge branch 'master' of https://github.com/nasgroup94/MOOSE 2025-10-25 12:39:54 -04:00
Applevangelist 7d4e103660 #UTILS - SpawnFarp helper, build multiple pads as a single static group, not separate objects. 2025-10-25 16:56:16 +02:00
Applevangelist 86798ae9ea #CTLD - fix 2025-10-24 16:27:17 +02:00
Thomas 2830e6d199 Merge pull request #2421 from leka1986/patch-1
Update CTLD.lua
2025-10-24 16:16:00 +02:00
leka1986 8c07573f8f Update CTLD.lua 2025-10-24 16:13:18 +02:00
leka1986 f3af0262df Update CTLD.lua
Added Crates amount to the menus and AddCratesCargoNoMove.
2025-10-24 14:02:06 +02:00
Applevangelist 0f270a6a35 #UTILS - FARP helper - add options to spawn multiple pads 2025-10-23 12:10:05 +02:00
Applevangelist 8432f46e48 #AIRBOSS - Fixed omission of magnetic in expected BRC call 2025-10-23 08:10:26 +02:00
nasgroup94 faccee88e7 added missing end to TIG "_OK_" subtraction 2025-10-22 05:19:50 -04:00
Thomas e8246b3b90 Merge pull request #2420 from FlightControl-Master/revert-2417-master
Revert "Minor fixes"
2025-10-22 07:23:37 +02:00
Thomas eb4e7b9281 Revert "Minor fixes" 2025-10-22 07:23:21 +02:00
Thomas 1e2190a6cc Merge pull request #2417 from nasgroup94/master
Minor fixes
2025-10-22 06:31:24 +02:00
nasgroup94 1644c1dc5b fixes to goshawk AOA f14 AA and TIG bug 2025-10-21 16:49:51 -04:00
nasgroup94 5fc3798c42 Update Airboss.lua
Fixed possible bug where a player will get points deducted when getting a perfect groove time
2025-10-21 05:44:19 -04:00
Applevangelist fae81cdb1b Merge remote-tracking branch 'origin/master' 2025-10-13 18:51:59 +02:00
Applevangelist dbae37f151 xx 2025-10-13 18:51:55 +02:00
Applevangelist f7d58a0b76 #ZONE - Added missing ZONE_UNIT:UpdateFromUnit() and ZONE_GROUP:UpdateFromGroup() 2025-10-13 18:51:22 +02:00
Applevangelist 2e0d1fd90f #DYNAMICCARGO - Added Mi-8 type and dimensions 2025-10-12 19:14:59 +02:00
Applevangelist 69e6497655 #CTLD - Small fix for subcats 2025-10-12 17:23:54 +02:00
Thomas ef8c7c9084 Merge pull request #2415 from shaji-Dev/master
[ADDED] UH-60L 'DAP' to `UTILS.IsLoadingDoorOpen` check
2025-10-10 11:41:52 +02:00
shaji-Dev e4eaf72769 Merge branch 'FlightControl-Master:master' into master 2025-10-10 09:19:46 +02:00
smiki 5138ced630 Merge remote-tracking branch 'origin/master' 2025-10-10 09:19:31 +02:00
smiki 534f445f8c [ADDED] UH-60L 'DAP' to UTILS.IsLoadingDoorOpen check 2025-10-10 09:19:23 +02:00
Thomas b2cc3e5329 Merge pull request #2413 from leka1986/master
Master
2025-10-09 17:41:07 +02:00
Thomas efde321616 Merge pull request #2412 from shaji-Dev/master
[ADDED] Fuel Tanks and gunner seat loadout enums for UH-60L mod
2025-10-09 17:40:03 +02:00
leka1986 3a61581608 #Added a new option ( true by default), returntroopstobase. If set to false, troops would not return to base when dropped at load zone. 2025-10-09 17:33:15 +02:00
shaji-Dev 3a10f0b946 Merge branch 'FlightControl-Master:master' into master 2025-10-09 13:30:04 +02:00
smiki 6dc6972bdb [ADDED] Fuel Tanks and gunner seat loadout enums for UH-60L mod 2025-10-09 13:29:45 +02:00
Applevangelist 405235a59d #CONTROLLABLE - Fix for double brackets 2025-10-08 16:01:21 +02:00
Thomas 9c148625e4 Merge pull request #2410 from shaji-Dev/master
[FIXED] CTLD. Memory leak adding zones of the same name and type
2025-10-08 13:24:57 +02:00
shaji-Dev a08d82a3d9 Merge branch 'FlightControl-Master:master' into master 2025-10-08 13:15:39 +02:00
smiki 48b51f21de [FIXED] CTLD. Memory leak adding zones of the same name and type
[FIXED] CSAR. nil pointer
2025-10-08 13:15:22 +02:00
Applevangelist 3260279cb7 xx 2025-10-08 12:29:59 +02:00
Applevangelist 1e60a0a32a #RAT 3.0.0 2025-10-07 18:06:20 +02:00
Applevangelist 146f869aaa #RAT - reduce log noise 2025-10-07 17:48:06 +02:00
Thomas 0bd35727f4 Merge pull request #2408 from shaji-Dev/master
[FIXED] Incorrect Airbase center position. [ADDED] UH-60L weapons
2025-10-07 15:51:44 +02:00
Thomas 5183fcc316 Update Enums.lua 2025-10-07 15:51:22 +02:00
shaji-Dev bf7596521c Merge branch 'FlightControl-Master:master' into master 2025-10-07 15:42:17 +02:00
smiki a85b6c960c [FIXED] Incorrect Airbase center position
[ADDED] UH-60L weapons
2025-10-07 15:41:54 +02:00
Thomas a1aebf0575 Merge pull request #2406 from nasgroup94/master
AIRBOSS adjustments
2025-10-07 10:14:31 +02:00
nasgroup94 0f42218681 minor edits 2025-10-06 18:08:23 -04:00
frankiep95 5404f9ef19 Minor Fixes to grading fixed high low comments and BRC comment 2025-10-05 13:31:18 -04:00
frankiep95 8a84be19df Merge branch 'master' of https://github.com/nasgroup94/MOOSE 2025-10-05 12:50:58 -04:00
frankiep95 fd4ea81e46 minor fixes to grading, and BRC callout 2025-10-05 12:50:56 -04:00
Thomas 3df79aedb1 Merge pull request #2404 from shaji-Dev/master
[FIXED] SPAWNSTATIC not registering script spawned static templates therefore ReSpawn is not working.
2025-10-05 18:04:09 +02:00
smiki 4141aa35ba Merge remote-tracking branch 'origin/master' 2025-10-05 16:57:41 +02:00
smiki 6e45ee558e [FIXED] SPAWNSTATIC not registering script spawned static templates therefore ReSpawn is not working. 2025-10-05 16:57:33 +02:00
Applevangelist db138be5f3 #SCoRING - suppress autocreation of CSV files better 2025-10-05 13:52:22 +02:00
Applevangelist 5ae6495e69 #CSAR Added functionality to determine if a landing took place at a helo base (named "H ..." in newer maps). 2025-10-05 13:51:55 +02:00
Thomas 58f1bc5531 Merge pull request #2402 from shaji-Dev/master
[ADDED] `SET_OPSGROUP:CountAlive`
2025-10-01 15:25:45 +02:00
smiki 935b52c489 [FIXED] ZONE_POLYGON from RECT ME drawing rotation not taken into account. 2025-10-01 15:11:44 +02:00
smiki aace98545a [FIXED] ZONE_POLYGON from RECT ME drawing rotation not taken into account. 2025-10-01 15:07:18 +02:00
smiki f39236c8fd [FIXED] ZONE_POLYGON from RECT ME drawing rotation not taken into account. 2025-10-01 14:59:59 +02:00
smiki 43b4a6834b [FIXED] ZONE_POLYGON from RECT ME drawing rotation not taken into account. 2025-10-01 14:50:04 +02:00
shaji-Dev aa3978b04d Merge branch 'FlightControl-Master:master' into master 2025-09-30 21:17:51 +02:00
smiki b51e758516 [ADDED] SET_OPSGROUP:CountAlive 2025-09-30 21:17:29 +02:00
Thomas 5be1832c09 Merge pull request #2400 from shaji-Dev/master
[ADDED] `UH-60L DAP to CSAR and CTLD`
2025-09-26 15:52:30 +02:00
smiki 362652ac6c [ADDED] CSAR. UH-60L DAP aircraft type 2025-09-26 15:14:12 +02:00
smiki aec69884dc [ADDED] CTLD. UH-60L DAP default unit capability 2025-09-26 15:13:03 +02:00
Applevangelist 8fb4d4c7c6 #CTLD - add CratesPickedUp at one more point 2025-09-25 12:13:29 +02:00
Thomas b5524b9a69 Merge pull request #2398 from shaji-Dev/master
[Fixed] Zone Scans returns objects outside the zone
2025-09-24 19:16:14 +02:00
smiki ec0ff7afcd [Fixed] Zone Scans returns objects outside the zone 2025-09-24 15:14:21 +02:00
Thomas d0cf68c2e2 Merge pull request #2396 from FlightControl-Master/Applevangelist-patch-3
Update Storage.lua
2025-09-23 15:26:54 +02:00
Thomas 3beb98a5e9 Update Storage.lua 2025-09-23 15:26:38 +02:00
Thomas dd83ebe0e2 Merge pull request #2395 from FlightControl-Master/Applevangelist-patch-3
Fix for #Storage.lua some missing string concats
2025-09-23 15:19:42 +02:00
Thomas 6fdf3957bd Fix for #Storage.lua some missing string concats 2025-09-23 15:19:10 +02:00
Thomas f3d586d455 Merge pull request #2393 from FlightControl-Master/Applevangelist-patch-2
Update Airbase.lua
2025-09-22 11:13:59 +02:00
Thomas c2f0ce0fa2 Update Airbase.lua 2025-09-22 11:13:44 +02:00
Thomas 354490d149 Merge pull request #2391 from FlightControl-Master/Applevangelist-patch-2
Update Airbase.lua Iraq Airbases
2025-09-22 11:09:47 +02:00
Thomas c5b0be5d21 Update Airbase.lua Iraq Airbases 2025-09-22 11:08:15 +02:00
Thomas 5e8676cf8a Merge pull request #2387 from shaji-Dev/master
LandingAfterEjection error
2025-09-18 06:47:01 +02:00
smiki f4264cd149 Merge remote-tracking branch 'origin/master' 2025-09-17 20:19:54 +02:00
smiki 65d1c4187e [Fixed] attempt to index field 'Place' (a nil value) in LandingAfterEjection 2025-09-17 20:19:17 +02:00
Thomas cda1432d04 Merge pull request #2383 from shaji-Dev/master
[FIXED] CTLD. Injected spawns not using `InitValidateAndRepositionGroundUnits`
2025-09-11 05:13:50 +02:00
smiki 09e5fca1a5 [FIXED] CTLD. Injected spawns not using InitValidateAndRepositionGroundUnits 2025-09-11 00:38:20 +02:00
Thomas e38d73df8b Merge pull request #2381 from shaji-Dev/master
[ADDED] `GROUP:GetBoundingBox()`
2025-09-03 10:35:42 +02:00
smiki 7df90b2d30 [ADDED] GROUP:GetBoundingBox() since POSITIONABLE:GetBoundingBox() is only for units 2025-09-03 09:12:20 +02:00
Thomas a917ee8f1e Merge pull request #2379 from shaji-Dev/master
[FIXED] `UTILS.HdgTo to accept both Vec2 or Vec3`
2025-09-01 10:57:48 +02:00
smiki 44f3c776eb [FIXED] UTILS.HdgTo to accept both Vec2 or Vec3 2025-09-01 09:30:05 +02:00
Applevangelist 873879ff79 #AIRBOSS - Slight tweak to EnableSRS() when no parameters are handed in. 2025-08-31 18:22:17 +02:00
Applevangelist 6c1907f7e0 GROUO correction in class self line 3205 2025-08-31 13:27:24 +02:00
Applevangelist 42ecdd3b14 #AIRBASE - Add Sinai Damascus Intl Airbase in the enumerator 2025-08-31 13:24:35 +02:00
Thomas 297164a0ee Merge pull request #2378 from shaji-Dev/master
[ADDED] `SPAWNSTATIC:InitValidateAndRepositionStatic(OnOff, MaxRadius)`
2025-08-28 19:58:19 +02:00
smiki 323f09b06c [ADDED] SPAWNSTATIC:InitValidateAndRepositionStatic(OnOff, MaxRadius) 2025-08-28 19:38:05 +02:00
smiki e003b91bbe [ADDED] SPAWNSTATIC:InitValidateAndRepositionStatic(OnOff, MaxRadius) 2025-08-28 19:36:22 +02:00
Thomas f1636fc5a9 Merge pull request #2375 from tspindler-cms/TeTeT/master
Add support for Vietnam War Vessels carriers to Airboss
2025-08-27 14:23:36 +02:00
TeTeT Nimitz db053398d2 Add support for Vietnam War Vessels carriers to Airboss:
- CVA-31 Bon Homme Richard
    - Generic Essex with SCB-125 upgrade (angled Deck)
    - CVAN-65 Enterprise 1966
    - CVN-65 Enterprise modern
2025-08-27 13:12:50 +02:00
Thomas 417caf1b62 Merge pull request #2370 from shaji-Dev/master
[ADDED] `ValidateAndRepositionGroundUnits` to UNIT and GROUP respawns
2025-08-26 06:22:57 +02:00
smiki cc76851614 [ADDED] ValidateAndRepositionGroundUnits to UNIT and GROUP respawns 2025-08-25 23:08:25 +02:00
Thomas 27fe314c1e Merge pull request #2368 from shaji-Dev/master
[ADDED] WAREHOUSE:SetValidateAndRepositionGroundUnits
2025-08-25 12:08:27 +02:00
smiki 2c12cfe4fd [ADDED] WAREHOUSE:SetValidateAndRepositionGroundUnits to use for Brigades 2025-08-24 17:06:45 +02:00
smiki 9adf342dd8 [ADDED] WAREHOUSE:SetValidateAndRepositionGroundUnits to use for Brigades 2025-08-24 16:45:54 +02:00
smiki facac82130 [ADDED] WAREHOUSE:SetValidateAndRepositionGroundUnits to use for Brigades 2025-08-24 16:44:41 +02:00
Thomas 3e095711f4 Merge pull request #2366 from shaji-Dev/master
[FIXED] Maintain valid unit positions
2025-08-24 16:35:43 +02:00
smiki ca1ddb4013 Merge remote-tracking branch 'origin/master' 2025-08-24 16:28:08 +02:00
smiki 8169235d2f [FIXED] Maintain valid unit positions 2025-08-24 16:27:55 +02:00
Thomas 4553785918 Merge pull request #2364 from shaji-Dev/master
[ADDED] Validate and Reposition Ground Units algorithm
2025-08-24 15:23:32 +02:00
smiki 78b3efcf00 Validate and Reposition Ground Units algorithm
[ADDED] UTILS.ValidateAndRepositionGroundUnits
[ADDED] SPAWN:InitValidateAndRepositionGroundUnits
[ADDED] CTLD.validateAndRepositionUnits
2025-08-24 15:10:47 +02:00
smiki 67cb844550 Validate and Reposition Ground Units algorithm
[ADDED] UTILS.ValidateAndRepositionGroundUnits
[ADDED] SPAWN:InitValidateAndRepositionGroundUnits
[ADDED] CTLD.validateAndRepositionUnits
2025-08-24 15:07:27 +02:00
Applevangelist b9cf1e46af xx 2025-08-14 17:17:34 +02:00
Applevangelist 4a04d7cce7 xx 2025-08-14 17:15:43 +02:00
Applevangelist 35f15435a3 #MANTIS - Added Pantsir S1, TOR M2, IRIS-T SLM to main man SAM data (from CH mod) 2025-08-14 09:12:58 +02:00
Applevangelist 4c97d966a2 #MSRS - align google voices catalog with new voice types. 2025-08-10 13:20:22 +02:00
Applevangelist 674c6eec81 More randomness in functions using random coordinates 2025-08-07 11:30:44 +02:00
Thomas c75c3d8777 Merge pull request #2361 from FlightControl-Master/Applevangelist-score-1
Update Scoring.lua
2025-08-07 11:16:29 +02:00
Thomas 4fa63986dc Update Scoring.lua
Further changes
2025-08-07 11:16:07 +02:00
Thomas 029f7a3f5c Update Scoring.lua
Better check for Scenery hits where target category is usually nil
2025-08-06 12:27:28 +02:00
Thomas e9194c59f4 Merge pull request #2358 from FlightControl-Master/Applevangelist-patch-1
Update Airbase.lua
2025-08-04 16:11:00 +02:00
Thomas c8d693c8e7 Update Airbase.lua
Sinai add'l bases
2025-08-04 16:10:10 +02:00
Thomas 2341014882 Merge pull request #2356 from leka1986/master
Master
2025-08-02 18:34:25 +02:00
leka1986 eb15fadcfe Added SetPartlyInside. if used, it the :Trigger will trigger as soon as any of the group units enteres the zone even if they are far apart. 2025-08-02 17:40:55 +02:00
Applevangelist 13fa8f373e #MANTIS - added radar entry for Dog Ear and Nike 2025-08-01 14:02:57 +02:00
Applevangelist b318e8ae13 #AIRBOSS - Added :SetCarrierIllumination(Mode) 2025-07-31 09:47:54 +02:00
Thomas 7e963bef41 Merge pull request #2354 from shaji-Dev/master
[ADDED] `UTILS.ShowPicture` For all, coalition, country, group and unit
2025-07-31 09:26:09 +02:00
smiki 933000ffc7 [ADDED] UNIT:SetCarrierIlluminationMode 2025-07-31 09:06:19 +02:00
smiki 9b217e1c97 [ADDED] UTILS.ShowPicture For all, coalition, country, group and unit
[ADDED] `UTILS.ShowHelperGateForUnit`
2025-07-31 08:57:20 +02:00
smiki 324f4944b4 [ADDED] UTILS.ShowPicture For all, coalition, country, group and unit
[ADDED] `UTILS.ShowHelperGateForUnit`
2025-07-31 08:54:16 +02:00
Applevangelist f735f1eb53 CTLD - correct ground speed for routing 2025-07-29 17:38:35 +02:00
Thomas 7149226283 Merge pull request #2353 from shaji-Dev/master
[CHANGED] Use file path instead of resource key
2025-07-29 13:04:46 +02:00
shaji-Dev 4164a5288a Merge branch 'FlightControl-Master:master' into master 2025-07-29 12:50:45 +02:00
smiki 1992276b07 Merge remote-tracking branch 'origin/master' 2025-07-29 12:50:27 +02:00
smiki 21a7023b7b Removed getValueResourceByKey UTILS.ShowPicture and UTILS.SetMissionBriefing to use full file paths 2025-07-29 12:50:19 +02:00
Applevangelist f094716b73 CTLD - Added option for Vehicle Formation when going to a MOVE zone. 2025-07-29 12:04:41 +02:00
Applevangelist 4b1888a34d CSAR - Allow also the initial down message to be suppressed 2025-07-29 10:02:22 +02:00
Applevangelist b9be3aa7f8 xx 2025-07-27 14:50:45 +02:00
Thomas fd2dacaefb Merge pull request #2351 from shaji-Dev/master
[ADDED] `UTILS.LoadMission` and `UTILS.SetMissionBriefing`
2025-07-27 14:15:16 +02:00
smiki cc60e85901 [ADDED] UTILS.LoadMission and UTILS.SetMissionBriefing 2025-07-27 13:18:56 +02:00
Thomas f172f6efeb Merge pull request #2349 from shaji-Dev/master
[ADDED] `UTILS.ShowPicture`. Overlay pictures for players
2025-07-26 09:01:02 +02:00
smiki b6b6686873 [ADDED] COORDINATE:GetLandProfile 2025-07-25 23:43:00 +02:00
smiki 5e724e7a3f [ADDED] COORDINATE:GetLandProfile 2025-07-25 23:39:53 +02:00
smiki 90f1d1df2a Merge remote-tracking branch 'origin/master' 2025-07-25 23:27:11 +02:00
smiki a5726c0ed8 [ADDED] UTILS.ShowPicture. Overlay pictures for players.
Refactoring
2025-07-25 23:27:01 +02:00
Applevangelist 23ff128ac8 #ZONE added ZONE_BASE:FindNearestCoordinateOnRadius() 2025-07-25 19:05:01 +02:00
Applevangelist 7d3fc1740a xx 2025-07-25 14:57:58 +02:00
Applevangelist b2a084d669 xx 2025-07-25 14:57:06 +02:00
Applevangelist 30203668e4 Revert "#UTILS - Added FindNearestPointOnCircle()"
This reverts commit 2cc1ddd4679b0e3fb7a5f72ea5e4822112e2f2d1.
2025-07-25 14:57:06 +02:00
Thomas ebecc70693 Merge pull request #2348 from shaji-Dev/master
[ADDED] `Disposition.getSimpleZones`  support for ZONE_POLYGON_BASE
2025-07-25 14:47:08 +02:00
smiki 74712b6e27 [ADDED] Disposition.getSimpleZones to ZONE_POLYGON_BASE to support all zone types 2025-07-25 14:17:03 +02:00
Applevangelist 40253ea8bb xx 2025-07-24 18:27:44 +02:00
Applevangelist 4e56078d2a #CONTROLLABLE - added options for landing approaches
* Prefer vertical for helos
and for aircraft
* Straight in
* Overhead break
* Force pair
* Restrict pair
2025-07-24 16:17:09 +02:00
Thomas 4bbf20ca4e Merge pull request #2345 from shaji-Dev/master
[Fixed] `Disposition.getSimpleZones`
2025-07-24 09:39:09 +02:00
smiki a462c5a493 [Fixed] Disposition.getSimpleZones 2025-07-24 01:51:10 +02:00
Applevangelist 367014ebf3 xxx 2025-07-23 15:47:56 +02:00
Thomas 326b20b08d Merge pull request #2344 from shaji-Dev/master
[ADDED] `Disposition.getSimpleZones`
2025-07-23 12:35:16 +02:00
Applevangelist 11b0ce6275 #AIRBASE - remove some differences between data produced by _InitRunways and GetRunwayData 2025-07-23 12:34:52 +02:00
smiki 03763e16d6 [ADDED] Disposition.getSimpleZones 2025-07-23 12:19:00 +02:00
smiki c1e8ee12e0 [ADDED] Disposition.getSimpleZones 2025-07-23 11:48:33 +02:00
smiki ac8cc408c1 [FIXED] Disposition.getSimpleZones 2025-07-23 11:48:07 +02:00
Applevangelist ada38fa3ea #AIRBOSS - SRS 2.2.x path in documentation 2025-07-22 13:08:46 +02:00
Applevangelist 2ee0597d48 #CTLD - added FSM event "CratesPacked"
#UTILS - more options for MASH building
2025-07-22 13:08:18 +02:00
Applevangelist 7ae4cdc8f1 #Documentation 2025-07-21 15:02:45 +02:00
Applevangelist 8c92a578ed #UTILS - added UTILS.SpawnMASHStatics() 2025-07-21 14:50:08 +02:00
Thomas 096f2caf9c Merge pull request #2341 from nasgroup94/master
Added VNAO Edits
2025-07-21 09:09:54 +02:00
frankiep95 0b37c909b3 Added VNAO Edits 2025-07-20 16:58:33 -04:00
Applevangelist 1b18ae1597 #MANTIS - Added SAMP/T, SA-17 data correction, HDS explanations expanded 2025-07-20 14:03:33 +02:00
Applevangelist c9ac6d73e6 #MANTIS - Better documented use of SA-10B/C/12/23 naming usage with launcher differences. 2025-07-19 18:36:03 +02:00
Applevangelist 0e836973fd #Fix SRS TTS folder path in documentation and defaults 2025-07-19 16:04:49 +02:00
Applevangelist be40d7be9a #SPAWNSTATIC - NewFromStatic now creates a new template in the database under the new name - if not already there. This allows #WAREHOUSE static warehouses spawned that way to be respawned eg on coalition change. 2025-07-18 18:09:57 +02:00
Thomas f3b7740041 Merge pull request #2335 from shaji-Dev/master
[ADDED] GROUP.Attribute.GROUND_SHORAD
2025-07-15 11:19:41 +02:00
smiki 7d7488db6f [ADDED] GROUP.Attribute.GROUND_SHORAD 2025-07-15 11:05:03 +02:00
Thomas 4964cc2f2d Merge pull request #2332 from FlightControl-Master/Applevangelist-Vertical
Controllable - add option prefer vertical landing
2025-07-09 12:18:10 +02:00
Thomas f0a4c5b008 Merge pull request #2331 from FlightControl-Master/Applevangelist-patch-2
Update Controllable.lua
2025-07-09 12:16:29 +02:00
Thomas 1b6412821b Update Controllable.lua 2025-07-09 12:15:34 +02:00
Thomas 926a0733e4 Controllable - add option prefer vertical landing
Addrd
2025-07-09 12:14:41 +02:00
Applevangelist da70f4ce6c #DynamicSlots for dynamic FARPs 2025-07-05 18:56:59 +02:00
Applevangelist 727cb3276c #SET fix for table insert of GetAliveSet 2025-07-03 16:39:24 +02:00
Thomas 33e63a4819 Merge pull request #2330 from shaji-Dev/master
[FIXED] index `nil` at  `MARKEROPS_BASE:OnEventMark`
2025-07-03 15:14:11 +02:00
smiki 3543b2c79a [FIXED] index nil at MARKEROPS_BASE:OnEventMark 2025-07-03 14:59:07 +02:00
Applevangelist 4489efff94 #POSITIONABLE - make GetVec3/GetCoordinate a bit more robust 2025-07-03 14:57:48 +02:00
Applevangelist 6a4bddde99 #SET - do not create a new SET on GetAliveSet is we only send back the object table 2025-07-03 11:58:44 +02:00
Thomas dc2511942c Merge pull request #2329 from shaji-Dev/master
[FIXED] Memory leaks
2025-07-03 10:52:40 +02:00
Thomas f0c257c4a5 Merge branch 'master' into master 2025-07-03 10:52:29 +02:00
Applevangelist 068d21612f #MARKEROPS - do not crate a COORDINATE b4 you need it
#UTILS - added
* UTILS.ShowHelperGate(pos, heading)
* UTILS.ShellZone
* UTILS.RemoveObjects
* UTILS.DestroyScenery
2025-07-03 10:48:54 +02:00
smiki 773461aad9 [FIXED] Memory leaks 2025-07-03 09:54:07 +02:00
smiki f9257b2b0d [FIXED] Memory leaks 2025-07-03 09:45:21 +02:00
smiki 9e0f03a3cd [FIXED] Memory leaks 2025-07-03 08:44:41 +02:00
Thomas a467fabdc8 Merge pull request #2327 from leka1986/patch-1
Update CTLD.lua
2025-06-24 19:26:36 +02:00
leka1986 a2ab84c45a Update CTLD.lua
Added Herc fix when dropping from air.

Added CratesName in the OnAfterCratesBuildStarted parm
2025-06-24 19:24:00 +02:00
Thomas 9fd6729967 Merge pull request #2325 from FlightControl-Master/Applevangelist-patch-1-1
Update Airbase.lua
2025-06-24 18:22:18 +02:00
Thomas f1d4f1753a Update Airbase.lua 2025-06-24 16:28:46 +02:00
Frank 6d9c3fd0aa Merge pull request #2324 from FlightControl-Master/FF/MasterDevel
AIRBOSS Essex+Corsair
2025-06-23 22:41:16 +02:00
Frank 28ae63bd8d Update Airboss.lua 2025-06-23 22:39:52 +02:00
Frank 42e7e3f94f Update Airboss.lua 2025-06-23 22:28:48 +02:00
Thomas 6466c5e95e Merge pull request #2322 from leka1986/master
Merge branch 'master' of https://github.com/FlightControl-Master/MOOSE
2025-06-23 19:02:56 +02:00
leka1986 829f5af25f Merge branch 'master' of https://github.com/FlightControl-Master/MOOSE 2025-06-23 18:28:08 +02:00
leka1986 0d1147bac4 Added the missing lines to check if the droped troop is engineer, then start the engineer instance. Added missing messages when dropping single crate type, ie truck for example. Added a call to refreshdropcratesmenu in the takeoff / land event. Drop and build is only created if fixedwing is on the ground. 2025-06-23 18:28:02 +02:00
Frank 24b47b02e0 AIRBOSS
- Essex
- Corsair
2025-06-22 22:29:52 +02:00
Thomas 3cabc07d58 Merge pull request #2320 from shaji-Dev/master
[ADDED] New Kola Airbases
2025-06-20 14:01:24 +02:00
shaji b0546b1e60 [ADDED] New Kola Airbases 2025-06-20 12:58:50 +02:00
shaji a988e67490 [ADDED] New Kola Airbases 2025-06-20 12:20:58 +02:00
Thomas 2594c5bbf0 Merge pull request #2318 from shaji-Dev/master
[FIXED] Error: attempt to index local 'Schedule' (a nil value)
2025-06-19 09:15:42 +02:00
shaji db70fa341c Merge remote-tracking branch 'origin/master' 2025-06-19 07:42:52 +02:00
shaji 763e3852ac [FIXED] Error: attempt to index local 'Schedule' (a nil value) 2025-06-19 07:42:29 +02:00
Thomas 8ec86973c6 Update SpawnStatic.lua
Fix SpawnFromZone()
2025-06-18 14:29:34 +02:00
Thomas eb2c6ac6f2 Update SRS.lua
#MSRS Voice mapping correction
2025-06-18 14:19:50 +02:00
Applevangelist cbcc893ce5 #CTLD - avoid smoking runways on airbase zones 2025-06-15 17:01:58 +02:00
Applevangelist 382b049c5f #AIRBASE - Syria and Sinai few names corrected 2025-06-15 15:38:12 +02:00
Thomas a53763221c Update Airbase.lua
Correct afb name gor Borg al arab on Sinai
2025-06-15 13:14:05 +02:00
Thomas b7bac28113 Merge pull request #2313 from FlightControl-Master/Applevangelist-patch-1
Update CSAR.lua
2025-06-15 10:18:01 +02:00
Thomas a9edb16554 Update CSAR.lua
Make static and zone mash SETs dynamic
2025-06-15 10:17:32 +02:00
Applevangelist 0aeb1fc6af #UTILS - Small fix for GetReportingName to distinguish Shark from Mainstay 2025-06-10 18:05:02 +02:00
Applevangelist eeeeda4e5e #POINT - Offset options for smoke 2025-06-08 18:43:01 +02:00
Applevangelist f5881eda53 AIRBOSS - Remove useless E Messages for non-debug 2025-06-01 12:19:42 +02:00
Thomas c1997d9f70 Merge pull request #2311 from FlightControl-Master/Applevangelist-patch-1
Update CSAR.lua
2025-05-30 18:37:50 +02:00
Thomas bb1caa6642 Update CSAR.lua 2025-05-30 18:37:38 +02:00
Applevangelist dd5ca93f26 CSAR Small addition 2025-05-30 11:13:50 +02:00
Thomas 1889df4952 Merge pull request #2308 from shaji-Dev/master
[FIXED] Velocity is taking into account dead units for GROUP
2025-05-25 09:12:04 +02:00
shaji 7ca219748d [FIXED] Velocity is taking into account dead units for GROUP 2025-05-24 19:46:20 +02:00
Applevangelist 2fc16ba694 Runway text duplication 2025-05-24 15:53:43 +02:00
Applevangelist a4feafab8e #POINT - improved IsDay() for Kola 2025-05-21 10:21:48 +02:00
Applevangelist 997baf21a0 #CSAR fix for ADF beacons 2025-05-21 10:04:58 +02:00
Applevangelist b126cc00d0 xx 2025-05-16 13:43:03 +02:00
Applevangelist 09b7922b84 Small fixes 2025-05-16 11:58:40 +02:00
Applevangelist 7a5b9a75f3 #AIRBASE - added Syria Marka AFB 2025-05-15 17:07:55 +02:00
Applevangelist 4bab2ee1de Add deprecated banner 2025-05-15 13:19:42 +02:00
Applevangelist d7defe6f7f xx 2025-05-15 11:42:05 +02:00
Applevangelist db869bcb6d #MANTIS - Make DLINK caching (DEV version) configureable 2025-05-15 08:51:30 +02:00
Thomas ea4a1f9ff9 Merge pull request #2305 from shaji-Dev/master
[FIXED] Kola Airbase name "Alakourtti" to "Alakurtti"
2025-05-15 06:42:07 +02:00
shaji 20406e40ca [FIXED] Kola Airbase name "Alakourtti" to "Alakurtti" 2025-05-15 01:17:55 +02:00
Applevangelist 3b50fee5a0 #CTLD - extract troops, check for groupname in task properties of PLAYERTASKs, so the right people rescue the correct group 2025-05-12 17:50:37 +02:00
Applevangelist 804004198b #MANTIS - Update docu 2025-05-12 17:49:25 +02:00
Thomas 5b8b8a5566 Merge pull request #2303 from leka1986/master
Fix Line 77390: attempt to index local 'zonecoord' (a nil value)
2025-05-12 07:00:19 +02:00
leka1986 0468bacc0b Fix Line 77390: attempt to index local 'zonecoord' (a nil value) 2025-05-11 21:15:31 +02:00
Thomas 7eba1349ae Merge pull request #2301 from leka1986/master
VS Code pointed out some errors, like duplicated values in tables. This is first time I do changes through VS Code, Hope for the best
2025-05-04 10:47:28 +02:00
leka1986 b6074a4795 VS Code pointed out some errors, like duplicated values in tables. This is first time I do changes through VS Code, Hope for the best 2025-05-04 10:38:44 +02:00
Thomas 36c9f551d9 Merge pull request #2299 from leka1986/patch-3
Update CTLD.lua
2025-05-03 20:32:40 +02:00
leka1986 89c3f7310b Update CTLD.lua
Changed the naming from Get only to Get

and the order is Get, Get and load
Instead of Get and load, and Get only.

Changed the order on Pack and load, Pack and remove, pack only to 
Pack, Pack and load, Pack and remove.

Same goes for Drop and build, Drop only to Drop, Drop and build.

It purely subjective what one would like, so I leave it up to you. If you like it this way or the first version, you decide, then disregard this change.
2025-05-03 19:22:59 +02:00
Applevangelist a6b622ed31 #CTLD - Additional features by Lekaa to drop and build one/many in one go and pack/load or get/load in one go 2025-05-03 17:01:02 +02:00
Frank f1af3a50b8 Update Unit.lua
- GetAmmo HE shells can also be named "HESH"
2025-05-02 21:36:03 +02:00
Applevangelist 0c90e90c18 #CSAR - fixed design issue that prevented usage of ZONE objects as MASHes 2025-05-02 10:53:02 +02:00
Frank f97ef25104 Update Unit.lua 2025-05-01 22:11:43 +02:00
Thomas 069c0aa03f Merge pull request #2297 from FlightControl-Master/Applevangelist-patch-1
Update CTLD.lua
2025-04-28 09:20:58 +02:00
Thomas b145588ed5 Update CTLD.lua
Fix an issue when a ship is used as loading zone and the ship is destroyed
2025-04-28 09:20:04 +02:00
Applevangelist 3ad60a95ce #MANTIS - Adde Gepard data, made Roland Short 2025-04-27 11:25:46 +02:00
Frank ac4b620f16 COORDINATE
- Improved Smoke and Fire and Smoke functions by adding delay and duration parameters
2025-04-26 23:39:22 +02:00
Thomas ccada18a6a Merge pull request #2295 from leka1986/patch-2
Update CTLD.lua
2025-04-26 07:52:01 +02:00
leka1986 1547d66327 Update CTLD.lua
Getting rid of this error,
bad argument #1 to 'find' (string expected, got nil)
2025-04-26 03:28:16 +02:00
Thomas 8042e8bfaf Merge pull request #2293 from shaji-Dev/master
[ADDED] AIRBOSS:SetMaxSectionDistance
2025-04-23 14:21:31 +02:00
shaji dd7b87e9cd [ADDED] AIRBOSS:SetMaxSectionDistance 2025-04-23 13:39:55 +02:00
Thomas 460d2768ff Merge pull request #2291 from FlightControl-Master/Applevangelist-patch-1
Update Range.lua
2025-04-23 09:03:54 +02:00
Thomas 3c74272749 Update Range.lua
#RANGE log an error if os/os.date() are not available
2025-04-23 09:00:05 +02:00
Thomas 82c409d77a Merge pull request #2289 from shaji-Dev/master
[ADDED] IsAlive condition for Unit and Group out message
2025-04-23 06:28:13 +02:00
shaji 195aac4504 [ADDED] IsAlive condition for Unit and Group out message 2025-04-22 20:57:06 +02:00
Thomas 08d8f3e25f Merge pull request #2285 from shaji-Dev/master
[ADDED] New Kola airbases
2025-04-21 19:37:22 +02:00
shaji 6f72697e26 [ADDED] New Kola airbases
-- * AIRBASE.Kola.Alta
-- * AIRBASE.Kola.Sodankyla
-- * AIRBASE.Kola.Enontekio
-- * AIRBASE.Kola.Evenes
-- * AIRBASE.Kola.Hosio
2025-04-21 19:11:22 +02:00
Applevangelist 0f6439cf9f #MANTIS - added C-RAM Point Defense 2025-04-20 17:49:25 +02:00
Frank 2c10943cb1 Update Airbase.lua
Germany map Umlaute
2025-04-18 17:50:01 +02:00
Frank 544db963ea Update Airbase.lua 2025-04-18 17:45:43 +02:00
Frank 207698a2dd Update Airbase.lua
- Germany map readded Umlaute in keys
2025-04-18 17:40:55 +02:00
Applevangelist d1ae2c0f5e xx 2025-04-18 16:01:55 +02:00
Applevangelist 0392417189 Germany CW Bases 2025-04-18 14:46:13 +02:00
Frank be4beea9d0 Update Airbase.lua
- Removed umlauts and ß in airbase names
2025-04-17 21:34:01 +02:00
Frank 5da899138b Merge pull request #2284 from FlightControl-Master/FF/MasterDevel
Germany CW map
2025-04-17 21:19:48 +02:00
Frank 1ec1e00bde Germany CW map
- ATIS Germany map
- UTILS magnetic declination
2025-04-17 21:19:01 +02:00
Thomas 5d93b33d42 Merge pull request #2282 from shaji-Dev/master
[FIXED] Returns nil for late activated templates we use to mark paths to use in our scripts
2025-04-17 08:44:38 +02:00
shaji b2077bfc74 [FIXED] Returns nil for late activated templates we use to mark waypoint paths to use in the scripts. 2025-04-16 19:59:13 +02:00
Applevangelist 6fdf9a649f #AIRBASE rescribe umlauts 2025-04-14 12:23:12 +02:00
Applevangelist d013bbc751 #STORAGE Enum, some additions 2025-04-14 12:11:27 +02:00
Applevangelist e0092fdba0 #AIRBASE GermanCW Map airbases 2025-04-14 11:37:45 +02:00
Thomas fbeada439f Merge pull request #2278 from leka1986/patch-5
Update Group.lua
2025-04-12 10:51:42 +02:00
Thomas 6c8858d2f5 Merge pull request #2280 from leka1986/patch-7
Update Set.lua
2025-04-12 10:51:00 +02:00
Thomas e2b77878df Merge pull request #2279 from leka1986/patch-6
Update Event.lua
2025-04-12 10:50:39 +02:00
leka1986 53d7972858 Update Set.lua
Removed the Filter={},
2025-04-12 10:48:22 +02:00
leka1986 04a55e4104 Update Event.lua
Added nil checks which was causing nil. had this for a few weeks with no errors.
2025-04-12 10:44:29 +02:00
leka1986 d11acecdac Update Group.lua
Fix for the error attempt to index a nil value called from suppression
2025-04-12 10:26:34 +02:00
Applevangelist 49c11073e6 #MANTIS Mod data updates 2025-04-09 08:15:50 +02:00
Applevangelist 1a156e7e12 #CTLD - make menu build for CA a bit faster 2025-04-07 11:57:15 +02:00
Applevangelist 1856754614 #Smaller Changes 2025-04-07 10:40:30 +02:00
Thomas 6ac452ff15 Update docs-header.py 2025-04-06 16:28:19 +02:00
Applevangelist d707a4775c xx 2025-04-06 16:19:12 +02:00
Thomas ffccc31e38 Update CargoGroup.lua 2025-04-06 16:12:13 +02:00
Thomas 0405af2bde Update docs-header.py 2025-04-06 16:04:07 +02:00
Thomas e50e572c78 Update classes-core.md 2025-04-06 15:43:09 +02:00
Applevangelist 3083599158 #CTLD - Allow CA Ground Transport 2025-04-06 15:38:26 +02:00
Applevangelist b7b6c1ea19 #RADIOQUEUE - small tweak for a group when a unit dies. 2025-04-03 14:21:58 +02:00
Applevangelist 5b107ce2da #CONTROLLABLE:CommandSmokeOnOff(OnOff, Delay) added 2025-04-03 11:48:53 +02:00
Thomas 5c1e342a79 Update classes-core.md 2025-04-03 09:33:49 +02:00
Applevangelist ddf33da787 #DYNAMICCARGO - Hover / Sling checks 2025-04-03 09:29:19 +02:00
Thomas b0a192a767 Update DynamicCargo.lua
small fix
2025-04-02 16:12:06 +02:00
Thomas 986c340211 Merge pull request #2275 from FlightControl-Master/Applevangelist-patch-1
Update classes-core.md
2025-04-02 09:54:54 +02:00
Thomas 2109537f86 Update classes-core.md
fix
2025-04-02 09:54:20 +02:00
Thomas 690db7f12f Merge pull request #2273 from FlightControl-Master/Applevangelist-SpawnStatic-1
Update SpawnStatic.lua
2025-04-02 09:43:04 +02:00
Thomas 4f3fd06cc9 Update SpawnStatic.lua
Restored previous version as overwritten
2025-04-02 09:42:02 +02:00
Applevangelist 4074023ed3 #DYNAMICCARGO - enhance checks for unloading cargo from hovering Hooks 2025-04-01 15:27:23 +02:00
Applevangelist 6c00b0c7eb #POINT - some catches for POINT_VEC2 behaviour 2025-04-01 14:13:14 +02:00
Applevangelist 76dc0d690a #POINT - Removal of References to legacy POINT_VEC2/3 classes 2025-04-01 13:17:48 +02:00
Thomas d783f7be99 Merge pull request #2270 from FlightControl-Master/Applevangelist-patch-1
Update DynamicCargo.lua
2025-03-31 12:31:52 +02:00
Thomas b66e91b11f Update DynamicCargo.lua
#DYNAMICCARGO small fixes
2025-03-31 12:31:23 +02:00
103 changed files with 11856 additions and 6426 deletions
+1 -1
View File
@@ -1953,7 +1953,7 @@ local function refct_from_id(id) -- refct = refct_from_id(CTypeID)
unsigned = refct.unsigned,
size = bit.band(bit.rshift(ctype.info, 16), 127),
}
refct.bool, refct.const, refct.volatile, refct.unsigned = nil
refct.bool, refct.const, refct.volatile, refct.unsigned = nil, nil, nil, nil
end
if CT[4] then -- Merge sibling attributes onto this type.
+3 -1
View File
@@ -17,7 +17,9 @@
--- The AI_A2A_CAP class implements the core functions to patrol a @{Core.Zone} by an AI @{Wrapper.Group} or @{Wrapper.Group}
-- and automatically engage any airborne enemies that are within a certain range or within a certain zone.
--
--
-- ![Banner Image](..\Images\deprecated.png)
--
-- ![Process](..\Presentations\AI_CAP\Dia3.JPG)
--
-- The AI_A2A_CAP is assigned a @{Wrapper.Group} and this must be done before the AI_A2A_CAP process can be started using the **Start** event.
@@ -32,7 +32,9 @@
-- [DCS WORLD - MOOSE - A2A GCICAP - Build an automatic A2A Defense System](https://www.youtube.com/playlist?list=PL7ZUrU4zZUl0S4KMNUUJpaUs6zZHjLKNx)
--
-- ===
--
--
-- ![Banner Image](..\Images\deprecated.png)
--
-- # QUICK START GUIDE
--
-- There are basically two classes available to model an A2A defense system.
@@ -19,6 +19,8 @@
--- Implements the core functions to intercept intruders. Use the Engage trigger to intercept intruders.
--
-- ![Banner Image](..\Images\deprecated.png)
--
-- The AI_A2A_GCI is assigned a @{Wrapper.Group} and this must be done before the AI_A2A_GCI process can be started using the **Start** event.
--
-- The AI will fly towards the random 3D point within the patrol zone, using a random speed within the given altitude and speed limits.
@@ -15,6 +15,8 @@
--- Implements the core functions to patrol a @{Core.Zone} by an AI @{Wrapper.Group} or @{Wrapper.Group}.
--
-- ![Banner Image](..\Images\deprecated.png)
--
-- ![Process](..\Presentations\AI_PATROL\Dia3.JPG)
--
-- The AI_A2A_PATROL is assigned a @{Wrapper.Group} and this must be done before the AI_A2A_PATROL process can be started using the **Start** event.
+3 -1
View File
@@ -16,7 +16,9 @@
-- @extends AI.AI_Air_Engage#AI_AIR_ENGAGE
--- Implements the core functions to intercept intruders. Use the Engage trigger to intercept intruders.
--
--
-- ![Banner Image](..\Images\deprecated.png)
--
-- # Developer Note
--
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
@@ -19,6 +19,8 @@
--
-- # Developer Note
--
-- ![Banner Image](..\Images\deprecated.png)
--
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
-- Therefore, this class is considered to be deprecated
--
@@ -36,6 +36,8 @@
--
-- # QUICK START GUIDE
--
-- ![Banner Image](..\Images\deprecated.png)
--
-- The following class is available to model an A2G defense system.
--
-- AI_A2G_DISPATCHER is the main A2G defense class that models the A2G defense system.
@@ -20,6 +20,8 @@
--- Implements the core functions to SEAD intruders. Use the Engage trigger to intercept intruders.
--
-- ![Banner Image](..\Images\deprecated.png)
--
-- The AI_A2G_SEAD is assigned a @{Wrapper.Group} and this must be done before the AI_A2G_SEAD process can be started using the **Start** event.
--
-- The AI will fly towards the random 3D point within the patrol zone, using a random speed within the given altitude and speed limits.
+7 -6
View File
@@ -15,6 +15,7 @@
--- The AI_AIR class implements the core functions to operate an AI @{Wrapper.Group}.
--
-- ![Banner Image](..\Images\deprecated.png)
--
-- # 1) AI_AIR constructor
--
@@ -657,8 +658,8 @@ function AI_AIR:onafterRTB( AIGroup, From, Event, To )
--- Create a route point of type air.
local FromRTBRoutePoint = FromCoord:WaypointAir(
self.PatrolAltType,
POINT_VEC3.RoutePointType.TurningPoint,
POINT_VEC3.RoutePointAction.TurningPoint,
COORDINATE.WaypointType.TurningPoint,
COORDINATE.WaypointAction.TurningPoint,
RTBSpeed,
true
)
@@ -666,8 +667,8 @@ function AI_AIR:onafterRTB( AIGroup, From, Event, To )
--- Create a route point of type air.
local ToRTBRoutePoint = ToAirbaseCoord:WaypointAir(
self.PatrolAltType,
POINT_VEC3.RoutePointType.TurningPoint,
POINT_VEC3.RoutePointAction.TurningPoint,
COORDINATE.WaypointType.TurningPoint,
COORDINATE.WaypointAction.TurningPoint,
RTBSpeed,
true
)
@@ -761,10 +762,10 @@ function AI_AIR:onafterRefuel( AIGroup, From, Event, To )
local ToRefuelSpeed = math.random( self.PatrolMinSpeed, self.PatrolMaxSpeed )
--- Create a route point of type air.
local FromRefuelRoutePoint = FromRefuelCoord:WaypointAir(self.PatrolAltType, POINT_VEC3.RoutePointType.TurningPoint, POINT_VEC3.RoutePointAction.TurningPoint, ToRefuelSpeed, true)
local FromRefuelRoutePoint = FromRefuelCoord:WaypointAir(self.PatrolAltType, COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.TurningPoint, ToRefuelSpeed, true)
--- Create a route point of type air. NOT used!
local ToRefuelRoutePoint = Tanker:GetCoordinate():WaypointAir(self.PatrolAltType, POINT_VEC3.RoutePointType.TurningPoint, POINT_VEC3.RoutePointAction.TurningPoint, ToRefuelSpeed, true)
local ToRefuelRoutePoint = Tanker:GetCoordinate():WaypointAir(self.PatrolAltType, COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.TurningPoint, ToRefuelSpeed, true)
self:F( { ToRefuelSpeed = ToRefuelSpeed } )
@@ -36,6 +36,8 @@
--
-- # QUICK START GUIDE
--
-- ![Banner Image](..\Images\deprecated.png)
--
-- The following class is available to model an AIR defense system.
--
-- AI_AIR_DISPATCHER is the main AIR defense class that models the AIR defense system.
+7 -5
View File
@@ -13,12 +13,14 @@
-- @type AI_AIR_ENGAGE
--- @type AI_AIR_ENGAGE
-- @extends AI.AI_AIR#AI_AIR
--- Implements the core functions to intercept intruders. Use the Engage trigger to intercept intruders.
--
-- ![Banner Image](..\Images\deprecated.png)
--
-- The AI_AIR_ENGAGE is assigned a @{Wrapper.Group} and this must be done before the AI_AIR_ENGAGE process can be started using the **Start** event.
--
-- The AI will fly towards the random 3D point within the patrol zone, using a random speed within the given altitude and speed limits.
@@ -453,7 +455,7 @@ function AI_AIR_ENGAGE:onafterEngageRoute( DefenderGroup, From, Event, To, Attac
--- Calculate the target route point.
local FromWP = DefenderCoord:WaypointAir(self.PatrolAltType or "RADIO", POINT_VEC3.RoutePointType.TurningPoint, POINT_VEC3.RoutePointAction.TurningPoint, EngageSpeed, true)
local FromWP = DefenderCoord:WaypointAir(self.PatrolAltType or "RADIO", COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.TurningPoint, EngageSpeed, true)
EngageRoute[#EngageRoute+1] = FromWP
@@ -462,7 +464,7 @@ function AI_AIR_ENGAGE:onafterEngageRoute( DefenderGroup, From, Event, To, Attac
local FromEngageAngle = DefenderCoord:GetAngleDegrees( DefenderCoord:GetDirectionVec3( TargetCoord ) )
local ToCoord=DefenderCoord:Translate( EngageDistance, FromEngageAngle, true )
local ToWP = ToCoord:WaypointAir(self.PatrolAltType or "RADIO", POINT_VEC3.RoutePointType.TurningPoint, POINT_VEC3.RoutePointAction.TurningPoint, EngageSpeed, true)
local ToWP = ToCoord:WaypointAir(self.PatrolAltType or "RADIO", COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.TurningPoint, EngageSpeed, true)
EngageRoute[#EngageRoute+1] = ToWP
@@ -536,7 +538,7 @@ function AI_AIR_ENGAGE:onafterEngage( DefenderGroup, From, Event, To, AttackSetU
local EngageRoute = {}
local AttackTasks = {}
local FromWP = DefenderCoord:WaypointAir(self.EngageAltType or "RADIO", POINT_VEC3.RoutePointType.TurningPoint, POINT_VEC3.RoutePointAction.TurningPoint, EngageSpeed, true)
local FromWP = DefenderCoord:WaypointAir(self.EngageAltType or "RADIO", COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.TurningPoint, EngageSpeed, true)
EngageRoute[#EngageRoute+1] = FromWP
self:SetTargetDistance( TargetCoord ) -- For RTB status check
@@ -544,7 +546,7 @@ function AI_AIR_ENGAGE:onafterEngage( DefenderGroup, From, Event, To, AttackSetU
local FromEngageAngle = DefenderCoord:GetAngleDegrees( DefenderCoord:GetDirectionVec3( TargetCoord ) )
local ToCoord=DefenderCoord:Translate( EngageDistance, FromEngageAngle, true )
local ToWP = ToCoord:WaypointAir(self.EngageAltType or "RADIO", POINT_VEC3.RoutePointType.TurningPoint, POINT_VEC3.RoutePointAction.TurningPoint, EngageSpeed, true)
local ToWP = ToCoord:WaypointAir(self.EngageAltType or "RADIO", COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.TurningPoint, EngageSpeed, true)
EngageRoute[#EngageRoute+1] = ToWP
-- TODO: A factor of * 3 this way too low. This causes the AI NOT to engage until very close or even merged sometimes. Some A2A missiles have a much longer range! Needs more frequent updates of the task!
+5 -3
View File
@@ -15,6 +15,8 @@
--- The AI_AIR_PATROL class implements the core functions to patrol a @{Core.Zone} by an AI @{Wrapper.Group}
-- and automatically engage any airborne enemies that are within a certain range or within a certain zone.
--
-- ![Banner Image](..\Images\deprecated.png)
--
-- ![Process](..\Presentations\AI_CAP\Dia3.JPG)
--
-- The AI_AIR_PATROL is assigned a @{Wrapper.Group} and this must be done before the AI_AIR_PATROL process can be started using the **Start** event.
@@ -309,7 +311,7 @@ function AI_AIR_PATROL:onafterPatrolRoute( AIPatrol, From, Event, To )
local ToTargetSpeed = math.random( self.PatrolMinSpeed, self.PatrolMaxSpeed )
local speedkmh=ToTargetSpeed
local FromWP = CurrentCoord:WaypointAir(self.PatrolAltType or "RADIO", POINT_VEC3.RoutePointType.TurningPoint, POINT_VEC3.RoutePointAction.TurningPoint, ToTargetSpeed, true)
local FromWP = CurrentCoord:WaypointAir(self.PatrolAltType or "RADIO", COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.TurningPoint, ToTargetSpeed, true)
PatrolRoute[#PatrolRoute+1] = FromWP
if self.racetrack then
@@ -359,9 +361,9 @@ function AI_AIR_PATROL:onafterPatrolRoute( AIPatrol, From, Event, To )
else
--- Create a route point of type air.
local ToWP = ToTargetCoord:WaypointAir(self.PatrolAltType, POINT_VEC3.RoutePointType.TurningPoint, POINT_VEC3.RoutePointAction.TurningPoint, ToTargetSpeed, true)
local ToWP = ToTargetCoord:WaypointAir(self.PatrolAltType, COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.TurningPoint, ToTargetSpeed, true)
PatrolRoute[#PatrolRoute+1] = ToWP
local Tasks = {}
Tasks[#Tasks+1] = AIPatrol:TaskFunction("AI_AIR_PATROL.___PatrolRoute", self)
PatrolRoute[#PatrolRoute].task = AIPatrol:TaskCombo( Tasks )
@@ -13,7 +13,7 @@
-- @type AI_AIR_SQUADRON
--- @type AI_AIR_SQUADRON
-- @extends Core.Base#BASE
@@ -21,6 +21,8 @@
--
-- # Developer Note
--
-- ![Banner Image](..\Images\deprecated.png)
--
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
-- Therefore, this class is considered to be deprecated
--
+8 -6
View File
@@ -38,6 +38,8 @@
--- Implements the core functions to provide BattleGround Air Interdiction in an Engage @{Core.Zone} by an AIR @{Wrapper.Controllable} or @{Wrapper.Group}.
--
-- ![Banner Image](..\Images\deprecated.png)
--
-- The AI_BAI_ZONE runs a process. It holds an AI in a Patrol Zone and when the AI is commanded to engage, it will fly to an Engage Zone.
--
-- ![HoldAndEngage](..\Presentations\AI_BAI\Dia3.JPG)
@@ -521,12 +523,12 @@ function AI_BAI_ZONE:onafterEngage( Controllable, From, Event, To,
--DONE: Create GetAltitude function for GROUP, and delete GetUnit(1).
local CurrentAltitude = self.Controllable:GetAltitude()
local CurrentPointVec3 = POINT_VEC3:New( CurrentVec2.x, CurrentAltitude, CurrentVec2.y )
local CurrentPointVec3 = COORDINATE:New( CurrentVec2.x, CurrentAltitude, CurrentVec2.y )
local ToEngageZoneSpeed = self.PatrolMaxSpeed
local CurrentRoutePoint = CurrentPointVec3:WaypointAir(
self.PatrolAltType,
POINT_VEC3.RoutePointType.TurningPoint,
POINT_VEC3.RoutePointAction.TurningPoint,
COORDINATE.WaypointType.TurningPoint,
COORDINATE.WaypointAction.TurningPoint,
self.EngageSpeed,
true
)
@@ -577,13 +579,13 @@ function AI_BAI_ZONE:onafterEngage( Controllable, From, Event, To,
self:T2( ToTargetVec2 )
--- Obtain a 3D @{Point} from the 2D point + altitude.
local ToTargetPointVec3 = POINT_VEC3:New( ToTargetVec2.x, self.EngageAltitude, ToTargetVec2.y )
local ToTargetPointVec3 = COORDINATE:New( ToTargetVec2.x, self.EngageAltitude, ToTargetVec2.y )
--- Create a route point of type air.
local ToTargetRoutePoint = ToTargetPointVec3:WaypointAir(
self.PatrolAltType,
POINT_VEC3.RoutePointType.TurningPoint,
POINT_VEC3.RoutePointAction.TurningPoint,
COORDINATE.WaypointType.TurningPoint,
COORDINATE.WaypointAction.TurningPoint,
self.EngageSpeed,
true
)
+4 -10
View File
@@ -33,8 +33,9 @@
-- @field Wrapper.Group#GROUP Test
-- @extends Core.Fsm#FSM_SET
--- Monitors and manages as many replacement AI groups as there are
--- ![Banner Image](..\Images\deprecated.png)
--
-- Monitors and manages as many replacement AI groups as there are
-- CLIENTS in a SET\_CLIENT collection, which are not occupied by human players.
-- In other words, use AI_BALANCER to simulate human behaviour by spawning in replacement AI in multi player missions.
--
@@ -220,16 +221,9 @@ function AI_BALANCER:onenterReturning( SetGroup, From, Event, To, AIGroup )
AIGroup:MessageToRed( "Returning to home base ...", 30 )
else
-- Okay, we need to send this Group back to the nearest base of the Coalition of the AI.
--TODO: i need to rework the POINT_VEC2 thing.
local PointVec2 = POINT_VEC2:New( AIGroup:GetVec2().x, AIGroup:GetVec2().y )
local PointVec2 = COORDINATE:New(AIGroup:GetVec2().x, 0, AIGroup:GetVec2().y)
local ClosestAirbase = self.ReturnAirbaseSet:FindNearestAirbaseFromPointVec2( PointVec2 )
self:T( ClosestAirbase.AirbaseName )
--[[
AIGroup:MessageToRed( "Returning to " .. ClosestAirbase:GetName().. " ...", 30 )
local RTBRoute = AIGroup:RouteReturnToAirbase( ClosestAirbase )
AIGroupTemplate.route = RTBRoute
AIGroup:Respawn( AIGroupTemplate )
]]
AIGroup:RouteRTB(ClosestAirbase)
end
+8 -6
View File
@@ -39,6 +39,8 @@
--- Implements the core functions to patrol a @{Core.Zone} by an AI @{Wrapper.Controllable} or @{Wrapper.Group}
-- and automatically engage any airborne enemies that are within a certain range or within a certain zone.
--
-- ![Banner Image](..\Images\deprecated.png)
--
-- ![Process](..\Presentations\AI_CAP\Dia3.JPG)
--
-- The AI_CAP_ZONE is assigned a @{Wrapper.Group} and this must be done before the AI_CAP_ZONE process can be started using the **Start** event.
@@ -423,12 +425,12 @@ function AI_CAP_ZONE:onafterEngage( Controllable, From, Event, To )
--DONE: Create GetAltitude function for GROUP, and delete GetUnit(1).
local CurrentAltitude = self.Controllable:GetAltitude()
local CurrentPointVec3 = POINT_VEC3:New( CurrentVec2.x, CurrentAltitude, CurrentVec2.y )
local CurrentPointVec3 = COORDINATE:New( CurrentVec2.x, CurrentAltitude, CurrentVec2.y )
local ToEngageZoneSpeed = self.PatrolMaxSpeed
local CurrentRoutePoint = CurrentPointVec3:WaypointAir(
self.PatrolAltType,
POINT_VEC3.RoutePointType.TurningPoint,
POINT_VEC3.RoutePointAction.TurningPoint,
COORDINATE.WaypointType.TurningPoint,
COORDINATE.WaypointAction.TurningPoint,
ToEngageZoneSpeed,
true
)
@@ -445,13 +447,13 @@ function AI_CAP_ZONE:onafterEngage( Controllable, From, Event, To )
self:T2( { self.PatrolMinSpeed, self.PatrolMaxSpeed, ToTargetSpeed } )
--- Obtain a 3D @{Point} from the 2D point + altitude.
local ToTargetPointVec3 = POINT_VEC3:New( ToTargetVec2.x, ToTargetAltitude, ToTargetVec2.y )
local ToTargetPointVec3 = COORDINATE:New( ToTargetVec2.x, ToTargetAltitude, ToTargetVec2.y )
--- Create a route point of type air.
local ToPatrolRoutePoint = ToTargetPointVec3:WaypointAir(
self.PatrolAltType,
POINT_VEC3.RoutePointType.TurningPoint,
POINT_VEC3.RoutePointAction.TurningPoint,
COORDINATE.WaypointType.TurningPoint,
COORDINATE.WaypointAction.TurningPoint,
ToTargetSpeed,
true
)
+9 -6
View File
@@ -38,6 +38,9 @@
-- @extends AI.AI_Patrol#AI_PATROL_ZONE
--- Implements the core functions to provide Close Air Support in an Engage @{Core.Zone} by an AIR @{Wrapper.Controllable} or @{Wrapper.Group}.
--
-- ![Banner Image](..\Images\deprecated.png)
--
-- The AI_CAS_ZONE runs a process. It holds an AI in a Patrol Zone and when the AI is commanded to engage, it will fly to an Engage Zone.
--
-- ![HoldAndEngage](..\Presentations\AI_CAS\Dia3.JPG)
@@ -466,12 +469,12 @@ function AI_CAS_ZONE:onafterEngage( Controllable, From, Event, To,
--DONE: Create GetAltitude function for GROUP, and delete GetUnit(1).
local CurrentAltitude = self.Controllable:GetAltitude()
local CurrentPointVec3 = POINT_VEC3:New( CurrentVec2.x, CurrentAltitude, CurrentVec2.y )
local CurrentPointVec3 = COORDINATE:New( CurrentVec2.x, CurrentAltitude, CurrentVec2.y )
local ToEngageZoneSpeed = self.PatrolMaxSpeed
local CurrentRoutePoint = CurrentPointVec3:WaypointAir(
self.PatrolAltType,
POINT_VEC3.RoutePointType.TurningPoint,
POINT_VEC3.RoutePointAction.TurningPoint,
COORDINATE.WaypointType.TurningPoint,
COORDINATE.WaypointAction.TurningPoint,
self.EngageSpeed,
true
)
@@ -508,13 +511,13 @@ function AI_CAS_ZONE:onafterEngage( Controllable, From, Event, To,
self:T2( ToTargetVec2 )
--- Obtain a 3D @{Point} from the 2D point + altitude.
local ToTargetPointVec3 = POINT_VEC3:New( ToTargetVec2.x, self.EngageAltitude, ToTargetVec2.y )
local ToTargetPointVec3 = COORDINATE:New( ToTargetVec2.x, self.EngageAltitude, ToTargetVec2.y )
--- Create a route point of type air.
local ToTargetRoutePoint = ToTargetPointVec3:WaypointAir(
self.PatrolAltType,
POINT_VEC3.RoutePointType.TurningPoint,
POINT_VEC3.RoutePointAction.TurningPoint,
COORDINATE.WaypointType.TurningPoint,
COORDINATE.WaypointAction.TurningPoint,
self.EngageSpeed,
true
)
+3 -1
View File
@@ -9,12 +9,14 @@
-- @module AI.AI_Cargo
-- @image Cargo.JPG
-- @type AI_CARGO
--- @type AI_CARGO
-- @extends Core.Fsm#FSM_CONTROLLABLE
--- Base class for the dynamic cargo handling capability for AI groups.
--
-- ![Banner Image](..\Images\deprecated.png)
--
-- Carriers can be mobilized to intelligently transport infantry and other cargo within the simulation.
-- The AI_CARGO module uses the @{Cargo.Cargo} capabilities within the MOOSE framework.
-- CARGO derived objects must be declared within the mission to make the AI_CARGO object recognize the cargo.
@@ -15,6 +15,8 @@
--- Brings a dynamic cargo handling capability for an AI vehicle group.
--
-- ![Banner Image](..\Images\deprecated.png)
--
-- Armoured Personnel Carriers (APC), Trucks, Jeeps and other ground based carrier equipment can be mobilized to intelligently transport infantry and other cargo within the simulation.
--
-- The AI_CARGO_APC class uses the @{Cargo.Cargo} capabilities within the MOOSE framework.
@@ -14,6 +14,8 @@
--- Brings a dynamic cargo handling capability for an AI airplane group.
--
-- ![Banner Image](..\Images\deprecated.png)
--
-- Airplane carrier equipment can be mobilized to intelligently transport infantry and other cargo within the simulation between airbases.
--
@@ -440,7 +442,7 @@ function AI_CARGO_AIRPLANE:Route( Airplane, Airbase, Speed, Height, Uncontrolled
-- To point.
local AirbasePointVec2 = Airbase:GetPointVec2()
local ToWaypoint = AirbasePointVec2:WaypointAir(POINT_VEC3.RoutePointAltType.BARO, "Land", "Landing", Speed or Airplane:GetSpeedMax()*0.8, true, Airbase)
local ToWaypoint = AirbasePointVec2:WaypointAir(COORDINATE.WaypointAltType.BARO, "Land", "Landing", Speed or Airplane:GetSpeedMax()*0.8, true, Airbase)
--ToWaypoint["airdromeId"] = Airbase:GetID()
--ToWaypoint["speed_locked"] = true
@@ -22,6 +22,8 @@
--
-- ===
--
-- ![Banner Image](..\Images\deprecated.png)
--
-- # The dispatcher concept.
--
-- Carrier equipment can be mobilized to intelligently transport infantry and other cargo within the simulation.
@@ -36,6 +36,8 @@
--- A dynamic cargo transportation capability for AI groups.
--
-- ![Banner Image](..\Images\deprecated.png)
--
-- Armoured Personnel APCs (APC), Trucks, Jeeps and other carrier equipment can be mobilized to intelligently transport infantry and other cargo within the simulation.
--
-- The AI_CARGO_DISPATCHER_APC module is derived from the AI_CARGO_DISPATCHER module.
@@ -30,6 +30,8 @@
--- Brings a dynamic cargo handling capability for AI groups.
--
-- ![Banner Image](..\Images\deprecated.png)
--
-- Airplanes can be mobilized to intelligently transport infantry and other cargo within the simulation.
--
-- The AI_CARGO_DISPATCHER_AIRPLANE module is derived from the AI_CARGO_DISPATCHER module.
@@ -31,6 +31,8 @@
--- A dynamic cargo handling capability for AI helicopter groups.
--
-- ![Banner Image](..\Images\deprecated.png)
--
-- Helicopters can be mobilized to intelligently transport infantry and other cargo within the simulation.
--
--
@@ -29,6 +29,8 @@
--- A dynamic cargo transportation capability for AI groups.
--
-- ![Banner Image](..\Images\deprecated.png)
--
-- Naval vessels can be mobilized to semi-intelligently transport cargo within the simulation.
--
-- The AI_CARGO_DISPATCHER_SHIP module is derived from the AI_CARGO_DISPATCHER module.
@@ -15,6 +15,8 @@
--- Brings a dynamic cargo handling capability for an AI helicopter group.
--
-- ![Banner Image](..\Images\deprecated.png)
--
-- Helicopter carriers can be mobilized to intelligently transport infantry and other cargo within the simulation.
--
-- The AI_CARGO_HELICOPTER class uses the @{Cargo.Cargo} capabilities within the MOOSE framework.
@@ -367,8 +369,8 @@ function AI_CARGO_HELICOPTER:onafterQueue( Helicopter, From, Event, To, Coordina
-- local CoordinateFrom = Helicopter:GetCoordinate()
-- local WaypointFrom = CoordinateFrom:WaypointAir(
-- "RADIO",
-- POINT_VEC3.RoutePointType.TurningPoint,
-- POINT_VEC3.RoutePointAction.TurningPoint,
-- COORDINATE.WaypointType.TurningPoint,
-- COORDINATE.WaypointAction.TurningPoint,
-- Speed,
-- true
-- )
@@ -380,8 +382,8 @@ function AI_CARGO_HELICOPTER:onafterQueue( Helicopter, From, Event, To, Coordina
local WaypointTo = CoordinateTo:WaypointAir(
"RADIO",
POINT_VEC3.RoutePointType.TurningPoint,
POINT_VEC3.RoutePointAction.TurningPoint,
COORDINATE.WaypointType.TurningPoint,
COORDINATE.WaypointAction.TurningPoint,
50,
true
)
@@ -427,7 +429,7 @@ function AI_CARGO_HELICOPTER:onafterOrbit( Helicopter, From, Event, To, Coordina
local landheight = CoordinateTo:GetLandHeight() -- get target height
CoordinateTo.y = landheight + 50 -- flight height should be 50m above ground
local WaypointTo = CoordinateTo:WaypointAir("RADIO", POINT_VEC3.RoutePointType.TurningPoint, POINT_VEC3.RoutePointAction.TurningPoint, 50, true)
local WaypointTo = CoordinateTo:WaypointAir("RADIO", COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.TurningPoint, 50, true)
Route[#Route+1] = WaypointTo
local Tasks = {}
@@ -496,14 +498,14 @@ function AI_CARGO_HELICOPTER:onafterPickup( Helicopter, From, Event, To, Coordin
local CoordinateFrom = Helicopter:GetCoordinate()
--- Create a route point of type air.
local WaypointFrom = CoordinateFrom:WaypointAir("RADIO", POINT_VEC3.RoutePointType.TurningPoint, POINT_VEC3.RoutePointAction.TurningPoint, _speed, true)
local WaypointFrom = CoordinateFrom:WaypointAir("RADIO", COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.TurningPoint, _speed, true)
--- Create a route point of type air.
local CoordinateTo = Coordinate
local landheight = CoordinateTo:GetLandHeight() -- get target height
CoordinateTo.y = landheight + 50 -- flight height should be 50m above ground
local WaypointTo = CoordinateTo:WaypointAir("RADIO", POINT_VEC3.RoutePointType.TurningPoint, POINT_VEC3.RoutePointAction.TurningPoint,_speed, true)
local WaypointTo = CoordinateTo:WaypointAir("RADIO", COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.TurningPoint,_speed, true)
Route[#Route+1] = WaypointFrom
Route[#Route+1] = WaypointTo
@@ -563,7 +565,7 @@ function AI_CARGO_HELICOPTER:onafterDeploy( Helicopter, From, Event, To, Coordin
--- Create a route point of type air.
local CoordinateFrom = Helicopter:GetCoordinate()
local WaypointFrom = CoordinateFrom:WaypointAir("RADIO", POINT_VEC3.RoutePointType.TurningPoint, POINT_VEC3.RoutePointAction.TurningPoint, _speed, true)
local WaypointFrom = CoordinateFrom:WaypointAir("RADIO", COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.TurningPoint, _speed, true)
Route[#Route+1] = WaypointFrom
Route[#Route+1] = WaypointFrom
@@ -573,7 +575,7 @@ function AI_CARGO_HELICOPTER:onafterDeploy( Helicopter, From, Event, To, Coordin
local landheight = CoordinateTo:GetLandHeight() -- get target height
CoordinateTo.y = landheight + 50 -- flight height should be 50m above ground
local WaypointTo = CoordinateTo:WaypointAir("RADIO", POINT_VEC3.RoutePointType.TurningPoint, POINT_VEC3.RoutePointAction.TurningPoint, _speed, true)
local WaypointTo = CoordinateTo:WaypointAir("RADIO", COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.TurningPoint, _speed, true)
Route[#Route+1] = WaypointTo
Route[#Route+1] = WaypointTo
@@ -631,7 +633,7 @@ function AI_CARGO_HELICOPTER:onafterHome( Helicopter, From, Event, To, Coordinat
--- Create a route point of type air.
local CoordinateFrom = Helicopter:GetCoordinate()
local WaypointFrom = CoordinateFrom:WaypointAir("RADIO", POINT_VEC3.RoutePointType.TurningPoint, POINT_VEC3.RoutePointAction.TurningPoint, Speed, true)
local WaypointFrom = CoordinateFrom:WaypointAir("RADIO", COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.TurningPoint, Speed, true)
Route[#Route+1] = WaypointFrom
--- Create a route point of type air.
@@ -639,7 +641,7 @@ function AI_CARGO_HELICOPTER:onafterHome( Helicopter, From, Event, To, Coordinat
local landheight = CoordinateTo:GetLandHeight() -- get target height
CoordinateTo.y = landheight + Height -- flight height should be 50m above ground
local WaypointTo = CoordinateTo:WaypointAir("RADIO", POINT_VEC3.RoutePointType.TurningPoint, POINT_VEC3.RoutePointAction.TurningPoint, Speed, true)
local WaypointTo = CoordinateTo:WaypointAir("RADIO", COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.TurningPoint, Speed, true)
Route[#Route+1] = WaypointTo
@@ -14,6 +14,8 @@
--- Brings a dynamic cargo handling capability for an AI naval group.
--
-- ![Banner Image](..\Images\deprecated.png)
--
-- Naval ships can be utilized to transport cargo around the map following naval shipping lanes.
-- The AI_CARGO_SHIP class uses the @{Cargo.Cargo} capabilities within the MOOSE framework.
-- @{Cargo.Cargo} must be declared within the mission or warehouse to make the AI_CARGO_SHIP recognize the cargo.
+2
View File
@@ -25,6 +25,8 @@
--
-- Allows you to interact with escorting AI on your flight and take the lead.
--
-- ![Banner Image](..\Images\deprecated.png)
--
-- Each escorting group can be commanded with a complete set of radio commands (radio menu in your flight, and then F10).
--
-- The radio commands will vary according the category of the group. The richest set of commands are with helicopters and airPlanes.
@@ -23,6 +23,8 @@
--
-- # Developer Note
--
-- ![Banner Image](..\Images\deprecated.png)
--
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
-- Therefore, this class is considered to be deprecated
--
@@ -21,6 +21,8 @@
--- Models the assignment of AI escorts to player flights upon request using the radio menu.
--
-- ![Banner Image](..\Images\deprecated.png)
--
-- # Developer Note
--
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
@@ -25,6 +25,8 @@
--
-- Allows you to interact with escorting AI on your flight and take the lead.
--
-- ![Banner Image](..\Images\deprecated.png)
--
-- Each escorting group can be commanded with a complete set of radio commands (radio menu in your flight, and then F10).
--
-- The radio commands will vary according the category of the group. The richest set of commands are with helicopters and airPlanes.
+5 -5
View File
@@ -40,6 +40,8 @@
--- Build large formations, make AI follow a @{Wrapper.Client#CLIENT} (player) leader or a @{Wrapper.Unit#UNIT} (AI) leader.
--
-- ![Banner Image](..\Images\deprecated.png)
--
-- AI_FORMATION makes AI @{Wrapper.Group#GROUP}s fly in formation of various compositions.
-- The AI_FORMATION class models formations in a different manner than the internal DCS formation logic!!!
@@ -158,7 +160,6 @@ AI_FORMATION.__Enum.Mode = {
-- @field #number GroundRadar
-- @field #number Ground
AI_FORMATION.__Enum.ReportType = {
Airborne = "*",
Airborne = "A",
GroundRadar = "R",
Ground = "G",
@@ -725,7 +726,7 @@ function AI_FORMATION:onafterFormationLine( FollowGroupSet, From , Event , To, X
for FollowID, FollowGroup in pairs( FollowSet ) do
local PointVec3 = POINT_VEC3:New()
local PointVec3 = COORDINATE:New()
PointVec3:SetX( XStart + i * XSpace )
PointVec3:SetY( YStart + i * YSpace )
PointVec3:SetZ( ZStart + i * ZSpace )
@@ -877,7 +878,7 @@ function AI_FORMATION:onafterFormationCenterWing( FollowGroupSet, From , Event ,
for FollowID, FollowGroup in pairs( FollowSet ) do
local PointVec3 = POINT_VEC3:New()
local PointVec3 = COORDINATE:New()
local Side = ( i % 2 == 0 ) and 1 or -1
local Row = i / 2 + 1
@@ -936,7 +937,7 @@ function AI_FORMATION:onafterFormationBox( FollowGroupSet, From , Event , To, XS
for FollowID, FollowGroup in pairs( FollowSet ) do
local PointVec3 = POINT_VEC3:New()
local PointVec3 = COORDINATE:New()
local ZIndex = i % ZLevels
local XIndex = math.floor( i / ZLevels )
@@ -1222,7 +1223,6 @@ function AI_FORMATION:FollowMe(FollowGroup, ClientUnit, CT1, CV1, CT2, CV2)
local CVI = {
x = CV2.x + CS * 10 * math.sin(Ca),
y = GH2.y + Inclination, -- + FollowFormation.y,
y = GH2.y,
z = CV2.z + CS * 10 * math.cos(Ca),
}
+14 -12
View File
@@ -48,6 +48,8 @@
--- Implements the core functions to patrol a @{Core.Zone} by an AI @{Wrapper.Controllable} or @{Wrapper.Group}.
--
-- ![Banner Image](..\Images\deprecated.png)
--
-- ![Process](..\Presentations\AI_PATROL\Dia3.JPG)
--
-- The AI_PATROL_ZONE is assigned a @{Wrapper.Group} and this must be done before the AI_PATROL_ZONE process can be started using the **Start** event.
@@ -751,12 +753,12 @@ function AI_PATROL_ZONE:onafterRoute( Controllable, From, Event, To )
if not CurrentVec2 then return end
--Done: Create GetAltitude function for GROUP, and delete GetUnit(1).
local CurrentAltitude = self.Controllable:GetAltitude()
local CurrentPointVec3 = POINT_VEC3:New( CurrentVec2.x, CurrentAltitude, CurrentVec2.y )
local CurrentPointVec3 = COORDINATE:New( CurrentVec2.x, CurrentAltitude, CurrentVec2.y )
local ToPatrolZoneSpeed = self.PatrolMaxSpeed
local CurrentRoutePoint = CurrentPointVec3:WaypointAir(
self.PatrolAltType,
POINT_VEC3.RoutePointType.TakeOffParking,
POINT_VEC3.RoutePointAction.FromParkingArea,
COORDINATE.WaypointType.TakeOffParking,
COORDINATE.WaypointAction.FromParkingArea,
ToPatrolZoneSpeed,
true
)
@@ -767,12 +769,12 @@ function AI_PATROL_ZONE:onafterRoute( Controllable, From, Event, To )
if not CurrentVec2 then return end
--DONE: Create GetAltitude function for GROUP, and delete GetUnit(1).
local CurrentAltitude = self.Controllable:GetAltitude()
local CurrentPointVec3 = POINT_VEC3:New( CurrentVec2.x, CurrentAltitude, CurrentVec2.y )
local CurrentPointVec3 = COORDINATE:New( CurrentVec2.x, CurrentAltitude, CurrentVec2.y )
local ToPatrolZoneSpeed = self.PatrolMaxSpeed
local CurrentRoutePoint = CurrentPointVec3:WaypointAir(
self.PatrolAltType,
POINT_VEC3.RoutePointType.TurningPoint,
POINT_VEC3.RoutePointAction.TurningPoint,
COORDINATE.WaypointType.TurningPoint,
COORDINATE.WaypointAction.TurningPoint,
ToPatrolZoneSpeed,
true
)
@@ -792,13 +794,13 @@ function AI_PATROL_ZONE:onafterRoute( Controllable, From, Event, To )
self:T2( { self.PatrolMinSpeed, self.PatrolMaxSpeed, ToTargetSpeed } )
--- Obtain a 3D @{Point} from the 2D point + altitude.
local ToTargetPointVec3 = POINT_VEC3:New( ToTargetVec2.x, ToTargetAltitude, ToTargetVec2.y )
local ToTargetPointVec3 = COORDINATE:New( ToTargetVec2.x, ToTargetAltitude, ToTargetVec2.y )
--- Create a route point of type air.
local ToTargetRoutePoint = ToTargetPointVec3:WaypointAir(
self.PatrolAltType,
POINT_VEC3.RoutePointType.TurningPoint,
POINT_VEC3.RoutePointAction.TurningPoint,
COORDINATE.WaypointType.TurningPoint,
COORDINATE.WaypointAction.TurningPoint,
ToTargetSpeed,
true
)
@@ -890,12 +892,12 @@ function AI_PATROL_ZONE:onafterRTB()
--DONE: Create GetAltitude function for GROUP, and delete GetUnit(1).
--local CurrentAltitude = self.Controllable:GetUnit(1):GetAltitude()
local CurrentAltitude = self.Controllable:GetAltitude()
local CurrentPointVec3 = POINT_VEC3:New( CurrentVec2.x, CurrentAltitude, CurrentVec2.y )
local CurrentPointVec3 = COORDINATE:New( CurrentVec2.x, CurrentAltitude, CurrentVec2.y )
local ToPatrolZoneSpeed = self.PatrolMaxSpeed
local CurrentRoutePoint = CurrentPointVec3:WaypointAir(
self.PatrolAltType,
POINT_VEC3.RoutePointType.TurningPoint,
POINT_VEC3.RoutePointAction.TurningPoint,
COORDINATE.WaypointType.TurningPoint,
COORDINATE.WaypointAction.TurningPoint,
ToPatrolZoneSpeed,
true
)
@@ -1,6 +1,6 @@
--- **Actions** - ACT_ACCOUNT_ classes **account for** (detect, count & report) various DCS events occurring on UNITs.
--
-- ![Banner Image](..\Presentations\ACT_ACCOUNT\Dia1.JPG)
-- ![Banner Image](..\Images\deprecated.png)
--
-- ===
--
@@ -8,9 +8,11 @@
-- @image MOOSE.JPG
do -- ACT_ACCOUNT
--- # @{#ACT_ACCOUNT} FSM class, extends @{Core.Fsm#FSM_PROCESS}
--
--
-- ![Banner Image](..\Images\deprecated.png)
--
-- ## ACT_ACCOUNT state machine:
--
-- This class is a state machine: it manages a process that is triggered by events causing state transitions to occur.
@@ -133,7 +135,7 @@ do -- ACT_ACCOUNT
-- @param #string Event
-- @param #string From
-- @param #string To
function ACT_ACCOUNT:onafterEvent( ProcessUnit, From, Event, To, Event )
function ACT_ACCOUNT:onafterEvent( ProcessUnit, From, Event, To )
self:__NoMore( 1 )
end
@@ -1,6 +1,8 @@
--- (SP) (MP) (FSM) Accept or reject process for player (task) assignments.
--
-- ===
--
-- ![Banner Image](..\Images\deprecated.png)
--
-- # @{#ACT_ASSIGN} FSM template class, extends @{Core.Fsm#FSM_PROCESS}
--
@@ -1,5 +1,6 @@
--- (SP) (MP) (FSM) Route AI or players through waypoints or to zones.
--
-- ![Banner Image](..\Images\deprecated.png)
-- ## ACT_ASSIST state machine:
--
-- This class is a state machine: it manages a process that is triggered by events causing state transitions to occur.
@@ -2,6 +2,8 @@
--
-- ===
--
-- ![Banner Image](..\Images\deprecated.png)
--
-- # @{#ACT_ROUTE} FSM class, extends @{Core.Fsm#FSM_PROCESS}
--
-- ## ACT_ROUTE state machine:
+9 -7
View File
@@ -2,6 +2,8 @@
--
-- ===
--
-- ![Banner Image](..\Images\deprecated.png)
--
-- # 1) MOOSE Cargo System.
--
-- #### Those who have used the mission editor, know that the DCS mission editor provides cargo facilities.
@@ -275,14 +277,14 @@
-- The cargo must be in the **Loaded** state.
-- @function [parent=#CARGO] UnBoard
-- @param #CARGO self
-- @param Core.Point#POINT_VEC2 ToPointVec2 (optional) @{Core.Point#POINT_VEC2) to where the cargo should run after onboarding. If not provided, the cargo will run to 60 meters behind the Carrier location.
-- @param Core.Point#COORDINATE ToPointVec2 (optional) @{Core.Point#COORDINATE) to where the cargo should run after onboarding. If not provided, the cargo will run to 60 meters behind the Carrier location.
--- UnBoards the cargo to a Carrier. The event will create a movement (= running or driving) of the cargo from the Carrier.
-- The cargo must be in the **Loaded** state.
-- @function [parent=#CARGO] __UnBoard
-- @param #CARGO self
-- @param #number DelaySeconds The amount of seconds to delay the action.
-- @param Core.Point#POINT_VEC2 ToPointVec2 (optional) @{Core.Point#POINT_VEC2) to where the cargo should run after onboarding. If not provided, the cargo will run to 60 meters behind the Carrier location.
-- @param Core.Point#COORDINATE ToPointVec2 (optional) @{Core.Point#COORDINATE) to where the cargo should run after onboarding. If not provided, the cargo will run to 60 meters behind the Carrier location.
-- Load
@@ -307,14 +309,14 @@
-- The cargo must be in the **Loaded** state.
-- @function [parent=#CARGO] UnLoad
-- @param #CARGO self
-- @param Core.Point#POINT_VEC2 ToPointVec2 (optional) @{Core.Point#POINT_VEC2) to where the cargo will be placed after unloading. If not provided, the cargo will be placed 60 meters behind the Carrier location.
-- @param Core.Point#COORDINATE ToPointVec2 (optional) @{Core.Point#COORDINATE) to where the cargo will be placed after unloading. If not provided, the cargo will be placed 60 meters behind the Carrier location.
--- UnLoads the cargo to a Carrier. The event will unload the cargo from the Carrier. There will be no movement simulated of the cargo loading.
-- The cargo must be in the **Loaded** state.
-- @function [parent=#CARGO] __UnLoad
-- @param #CARGO self
-- @param #number DelaySeconds The amount of seconds to delay the action.
-- @param Core.Point#POINT_VEC2 ToPointVec2 (optional) @{Core.Point#POINT_VEC2) to where the cargo will be placed after unloading. If not provided, the cargo will be placed 60 meters behind the Carrier location.
-- @param Core.Point#COORDINATE ToPointVec2 (optional) @{Core.Point#COORDINATE) to where the cargo will be placed after unloading. If not provided, the cargo will be placed 60 meters behind the Carrier location.
-- State Transition Functions
@@ -467,7 +469,7 @@ do -- CARGO
self.Type = Type
self.Name = Name
self.Weight = Weight or 0
self.CargoObject = nil
self.CargoObject = nil -- Wrapper.Group#GROUP
self.CargoCarrier = nil -- Wrapper.Client#CLIENT
self.Representable = false
self.Slingloadable = false
@@ -897,7 +899,7 @@ do -- CARGO
--- Get the current PointVec2 of the cargo.
-- @param #CARGO self
-- @return Core.Point#POINT_VEC2
-- @return Core.Point#COORDINATE
function CARGO:GetPointVec2()
return self.CargoObject:GetPointVec2()
end
@@ -1094,7 +1096,7 @@ do -- CARGO_REPRESENTABLE
--- Route a cargo unit to a PointVec2.
-- @param #CARGO_REPRESENTABLE self
-- @param Core.Point#POINT_VEC2 ToPointVec2
-- @param Core.Point#COORDINATE ToPointVec2
-- @param #number Speed
-- @return #CARGO_REPRESENTABLE
function CARGO_REPRESENTABLE:RouteTo( ToPointVec2, Speed )
+4 -1
View File
@@ -22,6 +22,9 @@ do -- CARGO_CRATE
-- @type CARGO_CRATE
-- @extends Cargo.Cargo#CARGO_REPRESENTABLE
---
-- ![Banner Image](..\Images\deprecated.png)
--
--- 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.
--
@@ -114,7 +117,7 @@ do -- CARGO_CRATE
-- @param #string Event
-- @param #string From
-- @param #string To
-- @param Core.Point#POINT_VEC2
-- @param Core.Point#COORDINATE
function CARGO_CRATE:onenterUnLoaded( From, Event, To, ToPointVec2 )
--self:T( { ToPointVec2, From, Event, To } )
+7 -3
View File
@@ -22,9 +22,12 @@ do -- CARGO_GROUP
--- @type CARGO_GROUP
-- @field Core.Set#SET_CARGO CargoSet The collection of derived CARGO objects.
-- @field #string GroupName The name of the CargoGroup.
-- @field Wrapper.Group#GROUÜ CargoCarrier The carrier group.
-- @extends Cargo.Cargo#CARGO_REPORTABLE
--- Defines a cargo that is represented by a @{Wrapper.Group} object within the simulator.
--
-- ![Banner Image](..\Images\deprecated.png)
-- The cargo can be Loaded, UnLoaded, Boarded, UnBoarded to and from Carriers.
--
-- The above cargo classes are used by the following AI_CARGO_ classes to allow AI groups to transport cargo:
@@ -410,7 +413,7 @@ do -- CARGO_GROUP
-- @param #string Event
-- @param #string From
-- @param #string To
-- @param Core.Point#POINT_VEC2 ToPointVec2
-- @param Core.Point#COORDINATE ToPointVec2
-- @param #number NearRadius If distance is smaller than this number, cargo is loaded into the carrier.
function CARGO_GROUP:onafterUnBoard( From, Event, To, ToPointVec2, NearRadius, ... )
self:T( {From, Event, To, ToPointVec2, NearRadius } )
@@ -453,7 +456,7 @@ do -- CARGO_GROUP
-- @param #string Event
-- @param #string From
-- @param #string To
-- @param Core.Point#POINT_VEC2 ToPointVec2
-- @param Core.Point#COORDINATE ToPointVec2
-- @param #number NearRadius If distance is smaller than this number, cargo is loaded into the carrier.
function CARGO_GROUP:onafterUnBoarding( From, Event, To, ToPointVec2, NearRadius, ... )
--self:T( { From, Event, To, ToPointVec2, NearRadius } )
@@ -491,7 +494,7 @@ do -- CARGO_GROUP
-- @param #string Event
-- @param #string From
-- @param #string To
-- @param Core.Point#POINT_VEC2 ToPointVec2
-- @param Core.Point#COORDINATE ToPointVec2
function CARGO_GROUP:onafterUnLoad( From, Event, To, ToPointVec2, ... )
--self:T( { From, Event, To, ToPointVec2 } )
@@ -771,3 +774,4 @@ do -- CARGO_GROUP
end -- CARGO_GROUP
@@ -32,6 +32,8 @@ do -- CARGO_SLINGLOAD
--
-- # Developer Note
--
-- ![Banner Image](..\Images\deprecated.png)
--
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
-- Therefore, this class is considered to be deprecated
--
+6 -4
View File
@@ -30,6 +30,8 @@ do -- CARGO_UNIT
--
-- # Developer Note
--
-- ![Banner Image](..\Images\deprecated.png)
--
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
-- Therefore, this class is considered to be deprecated
--
@@ -72,7 +74,7 @@ do -- CARGO_UNIT
-- @param #string Event
-- @param #string From
-- @param #string To
-- @param Core.Point#POINT_VEC2 ToPointVec2
-- @param Core.Point#COORDINATE ToPointVec2
-- @param #number NearRadius (optional) Defaut 25 m.
function CARGO_UNIT:onenterUnBoarding( From, Event, To, ToPointVec2, NearRadius )
self:T( { From, Event, To, ToPointVec2, NearRadius } )
@@ -145,7 +147,7 @@ do -- CARGO_UNIT
-- @param #string Event
-- @param #string From
-- @param #string To
-- @param Core.Point#POINT_VEC2 ToPointVec2
-- @param Core.Point#COORDINATE ToPointVec2
-- @param #number NearRadius (optional) Defaut 100 m.
function CARGO_UNIT:onleaveUnBoarding( From, Event, To, ToPointVec2, NearRadius )
self:T( { From, Event, To, ToPointVec2, NearRadius } )
@@ -171,7 +173,7 @@ do -- CARGO_UNIT
-- @param #string Event
-- @param #string From
-- @param #string To
-- @param Core.Point#POINT_VEC2 ToPointVec2
-- @param Core.Point#COORDINATE ToPointVec2
-- @param #number NearRadius (optional) Defaut 100 m.
function CARGO_UNIT:onafterUnBoarding( From, Event, To, ToPointVec2, NearRadius )
self:T( { From, Event, To, ToPointVec2, NearRadius } )
@@ -197,7 +199,7 @@ do -- CARGO_UNIT
-- @param #string Event
-- @param #string From
-- @param #string To
-- @param Core.Point#POINT_VEC2
-- @param Core.Point#COORDINATE
function CARGO_UNIT:onenterUnLoaded( From, Event, To, ToPointVec2 )
self:T( { ToPointVec2, From, Event, To } )
+1 -1
View File
@@ -974,7 +974,7 @@ do -- Scheduling
-- @param #BASE self
-- @param #number Start Specifies the amount of seconds that will be waited before the scheduling is started, and the event function is called.
-- @param #function SchedulerFunction The event function to be called when a timer event occurs. The event function needs to accept the parameters specified in SchedulerArguments.
-- @param #table ... Optional arguments that can be given as part of scheduler. The arguments need to be given as a table { param1, param 2, ... }.
-- @param ... Optional arguments that can be given as part of scheduler. The arguments need to be given as a table { param1, param 2, ... }.
-- @return #string The Schedule ID of the planned schedule.
function BASE:ScheduleOnce( Start, SchedulerFunction, ... )
+20 -12
View File
@@ -577,13 +577,19 @@ do -- Zones and Pathlines
-- For a rectangular polygon drawing, we have the width (y) and height (x).
local w=objectData.width
local h=objectData.height
local rotation = UTILS.ToRadian(objectData.angle or 0)
-- Create points from center using with and height (width for y and height for x is a bit confusing, but this is how ED implemented it).
local points={}
points[1]={x=vec2.x-h/2, y=vec2.y+w/2} --Upper left
points[2]={x=vec2.x+h/2, y=vec2.y+w/2} --Upper right
points[3]={x=vec2.x+h/2, y=vec2.y-w/2} --Lower right
points[4]={x=vec2.x-h/2, y=vec2.y-w/2} --Lower left
local sinRot = math.sin(rotation)
local cosRot = math.cos(rotation)
local dx = h / 2
local dy = w / 2
local points = {
{ x = -dx * cosRot - (-dy * sinRot) + vec2.x, y = -dx * sinRot + (-dy * cosRot) + vec2.y },
{ x = dx * cosRot - (-dy * sinRot) + vec2.x, y = dx * sinRot + (-dy * cosRot) + vec2.y },
{ x = dx * cosRot - (dy * sinRot) + vec2.x, y = dx * sinRot + (dy * cosRot) + vec2.y },
{ x = -dx * cosRot - (dy * sinRot) + vec2.x, y = -dx * sinRot + (dy * cosRot) + vec2.y },
}
--local coord=COORDINATE:NewFromVec2(vec2):MarkToAll("MapX, MapY")
@@ -872,6 +878,8 @@ end
-- @return Wrapper.Group#GROUP The found GROUP.
function DATABASE:FindGroup( GroupName )
if type(GroupName) ~= "string" or GroupName == "" then return end
local GroupFound = self.GROUPS[GroupName]
if GroupFound == nil and GroupName ~= nil and self.Templates.Groups[GroupName] == nil then
@@ -1110,7 +1118,7 @@ function DATABASE:_RegisterGroupTemplate( GroupTemplate, CoalitionSide, Category
self:E("WARNING: Invalid STN "..tostring(UnitTemplate.AddPropAircraft.STN_L16).." for ".. UnitTemplate.name)
else
self.STNS[stn] = UnitTemplate.name
self:I("Register STN "..tostring(UnitTemplate.AddPropAircraft.STN_L16).." for ".. UnitTemplate.name)
self:T("Register STN "..tostring(UnitTemplate.AddPropAircraft.STN_L16).." for ".. UnitTemplate.name)
end
end
if UnitTemplate.AddPropAircraft.SADL_TN then
@@ -1119,7 +1127,7 @@ function DATABASE:_RegisterGroupTemplate( GroupTemplate, CoalitionSide, Category
self:E("WARNING: Invalid SADL "..tostring(UnitTemplate.AddPropAircraft.SADL_TN).." for ".. UnitTemplate.name)
else
self.SADL[sadl] = UnitTemplate.name
self:I("Register SADL "..tostring(UnitTemplate.AddPropAircraft.SADL_TN).." for ".. UnitTemplate.name)
self:T("Register SADL "..tostring(UnitTemplate.AddPropAircraft.SADL_TN).." for ".. UnitTemplate.name)
end
end
end
@@ -1380,7 +1388,7 @@ function DATABASE:GetCoalitionFromClientTemplate( ClientName )
if self.Templates.ClientsByName[ClientName] then
return self.Templates.ClientsByName[ClientName].CoalitionID
end
self:E("WARNING: Template does not exist for client "..tostring(ClientName))
self:T("WARNING: Template does not exist for client "..tostring(ClientName))
return nil
end
@@ -1392,7 +1400,7 @@ function DATABASE:GetCategoryFromClientTemplate( ClientName )
if self.Templates.ClientsByName[ClientName] then
return self.Templates.ClientsByName[ClientName].CategoryID
end
self:E("WARNING: Template does not exist for client "..tostring(ClientName))
self:T("WARNING: Template does not exist for client "..tostring(ClientName))
return nil
end
@@ -1404,7 +1412,7 @@ function DATABASE:GetCountryFromClientTemplate( ClientName )
if self.Templates.ClientsByName[ClientName] then
return self.Templates.ClientsByName[ClientName].CountryID
end
self:E("WARNING: Template does not exist for client "..tostring(ClientName))
self:T("WARNING: Template does not exist for client "..tostring(ClientName))
return nil
end
@@ -1697,7 +1705,7 @@ function DATABASE:_EventOnBirth( Event )
if PlayerName then
-- Debug info.
self:I(string.format("Player '%s' joined unit '%s' of group '%s'", tostring(PlayerName), tostring(Event.IniDCSUnitName), tostring(Event.IniDCSGroupName)))
self:I(string.format("Player '%s' joined unit '%s' (%s) of group '%s'", tostring(PlayerName), tostring(Event.IniDCSUnitName), tostring(Event.IniTypeName), tostring(Event.IniDCSGroupName)))
-- Add client in case it does not exist already.
if client == nil or (client and client:CountPlayers() == 0) then
+8 -5
View File
@@ -1372,11 +1372,12 @@ function EVENT:onEvent( Event )
-- Scenery
---
Event.IniDCSUnit = Event.initiator
Event.IniDCSUnitName = Event.IniDCSUnit.getName and Event.IniDCSUnit:getName() or "Scenery no name "..math.random(1,20000)
Event.IniDCSUnitName = ( Event.IniDCSUnit and Event.IniDCSUnit.getName ) and Event.IniDCSUnit:getName() or "Scenery no name "..math.random(1,20000)
Event.IniUnitName = Event.IniDCSUnitName
Event.IniUnit = SCENERY:Register( Event.IniDCSUnitName, Event.initiator )
Event.IniCategory = Event.IniDCSUnit.getDesc and Event.IniDCSUnit:getDesc().category
Event.IniTypeName = Event.initiator:isExist() and Event.IniDCSUnit:getTypeName() or "SCENERY"
Event.IniCategory = (Event.IniDCSUnit and Event.IniDCSUnit.getDesc ) and Event.IniDCSUnit:getDesc().category
Event.IniTypeName = (Event.initiator and Event.initiator.isExist
and Event.initiator:isExist() and Event.IniDCSUnit and Event.IniDCSUnit.getTypeName) and Event.IniDCSUnit:getTypeName() or "SCENERY"
elseif Event.IniObjectCategory == Object.Category.BASE then
---
@@ -1474,7 +1475,7 @@ function EVENT:onEvent( Event )
-- SCENERY
---
Event.TgtDCSUnit = Event.target
Event.TgtDCSUnitName = Event.TgtDCSUnit.getName and Event.TgtDCSUnit.getName() or nil
Event.TgtDCSUnitName = Event.TgtDCSUnit.getName and Event.TgtDCSUnit:getName() or nil
if Event.TgtDCSUnitName~=nil then
Event.TgtUnitName = Event.TgtDCSUnitName
Event.TgtUnit = SCENERY:Register( Event.TgtDCSUnitName, Event.target )
@@ -1507,7 +1508,9 @@ function EVENT:onEvent( Event )
else
if Event.place:isExist() and Object.getCategory(Event.place) ~= Object.Category.SCENERY then
Event.Place=AIRBASE:Find(Event.place)
Event.PlaceName=Event.Place:GetName()
if Event.Place then
Event.PlaceName=Event.Place:GetName()
end
end
end
end
+18 -13
View File
@@ -50,7 +50,7 @@ MARKEROPS_BASE = {
ClassName = "MARKEROPS",
Tag = "mytag",
Keywords = {},
version = "0.1.3",
version = "0.1.4",
debug = false,
Casesensitive = true,
}
@@ -154,14 +154,7 @@ function MARKEROPS_BASE:OnEventMark(Event)
self:E("Skipping onEvent. Event or Event.idx unknown.")
return true
end
--position
local vec3={y=Event.pos.y, x=Event.pos.x, z=Event.pos.z}
local coord=COORDINATE:NewFromVec3(vec3)
if self.debug then
local coordtext = coord:ToStringLLDDM()
local text = tostring(Event.text)
local m = MESSAGE:New(string.format("Mark added at %s with text: %s",coordtext,text),10,"Info",false):ToAll()
end
local coalition = Event.MarkCoalition
-- decision
if Event.id==world.event.S_EVENT_MARK_ADDED then
@@ -170,8 +163,14 @@ function MARKEROPS_BASE:OnEventMark(Event)
local Eventtext = tostring(Event.text)
if Eventtext~=nil then
if self:_MatchTag(Eventtext) then
local matchtable = self:_MatchKeywords(Eventtext)
self:MarkAdded(Eventtext,matchtable,coord,Event.idx,coalition,Event.PlayerName,Event)
local coord=COORDINATE:NewFromVec3({y=Event.pos.y, x=Event.pos.x, z=Event.pos.z})
if self.debug then
local coordtext = coord:ToStringLLDDM()
local text = tostring(Event.text)
local m = MESSAGE:New(string.format("Mark added at %s with text: %s",coordtext,text),10,"Info",false):ToAll()
end
local matchtable = self:_MatchKeywords(Eventtext)
self:MarkAdded(Eventtext,matchtable,coord,Event.idx,coalition,Event.PlayerName,Event)
end
end
elseif Event.id==world.event.S_EVENT_MARK_CHANGE then
@@ -180,8 +179,14 @@ function MARKEROPS_BASE:OnEventMark(Event)
local Eventtext = tostring(Event.text)
if Eventtext~=nil then
if self:_MatchTag(Eventtext) then
local matchtable = self:_MatchKeywords(Eventtext)
self:MarkChanged(Eventtext,matchtable,coord,Event.idx,coalition,Event.PlayerName,Event)
local coord=COORDINATE:NewFromVec3({y=Event.pos.y, x=Event.pos.x, z=Event.pos.z})
if self.debug then
local coordtext = coord:ToStringLLDDM()
local text = tostring(Event.text)
local m = MESSAGE:New(string.format("Mark changed at %s with text: %s",coordtext,text),10,"Info",false):ToAll()
end
local matchtable = self:_MatchKeywords(Eventtext)
self:MarkChanged(Eventtext,matchtable,coord,Event.idx,coalition,Event.PlayerName,Event)
end
end
elseif Event.id==world.event.S_EVENT_MARK_REMOVED then
+9 -9
View File
@@ -206,7 +206,7 @@ end
function MESSAGE:ToGroup( Group, Settings )
self:F( Group.GroupName )
if Group then
if Group and Group:IsAlive() then
if self.MessageType then
local Settings = Settings or (Group and _DATABASE:GetPlayerSettings( Group:GetPlayerName() )) or _SETTINGS -- Core.Settings#SETTINGS
@@ -231,7 +231,7 @@ end
function MESSAGE:ToUnit( Unit, Settings )
self:F( Unit.IdentifiableName )
if Unit then
if Unit and Unit:IsAlive() then
if self.MessageType then
local Settings = Settings or ( Unit and _DATABASE:GetPlayerSettings( Unit:GetPlayerName() ) ) or _SETTINGS -- Core.Settings#SETTINGS
@@ -452,7 +452,7 @@ end
_MESSAGESRS = {}
--- Set up MESSAGE generally to allow Text-To-Speech via SRS and TTS functions. `SetMSRS()` will try to use as many attributes configured with @{Sound.SRS#MSRS.LoadConfigFile}() as possible.
-- @param #string PathToSRS (optional) Path to SRS Folder, defaults to "C:\\\\Program Files\\\\DCS-SimpleRadio-Standalone" or your configuration file setting.
-- @param #string PathToSRS (optional) Path to SRS TTS Folder, defaults to "C:\\\\Program Files\\\\DCS-SimpleRadio-Standalone\\ExternalAudio" or your configuration file setting.
-- @param #number Port Port (optional) number of SRS, defaults to 5002 or your configuration file setting.
-- @param #string PathToCredentials (optional) Path to credentials file for Google.
-- @param #number Frequency Frequency in MHz. Can also be given as a #table of frequencies.
@@ -468,13 +468,13 @@ _MESSAGESRS = {}
-- @usage
-- -- Mind the dot here, not using the colon this time around!
-- -- Needed once only
-- MESSAGE.SetMSRS("D:\\Program Files\\DCS-SimpleRadio-Standalone",5012,nil,127,radio.modulation.FM,"female","en-US",nil,coalition.side.BLUE)
-- MESSAGE.SetMSRS("D:\\Program Files\\DCS-SimpleRadio-Standalone\\ExternalAudio",5012,nil,127,radio.modulation.FM,"female","en-US",nil,coalition.side.BLUE)
-- -- later on in your code
-- MESSAGE:New("Test message!",15,"SPAWN"):ToSRS()
--
function MESSAGE.SetMSRS(PathToSRS,Port,PathToCredentials,Frequency,Modulation,Gender,Culture,Voice,Coalition,Volume,Label,Coordinate,Backend)
_MESSAGESRS.PathToSRS = PathToSRS or MSRS.path or "C:\\Program Files\\DCS-SimpleRadio-Standalone"
_MESSAGESRS.PathToSRS = PathToSRS or MSRS.path or "C:\\Program Files\\DCS-SimpleRadio-Standalone\\ExternalAudio"
_MESSAGESRS.frequency = Frequency or MSRS.frequencies or 243
_MESSAGESRS.modulation = Modulation or MSRS.modulations or radio.modulation.AM
@@ -535,7 +535,7 @@ end
-- @usage
-- -- Mind the dot here, not using the colon this time around!
-- -- Needed once only
-- MESSAGE.SetMSRS("D:\\Program Files\\DCS-SimpleRadio-Standalone",5012,nil,127,radio.modulation.FM,"female","en-US",nil,coalition.side.BLUE)
-- MESSAGE.SetMSRS("D:\\Program Files\\DCS-SimpleRadio-Standalone\\ExternalAudio",5012,nil,127,radio.modulation.FM,"female","en-US",nil,coalition.side.BLUE)
-- -- later on in your code
-- MESSAGE:New("Test message!",15,"SPAWN"):ToSRS()
--
@@ -567,7 +567,7 @@ end
-- @usage
-- -- Mind the dot here, not using the colon this time around!
-- -- Needed once only
-- MESSAGE.SetMSRS("D:\\Program Files\\DCS-SimpleRadio-Standalone",5012,nil,127,radio.modulation.FM,"female","en-US",nil,coalition.side.BLUE)
-- MESSAGE.SetMSRS("D:\\Program Files\\DCS-SimpleRadio-Standalone\\ExternalAudio",5012,nil,127,radio.modulation.FM,"female","en-US",nil,coalition.side.BLUE)
-- -- later on in your code
-- MESSAGE:New("Test message!",15,"SPAWN"):ToSRSBlue()
--
@@ -589,7 +589,7 @@ end
-- @usage
-- -- Mind the dot here, not using the colon this time around!
-- -- Needed once only
-- MESSAGE.SetMSRS("D:\\Program Files\\DCS-SimpleRadio-Standalone",5012,nil,127,radio.modulation.FM,"female","en-US",nil,coalition.side.RED)
-- MESSAGE.SetMSRS("D:\\Program Files\\DCS-SimpleRadio-Standalone\\ExternalAudio",5012,nil,127,radio.modulation.FM,"female","en-US",nil,coalition.side.RED)
-- -- later on in your code
-- MESSAGE:New("Test message!",15,"SPAWN"):ToSRSRed()
--
@@ -611,7 +611,7 @@ end
-- @usage
-- -- Mind the dot here, not using the colon this time around!
-- -- Needed once only
-- MESSAGE.SetMSRS("D:\\Program Files\\DCS-SimpleRadio-Standalone",5012,nil,127,radio.modulation.FM,"female","en-US",nil,coalition.side.NEUTRAL)
-- MESSAGE.SetMSRS("D:\\Program Files\\DCS-SimpleRadio-Standalone\\ExternalAudio",5012,nil,127,radio.modulation.FM,"female","en-US",nil,coalition.side.NEUTRAL)
-- -- later on in your code
-- MESSAGE:New("Test message!",15,"SPAWN"):ToSRSAll()
--
+441 -346
View File
@@ -25,7 +25,7 @@
do -- COORDINATE
---
--- Coordinate class
-- @type COORDINATE
-- @field #string ClassName Name of the class
-- @field #number x Component of the 3D vector.
@@ -59,6 +59,10 @@ do -- COORDINATE
-- * @{#COORDINATE.SmokeOrange}(): To smoke the point in orange.
-- * @{#COORDINATE.SmokeWhite}(): To smoke the point in white.
-- * @{#COORDINATE.SmokeGreen}(): To smoke the point in green.
-- * @{#COORDINATE.SetSmokeOffsetDirection}(): To set an offset point direction for smoke.
-- * @{#COORDINATE.SetSmokeOffsetDistance}(): To set an offset point distance for smoke.
-- * @{#COORDINATE.SwitchSmokeOffsetOn}(): To set an offset point for smoke to on.
-- * @{#COORDINATE.SwitchSmokeOffsetOff}(): To set an offset point for smoke to off.
--
-- ## 2.2) Flare
--
@@ -773,7 +777,9 @@ do -- COORDINATE
-- @return DCS#Vec2 Vec2
function COORDINATE:GetRandomVec2InRadius( OuterRadius, InnerRadius )
self:F2( { OuterRadius, InnerRadius } )
math.random()
math.random()
math.random()
local Theta = 2 * math.pi * math.random()
local Radials = math.random() + math.random()
if Radials > 1 then
@@ -833,6 +839,26 @@ do -- COORDINATE
return land.getHeight( Vec2 )
end
--- Returns a table of DCS#Vec3 points representing the terrain profile between two points.
-- @param #COORDINATE self
-- @param Destination DCS#Vec3 Ending point of the profile.
-- @return #table DCS#Vec3 table of the profile
function COORDINATE:GetLandProfileVec3(Destination)
return land.profile(self:GetVec3(), Destination)
end
--- Returns a table of #COORDINATE representing the terrain profile between two points.
-- @param #COORDINATE self
-- @param Destination #COORDINATE Ending coordinate of the profile.
-- @return #table #COORDINATE table of the profile
function COORDINATE:GetLandProfileCoordinates(Destination)
local points = self:GetLandProfileVec3(Destination:GetVec3())
local coords = {}
for _, point in ipairs(points) do
table.insert(coords, COORDINATE:NewFromVec3(point))
end
return coords
end
--- Set the heading of the coordinate, if applicable.
-- @param #COORDINATE self
@@ -1157,6 +1183,162 @@ do -- COORDINATE
return vec3
end
--- Return the x coordinate of the COORDINATE.
-- @param #COORDINATE self
-- @return #number The x coordinate.
function COORDINATE:GetX()
return self.x
end
--- Return the y coordinate of the COORDINATE.
-- @param #COORDINATE self
-- @return #number The y coordinate.
function COORDINATE:GetY()
if self:IsInstanceOf("POINT_VEC2") then
return self.z
end
return self.y
end
--- Return the z coordinate of the COORDINATE.
-- @param #COORDINATE self
-- @return #number The z coordinate.
function COORDINATE:GetZ()
return self.z
end
--- Set the x coordinate of the COORDINATE.
-- @param #COORDINATE self
-- @param #number x The x coordinate.
-- @return #COORDINATE
function COORDINATE:SetX( x )
self.x = x
return self
end
--- Set the y coordinate of the COORDINATE.
-- @param #COORDINATE self
-- @param #number y The y coordinate.
-- @return #COORDINATE
function COORDINATE:SetY( y )
if self:IsInstanceOf("POINT_VEC2") then
self.z = y
else
self.y = y
end
return self
end
--- Set the z coordinate of the COORDINATE.
-- @param #COORDINATE self
-- @param #number z The z coordinate.
-- @return #COORDINATE
function COORDINATE:SetZ( z )
self.z = z
return self
end
--- Add to the x coordinate of the COORDINATE.
-- @param #COORDINATE self
-- @param #number x The x coordinate value to add to the current x coordinate.
-- @return #COORDINATE
function COORDINATE:AddX( x )
self.x = self.x + x
return self
end
--- Return Return the Lat(itude) coordinate of the COORDINATE (ie: (parent)COORDINATE.x).
-- @param #COORDINATE self
-- @return #number The x coordinate.
function COORDINATE:GetLat()
return self.x
end
--- Set the Lat(itude) coordinate of the COORDINATE (ie: COORDINATE.x).
-- @param #COORDINATE self
-- @param #number x The x coordinate.
-- @return #COORDINATE
function COORDINATE:SetLat( x )
self.x = x
return self
end
--- Return the Lon(gitude) coordinate of the COORDINATE (ie: (parent)COORDINATE.z).
-- @param #COORDINATE self
-- @return #number The y coordinate.
function COORDINATE:GetLon()
return self.z
end
--- Set the Lon(gitude) coordinate of the COORDINATE (ie: COORDINATE.z).
-- @param #COORDINATE self
-- @param #number y The y coordinate.
-- @return #COORDINATE
function COORDINATE:SetLon( z )
self.z = z
return self
end
--- Return the altitude (height) of the land at the COORDINATE.
-- @param #COORDINATE self
-- @return #number The land altitude.
function COORDINATE:GetAlt()
return self.y ~= 0 or land.getHeight( { x = self.x, y = self.z } )
end
--- Set the altitude of the COORDINATE.
-- @param #COORDINATE self
-- @param #number Altitude The land altitude. If nothing (nil) is given, then the current land altitude is set.
-- @return #COORDINATE
function COORDINATE:SetAlt( Altitude )
self.y = Altitude or land.getHeight( { x = self.x, y = self.z } )
return self
end
--- Add to the current land height an altitude.
-- @param #COORDINATE self
-- @param #number Altitude The Altitude to add. If nothing (nil) is given, then the current land altitude is set.
-- @return #COORDINATE
function COORDINATE:AddAlt( Altitude )
self.y = land.getHeight( { x = self.x, y = self.z } ) + Altitude or 0
return self
end
--- Return a random COORDINATE within an Outer Radius and optionally NOT within an Inner Radius of the COORDINATE.
-- @param #COORDINATE self
-- @param DCS#Distance OuterRadius
-- @param DCS#Distance InnerRadius
-- @return #COORDINATE
function COORDINATE:GetRandomPointVec2InRadius( OuterRadius, InnerRadius )
self:F2( { OuterRadius, InnerRadius } )
return COORDINATE:NewFromVec2( self:GetRandomVec2InRadius( OuterRadius, InnerRadius ) )
end
--- Add to the y coordinate of the COORDINATE.
-- @param #COORDINATE self
-- @param #number y The y coordinate value to add to the current y coordinate.
-- @return #COORDINATE
function COORDINATE:AddY( y )
if self:IsInstanceOf("POINT_VEC2") then
return self:AddZ(y)
else
self.y = self.y + y
end
return self
end
--- Add to the z coordinate of the COORDINATE.
-- @param #COORDINATE self
-- @param #number z The z coordinate value to add to the current z coordinate.
-- @return #COORDINATE
function COORDINATE:AddZ( z )
self.z = self.z +z
return self
end
--- Returns a text documenting the wind direction (from) and strength according the measurement system @{Core.Settings}.
-- The text will reflect the wind like this:
@@ -1455,6 +1637,7 @@ do -- COORDINATE
if AirbaseCategory == Airbase.Category.SHIP or AirbaseCategory == Airbase.Category.HELIPAD then
RoutePoint.linkUnit = AirbaseID
RoutePoint.helipadId = AirbaseID
RoutePoint.airdromeId = airbase:IsAirdrome() and AirbaseID or nil
elseif AirbaseCategory == Airbase.Category.AIRDROME then
RoutePoint.airdromeId = AirbaseID
else
@@ -1962,14 +2145,112 @@ do -- COORDINATE
end
--- Smokes the point in a color.
--- Create colored smoke the point. The smoke we last up to 5 min (DCS limitation) but you can optionally specify a shorter duration or stop it manually.
-- @param #COORDINATE self
-- @param Utilities.Utils#SMOKECOLOR SmokeColor
-- @param #string name (Optional) Name if you want to stop the smoke early (normal duration: 5mins)
function COORDINATE:Smoke( SmokeColor, name )
self:F2( { SmokeColor } )
self.firename = name or "Smoke-"..math.random(1,100000)
trigger.action.smoke( self:GetVec3(), SmokeColor, self.firename )
-- @param #number SmokeColor Color of smoke, e.g. `SMOKECOLOR.Green` for green smoke.
-- @param #number Duration (Optional) Duration of the smoke in seconds. DCS stopps the smoke automatically after 5 min.
-- @param #number Delay (Optional) Delay before the smoke is started in seconds.
-- @param #string Name (Optional) Name if you want to stop the smoke early (normal duration: 5mins)
-- @param #boolean Offset (Optional) If true, offset the smokle a bit.
-- @param #number Direction (Optional) If Offset is true this is the direction of the offset, 1-359 (degrees). Default random.
-- @param #number Distance (Optional) If Offset is true this is the distance of the offset in meters. Default random 10-20.
-- @return #COORDINATE self
function COORDINATE:Smoke( SmokeColor, Duration, Delay, Name, Offset,Direction,Distance)
self:F2( { SmokeColor, Name, Duration, Delay, Offset } )
SmokeColor=SmokeColor or SMOKECOLOR.Green
if Delay and Delay>0 then
self:ScheduleOnce(Delay, COORDINATE.Smoke, self, SmokeColor, Duration, 0, Name, Direction,Distance)
else
-- Create a name which is used to stop the smoke manually
self.firename = Name or "Smoke-"..math.random(1,100000)
-- Create smoke
if Offset or self.SmokeOffset then
local Angle = Direction or self:GetSmokeOffsetDirection()
local Distance = Distance or self:GetSmokeOffsetDistance()
local newpos = self:Translate(Distance,Angle,true,false)
local newvec3 = newpos:GetVec3()
trigger.action.smoke( newvec3, SmokeColor, self.firename )
else
trigger.action.smoke( self:GetVec3(), SmokeColor, self.firename )
end
-- Stop smoke
if Duration and Duration>0 then
self:ScheduleOnce(Duration, COORDINATE.StopSmoke, self, self.firename )
end
end
return self
end
--- Get the offset direction when using `COORDINATE:Smoke()`.
-- @param #COORDINATE self
-- @return #number Direction in degrees.
function COORDINATE:GetSmokeOffsetDirection()
local direction = self.SmokeOffsetDirection or math.random(1,359)
return direction
end
--- Set the offset direction when using `COORDINATE:Smoke()`.
-- @param #COORDINATE self
-- @param #number Direction (Optional) This is the direction of the offset, 1-359 (degrees). Default random.
-- @return #COORDINATE self
function COORDINATE:SetSmokeOffsetDirection(Direction)
if self then
self.SmokeOffsetDirection = Direction or math.random(1,359)
return self
else
COORDINATE.SmokeOffsetDirection = Direction or math.random(1,359)
end
end
--- Get the offset distance when using `COORDINATE:Smoke()`.
-- @param #COORDINATE self
-- @return #number Distance Distance in meters.
function COORDINATE:GetSmokeOffsetDistance()
local distance = self.SmokeOffsetDistance or math.random(10,20)
return distance
end
--- Set the offset distance when using `COORDINATE:Smoke()`.
-- @param #COORDINATE self
-- @param #number Distance (Optional) This is the distance of the offset in meters. Default random 10-20.
-- @return #COORDINATE self
function COORDINATE:SetSmokeOffsetDistance(Distance)
if self then
self.SmokeOffsetDistance = Distance or math.random(10,20)
return self
else
COORDINATE.SmokeOffsetDistance = Distance or math.random(10,20)
end
end
--- Set the offset on when using `COORDINATE:Smoke()`.
-- @param #COORDINATE self
-- @return #COORDINATE self
function COORDINATE:SwitchSmokeOffsetOn()
if self then
self.SmokeOffset = true
return self
else
COORDINATE.SmokeOffset = true
end
end
--- Set the offset off when using `COORDINATE:Smoke()`.
-- @param #COORDINATE self
-- @return #COORDINATE self
function COORDINATE:SwitchSmokeOffsetOff()
if self then
self.SmokeOffset = false
return self
else
COORDINATE.SmokeOffset = false
end
end
--- Stops smoking the point in a color.
@@ -1981,49 +2262,83 @@ do -- COORDINATE
--- Smoke the COORDINATE Green.
-- @param #COORDINATE self
function COORDINATE:SmokeGreen()
self:F2()
self:Smoke( SMOKECOLOR.Green )
-- @param #number Duration (Optional) Duration of the smoke in seconds. DCS stopps the smoke automatically after 5 min.
-- @param #number Delay (Optional) Delay before the smoke is started in seconds.
-- @return #COORDINATE self
function COORDINATE:SmokeGreen(Duration, Delay)
self:Smoke( SMOKECOLOR.Green, Duration, Delay )
return self
end
--- Smoke the COORDINATE Red.
-- @param #COORDINATE self
function COORDINATE:SmokeRed()
self:F2()
self:Smoke( SMOKECOLOR.Red )
-- @param #number Duration (Optional) Duration of the smoke in seconds. DCS stopps the smoke automatically after 5 min.
-- @param #number Delay (Optional) Delay before the smoke is started in seconds.
-- @return #COORDINATE self
function COORDINATE:SmokeRed(Duration, Delay)
self:Smoke( SMOKECOLOR.Red, Duration, Delay )
return self
end
--- Smoke the COORDINATE White.
-- @param #COORDINATE self
function COORDINATE:SmokeWhite()
self:F2()
self:Smoke( SMOKECOLOR.White )
-- @param #number Duration (Optional) Duration of the smoke in seconds. DCS stopps the smoke automatically after 5 min.
-- @param #number Delay (Optional) Delay before the smoke is started in seconds.
-- @return #COORDINATE self
function COORDINATE:SmokeWhite(Duration, Delay)
self:Smoke( SMOKECOLOR.White, Duration, Delay )
return self
end
--- Smoke the COORDINATE Orange.
-- @param #COORDINATE self
function COORDINATE:SmokeOrange()
self:F2()
self:Smoke( SMOKECOLOR.Orange )
-- @param #number Duration (Optional) Duration of the smoke in seconds. DCS stopps the smoke automatically after 5 min.
-- @param #number Delay (Optional) Delay before the smoke is started in seconds.
-- @return #COORDINATE self
function COORDINATE:SmokeOrange(Duration, Delay)
self:Smoke( SMOKECOLOR.Orange, Duration, Delay )
return self
end
--- Smoke the COORDINATE Blue.
-- @param #COORDINATE self
function COORDINATE:SmokeBlue()
self:F2()
self:Smoke( SMOKECOLOR.Blue )
-- @param #number Duration (Optional) Duration of the smoke in seconds. DCS stopps the smoke automatically after 5 min.
-- @param #number Delay (Optional) Delay before the smoke is started in seconds.
-- @return #COORDINATE self
function COORDINATE:SmokeBlue(Duration, Delay)
self:Smoke( SMOKECOLOR.Blue, Duration, Delay )
return self
end
--- Big smoke and fire at the coordinate.
-- @param #COORDINATE self
-- @param Utilities.Utils#BIGSMOKEPRESET preset Smoke preset (1=small smoke and fire, 2=medium smoke and fire, 3=large smoke and fire, 4=huge smoke and fire, 5=small smoke, 6=medium smoke, 7=large smoke, 8=huge smoke).
-- @param #number density (Optional) Smoke density. Number in [0,...,1]. Default 0.5.
-- @param #string name (Optional) Name of the fire to stop it later again if not using the same COORDINATE object. Defaults to "Fire-" plus a random 5-digit-number.
function COORDINATE:BigSmokeAndFire( preset, density, name )
self:F2( { preset=preset, density=density } )
density=density or 0.5
self.firename = name or "Fire-"..math.random(1,10000)
trigger.action.effectSmokeBig( self:GetVec3(), preset, density, self.firename )
-- @param #number Preset Smoke preset (1=small smoke and fire, 2=medium smoke and fire, 3=large smoke and fire, 4=huge smoke and fire, 5=small smoke, 6=medium smoke, 7=large smoke, 8=huge smoke).
-- @param #number Density (Optional) Smoke density. Number in [0,...,1]. Default 0.5.
-- @param #number Duration (Optional) Duration of the smoke and fire in seconds.
-- @param #number Delay (Optional) Delay before the smoke and fire is started in seconds.
-- @param #string Name (Optional) Name of the fire to stop it later again if not using the same COORDINATE object. Defaults to "Fire-" plus a random 5-digit-number.
-- @return #COORDINATE self
function COORDINATE:BigSmokeAndFire( Preset, Density, Duration, Delay, Name )
self:F2( { preset=Preset, density=Density } )
Preset=Preset or BIGSMOKEPRESET.SmallSmokeAndFire
Density=Density or 0.5
if Delay and Delay>0 then
self:ScheduleOnce(Delay, COORDINATE.BigSmokeAndFire, self, Preset, Density, Duration, 0, Name)
else
self.firename = Name or "Fire-"..math.random(1,10000)
trigger.action.effectSmokeBig( self:GetVec3(), Preset, Density, self.firename )
-- Stop smoke
if Duration and Duration>0 then
self:ScheduleOnce(Duration, COORDINATE.StopBigSmokeAndFire, self, self.firename )
end
end
return self
end
--- Stop big smoke and fire at the coordinate.
@@ -2036,82 +2351,98 @@ do -- COORDINATE
--- Small smoke and fire at the coordinate.
-- @param #COORDINATE self
-- @param #number density (Optional) Smoke density. Number between 0 and 1. Default 0.5.
-- @param #string name (Optional) Name of the fire to stop it later again if not using the same COORDINATE object. Defaults to "Fire-" plus a random 5-digit-number.
function COORDINATE:BigSmokeAndFireSmall( density, name )
self:F2( { density=density } )
density=density or 0.5
self:BigSmokeAndFire(BIGSMOKEPRESET.SmallSmokeAndFire, density, name)
-- @param #number Density (Optional) Smoke density. Number between 0 and 1. Default 0.5.
-- @param #number Duration (Optional) Duration of the smoke and fire in seconds.
-- @param #number Delay (Optional) Delay before the smoke and fire is started in seconds.
-- @param #string Name (Optional) Name of the fire to stop it later again if not using the same COORDINATE object. Defaults to "Fire-" plus a random 5-digit-number.
-- @return #COORDINATE self
function COORDINATE:BigSmokeAndFireSmall( Density, Duration, Delay, Name )
self:BigSmokeAndFire(BIGSMOKEPRESET.SmallSmokeAndFire, Density, Duration, Delay, Name)
return self
end
--- Medium smoke and fire at the coordinate.
-- @param #COORDINATE self
-- @param #number density (Optional) Smoke density. Number between 0 and 1. Default 0.5.
-- @param #number Duration (Optional) Duration of the smoke and fire in seconds.
-- @param #number Delay (Optional) Delay before the smoke and fire is started in seconds.
-- @param #string name (Optional) Name of the fire to stop it later again if not using the same COORDINATE object. Defaults to "Fire-" plus a random 5-digit-number.
function COORDINATE:BigSmokeAndFireMedium( density, name )
self:F2( { density=density } )
density=density or 0.5
self:BigSmokeAndFire(BIGSMOKEPRESET.MediumSmokeAndFire, density, name)
-- @return #COORDINATE self
function COORDINATE:BigSmokeAndFireMedium( Density, Duration, Delay, Name )
self:BigSmokeAndFire(BIGSMOKEPRESET.MediumSmokeAndFire, Density, Duration, Delay, Name)
return self
end
--- Large smoke and fire at the coordinate.
-- @param #COORDINATE self
-- @param #number density (Optional) Smoke density. Number between 0 and 1. Default 0.5.
-- @param #number Duration (Optional) Duration of the smoke and fire in seconds.
-- @param #number Delay (Optional) Delay before the smoke and fire is started in seconds.
-- @param #string name (Optional) Name of the fire to stop it later again if not using the same COORDINATE object. Defaults to "Fire-" plus a random 5-digit-number.
function COORDINATE:BigSmokeAndFireLarge( density, name )
self:F2( { density=density } )
density=density or 0.5
self:BigSmokeAndFire(BIGSMOKEPRESET.LargeSmokeAndFire, density, name)
-- @return #COORDINATE self
function COORDINATE:BigSmokeAndFireLarge( Density, Duration, Delay, Name )
self:BigSmokeAndFire(BIGSMOKEPRESET.LargeSmokeAndFire, Density, Duration, Delay, Name)
return self
end
--- Huge smoke and fire at the coordinate.
-- @param #COORDINATE self
-- @param #number density (Optional) Smoke density. Number between 0 and 1. Default 0.5.
-- @param #number Duration (Optional) Duration of the smoke and fire in seconds.
-- @param #number Delay (Optional) Delay before the smoke and fire is started in seconds.
-- @param #string name (Optional) Name of the fire to stop it later again if not using the same COORDINATE object. Defaults to "Fire-" plus a random 5-digit-number.
function COORDINATE:BigSmokeAndFireHuge( density, name )
self:F2( { density=density } )
density=density or 0.5
self:BigSmokeAndFire(BIGSMOKEPRESET.HugeSmokeAndFire, density, name)
-- @return #COORDINATE self
function COORDINATE:BigSmokeAndFireHuge( Density, Duration, Delay, Name )
self:BigSmokeAndFire(BIGSMOKEPRESET.HugeSmokeAndFire, Density, Duration, Delay, Name)
return self
end
--- Small smoke at the coordinate.
-- @param #COORDINATE self
-- @param #number density (Optional) Smoke density. Number between 0 and 1. Default 0.5.
-- @param #number Duration (Optional) Duration of the smoke and fire in seconds.
-- @param #number Delay (Optional) Delay before the smoke and fire is started in seconds.
-- @param #string name (Optional) Name of the fire to stop it later again if not using the same COORDINATE object. Defaults to "Fire-" plus a random 5-digit-number.
function COORDINATE:BigSmokeSmall( density, name )
self:F2( { density=density } )
density=density or 0.5
self:BigSmokeAndFire(BIGSMOKEPRESET.SmallSmoke, density, name)
-- @return #COORDINATE self
function COORDINATE:BigSmokeSmall( Density, Duration, Delay, Name )
self:BigSmokeAndFire(BIGSMOKEPRESET.SmallSmoke, Density, Duration, Delay, Name)
return self
end
--- Medium smoke at the coordinate.
-- @param #COORDINATE self
-- @param number density (Optional) Smoke density. Number between 0 and 1. Default 0.5.
-- @param #number Duration (Optional) Duration of the smoke and fire in seconds.
-- @param #number Delay (Optional) Delay before the smoke and fire is started in seconds.
-- @param #string name (Optional) Name of the fire to stop it later again if not using the same COORDINATE object. Defaults to "Fire-" plus a random 5-digit-number.
function COORDINATE:BigSmokeMedium( density, name )
self:F2( { density=density } )
density=density or 0.5
self:BigSmokeAndFire(BIGSMOKEPRESET.MediumSmoke, density, name)
-- @return #COORDINATE self
function COORDINATE:BigSmokeMedium( Density, Duration, Delay, Name )
self:BigSmokeAndFire(BIGSMOKEPRESET.MediumSmoke, Density, Duration, Delay, Name)
return self
end
--- Large smoke at the coordinate.
-- @param #COORDINATE self
-- @param #number density (Optional) Smoke density. Number between 0 and 1. Default 0.5.
-- @param #number Duration (Optional) Duration of the smoke and fire in seconds.
-- @param #number Delay (Optional) Delay before the smoke and fire is started in seconds.
-- @param #string name (Optional) Name of the fire to stop it later again if not using the same COORDINATE object. Defaults to "Fire-" plus a random 5-digit-number.
function COORDINATE:BigSmokeLarge( density, name )
self:F2( { density=density } )
density=density or 0.5
self:BigSmokeAndFire(BIGSMOKEPRESET.LargeSmoke, density,name)
-- @return #COORDINATE self
function COORDINATE:BigSmokeLarge( Density, Duration, Delay, Name )
self:BigSmokeAndFire(BIGSMOKEPRESET.LargeSmoke, Density, Duration, Delay, Name)
return self
end
--- Huge smoke at the coordinate.
-- @param #COORDINATE self
-- @param #number density (Optional) Smoke density. Number between 0 and 1. Default 0.5.
-- @param #number Duration (Optional) Duration of the smoke and fire in seconds.
-- @param #number Delay (Optional) Delay before the smoke and fire is started in seconds.
-- @param #string name (Optional) Name of the fire to stop it later again if not using the same COORDINATE object. Defaults to "Fire-" plus a random 5-digit-number.
function COORDINATE:BigSmokeHuge( density, name )
self:F2( { density=density } )
density=density or 0.5
self:BigSmokeAndFire(BIGSMOKEPRESET.HugeSmoke, density,name)
-- @return #COORDINATE self
function COORDINATE:BigSmokeHuge( Density, Duration, Delay, Name )
self:BigSmokeAndFire(BIGSMOKEPRESET.HugeSmoke, Density, Duration, Delay, Name)
return self
end
--- Flares the point in a color.
@@ -2765,8 +3096,10 @@ do -- COORDINATE
local sunrise=UTILS.GetSunRiseAndSet(DayOfYear, Latitude, Longitude, true, Tdiff)
local sunset=UTILS.GetSunRiseAndSet(DayOfYear, Latitude, Longitude, false, Tdiff)
if sunrise == "N/R" then return false end
if sunrise == "N/S" then return true end
if type(sunrise) == "string" or type(sunset) == "string" then
if sunrise == "N/R" then return false end
if sunset == "N/S" then return true end
end
local time=UTILS.ClockToSeconds(clock)
@@ -2784,6 +3117,11 @@ do -- COORDINATE
-- Todays sun set in sec.
local sunset=self:GetSunset(true)
if type(sunrise) == "string" or type(sunset) == "string" then
if sunrise == "N/R" then return false end
if sunset == "N/S" then return true end
end
-- Seconds passed since midnight.
local time=UTILS.SecondsOfToday()
@@ -3474,9 +3812,37 @@ do -- COORDINATE
return flat, elev
end
--- Return a random COORDINATE within an Outer Radius and optionally NOT within an Inner Radius of the COORDINATE.
-- @param #COORDINATE self
-- @param DCS#Distance OuterRadius
-- @param DCS#Distance InnerRadius
-- @return #COORDINATE
function COORDINATE:GetRandomPointVec3InRadius( OuterRadius, InnerRadius )
return COORDINATE:NewFromVec3( self:GetRandomVec3InRadius( OuterRadius, InnerRadius ) )
end
--- Search for clear zones in a given area. A powerful and efficient function using Disposition to find clear areas for spawning ground units avoiding trees, water and map scenery.
-- @param #number SearchRadius Radius of the search area.
-- @param #number PosRadius Required clear radius around each position.
-- @param #number NumPositions Number of positions to find.
-- @return #table A table of Core.Point#COORDINATE that are clear of map objects within the given PosRadius. nil if no positions are found.
function COORDINATE:GetSimpleZones(SearchRadius, PosRadius, NumPositions)
local clearPositions = UTILS.GetSimpleZones(self:GetVec3(), SearchRadius, PosRadius, NumPositions)
if clearPositions and #clearPositions > 0 then
local coords = {}
for _, pos in pairs(clearPositions) do
local coord = COORDINATE:NewFromVec2(pos)
table.insert(coords, coord)
end
return coords
end
return nil
end
end
do -- POINT_VEC3
do
--- The POINT_VEC3 class
-- @type POINT_VEC3
@@ -3493,6 +3859,8 @@ do -- POINT_VEC3
--- Defines a 3D point in the simulator and with its methods, you can use or manipulate the point in 3D space.
--
-- **DEPRECATED - PLEASE USE COORDINATE!**
--
-- **Important Note:** Most of the functions in this section were taken from MIST, and reworked to OO concepts.
-- In order to keep the credibility of the the author,
-- I want to emphasize that the formulas embedded in the MIST framework were created by Grimes or previous authors,
@@ -3580,130 +3948,19 @@ do -- POINT_VEC3
return self
end
--- Create a new POINT_VEC3 object from Vec2 coordinates.
-- @param #POINT_VEC3 self
-- @param DCS#Vec2 Vec2 The Vec2 point.
-- @param DCS#Distance LandHeightAdd (optional) Add a landheight.
-- @return Core.Point#POINT_VEC3 self
function POINT_VEC3:NewFromVec2( Vec2, LandHeightAdd )
local self = BASE:Inherit( self, COORDINATE:NewFromVec2( Vec2, LandHeightAdd ) ) -- Core.Point#POINT_VEC3
self:F2( self )
return self
end
--- Create a new POINT_VEC3 object from Vec3 coordinates.
-- @param #POINT_VEC3 self
-- @param DCS#Vec3 Vec3 The Vec3 point.
-- @return Core.Point#POINT_VEC3 self
function POINT_VEC3:NewFromVec3( Vec3 )
local self = BASE:Inherit( self, COORDINATE:NewFromVec3( Vec3 ) ) -- Core.Point#POINT_VEC3
self:F2( self )
return self
end
--- Return the x coordinate of the POINT_VEC3.
-- @param #POINT_VEC3 self
-- @return #number The x coordinate.
function POINT_VEC3:GetX()
return self.x
end
--- Return the y coordinate of the POINT_VEC3.
-- @param #POINT_VEC3 self
-- @return #number The y coordinate.
function POINT_VEC3:GetY()
return self.y
end
--- Return the z coordinate of the POINT_VEC3.
-- @param #POINT_VEC3 self
-- @return #number The z coordinate.
function POINT_VEC3:GetZ()
return self.z
end
--- Set the x coordinate of the POINT_VEC3.
-- @param #POINT_VEC3 self
-- @param #number x The x coordinate.
-- @return #POINT_VEC3
function POINT_VEC3:SetX( x )
self.x = x
return self
end
--- Set the y coordinate of the POINT_VEC3.
-- @param #POINT_VEC3 self
-- @param #number y The y coordinate.
-- @return #POINT_VEC3
function POINT_VEC3:SetY( y )
self.y = y
return self
end
--- Set the z coordinate of the POINT_VEC3.
-- @param #POINT_VEC3 self
-- @param #number z The z coordinate.
-- @return #POINT_VEC3
function POINT_VEC3:SetZ( z )
self.z = z
return self
end
--- Add to the x coordinate of the POINT_VEC3.
-- @param #POINT_VEC3 self
-- @param #number x The x coordinate value to add to the current x coordinate.
-- @return #POINT_VEC3
function POINT_VEC3:AddX( x )
self.x = self.x + x
return self
end
--- Add to the y coordinate of the POINT_VEC3.
-- @param #POINT_VEC3 self
-- @param #number y The y coordinate value to add to the current y coordinate.
-- @return #POINT_VEC3
function POINT_VEC3:AddY( y )
self.y = self.y + y
return self
end
--- Add to the z coordinate of the POINT_VEC3.
-- @param #POINT_VEC3 self
-- @param #number z The z coordinate value to add to the current z coordinate.
-- @return #POINT_VEC3
function POINT_VEC3:AddZ( z )
self.z = self.z +z
return self
end
--- Return a random POINT_VEC3 within an Outer Radius and optionally NOT within an Inner Radius of the POINT_VEC3.
-- @param #POINT_VEC3 self
-- @param DCS#Distance OuterRadius
-- @param DCS#Distance InnerRadius
-- @return #POINT_VEC3
function POINT_VEC3:GetRandomPointVec3InRadius( OuterRadius, InnerRadius )
return POINT_VEC3:NewFromVec3( self:GetRandomVec3InRadius( OuterRadius, InnerRadius ) )
end
end
do -- POINT_VEC2
do
-- @type POINT_VEC2
--- @type POINT_VEC2
-- @field DCS#Distance x The x coordinate in meters.
-- @field DCS#Distance y the y coordinate in meters.
-- @extends Core.Point#COORDINATE
--- Defines a 2D point in the simulator. The height coordinate (if needed) will be the land height + an optional added height specified.
--
-- **DEPRECATED - PLEASE USE COORDINATE!**
--
-- ## POINT_VEC2 constructor
--
-- A new POINT_VEC2 instance can be created with:
@@ -3751,166 +4008,4 @@ do -- POINT_VEC2
return self
end
--- Create a new POINT_VEC2 object from Vec2 coordinates.
-- @param #POINT_VEC2 self
-- @param DCS#Vec2 Vec2 The Vec2 point.
-- @return Core.Point#POINT_VEC2 self
function POINT_VEC2:NewFromVec2( Vec2, LandHeightAdd )
local LandHeight = land.getHeight( Vec2 )
LandHeightAdd = LandHeightAdd or 0
LandHeight = LandHeight + LandHeightAdd
local self = BASE:Inherit( self, COORDINATE:NewFromVec2( Vec2, LandHeightAdd ) ) -- #POINT_VEC2
self:F2( self )
return self
end
--- Create a new POINT_VEC2 object from Vec3 coordinates.
-- @param #POINT_VEC2 self
-- @param DCS#Vec3 Vec3 The Vec3 point.
-- @return Core.Point#POINT_VEC2 self
function POINT_VEC2:NewFromVec3( Vec3 )
local self = BASE:Inherit( self, COORDINATE:NewFromVec3( Vec3 ) ) -- #POINT_VEC2
self:F2( self )
return self
end
--- Return the x coordinate of the POINT_VEC2.
-- @param #POINT_VEC2 self
-- @return #number The x coordinate.
function POINT_VEC2:GetX()
return self.x
end
--- Return the y coordinate of the POINT_VEC2.
-- @param #POINT_VEC2 self
-- @return #number The y coordinate.
function POINT_VEC2:GetY()
return self.z
end
--- Set the x coordinate of the POINT_VEC2.
-- @param #POINT_VEC2 self
-- @param #number x The x coordinate.
-- @return #POINT_VEC2
function POINT_VEC2:SetX( x )
self.x = x
return self
end
--- Set the y coordinate of the POINT_VEC2.
-- @param #POINT_VEC2 self
-- @param #number y The y coordinate.
-- @return #POINT_VEC2
function POINT_VEC2:SetY( y )
self.z = y
return self
end
--- Return Return the Lat(itude) coordinate of the POINT_VEC2 (ie: (parent)POINT_VEC3.x).
-- @param #POINT_VEC2 self
-- @return #number The x coordinate.
function POINT_VEC2:GetLat()
return self.x
end
--- Set the Lat(itude) coordinate of the POINT_VEC2 (ie: POINT_VEC3.x).
-- @param #POINT_VEC2 self
-- @param #number x The x coordinate.
-- @return #POINT_VEC2
function POINT_VEC2:SetLat( x )
self.x = x
return self
end
--- Return the Lon(gitude) coordinate of the POINT_VEC2 (ie: (parent)POINT_VEC3.z).
-- @param #POINT_VEC2 self
-- @return #number The y coordinate.
function POINT_VEC2:GetLon()
return self.z
end
--- Set the Lon(gitude) coordinate of the POINT_VEC2 (ie: POINT_VEC3.z).
-- @param #POINT_VEC2 self
-- @param #number y The y coordinate.
-- @return #POINT_VEC2
function POINT_VEC2:SetLon( z )
self.z = z
return self
end
--- Return the altitude (height) of the land at the POINT_VEC2.
-- @param #POINT_VEC2 self
-- @return #number The land altitude.
function POINT_VEC2:GetAlt()
return self.y ~= 0 or land.getHeight( { x = self.x, y = self.z } )
end
--- Set the altitude of the POINT_VEC2.
-- @param #POINT_VEC2 self
-- @param #number Altitude The land altitude. If nothing (nil) is given, then the current land altitude is set.
-- @return #POINT_VEC2
function POINT_VEC2:SetAlt( Altitude )
self.y = Altitude or land.getHeight( { x = self.x, y = self.z } )
return self
end
--- Add to the x coordinate of the POINT_VEC2.
-- @param #POINT_VEC2 self
-- @param #number x The x coordinate.
-- @return #POINT_VEC2
function POINT_VEC2:AddX( x )
self.x = self.x + x
return self
end
--- Add to the y coordinate of the POINT_VEC2.
-- @param #POINT_VEC2 self
-- @param #number y The y coordinate.
-- @return #POINT_VEC2
function POINT_VEC2:AddY( y )
self.z = self.z + y
return self
end
--- Add to the current land height an altitude.
-- @param #POINT_VEC2 self
-- @param #number Altitude The Altitude to add. If nothing (nil) is given, then the current land altitude is set.
-- @return #POINT_VEC2
function POINT_VEC2:AddAlt( Altitude )
self.y = land.getHeight( { x = self.x, y = self.z } ) + Altitude or 0
return self
end
--- Return a random POINT_VEC2 within an Outer Radius and optionally NOT within an Inner Radius of the POINT_VEC2.
-- @param #POINT_VEC2 self
-- @param DCS#Distance OuterRadius
-- @param DCS#Distance InnerRadius
-- @return #POINT_VEC2
function POINT_VEC2:GetRandomPointVec2InRadius( OuterRadius, InnerRadius )
self:F2( { OuterRadius, InnerRadius } )
return POINT_VEC2:NewFromVec2( self:GetRandomVec2InRadius( OuterRadius, InnerRadius ) )
end
-- TODO: Check this to replace
--- Calculate the distance from a reference @{#POINT_VEC2}.
-- @param #POINT_VEC2 self
-- @param #POINT_VEC2 PointVec2Reference The reference @{#POINT_VEC2}.
-- @return DCS#Distance The distance from the reference @{#POINT_VEC2} in meters.
function POINT_VEC2:DistanceFromPointVec2( PointVec2Reference )
self:F2( PointVec2Reference )
local Distance = ( ( PointVec2Reference.x - self.x ) ^ 2 + ( PointVec2Reference.z - self.z ) ^2 ) ^ 0.5
self:T2( Distance )
return Distance
end
end
@@ -175,7 +175,7 @@ function SCHEDULEDISPATCHER:AddSchedule( Scheduler, ScheduleFunction, ScheduleAr
local Name = Info.name or "?"
local ErrorHandler = function( errmsg )
env.info( "Error in timer function: " .. errmsg )
env.info( "Error in timer function: " .. errmsg or "" )
if BASE.Debug ~= nil then
env.info( BASE.Debug.traceback() )
end
@@ -326,7 +326,7 @@ function SCHEDULEDISPATCHER:Stop( Scheduler, CallID )
local Schedule = self.Schedule[Scheduler][CallID] -- #SCHEDULEDISPATCHER.ScheduleData
-- Only stop when there is a ScheduleID defined for the CallID. So, when the scheduler was stopped before, do nothing.
if Schedule.ScheduleID then
if Schedule and Schedule.ScheduleID then
self:T( string.format( "SCHEDULEDISPATCHER stopping scheduler CallID=%s, ScheduleID=%s", tostring( CallID ), tostring( Schedule.ScheduleID ) ) )
File diff suppressed because it is too large Load Diff
+29 -6
View File
@@ -1049,6 +1049,23 @@ function SPAWN:InitSetUnitAbsolutePositions(Positions)
return self
end
--- Uses Disposition and other fallback logic to find better ground positions for ground units.
--- NOTE: This is not a spawn randomizer.
--- It will try to find clear ground locations avoiding trees, water, roads, runways, map scenery, statics and other units in the area.
--- Maintains the original layout and unit positions as close as possible by searching for the next closest valid position to each unit.
-- @param #SPAWN self
-- @param #boolean OnOff Enable/disable the feature.
-- @param #number MaxRadius (Optional) Max radius to search for valid ground locations in meters. Default is double the max radius of the units.
-- @param #number Spacing (Optional) Minimum spacing between units in meters. Default is 5% of the search radius or 5 meters, whichever is larger.
-- @return #SPAWN
function SPAWN:InitValidateAndRepositionGroundUnits(OnOff, MaxRadius, Spacing)
self.SpawnValidateAndRepositionGroundUnits = OnOff
self.SpawnValidateAndRepositionGroundUnitsRadius = MaxRadius
self.SpawnValidateAndRepositionGroundUnitsSpacing = Spacing
return self
end
--- This method is rather complicated to understand. But I'll try to explain.
-- 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.
@@ -1631,7 +1648,7 @@ function SPAWN:SpawnWithIndex( SpawnIndex, NoBirth )
if SpawnTemplate then
local PointVec3 = POINT_VEC3:New( SpawnTemplate.route.points[1].x, SpawnTemplate.route.points[1].alt, SpawnTemplate.route.points[1].y )
local PointVec3 = COORDINATE:New( SpawnTemplate.route.points[1].x, SpawnTemplate.route.points[1].alt, SpawnTemplate.route.points[1].y )
--self:T2( { "Current point of ", self.SpawnTemplatePrefix, PointVec3 } )
-- If RandomizePosition, then Randomize the formation in the zone band, keeping the template.
@@ -1829,7 +1846,13 @@ function SPAWN:SpawnWithIndex( SpawnIndex, NoBirth )
if self.SpawnHiddenOnMap then
SpawnTemplate.hidden=self.SpawnHiddenOnMap
end
if self.SpawnValidateAndRepositionGroundUnits then
local units = SpawnTemplate.units
local gPos = { x = SpawnTemplate.x, y = SpawnTemplate.y }
UTILS.ValidateAndRepositionGroundUnits(units, gPos, self.SpawnValidateAndRepositionGroundUnitsRadius, self.SpawnValidateAndRepositionGroundUnitsSpacing)
end
-- Set country, coalition and category.
SpawnTemplate.CategoryID = self.SpawnInitCategory or SpawnTemplate.CategoryID
SpawnTemplate.CountryID = self.SpawnInitCountry or SpawnTemplate.CountryID
@@ -2830,7 +2853,7 @@ end
function SPAWN:SpawnFromVec3( Vec3, SpawnIndex )
--self:F( { self.SpawnTemplatePrefix, Vec3, SpawnIndex } )
local PointVec3 = POINT_VEC3:NewFromVec3( Vec3 )
local PointVec3 = COORDINATE:NewFromVec3( Vec3 )
--self:T2( PointVec3 )
if SpawnIndex then
@@ -2906,7 +2929,7 @@ end
-- Note that each point in the route assigned to the spawning group is reset to the point of the spawn.
-- You can use the returned group to further define the route to be followed.
-- @param #SPAWN self
-- @param Core.Point#POINT_VEC3 PointVec3 The PointVec3 coordinates where to spawn the group.
-- @param Core.Point#COORDINATE PointVec3 The COORDINATE coordinates where to spawn the group.
-- @param #number SpawnIndex (optional) The index which group to spawn within the given zone.
-- @return Wrapper.Group#GROUP that was spawned or #nil if nothing was spawned.
-- @usage
@@ -2954,12 +2977,12 @@ function SPAWN:SpawnFromVec2( Vec2, MinHeight, MaxHeight, SpawnIndex )
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
--- Will spawn a group from a POINT_VEC2 in 3D space.
--- Will spawn a group from a COORDINATE in 3D space.
-- This method is mostly advisable to be used if you want to simulate spawning groups on the ground from air units, like vehicles.
-- Note that each point in the route assigned to the spawning group is reset to the point of the spawn.
-- You can use the returned group to further define the route to be followed.
-- @param #SPAWN self
-- @param Core.Point#POINT_VEC2 PointVec2 The PointVec2 coordinates where to spawn the group.
-- @param Core.Point#COORDINATE PointVec2 The 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.
+55 -7
View File
@@ -105,7 +105,7 @@
--
-- * @{#SPAWNSTATIC.Spawn}(Heading, NewName) spawns the static with the set parameters. Optionally, heading and name can be given. The name **must be unique**!
-- * @{#SPAWNSTATIC.SpawnFromCoordinate}(Coordinate, Heading, NewName) spawn the static at the given coordinate. Optionally, heading and name can be given. The name **must be unique**!
-- * @{#SPAWNSTATIC.SpawnFromPointVec2}(PointVec2, Heading, NewName) spawns the static at a POINT_VEC2 coordinate. Optionally, heading and name can be given. The name **must be unique**!
-- * @{#SPAWNSTATIC.SpawnFromPointVec2}(PointVec2, Heading, NewName) spawns the static at a COORDINATE coordinate. Optionally, heading and name can be given. The name **must be unique**!
-- * @{#SPAWNSTATIC.SpawnFromZone}(Zone, Heading, NewName) spawns the static at the center of a @{Core.Zone}. Optionally, heading and name can be given. The name **must be unique**!
--
-- @field #SPAWNSTATIC SPAWNSTATIC
@@ -149,6 +149,7 @@ function SPAWNSTATIC:NewFromStatic(SpawnTemplateName, SpawnCountryID)
self.CategoryID = CategoryID
self.CoalitionID = CoalitionID
self.SpawnIndex = 0
self.StaticCopyFrom = SpawnTemplateName
else
error( "SPAWNSTATIC:New: There is no static declared in the mission editor with SpawnTemplatePrefix = '" .. tostring(SpawnTemplateName) .. "'" )
end
@@ -302,12 +303,16 @@ end
-- @param #number CallsignID Callsign ID. Default 1 (="London").
-- @param #number Frequency Frequency in MHz. Default 127.5 MHz.
-- @param #number Modulation Modulation 0=AM, 1=FM.
-- @param #boolean DynamicSpawns If true, allow Dynamic Spawns
-- @param #boolean DynamicHotStarts If true, and DynamicSpawns is true, then allow Dynamic Spawns with hot starts.
-- @return #SPAWNSTATIC self
function SPAWNSTATIC:InitFARP(CallsignID, Frequency, Modulation)
function SPAWNSTATIC:InitFARP(CallsignID, Frequency, Modulation, DynamicSpawns,DynamicHotStarts)
self.InitFarp=true
self.InitFarpCallsignID=CallsignID or 1
self.InitFarpFreq=Frequency or 127.5
self.InitFarpModu=Modulation or 0
self.InitFarpDynamicSpawns = DynamicSpawns
self.InitFarpDynamicHotStarts = (DynamicSpawns == true and DynamicHotStarts == true) and true or nil
return self
end
@@ -373,6 +378,20 @@ function SPAWNSTATIC:InitLinkToUnit(Unit, OffsetX, OffsetY, OffsetAngle)
return self
end
--- Uses Disposition and other fallback logic to find a better and valid ground spawn position.
--- NOTE: This is not a spawn randomizer.
--- It will try to a find clear ground location avoiding trees, water, roads, runways, map scenery, other statics and other units in the area.
--- Uses the initial position if it's a valid location.
-- @param #SPAWNSTATIC self
-- @param #boolean OnOff Enable/disable the feature.
-- @param #number MaxRadius (Optional) Max radius to search for a valid ground location in meters. Default is 10 times the max radius of the static.
-- @return #SPAWNSTATIC self
function SPAWNSTATIC:InitValidateAndRepositionStatic(OnOff, MaxRadius)
self.ValidateAndRepositionStatic = OnOff
self.ValidateAndRepositionStaticMaxRadius = MaxRadius
return self
end
--- Allows to place a CallFunction hook when a new static spawns.
-- The provided method will be called when a new group is spawned, including its given parameters.
-- The first parameter of the SpawnFunction is the @{Wrapper.Static#STATIC} that was spawned.
@@ -411,9 +430,9 @@ function SPAWNSTATIC:Spawn(Heading, NewName)
end
--- Creates a new @{Wrapper.Static} from a POINT_VEC2.
--- Creates a new @{Wrapper.Static} from a COORDINATE.
-- @param #SPAWNSTATIC self
-- @param Core.Point#POINT_VEC2 PointVec2 The 2D coordinate where to spawn the static.
-- @param Core.Point#COORDINATE PointVec2 The 2D coordinate where to spawn the static.
-- @param #number Heading The heading of the static, which is a number in degrees from 0 to 360.
-- @param #string NewName (Optional) The name of the new static.
-- @return Wrapper.Static#STATIC The static spawned.
@@ -459,8 +478,9 @@ end
function SPAWNSTATIC:SpawnFromZone(Zone, Heading, NewName)
-- Spawn the new static at the center of the zone.
local Static = self:SpawnFromPointVec2( Zone:GetPointVec2(), Heading, NewName )
--local Static = self:SpawnFromPointVec2( Zone:GetPointVec2(), Heading, NewName )
local Static = self:SpawnFromCoordinate(Zone:GetCoordinate(), Heading, NewName)
return Static
end
@@ -538,6 +558,14 @@ function SPAWNSTATIC:_SpawnStatic(Template, CountryID)
-- Add static to the game.
local Static=nil --DCS#StaticObject
if self.ValidateAndRepositionStatic then
local validPos = UTILS.ValidateAndRepositionStatic(CountryID, Template.category, Template.type, Template, Template.shape_name, self.ValidateAndRepositionStaticMaxRadius)
if validPos then
Template.x = validPos.x
Template.y = validPos.y
end
end
if self.InitFarp then
local TemplateGroup={}
@@ -549,6 +577,13 @@ function SPAWNSTATIC:_SpawnStatic(Template, CountryID)
TemplateGroup.x=Template.x
TemplateGroup.y=Template.y
TemplateGroup.name=Template.name
if self.InitFarpDynamicSpawns == true then
TemplateGroup.units[1].dynamicSpawn = true
if self.InitFarpDynamicHotStarts == true then
TemplateGroup.units[1].allowHotStart = true
end
end
self:T("Spawning FARP")
self:T({Template=Template})
@@ -556,7 +591,8 @@ function SPAWNSTATIC:_SpawnStatic(Template, CountryID)
-- ED's dirty way to spawn FARPS.
Static=coalition.addGroup(CountryID, -1, TemplateGroup)
--Static=coalition.addStaticObject(CountryID, Template)
-- Currently DCS 2.8 does not trigger birth events if FARPS are spawned!
-- We create such an event. The airbase is registered in Core.Event
local Event = {
@@ -594,6 +630,18 @@ function SPAWNSTATIC:_SpawnStatic(Template, CountryID)
-- delay calling this for .3 seconds so that it hopefully comes after the BIRTH event of the group.
self:ScheduleOnce(0.3, self.SpawnFunctionHook, mystatic, unpack(self.SpawnFunctionArguments))
end
if self.StaticCopyFrom ~= nil then
mystatic.StaticCopyFrom = self.StaticCopyFrom
end
local TemplateGroup={}
TemplateGroup.units={}
TemplateGroup.units[1]=Template
TemplateGroup.x=Template.x
TemplateGroup.y=Template.y
TemplateGroup.name=Template.name
_DATABASE:_RegisterStaticTemplate( TemplateGroup, self.CoalitionID, self.CategoryID, CountryID )
return mystatic
end
+160 -58
View File
@@ -70,6 +70,7 @@
-- @field #table Table of any trigger zone properties from the ME. The key is the Name of the property, and the value is the property's Value.
-- @field #number Surface Type of surface. Only determined at the center of the zone!
-- @field #number Checktime Check every Checktime seconds, used for ZONE:Trigger()
-- @field #boolean PartlyInside When called, a GROUP is considered inside as soon as any of its units enters the zone even if they are far apart.
-- @extends Core.Fsm#FSM
@@ -213,7 +214,7 @@ end
--- Returns if a PointVec3 is within the zone.
-- @param #ZONE_BASE self
-- @param Core.Point#POINT_VEC3 PointVec3 The PointVec3 to test.
-- @param Core.Point#COORDINATE PointVec3 The PointVec3 to test.
-- @return #boolean true if the PointVec3 is within the zone.
function ZONE_BASE:IsPointVec3InZone( PointVec3 )
local InZone = self:IsPointVec2InZone( PointVec3 )
@@ -227,16 +228,16 @@ function ZONE_BASE:GetVec2()
return nil
end
--- Returns a @{Core.Point#POINT_VEC2} of the zone.
--- Returns a @{Core.Point#COORDINATE} of the zone.
-- @param #ZONE_BASE self
-- @param DCS#Distance Height The height to add to the land height where the center of the zone is located.
-- @return Core.Point#POINT_VEC2 The PointVec2 of the zone.
-- @return Core.Point#COORDINATE The COORDINATE of the zone.
function ZONE_BASE:GetPointVec2()
--self:F2( self.ZoneName )
local Vec2 = self:GetVec2()
local PointVec2 = POINT_VEC2:NewFromVec2( Vec2 )
local PointVec2 = COORDINATE:NewFromVec2( Vec2 )
--self:T2( { PointVec2 } )
@@ -261,16 +262,16 @@ function ZONE_BASE:GetVec3( Height )
return Vec3
end
--- Returns a @{Core.Point#POINT_VEC3} of the zone.
--- Returns a @{Core.Point#COORDINATE} of the zone.
-- @param #ZONE_BASE self
-- @param DCS#Distance Height The height to add to the land height where the center of the zone is located.
-- @return Core.Point#POINT_VEC3 The PointVec3 of the zone.
-- @return Core.Point#COORDINATE The PointVec3 of the zone.
function ZONE_BASE:GetPointVec3( Height )
--self:F2( self.ZoneName )
local Vec3 = self:GetVec3( Height )
local PointVec3 = POINT_VEC3:NewFromVec3( Vec3 )
local PointVec3 = COORDINATE:NewFromVec3( Vec3 )
--self:T2( { PointVec3 } )
@@ -330,16 +331,16 @@ function ZONE_BASE:GetRandomVec2()
return nil
end
--- Define a random @{Core.Point#POINT_VEC2} within the zone. Note that this is actually a @{Core.Point#COORDINATE} type object, and not a simple Vec2 table.
--- Define a random @{Core.Point#COORDINATE} within the zone. Note that this is actually a @{Core.Point#COORDINATE} type object, and not a simple Vec2 table.
-- @param #ZONE_BASE self
-- @return Core.Point#POINT_VEC2 The PointVec2 coordinates.
-- @return Core.Point#COORDINATE The COORDINATE coordinates.
function ZONE_BASE:GetRandomPointVec2()
return nil
end
--- Define a random @{Core.Point#POINT_VEC3} within the zone. Note that this is actually a @{Core.Point#COORDINATE} type object, and not a simple Vec3 table.
--- Define a random @{Core.Point#COORDINATE} within the zone. Note that this is actually a @{Core.Point#COORDINATE} type object, and not a simple Vec3 table.
-- @param #ZONE_BASE self
-- @return Core.Point#POINT_VEC3 The PointVec3 coordinates.
-- @return Core.Point#COORDINATE The COORDINATE coordinates.
function ZONE_BASE:GetRandomPointVec3()
return nil
end
@@ -534,6 +535,19 @@ function ZONE_BASE:GetZoneProbability()
return self.ZoneProbability
end
--- Get the coordinate on the radius of the zone nearest to Outsidecoordinate. Useto e.g. find an ingress point.
-- @param #ZONE_BASE self
-- @param Core.Point#COORDINATE Outsidecoordinate The coordinate outside of the zone from where to look.
-- @return Core.Point#COORDINATE CoordinateOnRadius
function ZONE_BASE:FindNearestCoordinateOnRadius(Outsidecoordinate)
local Vec1 = self:GetVec2()
local Radius = self:GetRadius()
local Vec2 = Outsidecoordinate:GetVec2()
local Point = UTILS.FindNearestPointOnCircle(Vec1,Radius,Vec2)
local rc = COORDINATE:NewFromVec2(Point)
return rc
end
--- Get the zone taking into account the randomization probability of a zone to be selected.
-- @param #ZONE_BASE self
-- @return #ZONE_BASE The zone is selected taking into account the randomization probability factor.
@@ -599,6 +613,8 @@ end
--
-- -- Stop watching the zone after 1 hour
-- triggerzone:__TriggerStop(3600)
-- -- Call :SetPartlyInside() if you use SET_GROUP to count as inside when any of their units enters even when they are far apart.
-- -- Make sure to call :SetPartlyInside() before :Trigger()!
function ZONE_BASE:Trigger(Objects)
--self:I("Added Zone Trigger")
self:SetStartState("TriggerStopped")
@@ -667,6 +683,16 @@ function ZONE_BASE:Trigger(Objects)
end
--- Toggle “partly-inside” handling for this zone. To be used before :Trigger().
-- * Default:* flag is **false** until you call the method.
-- * Call with no argument or with **true** → enable.
-- * Call with **false** → disable again (handy if it was enabled before).
-- @param #ZONE_BASE self
-- @return #ZONE_BASE self
function ZONE_BASE:SetPartlyInside(state)
self.PartlyInside = state or not ( state == false )
return self
end
--- (Internal) Check the assigned objects for being in/out of the zone
-- @param #ZONE_BASE self
-- @param #boolean fromstart If true, do the init of the objects
@@ -705,7 +731,12 @@ function ZONE_BASE:_TriggerCheck(fromstart)
obj.TriggerInZone[self.ZoneName] = false
end
-- is obj in zone?
local inzone = self:IsCoordinateInZone(obj:GetCoordinate())
local inzone
if self.PartlyInside and obj.ClassName == "GROUP" then
inzone = obj:IsAnyInZone(self) -- TRUE if any unit is inside
else
inzone = self:IsCoordinateInZone(obj:GetCoordinate()) -- original barycentre test
end
--self:I("Object "..obj:GetName().." is in zone: "..tostring(inzone))
if inzone and obj.TriggerInZone[self.ZoneName] then
-- just count
@@ -814,8 +845,8 @@ end
-- Various functions exist to find random points within the zone.
--
-- * @{#ZONE_RADIUS.GetRandomVec2}(): Gets a random 2D point in the zone.
-- * @{#ZONE_RADIUS.GetRandomPointVec2}(): Gets a @{Core.Point#POINT_VEC2} object representing a random 2D point in the zone.
-- * @{#ZONE_RADIUS.GetRandomPointVec3}(): Gets a @{Core.Point#POINT_VEC3} object representing a random 3D point in the zone. Note that the height of the point is at landheight.
-- * @{#ZONE_RADIUS.GetRandomPointVec2}(): Gets a @{Core.Point#COORDINATE} object representing a random 2D point in the zone.
-- * @{#ZONE_RADIUS.GetRandomPointVec3}(): Gets a @{Core.Point#COORDINATE} object representing a random 3D point in the zone. Note that the height of the point is at landheight.
--
-- ## Draw zone
--
@@ -1010,7 +1041,7 @@ function ZONE_RADIUS:SmokeZone( SmokeColor, Points, AddHeight, AngleOffset )
local Radial = ( Angle + AngleOffset ) * RadialBase / 360
Point.x = Vec2.x + math.cos( Radial ) * self:GetRadius()
Point.y = Vec2.y + math.sin( Radial ) * self:GetRadius()
POINT_VEC2:New( Point.x, Point.y, AddHeight ):Smoke( SmokeColor )
COORDINATE:New( Point.x, AddHeight, Point.y ):Smoke( SmokeColor )
end
return self
@@ -1040,7 +1071,7 @@ function ZONE_RADIUS:FlareZone( FlareColor, Points, Azimuth, AddHeight )
local Radial = Angle * RadialBase / 360
Point.x = Vec2.x + math.cos( Radial ) * self:GetRadius()
Point.y = Vec2.y + math.sin( Radial ) * self:GetRadius()
POINT_VEC2:New( Point.x, Point.y, AddHeight ):Flare( FlareColor, Azimuth )
COORDINATE:New( Point.x, AddHeight, Point.y ):Flare( FlareColor, Azimuth )
end
return self
@@ -1134,7 +1165,7 @@ function ZONE_RADIUS:Scan( ObjectCategories, UnitCategories )
self.ScanData.SceneryTable = {}
self.ScanData.Units = {}
local ZoneCoord = self:GetCoordinate()
local ZoneCoord = self:GetCoordinate():SetAlt()
local ZoneRadius = self:GetRadius()
--self:F({ZoneCoord = ZoneCoord, ZoneRadius = ZoneRadius, ZoneCoordLL = ZoneCoord:ToStringLLDMS()})
@@ -1149,15 +1180,13 @@ function ZONE_RADIUS:Scan( ObjectCategories, UnitCategories )
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
if ZoneObject and self:IsVec3InZone(ZoneObject:getPoint()) then
-- Get object category.
local ObjectCategory = Object.getCategory(ZoneObject)
if ( ObjectCategory == Object.Category.UNIT and ZoneObject:isExist() and ZoneObject:isActive() ) or (ObjectCategory == Object.Category.STATIC and ZoneObject:isExist()) then
local CoalitionDCSUnit = ZoneObject:getCoalition()
local Include = false
if not UnitCategories then
-- Anything found is included.
@@ -1509,6 +1538,26 @@ function ZONE_RADIUS:IsVec3InZone( Vec3 )
return InZone
end
--- Search for clear ground spawn zones within this zone. A powerful and efficient function using Disposition to find clear areas for spawning ground units avoiding trees, water and map scenery.
-- @param #ZONE_RADIUS self
-- @param #number PosRadius Required clear radius around each position.
-- @param #number NumPositions Number of positions to find.
-- @return #table A table of DCS#Vec2 positions that are clear of map objects within the given PosRadius. nil if no clear positions are found.
function ZONE_RADIUS:GetClearZonePositions(PosRadius, NumPositions)
return UTILS.GetClearZonePositions(self, PosRadius, NumPositions)
end
--- Search for a random clear ground spawn coordinate within this zone. A powerful and efficient function using Disposition to find clear areas for spawning ground units avoiding trees, water and map scenery.
-- @param #ZONE_RADIUS self
-- @param #number PosRadius (Optional) Required clear radius around each position. (Default is math.min(Radius/10, 200))
-- @param #number NumPositions (Optional) Number of positions to find. (Default 50)
-- @return Core.Point#COORDINATE A random coordinate for a clear zone. nil if no clear positions are found.
-- @return #number Assigned radius for the found zones. nil if no clear positions are found.
function ZONE_RADIUS:GetRandomClearZoneCoordinate(PosRadius, NumPositions)
return UTILS.GetRandomClearZoneCoordinate(self, PosRadius, NumPositions)
end
--- Returns a random Vec2 location within the zone.
-- @param #ZONE_RADIUS self
-- @param #number inner (Optional) Minimal distance from the center of the zone. Default is 0.
@@ -1520,6 +1569,10 @@ function ZONE_RADIUS:GetRandomVec2(inner, outer, surfacetypes)
local Vec2 = self:GetVec2()
local _inner = inner or 0
local _outer = outer or self:GetRadius()
math.random()
math.random()
math.random()
if surfacetypes and type(surfacetypes)~="table" then
surfacetypes={surfacetypes}
@@ -1561,15 +1614,15 @@ function ZONE_RADIUS:GetRandomVec2(inner, outer, surfacetypes)
return point
end
--- Returns a @{Core.Point#POINT_VEC2} object reflecting a random 2D location within the zone. Note that this is actually a @{Core.Point#COORDINATE} type object, and not a simple Vec2 table.
--- Returns a @{Core.Point#COORDINATE} object reflecting a random 2D location within the zone. Note that this is actually a @{Core.Point#COORDINATE} type object, and not a simple Vec2 table.
-- @param #ZONE_RADIUS self
-- @param #number inner (optional) Minimal distance from the center of the zone. Default is 0.
-- @param #number outer (optional) Maximal distance from the outer edge of the zone. Default is the radius of the zone.
-- @return Core.Point#POINT_VEC2 The @{Core.Point#POINT_VEC2} object reflecting the random 3D location within the zone.
-- @return Core.Point#COORDINATE The @{Core.Point#COORDINATE} object reflecting the random 3D location within the zone.
function ZONE_RADIUS:GetRandomPointVec2( inner, outer )
--self:F( self.ZoneName, inner, outer )
local PointVec2 = POINT_VEC2:NewFromVec2( self:GetRandomVec2( inner, outer ) )
local PointVec2 = COORDINATE:NewFromVec2( self:GetRandomVec2( inner, outer ) )
--self:T3( { PointVec2 } )
@@ -1592,15 +1645,15 @@ function ZONE_RADIUS:GetRandomVec3( inner, outer )
end
--- Returns a @{Core.Point#POINT_VEC3} object reflecting a random 3D location within the zone. Note that this is actually a @{Core.Point#COORDINATE} type object, and not a simple Vec3 table.
--- Returns a @{Core.Point#COORDINATE} object reflecting a random 3D location within the zone. Note that this is actually a @{Core.Point#COORDINATE} type object, and not a simple Vec3 table.
-- @param #ZONE_RADIUS self
-- @param #number inner (optional) Minimal distance from the center of the zone. Default is 0.
-- @param #number outer (optional) Maximal distance from the outer edge of the zone. Default is the radius of the zone.
-- @return Core.Point#POINT_VEC3 The @{Core.Point#POINT_VEC3} object reflecting the random 3D location within the zone.
-- @return Core.Point#COORDINATE The @{Core.Point#COORDINATE} object reflecting the random 3D location within the zone.
function ZONE_RADIUS:GetRandomPointVec3( inner, outer )
--self:F( self.ZoneName, inner, outer )
local PointVec3 = POINT_VEC3:NewFromVec2( self:GetRandomVec2( inner, outer ) )
local PointVec3 = COORDINATE:NewFromVec2( self:GetRandomVec2( inner, outer ) )
--self:T3( { PointVec3 } )
@@ -1881,6 +1934,21 @@ function ZONE_UNIT:New( ZoneName, ZoneUNIT, Radius, Offset)
return self
end
--- Updates the current location from a @{Wrapper.Group}.
-- @param #ZONE_UNIT self
-- @param Wrapper.Group#GROUP Group (optional) Update from this Unit, if nil, update from the UNIT this zone is based on.
-- @return self
function ZONE_UNIT:UpdateFromUnit(Unit)
if Unit and Unit:IsAlive() then
local vec2 = Unit:GetVec2()
self.LastVec2 = vec2
elseif self.ZoneUNIT and self.ZoneUNIT:IsAlive() then
local ZoneVec2 = self.ZoneUNIT:GetVec2()
self.LastVec2 = ZoneVec2
end
return self
end
--- Returns the current location of the @{Wrapper.Unit#UNIT}.
-- @param #ZONE_UNIT self
@@ -2018,6 +2086,22 @@ function ZONE_GROUP:GetVec2()
return ZoneVec2
end
--- Updates the current location from a @{Wrapper.Group}.
-- @param #ZONE_GROUP self
-- @param Wrapper.Group#GROUP Group (optional) Update from this Group, if nil, update from the GROUP this zone is based on.
-- @return self
function ZONE_GROUP:UpdateFromGroup(Group)
if Group and Group:IsAlive() then
local vec2 = Group:GetVec2()
self.Vec2 = vec2
elseif self._.ZoneGROUP and self._.ZoneGROUP:IsAlive() then
local ZoneVec2 = self._.ZoneGROUP:GetVec2()
self.Vec2 = ZoneVec2
self._.ZoneVec2Cache = ZoneVec2
end
return self
end
--- Returns a random location within the zone of the @{Wrapper.Group}.
-- @param #ZONE_GROUP self
-- @return DCS#Vec2 The random location of the zone based on the @{Wrapper.Group} location.
@@ -2036,15 +2120,15 @@ function ZONE_GROUP:GetRandomVec2()
return Point
end
--- Returns a @{Core.Point#POINT_VEC2} object reflecting a random 2D location within the zone. Note that this is actually a @{Core.Point#COORDINATE} type object, and not a simple Vec2 table.
--- Returns a @{Core.Point#COORDINATE} object reflecting a random 2D location within the zone. Note that this is actually a @{Core.Point#COORDINATE} type object, and not a simple Vec2 table.
-- @param #ZONE_GROUP self
-- @param #number inner (optional) Minimal distance from the center of the zone. Default is 0.
-- @param #number outer (optional) Maximal distance from the outer edge of the zone. Default is the radius of the zone.
-- @return Core.Point#POINT_VEC2 The @{Core.Point#POINT_VEC2} object reflecting the random 3D location within the zone.
-- @return Core.Point#COORDINATE The @{Core.Point#COORDINATE} object reflecting the random 3D location within the zone.
function ZONE_GROUP:GetRandomPointVec2( inner, outer )
--self:F( self.ZoneName, inner, outer )
local PointVec2 = POINT_VEC2:NewFromVec2( self:GetRandomVec2() )
local PointVec2 = COORDINATE:NewFromVec2( self:GetRandomVec2() )
--self:T3( { PointVec2 } )
@@ -2192,8 +2276,8 @@ end
-- Various functions exist to find random points within the zone.
--
-- * @{#ZONE_POLYGON_BASE.GetRandomVec2}(): Gets a random 2D point in the zone.
-- * @{#ZONE_POLYGON_BASE.GetRandomPointVec2}(): Return a @{Core.Point#POINT_VEC2} object representing a random 2D point within the zone.
-- * @{#ZONE_POLYGON_BASE.GetRandomPointVec3}(): Return a @{Core.Point#POINT_VEC3} object representing a random 3D point at landheight within the zone.
-- * @{#ZONE_POLYGON_BASE.GetRandomPointVec2}(): Return a @{Core.Point#COORDINATE} object representing a random 2D point within the zone.
-- * @{#ZONE_POLYGON_BASE.GetRandomPointVec3}(): Return a @{Core.Point#COORDINATE} object representing a random 3D point at landheight within the zone.
--
-- ## Draw zone
--
@@ -2487,6 +2571,26 @@ function ZONE_POLYGON_BASE:Flush()
return self
end
--- Search for clear ground spawn zones within this zone. A powerful and efficient function using Disposition to find clear areas for spawning ground units avoiding trees, water and map scenery.
-- @param #ZONE_POLYGON_BASE self
-- @param #number PosRadius Required clear radius around each position.
-- @param #number NumPositions Number of positions to find.
-- @return #table A table of DCS#Vec2 positions that are clear of map objects within the given PosRadius. nil if no clear positions are found.
function ZONE_POLYGON_BASE:GetClearZonePositions(PosRadius, NumPositions)
return UTILS.GetClearZonePositions(self, PosRadius, NumPositions)
end
--- Search for a random clear ground spawn coordinate within this zone. A powerful and efficient function using Disposition to find clear areas for spawning ground units avoiding trees, water and map scenery.
-- @param #ZONE_POLYGON_BASE self
-- @param #number PosRadius (Optional) Required clear radius around each position. (Default is math.min(Radius/10, 200))
-- @param #number NumPositions (Optional) Number of positions to find. (Default 50)
-- @return Core.Point#COORDINATE A random coordinate for a clear zone. nil if no clear positions are found.
-- @return #number Assigned radius for the found zones. nil if no clear positions are found.
function ZONE_POLYGON_BASE:GetRandomClearZoneCoordinate(PosRadius, NumPositions)
return UTILS.GetRandomClearZoneCoordinate(self, PosRadius, NumPositions)
end
--- Smokes the zone boundaries in a color.
-- @param #ZONE_POLYGON_BASE self
-- @param #boolean UnBound If true, the tyres will be destroyed.
@@ -2769,7 +2873,7 @@ function ZONE_POLYGON_BASE:SmokeZone( SmokeColor, Segments )
for Segment = 0, Segments do -- We divide each line in 5 segments and smoke a point on the line.
local PointX = self._.Polygon[i].x + ( Segment * DeltaX / Segments )
local PointY = self._.Polygon[i].y + ( Segment * DeltaY / Segments )
POINT_VEC2:New( PointX, PointY ):Smoke( SmokeColor )
COORDINATE:New( PointX, 0, PointY ):Smoke( SmokeColor )
end
j = i
i = i + 1
@@ -2804,7 +2908,7 @@ function ZONE_POLYGON_BASE:FlareZone( FlareColor, Segments, Azimuth, AddHeight )
for Segment = 0, Segments do -- We divide each line in 5 segments and smoke a point on the line.
local PointX = self._.Polygon[i].x + ( Segment * DeltaX / Segments )
local PointY = self._.Polygon[i].y + ( Segment * DeltaY / Segments )
POINT_VEC2:New( PointX, PointY, AddHeight ):Flare(FlareColor, Azimuth)
COORDINATE:New( PointX, AddHeight, PointY ):Flare(FlareColor, Azimuth)
end
j = i
i = i + 1
@@ -2865,6 +2969,11 @@ end
function ZONE_POLYGON_BASE:GetRandomVec2()
-- make sure we assign weights to the triangles based on their surface area, otherwise
-- we'll be more likely to generate random points in smaller triangles
math.random()
math.random()
math.random()
local weights = {}
for _, triangle in pairs(self._Triangles) do
weights[triangle] = triangle.SurfaceArea / self.SurfaceArea
@@ -2880,26 +2989,26 @@ function ZONE_POLYGON_BASE:GetRandomVec2()
end
end
--- Return a @{Core.Point#POINT_VEC2} object representing a random 2D point at landheight within the zone. Note that this is actually a @{Core.Point#COORDINATE} type object, and not a simple Vec2 table.
--- Return a @{Core.Point#COORDINATE} object representing a random 2D point at landheight within the zone. Note that this is actually a @{Core.Point#COORDINATE} type object, and not a simple Vec2 table.
-- @param #ZONE_POLYGON_BASE self
-- @return @{Core.Point#POINT_VEC2}
-- @return @{Core.Point#COORDINATE}
function ZONE_POLYGON_BASE:GetRandomPointVec2()
--self:F2()
local PointVec2 = POINT_VEC2:NewFromVec2( self:GetRandomVec2() )
local PointVec2 = COORDINATE:NewFromVec2( self:GetRandomVec2() )
--self:T2( PointVec2 )
return PointVec2
end
--- Return a @{Core.Point#POINT_VEC3} object representing a random 3D point at landheight within the zone. Note that this is actually a @{Core.Point#COORDINATE} type object, and not a simple Vec3 table.
--- Return a @{Core.Point#COORDINATE} object representing a random 3D point at landheight within the zone. Note that this is actually a @{Core.Point#COORDINATE} type object, and not a simple Vec3 table.
-- @param #ZONE_POLYGON_BASE self
-- @return @{Core.Point#POINT_VEC3}
-- @return @{Core.Point#COORDINATE}
function ZONE_POLYGON_BASE:GetRandomPointVec3()
--self:F2()
local PointVec3 = POINT_VEC3:NewFromVec2( self:GetRandomVec2() )
local PointVec3 = COORDINATE:NewFromVec2( self:GetRandomVec2() )
--self:T2( PointVec3 )
@@ -3204,12 +3313,7 @@ function ZONE_POLYGON:Scan( ObjectCategories, UnitCategories )
local vectors = self:GetBoundingSquare()
local minVec3 = {x=vectors.x1, y=0, z=vectors.y1}
local maxVec3 = {x=vectors.x2, y=0, z=vectors.y2}
local minmarkcoord = COORDINATE:NewFromVec3(minVec3)
local maxmarkcoord = COORDINATE:NewFromVec3(maxVec3)
local ZoneRadius = minmarkcoord:Get2DDistance(maxmarkcoord)/2
local ZoneRadius = UTILS.VecDist2D({x=vectors.x1, y=vectors.y1}, {x=vectors.x2, y=vectors.y2})/2
-- self:I("Scan Radius:" ..ZoneRadius)
local CenterVec3 = self:GetCoordinate():GetVec3()
@@ -3233,14 +3337,12 @@ function ZONE_POLYGON:Scan( ObjectCategories, UnitCategories )
local function EvaluateZone( ZoneObject )
if ZoneObject then
if ZoneObject and self:IsVec3InZone(ZoneObject:getPoint()) then
local ObjectCategory = Object.getCategory(ZoneObject)
if ( ObjectCategory == Object.Category.UNIT and ZoneObject:isExist() and ZoneObject:isActive() ) or (ObjectCategory == Object.Category.STATIC and ZoneObject:isExist()) then
local CoalitionDCSUnit = ZoneObject:getCoalition()
local Include = false
if not UnitCategories then
-- Anything found is included.
@@ -3272,7 +3374,7 @@ function ZONE_POLYGON:Scan( ObjectCategories, UnitCategories )
end
-- trying with box search
if ObjectCategory == Object.Category.SCENERY and self:IsVec3InZone(ZoneObject:getPoint()) then
if ObjectCategory == Object.Category.SCENERY then
local SceneryType = ZoneObject:getTypeName()
local SceneryName = ZoneObject:getName()
self.ScanData.Scenery[SceneryType] = self.ScanData.Scenery[SceneryType] or {}
@@ -3931,18 +4033,18 @@ function ZONE_OVAL:GetRandomVec2()
return {x=rx, y=ry}
end
--- Define a random @{Core.Point#POINT_VEC2} within the zone. Note that this is actually a @{Core.Point#COORDINATE} type object, and not a simple Vec2 table.
--- Define a random @{Core.Point#COORDINATE} within the zone. Note that this is actually a @{Core.Point#COORDINATE} type object, and not a simple Vec2 table.
-- @param #ZONE_OVAL self
-- @return Core.Point#POINT_VEC2 The PointVec2 coordinates.
-- @return Core.Point#COORDINATE The COORDINATE coordinates.
function ZONE_OVAL:GetRandomPointVec2()
return POINT_VEC2:NewFromVec2(self:GetRandomVec2())
return COORDINATE:NewFromVec2(self:GetRandomVec2())
end
--- Define a random @{Core.Point#POINT_VEC2} within the zone. Note that this is actually a @{Core.Point#COORDINATE} type object, and not a simple Vec3 table.
--- Define a random @{Core.Point#COORDINATE} within the zone. Note that this is actually a @{Core.Point#COORDINATE} type object, and not a simple Vec3 table.
-- @param #ZONE_OVAL self
-- @return Core.Point#POINT_VEC2 The PointVec2 coordinates.
-- @return Core.Point#COORDINATE The COORDINATE coordinates.
function ZONE_OVAL:GetRandomPointVec3()
return POINT_VEC3:NewFromVec3(self:GetRandomVec2())
return COORDINATE:NewFromVec3(self:GetRandomVec2())
end
--- Draw the zone on the F10 map.
@@ -4082,15 +4184,15 @@ do -- ZONE_AIRBASE
return ZoneVec2
end
--- Returns a @{Core.Point#POINT_VEC2} object reflecting a random 2D location within the zone. Note that this is actually a @{Core.Point#COORDINATE} type object, and not a simple Vec2 table.
--- Returns a @{Core.Point#COORDINATE} object reflecting a random 2D location within the zone. Note that this is actually a @{Core.Point#COORDINATE} type object, and not a simple Vec2 table.
-- @param #ZONE_AIRBASE self
-- @param #number inner (optional) Minimal distance from the center of the zone. Default is 0.
-- @param #number outer (optional) Maximal distance from the outer edge of the zone. Default is the radius of the zone.
-- @return Core.Point#POINT_VEC2 The @{Core.Point#POINT_VEC2} object reflecting the random 3D location within the zone.
-- @return Core.Point#COORDINATE The @{Core.Point#COORDINATE} object reflecting the random 3D location within the zone.
function ZONE_AIRBASE:GetRandomPointVec2( inner, outer )
--self:F( self.ZoneName, inner, outer )
local PointVec2 = POINT_VEC2:NewFromVec2( self:GetRandomVec2() )
local PointVec2 = COORDINATE:NewFromVec2( self:GetRandomVec2() )
--self:T3( { PointVec2 } )
@@ -2,7 +2,8 @@
-- @module Core.Zone_Detection
-- @image MOOSE.JPG
--- @type ZONE_DETECTION
---
-- @type ZONE_DETECTION
-- @field DCS#Vec2 Vec2 The current location of the zone.
-- @field DCS#Distance Radius The radius of the zone.
-- @extends #ZONE_BASE
@@ -106,7 +107,7 @@ function ZONE_DETECTION:SmokeZone( SmokeColor, Points, AddHeight, AngleOffset )
local Radial = ( Angle + AngleOffset ) * RadialBase / 360
Point.x = Vec2.x + math.cos( Radial ) * self:GetRadius()
Point.y = Vec2.y + math.sin( Radial ) * self:GetRadius()
POINT_VEC2:New( Point.x, Point.y, AddHeight ):Smoke( SmokeColor )
COORDINATE:New( Point.x, AddHeight, Point.y):Smoke( SmokeColor )
end
return self
@@ -137,7 +138,7 @@ function ZONE_DETECTION:FlareZone( FlareColor, Points, Azimuth, AddHeight )
local Radial = Angle * RadialBase / 360
Point.x = Vec2.x + math.cos( Radial ) * self:GetRadius()
Point.y = Vec2.y + math.sin( Radial ) * self:GetRadius()
POINT_VEC2:New( Point.x, Point.y, AddHeight ):Flare( FlareColor, Azimuth )
COORDINATE:New( Point.x, AddHeight, Point.y ):Flare( FlareColor, Azimuth )
end
return self
@@ -201,4 +202,3 @@ function ZONE_DETECTION:IsVec3InZone( Vec3 )
return InZone
end
+1 -1
View File
@@ -198,7 +198,7 @@ end -- env
do -- radio
---@type radio
--@type radio
-- @field #radio.modulation modulation
---
@@ -141,7 +141,6 @@ FOX = {
explosiondist = 200,
explosiondist2 = 500,
bigmissilemass = 50,
destroy = nil,
dt50 = 5,
dt10 = 1,
dt05 = 0.5,
+141 -102
View File
@@ -22,7 +22,7 @@
-- @module Functional.Mantis
-- @image Functional.Mantis.jpg
--
-- Last Update: Mar 2025
-- Last Update: August 2025
-------------------------------------------------------------------------
--- **MANTIS** class, extends Core.Base#BASE
@@ -62,7 +62,9 @@
-- @field #table FilterZones Table of Core.Zone#ZONE Zones Consider SAM groups in this zone(s) only for this MANTIS instance, must be handed as #table of Zone objects.
-- @field #boolean SmokeDecoy If true, smoke short range SAM units as decoy if a plane is in firing range.
-- @field #number SmokeDecoyColor Color to use, defaults to SMOKECOLOR.White
-- @field #number checkcounter Counter for SAM Table refreshes
-- @field #number checkcounter Counter for SAM Table refreshes.
-- @field #number DLinkCacheTime Seconds after which cached contacts in DLink will decay.
-- @field #boolean logsamstatus Log SAM status in dcs.log every cycle if true
-- @extends Core.Base#BASE
@@ -74,10 +76,9 @@
--
-- * Moose derived Modular, Automatic and Network capable Targeting and Interception System.
-- * Controls a network of SAM sites. Uses detection to switch on the SAM site closest to the enemy.
-- * **Automatic mode** (default since 0.8) will set-up your SAM site network automatically for you
-- * **Classic mode** behaves like before
-- * Leverage evasiveness from SEAD, leverage attack range setting
-- * Automatic setup of SHORAD based on groups of the class "short-range"
-- * **Automatic mode** (default) will set-up your SAM site network automatically for you.
-- * Leverage evasiveness from SEAD, leverage attack range setting.
-- * Automatic setup of SHORAD based on groups of the class "short-range".
--
-- # 0. Base considerations and naming conventions
--
@@ -107,10 +108,15 @@
-- * Patriot
-- * Rapier
-- * Roland
-- * IRIS-T SLM
-- * Pantsir S1
-- * TOR M2
-- * C-RAM
-- * Silkworm (though strictly speaking this is a surface to ship missile)
-- * SA-2, SA-3, SA-5, SA-6, SA-7, SA-8, SA-9, SA-10, SA-11, SA-13, SA-15, SA-19
-- * From IDF mod: STUNNER IDFA, TAMIR IDFA (Note all caps!)
-- * From HDS (see note on HDS below): SA-2, SA-3, SA-10B, SA-10C, SA-12, SA-17, SA-20A, SA-20B, SA-23, HQ-2
-- * From HDS (see note on HDS below): SA-2, SA-3, SA-10B, SA-10C, SA-12, SA-17, SA-20A, SA-20B, SA-23, HQ-2, SAMP/T Block 1, SAMP/T Block 1INT, SAMP/T Block2
-- * Other Mods: Nike
--
-- * From SMA: RBS98M, RBS70, RBS90, RBS90M, RBS103A, RBS103B, RBS103AM, RBS103BM, Lvkv9040M
-- **NOTE** If you are using the Swedish Military Assets (SMA), please note that the **group name** for RBS-SAM types also needs to contain the keyword "SMA"
@@ -124,19 +130,20 @@
-- * SA-2 (with V759 missile, e.g. "Red SAM SA-2 HDS")
-- * SA-2 (with HQ-2 launcher, use HQ-2 in the group name, e.g. "Red SAM HQ-2" )
-- * SA-3 (with V601P missile, e.g. "Red SAM SA-3 HDS")
-- * SA-10B (overlap with other SA-10 types, e.g. "Red SAM SA-10B HDS")
-- * SA-10C (overlap with other SA-10 types, e.g. "Red SAM SA-10C HDS")
-- * SA-12 (launcher dependent range, e.g. "Red SAM SA-12 HDS")
-- * SA-23 (launcher dependent range, e.g. "Red SAM SA-23 HDS")
-- * SA-10B (overlap with other SA-10 types, e.g. "Red SAM SA-10B HDS" with 5P85CE launcher)
-- * SA-10C (overlap with other SA-10 types, e.g. "Red SAM SA-10C HDS" with 5P85SE launcher)
-- * SA-12 (launcher dependent range, e.g. "Red SAM SA-12 HDS 2" for the 9A82 variant and "Red SAM SA-12 HDS 1" for the 9A83 variant)
-- * SA-23 (launcher dependent range, e.g. "Red SAM SA-23 HDS 2" for the 9A82ME variant and "Red SAM SA-23 HDS 1" for the 9A83ME variant)
-- * SAMP/T (launcher dependent range, e.g. "Blue SAM SAMPT Block 1 HDS" for Block 1, "Blue SAM SAMPT Block 1INT HDS", "Blue SAM SAMPT Block 2 HDS")
--
-- The other HDS types work like the rest of the known SAM systems.
--
-- # 0.1 Set-up in the mission editor
--
-- Set up your SAM sites in the mission editor. Name the groups using a systematic approach like above.
-- Set up your EWR system in the mission editor. Name the groups using a systematic approach like above. Can be e.g. AWACS or a combination of AWACS and Search Radars like e.g. EWR 1L13 etc.
-- Set up your SAM sites in the mission editor. Name the groups using a systematic approach like above.Can be e.g. AWACS or a combination of AWACS and Search Radars like e.g. EWR 1L13 etc.
-- Search Radars usually have "SR" or "STR" in their names. Use the encyclopedia in the mission editor to inform yourself.
-- Set up your SHORAD systems. They need to be **close** to (i.e. around) the SAM sites to be effective. Use **one** group per SAM location. SA-15 TOR systems offer a good missile defense.
-- Set up your SHORAD systems. They need to be **close** to (i.e. around) the SAM sites to be effective. Use **one unit ** per group (multiple groups) for the SAM location.
-- Else, evasive manoevers might club up all defenders in one place. Red SA-15 TOR systems offer a good missile defense.
--
-- [optional] Set up your HQ. Can be any group, e.g. a command vehicle.
--
@@ -188,7 +195,7 @@
--
-- ## 2.1 Auto mode features
--
-- ### 2.1.1 You can now add Accept-, Reject- and Conflict-Zones to your setup, e.g. to consider borders or de-militarized zones:
-- ### 2.1.1 You can add Accept-, Reject- and Conflict-Zones to your setup, e.g. to consider borders or de-militarized zones:
--
-- -- Parameters are tables of Core.Zone#ZONE objects!
-- -- This is effectively a 3-stage filter allowing for zone overlap. A coordinate is accepted first when
@@ -205,9 +212,6 @@
-- ### 2.1.3 SHORAD/Point defense will automatically be added from SAM sites of type "point" or if the range is less than 5km or if the type is AAA.
--
-- ### 2.1.4 Advanced features
--
-- -- Option to switch off auto mode **before** you start MANTIS (not recommended)
-- mybluemantis.automode = false
--
-- -- Option to set the scale of the activation range, i.e. don't activate at the fringes of max range, defaults below.
-- -- also see engagerange below.
@@ -220,6 +224,12 @@
--
-- -- For some scenarios, like Cold War, it might be useful not to activate SAMs if friendly aircraft are around to avoid death by friendly fire.
-- mybluemantis.checkforfriendlies = true
--
-- ### 2.1.6 Shoot & Scoot
--
-- -- Option to make the (driveable) SHORAD units drive around and shuffle positions
-- -- We use a SET_ZONE for that, number of zones to consider defaults to three, Random is true for random coordinates and Formation is e.g. "Vee".
-- mybluemantis:AddScootZones(ZoneSet, Number, Random, Formation)
--
-- # 3. Default settings [both modes unless stated otherwise]
--
@@ -242,26 +252,8 @@
-- E.g. mymantis:SetAdvancedMode( true, 90 )
--
-- Use this option if you want to make use of or allow advanced SEAD tactics.
--
-- # 5. Integrate SHORAD [classic mode, not necessary in automode, not recommended for manual setup]
--
-- You can also choose to integrate Mantis with @{Functional.Shorad#SHORAD} for protection against HARMs and AGMs manually. When SHORAD detects a missile fired at one of MANTIS' SAM sites, it will activate SHORAD systems in
-- the given defense checkradius around that SAM site. Create a SHORAD object first, then integrate with MANTIS like so:
--
-- local SamSet = SET_GROUP:New():FilterPrefixes("Blue SAM"):FilterCoalitions("blue"):FilterStart()
-- myshorad = SHORAD:New("BlueShorad", "Blue SHORAD", SamSet, 22000, 600, "blue")
-- -- now set up MANTIS
-- mymantis = MANTIS:New("BlueMantis","Blue SAM","Blue EWR",nil,"blue",false,"Blue Awacs")
-- mymantis:AddShorad(myshorad,720)
-- mymantis:Start()
--
-- If you systematically name your SHORAD groups starting with "Blue SHORAD" you'll need exactly **one** SHORAD instance to manage all SHORAD groups.
--
-- (Optionally) you can remove the link later on with
--
-- mymantis:RemoveShorad()
--
-- # 6. Integrated SEAD
-- # 5. Integrated SEAD
--
-- MANTIS is using @{Functional.Sead#SEAD} internally to both detect and evade HARM attacks. No extra efforts needed to set this up!
-- Once a HARM attack is detected, MANTIS (via SEAD) will shut down the radars of the attacked SAM site and take evasive action by moving the SAM
@@ -288,6 +280,7 @@
MANTIS = {
ClassName = "MANTIS",
name = "mymantis",
version = "0.9.34",
SAM_Templates_Prefix = "",
SAM_Group = nil,
EWR_Templates_Prefix = "",
@@ -336,6 +329,8 @@ MANTIS = {
SmokeDecoy = false,
SmokeDecoyColor = SMOKECOLOR.White,
checkcounter = 1,
DLinkCacheTime = 120,
logsamstatus = false,
}
--- Advanced state enumerator
@@ -374,7 +369,7 @@ MANTIS.radiusscale[MANTIS.SamType.POINT] = 3
MANTIS.SamData = {
["Hawk"] = { Range=35, Blindspot=0, Height=12, Type="Medium", Radar="Hawk" }, -- measures in km
["NASAMS"] = { Range=14, Blindspot=0, Height=7, Type="Short", Radar="NSAMS" }, -- AIM 120B
["Patriot"] = { Range=99, Blindspot=0, Height=25, Type="Long", Radar="Patriot" },
["Patriot"] = { Range=99, Blindspot=0, Height=25, Type="Long", Radar="Patriot str" },
["Rapier"] = { Range=10, Blindspot=0, Height=3, Type="Short", Radar="rapier" },
["SA-2"] = { Range=40, Blindspot=7, Height=25, Type="Medium", Radar="S_75M_Volhov" },
["SA-3"] = { Range=18, Blindspot=6, Height=18, Type="Short", Radar="5p73 s-125 ln" },
@@ -382,7 +377,8 @@ MANTIS.SamData = {
["SA-6"] = { Range=25, Blindspot=0, Height=8, Type="Medium", Radar="1S91" },
["SA-10"] = { Range=119, Blindspot=0, Height=18, Type="Long" , Radar="S-300PS 4"},
["SA-11"] = { Range=35, Blindspot=0, Height=20, Type="Medium", Radar="SA-11" },
["Roland"] = { Range=5, Blindspot=0, Height=5, Type="Point", Radar="Roland" },
["Roland"] = { Range=6, Blindspot=0, Height=5, Type="Short", Radar="Roland" },
["Gepard"] = { Range=5, Blindspot=0, Height=4, Type="Point", Radar="Gepard" },
["HQ-7"] = { Range=12, Blindspot=0, Height=3, Type="Short", Radar="HQ-7" },
["SA-9"] = { Range=4, Blindspot=0, Height=3, Type="Point", Radar="Strela", Point="true" },
["SA-8"] = { Range=10, Blindspot=0, Height=5, Type="Short", Radar="Osa 9A33" },
@@ -393,14 +389,21 @@ MANTIS.SamData = {
["Chaparral"] = { Range=8, Blindspot=0, Height=3, Type="Short", Radar="Chaparral" },
["Linebacker"] = { Range=4, Blindspot=0, Height=3, Type="Point", Radar="Linebacker", Point="true" },
["Silkworm"] = { Range=90, Blindspot=1, Height=0.2, Type="Long", Radar="Silkworm" },
["C-RAM"] = { Range=2, Blindspot=0, Height=2, Type="Point", Radar="HEMTT_C-RAM_Phalanx", Point="true" },
-- units from HDS Mod, multi launcher options is tricky
["SA-10B"] = { Range=75, Blindspot=0, Height=18, Type="Medium" , Radar="SA-10B"},
["SA-17"] = { Range=50, Blindspot=3, Height=30, Type="Medium", Radar="SA-17" },
["SA-17"] = { Range=50, Blindspot=3, Height=50, Type="Medium", Radar="SA-17" },
["SA-20A"] = { Range=150, Blindspot=5, Height=27, Type="Long" , Radar="S-300PMU1"},
["SA-20B"] = { Range=200, Blindspot=4, Height=27, Type="Long" , Radar="S-300PMU2"},
["HQ-2"] = { Range=50, Blindspot=6, Height=35, Type="Medium", Radar="HQ_2_Guideline_LN" },
["TAMIR IDFA"] = { Range=20, Blindspot=0.6, Height=12.3, Type="Short", Radar="IRON_DOME_LN" },
["STUNNER IDFA"] = { Range=250, Blindspot=1, Height=45, Type="Long", Radar="DAVID_SLING_LN" },
["STUNNER IDFA"] = { Range=250, Blindspot=1, Height=45, Type="Long", Radar="DAVID_SLING_LN" },
["NIKE"] = { Range=155, Blindspot=6, Height=30, Type="Long", Radar="HIPAR" },
["Dog Ear"] = { Range=11, Blindspot=0, Height=9, Type="Point", Radar="Dog Ear", Point="true" },
-- CH Added to DCS core 2.9.19.x
["Pantsir S1"] = { Range=20, Blindspot=1.2, Height=15, Type="Point", Radar="PantsirS1" , Point="true" },
["Tor M2"] = { Range=12, Blindspot=1, Height=10, Type="Point", Radar="TorM2", Point="true" },
["IRIS-T SLM"] = { Range=40, Blindspot=0.5, Height=20, Type="Medium", Radar="CH_IRIST_SLM" },
}
--- SAM data HDS
@@ -416,13 +419,17 @@ MANTIS.SamDataHDS = {
-- group name MUST contain HDS to ID launcher type correctly!
["SA-2 HDS"] = { Range=56, Blindspot=7, Height=30, Type="Medium", Radar="V759" },
["SA-3 HDS"] = { Range=20, Blindspot=6, Height=30, Type="Short", Radar="V-601P" },
["SA-10C HDS 2"] = { Range=90, Blindspot=5, Height=25, Type="Long" , Radar="5P85DE ln"}, -- V55RUD
["SA-10C HDS 1"] = { Range=90, Blindspot=5, Height=25, Type="Long" , Radar="5P85CE ln"}, -- V55RUD
["SA-12 HDS 2"] = { Range=100, Blindspot=10, Height=25, Type="Long" , Radar="S-300V 9A82 l"},
["SA-12 HDS 1"] = { Range=75, Blindspot=1, Height=25, Type="Long" , Radar="S-300V 9A83 l"},
["SA-10B HDS"] = { Range=90, Blindspot=5, Height=25, Type="Long" , Radar="5P85CE ln"}, -- V55RUD
["SA-10C HDS"] = { Range=75, Blindspot=5, Height=25, Type="Long" , Radar="5P85SE ln"}, -- V55RUD
["SA-17 HDS"] = { Range=50, Blindspot=3, Height=50, Type="Medium", Radar="SA-17 " },
["SA-12 HDS 2"] = { Range=100, Blindspot=13, Height=30, Type="Long" , Radar="S-300V 9A82 l"},
["SA-12 HDS 1"] = { Range=75, Blindspot=6, Height=25, Type="Long" , Radar="S-300V 9A83 l"},
["SA-23 HDS 2"] = { Range=200, Blindspot=5, Height=37, Type="Long", Radar="S-300VM 9A82ME" },
["SA-23 HDS 1"] = { Range=100, Blindspot=1, Height=50, Type="Long", Radar="S-300VM 9A83ME" },
["HQ-2 HDS"] = { Range=50, Blindspot=6, Height=35, Type="Medium", Radar="HQ_2_Guideline_LN" },
["SAMPT Block 1 HDS"] = { Range=120, Blindspot=1, Height=20, Type="long", Radar="SAMPT_MLT_Blk1" }, -- Block 1 Launcher
["SAMPT Block 1INT HDS"] = { Range=150, Blindspot=1, Height=25, Type="long", Radar="SAMPT_MLT_Blk1NT" }, -- Block 1-INT Launcher
["SAMPT Block 2 HDS"] = { Range=200, Blindspot=10, Height=70, Type="long", Radar="SAMPT_MLT_Blk2" }, -- Block 2 Launcher
}
--- SAM data SMA
@@ -437,16 +444,16 @@ MANTIS.SamDataSMA = {
-- units from SMA Mod (Sweedish Military Assets)
-- https://forum.dcs.world/topic/295202-swedish-military-assets-for-dcs-by-currenthill/
-- group name MUST contain SMA to ID launcher type correctly!
["RBS98M SMA"] = { Range=20, Blindspot=0, Height=8, Type="Short", Radar="RBS-98" },
["RBS70 SMA"] = { Range=8, Blindspot=0, Height=5.5, Type="Short", Radar="RBS-70" },
["RBS70M SMA"] = { Range=8, Blindspot=0, Height=5.5, Type="Short", Radar="BV410_RBS70" },
["RBS90 SMA"] = { Range=8, Blindspot=0, Height=5.5, Type="Short", Radar="RBS-90" },
["RBS90M SMA"] = { Range=8, Blindspot=0, Height=5.5, Type="Short", Radar="BV410_RBS90" },
["RBS103A SMA"] = { Range=150, Blindspot=3, Height=24.5, Type="Long", Radar="LvS-103_Lavett103_Rb103A" },
["RBS103B SMA"] = { Range=35, Blindspot=0, Height=36, Type="Medium", Radar="LvS-103_Lavett103_Rb103B" },
["RBS103AM SMA"] = { Range=150, Blindspot=3, Height=24.5, Type="Long", Radar="LvS-103_Lavett103_HX_Rb103A" },
["RBS103BM SMA"] = { Range=35, Blindspot=0, Height=36, Type="Medium", Radar="LvS-103_Lavett103_HX_Rb103B" },
["Lvkv9040M SMA"] = { Range=4, Blindspot=0, Height=2.5, Type="Point", Radar="LvKv9040",Point="true" },
["RBS98M SMA"] = { Range=20, Blindspot=0.2, Height=8, Type="Short", Radar="RBS-98" },
["RBS70 SMA"] = { Range=8, Blindspot=0.25, Height=6, Type="Short", Radar="RBS-70" },
["RBS70M SMA"] = { Range=8, Blindspot=0.25, Height=6, Type="Short", Radar="BV410_RBS70" },
["RBS90 SMA"] = { Range=8, Blindspot=0.25, Height=6, Type="Short", Radar="RBS-90" },
["RBS90M SMA"] = { Range=8, Blindspot=0.25, Height=6, Type="Short", Radar="BV410_RBS90" },
["RBS103A SMA"] = { Range=160, Blindspot=1, Height=36, Type="Long", Radar="LvS-103_Lavett103_Rb103A" },
["RBS103B SMA"] = { Range=120, Blindspot=3, Height=24.5, Type="Long", Radar="LvS-103_Lavett103_Rb103B" },
["RBS103AM SMA"] = { Range=160, Blindspot=1, Height=36, Type="Long", Radar="LvS-103_Lavett103_HX_Rb103A" },
["RBS103BM SMA"] = { Range=120, Blindspot=3, Height=24.5, Type="Long", Radar="LvS-103_Lavett103_HX_Rb103B" },
["Lvkv9040M SMA"] = { Range=2, Blindspot=0.1, Height=1.2, Type="Point", Radar="LvKv9040",Point="true" },
}
--- SAM data CH
@@ -461,47 +468,49 @@ MANTIS.SamDataCH = {
-- units from CH (Military Assets by Currenthill)
-- https://www.currenthill.com/
-- group name MUST contain CHM to ID launcher type correctly!
["2S38 CHM"] = { Range=8, Blindspot=0.5, Height=6, Type="Short", Radar="2S38" },
["PantsirS1 CHM"] = { Range=20, Blindspot=1.2, Height=15, Type="Short", Radar="PantsirS1" },
["2S38 CHM"] = { Range=6, Blindspot=0.1, Height=4.5, Type="Short", Radar="2S38" },
["PantsirS1 CHM"] = { Range=20, Blindspot=1.2, Height=15, Type="Point", Radar="PantsirS1", Point="true" },
["PantsirS2 CHM"] = { Range=30, Blindspot=1.2, Height=18, Type="Medium", Radar="PantsirS2" },
["PGL-625 CHM"] = { Range=10, Blindspot=0.5, Height=5, Type="Short", Radar="PGL_625" },
["HQ-17A CHM"] = { Range=20, Blindspot=1.5, Height=10, Type="Short", Radar="HQ17A" },
["M903PAC2 CHM"] = { Range=160, Blindspot=3, Height=24.5, Type="Long", Radar="MIM104_M903_PAC2" },
["M903PAC3 CHM"] = { Range=120, Blindspot=1, Height=40, Type="Long", Radar="MIM104_M903_PAC3" },
["TorM2 CHM"] = { Range=12, Blindspot=1, Height=10, Type="Short", Radar="TorM2" },
["TorM2K CHM"] = { Range=12, Blindspot=1, Height=10, Type="Short", Radar="TorM2K" },
["TorM2M CHM"] = { Range=16, Blindspot=1, Height=10, Type="Short", Radar="TorM2M" },
["PGL-625 CHM"] = { Range=10, Blindspot=1, Height=5, Type="Short", Radar="PGL_625" },
["HQ-17A CHM"] = { Range=15, Blindspot=1.5, Height=10, Type="Short", Radar="HQ17A" },
["M903PAC2 CHM"] = { Range=120, Blindspot=3, Height=24.5, Type="Long", Radar="MIM104_M903_PAC2" },
["M903PAC3 CHM"] = { Range=160, Blindspot=1, Height=40, Type="Long", Radar="MIM104_M903_PAC3" },
["TorM2 CHM"] = { Range=12, Blindspot=1, Height=10, Type="Point", Radar="TorM2", Point="true" },
["TorM2K CHM"] = { Range=12, Blindspot=1, Height=10, Type="Point", Radar="TorM2K", Point="true" },
["TorM2M CHM"] = { Range=16, Blindspot=1, Height=10, Type="Point", Radar="TorM2M", Point="true" },
["NASAMS3-AMRAAMER CHM"] = { Range=50, Blindspot=2, Height=35.7, Type="Medium", Radar="CH_NASAMS3_LN_AMRAAM_ER" },
["NASAMS3-AIM9X2 CHM"] = { Range=20, Blindspot=0.2, Height=18, Type="Short", Radar="CH_NASAMS3_LN_AIM9X2" },
["C-RAM CHM"] = { Range=2, Blindspot=0, Height=2, Type="Point", Radar="CH_Centurion_C_RAM", Point="true" },
["PGZ-09 CHM"] = { Range=4, Blindspot=0, Height=3, Type="Point", Radar="CH_PGZ09", Point="true" },
["S350-9M100 CHM"] = { Range=15, Blindspot=1.5, Height=8, Type="Short", Radar="CH_S350_50P6_9M100" },
["PGZ-09 CHM"] = { Range=4, Blindspot=0.5, Height=3, Type="Point", Radar="CH_PGZ09", Point="true" },
["S350-9M100 CHM"] = { Range=15, Blindspot=1, Height=8, Type="Short", Radar="CH_S350_50P6_9M100" },
["S350-9M96D CHM"] = { Range=150, Blindspot=2.5, Height=30, Type="Long", Radar="CH_S350_50P6_9M96D" },
["LAV-AD CHM"] = { Range=8, Blindspot=0.2, Height=4.8, Type="Short", Radar="CH_LAVAD" },
["LAV-AD CHM"] = { Range=8, Blindspot=0.16, Height=4.8, Type="Short", Radar="CH_LAVAD" },
["HQ-22 CHM"] = { Range=170, Blindspot=5, Height=27, Type="Long", Radar="CH_HQ22_LN" },
["PGZ-95 CHM"] = { Range=2, Blindspot=0, Height=2, Type="Point", Radar="CH_PGZ95",Point="true" },
["LD-3000 CHM"] = { Range=3, Blindspot=0, Height=3, Type="Point", Radar="CH_LD3000_stationary", Point="true" },
["LD-3000M CHM"] = { Range=3, Blindspot=0, Height=3, Type="Point", Radar="CH_LD3000", Point="true" },
["FlaRakRad CHM"] = { Range=8, Blindspot=1.5, Height=6, Type="Short", Radar="HQ17A" },
["PGZ-95 CHM"] = { Range=2.5, Blindspot=0.5, Height=2, Type="Point", Radar="CH_PGZ95",Point="true" },
["LD-3000 CHM"] = { Range=2.5, Blindspot=0.1, Height=3, Type="Point", Radar="CH_LD3000_stationary", Point="true" },
["LD-3000M CHM"] = { Range=2.5, Blindspot=0.1, Height=3, Type="Point", Radar="CH_LD3000", Point="true" },
["FlaRakRad CHM"] = { Range=8, Blindspot=1.5, Height=6, Type="Short", Radar="CH_FlaRakRad" },
["IRIS-T SLM CHM"] = { Range=40, Blindspot=0.5, Height=20, Type="Medium", Radar="CH_IRIST_SLM" },
["M903PAC2KAT1 CHM"] = { Range=160, Blindspot=3, Height=24.5, Type="Long", Radar="CH_MIM104_M903_PAC2_KAT1" },
["Skynex CHM"] = { Range=3.5, Blindspot=0, Height=3.5, Type="Point", Radar="CH_SkynexHX", Point="true" },
["Skyshield CHM"] = { Range=3.5, Blindspot=0, Height=3.5, Type="Point", Radar="CH_Skyshield_Gun", Point="true" },
["WieselOzelot CHM"] = { Range=8, Blindspot=0.2, Height=4.8, Type="Short", Radar="CH_Wiesel2Ozelot" },
["M903PAC2KAT1 CHM"] = { Range=120, Blindspot=3, Height=24.5, Type="Long", Radar="CH_MIM104_M903_PAC2_KAT1" },
["Skynex CHM"] = { Range=3.5, Blindspot=0.1, Height=3.5, Type="Point", Radar="CH_SkynexHX", Point="true" },
["Skyshield CHM"] = { Range=3.5, Blindspot=0.1, Height=3.5, Type="Point", Radar="CH_Skyshield_Gun", Point="true" },
["WieselOzelot CHM"] = { Range=8, Blindspot=0.16, Height=4.8, Type="Short", Radar="CH_Wiesel2Ozelot" },
["BukM3-9M317M CHM"] = { Range=70, Blindspot=0.25, Height=35, Type="Medium", Radar="CH_BukM3_9A317M" },
["BukM3-9M317MA CHM"] = { Range=70, Blindspot=0.25, Height=35, Type="Medium", Radar="CH_BukM3_9A317MA" },
["SkySabre CHM"] = { Range=30, Blindspot=0.5, Height=10, Type="Medium", Radar="CH_SkySabreLN" },
["Stormer CHM"] = { Range=7.5, Blindspot=0.3, Height=7, Type="Short", Radar="CH_StormerHVM" },
["THAAD CHM"] = { Range=200, Blindspot=40, Height=150, Type="Long", Radar="CH_THAAD_M1120" },
["USInfantryFIM92K CHM"] = { Range=8, Blindspot=0.2, Height=4.8, Type="Short", Radar="CH_USInfantry_FIM92" },
["RBS98M CHM"] = { Range=20, Blindspot=0, Height=8, Type="Short", Radar="RBS-98" },
["RBS70 CHM"] = { Range=8, Blindspot=0, Height=5.5, Type="Short", Radar="RBS-70" },
["RBS90 CHM"] = { Range=8, Blindspot=0, Height=5.5, Type="Short", Radar="RBS-90" },
["RBS103A CHM"] = { Range=150, Blindspot=3, Height=24.5, Type="Long", Radar="LvS-103_Lavett103_Rb103A" },
["RBS103B CHM"] = { Range=35, Blindspot=0, Height=36, Type="Medium", Radar="LvS-103_Lavett103_Rb103B" },
["RBS103AM CHM"] = { Range=150, Blindspot=3, Height=24.5, Type="Long", Radar="LvS-103_Lavett103_HX_Rb103A" },
["RBS103BM CHM"] = { Range=35, Blindspot=0, Height=36, Type="Medium", Radar="LvS-103_Lavett103_HX_Rb103B" },
["Lvkv9040M CHM"] = { Range=4, Blindspot=0, Height=2.5, Type="Point", Radar="LvKv9040", Point="true" },
["USInfantryFIM92K CHM"] = { Range=8, Blindspot=0.16, Height=4.8, Type="Short", Radar="CH_USInfantry_FIM92" },
["RBS98M CHM"] = { Range=20, Blindspot=0.2, Height=8, Type="Short", Radar="RBS-98" },
["RBS70 CHM"] = { Range=8, Blindspot=0.25, Height=6, Type="Short", Radar="RBS-70" },
["RBS70M CHM"] = { Range=8, Blindspot=0.25, Height=6, Type="Short", Radar="BV410_RBS70" },
["RBS90 CHM"] = { Range=8, Blindspot=0.25, Height=6, Type="Short", Radar="RBS-90" },
["RBS90M CHM"] = { Range=8, Blindspot=0.25, Height=6, Type="Short", Radar="BV410_RBS90" },
["RBS103A CHM"] = { Range=160, Blindspot=1, Height=36, Type="Long", Radar="LvS-103_Lavett103_Rb103A" },
["RBS103B CHM"] = { Range=120, Blindspot=3, Height=24.5, Type="Long", Radar="LvS-103_Lavett103_Rb103B" },
["RBS103AM CHM"] = { Range=160, Blindspot=1, Height=36, Type="Long", Radar="LvS-103_Lavett103_HX_Rb103A" },
["RBS103BM CHM"] = { Range=120, Blindspot=3, Height=24.5, Type="Long", Radar="LvS-103_Lavett103_HX_Rb103B" },
["Lvkv9040M CHM"] = { Range=2, Blindspot=0.1, Height=1.2, Type="Point", Radar="LvKv9040",Point="true" },
}
-----------------------------------------------------------------------
@@ -623,7 +632,8 @@ do
self.advAwacs = false
end
self:SetDLinkCacheTime()
-- Set the string id for output to DCS.log file.
self.lid=string.format("MANTIS %s | ", self.name)
@@ -656,6 +666,8 @@ do
table.insert(self.ewr_templates,awacs)
end
self.logsamstatus = false
self:T({self.ewr_templates})
self.SAM_Group = SET_GROUP:New():FilterPrefixes(self.SAM_Templates_Prefix):FilterCoalitions(self.Coalition)
@@ -685,9 +697,6 @@ do
-- counter for SAM table updates
self.checkcounter = 1
-- TODO Version
-- @field #string version
self.version="0.9.27"
self:I(string.format("***** Starting MANTIS Version %s *****", self.version))
--- FSM Functions ---
@@ -884,7 +893,11 @@ do
self.AcceptZones = AcceptZones or {}
self.RejectZones = RejectZones or {}
self.ConflictZones = ConflictZones or {}
if #self.AcceptZones > 0 or #self.RejectZones > 0 or #self.ConflictZones > 0 then
self.AcceptZonesNo = UTILS.TableLength(self.AcceptZones)
self.RejectZonesNo = UTILS.TableLength(self.RejectZones)
self.ConflictZonesNo = UTILS.TableLength(self.ConflictZones)
self:T(string.format("AcceptZonesNo = %d | RejectZonesNo = %d | ConflictZonesNo = %d",self.AcceptZonesNo,self.RejectZonesNo,self.ConflictZonesNo))
if self.AcceptZonesNo > 0 or self.RejectZonesNo > 0 or self.ConflictZonesNo > 0 then
self.usezones = true
end
return self
@@ -1037,6 +1050,16 @@ do
end
return self
end
--- Function to set how long INTEL DLINK remembers contacts.
-- @param #MANTIS self
-- @param #number seconds Remember this many seconds, at least 5 seconds.
-- @return #MANTIS self
function MANTIS:SetDLinkCacheTime(seconds)
self.DLinkCacheTime = math.abs(seconds or 120)
if self.DLinkCacheTime < 5 then self.DLinkCacheTime = 5 end
return self
end
--- Function to set the detection interval
-- @param #MANTIS self
@@ -1266,7 +1289,8 @@ do
self:T(self.lid.."_CheckCoordinateInZones")
local inzone = false
-- acceptzones
if #self.AcceptZones > 0 then
self:T(string.format("AcceptZonesNo = %d | RejectZonesNo = %d | ConflictZonesNo = %d",self.AcceptZonesNo,self.RejectZonesNo,self.ConflictZonesNo))
if self.AcceptZonesNo > 0 then
for _,_zone in pairs(self.AcceptZones) do
local zone = _zone -- Core.Zone#ZONE
if zone:IsCoordinateInZone(coord) then
@@ -1277,7 +1301,7 @@ do
end
end
-- rejectzones
if #self.RejectZones > 0 and inzone then -- maybe in accept zone, but check the overlaps
if self.RejectZonesNo > 0 then
for _,_zone in pairs(self.RejectZones) do
local zone = _zone -- Core.Zone#ZONE
if zone:IsCoordinateInZone(coord) then
@@ -1288,7 +1312,7 @@ do
end
end
-- conflictzones
if #self.ConflictZones > 0 and not inzone then -- if not already accepted, might be in conflict zones
if self.ConflictZonesNo > 0 then
for _,_zone in pairs(self.ConflictZones) do
local zone = _zone -- Core.Zone#ZONE
if zone:IsCoordinateInZone(coord) then
@@ -1354,6 +1378,7 @@ do
end
-- check accept/reject zones
local zonecheck = true
self:T("self.usezones = "..tostring(self.usezones))
if self.usezones then
-- DONE
zonecheck = self:_CheckCoordinateInZones(coord)
@@ -1429,7 +1454,9 @@ do
--IntelTwo:SetClusterRadius(5000)
IntelTwo:Start()
local IntelDlink = INTEL_DLINK:New({IntelOne,IntelTwo},self.name.." DLINK",22,300)
local CacheTime = self.DLinkCacheTime or 120
local IntelDlink = INTEL_DLINK:New({IntelOne,IntelTwo},self.name.." DLINK",22,CacheTime)
IntelDlink:__Start(1)
self:SetUsingDLink(IntelDlink)
@@ -1491,7 +1518,7 @@ do
elseif chm then
SAMData = self.SamDataCH
end
--self:T("Looking to auto-match for "..grpname)
--self:I("Looking to auto-match for "..grpname)
for _,_unit in pairs(units) do
local unit = _unit -- Wrapper.Unit#UNIT
local type = string.lower(unit:GetTypeName())
@@ -1692,7 +1719,9 @@ do
local grpname = group:GetName()
local grpcoord = group:GetCoordinate()
local grprange, grpheight,type,blind = self:_GetSAMRange(grpname)
local radaralive = group:IsSAM()
-- TODO the below might stop working at some point after some hours, needs testing
--local radaralive = group:IsSAM()
local radaralive = true
table.insert( SAM_Tbl, {grpname, grpcoord, grprange, grpheight, blind, type}) -- make the table lighter, as I don't really use the zone here
table.insert( SEAD_Grps, grpname )
if type == MANTIS.SamType.LONG and radaralive then
@@ -1789,7 +1818,7 @@ do
if self.Shorad and self.Shorad.ActiveGroups and self.Shorad.ActiveGroups[name] then
activeshorad = true
end
if IsInZone and not suppressed and not activeshorad then --check any target in zone and not currently managed by SEAD
if IsInZone and (not suppressed) and (not activeshorad) then --check any target in zone and not currently managed by SEAD
if samgroup:IsAlive() then
-- switch on SAM
local switch = false
@@ -1821,7 +1850,7 @@ do
-- link in to SHORAD if available
-- DONE: Test integration fully
if self.ShoradLink and (Distance < self.ShoradActDistance or Distance < blind ) then -- don't give SHORAD position away too early
local Shorad = self.Shorad
local Shorad = self.Shorad --Functional.Shorad#SHORAD
local radius = self.checkradius
local ontime = self.ShoradTime
Shorad:WakeUpShorad(name, radius, ontime)
@@ -1854,7 +1883,7 @@ do
end --end alive
end --end check
end --for loop
if self.debug or self.verbose then
if self.debug or self.verbose or self.logsamstatus then
for _,_status in pairs(self.SamStateTracker) do
if _status == "GREEN" then
instatusgreen=instatusgreen+1
@@ -1875,8 +1904,9 @@ do
-- @param #MANTIS self
-- @param Functional.Detection#DETECTION_AREAS detection Detection object
-- @param #boolean dlink
-- @param #boolean reporttolog
-- @return #MANTIS self
function MANTIS:_Check(detection,dlink)
function MANTIS:_Check(detection,dlink,reporttolog)
self:T(self.lid .. "Check")
--get detected set
local detset = detection:GetDetectedItemCoordinates()
@@ -1903,7 +1933,8 @@ do
local samset = self:_GetSAMTable() -- table of i.1=names, i.2=coordinates, i.3=firing range, i.4=firing height
instatusred, instatusgreen, activeshorads = self:_CheckLoop(samset,detset,dlink,self.maxclassic)
end
if self.debug or self.verbose then
local function GetReport()
local statusreport = REPORT:New("\nMANTIS Status "..self.name)
statusreport:Add("+-----------------------------+")
statusreport:Add(string.format("+ SAM in RED State: %2d",instatusred))
@@ -1912,7 +1943,15 @@ do
statusreport:Add(string.format("+ SHORAD active: %2d",activeshorads))
end
statusreport:Add("+-----------------------------+")
return statusreport
end
if self.debug or self.verbose then
local statusreport = GetReport()
MESSAGE:New(statusreport:Text(),10):ToAll():ToLog()
elseif reporttolog == true then
local statusreport = GetReport()
MESSAGE:New(statusreport:Text(),10):ToLog()
end
return self
end
@@ -2020,7 +2059,7 @@ do
self:T({From, Event, To})
-- check detection
if not self.state2flag then
self:_Check(self.Detection,self.DLink)
self:_Check(self.Detection,self.DLink,self.logsamstatus)
end
local EWRAlive = self:_CheckAnyEWRAlive()
@@ -2091,7 +2130,7 @@ do
if self.debug and self.verbose then
self:I(self.lid .. "Status Report")
for _name,_state in pairs(self.SamStateTracker) do
self:I(string.format("Site %s\tStatus %s",_name,_state))
self:I(string.format("Site %s | Status %s",_name,_state))
end
end
local interval = self.detectinterval * -1
@@ -53,6 +53,8 @@
--
-- # Developer Note
--
-- ![Banner Image](..\Images\deprecated.png)
--
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE.
-- Therefore, this class is considered to be deprecated and superseded by the [Functional.Fox](https://flightcontrol-master.github.io/MOOSE_DOCS_DEVELOP/Documentation/Functional.Fox.html) class, which provides the same functionality.
--
File diff suppressed because it is too large Load Diff
+6 -1
View File
@@ -2102,7 +2102,12 @@ function RANGE._OnImpact(weapon, self, playerData, attackHdg, attackAlt, attackV
result.attackHdg = attackHdg
result.attackVel = attackVel
result.attackAlt = attackAlt
result.date=os and os.date() or "n/a"
if os and os.date then
result.date=os.date()
else
self:E(self.lid.."os or os.date() not available")
result.date = "n/a"
end
-- Add to table.
table.insert( _results, result )
+217 -61
View File
@@ -90,7 +90,8 @@
-- @image Scoring.JPG
--- @type SCORING
-- @field Players A collection of the current players that have joined the game.
-- @field #table Players A collection of the current players that have joined the game.
-- @field Core.Set#SET_SCENERY ScoringScenery
-- @extends Core.Base#BASE
--- SCORING class
@@ -229,7 +230,8 @@ SCORING = {
ClassID = 0,
Players = {},
AutoSave = true,
version = "1.18.4"
version = "1.18.4",
ScoringScenery = nil, -- Core.Set#SET_SCENERY
}
local _SCORINGCoalition = {
@@ -320,8 +322,12 @@ function SCORING:New( GameName, SavePath, AutoSave )
-- Create the CSV file.
self.AutoSavePath = SavePath
self.AutoSave = AutoSave or true
self:OpenCSV( GameName )
self.AutoSave = (AutoSave == nil or AutoSave == true) and true or false
if self.AutoSavePath and self.AutoSave == true then
self:OpenCSV( GameName )
end
self:I("SCORING "..tostring(GameName).." started! v"..self.version)
return self
@@ -375,7 +381,7 @@ function SCORING:AddUnitScore( ScoreUnit, Score )
return self
end
--- Removes a @{Wrapper.Unit} for additional scoring when the @{Wrapper.Unit} is destroyed.
--- Removes a @{Wrapper.Unit} for scoring when the @{Wrapper.Unit} is destroyed.
-- @param #SCORING self
-- @param Wrapper.Unit#UNIT ScoreUnit The @{Wrapper.Unit} for which the Score needs to be given.
-- @return #SCORING
@@ -392,10 +398,26 @@ end
-- Note that if there was already a @{Wrapper.Static} declared within the scoring with the same name,
-- then the old @{Wrapper.Static} will be replaced with the new @{Wrapper.Static}.
-- @param #SCORING self
-- @param Wrapper.Static#UNIT ScoreStatic The @{Wrapper.Static} for which the Score needs to be given.
-- @param Wrapper.Static#STATIC ScoreStatic The @{Wrapper.Static} for which the Score needs to be given.
-- @param #number Score The Score value.
-- @return #SCORING
function SCORING:AddStaticScore( ScoreStatic, Score )
return self:AddScoreStatic( ScoreStatic, Score )
end
--- Add a @{Wrapper.Static} for additional scoring when the @{Wrapper.Static} is destroyed.
-- Note that if there was already a @{Wrapper.Static} declared within the scoring with the same name,
-- then the old @{Wrapper.Static} will be replaced with the new @{Wrapper.Static}.
-- @param #SCORING self
-- @param Wrapper.Static#STATIC ScoreStatic The @{Wrapper.Static} for which the Score needs to be given.
-- @param #number Score The Score value.
-- @return #SCORING
function SCORING:AddScoreStatic( ScoreStatic, Score )
if ScoreStatic == nil then
BASE:E("SCORING.AddStaticScore: Parameter ScoreStatic is nil!")
return self
end
local StaticName = ScoreStatic:GetName()
@@ -404,7 +426,61 @@ function SCORING:AddStaticScore( ScoreStatic, Score )
return self
end
--- Removes a @{Wrapper.Static} for additional scoring when the @{Wrapper.Static} is destroyed.
--- Add a @{Wrapper.Scenery} for additional scoring when the @{Wrapper.Scenery} is destroyed.
-- @param #SCORING self
-- @param Wrapper.Scenery#SCENERY ScoreScenery The @{Wrapper.Scenery} for which the Score needs to be given.
-- @param #number Score The Score value.
-- @return #SCORING
function SCORING:AddScoreScenery( ScoreScenery, Score )
if ScoreScenery == nil then
self:E("SCORING.ScoreScenery: Parameter ScoreScenery is nil!")
return self
end
if not self.ScoringScenery then
self.ScoringScenery = SET_SCENERY:New() -- Core.Set#SET_SCENERY
end
local StaticName = ScoreScenery:GetName()
self:T("Scenery name = ".. StaticName)
self.ScoringScenery:AddScenery(ScoreScenery)
return self
end
--- Removes a @{Wrapper.Scenery} for scoring when the @{Wrapper.Scenery} is destroyed.
-- @param #SCORING self
-- @param Wrapper.Scenery#SCENERY ScoreStatic The @{Wrapper.Scenery} for which the Score needs to be given.
-- @return #SCORING
function SCORING:RemoveSceneryScore( ScoreScenery )
local StaticName = ScoreScenery:GetName()
self.ScoringObjects[StaticName] = nil
return self
end
--- Specify a special additional score for a @{Core.Set#SET_SCENERY}.
-- @param #SCORING self
-- @param Core.Set#SET_SCENERY Set The @{Core.Set#SET_SCENERY} for which each @{Wrapper.Scenery} in the SET a Score is given.
-- @param #number Score The Score value.
-- @return #SCORING
function SCORING:AddScoreSetScenery(Set, Score)
local set = Set.Set
for _,_static in pairs (set) do
if _static ~= nil then
self:AddScoreScenery(_static,Score)
end
end
return self
end
--- Removes a @{Wrapper.Static} for scoring when the @{Wrapper.Static} is destroyed.
-- @param #SCORING self
-- @param Wrapper.Static#UNIT ScoreStatic The @{Wrapper.Static} for which the Score needs to be given.
-- @return #SCORING
@@ -459,6 +535,31 @@ function SCORING:AddScoreSetGroup(Set, Score)
return self
end
--- Specify a special additional score for a @{Core.Set#SET_STATIC}.
-- @param #SCORING self
-- @param Core.Set#SET_STATIC Set The @{Core.Set#SET_STATIC} for which each @{Wrapper.Static} in the SET a Score is given.
-- @param #number Score The Score value.
-- @return #SCORING
function SCORING:AddScoreSetStatic(Set, Score)
local set = Set:GetSetObjects()
for _,_static in pairs (set) do
if _static and _static:IsAlive() then
self:AddStaticScore(_static,Score)
end
end
local function AddScore(static)
self:AddStaticScore(static,Score)
end
function Set:OnAfterAdded(From,Event,To,ObjectName,Object)
AddScore(Object)
end
return self
end
--- Add a @{Core.Zone} to define additional scoring when any object is destroyed in that zone.
-- Note that if a @{Core.Zone} with the same name is already within the scoring added, the @{Core.Zone} (type) and Score will be replaced!
-- This allows for a dynamic destruction zone evolution within your mission.
@@ -478,7 +579,24 @@ function SCORING:AddZoneScore( ScoreZone, Score )
return self
end
--- Remove a @{Core.Zone} for additional scoring.
--- Add a @{Core.Set#SET_ZONE} to define additional scoring when any object is destroyed in that zone.
-- Note that if a @{Core.Zone} with the same name is already within the scoring added, the @{Core.Zone} (type) and Score will be replaced!
-- This allows for a dynamic destruction zone evolution within your mission.
-- @param #SCORING self
-- @param Core.Set#SET_ZONE ScoreZoneSet The @{Core.Set#SET_ZONE} which defines the destruction score perimeters.
-- Note that a zone can be a polygon or a moving zone.
-- @param #number Score The Score value.
-- @return #SCORING
function SCORING:AddZoneScoreSet( ScoreZoneSet, Score )
for _,_zone in pairs(ScoreZoneSet.Set or {}) do
self:AddZoneScore(_zone,Score)
end
return self
end
--- Remove a @{Core.Zone} for scoring.
-- The scoring will search if any @{Core.Zone} is added with the given name, and will remove that zone from the scoring.
-- This allows for a dynamic destruction zone evolution within your mission.
-- @param #SCORING self
@@ -956,7 +1074,7 @@ end
-- @param #SCORING self
-- @param Core.Event#EVENTDATA Event
function SCORING:_EventOnHit( Event )
self:F( { Event } )
--self:F( { Event } )
local InitUnit = nil
local InitUNIT = nil
@@ -985,6 +1103,8 @@ function SCORING:_EventOnHit( Event )
local TargetUnitCoalition = nil
local TargetUnitCategory = nil
local TargetUnitType = nil
local TargetIsScenery = false
local TargetSceneryObject = nil
if Event.IniDCSUnit then
@@ -1006,7 +1126,7 @@ function SCORING:_EventOnHit( Event )
InitUnitCategory = _SCORINGCategory[InitCategory]
InitUnitType = InitType
self:T( { InitUnitName, InitGroupName, InitPlayerName, InitCoalition, InitCategory, InitType, InitUnitCoalition, InitUnitCategory, InitUnitType } )
--self:T( { InitUnitName, InitGroupName, InitPlayerName, InitCoalition, InitCategory, InitType, InitUnitCoalition, InitUnitCategory, InitUnitType } )
end
if Event.TgtDCSUnit then
@@ -1024,12 +1144,23 @@ function SCORING:_EventOnHit( Event )
-- TargetCategory = TargetUnit:getDesc().category
TargetCategory = Event.TgtCategory
TargetType = Event.TgtTypeName
-- Scenery hit
if TargetUNIT ~= nil and TargetUNIT:IsInstanceOf("SCENERY") then
TargetCategory = Unit.Category.STRUCTURE
TargetIsScenery = true
TargetType = "Scenery"
TargetSceneryObject = TargetUNIT
self:T("***** Target is Scenery and TargetUNIT is SCENERY object!")
UTILS.PrintTableToLog(TargetSceneryObject)
end
TargetUnitCoalition = _SCORINGCoalition[TargetCoalition]
TargetUnitCategory = _SCORINGCategory[TargetCategory]
TargetUnitType = TargetType
self:T( { TargetUnitName, TargetGroupName, TargetPlayerName, TargetCoalition, TargetCategory, TargetType, TargetUnitCoalition, TargetUnitCategory, TargetUnitType } )
--self:T( { TargetUnitName=TargetUnitName, TargetGroupName=TargetGroupName, TargetPlayerName=TargetPlayerName, TargetCoalition=TargetCoalition, TargetCategory=TargetCategory, TargetType=TargetType, TargetUnitCoalition=TargetUnitCoalition, TargetUnitCategory=TargetUnitCategory, TargetUnitType=TargetUnitType } )
end
if InitPlayerName ~= nil then -- It is a player that is hitting something
@@ -1042,7 +1173,7 @@ function SCORING:_EventOnHit( Event )
self:T( "Hitting Something" )
-- What is he hitting?
if TargetCategory then
if (TargetCategory ~=nil) and (TargetIsScenery == false) then
-- A target got hit, score it.
-- Player contains the score data from self.Players[InitPlayerName]
@@ -1062,7 +1193,7 @@ function SCORING:_EventOnHit( Event )
PlayerHit.TimeStamp = PlayerHit.TimeStamp or 0
PlayerHit.UNIT = PlayerHit.UNIT or TargetUNIT
-- After an instant kill we can't compute the threat level anymore. To fix this we compute at OnEventBirth
if PlayerHit.UNIT.ThreatType == nil then
if PlayerHit.UNIT and PlayerHit.UNIT.ThreatType == nil then
PlayerHit.ThreatLevel, PlayerHit.ThreatType = PlayerHit.UNIT:GetThreatLevel()
-- if this fails for some reason, set a good default value
if PlayerHit.ThreatType == nil or PlayerHit.ThreatType == "" then
@@ -1117,17 +1248,22 @@ function SCORING:_EventOnHit( Event )
MESSAGE.Type.Update )
:ToAllIf( self:IfMessagesHit() and self:IfMessagesToAll() )
:ToCoalitionIf( InitCoalition, self:IfMessagesHit() and self:IfMessagesToCoalition() )
else
elseif TargetIsScenery ~= true then
MESSAGE:NewType( self.DisplayMessagePrefix .. "Player '" .. InitPlayerName .. "' hit enemy target " .. TargetUnitCategory .. " ( " .. TargetType .. " ) " .. PlayerHit.ScoreHit .. " times. " ..
"Score: " .. PlayerHit.Score .. ". Score Total:" .. Player.Score - Player.Penalty,
MESSAGE.Type.Update )
:ToAllIf( self:IfMessagesHit() and self:IfMessagesToAll() )
:ToCoalitionIf( InitCoalition, self:IfMessagesHit() and self:IfMessagesToCoalition() )
elseif TargetIsScenery == true then
MESSAGE:NewType( self.DisplayMessagePrefix .. "Player '" .. InitPlayerName .. "' hit scenery object." .. " Score: " .. PlayerHit.Score .. ". Score Total:" .. Player.Score - Player.Penalty,
MESSAGE.Type.Update )
:ToAllIf( self:IfMessagesHit() and self:IfMessagesToAll() )
:ToCoalitionIf( InitCoalition, self:IfMessagesHit() and self:IfMessagesToCoalition() )
end
self:ScoreCSV( InitPlayerName, TargetPlayerName, "HIT_SCORE", 1, 1, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType )
end
else -- A scenery object was hit.
MESSAGE:NewType( self.DisplayMessagePrefix .. "Player '" .. InitPlayerName .. "' hit scenery object.",
MESSAGE:NewType( self.DisplayMessagePrefix .. "Player '" .. InitPlayerName .. "' hit nothing special.",
MESSAGE.Type.Update )
:ToAllIf( self:IfMessagesHit() and self:IfMessagesToAll() )
:ToCoalitionIf( InitCoalition, self:IfMessagesHit() and self:IfMessagesToCoalition() )
@@ -1143,21 +1279,21 @@ function SCORING:_EventOnHit( Event )
-- 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:_AddPlayerFromUnit( Event.WeaponUNIT )
if self.Players[Event.WeaponPlayerName] then -- This should normally not happen, but i'll test it anyway.
if TargetPlayerName ~= nil then -- It is a player hitting another player ...
self:_AddPlayerFromUnit( TargetUNIT )
end
if Event.WeaponPlayerName ~= nil or TargetIsScenery == true then
local playername = Event.WeaponPlayerName or Event.IniPlayerName or "Ghost"
--self:_AddPlayerFromUnit( Event.WeaponUNIT )
if self.Players[playername] then -- This should normally not happen, but i'll test it anyway.
self:T( "Hitting Scenery" )
self:T( "Hitting Scenery or Static" )
-- What is he hitting?
if TargetCategory then
if Event.TgtObjectCategory then
-- A scenery or static got hit, score it.
-- Player contains the score data from self.Players[WeaponPlayerName]
local Player = self.Players[Event.WeaponPlayerName]
local Player = self.Players[playername]
-- Ensure there is a hit table per TargetCategory and TargetUnitName.
Player.Hit[TargetCategory] = Player.Hit[TargetCategory] or {}
@@ -1165,15 +1301,17 @@ function SCORING:_EventOnHit( Event )
-- PlayerHit contains the score counters and data per unit that was hit.
local PlayerHit = Player.Hit[TargetCategory][TargetUnitName]
-- Init player scores
PlayerHit.Score = PlayerHit.Score or 0
PlayerHit.Penalty = PlayerHit.Penalty or 0
PlayerHit.ScoreHit = PlayerHit.ScoreHit or 0
PlayerHit.PenaltyHit = PlayerHit.PenaltyHit or 0
PlayerHit.TimeStamp = PlayerHit.TimeStamp or 0
PlayerHit.UNIT = PlayerHit.UNIT or TargetUNIT
-- After an instant kill we can't compute the threat level anymore. To fix this we compute at OnEventBirth
if PlayerHit.UNIT.ThreatType == nil then
if PlayerHit.UNIT and PlayerHit.UNIT.ThreatType == nil then
PlayerHit.ThreatLevel, PlayerHit.ThreatType = PlayerHit.UNIT:GetThreatLevel()
-- if this fails for some reason, set a good default value
if PlayerHit.ThreatType == nil then
@@ -1181,8 +1319,8 @@ function SCORING:_EventOnHit( Event )
PlayerHit.ThreatType = "Unknown"
end
else
PlayerHit.ThreatLevel = PlayerHit.UNIT.ThreatLevel
PlayerHit.ThreatType = PlayerHit.UNIT.ThreatType
PlayerHit.ThreatLevel = PlayerHit.UNIT and PlayerHit.UNIT.ThreatLevel or 1
PlayerHit.ThreatType = PlayerHit.UNIT and PlayerHit.UNIT.ThreatType or "Unknown"
end
-- Only grant hit scores if there was more than one second between the last hit.
@@ -1190,50 +1328,68 @@ function SCORING:_EventOnHit( Event )
PlayerHit.TimeStamp = timer.getTime()
local Score = 0
if InitCoalition then -- A coalition object was hit, probably a static.
if InitCoalition == TargetCoalition then
-- TODO: Penalty according scale
local Penalty = 10
Player.Penalty = Player.Penalty + Penalty --* self.ScaleDestroyPenalty
PlayerHit.Penalty = PlayerHit.Penalty + Penalty --* self.ScaleDestroyPenalty
PlayerHit.PenaltyHit = PlayerHit.PenaltyHit + 1 * self.ScaleDestroyPenalty
MESSAGE
:NewType( self.DisplayMessagePrefix .. "Player '" .. Event.WeaponPlayerName .. "' hit friendly target " ..
TargetUnitCategory .. " ( " .. TargetType .. " ) " ..
"Penalty: -" .. Penalty .. " = " .. Player.Score - Player.Penalty,
MESSAGE.Type.Update
)
:ToAllIf( self:IfMessagesHit() and self:IfMessagesToAll() )
:ToCoalitionIf( Event.WeaponCoalition, self:IfMessagesHit() and self:IfMessagesToCoalition() )
self:ScoreCSV( Event.WeaponPlayerName, TargetPlayerName, "HIT_PENALTY", 1, -10, Event.WeaponName, Event.WeaponCoalition, Event.WeaponCategory, Event.WeaponTypeName, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType )
else
local TgtName = Event.TgtDCSUnit and Event.TgtDCSUnit.getName and Event.TgtDCSUnit:getName() or "Unknown"
--if InitCoalition then -- A coalition object was hit, probably a static.
if TargetIsScenery == true and self.ScoringScenery:IsInSet(TargetSceneryObject) then
Player.Score = Player.Score + self.ScoreIncrementOnHit
PlayerHit.Score = PlayerHit.Score + self.ScoreIncrementOnHit
PlayerHit.ScoreHit = PlayerHit.ScoreHit + 1
MESSAGE:NewType( self.DisplayMessagePrefix .. "Player '" .. Event.WeaponPlayerName .. "' hit enemy target " .. TargetUnitCategory .. " ( " .. TargetType .. " ) " ..
MESSAGE:NewType( self.DisplayMessagePrefix .. "Player '" .. playername .. "' hit scenery target " .. TargetUnitCategory .. " ( " .. TargetType .. " ) " ..
"Score: " .. PlayerHit.Score .. ". Score Total:" .. Player.Score - Player.Penalty,
MESSAGE.Type.Update )
:ToAllIf( self:IfMessagesHit() and self:IfMessagesToAll() )
:ToCoalitionIf( Event.WeaponCoalition, self:IfMessagesHit() and self:IfMessagesToCoalition() )
self:ScoreCSV( Event.WeaponPlayerName, TargetPlayerName, "HIT_SCORE", 1, 1, Event.WeaponName, Event.WeaponCoalition, Event.WeaponCategory, Event.WeaponTypeName, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType )
end
else -- A scenery object was hit.
MESSAGE:NewType( self.DisplayMessagePrefix .. "Player '" .. Event.WeaponPlayerName .. "' hit scenery object.",
MESSAGE.Type.Update )
:ToAllIf( self:IfMessagesHit() and self:IfMessagesToAll() )
:ToCoalitionIf( InitCoalition, self:IfMessagesHit() and self:IfMessagesToCoalition() )
self:ScoreCSV( playername, TargetPlayerName, "HIT_SCORE", 1, 1, Event.WeaponName, Event.WeaponCoalition, Event.WeaponCategory, Event.WeaponTypeName, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType )
elseif TargetIsScenery == false and Event.TgtObjectCategory == Object.Category.STATIC and self.ScoringObjects[TgtName] then
Player.Score = Player.Score + self.ScoreIncrementOnHit
PlayerHit.Score = PlayerHit.Score + self.ScoreIncrementOnHit
PlayerHit.ScoreHit = PlayerHit.ScoreHit + 1
MESSAGE:NewType( self.DisplayMessagePrefix .. "Player '" .. playername .. "' hit static target " .. TargetUnitCategory .. " ( " .. TargetType .. " ) " ..
"Score: " .. PlayerHit.Score .. ". Score Total:" .. Player.Score - Player.Penalty,
MESSAGE.Type.Update )
:ToAllIf( self:IfMessagesHit() and self:IfMessagesToAll() )
:ToCoalitionIf( Event.WeaponCoalition, self:IfMessagesHit() and self:IfMessagesToCoalition() )
self:ScoreCSV( Event.WeaponPlayerName, "", "HIT_SCORE", 1, 0, Event.WeaponName, Event.WeaponCoalition, Event.WeaponCategory, Event.WeaponTypeName, TargetUnitName, "", "Scenery", TargetUnitType )
end
self:ScoreCSV( playername, TargetPlayerName, "HIT_SCORE", 1, 1, Event.WeaponName, Event.WeaponCoalition, Event.WeaponCategory, Event.WeaponTypeName, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType )
else
self:E("Hit unregistered scenery or static object - NO target! ("..TgtName..")")
end
--end
end
end
end
-- Check if there are Zones where the destruction happened.
for ZoneName, ScoreZoneData in pairs( self.ScoringZones ) do
self:F( { ScoringZone = ScoreZoneData } )
local hit=Event.TgtUnit
local ScoreZone = ScoreZoneData.ScoreZone -- Core.Zone#ZONE_BASE
local Score = ScoreZoneData.Score
if TargetUNIT and ScoreZone:IsVec2InZone( TargetUNIT:GetVec2() ) then
-- A scenery or static got hit, score it.
-- Player contains the score data from self.Players[WeaponPlayerName]
local PlayerName = Event.IniPlayerName or "Ghost"
local Player = self.Players[PlayerName]
Player.Score = Player.Score + Score
Player.Score = Player.Score + self.ScoreIncrementOnHit
MESSAGE:NewType( self.DisplayMessagePrefix .. "hit in zone '" .. ScoreZone:GetName() .. "'." ..
"Player '" .. PlayerName .. "' receives an extra " .. Score .. " points! " .. "Total: " .. Player.Score - Player.Penalty,
MESSAGE.Type.Information )
:ToAllIf( self:IfMessagesZone() and self:IfMessagesToAll() )
:ToCoalitionIf( InitCoalition, self:IfMessagesZone() and self:IfMessagesToCoalition() )
self:ScoreCSV( PlayerName, "", "HIT_SCORE", 1, Score, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, "", "Zone", TargetUnitType )
end
end
end
end
end
--- Track DEAD or CRASH events for the scoring.
-- @param #SCORING self
-- @param Core.Event#EVENTDATA Event
@@ -1291,7 +1447,7 @@ function SCORING:_EventOnDeadOrCrash( Event )
local Destroyed = false
-- What is the player destroying?
if Player and Player.Hit and Player.Hit[TargetCategory] and Player.Hit[TargetCategory][TargetUnitName] and Player.Hit[TargetCategory][TargetUnitName].TimeStamp ~= 0 and (TargetUnit.BirthTime == nil or Player.Hit[TargetCategory][TargetUnitName].TimeStamp > TargetUnit.BirthTime) then -- Was there a hit for this unit for this player before registered???
if Player and Player.Hit and Player.Hit[TargetCategory] and Player.Hit[TargetCategory][TargetUnitName] and Player.Hit[TargetCategory][TargetUnitName].TimeStamp ~= 0 and TargetUnit and (TargetUnit.BirthTime == nil or Player.Hit[TargetCategory][TargetUnitName].TimeStamp > TargetUnit.BirthTime) then -- Was there a hit for this unit for this player before registered???
local TargetThreatLevel = Player.Hit[TargetCategory][TargetUnitName].ThreatLevel
local TargetThreatType = Player.Hit[TargetCategory][TargetUnitName].ThreatType
@@ -1923,7 +2079,7 @@ function SCORING:ScoreCSV( PlayerName, TargetPlayerName, ScoreType, ScoreTimes,
TargetUnitType = TargetUnitType or ""
TargetUnitName = TargetUnitName or ""
if lfs and io and os and self.AutoSave then
if lfs and io and os and self.AutoSave == true and self.CSVFile ~= nil then
self.CSVFile:write(
'"' .. self.GameName .. '"' .. ',' ..
'"' .. self.RunTime .. '"' .. ',' ..
@@ -3153,7 +3153,7 @@ end
-- @param #WAREHOUSE self
-- @return Core.Point#COORDINATE The coordinate of the warehouse.
function WAREHOUSE:GetCoordinate()
return self.warehouse:GetCoordinate()
return self.warehouse:GetCoord()
end
--- Get 3D vector of warehouse static.
@@ -4247,6 +4247,16 @@ function WAREHOUSE:_AssetItemInfo(asset)
self:T3({Template=asset.template})
end
--- This function uses Disposition and other fallback logic to find better ground positions for ground units.
--- NOTE: This is not a spawn randomizer.
--- It will try to find clear ground locations avoiding trees, water, roads, runways, map scenery, statics and other units in the area and modifies the provided positions table.
--- Maintains the original layout and unit positions as close as possible by searching for the next closest valid position to each unit.
--- Uses UTILS.ValidateAndRepositionGroundUnits.
-- @param #boolean Enabled Enable/disable the feature.
function WAREHOUSE:SetValidateAndRepositionGroundUnits(Enabled)
self.ValidateAndRepositionGroundUnits = Enabled
end
--- On after "NewAsset" event. A new asset has been added to the warehouse stock.
-- @param #WAREHOUSE self
-- @param #string From From state.
@@ -5965,6 +5975,10 @@ function WAREHOUSE:_SpawnAssetGroundNaval(alias, asset, request, spawnzone, late
template.y = coord.z
template.alt = coord.y
if self.ValidateAndRepositionGroundUnits then
UTILS.ValidateAndRepositionGroundUnits(template.units)
end
-- Spawn group.
local group=_DATABASE:Spawn(template) --Wrapper.Group#GROUP
@@ -6893,7 +6907,7 @@ function WAREHOUSE:_CheckConquered()
for _,_unit in pairs(units) do
local unit=_unit --Wrapper.Unit#UNIT
local distance=coord:Get2DDistance(unit:GetCoordinate())
local distance=coord:Get2DDistance(unit:GetCoord())
-- Filter only alive groud units. Also check distance again, because the scan routine might give some larger distances.
if unit:IsGround() and unit:IsAlive() and distance <= radius then
@@ -7,6 +7,8 @@
--
-- # Developer Note
--
-- ![Banner Image](..\Images\deprecated.png)
--
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
-- Therefore, this class is considered to be deprecated
--
+6 -2
View File
@@ -501,6 +501,7 @@ ATIS.Alphabet = {
-- @field #number Kola +15° (East).
-- @field #number Afghanistan +3° (East).
-- @field #number Iraq +4.4° (East).
-- @field #number GermanyCW +0.1° (East).
ATIS.RunwayM2T = {
Caucasus = 0,
Nevada = 12,
@@ -513,7 +514,8 @@ ATIS.RunwayM2T = {
SinaiMap = 5,
Kola = 15,
Afghanistan = 3,
Iraq=4.4
Iraq=4.4,
GermanyCW=0.1,
}
--- Whether ICAO phraseology is used for ATIS broadcasts.
@@ -530,6 +532,7 @@ ATIS.RunwayM2T = {
-- @field #boolean Kola true.
-- @field #boolean Afghanistan true.
-- @field #boolean Iraq true.
-- @field #boolean GermanyCW true.
ATIS.ICAOPhraseology = {
Caucasus = true,
Nevada = false,
@@ -543,6 +546,7 @@ ATIS.ICAOPhraseology = {
Kola = true,
Afghanistan = true,
Iraq = true,
GermanyCW = true,
}
--- Nav point data.
@@ -2794,7 +2798,7 @@ function ATIS:onafterBroadcast( From, Event, To )
end
_RUNACT = subtitle
alltext = alltext .. ";\n" .. subtitle
--alltext = alltext .. ";\n" .. subtitle
-- Runway length.
if self.rwylength then
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+11 -1
View File
@@ -72,7 +72,7 @@ end
--- Checks if a point is contained within the circle.
-- @param #table point The point to check
-- @return #bool True if the point is contained, false otherwise
-- @return #boolean True if the point is contained, false otherwise
function CIRCLE:ContainsPoint(point)
if ((point.x - self.CenterVec2.x) ^ 2 + (point.y - self.CenterVec2.y) ^ 2) ^ 0.5 <= self.Radius then
return true
@@ -226,6 +226,11 @@ end
--- Returns a random Vec2 within the circle.
-- @return #table The random Vec2
function CIRCLE:GetRandomVec2()
math.random()
math.random()
math.random()
local angle = math.random() * 2 * math.pi
local rx = math.random(0, self.Radius) * math.cos(angle) + self.CenterVec2.x
@@ -237,6 +242,11 @@ end
--- Returns a random Vec2 on the border of the circle.
-- @return #table The random Vec2
function CIRCLE:GetRandomVec2OnBorder()
math.random()
math.random()
math.random()
local angle = math.random() * 2 * math.pi
local rx = self.Radius * math.cos(angle) + self.CenterVec2.x
@@ -352,6 +352,7 @@ end
--- Returns a random Vec2 within the polygon. The Vec2 is weighted by the areas of the triangles that make up the polygon.
-- @return #table The random Vec2
function POLYGON:GetRandomVec2()
local weights = {}
for _, triangle in pairs(self.Triangles) do
weights[triangle] = triangle.SurfaceArea / self.SurfaceArea
@@ -73,6 +73,11 @@ end
-- @param #table points The points of the triangle, or 3 other points if you're just using the TRIANGLE class without an object of it
-- @return #table The random Vec2
function TRIANGLE:GetRandomVec2(points)
math.random()
math.random()
math.random()
points = points or self.Points
local pt = {math.random(), math.random()}
table.sort(pt)
+3 -2
View File
@@ -380,7 +380,8 @@ function RADIOQUEUE:Broadcast(transmission)
self:T(self.lid..string.format("Broadcasting from aircraft %s", sender:GetName()))
if not self.senderinit then
--if not self.senderinit then
-- TODO Seems to be a DCS bug - if I explode ANY unit in a group the BC assignment gets lost
-- Command to set the Frequency for the transmission.
local commandFrequency={
@@ -394,7 +395,7 @@ function RADIOQUEUE:Broadcast(transmission)
sender:SetCommand(commandFrequency)
self.senderinit=true
end
--end
-- Set subtitle only if duration>0 sec.
local subtitle=nil
+205 -67
View File
@@ -443,28 +443,32 @@ MSRS.Voices = {
["en_AU_Standard_B"] = 'en-AU-Standard-B', -- [2] MALE
["en_AU_Standard_C"] = 'en-AU-Standard-C', -- [3] FEMALE
["en_AU_Standard_D"] = 'en-AU-Standard-D', -- [4] MALE
["en_IN_Standard_A"] = 'en-IN-Standard-A', -- [5] FEMALE
["en_IN_Standard_B"] = 'en-IN-Standard-B', -- [6] MALE
["en_IN_Standard_C"] = 'en-IN-Standard-C', -- [7] MALE
["en_IN_Standard_D"] = 'en-IN-Standard-D', -- [8] FEMALE
-- IN
["en_IN_Standard_A"] = 'en-IN-Standard-A', -- Female
["en_IN_Standard_B"] = 'en-IN-Standard-B', -- Male
["en_IN_Standard_C"] = 'en-IN-Standard-C', -- Male
["en_IN_Standard_D"] = 'en-IN-Standard-D', -- Female
["en_IN_Standard_E"] = 'en-IN-Standard-E', -- Female
["en_IN_Standard_F"] = 'en-IN-Standard-F', -- Male
-- 2025 changes
["en_GB_Standard_A"] = 'en-GB-Standard-N', -- [9] FEMALE
["en_GB_Standard_B"] = 'en-GB-Standard-O', -- [10] MALE
["en_GB_Standard_C"] = 'en-GB-Standard-N', -- [11] FEMALE
["en_GB_Standard_D"] = 'en-GB-Standard-O', -- [12] MALE
["en_GB_Standard_F"] = 'en-GB-Standard-N', -- [13] FEMALE
["en_GB_Standard_O"] = 'en-GB-Standard-O', -- [12] MALE
["en_GB_Standard_N"] = 'en-GB-Standard-N', -- [13] FEMALE
["en_US_Standard_A"] = 'en-US-Standard-A', -- [14] MALE
["en_US_Standard_B"] = 'en-US-Standard-B', -- [15] MALE
["en_US_Standard_C"] = 'en-US-Standard-C', -- [16] FEMALE
["en_US_Standard_D"] = 'en-US-Standard-D', -- [17] MALE
["en_US_Standard_E"] = 'en-US-Standard-E', -- [18] FEMALE
["en_US_Standard_F"] = 'en-US-Standard-F', -- [19] FEMALE
["en_US_Standard_G"] = 'en-US-Standard-G', -- [20] FEMALE
["en_US_Standard_H"] = 'en-US-Standard-H', -- [21] FEMALE
["en_US_Standard_I"] = 'en-US-Standard-I', -- [22] MALE
["en_US_Standard_J"] = 'en-US-Standard-J', -- [23] MALE
["en_GB_Standard_A"] = 'en-GB-Standard-A', -- Female
["en_GB_Standard_B"] = 'en-GB-Standard-B', -- Male
["en_GB_Standard_C"] = 'en-GB-Standard-C', -- Female
["en_GB_Standard_D"] = 'en-GB-Standard-D', -- Male
["en_GB_Standard_F"] = 'en-GB-Standard-F', -- Female
["en_GB_Standard_N"] = 'en-GB-Standard-N', -- Female
["en_GB_Standard_O"] = 'en-GB-Standard-O', -- Male
-- US
["en_US_Standard_A"] = 'en-US-Standard-A', -- Male
["en_US_Standard_B"] = 'en-US-Standard-B', -- Male
["en_US_Standard_C"] = 'en-US-Standard-C', -- Female
["en_US_Standard_D"] = 'en-US-Standard-D', -- Male
["en_US_Standard_E"] = 'en-US-Standard-E', -- Female
["en_US_Standard_F"] = 'en-US-Standard-F', -- Female
["en_US_Standard_G"] = 'en-US-Standard-G', -- Female
["en_US_Standard_H"] = 'en-US-Standard-H', -- Female
["en_US_Standard_I"] = 'en-US-Standard-I', -- Male
["en_US_Standard_J"] = 'en-US-Standard-J', -- Male
-- 2025 catalog changes
["fr_FR_Standard_A"] = "fr-FR-Standard-F", -- Female
["fr_FR_Standard_B"] = "fr-FR-Standard-G", -- Male
@@ -474,14 +478,15 @@ MSRS.Voices = {
["fr_FR_Standard_G"] = "fr-FR-Standard-G", -- Male
["fr_FR_Standard_F"] = "fr-FR-Standard-F", -- Female
-- 2025 catalog changes
["de_DE_Standard_A"] = "de-DE-Standard-G", -- Female
["de_DE_Standard_B"] = "de-DE-Standard-H", -- Male
["de_DE_Standard_C"] = "de-DE-Standard-G", -- Female
["de_DE_Standard_D"] = "de-DE-Standard-H", -- Male
["de_DE_Standard_E"] = "de-DE-Standard-H", -- Male
["de_DE_Standard_F"] = "de-DE-Standard-G", -- Female
["de_DE_Standard_H"] = "de-DE-Standard-H", -- Male
["de_DE_Standard_G"] = "de-DE-Standard-G", -- Female
["de_DE_Standard_A"] = 'de-DE-Standard-A', -- Female
["de_DE_Standard_B"] = 'de-DE-Standard-B', -- Male
["de_DE_Standard_C"] = 'de-DE-Standard-C', -- Female
["de_DE_Standard_D"] = 'de-DE-Standard-D', -- Male
["de_DE_Standard_E"] = 'de-DE-Standard-E', -- Male
["de_DE_Standard_F"] = 'de-DE-Standard-F', -- Female
["de_DE_Standard_G"] = 'de-DE-Standard-G', -- Female
["de_DE_Standard_H"] = 'de-DE-Standard-H', -- Male
-- ES
["es_ES_Standard_A"] = "es-ES-Standard-E", -- Female
["es_ES_Standard_B"] = "es-ES-Standard-F", -- Male
["es_ES_Standard_C"] = "es-ES-Standard-E", -- Female
@@ -497,32 +502,36 @@ MSRS.Voices = {
["it_IT_Standard_F"] = "it-IT-Standard-F", -- Male
},
Wavenet = {
["en_AU_Wavenet_A"] = 'en-AU-Wavenet-A', -- [1] FEMALE
["en_AU_Wavenet_B"] = 'en-AU-Wavenet-B', -- [2] MALE
["en_AU_Wavenet_C"] = 'en-AU-Wavenet-C', -- [3] FEMALE
["en_AU_Wavenet_D"] = 'en-AU-Wavenet-D', -- [4] MALE
["en_IN_Wavenet_A"] = 'en-IN-Wavenet-A', -- [5] FEMALE
["en_IN_Wavenet_B"] = 'en-IN-Wavenet-B', -- [6] MALE
["en_IN_Wavenet_C"] = 'en-IN-Wavenet-C', -- [7] MALE
["en_IN_Wavenet_D"] = 'en-IN-Wavenet-D', -- [8] FEMALE
["en_AU_Wavenet_A"] = 'en-AU-Wavenet-A', -- Female
["en_AU_Wavenet_B"] = 'en-AU-Wavenet-B', -- Male
["en_AU_Wavenet_C"] = 'en-AU-Wavenet-C', -- Female
["en_AU_Wavenet_D"] = 'en-AU-Wavenet-D', -- Male
-- IN
["en_IN_Wavenet_A"] = 'en-IN-Wavenet-A', -- Female
["en_IN_Wavenet_B"] = 'en-IN-Wavenet-B', -- Male
["en_IN_Wavenet_C"] = 'en-IN-Wavenet-C', -- Male
["en_IN_Wavenet_D"] = 'en-IN-Wavenet-D', -- Female
["en_IN_Wavenet_E"] = 'en-IN-Wavenet-E', -- Female
["en_IN_Wavenet_F"] = 'en-IN-Wavenet-F', -- Male
-- 2025 changes
["en_GB_Wavenet_A"] = 'en-GB-Wavenet-N', -- [9] FEMALE
["en_GB_Wavenet_B"] = 'en-GB-Wavenet-O', -- [10] MALE
["en_GB_Wavenet_C"] = 'en-GB-Wavenet-N', -- [11] FEMALE
["en_GB_Wavenet_D"] = 'en-GB-Wavenet-O', -- [12] MALE
["en_GB_Wavenet_F"] = 'en-GB-Wavenet-N', -- [13] FEMALE
["en_GB_Wavenet_A"] = 'en-GB-Wavenet-A', -- [9] FEMALE
["en_GB_Wavenet_B"] = 'en-GB-Wavenet-B', -- [10] MALE
["en_GB_Wavenet_C"] = 'en-GB-Wavenet-C', -- [11] FEMALE
["en_GB_Wavenet_D"] = 'en-GB-Wavenet-D', -- [12] MALE
["en_GB_Wavenet_F"] = 'en-GB-Wavenet-F', -- [13] FEMALE
["en_GB_Wavenet_O"] = 'en-GB-Wavenet-O', -- [12] MALE
["en_GB_Wavenet_N"] = 'en-GB-Wavenet-N', -- [13] FEMALE
["en_US_Wavenet_A"] = 'en-US-Wavenet-N', -- [14] MALE
["en_US_Wavenet_B"] = 'en-US-Wavenet-B', -- [15] MALE
["en_US_Wavenet_C"] = 'en-US-Wavenet-C', -- [16] FEMALE
["en_US_Wavenet_D"] = 'en-US-Wavenet-D', -- [17] MALE
["en_US_Wavenet_E"] = 'en-US-Wavenet-E', -- [18] FEMALE
["en_US_Wavenet_F"] = 'en-US-Wavenet-F', -- [19] FEMALE
["en_US_Wavenet_G"] = 'en-US-Wavenet-G', -- [20] FEMALE
["en_US_Wavenet_H"] = 'en-US-Wavenet-H', -- [21] FEMALE
["en_US_Wavenet_I"] = 'en-US-Wavenet-I', -- [22] MALE
["en_US_Wavenet_J"] = 'en-US-Wavenet-J', -- [23] MALE
["en_GB_Wavenet_N"] = 'en-GB-Wavenet-N', -- [13] FEMALE
-- US
["en_US_Wavenet_A"] = 'en-US-Wavenet-A', -- Male
["en_US_Wavenet_B"] = 'en-US-Wavenet-B', -- Male
["en_US_Wavenet_C"] = 'en-US-Wavenet-C', -- Female
["en_US_Wavenet_D"] = 'en-US-Wavenet-D', -- Male
["en_US_Wavenet_E"] = 'en-US-Wavenet-E', -- Female
["en_US_Wavenet_F"] = 'en-US-Wavenet-F', -- Female
["en_US_Wavenet_G"] = 'en-US-Wavenet-G', -- Female
["en_US_Wavenet_H"] = 'en-US-Wavenet-H', -- Female
["en_US_Wavenet_I"] = 'en-US-Wavenet-I', -- Male
["en_US_Wavenet_J"] = 'en-US-Wavenet-J', -- Male
-- 2025 catalog changes
["fr_FR_Wavenet_A"] = "fr-FR-Wavenet-F", -- Female
["fr_FR_Wavenet_B"] = "fr-FR-Wavenet-G", -- Male
@@ -532,14 +541,15 @@ MSRS.Voices = {
["fr_FR_Wavenet_G"] = "fr-FR-Wavenet-G", -- Male
["fr_FR_Wavenet_F"] = "fr-FR-Wavenet-F", -- Female
-- 2025 catalog changes
["de_DE_Wavenet_A"] = "de-DE-Wavenet-G", -- Female
["de_DE_Wavenet_B"] = "de-DE-Wavenet-H", -- Male
["de_DE_Wavenet_C"] = "de-DE-Wavenet-G", -- Female
["de_DE_Wavenet_D"] = "de-DE-Wavenet-H", -- Male
["de_DE_Wavenet_E"] = "de-DE-Wavenet-H", -- Male
["de_DE_Wavenet_F"] = "de-DE-Wavenet-G", -- Female
["de_DE_Wavenet_H"] = "de-DE-Wavenet-H", -- Male
["de_DE_Wavenet_G"] = "de-DE-Wavenet-G", -- Female
["de_DE_Wavenet_A"] = 'de-DE-Wavenet-A', -- Female
["de_DE_Wavenet_B"] = 'de-DE-Wavenet-B', -- Male
["de_DE_Wavenet_C"] = 'de-DE-Wavenet-C', -- Female
["de_DE_Wavenet_D"] = 'de-DE-Wavenet-D', -- Male
["de_DE_Wavenet_E"] = 'de-DE-Wavenet-E', -- Male
["de_DE_Wavenet_F"] = 'de-DE-Wavenet-F', -- Female
["de_DE_Wavenet_G"] = 'de-DE-Wavenet-G', -- Female
["de_DE_Wavenet_H"] = 'de-DE-Wavenet-H', -- Male
-- ES
["es_ES_Wavenet_B"] = "es-ES-Wavenet-E", -- Male
["es_ES_Wavenet_C"] = "es-ES-Wavenet-F", -- Female
["es_ES_Wavenet_D"] = "es-ES-Wavenet-E", -- Female
@@ -553,6 +563,134 @@ MSRS.Voices = {
["it_IT_Wavenet_E"] = "it-IT-Wavenet-E", -- Female
["it_IT_Wavenet_F"] = "it-IT-Wavenet-F", -- Male
} ,
Chirp3HD = {
["en_GB_Chirp3_HD_Aoede"] = 'en-GB-Chirp3-HD-Aoede', -- Female
["en_GB_Chirp3_HD_Charon"] = 'en-GB-Chirp3-HD-Charon', -- Male
["en_GB_Chirp3_HD_Fenrir"] = 'en-GB-Chirp3-HD-Fenrir', -- Male
["en_GB_Chirp3_HD_Kore"] = 'en-GB-Chirp3-HD-Kore', -- Female
["en_GB_Chirp3_HD_Leda"] = 'en-GB-Chirp3-HD-Leda', -- Female
["en_GB_Chirp3_HD_Orus"] = 'en-GB-Chirp3-HD-Orus', -- Male
["en_GB_Chirp3_HD_Puck"] = 'en-GB-Chirp3-HD-Puck', -- Male
["en_GB_Chirp3_HD_Zephyr"] = 'en-GB-Chirp3-HD-Zephyr', -- Female
--["de_DE_Chirp3_HD_Aoede"] = 'de-DE-Chirp3-HD-Aoede', -- Female (Datenfehler im Original)
["en_US_Chirp3_HD_Charon"] = 'en-US-Chirp3-HD-Charon', -- Male
["en_US_Chirp3_HD_Fenrir"] = 'en-US-Chirp3-HD-Fenrir', -- Male
["en_US_Chirp3_HD_Kore"] = 'en-US-Chirp3-HD-Kore', -- Female
["en_US_Chirp3_HD_Leda"] = 'en-US-Chirp3-HD-Leda', -- Female
["en_US_Chirp3_HD_Orus"] = 'en-US-Chirp3-HD-Orus', -- Male
["en_US_Chirp3_HD_Puck"] = 'en-US-Chirp3-HD-Puck', -- Male
--["de_DE_Chirp3_HD_Zephyr"] = 'de-DE-Chirp3-HD-Zephyr', -- Female (Datenfehler im Original)
-- DE
["de_DE_Chirp3_HD_Aoede"] = 'de-DE-Chirp3-HD-Aoede', -- Female
["de_DE_Chirp3_HD_Charon"] = 'de-DE-Chirp3-HD-Charon', -- Male
["de_DE_Chirp3_HD_Fenrir"] = 'de-DE-Chirp3-HD-Fenrir', -- Male
["de_DE_Chirp3_HD_Kore"] = 'de-DE-Chirp3-HD-Kore', -- Female
["de_DE_Chirp3_HD_Leda"] = 'de-DE-Chirp3-HD-Leda', -- Female
["de_DE_Chirp3_HD_Orus"] = 'de-DE-Chirp3-HD-Orus', -- Male
["de_DE_Chirp3_HD_Puck"] = 'de-DE-Chirp3-HD-Puck', -- Male
["de_DE_Chirp3_HD_Zephyr"] = 'de-DE-Chirp3-HD-Zephyr', -- Female
-- AU
["en_AU_Chirp3_HD_Aoede"] = 'en-AU-Chirp3-HD-Aoede', -- Female
["en_AU_Chirp3_HD_Charon"] = 'en-AU-Chirp3-HD-Charon', -- Male
["en_AU_Chirp3_HD_Fenrir"] = 'en-AU-Chirp3-HD-Fenrir', -- Male
["en_AU_Chirp3_HD_Kore"] = 'en-AU-Chirp3-HD-Kore', -- Female
["en_AU_Chirp3_HD_Leda"] = 'en-AU-Chirp3-HD-Leda', -- Female
["en_AU_Chirp3_HD_Orus"] = 'en-AU-Chirp3-HD-Orus', -- Male
["en_AU_Chirp3_HD_Puck"] = 'en-AU-Chirp3-HD-Puck', -- Male
["en_AU_Chirp3_HD_Zephyr"] = 'en-AU-Chirp3-HD-Zephyr', -- Female
-- IN
["en_IN_Chirp3_HD_Aoede"] = 'en-IN-Chirp3-HD-Aoede', -- Female
["en_IN_Chirp3_HD_Charon"] = 'en-IN-Chirp3-HD-Charon', -- Male
["en_IN_Chirp3_HD_Fenrir"] = 'en-IN-Chirp3-HD-Fenrir', -- Male
["en_IN_Chirp3_HD_Kore"] = 'en-IN-Chirp3-HD-Kore', -- Female
["en_IN_Chirp3_HD_Leda"] = 'en-IN-Chirp3-HD-Leda', -- Female
["en_IN_Chirp3_HD_Orus"] = 'en-IN-Chirp3-HD-Orus', -- Male
},
ChirpHD = {
["en_US_Chirp_HD_D"] = 'en-US-Chirp-HD-D', -- Male
["en_US_Chirp_HD_F"] = 'en-US-Chirp-HD-F', -- Female
["en_US_Chirp_HD_O"] = 'en-US-Chirp-HD-O', -- Female
-- DE
["de_DE_Chirp_HD_D"] = 'de-DE-Chirp-HD-D', -- Male
["de_DE_Chirp_HD_F"] = 'de-DE-Chirp-HD-F', -- Female
["de_DE_Chirp_HD_O"] = 'de-DE-Chirp-HD-O', -- Female
-- AU
["en_AU_Chirp_HD_D"] = 'en-AU-Chirp-HD-D', -- Male
["en_AU_Chirp_HD_F"] = 'en-AU-Chirp-HD-F', -- Female
["en_AU_Chirp_HD_O"] = 'en-AU-Chirp-HD-O', -- Female
-- IN
["en_IN_Chirp_HD_D"] = 'en-IN-Chirp-HD-D', -- Male
["en_IN_Chirp_HD_F"] = 'en-IN-Chirp-HD-F', -- Female
["en_IN_Chirp_HD_O"] = 'en-IN-Chirp-HD-O', -- Female
},
},
Neural2 = {
["en_GB_Neural2_A"] = 'en-GB-Neural2-A', -- Female
["en_GB_Neural2_B"] = 'en-GB-Neural2-B', -- Male
["en_GB_Neural2_C"] = 'en-GB-Neural2-C', -- Female
["en_GB_Neural2_D"] = 'en-GB-Neural2-D', -- Male
["en_GB_Neural2_F"] = 'en-GB-Neural2-F', -- Female
["en_GB_Neural2_N"] = 'en-GB-Neural2-N', -- Female
["en_GB_Neural2_O"] = 'en-GB-Neural2-O', -- Male
-- US
["en_US_Neural2_A"] = 'en-US-Neural2-A', -- Male
["en_US_Neural2_C"] = 'en-US-Neural2-C', -- Female
["en_US_Neural2_D"] = 'en-US-Neural2-D', -- Male
["en_US_Neural2_E"] = 'en-US-Neural2-E', -- Female
["en_US_Neural2_F"] = 'en-US-Neural2-F', -- Female
["en_US_Neural2_G"] = 'en-US-Neural2-G', -- Female
["en_US_Neural2_H"] = 'en-US-Neural2-H', -- Female
["en_US_Neural2_I"] = 'en-US-Neural2-I', -- Male
["en_US_Neural2_J"] = 'en-US-Neural2-J', -- Male
-- DE
["de_DE_Neural2_G"] = 'de-DE-Neural2-G', -- Female
["de_DE_Neural2_H"] = 'de-DE-Neural2-H', -- Male
-- AU
["en_AU_Neural2_A"] = 'en-AU-Neural2-A', -- Female
["en_AU_Neural2_B"] = 'en-AU-Neural2-B', -- Male
["en_AU_Neural2_C"] = 'en-AU-Neural2-C', -- Female
["en_AU_Neural2_D"] = 'en-AU-Neural2-D', -- Male
-- IN
["en_IN_Neural2_A"] = 'en-IN-Neural2-A', -- Female
["en_IN_Neural2_B"] = 'en-IN-Neural2-B', -- Male
["en_IN_Neural2_C"] = 'en-IN-Neural2-C', -- Male
["en_IN_Neural2_D"] = 'en-IN-Neural2-D', -- Female
},
News = {
["en_GB_News_G"] = 'en-GB-News-G', -- Female
["en_GB_News_H"] = 'en-GB-News-H', -- Female
["en_GB_News_I"] = 'en-GB-News-I', -- Female
["en_GB_News_J"] = 'en-GB-News-J', -- Male
["en_GB_News_K"] = 'en-GB-News-K', -- Male
["en_GB_News_L"] = 'en-GB-News-L', -- Male
["en_GB_News_M"] = 'en-GB-News-M', -- Male
-- US
["en_US_News_K"] = 'en-US-News-K', -- Female
["en_US_News_L"] = 'en-US-News-L', -- Female
["en_US_News_N"] = 'en-US-News-N', -- Male
-- AU
["en_AU_News_E"] = 'en-AU-News-E', -- Female
["en_AU_News_F"] = 'en-AU-News-F', -- Female
["en_AU_News_G"] = 'en-AU-News-G', -- Male
},
Casual = {
["en_US_Casual_K"] = 'en-US-Casual-K', -- Male
},
Polyglot = {
["en_US_Polyglot_1"] = 'en-US-Polyglot-1', -- Male
["de_DE_Polyglot_1"] = 'de-DE-Polyglot-1', -- Male
["en_AU_Polyglot_1"] = 'en-AU-Polyglot-1', -- Male
},
Studio = {
-- Englisch (UK) - Studio
["en_GB_Studio_B"] = 'en-GB-Studio-B', -- Male
["en_GB_Studio_C"] = 'en-GB-Studio-C', -- Female
-- Englisch (USA) - Studio
["en_US_Studio_O"] = 'en-US-Studio-O', -- Female
["en_US_Studio_Q"] = 'en-US-Studio-Q', -- Male
-- DE
["de_DE_Studio_B"] = 'de-DE-Studio-B', -- Male
["de_DE_Studio_C"] = 'de-DE-Studio-C', -- Female
},
}
@@ -632,7 +770,7 @@ end
-- set the path to the exe file via @{#MSRS.SetPath}.
--
-- @param #MSRS self
-- @param #string Path Path to SRS directory. Default `C:\\Program Files\\DCS-SimpleRadio-Standalone`.
-- @param #string Path Path to SRS directory. Default `C:\\Program Files\\DCS-SimpleRadio-Standalone\\ExternalAudio`.
-- @param #number Frequency Radio frequency in MHz. Default 143.00 MHz. Can also be given as a #table of multiple frequencies.
-- @param #number Modulation Radio modulation: 0=AM (default), 1=FM. See `radio.modulation.AM` and `radio.modulation.FM` enumerators. Can also be given as a #table of multiple modulations.
-- @param #string Backend Backend used: `MSRS.Backend.SRSEXE` (default) or `MSRS.Backend.GRPC`.
@@ -767,13 +905,13 @@ end
--- Set path to SRS install directory. More precisely, path to where the `DCS-SR-ExternalAudio.exe` is located.
-- @param #MSRS self
-- @param #string Path Path to the directory, where the sound file is located. Default is `C:\\Program Files\\DCS-SimpleRadio-Standalone`.
-- @param #string Path Path to the directory, where the sound file is located. Default is `C:\\Program Files\\DCS-SimpleRadio-Standalone\\ExternalAudio`.
-- @return #MSRS self
function MSRS:SetPath(Path)
self:F( {Path=Path} )
-- Set path.
self.path=Path or "C:\\Program Files\\DCS-SimpleRadio-Standalone"
self.path=Path or "C:\\Program Files\\DCS-SimpleRadio-Standalone\\ExternalAudio"
-- Remove (back)slashes.
local n=1 ; local nmax=1000
@@ -1817,7 +1955,7 @@ end
--
-- -- Moose MSRS default Config
-- MSRS_Config = {
-- Path = "C:\\Program Files\\DCS-SimpleRadio-Standalone", -- Path to SRS install directory.
-- Path = "C:\\Program Files\\DCS-SimpleRadio-Standalone\\ExternalAudio", -- Path to SRS install directory.
-- Port = 5002, -- Port of SRS server. Default 5002.
-- Backend = "srsexe", -- Interface to SRS: "srsexe" or "grpc".
-- Frequency = {127, 243}, -- Default frequences. Must be a table 1..n entries!
@@ -1837,7 +1975,7 @@ end
-- -- Google Cloud
-- gcloud = {
-- voice = "en-GB-Standard-A", -- The Google Cloud voice to use (see https://cloud.google.com/text-to-speech/docs/voices).
-- credentials="C:\\Program Files\\DCS-SimpleRadio-Standalone\\yourfilename.json", -- Full path to credentials JSON file (only for SRS-TTS.exe backend)
-- credentials="C:\\Program Files\\DCS-SimpleRadio-Standalone\\ExternalAudio\\yourfilename.json", -- Full path to credentials JSON file (only for SRS-TTS.exe backend)
-- key="Your access Key", -- Google API access key (only for DCS-gRPC backend)
-- },
-- -- Amazon Web Service
@@ -1905,7 +2043,7 @@ function MSRS:LoadConfigFile(Path,Filename)
local Self = self or MSRS --#MSRS
Self.path = MSRS_Config.Path or "C:\\Program Files\\DCS-SimpleRadio-Standalone"
Self.path = MSRS_Config.Path or "C:\\Program Files\\DCS-SimpleRadio-Standalone\\ExternalAudio"
Self.port = MSRS_Config.Port or 5002
Self.backend = MSRS_Config.Backend or MSRS.Backend.SRSEXE
Self.frequencies = MSRS_Config.Frequency or {127,243}
@@ -29,6 +29,8 @@
--- Governs multiple missions, the tasking and the reporting.
--
-- ![Banner Image](..\Images\deprecated.png)
--
-- Command centers govern missions, communicates the task assignments between human players of the coalition, and manages the menu flow.
-- It can assign a random task to a player when requested.
@@ -5,6 +5,8 @@
-- The @{#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.
--
-- ![Banner Image](..\Images\deprecated.png)
--
-- 1.1) DETECTION_MANAGER constructor:
-- -----------------------------------
-- * @{#DETECTION_MANAGER.New}(): Create a new DETECTION_MANAGER instance.
@@ -27,6 +27,8 @@
--- Models goals to be achieved and can contain multiple tasks to be executed to achieve the goals.
--
-- ![Banner Image](..\Images\deprecated.png)
--
-- A mission contains multiple tasks and can be of different task types.
-- These tasks need to be assigned to human players to be executed.
--
+2
View File
@@ -12,6 +12,8 @@
--
-- ===
--
-- ![Banner Image](..\Images\deprecated.png)
--
-- # 1) Tasking from a player perspective.
--
-- Tasking can be controlled by using the "other" menu in the radio menu of the player group.
@@ -17,6 +17,8 @@
---
-- # TASKINFO class, extends @{Core.Base#BASE}
--
-- ![Banner Image](..\Images\deprecated.png)
--
-- ## The TASKINFO class implements the methods to contain information and display information of a task.
--
-- # Developer Note
@@ -20,6 +20,9 @@ do -- TASK_A2A
--- Defines Air To Air tasks for a @{Core.Set} of Target Units,
-- based on the tasking capabilities defined in @{Tasking.Task#TASK}.
--
-- ![Banner Image](..\Images\deprecated.png)
--
-- The TASK_A2A is implemented using a @{Core.Fsm#FSM_TASK}, and has the following statuses:
--
-- * **None**: Start of the process
@@ -30,6 +30,8 @@ do -- TASK_A2A_DISPATCHER
-- @extends Tasking.DetectionManager#DETECTION_MANAGER
--- Orchestrates the dynamic dispatching of tasks upon groups of detected units determined a @{Core.Set} of EWR installation groups.
--
-- ![Banner Image](..\Images\deprecated.png)
--
-- ![Banner Image](..\Presentations\TASK_A2A_DISPATCHER\Dia3.JPG)
--
@@ -20,6 +20,9 @@ do -- TASK_A2G
--- The TASK_A2G class defines Air To Ground tasks for a @{Core.Set} of Target Units,
-- based on the tasking capabilities defined in @{Tasking.Task#TASK}.
--
-- ![Banner Image](..\Images\deprecated.png)
--
-- The TASK_A2G is implemented using a @{Core.Fsm#FSM_TASK}, and has the following statuses:
--
-- * **None**: Start of the process
@@ -33,6 +33,8 @@ do -- TASK_A2G_DISPATCHER
-- @extends Tasking.DetectionManager#DETECTION_MANAGER
--- Orchestrates dynamic **A2G Task Dispatching** based on the detection results of a linked @{Functional.Detection} object.
--
-- ![Banner Image](..\Images\deprecated.png)
--
-- It uses the Tasking System within the MOOSE framework, which is a multi-player Tasking Orchestration system.
-- It provides a truly dynamic battle environment for pilots and ground commanders to engage upon,
@@ -10,6 +10,8 @@
--
-- ===
--
-- ![Banner Image](..\Images\deprecated.png)
--
-- ## Test Missions:
--
-- Test missions can be located on the main GITHUB site.
@@ -1176,7 +1178,7 @@ do -- TASK_CARGO
end
---@param Color Might be SMOKECOLOR.Blue, SMOKECOLOR.Red SMOKECOLOR.Orange, SMOKECOLOR.White or SMOKECOLOR.Green
--@param Color Might be SMOKECOLOR.Blue, SMOKECOLOR.Red SMOKECOLOR.Orange, SMOKECOLOR.White or SMOKECOLOR.Green
function TASK_CARGO:SetSmokeColor(SmokeColor)
-- Makes sure Coloe is set
if SmokeColor == nil then
@@ -76,6 +76,8 @@ do -- TASK_CAPTURE_DISPATCHER
--- Implements the dynamic dispatching of capture zone tasks.
--
-- ![Banner Image](..\Images\deprecated.png)
--
-- The **TASK_CAPTURE_DISPATCHER** allows you to setup various tasks for let human
-- players capture zones in a co-operation effort.
--
@@ -20,6 +20,8 @@ do -- TASK_ZONE_GOAL
--- # TASK_ZONE_GOAL class, extends @{Tasking.Task#TASK}
--
-- ![Banner Image](..\Images\deprecated.png)
--
-- The TASK_ZONE_GOAL class defines the task to protect or capture a protection zone.
-- The TASK_ZONE_GOAL is implemented using a @{Core.Fsm#FSM_TASK}, and has the following statuses:
--
@@ -44,6 +44,8 @@
--
-- ===
--
-- ![Banner Image](..\Images\deprecated.png)
--
-- Please read through the @{Tasking.Task_CARGO} process to understand the mechanisms of tasking and cargo tasking and handling.
--
-- The cargo will be a downed pilot, which is located somwhere on the battlefield. Use the menus system and facilities to
@@ -2,6 +2,8 @@
--
-- The **TASK_CARGO_DISPATCHER** allows you to setup various tasks for let human
-- players transport cargo as part of a task.
--
-- ![Banner Image](..\Images\deprecated.png)
--
-- The cargo dispatcher will implement for you mechanisms to create cargo transportation tasks:
--
@@ -1,5 +1,7 @@
--- **Tasking** - Models tasks for players to transport cargo.
--
-- ![Banner Image](..\Images\deprecated.png)
--
-- **Specific features:**
--
-- * Creates a task to transport #Cargo.Cargo to and between deployment zones.
@@ -2,6 +2,8 @@
--
-- ===
--
-- ![Banner Image](..\Images\deprecated.png)
--
-- 1) @{Tasking.Task_Manager#TASK_MANAGER} class, extends @{Core.Fsm#FSM}
-- ===
-- The @{Tasking.Task_Manager#TASK_MANAGER} class defines the core functions to report tasks to groups.
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -168,16 +168,25 @@
-- * @{#CONTROLLABLE.OptionAlarmStateGreen}
-- * @{#CONTROLLABLE.OptionAlarmStateRed}
--
-- ## 5.4) Jettison weapons:
-- ## 5.4) [AIR] Jettison weapons:
--
-- * @{#CONTROLLABLE.OptionAllowJettisonWeaponsOnThreat}
-- * @{#CONTROLLABLE.OptionKeepWeaponsOnThreat}
--
-- ## 5.5) Air-2-Air missile attack range:
-- ## 5.5) [AIR] Air-2-Air missile attack range:
-- * @{#CONTROLLABLE.OptionAAAttackRange}(): Defines the usage of A2A missiles against possible targets.
--
-- # 6) [GROUND] IR Maker Beacons for GROUPs and UNITs
-- * @{#CONTROLLABLE:NewIRMarker}(): Create a blinking IR Marker on a GROUP or UNIT.
--
-- # 7) [HELICOPTER] Units prefer vertical landing and takeoffs:
-- * @{#CONTROLLABLE.OptionPreferVerticalLanding}(): Set aircraft to prefer vertical landing and takeoff.
--
-- # 8) [AIRCRAFT] Landing approach options
-- * @{#CONTROLLABLE.SetOptionLandingStraightIn}(): Landing approach straight in.
-- * @{#CONTROLLABLE.SetOptionLandingForcePair}(): Landing approach in pairs for groups > 1 unit.
-- * @{#CONTROLLABLE.SetOptionLandingRestrictPair}(): Landing approach single.
-- * @{#CONTROLLABLE.SetOptionLandingOverheadBreak}(): Landing approach overhead break.
--
-- @field #CONTROLLABLE
CONTROLLABLE = {
@@ -994,6 +1003,65 @@ function CONTROLLABLE:CommandSetFrequencyForUnit(Frequency,Modulation,Power,Unit
return self
end
--- [AIR] Set smoke on or off. See [DCS command smoke on off](https://wiki.hoggitworld.com/view/DCS_command_smoke_on_off)
-- @param #CONTROLLABLE self
-- @param #boolean OnOff Set to true for on and false for off. Defaults to true.
-- @param #number Delay (Optional) Delay the command by this many seconds.
-- @return #CONTROLLABLE self
function CONTROLLABLE:CommandSmokeOnOff(OnOff, Delay)
local switch = (OnOff == nil) and true or OnOff
local command = {
id = 'SMOKE_ON_OFF',
params = {
value = switch
}
}
if Delay and Delay>0 then
SCHEDULER:New(nil,self.CommandSmokeOnOff,{self,switch},Delay)
else
self:SetCommand(command)
end
return self
end
--- [AIR] Set smoke on. See [DCS command smoke on off](https://wiki.hoggitworld.com/view/DCS_command_smoke_on_off)
-- @param #CONTROLLABLE self
-- @param #number Delay (Optional) Delay the command by this many seconds.
-- @return #CONTROLLABLE self
function CONTROLLABLE:CommandSmokeON(Delay)
local command = {
id = 'SMOKE_ON_OFF',
params = {
value = true
}
}
if Delay and Delay>0 then
SCHEDULER:New(nil,self.CommandSmokeON,{self},Delay)
else
self:SetCommand(command)
end
return self
end
--- [AIR] Set smoke off. See [DCS command smoke on off](https://wiki.hoggitworld.com/view/DCS_command_smoke_on_off)
-- @param #CONTROLLABLE self
-- @param #number Delay (Optional) Delay the command by this many seconds.
-- @return #CONTROLLABLE self
function CONTROLLABLE:CommandSmokeOFF(Delay)
local command = {
id = 'SMOKE_ON_OFF',
params = {
value = false
}
}
if Delay and Delay>0 then
SCHEDULER:New(nil,self.CommandSmokeOFF,{self},Delay)
else
self:SetCommand(command)
end
return self
end
--- Set EPLRS data link on/off.
-- @param #CONTROLLABLE self
-- @param #boolean SwitchOnOff If true (or nil) switch EPLRS on. If false switch off.
@@ -1373,7 +1441,7 @@ end
-- @param #number Speed The speed [m/s] flying when holding the position.
-- @return #CONTROLLABLE self
function CONTROLLABLE:TaskOrbitCircleAtVec2( Point, Altitude, Speed )
self:F2( { self.ControllableName, Point, Altitude, Speed } )
--self:F2( { self.ControllableName, Point, Altitude, Speed } )
local DCSTask = {
id = 'Orbit',
@@ -2787,7 +2855,7 @@ do -- Route methods
-- @param Core.Zone#ZONE Zone The zone where to route to.
-- @param #boolean Randomize Defines whether to target point gets randomized within the Zone.
-- @param #number Speed The speed in m/s. Default is 5.555 m/s = 20 km/h.
-- @param Core.Base#FORMATION Formation The formation string.
-- @param DCS#FORMATION Formation The formation string.
function CONTROLLABLE:TaskRouteToZone( Zone, Randomize, Speed, Formation )
self:F2( Zone )
@@ -2847,7 +2915,7 @@ do -- Route methods
-- @param #CONTROLLABLE self
-- @param DCS#Vec2 Vec2 The Vec2 where to route to.
-- @param #number Speed The speed in m/s. Default is 5.555 m/s = 20 km/h.
-- @param Core.Base#FORMATION Formation The formation string.
-- @param DCS#FORMATION Formation The formation string.
function CONTROLLABLE:TaskRouteToVec2( Vec2, Speed, Formation )
local DCSControllable = self:GetDCSObject()
@@ -3570,6 +3638,26 @@ function CONTROLLABLE:OptionROTPassiveDefense()
return nil
end
--- Helicopter - prefer vertical landing.
-- @param #CONTROLLABLE self
-- @return #CONTROLLABLE self
function CONTROLLABLE:OptionPreferVerticalLanding()
self:F2( { self.ControllableName } )
local DCSControllable = self:GetDCSObject()
if DCSControllable then
local Controller = self:_GetController()
if self:IsAir() then
Controller:setOption( AI.Option.Air.id.PREFER_VERTICAL, true )
end
return self
end
return nil
end
--- Can the CONTROLLABLE evade on enemy fire?
-- @param #CONTROLLABLE self
-- @return #boolean
@@ -4075,7 +4163,7 @@ function CONTROLLABLE:OptionRestrictBurner( RestrictBurner )
end
--- Sets Controllable Option for A2A attack range for AIR FIGHTER units.
--- [AIR] Sets Controllable Option for A2A attack range for AIR FIGHTER units.
-- @param #CONTROLLABLE self
-- @param #number range Defines the range
-- @return #CONTROLLABLE self
@@ -4100,6 +4188,66 @@ function CONTROLLABLE:OptionAAAttackRange( range )
return nil
end
--- [GROUND/AAA] Sets Controllable Option for Ground AAA minimum firing height.
-- @param #CONTROLLABLE self
-- @param #number meters The minimum height in meters.
-- @return #CONTROLLABLE self
function CONTROLLABLE:OptionAAAMinFiringHeightMeters(meters)
self:F2( { self.ControllableName } )
local meters = meters or 20
local DCSControllable = self:GetDCSObject()
if DCSControllable then
local Controller = self:_GetController()
if Controller then
if self:IsGround() then
self:SetOption(27, meters)
end
end
return self
end
return nil
end
--- [GROUND/AAA] Sets Controllable Option for Ground AAA maximum firing height.
-- @param #CONTROLLABLE self
-- @param #number meters The maximum height in meters.
-- @return #CONTROLLABLE self
function CONTROLLABLE:OptionAAAMaxFiringHeightMeters(meters)
self:F2( { self.ControllableName } )
local meters = meters or 1000
local DCSControllable = self:GetDCSObject()
if DCSControllable then
local Controller = self:_GetController()
if Controller then
if self:IsGround() then
self:SetOption(29, meters)
end
end
return self
end
return nil
end
--- [GROUND/AAA] Sets Controllable Option for Ground AAA minimum firing height.
-- @param #CONTROLLABLE self
-- @param #number feet The minimum height in feet.
-- @return #CONTROLLABLE self
function CONTROLLABLE:OptionAAAMinFiringHeightFeet(feet)
self:F2( { self.ControllableName } )
local feet = feet or 60
return self:OptionAAAMinFiringHeightMeters(UTILS.FeetToMeters(feet))
end
--- [GROUND/AAA] Sets Controllable Option for Ground AAA maximum firing height.
-- @param #CONTROLLABLE self
-- @param #number feet The maximum height in feet.
-- @return #CONTROLLABLE self
function CONTROLLABLE:OptionAAAMaxFiringHeightfeet(feet)
self:F2( { self.ControllableName } )
local feet = feet or 3000
return self:OptionAAAMaxFiringHeightMeters(UTILS.FeetToMeters(feet))
end
--- Defines the range at which a GROUND unit/group is allowed to use its weapons automatically.
-- @param #CONTROLLABLE self
-- @param #number EngageRange Engage range limit in percent (a number between 0 and 100). Default 100.
@@ -4124,6 +4272,50 @@ function CONTROLLABLE:OptionEngageRange( EngageRange )
return nil
end
--- [AIR] Set how the AI lands on an airfield. Here: Straight in.
-- @param #CONTROLLABLE self
-- @return #CONTROLLABLE self
function CONTROLLABLE:SetOptionLandingStraightIn()
self:F2( { self.ControllableName } )
if self:IsAir() then
self:SetOption("36","0")
end
return self
end
--- [AIR] Set how the AI lands on an airfield. Here: In pairs (if > 1 aircraft in group)
-- @param #CONTROLLABLE self
-- @return #CONTROLLABLE self
function CONTROLLABLE:SetOptionLandingForcePair()
self:F2( { self.ControllableName } )
if self:IsAir() then
self:SetOption("36","1")
end
return self
end
--- [AIR] Set how the AI lands on an airfield. Here: No landing in pairs.
-- @param #CONTROLLABLE self
-- @return #CONTROLLABLE self
function CONTROLLABLE:SetOptionLandingRestrictPair()
self:F2( { self.ControllableName } )
if self:IsAir() then
self:SetOption("36","2")
end
return self
end
--- [AIR] Set how the AI lands on an airfield. Here: Overhead break.
-- @param #CONTROLLABLE self
-- @return #CONTROLLABLE self
function CONTROLLABLE:SetOptionLandingOverheadBreak()
self:F2( { self.ControllableName } )
if self:IsAir() then
self:SetOption("36","3")
end
return self
end
--- [AIR] Set how the AI uses the onboard radar.
-- @param #CONTROLLABLE self
-- @param #number Option Options are: `NEVER = 0, FOR_ATTACK_ONLY = 1,FOR_SEARCH_IF_REQUIRED = 2, FOR_CONTINUOUS_SEARCH = 3`
+121 -49
View File
@@ -2,17 +2,17 @@
--
-- ## Main Features:
--
-- * Convenient access to DCS API functions
-- * Convenient access to Ground Crew created cargo items.
--
-- ===
--
-- ## Example Missions:
--
-- Demo missions can be found on [github](https://github.com/FlightControl-Master/MOOSE_Demos/tree/master/Wrapper/Storage).
-- Demo missions can be found on [github](https://github.com/FlightControl-Master/MOOSE_Demos/tree/master/).
--
-- ===
--
-- ### Author: **Applevangelist**
-- ### Author: **Applevangelist**; additional checks **Chesster**
--
-- ===
-- @module Wrapper.DynamicCargo
@@ -108,6 +108,9 @@ DYNAMICCARGO.State = {
-- @type DYNAMICCARGO.AircraftTypes
DYNAMICCARGO.AircraftTypes = {
["CH-47Fbl1"] = "CH-47Fbl1",
["Mi-8MTV2"] = "Mi-8MTV2",
["Mi-8MT"] = "Mi-8MT",
["C-130J-30"] = "C-130J-30",
}
--- Helo types possible.
@@ -120,17 +123,36 @@ DYNAMICCARGO.AircraftDimensions = {
["length"] = 11,
["ropelength"] = 30,
},
["Mi-8MTV2"] = {
["width"] = 6,
["height"] = 6,
["length"] = 15,
["ropelength"] = 30,
},
["Mi-8MT"] = {
["width"] = 6,
["height"] = 6,
["length"] = 15,
["ropelength"] = 30,
},
["C-130J-30"] = {
["width"] = 4,
["height"] = 12,
["length"] = 35,
["ropelength"] = 0,
},
}
--- DYNAMICCARGO class version.
-- @field #string version
DYNAMICCARGO.version="0.0.5"
DYNAMICCARGO.version="0.1.0"
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO list
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO: A lot...
-- DONE: Added Mi-8 type and dimensions
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Constructor
@@ -183,7 +205,7 @@ end
-- @param #DYNAMICCARGO self
-- @return DCS static object
function DYNAMICCARGO:GetDCSObject()
local DCSStatic = Unit.getByName( self.StaticName )
local DCSStatic = StaticObject.getByName( self.StaticName ) or Unit.getByName( self.StaticName )
if DCSStatic then
return DCSStatic
end
@@ -227,7 +249,7 @@ end
-- @param #DYNAMICCARGO self
-- @return #boolean Outcome
function DYNAMICCARGO:IsUnloaded()
if self.CargoState and self.CargoState == DYNAMICCARGO.State.REMOVED then
if self.CargoState and self.CargoState == DYNAMICCARGO.State.UNLOADED then
return true
else
return false
@@ -238,7 +260,7 @@ end
-- @param #DYNAMICCARGO self
-- @return #boolean Outcome
function DYNAMICCARGO:IsRemoved()
if self.CargoState and self.CargoState == DYNAMICCARGO.State.UNLOADED then
if self.CargoState and self.CargoState == DYNAMICCARGO.State.REMOVED then
return true
else
return false
@@ -376,6 +398,33 @@ end
-- Private Functions
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- [Internal] _Get helo hovering intel
-- @param #DYNAMICCARGO self
-- @param Wrapper.Unit#UNIT Unit The Unit to test
-- @param #number ropelength Ropelength to test
-- @return #boolean Outcome
function DYNAMICCARGO:_HeloHovering(Unit,ropelength)
local DCSUnit = Unit:GetDCSObject() --DCS#Unit
local hovering = false
local Height = 0
if DCSUnit then
local UnitInAir = DCSUnit:inAir()
local UnitCategory = DCSUnit:getDesc().category
if UnitInAir == true and UnitCategory == 1 then
local VelocityVec3 = DCSUnit:getVelocity()
local Velocity = UTILS.VecNorm(VelocityVec3)
local Coordinate = DCSUnit:getPoint()
local LandHeight = land.getHeight({ x = Coordinate.x, y = Coordinate.z })
Height = Coordinate.y - LandHeight
if Velocity < 1 and Height <= ropelength and Height > 6 then -- hover lower than ropelength but higher than the normal FARP height.
hovering = true
end
end
return hovering, Height
end
return false
end
--- [Internal] _Get Possible Player Helo Nearby
-- @param #DYNAMICCARGO self
-- @param Core.Point#COORDINATE pos
@@ -393,30 +442,37 @@ function DYNAMICCARGO:_GetPossibleHeloNearby(pos,loading)
local name = helo:GetPlayerName() or _DATABASE:_FindPlayerNameByUnitName(helo:GetName()) or "None"
self:T(self.lid.." Checking: "..name)
local hpos = helo:GetCoordinate()
-- TODO Unloading via sling load?
--local inair = hpos.y-hpos:GetLandHeight() > 4.5 and true or false -- Standard FARP is 4.5m
local inair = helo:InAir()
self:T(self.lid.." InAir: AGL/InAir: "..hpos.y-hpos:GetLandHeight().."/"..tostring(inair))
-- TODO Check unloading via sling load?
local typename = helo:GetTypeName()
if hpos and typename and inair == false then
local dimensions = DYNAMICCARGO.AircraftDimensions[typename]
if dimensions then
local delta2D = hpos:Get2DDistance(pos)
local delta3D = hpos:Get3DDistance(pos)
if self.testing then
self:T(string.format("Cargo relative position: 2D %dm | 3D %dm",delta2D,delta3D))
self:T(string.format("Helo dimension: length %dm | width %dm | rope %dm",dimensions.length,dimensions.width,dimensions.ropelength))
end
if loading~=true and delta2D > dimensions.length or delta2D > dimensions.width or delta3D > dimensions.ropelength then
success = true
Helo = helo
Playername = name
end
if loading == true and delta2D < dimensions.length or delta2D < dimensions.width or delta3D < dimensions.ropelength then
success = true
Helo = helo
Playername = name
end
local dimensions = DYNAMICCARGO.AircraftDimensions[typename]
local hovering, height = self:_HeloHovering(helo,dimensions.ropelength)
local helolanded = not helo:InAir()
self:T(self.lid.." InAir: AGL/Hovering: "..hpos.y-hpos:GetLandHeight().."/"..tostring(hovering))
if hpos and typename and dimensions then
local delta2D = hpos:Get2DDistance(pos)
local delta3D = hpos:Get3DDistance(pos)
if self.testing then
self:T(string.format("Cargo relative position: 2D %dm | 3D %dm",delta2D,delta3D))
self:T(string.format("Helo dimension: length %dm | width %dm | rope %dm",dimensions.length,dimensions.width,dimensions.ropelength))
self:T(string.format("Helo hovering: %s at %dm",tostring(hovering),height))
end
-- unloading from ground
if loading~=true and (delta2D > dimensions.length or delta2D > dimensions.width) and helolanded then -- Theoretically the cargo could still be attached to the sling if landed next to the cargo. But once moved again it would go back into loaded state once lifted again.
success = true
Helo = helo
Playername = name
end
-- unloading from hover/rope
if loading~=true and delta3D > dimensions.ropelength then
success = true
Helo = helo
Playername = name
end
-- loading
if loading == true and ((delta2D < dimensions.length and delta2D < dimensions.width and helolanded) or (delta3D == dimensions.ropelength and helo:InAir())) then -- Loaded via ground or sling
success = true
Helo = helo
Playername = name
end
end
end
@@ -434,20 +490,22 @@ function DYNAMICCARGO:_UpdatePosition()
self:T(string.format("Cargo position: x=%d, y=%d, z=%d",pos.x,pos.y,pos.z))
self:T(string.format("Last position: x=%d, y=%d, z=%d",self.LastPosition.x,self.LastPosition.y,self.LastPosition.z))
end
if UTILS.Round(UTILS.VecDist3D(pos,self.LastPosition),2) > 0.5 then
if UTILS.Round(UTILS.VecDist3D(pos,self.LastPosition),2) > 0.5 then -- This checks if the cargo has moved more than 0.5m since last check. If so then the cargo is loaded
---------------
-- LOAD Cargo
---------------
if self.CargoState == DYNAMICCARGO.State.NEW then
local isloaded, client, playername = self:_GetPossibleHeloNearby(pos,true)
if self.CargoState == DYNAMICCARGO.State.NEW or self.CargoState == DYNAMICCARGO.State.UNLOADED then
local isloaded, client, playername = self:_GetPossibleHeloNearby(pos,true)
self:T(self.lid.." moved! NEW -> LOADED by "..tostring(playername))
self.CargoState = DYNAMICCARGO.State.LOADED
self.Owner = playername
_DATABASE:CreateEventDynamicCargoLoaded(self)
_DATABASE:CreateEventDynamicCargoLoaded(self)
end
---------------
-- UNLOAD Cargo
---------------
elseif self.CargoState == DYNAMICCARGO.State.LOADED then
---------------
-- If the cargo is stationary then we need to end this condition here to check whether it is unloaded or still onboard or still hooked if anyone can hover that precisly
elseif self.CargoState == DYNAMICCARGO.State.LOADED then
-- TODO add checker if we are in flight somehow
-- ensure not just the helo is moving
local count = _DYNAMICCARGO_HELOS:CountAlive()
@@ -459,31 +517,27 @@ function DYNAMICCARGO:_UpdatePosition()
local isunloaded = true
local client
local playername = self.Owner
if count > 0 and (agl > 0 or self.testing) then
self:T(self.lid.." Possible alive helos: "..count or -1)
if agl ~= 0 or self.testing then
isunloaded, client, playername = self:_GetPossibleHeloNearby(pos,false)
end
if count > 0 then
self:T(self.lid.." Possible alive helos: "..count or -1)
isunloaded, client, playername = self:_GetPossibleHeloNearby(pos,false)
if isunloaded then
self:T(self.lid.." moved! LOADED -> UNLOADED by "..tostring(playername))
self.CargoState = DYNAMICCARGO.State.UNLOADED
self.Owner = playername
_DATABASE:CreateEventDynamicCargoUnloaded(self)
end
elseif count > 0 and agl == 0 then
self:T(self.lid.." moved! LOADED -> UNLOADED by "..tostring(playername))
self.CargoState = DYNAMICCARGO.State.UNLOADED
self.Owner = playername
_DATABASE:CreateEventDynamicCargoUnloaded(self)
end
end
end
self.LastPosition = pos
end
--end
else
---------------
-- REMOVED Cargo
---------------
if self.timer and self.timer:IsRunning() then self.timer:Stop() end
if self.timer and self.timer:IsRunning() then
self.timer:Stop()
self.timer=nil
end
self:T(self.lid.." dead! " ..self.CargoState.."-> REMOVED")
self.CargoState = DYNAMICCARGO.State.REMOVED
_DATABASE:CreateEventDynamicCargoRemoved(self)
@@ -491,6 +545,24 @@ function DYNAMICCARGO:_UpdatePosition()
return self
end
--- [USER] Destroy a DYNAMICCARGO object.
-- @param #DYNAMICCARGO self
-- @param #boolean GenerateEvent Set to false to remove an item silently. Defaults to true.
-- @return #boolean Return Returns nil if the object could not be found, else returns true.
function DYNAMICCARGO:Destroy(GenerateEvent)
local DCSObject = self:GetDCSObject()
if DCSObject then
local GenerateEvent = (GenerateEvent ~= nil and GenerateEvent == false) and false or true
if GenerateEvent and GenerateEvent == true then
self:CreateEventDead( timer.getTime(), DCSObject )
end
DCSObject:destroy()
self:_UpdatePosition()
return true
end
return nil
end
--- [Internal] Track helos for loaded/unloaded decision making.
-- @param Wrapper.Client#CLIENT client
-- @return #boolean IsIn
+114 -27
View File
@@ -230,6 +230,8 @@ GROUP.Attribute = {
GROUND_EWR="Ground_EWR",
GROUND_AAA="Ground_AAA",
GROUND_SAM="Ground_SAM",
GROUND_SHORAD="Ground_SHORAD",
GROUND_BALLISTICMISSILE="Ground_BallisticMissile",
GROUND_OTHER="Ground_OtherGround",
NAVAL_AIRCRAFTCARRIER="Naval_AircraftCarrier",
NAVAL_WARSHIP="Naval_WarShip",
@@ -912,15 +914,18 @@ function GROUP:GetVelocityVec3()
if DCSGroup and DCSGroup:isExist() then
local GroupUnits = DCSGroup:getUnits()
local GroupCount = #GroupUnits
local GroupCount = 0
local VelocityVec3 = { x = 0, y = 0, z = 0 }
for _, DCSUnit in pairs( GroupUnits ) do
local UnitVelocityVec3 = DCSUnit:getVelocity()
VelocityVec3.x = VelocityVec3.x + UnitVelocityVec3.x
VelocityVec3.y = VelocityVec3.y + UnitVelocityVec3.y
VelocityVec3.z = VelocityVec3.z + UnitVelocityVec3.z
if DCSUnit:isExist() and DCSUnit:isActive() then
local UnitVelocityVec3 = DCSUnit:getVelocity()
VelocityVec3.x = VelocityVec3.x + UnitVelocityVec3.x
VelocityVec3.y = VelocityVec3.y + UnitVelocityVec3.y
VelocityVec3.z = VelocityVec3.z + UnitVelocityVec3.z
GroupCount = GroupCount + 1
end
end
VelocityVec3.x = VelocityVec3.x / GroupCount
@@ -1053,9 +1058,12 @@ function GROUP:GetTypeName()
local DCSGroup = self:GetDCSObject()
if DCSGroup then
local GroupTypeName = DCSGroup:getUnit(1):getTypeName()
--self:T3( GroupTypeName )
return( GroupTypeName )
local unit = DCSGroup:getUnit(1)
if unit then
local GroupTypeName = unit:getTypeName()
--self:T3( GroupTypeName )
return( GroupTypeName )
end
end
return nil
@@ -1070,9 +1078,12 @@ function GROUP:GetNatoReportingName()
local DCSGroup = self:GetDCSObject()
if DCSGroup then
local GroupTypeName = DCSGroup:getUnit(1):getTypeName()
--self:T3( GroupTypeName )
return UTILS.GetReportingName(GroupTypeName)
local unit = DCSGroup:getUnit(1)
if unit then
local GroupTypeName = unit:getTypeName()
--self:T3( GroupTypeName )
return UTILS.GetReportingName(GroupTypeName)
end
end
return "Bogey"
@@ -1088,9 +1099,12 @@ function GROUP:GetPlayerName()
local DCSGroup = self:GetDCSObject()
if DCSGroup then
local PlayerName = DCSGroup:getUnit(1):getPlayerName()
--self:T3( PlayerName )
return( PlayerName )
local unit = DCSGroup:getUnit(1)
if unit then
local PlayerName = unit:getPlayerName()
--self:T3( PlayerName )
return( PlayerName )
end
end
return nil
@@ -1106,9 +1120,12 @@ function GROUP:GetCallsign()
local DCSGroup = self:GetDCSObject()
if DCSGroup then
local GroupCallSign = DCSGroup:getUnit(1):getCallsign()
--self:T3( GroupCallSign )
return GroupCallSign
local unit = DCSGroup:getUnit(1)
if unit then
local GroupCallSign = unit:getCallsign()
--self:T3( GroupCallSign )
return GroupCallSign
end
end
BASE:E( { "Cannot GetCallsign", Positionable = self, Alive = self:IsAlive() } )
@@ -1179,9 +1196,9 @@ function GROUP:GetAverageVec3()
end
end
--- Returns a POINT_VEC2 object indicating the point in 2D of the first UNIT of the GROUP within the mission.
--- Returns a COORDINATE object indicating the point in 2D of the first UNIT of the GROUP within the mission.
-- @param #GROUP self
-- @return Core.Point#POINT_VEC2 The 2D point vector of the first DCS Unit of the GROUP.
-- @return Core.Point#COORDINATE The 3D point vector of the first DCS Unit of the GROUP.
-- @return #nil The first UNIT is not existing or alive.
function GROUP:GetPointVec2()
--self:F2(self.GroupName)
@@ -1194,7 +1211,7 @@ function GROUP:GetPointVec2()
return FirstUnitPointVec2
end
BASE:E( { "Cannot GetPointVec2", Group = self, Alive = self:IsAlive() } )
BASE:E( { "Cannot get COORDINATE", Group = self, Alive = self:IsAlive() } )
return nil
end
@@ -1754,11 +1771,13 @@ function GROUP:GetMaxVelocity()
for Index, UnitData in pairs( DCSGroup:getUnits() ) do
local UnitVelocityVec3 = UnitData:getVelocity()
local UnitVelocity = math.abs( UnitVelocityVec3.x ) + math.abs( UnitVelocityVec3.y ) + math.abs( UnitVelocityVec3.z )
if UnitData:isExist() and UnitData:isActive() then
local UnitVelocityVec3 = UnitData:getVelocity()
local UnitVelocity = math.abs( UnitVelocityVec3.x ) + math.abs( UnitVelocityVec3.y ) + math.abs( UnitVelocityVec3.z )
if UnitVelocity > GroupVelocityMax then
GroupVelocityMax = UnitVelocity
if UnitVelocity > GroupVelocityMax then
GroupVelocityMax = UnitVelocity
end
end
end
@@ -1843,7 +1862,10 @@ end
-- @return #table
function GROUP:GetTemplateRoutePoints()
local GroupName = self:GetName()
return UTILS.DeepCopy( _DATABASE:GetGroupTemplate( GroupName ).route.points )
local template = _DATABASE:GetGroupTemplate(GroupName)
if template and template.route and template.route.points then
return UTILS.DeepCopy(template.route.points)
end
end
@@ -2093,7 +2115,7 @@ function GROUP:Respawn( Template, Reset )
GroupUnitVec3 = Zone:GetRandomVec3()
else
if self.InitRespawnRandomizePositionInner and self.InitRespawnRandomizePositionOuter then
GroupUnitVec3 = POINT_VEC3:NewFromVec2( From ):GetRandomPointVec3InRadius( self.InitRespawnRandomizePositionsOuter, self.InitRespawnRandomizePositionsInner )
GroupUnitVec3 = COORDINATE:NewFromVec3(From):GetRandomVec3InRadius(self.InitRespawnRandomizePositionsOuter, self.InitRespawnRandomizePositionsInner)
else
GroupUnitVec3 = Zone:GetVec3()
end
@@ -2144,7 +2166,7 @@ function GROUP:Respawn( Template, Reset )
GroupUnitVec3 = Zone:GetRandomVec3()
else
if self.InitRespawnRandomizePositionInner and self.InitRespawnRandomizePositionOuter then
GroupUnitVec3 = POINT_VEC3:NewFromVec2( From ):GetRandomPointVec3InRadius( self.InitRespawnRandomizePositionsOuter, self.InitRespawnRandomizePositionsInner )
GroupUnitVec3 = COORDINATE:NewFromVec2( From ):GetRandomPointVec3InRadius( self.InitRespawnRandomizePositionsOuter, self.InitRespawnRandomizePositionsInner )
else
GroupUnitVec3 = Zone:GetVec3()
end
@@ -2222,6 +2244,10 @@ function GROUP:Respawn( Template, Reset )
--UTILS.PrintTableToLog(Template)
if self.ValidateAndRepositionGroundUnits then
UTILS.ValidateAndRepositionGroundUnits(Template.units)
end
-- Spawn new group.
self:ScheduleOnce(0.1,_DATABASE.Spawn,_DATABASE,Template)
--_DATABASE:Spawn(Template)
@@ -2630,6 +2656,8 @@ function GROUP:GetAttribute()
local artillery=self:HasAttribute("Artillery")
local tank=self:HasAttribute("Old Tanks") or self:HasAttribute("Modern Tanks") or self:HasAttribute("Tanks")
local aaa=self:HasAttribute("AAA") and (not self:HasAttribute("SAM elements"))
local ballisticMissile=artillery and self:HasAttribute("SS_missile")
local shorad=self:HasAttribute("SR SAM")
local ewr=self:HasAttribute("EWR")
local ifv=self:HasAttribute("IFV")
local sam=self:HasAttribute("SAM elements") or self:HasAttribute("Optical Tracker")
@@ -2671,6 +2699,8 @@ function GROUP:GetAttribute()
attribute=GROUP.Attribute.GROUND_SAM
elseif aaa then
attribute=GROUP.Attribute.GROUND_AAA
elseif artillery and ballisticMissile then
attribute=GROUP.Attribute.GROUND_BALLISTICMISSILE
elseif artillery then
attribute=GROUP.Attribute.GROUND_ARTILLERY
elseif tank then
@@ -3183,3 +3213,60 @@ function GROUP:IsAAA()
end
return isAAA
end
--- This function uses Disposition and other fallback logic to find better ground positions for ground units.
--- NOTE: This is not a spawn randomizer.
--- It will try to find clear ground locations avoiding trees, water, roads, runways, map scenery, statics and other units in the area and modifies the provided positions table.
--- Maintains the original layout and unit positions as close as possible by searching for the next closest valid position to each unit.
--- Uses UTILS.ValidateAndRepositionGroundUnits.
-- @param #GROUP self
-- @param #boolean Enabled Enable/disable the feature.
function GROUP:SetValidateAndRepositionGroundUnits(Enabled)
self.ValidateAndRepositionGroundUnits = Enabled
end
--- Get the bounding box of the group combining UNIT:GetBoundingBox() units.
-- @param #GROUP self
-- @return DCS#Box3 The bounding box of the GROUP.
-- @return #nil The GROUP does not have any alive units.
function GROUP:GetBoundingBox()
local bbox = { min = { x = math.huge, y = math.huge, z = math.huge },
max = { x = -math.huge, y = -math.huge, z = -math.huge }
}
local Units = self:GetUnits() or {}
if #Units == 0 then
return nil
end
for _, unit in pairs(Units) do
if unit and unit:IsAlive() then
local ubox = unit:GetBoundingBox()
if ubox then
if ubox.min.x < bbox.min.x then
bbox.min.x = ubox.min.x
end
if ubox.min.y < bbox.min.y then
bbox.min.y = ubox.min.y
end
if ubox.min.z < bbox.min.z then
bbox.min.z = ubox.min.z
end
if ubox.max.x > bbox.max.x then
bbox.max.x = ubox.max.x
end
if ubox.max.y > bbox.max.y then
bbox.max.y = ubox.max.y
end
if ubox.max.z > bbox.max.z then
bbox.max.z = ubox.max.z
end
end
end
end
return bbox
end
@@ -170,6 +170,27 @@ function IDENTIFIABLE:GetCoalition()
return nil
end
--- Returns true if identifiable is of RED coalition.
-- @param #IDENTIFIABLE self
-- @return #boolean If the identifiable is red.
function IDENTIFIABLE:IsRed()
return self:GetCoalition() == coalition.side.RED
end
--- Returns true if identifiable is of BLUE coalition.
-- @param #IDENTIFIABLE self
-- @return #boolean If the identifiable is blue.
function IDENTIFIABLE:IsBlue()
return self:GetCoalition() == coalition.side.BLUE
end
--- Returns true if identifiable is of NEUTRAL coalition.
-- @param #IDENTIFIABLE self
-- @return #boolean If the identifiable is neutral.
function IDENTIFIABLE:IsNeutral()
return self:GetCoalition() == coalition.side.NEUTRAL
end
--- Returns the name of the coalition of the Identifiable.
-- @param #IDENTIFIABLE self
-- @return #string The name of the coalition.
@@ -16,7 +16,7 @@
--- @type POSITIONABLE
-- @field Core.Point#COORDINATE coordinate Coordinate object.
-- @field Core.Point#POINT_VEC3 pointvec3 Point Vec3 object.
-- @field Core.Point#COORDINATE pointvec3 Point Vec3 object.
-- @extends Wrapper.Identifiable#IDENTIFIABLE
@@ -246,18 +246,20 @@ end
function POSITIONABLE:GetVec3()
local DCSPositionable = self:GetDCSObject()
if DCSPositionable then
--local status, vec3 = pcall(
-- function()
-- local vec3 = DCSPositionable:getPoint()
-- return vec3
--end
--)
local vec3 = DCSPositionable:getPoint()
--if status then
return vec3
--else
--self:E( { "Cannot get Vec3 from DCS Object", Positionable = self, Alive = self:IsAlive() } )
--end
if not vec3 then
local pos = DCSPositionable:getPosition()
if pos and pos.p then
vec3 = pos.p
else
self:E( { "Cannot get the position from DCS Object for GetVec3", Positionable = self, Alive = self:IsAlive() } )
end
end
return vec3
end
-- ERROR!
self:E( { "Cannot get the Positionable DCS Object for GetVec3", Positionable = self, Alive = self:IsAlive() } )
@@ -284,9 +286,9 @@ function POSITIONABLE:GetVec2()
return nil
end
--- Returns a POINT_VEC2 object indicating the point in 2D of the POSITIONABLE within the mission.
--- Returns a COORDINATE object indicating the point in 2D of the POSITIONABLE within the mission.
-- @param #POSITIONABLE self
-- @return Core.Point#POINT_VEC2 The 2D point vector of the POSITIONABLE.
-- @return Core.Point#COORDINATE The 3D point vector of the POSITIONABLE.
-- @return #nil The POSITIONABLE is not existing or alive.
function POSITIONABLE:GetPointVec2()
self:F2( self.PositionableName )
@@ -296,20 +298,20 @@ function POSITIONABLE:GetPointVec2()
if DCSPositionable then
local PositionableVec3 = DCSPositionable:getPosition().p
local PositionablePointVec2 = POINT_VEC2:NewFromVec3( PositionableVec3 )
local PositionablePointVec2 = COORDINATE:NewFromVec3( PositionableVec3 )
-- self:F( PositionablePointVec2 )
return PositionablePointVec2
end
self:E( { "Cannot GetPointVec2", Positionable = self, Alive = self:IsAlive() } )
self:E( { "Cannot Coordinate", Positionable = self, Alive = self:IsAlive() } )
return nil
end
--- Returns a POINT_VEC3 object indicating the point in 3D of the POSITIONABLE within the mission.
--- Returns a COORDINATE object indicating the point in 3D of the POSITIONABLE within the mission.
-- @param #POSITIONABLE self
-- @return Core.Point#POINT_VEC3 The 3D point vector of the POSITIONABLE.
-- @return Core.Point#COORDINATE The 3D point vector of the POSITIONABLE.
-- @return #nil The POSITIONABLE is not existing or alive.
function POSITIONABLE:GetPointVec3()
@@ -329,8 +331,8 @@ function POSITIONABLE:GetPointVec3()
else
-- Create a new POINT_VEC3 object.
self.pointvec3 = POINT_VEC3:NewFromVec3( PositionableVec3 )
-- Create a new COORDINATE object.
self.pointvec3 = COORDINATE:NewFromVec3( PositionableVec3 )
end
@@ -359,15 +361,17 @@ function POSITIONABLE:GetCoord()
-- Get the current position.
local PositionableVec3 = self:GetVec3()
if self.coordinate then
-- Update COORDINATE from 3D vector.
self.coordinate:UpdateFromVec3( PositionableVec3 )
else
-- New COORDINATE.
self.coordinate = COORDINATE:NewFromVec3( PositionableVec3 )
end
if PositionableVec3 then
if self.coordinate then
-- Update COORDINATE from 3D vector.
self.coordinate:UpdateFromVec3( PositionableVec3 )
else
-- New COORDINATE.
self.coordinate = COORDINATE:NewFromVec3( PositionableVec3 )
end
return self.coordinate
return self.coordinate
end
end
-- Error message.
@@ -388,13 +392,13 @@ function POSITIONABLE:GetCoordinate()
-- Get the current position.
local PositionableVec3 = self:GetVec3()
local coord=COORDINATE:NewFromVec3(PositionableVec3)
local heading = self:GetHeading()
coord.Heading = heading
-- Return a new coordiante object.
return coord
if PositionableVec3 then
local coord=COORDINATE:NewFromVec3(PositionableVec3)
local heading = self:GetHeading()
coord.Heading = heading
-- Return a new coordiante object.
return coord
end
end
-- Error message.
@@ -1861,6 +1865,7 @@ do -- Cargo
["HL_DSHK"] = 6*POSITIONABLE.DefaultInfantryWeight,
["CCKW_353"] = 16*POSITIONABLE.DefaultInfantryWeight, --GMC CCKW 2½-ton 6×6 truck, estimating 16 soldiers,
["MaxxPro_MRAP"] = 7*POSITIONABLE.DefaultInfantryWeight,
["Sd_Kfz_251"] = 10*POSITIONABLE.DefaultInfantryWeight,
}
}
+159 -27
View File
@@ -18,7 +18,13 @@
-- @field #string SceneryName Name of the scenery object.
-- @field DCS#Object SceneryObject DCS scenery object.
-- @field #number Life0 Initial life points.
-- @field #table Properties
-- @field #table Properties.
-- @field #number ID.
-- @field Core.Zone#ZONE_POLYGON SceneryZone.
-- @field Core.Point#COORDINATE Coordinate.
-- @field DCS#Vec2 Vec2.
-- @field DCS#Vec3 Vec3.
-- @field Core.Vector#VECTOR Vector.
-- @extends Wrapper.Positionable#POSITIONABLE
@@ -35,27 +41,72 @@ SCENERY = {
ClassName = "SCENERY",
}
_SCENERY = {}
--- Register scenery object as POSITIONABLE.
--@param #SCENERY self
--@param #string SceneryName Scenery name.
--@param DCS#Object SceneryObject DCS scenery object.
--@param Core.Zone#ZONE_POLYGON SceneryZone (optional) The zone object.
--@return #SCENERY Scenery object.
function SCENERY:Register( SceneryName, SceneryObject )
function SCENERY:Register( SceneryName, SceneryObject, SceneryZone )
local ID = (SceneryObject and SceneryObject.getID) and SceneryObject:getID() or SceneryName
if _SCENERY[ID] and _SCENERY[ID].SceneryObject == nil then
_SCENERY[ID].SceneryObject=SceneryObject
SCENERY._UpdateFromDCSObject(_SCENERY[ID])
end
if _SCENERY[ID] then return _SCENERY[ID] end
local self = BASE:Inherit( self, POSITIONABLE:New( SceneryName ) )
self.SceneryName = tostring(SceneryName)
self.ID = ID
self.SceneryObject = SceneryObject
self.SceneryZone = SceneryZone
if SceneryZone then
self.Vec3 = SceneryZone:GetVec3()
self.Vec2 = SceneryZone:GetVec2()
self.Vector = (self.Vec3 and VECTOR) and VECTOR:NewFromVec(self.Vec3) or nil
end
if self.SceneryObject and self.SceneryObject.getLife then -- fix some objects do not have all functions
self.Life0 = self.SceneryObject:getLife() or 0
self.Life0 = self.SceneryObject:getLife() or 1
else
self.Life0 = 0
self.Life0 = 1
end
self.Properties = {}
_SCENERY[self.ID] = self
return self
end
--- [INTERNAL] Update data
-- @param Wrapper.Scenery#SCENERY Scenery The object to update.
function SCENERY._UpdateFromDCSObject(Scenery)
env.info("APPLE _UpdateFromDCSObject "..tostring(Scenery.SceneryName))
local self=Scenery
if self.Vec2 == nil and self.SceneryObject ~= nil then
self.Vec3 = self.SceneryObject:getPoint()
if self.Vec3 then
self.Vec2 = {x=self.Vec3.x,y=self.Vec3.z}
self.Vector = VECTOR:NewFromVec(self.Vec3)
end
end
if not self.Life0 or self.Life0 == 1 then
if self.SceneryObject and self.SceneryObject.getLife() then
self.Life = self.SceneryObject:getLife() or 1
self.Life0 = self.Life
end
end
return self
end
@@ -99,6 +150,39 @@ function SCENERY:GetName()
return self.SceneryName
end
--- Obtain object coordinate.
--@param #SCENERY self
--@return Core.Point#COORDINATE Coordinate
function SCENERY:GetCoordinate()
if self.Coordinate then
return self.Coordinate
elseif self.Vec3 then
self.Coordinate = COORDINATE:NewFromVec3(self.Vec3):SetAlt()
end
return self.Coordinate
end
--- Obtain object coordinate.
--@param #SCENERY self
--@return DCS#Vec3 Vec3
function SCENERY:GetVec3()
return self.Vec3
end
--- Obtain object coordinate.
--@param #SCENERY self
--@return DCS#Vec2 Vec2
function SCENERY:GetVec2()
return self.Vec2
end
--- Obtain object coordinate.
--@param #SCENERY self
--@return Core.Vector#VECTOR Vector
function SCENERY:GetVector()
return self.Vector
end
--- Obtain DCS Object from the SCENERY Object.
--@param #SCENERY self
--@return DCS#Object DCS scenery object.
@@ -106,6 +190,13 @@ function SCENERY:GetDCSObject()
return self.SceneryObject
end
--- Obtain object ID.
--@param #SCENERY self
--@return #string Name
function SCENERY:GetID()
return self.ID
end
--- Get current life points from the SCENERY Object. Note - Some scenery objects always have 0 life points.
-- **CAVEAT**: Some objects change their life value or "hitpoints" **after** the first hit. Hence we will adjust the life0 value to 120%
-- of the last life value if life exceeds life0 (initial life) at any point. Thus will will get a smooth percentage decrease, if you use this e.g. as success
@@ -113,12 +204,14 @@ end
--@param #SCENERY self
--@return #number life
function SCENERY:GetLife()
local life = 0
local life = 1
if self.SceneryObject and self.SceneryObject.getLife then
life = self.SceneryObject:getLife()
if life > self.Life0 then
self.Life0 = math.floor(life * 1.2)
end
elseif self.Life then
life = self.Life
end
return life
end
@@ -176,12 +269,19 @@ end
--- Find a SCENERY object from its name or id. Since SCENERY isn't registered in the Moose database (just too many objects per map), we need to do a scan first
-- to find the correct object.
--@param #SCENERY self
--@param #string Name The name/id of the scenery object as taken from the ME. Ex. '595785449'
--@param Core.Point#COORDINATE Coordinate Where to find the scenery object
--@param #number Radius (optional) Search radius around coordinate, defaults to 100
--@return #SCENERY Scenery Object or `nil` if it cannot be found
function SCENERY:FindByName(Name, Coordinate, Radius, Role)
--@param #string Name The name/id of the scenery object as taken from the ME. Ex. '595785449'.
--@param Core.Point#COORDINATE Coordinate Where to find the scenery object.
--@param #number Radius (optional) Search radius around coordinate, defaults to 100.
--@param #string Role (optional) The role if set on the zone object.
--@param Core.Zone#ZONE_POLYGON Zone (optional) The Zone where the scenery is located.
--@return #SCENERY Scenery Object or `nil` if it cannot be found.
function SCENERY:FindByName(Name, Coordinate, Radius, Role, Zone)
--BASE:I("Coordinate x = "..Coordinate.x .. " y = "..Coordinate.y.." z = "..Coordinate.z)
local findme = self:_FindByName(Name)
if findme then return findme end
local radius = Radius or 100
local name = Name or "unknown"
local scenery = nil
@@ -193,12 +293,13 @@ function SCENERY:FindByName(Name, Coordinate, Radius, Role)
local function SceneryScan(scoordinate, sradius, sname)
if scoordinate ~= nil then
local Vec2 = scoordinate:GetVec2()
local scanzone = ZONE_RADIUS:New("Zone-"..sname,Vec2,sradius,true)
local scanzone = ZONE_RADIUS:New("Zone-"..sname,Vec2,sradius)
scanzone:Scan({Object.Category.SCENERY})
local scanned = scanzone:GetScannedSceneryObjects()
local rscenery = nil -- Wrapper.Scenery#SCENERY
for _,_scenery in pairs(scanned) do
local scenery = _scenery -- Wrapper.Scenery#SCENERY
--BASE:I({tostring(scenery.SceneryName),tostring(sname)})
if tostring(scenery.SceneryName) == tostring(sname) then
rscenery = scenery
if Role then rscenery:SetProperty("ROLE",Role) end
@@ -211,13 +312,36 @@ function SCENERY:FindByName(Name, Coordinate, Radius, Role)
end
if Coordinate then
--BASE:I("Coordinate Scenery Scan")
scenery = SceneryScan(Coordinate, radius, name)
end
if not scenery then scenery = SCENERY:Register(Name,nil,Zone) end
return scenery
end
--- Find a SCENERY object that was previously registered(!) by it's ID.
-- @param #SCENERY self
-- @param #number ID
-- @return Wrapper.Scenery#SCENERY Scenery or nil if it could not be found
function SCENERY:FindByID(ID)
return _SCENERY[ID]
end
--- Find a SCENERY object that was previously registered(!) by it's name.
-- @param #SCENERY self
-- @param #string Name
-- @return Wrapper.Scenery#SCENERY Scenery or nil if it could not be found
function SCENERY:_FindByName(Name)
for _id,_object in pairs(_SCENERY) do
if _object and _object.GetName and _object:GetName() then
local name = _object:GetName()
if Name == name then return _object end
end
end
return nil
end
--- Find a SCENERY object from its name or id. Since SCENERY isn't registered in the Moose database (just too many objects per map), we need to do a scan first
-- to find the correct object.
--@param #SCENERY self
@@ -231,8 +355,8 @@ function SCENERY:FindByNameInZone(Name, Zone, Radius)
if type(Zone) == "string" then
Zone = ZONE:FindByName(Zone)
end
local coordinate = Zone:GetCoordinate()
return self:FindByName(Name,coordinate,Radius,Zone:GetProperty("ROLE"))
local coordinate = Zone:GetCoordinate():SetAlt()
return self:FindByName(Name,coordinate,Radius,Zone:GetProperty("ROLE"),Zone)
end
--- Find a SCENERY object from its zone name. Since SCENERY isn't registered in the Moose database (just too many objects per map), we need to do a scan first
@@ -241,14 +365,18 @@ end
--@param #string ZoneName The name of the scenery zone as created with a right-click on the map in the mission editor and select "assigned to...". Can be handed over as ZONE object.
--@return #SCENERY First found Scenery Object or `nil` if it cannot be found
function SCENERY:FindByZoneName( ZoneName )
--BASE:I(ZoneName)
local zone = ZoneName -- Core.Zone#ZONE_BASE
if type(ZoneName) == "string" then
zone = ZONE:FindByName(ZoneName) -- Core.Zone#ZONE_POLYGON
end
local _id = zone:GetProperty('OBJECT ID')
--local properties = zone:GetAllProperties() or {}
--BASE:I(string.format("Object ID is: %s",_id or "none"))
--BASE:T("Object ID ".._id)
--BASE:I("Object ID ".._id)
if not _id then
-- this zone has no object ID
BASE:E("**** Zone without object ID: "..ZoneName.." | Type: "..tostring(zone.ClassName))
@@ -257,23 +385,27 @@ function SCENERY:FindByZoneName( ZoneName )
local scanned = zone:GetScannedSceneryObjects()
for _,_scenery in (scanned) do
local scenery = _scenery -- Wrapper.Scenery#SCENERY
if scenery:IsAlive() then
--if scenery:IsAlive() then
local role = zone:GetProperty("ROLE")
if role then scenery:SetProperty("ROLE",role) end
return scenery
end
--end
end
return nil
else
return self:FindByName(_id, zone:GetCoordinate(),nil,zone:GetProperty("ROLE"))
local coordinate = zone:GetCoordinate()
coordinate:SetAlt()
return self:FindByName(_id, coordinate,nil,zone:GetProperty("ROLE"),zone)
end
else
return self:FindByName(_id, zone:GetCoordinate(),nil,zone:GetProperty("ROLE"))
local coordinate = zone:GetCoordinate()
coordinate:SetAlt()
return self:FindByName(_id, coordinate,nil,zone:GetProperty("ROLE"),zone)
end
end
--- Scan and find all SCENERY objects from a zone by zone-name. Since SCENERY isn't registered in the Moose database (just too many objects per map), we need to do a scan first
-- to find the correct object.
-- to find the correct object. Might return nil!
--@param #SCENERY self
--@param #string ZoneName The name of the zone, can be handed as ZONE_RADIUS or ZONE_POLYGON object
--@return #table of SCENERY Objects, or `nil` if nothing found
@@ -295,7 +427,7 @@ function SCENERY:FindAllByZoneName( ZoneName )
return nil
end
else
local obj = self:FindByName(_id, zone:GetCoordinate(),nil,zone:GetProperty("ROLE"))
local obj = self:FindByName(_id, zone:GetCoordinate():SetAlt(),nil,zone:GetProperty("ROLE"), zone)
if obj then
return {obj}
else
@@ -64,6 +64,9 @@ function STATIC:Register( StaticName )
else
self:E(string.format("Static object %s does not exist!", tostring(self.StaticName)))
end
-- Cache position
self._vec3 = self:GetVec3()
return self
end
@@ -86,6 +89,30 @@ function STATIC:GetLife()
return nil
end
--- Get the position of the STATIC even if it is not alive.
-- @param #STATIC self
-- @return DCS#Vec2 The 2D point vector of the POSITIONABLE.
-- @return #nil The position was not cached.
function STATIC:GetVec2Cached()
local vec2 = self:GetVec2()
if not vec2 and self._vec3 then
vec2 = {x = self._vec3.x, y = self._vec3.z }
end
return vec2
end
--- Get the position of the STATIC even if it is not alive.
-- @param #STATIC self
-- @return DCS#Vec3 The 3D point vector of the POSITIONABLE.
-- @return #nil The position was not cached.
function STATIC:GetVec3Cached()
local vec3 = self:GetVec3()
if not vec3 and self._vec3 then
vec3 = self._vec3
end
return vec3
end
--- Finds a STATIC from the _DATABASE using a DCSStatic object.
-- @param #STATIC self
-- @param DCS#StaticObject DCSStatic An existing DCS Static object reference.
@@ -232,6 +259,8 @@ function STATIC:SpawnAt(Coordinate, Heading, Delay)
local SpawnStatic=SPAWNSTATIC:NewFromStatic(self.StaticName)
SpawnStatic:SpawnFromPointVec2( Coordinate, Heading, self.StaticName )
-- Cache position
self._vec3 = self:GetVec3()
end
@@ -255,6 +284,8 @@ function STATIC:ReSpawn(CountryID, Delay)
local SpawnStatic=SPAWNSTATIC:NewFromStatic(self.StaticName, CountryID)
SpawnStatic:Spawn(nil, self.StaticName)
-- Cache position
self._vec3 = self:GetVec3()
end
@@ -278,6 +309,8 @@ function STATIC:ReSpawnAt(Coordinate, Heading, Delay)
local SpawnStatic=SPAWNSTATIC:NewFromStatic(self.StaticName, self:GetCountry())
SpawnStatic:SpawnFromCoordinate(Coordinate, Heading, self.StaticName)
-- Cache position
self._vec3 = self:GetVec3()
end
+3 -3
View File
@@ -753,7 +753,7 @@ function STORAGE:LoadFromFile(Path,Filename)
end
end
else
self:E("File for Liquids could not be found: "..tostring(Path).."\\"..tostring(Filename"_Liquids.csv"))
self:E("File for Liquids could not be found: "..tostring(Path).."\\"..tostring(Filename).."_Liquids.csv")
end
end
@@ -773,7 +773,7 @@ function STORAGE:LoadFromFile(Path,Filename)
end
end
else
self:E("File for Aircraft could not be found: "..tostring(Path).."\\"..tostring(Filename"_Aircraft.csv"))
self:E("File for Aircraft could not be found: "..tostring(Path).."\\"..tostring(Filename).."_Aircraft.csv")
end
end
@@ -805,7 +805,7 @@ function STORAGE:LoadFromFile(Path,Filename)
end
end
else
self:E("File for Weapons could not be found: "..tostring(Path).."\\"..tostring(Filename"_Weapons.csv"))
self:E("File for Weapons could not be found: "..tostring(Path).."\\"..tostring(Filename).."_Weapons.csv")
end
end

Some files were not shown because too many files have changed in this diff Show More