Compare commits

...

1112 Commits

Author SHA1 Message Date
Applevangelist 30cf1f5713 #PLAYERTASK/MANAGER
- Option to Cancel a task silently
- Option to allow smoking per task (default: true)
- Option to show threat details per task (default: true)
2025-11-02 14:22:56 +01:00
Thomas 33f7a7084c Merge pull request #2431 from FlightControl-Master/master
Merge from master
2025-11-01 17:26:25 +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 8ca9474c1c Merge pull request #2429 from FlightControl-Master/master
Merge from master
2025-10-31 06:28:57 +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 37a5f68339 Merge pull request #2427 from FlightControl-Master/master
Merge from master
2025-10-29 07:03:23 +01: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 b28e66fe6d Merge remote-tracking branch 'origin/master' into develop 2025-10-26 16:19:44 +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 1965e24860 Merge pull request #2424 from FlightControl-Master/master
Merge from master
2025-10-26 07:31:50 +01: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 3da6187782 #AUFTRAG, #OPSGROUP - close issue #2201 2025-10-25 16:53:53 +02:00
Applevangelist 0bd79d518f Merge remote-tracking branch 'origin/master' into develop 2025-10-24 16:27:53 +02:00
Applevangelist 86798ae9ea #CTLD - fix 2025-10-24 16:27:17 +02:00
Thomas dfc63de745 Merge pull request #2422 from FlightControl-Master/master
Merge from master
2025-10-24 16:17:15 +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 d7841b47a5 Merge remote-tracking branch 'origin/master' into develop 2025-10-23 12:10:43 +02:00
Applevangelist 0f270a6a35 #UTILS - FARP helper - add options to spawn multiple pads 2025-10-23 12:10:05 +02:00
Applevangelist 92db68c36b Merge remote-tracking branch 'origin/master' into develop 2025-10-23 08:11:11 +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 e91bcdfe5e Merge pull request #2419 from FlightControl-Master/revert-2418-master
Revert "Merge from master"
2025-10-22 07:16:51 +02:00
Thomas 1f1a068d45 Revert "Merge from master" 2025-10-22 07:16:33 +02:00
Thomas a57c0a8c7d Merge pull request #2418 from FlightControl-Master/master
Merge from master
2025-10-22 06:32:18 +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 512c3c57e9 #TIRESIAS - Fixed a problem when a script wants to add exceptions pre-start. 2025-10-19 14:38:50 +02:00
Applevangelist 3a95e75c2d Merge remote-tracking branch 'origin/master' into develop 2025-10-13 18:52:26 +02: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 08fb458aa4 Merge remote-tracking branch 'origin/master' into develop 2025-10-12 19:16:14 +02:00
Applevangelist 2e0d1fd90f #DYNAMICCARGO - Added Mi-8 type and dimensions 2025-10-12 19:14:59 +02:00
Applevangelist 3694e9649d Merge remote-tracking branch 'origin/develop' into develop 2025-10-12 17:25:03 +02:00
Applevangelist 2c79fa6492 Merge remote-tracking branch 'origin/master' into develop 2025-10-12 17:24:58 +02:00
Applevangelist 69e6497655 #CTLD - Small fix for subcats 2025-10-12 17:23:54 +02:00
Thomas aca713b8d9 Merge pull request #2416 from FlightControl-Master/master
Merge
2025-10-10 11:42:36 +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 a2da4f0e77 Merge pull request #2414 from FlightControl-Master/master
Merge
2025-10-09 17:43:05 +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 5910c9502a Merge remote-tracking branch 'origin/master' into develop 2025-10-08 16:01:48 +02:00
Applevangelist 405235a59d #CONTROLLABLE - Fix for double brackets 2025-10-08 16:01:21 +02:00
Thomas bd8ac9551c Merge pull request #2411 from FlightControl-Master/master
Merge from master
2025-10-08 13:26:04 +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 c850ea10f5 Merge remote-tracking branch 'origin/master' into develop 2025-10-08 12:30:37 +02:00
Applevangelist 3260279cb7 xx 2025-10-08 12:29:59 +02:00
Applevangelist 2fcef1f277 xx 2025-10-07 18:10:00 +02:00
Applevangelist 1e60a0a32a #RAT 3.0.0 2025-10-07 18:06:20 +02:00
Applevangelist 7707522ce5 Merge remote-tracking branch 'origin/master' into develop
# Conflicts:
#	Moose Development/Moose/Functional/RAT.lua
2025-10-07 17:52:03 +02:00
Applevangelist 91e26adc6a #AUFTRAG - Added functions to check repeatability
#OPS - less noise in log
#LEGION - Added mission housekeeping
2025-10-07 17:50:29 +02:00
Applevangelist 146f869aaa #RAT - reduce log noise 2025-10-07 17:48:06 +02:00
Thomas dc863be38a Merge pull request #2409 from FlightControl-Master/master
Merge from master
2025-10-07 15:52:14 +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
Applevangelist 8cb91477cf #AWACS - added function to set own BullsEye coordinate if necessary 2025-10-07 11:41:00 +02:00
Thomas a8a69fdbca Merge pull request #2407 from FlightControl-Master/master
Merge from master
2025-10-07 10:15:02 +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 025bd3237c Merge pull request #2405 from FlightControl-Master/master
Merge from master
2025-10-05 18:04:43 +02: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 e867ce4c73 Merge remote-tracking branch 'origin/master' into develop 2025-10-05 13:52:59 +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 d8281b0103 Merge pull request #2403 from FlightControl-Master/master
Merge from master
2025-10-01 15:26:49 +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 4a870d0183 Merge pull request #2401 from FlightControl-Master/master
Merge from master
2025-09-26 15:53:13 +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 47ddc64239 #EASYGCICAP added EASYGCICAP:SetCAPEngageTargetTypes(types) 2025-09-25 15:17:03 +02:00
Applevangelist 2a32be40f6 Merge remote-tracking branch 'origin/master' into develop 2025-09-25 12:13:55 +02:00
Applevangelist 8fb4d4c7c6 #CTLD - add CratesPickedUp at one more point 2025-09-25 12:13:29 +02:00
Thomas b17748cfeb Merge pull request #2399 from FlightControl-Master/master
Merge from master
2025-09-24 19:16:55 +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 c761d5020b Merge pull request #2397 from FlightControl-Master/master
Merge from master
2025-09-23 15:31:20 +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 608fa1ca6c Merge pull request #2394 from FlightControl-Master/master
small fix
2025-09-22 11:15:13 +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 8535c39c2c Merge pull request #2392 from FlightControl-Master/master
Merge from master
2025-09-22 11:11:46 +02:00
Thomas da8f023f5b Merge pull request #2386 from shaji-Dev/develop
[Added] `PLAYERTASK:CanJoinTask`
2025-09-22 11:10:45 +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 7123562f85 Merge pull request #2388 from m1ndgames/develop
fix: Add conditional checks for AWACS markers based on AllowMarkers property
2025-09-18 07:41:14 +02:00
Thomas 6301f5a939 Merge pull request #2389 from FlightControl-Master/master
Merge from master
2025-09-18 06:48:20 +02:00
Thomas 5e8676cf8a Merge pull request #2387 from shaji-Dev/master
LandingAfterEjection error
2025-09-18 06:47:01 +02:00
m1nd b320ba597a fix: Add conditional checks for AWACS markers based on AllowMarkers property 2025-09-18 00:32:48 +02:00
shaji-Dev 12d16f355b Merge branch 'FlightControl-Master:develop' into develop 2025-09-17 20:20:37 +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
Applevangelist 58b169cb03 Merge remote-tracking branch 'origin/develop' into develop 2025-09-17 12:04:38 +02:00
Applevangelist 04fcb985fe #PLAYERTASK - Ensure call task failed on the controller 2025-09-17 12:04:34 +02:00
smiki 5414adc8d8 [Added] PLAYERTASK:CanJoinTask Override function in order to implement custom logic if a player can join a task or not. 2025-09-17 09:26:34 +02:00
Thomas 95210366e9 Merge pull request #2385 from shaji-Dev/develop
[Added] `PLAYERTASKCONTROLLER:CanJoinTask`
2025-09-16 19:14:17 +02:00
smiki f73dc6c3be [Added] PLAYERTASKCONTROLLER:CanJoinTask Override function in order to implement custom logic if a player can join a task or not. 2025-09-16 15:14:28 +02:00
Applevangelist 74383e3111 Merge remote-tracking branch 'origin/develop' into develop 2025-09-15 09:28:39 +02:00
Applevangelist 3f8954d21d #EASYGCICAP - Fixed - for Tanker Squadrons the TACAN channel could not be nil. 2025-09-15 09:28:35 +02:00
Thomas ebf393c58b Merge pull request #2384 from FlightControl-Master/master
Merge from master
2025-09-11 05:14:54 +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
Applevangelist 9c3c27f809 Merge remote-tracking branch 'origin/develop' into develop 2025-09-07 18:58:47 +02:00
Applevangelist 03275938e7 #CLIENTMENU - add missing func from documentation 2025-09-07 18:58:41 +02:00
Thomas a90e321a91 Merge pull request #2382 from FlightControl-Master/master
Merge from master
2025-09-03 10:37:03 +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 e531f12f94 Merge pull request #2380 from FlightControl-Master/master
Merge from master
2025-09-01 10:59:59 +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 5d3f5dac1e Merge remote-tracking branch 'origin/master' into develop 2025-08-31 18:22:41 +02:00
Applevangelist 873879ff79 #AIRBOSS - Slight tweak to EnableSRS() when no parameters are handed in. 2025-08-31 18:22:17 +02:00
Applevangelist 2f46a63041 Merge remote-tracking branch 'origin/master' into develop 2025-08-31 13:28:00 +02:00
Applevangelist 6c1907f7e0 GROUO correction in class self line 3205 2025-08-31 13:27:24 +02:00
Applevangelist f43dd389e2 Merge remote-tracking branch 'origin/master' into develop 2025-08-31 13:25:47 +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
Applevangelist efb1d79e77 #COHORT - Fix Callsign Setting 2025-08-28 13:17:57 +02:00
Applevangelist ee23daa651 Merge remote-tracking branch 'origin/develop' into develop 2025-08-28 11:13:56 +02:00
Applevangelist e590701c01 xx 2025-08-28 11:13:50 +02:00
Thomas 9f1777ca9b Merge pull request #2376 from FlightControl-Master/master
Airboss Vietnam Era Vessels
2025-08-27 14:24:43 +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 527c4d0de4 Merge pull request #2373 from shaji-Dev/develop
[ADDED] `ValidateAndRepositionGroundUnits` to OPSGROUP
2025-08-26 18:38:41 +02:00
smiki 2479147fd9 [ADDED] ValidateAndRepositionGroundUnits to OPSGROUP 2025-08-26 13:15:12 +02:00
Thomas 7b7a8c1bab Merge pull request #2372 from FlightControl-Master/master
Merge from master
2025-08-26 06:23:46 +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
Thomas 2ff630d394 Merge pull request #2371 from shaji-Dev/develop
[ADDED] `ValidateAndRepositionGroundUnits` to OPSGROUP
2025-08-26 06:21:58 +02:00
smiki b6d725920a [ADDED] ValidateAndRepositionGroundUnits to OPSGROUP 2025-08-25 23:22:00 +02:00
smiki cc76851614 [ADDED] ValidateAndRepositionGroundUnits to UNIT and GROUP respawns 2025-08-25 23:08:25 +02:00
Thomas c30d517a00 Merge pull request #2369 from FlightControl-Master/master
Merge from master
2025-08-25 12:09:30 +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 c96249906e Merge pull request #2367 from FlightControl-Master/master
QuickFix
2025-08-24 16:36:33 +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 0a56624657 Merge pull request #2365 from FlightControl-Master/master
Ground Spawn Options to avoid non-terrain by Heartbreaker
2025-08-24 15:25:46 +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 1b169f007c xx 2025-08-15 14:26:41 +02:00
Applevangelist 8efcad123c Merge remote-tracking branch 'origin/master' into develop 2025-08-14 17:18:03 +02:00
Applevangelist b9cf1e46af xx 2025-08-14 17:17:34 +02:00
Applevangelist 47409b11cb Merge remote-tracking branch 'origin/master' into develop 2025-08-14 17:16:30 +02:00
Applevangelist 4a04d7cce7 xx 2025-08-14 17:15:43 +02:00
Applevangelist 5ef6383c63 Merge remote-tracking branch 'origin/master' into develop 2025-08-14 09:13:32 +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
Thomas 38dcd04334 Merge pull request #2363 from FlightControl-Master/Applevangelist-patch-1
#EasyGCICAP Adjustments for CAP ZONE using
2025-08-11 12:58:30 +02:00
Thomas b32a8a2899 #EasyGCICAP Adjustments for CAP ZONE using
Added missing computations for coordinate when the zone is moving
2025-08-11 12:57:37 +02:00
Applevangelist 8cac4dbf9e #TIRESIAS - allow documents to build 2025-08-10 13:35:24 +02:00
Applevangelist ef2bec72a1 Merge remote-tracking branch 'origin/master' into develop 2025-08-10 13:33:44 +02:00
Applevangelist 03c3a20b1b #AIRWING, #EASYGCICAP - allow moving zones as patrol points for CAP/TANKER/AWACS/RECON 2025-08-10 13:33:16 +02:00
Applevangelist 4c97d966a2 #MSRS - align google voices catalog with new voice types. 2025-08-10 13:20:22 +02:00
Applevangelist f075c02db5 #EASYGCICAP - small tweak to allow the airbase to be a carrier ship 2025-08-07 18:47:49 +02:00
Applevangelist 32e61a7a09 Merge remote-tracking branch 'origin/master' into develop 2025-08-07 11:31:54 +02:00
Applevangelist 674c6eec81 More randomness in functions using random coordinates 2025-08-07 11:30:44 +02:00
Thomas da535eaddc Merge pull request #2362 from FlightControl-Master/master
Merge from Master - SCORING
2025-08-07 11:17:24 +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 eb6eba25f3 Merge pull request #2359 from FlightControl-Master/master
Airbase new Sinai Bases
2025-08-04 16:12:01 +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 72d8b29699 Merge pull request #2357 from FlightControl-Master/master
Merge from master
2025-08-02 18:35:43 +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 1e7203320f Merge remote-tracking branch 'origin/master' into develop 2025-08-01 14:03:29 +02:00
Applevangelist e3b587aa95 xx 2025-08-01 14:03:12 +02:00
Applevangelist 13fa8f373e #MANTIS - added radar entry for Dog Ear and Nike 2025-08-01 14:02:57 +02:00
Applevangelist c3dc055fb2 #FLIGHTGROUP - avoid nil error on dynamic spawn clients when looking for theri original prarking space 2025-08-01 09:23:40 +02:00
Applevangelist 4e024f7173 #EASYGCICAP - added FuelLow/Critical settings and stopping of Airwings if you call Stop(). 2025-07-31 12:35:40 +02:00
Applevangelist 1248006f3d Merge remote-tracking branch 'origin/master' into develop 2025-07-31 09:48:23 +02:00
Applevangelist b318e8ae13 #AIRBOSS - Added :SetCarrierIllumination(Mode) 2025-07-31 09:47:54 +02:00
Thomas 1af4d44ca5 Merge pull request #2355 from FlightControl-Master/master
Merge from master
2025-07-31 09:27:03 +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 b9d738c1ad Merge remote-tracking branch 'origin/master' into develop 2025-07-29 17:39:08 +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 bd054b26c0 Merge remote-tracking branch 'origin/master' into develop 2025-07-29 12:05:29 +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 b3100d2f5e Merge remote-tracking branch 'origin/master' into develop 2025-07-29 10:03:34 +02:00
Applevangelist 4b1888a34d CSAR - Allow also the initial down message to be suppressed 2025-07-29 10:02:22 +02:00
Applevangelist f4cd214823 #TIRESIAS - Avoid creating SET_GROUPs all the time for player objects, cached now 2025-07-27 19:24:43 +02:00
Applevangelist b9be3aa7f8 xx 2025-07-27 14:50:45 +02:00
Thomas bb6db2b7f8 Merge pull request #2352 from FlightControl-Master/master
Merge from Master
2025-07-27 14:16:07 +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 9520782a04 Merge pull request #2350 from FlightControl-Master/master
Merge from master
2025-07-26 09:02:12 +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 1860366986 Merge remote-tracking branch 'origin/master' into develop 2025-07-25 19:06:34 +02:00
Applevangelist 9db1d38a15 #TIRESIAS - some optimization 2025-07-25 19:06:12 +02:00
Applevangelist 04ceda693b #AUTOLASE - switch off increased ground awareness as default 2025-07-25 19:05:40 +02:00
Applevangelist 23ff128ac8 #ZONE added ZONE_BASE:FindNearestCoordinateOnRadius() 2025-07-25 19:05:01 +02:00
Applevangelist 3749142670 Merge remote-tracking branch 'origin/master' into develop 2025-07-25 14:58:41 +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 7279da7f09 xx 2025-07-24 18:26:28 +02:00
Applevangelist 31c40c96f2 Merge remote-tracking branch 'origin/develop' into develop 2025-07-24 16:21:24 +02:00
Applevangelist 7a833365ce #CONTROLLABLE - added options for landing approaches
* Prefer vertical for helos
and for aircraft
* Straight in
* Overhead break
* Force pair
* Restrict pair

You can also set these on AirWing and FlightGroup levels

#AUFTRAG - added dive bomb option to NewBombing
2025-07-24 16:21:04 +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 0ac156f2b5 Merge pull request #2346 from FlightControl-Master/master
Merge from master
2025-07-24 09:40:00 +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 179cb5f589 Merge remote-tracking branch 'origin/master' into develop 2025-07-23 15:48:26 +02:00
Applevangelist 367014ebf3 xxx 2025-07-23 15:47:56 +02:00
Applevangelist 9d8d0c2155 Merge remote-tracking branch 'origin/develop' into develop 2025-07-23 12:36:05 +02:00
Applevangelist edfe91274d Merge remote-tracking branch 'origin/master' into develop 2025-07-23 12:36:01 +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
Thomas dad91cca8c Merge pull request #2343 from shaji-Dev/develop
[FIXED] COMMANDER.maxMissionsAssignPerCycle typo
2025-07-22 18:55:50 +02:00
smiki 2f9c384ac0 [FIXED] COMMANDER.maxMissionsAssignPerCycle typo 2025-07-22 18:45:02 +02:00
Applevangelist f23a2267cf Merge remote-tracking branch 'origin/master' into develop 2025-07-22 13:09:48 +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 b39a83ad6e Merge remote-tracking branch 'origin/master' into develop 2025-07-21 15:03:22 +02:00
Applevangelist 7ae4cdc8f1 #Documentation 2025-07-21 15:02:45 +02:00
Applevangelist 7d47227fab Merge remote-tracking branch 'origin/develop' into develop 2025-07-21 14:50:42 +02:00
Applevangelist 1f09b8fe0b Merge remote-tracking branch 'origin/master' into develop 2025-07-21 14:50:38 +02:00
Applevangelist 8c92a578ed #UTILS - added UTILS.SpawnMASHStatics() 2025-07-21 14:50:08 +02:00
Thomas 992f09d9ba Merge pull request #2342 from FlightControl-Master/master
Vnao Airboss exits
2025-07-21 09:11:12 +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 bdad38e707 Merge remote-tracking branch 'origin/master' into develop 2025-07-20 14:04:24 +02:00
Applevangelist 1b18ae1597 #MANTIS - Added SAMP/T, SA-17 data correction, HDS explanations expanded 2025-07-20 14:03:33 +02:00
Thomas 8dcc3cbe8f Merge pull request #2340 from shaji-Dev/develop
[ADDED] COMMANDER:SetMaxMissionsAssignPerCycle
2025-07-20 12:28:36 +02:00
smiki aa8f3a824c [ADDED] COMMANDER:SetMaxMissionsStartPerCycle 2025-07-20 12:12:31 +02:00
smiki b5a19528a1 [ADDED] COMMANDER:SetMaxMissionsStartPerCycle 2025-07-20 12:11:57 +02:00
Thomas bd20e8fc81 Merge pull request #2339 from shaji-Dev/develop
Develop
2025-07-20 11:51:57 +02:00
smiki 2f806801bc [ADDED] AUFTRAG:SetRepeatDelay 2025-07-20 11:48:35 +02:00
shaji-Dev be006bd2bf Merge branch 'FlightControl-Master:develop' into develop 2025-07-20 11:44:34 +02:00
Applevangelist 18a08288ec Merge remote-tracking branch 'origin/master' into develop 2025-07-19 18:36:40 +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 f602455d1f Merge remote-tracking branch 'origin/master' into develop 2025-07-19 16:05:55 +02:00
Applevangelist d5c34a37b0 #AICSAR - Added functionality to use rescue zones instead of pure distance. Fixed helo not despawning after landing back at base. 2025-07-19 16:05:28 +02:00
Applevangelist 8a0e9a3400 #Fix SRS TTS folder path in documentation and defaults 2025-07-19 16:05:06 +02:00
Applevangelist 0e836973fd #Fix SRS TTS folder path in documentation and defaults 2025-07-19 16:04:49 +02:00
Applevangelist 1b57af88a0 Merge remote-tracking branch 'origin/master' into develop 2025-07-18 18:10:43 +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
Applevangelist 00de8d911c Merge remote-tracking branch 'origin/develop' into develop 2025-07-18 09:24:58 +02:00
smiki 9df3fcfdf7 [FIXED] attempt to index local 'airbase' (a nil value) 2025-07-17 23:36:23 +02:00
Thomas d675e34f37 Merge pull request #2338 from shaji-Dev/develop
[FIXED] AIRWING operational regardless of airbase coalition
2025-07-17 07:38:43 +02:00
smiki 2d96ba0f56 [FIXED] AIRWING operational regardless of airbase coalition 2025-07-16 23:39:04 +02:00
smiki 21c2bd1103 [FIXED] AIRWING operational regardless of airbase coalition 2025-07-16 23:17:47 +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 b9197d65d5 Merge pull request #2334 from shaji-Dev/develop
[ADDED] GROUP.Attribute.GROUND_SHORAD
2025-07-15 10:35:36 +02:00
smiki ec6f190b68 [ADDED] GROUP.Attribute.GROUND_SHORAD 2025-07-15 10:16:49 +02:00
Thomas 5e4f9f035b Merge pull request #2333 from shaji-Dev/develop
[FIXED] AUFTRAG and FSM state mismatch workaround `AUFTRAG:CheckGroupsDone`
2025-07-14 19:18:05 +02:00
smiki 7b6bf7f39b [FIXED] AUFTRAG and FSM state mismatch workaround for AUFTRAG:CheckGroupsDone 2025-07-14 19:04:26 +02:00
Thomas 2e8875dd2f Update Auftrag.lua
Fix catch all check groups 
2025-07-14 10:13:38 +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 124ebd3240 xxx 2025-07-05 18:57:39 +02:00
Applevangelist 7728609165 Merge remote-tracking branch 'origin/master' into develop 2025-07-05 18:57:27 +02:00
Applevangelist da70f4ce6c #DynamicSlots for dynamic FARPs 2025-07-05 18:56:59 +02:00
Applevangelist 69b3e9abad Small fix 2025-07-04 18:47:08 +02:00
Applevangelist f9f77bfa7b xxx 2025-07-04 18:46:56 +02:00
Applevangelist 429db73854 #AUFTRAG - fix condition for assets done test 2025-07-04 16:22:55 +02:00
Applevangelist 1e9c45c115 Merge remote-tracking branch 'origin/master' into develop 2025-07-03 16:39:55 +02:00
Applevangelist 727cb3276c #SET fix for table insert of GetAliveSet 2025-07-03 16:39:24 +02:00
Applevangelist a68175448d Merge remote-tracking branch 'origin/master' into develop 2025-07-03 15:15:54 +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
Applevangelist d7431478d1 Merge remote-tracking branch 'origin/master' into develop 2025-07-03 14:59:14 +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 dcdea379ef Merge remote-tracking branch 'origin/master' into develop 2025-07-03 11:59:23 +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
Applevangelist 2088359756 Merge remote-tracking branch 'origin/master' into develop 2025-07-03 10:55:02 +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
Applevangelist 0ab6a10ec4 #AWACS - added FSM transitions for VID Success and Failure 2025-06-29 15:50:24 +02:00
Thomas 73f393c542 Merge pull request #2328 from FlightControl-Master/master
Merge
2025-06-24 19:28:33 +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 7ec7228cb8 Merge pull request #2326 from FlightControl-Master/master
Merge from master
2025-06-24 18:23:19 +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 1f268b3b5d Merge branch 'master' into develop 2025-06-23 22:43:13 +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 4a5204aecb Merge pull request #2323 from FlightControl-Master/master
Merge
2025-06-23 19:09:47 +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 10262fd30b Merge pull request #2321 from FlightControl-Master/master
Merge from master
2025-06-20 14:03:40 +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 fa951838d2 Merge pull request #2319 from FlightControl-Master/master
Merge from master
2025-06-19 09:16:30 +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 66157d0596 Merge pull request #2316 from FlightControl-Master/master
Fixes from Master
2025-06-18 14:34:04 +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 93a8d8bc2d Merge remote-tracking branch 'origin/master' into develop 2025-06-15 17:02:35 +02:00
Applevangelist cbcc893ce5 #CTLD - avoid smoking runways on airbase zones 2025-06-15 17:01:58 +02:00
Applevangelist c19713949d Merge remote-tracking branch 'origin/master' into develop 2025-06-15 15:42:57 +02:00
Applevangelist 54450935a1 Merge remote-tracking branch 'origin/develop' into develop 2025-06-15 15:42:37 +02:00
Applevangelist d0f5712ca8 #AUFTRAG - Allow CAP Auftrag w/o Zone 2025-06-15 15:42:33 +02:00
Applevangelist 382b049c5f #AIRBASE - Syria and Sinai few names corrected 2025-06-15 15:38:12 +02:00
Thomas 6c2cc37abe Merge pull request #2315 from FlightControl-Master/master
Update Airbase.lua
2025-06-15 13:15:30 +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 83447a3fb4 Merge pull request #2314 from FlightControl-Master/master
Csar
2025-06-15 10:19:19 +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 52cbb7202c #EASYGCICAP - more noob catches 2025-06-12 09:09:38 +02:00
Frank f6a8317c42 Merge branch 'develop' of https://github.com/FlightControl-Master/MOOSE into develop 2025-06-10 21:58:21 +02:00
Frank 2a9a7db9b8 OPSGROUP
- Improved behaviour when mission is unpaused and groups are teleported
2025-06-10 21:58:19 +02:00
Applevangelist 3aeec78f79 Merge remote-tracking branch 'origin/master' into develop 2025-06-10 18:05:58 +02:00
Applevangelist 0aeb1fc6af #UTILS - Small fix for GetReportingName to distinguish Shark from Mainstay 2025-06-10 18:05:02 +02:00
Applevangelist 26565d7549 #EASYGCICAP - Added noob/fatfinger checks for airbase static warehouses and CAP point airwing names 2025-06-10 09:25:00 +02:00
Applevangelist 62816f217b Merge remote-tracking branch 'origin/master' into develop 2025-06-08 18:43:35 +02:00
Applevangelist eeeeda4e5e #POINT - Offset options for smoke 2025-06-08 18:43:01 +02:00
Applevangelist 95767c5ef4 AIRBOSS - Remove useless E Messages for non-debug 2025-06-01 12:20:08 +02:00
Applevangelist f5881eda53 AIRBOSS - Remove useless E Messages for non-debug 2025-06-01 12:19:42 +02:00
Applevangelist fca6faa3a8 xx 2025-05-30 20:51:04 +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
Thomas 638f083729 Merge pull request #2310 from shaji-Dev/develop
CSAR Downed Pilot Queue
2025-05-30 18:36:33 +02:00
shaji 59d41cf98b - [ADDED] Removes previous downed pilot with the same player name in Ejection event
- [ADDED] `useFIFOLimitReplacement` If true, it will remove the oldest downed pilot when a new one is added, if the limit is reached (FIFO queue), otherwise does not add downed pilots when the limit is reached.
2025-05-30 16:03:01 +02:00
Applevangelist 793adafda7 Merge remote-tracking branch 'origin/master' into develop 2025-05-30 11:14:33 +02:00
Applevangelist dd5ca93f26 CSAR Small addition 2025-05-30 11:13:50 +02:00
Thomas 0d1a7c770b Merge pull request #2309 from FlightControl-Master/master
Merge from master
2025-05-25 09:12: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 b3f944e82e Merge remote-tracking branch 'origin/master' into develop 2025-05-24 15:54:14 +02:00
Applevangelist 2fc16ba694 Runway text duplication 2025-05-24 15:53:43 +02:00
Thomas 432fc0ef4b Merge pull request #2307 from shaji-Dev/develop
[ADDED] `TARGET:GetObjects()` and `TARGET:GetCoordinates()` in case of SET
2025-05-24 12:50:44 +02:00
shaji 20c50c751f [ADDED] Sets target support for Auftrag STRIKE and BOMBING 2025-05-24 11:29:01 +02:00
shaji d3b62d0260 [ADDED] TARGET:GetObjects() and TARGET:GetCoordinates() in case of SET 2025-05-24 11:18:41 +02:00
Applevangelist d0449265c1 Merge remote-tracking branch 'origin/master' into develop 2025-05-21 10:22:16 +02:00
Applevangelist a4feafab8e #POINT - improved IsDay() for Kola 2025-05-21 10:21:48 +02:00
Applevangelist 309eedd165 Merge remote-tracking branch 'origin/master' into develop 2025-05-21 10:05:30 +02:00
Applevangelist 997baf21a0 #CSAR fix for ADF beacons 2025-05-21 10:04:58 +02:00
Applevangelist fa676cc750 Merge remote-tracking branch 'origin/master' into develop 2025-05-16 13:43:27 +02:00
Applevangelist b126cc00d0 xx 2025-05-16 13:43:03 +02:00
Applevangelist 1e0c27f599 Merge remote-tracking branch 'origin/master' into develop 2025-05-16 12:00:32 +02:00
Applevangelist 09b7922b84 Small fixes 2025-05-16 11:58:40 +02:00
Applevangelist 66032d6894 #EASYGCICAP - added SetDefaultTakeOffType() 2025-05-15 18:24:26 +02:00
Applevangelist 7c98a793c7 Merge remote-tracking branch 'origin/master' into develop 2025-05-15 17:08:28 +02:00
Applevangelist 7a5b9a75f3 #AIRBASE - added Syria Marka AFB 2025-05-15 17:07:55 +02:00
Applevangelist 0ea5631955 Merge remote-tracking branch 'origin/master' into develop 2025-05-15 13:20:07 +02:00
Applevangelist 4bab2ee1de Add deprecated banner 2025-05-15 13:19:42 +02:00
Applevangelist f5b9713639 Merge remote-tracking branch 'origin/master' into develop 2025-05-15 11:42:54 +02:00
Applevangelist 1bfb4fc4e1 Small fix 2025-05-15 11:42:27 +02:00
Applevangelist d7defe6f7f xx 2025-05-15 11:42:05 +02:00
Applevangelist ebb94c07b3 Small fix 2025-05-15 10:05:11 +02:00
Applevangelist f4cdbec376 Merge remote-tracking branch 'origin/develop' into develop 2025-05-15 08:52:18 +02:00
Applevangelist 21d5a5dfac Merge remote-tracking branch 'origin/master' into develop 2025-05-15 08:52:14 +02:00
Applevangelist f8947aab9c #MANTIS - Make DLINK caching (DEV version) configureable 2025-05-15 08:51:44 +02:00
Applevangelist db869bcb6d #MANTIS - Make DLINK caching (DEV version) configureable 2025-05-15 08:51:30 +02:00
Thomas 36a0cfd635 Merge pull request #2306 from FlightControl-Master/master
Merge
2025-05-15 06:52:23 +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 acbcb14cba Merge remote-tracking branch 'origin/master' into develop 2025-05-12 17:51:12 +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 67ef6c6e7b Merge pull request #2304 from FlightControl-Master/master
Nil check
2025-05-12 07:01:15 +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
Applevangelist eacc43cb5a Merge remote-tracking branch 'origin/develop' into develop 2025-05-04 12:54:33 +02:00
Applevangelist f3dcde075c Merge remote-tracking branch 'origin/master' into develop
# Conflicts:
#	Moose Development/Moose/AI/AI_Formation.lua
#	Moose Development/Moose/Functional/Fox.lua
2025-05-04 12:54:27 +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 615afb7cc4 Merge pull request #2300 from FlightControl-Master/master
Merge from master
2025-05-03 20:33:49 +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 6791a0e704 Merge remote-tracking branch 'origin/master' into develop 2025-05-03 17:02:29 +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 f999e45323 Merge remote-tracking branch 'origin/master' into develop 2025-05-02 10:53:29 +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 4747f3f48f Merge branch 'master' into develop 2025-05-01 22:11:54 +02:00
Frank f97ef25104 Update Unit.lua 2025-05-01 22:11:43 +02:00
Thomas e1a670185e Merge pull request #2298 from FlightControl-Master/master
CTLD - Fix issue when a ship zone is destroyed
2025-04-28 09:22:32 +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 b678e2cde1 Merge remote-tracking branch 'origin/master' into develop 2025-04-27 11:26:51 +02:00
Applevangelist db23a0bf2b #FlightGroup - added nil check for name 2025-04-27 11:26:22 +02:00
Applevangelist 3ad60a95ce #MANTIS - Adde Gepard data, made Roland Short 2025-04-27 11:25:46 +02:00
Frank 5c3b7312c0 Update Range.lua
- Reduced smoke duration at impact coordinate to 30 seconds
2025-04-26 23:55:13 +02:00
Frank f177d0a257 Merge branch 'master' into develop 2025-04-26 23:39:34 +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 c49b56eefc Merge pull request #2296 from FlightControl-Master/master
Merge from master
2025-04-26 07:53:01 +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
Applevangelist e21236655a Merge remote-tracking branch 'origin/develop' into develop 2025-04-24 14:48:17 +02:00
Applevangelist cdad3bd058 #PLAYERTASK - make an existing marker move with the group if the group is moving around 2025-04-24 14:48:12 +02:00
Thomas 0db9c27f7e Merge pull request #2294 from FlightControl-Master/master
Merge from master
2025-04-23 14:23:04 +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 68a539923f Merge pull request #2292 from FlightControl-Master/master
Range os.date fix
2025-04-23 09:24:02 +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 3442725525 Merge pull request #2290 from FlightControl-Master/master
Merge from master
2025-04-23 06:29:32 +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 326e27327d Merge pull request #2286 from FlightControl-Master/master
Kola airbase additions
2025-04-21 19:38:24 +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 296d4b1e93 Merge remote-tracking branch 'origin/master' into develop 2025-04-20 17:49:54 +02:00
Applevangelist 0f6439cf9f #MANTIS - added C-RAM Point Defense 2025-04-20 17:49:25 +02:00
Applevangelist 9705b49dbe #PLAYERTASKMANAGER - Surfaced some functions for conflict zones 2025-04-20 15:52:30 +02:00
Applevangelist 9364579a18 #EASYGCICAP - fixed some wrongly used self.values
#OPSZONE - make check time schedule configureable
2025-04-19 17:53:07 +02:00
Frank 02a6d8f2c0 Merge branch 'master' into develop 2025-04-18 17:50:11 +02:00
Frank 2c10943cb1 Update Airbase.lua
Germany map Umlaute
2025-04-18 17:50:01 +02:00
Frank a293c59d6d Merge branch 'master' into develop 2025-04-18 17:46:00 +02:00
Frank 544db963ea Update Airbase.lua 2025-04-18 17:45:43 +02:00
Frank d3fd21e6da Merge branch 'master' into develop 2025-04-18 17:41:07 +02:00
Frank 207698a2dd Update Airbase.lua
- Germany map readded Umlaute in keys
2025-04-18 17:40:55 +02:00
Applevangelist 27cd90a0ce Merge remote-tracking branch 'origin/master' into develop 2025-04-18 16:02:56 +02:00
Applevangelist d1ae2c0f5e xx 2025-04-18 16:01:55 +02:00
Applevangelist 66e6a603f1 Merge remote-tracking branch 'origin/master' into develop 2025-04-18 14:46:45 +02:00
Applevangelist 0392417189 Germany CW Bases 2025-04-18 14:46:13 +02:00
Frank 0678ad17f8 Merge branch 'master' into develop 2025-04-17 21:34:17 +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 d7d46d4f1b Merge pull request #2283 from FlightControl-Master/master
Merge from master
2025-04-17 08:45:51 +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 e958ca103a #EASYGCICAP - make conflict zones setup a bit more explic 2025-04-15 11:45:49 +02:00
Applevangelist 1d9ef869a7 Merge remote-tracking branch 'origin/master' into develop 2025-04-14 12:23:37 +02:00
Applevangelist 6fdf9a649f #AIRBASE rescribe umlauts 2025-04-14 12:23:12 +02:00
Applevangelist 90c6c57449 Merge remote-tracking branch 'origin/master' into develop 2025-04-14 12:11:56 +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 ecce2eff9b Merge pull request #2281 from FlightControl-Master/master
Merge
2025-04-12 10:52:39 +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 4b23c86daa Merge remote-tracking branch 'origin/master' into develop 2025-04-09 08:16:20 +02:00
Applevangelist 49c11073e6 #MANTIS Mod data updates 2025-04-09 08:15:50 +02:00
Applevangelist daa5caa125 Merge remote-tracking branch 'origin/master' into develop 2025-04-07 11:57:39 +02:00
Applevangelist 1a156e7e12 #CTLD - make menu build for CA a bit faster 2025-04-07 11:57:15 +02:00
Applevangelist 6fe88a6319 Merge remote-tracking branch 'origin/master' into develop 2025-04-07 10:40:58 +02:00
Applevangelist 1856754614 #Smaller Changes 2025-04-07 10:40:30 +02:00
Thomas b9f6c1b9c7 Merge pull request #2277 from FlightControl-Master/master
Update docs-header.py
2025-04-06 16:33:05 +02:00
Thomas 6ac452ff15 Update docs-header.py 2025-04-06 16:28:19 +02:00
Applevangelist b52176a0ff Merge remote-tracking branch 'origin/master' into develop 2025-04-06 16:19:43 +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 d09f0b1f6f Update classes-core.md 2025-04-06 15:47:52 +02:00
Thomas e50e572c78 Update classes-core.md 2025-04-06 15:43:09 +02:00
Applevangelist 2e688e7da1 Merge remote-tracking branch 'origin/master' into develop 2025-04-06 15:38:55 +02:00
Applevangelist 3083599158 #CTLD - Allow CA Ground Transport 2025-04-06 15:38:26 +02:00
Applevangelist 2921f7a76b Merge remote-tracking branch 'origin/master' into develop 2025-04-03 14:22:25 +02:00
Applevangelist b7b6c1ea19 #RADIOQUEUE - small tweak for a group when a unit dies. 2025-04-03 14:21:58 +02:00
Applevangelist 8a185c352e Merge remote-tracking branch 'origin/master' into develop 2025-04-03 11:49:30 +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 3fc8f52796 Merge remote-tracking branch 'origin/master' into develop 2025-04-03 09:29:57 +02:00
Applevangelist ddf33da787 #DYNAMICCARGO - Hover / Sling checks 2025-04-03 09:29:19 +02:00
Thomas e7cee4d97b Merge pull request #2276 from FlightControl-Master/master
Small fixes
2025-04-02 16:13:50 +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 bad9d1ea92 Merge pull request #2274 from FlightControl-Master/master
Fix SpawnStatic
2025-04-02 09:45:44 +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 f5b1050086 Merge remote-tracking branch 'origin/master' into develop 2025-04-01 15:27:55 +02:00
Applevangelist 4074023ed3 #DYNAMICCARGO - enhance checks for unloading cargo from hovering Hooks 2025-04-01 15:27:23 +02:00
Applevangelist f729b1d358 Merge remote-tracking branch 'origin/master' into develop 2025-04-01 14:13:42 +02:00
Applevangelist 6c00b0c7eb #POINT - some catches for POINT_VEC2 behaviour 2025-04-01 14:13:14 +02:00
Applevangelist 5adefe6f7b Merge remote-tracking branch 'origin/master' into develop 2025-04-01 13:18:55 +02:00
Applevangelist 76dc0d690a #POINT - Removal of References to legacy POINT_VEC2/3 classes 2025-04-01 13:17:48 +02:00
Thomas 13c16b8674 Merge pull request #2272 from shaji-Dev/develop
[Fixed] Parameter #1 (unit name) is incorrect
2025-03-31 14:05:41 +02:00
Thomas 222722225e Update OpsGroup.lua
Better make this a unit and alive check
2025-03-31 14:04:07 +02:00
shaji 82e1dcfc04 [Fixed] Parameter #1 (unit name) is incorrect 2025-03-31 13:11:56 +02:00
Thomas c26220d1fd Merge pull request #2271 from FlightControl-Master/master
DynamicCargo small fixes
2025-03-31 12:32:55 +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
Applevangelist dd0b2ace65 Merge remote-tracking branch 'origin/master' into develop 2025-03-30 16:51:23 +02:00
Applevangelist dc83af4d02 #SHORAD - fix typo for maxscootdist
#CTLD - slight refactoring of fixed wing support.
* Added `CTLD:AddAllowedFixedWingType(typename)` to add new types
* Renamed enabler flags into `enableFixedWing, FixedMinAngels, FixedMaxAngels, FixedMaxSpeed`
* Base support for Mosquito added
2025-03-30 16:50:43 +02:00
Applevangelist 342e901dd1 Merge remote-tracking branch 'origin/master' into develop 2025-03-28 15:05:57 +01:00
Applevangelist 0a38700edb #AI_Patrol - small enhancement 2025-03-28 15:05:30 +01:00
Applevangelist 659615114a xx 2025-03-28 15:04:42 +01:00
Applevangelist bfd26522d6 Merge remote-tracking branch 'origin/develop' into develop 2025-03-27 11:09:06 +01:00
Applevangelist 00d14c7c0a #PLAYERRECCE - small tweak for visual distance setting 2025-03-27 11:09:01 +01:00
Frank 47c9e1ba1f Update Legion.lua
- Dead assets are removed from cohort & legion
2025-03-23 22:45:15 +01:00
Frank 92e680a276 Merge branch 'master' into develop 2025-03-23 14:11:37 +01:00
Frank 4955fe4d92 Update Spawn.lua
- Fix for problem that helos are not spawned on ships but at origin of the map
2025-03-23 14:11:21 +01:00
Applevangelist e439bcdd0f Merge remote-tracking branch 'origin/master' into develop 2025-03-22 14:59:08 +01:00
Applevangelist 792aa73832 #AIBRASE - Afghanistan new Airbases 2025-03-22 14:58:24 +01:00
Applevangelist d375e0ce29 #AUTOLASE - small fix for interval 2025-03-22 10:42:36 +01:00
Applevangelist e3670219ed Merge remote-tracking branch 'origin/master' into develop 2025-03-21 09:22:36 +01:00
Applevangelist a915452e6e #COORDINATE - use magnetic for BRAA 2025-03-21 09:22:08 +01:00
Applevangelist 6662a1cf97 Merge remote-tracking branch 'origin/master' into develop 2025-03-16 16:57:38 +01:00
Applevangelist be8405b72b #MANTIS - fix for data table 2025-03-16 16:57:11 +01:00
Applevangelist 9b24695377 Merge remote-tracking branch 'origin/master' into develop 2025-03-16 13:59:23 +01:00
Applevangelist 5ca3e3b2b8 #SHORAD tweak 2025-03-16 13:58:58 +01:00
Applevangelist 8bbef34b74 Merge remote-tracking branch 'origin/master' into develop 2025-03-16 13:07:19 +01:00
Applevangelist 618a8744a2 #MANTIS - improve point defense behaviour if not SAM to defend is around 2025-03-16 13:06:53 +01:00
Applevangelist 5329da32eb Merge remote-tracking branch 'origin/develop' into develop 2025-03-16 11:02:59 +01:00
Applevangelist df86c3f2a1 #AUTOLASE - added a function to allow to set the monitoring report frequency 2025-03-16 11:02:55 +01:00
Frank 784fcb7882 Merge branch 'master' into develop 2025-03-15 22:49:57 +01:00
Frank 23aeef7a20 Airbase
- Airbase changes for helipads that are also airdromes
- Improved SpawnAtAirbase function
2025-03-15 22:49:43 +01:00
Applevangelist 0ee24b86dc Merge remote-tracking branch 'origin/master' into develop 2025-03-15 16:30:01 +01:00
Applevangelist 9ac4f136aa #MANTIS - extend scaling for short/point systems to make them more reactive 2025-03-15 16:29:24 +01:00
Applevangelist ca9b2d79cc Merge remote-tracking branch 'origin/master' into develop 2025-03-15 10:56:34 +01:00
Applevangelist c9a09c2fc9 #SOUND/MSRS - small fix to delete the "--ssml" tag if google provider is used in conjunction with a file based sound output. 2025-03-15 10:56:13 +01:00
Applevangelist 813286f7f3 Merge remote-tracking branch 'origin/master' into develop 2025-03-14 10:41:13 +01:00
Applevangelist 6028c91f81 #NET small fix if PlayerSlot remains nil 2025-03-14 10:40:52 +01:00
Frank 11b6bb2638 Merge branch 'master' into develop 2025-03-13 16:41:25 +01:00
Frank 3c57928f46 Update Airbase.lua
- Fixed bug in counting the number of parking spots per terminal type
2025-03-13 16:40:57 +01:00
Applevangelist e091e659a2 Merge remote-tracking branch 'origin/master' into develop 2025-03-13 10:51:00 +01:00
Applevangelist 32f0bb33c3 #ZONE - Trigger added OnAfterZoneEmpty and OnAfterObjectDead 2025-03-13 10:50:15 +01:00
Applevangelist dea64751c3 Merge remote-tracking branch 'origin/master' into develop 2025-03-12 09:18:43 +01:00
Applevangelist 31d0410284 #TEMPLATES remove files 2025-03-12 08:56:13 +01:00
Applevangelist 9cdf550432 #PLAYERTASKMANAGER - Allow use of multiple drones for lasing of precision bombing tasks 2025-03-12 08:45:08 +01:00
Applevangelist 09525029ab Merge remote-tracking branch 'origin/master' into develop
# Conflicts:
#	Moose Development/Moose/Modules.lua
#	Moose Setup/Moose.files
2025-03-12 08:44:00 +01:00
Applevangelist 87c436ba34 #STTS - remove from tree 2025-03-12 08:42:38 +01:00
Applevangelist b1002017e5 Merge remote-tracking branch 'origin/master' into develop 2025-03-11 16:30:07 +01:00
Applevangelist 6e9727e265 xx 2025-03-11 16:29:31 +01:00
Applevangelist 383e953ba1 Merge remote-tracking branch 'origin/master' into develop 2025-03-11 10:52:40 +01:00
Applevangelist 94ee76fe62 #CONTROLLABLE - Improved IR Markers 2025-03-11 10:52:16 +01:00
Frank 9b52b640e6 Merge branch 'master' into develop 2025-03-10 19:53:51 +01:00
Frank ea23162ca9 Update Spawn.lua
- Enabled explicit parking spots in SpawnAtAirbase
2025-03-10 19:53:24 +01:00
Thomas 68d0220912 Merge pull request #2268 from FlightControl-Master/master
merge from master
2025-03-10 15:35:08 +01:00
Thomas 683388faee Merge pull request #2266 from FlightControl-Master/Applevangelist-IR-1
Update Controllable.lua
2025-03-10 15:32:07 +01:00
Thomas 56ec3920c5 Update Controllable.lua
IR Strobe . some improvements
2025-03-10 13:12:00 +01:00
Thomas 88842d1c67 Merge pull request #2265 from FlightControl-Master/master
Update CTLD.lua
2025-03-10 10:57:19 +01:00
Thomas f335ffc4ec Update CTLD.lua
Clarify hover min/max height is in meters
2025-03-10 10:55:01 +01:00
Applevangelist f76aefa976 Merge remote-tracking branch 'origin/master' into develop 2025-03-09 14:37:56 +01:00
Applevangelist 4976cd86f2 ZONE_ELASTIC - function to remove vertices 2025-03-09 14:36:42 +01:00
Frank 2cd66ae1d4 Merge branch 'master' into develop 2025-03-08 21:37:59 +01:00
Frank c00eff8b23 AIRBASE
- AIRBASE: Workaround for DCS bug that helipads have category of airdrome
- SET_AIRBASE: Added FilterZones function
2025-03-08 21:37:43 +01:00
Applevangelist 7f0376561b Merge remote-tracking branch 'origin/master' into develop 2025-03-06 14:52:15 +01:00
Applevangelist 3c710613a8 CONTROLLABLE added HasIRMarker 2025-03-06 14:51:49 +01:00
Applevangelist 3585208547 Merge remote-tracking branch 'origin/master' into develop
# Conflicts:
#	Moose Development/Moose/Core/Zone.lua
2025-03-06 12:27:08 +01:00
Applevangelist 29c0017e80 xx 2025-03-06 12:26:24 +01:00
Applevangelist 45ebf9a3c7 #ZONE_ELASTIC - Fix zone filling 2025-03-06 12:25:57 +01:00
Frank 908e505ce3 Merge branch 'master' into develop 2025-03-05 20:48:28 +01:00
Frank c808e4a4e2 Update Airbase.lua
- Added FighterAircraftSmall parking spot type
2025-03-05 20:48:15 +01:00
Thomas e129eb97a7 Merge pull request #2263 from FlightControl-Master/master
ATIS
2025-03-03 14:21:02 +01:00
Thomas e2612b97d7 Merge pull request #2262 from FlightControl-Master/Applevangelist-Atis-Kola
Update ATIS.lua
2025-03-03 14:19:45 +01:00
Thomas 70e9d91bb5 Update ATIS.lua 2025-03-03 14:19:11 +01:00
Thomas 0b8810f8b3 Update ATIS.lua
ATIS - Fix for Kola map when no sunset or sunrise arise and SRS is not used
2025-03-03 14:16:47 +01:00
Applevangelist 3d39ccbdce Merge remote-tracking branch 'origin/master' into develop 2025-03-02 12:40:30 +01:00
Applevangelist 41b867a4ca #GROUP - ensure GROUP:GetCoordinate() returns a group heading data field 2025-03-02 12:40:00 +01:00
Applevangelist 427baa43d7 Merge remote-tracking branch 'origin/master' into develop 2025-02-23 16:12:14 +01:00
Applevangelist d4e141f3c5 #EASYGCICAP - use onbefore on foreign classes rather than OnAfter to avoid user overwrites 2025-02-23 16:11:36 +01:00
Applevangelist 1c0a8d9380 #SET_CLIENT - added option to handle CA slots
#CONTROLLABLE - fix typos
2025-02-23 16:10:32 +01:00
Thomas f05680f23d Merge pull request #2259 from FlightControl-Master/master
Master merge
2025-02-23 08:40:49 +01:00
Thomas 2b0b9d44eb Merge pull request #2258 from leka1986/patch-3
Update Controllable.lua
2025-02-23 08:40:00 +01:00
leka1986 2fc7a3b542 Update Controllable.lua
Fixing this error
Line 26056: attempt to index local '_coord' (a nil value)
in this line,
local _tocoord=_coord:GetRandomCoordinateInRadius(_radius,100)
2025-02-23 02:34:04 +01:00
Applevangelist 820ae2759b Merge remote-tracking branch 'origin/master' into develop 2025-02-22 16:36:52 +01:00
Applevangelist 12b596a47f #MANTIS - if no EWR system is left over, MANTIS will switch on a random SR/TR each cycle to detect incoming enemies. 2025-02-22 16:36:15 +01:00
Applevangelist a06d099917 Merge remote-tracking branch 'origin/master' into develop 2025-02-21 10:43:45 +01:00
Applevangelist 7552309a28 #AUTOLASE - option to make ground units aware of target to be lased 2025-02-21 10:43:14 +01:00
Applevangelist b9ad5b5ba7 #TARGET - add threat level determination for ZONE and OPSZONE 2025-02-21 10:42:52 +01:00
Applevangelist 8ef781a9ac #SET_BASE - added GetThreatLevelMax() 2025-02-21 10:39:21 +01:00
Applevangelist 5e24e8658b Merge remote-tracking branch 'origin/master' into develop 2025-02-19 17:33:17 +01:00
Applevangelist 43eeaede65 #SET - Error output for Addif the ObjectName variable is empty
#UNIT - Return zero is SpeedMax is nil
2025-02-19 17:32:37 +01:00
Frank 749c5f87de Merge pull request #2257 from leka1986/patch-2
Update Range.lua
2025-02-18 21:37:37 +01:00
leka1986 a520daeb56 Update Range.lua
attempt to index local 'target' (a nil value)

Was using this build in another mission. Added a nilcheck.
env.info('*** MOOSE GITHUB Commit Hash ID: 2025-02-14T06:13:08+01:00-24b320077721d45774acd56b25086ef6bdfb2e5a ***')
2025-02-18 21:23:58 +01:00
Applevangelist 9bb713db10 Merge remote-tracking branch 'origin/master' into develop 2025-02-18 11:14:00 +01:00
Applevangelist f9ba96f228 #MANTIS - New 4-Tier-Approach 2025-02-18 11:13:23 +01:00
Applevangelist a49bd23a2a #ATC_GROUND 2025-02-17 08:35:30 +01:00
Thomas 913b2c6d3f Merge pull request #2256 from FlightControl-Master/master
CTLD
2025-02-17 07:01:08 +01:00
Thomas cea2f18228 Merge pull request #2255 from leka1986/patch-1
Update CTLD.lua
2025-02-17 07:00:18 +01:00
leka1986 fd2d8a5119 Update CTLD.lua
Now in the listcargo, (cargo onboard) I will display CargoName and a number / number instead of listing each crate, 5 lines for 5 crates. 

Now 1 line for each CargoName and 2/2 or 3/3, etc.

"Rescan" have been moved to only show up if it detects lesser then what it's needed when loading.
2025-02-16 17:16:05 +01:00
Thomas 24b3200777 Merge pull request #2254 from FlightControl-Master/master
Tld
2025-02-14 06:13:08 +01:00
Thomas fa4e0447dd Merge pull request #2253 from leka1986/patch-1
Update CTLD.lua
2025-02-14 06:11:49 +01:00
leka1986 31aa604fc4 Update CTLD.lua
Added _LoadSingleCrateSet Function
Added _refreshLoadCratesMenu Function
Added Event for Takeoff, Land.

Changes to the RefreshF10menus function
the menus does not gets deleted, and rebuild, but only what is inside them. 
So they will remain at the same position. 

tested multiple times
2025-02-14 00:20:23 +01:00
Applevangelist 3518c89791 Merge remote-tracking branch 'origin/master' into develop 2025-02-10 18:03:22 +01:00
Applevangelist f44db27565 #ATC_GROUND_UNIVERSAL
* Correct usage of airbase names if given
* Exclude FARPs and Ships
2025-02-10 18:02:42 +01:00
Thomas acaab0c6a9 Merge pull request #2251 from FlightControl-Master/master
CTLD
2025-02-10 06:02:33 +01:00
Thomas 9b1abab73a Merge pull request #2250 from leka1986/master
Update CTLD.lua
2025-02-10 06:01:30 +01:00
leka1986 cad8f15b61 Update CTLD.lua
Reworked the logic of the menu.
Now it will Show be shown :
1. Ammo truck
2. Humvee
3. Ammo truck 1/2 -- 1/2 due to incomplete set.

And for the troops

Squad 8 (2) -- 2 set of squad 8, Selecting this will only deploy 1 set.
Squad 16

Changed so when loading troops, it will state 
Squad 8 boarded. same for the extraction.

I have tested it and it works
Heart8reaker also tested it and no issues so far.
2025-02-09 23:41:16 +01:00
Applevangelist aafbd8c297 Merge remote-tracking branch 'origin/master' into develop 2025-02-09 12:24:41 +01:00
Applevangelist 1d08bcf2e0 #CTLD docu 2025-02-09 12:24:16 +01:00
Applevangelist 6d38346eb8 Merge remote-tracking branch 'origin/master' into develop
# Conflicts:
#	Moose Development/Moose/Ops/CTLD.lua
2025-02-09 12:05:57 +01:00
Applevangelist 9487a5ae91 #CTLD 2025-02-09 12:05:18 +01:00
Thomas d2bb6a4fc0 Merge pull request #2248 from leka1986/patch-4
Update CTLD.lua
2025-02-09 12:04:39 +01:00
Applevangelist c3ccecdd4a #AWACS - Escort vector catch for noobs not reading the description 2025-02-09 12:01:57 +01:00
leka1986 5ad54648ab Update CTLD.lua
Removed the block from partly drop 1. 

It's not helpful for the user to have 1 incomplete a set of crates onboard. 
With this line removed, If someone loads 2 items, and second item is not completed, due to crate limit or due weight, player can unload the uncomplete set.
2025-02-09 11:51:34 +01:00
Applevangelist 96337cc5df #CTLD 2025-02-09 11:48:22 +01:00
Thomas fa0ce0927b Merge pull request #2247 from leka1986/patch-3
Update CTLD.lua
2025-02-09 11:34:58 +01:00
leka1986 693c2a730f Update CTLD.lua
Added  self:_RefreshDropCratesMenu(Group, Unit) to  function CTLD:_LoadCratesNearby(Group, Unit)
2025-02-09 11:26:38 +01:00
Thomas 0d438a9452 Merge pull request #2246 from FlightControl-Master/master
Ctd changes
2025-02-09 09:23:25 +01:00
Thomas bc9eee22b7 Merge pull request #2245 from FlightControl-Master/Applevangelist-patch-1
Update CTLD.lua
2025-02-08 14:29:59 +01:00
Thomas f74d25b31c Update CTLD.lua
Option to unload single cargo items by @lekaa
2025-02-08 14:29:35 +01:00
Applevangelist 66af360ce6 Merge remote-tracking branch 'origin/master' into develop 2025-02-06 16:36:27 +01:00
Applevangelist ad9893c3ab Merge remote-tracking branch 'origin/develop' into develop 2025-02-06 16:35:03 +01:00
Thomas 1156971d94 Merge pull request #2243 from shaji-Dev/master
[ADDED] `UNIT:IsEWR()`
2025-02-06 12:22:18 +01:00
Shafik c79b5c37c4 [ADDED] UNIT:IsEWR() 2025-02-06 13:16:03 +02:00
Thomas b4e6201b68 Merge pull request #2242 from FlightControl-Master/Applevangelist-patch-1
Update Autolase.lua
2025-02-06 08:52:20 +01:00
Thomas f26d8d6822 Update Autolase.lua
Added option to set offset smoke parameter
2025-02-06 08:52:05 +01:00
Applevangelist 3d0b7b9267 #AUTOLASE - Add offset parameters for autolase:EnableSmokeMenu({Angle=math.random(0,359),Distance=math.random(10,20)}) 2025-02-06 08:50:33 +01:00
Thomas a2b650a9e3 Merge pull request #2241 from shaji-Dev/master
[FIXED] attempt to index field  (a nil value)
2025-02-03 12:03:04 +01:00
Shafik 905b442e9b [FIXED] attempt to index field (a nil value) 2025-02-03 09:03:43 +02:00
Thomas 7cd95377f9 Merge pull request #2240 from FlightControl-Master/master
Merge from master
2025-02-02 12:54:42 +01:00
Thomas 18fe3112bd Merge pull request #2238 from shaji-Dev/master
[ADDED] Set AI On/Off for units
2025-02-02 12:53:37 +01:00
Thomas 84e85dd0b5 Merge pull request #2239 from shaji-Dev/develop
Develop
2025-02-02 12:53:25 +01:00
Shafik 2744befbab [FIXED] Group not turning off due to conflicting condition checking true and false (if grp.Tiresias and grp.Tiresias.invisible and grp.Tiresias.invisible == false then)
[FIXED] Units turning on for same coalition aircrafts in radius
2025-02-02 13:27:03 +02:00
Shafik e87dc525b9 [FIXED] Group not turning off due to conflicting condition checking true and false (if grp.Tiresias and grp.Tiresias.invisible and grp.Tiresias.invisible == false then)
[FIXED] Units turning on for same coalition aircrafts in radius
2025-02-02 13:25:53 +02:00
Shafik cc057744ba [ADDED] UNIT:IsSAM() and UNIT:IsAAA() to use used in their respective GROUP functions. 2025-02-02 12:46:55 +02:00
Shafik db1779e1db [ADDED] Set AI On/Off for units 2025-02-02 11:42:40 +02:00
Applevangelist ed31b87b2f Merge remote-tracking branch 'origin/master' into develop 2025-02-01 18:40:44 +01:00
Applevangelist d1e31a3652 #PLAYERRECCE - add parameter for SRS Backend option 2025-02-01 18:40:26 +01:00
Applevangelist d25a723fc7 #MESSAGE - add parameter for SRS Backend 2025-02-01 18:39:51 +01:00
Applevangelist 3fb4cae7b8 Merge remote-tracking branch 'origin/master' into develop 2025-01-31 14:27:25 +01:00
Applevangelist f0fe1b431d #SPAWN - Add optional waiting time to InitRepeatOnLanding 2025-01-31 14:26:32 +01:00
Thomas 8e286edd25 Merge pull request #2237 from shaji-Dev/master
[FIXED] attempt to index a nil value
2025-01-31 10:04:01 +01:00
Shafik 74520b1359 [FIXED] attempt to index a nil value (AWACS:_CheckAwacsStatus -> OPSGROUP:GetCallsignName -> GROUP:IsPlayer) 2025-01-31 10:30:18 +02:00
shaji-Dev 0ffcdf2f66 Merge branch 'FlightControl-Master:develop' into develop 2025-01-31 10:21:37 +02:00
Applevangelist fe0edeb011 Merge remote-tracking branch 'origin/master' into develop 2025-01-30 18:33:06 +01:00
Applevangelist d06e44d37b #CTLD small additions 2025-01-30 18:32:39 +01:00
Applevangelist 35348d9b81 #UTILS - Added UTILS.Weather for fog stuff 2025-01-30 18:32:25 +01:00
Applevangelist d06a618582 Merge remote-tracking branch 'origin/master' into develop 2025-01-30 13:20:35 +01:00
Applevangelist 4b16e94eaf #CTLD - Added function for the game designer to get an overview of stock and alive groups, if they want to manage the stock: CTLD:_CountStockPlusInHeloPlusAliveGroups() 2025-01-30 13:19:11 +01:00
Applevangelist d5253f0420 Merge remote-tracking branch 'origin/master' into develop 2025-01-30 09:04:46 +01:00
Thomas d983676330 Merge pull request #2236 from Fedge7/fedge/enums-weapons
Fixes AH-64D FCR enum value, adds APKWS.
2025-01-30 06:56:44 +01:00
Fedge 03c30f3cce Adds the 2 primary APKWS rockets as entries in the ENUMS.Storage.weapons.missiles table.
I added them to `missiles`, rather than `nurs` because that's where they appear in the mission editor's storage window.
2025-01-29 18:48:34 -07:00
Fedge 99b93266ad Fixes the AH-64D's FCR enum weapon definition. 2025-01-29 18:47:44 -07:00
Thomas 4530b74367 Merge pull request #2235 from FlightControl-Master/master
merge from master
2025-01-29 15:31:29 +01:00
Thomas e307b57e67 Merge pull request #2234 from shaji-Dev/master
nil fixes
2025-01-29 13:58:42 +01:00
Shafik 5ef9bb2acd [FIXED] attempt to get length of local 'parking' (a nil value) 2025-01-29 14:44:31 +02:00
Shafik 4aacdc1567 [FIXED] attempt to index local 'CleanUpUnit' (a nil value) 2025-01-29 14:43:43 +02:00
Thomas 57552f4300 Merge pull request #2233 from FlightControl-Master/Applevangelist-patch-3
Update CTLD.lua
2025-01-29 13:24:45 +01:00
Thomas 09d53f7d8c Update CTLD.lua
#CTLD - Added HelicopterLost Event
2025-01-29 13:24:04 +01:00
Shafik 161bdc0413 [FIXED] attempt to concatenate field 'IniGroupName' (a nil value) ?? 2025-01-29 10:13:34 +02:00
Shafik 44ad362dbc [FIXED] attempt to index local 'CleanUpUnit' (a nil value) 2025-01-29 10:06:19 +02:00
Shafik ea776aeacc [FIXED] attempt to get length of local 'parking' (a nil value) 2025-01-29 10:05:55 +02:00
Frank e30479329a Merge branch 'master' into develop 2025-01-28 20:29:45 +01:00
Frank d9948d1a19 Update Group.lua 2025-01-28 20:29:35 +01:00
Frank b962096661 Update RAT.lua
- Tried to fix bug the Pnow is nil
2025-01-28 20:29:04 +01:00
Frank 725b55a505 Merge branch 'master' into develop 2025-01-28 20:22:57 +01:00
Frank 5f7a4f2bbb Update Group.lua
- Added way to get the coordinate of the group
2025-01-28 20:22:45 +01:00
Thomas f555399e2f Merge pull request #2231 from FlightControl-Master/master
Master merge
2025-01-28 08:32:34 +01:00
Thomas 1b6945e0b0 Merge pull request #2230 from FlightControl-Master/Applevangelist-patch-2
Update Scenery.lua
2025-01-28 08:31:33 +01:00
Thomas 4fd55b1bd6 Update Scenery.lua
#SCENERY
2025-01-28 08:31:17 +01:00
Applevangelist fb276cf812 Merge remote-tracking branch 'origin/master' into develop 2025-01-27 18:49:01 +01:00
Applevangelist 41dfaab82a xx 2025-01-27 18:48:39 +01:00
Thomas 20b8deb6de Merge pull request #2228 from FlightControl-Master/Applevangelist-patch-2
Update CTLD.lua
2025-01-27 18:46:07 +01:00
Thomas 6af836c118 Update CTLD.lua 2025-01-27 18:45:39 +01:00
Thomas f87b8a2c2a Merge pull request #2229 from FlightControl-Master/Applevangelist-patch-3
Update Base.lua
2025-01-27 18:44:50 +01:00
Thomas daffd7412a Update Base.lua 2025-01-27 18:44:35 +01:00
Thomas bfb60b318e Update CTLD.lua
update
2025-01-27 13:27:13 +01:00
Thomas a55959dfbb Update Base.lua
Added property functions
2025-01-27 12:00:25 +01:00
Thomas 4d24eb82be Update CTLD.lua
#CTLD - Add the group name of the extracted group to TroopsExtracted FSM event
2025-01-27 08:51:17 +01:00
Applevangelist 4656d3e019 Merge remote-tracking branch 'origin/develop' into develop 2025-01-26 17:35:11 +01:00
Applevangelist 86b76ba216 Merge remote-tracking branch 'origin/master' into develop 2025-01-26 17:35:06 +01:00
Applevangelist ff561410ad xx 2025-01-26 17:34:36 +01:00
Applevangelist e26caa2f74 smaller fixes 2025-01-26 17:34:22 +01:00
Applevangelist b32d17c2ab Merge remote-tracking branch 'origin/develop' into develop 2025-01-26 14:55:24 +01:00
Applevangelist 29111e1018 xx 2025-01-26 14:55:21 +01:00
Applevangelist 3433ebd665 Merge remote-tracking branch 'origin/master' into develop 2025-01-26 14:54:53 +01:00
Applevangelist b75fff60c8 xx 2025-01-26 14:54:19 +01:00
Applevangelist a47fa3f9fc Merge remote-tracking branch 'origin/master' into develop 2025-01-26 13:54:59 +01:00
Applevangelist 4ac57fce7a #CTLD - Added CTLD:GetGenericCargoObjectFromGroupName(GroupName) to get the generic CTLD_CARGO entry from a group name. 2025-01-26 13:54:28 +01:00
Applevangelist 6218b94c99 Merge remote-tracking branch 'origin/develop' into develop 2025-01-26 13:29:57 +01:00
Applevangelist 74a6c89801 Merge remote-tracking branch 'origin/master' into develop 2025-01-26 13:29:53 +01:00
Applevangelist 25a9a0120a #CTLD
- If stock is set, show stock number in menu entries
- Corrected table build for GetStockCrates/Troops/Statics
2025-01-26 13:29:18 +01:00
Thomas deb0747e66 Merge pull request #2227 from shaji-Dev/develop
[FIXED] `bad argument #2 to 'format' (number expected, got nil)`
2025-01-26 08:38:11 +01:00
Shafik 00f5fde5a8 [FIXED] bad argument #2 to 'format' (number expected, got nil) 2025-01-26 00:19:19 +02:00
Applevangelist 03cd354f9e Merge remote-tracking branch 'origin/master' into develop 2025-01-25 15:55:01 +01:00
Applevangelist 66a1fa8af5 #CTLD - small fix for LoadesGroupsTable inserts 2025-01-25 15:54:29 +01:00
Applevangelist c2096c8dfd Merge remote-tracking branch 'origin/master' into develop 2025-01-25 15:06:40 +01:00
Applevangelist 1b4033cfce CTLD Small fix for PlayerTask ExtractTroops 2025-01-25 15:04:33 +01:00
Applevangelist 750edf1144 Merge remote-tracking branch 'origin/master' into develop 2025-01-24 12:22:24 +01:00
Applevangelist 48bc41873a #STORAGE - Added small helper to get Syria "H" Helipad warehouses via a zone 2025-01-24 12:21:44 +01:00
Applevangelist 2e54f51229 Merge remote-tracking branch 'origin/develop' into develop 2025-01-24 10:30:29 +01:00
Applevangelist e39e414e0d Merge remote-tracking branch 'origin/master' into develop 2025-01-24 10:30:25 +01:00
Applevangelist 068a1ab99c #CTLD
- Added `OnAfterLoaded` which gives you access to the rebuild troops and vehicles in a table  of loaded groups, each entry is a table with three values: Group, TimeStamp and CargoType
2025-01-24 10:29:52 +01:00
Thomas e35d9eb07f Merge pull request #2226 from FlightControl-Master/master
merge from master
2025-01-22 09:45:25 +01:00
Thomas 6551383070 Merge pull request #2225 from FlightControl-Master/Applevangelist-ZoneScaen-1
Update Zone.lua
2025-01-22 09:44:27 +01:00
Thomas b03978cc3d Update Zone.lua
Correct radius sphere search in  ZONE_RADIUS:SearchZone()
2025-01-22 09:43:57 +01:00
Frank 3a7233b594 Merge branch 'master' into develop 2025-01-19 19:18:26 +01:00
Frank 82f4c5790a Merge branch 'master' of https://github.com/FlightControl-Master/MOOSE 2025-01-19 19:18:01 +01:00
Frank 5957124e9e ARTY v1.3.3
- Added missing/new arty units to DB (min/max firing range)
- Adjusted immobile speed check because some DCS units report a speed of 1 m/s
2025-01-19 19:17:59 +01:00
Applevangelist 7c91b9847b Merge remote-tracking branch 'origin/master' into develop 2025-01-19 18:23:19 +01:00
Applevangelist 92a05ca74a #CTLD - If troops or vehicles have a stock set, you can only inject as many as there are in stock. Specifically, when using persistence, the load function will restrict to inject more objects than are in stock, each inject draws on the stock. 2025-01-19 18:22:25 +01:00
Applevangelist a3c13c8cea #PLAYERTASK - added option for custom player callsigns
#PLAYERRECCE - added option for custom player callsigns
#PLAYERRECCE - added KIOWA support
2025-01-19 17:41:17 +01:00
Frank d02b5db6dd Merge branch 'master' of https://github.com/FlightControl-Master/MOOSE 2025-01-18 22:34:25 +01:00
Frank bd074728fe Update Artillery.lua
- Update Arty DB
2025-01-18 22:34:21 +01:00
Applevangelist 8d87531464 #PLAYERRECCE - Add standard FOW for Kiowa 2025-01-18 15:32:08 +01:00
Applevangelist 5fbd3d9525 Merge remote-tracking branch 'origin/master' into develop 2025-01-18 15:30:33 +01:00
Applevangelist 61b7b3ead6 Smaller fixes 2025-01-18 15:30:03 +01:00
Applevangelist 8f2178a79c Merge remote-tracking branch 'origin/master' into develop 2025-01-17 09:56:00 +01:00
Applevangelist 72bb23ed0d xx 2025-01-17 09:55:12 +01:00
Applevangelist 7f7999e3e5 #CSAR - Make the list of downed pilots' coordinate dependent on _SETTINGS global or pilot 2025-01-17 09:54:41 +01:00
Applevangelist 0a08e3fdac Merge remote-tracking branch 'origin/master' into develop 2025-01-17 09:22:32 +01:00
Applevangelist b522b38d31 #SCENERY - Some fixes for kissing getLife function on some objects, and life points being zero on some objects 2025-01-17 09:21:48 +01:00
Thomas 646a2aec66 Merge pull request #2221 from FlightControl-Master/Applevangelist-awacs-1
Update Awacs.lua
2025-01-15 15:34:36 +01:00
Thomas 7392cb9bf3 Update Awacs.lua
#AWACS - clarify use of escort parameters and template
2025-01-15 12:14:14 +01:00
Frank 2e77988473 Merge branch 'master' into develop 2025-01-14 10:36:27 +01:00
Frank b2dc7bc232 ARTY v1.3.2
- Fixed bug that MLRS does not fire (ammo count if weapon type is auto)
2025-01-14 10:36:12 +01:00
Applevangelist 1b25220729 #AWACS - make # of escorts required assets 2025-01-13 12:38:53 +01:00
Applevangelist 4953000565 Merge remote-tracking branch 'origin/develop' into develop 2025-01-13 11:46:56 +01:00
Applevangelist 01b7575bca #AWACS
- Fix a logic error: cancel the Escort mission when the replacement has arrived
- Workaround for a situation where a player has a checkin-entry in the menu and a managed group entry at the same time - which should not be the case.
- Added Escort options for formation and relative position behind the AWACS
2025-01-13 11:46:51 +01:00
Frank f6e6dcac9a OPSGROUP ARTY
- Fixed bug in surface type for coord in range
- Improved search for coord in range
- Added option to set mission waypoint
2025-01-12 23:54:44 +01:00
Applevangelist 93c307d9dd Merge remote-tracking branch 'origin/develop' into develop 2025-01-12 17:10:32 +01:00
Applevangelist 852c18cef8 Merge remote-tracking branch 'origin/master' into develop 2025-01-12 17:10:27 +01:00
Applevangelist def622a02c #CTLD - InjectTroops - if precision coords is true, do also not randomize unit positions. 2025-01-12 17:09:31 +01:00
Frank acfe1a856e Update OpsGroup.lua
- Added surface type check for ARTY mission
- Improved search for coordinate in range
- Added option to specify distance conversion for weapon ranges
2025-01-11 23:38:15 +01:00
Thomas 9f1f6af647 Merge pull request #2220 from FlightControl-Master/master
Merge master
2025-01-11 10:17:39 +01:00
Thomas 30bedb39f1 Merge pull request #2219 from FlightControl-Master/Applevangelist-patch-1
Update Unit.lua
2025-01-11 10:14:44 +01:00
Thomas fbcc4ee32b Update Unit.lua
GetSTN fix if template os nil
2025-01-11 10:14:03 +01:00
Thomas 27571cc22f Merge pull request #2217 from shaji-Dev/develop
Develop
2025-01-11 10:04:44 +01:00
Shafik 1182a5eb1e [FIXED] attempt to index field 'IniDCSGroup' (a nil value) 2025-01-10 21:40:03 +02:00
Applevangelist 5f57c71c62 Merge remote-tracking branch 'origin/develop' into develop 2025-01-08 13:05:28 +01:00
Applevangelist c0d60b1bcf Merge remote-tracking branch 'origin/master' into develop 2025-01-08 13:05:24 +01:00
Applevangelist 63c68d729b #SET_GROUP - fix for lost event if IniDCSGroup isn't filled 2025-01-08 13:04:30 +01:00
Thomas 5fe29e2ba1 Merge pull request #2214 from FlightControl-Master/Applevangelist-patch-3
Update Auftrag.lua
2025-01-07 09:22:12 +01:00
Thomas 16ff1ac3e7 Update Auftrag.lua
#AUFTRAG Added some options for weapontype setting
2025-01-07 09:21:26 +01:00
Applevangelist 0e4f805e1c Merge remote-tracking branch 'origin/develop' into develop 2025-01-06 17:33:09 +01:00
Applevangelist 5f29bdc7a7 Merge remote-tracking branch 'origin/master' into develop 2025-01-06 17:33:04 +01:00
Applevangelist 04f8f6d512 xx 2025-01-06 17:32:29 +01:00
Thomas f4768aff07 Merge pull request #2213 from FlightControl-Master/master
Master merge
2025-01-06 14:21:42 +01:00
Thomas b74d46f762 Merge pull request #2211 from FlightControl-Master/Applevangelist-spawn-1
Update Spawn.lua
2025-01-06 14:20:23 +01:00
Thomas 02decc3901 Merge pull request #2212 from Rolln-dev/rolln/range
#RANGE - Changed parameter naming to fix docs
2025-01-06 14:19:02 +01:00
Rolln dcdea16624 #RANGE - Changed parameter naming to fix docs 2025-01-06 06:15:35 -07:00
Thomas 2635cf6345 Update Spawn.lua
#SPAWN Added option to use the center of the zone rather than a random postion when using InitRandomizeZone
2025-01-06 14:08:05 +01:00
Applevangelist 578c65196c Merge remote-tracking branch 'origin/master' into develop 2025-01-05 17:45:08 +01:00
Applevangelist 64fb24ce96 Merge remote-tracking branch 'origin/develop' into develop 2025-01-05 17:44:37 +01:00
Applevangelist 45dd7117c7 #CLIENTMENUMANAGER Add a retry loop if possibly client not yet exists in Database 2025-01-05 17:44:32 +01:00
Applevangelist e86069d39c Smaller updates 2025-01-05 17:43:12 +01:00
Thomas e9db714937 Merge pull request #2210 from FlightControl-Master/master
Master merhe
2025-01-05 10:21:40 +01:00
Thomas fdcf153b0b Merge pull request #2209 from shaji-Dev/master
[FIXED] `attempt to call method 'GetPlayerName' (a nil value)`
2025-01-05 10:20:23 +01:00
Shafik 8523b7e20a [FIXED] attempt to call method 'GetPlayerName' (a nil value) 2025-01-05 10:47:14 +02:00
Frank 29b992bf81 Merge pull request #2208 from Rolln-dev/rolln/range
ENHANCEMENT: Adds a ceiling to the range.
2025-01-04 19:15:33 +01:00
Rolln 4c52509d6d ENHANCEMENT: Adds a ceiling to the range. 2025-01-04 11:06:39 -07:00
Applevangelist 8d603a0cef Merge remote-tracking branch 'origin/master' into develop 2025-01-04 18:26:32 +01:00
Applevangelist 9bc067f2e8 #STORAGE - Switched saving items from the storage inventory to using the enumerator (+~120 items), better handling of table IDs. 2025-01-04 18:25:32 +01:00
Applevangelist 5fbe0d9a70 #ENUMS - Added items to the storage enumerator, some number corrections 2025-01-04 18:23:24 +01:00
Shafik 4c1c36ef46 [FIXED] attempt to call method 'GetPlayerName' (a nil value) 2025-01-04 16:16:03 +02:00
Applevangelist 067fbcaeaf Merge remote-tracking branch 'origin/develop' into develop 2025-01-04 13:25:38 +01:00
Applevangelist f0aad83d53 Merge remote-tracking branch 'origin/master' into develop 2025-01-04 13:25:33 +01:00
Applevangelist 474f767e56 #CTLD - Clarify doc for Hook loadable stuff 2025-01-04 13:24:51 +01:00
Frank be062061d5 Update Auftrag.lua
- Improved docs for ARTY
2025-01-02 23:01:49 +01:00
Applevangelist ac5dfab82f #PLAYERRECCE - Fine tune check when a unit is dead or just per se has less than 2 LifePoints 2025-01-02 17:22:39 +01:00
Applevangelist 13d5f4ac99 Merge remote-tracking branch 'origin/master' into develop 2025-01-02 17:07:29 +01:00
Applevangelist f9030be843 xx 2025-01-02 17:06:53 +01:00
Applevangelist 3cea1cc78c #PLAYERRECCE - allow to display add'l location in report as per user settings for laser and visual targets. 2025-01-02 16:20:47 +01:00
Applevangelist 37c1423c9f Merge remote-tracking branch 'origin/master' into develop 2025-01-02 13:20:55 +01:00
Applevangelist 538e35d8f0 xx 2025-01-02 13:20:18 +01:00
Applevangelist d23f029953 Merge remote-tracking branch 'origin/master' into develop 2025-01-02 11:19:39 +01:00
Applevangelist aafa37f80d Merge remote-tracking branch 'origin/develop' into develop 2025-01-02 11:19:16 +01:00
Applevangelist 203f0c8abc #docu 2025-01-02 11:18:44 +01:00
Thomas 1c0e6362a1 Merge pull request #2205 from shaji-Dev/Heartbreaker
[FIXED] OpsZone never goes to `Attacked` state if `threatlevelCapture` is higher than 0.
2025-01-02 07:31:11 +01:00
Shafik 68165cee75 [FIXED] OpsZone never goes to Attacked state if threatlevelCapture is higher than 0. 2025-01-01 23:08:30 +02:00
Applevangelist 8ef5f0b3f6 Merge remote-tracking branch 'origin/master' into develop 2025-01-01 17:56:35 +01:00
Applevangelist d0736b0b56 #SHORAD - Switch shorad group back to green&no emissions&scoot if it's directly attacked by a missile 2025-01-01 17:55:55 +01:00
Applevangelist 2fbcd9d2b9 Merge remote-tracking branch 'origin/master' into develop 2025-01-01 14:38:43 +01:00
Applevangelist 15b1ed028e #MANTIS - better handling of stats, verbose dist calc in km, coord in MGRS0 now 2025-01-01 14:38:07 +01:00
Applevangelist a611a38181 Merge remote-tracking branch 'origin/master' into develop 2025-01-01 09:14:46 +01:00
Applevangelist 008617a35c #MANTIS - Fix for Checkloop if no Sharad instance is alive 2025-01-01 09:14:07 +01:00
Thomas 81a403f02d Merge pull request #2204 from FlightControl-Master/master
Update Mantis.lua
2025-01-01 08:32:57 +01:00
Thomas 6144a61a2e Update Mantis.lua
Fix for zones count on possible empty variables
2025-01-01 08:31:06 +01:00
Applevangelist df102fba6c Merge remote-tracking branch 'origin/master' into develop 2024-12-31 15:35:23 +01:00
Applevangelist 5d192abd25 #SEAD - Add AGM_65 2024-12-31 15:34:46 +01:00
Applevangelist 902f6dae11 Merge remote-tracking branch 'origin/master' into develop 2024-12-31 14:05:41 +01:00
Applevangelist 62337f445a #CTLD - Save and load special static shapes, if they are set 2024-12-31 14:04:46 +01:00
Applevangelist b38c1c5827 xx 2024-12-30 14:42:03 +01:00
Thomas 8309768735 Merge pull request #2203 from shaji-Dev/Heartbreaker
Mankind saved.
2024-12-30 13:40:54 +01:00
Shafik 42e6b57296 Mankind saved. 2024-12-30 14:09:25 +02:00
Shafik 2835ec812f Mankind saved. 2024-12-30 14:08:04 +02:00
Applevangelist 990161729b Merge remote-tracking branch 'origin/master' into develop 2024-12-30 11:47:11 +01:00
Applevangelist c08cee2317 #STORAGE Documentation for persistence 2024-12-30 11:45:31 +01:00
Applevangelist e1ea4322a1 Merge remote-tracking branch 'origin/master' into develop 2024-12-29 18:08:45 +01:00
Applevangelist 0f7759d070 #STORAGE - Added StartAutoSave and StopAutoSave() 2024-12-29 18:04:42 +01:00
Applevangelist 6523c4473f Merge remote-tracking branch 'origin/master' into develop 2024-12-29 12:53:35 +01:00
Applevangelist 4a0842bea6 #STORAGE - Added persistence options 2024-12-29 12:52:51 +01:00
Applevangelist 3745e6a8d8 Merge remote-tracking branch 'origin/master' into develop 2024-12-28 14:52:54 +01:00
Applevangelist 3b3666c5f7 #AIRBASE add 2 Kola bases, correct #ENUM for OH-58D weps in STORAGE 2024-12-28 14:52:09 +01:00
Thomas 9e1a28f7ca Merge pull request #2202 from Fedge7/personal/fedge/enums-weapons-oh58-dec2024
Corrects the table values for OH58 weapon enums for patch `2.9.11.4686.`
2024-12-28 09:26:46 +01:00
Fedge 82c7e921eb Corrects the table values for OH58 weapon enums for patch 2.9.11.4686. 2024-12-27 18:48:30 -07:00
Applevangelist 67ccf532ea Merge remote-tracking branch 'origin/master' into develop 2024-12-27 14:41:15 +01:00
Applevangelist 45912911ee #MSRS Google 2025 voice catalog 2024-12-27 14:40:32 +01:00
Applevangelist c7fe42d919 Merge remote-tracking branch 'origin/master' into develop 2024-12-27 12:26:31 +01:00
Applevangelist 9916afaa49 #COORDINATE Adding names to smoke to be able to switch them off earlier 2024-12-27 12:25:25 +01:00
Applevangelist 55c5a23616 #CTLD Bugfix in selecting correct helo distance when hover/ground for the Chinook 2024-12-27 12:25:00 +01:00
Applevangelist 7b6df08268 #AUTOLASE - Somewhat nicer report display 2024-12-27 12:24:26 +01:00
Applevangelist 9300050573 Merge remote-tracking branch 'origin/master' into develop 2024-12-26 17:18:28 +01:00
Applevangelist 6bee1cc88e Small additions 2024-12-26 17:16:43 +01:00
Applevangelist c94767a715 Merge remote-tracking branch 'origin/develop' into develop 2024-12-22 13:00:49 +01:00
Applevangelist 7aa3169523 #AWACS - add a mission parameter to ensure selection of AWACS aircraft 2024-12-22 13:00:46 +01:00
Frank cf86eacb16 Merge branch 'master' into develop 2024-12-18 22:04:55 +01:00
Frank 43ab4d5f38 Update Warehouse.lua
- Removed trace output of qitem and queue because it stalls the game when written to log file
2024-12-18 22:04:38 +01:00
Applevangelist aa064a1d0e Merge remote-tracking branch 'origin/master' into develop 2024-12-18 12:35:32 +01:00
Applevangelist 21240a60de #AUFTRAG, OpsGroup - added speed option for mission hold, ingress and egress wpts 2024-12-18 12:35:13 +01:00
Applevangelist 0427c0d3a7 #CTLD - Added GetLoadedCargo(Unit) 2024-12-18 12:34:30 +01:00
Applevangelist 3f632b92e2 Merge remote-tracking branch 'origin/master' into develop 2024-12-18 11:35:39 +01:00
Applevangelist 014750ea7f #SET - Documentation fixes 2024-12-18 11:35:13 +01:00
Applevangelist 548b80969a Merge remote-tracking branch 'origin/master' into develop 2024-12-17 12:46:44 +01:00
Applevangelist e4bbfce314 #MANTIS
- Better status overview
- Some fixes for SHORAD setup
2024-12-17 12:45:45 +01:00
Applevangelist 278f1db9a9 Merge remote-tracking branch 'origin/master' into develop 2024-12-15 13:35:03 +01:00
Applevangelist 359429b17e #GROUP added Teleport(Coordinate) function leveraging Respawn(). Now also translate routes if there are any. 2024-12-15 13:34:13 +01:00
Applevangelist f151271cb1 Merge remote-tracking branch 'origin/master' into develop 2024-12-15 11:42:04 +01:00
Applevangelist 6001f6abda #EVENT - another fix for scenery without getName function 2024-12-15 11:41:24 +01:00
Applevangelist 18e5012546 Merge remote-tracking branch 'origin/master' into develop 2024-12-15 11:33:35 +01:00
Applevangelist fd9b5d8d16 #AIRBASE type fix for single Helipad 2024-12-15 11:33:01 +01:00
Frank da3ee13582 Merge branch 'master' into develop 2024-12-15 10:01:13 +01:00
Frank b6f184388a ATIS
- Fixed length of niner sound file
2024-12-15 10:00:59 +01:00
Frank 903c065b74 Merge branch 'master' into develop 2024-12-14 16:55:36 +01:00
Frank d8471698ab Merge pull request #2197 from FlightControl-Master/FF/MasterDevel
SPAWNSTATIC
2024-12-14 16:54:50 +01:00
Frank 6204cecbbd SPAWNSTATIC
- moved AddStatic to after static spawn fixing registration of spawned static
2024-12-14 16:54:39 +01:00
Frank ddeca49916 Merge pull request #2196 from FlightControl-Master/FF/MasterDevel
DATABASE (fix for SPAWNSTATIC)
2024-12-14 13:48:40 +01:00
Frank d8dcf37886 DATABASE
- Fixed error that static was not returned in `DATABASE:AddStatic()` (leads to issues if a static object with the same name is spawned)
- Other minor changes
2024-12-14 13:48:04 +01:00
Frank 5ae41a208b Merge branch 'master' into FF/MasterDevel 2024-12-14 11:29:57 +01:00
Applevangelist 0462d900e6 xx 2024-12-13 12:08:54 +01:00
Applevangelist 4fb2ad88bc #OpsGroup - fix holding condition for FG at holding coordinate 2024-12-13 12:07:31 +01:00
Applevangelist ea55e90e62 Merge remote-tracking branch 'origin/develop' into develop 2024-12-12 13:11:58 +01:00
Applevangelist 6025c05f33 #AUFTRAG #OPSGROUP Handling of Ingress and Holding points for FlightGroups 2024-12-12 13:11:54 +01:00
Frank 64f854e646 Merge branch 'master' into develop 2024-12-12 00:22:59 +01:00
Frank 0f962461e1 DCS Iraq update
- `AIRBASE`: Added Iraq airports to enums
- `ATIS`: Added missing maps to enums
- `UTILS`: Added missing maps to enums
2024-12-12 00:22:44 +01:00
Frank 62dfb5b5ff OPS update
- Set destination base to airwing base for flight groups
- Restored setting of home, destination and current base in OPSGROUP
- Fixed bug if no airbase associated with airwing in check rescuehelo
- Added check that cohort names are unique
- Removed InitWaypoints function from FLIGHTGROUP (obsolete)
2024-12-11 22:49:40 +01:00
Applevangelist 171af5a3c3 #AUFTRAG, #OPSGROUP - Better functionality for Ingress Points (used as IP Holding Point when combined with a push condition) 2024-12-11 16:45:05 +01:00
Applevangelist 874548d1c1 Merge remote-tracking branch 'origin/master' into develop 2024-12-11 14:18:51 +01:00
Applevangelist aadc03c38d #CTLD Added option/value for my_ctld.TroopUnloadDistHoverHook 2024-12-11 14:17:58 +01:00
Applevangelist fb0aeafaa2 Merge remote-tracking branch 'origin/master' into develop 2024-12-11 13:58:23 +01:00
Applevangelist 683fa13bb2 #WEAPON - fix for name not available on target 2024-12-11 13:57:55 +01:00
Applevangelist d3bd55a290 Merge remote-tracking branch 'origin/master' into develop 2024-12-11 13:54:33 +01:00
Applevangelist e4408a964d #MANTIS - update CHM assets 2024-12-11 13:54:01 +01:00
Frank 1fbe78b667 Merge pull request #2195 from FlightControl-Master/FF/Ops
OPSGROUP v1.0.3
2024-12-10 22:50:30 +01:00
Frank 4902e0f597 OPSGROUP v1.0.3
- fixes for (naval) teleporting
2024-12-10 22:44:44 +01:00
Thomas 34e248b1c3 Merge pull request #2194 from shaji-Dev/Heartbreaker
[Fixed] FlightGroup do not RTB because of incorrect `destbase` assignment.
2024-12-10 19:08:42 +01:00
shaji 5a05917bc2 [Fixed] FlightGroup do not RTB because of incorrect destbase assignment. 2024-12-10 19:04:09 +01:00
Frank 98a613261c Update OpsGroup.lua
- Delayed spawn
2024-12-09 23:32:24 +01:00
Frank ee880a893e OPSGROUP
- Improved respawn behaviour
2024-12-08 22:47:16 +01:00
Applevangelist 7e8555d6b7 #EASYGCICAP - allow multiple EWR string prefixes in a table 2024-12-08 18:56:28 +01:00
Applevangelist 0a6bdd6e04 #SET_OPSGROUP - fix for teleport/respawn 2024-12-06 14:07:09 +01:00
Frank f97f33ab59 ATIS v1.1.0
- Added dynamic fog
2024-12-06 00:09:15 +01:00
Frank f59102ee09 Merge branch 'master' into FF/MasterDevel 2024-12-05 21:06:06 +01:00
Applevangelist de304d6bb9 Merge remote-tracking branch 'origin/develop' into develop 2024-12-05 10:56:31 +01:00
Applevangelist 73181e3f45 xx 2024-12-05 10:56:27 +01:00
Frank e42e4e1ddf Merge branch 'master' into FF/MasterDevel 2024-12-03 21:15:46 +01:00
Thomas 86e899f39b Merge pull request #2192 from FlightControl-Master/master
Update Mantis.lua
2024-12-03 18:10:06 +01:00
Thomas a30079c45b Update Mantis.lua
Less noise
2024-12-03 18:07:38 +01:00
Frank f644d49e71 OPS Speed
- `AUFTRAG` Fixed speed unit conversion in multiple AUFTRAG types (DCS task parameter speed should be in m/s)
- `OPSGROUP`: Fixed unit conversion for engage target speed
2024-12-01 14:56:02 +01:00
Applevangelist c0b09b03d9 Merge remote-tracking branch 'origin/master' into develop 2024-11-30 16:20:14 +01:00
Applevangelist 50ffd9aba6 #MANTIS - Correct detail data check is run even if automode isn't defined 2024-11-30 16:19:51 +01:00
Applevangelist 4d4138c1e6 Merge remote-tracking branch 'origin/master' into develop 2024-11-28 09:47:43 +01:00
Frank 936fec1f49 Update Range.lua 2024-11-26 23:06:31 +01:00
Applevangelist 9625d87dd5 #NET - fix for net.force_player_slot(PlayerID, SideID, SlotID ) not working at all - destroy blocked client instead 2024-11-26 10:43:20 +01:00
Frank c4d0319bb2 Merge branch 'master' into develop 2024-11-24 21:54:19 +01:00
Frank 802139205c Update Unit.lua
- Fixed bug in `UNIT:GetDCSObject()` when DCS unit does not exist.
2024-11-24 21:54:05 +01:00
Frank 6022a3905f TARGET v0.7.1
- Fixed bug if TARGET is a COORDINATE or ZONE, where we cannot check if it is alive or dead. The count alive previously did not count coordinates or zones. Now it does, which is more consistent as we set life=1 and alive=true for these.
2024-11-23 22:10:26 +01:00
Frank 6f724c62fb Merge branch 'master' into develop 2024-11-21 23:44:13 +01:00
Frank fb918cb2a4 Update DCS.lua 2024-11-21 23:43:58 +01:00
Frank 1a74f112ef Merge branch 'master' into develop 2024-11-21 23:13:18 +01:00
Frank abb4de46d7 Controllable Detection Improvements/Fixes
- Fixed bug in detection functions for optical detection (enum incorrect)
- Fixed bug in order of return values of `CONTROLLABLE:IsTargetDetected` (both hoggit and DCS are WRONG and MOOSE adopted it).
2024-11-21 23:13:05 +01:00
Frank 5747c49abf Merge branch 'develop' of https://github.com/FlightControl-Master/MOOSE into develop 2024-11-20 11:15:09 +01:00
Frank b87930738a TARGET v0.7
- Bug fixes
- Improved FSM function docs
2024-11-20 11:15:05 +01:00
Thomas d2c78516f5 Merge pull request #2191 from shaji-Dev/Heartbreaker
[Added] OPSZONE:SetDrawZoneForCoalition
2024-11-19 06:44:13 +01:00
shaji 93cff96794 [Added] OPSZONE:SetDrawZoneForCoalition to set if zone is drawn on the F10 map for the owner coalition only instead for all. Useful for recon tasking and fog of war. 2024-11-19 00:42:37 +01:00
Thomas 75e80a0091 Merge pull request #2190 from shaji-Dev/Heartbreaker
Added usage docs
2024-11-18 18:36:47 +01:00
shaji 46d2c9c196 [Added] Usage to doc for PLAYERTASK:AddStaticObjectSuccessCondition, PLAYERTASK:AddOpsZoneCaptureSuccessCondition, PLAYERTASK:AddReconSuccessCondition, PLAYERTASK:AddTimeLimitFailureCondition 2024-11-18 09:25:00 +01:00
Applevangelist 6f61d160af Documentation 2024-11-18 08:54:21 +01:00
Thomas 13419171a9 Merge pull request #2189 from shaji-Dev/Heartbreaker
New New Capture OpsZone PlayerTask and Time Limit Conditions
2024-11-18 06:17:00 +01:00
shaji 147cfea587 [Added] New Capture OpsZone PlayerTask with OPSZONE and SET_OPSZONE targets
[Added] Task "Time Limit" failure condition `PLAYERTASK:AddTimeLimitFailureCondition(TimeLimit)`
[Added] `PLAYERTASK:AddOpsZoneCaptureSuccessCondition(CaptureSquadGroupNamePrefix, Coalition)`
[Added] `PLAYERTASK:_CheckCaptureOpsZoneSuccess`
2024-11-18 02:35:05 +01:00
Applevangelist c27da8e54e Merge remote-tracking branch 'origin/develop' into develop 2024-11-17 16:23:10 +01:00
Applevangelist f3c8b4c1cd Merge remote-tracking branch 'origin/master' into develop 2024-11-17 16:23:06 +01:00
Frank 09e1883488 Merge branch 'master' into develop 2024-11-15 23:22:00 +01:00
Frank dce9631399 Update Event.lua
- Set `Event.IniGroupName` from db in case group does not exist any more
2024-11-15 23:21:50 +01:00
Thomas fb2ba1dea0 Merge pull request #2188 from shaji-Dev/Heartbreaker
Docs update PLAYERTASK:AddReconSuccessCondition
2024-11-11 12:19:49 +01:00
Shafik 19073534dd Docs update for:
PLAYERTASK:AddReconSuccessCondition
2024-11-11 12:45:25 +02:00
Thomas 23080e3cc4 Merge pull request #2187 from shaji-Dev/Heartbreaker
PLAYERTASK Added helper functions
2024-11-10 14:56:24 +01:00
Shafik b50d3fa809 [Added] Constructor PLAYERTASK:NewFromTarget that determines task type based on the target object
[Added] `PLAYERTASK:_GetTaskTypeForTarget` to get the task type based on target description
[Added] `PLAYERTASKCONTROLLER.Scores` for RECON, ESCORT and CAP
[Added] `PLAYERTASK:AddStaticObjectSuccessCondition` task success condition for dead STATIC, SET_STATIC, SCENERY or SET_SCENERY targets
[Added] `PLAYERTASK:AddReconSuccessCondition` for AUFTRAG.Type.RECON tasks for when a client is at a certain LOS distance from the target
2024-11-10 15:41:21 +02:00
Shafik 1f191cf9bb [Added] Constructor PLAYERTASK:NewFromTarget that determines task type based on the target object
[Added] `PLAYERTASK:_GetTaskTypeForTarget` to get the task type based on target description
[Added] `PLAYERTASKCONTROLLER.Scores` for RECON, ESCORT and CAP
[Added] `PLAYERTASK:AddStaticObjectSuccessCondition` task success condition for dead STATIC, SET_STATIC, SCENERY or SET_SCENERY targets
[Added] `PLAYERTASK:AddReconSuccessCondition` for AUFTRAG.Type.RECON tasks for when a client is at a certain LOS distance from the target
2024-11-10 15:37:16 +02:00
Thomas 6c773786d2 Merge pull request #2186 from FlightControl-Master/Applevangelist-patch-2
Update Enums.lua
2024-11-10 13:46:00 +01:00
Thomas 8939963187 Update Enums.lua
OH58d weapons
2024-11-10 13:45:44 +01:00
Thomas e3fb693cb7 Merge pull request #2185 from Fedge7/personal/fedge/enums-weapons-oh58
Corrects the table values for OH58 weapon enums.
2024-11-10 13:44:01 +01:00
Fedge 7cc11f55bb Corrects the table values for OH58 weapon enums.
After seeing FARP rearming broken for the OH58 in a recent DCS update, I checked all these enum values and updated them by referencing a freshly-created MIZ. I dropped a FARP and added a unique quantity of all the OH58's weapons to the FARP's warehouse. The values were then scraped from the MIZ's `warehouse` lua file.
2024-11-08 00:09:18 -07:00
Thomas f9747d1c4c Merge pull request #2184 from FlightControl-Master/Applevangelist-pwsh-1
Update SRS.lua
2024-11-04 14:49:56 +01:00
Thomas 60a3d3409e Update SRS.lua
#MSRS Test to get the pwsh window to minimize
2024-11-04 14:49:26 +01:00
Applevangelist cd8cbc54c8 Merge remote-tracking branch 'origin/master' into develop 2024-10-31 18:16:32 +01:00
Applevangelist b72124c0d9 #CONTROLLABLE Corrected parameter omissions 2024-10-31 18:16:02 +01:00
Applevangelist 0d6a1644e2 Merge remote-tracking branch 'origin/master' into develop 2024-10-31 16:06:00 +01:00
Applevangelist d51e761b26 #CONTROLLABLE - Rollback changes for EPLRS command 2024-10-31 16:05:24 +01:00
Applevangelist 1ebe8b82ec Merge remote-tracking branch 'origin/master' into develop 2024-10-30 17:10:25 +01:00
Applevangelist 1445ef61a0 #AIRBASE - added bases from 2.9.9.2280 2024-10-30 17:09:38 +01:00
Applevangelist f82490f0d5 Merge remote-tracking branch 'origin/master' into develop 2024-10-29 13:57:56 +01:00
Applevangelist dfe2ed2a98 #EVENT - Fix for TgtUnit Name being unobtainable 2024-10-29 13:57:21 +01:00
Applevangelist bb5c044a25 Merge remote-tracking branch 'origin/master' into develop 2024-10-29 13:19:40 +01:00
Applevangelist be87103b53 #CTLD - fixed a collision when extracting on a possible distance key duplication 2024-10-29 13:18:55 +01:00
Applevangelist 54f7627f9c Merge remote-tracking branch 'origin/master' into develop 2024-10-29 11:37:44 +01:00
Applevangelist 2fb460c4bb #ATC_Ground - stop kicking players immediately for speeding 2024-10-29 11:37:06 +01:00
Applevangelist 1b3c94cc57 Merge remote-tracking branch 'origin/master' into develop 2024-10-27 13:25:41 +01:00
Applevangelist 216ea230a8 #BASE - Roll back to "old" serialize method for Trace 2024-10-27 13:25:13 +01:00
Applevangelist 7e727620a4 Merge remote-tracking branch 'origin/develop' into develop 2024-10-26 18:45:45 +02:00
Applevangelist 13ec9bcdd4 Merge remote-tracking branch 'origin/master' into develop 2024-10-26 18:45:40 +02:00
Applevangelist 90096163ee EPLRS - give group ID only if ground 2024-10-26 18:45:01 +02:00
Thomas d2564d4a54 Merge pull request #2183 from FlightControl-Master/master
Merge from master
2024-10-21 11:35:35 +02:00
Thomas cd178d6a8c Merge pull request #2182 from FlightControl-Master/Applevangelist-patch-1
Update MarkerOps_Base.lua
2024-10-21 11:33:14 +02:00
Thomas 2aa0b5ddfb Update MarkerOps_Base.lua
Added data to FSM events
2024-10-21 11:32:47 +02:00
Applevangelist cf6e026392 Merge remote-tracking branch 'origin/master' into develop 2024-10-11 08:06:29 +02:00
Applevangelist 37f819458a #AIRBOSS - Change event Land to event RunwayTouch 2024-10-11 08:06:05 +02:00
Applevangelist 16fb0c3081 Merge remote-tracking branch 'origin/master' into develop 2024-10-08 10:05:56 +02:00
Applevangelist 168f4301d2 #GROUP - extended options to create callsigns for TTS with own function 2024-10-08 10:05:31 +02:00
Applevangelist 9fb03d9d8a xx 2024-10-08 10:04:05 +02:00
Applevangelist d89ed535b7 Merge remote-tracking branch 'origin/master' into develop 2024-10-03 14:06:42 +02:00
Applevangelist 08b4b890ce #AWACS - added option to increase mission range from 100nm as default 2024-10-03 14:06:26 +02:00
Applevangelist d5a406c60f #MSRS experimental - option to use PowerShell to execute SRS-TTS - set MSRS.UsePowerShell = true to test it. Known issue - PS window does not close until everything is executed. 2024-10-03 14:05:51 +02:00
Applevangelist cb16210577 #SEAD - better event management of weapons, return earlier if no (H)ARM, return if SEAD Plane is nil 2024-10-03 14:03:06 +02:00
Applevangelist 8c0e0de45f xx 2024-10-01 12:10:21 +02:00
Applevangelist 3524cba4ef xx 2024-10-01 12:08:51 +02:00
Applevangelist df6a37a972 Merge remote-tracking branch 'origin/develop' into develop 2024-10-01 12:06:24 +02:00
Applevangelist 13600ff6fd Merge remote-tracking branch 'origin/master' into develop 2024-10-01 12:06:17 +02:00
Frank a957bb4968 Merge branch 'master' into develop 2024-10-01 09:08:03 +02:00
Frank 5f8d1cf5b0 Update Warehouse.lua
- Added check for incorrect plane attribute
2024-10-01 09:07:51 +02:00
Thomas a115267e08 Merge pull request #2181 from DarthZyll/patch-6
Update CSAR.lua - Updated correct type name for Kiowa to OH58D
2024-10-01 06:19:29 +02:00
Applevangelist 37998fbf1d Merge remote-tracking branch 'origin/master' into develop 2024-09-30 11:36:06 +02:00
Applevangelist 846aa823d4 fixes for #SEAD and #SPAWN 2024-09-30 11:35:25 +02:00
Applevangelist 0d877853eb Merge remote-tracking branch 'origin/master' into develop 2024-09-27 11:58:08 +02:00
Applevangelist 68298fc585 #EVENT Fix for scenery sometimes nit having a getName() function 2024-09-27 11:57:40 +02:00
Applevangelist b97a7cf387 Merge remote-tracking branch 'origin/master' into develop 2024-09-26 09:07:20 +02:00
Applevangelist e9d75f6d94 #CSAR Beacon Name Fix 2024-09-26 09:06:57 +02:00
Applevangelist 1dce2eb747 Merge remote-tracking branch 'origin/develop' into develop 2024-09-26 09:03:05 +02:00
Applevangelist 7c110d90cd Merge remote-tracking branch 'origin/master' into develop 2024-09-26 09:03:00 +02:00
Mike Young 2ecc02ce4d Update CSAR.lua - Updated correct type name for Kiowa to OH58D
Update CSAR.lua - Updated correct type name for Kiowa to OH58D - original Brykeller change
2024-09-26 01:05:38 -04:00
Thomas 8fa5277417 Merge pull request #2178 from brykeller/patch-2
Kiowa rescues sit on the skids, no doors need to be opened
2024-09-26 06:55:02 +02:00
Thomas 7cce5745af Merge pull request #2177 from DarthZyll/patch-5
Update CSAR.lua for BeaconName being built incorrectly
2024-09-26 06:54:20 +02:00
Thomas 231f1f236d Merge pull request #2180 from brykeller/patch-3
Update CTLD.lua to update the correct Kiowa typename to OH58D
2024-09-26 06:53:21 +02:00
Bryan Keller ece0a46f97 Update CTLD.lua to update the correct Kiowa typename to OH58D
Update CTLD.lua to update the correct Kiowa typename to OH58D
2024-09-25 18:59:26 -07:00
Bryan Keller 2c9b0b8376 Kiowa rescues sit on the skids, no doors need to be opened
Kiowa rescues sit on the skids, no doors need to be opened
2024-09-25 18:51:31 -07:00
Mike Young 76577c03e7 Update CSAR.lua for BeaconName being built incorrectly
Prior to this change, the F10 menu "List Active CSAR" is always blank even after a CSAR activity occurs
2024-09-25 21:13:22 -04:00
Applevangelist 48d30250a0 Merge remote-tracking branch 'origin/master' into develop 2024-09-23 12:44:14 +02:00
Applevangelist a798f2d61c Small fixes 2024-09-23 12:43:39 +02:00
Applevangelist d0f8b1436b #EASYGCICAP - Alert5 typo correction, typo corrected to assign correct coalition side 2024-09-23 10:21:05 +02:00
Applevangelist ddc5e0f86e Merge remote-tracking branch 'origin/master' into develop 2024-09-15 19:25:08 +02:00
Applevangelist ae08c87822 #CTLD 2024-09-15 19:24:24 +02:00
Thomas ae880e9d1c Merge pull request #2176 from Maintenance-Partnership-Systems/Minor-Doco-Fixes
Minor doco fixes
2024-09-15 11:16:08 +02:00
Michael Barnes 101d2e1de5 More incorrect AIRBASE constants in examples. 2024-09-15 18:48:42 +10:00
Michael Barnes f6b7708567 Fixed some outdated references to AIRBASE constants in examples. 2024-09-15 18:34:18 +10:00
Applevangelist 051286acd1 #SPAWN - Tuning measures from DEVELOP encorporated 2024-09-08 13:24:09 +02:00
Applevangelist d6d9c9d8cf Merge remote-tracking branch 'origin/master' into develop 2024-09-08 13:22:34 +02:00
Applevangelist 7f572a1a9b Small changes
#CSAR - add option for IR strobe
2024-09-08 13:22:10 +02:00
Applevangelist 68007306b3 Merge remote-tracking branch 'origin/develop' into develop 2024-09-08 11:44:47 +02:00
Applevangelist 0c3f97370c Merge remote-tracking branch 'origin/master' into develop
# Conflicts:
#	Moose Development/Moose/Wrapper/Group.lua
2024-09-08 11:44:44 +02:00
Applevangelist d62025dfe0 Small fixes 2024-09-08 11:43:33 +02:00
Thomas 6bc766e95f Merge pull request #2175 from FlightControl-Master/master
Update CSAR.lua
2024-09-07 09:03:00 +02:00
Thomas 07009630c6 Update CSAR.lua
Small fix
2024-09-07 09:01:58 +02:00
Applevangelist c2aeb1ebcd Merge remote-tracking branch 'origin/master' into develop 2024-09-06 16:41:11 +02:00
Applevangelist 865042a843 #CTLD #CSAR Function to add own SET_GROUP for pilots 2024-09-06 16:40:41 +02:00
Applevangelist 6243137d4c QoL 2024-09-06 13:42:14 +02:00
Applevangelist f00d0dc871 QoL 2024-09-06 13:40:27 +02:00
Applevangelist 8695953d5a #SPAWN - performance tuning for event workaround 2024-09-03 16:47:17 +02:00
Applevangelist 6afb68390b Merge remote-tracking branch 'origin/master' into develop 2024-09-01 15:37:31 +02:00
Applevangelist d6adcdf8bd #CONTROLLABLE - Added IR Marker Beacons for UNIT and GROUP objects 2024-09-01 15:36:41 +02:00
Applevangelist 8151700ad7 Merge remote-tracking branch 'origin/master' into develop
# Conflicts:
#	Moose Development/Moose/Ops/CTLD.lua
2024-09-01 13:37:34 +02:00
Applevangelist 2c192fba30 #SET - include checking functional filters in all sub-classes 2024-09-01 13:36:47 +02:00
Applevangelist 97f11c93bb #CTLD 2024-09-01 12:41:36 +02:00
Thomas a3102a7381 Merge pull request #2172 from DarthZyll/patch-5
Update CTLD.lua for missing self.ChinookTroopCircleRadius
2024-09-01 08:55:18 +02:00
Mike Young d41b5e8ede Update CTLD.lua for missing self.ChinookTroopCircleRadius
self.ChinookTroopCircleRadius was not being set
2024-09-01 02:52:33 -04:00
Applevangelist a45856c925 Merge remote-tracking branch 'origin/master' into develop 2024-08-29 10:25:40 +02:00
Applevangelist f531fdaa70 #RANGE less noise 2024-08-29 10:25:13 +02:00
Applevangelist f4b2f07656 Merge remote-tracking branch 'origin/master' into develop 2024-08-29 10:22:32 +02:00
Applevangelist 81f8e84ca4 xx 2024-08-29 10:22:14 +02:00
Applevangelist f7e64d98bc Merge remote-tracking branch 'origin/master' into develop 2024-08-27 18:37:56 +02:00
Applevangelist d74de11b8b CTLD small fix of container shape 2024-08-27 18:37:21 +02:00
Applevangelist 4380c1be2e Merge remote-tracking branch 'origin/master' into develop 2024-08-27 13:19:24 +02:00
Applevangelist 30f2097d7a #AIRBOSS - small fix in Numer2Sound etc 2024-08-27 13:18:53 +02:00
Applevangelist db2d4e97a6 Merge remote-tracking branch 'origin/master' into develop 2024-08-27 10:56:46 +02:00
Applevangelist f903844059 #CTLD - fix for type name restrictions in other functions 2024-08-27 10:56:14 +02:00
Applevangelist b4653be54e Merge remote-tracking branch 'origin/master' into develop 2024-08-26 18:31:07 +02:00
Applevangelist 68b2b452cc xx 2024-08-26 18:30:41 +02:00
Applevangelist e2b6efde7a Merge remote-tracking branch 'origin/master' into develop 2024-08-26 18:22:59 +02:00
Applevangelist 668d120d60 CTLD Small fix for crate removal 2024-08-26 18:22:32 +02:00
Applevangelist 3eea17bc76 Merge remote-tracking branch 'origin/develop' into develop 2024-08-26 15:53:23 +02:00
Applevangelist 2894bcc833 Merge remote-tracking branch 'origin/master' into develop 2024-08-26 15:53:20 +02:00
Applevangelist 7543f31c85 #CTLD
* Added option for crates to have any static shape (per crate type option)
* Added option for crates only to be transported by defined helo type names (per crate type option)
2024-08-26 15:52:50 +02:00
Thomas ff52197707 Merge pull request #2171 from FlightControl-Master/master
Update Utils.lua
2024-08-25 11:23:42 +02:00
Thomas 56d84e7b25 Update Utils.lua
Small fix
2024-08-25 11:22:30 +02:00
Applevangelist b025abaa88 Merge remote-tracking branch 'origin/master' into develop 2024-08-24 18:18:36 +02:00
Applevangelist ed2d3d856b Small fix 2024-08-24 18:18:08 +02:00
Applevangelist dac637f360 Merge remote-tracking branch 'origin/master' into develop 2024-08-23 16:29:18 +02:00
Applevangelist 1e5c3a3c21 #ENUMS storage AH64D weapons additions 2024-08-23 16:28:35 +02:00
Applevangelist 861588205a Merge remote-tracking branch 'origin/master' into develop 2024-08-23 13:56:58 +02:00
Applevangelist 37d5b6a0fc #Add'l storage items 2024-08-23 13:55:18 +02:00
Applevangelist 4d3fb2990e Merge remote-tracking branch 'origin/master' into develop 2024-08-23 12:47:37 +02:00
Applevangelist c58a954d18 #CTLD
* Fix for spawning the correct number of crates on inject
* Simplified example docu section 7 on how to build a FARP
* Some prep work for additional stuff
2024-08-23 12:44:17 +02:00
Applevangelist cce878e759 Merge remote-tracking branch 'origin/master' into develop 2024-08-22 18:27:00 +02:00
Applevangelist 0d481afa16 #SET_GROUP - small fix for FilterPrefixes compute 2024-08-22 18:26:34 +02:00
Applevangelist 2dbad7cb1b Merge remote-tracking branch 'origin/master' into develop 2024-08-22 17:18:13 +02:00
Applevangelist 016875d724 #ENUMS - added a couple of items to ENUMS.Storage.weapons for the Gazelle and CH-47 which do not have a name representation in the object warehouse
#UTILS Added function `UTILS.SpawnFARPAndFunctionalStatics()` to spawn a functional FARP with static items (and some options)
#UTILS Added VHF Beacon Frequencies for newer maps to avoid overlaps in `UTILS.GenerateVHFrequencies()`
2024-08-22 17:17:10 +02:00
Applevangelist 7a0fa629b5 Merge remote-tracking branch 'origin/master' into develop 2024-08-20 18:03:59 +02:00
Applevangelist 5df0d60135 Smaller Fixes 2024-08-20 18:03:18 +02:00
Applevangelist aee7bd8bb6 Merge remote-tracking branch 'origin/master' into develop 2024-08-20 10:56:08 +02:00
Applevangelist e77d61c4cb small correction 2024-08-20 10:55:41 +02:00
Applevangelist b1a40407b3 Merge remote-tracking branch 'origin/master' into develop 2024-08-20 10:47:56 +02:00
Applevangelist 504142c585 #CTLD Added self.TroopUnloadDistGround = 1.5, and self.TroopUnloadDistHover = 5,
#CSAR Added option to switch off ADF beacons
2024-08-20 10:47:28 +02:00
Thomas 0496571c92 Merge pull request #2170 from DarthZyll/patch-4
Update CSAR.lua - remove luadoc param addBeacon on SpawnCASEVAC()
2024-08-20 09:35:34 +02:00
Mike Young 62a0adce5a Update CSAR.lua - remove luadoc param addBeacon on SpawnCASEVAC()
this param doesn't actually exist, purely a luadoc correction
2024-08-19 13:46:21 -04:00
Applevangelist d1a1be1a9e Merge remote-tracking branch 'origin/develop' into develop 2024-08-18 19:38:27 +02:00
Applevangelist 80011f4e4e Merge remote-tracking branch 'origin/master' into develop 2024-08-18 19:38:24 +02:00
Applevangelist 80df849d18 #SET_GROUP small enhancement for prefix filter 2024-08-18 19:37:00 +02:00
Frank c2933b6bed Update Legion.lua
- commented out debug info line
2024-08-18 18:19:05 +02:00
Frank fc4ba9f21d Merge branch 'master' into develop 2024-08-18 18:06:30 +02:00
Frank e74c79b5d6 Merge branch 'master' of https://github.com/FlightControl-Master/MOOSE 2024-08-18 16:56:44 +02:00
Frank f738ddfca8 Update Positionable.lua
- Added cargo bay of "MaxxPro_MRAP"
2024-08-18 16:56:42 +02:00
Applevangelist 5bbd122fa4 Merge remote-tracking branch 'origin/master' into develop 2024-08-18 14:09:10 +02:00
Applevangelist af45b0d709 #EVENT DynamicCargoRemove fix is name is empty 2024-08-18 14:08:46 +02:00
Applevangelist 928c20c867 Merge remote-tracking branch 'origin/develop' into develop 2024-08-18 13:58:58 +02:00
Applevangelist 4bd36a4786 Merge remote-tracking branch 'origin/master' into develop 2024-08-18 13:58:55 +02:00
Applevangelist e746617139 #Rap up changes 2024-08-18 13:58:18 +02:00
Thomas 3105f7407d Merge pull request #2169 from FlightControl-Master/Applevangelist-patch-1
Update ATIS.lua
2024-08-18 13:14:13 +02:00
Thomas 2f568bca17 Update ATIS.lua
#ATIS New Light Rain presets
2024-08-18 13:11:58 +02:00
Frank ad7dba6fac Merge pull request #2168 from FlightControl-Master/FF/Ops
CHIEF v0.6.1
2024-08-17 23:56:07 +02:00
Frank 9efe0fe243 CHIEF v0.6.1
- Strategic zone: If zero transports are available and min carriers is zero, cargo assets need to go by themselfs.
2024-08-17 23:50:52 +02:00
Thomas 2836d7a40f Merge pull request #2167 from FlightControl-Master/Applevangelist-DC-1
Update DynamicCargo.lua
2024-08-17 14:20:51 +02:00
Thomas f1bf62e3c1 Update DynamicCargo.lua
#DYNAMICCARGO
2024-08-17 14:20:31 +02:00
Applevangelist a560d65ce7 Merge remote-tracking branch 'origin/master' into develop 2024-08-17 11:37:11 +02:00
Applevangelist 9de3cb73f7 Merge remote-tracking branch 'origin/develop' into develop 2024-08-17 11:36:17 +02:00
Applevangelist 757cc86a68 xx 2024-08-17 11:36:13 +02:00
Applevangelist aeb1664134 CTLD 2024-08-17 11:36:01 +02:00
Frank 2af1483724 Merge branch 'master' into develop 2024-08-16 23:13:22 +02:00
Frank b7702ab933 Merge pull request #2166 from FlightControl-Master/Statua-patch-1
Update ClientWatch.lua
2024-08-16 23:10:25 +02:00
Statua cc14f82e85 Update ClientWatch.lua
-Added check to verify the aircraft is controlled by a player
-Added :FilterByCoalition() and :FilterByCategory()
-Added ability to get ALL CLIENTS by leaving param1 of :New() blank
-Added more console outputs if CLIENTWATCH.Debug is true
-Minor documentation fixes
2024-08-16 15:19:26 -05:00
Applevangelist f23dd0a5dd Merge remote-tracking branch 'origin/master' into develop 2024-08-16 16:23:42 +02:00
Applevangelist 5aea17e20e #SET_DYNAMICCARGO Docu 2024-08-16 16:23:13 +02:00
Applevangelist 8336b744bb Merge remote-tracking branch 'origin/master' into develop 2024-08-16 15:46:34 +02:00
Applevangelist ad9eaea010 #SET - many less calls 2024-08-16 15:46:07 +02:00
Applevangelist 9c47e35d54 Merge remote-tracking branch 'origin/master' into develop
# Conflicts:
#	Moose Development/Moose/Wrapper/DynamicCargo.lua
2024-08-16 15:22:45 +02:00
Applevangelist 284a770daa Added #SET_DYNAMICCARGO 2024-08-16 15:21:46 +02:00
Applevangelist 16030d4fa1 Delete some non ready classes 2024-08-16 11:28:50 +02:00
Applevangelist 37d2dd17d7 Merge remote-tracking branch 'origin/master' into develop 2024-08-16 09:44:42 +02:00
Applevangelist ccd190a8b1 xx 2024-08-16 09:44:00 +02:00
Applevangelist 36bf2436b6 Merge remote-tracking branch 'origin/master' into develop
# Conflicts:
#	Moose Development/Moose/Core/Event.lua
#	Moose Development/Moose/Ops/CTLD.lua
#	Moose Development/Moose/Wrapper/DynamicCargo.lua
2024-08-16 09:39:48 +02:00
Applevangelist 19f6a8d8f6 #DYNAMICCARGO - Added functionalty 2024-08-16 09:36:29 +02:00
Applevangelist b8e09afcce Merge remote-tracking branch 'origin/master' into develop 2024-08-14 15:43:24 +02:00
Applevangelist 24264bd885 #ATIS French Translations 2024-08-14 15:42:46 +02:00
Applevangelist ed690ee6e9 Merge remote-tracking branch 'origin/master' into develop 2024-08-14 11:34:27 +02:00
Applevangelist 872bb3d775 #RANGE Fix trying to get a playername on dynamic cargo spawns 2024-08-14 11:33:13 +02:00
Applevangelist c0dcd12ada Merge remote-tracking branch 'origin/master' into develop 2024-08-14 09:47:39 +02:00
Applevangelist d36cd8e284 #UNIT - Fix getting skill from N/A Templates 2024-08-14 09:46:10 +02:00
Applevangelist 5d98672de5 #ATIS - Polar circle fixes 2024-08-13 10:31:26 +02:00
Applevangelist eab643268f #ATIS - Polar circle fixes 2024-08-13 10:30:46 +02:00
Applevangelist e2fa1f992b Merge remote-tracking branch 'origin/master' into develop 2024-08-12 19:06:01 +02:00
Applevangelist 9356794112 bit of performance tuning 2024-08-12 19:05:32 +02:00
Applevangelist bb865aef38 Merge branch 'master' into develop 2024-08-12 17:01:13 +02:00
Applevangelist 35c24810f9 xx 2024-08-12 17:00:52 +02:00
Applevangelist 875b5fb34d Merge remote-tracking branch 'origin/develop' into develop 2024-08-12 16:17:30 +02:00
Applevangelist 19187bcb14 xx 2024-08-12 16:17:21 +02:00
Thomas ebe6e9fb9f Merge pull request #2165 from FlightControl-Master/master
Various
2024-08-12 11:40:43 +02:00
Thomas a54944b021 Update CTLD.lua (#2164)
#CTLD 
* Fix for helo being no Chinook not finding crates e.g. on a ship or FARP
* `nil` check for static cargo position check
2024-08-12 11:39:03 +02:00
Thomas 5f7f75b1c9 BASE and SPAWN tuning (#2162)
* Update Base.lua (#2159)

Performance tuning - the BASE:I, F, T calls rank very high in overall number of calls taken from Moose. Ensure only the minimum number of actions based on trace state and level is taken

* Update Spawn.lua (#2161)

Updating this class as it calls BASE I,F,T a lot. Making it less noisy for some performance tuning
2024-08-12 10:18:14 +02:00
Thomas bc9938d08a Update Spawn.lua (#2161)
Updating this class as it calls BASE I,F,T a lot. Making it less noisy for some performance tuning
2024-08-12 10:16:40 +02:00
Thomas 59963e152d Update Base.lua (#2159) (#2160)
Performance tuning - the BASE:I, F, T calls rank very high in overall number of calls taken from Moose. Ensure only the minimum number of actions based on trace state and level is taken
2024-08-12 09:47:38 +02:00
Thomas b77f179acc Update Base.lua (#2159)
Performance tuning - the BASE:I, F, T calls rank very high in overall number of calls taken from Moose. Ensure only the minimum number of actions based on trace state and level is taken
2024-08-12 09:44:13 +02:00
148 changed files with 18290 additions and 12829 deletions
+1 -1
View File
@@ -1953,7 +1953,7 @@ local function refct_from_id(id) -- refct = refct_from_id(CTypeID)
unsigned = refct.unsigned, unsigned = refct.unsigned,
size = bit.band(bit.rshift(ctype.info, 16), 127), 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 end
if CT[4] then -- Merge sibling attributes onto this type. if CT[4] then -- Merge sibling attributes onto this type.
@@ -18,6 +18,8 @@
--- The AI_A2A_CAP class implements the core functions to patrol a @{Core.Zone} by an AI @{Wrapper.Group} or @{Wrapper.Group} --- 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. -- 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) -- ![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. -- 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.
@@ -33,6 +33,8 @@
-- --
-- === -- ===
-- --
-- ![Banner Image](..\Images\deprecated.png)
--
-- # QUICK START GUIDE -- # QUICK START GUIDE
-- --
-- There are basically two classes available to model an A2A defense system. -- 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. --- 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_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. -- 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}. --- 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) -- ![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. -- 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.
@@ -16,6 +16,8 @@
--- Implements the core functions to intercept intruders. Use the Engage trigger to intercept intruders. --- Implements the core functions to intercept intruders. Use the Engage trigger to intercept intruders.
-- --
-- ![Banner Image](..\Images\deprecated.png)
--
-- # Developer Note -- # Developer Note
-- --
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE -- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE
@@ -18,6 +18,8 @@
-- --
-- # Developer Note -- # 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 -- 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 -- Therefore, this class is considered to be deprecated
-- --
@@ -36,6 +36,8 @@
-- --
-- # QUICK START GUIDE -- # QUICK START GUIDE
-- --
-- ![Banner Image](..\Images\deprecated.png)
--
-- The following class is available to model an A2G defense system. -- 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. -- AI_A2G_DISPATCHER is the main A2G defense class that models the A2G defense system.
@@ -3895,10 +3897,14 @@ do -- AI_A2G_DISPATCHER
if Squadron then if Squadron then
local FirstUnit = AttackSetUnit:GetRandomSurely() local FirstUnit = AttackSetUnit:GetRandomSurely()
if FirstUnit then
local Coordinate = FirstUnit:GetCoordinate() -- Core.Point#COORDINATE local Coordinate = FirstUnit:GetCoordinate() -- Core.Point#COORDINATE
if self.SetSendPlayerMessages then if self.SetSendPlayerMessages then
Dispatcher:MessageToPlayers( Squadron, DefenderName .. ", on route to ground target at " .. Coordinate:ToStringA2G( DefenderGroup ), DefenderGroup ) Dispatcher:MessageToPlayers( Squadron, DefenderName .. ", on route to ground target at " .. Coordinate:ToStringA2G( DefenderGroup ), DefenderGroup )
end end
else
return
end
end end
self:GetParent(self).onafterEngageRoute( self, DefenderGroup, From, Event, To, AttackSetUnit ) self:GetParent(self).onafterEngageRoute( self, DefenderGroup, From, Event, To, AttackSetUnit )
end end
@@ -4785,3 +4791,4 @@ end
end end
self:T({Squadron = Squadron.Name,SquadronResourceCount = Squadron.ResourceCount}) self:T({Squadron = Squadron.Name,SquadronResourceCount = Squadron.ResourceCount})
end end
@@ -19,6 +19,8 @@
--- Implements the core functions to SEAD intruders. Use the Engage trigger to intercept intruders. --- 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_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. -- The AI will fly towards the random 3D point within the patrol zone, using a random speed within the given altitude and speed limits.
+8 -6
View File
@@ -9,11 +9,13 @@
-- @module AI.AI_Air -- @module AI.AI_Air
-- @image MOOSE.JPG -- @image MOOSE.JPG
---
-- @type AI_AIR -- @type AI_AIR
-- @extends Core.Fsm#FSM_CONTROLLABLE -- @extends Core.Fsm#FSM_CONTROLLABLE
--- The AI_AIR class implements the core functions to operate an AI @{Wrapper.Group}. --- The AI_AIR class implements the core functions to operate an AI @{Wrapper.Group}.
-- --
-- ![Banner Image](..\Images\deprecated.png)
-- --
-- # 1) AI_AIR constructor -- # 1) AI_AIR constructor
-- --
@@ -656,8 +658,8 @@ function AI_AIR:onafterRTB( AIGroup, From, Event, To )
--- Create a route point of type air. --- Create a route point of type air.
local FromRTBRoutePoint = FromCoord:WaypointAir( local FromRTBRoutePoint = FromCoord:WaypointAir(
self.PatrolAltType, self.PatrolAltType,
POINT_VEC3.RoutePointType.TurningPoint, COORDINATE.WaypointType.TurningPoint,
POINT_VEC3.RoutePointAction.TurningPoint, COORDINATE.WaypointAction.TurningPoint,
RTBSpeed, RTBSpeed,
true true
) )
@@ -665,8 +667,8 @@ function AI_AIR:onafterRTB( AIGroup, From, Event, To )
--- Create a route point of type air. --- Create a route point of type air.
local ToRTBRoutePoint = ToAirbaseCoord:WaypointAir( local ToRTBRoutePoint = ToAirbaseCoord:WaypointAir(
self.PatrolAltType, self.PatrolAltType,
POINT_VEC3.RoutePointType.TurningPoint, COORDINATE.WaypointType.TurningPoint,
POINT_VEC3.RoutePointAction.TurningPoint, COORDINATE.WaypointAction.TurningPoint,
RTBSpeed, RTBSpeed,
true true
) )
@@ -760,10 +762,10 @@ function AI_AIR:onafterRefuel( AIGroup, From, Event, To )
local ToRefuelSpeed = math.random( self.PatrolMinSpeed, self.PatrolMaxSpeed ) local ToRefuelSpeed = math.random( self.PatrolMinSpeed, self.PatrolMaxSpeed )
--- Create a route point of type air. --- 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! --- 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 } ) self:F( { ToRefuelSpeed = ToRefuelSpeed } )
@@ -36,6 +36,8 @@
-- --
-- # QUICK START GUIDE -- # QUICK START GUIDE
-- --
-- ![Banner Image](..\Images\deprecated.png)
--
-- The following class is available to model an AIR defense system. -- 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. -- 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 -- @extends AI.AI_AIR#AI_AIR
--- Implements the core functions to intercept intruders. Use the Engage trigger to intercept intruders. --- 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_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. -- 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. --- 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 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 FromEngageAngle = DefenderCoord:GetAngleDegrees( DefenderCoord:GetDirectionVec3( TargetCoord ) )
local ToCoord=DefenderCoord:Translate( EngageDistance, FromEngageAngle, true ) 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 EngageRoute[#EngageRoute+1] = ToWP
@@ -536,7 +538,7 @@ function AI_AIR_ENGAGE:onafterEngage( DefenderGroup, From, Event, To, AttackSetU
local EngageRoute = {} local EngageRoute = {}
local AttackTasks = {} 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 EngageRoute[#EngageRoute+1] = FromWP
self:SetTargetDistance( TargetCoord ) -- For RTB status check 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 FromEngageAngle = DefenderCoord:GetAngleDegrees( DefenderCoord:GetDirectionVec3( TargetCoord ) )
local ToCoord=DefenderCoord:Translate( EngageDistance, FromEngageAngle, true ) 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 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! -- 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!
+4 -2
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} --- 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. -- 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) -- ![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. -- 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 ToTargetSpeed = math.random( self.PatrolMinSpeed, self.PatrolMaxSpeed )
local speedkmh=ToTargetSpeed 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 PatrolRoute[#PatrolRoute+1] = FromWP
if self.racetrack then if self.racetrack then
@@ -359,7 +361,7 @@ function AI_AIR_PATROL:onafterPatrolRoute( AIPatrol, From, Event, To )
else else
--- Create a route point of type air. --- 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 PatrolRoute[#PatrolRoute+1] = ToWP
local Tasks = {} local Tasks = {}
@@ -13,7 +13,7 @@
-- @type AI_AIR_SQUADRON --- @type AI_AIR_SQUADRON
-- @extends Core.Base#BASE -- @extends Core.Base#BASE
@@ -21,6 +21,8 @@
-- --
-- # Developer Note -- # 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 -- 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 -- Therefore, this class is considered to be deprecated
-- --
+8 -7
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}. --- 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. -- 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) -- ![HoldAndEngage](..\Presentations\AI_BAI\Dia3.JPG)
@@ -175,7 +177,6 @@ function AI_BAI_ZONE:New( PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude
-- @param #string From The From State string. -- @param #string From The From State string.
-- @param #string Event The Event string. -- @param #string Event The Event string.
-- @param #string To The To State string. -- @param #string To The To State string.
-- @return #boolean Return false to cancel Transition. -- @return #boolean Return false to cancel Transition.
--- OnAfter Transition Handler for Event Engage. --- OnAfter Transition Handler for Event Engage.
@@ -522,12 +523,12 @@ function AI_BAI_ZONE:onafterEngage( Controllable, From, Event, To,
--DONE: Create GetAltitude function for GROUP, and delete GetUnit(1). --DONE: Create GetAltitude function for GROUP, and delete GetUnit(1).
local CurrentAltitude = self.Controllable: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 ToEngageZoneSpeed = self.PatrolMaxSpeed local ToEngageZoneSpeed = self.PatrolMaxSpeed
local CurrentRoutePoint = CurrentPointVec3:WaypointAir( local CurrentRoutePoint = CurrentPointVec3:WaypointAir(
self.PatrolAltType, self.PatrolAltType,
POINT_VEC3.RoutePointType.TurningPoint, COORDINATE.WaypointType.TurningPoint,
POINT_VEC3.RoutePointAction.TurningPoint, COORDINATE.WaypointAction.TurningPoint,
self.EngageSpeed, self.EngageSpeed,
true true
) )
@@ -578,13 +579,13 @@ function AI_BAI_ZONE:onafterEngage( Controllable, From, Event, To,
self:T2( ToTargetVec2 ) self:T2( ToTargetVec2 )
--- Obtain a 3D @{Point} from the 2D point + altitude. --- 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. --- Create a route point of type air.
local ToTargetRoutePoint = ToTargetPointVec3:WaypointAir( local ToTargetRoutePoint = ToTargetPointVec3:WaypointAir(
self.PatrolAltType, self.PatrolAltType,
POINT_VEC3.RoutePointType.TurningPoint, COORDINATE.WaypointType.TurningPoint,
POINT_VEC3.RoutePointAction.TurningPoint, COORDINATE.WaypointAction.TurningPoint,
self.EngageSpeed, self.EngageSpeed,
true true
) )
+4 -10
View File
@@ -33,8 +33,9 @@
-- @field Wrapper.Group#GROUP Test -- @field Wrapper.Group#GROUP Test
-- @extends Core.Fsm#FSM_SET -- @extends Core.Fsm#FSM_SET
--- ![Banner Image](..\Images\deprecated.png)
--- Monitors and manages as many replacement AI groups as there are --
-- Monitors and manages as many replacement AI groups as there are
-- CLIENTS in a SET\_CLIENT collection, which are not occupied by human players. -- 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. -- 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 ) AIGroup:MessageToRed( "Returning to home base ...", 30 )
else else
-- Okay, we need to send this Group back to the nearest base of the Coalition of the AI. -- 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 = COORDINATE:New(AIGroup:GetVec2().x, 0, AIGroup:GetVec2().y)
local PointVec2 = POINT_VEC2:New( AIGroup:GetVec2().x, AIGroup:GetVec2().y )
local ClosestAirbase = self.ReturnAirbaseSet:FindNearestAirbaseFromPointVec2( PointVec2 ) local ClosestAirbase = self.ReturnAirbaseSet:FindNearestAirbaseFromPointVec2( PointVec2 )
self:T( ClosestAirbase.AirbaseName ) 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) AIGroup:RouteRTB(ClosestAirbase)
end 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} --- 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. -- 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) -- ![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. -- 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). --DONE: Create GetAltitude function for GROUP, and delete GetUnit(1).
local CurrentAltitude = self.Controllable: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 ToEngageZoneSpeed = self.PatrolMaxSpeed local ToEngageZoneSpeed = self.PatrolMaxSpeed
local CurrentRoutePoint = CurrentPointVec3:WaypointAir( local CurrentRoutePoint = CurrentPointVec3:WaypointAir(
self.PatrolAltType, self.PatrolAltType,
POINT_VEC3.RoutePointType.TurningPoint, COORDINATE.WaypointType.TurningPoint,
POINT_VEC3.RoutePointAction.TurningPoint, COORDINATE.WaypointAction.TurningPoint,
ToEngageZoneSpeed, ToEngageZoneSpeed,
true true
) )
@@ -445,13 +447,13 @@ function AI_CAP_ZONE:onafterEngage( Controllable, From, Event, To )
self:T2( { self.PatrolMinSpeed, self.PatrolMaxSpeed, ToTargetSpeed } ) self:T2( { self.PatrolMinSpeed, self.PatrolMaxSpeed, ToTargetSpeed } )
--- Obtain a 3D @{Point} from the 2D point + altitude. --- 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. --- Create a route point of type air.
local ToPatrolRoutePoint = ToTargetPointVec3:WaypointAir( local ToPatrolRoutePoint = ToTargetPointVec3:WaypointAir(
self.PatrolAltType, self.PatrolAltType,
POINT_VEC3.RoutePointType.TurningPoint, COORDINATE.WaypointType.TurningPoint,
POINT_VEC3.RoutePointAction.TurningPoint, COORDINATE.WaypointAction.TurningPoint,
ToTargetSpeed, ToTargetSpeed,
true true
) )
+9 -7
View File
@@ -38,6 +38,9 @@
-- @extends AI.AI_Patrol#AI_PATROL_ZONE -- @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}. --- 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. -- 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) -- ![HoldAndEngage](..\Presentations\AI_CAS\Dia3.JPG)
@@ -162,7 +165,6 @@ function AI_CAS_ZONE:New( PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude
-- @param #string From The From State string. -- @param #string From The From State string.
-- @param #string Event The Event string. -- @param #string Event The Event string.
-- @param #string To The To State string. -- @param #string To The To State string.
-- @return #boolean Return false to cancel Transition. -- @return #boolean Return false to cancel Transition.
--- OnAfter Transition Handler for Event Engage. --- OnAfter Transition Handler for Event Engage.
@@ -466,12 +468,12 @@ function AI_CAS_ZONE:onafterEngage( Controllable, From, Event, To,
--DONE: Create GetAltitude function for GROUP, and delete GetUnit(1). --DONE: Create GetAltitude function for GROUP, and delete GetUnit(1).
local CurrentAltitude = self.Controllable: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 ToEngageZoneSpeed = self.PatrolMaxSpeed local ToEngageZoneSpeed = self.PatrolMaxSpeed
local CurrentRoutePoint = CurrentPointVec3:WaypointAir( local CurrentRoutePoint = CurrentPointVec3:WaypointAir(
self.PatrolAltType, self.PatrolAltType,
POINT_VEC3.RoutePointType.TurningPoint, COORDINATE.WaypointType.TurningPoint,
POINT_VEC3.RoutePointAction.TurningPoint, COORDINATE.WaypointAction.TurningPoint,
self.EngageSpeed, self.EngageSpeed,
true true
) )
@@ -508,13 +510,13 @@ function AI_CAS_ZONE:onafterEngage( Controllable, From, Event, To,
self:T2( ToTargetVec2 ) self:T2( ToTargetVec2 )
--- Obtain a 3D @{Point} from the 2D point + altitude. --- 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. --- Create a route point of type air.
local ToTargetRoutePoint = ToTargetPointVec3:WaypointAir( local ToTargetRoutePoint = ToTargetPointVec3:WaypointAir(
self.PatrolAltType, self.PatrolAltType,
POINT_VEC3.RoutePointType.TurningPoint, COORDINATE.WaypointType.TurningPoint,
POINT_VEC3.RoutePointAction.TurningPoint, COORDINATE.WaypointAction.TurningPoint,
self.EngageSpeed, self.EngageSpeed,
true true
) )
+3 -1
View File
@@ -9,12 +9,14 @@
-- @module AI.AI_Cargo -- @module AI.AI_Cargo
-- @image Cargo.JPG -- @image Cargo.JPG
-- @type AI_CARGO --- @type AI_CARGO
-- @extends Core.Fsm#FSM_CONTROLLABLE -- @extends Core.Fsm#FSM_CONTROLLABLE
--- Base class for the dynamic cargo handling capability for AI groups. --- 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. -- 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. -- 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. -- 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. --- 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. -- 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. -- The AI_CARGO_APC class uses the @{Cargo.Cargo} capabilities within the MOOSE framework.
@@ -15,6 +15,8 @@
--- Brings a dynamic cargo handling capability for an AI airplane group. --- 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. -- Airplane carrier equipment can be mobilized to intelligently transport infantry and other cargo within the simulation between airbases.
-- --
-- The AI_CARGO_AIRPLANE module uses the @{Cargo.Cargo} capabilities within the MOOSE framework. -- The AI_CARGO_AIRPLANE module uses the @{Cargo.Cargo} capabilities within the MOOSE framework.
@@ -440,7 +442,7 @@ function AI_CARGO_AIRPLANE:Route( Airplane, Airbase, Speed, Height, Uncontrolled
-- To point. -- To point.
local AirbasePointVec2 = Airbase:GetPointVec2() 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["airdromeId"] = Airbase:GetID()
--ToWaypoint["speed_locked"] = true --ToWaypoint["speed_locked"] = true
@@ -22,6 +22,8 @@
-- --
-- === -- ===
-- --
-- ![Banner Image](..\Images\deprecated.png)
--
-- # The dispatcher concept. -- # The dispatcher concept.
-- --
-- Carrier equipment can be mobilized to intelligently transport infantry and other cargo within the simulation. -- 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. --- 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. -- 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. -- 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. --- 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. -- 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. -- 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. --- 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. -- 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. --- 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. -- 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. -- 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. --- 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. -- 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. -- 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 CoordinateFrom = Helicopter:GetCoordinate()
-- local WaypointFrom = CoordinateFrom:WaypointAir( -- local WaypointFrom = CoordinateFrom:WaypointAir(
-- "RADIO", -- "RADIO",
-- POINT_VEC3.RoutePointType.TurningPoint, -- COORDINATE.WaypointType.TurningPoint,
-- POINT_VEC3.RoutePointAction.TurningPoint, -- COORDINATE.WaypointAction.TurningPoint,
-- Speed, -- Speed,
-- true -- true
-- ) -- )
@@ -380,8 +382,8 @@ function AI_CARGO_HELICOPTER:onafterQueue( Helicopter, From, Event, To, Coordina
local WaypointTo = CoordinateTo:WaypointAir( local WaypointTo = CoordinateTo:WaypointAir(
"RADIO", "RADIO",
POINT_VEC3.RoutePointType.TurningPoint, COORDINATE.WaypointType.TurningPoint,
POINT_VEC3.RoutePointAction.TurningPoint, COORDINATE.WaypointAction.TurningPoint,
50, 50,
true true
) )
@@ -427,7 +429,7 @@ function AI_CARGO_HELICOPTER:onafterOrbit( Helicopter, From, Event, To, Coordina
local landheight = CoordinateTo:GetLandHeight() -- get target height local landheight = CoordinateTo:GetLandHeight() -- get target height
CoordinateTo.y = landheight + 50 -- flight height should be 50m above ground 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 Route[#Route+1] = WaypointTo
local Tasks = {} local Tasks = {}
@@ -496,14 +498,14 @@ function AI_CARGO_HELICOPTER:onafterPickup( Helicopter, From, Event, To, Coordin
local CoordinateFrom = Helicopter:GetCoordinate() local CoordinateFrom = Helicopter:GetCoordinate()
--- Create a route point of type air. --- 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. --- Create a route point of type air.
local CoordinateTo = Coordinate local CoordinateTo = Coordinate
local landheight = CoordinateTo:GetLandHeight() -- get target height local landheight = CoordinateTo:GetLandHeight() -- get target height
CoordinateTo.y = landheight + 50 -- flight height should be 50m above ground 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] = WaypointFrom
Route[#Route+1] = WaypointTo 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. --- Create a route point of type air.
local CoordinateFrom = Helicopter:GetCoordinate() 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
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 local landheight = CoordinateTo:GetLandHeight() -- get target height
CoordinateTo.y = landheight + 50 -- flight height should be 50m above ground 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
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. --- Create a route point of type air.
local CoordinateFrom = Helicopter:GetCoordinate() 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
--- Create a route point of type air. --- 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 local landheight = CoordinateTo:GetLandHeight() -- get target height
CoordinateTo.y = landheight + Height -- flight height should be 50m above ground 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 Route[#Route+1] = WaypointTo
@@ -14,6 +14,8 @@
--- Brings a dynamic cargo handling capability for an AI naval group. --- 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. -- 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. -- 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. -- @{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. -- 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). -- 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. -- 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 -- # 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 -- 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 -- 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. --- Models the assignment of AI escorts to player flights upon request using the radio menu.
-- --
-- ![Banner Image](..\Images\deprecated.png)
--
-- # Developer Note -- # Developer Note
-- --
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE -- 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. -- 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). -- 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. -- The radio commands will vary according the category of the group. The richest set of commands are with helicopters and airPlanes.
+5 -3
View File
@@ -41,6 +41,8 @@
--- Build large formations, make AI follow a @{Wrapper.Client#CLIENT} (player) leader or a @{Wrapper.Unit#UNIT} (AI) leader. --- 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. -- 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!!! -- The AI_FORMATION class models formations in a different manner than the internal DCS formation logic!!!
-- The purpose of the class is to: -- The purpose of the class is to:
@@ -725,7 +727,7 @@ function AI_FORMATION:onafterFormationLine( FollowGroupSet, From , Event , To, X
for FollowID, FollowGroup in pairs( FollowSet ) do for FollowID, FollowGroup in pairs( FollowSet ) do
local PointVec3 = POINT_VEC3:New() local PointVec3 = COORDINATE:New()
PointVec3:SetX( XStart + i * XSpace ) PointVec3:SetX( XStart + i * XSpace )
PointVec3:SetY( YStart + i * YSpace ) PointVec3:SetY( YStart + i * YSpace )
PointVec3:SetZ( ZStart + i * ZSpace ) PointVec3:SetZ( ZStart + i * ZSpace )
@@ -877,7 +879,7 @@ function AI_FORMATION:onafterFormationCenterWing( FollowGroupSet, From , Event ,
for FollowID, FollowGroup in pairs( FollowSet ) do 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 Side = ( i % 2 == 0 ) and 1 or -1
local Row = i / 2 + 1 local Row = i / 2 + 1
@@ -936,7 +938,7 @@ function AI_FORMATION:onafterFormationBox( FollowGroupSet, From , Event , To, XS
for FollowID, FollowGroup in pairs( FollowSet ) do for FollowID, FollowGroup in pairs( FollowSet ) do
local PointVec3 = POINT_VEC3:New() local PointVec3 = COORDINATE:New()
local ZIndex = i % ZLevels local ZIndex = i % ZLevels
local XIndex = math.floor( i / ZLevels ) local XIndex = math.floor( i / ZLevels )
+24 -13
View File
@@ -48,6 +48,8 @@
--- Implements the core functions to patrol a @{Core.Zone} by an AI @{Wrapper.Controllable} or @{Wrapper.Group}. --- 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) -- ![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. -- 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 if not CurrentVec2 then return end
--Done: Create GetAltitude function for GROUP, and delete GetUnit(1). --Done: Create GetAltitude function for GROUP, and delete GetUnit(1).
local CurrentAltitude = self.Controllable: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 ToPatrolZoneSpeed = self.PatrolMaxSpeed
local CurrentRoutePoint = CurrentPointVec3:WaypointAir( local CurrentRoutePoint = CurrentPointVec3:WaypointAir(
self.PatrolAltType, self.PatrolAltType,
POINT_VEC3.RoutePointType.TakeOffParking, COORDINATE.WaypointType.TakeOffParking,
POINT_VEC3.RoutePointAction.FromParkingArea, COORDINATE.WaypointAction.FromParkingArea,
ToPatrolZoneSpeed, ToPatrolZoneSpeed,
true true
) )
@@ -767,12 +769,12 @@ function AI_PATROL_ZONE:onafterRoute( Controllable, From, Event, To )
if not CurrentVec2 then return end if not CurrentVec2 then return end
--DONE: Create GetAltitude function for GROUP, and delete GetUnit(1). --DONE: Create GetAltitude function for GROUP, and delete GetUnit(1).
local CurrentAltitude = self.Controllable: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 ToPatrolZoneSpeed = self.PatrolMaxSpeed
local CurrentRoutePoint = CurrentPointVec3:WaypointAir( local CurrentRoutePoint = CurrentPointVec3:WaypointAir(
self.PatrolAltType, self.PatrolAltType,
POINT_VEC3.RoutePointType.TurningPoint, COORDINATE.WaypointType.TurningPoint,
POINT_VEC3.RoutePointAction.TurningPoint, COORDINATE.WaypointAction.TurningPoint,
ToPatrolZoneSpeed, ToPatrolZoneSpeed,
true true
) )
@@ -792,13 +794,13 @@ function AI_PATROL_ZONE:onafterRoute( Controllable, From, Event, To )
self:T2( { self.PatrolMinSpeed, self.PatrolMaxSpeed, ToTargetSpeed } ) self:T2( { self.PatrolMinSpeed, self.PatrolMaxSpeed, ToTargetSpeed } )
--- Obtain a 3D @{Point} from the 2D point + altitude. --- 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. --- Create a route point of type air.
local ToTargetRoutePoint = ToTargetPointVec3:WaypointAir( local ToTargetRoutePoint = ToTargetPointVec3:WaypointAir(
self.PatrolAltType, self.PatrolAltType,
POINT_VEC3.RoutePointType.TurningPoint, COORDINATE.WaypointType.TurningPoint,
POINT_VEC3.RoutePointAction.TurningPoint, COORDINATE.WaypointAction.TurningPoint,
ToTargetSpeed, ToTargetSpeed,
true true
) )
@@ -846,7 +848,6 @@ function AI_PATROL_ZONE:onafterStatus()
OldAIControllable:SetTask( TimedOrbitTask, 10 ) OldAIControllable:SetTask( TimedOrbitTask, 10 )
RTB = true RTB = true
else
end end
-- TODO: Check GROUP damage function. -- TODO: Check GROUP damage function.
@@ -856,6 +857,16 @@ function AI_PATROL_ZONE:onafterStatus()
RTB = true RTB = true
end end
if self:IsInstanceOf("AI_CAS") or self:IsInstanceOf("AI_BAI") then
local atotal,shells,rockets,bombs,missiles = self.Controllable:GetAmmunition()
local arelevant = rockets+bombs
if arelevant == 0 or missiles == 0 then
RTB = true
self:T({total=atotal,shells=shells,rockets=rockets,bombs=bombs,missiles=missiles})
self:T( self.Controllable:GetName() .. " is out of ammo, RTB!" )
end
end
if RTB == true then if RTB == true then
self:RTB() self:RTB()
else else
@@ -881,12 +892,12 @@ function AI_PATROL_ZONE:onafterRTB()
--DONE: Create GetAltitude function for GROUP, and delete GetUnit(1). --DONE: Create GetAltitude function for GROUP, and delete GetUnit(1).
--local CurrentAltitude = self.Controllable:GetUnit(1):GetAltitude() --local CurrentAltitude = self.Controllable:GetUnit(1):GetAltitude()
local CurrentAltitude = self.Controllable: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 ToPatrolZoneSpeed = self.PatrolMaxSpeed
local CurrentRoutePoint = CurrentPointVec3:WaypointAir( local CurrentRoutePoint = CurrentPointVec3:WaypointAir(
self.PatrolAltType, self.PatrolAltType,
POINT_VEC3.RoutePointType.TurningPoint, COORDINATE.WaypointType.TurningPoint,
POINT_VEC3.RoutePointAction.TurningPoint, COORDINATE.WaypointAction.TurningPoint,
ToPatrolZoneSpeed, ToPatrolZoneSpeed,
true true
) )
@@ -1,6 +1,6 @@
--- **Actions** - ACT_ACCOUNT_ classes **account for** (detect, count & report) various DCS events occurring on UNITs. --- **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)
-- --
-- === -- ===
-- --
@@ -11,6 +11,8 @@ do -- ACT_ACCOUNT
--- # @{#ACT_ACCOUNT} FSM class, extends @{Core.Fsm#FSM_PROCESS} --- # @{#ACT_ACCOUNT} FSM class, extends @{Core.Fsm#FSM_PROCESS}
-- --
-- ![Banner Image](..\Images\deprecated.png)
--
-- ## ACT_ACCOUNT state machine: -- ## ACT_ACCOUNT state machine:
-- --
-- This class is a state machine: it manages a process that is triggered by events causing state transitions to occur. -- 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 Event
-- @param #string From -- @param #string From
-- @param #string To -- @param #string To
function ACT_ACCOUNT:onafterEvent( ProcessUnit, From, Event, To, Event ) function ACT_ACCOUNT:onafterEvent( ProcessUnit, From, Event, To )
self:__NoMore( 1 ) self:__NoMore( 1 )
end end
@@ -2,6 +2,8 @@
-- --
-- === -- ===
-- --
-- ![Banner Image](..\Images\deprecated.png)
--
-- # @{#ACT_ASSIGN} FSM template class, extends @{Core.Fsm#FSM_PROCESS} -- # @{#ACT_ASSIGN} FSM template class, extends @{Core.Fsm#FSM_PROCESS}
-- --
-- ## ACT_ASSIGN state machine: -- ## ACT_ASSIGN state machine:
@@ -1,5 +1,6 @@
--- (SP) (MP) (FSM) Route AI or players through waypoints or to zones. --- (SP) (MP) (FSM) Route AI or players through waypoints or to zones.
-- --
-- ![Banner Image](..\Images\deprecated.png)
-- ## ACT_ASSIST state machine: -- ## ACT_ASSIST state machine:
-- --
-- This class is a state machine: it manages a process that is triggered by events causing state transitions to occur. -- 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} FSM class, extends @{Core.Fsm#FSM_PROCESS}
-- --
-- ## ACT_ROUTE state machine: -- ## ACT_ROUTE state machine:
+9 -7
View File
@@ -2,6 +2,8 @@
-- --
-- === -- ===
-- --
-- ![Banner Image](..\Images\deprecated.png)
--
-- # 1) MOOSE Cargo System. -- # 1) MOOSE Cargo System.
-- --
-- #### Those who have used the mission editor, know that the DCS mission editor provides cargo facilities. -- #### 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. -- The cargo must be in the **Loaded** state.
-- @function [parent=#CARGO] UnBoard -- @function [parent=#CARGO] UnBoard
-- @param #CARGO self -- @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. --- 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. -- The cargo must be in the **Loaded** state.
-- @function [parent=#CARGO] __UnBoard -- @function [parent=#CARGO] __UnBoard
-- @param #CARGO self -- @param #CARGO self
-- @param #number DelaySeconds The amount of seconds to delay the action. -- @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 -- Load
@@ -307,14 +309,14 @@
-- The cargo must be in the **Loaded** state. -- The cargo must be in the **Loaded** state.
-- @function [parent=#CARGO] UnLoad -- @function [parent=#CARGO] UnLoad
-- @param #CARGO self -- @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. --- 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. -- The cargo must be in the **Loaded** state.
-- @function [parent=#CARGO] __UnLoad -- @function [parent=#CARGO] __UnLoad
-- @param #CARGO self -- @param #CARGO self
-- @param #number DelaySeconds The amount of seconds to delay the action. -- @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 -- State Transition Functions
@@ -467,7 +469,7 @@ do -- CARGO
self.Type = Type self.Type = Type
self.Name = Name self.Name = Name
self.Weight = Weight or 0 self.Weight = Weight or 0
self.CargoObject = nil self.CargoObject = nil -- Wrapper.Group#GROUP
self.CargoCarrier = nil -- Wrapper.Client#CLIENT self.CargoCarrier = nil -- Wrapper.Client#CLIENT
self.Representable = false self.Representable = false
self.Slingloadable = false self.Slingloadable = false
@@ -897,7 +899,7 @@ do -- CARGO
--- Get the current PointVec2 of the cargo. --- Get the current PointVec2 of the cargo.
-- @param #CARGO self -- @param #CARGO self
-- @return Core.Point#POINT_VEC2 -- @return Core.Point#COORDINATE
function CARGO:GetPointVec2() function CARGO:GetPointVec2()
return self.CargoObject:GetPointVec2() return self.CargoObject:GetPointVec2()
end end
@@ -1094,7 +1096,7 @@ do -- CARGO_REPRESENTABLE
--- Route a cargo unit to a PointVec2. --- Route a cargo unit to a PointVec2.
-- @param #CARGO_REPRESENTABLE self -- @param #CARGO_REPRESENTABLE self
-- @param Core.Point#POINT_VEC2 ToPointVec2 -- @param Core.Point#COORDINATE ToPointVec2
-- @param #number Speed -- @param #number Speed
-- @return #CARGO_REPRESENTABLE -- @return #CARGO_REPRESENTABLE
function CARGO_REPRESENTABLE:RouteTo( ToPointVec2, Speed ) function CARGO_REPRESENTABLE:RouteTo( ToPointVec2, Speed )
+4 -1
View File
@@ -22,6 +22,9 @@ do -- CARGO_CRATE
-- @type CARGO_CRATE -- @type CARGO_CRATE
-- @extends Cargo.Cargo#CARGO_REPRESENTABLE -- @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. --- 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. -- 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 Event
-- @param #string From -- @param #string From
-- @param #string To -- @param #string To
-- @param Core.Point#POINT_VEC2 -- @param Core.Point#COORDINATE
function CARGO_CRATE:onenterUnLoaded( From, Event, To, ToPointVec2 ) function CARGO_CRATE:onenterUnLoaded( From, Event, To, ToPointVec2 )
--self:T( { ToPointVec2, From, Event, To } ) --self:T( { ToPointVec2, From, Event, To } )
+7 -3
View File
@@ -22,9 +22,12 @@ do -- CARGO_GROUP
--- @type CARGO_GROUP --- @type CARGO_GROUP
-- @field Core.Set#SET_CARGO CargoSet The collection of derived CARGO objects. -- @field Core.Set#SET_CARGO CargoSet The collection of derived CARGO objects.
-- @field #string GroupName The name of the CargoGroup. -- @field #string GroupName The name of the CargoGroup.
-- @field Wrapper.Group#GROUÜ CargoCarrier The carrier group.
-- @extends Cargo.Cargo#CARGO_REPORTABLE -- @extends Cargo.Cargo#CARGO_REPORTABLE
--- Defines a cargo that is represented by a @{Wrapper.Group} object within the simulator. --- 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 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: -- 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 Event
-- @param #string From -- @param #string From
-- @param #string To -- @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. -- @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, ... ) function CARGO_GROUP:onafterUnBoard( From, Event, To, ToPointVec2, NearRadius, ... )
self:T( {From, Event, To, ToPointVec2, NearRadius } ) self:T( {From, Event, To, ToPointVec2, NearRadius } )
@@ -453,7 +456,7 @@ do -- CARGO_GROUP
-- @param #string Event -- @param #string Event
-- @param #string From -- @param #string From
-- @param #string To -- @param #string To
-- @param Core.Point#POINT_VEC2 ToPointVec2 -- @param Core.Point#COORDINATE ToPointVec2
-- @param #number NearRadius If distance is smaller than this number, cargo is loaded into the carrier. -- @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, ... ) function CARGO_GROUP:onafterUnBoarding( From, Event, To, ToPointVec2, NearRadius, ... )
--self:T( { From, Event, To, ToPointVec2, NearRadius } ) --self:T( { From, Event, To, ToPointVec2, NearRadius } )
@@ -491,7 +494,7 @@ do -- CARGO_GROUP
-- @param #string Event -- @param #string Event
-- @param #string From -- @param #string From
-- @param #string To -- @param #string To
-- @param Core.Point#POINT_VEC2 ToPointVec2 -- @param Core.Point#COORDINATE ToPointVec2
function CARGO_GROUP:onafterUnLoad( From, Event, To, ToPointVec2, ... ) function CARGO_GROUP:onafterUnLoad( From, Event, To, ToPointVec2, ... )
--self:T( { From, Event, To, ToPointVec2 } ) --self:T( { From, Event, To, ToPointVec2 } )
@@ -771,3 +774,4 @@ do -- CARGO_GROUP
end -- CARGO_GROUP end -- CARGO_GROUP
@@ -32,6 +32,8 @@ do -- CARGO_SLINGLOAD
-- --
-- # Developer Note -- # 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 -- 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 -- Therefore, this class is considered to be deprecated
-- --
+6 -4
View File
@@ -30,6 +30,8 @@ do -- CARGO_UNIT
-- --
-- # Developer Note -- # 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 -- 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 -- Therefore, this class is considered to be deprecated
-- --
@@ -72,7 +74,7 @@ do -- CARGO_UNIT
-- @param #string Event -- @param #string Event
-- @param #string From -- @param #string From
-- @param #string To -- @param #string To
-- @param Core.Point#POINT_VEC2 ToPointVec2 -- @param Core.Point#COORDINATE ToPointVec2
-- @param #number NearRadius (optional) Defaut 25 m. -- @param #number NearRadius (optional) Defaut 25 m.
function CARGO_UNIT:onenterUnBoarding( From, Event, To, ToPointVec2, NearRadius ) function CARGO_UNIT:onenterUnBoarding( From, Event, To, ToPointVec2, NearRadius )
self:T( { From, Event, To, ToPointVec2, NearRadius } ) self:T( { From, Event, To, ToPointVec2, NearRadius } )
@@ -145,7 +147,7 @@ do -- CARGO_UNIT
-- @param #string Event -- @param #string Event
-- @param #string From -- @param #string From
-- @param #string To -- @param #string To
-- @param Core.Point#POINT_VEC2 ToPointVec2 -- @param Core.Point#COORDINATE ToPointVec2
-- @param #number NearRadius (optional) Defaut 100 m. -- @param #number NearRadius (optional) Defaut 100 m.
function CARGO_UNIT:onleaveUnBoarding( From, Event, To, ToPointVec2, NearRadius ) function CARGO_UNIT:onleaveUnBoarding( From, Event, To, ToPointVec2, NearRadius )
self:T( { From, Event, To, ToPointVec2, NearRadius } ) self:T( { From, Event, To, ToPointVec2, NearRadius } )
@@ -171,7 +173,7 @@ do -- CARGO_UNIT
-- @param #string Event -- @param #string Event
-- @param #string From -- @param #string From
-- @param #string To -- @param #string To
-- @param Core.Point#POINT_VEC2 ToPointVec2 -- @param Core.Point#COORDINATE ToPointVec2
-- @param #number NearRadius (optional) Defaut 100 m. -- @param #number NearRadius (optional) Defaut 100 m.
function CARGO_UNIT:onafterUnBoarding( From, Event, To, ToPointVec2, NearRadius ) function CARGO_UNIT:onafterUnBoarding( From, Event, To, ToPointVec2, NearRadius )
self:T( { From, Event, To, ToPointVec2, NearRadius } ) self:T( { From, Event, To, ToPointVec2, NearRadius } )
@@ -197,7 +199,7 @@ do -- CARGO_UNIT
-- @param #string Event -- @param #string Event
-- @param #string From -- @param #string From
-- @param #string To -- @param #string To
-- @param Core.Point#POINT_VEC2 -- @param Core.Point#COORDINATE
function CARGO_UNIT:onenterUnLoaded( From, Event, To, ToPointVec2 ) function CARGO_UNIT:onenterUnLoaded( From, Event, To, ToPointVec2 )
self:T( { ToPointVec2, From, Event, To } ) self:T( { ToPointVec2, From, Event, To } )
+121 -23
View File
@@ -26,7 +26,7 @@
-- @module Core.Base -- @module Core.Base
-- @image Core_Base.JPG -- @image Core_Base.JPG
local _TraceOnOff = true local _TraceOnOff = false -- default to no tracing
local _TraceLevel = 1 local _TraceLevel = 1
local _TraceAll = false local _TraceAll = false
local _TraceClass = {} local _TraceClass = {}
@@ -34,11 +34,12 @@ local _TraceClassMethod = {}
local _ClassID = 0 local _ClassID = 0
--- --- Base class of everything
-- @type BASE -- @type BASE
-- @field ClassName The name of the class. -- @field #string ClassName The name of the class.
-- @field ClassID The ID number of the class. -- @field #number ClassID The ID number of the class.
-- @field ClassNameAndID The name of the class concatenated with the ID number of the class. -- @field #string ClassNameAndID The name of the class concatenated with the ID number of the class.
-- @field Core.Scheduler#SCHEDULER Scheduler The scheduler object.
--- BASE class --- BASE class
-- --
@@ -200,6 +201,7 @@ BASE = {
States = {}, States = {},
Debug = debug, Debug = debug,
Scheduler = nil, Scheduler = nil,
Properties = {},
} }
-- @field #BASE.__ -- @field #BASE.__
@@ -210,14 +212,6 @@ BASE._ = {
Schedules = {}, --- Contains the Schedulers Active Schedules = {}, --- Contains the Schedulers Active
} }
--- The Formation Class
-- @type FORMATION
-- @field Cone A cone formation.
FORMATION = {
Cone = "Cone",
Vee = "Vee",
}
--- BASE constructor. --- BASE constructor.
-- --
-- This is an example how to use the BASE:New() constructor in a new class definition when inheriting from BASE. -- This is an example how to use the BASE:New() constructor in a new class definition when inheriting from BASE.
@@ -742,6 +736,30 @@ do -- Event Handling
-- @param #BASE self -- @param #BASE self
-- @param Core.Event#EVENTDATA EventData The EventData structure. -- @param Core.Event#EVENTDATA EventData The EventData structure.
--- Occurs when a player creates a dynamic cargo object from the F8 ground crew menu.
-- *** NOTE *** this is a workarounf for DCS not creating these events as of Aug 2024.
-- @function [parent=#BASE] OnEventNewDynamicCargo
-- @param #BASE self
-- @param Core.Event#EVENTDATA EventData The EventData structure.
--- Occurs when a player loads a dynamic cargo object with the F8 ground crew menu into a helo.
-- *** NOTE *** this is a workarounf for DCS not creating these events as of Aug 2024.
-- @function [parent=#BASE] OnEventDynamicCargoLoaded
-- @param #BASE self
-- @param Core.Event#EVENTDATA EventData The EventData structure.
--- Occurs when a player unloads a dynamic cargo object with the F8 ground crew menu from a helo.
-- *** NOTE *** this is a workarounf for DCS not creating these events as of Aug 2024.
-- @function [parent=#BASE] OnEventDynamicCargoUnloaded
-- @param #BASE self
-- @param Core.Event#EVENTDATA EventData The EventData structure.
--- Occurs when a dynamic cargo crate is removed.
-- *** NOTE *** this is a workarounf for DCS not creating these events as of Aug 2024.
-- @function [parent=#BASE] OnEventDynamicCargoRemoved
-- @param #BASE self
-- @param Core.Event#EVENTDATA EventData The EventData structure.
end end
--- Creation of a Birth Event. --- Creation of a Birth Event.
@@ -863,6 +881,62 @@ end
world.onEvent(Event) world.onEvent(Event)
end end
--- Creation of a S_EVENT_NEW_DYNAMIC_CARGO event.
-- @param #BASE self
-- @param Wrapper.DynamicCargo#DYNAMICCARGO DynamicCargo the dynamic cargo object
function BASE:CreateEventNewDynamicCargo(DynamicCargo)
self:F({DynamicCargo})
local Event = {
id = EVENTS.NewDynamicCargo,
time = timer.getTime(),
dynamiccargo = DynamicCargo,
initiator = DynamicCargo:GetDCSObject(),
}
world.onEvent( Event )
end
--- Creation of a S_EVENT_DYNAMIC_CARGO_LOADED event.
-- @param #BASE self
-- @param Wrapper.DynamicCargo#DYNAMICCARGO DynamicCargo the dynamic cargo object
function BASE:CreateEventDynamicCargoLoaded(DynamicCargo)
self:F({DynamicCargo})
local Event = {
id = EVENTS.DynamicCargoLoaded,
time = timer.getTime(),
dynamiccargo = DynamicCargo,
initiator = DynamicCargo:GetDCSObject(),
}
world.onEvent( Event )
end
--- Creation of a S_EVENT_DYNAMIC_CARGO_UNLOADED event.
-- @param #BASE self
-- @param Wrapper.DynamicCargo#DYNAMICCARGO DynamicCargo the dynamic cargo object
function BASE:CreateEventDynamicCargoUnloaded(DynamicCargo)
self:F({DynamicCargo})
local Event = {
id = EVENTS.DynamicCargoUnloaded,
time = timer.getTime(),
dynamiccargo = DynamicCargo,
initiator = DynamicCargo:GetDCSObject(),
}
world.onEvent( Event )
end
--- Creation of a S_EVENT_DYNAMIC_CARGO_REMOVED event.
-- @param #BASE self
-- @param Wrapper.DynamicCargo#DYNAMICCARGO DynamicCargo the dynamic cargo object
function BASE:CreateEventDynamicCargoRemoved(DynamicCargo)
self:F({DynamicCargo})
local Event = {
id = EVENTS.DynamicCargoRemoved,
time = timer.getTime(),
dynamiccargo = DynamicCargo,
initiator = DynamicCargo:GetDCSObject(),
}
world.onEvent( Event )
end
--- The main event handling function... This function captures all events generated for the class. --- The main event handling function... This function captures all events generated for the class.
-- @param #BASE self -- @param #BASE self
-- @param DCS#Event event -- @param DCS#Event event
@@ -900,7 +974,7 @@ do -- Scheduling
-- @param #BASE self -- @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 #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 #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. -- @return #string The Schedule ID of the planned schedule.
function BASE:ScheduleOnce( Start, SchedulerFunction, ... ) function BASE:ScheduleOnce( Start, SchedulerFunction, ... )
@@ -1036,6 +1110,31 @@ function BASE:ClearState( Object, StateName )
end end
end end
--- Set one property of an object.
-- @param #BASE self
-- @param Key The key that is used as a reference of the value. Note that the key can be a #string, but it can also be any other type!
-- @param Value The value that is stored. Note that the value can be a #string, but it can also be any other type!
function BASE:SetProperty(Key,Value)
self.Properties = self.Properties or {}
self.Properties[Key] = Value
end
--- Get one property of an object by the key.
-- @param #BASE self
-- @param Key The key that is used as a reference of the value. Note that the key can be a #string, but it can also be any other type!
-- @return Value The value that is stored. Note that the value can be a #string, but it can also be any other type! Nil if not found.
function BASE:GetProperty(Key)
self.Properties = self.Properties or {}
return self.Properties[Key]
end
--- Get all of the properties of an object in a table.
-- @param #BASE self
-- @return #table of values, indexed by keys.
function BASE:GetProperties()
return self.Properties
end
-- Trace section -- Trace section
-- Log a trace (only shown when trace is on) -- Log a trace (only shown when trace is on)
@@ -1200,7 +1299,7 @@ end
-- @param Arguments A #table or any field. -- @param Arguments A #table or any field.
function BASE:F( Arguments ) function BASE:F( Arguments )
if BASE.Debug and _TraceOnOff then if BASE.Debug and _TraceOnOff == true then
local DebugInfoCurrent = BASE.Debug.getinfo( 2, "nl" ) local DebugInfoCurrent = BASE.Debug.getinfo( 2, "nl" )
local DebugInfoFrom = BASE.Debug.getinfo( 3, "l" ) local DebugInfoFrom = BASE.Debug.getinfo( 3, "l" )
@@ -1215,7 +1314,7 @@ end
-- @param Arguments A #table or any field. -- @param Arguments A #table or any field.
function BASE:F2( Arguments ) function BASE:F2( Arguments )
if BASE.Debug and _TraceOnOff then if BASE.Debug and _TraceOnOff == true and _TraceLevel >= 2 then
local DebugInfoCurrent = BASE.Debug.getinfo( 2, "nl" ) local DebugInfoCurrent = BASE.Debug.getinfo( 2, "nl" )
local DebugInfoFrom = BASE.Debug.getinfo( 3, "l" ) local DebugInfoFrom = BASE.Debug.getinfo( 3, "l" )
@@ -1230,7 +1329,7 @@ end
-- @param Arguments A #table or any field. -- @param Arguments A #table or any field.
function BASE:F3( Arguments ) function BASE:F3( Arguments )
if BASE.Debug and _TraceOnOff then if BASE.Debug and _TraceOnOff == true and _TraceLevel >= 3 then
local DebugInfoCurrent = BASE.Debug.getinfo( 2, "nl" ) local DebugInfoCurrent = BASE.Debug.getinfo( 2, "nl" )
local DebugInfoFrom = BASE.Debug.getinfo( 3, "l" ) local DebugInfoFrom = BASE.Debug.getinfo( 3, "l" )
@@ -1274,7 +1373,7 @@ end
-- @param Arguments A #table or any field. -- @param Arguments A #table or any field.
function BASE:T( Arguments ) function BASE:T( Arguments )
if BASE.Debug and _TraceOnOff then if BASE.Debug and _TraceOnOff == true then
local DebugInfoCurrent = BASE.Debug.getinfo( 2, "nl" ) local DebugInfoCurrent = BASE.Debug.getinfo( 2, "nl" )
local DebugInfoFrom = BASE.Debug.getinfo( 3, "l" ) local DebugInfoFrom = BASE.Debug.getinfo( 3, "l" )
@@ -1289,7 +1388,7 @@ end
-- @param Arguments A #table or any field. -- @param Arguments A #table or any field.
function BASE:T2( Arguments ) function BASE:T2( Arguments )
if BASE.Debug and _TraceOnOff then if BASE.Debug and _TraceOnOff == true and _TraceLevel >= 2 then
local DebugInfoCurrent = BASE.Debug.getinfo( 2, "nl" ) local DebugInfoCurrent = BASE.Debug.getinfo( 2, "nl" )
local DebugInfoFrom = BASE.Debug.getinfo( 3, "l" ) local DebugInfoFrom = BASE.Debug.getinfo( 3, "l" )
@@ -1304,7 +1403,7 @@ end
-- @param Arguments A #table or any field. -- @param Arguments A #table or any field.
function BASE:T3( Arguments ) function BASE:T3( Arguments )
if BASE.Debug and _TraceOnOff then if BASE.Debug and _TraceOnOff == true and _TraceLevel >= 3 then
local DebugInfoCurrent = BASE.Debug.getinfo( 2, "nl" ) local DebugInfoCurrent = BASE.Debug.getinfo( 2, "nl" )
local DebugInfoFrom = BASE.Debug.getinfo( 3, "l" ) local DebugInfoFrom = BASE.Debug.getinfo( 3, "l" )
@@ -1336,7 +1435,7 @@ function BASE:E( Arguments )
env.info( string.format( "%6d(%6d)/%1s:%30s%05d.%s(%s)", LineCurrent, LineFrom, "E", self.ClassName, self.ClassID, Function, UTILS.BasicSerialize( Arguments ) ) ) env.info( string.format( "%6d(%6d)/%1s:%30s%05d.%s(%s)", LineCurrent, LineFrom, "E", self.ClassName, self.ClassID, Function, UTILS.BasicSerialize( Arguments ) ) )
else else
env.info( string.format( "%1s:%30s%05d(%s)", "E", self.ClassName, self.ClassID, BASE:_Serialize(Arguments) ) ) env.info( string.format( "%1s:%30s%05d(%s)", "E", self.ClassName, self.ClassID, UTILS.BasicSerialize(Arguments) ) )
end end
end end
@@ -1363,8 +1462,7 @@ function BASE:I( Arguments )
env.info( string.format( "%6d(%6d)/%1s:%30s%05d.%s(%s)", LineCurrent, LineFrom, "I", self.ClassName, self.ClassID, Function, UTILS.BasicSerialize( Arguments ) ) ) env.info( string.format( "%6d(%6d)/%1s:%30s%05d.%s(%s)", LineCurrent, LineFrom, "I", self.ClassName, self.ClassID, Function, UTILS.BasicSerialize( Arguments ) ) )
else else
env.info( string.format( "%1s:%30s%05d(%s)", "I", self.ClassName, self.ClassID, BASE:_Serialize(Arguments)) ) env.info( string.format( "%1s:%30s%05d(%s)", "I", self.ClassName, self.ClassID, UTILS.BasicSerialize(Arguments)) )
end end
end end
+20 -6
View File
@@ -20,7 +20,7 @@
-- --
-- @module Core.ClientMenu -- @module Core.ClientMenu
-- @image Core_Menu.JPG -- @image Core_Menu.JPG
-- last change: May 2024 -- last change: Sept 2025
-- TODO -- TODO
---------------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------------------
@@ -57,9 +57,9 @@
--- ---
-- @field #CLIENTMENU -- @field #CLIENTMENU
CLIENTMENU = { CLIENTMENU = {
ClassName = "CLIENTMENUE", ClassName = "CLIENTMENU",
lid = "", lid = "",
version = "0.1.2", version = "0.1.3",
name = nil, name = nil,
path = nil, path = nil,
group = nil, group = nil,
@@ -417,7 +417,7 @@ end
CLIENTMENUMANAGER = { CLIENTMENUMANAGER = {
ClassName = "CLIENTMENUMANAGER", ClassName = "CLIENTMENUMANAGER",
lid = "", lid = "",
version = "0.1.6", version = "0.1.7",
name = nil, name = nil,
clientset = nil, clientset = nil,
menutree = {}, menutree = {},
@@ -455,7 +455,7 @@ end
-- @param #CLIENTMENUMANAGER self -- @param #CLIENTMENUMANAGER self
-- @param Core.Event#EVENTDATA EventData -- @param Core.Event#EVENTDATA EventData
-- @return #CLIENTMENUMANAGER self -- @return #CLIENTMENUMANAGER self
function CLIENTMENUMANAGER:_EventHandler(EventData) function CLIENTMENUMANAGER:_EventHandler(EventData,Retry)
self:T(self.lid.."_EventHandler: "..EventData.id) self:T(self.lid.."_EventHandler: "..EventData.id)
--self:I(self.lid.."_EventHandler: "..tostring(EventData.IniPlayerName)) --self:I(self.lid.."_EventHandler: "..tostring(EventData.IniPlayerName))
if EventData.id == EVENTS.PlayerLeaveUnit or EventData.id == EVENTS.Ejection or EventData.id == EVENTS.Crash or EventData.id == EVENTS.PilotDead then if EventData.id == EVENTS.PlayerLeaveUnit or EventData.id == EVENTS.Ejection or EventData.id == EVENTS.Crash or EventData.id == EVENTS.PilotDead then
@@ -468,6 +468,10 @@ function CLIENTMENUMANAGER:_EventHandler(EventData)
if EventData.IniPlayerName and EventData.IniGroup then if EventData.IniPlayerName and EventData.IniGroup then
if (not self.clientset:IsIncludeObject(_DATABASE:FindClient( EventData.IniUnitName ))) then if (not self.clientset:IsIncludeObject(_DATABASE:FindClient( EventData.IniUnitName ))) then
self:T(self.lid.."Client not in SET: "..EventData.IniPlayerName) self:T(self.lid.."Client not in SET: "..EventData.IniPlayerName)
if not Retry then
-- try again in 2 secs
self:ScheduleOnce(2,CLIENTMENUMANAGER._EventHandler,self,EventData,true)
end
return self return self
end end
--self:I(self.lid.."Join event for player: "..EventData.IniPlayerName) --self:I(self.lid.."Join event for player: "..EventData.IniPlayerName)
@@ -524,7 +528,7 @@ function CLIENTMENUMANAGER:InitAutoPropagation()
self:HandleEvent(EVENTS.PilotDead, self._EventHandler) self:HandleEvent(EVENTS.PilotDead, self._EventHandler)
self:HandleEvent(EVENTS.PlayerEnterAircraft, self._EventHandler) self:HandleEvent(EVENTS.PlayerEnterAircraft, self._EventHandler)
self:HandleEvent(EVENTS.PlayerEnterUnit, self._EventHandler) self:HandleEvent(EVENTS.PlayerEnterUnit, self._EventHandler)
self:SetEventPriority(5) self:SetEventPriority(6)
return self return self
end end
@@ -802,6 +806,16 @@ function CLIENTMENUMANAGER:ResetMenuComplete()
return self return self
end end
--- Remove the entry and all entries below the given entry from the client's F10 menus.
-- @param #CLIENTMENUMANAGER self
-- @param #CLIENTMENU Entry The entry to remove
-- @param Wrapper.Client#CLIENT Client (optional) If given, make this change only for this client.
-- @return #CLIENTMENUMANAGER self
function CLIENTMENUMANAGER:DeleteEntry(Entry,Client)
self:T(self.lid.."DeleteEntry")
return self:DeleteF10Entry(Entry,Client)
end
--- Remove the entry and all entries below the given entry from the client's F10 menus. --- Remove the entry and all entries below the given entry from the client's F10 menus.
-- @param #CLIENTMENUMANAGER self -- @param #CLIENTMENUMANAGER self
-- @param #CLIENTMENU Entry The entry to remove -- @param #CLIENTMENU Entry The entry to remove
+128 -28
View File
@@ -20,6 +20,7 @@
-- * Manage database of hits to units and statics. -- * Manage database of hits to units and statics.
-- * Manage database of destroys of units and statics. -- * Manage database of destroys of units and statics.
-- * Manage database of @{Core.Zone#ZONE_BASE} objects. -- * Manage database of @{Core.Zone#ZONE_BASE} objects.
-- * Manage database of @{Wrapper.DynamicCargo#DYNAMICCARGO} objects alive in the mission.
-- --
-- === -- ===
-- --
@@ -39,6 +40,7 @@
-- @field #table STORAGES DCS warehouse storages. -- @field #table STORAGES DCS warehouse storages.
-- @field #table STNS Used Link16 octal numbers for F16/15/18/AWACS planes. -- @field #table STNS Used Link16 octal numbers for F16/15/18/AWACS planes.
-- @field #table SADL Used Link16 octal numbers for A10/C-II planes. -- @field #table SADL Used Link16 octal numbers for A10/C-II planes.
-- @field #table DYNAMICCARGO Dynamic Cargo objects.
-- @extends Core.Base#BASE -- @extends Core.Base#BASE
--- Contains collections of wrapper objects defined within MOOSE that reflect objects within the simulator. --- Contains collections of wrapper objects defined within MOOSE that reflect objects within the simulator.
@@ -54,6 +56,7 @@
-- * PLAYERS -- * PLAYERS
-- * CARGOS -- * CARGOS
-- * STORAGES (DCS warehouses) -- * STORAGES (DCS warehouses)
-- * DYNAMICCARGO
-- --
-- On top, for internal MOOSE administration purposes, the DATABASE administers the Unit and Group TEMPLATES as defined within the Mission Editor. -- On top, for internal MOOSE administration purposes, the DATABASE administers the Unit and Group TEMPLATES as defined within the Mission Editor.
-- --
@@ -97,6 +100,7 @@ DATABASE = {
STORAGES = {}, STORAGES = {},
STNS={}, STNS={},
SADL={}, SADL={},
DYNAMICCARGO={},
} }
local _DATABASECoalition = local _DATABASECoalition =
@@ -143,6 +147,8 @@ function DATABASE:New()
self:HandleEvent( EVENTS.DeleteZone ) self:HandleEvent( EVENTS.DeleteZone )
--self:HandleEvent( EVENTS.PlayerEnterUnit, self._EventOnPlayerEnterUnit ) -- This is not working anymore!, handling this through the birth event. --self:HandleEvent( EVENTS.PlayerEnterUnit, self._EventOnPlayerEnterUnit ) -- This is not working anymore!, handling this through the birth event.
self:HandleEvent( EVENTS.PlayerLeaveUnit, self._EventOnPlayerLeaveUnit ) self:HandleEvent( EVENTS.PlayerLeaveUnit, self._EventOnPlayerLeaveUnit )
-- DCS 2.9.7 Moose own dynamic cargo events
self:HandleEvent( EVENTS.DynamicCargoRemoved, self._EventOnDynamicCargoRemoved)
self:_RegisterTemplates() self:_RegisterTemplates()
self:_RegisterGroupsAndUnits() self:_RegisterGroupsAndUnits()
@@ -174,15 +180,19 @@ end
-- @return Wrapper.Unit#UNIT The added unit. -- @return Wrapper.Unit#UNIT The added unit.
function DATABASE:AddUnit( DCSUnitName, force ) function DATABASE:AddUnit( DCSUnitName, force )
if not self.UNITS[DCSUnitName] or force == true then local DCSunitName = DCSUnitName
if type(DCSunitName) == "number" then DCSunitName = string.format("%d",DCSUnitName) end
if not self.UNITS[DCSunitName] or force == true then
-- Debug info. -- Debug info.
self:T( { "Add UNIT:", DCSUnitName } ) self:T( { "Add UNIT:", DCSunitName } )
-- Register unit -- Register unit
self.UNITS[DCSUnitName]=UNIT:Register(DCSUnitName) self.UNITS[DCSunitName]=UNIT:Register(DCSunitName)
end end
return self.UNITS[DCSUnitName] return self.UNITS[DCSunitName]
end end
@@ -201,10 +211,9 @@ function DATABASE:AddStatic( DCSStaticName )
if not self.STATICS[DCSStaticName] then if not self.STATICS[DCSStaticName] then
self.STATICS[DCSStaticName] = STATIC:Register( DCSStaticName ) self.STATICS[DCSStaticName] = STATIC:Register( DCSStaticName )
return self.STATICS[DCSStaticName]
end end
return nil return self.STATICS[DCSStaticName]
end end
@@ -214,16 +223,42 @@ function DATABASE:DeleteStatic( DCSStaticName )
self.STATICS[DCSStaticName] = nil self.STATICS[DCSStaticName] = nil
end end
--- Finds a STATIC based on the StaticName. --- Finds a STATIC based on the Static Name.
-- @param #DATABASE self -- @param #DATABASE self
-- @param #string StaticName -- @param #string StaticName Name of the static object.
-- @return Wrapper.Static#STATIC The found STATIC. -- @return Wrapper.Static#STATIC The found STATIC.
function DATABASE:FindStatic( StaticName ) function DATABASE:FindStatic( StaticName )
local StaticFound = self.STATICS[StaticName] local StaticFound = self.STATICS[StaticName]
return StaticFound return StaticFound
end end
--- Add a DynamicCargo to the database.
-- @param #DATABASE self
-- @param #string Name Name of the dynamic cargo.
-- @return Wrapper.DynamicCargo#DYNAMICCARGO The dynamic cargo object.
function DATABASE:AddDynamicCargo( Name )
if not self.DYNAMICCARGO[Name] then
self.DYNAMICCARGO[Name] = DYNAMICCARGO:Register(Name)
end
return self.DYNAMICCARGO[Name]
end
--- Finds a DYNAMICCARGO based on the Dynamic Cargo Name.
-- @param #DATABASE self
-- @param #string DynamicCargoName
-- @return Wrapper.DynamicCargo#DYNAMICCARGO The found DYNAMICCARGO.
function DATABASE:FindDynamicCargo( DynamicCargoName )
local StaticFound = self.DYNAMICCARGO[DynamicCargoName]
return StaticFound
end
--- Deletes a DYNAMICCARGO from the DATABASE based on the Dynamic Cargo Name.
-- @param #DATABASE self
function DATABASE:DeleteDynamicCargo( DynamicCargoName )
self.DYNAMICCARGO[DynamicCargoName] = nil
return self
end
--- Adds a Airbase based on the Airbase Name in the DATABASE. --- Adds a Airbase based on the Airbase Name in the DATABASE.
-- @param #DATABASE self -- @param #DATABASE self
-- @param #string AirbaseName The name of the airbase. -- @param #string AirbaseName The name of the airbase.
@@ -542,13 +577,19 @@ do -- Zones and Pathlines
-- For a rectangular polygon drawing, we have the width (y) and height (x). -- For a rectangular polygon drawing, we have the width (y) and height (x).
local w=objectData.width local w=objectData.width
local h=objectData.height 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 sinRot = math.sin(rotation)
local points={} local cosRot = math.cos(rotation)
points[1]={x=vec2.x-h/2, y=vec2.y+w/2} --Upper left local dx = h / 2
points[2]={x=vec2.x+h/2, y=vec2.y+w/2} --Upper right local dy = w / 2
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 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") --local coord=COORDINATE:NewFromVec2(vec2):MarkToAll("MapX, MapY")
@@ -819,11 +860,15 @@ end
-- @return Wrapper.Client#CLIENT The client object. -- @return Wrapper.Client#CLIENT The client object.
function DATABASE:AddClient( ClientName, Force ) function DATABASE:AddClient( ClientName, Force )
if not self.CLIENTS[ClientName] or Force == true then local DCSUnitName = ClientName
self.CLIENTS[ClientName] = CLIENT:Register( ClientName )
if type(DCSUnitName) == "number" then DCSUnitName = string.format("%d",ClientName) end
if not self.CLIENTS[DCSUnitName] or Force == true then
self.CLIENTS[DCSUnitName] = CLIENT:Register( DCSUnitName )
end end
return self.CLIENTS[ClientName] return self.CLIENTS[DCSUnitName]
end end
@@ -833,6 +878,8 @@ end
-- @return Wrapper.Group#GROUP The found GROUP. -- @return Wrapper.Group#GROUP The found GROUP.
function DATABASE:FindGroup( GroupName ) function DATABASE:FindGroup( GroupName )
if type(GroupName) ~= "string" or GroupName == "" then return end
local GroupFound = self.GROUPS[GroupName] local GroupFound = self.GROUPS[GroupName]
if GroupFound == nil and GroupName ~= nil and self.Templates.Groups[GroupName] == nil then if GroupFound == nil and GroupName ~= nil and self.Templates.Groups[GroupName] == nil then
@@ -864,8 +911,10 @@ end
-- @param #DATABASE self -- @param #DATABASE self
function DATABASE:AddPlayer( UnitName, PlayerName ) function DATABASE:AddPlayer( UnitName, PlayerName )
if type(UnitName) == "number" then UnitName = string.format("%d",UnitName) end
if PlayerName then if PlayerName then
self:T( { "Add player for unit:", UnitName, PlayerName } ) self:I( { "Add player for unit:", UnitName, PlayerName } )
self.PLAYERS[PlayerName] = UnitName self.PLAYERS[PlayerName] = UnitName
self.PLAYERUNITS[PlayerName] = self:FindUnit( UnitName ) self.PLAYERUNITS[PlayerName] = self:FindUnit( UnitName )
self.PLAYERSJOINED[PlayerName] = PlayerName self.PLAYERSJOINED[PlayerName] = PlayerName
@@ -873,6 +922,21 @@ function DATABASE:AddPlayer( UnitName, PlayerName )
end end
--- Get a PlayerName by UnitName from PLAYERS in DATABASE.
-- @param #DATABASE self
-- @return #string PlayerName
-- @return Wrapper.Unit#UNIT PlayerUnit
function DATABASE:_FindPlayerNameByUnitName(UnitName)
if UnitName then
for playername,unitname in pairs(self.PLAYERS) do
if unitname == UnitName and self.PLAYERUNITS[playername] and self.PLAYERUNITS[playername]:IsAlive() then
return playername, self.PLAYERUNITS[playername]
end
end
end
return nil
end
--- Deletes a player from the DATABASE based on the Player Name. --- Deletes a player from the DATABASE based on the Player Name.
-- @param #DATABASE self -- @param #DATABASE self
function DATABASE:DeletePlayer( UnitName, PlayerName ) function DATABASE:DeletePlayer( UnitName, PlayerName )
@@ -1054,7 +1118,7 @@ function DATABASE:_RegisterGroupTemplate( GroupTemplate, CoalitionSide, Category
self:E("WARNING: Invalid STN "..tostring(UnitTemplate.AddPropAircraft.STN_L16).." for ".. UnitTemplate.name) self:E("WARNING: Invalid STN "..tostring(UnitTemplate.AddPropAircraft.STN_L16).." for ".. UnitTemplate.name)
else else
self.STNS[stn] = UnitTemplate.name 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
end end
if UnitTemplate.AddPropAircraft.SADL_TN then if UnitTemplate.AddPropAircraft.SADL_TN then
@@ -1063,7 +1127,7 @@ function DATABASE:_RegisterGroupTemplate( GroupTemplate, CoalitionSide, Category
self:E("WARNING: Invalid SADL "..tostring(UnitTemplate.AddPropAircraft.SADL_TN).." for ".. UnitTemplate.name) self:E("WARNING: Invalid SADL "..tostring(UnitTemplate.AddPropAircraft.SADL_TN).." for ".. UnitTemplate.name)
else else
self.SADL[sadl] = UnitTemplate.name 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 end
end end
@@ -1244,7 +1308,7 @@ function DATABASE:_GetGenericStaticCargoGroupTemplate(Name,Typename,Mass,Coaliti
StaticTemplate.CategoryID = "static" StaticTemplate.CategoryID = "static"
StaticTemplate.CoalitionID = Coalition or coalition.side.BLUE StaticTemplate.CoalitionID = Coalition or coalition.side.BLUE
StaticTemplate.CountryID = Country or country.id.GERMANY StaticTemplate.CountryID = Country or country.id.GERMANY
UTILS.PrintTableToLog(StaticTemplate) --UTILS.PrintTableToLog(StaticTemplate)
return StaticTemplate return StaticTemplate
end end
@@ -1324,7 +1388,7 @@ function DATABASE:GetCoalitionFromClientTemplate( ClientName )
if self.Templates.ClientsByName[ClientName] then if self.Templates.ClientsByName[ClientName] then
return self.Templates.ClientsByName[ClientName].CoalitionID return self.Templates.ClientsByName[ClientName].CoalitionID
end end
self:E("ERROR: Template does not exist for client "..tostring(ClientName)) self:T("WARNING: Template does not exist for client "..tostring(ClientName))
return nil return nil
end end
@@ -1336,7 +1400,7 @@ function DATABASE:GetCategoryFromClientTemplate( ClientName )
if self.Templates.ClientsByName[ClientName] then if self.Templates.ClientsByName[ClientName] then
return self.Templates.ClientsByName[ClientName].CategoryID return self.Templates.ClientsByName[ClientName].CategoryID
end end
self:E("ERROR: Template does not exist for client "..tostring(ClientName)) self:T("WARNING: Template does not exist for client "..tostring(ClientName))
return nil return nil
end end
@@ -1348,7 +1412,7 @@ function DATABASE:GetCountryFromClientTemplate( ClientName )
if self.Templates.ClientsByName[ClientName] then if self.Templates.ClientsByName[ClientName] then
return self.Templates.ClientsByName[ClientName].CountryID return self.Templates.ClientsByName[ClientName].CountryID
end end
self:E("ERROR: Template does not exist for client "..tostring(ClientName)) self:T("WARNING: Template does not exist for client "..tostring(ClientName))
return nil return nil
end end
@@ -1417,7 +1481,7 @@ function DATABASE:_RegisterDynamicGroup(Groupname)
-- Add unit. -- Add unit.
self:I(string.format("Register Unit: %s", tostring(DCSUnitName))) self:I(string.format("Register Unit: %s", tostring(DCSUnitName)))
self:AddUnit( DCSUnitName, true ) self:AddUnit( tostring(DCSUnitName), true )
end end
else else
@@ -1524,11 +1588,28 @@ end
-- @return #DATABASE self -- @return #DATABASE self
function DATABASE:_RegisterAirbase(airbase) function DATABASE:_RegisterAirbase(airbase)
local IsSyria = UTILS.GetDCSMap() == "Syria" and true or false
local countHSyria = 0
if airbase then if airbase then
-- Get the airbase name. -- Get the airbase name.
local DCSAirbaseName = airbase:getName() local DCSAirbaseName = airbase:getName()
-- DCS 2.9.8.1107 added 143 helipads all named H with the same object ID ..
if IsSyria and DCSAirbaseName == "H" and countHSyria > 0 then
--[[
local p = airbase:getPosition().p
local mgrs = COORDINATE:New(p.x,p.z,p.y):ToStringMGRS()
self:I("Airbase on Syria map named H @ "..mgrs)
countHSyria = countHSyria + 1
if countHSyria > 1 then return self end
--]]
return self
elseif IsSyria and DCSAirbaseName == "H" and countHSyria == 0 then
countHSyria = countHSyria + 1
end
-- This gave the incorrect value to be inserted into the airdromeID for DCS 2.5.6. Is fixed now. -- This gave the incorrect value to be inserted into the airdromeID for DCS 2.5.6. Is fixed now.
local airbaseID=airbase:getID() local airbaseID=airbase:getID()
@@ -1568,7 +1649,7 @@ end
-- @param #DATABASE self -- @param #DATABASE self
-- @param Core.Event#EVENTDATA Event -- @param Core.Event#EVENTDATA Event
function DATABASE:_EventOnBirth( Event ) function DATABASE:_EventOnBirth( Event )
self:F( { Event } ) self:T( { Event } )
if Event.IniDCSUnit then if Event.IniDCSUnit then
@@ -1577,6 +1658,16 @@ function DATABASE:_EventOnBirth( Event )
-- Add static object to DB. -- Add static object to DB.
self:AddStatic( Event.IniDCSUnitName ) self:AddStatic( Event.IniDCSUnitName )
elseif Event.IniObjectCategory == Object.Category.CARGO and string.match(Event.IniUnitName,".+|%d%d:%d%d|PKG%d+") then
-- Add dynamic cargo object to DB
local cargo = self:AddDynamicCargo(Event.IniDCSUnitName)
self:I(string.format("Adding dynamic cargo %s", tostring(Event.IniDCSUnitName)))
self:CreateEventNewDynamicCargo( cargo )
else else
if Event.IniObjectCategory == Object.Category.UNIT then if Event.IniObjectCategory == Object.Category.UNIT then
@@ -1614,7 +1705,7 @@ function DATABASE:_EventOnBirth( Event )
if PlayerName then if PlayerName then
-- Debug info. -- 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. -- Add client in case it does not exist already.
if client == nil or (client and client:CountPlayers() == 0) then if client == nil or (client and client:CountPlayers() == 0) then
@@ -1762,6 +1853,15 @@ function DATABASE:_EventOnPlayerEnterUnit( Event )
end end
end end
--- Handles the OnDynamicCargoRemoved event to clean the active dynamic cargo table.
-- @param #DATABASE self
-- @param Core.Event#EVENTDATA Event
function DATABASE:_EventOnDynamicCargoRemoved( Event )
self:T( { Event } )
if Event.IniDynamicCargoName then
self:DeleteDynamicCargo(Event.IniDynamicCargoName)
end
end
--- Handles the OnPlayerLeaveUnit event to clean the active players table. --- Handles the OnPlayerLeaveUnit event to clean the active players table.
-- @param #DATABASE self -- @param #DATABASE self
+120 -5
View File
@@ -194,6 +194,11 @@ world.event.S_EVENT_NEW_ZONE_GOAL = world.event.S_EVENT_MAX + 1004
world.event.S_EVENT_DELETE_ZONE_GOAL = world.event.S_EVENT_MAX + 1005 world.event.S_EVENT_DELETE_ZONE_GOAL = world.event.S_EVENT_MAX + 1005
world.event.S_EVENT_REMOVE_UNIT = world.event.S_EVENT_MAX + 1006 world.event.S_EVENT_REMOVE_UNIT = world.event.S_EVENT_MAX + 1006
world.event.S_EVENT_PLAYER_ENTER_AIRCRAFT = world.event.S_EVENT_MAX + 1007 world.event.S_EVENT_PLAYER_ENTER_AIRCRAFT = world.event.S_EVENT_MAX + 1007
-- dynamic cargo
world.event.S_EVENT_NEW_DYNAMIC_CARGO = world.event.S_EVENT_MAX + 1008
world.event.S_EVENT_DYNAMIC_CARGO_LOADED = world.event.S_EVENT_MAX + 1009
world.event.S_EVENT_DYNAMIC_CARGO_UNLOADED = world.event.S_EVENT_MAX + 1010
world.event.S_EVENT_DYNAMIC_CARGO_REMOVED = world.event.S_EVENT_MAX + 1011
--- The different types of events supported by MOOSE. --- The different types of events supported by MOOSE.
@@ -276,6 +281,11 @@ EVENTS = {
SimulationUnfreeze = world.event.S_EVENT_SIMULATION_UNFREEZE or -1, SimulationUnfreeze = world.event.S_EVENT_SIMULATION_UNFREEZE or -1,
HumanAircraftRepairStart = world.event.S_EVENT_HUMAN_AIRCRAFT_REPAIR_START or -1, HumanAircraftRepairStart = world.event.S_EVENT_HUMAN_AIRCRAFT_REPAIR_START or -1,
HumanAircraftRepairFinish = world.event.S_EVENT_HUMAN_AIRCRAFT_REPAIR_FINISH or -1, HumanAircraftRepairFinish = world.event.S_EVENT_HUMAN_AIRCRAFT_REPAIR_FINISH or -1,
-- dynamic cargo
NewDynamicCargo = world.event.S_EVENT_NEW_DYNAMIC_CARGO or -1,
DynamicCargoLoaded = world.event.S_EVENT_DYNAMIC_CARGO_LOADED or -1,
DynamicCargoUnloaded = world.event.S_EVENT_DYNAMIC_CARGO_UNLOADED or -1,
DynamicCargoRemoved = world.event.S_EVENT_DYNAMIC_CARGO_REMOVED or -1,
} }
@@ -334,6 +344,9 @@ EVENTS = {
-- --
-- @field Core.Zone#ZONE Zone The zone object. -- @field Core.Zone#ZONE Zone The zone object.
-- @field #string ZoneName The name of the zone. -- @field #string ZoneName The name of the zone.
--
-- @field Wrapper.DynamicCargo#DYNAMICCARGO IniDynamicCargo The dynamic cargo object.
-- @field #string IniDynamicCargoName The dynamic cargo unit name.
@@ -731,6 +744,31 @@ local _EVENTMETA = {
Event = "OnEventHumanAircraftRepairFinish", Event = "OnEventHumanAircraftRepairFinish",
Text = "S_EVENT_HUMAN_AIRCRAFT_REPAIR_FINISH" Text = "S_EVENT_HUMAN_AIRCRAFT_REPAIR_FINISH"
}, },
-- dynamic cargo
[EVENTS.NewDynamicCargo] = {
Order = 1,
Side = "I",
Event = "OnEventNewDynamicCargo",
Text = "S_EVENT_NEW_DYNAMIC_CARGO"
},
[EVENTS.DynamicCargoLoaded] = {
Order = 1,
Side = "I",
Event = "OnEventDynamicCargoLoaded",
Text = "S_EVENT_DYNAMIC_CARGO_LOADED"
},
[EVENTS.DynamicCargoUnloaded] = {
Order = 1,
Side = "I",
Event = "OnEventDynamicCargoUnloaded",
Text = "S_EVENT_DYNAMIC_CARGO_UNLOADED"
},
[EVENTS.DynamicCargoRemoved] = {
Order = 1,
Side = "I",
Event = "OnEventDynamicCargoRemoved",
Text = "S_EVENT_DYNAMIC_CARGO_REMOVED"
},
} }
@@ -1147,6 +1185,62 @@ do -- Event Creation
world.onEvent( Event ) world.onEvent( Event )
end end
--- Creation of a S_EVENT_NEW_DYNAMIC_CARGO event.
-- @param #EVENT self
-- @param Wrapper.DynamicCargo#DYNAMICCARGO DynamicCargo the dynamic cargo object
function EVENT:CreateEventNewDynamicCargo(DynamicCargo)
self:F({DynamicCargo})
local Event = {
id = EVENTS.NewDynamicCargo,
time = timer.getTime(),
dynamiccargo = DynamicCargo,
initiator = DynamicCargo:GetDCSObject(),
}
world.onEvent( Event )
end
--- Creation of a S_EVENT_DYNAMIC_CARGO_LOADED event.
-- @param #EVENT self
-- @param Wrapper.DynamicCargo#DYNAMICCARGO DynamicCargo the dynamic cargo object
function EVENT:CreateEventDynamicCargoLoaded(DynamicCargo)
self:F({DynamicCargo})
local Event = {
id = EVENTS.DynamicCargoLoaded,
time = timer.getTime(),
dynamiccargo = DynamicCargo,
initiator = DynamicCargo:GetDCSObject(),
}
world.onEvent( Event )
end
--- Creation of a S_EVENT_DYNAMIC_CARGO_UNLOADED event.
-- @param #EVENT self
-- @param Wrapper.DynamicCargo#DYNAMICCARGO DynamicCargo the dynamic cargo object
function EVENT:CreateEventDynamicCargoUnloaded(DynamicCargo)
self:F({DynamicCargo})
local Event = {
id = EVENTS.DynamicCargoUnloaded,
time = timer.getTime(),
dynamiccargo = DynamicCargo,
initiator = DynamicCargo:GetDCSObject(),
}
world.onEvent( Event )
end
--- Creation of a S_EVENT_DYNAMIC_CARGO_REMOVED event.
-- @param #EVENT self
-- @param Wrapper.DynamicCargo#DYNAMICCARGO DynamicCargo the dynamic cargo object
function EVENT:CreateEventDynamicCargoRemoved(DynamicCargo)
self:F({DynamicCargo})
local Event = {
id = EVENTS.DynamicCargoRemoved,
time = timer.getTime(),
dynamiccargo = DynamicCargo,
initiator = DynamicCargo:GetDCSObject(),
}
world.onEvent( Event )
end
end end
--- Main event function. --- Main event function.
@@ -1235,6 +1329,7 @@ function EVENT:onEvent( Event )
end end
Event.IniDCSGroupName = Event.IniUnit and Event.IniUnit.GroupName or "" Event.IniDCSGroupName = Event.IniUnit and Event.IniUnit.GroupName or ""
Event.IniGroupName=Event.IniDCSGroupName --At least set the group name because group might not exist any more
if Event.IniDCSGroup and Event.IniDCSGroup:isExist() then if Event.IniDCSGroup and Event.IniDCSGroup:isExist() then
Event.IniDCSGroupName = Event.IniDCSGroup:getName() Event.IniDCSGroupName = Event.IniDCSGroup:getName()
Event.IniGroup = GROUP:FindByName( Event.IniDCSGroupName ) Event.IniGroup = GROUP:FindByName( Event.IniDCSGroupName )
@@ -1261,7 +1356,13 @@ function EVENT:onEvent( Event )
Event.IniDCSUnit = Event.initiator Event.IniDCSUnit = Event.initiator
Event.IniDCSUnitName = Event.IniDCSUnit:getName() Event.IniDCSUnitName = Event.IniDCSUnit:getName()
Event.IniUnitName = Event.IniDCSUnitName Event.IniUnitName = Event.IniDCSUnitName
if string.match(Event.IniUnitName,".+|%d%d:%d%d|PKG%d+") then
Event.IniDynamicCargo = DYNAMICCARGO:FindByName(Event.IniUnitName)
Event.IniDynamicCargoName = Event.IniUnitName
Event.IniPlayerName = string.match(Event.IniUnitName,"^(.+)|%d%d:%d%d|PKG%d+")
else
Event.IniUnit = CARGO:FindByName( Event.IniDCSUnitName ) Event.IniUnit = CARGO:FindByName( Event.IniDCSUnitName )
end
Event.IniCoalition = Event.IniDCSUnit:getCoalition() Event.IniCoalition = Event.IniDCSUnit:getCoalition()
Event.IniCategory = Event.IniDCSUnit:getDesc().category Event.IniCategory = Event.IniDCSUnit:getDesc().category
Event.IniTypeName = Event.IniDCSUnit:getTypeName() Event.IniTypeName = Event.IniDCSUnit:getTypeName()
@@ -1271,11 +1372,12 @@ function EVENT:onEvent( Event )
-- Scenery -- Scenery
--- ---
Event.IniDCSUnit = Event.initiator Event.IniDCSUnit = Event.initiator
Event.IniDCSUnitName = Event.IniDCSUnit:getName() 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.IniUnitName = Event.IniDCSUnitName
Event.IniUnit = SCENERY:Register( Event.IniDCSUnitName, Event.initiator ) Event.IniUnit = SCENERY:Register( Event.IniDCSUnitName, Event.initiator )
Event.IniCategory = Event.IniDCSUnit:getDesc().category Event.IniCategory = (Event.IniDCSUnit and Event.IniDCSUnit.getDesc ) and Event.IniDCSUnit:getDesc().category
Event.IniTypeName = Event.initiator:isExist() and Event.IniDCSUnit:getTypeName() or "SCENERY" 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 elseif Event.IniObjectCategory == Object.Category.BASE then
--- ---
@@ -1373,16 +1475,18 @@ function EVENT:onEvent( Event )
-- SCENERY -- SCENERY
--- ---
Event.TgtDCSUnit = Event.target Event.TgtDCSUnit = Event.target
Event.TgtDCSUnitName = Event.TgtDCSUnit:getName() Event.TgtDCSUnitName = Event.TgtDCSUnit.getName and Event.TgtDCSUnit.getName() or nil
if Event.TgtDCSUnitName~=nil then
Event.TgtUnitName = Event.TgtDCSUnitName Event.TgtUnitName = Event.TgtDCSUnitName
Event.TgtUnit = SCENERY:Register( Event.TgtDCSUnitName, Event.target ) Event.TgtUnit = SCENERY:Register( Event.TgtDCSUnitName, Event.target )
Event.TgtCategory = Event.TgtDCSUnit:getDesc().category Event.TgtCategory = Event.TgtDCSUnit:getDesc().category
Event.TgtTypeName = Event.TgtDCSUnit:getTypeName() Event.TgtTypeName = Event.TgtDCSUnit:getTypeName()
end end
end end
end
-- Weapon. -- Weapon.
if Event.weapon and type(Event.weapon) == "table" then if Event.weapon and type(Event.weapon) == "table" and Event.weapon.isExist and Event.weapon:isExist() then
Event.Weapon = Event.weapon Event.Weapon = Event.weapon
Event.WeaponName = Event.weapon:isExist() and Event.weapon:getTypeName() or "Unknown Weapon" Event.WeaponName = Event.weapon:isExist() and Event.weapon:getTypeName() or "Unknown Weapon"
Event.WeaponUNIT = CLIENT:Find( Event.Weapon, '', true ) -- Sometimes, the weapon is a player unit! Event.WeaponUNIT = CLIENT:Find( Event.Weapon, '', true ) -- Sometimes, the weapon is a player unit!
@@ -1404,10 +1508,12 @@ function EVENT:onEvent( Event )
else else
if Event.place:isExist() and Object.getCategory(Event.place) ~= Object.Category.SCENERY then if Event.place:isExist() and Object.getCategory(Event.place) ~= Object.Category.SCENERY then
Event.Place=AIRBASE:Find(Event.place) Event.Place=AIRBASE:Find(Event.place)
if Event.Place then
Event.PlaceName=Event.Place:GetName() Event.PlaceName=Event.Place:GetName()
end end
end end
end end
end
-- Mark points. -- Mark points.
if Event.idx then if Event.idx then
@@ -1426,6 +1532,15 @@ function EVENT:onEvent( Event )
Event.CargoName = Event.cargo.Name Event.CargoName = Event.cargo.Name
end end
-- Dynamic cargo Object
if Event.dynamiccargo then
Event.IniDynamicCargo = Event.dynamiccargo
Event.IniDynamicCargoName = Event.IniDynamicCargo.StaticName
if Event.IniDynamicCargo.Owner or Event.IniUnitName then
Event.IniPlayerName = Event.IniDynamicCargo.Owner or string.match(Event.IniUnitName or "None|00:00|PKG00","^(.+)|%d%d:%d%d|PKG%d+")
end
end
-- Zone object. -- Zone object.
if Event.zone then if Event.zone then
Event.Zone = Event.zone Event.Zone = Event.zone
+2
View File
@@ -949,6 +949,7 @@ end
do -- FSM_CONTROLLABLE do -- FSM_CONTROLLABLE
---
-- @type FSM_CONTROLLABLE -- @type FSM_CONTROLLABLE
-- @field Wrapper.Controllable#CONTROLLABLE Controllable -- @field Wrapper.Controllable#CONTROLLABLE Controllable
-- @extends Core.Fsm#FSM -- @extends Core.Fsm#FSM
@@ -1082,6 +1083,7 @@ end
do -- FSM_PROCESS do -- FSM_PROCESS
---
-- @type FSM_PROCESS -- @type FSM_PROCESS
-- @field Tasking.Task#TASK Task -- @field Tasking.Task#TASK Task
-- @extends Core.Fsm#FSM_CONTROLLABLE -- @extends Core.Fsm#FSM_CONTROLLABLE
+34 -25
View File
@@ -50,7 +50,7 @@ MARKEROPS_BASE = {
ClassName = "MARKEROPS", ClassName = "MARKEROPS",
Tag = "mytag", Tag = "mytag",
Keywords = {}, Keywords = {},
version = "0.1.3", version = "0.1.4",
debug = false, debug = false,
Casesensitive = true, Casesensitive = true,
} }
@@ -108,26 +108,30 @@ function MARKEROPS_BASE:New(Tagname,Keywords,Casesensitive)
--- On after "MarkAdded" event. Triggered when a Marker is added to the F10 map. --- On after "MarkAdded" event. Triggered when a Marker is added to the F10 map.
-- @function [parent=#MARKEROPS_BASE] OnAfterMarkAdded -- @function [parent=#MARKEROPS_BASE] OnAfterMarkAdded
-- @param #MARKEROPS_BASE self -- @param #MARKEROPS_BASE self
-- @param #string From The From state -- @param #string From The From state.
-- @param #string Event The Event called -- @param #string Event The Event called.
-- @param #string To The To state -- @param #string To The To state.
-- @param #string Text The text on the marker -- @param #string Text The text on the marker.
-- @param #table Keywords Table of matching keywords found in the Event text -- @param #table Keywords Table of matching keywords found in the Event text.
-- @param Core.Point#COORDINATE Coord Coordinate of the marker. -- @param Core.Point#COORDINATE Coord Coordinate of the marker.
-- @param #number MarkerID Id of this marker -- @param #number MarkerID Id of this marker.
-- @param #number CoalitionNumber Coalition of the marker creator -- @param #number CoalitionNumber Coalition of the marker creator.
-- @param #string PlayerName Name of the player creating/changing the mark. nil if it cannot be obtained.
-- @param Core.Event#EVENTDATA EventData the event data table.
--- On after "MarkChanged" event. Triggered when a Marker is changed on the F10 map. --- On after "MarkChanged" event. Triggered when a Marker is changed on the F10 map.
-- @function [parent=#MARKEROPS_BASE] OnAfterMarkChanged -- @function [parent=#MARKEROPS_BASE] OnAfterMarkChanged
-- @param #MARKEROPS_BASE self -- @param #MARKEROPS_BASE self
-- @param #string From The From state -- @param #string From The From state.
-- @param #string Event The Event called -- @param #string Event The Event called.
-- @param #string To The To state -- @param #string To The To state.
-- @param #string Text The text on the marker -- @param #string Text The text on the marker.
-- @param #table Keywords Table of matching keywords found in the Event text -- @param #table Keywords Table of matching keywords found in the Event text.
-- @param Core.Point#COORDINATE Coord Coordinate of the marker. -- @param Core.Point#COORDINATE Coord Coordinate of the marker.
-- @param #number MarkerID Id of this marker -- @param #number MarkerID Id of this marker.
-- @param #number CoalitionNumber Coalition of the marker creator -- @param #number CoalitionNumber Coalition of the marker creator.
-- @param #string PlayerName Name of the player creating/changing the mark. nil if it cannot be obtained.
-- @param Core.Event#EVENTDATA EventData the event data table
--- On after "MarkDeleted" event. Triggered when a Marker is deleted from the F10 map. --- On after "MarkDeleted" event. Triggered when a Marker is deleted from the F10 map.
-- @function [parent=#MARKEROPS_BASE] OnAfterMarkDeleted -- @function [parent=#MARKEROPS_BASE] OnAfterMarkDeleted
@@ -150,14 +154,7 @@ function MARKEROPS_BASE:OnEventMark(Event)
self:E("Skipping onEvent. Event or Event.idx unknown.") self:E("Skipping onEvent. Event or Event.idx unknown.")
return true return true
end 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 local coalition = Event.MarkCoalition
-- decision -- decision
if Event.id==world.event.S_EVENT_MARK_ADDED then if Event.id==world.event.S_EVENT_MARK_ADDED then
@@ -166,8 +163,14 @@ function MARKEROPS_BASE:OnEventMark(Event)
local Eventtext = tostring(Event.text) local Eventtext = tostring(Event.text)
if Eventtext~=nil then if Eventtext~=nil then
if self:_MatchTag(Eventtext) then if self:_MatchTag(Eventtext) then
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) local matchtable = self:_MatchKeywords(Eventtext)
self:MarkAdded(Eventtext,matchtable,coord,Event.idx,coalition) self:MarkAdded(Eventtext,matchtable,coord,Event.idx,coalition,Event.PlayerName,Event)
end end
end end
elseif Event.id==world.event.S_EVENT_MARK_CHANGE then elseif Event.id==world.event.S_EVENT_MARK_CHANGE then
@@ -176,8 +179,14 @@ function MARKEROPS_BASE:OnEventMark(Event)
local Eventtext = tostring(Event.text) local Eventtext = tostring(Event.text)
if Eventtext~=nil then if Eventtext~=nil then
if self:_MatchTag(Eventtext) then if self:_MatchTag(Eventtext) then
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) local matchtable = self:_MatchKeywords(Eventtext)
self:MarkChanged(Eventtext,matchtable,coord,Event.idx,coalition) self:MarkChanged(Eventtext,matchtable,coord,Event.idx,coalition,Event.PlayerName,Event)
end end
end end
elseif Event.id==world.event.S_EVENT_MARK_REMOVED then elseif Event.id==world.event.S_EVENT_MARK_REMOVED then
+11 -1
View File
@@ -105,6 +105,7 @@ function MENU_INDEX:PrepareCoalition( CoalitionSide )
self.Coalition[CoalitionSide] = self.Coalition[CoalitionSide] or {} self.Coalition[CoalitionSide] = self.Coalition[CoalitionSide] or {}
self.Coalition[CoalitionSide].Menus = self.Coalition[CoalitionSide].Menus or {} self.Coalition[CoalitionSide].Menus = self.Coalition[CoalitionSide].Menus or {}
end end
--- ---
-- @param Wrapper.Group#GROUP Group -- @param Wrapper.Group#GROUP Group
function MENU_INDEX:PrepareGroup( Group ) function MENU_INDEX:PrepareGroup( Group )
@@ -118,9 +119,11 @@ end
function MENU_INDEX:HasMissionMenu( Path ) function MENU_INDEX:HasMissionMenu( Path )
return self.MenuMission.Menus[Path] return self.MenuMission.Menus[Path]
end end
function MENU_INDEX:SetMissionMenu( Path, Menu ) function MENU_INDEX:SetMissionMenu( Path, Menu )
self.MenuMission.Menus[Path] = Menu self.MenuMission.Menus[Path] = Menu
end end
function MENU_INDEX:ClearMissionMenu( Path ) function MENU_INDEX:ClearMissionMenu( Path )
self.MenuMission.Menus[Path] = nil self.MenuMission.Menus[Path] = nil
end end
@@ -128,9 +131,11 @@ end
function MENU_INDEX:HasCoalitionMenu( Coalition, Path ) function MENU_INDEX:HasCoalitionMenu( Coalition, Path )
return self.Coalition[Coalition].Menus[Path] return self.Coalition[Coalition].Menus[Path]
end end
function MENU_INDEX:SetCoalitionMenu( Coalition, Path, Menu ) function MENU_INDEX:SetCoalitionMenu( Coalition, Path, Menu )
self.Coalition[Coalition].Menus[Path] = Menu self.Coalition[Coalition].Menus[Path] = Menu
end end
function MENU_INDEX:ClearCoalitionMenu( Coalition, Path ) function MENU_INDEX:ClearCoalitionMenu( Coalition, Path )
self.Coalition[Coalition].Menus[Path] = nil self.Coalition[Coalition].Menus[Path] = nil
end end
@@ -138,19 +143,24 @@ end
function MENU_INDEX:HasGroupMenu( Group, Path ) function MENU_INDEX:HasGroupMenu( Group, Path )
if Group and Group:IsAlive() then if Group and Group:IsAlive() then
local MenuGroupName = Group:GetName() local MenuGroupName = Group:GetName()
if self.Group[MenuGroupName] and self.Group[MenuGroupName].Menus and self.Group[MenuGroupName].Menus[Path] then
return self.Group[MenuGroupName].Menus[Path] return self.Group[MenuGroupName].Menus[Path]
end end
end
return nil return nil
end end
function MENU_INDEX:SetGroupMenu( Group, Path, Menu ) function MENU_INDEX:SetGroupMenu( Group, Path, Menu )
local MenuGroupName = Group:GetName() local MenuGroupName = Group:GetName()
Group:F({MenuGroupName=MenuGroupName,Path=Path}) --Group:F({MenuGroupName=MenuGroupName,Path=Path})
self.Group[MenuGroupName].Menus[Path] = Menu self.Group[MenuGroupName].Menus[Path] = Menu
end end
function MENU_INDEX:ClearGroupMenu( Group, Path ) function MENU_INDEX:ClearGroupMenu( Group, Path )
local MenuGroupName = Group:GetName() local MenuGroupName = Group:GetName()
self.Group[MenuGroupName].Menus[Path] = nil self.Group[MenuGroupName].Menus[Path] = nil
end end
function MENU_INDEX:Refresh( Group ) function MENU_INDEX:Refresh( Group )
for MenuID, Menu in pairs( self.MenuMission.Menus ) do for MenuID, Menu in pairs( self.MenuMission.Menus ) do
Menu:Refresh() Menu:Refresh()
+29 -22
View File
@@ -75,11 +75,11 @@ MESSAGE.Type = {
--- Creates a new MESSAGE object. Note that these MESSAGE objects are not yet displayed on the display panel. You must use the functions @{#MESSAGE.ToClient} or @{#MESSAGE.ToCoalition} or @{#MESSAGE.ToAll} to send these Messages to the respective recipients. --- Creates a new MESSAGE object. Note that these MESSAGE objects are not yet displayed on the display panel. You must use the functions @{#MESSAGE.ToClient} or @{#MESSAGE.ToCoalition} or @{#MESSAGE.ToAll} to send these Messages to the respective recipients.
-- @param self -- @param self
-- @param #string MessageText is the text of the Message. -- @param #string Text is the text of the Message.
-- @param #number MessageDuration is a number in seconds of how long the MESSAGE should be shown on the display panel. -- @param #number Duration Duration in seconds how long the message text is shown.
-- @param #string MessageCategory (optional) is a string expressing the "category" of the Message. The category will be shown as the first text in the message followed by a ": ". -- @param #string Category (Optional) String expressing the "category" of the Message. The category will be shown as the first text in the message followed by a ": ".
-- @param #boolean ClearScreen (optional) Clear all previous messages if true. -- @param #boolean ClearScreen (optional) Clear all previous messages if true.
-- @return #MESSAGE -- @return #MESSAGE self
-- @usage -- @usage
-- --
-- -- Create a series of new Messages. -- -- Create a series of new Messages.
@@ -92,18 +92,20 @@ MESSAGE.Type = {
-- MessageClient1 = MESSAGE:New( "Congratulations, you've just hit a target", 25, "Score" ) -- MessageClient1 = MESSAGE:New( "Congratulations, you've just hit a target", 25, "Score" )
-- MessageClient2 = MESSAGE:New( "Congratulations, you've just killed a target", 25, "Score") -- MessageClient2 = MESSAGE:New( "Congratulations, you've just killed a target", 25, "Score")
-- --
function MESSAGE:New( MessageText, MessageDuration, MessageCategory, ClearScreen ) function MESSAGE:New( Text, Duration, Category, ClearScreen )
local self = BASE:Inherit( self, BASE:New() ) local self = BASE:Inherit( self, BASE:New() )
self:F( { MessageText, MessageDuration, MessageCategory } )
self:F( { Text, Duration, Category } )
self.MessageType = nil self.MessageType = nil
-- When no MessageCategory is given, we don't show it as a title... -- When no MessageCategory is given, we don't show it as a title...
if MessageCategory and MessageCategory ~= "" then if Category and Category ~= "" then
if MessageCategory:sub( -1 ) ~= "\n" then if Category:sub( -1 ) ~= "\n" then
self.MessageCategory = MessageCategory .. ": " self.MessageCategory = Category .. ": "
else else
self.MessageCategory = MessageCategory:sub( 1, -2 ) .. ":\n" self.MessageCategory = Category:sub( 1, -2 ) .. ":\n"
end end
else else
self.MessageCategory = "" self.MessageCategory = ""
@@ -114,9 +116,9 @@ function MESSAGE:New( MessageText, MessageDuration, MessageCategory, ClearScreen
self.ClearScreen = ClearScreen self.ClearScreen = ClearScreen
end end
self.MessageDuration = MessageDuration or 5 self.MessageDuration = Duration or 5
self.MessageTime = timer.getTime() self.MessageTime = timer.getTime()
self.MessageText = MessageText:gsub( "^\n", "", 1 ):gsub( "\n$", "", 1 ) self.MessageText = Text:gsub( "^\n", "", 1 ):gsub( "\n$", "", 1 )
self.MessageSent = false self.MessageSent = false
self.MessageGroup = false self.MessageGroup = false
@@ -204,7 +206,7 @@ end
function MESSAGE:ToGroup( Group, Settings ) function MESSAGE:ToGroup( Group, Settings )
self:F( Group.GroupName ) self:F( Group.GroupName )
if Group then if Group and Group:IsAlive() then
if self.MessageType then if self.MessageType then
local Settings = Settings or (Group and _DATABASE:GetPlayerSettings( Group:GetPlayerName() )) or _SETTINGS -- Core.Settings#SETTINGS local Settings = Settings or (Group and _DATABASE:GetPlayerSettings( Group:GetPlayerName() )) or _SETTINGS -- Core.Settings#SETTINGS
@@ -229,7 +231,7 @@ end
function MESSAGE:ToUnit( Unit, Settings ) function MESSAGE:ToUnit( Unit, Settings )
self:F( Unit.IdentifiableName ) self:F( Unit.IdentifiableName )
if Unit then if Unit and Unit:IsAlive() then
if self.MessageType then if self.MessageType then
local Settings = Settings or ( Unit and _DATABASE:GetPlayerSettings( Unit:GetPlayerName() ) ) or _SETTINGS -- Core.Settings#SETTINGS local Settings = Settings or ( Unit and _DATABASE:GetPlayerSettings( Unit:GetPlayerName() ) ) or _SETTINGS -- Core.Settings#SETTINGS
@@ -450,7 +452,7 @@ end
_MESSAGESRS = {} _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. --- 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 #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 #string PathToCredentials (optional) Path to credentials file for Google.
-- @param #number Frequency Frequency in MHz. Can also be given as a #table of frequencies. -- @param #number Frequency Frequency in MHz. Can also be given as a #table of frequencies.
@@ -462,16 +464,17 @@ _MESSAGESRS = {}
-- @param #number Volume (optional) Volume, can be between 0.0 and 1.0 (loudest). -- @param #number Volume (optional) Volume, can be between 0.0 and 1.0 (loudest).
-- @param #string Label (optional) Label, defaults to "MESSAGE" or the Message Category set. -- @param #string Label (optional) Label, defaults to "MESSAGE" or the Message Category set.
-- @param Core.Point#COORDINATE Coordinate (optional) Coordinate this messages originates from. -- @param Core.Point#COORDINATE Coordinate (optional) Coordinate this messages originates from.
-- @param #string Backend (optional) Backend to be used, can be MSRS.Backend.SRSEXE or MSRS.Backend.GRPC
-- @usage -- @usage
-- -- Mind the dot here, not using the colon this time around! -- -- Mind the dot here, not using the colon this time around!
-- -- Needed once only -- -- 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 -- -- later on in your code
-- MESSAGE:New("Test message!",15,"SPAWN"):ToSRS() -- MESSAGE:New("Test message!",15,"SPAWN"):ToSRS()
-- --
function MESSAGE.SetMSRS(PathToSRS,Port,PathToCredentials,Frequency,Modulation,Gender,Culture,Voice,Coalition,Volume,Label,Coordinate) 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.frequency = Frequency or MSRS.frequencies or 243
_MESSAGESRS.modulation = Modulation or MSRS.modulations or radio.modulation.AM _MESSAGESRS.modulation = Modulation or MSRS.modulations or radio.modulation.AM
@@ -487,6 +490,10 @@ function MESSAGE.SetMSRS(PathToSRS,Port,PathToCredentials,Frequency,Modulation,G
_MESSAGESRS.MSRS:SetCoordinate(Coordinate) _MESSAGESRS.MSRS:SetCoordinate(Coordinate)
end end
if Backend then
_MESSAGESRS.MSRS:SetBackend(Backend)
end
_MESSAGESRS.Culture = Culture or MSRS.culture or "en-GB" _MESSAGESRS.Culture = Culture or MSRS.culture or "en-GB"
_MESSAGESRS.MSRS:SetCulture(Culture) _MESSAGESRS.MSRS:SetCulture(Culture)
@@ -528,7 +535,7 @@ end
-- @usage -- @usage
-- -- Mind the dot here, not using the colon this time around! -- -- Mind the dot here, not using the colon this time around!
-- -- Needed once only -- -- 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 -- -- later on in your code
-- MESSAGE:New("Test message!",15,"SPAWN"):ToSRS() -- MESSAGE:New("Test message!",15,"SPAWN"):ToSRS()
-- --
@@ -560,7 +567,7 @@ end
-- @usage -- @usage
-- -- Mind the dot here, not using the colon this time around! -- -- Mind the dot here, not using the colon this time around!
-- -- Needed once only -- -- 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 -- -- later on in your code
-- MESSAGE:New("Test message!",15,"SPAWN"):ToSRSBlue() -- MESSAGE:New("Test message!",15,"SPAWN"):ToSRSBlue()
-- --
@@ -582,7 +589,7 @@ end
-- @usage -- @usage
-- -- Mind the dot here, not using the colon this time around! -- -- Mind the dot here, not using the colon this time around!
-- -- Needed once only -- -- 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 -- -- later on in your code
-- MESSAGE:New("Test message!",15,"SPAWN"):ToSRSRed() -- MESSAGE:New("Test message!",15,"SPAWN"):ToSRSRed()
-- --
@@ -604,7 +611,7 @@ end
-- @usage -- @usage
-- -- Mind the dot here, not using the colon this time around! -- -- Mind the dot here, not using the colon this time around!
-- -- Needed once only -- -- 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 -- -- later on in your code
-- MESSAGE:New("Test message!",15,"SPAWN"):ToSRSAll() -- MESSAGE:New("Test message!",15,"SPAWN"):ToSRSAll()
-- --
File diff suppressed because it is too large Load Diff
@@ -175,7 +175,7 @@ function SCHEDULEDISPATCHER:AddSchedule( Scheduler, ScheduleFunction, ScheduleAr
local Name = Info.name or "?" local Name = Info.name or "?"
local ErrorHandler = function( errmsg ) local ErrorHandler = function( errmsg )
env.info( "Error in timer function: " .. errmsg ) env.info( "Error in timer function: " .. errmsg or "" )
if BASE.Debug ~= nil then if BASE.Debug ~= nil then
env.info( BASE.Debug.traceback() ) env.info( BASE.Debug.traceback() )
end end
@@ -326,7 +326,7 @@ function SCHEDULEDISPATCHER:Stop( Scheduler, CallID )
local Schedule = self.Schedule[Scheduler][CallID] -- #SCHEDULEDISPATCHER.ScheduleData 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. -- 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 ) ) ) 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
+13 -13
View File
@@ -494,7 +494,7 @@ do -- SETTINGS
return (self.A2ASystem and self.A2ASystem == "MGRS") or (not self.A2ASystem and _SETTINGS:IsA2A_MGRS()) return (self.A2ASystem and self.A2ASystem == "MGRS") or (not self.A2ASystem and _SETTINGS:IsA2A_MGRS())
end end
-- @param #SETTINGS self --- @param #SETTINGS self
-- @param Wrapper.Group#GROUP MenuGroup Group for which to add menus. -- @param Wrapper.Group#GROUP MenuGroup Group for which to add menus.
-- @param #table RootMenu Root menu table -- @param #table RootMenu Root menu table
-- @return #SETTINGS -- @return #SETTINGS
@@ -948,49 +948,49 @@ do -- SETTINGS
return self return self
end end
-- @param #SETTINGS self --- @param #SETTINGS self
function SETTINGS:A2GMenuSystem( MenuGroup, RootMenu, A2GSystem ) function SETTINGS:A2GMenuSystem( MenuGroup, RootMenu, A2GSystem )
self.A2GSystem = A2GSystem self.A2GSystem = A2GSystem
MESSAGE:New( string.format( "Settings: Default A2G coordinate system set to %s for all players!", A2GSystem ), 5 ):ToAll() MESSAGE:New( string.format( "Settings: Default A2G coordinate system set to %s for all players!", A2GSystem ), 5 ):ToAll()
self:SetSystemMenu( MenuGroup, RootMenu ) self:SetSystemMenu( MenuGroup, RootMenu )
end end
-- @param #SETTINGS self --- @param #SETTINGS self
function SETTINGS:A2AMenuSystem( MenuGroup, RootMenu, A2ASystem ) function SETTINGS:A2AMenuSystem( MenuGroup, RootMenu, A2ASystem )
self.A2ASystem = A2ASystem self.A2ASystem = A2ASystem
MESSAGE:New( string.format( "Settings: Default A2A coordinate system set to %s for all players!", A2ASystem ), 5 ):ToAll() MESSAGE:New( string.format( "Settings: Default A2A coordinate system set to %s for all players!", A2ASystem ), 5 ):ToAll()
self:SetSystemMenu( MenuGroup, RootMenu ) self:SetSystemMenu( MenuGroup, RootMenu )
end end
-- @param #SETTINGS self --- @param #SETTINGS self
function SETTINGS:MenuLL_DDM_Accuracy( MenuGroup, RootMenu, LL_Accuracy ) function SETTINGS:MenuLL_DDM_Accuracy( MenuGroup, RootMenu, LL_Accuracy )
self.LL_Accuracy = LL_Accuracy self.LL_Accuracy = LL_Accuracy
MESSAGE:New( string.format( "Settings: Default LL accuracy set to %s for all players!", LL_Accuracy ), 5 ):ToAll() MESSAGE:New( string.format( "Settings: Default LL accuracy set to %s for all players!", LL_Accuracy ), 5 ):ToAll()
self:SetSystemMenu( MenuGroup, RootMenu ) self:SetSystemMenu( MenuGroup, RootMenu )
end end
-- @param #SETTINGS self --- @param #SETTINGS self
function SETTINGS:MenuMGRS_Accuracy( MenuGroup, RootMenu, MGRS_Accuracy ) function SETTINGS:MenuMGRS_Accuracy( MenuGroup, RootMenu, MGRS_Accuracy )
self.MGRS_Accuracy = MGRS_Accuracy self.MGRS_Accuracy = MGRS_Accuracy
MESSAGE:New( string.format( "Settings: Default MGRS accuracy set to %s for all players!", MGRS_Accuracy ), 5 ):ToAll() MESSAGE:New( string.format( "Settings: Default MGRS accuracy set to %s for all players!", MGRS_Accuracy ), 5 ):ToAll()
self:SetSystemMenu( MenuGroup, RootMenu ) self:SetSystemMenu( MenuGroup, RootMenu )
end end
-- @param #SETTINGS self --- @param #SETTINGS self
function SETTINGS:MenuMWSystem( MenuGroup, RootMenu, MW ) function SETTINGS:MenuMWSystem( MenuGroup, RootMenu, MW )
self.Metric = MW self.Metric = MW
MESSAGE:New( string.format( "Settings: Default measurement format set to %s for all players!", MW and "Metric" or "Imperial" ), 5 ):ToAll() MESSAGE:New( string.format( "Settings: Default measurement format set to %s for all players!", MW and "Metric" or "Imperial" ), 5 ):ToAll()
self:SetSystemMenu( MenuGroup, RootMenu ) self:SetSystemMenu( MenuGroup, RootMenu )
end end
-- @param #SETTINGS self --- @param #SETTINGS self
function SETTINGS:MenuMessageTimingsSystem( MenuGroup, RootMenu, MessageType, MessageTime ) function SETTINGS:MenuMessageTimingsSystem( MenuGroup, RootMenu, MessageType, MessageTime )
self:SetMessageTime( MessageType, MessageTime ) self:SetMessageTime( MessageType, MessageTime )
MESSAGE:New( string.format( "Settings: Default message time set for %s to %d.", MessageType, MessageTime ), 5 ):ToAll() MESSAGE:New( string.format( "Settings: Default message time set for %s to %d.", MessageType, MessageTime ), 5 ):ToAll()
end end
do do
-- @param #SETTINGS self --- @param #SETTINGS self
function SETTINGS:MenuGroupA2GSystem( PlayerUnit, PlayerGroup, PlayerName, A2GSystem ) function SETTINGS:MenuGroupA2GSystem( PlayerUnit, PlayerGroup, PlayerName, A2GSystem )
--BASE:E( {PlayerUnit:GetName(), A2GSystem } ) --BASE:E( {PlayerUnit:GetName(), A2GSystem } )
self.A2GSystem = A2GSystem self.A2GSystem = A2GSystem
@@ -1001,7 +1001,7 @@ do -- SETTINGS
end end
end end
-- @param #SETTINGS self --- @param #SETTINGS self
function SETTINGS:MenuGroupA2ASystem( PlayerUnit, PlayerGroup, PlayerName, A2ASystem ) function SETTINGS:MenuGroupA2ASystem( PlayerUnit, PlayerGroup, PlayerName, A2ASystem )
self.A2ASystem = A2ASystem self.A2ASystem = A2ASystem
MESSAGE:New( string.format( "Settings: A2A format set to %s for player %s.", A2ASystem, PlayerName ), 5 ):ToGroup( PlayerGroup ) MESSAGE:New( string.format( "Settings: A2A format set to %s for player %s.", A2ASystem, PlayerName ), 5 ):ToGroup( PlayerGroup )
@@ -1011,7 +1011,7 @@ do -- SETTINGS
end end
end end
-- @param #SETTINGS self --- @param #SETTINGS self
function SETTINGS:MenuGroupLL_DDM_AccuracySystem( PlayerUnit, PlayerGroup, PlayerName, LL_Accuracy ) function SETTINGS:MenuGroupLL_DDM_AccuracySystem( PlayerUnit, PlayerGroup, PlayerName, LL_Accuracy )
self.LL_Accuracy = LL_Accuracy self.LL_Accuracy = LL_Accuracy
MESSAGE:New( string.format( "Settings: LL format accuracy set to %d decimal places for player %s.", LL_Accuracy, PlayerName ), 5 ):ToGroup( PlayerGroup ) MESSAGE:New( string.format( "Settings: LL format accuracy set to %d decimal places for player %s.", LL_Accuracy, PlayerName ), 5 ):ToGroup( PlayerGroup )
@@ -1021,7 +1021,7 @@ do -- SETTINGS
end end
end end
-- @param #SETTINGS self --- @param #SETTINGS self
function SETTINGS:MenuGroupMGRS_AccuracySystem( PlayerUnit, PlayerGroup, PlayerName, MGRS_Accuracy ) function SETTINGS:MenuGroupMGRS_AccuracySystem( PlayerUnit, PlayerGroup, PlayerName, MGRS_Accuracy )
self.MGRS_Accuracy = MGRS_Accuracy self.MGRS_Accuracy = MGRS_Accuracy
MESSAGE:New( string.format( "Settings: MGRS format accuracy set to %d for player %s.", MGRS_Accuracy, PlayerName ), 5 ):ToGroup( PlayerGroup ) MESSAGE:New( string.format( "Settings: MGRS format accuracy set to %d for player %s.", MGRS_Accuracy, PlayerName ), 5 ):ToGroup( PlayerGroup )
@@ -1031,7 +1031,7 @@ do -- SETTINGS
end end
end end
-- @param #SETTINGS self --- @param #SETTINGS self
function SETTINGS:MenuGroupMWSystem( PlayerUnit, PlayerGroup, PlayerName, MW ) function SETTINGS:MenuGroupMWSystem( PlayerUnit, PlayerGroup, PlayerName, MW )
self.Metric = MW self.Metric = MW
MESSAGE:New( string.format( "Settings: Measurement format set to %s for player %s.", MW and "Metric" or "Imperial", PlayerName ), 5 ):ToGroup( PlayerGroup ) MESSAGE:New( string.format( "Settings: Measurement format set to %s for player %s.", MW and "Metric" or "Imperial", PlayerName ), 5 ):ToGroup( PlayerGroup )
@@ -1041,7 +1041,7 @@ do -- SETTINGS
end end
end end
-- @param #SETTINGS self --- @param #SETTINGS self
function SETTINGS:MenuGroupMessageTimingsSystem( PlayerUnit, PlayerGroup, PlayerName, MessageType, MessageTime ) function SETTINGS:MenuGroupMessageTimingsSystem( PlayerUnit, PlayerGroup, PlayerName, MessageType, MessageTime )
self:SetMessageTime( MessageType, MessageTime ) self:SetMessageTime( MessageType, MessageTime )
MESSAGE:New( string.format( "Settings: Default message time set for %s to %d.", MessageType, MessageTime ), 5 ):ToGroup( PlayerGroup ) MESSAGE:New( string.format( "Settings: Default message time set for %s to %d.", MessageType, MessageTime ), 5 ):ToGroup( PlayerGroup )
File diff suppressed because it is too large Load Diff
+70 -12
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.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.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**! -- * @{#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 -- @field #SPAWNSTATIC SPAWNSTATIC
@@ -149,6 +149,7 @@ function SPAWNSTATIC:NewFromStatic(SpawnTemplateName, SpawnCountryID)
self.CategoryID = CategoryID self.CategoryID = CategoryID
self.CoalitionID = CoalitionID self.CoalitionID = CoalitionID
self.SpawnIndex = 0 self.SpawnIndex = 0
self.StaticCopyFrom = SpawnTemplateName
else else
error( "SPAWNSTATIC:New: There is no static declared in the mission editor with SpawnTemplatePrefix = '" .. tostring(SpawnTemplateName) .. "'" ) error( "SPAWNSTATIC:New: There is no static declared in the mission editor with SpawnTemplatePrefix = '" .. tostring(SpawnTemplateName) .. "'" )
end end
@@ -302,12 +303,16 @@ end
-- @param #number CallsignID Callsign ID. Default 1 (="London"). -- @param #number CallsignID Callsign ID. Default 1 (="London").
-- @param #number Frequency Frequency in MHz. Default 127.5 MHz. -- @param #number Frequency Frequency in MHz. Default 127.5 MHz.
-- @param #number Modulation Modulation 0=AM, 1=FM. -- @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 -- @return #SPAWNSTATIC self
function SPAWNSTATIC:InitFARP(CallsignID, Frequency, Modulation) function SPAWNSTATIC:InitFARP(CallsignID, Frequency, Modulation, DynamicSpawns,DynamicHotStarts)
self.InitFarp=true self.InitFarp=true
self.InitFarpCallsignID=CallsignID or 1 self.InitFarpCallsignID=CallsignID or 1
self.InitFarpFreq=Frequency or 127.5 self.InitFarpFreq=Frequency or 127.5
self.InitFarpModu=Modulation or 0 self.InitFarpModu=Modulation or 0
self.InitFarpDynamicSpawns = DynamicSpawns
self.InitFarpDynamicHotStarts = (DynamicSpawns == true and DynamicHotStarts == true) and true or nil
return self return self
end end
@@ -373,6 +378,20 @@ function SPAWNSTATIC:InitLinkToUnit(Unit, OffsetX, OffsetY, OffsetAngle)
return self return self
end 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. --- 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 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. -- The first parameter of the SpawnFunction is the @{Wrapper.Static#STATIC} that was spawned.
@@ -411,9 +430,9 @@ function SPAWNSTATIC:Spawn(Heading, NewName)
end end
--- Creates a new @{Wrapper.Static} from a POINT_VEC2. --- Creates a new @{Wrapper.Static} from a COORDINATE.
-- @param #SPAWNSTATIC self -- @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 #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. -- @param #string NewName (Optional) The name of the new static.
-- @return Wrapper.Static#STATIC The static spawned. -- @return Wrapper.Static#STATIC The static spawned.
@@ -459,7 +478,8 @@ end
function SPAWNSTATIC:SpawnFromZone(Zone, Heading, NewName) function SPAWNSTATIC:SpawnFromZone(Zone, Heading, NewName)
-- Spawn the new static at the center of the zone. -- 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 return Static
end end
@@ -535,15 +555,17 @@ function SPAWNSTATIC:_SpawnStatic(Template, CountryID)
-- Name of the spawned static. -- Name of the spawned static.
Template.name = self.InitStaticName or string.format("%s#%05d", self.SpawnTemplatePrefix, self.SpawnIndex) Template.name = self.InitStaticName or string.format("%s#%05d", self.SpawnTemplatePrefix, self.SpawnIndex)
-- Add and register the new static.
local mystatic=_DATABASE:AddStatic(Template.name)
-- Debug output.
self:T(Template)
-- Add static to the game. -- Add static to the game.
local Static=nil --DCS#StaticObject 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 if self.InitFarp then
local TemplateGroup={} local TemplateGroup={}
@@ -556,12 +578,20 @@ function SPAWNSTATIC:_SpawnStatic(Template, CountryID)
TemplateGroup.y=Template.y TemplateGroup.y=Template.y
TemplateGroup.name=Template.name 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("Spawning FARP")
self:T({Template=Template}) self:T({Template=Template})
self:T({TemplateGroup=TemplateGroup}) self:T({TemplateGroup=TemplateGroup})
-- ED's dirty way to spawn FARPS. -- ED's dirty way to spawn FARPS.
Static=coalition.addGroup(CountryID, -1, TemplateGroup) Static=coalition.addGroup(CountryID, -1, TemplateGroup)
--Static=coalition.addStaticObject(CountryID, Template)
-- Currently DCS 2.8 does not trigger birth events if FARPS are spawned! -- 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 -- We create such an event. The airbase is registered in Core.Event
@@ -577,13 +607,41 @@ function SPAWNSTATIC:_SpawnStatic(Template, CountryID)
self:T("Spawning Static") self:T("Spawning Static")
self:T2({Template=Template}) self:T2({Template=Template})
Static=coalition.addStaticObject(CountryID, Template) Static=coalition.addStaticObject(CountryID, Template)
if Static then
self:T(string.format("Succesfully spawned static object \"%s\" ID=%d", Static:getName(), Static:getID()))
--[[
local static=StaticObject.getByName(Static:getName())
if static then
env.info(string.format("FF got static from StaticObject.getByName"))
else
env.error(string.format("FF error did NOT get static from StaticObject.getByName"))
end ]]
else
self:E(string.format("ERROR: DCS static object \"%s\" is nil!", tostring(Template.name)))
end end
end
-- Add and register the new static.
local mystatic=_DATABASE:AddStatic(Template.name)
-- If there is a SpawnFunction hook defined, call it. -- If there is a SpawnFunction hook defined, call it.
if self.SpawnFunctionHook then if self.SpawnFunctionHook then
-- delay calling this for .3 seconds so that it hopefully comes after the BIRTH event of the group. -- 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)) self:ScheduleOnce(0.3, self.SpawnFunctionHook, mystatic, unpack(self.SpawnFunctionArguments))
end 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 return mystatic
end end
File diff suppressed because it is too large Load Diff
@@ -107,7 +107,7 @@ function ZONE_DETECTION:SmokeZone( SmokeColor, Points, AddHeight, AngleOffset )
local Radial = ( Angle + AngleOffset ) * RadialBase / 360 local Radial = ( Angle + AngleOffset ) * RadialBase / 360
Point.x = Vec2.x + math.cos( Radial ) * self:GetRadius() Point.x = Vec2.x + math.cos( Radial ) * self:GetRadius()
Point.y = Vec2.y + math.sin( Radial ) * self:GetRadius() Point.y = Vec2.y + math.sin( Radial ) * self:GetRadius()
POINT_VEC2:New( Point.x, Point.y, AddHeight ):Smoke( SmokeColor ) COORDINATE:New( Point.x, AddHeight, Point.y):Smoke( SmokeColor )
end end
return self return self
@@ -138,7 +138,7 @@ function ZONE_DETECTION:FlareZone( FlareColor, Points, Azimuth, AddHeight )
local Radial = Angle * RadialBase / 360 local Radial = Angle * RadialBase / 360
Point.x = Vec2.x + math.cos( Radial ) * self:GetRadius() Point.x = Vec2.x + math.cos( Radial ) * self:GetRadius()
Point.y = Vec2.y + math.sin( Radial ) * self:GetRadius() Point.y = Vec2.y + math.sin( Radial ) * self:GetRadius()
POINT_VEC2:New( Point.x, Point.y, AddHeight ):Flare( FlareColor, Azimuth ) COORDINATE:New( Point.x, AddHeight, Point.y ):Flare( FlareColor, Azimuth )
end end
return self return self
@@ -202,4 +202,3 @@ function ZONE_DETECTION:IsVec3InZone( Vec3 )
return InZone return InZone
end end
+53 -14
View File
@@ -14,6 +14,7 @@ do -- world
-- @field #world.event event [https://wiki.hoggitworld.com/view/DCS_enum_world](https://wiki.hoggitworld.com/view/DCS_enum_world) -- @field #world.event event [https://wiki.hoggitworld.com/view/DCS_enum_world](https://wiki.hoggitworld.com/view/DCS_enum_world)
-- @field #world.BirthPlace BirthPlace The birthplace enumerator is used to define where an aircraft or helicopter has spawned in association with birth events. -- @field #world.BirthPlace BirthPlace The birthplace enumerator is used to define where an aircraft or helicopter has spawned in association with birth events.
-- @field #world.VolumeType VolumeType The volumeType enumerator defines the types of 3d geometery used within the [world.searchObjects](https://wiki.hoggitworld.com/view/DCS_func_searchObjects) function. -- @field #world.VolumeType VolumeType The volumeType enumerator defines the types of 3d geometery used within the [world.searchObjects](https://wiki.hoggitworld.com/view/DCS_func_searchObjects) function.
-- @field #world.weather weather Weather functions for fog etc.
--- The world singleton contains functions centered around two different but extremely useful functions. --- The world singleton contains functions centered around two different but extremely useful functions.
-- * Events and event handlers are all governed within world. -- * Events and event handlers are all governed within world.
@@ -133,6 +134,36 @@ do -- world
-- @param #number coalitionId The coalition side number ID. Default is all airbases are returned. -- @param #number coalitionId The coalition side number ID. Default is all airbases are returned.
-- @return #table Table of DCS airbase objects. -- @return #table Table of DCS airbase objects.
--- Weather functions.
-- @type world.weather
--- Fog animation data structure.
-- @type world.FogAnimation
-- @field #number time
-- @field #number visibility
-- @field #number thickness
--- Returns the current fog thickness.
-- @function [parent=#world.weather] getFogThickness Returns the fog thickness.
-- @return #number Fog thickness in meters. If there is no fog, zero is returned.
--- Sets the fog thickness instantly. Any current fog animation is discarded.
-- @function [parent=#world.weather] setFogThickness
-- @param #number thickness Fog thickness in meters. Set to zero to disable fog.
--- Returns the current fog visibility distance.
-- @function [parent=#world.weather] getFogVisibilityDistance Returns the current maximum visibility distance in meters. Returns zero if fog is not present.
--- Instantly sets the maximum visibility distance of fog at sea level when looking at the horizon. Any current fog animation is discarded. Set zero to disable the fog.
-- @function [parent=#world.weather] setFogVisibilityDistance
-- @param #number visibility Max fog visibility in meters. Set to zero to disable fog.
--- Sets fog animation keys. Time is set in seconds and relative to the current simulation time, where time=0 is the current moment.
-- Time must be increasing. Previous animation is always discarded despite the data being correct.
-- @function [parent=#world.weather] setFogAnimation
-- @param #world.FogAnimation animation List of fog animations
end -- world end -- world
@@ -167,7 +198,7 @@ end -- env
do -- radio do -- radio
---@type radio --@type radio
-- @field #radio.modulation modulation -- @field #radio.modulation modulation
--- ---
@@ -407,7 +438,7 @@ do -- coalition
-- @param #table groupData Group data table. -- @param #table groupData Group data table.
-- @return DCS#Group The spawned Group object. -- @return DCS#Group The spawned Group object.
--- Dynamically spawns a static object. See [hoggit](https://wiki.hoggitworld.com/view/DCS_func_addGroup) --- Dynamically spawns a static object. See [hoggit](https://wiki.hoggitworld.com/view/DCS_func_addStaticObject)
-- @function [parent=#coalition] addStaticObject -- @function [parent=#coalition] addStaticObject
-- @param #number countryId Id of the country. -- @param #number countryId Id of the country.
-- @param #table groupData Group data table. -- @param #table groupData Group data table.
@@ -420,6 +451,7 @@ end -- coalition
do -- Types do -- Types
--- Descriptors.
-- @type Desc -- @type Desc
-- @field #number speedMax0 Max speed in meters/second at zero altitude. -- @field #number speedMax0 Max speed in meters/second at zero altitude.
-- @field #number massEmpty Empty mass in kg. -- @field #number massEmpty Empty mass in kg.
@@ -598,9 +630,13 @@ do -- Object
--- @function [parent=#Object] destroy --- @function [parent=#Object] destroy
-- @param #Object self -- @param #Object self
--- @function [parent=#Object] getCategory --- Returns an enumerator of the category for the specific object.
-- The enumerator returned is dependent on the category of the object and how the function is called.
-- As of DCS 2.9.2 when this function is called on an Object, Unit, Weapon, or Airbase a 2nd value will be returned which details the object sub-category value.
-- @function [parent=#Object] getCategory
-- @param #Object self -- @param #Object self
-- @return #Object.Category -- @return #Object.Category The object category (1=UNIT, 2=WEAPON, 3=STATIC, 4=BASE, 5=SCENERY, 6=Cargo)
-- @return #number The subcategory of the passed object, e.g. Unit.Category if a unit object was passed.
--- Returns type name of the Object. --- Returns type name of the Object.
-- @function [parent=#Object] getTypeName -- @function [parent=#Object] getTypeName
@@ -1013,12 +1049,14 @@ do -- Spot
end -- Spot end -- Spot
do -- Controller do -- Controller
--- Controller is an object that performs A.I.-tasks. Other words controller is an instance of A.I.. Controller stores current main task, active enroute tasks and behavior options. Controller performs commands. Please, read DCS A-10C GUI Manual EN.pdf chapter "Task Planning for Unit Groups", page 91 to understand A.I. system of DCS:A-10C. --- Controller is an object that performs A.I.-tasks. Other words controller is an instance of A.I.. Controller stores current main task, active enroute tasks and behavior options. Controller performs commands. Please, read DCS A-10C GUI Manual EN.pdf chapter "Task Planning for Unit Groups", page 91 to understand A.I. system of DCS:A-10C.
-- --
-- This class has 2 types of functions: -- This class has 2 types of functions:
-- --
-- * Tasks -- * Tasks
-- * Commands: Commands are instant actions those required zero time to perform. Commands may be used both for control unit/group behavior and control game mechanics. -- * Commands: Commands are instant actions those required zero time to perform. Commands may be used both for control unit/group behavior and control game mechanics.
--
-- @type Controller -- @type Controller
-- @field #Controller.Detection Detection Enum contains identifiers of surface types. -- @field #Controller.Detection Detection Enum contains identifiers of surface types.
@@ -1079,18 +1117,18 @@ do -- Controller
-- Detection -- Detection
--- Enum contains identifiers of surface types. --- Enum containing detection types.
-- @type Controller.Detection -- @type Controller.Detection
-- @field VISUAL -- @field #number VISUAL Visual detection. Numeric value 1.
-- @field OPTIC -- @field #number OPTIC Optical detection. Numeric value 2.
-- @field RADAR -- @field #number RADAR Radar detection. Numeric value 4.
-- @field IRST -- @field #number IRST Infra-red search and track detection. Numeric value 8.
-- @field RWR -- @field #number RWR Radar Warning Receiver detection. Numeric value 16.
-- @field DLINK -- @field #number DLINK Data link detection. Numeric value 32.
--- Detected target. --- Detected target.
-- @type DetectedTarget -- @type Controller.DetectedTarget
-- @field Wrapper.Object#Object object The target -- @field DCS#Object object The target
-- @field #boolean visible The target is visible -- @field #boolean visible The target is visible
-- @field #boolean type The target type is known -- @field #boolean type The target type is known
-- @field #boolean distance Distance to the target is known -- @field #boolean distance Distance to the target is known
@@ -1103,9 +1141,9 @@ do -- Controller
-- @param #Controller.Detection detection Controller.Detection detection1, Controller.Detection detection2, ... Controller.Detection detectionN -- @param #Controller.Detection detection Controller.Detection detection1, Controller.Detection detection2, ... Controller.Detection detectionN
-- @return #boolean detected True if the target is detected. -- @return #boolean detected True if the target is detected.
-- @return #boolean visible Has effect only if detected is true. True if the target is visible now. -- @return #boolean visible Has effect only if detected is true. True if the target is visible now.
-- @return #ModelTime lastTime Has effect only if visible is false. Last time when target was seen.
-- @return #boolean type Has effect only if detected is true. True if the target type is known. -- @return #boolean type Has effect only if detected is true. True if the target type is known.
-- @return #boolean distance Has effect only if detected is true. True if the distance to the target is known. -- @return #boolean distance Has effect only if detected is true. True if the distance to the target is known.
-- @return #ModelTime lastTime Has effect only if visible is false. Last time when target was seen.
-- @return #Vec3 lastPos Has effect only if visible is false. Last position of the target when it was seen. -- @return #Vec3 lastPos Has effect only if visible is false. Last position of the target when it was seen.
-- @return #Vec3 lastVel Has effect only if visible is false. Last velocity of the target when it was seen. -- @return #Vec3 lastVel Has effect only if visible is false. Last velocity of the target when it was seen.
@@ -1131,6 +1169,7 @@ end -- Controller
do -- Unit do -- Unit
--- Unit.
-- @type Unit -- @type Unit
-- @extends #CoalitionObject -- @extends #CoalitionObject
-- @field ID Identifier of an unit. It assigned to an unit by the Mission Editor automatically. -- @field ID Identifier of an unit. It assigned to an unit by the Mission Editor automatically.
+50 -16
View File
@@ -22,7 +22,7 @@
-- === -- ===
-- --
-- ### Author: **Applevangelist** -- ### Author: **Applevangelist**
-- Last Update Sept 2023 -- Last Update July 2025
-- --
-- === -- ===
-- @module Functional.AICSAR -- @module Functional.AICSAR
@@ -57,6 +57,8 @@
-- @field #number Speed Default speed setting for the helicopter FLIGHTGROUP is 100kn. -- @field #number Speed Default speed setting for the helicopter FLIGHTGROUP is 100kn.
-- @field #boolean UseEventEject In case Event LandingAfterEjection isn't working, use set this to true. -- @field #boolean UseEventEject In case Event LandingAfterEjection isn't working, use set this to true.
-- @field #number Delay In case of UseEventEject wait this long until we spawn a landed pilot. -- @field #number Delay In case of UseEventEject wait this long until we spawn a landed pilot.
-- @field #boolean UseRescueZone If true, use a rescue zone and not the max distance to FARP/MASH
-- @field Core.Zone#ZONE_RADIUS RescueZone Use this zone as operational area for the AICSAR instance.
-- @extends Core.Fsm#FSM -- @extends Core.Fsm#FSM
@@ -153,10 +155,10 @@
-- To set up AICSAR for SRS TTS output, add e.g. the following to your script: -- To set up AICSAR for SRS TTS output, add e.g. the following to your script:
-- --
-- -- setup for google TTS, radio 243 AM, SRS server port 5002 with a google standard-quality voice (google cloud account required) -- -- setup for google TTS, radio 243 AM, SRS server port 5002 with a google standard-quality voice (google cloud account required)
-- my_aicsar:SetSRSTTSRadio(true,"C:\\Program Files\\DCS-SimpleRadio-Standalone",243,radio.modulation.AM,5002,MSRS.Voices.Google.Standard.en_US_Standard_D,"en-US","female","C:\\Program Files\\DCS-SimpleRadio-Standalone\\google.json") -- my_aicsar:SetSRSTTSRadio(true,"C:\\Program Files\\DCS-SimpleRadio-Standalone\\ExternalAudio",243,radio.modulation.AM,5002,MSRS.Voices.Google.Standard.en_US_Standard_D,"en-US","female","C:\\Program Files\\DCS-SimpleRadio-Standalone\\ExternalAudio\\google.json")
-- --
-- -- alternatively for MS Desktop TTS (voices need to be installed locally first!) -- -- alternatively for MS Desktop TTS (voices need to be installed locally first!)
-- my_aicsar:SetSRSTTSRadio(true,"C:\\Program Files\\DCS-SimpleRadio-Standalone",243,radio.modulation.AM,5002,MSRS.Voices.Microsoft.Hazel,"en-GB","female") -- my_aicsar:SetSRSTTSRadio(true,"C:\\Program Files\\DCS-SimpleRadio-Standalone\\ExternalAudio",243,radio.modulation.AM,5002,MSRS.Voices.Microsoft.Hazel,"en-GB","female")
-- --
-- -- define a different voice for the downed pilot(s) -- -- define a different voice for the downed pilot(s)
-- my_aicsar:SetPilotTTSVoice(MSRS.Voices.Google.Standard.en_AU_Standard_D,"en-AU","male") -- my_aicsar:SetPilotTTSVoice(MSRS.Voices.Google.Standard.en_AU_Standard_D,"en-AU","male")
@@ -177,7 +179,7 @@
-- --
-- Switch on radio transmissions via **either** SRS **or** "normal" DCS radio e.g. like so: -- Switch on radio transmissions via **either** SRS **or** "normal" DCS radio e.g. like so:
-- --
-- my_aicsar:SetSRSRadio(true,"C:\\Program Files\\DCS-SimpleRadio-Standalone",270,radio.modulation.AM,nil,5002) -- my_aicsar:SetSRSRadio(true,"C:\\Program Files\\DCS-SimpleRadio-Standalone\\ExternalAudio",270,radio.modulation.AM,nil,5002)
-- --
-- or -- or
-- --
@@ -191,7 +193,7 @@
-- @field #AICSAR -- @field #AICSAR
AICSAR = { AICSAR = {
ClassName = "AICSAR", ClassName = "AICSAR",
version = "0.1.16", version = "0.1.18",
lid = "", lid = "",
coalition = coalition.side.BLUE, coalition = coalition.side.BLUE,
template = "", template = "",
@@ -236,6 +238,8 @@ AICSAR = {
Altitude = 1500, Altitude = 1500,
UseEventEject = false, UseEventEject = false,
Delay = 100, Delay = 100,
UseRescueZone = false,
RescueZone = nil,
} }
-- TODO Messages -- TODO Messages
@@ -304,8 +308,9 @@ AICSAR.RadioLength = {
-- @param #string Helotemplate Helicopter template name. -- @param #string Helotemplate Helicopter template name.
-- @param Wrapper.Airbase#AIRBASE FARP FARP object or Airbase from where to start. -- @param Wrapper.Airbase#AIRBASE FARP FARP object or Airbase from where to start.
-- @param Core.Zone#ZONE MASHZone Zone where to drop pilots after rescue. -- @param Core.Zone#ZONE MASHZone Zone where to drop pilots after rescue.
-- @param #number Helonumber Max number of alive Ai Helos at the same time. Defaults to three.
-- @return #AICSAR self -- @return #AICSAR self
function AICSAR:New(Alias,Coalition,Pilottemplate,Helotemplate,FARP,MASHZone) function AICSAR:New(Alias,Coalition,Pilottemplate,Helotemplate,FARP,MASHZone,Helonumber)
-- Inherit everything from FSM class. -- Inherit everything from FSM class.
local self=BASE:Inherit(self, FSM:New()) local self=BASE:Inherit(self, FSM:New())
@@ -373,7 +378,7 @@ function AICSAR:New(Alias,Coalition,Pilottemplate,Helotemplate,FARP,MASHZone)
-- limit number of available helos at the same time -- limit number of available helos at the same time
self.limithelos = true self.limithelos = true
self.helonumber = 3 self.helonumber = Helonumber or 3
-- localization -- localization
self:InitLocalization() self:InitLocalization()
@@ -524,10 +529,20 @@ function AICSAR:InitLocalization()
return self return self
end end
--- [User] Use a defined zone as area of operation and not the distance to FARP.
-- @param #AICSAR self
-- @param Core.Zone#ZONE Zone The operational zone to use. Downed pilots in this area will be rescued. Can be any known #ZONE type.
-- @return #AICSAR self
function AICSAR:SetUsingRescueZone(Zone)
self.UseRescueZone = true
self.RescueZone = Zone
return self
end
--- [User] Switch sound output on and use SRS output for sound files. --- [User] Switch sound output on and use SRS output for sound files.
-- @param #AICSAR self -- @param #AICSAR self
-- @param #boolean OnOff Switch on (true) or off (false). -- @param #boolean OnOff Switch on (true) or off (false).
-- @param #string Path Path to your SRS Server Component, e.g. "C:\\\\Program Files\\\\DCS-SimpleRadio-Standalone" -- @param #string Path Path to your SRS Server External Audio Component, e.g. "C:\\\\Program Files\\\\DCS-SimpleRadio-Standalone\\\\ExternalAudio"
-- @param #number Frequency Defaults to 243 (guard) -- @param #number Frequency Defaults to 243 (guard)
-- @param #number Modulation Radio modulation. Defaults to radio.modulation.AM -- @param #number Modulation Radio modulation. Defaults to radio.modulation.AM
-- @param #string SoundPath Where to find the audio files. Defaults to nil, i.e. add messages via "Sound to..." in the Mission Editor. -- @param #string SoundPath Where to find the audio files. Defaults to nil, i.e. add messages via "Sound to..." in the Mission Editor.
@@ -538,7 +553,7 @@ function AICSAR:SetSRSRadio(OnOff,Path,Frequency,Modulation,SoundPath,Port)
self.SRSRadio = OnOff and true self.SRSRadio = OnOff and true
self.SRSTTSRadio = false self.SRSTTSRadio = false
self.SRSFrequency = Frequency or 243 self.SRSFrequency = Frequency or 243
self.SRSPath = Path or MSRS.path or "C:\\Program Files\\DCS-SimpleRadio-Standalone" self.SRSPath = Path or MSRS.path or "C:\\Program Files\\DCS-SimpleRadio-Standalone\\ExternalAudio"
self.SRS:SetLabel("ACSR") self.SRS:SetLabel("ACSR")
self.SRS:SetCoalition(self.coalition) self.SRS:SetCoalition(self.coalition)
self.SRSModulation = Modulation or radio.modulation.AM self.SRSModulation = Modulation or radio.modulation.AM
@@ -556,7 +571,7 @@ end
-- See `AICSAR:SetPilotTTSVoice()` and `AICSAR:SetOperatorTTSVoice()` -- See `AICSAR:SetPilotTTSVoice()` and `AICSAR:SetOperatorTTSVoice()`
-- @param #AICSAR self -- @param #AICSAR self
-- @param #boolean OnOff Switch on (true) or off (false). -- @param #boolean OnOff Switch on (true) or off (false).
-- @param #string Path Path to your SRS Server Component, e.g. "E:\\\\Program Files\\\\DCS-SimpleRadio-Standalone" -- @param #string Path Path to your SRS Server Component, e.g. "E:\\\\Program Files\\\\DCS-SimpleRadio-Standalone\\ExternalAudio"
-- @param #number Frequency (Optional) Defaults to 243 (guard) -- @param #number Frequency (Optional) Defaults to 243 (guard)
-- @param #number Modulation (Optional) Radio modulation. Defaults to radio.modulation.AM -- @param #number Modulation (Optional) Radio modulation. Defaults to radio.modulation.AM
-- @param #number Port (Optional) Port of the SRS, defaults to 5002. -- @param #number Port (Optional) Port of the SRS, defaults to 5002.
@@ -570,7 +585,7 @@ function AICSAR:SetSRSTTSRadio(OnOff,Path,Frequency,Modulation,Port,Voice,Cultur
self.SRSTTSRadio = OnOff and true self.SRSTTSRadio = OnOff and true
self.SRSRadio = false self.SRSRadio = false
self.SRSFrequency = Frequency or 243 self.SRSFrequency = Frequency or 243
self.SRSPath = Path or MSRS.path or "C:\\Program Files\\DCS-SimpleRadio-Standalone" self.SRSPath = Path or MSRS.path or "C:\\Program Files\\DCS-SimpleRadio-Standalone\\ExternalAudio"
self.SRSModulation = Modulation or radio.modulation.AM self.SRSModulation = Modulation or radio.modulation.AM
self.SRSPort = Port or MSRS.port or 5002 self.SRSPort = Port or MSRS.port or 5002
if OnOff then if OnOff then
@@ -693,7 +708,7 @@ function AICSAR:_EjectEventHandler(EventData)
local _LandingPos = COORDINATE:NewFromVec3(_event.initiator:getPosition().p) local _LandingPos = COORDINATE:NewFromVec3(_event.initiator:getPosition().p)
local _country = _event.initiator:getCountry() local _country = _event.initiator:getCountry()
local _coalition = coalition.getCountryCoalition( _country ) local _coalition = coalition.getCountryCoalition( _country )
local data = UTILS.DeepCopy(EventData) --local data = UTILS.DeepCopy(EventData)
Unit.destroy(_event.initiator) -- shagrat remove static Pilot model Unit.destroy(_event.initiator) -- shagrat remove static Pilot model
self:ScheduleOnce(self.Delay,self._DelayedSpawnPilot,self,_LandingPos,_coalition) self:ScheduleOnce(self.Delay,self._DelayedSpawnPilot,self,_LandingPos,_coalition)
end end
@@ -709,6 +724,13 @@ end
function AICSAR:_DelayedSpawnPilot(_LandingPos,_coalition) function AICSAR:_DelayedSpawnPilot(_LandingPos,_coalition)
local distancetofarp = _LandingPos:Get2DDistance(self.farp:GetCoordinate()) local distancetofarp = _LandingPos:Get2DDistance(self.farp:GetCoordinate())
if self.UseRescueZone == true and self.RescueZone ~= nil then
if self.RescueZone:IsCoordinateInZone(_LandingPos) then
distancetofarp = self.maxdistance - 10
else
distancetofarp = self.maxdistance + 10
end
end
-- Mayday Message -- Mayday Message
local Text,Soundfile,Soundlength,Subtitle = self.gettext:GetEntry("PILOTDOWN",self.locale) local Text,Soundfile,Soundlength,Subtitle = self.gettext:GetEntry("PILOTDOWN",self.locale)
local text = "" local text = ""
@@ -795,7 +817,13 @@ function AICSAR:_EventHandler(EventData, FromEject)
-- DONE: add distance check -- DONE: add distance check
local distancetofarp = _LandingPos:Get2DDistance(self.farp:GetCoordinate()) local distancetofarp = _LandingPos:Get2DDistance(self.farp:GetCoordinate())
if self.UseRescueZone == true and self.RescueZone ~= nil then
if self.RescueZone:IsCoordinateInZone(_LandingPos) then
distancetofarp = self.maxdistance - 10
else
distancetofarp = self.maxdistance + 10
end
end
-- Mayday Message -- Mayday Message
local Text,Soundfile,Soundlength,Subtitle = self.gettext:GetEntry("PILOTDOWN",self.locale) local Text,Soundfile,Soundlength,Subtitle = self.gettext:GetEntry("PILOTDOWN",self.locale)
local text = "" local text = ""
@@ -817,7 +845,6 @@ function AICSAR:_EventHandler(EventData, FromEject)
if _coalition == self.coalition then if _coalition == self.coalition then
if self.verbose then if self.verbose then
MESSAGE:New(msgtxt,15,"AICSAR"):ToCoalition(self.coalition) MESSAGE:New(msgtxt,15,"AICSAR"):ToCoalition(self.coalition)
-- MESSAGE:New(msgtxt,15,"AICSAR"):ToLog()
end end
if self.SRSRadio then if self.SRSRadio then
local sound = SOUNDFILE:New(Soundfile,self.SRSSoundPath,Soundlength) local sound = SOUNDFILE:New(Soundfile,self.SRSSoundPath,Soundlength)
@@ -869,6 +896,7 @@ function AICSAR:_GetFlight()
:InitUnControlled(true) :InitUnControlled(true)
:OnSpawnGroup( :OnSpawnGroup(
function(Group) function(Group)
Group:OptionPreferVerticalLanding()
self:__HeloOnDuty(1,Group) self:__HeloOnDuty(1,Group)
end end
) )
@@ -934,6 +962,10 @@ function AICSAR:_InitMission(Pilot,Index)
helo:__UnloadingDone(5) helo:__UnloadingDone(5)
end end
function helo:OnAfterLandAtAirbase(From,Event,To,airbase)
helo:Despawn(2)
end
self.helos[Index] = helo self.helos[Index] = helo
return self return self
@@ -984,7 +1016,9 @@ function AICSAR:_CheckHelos()
local name = helo:GetName() local name = helo:GetName()
self:T("Helo group "..name.." in state "..state) self:T("Helo group "..name.." in state "..state)
if state == "Arrived" then if state == "Arrived" then
helo:__Stop(5) --helo:__Stop(5)
helo.OnAfterDead = nil
helo:Despawn(35)
self.helos[_index] = nil self.helos[_index] = nil
end end
else else
@@ -1025,7 +1059,7 @@ function AICSAR:_CheckQueue(OpsGroup)
if self:_CheckInMashZone(_pilot) then if self:_CheckInMashZone(_pilot) then
self:T("Pilot" .. _pilot.GroupName .. " rescued!") self:T("Pilot" .. _pilot.GroupName .. " rescued!")
if OpsGroup then if OpsGroup then
OpsGroup:Despawn(10) --OpsGroup:Despawn(10)
else else
_pilot:Destroy(true,10) _pilot:Destroy(true,10)
end end
@@ -18,7 +18,7 @@
-- ### Author: FlightControl - Framework Design & Programming -- ### Author: FlightControl - Framework Design & Programming
-- ### Refactoring to use the Runway auto-detection: Applevangelist -- ### Refactoring to use the Runway auto-detection: Applevangelist
-- @date August 2022 -- @date August 2022
-- Last Update Nov 2023 -- Last Update Feb 2025
-- --
-- === -- ===
-- --
@@ -416,7 +416,7 @@ end
-- @field #ATC_GROUND_UNIVERSAL -- @field #ATC_GROUND_UNIVERSAL
ATC_GROUND_UNIVERSAL = { ATC_GROUND_UNIVERSAL = {
ClassName = "ATC_GROUND_UNIVERSAL", ClassName = "ATC_GROUND_UNIVERSAL",
Version = "0.0.1", Version = "0.0.2",
SetClient = nil, SetClient = nil,
Airbases = nil, Airbases = nil,
AirbaseList = nil, AirbaseList = nil,
@@ -442,16 +442,24 @@ function ATC_GROUND_UNIVERSAL:New(AirbaseList)
self.Airbases = {} self.Airbases = {}
for _name,_ in pairs(_DATABASE.AIRBASES) do
self.Airbases[_name]={}
end
self.AirbaseList = AirbaseList self.AirbaseList = AirbaseList
if not self.AirbaseList then if not self.AirbaseList then
self.AirbaseList = {} self.AirbaseList = {}
for _name,_ in pairs(_DATABASE.AIRBASES) do for _name,_base in pairs(_DATABASE.AIRBASES) do
-- DONE exclude FARPS and Ships
if _base and _base.isAirdrome == true then
self.AirbaseList[_name]=_name self.AirbaseList[_name]=_name
self.Airbases[_name]={}
end
end
else
for _,_name in pairs(AirbaseList) do
-- DONE exclude FARPS and Ships
local airbase = _DATABASE:FindAirbase(_name)
if airbase and (airbase.isAirdrome == true) then
self.Airbases[_name]={}
end
end end
end end
@@ -721,14 +729,18 @@ function ATC_GROUND_UNIVERSAL:_AirbaseMonitor()
if NotInRunwayZone then if NotInRunwayZone then
if IsOnGround then
local Taxi = Client:GetState( self, "Taxi" ) local Taxi = Client:GetState( self, "Taxi" )
if IsOnGround then
self:T( Taxi ) self:T( Taxi )
if Taxi == false then if Taxi == false then
local Velocity = VELOCITY:New( AirbaseMeta.KickSpeed or self.KickSpeed ) local Velocity = VELOCITY:New( AirbaseMeta.KickSpeed or self.KickSpeed )
Client:Message( "Welcome to " .. AirbaseID .. ". The maximum taxiing speed is " .. Client:Message( "Welcome to " .. AirbaseID .. ". The maximum taxiing speed is " ..
Velocity:ToString() , 20, "ATC" ) Velocity:ToString() , 20, "ATC" )
Client:SetState( self, "Taxi", true ) Client:SetState( self, "Taxi", true )
Client:SetState( self, "Speeding", false )
Client:SetState( self, "Warnings", 0 )
end end
-- TODO: GetVelocityKMH function usage -- TODO: GetVelocityKMH function usage
@@ -737,7 +749,7 @@ function ATC_GROUND_UNIVERSAL:_AirbaseMonitor()
local IsAboveRunway = Client:IsAboveRunway() local IsAboveRunway = Client:IsAboveRunway()
self:T( {IsAboveRunway, IsOnGround, Velocity:Get() }) self:T( {IsAboveRunway, IsOnGround, Velocity:Get() })
if IsOnGround then if IsOnGround and not Taxi then
local Speeding = false local Speeding = false
if AirbaseMeta.MaximumKickSpeed then if AirbaseMeta.MaximumKickSpeed then
if Velocity:Get() > AirbaseMeta.MaximumKickSpeed then if Velocity:Get() > AirbaseMeta.MaximumKickSpeed then
@@ -749,15 +761,17 @@ function ATC_GROUND_UNIVERSAL:_AirbaseMonitor()
end end
end end
if Speeding == true then if Speeding == true then
MESSAGE:New( "Penalty! Player " .. Client:GetPlayerName() .. --MESSAGE:New( "Penalty! Player " .. Client:GetPlayerName() ..
" has been kicked, due to a severe airbase traffic rule violation ...", 10, "ATC" ):ToAll() -- " has been kicked, due to a severe airbase traffic rule violation ...", 10, "ATC" ):ToAll()
Client:Destroy() --Client:Destroy()
Client:SetState( self, "Speeding", false ) Client:SetState( self, "Speeding", true )
Client:SetState( self, "Warnings", 0 ) local SpeedingWarnings = Client:GetState( self, "Warnings" )
Client:SetState( self, "Warnings", SpeedingWarnings + 1 )
Client:Message( "Warning " .. SpeedingWarnings .. "/3! Airbase traffic rule violation! Slow down now! Your speed is " ..
Velocity:ToString(), 5, "ATC" )
end end
end end
if IsOnGround then if IsOnGround then
local Speeding = false local Speeding = false
@@ -1035,23 +1049,23 @@ end
-- The following airbases are monitored at the Nevada region. -- The following airbases are monitored at the Nevada region.
-- Use the @{Wrapper.Airbase#AIRBASE.Nevada} enumeration to select the airbases to be monitored. -- Use the @{Wrapper.Airbase#AIRBASE.Nevada} enumeration to select the airbases to be monitored.
-- --
-- * `AIRBASE.Nevada.Beatty_Airport` -- * `AIRBASE.Nevada.Beatty`
-- * `AIRBASE.Nevada.Boulder_City_Airport` -- * `AIRBASE.Nevada.Boulder_City`
-- * `AIRBASE.Nevada.Creech_AFB` -- * `AIRBASE.Nevada.Creech`
-- * `AIRBASE.Nevada.Echo_Bay` -- * `AIRBASE.Nevada.Echo_Bay`
-- * `AIRBASE.Nevada.Groom_Lake_AFB` -- * `AIRBASE.Nevada.Groom_Lake`
-- * `AIRBASE.Nevada.Henderson_Executive_Airport` -- * `AIRBASE.Nevada.Henderson_Executive`
-- * `AIRBASE.Nevada.Jean_Airport` -- * `AIRBASE.Nevada.Jean`
-- * `AIRBASE.Nevada.Laughlin_Airport` -- * `AIRBASE.Nevada.Laughlin`
-- * `AIRBASE.Nevada.Lincoln_County` -- * `AIRBASE.Nevada.Lincoln_County`
-- * `AIRBASE.Nevada.McCarran_International_Airport` -- * `AIRBASE.Nevada.McCarran_International`
-- * `AIRBASE.Nevada.Mesquite` -- * `AIRBASE.Nevada.Mesquite`
-- * `AIRBASE.Nevada.Mina_Airport` -- * `AIRBASE.Nevada.Mina`
-- * `AIRBASE.Nevada.Nellis_AFB` -- * `AIRBASE.Nevada.Nellis`
-- * `AIRBASE.Nevada.North_Las_Vegas` -- * `AIRBASE.Nevada.North_Las_Vegas`
-- * `AIRBASE.Nevada.Pahute_Mesa_Airstrip` -- * `AIRBASE.Nevada.Pahute_Mesa`
-- * `AIRBASE.Nevada.Tonopah_Airport` -- * `AIRBASE.Nevada.Tonopah`
-- * `AIRBASE.Nevada.Tonopah_Test_Range_Airfield` -- * `AIRBASE.Nevada.Tonopah_Test_Range`
-- --
-- # Installation -- # Installation
-- --
@@ -1088,10 +1102,10 @@ end
-- --
-- -- Monitor specific airbases. -- -- Monitor specific airbases.
-- ATC_Ground = ATC_GROUND_NEVADA:New( -- ATC_Ground = ATC_GROUND_NEVADA:New(
-- { AIRBASE.Nevada.Laughlin_Airport, -- { AIRBASE.Nevada.Laughlin,
-- AIRBASE.Nevada.Lincoln_County, -- AIRBASE.Nevada.Lincoln_County,
-- AIRBASE.Nevada.North_Las_Vegas, -- AIRBASE.Nevada.North_Las_Vegas,
-- AIRBASE.Nevada.McCarran_International_Airport -- AIRBASE.Nevada.McCarran_International
-- } -- }
-- ) -- )
-- --
@@ -1330,33 +1344,33 @@ end
-- The following airbases are monitored at the PersianGulf region. -- The following airbases are monitored at the PersianGulf region.
-- Use the @{Wrapper.Airbase#AIRBASE.PersianGulf} enumeration to select the airbases to be monitored. -- Use the @{Wrapper.Airbase#AIRBASE.PersianGulf} enumeration to select the airbases to be monitored.
-- --
-- * `AIRBASE.PersianGulf.Abu_Musa_Island_Airport` -- * `AIRBASE.PersianGulf.Abu_Musa_Island`
-- * `AIRBASE.PersianGulf.Al_Dhafra_AB` -- * `AIRBASE.PersianGulf.Al_Dhafra_AFB`
-- * `AIRBASE.PersianGulf.Al_Maktoum_Intl` -- * `AIRBASE.PersianGulf.Al_Maktoum_Intl`
-- * `AIRBASE.PersianGulf.Al_Minhad_AB` -- * `AIRBASE.PersianGulf.Al_Minhad_AFB`
-- * `AIRBASE.PersianGulf.Bandar_Abbas_Intl` -- * `AIRBASE.PersianGulf.Bandar_Abbas_Intl`
-- * `AIRBASE.PersianGulf.Bandar_Lengeh` -- * `AIRBASE.PersianGulf.Bandar_Lengeh`
-- * `AIRBASE.PersianGulf.Dubai_Intl` -- * `AIRBASE.PersianGulf.Dubai_Intl`
-- * `AIRBASE.PersianGulf.Fujairah_Intl` -- * `AIRBASE.PersianGulf.Fujairah_Intl`
-- * `AIRBASE.PersianGulf.Havadarya` -- * `AIRBASE.PersianGulf.Havadarya`
-- * `AIRBASE.PersianGulf.Kerman_Airport` -- * `AIRBASE.PersianGulf.Kerman`
-- * `AIRBASE.PersianGulf.Khasab` -- * `AIRBASE.PersianGulf.Khasab`
-- * `AIRBASE.PersianGulf.Lar_Airbase` -- * `AIRBASE.PersianGulf.Lar`
-- * `AIRBASE.PersianGulf.Qeshm_Island` -- * `AIRBASE.PersianGulf.Qeshm_Island`
-- * `AIRBASE.PersianGulf.Sharjah_Intl` -- * `AIRBASE.PersianGulf.Sharjah_Intl`
-- * `AIRBASE.PersianGulf.Shiraz_International_Airport` -- * `AIRBASE.PersianGulf.Shiraz_Intl`
-- * `AIRBASE.PersianGulf.Sir_Abu_Nuayr` -- * `AIRBASE.PersianGulf.Sir_Abu_Nuayr`
-- * `AIRBASE.PersianGulf.Sirri_Island` -- * `AIRBASE.PersianGulf.Sirri_Island`
-- * `AIRBASE.PersianGulf.Tunb_Island_AFB` -- * `AIRBASE.PersianGulf.Tunb_Island_AFB`
-- * `AIRBASE.PersianGulf.Tunb_Kochak` -- * `AIRBASE.PersianGulf.Tunb_Kochak`
-- * `AIRBASE.PersianGulf.Sas_Al_Nakheel_Airport` -- * `AIRBASE.PersianGulf.Sas_Al_Nakheel`
-- * `AIRBASE.PersianGulf.Bandar_e_Jask_airfield` -- * `AIRBASE.PersianGulf.Bandar_e_Jask`
-- * `AIRBASE.PersianGulf.Abu_Dhabi_International_Airport` -- * `AIRBASE.PersianGulf.Abu_Dhabi_Intl`
-- * `AIRBASE.PersianGulf.Al_Bateen_Airport` -- * `AIRBASE.PersianGulf.Al_Bateen`
-- * `AIRBASE.PersianGulf.Kish_International_Airport` -- * `AIRBASE.PersianGulf.Kish_Intl`
-- * `AIRBASE.PersianGulf.Al_Ain_International_Airport` -- * `AIRBASE.PersianGulf.Al_Ain_Intl`
-- * `AIRBASE.PersianGulf.Lavan_Island_Airport` -- * `AIRBASE.PersianGulf.Lavan_Island`
-- * `AIRBASE.PersianGulf.Jiroft_Airport` -- * `AIRBASE.PersianGulf.Jiroft`
-- --
-- # Installation -- # Installation
-- --
@@ -1391,8 +1405,8 @@ end
-- AirbasePoliceCaucasus = ATC_GROUND_PERSIANGULF:New() -- AirbasePoliceCaucasus = ATC_GROUND_PERSIANGULF:New()
-- --
-- ATC_Ground = ATC_GROUND_PERSIANGULF:New( -- ATC_Ground = ATC_GROUND_PERSIANGULF:New(
-- { AIRBASE.PersianGulf.Kerman_Airport, -- { AIRBASE.PersianGulf.Kerman,
-- AIRBASE.PersianGulf.Al_Minhad_AB -- AIRBASE.PersianGulf.Al_Minhad_AFB
-- } -- }
-- ) -- )
-- --
@@ -1441,12 +1455,11 @@ function ATC_GROUND_PERSIANGULF:Start( RepeatScanSeconds )
self.AirbaseMonitor = SCHEDULER:New( self, self._AirbaseMonitor, { self }, 0, RepeatScanSeconds ) self.AirbaseMonitor = SCHEDULER:New( self, self._AirbaseMonitor, { self }, 0, RepeatScanSeconds )
end end
---
-- @type ATC_GROUND_MARIANAISLANDS -- @type ATC_GROUND_MARIANAISLANDS
-- @extends #ATC_GROUND -- @extends #ATC_GROUND
--- # ATC\_GROUND\_MARIANA, extends @{#ATC_GROUND} --- # ATC\_GROUND\_MARIANA, extends @{#ATC_GROUND}
-- --
-- The ATC\_GROUND\_MARIANA class monitors the speed of the airplanes at the airbase during taxi. -- The ATC\_GROUND\_MARIANA class monitors the speed of the airplanes at the airbase during taxi.
+138 -51
View File
@@ -619,62 +619,147 @@ ARTY.WeaponType={
} }
--- Database of common artillery unit properties. --- Database of common artillery unit properties.
-- @type ARTY.dbitem
-- @field #string displayname Name displayed in ME.
-- @field #number minrange Minimum firing range in meters.
-- @field #number maxrange Maximum firing range in meters.
-- @field #number reloadtime Reload time in seconds.
--- Database of common artillery unit properties.
-- Table key is the "type name" and table value is and `ARTY.dbitem`.
-- @type ARTY.db -- @type ARTY.db
ARTY.db={ ARTY.db={
["2B11 mortar"] = { -- type "2B11 mortar" ["LeFH_18-40-105"] = {
minrange = 500, -- correct? displayname = "FH LeFH-18 105mm", -- name displayed in the ME
maxrange = 7000, -- 7 km minrange = 500, -- min range (green circle) in meters
reloadtime = 30, -- 30 sec maxrange = 10500, -- max range (red circle) in meters
reloadtime = nil, -- reload time in seconds
}, },
["SPH 2S1 Gvozdika"] = { -- type "SAU Gvozdika" ["M2A1-105"] = {
minrange = 300, -- correct? displayname = "FH M2A1 105mm",
maxrange = 15000, -- 15 km minrange = 500,
reloadtime = nil, -- unknown maxrange = 11500,
reloadtime = nil,
}, },
["SPH 2S19 Msta"] = { --type "SAU Msta", alias "2S19 Msta" ["Pak40"] = {
minrange = 300, -- correct? displayname = "FH Pak 40 75mm",
maxrange = 23500, -- 23.5 km minrange = 500,
reloadtime = nil, -- unknown maxrange = 3000,
reloadtime = nil,
}, },
["SPH 2S3 Akatsia"] = { -- type "SAU Akatsia", alias "2S3 Akatsia" ["L118_Unit"] = {
minrange = 300, -- correct? displayname = "L118 Light Artillery Gun",
maxrange = 17000, -- 17 km minrange = 500,
reloadtime = nil, -- unknown maxrange = 17500,
reloadtime = nil,
}, },
["SPH 2S9 Nona"] = { --type "SAU 2-C9" ["Smerch"] = {
minrange = 500, -- correct? displayname = "MLRS 9A52 Smerch CM 300mm",
maxrange = 7000, -- 7 km minrange = 20000,
reloadtime = nil, -- unknown maxrange = 70000,
reloadtime = 2160,
}, },
["SPH M109 Paladin"] = { -- type "M-109", alias "M109" ["Smerch_HE"] = {
minrange = 300, -- correct? displayname = "MLRS 9A52 Smerch HE 300mm",
maxrange = 22000, -- 22 km minrange = 20000,
reloadtime = nil, -- unknown maxrange = 70000,
reloadtime = 2160,
}, },
["SpGH Dana"] = { -- type "SpGH_Dana" ["Uragan_BM-27"] = {
minrange = 300, -- correct? displayname = "MLRS 9K57 Uragan BM-27 220mm",
maxrange = 18700, -- 18.7 km minrange = 11500,
reloadtime = nil, -- unknown maxrange = 35800,
reloadtime = 840,
}, },
["MLRS BM-21 Grad"] = { --type "Grad-URAL", alias "MLRS BM-21 Grad" ["Grad-URAL"] = {
minrange = 5000, -- 5 km displayname = "MLRS BM-21 Grad 122mm",
maxrange = 19000, -- 19 km minrange = 5000,
reloadtime = 420, -- 7 min maxrange = 19000,
reloadtime = 420,
}, },
["MLRS 9K57 Uragan BM-27"] = { -- type "Uragan_BM-27" ["HL_B8M1"] = {
minrange = 11500, -- 11.5 km displayname = "MLRS HL with B8M1 80mm",
maxrange = 35800, -- 35.8 km minrange = 500,
reloadtime = 840, -- 14 min maxrange = 5000,
reloadtime = nil,
}, },
["MLRS 9A52 Smerch"] = { -- type "Smerch" ["tt_B8M1"] = {
minrange = 20000, -- 20 km displayname = "MLRS LC with B8M1 80mm",
maxrange = 70000, -- 70 km minrange = 500,
reloadtime = 2160, -- 36 min maxrange = 5000,
reloadtime = nil,
}, },
["MLRS M270"] = { --type "MRLS", alias "M270 MRLS" ["MLRS"] = {
minrange = 10000, -- 10 km displayname = "MLRS M270 227mm",
maxrange = 32000, -- 32 km minrange = 10000,
reloadtime = 540, -- 9 min maxrange = 32000,
reloadtime = 540,
},
["2B11 mortar"] = {
displayname = "Mortar 2B11 120mm",
minrange = 500,
maxrange = 7000,
reloadtime = 30,
},
["PLZ05"] = {
displayname = "PLZ-05",
minrange = 500,
maxrange = 23500,
reloadtime = nil,
},
["SAU Gvozdika"] = {
displayname = "SPH 2S1 Gvozdika 122mm",
minrange = 300,
maxrange = 15000,
reloadtime = nil,
},
["SAU Msta"] = {
displayname = "SPH 2S19 Msta 152mm",
minrange = 300,
maxrange = 23500,
reloadtime = nil,
},
["SAU Akatsia"] = {
displayname = "SPH 2S3 Akatsia 152mm",
minrange = 300,
maxrange = 17000,
reloadtime = nil,
},
["SpGH_Dana"] = {
displayname = "SPH Dana vz77 152mm",
minrange = 300,
maxrange = 18700,
reloadtime = nil,
},
["M-109"] = {
displayname = "SPH M109 Paladin 155mm",
minrange = 300,
maxrange = 22000,
reloadtime = nil,
},
["M12_GMC"] = {
displayname = "SPH M12 GMC 155mm",
minrange = 300,
maxrange = 18200,
reloadtime = nil,
},
["Wespe124"] = {
displayname = "SPH Sd.Kfz.124 Wespe 105mm",
minrange = 300,
maxrange = 7000,
reloadtime = nil,
},
["T155_Firtina"] = {
displayname = "SPH T155 Firtina 155mm",
minrange = 300,
maxrange = 41000,
reloadtime = nil,
},
["SAU 2-C9"] = {
displayname = "SPM 2S9 Nona 120mm M",
minrange = 500,
maxrange = 7000,
reloadtime = nil,
}, },
} }
@@ -695,7 +780,7 @@ ARTY.db={
--- Arty script version. --- Arty script version.
-- @field #string version -- @field #string version
ARTY.version="1.3.1" ARTY.version="1.3.3"
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
@@ -797,8 +882,8 @@ function ARTY:New(group, alias)
-- Maximum speed in km/h. -- Maximum speed in km/h.
self.SpeedMax=group:GetSpeedMax() self.SpeedMax=group:GetSpeedMax()
-- Group is mobile or not (e.g. mortars). -- Group is mobile or not (e.g. mortars). Some immobile units have a speed of 1 m/s = 3.6 km/h. So we check this number.
if self.SpeedMax>1 then if self.SpeedMax>3.6 then
self.ismobile=true self.ismobile=true
else else
self.ismobile=false self.ismobile=false
@@ -1923,7 +2008,7 @@ function ARTY:onafterStart(Controllable, From, Event, To)
end end
-- Check if we have and arty type that is in the DB. -- Check if we have and arty type that is in the DB.
local _dbproperties=self:_CheckDB(self.DisplayName) local _dbproperties=self:_CheckDB(self.Type)
self:T({dbproperties=_dbproperties}) self:T({dbproperties=_dbproperties})
if _dbproperties~=nil then if _dbproperties~=nil then
for property,value in pairs(_dbproperties) do for property,value in pairs(_dbproperties) do
@@ -1969,8 +2054,8 @@ function ARTY:onafterStart(Controllable, From, Event, To)
text=text..string.format("Type = %s\n", self.Type) text=text..string.format("Type = %s\n", self.Type)
text=text..string.format("Display Name = %s\n", self.DisplayName) text=text..string.format("Display Name = %s\n", self.DisplayName)
text=text..string.format("Number of units = %d\n", self.IniGroupStrength) text=text..string.format("Number of units = %d\n", self.IniGroupStrength)
text=text..string.format("Speed max = %d km/h\n", self.SpeedMax) text=text..string.format("Speed max = %.1f km/h\n", self.SpeedMax)
text=text..string.format("Speed default = %d km/h\n", self.Speed) text=text..string.format("Speed default = %.1f km/h\n", self.Speed)
text=text..string.format("Is mobile = %s\n", tostring(self.ismobile)) text=text..string.format("Is mobile = %s\n", tostring(self.ismobile))
text=text..string.format("Is cargo = %s\n", tostring(self.iscargo)) text=text..string.format("Is cargo = %s\n", tostring(self.iscargo))
text=text..string.format("Min range = %.1f km\n", self.minrange/1000) text=text..string.format("Min range = %.1f km\n", self.minrange/1000)
@@ -3049,7 +3134,7 @@ function ARTY:onafterOpenFire(Controllable, From, Event, To, target)
local nfire=Narty local nfire=Narty
local _type="shots" local _type="shots"
if target.weapontype==ARTY.WeaponType.Auto then if target.weapontype==ARTY.WeaponType.Auto then
nfire=Narty nfire=Nammo -- We take everything that is available
_type="shots" _type="shots"
elseif target.weapontype==ARTY.WeaponType.Cannon then elseif target.weapontype==ARTY.WeaponType.Cannon then
nfire=Narty nfire=Narty
@@ -3071,6 +3156,8 @@ function ARTY:onafterOpenFire(Controllable, From, Event, To, target)
_type="cruise missiles" _type="cruise missiles"
end end
--env.info(string.format("FF type=%s, Nrockets=%d, Nfire=%d target.nshells=%d", _type, Nrockets, nfire, target.nshells))
-- Adjust if less than requested ammo is left. -- Adjust if less than requested ammo is left.
target.nshells=math.min(target.nshells, nfire) target.nshells=math.min(target.nshells, nfire)
+141 -12
View File
@@ -74,7 +74,7 @@
-- @image Designation.JPG -- @image Designation.JPG
-- --
-- Date: 24 Oct 2021 -- Date: 24 Oct 2021
-- Last Update: May 2024 -- Last Update: Mar 2025
-- --
--- Class AUTOLASE --- Class AUTOLASE
-- @type AUTOLASE -- @type AUTOLASE
@@ -89,6 +89,10 @@
-- @field #table playermenus -- @field #table playermenus
-- @field #boolean smokemenu -- @field #boolean smokemenu
-- @field #boolean threatmenu -- @field #boolean threatmenu
-- @field #number RoundingPrecision
-- @field #table smokeoffset
-- @field #boolean increasegroundawareness
-- @field #number MonitorFrequency
-- @extends Ops.Intel#INTEL -- @extends Ops.Intel#INTEL
--- ---
@@ -100,6 +104,9 @@ AUTOLASE = {
alias = "", alias = "",
debug = false, debug = false,
smokemenu = true, smokemenu = true,
RoundingPrecision = 0,
increasegroundawareness = false,
MonitorFrequency = 30,
} }
--- Laser spot info --- Laser spot info
@@ -118,7 +125,7 @@ AUTOLASE = {
--- AUTOLASE class version. --- AUTOLASE class version.
-- @field #string version -- @field #string version
AUTOLASE.version = "0.1.25" AUTOLASE.version = "0.1.31"
------------------------------------------------------------------- -------------------------------------------------------------------
-- Begin Functional.Autolase.lua -- Begin Functional.Autolase.lua
@@ -191,6 +198,7 @@ function AUTOLASE:New(RecceSet, Coalition, Alias, PilotSet)
self.reporttimelong = 30 self.reporttimelong = 30
self.smoketargets = false self.smoketargets = false
self.smokecolor = SMOKECOLOR.Red self.smokecolor = SMOKECOLOR.Red
self.smokeoffset = nil
self.notifypilots = true self.notifypilots = true
self.targetsperrecce = {} self.targetsperrecce = {}
self.RecceUnits = {} self.RecceUnits = {}
@@ -207,6 +215,11 @@ function AUTOLASE:New(RecceSet, Coalition, Alias, PilotSet)
self.playermenus = {} self.playermenus = {}
self.smokemenu = true self.smokemenu = true
self.threatmenu = true self.threatmenu = true
self.RoundingPrecision = 0
self.increasegroundawareness = false
self.MonitorFrequency = 30
self:EnableSmokeMenu({Angle=math.random(0,359),Distance=math.random(10,20)})
-- Set some string id for output to DCS.log file. -- Set some string id for output to DCS.log file.
self.lid=string.format("AUTOLASE %s (%s) | ", self.alias, self.coalition and UTILS.GetCoalitionName(self.coalition) or "unknown") self.lid=string.format("AUTOLASE %s (%s) | ", self.alias, self.coalition and UTILS.GetCoalitionName(self.coalition) or "unknown")
@@ -309,16 +322,41 @@ end
-- Helper Functions -- Helper Functions
------------------------------------------------------------------- -------------------------------------------------------------------
--- [User] When using Monitor, set the frequency here in which the report will appear
-- @param #AUTOLASE self
-- @param #number Seconds Run the report loop every number of seconds defined here.
-- @return #AUTOLASE self
function AUTOLASE:SetMonitorFrequency(Seconds)
self.MonitorFrequency = Seconds or 30
return self
end
--- [User] Set a table of possible laser codes. --- [User] Set a table of possible laser codes.
-- Each new RECCE can select a code from this table, default is { 1688, 1130, 4785, 6547, 1465, 4578 } . -- Each new RECCE can select a code from this table, default is { 1688, 1130, 4785, 6547, 1465, 4578 }.
-- @param #AUTOLASE self -- @param #AUTOLASE self
-- @param #list<#number> LaserCodes -- @param #list<#number> LaserCodes
-- @return #AUTOLASE -- @return #AUTOLASE self
function AUTOLASE:SetLaserCodes( LaserCodes ) function AUTOLASE:SetLaserCodes( LaserCodes )
self.LaserCodes = ( type( LaserCodes ) == "table" ) and LaserCodes or { LaserCodes } self.LaserCodes = ( type( LaserCodes ) == "table" ) and LaserCodes or { LaserCodes }
return self return self
end end
--- [User] Improve ground unit detection by using a zone scan and LOS check.
-- @param #AUTOLASE self
-- @return #AUTOLASE self
function AUTOLASE:EnableImproveGroundUnitsDetection()
self.increasegroundawareness = true
return self
end
--- [User] Do not improve ground unit detection by using a zone scan and LOS check.
-- @param #AUTOLASE self
-- @return #AUTOLASE self
function AUTOLASE:DisableImproveGroundUnitsDetection()
self.increasegroundawareness = false
return self
end
--- (Internal) Function to set pilot menu. --- (Internal) Function to set pilot menu.
-- @param #AUTOLASE self -- @param #AUTOLASE self
-- @return #AUTOLASE self -- @return #AUTOLASE self
@@ -455,7 +493,7 @@ end
--- (User) Function enable sending messages via SRS. --- (User) Function enable sending messages via SRS.
-- @param #AUTOLASE self -- @param #AUTOLASE self
-- @param #boolean OnOff Switch usage on and off -- @param #boolean OnOff Switch usage on and off
-- @param #string Path Path to SRS directory, e.g. C:\\Program Files\\DCS-SimpleRadio-Standalone -- @param #string Path Path to SRS TTS directory, e.g. C:\\Program Files\\DCS-SimpleRadio-Standalone\\ExternalAudio
-- @param #number Frequency Frequency to send, e.g. 243 -- @param #number Frequency Frequency to send, e.g. 243
-- @param #number Modulation Modulation i.e. radio.modulation.AM or radio.modulation.FM -- @param #number Modulation Modulation i.e. radio.modulation.AM or radio.modulation.FM
-- @param #string Label (Optional) Short label to be used on the SRS Client Overlay -- @param #string Label (Optional) Short label to be used on the SRS Client Overlay
@@ -470,7 +508,7 @@ end
function AUTOLASE:SetUsingSRS(OnOff,Path,Frequency,Modulation,Label,Gender,Culture,Port,Voice,Volume,PathToGoogleKey) function AUTOLASE:SetUsingSRS(OnOff,Path,Frequency,Modulation,Label,Gender,Culture,Port,Voice,Volume,PathToGoogleKey)
if OnOff then if OnOff then
self.useSRS = true self.useSRS = true
self.SRSPath = Path or MSRS.path or "C:\\Program Files\\DCS-SimpleRadio-Standalone" self.SRSPath = Path or MSRS.path or "C:\\Program Files\\DCS-SimpleRadio-Standalone\\ExternalAudio"
self.SRSFreq = Frequency or 271 self.SRSFreq = Frequency or 271
self.SRSMod = Modulation or radio.modulation.AM self.SRSMod = Modulation or radio.modulation.AM
self.Gender = Gender or MSRS.gender or "male" self.Gender = Gender or MSRS.gender or "male"
@@ -600,11 +638,26 @@ function AUTOLASE:SetSmokeTargets(OnOff,Color)
return self return self
end end
--- (User) Function to set rounding precision for BR distance output.
-- @param #AUTOLASE self
-- @param #number IDP Rounding precision before/after the decimal sign. Defaults to zero. Positive values round right of the decimal sign, negative ones left of the decimal sign.
-- @return #AUTOLASE self
function AUTOLASE:SetRoundingPrecsion(IDP)
self.RoundingPrecision = IDP or 0
return self
end
--- (User) Show the "Switch smoke target..." menu entry for pilots. On by default. --- (User) Show the "Switch smoke target..." menu entry for pilots. On by default.
-- @param #AUTOLASE self -- @param #AUTOLASE self
-- @param #table Offset (Optional) Define an offset for the smoke, i.e. not directly on the unit itself, angle is degrees and distance is meters. E.g. `autolase:EnableSmokeMenu({Angle=30,Distance=20})`
-- @return #AUTOLASE self -- @return #AUTOLASE self
function AUTOLASE:EnableSmokeMenu() function AUTOLASE:EnableSmokeMenu(Offset)
self.smokemenu = true self.smokemenu = true
if Offset then
self.smokeoffset = {}
self.smokeoffset.Distance = Offset.Distance or math.random(10,20)
self.smokeoffset.Angle = Offset.Angle or math.random(0,359)
end
return self return self
end end
@@ -613,6 +666,7 @@ end
-- @return #AUTOLASE self -- @return #AUTOLASE self
function AUTOLASE:DisableSmokeMenu() function AUTOLASE:DisableSmokeMenu()
self.smokemenu = false self.smokemenu = false
self.smokeoffset = nil
return self return self
end end
@@ -671,7 +725,8 @@ function AUTOLASE:CleanCurrentLasing()
local unit = recce:GetUnit(1) local unit = recce:GetUnit(1)
local name = unit:GetName() local name = unit:GetName()
if not self.RecceUnits[name] then if not self.RecceUnits[name] then
self.RecceUnits[name] = { name=name, unit=unit, cooldown = false, timestamp = timer.getAbsTime() } local isground = (unit and unit.IsGround) and unit:IsGround() or false
self.RecceUnits[name] = { name=name, unit=unit, cooldown = false, timestamp = timer.getAbsTime(), isground=isground }
end end
end end
end end
@@ -757,9 +812,11 @@ function AUTOLASE:ShowStatus(Group,Unit)
end end
local code = self:GetLaserCode(unit:GetName()) local code = self:GetLaserCode(unit:GetName())
report:Add(string.format("Recce %s has code %d",name,code)) report:Add(string.format("Recce %s has code %d",name,code))
report:Add("---------------")
end end
end end
report:Add(string.format("Lasing min threat level %d",self.minthreatlevel)) report:Add(string.format("Lasing min threat level %d",self.minthreatlevel))
report:Add("---------------")
local lines = 0 local lines = 0
for _ind,_entry in pairs(self.CurrentLasing) do for _ind,_entry in pairs(self.CurrentLasing) do
local entry = _entry -- #AUTOLASE.LaserSpot local entry = _entry -- #AUTOLASE.LaserSpot
@@ -779,22 +836,28 @@ function AUTOLASE:ShowStatus(Group,Unit)
if playername then if playername then
local settings = _DATABASE:GetPlayerSettings(playername) local settings = _DATABASE:GetPlayerSettings(playername)
if settings then if settings then
self:I("Get Settings ok!") self:T("Get Settings ok!")
if settings:IsA2G_MGRS() then if settings:IsA2G_MGRS() then
locationstring = entry.coordinate:ToStringMGRS(settings) locationstring = entry.coordinate:ToStringMGRS(settings)
elseif settings:IsA2G_LL_DMS() then elseif settings:IsA2G_LL_DMS() then
locationstring = entry.coordinate:ToStringLLDMS(settings) locationstring = entry.coordinate:ToStringLLDMS(settings)
elseif settings:IsA2G_LL_DDM() then
locationstring = entry.coordinate:ToStringLLDDM(settings)
elseif settings:IsA2G_BR() then elseif settings:IsA2G_BR() then
locationstring = entry.coordinate:ToStringBR(Group:GetCoordinate() or Unit:GetCoordinate(),settings) -- attention this is the distance from the ASKING unit to target, not from RECCE to target!
local startcoordinate = Unit:GetCoordinate() or Group:GetCoordinate()
locationstring = entry.coordinate:ToStringBR(startcoordinate,settings,false,self.RoundingPrecision)
end end
end end
end end
local text = string.format("%s lasing %s code %d\nat %s",reccename,typename,code,locationstring) local text = string.format("+ %s lasing %s code %d\nat %s",reccename,typename,code,locationstring)
report:Add(text) report:Add(text)
report:Add("---------------")
lines = lines + 1 lines = lines + 1
end end
if lines == 0 then if lines == 0 then
report:Add("No targets!") report:Add("No targets!")
report:Add("---------------")
end end
local reporttime = self.reporttimelong local reporttime = self.reporttimelong
if lines == 0 then reporttime = self.reporttimeshort end if lines == 0 then reporttime = self.reporttimeshort end
@@ -913,6 +976,65 @@ function AUTOLASE:CanLase(Recce,Unit)
return canlase return canlase
end end
--- (Internal) Function to do a zone check per ground Recce and make found units and statics "known".
-- @param #AUTOLASE self
-- @return #AUTOLASE self
function AUTOLASE:_Prescient()
-- self.RecceUnits[name] = { name=name, unit=unit, cooldown = false, timestamp = timer.getAbsTime(), isground=isground }
for _,_data in pairs(self.RecceUnits) do
-- ground units only
if _data.isground and _data.unit and _data.unit:IsAlive() then
local unit = _data.unit -- Wrapper.Unit#UNIT
local position = unit:GetCoordinate() -- Core.Point#COORDINATE
local needsinit = false
if position then
local lastposition = unit:GetProperty("lastposition")
-- property initiated?
if not lastposition then
unit:SetProperty("lastposition",position)
lastposition = position
needsinit = true
end
-- has moved?
local dist = position:Get2DDistance(lastposition)
-- refresh?
local TNow = timer.getAbsTime()
-- check
if dist > 10 or needsinit==true or TNow - _data.timestamp > 29 then
-- init scan objects
local hasunits,hasstatics,_,Units,Statics = position:ScanObjects(self.LaseDistance,true,true,false)
-- loop found units
if hasunits then
self:T(self.lid.."Checking possibly visible UNITs for Recce "..unit:GetName())
for _,_target in pairs(Units) do -- Wrapper.Unit#UNIT object here
local target = _target -- Wrapper.Unit#UNIT
if target and target:GetCoalition() ~= self.coalition then
if unit:IsLOS(target) and (not target:IsUnitDetected(unit))then
unit:KnowUnit(target,true,true)
end
end
end
end
-- loop found statics
if hasstatics then
self:T(self.lid.."Checking possibly visible STATICs for Recce "..unit:GetName())
for _,_static in pairs(Statics) do -- DCS static object here
local static = STATIC:Find(_static)
if static and static:GetCoalition() ~= self.coalition and static:GetCoordinate() then
local IsLOS = position:IsLOS(static:GetCoordinate())
if IsLOS then
unit:KnowUnit(static,true,true)
end
end
end
end
end
end
end
end
return self
end
------------------------------------------------------------------- -------------------------------------------------------------------
-- FSM Functions -- FSM Functions
------------------------------------------------------------------- -------------------------------------------------------------------
@@ -925,6 +1047,9 @@ end
-- @return #AUTOLASE self -- @return #AUTOLASE self
function AUTOLASE:onbeforeMonitor(From, Event, To) function AUTOLASE:onbeforeMonitor(From, Event, To)
self:T({From, Event, To}) self:T({From, Event, To})
if self.increasegroundawareness then
self:_Prescient()
end
-- Check if group has detected any units. -- Check if group has detected any units.
self:UpdateIntel() self:UpdateIntel()
return self return self
@@ -1077,6 +1202,9 @@ function AUTOLASE:onafterMonitor(From, Event, To)
} }
if self.smoketargets then if self.smoketargets then
local coord = unit:GetCoordinate() local coord = unit:GetCoordinate()
if self.smokeoffset then
coord:Translate(self.smokeoffset.Distance,self.smokeoffset.Angle,true,true)
end
local color = self:GetSmokeColor(reccename) local color = self:GetSmokeColor(reccename)
coord:Smoke(color) coord:Smoke(color)
end end
@@ -1087,7 +1215,8 @@ function AUTOLASE:onafterMonitor(From, Event, To)
end end
end end
self:__Monitor(-30) local nextloop = -self.MonitorFrequency or -30
self:__Monitor(nextloop)
return self return self
end end
@@ -357,7 +357,7 @@ function CLEANUP_AIRBASE.__:EventAddForCleanUp( Event )
self:F({Event}) self:F({Event})
if Event.IniDCSUnit and Event.IniCategory == Object.Category.UNIT then if Event.IniDCSUnit and Event.IniUnit and Event.IniCategory == Object.Category.UNIT then
if self.CleanUpList[Event.IniDCSUnitName] == nil then if self.CleanUpList[Event.IniDCSUnitName] == nil then
if self:IsInAirbase( Event.IniUnit:GetVec2() ) then if self:IsInAirbase( Event.IniUnit:GetVec2() ) then
self:AddForCleanUp( Event.IniUnit, Event.IniDCSUnitName ) self:AddForCleanUp( Event.IniUnit, Event.IniDCSUnitName )
@@ -365,7 +365,7 @@ function CLEANUP_AIRBASE.__:EventAddForCleanUp( Event )
end end
end end
if Event.TgtDCSUnit and Event.TgtCategory == Object.Category.UNIT then if Event.TgtDCSUnit and Event.TgtUnit and Event.TgtCategory == Object.Category.UNIT then
if self.CleanUpList[Event.TgtDCSUnitName] == nil then if self.CleanUpList[Event.TgtDCSUnitName] == nil then
if self:IsInAirbase( Event.TgtUnit:GetVec2() ) then if self:IsInAirbase( Event.TgtUnit:GetVec2() ) then
self:AddForCleanUp( Event.TgtUnit, Event.TgtDCSUnitName ) self:AddForCleanUp( Event.TgtUnit, Event.TgtDCSUnitName )
@@ -387,7 +387,7 @@ function CLEANUP_AIRBASE.__:CleanUpSchedule()
local CleanUpUnit = CleanUpListData.CleanUpUnit -- Wrapper.Unit#UNIT local CleanUpUnit = CleanUpListData.CleanUpUnit -- Wrapper.Unit#UNIT
local CleanUpGroupName = CleanUpListData.CleanUpGroupName local CleanUpGroupName = CleanUpListData.CleanUpGroupName
if CleanUpUnit:IsAlive() ~= nil then if CleanUpUnit and CleanUpUnit:IsAlive() ~= nil then
if self:IsInAirbase( CleanUpUnit:GetVec2() ) then if self:IsInAirbase( CleanUpUnit:GetVec2() ) then
@@ -414,7 +414,7 @@ function CLEANUP_AIRBASE.__:CleanUpSchedule()
end end
end end
-- Clean Units which are waiting for a very long time in the CleanUpZone. -- Clean Units which are waiting for a very long time in the CleanUpZone.
if CleanUpUnit and not CleanUpUnit:GetPlayerName() then if CleanUpUnit and (CleanUpUnit.GetPlayerName == nil or not CleanUpUnit:GetPlayerName()) then
local CleanUpUnitVelocity = CleanUpUnit:GetVelocityKMH() local CleanUpUnitVelocity = CleanUpUnit:GetVelocityKMH()
if CleanUpUnitVelocity < 1 then if CleanUpUnitVelocity < 1 then
if CleanUpListData.CleanUpMoved then if CleanUpListData.CleanUpMoved then
@@ -20,7 +20,7 @@
-- --
-- ==== -- ====
-- @module Functional.ClientWatch -- @module Functional.ClientWatch
-- @image ClientWatch.JPG -- @image clientwatch.jpg
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- CLIENTWATCH class --- CLIENTWATCH class
@@ -28,6 +28,8 @@
-- @field #string ClassName Name of the class. -- @field #string ClassName Name of the class.
-- @field #boolean Debug Write Debug messages to DCS log file and send Debug messages to all players. -- @field #boolean Debug Write Debug messages to DCS log file and send Debug messages to all players.
-- @field #string lid String for DCS log file. -- @field #string lid String for DCS log file.
-- @field #number FilterCoalition If not nil, will only activate for aircraft of the given coalition value.
-- @field #number FilterCategory If not nil, will only activate for aircraft of the given category value.
-- @extends Core.Fsm#FSM_CONTROLLABLE -- @extends Core.Fsm#FSM_CONTROLLABLE
--- Manage and track client slots easily to add your own client-based menus and modules to. --- Manage and track client slots easily to add your own client-based menus and modules to.
@@ -66,7 +68,7 @@
-- --
-- -- Create an instance with a client unit prefix and send them a message when they spawn -- -- Create an instance with a client unit prefix and send them a message when they spawn
-- local clientInstance = CLIENTWATCH:New("Rotary") -- local clientInstance = CLIENTWATCH:New("Rotary")
-- function clientInstance:OnAfterSpawn(From,Event,To,ClientObject) -- function clientInstance:OnAfterSpawn(From,Event,To,ClientObject,EventData)
-- MESSAGE:New("Welcome to your aircraft!",10):ToUnit(ClientObject.Unit) -- MESSAGE:New("Welcome to your aircraft!",10):ToUnit(ClientObject.Unit)
-- end -- end
-- --
@@ -108,7 +110,7 @@
-- --
-- -- Show a message to player when they take damage from a weapon -- -- Show a message to player when they take damage from a weapon
-- local clientInstance = CLIENTWATCH:New("Rotary") -- local clientInstance = CLIENTWATCH:New("Rotary")
-- function clientInstance:OnAfterSpawn(From,Event,To,ClientObject) -- function clientInstance:OnAfterSpawn(From,Event,To,ClientObject,EventData)
-- function ClientObject:OnAfterHit(From,Event,To,EventData) -- function ClientObject:OnAfterHit(From,Event,To,EventData)
-- local typeShooter = EventData.IniTypeName -- local typeShooter = EventData.IniTypeName
-- local nameWeapon = EventData.weapon_name -- local nameWeapon = EventData.weapon_name
@@ -120,6 +122,7 @@
CLIENTWATCH = {} CLIENTWATCH = {}
CLIENTWATCH.ClassName = "CLIENTWATCH" CLIENTWATCH.ClassName = "CLIENTWATCH"
CLIENTWATCH.Debug = false CLIENTWATCH.Debug = false
CLIENTWATCH.DebugEventData = false
CLIENTWATCH.lid = nil CLIENTWATCH.lid = nil
-- @type CLIENTWATCHTools -- @type CLIENTWATCHTools
@@ -139,7 +142,10 @@ CLIENTWATCH.version="1.0.1"
--- Creates a new instance of CLIENTWATCH to add scripts to. Can be used multiple times with the same client/prefixes if you need it for multiple scripts. --- Creates a new instance of CLIENTWATCH to add scripts to. Can be used multiple times with the same client/prefixes if you need it for multiple scripts.
-- @param #CLIENTWATCH self -- @param #CLIENTWATCH self
-- @param #string, #table, or Wrapper.Client#CLIENT client Takes multiple inputs. If provided a #string, it will watch for clients whos UNIT NAME or GROUP NAME matches part of the #string as a prefix. You can also provide it with a #table containing multiple #string prefixes. Lastly, you can provide it with a Wrapper.Client#CLIENT of the specific client you want to apply this to. -- @param #string Will watch for clients whos UNIT NAME or GROUP NAME matches part of the #string as a prefix.
-- @param #table Put strings in a table to use multiple prefixes for the above method.
-- @param Wrapper.Client#CLIENT Provide a Moose CLIENT object to apply to that specific aircraft slot (static slots only!)
-- @param #nil Leave blank to activate for ALL CLIENTS
-- @return #CLIENTWATCH self -- @return #CLIENTWATCH self
function CLIENTWATCH:New(client) function CLIENTWATCH:New(client)
--Init FSM --Init FSM
@@ -147,6 +153,9 @@ function CLIENTWATCH:New(client)
self:SetStartState( "Idle" ) self:SetStartState( "Idle" )
self:AddTransition( "*", "Spawn", "*" ) self:AddTransition( "*", "Spawn", "*" )
self.FilterCoalition = nil
self.FilterCategory = nil
--- User function for OnAfter "Spawn" event. --- User function for OnAfter "Spawn" event.
-- @function [parent=#CLIENTWATCH] OnAfterSpawn -- @function [parent=#CLIENTWATCH] OnAfterSpawn
-- @param #CLIENTWATCH self -- @param #CLIENTWATCH self
@@ -155,27 +164,50 @@ function CLIENTWATCH:New(client)
-- @param #string Event Event. -- @param #string Event Event.
-- @param #string To To state. -- @param #string To To state.
-- @param #table clientObject Custom object that handles events and stores Moose object data. See top documentation for more details. -- @param #table clientObject Custom object that handles events and stores Moose object data. See top documentation for more details.
-- @param #table eventdata Data from EVENTS.Birth.
--Set up spawn tracking --Set up spawn tracking
if type(client) == "table" or type(client) == "string" then if not client then
if self.Debug then self:I({"New client instance created. ClientType = All clients"}) end
self:HandleEvent(EVENTS.Birth)
function self:OnEventBirth(eventdata)
if (eventdata.IniCategory == 0 or eventdata.IniCategory == 1) and eventdata.IniPlayerName
and (not self.FilterCoalition or self.FilterCoalition == eventdata.IniCoalition)
and (not self.FilterCategory or self.FilterCategory == eventdata.IniCategory) then
if self.Debug then
self:I({"Client spawned in.",IniCategory = eventdata.IniCategory})
end
local clientWatchDebug = self.Debug
local clientObject = CLIENTWATCHTools:_newClient(clientWatchDebug,eventdata)
self:Spawn(clientObject,eventdata)
end
end
elseif type(client) == "table" or type(client) == "string" then
if type(client) == "table" then if type(client) == "table" then
--CLIENT TABLE --CLIENT TABLE
if client.ClassName == "CLIENT" then if client.ClassName == "CLIENT" then
if self.Debug then self:I({"New client instance created. ClientType = Wrapper.CLIENT",client}) end
self.ClientName = client:GetName() self.ClientName = client:GetName()
self:HandleEvent(EVENTS.Birth) self:HandleEvent(EVENTS.Birth)
function self:OnEventBirth(eventdata) function self:OnEventBirth(eventdata)
if self.Debug then UTILS.PrintTableToLog(eventdata) end if (eventdata.IniCategory == 0 or eventdata.IniCategory == 1) and eventdata.IniPlayerName
if eventdata.IniCategory and eventdata.IniCategory <= 1 then and (not self.FilterCoalition or self.FilterCoalition == eventdata.IniCoalition)
and (not self.FilterCategory or self.FilterCategory == eventdata.IniCategory) then
if self.ClientName == eventdata.IniUnitName then if self.ClientName == eventdata.IniUnitName then
local clientObject = CLIENTWATCHTools:_newClient(eventdata) if self.Debug then
self:Spawn(clientObject) self:I({"Client spawned in.",IniCategory = eventdata.IniCategory})
end
local clientWatchDebug = self.Debug
local clientObject = CLIENTWATCHTools:_newClient(clientWatchDebug,eventdata)
self:Spawn(clientObject,eventdata)
end end
end end
end end
--STRING TABLE --STRING TABLE
else else
if self.Debug then self:I({"New client instance created. ClientType = Multiple Prefixes",client}) end
local tableValid = true local tableValid = true
for _,entry in pairs(client) do for _,entry in pairs(client) do
if type(entry) ~= "string" then if type(entry) ~= "string" then
@@ -187,12 +219,17 @@ function CLIENTWATCH:New(client)
if tableValid then if tableValid then
self:HandleEvent(EVENTS.Birth) self:HandleEvent(EVENTS.Birth)
function self:OnEventBirth(eventdata) function self:OnEventBirth(eventdata)
if self.Debug then UTILS.PrintTableToLog(eventdata) end
for _,entry in pairs(client) do for _,entry in pairs(client) do
if eventdata.IniCategory and eventdata.IniCategory <= 1 then if (eventdata.IniCategory == 0 or eventdata.IniCategory == 1) and eventdata.IniPlayerName
and (not self.FilterCoalition or self.FilterCoalition == eventdata.IniCoalition)
and (not self.FilterCategory or self.FilterCategory == eventdata.IniCategory) then
if string.match(eventdata.IniUnitName,entry) or string.match(eventdata.IniGroupName,entry) then if string.match(eventdata.IniUnitName,entry) or string.match(eventdata.IniGroupName,entry) then
local clientObject = CLIENTWATCHTools:_newClient(eventdata) if self.Debug then
self:Spawn(clientObject) self:I({"Client spawned in.",IniCategory = eventdata.IniCategory})
end
local clientWatchDebug = self.Debug
local clientObject = CLIENTWATCHTools:_newClient(clientWatchDebug,eventdata)
self:Spawn(clientObject,eventdata)
break break
end end
end end
@@ -201,15 +238,21 @@ function CLIENTWATCH:New(client)
end end
end end
else else
if self.Debug then self:I({"New client instance created. ClientType = Single Prefix",client}) end
--SOLO STRING --SOLO STRING
self:HandleEvent(EVENTS.Birth) self:HandleEvent(EVENTS.Birth)
function self:OnEventBirth(eventdata) function self:OnEventBirth(eventdata)
if self.Debug then UTILS.PrintTableToLog(eventdata) end if (eventdata.IniCategory == 0 or eventdata.IniCategory == 1) and eventdata.IniPlayerName
if eventdata.IniCategory and eventdata.IniCategory <= 1 then and (not self.FilterCoalition or self.FilterCoalition == eventdata.IniCoalition)
and (not self.FilterCategory or self.FilterCategory == eventdata.IniCategory) then
if string.match(eventdata.IniUnitName,client) or string.match(eventdata.IniGroupName,client) then if string.match(eventdata.IniUnitName,client) or string.match(eventdata.IniGroupName,client) then
local clientObject = CLIENTWATCHTools:_newClient(eventdata) if self.Debug then
self:Spawn(clientObject) self:I({"Client spawned in.",IniCategory = eventdata.IniCategory})
end
local clientWatchDebug = self.Debug
local clientObject = CLIENTWATCHTools:_newClient(clientWatchDebug,eventdata)
self:Spawn(clientObject,eventdata)
end end
end end
end end
@@ -222,13 +265,41 @@ function CLIENTWATCH:New(client)
return self return self
end end
--- Filter out all clients not belonging to the provided coalition
-- @param #CLIENTWATCH self
-- @param #number Coalition number (1 = red, 2 = blue)
-- @param #string Coalition string ('red' or 'blue')
function CLIENTWATCH:FilterByCoalition(value)
if value == 1 or value == "red" then
self.FilterCoalition = 1
else
self.FilterCoalition = 2
end
return self
end
--- Filter out all clients that are not of the given category
-- @param #CLIENTWATCH self
-- @param #number Category number (0 = airplane, 1 = helicopter)
-- @param #string Category string ('airplane' or 'helicopter')
function CLIENTWATCH:FilterByCategory(value)
if value == 1 or value == "helicopter" then
self.FilterCategory = 1
else
self.FilterCategory = 0
end
return self
end
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- Internal function for creating a new client on birth. Do not use!!!. --- Internal function for creating a new client on birth. Do not use!!!.
-- @param #CLIENTWATCHTools self -- @param #CLIENTWATCHTools self
-- @param #EVENTS.Birth EventData -- @param #EVENTS.Birth EventData
-- @return #CLIENTWATCHTools self -- @return #CLIENTWATCHTools self
function CLIENTWATCHTools:_newClient(eventdata) function CLIENTWATCHTools:_newClient(clientWatchDebug,eventdata)
--Init FSM --Init FSM
local self=BASE:Inherit(self, FSM:New()) local self=BASE:Inherit(self, FSM:New())
self:SetStartState( "Alive" ) self:SetStartState( "Alive" )
@@ -299,78 +370,130 @@ function CLIENTWATCHTools:_newClient(eventdata)
function self:OnEventHit(EventData) function self:OnEventHit(EventData)
if EventData.TgtUnitName == self.UnitName then if EventData.TgtUnitName == self.UnitName then
if clientWatchDebug then
self:I({"Client triggered hit event.",Player = self.PlayerName,Group = self.GroupName,Unit = self.UnitName})
end
self:Hit(EventData) self:Hit(EventData)
end end
end end
function self:OnEventKill(EventData) function self:OnEventKill(EventData)
if EventData.IniUnitName == self.UnitName then if EventData.IniUnitName == self.UnitName then
if clientWatchDebug then
self:I({"Client triggered kill event.",Player = self.PlayerName,Group = self.GroupName,Unit = self.UnitName})
end
self:Kill(EventData) self:Kill(EventData)
end end
end end
function self:OnEventScore(EventData) function self:OnEventScore(EventData)
if EventData.IniUnitName == self.UnitName then if EventData.IniUnitName == self.UnitName then
if clientWatchDebug then
self:I({"Client triggered score event.",Player = self.PlayerName,Group = self.GroupName,Unit = self.UnitName})
end
self:Score(EventData) self:Score(EventData)
end end
end end
function self:OnEventShot(EventData) function self:OnEventShot(EventData)
if EventData.IniUnitName == self.UnitName then if EventData.IniUnitName == self.UnitName then
if clientWatchDebug then
self:I({"Client triggered shot event.",Player = self.PlayerName,Group = self.GroupName,Unit = self.UnitName})
end
self:Shot(EventData) self:Shot(EventData)
end end
end end
function self:OnEventShootingStart(EventData) function self:OnEventShootingStart(EventData)
if EventData.IniUnitName == self.UnitName then if EventData.IniUnitName == self.UnitName then
if clientWatchDebug then
self:I({"Client triggered shooting start event.",Player = self.PlayerName,Group = self.GroupName,Unit = self.UnitName})
end
self:ShootingStart(EventData) self:ShootingStart(EventData)
end end
end end
function self:OnEventShootingEnd(EventData) function self:OnEventShootingEnd(EventData)
if EventData.IniUnitName == self.UnitName then if EventData.IniUnitName == self.UnitName then
if clientWatchDebug then
self:I({"Client triggered shooting end event.",Player = self.PlayerName,Group = self.GroupName,Unit = self.UnitName})
end
self:ShootingEnd(EventData) self:ShootingEnd(EventData)
end end
end end
function self:OnEventLand(EventData) function self:OnEventLand(EventData)
if EventData.IniUnitName == self.UnitName then if EventData.IniUnitName == self.UnitName then
if clientWatchDebug then
self:I({"Client triggered land event.",Player = self.PlayerName,Group = self.GroupName,Unit = self.UnitName})
end
self:Land(EventData) self:Land(EventData)
end end
end end
function self:OnEventTakeoff(EventData) function self:OnEventTakeoff(EventData)
if EventData.IniUnitName == self.UnitName then if EventData.IniUnitName == self.UnitName then
if clientWatchDebug then
self:I({"Client triggered takeoff event.",Player = self.PlayerName,Group = self.GroupName,Unit = self.UnitName})
end
self:Takeoff(EventData) self:Takeoff(EventData)
end end
end end
function self:OnEventRunwayTakeoff(EventData) function self:OnEventRunwayTakeoff(EventData)
if EventData.IniUnitName == self.UnitName then if EventData.IniUnitName == self.UnitName then
if clientWatchDebug then
self:I({"Client triggered runway takeoff event.",Player = self.PlayerName,Group = self.GroupName,Unit = self.UnitName})
end
self:RunwayTakeoff(EventData) self:RunwayTakeoff(EventData)
end end
end end
function self:OnEventRunwayTouch(EventData) function self:OnEventRunwayTouch(EventData)
if EventData.IniUnitName == self.UnitName then if EventData.IniUnitName == self.UnitName then
if clientWatchDebug then
self:I({"Client triggered runway touch event.",Player = self.PlayerName,Group = self.GroupName,Unit = self.UnitName})
end
self:RunwayTouch(EventData) self:RunwayTouch(EventData)
end end
end end
function self:OnEventRefueling(EventData) function self:OnEventRefueling(EventData)
if EventData.IniUnitName == self.UnitName then if EventData.IniUnitName == self.UnitName then
if clientWatchDebug then
self:I({"Client triggered refueling event.",Player = self.PlayerName,Group = self.GroupName,Unit = self.UnitName})
end
self:Refueling(EventData) self:Refueling(EventData)
end end
end end
function self:OnEventRefuelingStop(EventData) function self:OnEventRefuelingStop(EventData)
if EventData.IniUnitName == self.UnitName then if EventData.IniUnitName == self.UnitName then
if clientWatchDebug then
self:I({"Client triggered refueling event.",Player = self.PlayerName,Group = self.GroupName,Unit = self.UnitName})
end
self:RefuelingStop(EventData) self:RefuelingStop(EventData)
end end
end end
function self:OnEventPlayerLeaveUnit(EventData) function self:OnEventPlayerLeaveUnit(EventData)
if EventData.IniUnitName == self.UnitName then if EventData.IniUnitName == self.UnitName then
if clientWatchDebug then
self:I({"Client triggered leave unit event.",Player = self.PlayerName,Group = self.GroupName,Unit = self.UnitName})
end
self:PlayerLeaveUnit(EventData) self:PlayerLeaveUnit(EventData)
self._deadRoutine() self._deadRoutine()
end end
@@ -378,6 +501,10 @@ function CLIENTWATCHTools:_newClient(eventdata)
function self:OnEventCrash(EventData) function self:OnEventCrash(EventData)
if EventData.IniUnitName == self.UnitName then if EventData.IniUnitName == self.UnitName then
if clientWatchDebug then
self:I({"Client triggered crash event.",Player = self.PlayerName,Group = self.GroupName,Unit = self.UnitName})
end
self:Crash(EventData) self:Crash(EventData)
self._deadRoutine() self._deadRoutine()
end end
@@ -385,6 +512,10 @@ function CLIENTWATCHTools:_newClient(eventdata)
function self:OnEventDead(EventData) function self:OnEventDead(EventData)
if EventData.IniUnitName == self.UnitName then if EventData.IniUnitName == self.UnitName then
if clientWatchDebug then
self:I({"Client triggered dead event.",Player = self.PlayerName,Group = self.GroupName,Unit = self.UnitName})
end
self:Dead(EventData) self:Dead(EventData)
self._deadRoutine() self._deadRoutine()
end end
@@ -392,6 +523,10 @@ function CLIENTWATCHTools:_newClient(eventdata)
function self:OnEventPilotDead(EventData) function self:OnEventPilotDead(EventData)
if EventData.IniUnitName == self.UnitName then if EventData.IniUnitName == self.UnitName then
if clientWatchDebug then
self:I({"Client triggered pilot dead event.",Player = self.PlayerName,Group = self.GroupName,Unit = self.UnitName})
end
self:PilotDead(EventData) self:PilotDead(EventData)
self._deadRoutine() self._deadRoutine()
end end
@@ -399,6 +534,10 @@ function CLIENTWATCHTools:_newClient(eventdata)
function self:OnEventUnitLost(EventData) function self:OnEventUnitLost(EventData)
if EventData.IniUnitName == self.UnitName then if EventData.IniUnitName == self.UnitName then
if clientWatchDebug then
self:I({"Client triggered unit lost event.",Player = self.PlayerName,Group = self.GroupName,Unit = self.UnitName})
end
self:UnitLost(EventData) self:UnitLost(EventData)
self._deadRoutine() self._deadRoutine()
end end
@@ -406,6 +545,10 @@ function CLIENTWATCHTools:_newClient(eventdata)
function self:OnEventEjection(EventData) function self:OnEventEjection(EventData)
if EventData.IniUnitName == self.UnitName then if EventData.IniUnitName == self.UnitName then
if clientWatchDebug then
self:I({"Client triggered ejection event.",Player = self.PlayerName,Group = self.GroupName,Unit = self.UnitName})
end
self:Ejection(EventData) self:Ejection(EventData)
self._deadRoutine() self._deadRoutine()
end end
@@ -413,6 +556,10 @@ function CLIENTWATCHTools:_newClient(eventdata)
function self:OnEventHumanFailure(EventData) function self:OnEventHumanFailure(EventData)
if EventData.IniUnitName == self.UnitName then if EventData.IniUnitName == self.UnitName then
if clientWatchDebug then
self:I({"Client triggered human failure event.",Player = self.PlayerName,Group = self.GroupName,Unit = self.UnitName})
end
self:HumanFailure(EventData) self:HumanFailure(EventData)
if not self.Unit:IsAlive() then if not self.Unit:IsAlive() then
self._deadRoutine() self._deadRoutine()
@@ -422,42 +569,70 @@ function CLIENTWATCHTools:_newClient(eventdata)
function self:OnEventHumanAircraftRepairFinish(EventData) function self:OnEventHumanAircraftRepairFinish(EventData)
if EventData.IniUnitName == self.UnitName then if EventData.IniUnitName == self.UnitName then
if clientWatchDebug then
self:I({"Client triggered repair finished event.",Player = self.PlayerName,Group = self.GroupName,Unit = self.UnitName})
end
self:HumanAircraftRepairFinish(EventData) self:HumanAircraftRepairFinish(EventData)
end end
end end
function self:OnEventHumanAircraftRepairStart(EventData) function self:OnEventHumanAircraftRepairStart(EventData)
if EventData.IniUnitName == self.UnitName then if EventData.IniUnitName == self.UnitName then
if clientWatchDebug then
self:I({"Client triggered repair start event.",Player = self.PlayerName,Group = self.GroupName,Unit = self.UnitName})
end
self:HumanAircraftRepairStart(EventData) self:HumanAircraftRepairStart(EventData)
end end
end end
function self:OnEventEngineShutdown(EventData) function self:OnEventEngineShutdown(EventData)
if EventData.IniUnitName == self.UnitName then if EventData.IniUnitName == self.UnitName then
if clientWatchDebug then
self:I({"Client triggered engine shutdown event.",Player = self.PlayerName,Group = self.GroupName,Unit = self.UnitName})
end
self:EngineShutdown(EventData) self:EngineShutdown(EventData)
end end
end end
function self:OnEventEngineStartup(EventData) function self:OnEventEngineStartup(EventData)
if EventData.IniUnitName == self.UnitName then if EventData.IniUnitName == self.UnitName then
if clientWatchDebug then
self:I({"Client triggered engine startup event.",Player = self.PlayerName,Group = self.GroupName,Unit = self.UnitName})
end
self:EngineStartup(EventData) self:EngineStartup(EventData)
end end
end end
function self:OnEventWeaponAdd(EventData) function self:OnEventWeaponAdd(EventData)
if EventData.IniUnitName == self.UnitName then if EventData.IniUnitName == self.UnitName then
if clientWatchDebug then
self:I({"Client triggered weapon add event.",Player = self.PlayerName,Group = self.GroupName,Unit = self.UnitName})
end
self:WeaponAdd(EventData) self:WeaponAdd(EventData)
end end
end end
function self:OnEventWeaponDrop(EventData) function self:OnEventWeaponDrop(EventData)
if EventData.IniUnitName == self.UnitName then if EventData.IniUnitName == self.UnitName then
if clientWatchDebug then
self:I({"Client triggered weapon drop event.",Player = self.PlayerName,Group = self.GroupName,Unit = self.UnitName})
end
self:WeaponDrop(EventData) self:WeaponDrop(EventData)
end end
end end
function self:OnEventWeaponRearm(EventData) function self:OnEventWeaponRearm(EventData)
if EventData.IniUnitName == self.UnitName then if EventData.IniUnitName == self.UnitName then
if clientWatchDebug then
self:I({"Client triggered weapon rearm event.",Player = self.PlayerName,Group = self.GroupName,Unit = self.UnitName})
end
self:WeaponRearm(EventData) self:WeaponRearm(EventData)
end end
end end
@@ -466,6 +641,9 @@ function CLIENTWATCHTools:_newClient(eventdata)
--Fallback timer --Fallback timer
self.FallbackTimer = TIMER:New(function() self.FallbackTimer = TIMER:New(function()
if not self.Unit:IsAlive() then if not self.Unit:IsAlive() then
if clientWatchDebug then
self:I({"Client is registered as dead without an event trigger. Running fallback dead routine.",Player = self.PlayerName,Group = self.GroupName,Unit = self.UnitName})
end
self._deadRoutine() self._deadRoutine()
end end
end) end)
@@ -473,6 +651,7 @@ function CLIENTWATCHTools:_newClient(eventdata)
--Stop event handlers and trigger Despawn --Stop event handlers and trigger Despawn
function self._deadRoutine() function self._deadRoutine()
if clientWatchDebug then self:I({"Client dead routine triggered. Shutting down tracking...",Player = self.PlayerName,Group = self.GroupName,Unit = self.UnitName}) end
self:UnHandleEvent( EVENTS.Hit ) self:UnHandleEvent( EVENTS.Hit )
self:UnHandleEvent( EVENTS.Kill ) self:UnHandleEvent( EVENTS.Kill )
self:UnHandleEvent( EVENTS.Score ) self:UnHandleEvent( EVENTS.Score )
@@ -503,6 +682,6 @@ function CLIENTWATCHTools:_newClient(eventdata)
self:Despawn() self:Despawn()
end end
self:I({"CLIENT SPAWN EVENT", PlayerName = self.PlayerName, UnitName = self.UnitName, GroupName = self.GroupName}) self:I({"Detected client spawn and applied internal functions and events.", PlayerName = self.PlayerName, UnitName = self.UnitName, GroupName = self.GroupName})
return self return self
end end
@@ -596,6 +596,7 @@ do -- DETECTION_BASE
return self return self
end end
---
-- @param #DETECTION_BASE self -- @param #DETECTION_BASE self
-- @param #string From The From State string. -- @param #string From The From State string.
-- @param #string Event The Event string. -- @param #string Event The Event string.
@@ -615,7 +616,7 @@ do -- DETECTION_BASE
self:T( { "DetectionGroup is Alive", Detection:GetName() } ) self:T( { "DetectionGroup is Alive", Detection:GetName() } )
local DetectionGroupName = Detection:GetName() local DetectionGroupName = Detection:GetName()
local DetectionUnit = Detection:GetUnit( 1 ) local DetectionUnit = Detection:GetFirstUnitAlive()
local DetectedUnits = {} local DetectedUnits = {}
@@ -632,7 +633,7 @@ do -- DETECTION_BASE
--self:T(UTILS.PrintTableToLog(DetectedTargets)) --self:T(UTILS.PrintTableToLog(DetectedTargets))
for DetectionObjectID, Detection in pairs( DetectedTargets ) do for DetectionObjectID, Detection in pairs( DetectedTargets or {}) do
local DetectedObject = Detection.object -- DCS#Object local DetectedObject = Detection.object -- DCS#Object
if DetectedObject and DetectedObject:isExist() and DetectedObject.id_ < 50000000 then -- and ( DetectedObject:getCategory() == Object.Category.UNIT or DetectedObject:getCategory() == Object.Category.STATIC ) then if DetectedObject and DetectedObject:isExist() and DetectedObject.id_ < 50000000 then -- and ( DetectedObject:getCategory() == Object.Category.UNIT or DetectedObject:getCategory() == Object.Category.STATIC ) then
@@ -645,13 +646,13 @@ do -- DETECTION_BASE
end end
end end
for DetectionObjectName, DetectedObjectData in pairs( self.DetectedObjects ) do for DetectionObjectName, DetectedObjectData in pairs( self.DetectedObjects or {}) do
local DetectedObject = DetectedObjectData.Object local DetectedObject = DetectedObjectData.Object
if DetectedObject:isExist() then if DetectedObject:isExist() then
local TargetIsDetected, TargetIsVisible, TargetLastTime, TargetKnowType, TargetKnowDistance, TargetLastPos, TargetLastVelocity = DetectionUnit:IsTargetDetected( local TargetIsDetected, TargetIsVisible, TargetKnowType, TargetKnowDistance, TargetLastTime, TargetLastPos, TargetLastVelocity = DetectionUnit:IsTargetDetected(
DetectedObject, DetectedObject,
self.DetectVisual, self.DetectVisual,
self.DetectOptical, self.DetectOptical,
@@ -1154,8 +1154,6 @@ function ESCORT:_ReportTargetsScheduler()
if self.EscortGroup:IsAlive() and self.EscortClient:IsAlive() then if self.EscortGroup:IsAlive() and self.EscortClient:IsAlive() then
if true then
local EscortGroupName = self.EscortGroup:GetName() local EscortGroupName = self.EscortGroup:GetName()
self.EscortMenuAttackNearbyTargets:RemoveSubMenus() self.EscortMenuAttackNearbyTargets:RemoveSubMenus()
@@ -1226,177 +1224,6 @@ function ESCORT:_ReportTargetsScheduler()
end end
return true return true
else
-- local EscortGroupName = self.EscortGroup:GetName()
-- local EscortTargets = self.EscortGroup:GetDetectedTargets()
--
-- local ClientEscortTargets = self.EscortClient._EscortGroups[EscortGroupName].Targets
--
-- local EscortTargetMessages = ""
-- for EscortTargetID, EscortTarget in pairs( EscortTargets ) do
-- local EscortObject = EscortTarget.object
-- self:T( EscortObject )
-- if EscortObject and EscortObject:isExist() and EscortObject.id_ < 50000000 then
--
-- local EscortTargetUnit = UNIT:Find( EscortObject )
-- local EscortTargetUnitName = EscortTargetUnit:GetName()
--
--
--
-- -- local EscortTargetIsDetected,
-- -- EscortTargetIsVisible,
-- -- EscortTargetLastTime,
-- -- EscortTargetKnowType,
-- -- EscortTargetKnowDistance,
-- -- EscortTargetLastPos,
-- -- EscortTargetLastVelocity
-- -- = self.EscortGroup:IsTargetDetected( EscortObject )
-- --
-- -- self:T( { EscortTargetIsDetected,
-- -- EscortTargetIsVisible,
-- -- EscortTargetLastTime,
-- -- EscortTargetKnowType,
-- -- EscortTargetKnowDistance,
-- -- EscortTargetLastPos,
-- -- EscortTargetLastVelocity } )
--
--
-- local EscortTargetUnitVec3 = EscortTargetUnit:GetVec3()
-- local EscortVec3 = self.EscortGroup:GetVec3()
-- local Distance = ( ( EscortTargetUnitVec3.x - EscortVec3.x )^2 +
-- ( EscortTargetUnitVec3.y - EscortVec3.y )^2 +
-- ( EscortTargetUnitVec3.z - EscortVec3.z )^2
-- ) ^ 0.5 / 1000
--
-- self:T( { self.EscortGroup:GetName(), EscortTargetUnit:GetName(), Distance, EscortTarget } )
--
-- if Distance <= 15 then
--
-- if not ClientEscortTargets[EscortTargetUnitName] then
-- ClientEscortTargets[EscortTargetUnitName] = {}
-- end
-- ClientEscortTargets[EscortTargetUnitName].AttackUnit = EscortTargetUnit
-- ClientEscortTargets[EscortTargetUnitName].visible = EscortTarget.visible
-- ClientEscortTargets[EscortTargetUnitName].type = EscortTarget.type
-- ClientEscortTargets[EscortTargetUnitName].distance = EscortTarget.distance
-- else
-- if ClientEscortTargets[EscortTargetUnitName] then
-- ClientEscortTargets[EscortTargetUnitName] = nil
-- end
-- end
-- end
-- end
--
-- self:T( { "Sorting Targets Table:", ClientEscortTargets } )
-- table.sort( ClientEscortTargets, function( a, b ) return a.Distance < b.Distance end )
-- self:T( { "Sorted Targets Table:", ClientEscortTargets } )
--
-- -- Remove the sub menus of the Attack menu of the Escort for the EscortGroup.
-- self.EscortMenuAttackNearbyTargets:RemoveSubMenus()
--
-- if self.EscortMenuTargetAssistance then
-- self.EscortMenuTargetAssistance:RemoveSubMenus()
-- end
--
-- --for MenuIndex = 1, #self.EscortMenuAttackTargets do
-- -- self:T( { "Remove Menu:", self.EscortMenuAttackTargets[MenuIndex] } )
-- -- self.EscortMenuAttackTargets[MenuIndex] = self.EscortMenuAttackTargets[MenuIndex]:Remove()
-- --end
--
--
-- if ClientEscortTargets then
-- for ClientEscortTargetUnitName, ClientEscortTargetData in pairs( ClientEscortTargets ) do
--
-- for ClientEscortGroupName, EscortGroupData in pairs( self.EscortClient._EscortGroups ) do
--
-- if ClientEscortTargetData and ClientEscortTargetData.AttackUnit:IsAlive() then
--
-- local EscortTargetMessage = ""
-- local EscortTargetCategoryName = ClientEscortTargetData.AttackUnit:GetCategoryName()
-- local EscortTargetCategoryType = ClientEscortTargetData.AttackUnit:GetTypeName()
-- if ClientEscortTargetData.type then
-- EscortTargetMessage = EscortTargetMessage .. EscortTargetCategoryName .. " (" .. EscortTargetCategoryType .. ") at "
-- else
-- EscortTargetMessage = EscortTargetMessage .. "Unknown target at "
-- end
--
-- local EscortTargetUnitVec3 = ClientEscortTargetData.AttackUnit:GetVec3()
-- local EscortVec3 = self.EscortGroup:GetVec3()
-- local Distance = ( ( EscortTargetUnitVec3.x - EscortVec3.x )^2 +
-- ( EscortTargetUnitVec3.y - EscortVec3.y )^2 +
-- ( EscortTargetUnitVec3.z - EscortVec3.z )^2
-- ) ^ 0.5 / 1000
--
-- self:T( { self.EscortGroup:GetName(), ClientEscortTargetData.AttackUnit:GetName(), Distance, ClientEscortTargetData.AttackUnit } )
-- if ClientEscortTargetData.visible == false then
-- EscortTargetMessage = EscortTargetMessage .. string.format( "%.2f", Distance ) .. " estimated km"
-- else
-- EscortTargetMessage = EscortTargetMessage .. string.format( "%.2f", Distance ) .. " km"
-- end
--
-- if ClientEscortTargetData.visible then
-- EscortTargetMessage = EscortTargetMessage .. ", visual"
-- end
--
-- if ClientEscortGroupName == EscortGroupName then
--
-- MENU_GROUP_COMMAND:New( self.EscortClient,
-- EscortTargetMessage,
-- self.EscortMenuAttackNearbyTargets,
-- ESCORT._AttackTarget,
-- { ParamSelf = self,
-- ParamUnit = ClientEscortTargetData.AttackUnit
-- }
-- )
-- EscortTargetMessages = EscortTargetMessages .. "\n - " .. EscortTargetMessage
-- else
-- if self.EscortMenuTargetAssistance then
-- local MenuTargetAssistance = MENU_GROUP:New( self.EscortClient, EscortGroupData.EscortName, self.EscortMenuTargetAssistance )
-- MENU_GROUP_COMMAND:New( self.EscortClient,
-- EscortTargetMessage,
-- MenuTargetAssistance,
-- ESCORT._AssistTarget,
-- self,
-- EscortGroupData.EscortGroup,
-- ClientEscortTargetData.AttackUnit
-- )
-- end
-- end
-- else
-- ClientEscortTargetData = nil
-- end
-- end
-- end
--
-- if EscortTargetMessages ~= "" and self.ReportTargets == true then
-- self.EscortGroup:MessageToClient( "Detected targets within 15 km range:" .. EscortTargetMessages:gsub("\n$",""), 20, self.EscortClient )
-- else
-- self.EscortGroup:MessageToClient( "No targets detected!", 20, self.EscortClient )
-- end
-- end
--
-- if self.EscortMenuResumeMission then
-- self.EscortMenuResumeMission:RemoveSubMenus()
--
-- -- if self.EscortMenuResumeWayPoints then
-- -- for MenuIndex = 1, #self.EscortMenuResumeWayPoints do
-- -- self:T( { "Remove Menu:", self.EscortMenuResumeWayPoints[MenuIndex] } )
-- -- self.EscortMenuResumeWayPoints[MenuIndex] = self.EscortMenuResumeWayPoints[MenuIndex]:Remove()
-- -- end
-- -- end
--
-- local TaskPoints = self:RegisterRoute()
-- for WayPointID, WayPoint in pairs( TaskPoints ) do
-- local EscortVec3 = self.EscortGroup:GetVec3()
-- local Distance = ( ( WayPoint.x - EscortVec3.x )^2 +
-- ( WayPoint.y - EscortVec3.z )^2
-- ) ^ 0.5 / 1000
-- MENU_GROUP_COMMAND:New( self.EscortClient, "Waypoint " .. WayPointID .. " at " .. string.format( "%.2f", Distance ).. "km", self.EscortMenuResumeMission, ESCORT._ResumeMission, { ParamSelf = self, ParamWayPoint = WayPointID } )
-- end
-- end
--
-- return true
end
end end
return false return false
+1 -1
View File
@@ -1060,7 +1060,7 @@ function FOX:onafterMissileLaunch(From, Event, To, missile)
-- Tracking info and init of last bomb position. -- Tracking info and init of last bomb position.
local text=string.format("FOX: Tracking missile %s(%s) - target %s - shooter %s", missile.missileType, missile.missileName, tostring(missile.targetName), missile.shooterName) local text=string.format("FOX: Tracking missile %s(%s) - target %s - shooter %s", missile.missileType, missile.missileName, tostring(missile.targetName), missile.shooterName)
self:I(FOX.lid..text) self:T(FOX.lid..text)
MESSAGE:New(text, 10):ToAllIf(self.Debug) MESSAGE:New(text, 10):ToAllIf(self.Debug)
-- Loop over players. -- Loop over players.
File diff suppressed because it is too large Load Diff
@@ -53,6 +53,8 @@
-- --
-- # Developer Note -- # 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. -- 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. -- 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.
-- --
+9 -4
View File
@@ -3814,15 +3814,20 @@ function RAT:Status(message, forID)
local N0units=group:GetInitialSize() local N0units=group:GetInitialSize()
-- Monitor travelled distance since last check. -- Monitor travelled distance since last check.
local Pnow=coords local Dtravel=0
local Dtravel=Pnow:Get2DDistance(ratcraft.Pnow) if coords and ratcraft.Pnow then
ratcraft.Pnow=Pnow local Dtravel=coords:Get2DDistance(ratcraft.Pnow)
ratcraft.Pnow=coords
end
-- Add up the travelled distance. -- Add up the travelled distance.
ratcraft.Distance=ratcraft.Distance+Dtravel ratcraft.Distance=ratcraft.Distance+Dtravel
-- Distance remaining to destination. -- Distance remaining to destination.
local Ddestination=Pnow:Get2DDistance(ratcraft.destination:GetCoordinate()) local Ddestination=-1
if ratcraft.Pnow then
Ddestination=ratcraft.Pnow:Get2DDistance(ratcraft.destination:GetCoordinate())
end
-- Status report. -- Status report.
if (forID and spawnindex==forID) or (not forID) then if (forID and spawnindex==forID) or (not forID) then
+79 -34
View File
@@ -107,6 +107,9 @@
-- @field Sound.SRS#MSRSQUEUE instructsrsQ SRS queue for range instructor. -- @field Sound.SRS#MSRSQUEUE instructsrsQ SRS queue for range instructor.
-- @field #number Coalition Coalition side for the menu, if any. -- @field #number Coalition Coalition side for the menu, if any.
-- @field Core.Menu#MENU_MISSION menuF10root Specific user defined root F10 menu. -- @field Core.Menu#MENU_MISSION menuF10root Specific user defined root F10 menu.
-- @field #number ceilingaltitude Range ceiling altitude in ft MSL. Aircraft above this altitude are not considered to be in the range. Default is 20000 ft.
-- @field #boolean ceilingenabled Range has a ceiling and is not unlimited. Default is false.
-- @extends Core.Fsm#FSM -- @extends Core.Fsm#FSM
--- *Don't only practice your art, but force your way into its secrets; art deserves that, for it and knowledge can raise man to the Divine.* - Ludwig van Beethoven --- *Don't only practice your art, but force your way into its secrets; art deserves that, for it and knowledge can raise man to the Divine.* - Ludwig van Beethoven
@@ -273,6 +276,10 @@
-- -- Create a range object. -- -- Create a range object.
-- GoldwaterRange=RANGE:New("Goldwater Range") -- GoldwaterRange=RANGE:New("Goldwater Range")
-- --
-- -- Set and enable the range ceiling altitude in feet MSL. If aircraft are above this altitude they are not considered to be in the range.
-- GoldwaterRange:SetRangeCeiling(20000)
-- GoldwaterRange:EnableRangeCeiling(true)
--
-- -- Distance between strafe target and foul line. You have to specify the names of the unit or static objects. -- -- Distance between strafe target and foul line. You have to specify the names of the unit or static objects.
-- -- Note that this could also be done manually by simply measuring the distance between the target and the foul line in the ME. -- -- Note that this could also be done manually by simply measuring the distance between the target and the foul line in the ME.
-- GoldwaterRange:GetFoullineDistance("GWR Strafe Pit Left 1", "GWR Foul Line Left") -- GoldwaterRange:GetFoullineDistance("GWR Strafe Pit Left 1", "GWR Foul Line Left")
@@ -358,6 +365,8 @@ RANGE = {
targetpath = nil, targetpath = nil,
targetprefix = nil, targetprefix = nil,
Coalition = nil, Coalition = nil,
ceilingaltitude = 20000,
ceilingenabled = false,
} }
--- Default range parameters. --- Default range parameters.
@@ -594,7 +603,7 @@ RANGE.MenuF10Root = nil
--- Range script version. --- Range script version.
-- @field #string version -- @field #string version
RANGE.version = "2.8.0" RANGE.version = "2.8.1"
-- TODO list: -- TODO list:
-- TODO: Verbosity level for messages. -- TODO: Verbosity level for messages.
@@ -1085,6 +1094,37 @@ function RANGE:SetRangeZone( zone )
return self return self
end end
--- Set range ceiling altitude in feet MSL.
-- @param #RANGE self
-- @param #number altitude (optional) Ceiling altitude of the range in ft MSL. Default 20000ft MSL
-- @return #RANGE self
function RANGE:SetRangeCeiling( altitude )
self:T(self.lid.."SetRangeCeiling")
if altitude and type(altitude) == "number" then
self.ceilingaltitude=altitude
else
self:E(self.lid.."Altitude either not provided or is not a number, using default setting (20000).")
self.ceilingaltitude=20000
end
return self
end
--- Enable range ceiling. Aircraft must be below the ceiling altitude to be considered in the range zone.
-- @param #RANGE self
-- @param #boolean enabled True if you would like to enable the ceiling check. If no value give, will Default to false.
-- @return #RANGE self
function RANGE:EnableRangeCeiling( enabled )
self:T(self.lid.."EnableRangeCeiling")
if enabled and type(enabled) == "boolean" then
self.ceilingenabled=enabled
else
self:E(self.lid.."Enabled either not provide or is not a boolean, using default setting (false).")
self.ceilingenabled=false
end
return self
end
--- Set smoke color for marking bomb targets. By default bomb targets are marked by red smoke. --- Set smoke color for marking bomb targets. By default bomb targets are marked by red smoke.
-- @param #RANGE self -- @param #RANGE self
-- @param Utilities.Utils#SMOKECOLOR colorid Color id. Default `SMOKECOLOR.Red`. -- @param Utilities.Utils#SMOKECOLOR colorid Color id. Default `SMOKECOLOR.Red`.
@@ -1340,7 +1380,7 @@ end
-- @return #RANGE self -- @return #RANGE self
function RANGE:SetSoundfilesPath( path ) function RANGE:SetSoundfilesPath( path )
self.soundpath = tostring( path or "Range Soundfiles/" ) self.soundpath = tostring( path or "Range Soundfiles/" )
self:I( self.lid .. string.format( "Setting sound files path to %s", self.soundpath ) ) self:T2( self.lid .. string.format( "Setting sound files path to %s", self.soundpath ) )
return self return self
end end
@@ -1636,9 +1676,9 @@ function RANGE:AddBombingTargetUnit( unit, goodhitrange, randommove )
-- Debug or error output. -- Debug or error output.
if _isstatic == true then if _isstatic == true then
self:I( self.lid .. string.format( "Adding STATIC bombing target %s with good hit range %d. Random move = %s.", name, goodhitrange, tostring( randommove ) ) ) self:T( self.lid .. string.format( "Adding STATIC bombing target %s with good hit range %d. Random move = %s.", name, goodhitrange, tostring( randommove ) ) )
elseif _isstatic == false then elseif _isstatic == false then
self:I( self.lid .. string.format( "Adding UNIT bombing target %s with good hit range %d. Random move = %s.", name, goodhitrange, tostring( randommove ) ) ) self:T( self.lid .. string.format( "Adding UNIT bombing target %s with good hit range %d. Random move = %s.", name, goodhitrange, tostring( randommove ) ) )
else else
self:E( self.lid .. string.format( "ERROR! No bombing target with name %s could be found. Carefully check all UNIT and STATIC names defined in the mission editor!", name ) ) self:E( self.lid .. string.format( "ERROR! No bombing target with name %s could be found. Carefully check all UNIT and STATIC names defined in the mission editor!", name ) )
end end
@@ -1706,7 +1746,7 @@ function RANGE:AddBombingTargetScenery( scenery, goodhitrange)
-- Debug or error output. -- Debug or error output.
if name then if name then
self:I( self.lid .. string.format( "Adding SCENERY bombing target %s with good hit range %d", name, goodhitrange) ) self:T( self.lid .. string.format( "Adding SCENERY bombing target %s with good hit range %d", name, goodhitrange) )
else else
self:E( self.lid .. string.format( "ERROR! No bombing target with name %s could be found!", name ) ) self:E( self.lid .. string.format( "ERROR! No bombing target with name %s could be found!", name ) )
end end
@@ -1811,7 +1851,7 @@ function RANGE:OnEventBirth( EventData )
if not EventData.IniPlayerName then return end if not EventData.IniPlayerName then return end
local _unitName = EventData.IniUnitName local _unitName = EventData.IniUnitName
local _unit, _playername = self:_GetPlayerUnitAndName( _unitName ) local _unit, _playername = self:_GetPlayerUnitAndName( _unitName, EventData.IniPlayerName )
self:T3( self.lid .. "BIRTH: unit = " .. tostring( EventData.IniUnitName ) ) self:T3( self.lid .. "BIRTH: unit = " .. tostring( EventData.IniUnitName ) )
self:T3( self.lid .. "BIRTH: group = " .. tostring( EventData.IniGroupName ) ) self:T3( self.lid .. "BIRTH: group = " .. tostring( EventData.IniGroupName ) )
@@ -1893,7 +1933,7 @@ function RANGE:OnEventHit( EventData )
local _currentTarget = self.strafeStatus[_unitID] --#RANGE.StrafeStatus local _currentTarget = self.strafeStatus[_unitID] --#RANGE.StrafeStatus
-- Player has rolled in on a strafing target. -- Player has rolled in on a strafing target.
if _currentTarget and target:IsAlive() then if _currentTarget and target and target:IsAlive() then
local playerPos = _unit:GetCoordinate() local playerPos = _unit:GetCoordinate()
local targetPos = target:GetCoordinate() local targetPos = target:GetCoordinate()
@@ -1968,6 +2008,8 @@ end
-- @param #number attackVel Attack velocity. -- @param #number attackVel Attack velocity.
function RANGE._OnImpact(weapon, self, playerData, attackHdg, attackAlt, attackVel) function RANGE._OnImpact(weapon, self, playerData, attackHdg, attackAlt, attackVel)
if not playerData then return end
-- Get closet target to last position. -- Get closet target to last position.
local _closetTarget = nil -- #RANGE.BombTarget local _closetTarget = nil -- #RANGE.BombTarget
local _distance = nil local _distance = nil
@@ -1984,16 +2026,16 @@ function RANGE._OnImpact(weapon, self, playerData, attackHdg, attackAlt, attackV
-- Coordinate of impact point. -- Coordinate of impact point.
local impactcoord = weapon:GetImpactCoordinate() local impactcoord = weapon:GetImpactCoordinate()
-- Check if impact happened in range zone. -- Check if impact happened in range zone.+
local insidezone = self.rangezone:IsCoordinateInZone( impactcoord ) local insidezone = self.rangezone:IsCoordinateInZone( impactcoord )
-- Smoke impact point of bomb. -- Smoke impact point of bomb.
if playerData.smokebombimpact and insidezone then if playerData and playerData.smokebombimpact and insidezone then
if playerData.delaysmoke then if playerData.delaysmoke then
timer.scheduleFunction( self._DelayedSmoke, { coord = impactcoord, color = playerData.smokecolor }, timer.getTime() + self.TdelaySmoke ) impactcoord:Smoke(playerData.smokecolor, 30, self.TdelaySmoke)
else else
impactcoord:Smoke( playerData.smokecolor ) impactcoord:Smoke(playerData.smokecolor, 30)
end end
end end
@@ -2060,7 +2102,12 @@ function RANGE._OnImpact(weapon, self, playerData, attackHdg, attackAlt, attackV
result.attackHdg = attackHdg result.attackHdg = attackHdg
result.attackVel = attackVel result.attackVel = attackVel
result.attackAlt = attackAlt 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. -- Add to table.
table.insert( _results, result ) table.insert( _results, result )
@@ -2115,7 +2162,7 @@ function RANGE:OnEventShot( EventData )
local _unitName = EventData.IniUnitName local _unitName = EventData.IniUnitName
-- Get player unit and name. -- Get player unit and name.
local _unit, _playername = self:_GetPlayerUnitAndName( _unitName ) local _unit, _playername = self:_GetPlayerUnitAndName( _unitName, EventData.IniPlayerName )
-- Distance Player-to-Range. Set this to larger value than the threshold. -- Distance Player-to-Range. Set this to larger value than the threshold.
local dPR = self.BombtrackThreshold * 2 local dPR = self.BombtrackThreshold * 2
@@ -2127,11 +2174,13 @@ function RANGE:OnEventShot( EventData )
end end
-- Only track if distance player to range is < 25 km. Also check that a player shot. No need to track AI weapons. -- Only track if distance player to range is < 25 km. Also check that a player shot. No need to track AI weapons.
if _track and dPR <= self.BombtrackThreshold and _unit and _playername then if _track and dPR <= self.BombtrackThreshold and _unit and _playername and self.PlayerSettings[_playername] then
-- Player data. -- Player data.
local playerData = self.PlayerSettings[_playername] -- #RANGE.PlayerData local playerData = self.PlayerSettings[_playername] -- #RANGE.PlayerData
if not playerData then return end
-- Attack parameters. -- Attack parameters.
local attackHdg=_unit:GetHeading() local attackHdg=_unit:GetHeading()
local attackAlt=_unit:GetHeight() local attackAlt=_unit:GetHeight()
@@ -2192,7 +2241,7 @@ function RANGE:onafterStatus( From, Event, To )
end end
-- Check range status. -- Check range status.
self:I( self.lid .. text ) self:T( self.lid .. text )
end end
@@ -2393,7 +2442,7 @@ function RANGE:onafterSave( From, Event, To )
if f then if f then
f:write( data ) f:write( data )
f:close() f:close()
self:I( self.lid .. string.format( "Saving player results to file %s", tostring( filename ) ) ) self:T( self.lid .. string.format( "Saving player results to file %s", tostring( filename ) ) )
else else
self:E( self.lid .. string.format( "ERROR: Could not save results to file %s", tostring( filename ) ) ) self:E( self.lid .. string.format( "ERROR: Could not save results to file %s", tostring( filename ) ) )
end end
@@ -2472,7 +2521,7 @@ function RANGE:onafterLoad( From, Event, To )
-- Info message. -- Info message.
local text = string.format( "Loading player bomb results from file %s", filename ) local text = string.format( "Loading player bomb results from file %s", filename )
self:I( self.lid .. text ) self:T( self.lid .. text )
-- Load asset data from file. -- Load asset data from file.
local data = _loadfile( filename ) local data = _loadfile( filename )
@@ -2591,13 +2640,6 @@ end
-- Display Messages -- Display Messages
----------------------------------------------------------------------------------------------------------------------------------------------------------------------- -----------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- Start smoking a coordinate with a delay.
-- @param #table _args Argements passed.
function RANGE._DelayedSmoke( _args )
_args.coord:Smoke(_args.color)
--trigger.action.smoke( _args.coord:GetVec3(), _args.color )
end
--- Display top 10 stafing results of a specific player. --- Display top 10 stafing results of a specific player.
-- @param #RANGE self -- @param #RANGE self
-- @param #string _unitName Name of the player unit. -- @param #string _unitName Name of the player unit.
@@ -2845,7 +2887,7 @@ function RANGE:_DisplayRangeInfo( _unitname )
-- Check if we have a player. -- Check if we have a player.
if unit and playername then if unit and playername then
self:I(playername) --self:I(playername)
-- Message text. -- Message text.
local text = "" local text = ""
@@ -2983,7 +3025,7 @@ function RANGE:_DisplayBombTargets( _unitname )
end end
end end
self:_DisplayMessageToGroup( _unit, _text, 120, true, true, _multiplayer ) self:_DisplayMessageToGroup( _unit, _text, 150, true, true, _multiplayer )
end end
end end
@@ -3108,7 +3150,10 @@ function RANGE:_CheckPlayers()
if unit and unit:IsAlive() then if unit and unit:IsAlive() then
if unit:IsInZone( self.rangezone ) then local unitalt = unit:GetAltitude(false)
local unitaltinfeet = UTILS.MetersToFeet(unitalt)
if unit:IsInZone(self.rangezone) and (not self.ceilingenabled or unitaltinfeet < self.ceilingaltitude) then
------------------------------ ------------------------------
-- Player INSIDE Range Zone -- -- Player INSIDE Range Zone --
@@ -3449,10 +3494,10 @@ function RANGE:_AddF10Commands( _unitName )
-- Range menu -- Range menu
local _rangePath = MENU_GROUP:New( group, self.rangename, _rootMenu ) local _rangePath = MENU_GROUP:New( group, self.rangename, _rootMenu )
local _statsPath = MENU_GROUP:New( group, "Statistics", _rangePath )
local _markPath = MENU_GROUP:New( group, "Mark Targets", _rangePath )
local _settingsPath = MENU_GROUP:New( group, "My Settings", _rangePath )
local _infoPath = MENU_GROUP:New( group, "Range Info", _rangePath ) local _infoPath = MENU_GROUP:New( group, "Range Info", _rangePath )
local _markPath = MENU_GROUP:New( group, "Mark Targets", _rangePath )
local _statsPath = MENU_GROUP:New( group, "Statistics", _rangePath )
local _settingsPath = MENU_GROUP:New( group, "My Settings", _rangePath )
-- F10/On the Range/<Range Name>/My Settings/ -- F10/On the Range/<Range Name>/My Settings/
local _mysmokePath = MENU_GROUP:New( group, "Smoke Color", _settingsPath ) local _mysmokePath = MENU_GROUP:New( group, "Smoke Color", _settingsPath )
@@ -4099,8 +4144,8 @@ end
-- @return Wrapper.Unit#UNIT Unit of player. -- @return Wrapper.Unit#UNIT Unit of player.
-- @return #string Name of the player. -- @return #string Name of the player.
-- @return #boolean If true, group has > 1 player in it -- @return #boolean If true, group has > 1 player in it
function RANGE:_GetPlayerUnitAndName( _unitName ) function RANGE:_GetPlayerUnitAndName( _unitName, PlayerName )
self:F2( _unitName ) --self:I( _unitName )
if _unitName ~= nil then if _unitName ~= nil then
@@ -4109,9 +4154,9 @@ function RANGE:_GetPlayerUnitAndName( _unitName )
-- Get DCS unit from its name. -- Get DCS unit from its name.
local DCSunit = Unit.getByName( _unitName ) local DCSunit = Unit.getByName( _unitName )
if DCSunit then if DCSunit and DCSunit.getPlayerName then
local playername = DCSunit:getPlayerName() local playername = DCSunit:getPlayerName() or PlayerName or "None"
local unit = UNIT:Find( DCSunit ) local unit = UNIT:Find( DCSunit )
self:T2( { DCSunit = DCSunit, unit = unit, playername = playername } ) self:T2( { DCSunit = DCSunit, unit = unit, playername = playername } )
+18 -4
View File
@@ -320,8 +320,10 @@ function SCORING:New( GameName, SavePath, AutoSave )
-- Create the CSV file. -- Create the CSV file.
self.AutoSavePath = SavePath self.AutoSavePath = SavePath
self.AutoSave = AutoSave or true self.AutoSave = (AutoSave == nil or AutoSave == true) and true or false
if self.AutoSavePath and self.AutoSave == true then
self:OpenCSV( GameName ) self:OpenCSV( GameName )
end
return self return self
@@ -985,6 +987,7 @@ function SCORING:_EventOnHit( Event )
local TargetUnitCoalition = nil local TargetUnitCoalition = nil
local TargetUnitCategory = nil local TargetUnitCategory = nil
local TargetUnitType = nil local TargetUnitType = nil
local TargetIsScenery = false
if Event.IniDCSUnit then if Event.IniDCSUnit then
@@ -1025,6 +1028,12 @@ function SCORING:_EventOnHit( Event )
TargetCategory = Event.TgtCategory TargetCategory = Event.TgtCategory
TargetType = Event.TgtTypeName TargetType = Event.TgtTypeName
-- Scenery hit
if (not TargetCategory) and TargetUNIT ~= nil and TargetUnit:IsInstanceOf("SCENERY") then
TargetCategory = Unit.Category.STRUCTURE
TargetIsScenery = true
end
TargetUnitCoalition = _SCORINGCoalition[TargetCoalition] TargetUnitCoalition = _SCORINGCoalition[TargetCoalition]
TargetUnitCategory = _SCORINGCategory[TargetCategory] TargetUnitCategory = _SCORINGCategory[TargetCategory]
TargetUnitType = TargetType TargetUnitType = TargetType
@@ -1117,17 +1126,22 @@ function SCORING:_EventOnHit( Event )
MESSAGE.Type.Update ) MESSAGE.Type.Update )
:ToAllIf( self:IfMessagesHit() and self:IfMessagesToAll() ) :ToAllIf( self:IfMessagesHit() and self:IfMessagesToAll() )
:ToCoalitionIf( InitCoalition, self:IfMessagesHit() and self:IfMessagesToCoalition() ) :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. " .. MESSAGE:NewType( self.DisplayMessagePrefix .. "Player '" .. InitPlayerName .. "' hit enemy target " .. TargetUnitCategory .. " ( " .. TargetType .. " ) " .. PlayerHit.ScoreHit .. " times. " ..
"Score: " .. PlayerHit.Score .. ". Score Total:" .. Player.Score - Player.Penalty, "Score: " .. PlayerHit.Score .. ". Score Total:" .. Player.Score - Player.Penalty,
MESSAGE.Type.Update ) MESSAGE.Type.Update )
:ToAllIf( self:IfMessagesHit() and self:IfMessagesToAll() ) :ToAllIf( self:IfMessagesHit() and self:IfMessagesToAll() )
:ToCoalitionIf( InitCoalition, self:IfMessagesHit() and self:IfMessagesToCoalition() ) :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 end
self:ScoreCSV( InitPlayerName, TargetPlayerName, "HIT_SCORE", 1, 1, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType ) self:ScoreCSV( InitPlayerName, TargetPlayerName, "HIT_SCORE", 1, 1, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType )
end end
else -- A scenery object was hit. 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 ) MESSAGE.Type.Update )
:ToAllIf( self:IfMessagesHit() and self:IfMessagesToAll() ) :ToAllIf( self:IfMessagesHit() and self:IfMessagesToAll() )
:ToCoalitionIf( InitCoalition, self:IfMessagesHit() and self:IfMessagesToCoalition() ) :ToCoalitionIf( InitCoalition, self:IfMessagesHit() and self:IfMessagesToCoalition() )
@@ -1923,7 +1937,7 @@ function SCORING:ScoreCSV( PlayerName, TargetPlayerName, ScoreType, ScoreTimes,
TargetUnitType = TargetUnitType or "" TargetUnitType = TargetUnitType or ""
TargetUnitName = TargetUnitName 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.CSVFile:write(
'"' .. self.GameName .. '"' .. ',' .. '"' .. self.GameName .. '"' .. ',' ..
'"' .. self.RunTime .. '"' .. ',' .. '"' .. self.RunTime .. '"' .. ',' ..
+34 -12
View File
@@ -19,7 +19,7 @@
-- --
-- ### Authors: **applevangelist**, **FlightControl** -- ### Authors: **applevangelist**, **FlightControl**
-- --
-- Last Update: Dec 2023 -- Last Update: Dec 2024
-- --
-- === -- ===
-- --
@@ -28,6 +28,16 @@
--- ---
-- @type SEAD -- @type SEAD
-- @field #string ClassName The Class Name.
-- @field #table TargetSkill Table of target skills.
-- @field #table SEADGroupPrefixes Table of SEAD prefixes.
-- @field #table SuppressedGroups Table of currently suppressed groups.
-- @field #number EngagementRange Engagement Range.
-- @field #number Padding Padding in seconds.
-- @field #function CallBack Callback function for suppression plans.
-- @field #boolean UseCallBack Switch for callback function to be used.
-- @field #boolean debug Debug switch.
-- @field #boolen WeaponTrack Track switch, if true track weapon speed for 30 secs.
-- @extends Core.Base#BASE -- @extends Core.Base#BASE
--- Make SAM sites execute evasive and defensive behaviour when being fired upon. --- Make SAM sites execute evasive and defensive behaviour when being fired upon.
@@ -56,10 +66,11 @@ SEAD = {
SEADGroupPrefixes = {}, SEADGroupPrefixes = {},
SuppressedGroups = {}, SuppressedGroups = {},
EngagementRange = 75, -- default 75% engagement range Feature Request #1355 EngagementRange = 75, -- default 75% engagement range Feature Request #1355
Padding = 10, Padding = 15,
CallBack = nil, CallBack = nil,
UseCallBack = false, UseCallBack = false,
debug = false, debug = false,
WeaponTrack = false,
} }
--- Missile enumerators --- Missile enumerators
@@ -69,6 +80,7 @@ SEAD = {
["AGM_122"] = "AGM_122", ["AGM_122"] = "AGM_122",
["AGM_84"] = "AGM_84", ["AGM_84"] = "AGM_84",
["AGM_45"] = "AGM_45", ["AGM_45"] = "AGM_45",
["AGM_65"] = "AGM_65",
["ALARM"] = "ALARM", ["ALARM"] = "ALARM",
["LD-10"] = "LD-10", ["LD-10"] = "LD-10",
["X_58"] = "X_58", ["X_58"] = "X_58",
@@ -88,6 +100,7 @@ SEAD = {
-- km and mach -- km and mach
["AGM_88"] = { 150, 3}, ["AGM_88"] = { 150, 3},
["AGM_45"] = { 12, 2}, ["AGM_45"] = { 12, 2},
["AGM_65"] = { 16, 0.9},
["AGM_122"] = { 16.5, 2.3}, ["AGM_122"] = { 16.5, 2.3},
["AGM_84"] = { 280, 0.8}, ["AGM_84"] = { 280, 0.8},
["ALARM"] = { 45, 2}, ["ALARM"] = { 45, 2},
@@ -144,7 +157,7 @@ function SEAD:New( SEADGroupPrefixes, Padding )
self:AddTransition("*", "ManageEvasion", "*") self:AddTransition("*", "ManageEvasion", "*")
self:AddTransition("*", "CalculateHitZone", "*") self:AddTransition("*", "CalculateHitZone", "*")
self:I("*** SEAD - Started Version 0.4.6") self:I("*** SEAD - Started Version 0.4.9")
return self return self
end end
@@ -371,7 +384,7 @@ function SEAD:onafterManageEvasion(From,Event,To,_targetskill,_targetgroup,SEADP
reach = wpndata[1] * 1.1 reach = wpndata[1] * 1.1
local mach = wpndata[2] local mach = wpndata[2]
wpnspeed = math.floor(mach * 340.29) wpnspeed = math.floor(mach * 340.29)
if Weapon then if Weapon and Weapon:GetSpeed() > 0 then
wpnspeed = Weapon:GetSpeed() wpnspeed = Weapon:GetSpeed()
self:T(string.format("*** SEAD - Weapon Speed from WEAPON: %f m/s",wpnspeed)) self:T(string.format("*** SEAD - Weapon Speed from WEAPON: %f m/s",wpnspeed))
end end
@@ -452,29 +465,38 @@ end
-- @return #SEAD self -- @return #SEAD self
function SEAD:HandleEventShot( EventData ) function SEAD:HandleEventShot( EventData )
self:T( { EventData.id } ) self:T( { EventData.id } )
local SEADWeapon = EventData.Weapon -- Identify the weapon fired
local SEADWeaponName = EventData.WeaponName or "None" -- return weapon type
if self:_CheckHarms(SEADWeaponName) then
--UTILS.PrintTableToLog(EventData)
local SEADPlane = EventData.IniUnit -- Wrapper.Unit#UNIT local SEADPlane = EventData.IniUnit -- Wrapper.Unit#UNIT
if not SEADPlane then return self end -- case IniUnit is empty
local SEADGroup = EventData.IniGroup -- Wrapper.Group#GROUP local SEADGroup = EventData.IniGroup -- Wrapper.Group#GROUP
local SEADPlanePos = SEADPlane:GetCoordinate() -- Core.Point#COORDINATE local SEADPlanePos = SEADPlane:GetCoordinate() -- Core.Point#COORDINATE
local SEADUnit = EventData.IniDCSUnit local SEADUnit = EventData.IniDCSUnit
local SEADUnitName = EventData.IniDCSUnitName local SEADUnitName = EventData.IniDCSUnitName
local SEADWeapon = EventData.Weapon -- Identify the weapon fired
local SEADWeaponName = EventData.WeaponName -- return weapon type
local WeaponWrapper = WEAPON:New(EventData.Weapon) local WeaponWrapper = WEAPON:New(EventData.Weapon) -- Wrapper.Weapon#WEAPON
--local SEADWeaponSpeed = WeaponWrapper:GetSpeed() -- mps
self:T( "*** SEAD - Missile Launched = " .. SEADWeaponName) self:T( "*** SEAD - Missile Launched = " .. SEADWeaponName)
--self:T({ SEADWeapon })
if self:_CheckHarms(SEADWeaponName) then
self:T( '*** SEAD - Weapon Match' ) self:T( '*** SEAD - Weapon Match' )
if self.WeaponTrack == true then
WeaponWrapper:SetFuncTrack(function(weapon) env.info(string.format("*** Weapon Speed: %d m/s",weapon:GetSpeed() or -1)) end)
WeaponWrapper:StartTrack(0.1)
WeaponWrapper:StopTrack(30)
end
local _targetskill = "Random" local _targetskill = "Random"
local _targetgroupname = "none" local _targetgroupname = "none"
local _target = EventData.Weapon:getTarget() -- Identify target local _target = EventData.Weapon:getTarget() -- Identify target
if not _target or self.debug then -- AGM-88 or 154 w/o target data if not _target or self.debug then -- AGM-88 or 154 w/o target data
self:E("***** SEAD - No target data for " .. (SEADWeaponName or "None")) self:E("***** SEAD - No target data for " .. (SEADWeaponName or "None"))
if string.find(SEADWeaponName,"AGM_88",1,true) or string.find(SEADWeaponName,"AGM_154",1,true) then if string.find(SEADWeaponName,"AGM_88",1,true) or string.find(SEADWeaponName,"AGM_154",1,true) then
self:I("**** Tracking AGM-88/154 with no target data.") self:T("**** Tracking AGM-88/154 with no target data.")
local pos0 = SEADPlane:GetCoordinate() local pos0 = SEADPlane:GetCoordinate()
local fheight = SEADPlane:GetHeight() local fheight = SEADPlane:GetHeight()
self:__CalculateHitZone(20,SEADWeapon,pos0,fheight,SEADGroup,SEADWeaponName) self:__CalculateHitZone(20,SEADWeapon,pos0,fheight,SEADGroup,SEADWeaponName)
@@ -520,7 +542,7 @@ function SEAD:HandleEventShot( EventData )
end end
if SEADGroupFound == true then -- yes we are being attacked if SEADGroupFound == true then -- yes we are being attacked
if string.find(SEADWeaponName,"ADM_141",1,true) then if string.find(SEADWeaponName,"ADM_141",1,true) then
self:__ManageEvasion(2,_targetskill,_targetgroup,SEADPlanePos,SEADWeaponName,SEADGroup,0,WeaponWrapper) self:__ManageEvasion(2,_targetskill,_targetgroup,SEADPlanePos,SEADWeaponName,SEADGroup,2,WeaponWrapper)
else else
self:ManageEvasion(_targetskill,_targetgroup,SEADPlanePos,SEADWeaponName,SEADGroup,0,WeaponWrapper) self:ManageEvasion(_targetskill,_targetgroup,SEADPlanePos,SEADWeaponName,SEADGroup,0,WeaponWrapper)
end end
+29 -7
View File
@@ -21,7 +21,7 @@
-- @image Functional.Shorad.jpg -- @image Functional.Shorad.jpg
-- --
-- Date: Nov 2021 -- Date: Nov 2021
-- Last Update: Nov 2023 -- Last Update: Jan 2025
------------------------------------------------------------------------- -------------------------------------------------------------------------
--- **SHORAD** class, extends Core.Base#BASE --- **SHORAD** class, extends Core.Base#BASE
@@ -113,7 +113,7 @@ SHORAD = {
SkateNumber = 3, SkateNumber = 3,
SkateZones = nil, SkateZones = nil,
minscootdist = 100, minscootdist = 100,
minscootdist = 3000, maxscootdist = 3000,
scootrandomcoord = false, scootrandomcoord = false,
} }
@@ -443,9 +443,11 @@ do
for _,_groups in pairs (shoradset) do for _,_groups in pairs (shoradset) do
local groupname = _groups:GetName() local groupname = _groups:GetName()
if string.find(groupname, tgtgrp, 1, true) then if string.find(groupname, tgtgrp, 1, true) then
if _groups:IsSAM() then
returnname = true returnname = true
end end
end end
end
return returnname return returnname
end end
@@ -470,6 +472,7 @@ do
-- @param #number Radius Radius of the #ZONE -- @param #number Radius Radius of the #ZONE
-- @param #number ActiveTimer Number of seconds to stay active -- @param #number ActiveTimer Number of seconds to stay active
-- @param #number TargetCat (optional) Category, i.e. Object.Category.UNIT or Object.Category.STATIC -- @param #number TargetCat (optional) Category, i.e. Object.Category.UNIT or Object.Category.STATIC
-- @param #boolean ShotAt If true, function is called after a shot
-- @return #SHORAD self -- @return #SHORAD self
-- @usage Use this function to integrate with other systems, example -- @usage Use this function to integrate with other systems, example
-- --
@@ -479,7 +482,7 @@ do
-- mymantis = MANTIS:New("BlueMantis","Blue SAM","Blue EWR",nil,"blue",false,"Blue Awacs") -- mymantis = MANTIS:New("BlueMantis","Blue SAM","Blue EWR",nil,"blue",false,"Blue Awacs")
-- mymantis:AddShorad(myshorad,720) -- mymantis:AddShorad(myshorad,720)
-- mymantis:Start() -- mymantis:Start()
function SHORAD:onafterWakeUpShorad(From, Event, To, TargetGroup, Radius, ActiveTimer, TargetCat) function SHORAD:onafterWakeUpShorad(From, Event, To, TargetGroup, Radius, ActiveTimer, TargetCat, ShotAt)
self:T(self.lid .. " WakeUpShorad") self:T(self.lid .. " WakeUpShorad")
self:T({TargetGroup, Radius, ActiveTimer, TargetCat}) self:T({TargetGroup, Radius, ActiveTimer, TargetCat})
local targetcat = TargetCat or Object.Category.UNIT local targetcat = TargetCat or Object.Category.UNIT
@@ -521,7 +524,27 @@ do
-- go through set and find the one(s) to activate -- go through set and find the one(s) to activate
local TDiff = 4 local TDiff = 4
for _,_group in pairs (shoradset) do for _,_group in pairs (shoradset) do
if _group:IsAnyInZone(targetzone) then
local groupname = _group:GetName()
if groupname == TargetGroup and ShotAt==true then
-- Shot at a SHORAD group
if self.UseEmOnOff then
_group:EnableEmission(false)
end
_group:OptionAlarmStateGreen()
self.ActiveGroups[groupname] = nil
local text = string.format("Shot at SHORAD %s! Evading!", _group:GetName())
self:T(text)
local m = MESSAGE:New(text,10,"SHORAD"):ToAllIf(self.debug)
--Shoot and Scoot
if self.shootandscoot then
self:__ShootAndScoot(1,_group)
end
elseif _group:IsAnyInZone(targetzone) or groupname == TargetGroup then
-- shot at a group we protect
local text = string.format("Waking up SHORAD %s", _group:GetName()) local text = string.format("Waking up SHORAD %s", _group:GetName())
self:T(text) self:T(text)
local m = MESSAGE:New(text,10,"SHORAD"):ToAllIf(self.debug) local m = MESSAGE:New(text,10,"SHORAD"):ToAllIf(self.debug)
@@ -529,7 +552,6 @@ do
_group:EnableEmission(true) _group:EnableEmission(true)
end end
_group:OptionAlarmStateRed() _group:OptionAlarmStateRed()
local groupname = _group:GetName()
if self.ActiveGroups[groupname] == nil then -- no timer yet for this group if self.ActiveGroups[groupname] == nil then -- no timer yet for this group
self.ActiveGroups[groupname] = { Timing = ActiveTimer } self.ActiveGroups[groupname] = { Timing = ActiveTimer }
local endtime = timer.getTime() + (ActiveTimer * math.random(75,100) / 100 ) -- randomize wakeup a bit local endtime = timer.getTime() + (ActiveTimer * math.random(75,100) / 100 ) -- randomize wakeup a bit
@@ -607,7 +629,7 @@ do
_targetgroupname = tgtgrp:GetName() -- group name _targetgroupname = tgtgrp:GetName() -- group name
_targetskill = tgtgrp:GetUnit(1):GetSkill() _targetskill = tgtgrp:GetUnit(1):GetSkill()
self:T("*** Found Target = ".. _targetgroupname) self:T("*** Found Target = ".. _targetgroupname)
self:WakeUpShorad(_targetgroupname, self.Radius, self.ActiveTimer, Object.Category.UNIT) self:WakeUpShorad(_targetgroupname, self.Radius, self.ActiveTimer, Object.Category.UNIT,true)
end end
end end
end end
@@ -736,7 +758,7 @@ do
-- if being shot at, find closest SHORADs to activate -- if being shot at, find closest SHORADs to activate
if shotatsams or shotatus then if shotatsams or shotatus then
self:T({shotatsams=shotatsams,shotatus=shotatus}) self:T({shotatsams=shotatsams,shotatus=shotatus})
self:WakeUpShorad(targetgroupname, self.Radius, self.ActiveTimer, targetcat) self:WakeUpShorad(targetgroupname, self.Radius, self.ActiveTimer, targetcat, true)
end end
end end
end end
File diff suppressed because it is too large Load Diff
+311 -225
View File
@@ -1,10 +1,10 @@
--- **Functional** - TIRESIAS - manages AI behaviour. ----- **Functional** - TIRESIAS - manages AI behaviour (OPTIMIZED VERSION).
---- ===
--- The @{#TIRESIAS} class is working in the back to keep your large-scale ground units in check.
-- --
-- === -- -- Features:
--
-- The @{#TIRESIAS} class is working in the back to keep your large-scale ground units in check.
--
-- ## Features:
-- --
-- * Designed to keep CPU and Network usage lower on missions with a lot of ground units. -- * Designed to keep CPU and Network usage lower on missions with a lot of ground units.
-- * Does not affect ships to keep the Navy guys happy. -- * Does not affect ships to keep the Navy guys happy.
@@ -16,24 +16,29 @@
-- --
-- === -- ===
-- --
-- ## Missions: -- ## Optimizations Applied:
-- --
-- ### [TIRESIAS](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master) -- * Cached frequently used functions and constants
-- * Reduced string concatenations and formatting
-- * Optimized loop structures and conditions
-- * Pre-allocated tables where possible
-- * Reduced function call overhead
-- * Improved memory management
-- --
-- === ---- ===
--
-- ### Author : **applevangelist **
-- --
---- #-- Author : **applevangelist ** (Optimized by AI)
---
-- @module Functional.Tiresias -- @module Functional.Tiresias
-- @image Functional.Tiresias.jpg -- @image Functional.Tiresias.jpg
--
-- Last Update: Dec 2023
------------------------------------------------------------------------- --- Last Update: Oct 2025
--- **TIRESIAS** class, extends Core.Base#BASE --- **TIRESIAS** class, extends Core.Base#BASE
-- @type TIRESIAS -- @type TIRESIAS
-- @field #string ClassName -- @field #string ClassName
-- @field #booelan debug -- @field #boolean debug
-- @field #string version -- @field #string version
-- @field #number Interval -- @field #number Interval
-- @field Core.Set#SET_GROUP GroundSet -- @field Core.Set#SET_GROUP GroundSet
@@ -48,6 +53,9 @@
-- @field #number PlaneSwitchRange -- @field #number PlaneSwitchRange
-- @field Core.Set#SET_GROUP FlightSet -- @field Core.Set#SET_GROUP FlightSet
-- @field #boolean SwitchAAA -- @field #boolean SwitchAAA
-- @field #string lid
-- @field #table _cached_zones
-- @field #table _cached_groupsets
-- @extends Core.Fsm#FSM -- @extends Core.Fsm#FSM
--- ---
@@ -58,8 +66,8 @@
-- @field #boolean AIOff -- @field #boolean AIOff
-- @field #boolean exception -- @field #boolean exception
---
--- *Tiresias, Greek demi-god and shapeshifter, blinded by the Gods, works as oracle for you.* (Wiki) -- *Tiresias, Greek demi-god and shapeshifter, blinded by the Gods, works as oracle for you.* (Wiki)
-- --
-- === -- ===
-- --
@@ -74,18 +82,17 @@
-- * Easy setup. -- * Easy setup.
-- --
-- ## Setup -- ## Setup
-- -- -- Setup is a one-liner:
-- Setup is a one-liner:
-- --
-- local blinder = TIRESIAS:New() -- local blinder = TIRESIAS:New()
-- --
-- Optionally you can set up exceptions, e.g. for convoys driving around -- -- Optionally you can set up exceptions, e.g. for convoys driving around
-- --
-- local exceptionset = SET_GROUP:New():FilterCoalitions("red"):FilterPrefixes("Convoy"):FilterStart() -- local exceptionset = SET_GROUP:New():FilterCoalitions(" red" ):FilterPrefixes(" Convoy" ):FilterStart()
-- local blinder = TIRESIAS:New() -- local blinder = TIRESIAS:New()
-- blinder:AddExceptionSet(exceptionset) -- blinder:AddExceptionSet(exceptionset)
-- --
-- Options -- -- Options
-- --
-- -- Setup different radius for activation around helo and airplane groups (applies to AI and humans) -- -- Setup different radius for activation around helo and airplane groups (applies to AI and humans)
-- blinder:SetActivationRanges(10,25) -- defaults are 10, and 25 -- blinder:SetActivationRanges(10,25) -- defaults are 10, and 25
@@ -93,11 +100,12 @@
-- -- Setup engagement ranges for AAA (non-advanced SAM units like Flaks etc) and if you want them to be AIOff -- -- Setup engagement ranges for AAA (non-advanced SAM units like Flaks etc) and if you want them to be AIOff
-- blinder:SetAAARanges(60,true) -- defaults are 60, and true -- blinder:SetAAARanges(60,true) -- defaults are 60, and true
-- --
---
-- @field #TIRESIAS -- @field #TIRESIAS
TIRESIAS = { TIRESIAS = {
ClassName = "TIRESIAS", ClassName = "TIRESIAS",
debug = false, debug = false,
version = "0.0.5", version = " 0.0.8" ,
Interval = 20, Interval = 20,
GroundSet = nil, GroundSet = nil,
VehicleSet = nil, VehicleSet = nil,
@@ -108,9 +116,12 @@ TIRESIAS = {
HeloSwitchRange = 10, -- NM HeloSwitchRange = 10, -- NM
PlaneSwitchRange = 25, -- NM PlaneSwitchRange = 25, -- NM
SwitchAAA = true, SwitchAAA = true,
} _cached_zones = {}, -- Cache for zone objects
_cached_groupsets = {}, -- Cache for group_set objects
}
--- [USER] Create a new Tiresias object and start it up. ---
-- [USER] Create a new Tiresias object and start it up.
-- @param #TIRESIAS self -- @param #TIRESIAS self
-- @return #TIRESIAS self -- @return #TIRESIAS self
function TIRESIAS:New() function TIRESIAS:New()
@@ -129,13 +140,15 @@ function TIRESIAS:New()
self:AddTransition("*", "Status", "*") -- TIRESIAS status update. self:AddTransition("*", "Status", "*") -- TIRESIAS status update.
self:AddTransition("*", "Stop", "Stopped") -- Stop FSM. self:AddTransition("*", "Stop", "Stopped") -- Stop FSM.
self.ExceptionSet = SET_GROUP:New():Clear(false) self.ExceptionSet = SET_GROUP:New() --:Clear(false)
self._cached_zones = {} -- Initialize zone cache
self:HandleEvent(EVENTS.PlayerEnterAircraft,self._EventHandler) self:HandleEvent(EVENTS.PlayerEnterAircraft, self._EventHandler)
self.lid = string.format("TIRESIAS %s | ",self.version) -- Cache the log identifier to avoid string concatenation in loops
self.lid = "TIRESIAS " .. self.version .. " | "
self:I(self.lid.."Managing ground groups!") self:I(self.lid .. "Managing ground groups!")
--- Triggers the FSM event "Stop". Stops TIRESIAS and all its event handlers. --- Triggers the FSM event "Stop". Stops TIRESIAS and all its event handlers.
-- @function [parent=#TIRESIAS] Stop -- @function [parent=#TIRESIAS] Stop
@@ -156,23 +169,26 @@ function TIRESIAS:New()
-- @param #number delay Delay in seconds. -- @param #number delay Delay in seconds.
self:__Start(1) self:__Start(1)
return self return self
end end
------------------------------------------------------------------------------------------------------------- -----
--
-- Helper Functions
--
-------------------------------------------------------------------------------------------------------------
---[USER] Set activation radius for Helos and Planes in Nautical Miles. ---
-- Helper Functions
---
--- [USER] Set activation radius for Helos and Planes in Nautical Miles.
-- @param #TIRESIAS self -- @param #TIRESIAS self
-- @param #number HeloMiles Radius around a Helicopter in which AI ground units will be activated. Defaults to 10NM. -- @param #number HeloMiles Radius around a Helicopter in which AI ground units will be activated. Defaults to 10NM.
-- @param #number PlaneMiles Radius around an Airplane in which AI ground units will be activated. Defaults to 25NM. -- @param #number PlaneMiles Radius around an Airplane in which AI ground units will be activated. Defaults to 25NM.
-- @return #TIRESIAS self -- @return #TIRESIAS self
function TIRESIAS:SetActivationRanges(HeloMiles,PlaneMiles) function TIRESIAS:SetActivationRanges(HeloMiles, PlaneMiles)
self.HeloSwitchRange = HeloMiles or 10 self.HeloSwitchRange = HeloMiles or 10
self.PlaneSwitchRange = PlaneMiles or 25 self.PlaneSwitchRange = PlaneMiles or 25
-- Clear zone cache when ranges change
self._cached_zones = {}
return self return self
end end
@@ -181,7 +197,7 @@ end
-- @param #number FiringRange The engagement range that AAA units will be set to. Can be 0 to 100 (percent). Defaults to 60. -- @param #number FiringRange The engagement range that AAA units will be set to. Can be 0 to 100 (percent). Defaults to 60.
-- @param #boolean SwitchAAA Decide if these system will have their AI switched off, too. Defaults to true. -- @param #boolean SwitchAAA Decide if these system will have their AI switched off, too. Defaults to true.
-- @return #TIRESIAS self -- @return #TIRESIAS self
function TIRESIAS:SetAAARanges(FiringRange,SwitchAAA) function TIRESIAS:SetAAARanges(FiringRange, SwitchAAA)
self.AAARange = FiringRange or 60 self.AAARange = FiringRange or 60
self.SwitchAAA = (SwitchAAA == false) and false or true self.SwitchAAA = (SwitchAAA == false) and false or true
return self return self
@@ -192,328 +208,393 @@ end
-- @param Core.Set#SET_GROUP Set to add to the exception list. -- @param Core.Set#SET_GROUP Set to add to the exception list.
-- @return #TIRESIAS self -- @return #TIRESIAS self
function TIRESIAS:AddExceptionSet(Set) function TIRESIAS:AddExceptionSet(Set)
self:T(self.lid.."AddExceptionSet") self:T(self.lid .. " AddExceptionSet" )
if not self.ExceptionSet then
self.ExceptionSet = SET_GROUP:New()
end
local exceptions = self.ExceptionSet local exceptions = self.ExceptionSet
Set:ForEachGroupAlive(
function(grp) -- Cache the exception data structure for reuse
if not grp.Tiresias then local exception_data = {
grp.Tiresias = { -- #TIRESIAS.Data type = " Exception" ,
type = "Exception",
exception = true, exception = true,
} }
exceptions:AddGroup(grp,true)
Set:ForEachGroupAlive(
function(grp)
--local inAAASet = self.AAASet:IsIncludeObject(grp)
--local inVehSet = self.VehicleSet:IsIncludeObject(grp)
--local inSAMSet = self.SAMSet:IsIncludeObject(grp)
if grp:IsGround() and (not grp.Tiresias) then --and (not inAAASet) and (not inVehSet) and (not inSAMSet) then
grp.Tiresias = exception_data
exceptions:AddGroup(grp, true)
BASE:T(" TIRESIAS: Added exception group: " .. grp:GetName())
end end
BASE:T("TIRESIAS: Added exception group: "..grp:GetName())
end end
) )
return self return self
end end
--- [INTERNAL] Filter Function --- [INTERNAL] Filter Function - Optimized with cached calls
-- @param Wrapper.Group#GROUP Group -- @param Wrapper.Group#GROUP Group
-- @return #boolean isin -- @return #boolean isin
function TIRESIAS._FilterNotAAA(Group) function TIRESIAS._FilterNotAAA(Group)
local grp = Group -- Wrapper.Group#GROUP local grp = Group -- Wrapper.Group#GROUP
local isaaa = grp:IsAAA() -- Cache method calls to reduce overhead
if isaaa == true and grp:IsGround() and not grp:IsShip() then local is_air = grp:IsAir()
return false -- remove from SET local is_ship = grp:IsShip()
else local is_AAA = grp:IsAAA()
if is_air or grp:IsShip() then -- air or ship - no AAA
return true -- keep in SET return true -- keep in SET
end end
return not is_AAA -- remove AAA, keep others
end end
--- [INTERNAL] Filter Function --- [INTERNAL] Filter Function - Optimized with cached calls
-- @param Wrapper.Group#GROUP Group -- @param Wrapper.Group#GROUP Group
-- @return #boolean isin -- @return #boolean isin
function TIRESIAS._FilterNotSAM(Group) function TIRESIAS._FilterNotSAM(Group)
local grp = Group -- Wrapper.Group#GROUP local grp = Group -- Wrapper.Group#GROUP
local issam = grp:IsSAM() -- Cache method calls to reduce overhead
if issam == true and grp:IsGround() and not grp:IsShip() then local is_air = grp:IsGround()
return false -- remove from SET local is_ship = grp:IsShip()
else local is_SAM = grp:IsSAM()
if is_air or grp:IsShip() then
return true -- keep in SET return true -- keep in SET
end end
return not is_SAM -- remove SAM, keep others
end end
--- [INTERNAL] Filter Function --- [INTERNAL] Filter Function - Optimized with cached calls
-- @param Wrapper.Group#GROUP Group -- @param Wrapper.Group#GROUP Group
-- @return #boolean isin -- @return #boolean isin
function TIRESIAS._FilterAAA(Group) function TIRESIAS._FilterAAA(Group)
local grp = Group -- Wrapper.Group#GROUP local grp = Group -- Wrapper.Group#GROUP
local isaaa = grp:IsAAA() -- Cache method calls to reduce overhead
if isaaa == true and grp:IsGround() and not grp:IsShip() then local is_ground = grp:IsGround()
return true -- remove from SET if (not is_ground) or grp:IsShip() then
else return false -- not AAA
return false -- keep in SET
end end
return grp:IsAAA() -- only AAA
end end
--- [INTERNAL] Filter Function --- [INTERNAL] Filter Function - Optimized with cached calls
-- @param Wrapper.Group#GROUP Group -- @param Wrapper.Group#GROUP Group
-- @return #boolean isin -- @return #boolean isin
function TIRESIAS._FilterSAM(Group) function TIRESIAS._FilterSAM(Group)
local grp = Group -- Wrapper.Group#GROUP local grp = Group -- Wrapper.Group#GROUP
local issam = grp:IsSAM() -- Cache method calls to reduce overhead
if issam == true and grp:IsGround() and not grp:IsShip() then local is_ground = grp:IsGround()
return true -- remove from SET if (not is_ground) or grp:IsShip() then
else return false -- not SAM
return false -- keep in SET
end end
return grp:IsSAM() -- only SAM
end end
--- [INTERNAL] Init Groups --- [INTERNAL] Init Groups - Optimized with reduced function calls
-- @param #TIRESIAS self -- @param #TIRESIAS self
-- @return #TIRESIAS self -- @return #TIRESIAS self
function TIRESIAS:_InitGroups() function TIRESIAS:_InitGroups()
self:T(self.lid.."_InitGroups") self:T(self.lid .. " _InitGroups" )
-- Set all groups invisible/motionless
local EngageRange = self.AAARange -- Cache frequently used values
local SwitchAAA = self.SwitchAAA local EngageRange = self.AAARange
--- AAA local SwitchAAA = self.SwitchAAA
self.AAASet:ForEachGroupAlive(
-- Pre-create data structures to avoid repeated table creation
local aaa_data_template = {
type = " AAA" ,
invisible = true,
range = EngageRange,
exception = false,
AIOff = SwitchAAA,
}
local vehicle_data_template = {
type = " Vehicle" ,
invisible = true,
AIOff = true,
exception = false,
}
local sam_data_template = {
type = " SAM" ,
invisible = true,
exception = false,
}
--- AAA - Optimized loop
self.AAASet:ForEachGroupAlive(
function(grp) function(grp)
if not grp.Tiresias then local tiresias_data = grp.Tiresias
if not tiresias_data then
grp:OptionEngageRange(EngageRange) grp:OptionEngageRange(EngageRange)
grp:SetCommandInvisible(true) grp:SetCommandInvisible(true)
if SwitchAAA then if SwitchAAA then
grp:SetAIOff() grp:SetAIOff()
grp:EnableEmission(false) grp:EnableEmission(false)
end end
grp.Tiresias = { -- #TIRESIAS.Data grp.Tiresias = aaa_data_template
type = "AAA", elseif not tiresias_data.exception == true then
invisible = true, if not tiresias_data.invisible == true then
range = EngageRange,
exception = false,
AIOff = SwitchAAA,
}
end
if grp.Tiresias and (not grp.Tiresias.exception == true) then
if grp.Tiresias.invisible and grp.Tiresias.invisible == false then
grp:SetCommandInvisible(true) grp:SetCommandInvisible(true)
grp.Tiresias.invisible = true tiresias_data.invisible = true
if SwitchAAA then if SwitchAAA == true then
grp:SetAIOff() grp:SetAIOff()
grp:EnableEmission(false) grp:EnableEmission(false)
grp.Tiresias.AIOff = true tiresias_data.AIOff = true
end end
end end
end end
--BASE:I(string.format("Init/Switch off AAA %s (Exception %s)",grp:GetName(),tostring(grp.Tiresias.exception)))
end end
) )
--- Vehicles
self.VehicleSet:ForEachGroupAlive( --- Vehicles - Optimized loop
self.VehicleSet:ForEachGroupAlive(
function(grp) function(grp)
if not grp.Tiresias then local tiresias_data = grp.Tiresias
if not tiresias_data then
grp:SetAIOff() grp:SetAIOff()
grp:SetCommandInvisible(true) grp:SetCommandInvisible(true)
grp.Tiresias = { -- #TIRESIAS.Data grp.Tiresias = vehicle_data_template
type = "Vehicle", elseif not tiresias_data.exception == true then
invisible = true, if not tiresias_data.invisible then
AIOff = true,
exception = false,
}
end
if grp.Tiresias and (not grp.Tiresias.exception == true) then
if grp.Tiresias and grp.Tiresias.invisible and grp.Tiresias.invisible == false then
grp:SetCommandInvisible(true) grp:SetCommandInvisible(true)
grp:SetAIOff() grp:SetAIOff()
grp.Tiresias.invisible = true tiresias_data.invisible = true
tiresias_data.AIOff = true
end end
end end
--BASE:I(string.format("Init/Switch off Vehicle %s (Exception %s)",grp:GetName(),tostring(grp.Tiresias.exception)))
end end
) )
--- SAM
self.SAMSet:ForEachGroupAlive( --- SAM - Optimized loop
self.SAMSet:ForEachGroupAlive(
function(grp) function(grp)
if not grp.Tiresias then local tiresias_data = grp.Tiresias
if not tiresias_data then
grp:SetCommandInvisible(true) grp:SetCommandInvisible(true)
grp.Tiresias = { -- #TIRESIAS.Data grp.Tiresias = sam_data_template
type = "SAM", elseif not tiresias_data.exception == true then
invisible = true, if not tiresias_data.invisible then
exception = false,
}
end
if grp.Tiresias and (not grp.Tiresias.exception == true) then
if grp.Tiresias and grp.Tiresias.invisible and grp.Tiresias.invisible == false then
grp:SetCommandInvisible(true) grp:SetCommandInvisible(true)
grp.Tiresias.invisible = true tiresias_data.invisible = true
end end
end end
--BASE:I(string.format("Init/Switch off SAM %s (Exception %s)",grp:GetName(),tostring(grp.Tiresias.exception)))
end end
) )
return self
return self
end end
--- [INTERNAL] Event handler function --- [INTERNAL] Event handler function - Optimized
-- @param #TIRESIAS self -- @param #TIRESIAS self
-- @param Core.Event#EVENTDATA EventData -- @param Core.Event#EVENTDATA EventData
-- @return #TIRESIAS self -- @return #TIRESIAS self
function TIRESIAS:_EventHandler(EventData) function TIRESIAS:_EventHandler(EventData)
self:T(string.format("%s Event = %d",self.lid, EventData.id)) self:T(string.format(" %s Event = %d" , self.lid, EventData.id))
local event = EventData -- Core.Event#EVENTDATA local event = EventData -- Core.Event#EVENTDATA
if event.id == EVENTS.PlayerEnterAircraft or event.id == EVENTS.PlayerEnterUnit then if event.id == EVENTS.PlayerEnterAircraft or event.id == EVENTS.PlayerEnterUnit then
--local _coalition = event.IniCoalition
--if _coalition ~= self.Coalition then
-- return --ignore!
--end
local unitname = event.IniUnitName or "none"
local _unit = event.IniUnit
local _group = event.IniGroup local _group = event.IniGroup
if _group and _group:IsAlive() then if _group and _group:IsAlive() then
local radius = self.PlaneSwitchRange -- Cache the radius calculation
if _group:IsHelicopter() then local radius = _group:IsHelicopter() and self.HeloSwitchRange or self.PlaneSwitchRange
radius = self.HeloSwitchRange self:_SwitchOnGroups(_group, radius)
end
self:_SwitchOnGroups(_group,radius)
end end
end end
return self return self
end end
--- [INTERNAL] Switch Groups Behaviour --- [INTERNAL] Switch Groups Behaviour - Optimized with zone caching
-- @param #TIRESIAS self -- @param #TIRESIAS self
-- @param Wrapper.Group#GROUP group -- @param Wrapper.Group#GROUP group
-- @param #number radius Radius in NM -- @param #number radius Radius in NM
-- @return #TIRESIAS self -- @return #TIRESIAS self
function TIRESIAS:_SwitchOnGroups(group,radius) function TIRESIAS:_SwitchOnGroups(group, radius)
self:T(self.lid.."_SwitchOnGroups "..group:GetName().." Radius "..radius.." NM") self:T(self.lid .. " _SwitchOnGroups " .. group:GetName() .. " Radius " .. radius .. " NM" )
local zone = ZONE_GROUP:New("Zone-"..group:GetName(),group,UTILS.NMToMeters(radius))
local ground = SET_GROUP:New():FilterCategoryGround():FilterZones({zone}):FilterOnce() -- Use cached zones to reduce object creation
local count = ground:CountAlive() local group_name = group:GetName()
if self.debug then local cache_key = group_name .. " _" .. radius
local text = string.format("There are %d groups around this plane or helo!",count) local zone = self._cached_zones[cache_key] -- Core.Zone#ZONE_RADIUS
self:I(text) --local ground = self._cached_groupsets[cache_key] -- Core.Set#SET_GROUP
if not zone then
zone = ZONE_GROUP:New(" Zone-" .. group_name, group, UTILS.NMToMeters(radius))
self._cached_zones[cache_key] = zone
else
-- Update zone center to current group position
zone:UpdateFromGroup(group)
end end
--if not ground then
--ground = SET_GROUP:New():FilterCategoryGround():FilterZones({zone}):FilterOnce()
--self._cached_groupsets[cache_key] = ground
--else
--ground:FilterZones({zone},true):FilterOnce()
zone:Scan({Object.Category.UNIT},{Unit.Category.GROUND_UNIT})
local ground = zone:GetScannedSetGroup()
--end
local count = ground:CountAlive()
if self.debug then
self:I(string.format(" There are %d groups around this plane or helo!" , count))
end
if count > 0 then
-- Cache values outside the loop
local SwitchAAA = self.SwitchAAA local SwitchAAA = self.SwitchAAA
if ground:CountAlive() > 0 then local group_coalition = group:GetCoalition()
ground:ForEachGroupAlive( ground:ForEachGroupAlive(
function(grp) function(grp)
local name = grp:GetName() local tiresias_data = grp.Tiresias
if grp.Tiresias and grp.Tiresias.type and (not grp.Tiresias.exception == true ) then if grp:GetCoalition() ~= group_coalition
if grp.Tiresias.invisible == true then and tiresias_data
and tiresias_data.type
and not tiresias_data.exception == true then
-- Make group visible if invisible
if tiresias_data.invisible == true then
grp:SetCommandInvisible(false) grp:SetCommandInvisible(false)
grp.Tiresias.invisible = false tiresias_data.invisible = false
end end
if grp.Tiresias.type == "Vehicle" and grp.Tiresias.AIOff and grp.Tiresias.AIOff == true then
-- Handle AI activation based on type
local grp_type = tiresias_data.type
if grp_type == "Vehicle" and tiresias_data.AIOff == true then
grp:SetAIOn() grp:SetAIOn()
grp.Tiresias.AIOff = false tiresias_data.AIOff = false
end elseif SwitchAAA == true and grp_type == "AAA" and tiresias_data.AIOff == true then
if SwitchAAA and grp.Tiresias.type == "AAA" and grp.Tiresias.AIOff and grp.Tiresias.AIOff == true then
grp:SetAIOn() grp:SetAIOn()
grp:EnableEmission(true) grp:EnableEmission(true)
grp.Tiresias.AIOff = false tiresias_data.AIOff = false
end end
--BASE:I(string.format("TIRESIAS - Switch on %s %s (Exception %s)",tostring(grp.Tiresias.type),grp:GetName(),tostring(grp.Tiresias.exception)))
else else
BASE:T("TIRESIAS - This group "..tostring(name).. " has not been initialized or is an exception!") BASE:T("TIRESIAS - This group " .. tostring(grp:GetName()) .. " has not been initialized or is an exception!")
end end
end end
) )
end end
return self return self
end end
------------------------------------------------------------------------------------------------------------- -----
--
-- FSM Functions
--
-------------------------------------------------------------------------------------------------------------
--- [INTERNAL] FSM Function ---
-- FSM Functions
----
--- [INTERNAL] FSM Function - Optimized initialization
-- @param #TIRESIAS self -- @param #TIRESIAS self
-- @param #string From -- @param #string From
-- @param #string Event -- @param #string Event
-- @param #string To -- @param #string To
-- @return #TIRESIAS self -- @return #TIRESIAS self
function TIRESIAS:onafterStart(From, Event, To) function TIRESIAS:onafterStart(From, Event, To)
self:T({From, Event, To}) self:T({From, Event, To})
local VehicleSet = SET_GROUP:New():FilterCategoryGround():FilterFunction(TIRESIAS._FilterNotAAA):FilterFunction(TIRESIAS._FilterNotSAM):FilterStart() -- Create sets with optimized filters
local AAASet = SET_GROUP:New():FilterCategoryGround():FilterFunction(TIRESIAS._FilterAAA):FilterStart() local VehicleSet = SET_GROUP:New():FilterCategoryGround():FilterFunction(TIRESIAS._FilterNotAAA):FilterFunction(TIRESIAS._FilterNotSAM):FilterStart()
local SAMSet = SET_GROUP:New():FilterCategoryGround():FilterFunction(TIRESIAS._FilterSAM):FilterStart() local AAASet = SET_GROUP:New():FilterCategoryGround():FilterFunction(TIRESIAS._FilterAAA):FilterStart()
local OpsGroupSet = SET_OPSGROUP:New():FilterActive(true):FilterStart() local SAMSet = SET_GROUP:New():FilterCategoryGround():FilterFunction(TIRESIAS._FilterSAM):FilterStart()
self.FlightSet = SET_GROUP:New():FilterCategories({"plane","helicopter"}):FilterStart() local OpsGroupSet = SET_OPSGROUP:New():FilterActive(true):FilterStart()
self.FlightSet = SET_GROUP:New():FilterCategories({" plane" ," helicopter" }):FilterStart()
local EngageRange = self.AAARange -- Cache frequently used values
local EngageRange = self.AAARange
local SwitchAAA = self.SwitchAAA
local ExceptionSet = self.ExceptionSet
local ExceptionSet = self.ExceptionSet -- Pre-create data templates to reduce object creation
if self.ExceptionSet then local exception_data = {
function ExceptionSet:OnAfterAdded(From,Event,To,ObjectName,Object) type = " Exception" ,
BASE:I("TIRESIAS: EXCEPTION Object Added: "..Object:GetName())
if Object and Object:IsAlive() then
Object.Tiresias = { -- #TIRESIAS.Data
type = "Exception",
exception = true, exception = true,
} }
local vehicle_data = {
type = " Vehicle" ,
invisible = true,
AIOff = true,
exception = false,
}
local aaa_data = {
type = " AAA" ,
invisible = true,
range = EngageRange,
exception = false,
AIOff = SwitchAAA,
}
local sam_data = {
type = " SAM" ,
invisible = true,
exception = false,
}
if ExceptionSet then
function ExceptionSet:OnAfterAdded(From, Event, To, ObjectName, Object)
BASE:I(" TIRESIAS: EXCEPTION Object Added: " .. Object:GetName())
if Object and Object:IsAlive() then
Object.Tiresias = exception_data
Object:SetAIOn() Object:SetAIOn()
Object:SetCommandInvisible(false) Object:SetCommandInvisible(false)
Object:EnableEmission(true) Object:EnableEmission(true)
end end
end end
-- Process existing OpsGroups more efficiently
local OGS = OpsGroupSet:GetAliveSet() local OGS = OpsGroupSet:GetAliveSet()
for _,_OG in pairs(OGS or {}) do for _, _OG in pairs(OGS or {}) do
local OG = _OG -- Ops.OpsGroup#OPSGROUP local OG = _OG -- Ops.OpsGroup#OPSGROUP
local grp = OG:GetGroup() local grp = OG:GetGroup()
ExceptionSet:AddGroup(grp,true) ExceptionSet:AddGroup(grp, true)
end end
function OpsGroupSet:OnAfterAdded(From,Event,To,ObjectName,Object) function OpsGroupSet:OnAfterAdded(From, Event, To, ObjectName, Object)
local grp = Object:GetGroup() local grp = Object:GetGroup()
ExceptionSet:AddGroup(grp,true) ExceptionSet:AddGroup(grp, true)
end
end end
end
function VehicleSet:OnAfterAdded(From,Event,To,ObjectName,Object) -- Optimized event handlers with pre-created data objects
BASE:I("TIRESIAS: VEHCILE Object Added: "..Object:GetName()) function VehicleSet:OnAfterAdded(From, Event, To, ObjectName, Object)
BASE:T(" TIRESIAS: VEHICLE Object Added: " .. Object:GetName())
if Object and Object:IsAlive() then if Object and Object:IsAlive() then
Object:SetAIOff() Object:SetAIOff()
Object:SetCommandInvisible(true) Object:SetCommandInvisible(true)
Object.Tiresias = { -- #TIRESIAS.Data Object.Tiresias = vehicle_data
type = "Vehicle",
invisible = true,
AIOff = true,
exception = false,
}
end
end end
end
local SwitchAAA = self.SwitchAAA function AAASet:OnAfterAdded(From, Event, To, ObjectName, Object)
function AAASet:OnAfterAdded(From,Event,To,ObjectName,Object)
if Object and Object:IsAlive() then if Object and Object:IsAlive() then
BASE:I("TIRESIAS: AAA Object Added: "..Object:GetName()) BASE:I(" TIRESIAS: AAA Object Added: " .. Object:GetName())
Object:OptionEngageRange(EngageRange) Object:OptionEngageRange(EngageRange)
Object:SetCommandInvisible(true) Object:SetCommandInvisible(true)
if SwitchAAA then if SwitchAAA then
Object:SetAIOff() Object:SetAIOff()
Object:EnableEmission(false) Object:EnableEmission(false)
end end
Object.Tiresias = { -- #TIRESIAS.Data Object.Tiresias = aaa_data
type = "AAA",
invisible = true,
range = EngageRange,
exception = false,
AIOff = SwitchAAA,
}
end
end end
end
function SAMSet:OnAfterAdded(From,Event,To,ObjectName,Object) function SAMSet:OnAfterAdded(From, Event, To, ObjectName, Object)
if Object and Object:IsAlive() then if Object and Object:IsAlive() then
BASE:I("TIRESIAS: SAM Object Added: "..Object:GetName()) BASE:T(" TIRESIAS: SAM Object Added: " .. Object:GetName())
Object:SetCommandInvisible(true) Object:SetCommandInvisible(true)
Object.Tiresias = { -- #TIRESIAS.Data Object.Tiresias = sam_data
type = "SAM",
invisible = true,
exception = false,
}
end
end end
end
-- Store references
self.VehicleSet = VehicleSet self.VehicleSet = VehicleSet
self.AAASet = AAASet self.AAASet = AAASet
self.SAMSet = SAMSet self.SAMSet = SAMSet
@@ -533,13 +614,10 @@ end
-- @return #TIRESIAS self -- @return #TIRESIAS self
function TIRESIAS:onbeforeStatus(From, Event, To) function TIRESIAS:onbeforeStatus(From, Event, To)
self:T({From, Event, To}) self:T({From, Event, To})
if self:GetState() == "Stopped" then return self:GetState() ~= " Stopped"
return false
end
return self
end end
--- [INTERNAL] FSM Function --- [INTERNAL] FSM Function - Optimized status processing
-- @param #TIRESIAS self -- @param #TIRESIAS self
-- @param #string From -- @param #string From
-- @param #string Event -- @param #string Event
@@ -547,28 +625,36 @@ end
-- @return #TIRESIAS self -- @return #TIRESIAS self
function TIRESIAS:onafterStatus(From, Event, To) function TIRESIAS:onafterStatus(From, Event, To)
self:T({From, Event, To}) self:T({From, Event, To})
if self.debug then if self.debug then
local count = self.VehicleSet:CountAlive() local count = self.VehicleSet:CountAlive()
local AAAcount = self.AAASet:CountAlive() local AAAcount = self.AAASet:CountAlive()
local SAMcount = self.SAMSet:CountAlive() local SAMcount = self.SAMSet:CountAlive()
local text = string.format("Overall: %d | Vehicles: %d | AAA: %d | SAM: %d",count+AAAcount+SAMcount,count,AAAcount,SAMcount) self:I(string.format(" Overall: %d | Vehicles: %d | AAA: %d | SAM: %d" ,
self:I(text) count + AAAcount + SAMcount, count, AAAcount, SAMcount))
end end
self:_InitGroups() self:_InitGroups()
if self.FlightSet:CountAlive() > 0 then
-- Process flight groups more efficiently
local flight_count = self.FlightSet:CountAlive()
if flight_count > 0 then
local Set = self.FlightSet:GetAliveSet() local Set = self.FlightSet:GetAliveSet()
for _,_plane in pairs(Set) do -- Cache range values outside loop
local helo_range = self.HeloSwitchRange
local plane_range = self.PlaneSwitchRange
for _, _plane in pairs(Set or {}) do
local plane = _plane -- Wrapper.Group#GROUP local plane = _plane -- Wrapper.Group#GROUP
local radius = self.PlaneSwitchRange local radius = plane:IsHelicopter() and helo_range or plane_range
if plane:IsHelicopter() then self:_SwitchOnGroups(plane, radius)
radius = self.HeloSwitchRange
end
self:_SwitchOnGroups(_plane,radius)
end end
end end
if self:GetState() ~= "Stopped" then
if self:GetState() ~= " Stopped" then
self:__Status(self.Interval) self:__Status(self.Interval)
end end
return self return self
end end
@@ -581,11 +667,11 @@ end
function TIRESIAS:onafterStop(From, Event, To) function TIRESIAS:onafterStop(From, Event, To)
self:T({From, Event, To}) self:T({From, Event, To})
self:UnHandleEvent(EVENTS.PlayerEnterAircraft) self:UnHandleEvent(EVENTS.PlayerEnterAircraft)
-- Clear zone cache on stop to free memory
self._cached_zones = {}
return self return self
end end
------------------------------------------------------------------------------------------------------------- -----
-- ---- End
-- End -----
--
-------------------------------------------------------------------------------------------------------------
@@ -3153,7 +3153,7 @@ end
-- @param #WAREHOUSE self -- @param #WAREHOUSE self
-- @return Core.Point#COORDINATE The coordinate of the warehouse. -- @return Core.Point#COORDINATE The coordinate of the warehouse.
function WAREHOUSE:GetCoordinate() function WAREHOUSE:GetCoordinate()
return self.warehouse:GetCoordinate() return self.warehouse:GetCoord()
end end
--- Get 3D vector of warehouse static. --- Get 3D vector of warehouse static.
@@ -4247,6 +4247,16 @@ function WAREHOUSE:_AssetItemInfo(asset)
self:T3({Template=asset.template}) self:T3({Template=asset.template})
end 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. --- On after "NewAsset" event. A new asset has been added to the warehouse stock.
-- @param #WAREHOUSE self -- @param #WAREHOUSE self
-- @param #string From From state. -- @param #string From From state.
@@ -5965,6 +5975,10 @@ function WAREHOUSE:_SpawnAssetGroundNaval(alias, asset, request, spawnzone, late
template.y = coord.z template.y = coord.z
template.alt = coord.y template.alt = coord.y
if self.ValidateAndRepositionGroundUnits then
UTILS.ValidateAndRepositionGroundUnits(template.units)
end
-- Spawn group. -- Spawn group.
local group=_DATABASE:Spawn(template) --Wrapper.Group#GROUP local group=_DATABASE:Spawn(template) --Wrapper.Group#GROUP
@@ -6047,7 +6061,7 @@ function WAREHOUSE:_SpawnAssetAircraft(alias, asset, request, parking, uncontrol
else else
if #parking<#template.units and not airstart then if parking and #parking<#template.units and not airstart then
local text=string.format("ERROR: Not enough parking! Free parking = %d < %d aircraft to be spawned.", #parking, #template.units) local text=string.format("ERROR: Not enough parking! Free parking = %d < %d aircraft to be spawned.", #parking, #template.units)
self:_DebugMessage(text) self:_DebugMessage(text)
return nil return nil
@@ -6089,7 +6103,7 @@ function WAREHOUSE:_SpawnAssetAircraft(alias, asset, request, parking, uncontrol
terminal=parking[i].TerminalID terminal=parking[i].TerminalID
end end
if self.Debug then if self.Debug and terminal then
local text=string.format("Spawnplace unit %s terminal %d.", unit.name, terminal) local text=string.format("Spawnplace unit %s terminal %d.", unit.name, terminal)
coord:MarkToAll(text) coord:MarkToAll(text)
env.info(text) env.info(text)
@@ -6732,7 +6746,7 @@ end
-- @param Wrapper.Group#GROUP deadgroup Group of unit that died. -- @param Wrapper.Group#GROUP deadgroup Group of unit that died.
-- @param #WAREHOUSE.Pendingitem request Request that needs to be updated. -- @param #WAREHOUSE.Pendingitem request Request that needs to be updated.
function WAREHOUSE:_UnitDead(deadunit, deadgroup, request) function WAREHOUSE:_UnitDead(deadunit, deadgroup, request)
self:F(self.lid.."FF unit dead "..deadunit:GetName()) --self:F(self.lid.."FF unit dead "..deadunit:GetName())
-- Find opsgroup. -- Find opsgroup.
local opsgroup=_DATABASE:FindOpsGroup(deadgroup) local opsgroup=_DATABASE:FindOpsGroup(deadgroup)
@@ -6893,7 +6907,7 @@ function WAREHOUSE:_CheckConquered()
for _,_unit in pairs(units) do for _,_unit in pairs(units) do
local unit=_unit --Wrapper.Unit#UNIT 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. -- 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 if unit:IsGround() and unit:IsAlive() and distance <= radius then
@@ -8122,9 +8136,11 @@ function WAREHOUSE:_FindParkingForAssets(airbase, assets)
-- Debug output for occupied spots. -- Debug output for occupied spots.
if self.Debug then if self.Debug then
local coord=problem.coord --Core.Point#COORDINATE local coord=problem.coord --Core.Point#COORDINATE
if coord then
local text=string.format("Obstacle %s [type=%s] blocking spot=%d! Size=%.1f m and distance=%.1f m.", problem.name, problem.type, _termid, problem.size, problem.dist) local text=string.format("Obstacle %s [type=%s] blocking spot=%d! Size=%.1f m and distance=%.1f m.", problem.name, problem.type, _termid, problem.size, problem.dist)
self:I(self.lid..text) self:I(self.lid..text)
coord:MarkToAll(string.format(text)) coord:MarkToAll(text)
end
else else
self:T(self.lid..string.format("Parking spot %d is occupied or not big enough!", _termid)) self:T(self.lid..string.format("Parking spot %d is occupied or not big enough!", _termid))
end end
@@ -8434,11 +8450,13 @@ function WAREHOUSE:_GetAttribute(group)
if group then if group then
local groupCat=group:GetCategory()
----------- -----------
--- Air --- --- Air ---
----------- -----------
-- Planes -- Planes
local transportplane=group:HasAttribute("Transports") and group:HasAttribute("Planes") local transportplane=group:HasAttribute("Transports") and group:HasAttribute("Planes") and groupCat==Group.Category.AIRPLANE
local awacs=group:HasAttribute("AWACS") local awacs=group:HasAttribute("AWACS")
local fighter=group:HasAttribute("Fighters") or group:HasAttribute("Interceptors") or group:HasAttribute("Multirole fighters") or (group:HasAttribute("Bombers") and not group:HasAttribute("Strategic bombers")) local fighter=group:HasAttribute("Fighters") or group:HasAttribute("Interceptors") or group:HasAttribute("Multirole fighters") or (group:HasAttribute("Bombers") and not group:HasAttribute("Strategic bombers"))
local bomber=group:HasAttribute("Strategic bombers") local bomber=group:HasAttribute("Strategic bombers")
@@ -8593,7 +8611,6 @@ end
-- @param #WAREHOUSE.Queueitem qitem Item of queue to be removed. -- @param #WAREHOUSE.Queueitem qitem Item of queue to be removed.
-- @param #table queue The queue from which the item should be deleted. -- @param #table queue The queue from which the item should be deleted.
function WAREHOUSE:_DeleteQueueItem(qitem, queue) function WAREHOUSE:_DeleteQueueItem(qitem, queue)
self:F({qitem=qitem, queue=queue})
for i=1,#queue do for i=1,#queue do
local _item=queue[i] --#WAREHOUSE.Queueitem local _item=queue[i] --#WAREHOUSE.Queueitem
@@ -7,6 +7,8 @@
-- --
-- # Developer Note -- # 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 -- 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 -- Therefore, this class is considered to be deprecated
-- --
+1 -1
View File
@@ -10,7 +10,7 @@ _SCHEDULEDISPATCHER = SCHEDULEDISPATCHER:New() -- Core.ScheduleDispatcher#SCHEDU
_DATABASE = DATABASE:New() -- Core.Database#DATABASE _DATABASE = DATABASE:New() -- Core.Database#DATABASE
--- Settings --- Settings
_SETTINGS = SETTINGS:Set() _SETTINGS = SETTINGS:Set() -- Core.Settings#SETTINGS
_SETTINGS:SetPlayerMenuOn() _SETTINGS:SetPlayerMenuOn()
--- Register cargos. --- Register cargos.
+1 -2
View File
@@ -1,8 +1,6 @@
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Utilities/Enums.lua' ) __Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Utilities/Enums.lua' )
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Utilities/Utils.lua' ) __Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Utilities/Utils.lua' )
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Utilities/Profiler.lua' ) __Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Utilities/Profiler.lua' )
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Utilities/Templates.lua' )
--__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Utilities/STTS.lua' )
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Utilities/FiFo.lua' ) __Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Utilities/FiFo.lua' )
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Utilities/Socket.lua' ) __Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Utilities/Socket.lua' )
@@ -49,6 +47,7 @@ __Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Wrapper/Marker.lua' )
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Wrapper/Weapon.lua' ) __Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Wrapper/Weapon.lua' )
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Wrapper/Net.lua' ) __Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Wrapper/Net.lua' )
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Wrapper/Storage.lua' ) __Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Wrapper/Storage.lua' )
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Wrapper/DynamicCargo.lua' )
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Cargo/Cargo.lua' ) __Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Cargo/Cargo.lua' )
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Cargo/CargoUnit.lua' ) __Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Cargo/CargoUnit.lua' )
+2 -1
View File
@@ -47,6 +47,7 @@ __Moose.Include( 'Wrapper\\Marker.lua' )
__Moose.Include( 'Wrapper\\Net.lua' ) __Moose.Include( 'Wrapper\\Net.lua' )
__Moose.Include( 'Wrapper\\Weapon.lua' ) __Moose.Include( 'Wrapper\\Weapon.lua' )
__Moose.Include( 'Wrapper\\Storage.lua' ) __Moose.Include( 'Wrapper\\Storage.lua' )
__Moose.Include( 'Wrapper\\DynamicCargo.lua' )
__Moose.Include( 'Cargo\\Cargo.lua' ) __Moose.Include( 'Cargo\\Cargo.lua' )
__Moose.Include( 'Cargo\\CargoUnit.lua' ) __Moose.Include( 'Cargo\\CargoUnit.lua' )
@@ -81,6 +82,7 @@ __Moose.Include( 'Functional\\AICSAR.lua' )
__Moose.Include( 'Functional\\AmmoTruck.lua' ) __Moose.Include( 'Functional\\AmmoTruck.lua' )
__Moose.Include( 'Functional\\Tiresias.lua' ) __Moose.Include( 'Functional\\Tiresias.lua' )
__Moose.Include( 'Functional\\Stratego.lua' ) __Moose.Include( 'Functional\\Stratego.lua' )
__Moose.Include( 'Functional\\ClientWatch.lua' )
__Moose.Include( 'Ops\\Airboss.lua' ) __Moose.Include( 'Ops\\Airboss.lua' )
__Moose.Include( 'Ops\\RecoveryTanker.lua' ) __Moose.Include( 'Ops\\RecoveryTanker.lua' )
@@ -113,7 +115,6 @@ __Moose.Include( 'Ops\\Operation.lua' )
__Moose.Include( 'Ops\\FlightControl.lua' ) __Moose.Include( 'Ops\\FlightControl.lua' )
__Moose.Include( 'Ops\\PlayerRecce.lua' ) __Moose.Include( 'Ops\\PlayerRecce.lua' )
__Moose.Include( 'Ops\\EasyGCICAP.lua' ) __Moose.Include( 'Ops\\EasyGCICAP.lua' )
__Moose.Include( 'Ops\\EasyA2G.lua' )
__Moose.Include( 'AI\\AI_Balancer.lua' ) __Moose.Include( 'AI\\AI_Balancer.lua' )
__Moose.Include( 'AI\\AI_Air.lua' ) __Moose.Include( 'AI\\AI_Air.lua' )
+226 -123
View File
@@ -19,7 +19,7 @@
-- * Option to present information in imperial or metric units -- * Option to present information in imperial or metric units
-- * Runway length and airfield elevation (optional) -- * Runway length and airfield elevation (optional)
-- * Frequencies/channels of nav aids (ILS, VOR, NDB, TACAN, PRMG, RSBN) (optional) -- * Frequencies/channels of nav aids (ILS, VOR, NDB, TACAN, PRMG, RSBN) (optional)
-- * SRS Simple-Text-To-Speech (STTS) integration (no sound files necessary) -- * SRS Simple-Text-To-Speech (MSRS) integration (no sound files necessary)
-- --
-- === -- ===
-- --
@@ -291,7 +291,7 @@
-- ## Nevada: Nellis AFB -- ## Nevada: Nellis AFB
-- --
-- -- ATIS Nellis AFB on 270.10 MHz AM. -- -- ATIS Nellis AFB on 270.10 MHz AM.
-- atisNellis=ATIS:New(AIRBASE.Nevada.Nellis_AFB, 270.1) -- atisNellis=ATIS:New(AIRBASE.Nevada.Nellis, 270.1)
-- atisNellis:SetRadioRelayUnitName("Radio Relay Nellis") -- atisNellis:SetRadioRelayUnitName("Radio Relay Nellis")
-- atisNellis:SetActiveRunway("21L") -- atisNellis:SetActiveRunway("21L")
-- atisNellis:SetTowerFrequencies({327.000, 132.550}) -- atisNellis:SetTowerFrequencies({327.000, 132.550})
@@ -302,7 +302,7 @@
-- ## Persian Gulf: Abu Dhabi International Airport -- ## Persian Gulf: Abu Dhabi International Airport
-- --
-- -- ATIS Abu Dhabi International on 125.1 MHz AM. -- -- ATIS Abu Dhabi International on 125.1 MHz AM.
-- atisAbuDhabi=ATIS:New(AIRBASE.PersianGulf.Abu_Dhabi_International_Airport, 125.1) -- atisAbuDhabi=ATIS:New(AIRBASE.PersianGulf.Abu_Dhabi_Intl, 125.1)
-- atisAbuDhabi:SetRadioRelayUnitName("Radio Relay Abu Dhabi International Airport") -- atisAbuDhabi:SetRadioRelayUnitName("Radio Relay Abu Dhabi International Airport")
-- atisAbuDhabi:SetMetricUnits() -- atisAbuDhabi:SetMetricUnits()
-- atisAbuDhabi:SetActiveRunway("L") -- atisAbuDhabi:SetActiveRunway("L")
@@ -498,6 +498,10 @@ ATIS.Alphabet = {
-- @field #number Syria +5° (East). -- @field #number Syria +5° (East).
-- @field #number MarianaIslands +2° (East). -- @field #number MarianaIslands +2° (East).
-- @field #number SinaiMap +5° (East). -- @field #number SinaiMap +5° (East).
-- @field #number Kola +15° (East).
-- @field #number Afghanistan +3° (East).
-- @field #number Iraq +4.4° (East).
-- @field #number GermanyCW +0.1° (East).
ATIS.RunwayM2T = { ATIS.RunwayM2T = {
Caucasus = 0, Caucasus = 0,
Nevada = 12, Nevada = 12,
@@ -508,6 +512,10 @@ ATIS.RunwayM2T = {
MarianaIslands = 2, MarianaIslands = 2,
Falklands = 12, Falklands = 12,
SinaiMap = 5, SinaiMap = 5,
Kola = 15,
Afghanistan = 3,
Iraq=4.4,
GermanyCW=0.1,
} }
--- Whether ICAO phraseology is used for ATIS broadcasts. --- Whether ICAO phraseology is used for ATIS broadcasts.
@@ -521,6 +529,10 @@ ATIS.RunwayM2T = {
-- @field #boolean MarianaIslands true. -- @field #boolean MarianaIslands true.
-- @field #boolean Falklands true. -- @field #boolean Falklands true.
-- @field #boolean SinaiMap true. -- @field #boolean SinaiMap true.
-- @field #boolean Kola true.
-- @field #boolean Afghanistan true.
-- @field #boolean Iraq true.
-- @field #boolean GermanyCW true.
ATIS.ICAOPhraseology = { ATIS.ICAOPhraseology = {
Caucasus = true, Caucasus = true,
Nevada = false, Nevada = false,
@@ -531,6 +543,10 @@ ATIS.ICAOPhraseology = {
MarianaIslands = true, MarianaIslands = true,
Falklands = true, Falklands = true,
SinaiMap = true, SinaiMap = true,
Kola = true,
Afghanistan = true,
Iraq = true,
GermanyCW = true,
} }
--- Nav point data. --- Nav point data.
@@ -619,83 +635,83 @@ ATIS.ICAOPhraseology = {
-- @field #ATIS.Soundfile TACANChannel -- @field #ATIS.Soundfile TACANChannel
-- @field #ATIS.Soundfile VORFrequency -- @field #ATIS.Soundfile VORFrequency
ATIS.Sound = { ATIS.Sound = {
ActiveRunway = { filename = "ActiveRunway.ogg", duration = 0.99 }, ActiveRunway = { filename = "ActiveRunway.ogg", duration = 0.85 },
ActiveRunwayDeparture = { filename = "ActiveRunwayDeparture.ogg", duration = 0.99 }, ActiveRunwayDeparture = { filename = "ActiveRunwayDeparture.ogg", duration = 1.50 },
ActiveRunwayArrival = { filename = "ActiveRunwayArrival.ogg", duration = 0.99 }, ActiveRunwayArrival = { filename = "ActiveRunwayArrival.ogg", duration = 1.38 },
AdviceOnInitial = { filename = "AdviceOnInitial.ogg", duration = 3.00 }, AdviceOnInitial = { filename = "AdviceOnInitial.ogg", duration = 2.98 },
Airport = { filename = "Airport.ogg", duration = 0.66 }, Airport = { filename = "Airport.ogg", duration = 0.55 },
Altimeter = { filename = "Altimeter.ogg", duration = 0.68 }, Altimeter = { filename = "Altimeter.ogg", duration = 0.91 },
At = { filename = "At.ogg", duration = 0.41 }, At = { filename = "At.ogg", duration = 0.32 },
CloudBase = { filename = "CloudBase.ogg", duration = 0.82 }, CloudBase = { filename = "CloudBase.ogg", duration = 0.69 },
CloudCeiling = { filename = "CloudCeiling.ogg", duration = 0.61 }, CloudCeiling = { filename = "CloudCeiling.ogg", duration = 0.53 },
CloudsBroken = { filename = "CloudsBroken.ogg", duration = 1.07 }, CloudsBroken = { filename = "CloudsBroken.ogg", duration = 0.81 },
CloudsFew = { filename = "CloudsFew.ogg", duration = 0.99 }, CloudsFew = { filename = "CloudsFew.ogg", duration = 0.74 },
CloudsNo = { filename = "CloudsNo.ogg", duration = 1.01 }, CloudsNo = { filename = "CloudsNo.ogg", duration = 0.69},
CloudsNotAvailable = { filename = "CloudsNotAvailable.ogg", duration = 2.35 }, CloudsNotAvailable = { filename = "CloudsNotAvailable.ogg", duration = 2.64 },
CloudsOvercast = { filename = "CloudsOvercast.ogg", duration = 0.83 }, CloudsOvercast = { filename = "CloudsOvercast.ogg", duration = 0.82 },
CloudsScattered = { filename = "CloudsScattered.ogg", duration = 1.18 }, CloudsScattered = { filename = "CloudsScattered.ogg", duration = 0.89 },
Decimal = { filename = "Decimal.ogg", duration = 0.54 }, Decimal = { filename = "Decimal.ogg", duration = 0.71 },
DegreesCelsius = { filename = "DegreesCelsius.ogg", duration = 1.27 }, DegreesCelsius = { filename = "DegreesCelsius.ogg", duration = 1.08 },
DegreesFahrenheit = { filename = "DegreesFahrenheit.ogg", duration = 1.23 }, DegreesFahrenheit = { filename = "DegreesFahrenheit.ogg", duration = 1.07 },
DewPoint = { filename = "DewPoint.ogg", duration = 0.65 }, DewPoint = { filename = "DewPoint.ogg", duration = 0.59 },
Dust = { filename = "Dust.ogg", duration = 0.54 }, Dust = { filename = "Dust.ogg", duration = 0.37 },
Elevation = { filename = "Elevation.ogg", duration = 0.78 }, Elevation = { filename = "Elevation.ogg", duration = 0.92 },
EndOfInformation = { filename = "EndOfInformation.ogg", duration = 1.15 }, EndOfInformation = { filename = "EndOfInformation.ogg", duration = 1.24 },
Feet = { filename = "Feet.ogg", duration = 0.45 }, Feet = { filename = "Feet.ogg", duration = 0.34 },
Fog = { filename = "Fog.ogg", duration = 0.47 }, Fog = { filename = "Fog.ogg", duration = 0.41 },
Gusting = { filename = "Gusting.ogg", duration = 0.55 }, Gusting = { filename = "Gusting.ogg", duration = 0.58 },
HectoPascal = { filename = "HectoPascal.ogg", duration = 1.15 }, HectoPascal = { filename = "HectoPascal.ogg", duration = 0.92 },
Hundred = { filename = "Hundred.ogg", duration = 0.47 }, Hundred = { filename = "Hundred.ogg", duration = 0.53 },
InchesOfMercury = { filename = "InchesOfMercury.ogg", duration = 1.16 },
Information = { filename = "Information.ogg", duration = 0.85 },
Kilometers = { filename = "Kilometers.ogg", duration = 0.78 },
Knots = { filename = "Knots.ogg", duration = 0.59 },
Left = { filename = "Left.ogg", duration = 0.54 },
MegaHertz = { filename = "MegaHertz.ogg", duration = 0.87 },
Meters = { filename = "Meters.ogg", duration = 0.59 },
MetersPerSecond = { filename = "MetersPerSecond.ogg", duration = 1.14 },
Miles = { filename = "Miles.ogg", duration = 0.60 },
MillimetersOfMercury = { filename = "MillimetersOfMercury.ogg", duration = 1.53 },
Minus = { filename = "Minus.ogg", duration = 0.64 },
N0 = { filename = "N-0.ogg", duration = 0.55 },
N1 = { filename = "N-1.ogg", duration = 0.41 },
N2 = { filename = "N-2.ogg", duration = 0.37 },
N3 = { filename = "N-3.ogg", duration = 0.41 },
N4 = { filename = "N-4.ogg", duration = 0.37 },
N5 = { filename = "N-5.ogg", duration = 0.43 },
N6 = { filename = "N-6.ogg", duration = 0.55 },
N7 = { filename = "N-7.ogg", duration = 0.43 },
N8 = { filename = "N-8.ogg", duration = 0.38 },
N9 = { filename = "N-9.ogg", duration = 0.55 },
NauticalMiles = { filename = "NauticalMiles.ogg", duration = 1.04 },
None = { filename = "None.ogg", duration = 0.43 },
QFE = { filename = "QFE.ogg", duration = 0.63 },
QNH = { filename = "QNH.ogg", duration = 0.71 },
Rain = { filename = "Rain.ogg", duration = 0.41 },
Right = { filename = "Right.ogg", duration = 0.44 },
Snow = { filename = "Snow.ogg", duration = 0.48 },
SnowStorm = { filename = "SnowStorm.ogg", duration = 0.82 },
StatuteMiles = { filename = "StatuteMiles.ogg", duration = 1.15 },
SunriseAt = { filename = "SunriseAt.ogg", duration = 0.92 },
SunsetAt = { filename = "SunsetAt.ogg", duration = 0.95 },
Temperature = { filename = "Temperature.ogg", duration = 0.64 },
Thousand = { filename = "Thousand.ogg", duration = 0.55 },
ThunderStorm = { filename = "ThunderStorm.ogg", duration = 0.81 },
TimeLocal = { filename = "TimeLocal.ogg", duration = 0.90 },
TimeZulu = { filename = "TimeZulu.ogg", duration = 0.86 },
TowerFrequency = { filename = "TowerFrequency.ogg", duration = 1.19 },
Visibilty = { filename = "Visibility.ogg", duration = 0.79 },
WeatherPhenomena = { filename = "WeatherPhenomena.ogg", duration = 1.07 },
WindFrom = { filename = "WindFrom.ogg", duration = 0.60 },
ILSFrequency = { filename = "ILSFrequency.ogg", duration = 1.30 }, ILSFrequency = { filename = "ILSFrequency.ogg", duration = 1.30 },
InnerNDBFrequency = { filename = "InnerNDBFrequency.ogg", duration = 1.56 }, InchesOfMercury = { filename = "InchesOfMercury.ogg", duration = 1.26 },
OuterNDBFrequency = { filename = "OuterNDBFrequency.ogg", duration = 1.59 }, Information = { filename = "Information.ogg", duration = 0.99 },
RunwayLength = { filename = "RunwayLength.ogg", duration = 0.91 }, InnerNDBFrequency = { filename = "InnerNDBFrequency.ogg", duration = 1.69 },
VORFrequency = { filename = "VORFrequency.ogg", duration = 1.38 }, Kilometers = { filename = "Kilometers.ogg", duration = 0.93 },
TACANChannel = { filename = "TACANChannel.ogg", duration = 0.88 }, Knots = { filename = "Knots.ogg", duration = 0.46 },
PRMGChannel = { filename = "PRMGChannel.ogg", duration = 1.18 }, Left = { filename = "Left.ogg", duration = 0.41 },
RSBNChannel = { filename = "RSBNChannel.ogg", duration = 1.14 }, MegaHertz = { filename = "MegaHertz.ogg", duration = 0.83 },
Zulu = { filename = "Zulu.ogg", duration = 0.62 }, Meters = { filename = "Meters.ogg", duration = 0.55 },
MetersPerSecond = { filename = "MetersPerSecond.ogg", duration = 1.03 },
Miles = { filename = "Miles.ogg", duration = 0.44 },
MillimetersOfMercury = { filename = "MillimetersOfMercury.ogg", duration = 1.59 },
Minus = { filename = "Minus.ogg", duration = 0.55 },
N0 = { filename = "N-0.ogg", duration = 0.52 },
N1 = { filename = "N-1.ogg", duration = 0.35 },
N2 = { filename = "N-2.ogg", duration = 0.41 },
N3 = { filename = "N-3.ogg", duration = 0.34 },
N4 = { filename = "N-4.ogg", duration = 0.37 },
N5 = { filename = "N-5.ogg", duration = 0.40 },
N6 = { filename = "N-6.ogg", duration = 0.46 },
N7 = { filename = "N-7.ogg", duration = 0.52 },
N8 = { filename = "N-8.ogg", duration = 0.36 },
N9 = { filename = "N-9.ogg", duration = 0.51 },
NauticalMiles = { filename = "NauticalMiles.ogg", duration = 0.93 },
None = { filename = "None.ogg", duration = 0.33 },
OuterNDBFrequency = { filename = "OuterNDBFrequency.ogg", duration = 1.70 },
PRMGChannel = { filename = "PRMGChannel.ogg", duration = 1.27 },
QFE = { filename = "QFE.ogg", duration = 0.90 },
QNH = { filename = "QNH.ogg", duration = 0.94 },
Rain = { filename = "Rain.ogg", duration = 0.35 },
Right = { filename = "Right.ogg", duration = 0.31 },
RSBNChannel = { filename = "RSBNChannel.ogg", duration = 1.26 },
RunwayLength = { filename = "RunwayLength.ogg", duration = 0.81 },
Snow = { filename = "Snow.ogg", duration = 0.40 },
SnowStorm = { filename = "SnowStorm.ogg", duration = 0.73 },
StatuteMiles = { filename = "StatuteMiles.ogg", duration = 0.90 },
SunriseAt = { filename = "SunriseAt.ogg", duration = 0.82 },
SunsetAt = { filename = "SunsetAt.ogg", duration = 0.87 },
TACANChannel = { filename = "TACANChannel.ogg", duration = 0.81 },
Temperature = { filename = "Temperature.ogg", duration = 0.70 },
Thousand = { filename = "Thousand.ogg", duration = 0.58 },
ThunderStorm = { filename = "ThunderStorm.ogg", duration = 0.79 },
TimeLocal = { filename = "TimeLocal.ogg", duration = 0.83 },
TimeZulu = { filename = "TimeZulu.ogg", duration = 0.83 },
TowerFrequency = { filename = "TowerFrequency.ogg", duration = 1.05 },
Visibilty = { filename = "Visibility.ogg", duration = 1.16 },
VORFrequency = { filename = "VORFrequency.ogg", duration = 1.28 },
WeatherPhenomena = { filename = "WeatherPhenomena.ogg", duration = 1.09 },
WindFrom = { filename = "WindFrom.ogg", duration = 0.63 },
Zulu = { filename = "Zulu.ogg", duration = 0.51 },
} }
--- ---
@@ -882,6 +898,66 @@ ATIS.Messages = {
FARP = "Farp", FARP = "Farp",
DELIMITER = "Punto", -- decimal delimiter DELIMITER = "Punto", -- decimal delimiter
}, },
-- French messages thanks to @Wojtech and Bing
FR = {
HOURS = "Heures",
TIME = "Temps",
NOCLOUDINFO = "Informations sur la couverture nuageuse non disponibles",
OVERCAST = "Ciel couvert",
BROKEN = "Nuages fragmentés",
SCATTERED = "Nuages épars",
FEWCLOUDS = "Nuages rares",
NOCLOUDS = "Clair",
AIRPORT = "Aéroport",
INFORMATION ="Information",
SUNRISEAT = "Levé du soleil à %s heure locale",
SUNSETAT = "Couché du soleil à %s heure locale",
WINDFROMMS = "Vent du %s pour %s mètres par seconde",
WINDFROMKNOTS = "Vent du %s pour %s noeuds",
GUSTING = "Rafale de vent",
VISIKM = "Visibilité %s kilomètres",
VISISM = "Visibilité %s Miles",
RAIN = "Pluie",
TSTORM = "Orage",
SNOW = "Neige",
SSTROM = "Tempête de neige",
FOG = "Brouillard",
DUST = "Poussière",
PHENOMENA = "Phénomène météorologique",
CLOUDBASEM = "Couverture nuageuse de %s à %s mètres",
CLOUDBASEFT = "Couverture nuageuse de %s à %s pieds",
TEMPERATURE = "Température",
DEWPOINT = "Point de rosée",
ALTIMETER = "Altimètre",
ACTIVERUN = "Décollages piste",
ACTIVELANDING = "Atterrissages piste",
LEFT = "Gauche",
RIGHT = "Droite",
RWYLENGTH = "Longueur de piste",
METERS = "Mètre",
FEET = "Pieds",
ELEVATION = "Hauteur",
TOWERFREQ = "Fréquences de la tour",
ILSFREQ = "Fréquences ILS",
OUTERNDB = "Fréquences Outer NDB",
INNERNDB = "Fréquences Inner NDB",
VORFREQ = "Fréquences VOR",
VORFREQTTS = "Fréquences V O R",
TACANCH = "Canal TACAN %d",
RSBNCH = "Canal RSBN",
PRMGCH = "Canal PRMG",
ADVISE = "Informez le contrôle que vous avez copié l'information",
STATUTE = "Statute Miles",
DEGREES = "Degré celcius",
FAHRENHEIT = "Degré Fahrenheit",
INCHHG = "Pouces de mercure",
MMHG = "Millimètres de mercure",
HECTO = "Hectopascals",
METERSPER = "Mètres par seconde",
TACAN = "TAKAN",
FARP = "FARPE",
DELIMITER = "Décimal", -- decimal delimiter
}
} }
--- ---
@@ -894,7 +970,7 @@ _ATIS = {}
--- ATIS class version. --- ATIS class version.
-- @field #string version -- @field #string version
ATIS.version = "1.0.0" ATIS.version = "1.0.1"
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO list -- TODO list
@@ -1061,7 +1137,7 @@ end
-- @return #ATIS self -- @return #ATIS self
function ATIS:_InitLocalization() function ATIS:_InitLocalization()
self:T(self.lid.."_InitLocalization") self:T(self.lid.."_InitLocalization")
self.gettext = TEXTANDSOUND:New("AWACS","en") -- Core.TextAndSound#TEXTANDSOUND self.gettext = TEXTANDSOUND:New("ATIS","en") -- Core.TextAndSound#TEXTANDSOUND
self.locale = "en" self.locale = "en"
for locale,table in pairs(self.Messages) do for locale,table in pairs(self.Messages) do
local Locale = string.lower(tostring(locale)) local Locale = string.lower(tostring(locale))
@@ -1975,18 +2051,29 @@ function ATIS:onafterBroadcast( From, Event, To )
local hours = self.gettext:GetEntry("HOURS",self.locale) local hours = self.gettext:GetEntry("HOURS",self.locale)
local sunrise = coord:GetSunrise() local sunrise = coord:GetSunrise()
--self:I(sunrise)
local SUNRISE = "no time"
local NorthPolar = true
if tostring(sunrise) ~= "N/S" and tostring(sunrise) ~= "N/R" then
sunrise = UTILS.Split( sunrise, ":" ) sunrise = UTILS.Split( sunrise, ":" )
local SUNRISE = string.format( "%s%s", sunrise[1], sunrise[2] ) SUNRISE = string.format( "%s%s", sunrise[1], sunrise[2] )
if self.useSRS then if self.useSRS then
SUNRISE = string.format( "%s %s %s", sunrise[1], sunrise[2], hours ) SUNRISE = string.format( "%s %s %s", sunrise[1], sunrise[2], hours )
end end
NorthPolar = false
end
local sunset = coord:GetSunset() local sunset = coord:GetSunset()
--self:I(sunset)
local SUNSET = "no time"
if tostring(sunset) ~= "N/S" and tostring(sunset) ~= "N/R" then
sunset = UTILS.Split( sunset, ":" ) sunset = UTILS.Split( sunset, ":" )
local SUNSET = string.format( "%s%s", sunset[1], sunset[2] ) SUNSET = string.format( "%s%s", sunset[1], sunset[2] )
if self.useSRS then if self.useSRS then
SUNSET = string.format( "%s %s %s", sunset[1], sunset[2], hours ) SUNSET = string.format( "%s %s %s", sunset[1], sunset[2], hours )
end end
NorthPolar = false
end
--------------------------------- ---------------------------------
--- Temperature and Dew Point --- --- Temperature and Dew Point ---
@@ -2012,34 +2099,32 @@ function ATIS:onafterBroadcast( From, Event, To )
--------------- ---------------
-- Get mission weather info. Most of this is static. -- Get mission weather info. Most of this is static.
local clouds, visibility, turbulence, fog, dust, static = self:GetMissionWeather() local clouds, visibility, turbulence, dustdens, static = self:GetMissionWeather()
-- Check that fog is actually "thick" enough to reach the airport. If an airport is in the mountains, fog might not affect it as it is measured from sea level. local dust=false
if fog and fog.thickness < height + 25 then local fog=false
fog = nil
end
-- Dust only up to 1500 ft = 457 m ASL.
if dust and height + 25 > UTILS.FeetToMeters( 1500 ) then
dust = nil
end
------------------ ------------------
--- Visibility --- --- Visibility ---
------------------ ------------------
-- Get min visibility. if dustdens then
local visibilitymin = visibility
if fog then -- Dust only up to 1500 ft = 457 m ASL.
if fog.visibility < visibilitymin then if UTILS.FeetToMeters( 1500 )> height+25 then
visibilitymin = fog.visibility dust=true
end visibility=math.min(visibility, dustdens)
end end
if dust then else -- As of DCS 2.9.10.3948 (December 2024), fog and dust are mutually exclusive!
if dust < visibilitymin then
visibilitymin = dust -- Get current fog visibility and thickness
local fvis=world.weather.getFogVisibilityDistance()
local fheight=world.weather.getFogThickness()
if fvis>0 and fheight>height+25 then
fog=true
visibility=math.min(visibility, fvis)
end end
end end
@@ -2047,7 +2132,7 @@ function ATIS:onafterBroadcast( From, Event, To )
if self.metric then if self.metric then
-- Visibility in km. -- Visibility in km.
local reportedviz = UTILS.Round( visibilitymin / 1000 ) local reportedviz = UTILS.Round( visibility / 1000 )
-- max reported visibility 9999 m -- max reported visibility 9999 m
if reportedviz > 10 then if reportedviz > 10 then
reportedviz = 10 reportedviz = 10
@@ -2055,7 +2140,7 @@ function ATIS:onafterBroadcast( From, Event, To )
VISIBILITY = string.format( "%d", reportedviz ) VISIBILITY = string.format( "%d", reportedviz )
else else
-- max reported visibility 10 NM -- max reported visibility 10 NM
local reportedviz = UTILS.Round( UTILS.MetersToSM( visibilitymin ) ) local reportedviz = UTILS.Round( UTILS.MetersToSM( visibility ) )
if reportedviz > 10 then if reportedviz > 10 then
reportedviz = 10 reportedviz = 10
end end
@@ -2100,6 +2185,39 @@ function ATIS:onafterBroadcast( From, Event, To )
else else
precepitation = 3 -- snow precepitation = 3 -- snow
end end
elseif cloudspreset:find( "RainyPreset4" ) then
-- Overcast + Rain
clouddens = 5
if temperature > 5 then
precepitation = 1 -- rain
else
precepitation = 3 -- snow
end
elseif cloudspreset:find( "RainyPreset5" ) then
-- Overcast + Rain
clouddens = 5
if temperature > 5 then
precepitation = 1 -- rain
else
precepitation = 3 -- snow
end
elseif cloudspreset:find( "RainyPreset6" ) then
-- Overcast + Rain
clouddens = 5
if temperature > 5 then
precepitation = 1 -- rain
else
precepitation = 3 -- snow
end
-- NEWRAINPRESET4
elseif cloudspreset:find( "NEWRAINPRESET4" ) then
-- Overcast + Rain
clouddens = 5
if temperature > 5 then
precepitation = 1 -- rain
else
precepitation = 3 -- snow
end
elseif cloudspreset:find( "RainyPreset" ) then elseif cloudspreset:find( "RainyPreset" ) then
-- Overcast + Rain -- Overcast + Rain
clouddens = 9 clouddens = 9
@@ -2294,7 +2412,7 @@ function ATIS:onafterBroadcast( From, Event, To )
local sunrise = self.gettext:GetEntry("SUNRISEAT",self.locale) local sunrise = self.gettext:GetEntry("SUNRISEAT",self.locale)
--subtitle = string.format( "Sunrise at %s local time", SUNRISE ) --subtitle = string.format( "Sunrise at %s local time", SUNRISE )
subtitle = string.format( sunrise, SUNRISE ) subtitle = string.format( sunrise, SUNRISE )
if not self.useSRS then if not self.useSRS and NorthPolar == false then
self:Transmission( self.Sound.SunriseAt, 0.5, subtitle ) self:Transmission( self.Sound.SunriseAt, 0.5, subtitle )
self.radioqueue:Number2Transmission( SUNRISE, nil, 0.2 ) self.radioqueue:Number2Transmission( SUNRISE, nil, 0.2 )
self:Transmission( self.Sound.TimeLocal, 0.2 ) self:Transmission( self.Sound.TimeLocal, 0.2 )
@@ -2305,7 +2423,7 @@ function ATIS:onafterBroadcast( From, Event, To )
local sunset = self.gettext:GetEntry("SUNSETAT",self.locale) local sunset = self.gettext:GetEntry("SUNSETAT",self.locale)
--subtitle = string.format( "Sunset at %s local time", SUNSET ) --subtitle = string.format( "Sunset at %s local time", SUNSET )
subtitle = string.format( sunset, SUNSET ) subtitle = string.format( sunset, SUNSET )
if not self.useSRS then if not self.useSRS and NorthPolar == false then
self:Transmission( self.Sound.SunsetAt, 0.5, subtitle ) self:Transmission( self.Sound.SunsetAt, 0.5, subtitle )
self.radioqueue:Number2Transmission( SUNSET, nil, 0.5 ) self.radioqueue:Number2Transmission( SUNSET, nil, 0.5 )
self:Transmission( self.Sound.TimeLocal, 0.2 ) self:Transmission( self.Sound.TimeLocal, 0.2 )
@@ -2680,7 +2798,7 @@ function ATIS:onafterBroadcast( From, Event, To )
end end
_RUNACT = subtitle _RUNACT = subtitle
alltext = alltext .. ";\n" .. subtitle --alltext = alltext .. ";\n" .. subtitle
-- Runway length. -- Runway length.
if self.rwylength then if self.rwylength then
@@ -3249,28 +3367,13 @@ function ATIS:GetMissionWeather()
dust = weather.dust_density dust = weather.dust_density
end end
-- Fog
--[[
["enable_fog"] = false,
["fog"] =
{
["thickness"] = 0,
["visibility"] = 25,
}, -- end of ["fog"]
]]
local fog = nil
if weather.enable_fog == true then
fog = weather.fog
end
self:T( "FF weather:" ) self:T( "FF weather:" )
self:T( { clouds = clouds } ) self:T( { clouds = clouds } )
self:T( { visibility = visibility } ) self:T( { visibility = visibility } )
self:T( { turbulence = turbulence } ) self:T( { turbulence = turbulence } )
self:T( { fog = fog } )
self:T( { dust = dust } ) self:T( { dust = dust } )
self:T( { static = static } ) self:T( { static = static } )
return clouds, visibility, turbulence, fog, dust, static return clouds, visibility, turbulence, dust, static
end end
--- Get thousands of a number. --- Get thousands of a number.
+94 -18
View File
@@ -159,6 +159,8 @@ AIRWING = {
-- @field #number refuelsystem Refueling system type: `0=Unit.RefuelingSystem.BOOM_AND_RECEPTACLE`, `1=Unit.RefuelingSystem.PROBE_AND_DROGUE`. -- @field #number refuelsystem Refueling system type: `0=Unit.RefuelingSystem.BOOM_AND_RECEPTACLE`, `1=Unit.RefuelingSystem.PROBE_AND_DROGUE`.
-- @field #number noccupied Number of flights on this patrol point. -- @field #number noccupied Number of flights on this patrol point.
-- @field Wrapper.Marker#MARKER marker F10 marker. -- @field Wrapper.Marker#MARKER marker F10 marker.
-- @field #boolean IsZonePoint flag for using a (moving) zone as point for patrol etc.
-- @field Core.Zone#ZONE_BASE patrolzone in case Patrol coordinate was handed as zone, store here.
--- Patrol zone. --- Patrol zone.
-- @type AIRWING.PatrolZone -- @type AIRWING.PatrolZone
@@ -187,13 +189,14 @@ AIRWING = {
--- AIRWING class version. --- AIRWING class version.
-- @field #string version -- @field #string version
AIRWING.version="0.9.5" AIRWING.version="0.9.7"
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- ToDo list -- ToDo list
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO: Check that airbase has enough parking spots if a request is BIG. -- TODO: Check that airbase has enough parking spots if a request is BIG.
-- DONE: Allow (moving) zones as base for patrol points.
-- DONE: Spawn in air ==> Needs WAREHOUSE update. -- DONE: Spawn in air ==> Needs WAREHOUSE update.
-- DONE: Spawn hot. -- DONE: Spawn hot.
-- DONE: Make special request to transfer squadrons to anther airwing (or warehouse). -- DONE: Make special request to transfer squadrons to anther airwing (or warehouse).
@@ -807,21 +810,30 @@ function AIRWING:_PatrolPointMarkerText(point)
end end
--- Update marker of the patrol point. --- Update marker of the patrol point.
-- @param #AIRWING self
-- @param #AIRWING.PatrolData point Patrol point table. -- @param #AIRWING.PatrolData point Patrol point table.
function AIRWING:UpdatePatrolPointMarker(point) function AIRWING:UpdatePatrolPointMarker(point)
if self.markpoints then -- sometimes there's a direct call from #OPSGROUP
if self and self.markpoints then -- sometimes there's a direct call from #OPSGROUP
local text=string.format("%s Occupied=%d\nheading=%03d, leg=%d NM, alt=%d ft, speed=%d kts", local text=string.format("%s Occupied=%d\nheading=%03d, leg=%d NM, alt=%d ft, speed=%d kts",
point.type, point.noccupied, point.heading, point.leg, point.altitude, point.speed) point.type, point.noccupied, point.heading, point.leg, point.altitude, point.speed)
if point.IsZonePoint and point.IsZonePoint == true and point.patrolzone then
-- update position
local Coordinate = point.patrolzone:GetCoordinate()
point.marker:UpdateCoordinate(Coordinate)
point.marker:UpdateText(text, 1.5)
else
point.marker:UpdateText(text, 1) point.marker:UpdateText(text, 1)
end end
end
end end
--- Create a new generic patrol point. --- Create a new generic patrol point.
-- @param #AIRWING self -- @param #AIRWING self
-- @param #string Type Patrol point type, e.g. "CAP" or "AWACS". Default "Unknown". -- @param #string Type Patrol point type, e.g. "CAP" or "AWACS". Default "Unknown".
-- @param Core.Point#COORDINATE Coordinate Coordinate of the patrol point. Default 10-15 NM away from the location of the airwing. -- @param Core.Point#COORDINATE Coordinate Coordinate of the patrol point. Default 10-15 NM away from the location of the airwing. Can be handed as a Core.Zone#ZONE object (e.g. in case you want the point to align with a moving zone).
-- @param #number Altitude Orbit altitude in feet. Default random between Angels 10 and 20. -- @param #number Altitude Orbit altitude in feet. Default random between Angels 10 and 20.
-- @param #number Heading Heading in degrees. Default random (0, 360] degrees. -- @param #number Heading Heading in degrees. Default random (0, 360] degrees.
-- @param #number LegLength Length of race-track orbit in NM. Default 15 NM. -- @param #number LegLength Length of race-track orbit in NM. Default 15 NM.
@@ -830,14 +842,16 @@ end
-- @return #AIRWING.PatrolData Patrol point table. -- @return #AIRWING.PatrolData Patrol point table.
function AIRWING:NewPatrolPoint(Type, Coordinate, Altitude, Speed, Heading, LegLength, RefuelSystem) function AIRWING:NewPatrolPoint(Type, Coordinate, Altitude, Speed, Heading, LegLength, RefuelSystem)
-- Check if a zone was passed instead of a coordinate.
if Coordinate and Coordinate:IsInstanceOf("ZONE_BASE") then
Coordinate=Coordinate:GetCoordinate()
end
local patrolpoint={} --#AIRWING.PatrolData local patrolpoint={} --#AIRWING.PatrolData
patrolpoint.type=Type or "Unknown" patrolpoint.type=Type or "Unknown"
patrolpoint.coord=Coordinate or self:GetCoordinate():Translate(UTILS.NMToMeters(math.random(10, 15)), math.random(360)) patrolpoint.coord=Coordinate or self:GetCoordinate():Translate(UTILS.NMToMeters(math.random(10, 15)), math.random(360))
if Coordinate and Coordinate:IsInstanceOf("ZONE_BASE") then
patrolpoint.IsZonePoint = true
patrolpoint.patrolzone = Coordinate
patrolpoint.coord = patrolpoint.patrolzone:GetCoordinate()
else
patrolpoint.IsZonePoint = false
end
patrolpoint.heading=Heading or math.random(360) patrolpoint.heading=Heading or math.random(360)
patrolpoint.leg=LegLength or 15 patrolpoint.leg=LegLength or 15
patrolpoint.altitude=Altitude or math.random(10,20)*1000 patrolpoint.altitude=Altitude or math.random(10,20)*1000
@@ -847,7 +861,7 @@ function AIRWING:NewPatrolPoint(Type, Coordinate, Altitude, Speed, Heading, LegL
if self.markpoints then if self.markpoints then
patrolpoint.marker=MARKER:New(Coordinate, "New Patrol Point"):ToAll() patrolpoint.marker=MARKER:New(Coordinate, "New Patrol Point"):ToAll()
AIRWING.UpdatePatrolPointMarker(patrolpoint) self:UpdatePatrolPointMarker(patrolpoint)
end end
return patrolpoint return patrolpoint
@@ -855,7 +869,7 @@ end
--- Add a patrol Point for CAP missions. --- Add a patrol Point for CAP missions.
-- @param #AIRWING self -- @param #AIRWING self
-- @param Core.Point#COORDINATE Coordinate Coordinate of the patrol point. -- @param Core.Point#COORDINATE Coordinate Coordinate of the patrol point. Can be handed as a Core.Zone#ZONE object (e.g. in case you want the point to align with a moving zone).
-- @param #number Altitude Orbit altitude in feet. -- @param #number Altitude Orbit altitude in feet.
-- @param #number Speed Orbit speed in knots. -- @param #number Speed Orbit speed in knots.
-- @param #number Heading Heading in degrees. -- @param #number Heading Heading in degrees.
@@ -872,7 +886,7 @@ end
--- Add a patrol Point for RECON missions. --- Add a patrol Point for RECON missions.
-- @param #AIRWING self -- @param #AIRWING self
-- @param Core.Point#COORDINATE Coordinate Coordinate of the patrol point. -- @param Core.Point#COORDINATE Coordinate Coordinate of the patrol point. Can be handed as a Core.Zone#ZONE object (e.g. in case you want the point to align with a moving zone).
-- @param #number Altitude Orbit altitude in feet. -- @param #number Altitude Orbit altitude in feet.
-- @param #number Speed Orbit speed in knots. -- @param #number Speed Orbit speed in knots.
-- @param #number Heading Heading in degrees. -- @param #number Heading Heading in degrees.
@@ -889,7 +903,7 @@ end
--- Add a patrol Point for TANKER missions. --- Add a patrol Point for TANKER missions.
-- @param #AIRWING self -- @param #AIRWING self
-- @param Core.Point#COORDINATE Coordinate Coordinate of the patrol point. -- @param Core.Point#COORDINATE Coordinate Coordinate of the patrol point. Can be handed as a Core.Zone#ZONE object (e.g. in case you want the point to align with a moving zone).
-- @param #number Altitude Orbit altitude in feet. -- @param #number Altitude Orbit altitude in feet.
-- @param #number Speed Orbit speed in knots. -- @param #number Speed Orbit speed in knots.
-- @param #number Heading Heading in degrees. -- @param #number Heading Heading in degrees.
@@ -907,7 +921,7 @@ end
--- Add a patrol Point for AWACS missions. --- Add a patrol Point for AWACS missions.
-- @param #AIRWING self -- @param #AIRWING self
-- @param Core.Point#COORDINATE Coordinate Coordinate of the patrol point. -- @param Core.Point#COORDINATE Coordinate Coordinate of the patrol point. Can be handed as a Core.Zone#ZONE object (e.g. in case you want the point to align with a moving zone).
-- @param #number Altitude Orbit altitude in feet. -- @param #number Altitude Orbit altitude in feet.
-- @param #number Speed Orbit speed in knots. -- @param #number Speed Orbit speed in knots.
-- @param #number Heading Heading in degrees. -- @param #number Heading Heading in degrees.
@@ -974,6 +988,46 @@ function AIRWING:SetTakeoffAir()
return self return self
end end
--- Set the aircraft of the AirWing to land straight in.
-- @param #AIRWING self
-- @return #FLIGHTGROUP self
function AIRWING:SetLandingStraightIn()
self.OptionLandingStraightIn = true
return self
end
--- Set the aircraft of the AirWing to land in pairs for groups > 1 aircraft.
-- @param #AIRWING self
-- @return #AIRWING self
function AIRWING:SetLandingForcePair()
self.OptionLandingForcePair = true
return self
end
--- Set the aircraft of the AirWing to NOT land in pairs.
-- @param #AIRWING self
-- @return #AIRWING self
function AIRWING:SetLandingRestrictPair()
self.OptionLandingRestrictPair = true
return self
end
--- Set the aircraft of the AirWing to land after overhead break.
-- @param #AIRWING self
-- @return #AIRWING self
function AIRWING:SetLandingOverheadBreak()
self.OptionLandingOverheadBreak = true
return self
end
--- [Helicopter] Set the aircraft of the AirWing to prefer vertical takeoff and landing.
-- @param #AIRWING self
-- @return #AIRWING self
function AIRWING:SetOptionPreferVerticalLanding()
self.OptionPreferVerticalLanding = true
return self
end
--- Set despawn after landing. Aircraft will be despawned after the landing event. --- Set despawn after landing. Aircraft will be despawned after the landing event.
-- Can help to avoid DCS AI taxiing issues. -- Can help to avoid DCS AI taxiing issues.
-- @param #AIRWING self -- @param #AIRWING self
@@ -1136,6 +1190,10 @@ function AIRWING:_GetPatrolData(PatrolPoints, RefuelSystem)
for _,_patrolpoint in pairs(PatrolPoints) do for _,_patrolpoint in pairs(PatrolPoints) do
local patrolpoint=_patrolpoint --#AIRWING.PatrolData local patrolpoint=_patrolpoint --#AIRWING.PatrolData
if patrolpoint.IsZonePoint and patrolpoint.IsZonePoint == true and patrolpoint.patrolzone then
-- update
patrolpoint.coord = patrolpoint.patrolzone:GetCoordinate()
end
if (RefuelSystem and patrolpoint.refuelsystem and RefuelSystem==patrolpoint.refuelsystem) or RefuelSystem==nil or patrolpoint.refuelsystem==nil then if (RefuelSystem and patrolpoint.refuelsystem and RefuelSystem==patrolpoint.refuelsystem) or RefuelSystem==nil or patrolpoint.refuelsystem==nil then
return patrolpoint return patrolpoint
end end
@@ -1195,7 +1253,7 @@ function AIRWING:CheckCAP()
patrol.noccupied=patrol.noccupied+1 patrol.noccupied=patrol.noccupied+1
if self.markpoints then AIRWING.UpdatePatrolPointMarker(patrol) end if self.markpoints then self:UpdatePatrolPointMarker(patrol) end
self:AddMission(missionCAP) self:AddMission(missionCAP)
@@ -1247,7 +1305,7 @@ function AIRWING:CheckRECON()
patrol.noccupied=patrol.noccupied+1 patrol.noccupied=patrol.noccupied+1
if self.markpoints then AIRWING.UpdatePatrolPointMarker(patrol) end if self.markpoints then self:UpdatePatrolPointMarker(patrol) end
self:AddMission(missionRECON) self:AddMission(missionRECON)
@@ -1292,7 +1350,7 @@ function AIRWING:CheckTANKER()
patrol.noccupied=patrol.noccupied+1 patrol.noccupied=patrol.noccupied+1
if self.markpoints then AIRWING.UpdatePatrolPointMarker(patrol) end if self.markpoints then self:UpdatePatrolPointMarker(patrol) end
self:AddMission(mission) self:AddMission(mission)
@@ -1311,7 +1369,7 @@ function AIRWING:CheckTANKER()
patrol.noccupied=patrol.noccupied+1 patrol.noccupied=patrol.noccupied+1
if self.markpoints then AIRWING.UpdatePatrolPointMarker(patrol) end if self.markpoints then self:UpdatePatrolPointMarker(patrol) end
self:AddMission(mission) self:AddMission(mission)
@@ -1349,7 +1407,7 @@ function AIRWING:CheckAWACS()
patrol.noccupied=patrol.noccupied+1 patrol.noccupied=patrol.noccupied+1
if self.markpoints then AIRWING.UpdatePatrolPointMarker(patrol) end if self.markpoints then self:UpdatePatrolPointMarker(patrol) end
self:AddMission(mission) self:AddMission(mission)
@@ -1365,6 +1423,8 @@ function AIRWING:CheckRescuhelo()
local N=self:CountMissionsInQueue({AUFTRAG.Type.RESCUEHELO}) local N=self:CountMissionsInQueue({AUFTRAG.Type.RESCUEHELO})
if self.airbase then
local name=self.airbase:GetName() local name=self.airbase:GetName()
local carrier=UNIT:FindByName(name) local carrier=UNIT:FindByName(name)
@@ -1377,6 +1437,8 @@ function AIRWING:CheckRescuhelo()
end end
end
return self return self
end end
@@ -1461,6 +1523,20 @@ function AIRWING:onafterFlightOnMission(From, Event, To, FlightGroup, Mission)
if self.UseConnectedOpsAwacs and self.ConnectedOpsAwacs then if self.UseConnectedOpsAwacs and self.ConnectedOpsAwacs then
self.ConnectedOpsAwacs:__FlightOnMission(2,FlightGroup,Mission) self.ConnectedOpsAwacs:__FlightOnMission(2,FlightGroup,Mission)
end end
-- Landing Options
if self.OptionLandingForcePair then
FlightGroup:SetOptionLandingForcePair()
elseif self.OptionLandingOverheadBreak then
FlightGroup:SetOptionLandingOverheadBreak()
elseif self.OptionLandingRestrictPair then
FlightGroup:SetOptionLandingRestrictPair()
elseif self.OptionLandingStraightIn then
FlightGroup:SetOptionLandingStraightIn()
end
-- Landing Options Helo
if self.OptionPreferVerticalLanding then
FlightGroup:SetOptionPreferVertical()
end
end end
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
File diff suppressed because it is too large Load Diff
+7 -52
View File
@@ -68,7 +68,7 @@ ARMYGROUP = {
--- Army Group version. --- Army Group version.
-- @field #string version -- @field #string version
ARMYGROUP.version="1.0.1" ARMYGROUP.version="1.0.3"
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO list -- TODO list
@@ -2049,12 +2049,14 @@ end
--- Initialize group parameters. Also initializes waypoints if self.waypoints is nil. --- Initialize group parameters. Also initializes waypoints if self.waypoints is nil.
-- @param #ARMYGROUP self -- @param #ARMYGROUP self
-- @param #table Template Template used to init the group. Default is `self.template`. -- @param #table Template Template used to init the group. Default is `self.template`.
-- @param #number Delay Delay in seconds before group is initialized. Default `nil`, *i.e.* instantaneous.
-- @return #ARMYGROUP self -- @return #ARMYGROUP self
function ARMYGROUP:_InitGroup(Template, Delay) function ARMYGROUP:_InitGroup(Template, Delay)
if Delay and Delay>0 then if Delay and Delay>0 then
self:ScheduleOnce(Delay, ARMYGROUP._InitGroup, self, Template, 0) self:ScheduleOnce(Delay, ARMYGROUP._InitGroup, self, Template, 0)
else else
-- First check if group was already initialized. -- First check if group was already initialized.
if self.groupinitialized then if self.groupinitialized then
self:T(self.lid.."WARNING: Group was already initialized! Will NOT do it again!") self:T(self.lid.."WARNING: Group was already initialized! Will NOT do it again!")
@@ -2101,62 +2103,16 @@ function ARMYGROUP:_InitGroup(Template, Delay)
-- Get current formation from first waypoint. -- Get current formation from first waypoint.
self.option.Formation=template.route.points[1].action self.option.Formation=template.route.points[1].action
-- Set default formation to "on road".
self.optionDefault.Formation=ENUMS.Formation.Vehicle.OnRoad
-- First check if group was already initialized.
if self.groupinitialized then
self:T(self.lid.."WARNING: Group was already initialized! Will NOT do it again!")
return
end
self:T(self.lid.."FF Initializing Group")
-- Get template of group.
local template=Template or self:_GetTemplate()
-- Ground are always AI.
self.isAI=true
-- Is (template) group late activated.
self.isLateActivated=template.lateActivation
-- Ground groups cannot be uncontrolled.
self.isUncontrolled=false
-- Max speed in km/h.
self.speedMax=self.group:GetSpeedMax()
-- Is group mobile?
if self.speedMax>3.6 then
self.isMobile=true
else
self.isMobile=false
end
-- Cruise speed in km/h
self.speedCruise=self.speedMax*0.7
-- Group ammo.
self.ammo=self:GetAmmoTot()
-- Radio parameters from template.
self.radio.On=false -- Radio is always OFF for ground.
self.radio.Freq=133
self.radio.Modu=radio.modulation.AM
-- Set default radio.
self:SetDefaultRadio(self.radio.Freq, self.radio.Modu, self.radio.On)
-- Get current formation from first waypoint.
self.option.Formation=template.route.points[1].action
-- Set default formation to "on road". -- Set default formation to "on road".
self.optionDefault.Formation=ENUMS.Formation.Vehicle.OnRoad self.optionDefault.Formation=ENUMS.Formation.Vehicle.OnRoad
-- Default TACAN off. -- Default TACAN off.
if not self.tacanDefault then
self:SetDefaultTACAN(nil, nil, nil, nil, true) self:SetDefaultTACAN(nil, nil, nil, nil, true)
end
if not self.tacan then
self.tacan=UTILS.DeepCopy(self.tacanDefault) self.tacan=UTILS.DeepCopy(self.tacanDefault)
end
-- Units of the group. -- Units of the group.
local units=self.group:GetUnits() local units=self.group:GetUnits()
@@ -2177,7 +2133,6 @@ function ARMYGROUP:_InitGroup(Template, Delay)
self:_AddElementByName(unitname) self:_AddElementByName(unitname)
end end
-- Init done. -- Init done.
self.groupinitialized=true self.groupinitialized=true
end end
+257 -29
View File
@@ -162,6 +162,7 @@
-- @field #number missionRange Mission range in meters. Used by LEGION classes (AIRWING, BRIGADE, ...). -- @field #number missionRange Mission range in meters. Used by LEGION classes (AIRWING, BRIGADE, ...).
-- @field Core.Point#COORDINATE missionWaypointCoord Mission waypoint coordinate. -- @field Core.Point#COORDINATE missionWaypointCoord Mission waypoint coordinate.
-- @field Core.Point#COORDINATE missionEgressCoord Mission egress waypoint coordinate. -- @field Core.Point#COORDINATE missionEgressCoord Mission egress waypoint coordinate.
-- @field Core.Point#COORDINATE missionIngressCoord Mission Ingress waypoint coordinate.
-- @field #number missionWaypointRadius Random radius in meters. -- @field #number missionWaypointRadius Random radius in meters.
-- @field #boolean legionReturn If `true`, assets return to their legion (default). If `false`, they will stay alive. -- @field #boolean legionReturn If `true`, assets return to their legion (default). If `false`, they will stay alive.
-- --
@@ -396,6 +397,7 @@ AUFTRAG = {
conditionPush = {}, conditionPush = {},
conditionSuccessSet = false, conditionSuccessSet = false,
conditionFailureSet = false, conditionFailureSet = false,
repeatDelay = 1,
} }
--- Global mission counter. --- Global mission counter.
@@ -1319,13 +1321,19 @@ end
-- @param #number Altitude Orbit altitude in feet. Default is y component of `Coordinate`. -- @param #number Altitude Orbit altitude in feet. Default is y component of `Coordinate`.
-- @param #number Speed Orbit indicated airspeed in knots at the set altitude ASL. Default 350 KIAS. -- @param #number Speed Orbit indicated airspeed in knots at the set altitude ASL. Default 350 KIAS.
-- @param #number Heading Heading of race-track pattern in degrees. Default 270 (East to West). -- @param #number Heading Heading of race-track pattern in degrees. Default 270 (East to West).
-- @param #number Leg Length of race-track in NM. Default 10 NM. -- @param #number Leg Length of race-track in NM. Default 10 NM. Set to 0 for a simple circular orbit.
-- @param #number RefuelSystem Refueling system (0=boom, 1=probe). This info is *only* for AIRWINGs so they launch the right tanker type. -- @param #number RefuelSystem Refueling system (0=boom, 1=probe). This info is *only* for AIRWINGs so they launch the right tanker type.
-- @return #AUFTRAG self -- @return #AUFTRAG self
function AUFTRAG:NewTANKER(Coordinate, Altitude, Speed, Heading, Leg, RefuelSystem) function AUFTRAG:NewTANKER(Coordinate, Altitude, Speed, Heading, Leg, RefuelSystem)
local mission
if Leg == 0 then
mission=AUFTRAG:NewORBIT_CIRCLE(Coordinate,Altitude,Speed)
else
mission=AUFTRAG:NewORBIT_RACETRACK(Coordinate,Altitude,Speed,Heading,Leg)
end
-- Create ORBIT first. -- Create ORBIT first.
local mission=AUFTRAG:NewORBIT_RACETRACK(Coordinate, Altitude, Speed, Heading, Leg) --local mission=AUFTRAG:NewORBIT_RACETRACK(Coordinate, Altitude, Speed, Heading, Leg)
-- Mission type TANKER. -- Mission type TANKER.
mission.type=AUFTRAG.Type.TANKER mission.type=AUFTRAG.Type.TANKER
@@ -1427,7 +1435,7 @@ function AUFTRAG:NewCAP(ZoneCAP, Altitude, Speed, Coordinate, Heading, Leg, Targ
mission:_SetLogID() mission:_SetLogID()
-- DCS task parameters: -- DCS task parameters:
mission.engageZone=ZoneCAP mission.engageZone=ZoneCAP or Coordinate
mission.engageTargetTypes=TargetTypes or {"Air"} mission.engageTargetTypes=TargetTypes or {"Air"}
-- Mission options: -- Mission options:
@@ -1714,19 +1722,56 @@ function AUFTRAG:NewSEAD(Target, Altitude)
return mission return mission
end end
--- **[AIR]** Create a SEAD in Zone mission.
-- @param #AUFTRAG self
-- @param Core.Zone#ZONE TargetZone The target zone to attack.
-- @param #number Altitude Engage altitude in feet. Default 25000 ft.
-- @param #table TargetTypes Table of string of DCS known target types, defaults to {"Air Defence"}. See [DCS Target Attributes](https://wiki.hoggitworld.com/view/DCS_enum_attributes)
-- @param #number Duration Engage this much time when the AUFTRAG starts executing.
-- @return #AUFTRAG self
function AUFTRAG:NewSEADInZone(TargetZone, Altitude, TargetTypes, Duration)
local mission=AUFTRAG:New(AUFTRAG.Type.SEAD)
--mission:_TargetFromObject(TargetZone)
-- DCS Task options:
mission.engageWeaponType=ENUMS.WeaponFlag.Auto
mission.engageWeaponExpend=AI.Task.WeaponExpend.ALL
mission.engageAltitude=UTILS.FeetToMeters(Altitude or 25000)
mission.engageZone = TargetZone
mission.engageTargetTypes = TargetTypes or {"Air Defence"}
-- Mission options:
mission.missionTask=ENUMS.MissionTask.SEAD
mission.missionAltitude=mission.engageAltitude
mission.missionFraction=0.2
mission.optionROE=ENUMS.ROE.OpenFire
mission.optionROT=ENUMS.ROT.EvadeFire
mission.categories={AUFTRAG.Category.AIRCRAFT}
mission.DCStask=mission:GetDCSMissionTask()
mission:SetDuration(Duration or 1800)
return mission
end
--- **[AIR]** Create a STRIKE mission. Flight will attack the closest map object to the specified coordinate. --- **[AIR]** Create a STRIKE mission. Flight will attack the closest map object to the specified coordinate.
-- @param #AUFTRAG self -- @param #AUFTRAG self
-- @param Core.Point#COORDINATE Target The target coordinate. Can also be given as a GROUP, UNIT, STATIC or TARGET object. -- @param Core.Point#COORDINATE Target The target coordinate. Can also be given as a GROUP, UNIT, STATIC, SET_GROUP, SET_UNIT, SET_STATIC or TARGET object.
-- @param #number Altitude Engage altitude in feet. Default 2000 ft. -- @param #number Altitude Engage altitude in feet. Default 2000 ft.
-- @param #number EngageWeaponType Which weapon to use. Defaults to auto, ie ENUMS.WeaponFlag.Auto. See ENUMS.WeaponFlag for options.
-- @return #AUFTRAG self -- @return #AUFTRAG self
function AUFTRAG:NewSTRIKE(Target, Altitude) function AUFTRAG:NewSTRIKE(Target, Altitude, EngageWeaponType)
local mission=AUFTRAG:New(AUFTRAG.Type.STRIKE) local mission=AUFTRAG:New(AUFTRAG.Type.STRIKE)
mission:_TargetFromObject(Target) mission:_TargetFromObject(Target)
-- DCS Task options: -- DCS Task options:
mission.engageWeaponType=ENUMS.WeaponFlag.Auto mission.engageWeaponType=EngageWeaponType or ENUMS.WeaponFlag.Auto
mission.engageWeaponExpend=AI.Task.WeaponExpend.ALL mission.engageWeaponExpend=AI.Task.WeaponExpend.ALL
mission.engageAltitude=UTILS.FeetToMeters(Altitude or 2000) mission.engageAltitude=UTILS.FeetToMeters(Altitude or 2000)
@@ -1747,17 +1792,19 @@ end
--- **[AIR]** Create a BOMBING mission. Flight will drop bombs a specified coordinate. --- **[AIR]** Create a BOMBING mission. Flight will drop bombs a specified coordinate.
-- See [DCS task bombing](https://wiki.hoggitworld.com/view/DCS_task_bombing). -- See [DCS task bombing](https://wiki.hoggitworld.com/view/DCS_task_bombing).
-- @param #AUFTRAG self -- @param #AUFTRAG self
-- @param Core.Point#COORDINATE Target Target coordinate. Can also be specified as a GROUP, UNIT, STATIC or TARGET object. -- @param Core.Point#COORDINATE Target Target coordinate. Can also be specified as a GROUP, UNIT, STATIC, SET_GROUP, SET_UNIT, SET_STATIC or TARGET object.
-- @param #number Altitude Engage altitude in feet. Default 25000 ft. -- @param #number Altitude Engage altitude in feet. Default 25000 ft.
-- @param #number EngageWeaponType Which weapon to use. Defaults to auto, ie ENUMS.WeaponFlag.Auto. See ENUMS.WeaponFlag for options.
-- @param #boolean Divebomb If true, use a dive bombing attack approach.
-- @return #AUFTRAG self -- @return #AUFTRAG self
function AUFTRAG:NewBOMBING(Target, Altitude) function AUFTRAG:NewBOMBING(Target, Altitude, EngageWeaponType, Divebomb)
local mission=AUFTRAG:New(AUFTRAG.Type.BOMBING) local mission=AUFTRAG:New(AUFTRAG.Type.BOMBING)
mission:_TargetFromObject(Target) mission:_TargetFromObject(Target)
-- DCS task options: -- DCS task options:
mission.engageWeaponType=ENUMS.WeaponFlag.Auto mission.engageWeaponType=EngageWeaponType or ENUMS.WeaponFlag.Auto
mission.engageWeaponExpend=AI.Task.WeaponExpend.ALL mission.engageWeaponExpend=AI.Task.WeaponExpend.ALL
mission.engageAltitude=UTILS.FeetToMeters(Altitude or 25000) mission.engageAltitude=UTILS.FeetToMeters(Altitude or 25000)
@@ -1767,6 +1814,7 @@ function AUFTRAG:NewBOMBING(Target, Altitude)
mission.missionFraction=0.5 mission.missionFraction=0.5
mission.optionROE=ENUMS.ROE.OpenFire mission.optionROE=ENUMS.ROE.OpenFire
mission.optionROT=ENUMS.ROT.NoReaction -- No reaction is better. mission.optionROT=ENUMS.ROT.NoReaction -- No reaction is better.
mission.optionDivebomb = Divebomb or nil
-- Evaluate result after 5 min. We might need time until the bombs have dropped and targets have been detroyed. -- Evaluate result after 5 min. We might need time until the bombs have dropped and targets have been detroyed.
mission.dTevaluate=5*60 mission.dTevaluate=5*60
@@ -1819,7 +1867,7 @@ end
--- **[AIR]** Create a BOMBRUNWAY mission. --- **[AIR]** Create a BOMBRUNWAY mission.
-- @param #AUFTRAG self -- @param #AUFTRAG self
-- @param Wrapper.Airbase#AIRBASE Airdrome The airbase to bomb. This must be an airdrome (not a FARP or ship) as these to not have a runway. -- @param Wrapper.Airbase#AIRBASE Airdrome The airbase to bomb. This must be an airdrome (not a FARP or ship) as these do not have a runway.
-- @param #number Altitude Engage altitude in feet. Default 25000 ft. -- @param #number Altitude Engage altitude in feet. Default 25000 ft.
-- @return #AUFTRAG self -- @return #AUFTRAG self
function AUFTRAG:NewBOMBRUNWAY(Airdrome, Altitude) function AUFTRAG:NewBOMBRUNWAY(Airdrome, Altitude)
@@ -2155,7 +2203,11 @@ end
]] ]]
--- **[GROUND, NAVAL]** Create an ARTY mission. --- **[GROUND, NAVAL]** Create an ARTY mission ("Fire at point" task).
--
-- If the group has more than one weapon type supporting the "Fire at point" task, the employed weapon type can be set via the `AUFTRAG:SetWeaponType()` function.
--
-- **Note** that it is recommended to set the weapon range via the `OPSGROUP:AddWeaponRange()` function as this cannot be retrieved from the DCS API.
-- @param #AUFTRAG self -- @param #AUFTRAG self
-- @param Core.Point#COORDINATE Target Center of the firing solution. -- @param Core.Point#COORDINATE Target Center of the firing solution.
-- @param #number Nshots Number of shots to be fired. Default `#nil`. -- @param #number Nshots Number of shots to be fired. Default `#nil`.
@@ -2178,6 +2230,7 @@ function AUFTRAG:NewARTY(Target, Nshots, Radius, Altitude)
mission.optionAlarm=0 mission.optionAlarm=0
mission.missionFraction=0.0 mission.missionFraction=0.0
mission.missionWaypointRadius=0.0
-- Evaluate after 8 min. -- Evaluate after 8 min.
mission.dTevaluate=8*60 mission.dTevaluate=8*60
@@ -2271,8 +2324,9 @@ end
-- @param #number Speed Speed in knots. -- @param #number Speed Speed in knots.
-- @param #number Altitude Altitude in feet. Only for airborne units. Default 2000 feet ASL. -- @param #number Altitude Altitude in feet. Only for airborne units. Default 2000 feet ASL.
-- @param #string Formation Formation used by ground units during patrol. Default "Off Road". -- @param #string Formation Formation used by ground units during patrol. Default "Off Road".
-- @param #number StayInZoneTime Stay this many seconds in the zone when done, only then drive back.
-- @return #AUFTRAG self -- @return #AUFTRAG self
function AUFTRAG:NewCAPTUREZONE(OpsZone, Coalition, Speed, Altitude, Formation) function AUFTRAG:NewCAPTUREZONE(OpsZone, Coalition, Speed, Altitude, Formation, StayInZoneTime)
local mission=AUFTRAG:New(AUFTRAG.Type.CAPTUREZONE) local mission=AUFTRAG:New(AUFTRAG.Type.CAPTUREZONE)
@@ -2286,6 +2340,7 @@ function AUFTRAG:NewCAPTUREZONE(OpsZone, Coalition, Speed, Altitude, Formation)
mission.optionROE=ENUMS.ROE.ReturnFire mission.optionROE=ENUMS.ROE.ReturnFire
mission.optionROT=ENUMS.ROT.PassiveDefense mission.optionROT=ENUMS.ROT.PassiveDefense
mission.optionAlarm=ENUMS.AlarmState.Auto mission.optionAlarm=ENUMS.AlarmState.Auto
mission.StayInZoneTime = StayInZoneTime
mission.missionFraction=0.1 mission.missionFraction=0.1
mission.missionSpeed=Speed and UTILS.KnotsToKmph(Speed) or nil mission.missionSpeed=Speed and UTILS.KnotsToKmph(Speed) or nil
@@ -2302,7 +2357,7 @@ function AUFTRAG:NewCAPTUREZONE(OpsZone, Coalition, Speed, Altitude, Formation)
params.formation=Formation or "Off Road" params.formation=Formation or "Off Road"
params.zone=mission:GetObjective() params.zone=mission:GetObjective()
params.altitude=mission.missionAltitude params.altitude=mission.missionAltitude
params.speed=mission.missionSpeed params.speed=mission.missionSpeed and UTILS.KmphToMps(mission.missionSpeed) or nil
mission.DCStask.params=params mission.DCStask.params=params
@@ -2352,7 +2407,7 @@ function AUFTRAG:NewGROUNDATTACK(Target, Speed, Formation)
mission.DCStask=mission:GetDCSMissionTask() mission.DCStask=mission:GetDCSMissionTask()
mission.DCStask.params.speed=Speed mission.DCStask.params.speed=mission.missionSpeed and UTILS.KmphToMps(mission.missionSpeed) or nil
mission.DCStask.params.formation=Formation or ENUMS.Formation.Vehicle.Vee mission.DCStask.params.formation=Formation or ENUMS.Formation.Vehicle.Vee
return mission return mission
@@ -2958,6 +3013,16 @@ function AUFTRAG:SetRepeat(Nrepeat)
return self return self
end end
--- **[LEGION, COMMANDER, CHIEF]** Set the repeat delay in seconds after a mission is successful/failed. Only valid if the mission is handled by a LEGION (AIRWING, BRIGADE, FLEET) or higher level.
-- @param #AUFTRAG self
-- @param #number Nrepeat Repeat delay in seconds. Default 1.
-- @return #AUFTRAG self
function AUFTRAG:SetRepeatDelay(RepeatDelay)
self.repeatDelay = RepeatDelay
return self
end
--- **[LEGION, COMMANDER, CHIEF]** Set how many times the mission is repeated if it fails. Only valid if the mission is handled by a LEGION (AIRWING, BRIGADE, FLEET) or higher level. --- **[LEGION, COMMANDER, CHIEF]** Set how many times the mission is repeated if it fails. Only valid if the mission is handled by a LEGION (AIRWING, BRIGADE, FLEET) or higher level.
-- @param #AUFTRAG self -- @param #AUFTRAG self
-- @param #number Nrepeat Number of repeats. Default 0. -- @param #number Nrepeat Number of repeats. Default 0.
@@ -3481,7 +3546,7 @@ end
--- Set Rules of Engagement (ROE) for this mission. --- Set Rules of Engagement (ROE) for this mission.
-- @param #AUFTRAG self -- @param #AUFTRAG self
-- @param #string roe Mission ROE. -- @param #number roe Mission ROE, e.g. `ENUMS.ROE.ReturnFire` (whiche equals 3)
-- @return #AUFTRAG self -- @return #AUFTRAG self
function AUFTRAG:SetROE(roe) function AUFTRAG:SetROE(roe)
@@ -3493,7 +3558,7 @@ end
--- Set Reaction on Threat (ROT) for this mission. --- Set Reaction on Threat (ROT) for this mission.
-- @param #AUFTRAG self -- @param #AUFTRAG self
-- @param #string rot Mission ROT. -- @param #number rot Mission ROT, e.g. `ENUMS.ROT.NoReaction` (whiche equals 0)
-- @return #AUFTRAG self -- @return #AUFTRAG self
function AUFTRAG:SetROT(rot) function AUFTRAG:SetROT(rot)
@@ -3953,6 +4018,23 @@ function AUFTRAG:IsOver()
return over return over
end end
--- Check if mission is repeatable.
-- @param #AUFTRAG self
-- @return #boolean If true, mission is repeatable.
function AUFTRAG:IsRepeatable()
local repeatmeS=self.repeatedSuccess<self.NrepeatSuccess or self.repeated<self.Nrepeat
local repeatmeF=self.repeatedFailure<self.NrepeatFailure or self.repeated<self.Nrepeat
if repeatmeS==true or repeatmeF==true then return true else return false end
return false
end
--- Check if mission is NOT repeatable.
-- @param #AUFTRAG self
-- @return #boolean If true, mission is NOT repeatable.
function AUFTRAG:IsNotRepeatable()
return not self:IsRepeatable()
end
--- Check if mission is NOT over. --- Check if mission is NOT over.
-- @param #AUFTRAG self -- @param #AUFTRAG self
-- @return #boolean If true, mission is NOT over yet. -- @return #boolean If true, mission is NOT over yet.
@@ -4657,6 +4739,16 @@ function AUFTRAG:SetGroupWaypointCoordinate(opsgroup, coordinate)
return self return self
end end
--- [Air] Set mission (ingress) waypoint coordinate for FLIGHT group.
-- @param #AUFTRAG self
-- @param Core.Point#COORDINATE coordinate Waypoint Coordinate.
-- @return #AUFTRAG self
function AUFTRAG:SetIngressCoordinate(coordinate)
self.missionIngressCoord = coordinate
self.missionIngressCoordAlt = UTILS.MetersToFeet(coordinate.y) or 10000
return self
end
--- Get mission (ingress) waypoint coordinate of OPS group --- Get mission (ingress) waypoint coordinate of OPS group
-- @param #AUFTRAG self -- @param #AUFTRAG self
-- @param Ops.OpsGroup#OPSGROUP opsgroup The OPS group. -- @param Ops.OpsGroup#OPSGROUP opsgroup The OPS group.
@@ -4747,6 +4839,8 @@ end
-- @return #boolean If `true`, all groups are done with the mission. -- @return #boolean If `true`, all groups are done with the mission.
function AUFTRAG:CheckGroupsDone() function AUFTRAG:CheckGroupsDone()
local fsmState = self:GetState()
-- Check status of all OPS groups. -- Check status of all OPS groups.
for groupname,data in pairs(self.groupdata) do for groupname,data in pairs(self.groupdata) do
local groupdata=data --#AUFTRAG.GroupData local groupdata=data --#AUFTRAG.GroupData
@@ -4805,6 +4899,11 @@ function AUFTRAG:CheckGroupsDone()
return true return true
end end
if (self:IsStarted() or self:IsExecuting()) and (fsmState == AUFTRAG.Status.STARTED or fsmState == AUFTRAG.Status.EXECUTING) and self:CountOpsGroups()>0 then
self:T(self.lid..string.format("CheckGroupsDone: Mission is STARTED state %s [FSM=%s] and count of alive OPSGROUP > zero. Mission NOT DONE!", self.status, self:GetState()))
return false
end
return true return true
end end
@@ -5142,7 +5241,7 @@ function AUFTRAG:onafterSuccess(From, Event, To)
-- Repeat mission. -- Repeat mission.
self:T(self.lid..string.format("Mission SUCCESS! Repeating mission for the %d time (max %d times) ==> Repeat mission!", self.repeated+1, N)) self:T(self.lid..string.format("Mission SUCCESS! Repeating mission for the %d time (max %d times) ==> Repeat mission!", self.repeated+1, N))
self:Repeat() self:__Repeat(self.repeatDelay)
else else
@@ -5184,7 +5283,7 @@ function AUFTRAG:onafterFailed(From, Event, To)
-- Repeat mission. -- Repeat mission.
self:T(self.lid..string.format("Mission FAILED! Repeating mission for the %d time (max %d times) ==> Repeat mission!", self.repeated+1, N)) self:T(self.lid..string.format("Mission FAILED! Repeating mission for the %d time (max %d times) ==> Repeat mission!", self.repeated+1, N))
self:Repeat() self:__Repeat(self.repeatDelay)
else else
@@ -5712,7 +5811,7 @@ function AUFTRAG:GetMissionTypesText(MissionTypes)
return text return text
end end
--- Set the mission waypoint coordinate where the mission is executed. Note that altitude is set via `:SetMissionAltitude`. --- [NON-AIR] Set the mission waypoint coordinate from where the mission is executed. Note that altitude is set via `:SetMissionAltitude`.
-- @param #AUFTRAG self -- @param #AUFTRAG self
-- @param Core.Point#COORDINATE Coordinate Coordinate where the mission is executed. -- @param Core.Point#COORDINATE Coordinate Coordinate where the mission is executed.
-- @return #AUFTRAG self -- @return #AUFTRAG self
@@ -5740,8 +5839,9 @@ end
-- @param #AUFTRAG self -- @param #AUFTRAG self
-- @param Core.Point#COORDINATE Coordinate Egrees coordinate. -- @param Core.Point#COORDINATE Coordinate Egrees coordinate.
-- @param #number Altitude (Optional) Altitude in feet. Default is y component of coordinate. -- @param #number Altitude (Optional) Altitude in feet. Default is y component of coordinate.
-- @param #number Speed (Optional) Speed in knots to reach this waypoint. Defaults to mission speed.
-- @return #AUFTRAG self -- @return #AUFTRAG self
function AUFTRAG:SetMissionEgressCoord(Coordinate, Altitude) function AUFTRAG:SetMissionEgressCoord(Coordinate, Altitude, Speed)
-- Obviously a zone was passed. We get the coordinate. -- Obviously a zone was passed. We get the coordinate.
if Coordinate:IsInstanceOf("ZONE_BASE") then if Coordinate:IsInstanceOf("ZONE_BASE") then
@@ -5752,7 +5852,64 @@ function AUFTRAG:SetMissionEgressCoord(Coordinate, Altitude)
if Altitude then if Altitude then
self.missionEgressCoord.y=UTILS.FeetToMeters(Altitude) self.missionEgressCoord.y=UTILS.FeetToMeters(Altitude)
self.missionEgressCoordAlt = UTILS.FeetToMeters(Altitude)
end end
self.missionEgressCoordSpeed=Speed and Speed or nil
return self
end
--- [Air] Set the mission ingress coordinate. This is the coordinate where the assigned group will fly before the actual mission coordinate.
-- @param #AUFTRAG self
-- @param Core.Point#COORDINATE Coordinate Ingrees coordinate.
-- @param #number Altitude (Optional) Altitude in feet. Default is y component of coordinate.
-- @param #number Speed (Optional) Speed in knots to reach this waypoint. Defaults to mission speed.
-- @return #AUFTRAG self
function AUFTRAG:SetMissionIngressCoord(Coordinate, Altitude, Speed)
-- Obviously a zone was passed. We get the coordinate.
if Coordinate:IsInstanceOf("ZONE_BASE") then
Coordinate=Coordinate:GetCoordinate()
end
self.missionIngressCoord=Coordinate
if Altitude then
self.missionIngressCoord.y=UTILS.FeetToMeters(Altitude)
self.missionIngressCoordAlt = UTILS.FeetToMeters(Altitude or 10000)
end
self.missionIngressCoordSpeed=Speed and Speed or nil
return self
end
--- [Air] Set the mission holding coordinate. This is the coordinate where the assigned group will fly before the actual mission execution starts. Do not forget to add a push condition, too!
-- @param #AUFTRAG self
-- @param Core.Point#COORDINATE Coordinate Holding coordinate.
-- @param #number Altitude (Optional) Altitude in feet. Default is y component of coordinate.
-- @param #number Speed (Optional) Speed in knots to reach this waypoint and hold there. Defaults to mission speed.
-- @param #number Duration (Optional) Duration in seconds on how long to hold, defaults to 15 minutes. Mission continues if either a push condition is met or the time is up.
-- @return #AUFTRAG self
function AUFTRAG:SetMissionHoldingCoord(Coordinate, Altitude, Speed, Duration)
-- Obviously a zone was passed. We get the coordinate.
if Coordinate:IsInstanceOf("ZONE_BASE") then
Coordinate=Coordinate:GetCoordinate()
end
self.missionHoldingCoord=Coordinate
self.missionHoldingDuration=Duration or 900
if Altitude then
self.missionHoldingCoord.y=UTILS.FeetToMeters(Altitude)
self.missionHoldingCoordAlt = UTILS.FeetToMeters(Altitude or 10000)
end
self.missionHoldingCoordSpeed=Speed and Speed or nil
return self
end end
--- Get the mission egress coordinate if this was defined. --- Get the mission egress coordinate if this was defined.
@@ -5762,6 +5919,20 @@ function AUFTRAG:GetMissionEgressCoord()
return self.missionEgressCoord return self.missionEgressCoord
end end
--- Get the mission ingress coordinate if this was defined.
-- @param #AUFTRAG self
-- @return Core.Point#COORDINATE Coordinate Coordinate or nil.
function AUFTRAG:GetMissionIngressCoord()
return self.missionIngressCoord
end
--- Get the mission holding coordinate if this was defined.
-- @param #AUFTRAG self
-- @return Core.Point#COORDINATE Coordinate Coordinate or nil.
function AUFTRAG:GetMissionHoldingCoord()
return self.missionHoldingCoord
end
--- Get coordinate which was set as mission waypoint coordinate. --- Get coordinate which was set as mission waypoint coordinate.
-- @param #AUFTRAG self -- @param #AUFTRAG self
-- @return Core.Point#COORDINATE Coordinate where the mission is executed or `#nil`. -- @return Core.Point#COORDINATE Coordinate where the mission is executed or `#nil`.
@@ -5797,9 +5968,26 @@ function AUFTRAG:GetMissionWaypointCoord(group, randomradius, surfacetypes)
return coord return coord
end end
local coord=group:GetCoordinate()
-- Check if an ingress or holding coord has been explicitly set.
if self.missionHoldingCoord then
coord=self.missionHoldingCoord
if self.missionHoldingCoorddAlt then
coord:SetAltitude(self.missionHoldingCoordAlt, true)
end
end
if self.missionIngressCoord then
coord=self.missionIngressCoord
if self.missionIngressCoordAlt then
coord:SetAltitude(self.missionIngressCoordAlt, true)
end
end
-- Create waypoint coordinate half way between us and the target. -- Create waypoint coordinate half way between us and the target.
local waypointcoord=COORDINATE:New(0,0,0) local waypointcoord=COORDINATE:New(0,0,0)
local coord=group:GetCoordinate()
if coord then if coord then
waypointcoord=coord:GetIntermediateCoordinate(self:GetTargetCoordinate(), self.missionFraction) waypointcoord=coord:GetIntermediateCoordinate(self:GetTargetCoordinate(), self.missionFraction)
else else
@@ -6001,9 +6189,12 @@ function AUFTRAG:GetDCSMissionTask()
-- BOMBING Mission -- -- BOMBING Mission --
--------------------- ---------------------
local DCStask=CONTROLLABLE.TaskBombing(nil, self:GetTargetVec2(), self.engageAsGroup, self.engageWeaponExpend, self.engageQuantity, self.engageDirection, self.engageAltitude, self.engageWeaponType, Divebomb) local coords = self.engageTarget:GetCoordinates()
for _, coord in pairs(coords) do
local DCStask = CONTROLLABLE.TaskBombing(nil, coord:GetVec2(), self.engageAsGroup, self.engageWeaponExpend, self.engageQuantity, self.engageDirection, self.engageAltitude, self.engageWeaponType, self.optionDivebomb)
table.insert(DCStasks, DCStask) table.insert(DCStasks, DCStask)
end
elseif self.type==AUFTRAG.Type.STRAFING then elseif self.type==AUFTRAG.Type.STRAFING then
@@ -6041,7 +6232,15 @@ function AUFTRAG:GetDCSMissionTask()
-- CAP Mission -- -- CAP Mission --
----------------- -----------------
local DCStask=CONTROLLABLE.EnRouteTaskEngageTargetsInZone(nil, self.engageZone:GetVec2(), self.engageZone:GetRadius(), self.engageTargetTypes, Priority) local Vec2 = self.engageZone:GetVec2()
local Radius
if self.engageZone:IsInstanceOf("COORDINATE") then
Radius = UTILS.NMToMeters(20)
else
Radius = self.engageZone:GetRadius()
end
local DCStask=CONTROLLABLE.EnRouteTaskEngageTargetsInZone(nil, Vec2, Radius, self.engageTargetTypes, Priority)
table.insert(self.enrouteTasks, DCStask) table.insert(self.enrouteTasks, DCStask)
@@ -6099,7 +6298,7 @@ function AUFTRAG:GetDCSMissionTask()
local param={} local param={}
param.zone=self:GetObjective() param.zone=self:GetObjective()
param.altitude=self.missionAltitude param.altitude=self.missionAltitude
param.speed=self.missionSpeed param.speed=self.missionSpeed and UTILS.KmphToMps(self.missionSpeed) or nil
DCStask.params=param DCStask.params=param
@@ -6179,7 +6378,7 @@ function AUFTRAG:GetDCSMissionTask()
local param={} local param={}
param.target=self.engageTarget param.target=self.engageTarget
param.altitude=self.missionAltitude param.altitude=self.missionAltitude
param.speed=self.missionSpeed param.speed=self.missionSpeed and UTILS.KmphToMps(self.missionSpeed) or nil
param.lastindex=nil param.lastindex=nil
DCStask.params=param DCStask.params=param
@@ -6196,17 +6395,46 @@ function AUFTRAG:GetDCSMissionTask()
--local DCStask=CONTROLLABLE.EnRouteTaskSEAD(nil, self.TargetType) --local DCStask=CONTROLLABLE.EnRouteTaskSEAD(nil, self.TargetType)
--table.insert(self.enrouteTasks, DCStask) --table.insert(self.enrouteTasks, DCStask)
if self.engageZone then
--local DCStask=CONTROLLABLE.EnRouteTaskSEAD(nil, self.engageTargetTypes)
--table.insert(self.enrouteTasks, DCStask)
self.engageZone:Scan({Object.Category.UNIT},{Unit.Category.GROUND_UNIT})
local ScanUnitSet = self.engageZone:GetScannedSetUnit()
local SeadUnitSet = SET_UNIT:New()
for _,_unit in pairs (ScanUnitSet.Set) do
local unit = _unit -- Wrapper.Unit#UNTI
if unit and unit:IsAlive() and unit:HasSEAD() then
self:T("Adding UNIT for SEAD: "..unit:GetName())
local task = CONTROLLABLE.TaskAttackUnit(nil,unit,GroupAttack,AI.Task.WeaponExpend.ALL,1,Direction,self.engageAltitude,2956984318)
table.insert(DCStasks, task)
SeadUnitSet:AddUnit(unit)
end
end
self.engageTarget = TARGET:New(SeadUnitSet)
--local OrbitTask = CONTROLLABLE.TaskOrbitCircle(nil,self.engageAltitude,self.missionSpeed,self.engageZone:GetCoordinate())
--local Point = self.engageZone:GetVec2()
--local OrbitTask = CONTROLLABLE.TaskOrbitCircleAtVec2(nil,Point,self.engageAltitude,self.missionSpeed)
--table.insert(DCStasks, OrbitTask)
else
self:_GetDCSAttackTask(self.engageTarget, DCStasks) self:_GetDCSAttackTask(self.engageTarget, DCStasks)
end
elseif self.type==AUFTRAG.Type.STRIKE then elseif self.type==AUFTRAG.Type.STRIKE then
-------------------- --------------------
-- STRIKE Mission -- -- STRIKE Mission --
-------------------- --------------------
local DCStask=CONTROLLABLE.TaskAttackMapObject(nil, self:GetTargetVec2(), self.engageAsGroup, self.engageWeaponExpend, self.engageQuantity, self.engageDirection, self.engageAltitude, self.engageWeaponType) local coords = self.engageTarget:GetCoordinates()
for _, coord in pairs(coords) do
local DCStask=CONTROLLABLE.TaskAttackMapObject(nil, coord:GetVec2(), self.engageAsGroup, self.engageWeaponExpend, self.engageQuantity, self.engageDirection, self.engageAltitude, self.engageWeaponType)
table.insert(DCStasks, DCStask) table.insert(DCStasks, DCStask)
end
elseif self.type==AUFTRAG.Type.TANKER or self.type==AUFTRAG.Type.RECOVERYTANKER then elseif self.type==AUFTRAG.Type.TANKER or self.type==AUFTRAG.Type.RECOVERYTANKER then
@@ -6352,7 +6580,7 @@ function AUFTRAG:GetDCSMissionTask()
local param={} local param={}
param.zone=self:GetObjective() param.zone=self:GetObjective()
param.altitude=self.missionAltitude param.altitude=self.missionAltitude
param.speed=self.missionSpeed param.speed=self.missionSpeed and UTILS.KmphToMps(self.missionSpeed) or nil
DCStask.params=param DCStask.params=param
@@ -6388,7 +6616,7 @@ function AUFTRAG:GetDCSMissionTask()
local param={} local param={}
param.zone=self:GetObjective() param.zone=self:GetObjective()
param.altitude=self.missionAltitude param.altitude=self.missionAltitude
param.speed=self.missionSpeed param.speed=self.missionSpeed and UTILS.KmphToMps(self.missionSpeed) or nil
DCStask.params=param DCStask.params=param
@@ -6408,7 +6636,7 @@ function AUFTRAG:GetDCSMissionTask()
local param={} local param={}
param.target=self:GetTargetData() param.target=self:GetTargetData()
param.action="Wedge" param.action="Wedge"
param.speed=self.missionSpeed param.speed=self.missionSpeed and UTILS.KmphToMps(self.missionSpeed) or nil
DCStask.params=param DCStask.params=param
+143 -28
View File
@@ -17,7 +17,7 @@
-- === -- ===
-- --
-- ### Author: **applevangelist** -- ### Author: **applevangelist**
-- @date Last Update July 2024 -- @date Last Update July 2025
-- @module Ops.AWACS -- @module Ops.AWACS
-- @image OPS_AWACS.jpg -- @image OPS_AWACS.jpg
@@ -122,6 +122,7 @@ do
-- @field #number TacticalModulation -- @field #number TacticalModulation
-- @field #number TacticalInterval -- @field #number TacticalInterval
-- @field Core.Set#SET_GROUP DetectionSet -- @field Core.Set#SET_GROUP DetectionSet
-- @field #number MaxMissionRange
-- @extends Core.Fsm#FSM -- @extends Core.Fsm#FSM
@@ -183,7 +184,7 @@ do
-- --
-- Add Escorts Squad (recommended, optional) -- Add Escorts Squad (recommended, optional)
-- --
-- local Squad_Two = SQUADRON:New("Escorts",4,"Escorts North") -- local Squad_Two = SQUADRON:New("Escorts",4,"Escorts North") -- taking a template with 2 planes here, will result in a group of 2 escorts which can fly in formation escorting the AWACS.
-- Squad_Two:AddMissionCapability({AUFTRAG.Type.ESCORT}) -- Squad_Two:AddMissionCapability({AUFTRAG.Type.ESCORT})
-- Squad_Two:SetFuelLowRefuel(true) -- Squad_Two:SetFuelLowRefuel(true)
-- Squad_Two:SetFuelLowThreshold(0.3) -- Squad_Two:SetFuelLowThreshold(0.3)
@@ -231,12 +232,12 @@ do
-- -- set up in the mission editor with a late activated helo named "Rock#ZONE_POLYGON". Note this also sets the BullsEye to be referenced as "Rock". -- -- set up in the mission editor with a late activated helo named "Rock#ZONE_POLYGON". Note this also sets the BullsEye to be referenced as "Rock".
-- -- The CAP station zone is called "Fremont". We will be on 255 AM. -- -- The CAP station zone is called "Fremont". We will be on 255 AM.
-- local testawacs = AWACS:New("AWACS North",AwacsAW,"blue",AIRBASE.Caucasus.Kutaisi,"Awacs Orbit",ZONE:FindByName("Rock"),"Fremont",255,radio.modulation.AM ) -- local testawacs = AWACS:New("AWACS North",AwacsAW,"blue",AIRBASE.Caucasus.Kutaisi,"Awacs Orbit",ZONE:FindByName("Rock"),"Fremont",255,radio.modulation.AM )
-- -- set two escorts -- -- set one escort group; this example has two units in the template group, so they can fly a nice formation.
-- testawacs:SetEscort(2) -- testawacs:SetEscort(1,ENUMS.Formation.FixedWing.FingerFour.Group,{x=-500,y=50,z=500},45)
-- -- Callsign will be "Focus". We'll be a Angels 30, doing 300 knots, orbit leg to 88deg with a length of 25nm. -- -- Callsign will be "Focus". We'll be a Angels 30, doing 300 knots, orbit leg to 88deg with a length of 25nm.
-- testawacs:SetAwacsDetails(CALLSIGN.AWACS.Focus,1,30,300,88,25) -- testawacs:SetAwacsDetails(CALLSIGN.AWACS.Focus,1,30,300,88,25)
-- -- Set up SRS on port 5010 - change the below to your path and port -- -- Set up SRS on port 5010 - change the below to your path and port
-- testawacs:SetSRS("C:\\Program Files\\DCS-SimpleRadio-Standalone","female","en-GB",5010) -- testawacs:SetSRS("C:\\Program Files\\DCS-SimpleRadio-Standalone\\ExternalAudio","female","en-GB",5010)
-- -- Add a "red" border we don't want to cross, set up in the mission editor with a late activated helo named "Red Border#ZONE_POLYGON" -- -- Add a "red" border we don't want to cross, set up in the mission editor with a late activated helo named "Red Border#ZONE_POLYGON"
-- testawacs:SetRejectionZone(ZONE:FindByName("Red Border")) -- testawacs:SetRejectionZone(ZONE:FindByName("Red Border"))
-- -- Our CAP flight will have the callsign "Ford", we want 4 AI planes, Time-On-Station is four hours, doing 300 kn IAS. -- -- Our CAP flight will have the callsign "Ford", we want 4 AI planes, Time-On-Station is four hours, doing 300 kn IAS.
@@ -254,7 +255,7 @@ do
-- -- The CAP station zone is called "Fremont". We will be on 255 AM. Note the Orbit Zone is given as *nil* in the `New()`-Statement -- -- The CAP station zone is called "Fremont". We will be on 255 AM. Note the Orbit Zone is given as *nil* in the `New()`-Statement
-- local testawacs = AWACS:New("GCI Senaki",AwacsAW,"blue",AIRBASE.Caucasus.Senaki_Kolkhi,nil,ZONE:FindByName("Rock"),"Fremont",255,radio.modulation.AM ) -- local testawacs = AWACS:New("GCI Senaki",AwacsAW,"blue",AIRBASE.Caucasus.Senaki_Kolkhi,nil,ZONE:FindByName("Rock"),"Fremont",255,radio.modulation.AM )
-- -- Set up SRS on port 5010 - change the below to your path and port -- -- Set up SRS on port 5010 - change the below to your path and port
-- testawacs:SetSRS("C:\\Program Files\\DCS-SimpleRadio-Standalone","female","en-GB",5010) -- testawacs:SetSRS("C:\\Program Files\\DCS-SimpleRadio-Standalone\\ExternalAudio","female","en-GB",5010)
-- -- Add a "red" border we don't want to cross, set up in the mission editor with a late activated helo named "Red Border#ZONE_POLYGON" -- -- Add a "red" border we don't want to cross, set up in the mission editor with a late activated helo named "Red Border#ZONE_POLYGON"
-- testawacs:SetRejectionZone(ZONE:FindByName("Red Border")) -- testawacs:SetRejectionZone(ZONE:FindByName("Red Border"))
-- -- Our CAP flight will have the callsign "Ford", we want 4 AI planes, Time-On-Station is four hours, doing 300 kn IAS. -- -- Our CAP flight will have the callsign "Ford", we want 4 AI planes, Time-On-Station is four hours, doing 300 kn IAS.
@@ -508,7 +509,7 @@ do
-- @field #AWACS -- @field #AWACS
AWACS = { AWACS = {
ClassName = "AWACS", -- #string ClassName = "AWACS", -- #string
version = "0.2.65", -- #string version = "0.2.73", -- #string
lid = "", -- #string lid = "", -- #string
coalition = coalition.side.BLUE, -- #number coalition = coalition.side.BLUE, -- #number
coalitiontxt = "blue", -- #string coalitiontxt = "blue", -- #string
@@ -605,6 +606,7 @@ AWACS = {
TacticalModulation = radio.modulation.AM, TacticalModulation = radio.modulation.AM,
TacticalInterval = 120, TacticalInterval = 120,
DetectionSet = nil, DetectionSet = nil,
MaxMissionRange = 125,
} }
--- ---
@@ -1121,7 +1123,7 @@ function AWACS:New(Name,AirWing,Coalition,AirbaseName,AwacsOrbit,OpsZone,Station
self.EscortMissionReplacement = {} self.EscortMissionReplacement = {}
-- SRS -- SRS
self.PathToSRS = "C:\\Program Files\\DCS-SimpleRadio-Standalone" self.PathToSRS = "C:\\Program Files\\DCS-SimpleRadio-Standalone\\ExternalAudio"
self.Gender = "female" self.Gender = "female"
self.Culture = "en-GB" self.Culture = "en-GB"
self.Voice = nil self.Voice = nil
@@ -1240,6 +1242,8 @@ function AWACS:New(Name,AirWing,Coalition,AirbaseName,AwacsOrbit,OpsZone,Station
self:AddTransition("*", "Intercept", "*") self:AddTransition("*", "Intercept", "*")
self:AddTransition("*", "InterceptSuccess", "*") self:AddTransition("*", "InterceptSuccess", "*")
self:AddTransition("*", "InterceptFailure", "*") self:AddTransition("*", "InterceptFailure", "*")
self:AddTransition("*", "VIDSuccess", "*")
self:AddTransition("*", "VIDFailure", "*")
self:AddTransition("*", "Stop", "Stopped") -- Stop FSM. self:AddTransition("*", "Stop", "Stopped") -- Stop FSM.
@@ -1363,19 +1367,39 @@ function AWACS:New(Name,AirWing,Coalition,AirbaseName,AwacsOrbit,OpsZone,Station
-- @param #string To To state. -- @param #string To To state.
--- On After "InterceptSuccess" event. Intercept successful. --- On After "InterceptSuccess" event. Intercept successful.
-- @function [parent=#AWACS] OnAfterIntercept -- @function [parent=#AWACS] OnAfterInterceptSuccess
-- @param #AWACS self -- @param #AWACS self
-- @param #string From From state. -- @param #string From From state.
-- @param #string Event Event. -- @param #string Event Event.
-- @param #string To To state. -- @param #string To To state.
--- On After "InterceptFailure" event. Intercept failure. --- On After "InterceptFailure" event. Intercept failure.
-- @function [parent=#AWACS] OnAfterIntercept -- @function [parent=#AWACS] OnAfterInterceptFailure
-- @param #AWACS self -- @param #AWACS self
-- @param #string From From state. -- @param #string From From state.
-- @param #string Event Event. -- @param #string Event Event.
-- @param #string To To state. -- @param #string To To state.
--- On After "VIDSuccess" event. Intercept successful.
-- @function [parent=#AWACS] OnAfterVIDSuccess
-- @param #AWACS self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
-- @param #number GID Managed group ID (Player)
-- @param Wrapper.Group#GROUP Group (Player) Group done the VID
-- @param #AWACS.ManagedContact Contact The contact that was VID'd
--- On After "VIDFailure" event. Intercept failure.
-- @function [parent=#AWACS] OnAfterVIDFailure
-- @param #AWACS self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
-- @param #number GID Managed group ID (Player)
-- @param Wrapper.Group#GROUP Group (Player) Group done the VID
-- @param #AWACS.ManagedContact Contact The contact that was VID'd
return self return self
end end
@@ -1572,6 +1596,25 @@ function AWACS:SetLocale(Locale)
return self return self
end end
--- [User] Set own coordinate for BullsEye.
-- @param #AWACS self
-- @param Core.Point#COORDINATE
-- @return #AWACS self
function AWACS:SetBullsCoordinate(Coordinate)
self:T(self.lid.."SetBullsCoordinate")
self.AOCoordinate = Coordinate
return self
end
--- [User] Set the max mission range flights can be away from their home base.
-- @param #AWACS self
-- @param #number NM Distance in nautical miles
-- @return #AWACS self
function AWACS:SetMaxMissionRange(NM)
self.MaxMissionRange = NM or 125
return self
end
--- [User] Add additional frequency and modulation for AWACS SRS output. --- [User] Add additional frequency and modulation for AWACS SRS output.
-- @param #AWACS self -- @param #AWACS self
-- @param #number Frequency The frequency to add, e.g. 132.5 -- @param #number Frequency The frequency to add, e.g. 132.5
@@ -1762,7 +1805,7 @@ function AWACS:_EventHandler(EventData)
end end
end end
if Event.id == EVENTS.PlayerLeaveUnit then --player left unit if Event.id == EVENTS.PlayerLeaveUnit and Event.IniGroupName then --player left unit
-- check known player? -- check known player?
self:T("Player group left unit: " .. Event.IniGroupName) self:T("Player group left unit: " .. Event.IniGroupName)
self:T("Player name left: " .. Event.IniPlayerName) self:T("Player name left: " .. Event.IniPlayerName)
@@ -1988,7 +2031,9 @@ function AWACS:SetAdditionalZone(Zone, Draw)
self.BorderZone = Zone self.BorderZone = Zone
if self.debug then if self.debug then
Zone:DrawZone(self.coalition,{1,0.64,0},1,{1,0.64,0},0.2,1,true) Zone:DrawZone(self.coalition,{1,0.64,0},1,{1,0.64,0},0.2,1,true)
if self.AllowMarkers then
MARKER:New(Zone:GetCoordinate(),"Defensive Zone"):ToCoalition(self.coalition) MARKER:New(Zone:GetCoordinate(),"Defensive Zone"):ToCoalition(self.coalition)
end
elseif Draw then elseif Draw then
Zone:DrawZone(self.coalition,{1,0.64,0},1,{1,0.64,0},0.2,1,true) Zone:DrawZone(self.coalition,{1,0.64,0},1,{1,0.64,0},0.2,1,true)
end end
@@ -2008,8 +2053,10 @@ function AWACS:SetRejectionZone(Zone,Draw)
--MARKER:New(Zone:GetCoordinate(),"Rejection Zone"):ToAll() --MARKER:New(Zone:GetCoordinate(),"Rejection Zone"):ToAll()
elseif self.debug then elseif self.debug then
Zone:DrawZone(self.coalition,{1,0.64,0},1,{1,0.64,0},0.2,1,true) Zone:DrawZone(self.coalition,{1,0.64,0},1,{1,0.64,0},0.2,1,true)
if self.AllowMarkers then
MARKER:New(Zone:GetCoordinate(),"Rejection Zone"):ToCoalition(self.coalition) MARKER:New(Zone:GetCoordinate(),"Rejection Zone"):ToCoalition(self.coalition)
end end
end
return self return self
end end
@@ -2080,7 +2127,7 @@ end
--- [User] Set AWACS SRS TTS details - see @{Sound.SRS} for details. `SetSRS()` will try to use as many attributes configured with @{Sound.SRS#MSRS.LoadConfigFile}() as possible. --- [User] Set AWACS SRS TTS details - see @{Sound.SRS} for details. `SetSRS()` will try to use as many attributes configured with @{Sound.SRS#MSRS.LoadConfigFile}() as possible.
-- @param #AWACS self -- @param #AWACS self
-- @param #string PathToSRS Defaults to "C:\\Program Files\\DCS-SimpleRadio-Standalone" -- @param #string PathToSRS Defaults to "C:\\Program Files\\DCS-SimpleRadio-Standalone\\ExternalAudio"
-- @param #string Gender Defaults to "male" -- @param #string Gender Defaults to "male"
-- @param #string Culture Defaults to "en-US" -- @param #string Culture Defaults to "en-US"
-- @param #number Port Defaults to 5002 -- @param #number Port Defaults to 5002
@@ -2093,7 +2140,7 @@ end
-- @return #AWACS self -- @return #AWACS self
function AWACS:SetSRS(PathToSRS,Gender,Culture,Port,Voice,Volume,PathToGoogleKey,AccessKey,Backend) function AWACS:SetSRS(PathToSRS,Gender,Culture,Port,Voice,Volume,PathToGoogleKey,AccessKey,Backend)
self:T(self.lid.."SetSRS") self:T(self.lid.."SetSRS")
self.PathToSRS = PathToSRS or MSRS.path or "C:\\Program Files\\DCS-SimpleRadio-Standalone" self.PathToSRS = PathToSRS or MSRS.path or "C:\\Program Files\\DCS-SimpleRadio-Standalone\\ExternalAudio"
self.Gender = Gender or MSRS.gender or "male" self.Gender = Gender or MSRS.gender or "male"
self.Culture = Culture or MSRS.culture or "en-US" self.Culture = Culture or MSRS.culture or "en-US"
self.Port = Port or MSRS.port or 5002 self.Port = Port or MSRS.port or 5002
@@ -2158,9 +2205,12 @@ end
--- [User] Set AWACS Escorts Template --- [User] Set AWACS Escorts Template
-- @param #AWACS self -- @param #AWACS self
-- @param #number EscortNumber Number of fighther planes to accompany this AWACS. 0 or nil means no escorts. -- @param #number EscortNumber Number of fighther plane GROUPs to accompany this AWACS. 0 or nil means no escorts. If you want >1 plane in an escort group, you can either set the respective squadron grouping to the desired number, or use a template for escorts with >1 unit.
-- @param #number Formation Formation the escort should take (if more than one plane), e.g. `ENUMS.Formation.FixedWing.FingerFour.Group`. Formation is used on GROUP level, multiple groups of one unit will NOT conform to this formation.
-- @param #table OffsetVector Offset the escorts should fly behind the AWACS, given as table, distance in meters, e.g. `{x=-500,y=0,z=500}` - 500m behind (negative value) and to the right (negative for left), no vertical separation (positive over, negative under the AWACS flight). For multiple groups, the vectors will be slightly changed to avoid collisions.
-- @param #number EscortEngageMaxDistance Escorts engage air targets max this NM away, defaults to 45NM.
-- @return #AWACS self -- @return #AWACS self
function AWACS:SetEscort(EscortNumber) function AWACS:SetEscort(EscortNumber,Formation,OffsetVector,EscortEngageMaxDistance)
self:T(self.lid.."SetEscort") self:T(self.lid.."SetEscort")
if EscortNumber and EscortNumber > 0 then if EscortNumber and EscortNumber > 0 then
self.HasEscorts = true self.HasEscorts = true
@@ -2169,6 +2219,9 @@ function AWACS:SetEscort(EscortNumber)
self.HasEscorts = false self.HasEscorts = false
self.EscortNumber = 0 self.EscortNumber = 0
end end
self.EscortFormation = Formation
self.OffsetVec = OffsetVector or {x=500,y=100,z=500}
self.EscortEngageMaxDistance = EscortEngageMaxDistance or 45
return self return self
end end
@@ -2223,11 +2276,26 @@ function AWACS:_StartEscorts(Shiftchange)
local group = AwacsFG:GetGroup() local group = AwacsFG:GetGroup()
local timeonstation = (self.EscortsTimeOnStation + self.ShiftChangeTime) * 3600 -- hours to seconds local timeonstation = (self.EscortsTimeOnStation + self.ShiftChangeTime) * 3600 -- hours to seconds
local OffsetX = 500
local OffsetY = 500
local OffsetZ = 500
if self.OffsetVec then
OffsetX = self.OffsetVec.x or 500
OffsetY = self.OffsetVec.y or 500
OffsetZ = self.OffsetVec.z or 500
end
for i=1,self.EscortNumber do for i=1,self.EscortNumber do
-- every -- every
local escort = AUFTRAG:NewESCORT(group, {x= -100*((i + (i%2))/2), y=0, z=(100 + 100*((i + (i%2))/2))*(-1)^i},45,{"Air"}) local escort = AUFTRAG:NewESCORT(group, {x= OffsetX*((i + (i%2))/2), y=OffsetY*((i + (i%2))/2), z=(OffsetZ + OffsetZ*((i + (i%2))/2))*(-1)^i},self.EscortEngageMaxDistance,{"Air"})
escort:SetRequiredAssets(1) --local escort = AUFTRAG:NewESCORT(group,self.OffsetVec,self.EscortEngageMaxDistance,{"Air"})
--escort:SetRequiredAssets(self.EscortNumber)
escort:SetTime(nil,timeonstation) escort:SetTime(nil,timeonstation)
if self.Escortformation then
escort:SetFormation(self.Escortformation)
end
escort:SetMissionRange(self.MaxMissionRange)
self.AirWing:AddMission(escort) self.AirWing:AddMission(escort)
self.CatchAllMissions[#self.CatchAllMissions+1] = escort self.CatchAllMissions[#self.CatchAllMissions+1] = escort
@@ -2434,7 +2502,7 @@ function AWACS:_GetCallSign(Group,GID, IsPlayer)
local callsign = "Ghost 1" local callsign = "Ghost 1"
if Group and Group:IsAlive() then if Group and Group:IsAlive() then
callsign = Group:GetCustomCallSign(self.callsignshort,self.keepnumber,self.callsignTranslations) callsign = Group:GetCustomCallSign(self.callsignshort,self.keepnumber,self.callsignTranslations,self.callsignCustomFunc,self.callsignCustomArgs)
end end
return callsign return callsign
end end
@@ -2443,10 +2511,12 @@ end
-- @param #AWACS self -- @param #AWACS self
-- @param #boolean ShortCallsign If true, only call out the major flight number -- @param #boolean ShortCallsign If true, only call out the major flight number
-- @param #boolean Keepnumber If true, keep the **customized callsign** in the #GROUP name as-is, no amendments or numbers. -- @param #boolean Keepnumber If true, keep the **customized callsign** in the #GROUP name as-is, no amendments or numbers.
-- @param #table CallsignTranslations (optional) Table to translate between DCS standard callsigns and bespoke ones. Does not apply if using customized -- @param #table CallsignTranslations (Optional) Table to translate between DCS standard callsigns and bespoke ones. Does not apply if using customized.
-- callsigns from playername or group name. -- callsigns from playername or group name.
-- @param #func CallsignCustomFunc (Optional) For player names only(!). If given, this function will return the callsign. Needs to take the groupname and the playername as first two arguments.
-- @param #arg ... (Optional) Comma separated arguments to add to the custom function call after groupname and playername.
-- @return #AWACS self -- @return #AWACS self
function AWACS:SetCallSignOptions(ShortCallsign,Keepnumber,CallsignTranslations) function AWACS:SetCallSignOptions(ShortCallsign,Keepnumber,CallsignTranslations,CallsignCustomFunc,...)
if not ShortCallsign or ShortCallsign == false then if not ShortCallsign or ShortCallsign == false then
self.callsignshort = false self.callsignshort = false
else else
@@ -2454,6 +2524,8 @@ function AWACS:SetCallSignOptions(ShortCallsign,Keepnumber,CallsignTranslations)
end end
self.keepnumber = Keepnumber or false self.keepnumber = Keepnumber or false
self.callsignTranslations = CallsignTranslations self.callsignTranslations = CallsignTranslations
self.callsignCustomFunc = CallsignCustomFunc
self.callsignCustomArgs = arg or {}
return self return self
end end
@@ -3227,12 +3299,14 @@ function AWACS:_VID(Group,Declaration)
local vidpos = self.gettext:GetEntry("VIDPOS",self.locale) local vidpos = self.gettext:GetEntry("VIDPOS",self.locale)
text = string.format(vidpos,Callsign,self.callsigntxt, Declaration) text = string.format(vidpos,Callsign,self.callsigntxt, Declaration)
self:T(text) self:T(text)
self:__VIDSuccess(3,GID,group,cluster)
else else
-- too far away -- too far away
self:T("Contact VID not close enough") self:T("Contact VID not close enough")
local vidneg = self.gettext:GetEntry("VIDNEG",self.locale) local vidneg = self.gettext:GetEntry("VIDNEG",self.locale)
text = string.format(vidneg,Callsign,self.callsigntxt) text = string.format(vidneg,Callsign,self.callsigntxt)
self:T(text) self:T(text)
self:__VIDFailure(3,GID,group,cluster)
end end
self:_NewRadioEntry(text,text,GID,Outcome,true,true,false,true) self:_NewRadioEntry(text,text,GID,Outcome,true,true,false,true)
end end
@@ -3893,6 +3967,12 @@ function AWACS:_SetClientMenus()
checkin = checkin, checkin = checkin,
} }
self.clientmenus:Push(menus,cgrpname) self.clientmenus:Push(menus,cgrpname)
-- catch errors - when this entry is built we should NOT have a managed entry
local GID,hasentry = self:_GetManagedGrpID(cgrp)
if hasentry then
-- this user is checked in but has the check in entry ... not good.
self:_CheckOut(cgrp,GID,true)
end
end end
end end
else else
@@ -4028,11 +4108,15 @@ function AWACS:_CreateAnchorStackFromMarker(Name,Coord)
if self.debug then if self.debug then
AnchorStackOne.StationZone:DrawZone(self.coalition,{0,0,1},1,{0,0,1},0.2,5,true) AnchorStackOne.StationZone:DrawZone(self.coalition,{0,0,1},1,{0,0,1},0.2,5,true)
local stationtag = string.format("Station: %s\nCoordinate: %s",newname,self.StationZone:GetCoordinate():ToStringLLDDM()) local stationtag = string.format("Station: %s\nCoordinate: %s",newname,self.StationZone:GetCoordinate():ToStringLLDDM())
if self.AllowMarkers then
AnchorStackOne.AnchorMarker=MARKER:New(AnchorStackOne.StationZone:GetCoordinate(),stationtag):ToCoalition(self.coalition) AnchorStackOne.AnchorMarker=MARKER:New(AnchorStackOne.StationZone:GetCoordinate(),stationtag):ToCoalition(self.coalition)
end
else else
local stationtag = string.format("Station: %s\nCoordinate: %s",newname,self.StationZone:GetCoordinate():ToStringLLDDM()) local stationtag = string.format("Station: %s\nCoordinate: %s",newname,self.StationZone:GetCoordinate():ToStringLLDDM())
if self.AllowMarkers then
AnchorStackOne.AnchorMarker=MARKER:New(AnchorStackOne.StationZone:GetCoordinate(),stationtag):ToCoalition(self.coalition) AnchorStackOne.AnchorMarker=MARKER:New(AnchorStackOne.StationZone:GetCoordinate(),stationtag):ToCoalition(self.coalition)
end end
end
self.AnchorStacks:Push(AnchorStackOne,newname) self.AnchorStacks:Push(AnchorStackOne,newname)
self.PlayerStationName = newname self.PlayerStationName = newname
@@ -4074,11 +4158,15 @@ function AWACS:_CreateAnchorStack()
--self.AnchorStacks:Flush() --self.AnchorStacks:Flush()
AnchorStackOne.StationZone:DrawZone(self.coalition,{0,0,1},1,{0,0,1},0.2,5,true) AnchorStackOne.StationZone:DrawZone(self.coalition,{0,0,1},1,{0,0,1},0.2,5,true)
local stationtag = string.format("Station: %s\nCoordinate: %s",newname,self.StationZone:GetCoordinate():ToStringLLDDM()) local stationtag = string.format("Station: %s\nCoordinate: %s",newname,self.StationZone:GetCoordinate():ToStringLLDDM())
if self.AllowMarkers then
AnchorStackOne.AnchorMarker=MARKER:New(AnchorStackOne.StationZone:GetCoordinate(),stationtag):ToCoalition(self.coalition) AnchorStackOne.AnchorMarker=MARKER:New(AnchorStackOne.StationZone:GetCoordinate(),stationtag):ToCoalition(self.coalition)
end
else else
local stationtag = string.format("Station: %s\nCoordinate: %s",newname,self.StationZone:GetCoordinate():ToStringLLDDM()) local stationtag = string.format("Station: %s\nCoordinate: %s",newname,self.StationZone:GetCoordinate():ToStringLLDDM())
if self.AllowMarkers then
AnchorStackOne.AnchorMarker=MARKER:New(AnchorStackOne.StationZone:GetCoordinate(),stationtag):ToCoalition(self.coalition) AnchorStackOne.AnchorMarker=MARKER:New(AnchorStackOne.StationZone:GetCoordinate(),stationtag):ToCoalition(self.coalition)
end end
end
self.AnchorStacks:Push(AnchorStackOne,newname) self.AnchorStacks:Push(AnchorStackOne,newname)
else else
local newsubname = AWACS.AnchorNames[stackscreated+1] or tostring(stackscreated+1) local newsubname = AWACS.AnchorNames[stackscreated+1] or tostring(stackscreated+1)
@@ -4101,11 +4189,15 @@ function AWACS:_CreateAnchorStack()
if self.debug then if self.debug then
AnchorStackOne.StationZone:DrawZone(self.coalition,{0,0,1},1,{0,0,1},0.2,5,true) AnchorStackOne.StationZone:DrawZone(self.coalition,{0,0,1},1,{0,0,1},0.2,5,true)
local stationtag = string.format("Station: %s\nCoordinate: %s",newname,self.StationZone:GetCoordinate():ToStringLLDDM()) local stationtag = string.format("Station: %s\nCoordinate: %s",newname,self.StationZone:GetCoordinate():ToStringLLDDM())
if self.AllowMarkers then
AnchorStackOne.AnchorMarker=MARKER:New(AnchorStackOne.StationZone:GetCoordinate(),stationtag):ToCoalition(self.coalition) AnchorStackOne.AnchorMarker=MARKER:New(AnchorStackOne.StationZone:GetCoordinate(),stationtag):ToCoalition(self.coalition)
end
else else
local stationtag = string.format("Station: %s\nCoordinate: %s",newname,self.StationZone:GetCoordinate():ToStringLLDDM()) local stationtag = string.format("Station: %s\nCoordinate: %s",newname,self.StationZone:GetCoordinate():ToStringLLDDM())
if self.AllowMarkers then
AnchorStackOne.AnchorMarker=MARKER:New(AnchorStackOne.StationZone:GetCoordinate(),stationtag):ToCoalition(self.coalition) AnchorStackOne.AnchorMarker=MARKER:New(AnchorStackOne.StationZone:GetCoordinate(),stationtag):ToCoalition(self.coalition)
end end
end
self.AnchorStacks:Push(AnchorStackOne,newname) self.AnchorStacks:Push(AnchorStackOne,newname)
end end
@@ -5036,11 +5128,15 @@ function AWACS:AddCAPAirWing(AirWing,Zone)
if self.debug then if self.debug then
AnchorStackOne.StationZone:DrawZone(self.coalition,{0,0,1},1,{0,0,1},0.2,5,true) AnchorStackOne.StationZone:DrawZone(self.coalition,{0,0,1},1,{0,0,1},0.2,5,true)
local stationtag = string.format("Station: %s\nCoordinate: %s",newname,self.StationZone:GetCoordinate():ToStringLLDDM()) local stationtag = string.format("Station: %s\nCoordinate: %s",newname,self.StationZone:GetCoordinate():ToStringLLDDM())
if self.AllowMarkers then
AnchorStackOne.AnchorMarker=MARKER:New(AnchorStackOne.StationZone:GetCoordinate(),stationtag):ToCoalition(self.coalition) AnchorStackOne.AnchorMarker=MARKER:New(AnchorStackOne.StationZone:GetCoordinate(),stationtag):ToCoalition(self.coalition)
end
else else
local stationtag = string.format("Station: %s\nCoordinate: %s",newname,self.StationZone:GetCoordinate():ToStringLLDDM()) local stationtag = string.format("Station: %s\nCoordinate: %s",newname,self.StationZone:GetCoordinate():ToStringLLDDM())
if self.AllowMarkers then
AnchorStackOne.AnchorMarker=MARKER:New(AnchorStackOne.StationZone:GetCoordinate(),stationtag):ToCoalition(self.coalition) AnchorStackOne.AnchorMarker=MARKER:New(AnchorStackOne.StationZone:GetCoordinate(),stationtag):ToCoalition(self.coalition)
end end
end
self.AnchorStacks:Push(AnchorStackOne,newname) self.AnchorStacks:Push(AnchorStackOne,newname)
AirWing.HasOwnStation = true AirWing.HasOwnStation = true
AirWing.StationName = newname AirWing.StationName = newname
@@ -5739,7 +5835,7 @@ function AWACS:_AssignPilotToTarget(Pilots,Targets)
local intercept = AUFTRAG:NewINTERCEPT(Target.Target) local intercept = AUFTRAG:NewINTERCEPT(Target.Target)
intercept:SetWeaponExpend(AI.Task.WeaponExpend.ALL) intercept:SetWeaponExpend(AI.Task.WeaponExpend.ALL)
intercept:SetWeaponType(ENUMS.WeaponFlag.Auto) intercept:SetWeaponType(ENUMS.WeaponFlag.Auto)
intercept:SetMissionRange(self.MaxMissionRange)
-- TODO -- TODO
-- now this is going to be interesting... -- now this is going to be interesting...
-- Check if the target left the "hot" area or is dead already -- Check if the target left the "hot" area or is dead already
@@ -5787,6 +5883,7 @@ function AWACS:_AssignPilotToTarget(Pilots,Targets)
AnchorSpeed = UTILS.KnotsToAltKIAS(AnchorSpeed,Angels) AnchorSpeed = UTILS.KnotsToAltKIAS(AnchorSpeed,Angels)
local Anchor = self.AnchorStacks:ReadByPointer(Pilot.AnchorStackNo) -- #AWACS.AnchorData local Anchor = self.AnchorStacks:ReadByPointer(Pilot.AnchorStackNo) -- #AWACS.AnchorData
local capauftrag = AUFTRAG:NewCAP(Anchor.StationZone,Angels,AnchorSpeed,Anchor.StationZoneCoordinate,0,15,{}) local capauftrag = AUFTRAG:NewCAP(Anchor.StationZone,Angels,AnchorSpeed,Anchor.StationZoneCoordinate,0,15,{})
capauftrag:SetMissionRange(self.MaxMissionRange)
capauftrag:SetTime(nil,((self.CAPTimeOnStation*3600)+(15*60))) capauftrag:SetTime(nil,((self.CAPTimeOnStation*3600)+(15*60)))
Pilot.FlightGroup:AddMission(capauftrag) Pilot.FlightGroup:AddMission(capauftrag)
@@ -5881,29 +5978,43 @@ function AWACS:onafterStart(From, Event, To)
self.OpsZone:DrawZone(self.coalition,{1,0,0},1,{1,0,0},0.2,5,true) self.OpsZone:DrawZone(self.coalition,{1,0,0},1,{1,0,0},0.2,5,true)
local AOCoordString = self.AOCoordinate:ToStringLLDDM() local AOCoordString = self.AOCoordinate:ToStringLLDDM()
local Rocktag = string.format("FEZ: %s\nBulls Coordinate: %s",self.AOName,AOCoordString) local Rocktag = string.format("FEZ: %s\nBulls Coordinate: %s",self.AOName,AOCoordString)
if self.AllowMarkers then
MARKER:New(self.AOCoordinate,Rocktag):ToCoalition(self.coalition) MARKER:New(self.AOCoordinate,Rocktag):ToCoalition(self.coalition)
end
self.StationZone:DrawZone(self.coalition,{0,0,1},1,{0,0,1},0.2,5,true) self.StationZone:DrawZone(self.coalition,{0,0,1},1,{0,0,1},0.2,5,true)
local stationtag = string.format("Station: %s\nCoordinate: %s",self.StationZoneName,self.StationZone:GetCoordinate():ToStringLLDDM()) local stationtag = string.format("Station: %s\nCoordinate: %s",self.StationZoneName,self.StationZone:GetCoordinate():ToStringLLDDM())
if not self.GCI then if not self.GCI then
if self.AllowMarkers then
MARKER:New(self.StationZone:GetCoordinate(),stationtag):ToCoalition(self.coalition) MARKER:New(self.StationZone:GetCoordinate(),stationtag):ToCoalition(self.coalition)
end
self.OrbitZone:DrawZone(self.coalition,{0,1,0},1,{0,1,0},0.2,5,true) self.OrbitZone:DrawZone(self.coalition,{0,1,0},1,{0,1,0},0.2,5,true)
if self.AllowMarkers then
MARKER:New(self.OrbitZone:GetCoordinate(),"AIC Orbit Zone"):ToCoalition(self.coalition) MARKER:New(self.OrbitZone:GetCoordinate(),"AIC Orbit Zone"):ToCoalition(self.coalition)
end end
end
else else
local AOCoordString = self.AOCoordinate:ToStringLLDDM() local AOCoordString = self.AOCoordinate:ToStringLLDDM()
local Rocktag = string.format("FEZ: %s\nBulls Coordinate: %s",self.AOName,AOCoordString) local Rocktag = string.format("FEZ: %s\nBulls Coordinate: %s",self.AOName,AOCoordString)
if self.AllowMarkers then
MARKER:New(self.AOCoordinate,Rocktag):ToCoalition(self.coalition) MARKER:New(self.AOCoordinate,Rocktag):ToCoalition(self.coalition)
end
if not self.GCI then if not self.GCI then
if self.AllowMarkers then
MARKER:New(self.OrbitZone:GetCoordinate(),"AIC Orbit Zone"):ToCoalition(self.coalition) MARKER:New(self.OrbitZone:GetCoordinate(),"AIC Orbit Zone"):ToCoalition(self.coalition)
end end
end
local stationtag = string.format("Station: %s\nCoordinate: %s",self.StationZoneName,self.StationZone:GetCoordinate():ToStringLLDDM()) local stationtag = string.format("Station: %s\nCoordinate: %s",self.StationZoneName,self.StationZone:GetCoordinate():ToStringLLDDM())
if self.AllowMarkers then
MARKER:New(self.StationZone:GetCoordinate(),stationtag):ToCoalition(self.coalition) MARKER:New(self.StationZone:GetCoordinate(),stationtag):ToCoalition(self.coalition)
end end
end
if not self.GCI then if not self.GCI then
-- set up the AWACS and let it orbit -- set up the AWACS and let it orbit
local AwacsAW = self.AirWing -- Ops.Airwing#AIRWING local AwacsAW = self.AirWing -- Ops.Airwing#AIRWING
local mission = AUFTRAG:NewORBIT_RACETRACK(self.OrbitZone:GetCoordinate(),self.AwacsAngels*1000,self.Speed,self.Heading,self.Leg) local mission = AUFTRAG:NewORBIT_RACETRACK(self.OrbitZone:GetCoordinate(),self.AwacsAngels*1000,self.Speed,self.Heading,self.Leg)
mission:SetMissionRange(self.MaxMissionRange)
mission:SetRequiredAttribute({ GROUP.Attribute.AIR_AWACS }) -- prefered plane type, thanks to Heart8reaker
local timeonstation = (self.AwacsTimeOnStation + self.ShiftChangeTime) * 3600 local timeonstation = (self.AwacsTimeOnStation + self.ShiftChangeTime) * 3600
mission:SetTime(nil,timeonstation) mission:SetTime(nil,timeonstation)
self.CatchAllMissions[#self.CatchAllMissions+1] = mission self.CatchAllMissions[#self.CatchAllMissions+1] = mission
@@ -6046,6 +6157,7 @@ function AWACS:_CheckAwacsStatus()
end end
end end
end end
-------------------------------- --------------------------------
-- AWACS -- AWACS
-------------------------------- --------------------------------
@@ -6194,12 +6306,13 @@ function AWACS:_CheckAwacsStatus()
report:Add("====================") report:Add("====================")
local RESMission
-- Check for replacement mission - if any -- Check for replacement mission - if any
if self.ShiftChangeEscortsFlag and self.ShiftChangeEscortsRequested then -- Ops.Auftrag#AUFTRAG if self.ShiftChangeEscortsFlag and self.ShiftChangeEscortsRequested then -- Ops.Auftrag#AUFTRAG
ESmission = self.EscortMissionReplacement[i] RESMission = self.EscortMissionReplacement[i]
local esstatus = ESmission:GetState() local esstatus = RESMission:GetState()
local ESmissiontime = (timer.getTime() - self.EscortsTimeStamp) local RESMissiontime = (timer.getTime() - self.EscortsTimeStamp)
local ESTOSLeft = UTILS.Round((((self.EscortsTimeOnStation+self.ShiftChangeTime)*3600) - ESmissiontime),0) -- seconds local ESTOSLeft = UTILS.Round((((self.EscortsTimeOnStation+self.ShiftChangeTime)*3600) - RESMissiontime),0) -- seconds
ESTOSLeft = UTILS.Round(ESTOSLeft/60,0) -- minutes ESTOSLeft = UTILS.Round(ESTOSLeft/60,0) -- minutes
local ChangeTime = UTILS.Round(((self.ShiftChangeTime * 3600)/60),0) local ChangeTime = UTILS.Round(((self.ShiftChangeTime * 3600)/60),0)
@@ -6207,7 +6320,7 @@ function AWACS:_CheckAwacsStatus()
report:Add(string.format("Auftrag Status: %s",esstatus)) report:Add(string.format("Auftrag Status: %s",esstatus))
report:Add(string.format("TOS Left: %d min",ESTOSLeft)) report:Add(string.format("TOS Left: %d min",ESTOSLeft))
local OpsGroups = ESmission:GetOpsGroups() local OpsGroups = RESMission:GetOpsGroups()
local OpsGroup = self:_GetAliveOpsGroupFromTable(OpsGroups) -- Ops.OpsGroup#OPSGROUP local OpsGroup = self:_GetAliveOpsGroupFromTable(OpsGroups) -- Ops.OpsGroup#OPSGROUP
if OpsGroup then if OpsGroup then
local OpsName = OpsGroup:GetName() or "Unknown" local OpsName = OpsGroup:GetName() or "Unknown"
@@ -6219,13 +6332,13 @@ function AWACS:_CheckAwacsStatus()
report:Add("***** Cannot obtain (yet) this missions OpsGroup!") report:Add("***** Cannot obtain (yet) this missions OpsGroup!")
end end
if ESmission:IsExecuting() then if RESMission and RESMission:IsExecuting() then
-- make the actual change in the queue -- make the actual change in the queue
self.ShiftChangeEscortsFlag = false self.ShiftChangeEscortsFlag = false
self.ShiftChangeEscortsRequested = false self.ShiftChangeEscortsRequested = false
-- cancel old mission -- cancel old mission
if ESmission and ESmission:IsNotOver() then if ESmission and ESmission:IsNotOver() then
ESmission:Cancel() ESmission:__Cancel(1)
end end
self.EscortMission[i] = self.EscortMissionReplacement[i] self.EscortMission[i] = self.EscortMissionReplacement[i]
self.EscortMissionReplacement[i] = nil self.EscortMissionReplacement[i] = nil
@@ -6477,6 +6590,7 @@ function AWACS:onafterAssignedAnchor(From, Event, To, GID, Anchor, AnchorStackNo
if auftragtype == AUFTRAG.Type.ALERT5 then if auftragtype == AUFTRAG.Type.ALERT5 then
-- all correct -- all correct
local capauftrag = AUFTRAG:NewCAP(Anchor.StationZone,Angels*1000,AnchorSpeed,Anchor.StationZone:GetCoordinate(),0,15,{}) local capauftrag = AUFTRAG:NewCAP(Anchor.StationZone,Angels*1000,AnchorSpeed,Anchor.StationZone:GetCoordinate(),0,15,{})
capauftrag:SetMissionRange(self.MaxMissionRange)
capauftrag:SetTime(nil,((self.CAPTimeOnStation*3600)+(15*60))) capauftrag:SetTime(nil,((self.CAPTimeOnStation*3600)+(15*60)))
capauftrag:AddAsset(managedgroup.FlightGroup) capauftrag:AddAsset(managedgroup.FlightGroup)
self.CatchAllMissions[#self.CatchAllMissions+1] = capauftrag self.CatchAllMissions[#self.CatchAllMissions+1] = capauftrag
@@ -6840,6 +6954,7 @@ function AWACS:onafterAwacsShiftChange(From,Event,To)
self.CatchAllMissions[#self.CatchAllMissions+1] = mission self.CatchAllMissions[#self.CatchAllMissions+1] = mission
local timeonstation = (self.AwacsTimeOnStation + self.ShiftChangeTime) * 3600 local timeonstation = (self.AwacsTimeOnStation + self.ShiftChangeTime) * 3600
mission:SetTime(nil,timeonstation) mission:SetTime(nil,timeonstation)
mission:SetMissionRange(self.MaxMissionRange)
AwacsAW:AddMission(mission) AwacsAW:AddMission(mission)
+253 -81
View File
@@ -31,7 +31,7 @@
-- @image OPS_CSAR.jpg -- @image OPS_CSAR.jpg
--- ---
-- Last Update July 2024 -- Last Update Oct 2025
------------------------------------------------------------------------- -------------------------------------------------------------------------
--- **CSAR** class, extends Core.Base#BASE, Core.Fsm#FSM --- **CSAR** class, extends Core.Base#BASE, Core.Fsm#FSM
@@ -41,6 +41,7 @@
-- @field #string lid Class id string for output to DCS log file. -- @field #string lid Class id string for output to DCS log file.
-- @field #number coalition Coalition side number, e.g. `coalition.side.RED`. -- @field #number coalition Coalition side number, e.g. `coalition.side.RED`.
-- @field Core.Set#SET_GROUP allheligroupset Set of CSAR heli groups. -- @field Core.Set#SET_GROUP allheligroupset Set of CSAR heli groups.
-- @field Core.Set#SET_GROUP UserSetGroup Set of CSAR heli groups as designed by the mission designer (if any set).
-- @extends Core.Fsm#FSM -- @extends Core.Fsm#FSM
--- *Combat search and rescue (CSAR) are search and rescue operations that are carried out during war that are within or near combat zones.* (Wikipedia) --- *Combat search and rescue (CSAR) are search and rescue operations that are carried out during war that are within or near combat zones.* (Wikipedia)
@@ -91,7 +92,7 @@
-- mycsar.immortalcrew = true -- Set to true to make wounded crew immortal. -- mycsar.immortalcrew = true -- Set to true to make wounded crew immortal.
-- mycsar.invisiblecrew = false -- Set to true to make wounded crew insvisible. -- mycsar.invisiblecrew = false -- Set to true to make wounded crew insvisible.
-- mycsar.loadDistance = 75 -- configure distance for pilots to get into helicopter in meters. -- mycsar.loadDistance = 75 -- configure distance for pilots to get into helicopter in meters.
-- mycsar.mashprefix = {"MASH"} -- prefixes of #GROUP objects used as MASHes. -- mycsar.mashprefix = {"MASH"} -- prefixes of #GROUP objects used as MASHes. Will also try to add ZONE and STATIC objects with this prefix once at startup.
-- mycsar.max_units = 6 -- max number of pilots that can be carried if #CSAR.AircraftType is undefined. -- mycsar.max_units = 6 -- max number of pilots that can be carried if #CSAR.AircraftType is undefined.
-- mycsar.messageTime = 15 -- Time to show messages for in seconds. Doubled for long messages. -- mycsar.messageTime = 15 -- Time to show messages for in seconds. Doubled for long messages.
-- mycsar.radioSound = "beacon.ogg" -- the name of the sound file to use for the pilots\' radio beacons. -- mycsar.radioSound = "beacon.ogg" -- the name of the sound file to use for the pilots\' radio beacons.
@@ -116,11 +117,20 @@
-- mycsar.topmenuname = "CSAR" -- set the menu entry name -- mycsar.topmenuname = "CSAR" -- set the menu entry name
-- mycsar.ADFRadioPwr = 1000 -- ADF Beacons sending with 1KW as default -- mycsar.ADFRadioPwr = 1000 -- ADF Beacons sending with 1KW as default
-- mycsar.PilotWeight = 80 -- Loaded pilots weigh 80kgs each -- mycsar.PilotWeight = 80 -- Loaded pilots weigh 80kgs each
-- mycsar.AllowIRStrobe = false -- Allow a menu item to request an IR strobe to find a downed pilot at night (requires NVGs to see it).
-- mycsar.IRStrobeRuntime = 300 -- If an IR Strobe is activated, it runs for 300 seconds (5 mins).
-- --
-- ## 2.1 SRS Features and Other Features -- ## 2.1 Create own SET_GROUP to manage CTLD Pilot groups
--
-- -- Parameter: Set The SET_GROUP object created by the mission designer/user to represent the CSAR pilot groups.
-- -- Needs to be set before starting the CSAR instance.
-- local myset = SET_GROUP:New():FilterPrefixes("Helikopter"):FilterCoalitions("red"):FilterStart()
-- mycsar:SetOwnSetPilotGroups(myset)
--
-- ## 2.2 SRS Features and Other Features
-- --
-- mycsar.useSRS = false -- Set true to use FF\'s SRS integration -- mycsar.useSRS = false -- Set true to use FF\'s SRS integration
-- mycsar.SRSPath = "C:\\Progra~1\\DCS-SimpleRadio-Standalone\\" -- adjust your own path in your SRS installation -- server(!) -- mycsar.SRSPath = "C:\\Progra~1\\DCS-SimpleRadio-Standalone\\ExternalAudio\\" -- adjust your own path in your SRS installation -- server(!)
-- mycsar.SRSchannel = 300 -- radio channel -- mycsar.SRSchannel = 300 -- radio channel
-- mycsar.SRSModulation = radio.modulation.AM -- modulation -- mycsar.SRSModulation = radio.modulation.AM -- modulation
-- mycsar.SRSport = 5002 -- and SRS Server port -- mycsar.SRSport = 5002 -- and SRS Server port
@@ -136,6 +146,7 @@
-- mycsar.csarUsePara = false -- If set to true, will use the LandingAfterEjection Event instead of Ejection. Requires mycsar.enableForAI to be set to true. --shagrat -- mycsar.csarUsePara = false -- If set to true, will use the LandingAfterEjection Event instead of Ejection. Requires mycsar.enableForAI to be set to true. --shagrat
-- mycsar.wetfeettemplate = "man in floating thingy" -- if you use a mod to have a pilot in a rescue float, put the template name in here for wet feet spawns. Note: in conjunction with csarUsePara this might create dual ejected pilots in edge cases. -- mycsar.wetfeettemplate = "man in floating thingy" -- if you use a mod to have a pilot in a rescue float, put the template name in here for wet feet spawns. Note: in conjunction with csarUsePara this might create dual ejected pilots in edge cases.
-- mycsar.allowbronco = false -- set to true to use the Bronco mod as a CSAR plane -- mycsar.allowbronco = false -- set to true to use the Bronco mod as a CSAR plane
-- mycsar.CreateRadioBeacons = true -- set to false to disallow creating ADF radio beacons.
-- --
-- ## 3. Results -- ## 3. Results
-- --
@@ -252,10 +263,15 @@ CSAR = {
rescuedpilots = 0, rescuedpilots = 0,
limitmaxdownedpilots = true, limitmaxdownedpilots = true,
maxdownedpilots = 10, maxdownedpilots = 10,
useFIFOLimitReplacement = false, -- If true, it will remove the oldest downed pilot when a new one is added, if the limit is reached.
allheligroupset = nil, allheligroupset = nil,
topmenuname = "CSAR", topmenuname = "CSAR",
ADFRadioPwr = 1000, ADFRadioPwr = 1000,
PilotWeight = 80, PilotWeight = 80,
CreateRadioBeacons = true,
UserSetGroup = nil,
AllowIRStrobe = false,
IRStrobeRuntime = 300,
} }
--- Downed pilots info. --- Downed pilots info.
@@ -272,6 +288,7 @@ CSAR = {
-- @field #number timestamp Timestamp for approach process. -- @field #number timestamp Timestamp for approach process.
-- @field #boolean alive Group is alive or dead/rescued. -- @field #boolean alive Group is alive or dead/rescued.
-- @field #boolean wetfeet Group is spawned over (deep) water. -- @field #boolean wetfeet Group is spawned over (deep) water.
-- @field #string BeaconName Name of radio beacon - if any.
--- All slot / Limit settings --- All slot / Limit settings
-- @type CSAR.AircraftType -- @type CSAR.AircraftType
@@ -288,16 +305,17 @@ CSAR.AircraftType["Mi-24P"] = 8
CSAR.AircraftType["Mi-24V"] = 8 CSAR.AircraftType["Mi-24V"] = 8
CSAR.AircraftType["Bell-47"] = 2 CSAR.AircraftType["Bell-47"] = 2
CSAR.AircraftType["UH-60L"] = 10 CSAR.AircraftType["UH-60L"] = 10
CSAR.AircraftType["UH-60L_DAP"] = 2
CSAR.AircraftType["AH-64D_BLK_II"] = 2 CSAR.AircraftType["AH-64D_BLK_II"] = 2
CSAR.AircraftType["Bronco-OV-10A"] = 2 CSAR.AircraftType["Bronco-OV-10A"] = 2
CSAR.AircraftType["MH-60R"] = 10 CSAR.AircraftType["MH-60R"] = 10
CSAR.AircraftType["OH-6A"] = 2 CSAR.AircraftType["OH-6A"] = 2
CSAR.AircraftType["OH-58D"] = 2 CSAR.AircraftType["OH58D"] = 2
CSAR.AircraftType["CH-47Fbl1"] = 31 CSAR.AircraftType["CH-47Fbl1"] = 31
--- CSAR class version. --- CSAR class version.
-- @field #string version -- @field #string version
CSAR.version="1.0.26" CSAR.version="1.0.34"
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- ToDo list -- ToDo list
@@ -452,16 +470,19 @@ function CSAR:New(Coalition, Template, Alias)
-- added 1.0.15 -- added 1.0.15
self.allowbronco = false -- set to true to use the Bronco mod as a CSAR plane self.allowbronco = false -- set to true to use the Bronco mod as a CSAR plane
self.ADFRadioPwr = 1000 self.ADFRadioPwr = 500
-- added 1.0.16 -- added 1.0.16
self.PilotWeight = 80 self.PilotWeight = 80
-- Own SET_GROUP if any
self.UserSetGroup = nil
-- WARNING - here\'ll be dragons -- WARNING - here\'ll be dragons
-- for this to work you need to de-sanitize your mission environment in <DCS root>\Scripts\MissionScripting.lua -- for this to work you need to de-sanitize your mission environment in <DCS root>\Scripts\MissionScripting.lua
-- needs SRS => 1.9.6 to work (works on the *server* side) -- needs SRS => 1.9.6 to work (works on the *server* side)
self.useSRS = false -- Use FF\'s SRS integration self.useSRS = false -- Use FF\'s SRS integration
self.SRSPath = "E:\\Program Files\\DCS-SimpleRadio-Standalone" -- adjust your own path in your server(!) self.SRSPath = "E:\\Program Files\\DCS-SimpleRadio-Standalone\\ExternalAudio" -- adjust your own path in your server(!)
self.SRSchannel = 300 -- radio channel self.SRSchannel = 300 -- radio channel
self.SRSModulation = radio.modulation.AM -- modulation self.SRSModulation = radio.modulation.AM -- modulation
self.SRSport = 5002 -- port self.SRSport = 5002 -- port
@@ -634,7 +655,7 @@ end
-- @param #string Playername Name of Player (if applicable) -- @param #string Playername Name of Player (if applicable)
-- @param #boolean Wetfeet Ejected over water -- @param #boolean Wetfeet Ejected over water
-- @return #CSAR self. -- @return #CSAR self.
function CSAR:_CreateDownedPilotTrack(Group,Groupname,Side,OriginalUnit,Description,Typename,Frequency,Playername,Wetfeet) function CSAR:_CreateDownedPilotTrack(Group,Groupname,Side,OriginalUnit,Description,Typename,Frequency,Playername,Wetfeet,BeaconName)
self:T({"_CreateDownedPilotTrack",Groupname,Side,OriginalUnit,Description,Typename,Frequency,Playername}) self:T({"_CreateDownedPilotTrack",Groupname,Side,OriginalUnit,Description,Typename,Frequency,Playername})
-- create new entry -- create new entry
@@ -642,7 +663,7 @@ function CSAR:_CreateDownedPilotTrack(Group,Groupname,Side,OriginalUnit,Descript
DownedPilot.desc = Description or "" DownedPilot.desc = Description or ""
DownedPilot.frequency = Frequency or 0 DownedPilot.frequency = Frequency or 0
DownedPilot.index = self.downedpilotcounter DownedPilot.index = self.downedpilotcounter
DownedPilot.name = Groupname or "" DownedPilot.name = Groupname or Playername or ""
DownedPilot.originalUnit = OriginalUnit or "" DownedPilot.originalUnit = OriginalUnit or ""
DownedPilot.player = Playername or "" DownedPilot.player = Playername or ""
DownedPilot.side = Side or 0 DownedPilot.side = Side or 0
@@ -651,6 +672,7 @@ function CSAR:_CreateDownedPilotTrack(Group,Groupname,Side,OriginalUnit,Descript
DownedPilot.timestamp = 0 DownedPilot.timestamp = 0
DownedPilot.alive = true DownedPilot.alive = true
DownedPilot.wetfeet = Wetfeet or false DownedPilot.wetfeet = Wetfeet or false
DownedPilot.BeaconName = BeaconName
-- Add Pilot -- Add Pilot
local PilotTable = self.downedPilots local PilotTable = self.downedPilots
@@ -737,7 +759,6 @@ function CSAR:_SpawnPilotInField(country,point,frequency,wetfeet)
:NewWithAlias(template,alias) :NewWithAlias(template,alias)
:InitCoalition(coalition) :InitCoalition(coalition)
:InitCountry(country) :InitCountry(country)
--:InitAIOnOff(pilotcacontrol)
:InitDelayOff() :InitDelayOff()
:SpawnFromCoordinate(point) :SpawnFromCoordinate(point)
@@ -790,6 +811,8 @@ end
-- @param #boolean noMessage -- @param #boolean noMessage
-- @param #string _description Description -- @param #string _description Description
-- @param #boolean forcedesc Use the description only for the pilot track entry -- @param #boolean forcedesc Use the description only for the pilot track entry
-- @return Wrapper.Group#GROUP PilotInField Pilot GROUP object
-- @return #string AliasName Alias display name
function CSAR:_AddCsar(_coalition , _country, _point, _typeName, _unitName, _playerName, _freq, noMessage, _description, forcedesc ) function CSAR:_AddCsar(_coalition , _country, _point, _typeName, _unitName, _playerName, _freq, noMessage, _description, forcedesc )
self:T(self.lid .. " _AddCsar") self:T(self.lid .. " _AddCsar")
self:T({_coalition , _country, _point, _typeName, _unitName, _playerName, _freq, noMessage, _description}) self:T({_coalition , _country, _point, _typeName, _unitName, _playerName, _freq, noMessage, _description})
@@ -819,8 +842,18 @@ function CSAR:_AddCsar(_coalition , _country, _point, _typeName, _unitName, _pla
end end
end end
local BeaconName
if _playerName then
BeaconName = _playerName..math.random(1,10000)
elseif _unitName then
BeaconName = _unitName..math.random(1,10000)
else
BeaconName = "Ghost-1-1"..math.random(1,10000)
end
if (_freq and _freq ~= 0) then --shagrat only add beacon if _freq is NOT 0 if (_freq and _freq ~= 0) then --shagrat only add beacon if _freq is NOT 0
self:_AddBeaconToGroup(_spawnedGroup, _freq) self:_AddBeaconToGroup(_spawnedGroup, _freq, BeaconName)
end end
self:_AddSpecialOptions(_spawnedGroup) self:_AddSpecialOptions(_spawnedGroup)
@@ -845,11 +878,11 @@ function CSAR:_AddCsar(_coalition , _country, _point, _typeName, _unitName, _pla
local _GroupName = _spawnedGroup:GetName() or _alias local _GroupName = _spawnedGroup:GetName() or _alias
self:_CreateDownedPilotTrack(_spawnedGroup,_GroupName,_coalition,_unitName,_text,_typeName,_freq,_playerName,wetfeet) self:_CreateDownedPilotTrack(_spawnedGroup,_GroupName,_coalition,_unitName,_text,_typeName,_freq,_playerName,wetfeet,BeaconName)
self:_InitSARForPilot(_spawnedGroup, _unitName, _freq, noMessage, _playerName) --shagrat use unitName to have the aircraft callsign / descriptive "name" etc. self:_InitSARForPilot(_spawnedGroup, _unitName, _freq, noMessage, _playerName) --shagrat use unitName to have the aircraft callsign / descriptive "name" etc.
return self return _spawnedGroup, _alias
end end
--- (Internal) Function to add a CSAR object into the scene at a zone coordinate. For mission designers wanting to add e.g. PoWs to the scene. --- (Internal) Function to add a CSAR object into the scene at a zone coordinate. For mission designers wanting to add e.g. PoWs to the scene.
@@ -963,7 +996,6 @@ end
-- @param Core.Point#COORDINATE Point -- @param Core.Point#COORDINATE Point
-- @param #number Coalition Coalition. -- @param #number Coalition Coalition.
-- @param #string Description (optional) Description. -- @param #string Description (optional) Description.
-- @param #boolean addBeacon (optional) yes or no.
-- @param #boolean Nomessage (optional) If true, don\'t send a message to SAR. -- @param #boolean Nomessage (optional) If true, don\'t send a message to SAR.
-- @param #string Unitname (optional) Name of the lost unit. -- @param #string Unitname (optional) Name of the lost unit.
-- @param #string Typename (optional) Type of plane. -- @param #string Typename (optional) Type of plane.
@@ -1115,6 +1147,37 @@ function CSAR:_EventHandler(EventData)
return self return self
end end
local initdcscoord = nil
local initcoord = nil
if _event.id == EVENTS.Ejection and _event.TgtDCSUnit then
initdcscoord = _event.TgtDCSUnit:getPoint()
initcoord = COORDINATE:NewFromVec3(initdcscoord)
self:T({initdcscoord})
elseif _event.IniDCSUnit then
initdcscoord = _event.IniDCSUnit:getPoint()
initcoord = COORDINATE:NewFromVec3(initdcscoord)
self:T({initdcscoord})
end
-- Remove downed pilot if already exists to replace with new one.
if _event.IniPlayerName then
local PilotTable = self.downedPilots --#CSAR.DownedPilot
local _foundPilot = nil
for _,_pilot in pairs(PilotTable) do
if _pilot.player == _event.IniPlayerName and _pilot.alive == true then
_foundPilot = _pilot
break
end
end
if _foundPilot then
self:T("Downed pilot already exists!")
_foundPilot.group:Destroy(false)
self:_RemoveNameFromDownedPilots(_foundPilot.name)
self:_CheckDownedPilotTable()
end
end
-- limit no of pilots in the field. -- limit no of pilots in the field.
if self.limitmaxdownedpilots and self:_ReachedPilotLimit() then if self.limitmaxdownedpilots and self:_ReachedPilotLimit() then
self:T("Maxed Downed Pilot!") self:T("Maxed Downed Pilot!")
@@ -1127,18 +1190,6 @@ function CSAR:_EventHandler(EventData)
local wetfeet = false local wetfeet = false
local initdcscoord = nil
local initcoord = nil
if _event.id == EVENTS.Ejection then
initdcscoord = _event.TgtDCSUnit:getPoint()
initcoord = COORDINATE:NewFromVec3(initdcscoord)
self:T({initdcscoord})
else
initdcscoord = _event.IniDCSUnit:getPoint()
initcoord = COORDINATE:NewFromVec3(initdcscoord)
self:T({initdcscoord})
end
--local surface = _unit:GetCoordinate():GetSurfaceType() --local surface = _unit:GetCoordinate():GetSurfaceType()
local surface = initcoord:GetSurfaceType() local surface = initcoord:GetSurfaceType()
@@ -1149,7 +1200,7 @@ function CSAR:_EventHandler(EventData)
-- all checks passed, get going. -- all checks passed, get going.
if self.csarUsePara == false or (self.csarUsePara and wetfeet ) then --shagrat check parameter LandingAfterEjection, if true don't spawn a Pilot from EJECTION event, wait for the Chute to land if self.csarUsePara == false or (self.csarUsePara and wetfeet ) then --shagrat check parameter LandingAfterEjection, if true don't spawn a Pilot from EJECTION event, wait for the Chute to land
local _freq = self:_GenerateADFFrequency() local _freq = self:_GenerateADFFrequency()
self:_AddCsar(_coalition, _unit:GetCountry(), initcoord , _unit:GetTypeName(), _unit:GetName(), _event.IniPlayerName, _freq, false, "none") self:_AddCsar(_coalition, _unit:GetCountry(), initcoord , _unit:GetTypeName(), _unit:GetName(), _event.IniPlayerName, _freq, self.suppressmessages, "none")
return self return self
end end
@@ -1193,7 +1244,10 @@ function CSAR:_EventHandler(EventData)
if _place:GetCoalition() == self.coalition or _place:GetCoalition() == coalition.side.NEUTRAL then if _place:GetCoalition() == self.coalition or _place:GetCoalition() == coalition.side.NEUTRAL then
self:__Landed(2,_event.IniUnitName, _place) self:__Landed(2,_event.IniUnitName, _place)
self:_ScheduledSARFlight(_event.IniUnitName,_event.IniGroupName,true,true) local IsHeloBase = false
local ABName = _place:GetName()
if ABName and string.find(ABName,"^H") then IsHeloBase = true end -- if name starts with an H it's an (possibly elevated) helo base on current maps
self:_ScheduledSARFlight(_event.IniUnitName,_event.IniGroupName,true,true,IsHeloBase)
else else
self:T(string.format("Airfield %d, Unit %d", _place:GetCoalition(), _unit:GetCoalition())) self:T(string.format("Airfield %d, Unit %d", _place:GetCoalition(), _unit:GetCoalition()))
end end
@@ -1214,7 +1268,7 @@ function CSAR:_EventHandler(EventData)
if _coalition == self.coalition then if _coalition == self.coalition then
local _freq = self:_GenerateADFFrequency() local _freq = self:_GenerateADFFrequency()
self:I({coalition=_coalition,country= _country, coord=_LandingPos, name=_unitname, player=_event.IniPlayerName, freq=_freq}) self:I({coalition=_coalition,country= _country, coord=_LandingPos, name=_unitname, player=_event.IniPlayerName, freq=_freq})
self:_AddCsar(_coalition, _country, _LandingPos, nil, _unitname, _event.IniPlayerName, _freq, false, "none")--shagrat add CSAR at Parachute location. self:_AddCsar(_coalition, _country, _LandingPos, nil, _unitname, _event.IniPlayerName, _freq, self.suppressmessages, "none")--shagrat add CSAR at Parachute location.
Unit.destroy(_event.initiator) -- shagrat remove static Pilot model Unit.destroy(_event.initiator) -- shagrat remove static Pilot model
end end
@@ -1680,8 +1734,9 @@ end
-- @param #string heliname Heli name -- @param #string heliname Heli name
-- @param #string groupname Group name -- @param #string groupname Group name
-- @param #boolean isairport If true, EVENT.Landing took place at an airport or FARP -- @param #boolean isairport If true, EVENT.Landing took place at an airport or FARP
-- @param #boolean noreschedule If true, do not try to reschedule this is distances are not ok (coming from landing event) -- @param #boolean noreschedule If true, do not try to reschedule this if distances are not ok (coming from landing event)
function CSAR:_ScheduledSARFlight(heliname,groupname, isairport, noreschedule) -- @param #boolean IsHeloBase If true, landing took place at a Helo Base (name "H ..." on current maps)
function CSAR:_ScheduledSARFlight(heliname,groupname, isairport, noreschedule, IsHeloBase)
self:T(self.lid .. " _ScheduledSARFlight") self:T(self.lid .. " _ScheduledSARFlight")
self:T({heliname,groupname}) self:T({heliname,groupname})
local _heliUnit = self:_GetSARHeli(heliname) local _heliUnit = self:_GetSARHeli(heliname)
@@ -1707,7 +1762,7 @@ function CSAR:_ScheduledSARFlight(heliname,groupname, isairport, noreschedule)
self:T(self.lid.."[Drop off debug] Check distance to MASH for "..heliname.." Distance km: "..math.floor(_dist/1000)) self:T(self.lid.."[Drop off debug] Check distance to MASH for "..heliname.." Distance km: "..math.floor(_dist/1000))
if ( _dist < self.FARPRescueDistance or isairport ) and _heliUnit:InAir() == false then if ( _dist < self.FARPRescueDistance or isairport ) and ((_heliUnit:InAir() == false) or (IsHeloBase == true)) then
self:T(self.lid.."[Drop off debug] Distance ok, door check") self:T(self.lid.."[Drop off debug] Distance ok, door check")
if self.pilotmustopendoors and self:_IsLoadingDoorOpen(heliname) == false then if self.pilotmustopendoors and self:_IsLoadingDoorOpen(heliname) == false then
self:_DisplayMessageToSAR(_heliUnit, "Open the door to let me out!", self.messageTime, true, true) self:_DisplayMessageToSAR(_heliUnit, "Open the door to let me out!", self.messageTime, true, true)
@@ -1722,7 +1777,7 @@ function CSAR:_ScheduledSARFlight(heliname,groupname, isairport, noreschedule)
--queue up --queue up
if not noreschedule then if not noreschedule then
self:__Returning(5,heliname,_woundedGroupName, isairport) self:__Returning(5,heliname,_woundedGroupName, isairport)
self:ScheduleOnce(5,self._ScheduledSARFlight,self,heliname,groupname, isairport, noreschedule) self:ScheduleOnce(5,self._ScheduledSARFlight,self,heliname,groupname, isairport, noreschedule, IsHeloBase)
end end
return self return self
end end
@@ -1793,9 +1848,6 @@ function CSAR:_DisplayMessageToSAR(_unit, _text, _time, _clear, _speak, _overrid
end end
_text = string.gsub(_text,"km"," kilometer") _text = string.gsub(_text,"km"," kilometer")
_text = string.gsub(_text,"nm"," nautical miles") _text = string.gsub(_text,"nm"," nautical miles")
--self.msrs:SetVoice(self.SRSVoice)
--self.SRSQueue:NewTransmission(_text,nil,self.msrs,nil,1)
--self:I("Voice = "..self.SRSVoice)
self.SRSQueue:NewTransmission(_text,duration,self.msrs,tstart,2,subgroups,subtitle,subduration,self.SRSchannel,self.SRSModulation,gender,culture,self.SRSVoice,volume,label,coord) self.SRSQueue:NewTransmission(_text,duration,self.msrs,tstart,2,subgroups,subtitle,subduration,self.SRSchannel,self.SRSModulation,gender,culture,self.SRSVoice,volume,label,coord)
end end
return self return self
@@ -1804,8 +1856,9 @@ end
--- (Internal) Function to get string of a group\'s position. --- (Internal) Function to get string of a group\'s position.
-- @param #CSAR self -- @param #CSAR self
-- @param Wrapper.Controllable#CONTROLLABLE _woundedGroup Group or Unit object. -- @param Wrapper.Controllable#CONTROLLABLE _woundedGroup Group or Unit object.
-- @param Wrapper.Unit#UNIT _Unit Requesting helo pilot unit
-- @return #string Coordinates as Text -- @return #string Coordinates as Text
function CSAR:_GetPositionOfWounded(_woundedGroup) function CSAR:_GetPositionOfWounded(_woundedGroup,_Unit)
self:T(self.lid .. " _GetPositionOfWounded") self:T(self.lid .. " _GetPositionOfWounded")
local _coordinate = _woundedGroup:GetCoordinate() local _coordinate = _woundedGroup:GetCoordinate()
local _coordinatesText = "None" local _coordinatesText = "None"
@@ -1820,6 +1873,26 @@ function CSAR:_GetPositionOfWounded(_woundedGroup)
_coordinatesText = _coordinate:ToStringBULLS(self.coalition) _coordinatesText = _coordinate:ToStringBULLS(self.coalition)
end end
end end
if _Unit and _Unit:GetPlayerName() then
local playername = _Unit:GetPlayerName()
if playername then
local settings = _DATABASE:GetPlayerSettings(playername) or _SETTINGS
if settings then
self:T("Get Settings ok!")
if settings:IsA2G_MGRS() then
_coordinatesText = _coordinate:ToStringMGRS(settings)
elseif settings:IsA2G_LL_DMS() then
_coordinatesText = _coordinate:ToStringLLDMS(settings)
elseif settings:IsA2G_LL_DDM() then
_coordinatesText = _coordinate:ToStringLLDDM(settings)
elseif settings:IsA2G_BR() then
-- attention this is the distance from the ASKING unit to target, not from RECCE to target!
local startcoordinate = _Unit:GetCoordinate()
_coordinatesText = _coordinate:ToStringBR(startcoordinate,settings)
end
end
end
end
return _coordinatesText return _coordinatesText
end end
@@ -1845,18 +1918,22 @@ function CSAR:_DisplayActiveSAR(_unitName)
self:T({Table=_value}) self:T({Table=_value})
local _woundedGroup = _value.group local _woundedGroup = _value.group
if _woundedGroup and _value.alive then if _woundedGroup and _value.alive then
local _coordinatesText = self:_GetPositionOfWounded(_woundedGroup) local _coordinatesText = self:_GetPositionOfWounded(_woundedGroup,_heli)
local _helicoord = _heli:GetCoordinate() local _helicoord = _heli:GetCoordinate()
local _woundcoord = _woundedGroup:GetCoordinate() local _woundcoord = _woundedGroup:GetCoordinate()
local _distance = self:_GetDistance(_helicoord, _woundcoord) local _distance = self:_GetDistance(_helicoord, _woundcoord)
self:T({_distance = _distance}) self:T({_distance = _distance})
local distancetext = "" local distancetext = ""
if _SETTINGS:IsImperial() then local settings = _SETTINGS
if _heli:GetPlayerName() then
settings = _DATABASE:GetPlayerSettings(_heli:GetPlayerName()) or _SETTINGS
end
if settings:IsImperial() then
distancetext = string.format("%.1fnm",UTILS.MetersToNM(_distance)) distancetext = string.format("%.1fnm",UTILS.MetersToNM(_distance))
else else
distancetext = string.format("%.1fkm", _distance/1000.0) distancetext = string.format("%.1fkm", _distance/1000.0)
end end
if _value.frequency == 0 then--shagrat insert CASEVAC without Frequency if _value.frequency == 0 or self.CreateRadioBeacons == false then--shagrat insert CASEVAC without Frequency
table.insert(_csarList, { dist = _distance, msg = string.format("%s at %s - %s ", _value.desc, _coordinatesText, distancetext) }) table.insert(_csarList, { dist = _distance, msg = string.format("%s at %s - %s ", _value.desc, _coordinatesText, distancetext) })
else else
table.insert(_csarList, { dist = _distance, msg = string.format("%s at %s - %.2f KHz ADF - %s ", _value.desc, _coordinatesText, _value.frequency / 1000, distancetext) }) table.insert(_csarList, { dist = _distance, msg = string.format("%s at %s - %.2f KHz ADF - %s ", _value.desc, _coordinatesText, _value.frequency / 1000, distancetext) })
@@ -1941,7 +2018,7 @@ function CSAR:_SignalFlare(_unitName)
else else
_distance = string.format("%.1fkm",_closest.distance/1000) _distance = string.format("%.1fkm",_closest.distance/1000)
end end
local _msg = string.format("%s - Popping signal flare at your %s o\'clock. Distance %s", self:_GetCustomCallSign(_unitName), _clockDir, _distance) local _msg = string.format("%s - Firing signal flare at your %s o\'clock. Distance %s", self:_GetCustomCallSign(_unitName), _clockDir, _distance)
self:_DisplayMessageToSAR(_heli, _msg, self.messageTime, false, true, true) self:_DisplayMessageToSAR(_heli, _msg, self.messageTime, false, true, true)
local _coord = _closest.pilot:GetCoordinate() local _coord = _closest.pilot:GetCoordinate()
@@ -1975,7 +2052,7 @@ function CSAR:_DisplayToAllSAR(_message, _side, _messagetime,ToSRS,ToScreen)
if self.msrs:GetProvider() == MSRS.Provider.WINDOWS then if self.msrs:GetProvider() == MSRS.Provider.WINDOWS then
voice = self.CSARVoiceMS or MSRS.Voices.Microsoft.Hedda voice = self.CSARVoiceMS or MSRS.Voices.Microsoft.Hedda
end end
self:F("Voice = "..voice) --self:F("Voice = "..voice)
self.SRSQueue:NewTransmission(_message,duration,self.msrs,tstart,2,subgroups,subtitle,subduration,self.SRSchannel,self.SRSModulation,gender,culture,voice,volume,label,self.coordinate) self.SRSQueue:NewTransmission(_message,duration,self.msrs,tstart,2,subgroups,subtitle,subduration,self.SRSchannel,self.SRSModulation,gender,culture,voice,volume,label,self.coordinate)
end end
if ToScreen == true or ToScreen == nil then if ToScreen == true or ToScreen == nil then
@@ -1989,6 +2066,41 @@ function CSAR:_DisplayToAllSAR(_message, _side, _messagetime,ToSRS,ToScreen)
return self return self
end end
---(Internal) Request IR Strobe at closest downed pilot.
--@param #CSAR self
--@param #string _unitName Name of the helicopter
function CSAR:_ReqIRStrobe( _unitName )
self:T(self.lid .. " _ReqIRStrobe")
local _heli = self:_GetSARHeli(_unitName)
if _heli == nil then
return
end
local smokedist = 8000
if smokedist < self.approachdist_far then smokedist = self.approachdist_far end
local _closest = self:_GetClosestDownedPilot(_heli)
if _closest ~= nil and _closest.pilot ~= nil and _closest.distance > 0 and _closest.distance < smokedist then
local _clockDir = self:_GetClockDirection(_heli, _closest.pilot)
local _distance = string.format("%.1fkm",_closest.distance/1000)
if _SETTINGS:IsImperial() then
_distance = string.format("%.1fnm",UTILS.MetersToNM(_closest.distance))
else
_distance = string.format("%.1fkm",_closest.distance/1000)
end
local _msg = string.format("%s - IR Strobe active at your %s o\'clock. Distance %s", self:_GetCustomCallSign(_unitName), _clockDir, _distance)
self:_DisplayMessageToSAR(_heli, _msg, self.messageTime, false, true, true)
_closest.pilot:NewIRMarker(true,self.IRStrobeRuntime or 300)
else
local _distance = string.format("%.1fkm",smokedist/1000)
if _SETTINGS:IsImperial() then
_distance = string.format("%.1fnm",UTILS.MetersToNM(smokedist))
else
_distance = string.format("%.1fkm",smokedist/1000)
end
self:_DisplayMessageToSAR(_heli, string.format("No Pilots within %s",_distance), self.messageTime, false, false, true)
end
return self
end
---(Internal) Request smoke at closest downed pilot. ---(Internal) Request smoke at closest downed pilot.
--@param #CSAR self --@param #CSAR self
--@param #string _unitName Name of the helicopter --@param #string _unitName Name of the helicopter
@@ -2029,56 +2141,50 @@ end
--- (Internal) Determine distance to closest MASH. --- (Internal) Determine distance to closest MASH.
-- @param #CSAR self -- @param #CSAR self
-- @param Wrapper.Unit#UNIT _heli Helicopter #UNIT -- @param Wrapper.Unit#UNIT _heli Helicopter #UNIT
-- @return #CSAR self -- @return #number Distance in meters
-- @return #string MASH Name as string
function CSAR:_GetClosestMASH(_heli) function CSAR:_GetClosestMASH(_heli)
self:T(self.lid .. " _GetClosestMASH") self:T(self.lid .. " _GetClosestMASH")
local _mashset = self.mash -- Core.Set#SET_GROUP local _mashset = self.mash -- Core.Set#SET_GROUP
local _mashes = _mashset:GetSetObjects() -- #table local MashSets = {}
--local _mashes = _mashset.Set-- #table
table.insert(MashSets,_mashset.Set)
table.insert(MashSets,self.zonemashes.Set)
table.insert(MashSets,self.staticmashes.Set)
local _shortestDistance = -1 local _shortestDistance = -1
local _distance = 0 local _distance = 0
local _helicoord = _heli:GetCoordinate() local _helicoord = _heli:GetCoordinate()
local MashName = nil
local function GetCloseAirbase(coordinate,Coalition,Category)
local a=coordinate:GetVec3()
local distmin=math.huge
local airbase=nil
for DCSairbaseID, DCSairbase in pairs(world.getAirbases(Coalition)) do
local b=DCSairbase:getPoint()
local c=UTILS.VecSubstract(a,b)
local dist=UTILS.VecNorm(c)
if dist<distmin and (Category==nil or Category==DCSairbase:getDesc().category) then
distmin=dist
airbase=DCSairbase
end
end
return distmin
end
if self.allowFARPRescue then if self.allowFARPRescue then
local position = _heli:GetCoordinate() local position = _heli:GetCoordinate()
local afb,distance = position:GetClosestAirbase(nil,self.coalition) local afb,distance = position:GetClosestAirbase(nil,self.coalition)
_shortestDistance = distance _shortestDistance = distance
MashName = (afb ~= nil) and afb:GetName() or "Unknown"
end end
for _, _mashUnit in pairs(_mashes) do for _,_mashes in pairs(MashSets) do
if _mashUnit and _mashUnit:IsAlive() then for _, _mashUnit in pairs(_mashes or {}) do
local _mashcoord = _mashUnit:GetCoordinate() local _mashcoord
if _mashUnit and (not _mashUnit:IsInstanceOf("ZONE_BASE")) and _mashUnit:IsAlive() then
_mashcoord = _mashUnit:GetCoordinate()
elseif _mashUnit and _mashUnit:IsInstanceOf("ZONE_BASE") then
_mashcoord = _mashUnit:GetCoordinate()
end
_distance = self:_GetDistance(_helicoord, _mashcoord) _distance = self:_GetDistance(_helicoord, _mashcoord)
if _distance ~= nil and (_shortestDistance == -1 or _distance < _shortestDistance) then if _distance ~= nil and (_shortestDistance == -1 or _distance < _shortestDistance) then
_shortestDistance = _distance _shortestDistance = _distance
MashName = _mashUnit:GetName() or "Unknown"
end end
end end
end end
if _shortestDistance ~= -1 then if _shortestDistance ~= -1 then
return _shortestDistance return _shortestDistance, MashName
else else
return -1 return -1
end end
end end
--- (Internal) Display onboarded rescued pilots. --- (Internal) Display onboarded rescued pilots.
@@ -2140,7 +2246,12 @@ function CSAR:_AddMedevacMenuItem()
local _rootMenu1 = MENU_GROUP_COMMAND:New(_group,"List Active CSAR",_rootPath, self._DisplayActiveSAR,self,_unitName) local _rootMenu1 = MENU_GROUP_COMMAND:New(_group,"List Active CSAR",_rootPath, self._DisplayActiveSAR,self,_unitName)
local _rootMenu2 = MENU_GROUP_COMMAND:New(_group,"Check Onboard",_rootPath, self._CheckOnboard,self,_unitName) local _rootMenu2 = MENU_GROUP_COMMAND:New(_group,"Check Onboard",_rootPath, self._CheckOnboard,self,_unitName)
local _rootMenu3 = MENU_GROUP_COMMAND:New(_group,"Request Signal Flare",_rootPath, self._SignalFlare,self,_unitName) local _rootMenu3 = MENU_GROUP_COMMAND:New(_group,"Request Signal Flare",_rootPath, self._SignalFlare,self,_unitName)
local _rootMenu4 = MENU_GROUP_COMMAND:New(_group,"Request Smoke",_rootPath, self._Reqsmoke,self,_unitName):Refresh() local _rootMenu4 = MENU_GROUP_COMMAND:New(_group,"Request Smoke",_rootPath, self._Reqsmoke,self,_unitName)
if self.AllowIRStrobe then
local _rootMenu5 = MENU_GROUP_COMMAND:New(_group,"Request IR Strobe",_rootPath, self._ReqIRStrobe,self,_unitName):Refresh()
else
_rootMenu4:Refresh()
end
end end
end end
end end
@@ -2231,9 +2342,13 @@ end
-- @param #CSAR self -- @param #CSAR self
-- @param Wrapper.Group#GROUP _group Group #GROUP object. -- @param Wrapper.Group#GROUP _group Group #GROUP object.
-- @param #number _freq Frequency to use -- @param #number _freq Frequency to use
function CSAR:_AddBeaconToGroup(_group, _freq) -- @param #string BeaconName Beacon Name to use
-- @return #CSAR self
function CSAR:_AddBeaconToGroup(_group, _freq, BeaconName)
self:T(self.lid .. " _AddBeaconToGroup") self:T(self.lid .. " _AddBeaconToGroup")
if self.CreateRadioBeacons == false then return end
local _group = _group local _group = _group
if _group == nil then if _group == nil then
--return frequency to pool of available --return frequency to pool of available
for _i, _current in ipairs(self.UsedVHFFrequencies) do for _i, _current in ipairs(self.UsedVHFFrequencies) do
@@ -2250,20 +2365,23 @@ function CSAR:_AddBeaconToGroup(_group, _freq)
if _radioUnit then if _radioUnit then
local name = _radioUnit:GetName() local name = _radioUnit:GetName()
local Frequency = _freq -- Freq in Hertz local Frequency = _freq -- Freq in Hertz
local name = _radioUnit:GetName() --local name = _radioUnit:GetName()
local Sound = "l10n/DEFAULT/"..self.radioSound local Sound = "l10n/DEFAULT/"..self.radioSound
local vec3 = _radioUnit:GetVec3() or _radioUnit:GetPositionVec3() or {x=0,y=0,z=0} local vec3 = _radioUnit:GetVec3() or _radioUnit:GetPositionVec3() or {x=0,y=0,z=0}
trigger.action.radioTransmission(Sound, vec3, 0, false, Frequency, self.ADFRadioPwr or 1000,name..math.random(1,10000)) -- Beacon in MP only runs for exactly 30secs straight self:I(self.lid..string.format("Added Radio Beacon %d Hertz | Name %s | Position {%d,%d,%d}",Frequency,BeaconName,vec3.x,vec3.y,vec3.z))
trigger.action.radioTransmission(Sound, vec3, 0, true, Frequency, self.ADFRadioPwr or 500,BeaconName) -- Beacon in MP only runs for exactly 30secs straight
end end
end end
return self return self
end end
--- (Internal) Helper function to (re-)add beacon to downed pilot. --- (Internal) Helper function to (re-)add beacon to downed pilot.
-- @param #CSAR self -- @param #CSAR self
-- @param #table _args Arguments -- @return #CSAR self
function CSAR:_RefreshRadioBeacons() function CSAR:_RefreshRadioBeacons()
self:T(self.lid .. " _RefreshRadioBeacons") self:T(self.lid .. " _RefreshRadioBeacons")
if self.CreateRadioBeacons == false then return end
if self:_CountActiveDownedPilots() > 0 then if self:_CountActiveDownedPilots() > 0 then
local PilotTable = self.downedPilots local PilotTable = self.downedPilots
for _,_pilot in pairs (PilotTable) do for _,_pilot in pairs (PilotTable) do
@@ -2271,8 +2389,14 @@ function CSAR:_RefreshRadioBeacons()
local pilot = _pilot -- #CSAR.DownedPilot local pilot = _pilot -- #CSAR.DownedPilot
local group = pilot.group local group = pilot.group
local frequency = pilot.frequency or 0 -- thanks to @Thrud local frequency = pilot.frequency or 0 -- thanks to @Thrud
local bname = pilot.BeaconName or pilot.name..math.random(1,100000)
--trigger.action.stopRadioTransmission(bname)
if group and group:IsAlive() and frequency > 0 then if group and group:IsAlive() and frequency > 0 then
self:_AddBeaconToGroup(group,frequency) --self:_AddBeaconToGroup(group,frequency,bname)
else
if frequency > 0 then
trigger.action.stopRadioTransmission(bname)
end
end end
end end
end end
@@ -2303,15 +2427,40 @@ function CSAR:_ReachedPilotLimit()
local islimited = self.limitmaxdownedpilots local islimited = self.limitmaxdownedpilots
local count = self:_CountActiveDownedPilots() local count = self:_CountActiveDownedPilots()
if islimited and (count >= limit) then if islimited and (count >= limit) then
if self.useFIFOLimitReplacement then
local oldIndex = -1
local oldDownedPilot = nil
for _index, _downedpilot in pairs(self.downedPilots) do
oldIndex = _index
oldDownedPilot = _downedpilot
break
end
if oldDownedPilot then
oldDownedPilot.group:Destroy(false)
oldDownedPilot.alive = false
self:_CheckDownedPilotTable()
return false
end
end
return true return true
else else
return false return false
end end
end end
------------------------------ --- User - Function to add onw SET_GROUP Set-up for pilot filtering and assignment.
--- FSM internal Functions --- -- Needs to be set before starting the CSAR instance.
------------------------------ -- @param #CSAR self
-- @param Core.Set#SET_GROUP Set The SET_GROUP object created by the mission designer/user to represent the CSAR pilot groups.
-- @return #CSAR self
function CSAR:SetOwnSetPilotGroups(Set)
self.UserSetGroup = Set
return self
end
------------------------------
--- FSM internal Functions ---
------------------------------
--- (Internal) Function called after Start() event. --- (Internal) Function called after Start() event.
-- @param #CSAR self. -- @param #CSAR self.
@@ -2330,7 +2479,9 @@ function CSAR:onafterStart(From, Event, To)
self:HandleEvent(EVENTS.PlayerEnterUnit, self._EventHandler) self:HandleEvent(EVENTS.PlayerEnterUnit, self._EventHandler)
self:HandleEvent(EVENTS.PilotDead, self._EventHandler) self:HandleEvent(EVENTS.PilotDead, self._EventHandler)
if self.allowbronco then if self.UserSetGroup then
self.allheligroupset = self.UserSetGroup
elseif self.allowbronco then
local prefixes = self.csarPrefix or {} local prefixes = self.csarPrefix or {}
self.allheligroupset = SET_GROUP:New():FilterCoalitions(self.coalitiontxt):FilterPrefixes(prefixes):FilterStart() self.allheligroupset = SET_GROUP:New():FilterCoalitions(self.coalitiontxt):FilterPrefixes(prefixes):FilterStart()
elseif self.useprefix then elseif self.useprefix then
@@ -2339,7 +2490,28 @@ function CSAR:onafterStart(From, Event, To)
else else
self.allheligroupset = SET_GROUP:New():FilterCoalitions(self.coalitiontxt):FilterCategoryHelicopter():FilterStart() self.allheligroupset = SET_GROUP:New():FilterCoalitions(self.coalitiontxt):FilterCategoryHelicopter():FilterStart()
end end
self.mash = SET_GROUP:New():FilterCoalitions(self.coalitiontxt):FilterPrefixes(self.mashprefix):FilterStart() -- currently only GROUP objects, maybe support STATICs also?
self.mash = SET_GROUP:New():FilterCoalitions(self.coalitiontxt):FilterPrefixes(self.mashprefix):FilterStart()
self.staticmashes = SET_STATIC:New():FilterCoalitions(self.coalitiontxt):FilterPrefixes(self.mashprefix):FilterStart()
self.zonemashes = SET_ZONE:New():FilterPrefixes(self.mashprefix):FilterStart()
--[[
if staticmashes:Count() > 0 then
for _,_mash in pairs(staticmashes.Set) do
self.mash:AddObject(_mash)
end
end
if zonemashes:Count() > 0 then
self:T("Adding zones to self.mash SET")
for _,_mash in pairs(zonemashes.Set) do
self.mash:AddObject(_mash)
end
self:T("Objects in SET: "..self.mash:Count())
end
--]]
if not self.coordinate then if not self.coordinate then
local csarhq = self.mash:GetRandom() local csarhq = self.mash:GetRandom()
if csarhq then if csarhq then
@@ -2839,7 +3011,7 @@ function CSAR:onafterLoad(From, Event, To, path, filename)
local unitName = dataset[9] local unitName = dataset[9]
local freq = tonumber(dataset[10]) local freq = tonumber(dataset[10])
self:_AddCsar(coalition, country, point, typeName, unitName, playerName, freq, nil, description, nil) self:_AddCsar(coalition, country, point, typeName, unitName, playerName, freq, false, description, nil)
end end
return self return self
File diff suppressed because it is too large Load Diff
+21 -5
View File
@@ -34,6 +34,7 @@
-- @field Ops.Commander#COMMANDER commander Commander of assigned legions. -- @field Ops.Commander#COMMANDER commander Commander of assigned legions.
-- @field #number Nsuccess Number of successful missions. -- @field #number Nsuccess Number of successful missions.
-- @field #number Nfailure Number of failed mission. -- @field #number Nfailure Number of failed mission.
-- @field #table assetNumbers Asset numbers. Each entry is a table of data type `#CHIEF.AssetNumber`.
-- @extends Ops.Intel#INTEL -- @extends Ops.Intel#INTEL
--- *In preparing for battle I have always found that plans are useless, but planning is indispensable* -- Dwight D Eisenhower --- *In preparing for battle I have always found that plans are useless, but planning is indispensable* -- Dwight D Eisenhower
@@ -331,7 +332,7 @@ CHIEF.Strategy = {
--- CHIEF class version. --- CHIEF class version.
-- @field #string version -- @field #string version
CHIEF.version="0.6.0" CHIEF.version="0.6.1"
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO list -- TODO list
@@ -1284,8 +1285,10 @@ end
-- --
-- Empty: -- Empty:
-- --
-- * `AUFTRAG.Type.ONGURAD` with Nmin=1 and Nmax=1 assets, Attribute=`GROUP.Attribute.GROUND_TANK`. -- * `AUFTRAG.Type.ONGURAD` with Nmin=0 and Nmax=1 assets, Attribute=`GROUP.Attribute.GROUND_TANK`.
-- * `AUFTRAG.Type.ONGURAD` with Nmin=0 and Nmax=1 assets, Attribute=`GROUP.Attribute.GROUND_IFV`.
-- * `AUFTRAG.Type.ONGUARD` with Nmin=1 and Nmax=3 assets, Attribute=`GROUP.Attribute.GROUND_INFANTRY`. -- * `AUFTRAG.Type.ONGUARD` with Nmin=1 and Nmax=3 assets, Attribute=`GROUP.Attribute.GROUND_INFANTRY`.
-- * `AUFTRAG.Type.OPSTRANSPORT` with Nmin=0 and Nmax=1 assets, Attribute=`GROUP.Attribute.AIR_TRANSPORTHELO` or `GROUP.Attribute.GROUND_APC`. This asset is used to transport the infantry groups.
-- --
-- Resources can be created with the @{#CHIEF.CreateResource} and @{#CHIEF.AddToResource} functions. -- Resources can be created with the @{#CHIEF.CreateResource} and @{#CHIEF.AddToResource} functions.
-- --
@@ -3033,10 +3036,13 @@ function CHIEF:RecruitAssetsForZone(StratZone, Resource)
end end
-- Recruite infantry assets. -- Recruite infantry assets.
self:T(self.lid..string.format("Recruiting assets for zone %s", StratZone.opszone:GetName()))
self:T(self.lid.."Missiontype="..MissionType) self:T(self.lid.."Missiontype="..MissionType)
self:T({categories=Categories}) self:T({categories=Categories})
self:T({attributes=Attributes}) self:T({attributes=Attributes})
self:T({properties=Properties}) self:T({properties=Properties})
local recruited, assets, legions=LEGION.RecruitCohortAssets(Cohorts, MissionType, nil, NassetsMin, NassetsMax, TargetVec2, nil, RangeMax, nil, nil, nil, nil, Categories, Attributes, Properties) local recruited, assets, legions=LEGION.RecruitCohortAssets(Cohorts, MissionType, nil, NassetsMin, NassetsMax, TargetVec2, nil, RangeMax, nil, nil, nil, nil, Categories, Attributes, Properties)
if recruited then if recruited then
@@ -3052,9 +3058,12 @@ function CHIEF:RecruitAssetsForZone(StratZone, Resource)
local TargetCoord = TargetZone:GetCoordinate() local TargetCoord = TargetZone:GetCoordinate()
-- First check if we need a transportation. -- First check if we need a transportation.
local transport=nil local transport=nil --Ops.OpsTransport#OPSTRANSPORT
local Ntransports=0
if Resource.carrierNmin and Resource.carrierNmax and Resource.carrierNmax>0 then if Resource.carrierNmin and Resource.carrierNmax and Resource.carrierNmax>0 then
self:T(self.lid..string.format("Recruiting carrier assets: Nmin=%s, Nmax=%s", tostring(Resource.carrierNmin), tostring(Resource.carrierNmax)))
-- Filter only those assets that shall be transported. -- Filter only those assets that shall be transported.
local cargoassets=CHIEF._FilterAssets(assets, Resource.Categories, Resource.Attributes, Resource.Properties) local cargoassets=CHIEF._FilterAssets(assets, Resource.Categories, Resource.Attributes, Resource.Properties)
@@ -3064,6 +3073,10 @@ function CHIEF:RecruitAssetsForZone(StratZone, Resource)
recruited, transport=LEGION.AssignAssetsForTransport(self.commander, self.commander.legions, cargoassets, recruited, transport=LEGION.AssignAssetsForTransport(self.commander, self.commander.legions, cargoassets,
Resource.carrierNmin, Resource.carrierNmax, TargetZone, nil, Resource.carrierCategories, Resource.carrierAttributes, Resource.carrierProperties) Resource.carrierNmin, Resource.carrierNmax, TargetZone, nil, Resource.carrierCategories, Resource.carrierAttributes, Resource.carrierProperties)
Ntransports=transport~=nil and #transport.assets or 0
self:T(self.lid..string.format("Recruited %d transport carrier assets success=%s", Ntransports, tostring(recruited)))
end end
end end
@@ -3076,7 +3089,7 @@ function CHIEF:RecruitAssetsForZone(StratZone, Resource)
return false return false
end end
-- Debug messgage. -- Debug message
self:T2(self.lid..string.format("Recruited %d assets for mission %s", #assets, MissionType)) self:T2(self.lid..string.format("Recruited %d assets for mission %s", #assets, MissionType))
@@ -3224,10 +3237,13 @@ function CHIEF:RecruitAssetsForZone(StratZone, Resource)
-- Attach mission to ops zone. -- Attach mission to ops zone.
StratZone.opszone:_AddMission(self.coalition, MissionType, mission) StratZone.opszone:_AddMission(self.coalition, MissionType, mission)
mission:SetName(string.format("Stratzone %s-%d", StratZone.opszone:GetName(), mission.auftragsnummer))
-- Attach mission to resource. -- Attach mission to resource.
Resource.mission=mission Resource.mission=mission
if transport then -- Check if transport assets could be allocated. If carrier Nmin=0 and 0 assets could be allocated, transport would still be created but not usefull obviously
if transport and Ntransports>0 then
-- Attach OPS transport to mission. -- Attach OPS transport to mission.
mission.opstransport=transport mission.opstransport=transport
-- Set ops zone to transport. -- Set ops zone to transport.
+35 -5
View File
@@ -88,7 +88,10 @@ COHORT = {
--- COHORT class version. --- COHORT class version.
-- @field #string version -- @field #string version
COHORT.version="0.3.5" COHORT.version="0.3.7"
--- Global variable to store the unique(!) cohort names
_COHORTNAMES={}
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO list -- TODO list
@@ -97,6 +100,7 @@ COHORT.version="0.3.5"
-- DONE: Create FLOTILLA class. -- DONE: Create FLOTILLA class.
-- DONE: Added check for properties. -- DONE: Added check for properties.
-- DONE: Make general so that PLATOON and SQUADRON can inherit this class. -- DONE: Make general so that PLATOON and SQUADRON can inherit this class.
-- DONE: Better setting of call signs.
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Constructor -- Constructor
@@ -110,6 +114,17 @@ COHORT.version="0.3.5"
-- @return #COHORT self -- @return #COHORT self
function COHORT:New(TemplateGroupName, Ngroups, CohortName) function COHORT:New(TemplateGroupName, Ngroups, CohortName)
-- Name of the cohort.
local name=tostring(CohortName or TemplateGroupName)
-- Cohort name has to be unique or we will get serious problems!
if UTILS.IsAnyInTable(_COHORTNAMES, name) then
env.error(string.format('ERROR: cannot create cohort "%s" because another cohort with that name already exists. Names must be unique!', name))
return nil
else
table.insert(_COHORTNAMES, name)
end
-- Inherit everything from FSM class. -- Inherit everything from FSM class.
local self=BASE:Inherit(self, FSM:New()) -- #COHORT local self=BASE:Inherit(self, FSM:New()) -- #COHORT
@@ -117,7 +132,7 @@ function COHORT:New(TemplateGroupName, Ngroups, CohortName)
self.templatename=TemplateGroupName self.templatename=TemplateGroupName
-- Cohort name. -- Cohort name.
self.name=tostring(CohortName or TemplateGroupName) self.name=name
-- Set some string id for output to DCS.log file. -- Set some string id for output to DCS.log file.
self.lid=string.format("COHORT %s | ", self.name) self.lid=string.format("COHORT %s | ", self.name)
@@ -501,10 +516,12 @@ end
-- @param #COHORT self -- @param #COHORT self
-- @param #number Callsign Callsign from CALLSIGN.Aircraft, e.g. "Chevy" for CALLSIGN.Aircraft.CHEVY. -- @param #number Callsign Callsign from CALLSIGN.Aircraft, e.g. "Chevy" for CALLSIGN.Aircraft.CHEVY.
-- @param #number Index Callsign index, Chevy-**1**. -- @param #number Index Callsign index, Chevy-**1**.
-- @param #string CallsignString (optional) Set this for tasks like TANKER, AWACS or KIOWA and the like, which have special names. E.g. "Darkstar" or "Roughneck".
-- @return #COHORT self -- @return #COHORT self
function COHORT:SetCallsign(Callsign, Index) function COHORT:SetCallsign(Callsign, Index, CallsignString)
self.callsignName=Callsign self.callsignName=Callsign
self.callsignIndex=Index self.callsignIndex=Index
self.callsignClearName=CallsignString
self.callsign={} self.callsign={}
self.callsign.NumberSquad=Callsign self.callsign.NumberSquad=Callsign
self.callsign.NumberGroup=Index self.callsign.NumberGroup=Index
@@ -665,7 +682,16 @@ end
function COHORT:GetCallsign(Asset) function COHORT:GetCallsign(Asset)
if self.callsignName then if self.callsignName then
--[[
["callsign"] =
{
[2] = 1,
["name"] = "Darkstar11",
[3] = 1,
[1] = 5,
[4] = "Darkstar11",
}, -- end of ["callsign"]
]]
Asset.callsign={} Asset.callsign={}
for i=1,Asset.nunits do for i=1,Asset.nunits do
@@ -681,12 +707,16 @@ function COHORT:GetCallsign(Asset)
else else
self.callsigncounter=self.callsigncounter+1 self.callsigncounter=self.callsigncounter+1
end end
callsign["name"] = self.callsignClearName or UTILS.GetCallsignName(self.callsignName) or "None"
callsign["name"] = string.format("%s%d%d",callsign["name"],callsign[2],callsign[3])
callsign[4] = callsign["name"]
Asset.callsign[i]=callsign Asset.callsign[i]=callsign
self:T3({callsign=callsign}) self:T3({callsign=callsign})
--TODO: there is also a table entry .name, which is a string. --DONE: there is also a table entry .name, which is a string.
--UTILS.PrintTableToLog(callsign)
end end
+27 -3
View File
@@ -136,6 +136,7 @@ COMMANDER = {
awacsZones = {}, awacsZones = {},
tankerZones = {}, tankerZones = {},
limitMission = {}, limitMission = {},
maxMissionsAssignPerCycle = 1,
} }
--- COMMANDER class version. --- COMMANDER class version.
@@ -1535,6 +1536,8 @@ function COMMANDER:CheckMissionQueue()
end end
end end
local missionsAssigned = 0
-- Loop over missions in queue. -- Loop over missions in queue.
for _,_mission in pairs(self.missionqueue) do for _,_mission in pairs(self.missionqueue) do
local mission=_mission --Ops.Auftrag#AUFTRAG local mission=_mission --Ops.Auftrag#AUFTRAG
@@ -1595,10 +1598,13 @@ function COMMANDER:CheckMissionQueue()
LEGION.UnRecruitAssets(assets, mission) LEGION.UnRecruitAssets(assets, mission)
end end
-- Only ONE mission is assigned. missionsAssigned = missionsAssigned + 1
if missionsAssigned >= (self.maxMissionsAssignPerCycle or 1) then
return return
end end
end
else else
--- ---
@@ -1611,6 +1617,16 @@ function COMMANDER:CheckMissionQueue()
end end
--- Set how many missions can be assigned in a single status iteration. (eg. This is useful for persistent missions where you need to load all AUFTRAGs on mission start and then change it back to default)
--- Warning: Increasing this value will increase the number of missions started per iteration and thus may lead to performance issues if too many missions are started at once.
-- @param #COMMANDER self
-- @param #number Number of missions assigned per status iteration. Default is 1.
-- @return #COMMANDER self.
function COMMANDER:SetMaxMissionsAssignPerCycle(MaxMissionsAssignPerCycle)
self.maxMissionsAssignPerCycle = MaxMissionsAssignPerCycle or 1
return self
end
--- Get cohorts. --- Get cohorts.
-- @param #COMMANDER self -- @param #COMMANDER self
-- @param #table Legions Special legions. -- @param #table Legions Special legions.
@@ -1671,7 +1687,10 @@ function COMMANDER:_GetCohorts(Legions, Cohorts, Operation)
local legion=_legion --Ops.Legion#LEGION local legion=_legion --Ops.Legion#LEGION
-- Check that runway is operational. -- Check that runway is operational.
local Runway=legion:IsAirwing() and legion:IsRunwayOperational() or true local Runway=true
if legion:IsAirwing() then
Runway=legion:IsRunwayOperational() and legion.airbase and legion.airbase:GetCoalition() == legion:GetCoalition()
end
-- Legion has to be running. -- Legion has to be running.
if legion:IsRunning() and Runway then if legion:IsRunning() and Runway then
@@ -1704,7 +1723,10 @@ function COMMANDER:_GetCohorts(Legions, Cohorts, Operation)
local legion=_legion --Ops.Legion#LEGION local legion=_legion --Ops.Legion#LEGION
-- Check that runway is operational. -- Check that runway is operational.
local Runway=legion:IsAirwing() and legion:IsRunwayOperational() or true local Runway=true
if legion:IsAirwing() then
Runway=legion:IsRunwayOperational() and legion.airbase and legion.airbase:GetCoalition() == legion:GetCoalition()
end
-- Legion has to be running. -- Legion has to be running.
if legion:IsRunning() and Runway then if legion:IsRunning() and Runway then
@@ -1775,8 +1797,10 @@ function COMMANDER:RecruitAssetsForMission(Mission)
end end
end end
if MaxWeight then
self:T(self.lid..string.format("Largest cargo bay available=%.1f", MaxWeight)) self:T(self.lid..string.format("Largest cargo bay available=%.1f", MaxWeight))
end end
end
local legions=self.legions local legions=self.legions
local cohorts=nil local cohorts=nil
File diff suppressed because it is too large Load Diff
+261 -57
View File
@@ -1,13 +1,18 @@
------------------------------------------------------------------------- -------------------------------------------------------------------------
-- Easy CAP/GCI Class, based on OPS classes -- Easy CAP/GCI Class, based on OPS classes
------------------------------------------------------------------------- -------------------------------------------------------------------------
-- Documentation --
-- ## Documentation:
-- --
-- https://flightcontrol-master.github.io/MOOSE_DOCS_DEVELOP/Documentation/Ops.EasyGCICAP.html -- https://flightcontrol-master.github.io/MOOSE_DOCS_DEVELOP/Documentation/Ops.EasyGCICAP.html
-- --
-- ## Example Missions:
--
-- Demo missions can be found on [github](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/develop/Ops/EasyGCICAP).
--
------------------------------------------------------------------------- -------------------------------------------------------------------------
-- Date: September 2023 -- Date: September 2023
-- Last Update: July 2024 -- Last Update: Aug 2025
------------------------------------------------------------------------- -------------------------------------------------------------------------
-- --
--- **Ops** - Easy GCI & CAP Manager --- **Ops** - Easy GCI & CAP Manager
@@ -50,7 +55,7 @@
-- @field #number capleg -- @field #number capleg
-- @field #number maxinterceptsize -- @field #number maxinterceptsize
-- @field #number missionrange -- @field #number missionrange
-- @field #number noaltert5 -- @field #number noalert5
-- @field #table ManagedAW -- @field #table ManagedAW
-- @field #table ManagedSQ -- @field #table ManagedSQ
-- @field #table ManagedCP -- @field #table ManagedCP
@@ -62,6 +67,7 @@
-- @field #number repeatsonfailure -- @field #number repeatsonfailure
-- @field Core.Set#SET_ZONE GoZoneSet -- @field Core.Set#SET_ZONE GoZoneSet
-- @field Core.Set#SET_ZONE NoGoZoneSet -- @field Core.Set#SET_ZONE NoGoZoneSet
-- @field Core.Set#SET_ZONE ConflictZoneSet
-- @field #boolean Monitor -- @field #boolean Monitor
-- @field #boolean TankerInvisible -- @field #boolean TankerInvisible
-- @field #number CapFormation -- @field #number CapFormation
@@ -69,6 +75,11 @@
-- @field #boolean DespawnAfterLanding -- @field #boolean DespawnAfterLanding
-- @field #boolean DespawnAfterHolding -- @field #boolean DespawnAfterHolding
-- @field #list<Ops.Auftrag#AUFTRAG> ListOfAuftrag -- @field #list<Ops.Auftrag#AUFTRAG> ListOfAuftrag
-- @field #string defaulttakeofftype Take off type
-- @field #number FuelLowThreshold
-- @field #number FuelCriticalThreshold
-- @field #boolean showpatrolpointmarks
-- @field #table EngageTargetTypes
-- @extends Core.Fsm#FSM -- @extends Core.Fsm#FSM
--- *“Airspeed, altitude, and brains. Two are always needed to successfully complete the flight.”* -- Unknown. --- *“Airspeed, altitude, and brains. Two are always needed to successfully complete the flight.”* -- Unknown.
@@ -102,6 +113,11 @@
-- Next put a late activated template group for your CAP/GCI Squadron on the map. Last, put a zone on the map for the CAP operations, let's name it "Blue Zone 1". Size of the zone plays no role. -- Next put a late activated template group for your CAP/GCI Squadron on the map. Last, put a zone on the map for the CAP operations, let's name it "Blue Zone 1". Size of the zone plays no role.
-- Put an EW radar system on the map and name it aptly, like "Blue EWR". -- Put an EW radar system on the map and name it aptly, like "Blue EWR".
-- --
-- ### Zones
--
-- For our example, you create a RED and a BLUE border, as a closed polygonal zone representing the borderlines. You can also have conflict zone, where - for our example - BLUE will attack
-- RED planes, despite being on RED territory. Think of a no-fly zone or an limited area of engagement. Conflict zones take precedence over borders, i.e. they can overlap all borders.
--
-- ### Code it -- ### Code it
-- --
-- -- Set up a basic system for the blue side, we'll reside on Kutaisi, and use GROUP objects with "Blue EWR" in the name as EW Radar Systems. -- -- Set up a basic system for the blue side, we'll reside on Kutaisi, and use GROUP objects with "Blue EWR" in the name as EW Radar Systems.
@@ -114,10 +130,10 @@
-- mywing:AddSquadron("Blue Sq1 M2000c","CAP Kutaisi",AIRBASE.Caucasus.Kutaisi,20,AI.Skill.GOOD,102,"ec1.5_Vendee_Jeanne_clean") -- mywing:AddSquadron("Blue Sq1 M2000c","CAP Kutaisi",AIRBASE.Caucasus.Kutaisi,20,AI.Skill.GOOD,102,"ec1.5_Vendee_Jeanne_clean")
-- --
-- -- Add a couple of zones -- -- Add a couple of zones
-- -- We'll defend our border -- -- We'll defend our own border
-- mywing:AddAcceptZone(ZONE_POLYGON:New( "Blue Border", GROUP:FindByName( "Blue Border" ) )) -- mywing:AddAcceptZone(ZONE_POLYGON:New( "Blue Border", GROUP:FindByName( "Blue Border" ) ))
-- -- We'll attack intruders also here -- -- We'll attack intruders also here - conflictzones can overlap borders(!) - limited zone of engagement
-- mywing:AddAcceptZone(ZONE_POLYGON:New("Red Defense Zone", GROUP:FindByName( "Red Defense Zone" ))) -- mywing:AddConflictZone(ZONE_POLYGON:New("Red Defense Zone", GROUP:FindByName( "Red Defense Zone" )))
-- -- We'll leave the reds alone on their turf -- -- We'll leave the reds alone on their turf
-- mywing:AddRejectZone(ZONE_POLYGON:New( "Red Border", GROUP:FindByName( "Red Border" ) )) -- mywing:AddRejectZone(ZONE_POLYGON:New( "Red Border", GROUP:FindByName( "Red Border" ) ))
-- --
@@ -125,10 +141,10 @@
-- -- Set up borders on map -- -- Set up borders on map
-- local BlueBorder = ZONE_POLYGON:New( "Blue Border", GROUP:FindByName( "Blue Border" ) ) -- local BlueBorder = ZONE_POLYGON:New( "Blue Border", GROUP:FindByName( "Blue Border" ) )
-- BlueBorder:DrawZone(-1,{0,0,1},1,FillColor,FillAlpha,1,true) -- BlueBorder:DrawZone(-1,{0,0,1},1,FillColor,FillAlpha,1,true)
-- local BlueNoGoZone = ZONE_POLYGON:New("Red Defense Zone", GROUP:FindByName( "Red Defense Zone" )) -- local ConflictZone = ZONE_POLYGON:New("Red Defense Zone", GROUP:FindByName( "Red Defense Zone" ))
-- BlueNoGoZone:DrawZone(-1,{1,1,0},1,FillColor,FillAlpha,2,true) -- ConflictZone:DrawZone(-1,{1,1,0},1,FillColor,FillAlpha,2,true)
-- local BlueNoGoZone2 = ZONE_POLYGON:New( "Red Border", GROUP:FindByName( "Red Border" ) ) -- local BlueNoGoZone = ZONE_POLYGON:New( "Red Border", GROUP:FindByName( "Red Border" ) )
-- BlueNoGoZone2:DrawZone(-1,{1,0,0},1,FillColor,FillAlpha,4,true) -- BlueNoGoZone:DrawZone(-1,{1,0,0},1,FillColor,FillAlpha,4,true)
-- --
-- ### Add a second airwing with squads and own CAP point (optional) -- ### Add a second airwing with squads and own CAP point (optional)
-- --
@@ -167,7 +183,7 @@
-- * @{#EASYGCICAP.SetDefaultCAPLeg}: Set the length of the CAP leg, default is 15 NM. -- * @{#EASYGCICAP.SetDefaultCAPLeg}: Set the length of the CAP leg, default is 15 NM.
-- * @{#EASYGCICAP.SetDefaultCAPGrouping}: Set how many planes will be spawned per mission (CVAP/GCI), defaults to 2. -- * @{#EASYGCICAP.SetDefaultCAPGrouping}: Set how many planes will be spawned per mission (CVAP/GCI), defaults to 2.
-- * @{#EASYGCICAP.SetDefaultMissionRange}: Set how many NM the planes can go from the home base, defaults to 100. -- * @{#EASYGCICAP.SetDefaultMissionRange}: Set how many NM the planes can go from the home base, defaults to 100.
-- * @{#EASYGCICAP.SetDefaultNumberAlter5Standby}: Set how many planes will be spawned on cold standby (Alert5), default 2. -- * @{#EASYGCICAP.SetDefaultNumberAlert5Standby}: Set how many planes will be spawned on cold standby (Alert5), default 2.
-- * @{#EASYGCICAP.SetDefaultEngageRange}: Set max engage range for CAP flights if they detect intruders, defaults to 50. -- * @{#EASYGCICAP.SetDefaultEngageRange}: Set max engage range for CAP flights if they detect intruders, defaults to 50.
-- * @{#EASYGCICAP.SetMaxAliveMissions}: Set max parallel missions can be done (CAP+GCI+Alert5+Tanker+AWACS), defaults to 8. -- * @{#EASYGCICAP.SetMaxAliveMissions}: Set max parallel missions can be done (CAP+GCI+Alert5+Tanker+AWACS), defaults to 8.
-- * @{#EASYGCICAP.SetDefaultRepeatOnFailure}: Set max repeats on failure for intercepting/killing intruders, defaults to 3. -- * @{#EASYGCICAP.SetDefaultRepeatOnFailure}: Set max repeats on failure for intercepting/killing intruders, defaults to 3.
@@ -197,7 +213,7 @@ EASYGCICAP = {
capleg = 15, capleg = 15,
maxinterceptsize = 2, maxinterceptsize = 2,
missionrange = 100, missionrange = 100,
noaltert5 = 4, noalert5 = 4,
ManagedAW = {}, ManagedAW = {},
ManagedSQ = {}, ManagedSQ = {},
ManagedCP = {}, ManagedCP = {},
@@ -210,13 +226,19 @@ EASYGCICAP = {
repeatsonfailure = 3, repeatsonfailure = 3,
GoZoneSet = nil, GoZoneSet = nil,
NoGoZoneSet = nil, NoGoZoneSet = nil,
ConflictZoneSet = nil,
Monitor = false, Monitor = false,
TankerInvisible = true, TankerInvisible = true,
CapFormation = nil, CapFormation = nil,
ReadyFlightGroups = {}, ReadyFlightGroups = {},
DespawnAfterLanding = false, DespawnAfterLanding = false,
DespawnAfterHolding = true, DespawnAfterHolding = true,
ListOfAuftrag = {} ListOfAuftrag = {},
defaulttakeofftype = "hot",
FuelLowThreshold = 25,
FuelCriticalThreshold = 10,
showpatrolpointmarks = false,
EngageTargetTypes = {"Air"},
} }
--- Internal Squadron data type --- Internal Squadron data type
@@ -249,10 +271,11 @@ EASYGCICAP = {
-- @field #number Speed -- @field #number Speed
-- @field #number Heading -- @field #number Heading
-- @field #number LegLength -- @field #number LegLength
-- @field Core.Zone#ZONE_BASE Zone
--- EASYGCICAP class version. --- EASYGCICAP class version.
-- @field #string version -- @field #string version
EASYGCICAP.version="0.1.13" EASYGCICAP.version="0.1.30"
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO list -- TODO list
@@ -269,7 +292,7 @@ EASYGCICAP.version="0.1.13"
-- @param #string Alias A Name for this GCICAP -- @param #string Alias A Name for this GCICAP
-- @param #string AirbaseName Name of the Home Airbase -- @param #string AirbaseName Name of the Home Airbase
-- @param #string Coalition Coalition, e.g. "blue" or "red" -- @param #string Coalition Coalition, e.g. "blue" or "red"
-- @param #string EWRName (Partial) group name of the EWR system of the coalition, e.g. "Red EWR" -- @param #string EWRName (Partial) group name of the EWR system of the coalition, e.g. "Red EWR", can be handed in as table of names, e.g.{"EWR","Radar","SAM"}
-- @return #EASYGCICAP self -- @return #EASYGCICAP self
function EASYGCICAP:New(Alias, AirbaseName, Coalition, EWRName) function EASYGCICAP:New(Alias, AirbaseName, Coalition, EWRName)
-- Inherit everything from FSM class. -- Inherit everything from FSM class.
@@ -278,14 +301,16 @@ function EASYGCICAP:New(Alias, AirbaseName, Coalition, EWRName)
-- defaults -- defaults
self.alias = Alias or AirbaseName.." CAP Wing" self.alias = Alias or AirbaseName.." CAP Wing"
self.coalitionname = string.lower(Coalition) or "blue" self.coalitionname = string.lower(Coalition) or "blue"
self.coalition = self.coaltitionname == "blue" and coalition.side.BLUE or coalition.side.RED self.coalition = self.coalitionname == "blue" and coalition.side.BLUE or coalition.side.RED
self.wings = {} self.wings = {}
self.EWRName = EWRName or self.coalitionname.." EWR" if type(EWRName) == "string" then EWRName = {EWRName} end
self.EWRName = EWRName --or self.coalitionname.." EWR"
--self.CapZoneName = CapZoneName --self.CapZoneName = CapZoneName
self.airbasename = AirbaseName self.airbasename = AirbaseName
self.airbase = AIRBASE:FindByName(self.airbasename) self.airbase = AIRBASE:FindByName(self.airbasename)
self.GoZoneSet = SET_ZONE:New() self.GoZoneSet = SET_ZONE:New()
self.NoGoZoneSet = SET_ZONE:New() self.NoGoZoneSet = SET_ZONE:New()
self.ConflictZoneSet = SET_ZONE:New()
self.resurrection = 900 self.resurrection = 900
self.capspeed = 300 self.capspeed = 300
self.capalt = 25000 self.capalt = 25000
@@ -293,7 +318,7 @@ function EASYGCICAP:New(Alias, AirbaseName, Coalition, EWRName)
self.capleg = 15 self.capleg = 15
self.capgrouping = 2 self.capgrouping = 2
self.missionrange = 100 self.missionrange = 100
self.noaltert5 = 2 self.noalert5 = 2
self.MaxAliveMissions = 8 self.MaxAliveMissions = 8
self.engagerange = 50 self.engagerange = 50
self.repeatsonfailure = 3 self.repeatsonfailure = 3
@@ -303,6 +328,11 @@ function EASYGCICAP:New(Alias, AirbaseName, Coalition, EWRName)
self.DespawnAfterLanding = false self.DespawnAfterLanding = false
self.DespawnAfterHolding = true self.DespawnAfterHolding = true
self.ListOfAuftrag = {} self.ListOfAuftrag = {}
self.defaulttakeofftype = "hot"
self.FuelLowThreshold = 25
self.FuelCriticalThreshold = 10
self.showpatrolpointmarks = false
self.EngageTargetTypes = {"Air"}
-- Set some string id for output to DCS.log file. -- Set some string id for output to DCS.log file.
self.lid=string.format("EASYGCICAP %s | ", self.alias) self.lid=string.format("EASYGCICAP %s | ", self.alias)
@@ -327,6 +357,63 @@ end
-- Functions -- Functions
------------------------------------------------------------------------- -------------------------------------------------------------------------
--- Get a specific managed AirWing by name
-- @param #EASYGCICAP self
-- @param #string AirbaseName Airbase name of the home of this wing.
-- @return Ops.AirWing#AIRWING Airwing or nil if not found
function EASYGCICAP:GetAirwing(AirbaseName)
self:T(self.lid.."GetAirwing")
if self.wings[AirbaseName] then
return self.wings[AirbaseName][1]
end
return nil
end
--- Get a table of all managed AirWings
-- @param #EASYGCICAP self
-- @return #table Table of Ops.AirWing#AIRWING Airwings
function EASYGCICAP:GetAirwingTable()
self:T(self.lid.."GetAirwingTable")
local Wingtable = {}
for _,_object in pairs(self.wings or {}) do
table.insert(Wingtable,_object[1])
end
return Wingtable
end
--- Set "fuel low" threshold for CAP and INTERCEPT flights.
-- @param #EASYGCICAP self
-- @param #number Percent RTB if fuel at this percent. Values: 1..100, defaults to 25.
-- @return #EASYGCICAP self
function EASYGCICAP:SetFuelLow(Percent)
self:T(self.lid.."SetFuelLow")
self.FuelLowThreshold = Percent or 25
return self
end
--- Set markers on the map for Patrol Points.
-- @param #EASYGCICAP self
-- @param #boolean onoff Set to true to switch markers on.
-- @return #EASYGCICAP self
function EASYGCICAP:ShowPatrolPointMarkers(onoff)
if onoff then
self.showpatrolpointmarks = true
else
self.showpatrolpointmarks = false
end
return self
end
--- Set "fuel critical" threshold for CAP and INTERCEPT flights.
-- @param #EASYGCICAP self
-- @param #number Percent RTB if fuel at this percent. Values: 1..100, defaults to 10.
-- @return #EASYGCICAP self
function EASYGCICAP:SetFuelCritical(Percent)
self:T(self.lid.."SetFuelCritical")
self.FuelCriticalThreshold = Percent or 10
return self
end
--- Set CAP formation. --- Set CAP formation.
-- @param #EASYGCICAP self -- @param #EASYGCICAP self
-- @param #number Formation Formation to fly, defaults to ENUMS.Formation.FixedWing.FingerFour.Group -- @param #number Formation Formation to fly, defaults to ENUMS.Formation.FixedWing.FingerFour.Group
@@ -347,9 +434,23 @@ function EASYGCICAP:SetTankerAndAWACSInvisible(Switch)
return self return self
end end
--- Set Maximum of alive missions to stop airplanes spamming the map --- (internal) Count alive missions in our internal stack.
-- @param #EASYGCICAP self -- @param #EASYGCICAP self
-- @param #number Maxiumum Maxmimum number of parallel missions allowed. Count is Cap-Missions + Intercept-Missions + Alert5-Missionsm default is 6 -- @return #number count
function EASYGCICAP:_CountAliveAuftrags()
local alive = 0
for _,_auftrag in pairs(self.ListOfAuftrag) do
local auftrag = _auftrag -- Ops.Auftrag#AUFTRAG
if auftrag and (not (auftrag:IsCancelled() or auftrag:IsDone() or auftrag:IsOver())) then
alive = alive + 1
end
end
return alive
end
--- Set Maximum of alive missions created by this instance to stop airplanes spamming the map
-- @param #EASYGCICAP self
-- @param #number Maxiumum Maxmimum number of parallel missions allowed. Count is Intercept-Missions + Alert5-Missions, default is 8
-- @return #EASYGCICAP self -- @return #EASYGCICAP self
function EASYGCICAP:SetMaxAliveMissions(Maxiumum) function EASYGCICAP:SetMaxAliveMissions(Maxiumum)
self:T(self.lid.."SetMaxAliveMissions") self:T(self.lid.."SetMaxAliveMissions")
@@ -377,6 +478,16 @@ function EASYGCICAP:SetDefaultRepeatOnFailure(Retries)
return self return self
end end
--- Add default take off type for the airwings.
-- @param #EASYGCICAP self
-- @param #string Takeoff Can be "hot", "cold", or "air" - default is "hot".
-- @return #EASYGCICAP self
function EASYGCICAP:SetDefaultTakeOffType(Takeoff)
self:T(self.lid.."SetDefaultTakeOffType")
self.defaulttakeofftype = Takeoff or "hot"
return self
end
--- Set default CAP Speed in knots --- Set default CAP Speed in knots
-- @param #EASYGCICAP self -- @param #EASYGCICAP self
-- @param #number Speed Speed defaults to 300 -- @param #number Speed Speed defaults to 300
@@ -441,9 +552,9 @@ end
-- @param #EASYGCICAP self -- @param #EASYGCICAP self
-- @param #number Airframes defaults to 2 -- @param #number Airframes defaults to 2
-- @return #EASYGCICAP self -- @return #EASYGCICAP self
function EASYGCICAP:SetDefaultNumberAlter5Standby(Airframes) function EASYGCICAP:SetDefaultNumberAlert5Standby(Airframes)
self:T(self.lid.."SetDefaultNumberAlter5Standby") self:T(self.lid.."SetDefaultNumberAlert5Standby")
self.noaltert5 = math.abs(Airframes) or 2 self.noalert5 = math.abs(Airframes) or 2
return self return self
end end
@@ -452,7 +563,7 @@ end
-- @param #number Range defaults to 50NM -- @param #number Range defaults to 50NM
-- @return #EASYGCICAP self -- @return #EASYGCICAP self
function EASYGCICAP:SetDefaultEngageRange(Range) function EASYGCICAP:SetDefaultEngageRange(Range)
self:T(self.lid.."SetDefaultNumberAlter5Standby") self:T(self.lid.."SetDefaultEngageRange")
self.engagerange = Range or 50 self.engagerange = Range or 50
return self return self
end end
@@ -500,6 +611,17 @@ function EASYGCICAP:SetCapStartTimeVariation(Start, End)
return self return self
end end
--- Set which target types CAP flights will prefer to engage, defaults to {"Air"}
-- @param #EASYGCICAP self
-- @param #table types Table of comma separated #string entries, defaults to {"Air"} (everything that flies and is not a weapon). Useful other options are e.g. {"Bombers"}, {"Fighters"},
-- or {"Helicopters"} or combinations like {"Bombers", "Fighters", "UAVs"}. See [Hoggit Wiki](https://wiki.hoggitworld.com/view/DCS_enum_attributes).
-- @return #EASYGCICAP self
function EASYGCICAP:SetCAPEngageTargetTypes(types)
self.EngageTargetTypes = types or {"Air"}
return self
end
--- Add an AirWing to the manager --- Add an AirWing to the manager
-- @param #EASYGCICAP self -- @param #EASYGCICAP self
-- @param #string Airbasename -- @param #string Airbasename
@@ -546,6 +668,13 @@ function EASYGCICAP:_AddAirwing(Airbasename, Alias)
local DespawnAfterLanding = self.DespawnAfterLanding local DespawnAfterLanding = self.DespawnAfterLanding
local DespawnAfterHolding = self.DespawnAfterHolding local DespawnAfterHolding = self.DespawnAfterHolding
-- Check STATIC name
local check = STATIC:FindByName(Airbasename,false) or UNIT:FindByName(Airbasename)
if check == nil then
MESSAGE:New(self.lid.."There's no warehouse static on the map (wrong naming?) for airbase "..tostring(Airbasename).."!",30,"CHECK"):ToAllIf(self.debug):ToLog()
return
end
-- Create Airwing -- Create Airwing
local CAP_Wing = AIRWING:New(Airbasename,Alias) local CAP_Wing = AIRWING:New(Airbasename,Alias)
CAP_Wing:SetVerbosityLevel(0) CAP_Wing:SetVerbosityLevel(0)
@@ -556,6 +685,10 @@ function EASYGCICAP:_AddAirwing(Airbasename, Alias)
CAP_Wing:SetNumberCAP(self.capgrouping) CAP_Wing:SetNumberCAP(self.capgrouping)
CAP_Wing:SetCapCloseRaceTrack(true) CAP_Wing:SetCapCloseRaceTrack(true)
if self.showpatrolpointmarks then
CAP_Wing:ShowPatrolPointMarkers(true)
end
if self.capOptionVaryStartTime then if self.capOptionVaryStartTime then
CAP_Wing:SetCapStartTimeVariation(self.capOptionVaryStartTime,self.capOptionVaryEndTime) CAP_Wing:SetCapStartTimeVariation(self.capOptionVaryStartTime,self.capOptionVaryEndTime)
end end
@@ -573,9 +706,8 @@ function EASYGCICAP:_AddAirwing(Airbasename, Alias)
if #self.ManagedREC > 0 then if #self.ManagedREC > 0 then
CAP_Wing:SetNumberRecon(1) CAP_Wing:SetNumberRecon(1)
end end
--local PatrolCoordinateKutaisi = ZONE:New(CapZoneName):GetCoordinate()
--CAP_Wing:AddPatrolPointCAP(PatrolCoordinateKutaisi,self.capalt,UTILS.KnotsToAltKIAS(self.capspeed,self.capalt),self.capdir,self.capleg) CAP_Wing:SetTakeoffType(self.defaulttakeofftype)
CAP_Wing:SetTakeoffHot()
CAP_Wing:SetLowFuelThreshold(0.3) CAP_Wing:SetLowFuelThreshold(0.3)
CAP_Wing.RandomAssetScore = math.random(50,100) CAP_Wing.RandomAssetScore = math.random(50,100)
CAP_Wing:Start() CAP_Wing:Start()
@@ -583,8 +715,14 @@ function EASYGCICAP:_AddAirwing(Airbasename, Alias)
local Intel = self.Intel local Intel = self.Intel
local TankerInvisible = self.TankerInvisible local TankerInvisible = self.TankerInvisible
local engagerange = self.engagerange
local GoZoneSet = self.GoZoneSet
local NoGoZoneSet = self.NoGoZoneSet
local FuelLow = self.FuelLowThreshold or 25
local FuelCritical = self.FuelCriticalThreshold or 10
local EngageTypes = self.EngageTargetTypes or {"Air"}
function CAP_Wing:OnAfterFlightOnMission(From, Event, To, Flightgroup, Mission) function CAP_Wing:onbeforeFlightOnMission(From, Event, To, Flightgroup, Mission)
local flightgroup = Flightgroup -- Ops.FlightGroup#FLIGHTGROUP local flightgroup = Flightgroup -- Ops.FlightGroup#FLIGHTGROUP
if DespawnAfterLanding then if DespawnAfterLanding then
flightgroup:SetDespawnAfterLanding() flightgroup:SetDespawnAfterLanding()
@@ -594,10 +732,15 @@ function EASYGCICAP:_AddAirwing(Airbasename, Alias)
flightgroup:SetDestinationbase(AIRBASE:FindByName(Airbasename)) flightgroup:SetDestinationbase(AIRBASE:FindByName(Airbasename))
flightgroup:GetGroup():CommandEPLRS(true,5) flightgroup:GetGroup():CommandEPLRS(true,5)
flightgroup:GetGroup():SetOptionRadarUsingForContinousSearch() flightgroup:GetGroup():SetOptionRadarUsingForContinousSearch()
flightgroup:GetGroup():SetOptionLandingOverheadBreak()
if Mission.type ~= AUFTRAG.Type.TANKER and Mission.type ~= AUFTRAG.Type.AWACS and Mission.type ~= AUFTRAG.Type.RECON then if Mission.type ~= AUFTRAG.Type.TANKER and Mission.type ~= AUFTRAG.Type.AWACS and Mission.type ~= AUFTRAG.Type.RECON then
flightgroup:SetDetection(true) flightgroup:SetDetection(true)
flightgroup:SetEngageDetectedOn(self.engagerange,{"Air"},self.GoZoneSet,self.NoGoZoneSet) flightgroup:SetEngageDetectedOn(engagerange,EngageTypes,GoZoneSet,NoGoZoneSet)
flightgroup:SetOutOfAAMRTB() flightgroup:SetOutOfAAMRTB()
flightgroup:SetFuelLowRTB(true)
flightgroup:SetFuelLowThreshold(FuelLow)
flightgroup:SetFuelCriticalRTB(true)
flightgroup:SetFuelCriticalThreshold(FuelCritical)
if CapFormation then if CapFormation then
flightgroup:GetGroup():SetOption(AI.Option.Air.id.FORMATION,CapFormation) flightgroup:GetGroup():SetOption(AI.Option.Air.id.FORMATION,CapFormation)
end end
@@ -614,15 +757,15 @@ function EASYGCICAP:_AddAirwing(Airbasename, Alias)
flightgroup:SetFuelLowRTB(true) flightgroup:SetFuelLowRTB(true)
Intel:AddAgent(flightgroup) Intel:AddAgent(flightgroup)
if DespawnAfterHolding then if DespawnAfterHolding then
function flightgroup:OnAfterHolding(From,Event,To) function flightgroup:onbeforeHolding(From,Event,To)
self:Despawn(1,true) self:Despawn(1,true)
end end
end end
end end
if self.noaltert5 > 0 then if self.noalert5 > 0 then
local alert = AUFTRAG:NewALERT5(AUFTRAG.Type.INTERCEPT) local alert = AUFTRAG:NewALERT5(AUFTRAG.Type.INTERCEPT)
alert:SetRequiredAssets(self.noaltert5) alert:SetRequiredAssets(self.noalert5)
alert:SetRepeat(99) alert:SetRepeat(99)
CAP_Wing:AddMission(alert) CAP_Wing:AddMission(alert)
table.insert(self.ListOfAuftrag,alert) table.insert(self.ListOfAuftrag,alert)
@@ -636,24 +779,30 @@ end
--- Add a CAP patrol point to a Wing --- Add a CAP patrol point to a Wing
-- @param #EASYGCICAP self -- @param #EASYGCICAP self
-- @param #string AirbaseName Name of the Wing's airbase -- @param #string AirbaseName Name of the Wing's airbase
-- @param Core.Point#COORDINATE Coordinate. -- @param Core.Point#COORDINATE Coordinate. Can be handed as a Core.Zone#ZONE object (e.g. in case you want the point to align with a moving zone).
-- @param #number Altitude Defaults to 25000 feet ASL. -- @param #number Altitude Defaults to 25000 feet ASL.
-- @param #number Speed Defaults to 300 knots TAS. -- @param #number Speed Defaults to 300 knots TAS.
-- @param #number Heading Defaults to 90 degrees (East). -- @param #number Heading Defaults to 90 degrees (East).
-- @param #number LegLength Defaults to 15 NM. -- @param #number LegLength Defaults to 15 NM.
-- @return #EASYGCICAP self -- @return #EASYGCICAP self
function EASYGCICAP:AddPatrolPointCAP(AirbaseName,Coordinate,Altitude,Speed,Heading,LegLength) function EASYGCICAP:AddPatrolPointCAP(AirbaseName,Coordinate,Altitude,Speed,Heading,LegLength)
self:T(self.lid.."AddPatrolPointCAP "..Coordinate:ToStringLLDDM()) self:T(self.lid.."AddPatrolPointCAP")--..Coordinate:ToStringLLDDM())
local coordinate = Coordinate
local EntryCAP = {} -- #EASYGCICAP.CapPoint local EntryCAP = {} -- #EASYGCICAP.CapPoint
if Coordinate:IsInstanceOf("ZONE_BASE") then
-- adjust coordinate and get the coordinate from the zone
coordinate = Coordinate:GetCoordinate()
EntryCAP.Zone = Coordinate
end
EntryCAP.AirbaseName = AirbaseName EntryCAP.AirbaseName = AirbaseName
EntryCAP.Coordinate = Coordinate EntryCAP.Coordinate = coordinate
EntryCAP.Altitude = Altitude or 25000 EntryCAP.Altitude = Altitude or 25000
EntryCAP.Speed = Speed or 300 EntryCAP.Speed = Speed or 300
EntryCAP.Heading = Heading or 90 EntryCAP.Heading = Heading or 90
EntryCAP.LegLength = LegLength or 15 EntryCAP.LegLength = LegLength or 15
self.ManagedCP[#self.ManagedCP+1] = EntryCAP self.ManagedCP[#self.ManagedCP+1] = EntryCAP
if self.debug then if self.debug then
local mark = MARKER:New(Coordinate,self.lid.."Patrol Point"):ToAll() local mark = MARKER:New(coordinate,self.lid.."Patrol Point"):ToAll()
end end
return self return self
end end
@@ -661,7 +810,7 @@ end
--- Add a RECON patrol point to a Wing --- Add a RECON patrol point to a Wing
-- @param #EASYGCICAP self -- @param #EASYGCICAP self
-- @param #string AirbaseName Name of the Wing's airbase -- @param #string AirbaseName Name of the Wing's airbase
-- @param Core.Point#COORDINATE Coordinate. -- @param Core.Point#COORDINATE Coordinate. Can be handed as a Core.Zone#ZONE object (e.g. in case you want the point to align with a moving zone).
-- @param #number Altitude Defaults to 25000 feet. -- @param #number Altitude Defaults to 25000 feet.
-- @param #number Speed Defaults to 300 knots. -- @param #number Speed Defaults to 300 knots.
-- @param #number Heading Defaults to 90 degrees (East). -- @param #number Heading Defaults to 90 degrees (East).
@@ -686,7 +835,7 @@ end
--- Add a TANKER patrol point to a Wing --- Add a TANKER patrol point to a Wing
-- @param #EASYGCICAP self -- @param #EASYGCICAP self
-- @param #string AirbaseName Name of the Wing's airbase -- @param #string AirbaseName Name of the Wing's airbase
-- @param Core.Point#COORDINATE Coordinate. -- @param Core.Point#COORDINATE Coordinate. Can be handed as a Core.Zone#ZONE object (e.g. in case you want the point to align with a moving zone).
-- @param #number Altitude Defaults to 25000 feet. -- @param #number Altitude Defaults to 25000 feet.
-- @param #number Speed Defaults to 300 knots. -- @param #number Speed Defaults to 300 knots.
-- @param #number Heading Defaults to 90 degrees (East). -- @param #number Heading Defaults to 90 degrees (East).
@@ -711,7 +860,7 @@ end
--- Add an AWACS patrol point to a Wing --- Add an AWACS patrol point to a Wing
-- @param #EASYGCICAP self -- @param #EASYGCICAP self
-- @param #string AirbaseName Name of the Wing's airbase -- @param #string AirbaseName Name of the Wing's airbase
-- @param Core.Point#COORDINATE Coordinate. -- @param Core.Point#COORDINATE Coordinate. Can be handed as a Core.Zone#ZONE object (e.g. in case you want the point to align with a moving zone).
-- @param #number Altitude Defaults to 25000 feet. -- @param #number Altitude Defaults to 25000 feet.
-- @param #number Speed Defaults to 300 knots. -- @param #number Speed Defaults to 300 knots.
-- @param #number Heading Defaults to 90 degrees (East). -- @param #number Heading Defaults to 90 degrees (East).
@@ -740,6 +889,11 @@ function EASYGCICAP:_SetTankerPatrolPoints()
self:T(self.lid.."_SetTankerPatrolPoints") self:T(self.lid.."_SetTankerPatrolPoints")
for _,_data in pairs(self.ManagedTK) do for _,_data in pairs(self.ManagedTK) do
local data = _data --#EASYGCICAP.CapPoint local data = _data --#EASYGCICAP.CapPoint
self:T("Airbasename = "..data.AirbaseName)
if not self.wings[data.AirbaseName] then
MESSAGE:New(self.lid.."You are trying to create a TANKER point for which there is no wing! "..tostring(data.AirbaseName),30,"CHECK"):ToAllIf(self.debug):ToLog()
return
end
local Wing = self.wings[data.AirbaseName][1] -- Ops.Airwing#AIRWING local Wing = self.wings[data.AirbaseName][1] -- Ops.Airwing#AIRWING
local Coordinate = data.Coordinate local Coordinate = data.Coordinate
local Altitude = data.Altitude local Altitude = data.Altitude
@@ -759,6 +913,11 @@ function EASYGCICAP:_SetAwacsPatrolPoints()
self:T(self.lid.."_SetAwacsPatrolPoints") self:T(self.lid.."_SetAwacsPatrolPoints")
for _,_data in pairs(self.ManagedEWR) do for _,_data in pairs(self.ManagedEWR) do
local data = _data --#EASYGCICAP.CapPoint local data = _data --#EASYGCICAP.CapPoint
self:T("Airbasename = "..data.AirbaseName)
if not self.wings[data.AirbaseName] then
MESSAGE:New(self.lid.."You are trying to create an AWACS point for which there is no wing! "..tostring(data.AirbaseName),30,"CHECK"):ToAllIf(self.debug):ToLog()
return
end
local Wing = self.wings[data.AirbaseName][1] -- Ops.Airwing#AIRWING local Wing = self.wings[data.AirbaseName][1] -- Ops.Airwing#AIRWING
local Coordinate = data.Coordinate local Coordinate = data.Coordinate
local Altitude = data.Altitude local Altitude = data.Altitude
@@ -778,14 +937,24 @@ function EASYGCICAP:_SetCAPPatrolPoints()
self:T(self.lid.."_SetCAPPatrolPoints") self:T(self.lid.."_SetCAPPatrolPoints")
for _,_data in pairs(self.ManagedCP) do for _,_data in pairs(self.ManagedCP) do
local data = _data --#EASYGCICAP.CapPoint local data = _data --#EASYGCICAP.CapPoint
self:T("Airbasename = "..data.AirbaseName)
if not self.wings[data.AirbaseName] then
MESSAGE:New(self.lid.."You are trying to create a CAP point for which there is no wing! "..tostring(data.AirbaseName),30,"CHECK"):ToAllIf(self.debug):ToLog()
return
end
local Wing = self.wings[data.AirbaseName][1] -- Ops.Airwing#AIRWING local Wing = self.wings[data.AirbaseName][1] -- Ops.Airwing#AIRWING
local Coordinate = data.Coordinate local Coordinate = data.Coordinate
local Altitude = data.Altitude local Altitude = data.Altitude
local Speed = data.Speed local Speed = data.Speed
local Heading = data.Heading local Heading = data.Heading
local LegLength = data.LegLength local LegLength = data.LegLength
local Zone = _data.Zone
if Zone then
Wing:AddPatrolPointCAP(Zone,Altitude,Speed,Heading,LegLength)
else
Wing:AddPatrolPointCAP(Coordinate,Altitude,Speed,Heading,LegLength) Wing:AddPatrolPointCAP(Coordinate,Altitude,Speed,Heading,LegLength)
end end
end
return self return self
end end
@@ -797,6 +966,11 @@ function EASYGCICAP:_SetReconPatrolPoints()
self:T(self.lid.."_SetReconPatrolPoints") self:T(self.lid.."_SetReconPatrolPoints")
for _,_data in pairs(self.ManagedREC) do for _,_data in pairs(self.ManagedREC) do
local data = _data --#EASYGCICAP.CapPoint local data = _data --#EASYGCICAP.CapPoint
self:T("Airbasename = "..data.AirbaseName)
if not self.wings[data.AirbaseName] then
MESSAGE:New(self.lid.."You are trying to create a RECON point for which there is no wing! "..tostring(data.AirbaseName),30,"CHECK"):ToAllIf(self.debug):ToLog()
return
end
local Wing = self.wings[data.AirbaseName][1] -- Ops.Airwing#AIRWING local Wing = self.wings[data.AirbaseName][1] -- Ops.Airwing#AIRWING
local Coordinate = data.Coordinate local Coordinate = data.Coordinate
local Altitude = data.Altitude local Altitude = data.Altitude
@@ -845,7 +1019,7 @@ end
-- @param #string SquadName Squadron name - must be unique! -- @param #string SquadName Squadron name - must be unique!
-- @param #string AirbaseName Name of the airbase the airwing resides on, e.g. AIRBASE.Caucasus.Kutaisi -- @param #string AirbaseName Name of the airbase the airwing resides on, e.g. AIRBASE.Caucasus.Kutaisi
-- @param #number AirFrames Number of available airframes, e.g. 20. -- @param #number AirFrames Number of available airframes, e.g. 20.
-- @param #string Skill(optional) Skill level, e.g. AI.Skill.AVERAGE -- @param #string Skill (optional) Skill level, e.g. AI.Skill.AVERAGE
-- @param #string Modex (optional) Modex to be used,e.g. 402. -- @param #string Modex (optional) Modex to be used,e.g. 402.
-- @param #string Livery (optional) Livery name to be used. -- @param #string Livery (optional) Livery name to be used.
-- @return #EASYGCICAP self -- @return #EASYGCICAP self
@@ -1050,7 +1224,9 @@ function EASYGCICAP:_AddTankerSquadron(TemplateName, SquadName, AirbaseName, Air
Squadron_One:SetSkill(Skill or AI.Skill.AVERAGE) Squadron_One:SetSkill(Skill or AI.Skill.AVERAGE)
Squadron_One:SetMissionRange(self.missionrange) Squadron_One:SetMissionRange(self.missionrange)
Squadron_One:SetRadio(Frequency,Modulation) Squadron_One:SetRadio(Frequency,Modulation)
if TACAN then
Squadron_One:AddTacanChannel(TACAN,TACAN) Squadron_One:AddTacanChannel(TACAN,TACAN)
end
local wing = self.wings[AirbaseName][1] -- Ops.Airwing#AIRWING local wing = self.wings[AirbaseName][1] -- Ops.Airwing#AIRWING
@@ -1098,7 +1274,7 @@ end
-- @param Core.Zone#ZONE_BASE Zone -- @param Core.Zone#ZONE_BASE Zone
-- @return #EASYGCICAP self -- @return #EASYGCICAP self
function EASYGCICAP:AddAcceptZone(Zone) function EASYGCICAP:AddAcceptZone(Zone)
self:T(self.lid.."AddAcceptZone0") self:T(self.lid.."AddAcceptZone")
self.GoZoneSet:AddZone(Zone) self.GoZoneSet:AddZone(Zone)
return self return self
end end
@@ -1113,6 +1289,18 @@ function EASYGCICAP:AddRejectZone(Zone)
return self return self
end end
--- Add a zone to the conflict zones set.
-- @param #EASYGCICAP self
-- @param Core.Zone#ZONE_BASE Zone
-- @return #EASYGCICAP self
function EASYGCICAP:AddConflictZone(Zone)
self:T(self.lid.."AddConflictZone")
self.ConflictZoneSet:AddZone(Zone)
self.GoZoneSet:AddZone(Zone)
return self
end
--- (Internal) Try to assign the intercept to a FlightGroup already in air and ready. --- (Internal) Try to assign the intercept to a FlightGroup already in air and ready.
-- @param #EASYGCICAP self -- @param #EASYGCICAP self
-- @param #table ReadyFlightGroups ReadyFlightGroups -- @param #table ReadyFlightGroups ReadyFlightGroups
@@ -1122,19 +1310,19 @@ end
-- @return #boolean assigned -- @return #boolean assigned
-- @return #number leftover -- @return #number leftover
function EASYGCICAP:_TryAssignIntercept(ReadyFlightGroups,InterceptAuftrag,Group,WingSize) function EASYGCICAP:_TryAssignIntercept(ReadyFlightGroups,InterceptAuftrag,Group,WingSize)
self:I("_TryAssignIntercept for size "..WingSize or 1) self:T("_TryAssignIntercept for size "..WingSize or 1)
local assigned = false local assigned = false
local wingsize = WingSize or 1 local wingsize = WingSize or 1
local mindist = 0 local mindist = 0
local disttable = {} local disttable = {}
if Group and Group:IsAlive() then if Group and Group:IsAlive() then
local gcoord = Group:GetCoordinate() or COORDINATE:New(0,0,0) local gcoord = Group:GetCoordinate() or COORDINATE:New(0,0,0)
self:I(self.lid..string.format("Assignment for %s",Group:GetName())) self:T(self.lid..string.format("Assignment for %s",Group:GetName()))
for _name,_FG in pairs(ReadyFlightGroups or {}) do for _name,_FG in pairs(ReadyFlightGroups or {}) do
local FG = _FG -- Ops.FlightGroup#FLIGHTGROUP local FG = _FG -- Ops.FlightGroup#FLIGHTGROUP
local fcoord = FG:GetCoordinate() local fcoord = FG:GetCoordinate()
local dist = math.floor(UTILS.Round(fcoord:Get2DDistance(gcoord)/1000,1)) local dist = math.floor(UTILS.Round(fcoord:Get2DDistance(gcoord)/1000,1))
self:I(self.lid..string.format("FG %s Distance %dkm",_name,dist)) self:T(self.lid..string.format("FG %s Distance %dkm",_name,dist))
disttable[#disttable+1] = { FG=FG, dist=dist} disttable[#disttable+1] = { FG=FG, dist=dist}
if dist>mindist then mindist=dist end if dist>mindist then mindist=dist end
end end
@@ -1151,7 +1339,7 @@ function EASYGCICAP:_TryAssignIntercept(ReadyFlightGroups,InterceptAuftrag,Group
local cm = FG:GetMissionCurrent() local cm = FG:GetMissionCurrent()
if cm then cm:Cancel() end if cm then cm:Cancel() end
wingsize = wingsize - 1 wingsize = wingsize - 1
self:I(self.lid..string.format("Assigned to FG %s Distance %dkm",FG:GetName(),_entry.dist)) self:T(self.lid..string.format("Assigned to FG %s Distance %dkm",FG:GetName(),_entry.dist))
if wingsize == 0 then if wingsize == 0 then
assigned = true assigned = true
break break
@@ -1176,8 +1364,9 @@ function EASYGCICAP:_AssignIntercept(Cluster)
local wings = self.wings local wings = self.wings
local ctlpts = self.ManagedCP local ctlpts = self.ManagedCP
local MaxAliveMissions = self.MaxAliveMissions * self.capgrouping local MaxAliveMissions = self.MaxAliveMissions --* self.capgrouping
local nogozoneset = self.NoGoZoneSet local nogozoneset = self.NoGoZoneSet
local conflictzoneset = self.ConflictZoneSet
local ReadyFlightGroups = self.ReadyFlightGroups local ReadyFlightGroups = self.ReadyFlightGroups
-- Aircraft? -- Aircraft?
@@ -1225,6 +1414,10 @@ function EASYGCICAP:_AssignIntercept(Cluster)
local data = _data -- #EASYGCICAP.CapPoint local data = _data -- #EASYGCICAP.CapPoint
local name = data.AirbaseName local name = data.AirbaseName
local zonecoord = data.Coordinate local zonecoord = data.Coordinate
if data.Zone then
-- refresh coordinate in case we have a (moving) zone
zonecoord = data.Zone:GetCoordinate()
end
local airwing = wings[name][1] local airwing = wings[name][1]
local coa = AIRBASE:FindByName(name):GetCoalition() local coa = AIRBASE:FindByName(name):GetCoalition()
local samecoalitionab = coa == self.coalition and true or false local samecoalitionab = coa == self.coalition and true or false
@@ -1241,9 +1434,10 @@ function EASYGCICAP:_AssignIntercept(Cluster)
-- Do we have a matching airwing? -- Do we have a matching airwing?
if targetairwing then if targetairwing then
local AssetCount = targetairwing:CountAssetsOnMission(MissionTypes,Cohort) local AssetCount = targetairwing:CountAssetsOnMission(MissionTypes,Cohort)
local missioncount = self:_CountAliveAuftrags()
-- Enough airframes on mission already? -- Enough airframes on mission already?
self:T(self.lid.." Assets on Mission "..AssetCount) self:T(self.lid.." Assets on Mission "..AssetCount)
if AssetCount <= MaxAliveMissions then if missioncount < MaxAliveMissions then
local repeats = repeatsonfailure local repeats = repeatsonfailure
local InterceptAuftrag = AUFTRAG:NewINTERCEPT(contact.group) local InterceptAuftrag = AUFTRAG:NewINTERCEPT(contact.group)
:SetMissionRange(150) :SetMissionRange(150)
@@ -1255,18 +1449,22 @@ function EASYGCICAP:_AssignIntercept(Cluster)
if nogozoneset:Count() > 0 then if nogozoneset:Count() > 0 then
InterceptAuftrag:AddConditionSuccess( InterceptAuftrag:AddConditionSuccess(
function(group,zoneset) function(group,zoneset,conflictset)
local success = false local success = false
if group and group:IsAlive() then if group and group:IsAlive() then
local coord = group:GetCoordinate() local coord = group:GetCoordinate()
if coord and zoneset:IsCoordinateInZone(coord) then if coord and zoneset:Count() > 0 and zoneset:IsCoordinateInZone(coord) then
success = true success = true
end end
if coord and conflictset:Count() > 0 and conflictset:IsCoordinateInZone(coord) then
success = false
end
end end
return success return success
end, end,
contact.group, contact.group,
nogozoneset nogozoneset,
conflictzoneset
) )
end end
@@ -1291,15 +1489,16 @@ function EASYGCICAP:_StartIntel()
self:T(self.lid.."_StartIntel") self:T(self.lid.."_StartIntel")
-- Border GCI Detection -- Border GCI Detection
local BlueAir_DetectionSetGroup = SET_GROUP:New() local BlueAir_DetectionSetGroup = SET_GROUP:New()
BlueAir_DetectionSetGroup:FilterPrefixes( { self.EWRName } ) BlueAir_DetectionSetGroup:FilterPrefixes( self.EWRName )
BlueAir_DetectionSetGroup:FilterStart() BlueAir_DetectionSetGroup:FilterStart()
-- Intel type detection -- Intel type detection
local BlueIntel = INTEL:New(BlueAir_DetectionSetGroup,self.coalitionname, self.EWRName) local BlueIntel = INTEL:New(BlueAir_DetectionSetGroup,self.coalitionname, self.alias)
BlueIntel:SetClusterAnalysis(true,false,false) BlueIntel:SetClusterAnalysis(true,false,false)
BlueIntel:SetForgetTime(300) BlueIntel:SetForgetTime(300)
BlueIntel:SetAcceptZones(self.GoZoneSet) BlueIntel:SetAcceptZones(self.GoZoneSet)
BlueIntel:SetRejectZones(self.NoGoZoneSet) BlueIntel:SetRejectZones(self.NoGoZoneSet)
BlueIntel:SetConflictZones(self.ConflictZoneSet)
BlueIntel:SetVerbosity(0) BlueIntel:SetVerbosity(0)
BlueIntel:Start() BlueIntel:Start()
@@ -1311,7 +1510,7 @@ function EASYGCICAP:_StartIntel()
self:_AssignIntercept(Cluster) self:_AssignIntercept(Cluster)
end end
function BlueIntel:OnAfterNewCluster(From,Event,To,Cluster) function BlueIntel:onbeforeNewCluster(From,Event,To,Cluster)
AssignCluster(Cluster) AssignCluster(Cluster)
end end
@@ -1320,7 +1519,7 @@ function EASYGCICAP:_StartIntel()
end end
------------------------------------------------------------------------- -------------------------------------------------------------------------
-- FSM Functions -- TODO FSM Functions
------------------------------------------------------------------------- -------------------------------------------------------------------------
--- (Internal) FSM Function onafterStart --- (Internal) FSM Function onafterStart
@@ -1416,7 +1615,7 @@ function EASYGCICAP:onafterStatus(From,Event,To)
local engage = FG:IsEngaging() local engage = FG:IsEngaging()
local hasmissiles = FG:IsOutOfMissiles() == nil and true or false local hasmissiles = FG:IsOutOfMissiles() == nil and true or false
local ready = hasmissiles and FG:IsFuelGood() and FG:IsAirborne() local ready = hasmissiles and FG:IsFuelGood() and FG:IsAirborne()
--self:I(string.format("Flightgroup %s Engaging = %s Ready = %s",tostring(name),tostring(engage),tostring(ready))) --self:T(string.format("Flightgroup %s Engaging = %s Ready = %s",tostring(name),tostring(engage),tostring(ready)))
if ready then if ready then
self.ReadyFlightGroups[name] = FG self.ReadyFlightGroups[name] = FG
end end
@@ -1428,12 +1627,14 @@ function EASYGCICAP:onafterStatus(From,Event,To)
local text = "GCICAP "..self.alias local text = "GCICAP "..self.alias
text = text.."\nWings: "..wings.."\nSquads: "..squads.."\nCapPoints: "..caps.."\nAssets on Mission: "..assets.."\nAssets in Stock: "..instock text = text.."\nWings: "..wings.."\nSquads: "..squads.."\nCapPoints: "..caps.."\nAssets on Mission: "..assets.."\nAssets in Stock: "..instock
text = text.."\nThreats: "..threatcount text = text.."\nThreats: "..threatcount
text = text.."\nMissions: "..capmission+interceptmission text = text.."\nAirWing managed Missions: "..capmission+awacsmission+tankermission+reconmission
text = text.."\n - CAP: "..capmission text = text.."\n - CAP: "..capmission
text = text.."\n - Intercept: "..interceptmission
text = text.."\n - AWACS: "..awacsmission text = text.."\n - AWACS: "..awacsmission
text = text.."\n - TANKER: "..tankermission text = text.."\n - TANKER: "..tankermission
text = text.."\n - Recon: "..reconmission text = text.."\n - Recon: "..reconmission
text = text.."\nSelf managed Missions:"
text = text.."\n - Mission Limit: "..self.MaxAliveMissions
text = text.."\n - Alert5+Intercept "..self:_CountAliveAuftrags()
MESSAGE:New(text,15,"GCICAP"):ToAll():ToLogIf(self.debug) MESSAGE:New(text,15,"GCICAP"):ToAll():ToLogIf(self.debug)
end end
self:__Status(30) self:__Status(30)
@@ -1449,5 +1650,8 @@ end
function EASYGCICAP:onafterStop(From,Event,To) function EASYGCICAP:onafterStop(From,Event,To)
self:T({From,Event,To}) self:T({From,Event,To})
self.Intel:Stop() self.Intel:Stop()
for _,_wing in pairs(self.wings or {}) do
_wing:Stop()
end
return self return self
end end
@@ -2464,7 +2464,7 @@ end
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Payer Menu -- Player Menu
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- Create player menu. --- Create player menu.
+99 -50
View File
@@ -217,7 +217,7 @@ FLIGHTGROUP.Players={}
--- FLIGHTGROUP class version. --- FLIGHTGROUP class version.
-- @field #string version -- @field #string version
FLIGHTGROUP.version="1.0.2" FLIGHTGROUP.version="1.0.3"
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO list -- TODO list
@@ -259,7 +259,7 @@ function FLIGHTGROUP:New(group)
local self=BASE:Inherit(self, OPSGROUP:New(group)) -- #FLIGHTGROUP local self=BASE:Inherit(self, OPSGROUP:New(group)) -- #FLIGHTGROUP
-- Set some string id for output to DCS.log file. -- Set some string id for output to DCS.log file.
self.lid=string.format("FLIGHTGROUP %s | ", self.groupname) self.lid=string.format("FLIGHTGROUP %s | ", self.groupname or "N/A")
-- Defaults -- Defaults
self:SetDefaultROE() self:SetDefaultROE()
@@ -779,6 +779,61 @@ function FLIGHTGROUP:SetJettisonWeapons(Switch)
return self return self
end end
--- Set the aircraft to land straight in.
-- @param #FLIGHTGROUP self
-- @return #FLIGHTGROUP self
function FLIGHTGROUP:SetOptionLandingStraightIn()
self.OptionLandingStraightIn = true
if self:GetGroup():IsAlive() then
self:GetGroup():SetOptionLandingStraightIn()
end
return self
end
--- Set the aircraft to land in pairs.
-- @param #FLIGHTGROUP self
-- @return #FLIGHTGROUP self
function FLIGHTGROUP:SetOptionLandingForcePair()
self.OptionLandingForcePair = true
if self:GetGroup():IsAlive() then
self:GetGroup():SetOptionLandingForcePair()
end
return self
end
--- Set the aircraft to NOT land in pairs.
-- @param #FLIGHTGROUP self
-- @return #FLIGHTGROUP self
function FLIGHTGROUP:SetOptionLandingRestrictPair()
self.OptionLandingRestrictPair = true
if self:GetGroup():IsAlive() then
self:GetGroup():SetOptionLandingRestrictPair()
end
return self
end
--- Set the aircraft to land after overhead break.
-- @param #FLIGHTGROUP self
-- @return #FLIGHTGROUP self
function FLIGHTGROUP:SetOptionLandingOverheadBreak()
self.OptionLandingOverheadBreak = true
if self:GetGroup():IsAlive() then
self:GetGroup():SetOptionLandingOverheadBreak()
end
return self
end
--- [HELICOPTER] Set the aircraft to prefer takeoff and landing vertically.
-- @param #FLIGHTGROUP self
-- @return #FLIGHTGROUP self
function FLIGHTGROUP:SetOptionPreferVertical()
self.OptionPreferVertical = true
if self:GetGroup():IsAlive() then
self:GetGroup():OptionPreferVerticalLanding()
end
return self
end
--- Set if group is ready for taxi/takeoff if controlled by a `FLIGHTCONTROL`. --- Set if group is ready for taxi/takeoff if controlled by a `FLIGHTCONTROL`.
-- @param #FLIGHTGROUP self -- @param #FLIGHTGROUP self
-- @param #boolean ReadyTO If `true`, flight is ready for takeoff. -- @param #boolean ReadyTO If `true`, flight is ready for takeoff.
@@ -1277,6 +1332,25 @@ function FLIGHTGROUP:Status()
end end
end end
--- check if we need to end holding
--self:T(self.lid.."Checking if we are holding at a holding point...")
if mission and mission.missionHoldingCoord and self.isHoldingAtHoldingPoint == true then
self:T(self.lid.."...yes")
if mission:IsReadyToPush() then
--self:T(self.lid.."Ready to push -> YES")
-- move flag to 1
self.flaghold:Set(1)
-- Not waiting any more.
self.Twaiting=nil
self.dTwait=nil
self.isHoldingAtHoldingPoint = false
--else
--self:T(self.lid.."Ready to push -> NO!")
end
--else
--self:T(self.lid.."...no")
end
-- If mission, check if DCS task needs to be updated. -- If mission, check if DCS task needs to be updated.
if mission and mission.updateDCSTask then if mission and mission.updateDCSTask then
@@ -1984,6 +2058,9 @@ function FLIGHTGROUP:onafterElementAirborne(From, Event, To, Element)
-- Debug info. -- Debug info.
self:T2(self.lid..string.format("Element airborne %s", Element.name)) self:T2(self.lid..string.format("Element airborne %s", Element.name))
-- Set parking spot to free. Also for FC. This is usually done after taxiing but doing it here in case the group is teleported.
self:_SetElementParkingFree(Element)
-- Set element status. -- Set element status.
self:_UpdateStatus(Element, OPSGROUP.ElementStatus.AIRBORNE) self:_UpdateStatus(Element, OPSGROUP.ElementStatus.AIRBORNE)
@@ -3057,7 +3134,7 @@ function FLIGHTGROUP:onbeforeLandAtAirbase(From, Event, To, airbase)
local Tsuspend=nil local Tsuspend=nil
if airbase==nil then if airbase==nil then
self:T(self.lid.."ERROR: Airbase is nil in LandAtAirase() call!") self:T(self.lid.."ERROR: Airbase is nil in LandAtAirbase() call!")
allowed=false allowed=false
end end
@@ -3803,8 +3880,13 @@ end
--- Initialize group parameters. Also initializes waypoints if self.waypoints is nil. --- Initialize group parameters. Also initializes waypoints if self.waypoints is nil.
-- @param #FLIGHTGROUP self -- @param #FLIGHTGROUP self
-- @param #table Template Template used to init the group. Default is `self.template`. -- @param #table Template Template used to init the group. Default is `self.template`.
-- @param #number Delay Delay in seconds before group is initialized. Default `nil`, *i.e.* instantaneous.
-- @return #FLIGHTGROUP self -- @return #FLIGHTGROUP self
function FLIGHTGROUP:_InitGroup(Template) function FLIGHTGROUP:_InitGroup(Template, Delay)
if Delay and Delay>0 then
self:ScheduleOnce(Delay, FLIGHTGROUP._InitGroup, self, Template, 0)
else
-- First check if group was already initialized. -- First check if group was already initialized.
if self.groupinitialized then if self.groupinitialized then
@@ -3878,8 +3960,12 @@ function FLIGHTGROUP:_InitGroup(Template)
end end
-- Default TACAN off. -- Default TACAN off.
if not self.tacanDefault then
self:SetDefaultTACAN(nil, nil, nil, nil, true) self:SetDefaultTACAN(nil, nil, nil, nil, true)
end
if not self.tacan then
self.tacan=UTILS.DeepCopy(self.tacanDefault) self.tacan=UTILS.DeepCopy(self.tacanDefault)
end
-- Is this purely AI? -- Is this purely AI?
self.isAI=not self:_IsHuman(group) self.isAI=not self:_IsHuman(group)
@@ -3911,6 +3997,7 @@ function FLIGHTGROUP:_InitGroup(Template)
-- Init done. -- Init done.
self.groupinitialized=true self.groupinitialized=true
end
return self return self
end end
@@ -4179,51 +4266,6 @@ function FLIGHTGROUP:IsLandingAirbase(wp)
return nil return nil
end end
--- Initialize Mission Editor waypoints.
-- @param #FLIGHTGROUP self
-- @return #FLIGHTGROUP self
function FLIGHTGROUP:InitWaypoints()
-- Template waypoints.
self.waypoints0=self.group:GetTemplateRoutePoints()
-- Waypoints
self.waypoints={}
for index,wp in pairs(self.waypoints0) do
local waypoint=self:_CreateWaypoint(wp)
self:_AddWaypoint(waypoint)
end
-- Get home and destination airbases from waypoints.
self.homebase=self.homebase or self:GetHomebaseFromWaypoints()
self.destbase=self.destbase or self:GetDestinationFromWaypoints()
self.currbase=self:GetHomebaseFromWaypoints()
-- Remove the landing waypoint. We use RTB for that. It makes adding new waypoints easier as we do not have to check if the last waypoint is the landing waypoint.
if self.destbase and #self.waypoints>1 then
table.remove(self.waypoints, #self.waypoints)
else
self.destbase=self.homebase
end
-- Debug info.
self:T(self.lid..string.format("Initializing %d waypoints. Homebase %s ==> %s Destination", #self.waypoints, self.homebase and self.homebase:GetName() or "unknown", self.destbase and self.destbase:GetName() or "uknown"))
-- Update route.
if #self.waypoints>0 then
-- Check if only 1 wp?
if #self.waypoints==1 then
self:_PassedFinalWaypoint(true, "FLIGHTGROUP:InitWaypoints #self.waypoints==1")
end
end
return self
end
--- Add an AIR waypoint to the flight plan. --- Add an AIR waypoint to the flight plan.
-- @param #FLIGHTGROUP self -- @param #FLIGHTGROUP self
@@ -4510,6 +4552,11 @@ function FLIGHTGROUP:GetParkingSpot(element, maxdist, airbase)
-- Airbase. -- Airbase.
airbase=airbase or self:GetClosestAirbase() airbase=airbase or self:GetClosestAirbase()
if airbase == nil then
self:T(self.lid.."No airbase found for element "..element.name)
return nil
end
-- Parking table of airbase. -- Parking table of airbase.
local parking=airbase.parking --:GetParkingSpotsTable() local parking=airbase.parking --:GetParkingSpotsTable()
@@ -4620,12 +4667,14 @@ function FLIGHTGROUP:GetParking(airbase)
local coords={} local coords={}
for clientname, client in pairs(clients) do for clientname, client in pairs(clients) do
local template=_DATABASE:GetGroupTemplateFromUnitName(clientname) local template=_DATABASE:GetGroupTemplateFromUnitName(clientname)
if template then
local units=template.units local units=template.units
for i,unit in pairs(units) do for i,unit in pairs(units) do
local coord=COORDINATE:New(unit.x, unit.alt, unit.y) local coord=COORDINATE:New(unit.x, unit.alt, unit.y)
coords[unit.name]=coord coords[unit.name]=coord
end end
end end
end
return coords return coords
end end
@@ -4980,7 +5029,7 @@ function FLIGHTGROUP:_UpdateMenu(delay)
-- Message to group. -- Message to group.
MESSAGE:New(text, 5):ToGroup(self.group) MESSAGE:New(text, 5):ToGroup(self.group)
self:I(self.lid..text) self:T(self.lid..text)
end end
-- Get current position of player. -- Get current position of player.
+15 -5
View File
@@ -2324,7 +2324,7 @@ INTEL_DLINK = {
verbose = 0, verbose = 0,
lid = nil, lid = nil,
alias = nil, alias = nil,
cachetime = 300, cachetime = 120,
interval = 20, interval = 20,
contacts = {}, contacts = {},
clusters = {}, clusters = {},
@@ -2333,7 +2333,7 @@ INTEL_DLINK = {
--- Version string --- Version string
-- @field #string version -- @field #string version
INTEL_DLINK.version = "0.0.1" INTEL_DLINK.version = "0.0.2"
--- Function to instantiate a new object --- Function to instantiate a new object
-- @param #INTEL_DLINK self -- @param #INTEL_DLINK self
@@ -2384,15 +2384,15 @@ function INTEL_DLINK:New(Intels, Alias, Interval, Cachetime)
self.alias="SPECTRE" self.alias="SPECTRE"
end end
-- Cache time
self.cachetime = Cachetime or 300
-- Interval -- Interval
self.interval = Interval or 20 self.interval = Interval or 20
-- Set some string id for output to DCS.log file. -- Set some string id for output to DCS.log file.
self.lid=string.format("INTEL_DLINK %s | ", self.alias) self.lid=string.format("INTEL_DLINK %s | ", self.alias)
-- Cache time
self:SetDLinkCacheTime(Cachetime or 120)
-- Start State. -- Start State.
self:SetStartState("Stopped") self:SetStartState("Stopped")
@@ -2477,6 +2477,16 @@ function INTEL_DLINK:onafterStart(From, Event, To)
return self return self
end end
--- Function to set how long INTEL DLINK remembers contacts.
-- @param #INTEL_DLINK self
-- @param #number seconds Remember this many seconds. Defaults to 180.
-- @return #INTEL_DLINK self
function INTEL_DLINK:SetDLinkCacheTime(seconds)
self.cachetime = math.abs(seconds or 120)
self:I(self.lid.."Caching for "..self.cachetime.." seconds.")
return self
end
--- Function to collect data from the various #INTEL --- Function to collect data from the various #INTEL
-- @param #INTEL_DLINK self -- @param #INTEL_DLINK self
-- @param #string From The From state -- @param #string From The From state
+47 -3
View File
@@ -53,7 +53,7 @@ LEGION.RandomAssetScore=1
--- LEGION class version. --- LEGION class version.
-- @field #string version -- @field #string version
LEGION.version="0.5.0" LEGION.version="0.5.1"
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- ToDo list -- ToDo list
@@ -445,6 +445,21 @@ function LEGION:DelCohort(Cohort)
return self return self
end end
--- Remove specific asset from legion.
-- @param #LEGION self
-- @param Functional.Warehouse#WAREHOUSE.Assetitem Asset The asset.
-- @return #LEGION self
function LEGION:DelAsset(Asset)
if Asset.cohort then
Asset.cohort:DelAsset(Asset)
else
self:E(self.lid..string.format("ERROR: Asset has not cohort attached. Cannot remove it from legion!"))
end
return self
end
--- Relocate a cohort to another legion. --- Relocate a cohort to another legion.
-- Assets in stock are spawned and routed to the new legion. -- Assets in stock are spawned and routed to the new legion.
@@ -647,6 +662,15 @@ function LEGION:CheckMissionQueue()
if mission:IsNotOver() and mission:IsReadyToCancel() then if mission:IsNotOver() and mission:IsReadyToCancel() then
mission:Cancel() mission:Cancel()
end end
-- Housekeeping
local TNow = timer.getTime()
if mission:IsOver() and mission:IsNotRepeatable() and mission.DeletionTimstamp == nil then
mission.DeletionTimstamp = TNow
end
if mission.DeletionTimstamp ~= nil and TNow - mission.DeletionTimstamp > 1800 then
mission = nil
end
end end
-- Check that runway is operational and that carrier is not recovering. -- Check that runway is operational and that carrier is not recovering.
@@ -746,7 +770,7 @@ function LEGION:CheckMissionQueue()
-- Reduce number of reinforcements. -- Reduce number of reinforcements.
if reinforce then if reinforce then
mission.reinforce=mission.reinforce-#assets mission.reinforce=mission.reinforce-#assets
self:I(self.lid..string.format("Reinforced with N=%d Nreinforce=%d", #assets, mission.reinforce)) self:T(self.lid..string.format("Reinforced with N=%d Nreinforce=%d", #assets, mission.reinforce))
end end
return true return true
@@ -1644,6 +1668,9 @@ function LEGION:onafterAssetDead(From, Event, To, asset, request)
self.commander.chief.detectionset:RemoveGroupsByName({asset.spawngroupname}) self.commander.chief.detectionset:RemoveGroupsByName({asset.spawngroupname})
end end
-- Remove asset from cohort and legion.
self:DelAsset(asset)
-- Remove asset from mission is done via Mission:AssetDead() call from flightgroup onafterFlightDead function -- Remove asset from mission is done via Mission:AssetDead() call from flightgroup onafterFlightDead function
-- Remove asset from squadron same -- Remove asset from squadron same
end end
@@ -1805,6 +1832,7 @@ function LEGION:_CreateFlightGroup(asset)
--- ---
opsgroup=ARMYGROUP:New(asset.spawngroupname) opsgroup=ARMYGROUP:New(asset.spawngroupname)
opsgroup:SetValidateAndRepositionGroundUnits(self.ValidateAndRepositionGroundUnits)
elseif self:IsFleet() then elseif self:IsFleet() then
@@ -1827,6 +1855,9 @@ function LEGION:_CreateFlightGroup(asset)
-- Set home base. -- Set home base.
opsgroup.homebase=self.airbase opsgroup.homebase=self.airbase
-- Set destination base
opsgroup.destbase=self.airbase
-- Set home zone. -- Set home zone.
opsgroup.homezone=self.spawnzone opsgroup.homezone=self.spawnzone
@@ -2493,7 +2524,10 @@ function LEGION._GetCohorts(Legions, Cohorts, Operation, OpsQueue)
local legion=_legion --Ops.Legion#LEGION local legion=_legion --Ops.Legion#LEGION
-- Check that runway is operational. -- Check that runway is operational.
local Runway=legion:IsAirwing() and legion:IsRunwayOperational() or true local Runway=true
if legion:IsAirwing() then
Runway=legion:IsRunwayOperational() and legion.airbase and legion.airbase:GetCoalition() == legion:GetCoalition()
end
-- Legion has to be running. -- Legion has to be running.
if legion:IsRunning() and Runway then if legion:IsRunning() and Runway then
@@ -2619,6 +2653,8 @@ function LEGION._CohortCan(Cohort, MissionType, Categories, Attributes, Properti
local RangeMax = RangeMax or 0 local RangeMax = RangeMax or 0
local InRange=(RangeMax and math.max(RangeMax, Rmax) or Rmax) >= TargetDistance local InRange=(RangeMax and math.max(RangeMax, Rmax) or Rmax) >= TargetDistance
--env.info(string.format("Range TargetDist=%.1f Rmax=%.1f RangeMax=%.1f InRange=%s", TargetDistance, Rmax, RangeMax, tostring(InRange)))
return InRange return InRange
end end
@@ -2785,6 +2821,8 @@ function LEGION.RecruitCohortAssets(Cohorts, MissionTypeRecruit, MissionTypeOpt,
-- Check if cohort can do the mission. -- Check if cohort can do the mission.
local can=LEGION._CohortCan(cohort, MissionTypeRecruit, Categories, Attributes, Properties, WeaponTypes, TargetVec2, RangeMax, RefuelSystem, CargoWeight, MaxWeight) local can=LEGION._CohortCan(cohort, MissionTypeRecruit, Categories, Attributes, Properties, WeaponTypes, TargetVec2, RangeMax, RefuelSystem, CargoWeight, MaxWeight)
--env.info(string.format("RecruitCohortAssets %s Cohort=%s can=%s", MissionTypeRecruit, cohort:GetName(), tostring(can)))
-- Check OnDuty, capable, in range and refueling type (if TANKER). -- Check OnDuty, capable, in range and refueling type (if TANKER).
if can then if can then
@@ -2800,6 +2838,12 @@ function LEGION.RecruitCohortAssets(Cohorts, MissionTypeRecruit, MissionTypeOpt,
end end
-- Break if no assets could be found
if #Assets==0 then
--env.info(string.format("LEGION.RecruitCohortAssets: No assets could be recruited for mission type %s [Nmin=%s, Nmax=%s]", MissionTypeRecruit, tostring(NreqMin), tostring(NreqMax)))
return false, {}, {}
end
-- Now we have a long list with assets. -- Now we have a long list with assets.
LEGION._OptimizeAssetSelection(Assets, MissionTypeOpt, TargetVec2, false, TotalWeight) LEGION._OptimizeAssetSelection(Assets, MissionTypeOpt, TargetVec2, false, TotalWeight)

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