mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2026-07-18 10:34:03 +00:00
Compare commits
135 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b33890ff03 | |||
| 1be2c92a5c | |||
| 4c8a17fe57 | |||
| 64dea17982 | |||
| b1f86c702d | |||
| 1a9540d0d4 | |||
| cdfaac527c | |||
| 4e3bf9969b | |||
| 74c16bd4f0 | |||
| 55e048b322 | |||
| b31fb7ece3 | |||
| 149e3421d9 | |||
| 338ec34604 | |||
| 3d79a16d3a | |||
| efa08c1280 | |||
| 589e65963f | |||
| af4f20af67 | |||
| b1b8630d21 | |||
| 98ed7d50c1 | |||
| 4ba81cb8bc | |||
| 626b12f486 | |||
| 36c0297344 | |||
| 8c60a8c678 | |||
| 6829d75464 | |||
| 867f919d5f | |||
| f769a0deb5 | |||
| 4efd71e36a | |||
| 7e9dd9deff | |||
| fed9174bcb | |||
| b6ea6606fc | |||
| 9963c737a3 | |||
| 5005203206 | |||
| a3455855b8 | |||
| 73d3ed119c | |||
| d1e4dd3fe9 | |||
| 23112c9954 | |||
| 9326cfad1c | |||
| 23c59d906f | |||
| cc62655ffe | |||
| b8e114101b | |||
| 401e9d9e8e | |||
| f083b77390 | |||
| db3bc3742e | |||
| 9b1a3e4894 | |||
| bf10196662 | |||
| 6c32aa6044 | |||
| edf70e971c | |||
| 7c5af54473 | |||
| a0420e1cb6 | |||
| 2aa9b91ce5 | |||
| 27bd27a2e5 | |||
| 8e219c5877 | |||
| fdc19a6898 | |||
| d3ebf023fb | |||
| 3d1dcd78a3 | |||
| d40c559d2d | |||
| 9cda1b88ea | |||
| 09f99b9a74 | |||
| ff5205e686 | |||
| ebd105f80d | |||
| cc8a4e0bad | |||
| 5f70e2d6b1 | |||
| 95f38fbf55 | |||
| aec3466f13 | |||
| 696630fe4d | |||
| 47aa524677 | |||
| 79f03c164c | |||
| ca7d3a48a7 | |||
| 2556dbe145 | |||
| af1e9546e5 | |||
| 3203a22668 | |||
| b69ac2f86f | |||
| 0d410f3e55 | |||
| cbe6756330 | |||
| 07045be32b | |||
| 52a2132463 | |||
| 9272b1f18c | |||
| b84880c0dd | |||
| a9be18b284 | |||
| 93178df67f | |||
| f34bf1e052 | |||
| e159eb83b7 | |||
| 2581836058 | |||
| d9651e1dea | |||
| 0347f185a5 | |||
| 5e2218de38 | |||
| 6db5441bb1 | |||
| 13b7e43729 | |||
| a72f7298d0 | |||
| 801cc105da | |||
| f186b4bd58 | |||
| 79f13fa6ae | |||
| d38fc4ec8f | |||
| ba1575d674 | |||
| 391182e23f | |||
| 6d5fb64fde | |||
| 5df1fb88f1 | |||
| 2e4d4f056a | |||
| a9ceda4edd | |||
| e76fd23396 | |||
| 7df1eb963f | |||
| aff1d3c7db | |||
| d15f6cdb44 | |||
| c59b668eec | |||
| 4620a83317 | |||
| 87d0c4e9d4 | |||
| 74361f6a3a | |||
| b82b882e02 | |||
| 347783d4b7 | |||
| 0b2f07ca6c | |||
| 7c5d5543e0 | |||
| 3d10716b1f | |||
| c48a7d4400 | |||
| 79130d4fe2 | |||
| aebb6ac0db | |||
| 3eb910b47e | |||
| 6223b8e1a7 | |||
| 533a4dfa6c | |||
| dbc752253b | |||
| 7f074781f4 | |||
| ab77fcbc1f | |||
| 56520092c3 | |||
| 252a1b0761 | |||
| 51e5f53965 | |||
| b0976d1613 | |||
| a737ca71e6 | |||
| 1071300a7f | |||
| 2490958090 | |||
| b78b76e579 | |||
| efff22fc18 | |||
| 4b27e92210 | |||
| f2063f41f6 | |||
| 12241e931a | |||
| 4cb6debef8 | |||
| efe4bf3912 |
@@ -735,6 +735,12 @@ do -- Event Handling
|
||||
-- @function [parent=#BASE] OnEventPlayerEnterAircraft
|
||||
-- @param #BASE self
|
||||
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
||||
|
||||
--- Occurs when an option is changed for an AI group.
|
||||
-- The event identifies the initiating group, but does not provide the option ID or value.
|
||||
-- @function [parent=#BASE] OnEventGroupChangeOption
|
||||
-- @param #BASE self
|
||||
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
||||
|
||||
--- Occurs when a player creates a dynamic cargo object from the F8 ground crew menu.
|
||||
-- *** NOTE *** this is a workarounf for DCS not creating these events as of Aug 2024.
|
||||
@@ -855,7 +861,7 @@ end
|
||||
-- @param DCS#Time EventTime The time stamp of the event.
|
||||
-- @param DCS#Object Initiator The initiating object of the event.
|
||||
function BASE:CreateEventTakeoff( EventTime, Initiator )
|
||||
self:F( { EventTime, Initiator } )
|
||||
--self:F( { EventTime, Initiator } )
|
||||
|
||||
local Event = {
|
||||
id = world.event.S_EVENT_TAKEOFF,
|
||||
@@ -880,6 +886,22 @@ end
|
||||
|
||||
world.onEvent(Event)
|
||||
end
|
||||
|
||||
--- Creation of a `S_EVENT_GROUP_CHANGE_OPTION` event.
|
||||
-- @param #BASE self
|
||||
-- @param DCS#Time EventTime The time stamp of the event.
|
||||
-- @param DCS#Group Initiator The initiating group of the event.
|
||||
function BASE:CreateEventGroupChangeOption( EventTime, Initiator )
|
||||
self:F( { EventTime, Initiator } )
|
||||
|
||||
local Event = {
|
||||
id = EVENTS.GroupChangeOption,
|
||||
time = EventTime,
|
||||
initiator = Initiator,
|
||||
}
|
||||
|
||||
world.onEvent( Event )
|
||||
end
|
||||
|
||||
--- Creation of a S_EVENT_NEW_DYNAMIC_CARGO event.
|
||||
-- @param #BASE self
|
||||
|
||||
@@ -1380,12 +1380,12 @@ function DATABASE:_RegisterDynamicGroup(Groupname)
|
||||
local DCSUnitName = DCSUnit:getName()
|
||||
|
||||
-- Add unit.
|
||||
self:I(string.format("Register Unit: %s", tostring(DCSUnitName)))
|
||||
self:T(string.format("Register Unit: %s", tostring(DCSUnitName)))
|
||||
self:AddUnit( tostring(DCSUnitName), true )
|
||||
|
||||
end
|
||||
else
|
||||
self:E({"Group does not exist: ", DCSGroup})
|
||||
self:T({"Group does not exist: ", DCSGroup})
|
||||
end
|
||||
return self
|
||||
end
|
||||
@@ -1488,27 +1488,28 @@ end
|
||||
-- @return #DATABASE self
|
||||
function DATABASE:_RegisterAirbase(airbase)
|
||||
|
||||
local IsSyria = UTILS.GetDCSMap() == "Syria" and true or false
|
||||
local countHSyria = 0
|
||||
--local IsSyria = UTILS.GetDCSMap() == "Syria" and true or false
|
||||
--local countHSyria = 0
|
||||
|
||||
if airbase then
|
||||
|
||||
-- Get the airbase name.
|
||||
local DCSAirbaseName = airbase:getName()
|
||||
|
||||
-- DCS 2.9.8.1107 added 143 helipads all named H with the same object ID ..
|
||||
--[[ DCS 2.9.8.1107 added 143 helipads all named H with the same object ID ..
|
||||
if IsSyria and DCSAirbaseName == "H" and countHSyria > 0 then
|
||||
--[[
|
||||
--
|
||||
local p = airbase:getPosition().p
|
||||
local mgrs = COORDINATE:New(p.x,p.z,p.y):ToStringMGRS()
|
||||
self:I("Airbase on Syria map named H @ "..mgrs)
|
||||
countHSyria = countHSyria + 1
|
||||
if countHSyria > 1 then return self end
|
||||
--]]
|
||||
--
|
||||
return self
|
||||
elseif IsSyria and DCSAirbaseName == "H" and countHSyria == 0 then
|
||||
countHSyria = countHSyria + 1
|
||||
end
|
||||
--]]
|
||||
|
||||
-- This gave the incorrect value to be inserted into the airdromeID for DCS 2.5.6. Is fixed now.
|
||||
local airbaseID=airbase:getID()
|
||||
|
||||
@@ -278,6 +278,7 @@ EVENTS = {
|
||||
SimulationUnfreeze = world.event.S_EVENT_SIMULATION_UNFREEZE or -1,
|
||||
HumanAircraftRepairStart = world.event.S_EVENT_HUMAN_AIRCRAFT_REPAIR_START or -1,
|
||||
HumanAircraftRepairFinish = world.event.S_EVENT_HUMAN_AIRCRAFT_REPAIR_FINISH or -1,
|
||||
GroupChangeOption = world.event.S_EVENT_GROUP_CHANGE_OPTION or -1,
|
||||
-- dynamic cargo
|
||||
NewDynamicCargo = world.event.S_EVENT_NEW_DYNAMIC_CARGO or -1,
|
||||
DynamicCargoLoaded = world.event.S_EVENT_DYNAMIC_CARGO_LOADED or -1,
|
||||
@@ -291,23 +292,25 @@ EVENTS = {
|
||||
--
|
||||
-- * A (Object.Category.)UNIT : A UNIT object type is involved in the Event.
|
||||
-- * A (Object.Category.)STATIC : A STATIC object type is involved in the Event.
|
||||
-- * A GROUP : A DCS Group object is involved in the Event.
|
||||
--
|
||||
-- @type EVENTDATA
|
||||
-- @field #number id The identifier of the event.
|
||||
--
|
||||
-- @field DCS#Unit initiator (UNIT/STATIC/SCENERY) The initiating @{DCS#Unit} or @{DCS#StaticObject}.
|
||||
-- @field DCS#Unit initiator (UNIT/STATIC/SCENERY/GROUP) The initiating @{DCS#Unit} or @{DCS#StaticObject}. For `S_EVENT_GROUP_CHANGE_OPTION`, this is a DCS Group.
|
||||
-- @field DCS#Object.Category IniObjectCategory (UNIT/STATIC/SCENERY) The initiator object category ( Object.Category.UNIT or Object.Category.STATIC ).
|
||||
-- @field DCS#Unit IniDCSUnit (UNIT/STATIC) The initiating @{DCS#Unit} or @{DCS#StaticObject}.
|
||||
-- @field #string IniDCSUnitName (UNIT/STATIC) The initiating Unit name.
|
||||
-- @field Wrapper.Unit#UNIT IniUnit (UNIT/STATIC) The initiating MOOSE wrapper @{Wrapper.Unit#UNIT} of the initiator Unit object.
|
||||
-- @field #string IniUnitName (UNIT/STATIC) The initiating UNIT name (same as IniDCSUnitName).
|
||||
-- @field DCS#Group IniDCSGroup (UNIT) The initiating {DCSGroup#Group}.
|
||||
-- @field #string IniDCSGroupName (UNIT) The initiating Group name.
|
||||
-- @field Wrapper.Group#GROUP IniGroup (UNIT) The initiating MOOSE wrapper @{Wrapper.Group#GROUP} of the initiator Group object.
|
||||
-- @field #string IniGroupName UNIT) The initiating GROUP name (same as IniDCSGroupName).
|
||||
-- @field DCS#Group IniDCSGroup (UNIT/GROUP) The initiating @{DCS#Group}.
|
||||
-- @field #string IniDCSGroupName (UNIT/GROUP) The initiating Group name.
|
||||
-- @field Wrapper.Group#GROUP IniGroup (UNIT/GROUP) The initiating MOOSE wrapper @{Wrapper.Group#GROUP} of the initiator Group object.
|
||||
-- @field #string IniGroupName (UNIT/GROUP) The initiating GROUP name (same as IniDCSGroupName).
|
||||
-- @field DCS#Group.Category IniGroupCategory (GROUP) The category of the initiating group.
|
||||
-- @field #string IniPlayerName (UNIT) The name of the initiating player in case the Unit is a client or player slot.
|
||||
-- @field #string IniPlayerUCID (UNIT) The UCID of the initiating player in case the Unit is a client or player slot and on a multi-player server.
|
||||
-- @field DCS#coalition.side IniCoalition (UNIT) The coalition of the initiator.
|
||||
-- @field DCS#coalition.side IniCoalition (UNIT/GROUP) The coalition of the initiator.
|
||||
-- @field DCS#Unit.Category IniCategory (UNIT) The category of the initiator.
|
||||
-- @field #string IniTypeName (UNIT) The type name of the initiator.
|
||||
--
|
||||
@@ -734,6 +737,12 @@ local _EVENTMETA = {
|
||||
Side = "I",
|
||||
Event = "OnEventHumanAircraftRepairFinish",
|
||||
Text = "S_EVENT_HUMAN_AIRCRAFT_REPAIR_FINISH"
|
||||
},
|
||||
[EVENTS.GroupChangeOption] = {
|
||||
Order = 1,
|
||||
Side = "I",
|
||||
Event = "OnEventGroupChangeOption",
|
||||
Text = "S_EVENT_GROUP_CHANGE_OPTION"
|
||||
},
|
||||
-- dynamic cargo
|
||||
[EVENTS.NewDynamicCargo] = {
|
||||
@@ -1234,7 +1243,16 @@ function EVENT:onEvent( Event )
|
||||
|
||||
if Event.initiator then
|
||||
|
||||
Event.IniObjectCategory = Object.getCategory(Event.initiator)
|
||||
if Event.id == EVENTS.GroupChangeOption then
|
||||
Event.IniDCSGroup = Event.initiator
|
||||
Event.IniDCSGroupName = Group.getName(Event.initiator)
|
||||
Event.IniGroupName = Event.IniDCSGroupName
|
||||
Event.IniGroup = GROUP:FindByName(Event.IniDCSGroupName)
|
||||
Event.IniCoalition = Group.getCoalition(Event.initiator)
|
||||
Event.IniGroupCategory = Group.getCategory(Event.initiator)
|
||||
else
|
||||
Event.IniObjectCategory = Object.getCategory(Event.initiator)
|
||||
end
|
||||
|
||||
if Event.IniObjectCategory == Object.Category.STATIC then
|
||||
---
|
||||
@@ -1453,7 +1471,12 @@ function EVENT:onEvent( Event )
|
||||
-- Weapon.
|
||||
if Event.weapon and type(Event.weapon) == "table" and Event.weapon.isExist and Event.weapon:isExist() then
|
||||
Event.Weapon = Event.weapon
|
||||
Event.WeaponName = Event.weapon:isExist() and Event.weapon:getTypeName() or "Unknown Weapon"
|
||||
if Event.weapon_name == "ZELL Booster" then
|
||||
Event.WeaponName = "ZELL Booster"
|
||||
else
|
||||
Event.WeaponName = Event.weapon:isExist() and Event.weapon.getTypeName and Event.weapon:getTypeName() or "Unknown Weapon"
|
||||
end
|
||||
if Event.weapon_name == "ZELL Booster" then Event.WeaponName = "ZELL Booster" end
|
||||
Event.WeaponUNIT = CLIENT:Find( Event.Weapon, '', true ) -- Sometimes, the weapon is a player unit!
|
||||
Event.WeaponPlayerName = Event.WeaponUNIT and Event.Weapon.getPlayerName and Event.Weapon:getPlayerName()
|
||||
--Event.WeaponPlayerName = Event.WeaponUNIT and Event.Weapon:getPlayerName()
|
||||
|
||||
@@ -869,10 +869,21 @@ do
|
||||
local MenuTable = {}
|
||||
for MenuText, Menu in pairs( self.Menus or {} ) do
|
||||
local tag = Menu.MenuTag or math.random(1,10000)
|
||||
MenuTable[#MenuTable+1] = {Tag=tag, Enty=Menu}
|
||||
MenuTable[#MenuTable+1] = {Tag=tag, Entry=Menu}
|
||||
end
|
||||
table.sort(MenuTable, function (k1, k2) return k1.tag < k2.tag end )
|
||||
for _, Menu in pairs( MenuTable ) do
|
||||
local function SortTable(k1,k2)
|
||||
if not k1 then
|
||||
if not k2 then return true else return false end
|
||||
elseif not k2 then
|
||||
if not k1 then return true else return false end
|
||||
else
|
||||
return (k1.Tag or 15) <= (k2.Tag or 15)
|
||||
end
|
||||
return false
|
||||
end
|
||||
table.sort(MenuTable, SortTable)
|
||||
--table.sort(MenuTable, function (k1, k2) return (k1.tag or 15) <= (k2.tag or 15) end )
|
||||
for _, Menu in ipairs( MenuTable ) do
|
||||
Menu.Entry:Refresh()
|
||||
end
|
||||
end
|
||||
|
||||
@@ -375,3 +375,13 @@ function SCHEDULEDISPATCHER:NoTrace( Scheduler )
|
||||
Scheduler.ShowTrace = false
|
||||
end
|
||||
|
||||
--- Helper for memory cleanup for self stopping schedulers
|
||||
-- @param #SCHEDULEDISPATCHER self
|
||||
-- @param Core.Scheduler#SCHEDULER Scheduler Scheduler object.
|
||||
-- @param #string CallID (Optional) Scheduler Call ID.
|
||||
function SCHEDULEDISPATCHER:_Reclaim( Scheduler, CallID )
|
||||
self:Stop( Scheduler, CallID ) -- remove DCS timer, nil ScheduleID
|
||||
if self.Schedule[Scheduler] then self.Schedule[Scheduler][CallID] = nil end
|
||||
self.ObjectSchedulers[CallID] = nil
|
||||
self.PersistentSchedulers[CallID] = nil
|
||||
end
|
||||
|
||||
@@ -62,7 +62,8 @@ do -- SET_BASE
|
||||
-- @field #table List Unused table.
|
||||
-- @field Core.Scheduler#SCHEDULER CallScheduler
|
||||
-- @field #SET_BASE.Filters Filter Filters
|
||||
-- @field #booleaen filterNoRegex If true, FilterPrefix ignores special characters and evaluates plain string.
|
||||
-- @field #boolean filterNoRegex If true, FilterPrefix ignores special characters and evaluates plain string. Defaults to false.
|
||||
-- @field #boolean filterReplaceDash If true then if filterNoRegex is false, replace dashes with regex pattern friendly pattern. Defaults to true
|
||||
-- @extends Core.Base#BASE
|
||||
|
||||
--- The @{Core.Set#SET_BASE} class defines the core functions that define a collection of objects.
|
||||
@@ -102,6 +103,7 @@ do -- SET_BASE
|
||||
},
|
||||
},
|
||||
filterNoRegex=false,
|
||||
filterReplaceDash=true,
|
||||
}
|
||||
|
||||
--- Filters
|
||||
@@ -256,7 +258,8 @@ do -- SET_BASE
|
||||
-- @return #boolean Returns `true`, if the pattern is contained in the name and false otherwise.
|
||||
function SET_BASE:_SearchPattern(Name, Pattern, NoRegex, ReplaceDash)
|
||||
NoRegex=NoRegex or self.filterNoRegex
|
||||
if ReplaceDash==true then
|
||||
ReplaceDash=ReplaceDash or self.filterReplaceDash
|
||||
if ReplaceDash==true and NoRegex ~= true then
|
||||
-- Not sure why "-" is replaced by "%-" ?! - So we can still match group names with a dash in them
|
||||
-- reason is that the string is interpreted as a pattern and "-" is a special character then. For interpreting it as a string, fourth parameter needs to be set to true.
|
||||
Pattern=Pattern:gsub("-", "%%-")
|
||||
@@ -265,6 +268,16 @@ do -- SET_BASE
|
||||
return contain
|
||||
end
|
||||
|
||||
---Set Regex Options for FilterPrefix function.
|
||||
-- @param #SET_BASE self
|
||||
-- @param #boolean NoRegex If true, switch off Regex pattern matching for FilterPrefixes.
|
||||
-- @param #boolean ReplaceDash If false, switch off dash "-" replacement in strings for FilterPrefixes.
|
||||
-- @return #SET_BASE self
|
||||
function SET_BASE:FilterSetRegex(NoRegex,ReplaceDash)
|
||||
if NoRegex ~= nil then self.filterNoRegex = NoRegex end
|
||||
self.filterReplaceDash = ReplaceDash or true
|
||||
return self
|
||||
end
|
||||
|
||||
--- Gets the Set.
|
||||
-- @param #SET_BASE self
|
||||
@@ -1198,7 +1211,21 @@ do
|
||||
-- @param #SET_GROUP self
|
||||
-- @return #SET_GROUP self
|
||||
|
||||
|
||||
---Set Regex Options for FilterPrefix function.
|
||||
-- @function [parent=#SET_GROUP] FilterSetRegex
|
||||
-- @param #SET_GROUP self
|
||||
-- @param #boolean NoRegex If true, switch off Regex pattern matching for FilterPrefixes.
|
||||
-- @param #boolean ReplaceDash If false, switch off dash "-" replacement in strings for FilterPrefixes.
|
||||
-- @return #SET_GROUP self
|
||||
|
||||
--- Builds a set of objects of same coalitions.
|
||||
-- Possible current coalitions are red, blue and neutral.
|
||||
-- @function [parent=#SET_GROUP] FilterCoalitions
|
||||
-- @param #SET_GROUP self
|
||||
-- @param #string Coalitions Can take the following values: "red", "blue", "neutral" and coalition.side.RED, coalition.side.BLUE,coalition.side.NEUTRAL
|
||||
-- @param #boolean Clear If `true`, clear any previously defined filters.
|
||||
-- @return #SET_GROUP self
|
||||
|
||||
end
|
||||
|
||||
--- Get a *new* set table that only contains alive groups.
|
||||
@@ -2116,7 +2143,7 @@ do
|
||||
if self.Filter.GroupPrefixes and MGroupInclude then
|
||||
local MGroupPrefix = false
|
||||
for GroupPrefixId, GroupPrefix in pairs(self.Filter.GroupPrefixes) do
|
||||
if self:_SearchPattern(MGroup:GetName(), GroupPrefix, false, true) then
|
||||
if self:_SearchPattern(MGroup:GetName(), GroupPrefix, self.filterNoRegex, self.filterReplaceDash) then
|
||||
MGroupPrefix = true
|
||||
end
|
||||
end
|
||||
@@ -2337,6 +2364,26 @@ do -- SET_UNIT
|
||||
-- @param #SET_UNIT self
|
||||
-- @return #SET_UNIT self
|
||||
|
||||
--- Filter the set once
|
||||
-- @function [parent=#SET_UNIT] FilterOnce
|
||||
-- @param #SET_UNIT self
|
||||
-- @return #SET_UNIT self
|
||||
|
||||
---Set Regex Options for FilterPrefix function.
|
||||
-- @function [parent=#SET_UNIT] FilterSetRegex
|
||||
-- @param #SET_UNIT self
|
||||
-- @param #boolean NoRegex If true, switch off Regex pattern matching for FilterPrefixes.
|
||||
-- @param #boolean ReplaceDash If false, switch off dash "-" replacement in strings for FilterPrefixes.
|
||||
-- @return #SET_UNIT self
|
||||
|
||||
--- Builds a set of objects of same coalitions.
|
||||
-- Possible current coalitions are red, blue and neutral.
|
||||
-- @function [parent=#SET_UNIT] FilterCoalitions
|
||||
-- @param #SET_UNIT self
|
||||
-- @param #string Coalitions Can take the following values: "red", "blue", "neutral" and coalition.side.RED, coalition.side.BLUE,coalition.side.NEUTRAL
|
||||
-- @param #boolean Clear If `true`, clear any previously defined filters.
|
||||
-- @return #SET_UNIT self
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
@@ -3348,7 +3395,7 @@ do -- SET_UNIT
|
||||
if self.Filter.UnitPrefixes and MUnitInclude then
|
||||
local MUnitPrefix = false
|
||||
for UnitPrefixId, UnitPrefix in pairs(self.Filter.UnitPrefixes) do
|
||||
if self:_SearchPattern(MUnit:GetName(), UnitPrefix, false, true) then
|
||||
if self:_SearchPattern(MUnit:GetName(), UnitPrefix, self.filterNoRegex, self.filterReplaceDash) then
|
||||
MUnitPrefix = true
|
||||
end
|
||||
end
|
||||
@@ -3544,7 +3591,27 @@ do -- SET_STATIC
|
||||
|
||||
-- Inherits from BASE
|
||||
local self = BASE:Inherit(self, SET_BASE:New(_DATABASE.STATICS)) -- Core.Set#SET_STATIC
|
||||
|
||||
|
||||
--- Filter the set once
|
||||
-- @function [parent=#SET_STATIC] FilterOnce
|
||||
-- @param #SET_STATIC self
|
||||
-- @return #SET_STATIC self
|
||||
|
||||
---Set Regex Options for FilterPrefix function.
|
||||
-- @function [parent=#SET_STATIC] FilterSetRegex
|
||||
-- @param #SET_STATIC self
|
||||
-- @param #boolean NoRegex If true, switch off Regex pattern matching for FilterPrefixes.
|
||||
-- @param #boolean ReplaceDash If false, switch off dash "-" replacement in strings for FilterPrefixes.
|
||||
-- @return #SET_STATIC self
|
||||
|
||||
--- Builds a set of objects of same coalitions.
|
||||
-- Possible current coalitions are red, blue and neutral.
|
||||
-- @function [parent=#SET_STATIC] FilterCoalitions
|
||||
-- @param #SET_STATIC self
|
||||
-- @param #string Coalitions Can take the following values: "red", "blue", "neutral" and coalition.side.RED, coalition.side.BLUE,coalition.side.NEUTRAL
|
||||
-- @param #boolean Clear If `true`, clear any previously defined filters.
|
||||
-- @return #SET_STATIC self
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
@@ -4119,7 +4186,7 @@ do -- SET_STATIC
|
||||
if self.Filter.StaticPrefixes then
|
||||
local MStaticPrefix = false
|
||||
for StaticPrefixId, StaticPrefix in pairs(self.Filter.StaticPrefixes) do
|
||||
if self:_SearchPattern(MStatic:GetName(), StaticPrefix, false, true) then
|
||||
if self:_SearchPattern(MStatic:GetName(), StaticPrefix, self.filterNoRegex, self.filterReplaceDash) then
|
||||
MStaticPrefix = true
|
||||
end
|
||||
end
|
||||
@@ -4303,7 +4370,27 @@ do -- SET_CLIENT
|
||||
local self = BASE:Inherit(self, SET_BASE:New(_DATABASE.CLIENTS)) -- #SET_CLIENT
|
||||
|
||||
self:FilterActive(false)
|
||||
|
||||
|
||||
--- Filter the set once
|
||||
-- @function [parent=#SET_CLIENT] FilterOnce
|
||||
-- @param #SET_CLIENT self
|
||||
-- @return #SET_CLIENT self
|
||||
|
||||
---Set Regex Options for FilterPrefix function.
|
||||
-- @function [parent=#SET_CLIENT] FilterSetRegex
|
||||
-- @param #SET_CLIENT self
|
||||
-- @param #boolean NoRegex If true, switch off Regex pattern matching for FilterPrefixes.
|
||||
-- @param #boolean ReplaceDash If false, switch off dash "-" replacement in strings for FilterPrefixes.
|
||||
-- @return #SET_CLIENT self
|
||||
|
||||
--- Builds a set of objects of same coalitions.
|
||||
-- Possible current coalitions are red, blue and neutral.
|
||||
-- @function [parent=#SET_CLIENT] FilterCoalitions
|
||||
-- @param #SET_CLIENT self
|
||||
-- @param #string Coalitions Can take the following values: "red", "blue", "neutral" and coalition.side.RED, coalition.side.BLUE,coalition.side.NEUTRAL
|
||||
-- @param #boolean Clear If `true`, clear any previously defined filters.
|
||||
-- @return #SET_CLIENT self
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
@@ -4902,7 +4989,7 @@ do -- SET_CLIENT
|
||||
if self.Filter.ClientPrefixes and MClientInclude then
|
||||
local MClientPrefix = false
|
||||
for ClientPrefixId, ClientPrefix in pairs(self.Filter.ClientPrefixes) do
|
||||
if self:_SearchPattern(MClient.UnitName, ClientPrefix) then
|
||||
if self:_SearchPattern(MClient.UnitName, ClientPrefix, self.filterNoRegex, self.filterReplaceDash) then
|
||||
MClientPrefix = true
|
||||
end
|
||||
end
|
||||
@@ -4926,7 +5013,7 @@ do -- SET_CLIENT
|
||||
local playername = MClient:GetPlayerName() or "Unknown"
|
||||
--self:T(playername)
|
||||
for _,_Playername in pairs(self.Filter.Playernames) do
|
||||
if playername and self:_SearchPattern(playername,_Playername) then
|
||||
if playername and self:_SearchPattern(playername,_Playername,self.filterNoRegex, self.filterReplaceDash) then
|
||||
MClientPlayername = true
|
||||
end
|
||||
end
|
||||
@@ -4939,7 +5026,7 @@ do -- SET_CLIENT
|
||||
local callsign = MClient:GetCallsign()
|
||||
--self:I(callsign)
|
||||
for _,_Callsign in pairs(self.Filter.Callsigns) do
|
||||
if callsign and self:_SearchPattern(callsign,_Callsign, true) then
|
||||
if callsign and self:_SearchPattern(callsign,_Callsign, self.filterNoRegex, self.filterReplaceDash) then
|
||||
MClientCallsigns = true
|
||||
end
|
||||
end
|
||||
@@ -5360,7 +5447,7 @@ do -- SET_PLAYER
|
||||
if self.Filter.ClientPrefixes then
|
||||
local MClientPrefix = false
|
||||
for ClientPrefixId, ClientPrefix in pairs(self.Filter.ClientPrefixes) do
|
||||
if self:_SearchPattern(MClient.UnitName,ClientPrefix) then
|
||||
if self:_SearchPattern(MClient.UnitName,ClientPrefix,self.filterNoRegex, self.filterReplaceDash) then
|
||||
MClientPrefix = true
|
||||
end
|
||||
end
|
||||
@@ -5830,7 +5917,19 @@ do -- SET_ZONE
|
||||
function SET_ZONE:New()
|
||||
-- Inherits from BASE
|
||||
local self = BASE:Inherit(self, SET_BASE:New(_DATABASE.ZONES))
|
||||
|
||||
|
||||
--- Filter the set once
|
||||
-- @function [parent=#SET_ZONE] FilterOnce
|
||||
-- @param #SET_ZONE self
|
||||
-- @return #SET_ZONE self
|
||||
|
||||
---Set Regex Options for FilterPrefix function.
|
||||
-- @function [parent=#SET_ZONE] FilterSetRegex
|
||||
-- @param #SET_ZONE self
|
||||
-- @param #boolean NoRegex If true, switch off Regex pattern matching for FilterPrefixes.
|
||||
-- @param #boolean ReplaceDash If false, switch off dash "-" replacement in strings for FilterPrefixes.
|
||||
-- @return #SET_ZONE self
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
@@ -6068,7 +6167,7 @@ do -- SET_ZONE
|
||||
if self.Filter.Prefixes then
|
||||
local MZonePrefix = false
|
||||
for ZonePrefixId, ZonePrefix in pairs(self.Filter.Prefixes) do
|
||||
if self:_SearchPattern(MZoneName, ZonePrefix, false, true) then
|
||||
if self:_SearchPattern(MZoneName, ZonePrefix, self.filterNoRegex, self.filterReplaceDash) then
|
||||
MZonePrefix = true
|
||||
end
|
||||
end
|
||||
@@ -6577,7 +6676,7 @@ do -- SET_ZONE_GOAL
|
||||
if self.Filter.Prefixes then
|
||||
local MZonePrefix = false
|
||||
for ZonePrefixId, ZonePrefix in pairs(self.Filter.Prefixes) do
|
||||
if self:_SearchPattern(MZoneName, ZonePrefix, false, true) then
|
||||
if self:_SearchPattern(MZoneName, ZonePrefix, self.filterNoRegex, self.filterReplaceDash) then
|
||||
MZonePrefix = true
|
||||
end
|
||||
end
|
||||
@@ -6713,7 +6812,19 @@ do -- SET_OPSZONE
|
||||
|
||||
-- Inherits from BASE
|
||||
local self = BASE:Inherit(self, SET_BASE:New(_DATABASE.OPSZONES))
|
||||
|
||||
|
||||
--- Filter the set once
|
||||
-- @function [parent=#SET_OPSZONE] FilterOnce
|
||||
-- @param #SET_OPSZONE self
|
||||
-- @return #SET_OPSZONE self
|
||||
|
||||
---Set Regex Options for FilterPrefix function.
|
||||
-- @function [parent=#SET_OPSZONE] FilterSetRegex
|
||||
-- @param #SET_OPSZONE self
|
||||
-- @param #boolean NoRegex If true, switch off Regex pattern matching for FilterPrefixes.
|
||||
-- @param #boolean ReplaceDash If false, switch off dash "-" replacement in strings for FilterPrefixes.
|
||||
-- @return #SET_OPSZONE self
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
@@ -6938,7 +7049,7 @@ do -- SET_OPSZONE
|
||||
for ZonePrefixId, ZonePrefix in pairs(self.Filter.Prefixes) do
|
||||
|
||||
-- Prefix
|
||||
if self:_SearchPattern(MZoneName, ZonePrefix, false, true) then
|
||||
if self:_SearchPattern(MZoneName, ZonePrefix, self.filterNoRegex, self.filterReplaceDash) then
|
||||
MZonePrefix = true
|
||||
break --Break the loop as we found the prefix.
|
||||
end
|
||||
@@ -7732,7 +7843,7 @@ function SET_OPSGROUP:_EventOnBirth(Event)
|
||||
local MGroupPrefix = false
|
||||
|
||||
for GroupPrefixId, GroupPrefix in pairs(self.Filter.GroupPrefixes) do
|
||||
if self:_SearchPattern(MGroup:GetName(), GroupPrefix, false, true) then
|
||||
if self:_SearchPattern(MGroup:GetName(), GroupPrefix, self.filterNoRegex, self.filterReplaceDash) then
|
||||
MGroupPrefix = true
|
||||
end
|
||||
end
|
||||
@@ -8066,7 +8177,7 @@ do -- SET_SCENERY
|
||||
if self.Filter.Prefixes then
|
||||
local MSceneryPrefix = false
|
||||
for ZonePrefixId, ZonePrefix in pairs(self.Filter.Prefixes) do
|
||||
if self:_SearchPattern(MSceneryName, ZonePrefix, false, true) then
|
||||
if self:_SearchPattern(MSceneryName, ZonePrefix, self.filterNoRegex, self.filterReplaceDash) then
|
||||
MSceneryPrefix = true
|
||||
end
|
||||
end
|
||||
@@ -8289,7 +8400,19 @@ do -- SET_DYNAMICCARGO
|
||||
|
||||
--- Inherits from BASE
|
||||
local self = BASE:Inherit(self, SET_BASE:New(_DATABASE.DYNAMICCARGO)) -- Core.Set#SET_DYNAMICCARGO
|
||||
|
||||
|
||||
--- Filter the set once
|
||||
-- @function [parent=#SET_DYNAMICCARGO] FilterOnce
|
||||
-- @param #SET_DYNAMICCARGO self
|
||||
-- @return #SET_DYNAMICCARGO self
|
||||
|
||||
---Set Regex Options for FilterPrefix function.
|
||||
-- @function [parent=#SET_DYNAMICCARGO] FilterSetRegex
|
||||
-- @param #SET_DYNAMICCARGO self
|
||||
-- @param #boolean NoRegex If true, switch off Regex pattern matching for FilterPrefixes.
|
||||
-- @param #boolean ReplaceDash If false, switch off dash "-" replacement in strings for FilterPrefixes.
|
||||
-- @return #SET_DYNAMICCARGO self
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
@@ -8337,7 +8460,7 @@ do -- SET_DYNAMICCARGO
|
||||
if self.Filter.StaticPrefixes then
|
||||
local DCargoPrefix = false
|
||||
for StaticPrefixId, StaticPrefix in pairs(self.Filter.StaticPrefixes) do
|
||||
if self:_SearchPattern(DCargo:GetName(), StaticPrefix, false, true) then
|
||||
if self:_SearchPattern(DCargo:GetName(), StaticPrefix, self.filterNoRegex, self.filterReplaceDash) then
|
||||
DCargoPrefix = true
|
||||
end
|
||||
end
|
||||
@@ -8505,7 +8628,7 @@ do -- SET_DYNAMICCARGO
|
||||
function SET_DYNAMICCARGO:FilterCurrentOwner(PlayerName)
|
||||
self:FilterFunction(
|
||||
function(cargo)
|
||||
if cargo and cargo.Owner and self:_SearchPattern(cargo.Owner, PlayerName, true) then
|
||||
if cargo and cargo.Owner and self:_SearchPattern(cargo.Owner, PlayerName, self.filterNoRegex, self.filterReplaceDash) then
|
||||
return true
|
||||
else
|
||||
return false
|
||||
|
||||
@@ -1184,6 +1184,7 @@ end
|
||||
|
||||
--- This method provides the functionality to randomize the spawning of the Groups at a given list of zones of different types.
|
||||
-- @param #SPAWN self
|
||||
-- @param #table SpawnZoneTable A table with @{Core.Zone} objects. If nil or empty, the method returns self without effect.
|
||||
-- @param #table SpawnZoneTable A table with @{Core.Zone} objects. If this table is given, then each spawn will be executed within the given list of @{Core.Zone}s objects.
|
||||
-- @param #boolean RandomizePositionInZone If nil or true, also the position inside the selected random zone will be randomized. Set to false to use the center of the zone.
|
||||
-- @return #SPAWN self
|
||||
@@ -1201,6 +1202,9 @@ end
|
||||
function SPAWN:InitRandomizeZones( SpawnZoneTable, RandomizePositionInZone )
|
||||
--self:F( { self.SpawnTemplatePrefix, SpawnZoneTable } )
|
||||
|
||||
if not SpawnZoneTable then
|
||||
return self
|
||||
end
|
||||
local temptable = {}
|
||||
for _,_temp in pairs(SpawnZoneTable) do
|
||||
temptable[#temptable+1] = _temp
|
||||
@@ -2149,6 +2153,7 @@ function SPAWN:SpawnAtAirbase( SpawnAirbase, Takeoff, TakeoffAltitude, TerminalT
|
||||
local parkingspots = {}
|
||||
local parkingindex = {}
|
||||
local spots
|
||||
local useexplicitspots = false
|
||||
|
||||
-- Spawn happens on ground, i.e. at an airbase, a FARP or a ship.
|
||||
if spawnonground and not SpawnTemplate.parked then
|
||||
@@ -2178,15 +2183,41 @@ function SPAWN:SpawnAtAirbase( SpawnAirbase, Takeoff, TakeoffAltitude, TerminalT
|
||||
local scanscenery = false
|
||||
local verysafe = false
|
||||
|
||||
-- Use exact parking data when provided, otherwise let helicopters on ships/FARPs
|
||||
-- use the smarter parking search before falling back to the procedural queue path.
|
||||
-- Number of free parking spots at the airbase.
|
||||
if autoparking then
|
||||
if Parkingdata~=nil then
|
||||
-- Parking data explicitly set by user as input parameter.
|
||||
nfree = #Parkingdata
|
||||
spots = Parkingdata
|
||||
useexplicitspots = true
|
||||
elseif autoparking and AirbaseCategory == Airbase.Category.HELIPAD and ishelo then
|
||||
if termtype == nil then
|
||||
-- Helo is spawned. Try exclusive helo spots first.
|
||||
spots = SpawnAirbase:FindFreeParkingSpotForAircraft( group, AIRBASE.TerminalType.HelicopterOnly, scanradius, scanunits, scanstatics, scanscenery, verysafe, nunits, nil )
|
||||
nfree = #spots
|
||||
if nfree < nunits then
|
||||
-- Not enough helo ports. Let's try also other terminal types.
|
||||
spots = SpawnAirbase:FindFreeParkingSpotForAircraft( group, AIRBASE.TerminalType.HelicopterUsable, scanradius, scanunits, scanstatics, scanscenery, verysafe, nunits, nil )
|
||||
nfree = #spots
|
||||
end
|
||||
else
|
||||
-- Terminal type explicitly given.
|
||||
spots = SpawnAirbase:FindFreeParkingSpotForAircraft( group, termtype, scanradius, scanunits, scanstatics, scanscenery, verysafe, nunits, nil )
|
||||
nfree = #spots
|
||||
end
|
||||
|
||||
if nfree >= nunits then
|
||||
useexplicitspots = true
|
||||
else
|
||||
-- These places work procedural and have some kind of build in queue ==> Less effort.
|
||||
nfree = SpawnAirbase:GetFreeParkingSpotsNumber( termtype, true )
|
||||
spots = SpawnAirbase:GetFreeParkingSpotsTable( termtype, true )
|
||||
end
|
||||
elseif autoparking then
|
||||
-- These places work procedural and have some kind of build in queue ==> Less effort.
|
||||
nfree = SpawnAirbase:GetFreeParkingSpotsNumber( termtype, true )
|
||||
spots = SpawnAirbase:GetFreeParkingSpotsTable( termtype, true )
|
||||
elseif Parkingdata~=nil then
|
||||
-- Parking data explicitly set by user as input parameter. (This was commented out for some unknown reason. But I need it this way.)
|
||||
nfree=#Parkingdata
|
||||
spots=Parkingdata
|
||||
else
|
||||
if ishelo then
|
||||
if termtype == nil then
|
||||
@@ -2238,7 +2269,7 @@ function SPAWN:SpawnAtAirbase( SpawnAirbase, Takeoff, TakeoffAltitude, TerminalT
|
||||
local _notenough = false
|
||||
|
||||
-- Need to differentiate some cases again.
|
||||
if autoparking then
|
||||
if autoparking and not useexplicitspots then
|
||||
|
||||
-- On free spot required in these cases.
|
||||
if nfree >= 1 then
|
||||
@@ -2271,6 +2302,10 @@ function SPAWN:SpawnAtAirbase( SpawnAirbase, Takeoff, TakeoffAltitude, TerminalT
|
||||
end
|
||||
end
|
||||
|
||||
if useexplicitspots and parkingspots[1] then
|
||||
PointVec3 = parkingspots[1]
|
||||
end
|
||||
|
||||
-- Not enough spots ==> Prepare airstart.
|
||||
if _notenough then
|
||||
|
||||
@@ -2296,9 +2331,15 @@ function SPAWN:SpawnAtAirbase( SpawnAirbase, Takeoff, TakeoffAltitude, TerminalT
|
||||
|
||||
Takeoff = GROUP.Takeoff.Air
|
||||
spawnonground = false
|
||||
else
|
||||
else
|
||||
if not Takeoff == GROUP.Takeoff.Runway then
|
||||
self:E( string.format( "WARNING: Group %s has no parking spots at %s ==> No emergency air start or uncontrolled spawning ==> No spawn!", self.SpawnTemplatePrefix, SpawnAirbase:GetName() ) )
|
||||
return nil
|
||||
else
|
||||
Takeoff = GROUP.Takeoff.Runway
|
||||
spawnonground = false
|
||||
self:E( string.format( "WARNING: Group %s set to runway spawning at %s, this only works in Single Player!", self.SpawnTemplatePrefix, SpawnAirbase:GetName() ) )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -2339,7 +2380,7 @@ function SPAWN:SpawnAtAirbase( SpawnAirbase, Takeoff, TakeoffAltitude, TerminalT
|
||||
if spawnonground then
|
||||
|
||||
-- Ships and FARPS seem to have a build in queue.
|
||||
if autoparking then
|
||||
if autoparking and not useexplicitspots then
|
||||
|
||||
-- Spawn on ship. We take only the position of the ship.
|
||||
SpawnTemplate.units[UnitID].x = PointVec3.x -- TX
|
||||
@@ -2357,7 +2398,7 @@ function SPAWN:SpawnAtAirbase( SpawnAirbase, Takeoff, TakeoffAltitude, TerminalT
|
||||
|
||||
else
|
||||
|
||||
-- Spawn in air as requested initially. Original template orientation is perserved, altitude is already correctly set.
|
||||
-- Spawn in air as requested initially. Original template orientation is preserved, altitude is already correctly set.
|
||||
SpawnTemplate.units[UnitID].x = TX
|
||||
SpawnTemplate.units[UnitID].y = TY
|
||||
SpawnTemplate.units[UnitID].alt = PointVec3.y
|
||||
@@ -2390,7 +2431,7 @@ function SPAWN:SpawnAtAirbase( SpawnAirbase, Takeoff, TakeoffAltitude, TerminalT
|
||||
if Takeoff == GROUP.Takeoff.Air then
|
||||
for UnitID, UnitSpawned in pairs( GroupSpawned:GetUnits() ) do
|
||||
--SCHEDULER:New( nil, BASE.CreateEventTakeoff, { GroupSpawned, timer.getTime(), UnitSpawned:GetDCSObject() }, 5 ) --No need to create a new SCHEDULER instance every time!
|
||||
self:ScheduleOnce(5, BASE.CreateEventTakeoff, {GroupSpawned, timer.getTime(), UnitSpawned:GetDCSObject()})
|
||||
self:ScheduleOnce(5, BASE.CreateEventTakeoff, GroupSpawned, timer.getTime(), UnitSpawned:GetDCSObject())
|
||||
end
|
||||
end
|
||||
|
||||
@@ -2582,21 +2623,51 @@ function SPAWN:ParkAircraft( SpawnAirbase, TerminalType, Parkingdata, SpawnIndex
|
||||
local scanscenery = false
|
||||
local verysafe = false
|
||||
|
||||
-- Number of free parking spots at the airbase.
|
||||
if spawnonship or spawnonfarp or spawnonrunway then
|
||||
-- These places work procedural and have some kind of build in queue ==> Less effort.
|
||||
--self:T2( string.format( "Group %s is spawned on farp/ship/runway %s.", self.SpawnTemplatePrefix, SpawnAirbase:GetName() ) )
|
||||
nfree = SpawnAirbase:GetFreeParkingSpotsNumber( termtype, true )
|
||||
spots = SpawnAirbase:GetFreeParkingSpotsTable( termtype, true )
|
||||
--[[
|
||||
elseif Parkingdata~=nil then
|
||||
-- Parking data explicitly set by user as input parameter.
|
||||
nfree=#Parkingdata
|
||||
spots=Parkingdata
|
||||
]]
|
||||
else
|
||||
if ishelo then
|
||||
-- Use exact parking data when provided, otherwise let helicopters on FARPs
|
||||
-- use the smarter parking search before falling back to the procedural queue path.
|
||||
local useexplicitspots = false
|
||||
|
||||
-- Number of free parking spots at the airbase.
|
||||
if Parkingdata~=nil then
|
||||
-- Parking data explicitly set by user as input parameter.
|
||||
nfree = #Parkingdata
|
||||
spots = Parkingdata
|
||||
useexplicitspots = true
|
||||
elseif spawnonfarp and ishelo then
|
||||
if termtype == nil then
|
||||
-- Helo is spawned. Try exclusive helo spots first.
|
||||
--self:T2( string.format( "Helo group %s is at %s using terminal type %d.", self.SpawnTemplatePrefix, SpawnAirbase:GetName(), AIRBASE.TerminalType.HelicopterOnly ) )
|
||||
spots = SpawnAirbase:FindFreeParkingSpotForAircraft( TemplateGroup, AIRBASE.TerminalType.HelicopterOnly, scanradius, scanunits, scanstatics, scanscenery, verysafe, nunits, nil )
|
||||
nfree = #spots
|
||||
if nfree < nunits then
|
||||
-- Not enough helo ports. Let's try also other terminal types.
|
||||
--self:T2( string.format( "Helo group %s is at %s using terminal type %d.", self.SpawnTemplatePrefix, SpawnAirbase:GetName(), AIRBASE.TerminalType.HelicopterUsable ) )
|
||||
spots = SpawnAirbase:FindFreeParkingSpotForAircraft( TemplateGroup, AIRBASE.TerminalType.HelicopterUsable, scanradius, scanunits, scanstatics, scanscenery, verysafe, nunits, nil )
|
||||
nfree = #spots
|
||||
end
|
||||
else
|
||||
-- Terminal type explicitly given.
|
||||
--self:T2( string.format( "Helo group %s is at %s using terminal type %d.", self.SpawnTemplatePrefix, SpawnAirbase:GetName(), termtype ) )
|
||||
spots = SpawnAirbase:FindFreeParkingSpotForAircraft( TemplateGroup, termtype, scanradius, scanunits, scanstatics, scanscenery, verysafe, nunits, nil )
|
||||
nfree = #spots
|
||||
end
|
||||
|
||||
if nfree >= nunits then
|
||||
useexplicitspots = true
|
||||
else
|
||||
-- These places work procedural and have some kind of build in queue ==> Less effort.
|
||||
--self:T2( string.format( "Group %s is spawned on farp %s using procedural spots.", self.SpawnTemplatePrefix, SpawnAirbase:GetName() ) )
|
||||
nfree = SpawnAirbase:GetFreeParkingSpotsNumber( termtype, true )
|
||||
spots = SpawnAirbase:GetFreeParkingSpotsTable( termtype, true )
|
||||
end
|
||||
elseif spawnonship or spawnonfarp or spawnonrunway then
|
||||
-- These places work procedural and have some kind of build in queue ==> Less effort.
|
||||
--self:T2( string.format( "Group %s is spawned on farp/ship/runway %s.", self.SpawnTemplatePrefix, SpawnAirbase:GetName() ) )
|
||||
nfree = SpawnAirbase:GetFreeParkingSpotsNumber( termtype, true )
|
||||
spots = SpawnAirbase:GetFreeParkingSpotsTable( termtype, true )
|
||||
else
|
||||
if ishelo then
|
||||
if termtype == nil then
|
||||
-- Helo is spawned. Try exclusive helo spots first.
|
||||
--self:T2( string.format( "Helo group %s is at %s using terminal type %d.", self.SpawnTemplatePrefix, SpawnAirbase:GetName(), AIRBASE.TerminalType.HelicopterOnly ) )
|
||||
spots = SpawnAirbase:FindFreeParkingSpotForAircraft( TemplateGroup, AIRBASE.TerminalType.HelicopterOnly, scanradius, scanunits, scanstatics, scanscenery, verysafe, nunits, Parkingdata )
|
||||
@@ -2659,7 +2730,7 @@ function SPAWN:ParkAircraft( SpawnAirbase, TerminalType, Parkingdata, SpawnIndex
|
||||
local _notenough = false
|
||||
|
||||
-- Need to differentiate some cases again.
|
||||
if spawnonship or spawnonfarp or spawnonrunway then
|
||||
if (spawnonship or spawnonfarp or spawnonrunway) and not useexplicitspots then
|
||||
|
||||
-- On free spot required in these cases.
|
||||
if nfree >= 1 then
|
||||
|
||||
@@ -87,7 +87,8 @@ do -- world
|
||||
-- @field S_EVENT_SIMULATION_UNFREEZE = 58
|
||||
-- @field S_EVENT_HUMAN_AIRCRAFT_REPAIR_START = 59
|
||||
-- @field S_EVENT_HUMAN_AIRCRAFT_REPAIR_FINISH = 60
|
||||
-- @field S_EVENT_MAX = 61
|
||||
-- @field S_EVENT_GROUP_CHANGE_OPTION = 61
|
||||
-- @field S_EVENT_MAX = 62
|
||||
|
||||
--- The birthplace enumerator is used to define where an aircraft or helicopter has spawned in association with birth events.
|
||||
-- @type world.BirthPlace
|
||||
|
||||
@@ -1848,7 +1848,7 @@ do -- DETECTION_BASE
|
||||
return self
|
||||
end
|
||||
|
||||
--- Validate if the detected item is locked.
|
||||
--- Validate if the detected item is locked (not in the radar sense, though!).
|
||||
-- @param #DETECTION_BASE self
|
||||
-- @param #DETECTION_BASE.DetectedItem DetectedItem The DetectedItem.
|
||||
-- @return #boolean
|
||||
@@ -1858,7 +1858,7 @@ do -- DETECTION_BASE
|
||||
|
||||
end
|
||||
|
||||
--- Lock a detected item.
|
||||
--- Lock a detected item (not in the radar sense, though!).
|
||||
-- @param #DETECTION_BASE self
|
||||
-- @param #DETECTION_BASE.DetectedItem DetectedItem The DetectedItem.
|
||||
-- @return #DETECTION_BASE
|
||||
@@ -1869,7 +1869,7 @@ do -- DETECTION_BASE
|
||||
return self
|
||||
end
|
||||
|
||||
--- Unlock a detected item.
|
||||
--- Unlock a detected item (not in the radar sense, though!).
|
||||
-- @param #DETECTION_BASE self
|
||||
-- @param #DETECTION_BASE.DetectedItem DetectedItem The DetectedItem.
|
||||
-- @return #DETECTION_BASE
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -795,15 +795,20 @@ do
|
||||
local tgtgrp1 = self.Samset:FindNearestGroupFromPointVec2(tgtcoord)
|
||||
local tgtcoord1 = tgtgrp1:GetCoordinate()
|
||||
local tgtgrp2 = self.Groupset:FindNearestGroupFromPointVec2(tgtcoord)
|
||||
local tgtcoord2 = tgtgrp2:GetCoordinate()
|
||||
local dist1 = tgtcoord:Get2DDistance(tgtcoord1)
|
||||
local dist2 = tgtcoord:Get2DDistance(tgtcoord2)
|
||||
|
||||
if dist1 < dist2 then
|
||||
targetunit = tgtgrp1
|
||||
targetcat = Object.Category.UNIT
|
||||
if tgtgrp2 then
|
||||
local tgtcoord2 = tgtgrp2:GetCoordinate()
|
||||
local dist1 = tgtcoord:Get2DDistance(tgtcoord1)
|
||||
local dist2 = tgtcoord:Get2DDistance(tgtcoord2)
|
||||
|
||||
if dist1 < dist2 then
|
||||
targetunit = tgtgrp1
|
||||
targetcat = Object.Category.UNIT
|
||||
else
|
||||
targetunit = tgtgrp2
|
||||
targetcat = Object.Category.UNIT
|
||||
end
|
||||
else
|
||||
targetunit = tgtgrp2
|
||||
targetunit = tgtgrp1
|
||||
targetcat = Object.Category.UNIT
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1485,7 +1485,7 @@ function SUPPRESSION:onafterStop(Controllable, From, Event, To)
|
||||
|
||||
local text=string.format("Stopping SUPPRESSION for group %s", self.Controllable:GetName())
|
||||
MESSAGE:New(text, 10):ToAllIf(self.Debug)
|
||||
sefl:T(self.lid..text)
|
||||
self:T(self.lid..text)
|
||||
|
||||
-- Clear all pending schedules
|
||||
self.CallScheduler:Clear()
|
||||
|
||||
@@ -4097,7 +4097,7 @@ function WAREHOUSE:_RegisterAsset(group, ngroups, forceattribute, forcecargobay,
|
||||
-- Get name of template group.
|
||||
local templategroupname=group:GetName()
|
||||
local unit = group:GetUnit(1)
|
||||
local Descriptors= (unit and unit:IsAlive()) and unit:GetDesc() or {}
|
||||
local Descriptors= (unit and unit:IsAlive()~=nil) and unit:GetDesc() or {}
|
||||
local Category=group:GetCategory()
|
||||
local TypeName=group:GetTypeName() or "none"
|
||||
local SpeedMax=group:GetSpeedMax()
|
||||
@@ -4115,7 +4115,7 @@ function WAREHOUSE:_RegisterAsset(group, ngroups, forceattribute, forcecargobay,
|
||||
for _i,_unit in pairs(group:GetUnits()) do
|
||||
local unit=_unit --Wrapper.Unit#UNIT
|
||||
local Desc=unit:GetDesc()
|
||||
|
||||
|
||||
-- Weight. We sum up all units in the group.
|
||||
local unitweight=forceweight or Desc.massEmpty
|
||||
if unitweight then
|
||||
|
||||
@@ -115,6 +115,7 @@ __Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Ops/Squadron.lua' )
|
||||
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Ops/Target.lua' )
|
||||
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Ops/EasyGCICAP.lua' )
|
||||
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Ops/EasyA2G.lua' )
|
||||
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Ops/TARS.lua' )
|
||||
|
||||
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Shapes/ShapeBase.lua' )
|
||||
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Shapes/Circle.lua' )
|
||||
|
||||
@@ -2717,17 +2717,27 @@ function AIRBOSS:DeleteRecoveryWindow( Window, Delay )
|
||||
self:ScheduleOnce( Delay, self.DeleteRecoveryWindow, self, Window )
|
||||
else
|
||||
|
||||
for i, _recovery in pairs( self.recoverytimes ) do
|
||||
local recovery = _recovery -- #AIRBOSS.Recovery
|
||||
if not Window then
|
||||
return
|
||||
end
|
||||
|
||||
if Window and Window.ID == recovery.ID then
|
||||
if Window.OPEN then
|
||||
-- Window is currently open.
|
||||
self:RecoveryStop()
|
||||
else
|
||||
table.remove( self.recoverytimes, i )
|
||||
end
|
||||
-- If this window is currently open, stop recovery first. Mark it OVER so the
|
||||
-- recovery time check cannot re-open it before/while we remove it.
|
||||
if Window.OPEN then
|
||||
Window.OPEN = false
|
||||
Window.OVER = true
|
||||
if self:IsRecovering() then
|
||||
self:RecoveryStop()
|
||||
end
|
||||
end
|
||||
|
||||
-- Remove the window from the queue by its unique ID. Iterate over a numerically
|
||||
-- indexed copy of the keys and remove via ipairs-safe reverse loop so that the
|
||||
-- removal does not corrupt traversal (the window may appear once).
|
||||
for i = #self.recoverytimes, 1, -1 do
|
||||
local recovery = self.recoverytimes[i] -- #AIRBOSS.Recovery
|
||||
if recovery and recovery.ID == Window.ID then
|
||||
table.remove( self.recoverytimes, i )
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -4078,15 +4088,23 @@ function AIRBOSS:_CheckRecoveryTimes()
|
||||
if self:IsRecovering() then
|
||||
-- Carrier is already recovering.
|
||||
state = "in progress"
|
||||
else
|
||||
-- Start recovery.
|
||||
elseif not recovery.OVER then
|
||||
-- Start recovery. Only if the window has not already been closed/cancelled.
|
||||
-- The OVER guard prevents a window that was stopped manually (e.g. via the
|
||||
-- Skipper "Stop Recovery" menu) from being immediately re-opened on the next
|
||||
-- status tick while its [START,STOP) range is still active.
|
||||
self:RecoveryStart( recovery.CASE, recovery.OFFSET )
|
||||
state = "starting now"
|
||||
recovery.OPEN = true
|
||||
else
|
||||
-- Window was already closed/cancelled within its active time range.
|
||||
state = "cancelled"
|
||||
end
|
||||
|
||||
-- Set current recovery window.
|
||||
currwindow = recovery
|
||||
-- Set current recovery window (unless this window has been cancelled).
|
||||
if not recovery.OVER then
|
||||
currwindow = recovery
|
||||
end
|
||||
|
||||
else -- Stop time HAS passed.
|
||||
|
||||
@@ -4183,13 +4201,16 @@ function AIRBOSS:_CheckRecoveryTimes()
|
||||
-- Time into the wind 1 day or if longer recovery time + the 5 min early.
|
||||
local t = math.max( nextwindow.STOP - nextwindow.START + self.dTturn, 60 * 60 * 24 )
|
||||
|
||||
-- Recovery wind on deck in knots.
|
||||
-- Recovery wind on deck in knots.
|
||||
-- NOTE: Do NOT clamp the desired wind-over-deck (WOD) to the carrier's max hull
|
||||
-- speed here. WOD = carrier speed + headwind, so a WOD target above the hull's
|
||||
-- top speed is achievable whenever there is wind. CarrierTurnIntoWind ->
|
||||
-- GetHeadingIntoWind already converts the WOD target into the required hull
|
||||
-- speed and caps THAT at the carrier's max speed (Vmax) internally. Clamping the
|
||||
-- WOD target itself capped achievable WOD at ~30 kts (the supercarrier's max
|
||||
-- hull speed) even in strong wind, which made high-WOD recovery windows fall
|
||||
-- short of their requested value.
|
||||
local v = UTILS.KnotsToMps( nextwindow.SPEED )
|
||||
|
||||
-- Check that we do not go above max possible speed.
|
||||
local vmax = self.carrier:GetSpeedMax() / 3.6 -- convert to m/s
|
||||
v = math.min( v, vmax )
|
||||
|
||||
-- Route carrier into the wind. Sets self.turnintowind=true
|
||||
self:CarrierTurnIntoWind( t, v, uturn )
|
||||
|
||||
@@ -4361,11 +4382,20 @@ function AIRBOSS:onafterRecoveryStop( From, Event, To )
|
||||
self:CarrierResumeRoute( coord )
|
||||
end
|
||||
|
||||
-- Delete current recovery window if open.
|
||||
if self.recoverywindow and self.recoverywindow.OPEN == true then
|
||||
-- Mark the current recovery window closed and cancelled, then remove it from the
|
||||
-- queue. We do NOT gate this on Window.OPEN: that flag is only set by
|
||||
-- _CheckRecoveryTimes (not by RecoveryStart), and the recovery time check nils and
|
||||
-- rebuilds self.recoverywindow every status tick, so OPEN is not a reliable signal
|
||||
-- here. Setting OVER=true is what actually prevents the window from being re-opened
|
||||
-- on the next tick while its [START,STOP) range is still active.
|
||||
--
|
||||
-- The removal is deferred by one tick (Delay>0) so it does not mutate the
|
||||
-- recoverytimes table while _CheckRecoveryTimes may be iterating over it (the natural
|
||||
-- close path calls RecoveryStop() from inside that loop).
|
||||
if self.recoverywindow then
|
||||
self.recoverywindow.OPEN = false
|
||||
self.recoverywindow.OVER = true
|
||||
self:DeleteRecoveryWindow( self.recoverywindow )
|
||||
self:DeleteRecoveryWindow( self.recoverywindow, 1 )
|
||||
end
|
||||
|
||||
-- Check recovery windows. This sets self.recoverywindow to the next window.
|
||||
@@ -12903,6 +12933,14 @@ function AIRBOSS:_LSOgrade( playerData )
|
||||
-- Circuit edit only take points awary from a 1 wire if there are more than 4 other deviations
|
||||
if playerData.wire == 1 and points >= 3 and N > 4 then
|
||||
points = points -1
|
||||
-- We also need to change the grade based on the new points.
|
||||
if points == 4 then
|
||||
grade = "OK"
|
||||
elseif points == 3 then
|
||||
grade = "(OK)"
|
||||
elseif points == 2 then
|
||||
grade = "--"
|
||||
end
|
||||
end
|
||||
|
||||
env.info("Returning: " .. grade .. " " .. points .. " " .. G)
|
||||
|
||||
@@ -6610,7 +6610,7 @@ function AUFTRAG:GetDCSMissionTask(MissionGroup)
|
||||
local SeadUnitSet = SET_UNIT:New()
|
||||
for _,_unit in pairs (ScanUnitSet.Set) do
|
||||
local unit = _unit -- Wrapper.Unit#UNTI
|
||||
if unit and unit:IsAlive() and unit:HasSEAD() then
|
||||
if unit and unit:IsAlive() and unit.HasSEAD and unit:HasSEAD() then
|
||||
self:T("Adding UNIT for SEAD: "..unit:GetName())
|
||||
local task = CONTROLLABLE.TaskAttackUnit(nil,unit,GroupAttack,AI.Task.WeaponExpend.ALL,1,Direction,self.engageAltitude,2956984318)
|
||||
table.insert(DCStasks, task)
|
||||
|
||||
@@ -504,6 +504,9 @@ CSAR.AircraftType["OH58D"] = 2
|
||||
CSAR.AircraftType["CH-47Fbl1"] = 31
|
||||
CSAR.AircraftType["AH-6J"] = 2
|
||||
CSAR.AircraftType["MH-6J"] = 2
|
||||
CSAR.AircraftType["Ka-50_3"] = 0
|
||||
CSAR.AircraftType["Ka-50"] = 0
|
||||
CSAR.AircraftType["AV8BNA"] = 0
|
||||
|
||||
--- CSAR class version.
|
||||
-- @field #string version
|
||||
@@ -2538,8 +2541,11 @@ function CSAR:_AddMedevacMenuItem()
|
||||
if _unit then
|
||||
--self:T("Unitname ".._unit:GetName().." IsAlive "..tostring(_unit:IsAlive()).." IsPlayer "..tostring(_unit:IsPlayer()))
|
||||
if _unit:IsAlive() and _unit:IsPlayer() then
|
||||
local unitName = _unit:GetName()
|
||||
_UnitList[unitName] = unitName
|
||||
local _maxUnits = self.AircraftType[_unit:GetTypeName()]
|
||||
if _maxUnits == nil or _maxUnits > 0 then
|
||||
local unitName = _unit:GetName()
|
||||
_UnitList[unitName] = unitName
|
||||
end
|
||||
end -- end isAlive
|
||||
end -- end if _unit
|
||||
end -- end for
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -21,7 +21,7 @@
|
||||
--
|
||||
-------------------------------------------------------------------------
|
||||
-- Date: September 2023
|
||||
-- Last Update: Mar 2026
|
||||
-- Last Update: June 2026
|
||||
-------------------------------------------------------------------------
|
||||
--
|
||||
--- **Ops** - Easy GCI & CAP Manager
|
||||
@@ -135,6 +135,7 @@
|
||||
-- local mywing = EASYGCICAP:New("Blue CAP Operations",AIRBASE.Caucasus.Kutaisi,"blue","Blue EWR")
|
||||
--
|
||||
-- -- Add a CAP patrol point belonging to our airbase, we'll be at 30k ft doing 400 kn, initial direction 90 degrees (East), leg 20NM
|
||||
-- -- NOTE - Skip this function and do not create CAP Points if you want GCI behaviour only.
|
||||
-- mywing:AddPatrolPointCAP(AIRBASE.Caucasus.Kutaisi,ZONE:FindByName("Blue Zone 1"):GetCoordinate(),30000,400,90,20)
|
||||
--
|
||||
-- -- Add a Squadron with template "Blue Sq1 M2000c", 20 airframes, skill good, Modex starting with 102 and skin "Vendee Jeanne"
|
||||
@@ -190,9 +191,10 @@
|
||||
-- * @{#EASYGCICAP.SetDefaultResurrection}: Set how many seconds the AirWing stays inoperable after the AirWing STATIC HQ ist destroyed, default 900 secs.
|
||||
-- * @{#EASYGCICAP.SetDefaultCAPSpeed}: Set how many knots the CAP flights should do (will be altitude corrected), default 300 kn.
|
||||
-- * @{#EASYGCICAP.SetDefaultCAPAlt}: Set at which altitude (ASL) the CAP planes will fly, default 25,000 ft.
|
||||
-- * @{#EASYGCICAP.SetDefaultINTERCEPTAlt}: Set at which altitude (ASL) the Intercept planes will fly, default 25,000 ft.
|
||||
-- * @{#EASYGCICAP.SetDefaultCAPDirection}: Set the initial direction from the CAP point the planes will fly in degrees, default is 90°.
|
||||
-- * @{#EASYGCICAP.SetDefaultCAPLeg}: Set the length of the CAP leg, default is 15 NM.
|
||||
-- * @{#EASYGCICAP.SetDefaultCAPGrouping}: Set how many planes will be spawned per mission (CVAP/GCI), defaults to 2.
|
||||
-- * @{#EASYGCICAP.SetDefaultCAPGrouping}: Set how many planes will be spawned per mission (CAP/GCI), defaults to 2.
|
||||
-- * @{#EASYGCICAP.SetDefaultMissionRange}: Set how many NM the planes can go from the home base, defaults to 100.
|
||||
-- * @{#EASYGCICAP.SetDefaultNumberAlert5Standby}: Set how many planes will be spawned on cold standby (Alert5), default 2.
|
||||
-- * @{#EASYGCICAP.SetDefaultEngageRange}: Set max engage range for CAP flights if they detect intruders, defaults to 50.
|
||||
@@ -286,7 +288,7 @@ EASYGCICAP = {
|
||||
|
||||
--- EASYGCICAP class version.
|
||||
-- @field #string version
|
||||
EASYGCICAP.version="0.1.35"
|
||||
EASYGCICAP.version="0.1.38"
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
--
|
||||
@@ -587,6 +589,17 @@ function EASYGCICAP:SetDefaultCAPAlt(Altitude)
|
||||
return self
|
||||
end
|
||||
|
||||
--- Set default INTERCEPT Altitude in feet
|
||||
-- @param #EASYGCICAP self
|
||||
-- @param #number Altitude (Optional) Altitude defaults to 25000
|
||||
-- @return #EASYGCICAP self
|
||||
function EASYGCICAP:SetDefaultINTERCEPTAlt(Altitude)
|
||||
self:T(self.lid.."SetDefaultINTERCEPTAlt")
|
||||
self.interceptalt = Altitude or 25000
|
||||
return self
|
||||
end
|
||||
--
|
||||
|
||||
--- Set default CAP lieg initial direction in degrees
|
||||
-- @param #EASYGCICAP self
|
||||
-- @param #number Direction (Optional) Direction defaults to 90 (East)
|
||||
@@ -754,6 +767,15 @@ end
|
||||
function EASYGCICAP:_AddAirwing(Airbasename, Alias)
|
||||
self:T(self.lid.."_AddAirwing "..Airbasename)
|
||||
|
||||
-- Gather Some Stats
|
||||
local function counttable(tbl)
|
||||
local count = 0
|
||||
for _,_data in pairs(tbl) do
|
||||
count = count + 1
|
||||
end
|
||||
return count
|
||||
end
|
||||
|
||||
local CapFormation = self.CapFormation
|
||||
local DespawnAfterLanding = self.DespawnAfterLanding
|
||||
local DespawnAfterHolding = self.DespawnAfterHolding
|
||||
@@ -772,7 +794,11 @@ function EASYGCICAP:_AddAirwing(Airbasename, Alias)
|
||||
CAP_Wing:SetMarker(false)
|
||||
CAP_Wing:SetAirbase(AIRBASE:FindByName(Airbasename))
|
||||
CAP_Wing:SetRespawnAfterDestroyed()
|
||||
CAP_Wing:SetNumberCAP(self.capgrouping)
|
||||
|
||||
--- #DONE avoid wings with no CAP points starting CAP anyhow; AirWing uses this to start CAP and creates points when there are none.
|
||||
if counttable(self.ManagedCP) >0 then
|
||||
CAP_Wing:SetNumberCAP(self.capgrouping)
|
||||
end
|
||||
CAP_Wing:SetCapCloseRaceTrack(true)
|
||||
|
||||
if self.showpatrolpointmarks then
|
||||
@@ -854,16 +880,18 @@ function EASYGCICAP:_AddAirwing(Airbasename, Alias)
|
||||
end
|
||||
|
||||
if self.noalert5 > 0 then
|
||||
local alert
|
||||
if self.ClassName == "EASYGCICAP" then
|
||||
alert = AUFTRAG:NewALERT5(AUFTRAG.Type.INTERCEPT)
|
||||
elseif self.ClassName == "EASYA2G" then
|
||||
alert = AUFTRAG:NewALERT5(AUFTRAG.Type.BAI)
|
||||
for i=1,self.noalert5 do
|
||||
local alert
|
||||
if self.ClassName == "EASYGCICAP" then
|
||||
alert = AUFTRAG:NewALERT5(AUFTRAG.Type.INTERCEPT)
|
||||
elseif self.ClassName == "EASYA2G" then
|
||||
alert = AUFTRAG:NewALERT5(AUFTRAG.Type.BAI)
|
||||
end
|
||||
alert:SetRequiredAssets(self.capgrouping)
|
||||
alert:SetRepeat(99)
|
||||
CAP_Wing:AddMission(alert)
|
||||
table.insert(self.ListOfAuftrag,alert)
|
||||
end
|
||||
alert:SetRequiredAssets(self.noalert5)
|
||||
alert:SetRepeat(99)
|
||||
CAP_Wing:AddMission(alert)
|
||||
table.insert(self.ListOfAuftrag,alert)
|
||||
end
|
||||
|
||||
self.wings[Airbasename] = { CAP_Wing, AIRBASE:FindByName(Airbasename):GetZone(), Airbasename }
|
||||
@@ -1037,7 +1065,7 @@ function EASYGCICAP:_SetCAPPatrolPoints()
|
||||
MESSAGE:New(self.lid.."You are trying to create a CAP point for which there is no wing! "..tostring(data.AirbaseName),30,"CHECK"):ToAllIf(self.debug):ToLog()
|
||||
return
|
||||
end
|
||||
local Wing = self.wings[data.AirbaseName][1] -- Ops.Airwing#AIRWING
|
||||
local Wing = self.wings[data.AirbaseName][1] -- Ops.AirWing#AIRWING
|
||||
local Coordinate = data.Coordinate
|
||||
local Altitude = data.Altitude
|
||||
local Speed = data.Speed
|
||||
@@ -1503,6 +1531,7 @@ function EASYGCICAP:_AssignIntercept(Cluster)
|
||||
local overhead = self.overhead
|
||||
local capspeed = self.capspeed + 100
|
||||
local capalt = self.capalt
|
||||
local interalt = self.interceptalt or self.capalt
|
||||
local maxsize = self.maxinterceptsize
|
||||
local repeatsonfailure = self.repeatsonfailure
|
||||
|
||||
@@ -1590,6 +1619,7 @@ function EASYGCICAP:_AssignIntercept(Cluster)
|
||||
:SetRepeatOnFailure(repeats)
|
||||
:SetMissionSpeed(UTILS.KnotsToAltKIAS(capspeed,capalt))
|
||||
:SetMissionAltitude(capalt)
|
||||
:SetEngageAltitude(interalt)
|
||||
|
||||
if nogozoneset:Count() > 0 then
|
||||
InterceptAuftrag:AddConditionSuccess(
|
||||
@@ -1835,9 +1865,10 @@ function EASYGCICAP:onafterRestart(From,Event,To)
|
||||
-- self.wings[Airbasename] = { CAP_Wing, AIRBASE:FindByName(Airbasename):GetZone(), Airbasename }
|
||||
for _,_wing in pairs(self.wings or {}) do
|
||||
for _,_aw in pairs(_wing) do
|
||||
_wing[1]:Start()
|
||||
_wing[1]:Restart()
|
||||
end
|
||||
end
|
||||
end
|
||||
self:__Status(5)
|
||||
return self
|
||||
end
|
||||
|
||||
@@ -1270,6 +1270,15 @@ function INTEL:_UpdateContact(Contact)
|
||||
else
|
||||
Contact.maneuvering = false
|
||||
end
|
||||
local typename = Contact.group:GetTypeName()
|
||||
local base_rcs = INTEL.RCS_Table[typename]
|
||||
|
||||
if not base_rcs then
|
||||
-- Fallback: category default
|
||||
local cat = Contact.group:GetCategory()
|
||||
base_rcs = (cat and INTEL.RCS_CategoryDefault[cat]) or INTEL.RCS_Reference
|
||||
end
|
||||
Contact.rcs = base_rcs
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -2581,7 +2581,7 @@ end
|
||||
-- @return #boolean Returns `true` if given cohort can meet all requirements.
|
||||
function LEGION._CohortCan(Cohort, MissionType, Categories, Attributes, Properties, WeaponTypes, TargetVec2, RangeMax, RefuelSystem, CargoWeight, MaxWeight, RangeMin)
|
||||
|
||||
RangeMin = RangeMin or 0
|
||||
RangeMin = RangeMin or -1
|
||||
|
||||
--- Function to check category.
|
||||
local function CheckCategory(_cohort)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -61,24 +61,21 @@
|
||||
--
|
||||
-- # The MSRS Concept
|
||||
--
|
||||
-- This class allows to broadcast sound files or text via Simple Radio Standalone (SRS).
|
||||
-- This class allows to broadcast sound files or text to speech via Simple Radio Standalone (SRS).
|
||||
--
|
||||
-- ## Prerequisites
|
||||
--
|
||||
-- * This script needs SRS version >= 1.9.6
|
||||
-- * You need to de-sanitize os, io and lfs in the missionscripting.lua
|
||||
-- * Optional: DCS-gRPC as backend to communicate with SRS (via infra)
|
||||
-- * Optional: HOUNDTTS as backend to communicate with SRS (via infra)
|
||||
-- * Optional but recommended: HOUND TTS as backend to communicate with SRS (via plugin)
|
||||
-- * Optional: DCS-gRPC as backend to communicate with SRS (via plugin)
|
||||
--
|
||||
-- ## Known Issues
|
||||
--
|
||||
-- ## Knwon Issues
|
||||
--
|
||||
-- ### Pop-up Window
|
||||
-- ### Pop-up Window (with backend windows)
|
||||
--
|
||||
-- The text-to-speech conversion of SRS is done via an external exe file. When this file is called, a windows `cmd` window is briefly opended. That puts DCS out of focus, which is annoying,
|
||||
-- expecially in VR but unavoidable (if you have a solution, please feel free to share!).
|
||||
-- expecially in VR, but unavoidable unless you use HOUD or gRPC as backends.
|
||||
--
|
||||
-- NOTE that this is not an issue if the mission is running on a server.
|
||||
-- Also NOTE that using DCS-gRPC and Hound-TTS as backend create no pop-up window.
|
||||
--
|
||||
-- # Play Sound Files
|
||||
--
|
||||
@@ -137,16 +134,17 @@
|
||||
--
|
||||
-- See @{#MSRS.LoadConfigFile} for details on how to set this up.
|
||||
--
|
||||
-- ## TTS Providers
|
||||
--
|
||||
-- The default provider for generating speech from text is the native Windows TTS service. Note that you need to install the voices you want to use.
|
||||
-- ## TTS (text-to-speech) Providers
|
||||
--
|
||||
-- The **currently recommended** backend is HOUND TTS (no pop-ups), which has a wide variety of TTS providers.
|
||||
-- The *default* provider for generating speech from text is the native Windows TTS service. Note that you need to install the voices you want to use.
|
||||
--
|
||||
-- **Pro-Tip** - use the command line with power shell to call `DCS-SR-ExternalAudio.exe` - it will tell you what is missing
|
||||
-- and also the Google Console error, in case you have missed a step in setting up your Google TTS.
|
||||
-- For example, `.\DCS-SR-ExternalAudio.exe -t "Text Message" -f 255 -m AM -c 2 -s 2 -z -G "Path_To_You_Google.Json"`
|
||||
-- plays a message on 255 MHz AM for the blue coalition in-game.
|
||||
--
|
||||
-- ### Google
|
||||
-- ### Google (best speech synthesis)
|
||||
--
|
||||
-- In order to use Google Cloud for TTS you need to use @{#MSRS.SetProvider} and @{#MSRS.SetProviderOptionsGoogle} functions:
|
||||
--
|
||||
@@ -162,7 +160,7 @@
|
||||
-- For more information on setting up a cloud account, visit: https://cloud.google.com/text-to-speech
|
||||
-- Google's supported SSML reference: https://cloud.google.com/text-to-speech/docs/ssml
|
||||
--
|
||||
-- ### Amazon Web Service [Only DCS-gRPC backend]
|
||||
-- ### Amazon Web Service [Only HOUDN and DCS-gRPC backend]
|
||||
--
|
||||
-- In order to use Amazon Web Service (AWS) for TTS you need to use @{#MSRS.SetProvider} and @{#MSRS.SetProviderOptionsAmazon} functions:
|
||||
--
|
||||
@@ -173,7 +171,7 @@
|
||||
--
|
||||
-- You can set the voice to use with AWS via @{#MSRS.SetVoiceAmazon}.
|
||||
--
|
||||
-- ### Microsoft Azure [Only DCS-gRPC backend]
|
||||
-- ### Microsoft Azure [Only HOUND and DCS-gRPC backend]
|
||||
--
|
||||
-- In order to use Microsoft Azure for TTS you need to use @{#MSRS.SetProvider} and @{#MSRS.SetProviderOptionsAzure} functions:
|
||||
--
|
||||
@@ -184,6 +182,12 @@
|
||||
--
|
||||
-- You can set the voice to use with Azure via @{#MSRS.SetVoiceAzure}.
|
||||
--
|
||||
-- ### Piper, OpenAI and further provider options [Only HOUND backend]
|
||||
--
|
||||
-- You can use further providers with HOUND TTS as a backend, see [Hound-TTS](https://github.com/uriba107/HoundTTS/releases) for setup.
|
||||
--
|
||||
-- msrs:SetProvider(MSRS.Provider.PIPER) -- e.g. for piper
|
||||
--
|
||||
-- ## Backend
|
||||
--
|
||||
-- The default interface to SRS is via calling the 'DCS-SR-ExternalAudio.exe'. As noted above, this has the unavoidable drawback that a pop-up briefly appears
|
||||
@@ -191,13 +195,13 @@
|
||||
--
|
||||
-- ## Hound TTS as an alternative to 'DCS-SR-ExternalAudio.exe' for TTS
|
||||
--
|
||||
-- An alternative interface to SRS is [Hound-TTS](https://github.com/uriba107/HoundTTS/releases). This does not call an exe file and therefore avoids the annoying pop-up window.
|
||||
-- the recommended alternative interface to SRS is [Hound-TTS](https://github.com/uriba107/HoundTTS/releases). This does not call an exe file and therefore avoids the annoying pop-up window.
|
||||
-- In addition to Windows and Google cloud, it also offers Piper local voice creation and others as providers for TTS.
|
||||
--
|
||||
-- Use @{#MSRS.SetDefaultBackendHound} to enable [Hound-TTS](https://github.com/uriba107/HoundTTS/releases) as an alternate backend.
|
||||
-- This can be useful if the popup should be avoided or to use Piper or others for TTS. Please note, only text-to-speech is supported and it it cannot be used to transmit audio files.
|
||||
--
|
||||
-- Hound TTS must be installed and configured per the [Hound TTS](https://github.com/uriba107/HoundTTS#installation) prior to use.
|
||||
-- Hound TTS must be installed and configured per the [Hound TTS](https://github.com/uriba107/HoundTTS#installation) GitHub prior to use.
|
||||
-- If a cloud TTS provider is being used, the API key(s) must be set as per the documentation.
|
||||
-- Hound TTS can be used both with DCS dedicated server and regular DCS installations.
|
||||
--
|
||||
@@ -280,7 +284,7 @@ MSRS = {
|
||||
|
||||
--- MSRS class version.
|
||||
-- @field #string version
|
||||
MSRS.version="0.3.5"
|
||||
MSRS.version="0.3.7"
|
||||
|
||||
--- Voices
|
||||
-- @type MSRS.Voices
|
||||
@@ -731,14 +735,16 @@ MSRS.Backend = {
|
||||
-- @field #string AZURE Microsoft Azure (`azure`). Only possible with DCS-gRPC backend.
|
||||
-- @field #string AMAZON Amazon Web Service (`aws`). Only possible with DCS-gRPC backend.
|
||||
-- @field #string PIPER Piper local voice service. Only possible with Hound-TTS backend.
|
||||
-- @field #string KITTEN Kitten voice server. Only possible with Hound-TTS backend.
|
||||
-- @field #string KITTEN Kitten voice server. Only possible with Hound-TTS backend. Superseded by OpenAI
|
||||
-- @field #string OPENAI OpenAI voice server. Only possible with Hound-TTS backend.
|
||||
MSRS.Provider = {
|
||||
WINDOWS = "win",
|
||||
GOOGLE = "gcloud",
|
||||
AZURE = "azure",
|
||||
AMAZON = "aws",
|
||||
PIPER = "piper",
|
||||
KITTEN = "kitten",
|
||||
KITTEN = "openai",
|
||||
OPENAI = "openai",
|
||||
}
|
||||
|
||||
--- Function for UUID.
|
||||
@@ -1471,6 +1477,15 @@ function MSRS:SetTTSProviderKitten()
|
||||
return self
|
||||
end
|
||||
|
||||
--- Use OpenAI to provide text-to-speech. Only supported if used in combination with Hound-TTS as backend.
|
||||
-- @param #MSRS self
|
||||
-- @return #MSRS self
|
||||
function MSRS:SetTTSProviderOpenAI()
|
||||
self:F()
|
||||
self:SetProvider(MSRS.Provider.OPENAI)
|
||||
return self
|
||||
end
|
||||
|
||||
--- Print SRS help to DCS log file.
|
||||
-- @param #MSRS self
|
||||
-- @return #MSRS self
|
||||
@@ -1605,7 +1620,7 @@ function MSRS:PlayText(Text, Delay, Coordinate, Speed, Speaker)
|
||||
else
|
||||
|
||||
local speaker = Speaker or self.Speaker
|
||||
|
||||
|
||||
if self.backend==MSRS.Backend.GRPC then
|
||||
self:T(self.lid.."Transmitting")
|
||||
self:_DCSgRPCtts(Text, nil, nil , nil, nil, nil, nil, Coordinate)
|
||||
@@ -2088,19 +2103,16 @@ function MSRS:_HoundTextToSpeech(Message,Frequencies,Modulations,Volume,Label,Co
|
||||
return
|
||||
end
|
||||
|
||||
Frequencies = UTILS.EnsureTable(Frequencies)
|
||||
Modulations = UTILS.EnsureTable(Modulations)
|
||||
Frequencies = UTILS.EnsureTable(Frequencies or self.frequencies)
|
||||
Modulations = UTILS.EnsureTable(Modulations or self.modulations)
|
||||
|
||||
local ffs = {}
|
||||
for _,_f in pairs(Frequencies or self.frequencies) do
|
||||
table.insert(ffs,string.format("%.1f",_f))
|
||||
for _,_f in pairs(Frequencies) do
|
||||
table.insert(ffs,string.format("%.3f",_f))
|
||||
end
|
||||
|
||||
local freqs = table.concat(ffs, ",")
|
||||
|
||||
|
||||
|
||||
local modus = table.concat(Modulations or self.modulations, ",")
|
||||
local modus = table.concat(Modulations, ",")
|
||||
|
||||
local coal=Coalition or self.coalition
|
||||
local gender=Gender or self.gender
|
||||
@@ -2144,7 +2156,7 @@ function MSRS:_HoundTextToSpeech(Message,Frequencies,Modulations,Volume,Label,Co
|
||||
gender = gender,
|
||||
speaker = Speaker or self.Speaker,
|
||||
}
|
||||
|
||||
|
||||
local speechtime = HoundTTS.Transmit(Message, TransmissionP, ProviderP)
|
||||
|
||||
return speechtime
|
||||
@@ -2202,7 +2214,7 @@ function MSRS:_HoundTestTone(Frequencies, Modulations, Coalition)
|
||||
|
||||
local ffs = {}
|
||||
for _,_f in pairs(Frequencies or self.frequencies) do
|
||||
table.insert(ffs,string.format("%.1f",_f))
|
||||
table.insert(ffs,string.format("%.3f",_f))
|
||||
end
|
||||
|
||||
local freqs = table.concat(ffs, ",")
|
||||
@@ -2258,6 +2270,71 @@ function MSRS._HoundTranslate(Message,Parameters,CallbackFunction)
|
||||
return
|
||||
end
|
||||
|
||||
--- Create and run a radio jammer for a number of seconds on given frequencies. Requires HOUND backend v0.2.0-beta5 or better.
|
||||
-- @param #MSRS self
|
||||
-- @param #table Frequencies The table of frequencies to use.
|
||||
-- @param #table Modulations The table of modulations to use.
|
||||
-- @param #number Coalition (Optional) The coalition to use. Defaults to previously set coalition on this instance.
|
||||
-- @param #string Noisetype (Optional) One of "white" (default) | "chirp" | "harsh" | "jam".
|
||||
-- @param #number Volume (Optional) Volume 0.0–1.0 (default 1.0).
|
||||
-- @param #number Seconds (Optional) How long in seconds this jammer runs. Defaults to 30 seconds.
|
||||
-- @param #string Label (Optional) The label to use, defaults to "MSRS".
|
||||
-- @param DCS#Vec3 Vec3 (Optional) Vec3 of the sender's position.
|
||||
-- @param #boolean Encrypt (Optional) If true, use the SRS encrypt option.
|
||||
-- @param #number EncKey (Optional) If encrypt is true, use this encrypt key.
|
||||
-- @return #number ID The Jammer ID to switch the jamming off again with `MSRS.RadioJammerOff()`
|
||||
function MSRS:RadioJammerOn(Frequencies, Modulations, Coalition, Noisetype, Volume, Seconds, Label, Vec3, Encrypt, EncKey)
|
||||
self:T(self.lid.."RadioJammerOn")
|
||||
|
||||
Frequencies = UTILS.EnsureTable(Frequencies)
|
||||
Modulations = UTILS.EnsureTable(Modulations)
|
||||
|
||||
local ffs = {}
|
||||
for _,_f in pairs(Frequencies or self.frequencies) do
|
||||
table.insert(ffs,string.format("%.3f",_f))
|
||||
end
|
||||
|
||||
local freqs = table.concat(ffs, ",")
|
||||
local modus = table.concat(Modulations or self.modulations, ",")
|
||||
-- Replace modulation
|
||||
modus=modus:gsub("0", "AM")
|
||||
modus=modus:gsub("1", "FM")
|
||||
|
||||
local coal=Coalition or self.coalition or coalition.side.RED
|
||||
local secs = Seconds or 30
|
||||
|
||||
local TransmissionP = {}
|
||||
local ProviderP = {}
|
||||
|
||||
TransmissionP.transmitter = "srs"
|
||||
TransmissionP.freqs = freqs
|
||||
TransmissionP.modulations = modus
|
||||
TransmissionP.coalition = coal or self.coalition -- number 0=spectator, 1=red, 2=blue
|
||||
TransmissionP.name = Label or self.Label -- string client name shown in SRS
|
||||
TransmissionP.point = Vec3 -- DCS Vec3 (optional) — initial transmitter position
|
||||
TransmissionP.encrypt = Encrypt -- bool
|
||||
TransmissionP.encKey = EncKey -- number 0–255
|
||||
|
||||
ProviderP.noiseType = Noisetype or "white"
|
||||
ProviderP.volume = Volume or 1
|
||||
|
||||
local ID = HoundTTS.TransmitNoise(TransmissionP, ProviderP)
|
||||
|
||||
self.NoiseID = ID
|
||||
|
||||
self:ScheduleOnce(secs,MSRS.RadioJammerOff,self,ID)
|
||||
|
||||
return ID
|
||||
|
||||
end
|
||||
|
||||
--- Switch off a running Jammer using its ID.
|
||||
-- @param #MSRS self
|
||||
-- @param #number ID
|
||||
function MSRS:RadioJammerOff(ID)
|
||||
return HoundTTS.KillSession(ID or self.NoiseID)
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- Config File
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -523,7 +523,7 @@ ENUMS.ReportingName =
|
||||
Tornado = "Tornado",
|
||||
-- Transport / Bomber / Others
|
||||
Atlas = "A400",
|
||||
Lancer = "B1-B",
|
||||
Lancer = "B-1B",
|
||||
Stratofortress = "B-52H",
|
||||
Herc = "C-130",
|
||||
Hercules = "C-130J-30",
|
||||
@@ -568,7 +568,7 @@ ENUMS.ReportingName =
|
||||
Apache = "AH-64",
|
||||
Chinook = "CH-47",
|
||||
Sea_Stallion = "CH-53",
|
||||
Kiowa = "OH-58",
|
||||
Kiowa = "OH58D",
|
||||
Seahawk = "SH-60",
|
||||
Blackhawk = "UH-60",
|
||||
Sea_King = "S-61",
|
||||
@@ -2126,6 +2126,47 @@ ENUMS.Storage.weapons.containers.UH60_GAU19_RIGHT = 'weapons.containers.{UH60_GA
|
||||
ENUMS.Storage.weapons.containers.UH60_M230_RIGHT = 'weapons.containers.{UH60_M230_RIGHT}'
|
||||
ENUMS.Storage.weapons.containers.UH60L_M2_GUNNER = 'weapons.containers.{UH60L_M2_GUNNER}'
|
||||
|
||||
|
||||
ENUMS.Storage.weapons.adapters.GD_F100_SUU_13 = 'weapons.adapters.GD_F100_SUU-13'
|
||||
ENUMS.Storage.weapons.containers.GPU_5_POD = 'weapons.containers.{GPU_5_POD}'
|
||||
ENUMS.Storage.weapons.bombs.BOLT_117 = 'weapons.bombs.BOLT-117'
|
||||
ENUMS.Storage.weapons.shells.F100_M39_20_TP_T = 'weapons.shells.F100_M39_20_TP_T'
|
||||
ENUMS.Storage.weapons.gunmounts.M_39_F_100 = 'weapons.gunmounts.M-39 F-100'
|
||||
ENUMS.Storage.weapons.droptanks.GD_F100_TANK_275_L = 'weapons.droptanks.GD_F100_TANK_275_L'
|
||||
ENUMS.Storage.weapons.bombs.BLU_4B_R_GROUP_R = 'weapons.bombs.BLU-4B_R_GROUP_R'
|
||||
ENUMS.Storage.weapons.containers.F100_CAMERA_P2 = 'weapons.containers.F100_CAMERA_P2'
|
||||
ENUMS.Storage.weapons.containers.HB_ORD_SUU_7 = 'weapons.containers.HB_ORD_SUU_7'
|
||||
ENUMS.Storage.weapons.adapters.SidewinderPylon = 'weapons.adapters.SidewinderPylon'
|
||||
ENUMS.Storage.weapons.adapters.apu_470 = 'weapons.adapters.apu_470'
|
||||
ENUMS.Storage.weapons.droptanks.GD_F100_TANK_335_R = 'weapons.droptanks.GD_F100_TANK_335_R'
|
||||
ENUMS.Storage.weapons.bombs.BLU_3B_R_GROUP_R = 'weapons.bombs.BLU-3B_R_GROUP_R'
|
||||
ENUMS.Storage.weapons.droptanks.GD_F100_TANK_335_L = 'weapons.droptanks.GD_F100_TANK_335_L'
|
||||
ENUMS.Storage.weapons.adapters.mbdz_u2t = 'weapons.adapters.mbdz_u2t'
|
||||
ENUMS.Storage.weapons.containers.ZellRocket = 'weapons.containers.ZellRocket'
|
||||
ENUMS.Storage.weapons.containers.apu_73 = 'weapons.containers.apu-73'
|
||||
ENUMS.Storage.weapons.gunmounts.GAU_13 = 'weapons.gunmounts.GAU-13'
|
||||
ENUMS.Storage.weapons.shells.F100_M39_20_TP = 'weapons.shells.F100_M39_20_TP'
|
||||
ENUMS.Storage.weapons.shells.F100_M39_20_API = 'weapons.shells.F100_M39_20_API'
|
||||
ENUMS.Storage.weapons.adapters.bdz_umk2b = 'weapons.adapters.bdz_umk2b'
|
||||
ENUMS.Storage.weapons.droptanks.GD_F100_TANK_450 = 'weapons.droptanks.GD_F100_TANK_450'
|
||||
ENUMS.Storage.weapons.droptanks.GD_F100_TANK_275_R = 'weapons.droptanks.GD_F100_TANK_275_R'
|
||||
ENUMS.Storage.weapons.bombs.BLU_18_B_GROUP = 'weapons.bombs.BLU-18/B_GROUP'
|
||||
ENUMS.Storage.weapons.containers.ZELL_Booster = 'weapons.containers.ZELL Booster'
|
||||
ENUMS.Storage.weapons.adapters.apu_60 = 'weapons.adapters.apu_60'
|
||||
ENUMS.Storage.weapons.gunmounts.GPU_5_POD = 'weapons.gunmounts.{GPU_5_POD}'
|
||||
ENUMS.Storage.weapons.containers.F100_CAMERA_KA71A = 'weapons.containers.F100_CAMERA_KA71A'
|
||||
ENUMS.Storage.weapons.bombs.BLU_3_R_GROUP_R = 'weapons.bombs.BLU-3_R_GROUP_R'
|
||||
ENUMS.Storage.weapons.shells.F100_M39_20_HEI = 'weapons.shells.F100_M39_20_HEI'
|
||||
ENUMS.Storage.weapons.droptanks.GD_F100_TANK_200 = 'weapons.droptanks.GD_F100_TANK_200'
|
||||
ENUMS.Storage.weapons.adapters.apu_73 = 'weapons.adapters.apu-73'
|
||||
ENUMS.Storage.weapons.gunmounts.AKAN_NO_TRC = 'weapons.gunmounts.AKAN_NO_TRC'
|
||||
ENUMS.Storage.weapons.gunmounts.AKAN = 'weapons.gunmounts.AKAN'
|
||||
ENUMS.Storage.weapons.shells.F100_M39_20_HEI_T = 'weapons.shells.F100_M39_20_HEI_T'
|
||||
ENUMS.Storage.weapons.shells.F100_M39_20_API_T = 'weapons.shells.F100_M39_20_API_T'
|
||||
ENUMS.Storage.weapons.containers.GD_F100_STRIKE_CAMERA = 'weapons.containers.GD_F100_STRIKE_CAMERA'
|
||||
ENUMS.Storage.weapons.bombs.BLU_49_B = 'weapons.bombs.BLU-49/B'
|
||||
ENUMS.Storage.weapons.containers.GD_F100_SUU_13 = 'weapons.containers.GD_F100_SUU-13'
|
||||
|
||||
---
|
||||
-- @type ENUMS.FARPType
|
||||
-- @field #string FARP
|
||||
|
||||
@@ -2378,6 +2378,11 @@ function UTILS.IsLoadingDoorOpen( unit_name )
|
||||
BASE:T(unit_name .. " front door(s) are open or doors removed")
|
||||
return true
|
||||
end
|
||||
|
||||
if type_name == "Ka-50_3" and unit:getDrawArgumentValue(38) == 1 then
|
||||
BASE:T(unit_name .. " cockpit door is open")
|
||||
return true
|
||||
end
|
||||
|
||||
if type_name=="C-130J-30" and (unit:getDrawArgumentValue(86)==1)then
|
||||
BASE:T(unit_name.." rear doors are open")
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
-- @field #boolean isAirdrome Airbase is an airdrome.
|
||||
-- @field #boolean isHelipad Airbase is a helipad.
|
||||
-- @field #boolean isShip Airbase is a ship.
|
||||
-- @field #boolean isZell Airbase is a ZELL Booster.
|
||||
-- @field #table parking Parking spot data.
|
||||
-- @field #table parkingByID Parking spot data table with ID as key.
|
||||
-- @field #table parkingWhitelist List of parking spot terminal IDs considered for spawning.
|
||||
@@ -458,115 +459,420 @@ AIRBASE.TheChannel = {
|
||||
|
||||
--- Airbases of the Syria map
|
||||
--
|
||||
-- * `AIRBASE.Syria.Abu_al_Duhur` Abu al-Duhur
|
||||
-- * `AIRBASE.Syria.Adana_Sakirpasa` Adana Sakirpasa
|
||||
-- * `AIRBASE.Syria.Akrotiri` Akrotiri
|
||||
-- * `AIRBASE.Syria.Al_Qusayr` Al Qusayr
|
||||
-- * `AIRBASE.Syria.Al_Dumayr` Al-Dumayr
|
||||
-- * `AIRBASE.Syria.Aleppo` Aleppo
|
||||
-- * `AIRBASE.Syria.An_Nasiriyah` An Nasiriyah
|
||||
-- * `AIRBASE.Syria.At_Tanf` At Tanf
|
||||
-- * `AIRBASE.Syria.Bassel_Al_Assad` Bassel Al-Assad
|
||||
-- * `AIRBASE.Syria.Beirut_Rafic_Hariri` Beirut-Rafic Hariri
|
||||
-- * `AIRBASE.Syria.Ben_Gurion` Ben Gurion
|
||||
-- * `AIRBASE.Syria.Damascus` Damascus
|
||||
-- * `AIRBASE.Syria.Deir_ez_Zor` Deir ez-Zor
|
||||
-- * `AIRBASE.Syria.Ercan` Ercan
|
||||
-- * `AIRBASE.Syria.Eyn_Shemer` Eyn Shemer
|
||||
-- * `AIRBASE.Syria.Gaziantep` Gaziantep
|
||||
-- * `AIRBASE.Syria.Gazipasa` Gazipasa
|
||||
-- * `AIRBASE.Syria.Gecitkale` Gecitkale
|
||||
-- * `AIRBASE.Syria.H` H
|
||||
-- * `AIRBASE.Syria.H3` H3
|
||||
-- * `AIRBASE.Syria.H3_Northwest` H3 Northwest
|
||||
-- * `AIRBASE.Syria.H3_Southwest` H3 Southwest
|
||||
-- * `AIRBASE.Syria.H4` H4
|
||||
-- * `AIRBASE.Syria.Haifa` Haifa
|
||||
-- * `AIRBASE.Syria.Hama` Hama
|
||||
-- * `AIRBASE.Syria.Hatay` Hatay
|
||||
-- * `AIRBASE.Syria.Hatzor` Hatzor
|
||||
-- * `AIRBASE.Syria.Herzliya` Herzliya
|
||||
-- * `AIRBASE.Syria.Incirlik` Incirlik
|
||||
-- * `AIRBASE.Syria.Jirah` Jirah
|
||||
-- * `AIRBASE.Syria.Khalkhalah` Khalkhalah
|
||||
-- * `AIRBASE.Syria.Kharab_Ishk` Kharab Ishk
|
||||
-- * `AIRBASE.Syria.King_Abdullah_II` King Abdullah II
|
||||
-- * `AIRBASE.Syria.King_Hussein_Air_College` King Hussein Air College
|
||||
-- * `AIRBASE.Syria.Kingsfield` Kingsfield
|
||||
-- * `AIRBASE.Syria.Kiryat_Shmona` Kiryat Shmona
|
||||
-- * `AIRBASE.Syria.Kuweires` Kuweires
|
||||
-- * `AIRBASE.Syria.Lakatamia` Lakatamia
|
||||
-- * `AIRBASE.Syria.Larnaca` Larnaca
|
||||
-- * `AIRBASE.Syria.Marj_Ruhayyil` Marj Ruhayyil
|
||||
-- * `AIRBASE.Syria.Marj_as_Sultan_North` Marj as Sultan North
|
||||
-- * `AIRBASE.Syria.Marj_as_Sultan_South` Marj as Sultan South
|
||||
-- * `AIRBASE.Syria.Marka` Marka
|
||||
-- * `AIRBASE.Syria.Megiddo` Megiddo
|
||||
-- * `AIRBASE.Syria.Mezzeh` Mezzeh
|
||||
-- * `AIRBASE.Syria.Minakh` Minakh
|
||||
-- * `AIRBASE.Syria.Muwaffaq_Salti` Muwaffaq Salti
|
||||
-- * `AIRBASE.Syria.Naqoura` Naqoura
|
||||
-- * `AIRBASE.Syria.Nicosia` Nicosia
|
||||
-- * `AIRBASE.Syria.Palmachim` Palmachim
|
||||
-- * `AIRBASE.Syria.Palmyra` Palmyra
|
||||
-- * `AIRBASE.Syria.Paphos` Paphos
|
||||
-- * `AIRBASE.Syria.Pinarbashi` Pinarbashi
|
||||
-- * `AIRBASE.Syria.Prince_Hassan` Prince Hassan
|
||||
-- * `AIRBASE.Syria.Qabr_as_Sitt` Qabr as Sitt
|
||||
-- * `AIRBASE.Syria.Ramat_David` Ramat David
|
||||
-- * `AIRBASE.Syria.Rayak` Rayak
|
||||
-- * `AIRBASE.Syria.Rene_Mouawad` Rene Mouawad
|
||||
-- * `AIRBASE.Syria.Rosh_Pina` Rosh Pina
|
||||
-- * `AIRBASE.Syria.Ruwayshid` Ruwayshid
|
||||
-- * `AIRBASE.Syria.Sanliurfa` Sanliurfa
|
||||
-- * `AIRBASE.Syria.Sayqal` Sayqal
|
||||
-- * `AIRBASE.Syria.Shayrat` Shayrat
|
||||
-- * `AIRBASE.Syria.Tabqa` Tabqa
|
||||
-- * `AIRBASE.Syria.Taftanaz` Taftanaz
|
||||
-- * `AIRBASE.Syria.Tal_Siman` Tal Siman
|
||||
-- * `AIRBASE.Syria.Tel_Nof` Tel Nof
|
||||
-- * `AIRBASE.Syria.Tha_lah` Tha'lah
|
||||
-- * `AIRBASE.Syria.Tiyas` Tiyas
|
||||
-- * `AIRBASE.Syria.Wujah_Al_Hajar` Wujah Al Hajar
|
||||
-- * AIRBASE.Syria.Abu_al_Duhur
|
||||
-- * AIRBASE.Syria.Adana_Sakirpasa
|
||||
-- * AIRBASE.Syria.Adiyaman
|
||||
-- * AIRBASE.Syria.Akrotiri
|
||||
-- * AIRBASE.Syria.Al_Dumayr
|
||||
-- * AIRBASE.Syria.Al_Qusayr
|
||||
-- * AIRBASE.Syria.Aleppo
|
||||
-- * AIRBASE.Syria.An_Nasiriyah
|
||||
-- * AIRBASE.Syria.At_Tanf
|
||||
-- * AIRBASE.Syria.Bassel_Al_Assad
|
||||
-- * AIRBASE.Syria.Beirut_Rafic_Hariri
|
||||
-- * AIRBASE.Syria.Ben_Gurion
|
||||
-- * AIRBASE.Syria.Chukurova
|
||||
-- * AIRBASE.Syria.Damascus
|
||||
-- * AIRBASE.Syria.Deir_ez_Zor
|
||||
-- * AIRBASE.Syria.Diyarbakir
|
||||
-- * AIRBASE.Syria.Ercan
|
||||
-- * AIRBASE.Syria.Eyn_Shemer
|
||||
-- * AIRBASE.Syria.Gaziantep
|
||||
-- * AIRBASE.Syria.Gazipasa
|
||||
-- * AIRBASE.Syria.Gecitkale
|
||||
-- * AIRBASE.Syria.Gulechoba
|
||||
-- * AIRBASE.Syria.H3
|
||||
-- * AIRBASE.Syria.H3_Northwest
|
||||
-- * AIRBASE.Syria.H3_Southwest
|
||||
-- * AIRBASE.Syria.H4
|
||||
-- * AIRBASE.Syria.H4_Emergency
|
||||
-- * AIRBASE.Syria.HC01
|
||||
-- * AIRBASE.Syria.HC02
|
||||
-- * AIRBASE.Syria.HC03
|
||||
-- * AIRBASE.Syria.HC04
|
||||
-- * AIRBASE.Syria.HC05
|
||||
-- * AIRBASE.Syria.HC06
|
||||
-- * AIRBASE.Syria.HI01
|
||||
-- * AIRBASE.Syria.HI02
|
||||
-- * AIRBASE.Syria.HI03
|
||||
-- * AIRBASE.Syria.HI05
|
||||
-- * AIRBASE.Syria.HI06
|
||||
-- * AIRBASE.Syria.HI07
|
||||
-- * AIRBASE.Syria.HI08
|
||||
-- * AIRBASE.Syria.HI09
|
||||
-- * AIRBASE.Syria.HI11
|
||||
-- * AIRBASE.Syria.HI12
|
||||
-- * AIRBASE.Syria.HI13
|
||||
-- * AIRBASE.Syria.HI14
|
||||
-- * AIRBASE.Syria.HI15
|
||||
-- * AIRBASE.Syria.HI16
|
||||
-- * AIRBASE.Syria.HI17
|
||||
-- * AIRBASE.Syria.HI18
|
||||
-- * AIRBASE.Syria.HI20
|
||||
-- * AIRBASE.Syria.HI21
|
||||
-- * AIRBASE.Syria.HI22
|
||||
-- * AIRBASE.Syria.HI23
|
||||
-- * AIRBASE.Syria.HI24
|
||||
-- * AIRBASE.Syria.HI25
|
||||
-- * AIRBASE.Syria.HI26
|
||||
-- * AIRBASE.Syria.HJ01
|
||||
-- * AIRBASE.Syria.HJ02
|
||||
-- * AIRBASE.Syria.HJ03
|
||||
-- * AIRBASE.Syria.HJ04
|
||||
-- * AIRBASE.Syria.HL01
|
||||
-- * AIRBASE.Syria.HL02
|
||||
-- * AIRBASE.Syria.HL03
|
||||
-- * AIRBASE.Syria.HL04
|
||||
-- * AIRBASE.Syria.HL05
|
||||
-- * AIRBASE.Syria.HL06
|
||||
-- * AIRBASE.Syria.HL07
|
||||
-- * AIRBASE.Syria.HL08
|
||||
-- * AIRBASE.Syria.HL09
|
||||
-- * AIRBASE.Syria.HL10
|
||||
-- * AIRBASE.Syria.HL11
|
||||
-- * AIRBASE.Syria.HL12
|
||||
-- * AIRBASE.Syria.HL13
|
||||
-- * AIRBASE.Syria.HMed00
|
||||
-- * AIRBASE.Syria.HMed01
|
||||
-- * AIRBASE.Syria.HMed02
|
||||
-- * AIRBASE.Syria.HMed03
|
||||
-- * AIRBASE.Syria.HMed04
|
||||
-- * AIRBASE.Syria.HMed05
|
||||
-- * AIRBASE.Syria.HMed06
|
||||
-- * AIRBASE.Syria.HMed07
|
||||
-- * AIRBASE.Syria.HMed08
|
||||
-- * AIRBASE.Syria.HMed09
|
||||
-- * AIRBASE.Syria.HMed10
|
||||
-- * AIRBASE.Syria.HMed11
|
||||
-- * AIRBASE.Syria.HMed12
|
||||
-- * AIRBASE.Syria.HMed13
|
||||
-- * AIRBASE.Syria.HMed14
|
||||
-- * AIRBASE.Syria.HMed15
|
||||
-- * AIRBASE.Syria.HMed16
|
||||
-- * AIRBASE.Syria.HMed17
|
||||
-- * AIRBASE.Syria.HMed18
|
||||
-- * AIRBASE.Syria.HMed19
|
||||
-- * AIRBASE.Syria.HMed20
|
||||
-- * AIRBASE.Syria.HMed21
|
||||
-- * AIRBASE.Syria.HMed22
|
||||
-- * AIRBASE.Syria.HMed23
|
||||
-- * AIRBASE.Syria.HMed24
|
||||
-- * AIRBASE.Syria.HMed25
|
||||
-- * AIRBASE.Syria.HMed26
|
||||
-- * AIRBASE.Syria.HMed27
|
||||
-- * AIRBASE.Syria.HMed28
|
||||
-- * AIRBASE.Syria.HMed29
|
||||
-- * AIRBASE.Syria.HMed30
|
||||
-- * AIRBASE.Syria.HOil01
|
||||
-- * AIRBASE.Syria.HOil02
|
||||
-- * AIRBASE.Syria.HOil03
|
||||
-- * AIRBASE.Syria.HOil04
|
||||
-- * AIRBASE.Syria.HOil05
|
||||
-- * AIRBASE.Syria.HOil06
|
||||
-- * AIRBASE.Syria.HS02
|
||||
-- * AIRBASE.Syria.HS03
|
||||
-- * AIRBASE.Syria.HS04
|
||||
-- * AIRBASE.Syria.HS05
|
||||
-- * AIRBASE.Syria.HS06
|
||||
-- * AIRBASE.Syria.HS07
|
||||
-- * AIRBASE.Syria.HS08
|
||||
-- * AIRBASE.Syria.HS09
|
||||
-- * AIRBASE.Syria.HS10
|
||||
-- * AIRBASE.Syria.HS11
|
||||
-- * AIRBASE.Syria.HS12
|
||||
-- * AIRBASE.Syria.HS13
|
||||
-- * AIRBASE.Syria.HS14
|
||||
-- * AIRBASE.Syria.HS15
|
||||
-- * AIRBASE.Syria.HS16
|
||||
-- * AIRBASE.Syria.HS17
|
||||
-- * AIRBASE.Syria.HS18
|
||||
-- * AIRBASE.Syria.HS19
|
||||
-- * AIRBASE.Syria.HS20
|
||||
-- * AIRBASE.Syria.HS21
|
||||
-- * AIRBASE.Syria.HS22
|
||||
-- * AIRBASE.Syria.HS23
|
||||
-- * AIRBASE.Syria.HS24
|
||||
-- * AIRBASE.Syria.HS25
|
||||
-- * AIRBASE.Syria.HS26
|
||||
-- * AIRBASE.Syria.HS27
|
||||
-- * AIRBASE.Syria.HS28
|
||||
-- * AIRBASE.Syria.HS29
|
||||
-- * AIRBASE.Syria.HS30
|
||||
-- * AIRBASE.Syria.HS31
|
||||
-- * AIRBASE.Syria.HS32
|
||||
-- * AIRBASE.Syria.HS33
|
||||
-- * AIRBASE.Syria.HS34
|
||||
-- * AIRBASE.Syria.HS35
|
||||
-- * AIRBASE.Syria.HS36
|
||||
-- * AIRBASE.Syria.HS37
|
||||
-- * AIRBASE.Syria.HS38
|
||||
-- * AIRBASE.Syria.HS39
|
||||
-- * AIRBASE.Syria.HS40
|
||||
-- * AIRBASE.Syria.HS41
|
||||
-- * AIRBASE.Syria.HS42
|
||||
-- * AIRBASE.Syria.HStad01
|
||||
-- * AIRBASE.Syria.HStad02
|
||||
-- * AIRBASE.Syria.HStad03
|
||||
-- * AIRBASE.Syria.HStad04
|
||||
-- * AIRBASE.Syria.HStad05
|
||||
-- * AIRBASE.Syria.HStad06
|
||||
-- * AIRBASE.Syria.HT01
|
||||
-- * AIRBASE.Syria.HT02
|
||||
-- * AIRBASE.Syria.H_med_orig_01
|
||||
-- * AIRBASE.Syria.H_med_orig_02
|
||||
-- * AIRBASE.Syria.H_med_orig_03
|
||||
-- * AIRBASE.Syria.H_med_orig_04
|
||||
-- * AIRBASE.Syria.H_med_orig_05
|
||||
-- * AIRBASE.Syria.H_med_orig_06
|
||||
-- * AIRBASE.Syria.H_med_orig_07
|
||||
-- * AIRBASE.Syria.H_med_orig_08
|
||||
-- * AIRBASE.Syria.H_med_orig_09
|
||||
-- * AIRBASE.Syria.Haifa
|
||||
-- * AIRBASE.Syria.Hama
|
||||
-- * AIRBASE.Syria.Hatay
|
||||
-- * AIRBASE.Syria.Hatzerim
|
||||
-- * AIRBASE.Syria.Hatzor
|
||||
-- * AIRBASE.Syria.Herzliya
|
||||
-- * AIRBASE.Syria.Incirlik
|
||||
-- * AIRBASE.Syria.Jirah
|
||||
-- * AIRBASE.Syria.Kahramanmaras
|
||||
-- * AIRBASE.Syria.Kedem
|
||||
-- * AIRBASE.Syria.Khalkhalah
|
||||
-- * AIRBASE.Syria.Kharab_Ishk
|
||||
-- * AIRBASE.Syria.King_Abdullah_II
|
||||
-- * AIRBASE.Syria.King_Hussein_Air_College
|
||||
-- * AIRBASE.Syria.Kingsfield
|
||||
-- * AIRBASE.Syria.Kiryat_Shmona
|
||||
-- * AIRBASE.Syria.Konya
|
||||
-- * AIRBASE.Syria.Kuweires
|
||||
-- * AIRBASE.Syria.Lakatamia
|
||||
-- * AIRBASE.Syria.Larnaca
|
||||
-- * AIRBASE.Syria.Marj_Ruhayyil
|
||||
-- * AIRBASE.Syria.Marj_as_Sultan_North
|
||||
-- * AIRBASE.Syria.Marj_as_Sultan_South
|
||||
-- * AIRBASE.Syria.Marka
|
||||
-- * AIRBASE.Syria.Megiddo
|
||||
-- * AIRBASE.Syria.Mezzeh
|
||||
-- * AIRBASE.Syria.Minakh
|
||||
-- * AIRBASE.Syria.Muwaffaq_Salti
|
||||
-- * AIRBASE.Syria.Naqoura
|
||||
-- * AIRBASE.Syria.Nevatim
|
||||
-- * AIRBASE.Syria.Nicosia
|
||||
-- * AIRBASE.Syria.Palmachim
|
||||
-- * AIRBASE.Syria.Palmyra
|
||||
-- * AIRBASE.Syria.Paphos
|
||||
-- * AIRBASE.Syria.Pinarbashi
|
||||
-- * AIRBASE.Syria.Prince_Hassan
|
||||
-- * AIRBASE.Syria.Qabr_as_Sitt
|
||||
-- * AIRBASE.Syria.Ramat_David
|
||||
-- * AIRBASE.Syria.Rayak
|
||||
-- * AIRBASE.Syria.Rene_Mouawad
|
||||
-- * AIRBASE.Syria.Rosh_Pina
|
||||
-- * AIRBASE.Syria.Ruwayshid
|
||||
-- * AIRBASE.Syria.Sanliurfa
|
||||
-- * AIRBASE.Syria.Sanliurfa_Heliport
|
||||
-- * AIRBASE.Syria.Sayqal
|
||||
-- * AIRBASE.Syria.Shayrat
|
||||
-- * AIRBASE.Syria.T2
|
||||
-- * AIRBASE.Syria.T3
|
||||
-- * AIRBASE.Syria.Tabqa
|
||||
-- * AIRBASE.Syria.Taftanaz
|
||||
-- * AIRBASE.Syria.Tal_Siman
|
||||
-- * AIRBASE.Syria.Tel_Nof
|
||||
-- * AIRBASE.Syria.Teyman
|
||||
-- * AIRBASE.Syria.Tha_lah
|
||||
-- * AIRBASE.Syria.Tiyas
|
||||
-- * AIRBASE.Syria.Wujah_Al_Hajar
|
||||
-- * AIRBASE.Syria.Zarqa
|
||||
|
||||
--
|
||||
-- @field Syria
|
||||
AIRBASE.Syria = {
|
||||
["Abu_al_Duhur"] = "Abu al-Duhur",
|
||||
["Adana_Sakirpasa"] = "Adana Sakirpasa",
|
||||
["Adiyaman"] = "Adiyaman",
|
||||
["Akrotiri"] = "Akrotiri",
|
||||
["Al_Qusayr"] = "Al Qusayr",
|
||||
["Al_Dumayr"] = "Al-Dumayr",
|
||||
["Al_Qusayr"] = "Al Qusayr",
|
||||
["Aleppo"] = "Aleppo",
|
||||
["An_Nasiriyah"] = "An Nasiriyah",
|
||||
["At_Tanf"] = "At Tanf",
|
||||
["Bassel_Al_Assad"] = "Bassel Al-Assad",
|
||||
["Beirut_Rafic_Hariri"] = "Beirut-Rafic Hariri",
|
||||
["Ben_Gurion"] = "Ben Gurion",
|
||||
["Chukurova"] = "Chukurova",
|
||||
["Damascus"] = "Damascus",
|
||||
["Deir_ez_Zor"] = "Deir ez-Zor",
|
||||
["Diyarbakir"] = "Diyarbakir",
|
||||
["Ercan"] = "Ercan",
|
||||
["Eyn_Shemer"] = "Eyn Shemer",
|
||||
["Gaziantep"] = "Gaziantep",
|
||||
["Gazipasa"] = "Gazipasa",
|
||||
["Gecitkale"] = "Gecitkale",
|
||||
["H"] = "H",
|
||||
["Gulechoba"] = "Gulechoba",
|
||||
["H3"] = "H3",
|
||||
["H3_Northwest"] = "H3 Northwest",
|
||||
["H3_Southwest"] = "H3 Southwest",
|
||||
["H4"] = "H4",
|
||||
["H4_Emergency"] = "H4 Emergency",
|
||||
["HC01"] = "HC01",
|
||||
["HC02"] = "HC02",
|
||||
["HC03"] = "HC03",
|
||||
["HC04"] = "HC04",
|
||||
["HC05"] = "HC05",
|
||||
["HC06"] = "HC06",
|
||||
["HI01"] = "HI01",
|
||||
["HI02"] = "HI02",
|
||||
["HI03"] = "HI03",
|
||||
["HI05"] = "HI05",
|
||||
["HI06"] = "HI06",
|
||||
["HI07"] = "HI07",
|
||||
["HI08"] = "HI08",
|
||||
["HI09"] = "HI09",
|
||||
["HI11"] = "HI11",
|
||||
["HI12"] = "HI12",
|
||||
["HI13"] = "HI13",
|
||||
["HI14"] = "HI14",
|
||||
["HI15"] = "HI15",
|
||||
["HI16"] = "HI16",
|
||||
["HI17"] = "HI17",
|
||||
["HI18"] = "HI18",
|
||||
["HI20"] = "HI20",
|
||||
["HI21"] = "HI21",
|
||||
["HI22"] = "HI22",
|
||||
["HI23"] = "HI23",
|
||||
["HI24"] = "HI24",
|
||||
["HI25"] = "HI25",
|
||||
["HI26"] = "HI26",
|
||||
["HJ01"] = "HJ01",
|
||||
["HJ02"] = "HJ02",
|
||||
["HJ03"] = "HJ03",
|
||||
["HJ04"] = "HJ04",
|
||||
["HL01"] = "HL01",
|
||||
["HL02"] = "HL02",
|
||||
["HL03"] = "HL03",
|
||||
["HL04"] = "HL04",
|
||||
["HL05"] = "HL05",
|
||||
["HL06"] = "HL06",
|
||||
["HL07"] = "HL07",
|
||||
["HL08"] = "HL08",
|
||||
["HL09"] = "HL09",
|
||||
["HL10"] = "HL10",
|
||||
["HL11"] = "HL11",
|
||||
["HL12"] = "HL12",
|
||||
["HL13"] = "HL13",
|
||||
["HMed00"] = "HMed00",
|
||||
["HMed01"] = "HMed01",
|
||||
["HMed02"] = "HMed02",
|
||||
["HMed03"] = "HMed03",
|
||||
["HMed04"] = "HMed04",
|
||||
["HMed05"] = "HMed05",
|
||||
["HMed06"] = "HMed06",
|
||||
["HMed07"] = "HMed07",
|
||||
["HMed08"] = "HMed08",
|
||||
["HMed09"] = "HMed09",
|
||||
["HMed10"] = "HMed10",
|
||||
["HMed11"] = "HMed11",
|
||||
["HMed12"] = "HMed12",
|
||||
["HMed13"] = "HMed13",
|
||||
["HMed14"] = "HMed14",
|
||||
["HMed15"] = "HMed15",
|
||||
["HMed16"] = "HMed16",
|
||||
["HMed17"] = "HMed17",
|
||||
["HMed18"] = "HMed18",
|
||||
["HMed19"] = "HMed19",
|
||||
["HMed20"] = "HMed20",
|
||||
["HMed21"] = "HMed21",
|
||||
["HMed22"] = "HMed22",
|
||||
["HMed23"] = "HMed23",
|
||||
["HMed24"] = "HMed24",
|
||||
["HMed25"] = "HMed25",
|
||||
["HMed26"] = "HMed26",
|
||||
["HMed27"] = "HMed27",
|
||||
["HMed28"] = "HMed28",
|
||||
["HMed29"] = "HMed29",
|
||||
["HMed30"] = "HMed30",
|
||||
["HOil01"] = "HOil01",
|
||||
["HOil02"] = "HOil02",
|
||||
["HOil03"] = "HOil03",
|
||||
["HOil04"] = "HOil04",
|
||||
["HOil05"] = "HOil05",
|
||||
["HOil06"] = "HOil06",
|
||||
["HS02"] = "HS02",
|
||||
["HS03"] = "HS03",
|
||||
["HS04"] = "HS04",
|
||||
["HS05"] = "HS05",
|
||||
["HS06"] = "HS06",
|
||||
["HS07"] = "HS07",
|
||||
["HS08"] = "HS08",
|
||||
["HS09"] = "HS09",
|
||||
["HS10"] = "HS10",
|
||||
["HS11"] = "HS11",
|
||||
["HS12"] = "HS12",
|
||||
["HS13"] = "HS13",
|
||||
["HS14"] = "HS14",
|
||||
["HS15"] = "HS15",
|
||||
["HS16"] = "HS16",
|
||||
["HS17"] = "HS17",
|
||||
["HS18"] = "HS18",
|
||||
["HS19"] = "HS19",
|
||||
["HS20"] = "HS20",
|
||||
["HS21"] = "HS21",
|
||||
["HS22"] = "HS22",
|
||||
["HS23"] = "HS23",
|
||||
["HS24"] = "HS24",
|
||||
["HS25"] = "HS25",
|
||||
["HS26"] = "HS26",
|
||||
["HS27"] = "HS27",
|
||||
["HS28"] = "HS28",
|
||||
["HS29"] = "HS29",
|
||||
["HS30"] = "HS30",
|
||||
["HS31"] = "HS31",
|
||||
["HS32"] = "HS32",
|
||||
["HS33"] = "HS33",
|
||||
["HS34"] = "HS34",
|
||||
["HS35"] = "HS35",
|
||||
["HS36"] = "HS36",
|
||||
["HS37"] = "HS37",
|
||||
["HS38"] = "HS38",
|
||||
["HS39"] = "HS39",
|
||||
["HS40"] = "HS40",
|
||||
["HS41"] = "HS41",
|
||||
["HS42"] = "HS42",
|
||||
["HStad01"] = "HStad01",
|
||||
["HStad02"] = "HStad02",
|
||||
["HStad03"] = "HStad03",
|
||||
["HStad04"] = "HStad04",
|
||||
["HStad05"] = "HStad05",
|
||||
["HStad06"] = "HStad06",
|
||||
["HT01"] = "HT01",
|
||||
["HT02"] = "HT02",
|
||||
["H_med_orig_01"] = "H_med_orig_01",
|
||||
["H_med_orig_02"] = "H_med_orig_02",
|
||||
["H_med_orig_03"] = "H_med_orig_03",
|
||||
["H_med_orig_04"] = "H_med_orig_04",
|
||||
["H_med_orig_05"] = "H_med_orig_05",
|
||||
["H_med_orig_06"] = "H_med_orig_06",
|
||||
["H_med_orig_07"] = "H_med_orig_07",
|
||||
["H_med_orig_08"] = "H_med_orig_08",
|
||||
["H_med_orig_09"] = "H_med_orig_09",
|
||||
["Haifa"] = "Haifa",
|
||||
["Hama"] = "Hama",
|
||||
["Hatay"] = "Hatay",
|
||||
["Hatzerim"] = "Hatzerim",
|
||||
["Hatzor"] = "Hatzor",
|
||||
["Herzliya"] = "Herzliya",
|
||||
["Incirlik"] = "Incirlik",
|
||||
["Jirah"] = "Jirah",
|
||||
["Kahramanmaras"] = "Kahramanmaras",
|
||||
["Kedem"] = "Kedem",
|
||||
["Khalkhalah"] = "Khalkhalah",
|
||||
["Kharab_Ishk"] = "Kharab Ishk",
|
||||
["King_Abdullah_II"] = "King Abdullah II",
|
||||
["King_Hussein_Air_College"] = "King Hussein Air College",
|
||||
["Kingsfield"] = "Kingsfield",
|
||||
["Kiryat_Shmona"] = "Kiryat Shmona",
|
||||
["Konya"] = "Konya",
|
||||
["Kuweires"] = "Kuweires",
|
||||
["Lakatamia"] = "Lakatamia",
|
||||
["Larnaca"] = "Larnaca",
|
||||
@@ -579,6 +885,7 @@ AIRBASE.Syria = {
|
||||
["Minakh"] = "Minakh",
|
||||
["Muwaffaq_Salti"] = "Muwaffaq Salti",
|
||||
["Naqoura"] = "Naqoura",
|
||||
["Nevatim"] = "Nevatim",
|
||||
["Nicosia"] = "Nicosia",
|
||||
["Palmachim"] = "Palmachim",
|
||||
["Palmyra"] = "Palmyra",
|
||||
@@ -592,15 +899,20 @@ AIRBASE.Syria = {
|
||||
["Rosh_Pina"] = "Rosh Pina",
|
||||
["Ruwayshid"] = "Ruwayshid",
|
||||
["Sanliurfa"] = "Sanliurfa",
|
||||
["Sanliurfa_Heliport"] = "Sanliurfa Heliport",
|
||||
["Sayqal"] = "Sayqal",
|
||||
["Shayrat"] = "Shayrat",
|
||||
["T2"] = "T2",
|
||||
["T3"] = "T3",
|
||||
["Tabqa"] = "Tabqa",
|
||||
["Taftanaz"] = "Taftanaz",
|
||||
["Tal_Siman"] = "Tal Siman",
|
||||
["Tel_Nof"] = "Tel Nof",
|
||||
["Teyman"] = "Teyman",
|
||||
["Tha_lah"] = "Tha'lah",
|
||||
["Tiyas"] = "Tiyas",
|
||||
["Wujah_Al_Hajar"] = "Wujah Al Hajar",
|
||||
["Zarqa"] = "Zarqa",
|
||||
}
|
||||
|
||||
--- Airbases of the Mariana Islands map
|
||||
@@ -1673,6 +1985,7 @@ elseif self.category==Airbase.Category.SHIP then
|
||||
self.category=Airbase.Category.HELIPAD
|
||||
_DATABASE:AddStatic(AirbaseName)
|
||||
end
|
||||
if self:GetTypeName() == "Zell" then self.isZell = true end
|
||||
else
|
||||
self:E("ERROR: Unknown airbase category!")
|
||||
end
|
||||
@@ -2122,6 +2435,13 @@ function AIRBASE:IsShip()
|
||||
return self.isShip
|
||||
end
|
||||
|
||||
--- Check if airbase is a ZELL booster.
|
||||
-- @param #AIRBASE self
|
||||
-- @return #boolean If true, airbase is a ZELL booster.
|
||||
function AIRBASE:IsZell()
|
||||
return self.isZell
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- Parking
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -112,6 +112,7 @@ Ops/OpsZone.lua
|
||||
Ops/ArmyGroup.lua
|
||||
Ops/OpsTransport.lua
|
||||
Ops/Target.lua
|
||||
Ops/TARS.lua
|
||||
|
||||
Sound/UserSound.lua
|
||||
Sound/SoundOutput.lua
|
||||
|
||||
Reference in New Issue
Block a user