Compare commits

...

50 Commits

Author SHA1 Message Date
Applevangelist 8099847e29 Fixes for DEAD event and extra nil checks 2022-05-04 10:25:50 +02:00
Applevangelist 6e8edd95ec GROUP - making GetCoordinate() a bit more resilient
POINT - slight changes to ToStringBRAANATO
2022-04-29 18:48:41 +02:00
Applevangelist 5112c9598b COORDINATE - added bogey option to COORDINATE:ToStringBRAANATO(FromCoordinate,Bogey,Spades) 2022-04-29 12:18:26 +02:00
Applevangelist 749158c086 Range added nil check 2022-04-29 12:09:57 +02:00
Applevangelist b3d4024f21 Nicefy docs 2022-04-28 17:10:26 +02:00
Applevangelist c283b66c1d added MESSAGE:ToUnit), altered MESSAGE:ToClient() accordingly 2022-04-28 16:58:37 +02:00
Applevangelist 3209843318 Added POSITIONABLE:MessageToSetUnit and POSITIONABLE:MessageToUnit 2022-04-28 16:55:31 +02:00
Applevangelist d35e5cc0f7 Added USERSOUND:ToUnit 2022-04-28 16:50:59 +02:00
Applevangelist e5eeb592a2 Enums - corrected Hawkeye, added Super_Hercules 2022-04-28 13:10:34 +02:00
Applevangelist 3d38f4d17a Enums - added a couple of names 2022-04-26 10:08:50 +02:00
Applevangelist 2d91647e0b QOL changes from DEVELOP 2022-04-25 10:36:36 +02:00
Applevangelist cac0f30673 Update Moose.files (#1717) 2022-04-25 10:35:38 +02:00
Applevangelist c5ecba3389 Menu cleanup for Refresh() 2022-04-24 14:05:45 +02:00
Applevangelist e0397dff47 GROUP - overwrite GetHeight() inherited from POSITIONABLE with something that is actually working for groups 2022-04-24 13:50:07 +02:00
Applevangelist e08fb2e972 Make BRAA heading a 3digit number 2022-04-22 13:31:58 +02:00
Applevangelist c02ae82003 Point - added ToStringBRAANATO 2022-04-21 18:59:31 +02:00
Applevangelist e6fc301b0d Utils Typo 2022-04-20 19:14:36 +02:00
Applevangelist a385ed57fb ZONE - added example to Scan, some minor changes
SET_GROUP - clarified return value to be a table, not a SET
2022-04-20 14:03:18 +02:00
Applevangelist 09dafe4b1d UTILS - added BearingToCardinal, ToStringBRAANATO 2022-04-20 14:02:16 +02:00
Applevangelist ba8505c983 FIFO 2022-04-14 15:54:38 +02:00
Applevangelist fba359d389 LIFO/FIFO enforce unique id 2022-04-14 15:06:14 +02:00
Applevangelist c56763b68f FIFO:HasUniqueID(UniqueID) 2022-04-14 11:11:33 +02:00
Applevangelist 03c2943545 Nicefy docs 2022-04-14 08:53:37 +02:00
Applevangelist 98039b9048 UTISL - FiFo/LiFo stacks 2022-04-14 08:12:29 +02:00
Applevangelist 5065d3b068 UTILS - added FiFo
CTLD - correct imperial hover check messages
2022-04-13 16:13:39 +02:00
Applevangelist 6828f7e262 UTILS - corrected door check for AH64 2022-04-12 08:23:18 +02:00
Applevangelist a685f3ffbd MSRS - honor port setting and coalition. Repaired command string for .bat sound file production
Added mission slash in SOUNDFILE
2022-04-10 18:29:09 +02:00
Applevangelist e84156d2e9 SRS - add port to docu 2022-04-10 10:18:12 +02:00
Applevangelist 0ce1c31e1c CSAR - added SRS port option 2022-04-10 09:29:22 +02:00
Applevangelist f7e14bb60c SET - logic correction in :Remove() 2022-04-08 11:27:31 +02:00
Penecruz 7b907df816 Airboss V/STOL Case III and grading (#1708)
* Update Airboss.lua

* Fix syntax error

C
2022-04-08 07:16:23 +02:00
Frank 7f5be2829c Update Database.lua
- Template statics saved under first statics unit name so they can be found.
2022-04-04 16:50:17 +02:00
Applevangelist fa5afae783 A2A Dispatcher - nil checks to evade dead units 2022-04-04 12:58:32 +02:00
Frank b17507d0fa Update SpawnStatic.lua
- Fixed isCargo flag not honored.
2022-04-04 12:18:45 +02:00
Applevangelist 5ed43a3190 CTLD - build object at the 1st crate location not randomly around helo 2022-04-04 11:31:35 +02:00
Applevangelist d2a5144a23 AIRBASE, added ["Deir_ez-Zor"] = "Deir ez-Zor", 2022-03-30 12:06:25 +02:00
Applevangelist fb2031d7ca docu nicefy 2022-03-29 12:01:28 +02:00
Applevangelist 4a42571925 CTLD - corrected error in setting Hercules min and max drop height, added documentation 2022-03-29 08:52:33 +02:00
Applevangelist 38413625c2 AIRBASE - Add'l AB for the Channels map 2022-03-28 10:12:39 +02:00
Frank 2d544b7a98 Merge pull request #1698 from gavinedwards/airboss.hermes.include
Added Hermes section to Airboss.  Will require tuning.
2022-03-26 23:34:54 +01:00
Lt Cdr Gavin Edwards b1e5e1840e Adding leading lines that I accidentally truncated. 2022-03-26 15:23:38 -07:00
Lt Cdr Gavin Edwards e6f9b4a125 Added Hermes section to Airboss. Will require tuning. 2022-03-26 11:54:53 -07:00
Applevangelist 5260b2b430 And don't forget Fahrenheit 2022-03-26 14:46:52 +01:00
Applevangelist 0213bc7aef Correcting Celcius to Celsius 2022-03-26 14:43:06 +01:00
Applevangelist ca8b0899d0 docu changes 2022-03-23 07:56:52 +01:00
Applevangelist a1f5c0ab9b CSAR/CTLD - added type to script 2022-03-22 10:38:20 +01:00
Applevangelist b0e3f82d27 AIRBASE - added 10 new AB names in Syria 2022-03-18 09:48:50 +01:00
Applevangelist 327ab4766b changed descriptions 2022-03-18 07:59:58 +01:00
Applevangelist 3aee8a49c1 Added CONTROLLABLE SetSpeed() and SetAltitude() 2022-03-18 07:39:48 +01:00
Applevangelist 57de0b7351 docu fixes 2022-03-16 08:45:27 +01:00
32 changed files with 3866 additions and 2081 deletions
+10
View File
@@ -0,0 +1,10 @@
{
"ExpandedNodes": [
"",
"\\Moose Development",
"\\Moose Development\\Moose",
"\\Moose Development\\Moose\\Ops"
],
"SelectedNode": "\\Moose Development\\Moose\\Ops\\Airboss.lua",
"PreviewInSolutionExplorer": false
}
BIN
View File
Binary file not shown.
@@ -2971,7 +2971,20 @@ do -- AI_A2A_DISPATCHER
for FriendlyDistance, AIFriendly in UTILS.spairs( DefenderFriendlies or {} ) do for FriendlyDistance, AIFriendly in UTILS.spairs( DefenderFriendlies or {} ) do
-- We only allow to ENGAGE targets as long as the Units on both sides are balanced. -- We only allow to ENGAGE targets as long as the Units on both sides are balanced.
if AttackerCount > DefenderCount then if AttackerCount > DefenderCount then
local Friendly = AIFriendly:GetGroup() -- Wrapper.Group#GROUP --self:I("***** AI_A2A_DISPATCHER:CountDefendersToBeEngaged() *****\nThis is supposed to be a UNIT:")
if AIFriendly then
local classname = AIFriendly.ClassName or "No Class Name"
local unitname = AIFriendly.IdentifiableName or "No Unit Name"
--self:I("Class Name: " .. classname)
--self:I("Unit Name: " .. unitname)
--self:I({AIFriendly})
end
local Friendly = nil
if AIFriendly and AIFriendly:IsAlive() then
--self:I("AIFriendly alive, getting GROUP")
Friendly = AIFriendly:GetGroup() -- Wrapper.Group#GROUP
end
if Friendly and Friendly:IsAlive() then if Friendly and Friendly:IsAlive() then
-- Ok, so we have a friendly near the potential target. -- Ok, so we have a friendly near the potential target.
-- Now we need to check if the AIGroup has a Task. -- Now we need to check if the AIGroup has a Task.
@@ -3570,7 +3583,7 @@ do -- AI_A2A_DISPATCHER
end end
--- Assigns A2G AI Tasks in relation to the detected items. --- Assigns A2G AI Tasks in relation to the detected items.
-- @param #AI_A2G_DISPATCHER self -- @param #AI_A2A_DISPATCHER self
function AI_A2A_DISPATCHER:Order( DetectedItem ) function AI_A2A_DISPATCHER:Order( DetectedItem )
local detection = self.Detection -- Functional.Detection#DETECTION_AREAS local detection = self.Detection -- Functional.Detection#DETECTION_AREAS
+2 -1
View File
@@ -731,13 +731,14 @@ end
-- @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.
-- @param DCS#Object Initiator The initiating object of the event. -- @param DCS#Object Initiator The initiating object of the event.
function BASE:CreateEventCrash( EventTime, Initiator ) function BASE:CreateEventCrash( EventTime, Initiator, IniObjectCategory )
self:F( { EventTime, Initiator } ) self:F( { EventTime, Initiator } )
local Event = { local Event = {
id = world.event.S_EVENT_CRASH, id = world.event.S_EVENT_CRASH,
time = EventTime, time = EventTime,
initiator = Initiator, initiator = Initiator,
IniObjectCategory = IniObjectCategory,
} }
world.onEvent( Event ) world.onEvent( Event )
+4 -2
View File
@@ -757,7 +757,9 @@ function DATABASE:_RegisterStaticTemplate( StaticTemplate, CoalitionID, Category
local StaticTemplate = UTILS.DeepCopy( StaticTemplate ) local StaticTemplate = UTILS.DeepCopy( StaticTemplate )
local StaticTemplateName = env.getValueDictByKey( StaticTemplate.name ) local StaticTemplateGroupName = env.getValueDictByKey( StaticTemplate.name )
local StaticTemplateName=StaticTemplate.units[1].name
self.Templates.Statics[StaticTemplateName] = self.Templates.Statics[StaticTemplateName] or {} self.Templates.Statics[StaticTemplateName] = self.Templates.Statics[StaticTemplateName] or {}
@@ -765,7 +767,7 @@ function DATABASE:_RegisterStaticTemplate( StaticTemplate, CoalitionID, Category
StaticTemplate.CoalitionID = CoalitionID StaticTemplate.CoalitionID = CoalitionID
StaticTemplate.CountryID = CountryID StaticTemplate.CountryID = CountryID
self.Templates.Statics[StaticTemplateName].StaticName = StaticTemplateName self.Templates.Statics[StaticTemplateName].StaticName = StaticTemplateGroupName
self.Templates.Statics[StaticTemplateName].GroupTemplate = StaticTemplate self.Templates.Statics[StaticTemplateName].GroupTemplate = StaticTemplate
self.Templates.Statics[StaticTemplateName].UnitTemplate = StaticTemplate.units[1] self.Templates.Statics[StaticTemplateName].UnitTemplate = StaticTemplate.units[1]
self.Templates.Statics[StaticTemplateName].CategoryID = CategoryID self.Templates.Statics[StaticTemplateName].CategoryID = CategoryID
+134 -109
View File
@@ -131,8 +131,6 @@
-- * Weapon data: Certain events populate weapon information. -- * Weapon data: Certain events populate weapon information.
-- * Place data: Certain events populate place information. -- * Place data: Certain events populate place information.
-- --
-- Example code snippet:
--
-- --- This function is an Event Handling function that will be called when Tank1 is Dead. -- --- This function is an Event Handling function that will be called when Tank1 is Dead.
-- -- EventData is an EVENTDATA structure. -- -- EventData is an EVENTDATA structure.
-- -- We use the EventData.IniUnit to smoke the tank Green. -- -- We use the EventData.IniUnit to smoke the tank Green.
@@ -143,6 +141,7 @@
-- 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)
@@ -152,7 +151,6 @@
-- In case a STATIC object is involved, the documentation indicates which fields will and won't not be populated. -- In case a STATIC object is involved, the documentation indicates which fields will and won't not be populated.
-- The fields **IniObjectCategory** and **TgtObjectCategory** contain the indicator which **kind of object is involved** in the event. -- The fields **IniObjectCategory** and **TgtObjectCategory** contain the indicator which **kind of object is involved** in the event.
-- You can use the enumerator **Object.Category.UNIT** and **Object.Category.STATIC** to check on IniObjectCategory and TgtObjectCategory. -- You can use the enumerator **Object.Category.UNIT** and **Object.Category.STATIC** to check on IniObjectCategory and TgtObjectCategory.
--
-- Example code snippet: -- Example code snippet:
-- --
-- if Event.IniObjectCategory == Object.Category.UNIT then -- if Event.IniObjectCategory == Object.Category.UNIT then
@@ -174,6 +172,7 @@
-- @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
@@ -195,6 +194,7 @@ 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,6 +304,8 @@ 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,
@@ -560,6 +562,7 @@ local _EVENTMETA = {
}, },
} }
--- The Events structure --- The Events structure
-- @type EVENT.Events -- @type EVENT.Events
-- @field #number IniUnit -- @field #number IniUnit
@@ -573,11 +576,12 @@ function EVENT:New()
local self = BASE:Inherit( self, BASE:New() ) local self = BASE:Inherit( self, BASE:New() )
-- Add world event handler. -- Add world event handler.
self.EventHandler = world.addEventHandler( self ) self.EventHandler = world.addEventHandler(self)
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.
@@ -591,7 +595,7 @@ function EVENT:Init( EventID, EventClass )
self.Events[EventID] = {} self.Events[EventID] = {}
end end
-- Each event has a sub-table of EventClasses, ordered by EventPriority. -- Each event has a subtable 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
@@ -634,7 +638,7 @@ end
-- @param Core.Base#BASE EventClass The self instance of the class for which the event is. -- @param Core.Base#BASE EventClass The self instance of the class for which the event is.
-- @param DCS#world.event EventID Event ID. -- @param DCS#world.event EventID Event ID.
-- @return #EVENT.Events -- @return #EVENT.Events
function EVENT:Reset( EventObject ) -- R2.1 function EVENT:Reset( EventObject ) --R2.1
self:F( { "Resetting subscriptions for class: ", EventObject:GetClassNameAndID() } ) self:F( { "Resetting subscriptions for class: ", EventObject:GetClassNameAndID() } )
@@ -653,11 +657,12 @@ 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.
-- @return #EVENT self -- @return #EVENT self
function EVENT:RemoveAll( EventClass ) function EVENT:RemoveAll(EventClass)
local EventClassName = EventClass:GetClassNameAndID() local EventClassName = EventClass:GetClassNameAndID()
@@ -671,6 +676,8 @@ 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
@@ -702,6 +709,7 @@ 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.
@@ -789,6 +797,7 @@ do -- OnDead
end end
do -- OnLand do -- OnLand
--- Create an OnLand event handler for a group --- Create an OnLand event handler for a group
@@ -920,6 +929,7 @@ 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.
@@ -935,6 +945,7 @@ 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.
@@ -944,7 +955,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 )
@@ -959,7 +970,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 )
@@ -972,24 +983,25 @@ end
-- @param #EVENTDATA Event Event data table. -- @param #EVENTDATA Event Event data table.
function EVENT:onEvent( Event ) function EVENT:onEvent( Event )
--- Function to handle errors.
local ErrorHandler = function( errmsg ) local ErrorHandler = function( errmsg )
env.info( "Error in SCHEDULER function:" .. errmsg ) env.info( "Error in SCHEDULER function:" .. errmsg )
if BASE.Debug ~= nil then if BASE.Debug ~= nil then
env.info( debug.traceback() ) env.info( debug.traceback() )
end end
return errmsg return errmsg
end end
-- Get event meta data. -- Get event meta data.
local EventMeta = _EVENTMETA[Event.id] local EventMeta = _EVENTMETA[Event.id]
-- Check if this is a known event? -- Check if this is a known event?
if EventMeta then if EventMeta then
if self and self.Events and self.Events[Event.id] and self.MissionEnd == false and (Event.initiator ~= nil or (Event.initiator == nil and Event.id ~= EVENTS.PlayerLeaveUnit)) then if self and self.Events and self.Events[Event.id] and self.MissionEnd==false and (Event.initiator~=nil or (Event.initiator==nil and Event.id~=EVENTS.PlayerLeaveUnit)) then
-- Check if mission has ended.
if Event.id and Event.id == EVENTS.MissionEnd then if Event.id and Event.id == EVENTS.MissionEnd then
self.MissionEnd = true self.MissionEnd = true
end end
@@ -998,46 +1010,23 @@ function EVENT:onEvent( Event )
Event.IniObjectCategory = Event.initiator:getCategory() Event.IniObjectCategory = Event.initiator:getCategory()
if Event.IniObjectCategory == Object.Category.UNIT then
Event.IniDCSUnit = Event.initiator
Event.IniDCSUnitName = Event.IniDCSUnit:getName()
Event.IniUnitName = Event.IniDCSUnitName
Event.IniDCSGroup = Event.IniDCSUnit:getGroup()
Event.IniUnit = UNIT:FindByName( Event.IniDCSUnitName )
if not Event.IniUnit then
-- Unit can be a CLIENT. Most likely this will be the case ...
Event.IniUnit = CLIENT:FindByName( Event.IniDCSUnitName, '', true )
end
Event.IniDCSGroupName = ""
if Event.IniDCSGroup and Event.IniDCSGroup:isExist() then
Event.IniDCSGroupName = Event.IniDCSGroup:getName()
Event.IniGroup = GROUP:FindByName( Event.IniDCSGroupName )
-- if Event.IniGroup then
Event.IniGroupName = Event.IniDCSGroupName
-- end
end
Event.IniPlayerName = Event.IniDCSUnit:getPlayerName()
Event.IniCoalition = Event.IniDCSUnit:getCoalition()
Event.IniTypeName = Event.IniDCSUnit:getTypeName()
Event.IniCategory = Event.IniDCSUnit:getDesc().category
end
if Event.IniObjectCategory == Object.Category.STATIC then if Event.IniObjectCategory == Object.Category.STATIC then
---
if Event.id == 31 then -- Static
---
if Event.id==31 then
-- Event.initiator is a Static object representing the pilot. But getName() errors due to DCS bug. -- Event.initiator is a Static object representing the pilot. But getName() errors due to DCS bug.
Event.IniDCSUnit = Event.initiator Event.IniDCSUnit = Event.initiator
local ID = Event.initiator.id_ local ID=Event.initiator.id_
Event.IniDCSUnitName = string.format( "Ejected Pilot ID %s", tostring( ID ) ) Event.IniDCSUnitName = string.format("Ejected Pilot ID %s", tostring(ID))
Event.IniUnitName = Event.IniDCSUnitName Event.IniUnitName = Event.IniDCSUnitName
Event.IniCoalition = 0 Event.IniCoalition = 0
Event.IniCategory = 0 Event.IniCategory = 0
Event.IniTypeName = "Ejected Pilot" Event.IniTypeName = "Ejected Pilot"
elseif Event.id == 33 then -- ejection seat discarded elseif Event.id == 33 then -- ejection seat discarded
Event.IniDCSUnit = Event.initiator Event.IniDCSUnit = Event.initiator
local ID = Event.initiator.id_ local ID=Event.initiator.id_
Event.IniDCSUnitName = string.format( "Ejection Seat ID %s", tostring( ID ) ) Event.IniDCSUnitName = string.format("Ejection Seat ID %s", tostring(ID))
Event.IniUnitName = Event.IniDCSUnitName Event.IniUnitName = Event.IniDCSUnitName
Event.IniCoalition = 0 Event.IniCoalition = 0
Event.IniCategory = 0 Event.IniCategory = 0
@@ -1051,9 +1040,47 @@ function EVENT:onEvent( Event )
Event.IniCategory = Event.IniDCSUnit:getDesc().category Event.IniCategory = Event.IniDCSUnit:getDesc().category
Event.IniTypeName = Event.IniDCSUnit:getTypeName() Event.IniTypeName = Event.IniDCSUnit:getTypeName()
end end
-- Dead events of units can be delayed and the initiator changed to a static.
-- Take care of that.
local Unit=UNIT:FindByName(Event.IniDCSUnitName)
if Unit then
Event.IniObjectCategory = Object.Category.UNIT
end
end
if Event.IniObjectCategory == Object.Category.UNIT then
---
-- Unit
---
Event.IniDCSUnit = Event.initiator
Event.IniDCSUnitName = Event.IniDCSUnit:getName()
Event.IniUnitName = Event.IniDCSUnitName
Event.IniDCSGroup = Event.IniDCSUnit:getGroup()
Event.IniUnit = UNIT:FindByName( Event.IniDCSUnitName )
if not Event.IniUnit then
-- Unit can be a CLIENT. Most likely this will be the case ...
Event.IniUnit = CLIENT:FindByName( Event.IniDCSUnitName, '', true )
end
Event.IniDCSGroupName = Event.IniUnit and Event.IniUnit.GroupName or ""
if Event.IniDCSGroup and Event.IniDCSGroup:isExist() then
Event.IniDCSGroupName = Event.IniDCSGroup:getName()
Event.IniGroup = GROUP:FindByName( Event.IniDCSGroupName )
Event.IniGroupName = Event.IniDCSGroupName
end
Event.IniPlayerName = Event.IniDCSUnit:getPlayerName()
Event.IniCoalition = Event.IniDCSUnit:getCoalition()
Event.IniTypeName = Event.IniDCSUnit:getTypeName()
Event.IniCategory = Event.IniDCSUnit:getDesc().category
end end
if Event.IniObjectCategory == Object.Category.CARGO then if Event.IniObjectCategory == Object.Category.CARGO then
---
-- Cargo
---
Event.IniDCSUnit = Event.initiator Event.IniDCSUnit = Event.initiator
Event.IniDCSUnitName = Event.IniDCSUnit:getName() Event.IniDCSUnitName = Event.IniDCSUnit:getName()
Event.IniUnitName = Event.IniDCSUnitName Event.IniUnitName = Event.IniDCSUnitName
@@ -1064,19 +1091,26 @@ function EVENT:onEvent( Event )
end end
if Event.IniObjectCategory == Object.Category.SCENERY then if Event.IniObjectCategory == Object.Category.SCENERY then
---
-- Scenery
---
Event.IniDCSUnit = Event.initiator Event.IniDCSUnit = Event.initiator
Event.IniDCSUnitName = Event.IniDCSUnit:getName() Event.IniDCSUnitName = Event.IniDCSUnit:getName()
Event.IniUnitName = Event.IniDCSUnitName Event.IniUnitName = Event.IniDCSUnitName
Event.IniUnit = SCENERY:Register( Event.IniDCSUnitName, Event.initiator ) Event.IniUnit = SCENERY:Register( Event.IniDCSUnitName, Event.initiator )
Event.IniCategory = Event.IniDCSUnit:getDesc().category Event.IniCategory = Event.IniDCSUnit:getDesc().category
Event.IniTypeName = Event.initiator:isExist() and Event.IniDCSUnit:getTypeName() or "SCENERY" -- TODO: Bug fix for 2.1! Event.IniTypeName = Event.initiator:isExist() and Event.IniDCSUnit:getTypeName() or "SCENERY"
end end
if Event.IniObjectCategory == Object.Category.BASE then if Event.IniObjectCategory == Object.Category.BASE then
---
-- Base Object
---
Event.IniDCSUnit = Event.initiator Event.IniDCSUnit = Event.initiator
Event.IniDCSUnitName = Event.IniDCSUnit:getName() Event.IniDCSUnitName = Event.IniDCSUnit:getName()
Event.IniUnitName = Event.IniDCSUnitName Event.IniUnitName = Event.IniDCSUnitName
Event.IniUnit = AIRBASE:FindByName( Event.IniDCSUnitName ) Event.IniUnit = AIRBASE:FindByName(Event.IniDCSUnitName)
Event.IniCoalition = Event.IniDCSUnit:getCoalition() Event.IniCoalition = Event.IniDCSUnit:getCoalition()
Event.IniCategory = Event.IniDCSUnit:getDesc().category Event.IniCategory = Event.IniDCSUnit:getDesc().category
Event.IniTypeName = Event.IniDCSUnit:getTypeName() Event.IniTypeName = Event.IniDCSUnit:getTypeName()
@@ -1085,6 +1119,11 @@ function EVENT:onEvent( Event )
if Event.target then if Event.target then
---
-- TARGET
---
-- Target category.
Event.TgtObjectCategory = Event.target:getCategory() Event.TgtObjectCategory = Event.target:getCategory()
if Event.TgtObjectCategory == Object.Category.UNIT then if Event.TgtObjectCategory == Object.Category.UNIT then
@@ -1097,9 +1136,7 @@ function EVENT:onEvent( Event )
if Event.TgtDCSGroup and Event.TgtDCSGroup:isExist() then if Event.TgtDCSGroup and Event.TgtDCSGroup:isExist() then
Event.TgtDCSGroupName = Event.TgtDCSGroup:getName() Event.TgtDCSGroupName = Event.TgtDCSGroup:getName()
Event.TgtGroup = GROUP:FindByName( Event.TgtDCSGroupName ) Event.TgtGroup = GROUP:FindByName( Event.TgtDCSGroupName )
-- if Event.TgtGroup then
Event.TgtGroupName = Event.TgtDCSGroupName Event.TgtGroupName = Event.TgtDCSGroupName
-- end
end end
Event.TgtPlayerName = Event.TgtDCSUnit:getPlayerName() Event.TgtPlayerName = Event.TgtDCSUnit:getPlayerName()
Event.TgtCoalition = Event.TgtDCSUnit:getCoalition() Event.TgtCoalition = Event.TgtDCSUnit:getCoalition()
@@ -1118,18 +1155,18 @@ function EVENT:onEvent( Event )
Event.TgtCategory = Event.TgtDCSUnit:getDesc().category Event.TgtCategory = Event.TgtDCSUnit:getDesc().category
Event.TgtTypeName = Event.TgtDCSUnit:getTypeName() Event.TgtTypeName = Event.TgtDCSUnit:getTypeName()
else else
Event.TgtDCSUnitName = string.format( "No target object for Event ID %s", tostring( Event.id ) ) Event.TgtDCSUnitName = string.format("No target object for Event ID %s", tostring(Event.id))
Event.TgtUnitName = Event.TgtDCSUnitName Event.TgtUnitName = Event.TgtDCSUnitName
Event.TgtUnit = nil Event.TgtUnit = nil
Event.TgtCoalition = 0 Event.TgtCoalition = 0
Event.TgtCategory = 0 Event.TgtCategory = 0
if Event.id == 6 then if Event.id == 6 then
Event.TgtTypeName = "Ejected Pilot" Event.TgtTypeName = "Ejected Pilot"
Event.TgtDCSUnitName = string.format( "Ejected Pilot ID %s", tostring( Event.IniDCSUnitName ) ) Event.TgtDCSUnitName = string.format("Ejected Pilot ID %s", tostring(Event.IniDCSUnitName))
Event.TgtUnitName = Event.TgtDCSUnitName Event.TgtUnitName = Event.TgtDCSUnitName
elseif Event.id == 33 then elseif Event.id == 33 then
Event.TgtTypeName = "Ejection Seat" Event.TgtTypeName = "Ejection Seat"
Event.TgtDCSUnitName = string.format( "Ejection Seat ID %s", tostring( Event.IniDCSUnitName ) ) Event.TgtDCSUnitName = string.format("Ejection Seat ID %s", tostring(Event.IniDCSUnitName))
Event.TgtUnitName = Event.TgtDCSUnitName Event.TgtUnitName = Event.TgtDCSUnitName
else else
Event.TgtTypeName = "Static" Event.TgtTypeName = "Static"
@@ -1147,6 +1184,7 @@ function EVENT:onEvent( Event )
end end
end end
-- Weapon.
if Event.weapon then if Event.weapon then
Event.Weapon = Event.weapon Event.Weapon = Event.weapon
Event.WeaponName = Event.Weapon:getTypeName() Event.WeaponName = Event.Weapon:getTypeName()
@@ -1155,50 +1193,49 @@ function EVENT:onEvent( Event )
Event.WeaponCoalition = Event.WeaponUNIT and Event.Weapon:getCoalition() Event.WeaponCoalition = Event.WeaponUNIT and Event.Weapon:getCoalition()
Event.WeaponCategory = Event.WeaponUNIT and Event.Weapon:getDesc().category Event.WeaponCategory = Event.WeaponUNIT and Event.Weapon:getDesc().category
Event.WeaponTypeName = Event.WeaponUNIT and Event.Weapon:getTypeName() Event.WeaponTypeName = Event.WeaponUNIT and Event.Weapon:getTypeName()
-- Event.WeaponTgtDCSUnit = Event.Weapon:getTarget() --Event.WeaponTgtDCSUnit = Event.Weapon:getTarget()
end end
-- Place should be given for takeoff and landing events as well as base captured. It should be a DCS airbase. -- Place should be given for takeoff and landing events as well as base captured. It should be a DCS airbase.
if Event.place then if Event.place then
if Event.id == EVENTS.LandingAfterEjection then if Event.id==EVENTS.LandingAfterEjection then
-- Place is here the UNIT of which the pilot ejected. -- Place is here the UNIT of which the pilot ejected.
-- local name=Event.place:getName() -- This returns a DCS error "Airbase doesn't exit" :( --local name=Event.place:getName() -- This returns a DCS error "Airbase doesn't exit" :(
-- However, this is not a big thing, as the aircraft the pilot ejected from is usually long crashed before the ejected pilot touches the ground. -- However, this is not a big thing, as the aircraft the pilot ejected from is usually long crashed before the ejected pilot touches the ground.
-- Event.Place=UNIT:Find(Event.place) --Event.Place=UNIT:Find(Event.place)
else else
Event.Place = AIRBASE:Find( Event.place ) Event.Place=AIRBASE:Find(Event.place)
Event.PlaceName = Event.Place:GetName() Event.PlaceName=Event.Place:GetName()
end end
end end
-- Mark points. -- Mark points.
if Event.idx then if Event.idx then
Event.MarkID = Event.idx Event.MarkID=Event.idx
Event.MarkVec3 = Event.pos Event.MarkVec3=Event.pos
Event.MarkCoordinate = COORDINATE:NewFromVec3( Event.pos ) Event.MarkCoordinate=COORDINATE:NewFromVec3(Event.pos)
Event.MarkText = Event.text Event.MarkText=Event.text
Event.MarkCoalition = Event.coalition Event.MarkCoalition=Event.coalition
Event.MarkGroupID = Event.groupID Event.MarkGroupID = Event.groupID
end end
-- Cargo object.
if Event.cargo then if Event.cargo then
Event.Cargo = Event.cargo Event.Cargo = Event.cargo
Event.CargoName = Event.cargo.Name Event.CargoName = Event.cargo.Name
end end
-- Zone object.
if Event.zone then if Event.zone then
Event.Zone = Event.zone Event.Zone = Event.zone
Event.ZoneName = Event.zone.ZoneName Event.ZoneName = Event.zone.ZoneName
end end
-- Priority order.
local PriorityOrder = EventMeta.Order local PriorityOrder = EventMeta.Order
local PriorityBegin = PriorityOrder == -1 and 5 or 1 local PriorityBegin = PriorityOrder == -1 and 5 or 1
local PriorityEnd = PriorityOrder == -1 and 1 or 5 local PriorityEnd = PriorityOrder == -1 and 1 or 5
if Event.IniObjectCategory ~= Object.Category.STATIC then
self:F( { EventMeta.Text, Event, Event.IniDCSUnitName, Event.TgtDCSUnitName, PriorityOrder } )
end
for EventPriority = PriorityBegin, PriorityEnd, PriorityOrder do for EventPriority = PriorityBegin, PriorityEnd, PriorityOrder do
if self.Events[Event.id][EventPriority] then if self.Events[Event.id][EventPriority] then
@@ -1206,12 +1243,12 @@ function EVENT:onEvent( Event )
-- Okay, we got the event from DCS. Now loop the SORTED self.EventSorted[] table for the received Event.id, and for each EventData registered, check if a function needs to be called. -- Okay, we got the event from DCS. Now loop the SORTED self.EventSorted[] table for the received Event.id, and for each EventData registered, check if a function needs to be called.
for EventClass, EventData in pairs( self.Events[Event.id][EventPriority] ) do for EventClass, EventData in pairs( self.Events[Event.id][EventPriority] ) do
-- if Event.IniObjectCategory ~= Object.Category.STATIC then --if Event.IniObjectCategory ~= Object.Category.STATIC then
-- self:E( { "Evaluating: ", EventClass:GetClassNameAndID() } ) -- self:E( { "Evaluating: ", EventClass:GetClassNameAndID() } )
-- end --end
Event.IniGroup = GROUP:FindByName( Event.IniDCSGroupName ) Event.IniGroup = Event.IniGroup or GROUP:FindByName( Event.IniDCSGroupName )
Event.TgtGroup = GROUP:FindByName( Event.TgtDCSGroupName ) Event.TgtGroup = Event.TgtGroup or GROUP:FindByName( Event.TgtDCSGroupName )
-- If the EventData is for a UNIT, the call directly the EventClass EventFunction for that UNIT. -- If the EventData is for a UNIT, the call directly the EventClass EventFunction for that UNIT.
if EventData.EventUnit then if EventData.EventUnit then
@@ -1221,39 +1258,35 @@ function EVENT:onEvent( Event )
Event.id == EVENTS.PlayerEnterUnit or Event.id == EVENTS.PlayerEnterUnit or
Event.id == EVENTS.Crash or Event.id == EVENTS.Crash or
Event.id == EVENTS.Dead or Event.id == EVENTS.Dead or
Event.id == EVENTS.RemoveUnit then Event.id == EVENTS.RemoveUnit or
Event.id == EVENTS.UnitLost then
local UnitName = EventClass:GetName() local UnitName = EventClass:GetName()
if (EventMeta.Side == "I" and UnitName == Event.IniDCSUnitName) or if ( EventMeta.Side == "I" and UnitName == Event.IniDCSUnitName ) or
(EventMeta.Side == "T" and UnitName == Event.TgtDCSUnitName) then ( EventMeta.Side == "T" and UnitName == Event.TgtDCSUnitName ) then
-- First test if a EventFunction is Set, otherwise search for the default function -- First test if a EventFunction is Set, otherwise search for the default function
if EventData.EventFunction then if EventData.EventFunction then
if Event.IniObjectCategory ~= 3 then local Result, Value = xpcall(
self:F( { "Calling EventFunction for UNIT ", EventClass:GetClassNameAndID(), ", Unit ", Event.IniUnitName, EventPriority } ) function()
end
local Result, Value = xpcall( function()
return EventData.EventFunction( EventClass, Event ) return EventData.EventFunction( EventClass, Event )
end, ErrorHandler ) end, ErrorHandler )
else else
-- There is no EventFunction defined, so try to find if a default OnEvent function is defined on the object. -- There is no EventFunction defined, so try to find if a default OnEvent function is defined on the object.
local EventFunction = EventClass[EventMeta.Event] local EventFunction = EventClass[ EventMeta.Event ]
if EventFunction and type( EventFunction ) == "function" then if EventFunction and type( EventFunction ) == "function" then
-- Now call the default event function. -- Now call the default event function.
if Event.IniObjectCategory ~= 3 then local Result, Value = xpcall(
self:F( { "Calling " .. EventMeta.Event .. " for Class ", EventClass:GetClassNameAndID(), EventPriority } ) function()
end
local Result, Value = xpcall( function()
return EventFunction( EventClass, Event ) return EventFunction( EventClass, Event )
end, ErrorHandler ) end, ErrorHandler )
end end
end end
end end
else else
@@ -1271,37 +1304,32 @@ function EVENT:onEvent( Event )
Event.id == EVENTS.PlayerEnterUnit or Event.id == EVENTS.PlayerEnterUnit or
Event.id == EVENTS.Crash or Event.id == EVENTS.Crash or
Event.id == EVENTS.Dead or Event.id == EVENTS.Dead or
Event.id == EVENTS.RemoveUnit then Event.id == EVENTS.RemoveUnit or
Event.id == EVENTS.UnitLost then
-- We can get the name of the EventClass, which is now always a GROUP object. -- We can get the name of the EventClass, which is now always a GROUP object.
local GroupName = EventClass:GetName() local GroupName = EventClass:GetName()
if (EventMeta.Side == "I" and GroupName == Event.IniDCSGroupName) or if ( EventMeta.Side == "I" and GroupName == Event.IniDCSGroupName ) or
(EventMeta.Side == "T" and GroupName == Event.TgtDCSGroupName) then ( EventMeta.Side == "T" and GroupName == Event.TgtDCSGroupName ) then
-- First test if a EventFunction is Set, otherwise search for the default function -- First test if a EventFunction is Set, otherwise search for the default function
if EventData.EventFunction then if EventData.EventFunction then
if Event.IniObjectCategory ~= 3 then local Result, Value = xpcall(
self:F( { "Calling EventFunction for GROUP ", EventClass:GetClassNameAndID(), ", Unit ", Event.IniUnitName, EventPriority } ) function()
end
local Result, Value = xpcall( function()
return EventData.EventFunction( EventClass, Event, unpack( EventData.Params ) ) return EventData.EventFunction( EventClass, Event, unpack( EventData.Params ) )
end, ErrorHandler ) end, ErrorHandler )
else else
-- There is no EventFunction defined, so try to find if a default OnEvent function is defined on the object. -- There is no EventFunction defined, so try to find if a default OnEvent function is defined on the object.
local EventFunction = EventClass[EventMeta.Event] local EventFunction = EventClass[ EventMeta.Event ]
if EventFunction and type( EventFunction ) == "function" then if EventFunction and type( EventFunction ) == "function" then
-- Now call the default event function. -- Now call the default event function.
if Event.IniObjectCategory ~= 3 then local Result, Value = xpcall(
self:F( { "Calling " .. EventMeta.Event .. " for GROUP ", EventClass:GetClassNameAndID(), EventPriority } ) function()
end
local Result, Value = xpcall( function()
return EventFunction( EventClass, Event, unpack( EventData.Params ) ) return EventFunction( EventClass, Event, unpack( EventData.Params ) )
end, ErrorHandler ) end, ErrorHandler )
end end
@@ -1309,7 +1337,7 @@ function EVENT:onEvent( Event )
end end
else else
-- The EventClass is not alive anymore, we remove it from the EventHandlers... -- The EventClass is not alive anymore, we remove it from the EventHandlers...
-- self:RemoveEvent( EventClass, Event.id ) --self:RemoveEvent( EventClass, Event.id )
end end
else else
@@ -1321,28 +1349,25 @@ function EVENT:onEvent( Event )
if EventData.EventFunction then if EventData.EventFunction then
-- There is an EventFunction defined, so call the EventFunction. -- There is an EventFunction defined, so call the EventFunction.
if Event.IniObjectCategory ~= 3 then local Result, Value = xpcall(
self:F2( { "Calling EventFunction for Class ", EventClass:GetClassNameAndID(), EventPriority } ) function()
end
local Result, Value = xpcall( function()
return EventData.EventFunction( EventClass, Event ) return EventData.EventFunction( EventClass, Event )
end, ErrorHandler ) end, ErrorHandler )
else else
-- There is no EventFunction defined, so try to find if a default OnEvent function is defined on the object. -- There is no EventFunction defined, so try to find if a default OnEvent function is defined on the object.
local EventFunction = EventClass[EventMeta.Event] local EventFunction = EventClass[ EventMeta.Event ]
if EventFunction and type( EventFunction ) == "function" then if EventFunction and type( EventFunction ) == "function" then
-- Now call the default event function. -- Now call the default event function.
if Event.IniObjectCategory ~= 3 then local Result, Value = xpcall(
self:F2( { "Calling " .. EventMeta.Event .. " for Class ", EventClass:GetClassNameAndID(), EventPriority } ) function()
end
local Result, Value = xpcall( function()
local Result, Value = EventFunction( EventClass, Event ) local Result, Value = EventFunction( EventClass, Event )
return Result, Value return Result, Value
end, ErrorHandler ) end, ErrorHandler )
end end
end end
end end
@@ -1365,7 +1390,7 @@ function EVENT:onEvent( Event )
self:T( { EventMeta.Text, Event } ) self:T( { EventMeta.Text, Event } )
end end
else else
self:E( string.format( "WARNING: Could not get EVENTMETA data for event ID=%d! Is this an unknown/new DCS event?", tostring( Event.id ) ) ) self:E(string.format("WARNING: Could not get EVENTMETA data for event ID=%d! Is this an unknown/new DCS event?", tostring(Event.id)))
end end
Event = nil Event = nil
+33 -125
View File
@@ -64,7 +64,6 @@ 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 ""
if ParentMenu then if ParentMenu then
if ParentMenu:IsInstanceOf( "MENU_GROUP" ) or ParentMenu:IsInstanceOf( "MENU_GROUP_COMMAND" ) then if ParentMenu:IsInstanceOf( "MENU_GROUP" ) or ParentMenu:IsInstanceOf( "MENU_GROUP_COMMAND" ) then
@@ -92,7 +91,6 @@ function MENU_INDEX:ParentPath( ParentMenu, MenuText )
Path = Path .. "@" .. MenuText Path = Path .. "@" .. MenuText
return Path return Path
end end
function MENU_INDEX:PrepareMission() function MENU_INDEX:PrepareMission()
@@ -103,7 +101,6 @@ function MENU_INDEX:PrepareCoalition( CoalitionSide )
self.Coalition[CoalitionSide] = self.Coalition[CoalitionSide] or {} self.Coalition[CoalitionSide] = self.Coalition[CoalitionSide] or {}
self.Coalition[CoalitionSide].Menus = self.Coalition[CoalitionSide].Menus or {} self.Coalition[CoalitionSide].Menus = self.Coalition[CoalitionSide].Menus or {}
end end
--- ---
-- @param Wrapper.Group#GROUP Group -- @param Wrapper.Group#GROUP Group
function MENU_INDEX:PrepareGroup( Group ) function MENU_INDEX:PrepareGroup( Group )
@@ -115,32 +112,22 @@ function MENU_INDEX:PrepareGroup( Group )
end end
function MENU_INDEX:HasMissionMenu( Path ) function MENU_INDEX:HasMissionMenu( Path )
return self.MenuMission.Menus[Path] return self.MenuMission.Menus[Path]
end end
function MENU_INDEX:SetMissionMenu( Path, Menu ) function MENU_INDEX:SetMissionMenu( Path, Menu )
self.MenuMission.Menus[Path] = Menu self.MenuMission.Menus[Path] = Menu
end end
function MENU_INDEX:ClearMissionMenu( Path ) function MENU_INDEX:ClearMissionMenu( Path )
self.MenuMission.Menus[Path] = nil self.MenuMission.Menus[Path] = nil
end end
function MENU_INDEX:HasCoalitionMenu( Coalition, Path ) function MENU_INDEX:HasCoalitionMenu( Coalition, Path )
return self.Coalition[Coalition].Menus[Path] return self.Coalition[Coalition].Menus[Path]
end end
function MENU_INDEX:SetCoalitionMenu( Coalition, Path, Menu ) function MENU_INDEX:SetCoalitionMenu( Coalition, Path, Menu )
self.Coalition[Coalition].Menus[Path] = Menu self.Coalition[Coalition].Menus[Path] = Menu
end end
function MENU_INDEX:ClearCoalitionMenu( Coalition, Path ) function MENU_INDEX:ClearCoalitionMenu( Coalition, Path )
self.Coalition[Coalition].Menus[Path] = nil self.Coalition[Coalition].Menus[Path] = nil
end end
@@ -151,46 +138,36 @@ function MENU_INDEX:HasGroupMenu( Group, Path )
end end
return nil return nil
end end
function MENU_INDEX:SetGroupMenu( Group, Path, Menu ) function MENU_INDEX:SetGroupMenu( Group, Path, Menu )
local MenuGroupName = Group:GetName() local MenuGroupName = Group:GetName()
Group:F( { MenuGroupName = MenuGroupName, Path = Path } ) Group:F({MenuGroupName=MenuGroupName,Path=Path})
self.Group[MenuGroupName].Menus[Path] = Menu self.Group[MenuGroupName].Menus[Path] = Menu
end end
function MENU_INDEX:ClearGroupMenu( Group, Path ) function MENU_INDEX:ClearGroupMenu( Group, Path )
local MenuGroupName = Group:GetName() local MenuGroupName = Group:GetName()
self.Group[MenuGroupName].Menus[Path] = nil self.Group[MenuGroupName].Menus[Path] = nil
end end
function MENU_INDEX:Refresh( Group ) function MENU_INDEX:Refresh( Group )
for MenuID, Menu in pairs( self.MenuMission.Menus ) do for MenuID, Menu in pairs( self.MenuMission.Menus ) do
Menu:Refresh() Menu:Refresh()
end end
for MenuID, Menu in pairs( self.Coalition[coalition.side.BLUE].Menus ) do for MenuID, Menu in pairs( self.Coalition[coalition.side.BLUE].Menus ) do
Menu:Refresh() Menu:Refresh()
end end
for MenuID, Menu in pairs( self.Coalition[coalition.side.RED].Menus ) do for MenuID, Menu in pairs( self.Coalition[coalition.side.RED].Menus ) do
Menu:Refresh() Menu:Refresh()
end end
local GroupName = Group:GetName() local GroupName = Group:GetName()
for MenuID, Menu in pairs( self.Group[GroupName].Menus ) do for MenuID, Menu in pairs( self.Group[GroupName].Menus ) do
Menu:Refresh() Menu:Refresh()
end end
return self
end end
do -- MENU_BASE do -- MENU_BASE
--- @type MENU_BASE --- @type MENU_BASE
-- @extends Core.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.
-- @field #MENU_BASE -- @field #MENU_BASE
@@ -210,14 +187,13 @@ do -- MENU_BASE
if ParentMenu ~= nil then if ParentMenu ~= nil then
MenuParentPath = ParentMenu.MenuPath MenuParentPath = ParentMenu.MenuPath
end end
local self = BASE:Inherit( self, BASE:New() ) local self = BASE:Inherit( self, BASE:New() )
self.MenuPath = nil self.MenuPath = nil
self.MenuText = MenuText self.MenuText = MenuText
self.ParentMenu = ParentMenu self.ParentMenu = ParentMenu
self.MenuParentPath = MenuParentPath self.MenuParentPath = MenuParentPath
self.Path = (self.ParentMenu and "@" .. table.concat( self.MenuParentPath or {}, "@" ) or "") .. "@" .. self.MenuText self.Path = ( self.ParentMenu and "@" .. table.concat( self.MenuParentPath or {}, "@" ) or "" ) .. "@" .. self.MenuText
self.Menus = {} self.Menus = {}
self.MenuCount = 0 self.MenuCount = 0
self.MenuStamp = timer.getTime() self.MenuStamp = timer.getTime()
@@ -230,7 +206,6 @@ do -- MENU_BASE
return self return self
end end
function MENU_BASE:SetParentMenu( MenuText, Menu ) function MENU_BASE:SetParentMenu( MenuText, Menu )
if self.ParentMenu then if self.ParentMenu then
self.ParentMenu.Menus = self.ParentMenu.Menus or {} self.ParentMenu.Menus = self.ParentMenu.Menus or {}
@@ -238,23 +213,21 @@ do -- MENU_BASE
self.ParentMenu.MenuCount = self.ParentMenu.MenuCount + 1 self.ParentMenu.MenuCount = self.ParentMenu.MenuCount + 1
end end
end end
function MENU_BASE:ClearParentMenu( MenuText ) function MENU_BASE:ClearParentMenu( MenuText )
if self.ParentMenu and self.ParentMenu.Menus[MenuText] then if self.ParentMenu and self.ParentMenu.Menus[MenuText] then
self.ParentMenu.Menus[MenuText] = nil self.ParentMenu.Menus[MenuText] = nil
self.ParentMenu.MenuCount = self.ParentMenu.MenuCount - 1 self.ParentMenu.MenuCount = self.ParentMenu.MenuCount - 1
if self.ParentMenu.MenuCount == 0 then if self.ParentMenu.MenuCount == 0 then
-- self.ParentMenu:Remove() --self.ParentMenu:Remove()
end end
end end
end end
--- Sets a @{Menu} to remove automatically the parent menu when the menu removed is the last child menu of that parent @{Menu}. --- Sets a @{Menu} to remove automatically the parent menu when the menu removed is the last child menu of that parent @{Menu}.
-- @param #MENU_BASE self -- @param #MENU_BASE self
-- @param #boolean RemoveParent If true, the parent menu is automatically removed when this menu is the last child menu of that parent @{Menu}. -- @param #boolean RemoveParent If true, the parent menu is automatically removed when this menu is the last child menu of that parent @{Menu}.
-- @return #MENU_BASE -- @return #MENU_BASE
function MENU_BASE:SetRemoveParent( RemoveParent ) function MENU_BASE:SetRemoveParent( RemoveParent )
-- self:F( { RemoveParent } ) --self:F( { RemoveParent } )
self.MenuRemoveParent = RemoveParent self.MenuRemoveParent = RemoveParent
return self return self
end end
@@ -266,7 +239,6 @@ do -- MENU_BASE
function MENU_BASE:GetMenu( MenuText ) function MENU_BASE:GetMenu( MenuText )
return self.Menus[MenuText] return self.Menus[MenuText]
end end
--- Sets a menu stamp for later prevention of menu removal. --- Sets a menu stamp for later prevention of menu removal.
-- @param #MENU_BASE self -- @param #MENU_BASE self
-- @param MenuStamp -- @param MenuStamp
@@ -276,6 +248,7 @@ 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
@@ -283,6 +256,7 @@ 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
@@ -302,9 +276,7 @@ do -- MENU_BASE
end end
end end
do -- MENU_COMMAND_BASE do -- MENU_COMMAND_BASE
--- @type MENU_COMMAND_BASE --- @type MENU_COMMAND_BASE
-- @field #function MenuCallHandler -- @field #function MenuCallHandler
-- @extends Core.Menu#MENU_BASE -- @extends Core.Menu#MENU_BASE
@@ -326,7 +298,6 @@ do -- MENU_COMMAND_BASE
function MENU_COMMAND_BASE:New( MenuText, ParentMenu, CommandMenuFunction, CommandMenuArguments ) function MENU_COMMAND_BASE:New( MenuText, ParentMenu, CommandMenuFunction, CommandMenuArguments )
local self = BASE:Inherit( self, MENU_BASE:New( MenuText, ParentMenu ) ) -- #MENU_COMMAND_BASE local self = BASE:Inherit( self, MENU_BASE:New( MenuText, ParentMenu ) ) -- #MENU_COMMAND_BASE
-- When a menu function goes into error, DCS displays an obscure menu message. -- When a menu function goes into error, DCS displays an obscure menu message.
-- This error handler catches the menu error and displays the full call stack. -- This error handler catches the menu error and displays the full call stack.
local ErrorHandler = function( errmsg ) local ErrorHandler = function( errmsg )
@@ -359,7 +330,6 @@ do -- MENU_COMMAND_BASE
self.CommandMenuFunction = CommandMenuFunction self.CommandMenuFunction = CommandMenuFunction
return self return self
end end
--- This sets the new command arguments of a menu, --- This sets the new command arguments of a menu,
-- so that if a menu is regenerated, or if command arguments change, -- so that if a menu is regenerated, or if command arguments change,
-- that the arguments set for the menu are loosely coupled with the menu itself!!! -- that the arguments set for the menu are loosely coupled with the menu itself!!!
@@ -370,14 +340,11 @@ do -- MENU_COMMAND_BASE
self.CommandMenuArguments = CommandMenuArguments self.CommandMenuArguments = CommandMenuArguments
return self return self
end end
end end
do -- MENU_MISSION do -- MENU_MISSION
--- @type MENU_MISSION --- @type MENU_MISSION
-- @extends Core.Menu#MENU_BASE -- @extends Core.Menu#MENU_BASE
--- Manages the main menus for a complete mission. --- Manages the main menus for a complete mission.
-- --
-- You can add menus with the @{#MENU_MISSION.New} method, which constructs a MENU_MISSION object and returns you the object reference. -- You can add menus with the @{#MENU_MISSION.New} method, which constructs a MENU_MISSION object and returns you the object reference.
@@ -397,7 +364,6 @@ do -- MENU_MISSION
MENU_INDEX:PrepareMission() MENU_INDEX:PrepareMission()
local Path = MENU_INDEX:ParentPath( ParentMenu, MenuText ) local Path = MENU_INDEX:ParentPath( ParentMenu, MenuText )
local MissionMenu = MENU_INDEX:HasMissionMenu( Path ) local MissionMenu = MENU_INDEX:HasMissionMenu( Path )
if MissionMenu then if MissionMenu then
return MissionMenu return MissionMenu
else else
@@ -410,17 +376,15 @@ do -- MENU_MISSION
end end
end end
--- Refreshes a radio item for a mission --- Refreshes a radio item for a mission
-- @param #MENU_MISSION self -- @param #MENU_MISSION self
-- @return #MENU_MISSION -- @return #MENU_MISSION
function MENU_MISSION:Refresh() function MENU_MISSION:Refresh()
do do
missionCommands.removeItem( self.MenuPath ) missionCommands.removeItem( self.MenuPath )
self.MenuPath = missionCommands.addSubMenu( self.MenuText, self.MenuParentPath ) self.MenuPath = missionCommands.addSubMenu( self.MenuText, self.MenuParentPath )
end end
return self
end end
--- Removes the sub menus recursively of this MENU_MISSION. Note that the main menu is kept! --- Removes the sub menus recursively of this MENU_MISSION. Note that the main menu is kept!
@@ -444,11 +408,10 @@ do -- MENU_MISSION
MENU_INDEX:PrepareMission() MENU_INDEX:PrepareMission()
local Path = MENU_INDEX:ParentPath( self.ParentMenu, self.MenuText ) local Path = MENU_INDEX:ParentPath( self.ParentMenu, self.MenuText )
local MissionMenu = MENU_INDEX:HasMissionMenu( Path ) local MissionMenu = MENU_INDEX:HasMissionMenu( Path )
if MissionMenu == self then if MissionMenu == self then
self:RemoveSubMenus() self:RemoveSubMenus()
if not MenuStamp or self.MenuStamp ~= MenuStamp then if not MenuStamp or self.MenuStamp ~= MenuStamp then
if (not MenuTag) or (MenuTag and self.MenuTag and MenuTag == self.MenuTag) then if ( not MenuTag ) or ( MenuTag and self.MenuTag and MenuTag == self.MenuTag ) then
self:F( { Text = self.MenuText, Path = self.MenuPath } ) self:F( { Text = self.MenuText, Path = self.MenuPath } )
if self.MenuPath ~= nil then if self.MenuPath ~= nil then
missionCommands.removeItem( self.MenuPath ) missionCommands.removeItem( self.MenuPath )
@@ -466,7 +429,6 @@ do -- MENU_MISSION
end end
end end
do -- MENU_MISSION_COMMAND do -- MENU_MISSION_COMMAND
--- @type MENU_MISSION_COMMAND --- @type MENU_MISSION_COMMAND
@@ -494,7 +456,6 @@ do -- MENU_MISSION_COMMAND
MENU_INDEX:PrepareMission() MENU_INDEX:PrepareMission()
local Path = MENU_INDEX:ParentPath( ParentMenu, MenuText ) local Path = MENU_INDEX:ParentPath( ParentMenu, MenuText )
local MissionMenu = MENU_INDEX:HasMissionMenu( Path ) local MissionMenu = MENU_INDEX:HasMissionMenu( Path )
if MissionMenu then if MissionMenu then
MissionMenu:SetCommandMenuFunction( CommandMenuFunction ) MissionMenu:SetCommandMenuFunction( CommandMenuFunction )
MissionMenu:SetCommandMenuArguments( arg ) MissionMenu:SetCommandMenuArguments( arg )
@@ -508,17 +469,15 @@ do -- MENU_MISSION_COMMAND
return self return self
end end
end end
--- Refreshes a radio item for a mission --- Refreshes a radio item for a mission
-- @param #MENU_MISSION_COMMAND self -- @param #MENU_MISSION_COMMAND self
-- @return #MENU_MISSION_COMMAND -- @return #MENU_MISSION_COMMAND
function MENU_MISSION_COMMAND:Refresh() function MENU_MISSION_COMMAND:Refresh()
do do
missionCommands.removeItem( self.MenuPath ) missionCommands.removeItem( self.MenuPath )
missionCommands.addCommand( self.MenuText, self.MenuParentPath, self.MenuCallHandler ) missionCommands.addCommand( self.MenuText, self.MenuParentPath, self.MenuCallHandler )
end end
return self
end end
--- Removes a radio command item for a coalition --- Removes a radio command item for a coalition
@@ -529,10 +488,9 @@ do -- MENU_MISSION_COMMAND
MENU_INDEX:PrepareMission() MENU_INDEX:PrepareMission()
local Path = MENU_INDEX:ParentPath( self.ParentMenu, self.MenuText ) local Path = MENU_INDEX:ParentPath( self.ParentMenu, self.MenuText )
local MissionMenu = MENU_INDEX:HasMissionMenu( Path ) local MissionMenu = MENU_INDEX:HasMissionMenu( Path )
if MissionMenu == self then if MissionMenu == self then
if not MenuStamp or self.MenuStamp ~= MenuStamp then if not MenuStamp or self.MenuStamp ~= MenuStamp then
if (not MenuTag) or (MenuTag and self.MenuTag and MenuTag == self.MenuTag) then if ( not MenuTag ) or ( MenuTag and self.MenuTag and MenuTag == self.MenuTag ) then
self:F( { Text = self.MenuText, Path = self.MenuPath } ) self:F( { Text = self.MenuText, Path = self.MenuPath } )
if self.MenuPath ~= nil then if self.MenuPath ~= nil then
missionCommands.removeItem( self.MenuPath ) missionCommands.removeItem( self.MenuPath )
@@ -548,11 +506,8 @@ do -- MENU_MISSION_COMMAND
return self return self
end end
end end
do -- MENU_COALITION do -- MENU_COALITION
--- @type MENU_COALITION --- @type MENU_COALITION
-- @extends Core.Menu#MENU_BASE -- @extends Core.Menu#MENU_BASE
@@ -601,7 +556,7 @@ 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.
@@ -611,15 +566,12 @@ do -- MENU_COALITION
-- @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). -- @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 )
MENU_INDEX:PrepareCoalition( Coalition ) MENU_INDEX:PrepareCoalition( Coalition )
local Path = MENU_INDEX:ParentPath( ParentMenu, MenuText ) local Path = MENU_INDEX:ParentPath( ParentMenu, MenuText )
local CoalitionMenu = MENU_INDEX:HasCoalitionMenu( Coalition, Path ) local CoalitionMenu = MENU_INDEX:HasCoalitionMenu( Coalition, Path )
if CoalitionMenu then if CoalitionMenu then
return CoalitionMenu return CoalitionMenu
else else
local self = BASE:Inherit( self, MENU_BASE:New( MenuText, ParentMenu ) ) local self = BASE:Inherit( self, MENU_BASE:New( MenuText, ParentMenu ) )
MENU_INDEX:SetCoalitionMenu( Coalition, Path, self ) MENU_INDEX:SetCoalitionMenu( Coalition, Path, self )
@@ -630,17 +582,15 @@ do -- MENU_COALITION
return self return self
end end
end end
--- Refreshes a radio item for a coalition --- Refreshes a radio item for a coalition
-- @param #MENU_COALITION self -- @param #MENU_COALITION self
-- @return #MENU_COALITION -- @return #MENU_COALITION
function MENU_COALITION:Refresh() function MENU_COALITION:Refresh()
do do
missionCommands.removeItemForCoalition( self.Coalition, self.MenuPath ) missionCommands.removeItemForCoalition( self.Coalition, self.MenuPath )
missionCommands.addSubMenuForCoalition( self.Coalition, self.MenuText, self.MenuParentPath ) missionCommands.addSubMenuForCoalition( self.Coalition, self.MenuText, self.MenuParentPath )
end end
return self
end end
--- Removes the sub menus recursively of this MENU_COALITION. Note that the main menu is kept! --- Removes the sub menus recursively of this MENU_COALITION. Note that the main menu is kept!
@@ -663,11 +613,10 @@ do -- MENU_COALITION
MENU_INDEX:PrepareCoalition( self.Coalition ) MENU_INDEX:PrepareCoalition( self.Coalition )
local Path = MENU_INDEX:ParentPath( self.ParentMenu, self.MenuText ) local Path = MENU_INDEX:ParentPath( self.ParentMenu, self.MenuText )
local CoalitionMenu = MENU_INDEX:HasCoalitionMenu( self.Coalition, Path ) local CoalitionMenu = MENU_INDEX:HasCoalitionMenu( self.Coalition, Path )
if CoalitionMenu == self then if CoalitionMenu == self then
self:RemoveSubMenus() self:RemoveSubMenus()
if not MenuStamp or self.MenuStamp ~= MenuStamp then if not MenuStamp or self.MenuStamp ~= MenuStamp then
if (not MenuTag) or (MenuTag and self.MenuTag and MenuTag == self.MenuTag) then if ( not MenuTag ) or ( MenuTag and self.MenuTag and MenuTag == self.MenuTag ) then
self:F( { Coalition = self.Coalition, Text = self.MenuText, Path = self.MenuPath } ) self:F( { Coalition = self.Coalition, Text = self.MenuText, Path = self.MenuPath } )
if self.MenuPath ~= nil then if self.MenuPath ~= nil then
missionCommands.removeItemForCoalition( self.Coalition, self.MenuPath ) missionCommands.removeItemForCoalition( self.Coalition, self.MenuPath )
@@ -683,9 +632,7 @@ do -- MENU_COALITION
return self return self
end end
end end
do -- MENU_COALITION_COMMAND do -- MENU_COALITION_COMMAND
--- @type MENU_COALITION_COMMAND --- @type MENU_COALITION_COMMAND
@@ -698,7 +645,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.
@@ -714,7 +661,6 @@ do -- MENU_COALITION_COMMAND
MENU_INDEX:PrepareCoalition( Coalition ) MENU_INDEX:PrepareCoalition( Coalition )
local Path = MENU_INDEX:ParentPath( ParentMenu, MenuText ) local Path = MENU_INDEX:ParentPath( ParentMenu, MenuText )
local CoalitionMenu = MENU_INDEX:HasCoalitionMenu( Coalition, Path ) local CoalitionMenu = MENU_INDEX:HasCoalitionMenu( Coalition, Path )
if CoalitionMenu then if CoalitionMenu then
CoalitionMenu:SetCommandMenuFunction( CommandMenuFunction ) CoalitionMenu:SetCommandMenuFunction( CommandMenuFunction )
CoalitionMenu:SetCommandMenuArguments( arg ) CoalitionMenu:SetCommandMenuArguments( arg )
@@ -729,19 +675,17 @@ do -- MENU_COALITION_COMMAND
self:SetParentMenu( self.MenuText, self ) self:SetParentMenu( self.MenuText, self )
return self return self
end end
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
function MENU_COALITION_COMMAND:Refresh() function MENU_COALITION_COMMAND:Refresh()
do do
missionCommands.removeItemForCoalition( self.Coalition, self.MenuPath ) missionCommands.removeItemForCoalition( self.Coalition, self.MenuPath )
missionCommands.addCommandForCoalition( self.Coalition, self.MenuText, self.MenuParentPath, self.MenuCallHandler ) missionCommands.addCommandForCoalition( self.Coalition, self.MenuText, self.MenuParentPath, self.MenuCallHandler )
end end
return self
end end
--- Removes a radio command item for a coalition --- Removes a radio command item for a coalition
@@ -752,10 +696,9 @@ do -- MENU_COALITION_COMMAND
MENU_INDEX:PrepareCoalition( self.Coalition ) MENU_INDEX:PrepareCoalition( self.Coalition )
local Path = MENU_INDEX:ParentPath( self.ParentMenu, self.MenuText ) local Path = MENU_INDEX:ParentPath( self.ParentMenu, self.MenuText )
local CoalitionMenu = MENU_INDEX:HasCoalitionMenu( self.Coalition, Path ) local CoalitionMenu = MENU_INDEX:HasCoalitionMenu( self.Coalition, Path )
if CoalitionMenu == self then if CoalitionMenu == self then
if not MenuStamp or self.MenuStamp ~= MenuStamp then if not MenuStamp or self.MenuStamp ~= MenuStamp then
if (not MenuTag) or (MenuTag and self.MenuTag and MenuTag == self.MenuTag) then if ( not MenuTag ) or ( MenuTag and self.MenuTag and MenuTag == self.MenuTag ) then
self:F( { Coalition = self.Coalition, Text = self.MenuText, Path = self.MenuPath } ) self:F( { Coalition = self.Coalition, Text = self.MenuText, Path = self.MenuPath } )
if self.MenuPath ~= nil then if self.MenuPath ~= nil then
missionCommands.removeItemForCoalition( self.Coalition, self.MenuPath ) missionCommands.removeItemForCoalition( self.Coalition, self.MenuPath )
@@ -771,11 +714,9 @@ do -- MENU_COALITION_COMMAND
return self return self
end end
end end
--- MENU_GROUP --- MENU_GROUP
do do
-- This local variable is used to cache the menus registered under groups. -- This local variable is used to cache the menus registered under groups.
-- Menus don't disappear when groups for players are destroyed and restarted. -- Menus don't disappear when groups for players are destroyed and restarted.
@@ -783,10 +724,10 @@ do
-- the same menus twice during initialization logic. -- the same menus twice during initialization logic.
-- These menu classes are handling this logic with this variable. -- These menu classes are handling this logic with this variable.
local _MENUGROUPS = {} local _MENUGROUPS = {}
--- @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.
@@ -844,7 +785,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.
@@ -858,16 +799,13 @@ do
MENU_INDEX:PrepareGroup( Group ) MENU_INDEX:PrepareGroup( Group )
local Path = MENU_INDEX:ParentPath( ParentMenu, MenuText ) local Path = MENU_INDEX:ParentPath( ParentMenu, MenuText )
local GroupMenu = MENU_INDEX:HasGroupMenu( Group, Path ) local GroupMenu = MENU_INDEX:HasGroupMenu( Group, Path )
if GroupMenu then if GroupMenu then
return GroupMenu return GroupMenu
else else
self = BASE:Inherit( self, MENU_BASE:New( MenuText, ParentMenu ) ) self = BASE:Inherit( self, MENU_BASE:New( MenuText, ParentMenu ) )
MENU_INDEX:SetGroupMenu( Group, Path, self ) MENU_INDEX:SetGroupMenu( Group, Path, self )
self.Group = Group self.Group = Group
self.GroupID = Group:GetID() self.GroupID = Group:GetID()
self.MenuPath = missionCommands.addSubMenuForGroup( self.GroupID, MenuText, self.MenuParentPath ) self.MenuPath = missionCommands.addSubMenuForGroup( self.GroupID, MenuText, self.MenuParentPath )
self:SetParentMenu( self.MenuText, self ) self:SetParentMenu( self.MenuText, self )
@@ -875,12 +813,10 @@ do
end end
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 self -- @param #MENU_GROUP self
-- @return #MENU_GROUP -- @return #MENU_GROUP
function MENU_GROUP:Refresh() function MENU_GROUP:Refresh()
do do
missionCommands.removeItemForGroup( self.GroupID, self.MenuPath ) missionCommands.removeItemForGroup( self.GroupID, self.MenuPath )
missionCommands.addSubMenuForGroup( self.GroupID, self.MenuText, self.MenuParentPath ) missionCommands.addSubMenuForGroup( self.GroupID, self.MenuText, self.MenuParentPath )
@@ -890,6 +826,7 @@ do
end end
end end
return self
end end
--- Removes the sub menus recursively of this MENU_GROUP. --- Removes the sub menus recursively of this MENU_GROUP.
@@ -898,7 +835,6 @@ do
-- @param MenuTag A Tag or Key to filter the menus to be refreshed with the Tag set. -- @param MenuTag A Tag or Key to filter the menus to be refreshed with the Tag set.
-- @return #MENU_GROUP self -- @return #MENU_GROUP self
function MENU_GROUP:RemoveSubMenus( MenuStamp, MenuTag ) function MENU_GROUP:RemoveSubMenus( MenuStamp, MenuTag )
for MenuText, Menu in pairs( self.Menus or {} ) do for MenuText, Menu in pairs( self.Menus or {} ) do
Menu:Remove( MenuStamp, MenuTag ) Menu:Remove( MenuStamp, MenuTag )
end end
@@ -913,15 +849,13 @@ do
-- @param MenuTag A Tag or Key to filter the menus to be refreshed with the Tag set. -- @param MenuTag A Tag or Key to filter the menus to be refreshed with the Tag set.
-- @return #nil -- @return #nil
function MENU_GROUP:Remove( MenuStamp, MenuTag ) function MENU_GROUP:Remove( MenuStamp, MenuTag )
MENU_INDEX:PrepareGroup( self.Group ) MENU_INDEX:PrepareGroup( self.Group )
local Path = MENU_INDEX:ParentPath( self.ParentMenu, self.MenuText ) local Path = MENU_INDEX:ParentPath( self.ParentMenu, self.MenuText )
local GroupMenu = MENU_INDEX:HasGroupMenu( self.Group, Path ) local GroupMenu = MENU_INDEX:HasGroupMenu( self.Group, Path )
if GroupMenu == self then if GroupMenu == self then
self:RemoveSubMenus( MenuStamp, MenuTag ) self:RemoveSubMenus( MenuStamp, MenuTag )
if not MenuStamp or self.MenuStamp ~= MenuStamp then if not MenuStamp or self.MenuStamp ~= MenuStamp then
if (not MenuTag) or (MenuTag and self.MenuTag and MenuTag == self.MenuTag) then if ( not MenuTag ) or ( MenuTag and self.MenuTag and MenuTag == self.MenuTag ) then
if self.MenuPath ~= nil then if self.MenuPath ~= nil then
self:F( { Group = self.GroupID, Text = self.MenuText, Path = self.MenuPath } ) self:F( { Group = self.GroupID, Text = self.MenuText, Path = self.MenuPath } )
missionCommands.removeItemForGroup( self.GroupID, self.MenuPath ) missionCommands.removeItemForGroup( self.GroupID, self.MenuPath )
@@ -939,6 +873,7 @@ 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
@@ -948,7 +883,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
@@ -960,18 +895,15 @@ do
-- @param CommandMenuArgument An argument for the function. -- @param CommandMenuArgument An argument for the function.
-- @return #MENU_GROUP_COMMAND -- @return #MENU_GROUP_COMMAND
function MENU_GROUP_COMMAND:New( Group, MenuText, ParentMenu, CommandMenuFunction, ... ) function MENU_GROUP_COMMAND:New( Group, MenuText, ParentMenu, CommandMenuFunction, ... )
MENU_INDEX:PrepareGroup( Group ) MENU_INDEX:PrepareGroup( Group )
local Path = MENU_INDEX:ParentPath( ParentMenu, MenuText ) local Path = MENU_INDEX:ParentPath( ParentMenu, MenuText )
local GroupMenu = MENU_INDEX:HasGroupMenu( Group, Path ) local GroupMenu = MENU_INDEX:HasGroupMenu( Group, Path )
if GroupMenu then if GroupMenu then
GroupMenu:SetCommandMenuFunction( CommandMenuFunction ) GroupMenu:SetCommandMenuFunction( CommandMenuFunction )
GroupMenu:SetCommandMenuArguments( arg ) GroupMenu:SetCommandMenuArguments( arg )
return GroupMenu return GroupMenu
else else
self = BASE:Inherit( self, MENU_COMMAND_BASE:New( MenuText, ParentMenu, CommandMenuFunction, arg ) ) self = BASE:Inherit( self, MENU_COMMAND_BASE:New( MenuText, ParentMenu, CommandMenuFunction, arg ) )
MENU_INDEX:SetGroupMenu( Group, Path, self ) MENU_INDEX:SetGroupMenu( Group, Path, self )
self.Group = Group self.Group = Group
@@ -982,19 +914,17 @@ do
self:SetParentMenu( self.MenuText, self ) self:SetParentMenu( self.MenuText, self )
return self return self
end end
end end
--- Refreshes a radio item for a group --- Refreshes a radio item for a group
-- @param #MENU_GROUP_COMMAND self -- @param #MENU_GROUP_COMMAND self
-- @return #MENU_GROUP_COMMAND -- @return #MENU_GROUP_COMMAND
function MENU_GROUP_COMMAND:Refresh() function MENU_GROUP_COMMAND:Refresh()
do do
missionCommands.removeItemForGroup( self.GroupID, self.MenuPath ) missionCommands.removeItemForGroup( self.GroupID, self.MenuPath )
missionCommands.addCommandForGroup( self.GroupID, self.MenuText, self.MenuParentPath, self.MenuCallHandler ) missionCommands.addCommandForGroup( self.GroupID, self.MenuText, self.MenuParentPath, self.MenuCallHandler )
end end
return self
end end
--- Removes a menu structure for a group. --- Removes a menu structure for a group.
@@ -1003,14 +933,12 @@ do
-- @param MenuTag A Tag or Key to filter the menus to be refreshed with the Tag set. -- @param MenuTag A Tag or Key to filter the menus to be refreshed with the Tag set.
-- @return #nil -- @return #nil
function MENU_GROUP_COMMAND:Remove( MenuStamp, MenuTag ) function MENU_GROUP_COMMAND:Remove( MenuStamp, MenuTag )
MENU_INDEX:PrepareGroup( self.Group ) MENU_INDEX:PrepareGroup( self.Group )
local Path = MENU_INDEX:ParentPath( self.ParentMenu, self.MenuText ) local Path = MENU_INDEX:ParentPath( self.ParentMenu, self.MenuText )
local GroupMenu = MENU_INDEX:HasGroupMenu( self.Group, Path ) local GroupMenu = MENU_INDEX:HasGroupMenu( self.Group, Path )
if GroupMenu == self then if GroupMenu == self then
if not MenuStamp or self.MenuStamp ~= MenuStamp then if not MenuStamp or self.MenuStamp ~= MenuStamp then
if (not MenuTag) or (MenuTag and self.MenuTag and MenuTag == self.MenuTag) then if ( not MenuTag ) or ( MenuTag and self.MenuTag and MenuTag == self.MenuTag ) then
if self.MenuPath ~= nil then if self.MenuPath ~= nil then
self:F( { Group = self.GroupID, Text = self.MenuText, Path = self.MenuPath } ) self:F( { Group = self.GroupID, Text = self.MenuText, Path = self.MenuPath } )
missionCommands.removeItemForGroup( self.GroupID, self.MenuPath ) missionCommands.removeItemForGroup( self.GroupID, self.MenuPath )
@@ -1026,16 +954,13 @@ do
return self return self
end end
end end
--- MENU_GROUP_DELAYED --- MENU_GROUP_DELAYED
do 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}.
@@ -1045,7 +970,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.
@@ -1059,16 +984,13 @@ do
MENU_INDEX:PrepareGroup( Group ) MENU_INDEX:PrepareGroup( Group )
local Path = MENU_INDEX:ParentPath( ParentMenu, MenuText ) local Path = MENU_INDEX:ParentPath( ParentMenu, MenuText )
local GroupMenu = MENU_INDEX:HasGroupMenu( Group, Path ) local GroupMenu = MENU_INDEX:HasGroupMenu( Group, Path )
if GroupMenu then if GroupMenu then
return GroupMenu return GroupMenu
else else
self = BASE:Inherit( self, MENU_BASE:New( MenuText, ParentMenu ) ) self = BASE:Inherit( self, MENU_BASE:New( MenuText, ParentMenu ) )
MENU_INDEX:SetGroupMenu( Group, Path, self ) MENU_INDEX:SetGroupMenu( Group, Path, self )
self.Group = Group self.Group = Group
self.GroupID = Group:GetID() self.GroupID = Group:GetID()
if self.MenuParentPath then if self.MenuParentPath then
self.MenuPath = UTILS.DeepCopy( self.MenuParentPath ) self.MenuPath = UTILS.DeepCopy( self.MenuParentPath )
else else
@@ -1086,7 +1008,6 @@ do
-- @param #MENU_GROUP_DELAYED self -- @param #MENU_GROUP_DELAYED self
-- @return #MENU_GROUP_DELAYED -- @return #MENU_GROUP_DELAYED
function MENU_GROUP_DELAYED:Set() function MENU_GROUP_DELAYED:Set()
do do
if not self.MenuSet then if not self.MenuSet then
missionCommands.addSubMenuForGroup( self.GroupID, self.MenuText, self.MenuParentPath ) missionCommands.addSubMenuForGroup( self.GroupID, self.MenuText, self.MenuParentPath )
@@ -1097,14 +1018,12 @@ do
Menu:Set() Menu:Set()
end end
end end
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
function MENU_GROUP_DELAYED:Refresh() function MENU_GROUP_DELAYED:Refresh()
do do
missionCommands.removeItemForGroup( self.GroupID, self.MenuPath ) missionCommands.removeItemForGroup( self.GroupID, self.MenuPath )
missionCommands.addSubMenuForGroup( self.GroupID, self.MenuText, self.MenuParentPath ) missionCommands.addSubMenuForGroup( self.GroupID, self.MenuText, self.MenuParentPath )
@@ -1114,6 +1033,7 @@ do
end end
end end
return self
end end
--- Removes the sub menus recursively of this MENU_GROUP_DELAYED. --- Removes the sub menus recursively of this MENU_GROUP_DELAYED.
@@ -1122,7 +1042,6 @@ do
-- @param MenuTag A Tag or Key to filter the menus to be refreshed with the Tag set. -- @param MenuTag A Tag or Key to filter the menus to be refreshed with the Tag set.
-- @return #MENU_GROUP_DELAYED self -- @return #MENU_GROUP_DELAYED self
function MENU_GROUP_DELAYED:RemoveSubMenus( MenuStamp, MenuTag ) function MENU_GROUP_DELAYED:RemoveSubMenus( MenuStamp, MenuTag )
for MenuText, Menu in pairs( self.Menus or {} ) do for MenuText, Menu in pairs( self.Menus or {} ) do
Menu:Remove( MenuStamp, MenuTag ) Menu:Remove( MenuStamp, MenuTag )
end end
@@ -1137,15 +1056,13 @@ do
-- @param MenuTag A Tag or Key to filter the menus to be refreshed with the Tag set. -- @param MenuTag A Tag or Key to filter the menus to be refreshed with the Tag set.
-- @return #nil -- @return #nil
function MENU_GROUP_DELAYED:Remove( MenuStamp, MenuTag ) function MENU_GROUP_DELAYED:Remove( MenuStamp, MenuTag )
MENU_INDEX:PrepareGroup( self.Group ) MENU_INDEX:PrepareGroup( self.Group )
local Path = MENU_INDEX:ParentPath( self.ParentMenu, self.MenuText ) local Path = MENU_INDEX:ParentPath( self.ParentMenu, self.MenuText )
local GroupMenu = MENU_INDEX:HasGroupMenu( self.Group, Path ) local GroupMenu = MENU_INDEX:HasGroupMenu( self.Group, Path )
if GroupMenu == self then if GroupMenu == self then
self:RemoveSubMenus( MenuStamp, MenuTag ) self:RemoveSubMenus( MenuStamp, MenuTag )
if not MenuStamp or self.MenuStamp ~= MenuStamp then if not MenuStamp or self.MenuStamp ~= MenuStamp then
if (not MenuTag) or (MenuTag and self.MenuTag and MenuTag == self.MenuTag) then if ( not MenuTag ) or ( MenuTag and self.MenuTag and MenuTag == self.MenuTag ) then
if self.MenuPath ~= nil then if self.MenuPath ~= nil then
self:F( { Group = self.GroupID, Text = self.MenuText, Path = self.MenuPath } ) self:F( { Group = self.GroupID, Text = self.MenuText, Path = self.MenuPath } )
missionCommands.removeItemForGroup( self.GroupID, self.MenuPath ) missionCommands.removeItemForGroup( self.GroupID, self.MenuPath )
@@ -1163,6 +1080,7 @@ 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
@@ -1173,7 +1091,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
@@ -1185,18 +1103,15 @@ do
-- @param CommandMenuArgument An argument for the function. -- @param CommandMenuArgument An argument for the function.
-- @return #MENU_GROUP_COMMAND_DELAYED -- @return #MENU_GROUP_COMMAND_DELAYED
function MENU_GROUP_COMMAND_DELAYED:New( Group, MenuText, ParentMenu, CommandMenuFunction, ... ) function MENU_GROUP_COMMAND_DELAYED:New( Group, MenuText, ParentMenu, CommandMenuFunction, ... )
MENU_INDEX:PrepareGroup( Group ) MENU_INDEX:PrepareGroup( Group )
local Path = MENU_INDEX:ParentPath( ParentMenu, MenuText ) local Path = MENU_INDEX:ParentPath( ParentMenu, MenuText )
local GroupMenu = MENU_INDEX:HasGroupMenu( Group, Path ) local GroupMenu = MENU_INDEX:HasGroupMenu( Group, Path )
if GroupMenu then if GroupMenu then
GroupMenu:SetCommandMenuFunction( CommandMenuFunction ) GroupMenu:SetCommandMenuFunction( CommandMenuFunction )
GroupMenu:SetCommandMenuArguments( arg ) GroupMenu:SetCommandMenuArguments( arg )
return GroupMenu return GroupMenu
else else
self = BASE:Inherit( self, MENU_COMMAND_BASE:New( MenuText, ParentMenu, CommandMenuFunction, arg ) ) self = BASE:Inherit( self, MENU_COMMAND_BASE:New( MenuText, ParentMenu, CommandMenuFunction, arg ) )
MENU_INDEX:SetGroupMenu( Group, Path, self ) MENU_INDEX:SetGroupMenu( Group, Path, self )
self.Group = Group self.Group = Group
@@ -1212,33 +1127,29 @@ do
self:SetParentMenu( self.MenuText, self ) self:SetParentMenu( self.MenuText, self )
return self return self
end end
end end
--- Refreshes a radio item for a group --- Refreshes a radio item for a group
-- @param #MENU_GROUP_COMMAND_DELAYED self -- @param #MENU_GROUP_COMMAND_DELAYED self
-- @return #MENU_GROUP_COMMAND_DELAYED -- @return #MENU_GROUP_COMMAND_DELAYED
function MENU_GROUP_COMMAND_DELAYED:Set() function MENU_GROUP_COMMAND_DELAYED:Set()
do do
if not self.MenuSet then if not self.MenuSet then
self.MenuPath = missionCommands.addCommandForGroup( self.GroupID, self.MenuText, self.MenuParentPath, self.MenuCallHandler ) self.MenuPath = missionCommands.addCommandForGroup( self.GroupID, self.MenuText, self.MenuParentPath, self.MenuCallHandler )
self.MenuSet = true self.MenuSet = true
end end
end end
end end
--- Refreshes a radio item for a group --- Refreshes a radio item for a group
-- @param #MENU_GROUP_COMMAND_DELAYED self -- @param #MENU_GROUP_COMMAND_DELAYED self
-- @return #MENU_GROUP_COMMAND_DELAYED -- @return #MENU_GROUP_COMMAND_DELAYED
function MENU_GROUP_COMMAND_DELAYED:Refresh() function MENU_GROUP_COMMAND_DELAYED:Refresh()
do do
missionCommands.removeItemForGroup( self.GroupID, self.MenuPath ) missionCommands.removeItemForGroup( self.GroupID, self.MenuPath )
missionCommands.addCommandForGroup( self.GroupID, self.MenuText, self.MenuParentPath, self.MenuCallHandler ) missionCommands.addCommandForGroup( self.GroupID, self.MenuText, self.MenuParentPath, self.MenuCallHandler )
end end
return self
end end
--- Removes a menu structure for a group. --- Removes a menu structure for a group.
@@ -1247,14 +1158,12 @@ do
-- @param MenuTag A Tag or Key to filter the menus to be refreshed with the Tag set. -- @param MenuTag A Tag or Key to filter the menus to be refreshed with the Tag set.
-- @return #nil -- @return #nil
function MENU_GROUP_COMMAND_DELAYED:Remove( MenuStamp, MenuTag ) function MENU_GROUP_COMMAND_DELAYED:Remove( MenuStamp, MenuTag )
MENU_INDEX:PrepareGroup( self.Group ) MENU_INDEX:PrepareGroup( self.Group )
local Path = MENU_INDEX:ParentPath( self.ParentMenu, self.MenuText ) local Path = MENU_INDEX:ParentPath( self.ParentMenu, self.MenuText )
local GroupMenu = MENU_INDEX:HasGroupMenu( self.Group, Path ) local GroupMenu = MENU_INDEX:HasGroupMenu( self.Group, Path )
if GroupMenu == self then if GroupMenu == self then
if not MenuStamp or self.MenuStamp ~= MenuStamp then if not MenuStamp or self.MenuStamp ~= MenuStamp then
if (not MenuTag) or (MenuTag and self.MenuTag and MenuTag == self.MenuTag) then if ( not MenuTag ) or ( MenuTag and self.MenuTag and MenuTag == self.MenuTag ) then
if self.MenuPath ~= nil then if self.MenuPath ~= nil then
self:F( { Group = self.GroupID, Text = self.MenuText, Path = self.MenuPath } ) self:F( { Group = self.GroupID, Text = self.MenuText, Path = self.MenuPath } )
missionCommands.removeItemForGroup( self.GroupID, self.MenuPath ) missionCommands.removeItemForGroup( self.GroupID, self.MenuPath )
@@ -1270,6 +1179,5 @@ do
return self return self
end end
end end
+34 -3
View File
@@ -10,6 +10,8 @@
-- * Send message to all players. -- * Send message to all players.
-- * Send messages to a coalition. -- * Send messages to a coalition.
-- * Send messages to a specific group. -- * Send messages to a specific group.
-- * Send messages to a specific unit or client.
--
-- --
-- === -- ===
-- --
@@ -35,6 +37,7 @@
-- --
-- * To a @{Client} using @{#MESSAGE.ToClient}(). -- * To a @{Client} using @{#MESSAGE.ToClient}().
-- * To a @{Wrapper.Group} using @{#MESSAGE.ToGroup}() -- * To a @{Wrapper.Group} using @{#MESSAGE.ToGroup}()
-- * To a @{Wrapper.Unit} using @{#MESSAGE.ToUnit}()
-- * To a coalition using @{#MESSAGE.ToCoalition}(). -- * To a coalition using @{#MESSAGE.ToCoalition}().
-- * To the red coalition using @{#MESSAGE.ToRed}(). -- * To the red coalition using @{#MESSAGE.ToRed}().
-- * To the blue coalition using @{#MESSAGE.ToBlue}(). -- * To the blue coalition using @{#MESSAGE.ToBlue}().
@@ -194,15 +197,18 @@ function MESSAGE:ToClient( Client, Settings )
if Client and Client:GetClientGroupID() then if Client and Client:GetClientGroupID() then
if self.MessageType then if self.MessageType then
local Settings = Settings or (Client and _DATABASE:GetPlayerSettings( Client:GetPlayerName() )) or _SETTINGS -- Core.Settings#SETTINGS local Settings = Settings or ( Client and _DATABASE:GetPlayerSettings( Client:GetPlayerName() ) ) or _SETTINGS -- Core.Settings#SETTINGS
self.MessageDuration = Settings:GetMessageTime( self.MessageType ) self.MessageDuration = Settings:GetMessageTime( self.MessageType )
self.MessageCategory = "" -- self.MessageType .. ": " self.MessageCategory = "" -- self.MessageType .. ": "
end end
local Unit = Client:GetClient()
if self.MessageDuration ~= 0 then if self.MessageDuration ~= 0 then
local ClientGroupID = Client:GetClientGroupID() local ClientGroupID = Client:GetClientGroupID()
self:T( self.MessageCategory .. self.MessageText:gsub( "\n$", "" ):gsub( "\n$", "" ) .. " / " .. self.MessageDuration ) self:T( self.MessageCategory .. self.MessageText:gsub("\n$",""):gsub("\n$","") .. " / " .. self.MessageDuration )
trigger.action.outTextForGroup( ClientGroupID, self.MessageCategory .. self.MessageText:gsub( "\n$", "" ):gsub( "\n$", "" ), self.MessageDuration, self.ClearScreen ) --trigger.action.outTextForGroup( ClientGroupID, self.MessageCategory .. self.MessageText:gsub("\n$",""):gsub("\n$",""), self.MessageDuration , self.ClearScreen)
trigger.action.outTextForUnit( Unit:GetID(), self.MessageCategory .. self.MessageText:gsub("\n$",""):gsub("\n$",""), self.MessageDuration , self.ClearScreen)
end end
end end
@@ -232,6 +238,31 @@ function MESSAGE:ToGroup( Group, Settings )
return self return self
end end
--- Sends a MESSAGE to a Unit.
-- @param #MESSAGE self
-- @param Wrapper.Unit#UNIT Unit to which the message is displayed.
-- @return #MESSAGE Message object.
function MESSAGE:ToUnit( Unit, Settings )
self:F( Unit.IdentifiableName )
if Unit then
if self.MessageType then
local Settings = Settings or ( Unit and _DATABASE:GetPlayerSettings( Unit:GetPlayerName() ) ) or _SETTINGS -- Core.Settings#SETTINGS
self.MessageDuration = Settings:GetMessageTime( self.MessageType )
self.MessageCategory = "" -- self.MessageType .. ": "
end
if self.MessageDuration ~= 0 then
self:T( self.MessageCategory .. self.MessageText:gsub("\n$",""):gsub("\n$","") .. " / " .. self.MessageDuration )
trigger.action.outTextForUnit( Unit:GetID(), self.MessageCategory .. self.MessageText:gsub("\n$",""):gsub("\n$",""), self.MessageDuration, self.ClearScreen )
end
end
return self
end
--- Sends a MESSAGE to the Blue coalition. --- Sends a MESSAGE to the Blue coalition.
-- @param #MESSAGE self -- @param #MESSAGE self
-- @return #MESSAGE -- @return #MESSAGE
+99 -16
View File
@@ -194,7 +194,12 @@ 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.ToStringBRA}(): Generates a Bearing, Range & Altitude text.
-- * @{#COORDINATE.ToStringBRAANATO}(): Generates a Generates a Bearing, Range, Aspect & Altitude text in NATOPS.
-- * @{#COORDINATE.ToStringLL}(): Generates a Latutide & Longitude text.
-- * @{#COORDINATE.ToStringLLDMS}(): Generates a Lat, Lon, Degree, Minute, Second text.
-- * @{#COORDINATE.ToStringLLDDM}(): Generates a Lat, Lon, Degree, decimal Minute text.
-- * @{#COORDINATE.ToStringMGRS}(): Generates a MGRS grid coordinate text.
-- --
-- ## 10) Drawings on F10 map -- ## 10) Drawings on F10 map
-- --
@@ -912,7 +917,7 @@ do -- COORDINATE
-- 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 Celcius (°C)
-- - For American 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:
-- --
@@ -932,7 +937,7 @@ do -- COORDINATE
if Settings:IsMetric() then if Settings:IsMetric() then
return string.format( " %-2.2f °C", DegreesCelcius ) return string.format( " %-2.2f °C", DegreesCelcius )
else else
return string.format( " %-2.2f °F", UTILS.CelciusToFarenheit( DegreesCelcius ) ) return string.format( " %-2.2f °F", UTILS.CelsiusToFahrenheit( DegreesCelcius ) )
end end
else else
return " no temperature" return " no temperature"
@@ -1112,25 +1117,28 @@ do -- COORDINATE
-- @param #COORDINATE self -- @param #COORDINATE self
-- @param #number Distance The distance in meters. -- @param #number Distance The distance in meters.
-- @param Core.Settings#SETTINGS Settings -- @param Core.Settings#SETTINGS Settings
-- @param #string Language (optional) "EN" or "RU"
-- @param #number Precision (optional) round to this many decimal places
-- @return #string The distance text expressed in the units of measurement. -- @return #string The distance text expressed in the units of measurement.
function COORDINATE:GetDistanceText( Distance, Settings, Language ) function COORDINATE:GetDistanceText( Distance, Settings, Language, Precision )
local Settings = Settings or _SETTINGS -- Core.Settings#SETTINGS local Settings = Settings or _SETTINGS -- Core.Settings#SETTINGS
local Language = Language or "EN" local Language = Language or "EN"
local Precision = Precision or 0
local DistanceText local DistanceText
if Settings:IsMetric() then if Settings:IsMetric() then
if Language == "EN" then if Language == "EN" then
DistanceText = " for " .. UTILS.Round( Distance / 1000, 2 ) .. " km" DistanceText = " for " .. UTILS.Round( Distance / 1000, Precision ) .. " km"
elseif Language == "RU" then elseif Language == "RU" then
DistanceText = " за " .. UTILS.Round( Distance / 1000, 2 ) .. " километров" DistanceText = " за " .. UTILS.Round( Distance / 1000, Precision ) .. " километров"
end end
else else
if Language == "EN" then if Language == "EN" then
DistanceText = " for " .. UTILS.Round( UTILS.MetersToNM( Distance ), 2 ) .. " miles" DistanceText = " for " .. UTILS.Round( UTILS.MetersToNM( Distance ), Precision ) .. " miles"
elseif Language == "RU" then elseif Language == "RU" then
DistanceText = " за " .. UTILS.Round( UTILS.MetersToNM( Distance ), 2 ) .. " миль" DistanceText = " за " .. UTILS.Round( UTILS.MetersToNM( Distance ), Precision ) .. " миль"
end end
end end
@@ -1208,7 +1216,7 @@ do -- COORDINATE
local Settings = Settings or _SETTINGS -- Core.Settings#SETTINGS local Settings = Settings or _SETTINGS -- Core.Settings#SETTINGS
local BearingText = self:GetBearingText( AngleRadians, 0, Settings, Language ) local BearingText = self:GetBearingText( AngleRadians, 0, Settings, Language )
local DistanceText = self:GetDistanceText( Distance, Settings, Language ) local DistanceText = self:GetDistanceText( Distance, Settings, Language, 0 )
local BRText = BearingText .. DistanceText local BRText = BearingText .. DistanceText
@@ -1226,7 +1234,7 @@ do -- COORDINATE
local Settings = Settings or _SETTINGS -- Core.Settings#SETTINGS local Settings = Settings or _SETTINGS -- Core.Settings#SETTINGS
local BearingText = self:GetBearingText( AngleRadians, 0, Settings, Language ) local BearingText = self:GetBearingText( AngleRadians, 0, Settings, Language )
local DistanceText = self:GetDistanceText( Distance, Settings, Language ) local DistanceText = self:GetDistanceText( Distance, Settings, Language, 0 )
local AltitudeText = self:GetAltitudeText( Settings, Language ) local AltitudeText = self:GetAltitudeText( Settings, Language )
local BRAText = BearingText .. DistanceText .. AltitudeText -- When the POINT is a VEC2, there will be no altitude shown. local BRAText = BearingText .. DistanceText .. AltitudeText -- When the POINT is a VEC2, there will be no altitude shown.
@@ -2164,14 +2172,21 @@ do -- COORDINATE
if ReadOnly==nil then if ReadOnly==nil then
ReadOnly=false ReadOnly=false
end end
local vec3=self:GetVec3() local vec3=self:GetVec3()
Radius=Radius or 1000 Radius=Radius or 1000
Coalition=Coalition or -1 Coalition=Coalition or -1
Color=Color or {1,0,0} Color=Color or {1,0,0}
Color[4]=Alpha or 1.0 Color[4]=Alpha or 1.0
LineType=LineType or 1 LineType=LineType or 1
FillColor=FillColor or Color
FillColor=FillColor or UTILS.DeepCopy(Color)
FillColor[4]=FillAlpha or 0.15 FillColor[4]=FillAlpha or 0.15
trigger.action.circleToAll(Coalition, MarkID, vec3, Radius, Color, FillColor, LineType, ReadOnly, Text or "") trigger.action.circleToAll(Coalition, MarkID, vec3, Radius, Color, FillColor, LineType, ReadOnly, Text or "")
return MarkID return MarkID
end end
@@ -2196,13 +2211,19 @@ do -- COORDINATE
if ReadOnly==nil then if ReadOnly==nil then
ReadOnly=false ReadOnly=false
end end
local vec3=Endpoint:GetVec3() local vec3=Endpoint:GetVec3()
Coalition=Coalition or -1 Coalition=Coalition or -1
Color=Color or {1,0,0} Color=Color or {1,0,0}
Color[4]=Alpha or 1.0 Color[4]=Alpha or 1.0
LineType=LineType or 1 LineType=LineType or 1
FillColor=FillColor or Color
FillColor=FillColor or UTILS.DeepCopy(Color)
FillColor[4]=FillAlpha or 0.15 FillColor[4]=FillAlpha or 0.15
trigger.action.rectToAll(Coalition, MarkID, self:GetVec3(), vec3, Color, FillColor, LineType, ReadOnly, Text or "") trigger.action.rectToAll(Coalition, MarkID, self:GetVec3(), vec3, Color, FillColor, LineType, ReadOnly, Text or "")
return MarkID return MarkID
end end
@@ -2226,17 +2247,23 @@ do -- COORDINATE
if ReadOnly==nil then if ReadOnly==nil then
ReadOnly=false ReadOnly=false
end end
local point1=self:GetVec3() local point1=self:GetVec3()
local point2=Coord2:GetVec3() local point2=Coord2:GetVec3()
local point3=Coord3:GetVec3() local point3=Coord3:GetVec3()
local point4=Coord4:GetVec3() local point4=Coord4:GetVec3()
Coalition=Coalition or -1 Coalition=Coalition or -1
Color=Color or {1,0,0} Color=Color or {1,0,0}
Color[4]=Alpha or 1.0 Color[4]=Alpha or 1.0
LineType=LineType or 1 LineType=LineType or 1
FillColor=FillColor or Color
FillColor=FillColor or UTILS.DeepCopy(Color)
FillColor[4]=FillAlpha or 0.15 FillColor[4]=FillAlpha or 0.15
trigger.action.quadToAll(Coalition, MarkID, self:GetVec3(), point2, point3, point4, Color, FillColor, LineType, ReadOnly, Text or "")
trigger.action.quadToAll(Coalition, MarkID, point1, point2, point3, point4, Color, FillColor, LineType, ReadOnly, Text or "")
return MarkID return MarkID
end end
@@ -2320,11 +2347,15 @@ do -- COORDINATE
ReadOnly=false ReadOnly=false
end end
Coalition=Coalition or -1 Coalition=Coalition or -1
Color=Color or {1,0,0} Color=Color or {1,0,0}
Color[4]=Alpha or 1.0 Color[4]=Alpha or 1.0
FillColor=FillColor or Color
FillColor=FillColor or UTILS.DeepCopy(Color)
FillColor[4]=FillAlpha or 0.3 FillColor[4]=FillAlpha or 0.3
FontSize=FontSize or 14 FontSize=FontSize or 14
trigger.action.textToAll(Coalition, MarkID, self:GetVec3(), Color, FillColor, FontSize, ReadOnly, Text or "Hello World") trigger.action.textToAll(Coalition, MarkID, self:GetVec3(), Color, FillColor, FontSize, ReadOnly, Text or "Hello World")
return MarkID return MarkID
end end
@@ -2346,13 +2377,19 @@ do -- COORDINATE
if ReadOnly==nil then if ReadOnly==nil then
ReadOnly=false ReadOnly=false
end end
local vec3=Endpoint:GetVec3() local vec3=Endpoint:GetVec3()
Coalition=Coalition or -1 Coalition=Coalition or -1
Color=Color or {1,0,0} Color=Color or {1,0,0}
Color[4]=Alpha or 1.0 Color[4]=Alpha or 1.0
LineType=LineType or 1 LineType=LineType or 1
FillColor=FillColor or Color
FillColor=FillColor or UTILS.DeepCopy(Color)
FillColor[4]=FillAlpha or 0.15 FillColor[4]=FillAlpha or 0.15
--trigger.action.textToAll(Coalition, MarkID, self:GetVec3(), Color, FillColor, FontSize, ReadOnly, Text or "Hello World") --trigger.action.textToAll(Coalition, MarkID, self:GetVec3(), Color, FillColor, FontSize, ReadOnly, Text or "Hello World")
trigger.action.arrowToAll(Coalition, MarkID, vec3, self:GetVec3(), Color, FillColor, LineType, ReadOnly, Text or "") trigger.action.arrowToAll(Coalition, MarkID, vec3, self:GetVec3(), Color, FillColor, LineType, ReadOnly, Text or "")
return MarkID return MarkID
@@ -2728,6 +2765,52 @@ do -- COORDINATE
return "BRA, " .. self:GetBRAText( AngleRadians, Distance, Settings, Language ) return "BRA, " .. self:GetBRAText( AngleRadians, Distance, Settings, Language )
end end
--- Create a BRAA NATO call string to this COORDINATE from the FromCOORDINATE. Note - BRA delivered if no aspect can be obtained and "Merged" if range < 3nm
-- @param #COORDINATE self
-- @param #COORDINATE FromCoordinate The coordinate to measure the distance and the bearing from.
-- @param #boolean Bogey Add "Bogey" at the end if true (not yet declared hostile or friendly)
-- @param #boolean Spades Add "Spades" at the end if true (no IFF/VID ID yet known)
-- @return #string The BRAA text.
function COORDINATE:ToStringBRAANATO(FromCoordinate,Bogey,Spades)
-- Thanks to @Pikey
local BRAANATO = "Merged."
local currentCoord = FromCoordinate
local DirectionVec3 = FromCoordinate:GetDirectionVec3( self )
local AngleRadians = self:GetAngleRadians( DirectionVec3 )
local bearing = UTILS.Round( UTILS.ToDegree( AngleRadians ),0 )
local rangeMetres = self:Get2DDistance(currentCoord)
local rangeNM = UTILS.Round( UTILS.MetersToNM(rangeMetres), 0)
local aspect = self:ToStringAspect(currentCoord)
local alt = UTILS.Round(UTILS.MetersToFeet(self.y)/1000,0)--*1000
local track = UTILS.BearingToCardinal(bearing) or "North"
if rangeNM > 3 then
if aspect == "" then
BRAANATO = string.format("BRA, %03d, %d miles, Angels %d, Track %s",bearing, rangeNM, alt, track)
else
BRAANATO = string.format("BRAA, %03d, %d miles, Angels %d, %s, Track %s",bearing, rangeNM, alt, aspect, track)
end
if Bogey and Spades then
BRAANATO = BRAANATO..", Bogey, Spades."
elseif Bogey then
BRAANATO = BRAANATO..", Bogey."
elseif Spades then
BRAANATO = BRAANATO..", Spades."
else
BRAANATO = BRAANATO.."."
end
end
return BRAANATO
end
--- 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.
+7 -2
View File
@@ -201,7 +201,7 @@ do -- SET_BASE
self:F2( { ObjectName = ObjectName } ) self:F2( { ObjectName = ObjectName } )
local TriggerEvent = true local TriggerEvent = true
if NoTriggerEvent == false then if NoTriggerEvent then
TriggerEvent = false TriggerEvent = false
end end
@@ -1004,7 +1004,7 @@ do -- SET_GROUP
--- Gets the Set. --- Gets the Set.
-- @param #SET_GROUP self -- @param #SET_GROUP self
-- @return #SET_GROUP self -- @return #table Table of objects
function SET_GROUP:GetAliveSet() function SET_GROUP:GetAliveSet()
self:F2() self:F2()
@@ -1065,10 +1065,15 @@ do -- SET_GROUP
self:Add( group:GetName(), group ) self:Add( group:GetName(), group )
if not DontSetCargoBayLimit then
-- I set the default cargo bay weight limit each time a new group is added to the set. -- I set the default cargo bay weight limit each time a new group is added to the set.
-- TODO Why is this here in the first place?
for UnitID, UnitData in pairs( group:GetUnits() ) do for UnitID, UnitData in pairs( group:GetUnits() ) do
if UnitData and UnitData:IsAlive() then
UnitData:SetCargoBayWeightLimit() UnitData:SetCargoBayWeightLimit()
end end
end
end
return self return self
end end
+36 -14
View File
@@ -2827,18 +2827,37 @@ end
-- 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.
-- @param #SPAWN self -- @param #SPAWN self
-- @param DCS#UNIT DCSUnit The @{DCSUnit} to be searched. -- @param Wrapper.Group#GROUP SpawnGroup The GROUP object.
-- @return #string The prefix -- @return #string The prefix or #nil if nothing was found.
-- @return #nil Nothing found
function SPAWN:_GetPrefixFromGroup( SpawnGroup ) function SPAWN:_GetPrefixFromGroup( SpawnGroup )
self:F3( { self.SpawnTemplatePrefix, self.SpawnAliasPrefix, SpawnGroup } )
local GroupName = SpawnGroup:GetName() local GroupName = SpawnGroup:GetName()
if GroupName then if GroupName then
local SpawnPrefix = string.match( GroupName, ".*#" )
if SpawnPrefix then local SpawnPrefix=self:_GetPrefixFromGroupName(GroupName)
SpawnPrefix = SpawnPrefix:sub( 1, -2 )
return SpawnPrefix
end end
return nil
end
--- Return the prefix of a spawned group.
-- The method will search for a `#`-mark, and will return the text before the `#`-mark. It will return nil of no prefix was found.
-- @param #SPAWN self
-- @param #string SpawnGroupName The name of the spawned group.
-- @return #string The prefix or #nil if nothing was found.
function SPAWN:_GetPrefixFromGroupName(SpawnGroupName)
if SpawnGroupName then
local SpawnPrefix=string.match(SpawnGroupName, ".*#")
if SpawnPrefix then
SpawnPrefix = SpawnPrefix:sub(1, -2)
end
return SpawnPrefix return SpawnPrefix
end end
@@ -3235,24 +3254,27 @@ function SPAWN:_OnBirth( EventData )
end end
--- Obscolete
-- @todo Need to delete this... _DATABASE does this now ...
--- @param #SPAWN self --- @param #SPAWN self
-- @param Core.Event#EVENTDATA EventData -- @param Core.Event#EVENTDATA EventData
function SPAWN:_OnDeadOrCrash( EventData ) function SPAWN:_OnDeadOrCrash( EventData )
self:F( self.SpawnTemplatePrefix ) self:F( self.SpawnTemplatePrefix )
local SpawnGroup = EventData.IniGroup local unit=UNIT:FindByName(EventData.IniUnitName)
if unit then
local EventPrefix = self:_GetPrefixFromGroupName(unit.GroupName)
if SpawnGroup then
local EventPrefix = self:_GetPrefixFromGroup( SpawnGroup )
if EventPrefix then -- EventPrefix can be nil if no # is found, which means, no spawnable group! if EventPrefix then -- EventPrefix can be nil if no # is found, which means, no spawnable group!
self:T( { "Dead event: " .. EventPrefix } ) self:T( { "Dead event: " .. EventPrefix } )
if EventPrefix == self.SpawnTemplatePrefix or (self.SpawnAliasPrefix and EventPrefix == self.SpawnAliasPrefix) then
if EventPrefix == self.SpawnTemplatePrefix or ( self.SpawnAliasPrefix and EventPrefix == self.SpawnAliasPrefix ) then
self.AliveUnits = self.AliveUnits - 1 self.AliveUnits = self.AliveUnits - 1
self:T( "Alive Units: " .. self.AliveUnits ) self:T( "Alive Units: " .. self.AliveUnits )
end end
end end
end end
end end
+23 -12
View File
@@ -46,14 +46,14 @@
-- @field #number InitOffsetAngle Link offset angle in degrees. -- @field #number InitOffsetAngle Link offset angle in degrees.
-- @field #number InitStaticHeading Heading of the static. -- @field #number InitStaticHeading Heading of the static.
-- @field #string InitStaticLivery Livery for aircraft. -- @field #string InitStaticLivery Livery for aircraft.
-- @field #string InitStaticShape Shape of teh static. -- @field #string InitStaticShape Shape of the static.
-- @field #string InitStaticType Type of the static. -- @field #string InitStaticType Type of the static.
-- @field #string InitStaticCategory Categrory of the static. -- @field #string InitStaticCategory Categrory of the static.
-- @field #string InitStaticName Name of the static. -- @field #string InitStaticName Name of the static.
-- @field Core.Point#COORDINATE InitStaticCoordinate Coordinate where to spawn the static. -- @field Core.Point#COORDINATE InitStaticCoordinate Coordinate where to spawn the static.
-- @field #boolean InitDead Set static to be dead if true. -- @field #boolean InitStaticDead Set static to be dead if true.
-- @field #boolean InitCargo If true, static can act as cargo. -- @field #boolean InitStaticCargo If true, static can act as cargo.
-- @field #number InitCargoMass Mass of cargo in kg. -- @field #number InitStaticCargoMass Mass of cargo in kg.
-- @extends Core.Base#BASE -- @extends Core.Base#BASE
@@ -260,7 +260,7 @@ end
-- @param #number Mass Mass of the cargo in kg. -- @param #number Mass Mass of the cargo in kg.
-- @return #SPAWNSTATIC self -- @return #SPAWNSTATIC self
function SPAWNSTATIC:InitCargoMass(Mass) function SPAWNSTATIC:InitCargoMass(Mass)
self.InitCargoMass=Mass self.InitStaticCargoMass=Mass
return self return self
end end
@@ -269,7 +269,16 @@ end
-- @param #boolean IsCargo If true, this static can act as cargo. -- @param #boolean IsCargo If true, this static can act as cargo.
-- @return #SPAWNSTATIC self -- @return #SPAWNSTATIC self
function SPAWNSTATIC:InitCargo(IsCargo) function SPAWNSTATIC:InitCargo(IsCargo)
self.InitCargo=IsCargo self.InitStaticCargo=IsCargo
return self
end
--- Initialize as dead.
-- @param #SPAWNSTATIC self
-- @param #boolean IsCargo If true, this static is dead.
-- @return #SPAWNSTATIC self
function SPAWNSTATIC:InitDead(IsDead)
self.InitStaticDead=IsDead
return self return self
end end
@@ -417,16 +426,16 @@ function SPAWNSTATIC:_SpawnStatic(Template, CountryID)
Template.livery_id=self.InitStaticLivery Template.livery_id=self.InitStaticLivery
end end
if self.InitDead~=nil then if self.InitStaticDead~=nil then
Template.dead=self.InitDead Template.dead=self.InitStaticDead
end end
if self.InitCargo~=nil then if self.InitStaticCargo~=nil then
Template.canCargo=self.InitCargo Template.canCargo=self.InitStaticCargo
end end
if self.InitCargoMass~=nil then if self.InitStaticCargoMass~=nil then
Template.mass=self.InitCargoMass Template.mass=self.InitStaticCargoMass
end end
if self.InitLinkUnit then if self.InitLinkUnit then
@@ -479,6 +488,8 @@ function SPAWNSTATIC:_SpawnStatic(Template, CountryID)
-- ED's dirty way to spawn FARPS. -- ED's dirty way to spawn FARPS.
Static=coalition.addGroup(CountryID, -1, TemplateGroup) Static=coalition.addGroup(CountryID, -1, TemplateGroup)
else else
self:T("Spawning Static")
self:T2({Template=Template})
Static=coalition.addStaticObject(CountryID, Template) Static=coalition.addStaticObject(CountryID, Template)
end end
File diff suppressed because it is too large Load Diff
+3 -1
View File
@@ -487,8 +487,10 @@ do -- Object
-- @field UNIT -- @field UNIT
-- @field WEAPON -- @field WEAPON
-- @field STATIC -- @field STATIC
-- @field SCENERY
-- @field BASE -- @field BASE
-- @field SCENERY
-- @field CARGO
--- @type Object.Desc --- @type Object.Desc
-- @extends #Desc -- @extends #Desc
+3 -3
View File
@@ -2755,7 +2755,7 @@ 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
@@ -3004,7 +3004,7 @@ function RANGE:_CheckInZone( _unitName )
Straferesult.rangename = self.rangename Straferesult.rangename = self.rangename
-- Save trap sheet. -- Save trap sheet.
if playerData.targeton and self.targetsheet then if playerData and playerData.targeton and self.targetsheet then
self:_SaveTargetSheet( _playername, result ) self:_SaveTargetSheet( _playername, result )
end end
-- RangeBoss edit for strafe data saved to file -- RangeBoss edit for strafe data saved to file
@@ -3524,7 +3524,7 @@ function RANGE:_TargetsheetOnOff( _unitname )
playerData.targeton = not playerData.targeton playerData.targeton = not playerData.targeton
-- Inform player. -- Inform player.
if playerData.targeton == true then if playerData and playerData.targeton == true then
text = string.format( "roger, your targetsheets are now SAVED." ) text = string.format( "roger, your targetsheets are now SAVED." )
else else
text = string.format( "affirm, your targetsheets are NOT SAVED." ) text = string.format( "affirm, your targetsheets are NOT SAVED." )
+1
View File
@@ -4,6 +4,7 @@ __Moose.Include( 'Scripts/Moose/Utilities/Utils.lua' )
__Moose.Include( 'Scripts/Moose/Utilities/Profiler.lua' ) __Moose.Include( 'Scripts/Moose/Utilities/Profiler.lua' )
__Moose.Include( 'Scripts/Moose/Utilities/Templates.lua' ) __Moose.Include( 'Scripts/Moose/Utilities/Templates.lua' )
__Moose.Include( 'Scripts/Moose/Utilities/STTS.lua' ) __Moose.Include( 'Scripts/Moose/Utilities/STTS.lua' )
__Moose.Include( 'Scripts/Moose/Utilities/FiFo.lua' )
__Moose.Include( 'Scripts/Moose/Core/Base.lua' ) __Moose.Include( 'Scripts/Moose/Core/Base.lua' )
__Moose.Include( 'Scripts/Moose/Core/Beacon.lua' ) __Moose.Include( 'Scripts/Moose/Core/Beacon.lua' )
+210 -121
View File
@@ -32,9 +32,11 @@
-- * [USS George Washington](https://en.wikipedia.org/wiki/USS_George_Washington_(CVN-73)) (CVN-73) [Super Carrier Module] -- * [USS George Washington](https://en.wikipedia.org/wiki/USS_George_Washington_(CVN-73)) (CVN-73) [Super Carrier Module]
-- * [USS Harry S. Truman](https://en.wikipedia.org/wiki/USS_Harry_S._Truman) (CVN-75) [Super Carrier Module] -- * [USS Harry S. Truman](https://en.wikipedia.org/wiki/USS_Harry_S._Truman) (CVN-75) [Super Carrier Module]
-- * [USS Forrestal](https://en.wikipedia.org/wiki/USS_Forrestal_(CV-59)) (CV-59) [Heatblur Carrier Module] -- * [USS Forrestal](https://en.wikipedia.org/wiki/USS_Forrestal_(CV-59)) (CV-59) [Heatblur Carrier Module]
-- * [HMS Hermes](https://en.wikipedia.org/wiki/HMS_Hermes_(R12)) (R12) [**WIP**]
-- * [USS Tarawa](https://en.wikipedia.org/wiki/USS_Tarawa_(LHA-1)) (LHA-1) [**WIP**] -- * [USS Tarawa](https://en.wikipedia.org/wiki/USS_Tarawa_(LHA-1)) (LHA-1) [**WIP**]
-- * [USS America](https://en.wikipedia.org/wiki/USS_America_(LHA-6)) (LHA-6) [**WIP**] -- * [USS America](https://en.wikipedia.org/wiki/USS_America_(LHA-6)) (LHA-6) [**WIP**]
-- * [Juan Carlos I](https://en.wikipedia.org/wiki/Spanish_amphibious_assault_ship_Juan_Carlos_I) (L61) [**WIP**] -- * [Juan Carlos I](https://en.wikipedia.org/wiki/Spanish_amphibious_assault_ship_Juan_Carlos_I) (L61) [**WIP**]
-- * [HMAS Canberra](https://en.wikipedia.org/wiki/HMAS_Canberra_(L02)) (L02) [**WIP**]
-- --
-- **Supported Aircraft:** -- **Supported Aircraft:**
-- --
@@ -51,9 +53,9 @@
-- --
-- At the moment, optimized parameters are available for the F/A-18C Hornet (Lot 20) and A-4E community mod as aircraft and the USS John C. Stennis as carrier. -- At the moment, optimized parameters are available for the F/A-18C Hornet (Lot 20) and A-4E community mod as aircraft and the USS John C. Stennis as carrier.
-- --
-- The AV-8B Harrier, the USS Tarawa, USS America, HMAS Canberra and Juan Carlos I are WIP. The AV-8B harrier and the LHA's and LHD can only be used together, i.e. these ships are the only carriers the harrier is supposed to land on and -- The AV-8B Harrier, HMS Hermes, the USS Tarawa, USS America, HMAS Canberra, and Juan Carlos I are WIP. The AV-8B harrier and the LHA's and LHD can only be used together, i.e. these ships are the only carriers the harrier is supposed to land on and
-- no other fixed wing aircraft (human or AI controlled) are supposed to land on these ships. Currently only Case I is supported. Case II/III take slightly different steps from the CVN carrier. -- no other fixed wing aircraft (human or AI controlled) are supposed to land on these ships. Currently only Case I is supported. Case II/III take slightly different steps from the CVN carrier.
-- However, the two Case II/III pattern are very similar so this is not a big drawback. -- However, if no offset is used for the holding radial this provides a very close representation of the V/STOL Case III, allowing for an approach to over the deck and a vertical landing.
-- --
-- Heatblur's mighty F-14B Tomcat has been added (March 13th 2019) as well. Same goes for the A version. -- Heatblur's mighty F-14B Tomcat has been added (March 13th 2019) as well. Same goes for the A version.
-- --
@@ -113,10 +115,11 @@
-- * [Harrier Ship Landing Mission with Auto LSO!](https://www.youtube.com/watch?v=lqmVvpunk2c) -- * [Harrier Ship Landing Mission with Auto LSO!](https://www.youtube.com/watch?v=lqmVvpunk2c)
-- * [Updated Airboss V/STOL Features USS Tarawa](https://youtu.be/K7I4pU6j718) -- * [Updated Airboss V/STOL Features USS Tarawa](https://youtu.be/K7I4pU6j718)
-- * [Harrier Practice pattern USS America](https://youtu.be/99NigITYmcI) -- * [Harrier Practice pattern USS America](https://youtu.be/99NigITYmcI)
-- * [Harrier CASE III TACAN Approach USS Tarawa](https://www.youtube.com/watch?v=bTgJXZ9Mhdc&t=1s)
-- --
-- === -- ===
-- --
-- ### Author: **funkyfranky** -- ### Author: **funkyfranky** LHA and LHD V/STOL additions by **Pene**
-- ### Special Thanks To **Bankler** -- ### Special Thanks To **Bankler**
-- For his great [Recovery Trainer](https://forums.eagle.ru/showthread.php?t=221412) mission and script! -- For his great [Recovery Trainer](https://forums.eagle.ru/showthread.php?t=221412) mission and script!
-- His work was the initial inspiration for this class. Also note that this implementation uses some routines for determining the player position in Case I recoveries he developed. -- His work was the initial inspiration for this class. Also note that this implementation uses some routines for determining the player position in Case I recoveries he developed.
@@ -1260,7 +1263,7 @@ AIRBOSS = {
--- Aircraft types capable of landing on carrier (human+AI). --- Aircraft types capable of landing on carrier (human+AI).
-- @type AIRBOSS.AircraftCarrier -- @type AIRBOSS.AircraftCarrier
-- @field #string AV8B AV-8B Night Harrier. Works only with the USS Tarawa, USS America and Juan Carlos I. -- @field #string AV8B AV-8B Night Harrier. Works only with the HMS Hermes, USS Tarawa, USS America, and Juan Carlos I.
-- @field #string A4EC A-4E Community mod. -- @field #string A4EC A-4E Community mod.
-- @field #string HORNET F/A-18C Lot 20 Hornet by Eagle Dynamics. -- @field #string HORNET F/A-18C Lot 20 Hornet by Eagle Dynamics.
-- @field #string F14A F-14A by Heatblur. -- @field #string F14A F-14A by Heatblur.
@@ -1296,6 +1299,7 @@ AIRBOSS.AircraftCarrier={
-- @field #string TRUMAN USS Harry S. Truman (CVN-75) [Super Carrier Module] -- @field #string TRUMAN USS Harry S. Truman (CVN-75) [Super Carrier Module]
-- @field #string FORRESTAL USS Forrestal (CV-59) [Heatblur Carrier Module] -- @field #string FORRESTAL USS Forrestal (CV-59) [Heatblur Carrier Module]
-- @field #string VINSON USS Carl Vinson (CVN-70) [Obsolete] -- @field #string VINSON USS Carl Vinson (CVN-70) [Obsolete]
-- @field #string HERMES HMS Hermes (R12) [V/STOL Carrier]
-- @field #string TARAWA USS Tarawa (LHA-1) [V/STOL Carrier] -- @field #string TARAWA USS Tarawa (LHA-1) [V/STOL Carrier]
-- @field #string AMERICA USS America (LHA-6) [V/STOL Carrier] -- @field #string AMERICA USS America (LHA-6) [V/STOL Carrier]
-- @field #string JCARLOS Juan Carlos I (L61) [V/STOL Carrier] -- @field #string JCARLOS Juan Carlos I (L61) [V/STOL Carrier]
@@ -1309,6 +1313,7 @@ AIRBOSS.CarrierType = {
STENNIS = "Stennis", STENNIS = "Stennis",
FORRESTAL = "Forrestal", FORRESTAL = "Forrestal",
VINSON = "VINSON", VINSON = "VINSON",
HERMES = "HERMES81",
TARAWA = "LHA_Tarawa", TARAWA = "LHA_Tarawa",
AMERICA = "USS America LHA-6", AMERICA = "USS America LHA-6",
JCARLOS = "L61", JCARLOS = "L61",
@@ -1980,6 +1985,9 @@ function AIRBOSS:New( carriername, alias )
elseif self.carriertype == AIRBOSS.CarrierType.VINSON then elseif self.carriertype == AIRBOSS.CarrierType.VINSON then
-- TODO: Carl Vinson parameters. -- TODO: Carl Vinson parameters.
self:_InitStennis() self:_InitStennis()
elseif self.carriertype == AIRBOSS.CarrierType.HERMES then
-- Hermes parameters.
self:_InitHermes()
elseif self.carriertype == AIRBOSS.CarrierType.TARAWA then elseif self.carriertype == AIRBOSS.CarrierType.TARAWA then
-- Tarawa parameters. -- Tarawa parameters.
self:_InitTarawa() self:_InitTarawa()
@@ -2082,7 +2090,7 @@ function AIRBOSS:New( carriername, alias )
-- cL:FlareYellow() -- cL:FlareYellow()
-- Carrier specific. -- Carrier specific.
if self.carrier:GetTypeName() ~= AIRBOSS.CarrierType.TARAWA or self.carrier:GetTypeName() ~= AIRBOSS.CarrierType.AMERICA or self.carrier:GetTypeName() ~= AIRBOSS.CarrierType.JCARLOS or self.carrier:GetTypeName() ~= AIRBOSS.CarrierType.CANBERRA then if self.carrier:GetTypeName() ~= AIRBOSS.CarrierType.HERMES or self.carrier:GetTypeName() ~= AIRBOSS.CarrierType.TARAWA or self.carrier:GetTypeName() ~= AIRBOSS.CarrierType.AMERICA or self.carrier:GetTypeName() ~= AIRBOSS.CarrierType.JCARLOS or self.carrier:GetTypeName() ~= AIRBOSS.CarrierType.CANBERRA then
-- Flare wires. -- Flare wires.
local w1 = stern:Translate( self.carrierparam.wire1, FB, true ) local w1 = stern:Translate( self.carrierparam.wire1, FB, true )
@@ -2811,13 +2819,29 @@ end
-- @param #number Low -- @param #number Low
-- @param #number LOW -- @param #number LOW
-- @return #AIRBOSS self -- @return #AIRBOSS self
function AIRBOSS:SetGlideslopeErrorThresholds( _max, _min, High, HIGH, Low, LOW )
self.gle._max = _max or 0.4 function AIRBOSS:SetGlideslopeErrorThresholds(_max,_min, High, HIGH, Low, LOW)
self.gle.High = High or 0.8
self.gle.HIGH = HIGH or 1.5 --Check if V/STOL Carrier
self.gle._min = _min or -0.3 if self.carriertype == AIRBOSS.CarrierType.HERMES or self.carriertype == AIRBOSS.CarrierType.TARAWA or self.carriertype == AIRBOSS.CarrierType.AMERICA or self.carriertype == AIRBOSS.CarrierType.JCARLOS or self.carriertype == AIRBOSS.CarrierType.CANBERRA then
self.gle.Low = Low or -0.6
self.gle.LOW = LOW or -0.9 -- allow a larger GSE for V/STOL operations --Pene Testing
self.gle._max=_max or 0.7
self.gle.High=High or 1.4
self.gle.HIGH=HIGH or 1.9
self.gle._min=_min or -0.5
self.gle.Low=Low or -1.2
self.gle.LOW=LOW or -1.5
-- CVN values
else
self.gle._max=_max or 0.4
self.gle.High=High or 0.8
self.gle.HIGH=HIGH or 1.5
self.gle._min=_min or -0.3
self.gle.Low=Low or -0.6
self.gle.LOW=LOW or -0.9
end
return self return self
end end
@@ -2832,15 +2856,33 @@ end
-- @param #number RightMed -- @param #number RightMed
-- @param #number RIGHT -- @param #number RIGHT
-- @return #AIRBOSS self -- @return #AIRBOSS self
function AIRBOSS:SetLineupErrorThresholds( _max, _min, Left, LeftMed, LEFT, Right, RightMed, RIGHT )
self.lue._max = _max or 0.5 function AIRBOSS:SetLineupErrorThresholds(_max,_min, Left, LeftMed, LEFT, Right, RightMed, RIGHT)
self.lue._min = _min or -0.5
self.lue.Left = Left or -1.0 --Check if V/STOL Carrier -- Pene testing
self.lue.LeftMed = LeftMed or -2.0 if self.carriertype == AIRBOSS.CarrierType.HERMES or self.carriertype == AIRBOSS.CarrierType.TARAWA or self.carriertype == AIRBOSS.CarrierType.AMERICA or self.carriertype == AIRBOSS.CarrierType.JCARLOS or self.carriertype == AIRBOSS.CarrierType.CANBERRA then
self.lue.LEFT = LEFT or -3.0
self.lue.Right = Right or 1.0 -- V/STOL Values -- allow a larger LUE for V/STOL operations
self.lue.RightMed = RightMed or 2.0 self.lue._max=_max or 1.8
self.lue.RIGHT = RIGHT or 3.0 self.lue._min=_min or -1.8
self.lue.Left=Left or -2.8
self.lue.LeftMed=LeftMed or -3.8
self.lue.LEFT=LEFT or -4.5
self.lue.Right=Right or 2.8
self.lue.RightMed=RightMed or 3.8
self.lue.RIGHT=RIGHT or 4.5
-- CVN Values
else
self.lue._max=_max or 0.5
self.lue._min=_min or -0.5
self.lue.Left=Left or -1.0
self.lue.LeftMed=LeftMed or -2.0
self.lue.LEFT=LEFT or -3.0
self.lue.Right=Right or 1.0
self.lue.RightMed=RightMed or 2.0
self.lue.RIGHT=RIGHT or 3.0
end
return self return self
end end
@@ -4384,6 +4426,46 @@ function AIRBOSS:_InitForrestal()
end end
--- Init parameters for R12 HMS Hermes carrier.
-- @param #AIRBOSS self
function AIRBOSS:_InitHermes()
-- Init Stennis as default.
self:_InitStennis()
-- Carrier Parameters.
self.carrierparam.sterndist = -105
self.carrierparam.deckheight = 12 -- From model viewer WL0.
-- Total size of the carrier (approx as rectangle).
self.carrierparam.totlength = 228.19
self.carrierparam.totwidthport = 20.5
self.carrierparam.totwidthstarboard = 24.5
-- Landing runway.
self.carrierparam.rwyangle = 0
self.carrierparam.rwylength = 215
self.carrierparam.rwywidth = 13
-- Wires.
self.carrierparam.wire1 = nil
self.carrierparam.wire2 = nil
self.carrierparam.wire3 = nil
self.carrierparam.wire4 = nil
-- Late break.
self.BreakLate.name = "Late Break"
self.BreakLate.Xmin = -UTILS.NMToMeters( 1 ) -- Not more than 1 NM behind the boat. Last check was at 0.
self.BreakLate.Xmax = UTILS.NMToMeters( 5 ) -- Not more than 5 NM in front of the boat. Enough for late breaks?
self.BreakLate.Zmin = -UTILS.NMToMeters( 0.25 ) -- Not more than 0.25 NM port.
self.BreakLate.Zmax = UTILS.NMToMeters( 0.5 ) -- Not more than 0.5 NM starboard.
self.BreakLate.LimitXmin = 0 -- Check and next step 0.8 NM port and in front of boat.
self.BreakLate.LimitXmax = nil
self.BreakLate.LimitZmin = -UTILS.NMToMeters( 0.5 ) -- 926 m port, closer than the stennis as abeam is 0.8-1.0 rather than 1.2
self.BreakLate.LimitZmax = nil
end
--- Init parameters for LHA-1 Tarawa carrier. --- Init parameters for LHA-1 Tarawa carrier.
-- @param #AIRBOSS self -- @param #AIRBOSS self
function AIRBOSS:_InitTarawa() function AIRBOSS:_InitTarawa()
@@ -5007,14 +5089,16 @@ function AIRBOSS:_GetAircraftAoA( playerData )
aoa.Fast = 8.25 -- =17.5/2 aoa.Fast = 8.25 -- =17.5/2
aoa.FAST = 8.00 -- =16.5/2 aoa.FAST = 8.00 -- =16.5/2
elseif harrier then elseif harrier then
-- AV-8B Harrier parameters. Tuning done on the Fast AoA to allow for abeam and ninety at Nozzles 60 - 73.
aoa.SLOW = 14.0 -- AV-8B Harrier parameters. Tuning done on the Fast AoA to allow for abeam and ninety at Nozzles 55. Pene testing
aoa.Slow = 13.0 aoa.SLOW = 16.0
aoa.OnSpeedMax = 12.0 aoa.Slow = 13.5
aoa.OnSpeed = 11.0 aoa.OnSpeedMax = 12.5
aoa.OnSpeedMin = 10.0 aoa.OnSpeed = 10.0
aoa.OnSpeedMin = 9.5
aoa.Fast = 8.0 aoa.Fast = 8.0
aoa.FAST = 7.5 aoa.FAST = 7.5
end end
return aoa return aoa
@@ -5273,8 +5357,8 @@ function AIRBOSS:_GetAircraftParameters( playerData, step )
elseif skyhawk then elseif skyhawk then
alt = UTILS.FeetToMeters( 300 ) -- ? alt = UTILS.FeetToMeters( 300 ) -- ?
elseif harrier then elseif harrier then
-- 300-325 ft alt=UTILS.FeetToMeters(312)-- 300-325 ft
alt = UTILS.FeetToMeters( 300 ) -- Need to verify
end end
aoa = aoaac.OnSpeed aoa = aoaac.OnSpeed
@@ -6209,7 +6293,7 @@ function AIRBOSS:_GetMarshalAltitude( stack, case )
p2 = Carrier:Translate( UTILS.NMToMeters( 1.5 ), hdg ) p2 = Carrier:Translate( UTILS.NMToMeters( 1.5 ), hdg )
-- Tarawa,LHA,LHD Delta patterns. -- Tarawa,LHA,LHD Delta patterns.
if self.carriertype == AIRBOSS.CarrierType.TARAWA or self.carriertype == AIRBOSS.CarrierType.AMERICA or self.carriertype == AIRBOSS.CarrierType.JCARLOS or self.carriertype == AIRBOSS.CarrierType.CANBERRA then if self.carriertype == AIRBOSS.CarrierType.HERMES or self.carriertype == AIRBOSS.CarrierType.TARAWA or self.carriertype == AIRBOSS.CarrierType.AMERICA or self.carriertype == AIRBOSS.CarrierType.JCARLOS or self.carriertype == AIRBOSS.CarrierType.CANBERRA then
-- Pattern is directly overhead the carrier. -- Pattern is directly overhead the carrier.
p1 = Carrier:Translate( UTILS.NMToMeters( 1.0 ), hdg + 90 ) p1 = Carrier:Translate( UTILS.NMToMeters( 1.0 ), hdg + 90 )
@@ -8048,7 +8132,7 @@ function AIRBOSS:OnEventLand( EventData )
self:T( self.lid .. text ) self:T( self.lid .. text )
-- Check carrier type. -- Check carrier type.
if self.carriertype == AIRBOSS.CarrierType.TARAWA or self.carriertype == AIRBOSS.CarrierType.AMERICA or self.carriertype == AIRBOSS.CarrierType.JCARLOS or self.carriertype == AIRBOSS.CarrierType.CANBERRA then if self.carriertype == AIRBOSS.CarrierType.HERMES or self.carriertype == AIRBOSS.CarrierType.TARAWA or self.carriertype == AIRBOSS.CarrierType.AMERICA or self.carriertype == AIRBOSS.CarrierType.JCARLOS or self.carriertype == AIRBOSS.CarrierType.CANBERRA then
-- Power "Idle". -- Power "Idle".
self:RadioTransmission( self.LSORadio, self.LSOCall.IDLE, false, 1, nil, true ) self:RadioTransmission( self.LSORadio, self.LSOCall.IDLE, false, 1, nil, true )
@@ -8083,7 +8167,7 @@ function AIRBOSS:OnEventLand( EventData )
-- AI unit landed -- -- AI unit landed --
-------------------- --------------------
if self.carriertype ~= AIRBOSS.CarrierType.TARAWA or self.carriertype ~= AIRBOSS.CarrierType.AMERICA or self.carriertype ~= AIRBOSS.CarrierType.JCARLOS or self.carriertype ~= AIRBOSS.CarrierType.CANBERRA then if self.carriertype ~= AIRBOSS.CarrierType.HERMES or self.carriertype ~= AIRBOSS.CarrierType.TARAWA or self.carriertype ~= AIRBOSS.CarrierType.AMERICA or self.carriertype ~= AIRBOSS.CarrierType.JCARLOS or self.carriertype ~= AIRBOSS.CarrierType.CANBERRA then
-- Coordinate at landing event -- Coordinate at landing event
local coord = EventData.IniUnit:GetCoordinate() local coord = EventData.IniUnit:GetCoordinate()
@@ -9121,7 +9205,7 @@ function AIRBOSS:_CheckForLongDownwind( playerData )
local limit = UTILS.NMToMeters( -1.6 ) local limit = UTILS.NMToMeters( -1.6 )
-- For the tarawa, other LHA and LHD we give a bit more space. -- For the tarawa, other LHA and LHD we give a bit more space.
if self.carriertype == AIRBOSS.CarrierType.TARAWA or self.carriertype == AIRBOSS.CarrierType.AMERICA or self.carriertype == AIRBOSS.CarrierType.JCARLOS or self.carriertype == AIRBOSS.CarrierType.CANBERRA then if self.carriertype == AIRBOSS.CarrierType.HERMES or self.carriertype == AIRBOSS.CarrierType.TARAWA or self.carriertype == AIRBOSS.CarrierType.AMERICA or self.carriertype == AIRBOSS.CarrierType.JCARLOS or self.carriertype == AIRBOSS.CarrierType.CANBERRA then
limit = UTILS.NMToMeters( -2.0 ) limit = UTILS.NMToMeters( -2.0 )
end end
@@ -9208,7 +9292,7 @@ function AIRBOSS:_Ninety( playerData )
self:_PlayerHint( playerData ) self:_PlayerHint( playerData )
-- Next step: wake. -- Next step: wake.
if self.carriertype == AIRBOSS.CarrierType.TARAWA or self.carriertype == AIRBOSS.CarrierType.AMERICA or self.carriertype == AIRBOSS.CarrierType.JCARLOS or self.carriertype == AIRBOSS.CarrierType.CANBERRA then if self.carriertype == AIRBOSS.CarrierType.HERMES or self.carriertype == AIRBOSS.CarrierType.TARAWA or self.carriertype == AIRBOSS.CarrierType.AMERICA or self.carriertype == AIRBOSS.CarrierType.JCARLOS or self.carriertype == AIRBOSS.CarrierType.CANBERRA then
-- Harrier has no wake stop. It stays port of the boat. -- Harrier has no wake stop. It stays port of the boat.
self:_SetPlayerStep( playerData, AIRBOSS.PatternStep.FINAL ) self:_SetPlayerStep( playerData, AIRBOSS.PatternStep.FINAL )
else else
@@ -9464,8 +9548,9 @@ function AIRBOSS:_Groove( playerData )
-- Speed difference. -- Speed difference.
local dv = math.abs( vplayer - vcarrier ) local dv = math.abs( vplayer - vcarrier )
-- Stable when speed difference < 20 km/h.
local stable = dv < 20 -- Stable when speed difference < 30 km/h.(16 Kts)Pene Testing
local stable=dv<30
-- Check if player is inside the zone. -- Check if player is inside the zone.
if playerData.unit:IsInZone( ZoneALS ) and stable then if playerData.unit:IsInZone( ZoneALS ) and stable then
@@ -9497,8 +9582,8 @@ function AIRBOSS:_Groove( playerData )
-- Speed difference. -- Speed difference.
local dv = math.abs( vplayer - vcarrier ) local dv = math.abs( vplayer - vcarrier )
-- Stable when v<10 km/h. -- Stable when v<15 km/h.
local stable = dv < 10 local stable=dv<15
-- Radio Transmission "Stabilized" once the aircraft has been cleared to cross and is over the Landing Spot and stable. -- Radio Transmission "Stabilized" once the aircraft has been cleared to cross and is over the Landing Spot and stable.
if playerData.unit:IsInZone( ZoneLS ) and stable and playerData.stable == true then if playerData.unit:IsInZone( ZoneLS ) and stable and playerData.stable == true then
@@ -9537,25 +9622,26 @@ function AIRBOSS:_Groove( playerData )
-- Nothing else necessary. -- Nothing else necessary.
return return
end end
end end
-- Long V/STOL groove time Wave Off over 75 seconds to IC - TOPGUN level Only. --pene testing (WIP) -- Long V/STOL groove time Wave Off over 75 seconds to IC - TOPGUN level Only. --pene testing (WIP)--- Need to think more about this.
-- if rho>=RAR and rho<=RIC and not playerData.waveoff and playerData.difficulty==AIRBOSS.Difficulty.HARD and playerData.actype== AIRBOSS.AircraftCarrier.AV8B then --if rho>=RAR and rho<=RIC and not playerData.waveoff and playerData.difficulty==AIRBOSS.Difficulty.HARD and playerData.actype== AIRBOSS.AircraftCarrier.AV8B then
-- Get groove time -- Get groove time
-- local vSlow=groovedata.time --local vSlow=groovedata.time
-- If too slow wave off. -- If too slow wave off.
-- if vSlow >75 then --if vSlow >75 then
-- LSO Wave off! -- LSO Wave off!
-- self:RadioTransmission(self.LSORadio, self.LSOCall.WAVEOFF, nil, nil, nil, true) --self:RadioTransmission(self.LSORadio, self.LSOCall.WAVEOFF, nil, nil, nil, true)
-- playerData.Tlso=timer.getTime() --playerData.Tlso=timer.getTime()
-- Player was waved Off -- Player was waved Off
-- playerData.waveoff=true --playerData.waveoff=true
-- return --return
-- end --end
-- end --end
-- Groovedata step. -- Groovedata step.
groovedata.Step = playerData.step groovedata.Step = playerData.step
@@ -9726,8 +9812,8 @@ function AIRBOSS:_CheckWaveOff( glideslopeError, lineupError, AoA, playerData )
-- For the harrier, we allow a bit more room. -- For the harrier, we allow a bit more room.
if playerData.actype == AIRBOSS.AircraftCarrier.AV8B then if playerData.actype == AIRBOSS.AircraftCarrier.AV8B then
glMax = 2.6 glMax = 2.6
glMin = -2.0 glMin = -2.2 -- Testing, @Engines may be just dragging it in on Hermes, or the carrier parameters need adjusting.
luAbs = 4.1 -- Testing Pene (WIP) needs feedback to tighten up tolerences. luAbs = 4.1 -- Testing Pene.
end end
@@ -9893,17 +9979,23 @@ function AIRBOSS:_GetSternCoord()
local hdg = self.carrier:GetHeading() local hdg = self.carrier:GetHeading()
-- Final bearing (true). -- Final bearing (true).
local FB = self:GetFinalBearing() local FB=self:GetFinalBearing()
local case=self.case
-- Stern coordinate (sterndist<0). Also translate 10 meters starboard wrt Final bearing. -- Stern coordinate (sterndist<0). Also translate 10 meters starboard wrt Final bearing.
self.sterncoord:UpdateFromCoordinate( self:GetCoordinate() ) self.sterncoord:UpdateFromCoordinate( self:GetCoordinate() )
-- local stern=self:GetCoordinate() -- local stern=self:GetCoordinate()
-- Stern coordinate (sterndist<0). -- Stern coordinate (sterndist<0). --Pene testing Case III
if self.carriertype == AIRBOSS.CarrierType.TARAWA or self.carriertype == AIRBOSS.CarrierType.AMERICA or self.carriertype == AIRBOSS.CarrierType.JCARLOS or self.carriertype == AIRBOSS.CarrierType.CANBERRA then if self.carriertype==AIRBOSS.CarrierType.HERMES or self.carriertype==AIRBOSS.CarrierType.TARAWA or self.carriertype==AIRBOSS.CarrierType.AMERICA or self.carriertype==AIRBOSS.CarrierType.JCARLOS or self.carriertype==AIRBOSS.CarrierType.CANBERRA then
-- Tarawa: Translate 8 meters port. if case==3 then
self.sterncoord:Translate( self.carrierparam.sterndist, hdg, true, true ):Translate( 8, FB - 90, true, true ) -- CASE III V/STOL translation Due over deck approach if needed.
elseif self.carriertype == AIRBOSS.CarrierType.STENNIS then self.sterncoord:Translate(self.carrierparam.sterndist, hdg, true, true):Translate(8, FB-90, true, true)
elseif case==2 or case==1 then
-- V/Stol: Translate 8 meters port.
self.sterncoord:Translate(self.carrierparam.sterndist, hdg, true, true):Translate(8, FB-90, true, true)
end
elseif self.carriertype==AIRBOSS.CarrierType.STENNIS then
-- Stennis: translate 7 meters starboard wrt Final bearing. -- Stennis: translate 7 meters starboard wrt Final bearing.
self.sterncoord:Translate( self.carrierparam.sterndist, hdg, true, true ):Translate( 7, FB + 90, true, true ) self.sterncoord:Translate( self.carrierparam.sterndist, hdg, true, true ):Translate( 7, FB + 90, true, true )
elseif self.carriertype == AIRBOSS.CarrierType.FORRESTAL then elseif self.carriertype == AIRBOSS.CarrierType.FORRESTAL then
@@ -10536,7 +10628,8 @@ function AIRBOSS:_GetZoneRunwayBox()
return self.zoneRunwaybox return self.zoneRunwaybox
end end
--- Get zone of primary abeam landing position of USS Tarawa, USS America and Juan Carlos. Box length 50 meters and width 30 meters. --- Get zone of primary abeam landing position of HMS Hermes, USS Tarawa, USS America and Juan Carlos. Box length 50 meters and width 30 meters.
--- Allow for Clear to land call from LSO approaching abeam the landing spot if stable as per NATOPS 00-80T --- Allow for Clear to land call from LSO approaching abeam the landing spot if stable as per NATOPS 00-80T
-- @param #AIRBOSS self -- @param #AIRBOSS self
-- @return Core.Zone#ZONE_POLYGON Zone surrounding landing runway. -- @return Core.Zone#ZONE_POLYGON Zone surrounding landing runway.
@@ -10548,8 +10641,8 @@ function AIRBOSS:_GetZoneAbeamLandingSpot()
-- Current carrier heading. -- Current carrier heading.
local FB = self:GetFinalBearing( false ) local FB = self:GetFinalBearing( false )
-- Coordinate array. -- Coordinate array. Pene Testing extended Abeam landing spot V/STOL.
local p = {} local p={}
-- Points. -- Points.
p[1] = S:Translate( 15, FB ):Translate( 15, FB + 90 ) -- Top-Right p[1] = S:Translate( 15, FB ):Translate( 15, FB + 90 ) -- Top-Right
@@ -10640,7 +10733,7 @@ function AIRBOSS:_GetZoneHolding( case, stack )
self.zoneHolding = ZONE_RADIUS:New( "CASE I Holding Zone", Post:GetVec2(), self.marshalradius ) self.zoneHolding = ZONE_RADIUS:New( "CASE I Holding Zone", Post:GetVec2(), self.marshalradius )
-- Delta pattern. -- Delta pattern.
if self.carriertype == AIRBOSS.CarrierType.TARAWA or self.carriertype == AIRBOSS.CarrierType.AMERICA or self.carriertype == AIRBOSS.CarrierType.JCARLOS or self.carriertype == AIRBOSS.CarrierType.CANBERRA then if self.carriertype == AIRBOSS.CarrierType.HERMES or self.carriertype == AIRBOSS.CarrierType.TARAWA or self.carriertype == AIRBOSS.CarrierType.AMERICA or self.carriertype == AIRBOSS.CarrierType.JCARLOS or self.carriertype == AIRBOSS.CarrierType.CANBERRA then
self.zoneHolding = ZONE_RADIUS:New( "CASE I Holding Zone", self.carrier:GetVec2(), UTILS.NMToMeters( 5 ) ) self.zoneHolding = ZONE_RADIUS:New( "CASE I Holding Zone", self.carrier:GetVec2(), UTILS.NMToMeters( 5 ) )
end end
@@ -10692,7 +10785,7 @@ function AIRBOSS:_GetZoneCommence( case, stack )
-- Three position -- Three position
local Three = self:GetCoordinate():Translate( D, hdg + 275 ) local Three = self:GetCoordinate():Translate( D, hdg + 275 )
if self.carriertype == AIRBOSS.CarrierType.TARAWA or self.carriertype == AIRBOSS.CarrierType.AMERICA or self.carriertype == AIRBOSS.CarrierType.JCARLOS or self.carriertype == AIRBOSS.CarrierType.CANBERRA then if self.carriertype == AIRBOSS.CarrierType.HERMES or self.carriertype == AIRBOSS.CarrierType.TARAWA or self.carriertype == AIRBOSS.CarrierType.AMERICA or self.carriertype == AIRBOSS.CarrierType.JCARLOS or self.carriertype == AIRBOSS.CarrierType.CANBERRA then
local Dx = UTILS.NMToMeters( 2.25 ) local Dx = UTILS.NMToMeters( 2.25 )
@@ -10983,7 +11076,7 @@ function AIRBOSS:_GetAltCarrier( unit )
return h return h
end end
--- Get optimal landing position of the aircraft. Usually between second and third wire. In case of Tarawa and America we take the abeam landing spot 120 ft abeam the 7.5 position, for the Juan Carlos I it is 120 ft and abeam the 5 position. --- Get optimal landing position of the aircraft. Usually between second and third wire. In case of Tarawa, Canberrra, Juan Carlos and America we take the abeam landing spot 120 ft above and 21 ft abeam the 7.5 position, for the Juan Carlos I and HMS Hermes it is 120 ft above and 21 ft abeam the 5 position. For CASE III it is 120ft directly above the landing spot.
-- @param #AIRBOSS self -- @param #AIRBOSS self
-- @return Core.Point#COORDINATE Optimal landing coordinate. -- @return Core.Point#COORDINATE Optimal landing coordinate.
function AIRBOSS:_GetOptLandingCoordinate() function AIRBOSS:_GetOptLandingCoordinate()
@@ -10993,44 +11086,27 @@ function AIRBOSS:_GetOptLandingCoordinate()
-- Stern coordinate. -- Stern coordinate.
-- local stern=self:_GetSternCoord() -- local stern=self:_GetSternCoord()
-- Final bearing. -- Final bearing.
local FB = self:GetFinalBearing( false )
if self.carriertype == AIRBOSS.CarrierType.TARAWA then local FB=self:GetFinalBearing(false)
local case=self.case
-- set Case III V/STOL abeam landing spot over deck -- Pene Testing
if self.carriertype==AIRBOSS.CarrierType.HERMES or self.carriertype==AIRBOSS.CarrierType.TARAWA or self.carriertype==AIRBOSS.CarrierType.AMERICA or self.carriertype==AIRBOSS.CarrierType.JCARLOS or self.carriertype==AIRBOSS.CarrierType.CANBERRA then
if case==3 then
self.landingcoord:UpdateFromCoordinate(self:_GetLandingSpotCoordinate())
-- Altitude 120ft -- is this corect for Case III?
self.landingcoord:SetAltitude(UTILS.FeetToMeters(120))
elseif case==2 or case==1 then
-- Landing 100 ft abeam, 120 ft alt. -- Landing 100 ft abeam, 120 ft alt.
self.landingcoord:UpdateFromCoordinate( self:_GetLandingSpotCoordinate() ):Translate( 35, FB - 90, true, true ) self.landingcoord:UpdateFromCoordinate(self:_GetLandingSpotCoordinate()):Translate(35, FB-90, true, true)
-- stern=self:_GetLandingSpotCoordinate():Translate(35, FB-90) --stern=self:_GetLandingSpotCoordinate():Translate(35, FB-90)
-- Alitude 120 ft. -- Alitude 120 ft.
self.landingcoord:SetAltitude( UTILS.FeetToMeters( 120 ) ) self.landingcoord:SetAltitude(UTILS.FeetToMeters(120))
elseif self.carriertype == AIRBOSS.CarrierType.AMERICA then end
-- Landing 100 ft abeam, 120 ft alt. To allow adjustments to match different deck configurations.
self.landingcoord:UpdateFromCoordinate( self:_GetLandingSpotCoordinate() ):Translate( 35, FB - 90, true, true )
-- stern=self:_GetLandingSpotCoordinate():Translate(35, FB-90)
-- Alitude 120 ft.
self.landingcoord:SetAltitude( UTILS.FeetToMeters( 120 ) )
elseif self.carriertype == AIRBOSS.CarrierType.JCARLOS then
-- Landing 100 ft abeam, 120 ft alt.
self.landingcoord:UpdateFromCoordinate( self:_GetLandingSpotCoordinate() ):Translate( 35, FB - 90, true, true )
-- stern=self:_GetLandingSpotCoordinate():Translate(35, FB-90)
-- Alitude 120 ft.
self.landingcoord:SetAltitude( UTILS.FeetToMeters( 120 ) )
elseif self.carriertype == AIRBOSS.CarrierType.CANBERRA then
-- Landing 100 ft abeam, 120 ft alt.
self.landingcoord:UpdateFromCoordinate( self:_GetLandingSpotCoordinate() ):Translate( 35, FB - 90, true, true )
-- stern=self:_GetLandingSpotCoordinate():Translate(35, FB-90)
-- Alitude 120 ft.
self.landingcoord:SetAltitude( UTILS.FeetToMeters( 120 ) )
else else
@@ -11059,7 +11135,14 @@ function AIRBOSS:_GetLandingSpotCoordinate()
-- Stern coordinate. -- Stern coordinate.
-- local stern=self:_GetSternCoord() -- local stern=self:_GetSternCoord()
if self.carriertype == AIRBOSS.CarrierType.TARAWA then if self.carriertype==AIRBOSS.CarrierType.HERMES then
-- Landing 100 ft abeam, 100 alt.
local hdg = self:GetHeading()
-- Primary landing spot 5
self.landingspotcoord:Translate( 69, hdg, true, true ):SetAltitude( self.carrierparam.deckheight )
elseif self.carriertype == AIRBOSS.CarrierType.TARAWA then
-- Landing 100 ft abeam, 120 alt. -- Landing 100 ft abeam, 120 alt.
local hdg = self:GetHeading() local hdg = self:GetHeading()
@@ -11649,15 +11732,17 @@ function AIRBOSS:_LSOgrade( playerData )
local G = GXX .. " " .. GIM .. " " .. " " .. GIC .. " " .. GAR local G = GXX .. " " .. GIM .. " " .. " " .. GIC .. " " .. GAR
-- Count number of minor, normal and major deviations. -- Count number of minor, normal and major deviations.
local N = nXX + nIM + nIC + nAR local N=nXX+nIM+nIC+nAR
local nL = count( G, '_' ) / 2 local Nv=nXX+nIM
local nS = count( G, '%(' ) local nL=count(G, '_')/2
local nN = N - nS - nL local nS=count(G, '%(')
local nN=N-nS-nL
local nNv=Nv-nS-nL
-- Groove time 15-18.99 sec for a unicorn. Or 65-70 for V/STOL unicorn. -- Groove time 15-18.99 sec for a unicorn. Or 60-65 for V/STOL unicorn.
local Tgroove = playerData.Tgroove local Tgroove=playerData.Tgroove
local TgrooveUnicorn = Tgroove and (Tgroove >= 15.0 and Tgroove <= 18.99) or false local TgrooveUnicorn=Tgroove and (Tgroove>=15.0 and Tgroove<=18.99) or false
local TgrooveVstolUnicorn = Tgroove and (Tgroove >= 60.0 and Tgroove <= 65.0) and playerData.actype == AIRBOSS.AircraftCarrier.AV8B or false local TgrooveVstolUnicorn=Tgroove and (Tgroove>=60.0 and Tgroove<=65.0)and playerData.actype==AIRBOSS.AircraftCarrier.AV8B or false
local grade local grade
local points local points
@@ -11668,28 +11753,32 @@ function AIRBOSS:_LSOgrade( playerData )
G = "Unicorn" G = "Unicorn"
else else
-- Add AV-8B Harrier devation allowances due to lower groundspeed and 3x conventional groove time, this allows to maintain LSO tolerances while respecting the deviations are not unsafe. (WIP requires feedback) -- Add AV-8B Harrier devation allowances due to lower groundspeed and 3x conventional groove time, this allows to maintain LSO tolerances while respecting the deviations are not unsafe.--Pene testing
-- Large devaitions still result in a No Grade, A Unicorn still requires a clean pass with no deviation. -- Large devaitions still result in a No Grade, A Unicorn still requires a clean pass with no deviation.
if nL > 3 and playerData.actype == AIRBOSS.AircraftCarrier.AV8B then if nL > 1 and playerData.actype==AIRBOSS.AircraftCarrier.AV8B then
-- Larger deviations ==> "No grade" 2.0 points. -- Larger deviations ==> "No grade" 2.0 points.
grade = "--" grade="--"
points = 2.0 points=2.0
elseif nN > 2 and playerData.actype == AIRBOSS.AircraftCarrier.AV8B then elseif nNv >= 1 and playerData.actype==AIRBOSS.AircraftCarrier.AV8B then
-- Only average deviations ==> "Fair Pass" Pass with average deviations and corrections. -- Only average deviations ==> "Fair Pass" Pass with average deviations and corrections.
grade = "(OK)" grade="(OK)"
points = 3.0 points=3.0
elseif nNv < 1 and playerData.actype==AIRBOSS.AircraftCarrier.AV8B then
-- Only minor average deviations ==> "OK" Pass with minor deviations and corrections. (test nNv<=1 and)
grade="OK"
points=4.0
elseif nL > 0 then elseif nL > 0 then
-- Larger deviations ==> "No grade" 2.0 points. -- Larger deviations ==> "No grade" 2.0 points.
grade = "--" grade="--"
points = 2.0 points=2.0
elseif nN > 0 then elseif nN> 0 then
-- No larger but average deviations ==> "Fair Pass" Pass with average deviations and corrections. -- No larger but average deviations ==> "Fair Pass" Pass with average deviations and corrections.
grade = "(OK)" grade="(OK)"
points = 3.0 points=3.0
else else
-- Only minor corrections -- Only minor corrections
grade = "OK" grade="OK"
points = 4.0 points=4.0
end end
end end
@@ -11994,7 +12083,7 @@ function AIRBOSS:_GS( step, n )
if n == -1 then if n == -1 then
gp = AIRBOSS.GroovePos.IC gp = AIRBOSS.GroovePos.IC
elseif n == 1 then elseif n == 1 then
if self.carriertype == AIRBOSS.CarrierType.TARAWA or self.carriertype == AIRBOSS.CarrierType.AMERICA or self.carriertype == AIRBOSS.CarrierType.JCARLOS or self.carriertype == AIRBOSS.CarrierType.CANBERRA then if self.carriertype == AIRBOSS.CarrierType.HERMES or self.carriertype == AIRBOSS.CarrierType.TARAWA or self.carriertype == AIRBOSS.CarrierType.AMERICA or self.carriertype == AIRBOSS.CarrierType.JCARLOS or self.carriertype == AIRBOSS.CarrierType.CANBERRA then
gp = AIRBOSS.GroovePos.AL gp = AIRBOSS.GroovePos.AL
else else
gp = AIRBOSS.GroovePos.IW gp = AIRBOSS.GroovePos.IW
@@ -13873,7 +13962,7 @@ function AIRBOSS:_IsCarrierAircraft( unit )
-- Special case for Harrier which can only land on Tarawa, LHA and LHD. -- Special case for Harrier which can only land on Tarawa, LHA and LHD.
if aircrafttype == AIRBOSS.AircraftCarrier.AV8B then if aircrafttype == AIRBOSS.AircraftCarrier.AV8B then
if self.carriertype == AIRBOSS.CarrierType.TARAWA or self.carriertype == AIRBOSS.CarrierType.AMERICA or self.carriertype == AIRBOSS.CarrierType.JCARLOS or self.carriertype == AIRBOSS.CarrierType.CANBERRA then if self.carriertype == AIRBOSS.CarrierType.HERMES or self.carriertype == AIRBOSS.CarrierType.TARAWA or self.carriertype == AIRBOSS.CarrierType.AMERICA or self.carriertype == AIRBOSS.CarrierType.JCARLOS or self.carriertype == AIRBOSS.CarrierType.CANBERRA then
return true return true
else else
return false return false
@@ -13881,7 +13970,7 @@ function AIRBOSS:_IsCarrierAircraft( unit )
end end
-- Also only Harriers can land on the Tarawa, LHA and LHD. -- Also only Harriers can land on the Tarawa, LHA and LHD.
if self.carriertype == AIRBOSS.CarrierType.TARAWA or self.carriertype == AIRBOSS.CarrierType.AMERICA or self.carriertype == AIRBOSS.CarrierType.JCARLOS or self.carriertype == AIRBOSS.CarrierType.CANBERRA then if self.carriertype == AIRBOSS.CarrierType.HERMES or self.carriertype == AIRBOSS.CarrierType.TARAWA or self.carriertype == AIRBOSS.CarrierType.AMERICA or self.carriertype == AIRBOSS.CarrierType.JCARLOS or self.carriertype == AIRBOSS.CarrierType.CANBERRA then
if aircrafttype ~= AIRBOSS.AircraftCarrier.AV8B then if aircrafttype ~= AIRBOSS.AircraftCarrier.AV8B then
return false return false
end end
@@ -17238,7 +17327,7 @@ function AIRBOSS:_MarkCaseZones( _unitName, flare )
end end
-- Tarawa, LHA and LHD landing spots. -- Tarawa, LHA and LHD landing spots.
if self.carriertype == AIRBOSS.CarrierType.TARAWA or self.carriertype == AIRBOSS.CarrierType.AMERICA or self.carriertype == AIRBOSS.CarrierType.JCARLOS or self.carriertype == AIRBOSS.CarrierType.CANBERRA then if self.carriertype == AIRBOSS.CarrierType.HERMES or self.carriertype == AIRBOSS.CarrierType.TARAWA or self.carriertype == AIRBOSS.CarrierType.AMERICA or self.carriertype == AIRBOSS.CarrierType.JCARLOS or self.carriertype == AIRBOSS.CarrierType.CANBERRA then
text = text .. "\n* abeam landing stop with RED flares" text = text .. "\n* abeam landing stop with RED flares"
-- Abeam landing spot zone. -- Abeam landing spot zone.
local ALSPT = self:_GetZoneAbeamLandingSpot() local ALSPT = self:_GetZoneAbeamLandingSpot()
+5 -1
View File
@@ -124,6 +124,7 @@
-- 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.SRSport = 5002 -- and SRS port
-- -- -- --
-- self.csarUsePara = false -- If set to true, will use the LandingAfterEjection Event instead of Ejection --shagrat -- self.csarUsePara = false -- If set to true, will use the LandingAfterEjection Event instead of Ejection --shagrat
-- self.wetfeettemplate = "man in floating thingy" -- if you use a mod to have a pilot in a rescue float, put the template name in here for wet feet spawns. Note: in conjunction with csarUsePara this might create dual ejected pilots in edge cases. -- self.wetfeettemplate = "man in floating thingy" -- if you use a mod to have a pilot in a rescue float, put the template name in here for wet feet spawns. Note: in conjunction with csarUsePara this might create dual ejected pilots in edge cases.
@@ -255,10 +256,11 @@ CSAR.AircraftType["Mi-24P"] = 8
CSAR.AircraftType["Mi-24V"] = 8 CSAR.AircraftType["Mi-24V"] = 8
CSAR.AircraftType["Bell-47"] = 2 CSAR.AircraftType["Bell-47"] = 2
CSAR.AircraftType["UH-60L"] = 10 CSAR.AircraftType["UH-60L"] = 10
CSAR.AircraftType["AH-64D_BLK_II"] = 2
--- CSAR class version. --- CSAR class version.
-- @field #string version -- @field #string version
CSAR.version="1.0.4c" CSAR.version="1.0.4e"
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- ToDo list -- ToDo list
@@ -412,6 +414,7 @@ function CSAR:New(Coalition, Template, Alias)
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
self.SRSport = 5002 -- port
------------------------ ------------------------
--- Pseudo Functions --- --- Pseudo Functions ---
@@ -1522,6 +1525,7 @@ function CSAR:_DisplayMessageToSAR(_unit, _text, _time, _clear, _speak, _overrid
local modulation = self.SRSModulation local modulation = self.SRSModulation
local channel = self.SRSchannel local channel = self.SRSchannel
local msrs = MSRS:New(path,channel,modulation) local msrs = MSRS:New(path,channel,modulation)
msrs:SetPort(self.SRSport)
msrs:PlaySoundText(srstext, 2) msrs:PlaySoundText(srstext, 2)
end end
return self return self
+43 -10
View File
@@ -28,7 +28,7 @@ do
------------------------------------------------------ ------------------------------------------------------
--- **CTLD_ENGINEERING** class, extends Core.Base#BASE --- **CTLD_ENGINEERING** class, extends Core.Base#BASE
--- @type CTLD_ENGINEERING -- @type CTLD_ENGINEERING
-- @field #string ClassName -- @field #string ClassName
-- @field #string lid -- @field #string lid
-- @field #string Name -- @field #string Name
@@ -870,8 +870,12 @@ do
-- --
-- ## 5. Support for Hercules mod by Anubis -- ## 5. Support for Hercules mod by Anubis
-- --
-- Basic support for the Hercules mod By Anubis has been build into CTLD. Currently this does **not** cover objects and troops which can -- Basic support for the Hercules mod By Anubis has been build into CTLD - that is you can load/drop/build the same objects as the helicopters.
-- be loaded from the Rearm/Refuel menu, i.e. you can drop them into the field, but you cannot use them in functions scripted with this class. -- To also cover objects and troops which can be loaded from the groud crew Rearm/Refuel menu, you need to use @{#CTLD_HERCULES.New}() and link
-- this object to your CTLD setup. In this case, do **not** use the `Hercules_Cargo.lua` or `Hercules_Cargo_CTLD.lua` which are part of the mod
-- in your mission!
--
-- ### 5.1 Create an own CTLD instance and allow the usage of the Hercules mod:
-- --
-- local my_ctld = CTLD:New(coalition.side.BLUE,{"Helicargo", "Hercules"},"Lufttransportbrigade I") -- local my_ctld = CTLD:New(coalition.side.BLUE,{"Helicargo", "Hercules"},"Lufttransportbrigade I")
-- --
@@ -882,10 +886,33 @@ do
-- my_ctld.HercMaxAngels = 2000 -- for troop/cargo drop via chute in meters, ca 6000 ft -- my_ctld.HercMaxAngels = 2000 -- for troop/cargo drop via chute in meters, ca 6000 ft
-- my_ctld.HercMaxSpeed = 77 -- 77mps or 270kph or 150kn -- my_ctld.HercMaxSpeed = 77 -- 77mps or 270kph or 150kn
-- --
-- Hint: you can **only** airdrop from the Hercules if you are "in parameters", i.e. at or below `HercMaxSpeed` and in the AGL bracket between
-- `HercMinAngels` and `HercMaxAngels`!
--
-- Also, the following options need to be set to `true`: -- Also, the following options need to be set to `true`:
-- --
-- my_ctld.useprefix = true -- this is true by default and MUST BE ON. -- my_ctld.useprefix = true -- this is true by default and MUST BE ON.
-- --
-- ### 5.2 Integrate Hercules ground crew loadable objects
--
-- Add ground crew loadable objects to your CTLD instance like so, where `my_ctld` is the previously created CTLD instance:
--
-- local herccargo = CTLD_HERCULES:New("blue", "Hercules Test", my_ctld)
--
-- You also need:
--
-- * A template called "Infantry" for 10 Paratroopers (as set via herccargo.infantrytemplate).
-- * Depending on what you are loading with the help of the ground crew, there are 42 more templates for the various vehicles that are loadable.
--
-- There's a **quick check output in the `dcs.log`** which tells you what's there and what not.
-- E.g.:
-- ...Checking template for APC BTR-82A Air [24998lb] (BTR-82A) ... MISSING)
-- ...Checking template for ART 2S9 NONA Skid [19030lb] (SAU 2-C9) ... MISSING)
-- ...Checking template for EWR SBORKA Air [21624lb] (Dog Ear radar) ... MISSING)
-- ...Checking template for Transport Tigr Air [15900lb] (Tigr_233036) ... OK)
--
-- Expected template names are the ones in the rounded brackets.
--
-- Standard transport capabilities as per the real Hercules are: -- Standard transport capabilities as per the real Hercules are:
-- --
-- ["Hercules"] = {type="Hercules", crates=true, troops=true, cratelimit = 7, trooplimit = 64}, -- 19t cargo, 64 paratroopers -- ["Hercules"] = {type="Hercules", crates=true, troops=true, cratelimit = 7, trooplimit = 64}, -- 19t cargo, 64 paratroopers
@@ -924,7 +951,6 @@ CTLD = {
FreeUHFFrequencies = {}, -- Table of UHF FreeUHFFrequencies = {}, -- Table of UHF
FreeFMFrequencies = {}, -- Table of FM FreeFMFrequencies = {}, -- Table of FM
CargoCounter = 0, CargoCounter = 0,
wpZones = {},
Cargo_Troops = {}, -- generic troops objects Cargo_Troops = {}, -- generic troops objects
Cargo_Crates = {}, -- generic crate objects Cargo_Crates = {}, -- generic crate objects
Loaded_Cargo = {}, -- cargo aboard units Loaded_Cargo = {}, -- cargo aboard units
@@ -1017,6 +1043,7 @@ CTLD.UnitTypes = {
["Hercules"] = {type="Hercules", crates=true, troops=true, cratelimit = 7, trooplimit = 64, length = 25, cargoweightlimit = 19000}, -- 19t cargo, 64 paratroopers. ["Hercules"] = {type="Hercules", crates=true, troops=true, cratelimit = 7, trooplimit = 64, length = 25, cargoweightlimit = 19000}, -- 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.
["UH-60L"] = {type="UH-60L", crates=true, troops=true, cratelimit = 2, trooplimit = 20, length = 16, cargoweightlimit = 3500}, -- 4t cargo, 20 (unsec) seats ["UH-60L"] = {type="UH-60L", crates=true, troops=true, cratelimit = 2, trooplimit = 20, length = 16, cargoweightlimit = 3500}, -- 4t cargo, 20 (unsec) seats
["AH-64D_BLK_II"] = {type="AH-64D_BLK_II", crates=false, troops=true, cratelimit = 0, trooplimit = 2, length = 17, cargoweightlimit = 200}, -- 2 ppl **outside** the helo
} }
--- CTLD class version. --- CTLD class version.
@@ -1822,6 +1849,8 @@ function CTLD:_GetCrates(Group, Unit, Cargo, number, drop)
local drop = drop or false local drop = drop or false
local ship = nil local ship = nil
local width = 20 local width = 20
local distance = nil
local zone = nil
if not drop then if not drop then
inzone = self:IsUnitInZone(Unit,CTLD.CargoZoneType.LOAD) inzone = self:IsUnitInZone(Unit,CTLD.CargoZoneType.LOAD)
if not inzone then if not inzone then
@@ -2686,6 +2715,8 @@ function CTLD:_BuildCrates(Group, Unit,Engineering)
local required = Crate:GetCratesNeeded() local required = Crate:GetCratesNeeded()
local template = Crate:GetTemplates() local template = Crate:GetTemplates()
local ctype = Crate:GetType() local ctype = Crate:GetType()
local ccoord = Crate:GetPositionable():GetCoordinate() -- Core.Point#COORDINATE
--local testmarker = ccoord:MarkToAll("Crate found",true,"Build Position")
if not buildables[name] then if not buildables[name] then
local object = {} -- #CTLD.Buildable local object = {} -- #CTLD.Buildable
object.Name = name object.Name = name
@@ -2694,6 +2725,7 @@ function CTLD:_BuildCrates(Group, Unit,Engineering)
object.Template = template object.Template = template
object.CanBuild = false object.CanBuild = false
object.Type = ctype -- #CTLD_CARGO.Enum object.Type = ctype -- #CTLD_CARGO.Enum
object.Coord = ccoord:GetVec2()
buildables[name] = object buildables[name] = object
foundbuilds = true foundbuilds = true
else else
@@ -2855,7 +2887,8 @@ function CTLD:_BuildObjectFromCrates(Group,Unit,Build,Repair,RepairLocation)
temptable = {temptable} temptable = {temptable}
end end
local zone = ZONE_GROUP:New(string.format("Unload zone-%s",unitname),Group,100) local zone = ZONE_GROUP:New(string.format("Unload zone-%s",unitname),Group,100)
local randomcoord = zone:GetRandomCoordinate(35):GetVec2() --local randomcoord = zone:GetRandomCoordinate(35):GetVec2()
local randomcoord = Build.Coord or zone:GetRandomCoordinate(35):GetVec2()
if Repair then if Repair then
randomcoord = RepairLocation:GetVec2() randomcoord = RepairLocation:GetVec2()
end end
@@ -2864,7 +2897,7 @@ function CTLD:_BuildObjectFromCrates(Group,Unit,Build,Repair,RepairLocation)
local alias = string.format("%s-%d", _template, math.random(1,100000)) local alias = string.format("%s-%d", _template, math.random(1,100000))
if canmove then if canmove then
self.DroppedTroops[self.TroopCounter] = SPAWN:NewWithAlias(_template,alias) self.DroppedTroops[self.TroopCounter] = SPAWN:NewWithAlias(_template,alias)
:InitRandomizeUnits(true,20,2) --:InitRandomizeUnits(true,20,2)
:InitDelayOff() :InitDelayOff()
:SpawnFromVec2(randomcoord) :SpawnFromVec2(randomcoord)
else -- don't random position of e.g. SAM units build as FOB else -- don't random position of e.g. SAM units build as FOB
@@ -3786,8 +3819,8 @@ end
local ucoord = Unit:GetCoordinate() local ucoord = Unit:GetCoordinate()
local gheight = ucoord:GetLandHeight() local gheight = ucoord:GetLandHeight()
local aheight = uheight - gheight -- height above ground local aheight = uheight - gheight -- height above ground
local maxh = self.HercMinAngels-- 1500m local minh = self.HercMinAngels-- 1500m
local minh = self.HercMaxAngels -- 5000m local maxh = self.HercMaxAngels -- 5000m
local maxspeed = self.HercMaxSpeed -- 77 mps local maxspeed = self.HercMaxSpeed -- 77 mps
-- DONE: TEST - Speed test for Herc, should not be above 280kph/150kn -- DONE: TEST - Speed test for Herc, should not be above 280kph/150kn
local kmspeed = uspeed * 3.6 local kmspeed = uspeed * 3.6
@@ -3815,7 +3848,7 @@ end
else else
local minheight = UTILS.MetersToFeet(self.minimumHoverHeight) local minheight = UTILS.MetersToFeet(self.minimumHoverHeight)
local maxheight = UTILS.MetersToFeet(self.maximumHoverHeight) local maxheight = UTILS.MetersToFeet(self.maximumHoverHeight)
text = string.format("Hover parameters (autoload/drop):\n - Min height %dm \n - Max height %dm \n - Max speed 6fts \n - In parameter: %s", minheight, maxheight, htxt) text = string.format("Hover parameters (autoload/drop):\n - Min height %dft \n - Max height %dft \n - Max speed 6ftps \n - In parameter: %s", minheight, maxheight, htxt)
end end
self:_SendMessage(text, 10, false, Group) self:_SendMessage(text, 10, false, Group)
return self return self
@@ -5096,7 +5129,7 @@ function CTLD_HERCULES:Cargo_SpawnObjects(Cargo_Drop_initiator,Cargo_Drop_Direct
self:Soldier_SpawnGroup(Cargo_Drop_initiator,Cargo_Content_position, Cargo_Type_name, CargoHeading, Cargo_Country, 5) self:Soldier_SpawnGroup(Cargo_Drop_initiator,Cargo_Content_position, Cargo_Type_name, CargoHeading, Cargo_Country, 5)
self:Soldier_SpawnGroup(Cargo_Drop_initiator,Cargo_Content_position, Cargo_Type_name, CargoHeading, Cargo_Country, 10) self:Soldier_SpawnGroup(Cargo_Drop_initiator,Cargo_Content_position, Cargo_Type_name, CargoHeading, Cargo_Country, 10)
else else
self:Cargo_SpawnGroup(Cargo_Drop_initiator,Cargo_Content_position, Cargo_Type_name, CargoHeading, Cargo_Country, 0) self:Cargo_SpawnGroup(Cargo_Drop_initiator,Cargo_Content_position, Cargo_Type_name, CargoHeading, Cargo_Country)
end end
else else
if all_cargo_gets_destroyed == true or Cargo_over_water == true then if all_cargo_gets_destroyed == true or Cargo_over_water == true then
+33 -6
View File
@@ -45,6 +45,7 @@
-- @field Core.Point#COORDINATE coordinate Coordinate from where the transmission is send. -- @field Core.Point#COORDINATE coordinate Coordinate from where the transmission is send.
-- @field #string path Path to the SRS exe. This includes the final slash "/". -- @field #string path Path to the SRS exe. This includes the final slash "/".
-- @field #string google Full path google credentials JSON file, e.g. "C:\Users\username\Downloads\service-account-file.json". -- @field #string google Full path google credentials JSON file, e.g. "C:\Users\username\Downloads\service-account-file.json".
-- @field #string Label Label showing up on the SRS radio overlay. Default is "ROBOT". No spaces allowed.
-- @extends Core.Base#BASE -- @extends Core.Base#BASE
--- *It is a very sad thing that nowadays there is so little useless information.* - Oscar Wilde --- *It is a very sad thing that nowadays there is so little useless information.* - Oscar Wilde
@@ -106,6 +107,10 @@
-- --
-- Use @{#MSRS.SetCoordinate} to define the origin from where the transmission is broadcasted. -- Use @{#MSRS.SetCoordinate} to define the origin from where the transmission is broadcasted.
-- --
-- ## Set SRS Port
--
-- Use @{#MSRS.SetPort} to define the SRS port. Defaults to 5002.
--
-- @field #MSRS -- @field #MSRS
MSRS = { MSRS = {
ClassName = "MSRS", ClassName = "MSRS",
@@ -121,11 +126,12 @@ MSRS = {
volume = 1, volume = 1,
speed = 1, speed = 1,
coordinate = nil, coordinate = nil,
Label = "ROBOT",
} }
--- MSRS class version. --- MSRS class version.
-- @field #string version -- @field #string version
MSRS.version="0.0.3" MSRS.version="0.0.4"
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO list -- TODO list
@@ -160,6 +166,7 @@ function MSRS:New(PathToSRS, Frequency, Modulation)
self:SetModulations(Modulation) self:SetModulations(Modulation)
self:SetGender() self:SetGender()
self:SetCoalition() self:SetCoalition()
self:SetLabel()
return self return self
end end
@@ -202,12 +209,29 @@ function MSRS:GetPath()
return self.path return self.path
end end
--- Set label.
-- @param #MSRS self
-- @param #number Label. Default "ROBOT"
-- @return #MSRS self
function MSRS:SetLabel(Label)
self.Label=Label or "ROBOT"
return self
end
--- Get label.
-- @param #MSRS self
-- @return #number Label.
function MSRS:GetLabel()
return self.Label
end
--- Set port. --- Set port.
-- @param #MSRS self -- @param #MSRS self
-- @param #number Port Port. Default 5002. -- @param #number Port Port. Default 5002.
-- @return #MSRS self -- @return #MSRS self
function MSRS:SetPort(Port) function MSRS:SetPort(Port)
self.port=Port or 5002 self.port=Port or 5002
return self
end end
--- Get port. --- Get port.
@@ -223,6 +247,7 @@ end
-- @return #MSRS self -- @return #MSRS self
function MSRS:SetCoalition(Coalition) function MSRS:SetCoalition(Coalition)
self.coalition=Coalition or 0 self.coalition=Coalition or 0
return self
end end
--- Get coalition. --- Get coalition.
@@ -391,7 +416,7 @@ function MSRS:PlaySoundFile(Soundfile, Delay)
local command=self:_GetCommand() local command=self:_GetCommand()
-- Append file. -- Append file.
command=command.." --file="..tostring(soundfile) command=command..' --file="'..tostring(soundfile)..'"'
self:_ExecCommand(command) self:_ExecCommand(command)
@@ -634,8 +659,9 @@ end
-- @param #number volume Volume. -- @param #number volume Volume.
-- @param #number speed Speed. -- @param #number speed Speed.
-- @param #number port Port. -- @param #number port Port.
-- @param #string label Label, defaults to "ROBOT" (displayed sender name in the radio overlay of SRS) - No spaces allowed!
-- @return #string Command. -- @return #string Command.
function MSRS:_GetCommand(freqs, modus, coal, gender, voice, culture, volume, speed, port) function MSRS:_GetCommand(freqs, modus, coal, gender, voice, culture, volume, speed, port,label)
local path=self:GetPath() or STTS.DIRECTORY local path=self:GetPath() or STTS.DIRECTORY
local exe=STTS.EXECUTABLE or "DCS-SR-ExternalAudio.exe" local exe=STTS.EXECUTABLE or "DCS-SR-ExternalAudio.exe"
@@ -648,6 +674,7 @@ function MSRS:_GetCommand(freqs, modus, coal, gender, voice, culture, volume, sp
volume=volume or self.volume volume=volume or self.volume
speed=speed or self.speed speed=speed or self.speed
port=port or self.port port=port or self.port
label=label or self.Label
-- Replace modulation -- Replace modulation
modus=modus:gsub("0", "AM") modus=modus:gsub("0", "AM")
@@ -657,12 +684,12 @@ function MSRS:_GetCommand(freqs, modus, coal, gender, voice, culture, volume, sp
--local command=string.format("%s --freqs=%s --modulations=%s --coalition=%d --port=%d --volume=%.2f --speed=%d", exe, freqs, modus, coal, port, volume, speed) --local command=string.format("%s --freqs=%s --modulations=%s --coalition=%d --port=%d --volume=%.2f --speed=%d", exe, freqs, modus, coal, port, volume, speed)
-- Command from orig STTS script. Works better for some unknown reason! -- Command from orig STTS script. Works better for some unknown reason!
local command=string.format("start /min \"\" /d \"%s\" /b \"%s\" -f %s -m %s -c %s -p %s -n \"%s\" -h", path, exe, freqs, modus, coal, port, "ROBOT") --local command=string.format("start /min \"\" /d \"%s\" /b \"%s\" -f %s -m %s -c %s -p %s -n \"%s\" -h", path, exe, freqs, modus, coal, port, "ROBOT")
--local command=string.format('start /b "" /d "%s" "%s" -f %s -m %s -c %s -p %s -n "%s" > bla.txt', path, exe, freqs, modus, coal, port, "ROBOT") --local command=string.format('start /b "" /d "%s" "%s" -f %s -m %s -c %s -p %s -n "%s" > bla.txt', path, exe, freqs, modus, coal, port, "ROBOT")
-- Command. -- Command.
local command=string.format('%s/%s -f %s -m %s -c %s -p %s -n "%s"', path, exe, freqs, modus, coal, port, "ROBOT") local command=string.format('"%s\\%s" -f %s -m %s -c %s -p %s -n "%s"', path, exe, freqs, modus, coal, port, label)
-- Set voice or gender/culture. -- Set voice or gender/culture.
if voice then if voice then
@@ -671,7 +698,7 @@ function MSRS:_GetCommand(freqs, modus, coal, gender, voice, culture, volume, sp
else else
-- Add gender. -- Add gender.
if gender and gender~="female" then if gender and gender~="female" then
command=command..string.format(" --gender=%s", tostring(gender)) command=command..string.format(" -g %s", tostring(gender))
end end
-- Add culture. -- Add culture.
if culture and culture~="en-GB" then if culture and culture~="en-GB" then
@@ -183,13 +183,17 @@ do -- Sound File
--- Set path, where the sound file is located. --- Set path, where the sound file is located.
-- @param #SOUNDFILE self -- @param #SOUNDFILE self
-- @param #string Path Path to the directory, where the sound file is located. -- @param #string Path Path to the directory, where the sound file is located. In case this is nil, it defaults to the DCS mission temp directory.
-- @return #SOUNDFILE self -- @return #SOUNDFILE self
function SOUNDFILE:SetPath(Path) function SOUNDFILE:SetPath(Path)
-- Init path. -- Init path.
self.path=Path or "l10n/DEFAULT/" self.path=Path or "l10n/DEFAULT/"
if not Path and self.useSRS then -- use path to mission temp dir
self.path = os.getenv('TMP') .. "\\DCS\\Mission\\l10n\\DEFAULT"
end
-- Remove (back)slashes. -- Remove (back)slashes.
local nmax=1000 ; local n=1 local nmax=1000 ; local n=1
while (self.path:sub(-1)=="/" or self.path:sub(-1)==[[\]]) and n<=nmax do while (self.path:sub(-1)=="/" or self.path:sub(-1)==[[\]]) and n<=nmax do
+29 -7
View File
@@ -40,7 +40,7 @@ do -- UserSound
-- @param #USERSOUND self -- @param #USERSOUND self
-- @param #string UserSoundFileName The filename of the usersound. -- @param #string UserSoundFileName The filename of the usersound.
-- @return #USERSOUND -- @return #USERSOUND
function USERSOUND:New( UserSoundFileName ) --R2.3 function USERSOUND:New( UserSoundFileName )
local self = BASE:Inherit( self, BASE:New() ) -- #USERSOUND local self = BASE:Inherit( self, BASE:New() ) -- #USERSOUND
@@ -58,7 +58,7 @@ do -- UserSound
-- local BlueVictory = USERSOUND:New( "BlueVictory.ogg" ) -- local BlueVictory = USERSOUND:New( "BlueVictory.ogg" )
-- BlueVictory:SetFileName( "BlueVictoryLoud.ogg" ) -- Set the BlueVictory to change the file name to play a louder sound. -- BlueVictory:SetFileName( "BlueVictoryLoud.ogg" ) -- Set the BlueVictory to change the file name to play a louder sound.
-- --
function USERSOUND:SetFileName( UserSoundFileName ) --R2.3 function USERSOUND:SetFileName( UserSoundFileName )
self.UserSoundFileName = UserSoundFileName self.UserSoundFileName = UserSoundFileName
@@ -75,7 +75,7 @@ do -- UserSound
-- local BlueVictory = USERSOUND:New( "BlueVictory.ogg" ) -- local BlueVictory = USERSOUND:New( "BlueVictory.ogg" )
-- BlueVictory:ToAll() -- Play the sound that Blue has won. -- BlueVictory:ToAll() -- Play the sound that Blue has won.
-- --
function USERSOUND:ToAll() --R2.3 function USERSOUND:ToAll()
trigger.action.outSound( self.UserSoundFileName ) trigger.action.outSound( self.UserSoundFileName )
@@ -91,7 +91,7 @@ do -- UserSound
-- local BlueVictory = USERSOUND:New( "BlueVictory.ogg" ) -- local BlueVictory = USERSOUND:New( "BlueVictory.ogg" )
-- BlueVictory:ToCoalition( coalition.side.BLUE ) -- Play the sound that Blue has won to the blue coalition. -- BlueVictory:ToCoalition( coalition.side.BLUE ) -- Play the sound that Blue has won to the blue coalition.
-- --
function USERSOUND:ToCoalition( Coalition ) --R2.3 function USERSOUND:ToCoalition( Coalition )
trigger.action.outSoundForCoalition(Coalition, self.UserSoundFileName ) trigger.action.outSoundForCoalition(Coalition, self.UserSoundFileName )
@@ -107,7 +107,7 @@ do -- UserSound
-- local BlueVictory = USERSOUND:New( "BlueVictory.ogg" ) -- local BlueVictory = USERSOUND:New( "BlueVictory.ogg" )
-- BlueVictory:ToCountry( country.id.USA ) -- Play the sound that Blue has won to the USA country. -- BlueVictory:ToCountry( country.id.USA ) -- Play the sound that Blue has won to the USA country.
-- --
function USERSOUND:ToCountry( Country ) --R2.3 function USERSOUND:ToCountry( Country )
trigger.action.outSoundForCountry( Country, self.UserSoundFileName ) trigger.action.outSoundForCountry( Country, self.UserSoundFileName )
@@ -123,9 +123,9 @@ do -- UserSound
-- @usage -- @usage
-- local BlueVictory = USERSOUND:New( "BlueVictory.ogg" ) -- local BlueVictory = USERSOUND:New( "BlueVictory.ogg" )
-- local PlayerGroup = GROUP:FindByName( "PlayerGroup" ) -- Search for the active group named "PlayerGroup", that contains a human player. -- local PlayerGroup = GROUP:FindByName( "PlayerGroup" ) -- Search for the active group named "PlayerGroup", that contains a human player.
-- BlueVictory:ToGroup( PlayerGroup ) -- Play the sound that Blue has won to the player group. -- BlueVictory:ToGroup( PlayerGroup ) -- Play the victory sound to the player group.
-- --
function USERSOUND:ToGroup( Group, Delay ) --R2.3 function USERSOUND:ToGroup( Group, Delay )
Delay=Delay or 0 Delay=Delay or 0
if Delay>0 then if Delay>0 then
@@ -137,4 +137,26 @@ do -- UserSound
return self return self
end end
--- Play the usersound to the given @{Wrapper.Unit}.
-- @param #USERSOUND self
-- @param Wrapper.Unit#UNIT Unit The @{Wrapper.Unit} to play the usersound to.
-- @param #number Delay (Optional) Delay in seconds, before the sound is played. Default 0.
-- @return #USERSOUND The usersound instance.
-- @usage
-- local BlueVictory = USERSOUND:New( "BlueVictory.ogg" )
-- local PlayerUnit = UNIT:FindByName( "PlayerUnit" ) -- Search for the active group named "PlayerUnit", a human player.
-- BlueVictory:ToUnit( PlayerUnit ) -- Play the victory sound to the player unit.
--
function USERSOUND:ToUnit( Unit, Delay )
Delay=Delay or 0
if Delay>0 then
SCHEDULER:New(nil, USERSOUND.ToUnit,{self, Unit}, Delay)
else
trigger.action.outSoundForUnit( Unit:GetID(), self.UserSoundFileName )
end
return self
end
end end
+244 -45
View File
@@ -30,16 +30,16 @@ 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 tasking. -- @field #number OpenFire AI will engage only targets specified in its taskings.
-- @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 = {
WeaponFree = 0, WeaponFree=0,
OpenFireWeaponFree = 1, OpenFireWeaponFree=1,
OpenFire = 2, OpenFire=2,
ReturnFire = 3, ReturnFire=3,
WeaponHold = 4, WeaponHold=4,
} }
--- Reaction On Threat. --- Reaction On Threat.
-- @type ENUMS.ROT -- @type ENUMS.ROT
@@ -49,11 +49,11 @@ ENUMS.ROE = {
-- @field #number BypassAndEscape AI will attempt to avoid enemy threat zones all together. This includes attempting to fly above or around threats. -- @field #number BypassAndEscape AI will attempt to avoid enemy threat zones all together. This includes attempting to fly above or around threats.
-- @field #number AllowAbortMission If a threat is deemed severe enough the AI will abort its mission and return to base. -- @field #number AllowAbortMission If a threat is deemed severe enough the AI will abort its mission and return to base.
ENUMS.ROT = { ENUMS.ROT = {
NoReaction = 0, NoReaction=0,
PassiveDefense = 1, PassiveDefense=1,
EvadeFire = 2, EvadeFire=2,
BypassAndEscape = 3, BypassAndEscape=3,
AllowAbortMission = 4, AllowAbortMission=4,
} }
--- Alarm state. --- Alarm state.
@@ -62,12 +62,12 @@ ENUMS.ROT = {
-- @field #number Green Group is not combat ready. Sensors are stowed if possible. -- @field #number Green Group is not combat ready. Sensors are stowed if possible.
-- @field #number Red Group is combat ready and actively searching for targets. Some groups like infantry will not move in this state. -- @field #number Red Group is combat ready and actively searching for targets. Some groups like infantry will not move in this state.
ENUMS.AlarmState = { ENUMS.AlarmState = {
Auto = 0, Auto=0,
Green = 1, Green=1,
Red = 2, Red=2,
} }
--- Weapon types. See the [Weapon Flag](https://wiki.hoggitworld.com/view/DCS_enum_weapon_flag) enumerator on Hoggit wiki. --- Weapon types. See the [Weapon Flag](https://wiki.hoggitworld.com/view/DCS_enum_weapon_flag) enumerotor 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 + Dispenser + CandleBomb + ParachuteBomb) AnyUnguidedBomb = 2147485680, -- (HeBomb + Penetrator + NapalmBomb + FAEBomb + ClusterBomb + Dispencer + CandleBomb + ParachuteBomb)
AnyBomb = 2147485694, -- (GuidedBomb + AnyUnguidedBomb) AnyBomb = 2147485694, -- (GuidedBomb + AnyUnguidedBomb)
--- Rockets --- Rockets
AnyRocket = 30720, -- LightRocket + MarkerRocket + CandleRocket + HeavyRocket AnyRocket = 30720, -- LightRocket + MarkerRocket + CandleRocket + HeavyRocket
@@ -126,6 +126,8 @@ ENUMS.WeaponFlag={
AnyMissile = 268402688, -- AnyASM + AnyAAM AnyMissile = 268402688, -- AnyASM + AnyAAM
--- Guns --- Guns
Cannons = 805306368, -- GUN_POD + BuiltInCannon Cannons = 805306368, -- GUN_POD + BuiltInCannon
--- Torpedo
Torpedo = 4294967296,
--- ---
-- Even More Genral -- Even More Genral
Auto = 3221225470, -- Any Weapon (AnyBomb + AnyRocket + AnyMissile + Cannons) Auto = 3221225470, -- Any Weapon (AnyBomb + AnyRocket + AnyMissile + Cannons)
@@ -136,6 +138,93 @@ ENUMS.WeaponFlag={
AnyGuided = 268402702, -- Any Guided Weapon AnyGuided = 268402702, -- Any Guided Weapon
} }
--- Weapon types by category. See the [Weapon Flag](https://wiki.hoggitworld.com/view/DCS_enum_weapon_flag) enumerator on hoggit wiki.
-- @type ENUMS.WeaponType
-- @field #table Bomb Bombs.
-- @field #table Rocket Rocket.
-- @field #table Gun Guns.
-- @field #table Missile Missiles.
-- @field #table AAM Air-to-Air missiles.
-- @field #table Torpedo Torpedos.
-- @field #table Any Combinations.
ENUMS.WeaponType={}
ENUMS.WeaponType.Bomb={
-- Bombs
LGB = 2,
TvGB = 4,
SNSGB = 8,
HEBomb = 16,
Penetrator = 32,
NapalmBomb = 64,
FAEBomb = 128,
ClusterBomb = 256,
Dispencer = 512,
CandleBomb = 1024,
ParachuteBomb = 2147483648,
-- Combinations
GuidedBomb = 14, -- (LGB + TvGB + SNSGB)
AnyUnguidedBomb = 2147485680, -- (HeBomb + Penetrator + NapalmBomb + FAEBomb + ClusterBomb + Dispencer + CandleBomb + ParachuteBomb)
AnyBomb = 2147485694, -- (GuidedBomb + AnyUnguidedBomb)
}
ENUMS.WeaponType.Rocket={
-- Rockets
LightRocket = 2048,
MarkerRocket = 4096,
CandleRocket = 8192,
HeavyRocket = 16384,
-- Combinations
AnyRocket = 30720, -- LightRocket + MarkerRocket + CandleRocket + HeavyRocket
}
ENUMS.WeaponType.Gun={
-- Guns
GunPod = 268435456,
BuiltInCannon = 536870912,
-- Combinations
Cannons = 805306368, -- GUN_POD + BuiltInCannon
}
ENUMS.WeaponType.Missile={
-- Missiles
AntiRadarMissile = 32768,
AntiShipMissile = 65536,
AntiTankMissile = 131072,
FireAndForgetASM = 262144,
LaserASM = 524288,
TeleASM = 1048576,
CruiseMissile = 2097152,
AntiRadarMissile2 = 1073741824,
-- Combinations
GuidedASM = 1572864, -- (LaserASM + TeleASM)
TacticalASM = 1835008, -- (GuidedASM + FireAndForgetASM)
AnyASM = 4161536, -- (AntiRadarMissile + AntiShipMissile + AntiTankMissile + FireAndForgetASM + GuidedASM + CruiseMissile)
AnyASM2 = 1077903360, -- 4161536+1073741824,
AnyAutonomousMissile = 36012032, -- IR_AAM + AntiRadarMissile + AntiShipMissile + FireAndForgetASM + CruiseMissile
AnyMissile = 268402688, -- AnyASM + AnyAAM
}
ENUMS.WeaponType.AAM={
-- Air-To-Air Missiles
SRAM = 4194304,
MRAAM = 8388608,
LRAAM = 16777216,
IR_AAM = 33554432,
SAR_AAM = 67108864,
AR_AAM = 134217728,
-- Combinations
AnyAAM = 264241152, -- IR_AAM + SAR_AAM + AR_AAM + SRAAM + MRAAM + LRAAM
}
ENUMS.WeaponType.Torpedo={
-- Torpedo
Torpedo = 4294967296,
}
ENUMS.WeaponType.Any={
-- General combinations
Weapon = 3221225470, -- Any Weapon (AnyBomb + AnyRocket + AnyMissile + Cannons)
AG = 2956984318, -- Any Air-To-Ground Weapon
AA = 264241152, -- Any Air-To-Air Weapon
Unguided = 2952822768, -- Any Unguided Weapon
Guided = 268402702, -- Any Guided Weapon
}
--- Mission tasks. --- Mission tasks.
-- @type ENUMS.MissionTask -- @type ENUMS.MissionTask
-- @field #string NOTHING No special task. Group can perform the minimal tasks: Orbit, Refuelling, Follow and Aerobatics. -- @field #string NOTHING No special task. Group can perform the minimal tasks: Orbit, Refuelling, Follow and Aerobatics.
@@ -173,7 +262,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={}
@@ -216,23 +305,23 @@ ENUMS.Formation.FixedWing.FighterVic.Close = 917505
ENUMS.Formation.FixedWing.FighterVic.Open = 917506 ENUMS.Formation.FixedWing.FighterVic.Open = 917506
ENUMS.Formation.RotaryWing={} ENUMS.Formation.RotaryWing={}
ENUMS.Formation.RotaryWing.Column={} ENUMS.Formation.RotaryWing.Column={}
ENUMS.Formation.RotaryWing.Column.D70 = 720896 ENUMS.Formation.RotaryWing.Column.D70=720896
ENUMS.Formation.RotaryWing.Wedge={} ENUMS.Formation.RotaryWing.Wedge={}
ENUMS.Formation.RotaryWing.Wedge.D70 = 8 ENUMS.Formation.RotaryWing.Wedge.D70=8
ENUMS.Formation.RotaryWing.FrontRight={} ENUMS.Formation.RotaryWing.FrontRight={}
ENUMS.Formation.RotaryWing.FrontRight.D300 = 655361 ENUMS.Formation.RotaryWing.FrontRight.D300=655361
ENUMS.Formation.RotaryWing.FrontRight.D600 = 655362 ENUMS.Formation.RotaryWing.FrontRight.D600=655362
ENUMS.Formation.RotaryWing.FrontLeft={} ENUMS.Formation.RotaryWing.FrontLeft={}
ENUMS.Formation.RotaryWing.FrontLeft.D300 = 655617 ENUMS.Formation.RotaryWing.FrontLeft.D300=655617
ENUMS.Formation.RotaryWing.FrontLeft.D600 = 655618 ENUMS.Formation.RotaryWing.FrontLeft.D600=655618
ENUMS.Formation.RotaryWing.EchelonRight={} ENUMS.Formation.RotaryWing.EchelonRight={}
ENUMS.Formation.RotaryWing.EchelonRight.D70 = 589825 ENUMS.Formation.RotaryWing.EchelonRight.D70 =589825
ENUMS.Formation.RotaryWing.EchelonRight.D300 = 589826 ENUMS.Formation.RotaryWing.EchelonRight.D300=589826
ENUMS.Formation.RotaryWing.EchelonRight.D600 = 589827 ENUMS.Formation.RotaryWing.EchelonRight.D600=589827
ENUMS.Formation.RotaryWing.EchelonLeft={} ENUMS.Formation.RotaryWing.EchelonLeft={}
ENUMS.Formation.RotaryWing.EchelonLeft.D70 = 590081 ENUMS.Formation.RotaryWing.EchelonLeft.D70 =590081
ENUMS.Formation.RotaryWing.EchelonLeft.D300 = 590082 ENUMS.Formation.RotaryWing.EchelonLeft.D300=590082
ENUMS.Formation.RotaryWing.EchelonLeft.D600 = 590083 ENUMS.Formation.RotaryWing.EchelonLeft.D600=590083
ENUMS.Formation.Vehicle={} ENUMS.Formation.Vehicle={}
ENUMS.Formation.Vehicle.Vee="Vee" ENUMS.Formation.Vehicle.Vee="Vee"
ENUMS.Formation.Vehicle.EchelonRight="EchelonR" ENUMS.Formation.Vehicle.EchelonRight="EchelonR"
@@ -244,25 +333,25 @@ 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={}
ENUMS.FormationOld.FixedWing.LineAbreast = 1 ENUMS.FormationOld.FixedWing.LineAbreast=1
ENUMS.FormationOld.FixedWing.Trail = 2 ENUMS.FormationOld.FixedWing.Trail=2
ENUMS.FormationOld.FixedWing.Wedge = 3 ENUMS.FormationOld.FixedWing.Wedge=3
ENUMS.FormationOld.FixedWing.EchelonRight = 4 ENUMS.FormationOld.FixedWing.EchelonRight=4
ENUMS.FormationOld.FixedWing.EchelonLeft = 5 ENUMS.FormationOld.FixedWing.EchelonLeft=5
ENUMS.FormationOld.FixedWing.FingerFour = 6 ENUMS.FormationOld.FixedWing.FingerFour=6
ENUMS.FormationOld.FixedWing.SpreadFour = 7 ENUMS.FormationOld.FixedWing.SpreadFour=7
ENUMS.FormationOld.FixedWing.BomberElement = 12 ENUMS.FormationOld.FixedWing.BomberElement=12
ENUMS.FormationOld.FixedWing.BomberElementHeight = 13 ENUMS.FormationOld.FixedWing.BomberElementHeight=13
ENUMS.FormationOld.FixedWing.FighterVic = 14 ENUMS.FormationOld.FixedWing.FighterVic=14
ENUMS.FormationOld.RotaryWing={} ENUMS.FormationOld.RotaryWing={}
ENUMS.FormationOld.RotaryWing.Wedge = 8 ENUMS.FormationOld.RotaryWing.Wedge=8
ENUMS.FormationOld.RotaryWing.Echelon = 9 ENUMS.FormationOld.RotaryWing.Echelon=9
ENUMS.FormationOld.RotaryWing.Front = 10 ENUMS.FormationOld.RotaryWing.Front=10
ENUMS.FormationOld.RotaryWing.Column = 11 ENUMS.FormationOld.RotaryWing.Column=11
--- Morse Code. See the [Wikipedia](https://en.wikipedia.org/wiki/Morse_code). --- Morse Code. See the [Wikipedia](https://en.wikipedia.org/wiki/Morse_code).
@@ -360,3 +449,113 @@ ENUMS.Phonetic =
Y = 'Yankee', Y = 'Yankee',
Z = 'Zulu', Z = 'Zulu',
} }
--- Reporting Names (NATO). See the [Wikipedia](https://en.wikipedia.org/wiki/List_of_NATO_reporting_names_for_fighter_aircraft).
-- DCS known aircraft types
--
-- @type ENUMS.ReportingName
ENUMS.ReportingName =
{
NATO = {
-- Fighters
Dragon = "JF-17", -- China, correctly Fierce Dragon, Thunder for PAC
Fagot = "MiG-15",
Farmer = "MiG-19", -- Shenyang J-6 and Mikoyan-Gurevich MiG-19
Felon = "Su-57",
Fencer = "Su-24",
Fishbed = "MiG-21",
Fitter = "Su-17", -- Sukhoi Su-7 and Su-17/Su-20/Su-22
Flogger = "MiG-23", --and MiG-27
Flogger_D = "MiG-27", --and MiG-23
Flagon = "Su-15",
Foxbat = "MiG-25",
Fulcrum = "MiG-29",
Foxhound = "MiG-31",
Flanker = "Su-27", -- Sukhoi Su-27/Su-30/Su-33/Su-35/Su-37 and Shenyang J-11/J-15/J-16
Flanker_C = "Su-30",
Flanker_E = "Su-35",
Flanker_F = "Su-37",
Flanker_L = "J-11A",
Firebird = "J-10",
Sea_Flanker = "Su-33",
Fullback = "Su-34", -- also Su-32
Frogfoot = "Su-25",
Tomcat = "F-14", -- Iran
Mirage = "Mirage", -- various non-NATO
Codling = "Yak-40",
Maya = "L-39",
-- Fighters US/NATO
Warthog = "A-10",
--Mosquito = "A-20",
Skyhawk = "A-4E",
Viggen = "AJS37",
Harrier = "AV-8B",
Spirit = "B-2",
Aviojet = "C-101",
Nighthawk = "F-117A",
Eagle = "F-15C",
Mudhen = "F-15E",
Viper = "F-16",
Phantom = "F-4E",
Tiger = "F-5", -- was thinking to name this MiG-25 ;)
Sabre = "F-86",
Hornet = "A-18", -- avoiding the slash
Hawk = "Hawk",
Albatros = "L-39",
Goshawk = "T-45",
Starfighter = "F-104",
Tornado = "Tornado",
-- Transport / Bomber / Others
Atlas = "A400",
Lancer = "B1-B",
Stratofortress = "B-52H",
Hercules = "C-130",
Super_Hercules = "Hercules",
Globemaster = "C-17",
Greyhound = "C-2A",
Galaxy = "C-5",
Hawkeye = "E-2D",
Sentry = "E-3A",
Stratotanker = "KC-135",
Extender = "KC-10",
Orion = "P-3C",
Viking = "S-3B",
Osprey = "V-22",
-- Bomber Rus
Badger = "H6-J",
Bear_J = "Tu-142", -- also Tu-95
Bear = "Tu-95", -- also Tu-142
Blinder = "Tu-22",
Blackjack = "Tu-160",
-- AIC / Transport / Other
Clank = "An-30",
Curl = "An-26",
Candid = "IL-76",
Midas = "IL-78",
Mainstay = "A-50",
Mainring = "KJ-2000", -- A-50 China
Yak = "Yak-52",
-- Helos
Helix = "Ka-27",
Shark = "Ka-50",
Hind = "Mi-24",
Halo = "Mi-26",
Hip = "Mi-8",
Havoc = "Mi-28",
Gazelle = "SA342",
-- Helos US
Huey = "UH-1H",
Cobra = "AH-1",
Apache = "AH-64",
Chinook = "CH-47",
Sea_Stallion = "CH-53",
Kiowa = "OH-58",
Seahawk = "SH-60",
Blackhawk = "UH-60",
Sea_King = "S-61",
-- Drones
UCAV = "WingLoong",
Reaper = "MQ-9",
Predator = "MQ-1A",
}
}
+773
View File
@@ -0,0 +1,773 @@
--- **UTILS** - ClassicFiFo Stack.
--
-- ===
--
-- ## Main Features:
--
-- * Build a simple multi-purpose FiFo (First-In, First-Out) stack for generic data.
-- * [Wikipedia](https://en.wikipedia.org/wiki/FIFO_(computing_and_electronics)
--
-- ===
--
-- ### Author: **applevangelist**
-- @module Utils.FiFo
-- @image MOOSE.JPG
-- Date: April 2022
do
--- FIFO class.
-- @type FIFO
-- @field #string ClassName Name of the class.
-- @field #string lid Class id string for output to DCS log file.
-- @field #string version Version of FiFo
-- @field #number counter
-- @field #number pointer
-- @field #table stackbypointer
-- @field #table stackbyid
-- @extends Core.Base#BASE
---
-- @type FIFO.IDEntry
-- @field #number pointer
-- @field #table data
-- @field #table uniqueID
---
-- @field #FIFO
FIFO = {
ClassName = "FIFO",
lid = "",
version = "0.0.5",
counter = 0,
pointer = 0,
stackbypointer = {},
stackbyid = {}
}
--- Instantiate a new FIFO Stack
-- @param #FIFO self
-- @return #FIFO self
function FIFO:New()
-- Inherit everything from BASE class.
local self=BASE:Inherit(self, BASE:New())
self.pointer = 0
self.counter = 0
self.stackbypointer = {}
self.stackbyid = {}
self.uniquecounter = 0
-- Set some string id for output to DCS.log file.
self.lid=string.format("%s (%s) | ", "FiFo", self.version)
self:T(self.lid .."Created.")
return self
end
--- Empty FIFO Stack
-- @param #FIFO self
-- @return #FIFO self
function FIFO:Clear()
self:T(self.lid.."Clear")
self.pointer = 0
self.counter = 0
self.stackbypointer = nil
self.stackbyid = nil
self.stackbypointer = {}
self.stackbyid = {}
self.uniquecounter = 0
return self
end
--- FIFO Push Object to Stack
-- @param #FIFO self
-- @param #table Object
-- @param #string UniqueID (optional) - will default to current pointer + 1. Note - if you intend to use `FIFO:GetIDStackSorted()` keep the UniqueID numerical!
-- @return #FIFO self
function FIFO:Push(Object,UniqueID)
self:T(self.lid.."Push")
self:T({Object,UniqueID})
self.pointer = self.pointer + 1
self.counter = self.counter + 1
local uniID = UniqueID
if not UniqueID then
self.uniquecounter = self.uniquecounter + 1
uniID = self.uniquecounter
end
self.stackbyid[uniID] = { pointer = self.pointer, data = Object, uniqueID = uniID }
self.stackbypointer[self.pointer] = { pointer = self.pointer, data = Object, uniqueID = uniID }
return self
end
--- FIFO Pull Object from Stack
-- @param #FIFO self
-- @return #table Object or nil if stack is empty
function FIFO:Pull()
self:T(self.lid.."Pull")
if self.counter == 0 then return nil end
--local object = self.stackbypointer[self.pointer].data
--self.stackbypointer[self.pointer] = nil
local object = self.stackbypointer[1].data
self.stackbypointer[1] = nil
self.counter = self.counter - 1
--self.pointer = self.pointer - 1
self:Flatten()
return object
end
--- FIFO Pull Object from Stack by Pointer
-- @param #FIFO self
-- @param #number Pointer
-- @return #table Object or nil if stack is empty
function FIFO:PullByPointer(Pointer)
self:T(self.lid.."PullByPointer " .. tostring(Pointer))
if self.counter == 0 then return nil end
local object = self.stackbypointer[Pointer] -- #FIFO.IDEntry
self.stackbypointer[Pointer] = nil
if object then self.stackbyid[object.uniqueID] = nil end
self.counter = self.counter - 1
self:Flatten()
if object then
return object.data
else
return nil
end
end
--- FIFO Read, not Pull, Object from Stack by Pointer
-- @param #FIFO self
-- @param #number Pointer
-- @return #table Object or nil if stack is empty or pointer does not exist
function FIFO:ReadByPointer(Pointer)
self:T(self.lid.."ReadByPointer " .. tostring(Pointer))
if self.counter == 0 or not Pointer or not self.stackbypointer[Pointer] then return nil end
local object = self.stackbypointer[Pointer] -- #FIFO.IDEntry
if object then
return object.data
else
return nil
end
end
--- FIFO Read, not Pull, Object from Stack by UniqueID
-- @param #FIFO self
-- @param #number UniqueID
-- @return #table Object data or nil if stack is empty or ID does not exist
function FIFO:ReadByID(UniqueID)
self:T(self.lid.."ReadByID " .. tostring(UniqueID))
if self.counter == 0 or not UniqueID or not self.stackbyid[UniqueID] then return nil end
local object = self.stackbyid[UniqueID] -- #FIFO.IDEntry
if object then
return object.data
else
return nil
end
end
--- FIFO Pull Object from Stack by UniqueID
-- @param #FIFO self
-- @param #tableUniqueID
-- @return #table Object or nil if stack is empty
function FIFO:PullByID(UniqueID)
self:T(self.lid.."PullByID " .. tostring(UniqueID))
if self.counter == 0 then return nil end
local object = self.stackbyid[UniqueID] -- #FIFO.IDEntry
--self.stackbyid[UniqueID] = nil
if object then
return self:PullByPointer(object.pointer)
else
return nil
end
end
--- FIFO Housekeeping
-- @param #FIFO self
-- @return #FIFO self
function FIFO:Flatten()
self:T(self.lid.."Flatten")
-- rebuild stacks
local pointerstack = {}
local idstack = {}
local counter = 0
for _ID,_entry in pairs(self.stackbypointer) do
counter = counter + 1
pointerstack[counter] = { pointer = counter, data = _entry.data, uniqueID = _entry.uniqueID}
end
for _ID,_entry in pairs(pointerstack) do
idstack[_entry.uniqueID] = { pointer = _entry.pointer , data = _entry.data, uniqueID = _entry.uniqueID}
end
self.stackbypointer = nil
self.stackbypointer = pointerstack
self.stackbyid = nil
self.stackbyid = idstack
self.counter = counter
self.pointer = counter
return self
end
--- FIFO Check Stack is empty
-- @param #FIFO self
-- @return #boolean empty
function FIFO:IsEmpty()
self:T(self.lid.."IsEmpty")
return self.counter == 0 and true or false
end
--- FIFO Get stack size
-- @param #FIFO self
-- @return #number size
function FIFO:GetSize()
self:T(self.lid.."GetSize")
return self.counter
end
--- FIFO Get stack size
-- @param #FIFO self
-- @return #number size
function FIFO:Count()
self:T(self.lid.."Count")
return self.counter
end
--- FIFO Check Stack is NOT empty
-- @param #FIFO self
-- @return #boolean notempty
function FIFO:IsNotEmpty()
self:T(self.lid.."IsNotEmpty")
return not self:IsEmpty()
end
--- FIFO Get the data stack by pointer
-- @param #FIFO self
-- @return #table Table of #FIFO.IDEntry entries
function FIFO:GetPointerStack()
self:T(self.lid.."GetPointerStack")
return self.stackbypointer
end
--- FIFO Check if a certain UniqeID exists
-- @param #FIFO self
-- @return #boolean exists
function FIFO:HasUniqueID(UniqueID)
self:T(self.lid.."HasUniqueID")
if self.stackbyid[UniqueID] ~= nil then
return true
else
return false
end
end
--- FIFO Get the data stack by UniqueID
-- @param #FIFO self
-- @return #table Table of #FIFO.IDEntry entries
function FIFO:GetIDStack()
self:T(self.lid.."GetIDStack")
return self.stackbyid
end
--- FIFO Get table of UniqueIDs sorted smallest to largest
-- @param #FIFO self
-- @return #table Table with index [1] to [n] of UniqueID entries
function FIFO:GetIDStackSorted()
self:T(self.lid.."GetIDStackSorted")
local stack = self:GetIDStack()
local idstack = {}
for _id,_entry in pairs(stack) do
idstack[#idstack+1] = _id
self:T({"pre",_id})
end
local function sortID(a, b)
return a < b
end
table.sort(idstack)
return idstack
end
--- FIFO Get table of data entries
-- @param #FIFO self
-- @return #table Raw table indexed [1] to [n] of object entries - might be empty!
function FIFO:GetDataTable()
self:T(self.lid.."GetDataTable")
local datatable = {}
for _,_entry in pairs(self.stackbypointer) do
datatable[#datatable+1] = _entry.data
end
return datatable
end
--- FIFO Get sorted table of data entries by UniqueIDs (must be numerical UniqueIDs only!)
-- @param #FIFO self
-- @return #table Table indexed [1] to [n] of sorted object entries - might be empty!
function FIFO:GetSortedDataTable()
self:T(self.lid.."GetSortedDataTable")
local datatable = {}
local idtablesorted = self:GetIDStackSorted()
for _,_entry in pairs(idtablesorted) do
datatable[#datatable+1] = self:ReadByID(_entry)
end
return datatable
end
--- Iterate the FIFO and call an iterator function for the given FIFO data, providing the object for each element of the stack and optional parameters.
-- @param #FIFO self
-- @param #function IteratorFunction The function that will be called.
-- @param #table Arg (Optional) Further Arguments of the IteratorFunction.
-- @param #function Function (Optional) A function returning a #boolean true/false. Only if true, the IteratorFunction is called.
-- @param #table FunctionArguments (Optional) Function arguments.
-- @return #FIFO self
function FIFO:ForEach( IteratorFunction, Arg, Function, FunctionArguments )
self:T(self.lid.."ForEach")
local Set = self:GetPointerStack() or {}
Arg = Arg or {}
local function CoRoutine()
local Count = 0
for ObjectID, ObjectData in pairs( Set ) do
local Object = ObjectData.data
self:T( {Object} )
if Function then
if Function( unpack( FunctionArguments or {} ), Object ) == true then
IteratorFunction( Object, unpack( Arg ) )
end
else
IteratorFunction( Object, unpack( Arg ) )
end
Count = Count + 1
end
return true
end
local co = CoRoutine
local function Schedule()
local status, res = co()
self:T( { status, res } )
if status == false then
error( res )
end
if res == false then
return true -- resume next time the loop
end
return false
end
Schedule()
return self
end
--- FIFO Print stacks to dcs.log
-- @param #FIFO self
-- @return #FIFO self
function FIFO:Flush()
self:T(self.lid.."FiFo Flush")
self:I("FIFO Flushing Stack by Pointer")
for _id,_data in pairs (self.stackbypointer) do
local data = _data -- #FIFO.IDEntry
self:I(string.format("Pointer: %s | Entry: Number = %s Data = %s UniqueID = %s",tostring(_id),tostring(data.pointer),tostring(data.data),tostring(data.uniqueID)))
end
self:I("FIFO Flushing Stack by ID")
for _id,_data in pairs (self.stackbyid) do
local data = _data -- #FIFO.IDEntry
self:I(string.format("ID: %s | Entry: Number = %s Data = %s UniqueID = %s",tostring(_id),tostring(data.pointer),tostring(data.data),tostring(data.uniqueID)))
end
self:I("Counter = " .. self.counter)
self:I("Pointer = ".. self.pointer)
return self
end
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- End FIFO
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
end
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- LIFO
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
do
--- **UTILS** - LiFo Stack.
--
-- **Main Features:**
--
-- * Build a simple multi-purpose LiFo (Last-In, First-Out) stack for generic data.
--
-- ===
--
-- ### Author: **applevangelist**
--- LIFO class.
-- @type LIFO
-- @field #string ClassName Name of the class.
-- @field #string lid Class id string for output to DCS log file.
-- @field #string version Version of LiFo
-- @field #number counter
-- @field #number pointer
-- @field #table stackbypointer
-- @field #table stackbyid
-- @extends Core.Base#BASE
---
-- @type LIFO.IDEntry
-- @field #number pointer
-- @field #table data
-- @field #table uniqueID
---
-- @field #LIFO
LIFO = {
ClassName = "LIFO",
lid = "",
version = "0.0.5",
counter = 0,
pointer = 0,
stackbypointer = {},
stackbyid = {}
}
--- Instantiate a new LIFO Stack
-- @param #LIFO self
-- @return #LIFO self
function LIFO:New()
-- Inherit everything from BASE class.
local self=BASE:Inherit(self, BASE:New())
self.pointer = 0
self.counter = 0
self.uniquecounter = 0
self.stackbypointer = {}
self.stackbyid = {}
-- Set some string id for output to DCS.log file.
self.lid=string.format("%s (%s) | ", "LiFo", self.version)
self:T(self.lid .."Created.")
return self
end
--- Empty LIFO Stack
-- @param #LIFO self
-- @return #LIFO self
function LIFO:Clear()
self:T(self.lid.."Clear")
self.pointer = 0
self.counter = 0
self.stackbypointer = nil
self.stackbyid = nil
self.stackbypointer = {}
self.stackbyid = {}
self.uniquecounter = 0
return self
end
--- LIFO Push Object to Stack
-- @param #LIFO self
-- @param #table Object
-- @param #string UniqueID (optional) - will default to current pointer + 1
-- @return #LIFO self
function LIFO:Push(Object,UniqueID)
self:T(self.lid.."Push")
self:T({Object,UniqueID})
self.pointer = self.pointer + 1
self.counter = self.counter + 1
local uniID = UniqueID
if not UniqueID then
self.uniquecounter = self.uniquecounter + 1
uniID = self.uniquecounter
end
self.stackbyid[uniID] = { pointer = self.pointer, data = Object, uniqueID = uniID }
self.stackbypointer[self.pointer] = { pointer = self.pointer, data = Object, uniqueID = uniID }
return self
end
--- LIFO Pull Object from Stack
-- @param #LIFO self
-- @return #table Object or nil if stack is empty
function LIFO:Pull()
self:T(self.lid.."Pull")
if self.counter == 0 then return nil end
local object = self.stackbypointer[self.pointer].data
self.stackbypointer[self.pointer] = nil
--local object = self.stackbypointer[1].data
--self.stackbypointer[1] = nil
self.counter = self.counter - 1
self.pointer = self.pointer - 1
self:Flatten()
return object
end
--- LIFO Pull Object from Stack by Pointer
-- @param #LIFO self
-- @param #number Pointer
-- @return #table Object or nil if stack is empty
function LIFO:PullByPointer(Pointer)
self:T(self.lid.."PullByPointer " .. tostring(Pointer))
if self.counter == 0 then return nil end
local object = self.stackbypointer[Pointer] -- #FIFO.IDEntry
self.stackbypointer[Pointer] = nil
if object then self.stackbyid[object.uniqueID] = nil end
self.counter = self.counter - 1
self:Flatten()
if object then
return object.data
else
return nil
end
end
--- LIFO Read, not Pull, Object from Stack by Pointer
-- @param #LIFO self
-- @param #number Pointer
-- @return #table Object or nil if stack is empty or pointer does not exist
function LIFO:ReadByPointer(Pointer)
self:T(self.lid.."ReadByPointer " .. tostring(Pointer))
if self.counter == 0 or not Pointer or not self.stackbypointer[Pointer] then return nil end
local object = self.stackbypointer[Pointer] -- #LIFO.IDEntry
if object then
return object.data
else
return nil
end
end
--- LIFO Read, not Pull, Object from Stack by UniqueID
-- @param #LIFO self
-- @param #number UniqueID
-- @return #table Object or nil if stack is empty or ID does not exist
function LIFO:ReadByID(UniqueID)
self:T(self.lid.."ReadByID " .. tostring(UniqueID))
if self.counter == 0 or not UniqueID or not self.stackbyid[UniqueID] then return nil end
local object = self.stackbyid[UniqueID] -- #LIFO.IDEntry
if object then
return object.data
else
return nil
end
end
--- LIFO Pull Object from Stack by UniqueID
-- @param #LIFO self
-- @param #tableUniqueID
-- @return #table Object or nil if stack is empty
function LIFO:PullByID(UniqueID)
self:T(self.lid.."PullByID " .. tostring(UniqueID))
if self.counter == 0 then return nil end
local object = self.stackbyid[UniqueID] -- #LIFO.IDEntry
--self.stackbyid[UniqueID] = nil
if object then
return self:PullByPointer(object.pointer)
else
return nil
end
end
--- LIFO Housekeeping
-- @param #LIFO self
-- @return #LIFO self
function LIFO:Flatten()
self:T(self.lid.."Flatten")
-- rebuild stacks
local pointerstack = {}
local idstack = {}
local counter = 0
for _ID,_entry in pairs(self.stackbypointer) do
counter = counter + 1
pointerstack[counter] = { pointer = counter, data = _entry.data, uniqueID = _entry.uniqueID}
end
for _ID,_entry in pairs(pointerstack) do
idstack[_entry.uniqueID] = { pointer = _entry.pointer , data = _entry.data, uniqueID = _entry.uniqueID}
end
self.stackbypointer = nil
self.stackbypointer = pointerstack
self.stackbyid = nil
self.stackbyid = idstack
self.counter = counter
self.pointer = counter
return self
end
--- LIFO Check Stack is empty
-- @param #LIFO self
-- @return #boolean empty
function LIFO:IsEmpty()
self:T(self.lid.."IsEmpty")
return self.counter == 0 and true or false
end
--- LIFO Get stack size
-- @param #LIFO self
-- @return #number size
function LIFO:GetSize()
self:T(self.lid.."GetSize")
return self.counter
end
--- LIFO Get stack size
-- @param #LIFO self
-- @return #number size
function LIFO:Count()
self:T(self.lid.."Count")
return self.counter
end
--- LIFO Check Stack is NOT empty
-- @param #LIFO self
-- @return #boolean notempty
function LIFO:IsNotEmpty()
self:T(self.lid.."IsNotEmpty")
return not self:IsEmpty()
end
--- LIFO Get the data stack by pointer
-- @param #LIFO self
-- @return #table Table of #LIFO.IDEntry entries
function LIFO:GetPointerStack()
self:T(self.lid.."GetPointerStack")
return self.stackbypointer
end
--- LIFO Get the data stack by UniqueID
-- @param #LIFO self
-- @return #table Table of #LIFO.IDEntry entries
function LIFO:GetIDStack()
self:T(self.lid.."GetIDStack")
return self.stackbyid
end
--- LIFO Get table of UniqueIDs sorted smallest to largest
-- @param #LIFO self
-- @return #table Table of #LIFO.IDEntry entries
function LIFO:GetIDStackSorted()
self:T(self.lid.."GetIDStackSorted")
local stack = self:GetIDStack()
local idstack = {}
for _id,_entry in pairs(stack) do
idstack[#idstack+1] = _id
self:T({"pre",_id})
end
local function sortID(a, b)
return a < b
end
table.sort(idstack)
return idstack
end
--- LIFO Check if a certain UniqeID exists
-- @param #LIFO self
-- @return #boolean exists
function LIFO:HasUniqueID(UniqueID)
self:T(self.lid.."HasUniqueID")
return self.stackbyid[UniqueID] and true or false
end
--- LIFO Print stacks to dcs.log
-- @param #LIFO self
-- @return #LIFO self
function LIFO:Flush()
self:T(self.lid.."FiFo Flush")
self:I("LIFO Flushing Stack by Pointer")
for _id,_data in pairs (self.stackbypointer) do
local data = _data -- #LIFO.IDEntry
self:I(string.format("Pointer: %s | Entry: Number = %s Data = %s UniqueID = %s",tostring(_id),tostring(data.pointer),tostring(data.data),tostring(data.uniqueID)))
end
self:I("LIFO Flushing Stack by ID")
for _id,_data in pairs (self.stackbyid) do
local data = _data -- #LIFO.IDEntry
self:I(string.format("ID: %s | Entry: Number = %s Data = %s UniqueID = %s",tostring(_id),tostring(data.pointer),tostring(data.data),tostring(data.uniqueID)))
end
self:I("Counter = " .. self.counter)
self:I("Pointer = ".. self.pointer)
return self
end
--- LIFO Get table of data entries
-- @param #LIFO self
-- @return #table Raw table indexed [1] to [n] of object entries - might be empty!
function LIFO:GetDataTable()
self:T(self.lid.."GetDataTable")
local datatable = {}
for _,_entry in pairs(self.stackbypointer) do
datatable[#datatable+1] = _entry.data
end
return datatable
end
--- LIFO Get sorted table of data entries by UniqueIDs (must be numerical UniqueIDs only!)
-- @param #LIFO self
-- @return #table Table indexed [1] to [n] of sorted object entries - might be empty!
function LIFO:GetSortedDataTable()
self:T(self.lid.."GetSortedDataTable")
local datatable = {}
local idtablesorted = self:GetIDStackSorted()
for _,_entry in pairs(idtablesorted) do
datatable[#datatable+1] = self:ReadByID(_entry)
end
return datatable
end
--- Iterate the LIFO and call an iterator function for the given LIFO data, providing the object for each element of the stack and optional parameters.
-- @param #LIFO self
-- @param #function IteratorFunction The function that will be called.
-- @param #table Arg (Optional) Further Arguments of the IteratorFunction.
-- @param #function Function (Optional) A function returning a #boolean true/false. Only if true, the IteratorFunction is called.
-- @param #table FunctionArguments (Optional) Function arguments.
-- @return #LIFO self
function LIFO:ForEach( IteratorFunction, Arg, Function, FunctionArguments )
self:T(self.lid.."ForEach")
local Set = self:GetPointerStack() or {}
Arg = Arg or {}
local function CoRoutine()
local Count = 0
for ObjectID, ObjectData in pairs( Set ) do
local Object = ObjectData.data
self:T( {Object} )
if Function then
if Function( unpack( FunctionArguments or {} ), Object ) == true then
IteratorFunction( Object, unpack( Arg ) )
end
else
IteratorFunction( Object, unpack( Arg ) )
end
Count = Count + 1
end
return true
end
local co = CoRoutine
local function Schedule()
local status, res = co()
self:T( { status, res } )
if status == false then
error( res )
end
if res == false then
return true -- resume next time the loop
end
return false
end
Schedule()
return self
end
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- End LIFO
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
end
File diff suppressed because it is too large Load Diff
+81 -56
View File
@@ -315,6 +315,9 @@ AIRBASE.PersianGulf = {
-- * AIRBASE.TheChannel.Lympne -- * AIRBASE.TheChannel.Lympne
-- * AIRBASE.TheChannel.Detling -- * AIRBASE.TheChannel.Detling
-- * AIRBASE.TheChannel.High_Halden -- * AIRBASE.TheChannel.High_Halden
-- * AIRBASE.TheChannel.Biggin_Hill
-- * AIRBASE.TheChannel.Eastchurch
-- * AIRBASE.TheChannel.Headcorn
-- --
-- @field TheChannel -- @field TheChannel
AIRBASE.TheChannel = { AIRBASE.TheChannel = {
@@ -327,6 +330,9 @@ AIRBASE.TheChannel = {
["Lympne"] = "Lympne", ["Lympne"] = "Lympne",
["Detling"] = "Detling", ["Detling"] = "Detling",
["High_Halden"] = "High Halden", ["High_Halden"] = "High Halden",
["Biggin_Hill"] = "Biggin Hill",
["Eastchurch"] = "Eastchurch",
["Headcorn"] = "Headcorn",
} }
--- Airbases of the Syria map: --- Airbases of the Syria map:
@@ -345,7 +351,6 @@ AIRBASE.TheChannel = {
-- * AIRBASE.Syria.Wujah_Al_Hajar -- * AIRBASE.Syria.Wujah_Al_Hajar
-- * AIRBASE.Syria.Al_Dumayr -- * AIRBASE.Syria.Al_Dumayr
-- * AIRBASE.Syria.Gazipasa -- * AIRBASE.Syria.Gazipasa
-- * AIRBASE.Syria.Ru_Convoy_4
-- * AIRBASE.Syria.Hatay -- * AIRBASE.Syria.Hatay
-- * AIRBASE.Syria.Nicosia -- * AIRBASE.Syria.Nicosia
-- * AIRBASE.Syria.Pinarbashi -- * AIRBASE.Syria.Pinarbashi
@@ -363,7 +368,6 @@ AIRBASE.TheChannel = {
-- * AIRBASE.Syria.Akrotiri -- * AIRBASE.Syria.Akrotiri
-- * AIRBASE.Syria.Naqoura -- * AIRBASE.Syria.Naqoura
-- * AIRBASE.Syria.Gaziantep -- * AIRBASE.Syria.Gaziantep
-- * AIRBASE.Syria.CVN_71
-- * AIRBASE.Syria.Sayqal -- * AIRBASE.Syria.Sayqal
-- * AIRBASE.Syria.Tiyas -- * AIRBASE.Syria.Tiyas
-- * AIRBASE.Syria.Shayrat -- * AIRBASE.Syria.Shayrat
@@ -384,61 +388,82 @@ AIRBASE.TheChannel = {
-- * AIRBASE.Syria.Beirut_Rafic_Hariri -- * AIRBASE.Syria.Beirut_Rafic_Hariri
-- * AIRBASE.Syria.An_Nasiriyah -- * AIRBASE.Syria.An_Nasiriyah
-- * AIRBASE.Syria.Abu_al_Duhur -- * AIRBASE.Syria.Abu_al_Duhur
-- * AIRBASE.Syria.At_Tanf
-- * AIRBASE.Syria.H3
-- * AIRBASE.Syria.H3_Northwest
-- * AIRBASE.Syria.H3_Southwest
-- * AIRBASE.Syria.Kharab_Ishk
-- * AIRBASE.Syria.Raj_al_Issa_East
-- * AIRBASE.Syria.Raj_al_Issa_West
-- * AIRBASE.Syria.Ruwayshid
-- * AIRBASE.Syria.Sanliurfa
-- * AIRBASE.Syria.Tal_Siman
-- --
-- @field Syria --@field Syria
AIRBASE.Syria = { AIRBASE.Syria={
["Kuweires"] = "Kuweires", ["Kuweires"]="Kuweires",
["Marj_Ruhayyil"] = "Marj Ruhayyil", ["Marj_Ruhayyil"]="Marj Ruhayyil",
["Kiryat_Shmona"] = "Kiryat Shmona", ["Kiryat_Shmona"]="Kiryat Shmona",
["Marj_as_Sultan_North"] = "Marj as Sultan North", ["Marj_as_Sultan_North"]="Marj as Sultan North",
["Eyn_Shemer"] = "Eyn Shemer", ["Eyn_Shemer"]="Eyn Shemer",
["Incirlik"] = "Incirlik", ["Incirlik"]="Incirlik",
["Damascus"] = "Damascus", ["Damascus"]="Damascus",
["Bassel_Al_Assad"] = "Bassel Al-Assad", ["Bassel_Al_Assad"]="Bassel Al-Assad",
["Rosh_Pina"] = "Rosh Pina", ["Rosh_Pina"]="Rosh Pina",
["Aleppo"] = "Aleppo", ["Aleppo"]="Aleppo",
["Al_Qusayr"] = "Al Qusayr", ["Al_Qusayr"]="Al Qusayr",
["Wujah_Al_Hajar"] = "Wujah Al Hajar", ["Wujah_Al_Hajar"]="Wujah Al Hajar",
["Al_Dumayr"] = "Al-Dumayr", ["Al_Dumayr"]="Al-Dumayr",
["Gazipasa"] = "Gazipasa", ["Gazipasa"]="Gazipasa",
["Ru_Convoy_4"] = "Ru Convoy-4", -- ["Ru_Convoy_4"]="Ru Convoy-4",
["Hatay"] = "Hatay", ["Hatay"]="Hatay",
["Nicosia"] = "Nicosia", ["Nicosia"]="Nicosia",
["Pinarbashi"] = "Pinarbashi", ["Pinarbashi"]="Pinarbashi",
["Paphos"] = "Paphos", ["Paphos"]="Paphos",
["Kingsfield"] = "Kingsfield", ["Kingsfield"]="Kingsfield",
["Thalah"] = "Tha'lah", ["Thalah"]="Tha'lah",
["Haifa"] = "Haifa", ["Haifa"]="Haifa",
["Khalkhalah"] = "Khalkhalah", ["Khalkhalah"]="Khalkhalah",
["Megiddo"] = "Megiddo", ["Megiddo"]="Megiddo",
["Lakatamia"] = "Lakatamia", ["Lakatamia"]="Lakatamia",
["Rayak"] = "Rayak", ["Rayak"]="Rayak",
["Larnaca"] = "Larnaca", ["Larnaca"]="Larnaca",
["Mezzeh"] = "Mezzeh", ["Mezzeh"]="Mezzeh",
["Gecitkale"] = "Gecitkale", ["Gecitkale"]="Gecitkale",
["Akrotiri"] = "Akrotiri", ["Akrotiri"]="Akrotiri",
["Naqoura"] = "Naqoura", ["Naqoura"]="Naqoura",
["Gaziantep"] = "Gaziantep", ["Gaziantep"]="Gaziantep",
["Sayqal"] = "Sayqal", ["Sayqal"]="Sayqal",
["Tiyas"] = "Tiyas", ["Tiyas"]="Tiyas",
["Shayrat"] = "Shayrat", ["Shayrat"]="Shayrat",
["Taftanaz"] = "Taftanaz", ["Taftanaz"]="Taftanaz",
["H4"] = "H4", ["H4"]="H4",
["King_Hussein_Air_College"] = "King Hussein Air College", ["King_Hussein_Air_College"]="King Hussein Air College",
["Rene_Mouawad"] = "Rene Mouawad", ["Rene_Mouawad"]="Rene Mouawad",
["Jirah"] = "Jirah", ["Jirah"]="Jirah",
["Ramat_David"] = "Ramat David", ["Ramat_David"]="Ramat David",
["Qabr_as_Sitt"] = "Qabr as Sitt", ["Qabr_as_Sitt"]="Qabr as Sitt",
["Minakh"] = "Minakh", ["Minakh"]="Minakh",
["Adana_Sakirpasa"] = "Adana Sakirpasa", ["Adana_Sakirpasa"]="Adana Sakirpasa",
["Palmyra"] = "Palmyra", ["Palmyra"]="Palmyra",
["Hama"] = "Hama", ["Hama"]="Hama",
["Ercan"] = "Ercan", ["Ercan"]="Ercan",
["Marj_as_Sultan_South"] = "Marj as Sultan South", ["Marj_as_Sultan_South"]="Marj as Sultan South",
["Tabqa"] = "Tabqa", ["Tabqa"]="Tabqa",
["Beirut_Rafic_Hariri"] = "Beirut-Rafic Hariri", ["Beirut_Rafic_Hariri"]="Beirut-Rafic Hariri",
["An_Nasiriyah"] = "An Nasiriyah", ["An_Nasiriyah"]="An Nasiriyah",
["Abu_al_Duhur"] = "Abu al-Duhur", ["Abu_al_Duhur"]="Abu al-Duhur",
["At_Tanf"]="At Tanf",
["H3"]="H3",
["H3_Northwest"]="H3 Northwest",
["H3_Southwest"]="H3 Southwest",
["Kharab_Ishk"]="Kharab Ishk",
["Raj_al_Issa_East"]="Raj al Issa East",
["Raj_al_Issa_West"]="Raj al Issa West",
["Ruwayshid"]="Ruwayshid",
["Sanliurfa"]="Sanliurfa",
["Tal_Siman"]="Tal Siman",
["Deir_ez-Zor"] = "Deir ez-Zor",
} }
--- Airbases of the Mariana Islands map: --- Airbases of the Mariana Islands map:
@@ -3770,3 +3770,44 @@ function POSITIONABLE:IsSubmarine()
return nil return nil
end end
--- Sets the controlled group to go at the specified speed in meters per second.
-- @param #CONTROLLABLE self
-- @param #number Speed Speed in meters per second.
-- @param #boolean Keep (Optional) When set to true, will maintain the speed on passing waypoints. If not present or false, the controlled group will return to the speed as defined by their route.
-- @return #CONTROLLABLE self
function CONTROLLABLE:SetSpeed(Speed, Keep)
self:F2( { self.ControllableName } )
-- Set default if not specified.
local speed = Speed or 5
local DCSControllable = self:GetDCSObject()
if DCSControllable then
local Controller = self:_GetController()
if Controller then
Controller:setSpeed(speed, Keep)
end
end
return self
end
--- [AIR] Sets the controlled aircraft group to fly at the specified altitude in meters.
-- @param #CONTROLLABLE self
-- @param #number Altitude Altitude in meters.
-- @param #boolean Keep (Optional) When set to true, will maintain the altitude on passing waypoints. If not present or false, the controlled group will return to the altitude as defined by their route.
-- @param #string AltType (Optional) Specifies the altitude type used. If nil, the altitude type of the current waypoint will be used. Accepted values are "BARO" and "RADIO".
-- @return #CONTROLLABLE self
function CONTROLLABLE:SetAltitude(Altitude, Keep, AltType)
self:F2( { self.ControllableName } )
-- Set default if not specified.
local altitude = Altitude or 1000
local DCSControllable = self:GetDCSObject()
if DCSControllable then
local Controller = self:_GetController()
if Controller then
if self:IsAir() then
Controller:setAltitude(altitude, Keep, AltType)
end
end
end
return self
end
+77 -19
View File
@@ -384,7 +384,7 @@ end
-- So all event listeners will catch the destroy event of this group for each unit in the group. -- So all event listeners will catch the destroy event of this group for each unit in the group.
-- To raise these events, provide the `GenerateEvent` parameter. -- To raise these events, provide the `GenerateEvent` parameter.
-- @param #GROUP self -- @param #GROUP self
-- @param #boolean GenerateEvent If true, a crash or dead event for each unit is generated. If false, if no event is triggered. If nil, a RemoveUnit event is triggered. -- @param #boolean GenerateEvent If true, a crash [AIR] or dead [GROUND] event for each unit is generated. If false, if no event is triggered. If nil, a RemoveUnit event is triggered.
-- @param #number delay Delay in seconds before despawning the group. -- @param #number delay Delay in seconds before despawning the group.
-- @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.
@@ -622,7 +622,7 @@ function GROUP:GetUnits()
local DCSGroup = self:GetDCSObject() local DCSGroup = self:GetDCSObject()
if DCSGroup then if DCSGroup then
local DCSUnits = DCSGroup:getUnits() local DCSUnits = DCSGroup:getUnits() or {}
local Units = {} local Units = {}
for Index, UnitData in pairs( DCSUnits ) do for Index, UnitData in pairs( DCSUnits ) do
Units[#Units+1] = UNIT:Find( UnitData ) Units[#Units+1] = UNIT:Find( UnitData )
@@ -680,6 +680,30 @@ function GROUP:GetUnit( UnitNumber )
return nil return nil
end end
--- Check if an (air) group is a client or player slot. Information is retrieved from the group template.
-- @param #GROUP self
-- @return #boolean If true, group is associated with a client or player slot.
function GROUP:IsPlayer()
-- Get group.
-- local group=self:GetGroup()
-- Units of template group.
local units=self:GetTemplate().units
-- Get numbers.
for _,unit in pairs(units) do
-- Check if unit name matach and skill is Client or Player.
if unit.name==self:GetName() and (unit.skill=="Client" or unit.skill=="Player") then
return true
end
end
return false
end
--- Returns the DCS Unit with number UnitNumber. --- Returns the DCS Unit with number UnitNumber.
-- If the underlying DCS Unit does not exist, the method will return nil. . -- If the underlying DCS Unit does not exist, the method will return nil. .
-- @param #GROUP self -- @param #GROUP self
@@ -765,8 +789,7 @@ end
--- Returns the average velocity Vec3 vector. --- Returns the average velocity Vec3 vector.
-- @param Wrapper.Group#GROUP self -- @param Wrapper.Group#GROUP self
-- @return DCS#Vec3 The velocity Vec3 vector -- @return DCS#Vec3 The velocity Vec3 vector or `#nil` if the GROUP is not existing or alive.
-- @return #nil The GROUP is not existing or alive.
function GROUP:GetVelocityVec3() function GROUP:GetVelocityVec3()
self:F2( self.GroupName ) self:F2( self.GroupName )
@@ -797,11 +820,19 @@ function GROUP:GetVelocityVec3()
return nil return nil
end end
--- Returns the average group altitude in meters.
-- @param Wrapper.Group#GROUP self
-- @param #boolean FromGround Measure from the ground or from sea level (ASL). Provide **true** for measuring from the ground (AGL). **false** or **nil** if you measure from sea level.
-- @return #number The altitude of the group or nil if is not existing or alive.
function GROUP:GetAltitude(FromGround)
self:F2( self.GroupName )
return self:GetHeight(FromGround)
end
--- Returns the average group height in meters. --- Returns the average group height in meters.
-- @param Wrapper.Group#GROUP self -- @param Wrapper.Group#GROUP self
-- @param #boolean FromGround Measure from the ground or from sea level. Provide **true** for measuring from the ground. **false** or **nil** if you measure from sea level. -- @param #boolean FromGround Measure from the ground or from sea level (ASL). Provide **true** for measuring from the ground (AGL). **false** or **nil** if you measure from sea level.
-- @return DCS#Vec3 The height of the group or nil if is not existing or alive. -- @return #number The height of the group or nil if is not existing or alive.
function GROUP:GetHeight( FromGround ) function GROUP:GetHeight( FromGround )
self:F2( self.GroupName ) self:F2( self.GroupName )
@@ -901,6 +932,24 @@ function GROUP:GetTypeName()
return nil return nil
end end
--- [AIRPLANE] Get the NATO reporting name (platform, e.g. "Flanker") of a GROUP (note - first unit the group). "Bogey" if not found. Currently airplanes only!
--@param #GROUP self
--@return #string NatoReportingName or "Bogey" if unknown.
function GROUP:GetNatoReportingName()
self:F2( self.GroupName )
local DCSGroup = self:GetDCSObject()
if DCSGroup then
local GroupTypeName = DCSGroup:getUnit(1):getTypeName()
self:T3( GroupTypeName )
return UTILS.GetReportingName(GroupTypeName)
end
return "Bogey"
end
--- Gets the player name of the group. --- Gets the player name of the group.
-- @param #GROUP self -- @param #GROUP self
-- @return #string The player name of the group. -- @return #string The player name of the group.
@@ -994,24 +1043,32 @@ end
-- @return Core.Point#COORDINATE The COORDINATE of the GROUP. -- @return Core.Point#COORDINATE The COORDINATE of the GROUP.
function GROUP:GetCoordinate() function GROUP:GetCoordinate()
local FirstUnit = self:GetUnit(1) local Units = self:GetUnits() or {}
for _,_unit in pairs(Units) do
local FirstUnit = _unit -- Wrapper.Unit#UNIT
if FirstUnit then if FirstUnit then
local FirstUnitCoordinate = FirstUnit:GetCoordinate() local FirstUnitCoordinate = FirstUnit:GetCoordinate()
if FirstUnitCoordinate then
local Heading = self:GetHeading()
FirstUnitCoordinate.Heading = Heading
return FirstUnitCoordinate return FirstUnitCoordinate
end end
end
end
BASE:E( { "Cannot GetCoordinate", Group = self, Alive = self:IsAlive() } ) BASE:E( { "Cannot GetCoordinate", Group = self, Alive = self:IsAlive() } )
return nil
end end
--- Returns a random @{DCS#Vec3} vector (point in 3D of the UNIT within the mission) within a range around the first UNIT of the GROUP. --- Returns a random @{DCS#Vec3} vector (point in 3D of the UNIT within the mission) within a range around the first UNIT of the GROUP.
-- @param #GROUP self -- @param #GROUP self
-- @param #number Radius -- @param #number Radius Radius in meters.
-- @return DCS#Vec3 The random 3D point vector around the first UNIT of the GROUP. -- @return DCS#Vec3 The random 3D point vector around the first UNIT of the GROUP or #nil The GROUP is invalid or empty.
-- @return #nil The GROUP is invalid or empty
-- @usage -- @usage
-- -- If Radius is ignored, returns the DCS#Vec3 of first UNIT of the GROUP -- -- If Radius is ignored, returns the DCS#Vec3 of first UNIT of the GROUP
function GROUP:GetRandomVec3(Radius) function GROUP:GetRandomVec3(Radius)
@@ -1032,8 +1089,7 @@ end
--- Returns the mean heading of every UNIT in the GROUP in degrees --- Returns the mean heading of every UNIT in the GROUP in degrees
-- @param #GROUP self -- @param #GROUP self
-- @return #number mean heading of the GROUP -- @return #number Mean heading of the GROUP in degrees or #nil The first UNIT is not existing or alive.
-- @return #nil The first UNIT is not existing or alive.
function GROUP:GetHeading() function GROUP:GetHeading()
self:F2(self.GroupName) self:F2(self.GroupName)
@@ -1061,8 +1117,8 @@ end
--- Return the fuel state and unit reference for the unit with the least --- Return the fuel state and unit reference for the unit with the least
-- amount of fuel in the group. -- amount of fuel in the group.
-- @param #GROUP self -- @param #GROUP self
-- @return #number The fuel state of the unit with the least amount of fuel -- @return #number The fuel state of the unit with the least amount of fuel.
-- @return #Unit reference to #Unit object for further processing -- @return Wrapper.Unit#UNIT reference to #Unit object for further processing.
function GROUP:GetFuelMin() function GROUP:GetFuelMin()
self:F3(self.ControllableName) self:F3(self.ControllableName)
@@ -1181,13 +1237,14 @@ function GROUP:IsInZone( Zone )
for UnitID, UnitData in pairs(self:GetUnits()) do for UnitID, UnitData in pairs(self:GetUnits()) do
local Unit = UnitData -- Wrapper.Unit#UNIT local Unit = UnitData -- Wrapper.Unit#UNIT
local vec2 = nil
if Unit then
-- Get 2D vector. That's all we need for the zone check. -- Get 2D vector. That's all we need for the zone check.
local vec2=Unit:GetVec2() vec2=Unit:GetVec2()
end
if Zone:IsVec2InZone(vec2) then if vec2 and Zone:IsVec2InZone(vec2) then
return true -- At least one unit is in the zone. That is enough. return true -- At least one unit is in the zone. That is enough.
else
-- This one is not but another could be.
end end
end end
@@ -2609,6 +2666,7 @@ function GROUP:GetSkill()
return skill return skill
end end
--- Get the unit in the group with the highest threat level, which is still alive. --- Get the unit in the group with the highest threat level, which is still alive.
-- @param #GROUP self -- @param #GROUP self
-- @return Wrapper.Unit#UNIT The most dangerous unit in the group. -- @return Wrapper.Unit#UNIT The most dangerous unit in the group.
@@ -382,7 +382,8 @@ function POSITIONABLE:GetCoordinate()
local PositionableVec3 = self:GetVec3() local PositionableVec3 = self:GetVec3()
local coord = COORDINATE:NewFromVec3( PositionableVec3 ) local coord = COORDINATE:NewFromVec3( PositionableVec3 )
local heading = self:GetHeading()
coord.Heading = heading
-- Return a new coordinate object. -- Return a new coordinate object.
return coord return coord
@@ -1176,6 +1177,30 @@ function POSITIONABLE:MessageToClient( Message, Duration, Client, Name )
return nil return nil
end end
--- Send a message to a @{Wrapper.Unit}.
-- 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 #string Message The message text
-- @param DCS#Duration Duration The duration of the message.
-- @param Wrapper.Unit#UNIT MessageUnit The UNIT object receiving the message.
-- @param #string Name (optional) The Name of the sender. If not provided, the Name is the type of the Positionable.
function POSITIONABLE:MessageToUnit( Message, Duration, MessageUnit, Name )
self:F2( { Message, Duration } )
local DCSObject = self:GetDCSObject()
if DCSObject then
if DCSObject:isExist() then
if MessageUnit:IsAlive() then
self:GetMessage( Message, Duration, Name ):ToUnit( MessageUnit )
else
BASE:E( { "Message not sent to Unit; Unit is not alive...", Message = Message, MessageUnit = MessageUnit } )
end
else
BASE:E( { "Message not sent to Unit; Positionable is not alive ...", Message = Message, Positionable = self, MessageUnit = MessageUnit } )
end
end
end
--- Send a message to a @{Wrapper.Group}. --- Send a message to a @{Wrapper.Group}.
-- 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
@@ -1249,6 +1274,30 @@ function POSITIONABLE:MessageToSetGroup( Message, Duration, MessageSetGroup, Nam
return nil return nil
end end
--- Send a message to a @{Core.Set#SET_UNIT}.
-- 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 #string Message The message text
-- @param DCS#Duration Duration The duration of the message.
-- @param Core.Set#SET_UNIT MessageSetUnit The SET_UNIT collection receiving the message.
-- @param #string Name (optional) The Name of the sender. If not provided, the Name is the type of the Positionable.
function POSITIONABLE:MessageToSetUnit( Message, Duration, MessageSetUnit, Name )
self:F2( { Message, Duration } )
local DCSObject = self:GetDCSObject()
if DCSObject then
if DCSObject:isExist() then
MessageSetUnit:ForEachUnit(
function( MessageGroup )
self:GetMessage( Message, Duration, Name ):ToUnit( MessageGroup )
end
)
end
end
return nil
end
--- Send a message to the players in the @{Wrapper.Group}. --- Send a message to the players in the @{Wrapper.Group}.
-- 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
+36 -25
View File
@@ -10,8 +10,11 @@
-- --
-- @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.
@@ -37,10 +40,13 @@
-- --
-- * @{#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 SANITIZE these STATIC OBJECT REFERENCES! (make the STATIC object references nil). -- IMPORTANT: ONE SHOULD NEVER SANATIZE these STATIC OBJECT REFERENCES! (make the STATIC object references nil).
-- --
-- @field #STATIC -- @field #STATIC
STATIC = { ClassName = "STATIC" } STATIC = {
ClassName = "STATIC",
}
--- Register a static object. --- Register a static object.
-- @param #STATIC self -- @param #STATIC self
@@ -52,6 +58,7 @@ 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.
@@ -90,9 +97,8 @@ end
--- Destroys the STATIC. --- Destroys the STATIC.
-- @param #STATIC self -- @param #STATIC self
-- @param #boolean GenerateEvent (Optional) true to generate a crash or dead event, false to not generate any event. `nil` (default) creates a remove event. -- @param #boolean GenerateEvent (Optional) true if you want to generate a crash or dead event for the static.
-- @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" )
@@ -111,7 +117,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 any event upon destruction. -- Ship:Destroy( false ) -- Don't generate an event upon destruction.
-- --
function STATIC:Destroy( GenerateEvent ) function STATIC:Destroy( GenerateEvent )
self:F2( self.ObjectName ) self:F2( self.ObjectName )
@@ -142,6 +148,7 @@ 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
@@ -173,6 +180,7 @@ 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.
@@ -186,15 +194,15 @@ end
-- @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 The heading of the static respawn in degrees. Default is 0 deg. -- @param #number Heading The heading of the static respawn in degrees. Default is 0 deg.
-- @param #number Delay Delay in seconds before the static is spawned. -- @param #number Delay Delay in seconds before the static is spawned.
function STATIC:SpawnAt( Coordinate, Heading, Delay ) function STATIC:SpawnAt(Coordinate, Heading, Delay)
Heading = Heading or 0 Heading=Heading or 0
if Delay and Delay > 0 then if Delay and Delay>0 then
SCHEDULER:New( nil, self.SpawnAt, { self, Coordinate, Heading }, Delay ) SCHEDULER:New(nil, self.SpawnAt, {self, Coordinate, Heading}, Delay)
else else
local SpawnStatic = SPAWNSTATIC:NewFromStatic( self.StaticName ) local SpawnStatic=SPAWNSTATIC:NewFromStatic(self.StaticName)
SpawnStatic:SpawnFromPointVec2( Coordinate, Heading, self.StaticName ) SpawnStatic:SpawnFromPointVec2( Coordinate, Heading, self.StaticName )
@@ -203,45 +211,48 @@ 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
-- @param DCS#country.id CountryID (Optional) The country ID used for spawning the new static. Default is same as currently. -- @param DCS#country.id CountryID (Optional) The country ID used for spawning the new static. Default is same as currently.
-- @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 now.
function STATIC:ReSpawn( CountryID, Delay ) function STATIC:ReSpawn(CountryID, Delay)
if Delay and Delay > 0 then if Delay and Delay>0 then
SCHEDULER:New( nil, self.ReSpawn, { self, CountryID }, Delay ) SCHEDULER:New(nil, self.ReSpawn, {self, CountryID}, Delay)
else else
CountryID = CountryID or self:GetCountry() CountryID=CountryID or self:GetCountry()
local SpawnStatic = SPAWNSTATIC:NewFromStatic( self.StaticName, CountryID ) local SpawnStatic=SPAWNSTATIC:NewFromStatic(self.StaticName, CountryID)
SpawnStatic:Spawn( nil, self.StaticName ) SpawnStatic:Spawn(nil, self.StaticName)
end end
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 is the current heading. -- @param #number Heading (Optional) The heading of the static respawn in degrees. Default the current heading.
-- @param #number Delay (Optional) Delay in seconds before static is respawned. Default is now. -- @param #number Delay (Optional) Delay in seconds before static is respawned. Default now.
function STATIC:ReSpawnAt( Coordinate, Heading, Delay ) function STATIC:ReSpawnAt(Coordinate, Heading, Delay)
-- Heading=Heading or 0 --Heading=Heading or 0
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() )
SpawnStatic:SpawnFromCoordinate( Coordinate, Heading, self.StaticName ) local SpawnStatic=SPAWNSTATIC:NewFromStatic(self.StaticName, self:GetCountry())
SpawnStatic:SpawnFromCoordinate(Coordinate, Heading, self.StaticName)
end end
return self return self
end end
+93 -4
View File
@@ -90,6 +90,7 @@
UNIT = { UNIT = {
ClassName="UNIT", ClassName="UNIT",
UnitName=nil, UnitName=nil,
GroupName=nil,
} }
@@ -110,11 +111,17 @@ UNIT = {
function UNIT:Register( UnitName ) function UNIT:Register( UnitName )
-- Inherit CONTROLLABLE. -- Inherit CONTROLLABLE.
local self = BASE:Inherit( self, CONTROLLABLE:New( UnitName ) ) local self = BASE:Inherit( self, CONTROLLABLE:New( UnitName ) ) --#UNIT
-- Set unit name. -- Set unit name.
self.UnitName = UnitName self.UnitName = UnitName
local unit=Unit.getByName(self.UnitName)
if unit then
self.GroupName=unit:getGroup():getName()
end
-- Set event prio. -- Set event prio.
self:SetEventPriority( 3 ) self:SetEventPriority( 3 )
@@ -168,6 +175,9 @@ 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:
@@ -260,6 +270,8 @@ 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.
@@ -296,6 +308,8 @@ 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.
@@ -401,6 +415,17 @@ function UNIT:GetClient()
return nil return nil
end end
--- [AIRPLANE] Get the NATO reporting name of a UNIT. Currently airplanes only!
--@param #UNIT self
--@return #string NatoReportingName or "Bogey" if unknown.
function UNIT:GetNatoReportingName()
local typename = self:GetTypeName()
return UTILS.GetReportingName(typename)
end
--- Returns the unit's number in the group. --- Returns the unit's number in the group.
-- The number is the same number the unit has in ME. -- The number is the same number the unit has in ME.
-- It may not be changed during the mission. -- It may not be changed during the mission.
@@ -517,6 +542,63 @@ function UNIT:IsTanker()
return tanker, system return tanker, system
end end
--- Check if the unit can supply ammo. Currently, we have
--
-- * M 818
-- * Ural-375
-- * ZIL-135
--
-- This list needs to be extended, if DCS adds other units capable of supplying ammo.
--
-- @param #UNIT self
-- @return #boolean If `true`, unit can supply ammo.
function UNIT:IsAmmoSupply()
-- Type name is the only thing we can check. There is no attribute (Sep. 2021) which would tell us.
local typename=self:GetTypeName()
if typename=="M 818" then
-- Blue ammo truck.
return true
elseif typename=="Ural-375" then
-- Red ammo truck.
return true
elseif typename=="ZIL-135" then
-- Red ammo truck. Checked that it can also provide ammo.
return true
end
return false
end
--- Check if the unit can supply fuel. Currently, we have
--
-- * M978 HEMTT Tanker
-- * ATMZ-5
-- * ATMZ-10
-- * ATZ-5
--
-- This list needs to be extended, if DCS adds other units capable of supplying fuel.
--
-- @param #UNIT self
-- @return #boolean If `true`, unit can supply fuel.
function UNIT:IsFuelSupply()
-- Type name is the only thing we can check. There is no attribute (Sep. 2021) which would tell us.
local typename=self:GetTypeName()
if typename=="M978 HEMTT Tanker" then
return true
elseif typename=="ATMZ-5" then
return true
elseif typename=="ATMZ-10" then
return true
elseif typename=="ATZ-5" then
return true
end
return false
end
--- Returns the unit's group if it exist and nil otherwise. --- Returns the unit's group if it exist and nil otherwise.
-- @param Wrapper.Unit#UNIT self -- @param Wrapper.Unit#UNIT self
@@ -676,8 +758,6 @@ function UNIT:GetAmmunition()
return nammo, nshells, nrockets, nbombs, nmissiles return nammo, nshells, nrockets, nbombs, nmissiles
end end
--- Returns the unit sensors. --- Returns the unit sensors.
-- @param #UNIT self -- @param #UNIT self
-- @return DCS#Unit.Sensors Table of sensors. -- @return DCS#Unit.Sensors Table of sensors.
@@ -954,6 +1034,7 @@ 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 = ""
@@ -979,6 +1060,7 @@ 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
@@ -992,7 +1074,7 @@ function UNIT:GetThreatLevel()
elseif ( Attributes["Tanks"] or Attributes["IFV"] ) and elseif ( Attributes["Tanks"] or Attributes["IFV"] ) and
not Attributes["ATGM"] then ThreatLevel = 3 not Attributes["ATGM"] then ThreatLevel = 3
elseif Attributes["Old Tanks"] or Attributes["APC"] or Attributes["Artillery"] then ThreatLevel = 2 elseif Attributes["Old Tanks"] or Attributes["APC"] or Attributes["Artillery"] then ThreatLevel = 2
elseif Attributes["Infantry"] then ThreatLevel = 1 elseif Attributes["Infantry"] or Attributes["EWR"] then ThreatLevel = 1
end end
ThreatText = ThreatLevels[ThreatLevel+1] ThreatText = ThreatLevels[ThreatLevel+1]
@@ -1014,6 +1096,7 @@ 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
@@ -1131,6 +1214,12 @@ 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.
+1
View File
@@ -5,6 +5,7 @@ Utilities/Enums.lua
Utilities/Profiler.lua Utilities/Profiler.lua
Utilities/Templates.lua Utilities/Templates.lua
Utilities/STTS.lua Utilities/STTS.lua
Utilities/FiFo.lua
Core/Base.lua Core/Base.lua
Core/Beacon.lua Core/Beacon.lua