Compare commits

..

60 Commits
2.7.7 ... 2.7.8

Author SHA1 Message Date
TommyC81
4a406604bd Core modules formatting (#1670)
* Update Fsm.lua

Code formatting and minor typo/documentation fixes.

* Update Goal.lua

Code formatting and minor typo/documentation fixes.

* Update Menu.lua

Code formatting and minor typo/documentation fixes.

* Update Message.lua

Code formatting and minor typo/documentation fixes.

* Update Report.lua

Code formatting and minor typo/documentation fixes.

* Update ScheduleDispatcher.lua

Code formatting and minor typo/documentation fixes.

* Update Scheduler.lua

Code formatting and minor typo/documentation fixes.

* Update Settings.lua

Code formatting and minor typo/documentation fixes.

* Update Spawn.lua

Code formatting and minor typo/documentation fixes.
2021-12-20 12:59:56 +01:00
TommyC81
55cee46a8d Core code formatting and typo fixes. (#1669)
* Update Beacon.lua

Code formatting and minor typo/text fixes.

* Update Database.lua

Code formatting and minor typo/text fixes.

* Update Event.lua

Code formatting and minor typo/text fixes.
2021-12-19 08:47:07 +01:00
TommyC81
607c52c0b7 Update CSAR.lua (#1665)
Code formatting and general typo/documentation fixes.
2021-12-17 09:07:32 +01:00
TommyC81
2694321256 Update CTLD.lua (#1666)
Code formatting. Minor typos and text fixes.
2021-12-17 09:07:24 +01:00
TommyC81
e8e790102a Update Base.lua (#1667)
Code Formatting. General whitespace and spelling.
2021-12-17 09:07:13 +01:00
Applevangelist
9c5561921b Noise reducing measures 2021-12-15 13:46:07 +01:00
Applevangelist
78fab9ab0c CSAR - make beacon length configureable 2021-12-14 09:50:34 +01:00
TommyC81
058c750bc6 Update Set.lua (#1663)
Additional minor code formatting and typo fixes.
2021-12-13 16:52:01 +01:00
Applevangelist
f29da39dff CSAR - override suppressmessages for menu driven information 2021-12-12 19:48:36 +01:00
Applevangelist
624a7c70c9 CTLD - corrected landheight of dropped smoke 2021-12-12 19:30:33 +01:00
TommyC81
0447ee2d9e Update Airboss.lua (#1664)
Code formatting. Typo fixing.
2021-12-12 19:15:30 +01:00
TommyC81
456fcd38d0 Code and documentation tweaks. (#1662)
* Update Point.lua

General code formatting.

* Update Set.lua

General code formatting.

* Update Positionable.lua

Code formatting, and documentation fixes.
2021-12-12 13:53:04 +01:00
Applevangelist
a3cab7097a SET - Typos 2021-12-11 19:41:02 +01:00
Applevangelist
848e2f1294 SET - Added Zone Filter for STATIC 2021-12-11 14:24:20 +01:00
Applevangelist
ef4dc48ea1 CTLD - added option for smoke/flare at position 2021-12-11 14:14:44 +01:00
Applevangelist
2138a33292 CSAR fixed KM message 2021-12-10 12:02:50 +01:00
TommyC81
a59343b987 Code formatting, spelling and documentation fixes. (#1661)
* Update Point.lua

Minor code formatting fix.

* Update Airboss.lua

Minor code formatting and documentation fixes.

* Update Set.lua

Code formatting, spelling and documentation fixes.

* Update ATIS.lua

Code formatting, spelling and documentation fixes.

* Update Task_A2A_Dispatcher.lua

Minor code formatting and documentation fixes. Added TODO re. possible unused variables.
2021-12-09 17:51:38 +01:00
TommyC81
a4ca4bdc99 Code and documentation fixes (#1659)
* Update .lua-format

Adjust for observed coding standards.

* Update ATIS.lua

Correct measurement units and spelling (also changed in Utils.lua).

* Update Utils.lua

Format the file, fix typos, adjust minor text. Rename "celcius" to "celsius". Rename "farenheit" to "fahrenheit".

* Update Warehouse.lua

Adjust measurement unit text.

* Update STTS.lua

Adjust formatting, minor typos, and fix error in documentation (missing blank rows) introduced in previous update.

* Update Range.lua

Adjust minor typos and code formatting. Adjust for celsius/fahrenheit typo correction.

* Update PseudoATC.lua

Adjust for celsius/fahrenheit typo correction in utils.lua.

* Update Point.lua

Code formatting, fix minor typos, adjust for celsius/fahrenheit corrrection in utils.lua.

* Update Range.lua

Minor documentation fix.
2021-12-08 19:52:29 +01:00
TommyC81
a57b9a9081 Update Range.lua (#1658)
Adjust some minor spelling and figure out the quirks of luadocumentor...
2021-12-07 18:13:51 +01:00
Applevangelist
249a6af456 Some false values seem to be in need of being set explicitly 2021-12-06 15:16:01 +01:00
Applevangelist
18685d1a94 Update Utils.lua (#1655)
Small bugfix for UTILS.LoadSetOfGroups
2021-12-06 14:57:49 +01:00
TommyC81
493b090534 LuaFormatter, RANGE formatting, and minor code fixes. (#1653)
* Create .lua-format

* Update Range.lua

Format code.

* Display distance in meters from bombtarget.

All other numbers, including menu lists etc. uses meters. Feet kept in parens.

* Fixed displaying of targetname when bombing.
2021-12-06 14:57:36 +01:00
Applevangelist
389adab9b8 SET - slight change to remove function 2021-12-06 10:26:32 +01:00
TommyC81
6360b8c58f General documentation and code fixes (#1650)
Documentation updates for correctness and clarity.
General code formatting updates.
Ajustment to POSITIONABLE:GetCoord to make use of existing POINT:UpdateFromVec3.
Added comments about clarifying the difference between POSITIONABLE:GetCoordinate() and POSITIONABLE:GetCoord() and to perhaps consider a renaming or merging the functions with an optional flag.
2021-12-04 18:50:05 +01:00
TommyC81
b0818977cf Code formatting. (#1651)
General code formatting and fixes of minor typos.
2021-12-04 18:49:57 +01:00
TommyC81
32deb160ef Formatting and typos (#1652)
* Formatting and typo fixes.

General formatting and typo fixes.

* Update STTS.lua

Keep class table on separate lines.
2021-12-04 18:49:47 +01:00
Applevangelist
2ba5215036 Merge pull request #1649 from TommyC81/RANGE_FIXES
Update Range.lua
2021-12-02 19:25:42 +01:00
Tommy Carlsson
73ea4c7b32 Update Range.lua
Fix documentation - including typos and updates to no longer correct text.
Remove duplicated RANGE.Defaults.goodthitrange value.
DCS seems to use headings 0-359 (i.e. <360), thus also deduct 360 from an exact 360 heading.
2021-12-02 20:49:48 +04:00
Applevangelist
46c37ff06a Merge pull request #1648 from TommyC81/A2G_DISPATCHER_FIXES
Update AI_A2G_Dispatcher.lua
2021-12-01 11:54:56 +01:00
Tommy Carlsson
ff4708b624 Update AI_A2G_Dispatcher.lua
General code formatting fixes, and correction of typos/examples.
2021-12-01 13:41:27 +04:00
Applevangelist
82b2c84f13 Merge pull request #1647 from TommyC81/A2G_DISPATCHER_DOCUMENTATION_2
Update AI_A2G_Dispatcher.lua
2021-12-01 09:17:46 +01:00
Tommy Carlsson
48e8b1a9b3 Update AI_A2G_Dispatcher.lua
More updates and fixes.

Update AI_A2G_Dispatcher.lua

General documentation updates.
2021-12-01 11:34:18 +04:00
Applevangelist
1ad7c54ace Merge pull request #1645 from TommyC81/A2G_Dispatcher_documentation
Update AI_A2G_Dispatcher.lua
2021-11-30 17:02:40 +01:00
Tommy Carlsson
9998c86c1f Update AI_A2G_Dispatcher.lua
Fix typos and incorrect references (leftovers) to A2A/CAP etc.
2021-11-30 19:37:26 +04:00
Applevangelist
01a707ae0a Small changes in GROUP 2021-11-29 07:57:07 +01:00
Applevangelist
570e8388fc Bug fixes 2021-11-27 17:30:25 +01:00
Applevangelist
9c5b5d4633 CSAR - added changes by Shagrat for Casevac
CSAR - don't make usePara default. Added coalition check if using the parachute landing event
2021-11-14 13:34:23 +01:00
Applevangelist
822bf13626 Merge pull request #1625 from FlightControl-Master/Applevangelist-unit-1
Wrapper Unit - fix for missile count
2021-11-14 12:59:51 +01:00
Applevangelist
c520de0087 Wrapper Unit - fix for missile count
Wrapper Unit - fix for missile count, issue #1624
2021-11-14 12:57:00 +01:00
Applevangelist
0e9076efa3 SEAD - align to dev changes, allow callback on SEAD events 2021-11-11 16:02:13 +01:00
Applevangelist
74cd5e3387 MANTIS - added docu and addition os SEAD events 2021-11-11 16:02:13 +01:00
Applevangelist
65c92be09e Merge pull request #1621 from FlightControl-Master/Applevangelist-casevac
Update CSAR.lua
2021-11-06 15:30:15 +01:00
Applevangelist
8e776cb3ab Update CSAR.lua
Adding CASEVAC option by Shagrat
2021-11-06 15:29:09 +01:00
Applevangelist
ab6cd2b751 Fix cleanup exisiting crates 2021-10-31 11:51:31 +01:00
Applevangelist
18c3d990fc Merge pull request #1618 from rollnthndr/master
Enabled SSML when using Google text-to-speech.
2021-10-31 08:15:25 +01:00
Rolln
19d5cb8ecb Added a command line option that will enable
SSML support when using Google text-to-speech.
2021-10-30 23:35:27 -06:00
Applevangelist
2b56a78255 Merge pull request #1617 from Penecruz/master
Airboss V/STOL updates
2021-10-30 22:05:21 +02:00
Penecruz
176d9df476 Merge branch 'FlightControl-Master:master' into master 2021-10-31 06:59:50 +11:00
Penecruz
c94275cb8b Airboss V/STOL updates
-Add additional Airboss V/STOL carrier HMAS Canberra L02
-Add Waveoff for AV-8B
-Add Cut Pass if Land without LSO clearance
-Changes to V/STOL groove timings
-Stabilise call when over the V/STOL landing spot
-larger abeam landing spot margin to allow decelerating to stable abeam and still be cleared to land
-Abeam area now extends further aft to allow LSO clearance 45-90 as per NATOPS
-Minor document changes
2021-10-31 06:41:58 +11:00
Applevangelist
45dbce3677 Speedmax returning 0 not nil 2021-10-30 16:33:18 +02:00
Applevangelist
18745158a3 Speedmax returning 0 not nil 2021-10-30 16:33:14 +02:00
Applevangelist
98c6c88391 Completed GetSetComplement 2021-10-29 18:32:13 +02:00
Frank
2e4fd72781 Update Fox.lua
Removed incomplete line `--@field #boolean`
2021-10-28 10:18:43 +02:00
Applevangelist
80ced88ef1 Fix for docs build 2021-10-28 08:31:14 +02:00
Applevangelist
8af3f89c14 Adjustments for Forrestal by Pene 2021-10-24 14:35:55 +02:00
Applevangelist
fe3079caad Added Bell-47 2021-10-22 17:04:23 +02:00
Applevangelist
61ac6b4131 Added Bell-47 2021-10-22 17:04:19 +02:00
Frank
36cb189512 Merge pull request #1612 from FlightControl-Master/FF/MasterDevel
AIRBOSS v1.2.0
2021-10-20 19:55:19 +02:00
Frank
15f9843878 AIRBOSS v1.2.0
- Added Forrestal carrier CV-59
2021-10-16 12:11:34 +02:00
Frank
67f847dd16 Update Group.lua
- Fixed SetInvisible and SetImmortal functions to acknowledge parameter false.
2021-10-12 22:16:18 +02:00
43 changed files with 23064 additions and 22654 deletions

View File

@@ -0,0 +1,33 @@
# 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

File diff suppressed because it is too large Load Diff

View File

@@ -585,7 +585,7 @@ function AI_AIR:onafterRTB( AIGroup, From, Event, To )
if AIGroup and AIGroup:IsAlive() then if AIGroup and AIGroup:IsAlive() then
self:I( "Group " .. AIGroup:GetName() .. " ... RTB! ( " .. self:GetState() .. " )" ) self:T( "Group " .. AIGroup:GetName() .. " ... RTB! ( " .. self:GetState() .. " )" )
self:ClearTargetDistance() self:ClearTargetDistance()
--AIGroup:ClearTasks() --AIGroup:ClearTasks()

View File

@@ -7,7 +7,7 @@
-- * The construction and inheritance of MOOSE classes. -- * The construction and inheritance of MOOSE classes.
-- * The class naming and numbering system. -- * The class naming and numbering system.
-- * The class hierarchy search system. -- * The class hierarchy search system.
-- * The tracing of information or objects during mission execution for debuggin purposes. -- * The tracing of information or objects during mission execution for debugging purposes.
-- * The subscription to DCS events for event handling in MOOSE objects. -- * The subscription to DCS events for event handling in MOOSE objects.
-- * Object inspection. -- * Object inspection.
-- --
@@ -49,7 +49,8 @@ local _ClassID = 0
-- # 2. Trace information for debugging. -- # 2. Trace information for debugging.
-- --
-- The BASE class contains trace methods to trace progress within a mission execution of a certain object. -- The BASE class contains trace methods to trace progress within a mission execution of a certain object.
-- These trace methods are inherited by each MOOSE class interiting BASE, soeach object created from derived class from BASE can use the tracing methods to trace its execution. -- These trace methods are inherited by each MOOSE class inheriting BASE, thus all objects created from
-- a class derived from BASE can use the tracing methods to trace its execution.
-- --
-- Any type of information can be passed to these tracing methods. See the following examples: -- Any type of information can be passed to these tracing methods. See the following examples:
-- --
@@ -111,7 +112,6 @@ local _ClassID = 0
-- --
-- The method @{#BASE.IsTrace}() will validate if tracing is activated or not. -- The method @{#BASE.IsTrace}() will validate if tracing is activated or not.
-- --
--
-- # 3. DCS simulator Event Handling. -- # 3. DCS simulator Event Handling.
-- --
-- The BASE class provides methods to catch DCS Events. These are events that are triggered from within the DCS simulator, -- The BASE class provides methods to catch DCS Events. These are events that are triggered from within the DCS simulator,
@@ -157,8 +157,6 @@ local _ClassID = 0
-- self:SmokeBlue() -- self:SmokeBlue()
-- end -- end
-- --
--
--
-- See the @{Event} module for more information about event handling. -- See the @{Event} module for more information about event handling.
-- --
-- # 4. Class identification methods. -- # 4. Class identification methods.
@@ -203,13 +201,12 @@ BASE = {
Scheduler = nil, Scheduler = nil,
} }
--- @field #BASE.__ --- @field #BASE.__
BASE.__ = {} BASE.__ = {}
--- @field #BASE._ --- @field #BASE._
BASE._ = { BASE._ = {
Schedules = {} --- Contains the Schedulers Active Schedules = {}, --- Contains the Schedulers Active
} }
--- The Formation Class --- The Formation Class
@@ -217,11 +214,9 @@ BASE._ = {
-- @field Cone A cone formation. -- @field Cone A cone formation.
FORMATION = { FORMATION = {
Cone = "Cone", Cone = "Cone",
Vee = "Vee" Vee = "Vee",
} }
--- BASE constructor. --- BASE constructor.
-- --
-- This is an example how to use the BASE:New() constructor in a new class definition when inheriting from BASE. -- This is an example how to use the BASE:New() constructor in a new class definition when inheriting from BASE.
@@ -275,7 +270,6 @@ function BASE:Inherit( Child, Parent )
return Child return Child
end end
local function getParent( Child ) local function getParent( Child )
local Parent = nil local Parent = nil
@@ -291,7 +285,6 @@ local function getParent( Child )
return Parent return Parent
end end
--- This is the worker method to retrieve the Parent class. --- This is the worker method to retrieve the Parent class.
-- Note that the Parent class must be passed to call the parent class method. -- Note that the Parent class must be passed to call the parent class method.
-- --
@@ -304,7 +297,6 @@ end
-- @return #BASE -- @return #BASE
function BASE:GetParent( Child, FromClass ) function BASE:GetParent( Child, FromClass )
local Parent local Parent
-- BASE class has no parent -- BASE class has no parent
if Child.ClassName == 'BASE' then if Child.ClassName == 'BASE' then
@@ -419,7 +411,6 @@ do -- Event Handling
return _EVENTDISPATCHER return _EVENTDISPATCHER
end end
--- Get the Class @{Event} processing Priority. --- Get the Class @{Event} processing Priority.
-- The Event processing Priority is a number from 1 to 10, -- The Event processing Priority is a number from 1 to 10,
-- reflecting the order of the classes subscribed to the Event to be processed. -- reflecting the order of the classes subscribed to the Event to be processed.
@@ -480,29 +471,29 @@ do -- Event Handling
-- @param Core.Event#EVENTDATA EventData The EventData structure. -- @param Core.Event#EVENTDATA EventData The EventData structure.
--- Occurs whenever an object is hit by a weapon. --- Occurs whenever an object is hit by a weapon.
-- initiator : The unit object the fired the weapon -- initiator : The unit object the fired the weapon.
-- weapon: Weapon object that hit the target -- weapon: Weapon object that hit the target.
-- target: The Object that was hit. -- target: The Object that was hit.
-- @function [parent=#BASE] OnEventHit -- @function [parent=#BASE] OnEventHit
-- @param #BASE self -- @param #BASE self
-- @param Core.Event#EVENTDATA EventData The EventData structure. -- @param Core.Event#EVENTDATA EventData The EventData structure.
--- Occurs when an aircraft takes off from an airbase, farp, or ship. --- Occurs when an aircraft takes off from an airbase, farp, or ship.
-- initiator : The unit that tookoff -- initiator : The unit that took off.
-- place: Object from where the AI took-off from. Can be an Airbase Object, FARP, or Ships -- place: Object from where the AI took-off from. Can be an Airbase Object, FARP, or Ships.
-- @function [parent=#BASE] OnEventTakeoff -- @function [parent=#BASE] OnEventTakeoff
-- @param #BASE self -- @param #BASE self
-- @param Core.Event#EVENTDATA EventData The EventData structure. -- @param Core.Event#EVENTDATA EventData The EventData structure.
--- Occurs when an aircraft lands at an airbase, farp or ship --- Occurs when an aircraft lands at an airbase, farp or ship
-- initiator : The unit that has landed -- initiator : The unit that has landed.
-- place: Object that the unit landed on. Can be an Airbase Object, FARP, or Ships -- place: Object that the unit landed on. Can be an Airbase Object, FARP, or Ships.
-- @function [parent=#BASE] OnEventLand -- @function [parent=#BASE] OnEventLand
-- @param #BASE self -- @param #BASE self
-- @param Core.Event#EVENTDATA EventData The EventData structure. -- @param Core.Event#EVENTDATA EventData The EventData structure.
--- Occurs when any aircraft crashes into the ground and is completely destroyed. --- Occurs when any aircraft crashes into the ground and is completely destroyed.
-- initiator : The unit that has crashed -- initiator : The unit that has crashed.
-- @function [parent=#BASE] OnEventCrash -- @function [parent=#BASE] OnEventCrash
-- @param #BASE self -- @param #BASE self
-- @param Core.Event#EVENTDATA EventData The EventData structure. -- @param Core.Event#EVENTDATA EventData The EventData structure.
@@ -538,18 +529,18 @@ do -- Event Handling
-- @param Core.Event#EVENTDATA EventData The EventData structure. -- @param Core.Event#EVENTDATA EventData The EventData structure.
--- Occurs when a ground unit captures either an airbase or a farp. --- Occurs when a ground unit captures either an airbase or a farp.
-- initiator : The unit that captured the base -- 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. -- 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 -- @function [parent=#BASE] OnEventBaseCaptured
-- @param #BASE self -- @param #BASE self
-- @param Core.Event#EVENTDATA EventData The EventData structure. -- @param Core.Event#EVENTDATA EventData The EventData structure.
--- Occurs when a mission starts --- Occurs when a mission starts.
-- @function [parent=#BASE] OnEventMissionStart -- @function [parent=#BASE] OnEventMissionStart
-- @param #BASE self -- @param #BASE self
-- @param Core.Event#EVENTDATA EventData The EventData structure. -- @param Core.Event#EVENTDATA EventData The EventData structure.
--- Occurs when a mission ends --- Occurs when a mission ends.
-- @function [parent=#BASE] OnEventMissionEnd -- @function [parent=#BASE] OnEventMissionEnd
-- @param #BASE self -- @param #BASE self
-- @param Core.Event#EVENTDATA EventData The EventData structure. -- @param Core.Event#EVENTDATA EventData The EventData structure.
@@ -561,25 +552,25 @@ do -- Event Handling
-- @param Core.Event#EVENTDATA EventData The EventData structure. -- @param Core.Event#EVENTDATA EventData The EventData structure.
--- Occurs when any object is spawned into the mission. --- Occurs when any object is spawned into the mission.
-- initiator : The unit that was spawned -- initiator : The unit that was spawned.
-- @function [parent=#BASE] OnEventBirth -- @function [parent=#BASE] OnEventBirth
-- @param #BASE self -- @param #BASE self
-- @param Core.Event#EVENTDATA EventData The EventData structure. -- @param Core.Event#EVENTDATA EventData The EventData structure.
--- Occurs when any system fails on a human controlled aircraft. --- Occurs when any system fails on a human controlled aircraft.
-- initiator : The unit that had the failure -- initiator : The unit that had the failure.
-- @function [parent=#BASE] OnEventHumanFailure -- @function [parent=#BASE] OnEventHumanFailure
-- @param #BASE self -- @param #BASE self
-- @param Core.Event#EVENTDATA EventData The EventData structure. -- @param Core.Event#EVENTDATA EventData The EventData structure.
--- Occurs when any aircraft starts its engines. --- Occurs when any aircraft starts its engines.
-- initiator : The unit that is starting its engines. -- initiator : The unit that is starting its engines..
-- @function [parent=#BASE] OnEventEngineStartup -- @function [parent=#BASE] OnEventEngineStartup
-- @param #BASE self -- @param #BASE self
-- @param Core.Event#EVENTDATA EventData The EventData structure. -- @param Core.Event#EVENTDATA EventData The EventData structure.
--- Occurs when any aircraft shuts down its engines. --- Occurs when any aircraft shuts down its engines.
-- initiator : The unit that is stopping its engines. -- initiator : The unit that is stopping its engines..
-- @function [parent=#BASE] OnEventEngineShutdown -- @function [parent=#BASE] OnEventEngineShutdown
-- @param #BASE self -- @param #BASE self
-- @param Core.Event#EVENTDATA EventData The EventData structure. -- @param Core.Event#EVENTDATA EventData The EventData structure.
@@ -627,7 +618,6 @@ do -- Event Handling
-- @param #BASE self -- @param #BASE self
-- @param Core.Event#EVENTDATA EventData The EventData structure. -- @param Core.Event#EVENTDATA EventData The EventData structure.
--- Unknown precisely what creates this event, likely tied into newer damage model. Will update this page when new information become available. --- Unknown precisely what creates this event, likely tied into newer damage model. Will update this page when new information become available.
-- --
-- * initiator: The unit that had the failure. -- * initiator: The unit that had the failure.
@@ -644,7 +634,7 @@ do -- Event Handling
--- 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. --- 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 -- * initiator: The unit that killed the target.
-- * target: Target Object -- * target: Target Object
-- * weapon: Weapon Object -- * weapon: Weapon Object
-- --
@@ -706,7 +696,6 @@ do -- Event Handling
-- @param #BASE self -- @param #BASE self
-- @param Core.Event#EVENTDATA EventData The EventData structure. -- @param Core.Event#EVENTDATA EventData The EventData structure.
--- Occurs when a player enters a slot and takes control of an aircraft. --- 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. -- **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. -- initiator : The unit that is being taken control of.
@@ -716,7 +705,6 @@ do -- Event Handling
end end
--- Creation of a Birth Event. --- Creation of a Birth Event.
-- @param #BASE self -- @param #BASE self
-- @param DCS#Time EventTime The time stamp of the event. -- @param DCS#Time EventTime The time stamp of the event.
@@ -733,7 +721,7 @@ function BASE:CreateEventBirth( EventTime, Initiator, IniUnitName, place, subpla
initiator = Initiator, initiator = Initiator,
IniUnitName = IniUnitName, IniUnitName = IniUnitName,
place = place, place = place,
subplace = subplace subplace = subplace,
} }
world.onEvent( Event ) world.onEvent( Event )
@@ -812,7 +800,7 @@ end
local Event = { local Event = {
id = EVENTS.PlayerEnterAircraft, id = EVENTS.PlayerEnterAircraft,
time = timer.getTime(), time = timer.getTime(),
initiator = PlayerUnit:GetDCSObject() initiator = PlayerUnit:GetDCSObject(),
} }
world.onEvent( Event ) world.onEvent( Event )
@@ -938,9 +926,8 @@ do -- Scheduling
end end
--- Set a state or property of the Object given a Key and a Value. --- Set a state or property of the Object given a Key and a Value.
-- Note that if the Object is destroyed, nillified or garbage collected, then the Values and Keys will also be gone. -- Note that if the Object is destroyed, set to nil, or garbage collected, then the Values and Keys will also be gone.
-- @param #BASE self -- @param #BASE self
-- @param Object The object that will hold the Value set by the Key. -- @param Object The object that will hold the Value set by the Key.
-- @param Key The key that is used as a reference of the value. Note that the key can be a #string, but it can also be any other type! -- @param Key The key that is used as a reference of the value. Note that the key can be a #string, but it can also be any other type!
@@ -956,9 +943,8 @@ function BASE:SetState( Object, Key, Value )
return self.States[ClassNameAndID][Key] return self.States[ClassNameAndID][Key]
end end
--- Get a Value given a Key from the Object. --- Get a Value given a Key from the Object.
-- Note that if the Object is destroyed, nillified or garbage collected, then the Values and Keys will also be gone. -- Note that if the Object is destroyed, set to nil, or garbage collected, then the Values and Keys will also be gone.
-- @param #BASE self -- @param #BASE self
-- @param Object The object that holds the Value set by the Key. -- @param Object The object that holds the Value set by the Key.
-- @param Key The key that is used to retrieve the value. Note that the key can be a #string, but it can also be any other type! -- @param Key The key that is used to retrieve the value. Note that the key can be a #string, but it can also be any other type!
@@ -1010,8 +996,6 @@ function BASE:TraceOff()
self:TraceOnOff( false ) self:TraceOnOff( false )
end end
--- Set trace on or off --- Set trace on or off
-- Note that when trace is off, no BASE.Debug statement is performed, increasing performance! -- Note that when trace is off, no BASE.Debug statement is performed, increasing performance!
-- When Moose is loaded statically, (as one file), tracing is switched off by default. -- When Moose is loaded statically, (as one file), tracing is switched off by default.
@@ -1020,11 +1004,13 @@ end
-- @param #BASE self -- @param #BASE self
-- @param #boolean TraceOnOff Switch the tracing on or off. -- @param #boolean TraceOnOff Switch the tracing on or off.
-- @usage -- @usage
--
-- -- Switch the tracing On -- -- Switch the tracing On
-- BASE:TraceOnOff( true ) -- BASE:TraceOnOff( true )
-- --
-- -- Switch the tracing Off -- -- Switch the tracing Off
-- BASE:TraceOnOff( false ) -- BASE:TraceOnOff( false )
--
function BASE:TraceOnOff( TraceOnOff ) function BASE:TraceOnOff( TraceOnOff )
if TraceOnOff == false then if TraceOnOff == false then
self:I( "Tracing in MOOSE is OFF" ) self:I( "Tracing in MOOSE is OFF" )
@@ -1035,7 +1021,6 @@ function BASE:TraceOnOff( TraceOnOff )
end end
end end
--- Enquires if tracing is on (for the class). --- Enquires if tracing is on (for the class).
-- @param #BASE self -- @param #BASE self
-- @return #boolean -- @return #boolean
@@ -1140,7 +1125,6 @@ function BASE:F( Arguments )
end end
end end
--- Trace a function call level 2. Must be at the beginning of the function logic. --- Trace a function call level 2. Must be at the beginning of the function logic.
-- @param #BASE self -- @param #BASE self
-- @param Arguments A #table or any field. -- @param Arguments A #table or any field.
@@ -1215,7 +1199,6 @@ function BASE:T( Arguments )
end end
end end
--- Trace a function logic level 2. Can be anywhere within the function logic. --- Trace a function logic level 2. Can be anywhere within the function logic.
-- @param #BASE self -- @param #BASE self
-- @param Arguments A #table or any field. -- @param Arguments A #table or any field.
@@ -1273,7 +1256,6 @@ function BASE:E( Arguments )
end end
--- Log an information which will be traced always. Can be anywhere within the function logic. --- Log an information which will be traced always. Can be anywhere within the function logic.
-- @param #BASE self -- @param #BASE self
-- @param Arguments A #table or any field. -- @param Arguments A #table or any field.
@@ -1301,8 +1283,6 @@ function BASE:I( Arguments )
end end
--- old stuff --- old stuff
-- function BASE:_Destructor() -- function BASE:_Destructor()
@@ -1311,7 +1291,6 @@ end
-- --self:EventRemoveAll() -- --self:EventRemoveAll()
-- end -- end
-- THIS IS WHY WE NEED LUA 5.2 ... -- THIS IS WHY WE NEED LUA 5.2 ...
-- function BASE:_SetDestructor() -- function BASE:_SetDestructor()
-- --

View File

@@ -95,7 +95,7 @@ BEACON.Type={
-- @field #number TACAN TACtical Air Navigation system on ground. -- @field #number TACAN TACtical Air Navigation system on ground.
-- @field #number TACAN_TANKER_X TACtical Air Navigation system for tankers on X band. -- @field #number TACAN_TANKER_X TACtical Air Navigation system for tankers on X band.
-- @field #number TACAN_TANKER_Y TACtical Air Navigation system for tankers on Y band. -- @field #number TACAN_TANKER_Y TACtical Air Navigation system for tankers on Y band.
-- @field #number VOR Very High Frequency Omni-Directional Range -- @field #number VOR Very High Frequency Omnidirectional Range
-- @field #number ILS_LOCALIZER ILS localizer -- @field #number ILS_LOCALIZER ILS localizer
-- @field #number ILS_GLIDESLOPE ILS glide slope. -- @field #number ILS_GLIDESLOPE ILS glide slope.
-- @field #number PRGM_LOCALIZER PRGM localizer. -- @field #number PRGM_LOCALIZER PRGM localizer.
@@ -131,7 +131,7 @@ BEACON.System={
-- If you want to create a BEACON, you probably should use @{Wrapper.Positionable#POSITIONABLE.GetBeacon}() instead. -- If you want to create a BEACON, you probably should use @{Wrapper.Positionable#POSITIONABLE.GetBeacon}() instead.
-- @param #BEACON self -- @param #BEACON self
-- @param Wrapper.Positionable#POSITIONABLE Positionable The @{Positionable} that will receive radio capabilities. -- @param Wrapper.Positionable#POSITIONABLE Positionable The @{Positionable} that will receive radio capabilities.
-- @return #BEACON Beacon object or #nil if the positionable is invalid. -- @return #BEACON Beacon object or #nil if the POSITIONABLE is invalid.
function BEACON:New( Positionable ) function BEACON:New( Positionable )
-- Inherit BASE. -- Inherit BASE.
@@ -141,18 +141,17 @@ function BEACON:New(Positionable)
self:F( Positionable ) self:F( Positionable )
-- Set positionable. -- Set positionable.
if Positionable:GetPointVec2() then -- It's stupid, but the only way I found to make sure positionable is valid if Positionable:GetPointVec2() then -- It's stupid, but the only way I found to make sure POSITIONABLE is valid
self.Positionable = Positionable self.Positionable = Positionable
self.name = Positionable:GetName() self.name = Positionable:GetName()
self:I( string.format( "New BEACON %s", tostring( self.name ) ) ) self:I( string.format( "New BEACON %s", tostring( self.name ) ) )
return self return self
end end
self:E({"The passed positionable is invalid, no BEACON created", Positionable}) self:E( { "The passed POSITIONABLE is invalid, no BEACON created", Positionable } )
return nil return nil
end end
--- Activates a TACAN BEACON. --- Activates a TACAN BEACON.
-- @param #BEACON self -- @param #BEACON self
-- @param #number Channel TACAN channel, i.e. the "10" part in "10Y". -- @param #number Channel TACAN channel, i.e. the "10" part in "10Y".
@@ -162,11 +161,13 @@ end
-- @param #number Duration How long will the beacon last in seconds. Omit for forever. -- @param #number Duration How long will the beacon last in seconds. Omit for forever.
-- @return #BEACON self -- @return #BEACON self
-- @usage -- @usage
--
-- -- Let's create a TACAN Beacon for a tanker -- -- Let's create a TACAN Beacon for a tanker
-- local myUnit = UNIT:FindByName("MyUnit") -- local myUnit = UNIT:FindByName("MyUnit")
-- local myBeacon = myUnit:GetBeacon() -- Creates the beacon -- local myBeacon = myUnit:GetBeacon() -- Creates the beacon
-- --
-- myBeacon:ActivateTACAN(20, "Y", "TEXACO", true) -- Activate the beacon -- myBeacon:ActivateTACAN(20, "Y", "TEXACO", true) -- Activate the beacon
--
function BEACON:ActivateTACAN( Channel, Mode, Message, Bearing, Duration ) function BEACON:ActivateTACAN( Channel, Mode, Message, Bearing, Duration )
self:T( { channel = Channel, mode = Mode, callsign = Message, bearing = Bearing, duration = Duration } ) self:T( { channel = Channel, mode = Mode, callsign = Message, bearing = Bearing, duration = Duration } )
@@ -191,7 +192,7 @@ function BEACON:ActivateTACAN(Channel, Mode, Message, Bearing, Duration)
System = 5 -- NOTE: 5 is how you cat the correct tanker behaviour! --BEACON.System.TACAN_TANKER System = 5 -- NOTE: 5 is how you cat the correct tanker behaviour! --BEACON.System.TACAN_TANKER
-- Check if "Y" mode is selected for aircraft. -- Check if "Y" mode is selected for aircraft.
if Mode ~= "Y" then if Mode ~= "Y" then
self:E({"WARNING: The POSITIONABLE you want to attach the AA Tacan Beacon is an aircraft: Mode should Y !The BEACON is not emitting.", self.Positionable}) self:E( { "WARNING: The POSITIONABLE you want to attach the AA TACAN Beacon is an aircraft: Mode should Y! The BEACON is not emitting.", self.Positionable } )
end end
end end
@@ -204,7 +205,7 @@ function BEACON:ActivateTACAN(Channel, Mode, Message, Bearing, Duration)
-- Start beacon. -- Start beacon.
self.Positionable:CommandActivateBeacon( Type, System, Frequency, UnitID, Channel, Mode, AA, Message, Bearing ) self.Positionable:CommandActivateBeacon( Type, System, Frequency, UnitID, Channel, Mode, AA, Message, Bearing )
-- Stop sheduler. -- Stop scheduler.
if Duration then if Duration then
self.Positionable:DeactivateBeacon( Duration ) self.Positionable:DeactivateBeacon( Duration )
end end
@@ -230,7 +231,7 @@ function BEACON:ActivateICLS(Channel, Callsign, Duration)
-- Start beacon. -- Start beacon.
self.Positionable:CommandActivateICLS( Channel, UnitID, Callsign ) self.Positionable:CommandActivateICLS( Channel, UnitID, Callsign )
-- Stop sheduler -- Stop scheduler
if Duration then -- Schedule the stop of the BEACON if asked by the MD if Duration then -- Schedule the stop of the BEACON if asked by the MD
self.Positionable:DeactivateBeacon( Duration ) self.Positionable:DeactivateBeacon( Duration )
end end
@@ -246,18 +247,20 @@ end
-- @param #number BeaconDuration How long will the beacon last in seconds. Omit for forever. -- @param #number BeaconDuration How long will the beacon last in seconds. Omit for forever.
-- @return #BEACON self -- @return #BEACON self
-- @usage -- @usage
--
-- -- Let's create a TACAN Beacon for a tanker -- -- Let's create a TACAN Beacon for a tanker
-- local myUnit = UNIT:FindByName("MyUnit") -- local myUnit = UNIT:FindByName("MyUnit")
-- local myBeacon = myUnit:GetBeacon() -- Creates the beacon -- local myBeacon = myUnit:GetBeacon() -- Creates the beacon
-- --
-- myBeacon:AATACAN(20, "TEXACO", true) -- Activate the beacon -- myBeacon:AATACAN(20, "TEXACO", true) -- Activate the beacon
--
function BEACON:AATACAN( TACANChannel, Message, Bearing, BeaconDuration ) function BEACON:AATACAN( TACANChannel, Message, Bearing, BeaconDuration )
self:F( { TACANChannel, Message, Bearing, BeaconDuration } ) self:F( { TACANChannel, Message, Bearing, BeaconDuration } )
local IsValid = true local IsValid = true
if not self.Positionable:IsAir() then 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}) 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 IsValid = false
end end
@@ -285,12 +288,11 @@ function BEACON:AATACAN(TACANChannel, Message, Bearing, BeaconDuration)
system = System, system = System,
callsign = Message, callsign = Message,
frequency = Frequency, frequency = Frequency,
} },
} ) } )
if BeaconDuration then -- Schedule the stop of the BEACON if asked by the MD if BeaconDuration then -- Schedule the stop of the BEACON if asked by the MD
SCHEDULER:New(nil, SCHEDULER:New( nil, function()
function()
self:StopAATACAN() self:StopAATACAN()
end, {}, BeaconDuration ) end, {}, BeaconDuration )
end end
@@ -305,18 +307,16 @@ end
function BEACON:StopAATACAN() function BEACON:StopAATACAN()
self:F() self:F()
if not self.Positionable then if not self.Positionable then
self:E({"Start the beacon first before stoping it !"}) self:E( { "Start the beacon first before stopping it!" } )
else else
self.Positionable:SetCommand( { self.Positionable:SetCommand( {
id = 'DeactivateBeacon', id = 'DeactivateBeacon',
params = { params = {},
}
} ) } )
end end
end end
--- Activates a general purpose Radio Beacon
--- Activates a general pupose Radio Beacon
-- This uses the very generic singleton function "trigger.action.radioTransmission()" provided by DCS to broadcast a sound file on a specific frequency. -- 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 2 DCS Modules can home on radio beacons at the time of writing : the Huey and the Mi-8. -- Although any frequency could be used, only 2 DCS Modules can home on radio beacons at the time of writing : the Huey and the Mi-8.
-- They can home in on these specific frequencies : -- They can home in on these specific frequencies :
@@ -367,7 +367,7 @@ function BEACON:RadioBeacon(FileName, Frequency, Modulation, Power, BeaconDurati
Frequency = Frequency * 1000000 -- Conversion to Hz Frequency = Frequency * 1000000 -- Conversion to Hz
-- Check the modulation -- 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 ? 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 } ) self:E( { "Modulation is invalid. Use DCS's enum radio.modulation.", Modulation } )
IsValid = false IsValid = false
end end
@@ -377,7 +377,7 @@ function BEACON:RadioBeacon(FileName, Frequency, Modulation, Power, BeaconDurati
self:E( { "Power is invalid. ", Power } ) self:E( { "Power is invalid. ", Power } )
IsValid = false IsValid = false
end end
Power = math.floor(math.abs(Power)) --TODO Find what is the maximum power allowed by DCS and limit power to that Power = math.floor( math.abs( Power ) ) -- TODO: Find what is the maximum power allowed by DCS and limit power to that
if IsValid then if IsValid then
self:T2( { "Activating Beacon on ", Frequency, Modulation } ) self:T2( { "Activating Beacon on ", Frequency, Modulation } )
@@ -385,8 +385,7 @@ function BEACON:RadioBeacon(FileName, Frequency, Modulation, Power, BeaconDurati
trigger.action.radioTransmission( FileName, self.Positionable:GetPositionVec3(), Modulation, true, Frequency, Power, tostring( self.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 if BeaconDuration then -- Schedule the stop of the BEACON if asked by the MD
SCHEDULER:New( nil, SCHEDULER:New( nil, function()
function()
self:StopRadioBeacon() self:StopRadioBeacon()
end, {}, BeaconDuration ) end, {}, BeaconDuration )
end end
@@ -407,7 +406,7 @@ end
-- @param #BEACON self -- @param #BEACON self
-- @param #number TACANChannel -- @param #number TACANChannel
-- @param #string TACANMode -- @param #string TACANMode
-- @return #number Frequecy -- @return #number Frequency
-- @return #nil if parameters are invalid -- @return #nil if parameters are invalid
function BEACON:_TACANToFrequency( TACANChannel, TACANMode ) function BEACON:_TACANToFrequency( TACANChannel, TACANMode )
self:F3( { TACANChannel, TACANMode } ) self:F3( { TACANChannel, TACANMode } )

View File

@@ -31,7 +31,6 @@
-- @module Core.Database -- @module Core.Database
-- @image Core_Database.JPG -- @image Core_Database.JPG
--- @type DATABASE --- @type DATABASE
-- @field #string ClassName Name of the class. -- @field #string ClassName Name of the class.
-- @field #table Templates Templates: Units, Groups, Statics, ClientsByName, ClientsByID. -- @field #table Templates Templates: Units, Groups, Statics, ClientsByName, ClientsByID.
@@ -51,7 +50,7 @@
-- * PLAYERS -- * PLAYERS
-- * CARGOS -- * CARGOS
-- --
-- On top, for internal MOOSE administration purposes, the DATBASE administers the Unit and Group TEMPLATES as defined within the Mission Editor. -- On top, for internal MOOSE administration purposes, the DATABASE administers the Unit and Group TEMPLATES as defined within the Mission Editor.
-- --
-- The singleton object **_DATABASE** is automatically created by MOOSE, that administers all objects within the mission. -- The singleton object **_DATABASE** is automatically created by MOOSE, that administers all objects within the mission.
-- Moose refers to **_DATABASE** within the framework extensively, but you can also refer to the _DATABASE object within your missions if required. -- Moose refers to **_DATABASE** within the framework extensively, but you can also refer to the _DATABASE object within your missions if required.
@@ -90,15 +89,13 @@ DATABASE = {
FLIGHTCONTROLS = {}, FLIGHTCONTROLS = {},
} }
local _DATABASECoalition = local _DATABASECoalition = {
{
[1] = "Red", [1] = "Red",
[2] = "Blue", [2] = "Blue",
[3] = "Neutral", [3] = "Neutral",
} }
local _DATABASECategory = local _DATABASECategory = {
{
["plane"] = Unit.Category.AIRPLANE, ["plane"] = Unit.Category.AIRPLANE,
["helicopter"] = Unit.Category.HELICOPTER, ["helicopter"] = Unit.Category.HELICOPTER,
["vehicle"] = Unit.Category.GROUND_UNIT, ["vehicle"] = Unit.Category.GROUND_UNIT,
@@ -106,7 +103,6 @@ local _DATABASECategory =
["static"] = Unit.Category.STRUCTURE, ["static"] = Unit.Category.STRUCTURE,
} }
--- Creates a new DATABASE object, building a set of units belonging to a coalitions, categories, countries, types or with defined prefix names. --- Creates a new DATABASE object, building a set of units belonging to a coalitions, categories, countries, types or with defined prefix names.
-- @param #DATABASE self -- @param #DATABASE self
-- @return #DATABASE -- @return #DATABASE
@@ -154,7 +150,6 @@ function DATABASE:FindUnit( UnitName )
return UnitFound return UnitFound
end end
--- Adds a Unit based on the Unit Name in the DATABASE. --- Adds a Unit based on the Unit Name in the DATABASE.
-- @param #DATABASE self -- @param #DATABASE self
-- @param #string DCSUnitName Unit name. -- @param #string DCSUnitName Unit name.
@@ -178,7 +173,6 @@ function DATABASE:AddUnit( DCSUnitName )
return self.UNITS[DCSUnitName] return self.UNITS[DCSUnitName]
end end
--- Deletes a Unit from the DATABASE based on the Unit Name. --- Deletes a Unit from the DATABASE based on the Unit Name.
-- @param #DATABASE self -- @param #DATABASE self
function DATABASE:DeleteUnit( DCSUnitName ) function DATABASE:DeleteUnit( DCSUnitName )
@@ -200,7 +194,6 @@ function DATABASE:AddStatic( DCSStaticName )
return nil return nil
end end
--- Deletes a Static from the DATABASE based on the Static Name. --- Deletes a Static from the DATABASE based on the Static Name.
-- @param #DATABASE self -- @param #DATABASE self
function DATABASE:DeleteStatic( DCSStaticName ) function DATABASE:DeleteStatic( DCSStaticName )
@@ -240,7 +233,6 @@ function DATABASE:AddAirbase( AirbaseName )
return self.AIRBASES[AirbaseName] return self.AIRBASES[AirbaseName]
end end
--- Deletes a Airbase from the DATABASE based on the Airbase Name. --- Deletes a Airbase from the DATABASE based on the Airbase Name.
-- @param #DATABASE self -- @param #DATABASE self
-- @param #string AirbaseName The name of the airbase -- @param #string AirbaseName The name of the airbase
@@ -259,7 +251,6 @@ function DATABASE:FindAirbase( AirbaseName )
return AirbaseFound return AirbaseFound
end end
do -- Zones do -- Zones
--- Finds a @{Zone} based on the zone name. --- Finds a @{Zone} based on the zone name.
@@ -283,7 +274,6 @@ do -- Zones
end end
end end
--- Deletes a @{Zone} from the DATABASE based on the zone name. --- Deletes a @{Zone} from the DATABASE based on the zone name.
-- @param #DATABASE self -- @param #DATABASE self
-- @param #string ZoneName The name of the zone. -- @param #string ZoneName The name of the zone.
@@ -292,7 +282,6 @@ do -- Zones
self.ZONES[ZoneName] = nil self.ZONES[ZoneName] = nil
end end
--- Private method that registers new ZONE_BASE derived objects within the DATABASE Object. --- Private method that registers new ZONE_BASE derived objects within the DATABASE Object.
-- @param #DATABASE self -- @param #DATABASE self
-- @return #DATABASE self -- @return #DATABASE self
@@ -376,7 +365,6 @@ do -- Zones
end end
end -- zone end -- zone
do -- Zone_Goal do -- Zone_Goal
@@ -402,7 +390,6 @@ do -- Zone_Goal
end end
end end
--- Deletes a @{Zone} from the DATABASE based on the zone name. --- Deletes a @{Zone} from the DATABASE based on the zone name.
-- @param #DATABASE self -- @param #DATABASE self
-- @param #string ZoneName The name of the zone. -- @param #string ZoneName The name of the zone.
@@ -424,7 +411,6 @@ do -- cargo
end end
end end
--- Deletes a Cargo from the DATABASE based on the Cargo Name. --- Deletes a Cargo from the DATABASE based on the Cargo Name.
-- @param #DATABASE self -- @param #DATABASE self
-- @param #string CargoName The name of the airbase -- @param #string CargoName The name of the airbase
@@ -518,7 +504,6 @@ function DATABASE:FindClient( ClientName )
return ClientFound return ClientFound
end end
--- Adds a CLIENT based on the ClientName in the DATABASE. --- Adds a CLIENT based on the ClientName in the DATABASE.
-- @param #DATABASE self -- @param #DATABASE self
-- @param #string ClientName Name of the Client unit. -- @param #string ClientName Name of the Client unit.
@@ -532,7 +517,6 @@ function DATABASE:AddClient( ClientName )
return self.CLIENTS[ClientName] return self.CLIENTS[ClientName]
end end
--- Finds a GROUP based on the GroupName. --- Finds a GROUP based on the GroupName.
-- @param #DATABASE self -- @param #DATABASE self
-- @param #string GroupName -- @param #string GroupName
@@ -543,7 +527,6 @@ function DATABASE:FindGroup( GroupName )
return GroupFound return GroupFound
end end
--- Adds a GROUP based on the GroupName in the DATABASE. --- Adds a GROUP based on the GroupName in the DATABASE.
-- @param #DATABASE self -- @param #DATABASE self
function DATABASE:AddGroup( GroupName ) function DATABASE:AddGroup( GroupName )
@@ -591,7 +574,6 @@ function DATABASE:GetPlayers()
return self.PLAYERS return self.PLAYERS
end end
--- Get the player table from the DATABASE, which contains all UNIT objects. --- Get the player table from the DATABASE, which contains all UNIT objects.
-- The player table contains all UNIT objects of the player with the key the name of the player (PlayerName). -- The player table contains all UNIT objects of the player with the key the name of the player (PlayerName).
-- @param #DATABASE self -- @param #DATABASE self
@@ -604,7 +586,6 @@ function DATABASE:GetPlayerUnits()
return self.PLAYERUNITS return self.PLAYERUNITS
end end
--- Get the player table from the DATABASE which have joined in the mission historically. --- Get the player table from the DATABASE which have joined in the mission historically.
-- The player table contains all UNIT objects with the key the name of the player (PlayerName). -- The player table contains all UNIT objects with the key the name of the player (PlayerName).
-- @param #DATABASE self -- @param #DATABASE self
@@ -617,7 +598,6 @@ function DATABASE:GetPlayersJoined()
return self.PLAYERSJOINED return self.PLAYERSJOINED
end end
--- Instantiate new Groups within the DCSRTE. --- Instantiate new Groups within the DCSRTE.
-- This method expects EXACTLY the same structure as a structure within the ME, and needs 2 additional fields defined: -- This method expects EXACTLY the same structure as a structure within the ME, and needs 2 additional fields defined:
-- SpawnCountryID, SpawnCategoryID -- SpawnCountryID, SpawnCategoryID
@@ -750,9 +730,8 @@ function DATABASE:_RegisterGroupTemplate( GroupTemplate, CoalitionSide, Category
Coalition = self.Templates.Groups[GroupTemplateName].CoalitionID, Coalition = self.Templates.Groups[GroupTemplateName].CoalitionID,
Category = self.Templates.Groups[GroupTemplateName].CategoryID, Category = self.Templates.Groups[GroupTemplateName].CategoryID,
Country = self.Templates.Groups[GroupTemplateName].CountryID, Country = self.Templates.Groups[GroupTemplateName].CountryID,
Units = UnitNames Units = UnitNames,
} } )
)
end end
--- Get group template. --- Get group template.
@@ -797,9 +776,8 @@ function DATABASE:_RegisterStaticTemplate( StaticTemplate, CoalitionID, Category
self:T( { Static = self.Templates.Statics[StaticTemplateName].StaticName, self:T( { Static = self.Templates.Statics[StaticTemplateName].StaticName,
Coalition = self.Templates.Statics[StaticTemplateName].CoalitionID, Coalition = self.Templates.Statics[StaticTemplateName].CoalitionID,
Category = self.Templates.Statics[StaticTemplateName].CategoryID, Category = self.Templates.Statics[StaticTemplateName].CategoryID,
Country = self.Templates.Statics[StaticTemplateName].CountryID Country = self.Templates.Statics[StaticTemplateName].CountryID,
} } )
)
self:AddStatic( StaticTemplateName ) self:AddStatic( StaticTemplateName )
@@ -902,8 +880,6 @@ function DATABASE:GetCategoryFromAirbase( AirbaseName )
return self.AIRBASES[AirbaseName]:GetCategory() return self.AIRBASES[AirbaseName]:GetCategory()
end end
--- Private method that registers all alive players in the mission. --- Private method that registers all alive players in the mission.
-- @param #DATABASE self -- @param #DATABASE self
-- @return #DATABASE self -- @return #DATABASE self
@@ -927,7 +903,6 @@ function DATABASE:_RegisterPlayers()
return self return self
end end
--- Private method that registers all Groups and Units within in the mission. --- Private method that registers all Groups and Units within in the mission.
-- @param #DATABASE self -- @param #DATABASE self
-- @return #DATABASE self -- @return #DATABASE self
@@ -1043,7 +1018,6 @@ function DATABASE:_RegisterAirbases()
return self return self
end end
--- Events --- Events
--- Handles the OnBirth event for the alive units set. --- Handles the OnBirth event for the alive units set.
@@ -1123,7 +1097,6 @@ function DATABASE:_EventOnBirth( Event )
end end
--- Handles the OnDead or OnCrash event for alive units set. --- Handles the OnDead or OnCrash event for alive units set.
-- @param #DATABASE self -- @param #DATABASE self
-- @param Core.Event#EVENTDATA Event -- @param Core.Event#EVENTDATA Event
@@ -1178,7 +1151,6 @@ function DATABASE:_EventOnDeadOrCrash( Event )
self:AccountDestroys( Event ) self:AccountDestroys( Event )
end end
--- Handles the OnPlayerEnterUnit event to fill the active players table (with the unit filter applied). --- Handles the OnPlayerEnterUnit event to fill the active players table (with the unit filter applied).
-- @param #DATABASE self -- @param #DATABASE self
-- @param Core.Event#EVENTDATA Event -- @param Core.Event#EVENTDATA Event
@@ -1216,7 +1188,6 @@ function DATABASE:_EventOnPlayerEnterUnit( Event )
end end
end end
--- Handles the OnPlayerLeaveUnit event to clean the active players table. --- Handles the OnPlayerLeaveUnit event to clean the active players table.
-- @param #DATABASE self -- @param #DATABASE self
-- @param Core.Event#EVENTDATA Event -- @param Core.Event#EVENTDATA Event
@@ -1302,7 +1273,6 @@ function DATABASE:ForEach( IteratorFunction, FinalizeFunction, arg, Set )
return self return self
end end
--- Iterate the DATABASE and call an iterator function for each **alive** STATIC, providing the STATIC and optional parameters. --- Iterate the DATABASE and call an iterator function for each **alive** STATIC, providing the STATIC and optional parameters.
-- @param #DATABASE self -- @param #DATABASE self
-- @param #function IteratorFunction The function that will be called for each object in the database. The function needs to accept a STATIC parameter. -- @param #function IteratorFunction The function that will be called for each object in the database. The function needs to accept a STATIC parameter.
@@ -1315,7 +1285,6 @@ function DATABASE:ForEachStatic( IteratorFunction, FinalizeFunction, ... ) --R2
return self return self
end end
--- Iterate the DATABASE and call an iterator function for each **alive** UNIT, providing the UNIT and optional parameters. --- Iterate the DATABASE and call an iterator function for each **alive** UNIT, providing the UNIT and optional parameters.
-- @param #DATABASE self -- @param #DATABASE self
-- @param #function IteratorFunction The function that will be called for each object in the database. The function needs to accept a UNIT parameter. -- @param #function IteratorFunction The function that will be called for each object in the database. The function needs to accept a UNIT parameter.
@@ -1328,7 +1297,6 @@ function DATABASE:ForEachUnit( IteratorFunction, FinalizeFunction, ... )
return self return self
end end
--- Iterate the DATABASE and call an iterator function for each **alive** GROUP, providing the GROUP and optional parameters. --- Iterate the DATABASE and call an iterator function for each **alive** GROUP, providing the GROUP and optional parameters.
-- @param #DATABASE self -- @param #DATABASE self
-- @param #function IteratorFunction The function that will be called for each object in the database. The function needs to accept a GROUP parameter. -- @param #function IteratorFunction The function that will be called for each object in the database. The function needs to accept a GROUP parameter.
@@ -1341,7 +1309,6 @@ function DATABASE:ForEachGroup( IteratorFunction, FinalizeFunction, ... )
return self return self
end end
--- Iterate the DATABASE and call an iterator function for each **ALIVE** player, providing the player name and optional parameters. --- Iterate the DATABASE and call an iterator function for each **ALIVE** player, providing the player name and optional parameters.
-- @param #DATABASE self -- @param #DATABASE self
-- @param #function IteratorFunction The function that will be called for each object in the database. The function needs to accept the player name. -- @param #function IteratorFunction The function that will be called for each object in the database. The function needs to accept the player name.
@@ -1354,7 +1321,6 @@ function DATABASE:ForEachPlayer( IteratorFunction, FinalizeFunction, ... )
return self return self
end end
--- Iterate the DATABASE and call an iterator function for each player who has joined the mission, providing the Unit of the player and optional parameters. --- Iterate the DATABASE and call an iterator function for each player who has joined the mission, providing the Unit of the player and optional parameters.
-- @param #DATABASE self -- @param #DATABASE self
-- @param #function IteratorFunction The function that will be called for each object in the database. The function needs to accept a UNIT parameter. -- @param #function IteratorFunction The function that will be called for each object in the database. The function needs to accept a UNIT parameter.
@@ -1379,7 +1345,6 @@ function DATABASE:ForEachPlayerUnit( IteratorFunction, FinalizeFunction, ... )
return self return self
end end
--- Iterate the DATABASE and call an iterator function for each CLIENT, providing the CLIENT to the function and optional parameters. --- Iterate the DATABASE and call an iterator function for each CLIENT, providing the CLIENT to the function and optional parameters.
-- @param #DATABASE self -- @param #DATABASE self
-- @param #function IteratorFunction The function that will be called object in the database. The function needs to accept a CLIENT parameter. -- @param #function IteratorFunction The function that will be called object in the database. The function needs to accept a CLIENT parameter.
@@ -1404,7 +1369,6 @@ function DATABASE:ForEachCargo( IteratorFunction, ... )
return self return self
end end
--- Handles the OnEventNewCargo event. --- Handles the OnEventNewCargo event.
-- @param #DATABASE self -- @param #DATABASE self
-- @param Core.Event#EVENTDATA EventData -- @param Core.Event#EVENTDATA EventData
@@ -1416,7 +1380,6 @@ function DATABASE:OnEventNewCargo( EventData )
end end
end end
--- Handles the OnEventDeleteCargo. --- Handles the OnEventDeleteCargo.
-- @param #DATABASE self -- @param #DATABASE self
-- @param Core.Event#EVENTDATA EventData -- @param Core.Event#EVENTDATA EventData
@@ -1428,7 +1391,6 @@ function DATABASE:OnEventDeleteCargo( EventData )
end end
end end
--- Handles the OnEventNewZone event. --- Handles the OnEventNewZone event.
-- @param #DATABASE self -- @param #DATABASE self
-- @param Core.Event#EVENTDATA EventData -- @param Core.Event#EVENTDATA EventData
@@ -1440,7 +1402,6 @@ function DATABASE:OnEventNewZone( EventData )
end end
end end
--- Handles the OnEventDeleteZone. --- Handles the OnEventDeleteZone.
-- @param #DATABASE self -- @param #DATABASE self
-- @param Core.Event#EVENTDATA EventData -- @param Core.Event#EVENTDATA EventData
@@ -1452,8 +1413,6 @@ function DATABASE:OnEventDeleteZone( EventData )
end end
end end
--- Gets the player settings --- Gets the player settings
-- @param #DATABASE self -- @param #DATABASE self
-- @param #string PlayerName -- @param #string PlayerName
@@ -1463,7 +1422,6 @@ function DATABASE:GetPlayerSettings( PlayerName )
return self.PLAYERSETTINGS[PlayerName] return self.PLAYERSETTINGS[PlayerName]
end end
--- Sets the player settings --- Sets the player settings
-- @param #DATABASE self -- @param #DATABASE self
-- @param #string PlayerName -- @param #string PlayerName

View File

@@ -14,7 +14,7 @@
-- ![Objects](..\Presentations\EVENT\Dia2.JPG) -- ![Objects](..\Presentations\EVENT\Dia2.JPG)
-- --
-- Within a running mission, various DCS events occur. Units are dynamically created, crash, die, shoot stuff, get hit etc. -- Within a running mission, various DCS events occur. Units are dynamically created, crash, die, shoot stuff, get hit etc.
-- This module provides a mechanism to dispatch those events occuring within your running mission, to the different objects orchestrating your mission. -- This module provides a mechanism to dispatch those events occurring within your running mission, to the different objects orchestrating your mission.
-- --
-- ![Objects](..\Presentations\EVENT\Dia3.JPG) -- ![Objects](..\Presentations\EVENT\Dia3.JPG)
-- --
@@ -141,7 +141,6 @@
-- EventData.IniUnit:SmokeGreen() -- EventData.IniUnit:SmokeGreen()
-- end -- end
-- --
--
-- Find below an overview which events populate which information categories: -- Find below an overview which events populate which information categories:
-- --
-- ![Objects](..\Presentations\EVENT\Dia14.JPG) -- ![Objects](..\Presentations\EVENT\Dia14.JPG)
@@ -172,7 +171,6 @@
-- @module Core.Event -- @module Core.Event
-- @image Core_Event.JPG -- @image Core_Event.JPG
--- @type EVENT --- @type EVENT
-- @field #EVENT.Events Events -- @field #EVENT.Events Events
-- @extends Core.Base#BASE -- @extends Core.Base#BASE
@@ -194,7 +192,6 @@ world.event.S_EVENT_DELETE_ZONE_GOAL = world.event.S_EVENT_MAX + 1005
world.event.S_EVENT_REMOVE_UNIT = world.event.S_EVENT_MAX + 1006 world.event.S_EVENT_REMOVE_UNIT = world.event.S_EVENT_MAX + 1006
world.event.S_EVENT_PLAYER_ENTER_AIRCRAFT = world.event.S_EVENT_MAX + 1007 world.event.S_EVENT_PLAYER_ENTER_AIRCRAFT = world.event.S_EVENT_MAX + 1007
--- The different types of events supported by MOOSE. --- The different types of events supported by MOOSE.
-- Use this structure to subscribe to events using the @{Core.Base#BASE.HandleEvent}() method. -- Use this structure to subscribe to events using the @{Core.Base#BASE.HandleEvent}() method.
-- @type EVENTS -- @type EVENTS
@@ -304,8 +301,6 @@ EVENTS = {
-- @field Core.ZONE#ZONE Zone The zone object. -- @field Core.ZONE#ZONE Zone The zone object.
-- @field #string ZoneName The name of the zone. -- @field #string ZoneName The name of the zone.
local _EVENTMETA = { local _EVENTMETA = {
[world.event.S_EVENT_SHOT] = { [world.event.S_EVENT_SHOT] = {
Order = 1, Order = 1,
@@ -562,7 +557,6 @@ local _EVENTMETA = {
}, },
} }
--- The Events structure --- The Events structure
-- @type EVENT.Events -- @type EVENT.Events
-- @field #number IniUnit -- @field #number IniUnit
@@ -581,7 +575,6 @@ function EVENT:New()
return self return self
end end
--- Initializes the Events structure for the event. --- Initializes the Events structure for the event.
-- @param #EVENT self -- @param #EVENT self
-- @param DCS#world.event EventID Event ID. -- @param DCS#world.event EventID Event ID.
@@ -595,7 +588,7 @@ function EVENT:Init( EventID, EventClass )
self.Events[EventID] = {} self.Events[EventID] = {}
end end
-- Each event has a subtable of EventClasses, ordered by EventPriority. -- Each event has a sub-table of EventClasses, ordered by EventPriority.
local EventPriority = EventClass:GetEventPriority() local EventPriority = EventClass:GetEventPriority()
if not self.Events[EventID][EventPriority] then if not self.Events[EventID][EventPriority] then
@@ -657,7 +650,6 @@ function EVENT:Reset( EventObject ) --R2.1
end end
end end
--- Clears all event subscriptions for a @{Core.Base#BASE} derived object. --- Clears all event subscriptions for a @{Core.Base#BASE} derived object.
-- @param #EVENT self -- @param #EVENT self
-- @param Core.Base#BASE EventClass The self class object for which the events are removed. -- @param Core.Base#BASE EventClass The self class object for which the events are removed.
@@ -676,8 +668,6 @@ function EVENT:RemoveAll(EventClass)
return self return self
end end
--- Create an OnDead event handler for a group --- Create an OnDead event handler for a group
-- @param #EVENT self -- @param #EVENT self
-- @param #table EventTemplate -- @param #table EventTemplate
@@ -709,7 +699,6 @@ function EVENT:OnEventGeneric( EventFunction, EventClass, EventID )
return self return self
end end
--- Set a new listener for an `S_EVENT_X` event for a UNIT. --- Set a new listener for an `S_EVENT_X` event for a UNIT.
-- @param #EVENT self -- @param #EVENT self
-- @param #string UnitName The name of the UNIT. -- @param #string UnitName The name of the UNIT.
@@ -797,7 +786,6 @@ do -- OnDead
end end
do -- OnLand do -- OnLand
--- Create an OnLand event handler for a group --- Create an OnLand event handler for a group
@@ -929,7 +917,6 @@ do -- Event Creation
world.onEvent( Event ) world.onEvent( Event )
end end
--- Creation of a ZoneGoal Deletion Event. --- Creation of a ZoneGoal Deletion Event.
-- @param #EVENT self -- @param #EVENT self
-- @param Core.ZoneGoal#ZONE_GOAL ZoneGoal The ZoneGoal created. -- @param Core.ZoneGoal#ZONE_GOAL ZoneGoal The ZoneGoal created.
@@ -945,7 +932,6 @@ do -- Event Creation
world.onEvent( Event ) world.onEvent( Event )
end end
--- Creation of a S_EVENT_PLAYER_ENTER_UNIT Event. --- Creation of a S_EVENT_PLAYER_ENTER_UNIT Event.
-- @param #EVENT self -- @param #EVENT self
-- @param Wrapper.Unit#UNIT PlayerUnit. -- @param Wrapper.Unit#UNIT PlayerUnit.
@@ -955,7 +941,7 @@ do -- Event Creation
local Event = { local Event = {
id = EVENTS.PlayerEnterUnit, id = EVENTS.PlayerEnterUnit,
time = timer.getTime(), time = timer.getTime(),
initiator = PlayerUnit:GetDCSObject() initiator = PlayerUnit:GetDCSObject(),
} }
world.onEvent( Event ) world.onEvent( Event )
@@ -970,7 +956,7 @@ do -- Event Creation
local Event = { local Event = {
id = EVENTS.PlayerEnterAircraft, id = EVENTS.PlayerEnterAircraft,
time = timer.getTime(), time = timer.getTime(),
initiator = PlayerUnit:GetDCSObject() initiator = PlayerUnit:GetDCSObject(),
} }
world.onEvent( Event ) world.onEvent( Event )
@@ -993,7 +979,6 @@ function EVENT:onEvent( Event )
return errmsg return errmsg
end end
-- Get event meta data. -- Get event meta data.
local EventMeta = _EVENTMETA[Event.id] local EventMeta = _EVENTMETA[Event.id]
@@ -1247,8 +1232,7 @@ function EVENT:onEvent( Event )
self:F( { "Calling EventFunction for UNIT ", EventClass:GetClassNameAndID(), ", Unit ", Event.IniUnitName, EventPriority } ) self:F( { "Calling EventFunction for UNIT ", EventClass:GetClassNameAndID(), ", Unit ", Event.IniUnitName, EventPriority } )
end end
local Result, Value = xpcall( local Result, Value = xpcall( function()
function()
return EventData.EventFunction( EventClass, Event ) return EventData.EventFunction( EventClass, Event )
end, ErrorHandler ) end, ErrorHandler )
@@ -1263,8 +1247,7 @@ function EVENT:onEvent( Event )
self:F( { "Calling " .. EventMeta.Event .. " for Class ", EventClass:GetClassNameAndID(), EventPriority } ) self:F( { "Calling " .. EventMeta.Event .. " for Class ", EventClass:GetClassNameAndID(), EventPriority } )
end end
local Result, Value = xpcall( local Result, Value = xpcall( function()
function()
return EventFunction( EventClass, Event ) return EventFunction( EventClass, Event )
end, ErrorHandler ) end, ErrorHandler )
end end
@@ -1300,8 +1283,7 @@ function EVENT:onEvent( Event )
self:F( { "Calling EventFunction for GROUP ", EventClass:GetClassNameAndID(), ", Unit ", Event.IniUnitName, EventPriority } ) self:F( { "Calling EventFunction for GROUP ", EventClass:GetClassNameAndID(), ", Unit ", Event.IniUnitName, EventPriority } )
end end
local Result, Value = xpcall( local Result, Value = xpcall( function()
function()
return EventData.EventFunction( EventClass, Event, unpack( EventData.Params ) ) return EventData.EventFunction( EventClass, Event, unpack( EventData.Params ) )
end, ErrorHandler ) end, ErrorHandler )
@@ -1316,8 +1298,7 @@ function EVENT:onEvent( Event )
self:F( { "Calling " .. EventMeta.Event .. " for GROUP ", EventClass:GetClassNameAndID(), EventPriority } ) self:F( { "Calling " .. EventMeta.Event .. " for GROUP ", EventClass:GetClassNameAndID(), EventPriority } )
end end
local Result, Value = xpcall( local Result, Value = xpcall( function()
function()
return EventFunction( EventClass, Event, unpack( EventData.Params ) ) return EventFunction( EventClass, Event, unpack( EventData.Params ) )
end, ErrorHandler ) end, ErrorHandler )
end end
@@ -1340,8 +1321,7 @@ function EVENT:onEvent( Event )
if Event.IniObjectCategory ~= 3 then if Event.IniObjectCategory ~= 3 then
self:F2( { "Calling EventFunction for Class ", EventClass:GetClassNameAndID(), EventPriority } ) self:F2( { "Calling EventFunction for Class ", EventClass:GetClassNameAndID(), EventPriority } )
end end
local Result, Value = xpcall( local Result, Value = xpcall( function()
function()
return EventData.EventFunction( EventClass, Event ) return EventData.EventFunction( EventClass, Event )
end, ErrorHandler ) end, ErrorHandler )
else else
@@ -1355,8 +1335,7 @@ function EVENT:onEvent( Event )
self:F2( { "Calling " .. EventMeta.Event .. " for Class ", EventClass:GetClassNameAndID(), EventPriority } ) self:F2( { "Calling " .. EventMeta.Event .. " for Class ", EventClass:GetClassNameAndID(), EventPriority } )
end end
local Result, Value = xpcall( local Result, Value = xpcall( function()
function()
local Result, Value = EventFunction( EventClass, Event ) local Result, Value = EventFunction( EventClass, Event )
return Result, Value return Result, Value
end, ErrorHandler ) end, ErrorHandler )

View File

@@ -53,7 +53,7 @@
-- --
-- Detailed explanations and API specifics are further below clarified and FSM derived class specifics are described in those class documentation sections. -- Detailed explanations and API specifics are further below clarified and FSM derived class specifics are described in those class documentation sections.
-- --
-- ##__Dislaimer:__ -- ##__Disclaimer:__
-- The FSM class development is based on a finite state machine implementation made by Conroy Kyle. -- The FSM class development is based on a finite state machine implementation made by Conroy Kyle.
-- The state machine can be found on [github](https://github.com/kyleconroy/lua-state-machine) -- The state machine can be found on [github](https://github.com/kyleconroy/lua-state-machine)
-- I've reworked this development (taken the concept), and created a **hierarchical state machine** out of it, embedded within the DCS simulator. -- I've reworked this development (taken the concept), and created a **hierarchical state machine** out of it, embedded within the DCS simulator.
@@ -69,7 +69,6 @@
-- --
-- === -- ===
-- --
--
-- ### Author: **FlightControl** -- ### Author: **FlightControl**
-- ### Contributions: **funkyfranky** -- ### Contributions: **funkyfranky**
-- --
@@ -89,7 +88,6 @@ do -- FSM
-- @field #string current Current state name. -- @field #string current Current state name.
-- @extends Core.Base#BASE -- @extends Core.Base#BASE
--- A Finite State Machine (FSM) models a process flow that transitions between various **States** through triggered **Events**. --- A Finite State Machine (FSM) models a process flow that transitions between various **States** through triggered **Events**.
-- --
-- A FSM can only be in one of a finite number of states. -- A FSM can only be in one of a finite number of states.
@@ -145,12 +143,12 @@ do -- FSM
-- Most of the time, these Event Triggers are used within the Transition Handler methods, so that a workflow is created running through the state machine. -- Most of the time, these Event Triggers are used within the Transition Handler methods, so that a workflow is created running through the state machine.
-- --
-- As explained above, a FSM supports **Linear State Transitions** and **Hierarchical State Transitions**, and both can be mixed to make a comprehensive FSM implementation. -- As explained above, a FSM supports **Linear State Transitions** and **Hierarchical State Transitions**, and both can be mixed to make a comprehensive FSM implementation.
-- The below documentation has a seperate chapter explaining both transition modes, taking into account the **Transition Rules**, **Transition Handlers** and **Event Triggers**. -- The below documentation has a separate chapter explaining both transition modes, taking into account the **Transition Rules**, **Transition Handlers** and **Event Triggers**.
-- --
-- ## FSM Linear Transitions -- ## FSM Linear Transitions
-- --
-- Linear Transitions are Transition Rules allowing an FSM to transition from one or multiple possible **From** state(s) towards a **To** state upon a Triggered **Event**. -- Linear Transitions are Transition Rules allowing an FSM to transition from one or multiple possible **From** state(s) towards a **To** state upon a Triggered **Event**.
-- The Lineair transition rule evaluation will always be done from the **current state** of the FSM. -- The Linear transition rule evaluation will always be done from the **current state** of the FSM.
-- If no valid Transition Rule can be found in the FSM, the FSM will log an error and stop. -- If no valid Transition Rule can be found in the FSM, the FSM will log an error and stop.
-- --
-- ### FSM Transition Rules -- ### FSM Transition Rules
@@ -185,7 +183,7 @@ do -- FSM
-- * The From states can be **a table of strings**, indicating that the transition rule will be valid **if the current state** of the FSM will be **one of the given From states**. -- * The From states can be **a table of strings**, indicating that the transition rule will be valid **if the current state** of the FSM will be **one of the given From states**.
-- * The From state can be a **"*"**, indicating that **the transition rule will always be valid**, regardless of the current state of the FSM. -- * The From state can be a **"*"**, indicating that **the transition rule will always be valid**, regardless of the current state of the FSM.
-- --
-- The below code snippet shows how the two last lines can be rewritten and consensed. -- The below code snippet shows how the two last lines can be rewritten and condensed.
-- --
-- FsmSwitch:AddTransition( { "On", "Middle" }, "SwitchOff", "Off" ) -- FsmSwitch:AddTransition( { "On", "Middle" }, "SwitchOff", "Off" )
-- --
@@ -221,7 +219,7 @@ do -- FSM
-- * The method **FSM:Event()** triggers an Event that will be processed **synchronously** or **immediately**. -- * The method **FSM:Event()** triggers an Event that will be processed **synchronously** or **immediately**.
-- * The method **FSM:__Event( __seconds__ )** triggers an Event that will be processed **asynchronously** over time, waiting __x seconds__. -- * The method **FSM:__Event( __seconds__ )** triggers an Event that will be processed **asynchronously** over time, waiting __x seconds__.
-- --
-- The destinction between these 2 Event Trigger methods are important to understand. An asynchronous call will "log" the Event Trigger to be executed at a later time. -- The distinction between these 2 Event Trigger methods are important to understand. An asynchronous call will "log" the Event Trigger to be executed at a later time.
-- Processing will just continue. Synchronous Event Trigger methods are useful to change states of the FSM immediately, but may have a larger processing impact. -- Processing will just continue. Synchronous Event Trigger methods are useful to change states of the FSM immediately, but may have a larger processing impact.
-- --
-- The following example provides a little demonstration on the difference between synchronous and asynchronous Event Triggering. -- The following example provides a little demonstration on the difference between synchronous and asynchronous Event Triggering.
@@ -345,7 +343,6 @@ do -- FSM
-- === -- ===
-- --
-- @field #FSM -- @field #FSM
--
FSM = { FSM = {
ClassName = "FSM", ClassName = "FSM",
} }
@@ -379,7 +376,6 @@ do -- FSM
return self return self
end end
--- Sets the start state of the FSM. --- Sets the start state of the FSM.
-- @param #FSM self -- @param #FSM self
-- @param #string State A string defining the start state. -- @param #string State A string defining the start state.
@@ -388,7 +384,6 @@ do -- FSM
self.current = State self.current = State
end end
--- Returns the start state of the FSM. --- Returns the start state of the FSM.
-- @param #FSM self -- @param #FSM self
-- @return #string A string containing the start state. -- @return #string A string containing the start state.
@@ -416,7 +411,6 @@ do -- FSM
self:_eventmap( self.Events, Transition ) self:_eventmap( self.Events, Transition )
end end
--- Returns a table of the transition rules defined within the FSM. --- Returns a table of the transition rules defined within the FSM.
-- @param #FSM self -- @param #FSM self
-- @return #table Transitions. -- @return #table Transitions.
@@ -450,7 +444,6 @@ do -- FSM
return Process return Process
end end
--- Returns a table of the SubFSM rules defined within the FSM. --- Returns a table of the SubFSM rules defined within the FSM.
-- @param #FSM self -- @param #FSM self
-- @return #table Sub processes. -- @return #table Sub processes.
@@ -499,7 +492,6 @@ do -- FSM
return self._EndStates or {} return self._EndStates or {}
end end
--- Adds a score for the FSM to be achieved. --- Adds a score for the FSM to be achieved.
-- @param #FSM self -- @param #FSM self
-- @param #string State is the state of the process when the score needs to be given. (See the relevant state descriptions of the process). -- @param #string State is the state of the process when the score needs to be given. (See the relevant state descriptions of the process).
@@ -647,7 +639,9 @@ do -- FSM
-- return self[handler](self, unpack( params )) -- return self[handler](self, unpack( params ))
-- Protected call. -- Protected call.
local Result, Value = xpcall( function() return self[handler]( self, unpack( params ) ) end, ErrorHandler ) local Result, Value = xpcall( function()
return self[handler]( self, unpack( params ) )
end, ErrorHandler )
return Value return Value
end end
@@ -673,7 +667,6 @@ do -- FSM
-- Parameters. -- Parameters.
local Params = { From, EventName, To, ... } local Params = { From, EventName, To, ... }
if self["onleave" .. From] or if self["onleave" .. From] or
self["OnLeave" .. From] or self["OnLeave" .. From] or
self["onbefore" .. EventName] or self["onbefore" .. EventName] or
@@ -835,7 +828,9 @@ do -- FSM
-- @param #string EventName Event name. -- @param #string EventName Event name.
-- @return #function Function. -- @return #function Function.
function FSM:_create_transition( EventName ) function FSM:_create_transition( EventName )
return function( self, ... ) return self._handler( self, EventName , ... ) end return function( self, ... )
return self._handler( self, EventName, ... )
end
end end
--- Go sub. --- Go sub.
@@ -1075,7 +1070,9 @@ do -- FSM_CONTROLLABLE
if self[handler] then if self[handler] then
self:T( "*** FSM *** " .. step .. " *** " .. params[1] .. " --> " .. params[2] .. " --> " .. params[3] .. " *** TaskUnit: " .. self.Controllable:GetName() ) self:T( "*** FSM *** " .. step .. " *** " .. params[1] .. " --> " .. params[2] .. " --> " .. params[3] .. " *** TaskUnit: " .. self.Controllable:GetName() )
self._EventSchedules[EventName] = nil self._EventSchedules[EventName] = nil
local Result, Value = xpcall( function() return self[handler]( self, self.Controllable, unpack( params ) ) end, ErrorHandler ) local Result, Value = xpcall( function()
return self[handler]( self, self.Controllable, unpack( params ) )
end, ErrorHandler )
return Value return Value
-- return self[handler]( self, self.Controllable, unpack( params ) ) -- return self[handler]( self, self.Controllable, unpack( params ) )
end end
@@ -1089,16 +1086,13 @@ do -- FSM_PROCESS
-- @field Tasking.Task#TASK Task -- @field Tasking.Task#TASK Task
-- @extends Core.Fsm#FSM_CONTROLLABLE -- @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 @{Task} actions, which control @{Client}s.
-- --
-- === -- ===
-- --
-- @field #FSM_PROCESS FSM_PROCESS -- @field #FSM_PROCESS FSM_PROCESS
-- --
FSM_PROCESS = { FSM_PROCESS = { ClassName = "FSM_PROCESS" }
ClassName = "FSM_PROCESS",
}
--- Creates a new FSM_PROCESS object. --- Creates a new FSM_PROCESS object.
-- @param #FSM_PROCESS self -- @param #FSM_PROCESS self
@@ -1139,7 +1133,9 @@ do -- FSM_PROCESS
self._EventSchedules[EventName] = nil self._EventSchedules[EventName] = nil
local Result, Value local Result, Value
if self.Controllable and self.Controllable:IsAlive() == true then if self.Controllable and self.Controllable:IsAlive() == true then
Result, Value = xpcall( function() return self[handler]( self, self.Controllable, self.Task, unpack( params ) ) end, ErrorHandler ) Result, Value = xpcall( function()
return self[handler]( self, self.Controllable, self.Task, unpack( params ) )
end, ErrorHandler )
end end
return Value return Value
-- return self[handler]( self, self.Controllable, unpack( params ) ) -- return self[handler]( self, self.Controllable, unpack( params ) )
@@ -1152,7 +1148,6 @@ do -- FSM_PROCESS
function FSM_PROCESS:Copy( Controllable, Task ) function FSM_PROCESS:Copy( Controllable, Task )
self:T( { self:GetClassNameAndID() } ) self:T( { self:GetClassNameAndID() } )
local NewFsm = self:New( Controllable, Task ) -- Core.Fsm#FSM_PROCESS local NewFsm = self:New( Controllable, Task ) -- Core.Fsm#FSM_PROCESS
NewFsm:Assign( Controllable, Task ) NewFsm:Assign( Controllable, Task )
@@ -1263,9 +1258,6 @@ do -- FSM_PROCESS
CC:MessageToGroup( Message, TaskGroup ) CC:MessageToGroup( Message, TaskGroup )
end end
--- Assign the process to a @{Wrapper.Unit} and activate the process. --- Assign the process to a @{Wrapper.Unit} and activate the process.
-- @param #FSM_PROCESS self -- @param #FSM_PROCESS self
-- @param Task.Tasking#TASK Task -- @param Task.Tasking#TASK Task
@@ -1296,7 +1288,6 @@ do -- FSM_PROCESS
self.Task:Fail() self.Task:Fail()
end end
--- StateMachine callback function for a FSM_PROCESS --- StateMachine callback function for a FSM_PROCESS
-- @param #FSM_PROCESS self -- @param #FSM_PROCESS self
-- @param Wrapper.Controllable#CONTROLLABLE ProcessUnit -- @param Wrapper.Controllable#CONTROLLABLE ProcessUnit
@@ -1375,7 +1366,9 @@ do -- FSM_TASK
self:T( "*** FSM *** " .. step .. " *** " .. params[1] .. " --> " .. params[2] .. " --> " .. params[3] .. " *** Task: " .. self.TaskName ) self:T( "*** FSM *** " .. step .. " *** " .. params[1] .. " --> " .. params[2] .. " --> " .. params[3] .. " *** Task: " .. self.TaskName )
self._EventSchedules[EventName] = nil self._EventSchedules[EventName] = nil
-- return self[handler]( self, unpack( params ) ) -- return self[handler]( self, unpack( params ) )
local Result, Value = xpcall( function() return self[handler]( self, unpack( params ) ) end, ErrorHandler ) local Result, Value = xpcall( function()
return self[handler]( self, unpack( params ) )
end, ErrorHandler )
return Value return Value
end end
end end
@@ -1389,14 +1382,12 @@ do -- FSM_SET
-- @field Core.Set#SET_BASE Set -- @field Core.Set#SET_BASE Set
-- @extends Core.Fsm#FSM -- @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 @{Set}s. Note that these FSMs control multiple objects!!! So State concerns here
-- for multiple objects or the position of the state machine in the process. -- for multiple objects or the position of the state machine in the process.
-- --
-- === -- ===
-- --
-- @field #FSM_SET FSM_SET -- @field #FSM_SET FSM_SET
--
FSM_SET = { FSM_SET = {
ClassName = "FSM_SET", ClassName = "FSM_SET",
} }

View File

@@ -22,13 +22,11 @@
-- @module Core.Goal -- @module Core.Goal
-- @image Core_Goal.JPG -- @image Core_Goal.JPG
do -- Goal do -- Goal
--- @type GOAL --- @type GOAL
-- @extends Core.Fsm#FSM -- @extends Core.Fsm#FSM
--- Models processes that have an objective with a defined achievement. Derived classes implement the ways how the achievements can be realized. --- Models processes that have an objective with a defined achievement. Derived classes implement the ways how the achievements can be realized.
-- --
-- # 1. GOAL constructor -- # 1. GOAL constructor
@@ -105,7 +103,6 @@ do -- Goal
-- @param #string Event -- @param #string Event
-- @param #string To -- @param #string To
self:SetStartState( "Pending" ) self:SetStartState( "Pending" )
self:AddTransition( "*", "Achieved", "Achieved" ) self:AddTransition( "*", "Achieved", "Achieved" )
@@ -138,7 +135,6 @@ do -- Goal
return self return self
end end
--- Add a new contribution by a player. --- Add a new contribution by a player.
-- @param #GOAL self -- @param #GOAL self
-- @param #string PlayerName The name of the player. -- @param #string PlayerName The name of the player.
@@ -149,14 +145,12 @@ do -- Goal
self.TotalContributions = self.TotalContributions + 1 self.TotalContributions = self.TotalContributions + 1
end end
--- @param #GOAL self --- @param #GOAL self
-- @param #number Player contribution. -- @param #number Player contribution.
function GOAL:GetPlayerContribution( PlayerName ) function GOAL:GetPlayerContribution( PlayerName )
return self.Players[PlayerName] or 0 return self.Players[PlayerName] or 0
end end
--- Get the players who contributed to achieve the goal. --- Get the players who contributed to achieve the goal.
-- The result is a list of players, sorted by the name of the players. -- The result is a list of players, sorted by the name of the players.
-- @param #GOAL self -- @param #GOAL self
@@ -165,7 +159,6 @@ do -- Goal
return self.Players or {} return self.Players or {}
end end
--- Gets the total contributions that happened to achieve the goal. --- Gets the total contributions that happened to achieve the goal.
-- The result is a number. -- The result is a number.
-- @param #GOAL self -- @param #GOAL self
@@ -174,8 +167,6 @@ do -- Goal
return self.TotalContributions or 0 return self.TotalContributions or 0
end end
--- Validates if the goal is achieved. --- Validates if the goal is achieved.
-- @param #GOAL self -- @param #GOAL self
-- @return #boolean true if the goal is achieved. -- @return #boolean true if the goal is achieved.

View File

@@ -14,7 +14,7 @@
-- * Only create or delete menus when required, and keep existing menus persistent. -- * Only create or delete menus when required, and keep existing menus persistent.
-- * Update menu structures. -- * Update menu structures.
-- * Refresh menu structures intelligently, based on a time stamp of updates. -- * Refresh menu structures intelligently, based on a time stamp of updates.
-- - Delete obscolete menus. -- - Delete obsolete menus.
-- - Create new one where required. -- - Create new one where required.
-- - Don't touch the existing ones. -- - Don't touch the existing ones.
-- * Provide a variable amount of parameters to menus. -- * Provide a variable amount of parameters to menus.
@@ -23,7 +23,7 @@
-- * Provide a great tool to manage menus in your code. -- * Provide a great tool to manage menus in your code.
-- --
-- DCS Menus can be managed using the MENU classes. -- DCS Menus can be managed using the MENU classes.
-- The advantage of using MENU classes is that it hides the complexity of dealing with menu management in more advanced scanerios where you need to -- The advantage of using MENU classes is that it hides the complexity of dealing with menu management in more advanced scenarios where you need to
-- set menus and later remove them, and later set them again. You'll find while using use normal DCS scripting functions, that setting and removing -- set menus and later remove them, and later set them again. You'll find while using use normal DCS scripting functions, that setting and removing
-- menus is not a easy feat if you have complex menu hierarchies defined. -- menus is not a easy feat if you have complex menu hierarchies defined.
-- Using the MOOSE menu classes, the removal and refreshing of menus are nicely being handled within these classes, and becomes much more easy. -- Using the MOOSE menu classes, the removal and refreshing of menus are nicely being handled within these classes, and becomes much more easy.
@@ -53,7 +53,6 @@
-- @module Core.Menu -- @module Core.Menu
-- @image Core_Menu.JPG -- @image Core_Menu.JPG
MENU_INDEX = {} MENU_INDEX = {}
MENU_INDEX.MenuMission = {} MENU_INDEX.MenuMission = {}
MENU_INDEX.MenuMission.Menus = {} MENU_INDEX.MenuMission.Menus = {}
@@ -64,8 +63,6 @@ MENU_INDEX.Coalition[coalition.side.RED] = {}
MENU_INDEX.Coalition[coalition.side.RED].Menus = {} MENU_INDEX.Coalition[coalition.side.RED].Menus = {}
MENU_INDEX.Group = {} MENU_INDEX.Group = {}
function MENU_INDEX:ParentPath( ParentMenu, MenuText ) function MENU_INDEX:ParentPath( ParentMenu, MenuText )
local Path = ParentMenu and "@" .. table.concat( ParentMenu.MenuPath or {}, "@" ) or "" local Path = ParentMenu and "@" .. table.concat( ParentMenu.MenuPath or {}, "@" ) or ""
@@ -98,12 +95,10 @@ function MENU_INDEX:ParentPath( ParentMenu, MenuText )
end end
function MENU_INDEX:PrepareMission() function MENU_INDEX:PrepareMission()
self.MenuMission.Menus = self.MenuMission.Menus or {} self.MenuMission.Menus = self.MenuMission.Menus or {}
end end
function MENU_INDEX:PrepareCoalition( CoalitionSide ) function MENU_INDEX:PrepareCoalition( CoalitionSide )
self.Coalition[CoalitionSide] = self.Coalition[CoalitionSide] or {} self.Coalition[CoalitionSide] = self.Coalition[CoalitionSide] or {}
self.Coalition[CoalitionSide].Menus = self.Coalition[CoalitionSide].Menus or {} self.Coalition[CoalitionSide].Menus = self.Coalition[CoalitionSide].Menus or {}
@@ -119,8 +114,6 @@ function MENU_INDEX:PrepareGroup( Group )
end end
end end
function MENU_INDEX:HasMissionMenu( Path ) function MENU_INDEX:HasMissionMenu( Path )
return self.MenuMission.Menus[Path] return self.MenuMission.Menus[Path]
@@ -136,8 +129,6 @@ function MENU_INDEX:ClearMissionMenu( Path )
self.MenuMission.Menus[Path] = nil self.MenuMission.Menus[Path] = nil
end end
function MENU_INDEX:HasCoalitionMenu( Coalition, Path ) function MENU_INDEX:HasCoalitionMenu( Coalition, Path )
return self.Coalition[Coalition].Menus[Path] return self.Coalition[Coalition].Menus[Path]
@@ -153,8 +144,6 @@ function MENU_INDEX:ClearCoalitionMenu( Coalition, Path )
self.Coalition[Coalition].Menus[Path] = nil self.Coalition[Coalition].Menus[Path] = nil
end end
function MENU_INDEX:HasGroupMenu( Group, Path ) function MENU_INDEX:HasGroupMenu( Group, Path )
if Group and Group:IsAlive() then if Group and Group:IsAlive() then
local MenuGroupName = Group:GetName() local MenuGroupName = Group:GetName()
@@ -197,17 +186,10 @@ function MENU_INDEX:Refresh( Group )
end end
do -- MENU_BASE do -- MENU_BASE
--- @type MENU_BASE --- @type MENU_BASE
-- @extends Base#BASE -- @extends Core.Base#BASE
--- Defines the main MENU class where other MENU classes are derived from. --- Defines the main MENU class where other MENU classes are derived from.
-- This is an abstract class, so don't use it. -- This is an abstract class, so don't use it.
@@ -216,10 +198,10 @@ do -- MENU_BASE
ClassName = "MENU_BASE", ClassName = "MENU_BASE",
MenuPath = nil, MenuPath = nil,
MenuText = "", MenuText = "",
MenuParentPath = nil MenuParentPath = nil,
} }
--- Consructor --- Constructor
-- @param #MENU_BASE -- @param #MENU_BASE
-- @return #MENU_BASE -- @return #MENU_BASE
function MENU_BASE:New( MenuText, ParentMenu ) function MENU_BASE:New( MenuText, ParentMenu )
@@ -277,7 +259,6 @@ do -- MENU_BASE
return self return self
end end
--- Gets a @{Menu} from a parent @{Menu} --- Gets a @{Menu} from a parent @{Menu}
-- @param #MENU_BASE self -- @param #MENU_BASE self
-- @param #string MenuText The text of the child menu. -- @param #string MenuText The text of the child menu.
@@ -295,7 +276,6 @@ do -- MENU_BASE
return self return self
end end
--- Gets a menu stamp for later prevention of menu removal. --- Gets a menu stamp for later prevention of menu removal.
-- @param #MENU_BASE self -- @param #MENU_BASE self
-- @return MenuStamp -- @return MenuStamp
@@ -303,7 +283,6 @@ do -- MENU_BASE
return timer.getTime() return timer.getTime()
end end
--- Sets a time stamp for later prevention of menu removal. --- Sets a time stamp for later prevention of menu removal.
-- @param #MENU_BASE self -- @param #MENU_BASE self
-- @param MenuStamp -- @param MenuStamp
@@ -394,7 +373,6 @@ do -- MENU_COMMAND_BASE
end end
do -- MENU_MISSION do -- MENU_MISSION
--- @type MENU_MISSION --- @type MENU_MISSION
@@ -406,13 +384,13 @@ do -- MENU_MISSION
-- Using this object reference, you can then remove ALL the menus and submenus underlying automatically with @{#MENU_MISSION.Remove}. -- Using this object reference, you can then remove ALL the menus and submenus underlying automatically with @{#MENU_MISSION.Remove}.
-- @field #MENU_MISSION -- @field #MENU_MISSION
MENU_MISSION = { MENU_MISSION = {
ClassName = "MENU_MISSION" ClassName = "MENU_MISSION",
} }
--- MENU_MISSION constructor. Creates a new MENU_MISSION object and creates the menu for a complete mission file. --- MENU_MISSION constructor. Creates a new MENU_MISSION object and creates the menu for a complete mission file.
-- @param #MENU_MISSION self -- @param #MENU_MISSION self
-- @param #string MenuText The text for the menu. -- @param #string MenuText The text for the menu.
-- @param #table ParentMenu The parent menu. This parameter can be ignored if you want the menu to be located at the perent menu of DCS world (under F10 other). -- @param #table ParentMenu The parent menu. This parameter can be ignored if you want the menu to be located at the parent menu of DCS world (under F10 other).
-- @return #MENU_MISSION -- @return #MENU_MISSION
function MENU_MISSION:New( MenuText, ParentMenu ) function MENU_MISSION:New( MenuText, ParentMenu )
@@ -487,8 +465,6 @@ do -- MENU_MISSION
return self return self
end end
end end
do -- MENU_MISSION_COMMAND do -- MENU_MISSION_COMMAND
@@ -503,7 +479,7 @@ do -- MENU_MISSION_COMMAND
-- --
-- @field #MENU_MISSION_COMMAND -- @field #MENU_MISSION_COMMAND
MENU_MISSION_COMMAND = { MENU_MISSION_COMMAND = {
ClassName = "MENU_MISSION_COMMAND" ClassName = "MENU_MISSION_COMMAND",
} }
--- MENU_MISSION constructor. Creates a new radio command item for a complete mission file, which can invoke a function with parameters. --- MENU_MISSION constructor. Creates a new radio command item for a complete mission file, which can invoke a function with parameters.
@@ -575,8 +551,6 @@ do -- MENU_MISSION_COMMAND
end end
do -- MENU_COALITION do -- MENU_COALITION
--- @type MENU_COALITION --- @type MENU_COALITION
@@ -627,14 +601,14 @@ do -- MENU_COALITION
-- --
-- @field #MENU_COALITION -- @field #MENU_COALITION
MENU_COALITION = { MENU_COALITION = {
ClassName = "MENU_COALITION" ClassName = "MENU_COALITION",
} }
--- MENU_COALITION constructor. Creates a new MENU_COALITION object and creates the menu for a complete coalition. --- MENU_COALITION constructor. Creates a new MENU_COALITION object and creates the menu for a complete coalition.
-- @param #MENU_COALITION self -- @param #MENU_COALITION self
-- @param DCS#coalition.side Coalition The coalition owning the menu. -- @param DCS#coalition.side Coalition The coalition owning the menu.
-- @param #string MenuText The text for the menu. -- @param #string MenuText The text for the menu.
-- @param #table ParentMenu The parent menu. This parameter can be ignored if you want the menu to be located at the perent menu of DCS world (under F10 other). -- @param #table ParentMenu The parent menu. This parameter can be ignored if you want the menu to be located at the parent menu of DCS world (under F10 other).
-- @return #MENU_COALITION self -- @return #MENU_COALITION self
function MENU_COALITION:New( Coalition, MenuText, ParentMenu ) function MENU_COALITION:New( Coalition, MenuText, ParentMenu )
@@ -712,8 +686,6 @@ do -- MENU_COALITION
end end
do -- MENU_COALITION_COMMAND do -- MENU_COALITION_COMMAND
--- @type MENU_COALITION_COMMAND --- @type MENU_COALITION_COMMAND
@@ -726,7 +698,7 @@ do -- MENU_COALITION_COMMAND
-- --
-- @field #MENU_COALITION_COMMAND -- @field #MENU_COALITION_COMMAND
MENU_COALITION_COMMAND = { MENU_COALITION_COMMAND = {
ClassName = "MENU_COALITION_COMMAND" ClassName = "MENU_COALITION_COMMAND",
} }
--- MENU_COALITION constructor. Creates a new radio command item for a coalition, which can invoke a function with parameters. --- MENU_COALITION constructor. Creates a new radio command item for a coalition, which can invoke a function with parameters.
@@ -760,7 +732,6 @@ do -- MENU_COALITION_COMMAND
end end
--- Refreshes a radio item for a coalition --- Refreshes a radio item for a coalition
-- @param #MENU_COALITION_COMMAND self -- @param #MENU_COALITION_COMMAND self
-- @return #MENU_COALITION_COMMAND -- @return #MENU_COALITION_COMMAND
@@ -803,7 +774,6 @@ do -- MENU_COALITION_COMMAND
end end
--- MENU_GROUP --- MENU_GROUP
do do
@@ -817,7 +787,6 @@ do
--- @type MENU_GROUP --- @type MENU_GROUP
-- @extends Core.Menu#MENU_BASE -- @extends Core.Menu#MENU_BASE
--- Manages the main menus for @{Wrapper.Group}s. --- Manages the main menus for @{Wrapper.Group}s.
-- --
-- You can add menus with the @{#MENU_GROUP.New} method, which constructs a MENU_GROUP object and returns you the object reference. -- You can add menus with the @{#MENU_GROUP.New} method, which constructs a MENU_GROUP object and returns you the object reference.
@@ -875,7 +844,7 @@ do
-- --
-- @field #MENU_GROUP -- @field #MENU_GROUP
MENU_GROUP = { MENU_GROUP = {
ClassName = "MENU_GROUP" ClassName = "MENU_GROUP",
} }
--- MENU_GROUP constructor. Creates a new radio menu item for a group. --- MENU_GROUP constructor. Creates a new radio menu item for a group.
@@ -938,7 +907,6 @@ do
end end
--- Removes the main menu and sub menus recursively of this MENU_GROUP. --- Removes the main menu and sub menus recursively of this MENU_GROUP.
-- @param #MENU_GROUP self -- @param #MENU_GROUP self
-- @param MenuStamp -- @param MenuStamp
@@ -971,7 +939,6 @@ do
return self return self
end end
--- @type MENU_GROUP_COMMAND --- @type MENU_GROUP_COMMAND
-- @extends Core.Menu#MENU_COMMAND_BASE -- @extends Core.Menu#MENU_COMMAND_BASE
@@ -981,7 +948,7 @@ do
-- --
-- @field #MENU_GROUP_COMMAND -- @field #MENU_GROUP_COMMAND
MENU_GROUP_COMMAND = { MENU_GROUP_COMMAND = {
ClassName = "MENU_GROUP_COMMAND" ClassName = "MENU_GROUP_COMMAND",
} }
--- Creates a new radio command item for a group --- Creates a new radio command item for a group
@@ -1069,7 +1036,6 @@ do
--- @type MENU_GROUP_DELAYED --- @type MENU_GROUP_DELAYED
-- @extends Core.Menu#MENU_BASE -- @extends Core.Menu#MENU_BASE
--- The MENU_GROUP_DELAYED class manages the main menus for groups. --- The MENU_GROUP_DELAYED class manages the main menus for groups.
-- You can add menus with the @{#MENU_GROUP.New} method, which constructs a MENU_GROUP object and returns you the object reference. -- You can add menus with the @{#MENU_GROUP.New} method, which constructs a MENU_GROUP object and returns you the object reference.
-- Using this object reference, you can then remove ALL the menus and submenus underlying automatically with @{#MENU_GROUP.Remove}. -- Using this object reference, you can then remove ALL the menus and submenus underlying automatically with @{#MENU_GROUP.Remove}.
@@ -1079,7 +1045,7 @@ do
-- --
-- @field #MENU_GROUP_DELAYED -- @field #MENU_GROUP_DELAYED
MENU_GROUP_DELAYED = { MENU_GROUP_DELAYED = {
ClassName = "MENU_GROUP_DELAYED" ClassName = "MENU_GROUP_DELAYED",
} }
--- MENU_GROUP_DELAYED constructor. Creates a new radio menu item for a group. --- MENU_GROUP_DELAYED constructor. Creates a new radio menu item for a group.
@@ -1116,7 +1082,6 @@ do
end end
--- Refreshes a new radio item for a group and submenus --- Refreshes a new radio item for a group and submenus
-- @param #MENU_GROUP_DELAYED self -- @param #MENU_GROUP_DELAYED self
-- @return #MENU_GROUP_DELAYED -- @return #MENU_GROUP_DELAYED
@@ -1135,7 +1100,6 @@ do
end end
--- Refreshes a new radio item for a group and submenus --- Refreshes a new radio item for a group and submenus
-- @param #MENU_GROUP_DELAYED self -- @param #MENU_GROUP_DELAYED self
-- @return #MENU_GROUP_DELAYED -- @return #MENU_GROUP_DELAYED
@@ -1167,7 +1131,6 @@ do
end end
--- Removes the main menu and sub menus recursively of this MENU_GROUP. --- Removes the main menu and sub menus recursively of this MENU_GROUP.
-- @param #MENU_GROUP_DELAYED self -- @param #MENU_GROUP_DELAYED self
-- @param MenuStamp -- @param MenuStamp
@@ -1200,7 +1163,6 @@ do
return self return self
end end
--- @type MENU_GROUP_COMMAND_DELAYED --- @type MENU_GROUP_COMMAND_DELAYED
-- @extends Core.Menu#MENU_COMMAND_BASE -- @extends Core.Menu#MENU_COMMAND_BASE
@@ -1211,7 +1173,7 @@ do
-- --
-- @field #MENU_GROUP_COMMAND_DELAYED -- @field #MENU_GROUP_COMMAND_DELAYED
MENU_GROUP_COMMAND_DELAYED = { MENU_GROUP_COMMAND_DELAYED = {
ClassName = "MENU_GROUP_COMMAND_DELAYED" ClassName = "MENU_GROUP_COMMAND_DELAYED",
} }
--- Creates a new radio command item for a group --- Creates a new radio command item for a group

View File

@@ -68,10 +68,9 @@ MESSAGE.Type = {
Information = "Information", Information = "Information",
Briefing = "Briefing Report", Briefing = "Briefing Report",
Overview = "Overview Report", Overview = "Overview Report",
Detailed = "Detailed Report" Detailed = "Detailed Report",
} }
--- Creates a new MESSAGE object. Note that these MESSAGE objects are not yet displayed on the display panel. You must use the functions @{ToClient} or @{ToCoalition} or @{ToAll} to send these Messages to the respective recipients. --- Creates a new MESSAGE object. Note that these MESSAGE objects are not yet displayed on the display panel. You must use the functions @{ToClient} or @{ToCoalition} or @{ToAll} to send these Messages to the respective recipients.
-- @param self -- @param self
-- @param #string MessageText is the text of the Message. -- @param #string MessageText is the text of the Message.
@@ -80,6 +79,7 @@ MESSAGE.Type = {
-- @param #boolean ClearScreen (optional) Clear all previous messages if true. -- @param #boolean ClearScreen (optional) Clear all previous messages if true.
-- @return #MESSAGE -- @return #MESSAGE
-- @usage -- @usage
--
-- -- Create a series of new Messages. -- -- Create a series of new Messages.
-- -- MessageAll is meant to be sent to all players, for 25 seconds, and is classified as "Score". -- -- MessageAll is meant to be sent to all players, for 25 seconds, and is classified as "Score".
-- -- MessageRED is meant to be sent to the RED players only, for 10 seconds, and is classified as "End of Mission", with ID "Win". -- -- MessageRED is meant to be sent to the RED players only, for 10 seconds, and is classified as "End of Mission", with ID "Win".
@@ -89,11 +89,11 @@ MESSAGE.Type = {
-- MessageRED = MESSAGE:New( "To the RED Players: You receive a penalty because you've killed one of your own units", 25, "Penalty" ) -- MessageRED = MESSAGE:New( "To the RED Players: You receive a penalty because you've killed one of your own units", 25, "Penalty" )
-- MessageClient1 = MESSAGE:New( "Congratulations, you've just hit a target", 25, "Score" ) -- MessageClient1 = MESSAGE:New( "Congratulations, you've just hit a target", 25, "Score" )
-- MessageClient2 = MESSAGE:New( "Congratulations, you've just killed a target", 25, "Score") -- MessageClient2 = MESSAGE:New( "Congratulations, you've just killed a target", 25, "Score")
--
function MESSAGE:New( MessageText, MessageDuration, MessageCategory, ClearScreen ) function MESSAGE:New( MessageText, MessageDuration, MessageCategory, ClearScreen )
local self = BASE:Inherit( self, BASE:New() ) local self = BASE:Inherit( self, BASE:New() )
self:F( { MessageText, MessageDuration, MessageCategory } ) self:F( { MessageText, MessageDuration, MessageCategory } )
self.MessageType = nil self.MessageType = nil
-- When no MessageCategory is given, we don't show it as a title... -- When no MessageCategory is given, we don't show it as a title...
@@ -123,7 +123,6 @@ function MESSAGE:New( MessageText, MessageDuration, MessageCategory, ClearScreen
return self return self
end end
--- Creates a new MESSAGE object of a certain type. --- Creates a new MESSAGE object of a certain type.
-- Note that these MESSAGE objects are not yet displayed on the display panel. -- 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. -- You must use the functions @{ToClient} or @{ToCoalition} or @{ToAll} to send these Messages to the respective recipients.
@@ -134,10 +133,12 @@ end
-- @param #boolean ClearScreen (optional) Clear all previous messages. -- @param #boolean ClearScreen (optional) Clear all previous messages.
-- @return #MESSAGE -- @return #MESSAGE
-- @usage -- @usage
--
-- MessageAll = MESSAGE:NewType( "To all Players: BLUE has won! Each player of BLUE wins 50 points!", MESSAGE.Type.Information ) -- MessageAll = MESSAGE:NewType( "To all Players: BLUE has won! Each player of BLUE wins 50 points!", MESSAGE.Type.Information )
-- MessageRED = MESSAGE:NewType( "To the RED Players: You receive a penalty because you've killed one of your own units", MESSAGE.Type.Information ) -- MessageRED = MESSAGE:NewType( "To the RED Players: You receive a penalty because you've killed one of your own units", MESSAGE.Type.Information )
-- MessageClient1 = MESSAGE:NewType( "Congratulations, you've just hit a target", MESSAGE.Type.Update ) -- MessageClient1 = MESSAGE:NewType( "Congratulations, you've just hit a target", MESSAGE.Type.Update )
-- MessageClient2 = MESSAGE:NewType( "Congratulations, you've just killed a target", MESSAGE.Type.Update ) -- MessageClient2 = MESSAGE:NewType( "Congratulations, you've just killed a target", MESSAGE.Type.Update )
--
function MESSAGE:NewType( MessageText, MessageType, ClearScreen ) function MESSAGE:NewType( MessageText, MessageType, ClearScreen )
local self = BASE:Inherit( self, BASE:New() ) local self = BASE:Inherit( self, BASE:New() )
@@ -156,8 +157,6 @@ function MESSAGE:NewType( MessageText, MessageType, ClearScreen )
return self return self
end end
--- Clears all previous messages from the screen before the new message is displayed. Not that this must come before all functions starting with ToX(), e.g. ToAll(), ToGroup() etc. --- Clears all previous messages from the screen before the new message is displayed. Not that this must come before all functions starting with ToX(), e.g. ToAll(), ToGroup() etc.
-- @param #MESSAGE self -- @param #MESSAGE self
-- @return #MESSAGE -- @return #MESSAGE
@@ -167,14 +166,13 @@ function MESSAGE:Clear()
return self return self
end 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". --- 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 #MESSAGE self
-- @param Wrapper.Client#CLIENT Client is the Group of the Client. -- @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 Settings used to display the message.
-- @return #MESSAGE -- @return #MESSAGE
-- @usage -- @usage
--
-- -- Send the 2 messages created with the @{New} method to the Client Group. -- -- Send the 2 messages created with the @{New} method to the Client Group.
-- -- Note that the Message of MessageClient2 is overwriting the Message of MessageClient1. -- -- Note that the Message of MessageClient2 is overwriting the Message of MessageClient1.
-- ClientGroup = Group.getByName( "ClientGroup" ) -- ClientGroup = Group.getByName( "ClientGroup" )
@@ -189,6 +187,7 @@ end
-- MessageClient2 = MESSAGE:New( "Congratulations, you've just killed a target", "Score", 25, "Score" ) -- MessageClient2 = MESSAGE:New( "Congratulations, you've just killed a target", "Score", 25, "Score" )
-- MessageClient1:ToClient( ClientGroup ) -- MessageClient1:ToClient( ClientGroup )
-- MessageClient2:ToClient( ClientGroup ) -- MessageClient2:ToClient( ClientGroup )
--
function MESSAGE:ToClient( Client, Settings ) function MESSAGE:ToClient( Client, Settings )
self:F( Client ) self:F( Client )
@@ -237,6 +236,7 @@ end
-- @param #MESSAGE self -- @param #MESSAGE self
-- @return #MESSAGE -- @return #MESSAGE
-- @usage -- @usage
--
-- -- Send a message created with the @{New} method to the BLUE coalition. -- -- 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, "Score" ):ToBlue()
-- or -- or
@@ -244,6 +244,7 @@ end
-- or -- 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, "Score" )
-- MessageBLUE:ToBlue() -- MessageBLUE:ToBlue()
--
function MESSAGE:ToBlue() function MESSAGE:ToBlue()
self:F() self:F()
@@ -256,6 +257,7 @@ end
-- @param #MESSAGE self -- @param #MESSAGE self
-- @return #MESSAGE -- @return #MESSAGE
-- @usage -- @usage
--
-- -- Send a message created with the @{New} method to the RED coalition. -- -- 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, "Score" ):ToRed()
-- or -- or
@@ -263,6 +265,7 @@ end
-- or -- 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, "Score" )
-- MessageRED:ToRed() -- MessageRED:ToRed()
--
function MESSAGE:ToRed() function MESSAGE:ToRed()
self:F() self:F()
@@ -277,6 +280,7 @@ end
-- @param Core.Settings#SETTINGS Settings (Optional) Settings for message display. -- @param Core.Settings#SETTINGS Settings (Optional) Settings for message display.
-- @return #MESSAGE Message object. -- @return #MESSAGE Message object.
-- @usage -- @usage
--
-- -- Send a message created with the @{New} method to the RED coalition. -- -- 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, "Score" ):ToCoalition( coalition.side.RED )
-- or -- or
@@ -284,6 +288,7 @@ end
-- or -- 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, "Score" )
-- MessageRED:ToCoalition( coalition.side.RED ) -- MessageRED:ToCoalition( coalition.side.RED )
--
function MESSAGE:ToCoalition( CoalitionSide, Settings ) function MESSAGE:ToCoalition( CoalitionSide, Settings )
self:F( CoalitionSide ) self:F( CoalitionSide )
@@ -323,6 +328,7 @@ end
-- @param Core.Settings#Settings Settings (Optional) Settings for message display. -- @param Core.Settings#Settings Settings (Optional) Settings for message display.
-- @return #MESSAGE -- @return #MESSAGE
-- @usage -- @usage
--
-- -- Send a message created to all players. -- -- 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, "Win" ):ToAll()
-- or -- or
@@ -330,6 +336,7 @@ end
-- or -- 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, "Win" )
-- MessageAll:ToAll() -- MessageAll:ToAll()
--
function MESSAGE:ToAll( Settings ) function MESSAGE:ToAll( Settings )
self:F() self:F()
@@ -347,7 +354,6 @@ function MESSAGE:ToAll(Settings)
return self return self
end end
--- Sends a MESSAGE to all players if the given Condition is true. --- Sends a MESSAGE to all players if the given Condition is true.
-- @param #MESSAGE self -- @param #MESSAGE self
-- @return #MESSAGE -- @return #MESSAGE

View File

@@ -33,15 +33,11 @@
-- @module Core.Point -- @module Core.Point
-- @image Core_Coordinate.JPG -- @image Core_Coordinate.JPG
do -- COORDINATE do -- COORDINATE
--- @type COORDINATE --- @type COORDINATE
-- @extends Core.Base#BASE -- @extends Core.Base#BASE
--- Defines a 3D point in the simulator and with its methods, you can use or manipulate the point in 3D space. --- Defines a 3D point in the simulator and with its methods, you can use or manipulate the point in 3D space.
-- --
-- # 1) Create a COORDINATE object. -- # 1) Create a COORDINATE object.
@@ -52,7 +48,6 @@ do -- COORDINATE
-- * @{#COORDINATE.NewFromVec2}(): from a @{DCS#Vec2} and possible altitude. -- * @{#COORDINATE.NewFromVec2}(): from a @{DCS#Vec2} and possible altitude.
-- * @{#COORDINATE.NewFromVec3}(): from a @{DCS#Vec3}. -- * @{#COORDINATE.NewFromVec3}(): from a @{DCS#Vec3}.
-- --
--
-- # 2) Smoke, flare, explode, illuminate at the coordinate. -- # 2) Smoke, flare, explode, illuminate at the coordinate.
-- --
-- At the point a smoke, flare, explosion and illumination bomb can be triggered. Use the following methods: -- At the point a smoke, flare, explosion and illumination bomb can be triggered. Use the following methods:
@@ -82,7 +77,6 @@ do -- COORDINATE
-- --
-- * @{#COORDINATE.IlluminationBomb}(): To illuminate the point. -- * @{#COORDINATE.IlluminationBomb}(): To illuminate the point.
-- --
--
-- # 3) Create markings on the map. -- # 3) Create markings on the map.
-- --
-- Place markers (text boxes with clarifications for briefings, target locations or any other reference point) -- Place markers (text boxes with clarifications for briefings, target locations or any other reference point)
@@ -128,8 +122,8 @@ do -- COORDINATE
-- ## 4.6) LOS between coordinates. -- ## 4.6) LOS between coordinates.
-- --
-- Calculate if the coordinate has Line of Sight (LOS) with the other given 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. -- Mountains, trees and other objects can be positioned between the two 3D points, preventing visibility 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. -- ## 4.7) Check the coordinate position.
-- --
@@ -139,8 +133,6 @@ do -- COORDINATE
-- * @{#COORDINATE.IsInSphere}(): is in a given sphere. -- * @{#COORDINATE.IsInSphere}(): is in a given sphere.
-- * @{#COORDINATE.IsAtCoordinate2D}(): is in a given coordinate within a specific precision. -- * @{#COORDINATE.IsAtCoordinate2D}(): is in a given coordinate within a specific precision.
-- --
--
--
-- # 5) Measure the simulation environment at the coordinate. -- # 5) Measure the simulation environment at the coordinate.
-- --
-- ## 5.1) Weather specific. -- ## 5.1) Weather specific.
@@ -185,7 +177,7 @@ do -- COORDINATE
-- ## 9) Coordinate text generation -- ## 9) Coordinate text generation
-- --
-- * @{#COORDINATE.ToStringBR}(): Generates a Bearing & Range text in the format of DDD for DI where DDD is degrees and DI is distance. -- * @{#COORDINATE.ToStringBR}(): Generates a Bearing & Range text in the format of DDD for DI where DDD is degrees and DI is distance.
-- * @{#COORDINATE.ToStringLL}(): Generates a Latutude & Longutude text. -- * @{#COORDINATE.ToStringLL}(): Generates a Latitude & Longitude text.
-- --
-- ## 10) Drawings on F10 map -- ## 10) Drawings on F10 map
-- --
@@ -228,7 +220,6 @@ do -- COORDINATE
LandingReFuAr = "LandingReFuAr", LandingReFuAr = "LandingReFuAr",
} }
--- COORDINATE constructor. --- COORDINATE constructor.
-- @param #COORDINATE self -- @param #COORDINATE self
-- @param DCS#Distance x The x coordinate of the Vec3 point, pointing to the North. -- @param DCS#Distance x The x coordinate of the Vec3 point, pointing to the North.
@@ -263,7 +254,7 @@ do -- COORDINATE
--- Create a new COORDINATE object from Vec2 coordinates. --- Create a new COORDINATE object from Vec2 coordinates.
-- @param #COORDINATE self -- @param #COORDINATE self
-- @param DCS#Vec2 Vec2 The Vec2 point. -- @param DCS#Vec2 Vec2 The Vec2 point.
-- @param DCS#Distance LandHeightAdd (optional) The default height if required to be evaluated will be the land height of the x, y coordinate. You can specify an extra height to be added to the land height. -- @param DCS#Distance LandHeightAdd (Optional) The default height if required to be evaluated will be the land height of the x, y coordinate. You can specify an extra height to be added to the land height.
-- @return #COORDINATE -- @return #COORDINATE
function COORDINATE:NewFromVec2( Vec2, LandHeightAdd ) function COORDINATE:NewFromVec2( Vec2, LandHeightAdd )
@@ -293,7 +284,6 @@ do -- COORDINATE
return self return self
end end
--- Return the coordinates of the COORDINATE in Vec3 format. --- Return the coordinates of the COORDINATE in Vec3 format.
-- @param #COORDINATE self -- @param #COORDINATE self
-- @return DCS#Vec3 The Vec3 format coordinate. -- @return DCS#Vec3 The Vec3 format coordinate.
@@ -301,7 +291,6 @@ do -- COORDINATE
return { x = self.x, y = self.y, z = self.z } return { x = self.x, y = self.y, z = self.z }
end end
--- Return the coordinates of the COORDINATE in Vec2 format. --- Return the coordinates of the COORDINATE in Vec2 format.
-- @param #COORDINATE self -- @param #COORDINATE self
-- @return DCS#Vec2 The Vec2 format coordinate. -- @return DCS#Vec2 The Vec2 format coordinate.
@@ -347,7 +336,6 @@ do -- COORDINATE
return self return self
end end
--- Returns the coordinate from the latitude and longitude given in decimal degrees. --- Returns the coordinate from the latitude and longitude given in decimal degrees.
-- @param #COORDINATE self -- @param #COORDINATE self
-- @param #number latitude Latitude in decimal degrees. -- @param #number latitude Latitude in decimal degrees.
@@ -372,7 +360,6 @@ do -- COORDINATE
return _coord return _coord
end end
--- Returns if the 2 coordinates are at the same 2D position. --- Returns if the 2 coordinates are at the same 2D position.
-- @param #COORDINATE self -- @param #COORDINATE self
-- @param #COORDINATE Coordinate -- @param #COORDINATE Coordinate
@@ -409,7 +396,7 @@ do -- COORDINATE
params = { params = {
point = self:GetVec3(), point = self:GetVec3(),
radius = radius, radius = radius,
} },
} }
-- Defaults -- Defaults
@@ -532,7 +519,6 @@ do -- COORDINATE
return umin return umin
end end
--- Calculate the distance from a reference @{#COORDINATE}. --- Calculate the distance from a reference @{#COORDINATE}.
-- @param #COORDINATE self -- @param #COORDINATE self
-- @param #COORDINATE PointVec2Reference The reference @{#COORDINATE}. -- @param #COORDINATE PointVec2Reference The reference @{#COORDINATE}.
@@ -550,10 +536,10 @@ do -- COORDINATE
-- @param #COORDINATE self -- @param #COORDINATE self
-- @param DCS#Distance Distance The Distance to be added in meters. -- @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 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 KeepAltitude 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. -- @return #COORDINATE The new calculated COORDINATE.
function COORDINATE:Translate( Distance, Angle, Keepalt, Overwrite ) function COORDINATE:Translate( Distance, Angle, KeepAltitude, Overwrite )
-- Angle in rad. -- Angle in rad.
local alpha = math.rad( (Angle or 0) ) local alpha = math.rad( (Angle or 0) )
@@ -561,7 +547,7 @@ do -- COORDINATE
local x = Distance * math.cos( alpha ) + self.x -- New x local x = Distance * math.cos( alpha ) + self.x -- New x
local z = Distance * math.sin( alpha ) + self.z -- New z local z = Distance * math.sin( alpha ) + self.z -- New z
local y=Keepalt and self.y or land.getHeight({x=x, y=z}) local y = KeepAltitude and self.y or land.getHeight( { x = x, y = z } )
if Overwrite then if Overwrite then
self.x = x self.x = x
@@ -631,7 +617,6 @@ do -- COORDINATE
return RandomVec2 return RandomVec2
end end
--- Return a random Coordinate within an Outer Radius and optionally NOT within an Inner Radius of the COORDINATE. --- Return a random Coordinate within an Outer Radius and optionally NOT within an Inner Radius of the COORDINATE.
-- @param #COORDINATE self -- @param #COORDINATE self
-- @param DCS#Distance OuterRadius Outer radius in meters. -- @param DCS#Distance OuterRadius Outer radius in meters.
@@ -643,7 +628,6 @@ do -- COORDINATE
return COORDINATE:NewFromVec2( self:GetRandomVec2InRadius( OuterRadius, InnerRadius ) ) return COORDINATE:NewFromVec2( self:GetRandomVec2InRadius( OuterRadius, InnerRadius ) )
end end
--- Return a random Vec3 within an Outer Radius and optionally NOT within an Inner Radius of the COORDINATE. --- Return a random Vec3 within an Outer Radius and optionally NOT within an Inner Radius of the COORDINATE.
-- @param #COORDINATE self -- @param #COORDINATE self
-- @param DCS#Distance OuterRadius -- @param DCS#Distance OuterRadius
@@ -666,14 +650,12 @@ do -- COORDINATE
return land.getHeight( Vec2 ) return land.getHeight( Vec2 )
end end
--- Set the heading of the coordinate, if applicable. --- Set the heading of the coordinate, if applicable.
-- @param #COORDINATE self -- @param #COORDINATE self
function COORDINATE:SetHeading( Heading ) function COORDINATE:SetHeading( Heading )
self.Heading = Heading self.Heading = Heading
end end
--- Get the heading of the coordinate, if applicable. --- Get the heading of the coordinate, if applicable.
-- @param #COORDINATE self -- @param #COORDINATE self
-- @return #number or nil -- @return #number or nil
@@ -681,7 +663,6 @@ do -- COORDINATE
return self.Heading return self.Heading
end end
--- Set the velocity of the COORDINATE. --- Set the velocity of the COORDINATE.
-- @param #COORDINATE self -- @param #COORDINATE self
-- @param #string Velocity Velocity in meters per second. -- @param #string Velocity Velocity in meters per second.
@@ -689,7 +670,6 @@ do -- COORDINATE
self.Velocity = Velocity self.Velocity = Velocity
end end
--- Return the velocity of the COORDINATE. --- Return the velocity of the COORDINATE.
-- @param #COORDINATE self -- @param #COORDINATE self
-- @return #number Velocity in meters per second. -- @return #number Velocity in meters per second.
@@ -698,7 +678,6 @@ do -- COORDINATE
return Velocity or 0 return Velocity or 0
end end
--- Return velocity text of the COORDINATE. --- Return velocity text of the COORDINATE.
-- @param #COORDINATE self -- @param #COORDINATE self
-- @return #string -- @return #string
@@ -707,8 +686,7 @@ do -- COORDINATE
return self:GetVelocityText( Settings ) .. ", " .. self:GetHeadingText( Settings ) return self:GetVelocityText( Settings ) .. ", " .. self:GetHeadingText( Settings )
end end
--- Return a direction vector Vec3 from this COORDINATE to the target COORDINATE.
--- Return a direction vector Vec3 from COORDINATE to the COORDINATE.
-- @param #COORDINATE self -- @param #COORDINATE self
-- @param #COORDINATE TargetCoordinate The target COORDINATE. -- @param #COORDINATE TargetCoordinate The target COORDINATE.
-- @return DCS#Vec3 DirectionVec3 The direction vector in Vec3 format. -- @return DCS#Vec3 DirectionVec3 The direction vector in Vec3 format.
@@ -716,7 +694,6 @@ do -- COORDINATE
return { x = TargetCoordinate.x - self.x, y = TargetCoordinate.y - self.y, z = TargetCoordinate.z - self.z } return { x = TargetCoordinate.x - self.x, y = TargetCoordinate.y - self.y, z = TargetCoordinate.z - self.z }
end end
--- Get a correction in radians of the real magnetic north of the COORDINATE. --- Get a correction in radians of the real magnetic north of the COORDINATE.
-- @param #COORDINATE self -- @param #COORDINATE self
-- @return #number CorrectionRadians The correction in radians. -- @return #number CorrectionRadians The correction in radians.
@@ -727,7 +704,6 @@ do -- COORDINATE
return math.atan2( north_posit.z - TargetVec3.z, north_posit.x - TargetVec3.x ) return math.atan2( north_posit.z - TargetVec3.z, north_posit.x - TargetVec3.x )
end end
--- Return an angle in radians from the COORDINATE using a direction vector in Vec3 format. --- Return an angle in radians from the COORDINATE using a direction vector in Vec3 format.
-- @param #COORDINATE self -- @param #COORDINATE self
-- @param DCS#Vec3 DirectionVec3 The direction vector in Vec3 format. -- @param DCS#Vec3 DirectionVec3 The direction vector in Vec3 format.
@@ -806,8 +782,8 @@ do -- COORDINATE
--- Returns a text of the temperature according the measurement system @{Settings}. --- Returns a text of the temperature according the measurement system @{Settings}.
-- The text will reflect the temperature like this: -- The text will reflect the temperature like this:
-- --
-- - For Russian and European aircraft using the metric system - Degrees Celcius (°C) -- - For Russian and European aircraft using the metric system - Degrees Celsius (°C)
-- - For Americain aircraft we link to the imperial system - Degrees Farenheit (°F) -- - For American aircraft we link to the imperial system - Degrees Fahrenheit (°F)
-- --
-- A text containing a pressure will look like this: -- A text containing a pressure will look like this:
-- --
@@ -819,15 +795,15 @@ do -- COORDINATE
-- @return #string Temperature according the measurement system @{Settings}. -- @return #string Temperature according the measurement system @{Settings}.
function COORDINATE:GetTemperatureText( height, Settings ) function COORDINATE:GetTemperatureText( height, Settings )
local DegreesCelcius = self:GetTemperature( height ) local DegreesCelsius = self:GetTemperature( height )
local Settings = Settings or _SETTINGS local Settings = Settings or _SETTINGS
if DegreesCelcius then if DegreesCelsius then
if Settings:IsMetric() then if Settings:IsMetric() then
return string.format( " %-2.2f °C", DegreesCelcius ) return string.format( " %-2.2f °C", DegreesCelsius )
else else
return string.format( " %-2.2f °F", UTILS.CelciusToFarenheit( DegreesCelcius ) ) return string.format( " %-2.2f °F", UTILS.CelsiusToFahrenheit( DegreesCelsius ) )
end end
else else
return " no temperature" return " no temperature"
@@ -836,7 +812,6 @@ do -- COORDINATE
return nil return nil
end end
--- Returns the pressure in hPa. --- Returns the pressure in hPa.
-- @param #COORDINATE self -- @param #COORDINATE self
-- @param height (Optional) parameter specifying the height ASL. E.g. set height=0 for QNH. -- @param height (Optional) parameter specifying the height ASL. E.g. set height=0 for QNH.
@@ -852,8 +827,8 @@ do -- COORDINATE
--- Returns a text of the pressure according the measurement system @{Settings}. --- Returns a text of the pressure according the measurement system @{Settings}.
-- The text will contain always the pressure in hPa and: -- The text will contain always the pressure in hPa and:
-- --
-- - For Russian and European aircraft using the metric system - hPa and mmHg -- - For Russian and European aircraft using the metric system - hPa and mmHg.
-- - For Americain and European aircraft we link to the imperial system - hPa and inHg -- - For American and European aircraft we link to the imperial system - hPa and inHg.
-- --
-- A text containing a pressure will look like this: -- A text containing a pressure will look like this:
-- --
@@ -884,7 +859,7 @@ do -- COORDINATE
return nil return nil
end end
--- Returns the heading from this to another coordinate. --- Returns the heading from this to another COORDINATE.
-- @param #COORDINATE self -- @param #COORDINATE self
-- @param #COORDINATE ToCoordinate -- @param #COORDINATE ToCoordinate
-- @return #number Heading in degrees. -- @return #number Heading in degrees.
@@ -941,12 +916,11 @@ do -- COORDINATE
return vec3 return vec3
end 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 @{Settings}.
-- The text will reflect the wind like this: -- The text will reflect the wind like this:
-- --
-- - For Russian and European aircraft using the metric system - Wind direction in degrees (°) and wind speed in meters per second (mps). -- - For Russian and European aircraft using the metric system - Wind direction in degrees (°) and wind speed in meters per second (mps).
-- - For Americain aircraft we link to the imperial system - Wind direction in degrees (°) and wind speed in knots per second (kps). -- - For American aircraft we link to the imperial system - Wind direction in degrees (°) and wind speed in knots per second (kps).
-- --
-- A text containing a pressure will look like this: -- A text containing a pressure will look like this:
-- --
@@ -985,10 +959,9 @@ do -- COORDINATE
return ((TargetVec3.x - SourceVec3.x) ^ 2 + (TargetVec3.y - SourceVec3.y) ^ 2 + (TargetVec3.z - SourceVec3.z) ^ 2) ^ 0.5 return ((TargetVec3.x - SourceVec3.x) ^ 2 + (TargetVec3.y - SourceVec3.y) ^ 2 + (TargetVec3.z - SourceVec3.z) ^ 2) ^ 0.5
end end
--- Provides a bearing text in degrees. --- Provides a bearing text in degrees.
-- @param #COORDINATE self -- @param #COORDINATE self
-- @param #number AngleRadians The angle in randians. -- @param #number AngleRadians The angle in radians.
-- @param #number Precision The precision. -- @param #number Precision The precision.
-- @param Core.Settings#SETTINGS Settings -- @param Core.Settings#SETTINGS Settings
-- @return #string The bearing text in degrees. -- @return #string The bearing text in degrees.
@@ -1059,8 +1032,6 @@ do -- COORDINATE
end end
end end
--- Return the velocity text of the COORDINATE. --- Return the velocity text of the COORDINATE.
-- @param #COORDINATE self -- @param #COORDINATE self
-- @return #string Velocity text. -- @return #string Velocity text.
@@ -1078,7 +1049,6 @@ do -- COORDINATE
end end
end end
--- Return the heading text of the COORDINATE. --- Return the heading text of the COORDINATE.
-- @param #COORDINATE self -- @param #COORDINATE self
-- @return #string Heading text. -- @return #string Heading text.
@@ -1091,10 +1061,9 @@ do -- COORDINATE
end end
end end
--- Provides a Bearing / Range string --- Provides a Bearing / Range string
-- @param #COORDINATE self -- @param #COORDINATE self
-- @param #number AngleRadians The angle in randians -- @param #number AngleRadians The angle in radians
-- @param #number Distance The distance -- @param #number Distance The distance
-- @param Core.Settings#SETTINGS Settings -- @param Core.Settings#SETTINGS Settings
-- @return #string The BR Text -- @return #string The BR Text
@@ -1112,7 +1081,7 @@ do -- COORDINATE
--- Provides a Bearing / Range / Altitude string --- Provides a Bearing / Range / Altitude string
-- @param #COORDINATE self -- @param #COORDINATE self
-- @param #number AngleRadians The angle in randians -- @param #number AngleRadians The angle in radians
-- @param #number Distance The distance -- @param #number Distance The distance
-- @param Core.Settings#SETTINGS Settings -- @param Core.Settings#SETTINGS Settings
-- @return #string The BRA Text -- @return #string The BRA Text
@@ -1129,7 +1098,6 @@ do -- COORDINATE
return BRAText return BRAText
end end
--- Set altitude. --- Set altitude.
-- @param #COORDINATE self -- @param #COORDINATE self
-- @param #number altitude New altitude in meters. -- @param #number altitude New altitude in meters.
@@ -1235,7 +1203,6 @@ do -- COORDINATE
return RoutePoint return RoutePoint
end end
--- Build a Waypoint Air "Turning Point". --- Build a Waypoint Air "Turning Point".
-- @param #COORDINATE self -- @param #COORDINATE self
-- @param #COORDINATE.WaypointAltType AltType The altitude type. -- @param #COORDINATE.WaypointAltType AltType The altitude type.
@@ -1247,7 +1214,6 @@ do -- COORDINATE
return self:WaypointAir( AltType, COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.TurningPoint, Speed, true, nil, DCSTasks, description ) return self:WaypointAir( AltType, COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.TurningPoint, Speed, true, nil, DCSTasks, description )
end end
--- Build a Waypoint Air "Fly Over Point". --- Build a Waypoint Air "Fly Over Point".
-- @param #COORDINATE self -- @param #COORDINATE self
-- @param #COORDINATE.WaypointAltType AltType The altitude type. -- @param #COORDINATE.WaypointAltType AltType The altitude type.
@@ -1257,7 +1223,6 @@ do -- COORDINATE
return self:WaypointAir( AltType, COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.FlyoverPoint, Speed ) return self:WaypointAir( AltType, COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.FlyoverPoint, Speed )
end end
--- Build a Waypoint Air "Take Off Parking Hot". --- Build a Waypoint Air "Take Off Parking Hot".
-- @param #COORDINATE self -- @param #COORDINATE self
-- @param #COORDINATE.WaypointAltType AltType The altitude type. -- @param #COORDINATE.WaypointAltType AltType The altitude type.
@@ -1267,7 +1232,6 @@ do -- COORDINATE
return self:WaypointAir( AltType, COORDINATE.WaypointType.TakeOffParkingHot, COORDINATE.WaypointAction.FromParkingAreaHot, Speed ) return self:WaypointAir( AltType, COORDINATE.WaypointType.TakeOffParkingHot, COORDINATE.WaypointAction.FromParkingAreaHot, Speed )
end end
--- Build a Waypoint Air "Take Off Parking". --- Build a Waypoint Air "Take Off Parking".
-- @param #COORDINATE self -- @param #COORDINATE self
-- @param #COORDINATE.WaypointAltType AltType The altitude type. -- @param #COORDINATE.WaypointAltType AltType The altitude type.
@@ -1277,7 +1241,6 @@ do -- COORDINATE
return self:WaypointAir( AltType, COORDINATE.WaypointType.TakeOffParking, COORDINATE.WaypointAction.FromParkingArea, Speed ) return self:WaypointAir( AltType, COORDINATE.WaypointType.TakeOffParking, COORDINATE.WaypointAction.FromParkingArea, Speed )
end end
--- Build a Waypoint Air "Take Off Runway". --- Build a Waypoint Air "Take Off Runway".
-- @param #COORDINATE self -- @param #COORDINATE self
-- @param #COORDINATE.WaypointAltType AltType The altitude type. -- @param #COORDINATE.WaypointAltType AltType The altitude type.
@@ -1287,7 +1250,6 @@ do -- COORDINATE
return self:WaypointAir( AltType, COORDINATE.WaypointType.TakeOff, COORDINATE.WaypointAction.FromRunway, Speed ) return self:WaypointAir( AltType, COORDINATE.WaypointType.TakeOff, COORDINATE.WaypointAction.FromRunway, Speed )
end end
--- Build a Waypoint Air "Landing". --- Build a Waypoint Air "Landing".
-- @param #COORDINATE self -- @param #COORDINATE self
-- @param DCS#Speed Speed Airspeed in km/h. -- @param DCS#Speed Speed Airspeed in km/h.
@@ -1318,7 +1280,6 @@ do -- COORDINATE
return self:WaypointAir( nil, COORDINATE.WaypointType.LandingReFuAr, COORDINATE.WaypointAction.LandingReFuAr, Speed, false, airbase, DCSTasks, description, timeReFuAr or 10 ) return self:WaypointAir( nil, COORDINATE.WaypointType.LandingReFuAr, COORDINATE.WaypointAction.LandingReFuAr, Speed, false, airbase, DCSTasks, description, timeReFuAr or 10 )
end end
--- Build an ground type route point. --- Build an ground type route point.
-- @param #COORDINATE self -- @param #COORDINATE self
-- @param #number Speed (Optional) Speed in km/h. The default speed is 20 km/h. -- @param #number Speed (Optional) Speed in km/h. The default speed is 20 km/h.
@@ -1463,7 +1424,7 @@ do -- COORDINATE
--- Gets the nearest parking spot. --- Gets the nearest parking spot.
-- @param #COORDINATE self -- @param #COORDINATE self
-- @param Wrapper.Airbase#AIRBASE airbase (Optional) Search only parking spots at this airbase. -- @param Wrapper.Airbase#AIRBASE airbase (Optional) Search only parking spots at this airbase.
-- @param Wrapper.Airbase#Terminaltype terminaltype (Optional) Type of the terminal. Default any execpt valid spawn points on runway. -- @param Wrapper.Airbase#Terminaltype terminaltype (Optional) Type of the terminal. Default any except valid spawn points on runway.
-- @param #boolean free (Optional) If true, returns the closest free spot. If false, returns the closest occupied spot. If nil, returns the closest spot regardless of free or occupied. -- @param #boolean free (Optional) If true, returns the closest free spot. If false, returns the closest occupied spot. If nil, returns the closest spot regardless of free or occupied.
-- @return Core.Point#COORDINATE Coordinate of the nearest parking spot. -- @return Core.Point#COORDINATE Coordinate of the nearest parking spot.
-- @return #number Terminal ID. -- @return #number Terminal ID.
@@ -1556,7 +1517,6 @@ do -- COORDINATE
return COORDINATE:NewFromVec2( vec2 ) return COORDINATE:NewFromVec2( vec2 )
end end
--- Returns a table of coordinates to a destination using only roads or railroads. --- Returns a table of coordinates to a destination using only roads or railroads.
-- The first point is the closest point on road of the given coordinate. -- The first point is the closest point on road of the given coordinate.
-- By default, the last point is the closest point on road of the ToCoord. Hence, the coordinate itself and the final ToCoord are not necessarily included in the path. -- By default, the last point is the closest point on road of the ToCoord. Hence, the coordinate itself and the final ToCoord are not necessarily included in the path.
@@ -1565,7 +1525,7 @@ do -- COORDINATE
-- @param #boolean IncludeEndpoints (Optional) Include the coordinate itself and the ToCoordinate in the path. -- @param #boolean IncludeEndpoints (Optional) Include the coordinate itself and the ToCoordinate in the path.
-- @param #boolean Railroad (Optional) If true, path on railroad is returned. Default false. -- @param #boolean Railroad (Optional) If true, path on railroad is returned. Default false.
-- @param #boolean MarkPath (Optional) If true, place markers on F10 map along the path. -- @param #boolean MarkPath (Optional) If true, place markers on F10 map along the path.
-- @param #boolean SmokePath (Optional) If true, put (green) smoke along the -- @param #boolean SmokePath (Optional) If true, put (green) smoke along the the path.
-- @return #table Table of coordinates on road. If no path on road can be found, nil is returned or just the endpoints. -- @return #table Table of coordinates on road. If no path on road can be found, nil is returned or just the endpoints.
-- @return #number Tonal length of path. -- @return #number Tonal length of path.
-- @return #boolean If true a valid path on road/rail was found. If false, only the direct way is possible. -- @return #boolean If true a valid path on road/rail was found. If false, only the direct way is possible.
@@ -1666,7 +1626,6 @@ do -- COORDINATE
return self:GetSurfaceType() == land.SurfaceType.LAND return self:GetSurfaceType() == land.SurfaceType.LAND
end end
--- Checks if the surface type is road. --- Checks if the surface type is road.
-- @param #COORDINATE self -- @param #COORDINATE self
-- @return #boolean If true, the surface type at the coordinate is a road. -- @return #boolean If true, the surface type at the coordinate is a road.
@@ -1695,7 +1654,6 @@ do -- COORDINATE
return self:GetSurfaceType() == land.SurfaceType.WATER return self:GetSurfaceType() == land.SurfaceType.WATER
end end
--- Creates an explosion at the point of a certain intensity. --- Creates an explosion at the point of a certain intensity.
-- @param #COORDINATE self -- @param #COORDINATE self
-- @param #number ExplosionIntensity Intensity of the explosion in kg TNT. Default 100 kg. -- @param #number ExplosionIntensity Intensity of the explosion in kg TNT. Default 100 kg.
@@ -1721,7 +1679,6 @@ do -- COORDINATE
trigger.action.illuminationBomb( self:GetVec3(), power ) trigger.action.illuminationBomb( self:GetVec3(), power )
end end
--- Smokes the point in a color. --- Smokes the point in a color.
-- @param #COORDINATE self -- @param #COORDINATE self
-- @param Utilities.Utils#SMOKECOLOR SmokeColor -- @param Utilities.Utils#SMOKECOLOR SmokeColor
@@ -1768,89 +1725,89 @@ do -- COORDINATE
--- Big smoke and fire at the coordinate. --- Big smoke and fire at the coordinate.
-- @param #COORDINATE self -- @param #COORDINATE self
-- @param Utilities.Utils#BIGSMOKEPRESET preset Smoke preset (0=small smoke and fire, 1=medium smoke and fire, 2=large smoke and fire, 3=huge smoke and fire, 4=small smoke, 5=medium smoke, 6=large smoke, 7=huge smoke). -- @param Utilities.Utils#BIGSMOKEPRESET preset Smoke preset (0=small smoke and fire, 1=medium smoke and fire, 2=large smoke and fire, 3=huge smoke and fire, 4=small smoke, 5=medium smoke, 6=large smoke, 7=huge smoke).
-- @param #number density (Optional) Smoke density. Number in [0,...,1]. Default 0.5. -- @param #number Density (Optional) Smoke density. Number in [0,...,1]. Default 0.5.
function COORDINATE:BigSmokeAndFire( preset, density ) function COORDINATE:BigSmokeAndFire( Preset, Density )
self:F2( { preset=preset, density=density } ) self:F2( { Preset = Preset, Density = Density } )
density=density or 0.5 Density = Density or 0.5
trigger.action.effectSmokeBig( self:GetVec3(), preset, density ) trigger.action.effectSmokeBig( self:GetVec3(), Preset, Density )
end end
--- Small smoke and fire at the coordinate. --- Small smoke and fire at the coordinate.
-- @param #COORDINATE self -- @param #COORDINATE self
-- @number density (Optional) Smoke density. Number between 0 and 1. Default 0.5. -- @number Density (Optional) Smoke density. Number between 0 and 1. Default 0.5.
function COORDINATE:BigSmokeAndFireSmall( density ) function COORDINATE:BigSmokeAndFireSmall( Density )
self:F2( { density=density } ) self:F2( { Density = Density } )
density=density or 0.5 Density = Density or 0.5
self:BigSmokeAndFire(BIGSMOKEPRESET.SmallSmokeAndFire, density) self:BigSmokeAndFire( BIGSMOKEPRESET.SmallSmokeAndFire, Density )
end end
--- Medium smoke and fire at the coordinate. --- Medium smoke and fire at the coordinate.
-- @param #COORDINATE self -- @param #COORDINATE self
-- @number density (Optional) Smoke density. Number between 0 and 1. Default 0.5. -- @number Density (Optional) Smoke density. Number between 0 and 1. Default 0.5.
function COORDINATE:BigSmokeAndFireMedium( density ) function COORDINATE:BigSmokeAndFireMedium( Density )
self:F2( { density=density } ) self:F2( { Density = Density } )
density=density or 0.5 Density = Density or 0.5
self:BigSmokeAndFire(BIGSMOKEPRESET.MediumSmokeAndFire, density) self:BigSmokeAndFire( BIGSMOKEPRESET.MediumSmokeAndFire, Density )
end end
--- Large smoke and fire at the coordinate. --- Large smoke and fire at the coordinate.
-- @param #COORDINATE self -- @param #COORDINATE self
-- @number density (Optional) Smoke density. Number between 0 and 1. Default 0.5. -- @number Density (Optional) Smoke density. Number between 0 and 1. Default 0.5.
function COORDINATE:BigSmokeAndFireLarge( density ) function COORDINATE:BigSmokeAndFireLarge( Density )
self:F2( { density=density } ) self:F2( { Density = Density } )
density=density or 0.5 Density = Density or 0.5
self:BigSmokeAndFire(BIGSMOKEPRESET.LargeSmokeAndFire, density) self:BigSmokeAndFire( BIGSMOKEPRESET.LargeSmokeAndFire, Density )
end end
--- Huge smoke and fire at the coordinate. --- Huge smoke and fire at the coordinate.
-- @param #COORDINATE self -- @param #COORDINATE self
-- @number density (Optional) Smoke density. Number between 0 and 1. Default 0.5. -- @number Density (Optional) Smoke density. Number between 0 and 1. Default 0.5.
function COORDINATE:BigSmokeAndFireHuge( density ) function COORDINATE:BigSmokeAndFireHuge( Density )
self:F2( { density=density } ) self:F2( { Density = Density } )
density=density or 0.5 Density = Density or 0.5
self:BigSmokeAndFire(BIGSMOKEPRESET.HugeSmokeAndFire, density) self:BigSmokeAndFire( BIGSMOKEPRESET.HugeSmokeAndFire, Density )
end end
--- Small smoke at the coordinate. --- Small smoke at the coordinate.
-- @param #COORDINATE self -- @param #COORDINATE self
-- @number density (Optional) Smoke density. Number between 0 and 1. Default 0.5. -- @number Density (Optional) Smoke density. Number between 0 and 1. Default 0.5.
function COORDINATE:BigSmokeSmall( density ) function COORDINATE:BigSmokeSmall( Density )
self:F2( { density=density } ) self:F2( { Density = Density } )
density=density or 0.5 Density = Density or 0.5
self:BigSmokeAndFire(BIGSMOKEPRESET.SmallSmoke, density) self:BigSmokeAndFire( BIGSMOKEPRESET.SmallSmoke, Density )
end end
--- Medium smoke at the coordinate. --- Medium smoke at the coordinate.
-- @param #COORDINATE self -- @param #COORDINATE self
-- @number density (Optional) Smoke density. Number between 0 and 1. Default 0.5. -- @number Density (Optional) Smoke density. Number between 0 and 1. Default 0.5.
function COORDINATE:BigSmokeMedium( density ) function COORDINATE:BigSmokeMedium( Density )
self:F2( { density=density } ) self:F2( { Density = Density } )
density=density or 0.5 Density = Density or 0.5
self:BigSmokeAndFire(BIGSMOKEPRESET.MediumSmoke, density) self:BigSmokeAndFire( BIGSMOKEPRESET.MediumSmoke, Density )
end end
--- Large smoke at the coordinate. --- Large smoke at the coordinate.
-- @param #COORDINATE self -- @param #COORDINATE self
-- @number density (Optional) Smoke density. Number between 0 and 1. Default 0.5. -- @number Density (Optional) Smoke density. Number between 0 and 1. Default 0.5.
function COORDINATE:BigSmokeLarge( density ) function COORDINATE:BigSmokeLarge( Density )
self:F2( { density=density } ) self:F2( { Density = Density } )
density=density or 0.5 Density = Density or 0.5
self:BigSmokeAndFire(BIGSMOKEPRESET.LargeSmoke, density) self:BigSmokeAndFire( BIGSMOKEPRESET.LargeSmoke, Density )
end end
--- Huge smoke at the coordinate. --- Huge smoke at the coordinate.
-- @param #COORDINATE self -- @param #COORDINATE self
-- @number density (Optional) Smoke density. Number between 0 and 1. Default 0.5. -- @number Density (Optional) Smoke density. Number between 0 and 1. Default 0.5.
function COORDINATE:BigSmokeHuge( density ) function COORDINATE:BigSmokeHuge( Density )
self:F2( { density=density } ) self:F2( { Density = Density } )
density=density or 0.5 Density = Density or 0.5
self:BigSmokeAndFire(BIGSMOKEPRESET.HugeSmoke, density) self:BigSmokeAndFire( BIGSMOKEPRESET.HugeSmoke, Density )
end end
--- Flares the point in a color. --- Flares the point in a color.
-- @param #COORDINATE self -- @param #COORDINATE self
-- @param Utilities.Utils#FLARECOLOR FlareColor -- @param Utilities.Utils#FLARECOLOR FlareColor
-- @param DCS#Azimuth Azimuth (optional) The azimuth of the flare direction. The default azimuth is 0. -- @param DCS#Azimuth Azimuth (Optional) The azimuth of the flare direction. The default azimuth is 0.
function COORDINATE:Flare( FlareColor, Azimuth ) function COORDINATE:Flare( FlareColor, Azimuth )
self:F2( { FlareColor } ) self:F2( { FlareColor } )
trigger.action.signalFlare( self:GetVec3(), FlareColor, Azimuth and Azimuth or 0 ) trigger.action.signalFlare( self:GetVec3(), FlareColor, Azimuth and Azimuth or 0 )
@@ -1858,7 +1815,7 @@ do -- COORDINATE
--- Flare the COORDINATE White. --- Flare the COORDINATE White.
-- @param #COORDINATE self -- @param #COORDINATE self
-- @param DCS#Azimuth Azimuth (optional) The azimuth of the flare direction. The default azimuth is 0. -- @param DCS#Azimuth Azimuth (Optional) The azimuth of the flare direction. The default azimuth is 0.
function COORDINATE:FlareWhite( Azimuth ) function COORDINATE:FlareWhite( Azimuth )
self:F2( Azimuth ) self:F2( Azimuth )
self:Flare( FLARECOLOR.White, Azimuth ) self:Flare( FLARECOLOR.White, Azimuth )
@@ -1866,7 +1823,7 @@ do -- COORDINATE
--- Flare the COORDINATE Yellow. --- Flare the COORDINATE Yellow.
-- @param #COORDINATE self -- @param #COORDINATE self
-- @param DCS#Azimuth Azimuth (optional) The azimuth of the flare direction. The default azimuth is 0. -- @param DCS#Azimuth Azimuth (Optional) The azimuth of the flare direction. The default azimuth is 0.
function COORDINATE:FlareYellow( Azimuth ) function COORDINATE:FlareYellow( Azimuth )
self:F2( Azimuth ) self:F2( Azimuth )
self:Flare( FLARECOLOR.Yellow, Azimuth ) self:Flare( FLARECOLOR.Yellow, Azimuth )
@@ -1874,7 +1831,7 @@ do -- COORDINATE
--- Flare the COORDINATE Green. --- Flare the COORDINATE Green.
-- @param #COORDINATE self -- @param #COORDINATE self
-- @param DCS#Azimuth Azimuth (optional) The azimuth of the flare direction. The default azimuth is 0. -- @param DCS#Azimuth Azimuth (Optional) The azimuth of the flare direction. The default azimuth is 0.
function COORDINATE:FlareGreen( Azimuth ) function COORDINATE:FlareGreen( Azimuth )
self:F2( Azimuth ) self:F2( Azimuth )
self:Flare( FLARECOLOR.Green, Azimuth ) self:Flare( FLARECOLOR.Green, Azimuth )
@@ -1991,7 +1948,7 @@ do -- COORDINATE
--- Line to all. --- Line to all.
-- Creates a line on the F10 map from one point to another. -- Creates a line on the F10 map from one point to another.
-- @param #COORDINATE self -- @param #COORDINATE self
-- @param #COORDINATE Endpoint COORDIANTE to where the line is drawn. -- @param #COORDINATE Endpoint COORDINATE to where the line is drawn.
-- @param #number Coalition Coalition: All=-1, Neutral=0, Red=1, Blue=2. Default -1=All. -- @param #number Coalition Coalition: All=-1, Neutral=0, Red=1, Blue=2. Default -1=All.
-- @param #table Color RGB color table {r, g, b}, e.g. {1,0,0} for red (default). -- @param #table Color RGB color table {r, g, b}, e.g. {1,0,0} for red (default).
-- @param #number Alpha Transparency [0,1]. Default 1. -- @param #number Alpha Transparency [0,1]. Default 1.
@@ -2016,7 +1973,7 @@ do -- COORDINATE
--- Circle to all. --- Circle to all.
-- Creates a circle on the map with a given radius, color, fill color, and outline. -- Creates a circle on the map with a given radius, color, fill color, and outline.
-- @param #COORDINATE self -- @param #COORDINATE self
-- @param #numberr Radius Radius in meters. Default 1000 m. -- @param #number Radius Radius in meters. Default 1000 m.
-- @param #number Coalition Coalition: All=-1, Neutral=0, Red=1, Blue=2. Default -1=All. -- @param #number Coalition Coalition: All=-1, Neutral=0, Red=1, Blue=2. Default -1=All.
-- @param #table Color RGB color table {r, g, b}, e.g. {1,0,0} for red (default). -- @param #table Color RGB color table {r, g, b}, e.g. {1,0,0} for red (default).
-- @param #number Alpha Transparency [0,1]. Default 1. -- @param #number Alpha Transparency [0,1]. Default 1.
@@ -2048,7 +2005,7 @@ do -- COORDINATE
--- Rectangle to all. Creates a rectangle on the map from the COORDINATE in one corner to the end COORDINATE in the opposite corner. --- Rectangle to all. Creates a rectangle on the map from the COORDINATE in one corner to the end COORDINATE in the opposite corner.
-- Creates a line on the F10 map from one point to another. -- Creates a line on the F10 map from one point to another.
-- @param #COORDINATE self -- @param #COORDINATE self
-- @param #COORDINATE Endpoint COORDIANTE in the opposite corner. -- @param #COORDINATE Endpoint COORDINATE in the opposite corner.
-- @param #number Coalition Coalition: All=-1, Neutral=0, Red=1, Blue=2. Default -1=All. -- @param #number Coalition Coalition: All=-1, Neutral=0, Red=1, Blue=2. Default -1=All.
-- @param #table Color RGB color table {r, g, b}, e.g. {1,0,0} for red (default). -- @param #table Color RGB color table {r, g, b}, e.g. {1,0,0} for red (default).
-- @param #number Alpha Transparency [0,1]. Default 1. -- @param #number Alpha Transparency [0,1]. Default 1.
@@ -2246,7 +2203,6 @@ do -- COORDINATE
return IsLOS return IsLOS
end end
--- Returns if a Coordinate is in a certain Radius of this Coordinate in 2D plane using the X and Z axis. --- Returns if a Coordinate is in a certain Radius of this Coordinate in 2D plane using the X and Z axis.
-- @param #COORDINATE self -- @param #COORDINATE self
-- @param #COORDINATE Coordinate The coordinate that will be tested if it is in the radius of this coordinate. -- @param #COORDINATE Coordinate The coordinate that will be tested if it is in the radius of this coordinate.
@@ -2262,7 +2218,6 @@ do -- COORDINATE
return InRadius return InRadius
end end
--- Returns if a Coordinate is in a certain radius of this Coordinate in 3D space using the X, Y and Z axis. --- Returns if a Coordinate is in a certain radius of this Coordinate in 3D space using the X, Y and Z axis.
-- So Radius defines the radius of the a Sphere in 3D space around this coordinate. -- So Radius defines the radius of the a Sphere in 3D space around this coordinate.
-- @param #COORDINATE self -- @param #COORDINATE self
@@ -2569,11 +2524,10 @@ do -- COORDINATE
return delta / 60 return delta / 60
end end
--- Return a BR string from a COORDINATE to the COORDINATE. --- Return a BR string from a COORDINATE to the COORDINATE.
-- @param #COORDINATE self -- @param #COORDINATE self
-- @param #COORDINATE FromCoordinate The coordinate to measure the distance and the bearing from. -- @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 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 BR text. -- @return #string The BR text.
function COORDINATE:ToStringBR( FromCoordinate, Settings ) function COORDINATE:ToStringBR( FromCoordinate, Settings )
local DirectionVec3 = FromCoordinate:GetDirectionVec3( self ) local DirectionVec3 = FromCoordinate:GetDirectionVec3( self )
@@ -2585,7 +2539,7 @@ do -- COORDINATE
--- Return a BRAA string from a COORDINATE to the COORDINATE. --- Return a BRAA string from a COORDINATE to the COORDINATE.
-- @param #COORDINATE self -- @param #COORDINATE self
-- @param #COORDINATE FromCoordinate The coordinate to measure the distance and the bearing from. -- @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 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 BR text. -- @return #string The BR text.
function COORDINATE:ToStringBRA( FromCoordinate, Settings, Language ) function COORDINATE:ToStringBRA( FromCoordinate, Settings, Language )
local DirectionVec3 = FromCoordinate:GetDirectionVec3( self ) local DirectionVec3 = FromCoordinate:GetDirectionVec3( self )
@@ -2598,7 +2552,7 @@ do -- COORDINATE
--- Return a BULLS string out of the BULLS of the coalition to the COORDINATE. --- Return a BULLS string out of the BULLS of the coalition to the COORDINATE.
-- @param #COORDINATE self -- @param #COORDINATE self
-- @param DCS#coalition.side Coalition The coalition. -- @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 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 BR text. -- @return #string The BR text.
function COORDINATE:ToStringBULLS( Coalition, Settings ) function COORDINATE:ToStringBULLS( Coalition, Settings )
local BullsCoordinate = COORDINATE:NewFromVec3( coalition.getMainRefPoint( Coalition ) ) local BullsCoordinate = COORDINATE:NewFromVec3( coalition.getMainRefPoint( Coalition ) )
@@ -2646,7 +2600,7 @@ do -- COORDINATE
--- Provides a Lat Lon string in Degree Minute Second format. --- Provides a Lat Lon string in Degree Minute Second format.
-- @param #COORDINATE self -- @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. -- @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 LL DMS Text -- @return #string The LL DMS Text
function COORDINATE:ToStringLLDMS( Settings ) function COORDINATE:ToStringLLDMS( Settings )
@@ -2657,7 +2611,7 @@ do -- COORDINATE
--- Provides a Lat Lon string in Degree Decimal Minute format. --- Provides a Lat Lon string in Degree Decimal Minute format.
-- @param #COORDINATE self -- @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. -- @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 LL DDM Text -- @return #string The LL DDM Text
function COORDINATE:ToStringLLDDM( Settings ) function COORDINATE:ToStringLLDDM( Settings )
@@ -2668,7 +2622,7 @@ do -- COORDINATE
--- Provides a MGRS string --- Provides a MGRS string
-- @param #COORDINATE self -- @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. -- @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 -- @return #string The MGRS Text
function COORDINATE:ToStringMGRS( Settings ) -- R2.1 Fixes issue #424. function COORDINATE:ToStringMGRS( Settings ) -- R2.1 Fixes issue #424.
@@ -2685,7 +2639,7 @@ do -- COORDINATE
-- @param #COORDINATE ReferenceCoord The refrence coordinate. -- @param #COORDINATE ReferenceCoord The refrence coordinate.
-- @param #string ReferenceName The refrence name. -- @param #string ReferenceName The refrence name.
-- @param Wrapper.Controllable#CONTROLLABLE Controllable -- @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 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 coordinate Text in the configured coordinate system. -- @return #string The coordinate Text in the configured coordinate system.
function COORDINATE:ToStringFromRP( ReferenceCoord, ReferenceName, Controllable, Settings ) function COORDINATE:ToStringFromRP( ReferenceCoord, ReferenceName, Controllable, Settings )
@@ -2714,7 +2668,7 @@ do -- COORDINATE
--- Provides a coordinate string of the point, based on the A2G coordinate format system. --- Provides a coordinate string of the point, based on the A2G coordinate format system.
-- @param #COORDINATE self -- @param #COORDINATE self
-- @param Wrapper.Controllable#CONTROLLABLE Controllable -- @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 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 coordinate Text in the configured coordinate system. -- @return #string The coordinate Text in the configured coordinate system.
function COORDINATE:ToStringA2G( Controllable, Settings ) function COORDINATE:ToStringA2G( Controllable, Settings )
@@ -2745,11 +2699,10 @@ do -- COORDINATE
end end
--- Provides a coordinate string of the point, based on the A2A coordinate format system. --- Provides a coordinate string of the point, based on the A2A coordinate format system.
-- @param #COORDINATE self -- @param #COORDINATE self
-- @param Wrapper.Controllable#CONTROLLABLE Controllable -- @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 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 coordinate Text in the configured coordinate system. -- @return #string The coordinate Text in the configured coordinate system.
function COORDINATE:ToStringA2A( Controllable, Settings, Language ) -- R2.2 function COORDINATE:ToStringA2A( Controllable, Settings, Language ) -- R2.2
@@ -2788,7 +2741,7 @@ do -- COORDINATE
-- * Can be overridden if for a GROUP containing x clients, a menu was selected to override the default. -- * Can be overridden if for a GROUP containing x clients, a menu was selected to override the default.
-- @param #COORDINATE self -- @param #COORDINATE self
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The controllable to retrieve the settings from, otherwise the default settings will be chosen. -- @param Wrapper.Controllable#CONTROLLABLE Controllable The controllable to retrieve the settings from, otherwise the default settings will be chosen.
-- @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 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 Tasking.Task#TASK Task The task for which coordinates need to be calculated. -- @param Tasking.Task#TASK Task The task for which coordinates need to be calculated.
-- @return #string The coordinate Text in the configured coordinate system. -- @return #string The coordinate Text in the configured coordinate system.
function COORDINATE:ToString( Controllable, Settings, Task ) function COORDINATE:ToString( Controllable, Settings, Task )
@@ -2816,7 +2769,6 @@ do -- COORDINATE
end end
end end
if ModeA2A == nil then if ModeA2A == nil then
local IsAir = Controllable and (Controllable:IsAirPlane() or Controllable:IsHelicopter()) or false local IsAir = Controllable and (Controllable:IsAirPlane() or Controllable:IsHelicopter()) or false
if IsAir then if IsAir then
@@ -2826,7 +2778,6 @@ do -- COORDINATE
end end
end end
if ModeA2A == true then if ModeA2A == true then
return self:ToStringA2A( Controllable, Settings ) return self:ToStringA2A( Controllable, Settings )
else else
@@ -2842,7 +2793,7 @@ do -- COORDINATE
-- * Can be overridden if for a GROUP containing x clients, a menu was selected to override the default. -- * Can be overridden if for a GROUP containing x clients, a menu was selected to override the default.
-- @param #COORDINATE self -- @param #COORDINATE self
-- @param Wrapper.Controllable#CONTROLLABLE Controllable -- @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 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. -- @return #string The pressure text in the configured measurement system.
function COORDINATE:ToStringPressure( Controllable, Settings ) -- R2.3 function COORDINATE:ToStringPressure( Controllable, Settings ) -- R2.3
@@ -2858,7 +2809,7 @@ do -- COORDINATE
-- * Can be overridden if for a GROUP containing x clients, a menu was selected to override the default. -- * Can be overridden if for a GROUP containing x clients, a menu was selected to override the default.
-- @param #COORDINATE self -- @param #COORDINATE self
-- @param Wrapper.Controllable#CONTROLLABLE Controllable -- @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 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 wind text in the configured measurement system. -- @return #string The wind text in the configured measurement system.
function COORDINATE:ToStringWind( Controllable, Settings ) function COORDINATE:ToStringWind( Controllable, Settings )
@@ -2901,7 +2852,6 @@ do -- POINT_VEC3
-- @field #POINT_VEC3.RoutePointAction RoutePointAction -- @field #POINT_VEC3.RoutePointAction RoutePointAction
-- @extends #COORDINATE -- @extends #COORDINATE
--- Defines a 3D point in the simulator and with its methods, you can use or manipulate the point in 3D space. --- Defines a 3D point in the simulator and with its methods, you can use or manipulate the point in 3D space.
-- --
-- **Important Note:** Most of the functions in this section were taken from MIST, and reworked to OO concepts. -- **Important Note:** Most of the functions in this section were taken from MIST, and reworked to OO concepts.
@@ -2909,7 +2859,6 @@ do -- POINT_VEC3
-- I want to emphasize that the formulas embedded in the MIST framework were created by Grimes or previous authors, -- I want to emphasize that the formulas embedded in the MIST framework were created by Grimes or previous authors,
-- who you can find on the Eagle Dynamics Forums. -- who you can find on the Eagle Dynamics Forums.
-- --
--
-- ## POINT_VEC3 constructor -- ## POINT_VEC3 constructor
-- --
-- A new POINT_VEC3 object can be created with: -- A new POINT_VEC3 object can be created with:
@@ -2931,19 +2880,16 @@ do -- POINT_VEC3
-- --
-- local Vec3 = PointVec3:AddX( 100 ):AddZ( 150 ):GetVec3() -- local Vec3 = PointVec3:AddX( 100 ):AddZ( 150 ):GetVec3()
-- --
--
-- ## 3D calculation methods -- ## 3D calculation methods
-- --
-- Various calculation methods exist to use or manipulate 3D space. Find below a short description of each method: -- Various calculation methods exist to use or manipulate 3D space. Find below a short description of each method:
-- --
--
-- ## Point Randomization -- ## Point Randomization
-- --
-- Various methods exist to calculate random locations around a given 3D point. -- Various methods exist to calculate random locations around a given 3D point.
-- --
-- * @{#POINT_VEC3.GetRandomPointVec3InRadius}(): Provides a random 3D point around the current 3D point, in the given inner to outer band. -- * @{#POINT_VEC3.GetRandomPointVec3InRadius}(): Provides a random 3D point around the current 3D point, in the given inner to outer band.
-- --
--
-- @field #POINT_VEC3 -- @field #POINT_VEC3
POINT_VEC3 = { POINT_VEC3 = {
ClassName = "POINT_VEC3", ClassName = "POINT_VEC3",
@@ -2994,7 +2940,7 @@ do -- POINT_VEC3
--- Create a new POINT_VEC3 object from Vec2 coordinates. --- Create a new POINT_VEC3 object from Vec2 coordinates.
-- @param #POINT_VEC3 self -- @param #POINT_VEC3 self
-- @param DCS#Vec2 Vec2 The Vec2 point. -- @param DCS#Vec2 Vec2 The Vec2 point.
-- @param DCS#Distance LandHeightAdd (optional) Add a landheight. -- @param DCS#Distance LandHeightAdd (Optional) Add a landheight.
-- @return Core.Point#POINT_VEC3 self -- @return Core.Point#POINT_VEC3 self
function POINT_VEC3:NewFromVec2( Vec2, LandHeightAdd ) function POINT_VEC3:NewFromVec2( Vec2, LandHeightAdd )
@@ -3004,7 +2950,6 @@ do -- POINT_VEC3
return self return self
end end
--- Create a new POINT_VEC3 object from Vec3 coordinates. --- Create a new POINT_VEC3 object from Vec3 coordinates.
-- @param #POINT_VEC3 self -- @param #POINT_VEC3 self
-- @param DCS#Vec3 Vec3 The Vec3 point. -- @param DCS#Vec3 Vec3 The Vec3 point.
@@ -3017,8 +2962,6 @@ do -- POINT_VEC3
return self return self
end end
--- Return the x coordinate of the POINT_VEC3. --- Return the x coordinate of the POINT_VEC3.
-- @param #POINT_VEC3 self -- @param #POINT_VEC3 self
-- @return #number The x coodinate. -- @return #number The x coodinate.
@@ -3141,13 +3084,11 @@ do -- POINT_VEC2
ClassName = "POINT_VEC2", ClassName = "POINT_VEC2",
} }
--- POINT_VEC2 constructor. --- POINT_VEC2 constructor.
-- @param #POINT_VEC2 self -- @param #POINT_VEC2 self
-- @param DCS#Distance x The x coordinate of the Vec3 point, pointing to the North. -- @param DCS#Distance x The x coordinate of the Vec3 point, pointing to the North.
-- @param DCS#Distance y The y coordinate of the Vec3 point, pointing to the Right. -- @param DCS#Distance y The y coordinate of the Vec3 point, pointing to the Right.
-- @param DCS#Distance LandHeightAdd (optional) The default height if required to be evaluated will be the land height of the x, y coordinate. You can specify an extra height to be added to the land height. -- @param DCS#Distance LandHeightAdd (Optional) The default height if required to be evaluated will be the land height of the x, y coordinate. You can specify an extra height to be added to the land height.
-- @return Core.Point#POINT_VEC2 -- @return Core.Point#POINT_VEC2
function POINT_VEC2:New( x, y, LandHeightAdd ) function POINT_VEC2:New( x, y, LandHeightAdd )
@@ -3294,11 +3235,10 @@ do -- POINT_VEC2
-- @param #number Altitude The Altitude to add. If nothing (nil) is given, then the current land altitude is set. -- @param #number Altitude The Altitude to add. If nothing (nil) is given, then the current land altitude is set.
-- @return #POINT_VEC2 -- @return #POINT_VEC2
function POINT_VEC2:AddAlt( Altitude ) function POINT_VEC2:AddAlt( Altitude )
self.y = land.getHeight( { x = self.x, y = self.z } ) + Altitude or 0 self.y = land.getHeight( { x = self.x, y = self.z } ) + (Altitude or 0)
return self return self
end end
--- Return a random POINT_VEC2 within an Outer Radius and optionally NOT within an Inner Radius of the POINT_VEC2. --- Return a random POINT_VEC2 within an Outer Radius and optionally NOT within an Inner Radius of the POINT_VEC2.
-- @param #POINT_VEC2 self -- @param #POINT_VEC2 self
-- @param DCS#Distance OuterRadius -- @param DCS#Distance OuterRadius
@@ -3326,4 +3266,3 @@ do -- POINT_VEC2
end end

View File

@@ -15,7 +15,6 @@
-- @module Core.Report -- @module Core.Report
-- @image Core_Report.JPG -- @image Core_Report.JPG
--- @type REPORT --- @type REPORT
-- @extends Core.Base#BASE -- @extends Core.Base#BASE
@@ -50,7 +49,6 @@ function REPORT:HasText() --R2.1
return #self.Report > 0 return #self.Report > 0
end end
--- Set indent of a REPORT. --- Set indent of a REPORT.
-- @param #REPORT self -- @param #REPORT self
-- @param #number Indent -- @param #number Indent
@@ -60,7 +58,6 @@ function REPORT:SetIndent( Indent ) --R2.1
return self return self
end end
--- Add a new line to a REPORT. --- Add a new line to a REPORT.
-- @param #REPORT self -- @param #REPORT self
-- @param #string Text -- @param #string Text
@@ -80,7 +77,7 @@ function REPORT:AddIndent( Text, Separator )
return self return self
end end
--- Produces the text of the report, taking into account an optional delimeter, which is \n by default. --- Produces the text of the report, taking into account an optional delimiter, which is \n by default.
-- @param #REPORT self -- @param #REPORT self
-- @param #string Delimiter (optional) A delimiter text. -- @param #string Delimiter (optional) A delimiter text.
-- @return #string The report text. -- @return #string The report text.

View File

@@ -17,7 +17,7 @@
-- - When a SCHEDULER object is not attached to another object (that is, it's first :Schedule() parameter is nil), then the SCHEDULER object is _persistent_ within memory. -- - When a SCHEDULER object is not attached to another object (that is, it's first :Schedule() parameter is nil), then the SCHEDULER object is _persistent_ within memory.
-- - When a SCHEDULER object *is* attached to another object, then the SCHEDULER object is _not persistent_ within memory after a garbage collection! -- - When a SCHEDULER object *is* attached to another object, then the SCHEDULER object is _not persistent_ within memory after a garbage collection!
-- --
-- The none persistency of SCHEDULERS attached to objects is required to allow SCHEDULER objects to be garbage collectged, when the parent object is also desroyed or nillified and garbage collected. -- The non-persistency of SCHEDULERS attached to objects is required to allow SCHEDULER objects to be garbage collected when the parent object is destroyed, or set to nil and garbage collected.
-- Even when there are pending timer scheduled functions to be executed for the SCHEDULER object, -- Even when there are pending timer scheduled functions to be executed for the SCHEDULER object,
-- these will not be executed anymore when the SCHEDULER object has been destroyed. -- these will not be executed anymore when the SCHEDULER object has been destroyed.
-- --
@@ -38,7 +38,7 @@
-- @type SCHEDULEDISPATCHER -- @type SCHEDULEDISPATCHER
-- @field #string ClassName Name of the class. -- @field #string ClassName Name of the class.
-- @field #number CallID Call ID counter. -- @field #number CallID Call ID counter.
-- @field #table PersistentSchedulers Persistant schedulers. -- @field #table PersistentSchedulers Persistent schedulers.
-- @field #table ObjectSchedulers Schedulers that only exist as long as the master object exists. -- @field #table ObjectSchedulers Schedulers that only exist as long as the master object exists.
-- @field #table Schedule Meta table setmetatable( {}, { __mode = "k" } ). -- @field #table Schedule Meta table setmetatable( {}, { __mode = "k" } ).
-- @extends Core.Base#BASE -- @extends Core.Base#BASE
@@ -58,7 +58,7 @@ SCHEDULEDISPATCHER = {
-- @field #function Function The schedule function to be called. -- @field #function Function The schedule function to be called.
-- @field #table Arguments Schedule function arguments. -- @field #table Arguments Schedule function arguments.
-- @field #number Start Start time in seconds. -- @field #number Start Start time in seconds.
-- @field #number Repeat Repeat time intervall in seconds. -- @field #number Repeat Repeat time interval in seconds.
-- @field #number Randomize Randomization factor [0,1]. -- @field #number Randomize Randomization factor [0,1].
-- @field #number Stop Stop time in seconds. -- @field #number Stop Stop time in seconds.
-- @field #number StartTime Time in seconds when the scheduler is created. -- @field #number StartTime Time in seconds when the scheduler is created.
@@ -77,7 +77,7 @@ end
--- Add a Schedule to the ScheduleDispatcher. --- Add a Schedule to the ScheduleDispatcher.
-- The development of this method was really tidy. -- The development of this method was really tidy.
-- It is constructed as such that a garbage collection is executed on the weak tables, when the Scheduler is nillified. -- It is constructed as such that a garbage collection is executed on the weak tables, when the Scheduler is set to nil.
-- Nothing of this code should be modified without testing it thoroughly. -- Nothing of this code should be modified without testing it thoroughly.
-- @param #SCHEDULEDISPATCHER self -- @param #SCHEDULEDISPATCHER self
-- @param Core.Scheduler#SCHEDULER Scheduler Scheduler object. -- @param Core.Scheduler#SCHEDULER Scheduler Scheduler object.
@@ -85,7 +85,7 @@ end
-- @param #table ScheduleArguments Table of arguments passed to the ScheduleFunction. -- @param #table ScheduleArguments Table of arguments passed to the ScheduleFunction.
-- @param #number Start Start time in seconds. -- @param #number Start Start time in seconds.
-- @param #number Repeat Repeat interval in seconds. -- @param #number Repeat Repeat interval in seconds.
-- @param #number Randomize Radomization factor [0,1]. -- @param #number Randomize Randomization factor [0,1].
-- @param #number Stop Stop time in seconds. -- @param #number Stop Stop time in seconds.
-- @param #number TraceLevel Trace level [0,3]. -- @param #number TraceLevel Trace level [0,3].
-- @param Core.Fsm#FSM Fsm Finite state model. -- @param Core.Fsm#FSM Fsm Finite state model.
@@ -127,7 +127,6 @@ function SCHEDULEDISPATCHER:AddSchedule( Scheduler, ScheduleFunction, ScheduleAr
self.Schedule[Scheduler][CallID].Randomize = Randomize or 0 self.Schedule[Scheduler][CallID].Randomize = Randomize or 0
self.Schedule[Scheduler][CallID].Stop = Stop self.Schedule[Scheduler][CallID].Stop = Stop
-- This section handles the tracing of the scheduled calls. -- This section handles the tracing of the scheduled calls.
-- Because these calls will be executed with a delay, we inspect the place where these scheduled calls are initiated. -- Because these calls will be executed with a delay, we inspect the place where these scheduled calls are initiated.
-- The Info structure contains the output of the debug.getinfo() calls, which inspects the call stack for the function name, line number and source name. -- The Info structure contains the output of the debug.getinfo() calls, which inspects the call stack for the function name, line number and source name.
@@ -149,7 +148,7 @@ function SCHEDULEDISPATCHER:AddSchedule( Scheduler, ScheduleFunction, ScheduleAr
-- Therefore, in the call stack, at the TraceLevel these functions are mentioned as "tail calls", and the Info.name field will be nil as a result. -- Therefore, in the call stack, at the TraceLevel these functions are mentioned as "tail calls", and the Info.name field will be nil as a result.
-- To obtain the correct function name for FSM object calls, the function is mentioned in the call stack at a higher stack level. -- To obtain the correct function name for FSM object calls, the function is mentioned in the call stack at a higher stack level.
-- So when function name stored in Info.name is nil, then I inspect the function name within the call stack one level higher. -- So when function name stored in Info.name is nil, then I inspect the function name within the call stack one level higher.
-- So this little piece of code does its magic wonderfully, preformance overhead is neglectible, as scheduled calls don't happen that often. -- So this little piece of code does its magic wonderfully, performance overhead is negligible, as scheduled calls don't happen that often.
local Info = {} local Info = {}
@@ -181,7 +180,7 @@ function SCHEDULEDISPATCHER:AddSchedule( Scheduler, ScheduleFunction, ScheduleAr
return errmsg return errmsg
end end
-- Get object or persistant scheduler object. -- Get object or persistent scheduler object.
local Scheduler = self.ObjectSchedulers[CallID] -- Core.Scheduler#SCHEDULER local Scheduler = self.ObjectSchedulers[CallID] -- Core.Scheduler#SCHEDULER
if not Scheduler then if not Scheduler then
Scheduler = self.PersistentSchedulers[CallID] Scheduler = self.PersistentSchedulers[CallID]
@@ -198,7 +197,7 @@ function SCHEDULEDISPATCHER:AddSchedule( Scheduler, ScheduleFunction, ScheduleAr
-- self:T3( { Schedule = Schedule } ) -- self:T3( { Schedule = Schedule } )
local SchedulerObject = Scheduler.MasterObject --Scheduler.SchedulerObject Now is this the Maste or Scheduler object? local SchedulerObject = Scheduler.MasterObject -- Scheduler.SchedulerObject Now is this the Master or Scheduler object?
local ShowTrace = Scheduler.ShowTrace local ShowTrace = Scheduler.ShowTrace
local ScheduleFunction = Schedule.Function local ScheduleFunction = Schedule.Function
@@ -209,7 +208,6 @@ function SCHEDULEDISPATCHER:AddSchedule( Scheduler, ScheduleFunction, ScheduleAr
local Stop = Schedule.Stop or 0 local Stop = Schedule.Stop or 0
local ScheduleID = Schedule.ScheduleID local ScheduleID = Schedule.ScheduleID
local Prefix = (Repeat == 0) and "--->" or "+++>" local Prefix = (Repeat == 0) and "--->" or "+++>"
local Status, Result local Status, Result
@@ -238,7 +236,6 @@ function SCHEDULEDISPATCHER:AddSchedule( Scheduler, ScheduleFunction, ScheduleAr
-- Debug info. -- Debug info.
self:F3( { CallID = CallID, ScheduleID = ScheduleID, Master = MasterObject, CurrentTime = CurrentTime, StartTime = StartTime, Start = Start, Repeat = Repeat, Randomize = Randomize, Stop = Stop } ) self:F3( { CallID = CallID, ScheduleID = ScheduleID, Master = MasterObject, CurrentTime = CurrentTime, StartTime = StartTime, Start = Start, Repeat = Repeat, Randomize = Randomize, Stop = Stop } )
if Status and ((Result == nil) or (Result and Result ~= false)) then if Status and ((Result == nil) or (Result and Result ~= false)) then
if Repeat ~= 0 and ((Stop == 0) or (Stop ~= 0 and CurrentTime <= StartTime + Stop)) then if Repeat ~= 0 and ((Stop == 0) or (Stop ~= 0 and CurrentTime <= StartTime + Stop)) then
@@ -301,7 +298,7 @@ function SCHEDULEDISPATCHER:Start( Scheduler, CallID, Info )
-- Start DCS schedule function https://wiki.hoggitworld.com/view/DCS_func_scheduleFunction -- Start DCS schedule function https://wiki.hoggitworld.com/view/DCS_func_scheduleFunction
Schedule.ScheduleID = timer.scheduleFunction( Schedule.CallHandler, { CallID = CallID, Info = Info }, Tnow + Schedule.Start ) Schedule.ScheduleID = timer.scheduleFunction( Schedule.CallHandler, { CallID = CallID, Info = Info }, Tnow + Schedule.Start )
self:T(string.format("Starting scheduledispatcher Call ID=%s ==> Schedule ID=%s", tostring(CallID), tostring(Schedule.ScheduleID))) self:T( string.format( "Starting SCHEDULEDISPATCHER Call ID=%s ==> Schedule ID=%s", tostring( CallID ), tostring( Schedule.ScheduleID ) ) )
end end
else else
@@ -328,7 +325,7 @@ function SCHEDULEDISPATCHER:Stop( Scheduler, CallID )
-- Only stop when there is a ScheduleID defined for the CallID. So, when the scheduler was stopped before, do nothing. -- Only stop when there is a ScheduleID defined for the CallID. So, when the scheduler was stopped before, do nothing.
if Schedule.ScheduleID then if Schedule.ScheduleID then
self:T(string.format("scheduledispatcher stopping scheduler CallID=%s, ScheduleID=%s", tostring(CallID), tostring(Schedule.ScheduleID))) self:T( string.format( "SCHEDULEDISPATCHER stopping scheduler CallID=%s, ScheduleID=%s", tostring( CallID ), tostring( Schedule.ScheduleID ) ) )
-- Remove schedule function https://wiki.hoggitworld.com/view/DCS_func_removeFunction -- Remove schedule function https://wiki.hoggitworld.com/view/DCS_func_removeFunction
timer.removeFunction( Schedule.ScheduleID ) timer.removeFunction( Schedule.ScheduleID )
@@ -359,7 +356,7 @@ function SCHEDULEDISPATCHER:Clear( Scheduler )
end end
end end
--- Shopw tracing info. --- Show tracing info.
-- @param #SCHEDULEDISPATCHER self -- @param #SCHEDULEDISPATCHER self
-- @param Core.Scheduler#SCHEDULER Scheduler Scheduler object. -- @param Core.Scheduler#SCHEDULER Scheduler Scheduler object.
function SCHEDULEDISPATCHER:ShowTrace( Scheduler ) function SCHEDULEDISPATCHER:ShowTrace( Scheduler )

View File

@@ -48,7 +48,6 @@
-- @field #boolean ShowTrace Trace info if true. -- @field #boolean ShowTrace Trace info if true.
-- @extends Core.Base#BASE -- @extends Core.Base#BASE
--- Creates and handles schedules over time, which allow to execute code at specific time intervals with randomization. --- Creates and handles schedules over time, which allow to execute code at specific time intervals with randomization.
-- --
-- A SCHEDULER can manage **multiple** (repeating) schedules. Each planned or executing schedule has a unique **ScheduleID**. -- A SCHEDULER can manage **multiple** (repeating) schedules. Each planned or executing schedule has a unique **ScheduleID**.
@@ -79,7 +78,7 @@
-- --
-- ### Construct a SCHEDULER object without a volatile schedule, but volatile to the Object existence... -- ### Construct a SCHEDULER object without a volatile schedule, but volatile to the Object existence...
-- --
-- * @{#SCHEDULER.New}( Object ): Setup a new SCHEDULER object, which is linked to the Object. When the Object is nillified or destroyed, the SCHEDULER object will also be destroyed and stopped after garbage collection. -- * @{#SCHEDULER.New}( Object ): Setup a new SCHEDULER object, which is linked to the Object. When the Object is set to nil or destroyed, the SCHEDULER object will also be destroyed and stopped after garbage collection.
-- --
-- ZoneObject = ZONE:New( "ZoneName" ) -- ZoneObject = ZONE:New( "ZoneName" )
-- MasterObject = SCHEDULER:New( ZoneObject ) -- MasterObject = SCHEDULER:New( ZoneObject )
@@ -149,13 +148,13 @@
-- ZoneObject = ZONE:New( "ZoneName" ) -- ZoneObject = ZONE:New( "ZoneName" )
-- MasterObject = SCHEDULER:New( ZoneObject ) -- MasterObject = SCHEDULER:New( ZoneObject )
-- --
-- Several parameters can be specified that influence the behaviour of a Schedule. -- Several parameters can be specified that influence the behavior of a Schedule.
-- --
-- ### A single schedule, immediately executed -- ### A single schedule, immediately executed
-- --
-- SchedulerID = MasterObject:Schedule( ZoneObject, ScheduleFunction, {} ) -- SchedulerID = MasterObject:Schedule( ZoneObject, ScheduleFunction, {} )
-- --
-- The above example schedules a new ScheduleFunction call to be executed asynchronously, within milleseconds ... -- The above example schedules a new ScheduleFunction call to be executed asynchronously, within milliseconds ...
-- --
-- ### A single schedule, planned over time -- ### A single schedule, planned over time
-- --
@@ -235,7 +234,7 @@ end
-- @param #number Start Specifies the amount of seconds that will be waited before the scheduling is started, and the event function is called. -- @param #number Start Specifies the amount of seconds that will be waited before the scheduling is started, and the event function is called.
-- @param #number Repeat Specifies the time interval in seconds when the scheduler will call the event function. -- @param #number Repeat Specifies the time interval in seconds when the scheduler will call the event function.
-- @param #number RandomizeFactor Specifies a randomization factor between 0 and 1 to randomize the Repeat. -- @param #number RandomizeFactor Specifies a randomization factor between 0 and 1 to randomize the Repeat.
-- @param #number Stop Time interval in seconds after which the scheduler will be stoppe. -- @param #number Stop Time interval in seconds after which the scheduler will be stopped.
-- @param #number TraceLevel Trace level [0,3]. Default 3. -- @param #number TraceLevel Trace level [0,3]. Default 3.
-- @param Core.Fsm#FSM Fsm Finite state model. -- @param Core.Fsm#FSM Fsm Finite state model.
-- @return #table The ScheduleID of the planned schedule. -- @return #table The ScheduleID of the planned schedule.
@@ -254,8 +253,7 @@ function SCHEDULER:Schedule( MasterObject, SchedulerFunction, SchedulerArguments
self.MasterObject = MasterObject self.MasterObject = MasterObject
-- Add schedule. -- Add schedule.
local ScheduleID = _SCHEDULEDISPATCHER:AddSchedule( local ScheduleID = _SCHEDULEDISPATCHER:AddSchedule( self,
self,
SchedulerFunction, SchedulerFunction,
SchedulerArguments, SchedulerArguments,
Start, Start,

File diff suppressed because it is too large Load Diff

View File

@@ -29,15 +29,14 @@
-- @module Core.Settings -- @module Core.Settings
-- @image Core_Settings.JPG -- @image Core_Settings.JPG
--- @type SETTINGS --- @type SETTINGS
-- @extends Core.Base#BASE -- @extends Core.Base#BASE
--- Takes care of various settings that influence the behaviour of certain functionalities and classes within the MOOSE framework. --- Takes care of various settings that influence the behavior of certain functionalities and classes within the MOOSE framework.
-- --
-- === -- ===
-- --
-- The SETTINGS class takes care of various settings that influence the behaviour of certain functionalities and classes within the MOOSE framework. -- The SETTINGS class takes care of various settings that influence the behavior of certain functionalities and classes within the MOOSE framework.
-- SETTINGS can work on 2 levels: -- SETTINGS can work on 2 levels:
-- --
-- - **Default settings**: A running mission has **Default settings**. -- - **Default settings**: A running mission has **Default settings**.
@@ -59,7 +58,7 @@
-- --
-- A menu is created automatically per Command Center that allows to modify the **Default** settings. -- A menu is created automatically per Command Center that allows to modify the **Default** settings.
-- So, when joining a CC unit, a menu will be available that allows to change the settings parameters **FOR ALL THE PLAYERS**! -- So, when joining a CC unit, a menu will be available that allows to change the settings parameters **FOR ALL THE PLAYERS**!
-- Note that the **Default settings** will only be used when a player has not choosen its own settings. -- Note that the **Default settings** will only be used when a player has not chosen its own settings.
-- --
-- ## 2.2) Player settings menu -- ## 2.2) Player settings menu
-- --
@@ -69,7 +68,7 @@
-- --
-- ## 2.3) Show or Hide the Player Setting menus -- ## 2.3) Show or Hide the Player Setting menus
-- --
-- Of course, it may be requried not to show any setting menus. In this case, a method is available on the **\_SETTINGS object**. -- Of course, it may be required not to show any setting menus. In this case, a method is available on the **\_SETTINGS object**.
-- Use @{#SETTINGS.SetPlayerMenuOff}() to hide the player menus, and use @{#SETTINGS.SetPlayerMenuOn}() show the player menus. -- Use @{#SETTINGS.SetPlayerMenuOff}() to hide the player menus, and use @{#SETTINGS.SetPlayerMenuOn}() show the player menus.
-- Note that when this method is used, any player already in a slot will not have its menus visibility changed. -- Note that when this method is used, any player already in a slot will not have its menus visibility changed.
-- The option will only have effect when a player enters a new slot or changes a slot. -- The option will only have effect when a player enters a new slot or changes a slot.
@@ -94,8 +93,8 @@
-- --
-- - A2G BR: [Bearing Range](https://en.wikipedia.org/wiki/Bearing_(navigation)). -- - A2G BR: [Bearing Range](https://en.wikipedia.org/wiki/Bearing_(navigation)).
-- - A2G MGRS: The [Military Grid Reference System](https://en.wikipedia.org/wiki/Military_Grid_Reference_System). The accuracy can also be adapted. -- - A2G MGRS: The [Military Grid Reference System](https://en.wikipedia.org/wiki/Military_Grid_Reference_System). The accuracy can also be adapted.
-- - A2G LL DMS: Lattitude Longitude [Degrees Minutes Seconds](https://en.wikipedia.org/wiki/Geographic_coordinate_conversion). The accuracy can also be adapted. -- - A2G LL DMS: Latitude Longitude [Degrees Minutes Seconds](https://en.wikipedia.org/wiki/Geographic_coordinate_conversion). The accuracy can also be adapted.
-- - A2G LL DDM: Lattitude Longitude [Decimal Degrees Minutes](https://en.wikipedia.org/wiki/Decimal_degrees). The accuracy can also be adapted. -- - A2G LL DDM: Latitude Longitude [Decimal Degrees Minutes](https://en.wikipedia.org/wiki/Decimal_degrees). The accuracy can also be adapted.
-- --
-- ### 3.1.2) A2G coordinates setting **menu** -- ### 3.1.2) A2G coordinates setting **menu**
-- --
@@ -183,7 +182,7 @@
-- The settings can be changed by using the **Default settings menu** on the Command Center or the **Player settings menu** on the Player Slot. -- The settings can be changed by using the **Default settings menu** on the Command Center or the **Player settings menu** on the Player Slot.
-- --
-- Each Message Type has specific timings that will be applied when the message is displayed. -- Each Message Type has specific timings that will be applied when the message is displayed.
-- The Settings Menu will provide for each Message Type a selection of proposed durations from which can be choosen. -- The Settings Menu will provide for each Message Type a selection of proposed durations from which can be chosen.
-- So the player can choose its own amount of seconds how long a message should be displayed of a certain type. -- So the player can choose its own amount of seconds how long a message should be displayed of a certain type.
-- Note that **Update** messages can be chosen not to be displayed at all! -- Note that **Update** messages can be chosen not to be displayed at all!
-- --
@@ -196,7 +195,7 @@
-- --
-- ## 3.5) **Era** of the battle -- ## 3.5) **Era** of the battle
-- --
-- The threat level metric is scaled according the era of the battle. A target that is AAA, will pose a much greather threat in WWII than on modern warfare. -- The threat level metric is scaled according the era of the battle. A target that is AAA, will pose a much greater threat in WWII than on modern warfare.
-- Therefore, there are 4 era that are defined within the settings: -- Therefore, there are 4 era that are defined within the settings:
-- --
-- - **WWII** era: Use for warfare with equipment during the world war II time. -- - **WWII** era: Use for warfare with equipment during the world war II time.
@@ -231,7 +230,6 @@ SETTINGS.__Enum.Era = {
Modern = 4, Modern = 4,
} }
do -- SETTINGS do -- SETTINGS
--- SETTINGS constructor. --- SETTINGS constructor.
@@ -344,7 +342,6 @@ do -- SETTINGS
self.MessageTypeTimings[MessageType] = MessageTime self.MessageTypeTimings[MessageType] = MessageTime
end end
--- Gets the SETTINGS Message Display Timing of a MessageType --- Gets the SETTINGS Message Display Timing of a MessageType
-- @param #SETTINGS self -- @param #SETTINGS self
-- @param Core.Message#MESSAGE MessageType The type of the message. -- @param Core.Message#MESSAGE MessageType The type of the message.
@@ -689,7 +686,6 @@ do -- SETTINGS
MENU_GROUP_COMMAND:New( MenuGroup, "2 minutes", DetailedReportsMenu, self.MenuMessageTimingsSystem, self, MenuGroup, RootMenu, MESSAGE.Type.DetailedReportsMenu, 120 ):SetTime( MenuTime ) MENU_GROUP_COMMAND:New( MenuGroup, "2 minutes", DetailedReportsMenu, self.MenuMessageTimingsSystem, self, MenuGroup, RootMenu, MESSAGE.Type.DetailedReportsMenu, 120 ):SetTime( MenuTime )
MENU_GROUP_COMMAND:New( MenuGroup, "3 minutes", DetailedReportsMenu, self.MenuMessageTimingsSystem, self, MenuGroup, RootMenu, MESSAGE.Type.DetailedReportsMenu, 180 ):SetTime( MenuTime ) MENU_GROUP_COMMAND:New( MenuGroup, "3 minutes", DetailedReportsMenu, self.MenuMessageTimingsSystem, self, MenuGroup, RootMenu, MESSAGE.Type.DetailedReportsMenu, 180 ):SetTime( MenuTime )
SettingsMenu:Remove( MenuTime ) SettingsMenu:Remove( MenuTime )
return self return self
@@ -802,7 +798,6 @@ do -- SETTINGS
end end
local A2ACoordinateMenu = MENU_GROUP:New( PlayerGroup, text, PlayerMenu ) local A2ACoordinateMenu = MENU_GROUP:New( PlayerGroup, text, PlayerMenu )
if not self:IsA2A_LL_DMS() or _SETTINGS.MenuStatic then if not self:IsA2A_LL_DMS() or _SETTINGS.MenuStatic then
local text = "Lat/Lon Degree Min Sec (LL DMS)" local text = "Lat/Lon Degree Min Sec (LL DMS)"
if _SETTINGS.MenuShort then if _SETTINGS.MenuShort then
@@ -935,7 +930,6 @@ do -- SETTINGS
return self return self
end end
--- @param #SETTINGS self --- @param #SETTINGS self
function SETTINGS:A2GMenuSystem( MenuGroup, RootMenu, A2GSystem ) function SETTINGS:A2GMenuSystem( MenuGroup, RootMenu, A2GSystem )
self.A2GSystem = A2GSystem self.A2GSystem = A2GSystem
@@ -1055,7 +1049,6 @@ do -- SETTINGS
end end
--- Configures the era of the mission to be Cold war. --- Configures the era of the mission to be Cold war.
-- @param #SETTINGS self -- @param #SETTINGS self
-- @return #SETTINGS self -- @return #SETTINGS self
@@ -1065,7 +1058,6 @@ do -- SETTINGS
end end
--- Configures the era of the mission to be Modern war. --- Configures the era of the mission to be Modern war.
-- @param #SETTINGS self -- @param #SETTINGS self
-- @return #SETTINGS self -- @return #SETTINGS self
@@ -1075,7 +1067,4 @@ do -- SETTINGS
end end
end end

View File

@@ -10,7 +10,7 @@
-- * Randomize the spawning location between different zones. -- * Randomize the spawning location between different zones.
-- * Randomize the initial positions within the zones. -- * Randomize the initial positions within the zones.
-- * Spawn in array formation. -- * Spawn in array formation.
-- * Spawn uncontrolled (for planes or helos only). -- * Spawn uncontrolled (for planes or helicopters only).
-- * Clean up inactive helicopters that "crashed". -- * Clean up inactive helicopters that "crashed".
-- * Place a hook to capture a spawn event, and tailor with customer code. -- * Place a hook to capture a spawn event, and tailor with customer code.
-- * Spawn late activated. -- * Spawn late activated.
@@ -46,7 +46,6 @@
-- @module Core.Spawn -- @module Core.Spawn
-- @image Core_Spawn.JPG -- @image Core_Spawn.JPG
--- SPAWN Class --- SPAWN Class
-- @type SPAWN -- @type SPAWN
-- @field ClassName -- @field ClassName
@@ -59,7 +58,6 @@
-- @field #SPAWN.SpawnZoneTable SpawnZoneTable -- @field #SPAWN.SpawnZoneTable SpawnZoneTable
-- @extends Core.Base#BASE -- @extends Core.Base#BASE
--- Allows to spawn dynamically new @{Core.Group}s. --- Allows to spawn dynamically new @{Core.Group}s.
-- --
-- Each SPAWN object needs to be have related **template groups** setup in the Mission Editor (ME), -- Each SPAWN object needs to be have related **template groups** setup in the Mission Editor (ME),
@@ -72,7 +70,7 @@
-- **the name of the template group** to be given as a string to those constructor methods. -- **the name of the template group** to be given as a string to those constructor methods.
-- --
-- Initialization settings can be applied on the SPAWN object, -- Initialization settings can be applied on the SPAWN object,
-- which modify the behaviour or the way groups are spawned. -- which modify the behavior or the way groups are spawned.
-- These initialization methods have the prefix **Init**. -- These initialization methods have the prefix **Init**.
-- There are also spawn methods with the prefix **Spawn** and will spawn new groups in various ways. -- There are also spawn methods with the prefix **Spawn** and will spawn new groups in various ways.
-- --
@@ -163,7 +161,7 @@
-- --
-- ### Array formation -- ### Array formation
-- --
-- * @{#SPAWN.InitArray}(): Make groups visible before they are actually activated, and order these groups like a batallion in an array. -- * @{#SPAWN.InitArray}(): Make groups visible before they are actually activated, and order these groups like a battalion in an array.
-- --
-- ### Position randomization -- ### Position randomization
-- --
@@ -183,16 +181,15 @@
-- --
-- ### Delay initial scheduled spawn -- ### Delay initial scheduled spawn
-- --
-- * @{#SPAWN.InitDelayOnOff}(): Turns the inital delay On/Off when scheduled spawning the first @{Wrapper.Group} object. -- * @{#SPAWN.InitDelayOnOff}(): Turns the initial delay On/Off when scheduled spawning the first @{Wrapper.Group} object.
-- * @{#SPAWN.InitDelayOn}(): Turns the inital delay On when scheduled spawning the first @{Wrapper.Group} object. -- * @{#SPAWN.InitDelayOn}(): Turns the initial delay On when scheduled spawning the first @{Wrapper.Group} object.
-- * @{#SPAWN.InitDelayOff}(): Turns the inital delay Off when scheduled spawning the first @{Wrapper.Group} object. -- * @{#SPAWN.InitDelayOff}(): Turns the initial delay Off when scheduled spawning the first @{Wrapper.Group} object.
-- --
-- ### Repeat spawned @{Wrapper.Group}s upon landing -- ### Repeat spawned @{Wrapper.Group}s upon landing
-- --
-- * @{#SPAWN.InitRepeat}() or @{#SPAWN.InitRepeatOnLanding}(): This method is used to re-spawn automatically the same group after it has landed. -- * @{#SPAWN.InitRepeat}() or @{#SPAWN.InitRepeatOnLanding}(): This method is used to re-spawn automatically the same group after it has landed.
-- * @{#SPAWN.InitRepeatOnEngineShutDown}(): This method is used to re-spawn automatically the same group after it has landed and it shuts down the engines at the ramp. -- * @{#SPAWN.InitRepeatOnEngineShutDown}(): This method is used to re-spawn automatically the same group after it has landed and it shuts down the engines at the ramp.
-- --
--
-- ## SPAWN **Spawn** methods -- ## SPAWN **Spawn** methods
-- --
-- Groups can be spawned at different times and methods: -- Groups can be spawned at different times and methods:
@@ -217,7 +214,6 @@
--- * @{#SPAWN.SpawnScheduleStart}(): Start or continue to spawn groups at scheduled time intervals. --- * @{#SPAWN.SpawnScheduleStart}(): Start or continue to spawn groups at scheduled time intervals.
-- * @{#SPAWN.SpawnScheduleStop}(): Stop the spawning of groups at scheduled time intervals. -- * @{#SPAWN.SpawnScheduleStop}(): Stop the spawning of groups at scheduled time intervals.
-- --
--
-- ## Retrieve alive GROUPs spawned by the SPAWN object -- ## Retrieve alive GROUPs spawned by the SPAWN object
-- --
-- The SPAWN class administers which GROUPS it has reserved (in stock) or has created during mission execution. -- The SPAWN class administers which GROUPS it has reserved (in stock) or has created during mission execution.
@@ -233,14 +229,14 @@
-- --
-- ## Spawned cleaning of inactive groups -- ## Spawned cleaning of inactive groups
-- --
-- Sometimes, it will occur during a mission run-time, that ground or especially air objects get damaged, and will while being damged stop their activities, while remaining alive. -- Sometimes, it will occur during a mission run-time, that ground or especially air objects get damaged, and will while being damaged stop their activities, while remaining alive.
-- In such cases, the SPAWN object will just sit there and wait until that group gets destroyed, but most of the time it won't, -- In such cases, the SPAWN object will just sit there and wait until that group gets destroyed, but most of the time it won't,
-- and it may occur that no new groups are or can be spawned as limits are reached. -- and it may occur that no new groups are or can be spawned as limits are reached.
-- To prevent this, a @{#SPAWN.InitCleanUp}() initialization method has been defined that will silently monitor the status of each spawned group. -- To prevent this, a @{#SPAWN.InitCleanUp}() initialization method has been defined that will silently monitor the status of each spawned group.
-- Once a group has a velocity = 0, and has been waiting for a defined interval, that group will be cleaned or removed from run-time. -- Once a group has a velocity = 0, and has been waiting for a defined interval, that group will be cleaned or removed from run-time.
-- There is a catch however :-) If a damaged group has returned to an airbase within the coalition, that group will not be considered as "lost"... -- There is a catch however :-) If a damaged group has returned to an airbase within the coalition, that group will not be considered as "lost"...
-- In such a case, when the inactive group is cleaned, a new group will Re-spawned automatically. -- In such a case, when the inactive group is cleaned, a new group will Re-spawned automatically.
-- This models AI that has succesfully returned to their airbase, to restart their combat activities. -- This models AI that has successfully returned to their airbase, to restart their combat activities.
-- Check the @{#SPAWN.InitCleanUp}() for further info. -- Check the @{#SPAWN.InitCleanUp}() for further info.
-- --
-- ## Catch the @{Wrapper.Group} Spawn Event in a callback function! -- ## Catch the @{Wrapper.Group} Spawn Event in a callback function!
@@ -255,22 +251,19 @@
-- --
-- ## Delay the initial spawning -- ## Delay the initial spawning
-- --
-- When using the @{#SPAWN.SpawnScheduled)() method, the default behaviour of this method will be that it will spawn the initial (first) @{Wrapper.Group} -- When using the @{#SPAWN.SpawnScheduled)() method, the default behavior of this method will be that it will spawn the initial (first) @{Wrapper.Group}
-- immediately when :SpawnScheduled() is initiated. The methods @{#SPAWN.InitDelayOnOff}() and @{#SPAWN.InitDelayOn}() can be used to -- immediately when :SpawnScheduled() is initiated. The methods @{#SPAWN.InitDelayOnOff}() and @{#SPAWN.InitDelayOn}() can be used to
-- activate a delay before the first @{Wrapper.Group} is spawned. For completeness, a method @{#SPAWN.InitDelayOff}() is also available, that -- activate a delay before the first @{Wrapper.Group} is spawned. For completeness, a method @{#SPAWN.InitDelayOff}() is also available, that
-- can be used to switch off the initial delay. Because there is no delay by default, this method would only be used when a -- can be used to switch off the initial delay. Because there is no delay by default, this method would only be used when a
-- @{#SPAWN.SpawnScheduleStop}() ; @{#SPAWN.SpawnScheduleStart}() sequence would have been used. -- @{#SPAWN.SpawnScheduleStop}() ; @{#SPAWN.SpawnScheduleStart}() sequence would have been used.
-- --
--
-- @field #SPAWN SPAWN -- @field #SPAWN SPAWN
--
SPAWN = { SPAWN = {
ClassName = "SPAWN", ClassName = "SPAWN",
SpawnTemplatePrefix = nil, SpawnTemplatePrefix = nil,
SpawnAliasPrefix = nil, SpawnAliasPrefix = nil,
} }
--- Enumerator for spawns at airbases --- Enumerator for spawns at airbases
-- @type SPAWN.Takeoff -- @type SPAWN.Takeoff
-- @extends Wrapper.Group#GROUP.Takeoff -- @extends Wrapper.Group#GROUP.Takeoff
@@ -286,7 +279,6 @@ SPAWN.Takeoff = {
--- @type SPAWN.SpawnZoneTable --- @type SPAWN.SpawnZoneTable
-- @list <Core.Zone#ZONE_BASE> SpawnZone -- @list <Core.Zone#ZONE_BASE> SpawnZone
--- Creates the main object to spawn a @{Wrapper.Group} defined in the DCS ME. --- Creates the main object to spawn a @{Wrapper.Group} defined in the DCS ME.
-- @param #SPAWN self -- @param #SPAWN self
-- @param #string SpawnTemplatePrefix is the name of the Group in the ME that defines the Template. Each new group will have the name starting with SpawnTemplatePrefix. -- @param #string SpawnTemplatePrefix is the name of the Group in the ME that defines the Template. Each new group will have the name starting with SpawnTemplatePrefix.
@@ -371,13 +363,13 @@ function SPAWN:NewWithAlias( SpawnTemplatePrefix, SpawnAliasPrefix )
self.AIOnOff = true -- The AI is on by default when spawning a group. self.AIOnOff = true -- The AI is on by default when spawning a group.
self.SpawnUnControlled = false self.SpawnUnControlled = false
self.SpawnInitKeepUnitNames = false -- Overwrite unit names by default with group name. self.SpawnInitKeepUnitNames = false -- Overwrite unit names by default with group name.
self.DelayOnOff = false -- No intial delay when spawning the first group. self.DelayOnOff = false -- No initial delay when spawning the first group.
self.SpawnGrouping = nil -- No grouping. self.SpawnGrouping = nil -- No grouping.
self.SpawnInitLivery = nil -- No special livery. self.SpawnInitLivery = nil -- No special livery.
self.SpawnInitSkill = nil -- No special skill. self.SpawnInitSkill = nil -- No special skill.
self.SpawnInitFreq = nil -- No special frequency. self.SpawnInitFreq = nil -- No special frequency.
self.SpawnInitModu = nil -- No special modulation. self.SpawnInitModu = nil -- No special modulation.
self.SpawnInitRadio = nil -- No radio comms setting. self.SpawnInitRadio = nil -- No radio communication setting.
self.SpawnInitModex = nil self.SpawnInitModex = nil
self.SpawnInitAirbase = nil self.SpawnInitAirbase = nil
self.TweakedTemplate = false -- Check if the user is using self made template. self.TweakedTemplate = false -- Check if the user is using self made template.
@@ -393,7 +385,6 @@ function SPAWN:NewWithAlias( SpawnTemplatePrefix, SpawnAliasPrefix )
return self return self
end 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.
-- @param #SPAWN self -- @param #SPAWN self
-- @param #table SpawnTemplate is the Template of the Group. This must be a valid Group Template structure! -- @param #table SpawnTemplate is the Template of the Group. This must be a valid Group Template structure!
@@ -404,8 +395,10 @@ end
-- -- Create a new SPAWN object based on a Group Template defined from scratch. -- -- 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' ) -- Spawn_BE_KA50 = SPAWN:NewWithAlias( 'BE KA-50@RAMP-Ground Defense', 'Helicopter Attacking a City' )
-- @usage -- @usage
--
-- -- Create a new CSAR_Spawn object based on a normal Group Template to spawn a soldier. -- -- Create a new CSAR_Spawn object based on a normal Group Template to spawn a soldier.
-- local CSAR_Spawn = SPAWN:NewWithFromTemplate( Template, "CSAR", "Pilot" ) -- local CSAR_Spawn = SPAWN:NewWithFromTemplate( Template, "CSAR", "Pilot" )
--
function SPAWN:NewFromTemplate( SpawnTemplate, SpawnTemplatePrefix, SpawnAliasPrefix ) function SPAWN:NewFromTemplate( SpawnTemplate, SpawnTemplatePrefix, SpawnAliasPrefix )
local self = BASE:Inherit( self, BASE:New() ) local self = BASE:Inherit( self, BASE:New() )
self:F( { SpawnTemplate, SpawnTemplatePrefix, SpawnAliasPrefix } ) self:F( { SpawnTemplate, SpawnTemplatePrefix, SpawnAliasPrefix } )
@@ -432,13 +425,13 @@ function SPAWN:NewFromTemplate( SpawnTemplate, SpawnTemplatePrefix, SpawnAliasPr
self.AIOnOff = true -- The AI is on by default when spawning a group. self.AIOnOff = true -- The AI is on by default when spawning a group.
self.SpawnUnControlled = false self.SpawnUnControlled = false
self.SpawnInitKeepUnitNames = false -- Overwrite unit names by default with group name. self.SpawnInitKeepUnitNames = false -- Overwrite unit names by default with group name.
self.DelayOnOff = false -- No intial delay when spawning the first group. self.DelayOnOff = false -- No initial delay when spawning the first group.
self.Grouping = nil -- No grouping. self.Grouping = nil -- No grouping.
self.SpawnInitLivery = nil -- No special livery. self.SpawnInitLivery = nil -- No special livery.
self.SpawnInitSkill = nil -- No special skill. self.SpawnInitSkill = nil -- No special skill.
self.SpawnInitFreq = nil -- No special frequency. self.SpawnInitFreq = nil -- No special frequency.
self.SpawnInitModu = nil -- No special modulation. self.SpawnInitModu = nil -- No special modulation.
self.SpawnInitRadio = nil -- No radio comms setting. self.SpawnInitRadio = nil -- No radio communication setting.
self.SpawnInitModex = nil self.SpawnInitModex = nil
self.SpawnInitAirbase = nil self.SpawnInitAirbase = nil
self.TweakedTemplate = true -- Check if the user is using self made template. self.TweakedTemplate = true -- Check if the user is using self made template.
@@ -454,7 +447,6 @@ function SPAWN:NewFromTemplate( SpawnTemplate, SpawnTemplatePrefix, SpawnAliasPr
return self return self
end end
--- Stops any more repeat spawns from happening once the UNIT count of Alive units, spawned by the same SPAWN object, exceeds the first parameter. Also can stop spawns from happening once a total GROUP still alive is met. --- Stops any more repeat spawns from happening once the UNIT count of Alive units, spawned by the same SPAWN object, exceeds the first parameter. Also can stop spawns from happening once a total GROUP still alive is met.
-- Exceptionally powerful when combined with SpawnSchedule for Respawning. -- Exceptionally powerful when combined with SpawnSchedule for Respawning.
-- Note that this method is exceptionally important to balance the performance of the mission. Depending on the machine etc, a mission can only process a maximum amount of units. -- Note that this method is exceptionally important to balance the performance of the mission. Depending on the machine etc, a mission can only process a maximum amount of units.
@@ -467,10 +459,12 @@ end
-- This parameter accepts the value 0, which defines that there are no maximum group limits, but there are limits on the maximum of units that can be alive at the same time. -- This parameter accepts the value 0, which defines that there are no maximum group limits, but there are limits on the maximum of units that can be alive at the same time.
-- @return #SPAWN self -- @return #SPAWN self
-- @usage -- @usage
--
-- -- NATO helicopters engaging in the battle field. -- -- NATO helicopters engaging in the battle field.
-- -- This helicopter group consists of one Unit. So, this group will SPAWN maximum 2 groups simultaneously within the DCSRTE. -- -- This helicopter group consists of one Unit. So, this group will SPAWN maximum 2 groups simultaneously within the DCSRTE.
-- -- There will be maximum 24 groups spawned during the whole mission lifetime. -- -- There will be maximum 24 groups spawned during the whole mission lifetime.
-- Spawn_BE_KA50 = SPAWN:New( 'BE KA-50@RAMP-Ground Defense' ):InitLimit( 2, 24 ) -- Spawn_BE_KA50 = SPAWN:New( 'BE KA-50@RAMP-Ground Defense' ):InitLimit( 2, 24 )
--
function SPAWN:InitLimit( SpawnMaxUnitsAlive, SpawnMaxGroups ) function SPAWN:InitLimit( SpawnMaxUnitsAlive, SpawnMaxGroups )
self:F( { self.SpawnTemplatePrefix, SpawnMaxUnitsAlive, SpawnMaxGroups } ) self:F( { self.SpawnTemplatePrefix, SpawnMaxUnitsAlive, SpawnMaxGroups } )
@@ -500,7 +494,6 @@ function SPAWN:InitKeepUnitNames( KeepUnitNames )
return self return self
end end
--- Flags that the spawned groups must be spawned late activated. --- Flags that the spawned groups must be spawned late activated.
-- @param #SPAWN self -- @param #SPAWN self
-- @param #boolean LateActivated (optional) If true, the spawned groups are late activated. -- @param #boolean LateActivated (optional) If true, the spawned groups are late activated.
@@ -517,7 +510,7 @@ end
-- @param #SPAWN self -- @param #SPAWN self
-- @param #string AirbaseName Name of the airbase. -- @param #string AirbaseName Name of the airbase.
-- @param #number Takeoff (Optional) Takeoff type. Can be SPAWN.Takeoff.Hot (default), SPAWN.Takeoff.Cold or SPAWN.Takeoff.Runway. -- @param #number Takeoff (Optional) Takeoff type. Can be SPAWN.Takeoff.Hot (default), SPAWN.Takeoff.Cold or SPAWN.Takeoff.Runway.
-- @param #number TerminalTyple (Optional) The terminal type. -- @param #number TerminalType (Optional) The terminal type.
-- @return #SPAWN self -- @return #SPAWN self
function SPAWN:InitAirbase( AirbaseName, Takeoff, TerminalType ) function SPAWN:InitAirbase( AirbaseName, Takeoff, TerminalType )
self:F() self:F()
@@ -531,7 +524,6 @@ function SPAWN:InitAirbase( AirbaseName, Takeoff, TerminalType )
return self return self
end end
--- Defines the Heading for the new spawned units. --- Defines the Heading for the new spawned units.
-- The heading can be given as one fixed degree, or can be randomized between minimum and maximum degrees. -- The heading can be given as one fixed degree, or can be randomized between minimum and maximum degrees.
-- @param #SPAWN self -- @param #SPAWN self
@@ -557,7 +549,6 @@ function SPAWN:InitHeading( HeadingMin, HeadingMax )
return self return self
end end
--- Defines the heading of the overall formation of the new spawned group. --- Defines the heading of the overall formation of the new spawned group.
-- The heading can be given as one fixed degree, or can be randomized between minimum and maximum degrees. -- The heading can be given as one fixed degree, or can be randomized between minimum and maximum degrees.
-- The Group's formation as laid out in its template will be rotated around the first unit in the group -- The Group's formation as laid out in its template will be rotated around the first unit in the group
@@ -575,12 +566,12 @@ end
-- -- Spawn the Group with the formation rotated +100 degrees around unit #1, compared to the mission template. -- -- Spawn the Group with the formation rotated +100 degrees around unit #1, compared to the mission template.
-- mySpawner:InitGroupHeading( 100 ) -- mySpawner:InitGroupHeading( 100 )
-- --
-- Spawn the Group with the formation rotated units between +100 and +150 degrees around unit #1, compared to the mission template, and with individual units varying by +/- 10 degrees from their templated facing. -- -- Spawn the Group with the formation rotated units between +100 and +150 degrees around unit #1, compared to the mission template, and with individual units varying by +/- 10 degrees from their templated facing.
-- mySpawner:InitGroupHeading( 100, 150, 10 ) -- mySpawner:InitGroupHeading( 100, 150, 10 )
-- --
-- Spawn the Group with the formation rotated -60 degrees around unit #1, compared to the mission template, but with all units facing due north regardless of how they were laid out in the template. -- -- Spawn the Group with the formation rotated -60 degrees around unit #1, compared to the mission template, but with all units facing due north regardless of how they were laid out in the template.
-- mySpawner:InitGroupHeading(-60):InitHeading(0) -- mySpawner:InitGroupHeading(-60):InitHeading(0)
-- or -- -- or
-- mySpawner:InitHeading(0):InitGroupHeading(-60) -- mySpawner:InitHeading(0):InitGroupHeading(-60)
-- --
function SPAWN:InitGroupHeading( HeadingMin, HeadingMax, unitVar ) function SPAWN:InitGroupHeading( HeadingMin, HeadingMax, unitVar )
@@ -592,13 +583,12 @@ function SPAWN:InitGroupHeading( HeadingMin, HeadingMax, unitVar )
return self return self
end end
--- Sets the coalition of the spawned group. Note that it might be necessary to also set the country explicitly! --- Sets the coalition of the spawned group. Note that it might be necessary to also set the country explicitly!
-- @param #SPAWN self -- @param #SPAWN self
-- @param DCS#coalition.side Coalition Coalition of the group as number of enumerator: -- @param DCS#coalition.side Coalition Coalition of the group as number of enumerator:
-- --
-- * @{DCS#coaliton.side.NEUTRAL} -- * @{DCS#coalition.side.NEUTRAL}
-- * @{DCS#coaliton.side.RED} -- * @{DCS#coalition.side.RED}
-- * @{DCS#coalition.side.BLUE} -- * @{DCS#coalition.side.BLUE}
-- --
-- @return #SPAWN self -- @return #SPAWN self
@@ -610,7 +600,7 @@ function SPAWN:InitCoalition( Coalition )
return self return self
end end
--- Sets the country of the spawn group. Note that the country determins the coalition of the group depending on which country is defined to be on which side for each specific mission! --- Sets the country of the spawn group. Note that the country determines the coalition of the group depending on which country is defined to be on which side for each specific mission!
-- @param #SPAWN self -- @param #SPAWN self
-- @param #number Country Country id as number or enumerator: -- @param #number Country Country id as number or enumerator:
-- --
@@ -626,7 +616,6 @@ function SPAWN:InitCountry( Country )
return self return self
end end
--- Sets category ID of the group. --- Sets category ID of the group.
-- @param #SPAWN self -- @param #SPAWN self
-- @param #number Category Category id. -- @param #number Category Category id.
@@ -641,7 +630,7 @@ end
--- Sets livery of the group. --- Sets livery of the group.
-- @param #SPAWN self -- @param #SPAWN self
-- @param #string Livery Livery name. Note that this is not necessarily the same name as displayed in the mission edior. -- @param #string Livery Livery name. Note that this is not necessarily the same name as displayed in the mission editor.
-- @return #SPAWN self -- @return #SPAWN self
function SPAWN:InitLivery( Livery ) function SPAWN:InitLivery( Livery )
self:F( { livery = Livery } ) self:F( { livery = Livery } )
@@ -672,9 +661,9 @@ function SPAWN:InitSkill( Skill )
return self return self
end end
--- Sets the radio comms on or off. Same as checking/unchecking the COMM box in the mission editor. --- Sets the radio communication on or off. Same as checking/unchecking the COMM box in the mission editor.
-- @param #SPAWN self -- @param #SPAWN self
-- @param #number switch If true (or nil), enables the radio comms. If false, disables the radio for the spawned group. -- @param #number switch If true (or nil), enables the radio communication. If false, disables the radio for the spawned group.
-- @return #SPAWN self -- @return #SPAWN self
function SPAWN:InitRadioCommsOnOff( switch ) function SPAWN:InitRadioCommsOnOff( switch )
self:F( { switch = switch } ) self:F( { switch = switch } )
@@ -721,8 +710,7 @@ function SPAWN:InitModex(modex)
return self return self
end end
--- Randomizes the defined route of the SpawnTemplatePrefix group in the ME. This is very useful to define extra variation of the behavior of groups.
--- Randomizes the defined route of the SpawnTemplatePrefix group in the ME. This is very useful to define extra variation of the behaviour of groups.
-- @param #SPAWN self -- @param #SPAWN self
-- @param #number SpawnStartPoint is the waypoint where the randomization begins. -- @param #number SpawnStartPoint is the waypoint where the randomization begins.
-- Note that the StartPoint = 0 equaling the point where the group is spawned. -- Note that the StartPoint = 0 equaling the point where the group is spawned.
@@ -732,11 +720,13 @@ end
-- @param #number SpawnHeight (optional) Specifies the **additional** height in meters that can be added to the base height specified at each waypoint in the ME. -- @param #number SpawnHeight (optional) Specifies the **additional** height in meters that can be added to the base height specified at each waypoint in the ME.
-- @return #SPAWN -- @return #SPAWN
-- @usage -- @usage
--
-- -- NATO helicopters engaging in the battle field. -- -- 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). -- -- 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. -- -- 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. -- -- 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 ) -- Spawn_BE_KA50 = SPAWN:New( 'BE KA-50@RAMP-Ground Defense' ):InitRandomizeRoute( 2, 2, 2000 )
--
function SPAWN:InitRandomizeRoute( SpawnStartPoint, SpawnEndPoint, SpawnRadius, SpawnHeight ) function SPAWN:InitRandomizeRoute( SpawnStartPoint, SpawnEndPoint, SpawnRadius, SpawnHeight )
self:F( { self.SpawnTemplatePrefix, SpawnStartPoint, SpawnEndPoint, SpawnRadius, SpawnHeight } ) self:F( { self.SpawnTemplatePrefix, SpawnStartPoint, SpawnEndPoint, SpawnRadius, SpawnHeight } )
@@ -773,7 +763,6 @@ function SPAWN:InitRandomizePosition( RandomizePosition, OuterRadius, InnerRadiu
return self return self
end end
--- Randomizes the UNITs that are spawned within a radius band given an Outer and Inner radius. --- Randomizes the UNITs that are spawned within a radius band given an Outer and Inner radius.
-- @param #SPAWN self -- @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 @{UNIT}s position within the group between a given outer and inner radius.
@@ -781,11 +770,13 @@ end
-- @param DCS#Distance InnerRadius (optional) The inner radius in meters where the new group will NOT be spawned. -- @param DCS#Distance InnerRadius (optional) The inner radius in meters where the new group will NOT be spawned.
-- @return #SPAWN -- @return #SPAWN
-- @usage -- @usage
--
-- -- NATO helicopters engaging in the battle field. -- -- 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). -- -- 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. -- -- 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. -- -- 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 ) -- Spawn_BE_KA50 = SPAWN:New( 'BE KA-50@RAMP-Ground Defense' ):InitRandomizeRoute( 2, 2, 2000 )
--
function SPAWN:InitRandomizeUnits( RandomizeUnits, OuterRadius, InnerRadius ) function SPAWN:InitRandomizeUnits( RandomizeUnits, OuterRadius, InnerRadius )
self:F( { self.SpawnTemplatePrefix, RandomizeUnits, OuterRadius, InnerRadius } ) self:F( { self.SpawnTemplatePrefix, RandomizeUnits, OuterRadius, InnerRadius } )
@@ -805,14 +796,15 @@ end
-- but they will all follow the same Template route and have the same prefix name. -- but they will all follow the same Template route and have the same prefix name.
-- In other words, this method randomizes between a defined set of groups the template to be used for each new spawn of a group. -- In other words, this method randomizes between a defined set of groups the template to be used for each new spawn of a group.
-- @param #SPAWN self -- @param #SPAWN self
-- @param #string SpawnTemplatePrefixTable A table with the names of the groups defined within the mission editor, from which one will be choosen when a new group will be spawned. -- @param #string SpawnTemplatePrefixTable A table with the names of the groups defined within the mission editor, from which one will be chosen when a new group will be spawned.
-- @return #SPAWN -- @return #SPAWN
-- @usage -- @usage
--
-- -- NATO Tank Platoons invading Gori. -- -- NATO Tank Platoons invading Gori.
-- -- Choose between 13 different 'US Tank Platoon' configurations for each new SPAWN the Group to be spawned for the -- -- Choose between 13 different 'US Tank Platoon' configurations for each new SPAWN the Group to be spawned for the
-- -- 'US Tank Platoon Left', 'US Tank Platoon Middle' and 'US Tank Platoon Right' SpawnTemplatePrefixes. -- -- 'US Tank Platoon Left', 'US Tank Platoon Middle' and 'US Tank Platoon Right' SpawnTemplatePrefixes.
-- -- Each new SPAWN will randomize the route, with a defined time interval of 200 seconds with 40% time variation (randomization) and -- -- Each new SPAWN will randomize the route, with a defined time interval of 200 seconds with 40% time variation (randomization) and
-- -- with a limit set of maximum 12 Units alive simulteneously and 150 Groups to be spawned during the whole mission. -- -- with a limit set of maximum 12 Units alive simultaneously and 150 Groups to be spawned during the whole mission.
-- Spawn_US_Platoon = { 'US Tank Platoon 1', 'US Tank Platoon 2', 'US Tank Platoon 3', 'US Tank Platoon 4', 'US Tank Platoon 5', -- Spawn_US_Platoon = { 'US Tank Platoon 1', 'US Tank Platoon 2', 'US Tank Platoon 3', 'US Tank Platoon 4', 'US Tank Platoon 5',
-- 'US Tank Platoon 6', 'US Tank Platoon 7', 'US Tank Platoon 8', 'US Tank Platoon 9', 'US Tank Platoon 10', -- 'US Tank Platoon 6', 'US Tank Platoon 7', 'US Tank Platoon 8', 'US Tank Platoon 9', 'US Tank Platoon 10',
-- 'US Tank Platoon 11', 'US Tank Platoon 12', 'US Tank Platoon 13' } -- 'US Tank Platoon 11', 'US Tank Platoon 12', 'US Tank Platoon 13' }
@@ -832,7 +824,6 @@ function SPAWN:InitRandomizeTemplate( SpawnTemplatePrefixTable )
return self return self
end end
--- Randomize templates to be used as the unit representatives for the Spawned group, defined using a SET_GROUP object. --- Randomize templates to be used as the unit representatives for the Spawned group, defined using a SET_GROUP object.
-- This method becomes useful when you need to spawn groups with random templates of groups defined within the mission editor, -- 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. -- but they will all follow the same Template route and have the same prefix name.
@@ -841,20 +832,22 @@ end
-- @param Core.Set#SET_GROUP SpawnTemplateSet A SET_GROUP object set, that contains the groups that are possible unit representatives of the group to be spawned. -- @param Core.Set#SET_GROUP SpawnTemplateSet A SET_GROUP object set, that contains the groups that are possible unit representatives of the group to be spawned.
-- @return #SPAWN -- @return #SPAWN
-- @usage -- @usage
--
-- -- NATO Tank Platoons invading Gori. -- -- NATO Tank Platoons invading Gori.
-- --
-- -- Choose between different 'US Tank Platoon Template' configurations to be spawned for the -- -- Choose between different 'US Tank Platoon Template' configurations to be spawned for the
-- -- 'US Tank Platoon Left', 'US Tank Platoon Middle' and 'US Tank Platoon Right' SPAWN objects. -- -- 'US Tank Platoon Left', 'US Tank Platoon Middle' and 'US Tank Platoon Right' SPAWN objects.
-- --
-- -- Each new SPAWN will randomize the route, with a defined time interval of 200 seconds with 40% time variation (randomization) and -- -- Each new SPAWN will randomize the route, with a defined time interval of 200 seconds with 40% time variation (randomization) and
-- -- with a limit set of maximum 12 Units alive simulteneously and 150 Groups to be spawned during the whole mission. -- -- with a limit set of maximum 12 Units alive simultaneously and 150 Groups to be spawned during the whole mission.
-- --
-- Spawn_US_PlatoonSet = SET_GROUP:New():FilterPrefixes( "US Tank Platoon Templates" ):FilterOnce() -- Spawn_US_PlatoonSet = SET_GROUP:New():FilterPrefixes( "US Tank Platoon Templates" ):FilterOnce()
-- --
-- --- Now use the Spawn_US_PlatoonSet to define the templates using InitRandomizeTemplateSet. -- -- Now use the Spawn_US_PlatoonSet to define the templates using InitRandomizeTemplateSet.
-- Spawn_US_Platoon_Left = SPAWN:New( 'US Tank Platoon Left' ):InitLimit( 12, 150 ):SpawnScheduled( 200, 0.4 ):InitRandomizeTemplateSet( Spawn_US_PlatoonSet ):InitRandomizeRoute( 3, 3, 2000 ) -- Spawn_US_Platoon_Left = SPAWN:New( 'US Tank Platoon Left' ):InitLimit( 12, 150 ):SpawnScheduled( 200, 0.4 ):InitRandomizeTemplateSet( Spawn_US_PlatoonSet ):InitRandomizeRoute( 3, 3, 2000 )
-- 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_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 ) -- 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 ) -- R2.3
self:F( { self.SpawnTemplatePrefix } ) self:F( { self.SpawnTemplatePrefix } )
@@ -868,7 +861,6 @@ function SPAWN:InitRandomizeTemplateSet( SpawnTemplateSet ) -- R2.3
return self return self
end end
--- Randomize templates to be used as the unit representatives for the Spawned group, defined by specifying the prefix names. --- Randomize templates to be used as the unit representatives for the Spawned group, defined by specifying the prefix names.
-- This method becomes useful when you need to spawn groups with random templates of groups defined within the mission editor, -- 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. -- but they will all follow the same Template route and have the same prefix name.
@@ -877,17 +869,19 @@ end
-- @param #string SpawnTemplatePrefixes A string or a list of string that contains the prefixes of the groups that are possible unit representatives of the group to be spawned. -- @param #string SpawnTemplatePrefixes A string or a list of string that contains the prefixes of the groups that are possible unit representatives of the group to be spawned.
-- @return #SPAWN -- @return #SPAWN
-- @usage -- @usage
--
-- -- NATO Tank Platoons invading Gori. -- -- NATO Tank Platoons invading Gori.
-- --
-- -- Choose between different 'US Tank Platoon Templates' configurations to be spawned for the -- -- Choose between different 'US Tank Platoon Templates' configurations to be spawned for the
-- -- 'US Tank Platoon Left', 'US Tank Platoon Middle' and 'US Tank Platoon Right' SPAWN objects. -- -- 'US Tank Platoon Left', 'US Tank Platoon Middle' and 'US Tank Platoon Right' SPAWN objects.
-- --
-- -- Each new SPAWN will randomize the route, with a defined time interval of 200 seconds with 40% time variation (randomization) and -- -- Each new SPAWN will randomize the route, with a defined time interval of 200 seconds with 40% time variation (randomization) and
-- -- with a limit set of maximum 12 Units alive simulteneously and 150 Groups to be spawned during the whole mission. -- -- with a limit set of maximum 12 Units alive simultaneously and 150 Groups to be spawned during the whole mission.
-- --
-- Spawn_US_Platoon_Left = SPAWN:New( 'US Tank Platoon Left' ):InitLimit( 12, 150 ):SpawnScheduled( 200, 0.4 ):InitRandomizeTemplatePrefixes( "US Tank Platoon Templates" ):InitRandomizeRoute( 3, 3, 2000 ) -- Spawn_US_Platoon_Left = SPAWN:New( 'US Tank Platoon Left' ):InitLimit( 12, 150 ):SpawnScheduled( 200, 0.4 ):InitRandomizeTemplatePrefixes( "US Tank Platoon Templates" ):InitRandomizeRoute( 3, 3, 2000 )
-- Spawn_US_Platoon_Middle = SPAWN:New( 'US Tank Platoon Middle' ):InitLimit( 12, 150 ):SpawnScheduled( 200, 0.4 ):InitRandomizeTemplatePrefixes( "US Tank Platoon Templates" ):InitRandomizeRoute( 3, 3, 2000 ) -- Spawn_US_Platoon_Middle = SPAWN:New( 'US Tank Platoon Middle' ):InitLimit( 12, 150 ):SpawnScheduled( 200, 0.4 ):InitRandomizeTemplatePrefixes( "US Tank Platoon Templates" ):InitRandomizeRoute( 3, 3, 2000 )
-- Spawn_US_Platoon_Right = SPAWN:New( 'US Tank Platoon Right' ):InitLimit( 12, 150 ):SpawnScheduled( 200, 0.4 ):InitRandomizeTemplatePrefixes( "US Tank Platoon Templates" ):InitRandomizeRoute( 3, 3, 2000 ) -- Spawn_US_Platoon_Right = SPAWN:New( 'US Tank Platoon Right' ):InitLimit( 12, 150 ):SpawnScheduled( 200, 0.4 ):InitRandomizeTemplatePrefixes( "US Tank Platoon Templates" ):InitRandomizeRoute( 3, 3, 2000 )
--
function SPAWN:InitRandomizeTemplatePrefixes( SpawnTemplatePrefixes ) -- R2.3 function SPAWN:InitRandomizeTemplatePrefixes( SpawnTemplatePrefixes ) -- R2.3
self:F( { self.SpawnTemplatePrefix } ) self:F( { self.SpawnTemplatePrefix } )
@@ -898,7 +892,6 @@ function SPAWN:InitRandomizeTemplatePrefixes( SpawnTemplatePrefixes ) --R2.3
return self return self
end end
--- When spawning a new group, make the grouping of the units according the InitGrouping setting. --- When spawning a new group, make the grouping of the units according the InitGrouping setting.
-- @param #SPAWN self -- @param #SPAWN self
-- @param #number Grouping Indicates the maximum amount of units in the group. -- @param #number Grouping Indicates the maximum amount of units in the group.
@@ -911,13 +904,12 @@ function SPAWN:InitGrouping( Grouping ) -- R2.2
return self return self
end end
--- This method provides the functionality to randomize the spawning of the Groups at a given list of zones of different types. --- 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 #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. -- @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 -- @return #SPAWN
-- @usage -- @usage
--
-- -- Create a zone table of the 2 zones. -- -- Create a zone table of the 2 zones.
-- ZoneTable = { ZONE:New( "Zone1" ), ZONE:New( "Zone2" ) } -- ZoneTable = { ZONE:New( "Zone1" ), ZONE:New( "Zone2" ) }
-- --
@@ -940,11 +932,7 @@ function SPAWN:InitRandomizeZones( SpawnZoneTable )
return self return self
end 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.
--- 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 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... -- This will enable a spawned group to be re-spawned after it lands, until it is destroyed...
-- Note: When the group is respawned, it will re-spawn from the original airbase where it took off. -- Note: When the group is respawned, it will re-spawn from the original airbase where it took off.
@@ -952,10 +940,10 @@ end
-- @param #SPAWN self -- @param #SPAWN self
-- @return #SPAWN self -- @return #SPAWN self
-- @usage -- @usage
--
-- -- RU Su-34 - AI Ship Attack -- -- RU Su-34 - AI Ship Attack
-- -- Re-SPAWN the Group(s) after each landing and Engine Shut-Down automatically. -- -- Re-SPAWN the Group(s) after each landing and Engine Shut-Down automatically.
-- SpawnRU_SU34 = SPAWN -- SpawnRU_SU34 = SPAWN:New( 'Su-34' )
-- :New( 'Su-34' )
-- :Schedule( 2, 3, 1800, 0.4 ) -- :Schedule( 2, 3, 1800, 0.4 )
-- :SpawnUncontrolled() -- :SpawnUncontrolled()
-- :InitRandomizeRoute( 1, 1, 3000 ) -- :InitRandomizeRoute( 1, 1, 3000 )
@@ -975,13 +963,14 @@ end
-- @param #SPAWN self -- @param #SPAWN self
-- @return #SPAWN self -- @return #SPAWN self
-- @usage -- @usage
--
-- -- RU Su-34 - AI Ship Attack -- -- RU Su-34 - AI Ship Attack
-- -- Re-SPAWN the Group(s) after each landing and Engine Shut-Down automatically. -- -- Re-SPAWN the Group(s) after each landing and Engine Shut-Down automatically.
-- SpawnRU_SU34 = SPAWN -- SpawnRU_SU34 = SPAWN:New( 'Su-34' )
-- :New( 'Su-34' )
-- :InitRandomizeRoute( 1, 1, 3000 ) -- :InitRandomizeRoute( 1, 1, 3000 )
-- :InitRepeatOnLanding() -- :InitRepeatOnLanding()
-- :Spawn() -- :Spawn()
--
function SPAWN:InitRepeatOnLanding() function SPAWN:InitRepeatOnLanding()
self:F( { self.SpawnTemplatePrefix } ) self:F( { self.SpawnTemplatePrefix } )
@@ -992,15 +981,14 @@ function SPAWN:InitRepeatOnLanding()
return self return self
end end
--- Respawn after landing when its engines have shut down. --- Respawn after landing when its engines have shut down.
-- @param #SPAWN self -- @param #SPAWN self
-- @return #SPAWN self -- @return #SPAWN self
-- @usage -- @usage
--
-- -- RU Su-34 - AI Ship Attack -- -- RU Su-34 - AI Ship Attack
-- -- Re-SPAWN the Group(s) after each landing and Engine Shut-Down automatically. -- -- Re-SPAWN the Group(s) after each landing and Engine Shut-Down automatically.
-- SpawnRU_SU34 = SPAWN -- SpawnRU_SU34 = SPAWN:New( 'Su-34' )
-- :New( 'Su-34' )
-- :SpawnUncontrolled() -- :SpawnUncontrolled()
-- :InitRandomizeRoute( 1, 1, 3000 ) -- :InitRandomizeRoute( 1, 1, 3000 )
-- :InitRepeatOnEngineShutDown() -- :InitRepeatOnEngineShutDown()
@@ -1015,7 +1003,6 @@ function SPAWN:InitRepeatOnEngineShutDown()
return self return self
end end
--- Delete groups that have not moved for X seconds - AIR ONLY!!! --- Delete groups that have not moved for X seconds - AIR ONLY!!!
-- DO NOT USE ON GROUPS THAT DO NOT MOVE OR YOUR SERVER WILL BURN IN HELL (Pikes - April 2020) -- DO NOT USE ON GROUPS THAT DO NOT MOVE OR YOUR SERVER WILL BURN IN HELL (Pikes - April 2020)
-- When groups are still alive and have become inactive due to damage and are unable to contribute anything, then this group will be removed at defined intervals in seconds. -- When groups are still alive and have become inactive due to damage and are unable to contribute anything, then this group will be removed at defined intervals in seconds.
@@ -1023,7 +1010,9 @@ end
-- @param #string SpawnCleanUpInterval The interval to check for inactive groups within seconds. -- @param #string SpawnCleanUpInterval The interval to check for inactive groups within seconds.
-- @return #SPAWN self -- @return #SPAWN self
-- @usage -- @usage
--
-- Spawn_Helicopter:InitCleanUp( 20 ) -- CleanUp the spawning of the helicopters every 20 seconds when they become inactive. -- Spawn_Helicopter:InitCleanUp( 20 ) -- CleanUp the spawning of the helicopters every 20 seconds when they become inactive.
--
function SPAWN:InitCleanUp( SpawnCleanUpInterval ) function SPAWN:InitCleanUp( SpawnCleanUpInterval )
self:F( { self.SpawnTemplatePrefix, SpawnCleanUpInterval } ) self:F( { self.SpawnTemplatePrefix, SpawnCleanUpInterval } )
@@ -1038,9 +1027,7 @@ function SPAWN:InitCleanUp( SpawnCleanUpInterval )
return self return self
end end
--- Makes the groups visible before start (like a battalion).
--- Makes the groups visible before start (like a batallion).
-- The method will take the position of the group as the first position in the array. -- The method will take the position of the group as the first position in the array.
-- CAUTION: this directive will NOT work with OnSpawnGroup function. -- CAUTION: this directive will NOT work with OnSpawnGroup function.
-- @param #SPAWN self -- @param #SPAWN self
@@ -1050,9 +1037,9 @@ end
-- @param #number SpawnDeltaY The space between each Group on the Y-axis. -- @param #number SpawnDeltaY The space between each Group on the Y-axis.
-- @return #SPAWN self -- @return #SPAWN self
-- @usage -- @usage
--
-- -- Define an array of Groups. -- -- Define an array of Groups.
-- Spawn_BE_Ground = SPAWN -- Spawn_BE_Ground = SPAWN:New( 'BE Ground' )
-- :New( 'BE Ground' )
-- :InitLimit( 2, 24 ) -- :InitLimit( 2, 24 )
-- :InitArray( 90, 10, 100, 50 ) -- :InitArray( 90, 10, 100, 50 )
-- --
@@ -1112,6 +1099,7 @@ function SPAWN:InitArray( SpawnAngle, SpawnWidth, SpawnDeltaX, SpawnDeltaY )
end end
do -- AI methods do -- AI methods
--- Turns the AI On or Off for the @{Wrapper.Group} when spawning. --- Turns the AI On or Off for the @{Wrapper.Group} when spawning.
-- @param #SPAWN self -- @param #SPAWN self
-- @param #boolean AIOnOff A value of true sets the AI On, a value of false sets the AI Off. -- @param #boolean AIOnOff A value of true sets the AI On, a value of false sets the AI Off.
@@ -1223,7 +1211,6 @@ function SPAWN:ReSpawn( SpawnIndex )
return SpawnGroup return SpawnGroup
end end
--- Set the spawn index to a specified index number. --- Set the spawn index to a specified index number.
-- This method can be used to "reset" the spawn counter to a specific index number. -- This method can be used to "reset" the spawn counter to a specific index number.
-- This will actually enable a respawn of groups from the specific index. -- This will actually enable a respawn of groups from the specific index.
@@ -1234,7 +1221,6 @@ function SPAWN:SetSpawnIndex( SpawnIndex )
self.SpawnIndex = SpawnIndex or 0 self.SpawnIndex = SpawnIndex or 0
end end
--- Will spawn a group with a specified index number. --- Will spawn a group with a specified index number.
-- Uses @{DATABASE} global object defined in MOOSE. -- Uses @{DATABASE} global object defined in MOOSE.
-- @param #SPAWN self -- @param #SPAWN self
@@ -1392,7 +1378,6 @@ function SPAWN:SpawnWithIndex( SpawnIndex, NoBirth )
SpawnTemplate.CountryID = self.SpawnInitCountry or SpawnTemplate.CountryID SpawnTemplate.CountryID = self.SpawnInitCountry or SpawnTemplate.CountryID
SpawnTemplate.CoalitionID = self.SpawnInitCoalition or SpawnTemplate.CoalitionID SpawnTemplate.CoalitionID = self.SpawnInitCoalition or SpawnTemplate.CoalitionID
-- if SpawnTemplate.CategoryID == Group.Category.HELICOPTER or SpawnTemplate.CategoryID == Group.Category.AIRPLANE then -- if SpawnTemplate.CategoryID == Group.Category.HELICOPTER or SpawnTemplate.CategoryID == Group.Category.AIRPLANE then
-- if SpawnTemplate.route.points[1].type == "TakeOffParking" then -- if SpawnTemplate.route.points[1].type == "TakeOffParking" then
-- SpawnTemplate.uncontrolled = self.SpawnUnControlled -- SpawnTemplate.uncontrolled = self.SpawnUnControlled
@@ -1437,7 +1422,6 @@ function SPAWN:SpawnWithIndex( SpawnIndex, NoBirth )
-- end -- end
end end
self.SpawnGroups[self.SpawnIndex].Spawned = true self.SpawnGroups[self.SpawnIndex].Spawned = true
return self.SpawnGroups[self.SpawnIndex].Group return self.SpawnGroups[self.SpawnIndex].Group
else else
@@ -1452,7 +1436,7 @@ end
-- @param #SPAWN self -- @param #SPAWN self
-- @param #number SpawnTime The time interval defined in seconds between each new spawn of new groups. -- @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. -- @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 %-tage of variation to be applied on the time interval. -- The variation is a number between 0 and 1, representing the % of variation to be applied on the time interval.
-- @return #SPAWN self -- @return #SPAWN self
-- @usage -- @usage
-- -- NATO helicopters engaging in the battle field. -- -- NATO helicopters engaging in the battle field.
@@ -1461,7 +1445,7 @@ end
-- -- This is calculated as follows: -- -- This is calculated as follows:
-- -- Low limit: 600 * ( 1 - 0.5 / 2 ) = 450 -- -- Low limit: 600 * ( 1 - 0.5 / 2 ) = 450
-- -- High limit: 600 * ( 1 + 0.5 / 2 ) = 750 -- -- High limit: 600 * ( 1 + 0.5 / 2 ) = 750
-- -- Between these two values, a random amount of seconds will be choosen for each new spawn of the helicopters. -- -- 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 ) -- 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 )
self:F( { SpawnTime, SpawnTimeVariation } ) self:F( { SpawnTime, SpawnTimeVariation } )
@@ -1498,7 +1482,6 @@ function SPAWN:SpawnScheduleStop()
return self return self
end end
--- Allows to place a CallFunction hook when a new group spawns. --- Allows to place a CallFunction hook when a new group spawns.
-- The provided method will be called when a new group is spawned, including its given parameters. -- The provided method will be called when a new group is spawned, including its given parameters.
-- The first parameter of the SpawnFunction is the @{Wrapper.Group#GROUP} that was spawned. -- The first parameter of the SpawnFunction is the @{Wrapper.Group#GROUP} that was spawned.
@@ -1507,12 +1490,11 @@ end
-- @param SpawnFunctionArguments A random amount of arguments to be provided to the function when the group spawns. -- @param SpawnFunctionArguments A random amount of arguments to be provided to the function when the group spawns.
-- @return #SPAWN -- @return #SPAWN
-- @usage -- @usage
--
-- -- Declare SpawnObject and call a function when a new Group is spawned. -- -- Declare SpawnObject and call a function when a new Group is spawned.
-- local SpawnObject = SPAWN -- local SpawnObject = SPAWN:New( "SpawnObject" )
-- :New( "SpawnObject" )
-- :InitLimit( 2, 10 ) -- :InitLimit( 2, 10 )
-- :OnSpawnGroup( -- :OnSpawnGroup( function( SpawnGroup )
-- function( SpawnGroup )
-- SpawnGroup:E( "I am spawned" ) -- SpawnGroup:E( "I am spawned" )
-- end -- end
-- ) -- )
@@ -1546,7 +1528,7 @@ end
-- The known AIRBASE objects are automatically imported at mission start by MOOSE. -- The known AIRBASE objects are automatically imported at mission start by MOOSE.
-- Therefore, there isn't any New() constructor defined for AIRBASE objects. -- Therefore, there isn't any New() constructor defined for AIRBASE objects.
-- --
-- Ships and Farps are added within the mission, and are therefore not known. -- Ships and FARPs are added within the mission, and are therefore not known.
-- For these AIRBASE objects, there isn't an @{Wrapper.Airbase#AIRBASE} enumeration defined. -- For these AIRBASE objects, there isn't an @{Wrapper.Airbase#AIRBASE} enumeration defined.
-- You need to provide the **exact name** of the airbase as the parameter to the @{Wrapper.Airbase#AIRBASE.FindByName}() method! -- You need to provide the **exact name** of the airbase as the parameter to the @{Wrapper.Airbase#AIRBASE.FindByName}() method!
-- --
@@ -1556,9 +1538,10 @@ end
-- @param #number TakeoffAltitude (optional) The altitude above the ground. -- @param #number TakeoffAltitude (optional) The altitude above the ground.
-- @param Wrapper.Airbase#AIRBASE.TerminalType TerminalType (optional) The terminal type the aircraft should be spawned at. See @{Wrapper.Airbase#AIRBASE.TerminalType}. -- @param Wrapper.Airbase#AIRBASE.TerminalType TerminalType (optional) The terminal type the aircraft should be spawned at. See @{Wrapper.Airbase#AIRBASE.TerminalType}.
-- @param #boolean EmergencyAirSpawn (optional) If true (default), groups are spawned in air if there is no parking spot at the airbase. If false, nothing is spawned if no parking spot is available. -- @param #boolean EmergencyAirSpawn (optional) If true (default), groups are spawned in air if there is no parking spot at the airbase. If false, nothing is spawned if no parking spot is available.
-- @param #table Parkingdata (optional) Table holding the coordinates and terminal ids for all units of the group. Spawning will be forced to happen at exactily these spots! -- @param #table Parkingdata (optional) Table holding the coordinates and terminal ids for all units of the group. Spawning will be forced to happen at exactly these spots!
-- @return Wrapper.Group#GROUP The group that was spawned or nil when nothing was spawned. -- @return Wrapper.Group#GROUP The group that was spawned or nil when nothing was spawned.
-- @usage -- @usage
--
-- Spawn_Plane = SPAWN:New( "Plane" ) -- Spawn_Plane = SPAWN:New( "Plane" )
-- Spawn_Plane:SpawnAtAirbase( AIRBASE:FindByName( AIRBASE.Caucasus.Krymsk ), SPAWN.Takeoff.Cold ) -- Spawn_Plane:SpawnAtAirbase( AIRBASE:FindByName( AIRBASE.Caucasus.Krymsk ), SPAWN.Takeoff.Cold )
-- Spawn_Plane:SpawnAtAirbase( AIRBASE:FindByName( AIRBASE.Caucasus.Krymsk ), SPAWN.Takeoff.Hot ) -- Spawn_Plane:SpawnAtAirbase( AIRBASE:FindByName( AIRBASE.Caucasus.Krymsk ), SPAWN.Takeoff.Hot )
@@ -1686,7 +1669,6 @@ function SPAWN:SpawnAtAirbase( SpawnAirbase, Takeoff, TakeoffAltitude, TerminalT
-- Spawn happens on ground, i.e. at an airbase, a FARP or a ship. -- Spawn happens on ground, i.e. at an airbase, a FARP or a ship.
if spawnonground and not SpawnTemplate.parked then if spawnonground and not SpawnTemplate.parked then
-- Number of free parking spots. -- Number of free parking spots.
local nfree = 0 local nfree = 0
@@ -2021,7 +2003,6 @@ function SPAWN:SpawnAtParkingSpot(Airbase, Spots, Takeoff) -- R2.5
self:E( "ERROR: Could not find enough free parking spots!" ) self:E( "ERROR: Could not find enough free parking spots!" )
end end
else else
self:E( "ERROR: Could not get number of units in group!" ) self:E( "ERROR: Could not get number of units in group!" )
end end
@@ -2128,7 +2109,6 @@ function SPAWN:ParkAircraft( SpawnAirbase, TerminalType, Parkingdata, SpawnIndex
-- Spawn happens on ground, i.e. at an airbase, a FARP or a ship. -- Spawn happens on ground, i.e. at an airbase, a FARP or a ship.
if spawnonground and not SpawnTemplate.parked then if spawnonground and not SpawnTemplate.parked then
-- Number of free parking spots. -- Number of free parking spots.
local nfree = 0 local nfree = 0
@@ -2485,7 +2465,6 @@ function SPAWN:SpawnFromVec3( Vec3, SpawnIndex )
return nil return nil
end end
--- Will spawn a group from a Coordinate in 3D space. --- Will spawn a group from a Coordinate in 3D space.
-- This method is mostly advisable to be used if you want to simulate spawning units in the air, like helicopters or airplanes. -- This method is mostly advisable to be used if you want to simulate spawning units in the air, like helicopters or airplanes.
-- Note that each point in the route assigned to the spawning group is reset to the point of the spawn. -- Note that each point in the route assigned to the spawning group is reset to the point of the spawn.
@@ -2501,8 +2480,6 @@ function SPAWN:SpawnFromCoordinate( Coordinate, SpawnIndex )
return self:SpawnFromVec3( Coordinate:GetVec3(), SpawnIndex ) return self:SpawnFromVec3( Coordinate:GetVec3(), SpawnIndex )
end end
--- Will spawn a group from a PointVec3 in 3D space. --- Will spawn a group from a PointVec3 in 3D space.
-- This method is mostly advisable to be used if you want to simulate spawning units in the air, like helicopters or airplanes. -- This method is mostly advisable to be used if you want to simulate spawning units in the air, like helicopters or airplanes.
-- Note that each point in the route assigned to the spawning group is reset to the point of the spawn. -- Note that each point in the route assigned to the spawning group is reset to the point of the spawn.
@@ -2525,7 +2502,6 @@ function SPAWN:SpawnFromPointVec3( PointVec3, SpawnIndex )
return self:SpawnFromVec3( PointVec3:GetVec3(), SpawnIndex ) return self:SpawnFromVec3( PointVec3:GetVec3(), SpawnIndex )
end end
--- Will spawn a group from a Vec2 in 3D space. --- Will spawn a group from a Vec2 in 3D space.
-- This method is mostly advisable to be used if you want to simulate spawning groups on the ground from air units, like vehicles. -- This method is mostly advisable to be used if you want to simulate spawning groups on the ground from air units, like vehicles.
-- Note that each point in the route assigned to the spawning group is reset to the point of the spawn. -- Note that each point in the route assigned to the spawning group is reset to the point of the spawn.
@@ -2559,7 +2535,6 @@ function SPAWN:SpawnFromVec2( Vec2, MinHeight, MaxHeight, SpawnIndex )
return self:SpawnFromVec3( { x = Vec2.x, y = Height, z = Vec2.y }, SpawnIndex ) -- y can be nil. In this case, spawn on the ground for vehicles, and in the template altitude for air. return self:SpawnFromVec3( { x = Vec2.x, y = Height, z = Vec2.y }, SpawnIndex ) -- y can be nil. In this case, spawn on the ground for vehicles, and in the template altitude for air.
end end
--- Will spawn a group from a POINT_VEC2 in 3D space. --- Will spawn a group from a POINT_VEC2 in 3D space.
-- This method is mostly advisable to be used if you want to simulate spawning groups on the ground from air units, like vehicles. -- This method is mostly advisable to be used if you want to simulate spawning groups on the ground from air units, like vehicles.
-- Note that each point in the route assigned to the spawning group is reset to the point of the spawn. -- Note that each point in the route assigned to the spawning group is reset to the point of the spawn.
@@ -2587,8 +2562,6 @@ function SPAWN:SpawnFromPointVec2( PointVec2, MinHeight, MaxHeight, SpawnIndex )
return self:SpawnFromVec2( PointVec2:GetVec2(), MinHeight, MaxHeight, SpawnIndex ) return self:SpawnFromVec2( PointVec2:GetVec2(), MinHeight, MaxHeight, SpawnIndex )
end end
--- Will spawn a group from a hosting unit. This method is mostly advisable to be used if you want to simulate spawning from air units, like helicopters, which are dropping infantry into a defined Landing Zone. --- Will spawn a group from a hosting unit. This method is mostly advisable to be used if you want to simulate spawning from air units, like helicopters, which are dropping infantry into a defined Landing Zone.
-- Note that each point in the route assigned to the spawning group is reset to the point of the spawn. -- Note that each point in the route assigned to the spawning group is reset to the point of the spawn.
-- You can use the returned group to further define the route to be followed. -- You can use the returned group to further define the route to be followed.
@@ -2712,7 +2685,6 @@ function SPAWN:InitUnControlled( UnControlled )
return self return self
end end
--- Get the Coordinate of the Group that is Late Activated as the template for the SPAWN object. --- Get the Coordinate of the Group that is Late Activated as the template for the SPAWN object.
-- @param #SPAWN self -- @param #SPAWN self
-- @return Core.Point#COORDINATE The Coordinate -- @return Core.Point#COORDINATE The Coordinate
@@ -2726,7 +2698,6 @@ function SPAWN:GetCoordinate()
return nil return nil
end end
--- Will return the SpawnGroupName either with with a specific count number or without any count. --- Will return the SpawnGroupName either with with a specific count number or without any count.
-- @param #SPAWN self -- @param #SPAWN self
-- @param #number SpawnIndex Is the number of the Group that is to be spawned. -- @param #number SpawnIndex Is the number of the Group that is to be spawned.
@@ -2755,12 +2726,14 @@ end
-- @return Wrapper.Group#GROUP, #number The @{Wrapper.Group} object found, the new Index where the group was found. -- @return Wrapper.Group#GROUP, #number The @{Wrapper.Group} object found, the new Index where the group was found.
-- @return #nil, #nil When no group is found, #nil is returned. -- @return #nil, #nil When no group is found, #nil is returned.
-- @usage -- @usage
--
-- -- Find the first alive @{Wrapper.Group} object of the SpawnPlanes SPAWN object @{Wrapper.Group} collection that it has spawned during the mission. -- -- Find the first alive @{Wrapper.Group} object of the SpawnPlanes SPAWN object @{Wrapper.Group} collection that it has spawned during the mission.
-- local GroupPlane, Index = SpawnPlanes:GetFirstAliveGroup() -- local GroupPlane, Index = SpawnPlanes:GetFirstAliveGroup()
-- while GroupPlane ~= nil do -- while GroupPlane ~= nil do
-- -- Do actions with the GroupPlane object. -- -- Do actions with the GroupPlane object.
-- GroupPlane, Index = SpawnPlanes:GetNextAliveGroup( Index ) -- GroupPlane, Index = SpawnPlanes:GetNextAliveGroup( Index )
-- end -- end
--
function SPAWN:GetFirstAliveGroup() function SPAWN:GetFirstAliveGroup()
self:F( { self.SpawnTemplatePrefix, self.SpawnAliasPrefix } ) self:F( { self.SpawnTemplatePrefix, self.SpawnAliasPrefix } )
@@ -2774,19 +2747,20 @@ function SPAWN:GetFirstAliveGroup()
return nil, nil return nil, nil
end end
--- Will find the next alive @{Wrapper.Group} object from a given Index, and return a reference to the alive @{Wrapper.Group} object and the next Index where the alive @{Wrapper.Group} has been found. --- Will find the next alive @{Wrapper.Group} object from a given Index, and return a reference to the alive @{Wrapper.Group} object and the next Index where the alive @{Wrapper.Group} has been found.
-- @param #SPAWN self -- @param #SPAWN self
-- @param #number SpawnIndexStart A Index holding the start position to search from. This method can also be used to find the first alive @{Wrapper.Group} object from the given Index. -- @param #number SpawnIndexStart A Index holding the start position to search from. This method can also be used to find the first alive @{Wrapper.Group} object from the given Index.
-- @return Wrapper.Group#GROUP, #number The next alive @{Wrapper.Group} object found, the next Index where the next alive @{Wrapper.Group} object was found. -- @return Wrapper.Group#GROUP, #number The next alive @{Wrapper.Group} object found, the next Index where the next alive @{Wrapper.Group} object was found.
-- @return #nil, #nil When no alive @{Wrapper.Group} object is found from the start Index position, #nil is returned. -- @return #nil, #nil When no alive @{Wrapper.Group} object is found from the start Index position, #nil is returned.
-- @usage -- @usage
--
-- -- Find the first alive @{Wrapper.Group} object of the SpawnPlanes SPAWN object @{Wrapper.Group} collection that it has spawned during the mission. -- -- Find the first alive @{Wrapper.Group} object of the SpawnPlanes SPAWN object @{Wrapper.Group} collection that it has spawned during the mission.
-- local GroupPlane, Index = SpawnPlanes:GetFirstAliveGroup() -- local GroupPlane, Index = SpawnPlanes:GetFirstAliveGroup()
-- while GroupPlane ~= nil do -- while GroupPlane ~= nil do
-- -- Do actions with the GroupPlane object. -- -- Do actions with the GroupPlane object.
-- GroupPlane, Index = SpawnPlanes:GetNextAliveGroup( Index ) -- GroupPlane, Index = SpawnPlanes:GetNextAliveGroup( Index )
-- end -- end
--
function SPAWN:GetNextAliveGroup( SpawnIndexStart ) function SPAWN:GetNextAliveGroup( SpawnIndexStart )
self:F( { self.SpawnTemplatePrefix, self.SpawnAliasPrefix, SpawnIndexStart } ) self:F( { self.SpawnTemplatePrefix, self.SpawnAliasPrefix, SpawnIndexStart } )
@@ -2806,11 +2780,13 @@ end
-- @return Wrapper.Group#GROUP, #number The last alive @{Wrapper.Group} object found, the last Index where the last alive @{Wrapper.Group} object was found. -- @return Wrapper.Group#GROUP, #number The last alive @{Wrapper.Group} object found, the last Index where the last alive @{Wrapper.Group} object was found.
-- @return #nil, #nil When no alive @{Wrapper.Group} object is found, #nil is returned. -- @return #nil, #nil When no alive @{Wrapper.Group} object is found, #nil is returned.
-- @usage -- @usage
--
-- -- Find the last alive @{Wrapper.Group} object of the SpawnPlanes SPAWN object @{Wrapper.Group} collection that it has spawned during the mission. -- -- Find the last alive @{Wrapper.Group} object of the SpawnPlanes SPAWN object @{Wrapper.Group} collection that it has spawned during the mission.
-- local GroupPlane, Index = SpawnPlanes:GetLastAliveGroup() -- local GroupPlane, Index = SpawnPlanes:GetLastAliveGroup()
-- if GroupPlane then -- GroupPlane can be nil!!! -- if GroupPlane then -- GroupPlane can be nil!!!
-- -- Do actions with the GroupPlane object. -- -- Do actions with the GroupPlane object.
-- end -- end
--
function SPAWN:GetLastAliveGroup() function SPAWN:GetLastAliveGroup()
self:F( { self.SpawnTemplatePrefix, self.SpawnAliasPrefix } ) self:F( { self.SpawnTemplatePrefix, self.SpawnAliasPrefix } )
@@ -2826,8 +2802,6 @@ function SPAWN:GetLastAliveGroup()
return nil return nil
end end
--- Get the group from an index. --- Get the group from an index.
-- Returns the group from the SpawnGroups list. -- Returns the group from the SpawnGroups list.
-- If no index is given, it will return the first group in the list. -- If no index is given, it will return the first group in the list.
@@ -2849,7 +2823,6 @@ function SPAWN:GetGroupFromIndex( SpawnIndex )
end end
end end
--- Return the prefix of a SpawnUnit. --- Return the prefix of a SpawnUnit.
-- The method will search for a #-mark, and will return the text before the #-mark. -- The method will search for a #-mark, and will return the text before the #-mark.
-- It will return nil of no prefix was found. -- It will return nil of no prefix was found.
@@ -2872,7 +2845,6 @@ function SPAWN:_GetPrefixFromGroup( SpawnGroup )
return nil return nil
end end
--- Get the index from a given group. --- Get the index from a given group.
-- The function will search the name of the group for a #, and will return the number behind the #-mark. -- The function will search the name of the group for a #, and will return the number behind the #-mark.
function SPAWN:GetSpawnIndexFromGroup( SpawnGroup ) function SPAWN:GetSpawnIndexFromGroup( SpawnGroup )
@@ -2916,8 +2888,6 @@ function SPAWN:_InitializeSpawnGroups( SpawnIndex )
return self.SpawnGroups[SpawnIndex] return self.SpawnGroups[SpawnIndex]
end end
--- Gets the CategoryID of the Group with the given SpawnPrefix --- Gets the CategoryID of the Group with the given SpawnPrefix
function SPAWN:_GetGroupCategoryID( SpawnPrefix ) function SPAWN:_GetGroupCategoryID( SpawnPrefix )
local TemplateGroup = Group.getByName( SpawnPrefix ) local TemplateGroup = Group.getByName( SpawnPrefix )
@@ -3002,7 +2972,6 @@ function SPAWN:_Prepare( SpawnTemplatePrefix, SpawnIndex ) --R2.2
SpawnTemplate.name = self:SpawnGroupName( SpawnIndex ) SpawnTemplate.name = self:SpawnGroupName( SpawnIndex )
end end
SpawnTemplate.groupId = nil SpawnTemplate.groupId = nil
-- SpawnTemplate.lateActivation = false -- SpawnTemplate.lateActivation = false
SpawnTemplate.lateActivation = self.LateActivated or false SpawnTemplate.lateActivation = self.LateActivated or false
@@ -3189,16 +3158,13 @@ function SPAWN:_TranslateRotate( SpawnIndex, SpawnRootX, SpawnRootY, SpawnX, Spa
-- From Wikipedia: https://en.wikipedia.org/wiki/Rotation_matrix#Common_rotations -- From Wikipedia: https://en.wikipedia.org/wiki/Rotation_matrix#Common_rotations
-- x' = x \cos \theta - y \sin \theta\ -- x' = x \cos \theta - y \sin \theta\
-- y' = x \sin \theta + y \cos \theta\ -- y' = x \sin \theta + y \cos \theta\
local RotatedX = - TranslatedX * math.cos( math.rad( SpawnAngle ) ) local RotatedX = -TranslatedX * math.cos( math.rad( SpawnAngle ) ) + TranslatedY * math.sin( math.rad( SpawnAngle ) )
+ TranslatedY * math.sin( math.rad( SpawnAngle ) ) local RotatedY = TranslatedX * math.sin( math.rad( SpawnAngle ) ) + TranslatedY * math.cos( math.rad( SpawnAngle ) )
local RotatedY = TranslatedX * math.sin( math.rad( SpawnAngle ) )
+ TranslatedY * math.cos( math.rad( SpawnAngle ) )
-- Assign -- Assign
self.SpawnGroups[SpawnIndex].SpawnTemplate.x = SpawnRootX - RotatedX self.SpawnGroups[SpawnIndex].SpawnTemplate.x = SpawnRootX - RotatedX
self.SpawnGroups[SpawnIndex].SpawnTemplate.y = SpawnRootY + RotatedY self.SpawnGroups[SpawnIndex].SpawnTemplate.y = SpawnRootY + RotatedY
local SpawnUnitCount = table.getn( self.SpawnGroups[SpawnIndex].SpawnTemplate.units ) local SpawnUnitCount = table.getn( self.SpawnGroups[SpawnIndex].SpawnTemplate.units )
for u = 1, SpawnUnitCount do for u = 1, SpawnUnitCount do
@@ -3207,10 +3173,8 @@ function SPAWN:_TranslateRotate( SpawnIndex, SpawnRootX, SpawnRootY, SpawnX, Spa
local TranslatedY = SpawnY - 10 * (u - 1) local TranslatedY = SpawnY - 10 * (u - 1)
-- Rotate -- Rotate
local RotatedX = - TranslatedX * math.cos( math.rad( SpawnAngle ) ) local RotatedX = -TranslatedX * math.cos( math.rad( SpawnAngle ) ) + TranslatedY * math.sin( math.rad( SpawnAngle ) )
+ TranslatedY * math.sin( math.rad( SpawnAngle ) ) local RotatedY = TranslatedX * math.sin( math.rad( SpawnAngle ) ) + TranslatedY * math.cos( math.rad( SpawnAngle ) )
local RotatedY = TranslatedX * math.sin( math.rad( SpawnAngle ) )
+ TranslatedY * math.cos( math.rad( SpawnAngle ) )
-- Assign -- Assign
self.SpawnGroups[SpawnIndex].SpawnTemplate.units[u].x = SpawnRootX - RotatedX self.SpawnGroups[SpawnIndex].SpawnTemplate.units[u].x = SpawnRootX - RotatedX
@@ -3249,7 +3213,6 @@ function SPAWN:_GetSpawnIndex( SpawnIndex )
return self.SpawnIndex return self.SpawnIndex
end end
-- TODO Need to delete this... _DATABASE does this now ... -- TODO Need to delete this... _DATABASE does this now ...
--- @param #SPAWN self --- @param #SPAWN self
@@ -3400,7 +3363,6 @@ function SPAWN:_SpawnCleanUpScheduler()
local SpawnUnit = UnitData -- Wrapper.Unit#UNIT local SpawnUnit = UnitData -- Wrapper.Unit#UNIT
local SpawnUnitName = SpawnUnit:GetName() local SpawnUnitName = SpawnUnit:GetName()
self.SpawnCleanUpTimeStamps[SpawnUnitName] = self.SpawnCleanUpTimeStamps[SpawnUnitName] or {} self.SpawnCleanUpTimeStamps[SpawnUnitName] = self.SpawnCleanUpTimeStamps[SpawnUnitName] or {}
local Stamp = self.SpawnCleanUpTimeStamps[SpawnUnitName] local Stamp = self.SpawnCleanUpTimeStamps[SpawnUnitName]
self:T( { SpawnUnitName, Stamp } ) self:T( { SpawnUnitName, Stamp } )

View File

@@ -23,7 +23,6 @@
-- @module Functional.FOX -- @module Functional.FOX
-- @image Functional_FOX.png -- @image Functional_FOX.png
--- FOX class. --- FOX class.
-- @type FOX -- @type FOX
-- @field #string ClassName Name of the class. -- @field #string ClassName Name of the class.
@@ -48,7 +47,6 @@
-- @field #number dt05 Time step [sec] for missile position updates if distance to target > 5 km and < 10 km. Default 0.5 sec. -- @field #number dt05 Time step [sec] for missile position updates if distance to target > 5 km and < 10 km. Default 0.5 sec.
-- @field #number dt01 Time step [sec] for missile position updates if distance to target > 1 km and < 5 km. Default 0.1 sec. -- @field #number dt01 Time step [sec] for missile position updates if distance to target > 1 km and < 5 km. Default 0.1 sec.
-- @field #number dt00 Time step [sec] for missile position updates if distance to target < 1 km. Default 0.01 sec. -- @field #number dt00 Time step [sec] for missile position updates if distance to target < 1 km. Default 0.01 sec.
-- @field #boolean
-- @extends Core.Fsm#FSM -- @extends Core.Fsm#FSM
--- Fox 3! --- Fox 3!

View File

@@ -19,8 +19,8 @@
-- --
-- @module Functional.Mantis -- @module Functional.Mantis
-- @image Functional.Mantis.jpg -- @image Functional.Mantis.jpg
--
-- Date: July 2021 -- Date: Nov 2021
------------------------------------------------------------------------- -------------------------------------------------------------------------
--- **MANTIS** class, extends Core.Base#BASE --- **MANTIS** class, extends Core.Base#BASE
@@ -101,23 +101,23 @@
-- --
-- # 2. Start up your MANTIS with a basic setting -- # 2. Start up your MANTIS with a basic setting
-- --
-- `myredmantis = MANTIS:New("myredmantis","Red SAM","Red EWR",nil,"red",false)` -- myredmantis = MANTIS:New("myredmantis","Red SAM","Red EWR",nil,"red",false)
-- `myredmantis:Start()` -- myredmantis:Start()
-- --
-- [optional] Use -- [optional] Use
-- --
-- * `MANTIS:SetEWRGrouping(radius)` -- * MANTIS:SetEWRGrouping(radius)
-- * `MANTIS:SetEWRRange(radius)` -- * MANTIS:SetEWRRange(radius)
-- * `MANTIS:SetSAMRadius(radius)` -- * MANTIS:SetSAMRadius(radius)
-- * `MANTIS:SetDetectInterval(interval)` -- * MANTIS:SetDetectInterval(interval)
-- * `MANTIS:SetAutoRelocate(hq, ewr)` -- * MANTIS:SetAutoRelocate(hq, ewr)
-- --
-- before starting #MANTIS to fine-tune your setup. -- before starting #MANTIS to fine-tune your setup.
-- --
-- If you want to use a separate AWACS unit (default detection range: 250km) to support your EWR system, use e.g. the following setup: -- If you want to use a separate AWACS unit (default detection range: 250km) to support your EWR system, use e.g. the following setup:
-- --
-- `mybluemantis = MANTIS:New("bluemantis","Blue SAM","Blue EWR",nil,"blue",false,"Blue Awacs")` -- mybluemantis = MANTIS:New("bluemantis","Blue SAM","Blue EWR",nil,"blue",false,"Blue Awacs")
-- `mybluemantis:Start()` -- mybluemantis:Start()
-- --
-- # 3. Default settings -- # 3. Default settings
-- --
@@ -138,7 +138,7 @@
-- --
-- Advanced mode will *decrease* reactivity of MANTIS, if HQ and/or EWR network dies. Awacs is counted as one EWR unit. It will set SAMs to RED state if both are dead. Requires usage of an **HQ** object and the **dynamic** option. -- Advanced mode will *decrease* reactivity of MANTIS, if HQ and/or EWR network dies. Awacs is counted as one EWR unit. It will set SAMs to RED state if both are dead. Requires usage of an **HQ** object and the **dynamic** option.
-- --
-- E.g. `mymantis:SetAdvancedMode( true, 90 )` -- E.g. mymantis:SetAdvancedMode( true, 90 )
-- --
-- Use this option if you want to make use of or allow advanced SEAD tactics. -- Use this option if you want to make use of or allow advanced SEAD tactics.
-- --
@@ -147,16 +147,39 @@
-- You can also choose to integrate Mantis with @{Functional.Shorad#SHORAD} for protection against HARMs and AGMs. When SHORAD detects a missile fired at one of MANTIS' SAM sites, it will activate SHORAD systems in -- You can also choose to integrate Mantis with @{Functional.Shorad#SHORAD} for protection against HARMs and AGMs. When SHORAD detects a missile fired at one of MANTIS' SAM sites, it will activate SHORAD systems in
-- the given defense checkradius around that SAM site. Create a SHORAD object first, then integrate with MANTIS like so: -- the given defense checkradius around that SAM site. Create a SHORAD object first, then integrate with MANTIS like so:
-- --
-- `local SamSet = SET_GROUP:New():FilterPrefixes("Blue SAM"):FilterCoalitions("blue"):FilterStart()` -- local SamSet = SET_GROUP:New():FilterPrefixes("Blue SAM"):FilterCoalitions("blue"):FilterStart()
-- `myshorad = SHORAD:New("BlueShorad", "Blue SHORAD", SamSet, 22000, 600, "blue")` -- myshorad = SHORAD:New("BlueShorad", "Blue SHORAD", SamSet, 22000, 600, "blue")
-- `-- now set up MANTIS` -- -- now set up MANTIS
-- `mymantis = MANTIS:New("BlueMantis","Blue SAM","Blue EWR",nil,"blue",false,"Blue Awacs")` -- mymantis = MANTIS:New("BlueMantis","Blue SAM","Blue EWR",nil,"blue",false,"Blue Awacs")
-- `mymantis:AddShorad(myshorad,720)` -- mymantis:AddShorad(myshorad,720)
-- `mymantis:Start()` -- mymantis:Start()
-- --
-- and (optionally) remove the link later on with -- and (optionally) remove the link later on with
-- --
-- `mymantis:RemoveShorad()` -- mymantis:RemoveShorad()
--
-- # 6. Integrated SEAD
--
-- MANTIS is using @{Functional.Sead#SEAD} internally to both detect and evade HARM attacks. No extra efforts needed to set this up!
-- Once a HARM attack is detected, MANTIS (via SEAD) will shut down the radars of the attacked SAM site and take evasive action by moving the SAM
-- vehicles around (*if they are __drivable__*, that is). There's a component of randomness in detection and evasion, which is based on the
-- skill set of the SAM set (the higher the skill, the more likely). When a missile is fired from far away, the SAM will stay active for a
-- period of time to stay defensive, before it takes evasive actions.
--
-- You can link into the SEAD driven events of MANTIS like so:
--
-- function mymantis:OnAfterSeadSuppressionPlanned(From, Event, To, Group, Name, SuppressionStartTime, SuppressionEndTime)
-- -- your code here - SAM site shutdown and evasion planned, but not yet executed
-- -- Time entries relate to timer.getTime() - see https://wiki.hoggitworld.com/view/DCS_func_getTime
-- end
--
-- function mymantis:OnAfterSeadSuppressionStart(From, Event, To, Group, Name)
-- -- your code here - SAM site is emissions off and possibly moving
-- end
--
-- function mymantis:OnAfterSeadSuppressionEnd(From, Event, To, Group, Name)
-- -- your code here - SAM site is back online
-- end
-- --
-- @field #MANTIS -- @field #MANTIS
MANTIS = { MANTIS = {
@@ -198,6 +221,7 @@ MANTIS = {
DLink = false, DLink = false,
DLTimeStamp = 0, DLTimeStamp = 0,
Padding = 10, Padding = 10,
SuppressedGroups = {},
} }
--- Advanced state enumerator --- Advanced state enumerator
@@ -227,23 +251,23 @@ do
--@return #MANTIS self --@return #MANTIS self
--@usage Start up your MANTIS with a basic setting --@usage Start up your MANTIS with a basic setting
-- --
-- `myredmantis = MANTIS:New("myredmantis","Red SAM","Red EWR",nil,"red",false)` -- myredmantis = MANTIS:New("myredmantis","Red SAM","Red EWR",nil,"red",false)
-- `myredmantis:Start()` -- myredmantis:Start()
-- --
-- [optional] Use -- [optional] Use
-- --
-- * `MANTIS:SetEWRGrouping(radius)` -- * MANTIS:SetEWRGrouping(radius)
-- * `MANTIS:SetEWRRange(radius)` -- * MANTIS:SetEWRRange(radius)
-- * `MANTIS:SetSAMRadius(radius)` -- * MANTIS:SetSAMRadius(radius)
-- * `MANTIS:SetDetectInterval(interval)` -- * MANTIS:SetDetectInterval(interval)
-- * `MANTIS:SetAutoRelocate(hq, ewr)` -- * MANTIS:SetAutoRelocate(hq, ewr)
-- --
-- before starting #MANTIS to fine-tune your setup. -- before starting #MANTIS to fine-tune your setup.
-- --
-- If you want to use a separate AWACS unit (default detection range: 250km) to support your EWR system, use e.g. the following setup: -- If you want to use a separate AWACS unit (default detection range: 250km) to support your EWR system, use e.g. the following setup:
-- --
-- `mybluemantis = MANTIS:New("bluemantis","Blue SAM","Blue EWR",nil,"blue",false,"Blue Awacs")` -- mybluemantis = MANTIS:New("bluemantis","Blue SAM","Blue EWR",nil,"blue",false,"Blue Awacs")
-- `mybluemantis:Start()` -- mybluemantis:Start()
-- --
function MANTIS:New(name,samprefix,ewrprefix,hq,coaltion,dynamic,awacs, EmOnOff, Padding) function MANTIS:New(name,samprefix,ewrprefix,hq,coaltion,dynamic,awacs, EmOnOff, Padding)
@@ -284,6 +308,7 @@ do
self.SamStateTracker = {} -- table to hold alert states, so we don't trigger state changes twice in adv mode self.SamStateTracker = {} -- table to hold alert states, so we don't trigger state changes twice in adv mode
self.DLink = false self.DLink = false
self.Padding = Padding or 10 self.Padding = Padding or 10
self.SuppressedGroups = {}
if EmOnOff then if EmOnOff then
if EmOnOff == false then if EmOnOff == false then
@@ -331,7 +356,7 @@ do
end end
-- @field #string version -- @field #string version
self.version="0.6.2" self.version="0.7.1"
self:I(string.format("***** Starting MANTIS Version %s *****", self.version)) self:I(string.format("***** Starting MANTIS Version %s *****", self.version))
--- FSM Functions --- --- FSM Functions ---
@@ -348,6 +373,9 @@ do
self:AddTransition("*", "RedState", "*") -- MANTIS A SAM switching to RED state. self:AddTransition("*", "RedState", "*") -- MANTIS A SAM switching to RED state.
self:AddTransition("*", "AdvStateChange", "*") -- MANTIS advanced mode state change. self:AddTransition("*", "AdvStateChange", "*") -- MANTIS advanced mode state change.
self:AddTransition("*", "ShoradActivated", "*") -- MANTIS woke up a connected SHORAD. self:AddTransition("*", "ShoradActivated", "*") -- MANTIS woke up a connected SHORAD.
self:AddTransition("*", "SeadSuppressionStart", "*") -- SEAD has switched off one group.
self:AddTransition("*", "SeadSuppressionEnd", "*") -- SEAD has switched on one group.
self:AddTransition("*", "SeadSuppressionPlanned", "*") -- SEAD has planned a suppression.
self:AddTransition("*", "Stop", "Stopped") -- Stop FSM. self:AddTransition("*", "Stop", "Stopped") -- Stop FSM.
------------------------ ------------------------
@@ -427,6 +455,35 @@ do
-- @param #number Radius Radius around the named group to find SHORAD groups -- @param #number Radius Radius around the named group to find SHORAD groups
-- @param #number Ontime Seconds the SHORAD will stay active -- @param #number Ontime Seconds the SHORAD will stay active
--- On After "SeadSuppressionPlanned" event. Mantis has planned to switch off a site to defend SEAD attack.
-- @function [parent=#MANTIS] OnAfterSeadSuppressionPlanned
-- @param #MANTIS self
-- @param #string From The From State
-- @param #string Event The Event
-- @param #string To The To State
-- @param Wrapper.Group#GROUP Group The suppressed GROUP object
-- @param #string Name Name of the suppressed group
-- @param #number SuppressionStartTime Model start time of the suppression from `timer.getTime()`
-- @param #number SuppressionEndTime Model end time of the suppression from `timer.getTime()`
--- On After "SeadSuppressionStart" event. Mantis has switched off a site to defend a SEAD attack.
-- @function [parent=#MANTIS] OnAfterSeadSuppressionStart
-- @param #MANTIS self
-- @param #string From The From State
-- @param #string Event The Event
-- @param #string To The To State
-- @param Wrapper.Group#GROUP Group The suppressed GROUP object
-- @param #string Name Name of the suppressed groupe
--- On After "SeadSuppressionEnd" event. Mantis has switched on a site after a SEAD attack.
-- @function [parent=#MANTIS] OnAfterSeadSuppressionEnd
-- @param #MANTIS self
-- @param #string From The From State
-- @param #string Event The Event
-- @param #string To The To State
-- @param Wrapper.Group#GROUP Group The suppressed GROUP object
-- @param #string Name Name of the suppressed group
return self return self
end end
@@ -625,7 +682,7 @@ do
return self return self
end end
--- Set using an #INTEL_DLINK object instead of #DETECTION. Requires Develop branch of Moose.lua. --- Set using an #INTEL_DLINK object instead of #DETECTION
-- @param #MANTIS self -- @param #MANTIS self
-- @param Ops.Intelligence#INTEL_DLINK DLink The data link object to be used. -- @param Ops.Intelligence#INTEL_DLINK DLink The data link object to be used.
function MANTIS:SetUsingDLink(DLink) function MANTIS:SetUsingDLink(DLink)
@@ -891,6 +948,7 @@ do
local group = _group -- Wrapper.Group#GROUP local group = _group -- Wrapper.Group#GROUP
-- TODO: add emissions on/off -- TODO: add emissions on/off
if self.UseEmOnOff then if self.UseEmOnOff then
group:OptionAlarmStateRed()
group:EnableEmission(false) group:EnableEmission(false)
--group:SetAIOff() --group:SetAIOff()
else else
@@ -909,6 +967,10 @@ do
-- make SAMs evasive -- make SAMs evasive
local mysead = SEAD:New( SEAD_Grps, self.Padding ) -- Functional.Sead#SEAD local mysead = SEAD:New( SEAD_Grps, self.Padding ) -- Functional.Sead#SEAD
mysead:SetEngagementRange(engagerange) mysead:SetEngagementRange(engagerange)
mysead:AddCallBack(self)
if self.UseEmOnOff then
mysead:SwitchEmissions(true)
end
self.mysead = mysead self.mysead = mysead
return self return self
end end
@@ -995,22 +1057,24 @@ do
local name = _data[1] local name = _data[1]
local samgroup = GROUP:FindByName(name) local samgroup = GROUP:FindByName(name)
local IsInZone, Distance = self:CheckObjectInZone(detset, samcoordinate) local IsInZone, Distance = self:CheckObjectInZone(detset, samcoordinate)
if IsInZone then --check any target in zone local suppressed = self.SuppressedGroups[name] or false
if IsInZone then --check any target in zone and not curr managed by SEAD
if samgroup:IsAlive() then if samgroup:IsAlive() then
-- switch on SAM -- switch on SAM
if self.UseEmOnOff then if self.UseEmOnOff and not suppressed then
-- TODO: add emissions on/off -- DONE: add emissions on/off
--samgroup:SetAIOn() --samgroup:SetAIOn()
samgroup:EnableEmission(true) samgroup:EnableEmission(true)
end elseif not self.UseEmOnOff and not suppressed then
samgroup:OptionAlarmStateRed() samgroup:OptionAlarmStateRed()
if self.SamStateTracker[name] ~= "RED" then end
if self.SamStateTracker[name] ~= "RED" and not suppressed then
self:__RedState(1,samgroup) self:__RedState(1,samgroup)
self.SamStateTracker[name] = "RED" self.SamStateTracker[name] = "RED"
end end
-- link in to SHORAD if available -- link in to SHORAD if available
-- DONE: Test integration fully -- DONE: Test integration fully
if self.ShoradLink and Distance < self.ShoradActDistance then -- don't give SHORAD position away too early if self.ShoradLink and (Distance < self.ShoradActDistance or suppressed) then -- don't give SHORAD position away too early
local Shorad = self.Shorad local Shorad = self.Shorad
local radius = self.checkradius local radius = self.checkradius
local ontime = self.ShoradTime local ontime = self.ShoradTime
@@ -1018,7 +1082,7 @@ do
self:__ShoradActivated(1,name, radius, ontime) self:__ShoradActivated(1,name, radius, ontime)
end end
-- debug output -- debug output
if self.debug or self.verbose then if self.debug or self.verbose and not suppressed then
local text = string.format("SAM %s switched to alarm state RED!", name) local text = string.format("SAM %s switched to alarm state RED!", name)
local m=MESSAGE:New(text,10,"MANTIS"):ToAllIf(self.debug) local m=MESSAGE:New(text,10,"MANTIS"):ToAllIf(self.debug)
if self.verbose then self:I(self.lid..text) end if self.verbose then self:I(self.lid..text) end
@@ -1027,15 +1091,16 @@ do
else else
if samgroup:IsAlive() then if samgroup:IsAlive() then
-- switch off SAM -- switch off SAM
if self.UseEmOnOff then if self.UseEmOnOff and not suppressed then
samgroup:EnableEmission(false) samgroup:EnableEmission(false)
end elseif not self.UseEmOnOff and not suppressed then
samgroup:OptionAlarmStateGreen() samgroup:OptionAlarmStateGreen()
if self.SamStateTracker[name] ~= "GREEN" then end
if self.SamStateTracker[name] ~= "GREEN" and not suppressed then
self:__GreenState(1,samgroup) self:__GreenState(1,samgroup)
self.SamStateTracker[name] = "GREEN" self.SamStateTracker[name] = "GREEN"
end end
if self.debug or self.verbose then if self.debug or self.verbose and not suppressed then
local text = string.format("SAM %s switched to alarm state GREEN!", name) local text = string.format("SAM %s switched to alarm state GREEN!", name)
local m=MESSAGE:New(text,10,"MANTIS"):ToAllIf(self.debug) local m=MESSAGE:New(text,10,"MANTIS"):ToAllIf(self.debug)
if self.verbose then self:I(self.lid..text) end if self.verbose then self:I(self.lid..text) end
@@ -1264,6 +1329,47 @@ do
self:T({From, Event, To, Name, Radius, Ontime}) self:T({From, Event, To, Name, Radius, Ontime})
return self return self
end end
--- [Internal] Function triggered by Event SeadSuppressionStart
-- @param #MANTIS self
-- @param #string From The From State
-- @param #string Event The Event
-- @param #string To The To State
-- @param Wrapper.Group#GROUP Group The suppressed GROUP object
-- @param #string Name Name of the suppressed group
function MANTIS:onafterSeadSuppressionStart(From, Event, To, Group, Name)
self:T({From, Event, To, Name})
self.SuppressedGroups[Name] = true
return self
end
--- [Internal] Function triggered by Event SeadSuppressionEnd
-- @param #MANTIS self
-- @param #string From The From State
-- @param #string Event The Event
-- @param #string To The To State
-- @param Wrapper.Group#GROUP Group The suppressed GROUP object
-- @param #string Name Name of the suppressed group
function MANTIS:onafterSeadSuppressionEnd(From, Event, To, Group, Name)
self:T({From, Event, To, Name})
self.SuppressedGroups[Name] = false
return self
end
--- [Internal] Function triggered by Event SeadSuppressionPlanned
-- @param #MANTIS self
-- @param #string From The From State
-- @param #string Event The Event
-- @param #string To The To State
-- @param Wrapper.Group#GROUP Group The suppressed GROUP object
-- @param #string Name Name of the suppressed group
-- @param #number SuppressionStartTime Model start time of the suppression from `timer.getTime()`
-- @param #number SuppressionEndTime Model end time of the suppression from `timer.getTime()`
function MANTIS:onafterSeadSuppressionPlanned(From, Event, To, Group, Name, SuppressionStartTime, SuppressionEndTime)
self:T({From, Event, To, Name})
return self
end
end end
----------------------------------------------------------------------- -----------------------------------------------------------------------
-- MANTIS end -- MANTIS end

View File

@@ -742,7 +742,7 @@ function PSEUDOATC:ReportWeather(GID, UID, position, location)
local T=position:GetTemperature() local T=position:GetTemperature()
-- Correct unit system. -- Correct unit system.
local _T=string.format('%d°F', UTILS.CelciusToFarenheit(T)) local _T=string.format('%d°F', UTILS.CelsiusToFahrenheit(T))
if settings:IsMetric() then if settings:IsMetric() then
_T=string.format('%d°C', T) _T=string.format('%d°C', T)
end end

View File

@@ -19,7 +19,7 @@
-- * Bomb, rocket and missile impact points can be marked by smoke. -- * Bomb, rocket and missile impact points can be marked by smoke.
-- * Direct hits on targets can trigger flares. -- * Direct hits on targets can trigger flares.
-- * Smoke and flare colors can be adjusted for each player via radio menu. -- * Smoke and flare colors can be adjusted for each player via radio menu.
-- * Range information and weather report at the range can be reported via radio menu. -- * Range information and weather at the range can be obtained via radio menu.
-- * Persistence: Bombing range results can be saved to disk and loaded the next time the mission is started. -- * Persistence: Bombing range results can be saved to disk and loaded the next time the mission is started.
-- * Range control voice overs (>40) for hit assessment. -- * Range control voice overs (>40) for hit assessment.
-- --
@@ -50,11 +50,10 @@
-- @module Functional.Range -- @module Functional.Range
-- @image Range.JPG -- @image Range.JPG
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- RANGE class --- RANGE class
-- @type RANGE -- @type RANGE
-- @field #string ClassName Name of the Class. -- @field #string ClassName Name of the Class.
-- @field #boolean Debug If true, debug info is send as messages on the screen. -- @field #boolean Debug If true, debug info is sent as messages on the screen.
-- @field #boolean verbose Verbosity level. Higher means more output to DCS log file. -- @field #boolean verbose Verbosity level. Higher means more output to DCS log file.
-- @field #string id String id of range for output in DCS log. -- @field #string id String id of range for output in DCS log.
-- @field #string rangename Name of the range. -- @field #string rangename Name of the range.
@@ -77,13 +76,13 @@
-- @field #number Tmsg Time [sec] messages to players are displayed. Default 30 sec. -- @field #number Tmsg Time [sec] messages to players are displayed. Default 30 sec.
-- @field #string examinergroupname Name of the examiner group which should get all messages. -- @field #string examinergroupname Name of the examiner group which should get all messages.
-- @field #boolean examinerexclusive If true, only the examiner gets messages. If false, clients and examiner get messages. -- @field #boolean examinerexclusive If true, only the examiner gets messages. If false, clients and examiner get messages.
-- @field #number strafemaxalt Maximum altitude above ground for registering for a strafe run. Default is 914 m = 3000 ft. -- @field #number strafemaxalt Maximum altitude in meters AGL for registering for a strafe run. Default is 914 m = 3000 ft.
-- @field #number ndisplayresult Number of (player) results that a displayed. Default is 10. -- @field #number ndisplayresult Number of (player) results that a displayed. Default is 10.
-- @field Utilities.Utils#SMOKECOLOR BombSmokeColor Color id used for smoking bomb targets. -- @field Utilities.Utils#SMOKECOLOR BombSmokeColor Color id used for smoking bomb targets.
-- @field Utilities.Utils#SMOKECOLOR StrafeSmokeColor Color id used to smoke strafe targets. -- @field Utilities.Utils#SMOKECOLOR StrafeSmokeColor Color id used to smoke strafe targets.
-- @field Utilities.Utils#SMOKECOLOR StrafePitSmokeColor Color id used to smoke strafe pit approach boxes. -- @field Utilities.Utils#SMOKECOLOR StrafePitSmokeColor Color id used to smoke strafe pit approach boxes.
-- @field #number illuminationminalt Minimum altitude AGL in meters at which illumination bombs are fired. Default is 500 m. -- @field #number illuminationminalt Minimum altitude in meters AGL at which illumination bombs are fired. Default is 500 m.
-- @field #number illuminationmaxalt Maximum altitude AGL in meters at which illumination bombs are fired. Default is 1000 m. -- @field #number illuminationmaxalt Maximum altitude in meters AGL at which illumination bombs are fired. Default is 1000 m.
-- @field #number scorebombdistance Distance from closest target up to which bomb hits are counted. Default 1000 m. -- @field #number scorebombdistance Distance from closest target up to which bomb hits are counted. Default 1000 m.
-- @field #number TdelaySmoke Time delay in seconds between impact of bomb and starting the smoke. Default 3 seconds. -- @field #number TdelaySmoke Time delay in seconds between impact of bomb and starting the smoke. Default 3 seconds.
-- @field #boolean eventmoose If true, events are handled by MOOSE. If false, events are handled directly by DCS eventhandler. Default true. -- @field #boolean eventmoose If true, events are handled by MOOSE. If false, events are handled directly by DCS eventhandler. Default true.
@@ -92,9 +91,9 @@
-- @field #boolean trackmissiles If true (default), all missile types are tracked and impact point to closest bombing target is evaluated. -- @field #boolean trackmissiles If true (default), all missile types are tracked and impact point to closest bombing target is evaluated.
-- @field #boolean defaultsmokebomb If true, initialize player settings to smoke bomb. -- @field #boolean defaultsmokebomb If true, initialize player settings to smoke bomb.
-- @field #boolean autosave If true, automatically save results every X seconds. -- @field #boolean autosave If true, automatically save results every X seconds.
-- @field #number instructorfreq Frequency on which the range control transmitts. -- @field #number instructorfreq Frequency on which the range control transmits.
-- @field Sound.RadioQueue#RADIOQUEUE instructor Instructor radio queue. -- @field Sound.RadioQueue#RADIOQUEUE instructor Instructor radio queue.
-- @field #number rangecontrolfreq Frequency on which the range control transmitts. -- @field #number rangecontrolfreq Frequency on which the range control transmits.
-- @field Sound.RadioQueue#RADIOQUEUE rangecontrol Range control radio queue. -- @field Sound.RadioQueue#RADIOQUEUE rangecontrol Range control radio queue.
-- @field #string rangecontrolrelayname Name of relay unit. -- @field #string rangecontrolrelayname Name of relay unit.
-- @field #string instructorrelayname Name of relay unit. -- @field #string instructorrelayname Name of relay unit.
@@ -122,7 +121,7 @@
-- --
-- Due to a DCS bug, it is not possible to directly monitor when a player enters a plane. So in a mission with client slots, it is vital that -- Due to a DCS bug, it is not possible to directly monitor when a player enters a plane. So in a mission with client slots, it is vital that
-- a player first enters as spectator or hits ESC twice and **after that** jumps into the slot of his aircraft! -- a player first enters as spectator or hits ESC twice and **after that** jumps into the slot of his aircraft!
-- If that is not done, the script is not started correctly. This can be checked by looking at the radio menues. If the mission was entered correctly, -- If that is not done, the script is not started correctly. This can be checked by looking at the radio menus. If the mission was entered correctly,
-- there should be an "On the Range" menu items in the "F10. Other..." menu. -- there should be an "On the Range" menu items in the "F10. Other..." menu.
-- --
-- # Strafe Pits -- # Strafe Pits
@@ -131,12 +130,12 @@
-- --
-- A strafe pit can be added to the range by the @{#RANGE.AddStrafePit}(*targetnames, boxlength, boxwidth, heading, inverseheading, goodpass, foulline*) function. -- A strafe pit can be added to the range by the @{#RANGE.AddStrafePit}(*targetnames, boxlength, boxwidth, heading, inverseheading, goodpass, foulline*) function.
-- --
-- * The first parameter *targetnames* defines the target or targets. This has to be given as a lua table which contains the names of @{Wrapper.Unit} or @{Static} objects defined in the mission editor. -- * The first parameter *targetnames* defines the target or targets. This can be a single item or a Table with the name(s) of @{Wrapper.Unit} or @{Static} objects defined in the mission editor.
-- * In order to perform a valid pass on the strafe pit, the pilot has to begin his run from the correct direction. Therefore, an "approach box" is defined in front -- * In order to perform a valid pass on the strafe pit, the pilot has to begin his run from the correct direction. Therefore, an "approach box" is defined in front
-- of the strafe targets. The parameters *boxlength* and *boxwidth* define the size of the box while the parameter *heading* defines its direction. -- of the strafe targets. The parameters *boxlength* and *boxwidth* define the size of the box in meters, while the *heading* parameter defines the heading of the box FROM the target.
-- If the parameter *heading* is passed as **nil**, the heading is automatically taken from the heading of the first target unit as defined in the ME. -- For example, if heading 120 is set, the approach box will start FROM the target and extend outwards on heading 120. A strafe run approach must then be flown apx. heading 300 TOWARDS the target.
-- The parameter *inverseheading* turns the heading around by 180 degrees. This is sometimes useful, since the default heading of strafe target units point in the -- If the parameter *heading* is passed as **nil**, the heading is automatically taken from the heading set in the ME for the first target unit.
-- wrong/opposite direction. -- * The parameter *inverseheading* turns the heading around by 180 degrees. This is useful when the default heading of strafe target units point in the wrong/opposite direction.
-- * The parameter *goodpass* defines the number of hits a pilot has to achieve during a run to be judged as a "good" pass. -- * The parameter *goodpass* defines the number of hits a pilot has to achieve during a run to be judged as a "good" pass.
-- * The last parameter *foulline* sets the distance from the pit targets to the foul line. Hit from closer than this line are not counted! -- * The last parameter *foulline* sets the distance from the pit targets to the foul line. Hit from closer than this line are not counted!
-- --
@@ -150,10 +149,9 @@
-- --
-- One ore multiple bombing targets can be added to the range by the @{#RANGE.AddBombingTargets}(targetnames, goodhitrange, randommove) function. -- One ore multiple bombing targets can be added to the range by the @{#RANGE.AddBombingTargets}(targetnames, goodhitrange, randommove) function.
-- --
-- * The first parameter *targetnames* has to be a lua table, which contains the names of @{Wrapper.Unit} and/or @{Static} objects defined in the mission editor. -- * The first parameter *targetnames* defines the target or targets. This can be a single item or a Table with the name(s) of @{Wrapper.Unit} or @{Static} objects defined in the mission editor.
-- Note that the @{Range} logic **automatically** determines, if a name belongs to a @{Wrapper.Unit} or @{Static} object now. -- * The (optional) parameter *goodhitrange* specifies the radius in metres around the target within which a bomb/rocket hit is considered to be "good".
-- * The (optional) parameter *goodhitrange* specifies the radius around the target. If a bomb or rocket falls at a distance smaller than this number, the hit is considered to be "good". -- * If final (optional) parameter *randommove* can be enabled to create moving targets. If this parameter is set to true, the units of this bombing target will randomly move within the range zone.
-- * If final (optional) parameter "*randommove*" can be enabled to create moving targets. If this parameter is set to true, the units of this bombing target will randomly move within the range zone.
-- Note that there might be quirks since DCS units can get stuck in buildings etc. So it might be safer to manually define a route for the units in the mission editor if moving targets are desired. -- Note that there might be quirks since DCS units can get stuck in buildings etc. So it might be safer to manually define a route for the units in the mission editor if moving targets are desired.
-- --
-- ## Adding Groups -- ## Adding Groups
@@ -188,7 +186,7 @@
-- --
-- The main range menu can be found at "F10. Other..." --> "F*X*. On the Range..." --> "F1. <Range Name>...". -- The main range menu can be found at "F10. Other..." --> "F*X*. On the Range..." --> "F1. <Range Name>...".
-- --
-- The range menu contains the following submenues: -- The range menu contains the following submenus:
-- --
-- ![Banner Image](..\Presentations\RANGE\Menu_Main.png) -- ![Banner Image](..\Presentations\RANGE\Menu_Main.png)
-- --
@@ -255,14 +253,14 @@
-- -- Note that this could also be done manually by simply measuring the distance between the target and the foul line in the ME. -- -- Note that this could also be done manually by simply measuring the distance between the target and the foul line in the ME.
-- GoldwaterRange:GetFoullineDistance("GWR Strafe Pit Left 1", "GWR Foul Line Left") -- GoldwaterRange:GetFoullineDistance("GWR Strafe Pit Left 1", "GWR Foul Line Left")
-- --
-- -- Add strafe pits. Each pit (left and right) consists of two targets. -- -- Add strafe pits. Each pit (left and right) consists of two targets. Where "nil" is used as input, the default value is used.
-- GoldwaterRange:AddStrafePit(strafepit_left, 3000, 300, nil, true, 20, fouldist) -- GoldwaterRange:AddStrafePit(strafepit_left, 3000, 300, nil, true, 30, 500)
-- GoldwaterRange:AddStrafePit(strafepit_right, nil, nil, nil, true, nil, fouldist) -- GoldwaterRange:AddStrafePit(strafepit_right, nil, nil, nil, true, nil, 500)
-- --
-- -- Add bombing targets. A good hit is if the bomb falls less then 50 m from the target. -- -- Add bombing targets. A good hit is if the bomb falls less then 50 m from the target.
-- GoldwaterRange:AddBombingTargets(bombtargets, 50) -- GoldwaterRange:AddBombingTargets(bombtargets, 50)
-- --
-- -- Start range. -- -- Start Range.
-- GoldwaterRange:Start() -- GoldwaterRange:Start()
-- --
-- The [476th - Air Weapons Range Objects mod](http://www.476vfightergroup.com/downloads.php?do=file&id=287) is (implicitly) used in this example. -- The [476th - Air Weapons Range Objects mod](http://www.476vfightergroup.com/downloads.php?do=file&id=287) is (implicitly) used in this example.
@@ -286,8 +284,6 @@
-- Note that it can happen that the RANGE radio menu is not shown. Check that the range object is defined as a **global** variable rather than a local one. -- Note that it can happen that the RANGE radio menu is not shown. Check that the range object is defined as a **global** variable rather than a local one.
-- The could avoid the lua garbage collection to accidentally/falsely deallocate the RANGE objects. -- The could avoid the lua garbage collection to accidentally/falsely deallocate the RANGE objects.
-- --
--
--
-- @field #RANGE -- @field #RANGE
RANGE = { RANGE = {
ClassName = "RANGE", ClassName = "RANGE",
@@ -333,24 +329,23 @@ RANGE={
instructor = nil, instructor = nil,
rangecontrolfreq = nil, rangecontrolfreq = nil,
rangecontrol = nil, rangecontrol = nil,
soundpath = "Range Soundfiles/" soundpath = "Range Soundfiles/",
} }
--- Default range parameters. --- Default range parameters.
-- @list Defaults -- @list Defaults
RANGE.Defaults = { RANGE.Defaults = {
goodhitrange=25, goodhitrange = 25, -- meters
strafemaxalt=914, strafemaxalt = 914, -- meters AGL
dtBombtrack=0.005, dtBombtrack = 0.005, -- seconds
Tmsg=30, Tmsg = 30, -- seconds
ndisplayresult = 10, ndisplayresult = 10,
rangeradius=5000, rangeradius = 5000, -- meters
TdelaySmoke=3.0, TdelaySmoke = 3.0, -- seconds
boxlength=3000, boxlength = 3000, -- meters
boxwidth=300, boxwidth = 300, -- meters
goodpass=20, goodpass = 20, -- targethits per pass
goodhitrange=25, foulline = 610, -- meters
foulline=610,
} }
--- Target type, i.e. unit, static, or coordinate. --- Target type, i.e. unit, static, or coordinate.
@@ -833,7 +828,7 @@ end
--- Set maximal strafing altitude. Player entering a strafe pit above that altitude are not registered for a valid pass. --- Set maximal strafing altitude. Player entering a strafe pit above that altitude are not registered for a valid pass.
-- @param #RANGE self -- @param #RANGE self
-- @param #number maxalt Maximum altitude AGL in meters. Default is 914 m= 3000 ft. -- @param #number maxalt Maximum altitude in meters AGL. Default is 914 m = 3000 ft.
-- @return #RANGE self -- @return #RANGE self
function RANGE:SetMaxStrafeAlt( maxalt ) function RANGE:SetMaxStrafeAlt( maxalt )
self.strafemaxalt = maxalt or RANGE.Defaults.strafemaxalt self.strafemaxalt = maxalt or RANGE.Defaults.strafemaxalt
@@ -905,10 +900,10 @@ end
--- Set player setting whether bomb impact points are smoked or not. --- Set player setting whether bomb impact points are smoked or not.
-- @param #RANGE self -- @param #RANGE self
-- @param #boolean switch If true nor nil default is to smoke impact points of bombs. -- @param #boolean switch (Optional) If true, impact points of bombs will be smoked. Default is true.
-- @return #RANGE self -- @return #RANGE self
function RANGE:SetDefaultPlayerSmokeBomb( switch ) function RANGE:SetDefaultPlayerSmokeBomb( switch )
if switch==true or switch==nil then if switch == nil or switch == true then
self.defaultsmokebomb = true self.defaultsmokebomb = true
else else
self.defaultsmokebomb = false self.defaultsmokebomb = false
@@ -1022,7 +1017,6 @@ function RANGE:SetMessagesON()
return self return self
end end
--- Enables tracking of all bomb types. Note that this is the default setting. --- Enables tracking of all bomb types. Note that this is the default setting.
-- @param #RANGE self -- @param #RANGE self
-- @return #RANGE self -- @return #RANGE self
@@ -1071,7 +1065,6 @@ function RANGE:TrackMissilesOFF()
return self return self
end end
--- Enable range control and set frequency. --- Enable range control and set frequency.
-- @param #RANGE self -- @param #RANGE self
-- @param #number frequency Frequency in MHz. Default 256 MHz. -- @param #number frequency Frequency in MHz. Default 256 MHz.
@@ -1096,7 +1089,7 @@ end
--- Set sound files folder within miz file. --- Set sound files folder within miz file.
-- @param #RANGE self -- @param #RANGE self
-- @param #string path Path for sound files. Default "ATIS Soundfiles/". Mind the slash "/" at the end! -- @param #string path Path for sound files. Default "Range Soundfiles/". Mind the slash "/" at the end!
-- @return #RANGE self -- @return #RANGE self
function RANGE:SetSoundfilesPath( path ) function RANGE:SetSoundfilesPath( path )
self.soundpath = tostring( path or "Range Soundfiles/" ) self.soundpath = tostring( path or "Range Soundfiles/" )
@@ -1105,16 +1098,16 @@ function RANGE:SetSoundfilesPath(path)
end end
--- Add new strafe pit. For a strafe pit, hits from guns are counted. One pit can consist of several units. --- Add new strafe pit. For a strafe pit, hits from guns are counted. One pit can consist of several units.
-- Note, an approach is only valid, if the player enters via a zone in front of the pit, which defined by boxlength and boxheading. -- A strafe run approach is only valid if the player enters via a zone in front of the pit, which is defined by boxlength, boxwidth, and heading.
-- Furthermore, the player must not be too high and fly in the direction of the pit to make a valid target apporoach. -- Furthermore, the player must not be too high and fly in the direction of the pit to make a valid target apporoach.
-- @param #RANGE self -- @param #RANGE self
-- @param #table targetnames Table of unit or static names defining the strafe targets. The first target in the list determines the approach zone (heading and box). -- @param #table targetnames Single or multiple (Table) unit or static names defining the strafe targets. The first target in the list determines the approach box origin (heading and box).
-- @param #number boxlength (Optional) Length of the approach box in meters. Default is 3000 m. -- @param #number boxlength (Optional) Length of the approach box in meters. Default is 3000 m.
-- @param #number boxwidth (Optional) Width of the approach box in meters. Default is 300 m. -- @param #number boxwidth (Optional) Width of the approach box in meters. Default is 300 m.
-- @param #number heading (Optional) Approach heading in Degrees. Default is heading of the unit as defined in the mission editor. -- @param #number heading (Optional) Approach box heading in degrees (originating FROM the target). Default is the heading set in the ME for the first target unit
-- @param #boolean inverseheading (Optional) Take inverse heading (heading --> heading - 180 Degrees). Default is false. -- @param #boolean inverseheading (Optional) Use inverse heading (heading --> heading - 180 Degrees). Default is false.
-- @param #number goodpass (Optional) Number of hits for a "good" strafing pass. Default is 20. -- @param #number goodpass (Optional) Number of hits for a "good" strafing pass. Default is 20.
-- @param #number foulline (Optional) Foul line distance. Hits from closer than this distance are not counted. Default 610 m = 2000 ft. Set to 0 for no foul line. -- @param #number foulline (Optional) Foul line distance. Hits from closer than this distance are not counted. Default is 610 m = 2000 ft. Set to 0 for no foul line.
-- @return #RANGE self -- @return #RANGE self
function RANGE:AddStrafePit( targetnames, boxlength, boxwidth, heading, inverseheading, goodpass, foulline ) function RANGE:AddStrafePit( targetnames, boxlength, boxwidth, heading, inverseheading, goodpass, foulline )
self:F( { targetnames = targetnames, boxlength = boxlength, boxwidth = boxwidth, heading = heading, inverseheading = inverseheading, goodpass = goodpass, foulline = foulline } ) self:F( { targetnames = targetnames, boxlength = boxlength, boxwidth = boxwidth, heading = heading, inverseheading = inverseheading, goodpass = goodpass, foulline = foulline } )
@@ -1190,7 +1183,7 @@ function RANGE:AddStrafePit(targetnames, boxlength, boxwidth, heading, inversehe
if heading < 0 then if heading < 0 then
heading = heading + 360 heading = heading + 360
end end
if heading>360 then if heading >= 360 then
heading = heading - 360 heading = heading - 360
end end
@@ -1244,7 +1237,6 @@ function RANGE:AddStrafePit(targetnames, boxlength, boxwidth, heading, inversehe
return self return self
end end
--- Add all units of a group as one new strafe target pit. --- Add all units of a group as one new strafe target pit.
-- For a strafe pit, hits from guns are counted. One pit can consist of several units. -- For a strafe pit, hits from guns are counted. One pit can consist of several units.
-- Note, an approach is only valid, if the player enters via a zone in front of the pit, which defined by boxlength and boxheading. -- Note, an approach is only valid, if the player enters via a zone in front of the pit, which defined by boxlength and boxheading.
@@ -1254,7 +1246,7 @@ end
-- @param #number boxlength (Optional) Length of the approach box in meters. Default is 3000 m. -- @param #number boxlength (Optional) Length of the approach box in meters. Default is 3000 m.
-- @param #number boxwidth (Optional) Width of the approach box in meters. Default is 300 m. -- @param #number boxwidth (Optional) Width of the approach box in meters. Default is 300 m.
-- @param #number heading (Optional) Approach heading in Degrees. Default is heading of the unit as defined in the mission editor. -- @param #number heading (Optional) Approach heading in Degrees. Default is heading of the unit as defined in the mission editor.
-- @param #boolean inverseheading (Optional) Take inverse heading (heading --> heading - 180 Degrees). Default is false. -- @param #boolean inverseheading (Optional) Use inverse heading (heading --> heading - 180 Degrees). Default is false.
-- @param #number goodpass (Optional) Number of hits for a "good" strafing pass. Default is 20. -- @param #number goodpass (Optional) Number of hits for a "good" strafing pass. Default is 20.
-- @param #number foulline (Optional) Foul line distance. Hits from closer than this distance are not counted. Default 610 m = 2000 ft. Set to 0 for no foul line. -- @param #number foulline (Optional) Foul line distance. Hits from closer than this distance are not counted. Default 610 m = 2000 ft. Set to 0 for no foul line.
-- @return #RANGE self -- @return #RANGE self
@@ -1288,9 +1280,9 @@ end
--- Add bombing target(s) to range. --- Add bombing target(s) to range.
-- @param #RANGE self -- @param #RANGE self
-- @param #table targetnames Table containing names of unit or static objects serving as bomb targets. -- @param #table targetnames Single or multiple (Table) names of unit or static objects serving as bomb targets.
-- @param #number goodhitrange (Optional) Max distance from target unit (in meters) which is considered as a good hit. Default is 25 m. -- @param #number goodhitrange (Optional) Max hit distance from target unit in meters which is considered as a good hit. Default is 25 m.
-- @param #boolean randommove If true, unit will move randomly within the range. Default is false. -- @param #boolean randommove (Optional) If true, unit will move randomly within the range. Default is false.
-- @return #RANGE self -- @return #RANGE self
function RANGE:AddBombingTargets( targetnames, goodhitrange, randommove ) function RANGE:AddBombingTargets( targetnames, goodhitrange, randommove )
self:F( { targetnames = targetnames, goodhitrange = goodhitrange, randommove = randommove } ) self:F( { targetnames = targetnames, goodhitrange = goodhitrange, randommove = randommove } )
@@ -1328,8 +1320,8 @@ end
--- Add a unit or static object as bombing target. --- Add a unit or static object as bombing target.
-- @param #RANGE self -- @param #RANGE self
-- @param Wrapper.Positionable#POSITIONABLE unit Positionable (unit or static) of the strafe target. -- @param Wrapper.Positionable#POSITIONABLE unit Positionable (unit or static) of the strafe target.
-- @param #number goodhitrange Max distance from unit which is considered as a good hit. -- @param #number goodhitrange (Optional) Max hit distance from target unit in meters which is considered as a good hit. Default is 25 m.
-- @param #boolean randommove If true, unit will move randomly within the range. Default is false. -- @param #boolean randommove (Optional) If true, unit will move randomly within the range. Default is false.
-- @return #RANGE self -- @return #RANGE self
function RANGE:AddBombingTargetUnit( unit, goodhitrange, randommove ) function RANGE:AddBombingTargetUnit( unit, goodhitrange, randommove )
self:F( { unit = unit, goodhitrange = goodhitrange, randommove = randommove } ) self:F( { unit = unit, goodhitrange = goodhitrange, randommove = randommove } )
@@ -1382,13 +1374,25 @@ function RANGE:AddBombingTargetUnit(unit, goodhitrange, randommove)
return self return self
end end
--- Add a coordinate of a bombing target.
--- Add a coordinate of a bombing target. This
-- @param #RANGE self -- @param #RANGE self
-- @param Core.Point#COORDINATE coord The coordinate. -- @param Core.Point#COORDINATE coord The coordinate.
-- @param #string name Name of target. -- @param #string name (Optional) Name of target. Default is "Bomb Target".
-- @param #number goodhitrange Max distance from unit which is considered as a good hit. -- @param #number goodhitrange (Optional) Max hit distance from target unit in meters which is considered as a good hit. Default is 25 m.
-- @return #RANGE self -- @return #RANGE self
-- @usage
--
-- -- Setup a Range
-- RangeOne = RANGE:New( "Range One" )
-- -- Find the STATIC target object as setup in the ME.
-- RangeOneBombTarget = STATIC:FindByName( "RangeOneBombTarget" )
-- -- Add the coordinate of the STATIC target object as a bomb target (thus keeping the bomb function active, even if the STATIC target is destroyed).
-- RangeOne:AddBombingTargetCoordinate( RangeOneBombTarget:GetCoordinate(), "RangeOneBombTarget", 50)
-- -- Or, add the coordinate of the STATIC target object as a bomb target using default values (name will be "Bomb Target", goodhitrange will be 25 m).
-- RangeOne:AddBombingTargetCoordinate( RangeOneBombTarget:GetCoordinate() )
-- -- Start Range.
-- RangeOne:Start()
--
function RANGE:AddBombingTargetCoordinate( coord, name, goodhitrange ) function RANGE:AddBombingTargetCoordinate( coord, name, goodhitrange )
local target = {} -- #RANGE.BombTarget local target = {} -- #RANGE.BombTarget
@@ -1409,8 +1413,8 @@ end
--- Add all units of a group as bombing targets. --- Add all units of a group as bombing targets.
-- @param #RANGE self -- @param #RANGE self
-- @param Wrapper.Group#GROUP group Group of bombing targets. -- @param Wrapper.Group#GROUP group Group of bombing targets.
-- @param #number goodhitrange Max distance from unit which is considered as a good hit. -- @param #number goodhitrange (Optional) Max hit distance from target unit in meters which is considered as a good hit. Default is 25 m.
-- @param #boolean randommove If true, unit will move randomly within the range. Default is false. -- @param #boolean randommove (Optional) If true, unit will move randomly within the range. Default is false.
-- @return #RANGE self -- @return #RANGE self
function RANGE:AddBombingTargetGroup( group, goodhitrange, randommove ) function RANGE:AddBombingTargetGroup( group, goodhitrange, randommove )
self:F( { group = group, goodhitrange = goodhitrange, randommove = randommove } ) self:F( { group = group, goodhitrange = goodhitrange, randommove = randommove } )
@@ -1429,11 +1433,22 @@ function RANGE:AddBombingTargetGroup(group, goodhitrange, randommove)
return self return self
end end
--- Measures the foule line distance between two unit or static objects. --- Returns the foul line distance between strafe pit target and a foul line distance marker object.
-- @param #RANGE self -- @param #RANGE self
-- @param #string namepit Name of the strafe pit target object. -- @param #string namepit Name of the strafe pit target object.
-- @param #string namefoulline Name of the fould line distance marker object. -- @param #string namefoulline Name of the foul line distance marker object.
-- @return #number Foul line distance in meters. -- @return #number Foul line distance in meters.
-- @usage
--
-- -- Setup a Range
-- RangeOne = RANGE:New( "Range One" )
-- -- Get distance between strafe target objext and foul line distance marker object.
-- RangeOneFoulDistance = RangeOne:GetFoullineDistance( "RangeOneStrafeTarget" , "RangeOneFoulLineObject" )
-- -- Add a strafe pit using the measured foul line distance. Where nil is used, strafe pit default values will be used - adjust as required.
-- RangeOne:AddStrafePit( "RangeOneStrafeTarget", nil, nil, nil, nil, nil, RangeOneFoulDistance )
-- -- Start Range.
-- RangeOne:Start()
--
function RANGE:GetFoullineDistance( namepit, namefoulline ) function RANGE:GetFoullineDistance( namepit, namefoulline )
self:F( { namepit = namepit, namefoulline = namefoulline } ) self:F( { namepit = namepit, namefoulline = namefoulline } )
@@ -1544,7 +1559,6 @@ function RANGE:onEvent(Event)
end end
--- Range event handler for event birth. --- Range event handler for event birth.
-- @param #RANGE self -- @param #RANGE self
-- @param Core.Event#EVENTDATA EventData -- @param Core.Event#EVENTDATA EventData
@@ -1559,7 +1573,6 @@ function RANGE:OnEventBirth(EventData)
self:T3( self.id .. "BIRTH: player = " .. tostring( _playername ) ) self:T3( self.id .. "BIRTH: player = " .. tostring( _playername ) )
if _unit and _playername then if _unit and _playername then
local _uid = _unit:GetID() local _uid = _unit:GetID()
local _group = _unit:GetGroup() local _group = _unit:GetGroup()
local _gid = _group:GetID() local _gid = _group:GetID()
@@ -1596,8 +1609,8 @@ function RANGE:OnEventBirth(EventData)
self.timerCheckZone = TIMER:New( self._CheckInZone, self, EventData.IniUnitName ):Start( 1, 1 ) self.timerCheckZone = TIMER:New( self._CheckInZone, self, EventData.IniUnitName ):Start( 1, 1 )
self.planes[_uid] = true self.planes[_uid] = true
end end
end end
end end
--- Range event handler for event hit. --- Range event handler for event hit.
@@ -1688,6 +1701,7 @@ function RANGE:OnEventHit(EventData)
end end
end end
end end
end end
--- Range event handler for event shot (when a unit releases a rocket or bomb (but not a fast firing gun). --- Range event handler for event shot (when a unit releases a rocket or bomb (but not a fast firing gun).
@@ -1748,7 +1762,6 @@ function RANGE:OnEventShot(EventData)
-- Only track if distance player to range is < 25 km. Also check that a player shot. No need to track AI weapons. -- Only track if distance player to range is < 25 km. Also check that a player shot. No need to track AI weapons.
if _track and dPR <= self.BombtrackThreshold and _unit and _playername then if _track and dPR <= self.BombtrackThreshold and _unit and _playername then
-- Player data. -- Player data.
local playerData = self.PlayerSettings[_playername] -- #RANGE.PlayerData local playerData = self.PlayerSettings[_playername] -- #RANGE.PlayerData
@@ -1762,8 +1775,7 @@ function RANGE:OnEventShot(EventData)
local function trackBomb( _ordnance ) local function trackBomb( _ordnance )
-- When the pcall returns a failure the weapon has hit. -- When the pcall returns a failure the weapon has hit.
local _status,_bombPos = pcall( local _status, _bombPos = pcall( function()
function()
return _ordnance:getPoint() return _ordnance:getPoint()
end ) end )
@@ -1940,7 +1952,6 @@ function RANGE:onafterStatus(From, Event, To)
text = text .. string.format( ", Control %.3f MHz (Relay=%s alive=%s)", self.rangecontrolfreq, tostring( self.rangecontrolrelayname ), alive ) text = text .. string.format( ", Control %.3f MHz (Relay=%s alive=%s)", self.rangecontrolfreq, tostring( self.rangecontrolrelayname ), alive )
end end
-- Check range status. -- Check range status.
self:I( self.id .. text ) self:I( self.id .. text )
@@ -1992,7 +2003,6 @@ function RANGE:onafterExitRange(From, Event, To, player)
end end
--- Function called after bomb impact on range. --- Function called after bomb impact on range.
-- @param #RANGE self -- @param #RANGE self
-- @param #string From From state. -- @param #string From From state.
@@ -2002,16 +2012,11 @@ end
-- @param #RANGE.PlayerData player Player data table. -- @param #RANGE.PlayerData player Player data table.
function RANGE:onafterImpact( From, Event, To, result, player ) function RANGE:onafterImpact( From, Event, To, result, player )
-- Only display target name if there is more than one bomb target.
local targetname=nil
if #self.bombingTargets>1 then
local targetname=result.name
end
-- Send message to player. -- Send message to player.
local text=string.format("%s, impact %03d° for %d ft", player.playername, result.radial, UTILS.MetersToFeet(result.distance)) local text = string.format( "%s, impact %03d° for %d m (%d ft)", player.playername, result.radial, result.distance, UTILS.MetersToFeet( result.distance ) )
if targetname then -- Only display target name if there is more than one bomb target.
text=text..string.format(" from bulls of target %s.") if #self.bombingTargets > 1 then
text = text .. string.format( " from bulls of target %s.", result.name )
else else
text = text .. "." text = text .. "."
end end
@@ -2115,7 +2120,7 @@ function RANGE:onafterSave(From, Event, To)
_savefile( filename, scores ) _savefile( filename, scores )
end end
--- Function called before save event. Checks that io and lfs are desanitized. --- Function called before load event. Checks that io and lfs are desanitized.
-- @param #RANGE self -- @param #RANGE self
-- @param #string From From state. -- @param #string From From state.
-- @param #string Event Event. -- @param #string Event Event.
@@ -2240,7 +2245,9 @@ function RANGE:_DisplayMyStrafePitResults(_unitName)
else else
-- Sort results table wrt number of hits. -- Sort results table wrt number of hits.
local _sort = function( a,b ) return a.hits > b.hits end local _sort = function( a, b )
return a.hits > b.hits
end
table.sort( _results, _sort ) table.sort( _results, _sort )
-- Prepare message of best results. -- Prepare message of best results.
@@ -2314,7 +2321,9 @@ function RANGE:_DisplayStrafePitResults(_unitName)
end end
-- Sort list! -- Sort list!
local _sort = function( a,b ) return a.hits > b.hits end local _sort = function( a, b )
return a.hits > b.hits
end
table.sort( _playerResults, _sort ) table.sort( _playerResults, _sort )
-- Add top 10 results. -- Add top 10 results.
@@ -2355,7 +2364,9 @@ function RANGE:_DisplayMyBombingResults(_unitName)
else else
-- Sort results wrt to distance. -- Sort results wrt to distance.
local _sort = function( a,b ) return a.distance < b.distance end local _sort = function( a, b )
return a.distance < b.distance
end
table.sort( _results, _sort ) table.sort( _results, _sort )
-- Loop over results. -- Loop over results.
@@ -2425,7 +2436,9 @@ function RANGE:_DisplayBombingResults(_unitName)
end end
-- Sort list of player results. -- Sort list of player results.
local _sort = function( a,b ) return a.distance < b.distance end local _sort = function( a, b )
return a.distance < b.distance
end
table.sort( _playerResults, _sort ) table.sort( _playerResults, _sort )
-- Loop over player results. -- Loop over player results.
@@ -2476,7 +2489,7 @@ function RANGE:_DisplayRangeInfo(_unitname)
local range = coord:Get2DDistance( position ) local range = coord:Get2DDistance( position )
-- Bearing string. -- Bearing string.
local Bs=string.format('%03d°', angle) local Bs = string.format( "%03d°", angle )
local texthit local texthit
if self.PlayerSettings[playername].flaredirecthits then if self.PlayerSettings[playername].flaredirecthits then
@@ -2614,7 +2627,6 @@ function RANGE:_DisplayStrafePits(_unitname)
end end
end end
--- Report weather conditions at range. Temperature, QFE pressure and wind data. --- Report weather conditions at range. Temperature, QFE pressure and wind data.
-- @param #RANGE self -- @param #RANGE self
-- @param #string _unitname Name of the player unit. -- @param #string _unitname Name of the player unit.
@@ -2644,7 +2656,7 @@ function RANGE:_DisplayRangeWeather(_unitname)
-- Get Beaufort wind scale. -- Get Beaufort wind scale.
local Bn, Bd = UTILS.BeaufortScale( Ws ) local Bn, Bd = UTILS.BeaufortScale( Ws )
local WD=string.format('%03d°', Wd) local WD = string.format( "%03d°", Wd )
local Ts = string.format( "%d°C", T ) local Ts = string.format( "%d°C", T )
local hPa2inHg = 0.0295299830714 local hPa2inHg = 0.0295299830714
@@ -2655,12 +2667,11 @@ function RANGE:_DisplayRangeWeather(_unitname)
local tW = string.format( "%.1f m/s", Ws ) local tW = string.format( "%.1f m/s", Ws )
local tP = string.format( "%.1f mmHg", P * hPa2mmHg ) local tP = string.format( "%.1f mmHg", P * hPa2mmHg )
if settings:IsImperial() then if settings:IsImperial() then
--tT=string.format("%d°F", UTILS.CelciusToFarenheit(T)) -- tT=string.format("%d°F", UTILS.CelsiusToFahrenheit(T))
tW = string.format( "%.1f knots", UTILS.MpsToKnots( Ws ) ) tW = string.format( "%.1f knots", UTILS.MpsToKnots( Ws ) )
tP = string.format( "%.2f inHg", P * hPa2inHg ) tP = string.format( "%.2f inHg", P * hPa2inHg )
end end
-- Message text. -- Message text.
text = text .. string.format( "Weather Report at %s:\n", self.rangename ) text = text .. string.format( "Weather Report at %s:\n", self.rangename )
text = text .. string.format( "--------------------------------------------------\n" ) text = text .. string.format( "--------------------------------------------------\n" )
@@ -2831,7 +2842,9 @@ function RANGE:_CheckInZone(_unitName)
local accur = 0 local accur = 0
if shots > 0 then if shots > 0 then
accur = _result.hits / shots * 100 accur = _result.hits / shots * 100
if accur > 100 then accur = 100 end if accur > 100 then
accur = 100
end
end end
-- Message text. -- Message text.
@@ -2962,7 +2975,6 @@ function RANGE:_AddF10Commands(_unitName)
end end
local _statsPath = missionCommands.addSubMenuForGroup( _gid, "Statistics", _rangePath ) local _statsPath = missionCommands.addSubMenuForGroup( _gid, "Statistics", _rangePath )
local _markPath = missionCommands.addSubMenuForGroup( _gid, "Mark Targets", _rangePath ) local _markPath = missionCommands.addSubMenuForGroup( _gid, "Mark Targets", _rangePath )
local _settingsPath = missionCommands.addSubMenuForGroup( _gid, "My Settings", _rangePath ) local _settingsPath = missionCommands.addSubMenuForGroup( _gid, "My Settings", _rangePath )
@@ -3019,7 +3031,7 @@ end
-- Helper Functions -- Helper Functions
----------------------------------------------------------------------------------------------------------------------------------------------------------------------- -----------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- Get the number of shells a unit currently has. --- Get the coordinate of a Bomb target.
-- @param #RANGE self -- @param #RANGE self
-- @param #RANGE.BombTarget target Bomb target data. -- @param #RANGE.BombTarget target Bomb target data.
-- @return Core.Point#COORDINATE Target coordinate. -- @return Core.Point#COORDINATE Target coordinate.
@@ -3056,7 +3068,6 @@ function RANGE:_GetBombTargetCoordinate(target)
return coord return coord
end end
--- Get the number of shells a unit currently has. --- Get the number of shells a unit currently has.
-- @param #RANGE self -- @param #RANGE self
-- @param #string unitname Name of the player unit. -- @param #string unitname Name of the player unit.
@@ -3496,7 +3507,7 @@ end
--- Checks if a static object with a certain name exists. It also added it to the MOOSE data base, if it is not already in there. --- Checks if a static object with a certain name exists. It also added it to the MOOSE data base, if it is not already in there.
-- @param #RANGE self -- @param #RANGE self
-- @param #string name Name of the potential static object. -- @param #string name Name of the potential static object.
-- @return #boolean Returns true if a static with this name exists. Retruns false if a unit with this name exists. Returns nil if neither unit or static exist. -- @return #boolean Returns true if a static with this name exists. Returns false if a unit with this name exists. Returns nil if neither unit or static exist.
function RANGE:_CheckStatic( name ) function RANGE:_CheckStatic( name )
self:F2( name ) self:F2( name )
@@ -3582,7 +3593,7 @@ function RANGE:_GetPlayerUnitAndName(_unitName)
return nil, nil return nil, nil
end end
--- Returns a string which consits of this callsign and the player name. --- Returns a string which consists of the player name.
-- @param #RANGE self -- @param #RANGE self
-- @param #string unitname Name of the player unit. -- @param #string unitname Name of the player unit.
function RANGE:_myname( unitname ) function RANGE:_myname( unitname )
@@ -3590,9 +3601,11 @@ function RANGE:_myname(unitname)
local unit = UNIT:FindByName( unitname ) local unit = UNIT:FindByName( unitname )
local pname = unit:GetPlayerName() local pname = unit:GetPlayerName()
local csign=unit:GetCallsign()
-- TODO: Either remove these leftovers, or implement them.
-- local csign=unit:GetCallsign()
-- return string.format("%s (%s)", csign, pname) -- return string.format("%s (%s)", csign, pname)
return string.format( "%s", pname ) return string.format( "%s", pname )
end end

View File

@@ -6,6 +6,8 @@
-- --
-- * When SAM sites are being fired upon, the SAMs will take evasive action will reposition themselves when possible. -- * When SAM sites are being fired upon, the SAMs will take evasive action will reposition themselves when possible.
-- * When SAM sites are being fired upon, the SAMs will take defensive action by shutting down their radars. -- * When SAM sites are being fired upon, the SAMs will take defensive action by shutting down their radars.
-- * SEAD calculates the time it takes for a HARM to reach the target - and will attempt to minimize the shut-down time.
-- * Detection and evasion of shots has a random component based on the skill level of the SAM groups.
-- --
-- === -- ===
-- --
@@ -17,7 +19,7 @@
-- --
-- ### Authors: **FlightControl**, **applevangelist** -- ### Authors: **FlightControl**, **applevangelist**
-- --
-- Last Update: Aug 2021 -- Last Update: Nov 2021
-- --
-- === -- ===
-- --
@@ -31,6 +33,10 @@
--- Make SAM sites execute evasive and defensive behaviour when being fired upon. --- Make SAM sites execute evasive and defensive behaviour when being fired upon.
-- --
-- This class is very easy to use. Just setup a SEAD object by using @{#SEAD.New}() and SAMs will evade and take defensive action when being fired upon. -- This class is very easy to use. Just setup a SEAD object by using @{#SEAD.New}() and SAMs will evade and take defensive action when being fired upon.
-- Once a HARM attack is detected, SEAD will shut down the radars of the attacked SAM site and take evasive action by moving the SAM
-- vehicles around (*if* they are drivable, that is). There's a component of randomness in detection and evasion, which is based on the
-- skill set of the SAM set (the higher the skill, the more likely). When a missile is fired from far away, the SAM will stay active for a
-- period of time to stay defensive, before it takes evasive actions.
-- --
-- # Constructor: -- # Constructor:
-- --
@@ -51,6 +57,8 @@ SEAD = {
SuppressedGroups = {}, SuppressedGroups = {},
EngagementRange = 75, -- default 75% engagement range Feature Request #1355 EngagementRange = 75, -- default 75% engagement range Feature Request #1355
Padding = 10, Padding = 10,
CallBack = nil,
UseCallBack = false,
} }
--- Missile enumerators --- Missile enumerators
@@ -93,7 +101,7 @@ SEAD = {
-- @param #SEAD self -- @param #SEAD self
-- @param #table SEADGroupPrefixes Table of #string entries or single #string, which is a table of Prefixes of the SA Groups in the DCS mission editor on which evasive actions need to be taken. -- @param #table SEADGroupPrefixes Table of #string entries or single #string, which is a table of Prefixes of the SA Groups in the DCS mission editor on which evasive actions need to be taken.
-- @param #number Padding (Optional) Extra number of seconds to add to radar switch-back-on time -- @param #number Padding (Optional) Extra number of seconds to add to radar switch-back-on time
-- @return SEAD -- @return #SEAD self
-- @usage -- @usage
-- -- CCCP SEAD Defenses -- -- CCCP SEAD Defenses
-- -- Defends the Russian SA installations from SEAD attacks. -- -- Defends the Russian SA installations from SEAD attacks.
@@ -114,14 +122,18 @@ function SEAD:New( SEADGroupPrefixes, Padding )
local padding = Padding or 10 local padding = Padding or 10
if padding < 10 then padding = 10 end if padding < 10 then padding = 10 end
self.Padding = padding self.Padding = padding
self.UseEmissionsOnOff = false
self.CallBack = nil
self.UseCallBack = false
self:HandleEvent( EVENTS.Shot, self.HandleEventShot ) self:HandleEvent( EVENTS.Shot, self.HandleEventShot )
self:I("*** SEAD - Started Version 0.3.1") self:I("*** SEAD - Started Version 0.3.3")
return self return self
end end
--- Update the active SEAD Set --- Update the active SEAD Set (while running)
-- @param #SEAD self -- @param #SEAD self
-- @param #table SEADGroupPrefixes The prefixes to add, note: can also be a single #string -- @param #table SEADGroupPrefixes The prefixes to add, note: can also be a single #string
-- @return #SEAD self -- @return #SEAD self
@@ -142,8 +154,8 @@ end
--- Sets the engagement range of the SAMs. Defaults to 75% to make it more deadly. Feature Request #1355 --- Sets the engagement range of the SAMs. Defaults to 75% to make it more deadly. Feature Request #1355
-- @param #SEAD self -- @param #SEAD self
-- @param #number range Set the engagement range in percent, e.g. 50 -- @param #number range Set the engagement range in percent, e.g. 55 (default 75)
-- @return self -- @return #SEAD self
function SEAD:SetEngagementRange(range) function SEAD:SetEngagementRange(range)
self:T( { range } ) self:T( { range } )
range = range or 75 range = range or 75
@@ -157,7 +169,8 @@ end
--- Set the padding in seconds, which extends the radar off time calculated by SEAD --- Set the padding in seconds, which extends the radar off time calculated by SEAD
-- @param #SEAD self -- @param #SEAD self
-- @param #number Padding Extra number of seconds to add for the switch-on -- @param #number Padding Extra number of seconds to add for the switch-on (default 10 seconds)
-- @return #SEAD self
function SEAD:SetPadding(Padding) function SEAD:SetPadding(Padding)
self:T( { Padding } ) self:T( { Padding } )
local padding = Padding or 10 local padding = Padding or 10
@@ -166,7 +179,31 @@ function SEAD:SetPadding(Padding)
return self return self
end end
--- Check if a known HARM was fired --- Set SEAD to use emissions on/off in addition to alarm state.
-- @param #SEAD self
-- @param #boolean Switch True for on, false for off.
-- @return #SEAD self
function SEAD:SwitchEmissions(Switch)
self:T({Switch})
self.UseEmissionsOnOff = Switch
return self
end
--- Add an object to call back when going evasive.
-- @param #SEAD self
-- @param #table Object The object to call. Needs to have object functions as follows:
-- `:SeadSuppressionPlanned(Group, Name, SuppressionStartTime, SuppressionEndTime)`
-- `:SeadSuppressionStart(Group, Name)`,
-- `:SeadSuppressionEnd(Group, Name)`,
-- @return #SEAD self
function SEAD:AddCallBack(Object)
self:T({Class=Object.ClassName})
self.CallBack = Object
self.UseCallBack = true
return self
end
--- (Internal) Check if a known HARM was fired
-- @param #SEAD self -- @param #SEAD self
-- @param #string WeaponName -- @param #string WeaponName
-- @return #boolean Returns true for a match -- @return #boolean Returns true for a match
@@ -212,10 +249,10 @@ end
end end
end end
--- Detects if an SAM site was shot with an anti radiation missile. In this case, take evasive actions based on the skill level set within the ME. --- (Internal) Detects if an SAM site was shot with an anti radiation missile. In this case, take evasive actions based on the skill level set within the ME.
-- @see SEAD -- @param #SEAD self
-- @param #SEAD
-- @param Core.Event#EVENTDATA EventData -- @param Core.Event#EVENTDATA EventData
-- @return #SEAD self
function SEAD:HandleEventShot( EventData ) function SEAD:HandleEventShot( EventData )
self:T( { EventData.id } ) self:T( { EventData.id } )
local SEADPlane = EventData.IniUnit -- Wrapper.Unit#UNIT local SEADPlane = EventData.IniUnit -- Wrapper.Unit#UNIT
@@ -245,7 +282,7 @@ function SEAD:HandleEventShot( EventData )
-- see if we are shot at -- see if we are shot at
local SEADGroupFound = false local SEADGroupFound = false
for SEADGroupPrefixID, SEADGroupPrefix in pairs( self.SEADGroupPrefixes ) do for SEADGroupPrefixID, SEADGroupPrefix in pairs( self.SEADGroupPrefixes ) do
self:T( SEADGroupPrefix ) self:T( _targetgroupname, SEADGroupPrefix )
if string.find( _targetgroupname, SEADGroupPrefix, 1, true ) then if string.find( _targetgroupname, SEADGroupPrefix, 1, true ) then
SEADGroupFound = true SEADGroupFound = true
self:T( '*** SEAD - Group Match Found' ) self:T( '*** SEAD - Group Match Found' )
@@ -291,16 +328,32 @@ function SEAD:HandleEventShot( EventData )
local function SuppressionStart(args) local function SuppressionStart(args)
self:T(string.format("*** SEAD - %s Radar Off & Relocating",args[2])) self:T(string.format("*** SEAD - %s Radar Off & Relocating",args[2]))
local grp = args[1] -- Wrapper.Group#GROUP local grp = args[1] -- Wrapper.Group#GROUP
grp:OptionAlarmStateGreen() local name = args[2] -- #string Group Name
if self.UseEmissionsOnOff then
grp:EnableEmission(false)
end
grp:OptionAlarmStateGreen() -- needed else we cannot move around
grp:RelocateGroundRandomInRadius(20,300,false,false,"Diamond") grp:RelocateGroundRandomInRadius(20,300,false,false,"Diamond")
if self.UseCallBack then
local object = self.CallBack
object:SeadSuppressionStart(grp,name)
end
end end
local function SuppressionStop(args) local function SuppressionStop(args)
self:T(string.format("*** SEAD - %s Radar On",args[2])) self:T(string.format("*** SEAD - %s Radar On",args[2]))
local grp = args[1] -- Wrapper.Group#GROUP local grp = args[1] -- Wrapper.Group#GROUP
grp:OptionAlarmStateRed() local name = args[2] -- #string Group Nam
if self.UseEmissionsOnOff then
grp:EnableEmission(true)
end
grp:OptionAlarmStateAuto()
grp:OptionEngageRange(self.EngagementRange) grp:OptionEngageRange(self.EngagementRange)
self.SuppressedGroups[args[2]] = false self.SuppressedGroups[name] = false
if self.UseCallBack then
local object = self.CallBack
object:SeadSuppressionEnd(grp,name)
end
end end
-- randomize switch-on time -- randomize switch-on time
@@ -316,6 +369,10 @@ function SEAD:HandleEventShot( EventData )
timer.scheduleFunction(SuppressionStart,{_targetgroup,_targetgroupname},SuppressionStartTime) timer.scheduleFunction(SuppressionStart,{_targetgroup,_targetgroupname},SuppressionStartTime)
timer.scheduleFunction(SuppressionStop,{_targetgroup,_targetgroupname},SuppressionEndTime) timer.scheduleFunction(SuppressionStop,{_targetgroup,_targetgroupname},SuppressionEndTime)
self.SuppressedGroups[_targetgroupname] = true self.SuppressedGroups[_targetgroupname] = true
if self.UseCallBack then
local object = self.CallBack
object:SeadSuppressionPlanned(_targetgroup,_targetgroupname,SuppressionStartTime,SuppressionEndTime)
end
end end
end end
@@ -323,4 +380,5 @@ function SEAD:HandleEventShot( EventData )
end end
end end
end end
return self
end end

View File

@@ -1601,7 +1601,7 @@ WAREHOUSE = {
-- @field #number range Range of the unit in meters. -- @field #number range Range of the unit in meters.
-- @field #number speedmax Maximum speed in km/h the group can do. -- @field #number speedmax Maximum speed in km/h the group can do.
-- @field #number size Maximum size in length and with of the asset in meters. -- @field #number size Maximum size in length and with of the asset in meters.
-- @field #number weight The weight of the whole asset group in kilo gramms. -- @field #number weight The weight of the whole asset group in kilograms.
-- @field DCS#Object.Desc DCSdesc All DCS descriptors. -- @field DCS#Object.Desc DCSdesc All DCS descriptors.
-- @field #WAREHOUSE.Attribute attribute Generalized attribute of the group. -- @field #WAREHOUSE.Attribute attribute Generalized attribute of the group.
-- @field #table cargobay Array of cargo bays of all units in an asset group. -- @field #table cargobay Array of cargo bays of all units in an asset group.

View File

@@ -45,10 +45,10 @@
-- === -- ===
-- --
-- ### Author: **funkyfranky** -- ### Author: **funkyfranky**
--
-- @module Ops.Atis -- @module Ops.Atis
-- @image OPS_ATIS.png -- @image OPS_ATIS.png
--- ATIS class. --- ATIS class.
-- @type ATIS -- @type ATIS
-- @field #string ClassName Name of the class. -- @field #string ClassName Name of the class.
@@ -67,7 +67,7 @@
-- @field #string activerunway The active runway specified by the user. -- @field #string activerunway The active runway specified by the user.
-- @field #number subduration Duration how long subtitles are displayed in seconds. -- @field #number subduration Duration how long subtitles are displayed in seconds.
-- @field #boolean metric If true, use metric units. If false, use imperial (default). -- @field #boolean metric If true, use metric units. If false, use imperial (default).
-- @field #boolean PmmHg If true, give pressure in millimeters of Mercury. Default is inHg for imperial and hecto Pascal (=mili Bars) for metric units. -- @field #boolean PmmHg If true, give pressure in millimeters of Mercury. Default is inHg for imperial and hectopascal (hPa, which is the same as millibar - mbar) for metric units.
-- @field #boolean qnhonly If true, suppresses reporting QFE. Default is to report both QNH and QFE. -- @field #boolean qnhonly If true, suppresses reporting QFE. Default is to report both QNH and QFE.
-- @field #boolean TDegF If true, give temperature in degrees Fahrenheit. Default is in degrees Celsius independent of chosen unit system. -- @field #boolean TDegF If true, give temperature in degrees Fahrenheit. Default is in degrees Celsius independent of chosen unit system.
-- @field #number zuludiff Time difference local vs. zulu in hours. -- @field #number zuludiff Time difference local vs. zulu in hours.
@@ -126,7 +126,7 @@
-- ## Subtitles -- ## Subtitles
-- --
-- Currently, DCS allows for displaying subtitles of radio transmissions only from airborne units, *i.e.* airplanes and helicopters. Therefore, if you want to have subtitles, it is necessary to place an -- Currently, DCS allows for displaying subtitles of radio transmissions only from airborne units, *i.e.* airplanes and helicopters. Therefore, if you want to have subtitles, it is necessary to place an
-- additonal aircraft on the ATIS airport and set it to uncontrolled. This unit can then function as a radio relay to transmit messages with subtitles. These subtitles will only be displayed, if the -- additional aircraft on the ATIS airport and set it to uncontrolled. This unit can then function as a radio relay to transmit messages with subtitles. These subtitles will only be displayed, if the
-- player has tuned in the correct ATIS frequency. -- player has tuned in the correct ATIS frequency.
-- --
-- Radio transmissions via an airborne unit can be set via the @{#ATIS.SetRadioRelayUnitName}(*unitname*) function, where the parameter *unitname* is the name of the unit passed as string, *e.g.* -- Radio transmissions via an airborne unit can be set via the @{#ATIS.SetRadioRelayUnitName}(*unitname*) function, where the parameter *unitname* is the name of the unit passed as string, *e.g.*
@@ -142,7 +142,7 @@
-- --
-- ## Active Runway -- ## Active Runway
-- --
-- By default, the currently active runway is determined automatically by analysing the wind direction. Therefore, you should obviously set the wind speed to be greater zero in your mission. -- By default, the currently active runway is determined automatically by analyzing the wind direction. Therefore, you should obviously set the wind speed to be greater zero in your mission.
-- --
-- Note however, there are a few special cases, where automatic detection does not yield the correct or desired result. -- Note however, there are a few special cases, where automatic detection does not yield the correct or desired result.
-- For example, there are airports with more than one runway facing in the same direction (usually denoted left and right). In this case, there is obviously no *unique* result depending on the wind vector. -- For example, there are airports with more than one runway facing in the same direction (usually denoted left and right). In this case, there is obviously no *unique* result depending on the wind vector.
@@ -170,7 +170,7 @@
-- --
-- ## Nav Aids -- ## Nav Aids
-- --
-- Frequencies or channels of navigation aids can be specified by the user and are then provided as additional information. Unfortunately, it is **not possible** to aquire this information via the DCS API -- Frequencies or channels of navigation aids can be specified by the user and are then provided as additional information. Unfortunately, it is **not possible** to acquire this information via the DCS API
-- we have access to. -- we have access to.
-- --
-- As they say, all road lead to Rome but (for me) the easiest way to obtain the available nav aids data of an airport, is to start a mission and click on an airport symbol. -- As they say, all road lead to Rome but (for me) the easiest way to obtain the available nav aids data of an airport, is to start a mission and click on an airport symbol.
@@ -239,7 +239,7 @@
-- --
-- atisBatumi:SetMetricUnits() -- atisBatumi:SetMetricUnits()
-- --
-- With this, wind speed is given in meters per second, pressure in hecto Pascal (mbar), visibility in kilometers etc. -- With this, wind speed is given in meters per second, pressure in hectopascal (hPa, which is the same as millibar - mbar), visibility in kilometers etc.
-- --
-- # Sound Files -- # Sound Files
-- --
@@ -259,7 +259,7 @@
-- --
-- # Text-To-Speech -- # Text-To-Speech
-- --
-- You can enable text-to-speech ATIS information with the @{#ATIS.SetSRS}() function. This uses [SRS](http://dcssimpleradio.com/) (Version >= 1.9.6.0) for broadcasing. -- You can enable text-to-speech ATIS information with the @{#ATIS.SetSRS}() function. This uses [SRS](http://dcssimpleradio.com/) (Version >= 1.9.6.0) for broadcasting.
-- Advantages are that **no sound files** or radio relay units are necessary. Also the issue that FC3 aircraft hear all transmissions will be circumvented. -- Advantages are that **no sound files** or radio relay units are necessary. Also the issue that FC3 aircraft hear all transmissions will be circumvented.
-- --
-- The @{#ATIS.SetSRS}() requires you to specify the path to the SRS install directory or more specifically the path to the DCS-SR-ExternalAudio.exe file. -- The @{#ATIS.SetSRS}() requires you to specify the path to the SRS install directory or more specifically the path to the DCS-SR-ExternalAudio.exe file.
@@ -416,7 +416,7 @@ ATIS.ICAOPhraseology={
PersianGulf = true, PersianGulf = true,
TheChannel = true, TheChannel = true,
Syria = true, Syria = true,
MarianaIslands=true, MarianaIslands = true
} }
--- Nav point data. --- Nav point data.
@@ -582,7 +582,6 @@ ATIS.Sound = {
Zulu = { filename = "Zulu.ogg", duration = 0.62 }, Zulu = { filename = "Zulu.ogg", duration = 0.62 },
} }
--- ATIS table containing all defined ATISes. --- ATIS table containing all defined ATISes.
-- @field #table _ATIS -- @field #table _ATIS
_ATIS = {} _ATIS = {}
@@ -680,7 +679,6 @@ function ATIS:New(airbasename, frequency, modulation)
-- @param #ATIS self -- @param #ATIS self
-- @param #number delay Delay in seconds. -- @param #number delay Delay in seconds.
--- Triggers the FSM event "Stop". Stops the ATIS. --- Triggers the FSM event "Stop". Stops the ATIS.
-- @function [parent=#ATIS] Stop -- @function [parent=#ATIS] Stop
-- @param #ATIS self -- @param #ATIS self
@@ -690,7 +688,6 @@ function ATIS:New(airbasename, frequency, modulation)
-- @param #ATIS self -- @param #ATIS self
-- @param #number delay Delay in seconds. -- @param #number delay Delay in seconds.
--- Triggers the FSM event "Status". --- Triggers the FSM event "Status".
-- @function [parent=#ATIS] Status -- @function [parent=#ATIS] Status
-- @param #ATIS self -- @param #ATIS self
@@ -700,7 +697,6 @@ function ATIS:New(airbasename, frequency, modulation)
-- @param #ATIS self -- @param #ATIS self
-- @param #number delay Delay in seconds. -- @param #number delay Delay in seconds.
--- Triggers the FSM event "Broadcast". --- Triggers the FSM event "Broadcast".
-- @function [parent=#ATIS] Broadcast -- @function [parent=#ATIS] Broadcast
-- @param #ATIS self -- @param #ATIS self
@@ -710,7 +706,6 @@ function ATIS:New(airbasename, frequency, modulation)
-- @param #ATIS self -- @param #ATIS self
-- @param #number delay Delay in seconds. -- @param #number delay Delay in seconds.
--- Triggers the FSM event "CheckQueue". --- Triggers the FSM event "CheckQueue".
-- @function [parent=#ATIS] CheckQueue -- @function [parent=#ATIS] CheckQueue
-- @param #ATIS self -- @param #ATIS self
@@ -720,7 +715,6 @@ function ATIS:New(airbasename, frequency, modulation)
-- @param #ATIS self -- @param #ATIS self
-- @param #number delay Delay in seconds. -- @param #number delay Delay in seconds.
--- Triggers the FSM event "Report". --- Triggers the FSM event "Report".
-- @function [parent=#ATIS] Report -- @function [parent=#ATIS] Report
-- @param #ATIS self -- @param #ATIS self
@@ -740,7 +734,6 @@ function ATIS:New(airbasename, frequency, modulation)
-- @param #string To To state. -- @param #string To To state.
-- @param #string Text Report text. -- @param #string Text Report text.
-- Debug trace. -- Debug trace.
if false then if false then
self.Debug = true self.Debug = true
@@ -1114,7 +1107,6 @@ function ATIS:AddPRMG(channel, runway)
return self return self
end end
--- Place marks with runway data on the F10 map. --- Place marks with runway data on the F10 map.
-- @param #ATIS self -- @param #ATIS self
-- @param #boolean markall If true, mark all runways of the map. By default only the current ATIS runways are marked. -- @param #boolean markall If true, mark all runways of the map. By default only the current ATIS runways are marked.
@@ -1243,8 +1235,7 @@ function ATIS:onafterStatus(From, Event, To)
-- Info text. -- Info text.
local text = string.format( "State %s: Freq=%.3f MHz %s", fsmstate, self.frequency, UTILS.GetModulationName( self.modulation ) ) local text = string.format( "State %s: Freq=%.3f MHz %s", fsmstate, self.frequency, UTILS.GetModulationName( self.modulation ) )
if self.useSRS then if self.useSRS then
text=text..string.format(", SRS path=%s (%s), gender=%s, culture=%s, voice=%s", text = text .. string.format( ", SRS path=%s (%s), gender=%s, culture=%s, voice=%s", tostring( self.msrs.path ), tostring( self.msrs.port ), tostring( self.msrs.gender ), tostring( self.msrs.culture ), tostring( self.msrs.voice ) )
tostring(self.msrs.path), tostring(self.msrs.port), tostring(self.msrs.gender), tostring(self.msrs.culture), tostring(self.msrs.voice))
else else
text = text .. string.format( ", Relay unit=%s (alive=%s)", tostring( self.relayunitname ), relayunitstatus ) text = text .. string.format( ", Relay unit=%s (alive=%s)", tostring( self.relayunitname ), relayunitstatus )
end end
@@ -1277,8 +1268,6 @@ function ATIS:onafterCheckQueue(From, Event, To)
self:T2( self.lid .. string.format( "Radio queue %d transmissions queued.", #self.radioqueue.queue ) ) self:T2( self.lid .. string.format( "Radio queue %d transmissions queued.", #self.radioqueue.queue ) )
end end
end end
-- Check back in 5 seconds. -- Check back in 5 seconds.
@@ -1322,7 +1311,6 @@ function ATIS:onafterBroadcast(From, Event, To)
local Q = P / (1 + L * height / TS) ^ (-g * M / (R * L)) -- Altimeter QNH local Q = P / (1 + L * height / TS) ^ (-g * M / (R * L)) -- Altimeter QNH
local A = (T0 / L) * ((P / q) ^ (((-R * L) / (g * M))) - 1) -- Altitude check local A = (T0 / L) * ((P / q) ^ (((-R * L) / (g * M))) - 1) -- Altitude check
-- Debug aoutput -- Debug aoutput
self:T2( self.lid .. string.format( "height=%.1f, A=%.1f, T0=%.1f, QFE=%.1f, QNH=%.1f, P=%.1f, Q=%.1f hPa = %.2f", height, A, T0 - 273.15, qfe, qnh, P / 100, Q / 100, UTILS.hPa2inHg( Q / 100 ) ) ) self:T2( self.lid .. string.format( "height=%.1f, A=%.1f, T0=%.1f, QFE=%.1f, QNH=%.1f, P=%.1f, Q=%.1f hPa = %.2f", height, A, T0 - 273.15, qfe, qnh, P / 100, Q / 100, UTILS.hPa2inHg( Q / 100 ) ) )
@@ -1331,7 +1319,6 @@ function ATIS:onafterBroadcast(From, Event, To)
end end
-- Convert to inHg. -- Convert to inHg.
if self.PmmHg then if self.PmmHg then
qfe = UTILS.hPa2mmHg( qfe ) qfe = UTILS.hPa2mmHg( qfe )
@@ -1417,7 +1404,6 @@ function ATIS:onafterBroadcast(From, Event, To)
ZULU = string.format( "%s hours", zulu[1] ) ZULU = string.format( "%s hours", zulu[1] )
end end
-- NATO time stamp. 0=Alfa, 1=Bravo, 2=Charlie, etc. -- NATO time stamp. 0=Alfa, 1=Bravo, 2=Charlie, etc.
local NATO = ATIS.Alphabet[tonumber( zulu[1] ) + 1] local NATO = ATIS.Alphabet[tonumber( zulu[1] ) + 1]
@@ -1446,7 +1432,6 @@ function ATIS:onafterBroadcast(From, Event, To)
SUNSET = string.format( "%s %s hours", sunset[1], sunset[2] ) SUNSET = string.format( "%s %s hours", sunset[1], sunset[2] )
end end
--------------------------------- ---------------------------------
--- Temperature and Dew Point --- --- Temperature and Dew Point ---
--------------------------------- ---------------------------------
@@ -1459,8 +1444,8 @@ function ATIS:onafterBroadcast(From, Event, To)
-- Convert to °F. -- Convert to °F.
if self.TDegF then if self.TDegF then
temperature=UTILS.CelciusToFarenheit(temperature) temperature = UTILS.CelsiusToFahrenheit( temperature )
dewpoint=UTILS.CelciusToFarenheit(dewpoint) dewpoint = UTILS.CelsiusToFahrenheit( dewpoint )
end end
local TEMPERATURE = string.format( "%d", math.abs( temperature ) ) local TEMPERATURE = string.format( "%d", math.abs( temperature ) )
@@ -2280,7 +2265,7 @@ function ATIS:onafterReport(From, Event, To, Text)
local text = string.gsub( text, "°F", "degrees Fahrenheit" ) local text = string.gsub( text, "°F", "degrees Fahrenheit" )
local text = string.gsub( text, "inHg", "inches of Mercury" ) local text = string.gsub( text, "inHg", "inches of Mercury" )
local text = string.gsub( text, "mmHg", "millimeters of Mercury" ) local text = string.gsub( text, "mmHg", "millimeters of Mercury" )
local text=string.gsub(text, "hPa", "hecto Pascals") local text = string.gsub( text, "hPa", "hectopascals" )
local text = string.gsub( text, "m/s", "meters per second" ) local text = string.gsub( text, "m/s", "meters per second" )
-- Replace ";" by "." -- Replace ";" by "."
@@ -2572,7 +2557,6 @@ function ATIS:GetMissionWeather()
return clouds, visibility, turbulence, fog, dust, static return clouds, visibility, turbulence, fog, dust, static
end end
--- Get thousands of a number. --- Get thousands of a number.
-- @param #ATIS self -- @param #ATIS self
-- @param #number n Number, *e.g.* 4359. -- @param #number n Number, *e.g.* 4359.

File diff suppressed because it is too large Load Diff

View File

@@ -22,7 +22,7 @@
-- @module Ops.CSAR -- @module Ops.CSAR
-- @image OPS_CSAR.jpg -- @image OPS_CSAR.jpg
-- Date: Oct 2021 -- Date: Dec 2021
------------------------------------------------------------------------- -------------------------------------------------------------------------
--- **CSAR** class, extends Core.Base#BASE, Core.Fsm#FSM --- **CSAR** class, extends Core.Base#BASE, Core.Fsm#FSM
@@ -42,13 +42,14 @@
-- # CSAR Concept -- # CSAR Concept
-- --
-- * MOOSE-based Helicopter CSAR Operations for Players. -- * MOOSE-based Helicopter CSAR Operations for Players.
-- * Object oriented refactoring of Ciribob\'s fantastic CSAR script. -- * Object oriented refactoring of Ciribob's fantastic CSAR script.
-- * No need for extra MIST loading. -- * No need for extra MIST loading.
-- * Additional events to tailor your mission. -- * Additional events to tailor your mission.
-- * Optional SpawnCASEVAC to create casualties without beacon (e.g. handling dead ground vehicles and create CASEVAC requests).
-- --
-- ## 0. Prerequisites -- ## 0. Prerequisites
-- --
-- You need to load an .ogg soundfile for the pilot\'s beacons into the mission, e.g. "beacon.ogg", use a once trigger, "sound to country" for that. -- You need to load an .ogg sound file for the pilot's beacons into the mission, e.g. "beacon.ogg", use a once trigger, "sound to country" for that.
-- Create a late-activated single infantry unit as template in the mission editor and name it e.g. "Downed Pilot". -- Create a late-activated single infantry unit as template in the mission editor and name it e.g. "Downed Pilot".
-- --
-- ## 1. Basic Setup -- ## 1. Basic Setup
@@ -67,23 +68,23 @@
-- --
-- The following options are available (with their defaults). Only set the ones you want changed: -- The following options are available (with their defaults). Only set the ones you want changed:
-- --
-- self.allowDownedPilotCAcontrol = false -- Set to false if you don\'t want to allow control by Combined Arms. -- self.allowDownedPilotCAcontrol = false -- Set to false if you don't want to allow control by Combined Arms.
-- self.allowFARPRescue = true -- allows pilots to be rescued by landing at a FARP or Airbase. Else MASH only! -- self.allowFARPRescue = true -- allows pilots to be rescued by landing at a FARP or Airbase. Else MASH only!
-- self.FARPRescueDistance = 1000 -- you need to be this close to a FARP or Airport for the pilot to be rescued. -- self.FARPRescueDistance = 1000 -- you need to be this close to a FARP or Airport for the pilot to be rescued.
-- self.autosmoke = false -- automatically smoke a downed pilot\'s location when a heli is near. -- self.autosmoke = false -- automatically smoke a downed pilot's location when a helicopter is near.
-- self.autosmokedistance = 1000 -- distance for autosmoke -- self.autosmokedistance = 1000 -- distance in meters for automatic smoke deployment
-- self.coordtype = 1 -- Use Lat/Long DDM (0), Lat/Long DMS (1), MGRS (2), Bullseye imperial (3) or Bullseye metric (4) for coordinates. -- self.coordtype = 1 -- Use Lat/Long DDM (0), Lat/Long DMS (1), MGRS (2), Bullseye imperial (3) or Bullseye metric (4) for coordinates.
-- self.csarOncrash = false -- (WIP) If set to true, will generate a downed pilot when a plane crashes as well. -- self.csarOncrash = false -- (WIP) If set to true, will generate a downed pilot when a plane crashes as well.
-- self.enableForAI = false -- set to false to disable AI pilots from being rescued. -- self.enableForAI = false -- set to false to disable AI pilots from being rescued.
-- self.pilotRuntoExtractPoint = true -- Downed pilot will run to the rescue helicopter up to self.extractDistance in meters. -- self.pilotRuntoExtractPoint = true -- Downed pilot will run to the rescue helicopter up to self.extractDistance in meters.
-- self.extractDistance = 500 -- Distance the downed pilot will start to run to the rescue helicopter. -- self.extractDistance = 500 -- Distance the downed pilot will start to run to the rescue helicopter.
-- self.immortalcrew = true -- Set to true to make wounded crew immortal. -- self.immortalcrew = true -- Set to true to make wounded crew immortal.
-- self.invisiblecrew = false -- Set to true to make wounded crew insvisible. -- self.invisiblecrew = false -- Set to true to make wounded crew invisible.
-- self.loadDistance = 75 -- configure distance for pilots to get into helicopter in meters. -- self.loadDistance = 75 -- configure distance for pilots to get into helicopter in meters.
-- self.mashprefix = {"MASH"} -- prefixes of #GROUP objects used as MASHes. -- self.mashprefix = {"MASH"} -- prefixes of #GROUP objects used as MASHes.
-- self.max_units = 6 -- max number of pilots that can be carried if #CSAR.AircraftType is undefined. -- self.max_units = 6 -- max number of pilots that can be carried if #CSAR.AircraftType is undefined.
-- self.messageTime = 15 -- Time to show messages for in seconds. Doubled for long messages. -- self.messageTime = 15 -- Time to show messages for in seconds. Doubled for long messages.
-- self.radioSound = "beacon.ogg" -- the name of the sound file to use for the pilots\' radio beacons. -- self.radioSound = "beacon.ogg" -- the name of the sound file to use for the pilots' radio beacons.
-- self.smokecolor = 4 -- Color of smoke marker, 0 is green, 1 is red, 2 is white, 3 is orange and 4 is blue. -- self.smokecolor = 4 -- Color of smoke marker, 0 is green, 1 is red, 2 is white, 3 is orange and 4 is blue.
-- self.useprefix = true -- Requires CSAR helicopter #GROUP names to have the prefix(es) defined below. -- self.useprefix = true -- Requires CSAR helicopter #GROUP names to have the prefix(es) defined below.
-- self.csarPrefix = { "helicargo", "MEDEVAC"} -- #GROUP name prefixes used for useprefix=true - DO NOT use # in helicopter names in the Mission Editor! -- self.csarPrefix = { "helicargo", "MEDEVAC"} -- #GROUP name prefixes used for useprefix=true - DO NOT use # in helicopter names in the Mission Editor!
@@ -108,13 +109,15 @@
-- --
-- ## 2.1 Experimental Features -- ## 2.1 Experimental Features
-- --
-- WARNING - Here\'ll be dragons! -- WARNING - Here'll be dragons!
-- DANGER - For this to work you need to de-sanitize your mission environment (all three entries) in <DCS root>\Scripts\MissionScripting.lua -- DANGER - For this to work you need to de-sanitize your mission environment (all three entries) in <DCS root>\Scripts\MissionScripting.lua
-- Needs SRS => 1.9.6 to work (works on the **server** side of SRS) -- Needs SRS => 1.9.6 to work (works on the **server** side of SRS)
-- self.useSRS = false -- Set true to use FF\'s SRS integration -- self.useSRS = false -- Set true to use FF's SRS integration
-- self.SRSPath = "E:\\Progra~1\\DCS-SimpleRadio-Standalone\\" -- adjust your own path in your SRS installation -- server(!) -- self.SRSPath = "E:\\Progra~1\\DCS-SimpleRadio-Standalone\\" -- adjust your own path in your SRS installation -- server(!)
-- self.SRSchannel = 300 -- radio channel -- self.SRSchannel = 300 -- radio channel
-- self.SRSModulation = radio.modulation.AM -- modulation -- self.SRSModulation = radio.modulation.AM -- modulation
-- --
-- self.csarUsePara = false -- If set to true, will use the LandingAfterEjection Event instead of Ejection --shagrat
-- --
-- ## 3. Results -- ## 3. Results
-- --
@@ -138,7 +141,7 @@
-- --
-- ### 4.2. Approach. -- ### 4.2. Approach.
-- --
-- A CSAR helicpoter is closing in on a downed pilot. Use e.g. `function my_csar:OnAfterApproach(...)` to link into this event: -- A CSAR helicopter is closing in on a downed pilot. Use e.g. `function my_csar:OnAfterApproach(...)` to link into this event:
-- --
-- function my_csar:OnAfterApproach(from, event, to, heliname, groupname) -- function my_csar:OnAfterApproach(from, event, to, heliname, groupname)
-- ... your code here ... -- ... your code here ...
@@ -175,6 +178,8 @@
-- -- Create downed "Pilot Wagner" in #ZONE "CSAR_Start_1" at a random point for the blue coalition -- -- Create downed "Pilot Wagner" in #ZONE "CSAR_Start_1" at a random point for the blue coalition
-- my_csar:SpawnCSARAtZone( "CSAR_Start_1", coalition.side.BLUE, "Pilot Wagner", true ) -- my_csar:SpawnCSARAtZone( "CSAR_Start_1", coalition.side.BLUE, "Pilot Wagner", true )
-- --
-- --Create a casualty and CASEVAC request from a "Point" (VEC2) for the blue coalition --shagrat
-- my_csar:SpawnCASEVAC(Point, coalition.side.BLUE)
-- --
-- @field #CSAR -- @field #CSAR
CSAR = { CSAR = {
@@ -200,7 +205,7 @@ CSAR = {
hoverStatus = {}, -- tracks status of a helis hover above a downed pilot hoverStatus = {}, -- tracks status of a helis hover above a downed pilot
pilotDisabled = {}, -- tracks what aircraft a pilot is disabled for pilotDisabled = {}, -- tracks what aircraft a pilot is disabled for
pilotLives = {}, -- tracks how many lives a pilot has pilotLives = {}, -- tracks how many lives a pilot has
useprefix = true, -- Use the Prefixed defined below, Requires Unit have the Prefix defined below useprefix = true, -- Use the Prefix defined below, requires Unit to have the Prefix defined
csarPrefix = {}, csarPrefix = {},
template = nil, template = nil,
mash = {}, mash = {},
@@ -238,10 +243,11 @@ CSAR.AircraftType["Mi-8MTV2"] = 12
CSAR.AircraftType["Mi-8MT"] = 12 CSAR.AircraftType["Mi-8MT"] = 12
CSAR.AircraftType["Mi-24P"] = 8 CSAR.AircraftType["Mi-24P"] = 8
CSAR.AircraftType["Mi-24V"] = 8 CSAR.AircraftType["Mi-24V"] = 8
CSAR.AircraftType["Bell-47"] = 2
--- CSAR class version. --- CSAR class version.
-- @field #string version -- @field #string version
CSAR.version="0.1.11r1" CSAR.version = "1.0.1r1"
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- ToDo list -- ToDo list
@@ -249,7 +255,7 @@ CSAR.version="0.1.11r1"
-- DONE: SRS Integration (to be tested) -- DONE: SRS Integration (to be tested)
-- TODO: Maybe - add option to smoke/flare closest MASH -- TODO: Maybe - add option to smoke/flare closest MASH
-- TODO: shagrat Add cargoWeight to helicopter when pilot boarded
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Constructor -- Constructor
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
@@ -338,35 +344,36 @@ function CSAR:New(Coalition, Template, Alias)
self.rescues = 0 -- counter for successful rescue landings at FARP/AFB/MASH self.rescues = 0 -- counter for successful rescue landings at FARP/AFB/MASH
self.rescuedpilots = 0 -- counter for saved pilots self.rescuedpilots = 0 -- counter for saved pilots
self.csarOncrash = false -- If set to true, will generate a csar when a plane crashes as well. self.csarOncrash = false -- If set to true, will generate a csar when a plane crashes as well.
self.allowDownedPilotCAcontrol = false -- Set to false if you don\'t want to allow control by Combined arms. self.allowDownedPilotCAcontrol = false -- Set to false if you don't want to allow control by Combined arms.
self.enableForAI = false -- set to false to disable AI units from being rescued. self.enableForAI = false -- set to false to disable AI units from being rescued.
self.smokecolor = 4 -- Color of smoke marker for blue side, 0 is green, 1 is red, 2 is white, 3 is orange and 4 is blue self.smokecolor = 4 -- Color of smoke marker for blue side, 0 is green, 1 is red, 2 is white, 3 is orange and 4 is blue
self.coordtype = 2 -- Use Lat/Long DDM (0), Lat/Long DMS (1), MGRS (2), Bullseye imperial (3) or Bullseye metric (4) for coordinates. self.coordtype = 2 -- Use Lat/Long DDM (0), Lat/Long DMS (1), MGRS (2), Bullseye imperial (3) or Bullseye metric (4) for coordinates.
self.immortalcrew = true -- Set to true to make wounded crew immortal self.immortalcrew = true -- Set to true to make wounded crew immortal
self.invisiblecrew = false -- Set to true to make wounded crew insvisible self.invisiblecrew = false -- Set to true to make wounded crew invisible
self.messageTime = 15 -- Time to show longer messages for in seconds self.messageTime = 15 -- Time to show longer messages for in seconds
self.pilotRuntoExtractPoint = true -- Downed Pilot will run to the rescue helicopter up to self.extractDistance METERS self.pilotRuntoExtractPoint = true -- Downed Pilot will run to the rescue helicopter up to self.extractDistance METERS.
self.loadDistance = 75 -- configure distance for pilot to get in helicopter in meters. self.loadDistance = 75 -- configure distance for pilot to get in helicopter in meters.
self.extractDistance = 500 -- Distance the Downed pilot will run to the rescue helicopter self.extractDistance = 500 -- Distance the Downed pilot will run to the rescue helicopter.
self.loadtimemax = 135 -- seconds self.loadtimemax = 135 -- seconds
self.radioSound = "beacon.ogg" -- the name of the sound file to use for the Pilot radio beacons. If this isnt added to the mission BEACONS WONT WORK! self.radioSound = "beacon.ogg" -- the name of the sound file to use for the Pilot radio beacons. If this isn't added to the mission BEACONS WONT WORK!
self.beaconRefresher = 29 -- seconds
self.allowFARPRescue = true -- allows pilot to be rescued by landing at a FARP or Airbase self.allowFARPRescue = true -- allows pilot to be rescued by landing at a FARP or Airbase
self.FARPRescueDistance = 1000 -- you need to be this close to a FARP or Airport for the pilot to be rescued. self.FARPRescueDistance = 1000 -- you need to be this close to a FARP or Airport for the pilot to be rescued.
self.max_units = 6 -- max number of pilots that can be carried self.max_units = 6 -- max number of pilots that can be carried
self.useprefix = true -- Use the Prefixed defined below, Requires Unit have the Prefix defined below self.useprefix = true -- Use the Prefixed defined below, Requires Unit have the Prefix defined below.
self.csarPrefix = { "helicargo", "MEDEVAC"} -- prefixes used for useprefix=true - DON\'T use # in names! self.csarPrefix = { "helicargo", "MEDEVAC" } -- prefixes used for useprefix=true - DON'T use # in names!
self.template = Template or "generic" -- template for downed pilot self.template = Template or "generic" -- template for downed pilot
self.mashprefix = { "MASH" } -- prefixes used to find MASHes self.mashprefix = { "MASH" } -- prefixes used to find MASHes
self.autosmoke = false -- automatically smoke location when heli is near self.autosmoke = false -- automatically smoke location when heli is near
self.autosmokedistance = 2000 -- distance for autosmoke self.autosmokedistance = 2000 -- distance in meters for automatic smoke deployment
-- added 0.1.4 -- added 0.1.4
self.limitmaxdownedpilots = true self.limitmaxdownedpilots = true
self.maxdownedpilots = 25 self.maxdownedpilots = 25
-- generate Frequencies -- generate Frequencies
self:_GenerateVHFrequencies() self:_GenerateVHFrequencies()
-- added 0.1.8 -- added 0.1.8
self.approachdist_far = 5000 -- switch do 10 sec interval approach mode, meters self.approachdist_far = 5000 -- switch to 10 sec interval approach mode, meters
self.approachdist_near = 3000 -- switch to 5 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 on open doors self.pilotmustopendoors = false -- switch to true to enable check on open doors
self.suppressmessages = false self.suppressmessages = false
@@ -380,10 +387,13 @@ function CSAR:New(Coalition, Template, Alias)
self.countryred = country.id.RUSSIA self.countryred = country.id.RUSSIA
self.countryneutral = country.id.UN_PEACEKEEPERS self.countryneutral = country.id.UN_PEACEKEEPERS
-- WARNING - here\'ll be dragons -- added 0.1.3
self.csarUsePara = false -- shagrat set to true, will use the LandingAfterEjection Event instead of Ejection
-- WARNING - here'll be dragons
-- for this to work you need to de-sanitize your mission environment in <DCS root>\Scripts\MissionScripting.lua -- for this to work you need to de-sanitize your mission environment in <DCS root>\Scripts\MissionScripting.lua
-- needs SRS => 1.9.6 to work (works on the *server* side) -- needs SRS => 1.9.6 to work (works on the *server* side)
self.useSRS = false -- Use FF\'s SRS integration self.useSRS = false -- Use FF's SRS integration
self.SRSPath = "E:\\Progra~1\\DCS-SimpleRadio-Standalone\\" -- adjust your own path in your server(!) self.SRSPath = "E:\\Progra~1\\DCS-SimpleRadio-Standalone\\" -- adjust your own path in your server(!)
self.SRSchannel = 300 -- radio channel self.SRSchannel = 300 -- radio channel
self.SRSModulation = radio.modulation.AM -- modulation self.SRSModulation = radio.modulation.AM -- modulation
@@ -436,7 +446,7 @@ function CSAR:New(Coalition, Template, Alias)
-- @param #string Event Event. -- @param #string Event Event.
-- @param #string To To state. -- @param #string To To state.
-- @param #string Heliname Name of the helicopter group. -- @param #string Heliname Name of the helicopter group.
-- @param #string Woundedgroupname Name of the downed pilot\'s group. -- @param #string Woundedgroupname Name of the downed pilot's group.
--- On After "Boarded" event. Downed pilot boarded heli. --- On After "Boarded" event. Downed pilot boarded heli.
-- @function [parent=#CSAR] OnAfterBoarded -- @function [parent=#CSAR] OnAfterBoarded
@@ -445,7 +455,7 @@ function CSAR:New(Coalition, Template, Alias)
-- @param #string Event Event. -- @param #string Event Event.
-- @param #string To To state. -- @param #string To To state.
-- @param #string Heliname Name of the helicopter group. -- @param #string Heliname Name of the helicopter group.
-- @param #string Woundedgroupname Name of the downed pilot\'s group. -- @param #string Woundedgroupname Name of the downed pilot's group.
--- On After "Returning" event. Heli can return home with downed pilot(s). --- On After "Returning" event. Heli can return home with downed pilot(s).
-- @function [parent=#CSAR] OnAfterReturning -- @function [parent=#CSAR] OnAfterReturning
@@ -454,7 +464,7 @@ function CSAR:New(Coalition, Template, Alias)
-- @param #string Event Event. -- @param #string Event Event.
-- @param #string To To state. -- @param #string To To state.
-- @param #string Heliname Name of the helicopter group. -- @param #string Heliname Name of the helicopter group.
-- @param #string Woundedgroupname Name of the downed pilot\'s group. -- @param #string Woundedgroupname Name of the downed pilot's group.
--- On After "Rescued" event. Pilot(s) have been brought to the MASH/FARP/AFB. --- On After "Rescued" event. Pilot(s) have been brought to the MASH/FARP/AFB.
-- @function [parent=#CSAR] OnAfterRescued -- @function [parent=#CSAR] OnAfterRescued
@@ -566,7 +576,9 @@ function CSAR:_SpawnPilotInField(country,point,frequency)
for i = 1, 10 do for i = 1, 10 do
math.random( i, 10000 ) math.random( i, 10000 )
end end
if point:IsSurfaceTypeWater() then point.y = 0 end if point:IsSurfaceTypeWater() then
point.y = 0
end
local template = self.template local template = self.template
local alias = string.format( "Pilot %.2fkHz-%d", freq, math.random( 1, 99 ) ) local alias = string.format( "Pilot %.2fkHz-%d", freq, math.random( 1, 99 ) )
local coalition = self.coalition local coalition = self.coalition
@@ -595,8 +607,8 @@ function CSAR:_AddSpecialOptions(group)
local _setImmortal = { local _setImmortal = {
id = 'SetImmortal', id = 'SetImmortal',
params = { params = {
value = true value = true,
} },
} }
group:SetCommand( _setImmortal ) group:SetCommand( _setImmortal )
end end
@@ -605,8 +617,8 @@ function CSAR:_AddSpecialOptions(group)
local _setInvisible = { local _setInvisible = {
id = 'SetInvisible', id = 'SetInvisible',
params = { params = {
value = true value = true,
} },
} }
group:SetCommand( _setInvisible ) group:SetCommand( _setInvisible )
end end
@@ -636,7 +648,9 @@ function CSAR:_AddCsar(_coalition , _country, _point, _typeName, _unitName, _pla
if not _freq then if not _freq then
_freq = self:_GenerateADFFrequency() _freq = self:_GenerateADFFrequency()
if not _freq then _freq = 333000 end --noob catch if not _freq then
_freq = 333000
end -- noob catch
end end
local _spawnedGroup, _alias = self:_SpawnPilotInField( _country, _point, _freq ) local _spawnedGroup, _alias = self:_SpawnPilotInField( _country, _point, _freq )
@@ -644,10 +658,14 @@ function CSAR:_AddCsar(_coalition , _country, _point, _typeName, _unitName, _pla
local _typeName = _typeName or "Pilot" local _typeName = _typeName or "Pilot"
if not noMessage then if not noMessage then
if _freq ~= 0 then -- shagrat different CASEVAC msg
self:_DisplayToAllSAR( "MAYDAY MAYDAY! " .. _typeName .. " is down. ", self.coalition, self.messageTime ) self:_DisplayToAllSAR( "MAYDAY MAYDAY! " .. _typeName .. " is down. ", self.coalition, self.messageTime )
else
self:_DisplayToAllSAR( "Troops In Contact. " .. _typeName .. " requests CASEVAC. ", self.coalition, self.messageTime )
end
end end
if _freq then if (_freq and _freq ~= 0) then -- shagrat only add beacon if _freq is NOT 0
self:_AddBeaconToGroup( _spawnedGroup, _freq ) self:_AddBeaconToGroup( _spawnedGroup, _freq )
end end
@@ -656,9 +674,17 @@ function CSAR:_AddCsar(_coalition , _country, _point, _typeName, _unitName, _pla
local _text = _description local _text = _description
if not forcedesc then if not forcedesc then
if _playerName ~= nil then if _playerName ~= nil then
if _freq ~= 0 then -- shagrat
_text = "Pilot " .. _playerName _text = "Pilot " .. _playerName
else
_text = "TIC - " .. _playerName
end
elseif _unitName ~= nil then elseif _unitName ~= nil then
if _freq ~= 0 then -- shagrat
_text = "AI Pilot of " .. _unitName _text = "AI Pilot of " .. _unitName
else
_text = "TIC - " .. _unitName
end
end end
end end
self:T( { _spawnedGroup, _alias } ) self:T( { _spawnedGroup, _alias } )
@@ -667,7 +693,7 @@ function CSAR:_AddCsar(_coalition , _country, _point, _typeName, _unitName, _pla
self:_CreateDownedPilotTrack( _spawnedGroup, _GroupName, _coalition, _unitName, _text, _typeName, _freq, _playerName ) self:_CreateDownedPilotTrack( _spawnedGroup, _GroupName, _coalition, _unitName, _text, _typeName, _freq, _playerName )
self:_InitSARForPilot(_spawnedGroup, _GroupName, _freq, noMessage) self:_InitSARForPilot( _spawnedGroup, _unitName, _freq, noMessage ) -- shagrat use unitName to have the aircraft callsign / descriptive "name" etc.
return self return self
end end
@@ -678,7 +704,7 @@ end
-- @param #number _coalition Coalition. -- @param #number _coalition Coalition.
-- @param #string _description (optional) Description. -- @param #string _description (optional) Description.
-- @param #boolean _randomPoint (optional) Random yes or no. -- @param #boolean _randomPoint (optional) Random yes or no.
-- @param #boolean _nomessage (optional) If true, don\'t send a message to SAR. -- @param #boolean _nomessage (optional) If true, don't send a message to SAR.
-- @param #string unitname (optional) Name of the lost unit. -- @param #string unitname (optional) Name of the lost unit.
-- @param #string typename (optional) Type of plane. -- @param #string typename (optional) Type of plane.
-- @param #boolean forcedesc (optional) Force to use the description passed only for the pilot track entry. Use to have fully custom names. -- @param #boolean forcedesc (optional) Force to use the description passed only for the pilot track entry. Use to have fully custom names.
@@ -723,7 +749,7 @@ end
-- @param #number Coalition Coalition. -- @param #number Coalition Coalition.
-- @param #string Description (optional) Description. -- @param #string Description (optional) Description.
-- @param #boolean RandomPoint (optional) Random yes or no. -- @param #boolean RandomPoint (optional) Random yes or no.
-- @param #boolean Nomessage (optional) If true, don\'t send a message to SAR. -- @param #boolean Nomessage (optional) If true, don't send a message to SAR.
-- @param #string Unitname (optional) Name of the lost unit. -- @param #string Unitname (optional) Name of the lost unit.
-- @param #string Typename (optional) Type of plane. -- @param #string Typename (optional) Type of plane.
-- @param #boolean Forcedesc (optional) Force to use the **description passed only** for the pilot track entry. Use to have fully custom names. -- @param #boolean Forcedesc (optional) Force to use the **description passed only** for the pilot track entry. Use to have fully custom names.
@@ -736,6 +762,58 @@ function CSAR:SpawnCSARAtZone(Zone, Coalition, Description, RandomPoint, Nomessa
return self return self
end end
--- (Internal) Function to add a CSAR object into the scene at a Point coordinate (VEC_2). For mission designers wanting to add e.g. casualties to the scene, that don't use beacons.
-- @param #CSAR self
-- @param #string _Point a POINT_VEC2.
-- @param #number _coalition Coalition.
-- @param #string _description (optional) Description.
-- @param #boolean _nomessage (optional) If true, don't send a message to SAR.
-- @param #string unitname (optional) Name of the lost unit.
-- @param #string typename (optional) Type of plane.
-- @param #boolean forcedesc (optional) Force to use the description passed only for the pilot track entry. Use to have fully custom names.
function CSAR:_SpawnCASEVAC( _Point, _coalition, _description, _nomessage, unitname, typename, forcedesc ) -- shagrat added internal Function _SpawnCASEVAC
self:T( self.lid .. " _SpawnCASEVAC" )
local _description = _description or "CASEVAC"
local unitname = unitname or "CASEVAC"
local typename = typename or "Ground Commander"
local pos = {}
pos = _Point
local _country = 0
if _coalition == coalition.side.BLUE then
_country = self.countryblue
elseif _coalition == coalition.side.RED then
_country = self.countryred
else
_country = self.countryneutral
end
-- shagrat set frequency to 0 as "flag" for no beacon
self:_AddCsar( _coalition, _country, pos, typename, unitname, _description, 0, _nomessage, _description, forcedesc )
return self
end
--- Function to add a CSAR object into the scene at a zone coordinate. For mission designers wanting to add e.g. PoWs to the scene.
-- @param #CSAR self
-- @param #string Point a POINT_VEC2.
-- @param #number Coalition Coalition.
-- @param #string Description (optional) Description.
-- @param #boolean addBeacon (optional) yes or no.
-- @param #boolean Nomessage (optional) If true, don't send a message to SAR.
-- @param #string Unitname (optional) Name of the lost unit.
-- @param #string Typename (optional) Type of plane.
-- @param #boolean Forcedesc (optional) Force to use the **description passed only** for the pilot track entry. Use to have fully custom names.
-- @usage If missions designers want to spawn downed pilots into the field, e.g. at mission begin, to give the helicopter guys work, they can do this like so:
--
-- -- Create casualty "CASEVAC" at Point #POINT_VEC2 for the blue coalition.
-- my_csar:SpawnCASEVAC( POINT_VEC2, coalition.side.BLUE )
function CSAR:SpawnCASEVAC( Point, Coalition, Description, Nomessage, Unitname, Typename, Forcedesc )
self:_SpawnCASEVAC( Point, Coalition, Description, Nomessage, Unitname, Typename, Forcedesc )
return self
end -- shagrat end added CASEVAC
--- (Internal) Event handler. --- (Internal) Event handler.
-- @param #CSAR self -- @param #CSAR self
function CSAR:_EventHandler( EventData ) function CSAR:_EventHandler( EventData )
@@ -744,6 +822,11 @@ function CSAR:_EventHandler(EventData)
local _event = EventData -- Core.Event#EVENTDATA local _event = EventData -- Core.Event#EVENTDATA
-- no Player
if self.enableForAI == false and _event.IniPlayerName == nil then
return
end
-- no event -- no event
if _event == nil or _event.initiator == nil then if _event == nil or _event.initiator == nil then
return false return false
@@ -833,10 +916,6 @@ function CSAR:_EventHandler(EventData)
return -- ignore! return -- ignore!
end end
if self.enableForAI == false and _event.IniPlayerName == nil then
return
end
if not self.takenOff[_event.IniUnitName] and not _group:IsAirborne() then if not self.takenOff[_event.IniUnitName] and not _group:IsAirborne() then
self:T( self.lid .. " Pilot has not taken off, ignore" ) self:T( self.lid .. " Pilot has not taken off, ignore" )
return -- give up, pilot hasnt taken off return -- give up, pilot hasnt taken off
@@ -852,9 +931,27 @@ function CSAR:_EventHandler(EventData)
end end
-- all checks passed, get going. -- all checks passed, get going.
if self.csarUsePara == false then -- shagrat check parameter LandingAfterEjection, if true don't spawn a Pilot from EJECTION event, wait for the Chute to land
local _freq = self:_GenerateADFFrequency() local _freq = self:_GenerateADFFrequency()
self:_AddCsar( _coalition, _unit:GetCountry(), _unit:GetCoordinate(), _unit:GetTypeName(), _unit:GetName(), _event.IniPlayerName, _freq, false, "none" ) self:_AddCsar( _coalition, _unit:GetCountry(), _unit:GetCoordinate(), _unit:GetTypeName(), _unit:GetName(), _event.IniPlayerName, _freq, false, "none" )
return true
end
---- shagrat on event LANDING_AFTER_EJECTION spawn pilot at parachute location
elseif (_event.id == EVENTS.LandingAfterEjection and self.csarUsePara == true) then
self:I( { EVENT = _event } )
local _LandingPos = COORDINATE:NewFromVec3( _event.initiator:getPosition().p )
local _unitname = "Aircraft" -- _event.initiator:getName() or "Aircraft" --shagrat Optional use of Object name which is unfortunately 'f15_Pilot_Parachute'
local _typename = "Ejected Pilot" -- _event.Initiator.getTypeName() or "Ejected Pilot"
local _country = _event.initiator:getCountry()
local _coalition = coalition.getCountryCoalition( _country )
if _coalition == self.coalition then
local _freq = self:_GenerateADFFrequency()
self:I( { coalition = _coalition, country = _country, coord = _LandingPos, name = _unitname, player = _event.IniPlayerName, freq = _freq } )
self:_AddCsar( _coalition, _country, _LandingPos, nil, _unitname, _event.IniPlayerName, _freq, false, "none" ) -- shagrat add CSAR at Parachute location.
Unit.destroy( _event.initiator ) -- shagrat remove static Pilot model
end
return true return true
elseif _event.id == EVENTS.Land then elseif _event.id == EVENTS.Land then
@@ -920,8 +1017,13 @@ function CSAR:_InitSARForPilot(_downedGroup, _GroupName, _freq, _nomessage)
local _leadername = _leader:GetName() local _leadername = _leader:GetName()
if not _nomessage then if not _nomessage then
local _text = string.format("%s requests SAR at %s, beacon at %.2f KHz", _leadername, _coordinatesText, _freqk) if _freq ~= 0 then -- shagrat
local _text = string.format( "%s requests SAR at %s, beacon at %.2f KHz", _groupName, _coordinatesText, _freqk ) -- shagrat _groupName to prevent 'f15_Pilot_Parachute'
self:_DisplayToAllSAR( _text, self.coalition, self.messageTime ) self:_DisplayToAllSAR( _text, self.coalition, self.messageTime )
else -- shagrat CASEVAC msg
local _text = string.format( "Pickup Zone at %s.", _coordinatesText )
self:_DisplayToAllSAR( _text, self.coalition, self.messageTime )
end
end end
for _, _heliName in pairs( self.csarUnits ) do for _, _heliName in pairs( self.csarUnits ) do
@@ -1010,7 +1112,7 @@ function CSAR:_CheckWoundedGroupStatus(heliname,woundedgroupname)
if _distance < self.approachdist_near and _distance > 0 then if _distance < self.approachdist_near and _distance > 0 then
if self:_CheckCloseWoundedGroup( _distance, _heliUnit, _heliName, _woundedGroup, _woundedGroupName ) == true then if self:_CheckCloseWoundedGroup( _distance, _heliUnit, _heliName, _woundedGroup, _woundedGroupName ) == true then
-- we\'re close, reschedule -- we're close, reschedule
_downedpilot.timestamp = timer.getAbsTime() _downedpilot.timestamp = timer.getAbsTime()
self:__Approach( -5, heliname, woundedgroupname ) self:__Approach( -5, heliname, woundedgroupname )
end end
@@ -1025,16 +1127,16 @@ function CSAR:_CheckWoundedGroupStatus(heliname,woundedgroupname)
local dist = UTILS.MetersToNM( self.autosmokedistance ) local dist = UTILS.MetersToNM( self.autosmokedistance )
disttext = string.format( "%.0fnm", dist ) disttext = string.format( "%.0fnm", dist )
end end
self:_DisplayMessageToSAR(_heliUnit, string.format("%s: %s. I hear you! Damn, that thing is loud!\nI'll pop a smoke when you are %s away.\nLand or hover by the smoke.", _heliName, _pilotName, disttext), self.messageTime,false,true) self:_DisplayMessageToSAR( _heliUnit, string.format( "%s: %s. I hear you! Finally, that is music in my ears!\nI'll pop a smoke when you are %s away.\nLand or hover by the smoke.", _heliName, _pilotName, disttext ), self.messageTime, false, true )
else else
self:_DisplayMessageToSAR(_heliUnit, string.format("%s: %s. I hear you! Damn, that thing is loud!\nRequest a flare or smoke if you need.", _heliName, _pilotName), self.messageTime,false,true) self:_DisplayMessageToSAR( _heliUnit, string.format( "%s: %s. I hear you! Finally, that is music in my ears!\nRequest a flare or smoke if you need.", _heliName, _pilotName ), self.messageTime, false, true )
end end
-- mark as shown for THIS heli and THIS group -- mark as shown for THIS heli and THIS group
self.heliVisibleMessage[_lookupKeyHeli] = true self.heliVisibleMessage[_lookupKeyHeli] = true
end end
self.heliCloseMessage[_lookupKeyHeli] = nil self.heliCloseMessage[_lookupKeyHeli] = nil
self.landedStatus[_lookupKeyHeli] = nil self.landedStatus[_lookupKeyHeli] = nil
--reschedule as units aren\'t dead yet , schedule for a bit slower though as we\'re far away -- reschedule as units aren't dead yet , schedule for a bit slower though as we're far away
_downedpilot.timestamp = timer.getAbsTime() _downedpilot.timestamp = timer.getAbsTime()
self:__Approach( -10, heliname, woundedgroupname ) self:__Approach( -10, heliname, woundedgroupname )
end end
@@ -1048,7 +1150,7 @@ function CSAR:_CheckWoundedGroupStatus(heliname,woundedgroupname)
return self return self
end end
--- (Internal) Function to pop a smoke at a wounded pilot\'s positions. --- (Internal) Function to pop a smoke at a wounded pilot's positions.
-- @param #CSAR self -- @param #CSAR self
-- @param #string _woundedGroupName Name of the group. -- @param #string _woundedGroupName Name of the group.
-- @param Wrapper.Group#GROUP _woundedLeader Object of the group. -- @param Wrapper.Group#GROUP _woundedLeader Object of the group.
@@ -1059,7 +1161,7 @@ function CSAR:_PopSmokeForGroup(_woundedGroupName, _woundedLeader)
if _lastSmoke == nil or timer.getTime() > _lastSmoke then if _lastSmoke == nil or timer.getTime() > _lastSmoke then
local _smokecolor = self.smokecolor local _smokecolor = self.smokecolor
local _smokecoord = _woundedLeader:GetCoordinate() local _smokecoord = _woundedLeader:GetCoordinate():Translate( 6, math.random( 1, 360 ) ) -- shagrat place smoke at a random 6 m distance, so smoke does not obscure the pilot
_smokecoord:Smoke( _smokecolor ) _smokecoord:Smoke( _smokecolor )
self.smokeMarkers[_woundedGroupName] = timer.getTime() + 300 -- next smoke time self.smokeMarkers[_woundedGroupName] = timer.getTime() + 300 -- next smoke time
end end
@@ -1097,14 +1199,7 @@ function CSAR:_PickupUnit(_heliUnit, _pilotName, _woundedGroup, _woundedGroupNam
local found, downedgrouptable = self:_CheckNameInDownedPilots( _woundedGroupName ) local found, downedgrouptable = self:_CheckNameInDownedPilots( _woundedGroupName )
local grouptable = downedgrouptable -- #CSAR.DownedPilot local grouptable = downedgrouptable -- #CSAR.DownedPilot
self.inTransitGroups[_heliName][_woundedGroupName] = self.inTransitGroups[_heliName][_woundedGroupName] = { originalUnit = grouptable.originalUnit, woundedGroup = _woundedGroupName, side = self.coalition, desc = grouptable.desc, player = grouptable.player }
{
originalUnit = grouptable.originalUnit,
woundedGroup = _woundedGroupName,
side = self.coalition,
desc = grouptable.desc,
player = grouptable.player,
}
_woundedGroup:Destroy( false ) _woundedGroup:Destroy( false )
self:_RemoveNameFromDownedPilots( _woundedGroupName, true ) self:_RemoveNameFromDownedPilots( _woundedGroupName, true )
@@ -1130,7 +1225,6 @@ function CSAR:_OrderGroupToMoveToPoint(_leader, _destination)
return self return self
end end
--- (internal) Function to check if the heli door(s) are open. Thanks to Shadowze. --- (internal) Function to check if the heli door(s) are open. Thanks to Shadowze.
-- @param #CSAR self -- @param #CSAR self
-- @param #string unit_name Name of unit. -- @param #string unit_name Name of unit.
@@ -1157,7 +1251,6 @@ function CSAR:_CheckCloseWoundedGroup(_distance, _heliUnit, _heliName, _woundedG
local _found, _pilotable = self:_CheckNameInDownedPilots( _woundedGroupName ) -- #boolean, #CSAR.DownedPilot local _found, _pilotable = self:_CheckNameInDownedPilots( _woundedGroupName ) -- #boolean, #CSAR.DownedPilot
local _pilotName = _pilotable.desc local _pilotName = _pilotable.desc
local _reset = true local _reset = true
if (_distance < 500) then if (_distance < 500) then
@@ -1222,7 +1315,9 @@ function CSAR:_CheckCloseWoundedGroup(_distance, _heliUnit, _heliName, _woundedG
-- check height! -- check height!
local leaderheight = _woundedLeader:GetHeight() local leaderheight = _woundedLeader:GetHeight()
if leaderheight < 0 then leaderheight = 0 end if leaderheight < 0 then
leaderheight = 0
end
local _height = _heliUnit:GetHeight() - leaderheight local _height = _heliUnit:GetHeight() - leaderheight
-- TODO - make variable -- TODO - make variable
@@ -1359,12 +1454,13 @@ end
-- @param #number _time Message show duration. -- @param #number _time Message show duration.
-- @param #boolean _clear (optional) Clear screen. -- @param #boolean _clear (optional) Clear screen.
-- @param #boolean _speak (optional) Speak message via SRS. -- @param #boolean _speak (optional) Speak message via SRS.
function CSAR:_DisplayMessageToSAR(_unit, _text, _time, _clear, _speak) -- @param #boolean _override (optional) Override message suppression
function CSAR:_DisplayMessageToSAR( _unit, _text, _time, _clear, _speak, _override )
self:T( self.lid .. " _DisplayMessageToSAR" ) self:T( self.lid .. " _DisplayMessageToSAR" )
local group = _unit:GetGroup() local group = _unit:GetGroup()
local _clear = _clear or nil local _clear = _clear or nil
local _time = _time or self.messageTime local _time = _time or self.messageTime
if not self.suppressmessages then if _override or not self.suppressmessages then
local m = MESSAGE:New( _text, _time, "Info", _clear ):ToGroup( group ) local m = MESSAGE:New( _text, _time, "Info", _clear ):ToGroup( group )
end end
-- integrate SRS -- integrate SRS
@@ -1379,7 +1475,7 @@ function CSAR:_DisplayMessageToSAR(_unit, _text, _time, _clear, _speak)
return self return self
end end
--- (Internal) Function to get string of a group\'s position. --- (Internal) Function to get string of a group's position.
-- @param #CSAR self -- @param #CSAR self
-- @param Wrapper.Controllable#CONTROLLABLE _woundedGroup Group or Unit object. -- @param Wrapper.Controllable#CONTROLLABLE _woundedGroup Group or Unit object.
-- @return #string Coordinates as Text -- @return #string Coordinates as Text
@@ -1434,9 +1530,13 @@ function CSAR:_DisplayActiveSAR(_unitName)
else else
distancetext = string.format( "%.1fkm", _distance / 1000.0 ) distancetext = string.format( "%.1fkm", _distance / 1000.0 )
end end
if _value.frequency == 0 then -- shagrat insert CASEVAC without Frequency
table.insert( _csarList, { dist = _distance, msg = string.format( "%s at %s - %s ", _value.desc, _coordinatesText, distancetext ) } )
else
table.insert( _csarList, { dist = _distance, msg = string.format( "%s at %s - %.2f KHz ADF - %s ", _value.desc, _coordinatesText, _value.frequency / 1000, distancetext ) } ) table.insert( _csarList, { dist = _distance, msg = string.format( "%s at %s - %.2f KHz ADF - %s ", _value.desc, _coordinatesText, _value.frequency / 1000, distancetext ) } )
end end
end end
end
local function sortDistance( a, b ) local function sortDistance( a, b )
return a.dist < b.dist return a.dist < b.dist
@@ -1448,7 +1548,7 @@ function CSAR:_DisplayActiveSAR(_unitName)
_msg = _msg .. "\n" .. _line.msg _msg = _msg .. "\n" .. _line.msg
end end
self:_DisplayMessageToSAR(_heli, _msg, self.messageTime*2) self:_DisplayMessageToSAR( _heli, _msg, self.messageTime * 2, false, false, true )
return self return self
end end
@@ -1505,8 +1605,10 @@ function CSAR:_SignalFlare(_unitName)
local _closest = self:_GetClosestDownedPilot( _heli ) local _closest = self:_GetClosestDownedPilot( _heli )
local smokedist = 8000 local smokedist = 8000
if self.approachdist_far > smokedist then smokedist = self.approachdist_far end if self.approachdist_far > smokedist then
if _closest ~= nil and _closest.pilot ~= nil and _closest.distance < smokedist then smokedist = self.approachdist_far
end
if _closest ~= nil and _closest.pilot ~= nil and _closest.distance > 0 and _closest.distance < smokedist then
local _clockDir = self:_GetClockDirection( _heli, _closest.pilot ) local _clockDir = self:_GetClockDirection( _heli, _closest.pilot )
local _distance = 0 local _distance = 0
@@ -1516,7 +1618,7 @@ function CSAR:_SignalFlare(_unitName)
_distance = string.format( "%.1fkm", _closest.distance ) _distance = string.format( "%.1fkm", _closest.distance )
end end
local _msg = string.format( "%s - Popping signal flare at your %s o\'clock. Distance %s", _unitName, _clockDir, _distance ) local _msg = string.format( "%s - Popping signal flare at your %s o\'clock. Distance %s", _unitName, _clockDir, _distance )
self:_DisplayMessageToSAR(_heli, _msg, self.messageTime, false, true) self:_DisplayMessageToSAR( _heli, _msg, self.messageTime, false, true, true )
local _coord = _closest.pilot:GetCoordinate() local _coord = _closest.pilot:GetCoordinate()
_coord:FlareRed( _clockDir ) _coord:FlareRed( _clockDir )
@@ -1527,7 +1629,7 @@ function CSAR:_SignalFlare(_unitName)
else else
_distance = string.format( "%.1fkm", smokedist / 1000 ) _distance = string.format( "%.1fkm", smokedist / 1000 )
end end
self:_DisplayMessageToSAR(_heli, string.format("No Pilots within %s",_distance), self.messageTime) self:_DisplayMessageToSAR( _heli, string.format( "No Pilots within %s", _distance ), self.messageTime, false, false, true )
end end
return self return self
end end
@@ -1559,18 +1661,20 @@ function CSAR:_Reqsmoke( _unitName )
return return
end end
local smokedist = 8000 local smokedist = 8000
if smokedist < self.approachdist_far then smokedist = self.approachdist_far end if smokedist < self.approachdist_far then
smokedist = self.approachdist_far
end
local _closest = self:_GetClosestDownedPilot( _heli ) local _closest = self:_GetClosestDownedPilot( _heli )
if _closest ~= nil and _closest.pilot ~= nil and _closest.distance < smokedist then if _closest ~= nil and _closest.pilot ~= nil and _closest.distance > 0 and _closest.distance < smokedist then
local _clockDir = self:_GetClockDirection( _heli, _closest.pilot ) local _clockDir = self:_GetClockDirection( _heli, _closest.pilot )
local _distance = 0 local _distance = 0
if _SETTINGS:IsImperial() then if _SETTINGS:IsImperial() then
_distance = string.format( "%.1fnm", UTILS.MetersToNM( _closest.distance ) ) _distance = string.format( "%.1fnm", UTILS.MetersToNM( _closest.distance ) )
else else
_distance = string.format("%.1fkm",_closest.distance) _distance = string.format( "%.1fkm", _closest.distance / 1000 )
end end
local _msg = string.format("%s - Popping signal smoke at your %s o\'clock. Distance %s", _unitName, _clockDir, _distance) local _msg = string.format( "%s - Popping smoke at your %s o\'clock. Distance %s", _unitName, _clockDir, _distance )
self:_DisplayMessageToSAR(_heli, _msg, self.messageTime, false, true) self:_DisplayMessageToSAR( _heli, _msg, self.messageTime, false, true, true )
local _coord = _closest.pilot:GetCoordinate() local _coord = _closest.pilot:GetCoordinate()
local color = self.smokecolor local color = self.smokecolor
_coord:Smoke( color ) _coord:Smoke( color )
@@ -1581,7 +1685,7 @@ function CSAR:_Reqsmoke( _unitName )
else else
_distance = string.format( "%.1fkm", smokedist / 1000 ) _distance = string.format( "%.1fkm", smokedist / 1000 )
end end
self:_DisplayMessageToSAR(_heli, string.format("No Pilots within %s",_distance), self.messageTime) self:_DisplayMessageToSAR( _heli, string.format( "No Pilots within %s", _distance ), self.messageTime, false, false, true )
end end
return self return self
end end
@@ -1653,13 +1757,13 @@ function CSAR:_CheckOnboard(_unitName)
-- list onboard pilots -- list onboard pilots
local _inTransit = self.inTransitGroups[_unitName] local _inTransit = self.inTransitGroups[_unitName]
if _inTransit == nil then if _inTransit == nil then
self:_DisplayMessageToSAR(_unit, "No Rescued Pilots onboard", self.messageTime) self:_DisplayMessageToSAR( _unit, "No Rescued Pilots onboard", self.messageTime, false, false, true )
else else
local _text = "Onboard - RTB to FARP/Airfield or MASH: " local _text = "Onboard - RTB to FARP/Airfield or MASH: "
for _, _onboard in pairs( self.inTransitGroups[_unitName] ) do for _, _onboard in pairs( self.inTransitGroups[_unitName] ) do
_text = _text .. "\n" .. _onboard.desc _text = _text .. "\n" .. _onboard.desc
end end
self:_DisplayMessageToSAR(_unit, _text, self.messageTime*2) self:_DisplayMessageToSAR( _unit, _text, self.messageTime * 2, false, false, true )
end end
return self return self
end end
@@ -1775,9 +1879,13 @@ function CSAR:_GetClockDirection(_heli, _group)
local clock = 12 local clock = 12
if _heading then if _heading then
local Aspect = Angle - _heading local Aspect = Angle - _heading
if Aspect == 0 then Aspect = 360 end if Aspect == 0 then
Aspect = 360
end
clock = math.abs( UTILS.Round( (Aspect / 30), 0 ) ) clock = math.abs( UTILS.Round( (Aspect / 30), 0 ) )
if clock == 0 then clock = 12 end if clock == 0 then
clock = 12
end
end end
return clock return clock
end end
@@ -1875,6 +1983,7 @@ function CSAR:onafterStart(From, Event, To)
self:HandleEvent( EVENTS.Takeoff, self._EventHandler ) self:HandleEvent( EVENTS.Takeoff, self._EventHandler )
self:HandleEvent( EVENTS.Land, self._EventHandler ) self:HandleEvent( EVENTS.Land, self._EventHandler )
self:HandleEvent( EVENTS.Ejection, self._EventHandler ) self:HandleEvent( EVENTS.Ejection, self._EventHandler )
self:HandleEvent( EVENTS.LandingAfterEjection, self._EventHandler ) -- shagrat
self:HandleEvent( EVENTS.PlayerEnterAircraft, self._EventHandler ) self:HandleEvent( EVENTS.PlayerEnterAircraft, self._EventHandler )
self:HandleEvent( EVENTS.PlayerEnterUnit, self._EventHandler ) self:HandleEvent( EVENTS.PlayerEnterUnit, self._EventHandler )
self:HandleEvent( EVENTS.PilotDead, self._EventHandler ) self:HandleEvent( EVENTS.PilotDead, self._EventHandler )
@@ -1918,7 +2027,12 @@ function CSAR:onbeforeStatus(From, Event, To)
self:T( { From, Event, To } ) self:T( { From, Event, To } )
-- housekeeping -- housekeeping
self:_AddMedevacMenuItem() self:_AddMedevacMenuItem()
self:_RefreshRadioBeacons()
if not self.BeaconTimer or (self.BeaconTimer and not self.BeaconTimer:IsRunning()) then
self.BeaconTimer = TIMER:New( self._RefreshRadioBeacons, self )
self.BeaconTimer:Start( 2, self.beaconRefresher )
end
self:_CheckDownedPilotTable() self:_CheckDownedPilotTable()
for _, _sar in pairs( self.csarUnits ) do for _, _sar in pairs( self.csarUnits ) do
local PilotTable = self.downedPilots local PilotTable = self.downedPilots
@@ -1928,7 +2042,7 @@ function CSAR:onbeforeStatus(From, Event, To)
local name = entry.name local name = entry.name
local timestamp = entry.timestamp or 0 local timestamp = entry.timestamp or 0
local now = timer.getAbsTime() local now = timer.getAbsTime()
if now - timestamp > 17 then -- only check if we\'re not in approach mode, which is iterations of 5 and 10. if now - timestamp > 17 then -- only check if we're not in approach mode, which is iterations of 5 and 10.
self:_CheckWoundedGroupStatus( _sar, name ) self:_CheckWoundedGroupStatus( _sar, name )
end end
end end
@@ -1960,8 +2074,7 @@ function CSAR:onafterStatus(From, Event, To)
end end
if self.verbose > 0 then if self.verbose > 0 then
local text = string.format("%s Active SAR: %d | Downed Pilots in field: %d (max %d) | Pilots boarded: %d | Landings: %d | Pilots rescued: %d", local text = string.format( "%s Active SAR: %d | Downed Pilots in field: %d (max %d) | Pilots boarded: %d | Landings: %d | Pilots rescued: %d", self.lid, NumberOfSARPilots, PilotsInFieldN, self.maxdownedpilots, PilotsBoarded, self.rescues, self.rescuedpilots )
self.lid,NumberOfSARPilots,PilotsInFieldN,self.maxdownedpilots,PilotsBoarded,self.rescues,self.rescuedpilots)
self:T( text ) self:T( text )
if self.verbose < 2 then if self.verbose < 2 then
self:I( text ) self:I( text )
@@ -1985,6 +2098,7 @@ function CSAR:onafterStop(From, Event, To)
self:UnHandleEvent( EVENTS.Takeoff ) self:UnHandleEvent( EVENTS.Takeoff )
self:UnHandleEvent( EVENTS.Land ) self:UnHandleEvent( EVENTS.Land )
self:UnHandleEvent( EVENTS.Ejection ) self:UnHandleEvent( EVENTS.Ejection )
self:UnHandleEvent( EVENTS.LandingAfterEjection ) -- shagrat
self:UnHandleEvent( EVENTS.PlayerEnterUnit ) self:UnHandleEvent( EVENTS.PlayerEnterUnit )
self:UnHandleEvent( EVENTS.PlayerEnterAircraft ) self:UnHandleEvent( EVENTS.PlayerEnterAircraft )
self:UnHandleEvent( EVENTS.PilotDead ) self:UnHandleEvent( EVENTS.PilotDead )
@@ -1998,7 +2112,7 @@ end
-- @param #string Event Event triggered. -- @param #string Event Event triggered.
-- @param #string To To state. -- @param #string To To state.
-- @param #string Heliname Name of the helicopter group. -- @param #string Heliname Name of the helicopter group.
-- @param #string Woundedgroupname Name of the downed pilot\'s group. -- @param #string Woundedgroupname Name of the downed pilot's group.
function CSAR:onbeforeApproach( From, Event, To, Heliname, Woundedgroupname ) function CSAR:onbeforeApproach( From, Event, To, Heliname, Woundedgroupname )
self:T( { From, Event, To, Heliname, Woundedgroupname } ) self:T( { From, Event, To, Heliname, Woundedgroupname } )
self:_CheckWoundedGroupStatus( Heliname, Woundedgroupname ) self:_CheckWoundedGroupStatus( Heliname, Woundedgroupname )
@@ -2011,7 +2125,7 @@ end
-- @param #string Event Event triggered. -- @param #string Event Event triggered.
-- @param #string To To state. -- @param #string To To state.
-- @param #string Heliname Name of the helicopter group. -- @param #string Heliname Name of the helicopter group.
-- @param #string Woundedgroupname Name of the downed pilot\'s group. -- @param #string Woundedgroupname Name of the downed pilot's group.
function CSAR:onbeforeBoarded( From, Event, To, Heliname, Woundedgroupname ) function CSAR:onbeforeBoarded( From, Event, To, Heliname, Woundedgroupname )
self:T( { From, Event, To, Heliname, Woundedgroupname } ) self:T( { From, Event, To, Heliname, Woundedgroupname } )
self:_ScheduledSARFlight( Heliname, Woundedgroupname ) self:_ScheduledSARFlight( Heliname, Woundedgroupname )
@@ -2024,7 +2138,7 @@ end
-- @param #string Event Event triggered. -- @param #string Event Event triggered.
-- @param #string To To state. -- @param #string To To state.
-- @param #string Heliname Name of the helicopter group. -- @param #string Heliname Name of the helicopter group.
-- @param #string Woundedgroupname Name of the downed pilot\'s group. -- @param #string Woundedgroupname Name of the downed pilot's group.
-- @param #boolean IsAirport True if heli has landed on an AFB (from event land). -- @param #boolean IsAirport True if heli has landed on an AFB (from event land).
function CSAR:onbeforeReturning( From, Event, To, Heliname, Woundedgroupname, IsAirPort ) function CSAR:onbeforeReturning( From, Event, To, Heliname, Woundedgroupname, IsAirPort )
self:T( { From, Event, To, Heliname, Woundedgroupname } ) self:T( { From, Event, To, Heliname, Woundedgroupname } )

View File

@@ -22,7 +22,7 @@
-- @module Ops.CTLD -- @module Ops.CTLD
-- @image OPS_CTLD.jpg -- @image OPS_CTLD.jpg
-- Date: Oct 2021 -- Date: Dec 2021
do do
------------------------------------------------------ ------------------------------------------------------
@@ -318,7 +318,8 @@ CTLD_CARGO = {
ClassName = "CTLD_CARGO", ClassName = "CTLD_CARGO",
ID = 0, ID = 0,
Name = "none", Name = "none",
Templates = {}, Templates = {
},
CargoType = "none", CargoType = "none",
HasBeenMoved = false, HasBeenMoved = false,
LoadDirectly = false, LoadDirectly = false,
@@ -348,7 +349,7 @@ CTLD_CARGO = {
-- @param #number ID ID of this #CTLD_CARGO -- @param #number ID ID of this #CTLD_CARGO
-- @param #string Name Name for menu. -- @param #string Name Name for menu.
-- @param #table Templates Table of #POSITIONABLE objects. -- @param #table Templates Table of #POSITIONABLE objects.
-- @param #CTLD_CARGO.Enum Sorte Enumerator of Type. -- @param #CTLD_CARGO.Enum SortEnum Enumerator of Type.
-- @param #boolean HasBeenMoved Flag for moving. -- @param #boolean HasBeenMoved Flag for moving.
-- @param #boolean LoadDirectly Flag for direct loading. -- @param #boolean LoadDirectly Flag for direct loading.
-- @param #number CratesNeeded Crates needed to build. -- @param #number CratesNeeded Crates needed to build.
@@ -357,14 +358,14 @@ CTLD_CARGO = {
-- @param #number PerCrateMass Mass in kg -- @param #number PerCrateMass Mass in kg
-- @param #number Stock Number of builds available, nil for unlimited -- @param #number Stock Number of builds available, nil for unlimited
-- @return #CTLD_CARGO self -- @return #CTLD_CARGO self
function CTLD_CARGO:New(ID, Name, Templates, Sorte, HasBeenMoved, LoadDirectly, CratesNeeded, Positionable, Dropped, PerCrateMass, Stock) function CTLD_CARGO:New( ID, Name, Templates, SortEnum, HasBeenMoved, LoadDirectly, CratesNeeded, Positionable, Dropped, PerCrateMass, Stock )
-- Inherit everything from BASE class. -- Inherit everything from BASE class.
local self = BASE:Inherit( self, BASE:New() ) -- #CTLD local self = BASE:Inherit( self, BASE:New() ) -- #CTLD
self:T({ID, Name, Templates, Sorte, HasBeenMoved, LoadDirectly, CratesNeeded, Positionable, Dropped}) self:T( { ID, Name, Templates, SortEnum, HasBeenMoved, LoadDirectly, CratesNeeded, Positionable, Dropped } )
self.ID = ID or math.random( 100000, 1000000 ) self.ID = ID or math.random( 100000, 1000000 )
self.Name = Name or "none" -- #string self.Name = Name or "none" -- #string
self.Templates = Templates or {} -- #table self.Templates = Templates or {} -- #table
self.CargoType = Sorte or "type" -- #CTLD_CARGO.Enum self.CargoType = SortEnum or "type" -- #CTLD_CARGO.Enum
self.HasBeenMoved = HasBeenMoved or false -- #boolean self.HasBeenMoved = HasBeenMoved or false -- #boolean
self.LoadDirectly = LoadDirectly or false -- #boolean self.LoadDirectly = LoadDirectly or false -- #boolean
self.CratesNeeded = CratesNeeded or 0 -- #number self.CratesNeeded = CratesNeeded or 0 -- #number
@@ -501,7 +502,9 @@ CTLD_CARGO = {
if self.Stock then -- Stock nil? if self.Stock then -- Stock nil?
local number = Number or 1 local number = Number or 1
self.Stock = self.Stock - number self.Stock = self.Stock - number
if self.Stock < 0 then self.Stock = 0 end if self.Stock < 0 then
self.Stock = 0
end
end end
return self return self
end end
@@ -554,7 +557,7 @@ do
-- @field #number coalition Coalition side number, e.g. `coalition.side.RED`. -- @field #number coalition Coalition side number, e.g. `coalition.side.RED`.
-- @extends Core.Fsm#FSM -- @extends Core.Fsm#FSM
--- *Combat Troop & Logistics Deployment (CTLD): Everyone wants to be a POG, until there\'s POG stuff to be done.* (Mil Saying) --- *Combat Troop & Logistics Deployment (CTLD): Everyone wants to be a POG, until there's POG stuff to be done.* (Mil Saying)
-- --
-- === -- ===
-- --
@@ -563,7 +566,7 @@ do
-- # CTLD Concept -- # CTLD Concept
-- --
-- * MOOSE-based CTLD for Players. -- * MOOSE-based CTLD for Players.
-- * Object oriented refactoring of Ciribob\'s fantastic CTLD script. -- * Object oriented refactoring of Ciribob's fantastic CTLD script.
-- * No need for extra MIST loading. -- * No need for extra MIST loading.
-- * Additional events to tailor your mission. -- * Additional events to tailor your mission.
-- * ANY late activated group can serve as cargo, either as troops, crates, which have to be build on-location, or static like ammo chests. -- * ANY late activated group can serve as cargo, either as troops, crates, which have to be build on-location, or static like ammo chests.
@@ -571,7 +574,7 @@ do
-- --
-- ## 0. Prerequisites -- ## 0. Prerequisites
-- --
-- You need to load an .ogg soundfile for the pilot\'s beacons into the mission, e.g. "beacon.ogg", use a once trigger, "sound to country" for that. -- You need to load an .ogg sound file for the pilot's beacons into the mission, e.g. "beacon.ogg", use a once trigger, "sound to country" for that.
-- Create the late-activated troops, vehicles (no statics at this point!) that will make up your deployable forces. -- Create the late-activated troops, vehicles (no statics at this point!) that will make up your deployable forces.
-- --
-- ## 1. Basic Setup -- ## 1. Basic Setup
@@ -598,7 +601,7 @@ do
-- my_ctld:AddTroopsCargo("Anti-Air",{"AA","AA2"},CTLD_CARGO.Enum.TROOPS,4,nil,2) -- my_ctld:AddTroopsCargo("Anti-Air",{"AA","AA2"},CTLD_CARGO.Enum.TROOPS,4,nil,2)
-- --
-- -- add an engineers unit called "Wrenches" using template "Engineers", of type ENGINEERS with size 2. Engineers can be loaded, dropped, -- -- add an engineers unit called "Wrenches" using template "Engineers", of type ENGINEERS with size 2. Engineers can be loaded, dropped,
-- -- and extracted like troops. However, they will seek to build and/or repair crates found in a given radius. Handy if you can\'t stay -- -- and extracted like troops. However, they will seek to build and/or repair crates found in a given radius. Handy if you can't stay
-- -- to build or repair or under fire. -- -- to build or repair or under fire.
-- my_ctld:AddTroopsCargo("Wrenches",{"Engineers"},CTLD_CARGO.Enum.ENGINEERS,4) -- my_ctld:AddTroopsCargo("Wrenches",{"Engineers"},CTLD_CARGO.Enum.ENGINEERS,4)
-- myctld.EngineerSearch = 2000 -- teams will search for crates in this radius. -- myctld.EngineerSearch = 2000 -- teams will search for crates in this radius.
@@ -619,7 +622,7 @@ do
-- my_ctld.repairtime = 300 -- takes 300 seconds to repair something -- my_ctld.repairtime = 300 -- takes 300 seconds to repair something
-- --
-- -- add static cargo objects, e.g ammo chests - the name needs to refer to a STATIC object in the mission editor, -- -- add static cargo objects, e.g ammo chests - the name needs to refer to a STATIC object in the mission editor,
-- -- here: it\'s the UNIT name (not the GROUP name!), the second parameter is the weight in kg. -- -- here: it's the UNIT name (not the GROUP name!), the second parameter is the weight in kg.
-- my_ctld:AddStaticsCargo("Ammunition",500) -- my_ctld:AddStaticsCargo("Ammunition",500)
-- --
-- ## 1.3 Add logistics zones -- ## 1.3 Add logistics zones
@@ -669,7 +672,9 @@ do
-- my_ctld.cratecountry = country.id.GERMANY -- ID of crates. Will default to country.id.RUSSIA for RED coalition setups. -- my_ctld.cratecountry = country.id.GERMANY -- ID of crates. Will default to country.id.RUSSIA for RED coalition setups.
-- my_ctld.allowcratepickupagain = true -- allow re-pickup crates that were dropped. -- my_ctld.allowcratepickupagain = true -- allow re-pickup crates that were dropped.
-- my_ctld.enableslingload = false -- allow cargos to be slingloaded - might not work for all cargo types -- my_ctld.enableslingload = false -- allow cargos to be slingloaded - might not work for all cargo types
-- my_ctld.pilotmustopendoors = false -- -- force opening of doors -- my_ctld.pilotmustopendoors = false -- force opening of doors
-- my_ctld.SmokeColor = SMOKECOLOR.Red -- color to use when dropping smoke from heli
-- my_ctld.FlareColor = FLARECOLOR.Red -- color to use when flaring from heli
-- --
-- ## 2.1 User functions -- ## 2.1 User functions
-- --
@@ -694,7 +699,6 @@ do
-- ["Mi-24V"] = {type="Mi-24V", crates=true, troops=true, cratelimit = 2, trooplimit = 8, length = 18}, -- ["Mi-24V"] = {type="Mi-24V", crates=true, troops=true, cratelimit = 2, trooplimit = 8, length = 18},
-- ["Hercules"] = {type="Hercules", crates=true, troops=true, cratelimit = 7, trooplimit = 64, length = 25}, -- ["Hercules"] = {type="Hercules", crates=true, troops=true, cratelimit = 7, trooplimit = 64, length = 25},
-- --
--
-- ### 2.1.2 Activate and deactivate zones -- ### 2.1.2 Activate and deactivate zones
-- --
-- Activate a zone: -- Activate a zone:
@@ -812,7 +816,7 @@ do
-- --
-- ## 4.1 Manage Crates -- ## 4.1 Manage Crates
-- --
-- Use this entry to get, load, list nearby, drop, build and repair crates. Also @see options. -- Use this entry to get, load, list nearby, drop, build and repair crates. Also see options.
-- --
-- ## 4.2 Manage Troops -- ## 4.2 Manage Troops
-- --
@@ -823,7 +827,7 @@ do
-- --
-- Lists what you have loaded. Shows load capabilities for number of crates and number of seats for troops. -- Lists what you have loaded. Shows load capabilities for number of crates and number of seats for troops.
-- --
-- ## 4.4 Smoke & Flare zones nearby -- ## 4.4 Smoke & Flare zones nearby or drop smoke or flare from Heli
-- --
-- Does what it says. -- Does what it says.
-- --
@@ -920,7 +924,7 @@ CTLD = {
-- DONE: Added support for Hercules -- DONE: Added support for Hercules
-- TODO: Possibly - either/or loading crates and troops -- TODO: Possibly - either/or loading crates and troops
-- DONE: Make inject respect existing cargo types -- DONE: Make inject respect existing cargo types
-- TODO: Drop beacons or flares/smoke -- DONE: Drop beacons or flares/smoke
-- DONE: Add statics as cargo -- DONE: Add statics as cargo
-- DONE: List cargo in stock -- DONE: List cargo in stock
-- DONE: Limit of troops, crates buildable? -- DONE: Limit of troops, crates buildable?
@@ -982,13 +986,12 @@ CTLD.UnitTypes = {
["Ka-50"] = { type = "Ka-50", crates = false, troops = false, cratelimit = 0, trooplimit = 0, length = 15 }, ["Ka-50"] = { type = "Ka-50", crates = false, troops = false, cratelimit = 0, trooplimit = 0, length = 15 },
["Mi-24P"] = { type = "Mi-24P", crates = true, troops = true, cratelimit = 2, trooplimit = 8, length = 18 }, ["Mi-24P"] = { type = "Mi-24P", crates = true, troops = true, cratelimit = 2, trooplimit = 8, length = 18 },
["Mi-24V"] = { type = "Mi-24V", crates = true, troops = true, cratelimit = 2, trooplimit = 8, length = 18 }, ["Mi-24V"] = { type = "Mi-24V", crates = true, troops = true, cratelimit = 2, trooplimit = 8, length = 18 },
["Hercules"] = {type="Hercules", crates=true, troops=true, cratelimit = 7, trooplimit = 64, length = 25}, -- 19t cargo, 64 paratroopers. ["Hercules"] = { type = "Hercules", crates = true, troops = true, cratelimit = 7, trooplimit = 64, length = 25 }, -- 19t cargo, 64 paratroopers. Actually it's longer, but the center coord is off-center of the model.
--Actually it's longer, but the center coord is off-center of the model.
} }
--- CTLD class version. --- CTLD class version.
-- @field #string version -- @field #string version
CTLD.version="0.2.4" CTLD.version = "1.0.1"
--- Instantiate a new CTLD. --- Instantiate a new CTLD.
-- @param #CTLD self -- @param #CTLD self
@@ -1154,6 +1157,10 @@ function CTLD:New(Coalition, Prefixes, Alias)
-- slingload -- slingload
self.enableslingload = false self.enableslingload = false
-- Smokes and Flares
self.SmokeColor = SMOKECOLOR.Red
self.FlareColor = FLARECOLOR.Red
for i = 1, 100 do for i = 1, 100 do
math.random() math.random()
end end
@@ -1343,7 +1350,6 @@ function CTLD:_GetUnitCapabilities(Unit)
return capabilities return capabilities
end end
--- (Internal) Function to generate valid UHF Frequencies --- (Internal) Function to generate valid UHF Frequencies
-- @param #CTLD self -- @param #CTLD self
function CTLD:_GenerateUHFrequencies() function CTLD:_GenerateUHFrequencies()
@@ -1448,13 +1454,19 @@ function CTLD:_LoadTroops(Group, Unit, Cargotype)
end end
if not inzone then if not inzone then
self:_SendMessage( "You are not close enough to a logistics zone!", 10, false, Group ) self:_SendMessage( "You are not close enough to a logistics zone!", 10, false, Group )
if not self.debug then return self end if not self.debug then
return self
end
elseif not grounded and not hoverload then elseif not grounded and not hoverload then
self:_SendMessage( "You need to land or hover in position to load!", 10, false, Group ) self:_SendMessage( "You need to land or hover in position to load!", 10, false, Group )
if not self.debug then return self end if not self.debug then
return self
end
elseif self.pilotmustopendoors and not UTILS.IsLoadingDoorOpen( Unit:GetName() ) then elseif self.pilotmustopendoors and not UTILS.IsLoadingDoorOpen( Unit:GetName() ) then
self:_SendMessage( "You need to open the door(s) to load troops!", 10, false, Group ) self:_SendMessage( "You need to open the door(s) to load troops!", 10, false, Group )
if not self.debug then return self end if not self.debug then
return self
end
end end
-- load troops into heli -- load troops into heli
local group = Group -- Wrapper.Group#GROUP local group = Group -- Wrapper.Group#GROUP
@@ -1538,7 +1550,9 @@ function CTLD:_FindRepairNearby(Group, Unit, Repairtype)
end end
else else
if type( String ) == "string" then if type( String ) == "string" then
if string.find(String,Table) then match = true end if string.find( String, Table ) then
match = true
end
end end
end end
return match return match
@@ -1579,7 +1593,9 @@ function CTLD:_RepairObjectFromCrates(Group,Unit,Crates,Build,Number,Engineering
local NearestGroup, CargoType = self:_FindRepairNearby( Group, Unit, Repairtype ) -- Wrapper.Group#GROUP, #CTLD_CARGO local NearestGroup, CargoType = self:_FindRepairNearby( Group, Unit, Repairtype ) -- Wrapper.Group#GROUP, #CTLD_CARGO
-- self:I({Repairtype=Repairtype, CargoType=CargoType, NearestGroup=NearestGroup}) -- self:I({Repairtype=Repairtype, CargoType=CargoType, NearestGroup=NearestGroup})
if NearestGroup ~= nil then if NearestGroup ~= nil then
if self.repairtime < 2 then self.repairtime = 30 end -- noob catch if self.repairtime < 2 then
self.repairtime = 30
end -- noob catch
if not Engineering then if not Engineering then
self:_SendMessage( string.format( "Repair started using %s taking %d secs", build.Name, self.repairtime ), 10, false, Group ) self:_SendMessage( string.format( "Repair started using %s taking %d secs", build.Name, self.repairtime ), 10, false, Group )
end end
@@ -1597,7 +1613,9 @@ function CTLD:_RepairObjectFromCrates(Group,Unit,Crates,Build,Number,Engineering
object.CanBuild = true object.CanBuild = true
object.Type = ctype -- #CTLD_CARGO.Enum object.Type = ctype -- #CTLD_CARGO.Enum
self:_CleanUpCrates( Crates, Build, Number ) self:_CleanUpCrates( Crates, Build, Number )
local desttimer = TIMER:New(function() NearestGroup:Destroy(false) end, self) local desttimer = TIMER:New( function()
NearestGroup:Destroy( false )
end, self )
desttimer:Start( self.repairtime - 1 ) desttimer:Start( self.repairtime - 1 )
local buildtimer = TIMER:New( self._BuildObjectFromCrates, self, Group, Unit, object, true, NearestGroup:GetCoordinate() ) local buildtimer = TIMER:New( self._BuildObjectFromCrates, self, Group, Unit, object, true, NearestGroup:GetCoordinate() )
buildtimer:Start( self.repairtime ) buildtimer:Start( self.repairtime )
@@ -1624,11 +1642,15 @@ end
if not grounded and not hoverload then if not grounded and not hoverload then
self:_SendMessage( "You need to land or hover in position to load!", 10, false, Group ) self:_SendMessage( "You need to land or hover in position to load!", 10, false, Group )
if not self.debug then return self end if not self.debug then
return self
end
end end
if self.pilotmustopendoors and not UTILS.IsLoadingDoorOpen( Unit:GetName() ) then if self.pilotmustopendoors and not UTILS.IsLoadingDoorOpen( Unit:GetName() ) then
self:_SendMessage( "You need to open the door(s) to extract troops!", 10, false, Group ) self:_SendMessage( "You need to open the door(s) to extract troops!", 10, false, Group )
if not self.debug then return self end if not self.debug then
return self
end
end end
-- load troops into heli -- load troops into heli
local unit = Unit -- Wrapper.Unit#UNIT local unit = Unit -- Wrapper.Unit#UNIT
@@ -1675,7 +1697,11 @@ end
local Cargotype = nil local Cargotype = nil
for k, v in pairs( self.Cargo_Troops ) do for k, v in pairs( self.Cargo_Troops ) do
local comparison = "" local comparison = ""
if type(v.Templates) == "string" then comparison = v.Templates else comparison = v.Templates[1] end if type( v.Templates ) == "string" then
comparison = v.Templates
else
comparison = v.Templates[1]
end
if comparison == groupType then if comparison == groupType then
Cargotype = v Cargotype = v
break break
@@ -1745,7 +1771,7 @@ end
-- @param Wrapper.Unit#UNIT Unit -- @param Wrapper.Unit#UNIT Unit
-- @param #CTLD_CARGO Cargo -- @param #CTLD_CARGO Cargo
-- @param #number number Number of crates to generate (for dropping) -- @param #number number Number of crates to generate (for dropping)
-- @param #boolean drop If true we\'re dropping from heli rather than loading. -- @param #boolean drop If true we're dropping from heli rather than loading.
function CTLD:_GetCrates( Group, Unit, Cargo, number, drop ) function CTLD:_GetCrates( Group, Unit, Cargo, number, drop )
self:T( self.lid .. " _GetCrates" ) self:T( self.lid .. " _GetCrates" )
if not drop then if not drop then
@@ -1778,7 +1804,9 @@ function CTLD:_GetCrates(Group, Unit, Cargo, number, drop)
if not inzone then if not inzone then
self:_SendMessage( "You are not close enough to a logistics zone!", 10, false, Group ) self:_SendMessage( "You are not close enough to a logistics zone!", 10, false, Group )
if not self.debug then return self end if not self.debug then
return self
end
end end
-- avoid crate spam -- avoid crate spam
@@ -1822,7 +1850,9 @@ function CTLD:_GetCrates(Group, Unit, Cargo, number, drop)
local cratealias = string.format( "%s-%d", cratetemplate, math.random( 1, 100000 ) ) local cratealias = string.format( "%s-%d", cratetemplate, math.random( 1, 100000 ) )
if not self.placeCratesAhead then if not self.placeCratesAhead then
cratedistance = (i - 1) * 2.5 + capabilities.length cratedistance = (i - 1) * 2.5 + capabilities.length
if cratedistance > self.CrateDistance then cratedistance = self.CrateDistance end if cratedistance > self.CrateDistance then
cratedistance = self.CrateDistance
end
-- altered heading logic -- altered heading logic
-- DONE: right standard deviation? -- DONE: right standard deviation?
rheading = UTILS.RandomGaussian( 0, 30, -90, 90, 100 ) rheading = UTILS.RandomGaussian( 0, 30, -90, 90, 100 )
@@ -1863,8 +1893,7 @@ function CTLD:_GetCrates(Group, Unit, Cargo, number, drop)
dist = dist - (20 + math.random( 1, 10 )) dist = dist - (20 + math.random( 1, 10 ))
local width = width / 2 local width = width / 2
local Offy = math.random( -width, width ) local Offy = math.random( -width, width )
self.Spawned_Crates[self.CrateCounter] = SPAWNSTATIC:NewFromType(basetype,"Cargos",self.cratecountry) self.Spawned_Crates[self.CrateCounter] = SPAWNSTATIC:NewFromType( basetype, "Cargos", self.cratecountry ) -- :InitCoordinate(cratecoord)
--:InitCoordinate(cratecoord)
:InitCargoMass( cgomass ) :InitCargoMass( cgomass )
:InitCargo( self.enableslingload ) :InitCargo( self.enableslingload )
:InitLinkToUnit( Ship, dist, Offy, 0 ) :InitLinkToUnit( Ship, dist, Offy, 0 )
@@ -1873,8 +1902,7 @@ function CTLD:_GetCrates(Group, Unit, Cargo, number, drop)
self.Spawned_Crates[self.CrateCounter] = SPAWNSTATIC:NewFromType( basetype, "Cargos", self.cratecountry ) self.Spawned_Crates[self.CrateCounter] = SPAWNSTATIC:NewFromType( basetype, "Cargos", self.cratecountry )
:InitCoordinate( cratecoord ) :InitCoordinate( cratecoord )
:InitCargoMass( cgomass ) :InitCargoMass( cgomass )
:InitCargo(self.enableslingload) :InitCargo( self.enableslingload ) -- :InitLinkToUnit(Unit,OffsetX,OffsetY,OffsetAngle)
--:InitLinkToUnit(Unit,OffsetX,OffsetY,OffsetAngle)
:Spawn( 270, cratealias ) :Spawn( 270, cratealias )
end end
local templ = cargotype:GetTemplates() local templ = cargotype:GetTemplates()
@@ -2070,7 +2098,7 @@ function CTLD:_LoadCratesNearby(Group, Unit)
local grounded = not self:IsUnitInAir( Unit ) local grounded = not self:IsUnitInAir( Unit )
local canhoverload = self:CanHoverLoad( Unit ) local canhoverload = self:CanHoverLoad( Unit )
--- cases ------------------------------- --- cases -------------------------------
-- Chopper can\'t do crates - bark & return -- Chopper can't do crates - bark & return
-- Chopper can do crates - -- Chopper can do crates -
-- --> hover if forcedhover or bark and return -- --> hover if forcedhover or bark and return
-- --> hover or land if not forcedhover -- --> hover or land if not forcedhover
@@ -2145,21 +2173,36 @@ function CTLD:_LoadCratesNearby(Group, Unit)
self.Loaded_Cargo[unitname] = loaded self.Loaded_Cargo[unitname] = loaded
self:_UpdateUnitCargoMass( Unit ) self:_UpdateUnitCargoMass( Unit )
-- clean up real world crates -- clean up real world crates
self:_CleanupTrackedCrates( crateidsloaded )
end
end
return self
end
--- (Internal) Function to clean up tracked cargo crates
function CTLD:_CleanupTrackedCrates( crateIdsToRemove )
local existingcrates = self.Spawned_Cargo -- #table local existingcrates = self.Spawned_Cargo -- #table
local newexcrates = {} local newexcrates = {}
for _, _crate in pairs( existingcrates ) do for _, _crate in pairs( existingcrates ) do
local excrate = _crate -- #CTLD_CARGO local excrate = _crate -- #CTLD_CARGO
local ID = excrate:GetID() local ID = excrate:GetID()
for _,_ID in pairs(crateidsloaded) do local keep = true
if ID ~= _ID then for _, _ID in pairs( crateIdsToRemove ) do
table.insert(newexcrates,_crate) if ID == _ID then
keep = false
end end
end end
-- remove destroyed crates here too
local static = _crate:GetPositionable() -- Wrapper.Static#STATIC -- crates
if not static or not static:IsAlive() then
keep = false
end
if keep then
table.insert( newexcrates, _crate )
end
end end
self.Spawned_Cargo = nil self.Spawned_Cargo = nil
self.Spawned_Cargo = newexcrates self.Spawned_Cargo = newexcrates
end
end
return self return self
end end
@@ -2375,7 +2418,9 @@ function CTLD:_UnloadTroops(Group, Unit)
local canunload = true local canunload = true
if self.pilotmustopendoors and not UTILS.IsLoadingDoorOpen( Unit:GetName() ) then if self.pilotmustopendoors and not UTILS.IsLoadingDoorOpen( Unit:GetName() ) then
self:_SendMessage( "You need to open the door(s) to unload troops!", 10, false, Group ) self:_SendMessage( "You need to open the door(s) to unload troops!", 10, false, Group )
if not self.debug then return self end if not self.debug then
return self
end
end end
local inzone, zonename, zone, distance = self:IsUnitInZone( Unit, CTLD.CargoZoneType.LOAD ) local inzone, zonename, zone, distance = self:IsUnitInZone( Unit, CTLD.CargoZoneType.LOAD )
if not inzone then if not inzone then
@@ -2385,13 +2430,13 @@ function CTLD:_UnloadTroops(Group, Unit)
droppingatbase = true droppingatbase = true
end end
-- check for hover unload -- check for hover unload
local hoverunload = self:IsCorrectHover(Unit) --if true we\'re hovering in parameters local hoverunload = self:IsCorrectHover( Unit ) -- if true we're hovering in parameters
local IsHerc = self:IsHercules( Unit ) local IsHerc = self:IsHercules( Unit )
if IsHerc then if IsHerc then
-- no hover but airdrop here -- no hover but airdrop here
hoverunload = self:IsCorrectFlightParameters( Unit ) hoverunload = self:IsCorrectFlightParameters( Unit )
end end
-- check if we\'re landed -- check if we're landed
local grounded = not self:IsUnitInAir( Unit ) local grounded = not self:IsUnitInAir( Unit )
-- Get what we have loaded -- Get what we have loaded
local unitname = Unit:GetName() local unitname = Unit:GetName()
@@ -2469,7 +2514,9 @@ function CTLD:_UnloadTroops(Group, Unit)
if _troop.Name == name then if _troop.Name == name then
local stock = _troop:GetStock() local stock = _troop:GetStock()
-- avoid making unlimited stock limited -- avoid making unlimited stock limited
if stock and tonumber(stock) >= 0 then _troop:AddStock() end if stock and tonumber( stock ) >= 0 then
_troop:AddStock()
end
end end
end end
end end
@@ -2506,13 +2553,13 @@ function CTLD:_UnloadCrates(Group, Unit)
end end
end end
-- check for hover unload -- check for hover unload
local hoverunload = self:IsCorrectHover(Unit) --if true we\'re hovering in parameters local hoverunload = self:IsCorrectHover( Unit ) -- if true we're hovering in parameters
local IsHerc = self:IsHercules( Unit ) local IsHerc = self:IsHercules( Unit )
if IsHerc then if IsHerc then
-- no hover but airdrop here -- no hover but airdrop here
hoverunload = self:IsCorrectFlightParameters( Unit ) hoverunload = self:IsCorrectFlightParameters( Unit )
end end
-- check if we\'re landed -- check if we're landed
local grounded = not self:IsUnitInAir( Unit ) local grounded = not self:IsUnitInAir( Unit )
-- Get what we have loaded -- Get what we have loaded
local unitname = Unit:GetName() local unitname = Unit:GetName()
@@ -2612,7 +2659,7 @@ function CTLD:_BuildCrates(Group, Unit,Engineering)
self:T( { buildables = buildables } ) self:T( { buildables = buildables } )
end -- end dropped end -- end dropped
end -- end crate loop end -- end crate loop
-- ok let\'s list what we have -- ok let's list what we have
local report = REPORT:New( "Checklist Buildable Crates" ) local report = REPORT:New( "Checklist Buildable Crates" )
report:Add( "------------------------------------------------------------" ) report:Add( "------------------------------------------------------------" )
for _, _build in pairs( buildables ) do for _, _build in pairs( buildables ) do
@@ -2627,7 +2674,9 @@ function CTLD:_BuildCrates(Group, Unit,Engineering)
local text = string.format( "Type: %s | Required %d | Found %d | Can Build %s", name, needed, found, txtok ) local text = string.format( "Type: %s | Required %d | Found %d | Can Build %s", name, needed, found, txtok )
report:Add( text ) report:Add( text )
end -- end list buildables end -- end list buildables
if not foundbuilds then report:Add(" --- None Found ---") end if not foundbuilds then
report:Add( " --- None Found ---" )
end
report:Add( "------------------------------------------------------------" ) report:Add( "------------------------------------------------------------" )
local text = report:Text() local text = report:Text()
if not Engineering then if not Engineering then
@@ -2635,7 +2684,7 @@ function CTLD:_BuildCrates(Group, Unit,Engineering)
else else
self:T( text ) self:T( text )
end end
-- let\'s get going -- let's get going
if canbuild then if canbuild then
-- loop again -- loop again
for _, _build in pairs( buildables ) do for _, _build in pairs( buildables ) do
@@ -2647,7 +2696,9 @@ function CTLD:_BuildCrates(Group, Unit,Engineering)
end end
end end
else else
if not Engineering then self:_SendMessage(string.format("No crates within %d meters!",finddist), 10, false, Group) end if not Engineering then
self:_SendMessage( string.format( "No crates within %d meters!", finddist ), 10, false, Group )
end
end -- number > 0 end -- number > 0
return self return self
end end
@@ -2696,7 +2747,7 @@ function CTLD:_RepairCrates(Group, Unit, Engineering)
self:T( { repair = buildables } ) self:T( { repair = buildables } )
end -- end dropped end -- end dropped
end -- end crate loop end -- end crate loop
-- ok let\'s list what we have -- ok let's list what we have
local report = REPORT:New( "Checklist Repairs" ) local report = REPORT:New( "Checklist Repairs" )
report:Add( "------------------------------------------------------------" ) report:Add( "------------------------------------------------------------" )
for _, _build in pairs( buildables ) do for _, _build in pairs( buildables ) do
@@ -2711,7 +2762,9 @@ function CTLD:_RepairCrates(Group, Unit, Engineering)
local text = string.format( "Type: %s | Required %d | Found %d | Can Repair %s", name, needed, found, txtok ) local text = string.format( "Type: %s | Required %d | Found %d | Can Repair %s", name, needed, found, txtok )
report:Add( text ) report:Add( text )
end -- end list buildables end -- end list buildables
if not foundbuilds then report:Add(" --- None Found ---") end if not foundbuilds then
report:Add( " --- None Found ---" )
end
report:Add( "------------------------------------------------------------" ) report:Add( "------------------------------------------------------------" )
local text = report:Text() local text = report:Text()
if not Engineering then if not Engineering then
@@ -2719,7 +2772,7 @@ function CTLD:_RepairCrates(Group, Unit, Engineering)
else else
self:T( text ) self:T( text )
end end
-- let\'s get going -- let's get going
if canbuild then if canbuild then
-- loop again -- loop again
for _, _build in pairs( buildables ) do for _, _build in pairs( buildables ) do
@@ -2730,7 +2783,9 @@ function CTLD:_RepairCrates(Group, Unit, Engineering)
end end
end end
else else
if not Engineering then self:_SendMessage(string.format("No crates within %d meters!",finddist), 10, false, Group) end if not Engineering then
self:_SendMessage( string.format( "No crates within %d meters!", finddist ), 10, false, Group )
end
end -- number > 0 end -- number > 0
return self return self
end end
@@ -2751,7 +2806,9 @@ function CTLD:_BuildObjectFromCrates(Group,Unit,Build,Repair,RepairLocation)
local name = Build.Name local name = Build.Name
local ctype = Build.Type -- #CTLD_CARGO.Enum local ctype = Build.Type -- #CTLD_CARGO.Enum
local canmove = false local canmove = false
if ctype == CTLD_CARGO.Enum.VEHICLE then canmove = true end if ctype == CTLD_CARGO.Enum.VEHICLE then
canmove = true
end
if ctype == CTLD_CARGO.Enum.STATIC then if ctype == CTLD_CARGO.Enum.STATIC then
return self return self
end end
@@ -2846,22 +2903,12 @@ function CTLD:_CleanUpCrates(Crates,Build,Number)
nowcrate.Positionable = nil nowcrate.Positionable = nil
nowcrate.HasBeenDropped = false nowcrate.HasBeenDropped = false
end end
if found == numberdest then break end -- got enough if found == numberdest then
break
end -- got enough
end end
-- loop and remove from real world representation -- loop and remove from real world representation
for _,_crate in pairs(existingcrates) do self:_CleanupTrackedCrates( destIDs )
local excrate = _crate -- #CTLD_CARGO
local ID = excrate:GetID()
for _,_ID in pairs(destIDs) do
if ID ~= _ID then
table.insert(newexcrates,_crate)
end
end
end
-- reset Spawned_Cargo
self.Spawned_Cargo = nil
self.Spawned_Cargo = newexcrates
return self return self
end end
@@ -2908,8 +2955,11 @@ function CTLD:_RefreshF10Menus()
local listmenu = MENU_GROUP_COMMAND:New( _group, "List boarded cargo", topmenu, self._ListCargo, self, _group, _unit ) local listmenu = MENU_GROUP_COMMAND:New( _group, "List boarded cargo", topmenu, self._ListCargo, self, _group, _unit )
local invtry = MENU_GROUP_COMMAND:New( _group, "Inventory", topmenu, self._ListInventory, self, _group, _unit ) local invtry = MENU_GROUP_COMMAND:New( _group, "Inventory", topmenu, self._ListInventory, self, _group, _unit )
local rbcns = MENU_GROUP_COMMAND:New( _group, "List active zone beacons", topmenu, self._ListRadioBeacons, self, _group, _unit ) local rbcns = MENU_GROUP_COMMAND:New( _group, "List active zone beacons", topmenu, self._ListRadioBeacons, self, _group, _unit )
local smokemenu = MENU_GROUP_COMMAND:New(_group,"Smoke zones nearby",topmenu, self.SmokeZoneNearBy, self, _unit, false) local smoketopmenu = MENU_GROUP:New( _group, "Smokes & Flares", topmenu )
local smokemenu = MENU_GROUP_COMMAND:New(_group,"Flare zones nearby",topmenu, self.SmokeZoneNearBy, self, _unit, true):Refresh() local smokemenu = MENU_GROUP_COMMAND:New( _group, "Smoke zones nearby", smoketopmenu, self.SmokeZoneNearBy, self, _unit, false )
local smokeself = MENU_GROUP_COMMAND:New( _group, "Drop smoke now", smoketopmenu, self.SmokePositionNow, self, _unit, false )
local flaremenu = MENU_GROUP_COMMAND:New( _group, "Flare zones nearby", smoketopmenu, self.SmokeZoneNearBy, self, _unit, true )
local flareself = MENU_GROUP_COMMAND:New( _group, "Fire flare now", smoketopmenu, self.SmokePositionNow, self, _unit, true ):Refresh()
-- sub menus -- sub menus
-- sub menu troops management -- sub menu troops management
if cantroops then if cantroops then
@@ -3068,7 +3118,7 @@ end
function CTLD:ActivateZone( Name, ZoneType, NewState ) function CTLD:ActivateZone( Name, ZoneType, NewState )
self:T( self.lid .. " AddZone" ) self:T( self.lid .. " AddZone" )
local newstate = true local newstate = true
-- set optional in case we\'re deactivating -- set optional in case we're deactivating
if NewState ~= nil then if NewState ~= nil then
newstate = NewState newstate = NewState
end end
@@ -3095,7 +3145,6 @@ function CTLD:ActivateZone(Name,ZoneType,NewState)
return self return self
end end
--- User function - Deactivate Name #CTLD.CargoZoneType ZoneType for this CTLD instance. --- User function - Deactivate Name #CTLD.CargoZoneType ZoneType for this CTLD instance.
-- @param #CTLD self -- @param #CTLD self
-- @param #string Name Name of the zone to change in the ME. -- @param #string Name Name of the zone to change in the ME.
@@ -3167,7 +3216,6 @@ function CTLD:_GetVHFBeacon(Name)
return beacon return beacon
end end
--- User function - Crates and adds a #CTLD.CargoZone zone for this CTLD instance. --- User function - Crates and adds a #CTLD.CargoZone zone for this CTLD instance.
-- Zones of type LOAD: Players load crates and troops here. -- Zones of type LOAD: Players load crates and troops here.
-- Zones of type DROP: Players can drop crates here. Note that troops can be unloaded anywhere. -- Zones of type DROP: Players can drop crates here. Note that troops can be unloaded anywhere.
@@ -3277,7 +3325,9 @@ function CTLD:_RefreshRadioBeacons()
local zones = { [1] = self.pickupZones, [2] = self.wpZones, [3] = self.dropOffZones, [4] = self.shipZones } local zones = { [1] = self.pickupZones, [2] = self.wpZones, [3] = self.dropOffZones, [4] = self.shipZones }
for i = 1, 4 do for i = 1, 4 do
local IsShip = false local IsShip = false
if i == 4 then IsShip = true end if i == 4 then
IsShip = true
end
for index, cargozone in pairs( zones[i] ) do for index, cargozone in pairs( zones[i] ) do
-- Get Beacon object from zone -- Get Beacon object from zone
local czone = cargozone -- #CTLD.CargoZone local czone = cargozone -- #CTLD.CargoZone
@@ -3323,7 +3373,7 @@ function CTLD:IsUnitInZone(Unit,Zonetype)
else else
zonetable = self.wpZones -- #table zonetable = self.wpZones -- #table
end end
--- now see if we\'re in --- now see if we're in
local zonecoord = nil local zonecoord = nil
local colorret = nil local colorret = nil
local maxdist = 1000000 -- 100km local maxdist = 1000000 -- 100km
@@ -3370,7 +3420,28 @@ function CTLD:IsUnitInZone(Unit,Zonetype)
end end
end end
--- User function - Start smoke in a zone close to the Unit. --- User function - Drop a smoke or flare at current location.
-- @param #CTLD self
-- @param Wrapper.Unit#UNIT Unit The Unit.
-- @param #boolean Flare If true, flare instead.
function CTLD:SmokePositionNow( Unit, Flare )
self:T( self.lid .. " SmokePositionNow" )
local SmokeColor = self.SmokeColor or SMOKECOLOR.Red
local FlareColor = self.FlareColor or FLARECOLOR.Red
-- table of #CTLD.CargoZone table
local unitcoord = Unit:GetCoordinate() -- Core.Point#COORDINATE
local Group = Unit:GetGroup()
if Flare then
unitcoord:Flare( FlareColor, 90 )
else
local height = unitcoord:GetLandHeight() + 2
unitcoord.y = height
unitcoord:Smoke( SmokeColor )
end
return self
end
--- User function - Start smoke/flare in a zone close to the Unit.
-- @param #CTLD self -- @param #CTLD self
-- @param Wrapper.Unit#UNIT Unit The Unit. -- @param Wrapper.Unit#UNIT Unit The Unit.
-- @param #boolean Flare If true, flare instead. -- @param #boolean Flare If true, flare instead.
@@ -3397,15 +3468,19 @@ function CTLD:SmokeZoneNearBy(Unit, Flare)
local color = CZone.color local color = CZone.color
local distance = self:_GetDistance( zonecoord, unitcoord ) local distance = self:_GetDistance( zonecoord, unitcoord )
if distance < smokedistance and active then if distance < smokedistance and active then
-- smoke zone since we\'re nearby -- smoke zone since we're nearby
if not Flare then if not Flare then
zonecoord:Smoke( color or SMOKECOLOR.White ) zonecoord:Smoke( color or SMOKECOLOR.White )
else else
if color == SMOKECOLOR.Blue then color = FLARECOLOR.White end if color == SMOKECOLOR.Blue then
color = FLARECOLOR.White
end
zonecoord:Flare( color or FLARECOLOR.White ) zonecoord:Flare( color or FLARECOLOR.White )
end end
local txt = "smoking" local txt = "smoking"
if Flare then txt = "flaring" end if Flare then
txt = "flaring"
end
self:_SendMessage( string.format( "Roger, %s zone %s!", txt, zonename ), 10, false, Group ) self:_SendMessage( string.format( "Roger, %s zone %s!", txt, zonename ), 10, false, Group )
smoked = true smoked = true
end end
@@ -3513,7 +3588,9 @@ end
function CTLD:_ShowHoverParams( Group, Unit ) function CTLD:_ShowHoverParams( Group, Unit )
local inhover = self:IsCorrectHover( Unit ) local inhover = self:IsCorrectHover( Unit )
local htxt = "true" local htxt = "true"
if not inhover then htxt = "false" end if not inhover then
htxt = "false"
end
local text = "" local text = ""
if _SETTINGS:IsMetric() then if _SETTINGS:IsMetric() then
text = string.format( "Hover parameters (autoload/drop):\n - Min height %dm \n - Max height %dm \n - Max speed 2mps \n - In parameter: %s", self.minimumHoverHeight, self.maximumHoverHeight, htxt ) text = string.format( "Hover parameters (autoload/drop):\n - Min height %dm \n - Max height %dm \n - Max speed 2mps \n - In parameter: %s", self.minimumHoverHeight, self.maximumHoverHeight, htxt )
@@ -3533,7 +3610,9 @@ end
function CTLD:_ShowFlightParams( Group, Unit ) function CTLD:_ShowFlightParams( Group, Unit )
local inhover = self:IsCorrectFlightParameters( Unit ) local inhover = self:IsCorrectFlightParameters( Unit )
local htxt = "true" local htxt = "true"
if not inhover then htxt = "false" end if not inhover then
htxt = "false"
end
local text = "" local text = ""
if _SETTINGS:IsImperial() then if _SETTINGS:IsImperial() then
local minheight = UTILS.MetersToFeet( self.HercMinAngels ) local minheight = UTILS.MetersToFeet( self.HercMinAngels )
@@ -3548,14 +3627,15 @@ end
return self return self
end end
--- (Internal) Check if a unit is in a load zone and is hovering in parameters. --- (Internal) Check if a unit is in a load zone and is hovering in parameters.
-- @param #CTLD self -- @param #CTLD self
-- @param Wrapper.Unit#UNIT Unit -- @param Wrapper.Unit#UNIT Unit
-- @return #boolean Outcome -- @return #boolean Outcome
function CTLD:CanHoverLoad( Unit ) function CTLD:CanHoverLoad( Unit )
self:T( self.lid .. " CanHoverLoad" ) self:T( self.lid .. " CanHoverLoad" )
if self:IsHercules(Unit) then return false end if self:IsHercules( Unit ) then
return false
end
local outcome = self:IsUnitInZone( Unit, CTLD.CargoZoneType.LOAD ) and self:IsCorrectHover( Unit ) local outcome = self:IsUnitInZone( Unit, CTLD.CargoZoneType.LOAD ) and self:IsCorrectHover( Unit )
if not outcome then if not outcome then
outcome = self:IsUnitInZone( Unit, CTLD.CargoZoneType.SHIP ) -- and self:IsCorrectHover(Unit) outcome = self:IsUnitInZone( Unit, CTLD.CargoZoneType.SHIP ) -- and self:IsCorrectHover(Unit)
@@ -3621,7 +3701,9 @@ end
if self.hoverautoloading then if self.hoverautoloading then
for _, _pilot in pairs( self.CtldUnits ) do for _, _pilot in pairs( self.CtldUnits ) do
local Unit = UNIT:FindByName( _pilot ) local Unit = UNIT:FindByName( _pilot )
if self:CanHoverLoad(Unit) then self:AutoHoverLoad(Unit) end if self:CanHoverLoad( Unit ) then
self:AutoHoverLoad( Unit )
end
end end
end end
return self return self
@@ -3876,7 +3958,9 @@ end
local randomcoord = zone:GetRandomCoordinate( 10, 30 * factor ):GetVec2() local randomcoord = zone:GetRandomCoordinate( 10, 30 * factor ):GetVec2()
cargo:SetWasDropped( true ) cargo:SetWasDropped( true )
local canmove = false local canmove = false
if type == CTLD_CARGO.Enum.VEHICLE then canmove = true end if type == CTLD_CARGO.Enum.VEHICLE then
canmove = true
end
for _, _template in pairs( temptable ) do for _, _template in pairs( temptable ) do
self.TroopCounter = self.TroopCounter + 1 self.TroopCounter = self.TroopCounter + 1
local alias = string.format( "%s-%d", _template, math.random( 1, 100000 ) ) local alias = string.format( "%s-%d", _template, math.random( 1, 100000 ) )
@@ -4062,7 +4146,6 @@ end
return self return self
end end
--- (Internal) FSM Function onbeforeTroopsDeployed. --- (Internal) FSM Function onbeforeTroopsDeployed.
-- @param #CTLD self -- @param #CTLD self
-- @param #string From State. -- @param #string From State.
@@ -4213,12 +4296,13 @@ end
cargo = thiscargo cargo = thiscargo
end end
end end
if match then break end if match then
break
end
end end
return match, cargo return match, cargo
end end
-- local data = "LoadedData = {\n" -- local data = "LoadedData = {\n"
local data = "Group,x,y,z,CargoName,CargoTemplates,CargoType,CratesNeeded,CrateMass\n" local data = "Group,x,y,z,CargoName,CargoTemplates,CargoType,CratesNeeded,CrateMass\n"
local n = 0 local n = 0
@@ -4255,8 +4339,7 @@ end
end end
local location = group:GetVec3() local location = group:GetVec3()
local txt = string.format("%s,%d,%d,%d,%s,%s,%s,%d,%d\n" local txt = string.format( "%s,%d,%d,%d,%s,%s,%s,%d,%d\n", template, location.x, location.y, location.z, cgoname, cgotemp, cgotype, cgoneed, cgomass )
,template,location.x,location.y,location.z,cgoname,cgotemp,cgotype,cgoneed,cgomass)
data = data .. txt data = data .. txt
end end
end end
@@ -4281,8 +4364,7 @@ end
local cgomass = object.PerCrateMass local cgomass = object.PerCrateMass
local crateobj = object.Positionable local crateobj = object.Positionable
local location = crateobj:GetVec3() local location = crateobj:GetVec3()
local txt = string.format("%s,%d,%d,%d,%s,%s,%s,%d,%d\n" local txt = string.format( "%s,%d,%d,%d,%s,%s,%s,%d,%d\n", "STATIC", location.x, location.y, location.z, cgoname, cgotemp, cgotype, cgoneed, cgomass )
,"STATIC",location.x,location.y,location.z,cgoname,cgotemp,cgotype,cgoneed,cgomass)
data = data .. txt data = data .. txt
end end

View File

@@ -802,7 +802,7 @@ function RESCUEHELO:_OnEventCrashOrEject(EventData)
-- Debug. -- Debug.
local text=string.format("Unit %s crashed or ejected.", unitname) local text=string.format("Unit %s crashed or ejected.", unitname)
MESSAGE:New(text, 10, "DEBUG"):ToAllIf(self.Debug) MESSAGE:New(text, 10, "DEBUG"):ToAllIf(self.Debug)
self:I(self.lid..text) self:T(self.lid..text)
-- Get coordinate of unit. -- Get coordinate of unit.
local coord=unit:GetCoordinate() local coord=unit:GetCoordinate()

View File

@@ -88,10 +88,19 @@
-- --
-- Use a specific "culture" with the @{#MSRS.SetCulture} function, e.g. `:SetCulture("en-US")` or `:SetCulture("de-DE")`. -- Use a specific "culture" with the @{#MSRS.SetCulture} function, e.g. `:SetCulture("en-US")` or `:SetCulture("de-DE")`.
-- --
-- ## Set Google
--
-- Use Google's text-to-speech engine with the @{#MSRS.SetGoogle} function, e.g. ':SetGoogle()'.
-- By enabling this it also allows you to utilize SSML in your text for added flexibilty.
-- For more information on setting up a cloud account, visit: https://cloud.google.com/text-to-speech
-- Google's supported SSML reference: https://cloud.google.com/text-to-speech/docs/ssml
--
-- ## Set Voice -- ## Set Voice
-- --
-- Use a specifc voice with the @{#MSRS.SetVoice} function, e.g, `:SetVoice("Microsoft Hedda Desktop")`. -- Use a specifc voice with the @{#MSRS.SetVoice} function, e.g, `:SetVoice("Microsoft Hedda Desktop")`.
-- Note that this must be installed on your windows system. -- Note that this must be installed on your windows system.
-- If enabling SetGoogle(), you can use voices provided by Google
-- Google's supported voices: https://cloud.google.com/text-to-speech/docs/voices
-- --
-- ## Set Coordinate -- ## Set Coordinate
-- --
@@ -678,7 +687,7 @@ function MSRS:_GetCommand(freqs, modus, coal, gender, voice, culture, volume, sp
-- Set google. -- Set google.
if self.google then if self.google then
command=command..string.format(' -G "%s"', self.google) command=command..string.format(' --ssml -G "%s"', self.google)
end end
-- Debug output. -- Debug output.

View File

@@ -38,7 +38,7 @@ do -- TASK_A2A
-- --
-- @field #TASK_A2A -- @field #TASK_A2A
TASK_A2A = { TASK_A2A = {
ClassName = "TASK_A2A", ClassName = "TASK_A2A"
} }
--- Instantiates a new TASK_A2A. --- Instantiates a new TASK_A2A.
@@ -60,7 +60,6 @@ do -- TASK_A2A
local Fsm = self:GetUnitProcess() local Fsm = self:GetUnitProcess()
Fsm:AddTransition( "Assigned", "RouteToRendezVous", "RoutingToRendezVous" ) Fsm:AddTransition( "Assigned", "RouteToRendezVous", "RoutingToRendezVous" )
Fsm:AddProcess( "RoutingToRendezVous", "RouteToRendezVousPoint", ACT_ROUTE_POINT:New(), { Arrived = "ArriveAtRendezVous" } ) Fsm:AddProcess( "RoutingToRendezVous", "RouteToRendezVousPoint", ACT_ROUTE_POINT:New(), { Arrived = "ArriveAtRendezVous" } )
Fsm:AddProcess( "RoutingToRendezVous", "RouteToRendezVousZone", ACT_ROUTE_ZONE:New(), { Arrived = "ArriveAtRendezVous" } ) Fsm:AddProcess( "RoutingToRendezVous", "RouteToRendezVousZone", ACT_ROUTE_ZONE:New(), { Arrived = "ArriveAtRendezVous" } )
@@ -81,8 +80,7 @@ do -- TASK_A2A
Fsm:AddTransition( "Rejected", "Reject", "Aborted" ) Fsm:AddTransition( "Rejected", "Reject", "Aborted" )
Fsm:AddTransition( "Failed", "Fail", "Failed" ) Fsm:AddTransition( "Failed", "Fail", "Failed" )
-- @param #FSM_PROCESS self
---- @param #FSM_PROCESS self
-- @param Wrapper.Unit#UNIT TaskUnit -- @param Wrapper.Unit#UNIT TaskUnit
-- @param #TASK_CARGO Task -- @param #TASK_CARGO Task
function Fsm:OnLeaveAssigned( TaskUnit, Task ) function Fsm:OnLeaveAssigned( TaskUnit, Task )
@@ -177,8 +175,6 @@ do -- TASK_A2A
self.TargetSetUnit = TargetSetUnit self.TargetSetUnit = TargetSetUnit
end end
--- @param #TASK_A2A self --- @param #TASK_A2A self
function TASK_A2A:GetPlannedMenuText() function TASK_A2A:GetPlannedMenuText()
return self:GetStateString() .. " - " .. self:GetTaskName() .. " ( " .. self.TargetSetUnit:GetUnitTypesText() .. " )" return self:GetStateString() .. " - " .. self:GetTaskName() .. " ( " .. self.TargetSetUnit:GetUnitTypesText() .. " )"
@@ -209,8 +205,6 @@ do -- TASK_A2A
return ActRouteRendezVous:GetCoordinate(), ActRouteRendezVous:GetRange() return ActRouteRendezVous:GetCoordinate(), ActRouteRendezVous:GetRange()
end end
--- @param #TASK_A2A self --- @param #TASK_A2A self
-- @param Core.Zone#ZONE_BASE RendezVousZone The Zone object where the RendezVous is located on the map. -- @param Core.Zone#ZONE_BASE RendezVousZone The Zone object where the RendezVous is located on the map.
-- @param Wrapper.Unit#UNIT TaskUnit -- @param Wrapper.Unit#UNIT TaskUnit
@@ -244,7 +238,6 @@ do -- TASK_A2A
ActRouteTarget:SetCoordinate( TargetCoordinate ) ActRouteTarget:SetCoordinate( TargetCoordinate )
end end
--- @param #TASK_A2A self --- @param #TASK_A2A self
-- @param Wrapper.Unit#UNIT TaskUnit -- @param Wrapper.Unit#UNIT TaskUnit
-- @return Core.Point#COORDINATE The Coordinate object where the Target is located on the map. -- @return Core.Point#COORDINATE The Coordinate object where the Target is located on the map.
@@ -256,7 +249,6 @@ do -- TASK_A2A
return ActRouteTarget:GetCoordinate() return ActRouteTarget:GetCoordinate()
end end
--- @param #TASK_A2A self --- @param #TASK_A2A self
-- @param Core.Zone#ZONE_BASE TargetZone The Zone object where the Target is located on the map. -- @param Core.Zone#ZONE_BASE TargetZone The Zone object where the Target is located on the map.
-- @param Wrapper.Unit#UNIT TaskUnit -- @param Wrapper.Unit#UNIT TaskUnit
@@ -268,7 +260,6 @@ do -- TASK_A2A
ActRouteTarget:SetZone( TargetZone, Altitude, Heading ) ActRouteTarget:SetZone( TargetZone, Altitude, Heading )
end end
--- @param #TASK_A2A self --- @param #TASK_A2A self
-- @param Wrapper.Unit#UNIT TaskUnit -- @param Wrapper.Unit#UNIT TaskUnit
-- @return Core.Zone#ZONE_BASE The Zone object where the Target is located on the map. -- @return Core.Zone#ZONE_BASE The Zone object where the Target is located on the map.
@@ -301,7 +292,6 @@ do -- TASK_A2A
return Distance return Distance
end end
--- This method checks every 10 seconds if the goal has been reached of the task. --- This method checks every 10 seconds if the goal has been reached of the task.
-- @param #TASK_A2A self -- @param #TASK_A2A self
function TASK_A2A:onafterGoal( TaskUnit, From, Event, To ) function TASK_A2A:onafterGoal( TaskUnit, From, Event, To )
@@ -314,7 +304,6 @@ do -- TASK_A2A
self:__Goal( -10 ) self:__Goal( -10 )
end end
--- @param #TASK_A2A self --- @param #TASK_A2A self
function TASK_A2A:UpdateTaskInfo( DetectedItem ) function TASK_A2A:UpdateTaskInfo( DetectedItem )
@@ -375,7 +364,6 @@ do -- TASK_A2A
end end
do -- TASK_A2A_INTERCEPT do -- TASK_A2A_INTERCEPT
--- The TASK_A2A_INTERCEPT class --- The TASK_A2A_INTERCEPT class
@@ -384,7 +372,7 @@ do -- TASK_A2A_INTERCEPT
-- @extends Tasking.Task#TASK -- @extends Tasking.Task#TASK
--- Defines an intercept task for a human player to be executed. --- Defines an intercept task for a human player to be executed.
-- When enemy planes need to be intercepted by human players, use this task type to urgen the players to get out there! -- When enemy planes need to be intercepted by human players, use this task type to urge the players to get out there!
-- --
-- The TASK_A2A_INTERCEPT is used by the @{Tasking.Task_A2A_Dispatcher#TASK_A2A_DISPATCHER} to automatically create intercept tasks -- The TASK_A2A_INTERCEPT is used by the @{Tasking.Task_A2A_Dispatcher#TASK_A2A_DISPATCHER} to automatically create intercept tasks
-- based on detected airborne enemy targets intruding friendly airspace. -- based on detected airborne enemy targets intruding friendly airspace.
@@ -394,11 +382,9 @@ do -- TASK_A2A_INTERCEPT
-- --
-- @field #TASK_A2A_INTERCEPT -- @field #TASK_A2A_INTERCEPT
TASK_A2A_INTERCEPT = { TASK_A2A_INTERCEPT = {
ClassName = "TASK_A2A_INTERCEPT", ClassName = "TASK_A2A_INTERCEPT"
} }
--- Instantiates a new TASK_A2A_INTERCEPT. --- Instantiates a new TASK_A2A_INTERCEPT.
-- @param #TASK_A2A_INTERCEPT self -- @param #TASK_A2A_INTERCEPT self
-- @param Tasking.Mission#MISSION Mission -- @param Tasking.Mission#MISSION Mission
@@ -413,10 +399,7 @@ do -- TASK_A2A_INTERCEPT
Mission:AddTask( self ) Mission:AddTask( self )
self:SetBriefing( self:SetBriefing( TaskBriefing or "Intercept incoming intruders.\n" )
TaskBriefing or
"Intercept incoming intruders.\n"
)
return self return self
end end
@@ -469,10 +452,8 @@ do -- TASK_A2A_INTERCEPT
return self return self
end end
end end
do -- TASK_A2A_SWEEP do -- TASK_A2A_SWEEP
--- The TASK_A2A_SWEEP class --- The TASK_A2A_SWEEP class
@@ -493,11 +474,9 @@ do -- TASK_A2A_SWEEP
-- --
-- @field #TASK_A2A_SWEEP -- @field #TASK_A2A_SWEEP
TASK_A2A_SWEEP = { TASK_A2A_SWEEP = {
ClassName = "TASK_A2A_SWEEP", ClassName = "TASK_A2A_SWEEP"
} }
--- Instantiates a new TASK_A2A_SWEEP. --- Instantiates a new TASK_A2A_SWEEP.
-- @param #TASK_A2A_SWEEP self -- @param #TASK_A2A_SWEEP self
-- @param Tasking.Mission#MISSION Mission -- @param Tasking.Mission#MISSION Mission
@@ -512,10 +491,7 @@ do -- TASK_A2A_SWEEP
Mission:AddTask( self ) Mission:AddTask( self )
self:SetBriefing( self:SetBriefing( TaskBriefing or "Perform a fighter sweep. Incoming intruders were detected and could be hiding at the location.\n" )
TaskBriefing or
"Perform a fighter sweep. Incoming intruders were detected and could be hiding at the location.\n"
)
return self return self
end end
@@ -581,7 +557,6 @@ do -- TASK_A2A_SWEEP
end end
do -- TASK_A2A_ENGAGE do -- TASK_A2A_ENGAGE
--- The TASK_A2A_ENGAGE class --- The TASK_A2A_ENGAGE class
@@ -600,11 +575,9 @@ do -- TASK_A2A_ENGAGE
-- --
-- @field #TASK_A2A_ENGAGE -- @field #TASK_A2A_ENGAGE
TASK_A2A_ENGAGE = { TASK_A2A_ENGAGE = {
ClassName = "TASK_A2A_ENGAGE", ClassName = "TASK_A2A_ENGAGE"
} }
--- Instantiates a new TASK_A2A_ENGAGE. --- Instantiates a new TASK_A2A_ENGAGE.
-- @param #TASK_A2A_ENGAGE self -- @param #TASK_A2A_ENGAGE self
-- @param Tasking.Mission#MISSION Mission -- @param Tasking.Mission#MISSION Mission
@@ -619,10 +592,7 @@ do -- TASK_A2A_ENGAGE
Mission:AddTask( self ) Mission:AddTask( self )
self:SetBriefing( self:SetBriefing( TaskBriefing or "Bogeys are nearby! Players close by are ordered to ENGAGE the intruders!\n" )
TaskBriefing or
"Bogeys are nearby! Players close by are ordered to ENGAGE the intruders!\n"
)
return self return self
end end

View File

@@ -108,7 +108,7 @@ do -- TASK_A2A_DISPATCHER
-- The above example creates a SET_GROUP instance, and stores this in the variable (object) **EWRSet**. -- The above example creates a SET_GROUP instance, and stores this in the variable (object) **EWRSet**.
-- **EWRSet** is then being configured to filter all active groups with a group name starting with **EWR** to be included in the Set. -- **EWRSet** is then being configured to filter all active groups with a group name starting with **EWR** to be included in the Set.
-- **EWRSet** is then being ordered to start the dynamic filtering. Note that any destroy or new spawn of a group with the above names will be removed or added to the Set. -- **EWRSet** is then being ordered to start the dynamic filtering. Note that any destroy or new spawn of a group with the above names will be removed or added to the Set.
-- Then a new **EWRDetection** object is created from the class DETECTION_AREAS. A grouping radius of 6000 is choosen, which is 6km. -- Then a new **EWRDetection** object is created from the class DETECTION_AREAS. A grouping radius of 6000 is chosen, which is 6 km.
-- The **EWRDetection** object is then passed to the @{#TASK_A2A_DISPATCHER.New}() method to indicate the EWR network configuration and setup the A2A tasking and detection mechanism. -- The **EWRDetection** object is then passed to the @{#TASK_A2A_DISPATCHER.New}() method to indicate the EWR network configuration and setup the A2A tasking and detection mechanism.
-- --
-- ### 2. Define the detected **target grouping radius**: -- ### 2. Define the detected **target grouping radius**:
@@ -185,7 +185,6 @@ do -- TASK_A2A_DISPATCHER
SweepZones = {}, SweepZones = {},
} }
--- TASK_A2A_DISPATCHER constructor. --- TASK_A2A_DISPATCHER constructor.
-- @param #TASK_A2A_DISPATCHER self -- @param #TASK_A2A_DISPATCHER self
-- @param Tasking.Mission#MISSION Mission The mission for which the task dispatching is done. -- @param Tasking.Mission#MISSION Mission The mission for which the task dispatching is done.
@@ -208,7 +207,6 @@ do -- TASK_A2A_DISPATCHER
self:AddTransition( "Started", "Assign", "Started" ) self:AddTransition( "Started", "Assign", "Started" )
--- OnAfter Transition Handler for Event Assign. --- OnAfter Transition Handler for Event Assign.
-- @function [parent=#TASK_A2A_DISPATCHER] OnAfterAssign -- @function [parent=#TASK_A2A_DISPATCHER] OnAfterAssign
-- @param #TASK_A2A_DISPATCHER self -- @param #TASK_A2A_DISPATCHER self
@@ -224,7 +222,6 @@ do -- TASK_A2A_DISPATCHER
return self return self
end end
--- Define the radius to when an ENGAGE task will be generated for any nearby by airborne friendlies, which are executing cap or returning from an intercept mission. --- Define the radius to when an ENGAGE task will be generated for any nearby by airborne friendlies, which are executing cap or returning from an intercept mission.
-- So, if there is a target area detected and reported, -- So, if there is a target area detected and reported,
-- then any friendlies that are airborne near this target area, -- then any friendlies that are airborne near this target area,
@@ -286,7 +283,6 @@ do -- TASK_A2A_DISPATCHER
return nil return nil
end end
--- Creates an SWEEP task when there are targets for it. --- Creates an SWEEP task when there are targets for it.
-- @param #TASK_A2A_DISPATCHER self -- @param #TASK_A2A_DISPATCHER self
-- @param Functional.Detection#DETECTION_BASE.DetectedItem DetectedItem -- @param Functional.Detection#DETECTION_BASE.DetectedItem DetectedItem
@@ -296,8 +292,7 @@ do -- TASK_A2A_DISPATCHER
self:F( { DetectedItem.ItemID } ) self:F( { DetectedItem.ItemID } )
local DetectedSet = DetectedItem.Set local DetectedSet = DetectedItem.Set
local DetectedZone = DetectedItem.Zone local DetectedZone = DetectedItem.Zone -- TODO: This seems unused, remove?
if DetectedItem.IsDetected == false then if DetectedItem.IsDetected == false then
@@ -312,7 +307,6 @@ do -- TASK_A2A_DISPATCHER
return nil return nil
end end
--- Creates an ENGAGE task when there are human friendlies airborne near the targets. --- Creates an ENGAGE task when there are human friendlies airborne near the targets.
-- @param #TASK_A2A_DISPATCHER self -- @param #TASK_A2A_DISPATCHER self
-- @param Functional.Detection#DETECTION_BASE.DetectedItem DetectedItem -- @param Functional.Detection#DETECTION_BASE.DetectedItem DetectedItem
@@ -322,11 +316,10 @@ do -- TASK_A2A_DISPATCHER
self:F( { DetectedItem.ItemID } ) self:F( { DetectedItem.ItemID } )
local DetectedSet = DetectedItem.Set local DetectedSet = DetectedItem.Set
local DetectedZone = DetectedItem.Zone local DetectedZone = DetectedItem.Zone -- TODO: This seems unused, remove?
local PlayersCount, PlayersReport = self:GetPlayerFriendliesNearBy( DetectedItem ) local PlayersCount, PlayersReport = self:GetPlayerFriendliesNearBy( DetectedItem )
-- Only allow ENGAGE when there are Players near the zone, and when the Area has detected items since the last run in a 60 seconds time zone. -- Only allow ENGAGE when there are Players near the zone, and when the Area has detected items since the last run in a 60 seconds time zone.
if PlayersCount > 0 and DetectedItem.IsDetected == true then if PlayersCount > 0 and DetectedItem.IsDetected == true then
@@ -341,9 +334,6 @@ do -- TASK_A2A_DISPATCHER
return nil return nil
end end
--- Evaluates the removal of the Task from the Mission. --- Evaluates the removal of the Task from the Mission.
-- Can only occur when the DetectedItem is Changed AND the state of the Task is "Planned". -- Can only occur when the DetectedItem is Changed AND the state of the Task is "Planned".
-- @param #TASK_A2A_DISPATCHER self -- @param #TASK_A2A_DISPATCHER self
@@ -443,7 +433,6 @@ do -- TASK_A2A_DISPATCHER
FriendlyTypesReport:Add( "-" ) FriendlyTypesReport:Add( "-" )
end end
return FriendliesCount, FriendlyTypesReport return FriendliesCount, FriendlyTypesReport
end end
@@ -487,7 +476,6 @@ do -- TASK_A2A_DISPATCHER
PlayerTypesReport:Add( "-" ) PlayerTypesReport:Add( "-" )
end end
return PlayersCount, PlayerTypesReport return PlayersCount, PlayerTypesReport
end end
@@ -496,7 +484,6 @@ do -- TASK_A2A_DISPATCHER
self.Tasks[TaskIndex] = nil self.Tasks[TaskIndex] = nil
end end
--- Assigns tasks in relation to the detected items to the @{Core.Set#SET_GROUP}. --- Assigns tasks in relation to the detected items to the @{Core.Set#SET_GROUP}.
-- @param #TASK_A2A_DISPATCHER self -- @param #TASK_A2A_DISPATCHER self
-- @param Functional.Detection#DETECTION_BASE Detection The detection created by the @{Functional.Detection#DETECTION_BASE} derived object. -- @param Functional.Detection#DETECTION_BASE Detection The detection created by the @{Functional.Detection#DETECTION_BASE} derived object.

View File

@@ -38,7 +38,7 @@ do -- TASK_A2G
-- --
-- @field #TASK_A2G -- @field #TASK_A2G
TASK_A2G = { TASK_A2G = {
ClassName = "TASK_A2G", ClassName = "TASK_A2G"
} }
--- Instantiates a new TASK_A2G. --- Instantiates a new TASK_A2G.
@@ -80,8 +80,6 @@ do -- TASK_A2G
Fsm:AddTransition( "Rejected", "Reject", "Aborted" ) Fsm:AddTransition( "Rejected", "Reject", "Aborted" )
Fsm:AddTransition( "Failed", "Fail", "Failed" ) Fsm:AddTransition( "Failed", "Fail", "Failed" )
--- Test --- Test
-- @param #FSM_PROCESS self -- @param #FSM_PROCESS self
-- @param Wrapper.Unit#UNIT TaskUnit -- @param Wrapper.Unit#UNIT TaskUnit
@@ -179,8 +177,6 @@ do -- TASK_A2G
self.TargetSetUnit = TargetSetUnit self.TargetSetUnit = TargetSetUnit
end end
--- @param #TASK_A2G self --- @param #TASK_A2G self
function TASK_A2G:GetPlannedMenuText() function TASK_A2G:GetPlannedMenuText()
return self:GetStateString() .. " - " .. self:GetTaskName() .. " ( " .. self.TargetSetUnit:GetUnitTypesText() .. " )" return self:GetStateString() .. " - " .. self:GetTaskName() .. " ( " .. self.TargetSetUnit:GetUnitTypesText() .. " )"
@@ -211,8 +207,6 @@ do -- TASK_A2G
return ActRouteRendezVous:GetCoordinate(), ActRouteRendezVous:GetRange() return ActRouteRendezVous:GetCoordinate(), ActRouteRendezVous:GetRange()
end end
--- @param #TASK_A2G self --- @param #TASK_A2G self
-- @param Core.Zone#ZONE_BASE RendezVousZone The Zone object where the RendezVous is located on the map. -- @param Core.Zone#ZONE_BASE RendezVousZone The Zone object where the RendezVous is located on the map.
-- @param Wrapper.Unit#UNIT TaskUnit -- @param Wrapper.Unit#UNIT TaskUnit
@@ -246,7 +240,6 @@ do -- TASK_A2G
ActRouteTarget:SetCoordinate( TargetCoordinate ) ActRouteTarget:SetCoordinate( TargetCoordinate )
end end
--- @param #TASK_A2G self --- @param #TASK_A2G self
-- @param Wrapper.Unit#UNIT TaskUnit -- @param Wrapper.Unit#UNIT TaskUnit
-- @return Core.Point#COORDINATE The Coordinate object where the Target is located on the map. -- @return Core.Point#COORDINATE The Coordinate object where the Target is located on the map.
@@ -258,7 +251,6 @@ do -- TASK_A2G
return ActRouteTarget:GetCoordinate() return ActRouteTarget:GetCoordinate()
end end
--- @param #TASK_A2G self --- @param #TASK_A2G self
-- @param Core.Zone#ZONE_BASE TargetZone The Zone object where the Target is located on the map. -- @param Core.Zone#ZONE_BASE TargetZone The Zone object where the Target is located on the map.
-- @param Wrapper.Unit#UNIT TaskUnit -- @param Wrapper.Unit#UNIT TaskUnit
@@ -270,7 +262,6 @@ do -- TASK_A2G
ActRouteTarget:SetZone( TargetZone ) ActRouteTarget:SetZone( TargetZone )
end end
--- @param #TASK_A2G self --- @param #TASK_A2G self
-- @param Wrapper.Unit#UNIT TaskUnit -- @param Wrapper.Unit#UNIT TaskUnit
-- @return Core.Zone#ZONE_BASE The Zone object where the Target is located on the map. -- @return Core.Zone#ZONE_BASE The Zone object where the Target is located on the map.
@@ -303,7 +294,6 @@ do -- TASK_A2G
return Distance return Distance
end end
--- This method checks every 10 seconds if the goal has been reached of the task. --- This method checks every 10 seconds if the goal has been reached of the task.
-- @param #TASK_A2G self -- @param #TASK_A2G self
function TASK_A2G:onafterGoal( TaskUnit, From, Event, To ) function TASK_A2G:onafterGoal( TaskUnit, From, Event, To )
@@ -381,7 +371,6 @@ do -- TASK_A2G
end end
do -- TASK_A2G_SEAD do -- TASK_A2G_SEAD
--- The TASK_A2G_SEAD class --- The TASK_A2G_SEAD class
@@ -397,7 +386,7 @@ do -- TASK_A2G_SEAD
-- --
-- @field #TASK_A2G_SEAD -- @field #TASK_A2G_SEAD
TASK_A2G_SEAD = { TASK_A2G_SEAD = {
ClassName = "TASK_A2G_SEAD", ClassName = "TASK_A2G_SEAD"
} }
--- Instantiates a new TASK_A2G_SEAD. --- Instantiates a new TASK_A2G_SEAD.
@@ -414,10 +403,7 @@ do -- TASK_A2G_SEAD
Mission:AddTask( self ) Mission:AddTask( self )
self:SetBriefing( self:SetBriefing( TaskBriefing or "Execute a Suppression of Enemy Air Defenses." )
TaskBriefing or
"Execute a Suppression of Enemy Air Defenses."
)
return self return self
end end
@@ -470,7 +456,6 @@ do -- TASK_A2G_SEAD
return self return self
end end
end end
do -- TASK_A2G_BAI do -- TASK_A2G_BAI
@@ -488,9 +473,7 @@ do -- TASK_A2G_BAI
-- based on detected enemy ground targets. -- based on detected enemy ground targets.
-- --
-- @field #TASK_A2G_BAI -- @field #TASK_A2G_BAI
TASK_A2G_BAI = { TASK_A2G_BAI = { ClassName = "TASK_A2G_BAI" }
ClassName = "TASK_A2G_BAI",
}
--- Instantiates a new TASK_A2G_BAI. --- Instantiates a new TASK_A2G_BAI.
-- @param #TASK_A2G_BAI self -- @param #TASK_A2G_BAI self
@@ -506,10 +489,7 @@ do -- TASK_A2G_BAI
Mission:AddTask( self ) Mission:AddTask( self )
self:SetBriefing( self:SetBriefing( TaskBriefing or "Execute a Battlefield Air Interdiction of a group of enemy targets." )
TaskBriefing or
"Execute a Battlefield Air Interdiction of a group of enemy targets."
)
return self return self
end end
@@ -564,9 +544,6 @@ do -- TASK_A2G_BAI
end end
do -- TASK_A2G_CAS do -- TASK_A2G_CAS
--- The TASK_A2G_CAS class --- The TASK_A2G_CAS class
@@ -581,9 +558,7 @@ do -- TASK_A2G_CAS
-- based on detected enemy ground targets. -- based on detected enemy ground targets.
-- --
-- @field #TASK_A2G_CAS -- @field #TASK_A2G_CAS
TASK_A2G_CAS = { TASK_A2G_CAS = { ClassName = "TASK_A2G_CAS" }
ClassName = "TASK_A2G_CAS",
}
--- Instantiates a new TASK_A2G_CAS. --- Instantiates a new TASK_A2G_CAS.
-- @param #TASK_A2G_CAS self -- @param #TASK_A2G_CAS self
@@ -599,17 +574,11 @@ do -- TASK_A2G_CAS
Mission:AddTask( self ) Mission:AddTask( self )
self:SetBriefing( self:SetBriefing( TaskBriefing or ( "Execute a Close Air Support for a group of enemy targets. " .. "Beware of friendlies at the vicinity! " ) )
TaskBriefing or
"Execute a Close Air Support for a group of enemy targets. " ..
"Beware of friendlies at the vicinity! "
)
return self return self
end end
--- Set a score when a target in scope of the A2G attack, has been destroyed . --- Set a score when a target in scope of the A2G attack, has been destroyed .
-- @param #TASK_A2G_CAS self -- @param #TASK_A2G_CAS self
-- @param #string PlayerName The name of the player. -- @param #string PlayerName The name of the player.
@@ -658,5 +627,4 @@ do -- TASK_A2G_CAS
return self return self
end end
end end

View File

@@ -6,11 +6,12 @@
-- * Dynamically change the tasks as the tactical situation evolves during the mission. -- * Dynamically change the tasks as the tactical situation evolves during the mission.
-- * Dynamically assign (CAS) Close Air Support tasks for human players. -- * Dynamically assign (CAS) Close Air Support tasks for human players.
-- * Dynamically assign (BAI) Battlefield Air Interdiction tasks for human players. -- * Dynamically assign (BAI) Battlefield Air Interdiction tasks for human players.
-- * Dynamically assign (SEAD) Supression of Enemy Air Defense tasks for human players to eliminate G2A missile threats. -- * Dynamically assign (SEAD) Suppression of Enemy Air Defense tasks for human players to eliminate G2A missile threats.
-- * Define and use an EWR (Early Warning Radar) network. -- * Define and use an EWR (Early Warning Radar) network.
-- * Define different ranges to engage upon intruders. -- * Define different ranges to engage upon intruders.
-- * Keep task achievements. -- * Keep task achievements.
-- * Score task achievements.-- -- * Score task achievements.
--
-- === -- ===
-- --
-- ### Author: **FlightControl** -- ### Author: **FlightControl**
@@ -122,7 +123,7 @@ do -- TASK_A2G_DISPATCHER
-- F1. Command Center [Lima] -- F1. Command Center [Lima]
-- F1. Mission "Overlord (High)" -- F1. Mission "Overlord (High)"
-- --
-- Command Center [Gori] is controlling Mission "Alpha", "Beta", "Gamma". Alpha is the Primary mission, Beta the Secondary and there is a Tacical mission Gamma. -- Command Center [Gori] is controlling Mission "Alpha", "Beta", "Gamma". Alpha is the Primary mission, Beta the Secondary and there is a Tactical mission Gamma.
-- Command Center [Lima] is controlling Missions "Overlord", which needs to be executed with High priority. -- Command Center [Lima] is controlling Missions "Overlord", which needs to be executed with High priority.
-- --
-- ## 1.1. Mission Menu (Under the Command Center Menu) -- ## 1.1. Mission Menu (Under the Command Center Menu)
@@ -196,7 +197,7 @@ do -- TASK_A2G_DISPATCHER
-- --
-- The Mission Reports Menu is a sub menu, that provides options to retrieve further information on the current Mission: -- The Mission Reports Menu is a sub menu, that provides options to retrieve further information on the current Mission:
-- --
-- - **Report Mission Progress**: Shows the progress of the current Mission. Each Task has a %-tage of completion. -- - **Report Mission Progress**: Shows the progress of the current Mission. Each Task has a % of completion.
-- - **Report Players per Task**: Show which players are engaged on which Task within the Mission. -- - **Report Players per Task**: Show which players are engaged on which Task within the Mission.
-- --
-- For CC |Gori|, Mission "Alpha", the Mission Reports menu structure could look like this: -- For CC |Gori|, Mission "Alpha", the Mission Reports menu structure could look like this:
@@ -264,7 +265,6 @@ do -- TASK_A2G_DISPATCHER
-- --
-- **The F5. Assigned Task __TaskName__ allows the player to control the current Assigned Task and take further actions.** -- **The F5. Assigned Task __TaskName__ allows the player to control the current Assigned Task and take further actions.**
-- --
--
-- ## 1.3. Join Planned Task Menu -- ## 1.3. Join Planned Task Menu
-- --
-- The Join Planned Task Menu contains the different Planned A2G Tasks **in a structured Menu Hierarchy**. -- The Join Planned Task Menu contains the different Planned A2G Tasks **in a structured Menu Hierarchy**.
@@ -388,7 +388,7 @@ do -- TASK_A2G_DISPATCHER
-- - A @{Mission} object. Each task belongs to a Mission. -- - A @{Mission} object. Each task belongs to a Mission.
-- - A @{Detection} object. There are several detection grouping methods to choose from. -- - A @{Detection} object. There are several detection grouping methods to choose from.
-- - A @{Task_A2G_Dispatcher} object. The master A2G task dispatcher. -- - A @{Task_A2G_Dispatcher} object. The master A2G task dispatcher.
-- - A @{Set} of @{Wrapper.Group} objects that will detect the emeny, the RecceSet. This is attached to the @{Detection} object. -- - A @{Set} of @{Wrapper.Group} objects that will detect the enemy, the RecceSet. This is attached to the @{Detection} object.
-- - A @{Set} ob @{Wrapper.Group} objects that will attack the enemy, the AttackSet. This is attached to the @{Task_A2G_Dispatcher} object. -- - A @{Set} ob @{Wrapper.Group} objects that will attack the enemy, the AttackSet. This is attached to the @{Task_A2G_Dispatcher} object.
-- --
-- Below an example mission declaration that is defines a Task A2G Dispatcher object. -- Below an example mission declaration that is defines a Task A2G Dispatcher object.
@@ -425,7 +425,7 @@ do -- TASK_A2G_DISPATCHER
-- --
-- -- Now we have everything to setup the main A2G TaskDispatcher. -- -- Now we have everything to setup the main A2G TaskDispatcher.
-- TaskDispatcher = TASK_A2G_DISPATCHER -- TaskDispatcher = TASK_A2G_DISPATCHER
-- :New( Mission, AttackSet, DetectionAreas ) -- We assign the TaskDispatcher under Mission. The AttackSet will engage the enemy and will recieve the dispatched Tasks. The DetectionAreas will report any detected enemies to the TaskDispatcher. -- :New( Mission, AttackSet, DetectionAreas ) -- We assign the TaskDispatcher under Mission. The AttackSet will engage the enemy and will receive the dispatched Tasks. The DetectionAreas will report any detected enemies to the TaskDispatcher.
-- --
-- --
-- --
@@ -434,10 +434,9 @@ do -- TASK_A2G_DISPATCHER
ClassName = "TASK_A2G_DISPATCHER", ClassName = "TASK_A2G_DISPATCHER",
Mission = nil, Mission = nil,
Detection = nil, Detection = nil,
Tasks = {}, Tasks = {}
} }
--- TASK_A2G_DISPATCHER constructor. --- TASK_A2G_DISPATCHER constructor.
-- @param #TASK_A2G_DISPATCHER self -- @param #TASK_A2G_DISPATCHER self
-- @param Tasking.Mission#MISSION Mission The mission for which the task dispatching is done. -- @param Tasking.Mission#MISSION Mission The mission for which the task dispatching is done.
@@ -518,7 +517,6 @@ do -- TASK_A2G_DISPATCHER
local DetectedSet = DetectedItem.Set local DetectedSet = DetectedItem.Set
local DetectedZone = DetectedItem.Zone local DetectedZone = DetectedItem.Zone
-- Determine if the set has ground units. -- Determine if the set has ground units.
-- There should be ground unit friendlies nearby. Airborne units are valid friendlies types. -- There should be ground unit friendlies nearby. Airborne units are valid friendlies types.
-- And there shouldn't be any radar. -- And there shouldn't be any radar.
@@ -550,7 +548,6 @@ do -- TASK_A2G_DISPATCHER
local DetectedSet = DetectedItem.Set local DetectedSet = DetectedItem.Set
local DetectedZone = DetectedItem.Zone local DetectedZone = DetectedItem.Zone
-- Determine if the set has ground units. -- Determine if the set has ground units.
-- There shouldn't be any ground unit friendlies nearby. -- There shouldn't be any ground unit friendlies nearby.
-- And there shouldn't be any radar. -- And there shouldn't be any radar.
@@ -571,7 +568,6 @@ do -- TASK_A2G_DISPATCHER
return nil return nil
end end
function TASK_A2G_DISPATCHER:RemoveTask( TaskIndex ) function TASK_A2G_DISPATCHER:RemoveTask( TaskIndex )
self.Mission:RemoveTask( self.Tasks[TaskIndex] ) self.Mission:RemoveTask( self.Tasks[TaskIndex] )
self.Tasks[TaskIndex] = nil self.Tasks[TaskIndex] = nil
@@ -597,7 +593,6 @@ do -- TASK_A2G_DISPATCHER
return Task return Task
end end
--- Assigns tasks in relation to the detected items to the @{Core.Set#SET_GROUP}. --- Assigns tasks in relation to the detected items to the @{Core.Set#SET_GROUP}.
-- @param #TASK_A2G_DISPATCHER self -- @param #TASK_A2G_DISPATCHER self
-- @param Functional.Detection#DETECTION_BASE Detection The detection created by the @{Functional.Detection#DETECTION_BASE} derived object. -- @param Functional.Detection#DETECTION_BASE Detection The detection created by the @{Functional.Detection#DETECTION_BASE} derived object.
@@ -800,14 +795,12 @@ do -- TASK_A2G_DISPATCHER
self:Aborted( Task ) self:Aborted( Task )
end end
TaskReport:Add( Task:GetName() ) TaskReport:Add( Task:GetName() )
else else
self:F( "This should not happen" ) self:F( "This should not happen" )
end end
end end
-- OK, so the tasking has been done, now delete the changes reported for the area. -- OK, so the tasking has been done, now delete the changes reported for the area.
Detection:AcceptChanges( DetectedItem ) Detection:AcceptChanges( DetectedItem )
end end

View File

@@ -11,7 +11,7 @@
-- --
-- DCS itself provides a lot of enumerators for various things. See [Enumerators](https://wiki.hoggitworld.com/view/Category:Enumerators) on Hoggit. -- DCS itself provides a lot of enumerators for various things. See [Enumerators](https://wiki.hoggitworld.com/view/Category:Enumerators) on Hoggit.
-- --
-- Other Moose classe also have enumerators. For example, the AIRBASE class has enumerators for airbase names. -- Other Moose classes also have enumerators. For example, the AIRBASE class has enumerators for airbase names.
-- --
-- @module ENUMS -- @module ENUMS
-- @image MOOSE.JPG -- @image MOOSE.JPG
@@ -30,7 +30,7 @@ ENUMS = {}
-- @type ENUMS.ROE -- @type ENUMS.ROE
-- @field #number WeaponFree AI will engage any enemy group it detects. Target prioritization is based based on the threat of the target. -- @field #number WeaponFree AI will engage any enemy group it detects. Target prioritization is based based on the threat of the target.
-- @field #number OpenFireWeaponFree AI will engage any enemy group it detects, but will prioritize targets specified in the groups tasking. -- @field #number OpenFireWeaponFree AI will engage any enemy group it detects, but will prioritize targets specified in the groups tasking.
-- @field #number OpenFire AI will engage only targets specified in its taskings. -- @field #number OpenFire AI will engage only targets specified in its tasking.
-- @field #number ReturnFire AI will only engage threats that shoot first. -- @field #number ReturnFire AI will only engage threats that shoot first.
-- @field #number WeaponHold AI will hold fire under all circumstances. -- @field #number WeaponHold AI will hold fire under all circumstances.
ENUMS.ROE = { ENUMS.ROE = {
@@ -67,7 +67,7 @@ ENUMS.AlarmState = {
Red = 2, Red = 2,
} }
--- Weapon types. See the [Weapon Flag](https://wiki.hoggitworld.com/view/DCS_enum_weapon_flag) enumerotor on hoggit wiki. --- Weapon types. See the [Weapon Flag](https://wiki.hoggitworld.com/view/DCS_enum_weapon_flag) enumerator on Hoggit wiki.
-- @type ENUMS.WeaponFlag -- @type ENUMS.WeaponFlag
ENUMS.WeaponFlag={ ENUMS.WeaponFlag={
-- Bombs -- Bombs
@@ -111,7 +111,7 @@ ENUMS.WeaponFlag={
-- --
-- Bombs -- Bombs
GuidedBomb = 14, -- (LGB + TvGB + SNSGB) GuidedBomb = 14, -- (LGB + TvGB + SNSGB)
AnyUnguidedBomb = 2147485680, -- (HeBomb + Penetrator + NapalmBomb + FAEBomb + ClusterBomb + Dispencer + CandleBomb + ParachuteBomb) AnyUnguidedBomb = 2147485680, -- (HeBomb + Penetrator + NapalmBomb + FAEBomb + ClusterBomb + Dispenser + CandleBomb + ParachuteBomb)
AnyBomb = 2147485694, -- (GuidedBomb + AnyUnguidedBomb) AnyBomb = 2147485694, -- (GuidedBomb + AnyUnguidedBomb)
--- Rockets --- Rockets
AnyRocket = 30720, -- LightRocket + MarkerRocket + CandleRocket + HeavyRocket AnyRocket = 30720, -- LightRocket + MarkerRocket + CandleRocket + HeavyRocket
@@ -173,7 +173,7 @@ ENUMS.MissionTask={
TRANSPORT="Transport", TRANSPORT="Transport",
} }
--- Formations (new). See the [Formations](https://wiki.hoggitworld.com/view/DCS_enum_formation) on hoggit wiki. --- Formations (new). See the [Formations](https://wiki.hoggitworld.com/view/DCS_enum_formation) on Hoggit wiki.
-- @type ENUMS.Formation -- @type ENUMS.Formation
ENUMS.Formation={} ENUMS.Formation={}
ENUMS.Formation.FixedWing={} ENUMS.Formation.FixedWing={}
@@ -244,7 +244,7 @@ ENUMS.Formation.Vehicle.Cone="Cone"
ENUMS.Formation.Vehicle.Diamond="Diamond" ENUMS.Formation.Vehicle.Diamond="Diamond"
--- Formations (old). The old format is a simplified version of the new formation enums, which allow more sophisticated settings. --- Formations (old). The old format is a simplified version of the new formation enums, which allow more sophisticated settings.
-- See the [Formations](https://wiki.hoggitworld.com/view/DCS_enum_formation) on hoggit wiki. -- See the [Formations](https://wiki.hoggitworld.com/view/DCS_enum_formation) on Hoggit wiki.
-- @type ENUMS.FormationOld -- @type ENUMS.FormationOld
ENUMS.FormationOld={} ENUMS.FormationOld={}
ENUMS.FormationOld.FixedWing={} ENUMS.FormationOld.FixedWing={}

View File

@@ -9,7 +9,6 @@
-- @module Utilities.PROFILER -- @module Utilities.PROFILER
-- @image MOOSE.JPG -- @image MOOSE.JPG
--- PROFILER class. --- PROFILER class.
-- @type PROFILER -- @type PROFILER
-- @field #string ClassName Name of the class. -- @field #string ClassName Name of the class.
@@ -25,7 +24,6 @@
-- @field #number ThreshTtot Total time threshold. Only write output if total function CPU time is more than this value. -- @field #number ThreshTtot Total time threshold. Only write output if total function CPU time is more than this value.
-- @field #string fileNamePrefix Output file name prefix, e.g. "MooseProfiler". -- @field #string fileNamePrefix Output file name prefix, e.g. "MooseProfiler".
-- @field #string fileNameSuffix Output file name prefix, e.g. "txt" -- @field #string fileNameSuffix Output file name prefix, e.g. "txt"
--- *The emperor counsels simplicity. First principles. Of each particular thing, ask: What is it in itself, in its own constitution? What is its causal nature? * --- *The emperor counsels simplicity. First principles. Of each particular thing, ask: What is it in itself, in its own constitution? What is its causal nature? *
-- --
-- === -- ===
@@ -35,12 +33,11 @@
-- # The PROFILER Concept -- # The PROFILER Concept
-- --
-- Profile your lua code. This tells you, which functions are called very often and which consume most real time. -- Profile your lua code. This tells you, which functions are called very often and which consume most real time.
-- With this information you can optimize the perfomance of your code. -- With this information you can optimize the performance of your code.
-- --
-- # Prerequisites -- # Prerequisites
-- --
-- The modules **os** and **lfs** need to be desanizied. -- The modules **os** and **lfs** need to be de-sanitized.
--
-- --
-- # Start -- # Start
-- --
@@ -122,15 +119,15 @@ function PROFILER.Start(Delay, Duration)
-- Check if os, io and lfs are available. -- Check if os, io and lfs are available.
local go = true local go = true
if not os then if not os then
env.error("ERROR: Profiler needs os to be desanitized!") env.error( "ERROR: Profiler needs os to be de-sanitized!" )
go = false go = false
end end
if not io then if not io then
env.error("ERROR: Profiler needs io to be desanitized!") env.error( "ERROR: Profiler needs io to be de-sanitized!" )
go = false go = false
end end
if not lfs then if not lfs then
env.error("ERROR: Profiler needs lfs to be desanitized!") env.error( "ERROR: Profiler needs lfs to be de-sanitized!" )
go = false go = false
end end
if not go then if not go then
@@ -161,7 +158,6 @@ function PROFILER.Start(Delay, Duration)
env.info( string.format( "- Output file \"%s\" in CSV format", PROFILER.getfilename( "csv" ) ) ) env.info( string.format( "- Output file \"%s\" in CSV format", PROFILER.getfilename( "csv" ) ) )
env.info( '###############################################################################' ) env.info( '###############################################################################' )
-- Message on screen -- Message on screen
local duration = Duration or 600 local duration = Duration or 600
trigger.action.outText( "### Profiler running ###", duration ) trigger.action.outText( "### Profiler running ###", duration )
@@ -191,7 +187,6 @@ function PROFILER.Stop(Delay)
-- Remove hook. -- Remove hook.
debug.sethook() debug.sethook()
-- Run time game. -- Run time game.
local runTimeGame = timer.getTime() - PROFILER.TstartGame local runTimeGame = timer.getTime() - PROFILER.TstartGame
@@ -337,7 +332,6 @@ function PROFILER.printCSV(data, runTimeGame)
g:close() g:close()
end end
--- Write info to output file. --- Write info to output file.
-- @param #string ext Extension. -- @param #string ext Extension.
-- @return #string File name. -- @return #string File name.
@@ -385,25 +379,20 @@ function PROFILER.showInfo(runTimeGame, runTimeOS)
local tforgen = nil -- #PROFILER.Data local tforgen = nil -- #PROFILER.Data
local tpairs = nil -- #PROFILER.Data local tpairs = nil -- #PROFILER.Data
for func, count in pairs( PROFILER.Counters ) do for func, count in pairs( PROFILER.Counters ) do
local s, src, line, tm = PROFILER.getData( func ) local s, src, line, tm = PROFILER.getData( func )
if PROFILER.logUnknown == true then if PROFILER.logUnknown == true then
if s==nil then s="<Unknown>" end if s == nil then
s = "<Unknown>"
end
end end
if s ~= nil then if s ~= nil then
-- Profile data. -- Profile data.
local T= local T = { func = s, src = src, line = line, count = count, tm = tm } -- #PROFILER.Data
{ func=s,
src=src,
line=line,
count=count,
tm=tm,
} --#PROFILER.Data
-- Collect special cases. Somehow, e.g. "_copy" appears multiple times so we try to gather all data. -- Collect special cases. Somehow, e.g. "_copy" appears multiple times so we try to gather all data.
if s == "_copy" then if s == "_copy" then
@@ -473,7 +462,9 @@ function PROFILER.showInfo(runTimeGame, runTimeOS)
env.info( "##############################################################################" ) env.info( "##############################################################################" )
-- Sort by total time. -- Sort by total time.
table.sort(t, function(a,b) return a.tm>b.tm end) table.sort( t, function( a, b )
return a.tm > b.tm
end )
-- Write data. -- Write data.
PROFILER._flog( f, "" ) PROFILER._flog( f, "" )
@@ -500,7 +491,9 @@ function PROFILER.showInfo(runTimeGame, runTimeOS)
PROFILER.showTable( t, f, runTimeGame ) PROFILER.showTable( t, f, runTimeGame )
-- Sort by number of calls. -- Sort by number of calls.
table.sort(t, function(a,b) return a.tm/a.count>b.tm/b.count end) table.sort( t, function( a, b )
return a.tm / a.count > b.tm / b.count
end )
-- Detailed data. -- Detailed data.
PROFILER._flog( f, "" ) PROFILER._flog( f, "" )
@@ -513,7 +506,9 @@ function PROFILER.showInfo(runTimeGame, runTimeOS)
PROFILER.showTable( t, f, runTimeGame ) PROFILER.showTable( t, f, runTimeGame )
-- Sort by number of calls. -- Sort by number of calls.
table.sort(t, function(a,b) return a.count>b.count end) table.sort( t, function( a, b )
return a.count > b.count
end )
-- Detailed data. -- Detailed data.
PROFILER._flog( f, "" ) PROFILER._flog( f, "" )
@@ -536,4 +531,3 @@ function PROFILER.showInfo(runTimeGame, runTimeOS)
-- Print csv file. -- Print csv file.
PROFILER.printCSV( t, runTimeGame ) PROFILER.printCSV( t, runTimeGame )
end end

View File

@@ -1,7 +1,6 @@
--- Various routines --- Various routines
-- @module routines -- @module routines
-- @image MOOSE.JPG -- @image MOOSE.JPG
env.setErrorMessageBoxEnabled( false ) env.setErrorMessageBoxEnabled( false )
--- Extract of MIST functions. --- Extract of MIST functions.
@@ -9,7 +8,6 @@ env.setErrorMessageBoxEnabled(false)
routines = {} routines = {}
-- don't change these -- don't change these
routines.majorVersion = 3 routines.majorVersion = 3
routines.minorVersion = 3 routines.minorVersion = 3
@@ -46,7 +44,6 @@ routines.utils.deepCopy = function(object)
return objectreturn return objectreturn
end end
-- porting in Slmod's serialize_slmod2 -- porting in Slmod's serialize_slmod2
routines.utils.oneLineSerialize = function( tbl ) -- serialization of a table all on a single line, no comments, made to replace old get_table_string function routines.utils.oneLineSerialize = function( tbl ) -- serialization of a table all on a single line, no comments, made to replace old get_table_string function
@@ -142,7 +139,6 @@ routines.utils.basicSerialize = function(s)
end end
end end
routines.utils.toDegree = function( angle ) routines.utils.toDegree = function( angle )
return angle * 180 / math.pi return angle * 180 / math.pi
end end
@@ -252,10 +248,6 @@ function routines.utils.get3DDist(point1, point2)
return routines.vec.mag( { x = point1.x - point2.x, y = point1.y - point2.y, z = point1.z - point2.z } ) return routines.vec.mag( { x = point1.x - point2.x, y = point1.y - point2.y, z = point1.z - point2.z } )
end end
-- 3D Vector manipulation -- 3D Vector manipulation
routines.vec = {} routines.vec = {}
@@ -295,16 +287,12 @@ routines.vec.rotateVec2 = function(vec2, theta)
end end
--------------------------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------------------------
-- acc- the accuracy of each easting/northing. 0, 1, 2, 3, 4, or 5. -- acc- the accuracy of each easting/northing. 0, 1, 2, 3, 4, or 5.
routines.tostringMGRS = function( MGRS, acc ) routines.tostringMGRS = function( MGRS, acc )
if acc == 0 then if acc == 0 then
return MGRS.UTMZone .. ' ' .. MGRS.MGRSDigraph return MGRS.UTMZone .. ' ' .. MGRS.MGRSDigraph
else else
return MGRS.UTMZone .. ' ' .. MGRS.MGRSDigraph .. ' ' .. string.format('%0' .. acc .. 'd', routines.utils.round(MGRS.Easting/(10^(5-acc)), 0)) return MGRS.UTMZone .. ' ' .. MGRS.MGRSDigraph .. ' ' .. string.format( '%0' .. acc .. 'd', routines.utils.round( MGRS.Easting / (10 ^ (5 - acc)), 0 ) ) .. ' ' .. string.format( '%0' .. acc .. 'd', routines.utils.round( MGRS.Northing / (10 ^ (5 - acc)), 0 ) )
.. ' ' .. string.format('%0' .. acc .. 'd', routines.utils.round(MGRS.Northing/(10^(5-acc)), 0))
end end
end end
@@ -366,8 +354,7 @@ routines.tostringLL = function(lat, lon, acc, DMS)
secFrmtStr = '%0' .. width .. '.' .. acc .. 'f' secFrmtStr = '%0' .. width .. '.' .. acc .. 'f'
end end
return string.format('%02d', latDeg) .. ' ' .. string.format('%02d', latMin) .. '\' ' .. string.format(secFrmtStr, latSec) .. '"' .. latHemi .. ' ' return string.format( '%02d', latDeg ) .. ' ' .. string.format( '%02d', latMin ) .. '\' ' .. string.format( secFrmtStr, latSec ) .. '"' .. latHemi .. ' ' .. string.format( '%02d', lonDeg ) .. ' ' .. string.format( '%02d', lonMin ) .. '\' ' .. string.format( secFrmtStr, lonSec ) .. '"' .. lonHemi
.. string.format('%02d', lonDeg) .. ' ' .. string.format('%02d', lonMin) .. '\' ' .. string.format(secFrmtStr, lonSec) .. '"' .. lonHemi
else -- degrees, decimal minutes. else -- degrees, decimal minutes.
latMin = routines.utils.round( latMin, acc ) latMin = routines.utils.round( latMin, acc )
@@ -391,8 +378,7 @@ routines.tostringLL = function(lat, lon, acc, DMS)
minFrmtStr = '%0' .. width .. '.' .. acc .. 'f' minFrmtStr = '%0' .. width .. '.' .. acc .. 'f'
end end
return string.format('%02d', latDeg) .. ' ' .. string.format(minFrmtStr, latMin) .. '\'' .. latHemi .. ' ' return string.format( '%02d', latDeg ) .. ' ' .. string.format( minFrmtStr, latMin ) .. '\'' .. latHemi .. ' ' .. string.format( '%02d', lonDeg ) .. ' ' .. string.format( minFrmtStr, lonMin ) .. '\'' .. lonHemi
.. string.format('%02d', lonDeg) .. ' ' .. string.format(minFrmtStr, lonMin) .. '\'' .. lonHemi
end end
end end
@@ -433,7 +419,6 @@ routines.getNorthCorrection = function(point) --gets the correction needed for
return math.atan2( north_posit.z - point.z, north_posit.x - point.x ) return math.atan2( north_posit.z - point.z, north_posit.x - point.x )
end end
do do
local idNum = 0 local idNum = 0
@@ -489,14 +474,7 @@ function routines.getRandPointInCircle(point, radius, innerRadius)
end end
routines.goRoute = function( group, path ) routines.goRoute = function( group, path )
local misTask = { local misTask = { id = 'Mission', params = { route = { points = routines.utils.deepCopy( path ) } } }
id = 'Mission',
params = {
route = {
points = routines.utils.deepCopy(path),
},
},
}
if type( group ) == 'string' then if type( group ) == 'string' then
group = Group.getByName( group ) group = Group.getByName( group )
end end
@@ -510,7 +488,6 @@ routines.goRoute = function(group, path)
return false return false
end end
-- Useful atomic functions from mist, ported. -- Useful atomic functions from mist, ported.
routines.ground = {} routines.ground = {}
@@ -569,9 +546,7 @@ routines.ground.buildWP = function(point, overRideForm, overRideSpeed)
end end
wp.type = 'Turning Point' wp.type = 'Turning Point'
return wp return wp
end end
routines.fixedWing.buildWP = function( point, WPtype, speed, alt, altType ) routines.fixedWing.buildWP = function( point, WPtype, speed, alt, altType )
@@ -702,7 +677,6 @@ routines.groupToRandomPoint = function(vars)
local headingDegrees = vars.headingDegrees local headingDegrees = vars.headingDegrees
local speed = vars.speed or routines.utils.kmphToMps( 20 ) local speed = vars.speed or routines.utils.kmphToMps( 20 )
local useRoads local useRoads
if not vars.disableRoads then if not vars.disableRoads then
useRoads = true useRoads = true
@@ -729,7 +703,6 @@ routines.groupToRandomPoint = function(vars)
offset.z = routines.utils.round( math.cos( heading + (math.pi / 2) ) * 50 + rndCoord.y, 3 ) offset.z = routines.utils.round( math.cos( heading + (math.pi / 2) ) * 50 + rndCoord.y, 3 )
path[#path + 1] = routines.ground.buildWP( posStart, form, speed ) path[#path + 1] = routines.ground.buildWP( posStart, form, speed )
if useRoads == true and ((point.x - posStart.x) ^ 2 + (point.z - posStart.z) ^ 2) ^ 0.5 > radius * 1.3 then if useRoads == true and ((point.x - posStart.x) ^ 2 + (point.z - posStart.z) ^ 2) ^ 0.5 > radius * 1.3 then
path[#path + 1] = routines.ground.buildWP( { ['x'] = posStart.x + 11, ['z'] = posStart.z + 11 }, 'off_road', speed ) path[#path + 1] = routines.ground.buildWP( { ['x'] = posStart.x + 11, ['z'] = posStart.z + 11 }, 'off_road', speed )
path[#path + 1] = routines.ground.buildWP( posStart, 'on_road', speed ) path[#path + 1] = routines.ground.buildWP( posStart, 'on_road', speed )
@@ -742,8 +715,6 @@ routines.groupToRandomPoint = function(vars)
path[#path + 1] = routines.ground.buildWP( rndCoord, form, speed ) path[#path + 1] = routines.ground.buildWP( rndCoord, form, speed )
routines.goRoute( group, path ) routines.goRoute( group, path )
return
end end
routines.groupRandomDistSelf = function( gpData, dist, form, heading, speed ) routines.groupRandomDistSelf = function( gpData, dist, form, heading, speed )
@@ -752,8 +723,6 @@ routines.groupRandomDistSelf = function(gpData, dist, form, heading, speed)
fakeZone.radius = dist or math.random( 300, 1000 ) fakeZone.radius = dist or math.random( 300, 1000 )
fakeZone.point = { x = pos.x, y, pos.y, z = pos.z } fakeZone.point = { x = pos.x, y, pos.y, z = pos.z }
routines.groupToRandomZone( gpData, fakeZone, form, heading, speed ) routines.groupToRandomZone( gpData, fakeZone, form, heading, speed )
return
end end
routines.groupToRandomZone = function( gpData, zone, form, heading, speed ) routines.groupToRandomZone = function( gpData, zone, form, heading, speed )
@@ -780,8 +749,6 @@ routines.groupToRandomZone = function(gpData, zone, form, heading, speed)
vars.point = routines.utils.zoneToVec3( zone ) vars.point = routines.utils.zoneToVec3( zone )
routines.groupToRandomPoint( vars ) routines.groupToRandomPoint( vars )
return
end end
routines.isTerrainValid = function( coord, terrainTypes ) -- vec2/3 and enum or table of acceptable terrain types routines.isTerrainValid = function( coord, terrainTypes ) -- vec2/3 and enum or table of acceptable terrain types
@@ -829,11 +796,8 @@ routines.groupToPoint = function(gpData, point, form, heading, speed, useRoads)
vars.disableRoads = useRoads vars.disableRoads = useRoads
vars.point = routines.utils.zoneToVec3( point ) vars.point = routines.utils.zoneToVec3( point )
routines.groupToRandomPoint( vars ) routines.groupToRandomPoint( vars )
return
end end
routines.getLeadPos = function( group ) routines.getLeadPos = function( group )
if type( group ) == 'string' then -- group name if type( group ) == 'string' then -- group name
group = Group.getByName( group ) group = Group.getByName( group )
@@ -934,7 +898,6 @@ routines.getBRString = function(vars)
end end
end end
-- Returns the Vec3 coordinates of the average position of the concentration of units most in the heading direction. -- Returns the Vec3 coordinates of the average position of the concentration of units most in the heading direction.
--[[ vars for routines.getLeadingPos: --[[ vars for routines.getLeadingPos:
vars.units - table of unit names vars.units - table of unit names
@@ -992,7 +955,6 @@ routines.getLeadingPos = function(vars)
end end
end end
--[[ vars for routines.getLeadingMGRSString: --[[ vars for routines.getLeadingMGRSString:
vars.units - table of unit names vars.units - table of unit names
vars.heading - direction vars.heading - direction
@@ -1026,8 +988,6 @@ routines.getLeadingLLString = function(vars)
end end
end end
--[[ vars for routines.getLeadingBRString: --[[ vars for routines.getLeadingBRString:
vars.units - table of unit names vars.units - table of unit names
vars.heading - direction, number vars.heading - direction, number
@@ -1083,11 +1043,7 @@ routines.msgMGRS = function(vars)
newText = text .. s newText = text .. s
end end
routines.message.add{ routines.message.add { text = newText, displayTime = displayTime, msgFor = msgFor }
text = newText,
displayTime = displayTime,
msgFor = msgFor
}
end end
--[[ vars for routines.msgLL --[[ vars for routines.msgLL
@@ -1114,15 +1070,10 @@ routines.msgLL = function(vars)
newText = text .. s newText = text .. s
end end
routines.message.add{ routines.message.add { text = newText, displayTime = displayTime, msgFor = msgFor }
text = newText,
displayTime = displayTime,
msgFor = msgFor
}
end end
--[[ --[[
vars.units- table of unit names (NOT unitNameTable- maybe this should change). vars.units- table of unit names (NOT unitNameTable- maybe this should change).
vars.ref - vec3 ref point, maybe overload for vec2 as well? vars.ref - vec3 ref point, maybe overload for vec2 as well?
@@ -1149,15 +1100,10 @@ routines.msgBR = function(vars)
newText = text .. s newText = text .. s
end end
routines.message.add{ routines.message.add { text = newText, displayTime = displayTime, msgFor = msgFor }
text = newText,
displayTime = displayTime,
msgFor = msgFor
}
end end
-------------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------------
-- basically, just sub-types of routines.msgBR... saves folks the work of getting the ref point. -- basically, just sub-types of routines.msgBR... saves folks the work of getting the ref point.
--[[ --[[
@@ -1228,14 +1174,9 @@ routines.msgLeadingMGRS = function(vars)
newText = text .. s newText = text .. s
end end
routines.message.add{ routines.message.add { text = newText, displayTime = displayTime, msgFor = msgFor }
text = newText,
displayTime = displayTime,
msgFor = msgFor
}
end end
--[[ vars for routines.msgLeadingLL: --[[ vars for routines.msgLeadingLL:
vars.units - table of unit names vars.units - table of unit names
vars.heading - direction, number vars.heading - direction, number
@@ -1266,12 +1207,7 @@ routines.msgLeadingLL = function(vars)
newText = text .. s newText = text .. s
end end
routines.message.add{ routines.message.add { text = newText, displayTime = displayTime, msgFor = msgFor }
text = newText,
displayTime = displayTime,
msgFor = msgFor
}
end end
--[[ --[[
@@ -1306,23 +1242,22 @@ routines.msgLeadingBR = function(vars)
newText = text .. s newText = text .. s
end end
routines.message.add{ routines.message.add { text = newText, displayTime = displayTime, msgFor = msgFor }
text = newText,
displayTime = displayTime,
msgFor = msgFor
}
end end
function spairs( t, order ) function spairs( t, order )
-- collect the keys -- collect the keys
local keys = {} local keys = {}
for k in pairs(t) do keys[#keys+1] = k end for k in pairs( t ) do
keys[#keys + 1] = k
end
-- if order function given, sort by it by passing the table and keys a, b, -- if order function given, sort by it by passing the table and keys a, b,
-- otherwise just sort the keys -- otherwise just sort the keys
if order then if order then
table.sort(keys, function(a,b) return order(t, a, b) end) table.sort( keys, function( a, b )
return order( t, a, b )
end )
else else
table.sort( keys ) table.sort( keys )
end end
@@ -1337,7 +1272,6 @@ function spairs(t, order)
end end
end end
function routines.IsPartOfGroupInZones( CargoGroup, LandingZones ) function routines.IsPartOfGroupInZones( CargoGroup, LandingZones )
-- trace.f() -- trace.f()
@@ -1359,8 +1293,6 @@ function routines.IsPartOfGroupInZones( CargoGroup, LandingZones )
return CurrentZoneID return CurrentZoneID
end end
function routines.IsUnitInZones( TransportUnit, LandingZones ) function routines.IsUnitInZones( TransportUnit, LandingZones )
-- trace.f("", "routines.IsUnitInZones" ) -- trace.f("", "routines.IsUnitInZones" )
@@ -1441,7 +1373,6 @@ function routines.IsUnitNearZonesRadius( TransportUnit, LandingZones, ZoneRadius
end end
end end
function routines.IsStaticInZones( TransportStatic, LandingZones ) function routines.IsStaticInZones( TransportStatic, LandingZones )
-- trace.f() -- trace.f()
@@ -1474,7 +1405,6 @@ function routines.IsStaticInZones( TransportStatic, LandingZones )
return TransportZoneResult return TransportZoneResult
end end
function routines.IsUnitInRadius( CargoUnit, ReferencePosition, Radius ) function routines.IsUnitInRadius( CargoUnit, ReferencePosition, Radius )
-- trace.f() -- trace.f()
@@ -1517,7 +1447,6 @@ function routines.IsPartOfGroupInRadius( CargoGroup, ReferencePosition, Radius )
return Valid return Valid
end end
function routines.ValidateString( Variable, VariableName, Valid ) function routines.ValidateString( Variable, VariableName, Valid )
-- trace.f() -- trace.f()
@@ -1546,7 +1475,6 @@ function routines.ValidateNumber( Variable, VariableName, Valid )
-- trace.r( "", "", { Valid } ) -- trace.r( "", "", { Valid } )
return Valid return Valid
end end
function routines.ValidateGroup( Variable, VariableName, Valid ) function routines.ValidateGroup( Variable, VariableName, Valid )
@@ -1672,7 +1600,6 @@ end
routines.ground.patrolRoute = function( vars ) routines.ground.patrolRoute = function( vars )
local tempRoute = {} local tempRoute = {}
local useRoute = {} local useRoute = {}
local gpData = vars.gpData local gpData = vars.gpData
@@ -1698,7 +1625,6 @@ routines.ground.patrolRoute = function(vars)
routeProvided = true routeProvided = true
end end
local overRideSpeed = vars.speed or 'default' local overRideSpeed = vars.speed or 'default'
local pType = vars.pType local pType = vars.pType
local offRoadForm = vars.offRoadForm or 'default' local offRoadForm = vars.offRoadForm or 'default'
@@ -1707,7 +1633,6 @@ routines.ground.patrolRoute = function(vars)
if routeProvided == false and #tempRoute > 0 then if routeProvided == false and #tempRoute > 0 then
local posStart = routines.getLeadPos( gpData ) local posStart = routines.getLeadPos( gpData )
useRoute[#useRoute + 1] = routines.ground.buildWP( posStart, offRoadForm, overRideSpeed ) useRoute[#useRoute + 1] = routines.ground.buildWP( posStart, offRoadForm, overRideSpeed )
for i = 1, #tempRoute do for i = 1, #tempRoute do
local tempForm = tempRoute[i].action local tempForm = tempRoute[i].action
@@ -1729,7 +1654,6 @@ routines.ground.patrolRoute = function(vars)
tempSpeed = overRideSpeed tempSpeed = overRideSpeed
end end
useRoute[#useRoute + 1] = routines.ground.buildWP( tempRoute[i], tempForm, tempSpeed ) useRoute[#useRoute + 1] = routines.ground.buildWP( tempRoute[i], tempForm, tempSpeed )
end end
@@ -1751,24 +1675,10 @@ routines.ground.patrolRoute = function(vars)
cTask3[#cTask3 + 1] = routines.utils.oneLineSerialize( newPatrol ) cTask3[#cTask3 + 1] = routines.utils.oneLineSerialize( newPatrol )
cTask3[#cTask3 + 1] = ')' cTask3[#cTask3 + 1] = ')'
cTask3 = table.concat( cTask3 ) cTask3 = table.concat( cTask3 )
local tempTask = { local tempTask = { id = 'WrappedAction', params = { action = { id = 'Script', params = { command = cTask3 } } } }
id = 'WrappedAction',
params = {
action = {
id = 'Script',
params = {
command = cTask3,
},
},
},
}
useRoute[#useRoute].task = tempTask useRoute[#useRoute].task = tempTask
routines.goRoute( gpData, useRoute ) routines.goRoute( gpData, useRoute )
return
end end
routines.ground.patrol = function( gpData, pType, form, speed ) routines.ground.patrol = function( gpData, pType, form, speed )
@@ -1785,8 +1695,6 @@ routines.ground.patrol = function(gpData, pType, form, speed)
vars.speed = speed vars.speed = speed
routines.ground.patrolRoute( vars ) routines.ground.patrolRoute( vars )
return
end end
function routines.GetUnitHeight( CheckUnit ) function routines.GetUnitHeight( CheckUnit )
@@ -1803,11 +1711,8 @@ function routines.GetUnitHeight( CheckUnit )
-- trace.f( "routines", "Unit Height = " .. UnitHeight - LandHeight ) -- trace.f( "routines", "Unit Height = " .. UnitHeight - LandHeight )
return UnitHeight - LandHeight return UnitHeight - LandHeight
end end
Su34Status = { status = {} } Su34Status = { status = {} }
boardMsgRed = { statusMsg = "" } boardMsgRed = { statusMsg = "" }
boardMsgAll = { timeMsg = "" } boardMsgAll = { timeMsg = "" }
@@ -1815,7 +1720,6 @@ SpawnSettings = {}
Su34MenuPath = {} Su34MenuPath = {}
Su34Menus = 0 Su34Menus = 0
function Su34AttackCarlVinson( groupName ) function Su34AttackCarlVinson( groupName )
-- trace.menu("", "Su34AttackCarlVinson") -- trace.menu("", "Su34AttackCarlVinson")
local groupSu34 = Group.getByName( groupName ) local groupSu34 = Group.getByName( groupName )
@@ -1982,7 +1886,6 @@ function Su34OverviewStatus()
boardMsgRed.statusMsg = msg boardMsgRed.statusMsg = msg
end end
function UpdateBoardMsg() function UpdateBoardMsg()
-- trace.f() -- trace.f()
Su34OverviewStatus() Su34OverviewStatus()
@@ -2007,63 +1910,22 @@ function Su34Menu(groupName)
-- env.info(( 'Su34Menu(' .. groupName .. ')' )) -- env.info(( 'Su34Menu(' .. groupName .. ')' ))
local groupSu34 = Group.getByName( groupName ) local groupSu34 = Group.getByName( groupName )
if Su34Status.status[groupName] == 1 or if Su34Status.status[groupName] == 1 or Su34Status.status[groupName] == 2 or Su34Status.status[groupName] == 3 or Su34Status.status[groupName] == 4 or Su34Status.status[groupName] == 5 then
Su34Status.status[groupName] == 2 or
Su34Status.status[groupName] == 3 or
Su34Status.status[groupName] == 4 or
Su34Status.status[groupName] == 5 then
if Su34MenuPath[groupName] == nil then if Su34MenuPath[groupName] == nil then
if planeMenuPath == nil then if planeMenuPath == nil then
planeMenuPath = missionCommands.addSubMenuForCoalition( planeMenuPath = missionCommands.addSubMenuForCoalition( coalition.side.RED, "SU-34 anti-ship flights", nil )
coalition.side.RED,
"SU-34 anti-ship flights",
nil
)
end end
Su34MenuPath[groupName] = missionCommands.addSubMenuForCoalition( Su34MenuPath[groupName] = missionCommands.addSubMenuForCoalition( coalition.side.RED, "Flight " .. groupName, planeMenuPath )
coalition.side.RED,
"Flight " .. groupName,
planeMenuPath
)
missionCommands.addCommandForCoalition( missionCommands.addCommandForCoalition( coalition.side.RED, "Attack carrier Carl Vinson", Su34MenuPath[groupName], Su34AttackCarlVinson, groupName )
coalition.side.RED,
"Attack carrier Carl Vinson",
Su34MenuPath[groupName],
Su34AttackCarlVinson,
groupName
)
missionCommands.addCommandForCoalition( missionCommands.addCommandForCoalition( coalition.side.RED, "Attack ships in the west", Su34MenuPath[groupName], Su34AttackWest, groupName )
coalition.side.RED,
"Attack ships in the west",
Su34MenuPath[groupName],
Su34AttackWest,
groupName
)
missionCommands.addCommandForCoalition( missionCommands.addCommandForCoalition( coalition.side.RED, "Attack ships in the north", Su34MenuPath[groupName], Su34AttackNorth, groupName )
coalition.side.RED,
"Attack ships in the north",
Su34MenuPath[groupName],
Su34AttackNorth,
groupName
)
missionCommands.addCommandForCoalition( missionCommands.addCommandForCoalition( coalition.side.RED, "Hold position and await instructions", Su34MenuPath[groupName], Su34Orbit, groupName )
coalition.side.RED,
"Hold position and await instructions",
Su34MenuPath[groupName],
Su34Orbit,
groupName
)
missionCommands.addCommandForCoalition( missionCommands.addCommandForCoalition( coalition.side.RED, "Report status", Su34MenuPath[groupName], Su34OverviewStatus )
coalition.side.RED,
"Report status",
Su34MenuPath[groupName],
Su34OverviewStatus
)
end end
else else
if Su34MenuPath[groupName] then if Su34MenuPath[groupName] then
@@ -2207,32 +2069,23 @@ function EscortCarrier ( CarrierGroup, EscortPrefix, EscortLastWayPoint, EscortE
EscortMission.units[u].unitId = nil EscortMission.units[u].unitId = nil
end end
EscortMission.route.points[1].task = {
EscortMission.route.points[1].task = { id = "ComboTask", id = "ComboTask",
params = params = {
{ tasks = {
tasks = [1] = {
{
[1] =
{
enabled = true, enabled = true,
auto = false, auto = false,
id = "Escort", id = "Escort",
number = 1, number = 1,
params = params = {
{
lastWptIndexFlagChangedManually = false, lastWptIndexFlagChangedManually = false,
groupId = CarrierGroup:getID(), groupId = CarrierGroup:getID(),
lastWptIndex = nil, lastWptIndex = nil,
lastWptIndexFlag = false, lastWptIndexFlag = false,
engagementDistMax = EscortEngagementDistanceMax, engagementDistMax = EscortEngagementDistanceMax,
targetTypes = EscortTargetTypes, targetTypes = EscortTargetTypes,
pos = pos = { y = 20, x = 20, z = 0 } -- end of ["pos"]
{
y = 20,
x = 20,
z = 0,
} -- end of ["pos"]
} -- end of ["params"] } -- end of ["params"]
} -- end of [1] } -- end of [1]
} -- end of ["tasks"] } -- end of ["tasks"]
@@ -2325,7 +2178,6 @@ function getCarrierHeight( CarrierGroup )
else else
return 999999 return 999999
end end
end end
function GetUnitHeight( CheckUnit ) function GetUnitHeight( CheckUnit )
@@ -2340,16 +2192,13 @@ function GetUnitHeight( CheckUnit )
-- env.info(( 'CarrierHeight: LandHeight = ' .. LandHeight .. ' CarrierHeight = ' .. CarrierHeight )) -- env.info(( 'CarrierHeight: LandHeight = ' .. LandHeight .. ' CarrierHeight = ' .. CarrierHeight ))
return UnitHeight - LandHeight return UnitHeight - LandHeight
end end
_MusicTable = {} _MusicTable = {}
_MusicTable.Files = {} _MusicTable.Files = {}
_MusicTable.Queue = {} _MusicTable.Queue = {}
_MusicTable.FileCnt = 0 _MusicTable.FileCnt = 0
function MusicRegister( SndRef, SndFile, SndTime ) function MusicRegister( SndRef, SndFile, SndTime )
-- trace.f() -- trace.f()
@@ -2357,7 +2206,6 @@ function MusicRegister( SndRef, SndFile, SndTime )
env.info( ('MusicRegister: SndFile = ' .. SndFile) ) env.info( ('MusicRegister: SndFile = ' .. SndFile) )
env.info( ('MusicRegister: SndTime = ' .. SndTime) ) env.info( ('MusicRegister: SndTime = ' .. SndTime) )
_MusicTable.FileCnt = _MusicTable.FileCnt + 1 _MusicTable.FileCnt = _MusicTable.FileCnt + 1
_MusicTable.Files[_MusicTable.FileCnt] = {} _MusicTable.Files[_MusicTable.FileCnt] = {}
@@ -2368,7 +2216,6 @@ function MusicRegister( SndRef, SndFile, SndTime )
if not _MusicTable.Function then if not _MusicTable.Function then
_MusicTable.Function = routines.scheduleFunction( MusicScheduler, {}, timer.getTime() + 10, 10 ) _MusicTable.Function = routines.scheduleFunction( MusicScheduler, {}, timer.getTime() + 10, 10 )
end end
end end
function MusicToPlayer( SndRef, PlayerName, SndContinue ) function MusicToPlayer( SndRef, PlayerName, SndContinue )
@@ -2391,7 +2238,6 @@ function MusicToPlayer( SndRef, PlayerName, SndContinue )
end end
-- env.info(( 'MusicToPlayer: end' )) -- env.info(( 'MusicToPlayer: end' ))
end end
function MusicToGroup( SndRef, SndGroup, SndContinue ) function MusicToGroup( SndRef, SndGroup, SndContinue )
@@ -2494,9 +2340,6 @@ function MusicScheduler()
end end
end end
end end
end end
env.info( ('Init: Scripts Loaded v1.1') ) env.info( ('Init: Scripts Loaded v1.1') )

View File

@@ -1,7 +1,6 @@
--- **Utilities** DCS Simple Text-To-Speech (STTS). --- **Utilities** DCS Simple Text-To-Speech (STTS).
-- --
-- --
--
-- @module Utils.STTS -- @module Utils.STTS
-- @image MOOSE.JPG -- @image MOOSE.JPG
@@ -15,7 +14,7 @@
-- --
-- # DCS Modification Required -- # DCS Modification Required
-- --
-- You will need to edit MissionScripting.lua in DCS World/Scripts/MissionScripting.lua and remove the sanitisation. -- You will need to edit MissionScripting.lua in DCS World/Scripts/MissionScripting.lua and remove the sanitization.
-- To do this remove all the code below the comment - the line starts "local function sanitizeModule(name)" -- To do this remove all the code below the comment - the line starts "local function sanitizeModule(name)"
-- Do this without DCS running to allow mission scripts to use os functions. -- Do this without DCS running to allow mission scripts to use os functions.
-- --
@@ -23,7 +22,7 @@
-- --
-- # USAGE: -- # USAGE:
-- --
-- Add this script into the mission as a DO SCRIPT or DO SCRIPT FROM FILE to initialise it -- Add this script into the mission as a DO SCRIPT or DO SCRIPT FROM FILE to initialize it
-- Make sure to edit the STTS.SRS_PORT and STTS.DIRECTORY to the correct values before adding to the mission. -- Make sure to edit the STTS.SRS_PORT and STTS.DIRECTORY to the correct values before adding to the mission.
-- Then its as simple as calling the correct function in LUA as a DO SCRIPT or in your own scripts. -- Then its as simple as calling the correct function in LUA as a DO SCRIPT or in your own scripts.
-- --
@@ -43,7 +42,7 @@
-- * OPTIONAL - Speed -10 to +10 -- * OPTIONAL - Speed -10 to +10
-- * OPTIONAL - Gender male, female or neuter -- * OPTIONAL - Gender male, female or neuter
-- * OPTIONAL - Culture - en-US, en-GB etc -- * OPTIONAL - Culture - en-US, en-GB etc
-- * OPTIONAL - Voice - a specfic voice by name. Run DCS-SR-ExternalAudio.exe with --help to get the ones you can use on the command line -- * OPTIONAL - Voice - a specific voice by name. Run DCS-SR-ExternalAudio.exe with --help to get the ones you can use on the command line
-- * OPTIONAL - Google TTS - Switch to Google Text To Speech - Requires STTS.GOOGLE_CREDENTIALS path and Google project setup correctly -- * OPTIONAL - Google TTS - Switch to Google Text To Speech - Requires STTS.GOOGLE_CREDENTIALS path and Google project setup correctly
-- --
-- --
@@ -80,7 +79,7 @@ STTS={
DIRECTORY = "", DIRECTORY = "",
SRS_PORT = 5002, SRS_PORT = 5002,
GOOGLE_CREDENTIALS = "C:\\Users\\Ciaran\\Downloads\\googletts.json", GOOGLE_CREDENTIALS = "C:\\Users\\Ciaran\\Downloads\\googletts.json",
EXECUTABLE="DCS-SR-ExternalAudio.exe", EXECUTABLE = "DCS-SR-ExternalAudio.exe"
} }
--- FULL Path to the FOLDER containing DCS-SR-ExternalAudio.exe - EDIT TO CORRECT FOLDER --- FULL Path to the FOLDER containing DCS-SR-ExternalAudio.exe - EDIT TO CORRECT FOLDER
@@ -92,10 +91,9 @@ STTS.SRS_PORT = 5002
--- Google credentials file --- Google credentials file
STTS.GOOGLE_CREDENTIALS = "C:\\Users\\Ciaran\\Downloads\\googletts.json" STTS.GOOGLE_CREDENTIALS = "C:\\Users\\Ciaran\\Downloads\\googletts.json"
--- DONT CHANGE THIS UNLESS YOU KNOW WHAT YOU'RE DOING --- DON'T CHANGE THIS UNLESS YOU KNOW WHAT YOU'RE DOING
STTS.EXECUTABLE = "DCS-SR-ExternalAudio.exe" STTS.EXECUTABLE = "DCS-SR-ExternalAudio.exe"
--- Function for UUID. --- Function for UUID.
function STTS.uuid() function STTS.uuid()
local random = math.random local random = math.random
@@ -112,16 +110,20 @@ end
function STTS.round( x, n ) function STTS.round( x, n )
n = math.pow( 10, n or 0 ) n = math.pow( 10, n or 0 )
x = x * n x = x * n
if x >= 0 then x = math.floor(x + 0.5) else x = math.ceil(x - 0.5) end if x >= 0 then
x = math.floor( x + 0.5 )
else
x = math.ceil( x - 0.5 )
end
return x / n return x / n
end end
--- Function returns estimated speech time in seconds. --- Function returns estimated speech time in seconds.
-- Assumptions for time calc: 100 Words per min, avarage of 5 letters for english word so -- Assumptions for time calc: 100 Words per min, average of 5 letters for english word so
-- --
-- * 5 chars * 100wpm = 500 characters per min = 8.3 chars per second -- * 5 chars * 100wpm = 500 characters per min = 8.3 chars per second
-- --
-- So lengh of msg / 8.3 = number of seconds needed to read it. rounded down to 8 chars per sec map function: -- So length of msg / 8.3 = number of seconds needed to read it. rounded down to 8 chars per sec map function:
-- --
-- * (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min -- * (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min
-- --
@@ -170,7 +172,6 @@ function STTS.TextToSpeech(message, freqs, modulations, volume, name, coalition,
volume = 1 volume = 1
speed = 1 speed = 1
message = message:gsub( "\"", "\\\"" ) message = message:gsub( "\"", "\\\"" )
local cmd = string.format( "start /min \"\" /d \"%s\" /b \"%s\" -f %s -m %s -c %s -p %s -n \"%s\" -h", STTS.DIRECTORY, STTS.EXECUTABLE, freqs or "305", modulations or "AM", coalition, STTS.SRS_PORT, name ) local cmd = string.format( "start /min \"\" /d \"%s\" /b \"%s\" -f %s -m %s -c %s -p %s -n \"%s\" -h", STTS.DIRECTORY, STTS.EXECUTABLE, freqs or "305", modulations or "AM", coalition, STTS.SRS_PORT, name )
@@ -237,8 +238,7 @@ end
-- @param #string volume Volume, e.g. "0.5". -- @param #string volume Volume, e.g. "0.5".
function STTS.PlayMP3( pathToMP3, freqs, modulations, volume, name, coalition, point ) function STTS.PlayMP3( pathToMP3, freqs, modulations, volume, name, coalition, point )
local cmd = string.format("start \"\" /d \"%s\" /b /min \"%s\" -i \"%s\" -f %s -m %s -c %s -p %s -n \"%s\" -v %s -h", local cmd = string.format( "start \"\" /d \"%s\" /b /min \"%s\" -i \"%s\" -f %s -m %s -c %s -p %s -n \"%s\" -v %s -h", STTS.DIRECTORY, STTS.EXECUTABLE, pathToMP3, freqs or "305", modulations or "AM", coalition or "0", STTS.SRS_PORT, name or "ROBOT", volume or "1" )
STTS.DIRECTORY, STTS.EXECUTABLE, pathToMP3, freqs or "305", modulations or "AM", coalition or "0", STTS.SRS_PORT, name or "ROBOT", volume or "1")
if point and type( point ) == "table" and point.x then if point and type( point ) == "table" and point.x then
local lat, lon, alt = coord.LOtoLL( point ) local lat, lon, alt = coord.LOtoLL( point )

View File

@@ -11,7 +11,6 @@
-- @module Utils -- @module Utils
-- @image MOOSE.JPG -- @image MOOSE.JPG
--- @type SMOKECOLOR --- @type SMOKECOLOR
-- @field Green -- @field Green
-- @field Red -- @field Red
@@ -58,10 +57,9 @@ DCSMAP = {
PersianGulf = "PersianGulf", PersianGulf = "PersianGulf",
TheChannel = "TheChannel", TheChannel = "TheChannel",
Syria = "Syria", Syria = "Syria",
MarianaIslands="MarianaIslands" MarianaIslands = "MarianaIslands",
} }
--- See [DCS_enum_callsigns](https://wiki.hoggitworld.com/view/DCS_enum_callsigns) --- See [DCS_enum_callsigns](https://wiki.hoggitworld.com/view/DCS_enum_callsigns)
-- @type CALLSIGN -- @type CALLSIGN
CALLSIGN = { CALLSIGN = {
@@ -201,7 +199,6 @@ UTILS.IsInstanceOf = function( object, className )
return false return false
end end
--- Deep copy a table. See http://lua-users.org/wiki/CopyTable --- Deep copy a table. See http://lua-users.org/wiki/CopyTable
-- @param #table object The input table. -- @param #table object The input table.
-- @return #table Copy of the input table. -- @return #table Copy of the input table.
@@ -233,7 +230,6 @@ UTILS.DeepCopy = function(object)
return objectreturn return objectreturn
end end
--- Porting in Slmod's serialize_slmod2. --- Porting in Slmod's serialize_slmod2.
-- @param #table tbl Input table. -- @param #table tbl Input table.
UTILS.OneLineSerialize = function( tbl ) -- serialization of a table all on a single line, no comments, made to replace old get_table_string function UTILS.OneLineSerialize = function( tbl ) -- serialization of a table all on a single line, no comments, made to replace old get_table_string function
@@ -326,7 +322,6 @@ UTILS.BasicSerialize = function(s)
end end
end end
UTILS.ToDegree = function( angle ) UTILS.ToDegree = function( angle )
return angle * 180 / math.pi return angle * 180 / math.pi
end end
@@ -409,24 +404,28 @@ end
-- @param #number knots Speed in knots. -- @param #number knots Speed in knots.
-- @return #number Speed in m/s. -- @return #number Speed in m/s.
UTILS.KnotsToMps = function( knots ) UTILS.KnotsToMps = function( knots )
if type(knots) == "number" then
return knots / 1.94384 --* 1852 / 3600 return knots / 1.94384 --* 1852 / 3600
else
return 0
end
end end
--- Convert temperature from Celsius to Farenheit. --- Convert temperature from Celsius to Fahrenheit.
-- @param #number Celcius Temperature in degrees Celsius. -- @param #number Celsius Temperature in degrees Celsius.
-- @return #number Temperature in degrees Farenheit. -- @return #number Temperature in degrees Fahrenheit.
UTILS.CelciusToFarenheit = function( Celcius ) UTILS.CelsiusToFahrenheit = function( Celsius )
return Celcius * 9/5 + 32 return Celsius * 9 / 5 + 32
end end
--- Convert pressure from hecto Pascal (hPa) to inches of mercury (inHg). --- Convert pressure from hectopascal (hPa) to inches of mercury (inHg).
-- @param #number hPa Pressure in hPa. -- @param #number hPa Pressure in hPa.
-- @return #number Pressure in inHg. -- @return #number Pressure in inHg.
UTILS.hPa2inHg = function( hPa ) UTILS.hPa2inHg = function( hPa )
return hPa * 0.0295299830714 return hPa * 0.0295299830714
end end
--- Convert knots to alitude corrected KIAS, e.g. for tankers. --- Convert knots to altitude corrected KIAS, e.g. for tankers.
-- @param #number knots Speed in knots. -- @param #number knots Speed in knots.
-- @param #number altitude Altitude in feet -- @param #number altitude Altitude in feet
-- @return #number Corrected KIAS -- @return #number Corrected KIAS
@@ -434,14 +433,14 @@ UTILS.KnotsToAltKIAS = function( knots, altitude )
return (knots * 0.018 * (altitude / 1000)) + knots return (knots * 0.018 * (altitude / 1000)) + knots
end end
--- Convert pressure from hecto Pascal (hPa) to millimeters of mercury (mmHg). --- Convert pressure from hectopascal (hPa) to millimeters of mercury (mmHg).
-- @param #number hPa Pressure in hPa. -- @param #number hPa Pressure in hPa.
-- @return #number Pressure in mmHg. -- @return #number Pressure in mmHg.
UTILS.hPa2mmHg = function( hPa ) UTILS.hPa2mmHg = function( hPa )
return hPa * 0.7500615613030 return hPa * 0.7500615613030
end end
--- Convert kilo gramms (kg) to pounds (lbs). --- Convert kilograms (kg) to pounds (lbs).
-- @param #number kg Mass in kg. -- @param #number kg Mass in kg.
-- @return #number Mass in lbs. -- @return #number Mass in lbs.
UTILS.kg2lbs = function( kg ) UTILS.kg2lbs = function( kg )
@@ -508,8 +507,7 @@ UTILS.tostringLL = function( lat, lon, acc, DMS)
end end
-- 024° 23' 12"N or 024° 23' 12.03"N -- 024° 23' 12"N or 024° 23' 12.03"N
return string.format('%03d°', latDeg)..string.format('%02d', latMin)..'\''..string.format(secFrmtStr, latSec)..'"'..latHemi..' ' return string.format( '%03d°', latDeg ) .. string.format( '%02d', latMin ) .. '\'' .. string.format( secFrmtStr, latSec ) .. '"' .. latHemi .. ' ' .. string.format( '%03d°', lonDeg ) .. string.format( '%02d', lonMin ) .. '\'' .. string.format( secFrmtStr, lonSec ) .. '"' .. lonHemi
.. string.format('%03d°', lonDeg)..string.format('%02d', lonMin)..'\''..string.format(secFrmtStr, lonSec)..'"'..lonHemi
else -- degrees, decimal minutes. else -- degrees, decimal minutes.
latMin = UTILS.Round( latMin, acc ) latMin = UTILS.Round( latMin, acc )
@@ -534,8 +532,7 @@ UTILS.tostringLL = function( lat, lon, acc, DMS)
end end
-- 024 23'N or 024 23.123'N -- 024 23'N or 024 23.123'N
return string.format('%03d°', latDeg) .. ' ' .. string.format(minFrmtStr, latMin) .. '\'' .. latHemi .. ' ' return string.format( '%03d°', latDeg ) .. ' ' .. string.format( minFrmtStr, latMin ) .. '\'' .. latHemi .. ' ' .. string.format( '%03d°', lonDeg ) .. ' ' .. string.format( minFrmtStr, lonMin ) .. '\'' .. lonHemi
.. string.format('%03d°', lonDeg) .. ' ' .. string.format(minFrmtStr, lonMin) .. '\'' .. lonHemi
end end
end end
@@ -560,8 +557,12 @@ UTILS.tostringMGRS = function(MGRS, acc) --R2.1
local nN = 5 - string.len( Northing ) local nN = 5 - string.len( Northing )
-- Get leading zeros (if any). -- Get leading zeros (if any).
for i=1,nE do Easting="0"..Easting end for i = 1, nE do
for i=1,nN do Northing="0"..Northing end Easting = "0" .. Easting
end
for i = 1, nN do
Northing = "0" .. Northing
end
-- Return MGRS string. -- Return MGRS string.
return string.format( "%s %s %s %s", MGRS.UTMZone, MGRS.MGRSDigraph, string.sub( Easting, 1, acc ), string.sub( Northing, 1, acc ) ) return string.format( "%s %s %s %s", MGRS.UTMZone, MGRS.MGRSDigraph, string.sub( Easting, 1, acc ), string.sub( Northing, 1, acc ) )
@@ -569,7 +570,6 @@ UTILS.tostringMGRS = function(MGRS, acc) --R2.1
end end
--- From http://lua-users.org/wiki/SimpleRound --- From http://lua-users.org/wiki/SimpleRound
-- use negative idp for rounding ahead of decimal place, positive for rounding after decimal place -- use negative idp for rounding ahead of decimal place, positive for rounding after decimal place
function UTILS.Round( num, idp ) function UTILS.Round( num, idp )
@@ -591,12 +591,16 @@ end
function UTILS.spairs( t, order ) function UTILS.spairs( t, order )
-- collect the keys -- collect the keys
local keys = {} local keys = {}
for k in pairs(t) do keys[#keys+1] = k end for k in pairs( t ) do
keys[#keys + 1] = k
end
-- if order function given, sort by it by passing the table and keys a, b, -- if order function given, sort by it by passing the table and keys a, b,
-- otherwise just sort the keys -- otherwise just sort the keys
if order then if order then
table.sort(keys, function(a,b) return order(t, a, b) end) table.sort( keys, function( a, b )
return order( t, a, b )
end )
else else
table.sort( keys ) table.sort( keys )
end end
@@ -611,18 +615,22 @@ function UTILS.spairs( t, order )
end end
end end
-- Here is a customized version of pairs, which I called kpairs because it iterates over the table in a sorted order, based on a function that will determine the keys as reference first. -- Here is a customized version of pairs, which I called kpairs because it iterates over the table in a sorted order, based on a function that will determine the keys as reference first.
function UTILS.kpairs( t, getkey, order ) function UTILS.kpairs( t, getkey, order )
-- collect the keys -- collect the keys
local keys = {} local keys = {}
local keyso = {} local keyso = {}
for k, o in pairs(t) do keys[#keys+1] = k keyso[#keyso+1] = getkey( o ) end for k, o in pairs( t ) do
keys[#keys + 1] = k
keyso[#keyso + 1] = getkey( o )
end
-- if order function given, sort by it by passing the table and keys a, b, -- if order function given, sort by it by passing the table and keys a, b,
-- otherwise just sort the keys -- otherwise just sort the keys
if order then if order then
table.sort(keys, function(a,b) return order(t, a, b) end) table.sort( keys, function( a, b )
return order( t, a, b )
end )
else else
table.sort( keys ) table.sort( keys )
end end
@@ -642,7 +650,9 @@ function UTILS.rpairs( t )
-- collect the keys -- collect the keys
local keys = {} local keys = {}
for k in pairs(t) do keys[#keys+1] = k end for k in pairs( t ) do
keys[#keys + 1] = k
end
local random = {} local random = {}
local j = #keys local j = #keys
@@ -681,7 +691,6 @@ function UTILS.RemoveMark(MarkID, Delay)
end end
end end
-- Test if a Vec2 is in a radius of another Vec2 -- Test if a Vec2 is in a radius of another Vec2
function UTILS.IsInRadius( InVec2, Vec2, Radius ) function UTILS.IsInRadius( InVec2, Vec2, Radius )
@@ -748,9 +757,9 @@ function UTILS.BeaufortScale(speed)
return bn, bd return bn, bd
end end
--- Split string at seperators. C.f. http://stackoverflow.com/questions/1426954/split-string-in-lua --- Split string at separators. C.f. http://stackoverflow.com/questions/1426954/split-string-in-lua
-- @param #string str Sting to split. -- @param #string str Sting to split.
-- @param #string sep Speparator for split. -- @param #string sep Separator for split.
-- @return #table Split text. -- @return #table Split text.
function UTILS.Split( str, sep ) function UTILS.Split( str, sep )
local result = {} local result = {}
@@ -827,7 +836,7 @@ function UTILS.SecondsOfToday()
return UTILS.ClockToSeconds( clock ) return UTILS.ClockToSeconds( clock )
end end
--- Cound seconds until next midnight. --- Count seconds until next midnight.
-- @return #number Seconds to midnight. -- @return #number Seconds to midnight.
function UTILS.SecondsToMidnight() function UTILS.SecondsToMidnight()
return 24 * 60 * 60 - UTILS.SecondsOfToday() return 24 * 60 * 60 - UTILS.SecondsOfToday()
@@ -970,6 +979,14 @@ function UTILS.VecDot(a, b)
return a.x * b.x + a.y * b.y + a.z * b.z return a.x * b.x + a.y * b.y + a.z * b.z
end end
--- Calculate the [dot product](https://en.wikipedia.org/wiki/Dot_product) of two 2D vectors. The result is a number.
-- @param DCS#Vec2 a Vector in 2D with x, y components.
-- @param DCS#Vec2 b Vector in 2D with x, y components.
-- @return #number Scalar product of the two vectors a*b.
function UTILS.Vec2Dot( a, b )
return a.x * b.x + a.y * b.y
end
--- Calculate the [euclidean norm](https://en.wikipedia.org/wiki/Euclidean_distance) (length) of a 3D vector. --- Calculate the [euclidean norm](https://en.wikipedia.org/wiki/Euclidean_distance) (length) of a 3D vector.
-- @param DCS#Vec3 a Vector in 3D with x, y, z components. -- @param DCS#Vec3 a Vector in 3D with x, y, z components.
-- @return #number Norm of the vector. -- @return #number Norm of the vector.
@@ -977,6 +994,13 @@ function UTILS.VecNorm(a)
return math.sqrt( UTILS.VecDot( a, a ) ) return math.sqrt( UTILS.VecDot( a, a ) )
end end
--- Calculate the [euclidean norm](https://en.wikipedia.org/wiki/Euclidean_distance) (length) of a 2D vector.
-- @param DCS#Vec2 a Vector in 2D with x, y components.
-- @return #number Norm of the vector.
function UTILS.Vec2Norm( a )
return math.sqrt( UTILS.Vec2Dot( a, a ) )
end
--- Calculate the distance between two 2D vectors. --- Calculate the distance between two 2D vectors.
-- @param DCS#Vec2 a Vector in 3D with x, y components. -- @param DCS#Vec2 a Vector in 3D with x, y components.
-- @param DCS#Vec2 b Vector in 3D with x, y components. -- @param DCS#Vec2 b Vector in 3D with x, y components.
@@ -990,7 +1014,6 @@ function UTILS.VecDist2D(a, b)
return d return d
end end
--- Calculate the distance between two 3D vectors. --- Calculate the distance between two 3D vectors.
-- @param DCS#Vec3 a Vector in 3D with x, y, z components. -- @param DCS#Vec3 a Vector in 3D with x, y, z components.
-- @param DCS#Vec3 b Vector in 3D with x, y, z components. -- @param DCS#Vec3 b Vector in 3D with x, y, z components.
@@ -1059,6 +1082,17 @@ function UTILS.VecHdg(a)
return h return h
end end
--- Calculate "heading" of a 2D vector in the X-Y plane.
-- @param DCS#Vec2 a Vector in "D with x, y components.
-- @return #number Heading in degrees in [0,360).
function UTILS.Vec2Hdg( a )
local h = math.deg( math.atan2( a.y, a.x ) )
if h < 0 then
h = h + 360
end
return h
end
--- Calculate the difference between two "heading", i.e. angles in [0,360) deg. --- Calculate the difference between two "heading", i.e. angles in [0,360) deg.
-- @param #number h1 Heading one. -- @param #number h1 Heading one.
-- @param #number h2 Heading two. -- @param #number h2 Heading two.
@@ -1078,7 +1112,6 @@ function UTILS.HdgDiff(h1, h2)
return math.abs( delta ) return math.abs( delta )
end end
--- Translate 3D vector in the 2D (x,z) plane. y-component (usually altitude) unchanged. --- Translate 3D vector in the 2D (x,z) plane. y-component (usually altitude) unchanged.
-- @param DCS#Vec3 a Vector in 3D with x, y, z components. -- @param DCS#Vec3 a Vector in 3D with x, y, z components.
-- @param #number distance The distance to translate. -- @param #number distance The distance to translate.
@@ -1095,6 +1128,22 @@ function UTILS.VecTranslate(a, distance, angle)
return { x = TX, y = a.y, z = TY } return { x = TX, y = a.y, z = TY }
end end
--- Translate 2D vector in the 2D (x,z) plane.
-- @param DCS#Vec2 a Vector in 2D with x, y components.
-- @param #number distance The distance to translate.
-- @param #number angle Rotation angle in degrees.
-- @return DCS#Vec2 Translated vector.
function UTILS.Vec2Translate( a, distance, angle )
local SX = a.x
local SY = a.y
local Radians = math.rad( angle or 0 )
local TX = distance * math.cos( Radians ) + SX
local TY = distance * math.sin( Radians ) + SY
return { x = TX, y = TY }
end
--- Rotate 3D vector in the 2D (x,z) plane. y-component (usually altitude) unchanged. --- Rotate 3D vector in the 2D (x,z) plane. y-component (usually altitude) unchanged.
-- @param DCS#Vec3 a Vector in 3D with x, y, z components. -- @param DCS#Vec3 a Vector in 3D with x, y, z components.
-- @param #number angle Rotation angle in degrees. -- @param #number angle Rotation angle in degrees.
@@ -1115,6 +1164,24 @@ function UTILS.Rotate2D(a, angle)
return A return A
end end
--- Rotate 2D vector in the 2D (x,z) plane.
-- @param DCS#Vec2 a Vector in 2D with x, y components.
-- @param #number angle Rotation angle in degrees.
-- @return DCS#Vec2 Vector rotated in the (x,y) plane.
function UTILS.Vec2Rotate2D( a, angle )
local phi = math.rad( angle )
local x = a.x
local y = a.y
local X = x * math.cos( phi ) - y * math.sin( phi )
local Y = x * math.sin( phi ) + y * math.cos( phi )
local A = { x = X, y = Y }
return A
end
--- Converts a TACAN Channel/Mode couple into a frequency in Hz. --- Converts a TACAN Channel/Mode couple into a frequency in Hz.
-- @param #number TACANChannel The TACAN channel, i.e. the 10 in "10X". -- @param #number TACANChannel The TACAN channel, i.e. the 10 in "10X".
@@ -1152,7 +1219,6 @@ function UTILS.TACANToFrequency(TACANChannel, TACANMode)
return (A + TACANChannel - B) * 1000000 return (A + TACANChannel - B) * 1000000
end end
--- Returns the DCS map/theatre as optained by env.mission.theatre --- Returns the DCS map/theatre as optained by env.mission.theatre
-- @return #string DCS map name. -- @return #string DCS map name.
function UTILS.GetDCSMap() function UTILS.GetDCSMap()
@@ -1287,7 +1353,6 @@ function UTILS.CheckMemory(output)
return mem return mem
end end
--- Get the coalition name from its numerical ID, e.g. coaliton.side.RED. --- Get the coalition name from its numerical ID, e.g. coaliton.side.RED.
-- @param #number Coalition The coalition ID. -- @param #number Coalition The coalition ID.
-- @return #string The coalition name, i.e. "Neutral", "Red" or "Blue" (or "Unknown"). -- @return #string The coalition name, i.e. "Neutral", "Red" or "Blue" (or "Unknown").
@@ -1387,7 +1452,6 @@ function UTILS.GMTToLocalTimeDifference()
end end
--- Get the day of the year. Counting starts on 1st of January. --- Get the day of the year. Counting starts on 1st of January.
-- @param #number Year The year. -- @param #number Year The year.
-- @param #number Month The month. -- @param #number Month The month.
@@ -1421,18 +1485,31 @@ function UTILS.GetSunRiseAndSet(DayOfYear, Latitude, Longitude, Rising, Tlocal)
local n = DayOfYear local n = DayOfYear
Tlocal = Tlocal or 0 Tlocal = Tlocal or 0
-- Short cuts. -- Short cuts.
local rad = math.rad local rad = math.rad
local deg = math.deg local deg = math.deg
local floor = math.floor local floor = math.floor
local frac = function(n) return n - floor(n) end local frac = function( n )
local cos = function(d) return math.cos(rad(d)) end return n - floor( n )
local acos = function(d) return deg(math.acos(d)) end end
local sin = function(d) return math.sin(rad(d)) end local cos = function( d )
local asin = function(d) return deg(math.asin(d)) end return math.cos( rad( d ) )
local tan = function(d) return math.tan(rad(d)) end end
local atan = function(d) return deg(math.atan(d)) end local acos = function( d )
return deg( math.acos( d ) )
end
local sin = function( d )
return math.sin( rad( d ) )
end
local asin = function( d )
return deg( math.asin( d ) )
end
local tan = function( d )
return math.tan( rad( d ) )
end
local atan = function( d )
return deg( math.atan( d ) )
end
local function fit_into_range( val, min, max ) local function fit_into_range( val, min, max )
local range = max - min local range = max - min
@@ -1549,7 +1626,7 @@ function UTILS.GetOSTime()
end end
--- Shuffle a table accoring to Fisher Yeates algorithm --- Shuffle a table accoring to Fisher Yeates algorithm
--@param #table table to be shuffled -- @param #table t Table to be shuffled
-- @return #table -- @return #table
function UTILS.ShuffleTable( t ) function UTILS.ShuffleTable( t )
if t == nil or type( t ) ~= "table" then if t == nil or type( t ) ~= "table" then
@@ -1613,6 +1690,11 @@ function UTILS.IsLoadingDoorOpen( unit_name )
ret_val = true ret_val = true
end end
if string.find( type_name, "Bell-47" ) then -- bell aint got no doors so always ready to load injured soldiers
BASE:T( unit_name .. " door is open" )
ret_val = true
end
if ret_val == false then if ret_val == false then
BASE:T( unit_name .. " all doors are closed" ) BASE:T( unit_name .. " all doors are closed" )
end end
@@ -1756,9 +1838,7 @@ function UTILS.GenerateLaserCodes()
while _code < 1777 and _count < 30 do while _code < 1777 and _count < 30 do
while true do while true do
_code = _code + 1 _code = _code + 1
if not ContainsDigit(_code, 8) if not ContainsDigit( _code, 8 ) and not ContainsDigit( _code, 9 ) and not ContainsDigit( _code, 0 ) then
and not ContainsDigit(_code, 9)
and not ContainsDigit(_code, 0) then
table.insert( jtacGeneratedLaserCodes, _code ) table.insert( jtacGeneratedLaserCodes, _code )
break break
end end
@@ -1767,3 +1847,427 @@ function UTILS.GenerateLaserCodes()
end end
return jtacGeneratedLaserCodes return jtacGeneratedLaserCodes
end end
--- Function to save an object to a file
-- @param #string Path The path to use. Use double backslashes \\\\ on Windows filesystems.
-- @param #string Filename The name of the file. Existing file will be overwritten.
-- @param #table Data The LUA data structure to save. This will be e.g. a table of text lines with an \\n at the end of each line.
-- @return #boolean outcome True if saving is possible, else false.
function UTILS.SaveToFile( Path, Filename, Data )
-- Thanks to @FunkyFranky
-- Check io module is available.
if not io then
BASE:E( "ERROR: io not desanitized. Can't save current file." )
return false
end
-- Check default path.
if Path == nil and not lfs then
BASE:E( "WARNING: lfs not desanitized. File will be saved in DCS installation root directory rather than your \"Saved Games\\DCS\" folder." )
end
-- Set path or default.
local path = nil
if lfs then
path = Path or lfs.writedir()
end
-- Set file name.
local filename = Filename
if path ~= nil then
filename = path .. "\\" .. filename
end
-- write
local f = assert( io.open( filename, "wb" ) )
f:write( Data )
f:close()
return true
end
--- Function to save an object to a file
-- @param #string Path The path to use. Use double backslashes \\\\ on Windows filesystems.
-- @param #string Filename The name of the file.
-- @return #boolean outcome True if reading is possible and successful, else false.
-- @return #table data The data read from the filesystem (table of lines of text). Each line is one single #string!
function UTILS.LoadFromFile( Path, Filename )
-- Thanks to @FunkyFranky
-- Check io module is available.
if not io then
BASE:E( "ERROR: io not desanitized. Can't save current state." )
return false
end
-- Check default path.
if Path == nil and not lfs then
BASE:E( "WARNING: lfs not desanitized. Loading will look into your DCS installation root directory rather than your \"Saved Games\\DCS\" folder." )
end
-- Set path or default.
local path = nil
if lfs then
path = Path or lfs.writedir()
end
-- Set file name.
local filename = Filename
if path ~= nil then
filename = path .. "\\" .. filename
end
-- Check if file exists.
local exists = UTILS.CheckFileExists( Path, Filename )
if not exists then
BASE:E( string.format( "ERROR: File %s does not exist!", filename ) )
return false
end
-- read
local file = assert( io.open( filename, "rb" ) )
local loadeddata = {}
for line in file:lines() do
loadeddata[#loadeddata + 1] = line
end
file:close()
return true, loadeddata
end
--- Function to check if a file exists.
-- @param #string Path The path to use. Use double backslashes \\\\ on Windows filesystems.
-- @param #string Filename The name of the file.
-- @return #boolean outcome True if reading is possible, else false.
function UTILS.CheckFileExists( Path, Filename )
-- Thanks to @FunkyFranky
-- Function that check if a file exists.
local function _fileexists( name )
local f = io.open( name, "r" )
if f ~= nil then
io.close( f )
return true
else
return false
end
end
-- Check io module is available.
if not io then
BASE:E( "ERROR: io not desanitized. Can't save current state." )
return false
end
-- Check default path.
if Path == nil and not lfs then
BASE:E( "WARNING: lfs not desanitized. Loading will look into your DCS installation root directory rather than your \"Saved Games\\DCS\" folder." )
end
-- Set path or default.
local path = nil
if lfs then
path = Path or lfs.writedir()
end
-- Set file name.
local filename = Filename
if path ~= nil then
filename = path .. "\\" .. filename
end
-- Check if file exists.
local exists = _fileexists( filename )
if not exists then
BASE:E( string.format( "ERROR: File %s does not exist!", filename ) )
return false
else
return true
end
end
--- Function to save the state of a list of groups found by name
-- @param #table List Table of strings with groupnames
-- @param #string Path The path to use. Use double backslashes \\\\ on Windows filesystems.
-- @param #string Filename The name of the file.
-- @return #boolean outcome True if saving is successful, else false.
-- @usage
-- We will go through the list and find the corresponding group and save the current group size (0 when dead).
-- These groups are supposed to be put on the map in the ME and have *not* moved (e.g. stationary SAM sites).
-- Position is still saved for your usage.
-- The idea is to reduce the number of units when reloading the data again to restart the saved mission.
-- The data will be a simple comma separated list of groupname and size, with one header line.
function UTILS.SaveStationaryListOfGroups( List, Path, Filename )
local filename = Filename or "StateListofGroups"
local data = "--Save Stationary List of Groups: " .. Filename .. "\n"
for _, _group in pairs( List ) do
local group = GROUP:FindByName( _group ) -- Wrapper.Group#GROUP
if group and group:IsAlive() then
local units = group:CountAliveUnits()
local position = group:GetVec3()
data = string.format( "%s%s,%d,%d,%d,%d\n", data, _group, units, position.x, position.y, position.z )
else
data = string.format( "%s%s,0,0,0,0\n", data, _group )
end
end
-- save the data
local outcome = UTILS.SaveToFile( Path, Filename, data )
return outcome
end
--- Function to save the state of a set of Wrapper.Group#GROUP objects.
-- @param Core.Set#SET_BASE Set of objects to save
-- @param #string Path The path to use. Use double backslashes \\\\ on Windows filesystems.
-- @param #string Filename The name of the file.
-- @return #boolean outcome True if saving is successful, else false.
-- @usage
-- We will go through the set and find the corresponding group and save the current group size and current position.
-- The idea is to respawn the groups **spawned during an earlier run of the mission** at the given location and reduce
-- the number of units in the group when reloading the data again to restart the saved mission. Note that *dead* groups
-- cannot be covered with this.
-- **Note** Do NOT use dashes or hashes in group template names (-,#)!
-- The data will be a simple comma separated list of groupname and size, with one header line.
-- The current task/waypoint/etc cannot be restored.
function UTILS.SaveSetOfGroups( Set, Path, Filename )
local filename = Filename or "SetOfGroups"
local data = "--Save SET of groups: " .. Filename .. "\n"
local List = Set:GetSetObjects()
for _, _group in pairs( List ) do
local group = _group -- Wrapper.Group#GROUP
if group and group:IsAlive() then
local name = group:GetName()
local template = string.gsub( name, "-(.+)$", "" )
if string.find( template, "#" ) then
template = string.gsub( name, "#(%d+)$", "" )
end
local units = group:CountAliveUnits()
local position = group:GetVec3()
data = string.format( "%s%s,%s,%d,%d,%d,%d\n", data, name, template, units, position.x, position.y, position.z )
end
end
-- save the data
local outcome = UTILS.SaveToFile( Path, Filename, data )
return outcome
end
--- Function to save the state of a set of Wrapper.Static#STATIC objects.
-- @param Core.Set#SET_BASE Set of objects to save
-- @param #string Path The path to use. Use double backslashes \\\\ on Windows filesystems.
-- @param #string Filename The name of the file.
-- @return #boolean outcome True if saving is successful, else false.
-- @usage
-- We will go through the set and find the corresponding static and save the current name and postion when alive.
-- The data will be a simple comma separated list of name and state etc, with one header line.
function UTILS.SaveSetOfStatics( Set, Path, Filename )
local filename = Filename or "SetOfStatics"
local data = "--Save SET of statics: " .. Filename .. "\n"
local List = Set:GetSetObjects()
for _, _group in pairs( List ) do
local group = _group -- Wrapper.Static#STATIC
if group and group:IsAlive() then
local name = group:GetName()
local position = group:GetVec3()
data = string.format( "%s%s,%d,%d,%d\n", data, name, position.x, position.y, position.z )
end
end
-- save the data
local outcome = UTILS.SaveToFile( Path, Filename, data )
return outcome
end
--- Function to save the state of a list of statics found by name
-- @param #table List Table of strings with statics names
-- @param #string Path The path to use. Use double backslashes \\\\ on Windows filesystems.
-- @param #string Filename The name of the file.
-- @return #boolean outcome True if saving is successful, else false.
-- @usage
-- We will go through the list and find the corresponding static and save the current alive state as 1 (0 when dead).
-- Position is saved for your usage. **Note** this works on UNIT-name level.
-- The idea is to reduce the number of units when reloading the data again to restart the saved mission.
-- The data will be a simple comma separated list of name and state etc, with one header line.
function UTILS.SaveStationaryListOfStatics( List, Path, Filename )
local filename = Filename or "StateListofStatics"
local data = "--Save Stationary List of Statics: " .. Filename .. "\n"
for _, _group in pairs( List ) do
local group = STATIC:FindByName( _group, false ) -- Wrapper.Static#STATIC
if group and group:IsAlive() then
local position = group:GetVec3()
data = string.format( "%s%s,1,%d,%d,%d\n", data, _group, position.x, position.y, position.z )
else
data = string.format( "%s%s,0,0,0,0\n", data, _group )
end
end
-- save the data
local outcome = UTILS.SaveToFile( Path, Filename, data )
return outcome
end
--- Load back a stationary list of groups from file.
-- @param #string Path The path to use. Use double backslashes \\\\ on Windows filesystems.
-- @param #string Filename The name of the file.
-- @param #boolean Reduce If false, existing loaded groups will not be reduced to fit the saved number.
-- @return #table Table of data objects (tables) containing groupname, coordinate and group object. Returns nil when file cannot be read.
function UTILS.LoadStationaryListOfGroups( Path, Filename, Reduce )
local reduce = true
if Reduce == false then
reduce = false
end
local filename = Filename or "StateListofGroups"
local datatable = {}
if UTILS.CheckFileExists( Path, filename ) then
local outcome, loadeddata = UTILS.LoadFromFile( Path, Filename )
-- remove header
table.remove( loadeddata, 1 )
for _id, _entry in pairs( loadeddata ) do
local dataset = UTILS.Split( _entry, "," )
-- groupname,units,position.x,position.y,position.z
local groupname = dataset[1]
local size = tonumber( dataset[2] )
local posx = tonumber( dataset[3] )
local posy = tonumber( dataset[4] )
local posz = tonumber( dataset[5] )
local coordinate = COORDINATE:NewFromVec3( { x = posx, y = posy, z = posz } )
local data = { groupname = groupname, size = size, coordinate = coordinate, group = GROUP:FindByName( groupname ) }
if reduce then
local actualgroup = GROUP:FindByName( groupname )
local actualsize = actualgroup:CountAliveUnits()
if actualsize > size then
local reduction = actualsize - size
BASE:I( "Reducing groupsize by " .. reduction .. " units!" )
-- reduce existing group
local units = actualgroup:GetUnits()
local units2 = UTILS.ShuffleTable( units ) -- randomize table
for i = 1, reduction do
units2[i]:Destroy( false )
end
end
end
table.insert( datatable, data )
end
else
return nil
end
return datatable
end
--- Load back a SET of groups from file.
-- @param #string Path The path to use. Use double backslashes \\\\ on Windows filesystems.
-- @param #string Filename The name of the file.
-- @param #boolean Spawn If set to false, do not re-spawn the groups loaded in location and reduce to size.
-- @return Core.Set#SET_GROUP Set of GROUP objects.
-- Returns nil when file cannot be read. Returns a table of data entries if Spawn is false: `{ groupname=groupname, size=size, coordinate=coordinate }`
function UTILS.LoadSetOfGroups( Path, Filename, Spawn )
local spawn = true
if Spawn == false then
spawn = false
end
BASE:I( "Spawn = " .. tostring( spawn ) )
local filename = Filename or "SetOfGroups"
local setdata = SET_GROUP:New()
local datatable = {}
if UTILS.CheckFileExists( Path, filename ) then
local outcome, loadeddata = UTILS.LoadFromFile( Path, Filename )
-- remove header
table.remove( loadeddata, 1 )
for _id, _entry in pairs( loadeddata ) do
local dataset = UTILS.Split( _entry, "," )
-- groupname,template,units,position.x,position.y,position.z
local groupname = dataset[1]
local template = dataset[2]
local size = tonumber( dataset[3] )
local posx = tonumber( dataset[4] )
local posy = tonumber( dataset[5] )
local posz = tonumber( dataset[6] )
local coordinate = COORDINATE:NewFromVec3( { x = posx, y = posy, z = posz } )
local group = nil
local data = { groupname = groupname, size = size, coordinate = coordinate }
table.insert( datatable, data )
if spawn then
local group = SPAWN:New( groupname ):InitDelayOff():OnSpawnGroup( function( spwndgrp )
setdata:AddObject( spwndgrp )
local actualsize = spwndgrp:CountAliveUnits()
if actualsize > size then
local reduction = actualsize - size
-- reduce existing group
local units = spwndgrp:GetUnits()
local units2 = UTILS.ShuffleTable( units ) -- randomize table
for i = 1, reduction do
units2[i]:Destroy( false )
end
end
end ):SpawnFromCoordinate( coordinate )
end
end
else
return nil
end
if spawn then
return setdata
else
return datatable
end
end
--- Load back a SET of statics from file.
-- @param #string Path The path to use. Use double backslashes \\\\ on Windows filesystems.
-- @param #string Filename The name of the file.
-- @return Core.Set#SET_STATIC Set SET_STATIC containing the static objects.
function UTILS.LoadSetOfStatics( Path, Filename )
local filename = Filename or "SetOfStatics"
local datatable = SET_STATIC:New()
if UTILS.CheckFileExists( Path, filename ) then
local outcome, loadeddata = UTILS.LoadFromFile( Path, Filename )
-- remove header
table.remove( loadeddata, 1 )
for _id, _entry in pairs( loadeddata ) do
local dataset = UTILS.Split( _entry, "," )
-- staticname,position.x,position.y,position.z
local staticname = dataset[1]
local posx = tonumber( dataset[2] )
local posy = tonumber( dataset[3] )
local posz = tonumber( dataset[4] )
local coordinate = COORDINATE:NewFromVec3( { x = posx, y = posy, z = posz } )
datatable:AddObject( STATIC:FindByName( staticname, false ) )
end
else
return nil
end
return datatable
end
--- Load back a stationary list of statics from file.
-- @param #string Path The path to use. Use double backslashes \\\\ on Windows filesystems.
-- @param #string Filename The name of the file.
-- @param #boolean Reduce If false, do not destroy the units with size=0.
-- @return #table Table of data objects (tables) containing staticname, size (0=dead else 1), coordinate and the static object.
-- Returns nil when file cannot be read.
function UTILS.LoadStationaryListOfStatics( Path, Filename, Reduce )
local reduce = true
if Reduce == false then
reduce = false
end
local filename = Filename or "StateListofStatics"
local datatable = {}
if UTILS.CheckFileExists( Path, filename ) then
local outcome, loadeddata = UTILS.LoadFromFile( Path, Filename )
-- remove header
table.remove( loadeddata, 1 )
for _id, _entry in pairs( loadeddata ) do
local dataset = UTILS.Split( _entry, "," )
-- staticname,units(1/0),position.x,position.y,position.z)
local staticname = dataset[1]
local size = tonumber( dataset[2] )
local posx = tonumber( dataset[3] )
local posy = tonumber( dataset[4] )
local posz = tonumber( dataset[5] )
local coordinate = COORDINATE:NewFromVec3( { x = posx, y = posy, z = posz } )
local data = { staticname = staticname, size = size, coordinate = coordinate, static = STATIC:FindByName( staticname, false ) }
table.insert( datatable, data )
if size == 0 and reduce then
local static = STATIC:FindByName( staticname, false )
if static then
static:Destroy( false )
end
end
end
else
return nil
end
return datatable
end

View File

@@ -310,8 +310,7 @@ end
--- Returns the @{DCS#Position3} position vectors indicating the point and direction vectors in 3D of the POSITIONABLE within the mission. --- Returns the @{DCS#Position3} position vectors indicating the point and direction vectors in 3D of the POSITIONABLE within the mission.
-- @param Wrapper.Positionable#POSITIONABLE self -- @param Wrapper.Positionable#POSITIONABLE self
-- @return DCS#Position The 3D position vectors of the POSITIONABLE. -- @return DCS#Position The 3D position vectors of the POSITIONABLE or #nil if the groups not existing or alive.
-- @return #nil The POSITIONABLE is not existing or alive.
function GROUP:GetPositionVec3() -- Overridden from POSITIONABLE:GetPositionVec3() function GROUP:GetPositionVec3() -- Overridden from POSITIONABLE:GetPositionVec3()
self:F2( self.PositionableName ) self:F2( self.PositionableName )
@@ -339,9 +338,7 @@ end
-- If the first @{Wrapper.Unit} of the group is inactive, it will return false. -- If the first @{Wrapper.Unit} of the group is inactive, it will return false.
-- --
-- @param #GROUP self -- @param #GROUP self
-- @return #boolean true if the group is alive and active. -- @return #boolean `true` if the group is alive *and* active, `false` if the group is alive but inactive or `#nil` if the group does not exist anymore.
-- @return #boolean false if the group is alive but inactive.
-- @return #nil if the group does not exist anymore.
function GROUP:IsAlive() function GROUP:IsAlive()
self:F2( self.GroupName ) self:F2( self.GroupName )
@@ -363,8 +360,7 @@ end
--- Returns if the group is activated. --- Returns if the group is activated.
-- @param #GROUP self -- @param #GROUP self
-- @return #boolean true if group is activated. -- @return #boolean `true` if group is activated or `#nil` The group is not existing or alive.
-- @return #nil The group is not existing or alive.
function GROUP:IsActive() function GROUP:IsActive()
self:F2( self.GroupName ) self:F2( self.GroupName )
@@ -412,7 +408,6 @@ function GROUP:Destroy( GenerateEvent, delay )
self:F2( self.GroupName ) self:F2( self.GroupName )
if delay and delay>0 then if delay and delay>0 then
--SCHEDULER:New(nil, GROUP.Destroy, {self, GenerateEvent}, delay)
self:ScheduleOnce(delay, GROUP.Destroy, self, GenerateEvent) self:ScheduleOnce(delay, GROUP.Destroy, self, GenerateEvent)
else else
@@ -568,12 +563,12 @@ function GROUP:GetSpeedMax()
local Units=self:GetUnits() local Units=self:GetUnits()
local speedmax=nil local speedmax=0
for _,unit in pairs(Units) do for _,unit in pairs(Units) do
local unit=unit --Wrapper.Unit#UNIT local unit=unit --Wrapper.Unit#UNIT
local speed=unit:GetSpeedMax() local speed=unit:GetSpeedMax()
if speedmax==nil then if speedmax==0 then
speedmax=speed speedmax=speed
elseif speed<speedmax then elseif speed<speedmax then
speedmax=speed speedmax=speed
@@ -2326,41 +2321,44 @@ function GROUP:GetAttribute()
local unarmedship=self:HasAttribute("Unarmed ships") local unarmedship=self:HasAttribute("Unarmed ships")
-- Define attribute. Order is important. -- Define attribute. Order of attack is important.
if transportplane then if fighter then
attribute=GROUP.Attribute.AIR_TRANSPORTPLANE
elseif awacs then
attribute=GROUP.Attribute.AIR_AWACS
elseif fighter then
attribute=GROUP.Attribute.AIR_FIGHTER attribute=GROUP.Attribute.AIR_FIGHTER
elseif bomber then elseif bomber then
attribute=GROUP.Attribute.AIR_BOMBER attribute=GROUP.Attribute.AIR_BOMBER
elseif awacs then
attribute=GROUP.Attribute.AIR_AWACS
elseif transportplane then
attribute=GROUP.Attribute.AIR_TRANSPORTPLANE
elseif tanker then elseif tanker then
attribute=GROUP.Attribute.AIR_TANKER attribute=GROUP.Attribute.AIR_TANKER
elseif transporthelo then -- helos
attribute=GROUP.Attribute.AIR_TRANSPORTHELO
elseif attackhelicopter then elseif attackhelicopter then
attribute=GROUP.Attribute.AIR_ATTACKHELO attribute=GROUP.Attribute.AIR_ATTACKHELO
elseif transporthelo then
attribute=GROUP.Attribute.AIR_TRANSPORTHELO
elseif uav then elseif uav then
attribute=GROUP.Attribute.AIR_UAV attribute=GROUP.Attribute.AIR_UAV
elseif apc then -- ground - order of attack
attribute=GROUP.Attribute.GROUND_APC
elseif infantry then
attribute=GROUP.Attribute.GROUND_INFANTRY
elseif artillery then
attribute=GROUP.Attribute.GROUND_ARTILLERY
elseif tank then
attribute=GROUP.Attribute.GROUND_TANK
elseif aaa then
attribute=GROUP.Attribute.GROUND_AAA
elseif ewr then elseif ewr then
attribute=GROUP.Attribute.GROUND_EWR attribute=GROUP.Attribute.GROUND_EWR
elseif sam then elseif sam then
attribute=GROUP.Attribute.GROUND_SAM attribute=GROUP.Attribute.GROUND_SAM
elseif aaa then
attribute=GROUP.Attribute.GROUND_AAA
elseif artillery then
attribute=GROUP.Attribute.GROUND_ARTILLERY
elseif tank then
attribute=GROUP.Attribute.GROUND_TANK
elseif apc then
attribute=GROUP.Attribute.GROUND_APC
elseif infantry then
attribute=GROUP.Attribute.GROUND_INFANTRY
elseif truck then elseif truck then
attribute=GROUP.Attribute.GROUND_TRUCK attribute=GROUP.Attribute.GROUND_TRUCK
elseif train then elseif train then
attribute=GROUP.Attribute.GROUND_TRAIN attribute=GROUP.Attribute.GROUND_TRAIN
-- ships
elseif aircraftcarrier then elseif aircraftcarrier then
attribute=GROUP.Attribute.NAVAL_AIRCRAFTCARRIER attribute=GROUP.Attribute.NAVAL_AIRCRAFTCARRIER
elseif warship then elseif warship then
@@ -2578,8 +2576,10 @@ end
-- @return #GROUP self -- @return #GROUP self
function GROUP:SetCommandInvisible(switch) function GROUP:SetCommandInvisible(switch)
self:F2( self.GroupName ) self:F2( self.GroupName )
local switch = switch or false if switch==nil then
local SetInvisible = {id = 'SetInvisible', params = {value = true}} switch=false
end
local SetInvisible = {id = 'SetInvisible', params = {value = switch}}
self:SetCommand(SetInvisible) self:SetCommand(SetInvisible)
return self return self
end end
@@ -2590,9 +2590,11 @@ end
-- @return #GROUP self -- @return #GROUP self
function GROUP:SetCommandImmortal(switch) function GROUP:SetCommandImmortal(switch)
self:F2( self.GroupName ) self:F2( self.GroupName )
local switch = switch or false if switch==nil then
local SetInvisible = {id = 'SetImmortal', params = {value = true}} switch=false
self:SetCommand(SetInvisible) end
local SetImmortal = {id = 'SetImmortal', params = {value = switch}}
self:SetCommand(SetImmortal)
return self return self
end end

View File

@@ -57,7 +57,6 @@ POSITIONABLE.__ = {}
--- @field #POSITIONABLE.__.Cargo --- @field #POSITIONABLE.__.Cargo
POSITIONABLE.__.Cargo = {} POSITIONABLE.__.Cargo = {}
--- A DCSPositionable --- A DCSPositionable
-- @type DCSPositionable -- @type DCSPositionable
-- @field id_ The ID of the controllable in DCS -- @field id_ The ID of the controllable in DCS
@@ -75,16 +74,19 @@ end
--- Destroys the POSITIONABLE. --- Destroys the POSITIONABLE.
-- @param #POSITIONABLE self -- @param #POSITIONABLE self
-- @param #boolean GenerateEvent (Optional) true if you want to generate a crash or dead event for the unit. -- @param #boolean GenerateEvent (Optional) If true, generates a crash or dead event for the unit. If false, no event generated. If nil, a remove event is generated.
-- @return #nil The DCS Unit is not existing or alive. -- @return #nil The DCS Unit is not existing or alive.
-- @usage -- @usage
-- -- Air unit example: destroy the Helicopter and generate a S_EVENT_CRASH for each unit in the Helicopter group. --
-- Air unit example: destroy the Helicopter and generate a S_EVENT_CRASH for each unit in the Helicopter group.
-- Helicopter = UNIT:FindByName( "Helicopter" ) -- Helicopter = UNIT:FindByName( "Helicopter" )
-- Helicopter:Destroy( true ) -- Helicopter:Destroy( true )
--
-- @usage -- @usage
-- -- Ground unit example: destroy the Tanks and generate a S_EVENT_DEAD for each unit in the Tanks group. -- -- Ground unit example: destroy the Tanks and generate a S_EVENT_DEAD for each unit in the Tanks group.
-- Tanks = UNIT:FindByName( "Tanks" ) -- Tanks = UNIT:FindByName( "Tanks" )
-- Tanks:Destroy( true ) -- Tanks:Destroy( true )
--
-- @usage -- @usage
-- -- Ship unit example: destroy the Ship silently. -- -- Ship unit example: destroy the Ship silently.
-- Ship = STATIC:FindByName( "Ship" ) -- Ship = STATIC:FindByName( "Ship" )
@@ -147,7 +149,7 @@ function POSITIONABLE:GetPosition()
return PositionablePosition return PositionablePosition
end end
BASE:E( { "Cannot GetPositionVec3", Positionable = self, Alive = self:IsAlive() } ) BASE:E( { "Cannot GetPosition", Positionable = self, Alive = self:IsAlive() } )
return nil return nil
end end
@@ -157,6 +159,7 @@ end
-- @return DCS#Vec3 X orientation, i.e. parallel to the direction of movement. -- @return DCS#Vec3 X orientation, i.e. parallel to the direction of movement.
-- @return DCS#Vec3 Y orientation, i.e. vertical. -- @return DCS#Vec3 Y orientation, i.e. vertical.
-- @return DCS#Vec3 Z orientation, i.e. perpendicular to the direction of movement. -- @return DCS#Vec3 Z orientation, i.e. perpendicular to the direction of movement.
-- @return #nil The POSITIONABLE is not existing or alive.
function POSITIONABLE:GetOrientation() function POSITIONABLE:GetOrientation()
local position = self:GetPosition() local position = self:GetPosition()
if position then if position then
@@ -170,6 +173,7 @@ end
--- Returns a {@DCS#Vec3} table of the objects current X orientation in 3D space, i.e. along the direction of movement. --- Returns a {@DCS#Vec3} table of the objects current X orientation in 3D space, i.e. along the direction of movement.
-- @param Wrapper.Positionable#POSITIONABLE self -- @param Wrapper.Positionable#POSITIONABLE self
-- @return DCS#Vec3 X orientation, i.e. parallel to the direction of movement. -- @return DCS#Vec3 X orientation, i.e. parallel to the direction of movement.
-- @return #nil The POSITIONABLE is not existing or alive.
function POSITIONABLE:GetOrientationX() function POSITIONABLE:GetOrientationX()
local position = self:GetPosition() local position = self:GetPosition()
if position then if position then
@@ -183,6 +187,7 @@ end
--- Returns a {@DCS#Vec3} table of the objects current Y orientation in 3D space, i.e. vertical orientation. --- Returns a {@DCS#Vec3} table of the objects current Y orientation in 3D space, i.e. vertical orientation.
-- @param Wrapper.Positionable#POSITIONABLE self -- @param Wrapper.Positionable#POSITIONABLE self
-- @return DCS#Vec3 Y orientation, i.e. vertical. -- @return DCS#Vec3 Y orientation, i.e. vertical.
-- @return #nil The POSITIONABLE is not existing or alive.
function POSITIONABLE:GetOrientationY() function POSITIONABLE:GetOrientationY()
local position = self:GetPosition() local position = self:GetPosition()
if position then if position then
@@ -196,6 +201,7 @@ end
--- Returns a {@DCS#Vec3} table of the objects current Z orientation in 3D space, i.e. perpendicular to direction of movement. --- Returns a {@DCS#Vec3} table of the objects current Z orientation in 3D space, i.e. perpendicular to direction of movement.
-- @param Wrapper.Positionable#POSITIONABLE self -- @param Wrapper.Positionable#POSITIONABLE self
-- @return DCS#Vec3 Z orientation, i.e. perpendicular to movement. -- @return DCS#Vec3 Z orientation, i.e. perpendicular to movement.
-- @return #nil The POSITIONABLE is not existing or alive.
function POSITIONABLE:GetOrientationZ() function POSITIONABLE:GetOrientationZ()
local position = self:GetPosition() local position = self:GetPosition()
if position then if position then
@@ -228,7 +234,8 @@ end
--- Returns the @{DCS#Vec3} vector indicating the 3D vector of the POSITIONABLE within the mission. --- Returns the @{DCS#Vec3} vector indicating the 3D vector of the POSITIONABLE within the mission.
-- @param Wrapper.Positionable#POSITIONABLE self -- @param Wrapper.Positionable#POSITIONABLE self
-- @return DCS#Vec3 The 3D point vector of the POSITIONABLE or `nil` if it is not existing or alive. -- @return DCS#Vec3 The 3D point vector of the POSITIONABLE.
-- @return #nil The POSITIONABLE is not existing or alive.
function POSITIONABLE:GetVec3() function POSITIONABLE:GetVec3()
local DCSPositionable = self:GetDCSObject() local DCSPositionable = self:GetDCSObject()
@@ -251,7 +258,8 @@ end
--- Returns the @{DCS#Vec2} vector indicating the point in 2D of the POSITIONABLE within the mission. --- Returns the @{DCS#Vec2} vector indicating the point in 2D of the POSITIONABLE within the mission.
-- @param Wrapper.Positionable#POSITIONABLE self -- @param Wrapper.Positionable#POSITIONABLE self
-- @return DCS#Vec2 The 2D point vector of the POSITIONABLE or #nil if it is not existing or alive. -- @return DCS#Vec2 The 2D point vector of the POSITIONABLE.
-- @return #nil The POSITIONABLE is not existing or alive.
function POSITIONABLE:GetVec2() function POSITIONABLE:GetVec2()
local DCSPositionable = self:GetDCSObject() local DCSPositionable = self:GetDCSObject()
@@ -326,9 +334,13 @@ function POSITIONABLE:GetPointVec3()
return nil return nil
end end
--- Returns a COORDINATE object indicating the point in 3D of the POSITIONABLE within the mission. --- Returns a reference to a COORDINATE object indicating the point in 3D of the POSITIONABLE within the mission.
-- This function works similar to POSITIONABLE.GetCoordinate(), however, this function caches, updates and re-uses the same COORDINATE object stored
-- within the POSITIONABLE. This has higher performance, but comes with all considerations associated with the possible referencing to the same COORDINATE object.
-- This should only be used when performance is critical and there is sufficient awareness of the possible pitfalls. However, in most instances, GetCoordinate() is
-- preferred as it will return a fresh new COORDINATE and thus avoid potentially unexpected issues.
-- @param Wrapper.Positionable#POSITIONABLE self -- @param Wrapper.Positionable#POSITIONABLE self
-- @return Core.Point#COORDINATE The COORDINATE of the POSITIONABLE. -- @return Core.Point#COORDINATE A reference to the COORDINATE object of the POSITIONABLE.
function POSITIONABLE:GetCoord() function POSITIONABLE:GetCoord()
-- Get DCS object. -- Get DCS object.
@@ -337,20 +349,14 @@ function POSITIONABLE:GetCoord()
if DCSPositionable then if DCSPositionable then
-- Get the current position. -- Get the current position.
local Vec3 = self:GetVec3() local PositionableVec3 = self:GetVec3()
if self.coordinate then if self.coordinate then
-- Update COORDINATE from 3D vector.
-- Update vector. self.coordinate:UpdateFromVec3( PositionableVec3 )
self.coordinate.x=Vec3.x
self.coordinate.y=Vec3.y
self.coordinate.z=Vec3.z
else else
-- New COORDINATE. -- New COORDINATE.
self.coordinate=COORDINATE:NewFromVec3(Vec3) self.coordinate = COORDINATE:NewFromVec3( PositionableVec3 )
end end
return self.coordinate return self.coordinate
@@ -362,9 +368,9 @@ function POSITIONABLE:GetCoord()
return nil return nil
end end
--- Returns a COORDINATE object indicating the point in 3D of the POSITIONABLE within the mission. --- Returns a new COORDINATE object indicating the point in 3D of the POSITIONABLE within the mission.
-- @param Wrapper.Positionable#POSITIONABLE self -- @param Wrapper.Positionable#POSITIONABLE self
-- @return Core.Point#COORDINATE The COORDINATE of the POSITIONABLE. -- @return Core.Point#COORDINATE A new COORDINATE object of the POSITIONABLE.
function POSITIONABLE:GetCoordinate() function POSITIONABLE:GetCoordinate()
-- Get DCS object. -- Get DCS object.
@@ -377,7 +383,7 @@ function POSITIONABLE:GetCoordinate()
local coord = COORDINATE:NewFromVec3( PositionableVec3 ) local coord = COORDINATE:NewFromVec3( PositionableVec3 )
-- Return a new coordiante object. -- Return a new coordinate object.
return coord return coord
end end
@@ -463,12 +469,11 @@ function POSITIONABLE:GetRandomVec3( Radius )
return nil return nil
end end
--- Get the bounding box of the underlying POSITIONABLE DCS Object. --- Get the bounding box of the underlying POSITIONABLE DCS Object.
-- @param #POSITIONABLE self -- @param #POSITIONABLE self
-- @return DCS#Box3 The bounding box of the POSITIONABLE. -- @return DCS#Box3 The bounding box of the POSITIONABLE.
-- @return #nil The POSITIONABLE is not existing or alive. -- @return #nil The POSITIONABLE is not existing or alive.
function POSITIONABLE:GetBoundingBox() --R2.1 function POSITIONABLE:GetBoundingBox()
self:F2() self:F2()
local DCSPositionable = self:GetDCSObject() local DCSPositionable = self:GetDCSObject()
@@ -486,7 +491,6 @@ function POSITIONABLE:GetBoundingBox() --R2.1
return nil return nil
end end
--- Get the object size. --- Get the object size.
-- @param #POSITIONABLE self -- @param #POSITIONABLE self
-- @return DCS#Distance Max size of object in x, z or 0 if bounding box could not be obtained. -- @return DCS#Distance Max size of object in x, z or 0 if bounding box could not be obtained.
@@ -510,14 +514,15 @@ end
--- Get the bounding radius of the underlying POSITIONABLE DCS Object. --- Get the bounding radius of the underlying POSITIONABLE DCS Object.
-- @param #POSITIONABLE self -- @param #POSITIONABLE self
-- @param #number mindist (Optional) If bounding box is smaller than this value, mindist is returned. -- @param #number MinDist (Optional) If bounding box is smaller than this value, MinDist is returned.
-- @return DCS#Distance The bounding radius of the POSITIONABLE or #nil if the POSITIONABLE is not existing or alive. -- @return DCS#Distance The bounding radius of the POSITIONABLE
function POSITIONABLE:GetBoundingRadius(mindist) -- @return #nil The POSITIONABLE is not existing or alive.
function POSITIONABLE:GetBoundingRadius( MinDist )
self:F2() self:F2()
local Box = self:GetBoundingBox() local Box = self:GetBoundingBox()
local boxmin=mindist or 0 local boxmin = MinDist or 0
if Box then if Box then
local X = Box.max.x - Box.min.x local X = Box.max.x - Box.min.x
local Z = Box.max.z - Box.min.z local Z = Box.max.z - Box.min.z
@@ -574,7 +579,6 @@ function POSITIONABLE:IsAboveRunway()
return nil return nil
end end
function POSITIONABLE:GetSize() function POSITIONABLE:GetSize()
local DCSObject = self:GetDCSObject() local DCSObject = self:GetDCSObject()
@@ -586,11 +590,10 @@ function POSITIONABLE:GetSize()
end end
end end
--- Returns the POSITIONABLE heading in degrees. --- Returns the POSITIONABLE heading in degrees.
-- @param Wrapper.Positionable#POSITIONABLE self -- @param Wrapper.Positionable#POSITIONABLE self
-- @return #number The POSITIONABLE heading in degrees or `nil` if not existing or alive. -- @return #number The POSITIONABLE heading in degrees.
-- @return #nil The POSITIONABLE is not existing or alive.
function POSITIONABLE:GetHeading() function POSITIONABLE:GetHeading()
local DCSPositionable = self:GetDCSObject() local DCSPositionable = self:GetDCSObject()
@@ -613,7 +616,6 @@ function POSITIONABLE:GetHeading()
end end
self:E( { "Cannot GetHeading", Positionable = self, Alive = self:IsAlive() } ) self:E( { "Cannot GetHeading", Positionable = self, Alive = self:IsAlive() } )
return nil return nil
end end
@@ -623,6 +625,7 @@ end
-- If the unit is a helicopter or a plane, then this method will return true, otherwise false. -- If the unit is a helicopter or a plane, then this method will return true, otherwise false.
-- @param #POSITIONABLE self -- @param #POSITIONABLE self
-- @return #boolean Air category evaluation result. -- @return #boolean Air category evaluation result.
-- @return #nil The POSITIONABLE is not existing or alive.
function POSITIONABLE:IsAir() function POSITIONABLE:IsAir()
self:F2() self:F2()
@@ -638,6 +641,7 @@ function POSITIONABLE:IsAir()
return IsAirResult return IsAirResult
end end
self:E( { "Cannot check IsAir", Positionable = self, Alive = self:IsAlive() } )
return nil return nil
end end
@@ -645,6 +649,7 @@ end
-- If the unit is a ground vehicle or infantry, this method will return true, otherwise false. -- If the unit is a ground vehicle or infantry, this method will return true, otherwise false.
-- @param #POSITIONABLE self -- @param #POSITIONABLE self
-- @return #boolean Ground category evaluation result. -- @return #boolean Ground category evaluation result.
-- @return #nil The POSITIONABLE is not existing or alive.
function POSITIONABLE:IsGround() function POSITIONABLE:IsGround()
self:F2() self:F2()
@@ -660,13 +665,14 @@ function POSITIONABLE:IsGround()
return IsGroundResult return IsGroundResult
end end
self:E( { "Cannot check IsGround", Positionable = self, Alive = self:IsAlive() } )
return nil return nil
end end
--- Returns if the unit is of ship category. --- Returns if the unit is of ship category.
-- @param #POSITIONABLE self -- @param #POSITIONABLE self
-- @return #boolean Ship category evaluation result. -- @return #boolean Ship category evaluation result.
-- @return #nil The POSITIONABLE is not existing or alive.
function POSITIONABLE:IsShip() function POSITIONABLE:IsShip()
self:F2() self:F2()
@@ -674,16 +680,18 @@ function POSITIONABLE:IsShip()
if DCSUnit then if DCSUnit then
local UnitDescriptor = DCSUnit:getDesc() local UnitDescriptor = DCSUnit:getDesc()
self:T3( { UnitDescriptor.category, Unit.Category.SHIP } )
local IsShip = ( UnitDescriptor.category == Unit.Category.SHIP ) local IsShipResult = (UnitDescriptor.category == Unit.Category.SHIP)
return IsShip self:T3( IsShipResult )
return IsShipResult
end end
self:E( { "Cannot check IsShip", Positionable = self, Alive = self:IsAlive() } )
return nil return nil
end end
--- Returns if the unit is a submarine. --- Returns if the unit is a submarine.
-- @param #POSITIONABLE self -- @param #POSITIONABLE self
-- @return #boolean Submarines attributes result. -- @return #boolean Submarines attributes result.
@@ -701,10 +709,10 @@ function POSITIONABLE:IsSubmarine()
end end
end end
self:E( { "Cannot check IsSubmarine", Positionable = self, Alive = self:IsAlive() } )
return nil return nil
end end
--- Returns true if the POSITIONABLE is in the air. --- Returns true if the POSITIONABLE is in the air.
-- Polymorphic, is overridden in GROUP and UNIT. -- Polymorphic, is overridden in GROUP and UNIT.
-- @param Wrapper.Positionable#POSITIONABLE self -- @param Wrapper.Positionable#POSITIONABLE self
@@ -716,8 +724,7 @@ function POSITIONABLE:InAir()
return nil return nil
end end
--- Returns the a @{Velocity} object from the POSITIONABLE.
--- Returns the a @{Velocity} object from the positionable.
-- @param Wrapper.Positionable#POSITIONABLE self -- @param Wrapper.Positionable#POSITIONABLE self
-- @return Core.Velocity#VELOCITY Velocity The Velocity object. -- @return Core.Velocity#VELOCITY Velocity The Velocity object.
-- @return #nil The POSITIONABLE is not existing or alive. -- @return #nil The POSITIONABLE is not existing or alive.
@@ -736,8 +743,6 @@ function POSITIONABLE:GetVelocity()
return nil return nil
end end
--- Returns the POSITIONABLE velocity Vec3 vector. --- Returns the POSITIONABLE velocity Vec3 vector.
-- @param Wrapper.Positionable#POSITIONABLE self -- @param Wrapper.Positionable#POSITIONABLE self
-- @return DCS#Vec3 The velocity Vec3 vector -- @return DCS#Vec3 The velocity Vec3 vector
@@ -760,30 +765,29 @@ end
--- Get relative velocity with respect to another POSITIONABLE. --- Get relative velocity with respect to another POSITIONABLE.
-- @param #POSITIONABLE self -- @param #POSITIONABLE self
-- @param #POSITIONABLE positionable Other positionable. -- @param #POSITIONABLE Positionable Other POSITIONABLE.
-- @return #number Relative velocity in m/s. -- @return #number Relative velocity in m/s.
function POSITIONABLE:GetRelativeVelocity(positionable) function POSITIONABLE:GetRelativeVelocity( Positionable )
self:F2( self.PositionableName ) self:F2( self.PositionableName )
local v1 = self:GetVelocityVec3() local v1 = self:GetVelocityVec3()
local v2=positionable:GetVelocityVec3() local v2 = Positionable:GetVelocityVec3()
local vtot = UTILS.VecAdd( v1, v2 ) local vtot = UTILS.VecAdd( v1, v2 )
return UTILS.VecNorm( vtot ) return UTILS.VecNorm( vtot )
end end
--- Returns the POSITIONABLE height in meters. --- Returns the POSITIONABLE height in meters.
-- @param Wrapper.Positionable#POSITIONABLE self -- @param Wrapper.Positionable#POSITIONABLE self
-- @return DCS#Vec3 The height of the positionable. -- @return DCS#Vec3 The height of the POSITIONABLE in meters.
-- @return #nil The POSITIONABLE is not existing or alive. -- @return #nil The POSITIONABLE is not existing or alive.
function POSITIONABLE:GetHeight() --R2.1 function POSITIONABLE:GetHeight()
self:F2( self.PositionableName ) self:F2( self.PositionableName )
local DCSPositionable = self:GetDCSObject() local DCSPositionable = self:GetDCSObject()
if DCSPositionable then if DCSPositionable and DCSPositionable:isExist() then
local PositionablePosition = DCSPositionable:getPosition() local PositionablePosition = DCSPositionable:getPosition()
if PositionablePosition then if PositionablePosition then
local PositionableHeight = PositionablePosition.p.y local PositionableHeight = PositionablePosition.p.y
@@ -795,10 +799,9 @@ function POSITIONABLE:GetHeight() --R2.1
return nil return nil
end end
--- Returns the POSITIONABLE velocity in km/h. --- Returns the POSITIONABLE velocity in km/h.
-- @param Wrapper.Positionable#POSITIONABLE self -- @param Wrapper.Positionable#POSITIONABLE self
-- @return #number The velocity in km/h -- @return #number The velocity in km/h.
function POSITIONABLE:GetVelocityKMH() function POSITIONABLE:GetVelocityKMH()
self:F2( self.PositionableName ) self:F2( self.PositionableName )
@@ -841,9 +844,10 @@ function POSITIONABLE:GetVelocityKNOTS()
return UTILS.MpsToKnots( self:GetVelocityMPS() ) return UTILS.MpsToKnots( self:GetVelocityMPS() )
end end
--- Returns the Angle of Attack of a positionable. --- Returns the Angle of Attack of a POSITIONABLE.
-- @param Wrapper.Positionable#POSITIONABLE self -- @param Wrapper.Positionable#POSITIONABLE self
-- @return #number Angle of attack in degrees. -- @return #number Angle of attack in degrees.
-- @return #nil The POSITIONABLE is not existing or alive.
function POSITIONABLE:GetAoA() function POSITIONABLE:GetAoA()
-- Get position of the unit. -- Get position of the unit.
@@ -889,9 +893,10 @@ function POSITIONABLE:GetAoA()
return nil return nil
end end
--- Returns the unit's climb or descent angle. --- Returns the climb or descent angle of the POSITIONABLE.
-- @param Wrapper.Positionable#POSITIONABLE self -- @param Wrapper.Positionable#POSITIONABLE self
-- @return #number Climb or descent angle in degrees. Or 0 if velocity vector norm is zero (or nil). Or nil, if the position of the POSITIONABLE returns nil. -- @return #number Climb or descent angle in degrees. Or 0 if velocity vector norm is zero.
-- @return #nil The POSITIONABLE is not existing or alive.
function POSITIONABLE:GetClimbAngle() function POSITIONABLE:GetClimbAngle()
-- Get position of the unit. -- Get position of the unit.
@@ -912,14 +917,16 @@ function POSITIONABLE:GetClimbAngle()
else else
return 0 return 0
end end
end end
return nil return nil
end end
--- Returns the pitch angle of a unit. --- Returns the pitch angle of a POSITIONABLE.
-- @param Wrapper.Positionable#POSITIONABLE self -- @param Wrapper.Positionable#POSITIONABLE self
-- @return #number Pitch ange in degrees. -- @return #number Pitch angle in degrees.
-- @return #nil The POSITIONABLE is not existing or alive.
function POSITIONABLE:GetPitch() function POSITIONABLE:GetPitch()
-- Get position of the unit. -- Get position of the unit.
@@ -934,7 +941,8 @@ end
--- Returns the roll angle of a unit. --- Returns the roll angle of a unit.
-- @param Wrapper.Positionable#POSITIONABLE self -- @param Wrapper.Positionable#POSITIONABLE self
-- @return #number Pitch ange in degrees. -- @return #number Pitch angle in degrees.
-- @return #nil The POSITIONABLE is not existing or alive.
function POSITIONABLE:GetRoll() function POSITIONABLE:GetRoll()
-- Get position of the unit. -- Get position of the unit.
@@ -942,34 +950,40 @@ function POSITIONABLE:GetRoll()
if unitpos then if unitpos then
--first, make a vector that is perpendicular to y and unitpos.x with cross product -- First, make a vector that is perpendicular to y and unitpos.x with cross product
local cp = UTILS.VecCross( unitpos.x, { x = 0, y = 1, z = 0 } ) local cp = UTILS.VecCross( unitpos.x, { x = 0, y = 1, z = 0 } )
--now, get dot product of of this cross product with unitpos.z -- Now, get dot product of of this cross product with unitpos.z
local dp = UTILS.VecDot( cp, unitpos.z ) local dp = UTILS.VecDot( cp, unitpos.z )
--now get the magnitude of the roll (magnitude of the angle between two vectors is acos(vec1.vec2/|vec1||vec2|) -- Now get the magnitude of the roll (magnitude of the angle between two vectors is acos(vec1.vec2/|vec1||vec2|)
local Roll = math.acos( dp / (UTILS.VecNorm( cp ) * UTILS.VecNorm( unitpos.z )) ) local Roll = math.acos( dp / (UTILS.VecNorm( cp ) * UTILS.VecNorm( unitpos.z )) )
--now, have to get sign of roll. -- Now, have to get sign of roll. By convention, making right roll positive
-- by convention, making right roll positive -- To get sign of roll, use the y component of unitpos.z. For right roll, y component is negative.
-- to get sign of roll, use the y component of unitpos.z. For right roll, y component is negative.
if unitpos.z.y > 0 then -- left roll, flip the sign of the roll if unitpos.z.y > 0 then -- left roll, flip the sign of the roll
Roll = -Roll Roll = -Roll
end end
return math.deg( Roll ) return math.deg( Roll )
end
end end
--- Returns the yaw angle of a unit. return nil
end
--- Returns the yaw angle of a POSITIONABLE.
-- @param Wrapper.Positionable#POSITIONABLE self -- @param Wrapper.Positionable#POSITIONABLE self
-- @return #number Yaw ange in degrees. -- @return #number Yaw angle in degrees.
-- @return #nil The POSITIONABLE is not existing or alive.
function POSITIONABLE:GetYaw() function POSITIONABLE:GetYaw()
-- Get position of the unit.
local unitpos = self:GetPosition() local unitpos = self:GetPosition()
if unitpos then if unitpos then
-- get unit velocity -- get unit velocity
local unitvel = self:GetVelocityVec3() local unitvel = self:GetVelocityVec3()
@@ -991,38 +1005,43 @@ function POSITIONABLE:GetYaw()
end end
return Yaw return Yaw
end end
end
end end
--- Returns the message text with the callsign embedded (if there is one).
-- @param #POSITIONABLE self
-- @param #string Message The message text
-- @param #string Name (optional) The Name of the sender. If not provided, the Name is the type of the Positionable.
-- @return #string The message text
function POSITIONABLE:GetMessageText( Message, Name )
local DCSObject = self:GetDCSObject()
if DCSObject then
local Callsign = string.format( "%s", ( ( Name ~= "" and Name ) or self:GetCallsign() ~= "" and self:GetCallsign() ) or self:GetName() )
local MessageText = string.format("%s - %s", Callsign, Message )
return MessageText
end
return nil return nil
end end
--- Returns the message text with the callsign embedded (if there is one).
-- @param #POSITIONABLE self
-- @param #string Message The message text.
-- @param #string Name (Optional) The Name of the sender. If not provided, Name is set to the type of the POSITIONABLE.
-- @return #string The message text.
-- @return #nil The POSITIONABLE is not existing or alive.
function POSITIONABLE:GetMessageText( Message, Name )
local DCSObject = self:GetDCSObject()
if DCSObject then
local Callsign = string.format( "%s", ((Name ~= "" and Name) or self:GetCallsign() ~= "" and self:GetCallsign()) or self:GetName() )
local MessageText = string.format( "%s - %s", Callsign, Message )
return MessageText
end
return nil
end
--- Returns a message with the callsign embedded (if there is one). --- Returns a message with the callsign embedded (if there is one).
-- @param #POSITIONABLE self -- @param #POSITIONABLE self
-- @param #string Message The message text -- @param #string Message The message text
-- @param DCS#Duration Duration The duration of the message. -- @param DCS#Duration Duration The duration of the message.
-- @param #string Name (optional) The Name of the sender. If not provided, the Name is the type of the Positionable. -- @param #string Name (Optional) The Name of the sender. If not provided, Name is set to the type of the POSITIONABLE.
-- @return Core.Message#MESSAGE -- @return Core.Message#MESSAGE
function POSITIONABLE:GetMessage( Message, Duration, Name ) --R2.1 changed callsign and name and using GetMessageText function POSITIONABLE:GetMessage( Message, Duration, Name )
local DCSObject = self:GetDCSObject() local DCSObject = self:GetDCSObject()
if DCSObject then if DCSObject then
local MessageText = self:GetMessageText( Message, Name ) local MessageText = self:GetMessageText( Message, Name )
return MESSAGE:New( MessageText, Duration ) return MESSAGE:New( MessageText, Duration )
@@ -1035,7 +1054,7 @@ end
-- @param #POSITIONABLE self -- @param #POSITIONABLE self
-- @param #string Message The message text -- @param #string Message The message text
-- @param Core.Message#MESSAGE MessageType MessageType The message type. -- @param Core.Message#MESSAGE MessageType MessageType The message type.
-- @param #string Name (optional) The Name of the sender. If not provided, the Name is the type of the Positionable. -- @param #string Name (Optional) The Name of the sender. If not provided, Name is set to the type of the POSITIONABLE.
-- @return Core.Message#MESSAGE -- @return Core.Message#MESSAGE
function POSITIONABLE:GetMessageType( Message, MessageType, Name ) -- R2.2 changed callsign and name and using GetMessageText function POSITIONABLE:GetMessageType( Message, MessageType, Name ) -- R2.2 changed callsign and name and using GetMessageText
@@ -1053,7 +1072,7 @@ end
-- @param #POSITIONABLE self -- @param #POSITIONABLE self
-- @param #string Message The message text -- @param #string Message The message text
-- @param DCS#Duration Duration The duration of the message. -- @param DCS#Duration Duration The duration of the message.
-- @param #string Name (optional) The Name of the sender. If not provided, the Name is the type of the Positionable. -- @param #string Name (Optional) The Name of the sender. If not provided, Name is set to the type of the POSITIONABLE.
function POSITIONABLE:MessageToAll( Message, Duration, Name ) function POSITIONABLE:MessageToAll( Message, Duration, Name )
self:F2( { Message, Duration } ) self:F2( { Message, Duration } )
@@ -1071,7 +1090,7 @@ end
-- @param #string Message The message text -- @param #string Message The message text
-- @param DCS#Duration Duration The duration of the message. -- @param DCS#Duration Duration The duration of the message.
-- @param DCS#coalition MessageCoalition The Coalition receiving the message. -- @param DCS#coalition MessageCoalition The Coalition receiving the message.
-- @param #string Name (optional) The Name of the sender. If not provided, the Name is the type of the Positionable. -- @param #string Name (Optional) The Name of the sender. If not provided, Name is set to the type of the POSITIONABLE.
function POSITIONABLE:MessageToCoalition( Message, Duration, MessageCoalition, Name ) function POSITIONABLE:MessageToCoalition( Message, Duration, MessageCoalition, Name )
self:F2( { Message, Duration } ) self:F2( { Message, Duration } )
@@ -1085,14 +1104,13 @@ function POSITIONABLE:MessageToCoalition( Message, Duration, MessageCoalition, N
return nil return nil
end end
--- Send a message to a coalition. --- Send a message to a coalition.
-- The message will appear in the message area. The message will begin with the callsign of the group and the type of the first unit sending the message. -- The message will appear in the message area. The message will begin with the callsign of the group and the type of the first unit sending the message.
-- @param #POSITIONABLE self -- @param #POSITIONABLE self
-- @param #string Message The message text -- @param #string Message The message text
-- @param Core.Message#MESSAGE.Type MessageType The message type that determines the duration. -- @param Core.Message#MESSAGE.Type MessageType The message type that determines the duration.
-- @param DCS#coalition MessageCoalition The Coalition receiving the message. -- @param DCS#coalition MessageCoalition The Coalition receiving the message.
-- @param #string Name (optional) The Name of the sender. If not provided, the Name is the type of the Positionable. -- @param #string Name (Optional) The Name of the sender. If not provided, Name is set to the type of the POSITIONABLE.
function POSITIONABLE:MessageTypeToCoalition( Message, MessageType, MessageCoalition, Name ) function POSITIONABLE:MessageTypeToCoalition( Message, MessageType, MessageCoalition, Name )
self:F2( { Message, MessageType } ) self:F2( { Message, MessageType } )
@@ -1106,13 +1124,12 @@ function POSITIONABLE:MessageTypeToCoalition( Message, MessageType, MessageCoali
return nil return nil
end end
--- Send a message to the red coalition. --- Send a message to the red coalition.
-- The message will appear in the message area. The message will begin with the callsign of the group and the type of the first unit sending the message. -- The message will appear in the message area. The message will begin with the callsign of the group and the type of the first unit sending the message.
-- @param #POSITIONABLE self -- @param #POSITIONABLE self
-- @param #string Message The message text -- @param #string Message The message text
-- @param DCS#Duration Duration The duration of the message. -- @param DCS#Duration Duration The duration of the message.
-- @param #string Name (optional) The Name of the sender. If not provided, the Name is the type of the Positionable. -- @param #string Name (Optional) The Name of the sender. If not provided, Name is set to the type of the POSITIONABLE.
function POSITIONABLE:MessageToRed( Message, Duration, Name ) function POSITIONABLE:MessageToRed( Message, Duration, Name )
self:F2( { Message, Duration } ) self:F2( { Message, Duration } )
@@ -1129,7 +1146,7 @@ end
-- @param #POSITIONABLE self -- @param #POSITIONABLE self
-- @param #string Message The message text -- @param #string Message The message text
-- @param DCS#Duration Duration The duration of the message. -- @param DCS#Duration Duration The duration of the message.
-- @param #string Name (optional) The Name of the sender. If not provided, the Name is the type of the Positionable. -- @param #string Name (Optional) The Name of the sender. If not provided, Name is set to the type of the POSITIONABLE.
function POSITIONABLE:MessageToBlue( Message, Duration, Name ) function POSITIONABLE:MessageToBlue( Message, Duration, Name )
self:F2( { Message, Duration } ) self:F2( { Message, Duration } )
@@ -1147,7 +1164,7 @@ end
-- @param #string Message The message text -- @param #string Message The message text
-- @param DCS#Duration Duration The duration of the message. -- @param DCS#Duration Duration The duration of the message.
-- @param Wrapper.Client#CLIENT Client The client object receiving the message. -- @param Wrapper.Client#CLIENT Client The client object receiving the message.
-- @param #string Name (optional) The Name of the sender. If not provided, the Name is the type of the Positionable. -- @param #string Name (Optional) The Name of the sender. If not provided, Name is set to the type of the POSITIONABLE.
function POSITIONABLE:MessageToClient( Message, Duration, Client, Name ) function POSITIONABLE:MessageToClient( Message, Duration, Client, Name )
self:F2( { Message, Duration } ) self:F2( { Message, Duration } )
@@ -1165,7 +1182,7 @@ end
-- @param #string Message The message text -- @param #string Message The message text
-- @param DCS#Duration Duration The duration of the message. -- @param DCS#Duration Duration The duration of the message.
-- @param Wrapper.Group#GROUP MessageGroup The GROUP object receiving the message. -- @param Wrapper.Group#GROUP MessageGroup The GROUP object receiving the message.
-- @param #string Name (optional) The Name of the sender. If not provided, the Name is the type of the Positionable. -- @param #string Name (Optional) The Name of the sender. If not provided, Name is set to the type of the POSITIONABLE.
function POSITIONABLE:MessageToGroup( Message, Duration, MessageGroup, Name ) function POSITIONABLE:MessageToGroup( Message, Duration, MessageGroup, Name )
self:F2( { Message, Duration } ) self:F2( { Message, Duration } )
@@ -1178,11 +1195,15 @@ function POSITIONABLE:MessageToGroup( Message, Duration, MessageGroup, Name )
BASE:E( { "Message not sent to Group; Group is not alive...", Message = Message, MessageGroup = MessageGroup } ) BASE:E( { "Message not sent to Group; Group is not alive...", Message = Message, MessageGroup = MessageGroup } )
end end
else else
BASE:E( { "Message not sent to Group; Positionable is not alive ...", Message = Message, Positionable = self, MessageGroup = MessageGroup } ) BASE:E( {
"Message not sent to Group; Positionable is not alive ...",
Message = Message,
Positionable = self,
MessageGroup = MessageGroup
} )
end end
end end
return nil return nil
end end
@@ -1192,7 +1213,7 @@ end
-- @param #string Message The message text -- @param #string Message The message text
-- @param Core.Message#MESSAGE.Type MessageType The message type that determines the duration. -- @param Core.Message#MESSAGE.Type MessageType The message type that determines the duration.
-- @param Wrapper.Group#GROUP MessageGroup The GROUP object receiving the message. -- @param Wrapper.Group#GROUP MessageGroup The GROUP object receiving the message.
-- @param #string Name (optional) The Name of the sender. If not provided, the Name is the type of the Positionable. -- @param #string Name (Optional) The Name of the sender. If not provided, the Name is the type of the POSITIONABLE.
function POSITIONABLE:MessageTypeToGroup( Message, MessageType, MessageGroup, Name ) function POSITIONABLE:MessageTypeToGroup( Message, MessageType, MessageGroup, Name )
self:F2( { Message, MessageType } ) self:F2( { Message, MessageType } )
@@ -1212,18 +1233,16 @@ end
-- @param #string Message The message text -- @param #string Message The message text
-- @param DCS#Duration Duration The duration of the message. -- @param DCS#Duration Duration The duration of the message.
-- @param Core.Set#SET_GROUP MessageSetGroup The SET_GROUP collection receiving the message. -- @param Core.Set#SET_GROUP MessageSetGroup The SET_GROUP collection receiving the message.
-- @param #string Name (optional) The Name of the sender. If not provided, the Name is the type of the Positionable. -- @param #string Name (Optional) The Name of the sender. If not provided, Name is set to the type of the POSITIONABLE.
function POSITIONABLE:MessageToSetGroup( Message, Duration, MessageSetGroup, Name ) --R2.1 function POSITIONABLE:MessageToSetGroup( Message, Duration, MessageSetGroup, Name )
self:F2( { Message, Duration } ) self:F2( { Message, Duration } )
local DCSObject = self:GetDCSObject() local DCSObject = self:GetDCSObject()
if DCSObject then if DCSObject then
if DCSObject:isExist() then if DCSObject:isExist() then
MessageSetGroup:ForEachGroupAlive( MessageSetGroup:ForEachGroupAlive( function( MessageGroup )
function( MessageGroup )
self:GetMessage( Message, Duration, Name ):ToGroup( MessageGroup ) self:GetMessage( Message, Duration, Name ):ToGroup( MessageGroup )
end end )
)
end end
end end
@@ -1235,7 +1254,7 @@ end
-- @param #POSITIONABLE self -- @param #POSITIONABLE self
-- @param #string Message The message text -- @param #string Message The message text
-- @param DCS#Duration Duration The duration of the message. -- @param DCS#Duration Duration The duration of the message.
-- @param #string Name (optional) The Name of the sender. If not provided, the Name is the type of the Positionable. -- @param #string Name (Optional) The Name of the sender. If not provided, Name is set to the type of the POSITIONABLE.
function POSITIONABLE:Message( Message, Duration, Name ) function POSITIONABLE:Message( Message, Duration, Name )
self:F2( { Message, Duration } ) self:F2( { Message, Duration } )
@@ -1251,7 +1270,7 @@ end
-- Set parameters with the methods provided, then use RADIO:Broadcast() to actually broadcast the message -- Set parameters with the methods provided, then use RADIO:Broadcast() to actually broadcast the message
-- @param #POSITIONABLE self -- @param #POSITIONABLE self
-- @return Core.Radio#RADIO Radio -- @return Core.Radio#RADIO Radio
function POSITIONABLE:GetRadio() --R2.1 function POSITIONABLE:GetRadio()
self:F2( self ) self:F2( self )
return RADIO:New( self ) return RADIO:New( self )
end end
@@ -1259,7 +1278,7 @@ end
--- Create a @{Core.Radio#BEACON}, to allow this POSITIONABLE to broadcast beacon signals --- Create a @{Core.Radio#BEACON}, to allow this POSITIONABLE to broadcast beacon signals
-- @param #POSITIONABLE self -- @param #POSITIONABLE self
-- @return Core.Radio#RADIO Radio -- @return Core.Radio#RADIO Radio
function POSITIONABLE:GetBeacon() --R2.1 function POSITIONABLE:GetBeacon()
self:F2( self ) self:F2( self )
return BEACON:New( self ) return BEACON:New( self )
end end
@@ -1270,7 +1289,7 @@ end
-- @param #number LaserCode Laser code or random number in [1000, 9999]. -- @param #number LaserCode Laser code or random number in [1000, 9999].
-- @param #number Duration Duration of lasing in seconds. -- @param #number Duration Duration of lasing in seconds.
-- @return Core.Spot#SPOT -- @return Core.Spot#SPOT
function POSITIONABLE:LaseUnit( Target, LaserCode, Duration ) --R2.1 function POSITIONABLE:LaseUnit( Target, LaserCode, Duration )
self:F2() self:F2()
LaserCode = LaserCode or math.random( 1000, 9999 ) LaserCode = LaserCode or math.random( 1000, 9999 )
@@ -1278,7 +1297,7 @@ function POSITIONABLE:LaseUnit( Target, LaserCode, Duration ) --R2.1
local RecceDcsUnit = self:GetDCSObject() local RecceDcsUnit = self:GetDCSObject()
local TargetVec3 = Target:GetVec3() local TargetVec3 = Target:GetVec3()
self:F("bulding spot") self:F( "building spot" )
self.Spot = SPOT:New( self ) -- Core.Spot#SPOT self.Spot = SPOT:New( self ) -- Core.Spot#SPOT
self.Spot:LaseOn( Target, LaserCode, Duration ) self.Spot:LaseOn( Target, LaserCode, Duration )
self.LaserCode = LaserCode self.LaserCode = LaserCode
@@ -1289,7 +1308,7 @@ end
--- Start Lasing a COORDINATE. --- Start Lasing a COORDINATE.
-- @param #POSITIONABLE self -- @param #POSITIONABLE self
-- @param Core.Point#COORDIUNATE Coordinate The coordinate where the lase is pointing at. -- @param Core.Point#COORDINATE Coordinate The coordinate where the lase is pointing at.
-- @param #number LaserCode Laser code or random number in [1000, 9999]. -- @param #number LaserCode Laser code or random number in [1000, 9999].
-- @param #number Duration Duration of lasing in seconds. -- @param #number Duration Duration of lasing in seconds.
-- @return Core.Spot#SPOT -- @return Core.Spot#SPOT
@@ -1308,7 +1327,7 @@ end
--- Stop Lasing a POSITIONABLE --- Stop Lasing a POSITIONABLE
-- @param #POSITIONABLE self -- @param #POSITIONABLE self
-- @return #POSITIONABLE -- @return #POSITIONABLE
function POSITIONABLE:LaseOff() --R2.1 function POSITIONABLE:LaseOff()
self:F2() self:F2()
if self.Spot then if self.Spot then
@@ -1322,7 +1341,7 @@ end
--- Check if the POSITIONABLE is lasing a target --- Check if the POSITIONABLE is lasing a target
-- @param #POSITIONABLE self -- @param #POSITIONABLE self
-- @return #boolean true if it is lasing a target -- @return #boolean true if it is lasing a target
function POSITIONABLE:IsLasing() --R2.1 function POSITIONABLE:IsLasing()
self:F2() self:F2()
local Lasing = false local Lasing = false
@@ -1337,7 +1356,7 @@ end
--- Get the Spot --- Get the Spot
-- @param #POSITIONABLE self -- @param #POSITIONABLE self
-- @return Core.Spot#SPOT The Spot -- @return Core.Spot#SPOT The Spot
function POSITIONABLE:GetSpot() --R2.1 function POSITIONABLE:GetSpot()
return self.Spot return self.Spot
end end
@@ -1345,7 +1364,7 @@ end
--- Get the last assigned laser code --- Get the last assigned laser code
-- @param #POSITIONABLE self -- @param #POSITIONABLE self
-- @return #number The laser code -- @return #number The laser code
function POSITIONABLE:GetLaserCode() --R2.1 function POSITIONABLE:GetLaserCode()
return self.LaserCode return self.LaserCode
end end
@@ -1368,8 +1387,6 @@ do -- Cargo
return self.__.Cargo return self.__.Cargo
end end
--- Remove cargo. --- Remove cargo.
-- @param #POSITIONABLE self -- @param #POSITIONABLE self
-- @param Core.Cargo#CARGO Cargo -- @param Core.Cargo#CARGO Cargo
@@ -1431,7 +1448,7 @@ do -- Cargo
-- @return #number CargoBayFreeWeight -- @return #number CargoBayFreeWeight
function POSITIONABLE:GetCargoBayFreeWeight() function POSITIONABLE:GetCargoBayFreeWeight()
-- When there is no cargo bay weight limit set, then calculate this for this positionable! -- When there is no cargo bay weight limit set, then calculate this for this POSITIONABLE!
if not self.__.CargoBayWeightLimit then if not self.__.CargoBayWeightLimit then
self:SetCargoBayWeightLimit() self:SetCargoBayWeightLimit()
end end
@@ -1460,16 +1477,16 @@ do -- Cargo
elseif self.__.CargoBayWeightLimit ~= nil then elseif self.__.CargoBayWeightLimit ~= nil then
-- Value already set ==> Do nothing! -- Value already set ==> Do nothing!
else else
-- If weightlimit is not provided, we will calculate it depending on the type of unit. -- If WeightLimit is not provided, we will calculate it depending on the type of unit.
-- When an airplane or helicopter, we calculate the weightlimit based on the descriptor. -- When an airplane or helicopter, we calculate the WeightLimit based on the descriptor.
if self:IsAir() then if self:IsAir() then
local Desc = self:GetDesc() local Desc = self:GetDesc()
self:F( { Desc = Desc } ) self:F( { Desc = Desc } )
local Weights = { local Weights = {
["C-17A"] = 35000, --77519 cannot be used, because it loads way too much apcs and infantry., ["C-17A"] = 35000, -- 77519 cannot be used, because it loads way too many APCs and infantry.
["C-130"] = 22000 --The real value cannot be used, because it loads way too much apcs and infantry., ["C-130"] = 22000 -- The real value cannot be used, because it loads way too many APCs and infantry.
} }
self.__.CargoBayWeightLimit = Weights[Desc.typeName] or (Desc.massMax - (Desc.massEmpty + Desc.fuelMassMax)) self.__.CargoBayWeightLimit = Weights[Desc.typeName] or (Desc.massMax - (Desc.massEmpty + Desc.fuelMassMax))
@@ -1485,7 +1502,7 @@ do -- Cargo
["Dry-cargo ship-2"] = 70000, ["Dry-cargo ship-2"] = 70000,
["Higgins_boat"] = 3700, -- Higgins Boat can load 3700 kg of general cargo or 36 men (source wikipedia). ["Higgins_boat"] = 3700, -- Higgins Boat can load 3700 kg of general cargo or 36 men (source wikipedia).
["USS_Samuel_Chase"] = 25000, -- Let's say 25 tons for now. Wiki says 33 Higgins boats, which would be 264 tons (can't be right!) and/or 578 troops. ["USS_Samuel_Chase"] = 25000, -- Let's say 25 tons for now. Wiki says 33 Higgins boats, which would be 264 tons (can't be right!) and/or 578 troops.
["LST_Mk2"] =2100000, -- Can carry 2100 tons according to wiki source! ["LST_Mk2"] = 2100000 -- Can carry 2100 tons according to wiki source!
} }
self.__.CargoBayWeightLimit = (Weights[Desc.typeName] or 50000) self.__.CargoBayWeightLimit = (Weights[Desc.typeName] or 50000)
@@ -1534,7 +1551,7 @@ do -- Cargo
["Ural-4320 APA-5D"] = 10, ["Ural-4320 APA-5D"] = 10,
["Ural-4320T"] = 14, ["Ural-4320T"] = 14,
["ZBD04A"] = 7, -- new by kappa ["ZBD04A"] = 7, -- new by kappa
["VAB_Mephisto"] = 8, -- new by Apple ["VAB_Mephisto"] = 8 -- new by Apple
} }
local CargoBayWeightLimit = (Weights[Desc.typeName] or 0) * 95 local CargoBayWeightLimit = (Weights[Desc.typeName] or 0) * 95
@@ -1586,9 +1603,9 @@ end
--- Smoke the POSITIONABLE. --- Smoke the POSITIONABLE.
-- @param #POSITIONABLE self -- @param #POSITIONABLE self
-- @param Utilities.Utils#SMOKECOLOR SmokeColor The color to smoke to positionable. -- @param Utilities.Utils#SMOKECOLOR SmokeColor The smoke color.
-- @param #number Range The range in meters to randomize the smoking around the positionable. -- @param #number Range The range in meters to randomize the smoking around the POSITIONABLE.
-- @param #number AddHeight The height in meters to add to the altitude of the positionable. -- @param #number AddHeight The height in meters to add to the altitude of the POSITIONABLE.
function POSITIONABLE:Smoke( SmokeColor, Range, AddHeight ) function POSITIONABLE:Smoke( SmokeColor, Range, AddHeight )
self:F2() self:F2()
if Range then if Range then
@@ -1638,7 +1655,6 @@ function POSITIONABLE:SmokeBlue()
trigger.action.smoke( self:GetVec3(), trigger.smokeColor.Blue ) trigger.action.smoke( self:GetVec3(), trigger.smokeColor.Blue )
end end
--- Returns true if the unit is within a @{Zone}. --- Returns true if the unit is within a @{Zone}.
-- @param #POSITIONABLE self -- @param #POSITIONABLE self
-- @param Core.Zone#ZONE_BASE Zone The zone to test. -- @param Core.Zone#ZONE_BASE Zone The zone to test.

View File

@@ -10,11 +10,8 @@
-- --
-- @module Wrapper.Static -- @module Wrapper.Static
-- @image Wrapper_Static.JPG -- @image Wrapper_Static.JPG
--- @type STATIC --- @type STATIC
-- @extends Wrapper.Positionable#POSITIONABLE -- @extends Wrapper.Positionable#POSITIONABLE
--- Wrapper class to handle Static objects. --- Wrapper class to handle Static objects.
-- --
-- Note that Statics are almost the same as Units, but they don't have a controller. -- Note that Statics are almost the same as Units, but they don't have a controller.
@@ -40,13 +37,10 @@
-- --
-- * @{#STATIC.FindByName}(): Find a STATIC instance from the _DATABASE object using a DCS Static name. -- * @{#STATIC.FindByName}(): Find a STATIC instance from the _DATABASE object using a DCS Static name.
-- --
-- IMPORTANT: ONE SHOULD NEVER SANATIZE these STATIC OBJECT REFERENCES! (make the STATIC object references nil). -- IMPORTANT: ONE SHOULD NEVER SANITIZE these STATIC OBJECT REFERENCES! (make the STATIC object references nil).
-- --
-- @field #STATIC -- @field #STATIC
STATIC = { STATIC = { ClassName = "STATIC" }
ClassName = "STATIC",
}
--- Register a static object. --- Register a static object.
-- @param #STATIC self -- @param #STATIC self
@@ -58,7 +52,6 @@ function STATIC:Register( StaticName )
return self return self
end end
--- Finds a STATIC from the _DATABASE using a DCSStatic object. --- Finds a STATIC from the _DATABASE using a DCSStatic object.
-- @param #STATIC self -- @param #STATIC self
-- @param DCS#StaticObject DCSStatic An existing DCS Static object reference. -- @param DCS#StaticObject DCSStatic An existing DCS Static object reference.
@@ -97,8 +90,9 @@ end
--- Destroys the STATIC. --- Destroys the STATIC.
-- @param #STATIC self -- @param #STATIC self
-- @param #boolean GenerateEvent (Optional) true if you want to generate a crash or dead event for the static. -- @param #boolean GenerateEvent (Optional) true to generate a crash or dead event, false to not generate any event. `nil` (default) creates a remove event.
-- @return #nil The DCS StaticObject is not existing or alive. -- @return #nil The DCS StaticObject is not existing or alive.
--
-- @usage -- @usage
-- -- Air static example: destroy the static Helicopter and generate a S_EVENT_CRASH. -- -- Air static example: destroy the static Helicopter and generate a S_EVENT_CRASH.
-- Helicopter = STATIC:FindByName( "Helicopter" ) -- Helicopter = STATIC:FindByName( "Helicopter" )
@@ -117,7 +111,7 @@ end
-- @usage -- @usage
-- -- Destroy without event generation example. -- -- Destroy without event generation example.
-- Ship = STATIC:FindByName( "Boat" ) -- Ship = STATIC:FindByName( "Boat" )
-- Ship:Destroy( false ) -- Don't generate an event upon destruction. -- Ship:Destroy( false ) -- Don't generate any event upon destruction.
-- --
function STATIC:Destroy( GenerateEvent ) function STATIC:Destroy( GenerateEvent )
self:F2( self.ObjectName ) self:F2( self.ObjectName )
@@ -148,7 +142,6 @@ function STATIC:Destroy( GenerateEvent )
return nil return nil
end end
--- Get DCS object of static of static. --- Get DCS object of static of static.
-- @param #STATIC self -- @param #STATIC self
-- @return DCS static object -- @return DCS static object
@@ -180,7 +173,6 @@ function STATIC:GetUnits()
return nil return nil
end end
--- Get threat level of static. --- Get threat level of static.
-- @param #STATIC self -- @param #STATIC self
-- @return #number Threat level 1. -- @return #number Threat level 1.
@@ -211,7 +203,6 @@ function STATIC:SpawnAt(Coordinate, Heading, Delay)
return self return self
end end
--- Respawn the @{Wrapper.Unit} at the same location with the same properties. --- Respawn the @{Wrapper.Unit} at the same location with the same properties.
-- This is useful to respawn a cargo after it has been destroyed. -- This is useful to respawn a cargo after it has been destroyed.
-- @param #STATIC self -- @param #STATIC self
@@ -234,12 +225,11 @@ function STATIC:ReSpawn(CountryID, Delay)
return self return self
end end
--- Respawn the @{Wrapper.Unit} at a defined Coordinate with an optional heading. --- Respawn the @{Wrapper.Unit} at a defined Coordinate with an optional heading.
-- @param #STATIC self -- @param #STATIC self
-- @param Core.Point#COORDINATE Coordinate The coordinate where to spawn the new Static. -- @param Core.Point#COORDINATE Coordinate The coordinate where to spawn the new Static.
-- @param #number Heading (Optional) The heading of the static respawn in degrees. Default the current heading. -- @param #number Heading (Optional) The heading of the static respawn in degrees. Default is the current heading.
-- @param #number Delay (Optional) Delay in seconds before static is respawned. Default now. -- @param #number Delay (Optional) Delay in seconds before static is respawned. Default is now.
function STATIC:ReSpawnAt( Coordinate, Heading, Delay ) function STATIC:ReSpawnAt( Coordinate, Heading, Delay )
-- Heading=Heading or 0 -- Heading=Heading or 0
@@ -247,11 +237,9 @@ function STATIC:ReSpawnAt(Coordinate, Heading, Delay)
if Delay and Delay > 0 then if Delay and Delay > 0 then
SCHEDULER:New( nil, self.ReSpawnAt, { self, Coordinate, Heading }, Delay ) SCHEDULER:New( nil, self.ReSpawnAt, { self, Coordinate, Heading }, Delay )
else else
local SpawnStatic = SPAWNSTATIC:NewFromStatic( self.StaticName, self:GetCountry() ) local SpawnStatic = SPAWNSTATIC:NewFromStatic( self.StaticName, self:GetCountry() )
SpawnStatic:SpawnFromCoordinate( Coordinate, Heading, self.StaticName ) SpawnStatic:SpawnFromCoordinate( Coordinate, Heading, self.StaticName )
end end
return self return self

View File

@@ -168,9 +168,6 @@ function UNIT:GetDCSObject()
return nil return nil
end end
--- Respawn the @{Wrapper.Unit} using a (tweaked) template of the parent Group. --- Respawn the @{Wrapper.Unit} using a (tweaked) template of the parent Group.
-- --
-- This function will: -- This function will:
@@ -263,8 +260,6 @@ function UNIT:ReSpawnAt( Coordinate, Heading )
_DATABASE:Spawn( SpawnGroupTemplate ) _DATABASE:Spawn( SpawnGroupTemplate )
end end
--- Returns if the unit is activated. --- Returns if the unit is activated.
-- @param #UNIT self -- @param #UNIT self
-- @return #boolean `true` if Unit is activated. `nil` The DCS Unit is not existing or alive. -- @return #boolean `true` if Unit is activated. `nil` The DCS Unit is not existing or alive.
@@ -301,8 +296,6 @@ function UNIT:IsAlive()
return nil return nil
end end
--- Returns the Unit's callsign - the localized string. --- Returns the Unit's callsign - the localized string.
-- @param #UNIT self -- @param #UNIT self
-- @return #string The Callsign of the Unit. -- @return #string The Callsign of the Unit.
@@ -442,7 +435,7 @@ function UNIT:GetSpeedMax()
return SpeedMax*3.6 return SpeedMax*3.6
end end
return nil return 0
end end
--- Returns the unit's max range in meters derived from the DCS descriptors. --- Returns the unit's max range in meters derived from the DCS descriptors.
@@ -626,8 +619,8 @@ function UNIT:GetAmmunition()
-- Type name of current weapon. -- Type name of current weapon.
local Tammo=ammotable[w]["desc"]["typeName"] local Tammo=ammotable[w]["desc"]["typeName"]
local _weaponString = UTILS.Split(Tammo,"%.") --local _weaponString = UTILS.Split(Tammo,"%.")
local _weaponName = _weaponString[#_weaponString] --local _weaponName = _weaponString[#_weaponString]
-- Get the weapon category: shell=0, missile=1, rocket=2, bomb=3 -- Get the weapon category: shell=0, missile=1, rocket=2, bomb=3
local Category=ammotable[w].desc.category local Category=ammotable[w].desc.category
@@ -656,7 +649,8 @@ function UNIT:GetAmmunition()
elseif Category==Weapon.Category.MISSILE then elseif Category==Weapon.Category.MISSILE then
-- Add up all cruise missiles (category 5)
-- Add up all missiles (category 5)
if MissileCategory==Weapon.MissileCategory.AAM then if MissileCategory==Weapon.MissileCategory.AAM then
nmissiles=nmissiles+Nammo nmissiles=nmissiles+Nammo
elseif MissileCategory==Weapon.MissileCategory.ANTI_SHIP then elseif MissileCategory==Weapon.MissileCategory.ANTI_SHIP then
@@ -665,6 +659,10 @@ function UNIT:GetAmmunition()
nmissiles=nmissiles+Nammo nmissiles=nmissiles+Nammo
elseif MissileCategory==Weapon.MissileCategory.OTHER then elseif MissileCategory==Weapon.MissileCategory.OTHER then
nmissiles=nmissiles+Nammo nmissiles=nmissiles+Nammo
elseif MissileCategory==Weapon.MissileCategory.SAM then
nmissiles=nmissiles+Nammo
elseif MissileCategory==Weapon.MissileCategory.CRUISE then
nmissiles=nmissiles+Nammo
end end
end end
@@ -956,7 +954,6 @@ end
-- @return #string Some text. -- @return #string Some text.
function UNIT:GetThreatLevel() function UNIT:GetThreatLevel()
local ThreatLevel = 0 local ThreatLevel = 0
local ThreatText = "" local ThreatText = ""
@@ -982,7 +979,6 @@ function UNIT:GetThreatLevel()
"LR SAMs" "LR SAMs"
} }
if Attributes["LR SAM"] then ThreatLevel = 10 if Attributes["LR SAM"] then ThreatLevel = 10
elseif Attributes["MR SAM"] then ThreatLevel = 9 elseif Attributes["MR SAM"] then ThreatLevel = 9
elseif Attributes["SR SAM"] and elseif Attributes["SR SAM"] and
@@ -1018,7 +1014,6 @@ function UNIT:GetThreatLevel()
"Fighter" "Fighter"
} }
if Attributes["Fighters"] then ThreatLevel = 10 if Attributes["Fighters"] then ThreatLevel = 10
elseif Attributes["Multirole fighters"] then ThreatLevel = 9 elseif Attributes["Multirole fighters"] then ThreatLevel = 9
elseif Attributes["Battleplanes"] then ThreatLevel = 8 elseif Attributes["Battleplanes"] then ThreatLevel = 8
@@ -1136,12 +1131,6 @@ function UNIT:OtherUnitInRadius( AwaitUnit, Radius )
return nil return nil
end end
--- Returns if the unit is a friendly unit. --- Returns if the unit is a friendly unit.
-- @param #UNIT self -- @param #UNIT self
-- @return #boolean IsFriendly evaluation result. -- @return #boolean IsFriendly evaluation result.