- AIRBASE: Workaround for DCS bug that helipads have category of airdrome
- SET_AIRBASE: Added FilterZones function
This commit is contained in:
Frank 2025-03-08 21:37:43 +01:00
parent 3c710613a8
commit c00eff8b23
4 changed files with 114 additions and 12 deletions

View File

@ -5403,6 +5403,7 @@ do -- SET_AIRBASE
Airbases = {}, Airbases = {},
Filter = { Filter = {
Coalitions = nil, Coalitions = nil,
Zones = nil,
}, },
FilterMeta = { FilterMeta = {
Coalitions = { Coalitions = {
@ -5554,6 +5555,31 @@ do -- SET_AIRBASE
end end
return self return self
end end
--- Builds a set of airbase objects in zones.
-- @param #SET_AIRBASE self
-- @param #table Zones Table of Core.Zone#ZONE Zone objects, or a Core.Set#SET_ZONE
-- @return #SET_AIRBASE self
function SET_AIRBASE:FilterZones( Zones )
if not self.Filter.Zones then
self.Filter.Zones = {}
end
local zones = {}
if Zones.ClassName and Zones.ClassName == "SET_ZONE" then
zones = Zones.Set
elseif type( Zones ) ~= "table" or (type( Zones ) == "table" and Zones.ClassName ) then
self:E("***** FilterZones needs either a table of ZONE Objects or a SET_ZONE as parameter!")
return self
else
zones = Zones
end
for _,Zone in pairs( zones ) do
local zonename = Zone:GetName()
--self:T((zonename)
self.Filter.Zones[zonename] = Zone
end
return self
end
--- Starts the filtering. --- Starts the filtering.
-- @param #SET_AIRBASE self -- @param #SET_AIRBASE self
@ -5692,6 +5718,20 @@ do -- SET_AIRBASE
--self:T(( { "Evaluated Category", MAirbaseCategory } ) --self:T(( { "Evaluated Category", MAirbaseCategory } )
MAirbaseInclude = MAirbaseInclude and MAirbaseCategory MAirbaseInclude = MAirbaseInclude and MAirbaseCategory
end end
if self.Filter.Zones and MAirbaseInclude then
local MAirbaseZone = false
for ZoneName, Zone in pairs( self.Filter.Zones ) do
--self:T(( "Zone:", ZoneName )
local coord = MAirbase:GetCoordinate()
if coord and Zone:IsCoordinateInZone(coord) then
MAirbaseZone = true
end
--self:T(( { "Evaluated Zone", MSceneryZone } )
end
MAirbaseInclude = MAirbaseInclude and MAirbaseZone
end
end end
if self.Filter.Functions and MAirbaseInclude then if self.Filter.Functions and MAirbaseInclude then

View File

@ -630,9 +630,13 @@ do -- Object
--- @function [parent=#Object] destroy --- @function [parent=#Object] destroy
-- @param #Object self -- @param #Object self
--- @function [parent=#Object] getCategory --- Returns an enumerator of the category for the specific object.
-- The enumerator returned is dependent on the category of the object and how the function is called.
-- As of DCS 2.9.2 when this function is called on an Object, Unit, Weapon, or Airbase a 2nd value will be returned which details the object sub-category value.
-- @function [parent=#Object] getCategory
-- @param #Object self -- @param #Object self
-- @return #Object.Category -- @return #Object.Category The object category (1=UNIT, 2=WEAPON, 3=STATIC, 4=BASE, 5=SCENERY, 6=Cargo)
-- @return #number The subcategory of the passed object, e.g. Unit.Category if a unit object was passed.
--- Returns type name of the Object. --- Returns type name of the Object.
-- @function [parent=#Object] getTypeName -- @function [parent=#Object] getTypeName

View File

@ -514,7 +514,7 @@ function UTILS.PrintTableToLog(table, indent, noprint)
env.info(string.rep(" ", indent) .. tostring(k) .. " = {") env.info(string.rep(" ", indent) .. tostring(k) .. " = {")
end end
text = text ..string.rep(" ", indent) .. tostring(k) .. " = {\n" text = text ..string.rep(" ", indent) .. tostring(k) .. " = {\n"
text = text .. tostring(UTILS.PrintTableToLog(v, indent + 1)).."\n" text = text .. tostring(UTILS.PrintTableToLog(v, indent + 1), noprint).."\n"
if not noprint then if not noprint then
env.info(string.rep(" ", indent) .. "},") env.info(string.rep(" ", indent) .. "},")
end end

View File

@ -994,7 +994,7 @@ function AIRBASE:Register(AirbaseName)
-- Debug info. -- Debug info.
--self:I({airbase=AirbaseName, descriptors=self.descriptors}) --self:I({airbase=AirbaseName, descriptors=self.descriptors})
-- Category. -- Category.
self.category=self.descriptors and self.descriptors.category or Airbase.Category.AIRDROME self.category=self.descriptors and self.descriptors.category or Airbase.Category.AIRDROME
@ -1009,6 +1009,7 @@ if self.category==Airbase.Category.AIRDROME then
self.isAirdrome=true self.isAirdrome=true
elseif self.category==Airbase.Category.HELIPAD or self.descriptors.typeName=="FARP_SINGLE_01" then elseif self.category==Airbase.Category.HELIPAD or self.descriptors.typeName=="FARP_SINGLE_01" then
self.isHelipad=true self.isHelipad=true
self.category=Airbase.Category.HELIPAD
elseif self.category==Airbase.Category.SHIP then elseif self.category==Airbase.Category.SHIP then
self.isShip=true self.isShip=true
-- DCS bug: Oil rigs and gas platforms have category=2 (ship). Also they cannot be retrieved by coalition.getStaticObjects() -- DCS bug: Oil rigs and gas platforms have category=2 (ship). Also they cannot be retrieved by coalition.getStaticObjects()
@ -1024,20 +1025,33 @@ end
-- Init Runways. -- Init Runways.
self:_InitRunways() self:_InitRunways()
-- Number of runways
local Nrunways=#self.runways
-- Set the active runways based on wind direction. -- Set the active runways based on wind direction.
if self.isAirdrome then if Nrunways>0 then
self:SetActiveRunway() self:SetActiveRunway()
end end
-- Init parking spots. -- Init parking spots.
self:_InitParkingSpots() self:_InitParkingSpots()
-- Some heliports identify as airdromes in the airbase category. This is buggy in the descriptors category but also in the getCategory() and getCategoryEx() functions.
if self.category==Airbase.Category.AIRDROME and (Nrunways==0 or self.NparkingTotal==self.NparkingTerminal[AIRBASE.TerminalType.HelicopterOnly]) then
self:E(string.format("WARNING: %s identifies as airdrome (category=0) but has no runways or just helo parking ==> will change to helipad (category=1)", self.AirbaseName))
self.category=Airbase.Category.HELIPAD
self.isAirdrome=false
self.isHelipad=true
--self:GetCoordinate():MarkToAll("Helipad not airdrome")
end
-- Get 2D position vector. -- Get 2D position vector.
local vec2=self:GetVec2() local vec2=self:GetVec2()
-- Init coordinate. -- Init coordinate.
self:GetCoordinate() self:GetCoordinate()
-- Storage. -- Storage.
self.storage=_DATABASE:AddStorage(AirbaseName) self.storage=_DATABASE:AddStorage(AirbaseName)
@ -1061,6 +1075,46 @@ end
return self return self
end end
--- Get the category of this airbase. This is only a debug function because DCS 2.9 incorrectly returns heliports as airdromes.
-- @param #AIRBASE self
function AIRBASE:_GetCategory()
local name=self.AirbaseName
local static=StaticObject.getByName(name)
local airbase=Airbase.getByName(name)
local unit=Unit.getByName(name)
local text=string.format("\n=====================================================")
text=text..string.format("\nAirbase %s:", name)
if static then
local oc, uc=static:getCategory()
local ex=static:getCategoryEx()
text=text..string.format("\nSTATIC: oc=%d, uc=%d, ex=%d", oc, uc, ex)
--text=text..UTILS.PrintTableToLog(static:getDesc(), nil, true)
text=text..string.format("\n--------------------------------------------------")
end
if unit then
local oc, uc=unit:getCategory()
local ex=unit:getCategoryEx()
text=text..string.format("\nUNIT: oc=%d, uc=%d, ex=%d", oc, uc, ex)
--text=text..UTILS.PrintTableToLog(unit:getDesc(), nil, true)
text=text..string.format("\n--------------------------------------------------")
end
if airbase then
local oc, uc=airbase:getCategory()
local ex=airbase:getCategoryEx()
text=text..string.format("\nAIRBASE: oc=%d, uc=%d, ex=%d", oc, uc, ex)
text=text..string.format("\n--------------------------------------------------")
text=text..UTILS.PrintTableToLog(airbase:getDesc(), nil, true)
end
text=text..string.format("\n=====================================================")
env.info(text)
end
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Reference methods -- Reference methods
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
@ -1592,6 +1646,9 @@ function AIRBASE:_InitParkingSpots()
self.parkingByID[park.TerminalID]=park self.parkingByID[park.TerminalID]=park
table.insert(self.parking, park) table.insert(self.parking, park)
end end
-- Runways are not included in total number of parking spots
self.NparkingTotal=self.NparkingTotal-self.NparkingTerminal[AIRBASE.TerminalType.Runway]
return self return self
end end
@ -2079,11 +2136,6 @@ function AIRBASE:_InitRunways(IncludeInverse)
-- Runway table. -- Runway table.
local Runways={} local Runways={}
if self:GetAirbaseCategory()~=Airbase.Category.AIRDROME then
self.runways={}
return {}
end
--- Function to create a runway data table. --- Function to create a runway data table.
local function _createRunway(name, course, width, length, center) local function _createRunway(name, course, width, length, center)
@ -2169,7 +2221,7 @@ function AIRBASE:_InitRunways(IncludeInverse)
-- Debug info. -- Debug info.
self:T2(runways) self:T2(runways)
if runways then if runways and #runways>0 then
-- Loop over runways. -- Loop over runways.
for _,rwy in pairs(runways) do for _,rwy in pairs(runways) do
@ -2202,6 +2254,12 @@ function AIRBASE:_InitRunways(IncludeInverse)
end end
end end
else
-- No runways
self.runways={}
return {}
end end