Compare commits

..

2165 Commits

Author SHA1 Message Date
Frank e76c26ff59 FLIGHTPLAN 2023-08-03 00:41:34 +02:00
Frank cb11de6f9c Navigation
- Added NavFix
2023-08-02 10:53:28 +02:00
Frank cdd78e5163 Update FlightPlan.lua 2023-08-01 00:25:08 +02:00
Frank a8da02774a Update FlightPlan.lua 2023-08-01 00:24:49 +02:00
Frank 04258a69c4 Navigation
- Init stuff
2023-07-31 21:58:01 +02:00
Frank 49882f03d9 Update FlightControl.lua 2023-07-26 16:05:15 +02:00
Frank a7857670d3 Merge branch 'develop' into FF/Ops 2023-07-22 10:16:40 +02:00
Frank c41b256775 Update SRS.lua 2023-07-22 10:16:31 +02:00
Applevangelist e2929a78c4 #AICSAR - correct code version 2023-07-19 16:06:44 +02:00
Applevangelist 15bf379cdc #AICSAR
* Added FSM Event "HeloOnDuty"
2023-07-19 09:56:27 +02:00
Applevangelist 8a8e40e810 #PLAYERTASK
* Refactored menubuilds to use new CLIENTMENU/CLIENTMENUCONTROLLER classes
2023-07-17 16:27:54 +02:00
Applevangelist 2c8adf58cb #CLIENTMENU
* Rewrite with a different data approach
2023-07-17 16:26:53 +02:00
Applevangelist bb579fff5b Merge remote-tracking branch 'origin/master' into develop 2023-07-16 11:28:24 +02:00
Applevangelist 6481f66e27 #MANTIS
* Added IDs for Current Hill Assets, keyword "CHM" for group names
2023-07-16 11:27:34 +02:00
Thomas 1ad538ea9f Commits from master (#1972)
* #SPAWN

* Update Spot.lua

Fix
2023-07-15 09:46:55 +02:00
Thomas 5954b8692f Update Spot.lua
Fix
2023-07-15 09:36:24 +02:00
Applevangelist f6fdecf892 Merge remote-tracking branch 'origin/master' 2023-07-13 16:15:11 +02:00
Applevangelist 53fb77b50d #SPAWN 2023-07-13 16:15:06 +02:00
Applevangelist 191f7a7377 Merge remote-tracking branch 'origin/master' into develop 2023-07-13 16:13:26 +02:00
Applevangelist 04a9dc3a8c #SPAWN
* Added method to init spawn position
2023-07-13 16:13:00 +02:00
Applevangelist 77d2804fce Merge remote-tracking branch 'origin/master' into develop 2023-07-12 17:55:07 +02:00
Applevangelist 10b9a32f29 #SPOT
* Fix for switching laser off and on again not follwing unit any more
2023-07-12 17:54:17 +02:00
Applevangelist 63ba50a83a #CLIENTMENUMANAGER Docu 2023-07-11 16:10:40 +02:00
Applevangelist fb8f804af2 # CLIENTMENU
* Initial release
2023-07-11 15:41:06 +02:00
Applevangelist ffbab7453c Merge remote-tracking branch 'origin/master' into develop 2023-07-07 15:15:09 +02:00
Applevangelist 40fa929eb0 * Added omissed DetectedItem.Name found by @Nocke 2023-07-07 15:14:33 +02:00
Applevangelist 10872918bb #AUFTRAG
* Added GROUNDESCORT from the DCS Task with same name
2023-07-03 17:29:06 +02:00
Applevangelist 8979097fd7 Merge remote-tracking branch 'origin/master' into develop 2023-07-03 17:06:47 +02:00
Applevangelist 71b2cc1ee5 #AMMOTRUCK
* Added TTL
2023-07-03 17:06:31 +02:00
Applevangelist 8c8ef19f01 #CONTROLLABLE
* Added TaskGroundEscort
2023-07-03 16:44:46 +02:00
Applevangelist 389d5c7e5b Merge remote-tracking branch 'origin/master' into develop 2023-07-01 13:17:19 +02:00
Applevangelist 1eaa3d309d #SCORING
* typo
2023-07-01 13:15:59 +02:00
Applevangelist 178005346d Merge remote-tracking branch 'origin/master' into develop 2023-07-01 13:12:54 +02:00
Applevangelist a52cd5612a Merge remote-tracking branch 'origin/master' 2023-07-01 13:12:29 +02:00
Applevangelist 041c21a883 Merge remote-tracking branch 'origin/master' into develop 2023-07-01 13:12:03 +02:00
Applevangelist e82ed762be Merge remote-tracking branch 'origin/master' 2023-07-01 13:11:46 +02:00
Applevangelist 0bb16ec827 #AIRBASE
* Fix for nil error in finding parking for a group

#MANTIS
* Added SAM type "SHORAD" as designator

#SCORING
* fix for non local problem

#UTILS
* fix for OneLineSerialize
2023-07-01 13:11:21 +02:00
Applevangelist fd946e971a #AWACS
* Bugfixes
2023-07-01 13:08:27 +02:00
Thomas 0dab316514 Point - BRAANATO (#1969) (#1970)
corrected Track to be direction of travel of bogey (self in this case)
2023-06-26 13:29:34 +02:00
Thomas a978420a67 Point - BRAANATO (#1969)
corrected Track to be direction of travel of bogey (self in this case)
2023-06-26 13:25:23 +02:00
Applevangelist 248228720e Merge remote-tracking branch 'origin/master' into develop 2023-06-24 14:04:32 +02:00
Applevangelist f59326bf10 #ATIS
* Fix for airbases which have no runways, e.g. Naqoura Syria
2023-06-24 14:03:43 +02:00
Applevangelist e9c1b6d268 Merge remote-tracking branch 'origin/master' into develop 2023-06-22 13:52:19 +02:00
Thomas 08be2d6e93 CTLD (#1967) (#1968)
* Added option for troops subcategories in menu
2023-06-22 13:49:21 +02:00
Thomas d937ab2679 CTLD (#1967)
* Added option for troops subcategories in menu
2023-06-22 13:46:11 +02:00
Applevangelist ac386d5ebe #AIRBOSS
* Bug fix
2023-06-22 09:34:02 +02:00
Frank 74c1e9d991 Merge branch 'develop' into FF/Ops 2023-06-21 22:00:14 +02:00
Frank 0e72717cdb OPSGROUP
Track
2023-06-21 22:00:04 +02:00
Applevangelist 1df525b9c5 #NAVY
* Min speed 4kn due to rudder effectiveness
2023-06-21 14:05:17 +02:00
Applevangelist cdbbad809a Merge remote-tracking branch 'origin/master' into develop 2023-06-21 10:43:40 +02:00
Applevangelist 7164e211f2 #AIRBASE
- Nicosia unused atm
2023-06-21 10:42:35 +02:00
Applevangelist 970275e96e #AIRBOSS
* Added adjustment degrees for wind speed
2023-06-21 10:25:00 +02:00
Applevangelist 5456cd04c3 #PLAYERTASKCONTROLLER
* Menu build lock
2023-06-18 13:29:07 +02:00
Applevangelist 1cdbe55cdd Merge remote-tracking branch 'origin/develop' into develop 2023-06-18 12:19:37 +02:00
Applevangelist 0577e5171b #AIRBOSS
* SRS: Remove lines starting with # from being spelled out
2023-06-18 12:19:28 +02:00
Frank 97376320f4 Merge pull request #1965 from ttrebuchon/tt/ops-auftrag-transport-attributes-and-properties
AUFTRAG Transport Attributes, Categories, and Properties Filters
2023-06-18 01:08:10 +02:00
ttrebuchon 9c1acc731a Make Attributes parameter documentation conform to other similar descriptions 2023-06-17 17:32:49 -04:00
ttrebuchon 92f81614ba Update/fix lua docs for new AUFTRAG transport fields 2023-06-17 17:09:50 -04:00
ttrebuchon 2a11c4c98a Rename AUFTRAG.transportCategories/etc to carrierCategories/etc 2023-06-17 17:07:56 -04:00
ttrebuchon e284773492 Move transport categories/etc to SetRequiredCarriers, to allow for specifying them without always needing to specify zones 2023-06-17 17:06:16 -04:00
ttrebuchon b3d46618c2 Missed 2 spots in Legion/Commander for transport filters. 2023-06-17 16:56:46 -04:00
ttrebuchon 4e36e2011f Add categories/attributes/properties filters for AUFTRAG transports 2023-06-17 15:35:11 -04:00
Applevangelist a3876c296e #AIRBOSS
* Added option to set Airboss voice for SRS etc
* Nicer read out of weather info and carrier info
2023-06-17 15:01:33 +02:00
Applevangelist c80213b4cf #AIRBOSS
* Initial SRS addition
2023-06-16 18:18:18 +02:00
Applevangelist bfe7bf1af5 Merge remote-tracking branch 'origin/master' into develop
# Conflicts:
#	Moose Development/Moose/Wrapper/Positionable.lua
#	Moose Development/Moose/Wrapper/Unit.lua
2023-06-16 11:11:37 +02:00
Applevangelist dae78d7ac1 #Positionable, Unit - remove pcall 2023-06-16 11:06:46 +02:00
Frank f28d92e865 Merge pull request #1963 from FlightControl-Master/FF/Ops
OPS
2023-06-15 19:15:34 +02:00
Frank bffb3e7778 OPS
UNIT and POSITIONABLE
- Removed pcall for GetVec3 and GetAmmo

CHIEF
- Deploy resources if zone is empty and owned by itself
2023-06-15 19:12:26 +02:00
Applevangelist d4c2de9dd1 Merge remote-tracking branch 'origin/develop' into develop 2023-06-15 14:52:09 +02:00
Applevangelist ab5425bd83 Merge remote-tracking branch 'origin/master' into develop 2023-06-15 14:52:02 +02:00
Applevangelist 254468c723 #NET
* Improvements
2023-06-15 14:51:36 +02:00
Applevangelist aec3eee3a5 #NET
* Slight improvements
2023-06-15 14:50:11 +02:00
Frank eec7e5f8d9 Merge branch 'develop' into FF/Ops 2023-06-15 01:25:10 +02:00
Frank a9b51cca93 Update Auftrag.lua 2023-06-15 01:24:59 +02:00
Frank 14ddba69b0 Merge pull request #1962 from ttrebuchon/tt/ops-chief-RecruitAssetsForZone-nmin-nmax-typo-fix
Fix typo (Nmax -> Nmin) in CHIEF:RecruitAssetsForZone
2023-06-15 00:39:45 +02:00
ttrebuchon a7806deb76 Recruit assets using resource Nmin and Nmax, rather than Nmax and Nmax. 2023-06-14 12:41:05 -04:00
Applevangelist 0cf35b664f Merge remote-tracking branch 'origin/master' into develop 2023-06-14 17:41:13 +02:00
Applevangelist 71be4d99d6 #POSITIONABLE:GetRelativeCoordinate( x, y, z ) 2023-06-14 17:40:33 +02:00
Frank c3ffffbb52 Merge branch 'master' into develop 2023-06-13 21:53:29 +02:00
Frank f86fc845e7 Update Timer.lua
- Timer stop is using protected call now because it can crash the whole script.
2023-06-13 21:53:19 +02:00
Frank d96a55d83c Merge pull request #1961 from ttrebuchon/tt/flightgroup-getparkingspot-ship-fix
FLIGHTGROUP:GetParkingSpot Carrier Issue Fix
2023-06-13 19:09:42 +02:00
ttrebuchon 83353d710d Use GetRelativeCoordinate in FLIGHTGROUP:GetParkingSpot 2023-06-13 13:04:24 -04:00
Frank 9a4c09d249 Merge branch 'master' into develop 2023-06-13 19:03:11 +02:00
Frank cc907b9c14 Update Unit.lua
- UNIT:IsAlive() fixed so it is consistent with GROUP:IsAlive()
2023-06-13 19:02:55 +02:00
ttrebuchon c825191556 Add POSITIONABLE:GetRelativeCoordinate 2023-06-13 12:54:38 -04:00
Applevangelist 27e85e921f Merge remote-tracking branch 'origin/develop' into develop 2023-06-13 18:00:18 +02:00
Applevangelist c120a48879 #UNIT
* Test to not return a stored DCS Object if the API doesn't think it's still there
2023-06-13 18:00:15 +02:00
Frank 4a03074571 Merge branch 'develop' of https://github.com/FlightControl-Master/MOOSE into develop 2023-06-13 16:02:00 +02:00
Frank 8855b117a8 Update OpsGroup.lua
- exists check for ammo and vec3
2023-06-13 16:01:47 +02:00
Applevangelist 2cedb5e996 Merge remote-tracking branch 'origin/master' into develop 2023-06-13 08:40:21 +02:00
Applevangelist 241b2beee1 * Makes calls for GetAmmo() and GetVec3() safer with pcall()
* Small docu fix Ben-Gurion
2023-06-13 08:39:56 +02:00
Frank 0af68cd780 Merge branch 'master' into develop 2023-06-12 23:01:36 +02:00
Frank 12f260e857 Update Unit.lua
- Added `UNIT:IsExist` function.
2023-06-12 23:01:19 +02:00
Thomas 6a58748cd1 Airbase (#1954)
* #UTILS
* Sinai TIme

* fix

* Update Airbase.lua

Corrected enumerator for Ben-Gurion (Ben_Gurion)

* Update Airbase.lua (#1957)

Deleted raj al … airbases #1955
2023-06-12 06:27:52 +02:00
Thomas 096d145cf9 Update Airbase.lua (#1957)
Deleted raj al … airbases #1955
2023-06-12 06:22:51 +02:00
Frank d31db1351a Merge pull request #1956 from FlightControl-Master/FF/Ops
AUFTRAG
2023-06-11 22:52:28 +02:00
Frank 0f33603ecc AUFTRAG
- Changed ingress waypoint of CASENHANCED
2023-06-11 22:45:59 +02:00
Thomas b3883301a2 Update Airbase.lua
Corrected enumerator for Ben-Gurion (Ben_Gurion)
2023-06-11 12:33:01 +02:00
Frank 3bbd55cfc2 Merge pull request #1953 from ttrebuchon/tt/fix-opsgroup-getlifepoints-typo
Set life0 based on itself, rather than off of life
2023-06-11 00:52:13 +02:00
ttrebuchon 163273096c Set life0 based on itself, rather than off of life 2023-06-10 18:08:29 -04:00
Applevangelist 3a7521c492 #UTILS
* Sinai TIme
2023-06-10 19:08:46 +02:00
Applevangelist caa5a96235 fix 2023-06-10 19:06:22 +02:00
Applevangelist cee1c592ba #UTILS
* Sinai TIme
2023-06-10 19:04:40 +02:00
Frank 6d1030925c Merge branch 'master' into develop 2023-06-10 10:08:35 +02:00
Frank f1fc9f0b27 Update Utils.lua
- Added parameters time zone and magvar for Sinai map
2023-06-10 10:08:22 +02:00
Applevangelist dabe8a58d1 Merge remote-tracking branch 'origin/develop' into develop 2023-06-09 15:16:41 +02:00
Applevangelist 16cf6693ab Merge remote-tracking branch 'origin/master' into develop 2023-06-09 15:16:38 +02:00
Applevangelist e9adcb0dd5 #AIRBASE
* Sinai airfield enumerator
2023-06-09 15:13:45 +02:00
Applevangelist fd51ec6932 #FIX 2023-06-09 13:25:29 +02:00
Frank 7a16a5dda8 Merge pull request #1952 from FlightControl-Master/FF/Ops
OPS
2023-06-08 19:55:30 +02:00
Frank 1b6648996c OPSGROUP
- Improved CAPTUREZONE for FLIGHTGROUP
2023-06-08 19:51:09 +02:00
Frank f45a22fe78 Merge branch 'develop' into FF/Ops 2023-06-08 15:52:25 +02:00
Applevangelist afe2b675e5 #RAT
* Fixes from dev
2023-06-08 13:59:59 +02:00
Applevangelist 2c14ee74b0 #SCORING
* Can leave text empty on some instances
2023-06-08 13:58:26 +02:00
Applevangelist 4314959cbb Merge remote-tracking branch 'origin/develop' into develop 2023-06-08 13:57:03 +02:00
Applevangelist fad85ef7ed #PLAYERTASK
* Added basic scoring
2023-06-08 13:56:59 +02:00
Frank 569b3df6af Merge branch 'master' into develop 2023-06-08 09:46:24 +02:00
Frank f351d2a37e Merge pull request #1951 from FlightControl-Master/FF/MasterDevel
Update RAT.lua
2023-06-08 09:45:49 +02:00
Frank 4cb0e70184 Update RAT.lua
- Fixed RATMANAGER spamming due to not accounting for planned/scheduled groups
2023-06-08 09:43:11 +02:00
Applevangelist 910da86caf Merge remote-tracking branch 'origin/develop' into develop 2023-06-07 17:25:49 +02:00
ttrebuchon 73ff2c576d Fix typo from TRANSPORT. to OPSTRANSPORT. (#1950) 2023-06-07 17:26:20 +02:00
Applevangelist d5ffb48548 #PLAYERTASK
* Fix for one tts output
2023-06-07 17:25:45 +02:00
Frank 8ce371f898 WAREHOUSE
- Runway destroyed event only triggered if it was operational
2023-06-07 09:03:01 +02:00
Thomas 6f02f23240 PlayerTask.lua (#1948)
Small fix for one tts text
2023-06-06 16:20:16 +02:00
ttrebuchon 0a1d469c68 Fix Offset values being saved to the ZONE_UNIT class itself (#1947) 2023-06-03 20:15:33 +02:00
Applevangelist 823f8fb4fb Merge remote-tracking branch 'origin/master' into develop 2023-06-03 12:35:05 +02:00
Applevangelist 41bb2551d3 #CTLD
* Ensure new menus can be build if player changes helos
2023-06-03 12:34:18 +02:00
Applevangelist f7e64bc9b5 #UNIT #CTLD
* Stabilize that sometimes a unit coordinate cannot be found
2023-06-02 08:45:35 +02:00
Applevangelist 55ed394782 #UNIT #CTLD
* Stabilize that sometimes a unit coordinate cannot be found
2023-06-02 08:44:14 +02:00
Applevangelist 261f79851c Merge remote-tracking branch 'origin/master' into develop 2023-06-01 10:03:34 +02:00
Applevangelist dd7a883a33 Fixes 2023-06-01 10:02:51 +02:00
Applevangelist 6773ac7841 #PLAYERTASK
* Added FSM event "Progress" that will be triggered if the targetcount goes down for a task, but is not yet zero. This will bubble up to PLAYERTASKCONTROLLER

#PLAYERTASKCONTROLLER
* Added FSM event"TaskProgess" (see above). The event function will recveive the PLAYERTASK and the current target count
* Changed the menu build strategy to ensure a lot less menu rebuilds. Menus are now only build if
	* A new player joins (for the joining single player)
	* On joining a task (for the joining single player)
	* When aborting a task (for the aborting single player)
	* On Task succes (for all players)
	* Removal of time based builds: The status loop will now only enforce the menu build if the task count in the queue is smaller than the menu item limit. This effectively enforces a time-based order of tasks, and newer, even higher prio task will not bubble into the task list of pilots automatically.
2023-05-30 12:06:03 +02:00
Applevangelist 39f29b066b Merge remote-tracking branch 'origin/master' into develop 2023-05-30 07:38:48 +02:00
Applevangelist f7acbc3928 #CSAR
* Corrected flare distance to kms
2023-05-30 07:38:19 +02:00
Applevangelist 246879c003 Merge remote-tracking branch 'origin/master' into develop 2023-05-28 15:28:37 +02:00
Applevangelist 2318578126 #SPAWN
* Logic fix for the last parameter of `NewFromTemplate()`
2023-05-28 15:27:34 +02:00
Frank 709621967d Merge pull request #1945 from FlightControl-Master/FF/Ops
OPSTRANSPORT
2023-05-27 14:38:30 +02:00
Frank 0c376aec63 OPSTRANSPORT
Fixed loaded not correctly checked in OPSGROUP
2023-05-27 14:28:53 +02:00
Frank 725efc3e70 Merge pull request #1944 from FlightControl-Master/FF/Ops
AUFTRAG
2023-05-26 11:42:26 +02:00
Frank 81abe422de Merge branch 'develop' into FF/Ops 2023-05-26 11:38:26 +02:00
Frank fb202012da AUFTRAG
Reinforcing
- improved check if reinforcing is still ongoing
- improved handling by commander/chief
- added check that assets are not added to a mission twice
2023-05-26 11:37:19 +02:00
Applevangelist 89223ae142 Merge remote-tracking branch 'origin/master' into develop 2023-05-26 08:28:45 +02:00
Applevangelist 3e6f25f17c #UTILS
* Added UTILS.PrintTableToLog()
2023-05-26 08:28:08 +02:00
Applevangelist 2967de8f6e #CONTROLLER
* Fix for Link4
2023-05-25 08:57:54 +02:00
Applevangelist 0cd6a59ce4 #CONTROLLER
* Fix for Link4
2023-05-25 08:57:15 +02:00
Applevangelist 9c5260f801 Merge remote-tracking branch 'origin/develop' into develop 2023-05-25 08:24:35 +02:00
Applevangelist 4d9ce80c98 Merge remote-tracking branch 'origin/master' into develop 2023-05-25 08:24:16 +02:00
Applevangelist 91a445961b #RESCUEHELO
* Small fix to get the coordinate of an ejected/crashed unit
2023-05-25 08:23:31 +02:00
Frank ee055531b6 Merge branch 'master' into develop 2023-05-24 11:16:36 +02:00
Frank 749e9b7e08 Update Event.lua
Fixed bug that statics are handled incorrectly if they are the target object of an event (*e.g.* hit event)
2023-05-24 11:16:01 +02:00
Frank c9b90e884d Merge pull request #1943 from FlightControl-Master/FF/Ops
OPS
2023-05-23 01:46:51 +02:00
Frank 21db80afad Merge branch 'develop' into FF/Ops 2023-05-23 01:29:04 +02:00
Frank d9d5458450 OPS
**AUFTRAG**
- New type `FAC`

**OPSZONE**
- Improved drawzone on capture
2023-05-23 01:28:52 +02:00
Applevangelist 0575b366dd #SPAWN
* Tweaked NewFromTemplate, and gave a better example
2023-05-22 17:57:50 +02:00
Applevangelist 905d29b279 #SPAWN
* Tweaked NewFromTemplate, and gave a better example
2023-05-22 17:57:03 +02:00
Applevangelist 034b2444ff Merge remote-tracking branch 'origin/master' into develop 2023-05-20 12:13:35 +02:00
Applevangelist 5f97299cb2 Small Fix 2023-05-20 12:12:18 +02:00
Applevangelist 7901d53d54 #POINT
* Added FindClosestStatic()
2023-05-19 17:13:17 +02:00
Applevangelist 60b75a4c8f #POINT
* Added FindClosestStatic()
2023-05-19 17:11:54 +02:00
Applevangelist 88f34e5bb0 Merge remote-tracking branch 'origin/master' into develop 2023-05-17 10:28:11 +02:00
Applevangelist 0868286f27 #WAREHOUSE
* Fixed one omission for SHIP transport types
2023-05-17 10:26:29 +02:00
Applevangelist 49f3e3fc2f Merge remote-tracking branch 'origin/develop' into develop 2023-05-17 09:41:32 +02:00
Applevangelist cae084a352 Merge remote-tracking branch 'origin/master' into develop 2023-05-17 09:41:27 +02:00
Applevangelist ffcc46cb2d #CTLD
* Changed VHF modulation to AM
* Added option to have a different sound file for UHF, in case you want to silent FC3 radios
* Thanks to Streakeagle
2023-05-17 09:34:54 +02:00
Frank 6d07f7c48c Merge branch 'develop' into FF/Ops 2023-05-13 23:36:36 +02:00
Frank 014fea5f10 Merge branch 'master' into develop 2023-05-13 23:36:12 +02:00
Frank 21bcd64c9d Update Controllable.lua
Corrected parameters for enroute tasks according to hoggit for
- CONTROLLABLE:EnRouteTaskFAC
- CONTROLLABLE:EnRouteTaskFAC_EngageGroup
2023-05-13 23:35:58 +02:00
Frank d07709a167 Update Auftrag.lua 2023-05-13 23:06:56 +02:00
Frank ac4db4a392 Merge branch 'develop' into FF/Ops 2023-05-13 17:57:23 +02:00
Applevangelist b30cdd073b Merge remote-tracking branch 'origin/master' into develop 2023-05-11 18:23:01 +02:00
Applevangelist 943b68f38f #CTLD
* placement of dropped crates to better align to unit length
2023-05-11 15:31:24 +02:00
Applevangelist a12e93c7cb Merge remote-tracking branch 'origin/master' into develop 2023-05-09 09:49:47 +02:00
Applevangelist bd01946f88 #AI_A2X...
* Fixes
2023-05-09 09:49:13 +02:00
Applevangelist 256b93087f #AI_A2X...
* Fixes
2023-05-09 09:48:21 +02:00
Applevangelist 7ed0d7eec3 #AI_A2X...
* Fixes
2023-05-09 09:44:41 +02:00
Applevangelist 8d25bdec7c Merge remote-tracking branch 'origin/master' into develop 2023-05-05 10:33:55 +02:00
Applevangelist 9b8154246f #COORDINATE
* Added `IsInSteepArea()`and `IsInFlatArea()`
2023-05-05 10:31:23 +02:00
Applevangelist 8da228c9a2 #COORDINATE
* Added `IsInSteepArea()`and `IsInFlatArea()`
2023-05-05 10:31:00 +02:00
Applevangelist 74abcce956 Merge remote-tracking branch 'origin/develop' into develop 2023-04-27 10:34:21 +02:00
Applevangelist 2032c2cfbf # AUFTRAG
* Bring options for afterburner usage down to AUFTRAG level

# OpsGroup (Flightgroup)
* Follow setting option for AB usage from mission, if set, generally and for execution phase of the AUFTRAG
2023-04-27 10:34:17 +02:00
Frank fb070a0c86 Merge branch 'develop' into FF/Ops 2023-04-25 21:54:04 +02:00
Frank 817c69bb11 Merge branch 'master' into develop 2023-04-25 21:53:39 +02:00
Frank c360759e49 Merge pull request #1939 from FlightControl-Master/FF/MasterDevel
Update Socket.lua
2023-04-25 21:42:53 +02:00
Frank d8b80aab1a Update Socket.lua
- Added `SOCKET:SendTextToSpeech()` function
2023-04-25 21:20:16 +02:00
Applevangelist 6cd56e4de4 Merge remote-tracking branch 'origin/master' into develop 2023-04-25 09:13:27 +02:00
Applevangelist b96ebc1872 #SCENERY
* Added update of Life0 value if `GetLife()`is called
#SET_SCENERY
* Added Documentation
2023-04-25 09:12:31 +02:00
Applevangelist 6896dc155a #SCENERY
* Added update of Life0 value if `GetLife()`is called
#SET_SCENERY
* Added Documentation
2023-04-25 09:12:25 +02:00
Applevangelist 19a4ec48bb Merge remote-tracking branch 'origin/master' into develop 2023-04-24 16:45:31 +02:00
Applevangelist 1060d63808 #SET_SCENERY
* Added functions to count Life0, Life and RelativeLife points of SET_SCENERY
2023-04-24 16:44:38 +02:00
Thomas c7d990850a AIRBASE - add Normandy AFBs (#1937) (#1938)
Add Normandy AFBs
2023-04-24 11:16:45 +02:00
Thomas 88b6540f5b AIRBASE - add Normandy AFBs (#1937)
Add Normandy AFBs
2023-04-24 11:09:03 +02:00
Frank 885d3b5228 Merge branch 'develop' into FF/Ops 2023-04-22 14:29:18 +02:00
Frank 7379b8135a Merge branch 'master' into develop 2023-04-22 14:08:05 +02:00
Frank 302e785f32 Merge pull request #1936 from FlightControl-Master/FF/MasterDevel
Remove Junk
2023-04-22 14:05:09 +02:00
Frank 1507cc0b42 Remove Junk
**ZONE**
- Added `ZONE_RADIUS:RemoveJunk()` function
- Added `ZONE_POLYGON_BASE:RemoveJunk()` function (not working)

**POSITIONABLE**
- Added `Explosion`
2023-04-22 14:02:18 +02:00
Applevangelist 240307ef94 #CTLD
* Docu changes
2023-04-20 08:23:03 +02:00
Applevangelist 549c9b9ce5 #CTLD
* Docu changes
2023-04-20 08:22:31 +02:00
Applevangelist f4080d93e8 #SET
- Minus one log entry
2023-04-20 08:06:57 +02:00
Applevangelist 90c74bd82c #SET
- Minus one log entry
2023-04-20 08:06:43 +02:00
Applevangelist 94b74b7056 Merge remote-tracking branch 'origin/develop' into develop 2023-04-20 08:05:15 +02:00
Applevangelist 6886107934 #SET
* Active Zone Filtering
2023-04-20 08:05:11 +02:00
Thomas 9414096de7 Added active ZONE filtering (#1935)
for groups, units, clients entering/leaving zones to be used with `FilterStart()`
2023-04-19 09:51:53 +02:00
Thomas f65783ed6c SET - added continous zone filtering (#1934)
SET - added continous zone filtering for SET_GROUP, SET_UNIT and SET_CLIENT. Adresses request #1933
2023-04-18 12:28:17 +02:00
Applevangelist d8e765a9b1 Fixes for getPlayerName() errors if DCS object is not a UNIT 2023-04-18 10:28:00 +02:00
Applevangelist 07c3be9d6a Fixes for getPlayername() errors 2023-04-18 10:24:56 +02:00
Frank 526f241dc3 Merge branch 'develop' into FF/Ops 2023-04-17 17:18:54 +02:00
Applevangelist dffb1c0768 Merge remote-tracking branch 'origin/master' into develop 2023-04-16 16:11:12 +02:00
Applevangelist 9869dbd95a #CTLD
* Include current group structure in load/save functions
2023-04-16 16:10:46 +02:00
Frank f30f32732c Merge branch 'master' into develop 2023-04-16 12:30:19 +02:00
Frank 49b702106a Update Weapon.lua
- Decreased min possible time step to 0.00001 seconds
2023-04-16 12:29:57 +02:00
Frank 9cd3027ea6 Update FlightGroup.lua 2023-04-16 11:16:54 +02:00
Applevangelist 8eb09beb96 Merge remote-tracking branch 'origin/master' 2023-04-15 16:19:46 +02:00
Applevangelist b402a99a25 #CTLD
* Small fix allowing minus signs in template names for repairs
2023-04-15 16:19:35 +02:00
Applevangelist b4c7b63381 #CTLD
* Small fix allowing minus signs in template names for repairs
2023-04-15 16:17:39 +02:00
Applevangelist ad8938cd74 #CTLD
* Small fix allowing minus signs in template names for repairs
2023-04-15 16:17:01 +02:00
Applevangelist 0782532763 Merge remote-tracking branch 'origin/master' into develop 2023-04-13 15:51:55 +02:00
Applevangelist ee409c45a0 #CTLD
* Allow save/loadback with precise(r) coordinates for vehicles and troops.
2023-04-13 15:51:21 +02:00
Applevangelist 9d5da3388d smaller docu item 2023-04-13 15:28:41 +02:00
Applevangelist 6fa9e5894e #DATABASE
* Small fix for CLIENT:FindByName()
2023-04-04 10:33:41 +02:00
Applevangelist 9e138aa149 #DATABASE
* Small fix for CLIENT:FindByName()
2023-04-04 10:33:04 +02:00
Applevangelist c0bc9b393c #NET
* Fix for ucid can be nil
2023-04-03 12:16:25 +02:00
Applevangelist cf94c4d043 #NET
* Fix for ucid can be nil
2023-04-03 12:15:29 +02:00
Applevangelist a97e844aca Added Init Methods to set Unit Positions on Spawn 2023-03-30 12:23:07 +02:00
Applevangelist 63b3807cf6 Added Init Methods to set Unit Positions on Spawn 2023-03-30 12:22:04 +02:00
Applevangelist d2e91ffcd2 Small fix for SET_UNIT if used in capture zone coalition with a polygon zone 2023-03-30 09:24:48 +02:00
Applevangelist f3b6b27521 Small fix for SET_UNIT if used in capture zone coalition with a polygon zone 2023-03-30 09:24:08 +02:00
Applevangelist d9eee7ea46 SET_STATIC - Added GetClosestStatic() 2023-03-28 11:03:34 +02:00
Applevangelist ff656182e8 SET_STATIC - Added GetClosestStatic() 2023-03-28 11:03:00 +02:00
Applevangelist b1e233421e Fix possible DCS Unit not existing in OPSGROUP:onafterElementDamaged(From, Event, To, Element) 2023-03-24 10:28:36 +01:00
Applevangelist 7157836eb1 Merge remote-tracking branch 'origin/master' into develop 2023-03-23 09:21:58 +01:00
Applevangelist a85ef6e769 Merge remote-tracking branch 'origin/master' 2023-03-23 09:21:46 +01:00
Applevangelist 0bb8c56ea9 Typo fix 2023-03-23 09:21:42 +01:00
Applevangelist 5f108aec23 Typo fix 2023-03-23 09:21:20 +01:00
Applevangelist bf6683f993 Merge remote-tracking branch 'origin/master' 2023-03-23 08:47:07 +01:00
Applevangelist b7a5e8dd85 Add'l check in UNIT:GetLife() 2023-03-23 08:47:04 +01:00
Applevangelist 53fa850d66 Add'l check in UNIT:GetLife() 2023-03-23 08:46:29 +01:00
Applevangelist 57294aeaf5 Add'l check in UNIT:GetLife() 2023-03-23 08:45:54 +01:00
Applevangelist 033c52ae54 Merge remote-tracking branch 'origin/develop' into develop 2023-03-16 08:45:17 +01:00
Applevangelist e08b44187e #AIRBASE
* Added/changed:
  ["Hipico_Flying_Club"] = "Hipico Flying Club",
  ["Aeropuerto_de_Gobernador_Gregores"] = "Aeropuerto de Gobernador Gregores",
  ["Aerodromo_O_Higgins"] = "Aerodromo O'Higgins",
  ["Cullen_Airport"] = "Cullen Airport",
  ["Gull_Point"] = "Gull Point",
2023-03-16 08:45:14 +01:00
Applevangelist 20bfb8b08f #AIRBASE
* Added/changed South Atlantic Map:
  ["Hipico_Flying_Club"] = "Hipico Flying Club",
  ["Aeropuerto_de_Gobernador_Gregores"] = "Aeropuerto de Gobernador Gregores",
  ["Aerodromo_O_Higgins"] = "Aerodromo O'Higgins",
  ["Cullen_Airport"] = "Cullen Airport",
  ["Gull_Point"] = "Gull Point",
2023-03-16 08:44:16 +01:00
Thomas 0d29c39724 Drop crates from herc as CTLD_Cargo (#1929) (#1930)
Adds option to drop crates from a herc via parachute drop as CTLD_Cargo that needs proper unpacking - can be picked up be a helo.

Co-authored-by: UglySkyfire <69476075+UglySkyfire@users.noreply.github.com>
2023-03-15 21:07:19 +01:00
UglySkyfire 5585a8992c Drop crates from herc as CTLD_Cargo (#1929)
Adds option to drop crates from a herc via parachute drop as CTLD_Cargo that needs proper unpacking - can be picked up be a helo.
2023-03-15 20:12:30 +01:00
Applevangelist 6946d8d185 Merge remote-tracking branch 'origin/master' into develop 2023-03-10 10:09:40 +01:00
Applevangelist d92a20050c #CTLD
* Added/completed add/get/set functions for stock
2023-03-10 10:09:08 +01:00
Applevangelist 6ac1d66aae #GROUP
* Fix for GetMaxHeight()
2023-03-09 08:49:53 +01:00
Applevangelist c9a91d0683 #GROUP
* Fix for GetMaxHeight()
2023-03-09 08:49:07 +01:00
Applevangelist a67bae4f0d #UTILS
* Added UTILS.PlotRacetrack courtesy of Buur!
2023-03-07 10:55:42 +01:00
Applevangelist 4e7c689f7a Merge branch 'master' into develop 2023-03-05 11:04:22 +01:00
Applevangelist ae6716ac01 #GROUP
* Callsign translation refactor
2023-03-05 11:03:26 +01:00
Anthony De Vellis f73ff10edb Refactored GROUP:GetCustomCallSign so that bespoke callsigns override parsing player name and playername overrides vanilla callsigns. Previously Bespoke callsigns would never be used if names contained # or |. If CallsignTranslations is unset, previous priority will be applied. (#1927) 2023-03-05 11:01:37 +01:00
Applevangelist 949e2f9ff3 #SPAWN
* clarified docu for SpawnScheduled()
* Added parameter to SpawnScheduled() for a delayed spawn
2023-02-28 08:00:43 +01:00
Applevangelist 34285b26ae #SPAWN
* clarified docu for SpawnScheduled()
* Added parameter to SpawnScheduled() for a delayed spawn
2023-02-28 08:00:06 +01:00
Thomas cb9ab26522 Update Enums.lua (#1925) 2023-02-26 19:06:45 +01:00
Thomas 5341e5faee Update Enums.lua 2023-02-26 19:03:33 +01:00
Frank 7aa4aaf371 Update Auftrag.lua
- Fixed wrong IAS to TAS convertion for orbit missions
2023-02-26 01:02:39 +01:00
Frank 901480d99c Merge branch 'FF/Ops' into develop 2023-02-24 23:29:32 +01:00
Frank 84dbda6f2b OPS
- Rm laser marker
2023-02-24 23:29:03 +01:00
Applevangelist 9d00ec0c25 Merge remote-tracking branch 'origin/master' into develop 2023-02-24 14:04:53 +01:00
Applevangelist 0d08d732a5 #AWACS - do not convert speed to IAS, as already done in AUFTRAG 2023-02-23 11:12:05 +01:00
Applevangelist a6224b484e dcs 2023-02-23 10:33:11 +01:00
Applevangelist 8c0f960e39 Merge remote-tracking branch 'origin/master' into develop 2023-02-23 10:32:38 +01:00
Applevangelist e95c1ad3aa #Fixes from dev 2023-02-23 10:30:59 +01:00
Frank b0978b362e Merge pull request #1924 from FlightControl-Master/FF/Ops
OPS
2023-02-22 23:18:29 +01:00
Frank ffef3183c7 OpsGroup
- Fixed bug in checklos
2023-02-22 23:01:47 +01:00
Frank 20a9857fcf Merge branch 'FF/OpsDev' into FF/Ops 2023-02-22 22:17:49 +01:00
Frank 828395c398 Merge branch 'develop' into FF/Ops 2023-02-22 22:17:35 +01:00
Frank 462e29da6e RANGE and OPS
** RANGE**
- Added scenery as target

**OPSGROUP**
- Added option that group does not return to its legion

**AUFTRAG**
- Added option that assets do not return to its legion
2023-02-22 22:16:42 +01:00
Applevangelist 29ebe94015 #CTLD logic correction for loading 2023-02-21 11:39:23 +01:00
Applevangelist 9cfed56847 #CTLD logic correction for loading 2023-02-21 11:38:40 +01:00
Applevangelist ce7b30b54e Merge remote-tracking branch 'origin/master' into develop 2023-02-19 17:16:34 +01:00
Applevangelist 6c1abddb1e #NET added a couple of functions 2023-02-19 17:16:00 +01:00
Applevangelist feeb0c01f2 Merge remote-tracking branch 'origin/master' into develop 2023-02-19 12:32:29 +01:00
Applevangelist 7dc239f506 Added CLIENT:FindByPlayerName(Name)
NET - slot blocker comments in log removed
2023-02-19 12:31:32 +01:00
Applevangelist bef8e53347 #AICSAR - added option to use eject event 2023-02-19 12:30:00 +01:00
Applevangelist 46c3ed72c3 Merge remote-tracking branch 'origin/master' into develop 2023-02-18 15:04:36 +01:00
Applevangelist 3e8413c6b7 #NET - further ado 2023-02-18 15:03:53 +01:00
Applevangelist 1fd8f4d837 #AICSAR
* Named functions for the events
2023-02-18 11:04:49 +01:00
Applevangelist 6f3fbb25cf Merge remote-tracking branch 'origin/master' into develop 2023-02-17 16:42:10 +01:00
Applevangelist ff86bfb91d #NET Event blocker fix 2023-02-17 16:41:38 +01:00
Applevangelist 05b8df0d88 Merge remote-tracking branch 'origin/master' into develop 2023-02-17 16:24:21 +01:00
Applevangelist 66494b7b5a NET 2023-02-17 16:23:02 +01:00
Applevangelist 973127aa8c #NET Fixes 2023-02-17 15:42:06 +01:00
Applevangelist a4dcb643bd #NET Fixes 2023-02-17 15:41:33 +01:00
Applevangelist 83866c3dd3 #NET Fixes 2023-02-17 15:02:11 +01:00
Applevangelist 9e23cda02a #NET Fixes 2023-02-17 15:01:49 +01:00
Applevangelist c29b67df55 #NET small fix 2023-02-17 14:33:32 +01:00
Applevangelist 4797abc287 #NET Bugfix 2023-02-17 14:32:48 +01:00
Applevangelist bd312b86d2 Merge remote-tracking branch 'origin/master' into develop 2023-02-17 13:23:10 +01:00
Applevangelist 50f73f1be2 #NET extended block to UCID 2023-02-17 13:22:10 +01:00
Applevangelist 822b95e8aa Merge remote-tracking branch 'origin/master' into develop 2023-02-17 08:55:27 +01:00
Applevangelist a7e45338e3 #AICSAR - Added alt/speed options 2023-02-17 08:54:54 +01:00
Applevangelist 2ebbc8f466 #NET - added docu 2023-02-17 08:54:15 +01:00
Applevangelist 7637f0c6ce Merge remote-tracking branch 'origin/develop' into develop 2023-02-16 18:22:10 +01:00
Applevangelist 6ec43b72ce #AICSAR
* Added PlayerName to `OnAfterPilotRescued(From,Event,To,PilotName)` if available
2023-02-16 18:22:06 +01:00
Frank 91e80bf1a6 Merge branch 'FF/Ops' into FF/OpsDev 2023-02-16 17:30:47 +01:00
Frank e6464dc5cb Merge branch 'develop' into FF/Ops 2023-02-16 17:30:15 +01:00
Frank 34c799b668 Merge branch 'master' into develop 2023-02-16 17:29:54 +01:00
Frank 1a96b30a45 Merge pull request #1922 from FlightControl-Master/FF/MasterDevel
Airspeed
2023-02-16 17:28:13 +01:00
Frank 3b1b57a33e Update Positionable.lua
- Added GetGroundSpeed
2023-02-16 17:20:53 +01:00
Frank f85c0320ec Airspeed
**POSITIONABLE**
- Added function `GetAirspeedIndicated` to return IAS
- Added function `GetAirspeedTrue` to return TAS

**UTILS**
- Added function `UTILS.IasToTas` to convert IAS to TAS
- Added function `TasToIas` to convert TAS to IAS.

**POINT**
- Added function `COORDINATE:GetWindVec3`
2023-02-16 17:09:12 +01:00
Applevangelist dbd7634f0e #NET
* Added event management for clients and block/unblock functions
2023-02-16 11:42:46 +01:00
Applevangelist bae7edb914 #NET
* Added event management for clients and block/unblock functions
2023-02-16 11:41:45 +01:00
Frank baa1dcbf8f OPSGROUP
- mission nothing is cancelled if transport is due
2023-02-15 23:06:34 +01:00
Applevangelist 660ebeadfe Merge remote-tracking branch 'origin/master' into develop 2023-02-15 12:24:09 +01:00
Applevangelist 35322399e9 #SPOT - minor fixes 2023-02-15 12:23:31 +01:00
Applevangelist ef0ddddb46 #PLAYERTASK
* added group/unit check for UseTypeNames
2023-02-15 10:32:30 +01:00
Applevangelist 5d4c0f3c87 Bugfix 2023-02-15 10:31:52 +01:00
Applevangelist 77a39364f4 #PLAYERTASKCONTROLLER
* Added ship detail types
2023-02-14 12:58:23 +01:00
Frank dc0a2bccd6 Update Legion.lua
- Increase score for nearby ground groups
2023-02-12 15:19:34 +01:00
Frank ac1b458eb4 Merge branch 'FF/Ops' into FF/OpsDev 2023-02-12 13:53:47 +01:00
Frank f5938bc235 Merge branch 'develop' into FF/Ops 2023-02-12 13:53:25 +01:00
Frank 7280c17506 Merge branch 'master' into develop 2023-02-12 13:04:32 +01:00
Frank 92c5c32e8c Merge pull request #1921 from FlightControl-Master/FF/MasterDevel
Update Range.lua
2023-02-12 13:03:08 +01:00
Frank c8780b2d5f Update Range.lua
- Coordinate of bomb target is now always updated (not only for moving targets)
- If the target is not alive any more, the last known position is used for its coordinate
2023-02-12 13:00:19 +01:00
Frank 4e280f02b6 Merge branch 'FF/Ops' into FF/OpsDev 2023-02-12 11:53:42 +01:00
Frank 854f6ae6ae Merge branch 'develop' into FF/Ops 2023-02-12 11:52:13 +01:00
Frank 0487487e7c Merge branch 'master' into develop 2023-02-12 11:51:16 +01:00
Frank f11dbfa367 Merge branch 'FF/MasterDevel' 2023-02-12 11:49:13 +01:00
Frank 54fb9deb3e Polygon and line drawings 2023-02-12 11:38:46 +01:00
Frank 9ec66912c8 Update OpsGroup.lua
- Added SetCargoBayLimit function
2023-02-12 09:36:35 +01:00
Thomas 960f261ddd Master merge (#1920)
* #NET
* Initial release

* Update MarkerOps_Base.lua (#1919)
2023-02-11 22:17:24 +01:00
Thomas d3c34ef04d Update MarkerOps_Base.lua (#1919) 2023-02-11 22:11:21 +01:00
Frank e55f96f393 OPSTRANSPORT 2023-02-11 00:21:15 +01:00
Applevangelist 713a5b067f #PLAYERTASKCONTROLLER
* Added `AddAgentSet()`
2023-02-10 11:40:15 +01:00
Applevangelist 3d5470eb22 #NET
* Initial release
2023-02-10 11:00:14 +01:00
Applevangelist d6aa7ec17c #Net
* Initial Release
2023-02-10 10:45:23 +01:00
Applevangelist 2da2ddb5bb #DETECTION
* Docu fixes
2023-02-09 16:12:39 +01:00
Applevangelist 2a3d69d0d5 #DETECTION
* Docu fixes
2023-02-09 16:11:45 +01:00
Applevangelist 608033f38f #AICSAR
* Docu additions
2023-02-09 13:17:49 +01:00
Applevangelist 28c25816a6 #AICSAR
* Fixed issue with underlying OpsTransport
* Added FSM Transition OnAfterPilotUnloaded()
* Added options for SRS TTS output - no sound files
* Added voice options for downed pilot and operator - these can have different voices
2023-02-09 11:57:28 +01:00
Frank 709fccd96c OSPTRANSPORT 2023-02-09 01:06:36 +01:00
Frank 2c24e56aa5 Merge branch 'FF/MasterDevel' into FF/OpsDev 2023-02-08 16:35:49 +01:00
Frank 9862c32378 Update settings.json 2023-02-08 16:30:44 +01:00
Frank 9f02232589 Update settings.json 2023-02-08 16:29:25 +01:00
Frank ffc86bf046 Unwanted changes 2023-02-08 16:28:04 +01:00
Frank f104ddbe64 Merge branch 'FF/Ops' into FF/OpsDev 2023-02-08 16:15:22 +01:00
Frank bbd8ceb8c0 Merge branch 'develop' into FF/Ops 2023-02-08 16:15:06 +01:00
Frank b8498fa58f Merge branch 'FF/MasterDevel' into FF/OpsDev 2023-02-08 16:14:45 +01:00
Frank e4c8ca34ed Update Pathline.lua 2023-02-08 16:11:47 +01:00
Frank f02b7036a9 PATHLINE 2023-02-08 12:37:18 +01:00
Frank 34c26c44bc Merge branch 'develop' into FF/OpsDev 2023-02-07 22:53:19 +01:00
Frank 6adef47340 PATHLINE
Added new class PATHLINE
2023-02-07 22:47:55 +01:00
Applevangelist c97f1791b0 Merge remote-tracking branch 'origin/master' into develop 2023-02-07 08:01:34 +01:00
Thomas 5b044cc036 Update CSAR.lua (#1917) 2023-02-07 07:28:00 +01:00
Applevangelist 63b16e5bd4 Merge remote-tracking branch 'origin/master' into develop 2023-02-06 08:17:05 +01:00
dogjutsu 184f93168b MSRS_BACKEND_DCSGRPC bug fix (#1916)
* Add another DCS-gRPC example for MSRS docu (ATIS)

* Fixes MSRS_BACKEND_DCSGRPC bad _GetLatLongAlt call
2023-02-06 08:16:14 +01:00
Mr.Alien 03ba7524b2 Comment out code for scoring hits (#1911) 2023-02-06 08:15:45 +01:00
Frank 0400f1a23e Merge branch 'FF/Ops' into FF/OpsDev 2023-02-05 00:23:42 +01:00
Frank d3d60757c1 Merge branch 'develop' into FF/Ops 2023-02-05 00:23:25 +01:00
Frank 57079e5104 Merge branch 'master' into develop 2023-02-04 23:34:14 +01:00
Frank 772921c6b8 WEAPON
- Added new class WEAPON
2023-02-04 23:31:55 +01:00
Frank 6d967358da WEAPON v0.1.0
**WEAPON**
- Improments of class
- ARTY works
- FOX works
- RANGE should work, not tested.
2023-02-04 23:28:45 +01:00
Mr.Alien d4d305d53b Fix confusing hit and kill messages with incorrect math (#1913) 2023-02-04 23:02:36 +01:00
Mr.Alien c58918e002 Add missing part of code in previous commit (#1910) 2023-02-04 22:36:16 +01:00
Mr.Alien dec7854476 Fix issue with getting thread level after a kill (#1908) 2023-02-04 22:01:55 +01:00
Applevangelist 095121d83c Merge remote-tracking branch 'origin/develop' into develop 2023-02-04 21:51:39 +01:00
Applevangelist a415b131c4 Merge remote-tracking branch 'origin/master' into develop 2023-02-04 21:51:35 +01:00
Thomas 54a1ea9f56 Scoring credits a kill to player who hit the same unit before it spawned (#1905) (#1907)
Co-authored-by: Mr.Alien <124381209+MrAlien753@users.noreply.github.com>
2023-02-04 21:50:17 +01:00
Mr.Alien 8ca102f584 Scoring credits a kill to player who hit the same unit before it spawned (#1905) 2023-02-04 21:46:34 +01:00
Applevangelist 23091ff851 #CTLD
* Added method `CTLD:PreloadCrates(Unit,Cratesname,NumberOfCrates)`
2023-02-04 17:21:52 +01:00
Applevangelist 4748c66d9c #CTLD
* Added method `CTLD:PreloadCrates(Unit,Cratesname,NumberOfCrates)`
2023-02-04 17:21:16 +01:00
Applevangelist 5571b49b4f Merge remote-tracking branch 'origin/master' into develop 2023-02-04 17:16:10 +01:00
Frank bf486b9f44 Merge pull request #1901 from MrAlien753/patch-1
fix nil error message in dcs.log
2023-02-03 22:34:01 +01:00
MrAlien753 6ff433ed7a fix nil error message in dcs.log
When instant killing a target in a capture zone nil error message is printed in the dcs.log. This fixes this issue.
2023-02-03 22:14:14 +01:00
Frank 4b4708e2a8 Weapon 2023-02-02 23:50:00 +01:00
Applevangelist 789a4c4b7f Merge remote-tracking branch 'origin/develop' into develop 2023-02-02 09:47:29 +01:00
Applevangelist 3775053609 PLAYERRECCE - bug fix 2023-02-02 09:47:25 +01:00
Applevangelist 35da50b67a Merge remote-tracking branch 'origin/develop' into develop-2 2023-02-02 09:38:32 +01:00
Applevangelist 9be30338a5 Herc fix 2023-02-02 09:37:47 +01:00
Applevangelist 6510cca837 Merge remote-tracking branch 'origin/develop' into develop 2023-02-02 09:36:48 +01:00
Applevangelist 08b8dfbe0e Merge remote-tracking branch 'origin/master' into develop 2023-02-02 09:36:44 +01:00
Applevangelist f9aa392c6d #CTLD_HERCULES
* Fixed an issue spawning 90 paratroopers instead of 30
2023-02-02 09:35:53 +01:00
Frank 9af242854a Weapon 2023-02-01 23:51:47 +01:00
Frank bfe9a1888e Merge pull request #1899 from ttrebuchon/tt/airwing-sortpayloads-fix
Airwing sortpayloads criteria fix
2023-02-01 19:07:46 +01:00
ttrebuchon fec496f154 Fix missing check for b.unlimited~=true in sortpayloads function. 2023-02-01 12:30:52 -05:00
Thomas 28fd35ad7e PlayerRecce - Added Shark_3 as type 2023-02-01 12:17:54 +01:00
Frank c5deb09c2c WEAPON v0.0.1
- New class
2023-01-31 23:22:48 +01:00
Applevangelist ee6d34a9bd #CTLD
* Added Subcategories for static cargo objects
2023-01-31 11:28:00 +01:00
Applevangelist 48721859fa #CTLD
* Added Subcategories for static cargo objects
2023-01-31 11:27:12 +01:00
Frank 6e6bb1e88d RANGE 2023-01-30 23:29:03 +01:00
Frank 0b3aea2bf3 Scenery 2023-01-30 21:52:22 +01:00
Applevangelist f731ec7b2f #POINT
* Added COORDINATE:SetAtLandheight()
2023-01-30 18:01:04 +01:00
Applevangelist ee59d999f5 #POINT
* Added COORDINATE:SetAtLandheight()
2023-01-30 18:00:16 +01:00
Applevangelist 5b8f840d6e Merge remote-tracking branch 'origin/master' into develop 2023-01-29 18:37:19 +01:00
Applevangelist 2f4f98cfe0 #CTLD - nobuildmenu option 2023-01-29 18:36:44 +01:00
Frank 694ad5d33d Merge branch 'develop' into FF/Ops 2023-01-29 12:57:09 +01:00
Frank 383ee00e71 Merge branch 'master' into develop 2023-01-29 12:54:13 +01:00
Frank ac1f202c19 Update Airboss.lua
- Added CJS Superhornet Mod
2023-01-29 12:53:50 +01:00
Frank c279ab6311 Update Auftrag.lua 2023-01-29 12:19:04 +01:00
Frank 4cc1db1365 Update Auftrag.lua
- condition success and failure evaluation
2023-01-28 22:31:53 +01:00
Frank f3d1378692 Merge branch 'master' into develop 2023-01-28 18:42:57 +01:00
Frank 3f97ba3bd7 Database
- Polygon drawings are registered as polygon zones
2023-01-28 18:42:29 +01:00
Frank 819912cfd3 Database
- Polygon drawings are adde as polygon zones to DB
2023-01-28 15:39:42 +01:00
Frank 50ee1ae922 Merge branch 'master' into FF/MasterDevel 2023-01-28 11:09:08 +01:00
Frank cfb3004142 Merge pull request #1893 from FlightControl-Master/FF/Ops
OPS
2023-01-28 10:47:49 +01:00
Thomas 016643e494 Merge from. Master (#1892)
* #CSAR - Add Persistence (#1889)

* Adds a modified version of ops.CTLD's Persistence to ops.CSAR

* Update Marker.lua

* Changed documentation for Marker.lua and MarkerOps_Base.lua (#1891)

---------

Co-authored-by: Jason du Plessis <33880363+TheChosenOn3@users.noreply.github.com>
Co-authored-by: grandpaSam <wouldyukindly@gmail.com>
2023-01-28 09:05:23 +01:00
grandpaSam c0442fca68 Changed documentation for Marker.lua and MarkerOps_Base.lua (#1891) 2023-01-28 09:02:15 +01:00
Thomas 5ec18d45a2 Merge (#1890)
* #CSAR - Add Persistence (#1889)

* Adds a modified version of ops.CTLD's Persistence to ops.CSAR

* Update Marker.lua

---------

Co-authored-by: Jason du Plessis <33880363+TheChosenOn3@users.noreply.github.com>
2023-01-27 18:36:38 +01:00
Thomas c20927b6d7 Update Marker.lua 2023-01-27 18:34:53 +01:00
Jason du Plessis 0d5b6d4c3e #CSAR - Add Persistence (#1889)
* Adds a modified version of ops.CTLD's Persistence to ops.CSAR
2023-01-26 21:11:15 +01:00
dogjutsu f4c9bced45 Add another DCS-gRPC example for MSRS docu (ATIS) (#1883) 2023-01-26 11:25:01 +01:00
Applevangelist e106ca3da5 * AIRBASE added airfields Falklands
* RANGE  added google key usage
2023-01-25 17:55:34 +01:00
Applevangelist bdc08a530d #AB 2023-01-25 17:54:13 +01:00
Applevangelist 6ab1632b4b #RANGE
* Set Google Key if given

#AIRBASE
* Added 3 Falklands AB to the enumerator
2023-01-25 17:53:29 +01:00
Applevangelist 262c8ffc59 Merge remote-tracking branch 'origin/develop' into develop 2023-01-25 17:19:03 +01:00
Applevangelist affde2f030 Merge remote-tracking branch 'origin/master' into develop 2023-01-25 17:18:59 +01:00
Thomas cec865b9fb UTILS - exclude 243 MHz and 121.5 MHz 2023-01-25 13:37:56 +01:00
Thomas a4982bd24e Update Utils.lua (#1886) (#1887) 2023-01-24 20:58:24 +01:00
Thomas d763e924a9 Update Utils.lua (#1886) 2023-01-24 20:16:46 +01:00
Applevangelist 1099e8e876 #CTLD added documentation 2023-01-24 15:27:09 +01:00
Applevangelist 57a30621e1 #CTLD added documentation 2023-01-24 15:26:32 +01:00
Applevangelist 6a4356fa94 #1885
#PSEUDOATC - Menu shows Waypoint name if it has been set
2023-01-24 10:06:40 +01:00
Applevangelist f344084791 #1885
#PSEUDOATC - Menu shows Waypoint name if it has been set
2023-01-24 10:06:05 +01:00
Applevangelist 2ec8d94e38 #CONTROLLABLE
* Added CommandActivateACLS()
* Added CommandDeactivateACLS()
2023-01-23 17:12:01 +01:00
Applevangelist be68314c3a #CONTROLLABLE
* Added CommandActivateACLS()
* Added CommandDeactivateACLS()
2023-01-23 17:11:18 +01:00
Applevangelist 24d47ef353 Merge remote-tracking branch 'origin/master' into develop 2023-01-22 13:11:13 +01:00
Applevangelist 53cff8229b #CTLD
* Added option movecratesbeforebuild
* Added option surfacetypes for build-in reloads
* Inject function can optionally take surfacetypes
* Inject function can use the center of the zone instead of a random position

#EVENT
* Handle landing event if the place is a SCENERY object (helopad on a map, but not an airbase)

#ZONE
* docu corrections
2023-01-22 13:10:27 +01:00
Frank 76ebf8df07 Merge branch 'develop' into FF/Ops 2023-01-21 22:43:11 +01:00
Frank a4e52c6c3c Legion
- Added enroute task SEAD to escort
2023-01-21 22:42:57 +01:00
Applevangelist 285f8d102b #AUFTRAG
* Added checking of bespoke conditions within the status call of AUFTRAG and not only when AUFTRAG is done already
2023-01-21 15:39:44 +01:00
Frank d0d21a6b5d Merge branch 'master' into develop 2023-01-19 19:11:09 +01:00
Frank 1d52e27668 Update Controllable.lua
- Added enroute task SEAD
2023-01-19 19:10:56 +01:00
Applevangelist ff58a47244 #FG - added nil check on GetClosestAirbase() 2023-01-19 17:01:59 +01:00
Applevangelist 6e666b0ac8 #UTILS - make LoadSetOfGroups save(r) for groups spawned with SpawnScheduled 2023-01-19 15:00:49 +01:00
Applevangelist 6ec867196c #UTILS - make LoadSetOfGroups save(r) for groups spawned with SpawnScheduled 2023-01-19 14:59:54 +01:00
Applevangelist 47684e8717 Merge remote-tracking branch 'origin/master' into develop 2023-01-19 10:35:02 +01:00
Applevangelist 0d0292385f #OPSGROUP - added docu 2023-01-19 10:33:26 +01:00
Applevangelist 83e20f8062 #Controllable - docu changes 2023-01-17 12:09:23 +01:00
Applevangelist 80798f278c #Controllable - docu changes 2023-01-17 12:09:13 +01:00
Applevangelist 4e61bbb92e Merge remote-tracking branch 'origin/master' 2023-01-17 09:26:16 +01:00
Applevangelist 5943ae0a46 #ATIS docu fix 2023-01-17 09:25:58 +01:00
Applevangelist fabab9bfbb #ATIS docu fix 2023-01-17 09:25:01 +01:00
Applevangelist 4ae0089e4f #CSAR
* Docu corrections
2023-01-15 17:40:03 +01:00
Applevangelist 56c4a11626 #CSAR
* Docu corrections
2023-01-15 17:39:28 +01:00
Applevangelist d82bce79c9 #CSAR
* Docu corrections
2023-01-15 17:38:54 +01:00
Applevangelist f0f42df374 #CTLD - Adde Shark III typename 2023-01-12 13:20:44 +01:00
Applevangelist 55fcaf1c05 #CTLD - Adde Shark III typename 2023-01-12 13:20:12 +01:00
Applevangelist 5898bc7f07 #PLAYERTASK
* Even nicer MGRS readouts
2023-01-10 17:09:17 +01:00
Applevangelist 0d8b94c7fd #AIRBASE - docu fixes 2023-01-10 13:09:25 +01:00
Applevangelist e83df502ed #AIRBASE - docu fixes 2023-01-10 13:08:05 +01:00
Applevangelist 0fa4be7c4a #AWACS
* Fixed initial screen text on bogey dope just being x group(s)
#PLAYERTASK
* Improved logic to declare task succes even if not player is assigned
2023-01-10 12:45:17 +01:00
Applevangelist a7bad8e9f4 #PSEUDOATC
* Fix for debug messages
2023-01-10 07:49:02 +01:00
Applevangelist 6501e89fa2 #PSEUDOATC
* Fix for debug messages
2023-01-10 07:47:56 +01:00
Frank 40276d190a Merge pull request #1882 from FlightControl-Master/FF/Ops
OPSZONE
2023-01-09 23:12:49 +01:00
Frank 71ccd23953 Merge branch 'develop' into FF/Ops 2023-01-09 23:03:12 +01:00
Frank 4e68e33ec7 Update OpsZone.lua
- Remove marker
2023-01-09 23:03:01 +01:00
Applevangelist 79c8b31042 #GROUP
* Improve functionality of GetUnit(x)
* Added GetFirstUnit()
2023-01-09 17:08:48 +01:00
Applevangelist 91801d441f #GROUP
* Improve functionality of GetUnit(x)
* Added GetFirstUnit()
2023-01-09 17:07:21 +01:00
Frank cee72c1d09 Merge branch 'master' into develop 2023-01-08 19:32:50 +01:00
Frank dd2a4ee7ff COORDINATE
- Added `GetMagneticDeclination` function
2023-01-08 19:32:38 +01:00
Applevangelist a7c8954740 Docu typo 2023-01-08 18:38:12 +01:00
Applevangelist a21b9b382e Merge remote-tracking branch 'origin/develop' into develop 2023-01-08 18:09:26 +01:00
Applevangelist ef0b76a632 #PLAYERTASK
* Added FSM events PlayerJoinedTask and PlayerAbortedTask
2023-01-08 18:09:22 +01:00
Mike 2806d3a191 Merge pull request #1880 from dogjutsu/dogjutsu/MSRS-gRPC-docs-cleanup
Doc fixes related to MSRS w/ DCS-gRPC alt backend
2023-01-08 16:41:38 +00:00
dogjutsu 9688c7ef01 Doc fixes related to MSRS w/ DCS-gRPC alt backend 2023-01-08 08:34:52 -08:00
dogjutsu d6181d26f8 Add DCS-gRPC TTS altnerate backend for MSRS (#1879) 2023-01-08 08:37:11 +01:00
Frank aa5e8662ed Merge pull request #1877 from FlightControl-Master/FF/Ops
OPSGROUP
2023-01-07 17:19:34 +01:00
Frank ca11e724ab Merge branch 'develop' into FF/Ops 2023-01-07 17:12:04 +01:00
Frank ab272da46e FLIGHTGROUP
- Increased dealy before Route to base to 1.0 sec. Previous delay of 0.1 sec was apparently too short for the stop flag to take effect and the task was not called done. Hence the mission was also not done.
2023-01-07 17:04:34 +01:00
Frank 584e932769 ARMYGROUP
- No retreat on out-of-ammo if rearming mission is in the queue
2023-01-07 10:53:46 +01:00
Applevangelist 691a500381 Merge remote-tracking branch 'origin/master' into develop 2023-01-05 11:00:06 +01:00
Applevangelist 8cedd88ce2 #SCENERY - explain destroy doesn't work 2023-01-05 10:58:40 +01:00
Applevangelist 21a2df0830 Merge remote-tracking branch 'origin/master' into develop 2023-01-05 10:49:13 +01:00
Applevangelist c3fde2b698 Merge remote-tracking branch 'origin/master' 2023-01-05 10:48:55 +01:00
Applevangelist 59e8aed445 #CSAR fix for beacons 2023-01-05 10:48:50 +01:00
Applevangelist e47b8f377c #CTLD/CSAR
* Small fix for
2023-01-05 10:45:37 +01:00
Thomas 4773a83a24 AWACS -correct error in SetAwacsDetails (#1873)
Corrected setting of Angels
2023-01-04 09:21:00 +01:00
Frank 09e9377e54 Merge pull request #1872 from FlightControl-Master/FF/Ops
OPS
2023-01-03 22:13:28 +01:00
Frank 19a90b7d9d Merge branch 'develop' into FF/Ops 2023-01-03 22:10:09 +01:00
Frank dbaed1e97b OPS
**CHIEF**
- Fixed bugs of polygon opszones
- Added option to use CAPTUREZONE auftrag for opszones

**OPSZONE**
- Fixed bug when marker off

**ZONE_POLYGON_BASE**
- Added `GetRadius()` function

**LEGION**
- Improved Reinforcement
2023-01-03 22:09:56 +01:00
Applevangelist 9695789843 #FG
* make us AB the default
2023-01-03 10:33:51 +01:00
Applevangelist 75ddd2e1e0 Merge remote-tracking branch 'origin/master' into develop 2023-01-03 10:23:34 +01:00
Applevangelist 793c0d988e Changes from dev 2023-01-03 10:22:10 +01:00
Applevangelist 43c81afd12 Merge remote-tracking branch 'origin/master' into develop 2023-01-03 10:17:48 +01:00
Applevangelist 88a837b769 #FlightGroup
* Added options to allow afterburner, jettison of empty tanks and jettison of weapons
2023-01-03 10:15:35 +01:00
Applevangelist b0eef34146 #CONTROLLABLE
* Docu fix

#WAREHOUSE
* Changes from dev

#ZONE
* Additions to ZONE_POLYGON
2023-01-03 10:15:16 +01:00
Applevangelist 55656761d2 #FIXES 2023-01-02 17:28:20 +01:00
Applevangelist 3fbfb8b528 #UNIT
* Fix #1865
2023-01-02 17:27:01 +01:00
Thomas cdd240abb7 PseudoATC - Option to display playername (#1870)
Use `myatc:SetReportPlayername()` to switch this on #1864
2023-01-02 14:28:35 +01:00
Frank 92710f4625 Merge pull request #1866 from FlightControl-Master/FF/Ops
Zones
2023-01-02 12:08:37 +01:00
Frank 58dc353bcd ZONE 2023-01-02 11:54:05 +01:00
Frank b194985827 Merge branch 'develop' into FF/Ops 2023-01-01 20:10:28 +01:00
Frank bdd283956c AUFTRAG CAP
- Fixed mission speed (unit conversion)
2023-01-01 20:07:14 +01:00
Frank a9b0017c04 OPS
request
2023-01-01 20:01:36 +01:00
Applevangelist 8f185d1291 #TIMER
* Added `StartIf()`
2023-01-01 12:34:32 +01:00
Applevangelist 5d802f0e16 #TIMER
* Added `StartIf()`
2023-01-01 12:34:02 +01:00
Frank 9564d9d893 Merge pull request #1861 from FlightControl-Master/FF/Ops
Update FlightGroup.lua
2023-01-01 09:30:15 +01:00
Frank fe01c6196e Update FlightGroup.lua
- fixed bug that mission does not exist
2023-01-01 09:27:05 +01:00
Frank c8d9377dbb Merge pull request #1860 from FlightControl-Master/FF/Ops
OPS
2023-01-01 01:08:59 +01:00
Frank d53f01232d OPS 2023-01-01 01:06:02 +01:00
Applevangelist e3f9a27f87 # FF changes from today 2022-12-31 18:07:35 +01:00
Applevangelist e25b9155b4 Merge remote-tracking branch 'origin/develop' into develop 2022-12-31 18:02:35 +01:00
Applevangelist b769568df1 #FG - let planes not limp around 2022-12-31 18:02:15 +01:00
Thomas daa60ac501 Update Auftrag.lua 2022-12-31 18:01:28 +01:00
Applevangelist 0340d17ab8 #PLAYERTASKCONTROLLER
* honing the menu build a bit
2022-12-31 15:56:01 +01:00
Frank c33f637717 Merge pull request #1859 from FlightControl-Master/FF/Ops
OPS
2022-12-31 12:42:02 +01:00
Frank 334af52ddf Merge branch 'develop' into FF/Ops 2022-12-31 12:35:59 +01:00
Frank 9a949c02c5 OPS
- Fixed bug task for recoverytanker mission
- Improved capturezone auftrag
2022-12-31 12:35:48 +01:00
Applevangelist 095c36b3ba #AWACS
* Block Helos from getting CAP assignments
2022-12-31 12:24:49 +01:00
Frank ff7ebb4f92 Merge pull request #1858 from FlightControl-Master/FF/Ops
OPS Capture Zone
2022-12-30 22:30:57 +01:00
Frank 3834991e6a Merge branch 'develop' into FF/Ops 2022-12-30 22:08:41 +01:00
Frank 67af073b95 OPS
Capture
2022-12-30 22:08:27 +01:00
Applevangelist 5a44948050 #FLIGHTGROUP
* Make one is local
2022-12-30 17:40:10 +01:00
Frank 3011d625b2 OPS
Capture Zone
2022-12-30 02:44:16 +01:00
Applevangelist d25efe2293 #ATIS
* Make SRS say TACAN and FARP and not spell the single characters
2022-12-29 16:34:11 +01:00
Applevangelist 8202791518 #AWACS
* Added option for helos to sign-in

#ATIS
* Make SRS say TACAN and FARP and not spell the single characters
2022-12-29 16:33:43 +01:00
Applevangelist 8661d07e1e #ATIS
* Make SRS say TACAN and FARP and not spell the single characters
2022-12-29 16:33:13 +01:00
Applevangelist 9871bf82d3 #UTILS
* Load/Save Improvements
2022-12-28 15:48:46 +01:00
Thomas 41eec658e0 UTILS - Update Load/Save Groups and Statics (#1857)
Addresses #1855 and #1856 

Added options to save groups in a structrued manner, allowing to despawn specific unit-types on a reload. Optionally, cinematic effects like smoke and fires can be put in place of despawned units. For statics, an option to replace them with dead statics has been added, and also cinematic effects.
2022-12-28 15:40:40 +01:00
Applevangelist f9c1d62173 #ATIS
* FARP support
2022-12-25 14:20:25 +01:00
Thomas 9facf07955 ATIS - added basic FARP support (#1854)
ATIS - added basic FARP support, only works with SRS
2022-12-25 14:18:53 +01:00
Applevangelist 89d854f5be #EVENT
* Small fix for hit event on coordinates
2022-12-24 12:04:08 +01:00
Applevangelist cd4844d26c #EVENT
* Small fix for hit event on coordinates
2022-12-24 12:03:04 +01:00
phr0gz f1e0bacadb CAPGROUP (#1853)
Fix help typo
2022-12-23 13:44:38 +01:00
Applevangelist 1b0131bd9d Merge remote-tracking branch 'origin/master' into develop 2022-12-23 13:43:43 +01:00
Applevangelist 9619b11c58 #CTLD
* add sound folder path option
2022-12-23 13:42:14 +01:00
Thomas 535060153a CTLD #1851 Add variable for a sound path (#1852)
CTLD #1851 Add variable for a sound path - defaults to  `self.RadioPath = "l10n/DEFAULT/"`
2022-12-23 13:39:00 +01:00
Applevangelist 2f6cd20cbd Merge remote-tracking branch 'origin/master' into develop 2022-12-21 14:12:23 +01:00
Applevangelist f26ff52712 #UNIT
* Docu fix
2022-12-21 14:09:47 +01:00
Applevangelist d66d99a24e #CTLD
* Added option to inject troops into helo cargo
2022-12-21 14:07:21 +01:00
Applevangelist 4a299ea53f #CTLD
* Added option to inject troops into helos
2022-12-21 14:05:58 +01:00
Applevangelist 9e823f12c2 #SET_SCENERY
* Added GetAliveSet
2022-12-21 12:55:38 +01:00
Applevangelist 6f0ba337c4 #SET_SCENERY
* Added GetAliveSet()
2022-12-21 12:55:01 +01:00
Applevangelist ef5ea01bc1 #TARGET
* Fixes for Scenery and Static Objects
2022-12-21 12:53:08 +01:00
Frank 30e6542887 OPS 2022-12-20 23:51:18 +01:00
Applevangelist b501eec306 #AUFTRAG
* Fix Orbit w&w/o racetrack
2022-12-20 18:18:24 +01:00
Applevangelist 79e99dcb38 #PLAYERTASK
* Added `GetTarget()`
2022-12-20 16:05:50 +01:00
Applevangelist f6eccba966 #SET_UNIT - docu fixes
#UNIT - Improved GetGroup() as after the Dec/22 patch getGroup() might be nil
2022-12-19 16:14:41 +01:00
Applevangelist 8df6e2dd57 #UNIT
* Improve GetGroup() as after Dec/22 patch geGroup() might be nil
# SET_UNIT
* Improved Docu
2022-12-19 16:12:09 +01:00
Applevangelist fa1f67420d #CTLD
* Fix to also save crates which have not been moved
2022-12-19 14:05:21 +01:00
Applevangelist 5010cdff71 #CTLD
* Fix to also save crates which have not been moved
2022-12-19 14:04:30 +01:00
Applevangelist 6e26e7eac3 #AUFTRAG
* Fix for orbit racetrack missing coordinate object
2022-12-19 13:08:35 +01:00
Applevangelist 0a04ff4f3c #AIRBASE
* Added Rio Chico
2022-12-16 18:45:21 +01:00
Applevangelist fea1839c06 #AIRBASE
* Added Rio Chico Airfield
2022-12-16 18:43:50 +01:00
Applevangelist 99023a3053 #UTILS
* UTILS.LoadSetOfStatics(Path,Filename) ignore statics which do not exist
2022-12-15 18:29:46 +01:00
Applevangelist 80e3b157ca #UTILS
* UTILS.LoadSetOfStatics(Path,Filename) ignore statics which do not exist
2022-12-15 18:28:06 +01:00
Applevangelist a3fd583d9d #PLAYERTASK
* additions for multiple setups
2022-12-15 11:50:05 +01:00
Applevangelist d5028d86df #SET_CLIENT
* small addition
2022-12-15 11:49:28 +01:00
Applevangelist a6e7ea6590 #SET_CLIENT
* Added FilterCallsigns()
* Added FilterPlayernames()
2022-12-14 14:50:06 +01:00
Applevangelist 1fac6b7c93 #SET_CLIENT
* Added `FilterCallsigns()` and `FilterPlayernames()`
2022-12-14 14:48:20 +01:00
Applevangelist 178e4ceb7f #PLAYERTASKCONTROLLER
* Added PLAYERTASKCONTROLLER:AddPlayerTaskToQueue(PlayerTask,Silent,TaskFilter) TaskFilter switch
2022-12-14 11:42:12 +01:00
Applevangelist e12455d154 #AI GCI DISPATCHER
* Fix demo mission link
2022-12-14 09:43:34 +01:00
Applevangelist 089467c15a #AI\_A2A\_GCICAP
* Fix demo mission link
2022-12-14 09:41:35 +01:00
Applevangelist 71d5983adf #AIRBASE
* docu typo
2022-12-12 16:25:07 +01:00
Applevangelist 696569f749 #PLAYERTASK
* Added typename combos as option for menu entries
2022-12-12 16:24:25 +01:00
Applevangelist 77e7f767d8 #AIRBASE
* docu correction
2022-12-12 16:23:47 +01:00
Applevangelist 4892a58084 #SET
* improve GetRandom() a bit
2022-12-11 15:51:22 +01:00
Applevangelist 75d8d55691 #AWACS
* Skip Task Assignement Menus if PlayerCapAssignement is false
2022-12-11 15:50:36 +01:00
Applevangelist 324739aeb9 #SET
* Improve GetRandom() a bit
2022-12-11 15:49:50 +01:00
Applevangelist 614cfcd7f7 Merge remote-tracking branch 'origin/master' into develop 2022-12-09 12:38:02 +01:00
Applevangelist 84d301c676 #CTLD
* Added disallow building in loadzones: my_ctld.nobuildinloadzones = true
2022-12-09 12:37:39 +01:00
phr0gz 8eef039312 New CAP auftrag (#1850)
Add Ability to CAP escort Ground group or helo with a new auftrag: AUFTRAG:NewCAPGROUP
2022-12-08 13:15:07 +01:00
Applevangelist f6a88db46b #CTLD Fix for Beacon Zone disappearing too fast 2022-12-07 18:58:56 +01:00
Applevangelist 9c5847153a Merge remote-tracking branch 'origin/develop' into develop 2022-12-07 18:58:11 +01:00
Applevangelist cdfb47448f #AWACS
* Fix setting of CapVoices according to documentation
#PLAYERRECCE
* Speed up Marker Build
#PLAYERTASK
* Improve menu build
2022-12-07 18:58:07 +01:00
Applevangelist dcfce8b619 #CTLD - enforce modulation on beacons 2022-12-07 18:50:26 +01:00
Frank 0adca414ce Merge branch 'develop' into FF/Ops 2022-12-07 18:36:04 +01:00
Frank 16bfbabf19 Merge branch 'master' into develop 2022-12-07 18:35:27 +01:00
Frank 813d4edc97 CONDITION v0.3.0
- Added methods to remove condition functions
- Added option to define output if no condition functions at all were given
-
2022-12-07 18:35:12 +01:00
Frank 539dfd6a38 OPS Operation
- Condition
- Armygroup
- Auftrag
- OPS
2022-12-07 18:32:50 +01:00
Applevangelist 525666be7c #PLAYERRECCE
* Smoke own position on ground, not mid-air
2022-12-06 18:05:41 +01:00
Applevangelist 386171bcab #PLAYERTASKCONTROLLER
* Make callout of MGRS coordinates slower
2022-12-06 12:50:08 +01:00
Applevangelist 9ea4a5dbd4 #CTLD less log noise 2022-12-06 12:49:27 +01:00
Applevangelist 55383575e0 #PLAYERTASKCONTROLLER
* Make callout of MGRS coordinates slower
2022-12-06 12:48:20 +01:00
Applevangelist 9659bfa553 #CTLD Fix for Beacon Zone disappearing too fast 2022-12-03 14:38:57 +01:00
Applevangelist 508e36d327 #CTLD Fix for Beacon Zone disappearing too fast 2022-12-03 14:37:01 +01:00
Applevangelist 85504fbe62 Small Fixes 2022-12-03 14:36:28 +01:00
Applevangelist de8dcc4024 Merge remote-tracking branch 'origin/master' into develop 2022-12-02 16:39:45 +01:00
Applevangelist 37b1e7366c *smaller fixes 2022-12-02 16:39:09 +01:00
Thomas b29b9f1b2c Update README.md 2022-12-01 21:32:19 +01:00
Applevangelist 620c8eaa27 Merge remote-tracking branch 'origin/master' into develop 2022-12-01 13:29:20 +01:00
Applevangelist 7865be43bb * Minor fixes 2022-12-01 13:27:58 +01:00
Frank 3f296554ed Merge branch 'develop' into FF/Ops 2022-11-30 18:37:51 +01:00
Frank 2a8d166c54 Merge branch 'master' into develop 2022-11-30 18:37:28 +01:00
Frank f17f688a20 Condition and Message 2022-11-30 18:37:14 +01:00
Frank 6bc263bd2b CONDITON and OPERATION 2022-11-30 13:36:13 +01:00
Applevangelist 907d62c4e7 Merge remote-tracking branch 'origin/master' into develop 2022-11-29 17:54:15 +01:00
Applevangelist df2a6a6902 #ATIS
* Added `ATIS:GetSRSText()`
2022-11-29 17:53:41 +01:00
Applevangelist 6965d319ef #CTLD
* Fix for BEACON zones
2022-11-29 15:42:49 +01:00
Applevangelist d674f55343 #PLAYERTASK
* Added Silent option for PLAYERTASKCONTROLLER:AddPlayerTaskToQueue(PlayerTask,Silent)
2022-11-29 15:42:04 +01:00
Applevangelist df0c0ec21e #CTLD
* Small fix for BEACON Zones
2022-11-29 15:39:58 +01:00
Thomas 75bc95167f Update RAT.lua (#1849)
Fix #1848
2022-11-28 17:45:47 +01:00
Thomas 53d71d9766 Update RAT.lua
Fix #1848
2022-11-28 17:42:09 +01:00
Applevangelist 66bf32351a Merge remote-tracking branch 'origin/master' into develop 2022-11-27 17:35:42 +01:00
Applevangelist eb5a72fc27 * less noise 2022-11-27 17:35:13 +01:00
Applevangelist cec045045e * Less noise 2022-11-27 17:35:13 +01:00
Applevangelist fe9a5aea2a #AUFTRAG
* Fix for orbit task not able to get a Vec2 from a Vec2...
2022-11-23 12:57:54 +01:00
Applevangelist b99d963cd5 #SPAWN
* Fix callsign dupplication of numbers introduced with 2.8
2022-11-23 09:56:37 +01:00
Applevangelist 33f30101d9 Merge remote-tracking branch 'origin/master' 2022-11-23 09:55:50 +01:00
Applevangelist 1e139a6005 #SPAWN
* Fix callsign dupplication of numbers introduced with 2.8
2022-11-23 09:55:47 +01:00
Applevangelist eacfbad729 #SPAWN
* Fix for unit callsign number duplication since 2.8 release (ED saving callsign.name now as "Texaco11" instead of "Texaco" for the F10 Map overview
2022-11-23 09:48:06 +01:00
Frank b8398af5a3 Merge branch 'master' into develop 2022-11-20 20:56:07 +01:00
Frank 6834a2e083 Spawning FARPS
**SPAWNSTATIC**
- Added event birth when static FARPS are spawned

**EVENT**
- Unknown airbases as inititiator are registered
2022-11-20 20:55:34 +01:00
Frank 10d8af2536 Merge branch 'master' into develop 2022-11-19 19:37:54 +01:00
Frank 2538d583ad Update Suppression.lua
- Fixed routing of group (passing waypoint function was triggered too early due to changed DCS behaviour)
2022-11-19 19:36:55 +01:00
Frank c9ccc28251 Merge branch 'master' into FF/MasterDevel 2022-11-19 11:44:46 +01:00
Frank e79941bb8b Merge pull request #1846 from FlightControl-Master/FF/Ops
OPS
2022-11-18 20:02:15 +01:00
Frank 4124b6d084 OPS
**LEGION**
- Added `Captured` event

**COMMANDER**
- Improved behaviour when legion/warehouse is captured
- Added `LegionLost` event
- Added `RemoveLegion` function

**CHIEF**
- Improved behaviour when legion/warehouse is captured
- Added `LegionLost` event
- Added `RemoveLegion` function
2022-11-18 19:56:30 +01:00
Applevangelist ae9c258531 Merge remote-tracking branch 'origin/master' into develop 2022-11-18 11:29:45 +01:00
Applevangelist 0f1ad9d811 # TaskRecoveryTanker 2022-11-18 11:28:52 +01:00
Applevangelist df17a3d2a3 # TaskRecoveryTanker 2022-11-18 11:28:33 +01:00
Applevangelist b47737bda3 #GROUP
* Added additional push of tanker task to GROUP:SetAsRecoveryTanker() for a working setup
2022-11-18 11:24:36 +01:00
Applevangelist 93c986f00a #GROUP
* Added additional push of tanker task to GROUP:SetAsRecoveryTanker() for a working setup
2022-11-18 11:23:56 +01:00
Applevangelist 96bb475306 #GROUP/CONTROLLABLE
* Added RecoveryTanker Task
2022-11-18 09:59:43 +01:00
Applevangelist 239e2ef86d #GROUP/CONTROLLABLE
* Added RecoveryTanker Task
2022-11-18 09:58:48 +01:00
Applevangelist 7490796637 #AIRBASE
* Added enumerators for
-- * AIRBASE.SouthAtlantic.Puerto_Santa_Cruz
-- * AIRBASE.SouthAtlantic.Comandante_Luis_Piedrabuena
-- * AIRBASE.SouthAtlantic.Aerodromo_De_Tolhuin
-- * AIRBASE.SouthAtlantic.Porvenir_Airfield
-- * AIRBASE.SouthAtlantic.Almirante_Schroeders
-- * AIRBASE.SouthAtlantic.Rio_Turbio
2022-11-17 17:14:52 +01:00
Applevangelist 5a7a23552d #AIRBASE
* Added enumerators for
-- * AIRBASE.SouthAtlantic.Puerto_Santa_Cruz
-- * AIRBASE.SouthAtlantic.Comandante_Luis_Piedrabuena
-- * AIRBASE.SouthAtlantic.Aerodromo_De_Tolhuin
-- * AIRBASE.SouthAtlantic.Porvenir_Airfield
-- * AIRBASE.SouthAtlantic.Almirante_Schroeders
-- * AIRBASE.SouthAtlantic.Rio_Turbio
2022-11-17 17:13:33 +01:00
Applevangelist a9f2df83ff #CSAR
* Make rescued pilot's weight configureable
2022-11-17 13:55:42 +01:00
Applevangelist 4fb98cf72b #CSAR
* Make rescued pilot's weight configureable
2022-11-17 13:54:43 +01:00
Applevangelist 50aca57112 #PLAYERTASK
* Extended use of marker ops:
-- Enable the function like so:
--          mycontroller:EnableMarkerOps("TASK")
-- Then as a player in a client slot, you can add a map marker on the F10 map. Next edit the text
-- in the marker to make it identifiable, e.g
--
-- TASK Name=Tanks Sochi, Text=Destroy tank group located near Sochi!
--
-- Where **TASK** is the tag that tells the controller this mark is a target location (must).
-- **Name=** ended by a comma **,** tells the controller the supposed menu entry name (optional). No extra spaces! End with a comma!
-- **Text=** tells the controller the supposed free text task description (optional, only taken if **Name=** is present first). No extra spaces!
function PLAYERTASKCONTROLLER:EnableMarkerOps(Tag)
2022-11-17 13:22:34 +01:00
Applevangelist 5011269586 #SPAWN
* Ensure we have a numbered table for InitRandomizeTemplate/Zone so math.random actually works
* Also, pre-shuffle tables
2022-11-16 11:17:19 +01:00
Applevangelist a125497fe7 #SPAWN
* Ensure we have a numbered table for InitRandomizeTemplate/Zone so math.random actually works
* Also, pre-shuffle tables
2022-11-16 11:12:47 +01:00
Frank bd42032e3a Merge pull request #1844 from FlightControl-Master/FF/Ops
OPS
2022-11-16 10:44:00 +01:00
Frank 1256cc3bd1 OPS
**FLIGHTGROUP**
- Waypoint altitude for helos is not radar (AGL)
- Increased cruise speed thresholds for helos to 110 kts and 380 kts for fixed wing
2022-11-16 10:41:33 +01:00
Applevangelist 62122a15bc #MESSAGE
* Added ToCountry()
* Added country names in country.id enum
2022-11-16 09:42:36 +01:00
Applevangelist ae2196585e #MESSAGE
* added to country
* added a couple of countries to country.id. enumerator
2022-11-16 09:39:54 +01:00
Applevangelist f86db5f134 #PLAYERTASK
* Verbose to false
* Verbose add message for marker ops showing coordinate as per _SETTINGS
2022-11-15 17:56:29 +01:00
Thomas 2acb841539 Update PlayerTask.lua
Feature added #1841 `PLAYERTASKCONTROLLER:SetInfoShowsCoordinate(OnOff,LLDDM)`
2022-11-15 15:59:03 +01:00
Applevangelist 6724bb8edd # Bug fixes 2022-11-14 18:17:27 +01:00
Applevangelist fbad50973f # Bug fixes 2022-11-14 18:15:55 +01:00
Applevangelist 7b5b5e0bd2 #ATIS
* Honor Stop() function
2022-11-14 17:38:46 +01:00
Applevangelist 243ac3027f #PLAYERTASK
* Added a couple of QOL functions for internal INTEL object
2022-11-14 17:38:07 +01:00
Applevangelist 782cfd1fd0 #ATIS
* Added honor Stop() functionality
2022-11-14 17:36:34 +01:00
Applevangelist 79a4af44d3 Merge remote-tracking branch 'origin/master' into develop 2022-11-13 13:51:59 +01:00
Applevangelist 180a0b39d1 Merge remote-tracking branch 'origin/develop' into develop 2022-11-13 13:38:13 +01:00
Applevangelist 2664c36a14 #CTLD
* Change call order to move troops, vehicle on `onafter..` internally
* added pseudo-function for "OnBefore..."
2022-11-13 13:37:55 +01:00
Applevangelist d4a06089c9 #CTLD
* Change call order to move troops, vehicle on `onafter..` internally
* added pseudo-function for "OnBefore..."
2022-11-13 13:37:25 +01:00
Rolln 911f4523a1 F10 Marker text fix (#1840) 2022-11-11 20:01:32 +01:00
Applevangelist 09b86d6fdf #OPSGROUP
* Fix for NewHover
2022-11-11 15:40:03 +01:00
Applevangelist 5ec8a4674c Merge remote-tracking branch 'origin/master' into develop
# Conflicts:
#	Moose Development/Moose/DCS.lua
2022-11-11 11:42:30 +01:00
Applevangelist 5c6efed995 Docu Headlines part II 2022-11-11 11:40:36 +01:00
Applevangelist 2a567c9f74 Docu Headlines part II 2022-11-11 11:40:22 +01:00
Applevangelist b9a7fc9409 #AUFTRAG
* Corrected speed setting in NewHover
2022-11-11 10:00:13 +01:00
Applevangelist 0db13b6cdf Merge remote-tracking branch 'origin/master' into develop
# Conflicts:
#	Moose Development/Moose/AI/AI_Cargo_Dispatcher_Ship.lua
#	Moose Development/Moose/Functional/ZoneGoalCoalition.lua
2022-11-11 09:38:27 +01:00
Applevangelist 68a31b1eb7 Docu - Nicer Headlines 2022-11-11 09:35:54 +01:00
Applevangelist 08c7409627 Docu Headlines 2022-11-11 09:22:48 +01:00
Applevangelist c38cb046cd #AMMOTRUCK
* Added demo mission link
2022-11-10 17:53:29 +01:00
Applevangelist 037b168825 Merge remote-tracking branch 'origin/master' into develop 2022-11-10 17:33:52 +01:00
Applevangelist f46f755327 #Docu fixes 2022-11-10 17:32:45 +01:00
Applevangelist 5d4f870a1d #Docu fixes 2022-11-10 17:29:40 +01:00
Applevangelist 41a928b775 #Docu fixes 2022-11-10 17:29:19 +01:00
Applevangelist 27598406d1 #AMMOTRUCK
* Initial Release
2022-11-10 17:11:29 +01:00
Applevangelist a0ad5292b9 #AWACS
* SRS output for "ShowTask"
* Some minor bug fixing
2022-11-10 12:18:18 +01:00
Frank a1a258f48e Merge pull request #1838 from FlightControl-Master/FF/Ops
OPS
2022-11-10 00:40:15 +01:00
Frank 4a0040a12f Merge branch 'develop' into FF/Ops 2022-11-10 00:36:14 +01:00
Frank ab13b5f198 Update Intelligence.lua
- Added check for filter categories.
2022-11-10 00:36:02 +01:00
Applevangelist 788d2d49b9 Merge remote-tracking branch 'origin/master' into develop 2022-11-09 16:11:44 +01:00
Applevangelist 08c5c38c7b Changes from last FF push 2022-11-09 16:09:05 +01:00
Frank 6c342ef910 Merge pull request #1834 from FlightControl-Master/FF/Ops
OPS
2022-11-08 22:11:21 +01:00
Frank a4b5362347 Update Cohort.lua
- Added functions to get and set attributes
- Added function to get category and properties
2022-11-08 22:01:44 +01:00
Frank 0e78be86e4 CHIEF
- Added resource.carrierProperties for LEGION.AssignAssetsForTransport
- Ensure table for carrier categories, attributes and properties
2022-11-08 20:29:51 +01:00
Applevangelist e348bbc344 #AWACS
* Minor Enhancements
2022-11-08 17:24:32 +01:00
Applevangelist bad17c39d1 * POINT/PLAYERTASK
* Added option to get BR/BRA with add'l magnetic heading
2022-11-08 15:43:46 +01:00
Applevangelist 8ed30da473 * POINT/PLAYERTASK
* Added option to get BR/BRA with add'l magnetic heading
2022-11-08 15:43:14 +01:00
Applevangelist 0c9238651a * POINT
* Added option to get BR/BRA with add'l magnetic heading
2022-11-08 15:33:09 +01:00
Applevangelist af1083d0f1 #MSRS
* Docu corrections
* Added `AddFrequencies()` and `AddModulations()`
2022-11-08 10:11:28 +01:00
Applevangelist 10a9b062b6 #MSRS
* Docu corrections
* Added `AddFrequencies()` and `AddModulations()`
2022-11-08 10:10:11 +01:00
Applevangelist 4fff842c90 #CTLD Fix Ship Zones 2022-11-07 19:14:09 +01:00
Thomas 53c6a17ccb Fix CTLD Ship Zones
Fixes #1830
2022-11-07 19:11:08 +01:00
Applevangelist 7f81039f46 #CTLD - Added Bronco support 2022-11-07 18:21:36 +01:00
Applevangelist b63be6dd28 #PLAYERTASK
* Fix #1826 CTLD/CSAR closing immediately
2022-11-07 17:39:11 +01:00
Applevangelist c10617e1b0 #CTLD
* Fix for Bronco #1827
* Fix for Ship Zones
2022-11-07 17:37:02 +01:00
Applevangelist 565a5294e2 Merge remote-tracking branch 'origin/master' into develop 2022-11-07 16:09:00 +01:00
Thomas be01567a1b CTLD - added Bronco (#1828)
Added data for the Bronco-OV-10A - needs further additions to ensure to work, as this is a plane, not a chopper #1827
2022-11-07 11:19:52 +01:00
TommyC81 88fc501c24 Update Range.lua (#1825)
Add meter text to RANGE bombing result.
2022-11-06 19:33:44 +01:00
Frank 254d43fef1 AIRWING/WAREHOUSE
- Improved parking spot check if explicitly given for an airwing or squadron
- Improved parking check if airstart is requested.
2022-11-06 12:17:07 +01:00
Applevangelist e93bb5ceba Merge remote-tracking branch 'origin/master' 2022-11-06 11:28:03 +01:00
Applevangelist 7983621f8e #SCORING
* Added option to switch AutoSave
2022-11-06 11:27:59 +01:00
Applevangelist 5819884c98 #SCORING
* Added option to switch AutoSave
2022-11-06 11:27:27 +01:00
Applevangelist 6c79d6b01f #SCORING
* Added option to switch AutoSave
2022-11-06 11:26:16 +01:00
Frank cb43f9c392 CHIEF
- cleaned up resources
2022-11-05 23:48:42 +01:00
Applevangelist ed677b7682 Merge remote-tracking branch 'origin/master' into develop 2022-11-05 14:04:06 +01:00
Applevangelist b2a351e67d UTILS 2022-11-05 14:03:38 +01:00
Frank ead8411454 Merge pull request #1824 from FlightControl-Master/FF/Ops
OPS
2022-11-04 22:55:24 +01:00
Frank 1fc9f13919 Version 2022-11-04 22:36:20 +01:00
Frank 6bf077e0aa Merge branch 'develop' into FF/Ops 2022-11-04 19:47:52 +01:00
Applevangelist 0de8c0beb2 #INTEL
* Added `INTEL:GetHighestThreatContact(Cluster)`
2022-11-04 13:31:33 +01:00
Frank 39f690f2b4 OPS
- AUFTRAG: Orbit is now in KIAS
- CHIEF: fixes for resource
2022-11-03 22:46:10 +01:00
Frank 1a575d9364 Update OpsGroup.lua
- Improved mission ingreess on-off-road waypoint
2022-11-02 23:51:53 +01:00
Frank fe58253a44 Update Chief.lua
added remove conflict zone
2022-11-02 23:30:19 +01:00
Frank 65cc72e28b Merge branch 'develop' into FF/Ops 2022-11-02 22:59:19 +01:00
Frank 00f8fccfae Update ArmyGroup.lua
- Improved updateroute waypoints
2022-11-02 22:57:05 +01:00
Applevangelist 1fea016ac1 Merge remote-tracking branch 'origin/master' into develop 2022-11-02 17:33:34 +01:00
Applevangelist 35057b9d05 Merge remote-tracking branch 'origin/develop' into develop 2022-11-02 17:32:20 +01:00
Applevangelist b2fdcd5cf0 #CHIEF
* Fix to auto-create CAS/CAS-Enhanced Missions from detected targets; Added BAI mission option for TANKS as target
2022-11-02 17:32:12 +01:00
Thomas 2b3363de40 Documentation fixes. (#1820) (#1821)
* Documentation fixes.

* Update Airboss.lua

Escape links.

Co-authored-by: TommyC81 <tommyc81@gmail.com>
2022-11-02 11:24:59 +01:00
TommyC81 574fa8abf4 Documentation fixes. (#1820)
* Documentation fixes.

* Update Airboss.lua

Escape links.
2022-11-02 11:20:35 +01:00
Frank d031651b58 Fixes for OPSTRANSPOTRT formation 2022-11-01 23:35:18 +01:00
Applevangelist 8fb66ed329 #ZONE_POLYGON
* Scan for Scenery - changed scan strategy as box seems not to work properly all the time
2022-11-01 16:32:40 +01:00
Applevangelist c4f4af5e5a #ZONE_POLYGON
* Scan for Scenery - changed scan strategy as box seems not to work properly all the time
2022-11-01 16:31:47 +01:00
Applevangelist e841a38866 #CTLD
* added option for build time delay
2022-11-01 14:33:06 +01:00
Applevangelist 1da0792ed7 #CTLD
* added option for build time delay
2022-11-01 14:32:02 +01:00
Frank addb7ba36a restore 2022-10-31 20:53:20 +01:00
Frank d4b5e24364 ARMYGROUP
- Fixed opstransport not being readded to brigade
2022-10-31 20:50:35 +01:00
Applevangelist dd32d2e53c #CTLD_HERCULES
* Fix for `CTLD_HERCULES:Cargo_Track(cargo, initiator)` when flying very low
2022-10-31 16:07:25 +01:00
Applevangelist 7d37acb1cd #CTLD_HERCULES
* Fix for `CTLD_HERCULES:Cargo_Track(cargo, initiator)` when flying very low
2022-10-31 16:06:30 +01:00
Applevangelist cc1e071e35 #EVENT
* Added events from 2.8.0
2022-10-31 15:44:29 +01:00
Applevangelist fd230701e9 #EVENT
* Added events from 2.8
2022-10-31 15:43:13 +01:00
Applevangelist 91d492c579 #EVENT
* Added events from 2.8
2022-10-31 15:15:47 +01:00
Frank 3f8efae23f Update Chief.lua
resources
2022-10-31 13:26:35 +01:00
Applevangelist 8ee8898a78 #AWACS
* Added airborne check for detected groups
2022-10-31 12:22:34 +01:00
Applevangelist fc77df4b5d Merge remote-tracking branch 'origin/master' into develop 2022-10-31 10:26:45 +01:00
Applevangelist 5eabe7e644 #GROUP
* Ensure also attribute "Tanks" is captured
2022-10-31 10:25:08 +01:00
Applevangelist 13018ed96a Merge remote-tracking branch 'origin/master' into develop 2022-10-31 08:02:21 +01:00
Frank 236e7afcfc AUFTRAG
- New mission type ORBIT_GROUP
- Updated mission type RECOVERYTANKER
2022-10-30 14:10:55 +01:00
Thomas 946a1de931 Merge docu changes (#1818)
* Documentation fixes. (#1810)

Fix documentation references.
Correct spelling errors.
Remove empty whitespaces.
Correct a single mis-spelled ZONE_BASE variable, see 'Core/Zone.lua' (variable "Sureface" -> "Surface", no references to mis-spelled "Sureface" throughout the codebase).
Correct mis-spelling of "coaltion" in 'Functional/Mantis.lua', corrected to "coalition".

* Documentation fixes. (#1811)

Update documentation text and links.
Fix spelling errors.
Other minor adjustments where appropriate, such as remove whitespaces and format code.

* Documentation fixes. (#1815)

Minor documentation and code formatting fixes.
This is mostly intended to have something re-trigger the documentation generation to see if the filename capitalization is resolved.

* Code formatting preparation. (#1817)

Use EmmyLuaCodeStyle that comes with "Lua" VS Code extension (https://marketplace.visualstudio.com/items?itemName=sumneko.lua). More features and configurability than LuaFormatter, and no need for additional extension (beyond "Lua").
Formatting file set up from default template with some tweaks to correspond to most common coding style observed in the code base. Further tweaks are likely required.

* Documentation fixes. (#1816)

Co-authored-by: TommyC81 <tommyc81@gmail.com>
2022-10-29 10:49:18 +02:00
TommyC81 368e720cab Documentation fixes. (#1816) 2022-10-29 10:07:50 +02:00
TommyC81 cba156b3dc Code formatting preparation. (#1817)
Use EmmyLuaCodeStyle that comes with "Lua" VS Code extension (https://marketplace.visualstudio.com/items?itemName=sumneko.lua). More features and configurability than LuaFormatter, and no need for additional extension (beyond "Lua").
Formatting file set up from default template with some tweaks to correspond to most common coding style observed in the code base. Further tweaks are likely required.
2022-10-29 10:07:01 +02:00
Frank 2840865b83 Up 2022-10-27 23:19:35 +02:00
TommyC81 676bc0fef0 Documentation fixes. (#1815)
Minor documentation and code formatting fixes.
This is mostly intended to have something re-trigger the documentation generation to see if the filename capitalization is resolved.
2022-10-27 18:38:59 +02:00
TommyC81 7455c63716 Documentation fixes. (#1811)
Update documentation text and links.
Fix spelling errors.
Other minor adjustments where appropriate, such as remove whitespaces and format code.
2022-10-23 16:45:40 +02:00
TommyC81 81818705df Documentation fixes. (#1810)
Fix documentation references.
Correct spelling errors.
Remove empty whitespaces.
Correct a single mis-spelled ZONE_BASE variable, see 'Core/Zone.lua' (variable "Sureface" -> "Surface", no references to mis-spelled "Sureface" throughout the codebase).
Correct mis-spelling of "coaltion" in 'Functional/Mantis.lua', corrected to "coalition".
2022-10-22 11:07:58 +02:00
Applevangelist 1411309204 Fixes 2022-10-21 15:15:51 +02:00
Applevangelist 60927e6728 Merge remote-tracking branch 'origin/master' into develop 2022-10-21 15:11:46 +02:00
Applevangelist 4b11a6a304 #OPS - typos 2022-10-21 15:09:35 +02:00
TommyC81 61ea484614 Documentation fixes. (#1809)
Fix incorrect references.
Simplify references within the same module.
Fix spelling errors and minor code formatting.
2022-10-21 13:52:09 +02:00
Applevangelist 37a00f25bc #OPERATION
* Added GetTargets()

#TARGET
* Also call Dead() when no targets left over

#PLAYERTASKCONTROLLER
* Added FSM events for Flaring, Smoking, and Illumination
* Added Illumination of targets in menu if it is night
* Rename menu parent setting to SetParentMenu(Menu)
2022-10-21 09:51:44 +02:00
Applevangelist 1fc541a9df Merge remote-tracking branch 'origin/master' into develop 2022-10-21 08:58:48 +02:00
TommyC81 d5e8de4d74 Documentation fixes. (#1807)
Correct module links.
Replace references to missing images with MOOSE.JPG.
Add default MOOSE.JPG where no image was previously set.
Fix minor spelling error.
2022-10-21 06:10:34 +02:00
Applevangelist c3cd732254 #MANTIS
* Add systems from SMA mod
2022-10-20 11:40:57 +02:00
Applevangelist b7d5144c91 #MANTIS
* Add systems from SMA mod
2022-10-20 11:39:51 +02:00
Applevangelist 8f7694111b #TARGET
* Docu additions
2022-10-19 19:13:55 +02:00
Applevangelist 2854a2d93e #TARGET
* Some QOL additions, docu, stuff for SCENERY
2022-10-19 17:26:40 +02:00
Applevangelist 78c209a96f #PLAYERTASKCONTROLLER
* No spaces in callsign numbers on pilot list in task info screen
2022-10-19 13:05:19 +02:00
Applevangelist 9809f08954 Merge remote-tracking branch 'origin/master' into develop 2022-10-19 12:46:17 +02:00
Applevangelist 7bba5ec69e #SCENERY, #SET_SCENERY
* Improvements
2022-10-19 12:37:24 +02:00
Applevangelist 4e671ce995 Merge remote-tracking branch 'origin/master' into develop 2022-10-19 12:28:26 +02:00
Rolln b5fd737cea Playertaskcontroller parent menu (#1806)
* Ability to set parent menu of PlayerTaskController

* Updated Docmentation

* Update PlayerTask.lua

Co-authored-by: Thomas <72444570+Applevangelist@users.noreply.github.com>
2022-10-19 12:21:16 +02:00
TommyC81 0441acf101 Documentation fixes. (#1803)
Improve the consistency of the module intros to the most commonly used version (single dash).

Add missing module information (abbreviated where none existed previously).

Fix broken documentation links

Make module names correspond to filenames (and fix links).

Fix typos.
2022-10-19 12:20:39 +02:00
Rolf Geuenich 89f0909a8f Fixed some errors in the documentation of Core MESSAGE (#1804)
Removed wrong forth parameter in most examples.
Removed duplicate of function ToUnit.
2022-10-19 06:32:57 +02:00
Frank 6f82fd7eb6 Merge branch 'develop' into FF/Ops 2022-10-18 22:33:07 +02:00
Applevangelist 542fe20782 #CTLD
* added a check for zones; not added when zone does not exist
2022-10-18 17:26:24 +02:00
Applevangelist ff0f1c4c24 #CTLD
* added a check for zones; not added when zone does not exist
2022-10-18 17:23:01 +02:00
Applevangelist 92591432d3 #CSAR
* Added use of custom callsigns
* Added cargo weight for rescued pilots
* Improved o'clock calculation

#CTLD
* Docu additions
2022-10-18 17:01:32 +02:00
Applevangelist a20cdac9c3 #CSAR
* Added use of custom callsigns
* Added cargo weight for rescued pilots
* Improved o'clock calculation

#CTLD
* Docu additions
2022-10-18 17:00:56 +02:00
Applevangelist 3a6c52ae73 #CSAR
* Added use of custom callsigns
* Added cargo weight for rescued pilots
* Improved o'clock calculation

#CTLD
* Docu additions
2022-10-18 16:59:19 +02:00
Applevangelist 23f45359f8 #PLAYERTASK - show freetext briefing also if not using SRS 2022-10-18 13:32:18 +02:00
Applevangelist 0bc09548cf #PLAYERRECCE - add picture 2022-10-18 10:27:25 +02:00
Applevangelist ee30ab48ae #SET_SCENERY
* additions
2022-10-17 18:07:55 +02:00
Applevangelist 3028a384a4 #TARGET
* Added SET_SCENERY
2022-10-17 18:07:04 +02:00
Applevangelist 7ec18ebf00 #SCENERY
* functional additions
#SET
* added SET_SCENERY
2022-10-17 18:06:29 +02:00
Thomas f17db43501 CTLD - No radius check (#1800) (#1801)
Get rid of radius check in IsUnitInZone()
2022-10-17 12:44:27 +02:00
Thomas 66f52d41eb CTLD - No radius check (#1800)
Get rid of radius check in IsUnitInZone()
2022-10-17 12:33:17 +02:00
Applevangelist 7dd46ec24f #PLAYERTASKCONTROLLER
* Show Freetext as Briefing in all tasks when available
* TARGET - added Average coordinate option from GROUP
2022-10-16 13:47:52 +02:00
Applevangelist cefb5d98f0 #GROUP
* Added function to obtain *average* Vec3 of the GROUP
* Added function to obtain *average* Coordinate of the GROUP

#TARGET
* Make use of new coordinate function in GROUP
2022-10-16 13:38:54 +02:00
Applevangelist 1172cf0ae7 #GROUP
* Added function to obtain *average* Vec3 of the GROUP
* Added function to obtain *average* Coordinate of the GROUP
2022-10-16 13:36:21 +02:00
Thomas e750a99636 Update PlayerRecce.lua
Event Handler simplification
2022-10-16 09:30:55 +02:00
Applevangelist 798684e300 #Docu additions 2022-10-14 16:51:59 +02:00
Applevangelist 1d296d1cf4 #CTLD
* Documentation additions
2022-10-14 16:50:31 +02:00
Applevangelist 7c004ee37c #docu 2022-10-14 16:50:16 +02:00
Applevangelist 0a4bc23fb8 #PLAYERRECCE
* Added switchable smoking of own position
* Changed smoking - now laser target single, other targets as combined coordinate
* Added battle field illumination
* Added support for the KA-50. Note - camera is seen as "always on". For lasing, target needs to be head-on 12 o'clock
2022-10-14 16:19:53 +02:00
Applevangelist 13a5146010 #PLAYERRECCE
* Added switchable smoking of own position
* Changed smoking - now laser target single, other targets as combined coordinate
* Added battle field illumination
* Added support for the KA-50. Note - camera is seen as "always on". For lasing, target needs to be head-on 12 o'clock
2022-10-14 16:19:21 +02:00
Applevangelist a6bddc5aca #SET_UNIT - fix GetCoordinate() 2022-10-14 16:18:53 +02:00
Frank 55fe3630c5 Update FlightGroup.lua
- Fixed bug that function `:GetAirWing` was renamed to `:GetAirwing()`
2022-10-13 23:11:09 +02:00
Applevangelist 265196398a #PLAYERTASK - CSAR, CTLD integration 2022-10-13 17:45:33 +02:00
Applevangelist 141d00e160 Merge remote-tracking branch 'origin/master' into develop 2022-10-13 17:44:04 +02:00
Applevangelist bdd40fdf7d #PLAYERTASK integration for CSAR and CTLD 2022-10-13 17:43:27 +02:00
Applevangelist 5c8d90f50e #SCENERY
* Improvements
2022-10-13 12:54:10 +02:00
Applevangelist c84e153ff2 #SCENERY
* Improvements
2022-10-13 12:53:27 +02:00
Applevangelist 351a2463a2 #SCENERY - Improvements 2022-10-13 10:49:58 +02:00
Applevangelist ab4c83d284 #SCENERY - Improvements 2022-10-13 10:49:17 +02:00
Applevangelist f604f0f913 Merge remote-tracking branch 'origin/master' into develop 2022-10-12 16:22:37 +02:00
Applevangelist cd99c053df #SCENERY
* Clarification in docu for :FindByName()
2022-10-12 16:21:55 +02:00
Applevangelist 7afe76212d #CTLD
* Added connection to PlayerTask/Controller
#PLAYERTASK
* Added helper functions
2022-10-12 12:36:33 +02:00
Applevangelist a777b40613 #PLAYERTASKCONTROLLER
* Initial additions for CTLD tasks
2022-10-12 10:14:40 +02:00
Applevangelist 11ef7c6a00 #STATIC
* Added GetLife() GetLife0()
#TARGET
* Added usesage of Life functions to TARGET
2022-10-12 09:36:42 +02:00
Applevangelist 3434ef47d9 #STATIC
* Add Life0 to STATIC Object
* Added functions for STATIC:GetLife() and STATIC:GetLife0()
2022-10-12 09:32:51 +02:00
Applevangelist b5bc881d52 Merge remote-tracking branch 'origin/master' into develop 2022-10-10 17:44:55 +02:00
Applevangelist 66d5ba9981 #Core.Point
* Cleanup GetClosestAirbase()
2022-10-10 17:44:20 +02:00
Applevangelist c5145a38e2 #Core.Point
* Cleanup GetClosestAirbase()
2022-10-10 17:42:02 +02:00
Applevangelist eecef9a0aa #PLAYERRECCE
* minor enhancements
2022-10-09 12:56:54 +02:00
Applevangelist 7e6aa20168 #PLAYERRECCE
* Minor Enhancement
2022-10-09 12:56:00 +02:00
Applevangelist 38b9778e9a #SET
* minor enhancement
2022-10-09 12:53:45 +02:00
Applevangelist 69a80a6c38 #PLAYERRECCE
* Added setting of laser distance as camera sight calc is a non-starter
* Added specific laser zone of 20m x length to catch targets to lase
* Reworked detection of hit on lased target
2022-10-07 14:33:38 +02:00
Applevangelist d63ab1138c #PLAYERTASKCONTROLLER
* Enable PLAYERTASKCONTROLLER:EnableBuddyLasing(Recce) - buddy lasing precision bombing tasks with a PLAYERRECCE connection
2022-10-06 17:05:16 +02:00
Applevangelist f790c4fb9e #PLAYERRECCE
* Gazelle optics refinement
* Added Shack FSM event
2022-10-06 13:29:58 +02:00
Applevangelist 40427c75b9 #FlightGroup dual naming in functions 2022-10-06 13:28:19 +02:00
Applevangelist e18a5e4832 #PLAYERTASKCONTROLLER
* Switch comms on opening task
2022-10-06 08:15:39 +02:00
Applevangelist 4d2a58e428 Fixes 2022-10-06 08:07:37 +02:00
Applevangelist 005d6d2b06 Merge remote-tracking branch 'origin/master' into develop 2022-10-06 08:03:07 +02:00
Jason du Plessis 2ca6168f47 #ZONE * Fixed ZONE_RADIUS Not being added to _Database (#1798)
* #ZONE * Fixed ZONE_RADIUS Not being added to _Database

Bugfix for #1797.

ZONE_RADIUS was not being registered within the _Database table, thus for CTLD, the Zone could not be found for moving units to ZONE_RADIUS zones. Because other Zone types inherit ZONE_RADIUS, I've added a RegisterZone parameter that is default to true, and modified the inheritance of the other Zone types to register the zone in the _Database depending if the zone does not get registered in that zone type.

* #ZONE * Updated ZONE_RADIUS RegisterZone to DoNotRegisterZone

Changed RegisterZone to DoNotRegisterZone and updated the different zone types values for RegisterZone.

Suggested by Applevangelist.

Co-authored-by: Jason du Plessis <jason.duplessis@ebtax.co.za>
2022-10-06 07:27:07 +02:00
Thomas 7ada57033a Update PlayerRecce.lua (#1796)
* Update PlayerRecce.lua

* Update PlayerRecce.lua
2022-10-06 07:25:24 +02:00
Applevangelist 1a332ae6ab Merge remote-tracking branch 'origin/master' into develop 2022-10-05 07:33:46 +02:00
Applevangelist 0da2299472 Docu changes 2022-10-05 07:32:17 +02:00
Frank 064e082a12 Airwing
- Added `:IncreasePayloadAmount` function
2022-10-03 19:12:19 +02:00
Frank 10eec8a47b Update FlightGroup.lua
- Added `GetSquadronName` and `GetAirwingName` functions
2022-10-03 16:32:55 +02:00
Frank db469d1b84 Merge branch 'develop' into FF/Ops 2022-10-02 22:10:52 +02:00
Frank 1e04aaa77d Update Airboss.lua
- reenabled ai handling
2022-10-02 19:45:48 +02:00
Applevangelist e97753125d Merge remote-tracking branch 'origin/master' into develop 2022-10-02 19:35:15 +02:00
Applevangelist 1474ff9b88 Merge remote-tracking branch 'origin/develop' into develop 2022-10-02 19:34:09 +02:00
Applevangelist 39bb95f127 #PLAYERRECCE
-- DONE: Sort for multiple targets in one direction
-- DONE: Targets with forget timeout, also report
2022-10-02 19:34:04 +02:00
Frank bf2ce3c4af AIRBOSS v1.3.0
- Copy from `develop` branch.
- Disabled AI handling as this is bugged (needs `FLIGHTGROUP` class)
2022-10-02 19:20:25 +02:00
Frank 42baf6c8d2 AIRBOSS v1.3.0
- Added Invincible parameters from master branch
- Increased version number
2022-10-02 19:13:51 +02:00
Frank 73b9552b5c Merge branch 'master' into develop 2022-10-02 16:55:47 +02:00
Frank c0f82eabb2 Server Name
**GLOBALS**
- Read out server name from `Config/serverSettings.lua`
**SOCKET**
- Added `server_name` to transmitted UDP data
2022-10-02 16:54:48 +02:00
Frank 60cf7506f8 Update Airboss.lua
- Added `landingdist` as carrier parameter and into LSO result
- Case III does not check groove time for unicorns
2022-10-02 16:10:14 +02:00
Applevangelist 894062c757 #POINT
* Added COORDINATE:ToStringFromRPShort
2022-10-02 13:16:56 +02:00
Applevangelist 165a5d7364 #PLAYERRECCE
* Message improvements
* Laser Distance 8km
* Option to set RP Reference Point
2022-10-02 13:16:00 +02:00
Applevangelist 30aba1258d #POINT
* Added COORDINATE:ToStringFromRPShort
2022-10-02 13:14:57 +02:00
Applevangelist 405e66ea72 #PLAYERTASK
* SRS transmit option only when players are on
2022-10-01 16:36:29 +02:00
Applevangelist a42ff85406 #PLAYERRECCE
* Integrated SRS
* Integrated PLAYERTASKCONTROLLER (optional), can upload target data from Recce
2022-10-01 16:03:05 +02:00
Applevangelist 2eba68b35c #ATIS, MSRSQUEUE
* Added option to only transmit via SRS if there are active Players
2022-10-01 11:58:28 +02:00
Applevangelist f2ed920214 #SRSQUEUE, ATIS
* Added option to only transmit via SRS if there are active players
2022-10-01 11:57:22 +02:00
Frank efe7673c4c Merge branch 'develop' into FF/Ops 2022-09-30 19:34:23 +02:00
Applevangelist ca92d7d569 #PLAYERRECCE
* Some nicefications
2022-09-30 19:07:12 +02:00
Applevangelist 0ee2baadce #AWACS
* Make Markers and Drawings strictly coalition specific
2022-09-30 19:03:26 +02:00
Applevangelist 43856341e6 #PLAYERRECCE
* Initial Release
2022-09-30 18:49:08 +02:00
Applevangelist 61aed403d9 #SET
* Added code to`SET:IsInSet(Object)` to be functional
2022-09-30 14:48:35 +02:00
Applevangelist 2fc7139f6b #SET
* Added code to`SET:IsInSet(Object)` to be functional
2022-09-30 14:47:51 +02:00
Applevangelist a8a92c00fe #AUTOLASE
* Don't forget min threatlevel 0 on unit targets
2022-09-30 14:41:38 +02:00
Applevangelist 84c41aa554 Merge remote-tracking branch 'origin/master' into develop 2022-09-29 16:45:29 +02:00
Applevangelist e8ace49e8b #SPOT - Set relative position to start lasing
#ZONE_POLYGON - Added `ZONE_POLYGON:NewFromPointsArray( ZoneName, PointsArray )`
2022-09-29 16:43:40 +02:00
Applevangelist de415384f3 #PLAYERTASK - a target can only be smoked again after 5 mins (that's how long smoke lasts)
#PLAYERTASKCONTROLLER - added option to hide smoke&flare menus
2022-09-28 13:07:37 +02:00
Applevangelist 8a9ee747c1 #ZONE_CAPTURE_COALITION - allow zone to be a ZONE_POLYGON
#1789
2022-09-28 11:51:22 +02:00
Applevangelist dddb9ff713 #ZONE_CAPTURE_COALITION - allow zone to be a ZONE_POLYGON 2022-09-28 11:49:06 +02:00
Applevangelist 2eeb918c8a #ATIS
* Fixed SetILS report not working
* Use new AIRBASE additions to set takeoff/landing runway
* Fixed Visibility is reported twice
* Added SetReportmBar() to report for mBar/hpa QNH/QFE even if not metric
* Added option to output additional freetext information when using SRS SetAdditionalInformation()

#1792
2022-09-27 11:17:04 +02:00
Applevangelist f582f7df7c #ATIS
* Fixed SetILS report not working
* Use new AIRBASE additions to set takeoff/landing runway
* Fixed Visibility is reported twice
* Added SetReportmBar() to report for mBar/hpa QNH/QFE even if not metric
* Added option to output additional freetext information when using SRS SetAdditionalInformation()

#1792
2022-09-27 11:16:08 +02:00
Applevangelist 72aa596317 #1790 Fix for error in GetCustomCallsign if the player name contains a |-sign but no string at the end or just numbers 2022-09-27 09:31:08 +02:00
Applevangelist 14c6d1be9b #1790 Fix for error in GetCustomCallsign if the player name contains a |-sign but no string at the end or just numbers 2022-09-27 09:27:59 +02:00
Frank 2157f8e8cd Airboss
Take animation for determining the wire
2022-09-26 23:34:00 +02:00
Frank 6de3a45a51 CHIEF
**CHIEF** v0.5.0
- Added `CHIEF:AddTransportToResource` function

**OPSZONE**
- Added `Undraw` option

**UTILS**
- Added `UTILS.EnsureTable` function
2022-09-26 19:00:26 +02:00
Applevangelist 28a826b35d #CSAR
* Added mycsar.ADFRadioPwr = 1000 for ADF beacon radio sending power
2022-09-26 17:03:08 +02:00
Applevangelist 0731e15385 #CSAR
* Added mycsar.ADFRadioPwr = 1000 for ADF beacon radio sending power
2022-09-26 17:01:18 +02:00
Applevangelist 41813dcc53 #AWACS - corrected aggressive 2022-09-25 15:04:39 +02:00
Applevangelist 6290409e54 #ATIS - added google option
#SRS - corrected enumerator
2022-09-25 14:42:51 +02:00
Applevangelist 9eb82060a5 SRS - corrected enumerator 2022-09-25 14:41:38 +02:00
Applevangelist 9f232ab5ec #ATIS - added Google TTS option 2022-09-25 14:41:19 +02:00
Applevangelist 25033f4f6b #FlightControl - Option to set Google key once on New() 2022-09-25 14:40:17 +02:00
Applevangelist b8fae00c1e #MSRS - put "" around frequencies and modulations 2022-09-25 14:16:19 +02:00
Applevangelist ec0d164619 #MSRS - put "" around frequencies and modulations 2022-09-25 14:14:56 +02:00
Applevangelist 6d4e4e2f69 #AWACS - give full radio freq in info 2022-09-25 14:12:46 +02:00
Applevangelist 1cde688fbb #RANGE
* Added 2 more SRS outputs
2022-09-24 10:11:23 +02:00
Applevangelist e804ab9254 Merge remote-tracking branch 'origin/master' 2022-09-24 10:10:06 +02:00
Applevangelist 25cb12a81a #FOX
* Added comfy function
2022-09-24 10:10:02 +02:00
Applevangelist 231acc7363 #RANGE
* added 2 more SRS outputs
2022-09-24 10:09:00 +02:00
Applevangelist e3493fbe3e #CSAR
* Added option to change top menu name
2022-09-23 10:29:41 +02:00
Applevangelist d8bdf6a8d3 #CSAR
* Added option to change top menu name
2022-09-23 10:28:35 +02:00
Applevangelist 1b691a3dd7 #FOX
* Typo in Event function fixed
2022-09-23 10:00:09 +02:00
Applevangelist d506067c72 #FOX
* Typo in Event Function fixed
2022-09-23 09:59:24 +02:00
Applevangelist 3022dce26e #CTLD
* check on loadable mass when loading troops added
2022-09-22 17:32:43 +02:00
Applevangelist 4483d3231a #CTLD
* Added: troop mass also checked when loading
2022-09-22 17:30:01 +02:00
Applevangelist 9780a65f09 #AIRBOSS, #UTILS
* Alitude to Altitude
* Deck height Nimitz class to 18.30m
2022-09-22 15:51:28 +02:00
Applevangelist 481ee186aa #AIRBOSS, #UTILS
* Alitude to Altitude
2022-09-22 15:49:31 +02:00
Thomas 8820b8a41c Nimitz deck height (#1787)
Corrected deck height of Nimitz class to 18.3m/60ft
2022-09-22 15:46:55 +02:00
Applevangelist 34dd864c8b #SPAWN
* Fix for InitCleanup()
2022-09-22 10:58:50 +02:00
Applevangelist 0971f8ffa7 #SPAWN
* Fix for InitCleanup()
2022-09-22 10:57:43 +02:00
Applevangelist 9b16519a7e #ATIS
* Added MSRSQueue to avoid overlapping speech
2022-09-20 17:18:00 +02:00
Applevangelist 9739f94428 #ATIS
* Add MSRSQUEUE to avoid overlaps
2022-09-20 17:15:57 +02:00
Applevangelist 76321343c2 #AIRBASE, ATIS
* less noise in log

#SRS
* Added enumerator for voices MSRS.Voices.Microsoft... and MSRS.Voices.Google...

#RANGE
* Added SRS support, some bug fixing
2022-09-20 15:53:09 +02:00
Applevangelist 450f4eaec0 #AIRBASE, ATIS
* less noise in log

#SRS
* Added enumerator for voices MSRS.Voices.Microsoft... and MSRS.Voices.Google...

#RANGE
* Added SRS support, some bug fixing
2022-09-20 15:51:16 +02:00
Applevangelist b5186fa328 #SETTINGS
* Fix IsImperial()
2022-09-20 15:26:34 +02:00
Applevangelist 0159ce5b1d Merge remote-tracking branch 'origin/master' into develop 2022-09-20 10:27:06 +02:00
Applevangelist 526dc8363d #DESIGNATE
* Remove useless summary autolase report, restored single lines when lasing
2022-09-20 10:26:19 +02:00
Applevangelist 242d735d8c #DETECTION
* Make designate refer A2G coordinate system as set by user
2022-09-20 09:27:19 +02:00
Applevangelist 5abec25c58 #UTILS
* Fix for loading back set of groups. Thanks to @BlueEcko!
2022-09-20 08:24:50 +02:00
Applevangelist 9fedd32e78 #UTILS
* Fix for group set reloading - thanks @BlueEcko!
2022-09-20 08:23:49 +02:00
Applevangelist d9de1e866f Merge remote-tracking branch 'origin/master' into develop 2022-09-19 18:26:56 +02:00
Applevangelist a146003a6a #DESIGNATE
* Some documentation clarifications
2022-09-19 18:25:54 +02:00
Applevangelist 1ae8e7d55e Merge remote-tracking branch 'origin/master' into develop 2022-09-19 13:22:18 +02:00
Applevangelist d17df74191 ATIS
* Remove dupe inheritance of BASE
2022-09-19 13:20:45 +02:00
Applevangelist 67dc4521e9 Merge remote-tracking branch 'origin/master' into develop 2022-09-19 11:44:59 +02:00
Applevangelist d23403383f #CSAR
* Added option to use the OV-10A Bronco
* Slight changes to SRS approach
* Added door check in UTILS for Bronco
2022-09-19 11:43:50 +02:00
Applevangelist 852ebba530 #AUTOLASE
* also show A2G BR Settings
2022-09-19 11:42:50 +02:00
jojom4n 79669d9a69 Make AWACS SRS talk as own coalition; Typo (#1784)
* Make AWACS SRS talk as own coalition

Set MSRS coalition to make AWACS talk only to its coalition, not to spectators

* Typo

SetModernEraAgressive() function should be SetModernEraAggressive() (two 'g')
2022-09-18 19:04:40 +02:00
Applevangelist 11d37bcb93 #CSAR
- triple try to get coordinate for beacon
2022-09-15 19:54:36 +02:00
Applevangelist 877b36f8a8 #CSAR
* overcome error cannot get Vec3
2022-09-15 19:51:15 +02:00
Applevangelist c95d5dc320 #PLAYERTASK
* coord text fix
2022-09-15 19:50:45 +02:00
Applevangelist 92044c7797 Merge remote-tracking branch 'origin/master' into develop 2022-09-15 14:02:09 +02:00
Applevangelist 299820162b #ATIS
* No old-style radioqueue when using SRS
2022-09-15 14:01:23 +02:00
Applevangelist 7084d9e084 #OPSGROUP
* Allow for customized CallSigns

#PLAYERTASK
* SRS output finetuning
2022-09-15 13:59:16 +02:00
Applevangelist af96e2f143 Merge remote-tracking branch 'origin/master' into develop 2022-09-15 13:52:20 +02:00
Applevangelist 5d20a59d92 #GROUP
* Customized Callsigns - remove extra spaces
2022-09-15 13:40:37 +02:00
Applevangelist f7560714e7 Merge remote-tracking branch 'origin/master' into develop 2022-09-15 08:18:19 +02:00
Applevangelist c1ab3b5476 #GROUP
* Fix ignore leading spaces in customized callsigns
2022-09-15 08:17:37 +02:00
Applevangelist 785c5e66ec bump number 2022-09-14 18:07:53 +02:00
Applevangelist f281e5aa95 #AWACS
* Align CallSign Generation
2022-09-14 18:06:36 +02:00
Applevangelist 55f0f5271d #PLAYERTASKCONTROLLER
* Clean up menu builds
2022-09-13 17:19:44 +02:00
Applevangelist b60d3a771d Merge remote-tracking branch 'origin/master' into develop 2022-09-13 10:55:57 +02:00
Applevangelist 0076130483 #GROUP
* Docu clarifications
2022-09-13 10:51:25 +02:00
Applevangelist d2132b2e64 #PLAYERTASKCONTROLLER
* Align creation of (player) callsigns with what is used in AWACS
2022-09-13 10:11:10 +02:00
Applevangelist 95494c0d03 Merge remote-tracking branch 'origin/master' into develop 2022-09-12 17:34:21 +02:00
Applevangelist a5194b1999 #GROUP
-- remove log output
2022-09-12 17:33:40 +02:00
Applevangelist 76a8286c04 Merge remote-tracking branch 'origin/master' into develop 2022-09-12 17:29:47 +02:00
Applevangelist b53b1f083f #GROUP
* Fix IsPlayer
* Added `GROUP:GetCustomCallSign()`
2022-09-12 17:28:49 +02:00
Applevangelist eca8d6dd8d #AWACS
* Fixed AWACS custom callsigns not observed
2022-09-11 18:21:58 +02:00
Applevangelist e6ae034f7e Merge remote-tracking branch 'origin/develop' into develop 2022-09-11 14:22:52 +02:00
Applevangelist 236b4efb9b #PLAYERTASKCONTROLLER
* Various fixes and improvements
2022-09-11 14:22:47 +02:00
Frank 4b4c9ba959 Merge branch 'master' into develop 2022-09-11 13:38:40 +02:00
Frank 994a36001f Merge pull request #1782 from FlightControl-Master/FF/MasterDevel
Updates from develop
2022-09-11 13:38:00 +02:00
Frank 26b91e3f66 Updates from develop
DCS.lua
Ops/ATIS.lua
Ops/RecoveryTanker.lua
Utilities/Enums.lua
2022-09-11 13:32:57 +02:00
Applevangelist 6bf05741a9 Merge remote-tracking branch 'origin/master' into develop 2022-09-10 15:16:47 +02:00
Applevangelist 5d1998accb #CONTROLLABLE
*Foreign class definiton removed
2022-09-10 15:14:41 +02:00
Applevangelist f42aedd485 #CONTROLLABLE
*Foreign class definiton removed
2022-09-10 15:14:28 +02:00
Applevangelist 3aa9ffc241 #MODULES
* ordered list
2022-09-10 12:54:37 +02:00
Applevangelist 8ab5575e0a Merge remote-tracking branch 'origin/master' into develop
# Conflicts:
#	Moose Development/Moose/Modules.lua
#	Moose Setup/Moose.files
2022-09-10 12:19:23 +02:00
Applevangelist a73818a615 #BUILD files 2022-09-10 12:08:30 +02:00
Applevangelist 7c22e9fe69 #Changes from Develop 2022-09-10 11:56:03 +02:00
Applevangelist c58e91b956 #TASKING
* Merge changes from Develop
2022-09-10 11:41:41 +02:00
Applevangelist a61059242c #AI
* Merge changes from DEV
2022-09-10 11:38:50 +02:00
Applevangelist 3980b8a9c8 Merge remote-tracking branch 'origin/master' into develop 2022-09-10 11:34:56 +02:00
Thomas 27550d7ec9 Merge changes from master into dev for GROUP (#1781)
* #GROUP
* changes from Dev
#UNIT
* changes from Dev

* #GROUP
Fix GetSpeedMax() always returns zero
2022-09-09 17:50:18 +02:00
Applevangelist cea9437e66 #GROUP
Fix GetSpeedMax() always returns zero
2022-09-09 17:33:23 +02:00
Thomas 35513e1e21 #GROUP (#1779)
* changes from Dev
#UNIT
* changes from Dev
2022-09-08 16:10:38 +02:00
Applevangelist 3f052ef1da #GROUP
* changes from Dev
#UNIT
* changes from Dev
2022-09-08 15:49:58 +02:00
Applevangelist 15496aed44 Merge remote-tracking branch 'origin/Apple/Develop' into develop
# Conflicts:
#	Moose Development/Moose/Functional/Autolase.lua
2022-09-08 11:58:29 +02:00
Applevangelist 27408c191d #AUTOLASE
* Added option for blacklist atttributes
* Added higher priority for radar units
* Removed the "#001-01" appendix of spawned Recce on messages
2022-09-08 11:55:29 +02:00
Applevangelist 4b6c6717ad #Autolase
* SetMinThreatLevel
2022-09-08 09:11:26 +02:00
Applevangelist c0bc3d8061 Merge remote-tracking branch 'origin/develop' into develop 2022-09-08 08:45:16 +02:00
Thomas fe5f252bc9 Update Autolase.lua (#1778) 2022-09-07 15:22:00 +02:00
Applevangelist e25af085fc Merge remote-tracking branch 'origin/master' into develop
# Conflicts:
#	Moose Development/Moose/AI/AI_A2A_Dispatcher.lua
#	Moose Development/Moose/AI/AI_A2G_Dispatcher.lua
#	Moose Development/Moose/AI/AI_CAP.lua
#	Moose Development/Moose/AI/AI_CAS.lua
#	Moose Development/Moose/AI/AI_Patrol.lua
#	Moose Development/Moose/Core/Base.lua
#	Moose Development/Moose/Core/Beacon.lua
#	Moose Development/Moose/Core/Database.lua
#	Moose Development/Moose/Core/Fsm.lua
#	Moose Development/Moose/Core/MarkerOps_Base.lua
#	Moose Development/Moose/Core/Menu.lua
#	Moose Development/Moose/Core/Message.lua
#	Moose Development/Moose/Core/Point.lua
#	Moose Development/Moose/Core/ScheduleDispatcher.lua
#	Moose Development/Moose/Core/Scheduler.lua
#	Moose Development/Moose/Core/Set.lua
#	Moose Development/Moose/Core/Spawn.lua
#	Moose Development/Moose/Core/Zone.lua
#	Moose Development/Moose/DCS.lua
#	Moose Development/Moose/Functional/Detection.lua
#	Moose Development/Moose/Functional/Mantis.lua
#	Moose Development/Moose/Functional/Range.lua
#	Moose Development/Moose/Functional/Scoring.lua
#	Moose Development/Moose/Functional/Sead.lua
#	Moose Development/Moose/Modules.lua
#	Moose Development/Moose/Ops/ATIS.lua
#	Moose Development/Moose/Ops/Airboss.lua
#	Moose Development/Moose/Sound/UserSound.lua
#	Moose Development/Moose/Utilities/Enums.lua
#	Moose Development/Moose/Utilities/FiFo.lua
#	Moose Development/Moose/Utilities/Profiler.lua
#	Moose Development/Moose/Utilities/Routines.lua
#	Moose Development/Moose/Utilities/STTS.lua
#	Moose Development/Moose/Utilities/Utils.lua
#	Moose Development/Moose/Wrapper/Airbase.lua
#	Moose Development/Moose/Wrapper/Controllable.lua
#	Moose Development/Moose/Wrapper/Group.lua
#	Moose Development/Moose/Wrapper/Marker.lua
#	Moose Development/Moose/Wrapper/Positionable.lua
#	Moose Development/Moose/Wrapper/Unit.lua
#	Moose Setup/Moose.files
2022-09-06 13:51:59 +02:00
Applevangelist c137a4b06d Revert "#ZONE"
This reverts commit 1207417894.
2022-09-06 13:18:22 +02:00
Applevangelist 6c46dafc59 Revert "Auxiliary commit to revert individual files from 1207417894a369fa4a353ca0a1f6120c2fc32666"
This reverts commit 551d4a9c85c89e4aaad2c59ed058c84ff8c7ad6c.
2022-09-06 13:16:40 +02:00
Applevangelist 1207417894 #ZONE
* ZONE_ELASTIC
* Typo
2022-09-06 11:17:50 +02:00
Applevangelist 400da676fa UTILS 2022-09-06 10:48:37 +02:00
Applevangelist bf9f02e53a DATABASE 2022-09-06 10:47:33 +02:00
Applevangelist a437da76ec Merge remote-tracking branch 'origin/Apple/Develop' into develop
# Conflicts:
#	Moose Development/Moose/Core/Database.lua
#	Moose Development/Moose/Core/Set.lua
#	Moose Development/Moose/Utilities/Profiler.lua
2022-09-06 10:43:48 +02:00
Applevangelist 8cceee49ea Merge remote-tracking branch 'origin/master' into develop
# Conflicts:
#	Moose Development/Moose/AI/AI_A2A_Dispatcher.lua
#	Moose Development/Moose/AI/AI_A2G_Dispatcher.lua
#	Moose Development/Moose/AI/AI_CAP.lua
#	Moose Development/Moose/AI/AI_CAS.lua
#	Moose Development/Moose/AI/AI_Patrol.lua
#	Moose Development/Moose/Core/Base.lua
#	Moose Development/Moose/Core/Beacon.lua
#	Moose Development/Moose/Core/Database.lua
#	Moose Development/Moose/Core/Fsm.lua
#	Moose Development/Moose/Core/MarkerOps_Base.lua
#	Moose Development/Moose/Core/Menu.lua
#	Moose Development/Moose/Core/Message.lua
#	Moose Development/Moose/Core/Point.lua
#	Moose Development/Moose/Core/ScheduleDispatcher.lua
#	Moose Development/Moose/Core/Scheduler.lua
#	Moose Development/Moose/Core/Set.lua
#	Moose Development/Moose/Core/Spawn.lua
#	Moose Development/Moose/Core/Zone.lua
#	Moose Development/Moose/DCS.lua
#	Moose Development/Moose/Functional/Detection.lua
#	Moose Development/Moose/Functional/Mantis.lua
#	Moose Development/Moose/Functional/Range.lua
#	Moose Development/Moose/Functional/Scoring.lua
#	Moose Development/Moose/Functional/Sead.lua
#	Moose Development/Moose/Modules.lua
#	Moose Development/Moose/Ops/ATIS.lua
#	Moose Development/Moose/Ops/Airboss.lua
#	Moose Development/Moose/Sound/UserSound.lua
#	Moose Development/Moose/Utilities/Enums.lua
#	Moose Development/Moose/Utilities/FiFo.lua
#	Moose Development/Moose/Utilities/Profiler.lua
#	Moose Development/Moose/Utilities/Routines.lua
#	Moose Development/Moose/Utilities/STTS.lua
#	Moose Development/Moose/Utilities/Utils.lua
#	Moose Development/Moose/Wrapper/Airbase.lua
#	Moose Development/Moose/Wrapper/Controllable.lua
#	Moose Development/Moose/Wrapper/Group.lua
#	Moose Development/Moose/Wrapper/Marker.lua
#	Moose Development/Moose/Wrapper/Positionable.lua
#	Moose Development/Moose/Wrapper/Unit.lua
#	Moose Setup/Moose.files
2022-09-06 10:27:28 +02:00
Applevangelist 34ff03936a Merge remote-tracking branch 'origin/master' into develop
# Conflicts:
#	Moose Development/Moose/AI/AI_A2A_Dispatcher.lua
#	Moose Development/Moose/AI/AI_A2G_Dispatcher.lua
#	Moose Development/Moose/AI/AI_CAP.lua
#	Moose Development/Moose/AI/AI_CAS.lua
#	Moose Development/Moose/AI/AI_Patrol.lua
#	Moose Development/Moose/Core/Base.lua
#	Moose Development/Moose/Core/Beacon.lua
#	Moose Development/Moose/Core/Database.lua
#	Moose Development/Moose/Core/Fsm.lua
#	Moose Development/Moose/Core/MarkerOps_Base.lua
#	Moose Development/Moose/Core/Menu.lua
#	Moose Development/Moose/Core/Message.lua
#	Moose Development/Moose/Core/Point.lua
#	Moose Development/Moose/Core/ScheduleDispatcher.lua
#	Moose Development/Moose/Core/Scheduler.lua
#	Moose Development/Moose/Core/Set.lua
#	Moose Development/Moose/Core/Spawn.lua
#	Moose Development/Moose/Core/Zone.lua
#	Moose Development/Moose/DCS.lua
#	Moose Development/Moose/Functional/Detection.lua
#	Moose Development/Moose/Functional/Mantis.lua
#	Moose Development/Moose/Functional/Range.lua
#	Moose Development/Moose/Functional/Scoring.lua
#	Moose Development/Moose/Functional/Sead.lua
#	Moose Development/Moose/Modules.lua
#	Moose Development/Moose/Ops/ATIS.lua
#	Moose Development/Moose/Ops/Airboss.lua
#	Moose Development/Moose/Sound/UserSound.lua
#	Moose Development/Moose/Utilities/Enums.lua
#	Moose Development/Moose/Utilities/FiFo.lua
#	Moose Development/Moose/Utilities/Profiler.lua
#	Moose Development/Moose/Utilities/Routines.lua
#	Moose Development/Moose/Utilities/STTS.lua
#	Moose Development/Moose/Utilities/Utils.lua
#	Moose Development/Moose/Wrapper/Airbase.lua
#	Moose Development/Moose/Wrapper/Controllable.lua
#	Moose Development/Moose/Wrapper/Group.lua
#	Moose Development/Moose/Wrapper/Marker.lua
#	Moose Development/Moose/Wrapper/Positionable.lua
#	Moose Development/Moose/Wrapper/Unit.lua
#	Moose Setup/Moose.files
2022-09-06 09:53:22 +02:00
Thomas bf3ee93c23 Update PlayerTask.lua (#1777) 2022-09-05 06:14:58 +02:00
Frank a3260b4ce3 Merge pull request #1776 from FlightControl-Master/FF/Ops
OPS
2022-09-04 21:04:59 +02:00
Frank ea8cf7b62a OPS
**OPSZONE**
- Added `:SetTimeCapture()` function to set time interval until a zone is captured.

**FLIGHTCONTROL**
- Added coalition to tower and pilot msrs.
2022-09-04 21:01:32 +02:00
Applevangelist 7168681918 #PLAYERTASKCONTROLLER
* Delay auto-start between 5 to 10 secs

#ATIS
* Add label to SRS
2022-09-04 14:48:06 +02:00
Applevangelist 233291b30c #AWACS
* added option for AWACS to send messages on multiple frequencies
2022-09-04 12:19:06 +02:00
Applevangelist e53ff167ee #PLAYERTASKCONTROLLER
* Menu build changed slightly to delayed
2022-09-03 16:28:32 +02:00
dogjutsu df54d09494 Fix usage example comment for ZONE_BASE:GetProperty() (#1775)
* Fixed some typos of forms of the word 'strategy'.

* Fix ZONE_BASE:GetProperty() usage example comment

Co-authored-by: dogjutsu <dogjutsu@mattjay.net>
2022-09-02 18:28:18 +02:00
Applevangelist 4aa3edc508 Errors
added docu
2022-09-02 17:01:39 +02:00
Applevangelist 4ea1b93f8d #PLAYERTASKCONTROLLER
* All map markers to be deleteable
2022-09-02 16:32:29 +02:00
Applevangelist 361ca2cece #MARKEROPS
* Added option to enforce case sensitive matches on Tagname

#PLAYERTASKCONTROLLER
* Text tweaking
* Fixed "mark on map" not showing subtitles
* Revamped menu build to have less rebuilds
* Added option to show additional info menu for tasks before joining
2022-09-02 13:12:52 +02:00
dogjutsu fa0d076a09 Dogjutsu/develop/feature/zone properties (#1774)
* Fixed some typos of forms of the word 'strategy'.

* Retrieve Zone 'properties' with ZONE_BASE.

* Extraneous comment cleanup.

Co-authored-by: dogjutsu <dogjutsu@mattjay.net>
2022-09-02 06:19:50 +02:00
Frank da5a1e0945 Merge pull request #1773 from FlightControl-Master/FF/Ops
Update Socket.lua
2022-09-01 23:50:04 +02:00
Frank 6d187f0d9a Update Socket.lua 2022-09-01 23:44:45 +02:00
Frank 7c717c219c Merge pull request #1771 from grandpaSam/master
Updated CARGO tag documentation
2022-09-01 22:54:22 +02:00
Frank 85eca4c464 Merge pull request #1772 from FlightControl-Master/FF/Ops
SOCKET
2022-09-01 22:44:43 +02:00
Frank 1efbce7661 Update Airboss.lua
- Removed output
2022-09-01 22:37:31 +02:00
Frank edf69d1ef1 Removed
Removed MOOSE_INCLUDE subdirectory
2022-09-01 22:34:48 +02:00
Frank 375e7db449 Merge branch 'develop' into FF/Ops 2022-09-01 22:31:52 +02:00
Frank ac71e38d96 FunkMan
**RANGE**
- Changed keyword in result tables to "command" for compatibility with DCSServerBot

**AIRBOSS**
- Changed keyword in result tables to "command" for compatibility with DCSServerBot
- Fix bug in Alt and AoA data round function when creating trapsheet data

**SOCKET**
- Changed for compatibility with DCSServerBot
2022-09-01 22:27:25 +02:00
grandpaSam a9fad53255 Updated CARGO tag documentation
The documentation for the CARGO tag on static objects omitted a required C= parameter. Without this parameter the database will not register the static as a CARGO object
2022-09-01 11:49:46 -07:00
Applevangelist ae5fd91cd4 #PLAYERTASK
* Fix to avoid double failed messages
2022-09-01 15:50:35 +02:00
Applevangelist 14e8b2ef17 #PLAYERTASK
* Added logging Errors and Documentation for trying to set zones before set up of detection
2022-09-01 09:22:18 +02:00
Applevangelist 372cc021bd UNIT - added optical tracker to HasSEAD() 2022-09-01 08:36:40 +02:00
Applevangelist 5bacea8b50 UNIT - added optical tracker to HasSEAD() 2022-09-01 08:36:21 +02:00
Applevangelist 15dff87200 #GROUP
* Added Optical Tracker to ID SAMs, corrected logic error in ID'ing SAMs

#PLAYERTASKCONTROLLER
* Added documentation in MarkerOps
* Corrected Cluster radius to be in KM
* Corrected set up of SEAD attribute table to work
2022-09-01 08:07:40 +02:00
Applevangelist 6820774266 GROUP - added optical tracker to ID SAMs 2022-09-01 08:03:53 +02:00
Applevangelist a0c189a349 UTILS - added NDB 305kHz in frequency generator 2022-08-31 18:11:55 +02:00
Applevangelist ae45c77523 UTILS - added NDB 305kHz in frequency generator 2022-08-31 18:10:57 +02:00
Applevangelist 1060ff16d8 GROUP - Attributes aligned to dev 2022-08-31 17:40:44 +02:00
Applevangelist 7c834993f6 Slight change of attack order 2022-08-31 17:40:15 +02:00
Applevangelist 5f5749ac8f bugfix 2022-08-31 17:32:41 +02:00
Thomas c99a7b6666 PlayerTaskController - SEAD attributes configure (#1769)
Making SEAD attributes for the task decision tree configure-able. Added ` PLAYERTASKCONTROLLER:SetSEADAttributes(Attributes)`
2022-08-31 16:57:20 +02:00
Applevangelist 1255f48645 Update Moose.files 2022-08-30 14:38:36 +02:00
Applevangelist 7ef69208d4 #ZONE_RADIUS
* Added `ZONE_RADIUS:GetRandomCoordinateWithoutBuildings(...)`

#MARKEROPS_BASE
* Added Class
2022-08-30 14:36:42 +02:00
Applevangelist b4e2d3edfe #ZONE
* Added `ZONE_RADIUS:GetRandomCoordinateWithoutBuildings(...)`

#MARKEROPS
* Some documentation improvement

#PLAYTASKCONTROLLER
* Added `PLAYERTASKCONTROLLER:EnableMarkerOps(Tag)`

#OPSGROUP
* Changed offset to 2m for lasing ground units

*AUFTRAG
* Documentation correction `NewARMOREDGUARD`
2022-08-30 14:29:41 +02:00
Frank 8f9308f349 Update Airboss.lua 2022-08-29 23:10:12 +02:00
Frank fc48473e40 Merge branch 'develop' into FF/Ops 2022-08-29 00:37:34 +02:00
Frank 71317db4cb FunkMan
**SOCKET**
- Changed port to 10042.
- Removed port as optional parameter in functions.

**AIRBOSS**
- Added FunkMan function
- Added onAfterLSOGrade which sends results table to socket

**RANGE**
- Compat to FunkMan.
2022-08-29 00:37:21 +02:00
Applevangelist 23815429e2 #PLAYERTASK
* remove two filters for task state where they do not belong
2022-08-27 18:26:04 +02:00
Applevangelist b468134432 #PLAYERTASK
* Remove filtering for task state preventing further players to join
2022-08-27 16:05:47 +02:00
Applevangelist 3e38db16f6 #PLAYERTASK
* Added option to use ArmyGroup as lasing unit
* Added TTS output to task info report for PRECISIONBOMBING to tell if unit is in reach and is lasing
2022-08-26 18:46:07 +02:00
Applevangelist bf591cc01e #RANGE
* Minor updates

#AWACS
* Added localisation
2022-08-26 14:23:55 +02:00
Applevangelist 5277cca4e1 Range fix issue #1753 (#1767)
Issue #1753 - when using `AddBombingTargets` the randommove flag was not passed to `AddBombingTargetUnit` for a group object
2022-08-25 16:00:47 +02:00
Applevangelist 3178cbc563 #RANGE
- fix for #1753
2022-08-25 16:00:03 +02:00
Applevangelist 1c54f6b2f4 #AUTOLASE
* Fix for "self" error after start
2022-08-25 13:28:20 +02:00
Applevangelist 7743456d7d #PLAYERTASK
* Short playername usage for broadcast
2022-08-25 12:10:20 +02:00
Applevangelist 4dc43263a5 usage correction 2022-08-25 11:41:27 +02:00
Applevangelist aaf77815ca #SRS
* Added MSRSQUEUE message queue
2022-08-25 10:50:45 +02:00
Applevangelist 3f488cc091 #AIRBASE
* Added 3 new airports to the enumerator SouthAtlantic
2022-08-25 10:38:44 +02:00
Applevangelist 5d84f1c523 #AIRBASE
* Added 3 new airports to the enumerator
2022-08-25 10:38:04 +02:00
Applevangelist 8289ebbe50 #PLAYERTASK
* added coalition check to event handler
2022-08-25 09:44:45 +02:00
Applevangelist 94741f1b4a #PLAYERTASK
* Added precision bombing option

#AUTOLASE
* Added "nomenu" option

#MENU_GROUP
* Added MENU_GROUP:RefreshAndOrderByTag()
2022-08-24 19:22:33 +02:00
Applevangelist a5b394aa93 #AWACS
- added docu on PikesSpecialSwitch
- added option to read callsign from playername
2022-08-23 12:44:42 +02:00
Applevangelist bdbbdfe60e #RANGE
* Added Instructor and RangeControl radio info on F10
2022-08-23 09:58:50 +02:00
Applevangelist 9f3d152d8c #AWACS
* Fixed logic for CallSignTranslations which now applies to both AI and Players, a set overwrite in the group name for a player still takes precedence.
* Added a switch self.PikesSpecialSwitch to omit "doing xy knots" from the station assignment
2022-08-23 09:58:06 +02:00
Applevangelist 94c91614d6 #Range
* Fix F10 Sheet
* Fix Typos
2022-08-22 17:28:01 +02:00
Applevangelist 02a59b0742 #UTILS
* Fix for GetOSTime
2022-08-22 17:05:02 +02:00
Applevangelist d15c2be2d0 Range fixes (#1764)
* Fixed some typos in self.PlayerSettings
* Fixed result messages
* Thanks for [JFG] Caponi
2022-08-22 17:03:33 +02:00
Applevangelist 73994914eb Fix for #1763 UTILS.GetOSTime() (#1765)
* Fix GetOSTime fixes #1763
2022-08-22 17:03:21 +02:00
Applevangelist 63b0dae794 Update ATC_Ground.lua (#1766)
* Make ATC_Ground work on any map
2022-08-22 17:03:02 +02:00
Applevangelist 882c2e2378 #ATC_GROUND
* Added universally working ATC_GROUND_UNIVERSAL as base class, can be used on any map without further changes
* Kept sub-class names for compatibility
* Added `:SetAirbaseBoundaries(Airbase, Zone)`
* Added `:DrawBoundaries( Color )`
2022-08-21 19:46:01 +02:00
Applevangelist f6b56735b6 #PLAYERTASK
* Speak "BR" as "Bee, Arr"
2022-08-20 09:45:09 +02:00
Applevangelist 8aec463eb4 #PLAYERTASK
* Some changes to SRS call order, documentation
2022-08-20 09:24:52 +02:00
Applevangelist 37cdcf93e6 #PLAYERTASK
* Demo mission link added
2022-08-19 10:34:36 +02:00
Applevangelist 9547a06f39 #PLAYERTASK
* Slight text change for TASKADDED
2022-08-19 08:12:06 +02:00
Applevangelist a8d5d2ace1 fix typos 2022-08-18 18:24:37 +02:00
Applevangelist e8a0464f6c Docu corrections 2022-08-18 18:19:27 +02:00
Applevangelist 85a39e64c1 #PLAYERTASKCONTROLLER
* Own picture for header
* Some docu additions
2022-08-18 18:06:41 +02:00
Applevangelist e18cf759f9 #PLAYERTASKCONTROLLER
* Add'l docu
2022-08-18 16:43:39 +02:00
Applevangelist 7e1ab1e6b0 #PLAYERTASKCONTROLLER
* Added base documentation
2022-08-18 16:01:34 +02:00
Frank eed74d72cd SOCKEt
- Added new SOCKET class
- Fixed bug in RANGE that self.PlayerSetti**n**gs was misspelled.
2022-08-18 01:33:09 +02:00
Applevangelist fa8c96af13 #AUTOLASE
* Update SRS stuff

#PLAYERTASKCONTROLLER
* Fix SRS to actually use Gender, Culture, Voice, Port
2022-08-17 17:33:29 +02:00
Applevangelist 18ec2ff458 #PLAYERTASK
* Corrected usage example on `SetTaskWhiteList()`
* Mark on map will add some basic info text
2022-08-17 16:23:37 +02:00
Applevangelist c38a737421 #PLAYERTASK
* Added option to whitelist task types
* Added localization. Contains "en" and "de" texts and tts texts
2022-08-17 15:38:20 +02:00
Applevangelist 0166b53e21 #PLAYERTASKCONTROLLER
* Added option to suppress screen output
* Added target information via SRS
* Added target radius for BAI vs CAS and target type COORDINATE to be configureable
* Refined SRS output
* Added STATIC targets to get task type BOMBING
* Added solution to detect bombing runways (kind of, bombing occuring in AFB zone)
* Added solution for COORDINATE and ZONE type TARGETs (find enemy GROUP and/or STATIC objects in target radius)
* Refined documentation
2022-08-16 16:48:13 +02:00
Applevangelist 724da4e500 #PLAYERTASKCONTROLLER
* Added Accept and Reject Zones to detection
* Added SRS Stuff
* Tasks sorted by priority
2022-08-15 19:07:05 +02:00
Applevangelist ce15e8dfe0 #PLAYERTASKCONTROLLER
* Set menu name
* Better menu buildup and refresh
2022-08-15 13:11:09 +02:00
Engines 003e865ff7 Late break bug (#1762)
* Quick update to Airboss.lua to inluce Invincible.  Not yet tested.

* Initial quick test and calibration of the landing spot; looks good.  More testing required.

* Recompiled the Moose.lua based off the last commit.

* Removing surpurflous Moose.lua for pull request.

* There was an error with the late break paratemers on the Brit carriers causing pilots to be thrown off the pattern on the break.  Fixed, tested on Invicible, working as anticipated now.

* Removing the test Moose.lua (again).

* Fixing merge confilict

* Trying again.
2022-08-15 07:15:15 +02:00
Applevangelist b968d0d694 #PLAYERTASKCONTROLLER
* Added detection setup
* Added number of joined players in join task overview, and a star when it's new
2022-08-14 16:50:57 +02:00
Gavin Edwards e3c03287b7 Engines invincible (#1758)
* Quick update to Airboss.lua to inluce Invincible.  Not yet tested.

* Initial quick test and calibration of the landing spot; looks good.  More testing required.

* Recompiled the Moose.lua based off the last commit.

* Removing surpurflous Moose.lua for pull request.
2022-08-13 21:40:53 +02:00
Frank fa0549f34f Merge pull request #1756 from FlightControl-Master/FF/Ops
Update Airboss.lua
2022-08-04 22:13:18 +02:00
Frank 999ef36963 Update Airboss.lua
#1755
2022-08-04 21:18:38 +02:00
Frank 7affd05247 Merge pull request #1754 from FlightControl-Master/FF/Ops
Updates
2022-08-03 09:14:12 +02:00
Frank 2ccf4011ed Merge branch 'develop' into FF/Ops 2022-08-03 09:12:32 +02:00
Frank 61f3908d33 Updates
**AIRBOSS**
- Stennis now takes dimensions of other super carriers

**FLIGHTCONTROL**
- Added queue for sounds
- Fixed bugs and minor improvements

**ZONE**
- Added defaults when getting colors if not set

**SRS**
- Added new class `MSRSQUEUE`
2022-08-03 09:12:22 +02:00
Applevangelist 73493c3a23 Update Unit.lua (#1751) 2022-07-31 09:17:36 +02:00
Applevangelist 08e429210a Update Unit.lua 2022-07-31 09:16:46 +02:00
Frank f94944c41a Merge pull request #1750 from FlightControl-Master/FF/Ops
ZONE
2022-07-31 01:16:55 +02:00
Frank 200631e57e Merge branch 'develop' into FF/Ops 2022-07-31 01:13:53 +02:00
Frank 9c83d5e752 ZONE
- Added new class `ZONE_ELASTIC`
2022-07-31 01:13:42 +02:00
Applevangelist 894bff2e35 PLAYERTASK - added list of pilots to TaskInfo 2022-07-30 12:26:29 +02:00
Applevangelist 6ff0a699c0 #PLAYERTASKCONTROLLER
* Added Event handling stuff in case client leaves/ejects/dies
* A2A - removed menus for smoke/flare
* Task menu entries now refreshed more intelligently
* Added `PLAYERTASKCONTROLLER:OnAfterTaskAdded(From, Event, To, Task)`
2022-07-30 12:06:11 +02:00
Frank 5083428a06 Merge branch 'develop' into FF/Ops 2022-07-30 01:24:52 +02:00
Applevangelist c74a14fcb0 PLAYERTASK - debugging 2022-07-29 15:31:56 +02:00
Applevangelist d060c7535a PLAYERTASK - added a couple of FSM events so task events bubble up to the controller 2022-07-29 14:53:23 +02:00
Applevangelist 5eb134f7b5 PLAYERTASK - Additions 2022-07-29 14:14:22 +02:00
Applevangelist c1c5117f01 Update Moose.files (#1749) 2022-07-29 12:25:45 +02:00
Applevangelist 8ce1f5884f PlayerTask Beta 2022-07-29 12:24:36 +02:00
Applevangelist 562a3f6208 SET - fix for dead units 2022-07-29 08:51:23 +02:00
Applevangelist 1f8b51fafe SET - fix for dead units 2022-07-29 08:51:00 +02:00
Applevangelist 80f73f0bb1 AUTOLASE - added per player settings observance, also 2022-07-27 19:41:20 +02:00
Applevangelist 88e7b3fb47 AUTOLASE - observe global _SETTINGS for coordinates 2022-07-27 19:28:36 +02:00
Frank 3bb36044c1 OPS
- Added check that cohorts cannot have the same name.
- Made clearer that cohorts cannot have the same name in the docs.
2022-07-25 22:45:43 +02:00
Applevangelist 3c5f3d6c37 UNIT - added get altitude function with AGL option 2022-07-25 08:12:28 +02:00
Applevangelist f9ace54fab UNIT - added get altitude function with AGL option 2022-07-25 08:12:10 +02:00
Applevangelist 498d7e2f66 Airbase - added 2 AFB to SA map 2022-07-22 11:02:08 +02:00
Frank 420526df9d Merge pull request #1747 from FlightControl-Master/FF/Ops
OPS
2022-07-20 22:58:57 +02:00
Frank ab00d9534d Merge branch 'develop' into FF/Ops 2022-07-20 22:21:17 +02:00
Frank 4bb9073ce1 OPS
- Increased selection score for GCICAP/INTERCEPT
2022-07-20 22:20:26 +02:00
Applevangelist 58cb0118b4 AWACS - added option for custom TTS callsigns 2022-07-19 09:34:40 +02:00
Applevangelist f19740e376 Beacon - added deactivate Link4 2022-07-19 08:30:09 +02:00
Applevangelist ab50d0a514 Controllable/Beacon - added function to switch on Link4
A2A - typo in documentation
2022-07-19 08:10:35 +02:00
Frank e551212516 Merge branch 'develop' into FF/OpsDev 2022-07-18 23:00:01 +02:00
Frank 888734b7d1 OPS
- Fixed bug in parking spot distance for ships.
- Added enroute  anti-ship task for anti-ship missions.
2022-07-18 22:59:49 +02:00
Applevangelist 90d1a01998 AWACS - delete open tasks on player leaving unit 2022-07-14 14:06:20 +02:00
Anthony De Vellis ab1dd2b374 AWACS - Tweaked escort logic to use one AUFTRAG per escort fighter and tweaked positioning logic. Allows more control over escort fighters which will support a future PR (#1746) 2022-07-12 08:18:47 +02:00
Anthony De Vellis 0e4d731068 AWACS - added the ability to use custom callsigns with TTS/messaging (#1745)
* AWACS - added the ability to use custom callsigns with TTS. Revised section 5.1 of documentation to demonstrate

* AWACS - Added nil check to callsign construction when looking for replacement
2022-07-12 08:13:24 +02:00
Frank f23416dfb8 Merge branch 'develop' into FF/OpsDev 2022-07-11 23:23:11 +02:00
Frank 469cc3d508 OPS
CHIEF: SetResponseOnTarget
TRANSPORT: improved transfer of loaded cargo
2022-07-11 23:22:58 +02:00
Applevangelist 5ad88be997 AWACS - change setup as TACS slightly 2022-07-09 15:34:08 +02:00
Applevangelist 536341b6de AWACS allow startasgci to process a string instead of a GROUP 2022-07-09 15:02:14 +02:00
Applevangelist 18dcd0a5d2 AWACS - some additions 2022-07-09 14:52:49 +02:00
Applevangelist 5f8a0643f4 AWACS - added GCI plane-less option 2022-07-07 17:55:35 +02:00
Applevangelist ccbf8b34ef Fix for #1736 2022-07-07 08:51:28 +02:00
Applevangelist 25915c077e Various fixes 2022-07-07 08:47:43 +02:00
Frank bcb574e618 Merge branch 'develop' into FF/OpsDev 2022-07-01 23:19:02 +02:00
Frank 6cfa24340f Update Range.lua
- Fixed bug in strafing runs
2022-07-01 23:10:10 +02:00
Frank 0dc26216c2 OPS 2022-07-01 23:00:25 +02:00
Frank 8dd850d685 OPS Operation 2022-06-29 22:25:08 +02:00
Frank 638f261bf4 OPS
- Improved FLIGHTCONTROL and minor other classes
2022-06-28 18:55:43 +02:00
Applevangelist ad5a0a5cd9 CSAR - hand back descriptive name as 3rd parameter on event Boarded() 2022-06-25 17:24:37 +02:00
Applevangelist 7dda54f36d UTILS - Fix for Gazelle Door Check 2022-06-25 14:28:04 +02:00
Frank a8477940e2 Merge branch 'FF/Ops' into FF/OpsDev 2022-06-21 16:15:03 +02:00
Frank 6a26f62ca1 Merge branch 'develop' into FF/Ops 2022-06-21 16:14:31 +02:00
Frank 06d0bfadca FLIGHTCONTROL v0.6.0 2022-06-21 16:08:46 +02:00
Applevangelist b805d7fe19 CSAR - fix for oncrash 2022-06-16 15:42:13 +02:00
Applevangelist b784671397 CSAR - added event for "Landed" at a friendly/neutral AFB. Fixed Airbase rescue. 2022-06-16 13:40:35 +02:00
Applevangelist 4784a31513 UTILS - Falklands additions 2022-06-14 17:20:12 +02:00
Applevangelist 3eb9bfe9ee COORDINATE - additions to BRAANATO
AWACS - make bogey dope use the priority queue to avoid collisions. Say "very low" and not "zero thousand", drop "vanished" if not tags is requested
2022-06-14 13:08:18 +02:00
Applevangelist ab31aecdac CSAR - some fixes for latest open beta 2022-06-14 12:37:56 +02:00
Applevangelist 5cb2bd1332 Update Beacon.lua 2022-06-13 15:41:19 +02:00
Applevangelist 8bff9efc5c Beacon - update docs (#1733)
Updated docs to point to ActivateTacan as better option to AAATACAN
2022-06-13 15:21:50 +02:00
Applevangelist d01360ca19 CSAR - Put wounded group back into status green, so they run to the chopper 2022-06-12 12:47:10 +02:00
Applevangelist f48c71f30c AWACS - Added option to use marker to create, move and delete a player station 2022-06-10 11:56:19 +02:00
Applevangelist a2b3190b1d More docu 2022-06-09 12:12:45 +02:00
Applevangelist 913d5a532d CTLD - further documentation 2022-06-09 11:46:17 +02:00
Applevangelist 96c6c372fd Added documentation for CTLD_HERCULES 2022-06-09 10:56:33 +02:00
Frank 8926e06e44 Runways
**AIRBASE**
- Runways are now retrieved from DCS API function
2022-06-08 23:42:17 +02:00
Applevangelist 6636e89a0b AIRBASE added South Atlantic 2022-06-08 20:24:31 +02:00
Applevangelist 01e9e83641 AWACS - PlayerGuidance makes picture calls refer to asking player BRA, delete contact engagement label on checking out 2022-06-07 11:30:20 +02:00
Applevangelist 30dc338636 CSAR - added a couple of more lines to go out via TTS 2022-06-07 08:56:25 +02:00
Applevangelist d4999de214 CSAR - added options to use Google TTS 2022-06-07 08:12:57 +02:00
Frank a53595a055 OPS
Enhanced OPERATION and FLIGHTCONTROL features.
2022-06-06 22:05:57 +02:00
Applevangelist 0cb7415a4c AWACS -- enforce EPLRS 2022-06-05 18:03:39 +02:00
Applevangelist 9f287d0d7f AWACS 0.1.27
* Added options for NoMissileCals and PlayerCapAssignment
* Added documentation on options
2022-06-04 13:56:57 +02:00
Applevangelist feddda2948 AWACS - added docu for speech queue padding options 2022-06-03 14:42:08 +02:00
Applevangelist 613b7eda8a AWACS 0.1.26 - corrected player picture call to use B/E references, bogey dope to announce only one group. ZipLip will also remove group tags. 2022-06-03 09:27:01 +02:00
Applevangelist bd3364a3cf AWACS - limit merge calls 2022-06-02 17:39:39 +02:00
Applevangelist 3f918bd309 AWACS 0.1.25
* Added Function ZipLip
* Changed merge distance to 5nm for account for delay in speech generation
* Altered RadioQueue to not save all calls until a player connects
* Some bugfixes
2022-06-02 15:31:03 +02:00
Frank 9b3f2ae3c7 OPS 2022-05-31 22:54:37 +02:00
Applevangelist 6c33c5701f Awacs 2022-05-31 16:21:19 +02:00
Applevangelist e731fe9b98 AWACS 0.1.24 - Added merge call, google now says "zero" not "oh", aligned some callouts to more realistic versions, bulls related calls without aspect now. 2022-05-31 14:02:14 +02:00
Frank edbfa9117d OPS
- Added new **CONDITION** class
- Added new **OPERATION** class
2022-05-30 11:45:56 +02:00
Frank ae54cd8fde OPS
** ARMYGROUP**
- Added suppression option

**COMMANDER**
- Added function to add targets with defined resources

**OPSGROUP**
- Added option to pause multiple missions

**INTEL**
- Fixed bug in cluster calc

**LEGION**
- Added function to get alive opsgroups

**TARGET**
* Added start condition
2022-05-27 22:14:21 +02:00
Applevangelist 91686e252c AWACS FSM Functions Docu 2022-05-24 16:05:04 +02:00
Applevangelist 88d132931e AWACS - Nicefy docs 2022-05-24 14:44:23 +02:00
Applevangelist 4afedcf126 AWACS - added documentation, added option to suppress group tags 2022-05-24 14:04:52 +02:00
Frank d3d815f26a Merge branch 'FF/Ops' into FF/OpsDev 2022-05-23 23:11:37 +02:00
Frank 62725b1930 OPS
**AUFTRAG**
- Added *invisible* and *immortal* options

**TARGET**
- Added `AddResource` function

**OPSGROUP**
- Added *invisible* and *immortal* options

**LEGION**
- Fixed bug in properties requirement

**COMMANDER**
- Added `AddTarget` function (still **WIP**)

**ARMYGROUP**
- Fixed routing bug after teleporting
2022-05-23 23:11:23 +02:00
Frank 06d509b5ac Update Airboss.lua
- Improved Case III entry waypoint
2022-05-22 22:36:43 +02:00
Applevangelist 77aba38625 AWACS - added docu 2022-05-22 17:14:14 +02:00
Applevangelist ce33e1d242 AWACS - Options to Draw Zones 2022-05-22 13:03:38 +02:00
Applevangelist 591cf29edf Update README.md 2022-05-22 11:17:20 +02:00
Frank dd81823e29 FC
**FLIGHTCONTROL**
- Less output to dcs log file

**FLIGHTGROUP**
- Added function :SetReadyForTakeoff
2022-05-21 22:25:08 +02:00
Frank 15994e7be8 FC
- Changed holding point to holding pattern or stack
- Replaced MESSAGE by TextMessageToFlight
2022-05-20 20:53:45 +02:00
Frank 61f3b87dae Update Airboss.lua
- Wind is calculated at 15 m (not 50 m)
2022-05-20 20:15:11 +02:00
Frank 6279f1920e FC
**FLIGHTCONTROL**
- Improved menus
- Added more menus
- Improved radio messages overlap
- Added options to limit number of fights taxiing and taking off
2022-05-20 20:08:28 +02:00
Applevangelist d169d60d8d AWACS BETA 0.1.22 - added some QOL functions, corrected standard TOS for AWACS and CAP, now 4 hours. 2022-05-20 19:31:11 +02:00
Applevangelist f49cf43fb1 Awacs - Documentation 2022-05-20 16:19:51 +02:00
Applevangelist aa94ae8759 AWACS moving to beta 1.22 - added documentation, some fixes 2022-05-20 15:51:54 +02:00
Applevangelist 8ad20b57fd TARGET - small typo 2022-05-19 14:41:06 +02:00
Frank 7c4cb5ea7f FC
- Improvements
2022-05-18 12:51:25 +02:00
Frank 23733bb1a6 Merge branch 'FF/Ops' into FF/OpsDev 2022-05-17 23:00:29 +02:00
Frank 5be3f333f3 Merge pull request #1731 from FlightControl-Master/FF/Ops
OPS
2022-05-17 22:53:10 +02:00
Frank b14f3f53aa Merge branch 'develop' into FF/Ops 2022-05-17 22:51:02 +02:00
Frank 47c3fc35e3 OPS
**OPSGROUP**
- Improved routing for ground.

**NAVYGROUP**
- Fixed U-turn of turn into wind

**ARMYGROUP**
- Improved updateroute

**LEGION** and **COMMANDER**
- Set mission range LARGE for relocation mission

**AUFTRAG**
- Fixed bug in Nassets for relocation
2022-05-17 22:50:35 +02:00
Applevangelist 0fd1497496 AWACS 0.0.19 2022-05-15 12:49:36 +02:00
Applevangelist 6c9c983f72 Positionable - added 6 passengers (cargo weight) to Toyota HL/LC new with 2.7.2 OB 2022-05-14 13:11:17 +02:00
Applevangelist 0422eee9af SRS - added hints on using Google with TTS 2022-05-13 16:38:10 +02:00
Frank 97a4b79713 OPS FC
- Improved holding point
2022-05-12 21:19:55 +02:00
Applevangelist 0785ee3099 Point - added option to add an SSML tag to ToStringBRAANATO
AWACS - 0.0.18
2022-05-12 14:48:56 +02:00
Frank d58d04d6a0 Merge branch 'FF/Ops' into FF/OpsDev 2022-05-12 11:04:13 +02:00
Frank 9bb2b17c77 Merge pull request #1730 from FlightControl-Master/FF/Ops
OPS
2022-05-12 10:50:47 +02:00
Frank 64e70d8e92 OPSGROUP
- #1677
- Fixed that damaged is triggered when group is despawned.
- Fixed total ammo calculation when group is dead
- Fixed assets do not carry out patrol zone after transport
2022-05-12 10:49:18 +02:00
Frank 6fa9eb558a Merge branch 'develop' into FF/Ops 2022-05-12 08:03:25 +02:00
Frank ddcc851951 FC
- Improved FC
2022-05-12 08:03:08 +02:00
Applevangelist dc2e5afe3e SRS - put volume in "" - just in case 2022-05-11 07:30:39 +02:00
Applevangelist d8e9997987 SRS - actually pass the volume to the command line 2022-05-11 06:18:48 +02:00
Applevangelist 3d919cd937 AIRBASE - corrected ["Deir_ez_Zor"] = "Deir ez-Zor" (minus doesn't work in enum) 2022-05-10 19:40:44 +02:00
Applevangelist b094c2d78f Correct link to demo missions 2022-05-10 16:17:46 +02:00
Applevangelist 9b699ba374 Update AI_Air.lua 2022-05-10 10:11:25 +02:00
Frank f8e5efc874 Merge branch 'develop' into FF/Ops 2022-05-09 08:41:55 +02:00
Frank 2c61c695d5 Update Chief.lua
- Added target in zone check to abort missions
2022-05-09 08:41:33 +02:00
Frank b6e806adbc Update FlightGroup.lua
-No despawn after player landed.
2022-05-08 00:29:36 +02:00
Applevangelist e74aa160af Group - small change 2022-05-07 19:42:10 +02:00
Clément Fassot 6793228fbe Add an option to display arrows if clusters are moving (#1728) 2022-05-07 15:32:48 +02:00
Applevangelist e83ea8124e GROUP - change to GetUnits(n) to make it more robust, now returns first alive unit,actually. Similar changes to GetHeading() 2022-05-07 11:54:48 +02:00
Frank 313f99d09d OPS
**AUFTRAG**
- Added option to specify mission type for escorts, *e.g.* `AUFTRAG.Type.SEAD`

**LEGION** and **COMMANDER**
- Improved handling of SEAD escorts.
2022-05-06 21:50:23 +02:00
Applevangelist 28de292107 ##AWACS Alpha 0.0.17
* Added RejectZone (foreign border)
* Option to suppress screen output
* Option to add google key in SetSRS
* Some corrections to callouts
* Menu option to show base info
* WIP - Basic player task assignment
2022-05-06 16:36:57 +02:00
Applevangelist 10efb98eb3 Fallout fixes 2022-05-06 11:44:59 +02:00
Applevangelist 8ac2241372 AI Patrol - life check on route 2022-05-06 10:36:51 +02:00
Applevangelist 092434a103 UNIT Register - small fix for trains 2022-05-06 08:01:18 +02:00
Applevangelist a777997f79 AI_CAP - more fallout from the dead units in the API 2022-05-05 17:40:17 +02:00
Applevangelist 36cf7f718b AI_AIR - restrict AB on RTB 2022-05-05 16:41:15 +02:00
Applevangelist 7989267d51 AI/ZONE - Some fixes for units unreachable 2022-05-05 12:08:43 +02:00
Applevangelist ef4398a5f1 SRS - adding volume setting and a test on OS and IO available
OpsGroup - added volume options for `SetSRS`
2022-05-05 11:35:27 +02:00
Applevangelist 0da8afc108 SRS - adding volume setting and a test on OS and IO available 2022-05-05 08:57:15 +02:00
Frank 0e74d36227 Update Range.lua
**RANGE** v2.4.0
- Copy from updated
2022-05-04 22:40:22 +02:00
Applevangelist 290cc151bc SET - further event related stuff not working any more
AWACS - update
2022-05-04 18:10:20 +02:00
Applevangelist 21f93aa7e8 AWACS - 0.0.12 2022-05-04 13:29:14 +02:00
Applevangelist 04c77e9760 Some fixes to make the SpawnScheduled work again 2022-05-04 09:58:30 +02:00
Frank c6da6544da Merge pull request #1725 from FlightControl-Master/FF/Ops
Dead Event
2022-05-04 09:49:37 +02:00
Frank 94d3e38bc7 Merge branch 'develop' into FF/Ops 2022-05-04 09:47:30 +02:00
Frank 5fcf992920 Dead Event
**EVENT**
- Improved handling of delayed dead event

**SPAWN**
- Improved handling of delayed dead event
2022-05-04 09:46:00 +02:00
Frank 22cc9eabc0 Merge pull request #1724 from Ked57/develop
Replace log MESSAGE when updating cluster markers in INTEL with a log
2022-05-03 23:31:15 +02:00
Clément Fassot b191c0d341 Replace log MESSAGE when updating cluster markers in INTEL with a log (#1) 2022-05-03 23:08:26 +02:00
Frank d2d431ce2e OPS (#1723)
**INTEL**
- Added nil check for cluster position update

**OPSGROUP**
- Improved fire at point task to take only max avail shots and relative shot amount
- Fixed tasks not executed after teleport
2022-05-03 09:41:22 +02:00
Frank 3a6b58ea8c Merge branch 'develop' into FF/Ops 2022-05-03 09:25:15 +02:00
Frank 2d8fc40307 OPS
**INTEL**
- Added nil check for cluster position update

**OPSGROUP**
- Improved fire at point task to take only max avail shots and relative shot amount
- Fixed tasks not executed after teleport
2022-05-03 09:23:53 +02:00
Applevangelist 68dce2f247 extra nil checks for dead units 2022-05-03 08:46:23 +02:00
Applevangelist bc03eb2e65 FIFO - FIFO:HasUniqueID(UniqueID)
GROUP - added GROUP:IsPlayer()
INTEL - added clustering by flight deck (10'k ft) for AIR
SET - added option to NOT set the cargo bay weight limit automatically on SET_GROUP:AddGroup( group, DontSetCargoBayLimit )
2022-05-02 17:18:48 +02:00
Frank f725709e5b Merge pull request #1721 from FlightControl-Master/FF/Ops
OPS
2022-04-29 22:02:24 +02:00
Frank ba591c9dc5 OPS
**AUFTRAG**
- Added new type `NOTHING` (similar to `ALERT5` but for ground/naval)
2022-04-29 22:00:23 +02:00
Applevangelist def5d33055 GROUP - making GetCoordinate() a bit more resilient
POINT - slight changes to ToStringBRAANATO
2022-04-29 18:48:27 +02:00
Applevangelist 1aaa51c4be COORDINATE - added bogey option to COORDINATE:ToStringBRAANATO(FromCoordinate,Bogey,Spades) 2022-04-29 12:19:06 +02:00
Applevangelist 37206bcc83 Range - added nil check for playerData 2022-04-29 12:10:16 +02:00
Frank c2b86bac4b Update Airboss.lua
- Fixed DATABASE:GetFlightGroup to DATABASE:GetOpsGroup
2022-04-28 20:52:47 +02:00
Frank 02dad179cd Recovery tanker 2022-04-28 20:50:30 +02:00
Applevangelist adb94f8773 Nicefy docs 2022-04-28 17:10:49 +02:00
Applevangelist 035110df75 AWACS - removed banner from docs 2022-04-28 16:48:24 +02:00
Applevangelist 5adb65899c USERSOUND - added USERSOUND:ToUnit() 2022-04-28 16:48:07 +02:00
Applevangelist 764a373e7d POSITIONABLE - added POSITIONABLE:MessageToUnit(), and :MessageToSetUnit() 2022-04-28 16:47:42 +02:00
Applevangelist 8114327c7e MESSAGE - added MESSAGE:ToUnit(), altered MESSAGE:ToClient() to message the unit only 2022-04-28 16:46:28 +02:00
Applevangelist 6404417dad luacheck barking 2022-04-28 13:48:48 +02:00
Applevangelist d89cb8f1e9 Added Awacs WIP to working tree, Enums - corrected Hawkeye, added Super_Hercules 2022-04-28 13:11:04 +02:00
Applevangelist dee95c2f08 Update Moose.files 2022-04-28 13:04:22 +02:00
Frank 3a907ec7c2 Merge pull request #1720 from FlightControl-Master/FF/Ops
Ff/ops
2022-04-28 09:19:01 +02:00
Frank 851dff6e8c Update Intelligence.lua
- Added function to add detection group
- Added functions to retrieve contact details
2022-04-28 09:17:33 +02:00
Frank 47e7364976 Merge branch 'develop' into FF/Ops 2022-04-27 22:46:36 +02:00
Frank 41f8207b3a Merge pull request #1719 from FlightControl-Master/FF/Ops
**CHIEF**
- Added resources as parameters to `:AddStrategicZone` function

**COMMANDER**
- Added function to relocate cohorts `:RelocateCohort`

**AUFTRAG**
- Added new type `AIRDEFENSE`
- Added new type `EWR`
- Added option to teleport assets to the mission ingress waypoint via `:SetTeleport`
- Added `:SetRequiredAttribute` and `:SetRequiredProperty` functions
- Added `:SetEmission` function

**LEGION**
- Fixed bug that assets on GCI dont get additional score for INTERCEPT missions
- Assets on ONGUARD or PATROLZONE are not considered for ARTY and GROUNDATTACK missions
- Added option for transport to `RelocateCohort` function
- Ground/naval assets now automatically return when out of ammo

**OPSGROUP**
- Immobile groups are teleported to mission ingress point

**RECOVERYTANKER**
- Added parameter to set TACAN mode/band (e.g. "X")

**GROUP**
- Fixed bug in `:GetSpeedMax` function

**BEACON**
- Allowed TACAN "X" mode for AA
2022-04-27 22:38:34 +02:00
Frank ed0a3a22ab OPS
**CHIEF**
- Added resources as parameters to `:AddStrategicZone` function

**COMMANDER**
- Added function to relocate cohorts `:RelocateCohort`

**AUFTRAG**
- Added new type `AIRDEFENSE`
- Added new type `EWR`
- Added option to teleport assets to the mission ingress waypoint via `:SetTeleport`
- Added `:SetRequiredAttribute` and `:SetRequiredProperty` functions
- Added `:SetEmission` function

**LEGION**
- Fixed bug that assets on GCI dont get additional score for INTERCEPT missions
- Assets on ONGUARD or PATROLZONE are not considered for ARTY and GROUNDATTACK missions
- Added option for transport to `RelocateCohort` function
- Ground/naval assets now automatically return when out of ammo

**OPSGROUP**
- Immobile groups are teleported to mission ingress point

**RECOVERYTANKER**
- Added parameter to set TACAN mode/band (e.g. "X")

**GROUP**
- Fixed bug in `:GetSpeedMax` function

**BEACON**
- Allowed TACAN "X" mode for AA
2022-04-27 22:36:13 +02:00
Applevangelist 3a513da942 Awacs next Alpha 2022-04-27 14:37:38 +02:00
Applevangelist a4f1c60da2 Enums - added a couple of names 2022-04-26 10:09:05 +02:00
Applevangelist de0bf7d814 typo 2022-04-25 10:36:10 +02:00
Applevangelist 71fd72e462 adding ZONE_POLYGON_BASE:IsVec3InZone( Vec3 ) (might be called from POSITIONABLE), closes gap for GROUP/UNIT:IsInZone(Zone_Polygon)
GROUP - better docu
2022-04-25 09:59:44 +02:00
Applevangelist 619cc3c047 various 2022-04-24 19:11:08 +02:00
Applevangelist 68c75a4e34 Menu Refresh cleanup 2022-04-24 14:06:24 +02:00
Applevangelist 37671cefa3 GROUP - overwrite GetHeight() inherited from POSITIONABLE with something that is actually working for groups 2022-04-24 13:50:23 +02:00
Applevangelist d9f409069a INTEL - add platform type for AIR contacts (Foxbat ... ), defaults to Bogey for AIR and Unknown for everything else
SRS- added option to set a label for the SRS radio overlay
OpsGroup - added options to use said label, and option to override a frequency for an SRS (TTS) sender
2022-04-24 12:46:11 +02:00
Applevangelist fd5a190490 AWACS Alpha 2022-04-23 18:58:27 +02:00
Applevangelist 2f4d5b32b6 GROUP/UNIT - added :GetNatoReportingName() 2022-04-23 16:41:47 +02:00
Applevangelist 4c7ac68858 UTILS - UTILS.GetReportingName(Typename)
ENUMS - added ENUMS.ReportingName
2022-04-23 15:09:02 +02:00
Applevangelist ad3a3c5266 AWACS a0.0.7 - cleaned up AWACS calls, implemented DECLARE 2022-04-22 20:34:24 +02:00
Applevangelist 51d924c1b8 BRAANato - make bearing a 3digit number 2022-04-22 13:32:34 +02:00
Applevangelist 83491f535a Point - BRAANATO - will return BRA only if no aspect can be generated 2022-04-21 18:56:51 +02:00
Applevangelist 380731a244 AWACS 0.0.6 2022-04-21 18:56:09 +02:00
Applevangelist 60c78da0f6 Utils/Point - Corrections 2022-04-21 12:56:40 +02:00
Frank 2d02f4f962 Merge branch 'develop' into FF/Ops 2022-04-21 08:40:45 +02:00
Frank 982bd89924 Merge branch 'develop' into FF/Ops 2022-04-20 22:03:24 +02:00
Frank 04f60747d9 Merge pull request #1716 from FlightControl-Master/FF/Ops
OPS
2022-04-20 21:51:09 +02:00
Frank 28c107b089 OPS
**AIRWING**
- Added option to start in air `:SetTakeoffAir()`
- Added option to despawn near airbase `:SetDespawnAfterHolding()`
- Added option to despawn after landing `:SetDepawnAfterLanding()`

**SQUADRON**
- Added option to start in air `:SetTakeoffAir()`
- Added option to despawn near airbase `:SetDespawnAfterHolding()`
- Added option to despawn after landing `:SetDepawnAfterLanding()`
- Squadron settings overrule Airwing settings

**OPSGROUP**
- Improved `:Teleport()` function
2022-04-20 21:48:03 +02:00
Applevangelist e6cc8757ac Utils typo 2022-04-20 19:14:19 +02:00
Applevangelist 9169bfc608 COORDINATE - Added Precision to GetDistanceText as an option 2022-04-20 19:04:37 +02:00
Applevangelist 610e33e4a4 COORDINATE - added ToStringBRAANATO (works hopfully ;)) 2022-04-20 18:54:51 +02:00
Applevangelist 77dd40fb4a SET - clarified return value of SET_GROUP:GetAliveSET() (table, not SET)
UTILS - BRAANATO
ZONE - added examples to ZONE_RADIUS:Scan()
2022-04-20 14:01:26 +02:00
Applevangelist 5a63c51316 Utils - docu spelling 2022-04-20 12:45:33 +02:00
Applevangelist eabc8b5854 UTILS - added BearingToCardinal, added ToStringBRAANATO 2022-04-20 12:43:24 +02:00
Applevangelist 1a798886a2 AIRWING - added function to callback AWACS "onafterflightonmission" 2022-04-20 08:33:49 +02:00
Applevangelist 8735dadbca Awacs updates 2022-04-20 08:33:11 +02:00
Applevangelist 2c53ebc0e4 FIFO Added Routines 2022-04-20 08:32:57 +02:00
Applevangelist f93033695d Alpha Updates 2022-04-19 15:38:29 +02:00
Applevangelist 2d0f5817d0 Minor Changes 2022-04-19 15:36:44 +02:00
Applevangelist 2033e22216 AWACS Alpha 0.0.2 (WIP) (#1714)
TBD
2022-04-18 16:57:33 +02:00
Applevangelist bada6f64ae Update Moose.files (#1713) 2022-04-18 12:27:58 +02:00
Applevangelist bc141698c8 FIFO - make own file in Utils
AUFTRAG - Add base missions params for NewNOTHING
Marker - typo
Modules - FiFo added
UTILS - removed FiFo code
2022-04-18 12:27:14 +02:00
Applevangelist 75fddd9349 FIFO/LIFO - Read functions. Count as alternative to GetSize() 2022-04-17 11:25:48 +02:00
Applevangelist b1a417295f TextAndSound - Docu 2022-04-17 11:24:36 +02:00
Applevangelist 0522036b80 Docu 2022-04-16 18:58:43 +02:00
Applevangelist 061469840b FIFO 2022-04-14 15:55:51 +02:00
Applevangelist 6e218ed908 LIFO/FIFO - enforce unique ID 2022-04-14 15:05:49 +02:00
Applevangelist 626b48c3d1 Added LIFO/FIFO:HasUniqueID(UniqueID) 2022-04-14 11:11:18 +02:00
Applevangelist dd957237e2 Nicefy docs 2022-04-14 08:54:42 +02:00
Applevangelist fc9e237dbb UTILS - LiFo/FiFo Stacks 2022-04-14 08:12:02 +02:00
Frank faac265373 Merge pull request #1712 from FlightControl-Master/FF/Ops
Ff/ops
2022-04-13 22:44:52 +02:00
Frank 998935e2a3 Merge branch 'develop' into FF/Ops 2022-04-13 22:40:19 +02:00
Frank 24f8116fce OPS
**ZONE**
- Fixed incorrect fillcolor alpha.

**COORDINATE**
- Fixed incorrect fillcolor alpha.

**AUFTRAG**
- Fixed `CASENHANCED` order of arguments wrong in docs.

**FLEET**
- Improved docs.
- Added ``:SetPathfinding` function

**OPSGROUP**
- Fixed RECON mission behaviour if not random.
- Improved stuck check if engaging.

**LEGION**
- Added weapon type as parameter for selecting cohort assets.

**COHORT**
- Added `:GetMissionRange` function that accounts for long range weapons.
- Added counting of asset ammo.
2022-04-13 22:39:48 +02:00
Applevangelist 3415330871 UTILS - added FiFo 2022-04-13 16:13:02 +02:00
Applevangelist eadeaae6db CTLD Corrected imperial hover message to say ft not m 2022-04-13 15:30:43 +02:00
Penecruz 32bdaf4f24 Update Ops Airboss for develop (#1711)
* Update Airboss.lua

* Revert "Update Airboss.lua"

This reverts commit 61b0f843eb.

* Update Airboss.lua
2022-04-13 09:35:18 +02:00
Applevangelist 7525fe9357 UTILS - corrected door check for AH64 2022-04-12 08:23:37 +02:00
Applevangelist b24f31922f Soundfile - missing backslash 2022-04-10 18:26:27 +02:00
Applevangelist 4c79349b8d MSRS - repair command string for .bat processing 2022-04-10 18:23:20 +02:00
Applevangelist 44f7a27387 AICSAR - missing \ in path 2022-04-10 18:22:31 +02:00
Applevangelist 369425bec1 Some SRS changes 2022-04-10 15:12:51 +02:00
Applevangelist 3dc284335e SoundOutput - Honor self.useSRS to find a path to sound files located inside the miz folder 2022-04-10 14:59:54 +02:00
Applevangelist bfc284994a SRS - port set not honored 2022-04-10 14:59:05 +02:00
Applevangelist 277409a807 Text and Sound: Spelling error 2022-04-10 14:58:47 +02:00
Applevangelist d1f1f14bc3 SRS - add port to docu 2022-04-10 10:18:26 +02:00
Applevangelist 5ee1f5d3af CSAR/AICSAR - added port options for SRS 2022-04-10 09:28:47 +02:00
Frank f4569fb5cc Merge pull request #1710 from FlightControl-Master/FF/Ops
OPS
2022-04-08 22:19:42 +02:00
Frank 4ba0a2dafb OPS
**FLEET v0.0.1**
- New class for naval units corresponding to AIRWING and BRIGADE

**FLOTILLA v0.0.1**
- New class for naval units corresponding to SQUADRON and PLATOON
2022-04-08 22:18:35 +02:00
Applevangelist c2b1c2b1d8 SET - logic correction in :Remove() 2022-04-08 11:26:59 +02:00
Frank 2e119e2efd Merge pull request #1709 from FlightControl-Master/FF/Ops
OPS
2022-04-07 12:39:49 +02:00
Frank 4641918486 OPS
**LEGION**
- Added function `:RelocateCohort()` to relocate cohorts from one legion to another.
2022-04-07 12:11:17 +02:00
Frank 407f6f2b0f Merge pull request #1707 from FlightControl-Master/FF/Ops
OPS
2022-04-04 22:31:33 +02:00
Frank f01d7ecd96 OPS
**AUFTRAG v0.9.1**
- Added new mission type `CARGOTRANSPORT`
2022-04-04 22:30:30 +02:00
Frank e3d987bbdf Update Database.lua
- Static templates saved under first unit name so they can be found.
2022-04-04 16:53:52 +02:00
Applevangelist 89845883d0 Some nil checks to the A2A dispatcher, keeping it from detecting nil units, added locale to Settings and use of it to TextAndSound 2022-04-04 12:57:31 +02:00
Frank 4e7ff94b33 Merge pull request #1706 from FlightControl-Master/FF/Ops
static spawn
2022-04-04 12:16:48 +02:00
Frank 2fb9a1b1d7 static spawn 2022-04-04 12:15:29 +02:00
Applevangelist 5c0ab36662 CTLD - Build object at the first crate location found, not randomly around the helo 2022-04-04 11:29:21 +02:00
Frank fc6dac326d Merge pull request #1705 from FlightControl-Master/FF/Ops
OPS
2022-04-04 00:00:51 +02:00
Frank 426dcff085 OPS
FLIGHTGROUP
- Improved homebase for spawned units
- Enabled helo inAir check due to DCS bug that inAir returns true when spawned at airbase or farp

SET_ZONE
- Added DrawZone() function

ARMYGROUP
- Improved EngageTarget() function

AUFTRAG
- ARMORATTACK is not falling back to GROUNDATTACK
2022-04-03 23:59:43 +02:00
Applevangelist e623f45c04 Update AICSAR.lua (#1704)
Added localization and fitting german (locale "de") texts
2022-04-02 12:49:09 +02:00
Applevangelist 3b9a9cb0fa some code cleanup 2022-04-01 19:37:55 +02:00
Applevangelist c018a86bdb adding missing goshawk variable 2022-04-01 19:37:37 +02:00
Applevangelist 559be38baf Update TextAndSound.lua (#1703)
Slight doc changes
2022-04-01 19:36:00 +02:00
Applevangelist e3e05e5003 Adding TextAndSound (#1702)
Adding TextAndSound localization class
2022-04-01 19:20:35 +02:00
Applevangelist 95649d7d46 Adding localisation class TEXTANDSOUND 2022-04-01 19:17:31 +02:00
Frank 61097de76d Merge pull request #1701 from FlightControl-Master/FF/Ops
OPS
2022-04-01 12:33:31 +02:00
Frank e49fff5028 Update Auftrag.lua 2022-04-01 12:11:28 +02:00
Frank 20ae7945e0 Merge branch 'develop' into FF/Ops 2022-04-01 12:09:33 +02:00
Frank c5a50d23b6 OPS
CHIEF
- Added option to customize reaction on strategic zones

AUFTRAG
- Added new type GROUNDATTACK
2022-04-01 11:17:43 +02:00
Applevangelist ad37e5ca27 AIRBASE, added ["Deir_ez-Zor"] = "Deir ez-Zor", 2022-03-30 12:05:04 +02:00
Frank e8303064b9 Update OpsGroup.lua 2022-03-29 16:32:50 +02:00
Applevangelist f8a577749a OPS - Some changes to ARMORATTACK to update route if target is moving 2022-03-29 12:03:45 +02:00
Applevangelist e113817293 CTLD - docu nicefy 2022-03-29 12:02:35 +02:00
Applevangelist 0d15cdd370 CTLD - corrected error in setting Hercules min and max drop height, added documentation 2022-03-29 08:52:21 +02:00
Applevangelist b5db08eec3 AIRBASE - Add'l AB for the Channels map 2022-03-28 10:13:02 +02:00
Frank c3591c1fae Merge pull request #1699 from FlightControl-Master/FF/Ops
OPS
2022-03-26 22:39:44 +01:00
Frank e1a4d5497a Merge branch 'develop' into FF/Ops 2022-03-26 22:38:20 +01:00
Frank 4e83162adc OPS
CHIEF
- Added `:RemoveStrategicZone()` function
- Added `:SetLimitMission()` function to limit number of total or specific mission types.
- Improved Tactical Overview

OPSZONE
- Improved `Stop()` function
2022-03-26 22:38:03 +01:00
Applevangelist 42c6b8a016 And don't forget Fahrenheit 2022-03-26 14:47:10 +01:00
Applevangelist 48f9d808cf Correcting Celcius to Celsius 2022-03-26 14:42:36 +01:00
Applevangelist 6546c27cf5 OPS - added HOVER mission type 2022-03-25 17:54:02 +01:00
Frank fc0c0f87dc Merge pull request #1697 from FlightControl-Master/FF/Ops
OPS
2022-03-25 12:52:31 +01:00
Frank 9d703c0af6 OPS
- CHIEF: added tactical overview
2022-03-25 12:50:45 +01:00
Frank 24559c475b Merge branch 'develop' into FF/Ops 2022-03-25 11:00:17 +01:00
Frank f92e8a285a OPS
- Added nil check on vec3 for _UndateEngageTarget in ARMYGROUP and NAVYGROUP
2022-03-25 10:27:32 +01:00
Frank 0411120551 OPS
OPSGROUP
- Added damage check for groups that are not alive.
- Added `:ReturnToLegion` function.
- Added `:Teleport` function

LEGION
- Aircraft dont start hot if on Alert5 mission

AUFTRAG
- Added Formation parameter to PATROLZONE (for ground only)

ARMYGROUP
- Set Vee formation for engage group
2022-03-25 09:49:26 +01:00
Applevangelist 5f57d4ddcd docu changes 2022-03-23 07:57:06 +01:00
Applevangelist 4164bbeba8 CSAR/CTLD - added type to script 2022-03-22 10:38:07 +01:00
Frank 14dea99ccd Update Utils.lua
- Removed useless UTILS.GetDate() function
2022-03-22 09:31:16 +01:00
Frank 3ea1881ff5 OPS INTEL v0.3.0
- Added option to detect statics via `INTEL:SetDetectStatics` function.
- Added `INTEL:KnowObject` function to make intel aware of GROUPs or STATICs.
- Improved cluster analysis.
- Changed `NewCluster` event: removed contact as first parameter.
2022-03-20 22:20:09 +01:00
Applevangelist 5192c188f4 AIRBASE - added 10 new AB names in Syria 2022-03-18 09:49:06 +01:00
Applevangelist c1ffa47e9d changed descriptions 2022-03-18 07:59:49 +01:00
Applevangelist 2808a9dcc5 CONTROLLABLE - added SetSpeed() and SetAltitude() from latest release 2022-03-18 07:41:10 +01:00
Applevangelist e1ab6b6c93 CSAR - remove timer check for "open the door" message to make behaviour more realistic 2022-03-14 09:12:06 +01:00
Frank 229868bb20 OPS
AUFTRAG: Trooptransport set pickup radius to 100 meters.
OPSGROUP: enabled pickup radius for trooptransport auftrag
ARMYGOUP: removed GetPathOnRoad as it seems unncessary
2022-03-14 08:32:09 +01:00
Frank 520eb4cd1d OPS
- Improved recovery of retreated groups
2022-03-11 22:36:00 +01:00
Applevangelist 2d0b4d6ae5 SCORING: Corrected calc error in summary scoring functions 2022-03-11 10:19:30 +01:00
Frank 5dae9a197a OPS
- CHIEF: fixed bug in LEGION.RecruitCohortAssets() function call
- COMMANDER: added total weight to LEGION.RecruitCohortAssets() function call
- POSITIONABLE: fixed bug in relFuel calculation for cargo bay size
2022-03-10 10:05:21 +01:00
Frank ff1ebf9775 OPS
- Legion: Improved max number of transport assets.
- OPSGROUP: fixed bugs in speed parameter
2022-03-09 19:07:24 +01:00
Applevangelist e6f388518a Update CTLD.lua (#1693)
minor nil check
2022-03-09 10:28:26 +01:00
Frank 3557706e3a OPS
- Added new AUFTRAG type  CASENHANCED
- Improved capturing of OPSZONES by CHIEF
2022-03-05 14:43:39 +01:00
Applevangelist f3d0d55a2f CTLD - small extra nil check in _GetUnitCargoMass(Unit 2022-03-03 12:34:55 +01:00
Applevangelist b0c2bad1d8 CTLD - small fix for finding crates when using engineers 2022-03-03 11:02:14 +01:00
Applevangelist 53c9ca3b3a SEAD/MANTIS - added Silkworm ASM 2022-03-03 11:02:14 +01:00
Frank e41ba1be45 Troop Transport
- Auftrag TROOPTRANSPORT: troops will wait in a zone and not at the exact position where the carrier lands.
2022-03-02 09:34:18 +01:00
Applevangelist 594febaece CSAR - remove double class 2022-02-21 19:36:13 +01:00
Applevangelist 890dae8ba7 SEAD - adding workaround for AGM_154 which lost target data 2022-02-21 08:35:56 +01:00
Applevangelist 8a3120be39 AUTOLASE - added nil check for CanLase() 2022-02-19 13:26:02 +01:00
Applevangelist 6b4975559d CSAR - added wet feet check if also using csarUsePara (no landing event triggered) 2022-02-18 08:22:57 +01:00
Applevangelist 3326550705 CSAR - added "wet feet" option for a 2nd template to be used over water 2022-02-17 17:41:20 +01:00
Frank 6be0d82fc6 Merge branch 'develop' into FF/Ops 2022-02-16 12:23:03 +01:00
Applevangelist 44ad841d05 CTLD - fix side effects in weight check - fixes #1688 (#1689)
Fixed _FindCratesNearby() to optionally ignore the helo's max load capacity, which prevented CTLD from finding, listing, building crates is weights are used. Fixes #1688
2022-02-16 10:02:44 +01:00
Applevangelist 53f45ace4c CTLD - corrected default weight limits when using CTLD:UnitCapabilities() - was setting loadable weight to zero 2022-02-15 18:07:14 +01:00
Applevangelist 42e9cae876 added back GROUP:GetHighestThreat() 2022-02-15 14:41:45 +01:00
Applevangelist e46922d341 small correction 2022-02-15 07:30:41 +01:00
Applevangelist 21c242ee05 Added CTLD:SetTroopDropZoneRadius(Radius) 2022-02-13 12:07:57 +01:00
Frank 33b7a0cef2 Merge branch 'develop' into FF/Ops 2022-02-08 08:53:03 +01:00
Frank 9cddca1af5 AUFTRAG and WAREHOUSE
- Added check for AUFTRAG that if it is executing and all groups are dead, it's done
- Added check in WAREHOUSE find parking that units need to be alive
2022-02-08 08:52:47 +01:00
Applevangelist 8cdf0d9fce CSAR - CSAR:SpawnCSARAtZone(Zone ...) - Zone can now be a ZONE object as well as a string 2022-02-08 07:49:16 +01:00
Applevangelist a079ac4207 CTLD - allow AFB zones smoke/flare 2022-02-07 12:17:41 +01:00
Applevangelist 099238a2e5 CTLD - Allow option to create sub-category names for crates (normal, repair), added function to create zones from AFB/FARP names directly 2022-02-07 11:54:35 +01:00
Applevangelist 595bc16d92 DETECTION - added 3 missing functions 2022-02-04 08:56:34 +01:00
Applevangelist e9875c8288 small correction 2022-02-04 08:54:22 +01:00
Applevangelist ec600ab672 CTLD - Added Hercules support for crates, troops & vehicles loaded with the help of the ground crew and dropped from the plane. 2022-02-03 09:59:35 +01:00
Applevangelist c3689aee93 AICSAR - added limiter for available helos 2022-02-01 11:47:36 +01:00
Applevangelist 60a728d521 SET - correct error in intersection 2022-02-01 08:03:02 +01:00
Applevangelist 7bd7071ec5 CTLD Docu updates 2022-01-31 11:36:20 +01:00
Applevangelist bb787aa9ca Update Range.lua (#1686)
Target sheet saving abilities as added by @TonyG
2022-01-31 11:27:44 +01:00
Applevangelist d2f629d100 CTLD - added maxweight, load weight checks for crates cargo, template checks 2022-01-31 11:15:24 +01:00
Applevangelist 5d949de0ee Point - fix typos 2022-01-30 09:49:42 +01:00
Applevangelist e21bc8a930 POINT - added option to name and stop smoke/fire 2022-01-30 09:39:03 +01:00
Applevangelist af79f63870 CTLD - small correction for Hercules 2022-01-27 15:56:10 +01:00
Applevangelist 4ff32342e3 AI Dispatchers - add ability to add/remove resources to/from a squad 2022-01-24 09:54:30 +01:00
Applevangelist 98d55faf4e CTLD - added selectable smoke drop color, droppable beacons 2022-01-23 11:37:53 +01:00
Applevangelist bd532ea808 Added Callsigns as per 2.7.9 2022-01-23 11:37:28 +01:00
Applevangelist d4bd57ee70 Autolase - small update on nil check 2022-01-21 10:09:12 +01:00
Applevangelist 90dbfb31a6 DETECTION - corrected call for Vec2 in zone 2022-01-19 07:51:43 +01:00
Applevangelist 55ca34cad3 Added doors check for UH-60L 2022-01-16 17:07:32 +01:00
Applevangelist 36a5e919cd CTLD, CSAR - added support for UH-60L 2022-01-16 11:39:37 +01:00
Applevangelist 3263ba1440 CTLD - make container shape configureable 2022-01-15 11:32:51 +01:00
Tony 9721c19e48 Update Range.lua (#1683)
Addition of self.rangename to results for Rangeboss
2022-01-10 15:10:49 +01:00
Applevangelist de71213eed AICSAR - added SRS and DCS radio capabilities, changed order of messages for initial spawning, documentation 2022-01-06 13:47:47 +01:00
Applevangelist 65abbf9563 AICSAR - added SRS option, made it easy to customize messages 2022-01-04 15:09:47 +01:00
Applevangelist a94098494a Docu updates 2022-01-01 14:57:40 +01:00
Applevangelist ec935356aa Mark visible as deprecated 2021-12-31 17:51:48 +01:00
Applevangelist 6ab419dfad Fix ATC new NTTR AFB names 2021-12-31 17:51:48 +01:00
Applevangelist b1ffcff064 Update Moose.files (#1679) 2021-12-31 15:37:08 +01:00
Applevangelist 4ce09a3845 New Module AI CSAR 2021-12-31 15:36:35 +01:00
Applevangelist 9686e74feb Update Airbase.lua (#1678)
Changed (again) Airport names on the Nevada map
2021-12-30 07:46:14 +01:00
Frank e97e24762d Merge pull request #1676 from FlightControl-Master/Applevangelist-patch-1
Update Range.lua
2021-12-29 15:41:48 +01:00
Applevangelist b3fd0805e8 Update Range.lua 2021-12-29 08:59:45 +01:00
Applevangelist 300092d07d SEAD - fix a rare case when a coordinate of a weapon cannot be found 2021-12-28 08:28:19 +01:00
Applevangelist 56ed3a11d6 Scoring - docu changes 2021-12-28 08:28:19 +01:00
Applevangelist 6938b20ab6 Group - added docu 2021-12-28 08:28:19 +01:00
Frank 77f2cf5089 Merge pull request #1672 from FlightControl-Master/FF/Ops
AIRWING
2021-12-23 19:55:27 +01:00
Frank 19e3b015c5 Merge branch 'develop' into FF/Ops 2021-12-23 19:54:15 +01:00
Frank 2702d0fc2a AIRWING
- Fix for missions not being assigned
2021-12-23 19:54:01 +01:00
Applevangelist 472a4883f0 ZONE: Set down trials for getting a random coordinate on a given land type to 100
Cohort -ensure fallback of mission range
2021-12-22 11:48:42 +01:00
Frank 485e2e18bf Merge pull request #1671 from FlightControl-Master/FF/Ops
OPS
2021-12-21 11:57:09 +01:00
Frank 40c0f69eff OPS
- Airwing added :SetPayloadAmount() and SetAirboss() functions
- AUFTRAG fixed Failure to Failed event name
- CHIEF added statics as targets
- LEGION added check that runway is operational and carrier is not recovering for mission selection
2021-12-21 11:54:55 +01:00
Frank 854a1e5723 Update ArmyGroup.lua
- Fixed speed nil in ofafterUpdateRoute
2021-12-17 15:57:28 +01:00
Applevangelist f4cd28cdb9 fixes 2021-12-17 14:31:06 +01:00
Applevangelist 5bae790dd8 Fix a rare occasion 2021-12-17 14:15:08 +01:00
Frank d1d43c38cd Merge pull request #1668 from FlightControl-Master/FF/Ops
OPS
2021-12-17 13:29:08 +01:00
Frank 7e1552eeb4 Merge branch 'develop' into FF/Ops 2021-12-17 13:27:13 +01:00
Frank 7306bf28e0 OPS
- CHIEF: fixed ground groups deployment
- AUFTRAG: minor fixes
- OPSGROUP: emission option
2021-12-17 13:26:27 +01:00
Applevangelist 07e00a8faf Noise reducing measures 2021-12-15 13:46:33 +01:00
Applevangelist ab93866366 Removing noise 2021-12-14 17:28:16 +01:00
Applevangelist d7801b59e7 OPS - making a couple of modules much less noisy as the logs on a large mission get rather big 2021-12-14 13:40:16 +01:00
Applevangelist ea926f173a CSAR - make beacon length configureable 2021-12-14 09:50:13 +01:00
Applevangelist f6b55da0c6 CSAR - override suppressmessages for menu driven information 2021-12-12 19:48:49 +01:00
Applevangelist ee4e562874 CTLD - corrected landheight of dropped smoke 2021-12-12 19:30:00 +01:00
Applevangelist abfe5ffc45 Typos 2021-12-11 19:41:21 +01:00
Applevangelist 9629b0e1a3 SET - Added Zone Filter for STATIC 2021-12-11 14:24:07 +01:00
Applevangelist 80b03dd194 CTLD Added menu for smoke/flare 2021-12-11 14:13:43 +01:00
Applevangelist 3f92f8d2aa SET - added a couple of zone filters for GROUP, UNIT, CLIENT and PLAYER 2021-12-10 16:02:50 +01:00
Applevangelist 823c94cace BRIGADE - Added function to load platoons back into the field 2021-12-10 12:09:04 +01:00
Frank 421ac6c427 Fixes in AUFTRAG and LEGION
- Object in AUFTRAG:_TargetFromObject(Object) can be nil
- Assets are optimized wrt later mission type for assets on alert5
2021-12-10 10:38:34 +01:00
Applevangelist 72550d6d84 small changes Legion & Auftrag 2021-12-09 17:44:44 +01:00
Applevangelist 72999cc7b0 Update Zone.lua (#1660) 2021-12-09 07:16:29 +01:00
Applevangelist 706cf641b3 Multiple fixes 2021-12-08 19:27:22 +01:00
Applevangelist d42bdb2505 Revert "Ops - Various"
This reverts commit 23ea5d9d06.
2021-12-07 18:13:13 +01:00
Applevangelist 9082054ba9 Revert "legion"
This reverts commit abc69bc838.
2021-12-07 18:10:21 +01:00
Applevangelist abc69bc838 legion 2021-12-07 17:35:56 +01:00
Applevangelist 23ea5d9d06 Ops - Various 2021-12-07 16:09:02 +01:00
Applevangelist 8d009d6366 Some false values seem to be in need of being set explicitly 2021-12-06 15:15:46 +01:00
Applevangelist 8213b51bd6 Update Utils.lua (#1654)
Small bugfix in UTILS.LoadSetOfGroups
2021-12-06 14:56:42 +01:00
Applevangelist a18fc2080d SET - slight change in remove function 2021-12-06 10:26:01 +01:00
Applevangelist 9c0ac0ff57 CHIEF - ArmoredGuard ensure on road 2021-12-04 18:40:14 +01:00
Applevangelist c34dc9f946 CHIEF/AUFTRAG/OPSGROUP Fixed RECON type mission adhereing to paramters adinfinitum and randomly, fixed CAS mission in CHIEF 2021-12-04 16:24:45 +01:00
Applevangelist 1c5c205614 OpsGroup - corrected speed calculation from DCSTask 2021-12-03 16:51:06 +01:00
Applevangelist 897df1b8fa CHIEF - Option to allow ground transport. Set CAS speed to 70% max as Russian Helos are overly slow 2021-12-03 14:27:03 +01:00
Applevangelist 3fb22b7c55 AUFTRAG - correct wrongly corrected speed conversion 2021-12-02 16:07:34 +01:00
Applevangelist 7819a30c57 BRIGADE - Fuel zones landing in the wrong table. Corrected 2021-12-02 12:17:48 +01:00
Applevangelist 37d2c72945 MANTIS - added variable ranges for short, med and long range systems. Altered engage range to 95% and shoradactivation to 25km as defaults
AUFTRAG/CHIEF/OPSGROUP - added Auftrag type ARMOREDGUARD to have an ONGUARD mission for tanks w/o triggering transport by CHIEF
Made classes around CHIEF & AIRBOSS a bit less noisy as it kills my logfile
2021-12-02 10:13:38 +01:00
Applevangelist 5631e2c09f Minor changes 2021-11-29 08:03:58 +01:00
Applevangelist c7ddd6ec35 CSAR - added check smoke/flare distance is valid 2021-11-27 17:27:58 +01:00
Applevangelist 7280ceac32 ARMYGROUP - in tracing, formation flag can be empty 2021-11-26 15:36:46 +01:00
Applevangelist f8b9128d8e CHIEF - Added catch if coalition us given as string 2021-11-26 15:36:09 +01:00
Applevangelist c482f1dccd Corrected typo in Unit.Category.HELICOPTER 2021-11-26 15:35:45 +01:00
Applevangelist 7e306be8aa UTILS - Added functionality to save & load groups and statics information 2021-11-26 15:34:47 +01:00
Frank 035e6913b5 Merge pull request #1643 from FlightControl-Master/Applevangelist-armor-1
CHIEF - Added use of ARMORATTACK
2021-11-24 13:38:25 +01:00
Applevangelist e12f233afc Update Chief.lua 2021-11-24 13:32:39 +01:00
Applevangelist 26c7ff8c18 Update Chief.lua 2021-11-24 13:32:14 +01:00
Frank 5647364293 Merge pull request #1644 from FlightControl-Master/Applevangelist-armor-1-1
OpsGroup - Added support for ARMORATTACK
2021-11-24 13:17:45 +01:00
Frank 06fa585f69 Merge pull request #1642 from FlightControl-Master/Applevangelist-Armor-1
Auftrag - Added type ARMORATTACK
2021-11-24 13:17:13 +01:00
Applevangelist 035eac2f1e OpsGroup - Added support for ARMORATTACK
OpsGroup - Added support for ARMORATTACK
2021-11-24 12:09:07 +01:00
Applevangelist f01889cbf7 CHIEF - Added use of ARMORATTACK 2021-11-24 12:07:03 +01:00
Applevangelist 73025bfd4b Auftrag - Added type ARMORATTACK
Auftrag - Added type ARMORATTACK
2021-11-24 12:06:02 +01:00
Applevangelist aec6dd1246 SEAD/SHORAD - Add AGM-88 player modes handling 2021-11-22 11:37:10 +01:00
Applevangelist ab4411e5bb SEAD - calculate HARM impact point from firing position if no target data is given
SHORAD - ignore HARM AGM-88 is not fired at a specific target
2021-11-21 18:40:04 +01:00
Frank 0ac00efda6 Merge pull request #1641 from FlightControl-Master/FF/Ops
Ff/ops
2021-11-20 22:38:38 +01:00
Frank f32eb8d710 OPS
AUFTRAG
- Added mission task param for RECON, PATROLZONE and TROOPTRANSPORT

FLIGHTGROUP
- Fixed CheckGroupDone if group is engaging and has a paused mission

TARGET
- Added GetThreatLevelMax functions

CHIEF
- Added :AddGciCapZone() function
2021-11-20 22:36:15 +01:00
Frank ec33dfb76c Merge branch 'develop' into FF/Ops 2021-11-20 20:38:40 +01:00
Frank 43dfbac2fa Update Auftrag.lua
- Changed ROE in ESCORT auftrag from OpenFireWeaponFree to OpenFire
2021-11-20 20:38:23 +01:00
Frank 7a483abec2 Merge pull request #1639 from FlightControl-Master/Applevangelist-ArmyGroup-1
Update ArmyGroup.lua
2021-11-20 17:50:36 +01:00
Frank 35e6b6faf4 Merge pull request #1637 from FlightControl-Master/Applevangelist-Chief-1
CHIEF - Updates
2021-11-20 17:49:30 +01:00
Frank 1066b58fb6 Merge pull request #1640 from FlightControl-Master/Applevangelist-OpsZone-2
Update OpsZone.lua
2021-11-20 17:47:43 +01:00
Applevangelist b41b8f251f Update Chief.lua 2021-11-20 17:26:42 +01:00
Applevangelist a1426c3e81 Update OpsZone.lua 2021-11-20 17:12:33 +01:00
Applevangelist aa3967d88f Update ArmyGroup.lua
Added code to obey routing on roads
2021-11-20 17:09:55 +01:00
Applevangelist c610c4cba9 Update Chief.lua
Added some improvements to threat calculation
2021-11-20 17:08:20 +01:00
Applevangelist abb3a2dbd2 CHIEF - Updates
Added alignment to OpsZone Mission table. Added ARTY. Added Tanks for patrol
2021-11-19 16:03:25 +01:00
Frank 1f035301d9 Merge pull request #1636 from IsmaelB83/InboundCallMarshall
Inbound call marshall
2021-11-19 15:48:28 +01:00
Frank ebf7f76d48 Merge pull request #1635 from FlightControl-Master/Applevangelist-OpsZone-1
OpsZone -Mission Table
2021-11-19 15:47:18 +01:00
Ismael 397ab77105 This pull request enhances Airboss class functionality to provide with the
1) Inbound calls both from Players requesting marshal and AI sent to marshal:
"Marshal, [MODEX], marking mom's [BEARING] for [DISTANCE], angels [HEIGHT], state [FUEL_STATE]
2) Commencing call and voiceover (both AI and Players)

For that, two boolean fields have been added to Airboss class to trigger or not extra voice overs:
xtVoiceOvers
xtVoiceOversAI

These fields can be modified trough methods:
AIRBOSS:SetExtraVoiceOvers(true/false)
AIRBOSS:SetExtraVoiceOversAI(true/false)

Note. At the moment both methods initialize to "false" at Airboss:NEW, so in case you want to have this functionality activated, you need to call the methods with (true) when initializing your Airboss class.
The new methods in charge of creating the radio calls are
AIRBOSS:_MarshalAI: for AI flights send to marshal
AIRBOSS:_RequestMarshal: for player flighs requesting marshal from F10 menu

2) AIRBOSS:_CommencingCall(unit, modex), which is called from
AIRBOSS:_ClearForLanding: for AI flights cleared for landing
AIRBOSS:_RequestCommence: for player flights requesting commencing from F10 menu (disregarding if the player call is right or not)

This enhacement of the Airboss class requires 5 new sound files (.ogg) to be included to folder "\Airboss Soundfiles" in your .miz file:
PILOT-Angels.ogg
PILOT-For.ogg
PILOT-MarkingMoms.ogg
PILOT-Marshal.ogg
PILOT-State.ogg
PILOT-Commencing.ogg
2021-11-19 15:31:49 +01:00
Applevangelist f37abc69ea Update OpsZone.lua 2021-11-19 14:29:18 +01:00
Applevangelist ee85b0e057 OpsZone -Mission Table
Added functionality to admin missions attached to an OpsZone (for CHIEF)
2021-11-19 14:20:53 +01:00
Ismael eab28abc86 Subject: Add Player and AI Inbound radio calls to better inmersion in Airboss #16311
This commit enhances Airboss class functionality to provide with the inbound calls both from Players requesting marshal and AI sent to marshal:
- "Marshal, [MODEX], marking mom's [BEARING] for [DISTANCE], angels [HEIGHT], state [FUEL_STATE]

Two new boolean fields have been added to Airboss class to trigger or not the inbound calls:
- inRadioCall
- inRadioCallAI

These fields can be modified trough methods:
- AIRBOSS:SetInboundMessagesPlayer(false)
- AIRBOSS:SetInboundMessagesAI(false)
Note. At the moment both methods initialize to "false" at Airboss:NEW, so in case you want to have this functionality activated, you need to call the methods with (true) when initializing your Airboss class.

This enhacement of the Airboss class requires 5 new sound files (.ogg) to be included to folder "\Airboss Soundfiles" in your .miz file:
- PILOT-Angels.ogg
- PILOT-For.ogg
- PILOT-MarkingMoms.ogg
- PILOT-Marshal.ogg
- PILOT-State.ogg

To get them, please refer to the SOUNDS MOOSE repository or the discord channel. Where they will be available.
2021-11-19 01:11:49 +01:00
Applevangelist 16c5307fc2 COMMANDER - Zone parameter doc not correctly mentioned in Luadocs 2021-11-18 10:58:42 +01:00
Applevangelist 8c8cae1e27 AUFTRAG - wrong speed conversion lines 925/295 corrected to KnotsToKmph 2021-11-18 10:58:13 +01:00
Frank 925c645821 Merge pull request #1633 from FlightControl-Master/FF/Ops
OPS
2021-11-17 17:17:11 +01:00
Frank c1c97a86b7 OPS
- COMMANDER: Added GCICAP zones
- AIRWING: Improved patrol zone counting, fixed bug in NewPatrolPoint
- OPSGROUP: mission speed acknowledged
2021-11-17 17:15:44 +01:00
Applevangelist 1fc1016148 Update Auftrag.lua
Added missionSpeed to Orbit
2021-11-17 16:42:58 +01:00
Frank e73545d296 Merge pull request #1630 from dogjutsu/dogutsu/develop
Fixed some typos of forms of the word 'strategy'.
2021-11-16 22:08:00 +01:00
dogjutsu f2fb7d43d0 Fixed some typos of forms of the word 'strategy'. 2021-11-16 12:45:14 -08:00
Applevangelist 781d421e1c slightly changes message 2021-11-16 15:48:00 +01:00
Applevangelist a3a7464a29 Small fix fox autoshorad parameters 2021-11-16 10:34:42 +01:00
Frank ac936f5650 Merge pull request #1629 from FlightControl-Master/FF/Ops
Scheduler
2021-11-16 10:34:12 +01:00
Frank c0f5dc2dc8 Scheduler
- Fixed bug
2021-11-16 10:33:35 +01:00
Applevangelist 31c113180e MANTIS - Zones - added conflict zones 2021-11-16 09:26:05 +01:00
Applevangelist 239df2deb2 SEAD - Updated TTI calculation for Tomahawk long shots 2021-11-16 09:25:38 +01:00
Applevangelist 31a8c4b0b9 SHORAD - Updates for missile without set target intel 2021-11-15 16:18:21 +01:00
Applevangelist f394bd45c7 SEAD - Updated to handle missiles w/o clear targets 2021-11-15 16:18:21 +01:00
Applevangelist 63999c9ec3 MANTIS - Added Attacker group info on planned/started suppression events 2021-11-15 16:18:21 +01:00
Frank 82c24cee7e Merge pull request #1628 from FlightControl-Master/FF/Ops
scheduler
2021-11-15 10:22:35 +01:00
Frank 5e94b0c009 Update Base.lua 2021-11-15 10:20:34 +01:00
Frank 452ff62134 SCHEDULER 2021-11-15 10:19:21 +01:00
Frank 3df494cacd Merge pull request #1627 from FlightControl-Master/FF/Ops
Ff/ops
2021-11-14 23:31:03 +01:00
Frank d62bb59df7 OPS
- Clean up tracing
2021-11-14 22:12:41 +01:00
Applevangelist b367f9320b CSAR - don't make usePara default. Added coalition check if using the parachute landing event 2021-11-14 13:33:31 +01:00
Applevangelist 4bc3dbbf6c MANTIS - added auto-setup of SHORAD 2021-11-14 13:13:41 +01:00
Applevangelist e7b7e3ac96 Merge pull request #1626 from FlightControl-Master/Applevangelist-unit-2
Wrapper Unit fix missile count
2021-11-14 13:00:35 +01:00
Applevangelist f3c4aea12f Wrapper Unit fix missile count
missile count for SAM and CRUISE types #1624
2021-11-14 12:59:24 +01:00
Frank b9b5938a91 OPS
- Fixed refuel system always true.
2021-11-13 20:08:22 +01:00
Applevangelist e7fdcf0db4 SEAD - Slightly wider escape radius 2021-11-13 19:11:25 +01:00
Applevangelist c1f22aa556 MANTIS - Added support for HighDigitSAM mod, added blindspot management, corrected distinguising between SA-2 and SA-3 2021-11-12 15:27:05 +01:00
Applevangelist 991b4089d6 SHORAD radius clarification 2021-11-12 15:25:25 +01:00
Frank a8132552de OPS
- Fixed bug in egress coord
- Improved barrage mission
- improved pickup at legion
- fixed bug in SetPathfindingOff function
2021-11-11 21:16:48 +01:00
Applevangelist a0323aef19 MANTIS - Some docu updates 2021-11-11 18:34:06 +01:00
Applevangelist a38abc2f7f MANTIS - latest updates 2021-11-11 17:45:25 +01:00
Applevangelist a6beecf510 MANTIS - Added Auto Mode 2021-11-11 17:22:21 +01:00
Applevangelist c5dece0e59 SEAD - make emissions on/off standard 2021-11-11 16:03:52 +01:00
Applevangelist ce935bafc1 Small fix to switch off pattern matching 2021-11-09 09:53:23 +01:00
Applevangelist fd426a96aa File functions 2021-11-09 09:51:31 +01:00
Applevangelist fad8800842 Added Docu 2021-11-09 09:51:05 +01:00
Applevangelist 273a473db1 MANTIS/SEAD make docu Pikes-friendly 2021-11-08 15:21:20 +01:00
Applevangelist a7588e517d SEAD - (re-)added emissions on/off option and ability to link object functions for state changes. 2021-11-08 13:11:58 +01:00
Applevangelist 84eff098eb MANTIS - Added FSM Events for SeadSuppressionPlanned/Start/ENd 2021-11-08 13:11:58 +01:00
Frank f157f3b5d6 OPS
- Fixed mission alt for patrol zone auftrag
2021-11-07 22:32:17 +01:00
Frank 6cd00c60a7 Update OpsGroup.lua
- Fixed waypoint alt for missions
2021-11-07 21:39:38 +01:00
Frank 2ea951db61 Removed WIP classes
- F10MENUE and FLIGHTCONTROL
2021-11-07 19:43:02 +01:00
Frank 9d0bd0aabb Update OpsGroup.lua 2021-11-07 19:39:53 +01:00
Frank 3d88d16b4b Merge branch 'FF/Ops' into FF/OpsDev 2021-11-07 18:24:48 +01:00
Frank 02724dc26d Merge branch 'develop' into FF/Ops 2021-11-07 18:20:27 +01:00
Frank 21a93652cd Update OpsGroup.lua
- Fix for AUFTRAG carried out only after the group has passed all waypoints
2021-11-07 16:08:11 +01:00
Frank fb4caf1a42 OPS
- Improved transport path
2021-11-07 16:03:44 +01:00
Frank 7a2508bf17 OPSTRANSPORT
- Improved pre-defined paths for pickup and transport
2021-11-06 18:10:49 +01:00
Applevangelist eeeab86952 added altered message 2021-11-06 18:07:42 +01:00
Applevangelist a149ff1705 Switch for fratricide and treason (coalition changes) 2021-11-06 15:15:30 +01:00
Applevangelist 2c73c9c815 Merge pull request #1620 from FlightControl-Master/Applevangelist-casevac-1
CSAR additions by Shagrat
2021-11-05 16:31:22 +01:00
Applevangelist f6f29db9f1 CSAR additions by Shagrat
Added functionality for Casevac
2021-11-04 17:23:29 +01:00
Frank c823a68616 OPS
- Fixed several bugs
2021-11-02 21:14:15 +01:00
Applevangelist e7e2184760 Autolase - fixed error when not using a pilotset 2021-11-01 19:46:56 +01:00
Applevangelist 6fe2422bc9 SRS Google addition by rollnthndr 2021-10-31 11:53:53 +01:00
Applevangelist cd62776be6 AIRBOSS additions by Pene 2021-10-31 11:53:24 +01:00
Applevangelist 037357efe9 Merge pull request #1619 from bbirchnz/ctld-crate-leak
fix cleanup of crates on load or build.
2021-10-31 11:31:19 +01:00
Ben Birch 8d3910ea4c fix cleanup of crates on load or build. 2021-10-31 19:37:26 +11:00
Applevangelist 3e5926f706 Speedmax returning 0 not nil 2021-10-30 16:32:59 +02:00
Applevangelist a1d67bf539 Speedmax returning 0 not nil 2021-10-30 16:32:42 +02:00
Applevangelist 3e65457041 doc impro 2021-10-29 18:30:22 +02:00
Applevangelist f70180eb66 SET_BASE - cmpleted GetSetComplement 2021-10-29 10:20:34 +02:00
Applevangelist c0a558e229 Merge pull request #1616 from Zonr0/Zonr0-ExternalToolsFix
Fixes broken external tools
2021-10-28 15:45:02 +02:00
Applevangelist 801069f5ac Update Moose_Create.lua 2021-10-28 15:39:57 +02:00
Frank f9dcac8264 Merge branch 'master' into develop 2021-10-28 10:21:16 +02:00
Frank 902c001aa4 OPS
Improved OPSTRANSPORT
2021-10-28 10:04:01 +02:00
Applevangelist 0cf2a4353d doc build - next try 2021-10-28 09:13:36 +02:00
Applevangelist 13c8cc90f2 doc build fix 2021-10-28 08:41:10 +02:00
Applevangelist db231fafeb Docs build test 2021-10-28 08:12:27 +02:00
Andrew Waugh c3f7deb602 Fixes broken external tools
Several small changes that should hopefully be a nice QoL upgrade for generating the imports and lead to less newbie confusion.

* Adds a lua binary directly to the repository instead of just expecting the user to have installed it via choco. Added binary is 5.4 as that's the lowest 5.x exe that's easily downloaded, and it works fine for what we need.
* Modifies the launch targets to use workspace_loc macros instead of resource_loc macros. Workspace_loc requires the user to have correctly set the name of their project, but that is already stressed in the documentation.  resource_loc was just wrong. (project_loc would cause problems if the user had selected something outside of the moose project before running).
* Modifies launch targets to use the folder structure that the project is actually structured with.
* Adds the include folder and files so Eclipse doesn't explode when they are missing.
* Small modifications to Moose_Create, also includes a path conversion function that in my testing doesn't make a difference eitherway on Windows, but is there for a troubleshooting option.
* Adds courtesy instructions when generating the dynamic include file.
2021-10-27 20:18:10 -07:00
Applevangelist 300e3f2f58 Merge pull request #1615 from FlightControl-Master/Applevangelist-docpatch
Update Task_Cargo_Transport.lua
2021-10-27 13:10:40 +02:00
Applevangelist 513406f0e5 Update Task_Cargo_Transport.lua 2021-10-27 13:09:30 +02:00
Applevangelist 27e21e77f9 Update Task_Cargo_Transport.lua 2021-10-27 11:19:32 +02:00
Applevangelist dadfd803f7 Update Autolase.lua
added docu
2021-10-26 13:58:11 +02:00
Frank 02b0ba2278 OPS
- Improved behaviour of OPSTRANSPORT when cargo or carrier is on mission.
2021-10-25 22:17:56 +02:00
Applevangelist 3e1005aef1 Small correction to silence wall of text when adding tasks to a mission 2021-10-25 16:29:14 +02:00
Applevangelist e2eb13739c Commented out wall of text when joining a unit as a player 2021-10-25 16:28:40 +02:00
Applevangelist c52e30ceae Added smoke color per RECCE 2021-10-25 16:28:11 +02:00
Applevangelist 07754cdf5f Merge pull request #1614 from madmoney99/develop
Forrestal Wire Corrections
2021-10-24 09:14:10 +02:00
madmoney99 c74c475a29 Forrestal Wire Corrections
Tested on MP and SP.  Both were recording incorrect wires on 1/2 and 4 wires regularly with an occasional 3 wire miss.  This tested correct in the Hornet.

TonyG
2021-10-23 16:34:21 -07:00
Applevangelist ad36ab520b Added Bell-47 2021-10-22 17:04:03 +02:00
Applevangelist bc32ff5db9 Added Bell-47 2021-10-22 17:03:57 +02:00
Frank 6009432933 OPS
- NAVYGROUP added engage target
- Barrage improvments
2021-10-22 11:23:29 +02:00
Frank 99eaa37c76 Merge branch 'master' into develop 2021-10-20 19:56:31 +02:00
Frank ed6d5f727a OPS 2021-10-20 19:49:26 +02:00
Frank c6995d6e58 OPS
- Fixed AUFTRAG :Repeat()
- Fixed bug in BRIGADE
- Improved cargo bay calculation in POSITIONABLE (includes rel. fuel)
- Changed carrier event names in OPSGROUP

- New class F10MENU (not sure about it)
2021-10-19 10:19:26 +02:00
Frank cb0f453a8d Merge branch 'FF/Ops' into FF/OpsDev 2021-10-16 13:41:40 +02:00
Frank d9866846ad Merge branch 'FF/MasterDevel' into FF/Ops 2021-10-16 13:40:37 +02:00
Frank de5d9195f3 OPSGROUP
- Cargo bay of element remains after respawn
- Added some docs for CHIEF
2021-10-16 09:32:47 +02:00
Frank fd1fe8562c Merge branch 'develop' into FF/Ops 2021-10-12 22:20:20 +02:00
Frank b1298223aa Merge branch 'master' into develop 2021-10-12 22:18:43 +02:00
Applevangelist c48128d92e CSAR - Added country options for spawned pilots 2021-10-12 08:30:44 +02:00
Frank 0f4d466953 OPS
- Changed mission, legion in MissionAssign functions (LEGION, COMMANDER, CHIEF)
- OPSTRANSPORT: improved TZC selection
- ARMYGROUP needs to
2021-10-11 21:28:35 +02:00
Applevangelist 1b752fcaf6 CTLD - bug fix for open doors 2021-10-11 18:47:39 +02:00
Applevangelist d06db9909c AUTOLASE Small update 2021-10-11 14:11:58 +02:00
Applevangelist 921024035c AUTOLASE - cleanup, added SRS option 2021-10-08 12:33:33 +02:00
Applevangelist 3b1c8c3deb AUTOLASE - added LOS check, maxlasingunits valid per lasing Recce 2021-10-07 18:16:40 +02:00
Applevangelist 69862ab67d CSAR - try to avoid spawning under water 2021-10-07 18:15:50 +02:00
Applevangelist b05c321306 CTLD - added door check for troops 2021-10-07 18:15:13 +02:00
Applevangelist 9b74a58dde UTILS - added door check for Hercules 2021-10-07 18:14:50 +02:00
Applevangelist d112ffaf6a Autolase - better calculation of LoS for lasing, somewhat faster detection 2021-10-07 09:49:06 +02:00
Applevangelist 554f063def INTEL - allow variable update times 2021-10-07 09:46:06 +02:00
Frank f6dce02203 INTEL
- Introduced pcall to getName() of detected objects. Found a problem with an object of ID 5,000,031
2021-10-06 22:03:02 +02:00
Frank 653dfe82fa OPS CHIEF
- Improved target queue for assigning new missions
2021-10-06 13:25:57 +02:00
Frank 5dbf743052 OPS
- Fixed a couple of minor bugs.
- FC added _PlayerAbortInbound function
2021-10-05 23:59:24 +02:00
Applevangelist f7e7e2e41c ZONE_CAPTURE_COALITION - fix an error when monitoring hits but the Event Function delivers SCENERY as a hit UNIT 2021-10-05 19:07:59 +02:00
Applevangelist b28b4db7fd docu fixes 2021-10-05 19:06:49 +02:00
Applevangelist c34f30e4a3 Docu fixes 2021-10-05 19:06:40 +02:00
Applevangelist aa7f11185d Small update 2021-10-05 19:06:30 +02:00
Frank 1790d19809 FC 2021-10-03 23:09:45 +02:00
Frank fa6fbca67b OPS
- Added tanker and CAP zones
2021-10-03 21:33:33 +02:00
Applevangelist cd79c57a27 AUTOLASE - added Cancel FSM to stop, docu changes, option to notify pilots in the set only 2021-10-02 14:45:37 +02:00
Applevangelist 4c3a97e2b2 Autolase! 2021-10-01 17:29:22 +02:00
Applevangelist f126dceeae Merge pull request #1610 from FlightControl-Master/Applevangelist-Autolase-2
Update Moose.files
2021-10-01 17:26:50 +02:00
Applevangelist 414521acc5 Merge pull request #1611 from FlightControl-Master/Applevangelist-autolase-3
Update Modules.lua
2021-10-01 17:26:40 +02:00
Applevangelist 9147422340 Merge pull request #1609 from FlightControl-Master/Applevangelist-Autolase-1
Create Autolase.lua
2021-10-01 17:26:29 +02:00
Applevangelist 920646ea74 Update Modules.lua
added autolase
2021-10-01 17:24:25 +02:00
Applevangelist c57d839927 Update Moose.files
Add Autolase.lua
2021-10-01 17:22:58 +02:00
Applevangelist e7fd5db2c2 Create Autolase.lua
Added Class AUTOLASE
2021-10-01 17:20:17 +02:00
Applevangelist b76486ef5f CSAR - added parameters for hovering rescue 2021-10-01 14:52:25 +02:00
Applevangelist 5c06584676 UTILS - correction door check MI-8 2021-10-01 14:52:00 +02:00
Frank 2ae2ee64be OPS
- Lots of updates and improvements
2021-10-01 12:04:15 +02:00
Applevangelist 17ba35e237 INTEL - also set isship and isground attributes on contacts 2021-10-01 10:44:25 +02:00
Applevangelist 53e98e70aa CTLD: added user-friendly function to inject static cargos: CTLD:InjectStaticFromTemplate(Zone, Template, Mass) 2021-10-01 10:43:49 +02:00
Applevangelist 359e18eb58 RADIO - delete frequency check 2021-09-30 08:07:42 +02:00
Applevangelist 3377459df5 Added option for silent mission addition 2021-09-29 16:57:45 +02:00
Frank 3e30d15405 Merge branch 'FF/Ops' into FF/OpsDev 2021-09-29 09:57:52 +02:00
Frank 2b50cf2243 Merge branch 'develop' into FF/Ops 2021-09-29 09:55:20 +02:00
Frank b72e2b6bf9 Merge branch 'master' into develop 2021-09-29 09:34:37 +02:00
Frank c7a2b34f59 Update Warehouse.lua
- Disabled fuel check.
2021-09-29 08:15:22 +02:00
Frank b48958995a OPS
- Fixed oscillation between UpdateRoute and CheckGroupDone in FLIGHTGROUP
- Improvements regarding capturing zones.
- Reduced log output
2021-09-28 23:26:33 +02:00
Applevangelist 58c496eacd GROUP - GROUP:GetAmmunition() - fix to also return bomb count correctly 2021-09-28 16:52:18 +02:00
Applevangelist 7bd867c9dd SEAD - Docu changes for Intellisense 2021-09-28 16:51:35 +02:00
Frank be0558849c OPS
- Added rearming zones
- Improved rearming
2021-09-27 16:11:03 +02:00
Applevangelist a1c7ec2ac9 Fix "local" error 2021-09-27 15:49:03 +02:00
Applevangelist 8bf073c0c6 Small fix for Airbase Parking Spot Finder 2021-09-26 09:51:02 +02:00
Frank 994689f05a OPS
- Improved transport assignments
2021-09-25 20:18:16 +02:00
Applevangelist 3e10f9f451 bugfix 2021-09-24 18:38:58 +02:00
Frank 972fa9f674 OPS
- Fixed bug in WAREHOUSE isShip
- FLIGHTGROUP added damage and ammo checks that trigger FSM events
- Improved engage detected targets
- Improved OPSZONE
2021-09-24 14:47:36 +02:00
Applevangelist 8e64d8e334 CTLD: Added mass and canCargo Flag on spawned statics. Use .enableslingload = true to use 2021-09-24 11:06:54 +02:00
Applevangelist eccd81d40a SPAWNSTATIC - bigfix on canCargo (not:isCargo) and mass (not transported into template) when spawning 2021-09-24 11:05:42 +02:00
Applevangelist 649136f98f small updates, fixes 2021-09-23 12:43:28 +02:00
Frank d7dae1366d OPS
- Improved OPSTRANSPORT for LEGION assets.
2021-09-22 19:27:33 +02:00
Applevangelist 19e2ebcd03 CTLD - Added statics as cargo (#1601)
.... and the ability to load and save them alongside your buildable crates.
2021-09-22 15:55:10 +02:00
Applevangelist 021c907d16 SET - Added SET_CLIENT:CountAlive() 2021-09-21 07:46:21 +02:00
Applevangelist 8ac3e28fdf CTLD - fix SAVE/LOAD when using no path on calls 2021-09-21 07:46:05 +02:00
Frank c5af279730 OPS
- Fixed some stuff for Egress coordinate
- Fixed some bugs in OPSTRANPORT if disembark carriers are specified
2021-09-20 22:47:51 +02:00
Applevangelist e9377e93f1 Postionable - Added Cargo Seats to VAB Mephisto 2021-09-20 14:20:09 +02:00
Applevangelist 6747c69511 CTLD Ability to fire an event on injection 2021-09-20 14:19:26 +02:00
Frank 9b6cae6c49 Update Commander.lua 2021-09-19 22:45:58 +02:00
Frank 7148bd1d42 OPS Escort
- Refined functions to recruit escort assets.
2021-09-19 22:10:52 +02:00
Frank 73940fffc6 Update Legion.lua
- Fix that assets did not get removed
2021-09-18 18:47:06 +02:00
Frank 09015449cd OPS Recruting
- Removed obsolete recruiting functions from code
2021-09-18 18:23:22 +02:00
Frank 4dfdb99731 OPS
- Recruit assets with new function (LEGION, COMMANDER, CHIEF)
2021-09-18 18:09:41 +02:00
Frank bbbca04066 OPS Legion
- Added new global function to recruit assets.
2021-09-18 00:11:04 +02:00
Frank e755bba608 OPS
- Clean up on "CheckMissionType" and "CheckMissionCapability" functions ==> moved to AUFTRAG as global functions.
2021-09-17 16:59:43 +02:00
Frank 9161cec238 OPS
- Simplified asset selection by using just one routine for LEGION, COMMANDER and CHIEF
2021-09-16 21:30:36 +02:00
Applevangelist dc14b60fcc bug fixing 2021-09-16 15:09:51 +02:00
Applevangelist da625d51f6 Merge pull request #1599 from FlightControl-Master/Applevangelist-CTLD-1
CTLD - Added persistance
2021-09-16 13:44:54 +02:00
Applevangelist ce69055758 CTLD - Added persistance
-- ## 6. Save and load back units - persistance
-- 
-- You can save and later load back units dropped or build to make your mission persistent.
-- For this to work, you need to de-sanitize **io** and **lfs** in your MissionScripting.lua, which is located in your DCS installtion folder under Scripts.
-- There is a risk involved in doing that; if you do not know what that means, this is possibly not for you.
-- 
-- Use the following options to manage your saves:
-- 
--              my_ctld.enableLoadSave = true -- allow auto-saving and loading of files
--              my_ctld.saveinterval = 600 -- save every 10 minutes
--              my_ctld.filename = "missionsave.csv" -- example filename
--              my_ctld.filepath = "C:\\Users\\myname\\Saved Games\\DCS\Missions\\MyMission" -- example path
--  
--  Then use an initial load at the beginning of your mission:
--  
--            my_ctld:__Load(10)
--            
-- **Caveat:**
-- If you use units build by multiple templates, they will effectively double on loading. Dropped crates are not saved. Current stock is not saved.
2021-09-16 13:43:39 +02:00
Frank 589ebd5bca CHIEF
- Improved asset selection
2021-09-16 11:02:49 +02:00
Frank 35b50e1a9d OPSZONE and CHIEF 2021-09-14 23:51:03 +02:00
Frank f038564b1b OPSTRANSPORT
- Added Cancel feature. First steps...
- Fixed a couple of other little bugs.
2021-09-13 16:04:16 +02:00
Frank 1d0eb9806d COMMANDER
- Added OPS transport (untested)
2021-09-13 08:31:00 +02:00
Applevangelist c50a9bd318 CTLD - small bug fix on stock removal 2021-09-12 17:37:21 +02:00
Applevangelist cd9006d29b CTLD - added alternative crate spawn by @mousepilot. Add menu item to list stock.Injected troops will not lead to cargo type duplication. 2021-09-11 15:20:36 +02:00
Applevangelist d3b88f9065 bug fixing 2021-09-11 10:03:32 +02:00
Frank 6a6cb1961d OPS LEGION
- Improved asset selection for transports
2021-09-10 11:37:53 +02:00
Frank 884c51a69a OPSTRANSPORT
- Improved assignment to multiple legions.
2021-09-10 00:32:15 +02:00
Frank 6f126e6cd4 OPSCARGO
- fixes for Legion assignment
2021-09-09 13:35:10 +02:00
Frank b0c2e5409a OPS AUFTRAG
- Added Alert 5 mission
- Added Fuel supply mission
- Added Ammo supply mission
2021-09-08 11:49:27 +02:00
Applevangelist 9516ec3cd2 CSAR: Gardening cleanup 2021-09-07 19:53:05 +02:00
Frank aecb92ccd3 OPSGROUP
- Added EPLRS option
- EPLRS is on if group has datalink capability
2021-09-07 11:17:20 +02:00
Frank bdf13f29f7 OPS
- COMMANDER and LEGION clean up of obsolete stuff for recruiting assets.
2021-09-06 23:40:58 +02:00
Frank 81120abfcb OPS
- LEGION and COMMANDER: Recruit assets for mission
2021-09-06 23:24:26 +02:00
Applevangelist 08a8170990 CTLD - improved crate spawning, added beacons / smoke / flare for ships, added documentation 2021-09-05 18:05:08 +02:00
Frank 316ea910c2 Update Cohort.lua
- Fixed some stuff for combat readiness check
2021-09-05 00:23:12 +02:00
Frank 0b5edfc21f OPSGROUP
- Ad infinitum fixes
- Turn into wind fixes
2021-09-04 23:51:17 +02:00
Applevangelist 76c08095ab CTLD - added country variable for crates 2021-09-03 18:38:51 +02:00
Frank 538864519e OPSGROUP
- Fixes that ARMY and NAVYGROUPS only go to first waypoint
- Fixes for PATROL and RECON missions that waypoints are added at the end
- Some other stuff
- Still need to fix adinfinitum
2021-09-03 18:20:28 +02:00
Applevangelist cd6631049b CSAR - Removed message for dead pilots 2021-09-03 14:16:30 +02:00
Applevangelist 079f8030b7 CTLD - added unit parameter to place crates in correct distance. Refactored location calculation for crates. 2021-09-03 14:16:11 +02:00
Frank ad0b32c0ee OPS
- Found and fixed bugs for ARMY and NAVY groups, which caused only one waypoint to be processed
- Added Duration for AUFTRAG
- Fixed bug in auftrag if no legion was assigned and mission was canceled at opsgroup level
- Trying (again) to include the whole route for ARMY and NAVY when UpdateRoute
- Simpler task function for passing waypoint

STILL a lot to do/check!
2021-09-03 00:05:58 +02:00
Applevangelist 8235b51a14 Bug fixing 2021-09-02 18:04:39 +02:00
Frank 1bd5e7472f OPSTRANSPORT v0.4.2
- Some fixed.
- All tested demo missions look nice
2021-09-02 08:30:54 +02:00
Applevangelist 7433a7144c CTLD Added method to inject troops into the field. 2021-09-01 13:33:43 +02:00
Frank 27632ecdd9 OPSTRANSPORT v0.4.1
- Fixed a couple of bugs
- Lots of other fixes and improvements
2021-09-01 00:07:54 +02:00
Frank 0b1e25b073 OPSTRANSPORT v0.4
- Multiple transport zone combos (TZC)
- Other issues solved.
- Demo miz D-day landing is still not working correctly.
2021-08-30 23:45:40 +02:00
Applevangelist 19a93f0026 MANTIS - allow SEAD padding in Mantis 2021-08-28 13:58:06 +02:00
Applevangelist 3256a6d596 SEAD - added time-back-on padding as variable 2021-08-28 13:57:15 +02:00
Frank 28ddfa5243 OPSTRANSPORT
- Fist working steps towards multiple pickup/deploy zone combos.
2021-08-28 00:17:16 +02:00
Applevangelist 05c560be3b CTLD - added delay after unsuccessful build or repair, relocate after done 2021-08-27 18:51:54 +02:00
Applevangelist 8ddd810fe2 SEAD - Refactor and enable delayed switch-off 2021-08-27 18:50:40 +02:00
Applevangelist f20760bae5 CSAR - Remove some noise 2021-08-27 18:48:18 +02:00
Applevangelist cea7320a9b UNIT/GROUP - added function to get the skill of a unit. SEAD - added functionality to calculate time-2-impact of HARMS and adjust behaviour accordingly 2021-08-27 14:56:50 +02:00
Frank fe6826016c Update Chief.lua 2021-08-27 11:59:34 +02:00
Frank f0167b3e88 OPS
- FSM pseudo function cleanup
- Fixed bug when mission is cancelled
2021-08-27 11:31:12 +02:00
Applevangelist 0edbf7f517 Added Engineering (Infantry) Troops 2021-08-27 09:14:54 +02:00
Frank a8a8dcff3f OPS Chief
- Removed mission queue. Now done via COMMANDER
- MissionCancel is buggy
2021-08-26 23:24:11 +02:00
Frank 1b0ad13529 OPS Commander 2021-08-26 21:24:47 +02:00
Frank 418d6c882c Update OpsGroup.lua 2021-08-25 17:46:00 +02:00
Frank 1e6899c40b OPS 2021-08-25 17:20:17 +02:00
Frank 259b201e65 OPS
Good version solving a few bugs and adding some new stuff.
2021-08-24 23:10:38 +02:00
Applevangelist 8fb113a04e CTLD - 1) added ability to limit stock. 2) Stopping Herc Pilots to try and build on the fly (look at you, Gunterlund! ;) ) 2021-08-24 14:16:11 +02:00
Frank c6ebbc6122 OPS
Strange version buggy
2021-08-23 23:34:15 +02:00
Applevangelist 755903a08e Changed priority to show bom target height in ft, in absence of player settings 2021-08-22 11:57:49 +02:00
Applevangelist 34e4825cd0 Merge pull request #1591 from bbirchnz/develop
CTLD: fix FOB units overwriting last instance, Unit Cargo Mass not working on first load
2021-08-22 08:32:18 +02:00
Ben Birch a68eeae9bd Merge remote-tracking branch 'origin/develop' into develop 2021-08-22 12:54:25 +10:00
Ben Birch e4e31b554e CTLD: fix FOB units overwriting last instance, Unit Cargo Mass not working on first load 2021-08-22 12:53:55 +10:00
Frank eba6e3f5f1 OPS Transport+Legion, Navy 2021-08-22 00:31:51 +02:00
Frank d73ebaca76 OPS
- Lots of stuff
2021-08-21 00:58:28 +02:00
Applevangelist 94167152e5 CTLD - added ability to spawn crates on ships 2021-08-20 12:33:10 +02:00
Applevangelist 830f76e909 Cleanup UTF-8 Mess 2021-08-18 18:00:38 +02:00
Applevangelist 8ae04944fe Fix for SAM pattern matching not working 2021-08-18 14:59:58 +02:00
Applevangelist c55b8d29f7 Fix for degree sign extra char 2021-08-18 11:51:41 +02:00
Applevangelist 30623f7d38 AIRBOSS / ATIS deleted extra char before degree char. Small correction for CSAR landings at Airports 2021-08-18 09:28:34 +02:00
Frank 16964520df OPS
- Lots of stuff to assign missions to multiple legions.
2021-08-18 00:25:18 +02:00
Frank 3050fdb3c3 OPS Zone 2021-08-15 00:28:03 +02:00
Frank 77fc2c5cf1 Update OpsGroup.lua 2021-08-12 11:41:30 +02:00
Frank b21c3ed4e9 OPS Cleanup 2021-08-12 11:07:28 +02:00
Frank 93f4b345c5 OPS Generalization 2021-08-12 00:17:55 +02:00
Frank 88e59a2739 OPS
- Ground ops
2021-08-11 10:40:16 +02:00
Frank 86bb256bf1 OPS
- Added Cohort and Legion classes
- Added Platoon and Brigade classes
2021-08-10 00:40:17 +02:00
Applevangelist 9a05f5bc93 Merge pull request #1589 from FlightControl-Master/Applevangelist-patch-5
CSAR fix for #1588
2021-08-09 09:18:51 +02:00
Applevangelist bce28cf389 CSAR fix for #1588
Fixes #1588
2021-08-09 09:06:15 +02:00
Frank 629c5e7739 AUFTRAG
- Recon Mission
2021-08-06 23:16:48 +02:00
Frank ed402e2f5f OPS Chief 2021-08-06 10:01:23 +02:00
Frank 4a56c7523d Wingcommander 2021-08-05 12:44:43 +02:00
Frank 218d9f48b0 Merge branch 'FF/Ops' into FF/OpsDev 2021-08-05 00:24:23 +02:00
Frank f67cf99477 OPS and SCHEDULER 2021-08-05 00:23:25 +02:00
Applevangelist 2201b2adda Update Utils.lua
Corrected self to BASE
2021-08-04 11:07:47 +02:00
Applevangelist 6b36421bce Merge pull request #1585 from FlightControl-Master/Applevangelist-patch-4
Update CSAR.lua
2021-08-04 08:04:21 +02:00
Frank 8c573c65d4 Update FlightControl.lua 2021-08-03 22:37:27 +02:00
Applevangelist 730dabd9cf Update CSAR.lua 2021-08-03 07:16:42 +02:00
Frank 69175e1b19 FC 2021-08-02 23:34:42 +02:00
Frank a5ad58e516 FC 2021-08-02 21:57:53 +02:00
Frank 82b4631341 Flightcontrol 2021-08-02 18:41:33 +02:00
Frank a1c9c1538d Merge branch 'FF/Ops' into FF/OpsDev 2021-08-02 11:59:32 +02:00
Frank 1a53f58540 OPS 2021-08-02 11:57:45 +02:00
Applevangelist 1b414b840e added AP check on landing/rescue 2021-07-31 15:50:50 +02:00
Applevangelist 642cc0e98f Added self.FARPRescueDistance reduced landing check to one call 2021-07-31 13:05:51 +02:00
Applevangelist 63431bb54b Couple of changes to make finding the distance to nearest pilot more stable 2021-07-30 17:30:32 +02:00
Frank d64de26ded OPS
- many fixes and improvements
2021-07-29 13:43:29 +02:00
Applevangelist 8b45067226 Various patches for AI_CARGO 2021-07-29 12:41:27 +02:00
Applevangelist 061032e3d7 Transition cleanup for AI Helicopter, deleted speed test bc in 20% of cases AI lands shit, which stops the FSM 2021-07-28 18:31:39 +02:00
Applevangelist 82432686aa Fixed display messages to all SAR, added option to suppress messaging 2021-07-27 14:10:10 +02:00
Applevangelist b66d2039be Added function to set speed and height parameters for landing 2021-07-27 14:09:10 +02:00
Applevangelist d245a73d7f Make Destroy() silent for scoring 2021-07-26 09:24:52 +02:00
Applevangelist f0037151e6 CTLD - added factor for troops extraction, making Destroy()s silent for scoring, refined autohoverload messaging 2021-07-26 09:24:35 +02:00
Applevangelist 52d494f573 Merge pull request #1582 from bbirchnz/develop
CTLD: fix troops being lost when crates dropped
2021-07-25 09:06:16 +02:00
Ben Birch 36a2d71731 CTLD: fix troops being lost when crates dropped 2021-07-25 13:46:15 +10:00
Frank 615a220acb Update OpsGroup.lua 2021-07-24 23:56:27 +02:00
Frank c718584755 Update OpsGroup.lua 2021-07-24 23:25:26 +02:00
Applevangelist 4db0ea616d Correct opendoor check to include anyone loaded 2021-07-24 15:53:20 +02:00
Applevangelist 5439e60078 Merge pull request #1580 from bbirchnz/ctld-add-mass
CTLD: Enable mass on cargo
2021-07-24 15:04:49 +02:00
Ben Birch a6880d4569 Add SetUnitInternalCargo to UNIT
Add PerCrateMass to CTLD_CARGO (default = 0kg)
Update unit internal cargo after each load/unload operation.
Add mass to cargo reports
2021-07-24 22:39:26 +10:00
Frank 65e852f341 OPS Transport 2021-07-24 01:06:44 +02:00
Frank 4ffdf9e536 Merge branch 'develop' into FF/Ops 2021-07-23 18:49:35 +02:00
Applevangelist 8f698e3e62 Changed Messaging Structure on Approach 2021-07-23 16:29:56 +02:00
Applevangelist 61481e6e9a CSAR updates to messaging. Detect if far approach note exceeds 8km for smoke/flare request 2021-07-23 11:19:53 +02:00
Applevangelist 49397df90b CTLD - added repair capabilties for VEHICLE and FOB types of CTLD_CARGO 2021-07-22 20:17:40 +02:00
Applevangelist 7b254a08fb Merge pull request #1579 from FlightControl-Master/Applevangelist-inteldlink
Update Intelligence.lua
2021-07-22 11:37:51 +02:00
Applevangelist 5bebbcf5eb Update Intelligence.lua
Added FSM functions and documentation for INTEL_DLINK
2021-07-22 11:36:21 +02:00
Applevangelist 83fd48e2f4 Merge pull request #1578 from madmoney99/develop
Airboss update for wind over deck
2021-07-22 08:03:32 +02:00
madmoney99 f5b25370b0 Change to wind measure for Skipper
Previous value 50m produced an incorrect heading and strength based on the actual wind over deck.
2021-07-21 22:51:29 -07:00
Tony Goodale f68d3209ac Merge branch 'FlightControl-Master:develop' into develop 2021-07-21 22:44:11 -07:00
Applevangelist 2ab7f784c9 Merge pull request #1576 from FlightControl-Master/Applevangelist-CTLD
Update CTLD.lua
2021-07-21 18:47:52 +02:00
Applevangelist 1e8d99a591 Merge pull request #1577 from FlightControl-Master/Applevangelist-INTEL
Update Intelligence.lua
2021-07-21 18:47:40 +02:00
Applevangelist d517cba765 Update Intelligence.lua
no dupe docs
2021-07-21 18:45:57 +02:00
Applevangelist 552eb5b9d8 Update CTLD.lua
Add housekeeping for dropped troops
2021-07-21 18:40:43 +02:00
Applevangelist 684c4ea113 Allow MANTIS to use INTEL_DLINK 2021-07-21 18:22:46 +02:00
Applevangelist 4dfaca610f INTEL - bug fixes, added new datalink class 2021-07-21 18:22:31 +02:00
Applevangelist 8a53998251 MANTIS - make start random async, so detection for multiple MANTIS objects works better
INTEL - added function to alter detection types, typos corrected etc
2021-07-20 18:30:11 +02:00
bbirchnz 6690f70b05 fix CTLD:ActivateZone not processing default correctly and using wrong zone table (#1575) 2021-07-19 07:16:21 +02:00
Applevangelist 96d1d3cb66 Light code cleanup, added docu for troop extract 2021-07-18 14:53:00 +02:00
bbirchnz 09785ef451 - ctld: add troop extract (#1574) 2021-07-18 13:01:45 +02:00
Applevangelist 25e118f3dc Added correct Player Mi-8MT unitname
CSAR - logic change to detect dead pilots, if they are not set to immortal. Added FSM event "KIA"
2021-07-17 15:48:18 +02:00
Frank 78b3e3c60b OPS Respawn 2021-07-15 22:25:02 +02:00
Applevangelist efe41a5e21 CSAR and CTLD - use Frequency generation moved to UTILS
CTLD - added option to drop crates anywhere
MANTIS - added state tracker to call Green/Red state change events only once
UTILS - added Marianas NDBs to Frequency generation
2021-07-15 17:16:30 +02:00
Frank 835041e5f6 OPS 2021-07-14 21:00:34 +02:00
Applevangelist 93a8086ff6 Update Mantis.lua (#1569)
Added state tracker so that Red/Green Events only get triggered when a state actually changes.
2021-07-14 15:37:57 +02:00
Applevangelist 1ac40684de Added option to force description on injected pilots for scripting 2021-07-14 08:39:54 +02:00
Applevangelist 433d1bbf57 MANTIS - Change logic to FSM, added functions
CSAR - advanced options to name injected AI downed pilots
CTLD - added Herc speed check
2021-07-13 17:50:44 +02:00
Applevangelist e33de03522 CSAR - honor settings NM vs KM
CTLD - documentation corrections
UTILS - added functions to generate beacon frequency tables FM,VHF,UHF and valid laser codes for JTACs
2021-07-12 19:17:39 +02:00
Applevangelist 86fedbfaae Updated noise level 2021-07-12 18:16:22 +02:00
Applevangelist c0f4eef896 Slightly changed versions of Mantis, Sead and Shorad as the Emissions On/Off stuff ED introduced doesn't really work well. 2021-07-12 18:10:12 +02:00
Frank a2f3bf3a8c Merge branch 'develop' into FF/Ops 2021-07-12 15:27:24 +02:00
Frank 1b717e4683 AUFTRAG
- Added push time
2021-07-12 15:27:08 +02:00
Applevangelist 52e2ac7174 Added documentation 2021-07-11 18:31:17 +02:00
Applevangelist 3d6b053eb4 Added function to check if a loading door on a heli is open 2021-07-11 18:31:09 +02:00
Frank 268eb1d60d OPS 2021-07-11 18:15:25 +02:00
Applevangelist a69865b8c9 -- -- (added 0.1.8) - allow to set far/near distance for approach and optionally pilot must open doors
--         self.approachdist_far = 5000 -- switch do 10 sec interval approach mode, meters
--         self.approachdist_near = 3000 -- switch to 5 sec interval approach mode, meters
--         self.pilotmustopendoors = false -- switch to true to enable check of open doors
2021-07-10 16:56:35 +02:00
Applevangelist 4a1df3d5cc -- -- (added 0.1.8) - allow to set far/near distance for approach and optionally pilot must open doors
--         self.approachdist_far = 5000 -- switch do 10 sec interval approach mode, meters
--         self.approachdist_near = 3000 -- switch to 5 sec interval approach mode, meters
--         self.pilotmustopendoors = false -- switch to true to enable check of open doors
2021-07-10 16:56:35 +02:00
Frank 6dfd757ea1 OPS 2021-07-08 22:59:29 +02:00
Frank fc1adf3b94 OPS Transport 2021-07-08 12:21:10 +02:00
Frank be2d1d7895 Update OpsTransport.lua 2021-07-07 11:33:51 +02:00
Frank 9e7c360912 Merge branch 'develop' into FF/Ops 2021-07-06 21:57:31 +02:00
Frank 51acd33d19 Merge branch 'master' into develop 2021-07-06 21:57:08 +02:00
Frank af3dbe2f86 Merge branch 'develop' into FF/Ops 2021-07-06 21:56:53 +02:00
Frank 97668e5413 Update FlightGroup.lua
- Fixed flight of airwing is going to tanker even if fuellowrefuel switch is false
2021-07-06 21:56:15 +02:00
Frank 464fde0ed2 OPS
- MSRS
- Callsign
2021-07-06 21:13:50 +02:00
cammel tech 65bd7909e1 Example for CTLD > SCORING added (#1566)
* Example added

Example for the connection to the SCORING Class.

* kleiner Fehler eingeschlichen
2021-07-06 20:26:20 +02:00
Applevangelist 5d3ea57d4d CSAR give scripted spawned pilots a name.
CTLD corrected that generic troops could be spawned only once.
2021-07-06 20:24:35 +02:00
Applevangelist b7bc3cfbcf Spawn crates in a wider radius. Also build, when only one crate is required. 2021-07-05 18:54:45 +02:00
Applevangelist 04ef32420b Merge pull request #1567 from thejuju/develop
Add ATC Ground Mariana Islands support
2021-07-05 14:44:02 +02:00
Julien B a3d8a48b92 Add ATC Ground Mariana Islands support
Added ATC_GROUND_MARIANAISLANDS
Supported optional airbase ZONE_POLYGON boundaries (like initially intented) when there is provided, fallback remain a ZONE from the center of the airfield.
Some airports are bigger than the default radius area and need custom boundaries to work properly on the edge of it.
2021-07-05 13:09:34 +02:00
Applevangelist ef86d1d7cb Merge pull request #1562 from cammeltech/SCORING-reactivate_destroy
Reactivate the :destroy() event on clients with scoring below thresmark
2021-07-04 18:10:45 +02:00
Applevangelist 00b3e9b371 Merge pull request #1564 from justin-lovell/justin-lovell-mark-changed-event
Synchronize Text with Wrapper State
2021-07-04 18:10:35 +02:00
Applevangelist 0d02f56855 Merge pull request #1565 from justin-lovell/updated-debug-msg
Correcting typo for debug message
2021-07-04 18:10:21 +02:00
Applevangelist 48aa841add ATIS - addede rainy presets 1-3
CTLD - avoid "preloading" when pilot leaves/crashes and rejoins
CSAR - added option for autosmokedistance
2021-07-04 18:04:27 +02:00
Applevangelist 4ba52212a9 ATIS - addede rainy presets 1-3
CTLD - avoid "preloading" when pilot leaves/crashes and rejoins
CSAR - added option for autosmokedistance
2021-07-04 18:04:08 +02:00
Justin Lovell a14bca1059 Synchronize Text with Wrapper State
Bug - text is not synchronized with the wrapper state, hence the `GetText()` will be incorrect.

Method `TextChanged` does not exist, resulting `nil` reference errors when the players update markers. Current implementation of `MARKER:OnEventMarkChange(EventData)` is not implemented the same as its siblings of `OnEventMarkRemoved` and `OnEventMarkAdded`. The siblings would move the FSM accordingly -- aligned implementation
2021-07-03 23:30:45 +10:00
Justin Lovell a7e07af24f Correcting typo for debug message
Small PR
2021-07-03 23:24:04 +10:00
Applevangelist e14d655447 Changed default fallback freq to 333.00Khz 2021-07-03 09:30:04 +02:00
Frank 74bdeaf4f7 AIRWING 2021-07-02 23:11:51 +02:00
Applevangelist 9591c62175 corrected autovalue for frequency - thanks to shadowze 2021-07-02 20:22:43 +02:00
Applevangelist 39c46dcab0 Changed frequency logic, some documentation changes 2021-07-02 20:15:12 +02:00
Applevangelist 299e08f53d additional checks to ensure only human players, extra checks in the logic, some logic errors corrected. 2021-07-02 17:52:58 +02:00
wob3155@posteo.de 12555a6ff1 Reactivate the :destroy() event on clients with scoring below thresmark 2021-07-02 08:56:28 +02:00
Frank 1cc012c7d1 Merge branch 'develop' into FF/Ops 2021-07-02 08:53:44 +02:00
Frank 28c6810878 Merge branch 'master' into develop 2021-07-02 08:52:07 +02:00
Frank 1ed36fdff4 Merge branch 'develop' into FF/Ops 2021-07-01 23:56:38 +02:00
Frank 26801cf206 Merge branch 'master' into develop 2021-07-01 23:54:57 +02:00
Frank c80cebb824 WAREHOUSE, AIRWING & SQUADRON
- Added function for hot start to SQUADRON
- Addressed bug #1560
2021-07-01 23:54:24 +02:00
Frank 3c6e8d6d01 OPS
- Transport
- Respawn
2021-07-01 12:29:29 +02:00
Applevangelist 76a53ab154 Added extra checks for Beacon refresh 2021-07-01 09:07:01 +02:00
Frank fa3e387dd1 OPS 2021-06-30 23:23:41 +02:00
Applevangelist dca626bbcb CTLD - added option to suppress messaging, added event for OnAfterTroopsRTB
CSAR - minor bugfix
2021-06-30 17:59:43 +02:00
Applevangelist 3289ad2817 Added basic support for Hercules mod 2021-06-29 17:49:42 +02:00
Applevangelist 5a022a2246 Messages going to SAR flights only 2021-06-29 08:50:46 +02:00
Frank b012c5b2aa OPS Transport
- Improved cargo bay weight calculation.
2021-06-28 13:17:55 +02:00
Frank a861f8d9d4 OPS 2021-06-25 21:13:24 +02:00
Frank 36669c80da OPSTRANSPORT 2021-06-25 13:23:56 +02:00
Applevangelist 2ff128f184 Added Docu for functions 2021-06-25 12:39:02 +02:00
Applevangelist 3b44aba341 Updated frequency test 2021-06-24 08:34:14 +02:00
Frank 978be4e383 OPS Transport 2021-06-23 17:20:51 +02:00
Applevangelist d4cdfcc48c Corrected Mi-8MTV2 Unit Type Name 2021-06-23 14:09:09 +02:00
Applevangelist 5123ab0720 Update CTLD.lua (#1558)
corrected fsm function name headlines in documentation
2021-06-23 09:47:05 +02:00
Applevangelist 5021a1e1f3 Update CTLD.lua 2021-06-22 18:26:44 +02:00
Applevangelist 576281a612 Update CSAR.lua (#1554)
Added options to limit number of downed pilots via Events (mission designers can still "inject" downed pilots):
`self.limitmaxdownedpilots = true
 self.maxdownedpilots = 10`
2021-06-22 18:24:46 +02:00
Applevangelist b84c0aba59 Update Moose.files (#1556) 2021-06-22 18:24:36 +02:00
Applevangelist ee503a378e Update Modules.lua (#1557)
added CTLD
2021-06-22 18:24:24 +02:00
Applevangelist f235037cb9 Create CTLD.lua (#1555)
Player Heli Cargo and Troops Ops :)
2021-06-22 18:24:11 +02:00
Applevangelist 0cd1cd97a6 Update CSAR.lua (#1553) 2021-06-22 13:11:12 +02:00
Frank 74513f1b5c Merge branch 'develop' into FF/Ops 2021-06-22 12:18:45 +02:00
Frank 231c5bfea7 Ops 2021-06-22 12:18:25 +02:00
Frank cfd0e4ba85 Merge branch 'master' into develop 2021-06-19 22:28:30 +02:00
Applevangelist bf33e4ed4f Update CSAR.lua (#1552) 2021-06-18 12:12:54 +02:00
Frank 6290db035d Merge branch 'develop' into FF/Ops 2021-06-15 22:00:14 +02:00
Applevangelist cd1935be1d Update CSAR.lua (#1551) 2021-06-15 15:49:58 +02:00
Applevangelist 64262d6ecc Update CSAR.lua (#1550) 2021-06-15 10:32:52 +02:00
Applevangelist 270c69344f Update CSAR.lua
Updated documentation / clarification. Added feature docu on using SRS
2021-06-15 07:42:45 +02:00
Applevangelist 10a0793af7 Update CSAR.lua
Small updates to reflect correct measurements. Options to SRS TTS.
2021-06-14 19:15:58 +02:00
Applevangelist 1b37af321f Update CSAR.lua
Small updates
2021-06-14 16:21:47 +02:00
Applevangelist 7cde279be1 Update Modules.lua
added CSAR module
2021-06-14 13:20:00 +02:00
Applevangelist 0396741f3d Create CSAR.lua
Initial Release
2021-06-14 13:18:27 +02:00
Applevangelist 117cf8888a Update Globals.lua 2021-06-13 10:39:07 +02:00
Frank 83db7b32e8 Merge branch 'master' into FF/Ops 2021-06-12 22:59:20 +02:00
Frank d496d3d16e Merge branch 'master' into develop 2021-06-12 22:23:10 +02:00
Frank 6b801247ab Merge branch 'FF/MasterDevel' into FF/Ops 2021-06-11 23:41:52 +02:00
Frank 4c6cd31bfc Merge branch 'FF/MasterDevel' into FF/Ops 2021-06-10 23:33:27 +02:00
Frank a8ef096f24 Merge branch 'FF/MasterDevel' into FF/Ops 2021-06-10 23:23:30 +02:00
Applevangelist c8d2a7e833 Added commands for immortal and invisible to Wrapper.Group#GROUP (#1547)
* Added function for message duration (#1542)

... and correct flash status setting

* Update Spawn.lua (#1544)

* Update Spawn.lua

* Update Group.lua (#1546)

Added invisible and immortal commands on GROUP level.
2021-06-10 11:59:50 +02:00
Frank 783391838b Merge branch 'FF/MasterDevel' into FF/Ops 2021-06-10 00:19:02 +02:00
Frank 7c37d8b204 Merge branch 'FF/MasterDevel' into FF/Ops 2021-06-09 13:19:14 +02:00
Applevangelist 65ed8825b0 Update Intelligence.lua
Added functionality to calculate the position of a cluster after x seconds, based on trajectory (average speed and heading) of a cluster
*  INTEL:CalcClusterFuturePosition(cluster,seconds)
Will also draw arrows on the map if `self.clustermarkers` is true and `self.verbose > 1`
Change cluster coordinate updates to better suite cluster movement
2021-06-08 15:59:36 +02:00
Applevangelist af9324dd5f master updates to develop for InitCleanup() and CC Messages (#1545)
* Added function for message duration (#1542)

... and correct flash status setting

* Update Spawn.lua (#1544)

* Update Spawn.lua
2021-06-07 18:26:43 +02:00
Frank 064f727676 Merge branch 'FF/MasterDevel' into FF/Ops 2021-06-05 23:45:15 +02:00
Frank 8025862fb9 Merge branch 'FF/MasterDevel' into FF/Ops 2021-06-01 23:20:59 +02:00
Frank 2544ec5587 Update SRS.lua 2021-05-30 01:44:36 +02:00
Frank 6c823b0137 Merge branch 'FF/MasterDevel' into FF/Ops 2021-05-30 01:36:43 +02:00
Frank 88d44fa654 Merge branch 'develop' into FF/Ops 2021-05-28 23:01:47 +02:00
Frank 8b6f9f9de7 Merge branch 'master' into develop 2021-05-28 23:01:15 +02:00
Applevangelist cb14961dcd Update Zone.lua (#1541)
added function `ZONE_POLYGON_BASE:Boundary()`
2021-05-26 15:54:20 +02:00
Applevangelist dab486ec99 Update Controllable.lua
Typo in `OptionDisperseOnAttack()`
2021-05-26 09:16:26 +02:00
Shadowze 75849fbfb5 Update Positionable.lua
function added to work out if a unit is a submarine
2021-05-25 22:30:16 +01:00
Frank f984ff044b Merge branch 'master' into develop 2021-05-25 21:13:36 +02:00
Frank aaf5f295da Merge branch 'develop' into FF/Ops 2021-05-20 23:27:05 +02:00
Frank 8f612f2017 Merge branch 'master' into develop 2021-05-20 23:25:29 +02:00
Frank a2808163a7 Boom and Probe 2021-05-20 23:23:12 +02:00
Frank e4aa23ce3d Update Point.lua 2021-05-15 00:29:20 +02:00
Frank 1b3cac9424 Merge branch 'FF/MasterDevel' into FF/Ops 2021-05-13 23:38:17 +02:00
Applevangelist e49020b905 Update README.md 2021-05-12 09:19:07 +02:00
Frank d68dcaf69a Merge branch 'develop' into FF/Ops 2021-05-11 14:52:31 +02:00
Frank 856c3578f6 Merge branch 'master' into develop 2021-05-11 11:59:48 +02:00
Tony Goodale 18c6ea39ce Merge pull request #7 from FlightControl-Master/develop
Develop
2021-05-10 15:47:14 -07:00
Frank 1ce46c016c Cargo 2021-05-10 00:14:07 +02:00
Frank 296944c23c Merge branch 'develop' into FF/Ops 2021-05-07 22:57:34 +02:00
Frank 4f772fecdc Merge branch 'master' into develop 2021-05-07 21:56:17 +02:00
Frank cdd22444b9 Merge branch 'master' into develop 2021-05-07 21:49:24 +02:00
Frank 15848bc8c4 Merge branch 'master' into FF/Ops 2021-05-07 17:47:41 +02:00
Applevangelist 9eba6d607c Updated doc images 2021-05-06 09:30:06 +02:00
Applevangelist e9d3c7c2e7 Update MarkerOps_Base.lua 2021-05-05 19:02:46 +02:00
Applevangelist ad16c6d44f Include MarkerOps_Base (#1533)
Include MarkerOps_Base
2021-05-05 11:56:00 +02:00
Applevangelist 2046958bd6 Added MarkerOps_Base.lua 2021-05-05 11:44:35 +02:00
Applevangelist 0046533d53 Added base class for action based on marker additions, changes, deletions and text keywords 2021-05-05 11:44:17 +02:00
Applevangelist ce7e152e13 Updated Shorad and Set 2021-05-04 12:59:21 +02:00
Tony Goodale edcdc057e6 Merge pull request #6 from FlightControl-Master/develop
Develop
2021-05-01 15:40:23 -07:00
Frank cfa851beea Merge branch 'master' into FF/Ops 2021-05-02 00:25:07 +02:00
Frank f5d8efe86e Merge branch 'master' into develop 2021-05-01 22:45:48 +02:00
Applevangelist 7c8e5033ec Merge pull request #1527 from FlightControl-Master/AA-1
Update Sead.lua
2021-05-01 17:29:43 +02:00
Applevangelist 22ec94b374 Merge pull request #1528 from FlightControl-Master/AA-2
Update Shorad.lua
2021-05-01 17:27:22 +02:00
Applevangelist 5cd3a172f1 Merge pull request #1529 from FlightControl-Master/AA-3
Update Mantis.lua
2021-05-01 17:24:33 +02:00
Applevangelist a89a3b38ce Update Mantis.lua
Adjustments for 2.7
2021-05-01 17:21:53 +02:00
Applevangelist 3202702612 Update Shorad.lua
Adjustments for 2.7
2021-05-01 17:20:35 +02:00
Applevangelist 725e32f439 Update Sead.lua
Adjust to Event changes
2021-05-01 17:19:10 +02:00
Applevangelist 7da1905ad3 Update Event.lua (#1525)
Updates for Events 33 and 6 - makes scoring also work again for STATIC targets
2021-05-01 14:22:01 +02:00
Frank 421005a3b6 event backfixed 2021-04-30 11:53:57 +02:00
Applevangelist d5bf28f799 Update AirWing.lua (#1521)
Markpoint honored for direct calls from #OPSGROUP
2021-04-29 18:20:03 +02:00
Frank 990f748e42 Update Database.lua 2021-04-27 09:19:33 +02:00
Applevangelist a466365949 Update Controllable.lua (#1519)
Error line 1463
2021-04-25 20:31:02 +02:00
Frank b12f71c430 Merge branch 'develop' into FF/Ops 2021-04-23 13:38:28 +02:00
Frank 236a69e5dc Merge branch 'master' into develop 2021-04-23 13:29:37 +02:00
Applevangelist 9458243926 Merge pull request #1516 from FlightControl-Master/AA
Update Controllable.lua
2021-04-23 11:00:50 +02:00
Applevangelist 41274e7801 Update Controllable.lua 2021-04-23 10:59:22 +02:00
Applevangelist 0259e41ce8 Create .luacheckrc 2021-04-22 10:10:59 +02:00
Applevangelist e78f9cbd46 Merge pull request #1512 from FlightControl-Master/aa
Update Airboss.lua
2021-04-22 08:53:52 +02:00
Applevangelist 9d6851adec Update Airboss.lua
Escape error 17933
2021-04-22 08:30:19 +02:00
Applevangelist 4668f072af Merge pull request #1511 from FlightControl-Master/AA-1
Update Airboss.lua
2021-04-22 08:21:00 +02:00
Applevangelist a1a414925f Update Airboss.lua 2021-04-22 08:19:56 +02:00
Applevangelist 19eb9dca30 Update Utils.lua 2021-04-20 18:49:54 +02:00
Applevangelist 8464a2ba43 Merge pull request #1507 from FlightControl-Master/Applevangelist-patch-1
Update Airbase.lua
2021-04-20 16:52:28 +02:00
Applevangelist a8549e2b7d Update Airbase.lua 2021-04-20 16:50:00 +02:00
Applevangelist 2531a25c9e Update Group.lua
Add EnableEmissions
2021-04-20 11:36:59 +02:00
Frank 2f7b7eeddd Merge branch 'master' into develop 2021-04-18 14:49:37 +02:00
Frank ab1ec54c03 Merge branch 'master' into develop 2021-04-18 14:34:46 +02:00
Frank a1ca605206 Merge branch 'master' into develop 2021-04-17 23:19:42 +02:00
Frank a7b444dfea Update OpsGroup.lua 2021-04-17 09:29:55 +02:00
Frank 64b35b9cb3 Merge branch 'develop' into FF/Ops 2021-04-16 23:15:30 +02:00
Frank 4a8d52b328 Merge branch 'master' into develop 2021-04-16 23:06:04 +02:00
Pikes 3cbf6fff90 Merge pull request #1490 from Applevangelist/patch-82
Update Event.lua workaround for 2.7
2021-04-16 18:01:25 +01:00
Frank 2693e76483 Update Airboss.lua 2021-04-15 21:13:35 +02:00
Applevangelist b232a5da37 Update Event.lua workaround for 2.7
Same as for Event 31
2021-04-15 13:02:59 +02:00
Frank e50fc00583 Merge branch 'develop' into FF/Ops 2021-04-14 23:44:43 +02:00
Frank 4b8802af37 Merge branch 'master' into develop 2021-04-14 23:42:48 +02:00
Frank ebd69fd10d Merge pull request #1482 from Applevangelist/patch-74
Update FlightGroup.lua
2021-04-12 15:55:50 +02:00
Applevangelist c1a8c08880 Update FlightGroup.lua 2021-04-12 13:02:16 +02:00
Frank 647fb6acbf Merge branch 'develop' into FF/Ops 2021-04-07 20:54:19 +02:00
Frank ede692ea2a Merge branch 'master' into develop 2021-04-07 20:53:27 +02:00
Frank ca44e2762b Update OpsGroup.lua 2021-04-07 20:53:15 +02:00
Frank eda70742eb Merge pull request #1486 from Applevangelist/patch-78
Update AirWing.lua
2021-04-04 22:03:49 +02:00
Frank b81e3e9e6d Merge pull request #1485 from Applevangelist/patch-77
Update Intelligence.lua
2021-04-04 22:03:40 +02:00
Applevangelist e766eaeccc Update AirWing.lua
Avoid loop if mission is governed by an Airwing. Mission cancel will ask airwing to cancel will ask flightgroup to cancel, which doesn't work if the latter is dead. Rare but happens.
2021-04-04 13:11:25 +02:00
Applevangelist bab61271f2 Update Intelligence.lua
Make Markers Coalition specific
2021-04-04 13:07:54 +02:00
Applevangelist b1465d89a6 Update FlightGroup.lua
Added check for velocity for the RTB loop (if group is taxiing). Added OutOfAAMissiles.
2021-04-04 12:49:40 +02:00
Frank 05b1ddf013 Merge pull request #1483 from Applevangelist/patch-75
Update AirWing.lua
2021-04-03 22:25:51 +02:00
Applevangelist 903e8711f7 Update AirWing.lua
Make Patrolpoint Markes Switchable
2021-04-01 13:28:59 +02:00
Applevangelist 31b93fb42c Update FlightGroup.lua
Avoid endless when plane/heli is not airborne by needs to RTB
2021-04-01 13:21:40 +02:00
Frank e16bbfc2b9 Merge branch 'develop' into FF/Ops 2021-03-29 19:55:35 +02:00
Frank 220e004d73 Merge branch 'master' into develop 2021-03-29 19:55:21 +02:00
Frank 3136861b24 Merge branch 'develop' into FF/Ops 2021-03-29 18:02:23 +02:00
Frank dc2693bead Merge branch 'master' into develop 2021-03-29 18:02:00 +02:00
Frank d7da8c4253 Merge branch 'develop' into FF/Ops 2021-03-29 09:55:13 +02:00
Frank c1ff5831ad Merge branch 'master' into develop 2021-03-29 09:53:51 +02:00
Frank ac5646075b Merge pull request #1481 from madmoney99/develop
Airboss CASE III fix for OS/AA
2021-03-29 00:31:46 +02:00
madmoney99 5a1faba796 CASE III fix for OS/AA 2021-03-28 15:25:59 -07:00
Tony Goodale 4ab16cb276 Merge pull request #5 from FlightControl-Master/develop
Merge pull request #1478 from madmoney99/develop
2021-03-28 15:12:27 -07:00
Frank eb1e885c0a Merge branch 'develop' into FF/Ops 2021-03-28 20:33:08 +02:00
Frank 00ff9a11b8 Merge branch 'master' into develop 2021-03-28 20:30:19 +02:00
Frank 8eabc024bf Merge pull request #1479 from madmoney99/develop
Update Airboss.lua
2021-03-23 08:44:14 +01:00
madmoney99 a848af0753 Update Airboss.lua 2021-03-22 19:01:04 -07:00
Frank f4e7a3a314 Merge pull request #1478 from madmoney99/develop
Airboss formating fixes
2021-03-22 22:19:29 +01:00
madmoney99 d83283c709 Update Airboss.lua
formatting fixes
2021-03-22 10:10:33 -07:00
Tony Goodale a35112a6f3 Merge pull request #4 from FlightControl-Master/develop
Merge pull request #1476 from madmoney99/develop
2021-03-22 10:01:53 -07:00
Frank 66c012a30d Merge pull request #1476 from madmoney99/develop
Develop Airboss grading additions
2021-03-22 12:03:58 +01:00
madmoney99 7b92b7853d Grading Additions
Addition of:
- AA - Angled Approach call (advisory)
- Drift Right/Left - DR/DL (advisory)
- Overshoot - OS - graded for start

Updated default SetMPWireCorrection(Dcorr) to 12 from 8.7 based on feedback.

Minor clean up and updates for intro section to include new additions and other changes previously made.

TonyG
2021-03-21 17:40:44 -07:00
madmoney99 6c9f10e6a8 Revert "Grading additions"
This reverts commit 6db2c4465d.
2021-03-21 17:38:06 -07:00
madmoney99 6db2c4465d Grading additions
Addition of:
 - AA - Angled Approach call (advisory)
 - Drift Right/Left - DR/DL (advisory)
 - Overshoot - OS - graded for start

Updated default SetMPWireCorrection(Dcorr) to 12 from 8.7 based on feedback.

Minor clean up and updates for intro section to include new additions and other changes previously made.

TonyG
2021-03-21 17:35:16 -07:00
Tony Goodale c0cc960df5 Merge pull request #3 from FlightControl-Master/develop
Develop
2021-03-21 14:53:53 -07:00
Frank 968240ad44 Merge pull request #1473 from Applevangelist/patch-72
Update Sead.lua
2021-03-14 22:46:16 +01:00
Applevangelist 50f3016711 Update Sead.lua
latest
2021-03-10 11:36:10 +01:00
Frank 56e2b06e9d OPS Cargo 2021-03-07 23:47:29 +01:00
Frank c02f69720a Merge pull request #1471 from Applevangelist/patch-71
Update Controllable.lua
2021-03-04 16:33:56 +01:00
Frank 96df7d1e42 Merge pull request #1470 from Applevangelist/patch-70
Update Intelligence.lua
2021-03-04 16:33:46 +01:00
Applevangelist 1d4caf7588 Update Controllable.lua
2 functions missing though they are in the doc header
2021-03-04 16:15:57 +01:00
Applevangelist b0e3201d3c Update Intelligence.lua
Added Docu
2021-03-04 11:13:30 +01:00
Frank bab097958f Merge branch 'develop' into FF/Ops 2021-03-03 00:03:52 +01:00
Frank f4a3f6d433 OPS 2021-03-03 00:03:39 +01:00
Frank e73ab89a18 Merge pull request #1469 from madmoney99/develop
Develop
2021-03-02 22:46:31 +01:00
madmoney99 187643f6ae Groove time additions
Changes on screen description of groove times to match NATOPs grading
NESA
LIG
Changes unicorn groove time from 16-18secs to 15-18.99 seconds.

No change to grading.  Reference GitHub issues 1445 &1446.
2021-03-02 13:36:54 -08:00
Tony Goodale 3c9bdb2915 Merge pull request #1 from FlightControl-Master/develop
Develop
2021-03-02 13:28:58 -08:00
Frank 5241642447 Merge branch 'master' into develop 2021-03-02 21:19:41 +01:00
Frank 3b2cbea1c4 Update OpsGroup.lua 2021-03-02 21:12:51 +01:00
Frank 80e3da49cb Merge pull request #1468 from Applevangelist/patch-69
Update Intelligence.lua
2021-03-02 15:34:27 +01:00
Applevangelist 1df7a12587 Update Intelligence.lua
Finalized Cluster functions, added bits and bobs
2021-03-02 14:28:37 +01:00
Frank 663a59bd71 Merge branch 'master' into develop 2021-02-28 23:26:48 +01:00
Frank ced859424b Merge branch 'master' into develop 2021-02-27 21:18:11 +01:00
Frank 4a6377c204 Ops Cargo 2021-02-27 21:17:58 +01:00
Frank fd22558207 Merge pull request #1467 from madmoney99/develop
T-45C Goshawk Parameters
2021-02-26 08:00:35 +01:00
madmoney99 a6faadea48 T-45C Goshawk Parameters
Addition of parameters for the VNAO T-45C Goshawk.
2021-02-25 12:52:50 -08:00
Frank 42a26100b7 Merge pull request #1465 from Applevangelist/patch-67
Update Intelligence.lua
2021-02-24 18:02:19 +01:00
Frank e8f4770abe Merge pull request #1464 from Applevangelist/patch-66
Update AirWing.lua
2021-02-24 18:01:44 +01:00
Applevangelist 7751d4ee88 Update Intelligence.lua
Added function to set verbosity
2021-02-24 16:22:13 +01:00
Applevangelist cdd829e7be Update AirWing.lua
Ensure correct type of tanker is going on mission
2021-02-24 16:16:28 +01:00
Frank 16bf3a89b5 Merge pull request #1461 from Applevangelist/patch-63
Update Intelligence.lua
2021-02-21 23:59:37 +01:00
Applevangelist 11cdae098b Update Intelligence.lua
Honor settings for clustermarkers
2021-02-21 19:55:48 +01:00
Frank a63ee3fa8b Merge branch 'develop' into FF/Ops 2021-02-21 11:54:06 +01:00
Frank 5cc023d1fe OPS Cargo 2021-02-21 11:53:52 +01:00
Frank c4084156ac OPS Cargo 2021-02-21 00:19:32 +01:00
Frank 302018feff OPS Cargo 2021-02-20 00:03:45 +01:00
Frank c50f6b72e7 OPS Cargo 2021-02-19 00:11:55 +01:00
Frank c0401447dd OPS Cargo 2021-02-18 00:10:17 +01:00
Frank 43680c2fc3 Merge branch 'master' into develop 2021-02-17 13:16:46 +01:00
Frank 2c92bb9d61 OPS Cargo 2021-02-17 00:29:59 +01:00
Frank dcf1a56756 Update OpsGroup.lua 2021-02-16 00:15:22 +01:00
Frank 5990ab1cc9 OPSTRANSPORT
- New class.
2021-02-15 23:19:35 +01:00
Frank 084499fa0e OPS Wait 2021-02-14 00:19:03 +01:00
Frank 74e84a73dd OPS Cargo 2021-02-13 00:09:25 +01:00
Frank 96b0393f91 OPS Cargo 2021-02-11 23:58:56 +01:00
Frank 0656c33e05 Update OpsGroup.lua 2021-02-10 23:50:37 +01:00
Frank ec1ab49b54 Merge pull request #1447 from Applevangelist/patch-51
Update Auftrag.lua
2021-02-10 21:34:12 +01:00
Applevangelist 1daa2857b2 Update Auftrag.lua
Corrected docu in NewTanker, 1 is actually boom, and 0 probe
2021-02-10 13:19:53 +01:00
Frank 8c55541d0e Update OpsGroup.lua 2021-02-08 16:27:58 +01:00
Frank c5a4776b3a OPS Cargo 2021-02-07 01:24:13 +01:00
Frank 8bb9f0d7c0 OPS Cargo 2021-02-06 09:41:24 +01:00
Frank 7d83c251a8 OPS Cargo 2021-02-03 22:51:18 +01:00
Frank ee3ead9aac OPS Cargo 2021-02-02 23:20:55 +01:00
Frank 54896e0e31 Merge pull request #1444 from rollnthndr/develop
Added a note pointing out that callsigns need to be chosen depending …
2021-02-01 08:06:11 +01:00
Frank 016198e7f2 OPS Cargo 2021-01-31 23:28:04 +01:00
Frank 0933eef4c3 Merge branch 'develop' into FF/Ops 2021-01-31 00:50:14 +01:00
Frank fe55555c67 OPS
- Fixed inAir check for spawned groups
- Reduced SCHEDULER min delay to 0.001 sec (was 0.1 sec)
2021-01-30 23:28:07 +01:00
Frank bcf8973eed OPS 2021-01-30 21:29:29 +01:00
rollnthndr 50d2e42cc3 Added VSCode settings folder and workspace file to the ignore list. 2021-01-29 18:31:19 -07:00
rollnthndr 261d1cbeba Added a note pointing out that callsigns need to be chosen depending on the type of unit that this task is being assigned to. 2021-01-29 18:15:20 -07:00
Frank 242462b9ba OPS Cargo 2021-01-29 00:32:38 +01:00
Frank fd4e478dbf Merge branch 'master' into develop 2021-01-26 12:40:15 +01:00
Frank 6b91e68668 OPS Cargo 2021-01-26 12:39:49 +01:00
Frank 7516d2af56 Merge branch 'master' into develop 2021-01-23 16:47:14 +01:00
Frank c247a98402 OPS cargo 2021-01-23 16:46:44 +01:00
Frank 83bcd55a7a Merge pull request #1439 from FlightControl-Master/wingthor_fixes
Added a table shuffler using Fisher Yeates algorithm in Utilities/Uti…
2021-01-22 23:28:42 +01:00
Wingthor 5a43936e35 Added a table shuffler using Fisher Yeates algorithm in Utilities/Utils.lua 2021-01-22 23:10:22 +01:00
Frank 35b776179e Merge branch 'master' into develop 2021-01-19 16:56:40 +01:00
Frank f4cb6df8d4 Ops
respawn
2021-01-19 16:53:22 +01:00
Frank a259b88f1d Merge branch 'develop' into FF/Ops 2021-01-16 22:57:10 +01:00
Frank 5b4f3d1c98 Merge branch 'master' into develop 2021-01-16 22:56:43 +01:00
Frank c62c21c386 FLIGHTGROUP v0.6.1
- Improved engage targets
2021-01-16 22:56:28 +01:00
Frank 17c56a11bd Merge pull request #1432 from OttoWerkr/develop
Update Scenery.lua
2021-01-15 23:53:37 +01:00
Frank 796561b8b6 Merge pull request #1433 from FlightControl-Master/FF/Ops
OPS
2021-01-15 23:44:46 +01:00
Frank 209b7a64ed Update OpsGroup.lua 2021-01-15 23:42:30 +01:00
Frank 8f56299380 OPS
**AUFTRAG**
- Added PATROLZONE type. Works for all OPSGROUPs (air, ground and sea).

**FLIGHTGROUP**
- Improved EngageTarget
- Added option to automatically engage detected targets.

**TARGET**
- Improved Zone type
2021-01-15 23:29:16 +01:00
OttoWerkr 73b1394ca7 Update Scenery.lua
Added FindByName() to SCENERY Class.
2021-01-15 14:27:43 -05:00
Frank f3a2cf7284 Patrol
- Added `FLIGHTGROUP:SetEngageDetectedOn()`
- AUFTRAG patrol zone.
2021-01-15 00:59:52 +01:00
Frank df79c765f8 Merge branch 'master' into develop 2021-01-12 17:40:40 +01:00
Frank d09737c218 Merge branch 'master' into develop 2021-01-12 13:51:26 +01:00
Frank 6b0c42ae50 Merge branch 'master' into develop 2021-01-12 10:45:11 +01:00
Frank 7363da1b54 Merge branch 'master' into develop 2021-01-09 23:48:42 +01:00
Frank 684f19c060 Merge branch 'master' into develop 2021-01-05 22:59:57 +01:00
Frank d08e4db0eb Merge branch 'master' into develop 2021-01-03 00:24:42 +01:00
Frank f1e7d8bd06 Merge branch 'master' into develop 2021-01-01 10:16:58 +01:00
Frank 1328ac061e Merge branch 'master' into develop 2020-12-31 21:22:59 +01:00
Frank 391f0fc9af Merge branch 'master' into develop 2020-12-29 23:38:44 +01:00
Frank 38cf5be738 Update Airbase.lua 2020-12-29 22:51:10 +01:00
Frank 1bb70b8697 Update Warehouse.lua
- added airbase coalition check when spawning aircraft #1413
2020-12-29 22:28:36 +01:00
Frank 6e35b80daf Update Warehouse.lua
- requests should no longer be processed if warehouse has no airbase
2020-12-29 21:41:15 +01:00
Frank a171c22ce4 Merge branch 'develop' into FF/Ops 2020-12-29 11:23:04 +01:00
Frank f56457bc28 Update Intelligence.lua
- added reject zones
2020-12-29 11:22:47 +01:00
Frank 9708de70c7 Merge branch 'master' into develop 2020-12-27 17:59:57 +01:00
Frank d68589bb70 Merge branch 'master' into develop 2020-12-23 16:10:07 +01:00
Frank 16eb38782a Merge branch 'master' into develop 2020-12-23 10:54:57 +01:00
Frank 2175e9c0d6 Merge branch 'master' into develop 2020-12-22 09:49:08 +01:00
Frank 9abd71f681 Merge branch 'develop' into FF/Ops 2020-12-21 00:13:09 +01:00
Frank d1dc829136 Merge branch 'master' into develop 2020-12-20 23:48:28 +01:00
Frank eda672bdc6 Merge branch 'develop' into FF/Ops 2020-12-19 12:48:12 +01:00
Frank 0e5dbbea79 Merge branch 'master' into develop 2020-12-19 01:18:17 +01:00
Frank f5809ef302 Merge branch 'develop' into FF/Ops 2020-12-18 23:50:59 +01:00
Frank 457ce1ece1 Merge branch 'master' into develop 2020-12-18 13:52:23 +01:00
Frank 9c9841332f Merge branch 'master' into develop 2020-12-17 13:55:38 +01:00
Frank 9470d3a2ef Merge branch 'master' into develop 2020-12-17 12:34:59 +01:00
Frank 8356271f8d Merge branch 'master' into develop 2020-12-17 12:34:04 +01:00
Frank 42a6f3272d Merge branch 'master' into develop 2020-12-16 00:12:38 +01:00
Frank 362b242c41 Merge pull request #1398 from Applevangelist/patch-20
Error in FlightGroup.lua in line 2390 as detected by HRP Zero
2020-12-15 00:36:57 +01:00
Frank 7ace7b49ca Merge branch 'develop' into FF/Ops 2020-12-15 00:14:15 +01:00
Frank 7cd902e924 Merge branch 'master' into develop 2020-12-15 00:11:34 +01:00
Applevangelist e3c14678e2 Error in FlightGroup.lua in line 2390 as detected by HRP Zero
Not searching in Paris, but in pairs :)
2020-12-14 13:37:17 +01:00
Frank bfaca75a7d Merge branch 'master' into develop 2020-12-14 12:37:45 +01:00
Frank 5aecd8c255 Ops
- Performance
2020-12-10 18:53:49 +01:00
Frank cfc0f1a1f7 Merge branch 'master' into develop 2020-12-03 23:18:32 +01:00
Frank edf657c65c Merge branch 'master' into develop 2020-11-30 11:40:34 +01:00
Frank 801d00fa26 Stuff 2020-11-30 11:38:36 +01:00
Frank eeffa31282 Update ChiefOfStaff.lua 2020-11-26 11:47:05 +01:00
Frank 206528a530 Merge branch 'FF/Ops' into FF/OpsDev 2020-11-26 10:56:17 +01:00
Frank 41690fdf7b Merge pull request #1385 from FlightControl-Master/FF/Ops
OPS
2020-11-25 11:34:41 +01:00
Frank 5b83f8e45b OPS 2020-11-25 11:27:07 +01:00
Frank 94863ed8ae Update OpsGroup.lua 2020-11-24 22:00:36 +01:00
Frank e63b99c890 Merge pull request #1379 from Applevangelist/patch-7
Update Controllable.lua
2020-11-22 15:54:03 +01:00
Frank e8542743b4 Merge pull request #1380 from Applevangelist/patch-8
Update Sead.lua
2020-11-22 15:53:14 +01:00
Applevangelist 309e1208c2 Update Sead.lua
Feature Request #1355
2020-11-22 14:17:42 +01:00
Applevangelist 3e0db05664 Update Controllable.lua
Added control to keep within limits of the options
2020-11-22 13:01:26 +01:00
Applevangelist 9573d92cc0 Update Controllable.lua
Add option to control a2a attack ranges for AIR fighter units. See https://wiki.hoggitworld.com/view/DCS_option_missileAttack
2020-11-22 12:07:49 +01:00
Frank 1abc0dcb6a Merge pull request #1378 from FlightControl-Master/FF/Ops
OPS
2020-11-21 21:55:20 +01:00
Frank 770fb3228f OPS
AUFTRAG
- Changed ESCORT engage distance input to NM (not meters)

TARGET
- Fixed bug in count targets
- Improved dead/destroyed management

FLIGHTGROUP
- Only register UNIT/STATIC kills (not SCENERY)

INTEL
- Improved agent set
2020-11-21 21:49:47 +01:00
Frank d6aa251c5e Merge pull request #1377 from Applevangelist/patch-6
Update AI_A2G_Dispatcher.lua
2020-11-20 18:17:25 +01:00
Frank 9305b870d2 Merge pull request #1376 from Applevangelist/patch-5
Update AI_A2A_Dispatcher.lua
2020-11-20 18:17:00 +01:00
Applevangelist 824a98d7a8 Update AI_A2G_Dispatcher.lua
Wrapper for player messages and function to set this on/off
2020-11-20 10:43:39 +01:00
Applevangelist 7a55ba105c Update AI_A2A_Dispatcher.lua
Wrap player messages, added function to switch on/off
2020-11-20 10:34:53 +01:00
Frank 122425338e Merge branch 'master' into develop 2020-11-20 10:18:05 +01:00
Frank 1d7f874a78 Merge pull request #1375 from FlightControl-Master/FF/Ops
OPS
2020-11-19 21:49:02 +01:00
Frank afb63a7331 Update Target.lua
- Fixed escort problem
2020-11-19 19:51:58 +01:00
Frank 0c07a660ee WAREHOUSE
- Added runway destroyed check.
2020-11-17 00:25:37 +01:00
Frank 8ffda53e3d Chief and Wing Commander
- Added back in
2020-11-16 18:11:15 +01:00
Frank 5a30c08ff6 Merge pull request #1369 from FlightControl-Master/FF/Ops
TARGET
2020-11-16 13:33:14 +01:00
Frank 9cac2674c4 Update Target.lua
- Alive checks improved
2020-11-16 13:22:53 +01:00
Frank ec3f43c69f Merge pull request #1367 from FlightControl-Master/FF/Ops
OPS
2020-11-16 00:02:20 +01:00
Frank 270dfab6a2 OPS
less output again
2020-11-15 23:49:25 +01:00
Frank 624b1f5647 Merge branch 'develop' into FF/Ops 2020-11-15 23:34:34 +01:00
Frank 84332a3ebf Update FlightGroup.lua
Fixes bug when flight searches a tanker when fuel is low.
2020-11-15 23:33:43 +01:00
Frank 63ff79ef0b Merge branch 'master' into FF/Ops 2020-11-15 23:00:50 +01:00
Frank 09452444d7 Merge branch 'master' into develop 2020-11-15 23:00:23 +01:00
Frank 75be2fc0ba Update Target.lua 2020-11-15 21:44:08 +01:00
Frank 1e0a0f8dc5 Ops 2020-11-13 23:26:56 +01:00
Frank f3d9b9c5be Ops 2020-11-06 00:29:42 +01:00
Frank cef0e444c9 Ops 2020-11-04 22:48:14 +01:00
Frank bad8dc2220 Merge pull request #1362 from FlightControl-Master/FF/Ops
Ops Enhancements
2020-10-31 22:05:58 +01:00
Frank e05d57d908 Merge branch 'develop' into FF/Ops 2020-10-31 21:22:17 +01:00
Frank 45c153f7a0 Merge branch 'master' into develop 2020-10-31 21:21:47 +01:00
Frank 0948f418cd Ops
- Fixed payload not reduced
2020-10-31 11:57:23 +01:00
Frank d027113b0b Merge branch 'develop' into FF/Ops 2020-10-28 09:48:36 +01:00
Frank ff00c2fb15 Merge branch 'master' into develop 2020-10-28 09:46:34 +01:00
Frank cd5b4ee1be Update AI_Formation.lua
- fixed bug
- set default mode to following
2020-10-28 09:44:33 +01:00
Frank ac337b8459 Ops
- Laser
2020-10-28 09:06:22 +01:00
Frank 567f7cbc29 Update OpsGroup.lua
- Laser
2020-10-27 00:12:59 +01:00
Frank d81ffcf119 Merge branch 'develop' into FF/Ops 2020-10-26 16:16:56 +01:00
Frank 6ed66a70a2 Merge branch 'master' into develop 2020-10-26 16:16:28 +01:00
Frank 9ed3b045f7 Merge branch 'master' into develop 2020-10-26 09:17:41 +01:00
Frank 2d6653c14a Ops
- Laser
2020-10-26 08:01:56 +01:00
Frank ab0e7e735a Merge branch 'develop' into FF/Ops 2020-10-20 23:40:52 +02:00
Frank 3243555d3f Merge branch 'master' into develop 2020-10-20 23:31:30 +02:00
Frank 8696ce0cc1 Ops 2020-10-20 23:04:15 +02:00
Frank 459ff26868 Ops 2020-10-19 23:33:39 +02:00
Frank 277eb2d09f Ops
- Laser
2020-10-18 00:02:48 +02:00
Frank 187093fa5a NavyGroup Update 2020-10-14 00:24:12 +02:00
Frank 6c9ce55759 Navygroup
- Fixed Astar bug
- Turn into wind stop
2020-10-13 00:29:31 +02:00
Frank f9721e501a Merge branch 'FF/Ops' into develop 2020-10-12 00:22:47 +02:00
Frank 23c22651be Update Airboss.lua
- Added USS Harry S. Truman (CVN-75) as SC type.
2020-10-12 00:21:47 +02:00
Frank 2ad81ca499 Ops 2020-10-12 00:09:02 +02:00
Frank 7792381c36 OPS 2020-10-09 17:10:24 +02:00
Frank 591dd128ce Navygroup 2020-10-09 00:15:19 +02:00
Frank ce10390406 ARMYGROUP 2020-10-07 23:26:46 +02:00
Frank bf299e5f8d Merge pull request #1353 from FlightControl-Master/FF/Ops
OPS fixes
2020-10-03 23:29:35 +02:00
Frank 7f98e703f1 Update Airbase.lua
- Fixed bug in the `AIRBASE:GetRunwaydata()` function.
2020-10-03 23:12:17 +02:00
Frank 421d27f640 Update Airboss.lua
- Fix if unit skill is not set in env.mission (DCS bug that should be fixed by ED meanwhile).
2020-10-03 21:43:09 +02:00
Frank fb1e95ab87 Pathfinding 2020-10-03 18:22:23 +02:00
Frank 3737592734 Ops
Fixes
2020-10-01 23:55:39 +02:00
Frank 6445cf01a2 Merge pull request #1350 from FlightControl-Master/FF/Ops
OPS Update
2020-09-20 00:26:10 +02:00
Frank 8e07b93eac Merge branch 'develop' into FF/Ops 2020-09-19 23:57:25 +02:00
Frank 23f6752362 Ops
- rm staff
2020-09-19 23:55:45 +02:00
Frank 19b870c038 Ops
- Less traceing.
2020-09-19 23:52:17 +02:00
Frank ca7f15e622 Ops 2020-09-19 01:15:34 +02:00
Frank d497bb25f3 Ops 2020-09-18 18:07:10 +02:00
Frank 29d694722b Ops
- Quite a few fixes while going through the example missions.
2020-09-16 23:35:13 +02:00
Frank 40ffef035b Ops 2020-09-15 18:11:19 +02:00
Frank a00c198bcc Update Warehouse.lua
- Added born check. Helps with delayed spawning on carriers.
2020-09-15 01:13:11 +02:00
Frank 717842b276 Ops 2020-09-10 00:34:17 +02:00
Frank d5c4c34759 Ops 2020-09-09 00:02:46 +02:00
Frank edb0032118 ops 2020-09-08 18:04:03 +02:00
Frank 123144d06e Ops temp 2020-09-08 00:15:29 +02:00
Frank 38f5d45d5b Merge branch 'master' into FF/Ops 2020-09-07 22:25:28 +02:00
Frank bcaf808b88 Ops little fixes 2020-09-07 22:17:33 +02:00
Frank 7b8db597ef Ops 2020-09-07 00:42:29 +02:00
Frank 18e192b235 Ops 2020-09-06 00:18:20 +02:00
Frank 5ad30277ba Ops 2020-09-05 00:56:44 +02:00
Frank 2e998dc315 Ops 2020-09-04 17:20:40 +02:00
Frank cda1658541 Ops 2020-09-04 00:58:37 +02:00
Frank 8b640912c3 Ops 2020-09-02 22:54:54 +02:00
Frank 81a773b861 Merge branch 'master' into develop 2020-09-02 00:09:15 +02:00
Frank 444cc43971 Ops 2020-09-02 00:05:05 +02:00
Frank eb86d59203 Ops 2020-09-01 11:42:45 +02:00
Frank 5ee35f3fbb Less output 2020-08-31 12:50:50 +02:00
Frank 9a91145f89 Small 2020-08-30 23:44:15 +02:00
Frank 637081ebdd Ops 2020-08-30 22:52:18 +02:00
Frank 7d2746e7be Merge branch 'develop' into FF/Ops 2020-08-30 17:24:57 +02:00
Frank c84a92c787 Merge branch 'master' into develop 2020-08-30 17:15:31 +02:00
Frank b775aaa274 Merge branch 'master' into FF/Ops 2020-08-30 17:05:09 +02:00
Frank a97d7abc24 Range Ops 2020-08-30 17:03:16 +02:00
Frank 7e73db505b Decreased Tracing 2020-08-30 01:38:18 +02:00
Frank a126906776 up 2020-08-29 21:24:15 +02:00
Frank 2d6092c114 TIMER
- Added new TIMER class.
2020-08-29 20:26:20 +02:00
Frank caef309547 Ops
- Airboss optimizations WIP
2020-08-28 13:24:29 +02:00
Frank f9ec21a2b5 Ops 2020-08-26 00:01:52 +02:00
Frank 06600b2a94 Ops 2020-08-25 17:55:53 +02:00
Frank 3f39ec0ae0 Stuff 2020-08-25 01:03:18 +02:00
Frank cfc45cf068 Warehouse marker and spawning update 2020-08-23 01:08:02 +02:00
Frank 45d809a641 Update Profiler.lua 2020-08-22 22:39:54 +02:00
Frank fcfbc5e17c Profiler
- Added lua Profiler.
2020-08-22 21:24:35 +02:00
Frank f30c66424c Radioqueue Profiler 2020-08-22 21:18:12 +02:00
Frank f823fc6ee0 Update AI_Formation.lua
Performance update
2020-08-22 16:31:56 +02:00
Frank aac291c0c6 Performance Optimizations 2020-08-22 00:09:36 +02:00
Frank 61adeeeda3 Delete Astar - Copy.lua 2020-08-20 01:24:28 +02:00
Frank f94a5eed61 Merge branch 'develop' into FF/OpsDev 2020-08-19 23:21:06 +02:00
Frank 0695c48e7a Merge branch 'master' into develop 2020-08-19 23:12:05 +02:00
Frank f4bfcf58fd Ops 2020-08-19 22:32:16 +02:00
Frank dee7307adc Ops 2020-08-19 01:06:28 +02:00
Frank 114032a743 Ops 2020-08-18 18:15:22 +02:00
Frank e9e6a63e6a Ops 2020-08-18 01:35:24 +02:00
Frank 2a4f6020c2 Ops 2020-08-17 01:24:51 +02:00
Frank 3ea8b3737f Update Profiler.lua 2020-08-16 01:18:18 +02:00
Frank ed47b4b3db Ops 2020-08-16 00:35:42 +02:00
Frank adc89feda9 Ops 2020-08-15 00:54:36 +02:00
Frank 32c9a59ff0 Ops 2020-08-14 18:09:13 +02:00
Frank 200c1dac85 Ops 2020-08-14 01:01:45 +02:00
Frank cf65c2af15 Ops 2020-08-13 01:21:02 +02:00
Frank fb6ebc42a5 Ops 2020-08-10 23:45:52 +02:00
Frank c7696c375e Ops 2020-08-10 01:46:03 +02:00
Frank 337e1a837f Ops 2020-08-08 01:10:03 +02:00
Frank 495a9fd3a0 Ops Target
New Class.
2020-08-06 01:43:42 +02:00
Frank e6f7493ddd Ops Fixes 2020-08-05 00:39:48 +02:00
Frank 76e75505e5 Ops 2020-08-04 16:56:45 +02:00
Frank dafbd3f368 Ops & Auftrag 2020-08-04 01:10:53 +02:00
Frank 11ec70441a Ops group 2020-08-03 00:31:10 +02:00
Frank d1a18913f3 Ops 2020-08-02 01:31:47 +02:00
Frank 775b9e9fde Fixed bugs with new option table. 2020-08-01 00:25:12 +02:00
Frank 286e34e057 Profiler 2020-07-31 17:32:24 +02:00
Frank da2aa00442 A*
Further improvements by switching to keys.
2020-07-31 00:09:21 +02:00
Frank ba90176bb1 A*
Further optimized by using DCS API land.isVisible instead of Moose IsLoS function.
2020-07-30 21:40:27 +02:00
Frank cf9248ecc8 A*
- Improved performance by caching cost and valid/invalid neighbours.
2020-07-30 17:41:26 +02:00
Frank 0d42b12658 Enhanced Groups 2020-07-30 01:08:25 +02:00
Frank 2f6d9b640f NAVY 2020-07-29 01:10:13 +02:00
Frank 04923b65b2 Stuff 2020-07-24 01:34:38 +02:00
Frank 2328f9a36b CHIEF 2020-07-23 19:15:26 +02:00
Frank 98971736f8 Astar 2020-07-23 00:24:59 +02:00
Frank ec809085b4 Waypoints 2020-07-22 01:05:24 +02:00
Frank af023c1994 Waypoints 2020-07-21 17:53:59 +02:00
Frank d9b7cc18f3 A* 2020-07-21 01:19:03 +02:00
Frank ce1121a4c2 INTEL
Clusters
2020-07-20 01:20:28 +02:00
Frank 5fa75bf6b9 INTEL
Improved clusters
2020-07-19 18:31:09 +02:00
Frank 5cb1036618 CHIEF
- Added Chief of Staff class.
2020-07-19 01:22:49 +02:00
Frank 9473dc2069 Update Intelligence.lua 2020-07-16 01:04:43 +02:00
Frank 81f5184b43 Added WINCOM;MANDER 2020-07-15 21:48:11 +02:00
Frank b6bc22f991 Squadron Grouping 2020-07-15 00:51:27 +02:00
Frank 56fad29df9 ops 2020-07-14 17:56:18 +02:00
Frank dfeea53cf6 Merge branch 'develop' into FF/Ops 2020-07-14 00:33:29 +02:00
Frank 71e6369960 INTEL class 2020-07-13 22:31:33 +02:00
Frank 0611db78b3 Intel 2020-07-13 18:31:01 +02:00
Frank 8c768cc517 Update Intelligence.lua 2020-07-12 22:20:20 +02:00
Frank b67750d808 Intel 2020-07-12 20:57:37 +02:00
Frank 96f2ad06e2 Update FlightGroup.lua
Fixed TACAN
2020-07-12 19:43:27 +02:00
Frank 5cf4833455 OpsGroup 2020-07-10 14:16:41 +02:00
Frank f578fcfdc7 NAVYGROUP
Improved dead/stop
2020-07-10 11:14:18 +02:00
Frank 9838e1af19 Ops 2020-07-09 00:06:02 +02:00
Frank cee443e28d Ops 2020-07-08 00:18:42 +02:00
Frank 1fe57cab67 bla 2020-07-08 00:12:57 +02:00
Frank 80b22a8444 Ops 2020-07-08 00:07:30 +02:00
Frank 71733babf8 NavyGroup 2020-07-07 22:28:54 +02:00
Frank 9f793d6cf7 OpsGroup 2020-07-07 00:47:42 +02:00
Frank 46e73a108f Ops 2020-07-04 23:16:57 +02:00
Frank b13ddc958b Update Warehouse.lua 2020-07-02 10:48:08 +02:00
Frank ba3954ad3f Update Airboss.lua 2020-07-01 23:56:05 +02:00
Frank f2e417b21f Ops 2020-07-01 23:52:27 +02:00
Frank d93d0afdf3 Ops 2020-06-30 00:33:26 +02:00
Frank 207c9ed62e blanks 2020-06-29 21:08:57 +02:00
Frank e3f4aa3d64 Update FlightGroup.lua 2020-06-29 21:05:26 +02:00
Frank 2392c9dc8e Ops 2020-06-29 20:55:32 +02:00
Frank 682c1f5ef2 Ops 2020-06-27 22:44:50 +02:00
176 changed files with 98167 additions and 10668 deletions
+7
View File
@@ -28,6 +28,13 @@ local.properties
.buildpath
#####################
## Visual Studio Code
#####################
*.code-workspace
.vscode/
#################
## Visual Studio
#################
+166
View File
@@ -0,0 +1,166 @@
# Repository: https://github.com/CppCXY/EmmyLuaCodeStyle
# English documentation: https://github.com/CppCXY/EmmyLuaCodeStyle/blob/master/README_EN.md
[*.lua]
# [basic]
# optional space/tab
indent_style = space
# if indent_style is space, this is valid
indent_size = 4
# if indent_style is tab, this is valid
tab_width = 4
# none/single/double
quote_style = none
# only support number
continuation_indent_size = 0
# optional crlf/lf/cr/auto, if it is 'auto', in windows it is crlf other platforms are lf
end_of_line = auto
detect_end_of_line = false
# this mean utf8 length , if this is 'unset' then the line width is no longer checked
# this option decides when to chopdown the code
max_line_length = 9999
# this will check text end with new line
insert_final_newline = true
# [function]
# function call expression's args will align to first arg
# optional true/false/only_after_more_indention_statement/only_not_exist_cross_row_expression
align_call_args = false
# if true, all function define params will align to first param
align_function_define_params = true
remove_expression_list_finish_comma = true
# keep/remove/remove_table_only/remove_string_only/unambiguous_remove_string_only
call_arg_parentheses = keep
# [table]
#optional none/comma/semicolon
table_separator_style = none
#optional keep/never/always/smart
trailing_table_separator = keep
# see document for detail
continuous_assign_table_field_align_to_equal_sign = true
# if true, format like this "local t = { 1, 2, 3 }"
keep_one_space_between_table_and_bracket = true
# if indent_style is tab, this option is invalid
align_table_field_to_first_field = true
# [statement]
align_chained_expression_statement = false
# continous line distance
max_continuous_line_distance = 1
# see document for detail
continuous_assign_statement_align_to_equal_sign = true
# if statement will align like switch case
if_condition_align_with_each_other = false
# if true, continuation_indent_size for local or assign statement is invalid
# however, if the expression list has cross row expression, it will not be aligned to the first expression
local_assign_continuation_align_to_first_expression = false
statement_inline_comment_space = 1
# [indentation]
# if true, the label loses its current indentation
label_no_indent = false
# if true, there will be no indentation in the do statement
do_statement_no_indent = false
# if true, the conditional expression of the if statement will not be a continuation line indent
if_condition_no_continuation_indent = false
if_branch_comments_after_block_no_indent = false
# [space]
# if true, t[#t+1] will not space wrapper '+'
table_append_expression_no_space = false
long_chain_expression_allow_one_space_after_colon = false
remove_empty_header_and_footer_lines_in_function = true
space_before_function_open_parenthesis = false
space_inside_function_call_parentheses = false
space_inside_function_param_list_parentheses = false
space_before_open_square_bracket = false
space_inside_square_brackets = false
# if true, ormat like this "local t <const> = 1"
keep_one_space_between_namedef_and_attribute = true
# [row_layout]
# The following configuration supports four expressions
# minLine:${n}
# keepLine
# keepLine:${n}
# maxLine:${n}
keep_line_after_if_statement = minLine:0
keep_line_after_do_statement = minLine:0
keep_line_after_while_statement = minLine:0
keep_line_after_repeat_statement = minLine:0
keep_line_after_for_statement = minLine:0
keep_line_after_local_or_assign_statement = keepLine
keep_line_after_function_define_statement = keepLine:1
keep_line_after_expression_statement = keepLine
# [diagnostic]
# the following is code diagnostic options
enable_check_codestyle = true
# [diagnostic.name_style]
enable_name_style_check = false
# the following is name style check rule
# base option off/camel_case/snake_case/upper_snake_case/pascal_case/same(filename/first_param/'<const string>', snake_case/pascal_case/camel_case)
# all option can use '|' represent or
# for example:
# snake_case | upper_snake_case
# same(first_param, snake_case)
# same('m')
local_name_define_style = snake_case
function_param_name_style = snake_case
function_name_define_style = snake_case
local_function_name_define_style = snake_case
table_field_name_define_style = snake_case
global_variable_name_define_style = snake_case|upper_snake_case
module_name_define_style = same('m')|same(filename, snake_case)
require_module_name_style = same(first_param, snake_case)
class_name_define_style = same(filename, snake_case)
-33
View File
@@ -1,33 +0,0 @@
# See https://github.com/Koihik/LuaFormatter
# Use '-- LuaFormatter off' and '-- LuaFormatter on' around code blocks to inhibit formatting
column_limit: 500
indent_width: 2
use_tab: false
continuation_indent_width: 2
keep_simple_control_block_one_line: false
keep_simple_function_one_line: false
align_args: true
break_after_functioncall_lp: false
break_before_functioncall_rp: false
align_parameter: true
chop_down_parameter: true
break_after_functiondef_lp: false
break_before_functiondef_rp: false
align_table_field: true
break_after_table_lb: true
break_before_table_rb: true
chop_down_table: true
chop_down_kv_table: true
column_table_limit: 500
table_sep: ','
extra_sep_at_table_end: true
break_after_operator: true
single_quote_to_double_quote: false
double_quote_to_single_quote: false
spaces_before_call: 1
spaces_inside_functiondef_parens: true
spaces_inside_functioncall_parens: true
spaces_inside_table_braces: true
spaces_around_equals_in_field: true
line_breaks_after_function_body: 1
+17
View File
@@ -0,0 +1,17 @@
{
"Lua.workspace.preloadFileSize": 1000,
"Lua.diagnostics.disable": [
"undefined-doc-name"
],
"Lua.diagnostics.globals": [
"BASE",
"lfs",
"__Moose",
"trigger",
"coord",
"missionCommands"
],
"Lua.completion.displayContext": 5,
"Lua.runtime.version": "Lua 5.1",
"Lua.completion.callSnippet": "Both"
}
+10 -9
View File
@@ -1,4 +1,6 @@
--- **AI** -- (R2.2) - Models the process of Combat Air Patrol (CAP) for airplanes.
--- **AI** - Models the process of Combat Air Patrol (CAP) for airplanes.
--
-- This is a class used in the @{AI.AI_A2A_Dispatcher}.
--
-- ===
--
@@ -13,8 +15,7 @@
-- @extends AI.AI_Air_Patrol#AI_AIR_PATROL
-- @extends AI.AI_Air_Engage#AI_AIR_ENGAGE
--- The AI_A2A_CAP class implements the core functions to patrol a @{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.
--
-- ![Process](..\Presentations\AI_CAP\Dia3.JPG)
@@ -81,15 +82,15 @@
-- that will define when the AI will engage with the detected airborne enemy targets.
-- The range can be beyond or smaller than the range of the Patrol Zone.
-- The range is applied at the position of the AI.
-- Use the method @{AI.AI_CAP#AI_A2A_CAP.SetEngageRange}() to define that range.
-- Use the method @{#AI_A2A_CAP.SetEngageRange}() to define that range.
--
-- ## 4. Set the Zone of Engagement
--
-- ![Zone](..\Presentations\AI_CAP\Dia12.JPG)
--
-- An optional @{Zone} can be set,
-- An optional @{Core.Zone} can be set,
-- that will define when the AI will engage with the detected airborne enemy targets.
-- Use the method @{AI.AI_Cap#AI_A2A_CAP.SetEngageZone}() to define that Zone.
-- Use the method @{#AI_A2A_CAP.SetEngageZone}() to define that Zone.
--
-- ===
--
@@ -106,7 +107,7 @@ AI_A2A_CAP = {
-- @param DCS#Altitude EngageFloorAltitude The lowest altitude in meters where to execute the engagement.
-- @param DCS#Altitude EngageCeilingAltitude The highest altitude in meters where to execute the engagement.
-- @param DCS#AltitudeType EngageAltType The altitude type ("RADIO"=="AGL", "BARO"=="ASL"). Defaults to "RADIO".
-- @param Core.Zone#ZONE_BASE PatrolZone The @{Zone} where the patrol needs to be executed.
-- @param Core.Zone#ZONE_BASE PatrolZone The @{Core.Zone} where the patrol needs to be executed.
-- @param DCS#Speed PatrolMinSpeed The minimum speed of the @{Wrapper.Group} in km/h.
-- @param DCS#Speed PatrolMaxSpeed The maximum speed of the @{Wrapper.Group} in km/h.
-- @param DCS#Altitude PatrolFloorAltitude The lowest altitude in meters where to execute the patrol.
@@ -132,7 +133,7 @@ end
--- Creates a new AI_A2A_CAP object
-- @param #AI_A2A_CAP self
-- @param Wrapper.Group#GROUP AICap
-- @param Core.Zone#ZONE_BASE PatrolZone The @{Zone} where the patrol needs to be executed.
-- @param Core.Zone#ZONE_BASE PatrolZone The @{Core.Zone} where the patrol needs to be executed.
-- @param DCS#Altitude PatrolFloorAltitude The lowest altitude in meters where to execute the patrol.
-- @param DCS#Altitude PatrolCeilingAltitude The highest altitude in meters where to execute the patrol.
-- @param DCS#Speed PatrolMinSpeed The minimum speed of the @{Wrapper.Group} in km/h.
@@ -191,7 +192,7 @@ end
--- Evaluate the attack and create an AttackUnitTask list.
-- @param #AI_A2A_CAP self
-- @param Core.Set#SET_UNIT AttackSetUnit The set of units to attack.
-- @param Wrappper.Group#GROUP DefenderGroup The group of defenders.
-- @param Wrapper.Group#GROUP DefenderGroup The group of defenders.
-- @param #number EngageAltitude The altitude to engage the targets.
-- @return #AI_A2A_CAP self
function AI_A2A_CAP:CreateAttackUnitTasks( AttackSetUnit, DefenderGroup, EngageAltitude )
@@ -1,4 +1,4 @@
--- **AI** - (R2.2) - Manages the process of an automatic A2A defense system based on an EWR network targets and coordinating CAP and GCI.
--- **AI** - Manages the process of an automatic A2A defense system based on an EWR network targets and coordinating CAP and GCI.
--
-- ===
--
@@ -57,8 +57,8 @@
--
-- ## 2. Which type of EWR will I setup? Grouping based per AREA, per TYPE or per UNIT? (Later others will follow).
--
-- The MOOSE framework leverages the @{Detection} classes to perform the EWR detection.
-- Several types of @{Detection} classes exist, and the most common characteristics of these classes is that they:
-- The MOOSE framework leverages the @{Functional.Detection} classes to perform the EWR detection.
-- Several types of @{Functional.Detection} classes exist, and the most common characteristics of these classes is that they:
--
-- * Perform detections from multiple FACs as one co-operating entity.
-- * Communicate with a Head Quarters, which consolidates each detection.
@@ -126,7 +126,7 @@
-- * polygon zones
-- * moving zones
--
-- Depending on the type of zone selected, a different @{Zone} object needs to be created from a ZONE_ class.
-- Depending on the type of zone selected, a different @{Core.Zone} object needs to be created from a ZONE_ class.
--
-- ## 14. For each Squadron doing CAP, what are the time intervals and CAP amounts to be performed?
--
@@ -356,7 +356,7 @@ do -- AI_A2A_DISPATCHER
--
-- ![Banner Image](..\Presentations\AI_A2A_DISPATCHER\Dia9.JPG)
--
-- If it's a cold war then the **borders of red and blue territory** need to be defined using a @{zone} object derived from @{Core.Zone#ZONE_BASE}.
-- If it's a cold war then the **borders of red and blue territory** need to be defined using a @{Core.Zone} object derived from @{Core.Zone#ZONE_BASE}.
-- If a hot war is chosen then **no borders** actually need to be defined using the helicopter units other than
-- it makes it easier sometimes for the mission maker to envisage where the red and blue territories roughly are.
-- In a hot war the borders are effectively defined by the ground based radar coverage of a coalition.
@@ -592,7 +592,7 @@ do -- AI_A2A_DISPATCHER
-- A2ADispatcher:SetSquadronCap( "Maykop", CAPZoneMiddle, 4000, 8000, 600, 800, 800, 1200, "RADIO" )
-- A2ADispatcher:SetSquadronCapInterval( "Sochi", 2, 30, 120, 1 )
--
-- Note the different @{Zone} MOOSE classes being used to create zones of different types. Please click the @{Zone} link for more information about the different zone types.
-- Note the different @{Core.Zone} MOOSE classes being used to create zones of different types. Please click the @{Core.Zone} link for more information about the different zone types.
-- Zones can be circles, can be setup in the mission editor using trigger zones, but can also be setup in the mission editor as polygons and in this case GROUP objects are being used!
--
-- ## 7.2. Set the squadron to execute CAP:
@@ -881,8 +881,9 @@ do -- AI_A2A_DISPATCHER
--- Enumerator for spawns at airbases
-- @type AI_A2A_DISPATCHER.Takeoff
-- @extends Wrapper.Group#GROUP.Takeoff
--- @field #AI_A2A_DISPATCHER.Takeoff Takeoff
---
-- @field #AI_A2A_DISPATCHER.Takeoff Takeoff
AI_A2A_DISPATCHER.Takeoff = GROUP.Takeoff
--- Defines Landing type/location.
@@ -928,6 +929,8 @@ do -- AI_A2A_DISPATCHER
self.DefenderTasks = {} -- The Defenders Tasks.
self.DefenderDefault = {} -- The Defender Default Settings over all Squadrons.
self.SetSendPlayerMessages = false --#boolean Flash messages to player
-- TODO: Check detection through radar.
self.Detection:FilterCategories( { Unit.Category.AIRPLANE, Unit.Category.HELICOPTER } )
-- self.Detection:InitDetectRadar( true )
@@ -1145,7 +1148,7 @@ do -- AI_A2A_DISPATCHER
self:I( "Captured " .. AirbaseName )
-- Now search for all squadrons located at the airbase, and sanatize them.
-- Now search for all squadrons located at the airbase, and sanitize them.
for SquadronName, Squadron in pairs( self.DefenderSquadrons ) do
if Squadron.AirbaseName == AirbaseName then
Squadron.ResourceCount = -999 -- The base has been captured, and the resources are eliminated. No more spawning.
@@ -1301,7 +1304,7 @@ do -- AI_A2A_DISPATCHER
--- Define a border area to simulate a **cold war** scenario.
-- A **cold war** is one where CAP aircraft patrol their territory but will not attack enemy aircraft or launch GCI aircraft unless enemy aircraft enter their territory. In other words the EWR may detect an enemy aircraft but will only send aircraft to attack it if it crosses the border.
-- A **hot war** is one where CAP aircraft will intercept any detected enemy aircraft and GCI aircraft will launch against detected enemy aircraft without regard for territory. In other words if the ground radar can detect the enemy aircraft then it will send CAP and GCI aircraft to attack it.
-- If it's a cold war then the **borders of red and blue territory** need to be defined using a @{zone} object derived from @{Core.Zone#ZONE_BASE}. This method needs to be used for this.
-- If it's a cold war then the **borders of red and blue territory** need to be defined using a @{Core.Zone} object derived from @{Core.Zone#ZONE_BASE}. This method needs to be used for this.
-- If a hot war is chosen then **no borders** actually need to be defined using the helicopter units other than it makes it easier sometimes for the mission maker to envisage where the red and blue territories roughly are. In a hot war the borders are effectively defined by the ground based radar coverage of a coalition. Set the noborders parameter to 1
-- @param #AI_A2A_DISPATCHER self
-- @param Core.Zone#ZONE_BASE BorderZone An object derived from ZONE_BASE, or a list of objects derived from ZONE_BASE.
@@ -1684,6 +1687,20 @@ do -- AI_A2A_DISPATCHER
return DefenderSquadron
end
--- Get a resource count from a specific squadron
-- @param #AI_A2A_DISPATCHER self
-- @param #string Squadron Name of the squadron.
-- @return #number Number of airframes available or nil if the squadron does not exist
function AI_A2A_DISPATCHER:QuerySquadron(Squadron)
local Squadron = self:GetSquadron(Squadron)
if Squadron.ResourceCount then
self:T2(string.format("%s = %s",Squadron.Name,Squadron.ResourceCount))
return Squadron.ResourceCount
end
self:F({Squadron = Squadron.Name,SquadronResourceCount = Squadron.ResourceCount})
return nil
end
--- [DEPRECATED - Might create problems launching planes] Set the Squadron visible before startup of the dispatcher.
-- All planes will be spawned as uncontrolled on the parking spot.
@@ -1710,7 +1727,7 @@ do -- AI_A2A_DISPATCHER
-- Get free parking for fighter aircraft.
local nfreeparking = DefenderSquadron.Airbase:GetFreeParkingSpotsNumber( AIRBASE.TerminalType.FighterAircraft, true )
-- Take number of free parking spots if no resource count was specifed.
-- Take number of free parking spots if no resource count was specified.
DefenderSquadron.ResourceCount = DefenderSquadron.ResourceCount or nfreeparking
-- Check that resource count is not larger than free parking spots.
@@ -1755,7 +1772,7 @@ do -- AI_A2A_DISPATCHER
-- @param DCS#Altitude EngageFloorAltitude The lowest altitude in meters where to execute the engagement.
-- @param DCS#Altitude EngageCeilingAltitude The highest altitude in meters where to execute the engagement.
-- @param #number EngageAltType The altitude type to engage, which is a string "BARO" defining Barometric or "RADIO" defining radio controlled altitude.
-- @param Core.Zone#ZONE_BASE Zone The @{Zone} object derived from @{Core.Zone#ZONE_BASE} that defines the zone wherein the CAP will be executed.
-- @param Core.Zone#ZONE_BASE Zone The @{Core.Zone} object derived from @{Core.Zone#ZONE_BASE} that defines the zone wherein the CAP will be executed.
-- @param #number PatrolMinSpeed The minimum speed at which the cap can be executed.
-- @param #number PatrolMaxSpeed The maximum speed at which the cap can be executed.
-- @param #number PatrolFloorAltitude The minimum altitude at which the cap can be executed.
@@ -1822,7 +1839,7 @@ do -- AI_A2A_DISPATCHER
--- Set a CAP for a Squadron.
-- @param #AI_A2A_DISPATCHER self
-- @param #string SquadronName The squadron name.
-- @param Core.Zone#ZONE_BASE Zone The @{Zone} object derived from @{Core.Zone#ZONE_BASE} that defines the zone wherein the CAP will be executed.
-- @param Core.Zone#ZONE_BASE Zone The @{Core.Zone} object derived from @{Core.Zone#ZONE_BASE} that defines the zone wherein the CAP will be executed.
-- @param #number PatrolFloorAltitude The minimum altitude at which the cap can be executed.
-- @param #number PatrolCeilingAltitude the maximum altitude at which the cap can be executed.
-- @param #number PatrolMinSpeed The minimum speed at which the cap can be executed.
@@ -2319,6 +2336,13 @@ do -- AI_A2A_DISPATCHER
return self
end
--- Set flashing player messages on or off
-- @param #AI_A2A_DISPATCHER self
-- @param #boolean onoff Set messages on (true) or off (false)
function AI_A2A_DISPATCHER:SetSendMessages( onoff )
self.SetSendPlayerMessages = onoff
end
--- Sets flights to take-off in the air, as part of the defense system.
-- @param #AI_A2A_DISPATCHER self
-- @param #string SquadronName The name of the squadron.
@@ -3188,7 +3212,9 @@ do -- AI_A2A_DISPATCHER
local Squadron = Dispatcher:GetSquadronFromDefender( DefenderGroup )
if Squadron then
Dispatcher:MessageToPlayers( Squadron, DefenderName .. " Wheels up.", DefenderGroup )
if self.SetSendPlayerMessages then
Dispatcher:MessageToPlayers( Squadron, DefenderName .. " Wheels up.", DefenderGroup )
end
AI_A2A_Fsm:__Patrol( 2 ) -- Start Patrolling
end
end
@@ -3200,10 +3226,10 @@ do -- AI_A2A_DISPATCHER
self:GetParent( self ).onafterPatrolRoute( self, DefenderGroup, From, Event, To )
local DefenderName = DefenderGroup:GetCallsign()
local Dispatcher = self:GetDispatcher() -- #AI_A2G_DISPATCHER
local Dispatcher = self:GetDispatcher() -- #AI_A2A_DISPATCHER
local Squadron = Dispatcher:GetSquadronFromDefender( DefenderGroup )
if Squadron then
Dispatcher:MessageToPlayers( Squadron, DefenderName .. ", patrolling.", DefenderGroup )
if Squadron and self.SetSendPlayerMessages then
Dispatcher:MessageToPlayers( Squadron, DefenderName .. ", patrolling.", DefenderGroup )
end
Dispatcher:ClearDefenderTaskTarget( DefenderGroup )
@@ -3219,8 +3245,8 @@ do -- AI_A2A_DISPATCHER
local DefenderName = DefenderGroup:GetCallsign()
local Dispatcher = self:GetDispatcher() -- #AI_A2A_DISPATCHER
local Squadron = Dispatcher:GetSquadronFromDefender( DefenderGroup )
if Squadron then
Dispatcher:MessageToPlayers( Squadron, DefenderName .. " returning to base.", DefenderGroup )
if Squadron and self.SetSendPlayerMessages then
Dispatcher:MessageToPlayers( Squadron, DefenderName .. " returning to base.", DefenderGroup )
end
Dispatcher:ClearDefenderTaskTarget( DefenderGroup )
end
@@ -3404,10 +3430,10 @@ do -- AI_A2A_DISPATCHER
local DefenderTarget = Dispatcher:GetDefenderTaskTarget( DefenderGroup )
if DefenderTarget then
if Squadron.Language == "EN" then
Dispatcher:MessageToPlayers( Squadron, DefenderName .. " wheels up.", DefenderGroup )
elseif Squadron.Language == "RU" then
Dispatcher:MessageToPlayers( Squadron, DefenderName .. " колеса вверх.", DefenderGroup )
if Squadron.Language == "EN" and self.SetSendPlayerMessages then
Dispatcher:MessageToPlayers( Squadron, DefenderName .. " wheels up.", DefenderGroup )
elseif Squadron.Language == "RU" and self.SetSendPlayerMessages then
Dispatcher:MessageToPlayers( Squadron, DefenderName .. " колёса вверх.", DefenderGroup )
end
-- Fsm:__Engage( 2, DefenderTarget.Set ) -- Engage on the TargetSetUnit
Fsm:EngageRoute( DefenderTarget.Set ) -- Engage on the TargetSetUnit
@@ -3425,12 +3451,12 @@ do -- AI_A2A_DISPATCHER
local FirstUnit = AttackSetUnit:GetFirst()
local Coordinate = FirstUnit:GetCoordinate() -- Core.Point#COORDINATE
if Squadron.Language == "EN" then
Dispatcher:MessageToPlayers( Squadron, DefenderName .. ", intercepting bogeys at " .. Coordinate:ToStringA2A( DefenderGroup, nil, Squadron.Language ), DefenderGroup )
elseif Squadron.Language == "RU" then
Dispatcher:MessageToPlayers( Squadron, DefenderName .. ", перехват самолетов в " .. Coordinate:ToStringA2A( DefenderGroup, nil, Squadron.Language ), DefenderGroup )
elseif Squadron.Language == "DE" then
Dispatcher:MessageToPlayers( Squadron, DefenderName .. ", Eindringlinge abfangen bei" .. Coordinate:ToStringA2A( DefenderGroup, nil, Squadron.Language ), DefenderGroup )
if Squadron.Language == "EN" and self.SetSendPlayerMessages then
Dispatcher:MessageToPlayers( Squadron, DefenderName .. ", intercepting bogeys at " .. Coordinate:ToStringA2A( DefenderGroup, nil, Squadron.Language ), DefenderGroup )
elseif Squadron.Language == "RU" and self.SetSendPlayerMessages then
Dispatcher:MessageToPlayers( Squadron, DefenderName .. ", перехватывая боги в " .. Coordinate:ToStringA2A( DefenderGroup, nil, Squadron.Language ), DefenderGroup )
elseif Squadron.Language == "DE" and self.SetSendPlayerMessages then
Dispatcher:MessageToPlayers( Squadron, DefenderName .. ", Eindringlinge abfangen bei" .. Coordinate:ToStringA2A( DefenderGroup, nil, Squadron.Language ), DefenderGroup )
end
end
self:GetParent( Fsm ).onafterEngageRoute( self, DefenderGroup, From, Event, To, AttackSetUnit )
@@ -3447,10 +3473,10 @@ do -- AI_A2A_DISPATCHER
local FirstUnit = AttackSetUnit:GetFirst()
local Coordinate = FirstUnit:GetCoordinate() -- Core.Point#COORDINATE
if Squadron.Language == "EN" then
Dispatcher:MessageToPlayers( Squadron, DefenderName .. ", engaging bogeys at " .. Coordinate:ToStringA2A( DefenderGroup, nil, Squadron.Language ), DefenderGroup )
elseif Squadron.Language == "RU" then
Dispatcher:MessageToPlayers( Squadron, DefenderName .. ", захватывающие самолеты в " .. Coordinate:ToStringA2A( DefenderGroup, nil, Squadron.Language ), DefenderGroup )
if Squadron.Language == "EN" and self.SetSendPlayerMessages then
Dispatcher:MessageToPlayers( Squadron, DefenderName .. ", engaging bogeys at " .. Coordinate:ToStringA2A( DefenderGroup, nil, Squadron.Language ), DefenderGroup )
elseif Squadron.Language == "RU" and self.SetSendPlayerMessages then
Dispatcher:MessageToPlayers( Squadron, DefenderName .. ", задействуя боги в " .. Coordinate:ToStringA2A( DefenderGroup, nil, Squadron.Language ), DefenderGroup )
end
end
self:GetParent( Fsm ).onafterEngage( self, DefenderGroup, From, Event, To, AttackSetUnit )
@@ -3465,10 +3491,10 @@ do -- AI_A2A_DISPATCHER
local Squadron = Dispatcher:GetSquadronFromDefender( DefenderGroup )
if Squadron then
if Squadron.Language == "EN" then
Dispatcher:MessageToPlayers( Squadron, DefenderName .. " returning to base.", DefenderGroup )
elseif Squadron.Language == "RU" then
Dispatcher:MessageToPlayers( Squadron, DefenderName .. ", возвращаясь на базу.", DefenderGroup )
if Squadron.Language == "EN" and self.SetSendPlayerMessages then
Dispatcher:MessageToPlayers( Squadron, DefenderName .. " returning to base.", DefenderGroup )
elseif Squadron.Language == "RU" and self.SetSendPlayerMessages then
Dispatcher:MessageToPlayers( Squadron, DefenderName .. ", возвращение на базу.", DefenderGroup )
end
end
Dispatcher:ClearDefenderTaskTarget( DefenderGroup )
@@ -3496,11 +3522,11 @@ do -- AI_A2A_DISPATCHER
local Dispatcher = self:GetDispatcher() -- #AI_A2A_DISPATCHER
local Squadron = Dispatcher:GetSquadronFromDefender( DefenderGroup )
if Squadron.Language == "EN" then
Dispatcher:MessageToPlayers( Squadron, DefenderName .. " landing at base.", DefenderGroup )
elseif Squadron.Language == "RU" then
Dispatcher:MessageToPlayers( Squadron, DefenderName .. ", захватывающие самолеты в посадка на базу.", DefenderGroup )
end
if Squadron.Language == "EN" and self.SetSendPlayerMessages then
Dispatcher:MessageToPlayers( Squadron, DefenderName .. " landing at base.", DefenderGroup )
elseif Squadron.Language == "RU" and self.SetSendPlayerMessages then
Dispatcher:MessageToPlayers( Squadron, DefenderName .. ", посадка на базу.", DefenderGroup )
end
if Action and Action == "Destroy" then
Dispatcher:RemoveDefenderFromSquadron( Squadron, DefenderGroup )
@@ -3890,7 +3916,7 @@ do
self:CAP( SquadronName )
end
--- Add resources to a Squadron
--- Add resources to a Squadron
-- @param #AI_A2A_DISPATCHER self
-- @param #string Squadron The squadron name.
-- @param #number Amount Number of resources to add.
@@ -3913,7 +3939,7 @@ do
end
self:T({Squadron = Squadron.Name,SquadronResourceCount = Squadron.ResourceCount})
end
end
do
@@ -3928,11 +3954,7 @@ do
--
-- # Demo Missions
--
-- ### [AI\_A2A\_GCICAP for Caucasus](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/release-2-2-pre/AID%20-%20AI%20Dispatching/AID-200%20-%20AI_A2A%20-%20GCICAP%20Demonstration)
-- ### [AI\_A2A\_GCICAP for NTTR](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/release-2-2-pre/AID%20-%20AI%20Dispatching/AID-210%20-%20NTTR%20AI_A2A_GCICAP%20Demonstration)
-- ### [AI\_A2A\_GCICAP for Normandy](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/release-2-2-pre/AID%20-%20AI%20Dispatching/AID-220%20-%20NORMANDY%20AI_A2A_GCICAP%20Demonstration)
--
-- ### [AI\_A2A\_GCICAP for beta testers](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/AID%20-%20AI%20Dispatching)
-- ### [Demo Missions](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/AID%20-%20AI%20Dispatching/AID-A2A%20-%20AI%20A2A%20Dispatching)
--
-- ===
--
@@ -4484,5 +4506,5 @@ do
return self
end
end
+6 -6
View File
@@ -1,6 +1,6 @@
--- **AI** -- (R2.2) - Models the process of Ground Controlled Interception (GCI) for airplanes.
--- **AI** - Models the process of Ground Controlled Interception (GCI) for airplanes.
--
-- This is a class used in the @{AI_A2A_Dispatcher}.
-- This is a class used in the @{AI.AI_A2A_Dispatcher}.
--
-- ===
--
@@ -8,7 +8,7 @@
--
-- ===
--
-- @module AI.AI_A2A_GCI
-- @module AI.AI_A2A_Gci
-- @image AI_Ground_Control_Intercept.JPG
@@ -89,9 +89,9 @@
--
-- ![Zone](..\Presentations\AI_GCI\Dia12.JPG)
--
-- An optional @{Zone} can be set,
-- An optional @{Core.Zone} can be set,
-- that will define when the AI will engage with the detected airborne enemy targets.
-- Use the method @{AI.AI_Cap#AI_A2A_GCI.SetEngageZone}() to define that Zone.
-- Use the method @{AI.AI_CAP#AI_CAP_ZONE.SetEngageZone}() to define that Zone.
--
-- ===
--
@@ -153,7 +153,7 @@ end
--- Evaluate the attack and create an AttackUnitTask list.
-- @param #AI_A2A_GCI self
-- @param Core.Set#SET_UNIT AttackSetUnit The set of units to attack.
-- @param Wrappper.Group#GROUP DefenderGroup The group of defenders.
-- @param Wrapper.Group#GROUP DefenderGroup The group of defenders.
-- @param #number EngageAltitude The altitude to engage the targets.
-- @return #AI_A2A_GCI self
function AI_A2A_GCI:CreateAttackUnitTasks( AttackSetUnit, DefenderGroup, EngageAltitude )
+7 -7
View File
@@ -1,4 +1,4 @@
--- **AI** -- (R2.2) - Models the process of air patrol of airplanes.
--- **AI** - Models the process of air patrol of airplanes.
--
-- ===
--
@@ -13,7 +13,7 @@
--- @type AI_A2A_PATROL
-- @extends AI.AI_A2A#AI_A2A
--- Implements the core functions to patrol a @{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}.
--
-- ![Process](..\Presentations\AI_PATROL\Dia3.JPG)
--
@@ -102,7 +102,7 @@
-- When the AI is out of fuel, it is required that a new AI is started, before the old AI can return to the home base.
-- Therefore, with a parameter and a calculation of the distance to the home base, the fuel threshold is calculated.
-- When the fuel threshold is reached, the AI will continue for a given time its patrol task in orbit,
-- while a new AI is targetted to the AI_A2A_PATROL.
-- while a new AI is targeted to the AI_A2A_PATROL.
-- Once the time is finished, the old AI will return to the base.
-- Use the method @{#AI_A2A_PATROL.ManageFuel}() to have this proces in place.
--
@@ -122,7 +122,7 @@ AI_A2A_PATROL = {
--- Creates a new AI_A2A_PATROL object
-- @param #AI_A2A_PATROL self
-- @param Wrapper.Group#GROUP AIPatrol The patrol group object.
-- @param Core.Zone#ZONE_BASE PatrolZone The @{Zone} where the patrol needs to be executed.
-- @param Core.Zone#ZONE_BASE PatrolZone The @{Core.Zone} where the patrol needs to be executed.
-- @param DCS#Altitude PatrolFloorAltitude The lowest altitude in meters where to execute the patrol.
-- @param DCS#Altitude PatrolCeilingAltitude The highest altitude in meters where to execute the patrol.
-- @param DCS#Speed PatrolMinSpeed The minimum speed of the @{Wrapper.Group} in km/h.
@@ -264,7 +264,7 @@ function AI_A2A_PATROL:SetAltitude( PatrolFloorAltitude, PatrolCeilingAltitude )
end
--- Defines a new patrol route using the @{Process_PatrolZone} parameters and settings.
--- Defines a new patrol route using the @{AI.AI_Patrol#AI_PATROL_ZONE} parameters and settings.
-- @param #AI_A2A_PATROL self
-- @return #AI_A2A_PATROL self
-- @param Wrapper.Group#GROUP AIPatrol The Group Object managed by the FSM.
@@ -287,7 +287,7 @@ function AI_A2A_PATROL:onafterPatrol( AIPatrol, From, Event, To )
end
--- This statis method is called from the route path within the last task at the last waaypoint of the AIPatrol.
--- This static method is called from the route path within the last task at the last waypoint of the AIPatrol.
-- Note that this method is required, as triggers the next route when patrolling for the AIPatrol.
-- @param Wrapper.Group#GROUP AIPatrol The AI group.
-- @param #AI_A2A_PATROL Fsm The FSM.
@@ -302,7 +302,7 @@ function AI_A2A_PATROL.PatrolRoute( AIPatrol, Fsm )
end
--- Defines a new patrol route using the @{Process_PatrolZone} parameters and settings.
--- Defines a new patrol route using the @{AI.AI_Patrol#AI_PATROL_ZONE} parameters and settings.
-- @param #AI_A2A_PATROL self
-- @param Wrapper.Group#GROUP AIPatrol The Group managed by the FSM.
-- @param #string From The From State string.
+7 -15
View File
@@ -1,6 +1,6 @@
--- **AI** -- Models the process of air to ground BAI engagement for airplanes and helicopters.
--- **AI** - Models the process of air to ground BAI engagement for airplanes and helicopters.
--
-- This is a class used in the @{AI_A2G_Dispatcher}.
-- This is a class used in the @{AI.AI_A2G_Dispatcher}.
--
-- ===
--
@@ -11,11 +11,8 @@
-- @module AI.AI_A2G_BAI
-- @image AI_Air_To_Ground_Engage.JPG
--- @type AI_A2G_BAI
-- @extends AI.AI_A2A_Engage#AI_A2A_Engage
-- @extends AI.AI_A2A_Engage#AI_A2A_Engage -- TODO: Documentation. This class does not exist, unable to determine what it extends.
--- Implements the core functions to intercept intruders. Use the Engage trigger to intercept intruders.
--
@@ -26,8 +23,6 @@ AI_A2G_BAI = {
ClassName = "AI_A2G_BAI",
}
--- Creates a new AI_A2G_BAI object
-- @param #AI_A2G_BAI self
-- @param Wrapper.Group#GROUP AIGroup
@@ -36,7 +31,7 @@ AI_A2G_BAI = {
-- @param DCS#Altitude EngageFloorAltitude The lowest altitude in meters where to execute the engagement.
-- @param DCS#Altitude EngageCeilingAltitude The highest altitude in meters where to execute the engagement.
-- @param DCS#AltitudeType EngageAltType The altitude type ("RADIO"=="AGL", "BARO"=="ASL"). Defaults to "RADIO".
-- @param Core.Zone#ZONE_BASE PatrolZone The @{Zone} where the patrol needs to be executed.
-- @param Core.Zone#ZONE_BASE PatrolZone The @{Core.Zone} where the patrol needs to be executed.
-- @param DCS#Altitude PatrolFloorAltitude The lowest altitude in meters where to execute the patrol.
-- @param DCS#Altitude PatrolCeilingAltitude The highest altitude in meters where to execute the patrol.
-- @param DCS#Speed PatrolMinSpeed The minimum speed of the @{Wrapper.Group} in km/h.
@@ -53,7 +48,6 @@ function AI_A2G_BAI:New2( AIGroup, EngageMinSpeed, EngageMaxSpeed, EngageFloorAl
return self
end
--- Creates a new AI_A2G_BAI object
-- @param #AI_A2G_BAI self
-- @param Wrapper.Group#GROUP AIGroup
@@ -61,7 +55,7 @@ end
-- @param DCS#Speed EngageMaxSpeed The maximum speed of the @{Wrapper.Group} in km/h when engaging a target.
-- @param DCS#Altitude EngageFloorAltitude The lowest altitude in meters where to execute the engagement.
-- @param DCS#Altitude EngageCeilingAltitude The highest altitude in meters where to execute the engagement.
-- @param Core.Zone#ZONE_BASE PatrolZone The @{Zone} where the patrol needs to be executed.
-- @param Core.Zone#ZONE_BASE PatrolZone The @{Core.Zone} where the patrol needs to be executed.
-- @param DCS#Altitude PatrolFloorAltitude The lowest altitude in meters where to execute the patrol.
-- @param DCS#Altitude PatrolCeilingAltitude The highest altitude in meters where to execute the patrol.
-- @param DCS#Speed PatrolMinSpeed The minimum speed of the @{Wrapper.Group} in km/h.
@@ -76,7 +70,7 @@ end
--- Evaluate the attack and create an AttackUnitTask list.
-- @param #AI_A2G_BAI self
-- @param Core.Set#SET_UNIT AttackSetUnit The set of units to attack.
-- @param Wrappper.Group#GROUP DefenderGroup The group of defenders.
-- @param Wrapper.Group#GROUP DefenderGroup The group of defenders.
-- @param #number EngageAltitude The altitude to engage the targets.
-- @return #AI_A2G_BAI self
function AI_A2G_BAI:CreateAttackUnitTasks( AttackSetUnit, DefenderGroup, EngageAltitude )
@@ -92,8 +86,6 @@ function AI_A2G_BAI:CreateAttackUnitTasks( AttackSetUnit, DefenderGroup, EngageA
end
end
end
return AttackUnitTasks
end
+7 -16
View File
@@ -1,6 +1,6 @@
--- **AI** -- Models the process of air to ground engagement for airplanes and helicopters.
--- **AI** - Models the process of air to ground engagement for airplanes and helicopters.
--
-- This is a class used in the @{AI_A2G_Dispatcher}.
-- This is a class used in the @{AI.AI_A2G_Dispatcher}.
--
-- ===
--
@@ -11,11 +11,8 @@
-- @module AI.AI_A2G_CAS
-- @image AI_Air_To_Ground_Engage.JPG
--- @type AI_A2G_CAS
-- @extends AI.AI_A2G_Patrol#AI_AIR_PATROL
-- @extends AI.AI_A2G_Patrol#AI_AIR_PATROL TODO: Documentation. This class does not exist, unable to determine what it extends.
--- Implements the core functions to intercept intruders. Use the Engage trigger to intercept intruders.
--
@@ -26,8 +23,6 @@ AI_A2G_CAS = {
ClassName = "AI_A2G_CAS",
}
--- Creates a new AI_A2G_CAS object
-- @param #AI_A2G_CAS self
-- @param Wrapper.Group#GROUP AIGroup
@@ -36,7 +31,7 @@ AI_A2G_CAS = {
-- @param DCS#Altitude EngageFloorAltitude The lowest altitude in meters where to execute the engagement.
-- @param DCS#Altitude EngageCeilingAltitude The highest altitude in meters where to execute the engagement.
-- @param DCS#AltitudeType EngageAltType The altitude type ("RADIO"=="AGL", "BARO"=="ASL"). Defaults to "RADIO".
-- @param Core.Zone#ZONE_BASE PatrolZone The @{Zone} where the patrol needs to be executed.
-- @param Core.Zone#ZONE_BASE PatrolZone The @{Core.Zone} where the patrol needs to be executed.
-- @param DCS#Altitude PatrolFloorAltitude The lowest altitude in meters where to execute the patrol.
-- @param DCS#Altitude PatrolCeilingAltitude The highest altitude in meters where to execute the patrol.
-- @param DCS#Speed PatrolMinSpeed The minimum speed of the @{Wrapper.Group} in km/h.
@@ -53,7 +48,6 @@ function AI_A2G_CAS:New2( AIGroup, EngageMinSpeed, EngageMaxSpeed, EngageFloorAl
return self
end
--- Creates a new AI_A2G_CAS object
-- @param #AI_A2G_CAS self
-- @param Wrapper.Group#GROUP AIGroup
@@ -61,7 +55,7 @@ end
-- @param DCS#Speed EngageMaxSpeed The maximum speed of the @{Wrapper.Group} in km/h when engaging a target.
-- @param DCS#Altitude EngageFloorAltitude The lowest altitude in meters where to execute the engagement.
-- @param DCS#Altitude EngageCeilingAltitude The highest altitude in meters where to execute the engagement.
-- @param Core.Zone#ZONE_BASE PatrolZone The @{Zone} where the patrol needs to be executed.
-- @param Core.Zone#ZONE_BASE PatrolZone The @{Core.Zone} where the patrol needs to be executed.
-- @param DCS#Altitude PatrolFloorAltitude The lowest altitude in meters where to execute the patrol.
-- @param DCS#Altitude PatrolCeilingAltitude The highest altitude in meters where to execute the patrol.
-- @param DCS#Speed PatrolMinSpeed The minimum speed of the @{Wrapper.Group} in km/h.
@@ -76,7 +70,7 @@ end
--- Evaluate the attack and create an AttackUnitTask list.
-- @param #AI_A2G_CAS self
-- @param Core.Set#SET_UNIT AttackSetUnit The set of units to attack.
-- @param Wrappper.Group#GROUP DefenderGroup The group of defenders.
-- @param Wrapper.Group#GROUP DefenderGroup The group of defenders.
-- @param #number EngageAltitude The altitude to engage the targets.
-- @return #AI_A2G_CAS self
function AI_A2G_CAS:CreateAttackUnitTasks( AttackSetUnit, DefenderGroup, EngageAltitude )
@@ -92,9 +86,6 @@ function AI_A2G_CAS:CreateAttackUnitTasks( AttackSetUnit, DefenderGroup, EngageA
end
end
end
return AttackUnitTasks
end
@@ -1,4 +1,4 @@
--- **AI** - Create an automated A2G defense system based on a detection network of reconnaissance vehicles and air units, coordinating SEAD, BAI and CAS operations.
--- **AI** - Create an automated A2G defense system with reconnaissance units, coordinating SEAD, BAI and CAS operations.
--
-- ===
--
@@ -175,7 +175,7 @@
-- * polygon zones
-- * moving zones
--
-- Depending on the type of zone selected, a different @{Zone} object needs to be created from a ZONE_ class.
-- Depending on the type of zone selected, a different @{Core.Zone} object needs to be created from a ZONE_ class.
--
--
-- ## 12. Are moving defense coordinates possible?
@@ -951,7 +951,7 @@ do -- AI_A2G_DISPATCHER
AI_A2G_DISPATCHER.DefenseQueue = {}
--- Defense approach types.
-- @type #AI_A2G_DISPATCHER.DefenseApproach
-- @type AI_A2G_DISPATCHER.DefenseApproach
AI_A2G_DISPATCHER.DefenseApproach = {
Random = 1,
Distance = 2,
@@ -999,7 +999,9 @@ do -- AI_A2G_DISPATCHER
-- self.Detection:InitDetectRadar( false )
-- self.Detection:InitDetectVisual( true )
-- self.Detection:SetRefreshTimeInterval( 30 )
self.SetSendPlayerMessages = false --flash messages to players
self:SetDefenseRadius()
self:SetDefenseLimit( nil )
self:SetDefenseApproach( AI_A2G_DISPATCHER.DefenseApproach.Random )
@@ -1387,7 +1389,7 @@ do -- AI_A2G_DISPATCHER
--- Define a border area to simulate a **cold war** scenario.
-- A **cold war** is one where Patrol aircraft patrol their territory but will not attack enemy aircraft or launch GCI aircraft unless enemy aircraft enter their territory. In other words the EWR may detect an enemy aircraft but will only send aircraft to attack it if it crosses the border.
-- A **hot war** is one where Patrol aircraft will intercept any detected enemy aircraft and GCI aircraft will launch against detected enemy aircraft without regard for territory. In other words if the ground radar can detect the enemy aircraft then it will send Patrol and GCI aircraft to attack it.
-- If it's a cold war then the **borders of red and blue territory** need to be defined using a @{zone} object derived from @{Core.Zone#ZONE_BASE}. This method needs to be used for this.
-- If it's a cold war then the **borders of red and blue territory** need to be defined using a @{Core.Zone} object derived from @{Core.Zone#ZONE_BASE}. This method needs to be used for this.
-- If a hot war is chosen then **no borders** actually need to be defined using the helicopter units other than it makes it easier sometimes for the mission maker to envisage where the red and blue territories roughly are. In a hot war the borders are effectively defined by the ground based radar coverage of a coalition. Set the noborders parameter to 1
-- @param #AI_A2G_DISPATCHER self
-- @param Core.Zone#ZONE_BASE BorderZone An object derived from ZONE_BASE, or a list of objects derived from ZONE_BASE.
@@ -1804,6 +1806,19 @@ do -- AI_A2G_DISPATCHER
return DefenderSquadron
end
--- Get a resource count from a specific squadron
-- @param #AI_A2G_DISPATCHER self
-- @param #string Squadron Name of the squadron.
-- @return #number Number of airframes available or nil if the squadron does not exist
function AI_A2G_DISPATCHER:QuerySquadron(Squadron)
local Squadron = self:GetSquadron(Squadron)
if Squadron.ResourceCount then
self:T2(string.format("%s = %s",Squadron.Name,Squadron.ResourceCount))
return Squadron.ResourceCount
end
self:F({Squadron = Squadron.Name,SquadronResourceCount = Squadron.ResourceCount})
return nil
end
--- Set the Squadron visible before startup of the dispatcher.
-- All planes will be spawned as uncontrolled on the parking spot.
@@ -1837,7 +1852,7 @@ do -- AI_A2G_DISPATCHER
--- Check if the Squadron is visible before startup of the dispatcher.
-- @param #AI_A2G_DISPATCHER self
-- @param #string SquadronName The squadron name.
-- @return #bool true if visible.
-- @return #boolean true if visible.
-- @usage
--
-- -- Set the Squadron visible before startup of dispatcher.
@@ -2183,7 +2198,7 @@ do -- AI_A2G_DISPATCHER
-- The Sead patrol will start a patrol of the aircraft at a specified zone, and will engage when commanded.
-- @param #AI_A2G_DISPATCHER self
-- @param #string SquadronName The squadron name.
-- @param Core.Zone#ZONE_BASE Zone The @{Zone} object derived from @{Core.Zone#ZONE_BASE} that defines the zone wherein the Patrol will be executed.
-- @param Core.Zone#ZONE_BASE Zone The @{Core.Zone} object derived from @{Core.Zone#ZONE_BASE} that defines the zone wherein the Patrol will be executed.
-- @param #number PatrolMinSpeed (optional, default = 50% of max speed) The minimum speed at which the cap can be executed.
-- @param #number PatrolMaxSpeed (optional, default = 75% of max speed) The maximum speed at which the cap can be executed.
-- @param #number PatrolFloorAltitude (optional, default = 1000m ) The minimum altitude at which the cap can be executed.
@@ -2232,7 +2247,7 @@ do -- AI_A2G_DISPATCHER
-- The Sead patrol will start a patrol of the aircraft at a specified zone, and will engage when commanded.
-- @param #AI_A2G_DISPATCHER self
-- @param #string SquadronName The squadron name.
-- @param Core.Zone#ZONE_BASE Zone The @{Zone} object derived from @{Core.Zone#ZONE_BASE} that defines the zone wherein the Patrol will be executed.
-- @param Core.Zone#ZONE_BASE Zone The @{Core.Zone} object derived from @{Core.Zone#ZONE_BASE} that defines the zone wherein the Patrol will be executed.
-- @param #number FloorAltitude (optional, default = 1000m ) The minimum altitude at which the cap can be executed.
-- @param #number CeilingAltitude (optional, default = 1500m ) The maximum altitude at which the cap can be executed.
-- @param #number PatrolMinSpeed (optional, default = 50% of max speed) The minimum speed at which the cap can be executed.
@@ -2334,7 +2349,7 @@ do -- AI_A2G_DISPATCHER
-- The Cas patrol will start a patrol of the aircraft at a specified zone, and will engage when commanded.
-- @param #AI_A2G_DISPATCHER self
-- @param #string SquadronName The squadron name.
-- @param Core.Zone#ZONE_BASE Zone The @{Zone} object derived from @{Core.Zone#ZONE_BASE} that defines the zone wherein the Patrol will be executed.
-- @param Core.Zone#ZONE_BASE Zone The @{Core.Zone} object derived from @{Core.Zone#ZONE_BASE} that defines the zone wherein the Patrol will be executed.
-- @param #number PatrolMinSpeed (optional, default = 50% of max speed) The minimum speed at which the cap can be executed.
-- @param #number PatrolMaxSpeed (optional, default = 75% of max speed) The maximum speed at which the cap can be executed.
-- @param #number PatrolFloorAltitude (optional, default = 1000m ) The minimum altitude at which the cap can be executed.
@@ -2383,7 +2398,7 @@ do -- AI_A2G_DISPATCHER
-- The Cas patrol will start a patrol of the aircraft at a specified zone, and will engage when commanded.
-- @param #AI_A2G_DISPATCHER self
-- @param #string SquadronName The squadron name.
-- @param Core.Zone#ZONE_BASE Zone The @{Zone} object derived from @{Core.Zone#ZONE_BASE} that defines the zone wherein the Patrol will be executed.
-- @param Core.Zone#ZONE_BASE Zone The @{Core.Zone} object derived from @{Core.Zone#ZONE_BASE} that defines the zone wherein the Patrol will be executed.
-- @param #number FloorAltitude (optional, default = 1000m ) The minimum altitude at which the cap can be executed.
-- @param #number CeilingAltitude (optional, default = 1500m ) The maximum altitude at which the cap can be executed.
-- @param #number PatrolMinSpeed (optional, default = 50% of max speed) The minimum speed at which the cap can be executed.
@@ -2485,7 +2500,7 @@ do -- AI_A2G_DISPATCHER
-- The Bai patrol will start a patrol of the aircraft at a specified zone, and will engage when commanded.
-- @param #AI_A2G_DISPATCHER self
-- @param #string SquadronName The squadron name.
-- @param Core.Zone#ZONE_BASE Zone The @{Zone} object derived from @{Core.Zone#ZONE_BASE} that defines the zone wherein the Patrol will be executed.
-- @param Core.Zone#ZONE_BASE Zone The @{Core.Zone} object derived from @{Core.Zone#ZONE_BASE} that defines the zone wherein the Patrol will be executed.
-- @param #number PatrolMinSpeed (optional, default = 50% of max speed) The minimum speed at which the cap can be executed.
-- @param #number PatrolMaxSpeed (optional, default = 75% of max speed) The maximum speed at which the cap can be executed.
-- @param #number PatrolFloorAltitude (optional, default = 1000m ) The minimum altitude at which the cap can be executed.
@@ -2534,7 +2549,7 @@ do -- AI_A2G_DISPATCHER
-- The Bai patrol will start a patrol of the aircraft at a specified zone, and will engage when commanded.
-- @param #AI_A2G_DISPATCHER self
-- @param #string SquadronName The squadron name.
-- @param Core.Zone#ZONE_BASE Zone The @{Zone} object derived from @{Core.Zone#ZONE_BASE} that defines the zone wherein the Patrol will be executed.
-- @param Core.Zone#ZONE_BASE Zone The @{Core.Zone} object derived from @{Core.Zone#ZONE_BASE} that defines the zone wherein the Patrol will be executed.
-- @param #number FloorAltitude (optional, default = 1000m ) The minimum altitude at which the cap can be executed.
-- @param #number CeilingAltitude (optional, default = 1500m ) The maximum altitude at which the cap can be executed.
-- @param #number PatrolMinSpeed (optional, default = 50% of max speed) The minimum speed at which the cap can be executed.
@@ -3718,7 +3733,9 @@ do -- AI_A2G_DISPATCHER
local Squadron = Dispatcher:GetSquadronFromDefender( DefenderGroup )
if Squadron then
Dispatcher:MessageToPlayers( Squadron, DefenderName .. ", wheels up.", DefenderGroup )
if self.SetSendPlayerMessages then
Dispatcher:MessageToPlayers( Squadron, DefenderName .. ", wheels up.", DefenderGroup )
end
AI_A2G_Fsm:Patrol() -- Engage on the TargetSetUnit
end
end
@@ -3730,7 +3747,7 @@ do -- AI_A2G_DISPATCHER
local DefenderName = DefenderGroup:GetCallsign()
local Dispatcher = self:GetDispatcher() -- #AI_A2G_DISPATCHER
local Squadron = Dispatcher:GetSquadronFromDefender( DefenderGroup )
if Squadron then
if Squadron and self.SetSendPlayerMessages then
Dispatcher:MessageToPlayers( Squadron, DefenderName .. ", patrolling.", DefenderGroup )
end
@@ -3749,8 +3766,9 @@ do -- AI_A2G_DISPATCHER
if Squadron and AttackSetUnit:Count() > 0 then
local FirstUnit = AttackSetUnit:GetFirst()
local Coordinate = FirstUnit:GetCoordinate() -- Core.Point#COORDINATE
Dispatcher:MessageToPlayers( Squadron, DefenderName .. ", moving on to ground target at " .. Coordinate:ToStringA2G( DefenderGroup ), DefenderGroup )
if self.SetSendPlayerMessages then
Dispatcher:MessageToPlayers( Squadron, DefenderName .. ", moving on to ground target at " .. Coordinate:ToStringA2G( DefenderGroup ), DefenderGroup )
end
end
end
@@ -3764,8 +3782,9 @@ do -- AI_A2G_DISPATCHER
local FirstUnit = AttackSetUnit:GetFirst()
if FirstUnit then
local Coordinate = FirstUnit:GetCoordinate()
Dispatcher:MessageToPlayers( Squadron, DefenderName .. ", engaging ground target at " .. Coordinate:ToStringA2G( DefenderGroup ), DefenderGroup )
if self.SetSendPlayerMessages then
Dispatcher:MessageToPlayers( Squadron, DefenderName .. ", engaging ground target at " .. Coordinate:ToStringA2G( DefenderGroup ), DefenderGroup )
end
end
end
@@ -3776,8 +3795,9 @@ do -- AI_A2G_DISPATCHER
local DefenderName = DefenderGroup:GetCallsign()
local Dispatcher = self:GetDispatcher() -- #AI_A2G_DISPATCHER
local Squadron = Dispatcher:GetSquadronFromDefender( DefenderGroup )
Dispatcher:MessageToPlayers( Squadron, DefenderName .. ", returning to base.", DefenderGroup )
if self.SetSendPlayerMessages then
Dispatcher:MessageToPlayers( Squadron, DefenderName .. ", returning to base.", DefenderGroup )
end
Dispatcher:ClearDefenderTaskTarget( DefenderGroup )
end
@@ -3789,7 +3809,9 @@ do -- AI_A2G_DISPATCHER
local DefenderName = DefenderGroup:GetCallsign()
local Dispatcher = AI_A2G_Fsm:GetDispatcher() -- #AI_A2G_DISPATCHER
local Squadron = Dispatcher:GetSquadronFromDefender( DefenderGroup )
Dispatcher:MessageToPlayers( Squadron, DefenderName .. ", lost control." )
if self.SetSendPlayerMessages then
Dispatcher:MessageToPlayers( Squadron, DefenderName .. ", lost control." )
end
if DefenderGroup:IsAboveRunway() then
Dispatcher:RemoveDefenderFromSquadron( Squadron, DefenderGroup )
DefenderGroup:Destroy()
@@ -3804,8 +3826,9 @@ do -- AI_A2G_DISPATCHER
local DefenderName = DefenderGroup:GetCallsign()
local Dispatcher = self:GetDispatcher() -- #AI_A2G_DISPATCHER
local Squadron = Dispatcher:GetSquadronFromDefender( DefenderGroup )
Dispatcher:MessageToPlayers( Squadron, DefenderName .. ", landing at base.", DefenderGroup )
if self.SetSendPlayerMessages then
Dispatcher:MessageToPlayers( Squadron, DefenderName .. ", landing at base.", DefenderGroup )
end
if Action and Action == "Destroy" then
Dispatcher:RemoveDefenderFromSquadron( Squadron, DefenderGroup )
DefenderGroup:Destroy()
@@ -3861,7 +3884,9 @@ do -- AI_A2G_DISPATCHER
self:F( { DefenderTarget = DefenderTarget } )
if DefenderTarget then
Dispatcher:MessageToPlayers( Squadron, DefenderName .. ", wheels up.", DefenderGroup )
if self.SetSendPlayerMessages then
Dispatcher:MessageToPlayers( Squadron, DefenderName .. ", wheels up.", DefenderGroup )
end
AI_A2G_Fsm:EngageRoute( DefenderTarget.Set ) -- Engage on the TargetSetUnit
end
end
@@ -3876,8 +3901,9 @@ do -- AI_A2G_DISPATCHER
if Squadron then
local FirstUnit = AttackSetUnit:GetFirst()
local Coordinate = FirstUnit:GetCoordinate() -- Core.Point#COORDINATE
Dispatcher:MessageToPlayers( Squadron, DefenderName .. ", on route to ground target at " .. Coordinate:ToStringA2G( DefenderGroup ), DefenderGroup )
if self.SetSendPlayerMessages then
Dispatcher:MessageToPlayers( Squadron, DefenderName .. ", on route to ground target at " .. Coordinate:ToStringA2G( DefenderGroup ), DefenderGroup )
end
end
self:GetParent(self).onafterEngageRoute( self, DefenderGroup, From, Event, To, AttackSetUnit )
end
@@ -3892,8 +3918,9 @@ do -- AI_A2G_DISPATCHER
local FirstUnit = AttackSetUnit:GetFirst()
if FirstUnit then
local Coordinate = FirstUnit:GetCoordinate()
Dispatcher:MessageToPlayers( Squadron, DefenderName .. ", engaging ground target at " .. Coordinate:ToStringA2G( DefenderGroup ), DefenderGroup )
if self.SetSendPlayerMessages then
Dispatcher:MessageToPlayers( Squadron, DefenderName .. ", engaging ground target at " .. Coordinate:ToStringA2G( DefenderGroup ), DefenderGroup )
end
end
end
@@ -3903,8 +3930,9 @@ do -- AI_A2G_DISPATCHER
local DefenderName = DefenderGroup:GetCallsign()
local Dispatcher = self:GetDispatcher() -- #AI_A2G_DISPATCHER
local Squadron = Dispatcher:GetSquadronFromDefender( DefenderGroup )
Dispatcher:MessageToPlayers( Squadron, DefenderName .. ", returning to base.", DefenderGroup )
if self.SetSendPlayerMessages then
Dispatcher:MessageToPlayers( Squadron, DefenderName .. ", returning to base.", DefenderGroup )
end
self:GetParent(self).onafterRTB( self, DefenderGroup, From, Event, To )
Dispatcher:ClearDefenderTaskTarget( DefenderGroup )
@@ -3918,8 +3946,9 @@ do -- AI_A2G_DISPATCHER
local DefenderName = DefenderGroup:GetCallsign()
local Dispatcher = AI_A2G_Fsm:GetDispatcher() -- #AI_A2G_DISPATCHER
local Squadron = Dispatcher:GetSquadronFromDefender( DefenderGroup )
--Dispatcher:MessageToPlayers( Squadron, "Squadron " .. Squadron.Name .. ", " .. DefenderName .. " lost control." )
if self.SetSendPlayerMessages then
Dispatcher:MessageToPlayers( Squadron, "Squadron " .. Squadron.Name .. ", " .. DefenderName .. " lost control." )
end
if DefenderGroup:IsAboveRunway() then
Dispatcher:RemoveDefenderFromSquadron( Squadron, DefenderGroup )
DefenderGroup:Destroy()
@@ -3934,8 +3963,9 @@ do -- AI_A2G_DISPATCHER
local DefenderName = DefenderGroup:GetCallsign()
local Dispatcher = self:GetDispatcher() -- #AI_A2G_DISPATCHER
local Squadron = Dispatcher:GetSquadronFromDefender( DefenderGroup )
Dispatcher:MessageToPlayers( Squadron, DefenderName .. ", landing at base.", DefenderGroup )
if self.SetSendPlayerMessages then
Dispatcher:MessageToPlayers( Squadron, DefenderName .. ", landing at base.", DefenderGroup )
end
if Action and Action == "Destroy" then
Dispatcher:RemoveDefenderFromSquadron( Squadron, DefenderGroup )
DefenderGroup:Destroy()
@@ -3975,7 +4005,7 @@ do -- AI_A2G_DISPATCHER
local EvaluateDistance = AttackCoordinate:Get2DDistance( DefenseCoordinate )
-- Now check if this coordinate is not in a danger zone, meaning, that the attack line is not crossing other coordinates.
-- (y1 y2)x + (x2 x1)y + (x1y2 x2y1) = 0
-- (y1 - y2)x + (x2 - x1)y + (x1y2 - x2y1) = 0
local c1 = DefenseCoordinate
local c2 = AttackCoordinate
@@ -4036,7 +4066,7 @@ do -- AI_A2G_DISPATCHER
for DefenderID, DefenderGroup in pairs( DefenderFriendlies or {} ) do
-- Here we check if the defenders have a defense line to the attackers.
-- If the attackers are behind enemy lines or too close to an other defense line; then don´t engage.
-- If the attackers are behind enemy lines or too close to an other defense line; then don't engage.
local DefenseCoordinate = DefenderGroup:GetCoordinate()
local HasDefenseLine = self:HasDefenseLine( DefenseCoordinate, DetectedItem )
@@ -4341,7 +4371,7 @@ do -- AI_A2G_DISPATCHER
-- Show tactical situation
local ThreatLevel = DetectedItem.Set:CalculateThreatLevelA2G()
Report:Add( string.format( " - %1s%s ( %04s ): ( #%02d - %-4s ) %s" , ( DetectedItem.IsDetected == true ) and "!" or " ", DetectedItem.ItemID, DetectedItem.Index, DetectedItem.Set:Count(), DetectedItem.Type or " --- ", string.rep( "", ThreatLevel ) ) )
Report:Add( string.format( " - %1s%s ( %04s ): ( #%02d - %-4s ) %s" , ( DetectedItem.IsDetected == true ) and "!" or " ", DetectedItem.ItemID, DetectedItem.Index, DetectedItem.Set:Count(), DetectedItem.Type or " --- ", string.rep( "", ThreatLevel ) ) )
for Defender, DefenderTask in pairs( self:GetDefenderTasks() ) do
local Defender = Defender -- Wrapper.Group#GROUP
if DefenderTask.Target and DefenderTask.Target.Index == DetectedItem.Index then
@@ -4559,7 +4589,7 @@ do -- AI_A2G_DISPATCHER
if self.TacticalDisplay then
-- Show tactical situation
local ThreatLevel = DetectedItem.Set:CalculateThreatLevelA2G()
Report:Add( string.format( " - %1s%s ( %4s ): ( #%d - %4s ) %s" , ( DetectedItem.IsDetected == true ) and "!" or " ", DetectedItem.ItemID, DetectedItem.Index, DetectedItem.Set:Count(), DetectedItem.Type or " --- ", string.rep( "", ThreatLevel ) ) )
Report:Add( string.format( " - %1s%s ( %4s ): ( #%d - %4s ) %s" , ( DetectedItem.IsDetected == true ) and "!" or " ", DetectedItem.ItemID, DetectedItem.Index, DetectedItem.Set:Count(), DetectedItem.Type or " --- ", string.rep( "", ThreatLevel ) ) )
for Defender, DefenderTask in pairs( self:GetDefenderTasks() ) do
local Defender = Defender -- Wrapper.Group#GROUP
if DefenderTask.Target and DefenderTask.Target.Index == DetectedItem.Index then
@@ -4729,7 +4759,15 @@ do
self:Patrol( SquadronName, PatrolTaskType )
end
--- Add resources to a Squadron
--- Set flashing player messages on or off
-- @param #AI_A2G_DISPATCHER self
-- @param #boolean onoff Set messages on (true) or off (false)
function AI_A2G_DISPATCHER:SetSendMessages( onoff )
self.SetSendPlayerMessages = onoff
end
end
--- Add resources to a Squadron
-- @param #AI_A2G_DISPATCHER self
-- @param #string Squadron The squadron name.
-- @param #number Amount Number of resources to add.
@@ -4751,7 +4789,4 @@ do
Squadron.ResourceCount = Squadron.ResourceCount - Amount
end
self:T({Squadron = Squadron.Name,SquadronResourceCount = Squadron.ResourceCount})
end
end
end
+7 -9
View File
@@ -1,6 +1,6 @@
--- **AI** -- Models the process of air to ground SEAD engagement for airplanes and helicopters.
--- **AI** - Models the process of air to ground SEAD engagement for airplanes and helicopters.
--
-- This is a class used in the @{AI_A2G_Dispatcher}.
-- This is a class used in the @{AI.AI_A2G_Dispatcher}.
--
-- ===
--
@@ -65,9 +65,9 @@
--
-- ![Zone](..\Presentations\AI_GCI\Dia12.JPG)
--
-- An optional @{Zone} can be set,
-- An optional @{Core.Zone} can be set,
-- that will define when the AI will engage with the detected airborne enemy targets.
-- Use the method @{AI.AI_Cap#AI_A2G_SEAD.SetEngageZone}() to define that Zone.
-- Use the method @{AI.AI_CAP#AI_CAP_ZONE.SetEngageZone}() to define that Zone. -- TODO: Documentation. Check that this is actually correct. The originally referenced class does not exist.
--
-- ===
--
@@ -76,8 +76,6 @@ AI_A2G_SEAD = {
ClassName = "AI_A2G_SEAD",
}
--- Creates a new AI_A2G_SEAD object
-- @param #AI_A2G_SEAD self
-- @param Wrapper.Group#GROUP AIGroup
@@ -86,7 +84,7 @@ AI_A2G_SEAD = {
-- @param DCS#Altitude EngageFloorAltitude The lowest altitude in meters where to execute the engagement.
-- @param DCS#Altitude EngageCeilingAltitude The highest altitude in meters where to execute the engagement.
-- @param DCS#AltitudeType EngageAltType The altitude type ("RADIO"=="AGL", "BARO"=="ASL"). Defaults to "RADIO".
-- @param Core.Zone#ZONE_BASE PatrolZone The @{Zone} where the patrol needs to be executed.
-- @param Core.Zone#ZONE_BASE PatrolZone The @{Core.Zone} where the patrol needs to be executed.
-- @param DCS#Altitude PatrolFloorAltitude The lowest altitude in meters where to execute the patrol.
-- @param DCS#Altitude PatrolCeilingAltitude The highest altitude in meters where to execute the patrol.
-- @param DCS#Speed PatrolMinSpeed The minimum speed of the @{Wrapper.Group} in km/h.
@@ -111,7 +109,7 @@ end
-- @param DCS#Speed EngageMaxSpeed The maximum speed of the @{Wrapper.Group} in km/h when engaging a target.
-- @param DCS#Altitude EngageFloorAltitude The lowest altitude in meters where to execute the engagement.
-- @param DCS#Altitude EngageCeilingAltitude The highest altitude in meters where to execute the engagement.
-- @param Core.Zone#ZONE_BASE PatrolZone The @{Zone} where the patrol needs to be executed.
-- @param Core.Zone#ZONE_BASE PatrolZone The @{Core.Zone} where the patrol needs to be executed.
-- @param DCS#Altitude PatrolFloorAltitude The lowest altitude in meters where to execute the patrol.
-- @param DCS#Altitude PatrolCeilingAltitude The highest altitude in meters where to execute the patrol.
-- @param DCS#Speed PatrolMinSpeed The minimum speed of the @{Wrapper.Group} in km/h.
@@ -127,7 +125,7 @@ end
--- Evaluate the attack and create an AttackUnitTask list.
-- @param #AI_A2G_SEAD self
-- @param Core.Set#SET_UNIT AttackSetUnit The set of units to attack.
-- @param Wrappper.Group#GROUP DefenderGroup The group of defenders.
-- @param Wrapper.Group#GROUP DefenderGroup The group of defenders.
-- @param #number EngageAltitude The altitude to engage the targets.
-- @return #AI_A2G_SEAD self
function AI_A2G_SEAD:CreateAttackUnitTasks( AttackSetUnit, DefenderGroup, EngageAltitude )
+32 -33
View File
@@ -374,7 +374,7 @@ end
--- When the AI is out of fuel, it is required that a new AI is started, before the old AI can return to the home base.
-- Therefore, with a parameter and a calculation of the distance to the home base, the fuel threshold is calculated.
-- When the fuel threshold is reached, the AI will continue for a given time its patrol task in orbit, while a new AIControllable is targetted to the AI_AIR.
-- When the fuel threshold is reached, the AI will continue for a given time its patrol task in orbit, while a new AIControllable is targeted to the AI_AIR.
-- Once the time is finished, the old AI will return to the base.
-- @param #AI_AIR self
-- @param #number FuelThresholdPercentage The threshold in percentage (between 0 and 1) when the AIControllable is considered to get out of fuel.
@@ -409,7 +409,7 @@ end
--- Defines a new patrol route using the @{Process_PatrolZone} parameters and settings.
--- Defines a new patrol route using the @{AI.AI_Patrol#AI_PATROL_ZONE} parameters and settings.
-- @param #AI_AIR self
-- @return #AI_AIR self
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
@@ -473,27 +473,27 @@ function AI_AIR:onafterStatus()
-- self:Home( "Destroy" )
-- end
-- end
if not self:Is( "Fuel" ) and not self:Is( "Home" ) and not self:is( "Refuelling" )then
local Fuel = self.Controllable:GetFuelMin()
-- If the fuel in the controllable is below the threshold percentage,
-- then send for refuel in case of a tanker, otherwise RTB.
if Fuel < self.FuelThresholdPercentage then
if self.TankerName then
self:I( self.Controllable:GetName() .. " is out of fuel: " .. Fuel .. " ... Refuelling at Tanker!" )
self:Refuel()
else
self:I( self.Controllable:GetName() .. " is out of fuel: " .. Fuel .. " ... RTB!" )
local OldAIControllable = self.Controllable
local OrbitTask = OldAIControllable:TaskOrbitCircle( math.random( self.PatrolFloorAltitude, self.PatrolCeilingAltitude ), self.PatrolMinSpeed )
local TimedOrbitTask = OldAIControllable:TaskControlled( OrbitTask, OldAIControllable:TaskCondition(nil,nil,nil,nil,self.OutOfFuelOrbitTime,nil ) )
OldAIControllable:SetTask( TimedOrbitTask, 10 )
self:Fuel()
RTB = true
end
@@ -504,11 +504,11 @@ function AI_AIR:onafterStatus()
if self:Is( "Fuel" ) and not self:Is( "Home" ) and not self:is( "Refuelling" ) then
RTB = true
end
-- TODO: Check GROUP damage function.
local Damage = self.Controllable:GetLife()
local InitialLife = self.Controllable:GetLife0()
-- If the group is damaged, then RTB.
-- Note that a group can consist of more units, so if one unit is damaged of a group, the mission may continue.
-- The damaged unit will RTB due to DCS logic, and the others will continue to engage.
@@ -518,7 +518,7 @@ function AI_AIR:onafterStatus()
RTB = true
self:SetStatusOff()
end
-- Check if planes went RTB and are out of control.
-- We only check if planes are out of control, when they are in duty.
if self.Controllable:HasTask() == false then
@@ -532,7 +532,7 @@ function AI_AIR:onafterStatus()
self:Damaged()
else
self:I( self.Controllable:GetName() .. " control lost! " )
self:LostControl()
end
else
@@ -550,7 +550,7 @@ function AI_AIR:onafterStatus()
if not self:Is("Home") then
self:__Status( 10 )
end
end
end
@@ -559,11 +559,11 @@ end
function AI_AIR.RTBRoute( AIGroup, Fsm )
AIGroup:F( { "AI_AIR.RTBRoute:", AIGroup:GetName() } )
if AIGroup:IsAlive() then
Fsm:RTB()
end
end
--- @param Wrapper.Group#GROUP AIGroup
@@ -576,7 +576,7 @@ function AI_AIR.RTBHold( AIGroup, Fsm )
local Task = AIGroup:TaskOrbitCircle( 4000, 400 )
AIGroup:SetTask( Task )
end
end
--- Set the min and max factors on RTB speed. Use this, if your planes are heading back to base too fast. Default values are 0.5 and 0.6.
@@ -598,54 +598,53 @@ end
function AI_AIR:onafterRTB( AIGroup, From, Event, To )
self:F( { AIGroup, From, Event, To } )
if AIGroup and AIGroup:IsAlive() then
if AIGroup and AIGroup:IsAlive() then
self:T( "Group " .. AIGroup:GetName() .. " ... RTB! ( " .. self:GetState() .. " )" )
self:ClearTargetDistance()
--AIGroup:ClearTasks()
AIGroup:OptionProhibitAfterburner(true)
local EngageRoute = {}
--- Calculate the target route point.
local FromCoord = AIGroup:GetCoordinate()
local ToTargetCoord = self.HomeAirbase:GetCoordinate() -- coordinate is on land height(!)
local ToTargetVec3 = ToTargetCoord:GetVec3()
ToTargetVec3.y = ToTargetCoord:GetLandHeight()+3000 -- let's set this 1000m/3000 feet above ground
local ToTargetCoord2 = COORDINATE:NewFromVec3( ToTargetVec3 )
if not self.RTBMinSpeed or not self.RTBMaxSpeed then
local RTBSpeedMax = AIGroup:GetSpeedMax()
local RTBSpeedMaxFactor = self.RTBSpeedMaxFactor or 0.6
local RTBSpeedMinFactor = self.RTBSpeedMinFactor or 0.5
self:SetRTBSpeed( RTBSpeedMax * RTBSpeedMinFactor, RTBSpeedMax * RTBSpeedMaxFactor)
end
local RTBSpeed = math.random( self.RTBMinSpeed, self.RTBMaxSpeed )
--local ToAirbaseAngle = FromCoord:GetAngleDegrees( FromCoord:GetDirectionVec3( ToTargetCoord2 ) )
local Distance = FromCoord:Get2DDistance( ToTargetCoord2 )
--local ToAirbaseCoord = FromCoord:Translate( 5000, ToAirbaseAngle )
local ToAirbaseCoord = ToTargetCoord2
if Distance < 5000 then
self:I( "RTB and near the airbase!" )
self:Home()
return
end
if not AIGroup:InAir() == true then
self:I( "Not anymore in the air, considered Home." )
self:Home()
return
end
--- Create a route point of type air.
local FromRTBRoutePoint = FromCoord:WaypointAir(
self.PatrolAltType,
@@ -666,10 +665,10 @@ function AI_AIR:onafterRTB( AIGroup, From, Event, To )
EngageRoute[#EngageRoute+1] = FromRTBRoutePoint
EngageRoute[#EngageRoute+1] = ToRTBRoutePoint
local Tasks = {}
Tasks[#Tasks+1] = AIGroup:TaskFunction( "AI_AIR.RTBRoute", self )
EngageRoute[#EngageRoute].task = AIGroup:TaskCombo( Tasks )
AIGroup:OptionROEHoldFire()
@@ -677,9 +676,9 @@ function AI_AIR:onafterRTB( AIGroup, From, Event, To )
--- NOW ROUTE THE GROUP!
AIGroup:Route( EngageRoute, self.TaskDelay )
end
end
--- @param #AI_AIR self
@@ -1,4 +1,4 @@
--- **AI** - Create an automated AIR defense system based on a detection network of reconnaissance vehicles and air units, coordinating SEAD, BAI and CAP operations.
--- **AI** - Create an automated AIR defense system with reconnaissance units, coordinating SEAD, BAI and CAP operations.
--
-- ===
--
@@ -7,7 +7,7 @@
-- * Setup quickly an AIR defense system for a coalition.
-- * Setup multiple defense zones to defend specific coordinates in your battlefield.
-- * Setup (SEAD) Suppression of Air Defense squadrons, to gain control in the air of enemy grounds.
-- * Setup (CAS) Controlled Air Support squadrons, to attack closeby enemy ground units near friendly installations.
-- * Setup (CAS) Controlled Air Support squadrons, to attack close by enemy ground units near friendly installations.
-- * Setup (BAI) Battleground Air Interdiction squadrons to attack remote enemy ground units and targets.
-- * Define and use a detection network controlled by recce.
-- * Define AIR defense squadrons at airbases, FARPs and carriers.
@@ -24,7 +24,7 @@
--
-- ## Missions:
--
-- [AID-AIR - AI AIR Dispatching](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/AID%20-%20AI%20Dispatching/AID-AIR%20-%20AI%20AIR%20Dispatching)
-- [AID-AIR - AI AIR Dispatching](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/AID%20-%20AI%20Dispatching)
--
-- ===
--
@@ -88,7 +88,7 @@
--
-- ## 4. How do the defenses decide **when and where to engage** on approaching enemy units?
--
-- The AIR dispacher needs you to setup (various) defense coordinates, which are strategic positions in the battle field to be defended.
-- The AIR dispatcher needs you to setup (various) defense coordinates, which are strategic positions in the battle field to be defended.
-- Any ground based enemy approaching within the proximity of such a defense point, may trigger for a defensive action by friendly air units.
--
-- There are 2 important parameters that play a role in the defensive decision making: defensiveness and reactivity.
@@ -108,7 +108,7 @@
-- ## 5. Are defense coordinates and defense reactivity the only parameters?
--
-- No, depending on the target type, and the threat level of the target, the probability of defense will be higher.
-- In other words, when a SAM-10 radar emitter is detected, its probabilty for defense will be much higher than when a BMP-1 vehicle is
-- In other words, when a SAM-10 radar emitter is detected, its probability for defense will be much higher than when a BMP-1 vehicle is
-- detected, even when both enemies are at the same distance from a defense coordinate.
-- This will ensure optimal defenses, SEAD tasks will be launched much more quicker against engaging radar emitters, to ensure air superiority.
-- Approaching main battle tanks will be engaged much faster, than a group of approaching trucks.
@@ -117,12 +117,12 @@
-- ## 6. Which Squadrons will I create and which name will I give each Squadron?
--
-- The AIR defense system works with **Squadrons**. Each Squadron must be given a unique name, that forms the **key** to the squadron.
-- Several options and activities can be set per Squadron. A free format name can be given, but always ensure that the name is meaningfull
-- Several options and activities can be set per Squadron. A free format name can be given, but always ensure that the name is meaningful
-- for your mission, and remember that squadron names are used for communication to the players of your mission.
--
-- There are mainly 3 types of defenses: **SEAD**, **CAS** and **BAI**.
--
-- Suppression of Air Defenses (SEAD) are effective agains radar emitters. Close Air Support (CAS) is launched when the enemy is close near friendly units.
-- Suppression of Air Defenses (SEAD) are effective against radar emitters. Close Air Support (CAS) is launched when the enemy is close near friendly units.
-- Battleground Air Interdiction (BAI) tasks are launched when there are no friendlies around.
--
-- Depending on the defense type, different payloads will be needed. See further points on squadron definition.
@@ -174,13 +174,13 @@
-- * polygon zones
-- * moving zones
--
-- Depending on the type of zone selected, a different @{Zone} object needs to be created from a ZONE_ class.
-- Depending on the type of zone selected, a different @{Core.Zone} object needs to be created from a ZONE_ class.
--
--
-- ## 12. Are moving defense coordinates possible?
--
-- Yes, different COORDINATE types are possible to be used.
-- The COORDINATE_UNIT will help you to specify a defense coodinate that is attached to a moving unit.
-- The COORDINATE_UNIT will help you to specify a defense coordinate that is attached to a moving unit.
--
--
-- ## 13. How much defense coordinates do I need to create?
@@ -214,7 +214,7 @@
-- * From a parking spot with running engines
-- * From a parking spot with cold engines
--
-- **The default takeoff method is staight in the air.**
-- **The default takeoff method is straight in the air.**
-- This takeoff method is the most useful if you want to avoid airplane clutter at airbases!
-- But it is the least realistic one!
--
@@ -236,10 +236,10 @@
--
-- For each Squadron, depending on the helicopter or airplane type (modern, old) and payload, which overhead is required to provide any defense?
--
-- In other words, if **X** enemy ground units are detected, how many **Y** defense helicpters or airplanes need to engage (per squadron)?
-- In other words, if **X** enemy ground units are detected, how many **Y** defense helicopters or airplanes need to engage (per squadron)?
-- The **Y** is dependent on the type of airplane (era), payload, fuel levels, skills etc.
-- But the most important factor is the payload, which is the amount of AIR weapons the defense can carry to attack the enemy ground units.
-- For example, a Ka-50 can carry 16 vikrs, that means, that it potentially can destroy at least 8 ground units without a reload of ammunication.
-- For example, a Ka-50 can carry 16 vikrs, that means, that it potentially can destroy at least 8 ground units without a reload of ammunition.
-- That means, that one defender can destroy more enemy ground units.
-- Thus, the overhead is a **factor** that will calculate dynamically how many **Y** defenses will be required based on **X** attackers detected.
--
@@ -259,7 +259,7 @@
--
-- ### Author: **FlightControl** rework of GCICAP + introduction of new concepts (squadrons).
--
-- @module AI.AI_AIR_Dispatcher
-- @module AI.AI_Air_Dispatcher
-- @image AI_Air_To_Ground_Dispatching.JPG
@@ -279,7 +279,7 @@ do -- AI_AIR_DISPATCHER
-- Multiple defense coordinates can be setup. Defense coordinates can be strategic or tactical positions or references to strategic units or scenery.
-- The AIR dispatcher will evaluate every x seconds the tactical situation around each defense coordinate. When a defense coordinate
-- is under threat, it will communicate through the command center that defensive actions need to be taken and will launch groups of air units for defense.
-- The level of threat to the defense coordinate varyies upon the strength and types of the enemy units, the distance to the defense point, and the defensiveness parameters.
-- The level of threat to the defense coordinate varies upon the strength and types of the enemy units, the distance to the defense point, and the defensiveness parameters.
-- Defensive actions are taken through probability, but the closer and the more threat the enemy poses to the defense coordinate, the faster it will be attacked by friendly AIR units.
--
-- Please study carefully the underlying explanations how to setup and use this module, as it has many features.
@@ -328,7 +328,7 @@ do -- AI_AIR_DISPATCHER
-- By spawning in dynamically additional recce, you can ensure that there is sufficient reconnaissance coverage so the defense mechanism is continuously
-- alerted of new enemy ground targets.
--
-- The following example defens a new reconnaissance network using a @{Functional.Detection#DETECTION_AREAS} object.
-- The following example defense a new reconnaissance network using a @{Functional.Detection#DETECTION_AREAS} object.
--
-- -- Define a SET_GROUP object that builds a collection of groups that define the recce network.
-- -- Here we build the network with all the groups that have a name starting with CCCP Recce.
@@ -473,7 +473,7 @@ do -- AI_AIR_DISPATCHER
-- the mission designer can choose to increase or reduce the amount of planes spawned.
--
-- The method @{#AI_AIR_DISPATCHER.SetSquadron}() defines for you a new squadron.
-- The provided parameters are the squadron name, airbase name and a list of template prefixe, and a number that indicates the amount of resources.
-- The provided parameters are the squadron name, airbase name and a list of template prefixes, and a number that indicates the amount of resources.
--
-- For example, this defines 3 new squadrons:
--
@@ -619,7 +619,7 @@ do -- AI_AIR_DISPATCHER
-- Depending on the demand of requested takeoffs by the AIR dispatcher, an airfield can become overloaded. Too many aircraft need to be taken
-- off at the same time, which will result in clutter as described above. In order to better control this behaviour, a takeoff scheduler is implemented,
-- which can be used to control how many aircraft are ordered for takeoff between specific time intervals.
-- The takeff intervals can be specified per squadron, which make sense, as each squadron have a "home" airfield.
-- The takeoff intervals can be specified per squadron, which make sense, as each squadron have a "home" airfield.
--
-- For this purpose, the method @{#AI_AIR_DISPATCHER.SetSquadronTakeOffInterval}() can be used to specify the takeoff intervals of
-- aircraft groups per squadron to avoid cluttering of aircraft at airbases.
@@ -947,7 +947,7 @@ do -- AI_AIR_DISPATCHER
AI_AIR_DISPATCHER.DefenseQueue = {}
--- Defense approach types
-- @type #AI_AIR_DISPATCHER.DefenseApproach
-- @type AI_AIR_DISPATCHER.DefenseApproach
AI_AIR_DISPATCHER.DefenseApproach = {
Random = 1,
Distance = 2,
@@ -1021,7 +1021,7 @@ do -- AI_AIR_DISPATCHER
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
-- @param Tasking.Task_AIR#AI_AIR Task
-- @param AI.AI_Air#AI_AIR Task
-- @param Wrapper.Unit#UNIT TaskUnit
-- @param #string PlayerName
@@ -1224,7 +1224,7 @@ do -- AI_AIR_DISPATCHER
self:I( "Captured " .. AirbaseName )
-- Now search for all squadrons located at the airbase, and sanatize them.
-- Now search for all squadrons located at the airbase, and sanitize them.
for SquadronName, Squadron in pairs( self.DefenderSquadrons ) do
if Squadron.AirbaseName == AirbaseName then
Squadron.ResourceCount = -999 -- The base has been captured, and the resources are eliminated. No more spawning.
@@ -1376,7 +1376,7 @@ do -- AI_AIR_DISPATCHER
--- Define a border area to simulate a **cold war** scenario.
-- A **cold war** is one where Patrol aircraft patrol their territory but will not attack enemy aircraft or launch GCI aircraft unless enemy aircraft enter their territory. In other words the EWR may detect an enemy aircraft but will only send aircraft to attack it if it crosses the border.
-- A **hot war** is one where Patrol aircraft will intercept any detected enemy aircraft and GCI aircraft will launch against detected enemy aircraft without regard for territory. In other words if the ground radar can detect the enemy aircraft then it will send Patrol and GCI aircraft to attack it.
-- If it's a cold war then the **borders of red and blue territory** need to be defined using a @{zone} object derived from @{Core.Zone#ZONE_BASE}. This method needs to be used for this.
-- If it's a cold war then the **borders of red and blue territory** need to be defined using a @{Core.Zone} object derived from @{Core.Zone#ZONE_BASE}. This method needs to be used for this.
-- If a hot war is chosen then **no borders** actually need to be defined using the helicopter units other than it makes it easier sometimes for the mission maker to envisage where the red and blue territories roughly are. In a hot war the borders are effectively defined by the ground based radar coverage of a coalition. Set the noborders parameter to 1
-- @param #AI_AIR_DISPATCHER self
-- @param Core.Zone#ZONE_BASE BorderZone An object derived from ZONE_BASE, or a list of objects derived from ZONE_BASE.
@@ -1796,12 +1796,12 @@ do -- AI_AIR_DISPATCHER
--
-- @return #AI_AIR_DISPATCHER
function AI_AIR_DISPATCHER:SetSquadron2( Squadron )
local SquadronName = Squadron:GetName() -- Retrieves the Squadron Name.
self.DefenderSquadrons[SquadronName] = self.DefenderSquadrons[SquadronName] or {}
self.DefenderSquadrons[SquadronName] = self.DefenderSquadrons[SquadronName] or {}
local DefenderSquadron = self.DefenderSquadrons[SquadronName]
return self
end
@@ -1812,15 +1812,15 @@ do -- AI_AIR_DISPATCHER
function AI_AIR_DISPATCHER:GetSquadron( SquadronName )
local DefenderSquadron = self.DefenderSquadrons[SquadronName]
if not DefenderSquadron then
error( "Unknown Squadron for Dispatcher:" .. SquadronName )
end
return DefenderSquadron
end
--- Set the Squadron visible before startup of the dispatcher.
-- All planes will be spawned as uncontrolled on the parking spot.
-- They will lock the parking spot.
@@ -1852,7 +1852,7 @@ do -- AI_AIR_DISPATCHER
--- Check if the Squadron is visible before startup of the dispatcher.
-- @param #AI_AIR_DISPATCHER self
-- @param #string SquadronName The squadron name.
-- @return #bool true if visible.
-- @return #boolean true if visible.
-- @usage
--
-- -- Set the Squadron visible before startup of dispatcher.
+4 -4
View File
@@ -1,6 +1,6 @@
--- **AI** -- Models the process of air to ground engagement for airplanes and helicopters.
--- **AI** - Models the process of air to ground engagement for airplanes and helicopters.
--
-- This is a class used in the @{AI_A2G_Dispatcher}.
-- This is a class used in the @{AI.AI_A2G_Dispatcher}.
--
-- ===
--
@@ -65,9 +65,9 @@
--
-- ![Zone](..\Presentations\AI_GCI\Dia12.JPG)
--
-- An optional @{Zone} can be set,
-- An optional @{Core.Zone} can be set,
-- that will define when the AI will engage with the detected airborne enemy targets.
-- Use the method @{AI.AI_Cap#AI_AIR_ENGAGE.SetEngageZone}() to define that Zone.
-- Use the method @{AI.AI_CAP#AI_AIR_ENGAGE.SetEngageZone}() to define that Zone.
--
-- ===
--
+53 -57
View File
@@ -1,4 +1,4 @@
--- **AI** -- Models the process of A2G patrolling and engaging ground targets for airplanes and helicopters.
--- **AI** - Models the process of A2G patrolling and engaging ground targets for airplanes and helicopters.
--
-- ===
--
@@ -12,8 +12,7 @@
--- @type AI_AIR_PATROL
-- @extends AI.AI_Air#AI_AIR
--- The AI_AIR_PATROL class implements the core functions to patrol a @{Zone} by an AI @{Wrapper.Group} or @{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.
--
-- ![Process](..\Presentations\AI_CAP\Dia3.JPG)
@@ -86,9 +85,9 @@
--
-- ![Zone](..\Presentations\AI_CAP\Dia12.JPG)
--
-- An optional @{Zone} can be set,
-- An optional @{Core.Zone} can be set,
-- that will define when the AI will engage with the detected airborne enemy targets.
-- Use the method @{AI.AI_Cap#AI_AIR_PATROL.SetEngageZone}() to define that Zone.
-- Use the method @{AI.AI_CAP#AI_AIR_PATROL.SetEngageZone}() to define that Zone.
--
-- ===
--
@@ -101,7 +100,7 @@ AI_AIR_PATROL = {
-- @param #AI_AIR_PATROL self
-- @param AI.AI_Air#AI_AIR AI_Air The AI_AIR FSM.
-- @param Wrapper.Group#GROUP AIGroup The AI group.
-- @param Core.Zone#ZONE_BASE PatrolZone The @{Zone} where the patrol needs to be executed.
-- @param Core.Zone#ZONE_BASE PatrolZone The @{Core.Zone} where the patrol needs to be executed.
-- @param DCS#Altitude PatrolFloorAltitude (optional, default = 1000m ) The lowest altitude in meters where to execute the patrol.
-- @param DCS#Altitude PatrolCeilingAltitude (optional, default = 1500m ) The highest altitude in meters where to execute the patrol.
-- @param DCS#Speed PatrolMinSpeed (optional, default = 50% of max speed) The minimum speed of the @{Wrapper.Group} in km/h.
@@ -114,17 +113,17 @@ function AI_AIR_PATROL:New( AI_Air, AIGroup, PatrolZone, PatrolFloorAltitude, Pa
local self = BASE:Inherit( self, AI_Air ) -- #AI_AIR_PATROL
local SpeedMax = AIGroup:GetSpeedMax()
self.PatrolZone = PatrolZone
self.PatrolFloorAltitude = PatrolFloorAltitude or 1000
self.PatrolCeilingAltitude = PatrolCeilingAltitude or 1500
self.PatrolMinSpeed = PatrolMinSpeed or SpeedMax * 0.5
self.PatrolMaxSpeed = PatrolMaxSpeed or SpeedMax * 0.75
-- defafult PatrolAltType to "RADIO" if not specified
self.PatrolAltType = PatrolAltType or "RADIO"
self:AddTransition( { "Started", "Airborne", "Refuelling" }, "Patrol", "Patrolling" )
--- OnBefore Transition Handler for Event Patrol.
@@ -135,7 +134,7 @@ function AI_AIR_PATROL:New( AI_Air, AIGroup, PatrolZone, PatrolFloorAltitude, Pa
-- @param #string Event The Event string.
-- @param #string To The To State string.
-- @return #boolean Return false to cancel Transition.
--- OnAfter Transition Handler for Event Patrol.
-- @function [parent=#AI_AIR_PATROL] OnAfterPatrol
-- @param #AI_AIR_PATROL self
@@ -143,16 +142,16 @@ function AI_AIR_PATROL:New( AI_Air, AIGroup, PatrolZone, PatrolFloorAltitude, Pa
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
--- Synchronous Event Trigger for Event Patrol.
-- @function [parent=#AI_AIR_PATROL] Patrol
-- @param #AI_AIR_PATROL self
--- Asynchronous Event Trigger for Event Patrol.
-- @function [parent=#AI_AIR_PATROL] __Patrol
-- @param #AI_AIR_PATROL self
-- @param #number Delay The delay in seconds.
--- OnLeave Transition Handler for State Patrolling.
-- @function [parent=#AI_AIR_PATROL] OnLeavePatrolling
-- @param #AI_AIR_PATROL self
@@ -161,7 +160,7 @@ function AI_AIR_PATROL:New( AI_Air, AIGroup, PatrolZone, PatrolFloorAltitude, Pa
-- @param #string Event The Event string.
-- @param #string To The To State string.
-- @return #boolean Return false to cancel Transition.
--- OnEnter Transition Handler for State Patrolling.
-- @function [parent=#AI_AIR_PATROL] OnEnterPatrolling
-- @param #AI_AIR_PATROL self
@@ -169,9 +168,9 @@ function AI_AIR_PATROL:New( AI_Air, AIGroup, PatrolZone, PatrolFloorAltitude, Pa
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
self:AddTransition( "Patrolling", "PatrolRoute", "Patrolling" ) -- FSM_CONTROLLABLE Transition for type #AI_AIR_PATROL.
--- OnBefore Transition Handler for Event PatrolRoute.
-- @function [parent=#AI_AIR_PATROL] OnBeforePatrolRoute
-- @param #AI_AIR_PATROL self
@@ -180,7 +179,7 @@ function AI_AIR_PATROL:New( AI_Air, AIGroup, PatrolZone, PatrolFloorAltitude, Pa
-- @param #string Event The Event string.
-- @param #string To The To State string.
-- @return #boolean Return false to cancel Transition.
--- OnAfter Transition Handler for Event PatrolRoute.
-- @function [parent=#AI_AIR_PATROL] OnAfterPatrolRoute
-- @param #AI_AIR_PATROL self
@@ -188,23 +187,21 @@ function AI_AIR_PATROL:New( AI_Air, AIGroup, PatrolZone, PatrolFloorAltitude, Pa
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
--- Synchronous Event Trigger for Event PatrolRoute.
-- @function [parent=#AI_AIR_PATROL] PatrolRoute
-- @param #AI_AIR_PATROL self
--- Asynchronous Event Trigger for Event PatrolRoute.
-- @function [parent=#AI_AIR_PATROL] __PatrolRoute
-- @param #AI_AIR_PATROL self
-- @param #number Delay The delay in seconds.
self:AddTransition( "*", "Reset", "Patrolling" ) -- FSM_CONTROLLABLE Transition for type #AI_AIR_PATROL.
return self
end
--- Set the Engage Range when the AI will engage with airborne enemies.
-- @param #AI_AIR_PATROL self
-- @param #number EngageRange The Engage Range.
@@ -230,7 +227,7 @@ end
-- @param #table CapCoordinates Table of coordinates of first race track point. Second point is determined by leg length and heading.
-- @return #AI_AIR_PATROL self
function AI_AIR_PATROL:SetRaceTrackPattern(LegMin, LegMax, HeadingMin, HeadingMax, DurationMin, DurationMax, CapCoordinates)
self.racetrack=true
self.racetracklegmin=LegMin or 10000
self.racetracklegmax=LegMax or 15000
@@ -238,18 +235,16 @@ function AI_AIR_PATROL:SetRaceTrackPattern(LegMin, LegMax, HeadingMin, HeadingMa
self.racetrackheadingmax=HeadingMax or 180
self.racetrackdurationmin=DurationMin
self.racetrackdurationmax=DurationMax
if self.racetrackdurationmax and not self.racetrackdurationmin then
self.racetrackdurationmin=self.racetrackdurationmax
end
self.racetrackcapcoordinates=CapCoordinates
end
--- Defines a new patrol route using the @{Process_PatrolZone} parameters and settings.
--- Defines a new patrol route using the @{AI.AI_Patrol#AI_PATROL_ZONE} parameters and settings.
-- @param #AI_AIR_PATROL self
-- @return #AI_AIR_PATROL self
-- @param Wrapper.Group#GROUP AIPatrol The Group Object managed by the FSM.
@@ -262,7 +257,7 @@ function AI_AIR_PATROL:onafterPatrol( AIPatrol, From, Event, To )
self:ClearTargetDistance()
self:__PatrolRoute( self.TaskDelay )
AIPatrol:OnReSpawn(
function( PatrolGroup )
self:__Reset( self.TaskDelay )
@@ -271,7 +266,7 @@ function AI_AIR_PATROL:onafterPatrol( AIPatrol, From, Event, To )
)
end
--- This statis method is called from the route path within the last task at the last waaypoint of the AIPatrol.
--- This static method is called from the route path within the last task at the last waypoint of the AIPatrol.
-- Note that this method is required, as triggers the next route when patrolling for the AIPatrol.
-- @param Wrapper.Group#GROUP AIPatrol The AI group.
-- @param #AI_AIR_PATROL Fsm The FSM.
@@ -282,10 +277,10 @@ function AI_AIR_PATROL.___PatrolRoute( AIPatrol, Fsm )
if AIPatrol and AIPatrol:IsAlive() then
Fsm:PatrolRoute()
end
end
--- Defines a new patrol route using the @{Process_PatrolZone} parameters and settings.
--- Defines a new patrol route using the @{AI.AI_Patrol#AI_PATROL_ZONE} parameters and settings.
-- @param #AI_AIR_PATROL self
-- @param Wrapper.Group#GROUP AIPatrol The Group managed by the FSM.
-- @param #string From The From State string.
@@ -300,21 +295,20 @@ function AI_AIR_PATROL:onafterPatrolRoute( AIPatrol, From, Event, To )
return
end
if AIPatrol and AIPatrol:IsAlive() then
local PatrolRoute = {}
--- Calculate the target route point.
local CurrentCoord = AIPatrol:GetCoordinate()
local altitude= math.random( self.PatrolFloorAltitude, self.PatrolCeilingAltitude )
local ToTargetCoord = self.PatrolZone:GetRandomPointVec2()
ToTargetCoord:SetAlt( altitude )
self:SetTargetDistance( ToTargetCoord ) -- For RTB status check
local ToTargetSpeed = math.random( self.PatrolMinSpeed, self.PatrolMaxSpeed )
local speedkmh=ToTargetSpeed
@@ -322,31 +316,31 @@ function AI_AIR_PATROL:onafterPatrolRoute( AIPatrol, From, Event, To )
PatrolRoute[#PatrolRoute+1] = FromWP
if self.racetrack then
-- Random heading.
local heading = math.random(self.racetrackheadingmin, self.racetrackheadingmax)
-- Random leg length.
local leg=math.random(self.racetracklegmin, self.racetracklegmax)
-- Random duration if any.
local duration = self.racetrackdurationmin
if self.racetrackdurationmax then
duration=math.random(self.racetrackdurationmin, self.racetrackdurationmax)
end
-- CAP coordinate.
local c0=self.PatrolZone:GetRandomCoordinate()
if self.racetrackcapcoordinates and #self.racetrackcapcoordinates>0 then
c0=self.racetrackcapcoordinates[math.random(#self.racetrackcapcoordinates)]
end
-- Race track points.
local c1=c0:SetAltitude(altitude) --Core.Point#COORDINATE
local c2=c1:Translate(leg, heading):SetAltitude(altitude)
self:SetTargetDistance(c0) -- For RTB status check
-- Debug:
self:T(string.format("Patrol zone race track: v=%.1f knots, h=%.1f ft, heading=%03d, leg=%d m, t=%s sec", UTILS.KmphToKnots(speedkmh), UTILS.MetersToFeet(altitude), heading, leg, tostring(duration)))
--c1:MarkToAll("Race track c1")
@@ -354,39 +348,41 @@ function AI_AIR_PATROL:onafterPatrolRoute( AIPatrol, From, Event, To )
-- Task to orbit.
local taskOrbit=AIPatrol:TaskOrbit(c1, altitude, UTILS.KmphToMps(speedkmh), c2)
-- Task function to redo the patrol at other random position.
local taskPatrol=AIPatrol:TaskFunction("AI_AIR_PATROL.___PatrolRoute", self)
-- Controlled task with task condition.
local taskCond=AIPatrol:TaskCondition(nil, nil, nil, nil, duration, nil)
local taskCont=AIPatrol:TaskControlled(taskOrbit, taskCond)
-- Second waypoint
PatrolRoute[2]=c1:WaypointAirTurningPoint(self.PatrolAltType, speedkmh, {taskCont, taskPatrol}, "CAP Orbit")
else
--- Create a route point of type air.
local ToWP = ToTargetCoord:WaypointAir(self.PatrolAltType, POINT_VEC3.RoutePointType.TurningPoint, POINT_VEC3.RoutePointAction.TurningPoint, ToTargetSpeed, true)
PatrolRoute[#PatrolRoute+1] = ToWP
local Tasks = {}
Tasks[#Tasks+1] = AIPatrol:TaskFunction("AI_AIR_PATROL.___PatrolRoute", self)
PatrolRoute[#PatrolRoute].task = AIPatrol:TaskCombo( Tasks )
end
AIPatrol:OptionROEReturnFire()
AIPatrol:OptionROTEvadeFire()
AIPatrol:Route( PatrolRoute, self.TaskDelay )
end
end
--- @param Wrapper.Group#GROUP AIPatrol
--- Resumes the AIPatrol
-- @param Wrapper.Group#GROUP AIPatrol
-- @param Core.Fsm#FSM Fsm
function AI_AIR_PATROL.Resume( AIPatrol, Fsm )
AIPatrol:F( { "AI_AIR_PATROL.Resume:", AIPatrol:GetName() } )
@@ -394,5 +390,5 @@ function AI_AIR_PATROL.Resume( AIPatrol, Fsm )
Fsm:__Reset( Fsm.TaskDelay )
Fsm:__PatrolRoute( Fsm.TaskDelay )
end
end
@@ -1,6 +1,6 @@
--- **AI** - Models squadrons for airplanes and helicopters.
--
-- This is a class used in the @{AI_Air_Dispatcher} and derived dispatcher classes.
-- This is a class used in the @{AI.AI_Air_Dispatcher} and derived dispatcher classes.
--
-- ===
--
+6 -6
View File
@@ -1,4 +1,4 @@
--- **AI** -- Peform Battlefield Area Interdiction (BAI) within an engagement zone.
--- **AI** - Peform Battlefield Area Interdiction (BAI) within an engagement zone.
--
-- **Features:**
--
@@ -26,17 +26,17 @@
--
-- ===
--
-- @module AI.AI_Bai
-- @module AI.AI_BAI
-- @image AI_Battlefield_Air_Interdiction.JPG
--- AI_BAI_ZONE class
-- @type AI_BAI_ZONE
-- @field Wrapper.Controllable#CONTROLLABLE AIControllable The @{Wrapper.Controllable} patrolling.
-- @field Core.Zone#ZONE_BASE TargetZone The @{Zone} where the patrol needs to be executed.
-- @field Core.Zone#ZONE_BASE TargetZone The @{Core.Zone} where the patrol needs to be executed.
-- @extends AI.AI_Patrol#AI_PATROL_ZONE
--- Implements the core functions to provide BattleGround Air Interdiction in an Engage @{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}.
--
-- 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.
--
@@ -142,7 +142,7 @@ AI_BAI_ZONE = {
--- Creates a new AI_BAI_ZONE object
-- @param #AI_BAI_ZONE self
-- @param Core.Zone#ZONE_BASE PatrolZone The @{Zone} where the patrol needs to be executed.
-- @param Core.Zone#ZONE_BASE PatrolZone The @{Core.Zone} where the patrol needs to be executed.
-- @param DCS#Altitude PatrolFloorAltitude The lowest altitude in meters where to execute the patrol.
-- @param DCS#Altitude PatrolCeilingAltitude The highest altitude in meters where to execute the patrol.
-- @param DCS#Speed PatrolMinSpeed The minimum speed of the @{Wrapper.Controllable} in km/h.
@@ -566,7 +566,7 @@ function AI_BAI_ZONE:onafterEngage( Controllable, From, Event, To,
EngageRoute[#EngageRoute].task = Controllable:TaskCombo( AttackTasks )
--- Define a random point in the @{Zone}. The AI will fly to that point within the zone.
--- Define a random point in the @{Core.Zone}. The AI will fly to that point within the zone.
--- Find a random 2D point in EngageZone.
local ToTargetVec2 = self.EngageZone:GetRandomVec2()
+1 -1
View File
@@ -1,4 +1,4 @@
--- **AI** -- Balance player slots with AI to create an engaging simulation environment, independent of the amount of players.
--- **AI** - Balance player slots with AI to create an engaging simulation environment, independent of the amount of players.
--
-- **Features:**
--
+54 -71
View File
@@ -1,4 +1,4 @@
--- **AI** -- Perform Combat Air Patrolling (CAP) for airplanes.
--- **AI** - Perform Combat Air Patrolling (CAP) for airplanes.
--
-- **Features:**
--
@@ -6,7 +6,6 @@
-- * Trigger detected events when enemy airplanes are detected.
-- * Manage a fuel threshold to RTB on time.
-- * Engage the enemy when detected.
--
--
-- ===
--
@@ -19,27 +18,25 @@
-- ===
--
-- ### Author: **FlightControl**
-- ### Contributions:
-- ### Contributions:
--
-- * **[Quax](https://forums.eagle.ru/member.php?u=90530)**: Concept, Advice & Testing.
-- * **[Pikey](https://forums.eagle.ru/member.php?u=62835)**: Concept, Advice & Testing.
-- * **[Gunterlund](http://forums.eagle.ru:8080/member.php?u=75036)**: Test case revision.
-- * **[Whisper](http://forums.eagle.ru/member.php?u=3829): Testing.
-- * **[Delta99](https://forums.eagle.ru/member.php?u=125166): Testing.
-- * **[Delta99](https://forums.eagle.ru/member.php?u=125166): Testing.
--
-- ===
--
-- @module AI.AI_Cap
-- @module AI.AI_CAP
-- @image AI_Combat_Air_Patrol.JPG
--- @type AI_CAP_ZONE
-- @field Wrapper.Controllable#CONTROLLABLE AIControllable The @{Wrapper.Controllable} patrolling.
-- @field Core.Zone#ZONE_BASE TargetZone The @{Zone} where the patrol needs to be executed.
-- @field Core.Zone#ZONE_BASE TargetZone The @{Core.Zone} where the patrol needs to be executed.
-- @extends AI.AI_Patrol#AI_PATROL_ZONE
--- Implements the core functions to patrol a @{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.
--
-- ![Process](..\Presentations\AI_CAP\Dia3.JPG)
@@ -106,15 +103,15 @@
-- that will define when the AI will engage with the detected airborne enemy targets.
-- The range can be beyond or smaller than the range of the Patrol Zone.
-- The range is applied at the position of the AI.
-- Use the method @{AI.AI_CAP#AI_CAP_ZONE.SetEngageRange}() to define that range.
-- Use the method @{#AI_CAP_ZONE.SetEngageRange}() to define that range.
--
-- ## 4. Set the Zone of Engagement
--
-- ![Zone](..\Presentations\AI_CAP\Dia12.JPG)
--
-- An optional @{Zone} can be set,
-- An optional @{Core.Zone} can be set,
-- that will define when the AI will engage with the detected airborne enemy targets.
-- Use the method @{AI.AI_Cap#AI_CAP_ZONE.SetEngageZone}() to define that Zone.
-- Use the method @{#AI_CAP_ZONE.SetEngageZone}() to define that Zone.
--
-- ===
--
@@ -123,11 +120,9 @@ AI_CAP_ZONE = {
ClassName = "AI_CAP_ZONE",
}
--- Creates a new AI_CAP_ZONE object
-- @param #AI_CAP_ZONE self
-- @param Core.Zone#ZONE_BASE PatrolZone The @{Zone} where the patrol needs to be executed.
-- @param Core.Zone#ZONE_BASE PatrolZone The @{Core.Zone} where the patrol needs to be executed.
-- @param DCS#Altitude PatrolFloorAltitude The lowest altitude in meters where to execute the patrol.
-- @param DCS#Altitude PatrolCeilingAltitude The highest altitude in meters where to execute the patrol.
-- @param DCS#Speed PatrolMinSpeed The minimum speed of the @{Wrapper.Controllable} in km/h.
@@ -141,7 +136,7 @@ function AI_CAP_ZONE:New( PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude
self.Accomplished = false
self.Engaging = false
self:AddTransition( { "Patrolling", "Engaging" }, "Engage", "Engaging" ) -- FSM_CONTROLLABLE Transition for type #AI_CAP_ZONE.
--- OnBefore Transition Handler for Event Engage.
@@ -152,7 +147,7 @@ function AI_CAP_ZONE:New( PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude
-- @param #string Event The Event string.
-- @param #string To The To State string.
-- @return #boolean Return false to cancel Transition.
--- OnAfter Transition Handler for Event Engage.
-- @function [parent=#AI_CAP_ZONE] OnAfterEngage
-- @param #AI_CAP_ZONE self
@@ -160,11 +155,11 @@ function AI_CAP_ZONE:New( PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
--- Synchronous Event Trigger for Event Engage.
-- @function [parent=#AI_CAP_ZONE] Engage
-- @param #AI_CAP_ZONE self
--- Asynchronous Event Trigger for Event Engage.
-- @function [parent=#AI_CAP_ZONE] __Engage
-- @param #AI_CAP_ZONE self
@@ -188,7 +183,7 @@ function AI_CAP_ZONE:New( PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude
-- @param #string To The To State string.
self:AddTransition( "Engaging", "Fired", "Engaging" ) -- FSM_CONTROLLABLE Transition for type #AI_CAP_ZONE.
--- OnBefore Transition Handler for Event Fired.
-- @function [parent=#AI_CAP_ZONE] OnBeforeFired
-- @param #AI_CAP_ZONE self
@@ -197,7 +192,7 @@ function AI_CAP_ZONE:New( PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude
-- @param #string Event The Event string.
-- @param #string To The To State string.
-- @return #boolean Return false to cancel Transition.
--- OnAfter Transition Handler for Event Fired.
-- @function [parent=#AI_CAP_ZONE] OnAfterFired
-- @param #AI_CAP_ZONE self
@@ -205,11 +200,11 @@ function AI_CAP_ZONE:New( PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
--- Synchronous Event Trigger for Event Fired.
-- @function [parent=#AI_CAP_ZONE] Fired
-- @param #AI_CAP_ZONE self
--- Asynchronous Event Trigger for Event Fired.
-- @function [parent=#AI_CAP_ZONE] __Fired
-- @param #AI_CAP_ZONE self
@@ -225,7 +220,7 @@ function AI_CAP_ZONE:New( PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude
-- @param #string Event The Event string.
-- @param #string To The To State string.
-- @return #boolean Return false to cancel Transition.
--- OnAfter Transition Handler for Event Destroy.
-- @function [parent=#AI_CAP_ZONE] OnAfterDestroy
-- @param #AI_CAP_ZONE self
@@ -233,17 +228,16 @@ function AI_CAP_ZONE:New( PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
--- Synchronous Event Trigger for Event Destroy.
-- @function [parent=#AI_CAP_ZONE] Destroy
-- @param #AI_CAP_ZONE self
--- Asynchronous Event Trigger for Event Destroy.
-- @function [parent=#AI_CAP_ZONE] __Destroy
-- @param #AI_CAP_ZONE self
-- @param #number Delay The delay in seconds.
self:AddTransition( "Engaging", "Abort", "Patrolling" ) -- FSM_CONTROLLABLE Transition for type #AI_CAP_ZONE.
--- OnBefore Transition Handler for Event Abort.
@@ -254,7 +248,7 @@ function AI_CAP_ZONE:New( PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude
-- @param #string Event The Event string.
-- @param #string To The To State string.
-- @return #boolean Return false to cancel Transition.
--- OnAfter Transition Handler for Event Abort.
-- @function [parent=#AI_CAP_ZONE] OnAfterAbort
-- @param #AI_CAP_ZONE self
@@ -262,11 +256,11 @@ function AI_CAP_ZONE:New( PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
--- Synchronous Event Trigger for Event Abort.
-- @function [parent=#AI_CAP_ZONE] Abort
-- @param #AI_CAP_ZONE self
--- Asynchronous Event Trigger for Event Abort.
-- @function [parent=#AI_CAP_ZONE] __Abort
-- @param #AI_CAP_ZONE self
@@ -282,7 +276,7 @@ function AI_CAP_ZONE:New( PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude
-- @param #string Event The Event string.
-- @param #string To The To State string.
-- @return #boolean Return false to cancel Transition.
--- OnAfter Transition Handler for Event Accomplish.
-- @function [parent=#AI_CAP_ZONE] OnAfterAccomplish
-- @param #AI_CAP_ZONE self
@@ -290,11 +284,11 @@ function AI_CAP_ZONE:New( PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
--- Synchronous Event Trigger for Event Accomplish.
-- @function [parent=#AI_CAP_ZONE] Accomplish
-- @param #AI_CAP_ZONE self
--- Asynchronous Event Trigger for Event Accomplish.
-- @function [parent=#AI_CAP_ZONE] __Accomplish
-- @param #AI_CAP_ZONE self
@@ -303,7 +297,6 @@ function AI_CAP_ZONE:New( PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude
return self
end
--- Set the Engage Zone which defines where the AI will engage bogies.
-- @param #AI_CAP_ZONE self
-- @param Core.Zone#ZONE EngageZone The zone where the AI is performing CAP.
@@ -311,7 +304,7 @@ end
function AI_CAP_ZONE:SetEngageZone( EngageZone )
self:F2()
if EngageZone then
if EngageZone then
self.EngageZone = EngageZone
else
self.EngageZone = nil
@@ -346,7 +339,6 @@ function AI_CAP_ZONE:onafterStart( Controllable, From, Event, To )
end
--- @param AI.AI_CAP#AI_CAP_ZONE
-- @param Wrapper.Group#GROUP EngageGroup
function AI_CAP_ZONE.EngageRoute( EngageGroup, Fsm )
@@ -358,8 +350,6 @@ function AI_CAP_ZONE.EngageRoute( EngageGroup, Fsm )
end
end
--- @param #AI_CAP_ZONE self
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
-- @param #string From The From State string.
@@ -380,11 +370,11 @@ end
function AI_CAP_ZONE:onafterDetected( Controllable, From, Event, To )
if From ~= "Engaging" then
local Engage = false
for DetectedUnit, Detected in pairs( self.DetectedUnits ) do
local DetectedUnit = DetectedUnit -- Wrapper.Unit#UNIT
self:T( DetectedUnit )
if DetectedUnit:IsAlive() and DetectedUnit:IsAir() then
@@ -392,7 +382,7 @@ function AI_CAP_ZONE:onafterDetected( Controllable, From, Event, To )
break
end
end
if Engage == true then
self:F( 'Detected -> Engaging' )
self:__Engage( 1 )
@@ -400,7 +390,6 @@ function AI_CAP_ZONE:onafterDetected( Controllable, From, Event, To )
end
end
--- @param #AI_CAP_ZONE self
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
-- @param #string From The From State string.
@@ -411,9 +400,6 @@ function AI_CAP_ZONE:onafterAbort( Controllable, From, Event, To )
self:__Route( 1 )
end
--- @param #AI_CAP_ZONE self
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
-- @param #string From The From State string.
@@ -427,26 +413,23 @@ function AI_CAP_ZONE:onafterEngage( Controllable, From, Event, To )
--- Calculate the current route point.
local CurrentVec2 = self.Controllable:GetVec2()
if not CurrentVec2 then -- flight dead at this point
return self
end
if not CurrentVec2 then return self end
--DONE: Create GetAltitude function for GROUP, and delete GetUnit(1).
local CurrentAltitude = self.Controllable:GetAltitude()
local CurrentPointVec3 = POINT_VEC3:New( CurrentVec2.x, CurrentAltitude, CurrentVec2.y )
local ToEngageZoneSpeed = self.PatrolMaxSpeed
local CurrentRoutePoint = CurrentPointVec3:WaypointAir(
self.PatrolAltType,
POINT_VEC3.RoutePointType.TurningPoint,
POINT_VEC3.RoutePointAction.TurningPoint,
ToEngageZoneSpeed,
true
local CurrentRoutePoint = CurrentPointVec3:WaypointAir(
self.PatrolAltType,
POINT_VEC3.RoutePointType.TurningPoint,
POINT_VEC3.RoutePointAction.TurningPoint,
ToEngageZoneSpeed,
true
)
EngageRoute[#EngageRoute+1] = CurrentRoutePoint
--- Find a random 2D point in PatrolZone.
local ToTargetVec2 = self.PatrolZone:GetRandomVec2()
self:T2( ToTargetVec2 )
@@ -455,17 +438,17 @@ function AI_CAP_ZONE:onafterEngage( Controllable, From, Event, To )
local ToTargetAltitude = math.random( self.EngageFloorAltitude, self.EngageCeilingAltitude )
local ToTargetSpeed = math.random( self.PatrolMinSpeed, self.PatrolMaxSpeed )
self:T2( { self.PatrolMinSpeed, self.PatrolMaxSpeed, ToTargetSpeed } )
--- Obtain a 3D @{Point} from the 2D point + altitude.
local ToTargetPointVec3 = POINT_VEC3:New( ToTargetVec2.x, ToTargetAltitude, ToTargetVec2.y )
--- Create a route point of type air.
local ToPatrolRoutePoint = ToTargetPointVec3:WaypointAir(
self.PatrolAltType,
POINT_VEC3.RoutePointType.TurningPoint,
POINT_VEC3.RoutePointAction.TurningPoint,
ToTargetSpeed,
true
local ToPatrolRoutePoint = ToTargetPointVec3:WaypointAir(
self.PatrolAltType,
POINT_VEC3.RoutePointType.TurningPoint,
POINT_VEC3.RoutePointAction.TurningPoint,
ToTargetSpeed,
true
)
EngageRoute[#EngageRoute+1] = ToPatrolRoutePoint
@@ -484,7 +467,7 @@ function AI_CAP_ZONE:onafterEngage( Controllable, From, Event, To )
self:F( {"Within Zone and Engaging ", DetectedUnit } )
AttackTasks[#AttackTasks+1] = Controllable:TaskAttackUnit( DetectedUnit )
end
else
else
if self.EngageRange then
if DetectedUnit:GetPointVec3():Get2DDistance(Controllable:GetPointVec3() ) <= self.EngageRange then
self:F( {"Within Range and Engaging", DetectedUnit } )
@@ -508,12 +491,12 @@ function AI_CAP_ZONE:onafterEngage( Controllable, From, Event, To )
AttackTasks[#AttackTasks+1] = Controllable:TaskFunction( "AI_CAP_ZONE.EngageRoute", self )
EngageRoute[1].task = Controllable:TaskCombo( AttackTasks )
self:SetDetectionDeactivated()
end
Controllable:Route( EngageRoute, 0.5 )
end
end
+7 -7
View File
@@ -1,4 +1,4 @@
--- **AI** -- Perform Close Air Support (CAS) near friendlies.
--- **AI** - Perform Close Air Support (CAS) near friendlies.
--
-- **Features:**
--
@@ -28,16 +28,16 @@
--
-- ===
--
-- @module AI.AI_Cas
-- @module AI.AI_CAS
-- @image AI_Close_Air_Support.JPG
--- AI_CAS_ZONE class
-- @type AI_CAS_ZONE
-- @field Wrapper.Controllable#CONTROLLABLE AIControllable The @{Wrapper.Controllable} patrolling.
-- @field Core.Zone#ZONE_BASE TargetZone The @{Zone} where the patrol needs to be executed.
-- @field Core.Zone#ZONE_BASE TargetZone The @{Core.Zone} where the patrol needs to be executed.
-- @extends AI.AI_Patrol#AI_PATROL_ZONE
--- Implements the core functions to provide Close Air Support in an Engage @{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}.
-- 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)
@@ -130,7 +130,7 @@ AI_CAS_ZONE = {
--- Creates a new AI_CAS_ZONE object
-- @param #AI_CAS_ZONE self
-- @param Core.Zone#ZONE_BASE PatrolZone The @{Zone} where the patrol needs to be executed.
-- @param Core.Zone#ZONE_BASE PatrolZone The @{Core.Zone} where the patrol needs to be executed.
-- @param DCS#Altitude PatrolFloorAltitude The lowest altitude in meters where to execute the patrol.
-- @param DCS#Altitude PatrolCeilingAltitude The highest altitude in meters where to execute the patrol.
-- @param DCS#Speed PatrolMinSpeed The minimum speed of the @{Wrapper.Controllable} in km/h.
@@ -459,7 +459,7 @@ function AI_CAS_ZONE:onafterEngage( Controllable, From, Event, To,
--- Calculate the current route point.
local CurrentVec2 = self.Controllable:GetVec2()
--TODO: 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 CurrentPointVec3 = POINT_VEC3:New( CurrentVec2.x, CurrentAltitude, CurrentVec2.y )
local ToEngageZoneSpeed = self.PatrolMaxSpeed
@@ -496,7 +496,7 @@ function AI_CAS_ZONE:onafterEngage( Controllable, From, Event, To,
AttackTasks[#AttackTasks+1] = Controllable:TaskFunction( "AI_CAS_ZONE.EngageRoute", self )
EngageRoute[#EngageRoute].task = Controllable:TaskCombo( AttackTasks )
--- Define a random point in the @{Zone}. The AI will fly to that point within the zone.
--- Define a random point in the @{Core.Zone}. The AI will fly to that point within the zone.
--- Find a random 2D point in EngageZone.
local ToTargetVec2 = self.EngageZone:GetRandomVec2()
@@ -1,4 +1,4 @@
--- **AI** -- (R2.4) - Models the intelligent transportation of infantry and other cargo using Planes.
--- **AI** - Models the intelligent transportation of infantry and other cargo using Planes.
--
-- ## Features:
--
@@ -1,4 +1,4 @@
--- **AI** -- (2.4) - Models the intelligent transportation of infantry and other cargo using Helicopters.
--- **AI** - Models the intelligent transportation of infantry and other cargo using Helicopters.
--
-- ## Features:
--
@@ -174,8 +174,8 @@ function AI_CARGO_DISPATCHER_HELICOPTER:New( HelicopterSet, CargoSet, PickupZone
self:SetPickupSpeed( 350, 150 )
self:SetDeploySpeed( 350, 150 )
self:SetPickupRadius( 0, 0 )
self:SetDeployRadius( 0, 0 )
self:SetPickupRadius( 40, 12 )
self:SetDeployRadius( 40, 12 )
self:SetPickupHeight( 500, 200 )
self:SetDeployHeight( 500, 200 )
@@ -186,6 +186,9 @@ end
function AI_CARGO_DISPATCHER_HELICOPTER:AICargo( Helicopter, CargoSet )
return AI_CARGO_HELICOPTER:New( Helicopter, CargoSet )
local dispatcher = AI_CARGO_HELICOPTER:New( Helicopter, CargoSet )
dispatcher:SetLandingSpeedAndHeight(27, 6)
return dispatcher
end
@@ -1,4 +1,4 @@
--- **AI** -- (2.5.1) - Models the intelligent transportation of infantry and other cargo using Ships
--- **AI** - Models the intelligent transportation of infantry and other cargo using Ships.
--
-- ## Features:
--
@@ -21,7 +21,7 @@
-- ===
--
-- @module AI.AI_Cargo_Dispatcher_Ship
-- @image AI_Cargo_Dispatching_For_Ship.JPG
-- @image AI_Cargo_Dispatcher.JPG
--- @type AI_CARGO_DISPATCHER_SHIP
-- @extends AI.AI_Cargo_Dispatcher#AI_CARGO_DISPATCHER
@@ -37,14 +37,14 @@
--
-- This will be particularly helpful in order to determine how to **Tailor the different cargo handling events**.
--
-- The AI_CARGO_DISPATCHER_SHIP class uses the @{Cargo.Cargo} capabilities within the MOOSE framwork.
-- The AI_CARGO_DISPATCHER_SHIP class uses the @{Cargo.Cargo} capabilities within the MOOSE framework.
-- Also ensure that you fully understand how to declare and setup Cargo objects within the MOOSE framework before using this class.
-- CARGO derived objects must generally be declared within the mission to make the AI_CARGO_DISPATCHER_SHIP object recognize the cargo.
--
--
-- # 1) AI_CARGO_DISPATCHER_SHIP constructor.
--
-- * @{AI_CARGO_DISPATCHER_SHIP.New}(): Creates a new AI_CARGO_DISPATCHER_SHIP object.
-- * @{#AI_CARGO_DISPATCHER_SHIP.New}(): Creates a new AI_CARGO_DISPATCHER_SHIP object.
--
-- ---
--
+4 -4
View File
@@ -1,4 +1,4 @@
--- **AI** -- (R2.5.1) - Models the intelligent transportation of infantry and other cargo.
--- **AI** - Models the intelligent transportation of infantry and other cargo.
--
-- ===
--
@@ -7,7 +7,7 @@
-- ===
--
-- @module AI.AI_Cargo_Ship
-- @image AI_Cargo_Dispatching_For_Ship.JPG
-- @image AI_Cargo_Dispatcher.JPG
--- @type AI_CARGO_SHIP
-- @extends AI.AI_Cargo#AI_CARGO
@@ -46,12 +46,12 @@
--
-- ## Cargo deployment.
--
-- Using the @{AI_CARGO_SHIP.Deploy}() method, you are able to direct the Ship towards a Deploy zone to unboard/unload the cargo at the
-- Using the @{#AI_CARGO_SHIP.Deploy}() method, you are able to direct the Ship towards a Deploy zone to unboard/unload the cargo at the
-- specified coordinate. The Ship will follow the Shipping Lane to ensure consistent cargo transportation within the simulation environment.
--
-- ## Cargo pickup.
--
-- Using the @{AI_CARGO_SHIP.Pickup}() method, you are able to direct the Ship towards a Pickup zone to board/load the cargo at the specified
-- Using the @{#AI_CARGO_SHIP.Pickup}() method, you are able to direct the Ship towards a Pickup zone to board/load the cargo at the specified
-- coordinate. The Ship will follow the Shipping Lane to ensure consistent cargo transportation within the simulation environment.
--
--
+22 -22
View File
@@ -1,4 +1,4 @@
--- **Functional** -- Taking the lead of AI escorting your flight or of other AI.
--- **AI** - Taking the lead of AI escorting your flight or of other AI.
--
-- ===
--
@@ -443,9 +443,9 @@ end
-- @param #AI_ESCORT self
-- @param #number XStart The start position on the X-axis in meters for the first group.
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
-- @param #number YStart The start position on the Y-axis in meters for the first group.
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
-- @param #nubmer ZStart The start position on the Z-axis in meters for the first group.
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
-- @param #number ZLevels The amount of levels on the Z-axis.
-- @return #AI_ESCORT
@@ -493,9 +493,9 @@ end
-- @param #AI_ESCORT self
-- @param #number XStart The start position on the X-axis in meters for the first group.
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
-- @param #number YStart The start position on the Y-axis in meters for the first group.
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
-- @param #nubmer ZStart The start position on the Z-axis in meters for the first group.
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
-- @param #number ZLevels The amount of levels on the Z-axis.
-- @return #AI_ESCORT
@@ -580,7 +580,7 @@ end
-- @param #AI_ESCORT self
-- @param #number XStart The start position on the X-axis in meters for the first group.
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
-- @param #number YStart The start position on the Y-axis in meters for the first group.
-- @return #AI_ESCORT
function AI_ESCORT:MenuFormationTrail( XStart, XSpace, YStart )
@@ -594,7 +594,7 @@ end
-- @param #AI_ESCORT self
-- @param #number XStart The start position on the X-axis in meters for the first group.
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
-- @param #number YStart The start position on the Y-axis in meters for the first group.
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
-- @return #AI_ESCORT
function AI_ESCORT:MenuFormationStack( XStart, XSpace, YStart, YSpace )
@@ -609,8 +609,8 @@ end
-- This menu will appear under **Formation**.
-- @param #AI_ESCORT self
-- @param #number XStart The start position on the X-axis in meters for the first group.
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
-- @param #nubmer ZStart The start position on the Z-axis in meters for the first group.
-- @param #number YStart The start position on the Y-axis in meters for the first group.
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
-- @return #AI_ESCORT
function AI_ESCORT:MenuFormationLeftLine( XStart, YStart, ZStart, ZSpace )
@@ -625,8 +625,8 @@ end
-- This menu will appear under **Formation**.
-- @param #AI_ESCORT self
-- @param #number XStart The start position on the X-axis in meters for the first group.
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
-- @param #nubmer ZStart The start position on the Z-axis in meters for the first group.
-- @param #number YStart The start position on the Y-axis in meters for the first group.
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
-- @return #AI_ESCORT
function AI_ESCORT:MenuFormationRightLine( XStart, YStart, ZStart, ZSpace )
@@ -642,8 +642,8 @@ end
-- @param #AI_ESCORT self
-- @param #number XStart The start position on the X-axis in meters for the first group.
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
-- @param #nubmer ZStart The start position on the Z-axis in meters for the first group.
-- @param #number YStart The start position on the Y-axis in meters for the first group.
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
-- @return #AI_ESCORT
function AI_ESCORT:MenuFormationLeftWing( XStart, XSpace, YStart, ZStart, ZSpace )
@@ -659,8 +659,8 @@ end
-- @param #AI_ESCORT self
-- @param #number XStart The start position on the X-axis in meters for the first group.
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
-- @param #nubmer ZStart The start position on the Z-axis in meters for the first group.
-- @param #number YStart The start position on the Y-axis in meters for the first group.
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
-- @return #AI_ESCORT
function AI_ESCORT:MenuFormationRightWing( XStart, XSpace, YStart, ZStart, ZSpace )
@@ -676,9 +676,9 @@ end
-- @param #AI_ESCORT self
-- @param #number XStart The start position on the X-axis in meters for the first group.
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
-- @param #number YStart The start position on the Y-axis in meters for the first group.
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
-- @param #nubmer ZStart The start position on the Z-axis in meters for the first group.
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
-- @return #AI_ESCORT
function AI_ESCORT:MenuFormationCenterWing( XStart, XSpace, YStart, YSpace, ZStart, ZSpace )
@@ -694,9 +694,9 @@ end
-- @param #AI_ESCORT self
-- @param #number XStart The start position on the X-axis in meters for the first group.
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
-- @param #number YStart The start position on the Y-axis in meters for the first group.
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
-- @param #nubmer ZStart The start position on the Z-axis in meters for the first group.
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
-- @return #AI_ESCORT
function AI_ESCORT:MenuFormationVic( XStart, XSpace, YStart, YSpace, ZStart, ZSpace )
@@ -712,9 +712,9 @@ end
-- @param #AI_ESCORT self
-- @param #number XStart The start position on the X-axis in meters for the first group.
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
-- @param #number YStart The start position on the Y-axis in meters for the first group.
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
-- @param #nubmer ZStart The start position on the Z-axis in meters for the first group.
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
-- @param #number ZLevels The amount of levels on the Z-axis.
-- @return #AI_ESCORT
@@ -1471,7 +1471,7 @@ end
-- @param #AI_ESCORT self
-- @param #number XStart The start position on the X-axis in meters for the first group.
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
-- @param #number YStart The start position on the Y-axis in meters for the first group.
-- @return #AI_ESCORT
function AI_ESCORT:_EscortFormationTrail( EscortGroup, XStart, XSpace, YStart )
@@ -11,7 +11,7 @@
--
-- ===
--
-- @module AI.AI_ESCORT_DISPATCHER_REQUEST
-- @module AI.AI_Escort_Dispatcher_Request
-- @image MOOSE.JPG
@@ -1,4 +1,4 @@
--- **Functional** -- Taking the lead of AI escorting your flight or of other AI, upon request using the menu.
--- **AI** - Taking the lead of AI escorting your flight or of other AI, upon request using the menu.
--
-- ===
--
@@ -143,7 +143,7 @@
--
-- ===
--
-- @module AI.AI_Escort
-- @module AI.AI_Escort_Request
-- @image Escorting.JPG
+4 -4
View File
@@ -1,4 +1,4 @@
--- **AI** -- Build large airborne formations of aircraft.
--- **AI** - Build large airborne formations of aircraft.
--
-- **Features:**
--
@@ -41,7 +41,7 @@
--- Build large formations, make AI follow a @{Wrapper.Client#CLIENT} (player) leader or a @{Wrapper.Unit#UNIT} (AI) leader.
--
-- AI_FORMATION makes AI @{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 purpose of the class is to:
--
@@ -1140,8 +1140,8 @@ end
-- @param DCS#Vec3 CV2 Vec3
function AI_FORMATION:FollowMe(FollowGroup, ClientUnit, CT1, CV1, CT2, CV2)
if FollowGroup:GetState( FollowGroup, "Mode" ) == self.__Enum.Mode.Formation then
if FollowGroup:GetState( FollowGroup, "Mode" ) == self.__Enum.Mode.Formation and not self:Is("Stopped") then
self:T({Mode=FollowGroup:GetState( FollowGroup, "Mode" )})
FollowGroup:OptionROTEvadeFire()
+40 -41
View File
@@ -1,4 +1,4 @@
--- **AI** -- Perform Air Patrolling for airplanes.
--- **AI** - Perform Air Patrolling for airplanes.
--
-- **Features:**
--
@@ -38,7 +38,7 @@
--- AI_PATROL_ZONE class
-- @type AI_PATROL_ZONE
-- @field Wrapper.Controllable#CONTROLLABLE AIControllable The @{Wrapper.Controllable} patrolling.
-- @field Core.Zone#ZONE_BASE PatrolZone The @{Zone} where the patrol needs to be executed.
-- @field Core.Zone#ZONE_BASE PatrolZone The @{Core.Zone} where the patrol needs to be executed.
-- @field DCS#Altitude PatrolFloorAltitude The lowest altitude in meters where to execute the patrol.
-- @field DCS#Altitude PatrolCeilingAltitude The highest altitude in meters where to execute the patrol.
-- @field DCS#Speed PatrolMinSpeed The minimum speed of the @{Wrapper.Controllable} in km/h.
@@ -46,7 +46,7 @@
-- @field Core.Spawn#SPAWN CoordTest
-- @extends Core.Fsm#FSM_CONTROLLABLE
--- Implements the core functions to patrol a @{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}.
--
-- ![Process](..\Presentations\AI_PATROL\Dia3.JPG)
--
@@ -135,15 +135,15 @@
-- When the AI is out of fuel, it is required that a new AI is started, before the old AI can return to the home base.
-- Therefore, with a parameter and a calculation of the distance to the home base, the fuel threshold is calculated.
-- When the fuel threshold is reached, the AI will continue for a given time its patrol task in orbit,
-- while a new AI is targetted to the AI_PATROL_ZONE.
-- while a new AI is targeted to the AI_PATROL_ZONE.
-- Once the time is finished, the old AI will return to the base.
-- Use the method @{#AI_PATROL_ZONE.ManageFuel}() to have this proces in place.
-- Use the method @{#AI_PATROL_ZONE.ManageFuel}() to have this process in place.
--
-- ## 7. Manage "damage" behaviour of the AI in the AI_PATROL_ZONE
--
-- When the AI is damaged, it is required that a new AIControllable is started. However, damage cannon be foreseen early on.
-- Therefore, when the damage threshold is reached, the AI will return immediately to the home base (RTB).
-- Use the method @{#AI_PATROL_ZONE.ManageDamage}() to have this proces in place.
-- Use the method @{#AI_PATROL_ZONE.ManageDamage}() to have this process in place.
--
-- ===
--
@@ -154,7 +154,7 @@ AI_PATROL_ZONE = {
--- Creates a new AI_PATROL_ZONE object
-- @param #AI_PATROL_ZONE self
-- @param Core.Zone#ZONE_BASE PatrolZone The @{Zone} where the patrol needs to be executed.
-- @param Core.Zone#ZONE_BASE PatrolZone The @{Core.Zone} where the patrol needs to be executed.
-- @param DCS#Altitude PatrolFloorAltitude The lowest altitude in meters where to execute the patrol.
-- @param DCS#Altitude PatrolCeilingAltitude The highest altitude in meters where to execute the patrol.
-- @param DCS#Speed PatrolMinSpeed The minimum speed of the @{Wrapper.Controllable} in km/h.
@@ -170,27 +170,27 @@ function AI_PATROL_ZONE:New( PatrolZone, PatrolFloorAltitude, PatrolCeilingAltit
-- Inherits from BASE
local self = BASE:Inherit( self, FSM_CONTROLLABLE:New() ) -- #AI_PATROL_ZONE
self.PatrolZone = PatrolZone
self.PatrolFloorAltitude = PatrolFloorAltitude
self.PatrolCeilingAltitude = PatrolCeilingAltitude
self.PatrolMinSpeed = PatrolMinSpeed
self.PatrolMaxSpeed = PatrolMaxSpeed
-- defafult PatrolAltType to "BARO" if not specified
self.PatrolAltType = PatrolAltType or "BARO"
self:SetRefreshTimeInterval( 30 )
self.CheckStatus = true
self:ManageFuel( .2, 60 )
self:ManageDamage( 1 )
self.DetectedUnits = {} -- This table contains the targets detected during patrol.
self:SetStartState( "None" )
self:AddTransition( "*", "Stop", "Stopped" )
@@ -228,7 +228,7 @@ function AI_PATROL_ZONE:New( PatrolZone, PatrolFloorAltitude, PatrolCeilingAltit
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
--- Synchronous Event Trigger for Event Stop.
-- @function [parent=#AI_PATROL_ZONE] Stop
-- @param #AI_PATROL_ZONE self
@@ -256,7 +256,7 @@ function AI_PATROL_ZONE:New( PatrolZone, PatrolFloorAltitude, PatrolCeilingAltit
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
--- Synchronous Event Trigger for Event Start.
-- @function [parent=#AI_PATROL_ZONE] Start
-- @param #AI_PATROL_ZONE self
@@ -329,7 +329,7 @@ function AI_PATROL_ZONE:New( PatrolZone, PatrolFloorAltitude, PatrolCeilingAltit
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
--- Synchronous Event Trigger for Event Status.
-- @function [parent=#AI_PATROL_ZONE] Status
-- @param #AI_PATROL_ZONE self
@@ -413,7 +413,7 @@ function AI_PATROL_ZONE:New( PatrolZone, PatrolFloorAltitude, PatrolCeilingAltit
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
--- Synchronous Event Trigger for Event RTB.
-- @function [parent=#AI_PATROL_ZONE] RTB
-- @param #AI_PATROL_ZONE self
@@ -441,11 +441,11 @@ function AI_PATROL_ZONE:New( PatrolZone, PatrolFloorAltitude, PatrolCeilingAltit
-- @param #string To The To State string.
self:AddTransition( "*", "Reset", "Patrolling" ) -- FSM_CONTROLLABLE Transition for type #AI_PATROL_ZONE.
self:AddTransition( "*", "Eject", "*" )
self:AddTransition( "*", "Crash", "Crashed" )
self:AddTransition( "*", "PilotDead", "*" )
return self
end
@@ -459,7 +459,7 @@ end
-- @return #AI_PATROL_ZONE self
function AI_PATROL_ZONE:SetSpeed( PatrolMinSpeed, PatrolMaxSpeed )
self:F2( { PatrolMinSpeed, PatrolMaxSpeed } )
self.PatrolMinSpeed = PatrolMinSpeed
self.PatrolMaxSpeed = PatrolMaxSpeed
end
@@ -473,7 +473,7 @@ end
-- @return #AI_PATROL_ZONE self
function AI_PATROL_ZONE:SetAltitude( PatrolFloorAltitude, PatrolCeilingAltitude )
self:F2( { PatrolFloorAltitude, PatrolCeilingAltitude } )
self.PatrolFloorAltitude = PatrolFloorAltitude
self.PatrolCeilingAltitude = PatrolCeilingAltitude
end
@@ -582,7 +582,7 @@ end
--- When the AI is out of fuel, it is required that a new AI is started, before the old AI can return to the home base.
-- Therefore, with a parameter and a calculation of the distance to the home base, the fuel threshold is calculated.
-- When the fuel threshold is reached, the AI will continue for a given time its patrol task in orbit, while a new AIControllable is targetted to the AI_PATROL_ZONE.
-- When the fuel threshold is reached, the AI will continue for a given time its patrol task in orbit, while a new AIControllable is targeted to the AI_PATROL_ZONE.
-- Once the time is finished, the old AI will return to the base.
-- @param #AI_PATROL_ZONE self
-- @param #number PatrolFuelThresholdPercentage The threshold in percentage (between 0 and 1) when the AIControllable is considered to get out of fuel.
@@ -592,7 +592,7 @@ function AI_PATROL_ZONE:ManageFuel( PatrolFuelThresholdPercentage, PatrolOutOfFu
self.PatrolFuelThresholdPercentage = PatrolFuelThresholdPercentage
self.PatrolOutOfFuelOrbitTime = PatrolOutOfFuelOrbitTime
return self
end
@@ -609,28 +609,28 @@ function AI_PATROL_ZONE:ManageDamage( PatrolDamageThreshold )
self.PatrolManageDamage = true
self.PatrolDamageThreshold = PatrolDamageThreshold
return self
end
--- Defines a new patrol route using the @{Process_PatrolZone} parameters and settings.
--- Defines a new patrol route using the @{#AI_PATROL_ZONE} parameters and settings.
-- @param #AI_PATROL_ZONE self
-- @return #AI_PATROL_ZONE self
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
-- @return #AI_PATROL_ZONE self
function AI_PATROL_ZONE:onafterStart( Controllable, From, Event, To )
self:F2()
self:__Route( 1 ) -- Route to the patrol point. The asynchronous trigger is important, because a spawned group and units takes at least one second to come live.
self:__Status( 60 ) -- Check status status every 30 seconds.
self:SetDetectionActivated()
self:HandleEvent( EVENTS.PilotDead, self.OnPilotDead )
self:HandleEvent( EVENTS.Crash, self.OnCrash )
self:HandleEvent( EVENTS.Ejection, self.OnEjection )
Controllable:OptionROEHoldFire()
Controllable:OptionROTVertical()
@@ -667,12 +667,12 @@ function AI_PATROL_ZONE:onafterDetect( Controllable, From, Event, To )
if TargetObject and TargetObject:isExist() and TargetObject.id_ < 50000000 then
local TargetUnit = UNIT:Find( TargetObject )
-- Check that target is alive due to issue https://github.com/FlightControl-Master/MOOSE/issues/1234
if TargetUnit and TargetUnit:IsAlive() then
local TargetUnitName = TargetUnit:GetName()
if self.DetectionZone then
if TargetUnit:IsInZone( self.DetectionZone ) then
self:T( {"Detected ", TargetUnit } )
@@ -687,13 +687,13 @@ function AI_PATROL_ZONE:onafterDetect( Controllable, From, Event, To )
end
Detected = true
end
end
end
end
self:__Detect( -self.DetectInterval )
if Detected == true then
self:__Detected( 1.5 )
end
@@ -701,7 +701,7 @@ function AI_PATROL_ZONE:onafterDetect( Controllable, From, Event, To )
end
--- @param Wrapper.Controllable#CONTROLLABLE AIControllable
-- This statis method is called from the route path within the last task at the last waaypoint of the Controllable.
-- This static method is called from the route path within the last task at the last waypoint of the Controllable.
-- Note that this method is required, as triggers the next route when patrolling for the Controllable.
function AI_PATROL_ZONE:_NewPatrolRoute( AIControllable )
@@ -710,7 +710,7 @@ function AI_PATROL_ZONE:_NewPatrolRoute( AIControllable )
end
--- Defines a new patrol route using the @{Process_PatrolZone} parameters and settings.
--- Defines a new patrol route using the @{#AI_PATROL_ZONE} parameters and settings.
-- @param #AI_PATROL_ZONE self
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
-- @param #string From The From State string.
@@ -725,12 +725,11 @@ function AI_PATROL_ZONE:onafterRoute( Controllable, From, Event, To )
return
end
local life = self.Controllable:GetLife() or 0
if self.Controllable:IsAlive() and life > 1 then
-- Determine if the AIControllable is within the PatrolZone.
-- If not, make a waypoint within the to that the AIControllable will fly at maximum speed to that point.
local PatrolRoute = {}
-- Calculate the current route point of the controllable as the start point of the route.
@@ -745,7 +744,7 @@ function AI_PATROL_ZONE:onafterRoute( Controllable, From, Event, To )
self:T( "Not in the air, finding route path within PatrolZone" )
local CurrentVec2 = self.Controllable:GetVec2()
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 CurrentPointVec3 = POINT_VEC3:New( CurrentVec2.x, CurrentAltitude, CurrentVec2.y )
local ToPatrolZoneSpeed = self.PatrolMaxSpeed
@@ -776,7 +775,7 @@ function AI_PATROL_ZONE:onafterRoute( Controllable, From, Event, To )
end
--- Define a random point in the @{Zone}. The AI will fly to that point within the zone.
--- Define a random point in the @{Core.Zone}. The AI will fly to that point within the zone.
--- Find a random 2D point in PatrolZone.
local ToTargetVec2 = self.PatrolZone:GetRandomVec2()
@@ -1,10 +1,10 @@
--- **Actions** - ACT_ACCOUNT_ classes **account for** (detect, count & report) various DCS events occuring on @{Wrapper.Unit}s.
--- **Actions** - ACT_ACCOUNT_ classes **account for** (detect, count & report) various DCS events occurring on UNITs.
--
-- ![Banner Image](..\Presentations\ACT_ACCOUNT\Dia1.JPG)
--
-- ===
--
-- @module Actions.Account
-- @module Actions.Act_Account
-- @image MOOSE.JPG
do -- ACT_ACCOUNT
@@ -20,7 +20,7 @@ do -- ACT_ACCOUNT
--
-- ### ACT_ACCOUNT States
--
-- * **Asigned**: The player is assigned.
-- * **Assigned**: The player is assigned.
-- * **Waiting**: Waiting for an event.
-- * **Report**: Reporting.
-- * **Account**: Account for an event.
@@ -104,7 +104,6 @@ do -- ACT_ACCOUNT
self:__Wait( 1 )
end
--- StateMachine callback function
-- @param #ACT_ACCOUNT self
-- @param Wrapper.Unit#UNIT ProcessUnit
@@ -141,7 +140,7 @@ do -- ACT_ACCOUNT_DEADS
--- # @{#ACT_ACCOUNT_DEADS} FSM class, extends @{Core.Fsm.Account#ACT_ACCOUNT}
--
-- The ACT_ACCOUNT_DEADS class accounts (detects, counts and reports) successful kills of DCS units.
-- The process is given a @{Set} of units that will be tracked upon successful destruction.
-- The process is given a @{Core.Set} of units that will be tracked upon successful destruction.
-- The process will end after each target has been successfully destroyed.
-- Each successful dead will trigger an Account state transition that can be scored, modified or administered.
--
@@ -157,7 +156,6 @@ do -- ACT_ACCOUNT_DEADS
ClassName = "ACT_ACCOUNT_DEADS",
}
--- Creates a new DESTROY process.
-- @param #ACT_ACCOUNT_DEADS self
-- @param Core.Set#SET_UNIT TargetSetUnit
@@ -195,7 +193,6 @@ do -- ACT_ACCOUNT_DEADS
self:GetCommandCenter():MessageTypeToGroup( MessageText, ProcessUnit:GetGroup(), MESSAGE.Type.Information )
end
--- StateMachine callback function
-- @param #ACT_ACCOUNT_DEADS self
-- @param Wrapper.Unit#UNIT ProcessUnit
@@ -270,7 +267,6 @@ do -- ACT_ACCOUNT_DEADS
end
end
--- DCS Events
--- @param #ACT_ACCOUNT_DEADS self
@@ -77,7 +77,7 @@
--
-- ===
--
-- @module Actions.Assign
-- @module Actions.Act_Assign
-- @image MOOSE.JPG
@@ -50,7 +50,7 @@
--
-- # 1) @{#ACT_ASSIST_SMOKE_TARGETS_ZONE} class, extends @{Core.Fsm.Route#ACT_ASSIST}
--
-- The ACT_ASSIST_SMOKE_TARGETS_ZONE class implements the core functions to smoke targets in a @{Zone}.
-- The ACT_ASSIST_SMOKE_TARGETS_ZONE class implements the core functions to smoke targets in a @{Core.Zone}.
-- The targets are smoked within a certain range around each target, simulating a realistic smoking behaviour.
-- At random intervals, a new target is smoked.
--
@@ -60,7 +60,7 @@
--
-- ===
--
-- @module Actions.Assist
-- @module Actions.Act_Assist
-- @image MOOSE.JPG
@@ -62,7 +62,7 @@
--
-- # 1) @{#ACT_ROUTE_ZONE} class, extends @{Core.Fsm.Route#ACT_ROUTE}
--
-- The ACT_ROUTE_ZONE class implements the core functions to route an AIR @{Wrapper.Controllable} player @{Wrapper.Unit} to a @{Zone}.
-- The ACT_ROUTE_ZONE class implements the core functions to route an AIR @{Wrapper.Controllable} player @{Wrapper.Unit} to a @{Core.Zone}.
-- The player receives on perioding times messages with the coordinates of the route to follow.
-- Upon arrival at the zone, a confirmation of arrival is sent, and the process will be ended.
--
@@ -72,7 +72,7 @@
--
-- ===
--
-- @module Actions.Route
-- @module Actions.Act_Route
-- @image MOOSE.JPG
+120 -155
View File
@@ -66,7 +66,7 @@
-- you can board the cargo into the carrier `CargoCarrier`.
-- Simple, isn't it? Told you, and this is only the beginning.
--
-- The boarding, unboarding, loading, unloading of cargo is however something that is not meant to be coded manualy by mission designers.
-- The boarding, unboarding, loading, unloading of cargo is however something that is not meant to be coded manually by mission designers.
-- It would be too low-level and not end-user friendly to deal with cargo handling complexity.
-- Things can become really complex if you want to make cargo being handled and behave in multiple scenarios.
--
@@ -77,8 +77,8 @@
--
-- ## 3.1) AI Cargo handlers.
--
-- - @{AI.AI_Cargo_APC} will create for you the capatility to make an APC group handle cargo.
-- - @{AI.AI_Cargo_Helicopter} will create for you the capatility to make a Helicopter group handle cargo.
-- - @{AI.AI_Cargo_APC} will create for you the capability to make an APC group handle cargo.
-- - @{AI.AI_Cargo_Helicopter} will create for you the capability to make a Helicopter group handle cargo.
--
--
-- ## 3.2) AI Cargo transportation dispatchers.
@@ -86,7 +86,7 @@
-- There are also dispatchers that make AI work together to transport cargo automatically!!!
--
-- - @{AI.AI_Cargo_Dispatcher_APC} derived classes will create for your dynamic cargo handlers controlled by AI ground vehicle groups (APCs) to transport cargo between sites.
-- - @{AI.AI_Cargo_Dispatcher_Helicopters} derived classes will create for your dynamic cargo handlers controlled by AI helicpter groups to transport cargo between sites.
-- - @{AI.AI_Cargo_Dispatcher_Helicopters} derived classes will create for your dynamic cargo handlers controlled by AI helicopter groups to transport cargo between sites.
--
-- ## 3.3) Cargo transportation tasking.
--
@@ -94,7 +94,7 @@
--
-- - @{Tasking.Task_CARGO} derived classes will create for you cargo transportation tasks, that allow human players to interact with MOOSE cargo objects to complete tasks.
--
-- Please refer to the documentation reflected within these modules to understand the detailed capabilties.
-- Please refer to the documentation reflected within these modules to understand the detailed capabilities.
--
-- # 4) Cargo SETs.
--
@@ -206,27 +206,29 @@
-- * **NR=** Provide the maximum range in meters when the cargo units will be boarded within the carrier during boarding.
-- Note that this option is optional, so can be omitted. The default value of the RR is 10 meters.
--
-- ## 5.2) The \#CARGO tag to create CARGO_CRATE objects:
-- ## 5.2) The \#CARGO tag to create CARGO_CRATE or CARGO_SLINGLOAD objects:
--
-- You can also use the \#CARGO tag on **static** objects, including **static cargo** objects of the mission editor.
--
-- For example, the following #CARGO naming in the **static name** of the object, will create a CARGO_CRATE object when the mission starts.
--
-- `Static #CARGO(T=Workmaterials,RR=500,NR=25)`
-- `Static #CARGO(T=Workmaterials,C=CRATE,RR=500,NR=25)`
--
-- This will create a CARGO_CRATE object:
--
-- * with the group name `Static #CARGO`
-- * is of type `Workmaterials`
-- * is of category `CRATE` (as opposed to `SLING`)
-- * will report when a carrier is within 500 meters
-- * will board to carriers when the carrier is within 500 meters from the cargo object
-- * will disappear when the cargo is within 25 meters from the carrier during boarding
--
-- So the overall syntax of the #CARGO naming tag and arguments are:
--
-- `StaticName #CARGO(T=CargoTypeName,RR=Range,NR=Range)`
-- `StaticName #CARGO(T=CargoTypeName,C=Category,RR=Range,NR=Range)`
--
-- * **T=** Provide a text that contains the type name of the cargo object. This type name can be used to filter cargo within a SET_CARGO object.
-- * **C=** Provide either `CRATE` or `SLING` to have this static created as a CARGO_CRATE or CARGO_SLINGLOAD respectively.
-- * **RR=** Provide the minimal range in meters when the report to the carrier, and board to the carrier.
-- Note that this option is optional, so can be omitted. The default value of the RR is 250 meters.
-- * **NR=** Provide the maximum range in meters when the cargo units will be boarded within the carrier during boarding.
@@ -375,7 +377,7 @@ do -- CARGO
-- @field #boolean Moveable This flag defines if the cargo is moveable.
-- @field #boolean Representable This flag defines if the cargo can be represented by a DCS Unit.
-- @field #boolean Containable This flag defines if the cargo can be contained within a DCS Unit.
--- Defines the core functions that defines a cargo object within MOOSE.
--
-- A cargo is a **logical object** defined that is available for transport, and has a life status within a simulation.
@@ -428,8 +430,7 @@ do -- CARGO
--- @type CARGO.CargoObjects
-- @map < #string, Wrapper.Positionable#POSITIONABLE > The alive POSITIONABLE objects representing the the cargo.
--- CARGO Constructor. This class is an abstract class and should not be instantiated.
-- @param #CARGO self
-- @param #string Type
@@ -439,10 +440,10 @@ do -- CARGO
-- @param #number NearRadius (optional)
-- @return #CARGO
function CARGO:New( Type, Name, Weight, LoadRadius, NearRadius ) --R2.1
local self = BASE:Inherit( self, FSM:New() ) -- #CARGO
self:F( { Type, Name, Weight, LoadRadius, NearRadius } )
self:SetStartState( "UnLoaded" )
self:AddTransition( { "UnLoaded", "Boarding" }, "Board", "Boarding" )
self:AddTransition( "Boarding" , "Boarding", "Boarding" )
@@ -457,7 +458,7 @@ do -- CARGO
self:AddTransition( "*", "Destroyed", "Destroyed" )
self:AddTransition( "*", "Respawn", "UnLoaded" )
self:AddTransition( "*", "Reset", "UnLoaded" )
self.Type = Type
self.Name = Name
self.Weight = Weight or 0
@@ -469,31 +470,29 @@ do -- CARGO
self.Containable = false
self.CargoLimit = 0
self.LoadRadius = LoadRadius or 500
--self.NearRadius = NearRadius or 25
self:SetDeployed( false )
self.CargoScheduler = SCHEDULER:New()
CARGOS[self.Name] = self
return self
end
--- Find a CARGO in the _DATABASE.
-- @param #CARGO self
-- @param #string CargoName The Cargo Name.
-- @return #CARGO self
function CARGO:FindByName( CargoName )
local CargoFound = _DATABASE:FindCargo( CargoName )
return CargoFound
end
--- Get the x position of the cargo.
-- @param #CARGO self
-- @return #number
@@ -502,9 +501,9 @@ do -- CARGO
return self.CargoCarrier:GetCoordinate().x
else
return self.CargoObject:GetCoordinate().x
end
end
end
--- Get the y position of the cargo.
-- @param #CARGO self
-- @return #number
@@ -513,9 +512,9 @@ do -- CARGO
return self.CargoCarrier:GetCoordinate().z
else
return self.CargoObject:GetCoordinate().z
end
end
end
--- Get the heading of the cargo.
-- @param #CARGO self
-- @return #number
@@ -524,22 +523,21 @@ do -- CARGO
return self.CargoCarrier:GetHeading()
else
return self.CargoObject:GetHeading()
end
end
end
--- Check if the cargo can be Slingloaded.
-- @param #CARGO self
function CARGO:CanSlingload()
return false
end
--- Check if the cargo can be Boarded.
-- @param #CARGO self
function CARGO:CanBoard()
return true
end
--- Check if the cargo can be Unboarded.
-- @param #CARGO self
function CARGO:CanUnboard()
@@ -551,14 +549,13 @@ do -- CARGO
function CARGO:CanLoad()
return true
end
--- Check if the cargo can be Unloaded.
-- @param #CARGO self
function CARGO:CanUnload()
return true
end
--- Destroy the cargo.
-- @param #CARGO self
function CARGO:Destroy()
@@ -567,14 +564,14 @@ do -- CARGO
end
self:Destroyed()
end
--- Get the name of the Cargo.
-- @param #CARGO self
-- @return #string The name of the Cargo.
function CARGO:GetName() --R2.1
return self.Name
end
--- Get the current active object representing or being the Cargo.
-- @param #CARGO self
-- @return Wrapper.Positionable#POSITIONABLE The object representing or being the Cargo.
@@ -583,9 +580,9 @@ do -- CARGO
return self.CargoCarrier
else
return self.CargoObject
end
end
end
--- Get the object name of the Cargo.
-- @param #CARGO self
-- @return #string The object name of the Cargo.
@@ -594,9 +591,9 @@ do -- CARGO
return self.CargoCarrier:GetName()
else
return self.CargoObject:GetName()
end
end
end
--- Get the amount of Cargo.
-- @param #CARGO self
-- @return #number The amount of Cargo.
@@ -611,7 +608,6 @@ do -- CARGO
return self.Type
end
--- Get the transportation method of the Cargo.
-- @param #CARGO self
-- @return #string The transportation method of the Cargo.
@@ -619,7 +615,6 @@ do -- CARGO
return self.TransportationMethod
end
--- Get the coalition of the Cargo.
-- @param #CARGO self
-- @return Coalition
@@ -628,32 +623,30 @@ do -- CARGO
return self.CargoCarrier:GetCoalition()
else
return self.CargoObject:GetCoalition()
end
end
end
--- Get the current coordinates of the Cargo.
-- @param #CARGO self
-- @return Core.Point#COORDINATE The coordinates of the Cargo.
function CARGO:GetCoordinate()
return self.CargoObject:GetCoordinate()
end
--- Check if cargo is destroyed.
-- @param #CARGO self
-- @return #boolean true if destroyed
function CARGO:IsDestroyed()
return self:Is( "Destroyed" )
end
--- Check if cargo is loaded.
-- @param #CARGO self
-- @return #boolean true if loaded
function CARGO:IsLoaded()
return self:Is( "Loaded" )
end
--- Check if cargo is loaded.
-- @param #CARGO self
-- @param Wrapper.Unit#UNIT Carrier
@@ -661,14 +654,14 @@ do -- CARGO
function CARGO:IsLoadedInCarrier( Carrier )
return self.CargoCarrier and self.CargoCarrier:GetName() == Carrier:GetName()
end
--- Check if cargo is unloaded.
-- @param #CARGO self
-- @return #boolean true if unloaded
function CARGO:IsUnLoaded()
return self:Is( "UnLoaded" )
end
--- Check if cargo is boarding.
-- @param #CARGO self
-- @return #boolean true if boarding
@@ -676,52 +669,47 @@ do -- CARGO
return self:Is( "Boarding" )
end
--- Check if cargo is unboarding.
-- @param #CARGO self
-- @return #boolean true if unboarding
function CARGO:IsUnboarding()
return self:Is( "UnBoarding" )
end
--- Check if cargo is alive.
-- @param #CARGO self
-- @return #boolean true if unloaded
function CARGO:IsAlive()
if self:IsLoaded() then
return self.CargoCarrier:IsAlive()
else
return self.CargoObject:IsAlive()
end
end
end
--- Set the cargo as deployed.
-- @param #CARGO self
-- @param #boolean Deployed true if the cargo is to be deployed. false or nil otherwise.
function CARGO:SetDeployed( Deployed )
self.Deployed = Deployed
end
--- Is the cargo deployed
-- @param #CARGO self
-- @return #boolean
function CARGO:IsDeployed()
return self.Deployed
end
--- Template method to spawn a new representation of the CARGO in the simulator.
-- @param #CARGO self
-- @return #CARGO
function CARGO:Spawn( PointVec2 )
self:F()
end
--- Signal a flare at the position of the CARGO.
-- @param #CARGO self
-- @param Utilities.Utils#FLARECOLOR FlareColor
@@ -730,31 +718,31 @@ do -- CARGO
trigger.action.signalFlare( self.CargoObject:GetVec3(), FlareColor , 0 )
end
end
--- Signal a white flare at the position of the CARGO.
-- @param #CARGO self
function CARGO:FlareWhite()
self:Flare( trigger.flareColor.White )
end
--- Signal a yellow flare at the position of the CARGO.
-- @param #CARGO self
function CARGO:FlareYellow()
self:Flare( trigger.flareColor.Yellow )
end
--- Signal a green flare at the position of the CARGO.
-- @param #CARGO self
function CARGO:FlareGreen()
self:Flare( trigger.flareColor.Green )
end
--- Signal a red flare at the position of the CARGO.
-- @param #CARGO self
function CARGO:FlareRed()
self:Flare( trigger.flareColor.Red )
end
--- Smoke the CARGO.
-- @param #CARGO self
-- @param Utilities.Utils#SMOKECOLOR SmokeColor The color of the smoke.
@@ -768,38 +756,37 @@ do -- CARGO
end
end
end
--- Smoke the CARGO Green.
-- @param #CARGO self
function CARGO:SmokeGreen()
self:Smoke( trigger.smokeColor.Green, Range )
end
--- Smoke the CARGO Red.
-- @param #CARGO self
function CARGO:SmokeRed()
self:Smoke( trigger.smokeColor.Red, Range )
end
--- Smoke the CARGO White.
-- @param #CARGO self
function CARGO:SmokeWhite()
self:Smoke( trigger.smokeColor.White, Range )
end
--- Smoke the CARGO Orange.
-- @param #CARGO self
function CARGO:SmokeOrange()
self:Smoke( trigger.smokeColor.Orange, Range )
end
--- Smoke the CARGO Blue.
-- @param #CARGO self
function CARGO:SmokeBlue()
self:Smoke( trigger.smokeColor.Blue, Range )
end
--- Set the Load radius, which is the radius till when the Cargo can be loaded.
-- @param #CARGO self
-- @param #number LoadRadius The radius till Cargo can be loaded.
@@ -807,23 +794,21 @@ do -- CARGO
function CARGO:SetLoadRadius( LoadRadius )
self.LoadRadius = LoadRadius or 150
end
--- Get the Load radius, which is the radius till when the Cargo can be loaded.
-- @param #CARGO self
-- @return #number The radius till Cargo can be loaded.
function CARGO:GetLoadRadius()
return self.LoadRadius
end
--- Check if Cargo is in the LoadRadius for the Cargo to be Boarded or Loaded.
-- @param #CARGO self
-- @param Core.Point#COORDINATE Coordinate
-- @return #boolean true if the CargoGroup is within the loading radius.
function CARGO:IsInLoadRadius( Coordinate )
self:F( { Coordinate, LoadRadius = self.LoadRadius } )
local Distance = 0
if self:IsUnLoaded() then
local CargoCoordinate = self.CargoObject:GetCoordinate()
@@ -833,18 +818,17 @@ do -- CARGO
return true
end
end
return false
end
--- Check if the Cargo can report itself to be Boarded or Loaded.
-- @param #CARGO self
-- @param Core.Point#COORDINATE Coordinate
-- @return #boolean true if the Cargo can report itself.
function CARGO:IsInReportRadius( Coordinate )
self:F( { Coordinate } )
local Distance = 0
if self:IsUnLoaded() then
Distance = Coordinate:Get2DDistance( self.CargoObject:GetCoordinate() )
@@ -853,7 +837,7 @@ do -- CARGO
return true
end
end
return false
end
@@ -865,7 +849,7 @@ do -- CARGO
-- @return #boolean
function CARGO:IsNear( Coordinate, NearRadius )
--self:F( { PointVec2 = PointVec2, NearRadius = NearRadius } )
if self.CargoObject:IsAlive() then
--local Distance = PointVec2:Get2DDistance( self.CargoObject:GetPointVec2() )
--self:F( { CargoObjectName = self.CargoObject:GetName() } )
@@ -873,26 +857,24 @@ do -- CARGO
--self:F( { PointVec2 = PointVec2:GetVec2() } )
local Distance = Coordinate:Get2DDistance( self.CargoObject:GetCoordinate() )
--self:F( { Distance = Distance, NearRadius = NearRadius or "nil" } )
if Distance <= NearRadius then
--self:F( { PointVec2 = PointVec2, NearRadius = NearRadius, IsNear = true } )
return true
end
end
--self:F( { PointVec2 = PointVec2, NearRadius = NearRadius, IsNear = false } )
return false
end
--- Check if Cargo is the given @{Zone}.
--- Check if Cargo is the given @{Core.Zone}.
-- @param #CARGO self
-- @param Core.Zone#ZONE_BASE Zone
-- @return #boolean **true** if cargo is in the Zone, **false** if cargo is not in the Zone.
function CARGO:IsInZone( Zone )
--self:F( { Zone } )
if self:IsLoaded() then
return Zone:IsPointVec2InZone( self.CargoCarrier:GetPointVec2() )
else
@@ -902,34 +884,33 @@ do -- CARGO
else
return false
end
end
end
return nil
end
--- Get the current PointVec2 of the cargo.
-- @param #CARGO self
-- @return Core.Point#POINT_VEC2
function CARGO:GetPointVec2()
return self.CargoObject:GetPointVec2()
end
--- Get the current Coordinate of the cargo.
-- @param #CARGO self
-- @return Core.Point#COORDINATE
function CARGO:GetCoordinate()
return self.CargoObject:GetCoordinate()
end
--- Get the weight of the cargo.
-- @param #CARGO self
-- @return #number Weight The weight in kg.
function CARGO:GetWeight()
return self.Weight
end
--- Set the weight of the cargo.
-- @param #CARGO self
-- @param #number Weight The weight in kg.
@@ -938,14 +919,14 @@ do -- CARGO
self.Weight = Weight
return self
end
--- Get the volume of the cargo.
-- @param #CARGO self
-- @return #number Volume The volume in kg.
function CARGO:GetVolume()
return self.Volume
end
--- Set the volume of the cargo.
-- @param #CARGO self
-- @param #number Volume The volume in kg.
@@ -954,18 +935,18 @@ do -- CARGO
self.Volume = Volume
return self
end
--- Send a CC message to a @{Wrapper.Group}.
-- @param #CARGO self
-- @param #string Message
-- @param Wrapper.Group#GROUP CarrierGroup The Carrier Group.
-- @param #string Name (optional) The name of the Group used as a prefix for the message to the Group. If not provided, there will be nothing shown.
function CARGO:MessageToGroup( Message, CarrierGroup, Name )
MESSAGE:New( Message, 20, "Cargo " .. self:GetName() ):ToGroup( CarrierGroup )
end
--- Report to a Carrier Group.
-- @param #CARGO self
-- @param #string Action The string describing the action for the cargo.
@@ -991,8 +972,7 @@ do -- CARGO
end
end
end
--- Report to a Carrier Group with a Flaring signal.
-- @param #CARGO self
-- @param Utils#UTILS.FlareColor FlareColor the color of the flare.
@@ -1001,8 +981,7 @@ do -- CARGO
self.ReportFlareColor = FlareColor
end
--- Report to a Carrier Group with a Smoking signal.
-- @param #CARGO self
-- @param Utils#UTILS.SmokeColor SmokeColor the color of the smoke.
@@ -1011,8 +990,7 @@ do -- CARGO
self.ReportSmokeColor = SmokeColor
end
--- Reset the reporting for a Carrier Group.
-- @param #CARGO self
-- @param #string Action The string describing the action for the cargo.
@@ -1022,7 +1000,7 @@ do -- CARGO
self.Reported[CarrierGroup][Action] = nil
end
--- Reset all the reporting for a Carrier Group.
-- @param #CARGO self
-- @param Wrapper.Group#GROUP CarrierGroup The Carrier Group to send the report to.
@@ -1031,7 +1009,7 @@ do -- CARGO
self.Reported[CarrierGroup] = nil
end
--- Respawn the cargo when destroyed
-- @param #CARGO self
-- @param #boolean RespawnDestroyed
@@ -1044,11 +1022,8 @@ do -- CARGO
else
self.onenterDestroyed = nil
end
end
end
end -- CARGO
@@ -1073,7 +1048,7 @@ do -- CARGO_REPRESENTABLE
-- @param #number NearRadius (optional) Radius in meters when the cargo is loaded into the carrier.
-- @return #CARGO_REPRESENTABLE
function CARGO_REPRESENTABLE:New( CargoObject, Type, Name, LoadRadius, NearRadius )
-- Inherit CARGO.
local self = BASE:Inherit( self, CARGO:New( Type, Name, 0, LoadRadius, NearRadius ) ) -- #CARGO_REPRESENTABLE
self:F( { Type, Name, LoadRadius, NearRadius } )
@@ -1081,10 +1056,10 @@ do -- CARGO_REPRESENTABLE
-- Descriptors.
local Desc=CargoObject:GetDesc()
self:T({Desc=Desc})
-- Weight.
local Weight = math.random( 80, 120 )
-- Adjust weight..
if Desc then
if Desc.typeName == "2B11 mortar" then
@@ -1095,8 +1070,8 @@ do -- CARGO_REPRESENTABLE
end
-- Set weight.
self:SetWeight( Weight )
self:SetWeight( Weight )
return self
end
@@ -1104,14 +1079,14 @@ do -- CARGO_REPRESENTABLE
-- @param #CARGO_REPRESENTABLE self
-- @return #CARGO_REPRESENTABLE
function CARGO_REPRESENTABLE:Destroy()
-- Cargo objects are deleted from the _DATABASE and SET_CARGO objects.
self:F( { CargoName = self:GetName() } )
--_EVENTDISPATCHER:CreateEventDeleteCargo( self )
return self
end
--- Route a cargo unit to a PointVec2.
-- @param #CARGO_REPRESENTABLE self
-- @param Core.Point#POINT_VEC2 ToPointVec2
@@ -1119,19 +1094,19 @@ do -- CARGO_REPRESENTABLE
-- @return #CARGO_REPRESENTABLE
function CARGO_REPRESENTABLE:RouteTo( ToPointVec2, Speed )
self:F2( ToPointVec2 )
local Points = {}
local PointStartVec2 = self.CargoObject:GetPointVec2()
Points[#Points+1] = PointStartVec2:WaypointGround( Speed )
Points[#Points+1] = ToPointVec2:WaypointGround( Speed )
local TaskRoute = self.CargoObject:TaskRoute( Points )
self.CargoObject:SetTask( TaskRoute, 2 )
return self
return self
end
--- Send a message to a @{Wrapper.Group} through a communication channel near the cargo.
-- @param #CARGO_REPRESENTABLE self
-- @param #string Message
@@ -1155,20 +1130,19 @@ do -- CARGO_REPRESENTABLE
end
end
end
end
end -- CARGO_REPRESENTABLE
do -- CARGO_REPORTABLE
--- @type CARGO_REPORTABLE
-- @extends #CARGO
CARGO_REPORTABLE = {
ClassName = "CARGO_REPORTABLE"
}
--- CARGO_REPORTABLE Constructor.
-- @param #CARGO_REPORTABLE self
-- @param #string Type
@@ -1180,31 +1154,23 @@ do -- CARGO_REPORTABLE
function CARGO_REPORTABLE:New( Type, Name, Weight, LoadRadius, NearRadius )
local self = BASE:Inherit( self, CARGO:New( Type, Name, Weight, LoadRadius, NearRadius ) ) -- #CARGO_REPORTABLE
self:F( { Type, Name, Weight, LoadRadius, NearRadius } )
return self
end
--- Send a CC message to a @{Wrapper.Group}.
-- @param #CARGO_REPORTABLE self
-- @param #string Message
-- @param Wrapper.Group#GROUP TaskGroup
-- @param #string Name (optional) The name of the Group used as a prefix for the message to the Group. If not provided, there will be nothing shown.
function CARGO_REPORTABLE:MessageToGroup( Message, TaskGroup, Name )
MESSAGE:New( Message, 20, "Cargo " .. self:GetName() .. " reporting" ):ToGroup( TaskGroup )
end
end
do -- CARGO_PACKAGE
--- @type CARGO_PACKAGE
@@ -1278,10 +1244,10 @@ function CARGO_PACKAGE:IsNear( CargoCarrier )
self:F()
local CargoCarrierPoint = CargoCarrier:GetCoordinate()
local Distance = CargoCarrierPoint:Get2DDistance( self.CargoCarrier:GetCoordinate() )
self:T( Distance )
if Distance <= self.NearRadius then
return true
else
@@ -1332,7 +1298,7 @@ function CARGO_PACKAGE:onafterUnBoard( From, Event, To, CargoCarrier, Speed, UnL
if not self.CargoInAir then
self:_Next( self.FsmP.UnLoad, UnLoadDistance, Angle )
local Points = {}
local StartPointVec2 = CargoCarrier:GetPointVec2()
@@ -1387,7 +1353,7 @@ function CARGO_PACKAGE:onafterLoad( From, Event, To, CargoCarrier, Speed, LoadDi
local CargoCarrierHeading = self.CargoCarrier:GetHeading() -- Get Heading of object in degrees.
local CargoDeployHeading = ( ( CargoCarrierHeading + Angle ) >= 360 ) and ( CargoCarrierHeading + Angle - 360 ) or ( CargoCarrierHeading + Angle )
local CargoDeployPointVec2 = StartPointVec2:Translate( LoadDistance, CargoDeployHeading )
local Points = {}
Points[#Points+1] = StartPointVec2:WaypointGround( Speed )
Points[#Points+1] = CargoDeployPointVec2:WaypointGround( Speed )
@@ -1408,12 +1374,12 @@ end
-- @param #number Angle
function CARGO_PACKAGE:onafterUnLoad( From, Event, To, CargoCarrier, Speed, Distance, Angle )
self:F()
local StartPointVec2 = self.CargoCarrier:GetPointVec2()
local CargoCarrierHeading = self.CargoCarrier:GetHeading() -- Get Heading of object in degrees.
local CargoDeployHeading = ( ( CargoCarrierHeading + Angle ) >= 360 ) and ( CargoCarrierHeading + Angle - 360 ) or ( CargoCarrierHeading + Angle )
local CargoDeployPointVec2 = StartPointVec2:Translate( Distance, CargoDeployHeading )
self.CargoCarrier = CargoCarrier
local Points = {}
@@ -1425,5 +1391,4 @@ function CARGO_PACKAGE:onafterUnLoad( From, Event, To, CargoCarrier, Speed, Dist
end
end
+1 -1
View File
@@ -1,4 +1,4 @@
--- **Cargo** -- Management of single cargo crates, which are based on a @{Static} object.
--- **Cargo** - Management of single cargo crates, which are based on a STATIC object.
--
-- ===
--
+3 -3
View File
@@ -1,4 +1,4 @@
--- **Cargo** - Management of grouped cargo logistics, which are based on a @{Wrapper.Group} object.
--- **Cargo** - Management of grouped cargo logistics, which are based on a GROUP object.
--
-- ===
--
@@ -47,7 +47,7 @@ do -- CARGO_GROUP
--- CARGO_GROUP constructor.
-- This make a new CARGO_GROUP from a @{Wrapper.Group} object.
-- It will "ungroup" the group object within the sim, and will create a @{Set} of individual Unit objects.
-- It will "ungroup" the group object within the sim, and will create a @{Core.Set} of individual Unit objects.
-- @param #CARGO_GROUP self
-- @param Wrapper.Group#GROUP CargoGroup Group to be transported as cargo.
-- @param #string Type Cargo type, e.g. "Infantry". This is the type used in SET_CARGO:New():FilterTypes("Infantry") to define the valid cargo groups of the set.
@@ -727,7 +727,7 @@ do -- CARGO_GROUP
end
end
--- Check if the first element of the CargoGroup is the given @{Zone}.
--- Check if the first element of the CargoGroup is the given @{Core.Zone}.
-- @param #CARGO_GROUP self
-- @param Core.Zone#ZONE_BASE Zone
-- @return #boolean **true** if the first element of the CargoGroup is in the Zone
@@ -1,4 +1,4 @@
--- **Cargo** -- Management of single cargo crates, which are based on a @{Static} object. The cargo can only be slingloaded.
--- **Cargo** - Management of single cargo crates, which are based on a STATIC object. The cargo can only be slingloaded.
--
-- ===
--
+1 -1
View File
@@ -1,4 +1,4 @@
--- **Cargo** - Management of single cargo logistics, which are based on a @{Wrapper.Unit} object.
--- **Cargo** - Management of single cargo logistics, which are based on a UNIT object.
--
-- ===
--
+943
View File
@@ -0,0 +1,943 @@
--- **Core** - A* Pathfinding.
--
-- **Main Features:**
--
-- * Find path from A to B.
-- * Pre-defined as well as custom valid neighbour functions.
-- * Pre-defined as well as custom cost functions.
-- * Easy rectangular grid setup.
--
-- ===
--
-- ### Author: **funkyfranky**
--
-- ===
-- @module Core.Astar
-- @image CORE_Astar.png
--- ASTAR class.
-- @type ASTAR
-- @field #string ClassName Name of the class.
-- @field #boolean Debug Debug mode. Messages to all about status.
-- @field #string lid Class id string for output to DCS log file.
-- @field #table nodes Table of nodes.
-- @field #number counter Node counter.
-- @field #number Nnodes Number of nodes.
-- @field #number nvalid Number of nvalid calls.
-- @field #number nvalidcache Number of cached valid evals.
-- @field #number ncost Number of cost evaluations.
-- @field #number ncostcache Number of cached cost evals.
-- @field #ASTAR.Node startNode Start node.
-- @field #ASTAR.Node endNode End node.
-- @field Core.Point#COORDINATE startCoord Start coordinate.
-- @field Core.Point#COORDINATE endCoord End coordinate.
-- @field #function ValidNeighbourFunc Function to check if a node is valid.
-- @field #table ValidNeighbourArg Optional arguments passed to the valid neighbour function.
-- @field #function CostFunc Function to calculate the heuristic "cost" to go from one node to another.
-- @field #table CostArg Optional arguments passed to the cost function.
-- @extends Core.Base#BASE
--- *When nothing goes right... Go left!*
--
-- ===
--
-- # The ASTAR Concept
--
-- Pathfinding algorithm.
--
--
-- # Start and Goal
--
-- The first thing we need to define is obviously the place where we want to start and where we want to go eventually.
--
-- ## Start
--
-- The start
--
-- ## Goal
--
--
-- # Nodes
--
-- ## Rectangular Grid
--
-- A rectangular grid can be created using the @{#ASTAR.CreateGrid}(*ValidSurfaceTypes, BoxHY, SpaceX, deltaX, deltaY, MarkGrid*), where
--
-- * *ValidSurfaceTypes* is a table of valid surface types. By default all surface types are valid.
-- * *BoxXY* is the width of the grid perpendicular the the line between start and end node. Default is 40,000 meters (40 km).
-- * *SpaceX* is the additional space behind the start and end nodes. Default is 20,000 meters (20 km).
-- * *deltaX* is the grid spacing between nodes in the direction of start and end node. Default is 2,000 meters (2 km).
-- * *deltaY* is the grid spacing perpendicular to the direction of start and end node. Default is the same as *deltaX*.
-- * *MarkGrid* If set to *true*, this places marker on the F10 map on each grid node. Note that this can stall DCS if too many nodes are created.
--
-- ## Valid Surfaces
--
-- Certain unit types can only travel on certain surfaces types, for example
--
-- * Naval units can only travel on water (that also excludes shallow water in DCS currently),
-- * Ground units can only traval on land.
--
-- By restricting the surface type in the grid construction, we also reduce the number of nodes, which makes the algorithm more efficient.
--
-- ## Box Width (BoxHY)
--
-- The box width needs to be large enough to capture all paths you want to consider.
--
-- ## Space in X
--
-- The space in X value is important if the algorithm needs to to backwards from the start node or needs to extend even further than the end node.
--
-- ## Grid Spacing
--
-- The grid spacing is an important factor as it determines the number of nodes and hence the performance of the algorithm. It should be as large as possible.
-- However, if the value is too large, the algorithm might fail to get a valid path.
--
-- A good estimate of the grid spacing is to set it to be smaller (~ half the size) of the smallest gap you need to path.
--
-- # Valid Neighbours
--
-- The A* algorithm needs to know if a transition from one node to another is allowed or not. By default, hopping from one node to another is always possible.
--
-- ## Line of Sight
--
-- For naval
--
--
-- # Heuristic Cost
--
-- In order to determine the optimal path, the pathfinding algorithm needs to know, how costly it is to go from one node to another.
-- Often, this can simply be determined by the distance between two nodes. Therefore, the default cost function is set to be the 2D distance between two nodes.
--
--
-- # Calculate the Path
--
-- Finally, we have to calculate the path. This is done by the @{ASTAR.GetPath}(*ExcludeStart, ExcludeEnd*) function. This function returns a table of nodes, which
-- describe the optimal path from the start node to the end node.
--
-- By default, the start and end node are include in the table that is returned.
--
-- Note that a valid path must not always exist. So you should check if the function returns *nil*.
--
-- Common reasons that a path cannot be found are:
--
-- * The grid is too small ==> increase grid size, e.g. *BoxHY* and/or *SpaceX* if you use a rectangular grid.
-- * The grid spacing is too large ==> decrease *deltaX* and/or *deltaY*
-- * There simply is no valid path ==> you are screwed :(
--
--
-- # Examples
--
-- ## Strait of Hormuz
--
-- Carrier Group finds its way through the Stait of Hormuz.
--
-- ##
--
--
--
-- @field #ASTAR
ASTAR = {
ClassName = "ASTAR",
Debug = nil,
lid = nil,
nodes = {},
counter = 1,
Nnodes = 0,
ncost = 0,
ncostcache = 0,
nvalid = 0,
nvalidcache = 0,
}
--- Node data.
-- @type ASTAR.Node
-- @field #number id Node id.
-- @field Core.Point#COORDINATE coordinate Coordinate of the node.
-- @field #number surfacetype Surface type.
-- @field #table valid Cached valid/invalid nodes.
-- @field #table cost Cached cost.
--- ASTAR infinity.
-- @field #number INF
ASTAR.INF=1/0
--- ASTAR class version.
-- @field #string version
ASTAR.version="0.4.0"
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO list
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO: Add more valid neighbour functions.
-- TODO: Write docs.
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Constructor
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- Create a new ASTAR object.
-- @param #ASTAR self
-- @return #ASTAR self
function ASTAR:New()
-- Inherit everything from INTEL class.
local self=BASE:Inherit(self, BASE:New()) --#ASTAR
self.lid="ASTAR | "
return self
end
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- User functions
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- Set coordinate from where to start.
-- @param #ASTAR self
-- @param Core.Point#COORDINATE Coordinate Start coordinate.
-- @return #ASTAR self
function ASTAR:SetStartCoordinate(Coordinate)
self.startCoord=Coordinate
return self
end
--- Set coordinate where you want to go.
-- @param #ASTAR self
-- @param Core.Point#COORDINATE Coordinate end coordinate.
-- @return #ASTAR self
function ASTAR:SetEndCoordinate(Coordinate)
self.endCoord=Coordinate
return self
end
--- Create a node from a given coordinate.
-- @param #ASTAR self
-- @param Core.Point#COORDINATE Coordinate The coordinate where to create the node.
-- @return #ASTAR.Node The node.
function ASTAR:GetNodeFromCoordinate(Coordinate)
local node={} --#ASTAR.Node
node.coordinate=Coordinate
node.surfacetype=Coordinate:GetSurfaceType()
node.id=self.counter
node.valid={}
node.cost={}
self.counter=self.counter+1
return node
end
--- Add a node to the table of grid nodes.
-- @param #ASTAR self
-- @param #ASTAR.Node Node The node to be added.
-- @return #ASTAR self
function ASTAR:AddNode(Node)
self.nodes[Node.id]=Node
self.Nnodes=self.Nnodes+1
return self
end
--- Add a node to the table of grid nodes specifying its coordinate.
-- @param #ASTAR self
-- @param Core.Point#COORDINATE Coordinate The coordinate where the node is created.
-- @return #ASTAR.Node The node.
function ASTAR:AddNodeFromCoordinate(Coordinate)
local node=self:GetNodeFromCoordinate(Coordinate)
self:AddNode(node)
return node
end
--- Check if the coordinate of a node has is at a valid surface type.
-- @param #ASTAR self
-- @param #ASTAR.Node Node The node to be added.
-- @param #table SurfaceTypes Surface types, for example `{land.SurfaceType.WATER}`. By default all surface types are valid.
-- @return #boolean If true, surface type of node is valid.
function ASTAR:CheckValidSurfaceType(Node, SurfaceTypes)
if SurfaceTypes then
if type(SurfaceTypes)~="table" then
SurfaceTypes={SurfaceTypes}
end
for _,surface in pairs(SurfaceTypes) do
if surface==Node.surfacetype then
return true
end
end
return false
else
return true
end
end
--- Add a function to determine if a neighbour of a node is valid.
-- @param #ASTAR self
-- @param #function NeighbourFunction Function that needs to return *true* for a neighbour to be valid.
-- @param ... Condition function arguments if any.
-- @return #ASTAR self
function ASTAR:SetValidNeighbourFunction(NeighbourFunction, ...)
self.ValidNeighbourFunc=NeighbourFunction
self.ValidNeighbourArg={}
if arg then
self.ValidNeighbourArg=arg
end
return self
end
--- Set valid neighbours to require line of sight between two nodes.
-- @param #ASTAR self
-- @param #number CorridorWidth Width of LoS corridor in meters.
-- @return #ASTAR self
function ASTAR:SetValidNeighbourLoS(CorridorWidth)
self:SetValidNeighbourFunction(ASTAR.LoS, CorridorWidth)
return self
end
--- Set valid neighbours to be in a certain distance.
-- @param #ASTAR self
-- @param #number MaxDistance Max distance between nodes in meters. Default is 2000 m.
-- @return #ASTAR self
function ASTAR:SetValidNeighbourDistance(MaxDistance)
self:SetValidNeighbourFunction(ASTAR.DistMax, MaxDistance)
return self
end
--- Set valid neighbours to be in a certain distance.
-- @param #ASTAR self
-- @param #number MaxDistance Max distance between nodes in meters. Default is 2000 m.
-- @return #ASTAR self
function ASTAR:SetValidNeighbourRoad(MaxDistance)
self:SetValidNeighbourFunction(ASTAR.Road, MaxDistance)
return self
end
--- Set the function which calculates the "cost" to go from one to another node.
-- The first to arguments of this function are always the two nodes under consideration. But you can add optional arguments.
-- Very often the distance between nodes is a good measure for the cost.
-- @param #ASTAR self
-- @param #function CostFunction Function that returns the "cost".
-- @param ... Condition function arguments if any.
-- @return #ASTAR self
function ASTAR:SetCostFunction(CostFunction, ...)
self.CostFunc=CostFunction
self.CostArg={}
if arg then
self.CostArg=arg
end
return self
end
--- Set heuristic cost to go from one node to another to be their 2D distance.
-- @param #ASTAR self
-- @return #ASTAR self
function ASTAR:SetCostDist2D()
self:SetCostFunction(ASTAR.Dist2D)
return self
end
--- Set heuristic cost to go from one node to another to be their 3D distance.
-- @param #ASTAR self
-- @return #ASTAR self
function ASTAR:SetCostDist3D()
self:SetCostFunction(ASTAR.Dist3D)
return self
end
--- Set heuristic cost to go from one node to another to be their 3D distance.
-- @param #ASTAR self
-- @return #ASTAR self
function ASTAR:SetCostRoad()
self:SetCostFunction(ASTAR)
return self
end
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Grid functions
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- Create a rectangular grid of nodes between star and end coordinate.
-- The coordinate system is oriented along the line between start and end point.
-- @param #ASTAR self
-- @param #table ValidSurfaceTypes Valid surface types. By default is all surfaces are allowed.
-- @param #number BoxHY Box "height" in meters along the y-coordinate. Default 40000 meters (40 km).
-- @param #number SpaceX Additional space in meters before start and after end coordinate. Default 10000 meters (10 km).
-- @param #number deltaX Increment in the direction of start to end coordinate in meters. Default 2000 meters.
-- @param #number deltaY Increment perpendicular to the direction of start to end coordinate in meters. Default is same as deltaX.
-- @param #boolean MarkGrid If true, create F10 map markers at grid nodes.
-- @return #ASTAR self
function ASTAR:CreateGrid(ValidSurfaceTypes, BoxHY, SpaceX, deltaX, deltaY, MarkGrid)
-- Note that internally
-- x coordinate is z: x-->z Line from start to end
-- y coordinate is x: y-->x Perpendicular
-- Grid length and width.
local Dz=SpaceX or 10000
local Dx=BoxHY and BoxHY/2 or 20000
-- Increments.
local dz=deltaX or 2000
local dx=deltaY or dz
-- Heading from start to end coordinate.
local angle=self.startCoord:HeadingTo(self.endCoord)
--Distance between start and end.
local dist=self.startCoord:Get2DDistance(self.endCoord)+2*Dz
-- Origin of map. Needed to translate back to wanted position.
local co=COORDINATE:New(0, 0, 0)
local do1=co:Get2DDistance(self.startCoord)
local ho1=co:HeadingTo(self.startCoord)
-- Start of grid.
local xmin=-Dx
local zmin=-Dz
-- Number of grid points.
local nz=dist/dz+1
local nx=2*Dx/dx+1
-- Debug info.
local text=string.format("Building grid with nx=%d ny=%d => total=%d nodes", nx, nz, nx*nz)
self:T(self.lid..text)
-- Loop over x and z coordinate to create a 2D grid.
for i=1,nx do
-- x coordinate perpendicular to z.
local x=xmin+dx*(i-1)
for j=1,nz do
-- z coordinate connecting start and end.
local z=zmin+dz*(j-1)
-- Rotate 2D.
local vec3=UTILS.Rotate2D({x=x, y=0, z=z}, angle)
-- Coordinate of the node.
local c=COORDINATE:New(vec3.z, vec3.y, vec3.x):Translate(do1, ho1, true)
-- Create a node at this coordinate.
local node=self:GetNodeFromCoordinate(c)
-- Check if node has valid surface type.
if self:CheckValidSurfaceType(node, ValidSurfaceTypes) then
if MarkGrid then
c:MarkToAll(string.format("i=%d, j=%d surface=%d", i, j, node.surfacetype))
end
-- Add node to grid.
self:AddNode(node)
end
end
end
-- Debug info.
local text=string.format("Done building grid!")
self:T2(self.lid..text)
return self
end
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Valid neighbour functions
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- Function to check if two nodes have line of sight (LoS).
-- @param #ASTAR.Node nodeA First node.
-- @param #ASTAR.Node nodeB Other node.
-- @param #number corridor (Optional) Width of corridor in meters.
-- @return #boolean If true, two nodes have LoS.
function ASTAR.LoS(nodeA, nodeB, corridor)
local offset=1
local dx=corridor and corridor/2 or nil
local dy=dx
local cA=nodeA.coordinate:GetVec3()
local cB=nodeB.coordinate:GetVec3()
cA.y=offset
cB.y=offset
local los=land.isVisible(cA, cB)
if los and corridor then
-- Heading from A to B.
local heading=nodeA.coordinate:HeadingTo(nodeB.coordinate)
local Ap=UTILS.VecTranslate(cA, dx, heading+90)
local Bp=UTILS.VecTranslate(cB, dx, heading+90)
los=land.isVisible(Ap, Bp)
if los then
local Am=UTILS.VecTranslate(cA, dx, heading-90)
local Bm=UTILS.VecTranslate(cB, dx, heading-90)
los=land.isVisible(Am, Bm)
end
end
return los
end
--- Function to check if two nodes have a road connection.
-- @param #ASTAR.Node nodeA First node.
-- @param #ASTAR.Node nodeB Other node.
-- @return #boolean If true, two nodes are connected via a road.
function ASTAR.Road(nodeA, nodeB)
local path=land.findPathOnRoads("roads", nodeA.coordinate.x, nodeA.coordinate.z, nodeB.coordinate.x, nodeB.coordinate.z)
if path then
return true
else
return false
end
end
--- Function to check if distance between two nodes is less than a threshold distance.
-- @param #ASTAR.Node nodeA First node.
-- @param #ASTAR.Node nodeB Other node.
-- @param #number distmax Max distance in meters. Default is 2000 m.
-- @return #boolean If true, distance between the two nodes is below threshold.
function ASTAR.DistMax(nodeA, nodeB, distmax)
distmax=distmax or 2000
local dist=nodeA.coordinate:Get2DDistance(nodeB.coordinate)
return dist<=distmax
end
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Heuristic cost functions
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- Heuristic cost is given by the 2D distance between the nodes.
-- @param #ASTAR.Node nodeA First node.
-- @param #ASTAR.Node nodeB Other node.
-- @return #number Distance between the two nodes.
function ASTAR.Dist2D(nodeA, nodeB)
local dist=nodeA.coordinate:Get2DDistance(nodeB)
return dist
end
--- Heuristic cost is given by the 3D distance between the nodes.
-- @param #ASTAR.Node nodeA First node.
-- @param #ASTAR.Node nodeB Other node.
-- @return #number Distance between the two nodes.
function ASTAR.Dist3D(nodeA, nodeB)
local dist=nodeA.coordinate:Get3DDistance(nodeB.coordinate)
return dist
end
--- Heuristic cost is given by the distance between the nodes on road.
-- @param #ASTAR.Node nodeA First node.
-- @param #ASTAR.Node nodeB Other node.
-- @return #number Distance between the two nodes.
function ASTAR.DistRoad(nodeA, nodeB)
-- Get the path.
local path=land.findPathOnRoads("roads", nodeA.coordinate.x, nodeA.coordinate.z, nodeB.coordinate.x, nodeB.coordinate.z)
if path then
local dist=0
for i=2,#path do
local b=path[i] --DCS#Vec2
local a=path[i-1] --DCS#Vec2
dist=dist+UTILS.VecDist2D(a,b)
end
return dist
end
return math.huge
end
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Misc functions
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- Find the closest node from a given coordinate.
-- @param #ASTAR self
-- @param Core.Point#COORDINATE Coordinate.
-- @return #ASTAR.Node Cloest node to the coordinate.
-- @return #number Distance to closest node in meters.
function ASTAR:FindClosestNode(Coordinate)
local distMin=math.huge
local closeNode=nil
for _,_node in pairs(self.nodes) do
local node=_node --#ASTAR.Node
local dist=node.coordinate:Get2DDistance(Coordinate)
if dist<distMin then
distMin=dist
closeNode=node
end
end
return closeNode, distMin
end
--- Find the start node.
-- @param #ASTAR self
-- @param #ASTAR.Node Node The node to be added to the nodes table.
-- @return #ASTAR self
function ASTAR:FindStartNode()
local node, dist=self:FindClosestNode(self.startCoord)
self.startNode=node
if dist>1000 then
self:T(self.lid.."Adding start node to node grid!")
self:AddNode(node)
end
return self
end
--- Add a node.
-- @param #ASTAR self
-- @param #ASTAR.Node Node The node to be added to the nodes table.
-- @return #ASTAR self
function ASTAR:FindEndNode()
local node, dist=self:FindClosestNode(self.endCoord)
self.endNode=node
if dist>1000 then
self:T(self.lid.."Adding end node to node grid!")
self:AddNode(node)
end
return self
end
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Main A* pathfinding function
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- A* pathfinding function. This seaches the path along nodes between start and end nodes/coordinates.
-- @param #ASTAR self
-- @param #boolean ExcludeStartNode If *true*, do not include start node in found path. Default is to include it.
-- @param #boolean ExcludeEndNode If *true*, do not include end node in found path. Default is to include it.
-- @return #table Table of nodes from start to finish.
function ASTAR:GetPath(ExcludeStartNode, ExcludeEndNode)
self:FindStartNode()
self:FindEndNode()
local nodes=self.nodes
local start=self.startNode
local goal=self.endNode
-- Sets.
local openset = {}
local closedset = {}
local came_from = {}
local g_score = {}
local f_score = {}
openset[start.id]=true
local Nopen=1
-- Initial scores.
g_score[start.id]=0
f_score[start.id]=g_score[start.id]+self:_HeuristicCost(start, goal)
-- Set start time.
local T0=timer.getAbsTime()
-- Debug message.
local text=string.format("Starting A* pathfinding with %d Nodes", self.Nnodes)
self:T(self.lid..text)
local Tstart=UTILS.GetOSTime()
-- Loop while we still have an open set.
while Nopen > 0 do
-- Get current node.
local current=self:_LowestFscore(openset, f_score)
-- Check if we are at the end node.
if current.id==goal.id then
local path=self:_UnwindPath({}, came_from, goal)
if not ExcludeEndNode then
table.insert(path, goal)
end
if ExcludeStartNode then
table.remove(path, 1)
end
local Tstop=UTILS.GetOSTime()
local dT=nil
if Tstart and Tstop then
dT=Tstop-Tstart
end
-- Debug message.
local text=string.format("Found path with %d nodes (%d total)", #path, self.Nnodes)
if dT then
text=text..string.format(", OS Time %.6f sec", dT)
end
text=text..string.format(", Nvalid=%d [%d cached]", self.nvalid, self.nvalidcache)
text=text..string.format(", Ncost=%d [%d cached]", self.ncost, self.ncostcache)
self:T(self.lid..text)
return path
end
-- Move Node from open to closed set.
openset[current.id]=nil
Nopen=Nopen-1
closedset[current.id]=true
-- Get neighbour nodes.
local neighbors=self:_NeighbourNodes(current, nodes)
-- Loop over neighbours.
for _,neighbor in pairs(neighbors) do
if self:_NotIn(closedset, neighbor.id) then
local tentative_g_score=g_score[current.id]+self:_DistNodes(current, neighbor)
if self:_NotIn(openset, neighbor.id) or tentative_g_score < g_score[neighbor.id] then
came_from[neighbor]=current
g_score[neighbor.id]=tentative_g_score
f_score[neighbor.id]=g_score[neighbor.id]+self:_HeuristicCost(neighbor, goal)
if self:_NotIn(openset, neighbor.id) then
-- Add to open set.
openset[neighbor.id]=true
Nopen=Nopen+1
end
end
end
end
end
-- Debug message.
local text=string.format("WARNING: Could NOT find valid path!")
self:E(self.lid..text)
MESSAGE:New(text, 60, "ASTAR"):ToAllIf(self.Debug)
return nil -- no valid path
end
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- A* pathfinding helper functions
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- Heuristic "cost" function to go from node A to node B. Default is the distance between the nodes.
-- @param #ASTAR self
-- @param #ASTAR.Node nodeA Node A.
-- @param #ASTAR.Node nodeB Node B.
-- @return #number "Cost" to go from node A to node B.
function ASTAR:_HeuristicCost(nodeA, nodeB)
-- Counter.
self.ncost=self.ncost+1
-- Get chached cost if available.
local cost=nodeA.cost[nodeB.id]
if cost~=nil then
self.ncostcache=self.ncostcache+1
return cost
end
local cost=nil
if self.CostFunc then
cost=self.CostFunc(nodeA, nodeB, unpack(self.CostArg))
else
cost=self:_DistNodes(nodeA, nodeB)
end
nodeA.cost[nodeB.id]=cost
nodeB.cost[nodeA.id]=cost -- Symmetric problem.
return cost
end
--- Check if going from a node to a neighbour is possible.
-- @param #ASTAR self
-- @param #ASTAR.Node node A node.
-- @param #ASTAR.Node neighbor Neighbour node.
-- @return #boolean If true, transition between nodes is possible.
function ASTAR:_IsValidNeighbour(node, neighbor)
-- Counter.
self.nvalid=self.nvalid+1
local valid=node.valid[neighbor.id]
if valid~=nil then
--env.info(string.format("Node %d has valid=%s neighbour %d", node.id, tostring(valid), neighbor.id))
self.nvalidcache=self.nvalidcache+1
return valid
end
local valid=nil
if self.ValidNeighbourFunc then
valid=self.ValidNeighbourFunc(node, neighbor, unpack(self.ValidNeighbourArg))
else
valid=true
end
node.valid[neighbor.id]=valid
neighbor.valid[node.id]=valid -- Symmetric problem.
return valid
end
--- Calculate 2D distance between two nodes.
-- @param #ASTAR self
-- @param #ASTAR.Node nodeA Node A.
-- @param #ASTAR.Node nodeB Node B.
-- @return #number Distance between nodes in meters.
function ASTAR:_DistNodes(nodeA, nodeB)
return nodeA.coordinate:Get2DDistance(nodeB.coordinate)
end
--- Function that calculates the lowest F score.
-- @param #ASTAR self
-- @param #table set The set of nodes IDs.
-- @param #number f_score F score.
-- @return #ASTAR.Node Best node.
function ASTAR:_LowestFscore(set, f_score)
local lowest, bestNode = ASTAR.INF, nil
for nid,node in pairs(set) do
local score=f_score[nid]
if score<lowest then
lowest, bestNode = score, nid
end
end
return self.nodes[bestNode]
end
--- Function to get valid neighbours of a node.
-- @param #ASTAR self
-- @param #ASTAR.Node theNode The node.
-- @param #table nodes Possible neighbours.
-- @param #table Valid neighbour nodes.
function ASTAR:_NeighbourNodes(theNode, nodes)
local neighbors = {}
for _,node in pairs(nodes) do
if theNode.id~=node.id then
local isvalid=self:_IsValidNeighbour(theNode, node)
if isvalid then
table.insert(neighbors, node)
end
end
end
return neighbors
end
--- Function to check if a node is not in a set.
-- @param #ASTAR self
-- @param #table set Set of nodes.
-- @param #ASTAR.Node theNode The node to check.
-- @return #boolean If true, the node is not in the set.
function ASTAR:_NotIn(set, theNode)
return set[theNode]==nil
end
--- Unwind path function.
-- @param #ASTAR self
-- @param #table flat_path Flat path.
-- @param #table map Map.
-- @param #ASTAR.Node current_node The current node.
-- @return #table Unwinded path.
function ASTAR:_UnwindPath( flat_path, map, current_node )
if map [current_node] then
table.insert (flat_path, 1, map[current_node])
return self:_UnwindPath(flat_path, map, map[current_node])
else
return flat_path
end
end
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+169 -108
View File
@@ -157,7 +157,7 @@ local _ClassID = 0
-- self:SmokeBlue()
-- end
--
-- See the @{Event} module for more information about event handling.
-- See the @{Core.Event} module for more information about event handling.
--
-- # 4. Class identification methods.
--
@@ -229,7 +229,8 @@ FORMATION = {
-- @param #BASE self
-- @return #BASE
function BASE:New()
local self = routines.utils.deepCopy( self ) -- Create a new self instance
--local self = routines.utils.deepCopy( self ) -- Create a new self instance
local self = UTILS.DeepCopy(self)
_ClassID = _ClassID + 1
self.ClassID = _ClassID
@@ -411,20 +412,20 @@ do -- Event Handling
return _EVENTDISPATCHER
end
--- Get the Class @{Event} processing Priority.
--- Get the Class @{Core.Event} processing Priority.
-- The Event processing Priority is a number from 1 to 10,
-- reflecting the order of the classes subscribed to the Event to be processed.
-- @param #BASE self
-- @return #number The @{Event} processing Priority.
-- @return #number The @{Core.Event} processing Priority.
function BASE:GetEventPriority()
return self._.EventPriority or 5
end
--- Set the Class @{Event} processing Priority.
--- Set the Class @{Core.Event} processing Priority.
-- The Event processing Priority is a number from 1 to 10,
-- reflecting the order of the classes subscribed to the Event to be processed.
-- @param #BASE self
-- @param #number EventPriority The @{Event} processing Priority.
-- @param #number EventPriority The @{Core.Event} processing Priority.
-- @return #BASE self
function BASE:SetEventPriority( EventPriority )
self._.EventPriority = EventPriority
@@ -462,132 +463,153 @@ do -- Event Handling
return self
end
-- Event handling function prototypes
--- Occurs whenever any unit in a mission fires a weapon. But not any machine gun or auto cannon based weapon, those are handled by EVENT.ShootingStart.
-- Event handling function prototypes - Have a look at the class @{Core.Event#EVENT} as these are just the prototypes.
--- Occurs whenever any unit in a mission fires a weapon. But not any machine gun or autocannon based weapon, those are handled by EVENT.ShootingStart.
-- Have a look at the class @{Core.Event#EVENT} as these are just the prototypes.
-- @function [parent=#BASE] OnEventShot
-- @param #BASE self
-- @param Core.Event#EVENTDATA EventData The EventData structure.
--- Occurs whenever an object is hit by a weapon.
-- initiator : The unit object the fired the weapon.
-- weapon: Weapon object that hit the target.
-- target: The Object that was hit.
-- Have a look at the class @{Core.Event#EVENT} as these are just the prototypes.
-- initiator : The unit object the fired the weapon
-- weapon: Weapon object that hit the target
-- target: The Object that was hit.
-- @function [parent=#BASE] OnEventHit
-- @param #BASE self
-- @param Core.Event#EVENTDATA EventData The EventData structure.
--- Occurs when an aircraft takes off from an airbase, farp, or ship.
-- initiator : The unit that took off.
-- place: Object from where the AI took-off from. Can be an Airbase Object, FARP, or Ships.
-- Have a look at the class @{Core.Event#EVENT} as these are just the prototypes.
-- initiator : The unit that tookoff
-- place: Object from where the AI took-off from. Can be an Airbase Object, FARP, or Ships
-- @function [parent=#BASE] OnEventTakeoff
-- @param #BASE self
-- @param Core.Event#EVENTDATA EventData The EventData structure.
--- Occurs when an aircraft lands at an airbase, farp or ship
-- initiator : The unit that has landed.
-- place: Object that the unit landed on. Can be an Airbase Object, FARP, or Ships.
-- Have a look at the class @{Core.Event#EVENT} as these are just the prototypes.
-- initiator : The unit that has landed
-- place: Object that the unit landed on. Can be an Airbase Object, FARP, or Ships
-- @function [parent=#BASE] OnEventLand
-- @param #BASE self
-- @param Core.Event#EVENTDATA EventData The EventData structure.
--- Occurs when any aircraft crashes into the ground and is completely destroyed.
-- initiator : The unit that has crashed.
-- Have a look at the class @{Core.Event#EVENT} as these are just the prototypes.
-- initiator : The unit that has crashed
-- @function [parent=#BASE] OnEventCrash
-- @param #BASE self
-- @param Core.Event#EVENTDATA EventData The EventData structure.
--- Occurs when a pilot ejects from an aircraft
-- initiator : The unit that has ejected
-- Have a look at the class @{Core.Event#EVENT} as these are just the prototypes.
-- initiator : The unit that has ejected
-- @function [parent=#BASE] OnEventEjection
-- @param #BASE self
-- @param Core.Event#EVENTDATA EventData The EventData structure.
--- Occurs when an aircraft connects with a tanker and begins taking on fuel.
-- initiator : The unit that is receiving fuel.
-- Have a look at the class @{Core.Event#EVENT} as these are just the prototypes.
-- initiator : The unit that is receiving fuel.
-- @function [parent=#BASE] OnEventRefueling
-- @param #BASE self
-- @param Core.Event#EVENTDATA EventData The EventData structure.
--- Occurs when an object is dead.
-- initiator : The unit that is dead.
-- Have a look at the class @{Core.Event#EVENT} as these are just the prototypes.
-- initiator : The unit that is dead.
-- @function [parent=#BASE] OnEventDead
-- @param #BASE self
-- @param Core.Event#EVENTDATA EventData The EventData structure.
--- Occurs when an object is completely destroyed.
-- initiator : The unit that is was destroyed.
--- Occurs when an Event for an object is triggered.
-- Have a look at the class @{Core.Event#EVENT} as these are just the prototypes.
-- initiator : The unit that triggered the event.
-- @function [parent=#BASE] OnEvent
-- @param #BASE self
-- @param Core.Event#EVENTDATA EventData The EventData structure.
--- Occurs when the pilot of an aircraft is killed. Can occur either if the player is alive and crashes or if a weapon kills the pilot without completely destroying the plane.
-- initiator : The unit that the pilot has died in.
-- Have a look at the class @{Core.Event#EVENT} as these are just the prototypes.
-- initiator : The unit that the pilot has died in.
-- @function [parent=#BASE] OnEventPilotDead
-- @param #BASE self
-- @param Core.Event#EVENTDATA EventData The EventData structure.
--- Occurs when a ground unit captures either an airbase or a farp.
-- initiator : The unit that captured the base.
-- place: The airbase that was captured, can be a FARP or Airbase. When calling place:getCoalition() the faction will already be the new owning faction.
-- Have a look at the class @{Core.Event#EVENT} as these are just the prototypes.
-- initiator : The unit that captured the base
-- place: The airbase that was captured, can be a FARP or Airbase. When calling place:getCoalition() the faction will already be the new owning faction.
-- @function [parent=#BASE] OnEventBaseCaptured
-- @param #BASE self
-- @param Core.Event#EVENTDATA EventData The EventData structure.
--- Occurs when a mission starts.
--- Occurs when a mission starts
-- Have a look at the class @{Core.Event#EVENT} as these are just the prototypes.
-- @function [parent=#BASE] OnEventMissionStart
-- @param #BASE self
-- @param Core.Event#EVENTDATA EventData The EventData structure.
--- Occurs when a mission ends.
--- Occurs when a mission ends
-- Have a look at the class @{Core.Event#EVENT} as these are just the prototypes.
-- @function [parent=#BASE] OnEventMissionEnd
-- @param #BASE self
-- @param Core.Event#EVENTDATA EventData The EventData structure.
--- Occurs when an aircraft is finished taking fuel.
-- initiator : The unit that was receiving fuel.
-- Have a look at the class @{Core.Event#EVENT} as these are just the prototypes.
-- initiator : The unit that was receiving fuel.
-- @function [parent=#BASE] OnEventRefuelingStop
-- @param #BASE self
-- @param Core.Event#EVENTDATA EventData The EventData structure.
--- Occurs when any object is spawned into the mission.
-- initiator : The unit that was spawned.
-- Have a look at the class @{Core.Event#EVENT} as these are just the prototypes.
-- initiator : The unit that was spawned
-- @function [parent=#BASE] OnEventBirth
-- @param #BASE self
-- @param Core.Event#EVENTDATA EventData The EventData structure.
--- Occurs when any system fails on a human controlled aircraft.
-- initiator : The unit that had the failure.
-- Have a look at the class @{Core.Event#EVENT} as these are just the prototypes.
-- initiator : The unit that had the failure
-- @function [parent=#BASE] OnEventHumanFailure
-- @param #BASE self
-- @param Core.Event#EVENTDATA EventData The EventData structure.
--- Occurs when any aircraft starts its engines.
-- initiator : The unit that is starting its engines..
-- Have a look at the class @{Core.Event#EVENT} as these are just the prototypes.
-- initiator : The unit that is starting its engines.
-- @function [parent=#BASE] OnEventEngineStartup
-- @param #BASE self
-- @param Core.Event#EVENTDATA EventData The EventData structure.
--- Occurs when any aircraft shuts down its engines.
-- initiator : The unit that is stopping its engines..
-- Have a look at the class @{Core.Event#EVENT} as these are just the prototypes.
-- initiator : The unit that is stopping its engines.
-- @function [parent=#BASE] OnEventEngineShutdown
-- @param #BASE self
-- @param Core.Event#EVENTDATA EventData The EventData structure.
--- Occurs when any player assumes direct control of a unit.
-- initiator : The unit that is being taken control of.
--- Occurs when any player assumes direct control of a unit. Note - not Mulitplayer safe. Use PlayerEnterAircraft.
-- Have a look at the class @{Core.Event#EVENT} as these are just the prototypes.
-- initiator : The unit that is being taken control of.
-- @function [parent=#BASE] OnEventPlayerEnterUnit
-- @param #BASE self
-- @param Core.Event#EVENTDATA EventData The EventData structure.
--- Occurs when any player relieves control of a unit to the AI.
-- initiator : The unit that the player left.
-- Have a look at the class @{Core.Event#EVENT} as these are just the prototypes.
-- initiator : The unit that the player left.
-- @function [parent=#BASE] OnEventPlayerLeaveUnit
-- @param #BASE self
-- @param Core.Event#EVENTDATA EventData The EventData structure.
--- Occurs when any unit begins firing a weapon that has a high rate of fire. Most common with aircraft cannons (GAU-8), auto cannons, and machine guns.
--- Occurs when any unit begins firing a weapon that has a high rate of fire. Most common with aircraft cannons (GAU-8), autocannons, and machine guns.
-- Have a look at the class @{Core.Event#EVENT} as these are just the prototypes.
-- initiator : The unit that is doing the shooting.
-- target: The unit that is being targeted.
-- @function [parent=#BASE] OnEventShootingStart
@@ -595,25 +617,29 @@ do -- Event Handling
-- @param Core.Event#EVENTDATA EventData The EventData structure.
--- Occurs when any unit stops firing its weapon. Event will always correspond with a shooting start event.
-- initiator : The unit that was doing the shooting.
-- Have a look at the class @{Core.Event#EVENT} as these are just the prototypes.
-- initiator : The unit that was doing the shooting.
-- @function [parent=#BASE] OnEventShootingEnd
-- @param #BASE self
-- @param Core.Event#EVENTDATA EventData The EventData structure.
--- Occurs when a new mark was added.
-- MarkID: ID of the mark.
-- Have a look at the class @{Core.Event#EVENT} as these are just the prototypes.
-- MarkID: ID of the mark.
-- @function [parent=#BASE] OnEventMarkAdded
-- @param #BASE self
-- @param Core.Event#EVENTDATA EventData The EventData structure.
--- Occurs when a mark was removed.
-- MarkID: ID of the mark.
-- Have a look at the class @{Core.Event#EVENT} as these are just the prototypes.
-- MarkID: ID of the mark.
-- @function [parent=#BASE] OnEventMarkRemoved
-- @param #BASE self
-- @param Core.Event#EVENTDATA EventData The EventData structure.
--- Occurs when a mark text was changed.
-- MarkID: ID of the mark.
-- Have a look at the class @{Core.Event#EVENT} as these are just the prototypes.
-- MarkID: ID of the mark.
-- @function [parent=#BASE] OnEventMarkChange
-- @param #BASE self
-- @param Core.Event#EVENTDATA EventData The EventData structure.
@@ -628,13 +654,15 @@ do -- Event Handling
--- Occurs when any modification to the "Score" as seen on the debrief menu would occur.
-- There is no information on what values the score was changed to. Event is likely similar to player_comment in this regard.
-- Have a look at the class @{Core.Event#EVENT} as these are just the prototypes.
-- @function [parent=#BASE] OnEventScore
-- @param #BASE self
-- @param Core.Event#EVENTDATA EventData The EventData structure.
--- Occurs on the death of a unit. Contains more and different information. Similar to unit_lost it will occur for aircraft before the aircraft crash event occurs.
--
-- * initiator: The unit that killed the target.
-- Have a look at the class @{Core.Event#EVENT} as these are just the prototypes.
--
-- * initiator: The unit that killed the target
-- * target: Target Object
-- * weapon: Weapon Object
--
@@ -644,12 +672,14 @@ do -- Event Handling
--- Occurs when any modification to the "Score" as seen on the debrief menu would occur.
-- There is no information on what values the score was changed to. Event is likely similar to player_comment in this regard.
-- Have a look at the class @{Core.Event#EVENT} as these are just the prototypes.
-- @function [parent=#BASE] OnEventScore
-- @param #BASE self
-- @param Core.Event#EVENTDATA EventData The EventData structure.
--- Occurs when the game thinks an object is destroyed.
--
-- Have a look at the class @{Core.Event#EVENT} as these are just the prototypes.
--
-- * initiator: The unit that is was destroyed.
--
-- @function [parent=#BASE] OnEventUnitLost
@@ -657,7 +687,8 @@ do -- Event Handling
-- @param Core.Event#EVENTDATA EventData The EventData structure.
--- Occurs shortly after the landing animation of an ejected pilot touching the ground and standing up. Event does not occur if the pilot lands in the water and sub combs to Davey Jones Locker.
--
-- Have a look at the class @{Core.Event#EVENT} as these are just the prototypes.
--
-- * initiator: Static object representing the ejected pilot. Place : Aircraft that the pilot ejected from.
-- * place: may not return as a valid object if the aircraft has crashed into the ground and no longer exists.
-- * subplace: is always 0 for unknown reasons.
@@ -667,38 +698,45 @@ do -- Event Handling
-- @param Core.Event#EVENTDATA EventData The EventData structure.
--- Paratrooper landing.
-- Have a look at the class @{Core.Event#EVENT} as these are just the prototypes.
-- @function [parent=#BASE] OnEventParatrooperLanding
-- @param #BASE self
-- @param Core.Event#EVENTDATA EventData The EventData structure.
--- Discard chair after ejection.
-- Have a look at the class @{Core.Event#EVENT} as these are just the prototypes.
-- @function [parent=#BASE] OnEventDiscardChairAfterEjection
-- @param #BASE self
-- @param Core.Event#EVENTDATA EventData The EventData structure.
--- Weapon add. Fires when entering a mission per pylon with the name of the weapon (double pylons not counted, infinite wep reload not counted.
-- Have a look at the class @{Core.Event#EVENT} as these are just the prototypes.
-- @function [parent=#BASE] OnEventParatrooperLanding
-- @param #BASE self
-- @param Core.Event#EVENTDATA EventData The EventData structure.
--- Trigger zone.
-- Have a look at the class @{Core.Event#EVENT} as these are just the prototypes.
-- @function [parent=#BASE] OnEventTriggerZone
-- @param #BASE self
-- @param Core.Event#EVENTDATA EventData The EventData structure.
--- Landing quality mark.
--- Landing quality mark.
-- Have a look at the class @{Core.Event#EVENT} as these are just the prototypes.
-- @function [parent=#BASE] OnEventLandingQualityMark
-- @param #BASE self
-- @param Core.Event#EVENTDATA EventData The EventData structure.
--- BDA.
-- Have a look at the class @{Core.Event#EVENT} as these are just the prototypes.
-- @function [parent=#BASE] OnEventBDA
-- @param #BASE self
-- @param Core.Event#EVENTDATA EventData The EventData structure.
--- Occurs when a player enters a slot and takes control of an aircraft.
-- **NOTE**: This is a workaround of a long standing DCS bug with the PLAYER_ENTER_UNIT event.
-- initiator : The unit that is being taken control of.
-- Have a look at the class @{Core.Event#EVENT} as these are just the prototypes.
-- **NOTE**: This is a workaround of a long standing DCS bug with the PLAYER_ENTER_UNIT event.
-- initiator : The unit that is being taken control of.
-- @function [parent=#BASE] OnEventPlayerEnterAircraft
-- @param #BASE self
-- @param Core.Event#EVENTDATA EventData The EventData structure.
@@ -744,18 +782,35 @@ function BASE:CreateEventCrash( EventTime, Initiator, IniObjectCategory )
world.onEvent( Event )
end
--- Creation of a Crash Event.
-- @param #BASE self
-- @param DCS#Time EventTime The time stamp of the event.
-- @param DCS#Object Initiator The initiating object of the event.
function BASE:CreateEventUnitLost(EventTime, Initiator)
self:F( { EventTime, Initiator } )
local Event = {
id = world.event.S_EVENT_UNIT_LOST,
time = EventTime,
initiator = Initiator,
}
world.onEvent( Event )
end
--- Creation of a Dead Event.
-- @param #BASE self
-- @param DCS#Time EventTime The time stamp of the event.
-- @param DCS#Object Initiator The initiating object of the event.
function BASE:CreateEventDead( EventTime, Initiator )
self:F( { EventTime, Initiator } )
function BASE:CreateEventDead( EventTime, Initiator, IniObjectCategory )
self:F( { EventTime, Initiator, IniObjectCategory } )
local Event = {
id = world.event.S_EVENT_DEAD,
time = EventTime,
initiator = Initiator,
}
IniObjectCategory = IniObjectCategory,
}
world.onEvent( Event )
end
@@ -792,22 +847,21 @@ function BASE:CreateEventTakeoff( EventTime, Initiator )
world.onEvent( Event )
end
--- Creation of a `S_EVENT_PLAYER_ENTER_AIRCRAFT` event.
-- @param #BASE self
-- @param Wrapper.Unit#UNIT PlayerUnit The aircraft unit the player entered.
function BASE:CreateEventPlayerEnterAircraft( PlayerUnit )
self:F( { PlayerUnit } )
local Event = {
id = EVENTS.PlayerEnterAircraft,
time = timer.getTime(),
initiator = PlayerUnit:GetDCSObject(),
}
world.onEvent( Event )
end
-- TODO: Complete DCS#Event structure.
--- Creation of a `S_EVENT_PLAYER_ENTER_AIRCRAFT` event.
-- @param #BASE self
-- @param Wrapper.Unit#UNIT PlayerUnit The aircraft unit the player entered.
function BASE:CreateEventPlayerEnterAircraft( PlayerUnit )
self:F( { PlayerUnit } )
local Event = {
id = EVENTS.PlayerEnterAircraft,
time = timer.getTime(),
initiator = PlayerUnit:GetDCSObject()
}
world.onEvent(Event)
end
--- The main event handling function... This function captures all events generated for the class.
-- @param #BASE self
-- @param DCS#Event event
@@ -846,32 +900,38 @@ do -- Scheduling
-- @param #number Start Specifies the amount of seconds that will be waited before the scheduling is started, and the event function is called.
-- @param #function SchedulerFunction The event function to be called when a timer event occurs. The event function needs to accept the parameters specified in SchedulerArguments.
-- @param #table ... Optional arguments that can be given as part of scheduler. The arguments need to be given as a table { param1, param 2, ... }.
-- @return #number The ScheduleID of the planned schedule.
-- @return #string The Schedule ID of the planned schedule.
function BASE:ScheduleOnce( Start, SchedulerFunction, ... )
self:F2( { Start } )
self:T3( { ... } )
-- Object name.
local ObjectName = "-"
ObjectName = self.ClassName .. self.ClassID
self:F3( { "ScheduleOnce: ", ObjectName, Start } )
-- Debug info.
self:F3( { "ScheduleOnce: ", ObjectName, Start } )
if not self.Scheduler then
self.Scheduler = SCHEDULER:New( self )
end
local ScheduleID = _SCHEDULEDISPATCHER:AddSchedule(
self,
SchedulerFunction,
{ ... },
Start,
nil,
nil,
nil
)
self._.Schedules[#self._.Schedules + 1] = ScheduleID
-- FF this was wrong!
--[[
local ScheduleID = _SCHEDULEDISPATCHER:AddSchedule(
self,
SchedulerFunction,
{ ... },
Start,
nil,
nil,
nil
)
]]
-- NOTE: MasterObject (first parameter) needs to be nil or it will be the first argument passed to the SchedulerFunction!
local ScheduleID = self.Scheduler:Schedule(nil, SchedulerFunction, {...}, Start)
self._.Schedules[#self._.Schedules+1] = ScheduleID
return self._.Schedules[#self._.Schedules]
end
@@ -883,7 +943,7 @@ do -- Scheduling
-- @param #number Stop Specifies the amount of seconds when the scheduler will be stopped.
-- @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, ... }.
-- @return #number The ScheduleID of the planned schedule.
-- @return #string The Schedule ID of the planned schedule.
function BASE:ScheduleRepeat( Start, Repeat, RandomizeFactor, Stop, SchedulerFunction, ... )
self:F2( { Start } )
self:T3( { ... } )
@@ -896,32 +956,33 @@ do -- Scheduling
if not self.Scheduler then
self.Scheduler = SCHEDULER:New( self )
end
-- NOTE: MasterObject (first parameter) should(!) be nil as it will be the first argument passed to the SchedulerFunction!
local ScheduleID = self.Scheduler:Schedule(
self,
SchedulerFunction,
{ ... },
Start,
Repeat,
RandomizeFactor,
Stop,
4
)
self._.Schedules[#self._.Schedules + 1] = ScheduleID
nil,
SchedulerFunction,
{ ... },
Start,
Repeat,
RandomizeFactor,
Stop,
4
)
self._.Schedules[#self._.Schedules+1] = ScheduleID
return self._.Schedules[#self._.Schedules]
end
--- Stops the Schedule.
-- @param #BASE self
-- @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.
function BASE:ScheduleStop( SchedulerFunction )
-- @param #string SchedulerID (Optional) Scheduler ID to be stopped. If nil, all pending schedules are stopped.
function BASE:ScheduleStop( SchedulerID )
self:F3( { "ScheduleStop:" } )
if self.Scheduler then
_SCHEDULEDISPATCHER:Stop( self.Scheduler, self._.Schedules[SchedulerFunction] )
--_SCHEDULEDISPATCHER:Stop( self.Scheduler, self._.Schedules[SchedulerFunction] )
_SCHEDULEDISPATCHER:Stop(self.Scheduler, SchedulerID)
end
end
@@ -1062,7 +1123,7 @@ end
--- Set tracing for a class
-- @param #BASE self
-- @param #string Class
-- @param #string Class Class name.
function BASE:TraceClass( Class )
_TraceClass[Class] = true
_TraceClassMethod[Class] = {}
@@ -1071,8 +1132,8 @@ end
--- Set tracing for a specific method of class
-- @param #BASE self
-- @param #string Class
-- @param #string Method
-- @param #string Class Class name.
-- @param #string Method Method.
function BASE:TraceClassMethod( Class, Method )
if not _TraceClassMethod[Class] then
_TraceClassMethod[Class] = {}
+58 -61
View File
@@ -18,7 +18,7 @@
-- After attaching a @{#BEACON} to your @{Wrapper.Positionable#POSITIONABLE}, you need to select the right function to activate the kind of beacon you want.
-- There are two types of BEACONs available : the (aircraft) TACAN Beacon and the general purpose Radio Beacon.
-- Note that in both case, you can set an optional parameter : the `BeaconDuration`. This can be very useful to simulate the battery time if your BEACON is
-- attach to a cargo crate, for exemple.
-- attach to a cargo crate, for example.
--
-- ## Aircraft TACAN Beacon usage
--
@@ -33,7 +33,7 @@
--
-- @type BEACON
-- @field #string ClassName Name of the class "BEACON".
-- @field Wrapper.Controllable#CONTROLLABLE Positionable The @{#CONTROLLABLE} that will receive radio capabilities.
-- @field Wrapper.Controllable#CONTROLLABLE Positionable The @{Wrapper.Controllable#CONTROLLABLE} that will receive radio capabilities.
-- @extends Core.Base#BASE
BEACON = {
ClassName = "BEACON",
@@ -72,12 +72,12 @@ BEACON.Type={
TACAN = 4,
VORTAC = 5,
RSBN = 128,
BROADCAST_STATION = 1024,
BROADCAST_STATION = 1024,
HOMER = 8,
AIRPORT_HOMER = 4104,
AIRPORT_HOMER_WITH_MARKER = 4136,
AIRPORT_HOMER = 4104,
AIRPORT_HOMER_WITH_MARKER = 4136,
ILS_FAR_HOMER = 16408,
ILS_NEAR_HOMER = 16424,
ILS_NEAR_HOMER = 16424,
ILS_LOCALIZER = 16640,
ILS_GLIDESLOPE = 16896,
PRMG_LOCALIZER = 33024,
@@ -108,13 +108,13 @@ BEACON.Type={
-- @field #number ICLS_LOCALIZER Carrier landing system.
-- @field #number ICLS_GLIDESLOPE Carrier landing system.
BEACON.System={
PAR_10 = 1,
RSBN_5 = 2,
TACAN = 3,
PAR_10 = 1,
RSBN_5 = 2,
TACAN = 3,
TACAN_TANKER_X = 4,
TACAN_TANKER_Y = 5,
VOR = 6,
ILS_LOCALIZER = 7,
VOR = 6,
ILS_LOCALIZER = 7,
ILS_GLIDESLOPE = 8,
PRMG_LOCALIZER = 9,
PRMG_GLIDESLOPE = 10,
@@ -130,16 +130,16 @@ BEACON.System={
--- Create a new BEACON Object. This doesn't activate the beacon, though, use @{#BEACON.ActivateTACAN} etc.
-- If you want to create a BEACON, you probably should use @{Wrapper.Positionable#POSITIONABLE.GetBeacon}() instead.
-- @param #BEACON self
-- @param Wrapper.Positionable#POSITIONABLE Positionable The @{Positionable} that will receive radio capabilities.
-- @param Wrapper.Positionable#POSITIONABLE Positionable The @{Wrapper.Positionable} that will receive radio capabilities.
-- @return #BEACON Beacon object or #nil if the positionable is invalid.
function BEACON:New(Positionable)
-- Inherit BASE.
local self=BASE:Inherit(self, BASE:New()) --#BEACON
-- Debug.
self:F(Positionable)
-- Set positionable.
if Positionable:GetPointVec2() then -- It's stupid, but the only way I found to make sure positionable is valid
self.Positionable = Positionable
@@ -147,12 +147,11 @@ function BEACON:New(Positionable)
self:I(string.format("New BEACON %s", tostring(self.name)))
return self
end
self:E({"The passed positionable is invalid, no BEACON created", Positionable})
return nil
end
--- Activates a TACAN BEACON.
-- @param #BEACON self
-- @param #number Channel TACAN channel, i.e. the "10" part in "10Y".
@@ -169,28 +168,28 @@ end
-- myBeacon:ActivateTACAN(20, "Y", "TEXACO", true) -- Activate the beacon
function BEACON:ActivateTACAN(Channel, Mode, Message, Bearing, Duration)
self:T({channel=Channel, mode=Mode, callsign=Message, bearing=Bearing, duration=Duration})
Mode=Mode or "Y"
-- Get frequency.
local Frequency=UTILS.TACANToFrequency(Channel, Mode)
-- Check.
if not Frequency then
self:E({"The passed TACAN channel is invalid, the BEACON is not emitting"})
return self
end
-- Beacon type.
local Type=BEACON.Type.TACAN
-- Beacon system.
local System=BEACON.System.TACAN
-- Check if unit is an aircraft and set system accordingly.
local AA=self.Positionable:IsAir()
if AA then
System=5 --NOTE: 5 is how you cat the correct tanker behaviour! --BEACON.System.TACAN_TANKER
-- Check if "Y" mode is selected for aircraft.
@@ -201,21 +200,21 @@ function BEACON:ActivateTACAN(Channel, Mode, Message, Bearing, Duration)
System=BEACON.System.TACAN_TANKER_Y
end
end
-- Attached unit.
local UnitID=self.Positionable:GetID()
-- Debug.
self:I({string.format("BEACON Activating TACAN %s: Channel=%d%s, Morse=%s, Bearing=%s, Duration=%s!", tostring(self.name), Channel, Mode, Message, tostring(Bearing), tostring(Duration))})
-- Start beacon.
self.Positionable:CommandActivateBeacon(Type, System, Frequency, UnitID, Channel, Mode, AA, Message, Bearing)
-- Stop scheduler.
if Duration then
self.Positionable:DeactivateBeacon(Duration)
end
return self
end
@@ -227,21 +226,21 @@ end
-- @return #BEACON self
function BEACON:ActivateICLS(Channel, Callsign, Duration)
self:F({Channel=Channel, Callsign=Callsign, Duration=Duration})
-- Attached unit.
local UnitID=self.Positionable:GetID()
-- Debug
self:T2({"ICLS BEACON started!"})
-- Start beacon.
self.Positionable:CommandActivateICLS(Channel, UnitID, Callsign)
-- Stop scheduler
if Duration then -- Schedule the stop of the BEACON if asked by the MD
self.Positionable:DeactivateBeacon(Duration)
end
return self
end
@@ -253,26 +252,25 @@ end
-- @return #BEACON self
function BEACON:ActivateLink4(Frequency, Morse, Duration)
self:F({Frequency=Frequency, Morse=Morse, Duration=Duration})
-- Attached unit.
local UnitID=self.Positionable:GetID()
-- Debug
self:T2({"LINK4 BEACON started!"})
-- Start beacon.
self.Positionable:CommandActivateLink4(Frequency,UnitID,Morse)
-- Stop sheduler
if Duration then -- Schedule the stop of the BEACON if asked by the MD
self.Positionable:DeactivateLink4(Duration)
self.Positionable:CommandDeactivateLink4(Duration)
end
return self
end
--- DEPRECATED: Please use @{BEACON:ActivateTACAN}() instead.
--- DEPRECATED: Please use @{#BEACON.ActivateTACAN}() instead.
-- Activates a TACAN BEACON on an Aircraft.
-- @param #BEACON self
-- @param #number TACANChannel (the "10" part in "10Y"). Note that AA TACAN are only available on Y Channels
@@ -288,20 +286,20 @@ end
-- myBeacon:AATACAN(20, "TEXACO", true) -- Activate the beacon
function BEACON:AATACAN(TACANChannel, Message, Bearing, BeaconDuration)
self:F({TACANChannel, Message, Bearing, BeaconDuration})
local IsValid = true
if not self.Positionable:IsAir() then
self:E({"The POSITIONABLE you want to attach the AA Tacan Beacon is not an aircraft ! The BEACON is not emitting", self.Positionable})
IsValid = false
end
local Frequency = self:_TACANToFrequency(TACANChannel, "Y")
if not Frequency then
self:E({"The passed TACAN channel is invalid, the BEACON is not emitting"})
IsValid = false
end
-- I'm using the beacon type 4 (BEACON_TYPE_TACAN). For System, I'm using 5 (TACAN_TANKER_MODE_Y) if the bearing shows its bearing or 14 (TACAN_AA_MODE_Y) if it does not
local System
if Bearing then
@@ -309,7 +307,7 @@ function BEACON:AATACAN(TACANChannel, Message, Bearing, BeaconDuration)
else
System = BEACON.System.TACAN_AA_MODE_Y
end
if IsValid then -- Starts the BEACON
self:T2({"AA TACAN BEACON started !"})
self.Positionable:SetCommand({
@@ -324,7 +322,7 @@ function BEACON:AATACAN(TACANChannel, Message, Bearing, BeaconDuration)
modeChannel = "Y",
}
})
if BeaconDuration then -- Schedule the stop of the BEACON if asked by the MD
SCHEDULER:New(nil,
function()
@@ -332,7 +330,7 @@ function BEACON:AATACAN(TACANChannel, Message, Bearing, BeaconDuration)
end, {}, BeaconDuration)
end
end
return self
end
@@ -352,7 +350,6 @@ function BEACON:StopAATACAN()
end
end
--- Activates a general purpose Radio Beacon
-- This uses the very generic singleton function "trigger.action.radioTransmission()" provided by DCS to broadcast a sound file on a specific frequency.
-- Although any frequency could be used, only a few DCS Modules can home on radio beacons at the time of writing, i.e. the Mi-8, Huey, Gazelle etc.
@@ -382,7 +379,7 @@ end
function BEACON:RadioBeacon(FileName, Frequency, Modulation, Power, BeaconDuration)
self:F({FileName, Frequency, Modulation, Power, BeaconDuration})
local IsValid = false
-- Check the filename
if type(FileName) == "string" then
if FileName:find(".ogg") or FileName:find(".wav") then
@@ -395,32 +392,32 @@ function BEACON:RadioBeacon(FileName, Frequency, Modulation, Power, BeaconDurati
if not IsValid then
self:E({"File name invalid. Maybe something wrong with the extension ? ", FileName})
end
-- Check the Frequency
if type(Frequency) ~= "number" and IsValid then
self:E({"Frequency invalid. ", Frequency})
IsValid = false
end
Frequency = Frequency * 1000000 -- Conversion to Hz
-- Check the modulation
if Modulation ~= radio.modulation.AM and Modulation ~= radio.modulation.FM and IsValid then --TODO Maybe make this future proof if ED decides to add an other modulation ?
self:E({"Modulation is invalid. Use DCS's enum radio.modulation.", Modulation})
IsValid = false
end
-- Check the Power
if type(Power) ~= "number" and IsValid then
self:E({"Power is invalid. ", Power})
IsValid = false
end
Power = math.floor(math.abs(Power)) --TODO Find what is the maximum power allowed by DCS and limit power to that
if IsValid then
self:T2({"Activating Beacon on ", Frequency, Modulation})
-- Note that this is looped. I have to give this transmission a unique name, I use the class ID
trigger.action.radioTransmission(FileName, self.Positionable:GetPositionVec3(), Modulation, true, Frequency, Power, tostring(self.ID))
if BeaconDuration then -- Schedule the stop of the BEACON if asked by the MD
SCHEDULER:New( nil,
function()
@@ -430,7 +427,7 @@ function BEACON:RadioBeacon(FileName, Frequency, Modulation, Power, BeaconDurati
end
end
--- Stop the Radio Beacon
--- Stops the Radio Beacon
-- @param #BEACON self
-- @return #BEACON self
function BEACON:StopRadioBeacon()
@@ -454,16 +451,16 @@ function BEACON:_TACANToFrequency(TACANChannel, TACANMode)
return nil -- error in arguments
end
end
-- This code is largely based on ED's code, in DCS World\Scripts\World\Radio\BeaconTypes.lua, line 137.
-- I have no idea what it does but it seems to work
local A = 1151 -- 'X', channel >= 64
local B = 64 -- channel >= 64
if TACANChannel < 64 then
B = 1
end
if TACANMode == 'Y' then
A = 1025
if TACANChannel < 64 then
@@ -474,6 +471,6 @@ function BEACON:_TACANToFrequency(TACANChannel, TACANMode)
A = 962
end
end
return (A + TACANChannel - B) * 1000000
end
+785
View File
@@ -0,0 +1,785 @@
--- **Core** - Client Menu Management.
--
-- **Main Features:**
--
-- * For complex, non-static menu structures
-- * Lightweigt implementation as alternative to MENU
-- * Separation of menu tree creation from menu on the clients's side
-- * Works with a SET_CLIENT set of clients
-- * Allow manipulation of the shadow tree in various ways
-- * Push to all or only one client
-- * Change entries' menu text
-- * Option to make an entry usable once only across all clients
-- * Auto appends GROUP and CLIENT objects to menu calls
--
-- ===
--
-- ### Author: **applevangelist**
--
-- ===
--
-- @module Core.ClientMenu
-- @image Core_Menu.JPG
-- last change: July 2023
-- TODO
----------------------------------------------------------------------------------------------------------------
--
-- CLIENTMENU
--
----------------------------------------------------------------------------------------------------------------
---
-- @type CLIENTMENU
-- @field #string ClassName Class Name
-- @field #string lid Lid for log entries
-- @field #string version Version string
-- @field #string name Name
-- @field #table path
-- @field #table parentpath
-- @field #CLIENTMENU Parent
-- @field Wrapper.Client#CLIENT client
-- @field #number GroupID Group ID
-- @field #number ID Entry ID
-- @field Wrapper.Group#GROUP group
-- @field #string UUID Unique ID based on path+name
-- @field #string Function
-- @field #table Functionargs
-- @field #table Children
-- @field #boolean Once
-- @field #boolean Generic
-- @field #boolean debug
-- @field #CLIENTMENUMANAGER Controller
-- @extends Core.Base#BASE
---
-- @field #CLIENTMENU
CLIENTMENU = {
ClassName = "CLIENTMENUE",
lid = "",
version = "0.1.0",
name = nil,
path = nil,
group = nil,
client = nil,
GroupID = nil,
Children = {},
Once = false,
Generic = false,
debug = false,
Controller = nil,
}
---
-- @field #CLIENTMENU_ID
CLIENTMENU_ID = 0
--- Create an new CLIENTMENU object.
-- @param #CLIENTMENU self
-- @param Wrapper.Client#CLIENT Client The client for whom this entry is.
-- @param #string Text Text of the F10 menu entry.
-- @param #CLIENTMENU Parent The parent menu entry.
-- @param #string Function (optional) Function to call when the entry is used.
-- @param ... (optional) Arguments for the Function, comma separated
-- @return #CLIENTMENU self
function CLIENTMENU:NewEntry(Client,Text,Parent,Function,...)
-- Inherit everything from BASE class.
local self=BASE:Inherit(self, BASE:New()) -- #CLIENTMENU
CLIENTMENU_ID = CLIENTMENU_ID + 1
self.ID = CLIENTMENU_ID
if Client then
self.group = Client:GetGroup()
self.client = Client
self.GroupID = self.group:GetID()
else
self.Generic = true
end
self.name = Text or "unknown entry"
if Parent then
if Parent:IsInstanceOf("MENU_BASE") then
self.parentpath = Parent.MenuPath
else
self.parentpath = Parent:GetPath()
Parent:AddChild(self)
end
end
self.Parent = Parent
self.Function = Function
self.Functionargs = arg or {}
table.insert(self.Functionargs,self.group)
table.insert(self.Functionargs,self.client)
if self.Functionargs and self.debug then
self:T({"Functionargs",self.Functionargs})
end
if not self.Generic then
if Function ~= nil then
local ErrorHandler = function( errmsg )
env.info( "MOOSE Error in CLIENTMENU COMMAND function: " .. errmsg )
if BASE.Debug ~= nil then
env.info( BASE.Debug.traceback() )
end
return errmsg
end
self.CallHandler = function()
local function MenuFunction()
return self.Function( unpack( self.Functionargs ) )
end
local Status, Result = xpcall( MenuFunction, ErrorHandler)
if self.Once == true then
self:Clear()
end
end
self.path = missionCommands.addCommandForGroup(self.GroupID,Text,self.parentpath, self.CallHandler)
else
self.path = missionCommands.addSubMenuForGroup(self.GroupID,Text,self.parentpath)
end
else
if self.parentpath then
self.path = UTILS.DeepCopy(self.parentpath)
else
self.path = {}
end
self.path[#self.path+1] = Text
end
self.UUID = table.concat(self.path,";")
self:T({self.UUID})
self.Once = false
-- Log id.
self.lid=string.format("CLIENTMENU %s | %s | ", self.ID, self.name)
self:T(self.lid.."Created")
return self
end
--- Create a UUID
-- @param #CLIENTMENU self
-- @param #CLIENTMENU Parent The parent object if any
-- @param #string Text The menu entry text
-- @return #string UUID
function CLIENTMENU:CreateUUID(Parent,Text)
local path = {}
if Parent and Parent.path then
path = Parent.path
end
path[#path+1] = Text
local UUID = table.concat(path,";")
return UUID
end
--- Set the CLIENTMENUMANAGER for this entry.
-- @param #CLIENTMENU self
-- @param #CLIENTMENUMANAGER Controller The controlling object.
-- @return #CLIENTMENU self
function CLIENTMENU:SetController(Controller)
self.Controller = Controller
return self
end
--- The entry will be deleted after being used used - for menu entries with functions only.
-- @param #CLIENTMENU self
-- @return #CLIENTMENU self
function CLIENTMENU:SetOnce()
self:T(self.lid.."SetOnce")
self.Once = true
return self
end
--- Remove the entry from the F10 menu.
-- @param #CLIENTMENU self
-- @return #CLIENTMENU self
function CLIENTMENU:RemoveF10()
self:T(self.lid.."RemoveF10")
if self.GroupID then
--self:I(self.lid.."Removing "..table.concat(self.path,";"))
missionCommands.removeItemForGroup(self.GroupID , self.path )
end
return self
end
--- Get the menu path table.
-- @param #CLIENTMENU self
-- @return #table Path
function CLIENTMENU:GetPath()
self:T(self.lid.."GetPath")
return self.path
end
--- Get the UUID.
-- @param #CLIENTMENU self
-- @return #string UUID
function CLIENTMENU:GetUUID()
self:T(self.lid.."GetUUID")
return self.UUID
end
--- Link a child entry.
-- @param #CLIENTMENU self
-- @param #CLIENTMENU Child The entry to link as a child.
-- @return #CLIENTMENU self
function CLIENTMENU:AddChild(Child)
self:T(self.lid.."AddChild "..Child.ID)
table.insert(self.Children,Child.ID,Child)
return self
end
--- Remove a child entry.
-- @param #CLIENTMENU self
-- @param #CLIENTMENU Child The entry to remove from the children.
-- @return #CLIENTMENU self
function CLIENTMENU:RemoveChild(Child)
self:T(self.lid.."RemoveChild "..Child.ID)
table.remove(self.Children,Child.ID)
return self
end
--- Remove all subentries (children) from this entry.
-- @param #CLIENTMENU self
-- @return #CLIENTMENU self
function CLIENTMENU:RemoveSubEntries()
self:T(self.lid.."RemoveSubEntries")
self:T({self.Children})
for _id,_entry in pairs(self.Children) do
self:T("Removing ".._id)
if _entry then
_entry:RemoveSubEntries()
_entry:RemoveF10()
if _entry.Parent then
_entry.Parent:RemoveChild(self)
end
--if self.Controller then
--self.Controller:_RemoveByID(_entry.ID)
--end
--_entry = nil
end
end
return self
end
--- Remove this entry and all subentries (children) from this entry.
-- @param #CLIENTMENU self
-- @return #CLIENTMENU self
function CLIENTMENU:Clear()
self:T(self.lid.."Clear")
for _id,_entry in pairs(self.Children) do
if _entry then
_entry:RemoveSubEntries()
_entry = nil
end
end
self:RemoveF10()
if self.Parent then
self.Parent:RemoveChild(self)
end
--if self.Controller then
--self.Controller:_RemoveByID(self.ID)
--end
return self
end
-- TODO
----------------------------------------------------------------------------------------------------------------
--
-- CLIENTMENUMANAGER
--
----------------------------------------------------------------------------------------------------------------
--- Class CLIENTMENUMANAGER
-- @type CLIENTMENUMANAGER
-- @field #string ClassName Class Name
-- @field #string lid Lid for log entries
-- @field #string version Version string
-- @field #string name Name
-- @field Core.Set#SET_CLIENT clientset The set of clients this menu manager is for
-- @field #table flattree
-- @field #table rootentries
-- @field #table menutree
-- @field #number entrycount
-- @field #boolean debug
-- @extends Core.Base#BASE
--- *As a child my family's menu consisted of two choices: take it, or leave it.*
--
-- ===
--
-- ## CLIENTMENU and CLIENTMENUMANAGER
--
-- Manage menu structures for a SET_CLIENT of clients.
--
-- ## Concept
--
-- Separate creation of a menu tree structure from pushing it to each client. Create a shadow "reference" menu structure tree for your client pilot's in a mission.
-- This can then be propagated to all clients. Manipulate the entries in the structure with removing, clearing or changing single entries, create replacement sub-structures
-- for entries etc, push to one or all clients.
--
-- Many functions can either change the tree for one client or for all clients.
--
-- ## Create a base reference tree and send to all clients
--
-- local clientset = SET_CLIENT:New():FilterStart()
--
-- local menumgr = CLIENTMENUMANAGER:New(clientset,"Dayshift")
-- local mymenu = menumgr:NewEntry("Top")
-- local mymenu_lv1a = menumgr:NewEntry("Level 1 a",mymenu)
-- local mymenu_lv1b = menumgr:NewEntry("Level 1 b",mymenu)
-- -- next one is a command menu entry, which can only be used once
-- local mymenu_lv1c = menumgr:NewEntry("Action Level 1 c",mymenu, testfunction, "testtext"):SetOnce()
--
-- local mymenu_lv2a = menumgr:NewEntry("Go here",mymenu_lv1a)
-- local mymenu_lv2b = menumgr:NewEntry("Level 2 ab",mymenu_lv1a)
-- local mymenu_lv2c = menumgr:NewEntry("Level 2 ac",mymenu_lv1a)
--
-- local mymenu_lv2ba = menumgr:NewEntry("Level 2 ba",mymenu_lv1b)
-- local mymenu_lv2bb = menumgr:NewEntry("Level 2 bb",mymenu_lv1b)
-- local mymenu_lv2bc = menumgr:NewEntry("Level 2 bc",mymenu_lv1b)
--
-- local mymenu_lv3a = menumgr:NewEntry("Level 3 aaa",mymenu_lv2a)
-- local mymenu_lv3b = menumgr:NewEntry("Level 3 aab",mymenu_lv2a)
-- local mymenu_lv3c = menumgr:NewEntry("Level 3 aac",mymenu_lv2a)
--
-- menumgr:Propagate()
--
-- ## Remove a single entry's subtree
--
-- menumgr:RemoveSubEntries(mymenu_lv3a)
--
-- ## Remove a single entry and also it's subtree
--
-- menumgr:DeleteEntry(mymenu_lv3a)
--
-- ## Add a single entry
--
-- local baimenu = menumgr:NewEntry("BAI",mymenu_lv1b)
--
-- menumgr:AddEntry(baimenu)
--
-- ## Add an entry with a function
--
-- local baimenu = menumgr:NewEntry("Task Action", mymenu_lv1b, TestFunction, Argument1, Argument1)
--
-- Now, the class will **automatically append the call with GROUP and CLIENT objects**, as this is can only be done when pushing the entry to the clients. So, the actual function implementation needs to look like this:
--
-- function TestFunction( Argument1, Argument2, Group, Client)
--
-- **Caveat is**, that you need to ensure your arguments are not **nil** or **false**, as LUA will optimize those away. You would end up having Group and Client in wrong places in the function call. Hence,
-- if you need/ want to send **nil** or **false**, send a place holder instead and ensure your function can handle this, e.g.
--
-- local baimenu = menumgr:NewEntry("Task Action", mymenu_lv1b, TestFunction, "nil", Argument1)
--
-- ## Change the text of a leaf entry in the menu tree
--
-- menumgr:ChangeEntryTextForAll(mymenu_lv1b,"Attack")
--
-- ## Reset a single clients menu tree
--
-- menumgr:ResetMenu(client)
--
-- ## Reset all and clear the reference tree
--
-- menumgr:ResetMenuComplete()
--
-- @field #CLIENTMENUMANAGER
CLIENTMENUMANAGER = {
ClassName = "CLIENTMENUMANAGER",
lid = "",
version = "0.1.0",
name = nil,
clientset = nil,
menutree = {},
flattree = {},
playertree = {},
entrycount = 0,
rootentries = {},
debug = true,
}
--- Create a new ClientManager instance.
-- @param #CLIENTMENUMANAGER self
-- @param Core.Set#SET_CLIENT ClientSet The set of clients to manage.
-- @param #string Alias The name of this manager.
-- @return #CLIENTMENUMANAGER self
function CLIENTMENUMANAGER:New(ClientSet, Alias)
-- Inherit everything from FSM class.
local self=BASE:Inherit(self, BASE:New()) -- #CLIENTMENUMANAGER
self.clientset = ClientSet
self.name = Alias or "Nightshift"
-- Log id.
self.lid=string.format("CLIENTMENUMANAGER %s | %s | ", self.version, self.name)
if self.debug then
self:T(self.lid.."Created")
end
return self
end
--- Create a new entry in the generic structure.
-- @param #CLIENTMENUMANAGER self
-- @param #string Text Text of the F10 menu entry.
-- @param #CLIENTMENU Parent The parent menu entry.
-- @param #string Function (optional) Function to call when the entry is used.
-- @param ... (optional) Arguments for the Function, comma separated.
-- @return #CLIENTMENU Entry
function CLIENTMENUMANAGER:NewEntry(Text,Parent,Function,...)
self:T(self.lid.."NewEntry "..Text or "None")
self.entrycount = self.entrycount + 1
local entry = CLIENTMENU:NewEntry(nil,Text,Parent,Function,unpack(arg))
if not Parent then
self.rootentries[self.entrycount] = entry
end
local depth = #entry.path
if not self.menutree[depth] then self.menutree[depth] = {} end
table.insert(self.menutree[depth],entry.UUID)
self.flattree[entry.UUID] = entry
return entry
end
--- Check matching entry in the generic structure by UUID.
-- @param #CLIENTMENUMANAGER self
-- @param #string UUID UUID of the menu entry.
-- @return #boolean Exists
function CLIENTMENUMANAGER:EntryUUIDExists(UUID)
local exists = self.flattree[UUID] and true or false
return exists
end
--- Find matching entry in the generic structure by UUID.
-- @param #CLIENTMENUMANAGER self
-- @param #string UUID UUID of the menu entry.
-- @return #CLIENTMENU Entry The #CLIENTMENU object found or nil.
function CLIENTMENUMANAGER:FindEntryByUUID(UUID)
self:T(self.lid.."FindEntryByUUID "..UUID or "None")
local entry = nil
for _gid,_entry in pairs(self.flattree) do
local Entry = _entry -- #CLIENTMENU
if Entry and Entry.UUID == UUID then
entry = Entry
end
end
return entry
end
--- Find matching entries by text in the generic structure by UUID.
-- @param #CLIENTMENUMANAGER self
-- @param #string Text Text or partial text of the menu entry to find.
-- @param #CLIENTMENU Parent (Optional) Only find entries under this parent entry.
-- @return #table Table of matching UUIDs of #CLIENTMENU objects
-- @return #table Table of matching #CLIENTMENU objects
-- @return #number Number of matches
function CLIENTMENUMANAGER:FindUUIDsByText(Text,Parent)
self:T(self.lid.."FindUUIDsByText "..Text or "None")
local matches = {}
local entries = {}
local n = 0
for _uuid,_entry in pairs(self.flattree) do
local Entry = _entry -- #CLIENTMENU
if Parent then
if Entry and string.find(Entry.name,Text) and string.find(Entry.UUID,Parent.UUID) then
table.insert(matches,_uuid)
table.insert(entries,Entry )
n=n+1
end
else
if Entry and string.find(Entry.name,Text) then
table.insert(matches,_uuid)
table.insert(entries,Entry )
n=n+1
end
end
end
return matches, entries, n
end
--- Find matching entries in the generic structure by the menu text.
-- @param #CLIENTMENUMANAGER self
-- @param #string Text Text or partial text of the F10 menu entry.
-- @param #CLIENTMENU Parent (Optional) Only find entries under this parent entry.
-- @return #table Table of matching #CLIENTMENU objects.
-- @return #number Number of matches
function CLIENTMENUMANAGER:FindEntriesByText(Text,Parent)
self:T(self.lid.."FindEntriesByText "..Text or "None")
local matches, objects, number = self:FindUUIDsByText(Text, Parent)
return objects, number
end
--- Find matching entries under a parent in the generic structure by UUID.
-- @param #CLIENTMENUMANAGER self
-- @param #CLIENTMENU Parent Find entries under this parent entry.
-- @return #table Table of matching UUIDs of #CLIENTMENU objects
-- @return #table Table of matching #CLIENTMENU objects
-- @return #number Number of matches
function CLIENTMENUMANAGER:FindUUIDsByParent(Parent)
self:T(self.lid.."FindUUIDsByParent")
local matches = {}
local entries = {}
local n = 0
for _uuid,_entry in pairs(self.flattree) do
local Entry = _entry -- #CLIENTMENU
if Parent then
if Entry and string.find(Entry.UUID,Parent.UUID) then
table.insert(matches,_uuid)
table.insert(entries,Entry )
n=n+1
end
end
end
return matches, entries, n
end
--- Find matching entries in the generic structure under a parent.
-- @param #CLIENTMENUMANAGER self
-- @param #CLIENTMENU Parent Find entries under this parent entry.
-- @return #table Table of matching #CLIENTMENU objects.
-- @return #number Number of matches
function CLIENTMENUMANAGER:FindEntriesByParent(Parent)
self:T(self.lid.."FindEntriesByParent")
local matches, objects, number = self:FindUUIDsByParent(Parent)
return objects, number
end
--- Alter the text of a leaf entry in the generic structure and push to one specific client's F10 menu.
-- @param #CLIENTMENUMANAGER self
-- @param #CLIENTMENU Entry The menu entry.
-- @param #string Text New Text of the F10 menu entry.
-- @param Wrapper.Client#CLIENT Client (optional) The client for whom to alter the entry, if nil done for all clients.
-- @return #CLIENTMENUMANAGER self
function CLIENTMENUMANAGER:ChangeEntryText(Entry, Text, Client)
self:T(self.lid.."ChangeEntryText "..Text or "None")
local newentry = CLIENTMENU:NewEntry(nil,Text,Entry.Parent,Entry.Function,unpack(Entry.Functionargs))
self:DeleteF10Entry(Entry,Client)
self:DeleteGenericEntry(Entry)
if not Entry.Parent then
self.rootentries[self.entrycount] = newentry
end
local depth = #newentry.path
if not self.menutree[depth] then self.menutree[depth] = {} end
table.insert(self.menutree[depth],newentry.UUID)
self.flattree[newentry.UUID] = newentry
self:AddEntry(newentry,Client)
return self
end
--- Push the complete menu structure to each of the clients in the set - refresh the menu tree of the clients.
-- @param #CLIENTMENUMANAGER self
-- @param Wrapper.Client#CLIENT Client (optional) If given, propagate only for this client.
-- @return #CLIENTMENU Entry
function CLIENTMENUMANAGER:Propagate(Client)
self:T(self.lid.."Propagate")
self:T(Client)
local Set = self.clientset.Set
if Client then
Set = {Client}
end
self:ResetMenu(Client)
for _,_client in pairs(Set) do
local client = _client -- Wrapper.Client#CLIENT
if client and client:IsAlive() then
local playername = client:GetPlayerName()
if not self.playertree[playername] then
self.playertree[playername] = {}
end
for level,branch in pairs (self.menutree) do
self:T("Building branch:" .. level)
for _,leaf in pairs(branch) do
self:T("Building leaf:" .. leaf)
local entry = self:FindEntryByUUID(leaf)
if entry then
self:T("Found generic entry:" .. entry.UUID)
local parent = nil
if entry.Parent and entry.Parent.UUID then
parent = self.playertree[playername][entry.Parent.UUID] or self:FindEntryByUUID(entry.Parent.UUID)
end
self.playertree[playername][entry.UUID] = CLIENTMENU:NewEntry(client,entry.name,parent,entry.Function,unpack(entry.Functionargs))
self.playertree[playername][entry.UUID].Once = entry.Once
else
self:T("NO generic entry for:" .. leaf)
end
end
end
end
end
return self
end
--- Push a single previously created entry into the menu structure of all clients.
-- @param #CLIENTMENUMANAGER self
-- @param #CLIENTMENU Entry The entry to add.
-- @param Wrapper.Client#CLIENT Client (optional) If given, make this change only for this client.
-- @return #CLIENTMENUMANAGER self
function CLIENTMENUMANAGER:AddEntry(Entry,Client)
self:T(self.lid.."AddEntry")
local Set = self.clientset.Set
if Client then
Set = {Client}
end
for _,_client in pairs(Set) do
local client = _client -- Wrapper.Client#CLIENT
if client and client:IsAlive() then
local playername = client:GetPlayerName()
if Entry then
self:T("Adding generic entry:" .. Entry.UUID)
local parent = nil
if not self.playertree[playername] then
self.playertree[playername] = {}
end
if Entry.Parent and Entry.Parent.UUID then
parent = self.playertree[playername][Entry.Parent.UUID] or self:FindEntryByUUID(Entry.Parent.UUID)
end
self.playertree[playername][Entry.UUID] = CLIENTMENU:NewEntry(client,Entry.name,parent,Entry.Function,unpack(Entry.Functionargs))
self.playertree[playername][Entry.UUID].Once = Entry.Once
else
self:T("NO generic entry given")
end
end
end
return self
end
--- Blank out the menu - remove **all root entries** and all entries below from the client's F10 menus, leaving the generic structure untouched.
-- @param #CLIENTMENUMANAGER self
-- @param Wrapper.Client#CLIENT Client (optional) If given, remove only for this client.
-- @return #CLIENTMENUMANAGER self
function CLIENTMENUMANAGER:ResetMenu(Client)
self:T(self.lid.."ResetMenu")
for _,_entry in pairs(self.rootentries) do
--local RootEntry = self.structure.generic[_entry]
if _entry then
self:DeleteF10Entry(_entry,Client)
end
end
return self
end
--- Blank out the menu - remove **all root entries** and all entries below from all clients' F10 menus, and **delete** the generic structure.
-- @param #CLIENTMENUMANAGER self
-- @return #CLIENTMENUMANAGER self
function CLIENTMENUMANAGER:ResetMenuComplete()
self:T(self.lid.."ResetMenuComplete")
for _,_entry in pairs(self.rootentries) do
--local RootEntry = self.structure.generic[_entry]
if _entry then
self:DeleteF10Entry(_entry)
end
end
self.playertree = nil
self.playertree = {}
self.rootentries = nil
self.rootentries = {}
self.menutree = nil
self.menutree = {}
return self
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. In this case the generic structure will not be touched.
-- @return #CLIENTMENUMANAGER self
function CLIENTMENUMANAGER:DeleteF10Entry(Entry,Client)
self:T(self.lid.."DeleteF10Entry")
local Set = self.clientset.Set
if Client then
Set = {Client}
end
for _,_client in pairs(Set) do
if _client and _client:IsAlive() then
local playername = _client:GetPlayerName()
if self.playertree[playername] then
local centry = self.playertree[playername][Entry.UUID] -- #CLIENTMENU
if centry then
--self:I("Match for "..Entry.UUID)
centry:Clear()
end
end
end
end
return self
end
--- Remove the entry and all entries below the given entry from the generic tree.
-- @param #CLIENTMENUMANAGER self
-- @param #CLIENTMENU Entry The entry to remove
-- @return #CLIENTMENUMANAGER self
function CLIENTMENUMANAGER:DeleteGenericEntry(Entry)
self:T(self.lid.."DeleteGenericEntry")
if Entry.Children and #Entry.Children > 0 then
self:RemoveGenericSubEntries(Entry)
end
local depth = #Entry.path
local uuid = Entry.UUID
local tbl = UTILS.DeepCopy(self.menutree)
if tbl[depth] then
for i=depth,#tbl do
--self:I("Level = "..i)
for _id,_uuid in pairs(tbl[i]) do
self:T(_uuid)
if string.find(_uuid,uuid) or _uuid == uuid then
--self:I("Match for ".._uuid)
self.menutree[i][_id] = nil
self.flattree[_uuid] = nil
end
end
end
end
return self
end
--- Remove all entries below the given entry from the generic tree.
-- @param #CLIENTMENUMANAGER self
-- @param #CLIENTMENU Entry The entry where to start. This entry stays.
-- @return #CLIENTMENUMANAGER self
function CLIENTMENUMANAGER:RemoveGenericSubEntries(Entry)
self:T(self.lid.."RemoveGenericSubEntries")
local depth = #Entry.path + 1
local uuid = Entry.UUID
local tbl = UTILS.DeepCopy(self.menutree)
if tbl[depth] then
for i=depth,#tbl do
self:T("Level = "..i)
for _id,_uuid in pairs(tbl[i]) do
self:T(_uuid)
if string.find(_uuid,uuid) then
self:T("Match for ".._uuid)
self.menutree[i][_id] = nil
self.flattree[_uuid] = nil
end
end
end
end
return self
end
--- Remove all entries below the given entry from the client's F10 menus.
-- @param #CLIENTMENUMANAGER self
-- @param #CLIENTMENU Entry The entry where to start. This entry stays.
-- @param Wrapper.Client#CLIENT Client (optional) If given, make this change only for this client. In this case the generic structure will not be touched.
-- @return #CLIENTMENUMANAGER self
function CLIENTMENUMANAGER:RemoveF10SubEntries(Entry,Client)
self:T(self.lid.."RemoveSubEntries")
local Set = self.clientset.Set
if Client then
Set = {Client}
end
for _,_client in pairs(Set) do
if _client and _client:IsAlive() then
local playername = _client:GetPlayerName()
if self.playertree[playername] then
local centry = self.playertree[playername][Entry.UUID] -- #CLIENTMENU
centry:RemoveSubEntries()
end
end
end
return self
end
----------------------------------------------------------------------------------------------------------------
--
-- End ClientMenu
--
----------------------------------------------------------------------------------------------------------------
+464
View File
@@ -0,0 +1,464 @@
--- **Core** - Define any or all conditions to be evaluated.
--
-- **Main Features:**
--
-- * Add arbitrary numbers of conditon functions
-- * Evaluate *any* or *all* conditions
--
-- ===
--
-- ## Example Missions:
--
-- Demo missions can be found on [github](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/develop/OPS%20-%20Operation).
--
-- ===
--
-- ### Author: **funkyfranky**
--
-- ===
-- @module Core.Condition
-- @image MOOSE.JPG
--- CONDITON class.
-- @type CONDITION
-- @field #string ClassName Name of the class.
-- @field #string lid Class id string for output to DCS log file.
-- @field #string name Name of the condition.
-- @field #boolean isAny General functions are evaluated as any condition.
-- @field #boolean negateResult Negate result of evaluation.
-- @field #boolean noneResult Boolean that is returned if no condition functions at all were specified.
-- @field #table functionsGen General condition functions.
-- @field #table functionsAny Any condition functions.
-- @field #table functionsAll All condition functions.
-- @field #number functionCounter Running number to determine the unique ID of condition functions.
-- @field #boolean defaultPersist Default persistence of condition functions.
--
-- @extends Core.Base#BASE
--- *Better three hours too soon than a minute too late.* - William Shakespeare
--
-- ===
--
-- # The CONDITION Concept
--
--
--
-- @field #CONDITION
CONDITION = {
ClassName = "CONDITION",
lid = nil,
functionsGen = {},
functionsAny = {},
functionsAll = {},
functionCounter = 0,
defaultPersist = false,
}
--- Condition function.
-- @type CONDITION.Function
-- @field #number uid Unique ID of the condition function.
-- @field #string type Type of the condition function: "gen", "any", "all".
-- @field #boolean persistence If `true`, this is persistent.
-- @field #function func Callback function to check for a condition. Must return a `#boolean`.
-- @field #table arg (Optional) Arguments passed to the condition callback function if any.
--- CONDITION class version.
-- @field #string version
CONDITION.version="0.3.0"
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO list
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO: Make FSM. No sure if really necessary.
-- DONE: Option to remove condition functions.
-- DONE: Persistence option for condition functions.
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Constructor
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- Create a new CONDITION object.
-- @param #CONDITION self
-- @param #string Name (Optional) Name used in the logs.
-- @return #CONDITION self
function CONDITION:New(Name)
-- Inherit BASE.
local self=BASE:Inherit(self, BASE:New()) --#CONDITION
self.name=Name or "Condition X"
self:SetNoneResult(false)
self.lid=string.format("%s | ", self.name)
return self
end
--- Set that general condition functions return `true` if `any` function returns `true`. Default is that *all* functions must return `true`.
-- @param #CONDITION self
-- @param #boolean Any If `true`, *any* condition can be true. Else *all* conditions must result `true`.
-- @return #CONDITION self
function CONDITION:SetAny(Any)
self.isAny=Any
return self
end
--- Negate result.
-- @param #CONDITION self
-- @param #boolean Negate If `true`, result is negated else not.
-- @return #CONDITION self
function CONDITION:SetNegateResult(Negate)
self.negateResult=Negate
return self
end
--- Set whether `true` or `false` is returned, if no conditions at all were specified. By default `false` is returned.
-- @param #CONDITION self
-- @param #boolean ReturnValue Returns this boolean.
-- @return #CONDITION self
function CONDITION:SetNoneResult(ReturnValue)
if not ReturnValue then
self.noneResult=false
else
self.noneResult=true
end
return self
end
--- Set whether condition functions are persistent, *i.e.* are removed.
-- @param #CONDITION self
-- @param #boolean IsPersistent If `true`, condition functions are persistent.
-- @return #CONDITION self
function CONDITION:SetDefaultPersistence(IsPersistent)
self.defaultPersist=IsPersistent
return self
end
--- Add a function that is evaluated. It must return a `#boolean` value, *i.e.* either `true` or `false` (or `nil`).
-- @param #CONDITION self
-- @param #function Function The function to call.
-- @param ... (Optional) Parameters passed to the function (if any).
--
-- @usage
-- local function isAequalB(a, b)
-- return a==b
-- end
--
-- myCondition:AddFunction(isAequalB, a, b)
--
-- @return #CONDITION.Function Condition function table.
function CONDITION:AddFunction(Function, ...)
-- Condition function.
local condition=self:_CreateCondition(0, Function, ...)
-- Add to table.
table.insert(self.functionsGen, condition)
return condition
end
--- Add a function that is evaluated. It must return a `#boolean` value, *i.e.* either `true` or `false` (or `nil`).
-- @param #CONDITION self
-- @param #function Function The function to call.
-- @param ... (Optional) Parameters passed to the function (if any).
-- @return #CONDITION.Function Condition function table.
function CONDITION:AddFunctionAny(Function, ...)
-- Condition function.
local condition=self:_CreateCondition(1, Function, ...)
-- Add to table.
table.insert(self.functionsAny, condition)
return condition
end
--- Add a function that is evaluated. It must return a `#boolean` value, *i.e.* either `true` or `false` (or `nil`).
-- @param #CONDITION self
-- @param #function Function The function to call.
-- @param ... (Optional) Parameters passed to the function (if any).
-- @return #CONDITION.Function Condition function table.
function CONDITION:AddFunctionAll(Function, ...)
-- Condition function.
local condition=self:_CreateCondition(2, Function, ...)
-- Add to table.
table.insert(self.functionsAll, condition)
return condition
end
--- Remove a condition function.
-- @param #CONDITION self
-- @param #CONDITION.Function ConditionFunction The condition function to be removed.
-- @return #CONDITION self
function CONDITION:RemoveFunction(ConditionFunction)
if ConditionFunction then
local data=nil
if ConditionFunction.type==0 then
data=self.functionsGen
elseif ConditionFunction.type==1 then
data=self.functionsAny
elseif ConditionFunction.type==2 then
data=self.functionsAll
end
if data then
for i=#data,1,-1 do
local cf=data[i] --#CONDITION.Function
if cf.uid==ConditionFunction.uid then
self:T(self.lid..string.format("Removed ConditionFunction UID=%d", cf.uid))
table.remove(data, i)
return self
end
end
end
end
return self
end
--- Remove all non-persistant condition functions.
-- @param #CONDITION self
-- @return #CONDITION self
function CONDITION:RemoveNonPersistant()
for i=#self.functionsGen,1,-1 do
local cf=self.functionsGen[i] --#CONDITION.Function
if not cf.persistence then
table.remove(self.functionsGen, i)
end
end
for i=#self.functionsAll,1,-1 do
local cf=self.functionsAll[i] --#CONDITION.Function
if not cf.persistence then
table.remove(self.functionsAll, i)
end
end
for i=#self.functionsAny,1,-1 do
local cf=self.functionsAny[i] --#CONDITION.Function
if not cf.persistence then
table.remove(self.functionsAny, i)
end
end
return self
end
--- Evaluate conditon functions.
-- @param #CONDITION self
-- @param #boolean AnyTrue If `true`, evaluation return `true` if *any* condition function returns `true`. By default, *all* condition functions must return true.
-- @return #boolean Result of condition functions.
function CONDITION:Evaluate(AnyTrue)
-- Check if at least one function was given.
if #self.functionsAll + #self.functionsAny + #self.functionsAll == 0 then
return self.noneResult
end
-- Any condition for gen.
local evalAny=self.isAny
if AnyTrue~=nil then
evalAny=AnyTrue
end
local isGen=nil
if evalAny then
isGen=self:_EvalConditionsAny(self.functionsGen)
else
isGen=self:_EvalConditionsAll(self.functionsGen)
end
-- Is any?
local isAny=self:_EvalConditionsAny(self.functionsAny)
-- Is all?
local isAll=self:_EvalConditionsAll(self.functionsAll)
-- Result.
local result=isGen and isAny and isAll
-- Negate result.
if self.negateResult then
result=not result
end
-- Debug message.
self:T(self.lid..string.format("Evaluate: isGen=%s, isAny=%s, isAll=%s (negate=%s) ==> result=%s", tostring(isGen), tostring(isAny), tostring(isAll), tostring(self.negateResult), tostring(result)))
return result
end
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Private Functions
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- Check if all given condition are true.
-- @param #CONDITION self
-- @param #table functions Functions to evaluate.
-- @return #boolean If true, all conditions were true (or functions was empty/nil). Returns false if at least one condition returned false.
function CONDITION:_EvalConditionsAll(functions)
-- At least one condition?
local gotone=false
-- Any stop condition must be true.
for _,_condition in pairs(functions or {}) do
local condition=_condition --#CONDITION.Function
-- At least one condition was defined.
gotone=true
-- Call function.
local istrue=condition.func(unpack(condition.arg))
-- Any false will return false.
if not istrue then
return false
end
end
-- All conditions were true.
return true
end
--- Check if any of the given conditions is true.
-- @param #CONDITION self
-- @param #table functions Functions to evaluate.
-- @return #boolean If true, at least one condition is true (or functions was emtpy/nil).
function CONDITION:_EvalConditionsAny(functions)
-- At least one condition?
local gotone=false
-- Any stop condition must be true.
for _,_condition in pairs(functions or {}) do
local condition=_condition --#CONDITION.Function
-- At least one condition was defined.
gotone=true
-- Call function.
local istrue=condition.func(unpack(condition.arg))
-- Any true will return true.
if istrue then
return true
end
end
-- No condition was true.
if gotone then
return false
else
-- No functions passed.
return true
end
end
--- Create conditon function object.
-- @param #CONDITION self
-- @param #number Ftype Function type: 0=Gen, 1=All, 2=Any.
-- @param #function Function The function to call.
-- @param ... (Optional) Parameters passed to the function (if any).
-- @return #CONDITION.Function Condition function.
function CONDITION:_CreateCondition(Ftype, Function, ...)
-- Increase counter.
self.functionCounter=self.functionCounter+1
local condition={} --#CONDITION.Function
condition.uid=self.functionCounter
condition.type=Ftype or 0
condition.persistence=self.defaultPersist
condition.func=Function
condition.arg={}
if arg then
condition.arg=arg
end
return condition
end
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Global Condition Functions
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- Condition to check if time is greater than a given threshold time.
-- @param #number Time Time in seconds.
-- @param #boolean Absolute If `true`, abs. mission time from `timer.getAbsTime()` is checked. Default is relative mission time from `timer.getTime()`.
-- @return #boolean Returns `true` if time is greater than give the time.
function CONDITION.IsTimeGreater(Time, Absolute)
local Tnow=nil
if Absolute then
Tnow=timer.getAbsTime()
else
Tnow=timer.getTime()
end
if Tnow>Time then
return true
else
return false
end
return nil
end
--- Function that returns `true` (success) with a certain probability. For example, if you specify `Probability=80` there is an 80% chance that `true` is returned.
-- Technically, a random number between 0 and 100 is created. If the given success probability is less then this number, `true` is returned.
-- @param #number Probability Success probability in percent. Default 50 %.
-- @return #boolean Returns `true` for success and `false` otherwise.
function CONDITION.IsRandomSuccess(Probability)
Probability=Probability or 50
-- Create some randomness.
math.random()
math.random()
math.random()
-- Number between 0 and 100.
local N=math.random()*100
if N<Probability then
return true
else
return false
end
end
--- Function that returns always `true`
-- @return #boolean Returns `true` unconditionally.
function CONDITION.ReturnTrue()
return true
end
--- Function that returns always `false`
-- @return #boolean Returns `false` unconditionally.
function CONDITION.ReturnFalse()
return false
end
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
File diff suppressed because it is too large Load Diff
+91 -12
View File
@@ -35,7 +35,7 @@
-- There are 5 types/levels of objects that the _EVENTDISPATCHER services:
--
-- * _DATABASE object: The core of the MOOSE objects. Any object that is created, deleted or updated, is done in this database.
-- * SET_ derived classes: These are subsets of the _DATABASE object. These subsets are updated by the _EVENTDISPATCHER as the second priority.
-- * SET_ derived classes: These are subsets of the global _DATABASE object (an instance of @{Core.Database#DATABASE}). These subsets are updated by the _EVENTDISPATCHER as the second priority.
-- * UNIT objects: UNIT objects can subscribe to DCS events. Each DCS event will be directly published to the subscribed UNIT object.
-- * GROUP objects: GROUP objects can subscribe to DCS events. Each DCS event will be directly published to the subscribed GROUP object.
-- * Any other object: Various other objects can subscribe to DCS events. Each DCS event triggered will be published to each subscribed object.
@@ -52,7 +52,7 @@
--
-- ![Objects](..\Presentations\EVENT\Dia8.JPG)
--
-- The actual event subscribing and handling is not facilitated through the _EVENTDISPATCHER, but it is done through the @{BASE} class, @{UNIT} class and @{GROUP} class.
-- The actual event subscribing and handling is not facilitated through the _EVENTDISPATCHER, but it is done through the @{Core.Base#BASE} class, @{Wrapper.Unit#UNIT} class and @{Wrapper.Group#GROUP} class.
-- The _EVENTDISPATCHER is a component that is quietly working in the background of MOOSE.
--
-- ![Objects](..\Presentations\EVENT\Dia9.JPG)
@@ -248,6 +248,18 @@ EVENTS = {
TriggerZone = world.event.S_EVENT_TRIGGER_ZONE or -1,
LandingQualityMark = world.event.S_EVENT_LANDING_QUALITY_MARK or -1,
BDA = world.event.S_EVENT_BDA or -1,
-- Added with DCS 2.8.0
AIAbortMission = world.event.S_EVENT_AI_ABORT_MISSION or -1,
DayNight = world.event.S_EVENT_DAYNIGHT or -1,
FlightTime = world.event.S_EVENT_FLIGHT_TIME or -1,
SelfKillPilot = world.event.S_EVENT_PLAYER_SELF_KILL_PILOT or -1,
PlayerCaptureAirfield = world.event.S_EVENT_PLAYER_CAPTURE_AIRFIELD or -1,
EmergencyLanding = world.event.S_EVENT_EMERGENCY_LANDING or -1,
UnitCreateTask = world.event.S_EVENT_UNIT_CREATE_TASK or -1,
UnitDeleteTask = world.event.S_EVENT_UNIT_DELETE_TASK or -1,
SimulationStart = world.event.S_EVENT_SIMULATION_START or -1,
WeaponRearm = world.event.S_EVENT_WEAPON_REARM or -1,
WeaponDrop = world.event.S_EVENT_WEAPON_DROP or -1,
}
--- The Event structure
@@ -293,8 +305,8 @@ EVENTS = {
-- @field Wrapper.Airbase#AIRBASE Place The MOOSE airbase object.
-- @field #string PlaceName The name of the airbase.
--
-- @field #table weapon The weapon used during the event.
-- @field #table Weapon
-- @field DCS#Weapon weapon The weapon used during the event.
-- @field DCS#Weapon Weapon The weapon used during the event.
-- @field #string WeaponName Name of the weapon.
-- @field DCS#Unit WeaponTgtDCSUnit Target DCS unit of the weapon.
--
@@ -560,9 +572,69 @@ local _EVENTMETA = {
Event = "OnEventBDA",
Text = "S_EVENT_BDA"
},
-- Added with DCS 2.8
[EVENTS.AIAbortMission] = {
Order = 1,
Side = "I",
Event = "OnEventAIAbortMission",
Text = "S_EVENT_AI_ABORT_MISSION"
},
[EVENTS.DayNight] = {
Order = 1,
Event = "OnEventDayNight",
Text = "S_EVENT_DAYNIGHT"
},
[EVENTS.FlightTime] = {
Order = 1,
Event = "OnEventFlightTime",
Text = "S_EVENT_FLIGHT_TIME"
},
[EVENTS.SelfKillPilot] = {
Order = 1,
Side = "I",
Event = "OnEventSelfKillPilot",
Text = "S_EVENT_PLAYER_SELF_KILL_PILOT"
},
[EVENTS.PlayerCaptureAirfield] = {
Order = 1,
Event = "OnEventPlayerCaptureAirfield",
Text = "S_EVENT_PLAYER_CAPTURE_AIRFIELD"
},
[EVENTS.EmergencyLanding] = {
Order = 1,
Side = "I",
Event = "OnEventEmergencyLanding",
Text = "S_EVENT_EMERGENCY_LANDING"
},
[EVENTS.UnitCreateTask] = {
Order = 1,
Event = "OnEventUnitCreateTask",
Text = "S_EVENT_UNIT_CREATE_TASK"
},
[EVENTS.UnitDeleteTask] = {
Order = 1,
Event = "OnEventUnitDeleteTask",
Text = "S_EVENT_UNIT_DELETE_TASK"
},
[EVENTS.SimulationStart] = {
Order = 1,
Event = "OnEventSimulationStart",
Text = "S_EVENT_SIMULATION_START"
},
[EVENTS.WeaponRearm] = {
Order = 1,
Side = "I",
Event = "OnEventWeaponRearm",
Text = "S_EVENT_WEAPON_REARM"
},
[EVENTS.WeaponDrop] = {
Order = 1,
Side = "I",
Event = "OnEventWeaponDrop",
Text = "S_EVENT_WEAPON_DROP"
},
}
--- The Events structure
-- @type EVENT.Events
-- @field #number IniUnit
@@ -932,7 +1004,7 @@ do -- Event Creation
--- Creation of a ZoneGoal Deletion Event.
-- @param #EVENT self
-- @param Core.ZoneGoal#ZONE_GOAL ZoneGoal The ZoneGoal created.
-- @param Functional.ZoneGoal#ZONE_GOAL ZoneGoal The ZoneGoal created.
function EVENT:CreateEventDeleteZoneGoal( ZoneGoal )
self:F( { ZoneGoal } )
@@ -1058,7 +1130,7 @@ function EVENT:onEvent( Event )
Event.IniUnitName = Event.IniDCSUnitName
Event.IniDCSGroup = Event.IniDCSUnit:getGroup()
Event.IniUnit = UNIT:FindByName( Event.IniDCSUnitName )
if not Event.IniUnit then
-- Unit can be a CLIENT. Most likely this will be the case ...
Event.IniUnit = CLIENT:FindByName( Event.IniDCSUnitName, '', true )
@@ -1093,8 +1165,7 @@ function EVENT:onEvent( Event )
if Event.IniObjectCategory == Object.Category.SCENERY then
---
-- Scenery
---
---
Event.IniDCSUnit = Event.initiator
Event.IniDCSUnitName = Event.IniDCSUnit:getName()
Event.IniUnitName = Event.IniDCSUnitName
@@ -1114,6 +1185,12 @@ function EVENT:onEvent( Event )
Event.IniCoalition = Event.IniDCSUnit:getCoalition()
Event.IniCategory = Event.IniDCSUnit:getDesc().category
Event.IniTypeName = Event.IniDCSUnit:getTypeName()
-- If the airbase does not exist in the DB, we add it (e.g. when FARPS are spawned).
if not Event.IniUnit then
_DATABASE:_RegisterAirbase(Event.initiator)
Event.IniUnit = AIRBASE:FindByName(Event.IniDCSUnitName)
end
end
end
@@ -1203,9 +1280,11 @@ function EVENT:onEvent( Event )
--local name=Event.place:getName() -- This returns a DCS error "Airbase doesn't exit" :(
-- However, this is not a big thing, as the aircraft the pilot ejected from is usually long crashed before the ejected pilot touches the ground.
--Event.Place=UNIT:Find(Event.place)
else
Event.Place=AIRBASE:Find(Event.place)
Event.PlaceName=Event.Place:GetName()
else
if Event.place:isExist() and Event.place:getCategory() ~= Object.Category.SCENERY then
Event.Place=AIRBASE:Find(Event.place)
Event.PlaceName=Event.Place:GetName()
end
end
end
+52 -52
View File
@@ -47,9 +47,9 @@
-- and tailored** by mission designers through **the implementation of Transition Handlers**.
-- Each of these FSM implementation classes start either with:
--
-- * an acronym **AI\_**, which indicates a FSM implementation directing **AI controlled** @{GROUP} and/or @{UNIT}. These AI\_ classes derive the @{#FSM_CONTROLLABLE} class.
-- * an acronym **TASK\_**, which indicates a FSM implementation executing a @{TASK} executed by Groups of players. These TASK\_ classes derive the @{#FSM_TASK} class.
-- * an acronym **ACT\_**, which indicates an Sub-FSM implementation, directing **Humans actions** that need to be done in a @{TASK}, seated in a @{CLIENT} (slot) or a @{UNIT} (CA join). These ACT\_ classes derive the @{#FSM_PROCESS} class.
-- * an acronym **AI\_**, which indicates a FSM implementation directing **AI controlled** @{Wrapper.Group#GROUP} and/or @{Wrapper.Unit#UNIT}. These AI\_ classes derive the @{#FSM_CONTROLLABLE} class.
-- * an acronym **TASK\_**, which indicates a FSM implementation executing a @{Tasking.Task#TASK} executed by Groups of players. These TASK\_ classes derive the @{#FSM_TASK} class.
-- * an acronym **ACT\_**, which indicates an Sub-FSM implementation, directing **Humans actions** that need to be done in a @{Tasking.Task#TASK}, seated in a @{Wrapper.Client#CLIENT} (slot) or a @{Wrapper.Unit#UNIT} (CA join). These ACT\_ classes derive the @{#FSM_PROCESS} class.
--
-- Detailed explanations and API specifics are further below clarified and FSM derived class specifics are described in those class documentation sections.
--
@@ -61,10 +61,10 @@
--
-- The following derived classes are available in the MOOSE framework, that implement a specialized form of a FSM:
--
-- * @{#FSM_TASK}: Models Finite State Machines for @{Task}s.
-- * @{#FSM_PROCESS}: Models Finite State Machines for @{Task} actions, which control @{Client}s.
-- * @{#FSM_CONTROLLABLE}: Models Finite State Machines for @{Wrapper.Controllable}s, which are @{Wrapper.Group}s, @{Wrapper.Unit}s, @{Client}s.
-- * @{#FSM_SET}: Models Finite State Machines for @{Set}s. Note that these FSMs control multiple objects!!! So State concerns here
-- * @{#FSM_TASK}: Models Finite State Machines for @{Tasking.Task}s.
-- * @{#FSM_PROCESS}: Models Finite State Machines for @{Tasking.Task} actions, which control @{Wrapper.Client}s.
-- * @{#FSM_CONTROLLABLE}: Models Finite State Machines for @{Wrapper.Controllable}s, which are @{Wrapper.Group}s, @{Wrapper.Unit}s, @{Wrapper.Client}s.
-- * @{#FSM_SET}: Models Finite State Machines for @{Core.Set}s. Note that these FSMs control multiple objects!!! So State concerns here
-- for multiple objects or the position of the state machine in the process.
--
-- ===
@@ -119,9 +119,9 @@ do -- FSM
-- and tailored** by mission designers through **the implementation of Transition Handlers**.
-- Each of these FSM implementation classes start either with:
--
-- * an acronym **AI\_**, which indicates an FSM implementation directing **AI controlled** @{GROUP} and/or @{UNIT}. These AI\_ classes derive the @{#FSM_CONTROLLABLE} class.
-- * an acronym **TASK\_**, which indicates an FSM implementation executing a @{TASK} executed by Groups of players. These TASK\_ classes derive the @{#FSM_TASK} class.
-- * an acronym **ACT\_**, which indicates an Sub-FSM implementation, directing **Humans actions** that need to be done in a @{TASK}, seated in a @{CLIENT} (slot) or a @{UNIT} (CA join). These ACT\_ classes derive the @{#FSM_PROCESS} class.
-- * an acronym **AI\_**, which indicates an FSM implementation directing **AI controlled** @{Wrapper.Group#GROUP} and/or @{Wrapper.Unit#UNIT}. These AI\_ classes derive the @{#FSM_CONTROLLABLE} class.
-- * an acronym **TASK\_**, which indicates an FSM implementation executing a @{Tasking.Task#TASK} executed by Groups of players. These TASK\_ classes derive the @{#FSM_TASK} class.
-- * an acronym **ACT\_**, which indicates an Sub-FSM implementation, directing **Humans actions** that need to be done in a @{Tasking.Task#TASK}, seated in a @{Wrapper.Client#CLIENT} (slot) or a @{Wrapper.Unit#UNIT} (CA join). These ACT\_ classes derive the @{#FSM_PROCESS} class.
--
-- ![Transition Rules and Transition Handlers and Event Triggers](..\Presentations\FSM\Dia3.JPG)
--
@@ -405,8 +405,8 @@ do -- FSM
Transition.To = To
-- Debug message.
self:T2( Transition )
--self:T3( Transition )
self._Transitions[Transition] = Transition
self:_eventmap( self.Events, Transition )
end
@@ -418,7 +418,7 @@ do -- FSM
return self._Transitions or {}
end
--- Set the default @{Process} template with key ProcessName providing the ProcessClass and the process object when it is assigned to a @{Wrapper.Controllable} by the task.
--- Set the default @{#FSM_PROCESS} template with key ProcessName providing the ProcessClass and the process object when it is assigned to a @{Wrapper.Controllable} by the task.
-- @param #FSM self
-- @param #table From Can contain a string indicating the From state or a table of strings containing multiple From states.
-- @param #string Event The Event name.
@@ -426,8 +426,8 @@ do -- FSM
-- @param #table ReturnEvents A table indicating for which returned events of the SubFSM which Event must be triggered in the FSM.
-- @return Core.Fsm#FSM_PROCESS The SubFSM.
function FSM:AddProcess( From, Event, Process, ReturnEvents )
self:T( { From, Event } )
--self:T3( { From, Event } )
local Sub = {}
Sub.From = From
Sub.Event = Event
@@ -524,9 +524,9 @@ do -- FSM
Process._Scores[State] = Process._Scores[State] or {}
Process._Scores[State].ScoreText = ScoreText
Process._Scores[State].Score = Score
self:T( Process._Scores )
--self:T3( Process._Scores )
return Process
end
@@ -560,19 +560,19 @@ do -- FSM
-- @param #table Events Events.
-- @param #table EventStructure Event structure.
function FSM:_eventmap( Events, EventStructure )
local Event = EventStructure.Event
local __Event = "__" .. EventStructure.Event
self[Event] = self[Event] or self:_create_transition( Event )
self[__Event] = self[__Event] or self:_delayed_transition( Event )
-- Debug message.
self:T2( "Added methods: " .. Event .. ", " .. __Event )
Events[Event] = self.Events[Event] or { map = {} }
self:_add_to_map( Events[Event].map, EventStructure )
local Event = EventStructure.Event
local __Event = "__" .. EventStructure.Event
self[Event] = self[Event] or self:_create_transition(Event)
self[__Event] = self[__Event] or self:_delayed_transition(Event)
-- Debug message.
--self:T3( "Added methods: " .. Event .. ", " .. __Event )
Events[Event] = self.Events[Event] or { map = {} }
self:_add_to_map( Events[Event].map, EventStructure )
end
--- Sub maps.
@@ -784,8 +784,8 @@ do -- FSM
return function( self, DelaySeconds, ... )
-- Debug.
self:T2( "Delayed Event: " .. EventName )
self:T3( "Delayed Event: " .. EventName )
local CallID = 0
if DelaySeconds ~= nil then
@@ -802,23 +802,23 @@ do -- FSM
self._EventSchedules[EventName] = CallID
-- Debug output.
self:T2( string.format( "NEGATIVE Event %s delayed by %.1f sec SCHEDULED with CallID=%s", EventName, DelaySeconds, tostring( CallID ) ) )
self:T2(string.format("NEGATIVE Event %s delayed by %.3f sec SCHEDULED with CallID=%s", EventName, DelaySeconds, tostring(CallID)))
else
self:T2( string.format( "NEGATIVE Event %s delayed by %.1f sec CANCELLED as we already have such an event in the queue.", EventName, DelaySeconds ) )
self:T2(string.format("NEGATIVE Event %s delayed by %.3f sec CANCELLED as we already have such an event in the queue.", EventName, DelaySeconds))
-- reschedule
end
else
CallID = self.CallScheduler:Schedule( self, self._handler, { EventName, ... }, DelaySeconds or 1, nil, nil, nil, 4, true )
self:T2( string.format( "Event %s delayed by %.1f sec SCHEDULED with CallID=%s", EventName, DelaySeconds, tostring( CallID ) ) )
self:T2(string.format("Event %s delayed by %.3f sec SCHEDULED with CallID=%s", EventName, DelaySeconds, tostring(CallID)))
end
else
error( "FSM: An asynchronous event trigger requires a DelaySeconds parameter!!! This can be positive or negative! Sorry, but will not process this." )
end
-- Debug.
self:T2( { CallID = CallID } )
--self:T3( { CallID = CallID } )
end
end
@@ -841,7 +841,7 @@ do -- FSM
function FSM:_gosub( ParentFrom, ParentEvent )
local fsmtable = {}
if self.subs[ParentFrom] and self.subs[ParentFrom][ParentEvent] then
self:T( { ParentFrom, ParentEvent, self.subs[ParentFrom], self.subs[ParentFrom][ParentEvent] } )
--self:T3( { ParentFrom, ParentEvent, self.subs[ParentFrom], self.subs[ParentFrom][ParentEvent] } )
return self.subs[ParentFrom][ParentEvent]
else
return {}
@@ -887,8 +887,8 @@ do -- FSM
Map[From] = Event.To
end
end
self:T3( { Map, Event } )
--self:T3( { Map, Event } )
end
--- Get current state.
@@ -908,7 +908,7 @@ do -- FSM
--- Check if FSM is in state.
-- @param #FSM self
-- @param #string State State name.
-- @param #boolean If true, FSM is in this state.
-- @return #boolean If true, FSM is in this state.
function FSM:Is( State )
return self.current == State
end
@@ -916,8 +916,8 @@ do -- FSM
--- Check if FSM is in state.
-- @param #FSM self
-- @param #string State State name.
-- @param #boolean If true, FSM is in this state.
function FSM:is( state )
-- @return #boolean If true, FSM is in this state.
function FSM:is(state)
return self.current == state
end
@@ -953,7 +953,7 @@ do -- FSM_CONTROLLABLE
-- @field Wrapper.Controllable#CONTROLLABLE Controllable
-- @extends Core.Fsm#FSM
--- Models Finite State Machines for @{Wrapper.Controllable}s, which are @{Wrapper.Group}s, @{Wrapper.Unit}s, @{Client}s.
--- Models Finite State Machines for @{Wrapper.Controllable}s, which are @{Wrapper.Group}s, @{Wrapper.Unit}s, @{Wrapper.Client}s.
--
-- ===
--
@@ -1086,7 +1086,7 @@ do -- FSM_PROCESS
-- @field Tasking.Task#TASK Task
-- @extends Core.Fsm#FSM_CONTROLLABLE
--- FSM_PROCESS class models Finite State Machines for @{Task} actions, which control @{Client}s.
--- FSM_PROCESS class models Finite State Machines for @{Tasking.Task} actions, which control @{Wrapper.Client}s.
--
-- ===
--
@@ -1146,7 +1146,7 @@ do -- FSM_PROCESS
-- @param #FSM_PROCESS self
-- @return #FSM_PROCESS
function FSM_PROCESS:Copy( Controllable, Task )
self:T( { self:GetClassNameAndID() } )
--self:T3( { self:GetClassNameAndID() } )
local NewFsm = self:New( Controllable, Task ) -- Core.Fsm#FSM_PROCESS
@@ -1171,13 +1171,13 @@ do -- FSM_PROCESS
-- Copy End States
for EndStateID, EndState in pairs( self:GetEndStates() ) do
self:T( EndState )
--self:T3( EndState )
NewFsm:AddEndState( EndState )
end
-- Copy the score tables
for ScoreID, Score in pairs( self:GetScores() ) do
self:T( Score )
--self:T3( Score )
NewFsm:AddScore( ScoreID, Score.ScoreText, Score.Score )
end
@@ -1241,7 +1241,7 @@ do -- FSM_PROCESS
-- TODO: Need to check and fix that an FSM_PROCESS is only for a UNIT. Not for a GROUP.
--- Send a message of the @{Task} to the Group of the Unit.
--- Send a message of the @{Tasking.Task} to the Group of the Unit.
-- @param #FSM_PROCESS self
function FSM_PROCESS:Message( Message )
self:F( { Message = Message } )
@@ -1382,7 +1382,7 @@ do -- FSM_SET
-- @field Core.Set#SET_BASE Set
-- @extends Core.Fsm#FSM
--- FSM_SET class models Finite State Machines for @{Set}s. Note that these FSMs control multiple objects!!! So State concerns here
--- FSM_SET class models Finite State Machines for @{Core.Set}s. Note that these FSMs control multiple objects!!! So State concerns here
-- for multiple objects or the position of the state machine in the process.
--
-- ===
@@ -1422,7 +1422,7 @@ do -- FSM_SET
-- @param #FSM_SET self
-- @return Core.Set#SET_BASE
function FSM_SET:Get()
return self.Controllable
return self.Set
end
function FSM_SET:_call_handler( step, trigger, params, EventName )
@@ -0,0 +1,274 @@
--- **Core** - Tap into markers added to the F10 map by users.
--
-- **Main Features:**
--
-- * Create an easy way to tap into markers added to the F10 map by users.
-- * Recognize own tag and list of keywords.
-- * Matched keywords are handed down to functions.
-- ##Listen for your tag
-- myMarker = MARKEROPS_BASE:New("tag", {}, false)
-- function myMarker:OnAfterMarkChanged(From, Event, To, Text, Keywords, Coord, idx)
--
-- end
-- Make sure to use the "MarkChanged" event as "MarkAdded" comes in right after the user places a blank marker and your callback will never be called.
--
-- ===
--
-- ### Author: **Applevangelist**
--
-- Date: 5 May 2021
-- Last Update: Feb 2023
--
-- ===
---
-- @module Core.MarkerOps_Base
-- @image MOOSE_Core.JPG
--------------------------------------------------------------------------
-- MARKEROPS_BASE Class Definition.
--------------------------------------------------------------------------
--- MARKEROPS_BASE class.
-- @type MARKEROPS_BASE
-- @field #string ClassName Name of the class.
-- @field #string Tag Tag to identify commands.
-- @field #table Keywords Table of keywords to recognize.
-- @field #string version Version of #MARKEROPS_BASE.
-- @field #boolean Casesensitive Enforce case when identifying the Tag, i.e. tag ~= Tag
-- @extends Core.Fsm#FSM
--- *Fiat lux.* -- Latin proverb.
--
-- ===
--
-- # The MARKEROPS_BASE Concept
--
-- This class enable scripting text-based actions from markers.
--
-- @field #MARKEROPS_BASE
MARKEROPS_BASE = {
ClassName = "MARKEROPS",
Tag = "mytag",
Keywords = {},
version = "0.1.1",
debug = false,
Casesensitive = true,
}
--- Function to instantiate a new #MARKEROPS_BASE object.
-- @param #MARKEROPS_BASE self
-- @param #string Tagname Name to identify us from the event text.
-- @param #table Keywords Table of keywords recognized from the event text.
-- @param #boolean Casesensitive (Optional) Switch case sensitive identification of Tagname. Defaults to true.
-- @return #MARKEROPS_BASE self
function MARKEROPS_BASE:New(Tagname,Keywords,Casesensitive)
-- Inherit FSM
local self=BASE:Inherit(self, FSM:New()) -- #MARKEROPS_BASE
-- Set some string id for output to DCS.log file.
self.lid=string.format("MARKEROPS_BASE %s | ", tostring(self.version))
self.Tag = Tagname or "mytag"-- #string
self.Keywords = Keywords or {} -- #table - might want to use lua regex here, too
self.debug = false
self.Casesensitive = true
if Casesensitive and Casesensitive == false then
self.Casesensitive = false
end
-----------------------
--- FSM Transitions ---
-----------------------
-- Start State.
self:SetStartState("Stopped")
-- Add FSM transitions.
-- From State --> Event --> To State
self:AddTransition("Stopped", "Start", "Running") -- Start the FSM.
self:AddTransition("*", "MarkAdded", "*") -- Start the FSM.
self:AddTransition("*", "MarkChanged", "*") -- Start the FSM.
self:AddTransition("*", "MarkDeleted", "*") -- Start the FSM.
self:AddTransition("Running", "Stop", "Stopped") -- Stop the FSM.
self:HandleEvent(EVENTS.MarkAdded, self.OnEventMark)
self:HandleEvent(EVENTS.MarkChange, self.OnEventMark)
self:HandleEvent(EVENTS.MarkRemoved, self.OnEventMark)
-- start
self:I(self.lid..string.format("started for %s",self.Tag))
self:__Start(1)
return self
-------------------
-- PSEUDO Functions
-------------------
--- On after "MarkAdded" event. Triggered when a Marker is added to the F10 map.
-- @function [parent=#MARKEROPS_BASE] OnAfterMarkAdded
-- @param #MARKEROPS_BASE self
-- @param #string From The From state
-- @param #string Event The Event called
-- @param #string To The To state
-- @param #string Text The text on the marker
-- @param #table Keywords Table of matching keywords found in the Event text
-- @param Core.Point#COORDINATE Coord Coordinate of the marker.
--- On after "MarkChanged" event. Triggered when a Marker is changed on the F10 map.
-- @function [parent=#MARKEROPS_BASE] OnAfterMarkChanged
-- @param #MARKEROPS_BASE self
-- @param #string From The From state
-- @param #string Event The Event called
-- @param #string To The To state
-- @param #string Text The text on the marker
-- @param #table Keywords Table of matching keywords found in the Event text
-- @param Core.Point#COORDINATE Coord Coordinate of the marker.
-- @param #number idx DCS Marker ID
--- On after "MarkDeleted" event. Triggered when a Marker is deleted from the F10 map.
-- @function [parent=#MARKEROPS_BASE] OnAfterMarkDeleted
-- @param #MARKEROPS_BASE self
-- @param #string From The From state
-- @param #string Event The Event called
-- @param #string To The To state
--- "Stop" trigger. Used to stop the function an unhandle events
-- @function [parent=#MARKEROPS_BASE] Stop
end
--- (internal) Handle events.
-- @param #MARKEROPS_BASE self
-- @param Core.Event#EVENTDATA Event
function MARKEROPS_BASE:OnEventMark(Event)
self:T({Event})
if Event == nil or Event.idx == nil then
self:E("Skipping onEvent. Event or Event.idx unknown.")
return true
end
--position
local vec3={y=Event.pos.y, x=Event.pos.x, z=Event.pos.z}
local coord=COORDINATE:NewFromVec3(vec3)
if self.debug then
local coordtext = coord:ToStringLLDDM()
local text = tostring(Event.text)
local m = MESSAGE:New(string.format("Mark added at %s with text: %s",coordtext,text),10,"Info",false):ToAll()
end
-- decision
if Event.id==world.event.S_EVENT_MARK_ADDED then
self:T({event="S_EVENT_MARK_ADDED", carrier=self.groupname, vec3=Event.pos})
-- Handle event
local Eventtext = tostring(Event.text)
if Eventtext~=nil then
if self:_MatchTag(Eventtext) then
local matchtable = self:_MatchKeywords(Eventtext)
self:MarkAdded(Eventtext,matchtable,coord)
end
end
elseif Event.id==world.event.S_EVENT_MARK_CHANGE then
self:T({event="S_EVENT_MARK_CHANGE", carrier=self.groupname, vec3=Event.pos})
-- Handle event.
local Eventtext = tostring(Event.text)
if Eventtext~=nil then
if self:_MatchTag(Eventtext) then
local matchtable = self:_MatchKeywords(Eventtext)
self:MarkChanged(Eventtext,matchtable,coord,Event.idx)
end
end
elseif Event.id==world.event.S_EVENT_MARK_REMOVED then
self:T({event="S_EVENT_MARK_REMOVED", carrier=self.groupname, vec3=Event.pos})
-- Hande event.
local Eventtext = tostring(Event.text)
if Eventtext~=nil then
if self:_MatchTag(Eventtext) then
self:MarkDeleted()
end
end
end
end
--- (internal) Match tag.
-- @param #MARKEROPS_BASE self
-- @param #string Eventtext Text added to the marker.
-- @return #boolean
function MARKEROPS_BASE:_MatchTag(Eventtext)
local matches = false
if not self.Casesensitive then
local type = string.lower(self.Tag) -- #string
if string.find(string.lower(Eventtext),type) then
matches = true --event text contains tag
end
else
local type = self.Tag -- #string
if string.find(Eventtext,type) then
matches = true --event text contains tag
end
end
return matches
end
--- (internal) Match keywords table.
-- @param #MARKEROPS_BASE self
-- @param #string Eventtext Text added to the marker.
-- @return #table
function MARKEROPS_BASE:_MatchKeywords(Eventtext)
local matchtable = {}
local keytable = self.Keywords
for _index,_word in pairs (keytable) do
if string.find(string.lower(Eventtext),string.lower(_word))then
table.insert(matchtable,_word)
end
end
return matchtable
end
--- On before "MarkAdded" event. Triggered when a Marker is added to the F10 map.
-- @param #MARKEROPS_BASE self
-- @param #string From The From state
-- @param #string Event The Event called
-- @param #string To The To state
-- @param #string Text The text on the marker
-- @param #table Keywords Table of matching keywords found in the Event text
-- @param Core.Point#COORDINATE Coord Coordinate of the marker.
function MARKEROPS_BASE:onbeforeMarkAdded(From,Event,To,Text,Keywords,Coord)
self:T({self.lid,From,Event,To,Text,Keywords,Coord:ToStringLLDDM()})
end
--- On before "MarkChanged" event. Triggered when a Marker is changed on the F10 map.
-- @param #MARKEROPS_BASE self
-- @param #string From The From state
-- @param #string Event The Event called
-- @param #string To The To state
-- @param #string Text The text on the marker
-- @param #table Keywords Table of matching keywords found in the Event text
-- @param Core.Point#COORDINATE Coord Coordinate of the marker.
function MARKEROPS_BASE:onbeforeMarkChanged(From,Event,To,Text,Keywords,Coord)
self:T({self.lid,From,Event,To,Text,Keywords,Coord:ToStringLLDDM()})
end
--- On before "MarkDeleted" event. Triggered when a Marker is removed from the F10 map.
-- @param #MARKEROPS_BASE self
-- @param #string From The From state
-- @param #string Event The Event called
-- @param #string To The To state
function MARKEROPS_BASE:onbeforeMarkDeleted(From,Event,To)
self:T({self.lid,From,Event,To})
end
--- On enter "Stopped" event. Unsubscribe events.
-- @param #MARKEROPS_BASE self
-- @param #string From The From state
-- @param #string Event The Event called
-- @param #string To The To state
function MARKEROPS_BASE:onenterStopped(From,Event,To)
self:T({self.lid,From,Event,To})
-- unsubscribe from events
self:UnHandleEvent(EVENTS.MarkAdded)
self:UnHandleEvent(EVENTS.MarkChange)
self:UnHandleEvent(EVENTS.MarkRemoved)
end
--------------------------------------------------------------------------
-- MARKEROPS_BASE Class Definition End.
--------------------------------------------------------------------------
+26 -1
View File
@@ -239,6 +239,7 @@ do -- MENU_BASE
function MENU_BASE:GetMenu( MenuText )
return self.Menus[MenuText]
end
--- Sets a menu stamp for later prevention of menu removal.
-- @param #MENU_BASE self
-- @param MenuStamp
@@ -376,6 +377,7 @@ do -- MENU_MISSION
end
end
--- Refreshes a radio item for a mission
-- @param #MENU_MISSION self
-- @return #MENU_MISSION
@@ -813,6 +815,7 @@ do
end
end
--- Refreshes a new radio item for a group and submenus
-- @param #MENU_GROUP self
-- @return #MENU_GROUP
@@ -829,6 +832,29 @@ do
return self
end
--- Refreshes a new radio item for a group and submenus, ordering by (numerical) MenuTag
-- @param #MENU_GROUP self
-- @return #MENU_GROUP
function MENU_GROUP:RefreshAndOrderByTag()
do
missionCommands.removeItemForGroup( self.GroupID, self.MenuPath )
missionCommands.addSubMenuForGroup( self.GroupID, self.MenuText, self.MenuParentPath )
local MenuTable = {}
for MenuText, Menu in pairs( self.Menus or {} ) do
local tag = Menu.MenuTag or math.random(1,10000)
MenuTable[#MenuTable+1] = {Tag=tag, Enty=Menu}
end
table.sort(MenuTable, function (k1, k2) return k1.tag < k2.tag end )
for _, Menu in pairs( MenuTable ) do
Menu.Entry:Refresh()
end
end
return self
end
--- Removes the sub menus recursively of this MENU_GROUP.
-- @param #MENU_GROUP self
-- @param MenuStamp
@@ -1180,4 +1206,3 @@ do
return self
end
end
+80 -22
View File
@@ -11,8 +11,7 @@
-- * Send messages to a coalition.
-- * Send messages to a specific group.
-- * Send messages to a specific unit or client.
--
--
--
-- ===
--
-- @module Core.Message
@@ -35,7 +34,7 @@
--
-- Messages are sent:
--
-- * To a @{Client} using @{#MESSAGE.ToClient}().
-- * To a @{Wrapper.Client} using @{#MESSAGE.ToClient}().
-- * To a @{Wrapper.Group} using @{#MESSAGE.ToGroup}()
-- * To a @{Wrapper.Unit} using @{#MESSAGE.ToUnit}()
-- * To a coalition using @{#MESSAGE.ToCoalition}().
@@ -99,7 +98,7 @@ function MESSAGE:New( MessageText, MessageDuration, MessageCategory, ClearScreen
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 MessageCategory:sub( -1 ) ~= "\n" then
self.MessageCategory = MessageCategory .. ": "
@@ -129,7 +128,7 @@ end
--- Creates a new MESSAGE object of a certain type.
-- Note that these MESSAGE objects are not yet displayed on the display panel.
-- You must use the functions @{ToClient} or @{ToCoalition} or @{ToAll} to send these Messages to the respective recipients.
-- The message display times are automatically defined based on the timing settings in the @{Settings} menu.
-- The message display times are automatically defined based on the timing settings in the @{Core.Settings} menu.
-- @param self
-- @param #string MessageText is the text of the Message.
-- @param #MESSAGE.Type MessageType The type of the message.
@@ -172,7 +171,7 @@ end
--- Sends a MESSAGE to a Client Group. Note that the Group needs to be defined within the ME with the skillset "Client" or "Player".
-- @param #MESSAGE self
-- @param Wrapper.Client#CLIENT Client is the Group of the Client.
-- @param Core.Settings#SETTINGS Settings Settings used to display the message.
-- @param Core.Settings#SETTINGS Settings used to display the message.
-- @return #MESSAGE
-- @usage
--
@@ -183,11 +182,11 @@ end
-- MessageClient1 = MESSAGE:New( "Congratulations, you've just hit a target", "Score", 25, "Score" ):ToClient( ClientGroup )
-- MessageClient2 = MESSAGE:New( "Congratulations, you've just killed a target", "Score", 25, "Score" ):ToClient( ClientGroup )
-- or
-- MESSAGE:New( "Congratulations, you've just hit a target", "Score", 25, "Score" ):ToClient( ClientGroup )
-- MESSAGE:New( "Congratulations, you've just killed a target", "Score", 25, "Score" ):ToClient( ClientGroup )
-- MESSAGE:New( "Congratulations, you've just hit a target", "Score", 25 ):ToClient( ClientGroup )
-- MESSAGE:New( "Congratulations, you've just killed a target", "Score", 25 ):ToClient( ClientGroup )
-- or
-- MessageClient1 = MESSAGE:New( "Congratulations, you've just hit a target", "Score", 25, "Score" )
-- MessageClient2 = MESSAGE:New( "Congratulations, you've just killed a target", "Score", 25, "Score" )
-- MessageClient1 = MESSAGE:New( "Congratulations, you've just hit a target", "Score", 25 )
-- MessageClient2 = MESSAGE:New( "Congratulations, you've just killed a target", "Score", 25 )
-- MessageClient1:ToClient( ClientGroup )
-- MessageClient2:ToClient( ClientGroup )
--
@@ -218,6 +217,7 @@ end
--- Sends a MESSAGE to a Group.
-- @param #MESSAGE self
-- @param Wrapper.Group#GROUP Group to which the message is displayed.
-- @param Core.Settings#Settings Settings (Optional) Settings for message display.
-- @return #MESSAGE Message object.
function MESSAGE:ToGroup( Group, Settings )
self:F( Group.GroupName )
@@ -242,6 +242,7 @@ end
--- Sends a MESSAGE to a Unit.
-- @param #MESSAGE self
-- @param Wrapper.Unit#UNIT Unit to which the message is displayed.
-- @param Core.Settings#Settings Settings (Optional) Settings for message display.
-- @return #MESSAGE Message object.
function MESSAGE:ToUnit( Unit, Settings )
self:F( Unit.IdentifiableName )
@@ -263,17 +264,52 @@ function MESSAGE:ToUnit( Unit, Settings )
return self
end
--- Sends a MESSAGE to a Country.
-- @param #MESSAGE self
-- @param #number Country to which the message is displayed, e.g. country.id.GERMANY. For all country numbers see here: [Hoggit Wiki](https://wiki.hoggitworld.com/view/DCS_enum_country)
-- @param Core.Settings#Settings Settings (Optional) Settings for message display.
-- @return #MESSAGE Message object.
function MESSAGE:ToCountry( Country, Settings )
self:F(Country )
if Country then
if self.MessageType then
local Settings = Settings or _SETTINGS -- Core.Settings#SETTINGS
self.MessageDuration = Settings:GetMessageTime( self.MessageType )
self.MessageCategory = "" -- self.MessageType .. ": "
end
if self.MessageDuration ~= 0 then
self:T( self.MessageCategory .. self.MessageText:gsub("\n$",""):gsub("\n$","") .. " / " .. self.MessageDuration )
trigger.action.outTextForCountry( Country, self.MessageCategory .. self.MessageText:gsub("\n$",""):gsub("\n$",""), self.MessageDuration, self.ClearScreen )
end
end
return self
end
--- Sends a MESSAGE to a Country.
-- @param #MESSAGE self
-- @param #number Country to which the message is displayed, , e.g. country.id.GERMANY. For all country numbers see here: [Hoggit Wiki](https://wiki.hoggitworld.com/view/DCS_enum_country)
-- @param #boolean Condition Sends the message only if the condition is true.
-- @param Core.Settings#Settings Settings (Optional) Settings for message display.
-- @return #MESSAGE Message object.
function MESSAGE:ToCountryIf( Country, Condition, Settings )
self:F(Country )
if Country and Condition == true then
self:ToCountry( Country, Settings )
end
return self
end
--- Sends a MESSAGE to the Blue coalition.
-- @param #MESSAGE self
-- @return #MESSAGE
-- @usage
--
-- -- Send a message created with the @{New} method to the BLUE coalition.
-- MessageBLUE = MESSAGE:New( "To the BLUE Players: You receive a penalty because you've killed one of your own units", "Penalty", 25, "Score" ):ToBlue()
-- MessageBLUE = MESSAGE:New( "To the BLUE Players: You receive a penalty because you've killed one of your own units", "Penalty", 25):ToBlue()
-- or
-- MESSAGE:New( "To the BLUE Players: You receive a penalty because you've killed one of your own units", "Penalty", 25, "Score" ):ToBlue()
-- MESSAGE:New( "To the BLUE Players: You receive a penalty because you've killed one of your own units", "Penalty", 25 ):ToBlue()
-- or
-- MessageBLUE = MESSAGE:New( "To the BLUE Players: You receive a penalty because you've killed one of your own units", "Penalty", 25, "Score" )
-- MessageBLUE = MESSAGE:New( "To the BLUE Players: You receive a penalty because you've killed one of your own units", "Penalty", 25 )
-- MessageBLUE:ToBlue()
--
function MESSAGE:ToBlue()
@@ -290,11 +326,11 @@ end
-- @usage
--
-- -- Send a message created with the @{New} method to the RED coalition.
-- MessageRED = MESSAGE:New( "To the RED Players: You receive a penalty because you've killed one of your own units", "Penalty", 25, "Score" ):ToRed()
-- MessageRED = MESSAGE:New( "To the RED Players: You receive a penalty because you've killed one of your own units", "Penalty", 25 ):ToRed()
-- or
-- MESSAGE:New( "To the RED Players: You receive a penalty because you've killed one of your own units", "Penalty", 25, "Score" ):ToRed()
-- MESSAGE:New( "To the RED Players: You receive a penalty because you've killed one of your own units", "Penalty", 25 ):ToRed()
-- or
-- MessageRED = MESSAGE:New( "To the RED Players: You receive a penalty because you've killed one of your own units", "Penalty", 25, "Score" )
-- MessageRED = MESSAGE:New( "To the RED Players: You receive a penalty because you've killed one of your own units", "Penalty", 25 )
-- MessageRED:ToRed()
--
function MESSAGE:ToRed()
@@ -313,11 +349,11 @@ end
-- @usage
--
-- -- Send a message created with the @{New} method to the RED coalition.
-- MessageRED = MESSAGE:New( "To the RED Players: You receive a penalty because you've killed one of your own units", "Penalty", 25, "Score" ):ToCoalition( coalition.side.RED )
-- MessageRED = MESSAGE:New( "To the RED Players: You receive a penalty because you've killed one of your own units", "Penalty", 25 ):ToCoalition( coalition.side.RED )
-- or
-- MESSAGE:New( "To the RED Players: You receive a penalty because you've killed one of your own units", "Penalty", 25, "Score" ):ToCoalition( coalition.side.RED )
-- MESSAGE:New( "To the RED Players: You receive a penalty because you've killed one of your own units", "Penalty", 25 ):ToCoalition( coalition.side.RED )
-- or
-- MessageRED = MESSAGE:New( "To the RED Players: You receive a penalty because you've killed one of your own units", "Penalty", 25, "Score" )
-- MessageRED = MESSAGE:New( "To the RED Players: You receive a penalty because you've killed one of your own units", "Penalty", 25 )
-- MessageRED:ToCoalition( coalition.side.RED )
--
function MESSAGE:ToCoalition( CoalitionSide, Settings )
@@ -361,11 +397,11 @@ end
-- @usage
--
-- -- Send a message created to all players.
-- MessageAll = MESSAGE:New( "To all Players: BLUE has won! Each player of BLUE wins 50 points!", "End of Mission", 25, "Win" ):ToAll()
-- MessageAll = MESSAGE:New( "To all Players: BLUE has won! Each player of BLUE wins 50 points!", "End of Mission", 25 ):ToAll()
-- or
-- MESSAGE:New( "To all Players: BLUE has won! Each player of BLUE wins 50 points!", "End of Mission", 25, "Win" ):ToAll()
-- MESSAGE:New( "To all Players: BLUE has won! Each player of BLUE wins 50 points!", "End of Mission", 25 ):ToAll()
-- or
-- MessageAll = MESSAGE:New( "To all Players: BLUE has won! Each player of BLUE wins 50 points!", "End of Mission", 25, "Win" )
-- MessageAll = MESSAGE:New( "To all Players: BLUE has won! Each player of BLUE wins 50 points!", "End of Mission", 25 )
-- MessageAll:ToAll()
--
function MESSAGE:ToAll( Settings )
@@ -387,6 +423,7 @@ end
--- Sends a MESSAGE to all players if the given Condition is true.
-- @param #MESSAGE self
-- @param #boolean Condition
-- @return #MESSAGE
function MESSAGE:ToAllIf( Condition )
@@ -396,3 +433,24 @@ function MESSAGE:ToAllIf( Condition )
return self
end
--- Sends a MESSAGE to DCS log file.
-- @param #MESSAGE self
-- @return #MESSAGE self
function MESSAGE:ToLog()
env.info(self.MessageCategory .. self.MessageText:gsub( "\n$", "" ):gsub( "\n$", "" ))
return self
end
--- Sends a MESSAGE to DCS log file if the given Condition is true.
-- @param #MESSAGE self
-- @return #MESSAGE self
function MESSAGE:ToLogIf( Condition )
if Condition and Condition == true then
env.info(self.MessageCategory .. self.MessageText:gsub( "\n$", "" ):gsub( "\n$", "" ))
end
return self
end
+370
View File
@@ -0,0 +1,370 @@
--- **Core** - Path from A to B.
--
-- **Main Features:**
--
-- * Path from A to B
-- * Arbitrary number of points
-- * Automatically from lines drawtool
--
-- ===
--
-- ### Author: **funkyfranky**
--
-- ===
-- @module Core.Pathline
-- @image CORE_Pathline.png
--- PATHLINE class.
-- @type PATHLINE
-- @field #string ClassName Name of the class.
-- @field #string lid Class id string for output to DCS log file.
-- @field #string name Name of the path line.
-- @field #table points List of 3D points defining the path.
-- @extends Core.Base#BASE
--- *The shortest distance between two points is a straight line.* -- Archimedes
--
-- ===
--
-- # The PATHLINE Concept
--
-- List of points defining a path from A to B. The pathline can consist of multiple points. Each point holds the information of its position, the surface type, the land height
-- and the water depth (if over sea).
--
-- Line drawings created in the mission editor are automatically registered as pathlines and stored in the MOOSE database.
-- They can be accessed with the @{#PATHLINE.FindByName) function.
--
-- # Constructor
--
-- The @{PATHLINE.New) function creates a new PATHLINE object. This does not hold any points. Points can be added with the @{#PATHLINE.AddPointFromVec2} and @{#PATHLINE.AddPointFromVec3}
--
-- For a given table of 2D or 3D positions, a new PATHLINE object can be created with the @{#PATHLINE.NewFromVec2Array} or @{#PATHLINE.NewFromVec3Array}, respectively.
--
-- # Line Drawings
--
-- The most convenient way to create a pathline is the draw panel feature in the DCS mission editor. You can select "Line" and then "Segments", "Segment" or "Free" to draw your lines.
-- These line drawings are then automatically added to the MOOSE database as PATHLINE objects and can be retrieved with the @{#PATHLINE.FindByName) function, where the name is the one
-- you specify in the draw panel.
--
-- # Mark on F10 map
--
-- The ponints of the PATHLINE can be marked on the F10 map with the @{#PATHLINE.MarkPoints}(`true`) function. The mark points contain information of the surface type, land height and
-- water depth.
--
-- To remove the marks, use @{#PATHLINE.MarkPoints}(`false`).
--
-- @field #PATHLINE
PATHLINE = {
ClassName = "PATHLINE",
lid = nil,
points = {},
}
--- Point of line.
-- @type PATHLINE.Point
-- @field DCS#Vec3 vec3 3D position.
-- @field DCS#Vec2 vec2 2D position.
-- @field #number surfaceType Surface type.
-- @field #number landHeight Land height in meters.
-- @field #number depth Water depth in meters.
-- @field #number markerID Marker ID.
--- PATHLINE class version.
-- @field #string version
PATHLINE.version="0.1.0"
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO list
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO: A lot...
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Constructor
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- Create a new PATHLINE object. Points need to be added later.
-- @param #PATHLINE self
-- @param #string Name Name of the path.
-- @return #PATHLINE self
function PATHLINE:New(Name)
-- Inherit everything from INTEL class.
local self=BASE:Inherit(self, BASE:New()) --#PATHLINE
self.name=Name or "Unknown Path"
self.lid=string.format("PATHLINE %s | ", Name)
return self
end
--- Create a new PATHLINE object from a given list of 2D points.
-- @param #PATHLINE self
-- @param #string Name Name of the pathline.
-- @param #table Vec2Array List of DCS#Vec2 points.
-- @return #PATHLINE self
function PATHLINE:NewFromVec2Array(Name, Vec2Array)
local self=PATHLINE:New(Name)
for i=1,#Vec2Array do
self:AddPointFromVec2(Vec2Array[i])
end
return self
end
--- Create a new PATHLINE object from a given list of 3D points.
-- @param #PATHLINE self
-- @param #string Name Name of the pathline.
-- @param #table Vec3Array List of DCS#Vec3 points.
-- @return #PATHLINE self
function PATHLINE:NewFromVec3Array(Name, Vec3Array)
local self=PATHLINE:New(Name)
for i=1,#Vec3Array do
self:AddPointFromVec3(Vec3Array[i])
end
return self
end
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- User functions
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- Find a pathline in the database.
-- @param #PATHLINE self
-- @param #string Name The name of the pathline.
-- @return #PATHLINE self
function PATHLINE:FindByName(Name)
local pathline = _DATABASE:FindPathline(Name)
return pathline
end
--- Add a point to the path from a given 2D position. The third dimension is determined from the land height.
-- @param #PATHLINE self
-- @param DCS#Vec2 Vec2 The 2D vector (x,y) to add.
-- @return #PATHLINE self
function PATHLINE:AddPointFromVec2(Vec2)
if Vec2 then
local point=self:_CreatePoint(Vec2)
table.insert(self.points, point)
end
return self
end
--- Add a point to the path from a given 3D position.
-- @param #PATHLINE self
-- @param DCS#Vec3 Vec3 The 3D vector (x,y) to add.
-- @return #PATHLINE self
function PATHLINE:AddPointFromVec3(Vec3)
if Vec3 then
local point=self:_CreatePoint(Vec3)
table.insert(self.points, point)
end
return self
end
--- Get name of pathline.
-- @param #PATHLINE self
-- @return #string Name of the pathline.
function PATHLINE:GetName()
return self.name
end
--- Get number of points.
-- @param #PATHLINE self
-- @return #number Number of points.
function PATHLINE:GetNumberOfPoints()
local N=#self.points
return N
end
--- Get points of pathline. Not that points are tables, that contain more information as just the 2D or 3D position but also the surface type etc.
-- @param #PATHLINE self
-- @return <#PATHLINE.Point> List of points.
function PATHLINE:GetPoints()
return self.points
end
--- Get 3D points of pathline.
-- @param #PATHLINE self
-- @return <DCS#Vec3> List of DCS#Vec3 points.
function PATHLINE:GetPoints3D()
local vecs={}
for _,_point in pairs(self.points) do
local point=_point --#PATHLINE.Point
table.insert(vecs, point.vec3)
end
return vecs
end
--- Get 2D points of pathline.
-- @param #PATHLINE self
-- @return <DCS#Vec2> List of DCS#Vec2 points.
function PATHLINE:GetPoints2D()
local vecs={}
for _,_point in pairs(self.points) do
local point=_point --#PATHLINE.Point
table.insert(vecs, point.vec2)
end
return vecs
end
--- Get COORDINATES of pathline. Note that COORDINATE objects are created when calling this function. That does involve deep copy calls and can have an impact on performance if done too often.
-- @param #PATHLINE self
-- @return <Core.Point#COORDINATE> List of COORDINATES points.
function PATHLINE:GetCoordinats()
local vecs={}
for _,_point in pairs(self.points) do
local point=_point --#PATHLINE.Point
local coord=COORDINATE:NewFromVec3(point.vec3)
end
return vecs
end
--- Get the n-th point of the pathline.
-- @param #PATHLINE self
-- @param #number n The index of the point. Default is the first point.
-- @return #PATHLINE.Point Point.
function PATHLINE:GetPointFromIndex(n)
local N=self:GetNumberOfPoints()
n=n or 1
local point=nil --#PATHLINE.Point
if n>=1 and n<=N then
point=self.point[n]
else
self:E(self.lid..string.format("ERROR: No point in pathline for N=%s", tostring(n)))
end
return point
end
--- Get the 3D position of the n-th point.
-- @param #PATHLINE self
-- @param #number n The n-th point.
-- @return DCS#VEC3 Position in 3D.
function PATHLINE:GetPoint3DFromIndex(n)
local point=self:GetPointFromIndex(n)
if point then
return point.vec3
end
return nil
end
--- Get the 2D position of the n-th point.
-- @param #PATHLINE self
-- @param #number n The n-th point.
-- @return DCS#VEC2 Position in 3D.
function PATHLINE:GetPoint2DFromIndex(n)
local point=self:GetPointFromIndex(n)
if point then
return point.vec2
end
return nil
end
--- Mark points on F10 map.
-- @param #PATHLINE self
-- @param #boolean Switch If `true` or nil, set marks. If `false`, remove marks.
-- @return <DCS#Vec3> List of DCS#Vec3 points.
function PATHLINE:MarkPoints(Switch)
for i,_point in pairs(self.points) do
local point=_point --#PATHLINE.Point
if Switch==false then
if point.markerID then
UTILS.RemoveMark(point.markerID, Delay)
end
else
if point.markerID then
UTILS.RemoveMark(point.markerID)
end
point.markerID=UTILS.GetMarkID()
local text=string.format("Pathline %s: Point #%d\nSurface Type=%d\nHeight=%.1f m\nDepth=%.1f m", self.name, i, point.surfaceType, point.landHeight, point.depth)
trigger.action.markToAll(point.markerID, text, point.vec3, "")
end
end
end
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Private functions
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- Get 3D points of pathline.
-- @param #PATHLINE self
-- @param DCS#Vec3 Vec Position vector. Can also be a DCS#Vec2 in which case the altitude at landheight is taken.
-- @return #PATHLINE.Point
function PATHLINE:_CreatePoint(Vec)
local point={} --#PATHLINE.Point
if Vec.z then
-- Given vec is 3D
point.vec3=UTILS.DeepCopy(Vec)
point.vec2={x=Vec.x, y=Vec.z}
else
-- Given vec is 2D
point.vec2=UTILS.DeepCopy(Vec)
point.vec3={x=Vec.x, y=land.getHeight(Vec), z=Vec.y}
end
-- Get surface type.
point.surfaceType=land.getSurfaceType(point.vec2)
-- Get land height and depth.
point.landHeight, point.depth=land.getSurfaceHeightWithSeabed(point.vec2)
point.markerID=nil
return point
end
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+343 -111
View File
@@ -138,7 +138,7 @@ do -- COORDINATE
--
-- Calculate if the coordinate has Line of Sight (LOS) with the other given coordinate.
-- Mountains, trees and other objects can be positioned between the two 3D points, preventing visibilty in a straight continuous line.
-- The method @{#COORDINATE.IsLOS}() returns if the two coodinates have LOS.
-- The method @{#COORDINATE.IsLOS}() returns if the two coordinates have LOS.
--
-- ## 4.7) Check the coordinate position.
--
@@ -406,6 +406,42 @@ do -- COORDINATE
return self
end
--- Returns the magnetic declination at the given coordinate.
-- NOTE that this needs `require` to be available so you need to desanitize the `MissionScripting.lua` file in your DCS/Scrips folder.
-- If `require` is not available, a constant value for the whole map.
-- @param #COORDINATE self
-- @param #number Month (Optional) The month at which the declination is calculated. Default is the mission month.
-- @param #number Year (Optional) The year at which the declination is calculated. Default is the mission year.
-- @return #number Magnetic declination in degrees.
function COORDINATE:GetMagneticDeclination(Month, Year)
local decl=UTILS.GetMagneticDeclination()
if require then
local magvar = require('magvar')
if magvar then
local date, year, month, day=UTILS.GetDCSMissionDate()
magvar.init(Month or month, Year or year)
local lat, lon=self:GetLLDDM()
decl=magvar.get_mag_decl(lat, lon)
if decl then
decl=math.deg(decl)
end
end
else
self:T("The require package is not available. Using constant value for magnetic declination")
end
return decl
end
--- Returns the coordinate from the latitude and longitude given in decimal degrees.
-- @param #COORDINATE self
@@ -567,6 +603,46 @@ do -- COORDINATE
return set
end
--- Scan/find STATICS within a certain radius around the coordinate using the world.searchObjects() DCS API function.
-- @param #COORDINATE self
-- @param #number radius (Optional) Scan radius in meters. Default 100 m.
-- @return Core.Set#SET_UNIT Set of units.
function COORDINATE:ScanStatics(radius)
local _,_,_,_,statics=self:ScanObjects(radius, false, true, false)
local set=SET_STATIC:New()
for _,stat in pairs(statics) do
set:AddStatic(STATIC:Find(stat))
end
return set
end
--- Find the closest static to the COORDINATE within a certain radius.
-- @param #COORDINATE self
-- @param #number radius Scan radius in meters. Default 100 m.
-- @return Wrapper.Static#STATIC The closest static or #nil if no unit is inside the given radius.
function COORDINATE:FindClosestStatic(radius)
local units=self:ScanStatics(radius)
local umin=nil --Wrapper.Unit#UNIT
local dmin=math.huge
for _,_unit in pairs(units.Set) do
local unit=_unit --Wrapper.Static#STATIC
local coordinate=unit:GetCoordinate()
local d=self:Get2DDistance(coordinate)
if d<dmin then
dmin=d
umin=unit
end
end
return umin
end
--- Find the closest unit to the COORDINATE within a certain radius.
-- @param #COORDINATE self
@@ -594,13 +670,13 @@ do -- COORDINATE
--- Scan/find SCENERY objects within a certain radius around the coordinate using the world.searchObjects() DCS API function.
-- @param #COORDINATE self
-- @param #number radius (Optional) Scan radius in meters. Default 100 m.
-- @return table Set of scenery objects.
-- @return table Table of SCENERY objects.
function COORDINATE:ScanScenery(radius)
local _,_,_,_,_,scenerys=self:ScanObjects(radius, false, false, true)
local set={}
for _,_scenery in pairs(scenerys) do
local scenery=_scenery --DCS#Object
@@ -654,7 +730,7 @@ do -- COORDINATE
-- @param DCS#Distance Distance The Distance to be added in meters.
-- @param DCS#Angle Angle The Angle in degrees. Defaults to 0 if not specified (nil).
-- @param #boolean Keepalt If true, keep altitude of original coordinate. Default is that the new coordinate is created at the translated land height.
-- @param #boolean Overwrite If true, overwrite the original COORDINATE with the translated one. Otherwise, create a new COODINATE.
-- @param #boolean Overwrite If true, overwrite the original COORDINATE with the translated one. Otherwise, create a new COORDINATE.
-- @return #COORDINATE The new calculated COORDINATE.
function COORDINATE:Translate( Distance, Angle, Keepalt, Overwrite )
@@ -825,7 +901,11 @@ do -- COORDINATE
-- @param #COORDINATE TargetCoordinate The target COORDINATE.
-- @return DCS#Vec3 DirectionVec3 The direction vector in Vec3 format.
function COORDINATE:GetDirectionVec3( TargetCoordinate )
return { x = TargetCoordinate.x - self.x, y = TargetCoordinate.y - self.y, z = TargetCoordinate.z - self.z }
if TargetCoordinate then
return { x = TargetCoordinate.x - self.x, y = TargetCoordinate.y - self.y, z = TargetCoordinate.z - self.z }
else
return { x=0,y=0,z=0}
end
end
@@ -874,6 +954,11 @@ do -- COORDINATE
-- Get the vector from A to B
local vec=UTILS.VecSubstract(ToCoordinate, self)
if f>1 then
local norm=UTILS.VecNorm(vec)
f=Fraction/norm
end
-- Scale the vector.
vec.x=f*vec.x
@@ -883,7 +968,9 @@ do -- COORDINATE
-- Move the vector to start at the end of A.
vec=UTILS.VecAdd(self, vec)
-- Create a new coordiante object.
local coord=COORDINATE:New(vec.x,vec.y,vec.z)
return coord
end
@@ -912,7 +999,7 @@ do -- COORDINATE
return T-273.15
end
--- Returns a text of the temperature according the measurement system @{Settings}.
--- Returns a text of the temperature according the measurement system @{Core.Settings}.
-- The text will reflect the temperature like this:
--
-- - For Russian and European aircraft using the metric system - Degrees Celcius (°C)
@@ -925,7 +1012,7 @@ do -- COORDINATE
--
-- @param #COORDINATE self
-- @param height (Optional) parameter specifying the height ASL.
-- @return #string Temperature according the measurement system @{Settings}.
-- @return #string Temperature according the measurement system @{Core.Settings}.
function COORDINATE:GetTemperatureText( height, Settings )
local DegreesCelcius = self:GetTemperature( height )
@@ -958,7 +1045,7 @@ do -- COORDINATE
return P/100
end
--- Returns a text of the pressure according the measurement system @{Settings}.
--- Returns a text of the pressure according the measurement system @{Core.Settings}.
-- The text will contain always the pressure in hPa and:
--
-- - For Russian and European aircraft using the metric system - hPa and mmHg
@@ -971,7 +1058,7 @@ do -- COORDINATE
--
-- @param #COORDINATE self
-- @param height (Optional) parameter specifying the height ASL. E.g. set height=0 for QNH.
-- @return #string Pressure in hPa and mmHg or inHg depending on the measurement system @{Settings}.
-- @return #string Pressure in hPa and mmHg or inHg depending on the measurement system @{Core.Settings}.
function COORDINATE:GetPressureText( height, Settings )
local Pressure_hPa = self:GetPressure( height )
@@ -1007,28 +1094,55 @@ do -- COORDINATE
return heading
end
--- Returns the 3D wind direction vector. Note that vector points into the direction the wind in blowing to.
-- @param #COORDINATE self
-- @param #number height (Optional) parameter specifying the height ASL in meters. The minimum height will be always be the land height since the wind is zero below the ground.
-- @param #boolean turbulence (Optional) If `true`, include turbulence.
-- @return DCS#Vec3 Wind 3D vector. Components in m/s.
function COORDINATE:GetWindVec3(height, turbulence)
-- We at 0.1 meters to be sure to be above ground since wind is zero below ground level.
local landheight=self:GetLandHeight()+0.1
local point={x=self.x, y=math.max(height or self.y, landheight), z=self.z}
-- Get wind velocity vector.
local wind = nil --DCS#Vec3
if turbulence then
wind = atmosphere.getWindWithTurbulence(point)
else
wind = atmosphere.getWind(point)
end
return wind
end
--- Returns the wind direction (from) and strength.
-- @param #COORDINATE self
-- @param height (Optional) parameter specifying the height ASL. The minimum height will be always be the land height since the wind is zero below the ground.
-- @return Direction the wind is blowing from in degrees.
-- @return Wind strength in m/s.
function COORDINATE:GetWind(height)
local landheight=self:GetLandHeight()+0.1 -- we at 0.1 meters to be sure to be above ground since wind is zero below ground level.
local point={x=self.x, y=math.max(height or self.y, landheight), z=self.z}
-- get wind velocity vector
local wind = atmosphere.getWind(point)
local direction = math.deg(math.atan2(wind.z, wind.x))
if direction < 0 then
direction = 360 + direction
end
-- Convert to direction to from direction
-- @param #number height (Optional) parameter specifying the height ASL. The minimum height will be always be the land height since the wind is zero below the ground.
-- @param #boolean turbulence If `true`, include turbulence. If `false` or `nil`, wind without turbulence.
-- @return #number Direction the wind is blowing from in degrees.
-- @return #number Wind strength in m/s.
function COORDINATE:GetWind(height, turbulence)
-- Get wind velocity vector
local wind = self:GetWindVec3(height, turbulence)
-- Calculate the direction of the vector.
local direction=UTILS.VecHdg(wind)
-- Invert "to" direction to "from" direction.
if direction > 180 then
direction = direction-180
else
direction = direction+180
end
local strength=math.sqrt((wind.x)^2+(wind.z)^2)
-- Return wind direction and strength km/h.
-- Wind strength in m/s.
local strength=UTILS.VecNorm(wind) -- math.sqrt((wind.x)^2+(wind.z)^2)
-- Return wind direction and strength.
return direction, strength
end
@@ -1051,7 +1165,7 @@ do -- COORDINATE
end
--- Returns a text documenting the wind direction (from) and strength according the measurement system @{Settings}.
--- Returns a text documenting the wind direction (from) and strength according the measurement system @{Core.Settings}.
-- The text will reflect the wind like this:
--
-- - For Russian and European aircraft using the metric system - Wind direction in degrees (°) and wind speed in meters per second (mps).
@@ -1064,7 +1178,7 @@ do -- COORDINATE
--
-- @param #COORDINATE self
-- @param height (Optional) parameter specifying the height ASL. The minimum height will be always be the land height since the wind is zero below the ground.
-- @return #string Wind direction and strength according the measurement system @{Settings}.
-- @return #string Wind direction and strength according the measurement system @{Core.Settings}.
function COORDINATE:GetWindText( height, Settings )
local Direction, Strength = self:GetWind( height )
@@ -1086,12 +1200,15 @@ do -- COORDINATE
--- Return the 3D distance in meters between the target COORDINATE and the COORDINATE.
-- @param #COORDINATE self
-- @param #COORDINATE TargetCoordinate The target COORDINATE.
-- @param #COORDINATE TargetCoordinate The target COORDINATE. Can also be a DCS#Vec3.
-- @return DCS#Distance Distance The distance in meters.
function COORDINATE:Get3DDistance( TargetCoordinate )
local TargetVec3 = TargetCoordinate:GetVec3()
--local TargetVec3 = TargetCoordinate:GetVec3()
local TargetVec3 = {x=TargetCoordinate.x, y=TargetCoordinate.y, z=TargetCoordinate.z}
local SourceVec3 = self:GetVec3()
return ( ( TargetVec3.x - SourceVec3.x ) ^ 2 + ( TargetVec3.y - SourceVec3.y ) ^ 2 + ( TargetVec3.z - SourceVec3.z ) ^ 2 ) ^ 0.5
--local dist=( ( TargetVec3.x - SourceVec3.x ) ^ 2 + ( TargetVec3.y - SourceVec3.y ) ^ 2 + ( TargetVec3.z - SourceVec3.z ) ^ 2 ) ^ 0.5
local dist=UTILS.VecDist3D(TargetVec3, SourceVec3)
return dist
end
@@ -1100,15 +1217,25 @@ do -- COORDINATE
-- @param #number AngleRadians The angle in randians.
-- @param #number Precision The precision.
-- @param Core.Settings#SETTINGS Settings
-- @param #boolean MagVar If true, include magentic degrees
-- @return #string The bearing text in degrees.
function COORDINATE:GetBearingText( AngleRadians, Precision, Settings, Language )
function COORDINATE:GetBearingText( AngleRadians, Precision, Settings, MagVar )
local Settings = Settings or _SETTINGS -- Core.Settings#SETTINGS
local AngleDegrees = UTILS.Round( UTILS.ToDegree( AngleRadians ), Precision )
local s = string.format( '%03d°', AngleDegrees )
if MagVar then
local variation = UTILS.GetMagneticDeclination() or 0
local AngleMagnetic = AngleDegrees - variation
if AngleMagnetic < 0 then AngleMagnetic = 360-AngleMagnetic end
s = string.format( '%03d°M|%03d°', AngleMagnetic,AngleDegrees )
end
return s
end
@@ -1122,21 +1249,22 @@ do -- COORDINATE
function COORDINATE:GetDistanceText( Distance, Settings, Language, Precision )
local Settings = Settings or _SETTINGS -- Core.Settings#SETTINGS
local Language = Language or "EN"
local Language = Language or Settings.Locale or _SETTINGS.Locale or "EN"
Language = string.lower(Language)
local Precision = Precision or 0
local DistanceText
if Settings:IsMetric() then
if Language == "EN" then
if Language == "en" then
DistanceText = " for " .. UTILS.Round( Distance / 1000, Precision ) .. " km"
elseif Language == "RU" then
elseif Language == "ru" then
DistanceText = " за " .. UTILS.Round( Distance / 1000, Precision ) .. " километров"
end
else
if Language == "EN" then
if Language == "en" then
DistanceText = " for " .. UTILS.Round( UTILS.MetersToNM( Distance ), Precision ) .. " miles"
elseif Language == "RU" then
elseif Language == "ru" then
DistanceText = " за " .. UTILS.Round( UTILS.MetersToNM( Distance ), Precision ) .. " миль"
end
end
@@ -1150,19 +1278,21 @@ do -- COORDINATE
function COORDINATE:GetAltitudeText( Settings, Language )
local Altitude = self.y
local Settings = Settings or _SETTINGS
local Language = Language or "EN"
local Language = Language or Settings.Locale or _SETTINGS.Locale or "EN"
Language = string.lower(Language)
if Altitude ~= 0 then
if Settings:IsMetric() then
if Language == "EN" then
if Language == "en" then
return " at " .. UTILS.Round( self.y, -3 ) .. " meters"
elseif Language == "RU" then
elseif Language == "ru" then
return " в " .. UTILS.Round( self.y, -3 ) .. " метры"
end
else
if Language == "EN" then
if Language == "en" then
return " at " .. UTILS.Round( UTILS.MetersToFeet( self.y ), -3 ) .. " feet"
elseif Language == "RU" then
elseif Language == "ru" then
return " в " .. UTILS.Round( self.y, -3 ) .. " ноги"
end
end
@@ -1209,12 +1339,14 @@ do -- COORDINATE
-- @param #number AngleRadians The angle in randians
-- @param #number Distance The distance
-- @param Core.Settings#SETTINGS Settings
-- @param #string Language (Optional) Language "en" or "ru"
-- @param #boolean MagVar If true, also state angle in magnetic
-- @return #string The BR Text
function COORDINATE:GetBRText( AngleRadians, Distance, Settings, Language )
function COORDINATE:GetBRText( AngleRadians, Distance, Settings, Language, MagVar )
local Settings = Settings or _SETTINGS -- Core.Settings#SETTINGS
local BearingText = self:GetBearingText( AngleRadians, 0, Settings, Language )
local BearingText = self:GetBearingText( AngleRadians, 0, Settings, MagVar )
local DistanceText = self:GetDistanceText( Distance, Settings, Language, 0 )
local BRText = BearingText .. DistanceText
@@ -1227,12 +1359,14 @@ do -- COORDINATE
-- @param #number AngleRadians The angle in randians
-- @param #number Distance The distance
-- @param Core.Settings#SETTINGS Settings
-- @param #string Language (Optional) Language "en" or "ru"
-- @param #boolean MagVar If true, also state angle in magnetic
-- @return #string The BRA Text
function COORDINATE:GetBRAText( AngleRadians, Distance, Settings, Language )
function COORDINATE:GetBRAText( AngleRadians, Distance, Settings, Language, MagVar )
local Settings = Settings or _SETTINGS -- Core.Settings#SETTINGS
local BearingText = self:GetBearingText( AngleRadians, 0, Settings, Language )
local BearingText = self:GetBearingText( AngleRadians, 0, Settings, MagVar )
local DistanceText = self:GetDistanceText( Distance, Settings, Language, 0 )
local AltitudeText = self:GetAltitudeText( Settings, Language )
@@ -1257,7 +1391,15 @@ do -- COORDINATE
self.y=alt
return self
end
--- Set altitude to be at land height (i.e. on the ground!)
-- @param #COORDINATE self
function COORDINATE:SetAtLandheight()
local alt=self:GetLandHeight()
self.y=alt
return self
end
--- Build an air type route point.
-- @param #COORDINATE self
-- @param #COORDINATE.WaypointAltType AltType The altitude type.
@@ -1508,7 +1650,7 @@ do -- COORDINATE
-- @param #number Coalition (Optional) Coalition of the airbase.
-- @return Wrapper.Airbase#AIRBASE Closest Airbase to the given coordinate.
-- @return #number Distance to the closest airbase in meters.
function COORDINATE:GetClosestAirbase2(Category, Coalition)
function COORDINATE:GetClosestAirbase(Category, Coalition)
-- Get all airbases of the map.
local airbases=AIRBASE.GetAllAirbases(Coalition)
@@ -1542,34 +1684,15 @@ do -- COORDINATE
return closest,distmin
end
--- Gets the nearest airbase with respect to the current coordinates.
--- [kept for downwards compatibility only] Gets the nearest airbase with respect to the current coordinates.
-- @param #COORDINATE self
-- @param #number Category (Optional) Category of the airbase. Enumerator of @{Wrapper.Airbase#AIRBASE.Category}.
-- @param #number Coalition (Optional) Coalition of the airbase.
-- @return Wrapper.Airbase#AIRBASE Closest Airbase to the given coordinate.
-- @return #number Distance to the closest airbase in meters.
function COORDINATE:GetClosestAirbase(Category, Coalition)
local a=self: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)
--env.info(string.format("Airbase %s dist=%d category=%d", DCSairbase:getName(), dist, DCSairbase:getCategory()))
if dist<distmin and (Category==nil or Category==DCSairbase:getDesc().category) then
distmin=dist
airbase=DCSairbase
end
end
return AIRBASE:Find(airbase)
function COORDINATE:GetClosestAirbase2(Category, Coalition)
local closest, distmin = self:GetClosestAirbase(Category, Coalition)
return closest, distmin
end
--- Gets the nearest parking spot.
@@ -1902,7 +2025,6 @@ do -- COORDINATE
-- @param #COORDINATE self
-- @param #string name (Optional) Name of the fire to stop it, if not using the same COORDINATE object.
function COORDINATE:StopBigSmokeAndFire( name )
self:F2( { name = name } )
name = name or self.firename
trigger.action.effectSmokeStop( name )
end
@@ -2267,7 +2389,7 @@ do -- COORDINATE
end
--- Creates a free form shape on the F10 map. The first point is the current COORDINATE. The remaining points need to be specified.
-- **NOTE**: A free form polygon must have **at least three points** in total and currently only **up to 10 points** in total are supported.
-- **NOTE**: A free form polygon must have **at least three points** in total and currently only **up to 15 points** in total are supported.
-- @param #COORDINATE self
-- @param #table Coordinates Table of coordinates of the remaining points of the shape.
-- @param #number Coalition Coalition: All=-1, Neutral=0, Red=1, Blue=2. Default -1=All.
@@ -2320,8 +2442,28 @@ do -- COORDINATE
trigger.action.markupToAll(7, Coalition, MarkID, vecs[1], vecs[2], vecs[3], vecs[4], vecs[5], vecs[6], vecs[7], vecs[8], vecs[9], Color, FillColor, LineType, ReadOnly, Text or "")
elseif #vecs==10 then
trigger.action.markupToAll(7, Coalition, MarkID, vecs[1], vecs[2], vecs[3], vecs[4], vecs[5], vecs[6], vecs[7], vecs[8], vecs[9], vecs[10], Color, FillColor, LineType, ReadOnly, Text or "")
elseif #vecs==11 then
trigger.action.markupToAll(7, Coalition, MarkID, vecs[1], vecs[2], vecs[3], vecs[4], vecs[5], vecs[6], vecs[7], vecs[8], vecs[9], vecs[10],
vecs[11],
Color, FillColor, LineType, ReadOnly, Text or "")
elseif #vecs==12 then
trigger.action.markupToAll(7, Coalition, MarkID, vecs[1], vecs[2], vecs[3], vecs[4], vecs[5], vecs[6], vecs[7], vecs[8], vecs[9], vecs[10],
vecs[11], vecs[12],
Color, FillColor, LineType, ReadOnly, Text or "")
elseif #vecs==13 then
trigger.action.markupToAll(7, Coalition, MarkID, vecs[1], vecs[2], vecs[3], vecs[4], vecs[5], vecs[6], vecs[7], vecs[8], vecs[9], vecs[10],
vecs[11], vecs[12], vecs[13],
Color, FillColor, LineType, ReadOnly, Text or "")
elseif #vecs==14 then
trigger.action.markupToAll(7, Coalition, MarkID, vecs[1], vecs[2], vecs[3], vecs[4], vecs[5], vecs[6], vecs[7], vecs[8], vecs[9], vecs[10],
vecs[11], vecs[12], vecs[13], vecs[14],
Color, FillColor, LineType, ReadOnly, Text or "")
elseif #vecs==15 then
trigger.action.markupToAll(7, Coalition, MarkID, vecs[1], vecs[2], vecs[3], vecs[4], vecs[5], vecs[6], vecs[7], vecs[8], vecs[9], vecs[10],
vecs[11], vecs[12], vecs[13], vecs[14], vecs[15],
Color, FillColor, LineType, ReadOnly, Text or "")
else
self:E("ERROR: Currently a free form polygon can only have 10 points in total!")
self:E("ERROR: Currently a free form polygon can only have 15 points in total!")
-- Unfortunately, unpack(vecs) does not work! So no idea how to generalize this :(
trigger.action.markupToAll(7, Coalition, MarkID, unpack(vecs), Color, FillColor, LineType, ReadOnly, Text or "")
end
@@ -2743,25 +2885,27 @@ do -- COORDINATE
-- @param #COORDINATE self
-- @param #COORDINATE FromCoordinate The coordinate to measure the distance and the bearing from.
-- @param Core.Settings#SETTINGS Settings (optional) The settings. Can be nil, and in this case the default settings are used. If you want to specify your own settings, use the _SETTINGS object.
-- @param #boolean MagVar If true, also get angle in MagVar for BR/BRA
-- @return #string The BR text.
function COORDINATE:ToStringBR( FromCoordinate, Settings )
function COORDINATE:ToStringBR( FromCoordinate, Settings, MagVar )
local DirectionVec3 = FromCoordinate:GetDirectionVec3( self )
local AngleRadians = self:GetAngleRadians( DirectionVec3 )
local Distance = self:Get2DDistance( FromCoordinate )
return "BR, " .. self:GetBRText( AngleRadians, Distance, Settings )
return "BR, " .. self:GetBRText( AngleRadians, Distance, Settings, nil, MagVar )
end
--- Return a BRAA string from a COORDINATE to the COORDINATE.
--- Return a BRA string from a COORDINATE to the COORDINATE.
-- @param #COORDINATE self
-- @param #COORDINATE FromCoordinate The coordinate to measure the distance and the bearing from.
-- @param Core.Settings#SETTINGS Settings (optional) The settings. Can be nil, and in this case the default settings are used. If you want to specify your own settings, use the _SETTINGS object.
-- @param #boolean MagVar If true, also get angle in MagVar for BR/BRA
-- @return #string The BR text.
function COORDINATE:ToStringBRA( FromCoordinate, Settings, Language )
function COORDINATE:ToStringBRA( FromCoordinate, Settings, MagVar )
local DirectionVec3 = FromCoordinate:GetDirectionVec3( self )
local AngleRadians = self:GetAngleRadians( DirectionVec3 )
local Distance = FromCoordinate:Get2DDistance( self )
local Altitude = self:GetAltitudeText()
return "BRA, " .. self:GetBRAText( AngleRadians, Distance, Settings, Language )
return "BRA, " .. self:GetBRAText( AngleRadians, Distance, Settings, nil, MagVar )
end
--- Create a BRAA NATO call string to this COORDINATE from the FromCOORDINATE. Note - BRA delivered if no aspect can be obtained and "Merged" if range < 3nm
@@ -2800,8 +2944,13 @@ do -- COORDINATE
if alt < 1 then
alttext = "very low"
end
local track = UTILS.BearingToCardinal(bearing) or "North"
-- corrected Track to be direction of travel of bogey (self in this case)
local track = "Maneuver"
if self.Heading then
track = UTILS.BearingToCardinal(self.Heading) or "North"
end
if rangeNM > 3 then
if SSML then -- google says "oh" instead of zero, be aware
@@ -2856,14 +3005,15 @@ do -- COORDINATE
-- @param #COORDINATE self
-- @param DCS#coalition.side Coalition The coalition.
-- @param Core.Settings#SETTINGS Settings (optional) The settings. Can be nil, and in this case the default settings are used. If you want to specify your own settings, use the _SETTINGS object.
-- @param #boolean MagVar If true, als get angle in magnetic
-- @return #string The BR text.
function COORDINATE:ToStringBULLS( Coalition, Settings )
function COORDINATE:ToStringBULLS( Coalition, Settings, MagVar )
local BullsCoordinate = COORDINATE:NewFromVec3( coalition.getMainRefPoint( Coalition ) )
local DirectionVec3 = BullsCoordinate:GetDirectionVec3( self )
local AngleRadians = self:GetAngleRadians( DirectionVec3 )
local Distance = self:Get2DDistance( BullsCoordinate )
local Altitude = self:GetAltitudeText()
return "BULLS, " .. self:GetBRText( AngleRadians, Distance, Settings )
return "BULLS, " .. self:GetBRText( AngleRadians, Distance, Settings, nil, MagVar )
end
--- Return an aspect string from a COORDINATE to the Angle of the object.
@@ -2927,7 +3077,7 @@ do -- COORDINATE
-- @param #COORDINATE self
-- @param Core.Settings#SETTINGS Settings (optional) The settings. Can be nil, and in this case the default settings are used. If you want to specify your own settings, use the _SETTINGS object.
-- @return #string The MGRS Text
function COORDINATE:ToStringMGRS( Settings ) --R2.1 Fixes issue #424.
function COORDINATE:ToStringMGRS( Settings )
local MGRS_Accuracy = Settings and Settings.MGRS_Accuracy or _SETTINGS.MGRS_Accuracy
local lat, lon = coord.LOtoLL( self:GetVec3() )
@@ -2939,12 +3089,13 @@ do -- COORDINATE
-- * Uses default settings in COORDINATE.
-- * Can be overridden if for a GROUP containing x clients, a menu was selected to override the default.
-- @param #COORDINATE self
-- @param #COORDINATE ReferenceCoord The refrence coordinate.
-- @param #string ReferenceName The refrence name.
-- @param #COORDINATE ReferenceCoord The reference coordinate.
-- @param #string ReferenceName The reference name.
-- @param Wrapper.Controllable#CONTROLLABLE Controllable
-- @param Core.Settings#SETTINGS Settings (optional) The settings. Can be nil, and in this case the default settings are used. If you want to specify your own settings, use the _SETTINGS object.
-- @param #boolean MagVar If true also show angle in magnetic
-- @return #string The coordinate Text in the configured coordinate system.
function COORDINATE:ToStringFromRP( ReferenceCoord, ReferenceName, Controllable, Settings )
function COORDINATE:ToStringFromRP( ReferenceCoord, ReferenceName, Controllable, Settings, MagVar )
self:F2( { ReferenceCoord = ReferenceCoord, ReferenceName = ReferenceName } )
@@ -2956,24 +3107,59 @@ do -- COORDINATE
local DirectionVec3 = ReferenceCoord:GetDirectionVec3( self )
local AngleRadians = self:GetAngleRadians( DirectionVec3 )
local Distance = self:Get2DDistance( ReferenceCoord )
return "Targets are the last seen " .. self:GetBRText( AngleRadians, Distance, Settings ) .. " from " .. ReferenceName
return "Targets are the last seen " .. self:GetBRText( AngleRadians, Distance, Settings, nil, MagVar ) .. " from " .. ReferenceName
else
local DirectionVec3 = ReferenceCoord:GetDirectionVec3( self )
local AngleRadians = self:GetAngleRadians( DirectionVec3 )
local Distance = self:Get2DDistance( ReferenceCoord )
return "Target are located " .. self:GetBRText( AngleRadians, Distance, Settings ) .. " from " .. ReferenceName
return "Target are located " .. self:GetBRText( AngleRadians, Distance, Settings, nil, MagVar ) .. " from " .. ReferenceName
end
return nil
end
--- Provides a coordinate string of the point, based on a coordinate format system:
-- * Uses default settings in COORDINATE.
-- * Can be overridden if for a GROUP containing x clients, a menu was selected to override the default.
-- @param #COORDINATE self
-- @param #COORDINATE ReferenceCoord The reference coordinate.
-- @param #string ReferenceName The reference name.
-- @param Wrapper.Controllable#CONTROLLABLE Controllable
-- @param Core.Settings#SETTINGS Settings (optional) The settings. Can be nil, and in this case the default settings are used. If you want to specify your own settings, use the _SETTINGS object.
-- @param #boolean MagVar If true also get the angle as magnetic
-- @return #string The coordinate Text in the configured coordinate system.
function COORDINATE:ToStringFromRPShort( ReferenceCoord, ReferenceName, Controllable, Settings, MagVar )
self:F2( { ReferenceCoord = ReferenceCoord, ReferenceName = ReferenceName } )
local Settings = Settings or ( Controllable and _DATABASE:GetPlayerSettings( Controllable:GetPlayerName() ) ) or _SETTINGS
local IsAir = Controllable and Controllable:IsAirPlane() or false
if IsAir then
local DirectionVec3 = ReferenceCoord:GetDirectionVec3( self )
local AngleRadians = self:GetAngleRadians( DirectionVec3 )
local Distance = self:Get2DDistance( ReferenceCoord )
return self:GetBRText( AngleRadians, Distance, Settings, nil, MagVar ) .. " from " .. ReferenceName
else
local DirectionVec3 = ReferenceCoord:GetDirectionVec3( self )
local AngleRadians = self:GetAngleRadians( DirectionVec3 )
local Distance = self:Get2DDistance( ReferenceCoord )
return self:GetBRText( AngleRadians, Distance, Settings, nil, MagVar ) .. " from " .. ReferenceName
end
return nil
end
--- Provides a coordinate string of the point, based on the A2G coordinate format system.
-- @param #COORDINATE self
-- @param Wrapper.Controllable#CONTROLLABLE Controllable
-- @param Core.Settings#SETTINGS Settings (optional) The settings. Can be nil, and in this case the default settings are used. If you want to specify your own settings, use the _SETTINGS object.
-- @param #boolean MagVar If true, also get angle in MagVar for BR/BRA
-- @return #string The coordinate Text in the configured coordinate system.
function COORDINATE:ToStringA2G( Controllable, Settings )
function COORDINATE:ToStringA2G( Controllable, Settings, MagVar )
self:F2( { Controllable = Controllable and Controllable:GetName() } )
@@ -2983,7 +3169,7 @@ do -- COORDINATE
-- If no Controllable is given to calculate the BR from, then MGRS will be used!!!
if Controllable then
local Coordinate = Controllable:GetCoordinate()
return Controllable and self:ToStringBR( Coordinate, Settings ) or self:ToStringMGRS( Settings )
return Controllable and self:ToStringBR( Coordinate, Settings, MagVar ) or self:ToStringMGRS( Settings )
else
return self:ToStringMGRS( Settings )
end
@@ -3007,33 +3193,34 @@ do -- COORDINATE
-- @param #COORDINATE self
-- @param Wrapper.Controllable#CONTROLLABLE Controllable
-- @param Core.Settings#SETTINGS Settings (optional) The settings. Can be nil, and in this case the default settings are used. If you want to specify your own settings, use the _SETTINGS object.
-- @param #boolean MagVar If true, also get angle in MagVar for BR/BRA
-- @return #string The coordinate Text in the configured coordinate system.
function COORDINATE:ToStringA2A( Controllable, Settings, Language ) -- R2.2
function COORDINATE:ToStringA2A( Controllable, Settings, MagVar )
self:F2( { Controllable = Controllable and Controllable:GetName() } )
local Settings = Settings or ( Controllable and _DATABASE:GetPlayerSettings( Controllable:GetPlayerName() ) ) or _SETTINGS
if Settings:IsA2A_BRAA() then
if Settings:IsA2A_BRAA() then
if Controllable then
local Coordinate = Controllable:GetCoordinate()
return self:ToStringBRA( Coordinate, Settings, Language )
return self:ToStringBRA( Coordinate, Settings, MagVar )
else
return self:ToStringMGRS( Settings, Language )
return self:ToStringMGRS( Settings )
end
end
if Settings:IsA2A_BULLS() then
local Coalition = Controllable:GetCoalition()
return self:ToStringBULLS( Coalition, Settings, Language )
return self:ToStringBULLS( Coalition, Settings, MagVar )
end
if Settings:IsA2A_LL_DMS() then
return self:ToStringLLDMS( Settings, Language )
return self:ToStringLLDMS( Settings )
end
if Settings:IsA2A_LL_DDM() then
return self:ToStringLLDDM( Settings, Language )
return self:ToStringLLDDM( Settings )
end
if Settings:IsA2A_MGRS() then
return self:ToStringMGRS( Settings, Language )
return self:ToStringMGRS( Settings )
end
return nil
@@ -3101,7 +3288,7 @@ do -- COORDINATE
-- @param Wrapper.Controllable#CONTROLLABLE Controllable
-- @param Core.Settings#SETTINGS Settings (optional) The settings. Can be nil, and in this case the default settings are used. If you want to specify your own settings, use the _SETTINGS object.
-- @return #string The pressure text in the configured measurement system.
function COORDINATE:ToStringPressure( Controllable, Settings ) -- R2.3
function COORDINATE:ToStringPressure( Controllable, Settings )
self:F2( { Controllable = Controllable and Controllable:GetName() } )
@@ -3141,7 +3328,52 @@ do -- COORDINATE
return self:GetTemperatureText( nil, Settings )
end
--- Function to check if a coordinate is in a steep (>8% elevation) area of the map
-- @param #COORDINATE self
-- @param #number Radius (Optional) Radius to check around the coordinate, defaults to 50m (100m diameter)
-- @param #number Minelevation (Optional) Elevation from which on a area is defined as steep, defaults to 8% (8m height gain across 100 meters)
-- @return #boolen IsSteep If true, area is steep
-- @return #number MaxElevation Elevation in meters measured over 100m
function COORDINATE:IsInSteepArea(Radius,Minelevation)
local steep = false
local elev = Minelevation or 8
local bdelta = 0
local h0 = self:GetLandHeight()
local radius = Radius or 50
local diam = radius * 2
for i=0,150,30 do
local polar = math.fmod(i+180,360)
local c1 = self:Translate(radius,i,false,false)
local c2 = self:Translate(radius,polar,false,false)
local h1 = c1:GetLandHeight()
local h2 = c2:GetLandHeight()
local d1 = math.abs(h1-h2)
local d2 = math.abs(h0-h1)
local d3 = math.abs(h0-h2)
local dm = d1 > d2 and d1 or d2
local dm1 = dm > d3 and dm or d3
bdelta = dm1 > bdelta and dm1 or bdelta
self:T(string.format("d1=%d, d2=%d, d3=%d, max delta=%d",d1,d2,d3,bdelta))
end
local steepness = bdelta / (radius / 100)
if steepness >= elev then steep = true end
return steep, math.floor(steepness)
end
--- Function to check if a coordinate is in a flat (<8% elevation) area of the map
-- @param #COORDINATE self
-- @param #number Radius (Optional) Radius to check around the coordinate, defaults to 50m (100m diameter)
-- @param #number Minelevation (Optional) Elevation from which on a area is defined as steep, defaults to 8% (8m height gain across 100 meters)
-- @return #boolen IsFlat If true, area is flat
-- @return #number MaxElevation Elevation in meters measured over 100m
function COORDINATE:IsInFlatArea(Radius,Minelevation)
local steep, elev = self:IsInSteepArea(Radius,Minelevation)
local flat = not steep
return flat, elev
end
end
do -- POINT_VEC3
@@ -3278,21 +3510,21 @@ do -- POINT_VEC3
--- Return the x coordinate of the POINT_VEC3.
-- @param #POINT_VEC3 self
-- @return #number The x coodinate.
-- @return #number The x coordinate.
function POINT_VEC3:GetX()
return self.x
end
--- Return the y coordinate of the POINT_VEC3.
-- @param #POINT_VEC3 self
-- @return #number The y coodinate.
-- @return #number The y coordinate.
function POINT_VEC3:GetY()
return self.y
end
--- Return the z coordinate of the POINT_VEC3.
-- @param #POINT_VEC3 self
-- @return #number The z coodinate.
-- @return #number The z coordinate.
function POINT_VEC3:GetZ()
return self.z
end
@@ -3326,7 +3558,7 @@ do -- POINT_VEC3
--- Add to the x coordinate of the POINT_VEC3.
-- @param #POINT_VEC3 self
-- @param #number x The x coordinate value to add to the current x coodinate.
-- @param #number x The x coordinate value to add to the current x coordinate.
-- @return #POINT_VEC3
function POINT_VEC3:AddX( x )
self.x = self.x + x
@@ -3335,7 +3567,7 @@ do -- POINT_VEC3
--- Add to the y coordinate of the POINT_VEC3.
-- @param #POINT_VEC3 self
-- @param #number y The y coordinate value to add to the current y coodinate.
-- @param #number y The y coordinate value to add to the current y coordinate.
-- @return #POINT_VEC3
function POINT_VEC3:AddY( y )
self.y = self.y + y
@@ -3344,7 +3576,7 @@ do -- POINT_VEC3
--- Add to the z coordinate of the POINT_VEC3.
-- @param #POINT_VEC3 self
-- @param #number z The z coordinate value to add to the current z coodinate.
-- @param #number z The z coordinate value to add to the current z coordinate.
-- @return #POINT_VEC3
function POINT_VEC3:AddZ( z )
self.z = self.z +z
@@ -3450,14 +3682,14 @@ do -- POINT_VEC2
--- Return the x coordinate of the POINT_VEC2.
-- @param #POINT_VEC2 self
-- @return #number The x coodinate.
-- @return #number The x coordinate.
function POINT_VEC2:GetX()
return self.x
end
--- Return the y coordinate of the POINT_VEC2.
-- @param #POINT_VEC2 self
-- @return #number The y coodinate.
-- @return #number The y coordinate.
function POINT_VEC2:GetY()
return self.z
end
@@ -3482,7 +3714,7 @@ do -- POINT_VEC2
--- Return Return the Lat(itude) coordinate of the POINT_VEC2 (ie: (parent)POINT_VEC3.x).
-- @param #POINT_VEC2 self
-- @return #number The x coodinate.
-- @return #number The x coordinate.
function POINT_VEC2:GetLat()
return self.x
end
@@ -3498,7 +3730,7 @@ do -- POINT_VEC2
--- Return the Lon(gitude) coordinate of the POINT_VEC2 (ie: (parent)POINT_VEC3.z).
-- @param #POINT_VEC2 self
-- @return #number The y coodinate.
-- @return #number The y coordinate.
function POINT_VEC2:GetLon()
return self.z
end
@@ -1,4 +1,4 @@
--- **Core** -- SCHEDULEDISPATCHER dispatches the different schedules.
--- **Core** - SCHEDULEDISPATCHER dispatches the different schedules.
--
-- ===
--
@@ -109,9 +109,11 @@ function SCHEDULEDISPATCHER:AddSchedule( Scheduler, ScheduleFunction, ScheduleAr
self.ObjectSchedulers = self.ObjectSchedulers or setmetatable( {}, { __mode = "v" } )
if Scheduler.MasterObject then
--env.info("FF Object Scheduler")
self.ObjectSchedulers[CallID] = Scheduler
self:F3( { CallID = CallID, ObjectScheduler = tostring( self.ObjectSchedulers[CallID] ), MasterObject = tostring( Scheduler.MasterObject ) } )
else
--env.info("FF Persistent Scheduler")
self.PersistentSchedulers[CallID] = Scheduler
self:F3( { CallID = CallID, PersistentScheduler = self.PersistentSchedulers[CallID] } )
end
@@ -121,8 +123,8 @@ function SCHEDULEDISPATCHER:AddSchedule( Scheduler, ScheduleFunction, ScheduleAr
self.Schedule[Scheduler][CallID] = {} -- #SCHEDULEDISPATCHER.ScheduleData
self.Schedule[Scheduler][CallID].Function = ScheduleFunction
self.Schedule[Scheduler][CallID].Arguments = ScheduleArguments
self.Schedule[Scheduler][CallID].StartTime = timer.getTime() + (Start or 0)
self.Schedule[Scheduler][CallID].Start = Start + 0.1
self.Schedule[Scheduler][CallID].StartTime = timer.getTime() + ( Start or 0 )
self.Schedule[Scheduler][CallID].Start = Start + 0.001
self.Schedule[Scheduler][CallID].Repeat = Repeat or 0
self.Schedule[Scheduler][CallID].Randomize = Randomize or 0
self.Schedule[Scheduler][CallID].Stop = Stop
@@ -217,7 +219,8 @@ function SCHEDULEDISPATCHER:AddSchedule( Scheduler, ScheduleFunction, ScheduleAr
if ShowTrace then
SchedulerObject:T( Prefix .. Name .. ":" .. Line .. " (" .. Source .. ")" )
end
return ScheduleFunction( SchedulerObject, unpack( ScheduleArguments ) )
-- The master object is passed as first parameter. A few :Schedule() calls in MOOSE expect this currently. But in principle it should be removed.
return ScheduleFunction( SchedulerObject, unpack( ScheduleArguments ) )
end
Status, Result = xpcall( Timer, ErrorHandler )
else
@@ -314,7 +317,7 @@ end
--- Stop dispatcher.
-- @param #SCHEDULEDISPATCHER self
-- @param Core.Scheduler#SCHEDULER Scheduler Scheduler object.
-- @param #table CallID Call ID.
-- @param #string CallID (Optional) Scheduler Call ID. If nil, all pending schedules are stopped recursively.
function SCHEDULEDISPATCHER:Stop( Scheduler, CallID )
self:F2( { Stop = CallID, Scheduler = Scheduler } )
+5 -5
View File
@@ -1,7 +1,7 @@
--- **Core** - Prepares and handles the execution of functions over scheduled time (intervals).
--
-- ===
--
--
-- ## Features:
--
-- * Schedule functions over time,
@@ -13,9 +13,9 @@
-- ===
--
-- # Demo Missions
--
--
-- ### [SCHEDULER Demo Missions source code](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/SCH%20-%20Scheduler)
--
--
-- ### [SCHEDULER Demo Missions, only for beta testers](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/SCH%20-%20Scheduler)
--
-- ### [ALL Demo Missions pack of the last release](https://github.com/FlightControl-Master/MOOSE_MISSIONS/releases)
@@ -237,7 +237,7 @@ end
-- @param #number Stop Time interval in seconds after which the scheduler will be stopped.
-- @param #number TraceLevel Trace level [0,3]. Default 3.
-- @param Core.Fsm#FSM Fsm Finite state model.
-- @return #table The ScheduleID of the planned schedule.
-- @return #string The Schedule ID of the planned schedule.
function SCHEDULER:Schedule( MasterObject, SchedulerFunction, SchedulerArguments, Start, Repeat, RandomizeFactor, Stop, TraceLevel, Fsm )
self:F2( { Start, Repeat, RandomizeFactor, Stop } )
self:T3( { SchedulerArguments } )
@@ -271,7 +271,7 @@ end
--- (Re-)Starts the schedules or a specific schedule if a valid ScheduleID is provided.
-- @param #SCHEDULER self
-- @param #string ScheduleID (Optional) The ScheduleID of the planned (repeating) schedule.
-- @param #string ScheduleID (Optional) The Schedule ID of the planned (repeating) schedule.
function SCHEDULER:Start( ScheduleID )
self:F3( { ScheduleID } )
self:T( string.format( "Starting scheduler ID=%s", tostring( ScheduleID ) ) )
File diff suppressed because it is too large Load Diff
+19 -4
View File
@@ -1,4 +1,4 @@
--- **Core** - Manages various settings for running missions, consumed by moose classes and provides a menu system for players to tweak settings in running missions.
--- **Core** - Manages various settings for missions, providing a menu for players to tweak settings in running missions.
--
-- ===
--
@@ -251,6 +251,7 @@ do -- SETTINGS
self:SetMessageTime( MESSAGE.Type.Overview, 60 )
self:SetMessageTime( MESSAGE.Type.Update, 15 )
self:SetEraModern()
self:SetLocale("en")
return self
else
local Settings = _DATABASE:GetPlayerSettings( PlayerName )
@@ -282,7 +283,21 @@ do -- SETTINGS
function SETTINGS:SetMetric()
self.Metric = true
end
--- Sets the SETTINGS default text locale.
-- @param #SETTINGS self
-- @param #string Locale
function SETTINGS:SetLocale(Locale)
self.Locale = Locale or "en"
end
--- Gets the SETTINGS text locale.
-- @param #SETTINGS self
-- @return #string
function SETTINGS:GetLocale()
return self.Locale or _SETTINGS:GetLocale()
end
--- Gets if the SETTINGS is metric.
-- @param #SETTINGS self
-- @return #boolean true if metric.
@@ -300,7 +315,7 @@ do -- SETTINGS
-- @param #SETTINGS self
-- @return #boolean true if imperial.
function SETTINGS:IsImperial()
return (self.Metric ~= nil and self.Metric == false) or (self.Metric == nil and _SETTINGS:IsMetric())
return (self.Metric ~= nil and self.Metric == false) or (self.Metric == nil and _SETTINGS:IsImperial())
end
--- Sets the SETTINGS LL accuracy.
@@ -320,7 +335,7 @@ do -- SETTINGS
--- Sets the SETTINGS MGRS accuracy.
-- @param #SETTINGS self
-- @param #number MGRS_Accuracy
-- @param #number MGRS_Accuracy 0 to 5
-- @return #SETTINGS
function SETTINGS:SetMGRS_Accuracy( MGRS_Accuracy )
self.MGRS_Accuracy = MGRS_Accuracy
+369 -89
View File
@@ -29,9 +29,9 @@
-- * Enquiry methods to check on spawn status.
--
-- ===
--
--
-- ### [Demo Missions](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/SPA%20-%20Spawning)
--
--
-- ===
--
-- ### [YouTube Playlist](https://www.youtube.com/playlist?list=PL7ZUrU4zZUl1jirWIo4t4YxqN-HxjqRkL)
@@ -162,12 +162,22 @@
-- ### Array formation
--
-- * @{#SPAWN.InitArray}(): Make groups visible before they are actually activated, and order these groups like a battalion in an array.
--
--
-- ### Group initial position - if wanted different from template position, for use with e.g. @{#SPAWN.SpawnScheduled}().
--
-- * @{#SPAWN.InitPositionCoordinate}(): Set initial position of group via a COORDINATE.
-- * @{#SPAWN.InitPositionVec2}(): Set initial position of group via a VEC2.
--
-- ### Set the positions of a group's units to absolute positions, or relative positions to unit No. 1
--
-- * @{#SPAWN.InitSetUnitRelativePositions}(): Spawn the UNITs of this group with individual relative positions to unit #1 and individual headings.
-- * @{#SPAWN.InitSetUnitAbsolutePositions}(): Spawn the UNITs of this group with individual absolute positions and individual headings.
--
-- ### Position randomization
--
-- * @{#SPAWN.InitRandomizePosition}(): Randomizes the position of @{Wrapper.Group}s that are spawned within a **radius band**, given an Outer and Inner radius, from the point that the spawn happens.
-- * @{#SPAWN.InitRandomizeUnits}(): Randomizes the @{Wrapper.Unit}s in the @{Wrapper.Group} that is spawned within a **radius band**, given an Outer and Inner radius.
-- * @{#SPAWN.InitRandomizeZones}(): Randomizes the spawning between a predefined list of @{Zone}s that are declared using this function. Each zone can be given a probability factor.
-- * @{#SPAWN.InitRandomizeZones}(): Randomizes the spawning between a predefined list of @{Core.Zone}s that are declared using this function. Each zone can be given a probability factor.
--
-- ### Enable / Disable AI when spawning a new @{Wrapper.Group}
--
@@ -200,13 +210,13 @@
-- * @{#SPAWN.ReSpawn}(): Re-spawn a group based on a given index.
-- * @{#SPAWN.SpawnFromVec3}(): Spawn a new group from a Vec3 coordinate. (The group will can be spawned at a point in the air).
-- * @{#SPAWN.SpawnFromVec2}(): Spawn a new group from a Vec2 coordinate. (The group will be spawned at land height ).
-- * @{#SPAWN.SpawnFromStatic}(): Spawn a new group from a structure, taking the position of a @{Static}.
-- * @{#SPAWN.SpawnFromStatic}(): Spawn a new group from a structure, taking the position of a @{Wrapper.Static}.
-- * @{#SPAWN.SpawnFromUnit}(): Spawn a new group taking the position of a @{Wrapper.Unit}.
-- * @{#SPAWN.SpawnInZone}(): Spawn a new group in a @{Zone}.
-- * @{#SPAWN.SpawnInZone}(): Spawn a new group in a @{Core.Zone}.
-- * @{#SPAWN.SpawnAtAirbase}(): Spawn a new group at an @{Wrapper.Airbase}, which can be an airdrome, ship or helipad.
--
-- Note that @{#SPAWN.Spawn} and @{#SPAWN.ReSpawn} return a @{Wrapper.Group#GROUP.New} object, that contains a reference to the DCSGroup object.
-- You can use the @{GROUP} object to do further actions with the DCSGroup.
-- You can use the @{Wrapper.Group#GROUP} object to do further actions with the DCSGroup.
--
-- ### **Scheduled** spawning methods
--
@@ -268,7 +278,7 @@ SPAWN = {
-- @type SPAWN.Takeoff
-- @extends Wrapper.Group#GROUP.Takeoff
--- @field #SPAWN.Takeoff Takeoff
-- @field #SPAWN.Takeoff Takeoff
SPAWN.Takeoff = {
Air = 1,
Runway = 2,
@@ -276,7 +286,7 @@ SPAWN.Takeoff = {
Cold = 4,
}
--- @type SPAWN.SpawnZoneTable
-- @type SPAWN.SpawnZoneTable
-- @list <Core.Zone#ZONE_BASE> SpawnZone
--- Creates the main object to spawn a @{Wrapper.Group} defined in the DCS ME.
@@ -335,7 +345,7 @@ end
-- @param #SPAWN self
-- @param #string SpawnTemplatePrefix is the name of the Group in the ME that defines the Template.
-- @param #string SpawnAliasPrefix is the name that will be given to the Group at runtime.
-- @return #SPAWN
-- @return #SPAWN self
-- @usage
-- -- NATO helicopters engaging in the battle field.
-- Spawn_BE_KA50 = SPAWN:NewWithAlias( 'BE KA-50@RAMP-Ground Defense', 'Helicopter Attacking a City' )
@@ -385,32 +395,129 @@ function SPAWN:NewWithAlias( SpawnTemplatePrefix, SpawnAliasPrefix )
return self
end
--- Creates a new SPAWN instance to create new groups based on the provided template.
--- Creates a new SPAWN instance to create new groups based on the provided template. This will also register the template for future use.
-- @param #SPAWN self
-- @param #table SpawnTemplate is the Template of the Group. This must be a valid Group Template structure!
-- @param #string SpawnTemplatePrefix is the name of the Group that will be given at each spawn.
-- @param #string SpawnAliasPrefix (optional) is the name that will be given to the Group at runtime.
-- @return #SPAWN
-- @param #table SpawnTemplate is the Template of the Group. This must be a valid Group Template structure - see [Hoggit Wiki](https://wiki.hoggitworld.com/view/DCS_func_addGroup)!
-- @param #string SpawnTemplatePrefix [Mandatory] is the name of the template and the prefix of the GROUP on spawn. The name in the template **will** be overwritten!
-- @param #string SpawnAliasPrefix [Optional] is the prefix that will be given to the GROUP on spawn.
-- @param #boolean NoMooseNamingPostfix [Optional] If true, skip the Moose naming additions (like groupname#001-01) - **but** you need to ensure yourself no duplicate group names exist!
-- @return #SPAWN self
-- @usage
-- -- Create a new SPAWN object based on a Group Template defined from scratch.
-- Spawn_BE_KA50 = SPAWN:NewWithAlias( 'BE KA-50@RAMP-Ground Defense', 'Helicopter Attacking a City' )
-- @usage
--
-- -- Create a new CSAR_Spawn object based on a normal Group Template to spawn a soldier.
-- local CSAR_Spawn = SPAWN:NewWithFromTemplate( Template, "CSAR", "Pilot" )
--
function SPAWN:NewFromTemplate( SpawnTemplate, SpawnTemplatePrefix, SpawnAliasPrefix )
local self = BASE:Inherit( self, BASE:New() )
self:F( { SpawnTemplate, SpawnTemplatePrefix, SpawnAliasPrefix } )
if SpawnAliasPrefix == nil or SpawnAliasPrefix == "" then
BASE:I( "ERROR: in function NewFromTemplate, required paramter SpawnAliasPrefix is not set" )
-- -- Spawn a P51 Mustang from scratch
-- local ttemp =
-- {
-- ["modulation"] = 0,
-- ["tasks"] =
-- {
-- }, -- end of ["tasks"]
-- ["task"] = "Reconnaissance",
-- ["uncontrolled"] = false,
-- ["route"] =
-- {
-- ["points"] =
-- {
-- [1] =
-- {
-- ["alt"] = 2000,
-- ["action"] = "Turning Point",
-- ["alt_type"] = "BARO",
-- ["speed"] = 125,
-- ["task"] =
-- {
-- ["id"] = "ComboTask",
-- ["params"] =
-- {
-- ["tasks"] =
-- {
-- }, -- end of ["tasks"]
-- }, -- end of ["params"]
-- }, -- end of ["task"]
-- ["type"] = "Turning Point",
-- ["ETA"] = 0,
-- ["ETA_locked"] = true,
-- ["y"] = 666285.71428571,
-- ["x"] = -312000,
-- ["formation_template"] = "",
-- ["speed_locked"] = true,
-- }, -- end of [1]
-- }, -- end of ["points"]
-- }, -- end of ["route"]
-- ["groupId"] = 1,
-- ["hidden"] = false,
-- ["units"] =
-- {
-- [1] =
-- {
-- ["alt"] = 2000,
-- ["alt_type"] = "BARO",
-- ["livery_id"] = "USAF 364th FS",
-- ["skill"] = "High",
-- ["speed"] = 125,
-- ["type"] = "TF-51D",
-- ["unitId"] = 1,
-- ["psi"] = 0,
-- ["y"] = 666285.71428571,
-- ["x"] = -312000,
-- ["name"] = "P51-1-1",
-- ["payload"] =
-- {
-- ["pylons"] =
-- {
-- }, -- end of ["pylons"]
-- ["fuel"] = 340.68,
-- ["flare"] = 0,
-- ["chaff"] = 0,
-- ["gun"] = 100,
-- }, -- end of ["payload"]
-- ["heading"] = 0,
-- ["callsign"] =
-- {
-- [1] = 1,
-- [2] = 1,
-- ["name"] = "Enfield11",
-- [3] = 1,
-- }, -- end of ["callsign"]
-- ["onboard_num"] = "010",
-- }, -- end of [1]
-- }, -- end of ["units"]
-- ["y"] = 666285.71428571,
-- ["x"] = -312000,
-- ["name"] = "P51",
-- ["communication"] = true,
-- ["start_time"] = 0,
-- ["frequency"] = 124,
-- }
--
--
-- local mustang = SPAWN:NewFromTemplate(ttemp,"P51D")
-- -- you MUST set the next three:
-- mustang:InitCountry(country.id.FRANCE)
-- mustang:InitCategory(Group.Category.AIRPLANE)
-- mustang:InitCoalition(coalition.side.BLUE)
-- mustang:OnSpawnGroup(
-- function(grp)
-- MESSAGE:New("Group Spawned: "..grp:GetName(),15,"SPAWN"):ToAll()
-- end
-- )
-- mustang:Spawn()
--
function SPAWN:NewFromTemplate( SpawnTemplate, SpawnTemplatePrefix, SpawnAliasPrefix, NoMooseNamingPostfix )
local self = BASE:Inherit( self, BASE:New() )
self:F( { SpawnTemplate, SpawnTemplatePrefix, SpawnAliasPrefix } )
--if SpawnAliasPrefix == nil or SpawnAliasPrefix == "" then
--BASE:I( "ERROR: in function NewFromTemplate, required parameter SpawnAliasPrefix is not set" )
--return nil
--end
if SpawnTemplatePrefix == nil or SpawnTemplatePrefix == "" then
BASE:I( "ERROR: in function NewFromTemplate, required parameter SpawnTemplatePrefix is not set" )
return nil
end
if SpawnTemplate then
self.SpawnTemplate = SpawnTemplate -- Contains the template structure for a Group Spawn from the Mission Editor. Note that this group must have lateActivation always on!!!
self.SpawnTemplatePrefix = SpawnTemplatePrefix
self.SpawnAliasPrefix = SpawnAliasPrefix
self.SpawnAliasPrefix = SpawnAliasPrefix or SpawnTemplatePrefix
self.SpawnTemplate.name = SpawnTemplatePrefix
self.SpawnIndex = 0
self.SpawnCount = 0 -- The internal counter of the amount of spawning the has happened since SpawnStart.
self.AliveUnits = 0 -- Contains the counter how many units are currently alive
@@ -435,7 +542,11 @@ function SPAWN:NewFromTemplate( SpawnTemplate, SpawnTemplatePrefix, SpawnAliasPr
self.SpawnInitModex = nil
self.SpawnInitAirbase = nil
self.TweakedTemplate = true -- Check if the user is using self made template.
self.MooseNameing = true
if NoMooseNamingPostfix == true then
self.MooseNameing = false
end
self.SpawnGroups = {} -- Array containing the descriptions of each Group to be Spawned.
else
error( "There is no template provided for SpawnTemplatePrefix = '" .. SpawnTemplatePrefix .. "'" )
@@ -765,17 +876,15 @@ end
--- Randomizes the UNITs that are spawned within a radius band given an Outer and Inner radius.
-- @param #SPAWN self
-- @param #boolean RandomizeUnits If true, SPAWN will perform the randomization of the @{UNIT}s position within the group between a given outer and inner radius.
-- @param #boolean RandomizeUnits If true, SPAWN will perform the randomization of the @{Wrapper.Unit#UNIT}s position within the group between a given outer and inner radius.
-- @param DCS#Distance OuterRadius (optional) The outer radius in meters where the new group will be spawned.
-- @param DCS#Distance InnerRadius (optional) The inner radius in meters where the new group will NOT be spawned.
-- @return #SPAWN
-- @usage
--
-- -- NATO helicopters engaging in the battle field.
-- -- The KA-50 has waypoints Start point ( =0 or SP ), 1, 2, 3, 4, End point (= 5 or DP).
-- -- Waypoints 2 and 3 will only be randomized. The others will remain on their original position with each new spawn of the helicopter.
-- -- The randomization of waypoint 2 and 3 will take place within a radius of 2000 meters.
-- Spawn_BE_KA50 = SPAWN:New( 'BE KA-50@RAMP-Ground Defense' ):InitRandomizeRoute( 2, 2, 2000 )
-- -- UNIT positions of this group will be randomized around the base unit #1 in a circle of 50 to 500 meters.
-- Spawn_BE_KA50 = SPAWN:New( 'BE KA-50@RAMP-Ground Defense' ):InitRandomizeUnits( true, 500, 50 )
--
function SPAWN:InitRandomizeUnits( RandomizeUnits, OuterRadius, InnerRadius )
self:F( { self.SpawnTemplatePrefix, RandomizeUnits, OuterRadius, InnerRadius } )
@@ -791,6 +900,46 @@ function SPAWN:InitRandomizeUnits( RandomizeUnits, OuterRadius, InnerRadius )
return self
end
--- Spawn the UNITs of this group with individual relative positions to unit #1 and individual headings.
-- @param #SPAWN self
-- @param #table Positions Table of positions, needs to one entry per unit in the group(!). The table contains one table each for each unit, with x,y, and optionally z
-- relative positions, and optionally an individual heading.
-- @return #SPAWN
-- @usage
--
-- -- NATO helicopter group of three units engaging in the battle field.
-- local Positions = { [1] = {x = 0, y = 0, heading = 0}, [2] = {x = 50, y = 50, heading = 90}, [3] = {x = -50, y = 50, heading = 180} }
-- Spawn_BE_KA50 = SPAWN:New( 'BE KA-50@RAMP-Ground Defense' ):InitSetUnitRelativePositions(Positions)
--
function SPAWN:InitSetUnitRelativePositions(Positions)
self:F({self.SpawnTemplatePrefix, Positions})
self.SpawnUnitsWithRelativePositions = true
self.UnitsRelativePositions = Positions
return self
end
--- Spawn the UNITs of this group with individual absolute positions and individual headings.
-- @param #SPAWN self
-- @param #table Positions Table of positions, needs to one entry per unit in the group(!). The table contains one table each for each unit, with x,y, and optionally z
-- absolute positions, and optionally an individual heading.
-- @return #SPAWN
-- @usage
--
-- -- NATO helicopter group of three units engaging in the battle field.
-- local Positions = { [1] = {x = 0, y = 0, heading = 0}, [2] = {x = 50, y = 50, heading = 90}, [3] = {x = -50, y = 50, heading = 180} }
-- Spawn_BE_KA50 = SPAWN:New( 'BE KA-50@RAMP-Ground Defense' ):InitSetUnitAbsolutePositions(Positions)
--
function SPAWN:InitSetUnitAbsolutePositions(Positions)
self:F({self.SpawnTemplatePrefix, Positions})
self.SpawnUnitsWithAbsolutePositions = true
self.UnitsAbsolutePositions = Positions
return self
end
--- This method is rather complicated to understand. But I'll try to explain.
-- This method becomes useful when you need to spawn groups with random templates of groups defined within the mission editor,
-- but they will all follow the same Template route and have the same prefix name.
@@ -813,8 +962,13 @@ end
-- Spawn_US_Platoon_Right = SPAWN:New( 'US Tank Platoon Right' ):InitLimit( 12, 150 ):SpawnScheduled( 200, 0.4 ):InitRandomizeTemplate( Spawn_US_Platoon ):InitRandomizeRoute( 3, 3, 2000 )
function SPAWN:InitRandomizeTemplate( SpawnTemplatePrefixTable )
self:F( { self.SpawnTemplatePrefix, SpawnTemplatePrefixTable } )
self.SpawnTemplatePrefixTable = SpawnTemplatePrefixTable
local temptable = {}
for _,_temp in pairs(SpawnTemplatePrefixTable) do
temptable[#temptable+1] = _temp
end
self.SpawnTemplatePrefixTable = UTILS.ShuffleTable(temptable)
self.SpawnRandomizeTemplate = true
for SpawnGroupID = 1, self.SpawnMaxGroups do
@@ -848,16 +1002,12 @@ end
-- Spawn_US_Platoon_Middle = SPAWN:New( 'US Tank Platoon Middle' ):InitLimit( 12, 150 ):SpawnScheduled( 200, 0.4 ):InitRandomizeTemplateSet( Spawn_US_PlatoonSet ):InitRandomizeRoute( 3, 3, 2000 )
-- Spawn_US_Platoon_Right = SPAWN:New( 'US Tank Platoon Right' ):InitLimit( 12, 150 ):SpawnScheduled( 200, 0.4 ):InitRandomizeTemplateSet( Spawn_US_PlatoonSet ):InitRandomizeRoute( 3, 3, 2000 )
--
function SPAWN:InitRandomizeTemplateSet( SpawnTemplateSet ) -- R2.3
function SPAWN:InitRandomizeTemplateSet( SpawnTemplateSet )
self:F( { self.SpawnTemplatePrefix } )
self.SpawnTemplatePrefixTable = SpawnTemplateSet:GetSetNames()
self.SpawnRandomizeTemplate = true
for SpawnGroupID = 1, self.SpawnMaxGroups do
self:_RandomizeTemplate( SpawnGroupID )
end
local setnames = SpawnTemplateSet:GetSetNames()
self:InitRandomizeTemplate(setnames)
return self
end
@@ -906,8 +1056,8 @@ end
--- This method provides the functionality to randomize the spawning of the Groups at a given list of zones of different types.
-- @param #SPAWN self
-- @param #table SpawnZoneTable A table with @{Zone} objects. If this table is given, then each spawn will be executed within the given list of @{Zone}s objects.
-- @return #SPAWN
-- @param #table SpawnZoneTable A table with @{Core.Zone} objects. If this table is given, then each spawn will be executed within the given list of @{Core.Zone}s objects.
-- @return #SPAWN self
-- @usage
--
-- -- Create a zone table of the 2 zones.
@@ -921,8 +1071,13 @@ end
--
function SPAWN:InitRandomizeZones( SpawnZoneTable )
self:F( { self.SpawnTemplatePrefix, SpawnZoneTable } )
self.SpawnZoneTable = SpawnZoneTable
local temptable = {}
for _,_temp in pairs(SpawnZoneTable) do
temptable[#temptable+1] = _temp
end
self.SpawnZoneTable = UTILS.ShuffleTable(temptable)
self.SpawnRandomizeZones = true
for SpawnGroupID = 1, self.SpawnMaxGroups do
@@ -932,6 +1087,31 @@ function SPAWN:InitRandomizeZones( SpawnZoneTable )
return self
end
--- This method sets a spawn position for the group that is different from the location of the template.
-- @param #SPAWN self
-- @param Core.Point#COORDINATE Coordinate The position to spawn from
-- @return #SPAWN self
function SPAWN:InitPositionCoordinate(Coordinate)
self:T( { self.SpawnTemplatePrefix, Coordinate:GetVec2()} )
self:InitPositionVec2(Coordinate:GetVec2())
return self
end
--- This method sets a spawn position for the group that is different from the location of the template.
-- @param #SPAWN self
-- @param DCS#Vec2 Vec2 The position to spawn from
-- @return #SPAWN self
function SPAWN:InitPositionVec2(Vec2)
self:T( { self.SpawnTemplatePrefix, Vec2} )
self.SpawnInitPosition = Vec2
self.SpawnFromNewPosition = true
self:I("MaxGroups:"..self.SpawnMaxGroups)
for SpawnGroupID = 1, self.SpawnMaxGroups do
self:_SetInitialPosition( SpawnGroupID )
end
return self
end
--- For planes and helicopters, when these groups go home and land on their home airbases and FARPs, they normally would taxi to the parking spot, shut-down their engines and wait forever until the Group is removed by the runtime environment.
-- This method is used to re-spawn automatically (so no extra call is needed anymore) the same group after it has landed.
-- This will enable a spawned group to be re-spawned after it lands, until it is destroyed...
@@ -1140,7 +1320,8 @@ do -- Delay methods
return self
end
--- Turns the Delay On for the @{Wrapper.Group} when spawning.
--- Turns the Delay On for the @{Wrapper.Group} when spawning with @{SpawnScheduled}(). In effect then the 1st group will only be spawned
-- after the number of seconds given in SpawnScheduled as arguments, and not immediately.
-- @param #SPAWN self
-- @return #SPAWN The SPAWN object
function SPAWN:InitDelayOn()
@@ -1159,7 +1340,7 @@ do -- Delay methods
end -- Delay methods
--- Will spawn a group based on the internal index.
-- Note: Uses @{DATABASE} module defined in MOOSE.
-- Note: This method uses the global _DATABASE object (an instance of @{Core.Database#DATABASE}), which contains ALL initial and new spawned objects in MOOSE.
-- @param #SPAWN self
-- @return Wrapper.Group#GROUP The group that was spawned. You can use this group for further actions.
function SPAWN:Spawn()
@@ -1174,7 +1355,7 @@ function SPAWN:Spawn()
end
--- Will re-spawn a group based on a given index.
-- Note: Uses @{DATABASE} module defined in MOOSE.
-- Note: This method uses the global _DATABASE object (an instance of @{Core.Database#DATABASE}), which contains ALL initial and new spawned objects in MOOSE.
-- @param #SPAWN self
-- @param #string SpawnIndex The index of the group to be spawned.
-- @return Wrapper.Group#GROUP The group that was spawned. You can use this group for further actions.
@@ -1222,7 +1403,7 @@ function SPAWN:SetSpawnIndex( SpawnIndex )
end
--- Will spawn a group with a specified index number.
-- Uses @{DATABASE} global object defined in MOOSE.
-- Note: This method uses the global _DATABASE object (an instance of @{Core.Database#DATABASE}), which contains ALL initial and new spawned objects in MOOSE.
-- @param #SPAWN self
-- @param #string SpawnIndex The index of the group to be spawned.
-- @return Wrapper.Group#GROUP The group that was spawned. You can use this group for further actions.
@@ -1230,7 +1411,12 @@ function SPAWN:SpawnWithIndex( SpawnIndex, NoBirth )
self:F2( { SpawnTemplatePrefix = self.SpawnTemplatePrefix, SpawnIndex = SpawnIndex, AliveUnits = self.AliveUnits, SpawnMaxGroups = self.SpawnMaxGroups } )
if self:_GetSpawnIndex( SpawnIndex ) then
if self.SpawnFromNewPosition then
self:_SetInitialPosition( SpawnIndex )
end
if self.SpawnGroups[self.SpawnIndex].Visible then
self.SpawnGroups[self.SpawnIndex].Group:Activate()
else
@@ -1336,7 +1522,38 @@ function SPAWN:SpawnWithIndex( SpawnIndex, NoBirth )
SpawnTemplate.units[UnitID].psi = -SpawnTemplate.units[UnitID].heading
end
end
-- Individual relative unit positions + heading
if self.SpawnUnitsWithRelativePositions and self.UnitsRelativePositions then
local BaseX = SpawnTemplate.units[1].x or 0
local BaseY = SpawnTemplate.units[1].y or 0
local BaseZ = SpawnTemplate.units[1].z or 0
for UnitID = 1, #SpawnTemplate.units do
if self.UnitsRelativePositions[UnitID].heading then
SpawnTemplate.units[UnitID].heading = math.rad(self.UnitsRelativePositions[UnitID].heading or 0)
end
SpawnTemplate.units[UnitID].x = BaseX + (self.UnitsRelativePositions[UnitID].x or 0)
SpawnTemplate.units[UnitID].y = BaseY + (self.UnitsRelativePositions[UnitID].y or 0)
if self.UnitsRelativePositions[UnitID].z then
SpawnTemplate.units[UnitID].z = BaseZ + (self.UnitsRelativePositions[UnitID].z or 0)
end
end
end
-- Individual asbolute unit positions + heading
if self.SpawnUnitsWithAbsolutePositions and self.UnitsAbsolutePositions then
for UnitID = 1, #SpawnTemplate.units do
if self.UnitsAbsolutePositions[UnitID].heading then
SpawnTemplate.units[UnitID].heading = math.rad(self.UnitsAbsolutePositions[UnitID].heading or 0)
end
SpawnTemplate.units[UnitID].x = self.UnitsAbsolutePositions[UnitID].x or 0
SpawnTemplate.units[UnitID].y = self.UnitsAbsolutePositions[UnitID].y or 0
if self.UnitsAbsolutePositions[UnitID].z then
SpawnTemplate.units[UnitID].z = self.UnitsAbsolutePositions[UnitID].z or 0
end
end
end
-- Set livery.
if self.SpawnInitLivery then
for UnitID = 1, #SpawnTemplate.units do
@@ -1418,7 +1635,7 @@ function SPAWN:SpawnWithIndex( SpawnIndex, NoBirth )
end
-- TODO: Need to fix this by putting an "R" in the name of the group when the group repeats.
-- if self.Repeat then
-- _DATABASE:SetStatusGroup( SpawnTemplate.name, "ReSpawn" )
-- _DATABASE:SetStatusGroup( SpawnTemplate.name, "ReSpawn" )
-- end
end
@@ -1437,6 +1654,8 @@ end
-- @param #number SpawnTime The time interval defined in seconds between each new spawn of new groups.
-- @param #number SpawnTimeVariation The variation to be applied on the defined time interval between each new spawn.
-- The variation is a number between 0 and 1, representing the % of variation to be applied on the time interval.
-- @param #boolean WithDelay Do not spawn the **first** group immediately, but delay the spawn as per the calculation below.
-- Effectively the same as @{InitDelayOn}().
-- @return #SPAWN self
-- @usage
-- -- NATO helicopters engaging in the battle field.
@@ -1447,17 +1666,20 @@ end
-- -- High limit: 600 * ( 1 + 0.5 / 2 ) = 750
-- -- Between these two values, a random amount of seconds will be chosen for each new spawn of the helicopters.
-- Spawn_BE_KA50 = SPAWN:New( 'BE KA-50@RAMP-Ground Defense' ):SpawnScheduled( 600, 0.5 )
function SPAWN:SpawnScheduled( SpawnTime, SpawnTimeVariation )
function SPAWN:SpawnScheduled( SpawnTime, SpawnTimeVariation, WithDelay )
self:F( { SpawnTime, SpawnTimeVariation } )
local SpawnTime = SpawnTime or 60
local SpawnTimeVariation = SpawnTimeVariation or 0.5
if SpawnTime ~= nil and SpawnTimeVariation ~= nil then
local InitialDelay = 0
if self.DelayOnOff == true then
if WithDelay or self.DelayOnOff == true then
InitialDelay = math.random( SpawnTime - SpawnTime * SpawnTimeVariation, SpawnTime + SpawnTime * SpawnTimeVariation )
end
self.SpawnScheduler = SCHEDULER:New( self, self._Scheduler, {}, InitialDelay, SpawnTime, SpawnTimeVariation )
end
return self
end
@@ -2403,8 +2625,7 @@ end
-- @param #SPAWN self
-- @param DCS#Vec3 Vec3 The Vec3 coordinates where to spawn the group.
-- @param #number SpawnIndex (optional) The index which group to spawn within the given zone.
-- @return Wrapper.Group#GROUP that was spawned.
-- @return #nil Nothing was spawned.
-- @return Wrapper.Group#GROUP that was spawned or #nil if nothing was spawned.
function SPAWN:SpawnFromVec3( Vec3, SpawnIndex )
self:F( { self.SpawnTemplatePrefix, Vec3, SpawnIndex } )
@@ -2472,8 +2693,7 @@ end
-- @param #SPAWN self
-- @param Core.Point#Coordinate Coordinate The Coordinate coordinates where to spawn the group.
-- @param #number SpawnIndex (optional) The index which group to spawn within the given zone.
-- @return Wrapper.Group#GROUP that was spawned.
-- @return #nil Nothing was spawned.
-- @return Wrapper.Group#GROUP that was spawned or #nil if nothing was spawned.
function SPAWN:SpawnFromCoordinate( Coordinate, SpawnIndex )
self:F( { self.SpawnTemplatePrefix, SpawnIndex } )
@@ -2487,8 +2707,7 @@ end
-- @param #SPAWN self
-- @param Core.Point#POINT_VEC3 PointVec3 The PointVec3 coordinates where to spawn the group.
-- @param #number SpawnIndex (optional) The index which group to spawn within the given zone.
-- @return Wrapper.Group#GROUP that was spawned.
-- @return #nil Nothing was spawned.
-- @return Wrapper.Group#GROUP that was spawned or #nil if nothing was spawned.
-- @usage
--
-- local SpawnPointVec3 = ZONE:New( ZoneName ):GetPointVec3( 2000 ) -- Get the center of the ZONE object at 2000 meters from the ground.
@@ -2511,8 +2730,7 @@ end
-- @param #number MinHeight (optional) The minimum height to spawn an airborne group into the zone.
-- @param #number MaxHeight (optional) The maximum height to spawn an airborne group into the zone.
-- @param #number SpawnIndex (optional) The index which group to spawn within the given zone.
-- @return Wrapper.Group#GROUP that was spawned.
-- @return #nil Nothing was spawned.
-- @return Wrapper.Group#GROUP that was spawned or #nil if nothing was spawned.
-- @usage
--
-- local SpawnVec2 = ZONE:New( ZoneName ):GetVec2()
@@ -2544,8 +2762,7 @@ end
-- @param #number MinHeight (optional) The minimum height to spawn an airborne group into the zone.
-- @param #number MaxHeight (optional) The maximum height to spawn an airborne group into the zone.
-- @param #number SpawnIndex (optional) The index which group to spawn within the given zone.
-- @return Wrapper.Group#GROUP that was spawned.
-- @return #nil Nothing was spawned.
-- @return Wrapper.Group#GROUP that was spawned or #nil if nothing was spawned.
-- @usage
--
-- local SpawnPointVec2 = ZONE:New( ZoneName ):GetPointVec2()
@@ -2599,8 +2816,7 @@ end
-- @param #number MinHeight (optional) The minimum height to spawn an airborne group into the zone.
-- @param #number MaxHeight (optional) The maximum height to spawn an airborne group into the zone.
-- @param #number SpawnIndex (optional) The index which group to spawn within the given zone.
-- @return Wrapper.Group#GROUP that was spawned.
-- @return #nil Nothing was spawned.
-- @return Wrapper.Group#GROUP that was spawned or #nil if nothing was spawned.
-- @usage
--
-- local SpawnStatic = STATIC:FindByName( StaticName )
@@ -2621,8 +2837,8 @@ function SPAWN:SpawnFromStatic( HostStatic, MinHeight, MaxHeight, SpawnIndex )
return nil
end
--- Will spawn a Group within a given @{Zone}.
-- The @{Zone} can be of any type derived from @{Core.Zone#ZONE_BASE}.
--- Will spawn a Group within a given @{Core.Zone}.
-- The @{Core.Zone} can be of any type derived from @{Core.Zone#ZONE_BASE}.
-- Once the @{Wrapper.Group} is spawned within the zone, the @{Wrapper.Group} will continue on its route.
-- The **first waypoint** (where the group is spawned) is replaced with the zone location coordinates.
-- @param #SPAWN self
@@ -2631,8 +2847,7 @@ end
-- @param #number MinHeight (optional) The minimum height to spawn an airborne group into the zone.
-- @param #number MaxHeight (optional) The maximum height to spawn an airborne group into the zone.
-- @param #number SpawnIndex (optional) The index which group to spawn within the given zone.
-- @return Wrapper.Group#GROUP that was spawned.
-- @return #nil when nothing was spawned.
-- @return Wrapper.Group#GROUP that was spawned or #nil if nothing was spawned.
-- @usage
--
-- local SpawnZone = ZONE:New( ZoneName )
@@ -2944,7 +3159,7 @@ function SPAWN:_GetGroupCountryID( SpawnPrefix )
end
--- Gets the Group Template from the ME environment definition.
-- This method used the @{DATABASE} object, which contains ALL initial and new spawned object in MOOSE.
-- Note: This method uses the global _DATABASE object (an instance of @{Core.Database#DATABASE}), which contains ALL initial and new spawned objects in MOOSE.
-- @param #SPAWN self
-- @param #string SpawnTemplatePrefix
-- @return @SPAWN self
@@ -2952,7 +3167,11 @@ function SPAWN:_GetTemplate( SpawnTemplatePrefix )
self:F( { self.SpawnTemplatePrefix, self.SpawnAliasPrefix, SpawnTemplatePrefix } )
local SpawnTemplate = nil
if _DATABASE.Templates.Groups[SpawnTemplatePrefix] == nil then
error( 'No Template exists for SpawnTemplatePrefix = ' .. SpawnTemplatePrefix )
end
local Template = _DATABASE.Templates.Groups[SpawnTemplatePrefix].Template
self:F( { Template = Template } )
@@ -2978,14 +3197,19 @@ end
function SPAWN:_Prepare( SpawnTemplatePrefix, SpawnIndex ) -- R2.2
self:F( { self.SpawnTemplatePrefix, self.SpawnAliasPrefix } )
-- if not self.SpawnTemplate then
-- self.SpawnTemplate = self:_GetTemplate( SpawnTemplatePrefix )
-- end
-- if not self.SpawnTemplate then
-- self.SpawnTemplate = self:_GetTemplate( SpawnTemplatePrefix )
-- end
local SpawnTemplate
if self.TweakedTemplate ~= nil and self.TweakedTemplate == true then
BASE:I( "WARNING: You are using a tweaked template." )
SpawnTemplate = self.SpawnTemplate
if self.MooseNameing == true then
SpawnTemplate.name = self:SpawnGroupName( SpawnIndex )
else
SpawnTemplate.name = self:SpawnGroupName()
end
else
SpawnTemplate = self:_GetTemplate( SpawnTemplatePrefix )
SpawnTemplate.name = self:SpawnGroupName( SpawnIndex )
@@ -3039,6 +3263,7 @@ function SPAWN:_Prepare( SpawnTemplatePrefix, SpawnIndex ) -- R2.2
if type( Callsign ) ~= "number" then -- blue callsign
Callsign[2] = ((SpawnIndex - 1) % 10) + 1
local CallsignName = SpawnTemplate.units[UnitID].callsign["name"] -- #string
CallsignName = string.match(CallsignName,"^(%a+)") -- 2.8 - only the part w/o numbers
local CallsignLen = CallsignName:len()
SpawnTemplate.units[UnitID].callsign["name"] = CallsignName:sub( 1, CallsignLen ) .. SpawnTemplate.units[UnitID].callsign[2] .. SpawnTemplate.units[UnitID].callsign[3]
else
@@ -3115,7 +3340,58 @@ function SPAWN:_RandomizeTemplate( SpawnIndex )
return self
end
--- Private method that randomizes the @{Zone}s where the Group will be spawned.
--- Private method that sets the DCS#Vec2 where the Group will be spawned.
-- @param #SPAWN self
-- @param #number SpawnIndex
-- @return #SPAWN self
function SPAWN:_SetInitialPosition( SpawnIndex )
self:T( { self.SpawnTemplatePrefix, SpawnIndex, self.SpawnRandomizeZones } )
if self.SpawnFromNewPosition then
self:T( "Preparing Spawn at Vec2 ", self.SpawnInitPosition )
local SpawnVec2 = self.SpawnInitPosition
self:T( { SpawnVec2 = SpawnVec2 } )
local SpawnTemplate = self.SpawnGroups[SpawnIndex].SpawnTemplate
SpawnTemplate.route = SpawnTemplate.route or {}
SpawnTemplate.route.points = SpawnTemplate.route.points or {}
SpawnTemplate.route.points[1] = SpawnTemplate.route.points[1] or {}
SpawnTemplate.route.points[1].x = SpawnTemplate.route.points[1].x or 0
SpawnTemplate.route.points[1].y = SpawnTemplate.route.points[1].y or 0
self:T( { Route = SpawnTemplate.route } )
for UnitID = 1, #SpawnTemplate.units do
local UnitTemplate = SpawnTemplate.units[UnitID]
self:T( 'Before Translation SpawnTemplate.units[' .. UnitID .. '].x = ' .. UnitTemplate.x .. ', SpawnTemplate.units[' .. UnitID .. '].y = ' .. UnitTemplate.y )
local SX = UnitTemplate.x
local SY = UnitTemplate.y
local BX = SpawnTemplate.route.points[1].x
local BY = SpawnTemplate.route.points[1].y
local TX = SpawnVec2.x + (SX - BX)
local TY = SpawnVec2.y + (SY - BY)
UnitTemplate.x = TX
UnitTemplate.y = TY
-- TODO: Manage altitude based on landheight...
-- SpawnTemplate.units[UnitID].alt = SpawnVec2:
self:T( 'After Translation SpawnTemplate.units[' .. UnitID .. '].x = ' .. UnitTemplate.x .. ', SpawnTemplate.units[' .. UnitID .. '].y = ' .. UnitTemplate.y )
end
SpawnTemplate.route.points[1].x = SpawnVec2.x
SpawnTemplate.route.points[1].y = SpawnVec2.y
SpawnTemplate.x = SpawnVec2.x
SpawnTemplate.y = SpawnVec2.y
end
return self
end
--- Private method that randomizes the @{Core.Zone}s where the Group will be spawned.
-- @param #SPAWN self
-- @param #number SpawnIndex
-- @return #SPAWN self
@@ -3234,7 +3510,7 @@ end
-- TODO Need to delete this... _DATABASE does this now ...
--- @param #SPAWN self
-- @param #SPAWN self
-- @param Core.Event#EVENTDATA EventData
function SPAWN:_OnBirth( EventData )
self:F( self.SpawnTemplatePrefix )
@@ -3254,7 +3530,7 @@ function SPAWN:_OnBirth( EventData )
end
--- @param #SPAWN self
-- @param #SPAWN self
-- @param Core.Event#EVENTDATA EventData
function SPAWN:_OnDeadOrCrash( EventData )
self:F( self.SpawnTemplatePrefix )
@@ -3372,12 +3648,16 @@ end
-- @return #boolean True = Continue Scheduler
function SPAWN:_SpawnCleanUpScheduler()
self:F( { "CleanUp Scheduler:", self.SpawnTemplatePrefix } )
local SpawnGroup, SpawnCursor = self:GetFirstAliveGroup()
self:T( { "CleanUp Scheduler:", SpawnGroup, SpawnCursor } )
local IsHelo = false
while SpawnGroup do
IsHelo = SpawnGroup:IsHelicopter()
local SpawnUnits = SpawnGroup:GetUnits()
for UnitID, UnitData in pairs( SpawnUnits ) do
@@ -3390,8 +3670,8 @@ function SPAWN:_SpawnCleanUpScheduler()
self:T( { SpawnUnitName, Stamp } )
if Stamp.Vec2 then
if SpawnUnit:InAir() == false and SpawnUnit:GetVelocityKMH() < 1 then
local NewVec2 = SpawnUnit:GetVec2()
if (SpawnUnit:InAir() == false and SpawnUnit:GetVelocityKMH() < 1) or IsHelo then
local NewVec2 = SpawnUnit:GetVec2() or {x=0, y=0}
if (Stamp.Vec2.x == NewVec2.x and Stamp.Vec2.y == NewVec2.y) or (SpawnUnit:GetLife() <= 1) then
-- If the plane is not moving or dead , and is on the ground, assign it with a timestamp...
if Stamp.Time + self.SpawnCleanUpInterval < timer.getTime() then
@@ -3409,8 +3689,8 @@ function SPAWN:_SpawnCleanUpScheduler()
Stamp.Time = nil
end
else
if SpawnUnit:InAir() == false then
Stamp.Vec2 = SpawnUnit:GetVec2()
if SpawnUnit:InAir() == false or (IsHelo and SpawnUnit:GetLife() <= 1) then
Stamp.Vec2 = SpawnUnit:GetVec2() or {x=0, y=0}
if (SpawnUnit:GetVelocityKMH() < 1) then
Stamp.Time = timer.getTime()
end
+24 -13
View File
@@ -57,15 +57,15 @@
-- @extends Core.Base#BASE
--- Allows to spawn dynamically new @{Static}s into your mission.
--- Allows to spawn dynamically new @{Wrapper.Static}s into your mission.
--
-- Through creating a copy of an existing static object template as defined in the Mission Editor (ME), SPAWNSTATIC can retireve the properties of the defined static object template (like type, category etc),
-- and "copy" these properties to create a new static object and place it at the desired coordinate.
--
-- New spawned @{Static}s get **the same name** as the name of the template Static, or gets the given name when a new name is provided at the Spawn method.
-- By default, spawned @{Static}s will follow a naming convention at run-time:
-- New spawned @{Wrapper.Static}s get **the same name** as the name of the template Static, or gets the given name when a new name is provided at the Spawn method.
-- By default, spawned @{Wrapper.Static}s will follow a naming convention at run-time:
--
-- * Spawned @{Static}s will have the name _StaticName_#_nnn_, where _StaticName_ is the name of the **Template Static**, and _nnn_ is a **counter from 0 to 99999**.
-- * Spawned @{Wrapper.Static}s will have the name _StaticName_#_nnn_, where _StaticName_ is the name of the **Template Static**, and _nnn_ is a **counter from 0 to 99999**.
--
-- # SPAWNSTATIC Constructors
--
@@ -106,7 +106,7 @@
-- * @{#SPAWNSTATIC.Spawn}(Heading, NewName) spawns the static with the set parameters. Optionally, heading and name can be given. The name **must be unique**!
-- * @{#SPAWNSTATIC.SpawnFromCoordinate}(Coordinate, Heading, NewName) spawn the static at the given coordinate. Optionally, heading and name can be given. The name **must be unique**!
-- * @{#SPAWNSTATIC.SpawnFromPointVec2}(PointVec2, Heading, NewName) spawns the static at a POINT_VEC2 coordinate. Optionally, heading and name can be given. The name **must be unique**!
-- * @{#SPAWNSTATIC.SpawnFromZone}(Zone, Heading, NewName) spawns the static at the center of a @{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
--
@@ -131,7 +131,7 @@ SPAWNSTATIC = {
-- @field #number mass Cargo mass in kg.
-- @field #boolean canCargo Static can be a cargo.
--- Creates the main object to spawn a @{Static} defined in the mission editor (ME).
--- Creates the main object to spawn a @{Wrapper.Static} defined in the mission editor (ME).
-- @param #SPAWNSTATIC self
-- @param #string SpawnTemplateName Name of the static object in the ME. Each new static will have the name starting with this prefix.
-- @param DCS#country.id SpawnCountryID (Optional) The ID of the country.
@@ -158,7 +158,7 @@ function SPAWNSTATIC:NewFromStatic(SpawnTemplateName, SpawnCountryID)
return self
end
--- Creates the main object to spawn a @{Static} given a template table.
--- Creates the main object to spawn a @{Wrapper.Static} given a template table.
-- @param #SPAWNSTATIC self
-- @param #table SpawnTemplate Template used for spawning.
-- @param DCS#country.id CountryID The ID of the country. Default `country.id.USA`.
@@ -174,7 +174,7 @@ function SPAWNSTATIC:NewFromTemplate(SpawnTemplate, CountryID)
return self
end
--- Creates the main object to spawn a @{Static} from a given type.
--- Creates the main object to spawn a @{Wrapper.Static} from a given type.
-- NOTE that you have to init many other parameters as spawn coordinate etc.
-- @param #SPAWNSTATIC self
-- @param #string StaticType Type of the static.
@@ -275,7 +275,7 @@ end
--- Initialize as dead.
-- @param #SPAWNSTATIC self
-- @param #boolean IsCargo If true, this static is dead.
-- @param #boolean IsDead If true, this static is dead.
-- @return #SPAWNSTATIC self
function SPAWNSTATIC:InitDead(IsDead)
self.InitStaticDead=IsDead
@@ -336,7 +336,7 @@ function SPAWNSTATIC:Spawn(Heading, NewName)
end
--- Creates a new @{Static} from a POINT_VEC2.
--- Creates a new @{Wrapper.Static} from a POINT_VEC2.
-- @param #SPAWNSTATIC self
-- @param Core.Point#POINT_VEC2 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.
@@ -352,7 +352,7 @@ function SPAWNSTATIC:SpawnFromPointVec2(PointVec2, Heading, NewName)
end
--- Creates a new @{Static} from a COORDINATE.
--- Creates a new @{Wrapper.Static} from a COORDINATE.
-- @param #SPAWNSTATIC self
-- @param Core.Point#COORDINATE Coordinate The 3D coordinate where to spawn the static.
-- @param #number Heading (Optional) Heading The heading of the static in degrees. Default is 0 degrees.
@@ -375,7 +375,7 @@ function SPAWNSTATIC:SpawnFromCoordinate(Coordinate, Heading, NewName)
end
--- Creates a new @{Static} from a @{Zone}.
--- Creates a new @{Wrapper.Static} from a @{Core.Zone}.
-- @param #SPAWNSTATIC self
-- @param Core.Zone#ZONE_BASE Zone The Zone where to spawn the static.
-- @param #number Heading (Optional)The heading of the static in degrees. Default is the heading of the template.
@@ -467,7 +467,7 @@ function SPAWNSTATIC:_SpawnStatic(Template, CountryID)
self:T(Template)
-- Add static to the game.
local Static=nil
local Static=nil --DCS#StaticObject
if self.InitFarp then
@@ -487,6 +487,17 @@ function SPAWNSTATIC:_SpawnStatic(Template, CountryID)
-- ED's dirty way to spawn FARPS.
Static=coalition.addGroup(CountryID, -1, TemplateGroup)
-- Currently DCS 2.8 does not trigger birth events if FAPRS are spawned!
-- We create such an event. The airbase is registered in Core.Event
local Event = {
id = EVENTS.Birth,
time = timer.getTime(),
initiator = Static
}
-- Create BIRTH event.
world.onEvent(Event)
else
self:T("Spawning Static")
self:T2({Template=Template})
+76 -46
View File
@@ -5,7 +5,7 @@
-- SPOT implements the DCS Spot class functionality, but adds additional luxury to be able to:
--
-- * Spot for a defined duration.
-- * Updates of laer spot position every 0.2 seconds for moving targets.
-- * Updates of laser spot position every 0.2 seconds for moving targets.
-- * Wiggle the spot at the target.
-- * Provide a @{Wrapper.Unit} as a target, instead of a point.
-- * Implement a status machine, LaseOn, LaseOff.
@@ -13,18 +13,8 @@
-- ===
--
-- # Demo Missions
--
-- ### [SPOT Demo Missions source code]()
--
-- ### [SPOT Demo Missions, only for beta testers]()
--
-- ### [ALL Demo Missions pack of the last release](https://github.com/FlightControl-Master/MOOSE_MISSIONS/releases)
--
-- ===
--
-- # YouTube Channel
--
-- ### [SPOT YouTube Channel]()
-- ### [Demo Missions on GitHub](https://github.com/FlightControl-Master/MOOSE_MISSIONS)
--
-- ===
--
@@ -43,21 +33,22 @@
do
--- @type SPOT
---
-- @type SPOT
-- @extends Core.Fsm#FSM
--- Implements the target spotting or marking functionality, but adds additional luxury to be able to:
--
-- * Mark targets for a defined duration.
-- * Updates of laer spot position every 0.2 seconds for moving targets.
-- * Updates of laser spot position every 0.25 seconds for moving targets.
-- * Wiggle the spot at the target.
-- * Provide a @{Wrapper.Unit} as a target, instead of a point.
-- * Implement a status machine, LaseOn, LaseOff.
--
-- ## 1. SPOT constructor
--
-- * @{#SPOT.New}(..\Presentations\SPOT\Dia2.JPG): Creates a new SPOT object.
-- * @{#SPOT.New}(): Creates a new SPOT object.
--
-- ## 2. SPOT is a FSM
--
@@ -217,6 +208,8 @@ do
self.Recce = Recce
self.RecceName = self.Recce:GetName()
self.LaseScheduler = SCHEDULER:New( self )
@@ -236,21 +229,27 @@ do
-- @param #number LaserCode Laser code.
-- @param #number Duration Duration of lasing in seconds.
function SPOT:onafterLaseOn( From, Event, To, Target, LaserCode, Duration )
self:F( { "LaseOn", Target, LaserCode, Duration } )
self:T({From, Event, To})
self:T2( { "LaseOn", Target, LaserCode, Duration } )
local function StopLase( self )
self:LaseOff()
end
self.Target = Target
self.TargetName = Target:GetName()
self.LaserCode = LaserCode
self.Lasing = true
local RecceDcsUnit = self.Recce:GetDCSObject()
self.SpotIR = Spot.createInfraRed( RecceDcsUnit, { x = 0, y = 2, z = 0 }, Target:GetPointVec3():AddY(1):GetVec3() )
self.SpotLaser = Spot.createLaser( RecceDcsUnit, { x = 0, y = 2, z = 0 }, Target:GetPointVec3():AddY(1):GetVec3(), LaserCode )
local relativespot = self.relstartpos or { x = 0, y = 2, z = 0 }
self.SpotIR = Spot.createInfraRed( RecceDcsUnit, relativespot, Target:GetPointVec3():AddY(1):GetVec3() )
self.SpotLaser = Spot.createLaser( RecceDcsUnit, relativespot, Target:GetPointVec3():AddY(1):GetVec3(), LaserCode )
if Duration then
self.ScheduleID = self.LaseScheduler:Schedule( self, StopLase, {self}, Duration )
@@ -259,6 +258,8 @@ do
self:HandleEvent( EVENTS.Dead )
self:__Lasing( -1 )
return self
end
@@ -271,7 +272,7 @@ do
-- @param #number LaserCode Laser code.
-- @param #number Duration Duration of lasing in seconds.
function SPOT:onafterLaseOnCoordinate(From, Event, To, Coordinate, LaserCode, Duration)
self:F( { "LaseOnCoordinate", Coordinate, LaserCode, Duration } )
self:T2( { "LaseOnCoordinate", Coordinate, LaserCode, Duration } )
local function StopLase( self )
self:LaseOff()
@@ -293,55 +294,72 @@ do
end
self:__Lasing(-1)
return self
end
--- @param #SPOT self
---
-- @param #SPOT self
-- @param Core.Event#EVENTDATA EventData
function SPOT:OnEventDead(EventData)
self:F( { Dead = EventData.IniDCSUnitName, Target = self.Target } )
self:T2( { Dead = EventData.IniDCSUnitName, Target = self.Target } )
if self.Target then
if EventData.IniDCSUnitName == self.Target:GetName() then
self:F( {"Target dead ", self.Target:GetName() } )
if EventData.IniDCSUnitName == self.TargetName then
self:F( {"Target dead ", self.TargetName } )
self:Destroyed()
self:LaseOff()
end
end
if self.Recce then
if EventData.IniDCSUnitName == self.RecceName then
self:F( {"Recce dead ", self.RecceName } )
self:LaseOff()
end
end
return self
end
--- @param #SPOT self
---
-- @param #SPOT self
-- @param From
-- @param Event
-- @param To
function SPOT:onafterLasing( From, Event, To )
if self.Target and self.Target:IsAlive() then
self.SpotIR:setPoint( self.Target:GetPointVec3():AddY(1):AddY(math.random(-100,100)/100):AddX(math.random(-100,100)/100):GetVec3() )
self.SpotLaser:setPoint( self.Target:GetPointVec3():AddY(1):GetVec3() )
self:__Lasing( -0.2 )
elseif self.TargetCoord then
self:T({From, Event, To})
-- Wiggle the IR spot a bit.
local irvec3={x=self.TargetCoord.x+math.random(-100,100)/100, y=self.TargetCoord.y+math.random(-100,100)/100, z=self.TargetCoord.z} --#DCS.Vec3
local lsvec3={x=self.TargetCoord.x, y=self.TargetCoord.y, z=self.TargetCoord.z} --#DCS.Vec3
if self.Lasing then
if self.Target and self.Target:IsAlive() then
self.SpotIR:setPoint( self.Target:GetPointVec3():AddY(1):AddY(math.random(-100,100)/100):AddX(math.random(-100,100)/100):GetVec3() )
self.SpotLaser:setPoint( self.Target:GetPointVec3():AddY(1):GetVec3() )
self:__Lasing(0.2)
elseif self.TargetCoord then
self.SpotIR:setPoint(irvec3)
self.SpotLaser:setPoint(lsvec3)
self:__Lasing(-0.25)
else
self:F( { "Target is not alive", self.Target:IsAlive() } )
-- Wiggle the IR spot a bit.
local irvec3={x=self.TargetCoord.x+math.random(-100,100)/100, y=self.TargetCoord.y+math.random(-100,100)/100, z=self.TargetCoord.z} --#DCS.Vec3
local lsvec3={x=self.TargetCoord.x, y=self.TargetCoord.y, z=self.TargetCoord.z} --#DCS.Vec3
self.SpotIR:setPoint(irvec3)
self.SpotLaser:setPoint(lsvec3)
self:__Lasing(0.2)
else
self:F( { "Target is not alive", self.Target:IsAlive() } )
end
end
return self
end
--- @param #SPOT self
---
-- @param #SPOT self
-- @param From
-- @param Event
-- @param To
-- @return #SPOT
function SPOT:onafterLaseOff( From, Event, To )
self:F( {"Stopped lasing for ", self.Target and self.Target:GetName() or "coord", SpotIR = self.SportIR, SpotLaser = self.SpotLaser } )
self:T({From, Event, To})
self:T2( {"Stopped lasing for ", self.Target and self.Target:GetName() or "coord", SpotIR = self.SportIR, SpotLaser = self.SpotLaser } )
self.Lasing = false
@@ -368,4 +386,16 @@ do
return self.Lasing
end
end
--- Set laser start position relative to the lasing unit.
-- @param #SPOT self
-- @param #table position Start position of the laser relative to the lasing unit. Default is { x = 0, y = 2, z = 0 }
-- @return #SPOT self
-- @usage
-- -- Set lasing position to be the position of the optics of the Gazelle M:
-- myspot:SetRelativeStartPosition({ x = 1.7, y = 1.2, z = 0 })
function SPOT:SetRelativeStartPosition(position)
self.relstartpos = position or { x = 0, y = 2, z = 0 }
return self
end
end
@@ -0,0 +1,202 @@
--- **Core** - A Moose GetText system.
--
-- ===
--
-- ## Main Features:
--
-- * A GetText for Moose
-- * Build a set of localized text entries, alongside their sounds and subtitles
-- * Aimed at class developers to offer localizable language support
--
-- ===
--
-- ## Example Missions:
--
-- Demo missions can be found on [github](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/develop/).
--
-- ===
--
-- ### Author: **applevangelist**
-- ## Date: April 2022
--
-- ===
--
-- @module Core.TextAndSound
-- @image MOOSE.JPG
--- Text and Sound class.
-- @type TEXTANDSOUND
-- @field #string ClassName Name of this class.
-- @field #string version Versioning.
-- @field #string lid LID for log entries.
-- @field #string locale Default locale of this object.
-- @field #table entries Table of entries.
-- @field #string textclass Name of the class the texts belong to.
-- @extends Core.Base#BASE
---
--
-- @field #TEXTANDSOUND
TEXTANDSOUND = {
ClassName = "TEXTANDSOUND",
version = "0.0.1",
lid = "",
locale = "en",
entries = {},
textclass = "",
}
--- Text and Sound entry.
-- @type TEXTANDSOUND.Entry
-- @field #string Classname Name of the class this entry is for.
-- @field #string Locale Locale of this entry, defaults to "en".
-- @field #table Data The list of entries.
--- Text and Sound data
-- @type TEXTANDSOUND.Data
-- @field #string ID ID of this entry for retrieval.
-- @field #string Text Text of this entry.
-- @field #string Soundfile (optional) Soundfile File name of the corresponding sound file.
-- @field #number Soundlength (optional) Length of the sound file in seconds.
-- @field #string Subtitle (optional) Subtitle for the sound file.
--- Instantiate a new object
-- @param #TEXTANDSOUND self
-- @param #string ClassName Name of the class this instance is providing texts for.
-- @param #string Defaultlocale (Optional) Default locale of this instance, defaults to "en".
-- @return #TEXTANDSOUND self
function TEXTANDSOUND:New(ClassName,Defaultlocale)
-- Inherit everything from BASE class.
local self=BASE:Inherit(self, BASE:New())
-- Set some string id for output to DCS.log file.
self.lid=string.format("%s (%s) | ", self.ClassName, self.version)
self.locale = Defaultlocale or (_SETTINGS:GetLocale() or "en")
self.textclass = ClassName or "none"
self.entries = {}
local initentry = {} -- #TEXTANDSOUND.Entry
initentry.Classname = ClassName
initentry.Data = {}
initentry.Locale = self.locale
self.entries[self.locale] = initentry
self:I(self.lid .. "Instantiated.")
self:T({self.entries[self.locale]})
return self
end
--- Add an entry
-- @param #TEXTANDSOUND self
-- @param #string Locale Locale to set for this entry, e.g. "de".
-- @param #string ID Unique(!) ID of this entry under this locale (i.e. use the same ID to get localized text for the entry in another language).
-- @param #string Text Text for this entry.
-- @param #string Soundfile (Optional) Sound file name for this entry.
-- @param #number Soundlength (Optional) Length of the sound file in seconds.
-- @param #string Subtitle (Optional) Subtitle to be used alongside the sound file.
-- @return #TEXTANDSOUND self
function TEXTANDSOUND:AddEntry(Locale,ID,Text,Soundfile,Soundlength,Subtitle)
self:T(self.lid .. "AddEntry")
local locale = Locale or self.locale
local dataentry = {} -- #TEXTANDSOUND.Data
dataentry.ID = ID or "1"
dataentry.Text = Text or "none"
dataentry.Soundfile = Soundfile
dataentry.Soundlength = Soundlength or 0
dataentry.Subtitle = Subtitle
if not self.entries[locale] then
local initentry = {} -- #TEXTANDSOUND.Entry
initentry.Classname = self.textclass -- class name entry
initentry.Data = {} -- data array
initentry.Locale = locale -- default locale
self.entries[locale] = initentry
end
self.entries[locale].Data[ID] = dataentry
self:T({self.entries[locale].Data})
return self
end
--- Get an entry
-- @param #TEXTANDSOUND self
-- @param #string ID The unique ID of the data to be retrieved.
-- @param #string Locale (Optional) The locale of the text to be retrieved - defauls to default locale set with `New()`.
-- @return #string Text Text or nil if not found and no fallback.
-- @return #string Soundfile Filename or nil if not found and no fallback.
-- @return #string Soundlength Length of the sound or 0 if not found and no fallback.
-- @return #string Subtitle Text for subtitle or nil if not found and no fallback.
function TEXTANDSOUND:GetEntry(ID,Locale)
self:T(self.lid .. "GetEntry")
local locale = Locale or self.locale
if not self.entries[locale] then
-- fall back to default "en"
locale = self.locale
end
local Text,Soundfile,Soundlength,Subtitle = nil, nil, 0, nil
if self.entries[locale] then
if self.entries[locale].Data then
local data = self.entries[locale].Data[ID] -- #TEXTANDSOUND.Data
if data then
Text = data.Text
Soundfile = data.Soundfile
Soundlength = data.Soundlength
Subtitle = data.Subtitle
elseif self.entries[self.locale].Data[ID] then
-- no matching entry, try default
local data = self.entries[self.locale].Data[ID]
Text = data.Text
Soundfile = data.Soundfile
Soundlength = data.Soundlength
Subtitle = data.Subtitle
end
end
else
return nil, nil, 0, nil
end
return Text,Soundfile,Soundlength,Subtitle
end
--- Get the default locale of this object
-- @param #TEXTANDSOUND self
-- @return #string locale
function TEXTANDSOUND:GetDefaultLocale()
self:T(self.lid .. "GetDefaultLocale")
return self.locale
end
--- Set default locale of this object
-- @param #TEXTANDSOUND self
-- @param #string locale
-- @return #TEXTANDSOUND self
function TEXTANDSOUND:SetDefaultLocale(locale)
self:T(self.lid .. "SetDefaultLocale")
self.locale = locale or "en"
return self
end
--- Check if a locale exists
-- @param #TEXTANDSOUND self
-- @return #boolean outcome
function TEXTANDSOUND:HasLocale(Locale)
self:T(self.lid .. "HasLocale")
return self.entries[Locale] and true or false
end
--- Flush all entries to the log
-- @param #TEXTANDSOUND self
-- @return #TEXTANDSOUND self
function TEXTANDSOUND:FlushToLog()
self:I(self.lid .. "Flushing entries:")
local text = string.format("Textclass: %s | Default Locale: %s",self.textclass, self.locale)
for _,_entry in pairs(self.entries) do
local entry = _entry -- #TEXTANDSOUND.Entry
local text = string.format("Textclassname: %s | Locale: %s",entry.Classname, entry.Locale)
self:I(text)
for _ID,_data in pairs(entry.Data) do
local data = _data -- #TEXTANDSOUND.Data
local text = string.format("ID: %s\nText: %s\nSoundfile: %s With length: %d\nSubtitle: %s",tostring(_ID), data.Text or "none",data.Soundfile or "none",data.Soundlength or 0,data.Subtitle or "none")
self:I(text)
end
end
return self
end
----------------------------------------------------------------
-- End TextAndSound
----------------------------------------------------------------
+44 -18
View File
@@ -34,8 +34,6 @@
--
-- ===
--
-- ![Banner Image](..\Presentations\Timer\TIMER_Main.jpg)
--
-- # The TIMER Concept
--
-- The TIMER class is the little sister of the @{Core.Scheduler#SCHEDULER} class. It does the same thing but is a bit easier to use and has less overhead. It should be sufficient in many cases.
@@ -107,19 +105,17 @@ TIMER = {
--- Timer ID.
_TIMERID=0
--- Timer data base.
--_TIMERDB={}
--- TIMER class version.
-- @field #string version
TIMER.version="0.1.1"
TIMER.version="0.2.0"
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO list
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO: A lot.
-- TODO: Write docs.
-- TODO: Randomization.
-- TODO: Pause/unpause.
-- DONE: Write docs.
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Constructor
@@ -156,13 +152,10 @@ function TIMER:New(Function, ...)
-- Log id.
self.lid=string.format("TIMER UID=%d | ", self.uid)
-- Add to DB.
--_TIMERDB[self.uid]=self
return self
end
--- Create a new TIMER object.
--- Start TIMER object.
-- @param #TIMER self
-- @param #number Tstart Relative start time in seconds.
-- @param #number dT Interval between function calls in seconds. If not specified `nil`, the function is called only once.
@@ -174,7 +167,7 @@ function TIMER:Start(Tstart, dT, Duration)
local Tnow=timer.getTime()
-- Start time in sec.
self.Tstart=Tstart and Tnow+Tstart or Tnow+0.001 -- one millisecond delay if Tstart=nil
self.Tstart=Tstart and Tnow+math.max(Tstart, 0.001) or Tnow+0.001 -- one millisecond delay if Tstart=nil
-- Set time interval.
self.dT=dT
@@ -199,6 +192,20 @@ function TIMER:Start(Tstart, dT, Duration)
return self
end
--- Start TIMER object if a condition is met. Useful for e.g. debugging.
-- @param #TIMER self
-- @param #boolean Condition Must be true for the TIMER to start
-- @param #number Tstart Relative start time in seconds.
-- @param #number dT Interval between function calls in seconds. If not specified `nil`, the function is called only once.
-- @param #number Duration Time in seconds for how long the timer is running. If not specified `nil`, the timer runs forever or until stopped manually by the `TIMER:Stop()` function.
-- @return #TIMER self
function TIMER:StartIf(Condition,Tstart, dT, Duration)
if Condition then
self:Start(Tstart, dT, Duration)
end
return self
end
--- Stop the timer by removing the timer function.
-- @param #TIMER self
-- @param #number Delay (Optional) Delay in seconds, before the timer is stopped.
@@ -215,14 +222,24 @@ function TIMER:Stop(Delay)
-- Remove timer function.
self:T(self.lid..string.format("Stopping timer by removing timer function after %d calls!", self.ncalls))
timer.removeFunction(self.tid)
-- We use a pcall here because if the DCS timer does not exist any more, it crashes the whole script!
local status=pcall(
function ()
timer.removeFunction(self.tid)
end
)
-- Debug messages.
if status then
self:T2(self.lid..string.format("Stopped timer!"))
else
self:E(self.lid..string.format("WARNING: Could not remove timer function! isrunning=%s", tostring(self.isrunning)))
end
-- Not running any more.
self.isrunning=false
-- Remove DB entry.
--_TIMERDB[self.uid]=nil
end
end
@@ -239,6 +256,15 @@ function TIMER:SetMaxFunctionCalls(Nmax)
return self
end
--- Set time interval. Can also be set when the timer is already running and is applied after the next function call.
-- @param #TIMER self
-- @param #number dT Time interval in seconds.
-- @return #TIMER self
function TIMER:SetTimeInterval(dT)
self.dT=dT
return self
end
--- Check if the timer has been started and was not stopped.
-- @param #TIMER self
-- @return #boolean If `true`, the timer is running.
+13 -16
View File
@@ -35,13 +35,13 @@ do -- UserFlag
ClassName = "USERFLAG",
UserFlagName = nil,
}
--- USERFLAG Constructor.
-- @param #USERFLAG self
-- @param #string UserFlagName The name of the userflag, which is a free text string.
-- @return #USERFLAG
function USERFLAG:New( UserFlagName ) --R2.3
local self = BASE:Inherit( self, BASE:New() ) -- #USERFLAG
self.UserFlagName = UserFlagName
@@ -52,7 +52,7 @@ do -- UserFlag
--- Get the userflag name.
-- @param #USERFLAG self
-- @return #string Name of the user flag.
function USERFLAG:GetName()
function USERFLAG:GetName()
return self.UserFlagName
end
@@ -66,18 +66,17 @@ do -- UserFlag
-- BlueVictory:Set( 100 ) -- Set the UserFlag VictoryBlue to 100.
--
function USERFLAG:Set( Number, Delay ) --R2.3
if Delay and Delay>0 then
self:ScheduleOnce(Delay, USERFLAG.Set, self, Number)
else
--env.info(string.format("Setting flag \"%s\" to %d at T=%.1f", self.UserFlagName, Number, timer.getTime()))
trigger.action.setUserFlag( self.UserFlagName, Number )
end
return self
end
return self
end
--- Get the userflag Number.
-- @param #USERFLAG self
-- @return #number Number The number value to be checked if it is the same as the userflag.
@@ -86,12 +85,10 @@ do -- UserFlag
-- local BlueVictoryValue = BlueVictory:Get() -- Get the UserFlag VictoryBlue value.
--
function USERFLAG:Get() --R2.3
return trigger.misc.getUserFlag( self.UserFlagName )
end
return trigger.misc.getUserFlag( self.UserFlagName )
end
--- Check if the userflag has a value of Number.
-- @param #USERFLAG self
-- @param #number Number The number value to be checked if it is the same as the userflag.
@@ -102,9 +99,9 @@ do -- UserFlag
-- return "Blue has won"
-- end
function USERFLAG:Is( Number ) --R2.3
return trigger.misc.getUserFlag( self.UserFlagName ) == Number
end
end
end
+11 -12
View File
@@ -54,7 +54,7 @@ do -- Velocity
self.Velocity = VelocityMps
return self
end
--- Get the velocity in Mps (meters per second).
-- @param #VELOCITY self
-- @return #number The velocity in meters per second.
@@ -70,12 +70,12 @@ do -- Velocity
self.Velocity = UTILS.KmphToMps( VelocityKmph )
return self
end
--- Get the velocity in Kmph (kilometers per hour).
-- @param #VELOCITY self
-- @return #number The velocity in kilometers per hour.
function VELOCITY:GetKmph()
return UTILS.MpsToKmph( self.Velocity )
end
@@ -87,7 +87,7 @@ do -- Velocity
self.Velocity = UTILS.MiphToMps( VelocityMiph )
return self
end
--- Get the velocity in Miph (miles per hour).
-- @param #VELOCITY self
-- @return #number The velocity in miles per hour.
@@ -95,8 +95,7 @@ do -- Velocity
return UTILS.MpsToMiph( self.Velocity )
end
--- Get the velocity in text, according the player @{Settings}.
--- Get the velocity in text, according the player @{Core.Settings}.
-- @param #VELOCITY self
-- @param Core.Settings#SETTINGS Settings
-- @return #string The velocity in text.
@@ -113,11 +112,11 @@ do -- Velocity
end
end
--- Get the velocity in text, according the player or default @{Settings}.
--- Get the velocity in text, according the player or default @{Core.Settings}.
-- @param #VELOCITY self
-- @param Wrapper.Controllable#CONTROLLABLE Controllable
-- @param Core.Settings#SETTINGS Settings
-- @return #string The velocity in text according the player or default @{Settings}
-- @return #string The velocity in text according the player or default @{Core.Settings}
function VELOCITY:ToString( VelocityGroup, Settings ) -- R2.3
self:F( { Group = VelocityGroup and VelocityGroup:GetName() } )
local Settings = Settings or ( VelocityGroup and _DATABASE:GetPlayerSettings( VelocityGroup:GetPlayerName() ) ) or _SETTINGS
@@ -134,7 +133,7 @@ do -- VELOCITY_POSITIONABLE
--- # VELOCITY_POSITIONABLE class, extends @{Core.Base#BASE}
--
-- VELOCITY_POSITIONABLE monitors the speed of an @{Positionable} in the simulation, which can be expressed in various formats according the Settings.
-- @{#VELOCITY_POSITIONABLE} monitors the speed of a @{Wrapper.Positionable#POSITIONABLE} in the simulation, which can be expressed in various formats according the Settings.
--
-- ## 1. VELOCITY_POSITIONABLE constructor
--
@@ -167,7 +166,7 @@ do -- VELOCITY_POSITIONABLE
-- @param #VELOCITY_POSITIONABLE self
-- @return #number The velocity in kilometers per hour.
function VELOCITY_POSITIONABLE:GetKmph()
return UTILS.MpsToKmph( self.Positionable:GetVelocityMPS() or 0)
end
@@ -178,9 +177,9 @@ do -- VELOCITY_POSITIONABLE
return UTILS.MpsToMiph( self.Positionable:GetVelocityMPS() or 0 )
end
--- Get the velocity in text, according the player or default @{Settings}.
--- Get the velocity in text, according the player or default @{Core.Settings}.
-- @param #VELOCITY_POSITIONABLE self
-- @return #string The velocity in text according the player or default @{Settings}
-- @return #string The velocity in text according the player or default @{Core.Settings}
function VELOCITY_POSITIONABLE:ToString() -- R2.3
self:F( { Group = self.Positionable and self.Positionable:GetName() } )
local Settings = Settings or ( self.Positionable and _DATABASE:GetPlayerSettings( self.Positionable:GetPlayerName() ) ) or _SETTINGS
File diff suppressed because it is too large Load Diff
@@ -1,6 +1,8 @@
--- **Core** - The ZONE_DETECTION class, defined by a zone name, a detection object and a radius.
-- @module Core.Zone_Detection
-- @image MOOSE.JPG
--- The ZONE_DETECTION class, defined by a zone name, a detection object and a radius.
-- @type ZONE_DETECTION
--- @type ZONE_DETECTION
-- @field DCS#Vec2 Vec2 The current location of the zone.
-- @field DCS#Distance Radius The radius of the zone.
-- @extends #ZONE_BASE
@@ -29,7 +31,7 @@ function ZONE_DETECTION:New( ZoneName, Detection, Radius )
self.Detection = Detection
self.Radius = Radius
return self
end
@@ -48,15 +50,14 @@ function ZONE_DETECTION:BoundZone( Points, CountryID, UnBound )
local Angle
local RadialBase = math.pi*2
--
for Angle = 0, 360, (360 / Points ) do
local Radial = Angle * RadialBase / 360
Point.x = Vec2.x + math.cos( Radial ) * self:GetRadius()
Point.y = Vec2.y + math.sin( Radial ) * self:GetRadius()
local CountryName = _DATABASE.COUNTRY_NAME[CountryID]
local Tire = {
["country"] = CountryName,
["category"] = "Fortifications",
+137 -24
View File
@@ -1,4 +1,6 @@
--- **DCS API** Prototypes
--- **DCS API** Prototypes.
--
-- ===
--
-- See the [Simulator Scripting Engine Documentation](https://wiki.hoggitworld.com/view/Simulator_Scripting_Engine_Documentation) on Hoggit for further explanation and examples.
--
@@ -191,21 +193,29 @@ do -- land
--- [Type of surface enumerator](https://wiki.hoggitworld.com/view/DCS_singleton_land)
-- @type land.SurfaceType
-- @field LAND
-- @field SHALLOW_WATER
-- @field WATER
-- @field ROAD
-- @field RUNWAY
-- @field LAND Land=1
-- @field SHALLOW_WATER Shallow water=2
-- @field WATER Water=3
-- @field ROAD Road=4
-- @field RUNWAY Runway=5
--- Returns altitude MSL of the point.
--- Returns the distance from sea level (y-axis) of a given vec2 point.
-- @function [parent=#land] getHeight
-- @param #Vec2 point point on the ground.
-- @return #Distance
-- @param #Vec2 point Point on the ground.
-- @return #number Height in meters.
--- Returns the surface height and depth of a point. Useful for checking if the path is deep enough to support a given ship.
-- Both values are positive. When checked over water at sea level the first value is always zero.
-- When checked over water at altitude, for example the reservoir of the Inguri Dam, the first value is the corresponding altitude the water level is at.
-- @function [parent=#land] getSurfaceHeightWithSeabed
-- @param #Vec2 point Position where to check.
-- @return #number Height in meters.
-- @return #number Depth in meters.
--- returns surface type at the given point.
--- Returns surface type at the given point.
-- @function [parent=#land] getSurfaceType
-- @param #Vec2 point Point on the land.
-- @return #land.SurfaceType
-- @return #number Enumerator value from `land.SurfaceType` (LAND=1, SHALLOW_WATER=2, WATER=3, ROAD=4, RUNWAY=5)
--- [DCS Singleton land](https://wiki.hoggitworld.com/view/DCS_singleton_land)
land = {} --#land
@@ -306,6 +316,11 @@ do -- country
-- @field Argentinia
-- @field Cyprus
-- @field Slovenia
-- @field BOLIVIA
-- @field GHANA
-- @field NIGERIA
-- @field PERU
-- @field ECUADOR
country = {} --#country
@@ -334,9 +349,23 @@ do -- coalition
-- @field RED
-- @field BLUE
--- @function [parent=#coalition] getCountryCoalition
-- @param #number countryId
-- @return #number coalitionId
--- Get country coalition.
-- @function [parent=#coalition] getCountryCoalition
-- @param #number countryId Country ID.
-- @return #number coalitionId Coalition ID.
--- Dynamically spawns a group. See [hoggit](https://wiki.hoggitworld.com/view/DCS_func_addGroup)
-- @function [parent=#coalition] addGroup
-- @param #number countryId Id of the country.
-- @param #number groupCategory Group category. Set -1 for spawning FARPS.
-- @param #table groupData Group data table.
-- @return DCS#Group The spawned Group object.
--- Dynamically spawns a static object. See [hoggit](https://wiki.hoggitworld.com/view/DCS_func_addGroup)
-- @function [parent=#coalition] addStaticObject
-- @param #number countryId Id of the country.
-- @param #table groupData Group data table.
-- @return DCS#Static The spawned static object.
coalition = {} -- #coalition
@@ -406,8 +435,8 @@ do -- Types
--- Vec3 type is a 3D-vector.
-- DCS world has 3-dimensional coordinate system. DCS ground is an infinite plain.
-- @type Vec3
-- @field #Distance x is directed to the north
-- @field #Distance z is directed to the east
-- @field #Distance x is directed to the North
-- @field #Distance z is directed to the East
-- @field #Distance y is directed up
--- Vec2 is a 2D-vector for the ground plane as a reference plane.
@@ -471,6 +500,22 @@ do -- Types
--@field #boolean lateActivated
--@field #boolean uncontrolled
--- DCS template data structure.
-- @type Template
-- @field #boolean uncontrolled Aircraft is uncontrolled.
-- @field #boolean lateActivation Group is late activated.
-- @field #number x 2D Position on x-axis in meters.
-- @field #number y 2D Position on y-axis in meters.
-- @field #table units Unit list.
--
--- Unit data structure.
--@type Template.Unit
--@field #string name Name of the unit.
--@field #number x
--@field #number y
--@field #number alt
end --
@@ -490,7 +535,6 @@ do -- Object
-- @field BASE
-- @field SCENERY
-- @field CARGO
--- @type Object.Desc
-- @extends #Desc
@@ -500,6 +544,10 @@ do -- Object
--- @function [parent=#Object] isExist
-- @param #Object self
-- @return #boolean
--- @function [parent=#Object] isActive
-- @param #Object self
-- @return #boolean
--- @function [parent=#Object] destroy
-- @param #Object self
@@ -639,10 +687,11 @@ do -- Weapon
--- Weapon.Category enum that stores weapon categories.
-- @type Weapon.Category
-- @field SHELL
-- @field MISSILE
-- @field ROCKET
-- @field BOMB
-- @field #number SHELL Shell.
-- @field #number MISSILE Missile
-- @field #number ROCKET Rocket.
-- @field #number BOMB Bomb.
-- @field #number TORPEDO Torpedo.
--- Weapon.GuidanceType enum that stores guidance methods. Available only for guided weapon (Weapon.Category.MISSILE and some Weapon.Category.BOMB).
@@ -961,8 +1010,8 @@ do -- Unit
--- Enum that stores aircraft refueling system types.
-- @type Unit.RefuelingSystem
-- @field BOOM_AND_RECEPTACLE
-- @field PROBE_AND_DROGUE
-- @field BOOM_AND_RECEPTACLE Tanker with a boom.
-- @field PROBE_AND_DROGUE Tanker with a probe.
--- Enum that stores sensor types.
-- @type Unit.SensorType
@@ -1132,6 +1181,11 @@ do -- Unit
-- @function [parent=#Unit] getAmmo
-- @param #Unit self
-- @return #Unit.Ammo
--- Returns the number of infantry that can be embark onto the aircraft. Only returns a value if run on airplanes or helicopters. Returns nil if run on ground or ship units.
-- @function [parent=#Unit] getDescentCapacity
-- @param #Unit self
-- @return #number Number of soldiers that embark.
--- Returns the unit sensors.
-- @function [parent=#Unit] getSensors
@@ -1263,6 +1317,42 @@ do -- Group
end -- Group
do -- StaticObject
--- Represents a static object.
-- @type StaticObject
-- @extends DCS#Object
--- Returns the static object.
-- @function [parent=#StaticObject] getByName
-- @param #string name Name of the static object.
-- @return #StaticObject
StaticObject = {} --#StaticObject
end
do --Event
--- Event structure. Note that present fields depend on type of event.
-- @type Event
-- @field #number id Event ID.
-- @field #number time Mission time in seconds.
-- @field DCS#Unit initiator Unit initiating the event.
-- @field DCS#Unit target Target unit.
-- @field DCS#Airbase place Airbase.
-- @field number subPlace Subplace. Unknown and often just 0.
-- @field #string weapon_name Weapoin name.
-- @field #number idx Mark ID.
-- @field #number coalition Coalition ID.
-- @field #number groupID Group ID, *e.g.* of group that added mark point.
-- @field #string text Text, *e.g.* of mark point.
-- @field DCS#Vec3 pos Position vector, *e.g.* of mark point.
-- @field #string comment Comment, *e.g.* LSO score.
Event={} --#Event
end
do -- AI
@@ -1350,7 +1440,9 @@ do -- AI
--- @type AI.Option.Ground
-- @field #AI.Option.Ground.id id
-- @field #AI.Option.Ground.val val
-- @field #AI.Option.Ground.mid mid
-- @field #AI.Option.Ground.mval mval
--
--- @type AI.Option.Naval
-- @field #AI.Option.Naval.id id
-- @field #AI.Option.Naval.val val
@@ -1373,6 +1465,11 @@ do -- AI
-- @field PROHIBIT_AG
-- @field MISSILE_ATTACK
-- @field PROHIBIT_WP_PASS_REPORT
-- @field OPTION_RADIO_USAGE_CONTACT
-- @field OPTION_RADIO_USAGE_ENGAGE
-- @field OPTION_RADIO_USAGE_KILL
-- @field JETT_TANKS_IF_EMPTY
-- @field FORCED_ATTACK
--- @type AI.Option.Air.id.FORMATION
-- @field LINE_ABREAST
@@ -1442,19 +1539,35 @@ do -- AI
--- @type AI.Option.Ground.id
-- @field NO_OPTION
-- @field ROE @{#AI.Option.Ground.val.ROE}
-- @field FORMATION
-- @field DISPERSE_ON_ATTACK true or false
-- @field ALARM_STATE @{#AI.Option.Ground.val.ALARM_STATE}
-- @field ENGAGE_AIR_WEAPONS
-- @field AC_ENGAGEMENT_RANGE_RESTRICTION
--- @type AI.Option.Ground.mid -- Moose added
-- @field RESTRICT_AAA_MIN 27
-- @field RESTRICT_AAA_MAX 29
-- @field RESTRICT_TARGETS @{#AI.Option.Ground.mval.ENGAGE_TARGETS} 28
--- @type AI.Option.Ground.val
-- @field #AI.Option.Ground.val.ROE ROE
-- @field #AI.Option.Ground.val.ALARM_STATE ALARM_STATE
-- @field #AI.Option.Ground.val.ENGAGE_TARGETS RESTRICT_TARGETS
--- @type AI.Option.Ground.val.ROE
-- @field OPEN_FIRE
-- @field RETURN_FIRE
-- @field WEAPON_HOLD
--- @type AI.Option.Ground.mval -- Moose added
-- @field #AI.Option.Ground.mval.ENGAGE_TARGETS ENGAGE_TARGETS
--- @type AI.Option.Ground.mval.ENGAGE_TARGETS -- Moose added
-- @field ANY_TARGET -- 0
-- @field AIR_UNITS_ONLY -- 1
-- @field GROUND_UNITS_ONLY -- 2
--- @type AI.Option.Ground.val.ALARM_STATE
-- @field AUTO
-- @field GREEN
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,806 @@
--- **Functional** -- Send a truck to supply artillery groups.
--
-- ===
--
-- **AMMOTRUCK** - Send a truck to supply artillery groups.
--
-- ===
--
-- ## Missions:
--
-- ### [AmmoTruck](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/develop/AMT%20-%20AmmoTruck/AmmoTruck%20100%20-%20NTTR%20-%20Basic)
--
-- ===
--
-- ### Author : **applevangelist**
--
-- @module Functional.AmmoTruck
-- @image Artillery.JPG
--
-- Last update: July 2023
-------------------------------------------------------------------------
--- **AMMOTRUCK** class, extends Core.FSM#FSM
-- @type AMMOTRUCK
-- @field #string ClassName Class Name
-- @field #string lid Lid for log entries
-- @field #string version Version string
-- @field #string alias Alias name
-- @field #boolean debug Debug flag
-- @field #table trucklist List of (alive) #AMMOTRUCK.data trucks
-- @field #table targetlist List of (alive) #AMMOTRUCK.data artillery
-- @field #number coalition Coalition this is for
-- @field Core.Set#SET_GROUP truckset SET of trucks
-- @field Core.Set#SET_GROUP targetset SET of artillery
-- @field #table remunitionqueue List of (alive) #AMMOTRUCK.data artillery to be reloaded
-- @field #table waitingtargets List of (alive) #AMMOTRUCK.data artillery waiting
-- @field #number ammothreshold Threshold (min) ammo before sending a truck
-- @field #number remunidist Max distance trucks will go
-- @field #number monitor Monitor interval in seconds
-- @field #number unloadtime Unload time in seconds
-- @field #number waitingtime Max waiting time in seconds
-- @field #boolean routeonroad Route truck on road if true (default)
-- @field #number reloads Number of reloads a single truck can do before he must return home
-- @extends Core.FSM#FSM
--- *Amateurs talk about tactics, but professionals study logistics.* - General Robert H Barrow, USMC
--
-- Simple Class to re-arm your artillery with trucks.
--
-- #AMMOTRUCK
--
-- * Controls a SET\_GROUP of trucks which will re-arm a SET\_GROUP of artillery groups when they run out of ammunition.
--
-- ## 1 The AMMOTRUCK concept
--
-- A SET\_GROUP of trucks which will re-arm a SET\_GROUP of artillery groups when they run out of ammunition. They will be based on a
-- homebase and drive from there to the artillery groups and then back home.
-- Trucks are the **only known in-game mechanic** to re-arm artillery and other units in DCS. Working units are e.g.: M-939 (blue), Ural-375 and ZIL-135 (both red).
--
-- ## 2 Set-up
--
-- Define a set of trucks and a set of artillery:
--
-- local truckset = SET_GROUP:New():FilterCoalitions("blue"):FilterActive(true):FilterCategoryGround():FilterPrefixes("Ammo Truck"):FilterStart()
-- local ariset = SET_GROUP:New():FilterCoalitions("blue"):FilterActive(true):FilterCategoryGround():FilterPrefixes("Artillery"):FilterStart()
--
-- Create an AMMOTRUCK object to take care of the artillery using the trucks, with a homezone:
--
-- local ammotruck = AMMOTRUCK:New(truckset,ariset,coalition.side.BLUE,"Logistics",ZONE:FindByName("HomeZone")
--
-- ## 2 Options and their default values
--
-- ammotruck.ammothreshold = 5 -- send a truck when down to this many rounds
-- ammotruck.remunidist = 20000 -- 20km - send trucks max this far from home
-- ammotruck.unloadtime = 600 -- 10 minutes - min time to unload ammunition
-- ammotruck.waitingtime = 1800 -- 30 mintes - wait max this long until remunition is done
-- ammotruck.monitor = -60 -- 1 minute - AMMOTRUCK checks run every one minute
-- ammotruck.routeonroad = true -- Trucks will **try** to drive on roads
-- ammotruck.usearmygroup = false -- If true, will make use of ARMYGROUP in the background (if used in DEV branch)
-- ammotruck.reloads = 5 -- Maxn re-arms a truck can do before he needs to go home and restock. Set to -1 for unlimited
--
-- ## 3 FSM Events to shape mission
--
-- Truck has been sent off:
--
-- function ammotruck:OnAfterRouteTruck(From, Event, To, Truckdata, Aridata)
-- ...
-- end
--
-- Truck has arrived:
--
-- function ammotruck:OnAfterTruckArrived(From, Event, To, Truckdata)
-- ...
-- end
--
-- Truck is unloading:
--
-- function ammotruck:OnAfterTruckUnloading(From, Event, To, Truckdata)
-- ...
-- end
--
-- Truck is returning home:
--
-- function ammotruck:OnAfterTruckReturning(From, Event, To, Truckdata)
-- ...
-- end
--
-- Truck is arrived at home:
--
-- function ammotruck:OnAfterTruckHome(From, Event, To, Truckdata)
-- ...
-- end
--
-- @field #AMMOTRUCK
AMMOTRUCK = {
ClassName = "AMMOTRUCK",
lid = "",
version = "0.0.12",
alias = "",
debug = false,
trucklist = {},
targetlist = {},
coalition = nil,
truckset = nil,
targetset = nil,
remunitionqueue = {},
waitingtargets = {},
ammothreshold = 5,
remunidist = 20000,
monitor = -60,
unloadtime = 600,
waitingtime = 1800,
routeonroad = true,
reloads = 5,
}
---
-- @type AMMOTRUCK.State
AMMOTRUCK.State = {
IDLE = "idle",
DRIVING = "driving",
ARRIVED = "arrived",
UNLOADING = "unloading",
RETURNING = "returning",
WAITING = "waiting",
RELOADING = "reloading",
OUTOFAMMO = "outofammo",
REQUESTED = "requested",
}
---
--@type AMMOTRUCK.data
--@field Wrapper.Group#GROUP group
--@field #string name
--@field #AMMOTRUCK.State statusquo
--@field #number timestamp
--@field #number ammo
--@field Core.Point#COORDINATE coordinate
--@field #string targetname
--@field Wrapper.Group#GROUP targetgroup
--@field Core.Point#COORDINATE targetcoordinate
--@field #number reloads
---
-- @param #AMMOTRUCK self
-- @param Core.Set#SET_GROUP Truckset Set of truck groups
-- @param Core.Set#SET_GROUP Targetset Set of artillery groups
-- @param #number Coalition Coalition
-- @param #string Alias Alias Name
-- @param Core.Zone#ZONE Homezone Home, return zone for trucks
-- @return #AMMOTRUCK self
-- @usage
-- Define a set of trucks and a set of artillery:
-- local truckset = SET_GROUP:New():FilterCoalitions("blue"):FilterActive(true):FilterCategoryGround():FilterPrefixes("Ammo Truck"):FilterStart()
-- local ariset = SET_GROUP:New():FilterCoalitions("blue"):FilterActive(true):FilterCategoryGround():FilterPrefixes("Artillery"):FilterStart()
--
-- Create an AMMOTRUCK object to take care of the artillery using the trucks, with a homezone:
-- local ammotruck = AMMOTRUCK:New(truckset,ariset,coalition.side.BLUE,"Logistics",ZONE:FindByName("HomeZone")
function AMMOTRUCK:New(Truckset,Targetset,Coalition,Alias,Homezone)
-- Inherit everything from BASE class.
local self=BASE:Inherit(self, FSM:New()) -- #AMMOTRUCK
self.truckset = Truckset -- Core.Set#SET_GROUP
self.targetset = Targetset -- Core.Set#SET_GROUP
self.coalition = Coalition -- #number
self.alias = Alias -- #string
self.debug = false
self.remunitionqueue = {}
self.trucklist = {}
self.targetlist = {}
self.ammothreshold = 5
self.remunidist = 20000
self.homezone = Homezone -- Core.Zone#ZONE
self.waitingtime = 1800
self.usearmygroup = false
self.hasarmygroup = false
-- Log id.
self.lid=string.format("AMMOTRUCK %s | %s | ", self.version, self.alias)
self:SetStartState("Stopped")
self:AddTransition("Stopped", "Start", "Running")
self:AddTransition("*", "Monitor", "*")
self:AddTransition("*", "RouteTruck", "*")
self:AddTransition("*", "TruckArrived", "*")
self:AddTransition("*", "TruckUnloading", "*")
self:AddTransition("*", "TruckReturning", "*")
self:AddTransition("*", "TruckHome", "*")
self:AddTransition("*", "Stop", "Stopped")
self:__Start(math.random(5,10))
self:I(self.lid .. "Started")
------------------------
--- Pseudo Functions ---
------------------------
--- Triggers the FSM event "Stop". Stops the AMMOTRUCK and all its event handlers.
-- @function [parent=#AMMOTRUCK] Stop
-- @param #AMMOTRUCK self
--- Triggers the FSM event "Stop" after a delay. Stops the AMMOTRUCK and all its event handlers.
-- @function [parent=#AMMOTRUCK] __Stop
-- @param #AMMOTRUCK self
-- @param #number delay Delay in seconds.
--- On after "RouteTruck" event.
-- @function [parent=#AMMOTRUCK] OnAfterRouteTruck
-- @param #AMMOTRUCK self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
-- @param #AMMOTRUCK.data Truck
-- @param #AMMOTRUCK.data Artillery
--- On after "TruckUnloading" event.
-- @function [parent=#AMMOTRUCK] OnAfterTruckUnloading
-- @param #AMMOTRUCK self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
-- @param #AMMOTRUCK.data Truck
--- On after "TruckReturning" event.
-- @function [parent=#AMMOTRUCK] OnAfterTruckReturning
-- @param #AMMOTRUCK self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
-- @param #AMMOTRUCK.data Truck
--- On after "RouteTruck" event.
-- @function [parent=#AMMOTRUCK] OnAfterRouteTruck
-- @param #AMMOTRUCK self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
-- @param #AMMOTRUCK.data Truck
--- On after "TruckHome" event.
-- @function [parent=#AMMOTRUCK] OnAfterTruckHome
-- @param #AMMOTRUCK self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
-- @param #AMMOTRUCK.data Truck
return self
end
---
-- @param #AMMOTRUCK self
-- @param #table dataset table of #AMMOTRUCK.data entries
-- @return #AMMOTRUCK self
function AMMOTRUCK:CheckDrivingTrucks(dataset)
self:T(self.lid .. " CheckDrivingTrucks")
local data = dataset
for _,_data in pairs (data) do
local truck = _data -- #AMMOTRUCK.data
-- see if we arrived at destination
local coord = truck.group:GetCoordinate()
local tgtcoord = truck.targetcoordinate
local dist = coord:Get2DDistance(tgtcoord)
if dist <= 150 then
-- arrived
truck.statusquo = AMMOTRUCK.State.ARRIVED
truck.timestamp = timer.getAbsTime()
truck.coordinate = coord
self:__TruckArrived(1,truck)
end
-- still driving?
local Tnow = timer.getAbsTime()
if Tnow - truck.timestamp > 30 then
local group = truck.group
if self.usearmygroup then
group = truck.group:GetGroup()
end
local currspeed = group:GetVelocityKMH()
if truck.lastspeed then
if truck.lastspeed == 0 and currspeed == 0 then
self:T(truck.group:GetName().." Is not moving!")
-- try and move it
truck.timestamp = timer.getAbsTime()
if self.routeonroad then
group:RouteGroundOnRoad(truck.targetcoordinate,30,2,"Vee")
else
group:RouteGroundTo(truck.targetcoordinate,30,"Vee",2)
end
end
truck.lastspeed = currspeed
else
truck.lastspeed = currspeed
truck.timestamp = timer.getAbsTime()
end
self:I({truck=truck.group:GetName(),currspeed=currspeed,lastspeed=truck.lastspeed})
end
end
return self
end
---
-- @param #AMMOTRUCK self
-- @param Wrapper.Group#GROUP Group
-- @return #AMMOTRUCK self
function AMMOTRUCK:GetAmmoStatus(Group)
local ammotot, shells, rockets, bombs, missiles, narti = Group:GetAmmunition()
return rockets+missiles+narti
end
---
-- @param #AMMOTRUCK self
-- @param #table dataset table of #AMMOTRUCK.data entries
-- @return #AMMOTRUCK self
function AMMOTRUCK:CheckWaitingTargets(dataset)
self:T(self.lid .. " CheckWaitingTargets")
local data = dataset
for _,_data in pairs (data) do
local truck = _data -- #AMMOTRUCK.data
-- see how long we're waiting - maybe ammo truck is dead?
local Tnow = timer.getAbsTime()
local Tdiff = Tnow - truck.timestamp
if Tdiff > self.waitingtime then
local hasammo = self:GetAmmoStatus(truck.group)
if hasammo <= self.ammothreshold then
truck.statusquo = AMMOTRUCK.State.OUTOFAMMO
else
truck.statusquo = AMMOTRUCK.State.IDLE
end
end
end
return self
end
---
-- @param #AMMOTRUCK self
-- @param #table dataset table of #AMMOTRUCK.data entries
-- @return #AMMOTRUCK self
function AMMOTRUCK:CheckReturningTrucks(dataset)
self:T(self.lid .. " CheckReturningTrucks")
local data = dataset
local tgtcoord = self.homezone:GetCoordinate()
local radius = self.homezone:GetRadius()
for _,_data in pairs (data) do
local truck = _data -- #AMMOTRUCK.data
-- see if we arrived at destination
local coord = truck.group:GetCoordinate()
local dist = coord:Get2DDistance(tgtcoord)
self:T({name=truck.name,radius=radius,distance=dist})
if dist <= radius then
-- arrived
truck.statusquo = AMMOTRUCK.State.IDLE
truck.timestamp = timer.getAbsTime()
truck.coordinate = coord
truck.reloads = self.reloads or 5
self:__TruckHome(1,truck)
end
end
return self
end
---
-- @param #AMMOTRUCK self
-- @param #string name Artillery group name to find
-- @return #AMMOTRUCK.data Data
function AMMOTRUCK:FindTarget(name)
self:T(self.lid .. " FindTarget")
local data = nil
local dataset = self.targetlist
for _,_entry in pairs(dataset) do
local entry = _entry -- #AMMOTRUCK.data
if entry.name == name then
data = entry
break
end
end
return data
end
---
-- @param #AMMOTRUCK self
-- @param #string name Truck group name to find
-- @return #AMMOTRUCK.data Data
function AMMOTRUCK:FindTruck(name)
self:T(self.lid .. " FindTruck")
local data = nil
local dataset = self.trucklist
for _,_entry in pairs(dataset) do
local entry = _entry -- #AMMOTRUCK.data
if entry.name == name then
data = entry
break
end
end
return data
end
---
-- @param #AMMOTRUCK self
-- @param #table dataset table of #AMMOTRUCK.data entries
-- @return #AMMOTRUCK self
function AMMOTRUCK:CheckArrivedTrucks(dataset)
self:T(self.lid .. " CheckArrivedTrucks")
local data = dataset
for _,_data in pairs (data) do
-- set to unloading
local truck = _data -- #AMMOTRUCK.data
truck.statusquo = AMMOTRUCK.State.UNLOADING
truck.timestamp = timer.getAbsTime()
self:__TruckUnloading(2,truck)
-- set target to reloading
local aridata = self:FindTarget(truck.targetname) -- #AMMOTRUCK.data
if aridata then
aridata.statusquo = AMMOTRUCK.State.RELOADING
aridata.timestamp = timer.getAbsTime()
end
end
return self
end
---
-- @param #AMMOTRUCK self
-- @param #table dataset table of #AMMOTRUCK.data entries
-- @return #AMMOTRUCK self
function AMMOTRUCK:CheckUnloadingTrucks(dataset)
self:T(self.lid .. " CheckUnloadingTrucks")
local data = dataset
for _,_data in pairs (data) do
-- check timestamp
local truck = _data -- #AMMOTRUCK.data
local Tnow = timer.getAbsTime()
local Tpassed = Tnow - truck.timestamp
local hasammo = self:GetAmmoStatus(truck.targetgroup)
if Tpassed > self.unloadtime and hasammo > self.ammothreshold then
truck.statusquo = AMMOTRUCK.State.RETURNING
truck.timestamp = timer.getAbsTime()
self:__TruckReturning(2,truck)
-- set target to reloaded
local aridata = self:FindTarget(truck.targetname) -- #AMMOTRUCK.data
if aridata then
aridata.statusquo = AMMOTRUCK.State.IDLE
aridata.timestamp = timer.getAbsTime()
end
end
end
return self
end
---
-- @param #AMMOTRUCK self
-- @return #AMMOTRUCK self
function AMMOTRUCK:CheckTargetsAlive()
self:T(self.lid .. " CheckTargetsAlive")
local arilist = self.targetlist
for _,_ari in pairs(arilist) do
local ari = _ari -- #AMMOTRUCK.data
if ari.group and ari.group:IsAlive() then
-- everything fine
else
-- ari dead
self.targetlist[ari.name] = nil
end
end
-- new arrivals?
local aritable = self.targetset:GetSetObjects() --#table
for _,_ari in pairs(aritable) do
local ari = _ari -- Wrapper.Group#GROUP
if ari and ari:IsAlive() and not self.targetlist[ari:GetName()] then
local name = ari:GetName()
local newari = {} -- #AMMOTRUCK.data
newari.name = name
newari.group = ari
newari.statusquo = AMMOTRUCK.State.IDLE
newari.timestamp = timer.getAbsTime()
newari.coordinate = ari:GetCoordinate()
local hasammo = self:GetAmmoStatus(ari)
--newari.ammo = ari:GetAmmunition()
newari.ammo = hasammo
self.targetlist[name] = newari
end
end
return self
end
---
-- @param #AMMOTRUCK self
-- @return #AMMOTRUCK self
function AMMOTRUCK:CheckTrucksAlive()
self:T(self.lid .. " CheckTrucksAlive")
local trucklist = self.trucklist
for _,_truck in pairs(trucklist) do
local truck = _truck -- #AMMOTRUCK.data
if truck.group and truck.group:IsAlive() then
-- everything fine
else
-- truck dead
local tgtname = truck.targetname
local targetdata = self:FindTarget(tgtname) -- #AMMOTRUCK.data
if targetdata then
if targetdata.statusquo ~= AMMOTRUCK.State.IDLE then
targetdata.statusquo = AMMOTRUCK.State.IDLE
end
end
self.trucklist[truck.name] = nil
end
end
-- new arrivals?
local trucktable = self.truckset:GetSetObjects() --#table
for _,_truck in pairs(trucktable) do
local truck = _truck -- Wrapper.Group#GROUP
if truck and truck:IsAlive() and not self.trucklist[truck:GetName()] then
local name = truck:GetName()
local newtruck = {} -- #AMMOTRUCK.data
newtruck.name = name
newtruck.group = truck
if self.hasarmygroup then
-- is (not) already ARMYGROUP?
if truck.ClassName and truck.ClassName == "GROUP" then
local trucker = ARMYGROUP:New(truck)
trucker:Activate()
newtruck.group = trucker
end
end
newtruck.statusquo = AMMOTRUCK.State.IDLE
newtruck.timestamp = timer.getAbsTime()
newtruck.coordinate = truck:GetCoordinate()
newtruck.reloads = self.reloads or 5
self.trucklist[name] = newtruck
end
end
return self
end
---
-- @param #AMMOTRUCK self
-- @param #string From
-- @param #string Event
-- @param #string To
-- @return #AMMOTRUCK self
function AMMOTRUCK:onafterStart(From, Event, To)
self:T({From, Event, To})
if ARMYGROUP and self.usearmygroup then
self.hasarmygroup = true
else
self.hasarmygroup = false
end
if self.debug then
BASE:TraceOn()
BASE:TraceClass("AMMOTRUCK")
end
self:CheckTargetsAlive()
self:CheckTrucksAlive()
self:__Monitor(-30)
return self
end
---
-- @param #AMMOTRUCK self
-- @param #string From
-- @param #string Event
-- @param #string To
-- @return #AMMOTRUCK self
function AMMOTRUCK:onafterMonitor(From, Event, To)
self:T({From, Event, To})
self:CheckTargetsAlive()
self:CheckTrucksAlive()
-- update ammo state
local remunition = false
local remunitionqueue = {}
local waitingtargets = {}
for _,_ari in pairs(self.targetlist) do
local data = _ari -- #AMMOTRUCK.data
if data.group and data.group:IsAlive() then
data.ammo = self:GetAmmoStatus(data.group)
data.timestamp = timer.getAbsTime()
local text = string.format("Ari %s | Ammo %d | State %s",data.name,data.ammo,data.statusquo)
self:T(text)
if data.ammo <= self.ammothreshold and (data.statusquo == AMMOTRUCK.State.IDLE or data.statusquo == AMMOTRUCK.State.OUTOFAMMO) then
-- add to remu queue
data.statusquo = AMMOTRUCK.State.OUTOFAMMO
remunitionqueue[#remunitionqueue+1] = data
remunition = true
elseif data.statusquo == AMMOTRUCK.State.WAITING then
waitingtargets[#waitingtargets+1] = data
end
else
self.targetlist[data.name] = nil
end
end
-- sort trucks in buckets
local idletrucks = {}
local drivingtrucks = {}
local unloadingtrucks = {}
local arrivedtrucks = {}
local returningtrucks = {}
local found = false
for _,_truckdata in pairs(self.trucklist) do
local data = _truckdata -- #AMMOTRUCK.data
if data.group and data.group:IsAlive() then
-- check state
local text = string.format("Truck %s | State %s",data.name,data.statusquo)
self:T(text)
if data.statusquo == AMMOTRUCK.State.IDLE then
idletrucks[#idletrucks+1] = data
found = true
elseif data.statusquo == AMMOTRUCK.State.DRIVING then
drivingtrucks[#drivingtrucks+1] = data
elseif data.statusquo == AMMOTRUCK.State.ARRIVED then
arrivedtrucks[#arrivedtrucks+1] = data
elseif data.statusquo == AMMOTRUCK.State.UNLOADING then
unloadingtrucks[#unloadingtrucks+1] = data
elseif data.statusquo == AMMOTRUCK.State.RETURNING then
returningtrucks[#returningtrucks+1] = data
if data.reloads > 0 or data.reloads == -1 then
idletrucks[#idletrucks+1] = data
found = true
end
end
else
self.truckset[data.name] = nil
end
end
-- see if we can/need route one
local n=0
if found and remunition then
-- match
--local match = false
for _,_truckdata in pairs(idletrucks) do
local truckdata = _truckdata -- #AMMOTRUCK.data
local truckcoord = truckdata.group:GetCoordinate() -- Core.Point#COORDINATE
for _,_aridata in pairs(remunitionqueue) do
local aridata = _aridata -- #AMMOTRUCK.data
local aricoord = aridata.coordinate
local distance = truckcoord:Get2DDistance(aricoord)
if distance <= self.remunidist and aridata.statusquo == AMMOTRUCK.State.OUTOFAMMO and n <= #idletrucks then
n = n + 1
aridata.statusquo = AMMOTRUCK.State.REQUESTED
self:__RouteTruck(n*5,truckdata,aridata)
break
end
end
end
end
-- check driving trucks
if #drivingtrucks > 0 then
self:CheckDrivingTrucks(drivingtrucks)
end
-- check arrived trucks
if #arrivedtrucks > 0 then
self:CheckArrivedTrucks(arrivedtrucks)
end
-- check unloading trucks
if #unloadingtrucks > 0 then
self:CheckUnloadingTrucks(unloadingtrucks)
end
-- check returningtrucks trucks
if #returningtrucks > 0 then
self:CheckReturningTrucks(returningtrucks)
end
-- check waiting targets
if #waitingtargets > 0 then
self:CheckWaitingTargets(waitingtargets)
end
self:__Monitor(self.monitor)
return self
end
---
-- @param #AMMOTRUCK self
-- @param #string From
-- @param #string Event
-- @param #string To
-- @param #AMMOTRUCK.data Truckdata
-- @param #AMMOTRUCK.data Aridata
-- @return #AMMOTRUCK self
function AMMOTRUCK:onafterRouteTruck(From, Event, To, Truckdata, Aridata)
self:T({From, Event, To, Truckdata.name, Aridata.name})
local truckdata = Truckdata -- #AMMOTRUCK.data
local aridata = Aridata -- #AMMOTRUCK.data
local tgtgrp = aridata.group
local tgtzone = ZONE_GROUP:New(aridata.name,tgtgrp,30)
local tgtcoord = tgtzone:GetRandomCoordinate(15)
if self.hasarmygroup then
local mission = AUFTRAG:NewONGUARD(tgtcoord)
local oldmission = truckdata.group:GetMissionCurrent()
if oldmission then oldmission:Cancel() end
mission:SetTime(5)
mission:SetTeleport(false)
truckdata.group:AddMission(mission)
elseif self.routeonroad then
truckdata.group:RouteGroundOnRoad(tgtcoord,30)
else
truckdata.group:RouteGroundTo(tgtcoord,30)
end
truckdata.statusquo = AMMOTRUCK.State.DRIVING
truckdata.targetgroup = tgtgrp
truckdata.targetname = aridata.name
truckdata.targetcoordinate = tgtcoord
aridata.statusquo = AMMOTRUCK.State.WAITING
aridata.timestamp = timer.getAbsTime()
return self
end
---
-- @param #AMMOTRUCK self
-- @param #string From
-- @param #string Event
-- @param #string To
-- @param #AMMOTRUCK.data Truckdata
-- @return #AMMOTRUCK self
function AMMOTRUCK:onafterTruckUnloading(From, Event, To, Truckdata)
local m = MESSAGE:New("Truck "..Truckdata.name.." unloading!",15,"AmmoTruck"):ToCoalitionIf(self.coalition,self.debug)
local truck = Truckdata -- Functional.AmmoTruck#AMMOTRUCK.data
local coord = truck.group:GetCoordinate()
local heading = truck.group:GetHeading()
heading = heading < 180 and (360-heading) or (heading - 180)
local cid = self.coalition == coalition.side.BLUE and country.id.USA or country.id.RUSSIA
cid = self.coalition == coalition.side.NEUTRAL and country.id.UN_PEACEKEEPERS or cid
local ammo = {}
for i=1,5 do
ammo[i] = SPAWNSTATIC:NewFromType("ammo_cargo","Cargos",cid)
:InitCoordinate(coord:Translate((15+((i-1)*4)),heading))
:Spawn(0,"AmmoCrate-"..math.random(1,10000))
end
local function destroyammo(ammo)
for _,_crate in pairs(ammo) do
_crate:Destroy(false)
end
end
local scheduler = SCHEDULER:New(nil,destroyammo,{ammo},self.waitingtime)
-- one reload less
if truck.reloads ~= -1 then
truck.reloads = truck.reloads - 1
end
return self
end
---
-- @param #AMMOTRUCK self
-- @param #string From
-- @param #string Event
-- @param #string To
-- @param #AMMOTRUCK.data Truck
-- @return #AMMOTRUCK self
function AMMOTRUCK:onafterTruckReturning(From, Event, To, Truck)
self:T({From, Event, To, Truck.name})
-- route home
local truckdata = Truck -- #AMMOTRUCK.data
local tgtzone = self.homezone
local tgtcoord = tgtzone:GetRandomCoordinate()
if self.hasarmygroup then
local mission = AUFTRAG:NewONGUARD(tgtcoord)
local oldmission = truckdata.group:GetMissionCurrent()
if oldmission then oldmission:Cancel() end
mission:SetTime(5)
mission:SetTeleport(false)
truckdata.group:AddMission(mission)
elseif self.routeonroad then
truckdata.group:RouteGroundOnRoad(tgtcoord,30,1,"Cone")
else
truckdata.group:RouteGroundTo(tgtcoord,30,"Cone",1)
end
return self
end
---
-- @param #AMMOTRUCK self
-- @param #string From
-- @param #string Event
-- @param #string To
-- @return #AMMOTRUCK self
function AMMOTRUCK:onafterStop(From, Event, To)
self:T({From, Event, To})
return self
end
+150 -145
View File
@@ -30,7 +30,7 @@
-- ### Contributions: [FlightControl](https://forums.eagle.ru/member.php?u=89536)
--
-- ====
-- @module Functional.Arty
-- @module Functional.Artillery
-- @image Artillery.JPG
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
@@ -103,12 +103,13 @@
-- @field #number coalition The coalition of the arty group.
-- @field #boolean respawnafterdeath Respawn arty group after all units are dead.
-- @field #number respawndelay Respawn delay in seconds.
-- @field #number dtTrack Time interval in seconds for weapon tracking.
-- @extends Core.Fsm#FSM_CONTROLLABLE
--- Enables mission designers easily to assign targets for artillery units. Since the implementation is based on a Finite State Model (FSM), the mission designer can
-- interact with the process at certain events or states.
--
-- A new ARTY object can be created with the @{#ARTY.New}(*group*) contructor.
-- A new ARTY object can be created with the @{#ARTY.New}(*group*) constructor.
-- The parameter *group* has to be a MOOSE Group object and defines ARTY group.
--
-- The ARTY FSM process can be started by the @{#ARTY.Start}() command.
@@ -146,7 +147,7 @@
-- When a new target is assigned via the @{#ARTY.AssignTargetCoord}() function (see below), the **NewTarget** event is triggered.
--
-- ## Assigning Targets
-- Assigning targets is a central point of the ARTY class. Multiple targets can be assigned simultanioulsly and are put into a queue.
-- Assigning targets is a central point of the ARTY class. Multiple targets can be assigned simultaneously and are put into a queue.
-- Of course, targets can be added at any time during the mission. For example, once they are detected by a reconnaissance unit.
--
-- In order to add a target, the function @{#ARTY.AssignTargetCoord}(*coord*, *prio*, *radius*, *nshells*, *maxengage*, *time*, *weapontype*, *name*) has to be used.
@@ -161,7 +162,7 @@
-- * *maxengage*: Number of times a target is engaged.
-- * *time*: Time of day the engagement is schedule in the format "hh:mm:ss" for hh=hours, mm=minutes, ss=seconds.
-- For example "10:15:35". In the case the attack will be executed at a quarter past ten in the morning at the day the mission started.
-- If the engagement should start on the following day the format can be specified as "10:15:35+1", where the +1 denots the following day.
-- If the engagement should start on the following day the format can be specified as "10:15:35+1", where the +1 denotes the following day.
-- This is useful for longer running missions or if the mission starts at 23:00 hours and the attack should be scheduled at 01:00 hours on the following day.
-- Of course, later days are also possible by appending "+2", "+3", etc.
-- **Note** that the time has to be given as a string. So the enclosing quotation marks "" are important.
@@ -179,7 +180,7 @@
-- Let's first consider the case that none of the targets is scheduled to be executed at a certain time (*time*=nil).
-- The ARTY group will first engage the target with higher priority (*prio*=10). After the engagement is finished, the target with lower priority is attacked.
-- This is because the target with lower prio has been attacked one time less. After the attack on the lower priority task is finished and both targets
-- have been engaged equally often, the target with the higher priority is engaged again. This coninues until a target has engaged three times.
-- have been engaged equally often, the target with the higher priority is engaged again. This continues until a target has engaged three times.
-- Once the maximum number of engagements is reached, the target is deleted from the queue.
--
-- In other words, the queue is first sorted with respect to the number of engagements and targets with the same number of engagements are sorted with
@@ -190,7 +191,7 @@
-- As mentioned above, targets can be engaged at a specific time of the day via the *time* parameter.
--
-- If the *time* parameter is specified for a target, the first engagement of that target will happen at that time of the day and not before.
-- This also applies when multiple engagements are requested via the *maxengage* parameter. The first attack will not happen before the specifed time.
-- This also applies when multiple engagements are requested via the *maxengage* parameter. The first attack will not happen before the specified time.
-- When that timed attack is finished, the *time* parameter is deleted and the remaining engagements are carried out in the same manner as for untimed targets (described above).
--
-- Of course, it can happen that a scheduled task should be executed at a time, when another target is already under attack.
@@ -201,7 +202,7 @@
--
-- ## Determining the Amount of Ammo
--
-- In order to determin when a unit is out of ammo and possible initiate the rearming process it is necessary to know which types of weapons have to be counted.
-- In order to determine when a unit is out of ammo and possible initiate the rearming process it is necessary to know which types of weapons have to be counted.
-- For most artillery unit types, this is simple because they only have one type of weapon and hence ammunition.
--
-- However, there are more complex scenarios. For example, naval units carry a big arsenal of different ammunition types ranging from various cannon shell types
@@ -217,7 +218,7 @@
-- **Note** that the default parameters "weapons.shells", "weapons.nurs", "weapons.missiles" **should in priciple** capture all the corresponding ammo types.
-- However, the logic searches for the string "weapon.missies" in the ammo type. Especially for missiles, this string is often not contained in the ammo type descriptor.
--
-- One way to determin which types of ammo the unit carries, one can use the debug mode of the arty class via @{#ARTY.SetDebugON}().
-- One way to determine which types of ammo the unit carries, one can use the debug mode of the arty class via @{#ARTY.SetDebugON}().
-- In debug mode, the all ammo types of the group are printed to the monitor as message and can be found in the DCS.log file.
--
-- ## Employing Selected Weapons
@@ -274,7 +275,7 @@
--
-- ## Simulated Weapons
--
-- In addtion to the standard weapons a group has available some special weapon types that are not possible to use in the native DCS environment are simulated.
-- In addition to the standard weapons a group has available some special weapon types that are not possible to use in the native DCS environment are simulated.
--
-- ### Tactical Nukes
--
@@ -283,9 +284,9 @@
--
-- By default, they group does not have any nukes available. To give the group the ability the function @{#ARTY.SetTacNukeShells}(*n*) can be used.
-- This supplies the group with *n* nuclear shells, where *n* is restricted to the number of conventional shells the group can carry.
-- Note that the group must always have convenctional shells left in order to fire a nuclear shell.
-- Note that the group must always have conventional shells left in order to fire a nuclear shell.
--
-- The default explostion strength is 0.075 kilo tons TNT. The can be changed with the @{#ARTY.SetTacNukeWarhead}(*strength*), where *strength* is given in kilo tons TNT.
-- The default explosion strength is 0.075 kilo tons TNT. The can be changed with the @{#ARTY.SetTacNukeWarhead}(*strength*), where *strength* is given in kilo tons TNT.
--
-- ### Illumination Shells
--
@@ -301,12 +302,12 @@
--
-- ### Smoke Shells
--
-- In a similar way to illumination shells, ARTY groups can also employ smoke shells. The numer of smoke shells the group has available is set by the function
-- In a similar way to illumination shells, ARTY groups can also employ smoke shells. The number of smoke shells the group has available is set by the function
-- @{#ARTY.SetSmokeShells}(*n*, *color*), where *n* is the number of shells and *color* defines the smoke color. Default is SMOKECOLOR.Red.
--
-- The weapon type to be used in the @{#ARTY.AssignTargetCoord}() function is *ARTY.WeaponType.SmokeShells*.
--
-- The explosive shell the group fired is destroyed shortly before its impact on the ground and smoke of the speficied color is triggered at that position.
-- The explosive shell the group fired is destroyed shortly before its impact on the ground and smoke of the specified color is triggered at that position.
--
--
-- ## Assignments via Markers on F10 Map
@@ -320,15 +321,15 @@
-- ### Target Assignments
-- A new target can be assigned by writing **arty engage** in the marker text.
-- This is followed by a **comma separated list** of (optional) keywords and parameters.
-- First, it is important to address the ARTY group or groups that should engage. This can be done in numrous ways. The keywords are *battery*, *alias*, *cluster*.
-- First, it is important to address the ARTY group or groups that should engage. This can be done in numerous ways. The keywords are *battery*, *alias*, *cluster*.
-- It is also possible to address all ARTY groups by the keyword *everyone* or *allbatteries*. These two can be used synonymously.
-- **Note that**, if no battery is assigned nothing will happen.
--
-- * *everyone* or *allbatteries* The target is assigned to all batteries.
-- * *battery* Name of the ARTY group that the target is assigned to. Note that **the name is case sensitive** and has to be given in quotation marks. Default is all ARTY groups of the right coalition.
-- * *alias* Alias of the ARTY group that the target is assigned to. The alias is **case sensitive** and needs to be in quotation marks.
-- * *cluster* The cluster of ARTY groups that is addessed. Clusters can be defined by the function @{#ARTY.AddToCluster}(*clusters*). Names are **case sensitive** and need to be in quotation marks.
-- * *key* A number to authorize the target assignment. Only specifing the correct number will trigger an engagement.
-- * *cluster* The cluster of ARTY groups that is addressed. Clusters can be defined by the function @{#ARTY.AddToCluster}(*clusters*). Names are **case sensitive** and need to be in quotation marks.
-- * *key* A number to authorize the target assignment. Only specifying the correct number will trigger an engagement.
-- * *time* Time for which which the engagement is schedules, e.g. 08:42. Default is as soon as possible.
-- * *prio* Priority of the engagement as number between 1 (high prio) and 100 (low prio). Default is 50, i.e. medium priority.
-- * *shots* Number of shots (shells, rockets or missiles) fired at each engagement. Default is 5.
@@ -353,8 +354,8 @@
-- arty engage, battery "Paladin Alpha", weapon nukes, shots 1, time 20:15
-- arty engage, battery "Horwitzer 1", lldms 41:51:00N 41:47:58E
--
-- Note that the keywords and parameters are *case insensitve*. Only exception are the battery, alias and cluster names.
-- These must be exactly the same as the names of the goups defined in the mission editor or the aliases and cluster names defined in the script.
-- Note that the keywords and parameters are *case insensitive*. Only exception are the battery, alias and cluster names.
-- These must be exactly the same as the names of the groups defined in the mission editor or the aliases and cluster names defined in the script.
--
-- ### Relocation Assignments
--
@@ -363,11 +364,11 @@
-- * *time* Time for which which the relocation/move is schedules, e.g. 08:42. Default is as soon as possible.
-- * *speed* The speed in km/h the group will drive at. Default is 70% of its max possible speed.
-- * *on road* Group will use mainly roads. Default is off, i.e. it will go in a straight line from its current position to the assigned coordinate.
-- * *canceltarget* Group will cancel all running firing engagements and immidiately start to move. Default is that group will wait until is current assignment is over.
-- * *canceltarget* Group will cancel all running firing engagements and immediately start to move. Default is that group will wait until is current assignment is over.
-- * *battery* Name of the ARTY group that the relocation is assigned to.
-- * *alias* Alias of the ARTY group that the target is assigned to. The alias is **case sensitive** and needs to be in quotation marks.
-- * *cluster* The cluster of ARTY groups that is addessed. Clusters can be defined by the function @{#ARTY.AddToCluster}(*clusters*). Names are **case sensitive** and need to be in quotation marks.
-- * *key* A number to authorize the target assignment. Only specifing the correct number will trigger an engagement.
-- * *cluster* The cluster of ARTY groups that is addressed. Clusters can be defined by the function @{#ARTY.AddToCluster}(*clusters*). Names are **case sensitive** and need to be in quotation marks.
-- * *key* A number to authorize the target assignment. Only specifying the correct number will trigger an engagement.
-- * *lldms* Specify the coordinates in Lat/Long degrees, minutes and seconds format. The actual location of the marker is unimportant. The group will move to the coordinates given in the lldms keyword.
-- Format is DD:MM:SS[N,S] DD:MM:SS[W,E]. See example below.
-- * *readonly* Marker cannot be deleted by users any more. Hence, assignment cannot be cancelled by removing the marker.
@@ -410,12 +411,12 @@
--
-- A few options can be set by marks. The corresponding keyword is **arty set**. This can be used to define the rearming place and group for a battery.
--
-- To set the reamring place of a group at the marker position type
-- To set the rearming place of a group at the marker position type
-- arty set, battery "Paladin Alpha", rearming place
--
-- Setting the rearming group is independent of the position of the mark. Just create one anywhere on the map and type
-- arty set, battery "Mortar Bravo", rearming group "Ammo Truck M818"
-- Note that the name of the rearming group has to be given in quotation marks and spellt exactly as the group name defined in the mission editor.
-- Note that the name of the rearming group has to be given in quotation marks and spelt exactly as the group name defined in the mission editor.
--
-- ## Transporting
--
@@ -693,7 +694,7 @@ ARTY.db={
--- Arty script version.
-- @field #string version
ARTY.version="1.2.0"
ARTY.version="1.3.0"
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
@@ -801,6 +802,9 @@ function ARTY:New(group, alias)
else
self.ismobile=false
end
-- Set track time interval.
self.dtTrack=0.2
-- Set speed to 0.7 of maximum.
self.Speed=self.SpeedMax * 0.7
@@ -1497,6 +1501,15 @@ function ARTY:SetStatusInterval(interval)
return self
end
--- Set time interval for weapon tracking.
-- @param #ARTY self
-- @param #number interval Time interval in seconds. Default 0.2 seconds.
-- @return self
function ARTY:SetTrackInterval(interval)
self.dtTrack=interval or 0.2
return self
end
--- Set time how it is waited a unit the first shot event happens. If no shot is fired after this time, the task to fire is aborted and the target removed.
-- @param #ARTY self
-- @param #number waittime Time in seconds. Default 300 seconds.
@@ -2129,6 +2142,95 @@ end
-- Event Handling
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- Function called during tracking of weapon.
-- @param Wrapper.Weapon#WEAPON weapon Weapon object.
-- @param #ARTY self ARTY object.
-- @param #ARTY.Target target Target of the weapon.
function ARTY._FuncTrack(weapon, self, target)
-- Coordinate and distance to target.
local _coord=weapon.coordinate
local _dist=_coord:Get2DDistance(target.coord)
local _destroyweapon=false
-- Debug
self:T3(self.lid..string.format("ARTY %s weapon to target dist = %d m", self.groupname,_dist))
if target.weapontype==ARTY.WeaponType.IlluminationShells then
-- Check if within distace.
if _dist<target.radius then
-- Get random coordinate within certain radius of the target.
local _cr=target.coord:GetRandomCoordinateInRadius(target.radius)
-- Get random altitude over target.
local _alt=_cr:GetLandHeight()+math.random(self.illuMinalt, self.illuMaxalt)
-- Adjust explosion height of coordinate.
local _ci=COORDINATE:New(_cr.x,_alt,_cr.z)
-- Create illumination flare.
_ci:IlluminationBomb(self.illuPower)
-- Destroy actual shell.
_destroyweapon=true
end
elseif target.weapontype==ARTY.WeaponType.SmokeShells then
if _dist<target.radius then
-- Get random coordinate within a certain radius.
local _cr=_coord:GetRandomCoordinateInRadius(_data.target.radius)
-- Fire smoke at this coordinate.
_cr:Smoke(self.smokeColor)
-- Destroy actual shell.
_destroyweapon=true
end
end
if _destroyweapon then
self:T2(self.lid..string.format("ARTY %s destroying shell, stopping timer.", self.groupname))
-- Destroy weapon and stop timer.
weapon:Destroy()
-- No more tracking.
weapon.tracking=false
end
end
--- Function called after impact of weapon.
-- @param Wrapper.Weapon#WEAPON weapon Weapon object.
-- @param #ARTY self ARTY object.
-- @param #ARTY.Target target Target of the weapon.
function ARTY._FuncImpact(weapon, self, target)
-- Debug info.
self:I(self.lid..string.format("ARTY %s weapon NOT ALIVE any more.", self.groupname))
-- Get impact coordinate.
local _impactcoord=weapon:GetImpactCoordinate()
-- Create a "nuclear" explosion and blast at the impact point.
if target.weapontype==ARTY.WeaponType.TacticalNukes then
self:T(self.lid..string.format("ARTY %s triggering nuclear explosion in one second.", self.groupname))
--SCHEDULER:New(nil, ARTY._NuclearBlast, {self,_impactcoord}, 1.0)
self:ScheduleOnce(1.0, ARTY._NuclearBlast, self, _impactcoord)
end
end
--- Eventhandler for shot event.
-- @param #ARTY self
-- @param Core.Event#EVENTDATA EventData
@@ -2162,128 +2264,32 @@ function ARTY:OnEventShot(EventData)
self:T(self.lid..text)
MESSAGE:New(text, 5):Clear():ToAllIf(self.report or self.Debug)
-- Last known position of the weapon fired.
local _lastpos={x=0, y=0, z=0}
--- Track the position of the weapon if it is supposed to model a tac nuke, illumination or smoke shell.
-- @param #table _weapon
local function _TrackWeapon(_data)
-- When the pcall status returns false the weapon has hit.
local _weaponalive,_currpos = pcall(
function()
return _data.weapon:getPoint()
end)
-- Debug
self:T3(self.lid..string.format("ARTY %s: Weapon still in air: %s", self.groupname, tostring(_weaponalive)))
-- Destroy weapon before impact.
local _destroyweapon=false
if _weaponalive then
-- Update last position.
_lastpos={x=_currpos.x, y=_currpos.y, z=_currpos.z}
-- Coordinate and distance to target.
local _coord=COORDINATE:NewFromVec3(_lastpos)
local _dist=_coord:Get2DDistance(_data.target.coord)
-- Debug
self:T3(self.lid..string.format("ARTY %s weapon to target dist = %d m", self.groupname,_dist))
if _data.target.weapontype==ARTY.WeaponType.IlluminationShells then
-- Check if within distace.
if _dist<_data.target.radius then
-- Get random coordinate within certain radius of the target.
local _cr=_data.target.coord:GetRandomCoordinateInRadius(_data.target.radius)
-- Get random altitude over target.
local _alt=_cr:GetLandHeight()+math.random(self.illuMinalt, self.illuMaxalt)
-- Adjust explosion height of coordinate.
local _ci=COORDINATE:New(_cr.x,_alt,_cr.z)
-- Create illumination flare.
_ci:IlluminationBomb(self.illuPower)
-- Destroy actual shell.
_destroyweapon=true
end
elseif _data.target.weapontype==ARTY.WeaponType.SmokeShells then
if _dist<_data.target.radius then
-- Get random coordinate within a certain radius.
local _cr=_coord:GetRandomCoordinateInRadius(_data.target.radius)
-- Fire smoke at this coordinate.
_cr:Smoke(self.smokeColor)
-- Destroy actual shell.
_destroyweapon=true
end
end
if _destroyweapon then
self:T2(self.lid..string.format("ARTY %s destroying shell, stopping timer.", self.groupname))
-- Destroy weapon and stop timer.
_data.weapon:destroy()
return nil
else
-- TODO: Make dt input parameter.
local dt=0.02
self:T3(self.lid..string.format("ARTY %s tracking weapon again in %.3f seconds", self.groupname, dt))
-- Check again in 0.05 seconds.
return timer.getTime() + dt
end
else
-- Get impact coordinate.
local _impactcoord=COORDINATE:NewFromVec3(_lastpos)
self:I(self.lid..string.format("ARTY %s weapon NOT ALIVE any more.", self.groupname))
-- Create a "nuclear" explosion and blast at the impact point.
if _data.target.weapontype==ARTY.WeaponType.TacticalNukes then
self:T(self.lid..string.format("ARTY %s triggering nuclear explosion in one second.", self.groupname))
SCHEDULER:New(nil, ARTY._NuclearBlast, {self,_impactcoord}, 1.0)
end
-- Stop timer.
return nil
end
end
-- Start track the shell if we want to model a tactical nuke.
local _tracknuke = self.currentTarget.weapontype==ARTY.WeaponType.TacticalNukes and self.Nukes>0
local _trackillu = self.currentTarget.weapontype==ARTY.WeaponType.IlluminationShells and self.Nillu>0
local _tracksmoke = self.currentTarget.weapontype==ARTY.WeaponType.SmokeShells and self.Nsmoke>0
if _tracknuke or _trackillu or _tracksmoke then
self:T(self.lid..string.format("ARTY %s: Tracking of weapon starts in two seconds.", self.groupname))
local _peter={}
_peter.weapon=EventData.weapon
_peter.target=UTILS.DeepCopy(self.currentTarget)
timer.scheduleFunction(_TrackWeapon, _peter, timer.getTime() + 2.0)
-- Debug info.
self:T(self.lid..string.format("ARTY %s: Tracking of weapon starts in two seconds.", self.groupname))
-- Create a weapon object.
local weapon=WEAPON:New(EventData.weapon)
-- Set time step for tracking.
weapon:SetTimeStepTrack(self.dtTrack)
-- Copy target. We need a copy because it might already be overwritten with the next target during flight of weapon.
local target=UTILS.DeepCopy(self.currentTarget)
-- Set callback functions.
weapon:SetFuncTrack(ARTY._FuncTrack, self, target)
weapon:SetFuncImpact(ARTY._FuncImpact, self, target)
-- Start tracking in 2 sec (arty ammo should fly a bit).
weapon:StartTrack(2)
end
-- Get current ammo.
@@ -3422,7 +3428,7 @@ function ARTY:onafterMove(Controllable, From, Event, To, move)
-- Set current move.
self.currentMove=move
-- Route group to coodinate.
-- Route group to coordinate.
self:_Move(self.Controllable, move.coord, move.speed, move.onroad)
end
@@ -3541,8 +3547,6 @@ end
function ARTY:onafterRespawn(Controllable, From, Event, To)
self:_EventFromTo("onafterRespawn", Event, From, To)
env.info("FF Respawning arty group")
local group=self.Controllable --Wrapper.Group#GROUP
-- Respawn group.
@@ -3931,9 +3935,10 @@ function ARTY:GetAmmo(display)
return nammo, nshells, nrockets, nmissiles
end
for _,unit in pairs(units) do
for _,_unit in pairs(units) do
local unit=_unit --Wrapper.Unit#UNIT
if unit and unit:IsAlive() then
if unit then
-- Output.
local text=string.format("ARTY group %s - unit %s:\n", self.groupname, unit:GetName())
File diff suppressed because it is too large Load Diff
@@ -1,4 +1,4 @@
--- **Functional** -- Keep airbases clean of crashing or colliding airplanes, and kill missiles when being fired at airbases.
--- **Functional** - Keep airbases clean of crashing or colliding airplanes, and kill missiles when being fired at airbases.
--
-- ===
--
@@ -1,4 +1,4 @@
--- **Functional** -- Management of target **Designation**. Lase, smoke and illuminate targets.
--- **Functional** - Management of target **Designation**. Lase, smoke and illuminate targets.
--
-- ===
--
@@ -48,7 +48,7 @@
--
-- ![Banner Image](..\Presentations\DESIGNATE\Dia3.JPG)
--
-- A typical mission setup would require Recce (a @{Set} of Recce) to be detecting potential targets.
-- A typical mission setup would require Recce (a @{Core.Set} of Recce) to be detecting potential targets.
-- The DetectionObject will group the detected targets based on the detection method being used.
-- Possible detection methods could be by Area, by Type or by Unit.
-- Each grouping will result in a **TargetGroup**, for terminology and clarity we will use this term throughout the document.
@@ -213,7 +213,7 @@ do -- DESIGNATE
-- In order to prevent an overflow of designations due to many Detected Targets, there is a
-- Maximum Designations scope that is set in the DesignationObject.
--
-- The method @{#DESIGNATE.SetMaximumDesignations}() will put a limit on the amount of designations put in scope of the DesignationObject.
-- The method @{#DESIGNATE.SetMaximumDesignations}() will put a limit on the amount of designations (target groups) put in scope of the DesignationObject.
-- Using the menu system, the player can "forget" a designation, so that gradually a new designation can be put in scope when detected.
--
-- # 4. Laser codes
@@ -276,7 +276,7 @@ do -- DESIGNATE
-- # 7. Designate Menu Location for a Mission
--
-- You can make DESIGNATE work for a @{Tasking.Mission#MISSION} object. In this way, the designate menu will not appear in the root of the radio menu, but in the menu of the Mission.
-- Use the method @{#DESIGNATE.SetMission}() to set the @{Mission} object for the designate function.
-- Use the method @{#DESIGNATE.SetMission}() to set the @{Tasking.Mission} object for the designate function.
--
-- # 8. Status Report
--
@@ -562,7 +562,8 @@ do -- DESIGNATE
end
--- Set the maximum amount of designations.
--- Set the maximum amount of designations (target groups). This will put a limit on the amount of designations in scope.
-- Using the menu system, the player can "forget" a designation, so that gradually a new designation can be put in scope when detected.
-- @param #DESIGNATE self
-- @param #number MaximumDesignations
-- @return #DESIGNATE
@@ -602,7 +603,7 @@ do -- DESIGNATE
end
--- Set the maximum amount of markings FACs will do, per designated target group.
--- Set the maximum amount of markings FACs will do, per designated target group. This will limit the number of parallelly marked units of a target group.
-- @param #DESIGNATE self
-- @param #number MaximumMarkings Maximum markings FACs will do, per designated target group.
-- @return #DESIGNATE
@@ -911,8 +912,8 @@ do -- DESIGNATE
for DesignateIndex, Designating in pairs( self.Designating ) do
local DetectedItem = DetectedItems[DesignateIndex]
if DetectedItem then
local Report = self.Detection:DetectedItemReportSummary( DetectedItem, AttackGroup ):Text( ", " )
DetectedReport:Add( string.rep( "-", 140 ) )
local Report = self.Detection:DetectedItemReportSummary( DetectedItem, AttackGroup, nil, true ):Text( ", " )
DetectedReport:Add( string.rep( "-", 40 ) )
DetectedReport:Add( " - " .. Report )
if string.find( Designating, "L" ) then
DetectedReport:Add( " - " .. "Lasing Targets" )
@@ -1192,8 +1193,8 @@ do -- DESIGNATE
local MarkingCount = 0
local MarkedTypes = {}
local ReportTypes = REPORT:New()
local ReportLaserCodes = REPORT:New()
--local ReportTypes = REPORT:New()
--local ReportLaserCodes = REPORT:New()
TargetSetUnit:Flush( self )
@@ -1243,8 +1244,8 @@ do -- DESIGNATE
if not Recce then
self:F( "Lasing..." )
self.RecceSet:Flush( self)
--self.RecceSet:Flush( self)
for RecceGroupID, RecceGroup in pairs( self.RecceSet:GetSet() ) do
for UnitID, UnitData in pairs( RecceGroup:GetUnits() or {} ) do
@@ -1282,13 +1283,13 @@ do -- DESIGNATE
-- OK. We have assigned for the Recce a TargetUnit. We can exit the function.
MarkingCount = MarkingCount + 1
local TargetUnitType = TargetUnit:GetTypeName()
--RecceUnit:MessageToSetGroup( "Marking " .. TargetUnit:GetTypeName() .. " with laser " .. RecceUnit:GetSpot().LaserCode .. " for " .. Duration .. "s.",
-- 5, self.AttackSet, DesignateName )
RecceUnit:MessageToSetGroup( "Marking " .. TargetUnit:GetTypeName() .. " with laser " .. RecceUnit:GetSpot().LaserCode .. " for " .. Duration .. "s.",
10, self.AttackSet, DesignateName )
if not MarkedTypes[TargetUnitType] then
MarkedTypes[TargetUnitType] = true
ReportTypes:Add(TargetUnitType)
--ReportTypes:Add(TargetUnitType)
end
ReportLaserCodes:Add(RecceUnit.LaserCode)
--ReportLaserCodes:Add(RecceUnit.LaserCode)
return
end
else
@@ -1303,16 +1304,16 @@ do -- DESIGNATE
if Recce then
Recce:LaseOff()
Recce:MessageToSetGroup( "Target " .. TargetUnit:GetTypeName() "out of LOS. Cancelling lase!", 5, self.AttackSet, self.DesignateName )
Recce:MessageToSetGroup( "Target " .. TargetUnit:GetTypeName() "out of LOS. Cancelling lase!", 10, self.AttackSet, self.DesignateName )
end
else
--MarkingCount = MarkingCount + 1
local TargetUnitType = TargetUnit:GetTypeName()
if not MarkedTypes[TargetUnitType] then
MarkedTypes[TargetUnitType] = true
ReportTypes:Add(TargetUnitType)
--ReportTypes:Add(TargetUnitType)
end
ReportLaserCodes:Add(RecceUnit.LaserCode)
--ReportLaserCodes:Add(RecceUnit.LaserCode)
end
end
end
@@ -1322,19 +1323,19 @@ do -- DESIGNATE
local TargetUnitType = TargetUnit:GetTypeName()
if not MarkedTypes[TargetUnitType] then
MarkedTypes[TargetUnitType] = true
ReportTypes:Add(TargetUnitType)
--ReportTypes:Add(TargetUnitType)
end
ReportLaserCodes:Add(Recce.LaserCode)
--Recce:MessageToSetGroup( self.DesignateName .. ": Marking " .. TargetUnit:GetTypeName() .. " with laser " .. Recce.LaserCode .. ".", 5, self.AttackSet )
--ReportLaserCodes:Add(Recce.LaserCode)
Recce:MessageToSetGroup( self.DesignateName .. ": Marking " .. TargetUnit:GetTypeName() .. " with laser " .. Recce.LaserCode .. ".", 10, self.AttackSet )
end
end
end
end
)
local MarkedTypesText = ReportTypes:Text(', ')
local MarkedLaserCodesText = ReportLaserCodes:Text(', ')
self.CC:GetPositionable():MessageToSetGroup( "Marking " .. MarkingCount .. " x " .. MarkedTypesText .. ", code " .. MarkedLaserCodesText .. ".", 5, self.AttackSet, self.DesignateName )
--local MarkedTypesText = ReportTypes:Text(', ')
--local MarkedLaserCodesText = ReportLaserCodes:Text(', ')
--self.CC:GetPositionable():MessageToSetGroup( "Marking " .. MarkingCount .. " x " .. MarkedTypesText .. ", code " .. MarkedLaserCodesText .. ".", 5, self.AttackSet, self.DesignateName )
self:__Lasing( -self.LaseDuration, Index, Duration, LaserCodeRequested )
+146 -140
View File
@@ -1,4 +1,4 @@
--- **Functional** -- Models the detection of enemy units by FACs or RECCEs and group them according various methods.
--- **Functional** - Models the detection of enemy units by FACs or RECCEs and group them according various methods.
--
-- ===
--
@@ -40,7 +40,7 @@
do -- DETECTION_BASE
--- @type DETECTION_BASE
-- @field Core.Set#SET_GROUP DetectionSetGroup The @{Set} of GROUPs in the Forward Air Controller role.
-- @field Core.Set#SET_GROUP DetectionSetGroup The @{Core.Set} of GROUPs in the Forward Air Controller role.
-- @field DCS#Distance DetectionRange The range till which targets are accepted to be detected.
-- @field #DETECTION_BASE.DetectedObjects DetectedObjects The list of detected objects.
-- @field #table DetectedObjectsIdentified Map of the DetectedObjects identified.
@@ -318,7 +318,7 @@ do -- DETECTION_BASE
--- DETECTION constructor.
-- @param #DETECTION_BASE self
-- @param Core.Set#SET_GROUP DetectionSet The @{Set} of @{Group}s that is used to detect the units.
-- @param Core.Set#SET_GROUP DetectionSet The @{Core.Set} of @{Wrapper.Group}s that is used to detect the units.
-- @return #DETECTION_BASE self
function DETECTION_BASE:New( DetectionSet )
@@ -474,7 +474,7 @@ do -- DETECTION_BASE
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
-- @param #table DetectedItem The DetectedItem.
-- @param #DetectedItem DetectedItem The DetectedItem data structure.
self:AddTransition( "*", "Stop", "Stopped" )
@@ -653,131 +653,132 @@ do -- DETECTION_BASE
-- self:T2( { TargetIsDetected = TargetIsDetected, TargetIsVisible = TargetIsVisible, TargetLastTime = TargetLastTime, TargetKnowType = TargetKnowType, TargetKnowDistance = TargetKnowDistance, TargetLastPos = TargetLastPos, TargetLastVelocity = TargetLastVelocity } )
-- Only process if the target is visible. Detection also returns invisible units.
-- if Detection.visible == true then
local DetectionAccepted = true
local DetectedObjectName = DetectedObject:getName()
local DetectedObjectType = DetectedObject:getTypeName()
local DetectedObjectVec3 = DetectedObject:getPoint()
local DetectedObjectVec2 = { x = DetectedObjectVec3.x, y = DetectedObjectVec3.z }
local DetectionGroupVec3 = Detection:GetVec3() or {x=0,y=0,z=0}
local DetectionGroupVec2 = { x = DetectionGroupVec3.x, y = DetectionGroupVec3.z }
local Distance = ((DetectedObjectVec3.x - DetectionGroupVec3.x) ^ 2 +
(DetectedObjectVec3.y - DetectionGroupVec3.y) ^ 2 +
(DetectedObjectVec3.z - DetectionGroupVec3.z) ^ 2) ^ 0.5 / 1000
local DetectedUnitCategory = DetectedObject:getDesc().category
-- self:F( { "Detected Target:", DetectionGroupName, DetectedObjectName, DetectedObjectType, Distance, DetectedUnitCategory } )
-- Calculate Acceptance
DetectionAccepted = self._.FilterCategories[DetectedUnitCategory] ~= nil and DetectionAccepted or false
-- if Distance > 15000 then
-- if DetectedUnitCategory == Unit.Category.GROUND_UNIT or DetectedUnitCategory == Unit.Category.SHIP then
-- if DetectedObject:hasSensors( Unit.SensorType.RADAR, Unit.RadarType.AS ) == false then
-- DetectionAccepted = false
-- end
-- end
-- end
if self.AcceptRange and Distance * 1000 > self.AcceptRange then
DetectionAccepted = false
end
if self.AcceptZones then
local AnyZoneDetection = false
for AcceptZoneID, AcceptZone in pairs( self.AcceptZones ) do
local AcceptZone = AcceptZone -- Core.Zone#ZONE_BASE
if AcceptZone:IsVec2InZone( DetectedObjectVec2 ) then
AnyZoneDetection = true
--if Detection.visible == true then
local DetectionAccepted = true
local DetectedObjectName = DetectedObject:getName()
local DetectedObjectType = DetectedObject:getTypeName()
local DetectedObjectVec3 = DetectedObject:getPoint()
local DetectedObjectVec2 = { x = DetectedObjectVec3.x, y = DetectedObjectVec3.z }
local DetectionGroupVec3 = Detection:GetVec3() or {x=0,y=0,z=0}
local DetectionGroupVec2 = { x = DetectionGroupVec3.x, y = DetectionGroupVec3.z }
local Distance = ( ( DetectedObjectVec3.x - DetectionGroupVec3.x )^2 +
( DetectedObjectVec3.y - DetectionGroupVec3.y )^2 +
( DetectedObjectVec3.z - DetectionGroupVec3.z )^2
) ^ 0.5 / 1000
local DetectedUnitCategory = DetectedObject:getDesc().category
--self:F( { "Detected Target:", DetectionGroupName, DetectedObjectName, DetectedObjectType, Distance, DetectedUnitCategory } )
-- Calculate Acceptance
DetectionAccepted = self._.FilterCategories[DetectedUnitCategory] ~= nil and DetectionAccepted or false
-- if Distance > 15000 then
-- if DetectedUnitCategory == Unit.Category.GROUND_UNIT or DetectedUnitCategory == Unit.Category.SHIP then
-- if DetectedObject:hasSensors( Unit.SensorType.RADAR, Unit.RadarType.AS ) == false then
-- DetectionAccepted = false
-- end
-- end
-- end
if self.AcceptRange and Distance * 1000 > self.AcceptRange then
DetectionAccepted = false
end
if self.AcceptZones then
local AnyZoneDetection = false
for AcceptZoneID, AcceptZone in pairs( self.AcceptZones ) do
local AcceptZone = AcceptZone -- Core.Zone#ZONE_BASE
if AcceptZone:IsVec2InZone( DetectedObjectVec2 ) then
AnyZoneDetection = true
end
end
if not AnyZoneDetection then
DetectionAccepted = false
end
end
if not AnyZoneDetection then
DetectionAccepted = false
end
end
if self.RejectZones then
for RejectZoneID, RejectZone in pairs( self.RejectZones ) do
local RejectZone = RejectZone -- Core.Zone#ZONE_BASE
if RejectZone:IsVec2InZone( DetectedObjectVec2 ) == true then
DetectionAccepted = false
end
end
end
-- Calculate additional probabilities
if not self.DetectedObjects[DetectedObjectName] and TargetIsVisible and self.DistanceProbability then
local DistanceFactor = Distance / 4
local DistanceProbabilityReversed = (1 - self.DistanceProbability) * DistanceFactor
local DistanceProbability = 1 - DistanceProbabilityReversed
DistanceProbability = DistanceProbability * 30 / 300
local Probability = math.random() -- Selects a number between 0 and 1
-- self:T( { Probability, DistanceProbability } )
if Probability > DistanceProbability then
DetectionAccepted = false
end
end
if not self.DetectedObjects[DetectedObjectName] and TargetIsVisible and self.AlphaAngleProbability then
local NormalVec2 = { x = DetectedObjectVec2.x - DetectionGroupVec2.x, y = DetectedObjectVec2.y - DetectionGroupVec2.y }
local AlphaAngle = math.atan2( NormalVec2.y, NormalVec2.x )
local Sinus = math.sin( AlphaAngle )
local AlphaAngleProbabilityReversed = (1 - self.AlphaAngleProbability) * (1 - Sinus)
local AlphaAngleProbability = 1 - AlphaAngleProbabilityReversed
AlphaAngleProbability = AlphaAngleProbability * 30 / 300
local Probability = math.random() -- Selects a number between 0 and 1
-- self:T( { Probability, AlphaAngleProbability } )
if Probability > AlphaAngleProbability then
DetectionAccepted = false
end
end
if not self.DetectedObjects[DetectedObjectName] and TargetIsVisible and self.ZoneProbability then
for ZoneDataID, ZoneData in pairs( self.ZoneProbability ) do
self:F( { ZoneData } )
local ZoneObject = ZoneData[1] -- Core.Zone#ZONE_BASE
local ZoneProbability = ZoneData[2] -- #number
ZoneProbability = ZoneProbability * 30 / 300
if ZoneObject:IsVec2InZone( DetectedObjectVec2 ) == true then
local Probability = math.random() -- Selects a number between 0 and 1
-- self:T( { Probability, ZoneProbability } )
if Probability > ZoneProbability then
if self.RejectZones then
for RejectZoneID, RejectZone in pairs( self.RejectZones ) do
local RejectZone = RejectZone -- Core.Zone#ZONE_BASE
if RejectZone:IsVec2InZone( DetectedObjectVec2 ) == true then
DetectionAccepted = false
break
end
end
end
end
if DetectionAccepted then
HasDetectedObjects = true
self.DetectedObjects[DetectedObjectName] = self.DetectedObjects[DetectedObjectName] or {}
self.DetectedObjects[DetectedObjectName].Name = DetectedObjectName
if TargetIsDetected and TargetIsDetected == true then
self.DetectedObjects[DetectedObjectName].IsDetected = TargetIsDetected
-- Calculate additional probabilities
if not self.DetectedObjects[DetectedObjectName] and TargetIsVisible and self.DistanceProbability then
local DistanceFactor = Distance / 4
local DistanceProbabilityReversed = ( 1 - self.DistanceProbability ) * DistanceFactor
local DistanceProbability = 1 - DistanceProbabilityReversed
DistanceProbability = DistanceProbability * 30 / 300
local Probability = math.random() -- Selects a number between 0 and 1
--self:T( { Probability, DistanceProbability } )
if Probability > DistanceProbability then
DetectionAccepted = false
end
end
if TargetIsDetected and TargetIsVisible and TargetIsVisible == true then
self.DetectedObjects[DetectedObjectName].IsVisible = TargetIsDetected and TargetIsVisible
if not self.DetectedObjects[DetectedObjectName] and TargetIsVisible and self.AlphaAngleProbability then
local NormalVec2 = { x = DetectedObjectVec2.x - DetectionGroupVec2.x, y = DetectedObjectVec2.y - DetectionGroupVec2.y }
local AlphaAngle = math.atan2( NormalVec2.y, NormalVec2.x )
local Sinus = math.sin( AlphaAngle )
local AlphaAngleProbabilityReversed = ( 1 - self.AlphaAngleProbability ) * ( 1 - Sinus )
local AlphaAngleProbability = 1 - AlphaAngleProbabilityReversed
AlphaAngleProbability = AlphaAngleProbability * 30 / 300
local Probability = math.random() -- Selects a number between 0 and 1
--self:T( { Probability, AlphaAngleProbability } )
if Probability > AlphaAngleProbability then
DetectionAccepted = false
end
end
if TargetIsDetected and not self.DetectedObjects[DetectedObjectName].KnowType then
self.DetectedObjects[DetectedObjectName].KnowType = TargetIsDetected and TargetKnowType
if not self.DetectedObjects[DetectedObjectName] and TargetIsVisible and self.ZoneProbability then
for ZoneDataID, ZoneData in pairs( self.ZoneProbability ) do
self:F({ZoneData})
local ZoneObject = ZoneData[1] -- Core.Zone#ZONE_BASE
local ZoneProbability = ZoneData[2] -- #number
ZoneProbability = ZoneProbability * 30 / 300
if ZoneObject:IsVec2InZone( DetectedObjectVec2 ) == true then
local Probability = math.random() -- Selects a number between 0 and 1
--self:T( { Probability, ZoneProbability } )
if Probability > ZoneProbability then
DetectionAccepted = false
break
end
end
end
end
if DetectionAccepted then
HasDetectedObjects = true
self.DetectedObjects[DetectedObjectName] = self.DetectedObjects[DetectedObjectName] or {}
self.DetectedObjects[DetectedObjectName].Name = DetectedObjectName
if TargetIsDetected and TargetIsDetected == true then
self.DetectedObjects[DetectedObjectName].IsDetected = TargetIsDetected
end
if TargetIsDetected and TargetIsVisible and TargetIsVisible == true then
self.DetectedObjects[DetectedObjectName].IsVisible = TargetIsDetected and TargetIsVisible
end
if TargetIsDetected and not self.DetectedObjects[DetectedObjectName].KnowType then
self.DetectedObjects[DetectedObjectName].KnowType = TargetIsDetected and TargetKnowType
end
self.DetectedObjects[DetectedObjectName].KnowDistance = TargetKnowDistance -- Detection.distance -- TargetKnowDistance
self.DetectedObjects[DetectedObjectName].LastTime = (TargetIsDetected and TargetIsVisible == false) and TargetLastTime
@@ -1981,7 +1982,7 @@ do -- DETECTION_UNITS
--- Will detect units within the battle zone.
--
-- It will build a DetectedItems list filled with DetectedItems. Each DetectedItem will contain a field Set, which contains a @{Core.Set#SET_UNIT} containing ONE @{UNIT} object reference.
-- It will build a DetectedItems list filled with DetectedItems. Each DetectedItem will contain a field Set, which contains a @{Core.Set#SET_UNIT} containing ONE @{Wrapper.Unit#UNIT} object reference.
-- Beware that when the amount of units detected is large, the DetectedItems list will be large also.
--
-- @field #DETECTION_UNITS
@@ -1992,7 +1993,7 @@ do -- DETECTION_UNITS
--- DETECTION_UNITS constructor.
-- @param Functional.Detection#DETECTION_UNITS self
-- @param Core.Set#SET_GROUP DetectionSetGroup The @{Set} of GROUPs in the Forward Air Controller role.
-- @param Core.Set#SET_GROUP DetectionSetGroup The @{Core.Set} of GROUPs in the Forward Air Controller role.
-- @return Functional.Detection#DETECTION_UNITS self
function DETECTION_UNITS:New( DetectionSetGroup )
@@ -2151,8 +2152,9 @@ do -- DETECTION_UNITS
-- @param #DETECTION_BASE.DetectedItem DetectedItem The DetectedItem.
-- @param Wrapper.Group#GROUP AttackGroup The group to generate the report for.
-- @param Core.Settings#SETTINGS Settings Message formatting settings to use.
-- @param #boolean ForceA2GCoordinate Set creation of A2G coordinate
-- @return Core.Report#REPORT The report of the detection items.
function DETECTION_UNITS:DetectedItemReportSummary( DetectedItem, AttackGroup, Settings )
function DETECTION_UNITS:DetectedItemReportSummary( DetectedItem, AttackGroup, Settings, ForceA2GCoordinate )
self:F( { DetectedItem = DetectedItem } )
local DetectedItemID = self:GetDetectedItemID( DetectedItem )
@@ -2187,7 +2189,11 @@ do -- DETECTION_UNITS
-- TODO: solve Index reference
local DetectedItemCoordinate = self:GetDetectedItemCoordinate( DetectedItem )
local DetectedItemCoordText = DetectedItemCoordinate:ToString( AttackGroup, Settings )
if ForceA2GCoordinate then
DetectedItemCoordText = DetectedItemCoordinate:ToStringA2G(AttackGroup,Settings)
end
local ThreatLevelA2G = self:GetDetectedItemThreatLevel( DetectedItem )
local Report = REPORT:New()
@@ -2231,7 +2237,7 @@ do -- DETECTION_TYPES
--- Will detect units within the battle zone.
-- It will build a DetectedItems[] list filled with DetectedItems, grouped by the type of units detected.
-- Each DetectedItem will contain a field Set, which contains a @{Core.Set#SET_UNIT} containing ONE @{UNIT} object reference.
-- Each DetectedItem will contain a field Set, which contains a @{Core.Set#SET_UNIT} containing ONE @{Wrapper.Unit#UNIT} object reference.
-- Beware that when the amount of different types detected is large, the DetectedItems[] list will be large also.
--
-- @field #DETECTION_TYPES
@@ -2242,7 +2248,7 @@ do -- DETECTION_TYPES
--- DETECTION_TYPES constructor.
-- @param Functional.Detection#DETECTION_TYPES self
-- @param Core.Set#SET_GROUP DetectionSetGroup The @{Set} of GROUPs in the Recce role.
-- @param Core.Set#SET_GROUP DetectionSetGroup The @{Core.Set} of GROUPs in the Recce role.
-- @return Functional.Detection#DETECTION_TYPES self
function DETECTION_TYPES:New( DetectionSetGroup )
@@ -2348,6 +2354,7 @@ do -- DETECTION_TYPES
if not DetectedItem then
DetectedItem = self:AddDetectedItem( "TYPE", DetectedTypeName )
DetectedItem.TypeName = DetectedTypeName
DetectedItem.Name = DetectedUnitName -- fix by @Nocke
end
DetectedItem.Set:AddUnit( DetectedUnit )
@@ -2430,7 +2437,7 @@ do -- DETECTION_AREAS
--- @type DETECTION_AREAS
-- @field DCS#Distance DetectionZoneRange The range till which targets are grouped upon the first detected target.
-- @field #DETECTION_BASE.DetectedItems DetectedItems A list of areas containing the set of @{Wrapper.Unit}s, @{Zone}s, the center @{Wrapper.Unit} within the zone, and ID of each area that was detected within a DetectionZoneRange.
-- @field #DETECTION_BASE.DetectedItems DetectedItems A list of areas containing the set of @{Wrapper.Unit}s, @{Core.Zone}s, the center @{Wrapper.Unit} within the zone, and ID of each area that was detected within a DetectionZoneRange.
-- @extends Functional.Detection#DETECTION_BASE
--- Detect units within the battle zone for a list of @{Wrapper.Group}s detecting targets following (a) detection method(s),
@@ -2439,16 +2446,16 @@ do -- DETECTION_AREAS
-- A set with multiple detected zones will be created as there are groups of units detected.
--
-- ## 4.1) Retrieve the Detected Unit Sets and Detected Zones
--
-- The methods to manage the DetectedItems[].Set(s) are implemented in @{Functional.Detection#DETECTION_BASE} and
--
-- The methods to manage the DetectedItems[].Set(s) are implemented in @{Functional.Detection#DECTECTION_BASE} and
-- the methods to manage the DetectedItems[].Zone(s) are implemented in @{Functional.Detection#DETECTION_AREAS}.
--
--
-- Retrieve the DetectedItems[].Set with the method @{Functional.Detection#DETECTION_BASE.GetDetectedSet}(). A @{Core.Set#SET_UNIT} object will be returned.
--
--
-- Retrieve the formed @{Zone@ZONE_UNIT}s as a result of the grouping the detected units within the DetectionZoneRange, use the method @{Functional.Detection#DETECTION_AREAS.GetDetectionZones}().
-- To understand the amount of zones created, use the method @{Functional.Detection#DETECTION_AREAS.GetDetectionZoneCount}().
-- To understand the amount of zones created, use the method @{Functional.Detection#DETECTION_AREAS.GetDetectionZoneCount}().
-- If you want to obtain a specific zone from the DetectedZones, use the method @{Functional.Detection#DETECTION_AREAS.GetDetectionZoneByID}() with a given index.
--
--
-- ## 4.4) Flare or Smoke detected units
--
-- Use the methods @{Functional.Detection#DETECTION_AREAS.FlareDetectedUnits}() or @{Functional.Detection#DETECTION_AREAS.SmokeDetectedUnits}() to flare or smoke the detected units when a new detection has taken place.
@@ -2471,15 +2478,15 @@ do -- DETECTION_AREAS
--- DETECTION_AREAS constructor.
-- @param #DETECTION_AREAS self
-- @param Core.Set#SET_GROUP DetectionSetGroup The @{Set} of GROUPs in the Forward Air Controller role.
-- @param DCS#Distance DetectionZoneRange The range till which targets are grouped upon the first detected target.
-- @param Core.Set#SET_GROUP DetectionSetGroup The @{Core.Set} of GROUPs in the Forward Air Controller role.
-- @param #number DetectionZoneRange The range in meters within which targets are grouped upon the first detected target. Default 5000m.
-- @return #DETECTION_AREAS
function DETECTION_AREAS:New( DetectionSetGroup, DetectionZoneRange )
-- Inherits from DETECTION_BASE
local self = BASE:Inherit( self, DETECTION_BASE:New( DetectionSetGroup ) )
self.DetectionZoneRange = DetectionZoneRange
self.DetectionZoneRange = DetectionZoneRange or 5000
self._SmokeDetectedUnits = false
self._FlareDetectedUnits = false
@@ -2489,10 +2496,10 @@ do -- DETECTION_AREAS
return self
end
--- Retrieve set of detected zones.
-- @param #DETECTION_AREAS self
-- @return Core.Set#SET_ZONE The @{Set} of ZONE_UNIT objects detected.
-- @return Core.Set#SET_ZONE The @{Core.Set} of ZONE_UNIT objects detected.
function DETECTION_AREAS:GetDetectionZones()
local zoneset = SET_ZONE:New()
for _ID,_Item in pairs (self.DetectedItems) do
@@ -2982,4 +2989,3 @@ do -- DETECTION_AREAS
end
end
@@ -1,8 +1,12 @@
--- **Functional** - Captures the class DETECTION_ZONES.
-- @module Functional.DetectionZones
-- @image MOOSE.JPG
do -- DETECTION_ZONES
--- @type DETECTION_ZONES
-- @field DCS#Distance DetectionZoneRange The range till which targets are grouped upon the first detected target.
-- @field #DETECTION_BASE.DetectedItems DetectedItems A list of areas containing the set of @{Wrapper.Unit}s, @{Zone}s, the center @{Wrapper.Unit} within the zone, and ID of each area that was detected within a DetectionZoneRange.
-- @field #DETECTION_BASE.DetectedItems DetectedItems A list of areas containing the set of @{Wrapper.Unit}s, @{Core.Zone}s, the center @{Wrapper.Unit} within the zone, and ID of each area that was detected within a DetectionZoneRange.
-- @extends Functional.Detection#DETECTION_BASE
--- (old, to be revised ) Detect units within the battle zone for a list of @{Core.Zone}s detecting targets following (a) detection method(s),
@@ -40,27 +44,27 @@ do -- DETECTION_ZONES
ClassName = "DETECTION_ZONES",
DetectionZoneRange = nil,
}
--- DETECTION_ZONES constructor.
-- @param #DETECTION_ZONES self
-- @param Core.Set#SET_ZONE DetectionSetZone The @{Set} of ZONE_RADIUS.
-- @param Core.Set#SET_ZONE DetectionSetZone The @{Core.Set} of ZONE_RADIUS.
-- @param DCS#Coalition.side DetectionCoalition The coalition of the detection.
-- @return #DETECTION_ZONES
function DETECTION_ZONES:New( DetectionSetZone, DetectionCoalition )
-- Inherits from DETECTION_BASE
local self = BASE:Inherit( self, DETECTION_BASE:New( DetectionSetZone ) ) -- #DETECTION_ZONES
self.DetectionSetZone = DetectionSetZone -- Core.Set#SET_ZONE
self.DetectionCoalition = DetectionCoalition
self._SmokeDetectedUnits = false
self._FlareDetectedUnits = false
self._SmokeDetectedZones = false
self._FlareDetectedZones = false
self._BoundDetectedZones = false
return self
end
@@ -1,4 +1,4 @@
--- **Functional** -- Taking the lead of AI escorting your flight.
--- **Functional** - Taking the lead of AI escorting your flight.
--
-- ===
--
+347 -322
View File
@@ -1,4 +1,4 @@
--- **Functional** - (R2.5) - Yet Another Missile Trainer.
--- **Functional** - Yet Another Missile Trainer.
--
--
-- Practice to evade missiles without being destroyed.
@@ -20,12 +20,13 @@
-- ===
--
-- ### Author: **funkyfranky**
-- @module Functional.FOX
-- @module Functional.Fox
-- @image Functional_FOX.png
--- FOX class.
-- @type FOX
-- @field #string ClassName Name of the class.
-- @field #number verbose Verbosity level.
-- @field #boolean Debug Debug mode. Messages to all about status.
-- @field #string lid Class id string for output to DCS log file.
-- @field #table menuadded Table of groups the menu was added for.
@@ -124,6 +125,7 @@
-- @field #FOX
FOX = {
ClassName = "FOX",
verbose = 0,
Debug = false,
lid = nil,
menuadded = {},
@@ -168,7 +170,7 @@ FOX = {
--- Missile data table.
-- @type FOX.MissileData
-- @field Wrapper.Unit#UNIT weapon Missile weapon unit.
-- @field DCS#Weapon weapon Missile weapon object.
-- @field #boolean active If true the missile is active.
-- @field #string missileType Type of missile.
-- @field #string missileName Name of missile.
@@ -185,6 +187,8 @@ FOX = {
-- @field #string targetName Name of the target unit or "unknown".
-- @field #string targetOrig Name of the "original" target, i.e. the one right after launched.
-- @field #FOX.PlayerData targetPlayer Player that was targeted or nil.
-- @field Core.Point#COORDINATE missileCoord Missile coordinate during tracking.
-- @field Wrapper.Weapon#WEAPON Weapon Weapon object.
--- Main radio menu on group level.
-- @field #table MenuF10 Root menu table on group level.
@@ -196,7 +200,7 @@ FOX.MenuF10Root=nil
--- FOX class version.
-- @field #string version
FOX.version="0.6.1"
FOX.version="0.8.0"
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- ToDo list
@@ -492,7 +496,6 @@ end
--- Disable F10 menu for all players.
-- @param #FOX self
-- @param #boolean switch If true debug mode on. If false/nil debug mode off
-- @return #FOX self
function FOX:SetDisableF10Menu()
@@ -501,6 +504,26 @@ function FOX:SetDisableF10Menu()
return self
end
--- Enable F10 menu for all players.
-- @param #FOX self
-- @return #FOX self
function FOX:SetEnableF10Menu()
self.menudisabled=false
return self
end
--- Set verbosity level.
-- @param #FOX self
-- @param #number VerbosityLevel Level of output (higher=more). Default 0.
-- @return #FOX self
function FOX:SetVerbosity(VerbosityLevel)
self.verbose=VerbosityLevel or 0
return self
end
--- Set default player setting for missile destruction.
-- @param #FOX self
-- @param #boolean switch If true missiles are destroyed. If false/nil missiles are not destroyed.
@@ -596,7 +619,9 @@ function FOX:onafterStatus(From, Event, To)
local clock=UTILS.SecondsToClock(time)
-- Status.
self:I(self.lid..string.format("Missile trainer status %s: %s", clock, fsmstate))
if self.verbose>=1 then
self:I(self.lid..string.format("Missile trainer status %s: %s", clock, fsmstate))
end
-- Check missile status.
self:_CheckMissileStatus()
@@ -704,7 +729,9 @@ function FOX:_CheckMissileStatus()
if #self.missiles==0 then
text=text.." none"
end
self:I(self.lid..text)
if self.verbose>=2 then
self:I(self.lid..text)
end
-- Remove inactive missiles.
for i=#self.missiles,1,-1 do
@@ -734,7 +761,7 @@ function FOX:_IsProtected(targetunit)
if targetgroup then
local targetname=targetgroup:GetName()
for _,_group in pairs(self.protectedset:GetSetObjects()) do
for _,_group in pairs(self.protectedset:GetSet()) do
local group=_group --Wrapper.Group#GROUP
if group then
@@ -753,6 +780,277 @@ function FOX:_IsProtected(targetunit)
return false
end
--- Function called from weapon tracking.
-- @param Wrapper.Weapon#WEAPON weapon Weapon object.
-- @param #FOX self FOX object.
-- @param #FOX.MissileData missile Fired missile
function FOX._FuncTrack(weapon, self, missile)
-- Missile coordinate.
local missileCoord= missile.missileCoord:UpdateFromVec3(weapon.vec3) --COORDINATE:NewFromVec3(_lastBombPos)
-- Missile velocity in m/s.
local missileVelocity=weapon:GetSpeed() --UTILS.VecNorm(_ordnance:getVelocity())
-- Update missile target if necessary.
self:GetMissileTarget(missile)
-- Target unit of the missile.
local target=nil --Wrapper.Unit#UNIT
if missile.targetUnit then
-----------------------------------
-- Missile has a specific target --
-----------------------------------
if missile.targetPlayer then
-- Target is a player.
if missile.targetPlayer.destroy==true then
target=missile.targetUnit
end
else
-- Check if unit is protected.
if self:_IsProtected(missile.targetUnit) then
target=missile.targetUnit
end
end
else
------------------------------------
-- Missile has NO specific target --
------------------------------------
-- TODO: This might cause a problem with wingman. Even if the shooter itself is excluded from the check, it's wingmen are not.
-- That would trigger the distance check right after missile launch if things to wrong.
--
-- Possible solutions:
-- * Time check: enable this check after X seconds after missile was fired. What is X?
-- * Coalition check. But would not work in training situations where blue on blue is valid!
-- * At least enable it for surface-to-air missiles.
local function _GetTarget(_unit)
local unit=_unit --Wrapper.Unit#UNIT
-- Player position.
local playerCoord=unit:GetCoordinate()
-- Distance.
local dist=missileCoord:Get3DDistance(playerCoord)
-- Update mindist if necessary. Only include players in range of missile + 50% safety margin.
if dist<=self.explosiondist then
return unit
end
end
-- Distance to closest player.
local mindist=nil
-- Loop over players.
for _,_player in pairs(self.players) do
local player=_player --#FOX.PlayerData
-- Check that player was not the one who launched the missile.
if player.unitname~=missile.shooterName then
-- Player position.
local playerCoord=player.unit:GetCoordinate()
-- Distance.
local dist=missileCoord:Get3DDistance(playerCoord)
-- Distance from shooter to player.
local Dshooter2player=playerCoord:Get3DDistance(missile.shotCoord)
-- Update mindist if necessary. Only include players in range of missile + 50% safety margin.
if (mindist==nil or dist<mindist) and (Dshooter2player<=missile.missileRange*1.5 or dist<=self.explosiondist) then
mindist=dist
target=player.unit
end
end
end
if self.protectedset then
-- Distance to closest protected unit.
mindist=nil
for _,_group in pairs(self.protectedset:GetSet()) do
local group=_group --Wrapper.Group#GROUP
for _,_unit in pairs(group:GetUnits()) do
local unit=_unit --Wrapper.Unit#UNIT
if unit and unit:IsAlive() then
-- Check that player was not the one who launched the missile.
if unit:GetName()~=missile.shooterName then
-- Player position.
local playerVec3=unit:GetVec3()
-- Distance.
local dist=missileCoord:Get3DDistance(playerVec3)
-- Distance from shooter to player.
local Dshooter2player=missile.shotCoord:Get3DDistance(playerVec3)
-- Update mindist if necessary. Only include players in range of missile + 50% safety margin.
if (mindist==nil or dist<mindist) and (Dshooter2player<=missile.missileRange*1.5 or dist<=self.explosiondist) then
mindist=dist
target=unit
end
end
end
end
end
end
if target then
self:T(self.lid..string.format("Missile %s with NO explicit target got closest unit to missile as target %s. Dist=%s m", missile.missileType, target:GetName(), tostring(mindist)))
end
end
-- Check if missile has a valid target.
if target then
-- Target coordinate.
local targetVec3=target:GetVec3() --target:GetCoordinate()
-- Distance from missile to target.
local distance=missileCoord:Get3DDistance(targetVec3)
-- Distance missile to shooter.
local distShooter=nil
if missile.shooterUnit and missile.shooterUnit:IsAlive() then
distShooter=missileCoord:Get3DDistance(missile.shooterUnit:GetVec3())
end
-- Debug output.
if self.Debug then
local bearing=missileCoord:HeadingTo(targetVec3)
local eta=distance/missileVelocity
-- Debug distance check.
self:I(self.lid..string.format("Missile %s Target %s: Distance = %.1f m, v=%.1f m/s, bearing=%03d°, ETA=%.1f sec", missile.missileType, target:GetName(), distance, missileVelocity, bearing, eta))
end
-- Distroy missile if it's getting too close.
local destroymissile=distance<=self.explosiondist
-- Check BIG missiles.
if self.explosiondist2 and distance<=self.explosiondist2 and not destroymissile then
destroymissile=missile.explosive>=self.bigmissilemass
end
-- If missile is 150 m from target ==> destroy missile if in safe zone.
if destroymissile and self:_CheckCoordSafe(targetVec3) then
-- Destroy missile.
self:I(self.lid..string.format("Destroying missile %s(%s) fired by %s aimed at %s [player=%s] at distance %.1f m",
missile.missileType, missile.missileName, missile.shooterName, target:GetName(), tostring(missile.targetPlayer~=nil), distance))
weapon:Destroy()
-- Missile is not active any more.
missile.active=false
-- Debug smoke.
if self.Debug then
missileCoord:SmokeRed()
end
-- Create event.
self:MissileDestroyed(missile)
-- Little explosion for the visual effect.
if self.explosionpower>0 and distance>50 and (distShooter==nil or (distShooter and distShooter>50)) then
missileCoord:Explosion(self.explosionpower)
end
-- Target was a player.
if missile.targetPlayer then
-- Message to target.
local text=string.format("Destroying missile. %s", self:_DeadText())
MESSAGE:New(text, 10):ToGroup(target:GetGroup())
-- Increase dead counter.
missile.targetPlayer.dead=missile.targetPlayer.dead+1
end
-- We could disable the tracking here but then the impact function would not be called.
--weapon.tracking=false
else
-- Time step.
local dt=1.0
if distance>50000 then
-- > 50 km
dt=self.dt50 --=5.0
elseif distance>10000 then
-- 10-50 km
dt=self.dt10 --=1.0
elseif distance>5000 then
-- 5-10 km
dt=self.dt05 --0.5
elseif distance>1000 then
-- 1-5 km
dt=self.dt01 --0.1
else
-- < 1 km
dt=self.dt00 --0.01
end
-- Set time step.
weapon:SetTimeStepTrack(dt)
end
else
-- No current target.
self:T(self.lid..string.format("Missile %s(%s) fired by %s has no current target. Checking back in 0.1 sec.", missile.missileType, missile.missileName, missile.shooterName))
weapon:SetTimeStepTrack(0.1)
end
end
--- Callback function on impact or destroy otherwise.
-- @param Wrapper.Weapon#WEAPON weapon Weapon object.
-- @param #FOX self FOX object.
-- @param #FOX.MissileData missile Fired missile.
function FOX._FuncImpact(weapon, self, missile)
if missile.targetPlayer then
-- Get human player.
local player=missile.targetPlayer
-- Check for player and distance < 10 km.
if player and player.unit:IsAlive() then -- and missileCoord and player.unit:GetCoordinate():Get3DDistance(missileCoord)<10*1000 then
local text=string.format("Missile defeated. Well done, %s!", player.name)
MESSAGE:New(text, 10):ToClient(player.client)
-- Increase defeated counter.
player.defeated=player.defeated+1
end
end
-- Missile is not active any more.
missile.active=false
--Terminate the timer.
self:T(FOX.lid..string.format("Terminating missile track timer."))
weapon.tracking=false
end
--- Missle launch event.
-- @param #FOX self
-- @param #string From From state.
@@ -792,7 +1090,7 @@ function FOX:onafterMissileLaunch(From, Event, To, missile)
local text=string.format("Missile launch detected! Distance %.1f NM, bearing %03d°.", UTILS.MetersToNM(distance), bearing)
-- Say notching headings.
BASE:ScheduleOnce(5, FOX._SayNotchingHeadings, self, player, missile.weapon)
self:ScheduleOnce(5, FOX._SayNotchingHeadings, self, player, missile.weapon)
--TODO: ALERT or INFO depending on whether this is a direct target.
--TODO: lauchalertall option.
@@ -809,304 +1107,19 @@ function FOX:onafterMissileLaunch(From, Event, To, missile)
end
end
end
end
-- Init missile position.
local _lastBombPos = {x=0,y=0,z=0}
-- Set callback function for tracking.
missile.Weapon:SetFuncTrack(FOX._FuncTrack, self, missile)
-- Missile coordinate.
local missileCoord = nil --Core.Point#COORDINATE
-- Set callback function for impact.
missile.Weapon:SetFuncImpact(FOX._FuncImpact, self, missile)
-- Target unit of the missile.
local target=nil --Wrapper.Unit#UNIT
--- Function monitoring the position of a bomb until impact.
local function trackMissile(_ordnance)
-- When the pcall returns a failure the weapon has hit.
local _status,_bombPos = pcall(
function()
return _ordnance:getPoint()
end)
-- Check if status is not nil. If so, we have a valid point.
if _status then
----------------------------------------------
-- Still in the air. Remember this position --
----------------------------------------------
-- Missile position.
_lastBombPos = {x=_bombPos.x, y=_bombPos.y, z=_bombPos.z}
-- Missile coordinate.
missileCoord=COORDINATE:NewFromVec3(_lastBombPos)
-- Missile velocity in m/s.
local missileVelocity=UTILS.VecNorm(_ordnance:getVelocity())
-- Update missile target if necessary.
self:GetMissileTarget(missile)
if missile.targetUnit then
-----------------------------------
-- Missile has a specific target --
-----------------------------------
if missile.targetPlayer then
-- Target is a player.
if missile.targetPlayer.destroy==true then
target=missile.targetUnit
end
else
-- Check if unit is protected.
if self:_IsProtected(missile.targetUnit) then
target=missile.targetUnit
end
end
else
------------------------------------
-- Missile has NO specific target --
------------------------------------
-- TODO: This might cause a problem with wingman. Even if the shooter itself is excluded from the check, it's wingmen are not.
-- That would trigger the distance check right after missile launch if things to wrong.
--
-- Possible solutions:
-- * Time check: enable this check after X seconds after missile was fired. What is X?
-- * Coalition check. But would not work in training situations where blue on blue is valid!
-- * At least enable it for surface-to-air missiles.
local function _GetTarget(_unit)
local unit=_unit --Wrapper.Unit#UNIT
-- Player position.
local playerCoord=unit:GetCoordinate()
-- Distance.
local dist=missileCoord:Get3DDistance(playerCoord)
-- Update mindist if necessary. Only include players in range of missile + 50% safety margin.
if dist<=self.explosiondist then
return unit
end
end
-- Distance to closest player.
local mindist=nil
-- Loop over players.
for _,_player in pairs(self.players) do
local player=_player --#FOX.PlayerData
-- Check that player was not the one who launched the missile.
if player.unitname~=missile.shooterName then
-- Player position.
local playerCoord=player.unit:GetCoordinate()
-- Distance.
local dist=missileCoord:Get3DDistance(playerCoord)
-- Distance from shooter to player.
local Dshooter2player=playerCoord:Get3DDistance(missile.shotCoord)
-- Update mindist if necessary. Only include players in range of missile + 50% safety margin.
if (mindist==nil or dist<mindist) and (Dshooter2player<=missile.missileRange*1.5 or dist<=self.explosiondist) then
mindist=dist
target=player.unit
end
end
end
if self.protectedset then
-- Distance to closest protected unit.
mindist=nil
for _,_group in pairs(self.protectedset:GetSet()) do
local group=_group --Wrapper.Group#GROUP
for _,_unit in pairs(group:GetUnits()) do
local unit=_unit --Wrapper.Unit#UNIT
if unit and unit:IsAlive() then
-- Check that player was not the one who launched the missile.
if unit:GetName()~=missile.shooterName then
-- Player position.
local playerCoord=unit:GetCoordinate()
-- Distance.
local dist=missileCoord:Get3DDistance(playerCoord)
-- Distance from shooter to player.
local Dshooter2player=playerCoord:Get3DDistance(missile.shotCoord)
-- Update mindist if necessary. Only include players in range of missile + 50% safety margin.
if (mindist==nil or dist<mindist) and (Dshooter2player<=missile.missileRange*1.5 or dist<=self.explosiondist) then
mindist=dist
target=unit
end
end
end
end
end
end
if target then
self:T(self.lid..string.format("Missile %s with NO explicit target got closest unit to missile as target %s. Dist=%s m", missile.missileType, target:GetName(), tostring(mindist)))
end
end
-- Check if missile has a valid target.
if target then
-- Target coordinate.
local targetCoord=target:GetCoordinate()
-- Distance from missile to target.
local distance=missileCoord:Get3DDistance(targetCoord)
-- Distance missile to shooter.
local distShooter=nil
if missile.shooterUnit and missile.shooterUnit:IsAlive() then
distShooter=missileCoord:Get3DDistance(missile.shooterUnit:GetCoordinate())
end
-- Debug output.
if self.Debug then
local bearing=targetCoord:HeadingTo(missileCoord)
local eta=distance/missileVelocity
-- Debug distance check.
self:I(self.lid..string.format("Missile %s Target %s: Distance = %.1f m, v=%.1f m/s, bearing=%03d°, ETA=%.1f sec", missile.missileType, target:GetName(), distance, missileVelocity, bearing, eta))
end
-- Distroy missile if it's getting too close.
local destroymissile=distance<=self.explosiondist
-- Check BIG missiles.
if self.explosiondist2 and distance<=self.explosiondist2 and not destroymissile then
destroymissile=missile.explosive>=self.bigmissilemass
end
-- If missile is 150 m from target ==> destroy missile if in safe zone.
if destroymissile and self:_CheckCoordSafe(targetCoord) then
-- Destroy missile.
self:I(self.lid..string.format("Destroying missile %s(%s) fired by %s aimed at %s [player=%s] at distance %.1f m",
missile.missileType, missile.missileName, missile.shooterName, target:GetName(), tostring(missile.targetPlayer~=nil), distance))
_ordnance:destroy()
-- Missile is not active any more.
missile.active=false
-- Debug smoke.
if self.Debug then
missileCoord:SmokeRed()
targetCoord:SmokeGreen()
end
-- Create event.
self:MissileDestroyed(missile)
-- Little explosion for the visual effect.
if self.explosionpower>0 and distance>50 and (distShooter==nil or (distShooter and distShooter>50)) then
missileCoord:Explosion(self.explosionpower)
end
-- Target was a player.
if missile.targetPlayer then
-- Message to target.
local text=string.format("Destroying missile. %s", self:_DeadText())
MESSAGE:New(text, 10):ToGroup(target:GetGroup())
-- Increase dead counter.
missile.targetPlayer.dead=missile.targetPlayer.dead+1
end
-- Terminate timer.
return nil
else
-- Time step.
local dt=1.0
if distance>50000 then
-- > 50 km
dt=self.dt50 --=5.0
elseif distance>10000 then
-- 10-50 km
dt=self.dt10 --=1.0
elseif distance>5000 then
-- 5-10 km
dt=self.dt05 --0.5
elseif distance>1000 then
-- 1-5 km
dt=self.dt01 --0.1
else
-- < 1 km
dt=self.dt00 --0.01
end
-- Check again in dt seconds.
return timer.getTime()+dt
end
else
-- Destroy missile.
self:T(self.lid..string.format("Missile %s(%s) fired by %s has no current target. Checking back in 0.1 sec.", missile.missileType, missile.missileName, missile.shooterName))
return timer.getTime()+0.1
-- No target ==> terminate timer.
--return nil
end
else
-------------------------------------
-- Missile does not exist any more --
-------------------------------------
if target then
-- Get human player.
local player=self:_GetPlayerFromUnit(target)
-- Check for player and distance < 10 km.
if player and player.unit:IsAlive() then -- and missileCoord and player.unit:GetCoordinate():Get3DDistance(missileCoord)<10*1000 then
local text=string.format("Missile defeated. Well done, %s!", player.name)
MESSAGE:New(text, 10):ToClient(player.client)
-- Increase defeated counter.
player.defeated=player.defeated+1
end
end
-- Missile is not active any more.
missile.active=false
--Terminate the timer.
self:T(FOX.lid..string.format("Terminating missile track timer."))
return nil
end -- _status check
end -- end function trackBomb
-- Weapon is not yet "alife" just yet. Start timer with a little delay.
self:T(FOX.lid..string.format("Tracking of missile starts in 0.0001 seconds."))
timer.scheduleFunction(trackMissile, missile.weapon, timer.getTime()+0.0001)
--timer.scheduleFunction(trackMissile, missile.weapon, timer.getTime()+0.0001)
missile.Weapon:StartTrack(0.0001)
end
@@ -1114,6 +1127,13 @@ end
-- Event Functions
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- FOX event handler for event birth.
-- @param #FOX self
-- @param Core.Event#EVENTDATA EventData
function FOX:OnEventPlayerEnterAircraft(EventData)
end
--- FOX event handler for event birth.
-- @param #FOX self
-- @param Core.Event#EVENTDATA EventData
@@ -1155,7 +1175,7 @@ function FOX:OnEventBirth(EventData)
-- Add F10 radio menu for player.
if not self.menudisabled then
SCHEDULER:New(nil, self._AddF10Commands, {self,_unitName}, 0.1)
self:ScheduleOnce(0.1, self._AddF10Commands, self, _unitName)
end
-- Player data.
@@ -1230,30 +1250,29 @@ end
-- @param Core.Event#EVENTDATA EventData
function FOX:OnEventShot(EventData)
self:T2({eventshot=EventData})
-- Nil checks.
if EventData.Weapon==nil or EventData.IniDCSUnit==nil or EventData.weapon==nil then
return
end
if EventData.Weapon==nil then
return
end
if EventData.IniDCSUnit==nil then
return
end
-- Create a weapon object.
local weapon=WEAPON:New(EventData.weapon)
-- Weapon data.
local _weapon = EventData.WeaponName
local _weapon = weapon:GetTypeName()
local _target = EventData.Weapon:getTarget()
local _targetName = "unknown"
local _targetUnit = nil --Wrapper.Unit#UNIT
-- Weapon descriptor.
local desc=EventData.Weapon:getDesc()
local desc=weapon.desc
self:T2({desc=desc})
-- Weapon category: 0=Shell, 1=Missile, 2=Rocket, 3=BOMB
local weaponcategory=desc.category
-- Missile category: 1=AAM, 2=SAM, 6=OTHER
local missilecategory=desc.missileCategory
-- Missile range.
local missilerange=nil
if missilecategory then
missilerange=desc.rangeMaxAltMax
@@ -1263,8 +1282,8 @@ function FOX:OnEventShot(EventData)
self:T2(FOX.lid.."EVENT SHOT: FOX")
self:T2(FOX.lid..string.format("EVENT SHOT: Ini unit = %s", tostring(EventData.IniUnitName)))
self:T2(FOX.lid..string.format("EVENT SHOT: Ini group = %s", tostring(EventData.IniGroupName)))
self:T2(FOX.lid..string.format("EVENT SHOT: Weapon type = %s", tostring(_weapon)))
self:T2(FOX.lid..string.format("EVENT SHOT: Weapon categ = %s", tostring(weaponcategory)))
self:T2(FOX.lid..string.format("EVENT SHOT: Weapon type = %s", tostring(weapon:GetTypeName())))
self:T2(FOX.lid..string.format("EVENT SHOT: Weapon categ = %s", tostring(weapon:GetCategory())))
self:T2(FOX.lid..string.format("EVENT SHOT: Missil categ = %s", tostring(missilecategory)))
self:T2(FOX.lid..string.format("EVENT SHOT: Missil range = %s", tostring(missilerange)))
@@ -1276,7 +1295,7 @@ function FOX:OnEventShot(EventData)
end
-- Track missiles of type AAM=1, SAM=2 or OTHER=6
local _track = weaponcategory==1 and missilecategory and (missilecategory==1 or missilecategory==2 or missilecategory==6)
local _track = weapon:IsMissile() and missilecategory and (missilecategory==1 or missilecategory==2 or missilecategory==6)
-- Only track missiles
if _track then
@@ -1285,6 +1304,7 @@ function FOX:OnEventShot(EventData)
missile.active=true
missile.weapon=EventData.weapon
missile.Weapon=weapon
missile.missileType=_weapon
missile.missileRange=missilerange
missile.missileName=EventData.weapon:getName()
@@ -1297,6 +1317,7 @@ function FOX:OnEventShot(EventData)
missile.fuseDist=desc.fuseDist
missile.explosive=desc.warhead.explosiveMass or desc.warhead.shapedExplosiveMass
missile.targetOrig=missile.targetName
missile.missileCoord=COORDINATE:New(0,0,0)
-- Set missile target name, unit and player.
self:GetMissileTarget(missile)
@@ -1422,10 +1443,10 @@ function FOX:_AddF10Commands(_unitName)
end
else
self:E(self.lid..string.format("ERROR: Could not find group or group ID in AddF10Menu() function. Unit name: %s.", _unitName))
self:E(self.lid..string.format("ERROR: Could not find group or group ID in AddF10Menu() function. Unit name: %s.", _unitName or "unknown"))
end
else
self:E(self.lid..string.format("ERROR: Player unit does not exist in AddF10Menu() function. Unit name: %s.", _unitName))
self:E(self.lid..string.format("ERROR: Player unit does not exist in AddF10Menu() function. Unit name: %s.", _unitName or "unknown"))
end
end
@@ -1615,7 +1636,7 @@ end
--- Check if a coordinate lies within a safe training zone.
-- @param #FOX self
-- @param Core.Point#COORDINATE coord Coordinate to check.
-- @param Core.Point#COORDINATE coord Coordinate to check. Can also be a DCS#Vec3.
-- @return #boolean True if safe.
function FOX:_CheckCoordSafe(coord)
@@ -1627,7 +1648,9 @@ function FOX:_CheckCoordSafe(coord)
-- Loop over all zones.
for _,_zone in pairs(self.safezones) do
local zone=_zone --Core.Zone#ZONE
local inzone=zone:IsCoordinateInZone(coord)
local Vec2={x=coord.x, y=coord.z}
local inzone=zone:IsVec2InZone(Vec2)
--local inzone=zone:IsCoordinateInZone(coord)
if inzone then
return true
end
@@ -1638,7 +1661,7 @@ end
--- Check if a coordinate lies within a launch zone.
-- @param #FOX self
-- @param Core.Point#COORDINATE coord Coordinate to check.
-- @param Core.Point#COORDINATE coord Coordinate to check. Can also be a DCS#Vec2.
-- @return #boolean True if in launch zone.
function FOX:_CheckCoordLaunch(coord)
@@ -1650,7 +1673,9 @@ function FOX:_CheckCoordLaunch(coord)
-- Loop over all zones.
for _,_zone in pairs(self.launchzones) do
local zone=_zone --Core.Zone#ZONE
local inzone=zone:IsCoordinateInZone(coord)
local Vec2={x=coord.x, y=coord.z}
local inzone=zone:IsVec2InZone(Vec2)
--local inzone=zone:IsCoordinateInZone(coord)
if inzone then
return true
end
File diff suppressed because it is too large Load Diff
@@ -1,41 +1,41 @@
--- **Functional** -- Train missile defence and deflection.
--
--- **Functional** - Train missile defence and deflection.
--
-- ===
--
-- ## Features:
--
--
-- * Track the missiles fired at you and other players, providing bearing and range information of the missiles towards the airplanes.
-- * Provide alerts of missile launches, including detailed information of the units launching, including bearing, range °
-- * Provide alerts of missile launches, including detailed information of the units launching, including bearing, range
-- * Provide alerts when a missile would have killed your aircraft.
-- * Provide alerts when the missile self destructs.
-- * Enable / Disable and Configure the Missile Trainer using the various menu options.
--
--
-- ===
--
--
-- ## Missions:
--
--
-- [MIT - Missile Trainer](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/MIT%20-%20Missile%20Trainer)
--
--
-- ===
--
--
-- Uses the MOOSE messaging system to be alerted of any missiles fired, and when a missile would hit your aircraft,
-- the class will destroy the missile within a certain range, to avoid damage to your aircraft.
--
--
-- When running a mission where the missile trainer is used, the following radio menu structure ( 'Radio Menu' -> 'Other (F10)' -> 'MissileTrainer' ) options are available for the players:
--
--
-- * **Messages**: Menu to configure all messages.
-- * **Messages On**: Show all messages.
-- * **Messages Off**: Disable all messages.
-- * **Tracking**: Menu to configure missile tracking messages.
-- * **To All**: Shows missile tracking messages to all players.
-- * **To Target**: Shows missile tracking messages only to the player where the missile is targetted at.
-- * **To Target**: Shows missile tracking messages only to the player where the missile is targeted at.
-- * **Tracking On**: Show missile tracking messages.
-- * **Tracking Off**: Disable missile tracking messages.
-- * **Frequency Increase**: Increases the missile tracking message frequency with one second.
-- * **Frequency Decrease**: Decreases the missile tracking message frequency with one second.
-- * **Alerts**: Menu to configure alert messages.
-- * **To All**: Shows alert messages to all players.
-- * **To Target**: Shows alert messages only to the player where the missile is (was) targetted at.
-- * **To Target**: Shows alert messages only to the player where the missile is (was) targeted at.
-- * **Hits On**: Show missile hit alert messages.
-- * **Hits Off**: Disable missile hit alert messages.
-- * **Launches On**: Show missile launch messages.
@@ -45,23 +45,23 @@
-- * **Range Off**: Disable range information when a missile is fired to a target.
-- * **Bearing On**: Shows bearing information when a missile is fired to a target.
-- * **Bearing Off**: Disable bearing information when a missile is fired to a target.
-- * **Distance**: Menu to configure the distance when a missile needs to be destroyed when near to a player, during tracking. This will improve/influence hit calculation accuracy, but has the risk of damaging the aircraft when the missile reaches the aircraft before the distance is measured.
-- * **Distance**: Menu to configure the distance when a missile needs to be destroyed when near to a player, during tracking. This will improve/influence hit calculation accuracy, but has the risk of damaging the aircraft when the missile reaches the aircraft before the distance is measured.
-- * **50 meter**: Destroys the missile when the distance to the aircraft is below or equal to 50 meter.
-- * **100 meter**: Destroys the missile when the distance to the aircraft is below or equal to 100 meter.
-- * **150 meter**: Destroys the missile when the distance to the aircraft is below or equal to 150 meter.
-- * **200 meter**: Destroys the missile when the distance to the aircraft is below or equal to 200 meter.
--
--
-- ===
--
--
-- ### Authors: **FlightControl**
--
--
-- ### Contributions:
--
-- * **Stuka (Danny)**: Who you can search on the Eagle Dynamics Forums. Working together with Danny has resulted in the MISSILETRAINER class.
-- Danny has shared his ideas and together we made a design.
--
-- * **Stuka (Danny)**: Who you can search on the Eagle Dynamics Forums. Working together with Danny has resulted in the MISSILETRAINER class.
-- Danny has shared his ideas and together we made a design.
-- Together with the **476 virtual team**, we tested the MISSILETRAINER class, and got much positive feedback!
-- * **132nd Squadron**: Testing and optimizing the logic.
--
--
-- ===
--
-- @module Functional.MissileTrainer
@@ -76,7 +76,7 @@
---
--
-- # Constructor:
--
--
-- Create a new MISSILETRAINER object with the @{#MISSILETRAINER.New} method:
--
-- * @{#MISSILETRAINER.New}: Creates a new MISSILETRAINER object taking the maximum distance to your aircraft to evaluate when a missile needs to be destroyed.
@@ -84,11 +84,11 @@
-- MISSILETRAINER will collect each unit declared in the mission with a skill level "Client" and "Player", and will monitor the missiles shot at those.
--
-- # Initialization:
--
--
-- A MISSILETRAINER object will behave differently based on the usage of initialization methods:
--
-- * @{#MISSILETRAINER.InitMessagesOnOff}: Sets by default the display of any message to be ON or OFF.
-- * @{#MISSILETRAINER.InitTrackingToAll}: Sets by default the missile tracking report for all players or only for those missiles targetted to you.
-- * @{#MISSILETRAINER.InitTrackingToAll}: Sets by default the missile tracking report for all players or only for those missiles targeted to you.
-- * @{#MISSILETRAINER.InitTrackingOnOff}: Sets by default the display of missile tracking report to be ON or OFF.
-- * @{#MISSILETRAINER.InitTrackingFrequency}: Increases, decreases the missile tracking message display frequency with the provided time interval in seconds.
-- * @{#MISSILETRAINER.InitAlertsToAll}: Sets by default the display of alerts to be shown to all players or only to you.
@@ -97,8 +97,8 @@
-- * @{#MISSILETRAINER.InitRangeOnOff}: Sets by default the display of range information of missiles ON of OFF.
-- * @{#MISSILETRAINER.InitBearingOnOff}: Sets by default the display of bearing information of missiles ON of OFF.
-- * @{#MISSILETRAINER.InitMenusOnOff}: Allows to configure the options through the radio menu.
--
-- @field #MISSILETRAINER
--
-- @field #MISSILETRAINER
MISSILETRAINER = {
ClassName = "MISSILETRAINER",
TrackingMissiles = {},
@@ -167,7 +167,7 @@ end
-- When a missile is fired a SCHEDULER is set off that follows the missile. When near a certain a client player, the missile will be destroyed.
-- @param #MISSILETRAINER self
-- @param #number Distance The distance in meters when a tracked missile needs to be destroyed when close to a player.
-- @param #string Briefing (Optional) Will show a text to the players when starting their mission. Can be used for briefing purposes.
-- @param #string Briefing (Optional) Will show a text to the players when starting their mission. Can be used for briefing purposes.
-- @return #MISSILETRAINER
function MISSILETRAINER:New( Distance, Briefing )
local self = BASE:Inherit( self, BASE:New() )
@@ -194,8 +194,8 @@ function MISSILETRAINER:New( Distance, Briefing )
-- self:F( "ForEach:" .. Client.UnitName )
-- Client:Alive( self._Alive, self )
-- end
--
self.DBClients:ForEachClient(
--
self.DBClients:ForEachClient(
function( Client )
self:F( "ForEach:" .. Client.UnitName )
Client:Alive( self._Alive, self )
@@ -207,9 +207,9 @@ function MISSILETRAINER:New( Distance, Briefing )
-- self.DB:ForEachClient(
-- --- @param Wrapper.Client#CLIENT Client
-- function( Client )
--
--
-- ... actions ...
--
--
-- end
-- )
@@ -225,7 +225,7 @@ function MISSILETRAINER:New( Distance, Briefing )
self.DetailsRangeOnOff = true
self.DetailsBearingOnOff = true
self.MenusOnOff = true
self.TrackingMissiles = {}
@@ -256,7 +256,7 @@ function MISSILETRAINER:InitMessagesOnOff( MessagesOnOff )
return self
end
--- Sets by default the missile tracking report for all players or only for those missiles targetted to you.
--- Sets by default the missile tracking report for all players or only for those missiles targeted to you.
-- @param #MISSILETRAINER self
-- @param #boolean TrackingToAll true or false
-- @return #MISSILETRAINER self
@@ -293,7 +293,7 @@ end
--- Increases, decreases the missile tracking message display frequency with the provided time interval in seconds.
-- The default frequency is a 3 second interval, so the Tracking Frequency parameter specifies the increase or decrease from the default 3 seconds or the last frequency update.
-- @param #MISSILETRAINER self
-- @param #number TrackingFrequency Provide a negative or positive value in seconds to incraese or decrease the display frequency.
-- @param #number TrackingFrequency Provide a negative or positive value in seconds to incraese or decrease the display frequency.
-- @return #MISSILETRAINER self
function MISSILETRAINER:InitTrackingFrequency( TrackingFrequency )
self:F( TrackingFrequency )
@@ -478,30 +478,30 @@ function MISSILETRAINER:OnEventShot( EVentData )
if TrainerTargetDCSUnit then
local TrainerTargetDCSUnitName = Unit.getName( TrainerTargetDCSUnit )
local TrainerTargetSkill = _DATABASE.Templates.Units[TrainerTargetDCSUnitName].Template.skill
self:T(TrainerTargetDCSUnitName )
local Client = self.DBClients:FindClient( TrainerTargetDCSUnitName )
if Client then
local TrainerSourceUnit = UNIT:Find( TrainerSourceDCSUnit )
local TrainerTargetUnit = UNIT:Find( TrainerTargetDCSUnit )
if self.MessagesOnOff == true and self.AlertsLaunchesOnOff == true then
local Message = MESSAGE:New(
string.format( "%s launched a %s",
TrainerSourceUnit:GetTypeName(),
TrainerWeaponName
) .. self:_AddRange( Client, TrainerWeapon ) .. self:_AddBearing( Client, TrainerWeapon ), 5, "Launch Alert" )
if self.AlertsToAll then
Message:ToAll()
else
Message:ToClient( Client )
end
end
local ClientID = Client:GetID()
self:T( ClientID )
local MissileData = {}
@@ -579,52 +579,52 @@ function MISSILETRAINER:_TrackMissiles()
end
-- ALERTS PART
-- Loop for all Player Clients to check the alerts and deletion of missiles.
for ClientDataID, ClientData in pairs( self.TrackingMissiles ) do
local Client = ClientData.Client
if Client and Client:IsAlive() then
for MissileDataID, MissileData in pairs( ClientData.MissileData ) do
self:T3( MissileDataID )
local TrainerSourceUnit = MissileData.TrainerSourceUnit
local TrainerWeapon = MissileData.TrainerWeapon
local TrainerTargetUnit = MissileData.TrainerTargetUnit
local TrainerWeaponTypeName = MissileData.TrainerWeaponTypeName
local TrainerWeaponLaunched = MissileData.TrainerWeaponLaunched
if Client and Client:IsAlive() and TrainerSourceUnit and TrainerSourceUnit:IsAlive() and TrainerWeapon and TrainerWeapon:isExist() and TrainerTargetUnit and TrainerTargetUnit:IsAlive() then
local PositionMissile = TrainerWeapon:getPosition().p
local TargetVec3 = Client:GetVec3()
local Distance = ( ( PositionMissile.x - TargetVec3.x )^2 +
( PositionMissile.y - TargetVec3.y )^2 +
( PositionMissile.z - TargetVec3.z )^2
) ^ 0.5 / 1000
if Distance <= self.Distance then
-- Hit alert
TrainerWeapon:destroy()
if self.MessagesOnOff == true and self.AlertsHitsOnOff == true then
self:T( "killed" )
local Message = MESSAGE:New(
string.format( "%s launched by %s killed %s",
TrainerWeapon:getTypeName(),
TrainerSourceUnit:GetTypeName(),
TrainerTargetUnit:GetPlayerName()
), 15, "Hit Alert" )
if self.AlertsToAll == true then
Message:ToAll()
else
Message:ToClient( Client )
end
MissileData = nil
table.remove( ClientData.MissileData, MissileDataID )
self:T(ClientData.MissileData)
@@ -639,7 +639,7 @@ function MISSILETRAINER:_TrackMissiles()
TrainerWeaponTypeName,
TrainerSourceUnit:GetTypeName()
), 5, "Tracking" )
if self.AlertsToAll == true then
Message:ToAll()
else
@@ -660,41 +660,41 @@ function MISSILETRAINER:_TrackMissiles()
if ShowMessages == true and self.MessagesOnOff == true and self.TrackingOnOff == true then -- Only do this when tracking information needs to be displayed.
-- TRACKING PART
-- For the current client, the missile range and bearing details are displayed To the Player Client.
-- For the other clients, the missile range and bearing details are displayed To the other Player Clients.
-- To achieve this, a cross loop is done for each Player Client <-> Other Player Client missile information.
-- To achieve this, a cross loop is done for each Player Client <-> Other Player Client missile information.
-- Main Player Client loop
for ClientDataID, ClientData in pairs( self.TrackingMissiles ) do
local Client = ClientData.Client
--self:T2( { Client:GetName() } )
ClientData.MessageToClient = ""
ClientData.MessageToAll = ""
-- Other Players Client loop
for TrackingDataID, TrackingData in pairs( self.TrackingMissiles ) do
for MissileDataID, MissileData in pairs( TrackingData.MissileData ) do
--self:T3( MissileDataID )
local TrainerSourceUnit = MissileData.TrainerSourceUnit
local TrainerWeapon = MissileData.TrainerWeapon
local TrainerTargetUnit = MissileData.TrainerTargetUnit
local TrainerWeaponTypeName = MissileData.TrainerWeaponTypeName
local TrainerWeaponLaunched = MissileData.TrainerWeaponLaunched
if Client and Client:IsAlive() and TrainerSourceUnit and TrainerSourceUnit:IsAlive() and TrainerWeapon and TrainerWeapon:isExist() and TrainerTargetUnit and TrainerTargetUnit:IsAlive() then
if ShowMessages == true then
local TrackingTo
TrackingTo = string.format( " -> %s",
TrainerWeaponTypeName
)
if ClientDataID == TrackingDataID then
if ClientData.MessageToClient == "" then
ClientData.MessageToClient = "Missiles to You:\n"
@@ -712,7 +712,7 @@ function MISSILETRAINER:_TrackMissiles()
end
end
end
-- Once the Player Client and the Other Player Client tracking messages are prepared, show them.
if ClientData.MessageToClient ~= "" or ClientData.MessageToAll ~= "" then
local Message = MESSAGE:New( ClientData.MessageToClient .. ClientData.MessageToAll, 1, "Tracking" ):ToClient( Client )
+12 -12
View File
@@ -1,4 +1,4 @@
--- **Functional** -- Limit the movement of simulaneous moving ground vehicles.
--- **Functional** - Limit the movement of simulaneous moving ground vehicles.
--
-- ===
--
@@ -30,23 +30,23 @@ MOVEMENT = {
function MOVEMENT:New( MovePrefixes, MoveMaximum )
local self = BASE:Inherit( self, BASE:New() ) -- #MOVEMENT
self:F( { MovePrefixes, MoveMaximum } )
if type( MovePrefixes ) == 'table' then
self.MovePrefixes = MovePrefixes
else
self.MovePrefixes = { MovePrefixes }
end
self.MoveCount = 0 -- The internal counter of the amount of Moveing the has happened since MoveStart.
self.MoveMaximum = MoveMaximum -- Contains the Maximum amount of units that are allowed to move...
self.AliveUnits = 0 -- Contains the counter how many units are currently alive
self.MoveUnits = {} -- Reflects if the Moving for this MovePrefixes is going to be scheduled or not.
self.MoveCount = 0 -- The internal counter of the amount of Moving the has happened since MoveStart.
self.MoveMaximum = MoveMaximum -- Contains the Maximum amount of units that are allowed to move.
self.AliveUnits = 0 -- Contains the counter how many units are currently alive.
self.MoveUnits = {} -- Reflects if the Moving for this MovePrefixes is going to be scheduled or not.
self:HandleEvent( EVENTS.Birth )
-- self:AddEvent( world.event.S_EVENT_BIRTH, self.OnBirth )
--
-- self:EnableEvents()
self:ScheduleStart()
return self
@@ -67,7 +67,7 @@ function MOVEMENT:ScheduleStop()
end
--- Captures the birth events when new Units were spawned.
-- @todo This method should become obsolete. The new @{DATABASE} class will handle the collection administration.
-- @todo This method should become obsolete. The global _DATABASE object (an instance of @{Core.Database#DATABASE}) will handle the collection administration.
-- @param #MOVEMENT self
-- @param Core.Event#EVENTDATA self
function MOVEMENT:OnEventBirth( EventData )
@@ -86,14 +86,14 @@ function MOVEMENT:OnEventBirth( EventData )
end
end
end
EventData.IniUnit:HandleEvent( EVENTS.DEAD, self.OnDeadOrCrash )
end
end
--- Captures the Dead or Crash events when Units crash or are destroyed.
-- @todo This method should become obsolete. The new @{DATABASE} class will handle the collection administration.
-- @todo This method should become obsolete. The global _DATABASE object (an instance of @{Core.Database#DATABASE}) will handle the collection administration.
function MOVEMENT:OnDeadOrCrash( Event )
self:F( { Event } )
+69 -137
View File
@@ -1,4 +1,4 @@
--- **Functional** - Rudimentary ATC.
--- **Functional** - Basic ATC.
--
-- ![Banner Image](..\Presentations\PSEUDOATC\PSEUDOATC_Main.jpg)
--
@@ -26,9 +26,9 @@
--
-- ===
--
-- ### Author: **[funkyfranky](https://forums.eagle.ru/member.php?u=115026)**
-- ### Author: **funkyfranky**
--
-- ### Contributions: [FlightControl](https://forums.eagle.ru/member.php?u=89536)
-- ### Contributions: FlightControl, Applevangelist
--
-- ====
-- @module Functional.PseudoATC
@@ -44,7 +44,8 @@
-- @field #number mrefresh Interval in seconds after which the F10 menu is refreshed. E.g. by the closest airports. Default is 120 sec.
-- @field #number talt Interval in seconds between reporting altitude until touchdown. Default 3 sec.
-- @field #boolean chatty Display some messages on events like take-off and touchdown.
-- @field #boolean eventsmoose If true, events are handled by MOOSE. If false, events are handled directly by DCS eventhandler.
-- @field #boolean eventsmoose [Deprecated] If true, events are handled by MOOSE. If false, events are handled directly by DCS eventhandler.
-- @field #boolean reportplayername If true, use playername not callsign on callouts
-- @extends Core.Base#BASE
--- Adds some rudimentary ATC functionality via the radio menu.
@@ -88,6 +89,7 @@ PSEUDOATC={
talt=3,
chatty=true,
eventsmoose=true,
reportplayername = false,
}
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
@@ -98,13 +100,14 @@ PSEUDOATC.id="PseudoATC | "
--- PSEUDOATC version.
-- @field #number version
PSEUDOATC.version="0.9.2"
PSEUDOATC.version="0.10.5"
-----------------------------------------------------------------------------------------------------------------------------------------
-- TODO list
-- DONE: Add takeoff event.
-- DONE: Add user functions.
-- DONE: Refactor to use Moose event handling only
-----------------------------------------------------------------------------------------------------------------------------------------
@@ -129,23 +132,14 @@ function PSEUDOATC:Start()
self:F()
-- Debug info
self:E(PSEUDOATC.id.."Starting PseudoATC")
self:I(PSEUDOATC.id.."Starting PseudoATC")
-- Handle events.
if self.eventsmoose then
self:T(PSEUDOATC.id.."Events are handled by MOOSE.")
self:HandleEvent(EVENTS.Birth, self._OnBirth)
self:HandleEvent(EVENTS.Land, self._PlayerLanded)
self:HandleEvent(EVENTS.Takeoff, self._PlayerTakeOff)
self:HandleEvent(EVENTS.PlayerLeaveUnit, self._PlayerLeft)
self:HandleEvent(EVENTS.Crash, self._PlayerLeft)
--self:HandleEvent(EVENTS.Ejection, self._PlayerLeft)
--self:HandleEvent(EVENTS.PilotDead, self._PlayerLeft)
else
self:T(PSEUDOATC.id.."Events are handled by DCS.")
-- Events are handled directly by DCS.
world.addEventHandler(self)
end
self:HandleEvent(EVENTS.Birth, self._OnBirth)
self:HandleEvent(EVENTS.Land, self._PlayerLanded)
self:HandleEvent(EVENTS.Takeoff, self._PlayerTakeOff)
self:HandleEvent(EVENTS.PlayerLeaveUnit, self._PlayerLeft)
self:HandleEvent(EVENTS.Crash, self._PlayerLeft)
end
@@ -183,6 +177,13 @@ function PSEUDOATC:SetMessageDuration(duration)
self.mdur=duration or 30
end
--- Use player name, not call sign, in callouts
-- @param #PSEUDOATC self
function PSEUDOATC:SetReportPlayername()
self.reportplayername = true
return self
end
--- Set time interval after which the F10 radio menu is refreshed.
-- @param #PSEUDOATC self
-- @param #number interval Interval in seconds. Default is every 120 sec.
@@ -190,7 +191,7 @@ function PSEUDOATC:SetMenuRefresh(interval)
self.mrefresh=interval or 120
end
--- Enable/disable event handling by MOOSE or DCS.
--- [Deprecated] Enable/disable event handling by MOOSE or DCS.
-- @param #PSEUDOATC self
-- @param #boolean switch If true, events are handled by MOOSE (default). If false, events are handled directly by DCS.
function PSEUDOATC:SetEventsMoose(switch)
@@ -207,84 +208,6 @@ end
-----------------------------------------------------------------------------------------------------------------------------------------
-- Event Handling
--- Event handler for suppressed groups.
--@param #PSEUDOATC self
--@param #table Event Event data table. Holds event.id, event.initiator and event.target etc.
function PSEUDOATC:onEvent(Event)
if Event == nil or Event.initiator == nil or Unit.getByName(Event.initiator:getName()) == nil then
return true
end
local DCSiniunit = Event.initiator
local DCSplace = Event.place
local DCSsubplace = Event.subplace
local EventData={}
local _playerunit=nil
local _playername=nil
if Event.initiator then
EventData.IniUnitName = Event.initiator:getName()
EventData.IniDCSGroup = Event.initiator:getGroup()
EventData.IniGroupName = Event.initiator:getGroup():getName()
-- Get player unit and name. This returns nil,nil if the event was not fired by a player unit. And these are the only events we are interested in.
_playerunit, _playername = self:_GetPlayerUnitAndName(EventData.IniUnitName)
end
if Event.place then
EventData.Place=Event.place
EventData.PlaceName=Event.place:getName()
end
if Event.subplace then
EventData.SubPlace=Event.subplace
EventData.SubPlaceName=Event.subplace:getName()
end
-- Event info.
self:T3(PSEUDOATC.id..string.format("EVENT: Event in onEvent with ID = %s", tostring(Event.id)))
self:T3(PSEUDOATC.id..string.format("EVENT: Ini unit = %s" , tostring(EventData.IniUnitName)))
self:T3(PSEUDOATC.id..string.format("EVENT: Ini group = %s" , tostring(EventData.IniGroupName)))
self:T3(PSEUDOATC.id..string.format("EVENT: Ini player = %s" , tostring(_playername)))
self:T3(PSEUDOATC.id..string.format("EVENT: Place = %s" , tostring(EventData.PlaceName)))
self:T3(PSEUDOATC.id..string.format("EVENT: SubPlace = %s" , tostring(EventData.SubPlaceName)))
-- Event birth.
if Event.id == world.event.S_EVENT_BIRTH and _playername then
self:_OnBirth(EventData)
end
-- Event takeoff.
if Event.id == world.event.S_EVENT_TAKEOFF and _playername and EventData.Place then
self:_PlayerTakeOff(EventData)
end
-- Event land.
if Event.id == world.event.S_EVENT_LAND and _playername and EventData.Place then
self:_PlayerLanded(EventData)
end
-- Event player left unit
if Event.id == world.event.S_EVENT_PLAYER_LEAVE_UNIT and _playername then
self:_PlayerLeft(EventData)
end
-- Event crash ==> player left unit
if Event.id == world.event.S_EVENT_CRASH and _playername then
self:_PlayerLeft(EventData)
end
--[[
-- Event eject ==> player left unit
if Event.id == world.event.S_EVENT_EJECTION and _playername then
self:_PlayerLeft(EventData)
end
-- Event pilot dead ==> player left unit
if Event.id == world.event.S_EVENT_PILOT_DEAD and _playername then
self:_PlayerLeft(EventData)
end
]]
end
--- Function called my MOOSE event handler when a player enters a unit.
-- @param #PSEUDOATC self
@@ -294,7 +217,9 @@ function PSEUDOATC:_OnBirth(EventData)
-- Get unit and player.
local _unitName=EventData.IniUnitName
local _unit, _playername=self:_GetPlayerUnitAndName(_unitName)
--local _unit, _playername=self:_GetPlayerUnitAndName(_unitName)
local _unit = EventData.IniUnit
local _playername = EventData.IniPlayerName
-- Check if a player entered.
if _unit and _playername then
@@ -311,7 +236,10 @@ function PSEUDOATC:_PlayerLeft(EventData)
-- Get unit and player.
local _unitName=EventData.IniUnitName
local _unit, _playername=self:_GetPlayerUnitAndName(_unitName)
--local _unit, _playername=self:_GetPlayerUnitAndName(_unitName)
local _unit = EventData.IniUnit
local _playername = EventData.IniPlayerName
-- Check if a player left.
if _unit and _playername then
@@ -326,18 +254,16 @@ function PSEUDOATC:_PlayerLanded(EventData)
self:F({EventData=EventData})
-- Get unit, player and place.
local _unitName=EventData.IniUnitName
local _unit, _playername=self:_GetPlayerUnitAndName(_unitName)
local _unitName=EventData.IniUnitName
local _unit = EventData.IniUnit
local _playername = EventData.IniPlayerName
--local _unit, _playername=self:_GetPlayerUnitAndName(_unitName)
local _base=nil
local _baseName=nil
if EventData.place then
_base=EventData.place
_baseName=EventData.place:getName()
end
-- if EventData.subplace then
-- local _subPlace=EventData.subplace
-- local _subPlaceName=EventData.subplace:getName()
-- end
-- Call landed function.
if _unit and _playername and _base then
@@ -352,8 +278,10 @@ function PSEUDOATC:_PlayerTakeOff(EventData)
self:F({EventData=EventData})
-- Get unit, player and place.
local _unitName=EventData.IniUnitName
local _unit,_playername=self:_GetPlayerUnitAndName(_unitName)
local _unitName=EventData.IniUnitName
local _unit = EventData.IniUnit
local _playername = EventData.IniPlayerName
--local _unit,_playername=self:_GetPlayerUnitAndName(_unitName)
local _base=nil
local _baseName=nil
if EventData.place then
@@ -441,14 +369,15 @@ function PSEUDOATC:PlayerLanded(unit, place)
local group=unit:GetGroup()
local GID=group:GetID()
local UID=unit:GetDCSObject():getID()
local PlayerName=self.group[GID].player[UID].playername
local UnitName=self.group[GID].player[UID].unitname
local GroupName=self.group[GID].player[UID].groupname
-- Debug message.
local text=string.format("Player %s in unit %s of group %s (id=%d) landed at %s.", PlayerName, UnitName, GroupName, GID, place)
self:T(PSEUDOATC.id..text)
MESSAGE:New(text, 30):ToAllIf(self.Debug)
local PlayerName = unit:GetPlayerName() or "Ghost"
local UnitName = unit:GetName() or "Ghostplane"
local GroupName = group:GetName() or "Ghostgroup"
if self.Debug then
-- Debug message.
local text=string.format("Player %s in unit %s of group %s landed at %s.", PlayerName, UnitName, GroupName, place)
self:T(PSEUDOATC.id..text)
MESSAGE:New(text, 30):ToAllIf(self.Debug)
end
-- Stop altitude reporting timer if its activated.
self:AltitudeTimerStop(GID,UID)
@@ -470,21 +399,22 @@ function PSEUDOATC:PlayerTakeOff(unit, place)
-- Gather some information.
local group=unit:GetGroup()
local GID=group:GetID()
local UID=unit:GetDCSObject():getID()
local PlayerName=self.group[GID].player[UID].playername
local CallSign=self.group[GID].player[UID].callsign
local UnitName=self.group[GID].player[UID].unitname
local GroupName=self.group[GID].player[UID].groupname
-- Debug message.
local text=string.format("Player %s in unit %s of group %s (id=%d) took off at %s.", PlayerName, UnitName, GroupName, GID, place)
self:T(PSEUDOATC.id..text)
MESSAGE:New(text, 30):ToAllIf(self.Debug)
local PlayerName = unit:GetPlayerName() or "Ghost"
local UnitName = unit:GetName() or "Ghostplane"
local GroupName = group:GetName() or "Ghostgroup"
local CallSign = unit:GetCallsign() or "Ghost11"
if self.Debug then
-- Debug message.
local text=string.format("Player %s in unit %s of group %s took off at %s.", PlayerName, UnitName, GroupName, place)
self:T(PSEUDOATC.id..text)
MESSAGE:New(text, 30):ToAllIf(self.Debug)
end
-- Bye-Bye message.
if place and self.chatty then
local text=string.format("%s, %s, you are airborne. Have a safe trip!", place, CallSign)
if self.reportplayername then
text=string.format("%s, %s, you are airborne. Have a safe trip!", place, PlayerName)
end
MESSAGE:New(text, self.mdur):ToGroup(group)
end
@@ -501,7 +431,7 @@ function PSEUDOATC:PlayerLeft(unit)
local GID=group:GetID()
local UID=unit:GetDCSObject():getID()
if self.group[GID].player[UID] then
if self.group[GID] and self.group[GID].player and self.group[GID].player[UID] then
local PlayerName=self.group[GID].player[UID].playername
local CallSign=self.group[GID].player[UID].callsign
local UnitName=self.group[GID].player[UID].unitname
@@ -687,7 +617,9 @@ function PSEUDOATC:MenuWaypoints(GID, UID)
-- Position of Waypoint
local pos=COORDINATE:New(wp.x, wp.alt, wp.y)
local name=string.format("Waypoint %d", i-1)
if wp.name and wp.name ~= "" then
name = string.format("Waypoint %s",wp.name)
end
-- "F10/PseudoATC/Waypoints/Waypoint X"
local submenu=missionCommands.addSubMenuForGroup(GID, name, self.group[GID].player[UID].menu_waypoints)
@@ -844,7 +776,8 @@ function PSEUDOATC:ReportHeight(GID, UID, dt, _clear)
local position=unit:GetCoordinate()
local height=get_AGL(position)
local callsign=unit:GetCallsign()
local PlayerName=self.group[GID].player[UID].playername
-- Settings.
local settings=_DATABASE:GetPlayerSettings(self.group[GID].player[UID].playername) or _SETTINGS --Core.Settings#SETTINGS
@@ -856,7 +789,9 @@ function PSEUDOATC:ReportHeight(GID, UID, dt, _clear)
-- Message text.
local _text=string.format("%s, your altitude is %s AGL.", callsign, Hs)
if self.reportplayername then
_text=string.format("%s, your altitude is %s AGL.", PlayerName, Hs)
end
-- Append flight level.
if _clear==false then
_text=_text..string.format(" FL%03d.", position.y/30.48)
@@ -901,7 +836,7 @@ function PSEUDOATC:AltitudeTimeStart(GID, UID)
self:T(PSEUDOATC.id..string.format("Starting altitude report timer for player ID %d.", UID))
-- Start timer. Altitude is reported every ~3 seconds.
self.group[GID].player[UID].altimer, self.group[GID].player[UID].altimerid=SCHEDULER:New(nil, self.ReportHeight, {self, GID, UID, 0.1, true}, 1, 3)
self.group[GID].player[UID].altimer, self.group[GID].player[UID].altimerid=SCHEDULER:New(nil, self.ReportHeight, {self, GID, UID, 1, true}, 1, 3)
end
--- Stop/destroy DCS scheduler function for reporting altitude.
@@ -1044,6 +979,3 @@ function PSEUDOATC:_myname(unitname)
return string.format("%s (%s)", csign, pname)
end
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+150 -97
View File
@@ -1,4 +1,4 @@
--- **Functional** - Administer the scoring of player achievements, and create a CSV file logging the scoring events for use at team or squadron websites.
--- **Functional** - Administer the scoring of player achievements, file and log the scoring events for use at websites.
--
-- ===
--
@@ -12,7 +12,7 @@
-- * Score the hits and destroys of units.
-- * Score the hits and destroys of statics.
-- * Score the hits and destroys of scenery.
-- * Log scores into a CSV file.
-- * (optional) Log scores into a CSV file.
-- * Connect to a remote server using JSON and IP.
--
-- ===
@@ -59,7 +59,7 @@
--
-- ![Banner Image](..\Presentations\SCORING\Dia9.JPG)
--
-- Various @{Zone}s can be defined for which scores are also granted when objects in that @{Zone} are destroyed.
-- Various @{Core.Zone}s can be defined for which scores are also granted when objects in that @{Core.Zone} are destroyed.
-- This is **specifically useful** to designate **scenery targets on the map** that will generate points when destroyed.
--
-- With a small change in MissionScripting.lua, the scoring results can also be logged in a **CSV file**.
@@ -115,7 +115,7 @@
--
-- Special targets can be set that will give extra scores to the players when these are destroyed.
-- Use the methods @{#SCORING.AddUnitScore}() and @{#SCORING.RemoveUnitScore}() to specify a special additional score for a specific @{Wrapper.Unit}s.
-- Use the methods @{#SCORING.AddStaticScore}() and @{#SCORING.RemoveStaticScore}() to specify a special additional score for a specific @{Static}s.
-- Use the methods @{#SCORING.AddStaticScore}() and @{#SCORING.RemoveStaticScore}() to specify a special additional score for a specific @{Wrapper.Static}s.
-- Use the method @{#SCORING.SetGroupGroup}() to specify a special additional score for a specific @{Wrapper.Group}s.
--
-- local Scoring = SCORING:New( "Scoring File" )
@@ -131,11 +131,11 @@
-- # Define destruction zones that will give extra scores:
--
-- Define zones of destruction. Any object destroyed within the zone of the given category will give extra points.
-- Use the method @{#SCORING.AddZoneScore}() to add a @{Zone} for additional scoring.
-- Use the method @{#SCORING.RemoveZoneScore}() to remove a @{Zone} for additional scoring.
-- There are interesting variations that can be achieved with this functionality. For example, if the @{Zone} is a @{Core.Zone#ZONE_UNIT},
-- then the zone is a moving zone, and anything destroyed within that @{Zone} will generate points.
-- The other implementation could be to designate a scenery target (a building) in the mission editor surrounded by a @{Zone},
-- Use the method @{#SCORING.AddZoneScore}() to add a @{Core.Zone} for additional scoring.
-- Use the method @{#SCORING.RemoveZoneScore}() to remove a @{Core.Zone} for additional scoring.
-- There are interesting variations that can be achieved with this functionality. For example, if the @{Core.Zone} is a @{Core.Zone#ZONE_UNIT},
-- then the zone is a moving zone, and anything destroyed within that @{Core.Zone} will generate points.
-- The other implementation could be to designate a scenery target (a building) in the mission editor surrounded by a @{Core.Zone},
-- just large enough around that building.
--
-- # Add extra Goal scores upon an event or a condition:
@@ -225,6 +225,7 @@ SCORING = {
ClassName = "SCORING",
ClassID = 0,
Players = {},
AutoSave = true,
}
local _SCORINGCoalition = {
@@ -280,11 +281,11 @@ function SCORING:New( GameName )
-- Default fratricide penalty level (maximum penalty that can be assigned to a player before he gets kicked).
self:SetFratricide( self.ScaleDestroyPenalty * 3 )
self.penaltyonfratricide = true
-- Default penalty when a player changes coalition.
self:SetCoalitionChangePenalty( self.ScaleDestroyPenalty )
self.penaltyoncoalitionchange = true
self:SetDisplayMessagePrefix()
-- Event handlers
@@ -306,6 +307,7 @@ function SCORING:New( GameName )
end )
-- Create the CSV file.
self.AutoSave = true
self:OpenCSV( GameName )
return self
@@ -373,11 +375,11 @@ function SCORING:RemoveUnitScore( ScoreUnit )
return self
end
--- Add a @{Static} for additional scoring when the @{Static} is destroyed.
-- Note that if there was already a @{Static} declared within the scoring with the same name,
-- then the old @{Static} will be replaced with the new @{Static}.
--- Add a @{Wrapper.Static} for additional scoring when the @{Wrapper.Static} is destroyed.
-- Note that if there was already a @{Wrapper.Static} declared within the scoring with the same name,
-- then the old @{Wrapper.Static} will be replaced with the new @{Wrapper.Static}.
-- @param #SCORING self
-- @param Wrapper.Static#UNIT ScoreStatic The @{Static} for which the Score needs to be given.
-- @param Wrapper.Static#UNIT ScoreStatic The @{Wrapper.Static} for which the Score needs to be given.
-- @param #number Score The Score value.
-- @return #SCORING
function SCORING:AddStaticScore( ScoreStatic, Score )
@@ -389,9 +391,9 @@ function SCORING:AddStaticScore( ScoreStatic, Score )
return self
end
--- Removes a @{Static} for additional scoring when the @{Static} is destroyed.
--- Removes a @{Wrapper.Static} for additional scoring when the @{Wrapper.Static} is destroyed.
-- @param #SCORING self
-- @param Wrapper.Static#UNIT ScoreStatic The @{Static} for which the Score needs to be given.
-- @param Wrapper.Static#UNIT ScoreStatic The @{Wrapper.Static} for which the Score needs to be given.
-- @return #SCORING
function SCORING:RemoveStaticScore( ScoreStatic )
@@ -419,11 +421,11 @@ function SCORING:AddScoreGroup( ScoreGroup, Score )
return self
end
--- Add a @{Zone} to define additional scoring when any object is destroyed in that zone.
-- Note that if a @{Zone} with the same name is already within the scoring added, the @{Zone} (type) and Score will be replaced!
--- Add a @{Core.Zone} to define additional scoring when any object is destroyed in that zone.
-- Note that if a @{Core.Zone} with the same name is already within the scoring added, the @{Core.Zone} (type) and Score will be replaced!
-- This allows for a dynamic destruction zone evolution within your mission.
-- @param #SCORING self
-- @param Core.Zone#ZONE_BASE ScoreZone The @{Zone} which defines the destruction score perimeters.
-- @param Core.Zone#ZONE_BASE ScoreZone The @{Core.Zone} which defines the destruction score perimeters.
-- Note that a zone can be a polygon or a moving zone.
-- @param #number Score The Score value.
-- @return #SCORING
@@ -438,11 +440,11 @@ function SCORING:AddZoneScore( ScoreZone, Score )
return self
end
--- Remove a @{Zone} for additional scoring.
-- The scoring will search if any @{Zone} is added with the given name, and will remove that zone from the scoring.
--- Remove a @{Core.Zone} for additional scoring.
-- The scoring will search if any @{Core.Zone} is added with the given name, and will remove that zone from the scoring.
-- This allows for a dynamic destruction zone evolution within your mission.
-- @param #SCORING self
-- @param Core.Zone#ZONE_BASE ScoreZone The @{Zone} which defines the destruction score perimeters.
-- @param Core.Zone#ZONE_BASE ScoreZone The @{Core.Zone} which defines the destruction score perimeters.
-- Note that a zone can be a polygon or a moving zone.
-- @return #SCORING
function SCORING:RemoveZoneScore( ScoreZone )
@@ -656,11 +658,12 @@ function SCORING:_AddPlayerFromUnit( UnitData )
if self.Players[PlayerName].UnitCoalition ~= UnitCoalition and self.penaltyoncoalitionchange then
self.Players[PlayerName].Penalty = self.Players[PlayerName].Penalty + self.CoalitionChangePenalty or 50
self.Players[PlayerName].PenaltyCoalition = self.Players[PlayerName].PenaltyCoalition + 1
MESSAGE:NewType( self.DisplayMessagePrefix .. "Player '" .. PlayerName .. "' changed coalition from " .. _SCORINGCoalition[self.Players[PlayerName].UnitCoalition] .. " to " .. _SCORINGCoalition[UnitCoalition] .. "(changed " .. self.Players[PlayerName].PenaltyCoalition .. " times the coalition). " ..
self.CoalitionChangePenalty .. "Penalty points added.",
MESSAGE.Type.Information )
:ToAll()
self:ScoreCSV( PlayerName, "", "COALITION_PENALTY", 1, -1 * self.CoalitionChangePenalty, self.Players[PlayerName].UnitName, _SCORINGCoalition[self.Players[PlayerName].UnitCoalition], _SCORINGCategory[self.Players[PlayerName].UnitCategory], self.Players[PlayerName].UnitType, UnitName, _SCORINGCoalition[UnitCoalition], _SCORINGCategory[UnitCategory], UnitData:GetTypeName() )
MESSAGE:NewType( self.DisplayMessagePrefix .. "Player '" .. PlayerName .. "' changed coalition from " .. _SCORINGCoalition[self.Players[PlayerName].UnitCoalition] .. " to " .. _SCORINGCoalition[UnitCoalition] ..
"(changed " .. self.Players[PlayerName].PenaltyCoalition .. " times the coalition). ".. self.CoalitionChangePenalty .."Penalty points added.",
MESSAGE.Type.Information
):ToAll()
self:ScoreCSV( PlayerName, "", "COALITION_PENALTY", 1, -1*self.CoalitionChangePenalty, self.Players[PlayerName].UnitName, _SCORINGCoalition[self.Players[PlayerName].UnitCoalition], _SCORINGCategory[self.Players[PlayerName].UnitCategory], self.Players[PlayerName].UnitType,
UnitName, _SCORINGCoalition[UnitCoalition], _SCORINGCategory[UnitCategory], UnitData:GetTypeName() )
end
end
@@ -671,7 +674,7 @@ function SCORING:_AddPlayerFromUnit( UnitData )
self.Players[PlayerName].UNIT = UnitData
self.Players[PlayerName].ThreatLevel = UnitThreatLevel
self.Players[PlayerName].ThreatType = UnitThreatType
-- TODO: make fratricide switchable
if self.Players[PlayerName].Penalty > self.Fratricide * 0.50 and self.penaltyonfratricide then
if self.Players[PlayerName].PenaltyWarning < 1 then
@@ -712,11 +715,11 @@ function SCORING:AddGoalScorePlayer( PlayerName, GoalTag, Text, Score )
PlayerData.Goals[GoalTag] = PlayerData.Goals[GoalTag] or { Score = 0 }
PlayerData.Goals[GoalTag].Score = PlayerData.Goals[GoalTag].Score + Score
PlayerData.Score = PlayerData.Score + Score
MESSAGE:NewType( self.DisplayMessagePrefix .. Text,
MESSAGE.Type.Information )
:ToAll()
if Text then
MESSAGE:NewType( self.DisplayMessagePrefix .. Text,
MESSAGE.Type.Information )
:ToAll()
end
self:ScoreCSV( PlayerName, "", "GOAL_" .. string.upper( GoalTag ), 1, Score, nil )
end
end
@@ -735,7 +738,7 @@ function SCORING:AddGoalScore( PlayerUnit, GoalTag, Text, Score )
local PlayerName = PlayerUnit:GetPlayerName()
self:F( { PlayerUnit.UnitName, PlayerName, GoalTag, Text, Score } )
self:T2( { PlayerUnit.UnitName, PlayerName, GoalTag, Text, Score } )
-- PlayerName can be nil, if the Unit with the player crashed or due to another reason.
if PlayerName then
@@ -744,11 +747,12 @@ function SCORING:AddGoalScore( PlayerUnit, GoalTag, Text, Score )
PlayerData.Goals[GoalTag] = PlayerData.Goals[GoalTag] or { Score = 0 }
PlayerData.Goals[GoalTag].Score = PlayerData.Goals[GoalTag].Score + Score
PlayerData.Score = PlayerData.Score + Score
MESSAGE:NewType( self.DisplayMessagePrefix .. Text,
if Text then
MESSAGE:NewType( self.DisplayMessagePrefix .. Text,
MESSAGE.Type.Information )
:ToAll()
end
self:ScoreCSV( PlayerName, "", "GOAL_" .. string.upper( GoalTag ), 1, Score, PlayerUnit:GetName() )
end
end
@@ -781,11 +785,12 @@ function SCORING:_AddMissionTaskScore( Mission, PlayerUnit, Text, Score )
PlayerData.Score = self.Players[PlayerName].Score + Score
PlayerData.Mission[MissionName].ScoreTask = self.Players[PlayerName].Mission[MissionName].ScoreTask + Score
MESSAGE:NewType( self.DisplayMessagePrefix .. Mission:GetText() .. " : " .. Text .. " Score: " .. Score,
MESSAGE.Type.Information )
:ToAll()
if Text then
MESSAGE:NewType( self.DisplayMessagePrefix .. Mission:GetText() .. " : " .. Text .. " Score: " .. Score,
MESSAGE.Type.Information )
:ToAll()
end
self:ScoreCSV( PlayerName, "", "TASK_" .. MissionName:gsub( ' ', '_' ), 1, Score, PlayerUnit:GetName() )
end
end
@@ -817,9 +822,11 @@ function SCORING:_AddMissionGoalScore( Mission, PlayerName, Text, Score )
PlayerData.Score = self.Players[PlayerName].Score + Score
PlayerData.Mission[MissionName].ScoreTask = self.Players[PlayerName].Mission[MissionName].ScoreTask + Score
MESSAGE:NewType( string.format( "%s%s: %s! Player %s receives %d score!", self.DisplayMessagePrefix, Mission:GetText(), Text, PlayerName, Score ), MESSAGE.Type.Information ):ToAll()
if Text then
MESSAGE:NewType( string.format( "%s%s: %s! Player %s receives %d score!", self.DisplayMessagePrefix, Mission:GetText(), Text, PlayerName, Score ), MESSAGE.Type.Information ):ToAll()
end
self:ScoreCSV( PlayerName, "", "TASK_" .. MissionName:gsub( ' ', '_' ), 1, Score )
end
end
@@ -844,11 +851,12 @@ function SCORING:_AddMissionScore( Mission, Text, Score )
PlayerData.Score = PlayerData.Score + Score
PlayerData.Mission[MissionName].ScoreMission = PlayerData.Mission[MissionName].ScoreMission + Score
MESSAGE:NewType( self.DisplayMessagePrefix .. "Player '" .. PlayerName .. "' has " .. Text .. " in " .. Mission:GetText() .. ". " .. Score .. " mission score!",
if Text then
MESSAGE:NewType( self.DisplayMessagePrefix .. "Player '" .. PlayerName .. "' has " .. Text .. " in " .. Mission:GetText() .. ". " .. Score .. " mission score!",
MESSAGE.Type.Information )
:ToAll()
end
self:ScoreCSV( PlayerName, "", "MISSION_" .. MissionName:gsub( ' ', '_' ), 1, Score )
end
end
@@ -870,8 +878,10 @@ end
function SCORING:OnEventBirth( Event )
if Event.IniUnit then
Event.IniUnit.ThreatLevel, Event.IniUnit.ThreatType = Event.IniUnit:GetThreatLevel()
if Event.IniObjectCategory == 1 then
local PlayerName = Event.IniUnit:GetPlayerName()
Event.IniUnit.BirthTime = timer.getTime()
if PlayerName then
self:_AddPlayerFromUnit( Event.IniUnit )
self:SetScoringMenu( Event.IniGroup )
@@ -1002,7 +1012,18 @@ function SCORING:_EventOnHit( Event )
PlayerHit.PenaltyHit = PlayerHit.PenaltyHit or 0
PlayerHit.TimeStamp = PlayerHit.TimeStamp or 0
PlayerHit.UNIT = PlayerHit.UNIT or TargetUNIT
-- After an instant kill we can't compute the thread level anymore. To fix this we compute at OnEventBirth
if PlayerHit.UNIT.ThreatType == nil then
PlayerHit.ThreatLevel, PlayerHit.ThreatType = PlayerHit.UNIT:GetThreatLevel()
-- if this fails for some reason, set a good default value
if PlayerHit.ThreatType == nil then
PlayerHit.ThreatLevel = 1
PlayerHit.ThreatType = "Unknown"
end
else
PlayerHit.ThreatLevel = PlayerHit.UNIT.ThreatLevel
PlayerHit.ThreatType = PlayerHit.UNIT.ThreatType
end
-- Only grant hit scores if there was more than one second between the last hit.
if timer.getTime() - PlayerHit.TimeStamp > 1 then
@@ -1018,27 +1039,30 @@ function SCORING:_EventOnHit( Event )
if InitCoalition then -- A coalition object was hit.
if InitCoalition == TargetCoalition then
Player.Penalty = Player.Penalty + 10
PlayerHit.Penalty = PlayerHit.Penalty + 10
local Penalty = 10
Player.Penalty = Player.Penalty + Penalty
PlayerHit.Penalty = PlayerHit.Penalty + Penalty
PlayerHit.PenaltyHit = PlayerHit.PenaltyHit + 1
if TargetPlayerName ~= nil then -- It is a player hitting another player ...
MESSAGE:NewType( self.DisplayMessagePrefix .. "Player '" .. InitPlayerName .. "' hit friendly player '" .. TargetPlayerName .. "' " .. TargetUnitCategory .. " ( " .. TargetType .. " ) " .. PlayerHit.PenaltyHit .. " times. " ..
"Penalty: -" .. PlayerHit.Penalty .. ". Score Total:" .. Player.Score - Player.Penalty,
"Penalty: -" .. Penalty .. ". Score Total:" .. Player.Score - Player.Penalty,
MESSAGE.Type.Update )
:ToAllIf( self:IfMessagesHit() and self:IfMessagesToAll() )
:ToCoalitionIf( InitCoalition, self:IfMessagesHit() and self:IfMessagesToCoalition() )
else
MESSAGE:NewType( self.DisplayMessagePrefix .. "Player '" .. InitPlayerName .. "' hit friendly target " .. TargetUnitCategory .. " ( " .. TargetType .. " ) " .. PlayerHit.PenaltyHit .. " times. " ..
"Penalty: -" .. PlayerHit.Penalty .. ". Score Total:" .. Player.Score - Player.Penalty,
"Penalty: -" .. Penalty .. ". Score Total:" .. Player.Score - Player.Penalty,
MESSAGE.Type.Update )
:ToAllIf( self:IfMessagesHit() and self:IfMessagesToAll() )
:ToCoalitionIf( InitCoalition, self:IfMessagesHit() and self:IfMessagesToCoalition() )
end
self:ScoreCSV( InitPlayerName, TargetPlayerName, "HIT_PENALTY", 1, -10, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType )
else
Player.Score = Player.Score + 1
PlayerHit.Score = PlayerHit.Score + 1
-- Hitting a target multiple times before destoying it should not result in a higger score
-- Multiple hits is typically a results of bombs/missles missing their target but still inflict some spash damage
-- Player.Score = Player.Score + 1
-- PlayerHit.Score = PlayerHit.Score + 1
PlayerHit.ScoreHit = PlayerHit.ScoreHit + 1
if TargetPlayerName ~= nil then -- It is a player hitting another player ...
MESSAGE:NewType( self.DisplayMessagePrefix .. "Player '" .. InitPlayerName .. "' hit enemy player '" .. TargetPlayerName .. "' " .. TargetUnitCategory .. " ( " .. TargetType .. " ) " .. PlayerHit.ScoreHit .. " times. " ..
@@ -1101,7 +1125,18 @@ function SCORING:_EventOnHit( Event )
PlayerHit.PenaltyHit = PlayerHit.PenaltyHit or 0
PlayerHit.TimeStamp = PlayerHit.TimeStamp or 0
PlayerHit.UNIT = PlayerHit.UNIT or TargetUNIT
-- After an instant kill we can't compute the thread level anymore. To fix this we compute at OnEventBirth
if PlayerHit.UNIT.ThreatType == nil then
PlayerHit.ThreatLevel, PlayerHit.ThreatType = PlayerHit.UNIT:GetThreatLevel()
-- if this fails for some reason, set a good default value
if PlayerHit.ThreatType == nil then
PlayerHit.ThreatLevel = 1
PlayerHit.ThreatType = "Unknown"
end
else
PlayerHit.ThreatLevel = PlayerHit.UNIT.ThreatLevel
PlayerHit.ThreatType = PlayerHit.UNIT.ThreatType
end
-- Only grant hit scores if there was more than one second between the last hit.
if timer.getTime() - PlayerHit.TimeStamp > 1 then
@@ -1112,23 +1147,28 @@ function SCORING:_EventOnHit( Event )
if InitCoalition then -- A coalition object was hit, probably a static.
if InitCoalition == TargetCoalition then
-- TODO: Penalty according scale
Player.Penalty = Player.Penalty + 10 -- * self.ScaleDestroyPenalty
PlayerHit.Penalty = PlayerHit.Penalty + 10 -- * self.ScaleDestroyPenalty
local Penalty = 10
Player.Penalty = Player.Penalty + Penalty --* self.ScaleDestroyPenalty
PlayerHit.Penalty = PlayerHit.Penalty + Penalty --* self.ScaleDestroyPenalty
PlayerHit.PenaltyHit = PlayerHit.PenaltyHit + 1 * self.ScaleDestroyPenalty
MESSAGE:NewType( self.DisplayMessagePrefix .. "Player '" .. Event.WeaponPlayerName .. "' hit friendly target " .. TargetUnitCategory .. " ( " .. TargetType .. " ) " ..
"Penalty: -" .. PlayerHit.Penalty .. " = " .. Player.Score - Player.Penalty,
MESSAGE.Type.Update )
:ToAllIf( self:IfMessagesHit() and self:IfMessagesToAll() )
:ToCoalitionIf( Event.WeaponCoalition, self:IfMessagesHit() and self:IfMessagesToCoalition() )
MESSAGE
:NewType( self.DisplayMessagePrefix .. "Player '" .. Event.WeaponPlayerName .. "' hit friendly target " ..
TargetUnitCategory .. " ( " .. TargetType .. " ) " ..
"Penalty: -" .. Penalty .. " = " .. Player.Score - Player.Penalty,
MESSAGE.Type.Update
)
:ToAllIf( self:IfMessagesHit() and self:IfMessagesToAll() )
:ToCoalitionIf( Event.WeaponCoalition, self:IfMessagesHit() and self:IfMessagesToCoalition() )
self:ScoreCSV( Event.WeaponPlayerName, TargetPlayerName, "HIT_PENALTY", 1, -10, Event.WeaponName, Event.WeaponCoalition, Event.WeaponCategory, Event.WeaponTypeName, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType )
else
Player.Score = Player.Score + 1
PlayerHit.Score = PlayerHit.Score + 1
-- Hitting a target multiple times before destoying it should not result in a higger score
-- Multiple hits is typically a results of bombs/missles missing their target but still inflict some spash damage
-- Player.Score = Player.Score + 1
-- PlayerHit.Score = PlayerHit.Score + 1
PlayerHit.ScoreHit = PlayerHit.ScoreHit + 1
MESSAGE:NewType( self.DisplayMessagePrefix .. "Player '" .. Event.WeaponPlayerName .. "' hit enemy target " .. TargetUnitCategory .. " ( " .. TargetType .. " ) " ..
"Score: +" .. PlayerHit.Score .. " = " .. Player.Score - Player.Penalty,
"Score: " .. PlayerHit.Score .. ". Score Total:" .. Player.Score - Player.Penalty,
MESSAGE.Type.Update )
:ToAllIf( self:IfMessagesHit() and self:IfMessagesToAll() )
:ToCoalitionIf( Event.WeaponCoalition, self:IfMessagesHit() and self:IfMessagesToCoalition() )
@@ -1206,7 +1246,7 @@ function SCORING:_EventOnDeadOrCrash( Event )
local Destroyed = false
-- What is the player destroying?
if Player and Player.Hit and Player.Hit[TargetCategory] and Player.Hit[TargetCategory][TargetUnitName] and Player.Hit[TargetCategory][TargetUnitName].TimeStamp ~= 0 then -- Was there a hit for this unit for this player before registered???
if Player and Player.Hit and Player.Hit[TargetCategory] and Player.Hit[TargetCategory][TargetUnitName] and Player.Hit[TargetCategory][TargetUnitName].TimeStamp ~= 0 and (TargetUnit.BirthTime == nil or Player.Hit[TargetCategory][TargetUnitName].TimeStamp > TargetUnit.BirthTime) then -- Was there a hit for this unit for this player before registered???
local TargetThreatLevel = Player.Hit[TargetCategory][TargetUnitName].ThreatLevel
local TargetThreatType = Player.Hit[TargetCategory][TargetUnitName].ThreatType
@@ -1235,13 +1275,13 @@ function SCORING:_EventOnDeadOrCrash( Event )
if Player.HitPlayers[TargetPlayerName] then -- A player destroyed another player
MESSAGE:NewType( self.DisplayMessagePrefix .. "Player '" .. PlayerName .. "' destroyed friendly player '" .. TargetPlayerName .. "' " .. TargetUnitCategory .. " ( " .. ThreatTypeTarget .. " ) " ..
"Penalty: -" .. TargetDestroy.Penalty .. " = " .. Player.Score - Player.Penalty,
"Penalty: -" .. ThreatPenalty .. " = " .. Player.Score - Player.Penalty,
MESSAGE.Type.Information )
:ToAllIf( self:IfMessagesDestroy() and self:IfMessagesToAll() )
:ToCoalitionIf( InitCoalition, self:IfMessagesDestroy() and self:IfMessagesToCoalition() )
else
MESSAGE:NewType( self.DisplayMessagePrefix .. "Player '" .. PlayerName .. "' destroyed friendly target " .. TargetUnitCategory .. " ( " .. ThreatTypeTarget .. " ) " ..
"Penalty: -" .. TargetDestroy.Penalty .. " = " .. Player.Score - Player.Penalty,
"Penalty: -" .. ThreatPenalty .. " = " .. Player.Score - Player.Penalty,
MESSAGE.Type.Information )
:ToAllIf( self:IfMessagesDestroy() and self:IfMessagesToAll() )
:ToCoalitionIf( InitCoalition, self:IfMessagesDestroy() and self:IfMessagesToCoalition() )
@@ -1263,13 +1303,13 @@ function SCORING:_EventOnDeadOrCrash( Event )
TargetDestroy.ScoreDestroy = TargetDestroy.ScoreDestroy + 1
if Player.HitPlayers[TargetPlayerName] then -- A player destroyed another player
MESSAGE:NewType( self.DisplayMessagePrefix .. "Player '" .. PlayerName .. "' destroyed enemy player '" .. TargetPlayerName .. "' " .. TargetUnitCategory .. " ( " .. ThreatTypeTarget .. " ) " ..
"Score: +" .. TargetDestroy.Score .. " = " .. Player.Score - Player.Penalty,
"Score: +" .. ThreatScore .. " = " .. Player.Score - Player.Penalty,
MESSAGE.Type.Information )
:ToAllIf( self:IfMessagesDestroy() and self:IfMessagesToAll() )
:ToCoalitionIf( InitCoalition, self:IfMessagesDestroy() and self:IfMessagesToCoalition() )
else
MESSAGE:NewType( self.DisplayMessagePrefix .. "Player '" .. PlayerName .. "' destroyed enemy " .. TargetUnitCategory .. " ( " .. ThreatTypeTarget .. " ) " ..
"Score: +" .. TargetDestroy.Score .. " = " .. Player.Score - Player.Penalty,
"Score: +" .. ThreatScore .. " = " .. Player.Score - Player.Penalty,
MESSAGE.Type.Information )
:ToAllIf( self:IfMessagesDestroy() and self:IfMessagesToAll() )
:ToCoalitionIf( InitCoalition, self:IfMessagesDestroy() and self:IfMessagesToCoalition() )
@@ -1651,18 +1691,19 @@ function SCORING:ReportScoreGroupDetailed( PlayerGroup )
local PlayerScore = ScoreHits + ScoreDestroys + ScoreCoalitionChanges + ScoreGoals + ScoreMissions
local PlayerPenalty = PenaltyHits + PenaltyDestroys + PenaltyCoalitionChanges + PenaltyGoals + PenaltyMissions
PlayerMessage = string.format( "Player '%s' Score = %d ( %d Score, -%d Penalties )%s%s%s%s%s",
PlayerName,
PlayerScore - PlayerPenalty,
PlayerScore,
PlayerPenalty,
ReportHits,
ReportDestroys,
ReportCoalitionChanges,
ReportGoals,
ReportMissions
)
PlayerMessage =
string.format( "Player '%s' Score = %d ( %d Score, -%d Penalties )%s%s%s%s%s",
PlayerName,
PlayerScore - PlayerPenalty,
PlayerScore,
PlayerPenalty,
ReportHits,
ReportDestroys,
ReportCoalitionChanges,
ReportGoals,
ReportMissions
)
MESSAGE:NewType( PlayerMessage, MESSAGE.Type.Detailed ):ToGroup( PlayerGroup )
end
end
@@ -1706,13 +1747,14 @@ function SCORING:ReportScoreAllSummary( PlayerGroup )
local PlayerScore = ScoreHits + ScoreDestroys + ScoreCoalitionChanges + ScoreGoals + ScoreMissions
local PlayerPenalty = PenaltyHits + PenaltyDestroys + PenaltyCoalitionChanges + PenaltyGoals + PenaltyMissions
PlayerMessage = string.format( "Player '%s' Score = %d ( %d Score, -%d Penalties )",
PlayerName,
PlayerScore - PlayerPenalty,
PlayerScore,
PlayerPenalty
)
PlayerMessage =
string.format( "Player '%s' Score = %d ( %d Score, -%d Penalties )",
PlayerName,
PlayerScore - PlayerPenalty,
PlayerScore,
PlayerPenalty
)
MESSAGE:NewType( PlayerMessage, MESSAGE.Type.Overview ):ToGroup( PlayerGroup )
end
end
@@ -1725,9 +1767,9 @@ function SCORING:SecondsToClock( sSeconds )
-- return nil;
return "00:00:00";
else
nHours = string.format( "%02.f", math.floor( nSeconds / 3600 ) );
nMins = string.format( "%02.f", math.floor( nSeconds / 60 - (nHours * 60) ) );
nSecs = string.format( "%02.f", math.floor( nSeconds - nHours * 3600 - nMins * 60 ) );
local nHours = string.format( "%02.f", math.floor( nSeconds / 3600 ) );
local nMins = string.format( "%02.f", math.floor( nSeconds / 60 - (nHours * 60) ) );
local nSecs = string.format( "%02.f", math.floor( nSeconds - nHours * 3600 - nMins * 60 ) );
return nHours .. ":" .. nMins .. ":" .. nSecs
end
end
@@ -1743,7 +1785,7 @@ end
function SCORING:OpenCSV( ScoringCSV )
self:F( ScoringCSV )
if lfs and io and os then
if lfs and io and os and self.AutoSave then
if ScoringCSV then
self.ScoringCSV = ScoringCSV
local fdir = lfs.writedir() .. [[Logs\]] .. self.ScoringCSV .. " " .. os.date( "%Y-%m-%d %H-%M-%S" ) .. ".csv"
@@ -1823,7 +1865,7 @@ function SCORING:ScoreCSV( PlayerName, TargetPlayerName, ScoreType, ScoreTimes,
TargetUnitType = TargetUnitType or ""
TargetUnitName = TargetUnitName or ""
if lfs and io and os then
if lfs and io and os and self.AutoSave then
self.CSVFile:write(
'"' .. self.GameName .. '"' .. ',' ..
'"' .. self.RunTime .. '"' .. ',' ..
@@ -1847,9 +1889,20 @@ function SCORING:ScoreCSV( PlayerName, TargetPlayerName, ScoreType, ScoreTimes,
end
end
--- Close CSV file
-- @param #SCORING self
-- @return #SCORING self
function SCORING:CloseCSV()
if lfs and io and os then
if lfs and io and os and self.AutoSave then
self.CSVFile:close()
end
end
--- Registers a score for a player.
-- @param #SCORING self
-- @param #boolean OnOff Switch saving to CSV on = true or off = false
-- @return #SCORING self
function SCORING:SwitchAutoSave(OnOff)
self.AutoSave = OnOff
return self
end
+3 -1
View File
@@ -1,4 +1,4 @@
--- **Functional** -- Make SAM sites execute evasive and defensive behaviour when being fired upon.
--- **Functional** - Make SAM sites execute evasive and defensive behaviour when being fired upon.
--
-- ===
--
@@ -79,6 +79,7 @@ SEAD = {
["Kh25"] = "Kh25",
["BGM_109"] = "BGM_109",
["AGM_154"] = "AGM_154",
["HY-2"] = "HY-2",
}
--- Missile enumerators - from DCS ME and Wikipedia
@@ -98,6 +99,7 @@ SEAD = {
["Kh25"] = {25, 0.8},
["BGM_109"] = {460, 0.705}, --in-game ~465kn
["AGM_154"] = {130, 0.61},
["HY-2"] = {90,1},
}
--- Creates the main object which is handling defensive actions for SA sites or moving SA vehicles.
+135 -14
View File
@@ -1,9 +1,11 @@
--- **Functional** -- Short Range Air Defense System
--- **Functional** - Short Range Air Defense System.
--
-- ===
--
-- ## Features:
--
-- **SHORAD** - Short Range Air Defense System
-- Controls a network of short range air/missile defense groups.
-- * Short Range Air Defense System
-- * Controls a network of short range air/missile defense groups.
--
-- ===
--
@@ -18,7 +20,7 @@
-- @module Functional.Shorad
-- @image Functional.Shorad.jpg
--
-- Date: July 2021
-- Date: Nov 2021
-------------------------------------------------------------------------
--- **SHORAD** class, extends Core.Base#BASE
@@ -41,6 +43,7 @@
-- @field #boolean UseEmOnOff Decide if we are using Emission on/off (default) or AlarmState red/green.
-- @extends Core.Base#BASE
--- *Good friends are worth defending.* Mr Tushman, Wonder (the Movie)
--
-- Simple Class for a more intelligent Short Range Air Defense System
@@ -131,6 +134,7 @@ do
["Kh29"] = "Kh29",
["Kh31"] = "Kh31",
["Kh66"] = "Kh66",
--["BGM_109"] = "BGM_109",
}
--- Instantiates a new SHORAD object
@@ -138,13 +142,13 @@ do
-- @param #string Name Name of this SHORAD
-- @param #string ShoradPrefix Filter for the Shorad #SET_GROUP
-- @param Core.Set#SET_GROUP Samset The #SET_GROUP of SAM sites to defend
-- @param #number Radius Defense radius in meters, used to switch on groups
-- @param #number Radius Defense radius in meters, used to switch on SHORAD groups **within** this radius
-- @param #number ActiveTimer Determines how many seconds the systems stay on red alert after wake-up call
-- @param #string Coalition Coalition, i.e. "blue", "red", or "neutral"
-- @param #boolean UseEmOnOff Use Emissions On/Off rather than Alarm State Red/Green (default: use Emissions switch)
-- @retunr #SHORAD self
function SHORAD:New(Name, ShoradPrefix, Samset, Radius, ActiveTimer, Coalition, UseEmOnOff)
local self = BASE:Inherit( self, BASE:New() )
local self = BASE:Inherit( self, FSM:New() )
self:T({Name, ShoradPrefix, Samset, Radius, ActiveTimer, Coalition})
local GroupSet = SET_GROUP:New():FilterPrefixes(ShoradPrefix):FilterCoalitions(Coalition):FilterCategoryGround():FilterStart()
@@ -162,11 +166,17 @@ do
self.DefenseLowProb = 70 -- probability to detect a missile shot, low margin
self.DefenseHighProb = 90 -- probability to detect a missile shot, high margin
self.UseEmOnOff = UseEmOnOff or false -- Decide if we are using Emission on/off (default) or AlarmState red/green
self:I("*** SHORAD - Started Version 0.2.8")
self:I("*** SHORAD - Started Version 0.3.1")
-- Set the string id for output to DCS.log file.
self.lid=string.format("SHORAD %s | ", self.name)
self:_InitState()
self:HandleEvent(EVENTS.Shot, self.HandleEventShot)
-- Start State.
self:SetStartState("Running")
self:AddTransition("*", "WakeUpShorad", "*")
self:AddTransition("*", "CalculateHitZone", "*")
return self
end
@@ -310,7 +320,7 @@ do
local hit = false
if self.DefendHarms then
for _,_name in pairs (SHORAD.Harms) do
if string.find(WeaponName,_name,1) then hit = true end
if string.find(WeaponName,_name,1,true) then hit = true end
end
end
return hit
@@ -326,7 +336,7 @@ do
local hit = false
if self.DefendMavs then
for _,_name in pairs (SHORAD.Mavs) do
if string.find(WeaponName,_name,1) then hit = true end
if string.find(WeaponName,_name,1,true) then hit = true end
end
end
return hit
@@ -367,7 +377,7 @@ do
local returnname = false
for _,_groups in pairs (shoradset) do
local groupname = _groups:GetName()
if string.find(groupname, tgtgrp, 1) then
if string.find(groupname, tgtgrp, 1, true) then
returnname = true
--_groups:RelocateGroundRandomInRadius(7,100,false,false) -- be a bit evasive
end
@@ -388,7 +398,7 @@ do
local returnname = false
for _,_groups in pairs (shoradset) do
local groupname = _groups:GetName()
if string.find(groupname, tgtgrp, 1) then
if string.find(groupname, tgtgrp, 1, true) then
returnname = true
end
end
@@ -400,6 +410,7 @@ do
-- @return #boolean Returns true for a detection, else false
function SHORAD:_ShotIsDetected()
self:T(self.lid .. " _ShotIsDetected")
if self.debug then return true end
local IsDetected = false
local DetectionProb = math.random(self.DefenseLowProb, self.DefenseHighProb) -- reference value
local ActualDetection = math.random(1,100) -- value for this shot
@@ -423,7 +434,7 @@ do
-- mymantis = MANTIS:New("BlueMantis","Blue SAM","Blue EWR",nil,"blue",false,"Blue Awacs")
-- mymantis:AddShorad(myshorad,720)
-- mymantis:Start()
function SHORAD:WakeUpShorad(TargetGroup, Radius, ActiveTimer, TargetCat)
function SHORAD:onafterWakeUpShorad(From, Event, To, TargetGroup, Radius, ActiveTimer, TargetCat)
self:T(self.lid .. " WakeUpShorad")
self:T({TargetGroup, Radius, ActiveTimer, TargetCat})
local targetcat = TargetCat or Object.Category.UNIT
@@ -477,6 +488,76 @@ do
return self
end
--- (Internal) Calculate hit zone of an AGM-88
-- @param #SHORAD self
-- @param #table SEADWeapon DCS.Weapon object
-- @param Core.Point#COORDINATE pos0 Position of the plane when it fired
-- @param #number height Height when the missile was fired
-- @param Wrapper.Group#GROUP SEADGroup Attacker group
-- @return #SHORAD self
function SHORAD:onafterCalculateHitZone(From,Event,To,SEADWeapon,pos0,height,SEADGroup)
self:T("**** Calculating hit zone")
if SEADWeapon and SEADWeapon:isExist() then
--local pos = SEADWeapon:getPoint()
-- postion and height
local position = SEADWeapon:getPosition()
local mheight = height
-- heading
local wph = math.atan2(position.x.z, position.x.x)
if wph < 0 then
wph=wph+2*math.pi
end
wph=math.deg(wph)
-- velocity
local wpndata = SEAD.HarmData["AGM_88"]
local mveloc = math.floor(wpndata[2] * 340.29)
local c1 = (2*mheight*9.81)/(mveloc^2)
local c2 = (mveloc^2) / 9.81
local Ropt = c2 * math.sqrt(c1+1)
if height <= 5000 then
Ropt = Ropt * 0.72
elseif height <= 7500 then
Ropt = Ropt * 0.82
elseif height <= 10000 then
Ropt = Ropt * 0.87
elseif height <= 12500 then
Ropt = Ropt * 0.98
end
-- look at a couple of zones across the trajectory
for n=1,3 do
local dist = Ropt - ((n-1)*20000)
local predpos= pos0:Translate(dist,wph)
if predpos then
local targetzone = ZONE_RADIUS:New("Target Zone",predpos:GetVec2(),20000)
if self.debug then
predpos:MarkToAll(string.format("height=%dm | heading=%d | velocity=%ddeg | Ropt=%dm",mheight,wph,mveloc,Ropt),false)
targetzone:DrawZone(coalition.side.BLUE,{0,0,1},0.2,nil,nil,3,true)
end
local seadset = self.Groupset
local tgtcoord = targetzone:GetRandomPointVec2()
local tgtgrp = seadset:FindNearestGroupFromPointVec2(tgtcoord)
local _targetgroup = nil
local _targetgroupname = "none"
local _targetskill = "Random"
if tgtgrp and tgtgrp:IsAlive() then
_targetgroup = tgtgrp
_targetgroupname = tgtgrp:GetName() -- group name
_targetskill = tgtgrp:GetUnit(1):GetSkill()
self:T("*** Found Target = ".. _targetgroupname)
self:WakeUpShorad(_targetgroupname, self.Radius, self.ActiveTimer, Object.Category.UNIT)
end
end
end
end
return self
end
--- Main function - work on the EventData
-- @param #SHORAD self
-- @param Core.Event#EVENTDATA EventData The event details table data set
@@ -504,13 +585,48 @@ do
if (self:_CheckHarms(ShootingWeaponName) or self:_CheckMavs(ShootingWeaponName)) and IsDetected then
-- get target data
local targetdata = EventData.Weapon:getTarget() -- Identify target
-- Is there target data?
if not targetdata or self.debug then
if string.find(ShootingWeaponName,"AGM_88",1,true) then
self:I("**** Tracking AGM-88 with no target data.")
local pos0 = EventData.IniUnit:GetCoordinate()
local fheight = EventData.IniUnit:GetHeight()
self:__CalculateHitZone(20,ShootingWeapon,pos0,fheight,EventData.IniGroup)
end
return self
end
local targetcat = targetdata:getCategory() -- Identify category
self:T(string.format("Target Category (3=STATIC, 1=UNIT)= %s",tostring(targetcat)))
self:T({targetdata})
local targetunit = nil
if targetcat == Object.Category.UNIT then -- UNIT
targetunit = UNIT:Find(targetdata)
elseif targetcat == Object.Category.STATIC then -- STATIC
targetunit = STATIC:Find(targetdata)
--self:T("Static Target Data")
--self:T({targetdata:isExist()})
--self:T({targetdata:getPoint()})
local tgtcoord = COORDINATE:NewFromVec3(targetdata:getPoint())
--tgtcoord:MarkToAll("Missile Target",true)
local tgtgrp1 = self.Samset:FindNearestGroupFromPointVec2(tgtcoord)
local tgtcoord1 = tgtgrp1:GetCoordinate()
--tgtcoord1:MarkToAll("Close target SAM",true)
local tgtgrp2 = self.Groupset:FindNearestGroupFromPointVec2(tgtcoord)
local tgtcoord2 = tgtgrp2:GetCoordinate()
--tgtcoord2:MarkToAll("Close target SHORAD",true)
local dist1 = tgtcoord:Get2DDistance(tgtcoord1)
local dist2 = tgtcoord:Get2DDistance(tgtcoord2)
if dist1 < dist2 then
targetunit = tgtgrp1
targetcat = Object.Category.UNIT
else
targetunit = tgtgrp2
targetcat = Object.Category.UNIT
end
end
--local targetunitname = Unit.getName(targetdata) -- Unit name
if targetunit and targetunit:IsAlive() then
@@ -519,7 +635,11 @@ do
local targetgroup = nil
local targetgroupname = "none"
if targetcat == Object.Category.UNIT then
targetgroup = targetunit:GetGroup()
if targetunit.ClassName == "UNIT" then
targetgroup = targetunit:GetGroup()
elseif targetunit.ClassName == "GROUP" then
targetgroup = targetunit
end
targetgroupname = targetgroup:GetName() -- group name
elseif targetcat == Object.Category.STATIC then
targetgroup = targetunit
@@ -540,6 +660,7 @@ do
end
end
end
return self
end
--
end
@@ -85,6 +85,7 @@
-- @field #boolean eventmoose If true, events are handled by MOOSE. If false, events are handled directly by DCS eventhandler. Default true.
-- @field Core.Zone#ZONE BattleZone
-- @field #boolean AutoEngage
-- @field #table waypoints Waypoints of the group as defined in the ME.
-- @extends Core.Fsm#FSM_CONTROLLABLE
--
@@ -265,6 +266,7 @@ SUPPRESSION={
DefaultAlarmState = "Auto",
DefaultROE = "Weapon Free",
eventmoose = true,
waypoints = {},
}
--- Enumerator of possible rules of engagement.
@@ -295,7 +297,7 @@ SUPPRESSION.MenuF10=nil
--- PSEUDOATC version.
-- @field #number version
SUPPRESSION.version="0.9.3"
SUPPRESSION.version="0.9.4"
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
@@ -309,7 +311,7 @@ SUPPRESSION.version="0.9.3"
--- Creates a new AI_suppression object.
-- @param #SUPPRESSION self
-- @param Wrapper.Group#GROUP group The GROUP object for which suppression should be applied.
-- @return #SUPPRESSION SUPPRESSION object or *nil* if group does not exist or is not a ground group.
-- @return #SUPPRESSION self
function SUPPRESSION:New(group)
-- Inherits from FSM_CONTROLLABLE
@@ -320,7 +322,7 @@ function SUPPRESSION:New(group)
self.lid=string.format("SUPPRESSION %s | ", tostring(group:GetName()))
self:T(self.lid..string.format("SUPPRESSION version %s. Activating suppressive fire for group %s", SUPPRESSION.version, group:GetName()))
else
self:E(self.lid.."SUPPRESSION | Requested group does not exist! (Has to be a MOOSE group.)")
self:E("SUPPRESSION | Requested group does not exist! (Has to be a MOOSE group)")
return nil
end
@@ -1186,6 +1188,16 @@ function SUPPRESSION:onafterFightBack(Controllable, From, Event, To)
-- Set ROE and alarm state back to default.
self:_SetROE()
self:_SetAlarmState()
local group=Controllable --Wrapper.Group#GROUP
local Waypoints = group:GetTemplateRoutePoints()
-- env.info("FF waypoints",showMessageBox)
-- self:I(Waypoints)
group:Route(Waypoints, 5)
end
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
@@ -1251,7 +1263,7 @@ function SUPPRESSION:onafterFallBack(Controllable, From, Event, To, AttackUnit)
self:_SetROE(SUPPRESSION.ROE.Hold)
-- Set alarm state to GREEN and let the unit run away.
self:_SetAlarmState(SUPPRESSION.AlarmState.Green)
self:_SetAlarmState(SUPPRESSION.AlarmState.Auto)
-- Make the group run away.
self:_Run(Coord, self.Speed, self.Formation, self.FallbackWait)
@@ -1537,7 +1549,7 @@ end
-- @param #SUPPRESSION self
-- @param Core.Event#EVENTDATA EventData
function SUPPRESSION:_OnEventHit(EventData)
self:F(EventData)
self:F3(EventData)
local GroupNameSelf=self.Controllable:GetName()
local GroupNameTgt=EventData.TgtGroupName
@@ -1676,15 +1688,15 @@ end
function SUPPRESSION:_Run(fin, speed, formation, wait)
speed=speed or 20
formation=formation or "Off road"
formation=formation or ENUMS.Formation.Vehicle.OffRoad
wait=wait or 30
local group=self.Controllable -- Wrapper.Controllable#CONTROLLABLE
local group=self.Controllable -- Wrapper.Group#GROUP
if group and group:IsAlive() then
-- Clear all tasks.
group:ClearTasks()
--group:ClearTasks()
-- Current coordinates of group.
local ini=group:GetCoordinate()
@@ -1694,57 +1706,18 @@ function SUPPRESSION:_Run(fin, speed, formation, wait)
-- Heading from ini to fin.
local heading=self:_Heading(ini, fin)
-- Number of waypoints.
local nx
if dist <= 50 then
nx=2
elseif dist <= 100 then
nx=3
elseif dist <= 500 then
nx=4
else
nx=5
end
-- Number of intermediate waypoints.
local dx=dist/(nx-1)
-- Waypoint and task arrays.
local wp={}
local tasks={}
-- First waypoint is the current position of the group.
wp[1]=ini:WaypointGround(speed, formation)
tasks[1]=group:TaskFunction("SUPPRESSION._Passing_Waypoint", self, 1, false)
if self.Debug then
local MarkerID=ini:MarkToAll(string.format("Waypoing %d of group %s (initial)", #wp, self.Controllable:GetName()))
end
self:T2(self.lid..string.format("Number of waypoints %d", nx))
for i=1,nx-2 do
local x=dx*i
local coord=ini:Translate(x, heading)
wp[#wp+1]=coord:WaypointGround(speed, formation)
tasks[#tasks+1]=group:TaskFunction("SUPPRESSION._Passing_Waypoint", self, #wp, false)
self:T2(self.lid..string.format("%d x = %4.1f", i, x))
if self.Debug then
local MarkerID=coord:MarkToAll(string.format("Waypoing %d of group %s", #wp, self.Controllable:GetName()))
end
end
self:T2(self.lid..string.format("Total distance: %4.1f", dist))
-- Final waypoint.
wp[#wp+1]=fin:WaypointGround(speed, formation)
if self.Debug then
local MarkerID=fin:MarkToAll(string.format("Waypoing %d of group %s (final)", #wp, self.Controllable:GetName()))
end
-- Task to hold.
local ConditionWait=group:TaskCondition(nil, nil, nil, nil, wait, nil)
local TaskHold = group:TaskHold()
@@ -1753,25 +1726,15 @@ function SUPPRESSION:_Run(fin, speed, formation, wait)
local TaskComboFin = {}
TaskComboFin[#TaskComboFin+1] = group:TaskFunction("SUPPRESSION._Passing_Waypoint", self, #wp, true)
TaskComboFin[#TaskComboFin+1] = group:TaskControlled(TaskHold, ConditionWait)
-- Add final task.
tasks[#tasks+1]=group:TaskCombo(TaskComboFin)
-- Original waypoints of the group.
local Waypoints = group:GetTemplateRoutePoints()
-- New points are added to the default route.
for i,p in ipairs(wp) do
table.insert(Waypoints, i, wp[i])
end
-- Set task for all waypoints.
for i,wp in ipairs(Waypoints) do
group:SetTaskWaypoint(Waypoints[i], tasks[i])
end
-- Final waypoint.
wp[#wp+1]=fin:WaypointGround(speed, formation, TaskComboFin)
if self.Debug then
local MarkerID=fin:MarkToAll(string.format("Waypoing %d of group %s (final)", #wp, self.Controllable:GetName()))
end
-- Submit task and route group along waypoints.
group:Route(Waypoints)
group:Route(wp)
else
self:E(self.lid..string.format("ERROR: Group is not alive!"))
@@ -1790,7 +1753,7 @@ function SUPPRESSION._Passing_Waypoint(group, Fsm, i, final)
local text=string.format("Group %s passing waypoint %d (final=%s)", group:GetName(), i, tostring(final))
MESSAGE:New(text,10):ToAllIf(Fsm.Debug)
if Fsm.Debug then
env.info(self.lid..text)
env.info(Fsm.lid..text)
end
if final then
@@ -1891,7 +1854,7 @@ function SUPPRESSION:_GetLife()
local groupstrength=#units/self.IniGroupStrength*100
self.T2(self.lid..string.format("Group %s _GetLife nunits = %d", self.Controllable:GetName(), #units))
self:T2(self.lid..string.format("Group %s _GetLife nunits = %d", self.Controllable:GetName(), #units))
for _,unit in pairs(units) do
File diff suppressed because it is too large Load Diff
@@ -1,4 +1,4 @@
--- **Functional** -- Models the process to zone guarding and capturing.
--- **Functional** - Models the process to zone guarding and capturing.
--
-- ===
--
@@ -68,9 +68,9 @@ do -- ZONE_CAPTURE_COALITION
--
-- In order to use ZONE_CAPTURE_COALITION, you need to:
--
-- * Create a @{Zone} object from one of the ZONE_ classes.
-- Note that ZONE_POLYGON_ classes are not yet functional.
-- The only functional ZONE_ classses are those derived from a ZONE_RADIUS.
-- * Create a @{Core.Zone} object from one of the ZONE_ classes.
-- The functional ZONE_ classses are those derived from a ZONE_RADIUS.
-- In order to use a ZONE_POLYGON, hand over the **GROUP name** of a late activated group forming a polygon with it's waypoints.
-- * Set the state of the zone. Most of the time, Guarded would be the initial state.
-- * Start the zone capturing **monitoring process**.
-- This will check the presence of friendly and/or enemy units within the zone and will transition the state of the zone when the tactical situation changed.
@@ -363,7 +363,7 @@ do -- ZONE_CAPTURE_COALITION
--- ZONE_CAPTURE_COALITION Constructor.
-- @param #ZONE_CAPTURE_COALITION self
-- @param Core.Zone#ZONE Zone A @{Zone} object with the goal to be achieved.
-- @param Core.Zone#ZONE Zone A @{Core.Zone} object with the goal to be achieved. Alternatively, can be handed as the name of late activated group describing a @{ZONE_POLYGON} with its waypoints.
-- @param DCSCoalition.DCSCoalition#coalition Coalition The initial coalition owning the zone.
-- @param #table UnitCategories Table of unit categories. See [DCS Class Unit](https://wiki.hoggitworld.com/view/DCS_Class_Unit). Default {Unit.Category.GROUND_UNIT}.
-- @param #table ObjectCategories Table of unit categories. See [DCS Class Object](https://wiki.hoggitworld.com/view/DCS_Class_Object). Default {Object.Category.UNIT, Object.Category.STATIC}, i.e. all UNITS and STATICS.
@@ -715,7 +715,7 @@ do -- ZONE_CAPTURE_COALITION
local UnitHit = EventData.TgtUnit
if UnitHit.ClassName ~= "SCENERY" then
if UnitHit and UnitHit.ClassName ~= "SCENERY" then
-- Check if unit is inside the capture zone and that it is of the defending coalition.
if UnitHit and UnitHit:IsInZone(self) and UnitHit:GetCoalition()==self.Coalition then
+36 -38
View File
@@ -1,4 +1,4 @@
--- **Functional (WIP)** -- Base class that models processes to achieve goals involving a Zone.
--- **Functional** - Base class that models processes to achieve goals involving a Zone.
--
-- ===
--
@@ -8,7 +8,7 @@
-- ===
--
-- ### Author: **FlightControl**
-- ### Contributions: **funkyfranky**
-- ### Contributions: **funkyfranky**, **Applevangelist**
--
-- ===
--
@@ -26,7 +26,6 @@ do -- Zone
-- @field #boolean SmokeZone If true, smoke zone.
-- @extends Core.Zone#ZONE_RADIUS
--- Models processes that have a Goal with a defined achievement involving a Zone.
-- Derived classes implement the ways how the achievements can be realized.
--
@@ -53,21 +52,26 @@ do -- Zone
SmokeColor = nil,
SmokeZone = nil,
}
--- ZONE_GOAL Constructor.
-- @param #ZONE_GOAL self
-- @param Core.Zone#ZONE_RADIUS Zone A @{Zone} object with the goal to be achieved.
-- @param Core.Zone#ZONE_RADIUS Zone A @{Core.Zone} object with the goal to be achieved. Alternatively, can be handed as the name of late activated group describing a ZONE_POLYGON with its waypoints.
-- @return #ZONE_GOAL
function ZONE_GOAL:New( Zone )
local self = BASE:Inherit( self, ZONE_RADIUS:New( Zone:GetName(), Zone:GetVec2(), Zone:GetRadius() ) ) -- #ZONE_GOAL
self:F( { Zone = Zone } )
BASE:I({Zone=Zone})
local self = BASE:Inherit( self, BASE:New())
if type(Zone) == "string" then
self = BASE:Inherit( self, ZONE_POLYGON:NewFromGroupName(Zone) )
else
self = BASE:Inherit( self, ZONE_RADIUS:New( Zone:GetName(), Zone:GetVec2(), Zone:GetRadius() ) ) -- #ZONE_GOAL
self:F( { Zone = Zone } )
end
-- Goal object.
self.Goal = GOAL:New()
self.SmokeTime = nil
-- Set smoke ON.
self:SetSmokeZone(true)
@@ -81,7 +85,7 @@ do -- Zone
-- @function [parent=#ZONE_GOAL] __DestroyedUnit
-- @param #ZONE_GOAL self
-- @param #number delay Delay in seconds.
--- DestroyedUnit Handler OnAfter for ZONE_GOAL
-- @function [parent=#ZONE_GOAL] OnAfterDestroyedUnit
-- @param #ZONE_GOAL self
@@ -93,15 +97,15 @@ do -- Zone
return self
end
--- Get the Zone.
-- @param #ZONE_GOAL self
-- @return #ZONE_GOAL
function ZONE_GOAL:GetZone()
return self
end
--- Get the name of the Zone.
-- @param #ZONE_GOAL self
-- @return #string
@@ -109,7 +113,6 @@ do -- Zone
return self:GetName()
end
--- Activate smoking of zone with the color or the current owner.
-- @param #ZONE_GOAL self
-- @param #boolean switch If *true* or *nil* activate smoke. If *false* or *nil*, no smoke.
@@ -131,11 +134,10 @@ do -- Zone
-- @param DCS#SMOKECOLOR.Color SmokeColor
function ZONE_GOAL:Smoke( SmokeColor )
self:F( { SmokeColor = SmokeColor} )
self.SmokeColor = SmokeColor
end
--- Flare the zone boundary.
-- @param #ZONE_GOAL self
-- @param DCS#SMOKECOLOR.Color FlareColor
@@ -143,7 +145,6 @@ do -- Zone
self:FlareZone( FlareColor, 30)
end
--- When started, check the Smoke and the Zone status.
-- @param #ZONE_GOAL self
function ZONE_GOAL:onafterGuard()
@@ -155,17 +156,16 @@ do -- Zone
end
end
--- Check status Smoke.
-- @param #ZONE_GOAL self
function ZONE_GOAL:StatusSmoke()
self:F({self.SmokeTime, self.SmokeColor})
if self.SmokeZone then
-- Current time.
local CurrentTime = timer.getTime()
-- Restart smoke every 5 min.
if self.SmokeTime == nil or self.SmokeTime + 300 <= CurrentTime then
if self.SmokeColor then
@@ -173,11 +173,10 @@ do -- Zone
self.SmokeTime = CurrentTime
end
end
end
end
end
end
--- @param #ZONE_GOAL self
-- @param Core.Event#EVENTDATA EventData Event data table.
@@ -185,38 +184,37 @@ do -- Zone
self:F( { "EventDead", EventData } )
self:F( { EventData.IniUnit } )
if EventData.IniDCSUnit then
local Vec3 = EventData.IniDCSUnit:getPosition().p
self:F( { Vec3 = Vec3 } )
if Vec3 and self:IsVec3InZone(Vec3) then
local PlayerHits = _DATABASE.HITS[EventData.IniUnitName]
if PlayerHits then
for PlayerName, PlayerHit in pairs( PlayerHits.Players or {} ) do
self.Goal:AddPlayerContribution( PlayerName )
self:DestroyedUnit( EventData.IniUnitName, PlayerName )
end
end
end
end
end
--- Activate the event UnitDestroyed to be fired when a unit is destroyed in the zone.
-- @param #ZONE_GOAL self
function ZONE_GOAL:MonitorDestroyedUnits()
self:HandleEvent( EVENTS.Dead, self.__Destroyed )
self:HandleEvent( EVENTS.Crash, self.__Destroyed )
end
end
@@ -1,4 +1,4 @@
--- **Functional (WIP)** -- Base class that models processes to achieve goals involving a Zone and Cargo.
--- **Functional** - Base class that models processes to achieve goals involving a Zone and Cargo.
--
-- ===
--
@@ -55,7 +55,7 @@ do -- ZoneGoal
--- ZONE_GOAL_CARGO Constructor.
-- @param #ZONE_GOAL_CARGO self
-- @param Core.Zone#ZONE Zone A @{Zone} object with the goal to be achieved.
-- @param Core.Zone#ZONE Zone A @{Core.Zone} object with the goal to be achieved.
-- @param DCSCoalition.DCSCoalition#coalition Coalition The initial coalition owning the zone.
-- @return #ZONE_GOAL_CARGO
function ZONE_GOAL_CARGO:New( Zone, Coalition )
@@ -1,4 +1,4 @@
--- **Functional (WIP)** -- Base class that models processes to achieve goals involving a Zone for a Coalition.
--- **Functional (WIP)** - Base class modeling processes to achieve goals involving coalition zones.
--
-- ===
--
@@ -53,7 +53,7 @@ do -- ZoneGoal
--- ZONE_GOAL_COALITION Constructor.
-- @param #ZONE_GOAL_COALITION self
-- @param Core.Zone#ZONE Zone A @{Zone} object with the goal to be achieved.
-- @param Core.Zone#ZONE Zone A @{Core.Zone} object with the goal to be achieved.
-- @param DCSCoalition.DCSCoalition#coalition Coalition The initial coalition owning the zone. Default coalition.side.NEUTRAL.
-- @param #table UnitCategories Table of unit categories. See [DCS Class Unit](https://wiki.hoggitworld.com/view/DCS_Class_Unit). Default {Unit.Category.GROUND_UNIT}.
-- @return #ZONE_GOAL_COALITION
+16 -4
View File
@@ -22,25 +22,37 @@ _DATABASE:_RegisterAirbases()
--- Check if os etc is available.
BASE:I("Checking de-sanitization of os, io and lfs:")
local __na=false
local __na = false
if os then
BASE:I("- os available")
else
BASE:I("- os NOT available! Some functions may not work.")
__na=true
__na = true
end
if io then
BASE:I("- io available")
else
BASE:I("- io NOT available! Some functions may not work.")
__na=true
__na = true
end
if lfs then
BASE:I("- lfs available")
else
BASE:I("- lfs NOT available! Some functions may not work.")
__na=true
__na = true
end
if __na then
BASE:I("Check <DCS install folder>/Scripts/MissionScripting.lua and comment out the lines with sanitizeModule(''). Use at your own risk!)")
end
BASE.ServerName = "Unknown"
if lfs and loadfile then
local serverfile = lfs.writedir() .. 'Config/serverSettings.lua'
if UTILS.FileExists(serverfile) then
loadfile(serverfile)()
if cfg and cfg.name then
BASE.ServerName = cfg.name
end
end
BASE.ServerName = BASE.ServerName or "Unknown"
BASE:I("Server Name: " .. tostring(BASE.ServerName))
end
+91 -49
View File
@@ -1,45 +1,55 @@
__Moose.Include( 'Scripts/Moose/Utilities/Enums.lua' )
__Moose.Include( 'Scripts/Moose/Utilities/Routines.lua' )
__Moose.Include( 'Scripts/Moose/Utilities/Utils.lua' )
__Moose.Include( 'Scripts/Moose/Utilities/Profiler.lua' )
__Moose.Include( 'Scripts/Moose/Utilities/Templates.lua' )
__Moose.Include( 'Scripts/Moose/Utilities/STTS.lua' )
__Moose.Include( 'Scripts/Moose/Utilities/FiFo.lua' )
__Moose.Include( 'Scripts/Moose/Utilities/Profiler.lua' )
__Moose.Include( 'Scripts/Moose/Utilities/Routines.lua' )
__Moose.Include( 'Scripts/Moose/Utilities/Socket.lua' )
__Moose.Include( 'Scripts/Moose/Utilities/STTS.lua' )
__Moose.Include( 'Scripts/Moose/Utilities/Templates.lua' )
__Moose.Include( 'Scripts/Moose/Utilities/Utils.lua' )
__Moose.Include( 'Scripts/Moose/Core/Base.lua' )
__Moose.Include( 'Scripts/Moose/Core/Astar.lua' )
__Moose.Include( 'Scripts/Moose/Core/Beacon.lua' )
__Moose.Include( 'Scripts/Moose/Core/UserFlag.lua' )
__Moose.Include( 'Scripts/Moose/Core/Report.lua' )
__Moose.Include( 'Scripts/Moose/Core/Scheduler.lua' )
__Moose.Include( 'Scripts/Moose/Core/ScheduleDispatcher.lua' )
__Moose.Include( 'Scripts/Moose/Core/Event.lua' )
__Moose.Include( 'Scripts/Moose/Core/Settings.lua' )
__Moose.Include( 'Scripts/Moose/Core/Menu.lua' )
__Moose.Include( 'Scripts/Moose/Core/Zone.lua' )
__Moose.Include( 'Scripts/Moose/Core/Zone_Detection.lua' )
__Moose.Include( 'Scripts/Moose/Core/Condition.lua' )
__Moose.Include( 'Scripts/Moose/Core/ClientMenu.lua')
__Moose.Include( 'Scripts/Moose/Core/Database.lua' )
__Moose.Include( 'Scripts/Moose/Core/Set.lua' )
__Moose.Include( 'Scripts/Moose/Core/Point.lua' )
__Moose.Include( 'Scripts/Moose/Core/Velocity.lua' )
__Moose.Include( 'Scripts/Moose/Core/Message.lua' )
__Moose.Include( 'Scripts/Moose/Core/Event.lua' )
__Moose.Include( 'Scripts/Moose/Core/Fsm.lua' )
__Moose.Include( 'Scripts/Moose/Core/Goal.lua' )
__Moose.Include( 'Scripts/Moose/Core/MarkerOps_Base.lua' )
__Moose.Include( 'Scripts/Moose/Core/Menu.lua' )
__Moose.Include( 'Scripts/Moose/Core/Message.lua' )
__Moose.Include( 'Scripts/Moose/Core/Point.lua' )
__Moose.Include( 'Scripts/Moose/Core/Report.lua' )
__Moose.Include( 'Scripts/Moose/Core/ScheduleDispatcher.lua' )
__Moose.Include( 'Scripts/Moose/Core/Scheduler.lua' )
__Moose.Include( 'Scripts/Moose/Core/Set.lua' )
__Moose.Include( 'Scripts/Moose/Core/Settings.lua' )
__Moose.Include( 'Scripts/Moose/Core/Spawn.lua' )
__Moose.Include( 'Scripts/Moose/Core/SpawnStatic.lua' )
__Moose.Include( 'Scripts/Moose/Core/Timer.lua' )
__Moose.Include( 'Scripts/Moose/Core/Goal.lua' )
__Moose.Include( 'Scripts/Moose/Core/Spot.lua' )
__Moose.Include( 'Scripts/Moose/Core/TextAndSound.lua' )
__Moose.Include( 'Scripts/Moose/Core/Timer.lua' )
__Moose.Include( 'Scripts/Moose/Core/UserFlag.lua' )
__Moose.Include( 'Scripts/Moose/Core/Velocity.lua' )
__Moose.Include( 'Scripts/Moose/Core/Zone_Detection.lua' )
__Moose.Include( 'Scripts/Moose/Core/Zone.lua' )
__Moose.Include( 'Scripts/Moose/Core/Pathline.lua' )
__Moose.Include( 'Scripts/Moose/Wrapper/Object.lua' )
__Moose.Include( 'Scripts/Moose/Wrapper/Identifiable.lua' )
__Moose.Include( 'Scripts/Moose/Wrapper/Positionable.lua' )
__Moose.Include( 'Scripts/Moose/Wrapper/Airbase.lua' )
__Moose.Include( 'Scripts/Moose/Wrapper/Client.lua' )
__Moose.Include( 'Scripts/Moose/Wrapper/Controllable.lua' )
__Moose.Include( 'Scripts/Moose/Wrapper/Group.lua' )
__Moose.Include( 'Scripts/Moose/Wrapper/Unit.lua' )
__Moose.Include( 'Scripts/Moose/Wrapper/Client.lua' )
__Moose.Include( 'Scripts/Moose/Wrapper/Static.lua' )
__Moose.Include( 'Scripts/Moose/Wrapper/Airbase.lua' )
__Moose.Include( 'Scripts/Moose/Wrapper/Scenery.lua' )
__Moose.Include( 'Scripts/Moose/Wrapper/Identifiable.lua' )
__Moose.Include( 'Scripts/Moose/Wrapper/Marker.lua' )
__Moose.Include( 'Scripts/Moose/Wrapper/Object.lua' )
__Moose.Include( 'Scripts/Moose/Wrapper/Positionable.lua' )
__Moose.Include( 'Scripts/Moose/Wrapper/Scenery.lua' )
__Moose.Include( 'Scripts/Moose/Wrapper/Static.lua' )
__Moose.Include( 'Scripts/Moose/Wrapper/Unit.lua' )
__Moose.Include( 'Scripts/Moose/Wrapper/Weapon.lua' )
__Moose.Include( 'Scripts/Moose/Wrapper/Net.lua' )
__Moose.Include( 'Scripts/Moose/Cargo/Cargo.lua' )
__Moose.Include( 'Scripts/Moose/Cargo/CargoUnit.lua' )
@@ -47,35 +57,67 @@ __Moose.Include( 'Scripts/Moose/Cargo/CargoSlingload.lua' )
__Moose.Include( 'Scripts/Moose/Cargo/CargoCrate.lua' )
__Moose.Include( 'Scripts/Moose/Cargo/CargoGroup.lua' )
__Moose.Include( 'Scripts/Moose/Functional/Scoring.lua' )
__Moose.Include( 'Scripts/Moose/Functional/CleanUp.lua' )
__Moose.Include( 'Scripts/Moose/Functional/Movement.lua' )
__Moose.Include( 'Scripts/Moose/Functional/Sead.lua' )
__Moose.Include( 'Scripts/Moose/Functional/Escort.lua' )
__Moose.Include( 'Scripts/Moose/Functional/MissileTrainer.lua' )
__Moose.Include( 'Scripts/Moose/Functional/AICSAR.lua' )
__Moose.Include( 'Scripts/Moose/Functional/AmmoTruck.lua' )
__Moose.Include( 'Scripts/Moose/Functional/Artillery.lua' )
__Moose.Include( 'Scripts/Moose/Functional/ATC_Ground.lua' )
__Moose.Include( 'Scripts/Moose/Functional/Autolase.lua' )
__Moose.Include( 'Scripts/Moose/Functional/CleanUp.lua' )
__Moose.Include( 'Scripts/Moose/Functional/Designate.lua' )
__Moose.Include( 'Scripts/Moose/Functional/Detection.lua' )
__Moose.Include( 'Scripts/Moose/Functional/DetectionZones.lua' )
__Moose.Include( 'Scripts/Moose/Functional/Designate.lua' )
__Moose.Include( 'Scripts/Moose/Functional/RAT.lua' )
__Moose.Include( 'Scripts/Moose/Functional/Range.lua' )
__Moose.Include( 'Scripts/Moose/Functional/ZoneGoal.lua' )
__Moose.Include( 'Scripts/Moose/Functional/ZoneGoalCoalition.lua' )
__Moose.Include( 'Scripts/Moose/Functional/ZoneCaptureCoalition.lua' )
__Moose.Include( 'Scripts/Moose/Functional/Artillery.lua' )
__Moose.Include( 'Scripts/Moose/Functional/Suppression.lua' )
__Moose.Include( 'Scripts/Moose/Functional/PseudoATC.lua' )
__Moose.Include( 'Scripts/Moose/Functional/Warehouse.lua' )
__Moose.Include( 'Scripts/Moose/Functional/Escort.lua' )
__Moose.Include( 'Scripts/Moose/Functional/Fox.lua' )
__Moose.Include( 'Scripts/Moose/Functional/Mantis.lua' )
__Moose.Include( 'Scripts/Moose/Functional/MissileTrainer.lua' )
__Moose.Include( 'Scripts/Moose/Functional/Movement.lua' )
__Moose.Include( 'Scripts/Moose/Functional/PseudoATC.lua' )
__Moose.Include( 'Scripts/Moose/Functional/Range.lua' )
__Moose.Include( 'Scripts/Moose/Functional/RAT.lua' )
__Moose.Include( 'Scripts/Moose/Functional/Scoring.lua' )
__Moose.Include( 'Scripts/Moose/Functional/Sead.lua' )
__Moose.Include( 'Scripts/Moose/Functional/Shorad.lua' )
__Moose.Include( 'Scripts/Moose/Functional/Suppression.lua' )
__Moose.Include( 'Scripts/Moose/Functional/Warehouse.lua' )
__Moose.Include( 'Scripts/Moose/Functional/ZoneCaptureCoalition.lua' )
__Moose.Include( 'Scripts/Moose/Functional/ZoneGoal.lua' )
__Moose.Include( 'Scripts/Moose/Functional/ZoneGoalCargo.lua' )
__Moose.Include( 'Scripts/Moose/Functional/ZoneGoalCoalition.lua' )
__Moose.Include( 'Scripts/Moose/Ops/Airboss.lua' )
__Moose.Include( 'Scripts/Moose/Ops/AirWing.lua' )
__Moose.Include( 'Scripts/Moose/Ops/ArmyGroup.lua' )
__Moose.Include( 'Scripts/Moose/Ops/ATIS.lua' )
__Moose.Include( 'Scripts/Moose/Ops/Auftrag.lua' )
__Moose.Include( 'Scripts/Moose/Ops/Awacs.lua' )
__Moose.Include( 'Scripts/Moose/Ops/Brigade.lua' )
__Moose.Include( 'Scripts/Moose/Ops/Chief.lua' )
__Moose.Include( 'Scripts/Moose/Ops/Cohort.lua' )
__Moose.Include( 'Scripts/Moose/Ops/Commander.lua' )
__Moose.Include( 'Scripts/Moose/Ops/CSAR.lua' )
__Moose.Include( 'Scripts/Moose/Ops/CTLD.lua' )
__Moose.Include( 'Scripts/Moose/Ops/Fleet.lua' )
__Moose.Include( 'Scripts/Moose/Ops/FlightControl.lua' )
__Moose.Include( 'Scripts/Moose/Ops/FlightGroup.lua' )
__Moose.Include( 'Scripts/Moose/Ops/Flotilla.lua' )
__Moose.Include( 'Scripts/Moose/Ops/Intelligence.lua' )
__Moose.Include( 'Scripts/Moose/Ops/Legion.lua' )
__Moose.Include( 'Scripts/Moose/Ops/NavyGroup.lua' )
__Moose.Include( 'Scripts/Moose/Ops/Operation.lua' )
__Moose.Include( 'Scripts/Moose/Ops/OpsGroup.lua' )
__Moose.Include( 'Scripts/Moose/Ops/OpsTransport.lua' )
__Moose.Include( 'Scripts/Moose/Ops/OpsZone.lua' )
__Moose.Include( 'Scripts/Moose/Ops/Platoon.lua' )
__Moose.Include( 'Scripts/Moose/Ops/PlayerTask.lua' )
__Moose.Include( 'Scripts/Moose/Ops/PlayerRecce.lua' )
__Moose.Include( 'Scripts/Moose/Ops/RecoveryTanker.lua' )
__Moose.Include( 'Scripts/Moose/Ops/RescueHelo.lua' )
__Moose.Include( 'Scripts/Moose/Ops/ATIS.lua' )
__Moose.Include( 'Scripts/Moose/Ops/CTLD.lua' )
__Moose.Include( 'Scripts/Moose/Ops/CSAR.lua' )
__Moose.Include( 'Scripts/Moose/Ops/Squadron.lua' )
__Moose.Include( 'Scripts/Moose/Ops/Target.lua' )
__Moose.Include( 'Scripts/Moose/Navigation/Navaid.lua' )
__Moose.Include( 'Scripts/Moose/Navigation/NavFix.lua' )
__Moose.Include( 'Scripts/Moose/Navigation/FlightPlan.lua' )
__Moose.Include( 'Scripts/Moose/AI/AI_Balancer.lua' )
__Moose.Include( 'Scripts/Moose/AI/AI_Air.lua' )
@@ -114,12 +156,12 @@ __Moose.Include( 'Scripts/Moose/Actions/Act_Route.lua' )
__Moose.Include( 'Scripts/Moose/Actions/Act_Account.lua' )
__Moose.Include( 'Scripts/Moose/Actions/Act_Assist.lua' )
__Moose.Include( 'Scripts/Moose/Sound/UserSound.lua' )
__Moose.Include( 'Scripts/Moose/Sound/SoundOutput.lua' )
__Moose.Include( 'Scripts/Moose/Sound/Radio.lua' )
__Moose.Include( 'Scripts/Moose/Sound/RadioQueue.lua' )
__Moose.Include( 'Scripts/Moose/Sound/RadioSpeech.lua' )
__Moose.Include( 'Scripts/Moose/Sound/SoundOutput.lua' )
__Moose.Include( 'Scripts/Moose/Sound/SRS.lua' )
__Moose.Include( 'Scripts/Moose/Sound/UserSound.lua' )
__Moose.Include( 'Scripts/Moose/Tasking/CommandCenter.lua' )
__Moose.Include( 'Scripts/Moose/Tasking/Mission.lua' )
@@ -0,0 +1,203 @@
--- **NAVIGATION** - Flight Plan.
--
-- **Main Features:**
--
-- * Manage navigation aids
-- * VOR, NDB
--
-- ===
--
-- ## Example Missions:
--
-- Demo missions can be found on [github](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/develop/Ops%20-%20FlightPlan).
--
-- ===
--
-- ### Author: **funkyfranky**
--
-- ===
-- @module Navigation.FlightPlan
-- @image NAVIGATION_FlightPlan.png
--- FLIGHTPLAN class.
-- @type FLIGHTPLAN
-- @field #string ClassName Name of the class.
-- @field #number verbose Verbosity of output.
-- @field #table fixes Navigation fixes.
-- @field Wrapper.Airbase#AIRBASE departureAirbase Departure airbase.
-- @field Wrapper.Airbase#AIRBASE destinationAirbase Destination airbase.
-- @field #number altitudeCruiseMin Minimum cruise altitude in feet MSL.
-- @field #number altitudeCruiseMax Maximum cruise altitude in feet MSL.
-- @extends Core.Base#BASE
--- *A fleet of British ships at war are the best negotiators.* -- Horatio Nelson
--
-- ===
--
-- # The FLIGHTPLAN Concept
--
-- A FLIGHTPLAN consists of one or multiple FLOTILLAs. These flotillas "live" in a WAREHOUSE that has a phyiscal struction (STATIC or UNIT) and can be captured or destroyed.
--
-- # Basic Setup
--
-- A new `FLIGHTPLAN` object can be created with the @{#FLIGHTPLAN.New}(`WarehouseName`, `FleetName`) function, where `WarehouseName` is the name of the static or unit object hosting the fleet
-- and `FleetName` is the name you want to give the fleet. This must be *unique*!
--
-- myFlightplan=FLIGHTPLAN:New("Plan A")
-- myFleet:SetPortZone(ZonePort1stFleet)
-- myFleet:Start()
--
-- A fleet needs a *port zone*, which is set via the @{#FLIGHTPLAN.SetPortZone}(`PortZone`) function. This is the zone where the naval assets are spawned and return to.
--
-- Finally, the fleet needs to be started using the @{#FLIGHTPLAN.Start}() function. If the fleet is not started, it will not process any requests.
--
-- @field #FLIGHTPLAN
FLIGHTPLAN = {
ClassName = "FLIGHTPLAN",
verbose = 0,
fixes = {}
}
--- Type of navaid
-- @type FLIGHTPLAN.Type
-- @field #string VOR VOR
-- @field #string NDB NDB
FLIGHTPLAN.TYPE={
VOR="VOR",
NDB="NDB",
}
--- FLIGHTPLAN class version.
-- @field #string version
FLIGHTPLAN.version="0.0.1"
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- ToDo list
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO: A lot...
-- TODO: How to handle the FLIGHTGROUP:_LandAtAirBase
-- TODO: Do we always need a holding pattern? https://www.faa.gov/air_traffic/publications/atpubs/aip_html/part2_enr_section_1.5.html#:~:text=If%20no%20holding%20pattern%20is,than%20that%20desired%20by%20ATC.
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Constructor
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- Create a new FLIGHTPLAN instance.
-- @param #FLIGHTPLAN self
-- @param #string Name Name of this flight plan.
-- @return #FLIGHTPLAN self
function FLIGHTPLAN:New(Name)
-- Inherit everything from SCENERY class.
self=BASE:Inherit(self, BASE:New()) -- #FLIGHTPLAN
-- Set alias.
self.alias=tostring(Name)
-- Set some string id for output to DCS.log file.
self.lid=string.format("FLIGHTPLAN %s | ", self.alias)
-- Debug info.
self:I(self.lid..string.format("Created FLIGHTPLAN!"))
return self
end
--- Create a new FLIGHTPLAN instance from another FLIGHTPLAN acting as blue print.
-- The newly created flight plan is deep copied from the given one.
-- @param #FLIGHTPLAN self
-- @param #FLIGHTPLAN FlightPlan Blue print of the flight plan to copy.
-- @return #FLIGHTPLAN self
function FLIGHTPLAN:NewFromFlightPlan(FlightPlan)
self=UTILS.DeepCopy(FlightPlan)
return self
end
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- User Functions
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- Add navigation fix to the flight plan.
-- @param #FLIGHTPLAN self
-- @param Navigation.NavFix#NAVFIX NavFix The nav fix.
-- @return #FLIGHTPLAN self
function FLIGHTPLAN:AddNavFix(NavFix)
table.insert(self.fixes, NavFix)
return self
end
--- Set depature airbase.
-- @param #FLIGHTPLAN self
-- @param #string AirbaseName Name of the airbase or AIRBASE object.
-- @return #FLIGHTPLAN self
function FLIGHTPLAN:SetDepartureAirbase(AirbaseName)
self.departureAirbase=AIRBASE:FindByName(AirbaseName)
return self
end
--- Set destination airbase.
-- @param #FLIGHTPLAN self
-- @param #string AirbaseName Name of the airbase or AIRBASE object.
-- @return #FLIGHTPLAN self
function FLIGHTPLAN:SetDestinationAirbase(AirbaseName)
self.destinationAirbase=AIRBASE:FindByName(AirbaseName)
return self
end
--- Set cruise altitude.
-- @param #FLIGHTPLAN self
-- @param #number AltMin Minimum altitude in feet MSL.
-- @param #number AltMax Maximum altitude in feet MSL. Default is `AltMin`.
-- @return #FLIGHTPLAN self
function FLIGHTPLAN:SetCruiseAltitude(AltMin, AltMax)
self.altitudeCruiseMin=AltMin
self.altitudeCruiseMax=AltMax or self.altitudeCruiseMin
return self
end
--- Get the name of this flight plan.
-- @param #FLIGHTPLAN self
-- @return #string The name.
function FLIGHTPLAN:GetName()
return self.alias
end
--- Get cruise altitude. This returns a random altitude between the set min/max cruise altitudes.
-- @param #FLIGHTPLAN self
-- @return #number Cruise altitude in feet MSL.
function FLIGHTPLAN:GetCruiseAltitude()
local alt=10000
if self.altitudeCruiseMin and self.altitudeCruiseMax then
alt=math.random(self.altitudeCruiseMin, self.altitudeCruiseMax)
elseif self.altitudeCruiseMin then
alt=self.altitudeCruiseMin
elseif self.altitudeCruiseMax then
alt=self.altitudeCruiseMax
end
return alt
end
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Private Functions
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
@@ -0,0 +1,212 @@
--- **NAVIGATION** - Navigation Airspace Fix.
--
-- **Main Features:**
--
-- * Stuff
-- * More Stuff
--
-- ===
--
-- ## Example Missions:
--
-- Demo missions can be found on [github](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/develop/Navigation%20-%20NavFix).
--
-- ===
--
-- ### Author: **funkyfranky**
--
-- ===
-- @module Navigation.NavFix
-- @image NAVIGATION_NavFix.png
--- NAVFIX class.
-- @type NAVFIX
-- @field #string ClassName Name of the class.
-- @field #number verbose Verbosity of output.
-- @field #string name Name of the fix.
-- @field Core.Point#COORDINATE coordinate Coordinate of the fix.
-- @field Wrapper.Marker#MARKER marker Marker of fix on F10 map.
-- @field #boolean isCompulsory Is this a compulsory fix.
-- @field #boolean isFlyover Is this a fly over fix.
-- @field #boolean isIAF Is initial approach fix (IAF).
-- @field #boolean isIF Is intermediate fix (IF).
--
-- @extends Core.Base#BASE
--- *A fleet of British ships at war are the best negotiators.* -- Horatio Nelson
--
-- ===
--
-- # The NAVFIX Concept
--
-- The NAVFIX class has a great concept!
--
-- # Basic Setup
--
-- A new `NAVFIX` object can be created with the @{#NAVFIX.New}() function.
--
-- myTemplate=NAVFIX:New()
-- myTemplate:SetXYZ(X, Y, Z)
--
-- This is how it works.
--
-- @field #NAVFIX
NAVFIX = {
ClassName = "NAVFIX",
verbose = 0,
}
--- Type of navaid
-- @type NAVFIX.Type
-- @field #string VOR VOR
-- @field #string NDB NDB
NAVFIX.Type={
VOR="VOR",
NDB="NDB",
}
--- NAVFIX class version.
-- @field #string version
NAVFIX.version="0.0.1"
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- ToDo list
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO: A lot...
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Constructor
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- Create a new NAVFIX class instance.
-- @param #NAVFIX self
-- @return #NAVFIX self
function NAVFIX:New(Coordinate, Name)
-- Inherit everything from SCENERY class.
self=BASE:Inherit(self, BASE:New()) -- #NAVFIX
self.coordinate=Coordinate
self.name=Name
self.marker=MARKER:New(Coordinate, self:_GetMarkerText())
self.marker:ToAll()
return self
end
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- User Functions
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- Set minimum altitude.
-- @param #NAVFIX self
-- @param #number Altitude Min altitude in feet.
-- @return #NAVFIX self
function NAVFIX:SetAltMin(Altitude)
self.altMin=Altitude
return self
end
--- Set maximum altitude.
-- @param #NAVFIX self
-- @param #number Altitude Max altitude in feet.
-- @return #NAVFIX self
function NAVFIX:SetAltMax(Altitude)
self.altMax=Altitude
return self
end
--- Set whether this fix is compulsory.
-- @param #NAVFIX self
-- @param #boolean Compulsory If `true`, this is a compusory fix. If `false` or nil, it is non-compulsory.
-- @return #NAVFIX self
function NAVFIX:SetCompulsory(Compulsory)
self.isCompulsory=Compulsory
return self
end
--- Set whether this fix is compulsory.
-- @param #NAVFIX self
-- @param #boolean FlyOver If `true`, this is a fly over fix. If `false` or nil, it is not.
-- @return #NAVFIX self
function NAVFIX:SetFlyOver(FlyOver)
self.isFlyover=FlyOver
return self
end
--- Set whether this is the intermediate fix.
-- @param #NAVFIX self
-- @param #boolean IntermediateFix If `true`, this is an intermediate fix.
-- @return #NAVFIX self
function NAVFIX:SetIntermediateFix(IntermediateFix)
self.isIF=IntermediateFix
return self
end
--- Set whether this is an initial approach fix (IAF).
-- @param #NAVFIX self
-- @param #boolean IntermediateFix If `true`, this is an intermediate fix.
-- @return #NAVFIX self
function NAVFIX:SetInitialApproachFix(IntermediateFix)
self.isIAF=IntermediateFix
return self
end
--- Get the altitude in feet MSL.
-- @param #NAVFIX self
-- @return #number Altitude in feet MSL. Can be `#nil`
function NAVFIX:GetAltitude()
local alt=nil
if self.altMin and self.altMax then
alt=math.random(self.altMin, self.altMax)
elseif self.altMin then
alt=self.altMin
elseif self.altMax then
alt=self.altMax
end
return alt
end
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Private Functions
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- Get text displayed in the F10 marker.
-- @param #NAVFIX self
-- @return #string Marker text.
function NAVFIX:_GetMarkerText()
local altmin=self.altMin and tostring(self.altMin) or ""
local altmax=self.altMax and tostring(self.altMax) or ""
local speedmin=self.speedMin and tostring(self.speedMin) or ""
local speedmax=self.speedMax and tostring(self.speedMax) or ""
local text=string.format("NAVFIX %s", self.name)
if self.isIAF then
text=text..string.format(" (IAF)")
end
if self.isIF then
text=text..string.format(" (IF)")
end
text=text..string.format("\nAltitude: %s - %s", altmin, altmax)
text=text..string.format("\nSpeed: %s - %s", speedmin, speedmax)
text=text..string.format("\nCompulsory: %s", tostring(self.isCompulsory))
text=text..string.format("\nFly Over: %s", tostring(self.isFlyover))
return text
end
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
@@ -0,0 +1,172 @@
--- **Navigation** - Navigation aid.
--
-- **Main Features:**
--
-- * Manage navigation aids
-- * VOR, NDB
--
-- ===
--
-- ## Example Missions:
--
-- Demo missions can be found on [github](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/develop/Navigation%20-%20Navaid).
--
-- ===
--
-- ### Author: **funkyfranky**
--
-- ===
-- @module Navigation.Navaid
-- @image Navigation_Navaid.png
--- NAVAID class.
-- @type NAVAID
-- @field #string ClassName Name of the class.
-- @field #number verbose Verbosity of output.
-- @extends Core.Base#BASE
--- *A fleet of British ships at war are the best negotiators.* -- Horatio Nelson
--
-- ===
--
-- # The NAVAID Concept
--
-- A NAVAID consists of one or multiple FLOTILLAs. These flotillas "live" in a WAREHOUSE that has a phyiscal struction (STATIC or UNIT) and can be captured or destroyed.
--
-- # Basic Setup
--
-- A new `NAVAID` object can be created with the @{#NAVAID.New}(`WarehouseName`, `FleetName`) function, where `WarehouseName` is the name of the static or unit object hosting the fleet
-- and `FleetName` is the name you want to give the fleet. This must be *unique*!
--
-- myFleet=NAVAID:New("myWarehouseName", "1st Fleet")
-- myFleet:SetPortZone(ZonePort1stFleet)
-- myFleet:Start()
--
-- A fleet needs a *port zone*, which is set via the @{#NAVAID.SetPortZone}(`PortZone`) function. This is the zone where the naval assets are spawned and return to.
--
-- Finally, the fleet needs to be started using the @{#NAVAID.Start}() function. If the fleet is not started, it will not process any requests.
--
-- @field #NAVAID
NAVAID = {
ClassName = "NAVAID",
verbose = 0,
}
--- Type of navaid
-- @type NAVAID.Type
-- @field #string VOR VOR
-- @field #string NDB NDB
NAVAID.TYPE={
VOR="VOR",
NDB="NDB",
}
--- NAVAID class version.
-- @field #string version
NAVAID.version="0.0.1"
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- ToDo list
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO: A lot...
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Constructor
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- Create a new NAVAID class instance.
-- @param #NAVAID self
-- @param #string ZoneName Name of the zone to scan the scenery.
-- @param #string SceneryName Name of the scenery object.
-- @param #string Type Type of Navaid.
-- @return #NAVAID self
function NAVAID:New(ZoneName, SceneryName, Type)
-- Inherit everything from SCENERY class.
self=BASE:Inherit(self, BASE:New()) -- #NAVAID
self.zone=ZONE:FindByName(ZoneName)
self.coordinate=self.zone:GetCoordinate()
if SceneryName then
self.scenery=SCENERY:FindByNameInZone(SceneryName, ZoneName)
if not self.scenery then
self:E("ERROR: Could not find scenery object %s in zone %s", SceneryName, ZoneName)
end
end
self.alias=string.format("%s %s %s", tostring(ZoneName), tostring(SceneryName), tostring(Type))
-- Set some string id for output to DCS.log file.
self.lid=string.format("NAVAID %s | ", self.alias)
self:I(self.lid..string.format("Created NAVAID!"))
return self
end
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- User Functions
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- Set frequency.
-- @param #NAVAID self
-- @param #number Frequency Frequency in Hz.
-- @return #NAVAID self
function NAVAID:SetFrequency(Frequency)
self.frequency=Frequency
return self
end
--- Set channel.
-- @param #NAVAID self
-- @param #number Channel
-- @param #string Band
-- @return #NAVAID self
function NAVAID:SetChannel(Channel, Band)
self.channel=Channel
self.band=Band
return self
end
--- Add marker the NAVAID on the F10 map.
-- @param #NAVAID self
-- @return #NAVAID self
function NAVAID:AddMarker()
local text=string.format("I am a NAVAID!")
self.markID=self.coordinate:MarkToAll(text, true)
return self
end
--- Remove marker of the NAVAID from the F10 map.
-- @param #NAVAID self
-- @return #NAVAID self
function NAVAID:DelMarker()
if self.markID then
UTILS.RemoveMark(self.markID)
end
return self
end
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Private Functions
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
@@ -0,0 +1,108 @@
--- **NAVIGATION** - Template.
--
-- **Main Features:**
--
-- * Stuff
-- * More Stuff
--
-- ===
--
-- ## Example Missions:
--
-- Demo missions can be found on [github](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/develop/Navigation%20-%20Template).
--
-- ===
--
-- ### Author: **funkyfranky**
--
-- ===
-- @module Navigation.Template
-- @image NAVIGATION_Template.png
--- TEMPLATE class.
-- @type TEMPLATE
-- @field #string ClassName Name of the class.
-- @field #number verbose Verbosity of output.
-- @extends Core.Base#BASE
--- *A fleet of British ships at war are the best negotiators.* -- Horatio Nelson
--
-- ===
--
-- # The TEMPLATE Concept
--
-- The TEMPLATE class has a great concept!
--
-- # Basic Setup
--
-- A new `TEMPLATE` object can be created with the @{#TEMPLATE.New}() function.
--
-- myTemplate=TEMPLATE:New()
-- myTemplate:SetXYZ(X, Y, Z)
--
-- This is how it works.
--
-- @field #TEMPLATE
TEMPLATE = {
ClassName = "TEMPLATE",
verbose = 0,
}
--- Type of navaid
-- @type TEMPLATE.Type
-- @field #string VOR VOR
-- @field #string NDB NDB
TEMPLATE.TYPE={
VOR="VOR",
NDB="NDB",
}
--- TEMPLATE class version.
-- @field #string version
TEMPLATE.version="0.0.1"
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- ToDo list
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO: A lot...
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Constructor
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- Create a new TEMPLATE class instance.
-- @param #TEMPLATE self
-- @return #TEMPLATE self
function TEMPLATE:New()
-- Inherit everything from SCENERY class.
self=BASE:Inherit(self, BASE:New()) -- #TEMPLATE
return self
end
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- User Functions
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- Set frequency.
-- @param #TEMPLATE self
-- @param #number Frequency Frequency in Hz.
-- @return #TEMPLATE self
function TEMPLATE:SetFrequency(Frequency)
self.frequency=Frequency
return self
end
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Private Functions
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+316 -177
View File
@@ -1,3 +1,4 @@
---@diagnostic disable: cast-local-type
--- **Ops** - Automatic Terminal Information Service (ATIS).
--
-- ===
@@ -46,13 +47,12 @@
--
-- ### Author: **funkyfranky**
--
-- @module Ops.Atis
-- @module Ops.ATIS
-- @image OPS_ATIS.png
--- ATIS class.
-- @type ATIS
-- @field #string ClassName Name of the class.
-- @field #boolean Debug Debug mode. Messages to all about status.
-- @field #string lid Class id string for output to DCS log file.
-- @field #string theatre DCS map name.
-- @field #string airbasename The name of the airbase.
@@ -92,6 +92,10 @@
-- @field #boolean useSRS If true, use SRS for transmission.
-- @field Sound.SRS#MSRS msrs Moose SRS object.
-- @field #number dTQueueCheck Time interval to check the radio queue. Default 5 sec or 90 sec if SRS is used.
-- @field #boolean ReportmBar Report mBar/hpa even if not metric, i.e. for Mirage flights
-- @field #boolean TransmitOnlyWithPlayers For SRS - If true, only transmit if there are alive Players.
-- @field #string SRSText Text of the complete SRS message (if done at least once, else nil)
-- @field #boolean ATISforFARPs Will be set to true if the base given is a FARP/Helipad
-- @extends Core.Fsm#FSM
--- *It is a very sad thing that nowadays there is so little useless information.* - Oscar Wilde
@@ -121,7 +125,7 @@
-- The @{#ATIS.New}(*airbasename*, *frequency*) creates a new ATIS object. The parameter *airbasename* is the name of the airbase or airport. Note that this has to be spelled exactly as in the DCS mission editor.
-- The parameter *frequency* is the frequency the ATIS broadcasts in MHz.
--
-- Broadcasting is started via the @{#ATIS.Start}() function. The start can be delayed by useing @{#ATIS.__Start}(*delay*), where *delay* is the delay in seconds.
-- Broadcasting is started via the @{#ATIS.Start}() function. The start can be delayed by using @{#ATIS.__Start}(*delay*), where *delay* is the delay in seconds.
--
-- ## Subtitles
--
@@ -267,6 +271,8 @@
-- Unfortunately, it is not possible to determine the duration of the complete transmission. So once the transmission is finished, there might be some radio silence before
-- the next iteration begins. You can fine tune the time interval between transmissions with the @{#ATIS.SetQueueUpdateTime}() function. The default interval is 90 seconds.
--
-- An SRS Setup-Guide can be found here: [Moose TTS Setup Guide](https://github.com/FlightControl-Master/MOOSE_GUIDES/blob/master/documents/Moose%20TTS%20Setup%20Guide.pdf)
--
-- # Examples
--
-- ## Caucasus: Batumi
@@ -305,11 +311,23 @@
-- atis:Start()
--
-- This uses a male voice with US accent. It requires SRS to be installed in the `D:\DCS\_SRS\` directory. Not that backslashes need to be escaped or simply use slashes (as in linux).
--
-- ## FARPS
--
-- ATIS is working with FARPS, but this requires the usage of SRS. The airbase name for the `New()-method` is the UNIT name of the FARP:
--
-- atis = ATIS:New("FARP Gold",119,radio.modulation.AM)
-- atis:SetMetricUnits()
-- atis:SetTransmitOnlyWithPlayers(true)
-- atis:SetReportmBar(true)
-- atis:SetTowerFrequencies(127.50)
-- atis:SetSRS("D:\\DCS\\_SRS\\", "male", "en-US",nil,5002)
-- atis:SetAdditionalInformation("Welcome to the Jungle!")
-- atis:__Start(3)
--
-- @field #ATIS
ATIS = {
ClassName = "ATIS",
Debug = false,
lid = nil,
theatre = nil,
airbasename = nil,
@@ -346,6 +364,9 @@ ATIS = {
usemarker = nil,
markerid = nil,
relHumidity = nil,
ReportmBar = false,
TransmitOnlyWithPlayers = false,
ATISforFARPs = false,
}
--- NATO alphabet.
@@ -588,15 +609,19 @@ _ATIS = {}
--- ATIS class version.
-- @field #string version
ATIS.version = "0.9.6"
ATIS.version = "0.9.15"
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO list
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO: Add new Normany airfields.
-- TODO: Zulu time --> Zulu in output.
-- TODO: Correct fog for elevation.
-- DONE: Zulu time --> Zulu in output.
-- DONE: Fix for AB not having a runway - Helopost like Naqoura
-- DONE: Add new Normandy airfields.
-- DONE: Use new AIRBASE system to set start/landing runway
-- DONE: SetILS doesn't work
-- DONE: Visibility reported twice over SRS
-- DONE: Add text report for output.
-- DONE: Add stop FMS functions.
-- NOGO: Use local time. Not realisitc!
@@ -611,28 +636,28 @@ ATIS.version = "0.9.6"
-- Constructor
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- Create a new ATIS class object for a specific aircraft carrier unit.
--- Create a new ATIS class object for a specific airbase.
-- @param #ATIS self
-- @param #string airbasename Name of the airbase.
-- @param #number frequency Radio frequency in MHz. Default 143.00 MHz.
-- @param #number modulation Radio modulation: 0=AM, 1=FM. Default 0=AM. See `radio.modulation.AM` and `radio.modulation.FM` enumerators
-- @param #string AirbaseName Name of the airbase.
-- @param #number Frequency Radio frequency in MHz. Default 143.00 MHz.
-- @param #number Modulation Radio modulation: 0=AM, 1=FM. Default 0=AM. See `radio.modulation.AM` and `radio.modulation.FM` enumerators.
-- @return #ATIS self
function ATIS:New( airbasename, frequency, modulation )
function ATIS:New(AirbaseName, Frequency, Modulation)
-- Inherit everything from FSM class.
local self = BASE:Inherit( self, FSM:New() ) -- #ATIS
self.airbasename = airbasename
self.airbase = AIRBASE:FindByName( airbasename )
self.airbasename=AirbaseName
self.airbase=AIRBASE:FindByName(AirbaseName)
if self.airbase == nil then
self:E( "ERROR: Airbase %s for ATIS could not be found!", tostring( airbasename ) )
if self.airbase==nil then
self:E("ERROR: Airbase %s for ATIS could not be found!", tostring(AirbaseName))
return nil
end
-- Default freq and modulation.
self.frequency = frequency or 143.00
self.modulation = modulation or 0
self.frequency=Frequency or 143.00
self.modulation=Modulation or 0
-- Get map.
self.theatre = env.mission.theatre
@@ -653,6 +678,7 @@ function ATIS:New( airbasename, frequency, modulation )
self:SetMapMarks( false )
self:SetRelativeHumidity()
self:SetQueueUpdateTime()
self:SetReportmBar(false)
-- Start State.
self:SetStartState( "Stopped" )
@@ -734,14 +760,6 @@ function ATIS:New( airbasename, frequency, modulation )
-- @param #string To To state.
-- @param #string Text Report text.
-- Debug trace.
if false then
self.Debug = true
BASE:TraceOnOff( true )
BASE:TraceClass( self.ClassName )
BASE:TraceLevel( 1 )
end
return self
end
@@ -755,7 +773,7 @@ end
-- @return #ATIS self
function ATIS:SetSoundfilesPath( path )
self.soundpath = tostring( path or "ATIS Soundfiles/" )
self:I( self.lid .. string.format( "Setting sound files path to %s", self.soundpath ) )
self:T( self.lid .. string.format( "Setting sound files path to %s", self.soundpath ) )
return self
end
@@ -766,7 +784,7 @@ end
-- @return #ATIS self
function ATIS:SetRadioRelayUnitName( unitname )
self.relayunitname = unitname
self:I( self.lid .. string.format( "Setting radio relay unit to %s", self.relayunitname ) )
self:T( self.lid .. string.format( "Setting radio relay unit to %s", self.relayunitname ) )
return self
end
@@ -784,13 +802,52 @@ function ATIS:SetTowerFrequencies( freqs )
return self
end
--- Set active runway. This can be used if the automatic runway determination via the wind direction gives incorrect results.
--- For SRS - Switch to only transmit if there are players on the server.
-- @param #ATIS self
-- @param #boolean Switch If true, only send SRS if there are alive Players.
-- @return #ATIS self
function ATIS:SetTransmitOnlyWithPlayers(Switch)
self.TransmitOnlyWithPlayers = Switch
if self.msrsQ then
self.msrsQ:SetTransmitOnlyWithPlayers(Switch)
end
return self
end
--- Set active runway for **landing** operations. This can be used if the automatic runway determination via the wind direction gives incorrect results.
-- For example, use this if there are two runways with the same directions.
-- @param #ATIS self
-- @param #string runway Active runway, *e.g.* "31L".
-- @return #ATIS self
function ATIS:SetActiveRunway( runway )
self.activerunway = tostring( runway )
local prefer = nil
if string.find(string.lower(runway),"l") then
prefer = true
elseif string.find(string.lower(runway),"r") then
prefer = false
end
self.airbase:SetActiveRunway(runway,prefer)
return self
end
--- Set the active runway for landing.
-- @param #ATIS self
-- @param #string runway : Name of the runway, e.g. "31" or "02L" or "90R". If not given, the runway is determined from the wind direction.
-- @param #boolean preferleft : If true, perfer the left runway. If false, prefer the right runway. If nil (default), do not care about left or right.
-- @return #ATIS self
function ATIS:SetActiveRunwayLanding(runway, preferleft)
self.airbase:SetActiveRunwayLanding(runway,preferleft)
return self
end
--- Set the active runway for take-off.
-- @param #ATIS self
-- @param #string runway : Name of the runway, e.g. "31" or "02L" or "90R". If not given, the runway is determined from the wind direction.
-- @param #boolean preferleft : If true, perfer the left runway. If false, prefer the right runway. If nil (default), do not care about left or right.
-- @return #ATIS self
function ATIS:SetActiveRunwayTakeoff(runway,preferleft)
self.airbase:SetActiveRunwayTakeoff(runway,preferleft)
return self
end
@@ -802,6 +859,15 @@ function ATIS:SetRunwayLength()
return self
end
--- Give information on runway length.
-- @param #ATIS self
-- @return #ATIS self
function ATIS:SetRunwayLength()
self.rwylength=true
return self
end
--- Give information on airfield elevation
-- @param #ATIS self
-- @return #ATIS self
@@ -832,6 +898,13 @@ function ATIS:SetMapMarks( switch )
return self
end
--- Return the complete SRS Text block, if at least generated once. Else nil.
-- @param #ATIS self
-- @return #string SRSText
function ATIS:GetSRSText()
return self.SRSText
end
--- Set magnetic runway headings as depicted on the runway, *e.g.* "13" for 130° or "25L" for the left runway with magnetic heading 250°.
-- @param #ATIS self
-- @param #table headings Magnetic headings. Inverse (-180°) headings are added automatically. You only need to specify one heading per runway direction. "L"eft and "R" right can also be appended.
@@ -852,7 +925,7 @@ function ATIS:SetRunwayHeadingsMagnetic( headings )
end
-- Add runway heading to table.
self:I( self.lid .. string.format( "Adding user specified magnetic runway heading %s", heading ) )
self:T( self.lid .. string.format( "Adding user specified magnetic runway heading %s", heading ) )
table.insert( self.runwaymag, heading )
local h = self:GetRunwayWithoutLR( heading )
@@ -874,7 +947,7 @@ function ATIS:SetRunwayHeadingsMagnetic( headings )
end
-- Add inverse runway heading to table.
self:I( self.lid .. string.format( "Adding user specified magnetic runway heading %s (inverse)", head2 ) )
self:T( self.lid .. string.format( "Adding user specified magnetic runway heading %s (inverse)", head2 ) )
table.insert( self.runwaymag, head2 )
end
@@ -948,6 +1021,28 @@ function ATIS:SetAltimeterQNH( switch )
return self
end
--- Additionally report altimeter QNH/QFE in hPa, even if not set to metric.
-- @param #ATIS self
-- @param #boolean switch If true or nil, report mBar/hPa in addition.
-- @return #ATIS self
function ATIS:SetReportmBar(switch)
if switch == true or switch == nil then
self.ReportmBar = true
else
self.ReportmBar = false
end
return self
end
--- Additionally report free text, only working with SRS(!)
-- @param #ATIS self
-- @param #string text The text to report at the end of the ATIS message, e.g. runway closure, warnings, etc.
-- @return #ATIS self
function ATIS:SetAdditionalInformation(text)
self.AdditionalInformation = text
return self
end
--- Suppresses QFE readout. Default is to report both QNH and QFE.
-- @param #ATIS self
-- @return #ATIS self
@@ -971,7 +1066,7 @@ end
--
-- * 186° on the Caucaus map
-- * 192° on the Nevada map
-- * 170° on the Normany map
-- * 170° on the Normandy map
-- * 182° on the Persian Gulf map
--
-- Likewise, to convert *true* into *magnetic* heading, one has to substract easterly and add westerly variation.
@@ -979,7 +1074,7 @@ end
-- Or you make your life simple and just include the sign so you don't have to bother about East/West.
--
-- @param #ATIS self
-- @param #number magvar Magnetic variation in degrees. Positive for easterly and negative for westerly variation. Default is magnatic declinaton of the used map, c.f. @{Utilities.UTils#UTILS.GetMagneticDeclination}.
-- @param #number magvar Magnetic variation in degrees. Positive for easterly and negative for westerly variation. Default is magnatic declinaton of the used map, c.f. @{Utilities.Utils#UTILS.GetMagneticDeclination}.
-- @return #ATIS self
function ATIS:SetMagneticDeclination( magvar )
self.magvar = magvar or UTILS.GetMagneticDeclination()
@@ -1127,17 +1222,26 @@ end
-- @param #string Culture Culture, e.g. "en-GB" (default).
-- @param #string Voice Specific voice. Overrides `Gender` and `Culture`.
-- @param #number Port SRS port. Default 5002.
-- @param #string GoogleKey Path to Google JSON-Key.
-- @return #ATIS self
function ATIS:SetSRS( PathToSRS, Gender, Culture, Voice, Port )
self.useSRS = true
self.msrs = MSRS:New( PathToSRS, self.frequency, self.modulation )
self.msrs:SetGender( Gender )
self.msrs:SetCulture( Culture )
self.msrs:SetVoice( Voice )
self.msrs:SetPort( Port )
self.msrs:SetCoalition( self:GetCoalition() )
if self.dTQueueCheck <= 10 then
self:SetQueueUpdateTime( 90 )
function ATIS:SetSRS(PathToSRS, Gender, Culture, Voice, Port, GoogleKey)
if PathToSRS then
self.useSRS=true
self.msrs=MSRS:New(PathToSRS, self.frequency, self.modulation)
self.msrs:SetGender(Gender)
self.msrs:SetCulture(Culture)
self.msrs:SetVoice(Voice)
self.msrs:SetPort(Port)
self.msrs:SetCoalition(self:GetCoalition())
self.msrs:SetLabel("ATIS")
self.msrs:SetGoogle(GoogleKey)
self.msrsQ = MSRSQUEUE:New("ATIS")
self.msrsQ:SetTransmitOnlyWithPlayers(self.TransmitOnlyWithPlayers)
if self.dTQueueCheck<=10 then
self:SetQueueUpdateTime(90)
end
else
self:E(self.lid..string.format("ERROR: No SRS path specified!"))
end
return self
end
@@ -1170,40 +1274,49 @@ end
function ATIS:onafterStart( From, Event, To )
-- Check that this is an airdrome.
if self.airbase:GetAirbaseCategory() ~= Airbase.Category.AIRDROME then
self:E( self.lid .. string.format( "ERROR: Cannot start ATIS for airbase %s! Only AIRDROMES are supported but NOT FARPS or SHIPS.", self.airbasename ) )
if self.airbase:GetAirbaseCategory() == Airbase.Category.SHIP then
self:E( self.lid .. string.format( "ERROR: Cannot start ATIS for airbase %s! Only AIRDROMES are supported but NOT SHIPS.", self.airbasename ) )
return
end
-- Check that if is a Helipad.
if self.airbase:GetAirbaseCategory() == Airbase.Category.HELIPAD then
self:E( self.lid .. string.format( "EXPERIMENTAL: Starting ATIS for Helipad %s! SRS must be ON", self.airbasename ) )
self.ATISforFARPs = true
self.useSRS = true
end
-- Info.
self:I( self.lid .. string.format( "Starting ATIS v%s for airbase %s on %.3f MHz Modulation=%d", ATIS.version, self.airbasename, self.frequency, self.modulation ) )
-- Start radio queue.
self.radioqueue = RADIOQUEUE:New( self.frequency, self.modulation, string.format( "ATIS %s", self.airbasename ) )
if not self.useSRS then
self.radioqueue = RADIOQUEUE:New( self.frequency, self.modulation, string.format( "ATIS %s", self.airbasename ) )
-- Send coordinate is airbase coord.
self.radioqueue:SetSenderCoordinate( self.airbase:GetCoordinate() )
-- Send coordinate is airbase coord.
self.radioqueue:SetSenderCoordinate( self.airbase:GetCoordinate() )
-- Set relay unit if we have one.
self.radioqueue:SetSenderUnitName( self.relayunitname )
-- Set relay unit if we have one.
self.radioqueue:SetSenderUnitName( self.relayunitname )
-- Set radio power.
self.radioqueue:SetRadioPower( self.power )
-- Set radio power.
self.radioqueue:SetRadioPower( self.power )
-- Init numbers.
self.radioqueue:SetDigit( 0, ATIS.Sound.N0.filename, ATIS.Sound.N0.duration, self.soundpath )
self.radioqueue:SetDigit( 1, ATIS.Sound.N1.filename, ATIS.Sound.N1.duration, self.soundpath )
self.radioqueue:SetDigit( 2, ATIS.Sound.N2.filename, ATIS.Sound.N2.duration, self.soundpath )
self.radioqueue:SetDigit( 3, ATIS.Sound.N3.filename, ATIS.Sound.N3.duration, self.soundpath )
self.radioqueue:SetDigit( 4, ATIS.Sound.N4.filename, ATIS.Sound.N4.duration, self.soundpath )
self.radioqueue:SetDigit( 5, ATIS.Sound.N5.filename, ATIS.Sound.N5.duration, self.soundpath )
self.radioqueue:SetDigit( 6, ATIS.Sound.N6.filename, ATIS.Sound.N6.duration, self.soundpath )
self.radioqueue:SetDigit( 7, ATIS.Sound.N7.filename, ATIS.Sound.N7.duration, self.soundpath )
self.radioqueue:SetDigit( 8, ATIS.Sound.N8.filename, ATIS.Sound.N8.duration, self.soundpath )
self.radioqueue:SetDigit( 9, ATIS.Sound.N9.filename, ATIS.Sound.N9.duration, self.soundpath )
-- Init numbers.
self.radioqueue:SetDigit( 0, ATIS.Sound.N0.filename, ATIS.Sound.N0.duration, self.soundpath )
self.radioqueue:SetDigit( 1, ATIS.Sound.N1.filename, ATIS.Sound.N1.duration, self.soundpath )
self.radioqueue:SetDigit( 2, ATIS.Sound.N2.filename, ATIS.Sound.N2.duration, self.soundpath )
self.radioqueue:SetDigit( 3, ATIS.Sound.N3.filename, ATIS.Sound.N3.duration, self.soundpath )
self.radioqueue:SetDigit( 4, ATIS.Sound.N4.filename, ATIS.Sound.N4.duration, self.soundpath )
self.radioqueue:SetDigit( 5, ATIS.Sound.N5.filename, ATIS.Sound.N5.duration, self.soundpath )
self.radioqueue:SetDigit( 6, ATIS.Sound.N6.filename, ATIS.Sound.N6.duration, self.soundpath )
self.radioqueue:SetDigit( 7, ATIS.Sound.N7.filename, ATIS.Sound.N7.duration, self.soundpath )
self.radioqueue:SetDigit( 8, ATIS.Sound.N8.filename, ATIS.Sound.N8.duration, self.soundpath )
self.radioqueue:SetDigit( 9, ATIS.Sound.N9.filename, ATIS.Sound.N9.duration, self.soundpath )
-- Start radio queue.
self.radioqueue:Start( 1, 0.1 )
-- Start radio queue.
self.radioqueue:Start( 1, 0.1 )
end
-- Handle airbase capture
-- Handle events.
@@ -1239,9 +1352,11 @@ function ATIS:onafterStatus( From, Event, To )
else
text = text .. string.format( ", Relay unit=%s (alive=%s)", tostring( self.relayunitname ), relayunitstatus )
end
self:I( self.lid .. text )
self:__Status( -60 )
self:T( self.lid .. text )
if not self:Is("Stopped") then
self:__Status( -60 )
end
end
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
@@ -1269,9 +1384,11 @@ function ATIS:onafterCheckQueue( From, Event, To )
end
end
-- Check back in 5 seconds.
self:__CheckQueue( -math.abs( self.dTQueueCheck ) )
if not self:Is("Stopped") then
-- Check back in 5 seconds.
self:__CheckQueue( -math.abs( self.dTQueueCheck ) )
end
end
--- Broadcast ATIS radio message.
@@ -1319,6 +1436,9 @@ function ATIS:onafterBroadcast( From, Event, To )
end
local mBarqnh = qnh
local mBarqfe = qfe
-- Convert to inHg.
if self.PmmHg then
qfe = UTILS.hPa2mmHg( qfe )
@@ -1377,9 +1497,19 @@ function ATIS:onafterBroadcast( From, Event, To )
--------------
--- Runway ---
--------------
local runway, rwyLeft = self:GetActiveRunway()
local runwayLanding, rwyLandingLeft
local runwayTakeoff, rwyTakeoffLeft
if self.airbase:GetAirbaseCategory() == Airbase.Category.HELIPAD then
runwayLanding, rwyLandingLeft="PAD 01",false
runwayTakeoff, rwyTakeoffLeft="PAD 02",false
else
runwayLanding, rwyLandingLeft=self:GetActiveRunway()
runwayTakeoff, rwyTakeoffLeft=self:GetActiveRunway(true)
end
------------
--- Time ---
------------
@@ -1444,8 +1574,8 @@ function ATIS:onafterBroadcast( From, Event, To )
-- Convert to °F.
if self.TDegF then
temperature = UTILS.CelsiusToFahrenheit( temperature )
dewpoint = UTILS.CelsiusToFahrenheit( dewpoint )
temperature=UTILS.CelsiusToFahrenheit(temperature)
dewpoint=UTILS.CelsiusToFahrenheit(dewpoint)
end
local TEMPERATURE = string.format( "%d", math.abs( temperature ) )
@@ -1693,7 +1823,7 @@ function ATIS:onafterBroadcast( From, Event, To )
-- Airbase name
subtitle = string.format( "%s", self.airbasename )
if self.airbasename:find( "AFB" ) == nil and self.airbasename:find( "Airport" ) == nil and self.airbasename:find( "Airstrip" ) == nil and self.airbasename:find( "airfield" ) == nil and self.airbasename:find( "AB" ) == nil then
if (not self.ATISforFARPs) and self.airbasename:find( "AFB" ) == nil and self.airbasename:find( "Airport" ) == nil and self.airbasename:find( "Airstrip" ) == nil and self.airbasename:find( "airfield" ) == nil and self.airbasename:find( "AB" ) == nil then
subtitle = subtitle .. " Airport"
end
if not self.useSRS then
@@ -1740,10 +1870,10 @@ function ATIS:onafterBroadcast( From, Event, To )
end
-- Wind
-- Adding a space after each digit of WINDFROM to convert this to aviation-speak for TTS via SRS
-- Adding a space after each digit of WINDFROM to convert this to aviation-speak for TTS via SRS
if self.useSRS then
WINDFROM = string.gsub(WINDFROM,".", "%1 ")
end
end
if self.metric then
subtitle = string.format( "Wind from %s at %s m/s", WINDFROM, WINDSPEED )
else
@@ -1768,7 +1898,7 @@ function ATIS:onafterBroadcast( From, Event, To )
end
end
alltext = alltext .. ";\n" .. subtitle
-- Visibility
if self.metric then
subtitle = string.format( "Visibility %s km", VISIBILITY )
@@ -1785,7 +1915,8 @@ function ATIS:onafterBroadcast( From, Event, To )
end
end
alltext = alltext .. ";\n" .. subtitle
subtitle = ""
-- Weather phenomena
local wp = false
local wpsub = ""
@@ -1885,8 +2016,9 @@ function ATIS:onafterBroadcast( From, Event, To )
end
end
end
alltext = alltext .. ";\n" .. subtitle
alltext = alltext .. ";\n" .. subtitle
subtitle = ""
-- Temperature
if self.TDegF then
if temperature < 0 then
@@ -1915,7 +2047,7 @@ function ATIS:onafterBroadcast( From, Event, To )
end
end
alltext = alltext .. ";\n" .. subtitle
-- Dew point
if self.TDegF then
if dewpoint < 0 then
@@ -1967,6 +2099,15 @@ function ATIS:onafterBroadcast( From, Event, To )
end
end
end
if self.ReportmBar and not self.metric then
if self.qnhonly then
subtitle = string.format( "%s;\nAltimeter %d hPa", subtitle, mBarqnh )
else
subtitle = string.format( "%s;\nAltimeter: QNH %d, QFE %d hPa", subtitle, mBarqnh, mBarqfe)
end
end
local _ALTIMETER = subtitle
if not self.useSRS then
self:Transmission( ATIS.Sound.Altimeter, 1.0, subtitle )
@@ -2000,66 +2141,71 @@ function ATIS:onafterBroadcast( From, Event, To )
end
end
alltext = alltext .. ";\n" .. subtitle
local _RUNACT
-- Active runway.
local subtitle = string.format( "Active runway %s", runway )
if rwyLeft == true then
subtitle = subtitle .. " Left"
elseif rwyLeft == false then
subtitle = subtitle .. " Right"
end
local _RUNACT = subtitle
if not self.useSRS then
self:Transmission( ATIS.Sound.ActiveRunway, 1.0, subtitle )
self.radioqueue:Number2Transmission( runway )
if rwyLeft == true then
self:Transmission( ATIS.Sound.Left, 0.2 )
elseif rwyLeft == false then
self:Transmission( ATIS.Sound.Right, 0.2 )
if not self.ATISforFARPs then
-- Active runway.
if runwayLanding then
local subtitle=string.format("Active runway %s", runwayLanding)
if rwyLandingLeft==true then
subtitle=subtitle.." Left"
elseif rwyLandingLeft==false then
subtitle=subtitle.." Right"
end
end
end
alltext = alltext .. ";\n" .. subtitle
-- Runway length.
if self.rwylength then
local runact = self.airbase:GetActiveRunway( self.runwaym2t )
local length = runact.length
if not self.metric then
length = UTILS.MetersToFeet( length )
end
-- Length in thousands and hundrets of ft/meters.
local L1000, L0100 = self:_GetThousandsAndHundreds( length )
-- Subtitle.
local subtitle = string.format( "Runway length %d", length )
if self.metric then
subtitle = subtitle .. " meters"
else
subtitle = subtitle .. " feet"
end
-- Transmit.
_RUNACT = subtitle
if not self.useSRS then
self:Transmission( ATIS.Sound.RunwayLength, 1.0, subtitle )
if tonumber( L1000 ) > 0 then
self.radioqueue:Number2Transmission( L1000 )
self:Transmission( ATIS.Sound.Thousand, 0.1 )
end
if tonumber( L0100 ) > 0 then
self.radioqueue:Number2Transmission( L0100 )
self:Transmission( ATIS.Sound.Hundred, 0.1 )
end
if self.metric then
self:Transmission( ATIS.Sound.Meters, 0.1 )
else
self:Transmission( ATIS.Sound.Feet, 0.1 )
self:Transmission(ATIS.Sound.ActiveRunway, 1.0, subtitle)
self.radioqueue:Number2Transmission(runwayLanding)
if rwyLandingLeft==true then
self:Transmission(ATIS.Sound.Left, 0.2)
elseif rwyLandingLeft==false then
self:Transmission(ATIS.Sound.Right, 0.2)
end
end
alltext = alltext .. ";\n" .. subtitle
-- Runway length.
if self.rwylength then
local runact = self.airbase:GetActiveRunway( self.runwaym2t )
local length = runact.length
if not self.metric then
length = UTILS.MetersToFeet( length )
end
-- Length in thousands and hundrets of ft/meters.
local L1000, L0100 = self:_GetThousandsAndHundreds( length )
-- Subtitle.
local subtitle = string.format( "Runway length %d", length )
if self.metric then
subtitle = subtitle .. " meters"
else
subtitle = subtitle .. " feet"
end
-- Transmit.
if not self.useSRS then
self:Transmission( ATIS.Sound.RunwayLength, 1.0, subtitle )
if tonumber( L1000 ) > 0 then
self.radioqueue:Number2Transmission( L1000 )
self:Transmission( ATIS.Sound.Thousand, 0.1 )
end
if tonumber( L0100 ) > 0 then
self.radioqueue:Number2Transmission( L0100 )
self:Transmission( ATIS.Sound.Hundred, 0.1 )
end
if self.metric then
self:Transmission( ATIS.Sound.Meters, 0.1 )
else
self:Transmission( ATIS.Sound.Feet, 0.1 )
end
end
alltext = alltext .. ";\n" .. subtitle
end
end
-- Airfield elevation
if self.elevation then
@@ -2126,7 +2272,7 @@ function ATIS:onafterBroadcast( From, Event, To )
end
-- ILS
local ils = self:GetNavPoint( self.ils, runway, rwyLeft )
local ils=self:GetNavPoint(self.ils, runwayLanding, rwyLandingLeft)
if ils then
subtitle = string.format( "ILS frequency %.2f MHz", ils.frequency )
if not self.useSRS then
@@ -2144,7 +2290,7 @@ function ATIS:onafterBroadcast( From, Event, To )
end
-- Outer NDB
local ndb = self:GetNavPoint( self.ndbouter, runway, rwyLeft )
local ndb=self:GetNavPoint(self.ndbouter, runwayLanding, rwyLandingLeft)
if ndb then
subtitle = string.format( "Outer NDB frequency %.2f MHz", ndb.frequency )
if not self.useSRS then
@@ -2162,7 +2308,7 @@ function ATIS:onafterBroadcast( From, Event, To )
end
-- Inner NDB
local ndb = self:GetNavPoint( self.ndbinner, runway, rwyLeft )
local ndb=self:GetNavPoint(self.ndbinner, runwayLanding, rwyLandingLeft)
if ndb then
subtitle = string.format( "Inner NDB frequency %.2f MHz", ndb.frequency )
if not self.useSRS then
@@ -2201,7 +2347,7 @@ function ATIS:onafterBroadcast( From, Event, To )
-- TACAN
if self.tacan then
subtitle = string.format( "TACAN channel %dX Ray", self.tacan )
subtitle=string.format("TACAN channel %dX Ray", self.tacan)
if not self.useSRS then
self:Transmission( ATIS.Sound.TACANChannel, 1.0, subtitle )
self.radioqueue:Number2Transmission( tostring( self.tacan ), nil, 0.2 )
@@ -2221,7 +2367,7 @@ function ATIS:onafterBroadcast( From, Event, To )
end
-- PRMG
local ndb = self:GetNavPoint( self.prmg, runway, rwyLeft )
local ndb=self:GetNavPoint(self.prmg, runwayLanding, rwyLandingLeft)
if ndb then
subtitle = string.format( "PRMG channel %d", ndb.frequency )
if not self.useSRS then
@@ -2230,7 +2376,12 @@ function ATIS:onafterBroadcast( From, Event, To )
end
alltext = alltext .. ";\n" .. subtitle
end
-- additional info, if any
if self.useSRS and self.AdditionalInformation then
alltext = alltext .. ";\n"..self.AdditionalInformation
end
-- Advice on initial...
subtitle = string.format( "Advise on initial contact, you have information %s", NATO )
if not self.useSRS then
@@ -2271,6 +2422,8 @@ function ATIS:onafterReport( From, Event, To, Text )
local text = string.gsub( text, "mmHg", "millimeters of Mercury" )
local text = string.gsub( text, "hPa", "hectopascals" )
local text = string.gsub( text, "m/s", "meters per second" )
local text = string.gsub( text, "TACAN", "tackan" )
local text = string.gsub( text, "FARP", "farp" )
-- Replace ";" by "."
local text = string.gsub( text, ";", " . " )
@@ -2278,9 +2431,12 @@ function ATIS:onafterReport( From, Event, To, Text )
-- Debug output.
self:T( "SRS TTS: " .. text )
-- Play text-to-speech report.
self.msrs:PlayText( text )
-- Play text-to-speech report.
local duration = STTS.getSpeechTime(text,0.95)
self.msrsQ:NewTransmission(text,duration,self.msrs,nil,2)
--self.msrs:PlayText( text )
self.SRSText = text
end
end
@@ -2348,39 +2504,22 @@ end
--- Get active runway runway.
-- @param #ATIS self
-- @param #boolean Takeoff If `true`, get runway for takeoff. Default is for landing.
-- @return #string Active runway, e.g. "31" for 310 deg.
-- @return #boolean Use Left=true, Right=false, or nil.
function ATIS:GetActiveRunway()
local coord = self.airbase:GetCoordinate()
local height = coord:GetLandHeight()
-- Get wind direction and speed in m/s.
local windFrom, windSpeed = coord:GetWind( height + 10 )
-- Get active runway data based on wind direction.
local runact = self.airbase:GetActiveRunway( self.runwaym2t )
-- Active runway "31".
local runway = self:GetMagneticRunway( windFrom ) or runact.idx
-- Left or right in case there are two runways with the same heading.
local rwyLeft = nil
-- Check if user explicitly specified a runway.
if self.activerunway then
-- Get explicit runway heading if specified.
local runwayno = self:GetRunwayWithoutLR( self.activerunway )
if runwayno ~= "" then
runway = runwayno
end
-- Was "L"eft or "R"ight given?
rwyLeft = self:GetRunwayLR( self.activerunway )
function ATIS:GetActiveRunway(Takeoff)
local runway=nil --Wrapper.Airbase#AIRBASE.Runway
if Takeoff then
runway=self.airbase:GetActiveRunwayTakeoff()
else
runway=self.airbase:GetActiveRunwayLanding()
end
if runway then -- some ABs have NO runways, e.g. Syria Naqoura
return runway.name, runway.isLeft
else
return nil, nil
end
return runway, rwyLeft
end
--- Get runway from user supplied magnetic heading.
@@ -2446,7 +2585,7 @@ end
-- @return #string Runway heading without left or right, *e.g.* "31".
function ATIS:GetRunwayWithoutLR( runway )
local rwywo = runway:gsub( "%D+", "" )
-- self:I(string.format("FF runway=%s ==> rwywo=%s", runway, rwywo))
-- self:T(string.format("FF runway=%s ==> rwywo=%s", runway, rwywo))
return rwywo
end
File diff suppressed because it is too large Load Diff

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