This commit is contained in:
Frank
2020-01-25 23:32:41 +01:00
parent 74a4b84b78
commit 50ee8865ed
2 changed files with 385 additions and 188 deletions
+244 -64
View File
@@ -41,7 +41,7 @@
-- @field #number atcfreq ATC radio frequency. -- @field #number atcfreq ATC radio frequency.
-- @field Core.RadioQueue#RADIOQUEUE atcradio ATC radio queue. -- @field Core.RadioQueue#RADIOQUEUE atcradio ATC radio queue.
-- @field #table playermenu Player Menu. -- @field #table playermenu Player Menu.
-- @field #number Nlading Max number of aircraft groups in the landing pattern. -- @field #number Nlanding Max number of aircraft groups in the landing pattern.
-- @field #number dTlanding Time interval in seconds between landing clearance. -- @field #number dTlanding Time interval in seconds between landing clearance.
-- @field #number Nparkingspots Total number of parking spots. -- @field #number Nparkingspots Total number of parking spots.
-- @extends Core.Fsm#FSM -- @extends Core.Fsm#FSM
@@ -119,7 +119,7 @@ FLIGHTCONTROL = {
--- FlightControl class version. --- FlightControl class version.
-- @field #string version -- @field #string version
FLIGHTCONTROL.version="0.1.5" FLIGHTCONTROL.version="0.1.6"
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO list -- TODO list
@@ -303,11 +303,11 @@ end
-- @param #FLIGHTCONTROL self -- @param #FLIGHTCONTROL self
function FLIGHTCONTROL:onafterStatus() function FLIGHTCONTROL:onafterStatus()
-- Scan airbase for units, statics, and scenery. -- Check status of all registered flights.
--self:_CheckAirbase() self:_CheckFlights()
-- Update parking spots. -- Check parking spots.
--self:_UpdateParkingSpots() self:_CheckParking()
-- Check waiting and landing queue. -- Check waiting and landing queue.
self:_CheckQueues() self:_CheckQueues()
@@ -315,31 +315,33 @@ function FLIGHTCONTROL:onafterStatus()
-- Get runway. -- Get runway.
local runway=self:GetActiveRunway() local runway=self:GetActiveRunway()
-- Get free parking spots.
--local nfree=self:_GetFreeParkingSpots()
local nfree=self.Nparkingspots
local Nflights= #self.flights local Nflights= #self.flights
local NQparking=#self.Qparking local NQparking=#self.Qparking
local NQtaxiout=#self.Qtaxiout local NQtaxiout=#self.Qtaxiout
local NQreadyto=#self.Qreadyto local NQreadyto=#self.Qreadyto
local NQtakeoff=#self.Qtakeoff local NQtakeoff=#self.Qtakeoff
--local NQtravel2=#self.Qtravel2 local NQinbound=#self.Qinbound
local NQholding=#self.Qholding local NQholding=#self.Qholding
local NQlanding=#self.Qlanding local NQlanding=#self.Qlanding
local NQtaxiinb=#self.Qtaxiinb local NQtaxiinb=#self.Qtaxiinb
local NQarrived=#self.Qarrived local NQarrived=#self.Qarrived
local Nqueues=NQparking+NQtaxiout+NQreadyto+NQtakeoff+NQholding+NQlanding+NQtaxiinb+NQarrived -- =========================================================================================================
local Nqueues = (NQparking+NQtaxiout+NQreadyto+NQtakeoff) + (NQinbound+NQholding+NQlanding+NQtaxiinb+NQarrived)
-- Count free parking spots.
--TODO: get and substract number of reserved parking spots.
local nfree=self.Nparkingspots-NQarrived-NQparking
-- Info text. -- Info text.
local text=string.format("State %s - Runway %s - Parking %d/%d - Flights=%s: Qpark=%d Qtxout=%d Qready=%d Qto=%d | Qhold=%d Qland=%d Qtxinb=%d Qarr=%d", local text=string.format("State %s - Runway %s - Parking %d/%d - Flights=%s: Qpark=%d Qtxout=%d Qready=%d Qto=%d | Qinbound=%d Qhold=%d Qland=%d Qtxinb=%d Qarr=%d",
self:GetState(), runway.idx, nfree, self.Nparkingspots, #self.flights, #self.Qparking, #self.Qtaxiout, #self.Qreadyto, #self.Qtakeoff, #self.Qholding, #self.Qlanding, #self.Qtaxiinb, #self.Qarrived) self:GetState(), runway.idx, nfree, self.Nparkingspots, #self.flights, #self.Qparking, #self.Qtaxiout, #self.Qreadyto, #self.Qtakeoff, #self.Qinbound, #self.Qholding, #self.Qlanding, #self.Qtaxiinb, #self.Qarrived)
self:I(self.lid..text) self:I(self.lid..text)
if Nflights==Nqueues then if Nflights==Nqueues then
--Check! --Check!
else else
self:I(string.format("Warning: Number of total flights != number of flights in queue: Ntot=%d, Nqueues=%d", Nflights, Nqueues)) self:E(string.format("WARNING: Number of total flights %d!=%d number of flights in all queues!", Nflights, Nqueues))
end end
-- Next status update in ~30 seconds. -- Next status update in ~30 seconds.
@@ -476,7 +478,7 @@ end
function FLIGHTCONTROL:_CheckQueues() function FLIGHTCONTROL:_CheckQueues()
-- Print queues -- Print queues
if false then if true then
self:_PrintQueue(self.flights, "All flights") self:_PrintQueue(self.flights, "All flights")
self:_PrintQueue(self.Qparking, "Parking") self:_PrintQueue(self.Qparking, "Parking")
self:_PrintQueue(self.Qtaxiout, "TaxiOut") self:_PrintQueue(self.Qtaxiout, "TaxiOut")
@@ -507,7 +509,7 @@ function FLIGHTCONTROL:_CheckQueues()
-- Check if somebody wants something. -- Check if somebody wants something.
if flight and ntakeoff==0 and nlanding<self.Nlanding then if flight then
if isholding then if isholding then
@@ -515,28 +517,34 @@ function FLIGHTCONTROL:_CheckQueues()
-- Holding flight -- -- Holding flight --
-------------------- --------------------
-- Get interval to last flight that got landing clearance. -- No other flight is taking off and number of landing flights is below threshold.
local dTlanding=99999 if ntakeoff==0 and nlanding<self.Nlanding then
if self.Tlanding then
dTlanding=timer.getAbsTime()-self.Tlanding
end
if parking and dTlanding>=self.dTlanding then -- Get interval to last flight that got landing clearance.
local dTlanding=99999
-- Message. if self.Tlanding then
local text=string.format("Flight %s, you are cleared to land.", flight.groupname) dTlanding=timer.getAbsTime()-self.Tlanding
MESSAGE:New(text, 5, "FLIGHTCONTROL"):ToAll()
-- Give AI the landing signal.
-- TODO: Humans have to confirm via F10 menu.
if flight.ai then
flight:FlightLanding()
self:_LandAI(flight, parking)
end end
-- Set time last flight got landing clearance. if parking and dTlanding>=self.dTlanding then
self.Tlanding=timer.getAbsTime()
-- Message.
local text=string.format("Flight %s, you are cleared to land.", flight.groupname)
MESSAGE:New(text, 5, "FLIGHTCONTROL"):ToAll()
-- Give AI the landing signal.
-- TODO: Humans have to confirm via F10 menu.
if flight.ai then
flight:FlightLanding()
self:_LandAI(flight, parking)
end
-- Set time last flight got landing clearance.
self.Tlanding=timer.getAbsTime()
end
else
self:I(self.lid..string.format("FYI: Landing clearance for flight %s denied as other flights are taking off (N=%d) or max. landing reached (N=%d/%d).", flight.groupname, ntakeoff, nlanding, self.Nlanding))
end end
else else
@@ -545,35 +553,41 @@ function FLIGHTCONTROL:_CheckQueues()
-- Takeoff flight -- -- Takeoff flight --
-------------------- --------------------
-- Check if flight is AI. Humans have to request taxi via F10 menu. -- No other flight is taking of or landing.
if flight.ai then if ntakeoff==0 and nlanding==0 then
-- NOTE that AI will start taxiing once they started their engine. -- Check if flight is AI. Humans have to request taxi via F10 menu.
if flight.ai then
-- Message. -- NOTE that AI will start taxiing once they started their engine.
local text=string.format("Flight %s, you are cleared to taxi to runway.", flight.groupname)
self:I(self.lid..text)
MESSAGE:New(text, 5, "FLIGHTCONTROL"):ToAll()
-- Start uncontrolled aircraft. -- Message.
-- TODO: handle case with engines hot. That does not trigger a ENGINE_START event. More a FLIGHTGROUP issue. local text=string.format("Flight %s, you are cleared to taxi to runway.", flight.groupname)
flight.group:StartUncontrolled() self:I(self.lid..text)
MESSAGE:New(text, 5, "FLIGHTCONTROL"):ToAll()
env.info("FF remove flight from parking queue - if possible.") -- Start uncontrolled aircraft.
self:_RemoveFlightFromQueue(self.Qparking, flight, "parking") -- TODO: handle case with engines hot. That does not trigger a ENGINE_START event. More a FLIGHTGROUP issue.
flight.group:StartUncontrolled()
-- Add flight to takeoff queue. env.info("FF remove flight from parking queue - if possible.")
self:_AddFlightToTakeoffQueue(flight) self:_RemoveFlightFromQueue(self.Qparking, flight, "parking")
-- Add flight to takeoff queue.
self:_AddFlightToTakeoffQueue(flight)
else
local text=string.format("HUMAN Flight %s, you are cleared for takeoff.", flight.groupname)
self:I(self.lid..text)
MESSAGE:New(text, 5, "FLIGHTCONTROL"):ToAll()
end
else else
local text=string.format("HUMAN Flight %s, you are cleared for takeoff.", flight.groupname) self:I(self.lid..string.format("FYI: Take of for flight %s denied as other flights are taking off (N=%d) or landing (N=%d).", flight.groupname, ntakeoff, nlanding))
self:I(self.lid..text)
MESSAGE:New(text, 5, "FLIGHTCONTROL"):ToAll()
end end
end end
else
self:I(self.lid..string.format("FYI: No flight in queue for takeoff or landing."))
end end
end end
@@ -702,7 +716,7 @@ function FLIGHTCONTROL:_GetNextFightParking()
return self.Qtaxiout[1] return self.Qtaxiout[1]
end end
-- Check special cases where only up to one flight is waiting for takeoff.
if #self.Qparking==0 then if #self.Qparking==0 then
return nil return nil
elseif #self.Qparking==1 then elseif #self.Qparking==1 then
@@ -725,6 +739,7 @@ end
-- @param #FLIGHTCONTROL self -- @param #FLIGHTCONTROL self
-- @param #table queue Queue to print. -- @param #table queue Queue to print.
-- @param #string name Queue name. -- @param #string name Queue name.
-- @return #string Queue text.
function FLIGHTCONTROL:_PrintQueue(queue, name) function FLIGHTCONTROL:_PrintQueue(queue, name)
local text=string.format("%s Queue N=%d:", name, #queue) local text=string.format("%s Queue N=%d:", name, #queue)
@@ -780,7 +795,9 @@ function FLIGHTCONTROL:_PrintQueue(queue, name)
end end
-- Display text. -- Display text.
self:T(self.lid..text) self:I(self.lid..text)
return text
end end
--- Remove a flight group from a queue. --- Remove a flight group from a queue.
@@ -815,6 +832,29 @@ function FLIGHTCONTROL:_RemoveFlightFromQueue(queue, flight, queuename)
return false, nil return false, nil
end end
--- Add flight to inbound queue (flights that are traveling to the holding pattern).
-- @param #FLIGHTCONTROL self
-- @param Ops.FlightGroup#FLIGHTGROUP flight Flight group.
-- @return #boolean If true, flight was added. False otherwise.
function FLIGHTCONTROL:_AddFlightToInboundQueue(flight)
-- Check if already in queue.
if self:_InQueue(self.Qinbound, flight.group) then
self:E(self.lid..string.format("WARNING: Flight %s is already in INBOUND queue.", flight.groupname))
return false
else
self:T(self.lid..string.format("Adding flight %s to INBOUND queue.", flight.groupname))
end
-- Add flight to table.
table.insert(self.Qinbound, flight)
-- Flight is not holding yet. Clear Tholding in any case.
flight.Tholding=nil
return true
end
--- Add flight to holding queue. --- Add flight to holding queue.
-- @param #FLIGHTCONTROL self -- @param #FLIGHTCONTROL self
-- @param Ops.FlightGroup#FLIGHTGROUP flight Flight group. -- @param Ops.FlightGroup#FLIGHTGROUP flight Flight group.
@@ -856,6 +896,23 @@ function FLIGHTCONTROL:_AddFlightToLandingQueue(flight)
return true return true
end end
--- Add flight to taxi inbound queue. These are flights that just landed and are taxiing to their parking position.
-- @param #FLIGHTCONTROL self
-- @param Ops.FlightGroup#FLIGHTGROUP flight Flight group.
-- @return #boolean If true, flight was added. False otherwise.
function FLIGHTCONTROL:_AddFlightToTaxiInboundQueue(flight)
-- Check if already in queue.
if self:_InQueue(self.Qtaxiinb, flight.group) then
return false
end
-- Add flight to table.
table.insert(self.Qtaxiinb, flight)
return true
end
--- Add flight to parking queue. --- Add flight to parking queue.
-- @param #FLIGHTCONTROL self -- @param #FLIGHTCONTROL self
-- @param Ops.FlightGroup#FLIGHTGROUP flight Flight group. -- @param Ops.FlightGroup#FLIGHTGROUP flight Flight group.
@@ -876,6 +933,24 @@ function FLIGHTCONTROL:_AddFlightToParkingQueue(flight)
return true return true
end end
--- Add flight to arrived queue. These are flights that have arrived at their parking position.
-- @param #FLIGHTCONTROL self
-- @param Ops.FlightGroup#FLIGHTGROUP flight Flight group.
-- @return #boolean If true, flight was added. False otherwise.
function FLIGHTCONTROL:_AddFlightToArrivedQueue(flight)
-- Check if already in queue.
if self:_InQueue(self.Qarrived, flight.group) then
return false
end
-- Add flight to table.
table.insert(self.Qarrived, flight)
return true
end
--- Add flight to taxi out for takeoff queue. --- Add flight to taxi out for takeoff queue.
-- @param #FLIGHTCONTROL self -- @param #FLIGHTCONTROL self
-- @param Ops.FlightGroup#FLIGHTGROUP flight Flight group. -- @param Ops.FlightGroup#FLIGHTGROUP flight Flight group.
@@ -1000,6 +1075,27 @@ function FLIGHTCONTROL:_InitParkingSpots()
-- Init parking spots table. -- Init parking spots table.
self.parking={} self.parking={}
-- Get client coordinates.
local function _clients()
local clients=_DATABASE.CLIENTS
local coords={}
for clientname, client in pairs(clients) do
local template=_DATABASE:GetGroupTemplateFromUnitName(clientname)
local units=template.units
for i,unit in pairs(units) do
local coord=COORDINATE:New(unit.x, unit.alt, unit.y)
coords[unit.name]=coord
local _,TermID, dist, spot=coord:GetClosestParkingSpot(self.airbase)
if dist<=10 then
self:I(self.lid..string.format("Found client %s on parking spot %d", tostring(unit.name), TermID))
self.parking[TermID].Reserved=tostring(unit.name)
end
end
end
end
self.Nparkingspots=0 self.Nparkingspots=0
for _,_spot in pairs(parkingdata) do for _,_spot in pairs(parkingdata) do
local spot=_spot --Wrapper.Airbase#AIRBASE.ParkingSpot local spot=_spot --Wrapper.Airbase#AIRBASE.ParkingSpot
@@ -1011,7 +1107,7 @@ function FLIGHTCONTROL:_InitParkingSpots()
-- Mark position. -- Mark position.
local text=string.format("ID=%d, Terminal=%d, Free=%s, Reserved=%s, Dist=%.1f", parking.TerminalID, parking.TerminalType, tostring(parking.Free), tostring(parking.reserved), parking.DistToRwy) local text=string.format("ID=%d, Terminal=%d, Free=%s, Reserved=%s, Dist=%.1f", parking.TerminalID, parking.TerminalType, tostring(parking.Free), tostring(parking.Reserved), parking.DistToRwy)
-- Add to table. -- Add to table.
self.parking[parking.TerminalID]=parking self.parking[parking.TerminalID]=parking
@@ -1019,6 +1115,9 @@ function FLIGHTCONTROL:_InitParkingSpots()
self.Nparkingspots=self.Nparkingspots+1 self.Nparkingspots=self.Nparkingspots+1
end end
-- Check clients.
_clients()
end end
@@ -1035,7 +1134,7 @@ function FLIGHTCONTROL:_GetFreeParkingSpots(terminal)
for _,_parking in pairs(self.parking) do for _,_parking in pairs(self.parking) do
local parking=_parking --#FLIGHTCONTROL.ParkingSpot local parking=_parking --#FLIGHTCONTROL.ParkingSpot
if parking.Free and parking.TOAC==false and not parking.reserved then if parking.Free and parking.TOAC==false and not parking.Reserved then
if terminal==nil or terminal==parking.terminal then if terminal==nil or terminal==parking.terminal then
n=n+1 n=n+1
table.insert(freespots, parking) table.insert(freespots, parking)
@@ -1179,9 +1278,14 @@ function FLIGHTCONTROL:_CreatePlayerMenu(flight, atcmenu)
local rootmenu=atcmenu[airbasename].root --Core.Menu#MENU_GROUP_DELAYED local rootmenu=atcmenu[airbasename].root --Core.Menu#MENU_GROUP_DELAYED
-- Some info.
local helpmenu=MENU_GROUP_DELAYED:New(group, "Help", rootmenu):SetTime(Tnow):SetTag(Tag)
-- Some info. -- Some info.
local infomenu=MENU_GROUP_DELAYED:New(group, "Info", rootmenu):SetTime(Tnow):SetTag(Tag) local infomenu=MENU_GROUP_DELAYED:New(group, "Info", rootmenu):SetTime(Tnow):SetTag(Tag)
MENU_GROUP_COMMAND_DELAYED:New(group, "Request Info", infomenu, self._PlayerRequestInfo, self, groupname):SetTime(Tnow):SetTag(Tag) MENU_GROUP_COMMAND_DELAYED:New(group, "Airbase", infomenu, self._PlayerRequestInfo, self, groupname):SetTime(Tnow):SetTag(Tag)
MENU_GROUP_COMMAND_DELAYED:New(group, "Queues", infomenu, self._PlayerRequestInfoQueues, self, groupname):SetTime(Tnow):SetTag(Tag)
MENU_GROUP_COMMAND_DELAYED:New(group, "ATIS", infomenu, self._PlayerRequestInfoATIS, self, groupname):SetTime(Tnow):SetTag(Tag)
-- Root Commands -- Root Commands
if flight.flightcontrol and flight.flightcontrol.airbasename==self.airbasename then if flight.flightcontrol and flight.flightcontrol.airbasename==self.airbasename then
@@ -1193,7 +1297,7 @@ function FLIGHTCONTROL:_CreatePlayerMenu(flight, atcmenu)
elseif flight:IsAirborne() then elseif flight:IsAirborne() then
end end
if flight:IsLanding() or flight:IsLanded() then if flight:IsInbound() or flight:IsHolding() or flight:IsLanding() or flight:IsLanded() or true then
MENU_GROUP_COMMAND_DELAYED:New(group, "Request Parking", rootmenu, self._PlayerRequestParking, self, groupname):SetTime(Tnow):SetTag(Tag) MENU_GROUP_COMMAND_DELAYED:New(group, "Request Parking", rootmenu, self._PlayerRequestParking, self, groupname):SetTime(Tnow):SetTag(Tag)
end end
else else
@@ -1203,7 +1307,7 @@ function FLIGHTCONTROL:_CreatePlayerMenu(flight, atcmenu)
end end
if flight.flightcontrol and flight.flightcontrol.airbasename==self.airbasename then if flight.flightcontrol and flight.flightcontrol.airbasename==self.airbasename then
MENU_GROUP_COMMAND_DELAYED:New(group, "My Status", rootmenu, self._PlayerMyStatus, self, groupname):SetTime(Tnow):SetTag(Tag) MENU_GROUP_COMMAND_DELAYED:New(group, "My Status", rootmenu, self._PlayerMyStatus, self, groupname):SetTime(Tnow):SetTag(Tag)
end end
-- Reset the menu. -- Reset the menu.
@@ -1247,6 +1351,23 @@ function FLIGHTCONTROL:_PlayerRequestParking(groupname)
end end
--- Player menu request info.
-- @param #FLIGHTCONTROL self
-- @param #string groupname Name of the flight group.
function FLIGHTCONTROL:_PlayerRequestInfo(groupname)
-- Get flight group.
local flight=_DATABASE:GetFlightGroup(groupname)
if flight then
end
end
--- Player menu request info. --- Player menu request info.
-- @param #FLIGHTCONTROL self -- @param #FLIGHTCONTROL self
-- @param #string groupname Name of the flight group. -- @param #string groupname Name of the flight group.
@@ -1260,9 +1381,14 @@ function FLIGHTCONTROL:_PlayerRequestInfo(groupname)
-- --
local text=string.format("Airbase %s Status:", self.airbasename) local text=string.format("Airbase %s Status:", self.airbasename)
text=text..string.format("\nFlights %d", #self.flights) text=text..string.format("\nFlights %d", #self.flights)
text=text..string.format("\nQlanding %d", #self.Qlanding) text=text..string.format("\nQinbound %d", #self.Qinbound)
text=text..string.format("\nQholding %d", #self.Qholding) text=text..string.format("\nQholding %d", #self.Qholding)
text=text..string.format("\nQlanding %d", #self.Qlanding)
text=text..string.format("\nQtaxiInb %d", #self.Qtaxiinb)
text=text..string.format("\nQarrived %d", #self.Qarrived)
text=text..string.format("\nQparking %d", #self.Qparking) text=text..string.format("\nQparking %d", #self.Qparking)
text=text..string.format("\nQtaxiOut %d", #self.Qtaxiout)
text=text..string.format("\nQreadiTO %d", #self.Qreadyto)
text=text..string.format("\nQtakeoff %d", #self.Qtakeoff) text=text..string.format("\nQtakeoff %d", #self.Qtakeoff)
text=text..string.format("\nRunway %s", self:GetActiveRunwayText()) text=text..string.format("\nRunway %s", self:GetActiveRunwayText())
if self.atis then if self.atis then
@@ -1543,9 +1669,59 @@ function FLIGHTCONTROL:_GetFlightElement(unitname)
end end
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Routing Functions -- Check Sanity Functions
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- Check status of all registered flights and do some sanity checks.
-- @param #FLIGHTCONTROL self
function FLIGHTCONTROL:_CheckFlights()
-- First remove all dead flights.
for i=#self.flights,1,-1 do
local flight=self.flights[i] --Ops.FlightGroup#FLIGHTGROUP
if flight:IsDead() then
self:I(self.lid..string.format("Removing DEAD flight %s", tostring(flight.groupname)))
self:_RemoveFlight(flight)
end
end
--TODO: check parking?
end
--- Check status of all registered flights and do some sanity checks.
-- @param #FLIGHTCONTROL self
function FLIGHTCONTROL:_CheckParking()
for TerminalID,_spot in pairs(self.parking) do
local spot=_spot --Wrapper.Airbase#AIRBASE.ParkingSpot
if spot.Reserved then
if spot.MarkerID then
spot.Coordinate:RemoveMark(spot.MarkerID)
end
spot.MarkerID=spot.Coordinate:MarkToCoalition(string.format("Parking reserved for %s", tostring(spot.Reserved)), self.airbase:GetCoalition())
end
-- First remove all dead flights.
for i=#self.flights,1,-1 do
local flight=self.flights[i] --Ops.FlightGroup#FLIGHTGROUP
for _,_element in pairs(flight.elements) do
local element=_element --Ops.FlightGroup#FLIGHTGROUP.Element
if element.parking and element.parking.TerminalID==TerminalID then
if spot.MarkerID then
spot.Coordinate:RemoveMark(spot.MarkerID)
end
spot.MarkerID=spot.Coordinate:MarkToCoalition(string.format("Parking spot occupied by %s", tostring(element.name)), self.airbase:GetCoalition())
end
end
end
end
end
--- Scan airbase zone for units, statics and scenery. --- Scan airbase zone for units, statics and scenery.
-- @param #FLIGHTCONTROL self -- @param #FLIGHTCONTROL self
-- @return Core.Set#SET_UNIT Set of scanned units. -- @return Core.Set#SET_UNIT Set of scanned units.
@@ -1670,6 +1846,10 @@ function FLIGHTCONTROL:_CheckACstatus(unitset)
end end
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Routing Functions
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- Tell AI to land at the airbase. Flight is added to the landing queue. --- Tell AI to land at the airbase. Flight is added to the landing queue.
-- @param #FLIGHTCONTROL self -- @param #FLIGHTCONTROL self
-- @param Ops.FlightGroup#FLIGHTGROUP flight Flight group. -- @param Ops.FlightGroup#FLIGHTGROUP flight Flight group.
+130 -113
View File
@@ -19,7 +19,7 @@
-- @type FLIGHTGROUP -- @type FLIGHTGROUP
-- @field #string ClassName Name of the class. -- @field #string ClassName Name of the class.
-- @field #boolean Debug Debug mode. Messages to all about status. -- @field #boolean Debug Debug mode. Messages to all about status.
-- @field #string sid Class id string for output to DCS log file. -- @field #string lid Class id string for output to DCS log file.
-- @field #string groupname Name of flight group. -- @field #string groupname Name of flight group.
-- @field Wrapper.Group#GROUP group Flight group object. -- @field Wrapper.Group#GROUP group Flight group object.
-- @field #string type Aircraft type of flight group. -- @field #string type Aircraft type of flight group.
@@ -100,7 +100,7 @@
FLIGHTGROUP = { FLIGHTGROUP = {
ClassName = "FLIGHTGROUP", ClassName = "FLIGHTGROUP",
Debug = false, Debug = false,
sid = nil, lid = nil,
groupname = nil, groupname = nil,
group = nil, group = nil,
grouptemplate = nil, grouptemplate = nil,
@@ -263,7 +263,7 @@ FLIGHTGROUP.TaskType={
--- FLIGHTGROUP class version. --- FLIGHTGROUP class version.
-- @field #string version -- @field #string version
FLIGHTGROUP.version="0.2.2" FLIGHTGROUP.version="0.2.3"
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO list -- TODO list
@@ -298,7 +298,7 @@ function FLIGHTGROUP:New(groupname)
-- First check if we already have a flight group for this group. -- First check if we already have a flight group for this group.
local fg=_DATABASE:GetFlightGroup(groupname) local fg=_DATABASE:GetFlightGroup(groupname)
if fg then if fg then
fg:I(fg.sid..string.format("WARNING: Flight group %s already exists in data base!", groupname)) fg:I(fg.lid..string.format("WARNING: Flight group %s already exists in data base!", groupname))
return fg return fg
end end
@@ -309,7 +309,7 @@ function FLIGHTGROUP:New(groupname)
self.groupname=tostring(groupname) self.groupname=tostring(groupname)
-- Set some string id for output to DCS.log file. -- Set some string id for output to DCS.log file.
self.sid=string.format("FLIGHTGROUP %s | ", self.groupname) self.lid=string.format("FLIGHTGROUP %s | ", self.groupname)
-- Start State. -- Start State.
self:SetStartState("Stopped") self:SetStartState("Stopped")
@@ -337,8 +337,8 @@ function FLIGHTGROUP:New(groupname)
self:AddTransition("*", "UpdateRoute", "*") -- Update route of group. Only if airborne. self:AddTransition("*", "UpdateRoute", "*") -- Update route of group. Only if airborne.
self:AddTransition("*", "RTB", "Returning") -- Group is returning to base. self:AddTransition("*", "RTB", "Returning") -- Group is returning to base.
self:AddTransition("*", "Orbit", "Orbiting") -- Group is holding position. self:AddTransition("*", "Orbit", "Orbiting") -- Group is is orbiting.
self:AddTransition("*", "Hold", "Inbound") -- Group is holding position. self:AddTransition("*", "Hold", "Inbound") -- Group is inbound to holding pattern.
self:AddTransition("Inbound", "Holding", "Holding") -- Group is holding position. self:AddTransition("Inbound", "Holding", "Holding") -- Group is holding position.
self:AddTransition("*", "PassingWaypoint", "*") -- Group passed a waypoint. self:AddTransition("*", "PassingWaypoint", "*") -- Group passed a waypoint.
@@ -479,7 +479,7 @@ function FLIGHTGROUP:AddTask(description, task, prio, clock, duration)
newtask.type=FLIGHTGROUP.TaskType.SCHEDULED newtask.type=FLIGHTGROUP.TaskType.SCHEDULED
-- Info. -- Info.
self:I(self.sid..string.format("Adding task %s scheduled at %s", newtask.description, UTILS.SecondsToClock(time, true))) self:I(self.lid..string.format("Adding task %s scheduled at %s", newtask.description, UTILS.SecondsToClock(time, true)))
-- Debug info. -- Debug info.
self:T2({newtask=newtask}) self:T2({newtask=newtask})
@@ -521,7 +521,7 @@ function FLIGHTGROUP:AddTaskWaypoint(description, task, waypointindex, prio, dur
table.insert(self.taskqueue, newtask) table.insert(self.taskqueue, newtask)
-- Update route. -- Update route.
self:__UpdateRoute(-0.1) self:__UpdateRoute(-1)
return self return self
end end
@@ -531,7 +531,7 @@ end
-- @param Ops.Squadron#SQUADRON squadron The squadron object. -- @param Ops.Squadron#SQUADRON squadron The squadron object.
-- @return #FLIGHTGROUP self -- @return #FLIGHTGROUP self
function FLIGHTGROUP:SetSquadron(squadron) function FLIGHTGROUP:SetSquadron(squadron)
self:I(self.sid..string.format("Add flight to SQUADRON %s", squadron.squadronname)) self:I(self.lid..string.format("Add flight to SQUADRON %s", squadron.squadronname))
self.squadron=squadron self.squadron=squadron
return self return self
end end
@@ -559,7 +559,7 @@ end
-- @param Ops.FlightControl#FLIGHTCONTROL flightcontrol The FLIGHTCONTROL object. -- @param Ops.FlightControl#FLIGHTCONTROL flightcontrol The FLIGHTCONTROL object.
-- @return #FLIGHTGROUP self -- @return #FLIGHTGROUP self
function FLIGHTGROUP:SetFlightControl(flightcontrol) function FLIGHTGROUP:SetFlightControl(flightcontrol)
self:I(self.sid..string.format("Setting FLIGHTCONTROL to airbase %s", flightcontrol.airbasename)) self:I(self.lid..string.format("Setting FLIGHTCONTROL to airbase %s", flightcontrol.airbasename))
-- Remove flight from previous FC. -- Remove flight from previous FC.
if self.flightcontrol and self.flightcontrol.airbasename~=flightcontrol.airbasename then if self.flightcontrol and self.flightcontrol.airbasename~=flightcontrol.airbasename then
@@ -739,6 +739,13 @@ function FLIGHTGROUP:IsArrived()
return self:Is("Arrived") return self:Is("Arrived")
end end
--- Check if flight is inbound and traveling to holding pattern.
-- @param #FLIGHTGROUP self
-- @return #boolean If true, flight is holding.
function FLIGHTGROUP:IsInbound()
return self:Is("Inbound")
end
--- Check if flight is holding and waiting for landing clearance. --- Check if flight is holding and waiting for landing clearance.
-- @param #FLIGHTGROUP self -- @param #FLIGHTGROUP self
-- @return #boolean If true, flight is holding. -- @return #boolean If true, flight is holding.
@@ -782,7 +789,7 @@ function FLIGHTGROUP:onafterStart(From, Event, To)
-- Short info. -- Short info.
local text=string.format("Starting flight group v%s", FLIGHTGROUP.version) local text=string.format("Starting flight group v%s", FLIGHTGROUP.version)
self:I(self.sid..text) self:I(self.lid..text)
-- Check if the group is already alive and if so, add its elements. -- Check if the group is already alive and if so, add its elements.
local group=GROUP:FindByName(self.groupname) local group=GROUP:FindByName(self.groupname)
@@ -796,7 +803,7 @@ function FLIGHTGROUP:onafterStart(From, Event, To)
local units=group:GetUnits() local units=group:GetUnits()
-- Debug info. -- Debug info.
self:I(self.sid..string.format("FF Found alive group %s at start with %d units", group:GetName(), #units)) self:I(self.lid..string.format("FF Found alive group %s at start with %d units", group:GetName(), #units))
-- Add elemets. -- Add elemets.
@@ -875,7 +882,7 @@ function FLIGHTGROUP:onafterFlightStatus(From, Event, To)
local text=string.format("Flight status %s [%d/%d]. Task=%d/%d. Waypoint=%d/%d. Detected=%d. FC=%s. Destination=%s", local text=string.format("Flight status %s [%d/%d]. Task=%d/%d. Waypoint=%d/%d. Detected=%d. FC=%s. Destination=%s",
fsmstate, #self.elements, #self.elements, self.taskcurrent, #self.taskqueue, self.currentwp or 0, self.waypoints and #self.waypoints or 0, fsmstate, #self.elements, #self.elements, self.taskcurrent, #self.taskqueue, self.currentwp or 0, self.waypoints and #self.waypoints or 0,
self.detectedunits:Count(), self.flightcontrol and self.flightcontrol.airbasename or "none", self.destination and self.destination:GetName() or "unknown") self.detectedunits:Count(), self.flightcontrol and self.flightcontrol.airbasename or "none", self.destination and self.destination:GetName() or "unknown")
self:I(self.sid..text) self:I(self.lid..text)
-- Element status. -- Element status.
text="Elements:" text="Elements:"
@@ -918,7 +925,7 @@ function FLIGHTGROUP:onafterFlightStatus(From, Event, To)
if #self.elements==0 then if #self.elements==0 then
text=text.." none!" text=text.." none!"
end end
self:T(self.sid..text) self:T(self.lid..text)
-- Low fuel? -- Low fuel?
if fuelmin<self.fuellowthresh and not self.fuellow then if fuelmin<self.fuellowthresh and not self.fuellow then
@@ -953,7 +960,7 @@ function FLIGHTGROUP:onafterFlightStatus(From, Event, To)
text=text..string.format("\n[%d] %s: %s: status=%s, scheduled=%s (%d sec), started=%s, duration=%d", i, taskid, name, status, clock, eta, started, duration) text=text..string.format("\n[%d] %s: %s: status=%s, scheduled=%s (%d sec), started=%s, duration=%d", i, taskid, name, status, clock, eta, started, duration)
end end
if #self.taskqueue>0 then if #self.taskqueue>0 then
self:T(self.sid..text) self:T(self.lid..text)
end end
@@ -1054,7 +1061,7 @@ function FLIGHTGROUP:OnEventBirth(EventData)
end end
-- Set element to spawned state. -- Set element to spawned state.
self:T(self.sid..string.format("EVENT: Element %s born ==> spawned", element.name)) self:T(self.lid..string.format("EVENT: Element %s born ==> spawned", element.name))
self:ElementSpawned(element) self:ElementSpawned(element)
end end
@@ -1076,10 +1083,10 @@ function FLIGHTGROUP:OnEventEngineStartup(EventData)
local element=self:GetElementByName(unitname) local element=self:GetElementByName(unitname)
if element then if element then
if self:IsAirborne() or self:IsHolding() then if self:IsAirborne() or self:IsInbound() or self:IsHolding() then
-- TODO: what? -- TODO: what?
else else
self:T(self.sid..string.format("EVENT: Element %s started engines ==> taxiing (if AI)", element.name)) self:T(self.lid..string.format("EVENT: Element %s started engines ==> taxiing (if AI)", element.name))
-- TODO: could be that this element is part of a human flight group. -- TODO: could be that this element is part of a human flight group.
-- Problem: when player starts hot, the AI does too and starts to taxi immidiately :( -- Problem: when player starts hot, the AI does too and starts to taxi immidiately :(
-- when player starts cold, ? -- when player starts cold, ?
@@ -1113,7 +1120,7 @@ function FLIGHTGROUP:OnEventTakeOff(EventData)
local element=self:GetElementByName(unitname) local element=self:GetElementByName(unitname)
if element then if element then
self:T3(self.sid..string.format("EVENT: Element %s took off ==> airborne", element.name)) self:T3(self.lid..string.format("EVENT: Element %s took off ==> airborne", element.name))
self:ElementTakeoff(element, EventData.Place) self:ElementTakeoff(element, EventData.Place)
end end
@@ -1143,7 +1150,7 @@ function FLIGHTGROUP:OnEventLanding(EventData)
end end
if element then if element then
self:T3(self.sid..string.format("EVENT: Element %s landed at %s ==> landed", element.name, airbasename)) self:T3(self.lid..string.format("EVENT: Element %s landed at %s ==> landed", element.name, airbasename))
self:ElementLanded(element, airbase) self:ElementLanded(element, airbase)
end end
@@ -1174,15 +1181,15 @@ function FLIGHTGROUP:OnEventEngineShutdown(EventData)
if airbase and parking then if airbase and parking then
self:ElementArrived(element, airbase, parking) self:ElementArrived(element, airbase, parking)
self:T3(self.sid..string.format("EVENT: Element %s shut down engines ==> arrived", element.name)) self:T3(self.lid..string.format("EVENT: Element %s shut down engines ==> arrived", element.name))
else else
self:T3(self.sid..string.format("EVENT: Element %s shut down engines (in air) ==> dead", element.name)) self:T3(self.lid..string.format("EVENT: Element %s shut down engines (in air) ==> dead", element.name))
self:ElementDead(element) self:ElementDead(element)
end end
else else
self:T(self.sid..string.format("EVENT: Element %s shut down engines but is NOT alive ==> waiting for crash event (==> dead)", element.name)) self:T(self.lid..string.format("EVENT: Element %s shut down engines but is NOT alive ==> waiting for crash event (==> dead)", element.name))
end end
@@ -1209,7 +1216,7 @@ function FLIGHTGROUP:OnEventCrash(EventData)
local element=self:GetElementByName(unitname) local element=self:GetElementByName(unitname)
if element then if element then
self:T3(self.sid..string.format("EVENT: Element %s crashed ==> dead", element.name)) self:T3(self.lid..string.format("EVENT: Element %s crashed ==> dead", element.name))
self:ElementDead(element) self:ElementDead(element)
end end
@@ -1232,7 +1239,7 @@ function FLIGHTGROUP:OnEventRemoveUnit(EventData)
local element=self:GetElementByName(unitname) local element=self:GetElementByName(unitname)
if element then if element then
self:T3(self.sid..string.format("EVENT: Element %s removed ==> dead", element.name)) self:T3(self.lid..string.format("EVENT: Element %s removed ==> dead", element.name))
self:ElementDead(element) self:ElementDead(element)
end end
@@ -1251,7 +1258,7 @@ end
-- @param #string To To state. -- @param #string To To state.
-- @param #FLIGHTGROUP.Element Element The flight group element. -- @param #FLIGHTGROUP.Element Element The flight group element.
function FLIGHTGROUP:onafterElementSpawned(From, Event, To, Element) function FLIGHTGROUP:onafterElementSpawned(From, Event, To, Element)
self:T(self.sid..string.format("Element spawned %s.", Element.name)) self:T(self.lid..string.format("Element spawned %s.", Element.name))
-- Set element status. -- Set element status.
self:_UpdateStatus(Element, FLIGHTGROUP.ElementStatus.SPAWNED) self:_UpdateStatus(Element, FLIGHTGROUP.ElementStatus.SPAWNED)
@@ -1270,7 +1277,7 @@ function FLIGHTGROUP:onafterElementSpawned(From, Event, To, Element)
self:ElementParking(Element) self:ElementParking(Element)
else else
self:E(self.sid..string.format("Element spawned not in air but not on any parking spot.")) self:E(self.lid..string.format("Element spawned not in air but not on any parking spot."))
end end
end end
end end
@@ -1282,7 +1289,7 @@ end
-- @param #string To To state. -- @param #string To To state.
-- @param #FLIGHTGROUP.Element Element The flight group element. -- @param #FLIGHTGROUP.Element Element The flight group element.
function FLIGHTGROUP:onafterElementParking(From, Event, To, Element) function FLIGHTGROUP:onafterElementParking(From, Event, To, Element)
self:T(self.sid..string.format("Element parking %s at spot %s.", Element.name, tostring(Element.parking.TerminalID))) self:T(self.lid..string.format("Element parking %s at spot %s.", Element.name, tostring(Element.parking.TerminalID)))
-- Set element status. -- Set element status.
@@ -1296,7 +1303,16 @@ end
-- @param #string To To state. -- @param #string To To state.
-- @param #FLIGHTGROUP.Element Element The flight group element. -- @param #FLIGHTGROUP.Element Element The flight group element.
function FLIGHTGROUP:onafterElementTaxiing(From, Event, To, Element) function FLIGHTGROUP:onafterElementTaxiing(From, Event, To, Element)
self:T2(self.sid..string.format("Element taxiing %s.", Element.name)) local TerminalID="N/A"
if Element.parking then
if Element.parking.MarkerID then
Element.parking.Coordinate:RemoveMark(Element.parking.MarkerID)
end
Element.parking.Reserved=nil
TerminalID=tostring(Element.parking.TerminalID)
end
self:I(self.lid..string.format("Element taxiing %s. Parking spot %s is now free", Element.name, TerminalID))
-- Not parking any more. -- Not parking any more.
Element.parking=nil Element.parking=nil
@@ -1313,7 +1329,7 @@ end
-- @param #FLIGHTGROUP.Element Element The flight group element. -- @param #FLIGHTGROUP.Element Element The flight group element.
-- @param Wrapper.Airbase#AIRBASE airbase The airbase if applicable or nil. -- @param Wrapper.Airbase#AIRBASE airbase The airbase if applicable or nil.
function FLIGHTGROUP:onafterElementTakeoff(From, Event, To, Element, airbase) function FLIGHTGROUP:onafterElementTakeoff(From, Event, To, Element, airbase)
self:T(self.sid..string.format("Element takeoff %s at %s airbase.", Element.name, airbase and airbase:GetName() or "unknown")) self:T(self.lid..string.format("Element takeoff %s at %s airbase.", Element.name, airbase and airbase:GetName() or "unknown"))
-- Set element status. -- Set element status.
self:_UpdateStatus(Element, FLIGHTGROUP.ElementStatus.TAKEOFF, airbase) self:_UpdateStatus(Element, FLIGHTGROUP.ElementStatus.TAKEOFF, airbase)
@@ -1329,7 +1345,7 @@ end
-- @param #string To To state. -- @param #string To To state.
-- @param #FLIGHTGROUP.Element Element The flight group element. -- @param #FLIGHTGROUP.Element Element The flight group element.
function FLIGHTGROUP:onafterElementAirborne(From, Event, To, Element) function FLIGHTGROUP:onafterElementAirborne(From, Event, To, Element)
self:T2(self.sid..string.format("Element airborne %s", Element.name)) self:T2(self.lid..string.format("Element airborne %s", Element.name))
-- Set element status. -- Set element status.
self:_UpdateStatus(Element, FLIGHTGROUP.ElementStatus.AIRBORNE) self:_UpdateStatus(Element, FLIGHTGROUP.ElementStatus.AIRBORNE)
@@ -1343,7 +1359,7 @@ end
-- @param #FLIGHTGROUP.Element Element The flight group element. -- @param #FLIGHTGROUP.Element Element The flight group element.
-- @param Wrapper.Airbase#AIRBASE airbase The airbase if applicable or nil. -- @param Wrapper.Airbase#AIRBASE airbase The airbase if applicable or nil.
function FLIGHTGROUP:onafterElementLanded(From, Event, To, Element, airbase) function FLIGHTGROUP:onafterElementLanded(From, Event, To, Element, airbase)
self:T2(self.sid..string.format("Element landed %s at %s airbase", Element.name, airbase and airbase:GetName() or "unknown")) self:T2(self.lid..string.format("Element landed %s at %s airbase", Element.name, airbase and airbase:GetName() or "unknown"))
-- Set element status. -- Set element status.
self:_UpdateStatus(Element, FLIGHTGROUP.ElementStatus.LANDED, airbase) self:_UpdateStatus(Element, FLIGHTGROUP.ElementStatus.LANDED, airbase)
@@ -1356,7 +1372,7 @@ end
-- @param #string To To state. -- @param #string To To state.
-- @param #FLIGHTGROUP.Element Element The flight group element. -- @param #FLIGHTGROUP.Element Element The flight group element.
function FLIGHTGROUP:onafterElementArrived(From, Event, To, Element) function FLIGHTGROUP:onafterElementArrived(From, Event, To, Element)
self:T2(self.sid..string.format("Element arrived %s.", Element.name)) self:T2(self.lid..string.format("Element arrived %s.", Element.name))
-- Set element status. -- Set element status.
self:_UpdateStatus(Element, FLIGHTGROUP.ElementStatus.ARRIVED) self:_UpdateStatus(Element, FLIGHTGROUP.ElementStatus.ARRIVED)
@@ -1369,7 +1385,7 @@ end
-- @param #string To To state. -- @param #string To To state.
-- @param #FLIGHTGROUP.Element Element The flight group element. -- @param #FLIGHTGROUP.Element Element The flight group element.
function FLIGHTGROUP:onafterElementDead(From, Event, To, Element) function FLIGHTGROUP:onafterElementDead(From, Event, To, Element)
self:I(self.sid..string.format("Element dead %s.", Element.name)) self:I(self.lid..string.format("Element dead %s.", Element.name))
-- Not parking any more. -- Not parking any more.
Element.parking=nil Element.parking=nil
@@ -1431,7 +1447,7 @@ end
-- @param #string Event Event. -- @param #string Event Event.
-- @param #string To To state. -- @param #string To To state.
function FLIGHTGROUP:onafterFlightParking(From, Event, To) function FLIGHTGROUP:onafterFlightParking(From, Event, To)
self:T(self.sid..string.format("Flight is parking %s.", self.groupname)) self:T(self.lid..string.format("Flight is parking %s.", self.groupname))
local airbase=self.group:GetCoordinate():GetClosestAirbase() local airbase=self.group:GetCoordinate():GetClosestAirbase()
@@ -1465,7 +1481,7 @@ end
-- @param #string Event Event. -- @param #string Event Event.
-- @param #string To To state. -- @param #string To To state.
function FLIGHTGROUP:onafterFlightTaxiing(From, Event, To) function FLIGHTGROUP:onafterFlightTaxiing(From, Event, To)
self:T(self.sid..string.format("Flight is taxiing %s.", self.groupname)) self:T(self.lid..string.format("Flight is taxiing %s.", self.groupname))
-- Parking over. -- Parking over.
self.Tparking=nil self.Tparking=nil
@@ -1479,10 +1495,10 @@ function FLIGHTGROUP:onafterFlightTaxiing(From, Event, To)
-- Add AI flight to takeoff queue. -- Add AI flight to takeoff queue.
if self.ai then if self.ai then
-- AI flights go directly to takeoff as we don't know when they finished taxiing. -- AI flights go directly to TAKEOFF as we don't know when they finished taxiing.
self.flightcontrol:_AddFlightToTakeoffQueue(self) self.flightcontrol:_AddFlightToTakeoffQueue(self)
else else
-- Human flights go to taxi out queue. They will go to the ready for takeoff queue when they request it. -- Human flights go to TAXI OUT queue. They will go to the ready for takeoff queue when they request it.
self.flightcontrol:_AddFlightToTaxiOutQueue(self) self.flightcontrol:_AddFlightToTaxiOutQueue(self)
end end
@@ -1497,7 +1513,7 @@ end
-- @param #string To To state. -- @param #string To To state.
-- @param Wrapper.Airbase#AIRBASE airbase The airbase the flight landed. -- @param Wrapper.Airbase#AIRBASE airbase The airbase the flight landed.
function FLIGHTGROUP:onafterFlightTakeoff(From, Event, To, airbase) function FLIGHTGROUP:onafterFlightTakeoff(From, Event, To, airbase)
self:T(self.sid..string.format("Flight takeoff %s at %s.", self.groupname, airbase and airbase:GetName() or "unknown airbase")) self:T(self.lid..string.format("Flight takeoff %s at %s.", self.groupname, airbase and airbase:GetName() or "unknown airbase"))
-- Remove flight from all FC queues. -- Remove flight from all FC queues.
if self.flightcontrol and airbase and self.flightcontrol.airbasename==airbase:GetName() then if self.flightcontrol and airbase and self.flightcontrol.airbasename==airbase:GetName() then
@@ -1517,11 +1533,10 @@ end
-- @param #string To To state. -- @param #string To To state.
-- @param Wrapper.Airbase#AIRBASE airbase The airbase the flight landed. -- @param Wrapper.Airbase#AIRBASE airbase The airbase the flight landed.
function FLIGHTGROUP:onafterFlightAirborne(From, Event, To, airbase) function FLIGHTGROUP:onafterFlightAirborne(From, Event, To, airbase)
self:T(self.sid..string.format("Flight airborne %s at %s.", self.groupname,airbase and airbase:GetName() or "unknown airbase")) self:T(self.lid..string.format("Flight airborne %s at %s.", self.groupname,airbase and airbase:GetName() or "unknown airbase"))
-- Update queue. -- Update queue.
self:__QueueUpdate(-1) self:__QueueUpdate(-1)
end end
--- On after "FlightLanding" event. --- On after "FlightLanding" event.
@@ -1530,7 +1545,7 @@ end
-- @param #string Event Event. -- @param #string Event Event.
-- @param #string To To state. -- @param #string To To state.
function FLIGHTGROUP:onafterFlightLanding(From, Event, To) function FLIGHTGROUP:onafterFlightLanding(From, Event, To)
self:T(self.sid..string.format("Flight landing %s", self.groupname)) self:T(self.lid..string.format("Flight landing %s", self.groupname))
self:_SetElementStatusAll(FLIGHTGROUP.ElementStatus.LANDING) self:_SetElementStatusAll(FLIGHTGROUP.ElementStatus.LANDING)
@@ -1543,13 +1558,13 @@ end
-- @param #string To To state. -- @param #string To To state.
-- @param Wrapper.Airbase#AIRBASE airbase The airbase the flight landed. -- @param Wrapper.Airbase#AIRBASE airbase The airbase the flight landed.
function FLIGHTGROUP:onafterFlightLanded(From, Event, To, airbase) function FLIGHTGROUP:onafterFlightLanded(From, Event, To, airbase)
self:T(self.sid..string.format("Flight landed %s at %s.", self.groupname, airbase and airbase:GetName() or "unknown airbase")) self:T(self.lid..string.format("Flight landed %s at %s.", self.groupname, airbase and airbase:GetName() or "unknown airbase"))
-- Remove flight from landing queue. -- Remove flight from landing queue.
if self.flightcontrol and airbase and self.flightcontrol.airbasename==airbase:GetName() then if self.flightcontrol and airbase and self.flightcontrol.airbasename==airbase:GetName() then
self.flightcontrol:_RemoveFlightFromQueue(self.flightcontrol.Qlanding, self, "landing") self.flightcontrol:_RemoveFlightFromQueue(self.flightcontrol.Qlanding, self, "LANDING")
-- TODO: add flight to taxiinb queue. -- Add flight to taxiinb queue.
--self.flightcontrol:_Add self.flightcontrol:_AddFlightToTaxiInboundQueue(self)
end end
end end
@@ -1559,13 +1574,13 @@ end
-- @param #string Event Event. -- @param #string Event Event.
-- @param #string To To state. -- @param #string To To state.
function FLIGHTGROUP:onafterFlightArrived(From, Event, To) function FLIGHTGROUP:onafterFlightArrived(From, Event, To)
self:T(self.sid..string.format("Flight arrived %s", self.groupname)) self:T(self.lid..string.format("Flight arrived %s", self.groupname))
-- Remove flight from landing queue. -- Remove flight from landing queue.
if self.flightcontrol then if self.flightcontrol then
self.flightcontrol:_RemoveFlightFromQueue(self.flightcontrol.Qtaxiinb, self, "taxiINB") self.flightcontrol:_RemoveFlightFromQueue(self.flightcontrol.Qtaxiinb, self, "TAXI_INB")
-- TODO: add flight to arrived queue -- Add flight to arrived queue.
--self.flightcontrol:_AddFl self.flightcontrol:_AddFlightToArrivedQueue(self)
end end
end end
@@ -1576,7 +1591,7 @@ end
-- @param #string Event Event. -- @param #string Event Event.
-- @param #string To To state. -- @param #string To To state.
function FLIGHTGROUP:onafterFlightDead(From, Event, To) function FLIGHTGROUP:onafterFlightDead(From, Event, To)
self:T(self.sid..string.format("Flight dead %s", self.groupname)) self:T(self.lid..string.format("Flight dead %s", self.groupname))
-- Delete waypoints so they are re-initialized at the next spawn. -- Delete waypoints so they are re-initialized at the next spawn.
self.waypoints=nil self.waypoints=nil
@@ -1602,14 +1617,14 @@ function FLIGHTGROUP:onbeforeUpdateRoute(From, Event, To, n)
if self.group and self.group:IsAlive() and self:IsAirborne() then if self.group and self.group:IsAlive() and self:IsAirborne() then
-- Alive & Airborne ==> Update route possible. -- Alive & Airborne ==> Update route possible.
self:T2(self.sid.."Update route allowed") self:T2(self.lid.."Update route allowed")
return true return true
elseif self:IsDead() then elseif self:IsDead() then
-- Group is dead! No more updates. -- Group is dead! No more updates.
return false return false
else else
-- Not airborne yet. Try again in 1 sec. -- Not airborne yet. Try again in 1 sec.
self:T3(self.sid.."FF update route denied ==> checking back in 1 sec") self:T3(self.lid.."FF update route denied ==> checking back in 1 sec")
self:__UpdateRoute(-1, n) self:__UpdateRoute(-1, n)
return false return false
end end
@@ -1625,7 +1640,7 @@ end
function FLIGHTGROUP:onafterUpdateRoute(From, Event, To, n) function FLIGHTGROUP:onafterUpdateRoute(From, Event, To, n)
MESSAGE:New("Updating route", 10):ToAll() MESSAGE:New("Updating route", 10):ToAll()
self:I(self.sid.."Updating route") self:I(self.lid.."Updating route")
-- TODO: what happens if currentwp=#waypoints -- TODO: what happens if currentwp=#waypoints
n=n or self.currentwp+1 n=n or self.currentwp+1
@@ -1638,8 +1653,8 @@ function FLIGHTGROUP:onafterUpdateRoute(From, Event, To, n)
-- Set current waypoint or we get problem that the _PassingWaypoint function is triggered too early, i.e. right now and not when passing the next WP. -- Set current waypoint or we get problem that the _PassingWaypoint function is triggered too early, i.e. right now and not when passing the next WP.
-- TODO: This, however, leads to the flight to go right over this point when it is on an airport ==> Need to test Waypoint takeoff -- TODO: This, however, leads to the flight to go right over this point when it is on an airport ==> Need to test Waypoint takeoff
local current=self.group:GetCoordinate():WaypointAir(nil, COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.TurningPoint, 350, true, nil, {}, "Current") --local current=self.group:GetCoordinate():WaypointAir(nil, COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.TurningPoint, 350, true, nil, {}, "Current")
table.insert(wp, current) --table.insert(wp, current)
-- Set "remaining" waypoits. -- Set "remaining" waypoits.
for i=n, #self.waypoints do for i=n, #self.waypoints do
@@ -1662,7 +1677,7 @@ function FLIGHTGROUP:onafterUpdateRoute(From, Event, To, n)
local wpoverhead=coordoverhead:WaypointAir(nil, COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.FlyoverPoint, 500, false, nil, {TaskOverhead}, "Destination Overhead") local wpoverhead=coordoverhead:WaypointAir(nil, COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.FlyoverPoint, 500, false, nil, {TaskOverhead}, "Destination Overhead")
-- Debug info. -- Debug info.
self:T(self.sid..string.format("Adding overhead waypoint as #%d", #wp)) self:T(self.lid..string.format("Adding overhead waypoint as #%d", #wp))
-- Add overhead to waypoints. -- Add overhead to waypoints.
table.insert(wp, #wp, wpoverhead) table.insert(wp, #wp, wpoverhead)
@@ -1672,7 +1687,7 @@ function FLIGHTGROUP:onafterUpdateRoute(From, Event, To, n)
-- Debug info. -- Debug info.
local hb=self.homebase and self.homebase:GetName() or "unknown" local hb=self.homebase and self.homebase:GetName() or "unknown"
local db=self.destination and self.destination:GetName() or "unknown" local db=self.destination and self.destination:GetName() or "unknown"
self:I(self.sid..string.format("Updating route for WP>=%d/%d (%d) homebase=%s destination=%s", n, #wp, #self.waypoints, hb, db)) self:I(self.lid..string.format("Updating route for WP>=%d/%d (%d) homebase=%s destination=%s", n, #wp, #self.waypoints, hb, db))
if #wp>0 then if #wp>0 then
@@ -1717,7 +1732,7 @@ end
-- @param #number N Final waypoint number. -- @param #number N Final waypoint number.
function FLIGHTGROUP:onafterPassingWaypoint(From, Event, To, n, N) function FLIGHTGROUP:onafterPassingWaypoint(From, Event, To, n, N)
local text=string.format("Flight %s passed waypoint %d/%d", self.groupname, n, N) local text=string.format("Flight %s passed waypoint %d/%d", self.groupname, n, N)
self:I(self.sid..text) self:I(self.lid..text)
MESSAGE:New(text, 30, "DEBUG"):ToAllIf(self.Debug) MESSAGE:New(text, 30, "DEBUG"):ToAllIf(self.Debug)
@@ -1737,7 +1752,7 @@ function FLIGHTGROUP:onafterFuelLow(From, Event, To)
-- Debug message. -- Debug message.
local text=string.format("Low fuel for flight group %s", self.groupname) local text=string.format("Low fuel for flight group %s", self.groupname)
MESSAGE:New(text, 30, "DEBUG"):ToAllIf(self.Debug) MESSAGE:New(text, 30, "DEBUG"):ToAllIf(self.Debug)
self:I(self.sid..text) self:I(self.lid..text)
-- Set switch to true. -- Set switch to true.
self.fuellow=true self.fuellow=true
@@ -1760,7 +1775,7 @@ function FLIGHTGROUP:onafterFuelCritical(From, Event, To)
-- Debug message. -- Debug message.
local text=string.format("Critical fuel for flight group %s", self.groupname) local text=string.format("Critical fuel for flight group %s", self.groupname)
MESSAGE:New(text, 30, "DEBUG"):ToAllIf(self.Debug) MESSAGE:New(text, 30, "DEBUG"):ToAllIf(self.Debug)
self:I(self.sid..text) self:I(self.lid..text)
-- Set switch to true. -- Set switch to true.
self.fuelcritical=true self.fuelcritical=true
@@ -1785,7 +1800,7 @@ function FLIGHTGROUP:onafterRTB(From, Event, To, airbase)
-- Debug message. -- Debug message.
local text=string.format("Flight group returning to airbase %s.", airbase:GetName()) local text=string.format("Flight group returning to airbase %s.", airbase:GetName())
MESSAGE:New(text, 30, "DEBUG"):ToAllIf(self.Debug) MESSAGE:New(text, 30, "DEBUG"):ToAllIf(self.Debug)
self:I(self.sid..text) self:I(self.lid..text)
-- Route helo back home. It is respawned! But this is the only way to ensure that it actually lands at the airbase. -- Route helo back home. It is respawned! But this is the only way to ensure that it actually lands at the airbase.
self:RouteRTB(airbase) self:RouteRTB(airbase)
@@ -1804,7 +1819,7 @@ function FLIGHTGROUP:onafterOrbit(From, Event, To, Coord, Altitude, Speed)
-- Debug message. -- Debug message.
local text=string.format("Flight group set to orbit at altitude %d m and speed %.1f km/h", Altitude, Speed) local text=string.format("Flight group set to orbit at altitude %d m and speed %.1f km/h", Altitude, Speed)
MESSAGE:New(text, 30, "DEBUG"):ToAllIf(self.Debug) MESSAGE:New(text, 30, "DEBUG"):ToAllIf(self.Debug)
self:I(self.sid..text) self:I(self.lid..text)
--TODO: set ROE passive. introduce roe event/state/variable. --TODO: set ROE passive. introduce roe event/state/variable.
@@ -1855,7 +1870,7 @@ function FLIGHTGROUP:onafterHold(From, Event, To, airbase, SpeedTo, SpeedHold, S
-- Debug message. -- Debug message.
local text=string.format("Flight group set to hold at airbase %s", airbase:GetName()) local text=string.format("Flight group set to hold at airbase %s", airbase:GetName())
MESSAGE:New(text, 10, "DEBUG"):ToAllIf(self.Debug) MESSAGE:New(text, 10, "DEBUG"):ToAllIf(self.Debug)
self:I(self.sid..text) self:I(self.lid..text)
-- Holding points. -- Holding points.
@@ -1879,6 +1894,9 @@ function FLIGHTGROUP:onafterHold(From, Event, To, airbase, SpeedTo, SpeedHold, S
-- Set flightcontrol for this flight. -- Set flightcontrol for this flight.
self:SetFlightControl(fc) self:SetFlightControl(fc)
-- Add flight to inbound queue.
self.flightcontrol:_AddFlightToInboundQueue(self)
end end
-- Altitude above ground for a glide slope of 3. -- Altitude above ground for a glide slope of 3.
@@ -1920,7 +1938,12 @@ function FLIGHTGROUP:onafterHold(From, Event, To, airbase, SpeedTo, SpeedHold, S
wp[#wp+1]=pland:WaypointAirLanding(UTILS.KnotsToKmph(SpeedLand), airbase, {}, "Landing") wp[#wp+1]=pland:WaypointAirLanding(UTILS.KnotsToKmph(SpeedLand), airbase, {}, "Landing")
-- Respawn? -- Respawn?
if not fc then if fc then
-- Just route the group. Respawn will happen when going from holding to final.
self.group:Route(wp, 1)
else
-- Get group template. -- Get group template.
local Template=self.group:GetTemplate() local Template=self.group:GetTemplate()
@@ -1928,16 +1951,9 @@ function FLIGHTGROUP:onafterHold(From, Event, To, airbase, SpeedTo, SpeedHold, S
-- Set route points. -- Set route points.
Template.route.points=wp Template.route.points=wp
MESSAGE:New("Respawning group"):ToAll() --Respawn the group with new waypoints.
--Respawn the group.
self.group=self.group:Respawn(Template) self.group=self.group:Respawn(Template)
else
-- Route the group.
self.group:Route(wp, 1)
end end
end end
@@ -1949,13 +1965,17 @@ end
-- @param #string To To state. -- @param #string To To state.
function FLIGHTGROUP:onafterHolding(From, Event, To) function FLIGHTGROUP:onafterHolding(From, Event, To)
-- Set holding flag to 666.
self.flaghold:Set(666) self.flaghold:Set(666)
local text=string.format("Flight group %s is HOLDING now", self.groupname)
MESSAGE:New(text, 10, "DEBUG"):ToAllIf(self.Debug)
self:I(self.lid..text)
-- Add flight to waiting/holding queue. -- Add flight to waiting/holding queue.
if self.flightcontrol then if self.flightcontrol then
-- Add flight to all flights. -- Add flight to holding queue.
--table.insert(flightgroup.flightcontrol.flights, flightgroup) self.flightcontrol:_RemoveFlightFromQueue(self.flightcontrol.Qinbound, self, "inbound")
self.flightcontrol:_AddFlightToHoldingQueue(self) self.flightcontrol:_AddFlightToHoldingQueue(self)
end end
@@ -1972,7 +1992,7 @@ function FLIGHTGROUP:onafterTaskExecute(From, Event, To, Task)
-- Debug message. -- Debug message.
local text=string.format("Task %s ID=%d execute.", Task.description, Task.id) local text=string.format("Task %s ID=%d execute.", Task.description, Task.id)
MESSAGE:New(text, 10, "DEBUG"):ToAllIf(self.Debug) MESSAGE:New(text, 10, "DEBUG"):ToAllIf(self.Debug)
self:I(self.sid..text) self:I(self.lid..text)
-- Cancel current task if there is any. -- Cancel current task if there is any.
if self.taskcurrent>0 then if self.taskcurrent>0 then
@@ -2056,14 +2076,14 @@ function FLIGHTGROUP:onafterTaskCancel(From, Event, To)
if task then if task then
local text=string.format("Task %s ID=%d cancelled.", task.description, task.id) local text=string.format("Task %s ID=%d cancelled.", task.description, task.id)
MESSAGE:New(text, 10, "DEBUG"):ToAllIf(self.Debug) MESSAGE:New(text, 10, "DEBUG"):ToAllIf(self.Debug)
self:I(self.sid..text) self:I(self.lid..text)
-- Clear tasks. -- Clear tasks.
self.group:ClearTasks() self.group:ClearTasks()
self:TaskDone(task) self:TaskDone(task)
else else
local text=string.format("WARNING: No current task to cancel!") local text=string.format("WARNING: No current task to cancel!")
MESSAGE:New(text, 10, "DEBUG"):ToAllIf(self.Debug) MESSAGE:New(text, 10, "DEBUG"):ToAllIf(self.Debug)
self:I(self.sid..text) self:I(self.lid..text)
end end
end end
@@ -2079,7 +2099,7 @@ function FLIGHTGROUP:onafterTaskDone(From, Event, To, Task)
-- Debug message. -- Debug message.
local text=string.format("Task done: %s ID=%d", Task.description, Task.id) local text=string.format("Task done: %s ID=%d", Task.description, Task.id)
MESSAGE:New(text, 10, "DEBUG"):ToAllIf(self.Debug) MESSAGE:New(text, 10, "DEBUG"):ToAllIf(self.Debug)
self:I(self.sid..text) self:I(self.lid..text)
-- No current task. -- No current task.
self.taskcurrent=0 self.taskcurrent=0
@@ -2088,7 +2108,7 @@ function FLIGHTGROUP:onafterTaskDone(From, Event, To, Task)
Task.status=FLIGHTGROUP.TaskStatus.ACCOMPLISHED Task.status=FLIGHTGROUP.TaskStatus.ACCOMPLISHED
-- Update route. -- Update route.
self:__UpdateRoute(-0.1) self:__UpdateRoute(-1)
end end
@@ -2100,7 +2120,7 @@ end
-- @param #string To To state. -- @param #string To To state.
-- @param Wrapper.Unit#UNIT Unit The detected unit -- @param Wrapper.Unit#UNIT Unit The detected unit
function FLIGHTGROUP:onafterDetectedUnit(From, Event, To, Unit) function FLIGHTGROUP:onafterDetectedUnit(From, Event, To, Unit)
self:T(self.sid..string.format("Detected unit %s", Unit:GetName())) self:T(self.lid..string.format("Detected unit %s", Unit:GetName()))
self.detectedunits:AddUnit(Unit) self.detectedunits:AddUnit(Unit)
end end
@@ -2111,7 +2131,7 @@ end
-- @param #string To To state. -- @param #string To To state.
-- @param Wrapper.Unit#UNIT Unit The detected unit -- @param Wrapper.Unit#UNIT Unit The detected unit
function FLIGHTGROUP:onafterDetectedUnitNew(From, Event, To, Unit) function FLIGHTGROUP:onafterDetectedUnitNew(From, Event, To, Unit)
self:T(self.sid..string.format("Detected New unit %s", Unit:GetName())) self:T(self.lid..string.format("Detected New unit %s", Unit:GetName()))
end end
@@ -2122,7 +2142,7 @@ end
-- @param #string To To state. -- @param #string To To state.
-- @param Core.Zone#ZONE Zone The zone that the group entered. -- @param Core.Zone#ZONE Zone The zone that the group entered.
function FLIGHTGROUP:onafterEnterZone(From, Event, To, Zone) function FLIGHTGROUP:onafterEnterZone(From, Event, To, Zone)
self:I(self.sid..string.format("Entered Zone %s", Zone:GetName())) self:I(self.lid..string.format("Entered Zone %s", Zone:GetName()))
self.inzone=Zone self.inzone=Zone
end end
@@ -2133,7 +2153,7 @@ end
-- @param #string To To state. -- @param #string To To state.
-- @param Core.Zone#ZONE Zone The zone that the group entered. -- @param Core.Zone#ZONE Zone The zone that the group entered.
function FLIGHTGROUP:onafterLeaveZone(From, Event, To, Zone) function FLIGHTGROUP:onafterLeaveZone(From, Event, To, Zone)
self:I(self.sid..string.format("Left Zone %s", Zone:GetName())) self:I(self.lid..string.format("Left Zone %s", Zone:GetName()))
self.inzone=nil self.inzone=nil
end end
@@ -2221,7 +2241,7 @@ function FLIGHTGROUP._TaskExecute(group, flightgroup, task)
-- Debug message. -- Debug message.
local text=string.format("Task Execute %s", task.description) local text=string.format("Task Execute %s", task.description)
flightgroup:T2(flightgroup.sid..text) flightgroup:T2(flightgroup.lid..text)
-- Set current task to nil so that the next in line can be executed. -- Set current task to nil so that the next in line can be executed.
if flightgroup then if flightgroup then
@@ -2238,7 +2258,7 @@ function FLIGHTGROUP._TaskDone(group, flightgroup, task)
-- Debug message. -- Debug message.
local text=string.format("Task Done %s", task.description) local text=string.format("Task Done %s", task.description)
flightgroup:T2(flightgroup.sid..text) flightgroup:T2(flightgroup.lid..text)
-- Set current task to nil so that the next in line can be executed. -- Set current task to nil so that the next in line can be executed.
if flightgroup then if flightgroup then
@@ -2265,7 +2285,7 @@ function FLIGHTGROUP._PassingWaypoint(group, flightgroup, i)
end end
-- Debug message. -- Debug message.
flightgroup:T3(flightgroup.sid..text) flightgroup:T3(flightgroup.lid..text)
-- Set current waypoint. -- Set current waypoint.
flightgroup.currentwp=i flightgroup.currentwp=i
@@ -2283,7 +2303,7 @@ end
-- @param Wrapper.Group#GROUP group Group object. -- @param Wrapper.Group#GROUP group Group object.
-- @param #FLIGHTGROUP flightgroup Flight group object. -- @param #FLIGHTGROUP flightgroup Flight group object.
function FLIGHTGROUP._ReachedHolding(group, flightgroup) function FLIGHTGROUP._ReachedHolding(group, flightgroup)
flightgroup:T(flightgroup.sid..string.format("Group %s reached holding point", group:GetName())) flightgroup:T(flightgroup.lid..string.format("Group %s reached holding point", group:GetName()))
if flightgroup.Debug then if flightgroup.Debug then
group:GetCoordinate():MarkToAll("Holding Point Reached") group:GetCoordinate():MarkToAll("Holding Point Reached")
@@ -2445,7 +2465,7 @@ function FLIGHTGROUP:AddElementByName(unitname)
local text=string.format("Adding element %s: status=%s, skill=%s, modex=%s, fuelmass=%.1f, category=%d, categoryname=%s, callsign=%s, ai=%s", local text=string.format("Adding element %s: status=%s, skill=%s, modex=%s, fuelmass=%.1f, category=%d, categoryname=%s, callsign=%s, ai=%s",
element.name, element.status, element.skill, element.modex, element.fuelmass, element.category, element.categoryname, element.callsign, tostring(element.ai)) element.name, element.status, element.skill, element.modex, element.fuelmass, element.category, element.categoryname, element.callsign, tostring(element.ai))
self:I(self.sid..text) self:I(self.lid..text)
-- Add element to table. -- Add element to table.
table.insert(self.elements, element) table.insert(self.elements, element)
@@ -2618,7 +2638,7 @@ function FLIGHTGROUP:_UpdateWaypointTasks()
if i>self.currentwp or #self.waypoints==1 then if i>self.currentwp or #self.waypoints==1 then
self:T(self.sid..string.format("Updating waypoint task for waypoint %d/%d. Last waypoint passed %d.", i, #self.waypoints, self.currentwp)) self:T(self.lid..string.format("Updating waypoint task for waypoint %d/%d. Last waypoint passed %d.", i, #self.waypoints, self.currentwp))
-- Tasks of this waypoint -- Tasks of this waypoint
local taskswp={} local taskswp={}
@@ -2669,7 +2689,7 @@ function FLIGHTGROUP:InitWaypoints(waypoints)
-- Waypoints of group as defined in the ME. -- Waypoints of group as defined in the ME.
self.waypoints=waypoints or self.waypoints0 self.waypoints=waypoints or self.waypoints0
self:I(self.sid..string.format("Initializing %d waypoints", #self.waypoints)) self:I(self.lid..string.format("Initializing %d waypoints", #self.waypoints))
-- Init array. -- Init array.
self.coordinates={} self.coordinates={}
@@ -2696,11 +2716,13 @@ function FLIGHTGROUP:InitWaypoints(waypoints)
-- Set current waypoint. Counting starts a one. -- Set current waypoint. Counting starts a one.
self.currentwp=1 self.currentwp=1
-- Get home and destination airbases from waypoints.
self.homebase=self:GetHomebaseFromWaypoints()
self.destination=self:GetDestinationFromWaypoints()
-- Update route. -- Update route.
if #self.waypoints>0 then if #self.waypoints>0 then
self:__UpdateRoute(-0.1, 1) self:__UpdateRoute(-1, 1)
end end
return self return self
@@ -2730,7 +2752,7 @@ function FLIGHTGROUP:AddWaypointAir(coordinate, wpnumber, speed)
table.insert(self.waypoints, wpnumber, wp) table.insert(self.waypoints, wpnumber, wp)
-- Debug info. -- Debug info.
self:I(self.sid..string.format("Adding AIR waypoint #%d, speed=%.1f knots. Last waypoint passed was #%s. Total waypoints #%d", wpnumber, speed, self.currentwp, #self.waypoints)) self:I(self.lid..string.format("Adding AIR waypoint #%d, speed=%.1f knots. Last waypoint passed was #%s. Total waypoints #%d", wpnumber, speed, self.currentwp, #self.waypoints))
-- Shift all waypoint tasks after the inserted waypoint. -- Shift all waypoint tasks after the inserted waypoint.
for _,_task in pairs(self.taskqueue) do for _,_task in pairs(self.taskqueue) do
@@ -2741,7 +2763,7 @@ function FLIGHTGROUP:AddWaypointAir(coordinate, wpnumber, speed)
end end
-- Update route. -- Update route.
self:__UpdateRoute(-0.1) self:__UpdateRoute(-1)
end end
--- Check if a unit is and element of the flightgroup. --- Check if a unit is and element of the flightgroup.
@@ -2803,7 +2825,7 @@ function FLIGHTGROUP:_AllSimilarStatus(status)
for _,_element in pairs(self.elements) do for _,_element in pairs(self.elements) do
local element=_element --#FLIGHTGROUP.Element local element=_element --#FLIGHTGROUP.Element
self:T2(self.sid..string.format("Status=%s, element %s status=%s", status, element.name, element.status)) self:T2(self.lid..string.format("Status=%s, element %s status=%s", status, element.name, element.status))
-- Dead units dont count ==> We wont return false for those. -- Dead units dont count ==> We wont return false for those.
if element.status~=FLIGHTGROUP.ElementStatus.DEAD then if element.status~=FLIGHTGROUP.ElementStatus.DEAD then
@@ -2847,7 +2869,7 @@ function FLIGHTGROUP:_AllSimilarStatus(status)
element.status==FLIGHTGROUP.ElementStatus.SPAWNED or element.status==FLIGHTGROUP.ElementStatus.SPAWNED or
element.status==FLIGHTGROUP.ElementStatus.PARKING or element.status==FLIGHTGROUP.ElementStatus.PARKING or
element.status==FLIGHTGROUP.ElementStatus.TAXIING) then element.status==FLIGHTGROUP.ElementStatus.TAXIING) then
self:T3(self.sid..string.format("Status=%s, element %s status=%s ==> returning FALSE", status, element.name, element.status)) self:T3(self.lid..string.format("Status=%s, element %s status=%s ==> returning FALSE", status, element.name, element.status))
return false return false
end end
@@ -2891,7 +2913,7 @@ function FLIGHTGROUP:_AllSimilarStatus(status)
end end
-- Debug info. -- Debug info.
self:T2(self.sid..string.format("All similar status %s ==> returning TRUE", status)) self:T2(self.lid..string.format("All similar status %s ==> returning TRUE", status))
return true return true
end end
@@ -3268,9 +3290,9 @@ function FLIGHTGROUP:GetAmmoElement(element, display)
-- Debug text and send message. -- Debug text and send message.
if display then if display then
self:I(self.sid..text) self:I(self.lid..text)
else else
self:T3(self.sid..text) self:T3(self.lid..text)
end end
MESSAGE:New(text, 10):ToAllIf(display) MESSAGE:New(text, 10):ToAllIf(display)
@@ -3556,7 +3578,7 @@ function FLIGHTGROUP:GetParking(airbase)
-- Safe parking using TO_AC from DCS result. -- Safe parking using TO_AC from DCS result.
if verysafe and parkingspot.TOAC then if verysafe and parkingspot.TOAC then
free=false free=false
self:I(self.sid..string.format("Parking spot %d is occupied by other aircraft taking off (TOAC).", parkingspot.TerminalID)) self:I(self.lid..string.format("Parking spot %d is occupied by other aircraft taking off (TOAC).", parkingspot.TerminalID))
end end
-- Loop over all obstacles. -- Loop over all obstacles.
@@ -3582,7 +3604,7 @@ function FLIGHTGROUP:GetParking(airbase)
-- Add parkingspot for this element. -- Add parkingspot for this element.
table.insert(parking, parkingspot) table.insert(parking, parkingspot)
self:I(self.sid..string.format("Parking spot %d is free for element %s!", parkingspot.TerminalID, element.name)) self:I(self.lid..string.format("Parking spot %d is free for element %s!", parkingspot.TerminalID, element.name))
-- Add the unit as obstacle so that this spot will not be available for the next unit. -- Add the unit as obstacle so that this spot will not be available for the next unit.
table.insert(obstacles, {coord=parkingspot.Coordinate, size=element.size, name=element.name, type="element"}) table.insert(obstacles, {coord=parkingspot.Coordinate, size=element.size, name=element.name, type="element"})
@@ -3593,7 +3615,7 @@ function FLIGHTGROUP:GetParking(airbase)
else else
-- Debug output for occupied spots. -- Debug output for occupied spots.
self:I(self.sid..string.format("Parking spot %d is occupied or not big enough!", parkingspot.TerminalID)) self:I(self.lid..string.format("Parking spot %d is occupied or not big enough!", parkingspot.TerminalID))
--if self.Debug then --if self.Debug then
-- local coord=problem.coord --Core.Point#COORDINATE -- local coord=problem.coord --Core.Point#COORDINATE
-- local text=string.format("Obstacle blocking spot #%d is %s type %s with size=%.1f m and distance=%.1f m.", _termid, problem.name, problem.type, problem.size, problem.dist) -- local text=string.format("Obstacle blocking spot #%d is %s type %s with size=%.1f m and distance=%.1f m.", _termid, problem.name, problem.type, problem.size, problem.dist)
@@ -3607,7 +3629,7 @@ function FLIGHTGROUP:GetParking(airbase)
-- No parking spot for at least one asset :( -- No parking spot for at least one asset :(
if not gotit then if not gotit then
self:I(self.sid..string.format("WARNING: No free parking spot for element %s", element.name)) self:I(self.lid..string.format("WARNING: No free parking spot for element %s", element.name))
return nil return nil
end end
@@ -3722,8 +3744,9 @@ end
--- Get the proper terminal type based on generalized attribute of the group. --- Get the proper terminal type based on generalized attribute of the group.
--@param #FLIGHTGROUP self --@param #FLIGHTGROUP self
function FLIGHTGROUP:_UpdateMenu() function FLIGHTGROUP:_UpdateMenu()
env.info("FF updating menu") self:I(self.lid.."FF updating menu")
-- Get current position of group.
local position=self.group:GetCoordinate() local position=self.group:GetCoordinate()
-- Get all FLIGHTCONTROLS -- Get all FLIGHTCONTROLS
@@ -3747,12 +3770,6 @@ function FLIGHTGROUP:_UpdateMenu()
end end
table.sort(fc, _sort) table.sort(fc, _sort)
--local playermenu=self.menu.atc.root --Ops.FlightControl#FLIGHTCONTROL.PlayerMenu
--playermenu:RemoveSubMenus() --Core.Menu#MENU_GROUP
self.menu.atc.root=self.menu.atc.root or MENU
-- If there is a designated FC, we put it first. -- If there is a designated FC, we put it first.
local N=8 local N=8
if self.flightcontrol then if self.flightcontrol then