Performance Optimizations

This commit is contained in:
Frank 2020-08-22 00:09:36 +02:00
parent 61adeeeda3
commit aac291c0c6
10 changed files with 304 additions and 138 deletions

View File

@ -254,6 +254,8 @@ end
-- @param #BASE Parent is the Parent class that the Child inherits from.
-- @return #BASE Child
function BASE:Inherit( Child, Parent )
-- Create child.
local Child = routines.utils.deepCopy( Child )
if Child ~= nil then
@ -269,6 +271,7 @@ function BASE:Inherit( Child, Parent )
--Child:_SetDestructor()
end
return Child
end

View File

@ -896,31 +896,25 @@ function DATABASE:_RegisterStatics()
return self
end
--- @param #DATABASE self
--- Register all world airbases.
-- @param #DATABASE self
-- @return #DATABASE self
function DATABASE:_RegisterAirbases()
--[[
local CoalitionsData = { AirbasesRed = coalition.getAirbases( coalition.side.RED ), AirbasesBlue = coalition.getAirbases( coalition.side.BLUE ), AirbasesNeutral = coalition.getAirbases( coalition.side.NEUTRAL ) }
for CoalitionId, CoalitionData in pairs( CoalitionsData ) do
for DCSAirbaseId, DCSAirbase in pairs( CoalitionData ) do
local DCSAirbaseName = DCSAirbase:getName()
self:T( { "Register Airbase:", DCSAirbaseName, DCSAirbase:getID() } )
self:AddAirbase( DCSAirbaseName )
end
end
]]
for DCSAirbaseId, DCSAirbase in pairs(world.getAirbases()) do
local DCSAirbaseName = DCSAirbase:getName()
-- Get the airbase name.
local DCSAirbaseName = DCSAirbase:getName()
-- This gives the incorrect value to be inserted into the airdromeID for DCS 2.5.6!
local airbaseID=DCSAirbase:getID()
-- This gave the incorrect value to be inserted into the airdromeID for DCS 2.5.6. Is fixed now.
local airbaseID=DCSAirbase:getID()
local airbase=self:AddAirbase( DCSAirbaseName )
-- Add and register airbase.
local airbase=self:AddAirbase( DCSAirbaseName )
self:I(string.format("Register Airbase: %s, getID=%d, GetID=%d (unique=%d)", DCSAirbaseName, DCSAirbase:getID(), airbase:GetID(), airbase:GetID(true)))
-- Debug output.
self:I(string.format("Register Airbase: %s, getID=%d, GetID=%d (unique=%d)", DCSAirbaseName, DCSAirbase:getID(), airbase:GetID(), airbase:GetID(true)))
end
return self

View File

@ -228,6 +228,7 @@ do -- COORDINATE
-- @return #COORDINATE
function COORDINATE:New( x, y, z )
--env.info("FF COORDINATE New")
local self = BASE:Inherit( self, BASE:New() ) -- #COORDINATE
self.x = x
self.y = y
@ -717,12 +718,18 @@ do -- COORDINATE
--- Return the 2D distance in meters between the target COORDINATE and the COORDINATE.
-- @param #COORDINATE self
-- @param #COORDINATE TargetCoordinate The target COORDINATE.
-- @param #COORDINATE TargetCoordinate The target COORDINATE. Can also be a DCS#Vec3.
-- @return DCS#Distance Distance The distance in meters.
function COORDINATE:Get2DDistance( TargetCoordinate )
local TargetVec3 = TargetCoordinate:GetVec3()
local SourceVec3 = self:GetVec3()
return ( ( TargetVec3.x - SourceVec3.x ) ^ 2 + ( TargetVec3.z - SourceVec3.z ) ^ 2 ) ^ 0.5
local a={x=TargetCoordinate.x-self.x, y=0, z=TargetCoordinate.z-self.z}
return UTILS.VecNorm(a)
--local TargetVec3 = TargetCoordinate:GetVec3()
--local SourceVec3 = self:GetVec3()
--return ( ( TargetVec3.x - SourceVec3.x ) ^ 2 + ( TargetVec3.z - SourceVec3.z ) ^ 2 ) ^ 0.5
end
--- Returns the temperature in Degrees Celsius.

View File

@ -56,6 +56,7 @@
--- @type ZONE_BASE
-- @field #string ZoneName Name of the zone.
-- @field #number ZoneProbability A value between 0 and 1. 0 = 0% and 1 = 100% probability.
-- @field Core.Point#COORDINATE Coordinate object of the zone.
-- @extends Core.Fsm#FSM
@ -221,22 +222,6 @@ function ZONE_BASE:GetPointVec2()
end
--- Returns a @{Core.Point#COORDINATE} of the zone.
-- @param #ZONE_BASE self
-- @return Core.Point#COORDINATE The Coordinate of the zone.
function ZONE_BASE:GetCoordinate()
self:F2( self.ZoneName )
local Vec2 = self:GetVec2()
local Coordinate = COORDINATE:NewFromVec2( Vec2 )
self:T2( { Coordinate } )
return Coordinate
end
--- Returns the @{DCS#Vec3} of the zone.
-- @param #ZONE_BASE self
-- @param DCS#Distance Height The height to add to the land height where the center of the zone is located.
@ -276,15 +261,27 @@ end
-- @param DCS#Distance Height The height to add to the land height where the center of the zone is located.
-- @return Core.Point#COORDINATE The Coordinate of the zone.
function ZONE_BASE:GetCoordinate( Height ) --R2.1
self:F2( self.ZoneName )
self:F2(self.ZoneName)
local Vec3 = self:GetVec3( Height )
local PointVec3 = COORDINATE:NewFromVec3( Vec3 )
self:T2( { PointVec3 } )
return PointVec3
if self.Coordinate then
-- Update coordinates.
self.Coordinate.x=Vec3.x
self.Coordinate.y=Vec3.y
self.Coordinate.z=Vec3.z
--env.info("FF GetCoordinate NEW for ZONE_BASE "..tostring(self.ZoneName))
else
-- Create a new coordinate object.
self.Coordinate=COORDINATE:NewFromVec3(Vec3)
--env.info("FF GetCoordinate NEW for ZONE_BASE "..tostring(self.ZoneName))
end
return self.Coordinate
end
@ -433,12 +430,16 @@ ZONE_RADIUS = {
-- @param DCS#Distance Radius The radius of the zone.
-- @return #ZONE_RADIUS self
function ZONE_RADIUS:New( ZoneName, Vec2, Radius )
-- Inherit ZONE_BASE.
local self = BASE:Inherit( self, ZONE_BASE:New( ZoneName ) ) -- #ZONE_RADIUS
self:F( { ZoneName, Vec2, Radius } )
self.Radius = Radius
self.Vec2 = Vec2
--self.Coordinate=COORDINATE:NewFromVec2(Vec2)
return self
end

View File

@ -7521,13 +7521,6 @@ function WAREHOUSE:_FindParkingForAssets(airbase, assets)
for i,unit in pairs(units) do
local coord=COORDINATE:New(unit.x, unit.alt, unit.y)
coords[unit.name]=coord
--[[
local airbase=coord:GetClosestAirbase()
local _,TermID, dist, spot=coord:GetClosestParkingSpot(airbase)
if dist<=10 then
env.info(string.format("Found client %s on parking spot %d at airbase %s", unit.name, TermID, airbase:GetName()))
end
]]
end
end
return coords
@ -7538,6 +7531,12 @@ function WAREHOUSE:_FindParkingForAssets(airbase, assets)
-- List of obstacles.
local obstacles={}
-- Check all clients. Clients dont change so we can put that out of the loop.
local clientcoords=_clients()
for clientname,_coord in pairs(clientcoords) do
table.insert(obstacles, {coord=_coord, size=15, name=clientname, type="client"})
end
-- Loop over all parking spots and get the currently present obstacles.
-- How long does this take on very large airbases, i.e. those with hundereds of parking spots? Seems to be okay!
@ -7553,22 +7552,16 @@ function WAREHOUSE:_FindParkingForAssets(airbase, assets)
-- Check all units.
for _,_unit in pairs(_units) do
local unit=_unit --Wrapper.Unit#UNIT
local _coord=unit:GetCoordinate()
local _coord=unit:GetVec3()
local _size=self:_GetObjectSize(unit:GetDCSObject())
local _name=unit:GetName()
table.insert(obstacles, {coord=_coord, size=_size, name=_name, type="unit"})
end
-- Check all clients.
local clientcoords=_clients()
for clientname,_coord in pairs(clientcoords) do
table.insert(obstacles, {coord=_coord, size=15, name=clientname, type="client"})
end
-- Check all statics.
for _,static in pairs(_statics) do
local _vec3=static:getPoint()
local _coord=COORDINATE:NewFromVec3(_vec3)
local _coord=static:getPoint()
--local _coord=COORDINATE:NewFromVec3(_vec3)
local _name=static:getName()
local _size=self:_GetObjectSize(static)
table.insert(obstacles, {coord=_coord, size=_size, name=_name, type="static"})
@ -7576,11 +7569,11 @@ function WAREHOUSE:_FindParkingForAssets(airbase, assets)
-- Check all scenery.
for _,scenery in pairs(_sceneries) do
local _vec3=scenery:getPoint()
local _coord=COORDINATE:NewFromVec3(_vec3)
local _coord=scenery:getPoint()
--local _coord=COORDINATE:NewFromVec3(_vec3)
local _name=scenery:getTypeName()
local _size=self:_GetObjectSize(scenery)
table.insert(obstacles,{coord=_coord, size=_size, name=_name, type="scenery"})
table.insert(obstacles, {coord=_coord, size=_size, name=_name, type="scenery"})
end
end

View File

@ -49,6 +49,7 @@
-- @field #boolean detectionOn If true, detected units of the group are analyzed.
-- @field Ops.Auftrag#AUFTRAG missionpaused Paused mission.
--
-- @field Core.Point#COORDINATE coordinate Current coordinate.
-- @field Core.Point#COORDINATE position Position of the group at last status check.
-- @field #number traveldist Distance traveled in meters. This is a lower bound!
-- @field #number traveltime Time.
@ -481,15 +482,36 @@ function OPSGROUP:GetName()
return self.groupname
end
--- Get current 3D vector of the group.
-- @param #OPSGROUP self
-- @return DCS#Vec3 Vector with x,y,z components.
function OPSGROUP:GetVec3()
if self.group:IsAlive() then
self.group:GetVec3()
end
return nil
end
--- Get current coordinate of the group.
-- @param #OPSGROUP self
-- @return Core.Point#COORDINATE The coordinate (of the first unit) of the group.
function OPSGROUP:GetCoordinate()
if self:IsAlive()~=nil then
return self.group:GetCoordinate()
local vec3=self:GetVec3()
if vec3 then
self.coordinate=self.coordinate or COORDINATE:New(0,0,0)
self.coordinate.x=vec3.x
self.coordinate.y=vec3.y
self.coordinate.z=vec3.z
return self.coordinate
else
self:E(self.lid.."WARNING: Group is not alive. Cannot get coordinate!")
end
return nil
end

View File

@ -21,7 +21,8 @@
-- @field #number TstartGame Game start time timer.getTime().
-- @field #number TstartOS OS real start time os.clock.
-- @field #boolean logUnknown Log unknown functions. Default is off.
-- @field #number lowCpsThres Low calls per second threashold. Only write output if function has more calls per second than this value.
-- @field #number ThreshCPS Low calls per second threshold. Only write output if function has more calls per second than this value.
-- @field #number ThreshTtot Total time threshold. Only write output if total function CPU time is more than this value.
-- @field #string fileNamePrefix Output file name prefix, e.g. "MooseProfiler".
-- @field #string fileNameSuffix Output file name prefix, e.g. "txt"
@ -76,7 +77,7 @@
--
-- If you only want output for functions that are called more than X times per second, you can set
--
-- PROFILER.lowCpsThres=1.5
-- PROFILER.ThreshCPS=1.5
--
-- With this setting, only functions which are called more than 1.5 times per second are displayed.
--
@ -89,7 +90,8 @@ PROFILER = {
fTimeTotal = {},
eventHandler = {},
logUnknown = false,
lowCpsThres = 0.0,
ThreshCPS = 0.0,
ThreshTtot = 0.005,
fileNamePrefix = "MooseProfiler",
fileNameSuffix = "txt"
}
@ -147,7 +149,8 @@ function PROFILER.Start(Delay, Duration)
else
env.info(string.format("- Will be stopped when mission ends"))
end
env.info(string.format("- Calls per second threshold %.3f/sec", PROFILER.lowCpsThres))
env.info(string.format("- Calls per second threshold %.3f/sec", PROFILER.ThreshCPS))
env.info(string.format("- Total function time threshold %.3f/sec", PROFILER.ThreshTtot))
env.info(string.format("- Output file \"%s\" in your DCS log file folder", PROFILER.getfilename()))
env.info('###############################################################################')
@ -283,7 +286,10 @@ function PROFILER.showTable(data, f, runTimeGame)
-- Calls per second.
local cps=t.count/runTimeGame
if cps>=PROFILER.lowCpsThres then
local threshCPS=cps>=PROFILER.ThreshCPS
local threshTot=t.tm>=PROFILER.ThreshTtot
if threshCPS and threshTot then
-- Output
local text=string.format("%30s: %8d calls %8.1f/sec - Time Total %8.3f sec (%.3f %%) %5.3f sec/call %s line %s", t.func, t.count, cps, t.tm, t.tm/runTimeGame*100, t.tm/t.count, tostring(t.src), tostring(t.line))

View File

@ -191,21 +191,30 @@ end
-- @param #table object The input table.
-- @return #table Copy of the input table.
UTILS.DeepCopy = function(object)
local lookup_table = {}
-- Copy function.
local function _copy(object)
if type(object) ~= "table" then
return object
elseif lookup_table[object] then
return lookup_table[object]
end
local new_table = {}
lookup_table[object] = new_table
for index, value in pairs(object) do
new_table[_copy(index)] = _copy(value)
end
return setmetatable(new_table, getmetatable(object))
end
local objectreturn = _copy(object)
return objectreturn
end

View File

@ -15,6 +15,15 @@
--- @type AIRBASE
-- @field #string ClassName Name of the class, i.e. "AIRBASE".
-- @field #table CategoryName Names of airbase categories.
-- @field #string AirbaseName Name of the airbase.
-- @field #number AirbaseID Airbase ID.
-- @field #number category Airbase category.
-- @field #table descriptors DCS descriptors.
-- @field #boolean isAirdrome Airbase is an airdrome.
-- @field #boolean isHelipad Airbase is a helipad.
-- @field #boolean isShip Airbase is a ship.
-- @field #table parking Parking spot data.
-- @field #table parkingByID Parking spot data table with ID as key.
-- @field #number activerwyno Active runway number (forced).
-- @extends Wrapper.Positionable#POSITIONABLE
@ -445,15 +454,44 @@ AIRBASE.TerminalType = {
--- Create a new AIRBASE from DCSAirbase.
-- @param #AIRBASE self
-- @param #string AirbaseName The name of the airbase.
-- @return Wrapper.Airbase#AIRBASE
function AIRBASE:Register( AirbaseName )
-- @return #AIRBASE self
function AIRBASE:Register(AirbaseName)
local self = BASE:Inherit( self, POSITIONABLE:New( AirbaseName ) ) --#AIRBASE
self.AirbaseName = AirbaseName
self.AirbaseID = self:GetID(true)
-- Inherit everything from positionable.
local self=BASE:Inherit(self, POSITIONABLE:New(AirbaseName)) --#AIRBASE
-- Set airbase name.
self.AirbaseName=AirbaseName
-- Set airbase ID.
self.AirbaseID=self:GetID(true)
-- Get descriptors.
self.descriptors=self:GetDesc()
-- Category.
self.category=self.descriptors and self.descriptors.category or Airbase.Category.AIRDROME
-- Set category.
if self.category==Airbase.Category.AIRDROME then
self.isAirdrome=true
elseif self.category==Airbase.Category.HELIPAD then
self.isHelipad=true
elseif self.category==Airbase.Category.SHIP then
self.isShip=true
else
self:E("ERROR: Unknown airbase category!")
end
self:_InitParkingSpots()
local vec2=self:GetVec2()
-- Init coordinate.
self:GetCoordinate()
if vec2 then
self.AirbaseZone = ZONE_RADIUS:New( AirbaseName, vec2, 2500 )
self.AirbaseZone=ZONE_RADIUS:New( AirbaseName, vec2, 2500 )
else
self:E(string.format("ERROR: Cound not get position Vec2 of airbase %s", AirbaseName))
end
@ -508,7 +546,9 @@ end
-- @param #AIRBASE self
-- @return DCS#Airbase DCS airbase object.
function AIRBASE:GetDCSObject()
local DCSAirbase = Airbase.getByName( self.AirbaseName )
-- Get the DCS object.
local DCSAirbase = Airbase.getByName(self.AirbaseName)
if DCSAirbase then
return DCSAirbase
@ -533,7 +573,7 @@ function AIRBASE.GetAllAirbases(coalition, category)
local airbases={}
for _,_airbase in pairs(_DATABASE.AIRBASES) do
local airbase=_airbase --#AIRBASE
if (coalition~=nil and airbase:GetCoalition()==coalition) or coalition==nil then
if coalition==nil or airbase:GetCoalition()==coalition then
if category==nil or category==airbase:GetAirbaseCategory() then
table.insert(airbases, airbase)
end
@ -564,23 +604,7 @@ function AIRBASE:GetID(unique)
local airbaseID=tonumber(DCSAirbase:getID())
local airbaseCategory=self:GetAirbaseCategory()
--env.info(string.format("FF airbase=%s id=%s category=%s", tostring(AirbaseName), tostring(airbaseID), tostring(airbaseCategory)))
-- No way AFIK to get the DCS version. So we check if the event exists. That should tell us if we are on DCS 2.5.6 or prior to that.
--[[
if world.event.S_EVENT_KILL and world.event.S_EVENT_KILL>0 and airbaseCategory==Airbase.Category.AIRDROME then
-- We have to take the key value of this loop!
airbaseID=DCSAirbaseId
-- Now another quirk: for Caucasus, we need to add 11 to the key value to get the correct ID. See https://forums.eagle.ru/showpost.php?p=4210774&postcount=11
if UTILS.GetDCSMap()==DCSMAP.Caucasus then
airbaseID=airbaseID+11
end
end
]]
if AirbaseName==self.AirbaseName then
if airbaseCategory==Airbase.Category.SHIP or airbaseCategory==Airbase.Category.HELIPAD then
-- Ships get a negative sign as their unit number might be the same as the ID of another airbase.
@ -728,6 +752,69 @@ function AIRBASE:GetParkingSpotsCoordinates(termtype)
return spots
end
--- Get a table containing the coordinates, terminal index and terminal type of free parking spots at an airbase.
-- @param #AIRBASE self
-- @return#AIRBASE self
function AIRBASE:_InitParkingSpots()
-- Get parking data of all spots (free or occupied)
local parkingdata=self:GetParkingData(false)
-- Init table.
self.parking={}
self.parkingByID={}
self.NparkingTotal=0
self.NparkingX=0
self.NparkingY=0
-- Put coordinates of parking spots into table.
for _,spot in pairs(parkingdata) do
-- New parking spot.
local park={} --#AIRBASE.ParkingSpot
park.Vec3=spot.vTerminalPos
park.Coordinate=COORDINATE:NewFromVec3(spot.vTerminalPos)
park.DistToRwy=spot.fDistToRW
park.Free=nil
park.TerminalID=spot.Term_Index
park.TerminalID0=spot.Term_Index_0
park.TerminalType=spot.Term_Type
park.TOAC=spot.TO_AC
if park.TerminalID==AIRBASE.TerminalType.FighterAircraft then
elseif park.TerminalID==AIRBASE.TerminalType.HelicopterOnly then
elseif park.TerminalID==AIRBASE.TerminalType.HelicopterUsable then
elseif park.TerminalID==AIRBASE.TerminalType.OpenBig then
elseif park.TerminalID==AIRBASE.TerminalType.OpenMed then
elseif park.TerminalID==AIRBASE.TerminalType.OpenMedOrBig then
elseif park.TerminalID==AIRBASE.TerminalType.Runway then
elseif park.TerminalID==AIRBASE.TerminalType.Shelter then
end
self.parkingByID[park.TerminalID]=park
table.insert(self.parking, park)
end
return self
end
--- Get a table containing the coordinates, terminal index and terminal type of free parking spots at an airbase.
-- @param #AIRBASE self
-- @param #number TerminalID Terminal ID.
-- @return #AIRBASE.ParkingSpot Parking spot.
function AIRBASE:_GetParkingSpotByID(TerminalID)
return self.parkingByID[TerminalID]
end
--- Get a table containing the coordinates, terminal index and terminal type of free parking spots at an airbase.
-- @param #AIRBASE self
@ -737,6 +824,7 @@ function AIRBASE:GetParkingSpotsTable(termtype)
-- Get parking data of all spots (free or occupied)
local parkingdata=self:GetParkingData(false)
-- Get parking data of all free spots.
local parkingfree=self:GetParkingData(true)
@ -753,16 +841,19 @@ function AIRBASE:GetParkingSpotsTable(termtype)
-- Put coordinates of parking spots into table.
local spots={}
for _,_spot in pairs(parkingdata) do
if AIRBASE._CheckTerminalType(_spot.Term_Type, termtype) then
self:T2({_spot=_spot})
local _free=_isfree(_spot)
local _coord=COORDINATE:NewFromVec3(_spot.vTerminalPos)
table.insert(spots, {Coordinate=_coord, TerminalID=_spot.Term_Index, TerminalType=_spot.Term_Type, TOAC=_spot.TO_AC, Free=_free, TerminalID0=_spot.Term_Index_0, DistToRwy=_spot.fDistToRW})
local spot=self:_GetParkingSpotByID(_spot.Term_Index)
spot.Free=_isfree(_spot) -- updated
spot.TOAC=_spot.TO_AC -- updated
table.insert(spots, spot)
end
end
self:T2({ spots = spots } )
return spots
end
@ -781,8 +872,14 @@ function AIRBASE:GetFreeParkingSpotsTable(termtype, allowTOAC)
for _,_spot in pairs(parkingfree) do
if AIRBASE._CheckTerminalType(_spot.Term_Type, termtype) and _spot.Term_Index>0 then
if (allowTOAC and allowTOAC==true) or _spot.TO_AC==false then
local _coord=COORDINATE:NewFromVec3(_spot.vTerminalPos)
table.insert(freespots, {Coordinate=_coord, TerminalID=_spot.Term_Index, TerminalType=_spot.Term_Type, TOAC=_spot.TO_AC, Free=true, TerminalID0=_spot.Term_Index_0, DistToRwy=_spot.fDistToRW})
local spot=self:_GetParkingSpotByID(_spot.Term_Index)
spot.Free=true -- updated
spot.TOAC=_spot.TO_AC -- updated
table.insert(freespots, spot)
end
end
end
@ -795,14 +892,10 @@ end
-- @param #number TerminalID The terminal ID of the parking spot.
-- @return #AIRBASE.ParkingSpot Table free parking spots. Table has the elements ".Coordinate, ".TerminalID", ".TerminalType", ".TOAC", ".Free", ".TerminalID0", ".DistToRwy".
function AIRBASE:GetParkingSpotData(TerminalID)
self:F({TerminalID=TerminalID})
-- Get parking data.
local parkingdata=self:GetParkingSpotsTable()
-- Debug output.
self:T2({parkingdata=parkingdata})
for _,_spot in pairs(parkingdata) do
local spot=_spot --#AIRBASE.ParkingSpot
self:T({TerminalID=spot.TerminalID,TerminalType=spot.TerminalType})
@ -1065,13 +1158,6 @@ function AIRBASE:CheckOnRunWay(group, radius, despawn)
-- Get coordinates on runway.
local runwaypoints=self:GetParkingSpotsCoordinates(AIRBASE.TerminalType.Runway)
-- Mark runway spawn points.
--[[
for _i,_coord in pairs(runwaypoints) do
_coord:MarkToAll(string.format("runway %d",_i))
end
]]
-- Get units of group.
local units=group:GetUnits()
@ -1118,22 +1204,34 @@ function AIRBASE:CheckOnRunWay(group, radius, despawn)
return false
end
--- Check if airbase is an airdrome.
-- @param #AIRBASE self
-- @return #boolean If true, airbase is an airdrome.
function AIRBASE:IsAirdrome()
return self.isAirdrome
end
--- Check if airbase is a helipad.
-- @param #AIRBASE self
-- @return #boolean If true, airbase is a helipad.
function AIRBASE:IsHelipad()
return self.isHelipad
end
--- Check if airbase is a ship.
-- @param #AIRBASE self
-- @return #boolean If true, airbase is a ship.
function AIRBASE:IsShip()
return self.isShip
end
--- Get category of airbase.
-- @param #AIRBASE self
-- @return #number Category of airbase from GetDesc().category.
function AIRBASE:GetAirbaseCategory()
local desc=self:GetDesc()
local category=Airbase.Category.AIRDROME
if desc and desc.category then
category=desc.category
else
self:E(string.format("ERROR: Cannot get category of airbase %s due to DCS 2.5.6 bug! Assuming it is an AIRDROME for now...", tostring(self.AirbaseName)))
end
return category
return self.category
end
--- Helper function to check for the correct terminal type including "artificial" ones.
-- @param #number Term_Type Termial type from getParking routine.
-- @param #AIRBASE.TerminalType termtype Terminal type from AIRBASE.TerminalType enumerator.

View File

@ -15,6 +15,8 @@
-- @extends Wrapper.Identifiable#IDENTIFIABLE
--- @type POSITIONABLE
-- @field Core.Point#COORDINATE coordinate Coordinate object.
-- @field Core.Point#POINT_VEC3 pointvec3 Point Vec3 object.
-- @extends Wrapper.Identifiable#IDENTIFIABLE
@ -45,6 +47,8 @@
POSITIONABLE = {
ClassName = "POSITIONABLE",
PositionableName = "",
coordinate = nil,
pointvec3 = nil,
}
--- @field #POSITIONABLE.__
@ -268,17 +272,29 @@ end
-- @return Core.Point#POINT_VEC3 The 3D point vector of the POSITIONABLE.
-- @return #nil The POSITIONABLE is not existing or alive.
function POSITIONABLE:GetPointVec3()
self:F2( self.PositionableName )
local DCSPositionable = self:GetDCSObject()
if DCSPositionable then
local PositionableVec3 = self:GetPositionVec3()
local PositionablePointVec3 = POINT_VEC3:NewFromVec3( PositionableVec3 )
self:T2( PositionablePointVec3 )
return PositionablePointVec3
-- Get 3D vector.
local PositionableVec3 = self:GetPositionVec3()
if self.pointvec3 then
--env.info("FF GetCoordinate GOT for "..tostring(self.PositionableName))
-- Update vector.
self.pointvec3.x=PositionableVec3.x
self.pointvec3.y=PositionableVec3.y
self.pointvec3.z=PositionableVec3.z
else
--env.info("FF GetCoordinate NEW for "..tostring(self.PositionableName))
self.pointvec3=POINT_VEC3:NewFromVec3(PositionableVec3)
end
return self.pointvec3
end
BASE:E( { "Cannot GetPointVec3", Positionable = self, Alive = self:IsAlive() } )
@ -290,21 +306,38 @@ end
-- @param Wrapper.Positionable#POSITIONABLE self
-- @return Core.Point#COORDINATE The COORDINATE of the POSITIONABLE.
function POSITIONABLE:GetCoordinate()
self:F2( self.PositionableName )
-- Get DCS object.
local DCSPositionable = self:GetDCSObject()
if DCSPositionable then
-- Get the current position.
local PositionableVec3 = self:GetPositionVec3()
local PositionableCoordinate = COORDINATE:NewFromVec3( PositionableVec3 )
PositionableCoordinate:SetHeading( self:GetHeading() )
PositionableCoordinate:SetVelocity( self:GetVelocityMPS() )
if self.coordinate then
--env.info("FF GetCoordinate GOT for "..tostring(self.PositionableName))
-- Update vector.
self.coordinate.x=PositionableVec3.x
self.coordinate.y=PositionableVec3.y
self.coordinate.z=PositionableVec3.z
else
--env.info("FF GetCoordinate NEW for "..tostring(self.PositionableName))
self.coordinate=COORDINATE:NewFromVec3(PositionableVec3)
end
-- Set heading and velocity.
self.coordinate:SetHeading( self:GetHeading() )
self.coordinate:SetVelocity( self:GetVelocityMPS() )
self:T2( PositionableCoordinate )
return PositionableCoordinate
return self.coordinate
end
-- Error message.
BASE:E( { "Cannot GetCoordinate", Positionable = self, Alive = self:IsAlive() } )
return nil
@ -1533,7 +1566,7 @@ end
--- Returns true if the unit is within a @{Zone}.
-- @param #STPOSITIONABLEATIC self
-- @param #POSITIONABLE self
-- @param Core.Zone#ZONE_BASE Zone The zone to test.
-- @return #boolean Returns true if the unit is within the @{Core.Zone#ZONE_BASE}
function POSITIONABLE:IsInZone( Zone )