- More cleanup

OPSGROUP
- Fixed group init (masterunit)
This commit is contained in:
Frank 2024-03-31 23:33:37 +02:00
parent ef8c71d27c
commit a5632ec3a4
4 changed files with 192 additions and 103 deletions

View File

@ -3238,7 +3238,7 @@ end
--- Get the index from a given group. --- Get the index from a given group.
-- The function will search the name of the group for a #, and will return the number behind the #-mark. -- The function will search the name of the group for a #, and will return the number behind the #-mark.
function SPAWN:GetSpawnIndexFromGroup( SpawnGroup ) function SPAWN:GetSpawnIndexFromGroup( SpawnGroup )
self:F2( { self.SpawnTemplatePrefix, self.SpawnAliasPrefix, SpawnGroup } ) self:F3( { self.SpawnTemplatePrefix, self.SpawnAliasPrefix, SpawnGroup } )
local IndexString = string.match( SpawnGroup:GetName(), "#(%d*)$" ):sub( 2 ) local IndexString = string.match( SpawnGroup:GetName(), "#(%d*)$" ):sub( 2 )
local Index = tonumber( IndexString ) local Index = tonumber( IndexString )
@ -3250,7 +3250,7 @@ end
--- Return the last maximum index that can be used. --- Return the last maximum index that can be used.
function SPAWN:_GetLastIndex() function SPAWN:_GetLastIndex()
self:F( { self.SpawnTemplatePrefix, self.SpawnAliasPrefix } ) self:F3( { self.SpawnTemplatePrefix, self.SpawnAliasPrefix } )
return self.SpawnMaxGroups return self.SpawnMaxGroups
end end

View File

@ -2193,21 +2193,56 @@ function RAT:_SpawnWithRoute(_departure, _destination, _takeoff, _landing, _live
-- Actually spawn the group. -- Actually spawn the group.
local group=self:SpawnWithIndex(self.SpawnIndex) -- Wrapper.Group#GROUP local group=self:SpawnWithIndex(self.SpawnIndex) -- Wrapper.Group#GROUP
-- Group name.
local groupname=group:GetName()
-- Create a flightgroup object. -- Create a flightgroup object.
local flightgroup=FLIGHTGROUP:New(group) local flightgroup=FLIGHTGROUP:New(group)
-- Setting holding time to nil
flightgroup.holdtime=nil
local _self=self
--- Function called when passing a waypoint.
function flightgroup.OnAfterPassingWaypoint(flightgroup, From, Event, To, Waypoint) function flightgroup.OnAfterPassingWaypoint(flightgroup, From, Event, To, Waypoint)
local waypoint=Waypoint --Ops.OpsGroup#OPSGROUP.Waypoint local waypoint=Waypoint --Ops.OpsGroup#OPSGROUP.Waypoint
-- Debug info.
self:T(self.lid..string.format("RAT passed waypoint %s [uid=%d]", waypoint.name, waypoint.uid)) self:T(self.lid..string.format("RAT passed waypoint %s [uid=%d]", waypoint.name, waypoint.uid))
-- Call RAT waypoint function.
-- * calls _ATCRegisterFlight at holding waypoint ==> now in OnAfterHolding
-- * sets despawnme switch at final waypoint if landing=air
-- * sets status
RAT._WaypointFunction(group, self, waypoint.uid) RAT._WaypointFunction(group, self, waypoint.uid)
end end
function flightgroup:OnAfterPassedFinalWaypoint(From, Event, To) --- Function called when passing the final waypoint
function flightgroup.OnAfterPassedFinalWaypoint(flightgroup, From, Event, To)
self:T(self.lid..string.format("RAT passed FINAL waypoint")) self:T(self.lid..string.format("RAT passed FINAL waypoint"))
--TODO: Set despawnme switch if landing=air
end
--- Function called when flight is RTB.
function flightgroup.OnAfterRTB(flightgroup, From, Event, To, airbase, SpeedTo, SpeedHold, SpeedLand)
self:T(self.lid..string.format("RAT group is RTB"))
end
--- Function called when flight is holding.
function flightgroup.OnAfterHolding(flightgroup, From,Event,To)
self:T(self.lid..string.format("RAT group is HOLDING ==> ATCRegisterFlight"))
self:_ATCRegisterFlight(groupname, timer.getTime())
-- Register aircraft at ATC.
if self.ATCswitch then
if self.f10menu then
MENU_MISSION_COMMAND:New("Clear for landing", self.Menu[self.SubMenuName].groups[self.SpawnIndex], self.ClearForLanding, self, groupname)
end
self:_ATCRegisterFlight(groupname, timer.getTime())
end
end end
@ -2218,9 +2253,9 @@ function RAT:_SpawnWithRoute(_departure, _destination, _takeoff, _landing, _live
-- ATC is monitoring this flight (if it is supposed to land). -- ATC is monitoring this flight (if it is supposed to land).
if self.ATCswitch and landing==RAT.wp.landing then if self.ATCswitch and landing==RAT.wp.landing then
if self.returnzone then if self.returnzone then
self:_ATCAddFlight(group:GetName(), departure:GetName()) self:_ATCAddFlight(groupname, departure:GetName())
else else
self:_ATCAddFlight(group:GetName(), destination:GetName()) self:_ATCAddFlight(groupname, destination:GetName())
end end
end end
@ -2229,6 +2264,8 @@ function RAT:_SpawnWithRoute(_departure, _destination, _takeoff, _landing, _live
self:_PlaceMarkers(waypoints, self.SpawnIndex) self:_PlaceMarkers(waypoints, self.SpawnIndex)
end end
-- TODO: Use FLIGHTGROUP functions for invisible, immortal, etc.
-- Set group to be invisible. -- Set group to be invisible.
if self.invisible then if self.invisible then
self:_CommandInvisible(group, true) self:_CommandInvisible(group, true)
@ -3121,14 +3158,14 @@ function RAT:_SetRoute(takeoff, landing, _departure, _destination, _waypoint)
-- Holding and final destination. -- Holding and final destination.
if landing==RAT.wp.landing then if landing==RAT.wp.landing then
-- Holding point -- Holding point (removed the holding point because FLIGHTGROUP sends group to holding point with RTB command after the last waypoint)
c[#c+1]=Pholding -- c[#c+1]=Pholding
wp[#wp+1]=self:_Waypoint(#wp+1, "Holding Point", RAT.wp.holding, c[#wp+1], VxHolding, H_holding+h_holding) -- wp[#wp+1]=self:_Waypoint(#wp+1, "Holding Point", RAT.wp.holding, c[#wp+1], VxHolding, H_holding+h_holding)
self.waypointdescriptions[#wp]="Holding Point" -- self.waypointdescriptions[#wp]="Holding Point"
self.waypointstatus[#wp]=RAT.status.Holding -- self.waypointstatus[#wp]=RAT.status.Holding
wpholding=#wp -- wpholding=#wp
-- Final destination. -- Final destination (leave this in because FLIGHTGROUP needs to know that we want to land and removes the landing waypoint automatically)
c[#c+1]=Pdestination c[#c+1]=Pdestination
wp[#wp+1]=self:_Waypoint(#wp+1, "Final Destination", landing, c[#wp+1], VxFinal, H_destination, destination) wp[#wp+1]=self:_Waypoint(#wp+1, "Final Destination", landing, c[#wp+1], VxFinal, H_destination, destination)
self.waypointdescriptions[#wp]="Final Destination" self.waypointdescriptions[#wp]="Final Destination"
@ -4321,15 +4358,19 @@ function RAT:_OnCrash(EventData)
-- Check that the template name actually belongs to this object. -- Check that the template name actually belongs to this object.
if EventPrefix and EventPrefix == self.alias then if EventPrefix and EventPrefix == self.alias then
-- Update number of alive units in the group. -- Get ratcraft object of this group.
local ratcraft=self:_GetRatcraftFromGroup(SpawnGroup) local ratcraft=self:_GetRatcraftFromGroup(SpawnGroup)
local _i=self:GetSpawnIndexFromGroup(SpawnGroup)
if ratcraft then
-- Update number of alive units in the group.
ratcraft.nunits=ratcraft.nunits-1 ratcraft.nunits=ratcraft.nunits-1
local _n=ratcraft.nunits
-- Number of initial units.
local _n0=SpawnGroup:GetInitialSize() local _n0=SpawnGroup:GetInitialSize()
-- Debug info. -- Debug info.
local text=string.format("Event: Group %s crashed. Unit %s. Units still alive %d of %d.", SpawnGroup:GetName(), EventData.IniUnitName, _n, _n0) local text=string.format("Event: Group %s crashed. Unit %s. Units still alive %d of %d.", SpawnGroup:GetName(), EventData.IniUnitName, ratcraft.nunits, _n0)
self:T(self.lid..text) self:T(self.lid..text)
-- Set status. -- Set status.
@ -4337,15 +4378,23 @@ function RAT:_OnCrash(EventData)
self:_SetStatus(SpawnGroup, status) self:_SetStatus(SpawnGroup, status)
-- Respawn group if all units are dead. -- Respawn group if all units are dead.
if _n==0 and self.respawn_after_crash and not self.norespawn then if ratcraft.nunits==0 and self.respawn_after_crash and not self.norespawn then
local text=string.format("No units left of group %s. Group will be respawned now.", SpawnGroup:GetName())
self:T(self.lid..text) -- Debug info.
-- Respawn group. self:T(self.lid..string.format("No units left of group %s. Group will be respawned now.", SpawnGroup:GetName()))
-- Get spawn index
local idx=self:GetSpawnIndexFromGroup(SpawnGroup) local idx=self:GetSpawnIndexFromGroup(SpawnGroup)
local coord=SpawnGroup:GetCoordinate() local coord=SpawnGroup:GetCoordinate()
-- Respawn group.
self:_Respawn(idx, coord) self:_Respawn(idx, coord)
end end
else
self:E(self.lid..string.format("ERROR: Could not find ratcraft object for crashed group %s!", SpawnGroup:GetName()))
end
end end
else else
@ -4784,8 +4833,10 @@ function RAT._WaypointFunction(group, rat, wp)
-- Aircraft arrived at holding point -- Aircraft arrived at holding point
text=string.format("Flight %s to %s ATC: Holding and awaiting landing clearance.", group:GetName(), destination) text=string.format("Flight %s to %s ATC: Holding and awaiting landing clearance.", group:GetName(), destination)
rat:T(rat.lid..text)
MESSAGE:New(text, 10):ToAllIf(rat.reportstatus) MESSAGE:New(text, 10):ToAllIf(rat.reportstatus)
-- Register aircraft at ATC. -- Register aircraft at ATC.
if rat.ATCswitch then if rat.ATCswitch then
if rat.f10menu then if rat.f10menu then
@ -5700,6 +5751,7 @@ end
-- @field #boolean busy Whether airport is busy. -- @field #boolean busy Whether airport is busy.
-- @field #table onfinal List of flights on final. -- @field #table onfinal List of flights on final.
-- @field #number Nonfinal Number of flights on final. -- @field #number Nonfinal Number of flights on final.
-- @field #number traffic Number of flights that landed (just for stats).
-- @field #number Tlastclearance Time stamp when last flight started final approach. -- @field #number Tlastclearance Time stamp when last flight started final approach.
--- Data structure a RAT ATC airbase object. --- Data structure a RAT ATC airbase object.
@ -5717,7 +5769,7 @@ function RAT:_ATCInit(airports_map)
if not RAT.ATC.init then if not RAT.ATC.init then
local text="Starting RAT ATC.\nSimultanious = "..RAT.ATC.Nclearance.."\n".."Delay = "..RAT.ATC.delay local text="Starting RAT ATC.\nSimultanious = "..RAT.ATC.Nclearance.."\n".."Delay = "..RAT.ATC.delay
BASE:T(RAT.id..text) BASE:I(RAT.id..text)
for _,ap in pairs(airports_map) do for _,ap in pairs(airports_map) do
local airbase=ap --Wrapper.Airbase#AIRBASE local airbase=ap --Wrapper.Airbase#AIRBASE
@ -5727,6 +5779,14 @@ function RAT:_ATCInit(airports_map)
if not fc then if not fc then
local airport={} --#RAT.AtcAirport
airport.queue={}
airport.busy=false
airport.onfinal={}
airport.Nonfinal=0
airport.traffic=0
airport.Tlastclearance=nil
RAT.ATC.airport[name]={} RAT.ATC.airport[name]={}
RAT.ATC.airport[name].queue={} RAT.ATC.airport[name].queue={}
RAT.ATC.airport[name].busy=false RAT.ATC.airport[name].busy=false
@ -5754,7 +5814,7 @@ end
-- @param #string dest Name of the destination airport. -- @param #string dest Name of the destination airport.
function RAT:_ATCAddFlight(name, dest) function RAT:_ATCAddFlight(name, dest)
-- Debug info -- Debug info
BASE:T(RAT.id..string.format("ATC %s: Adding flight %s with destination %s.", dest, name, dest)) BASE:I(RAT.id..string.format("ATC %s: Adding flight %s with destination %s.", dest, name, dest))
local flight={} --#RAT.AtcFlight local flight={} --#RAT.AtcFlight
flight.destination=dest flight.destination=dest
@ -5787,7 +5847,7 @@ end
-- @param #string name Group name of the flight. -- @param #string name Group name of the flight.
-- @param #number time Time the fight first registered. -- @param #number time Time the fight first registered.
function RAT:_ATCRegisterFlight(name, time) function RAT:_ATCRegisterFlight(name, time)
BASE:T(RAT.id..string.format("Flight %s registered at ATC for landing clearance.", name)) BASE:I(RAT.id..string.format("Flight %s registered at ATC for landing clearance.", name))
RAT.ATC.flight[name].Tarrive=time RAT.ATC.flight[name].Tarrive=time
RAT.ATC.flight[name].holding=0 RAT.ATC.flight[name].holding=0
end end
@ -5800,27 +5860,30 @@ function RAT:_ATCStatus()
-- Current time. -- Current time.
local Tnow=timer.getTime() local Tnow=timer.getTime()
for name,_ in pairs(RAT.ATC.flight) do for name,_flight in pairs(RAT.ATC.flight) do
local flight=_flight --#RAT.AtcFlight
-- Holding time at destination. -- Holding time at destination.
local hold=RAT.ATC.flight[name].holding local hold=RAT.ATC.flight[name].holding
local dest=RAT.ATC.flight[name].destination local dest=RAT.ATC.flight[name].destination
if RAT.ATC.airport[dest] then local airport=RAT.ATC.airport[dest] --#RAT.AtcAirport
if airport then
if hold >= 0 then if hold >= 0 then
-- Some string whether the runway is busy or not. -- Some string whether the runway is busy or not.
local busy="Runway state is unknown" local busy="Runway state is unknown"
if RAT.ATC.airport[dest].Nonfinal>0 then if airport.Nonfinal>0 then
busy="Runway is occupied by "..RAT.ATC.airport[dest].Nonfinal busy="Runway is occupied by "..airport.Nonfinal
else else
busy="Runway is currently clear" busy="Runway is currently clear"
end end
-- Aircraft is holding. -- Aircraft is holding.
local text=string.format("ATC %s: Flight %s is holding for %i:%02d. %s.", dest, name, hold/60, hold%60, busy) local text=string.format("ATC %s: Flight %s is holding for %i:%02d. %s.", dest, name, hold/60, hold%60, busy)
BASE:T(RAT.id..text) BASE:I(RAT.id..text)
elseif hold==RAT.ATC.onfinal then elseif hold==RAT.ATC.onfinal then
@ -5828,7 +5891,7 @@ function RAT:_ATCStatus()
local Tfinal=Tnow-RAT.ATC.flight[name].Tonfinal local Tfinal=Tnow-RAT.ATC.flight[name].Tonfinal
local text=string.format("ATC %s: Flight %s is on final. Waiting %i:%02d for landing event.", dest, name, Tfinal/60, Tfinal%60) local text=string.format("ATC %s: Flight %s is on final. Waiting %i:%02d for landing event.", dest, name, Tfinal/60, Tfinal%60)
BASE:T(RAT.id..text) BASE:I(RAT.id..text)
elseif hold==RAT.ATC.unregistered then elseif hold==RAT.ATC.unregistered then
@ -5850,46 +5913,51 @@ end
function RAT:_ATCCheck() function RAT:_ATCCheck()
-- Init queue of flights at all airports. -- Init queue of flights at all airports.
-- TODO: Global function
RAT:_ATCQueue() RAT:_ATCQueue()
-- Current time. -- Current time.
local Tnow=timer.getTime() local Tnow=timer.getTime()
for name,_ in pairs(RAT.ATC.airport) do for airportname,_airport in pairs(RAT.ATC.airport) do
local airport=_airport --#RAT.AtcAirport
for qID,flight in ipairs(RAT.ATC.airport[name].queue) do for qID,flightname in pairs(airport.queue) do
local flight=RAT.ATC.flight[flightname] --#RAT.AtcFlight
-- Number of aircraft in queue. -- Number of aircraft in queue.
local nqueue=#RAT.ATC.airport[name].queue local nqueue=#airport.queue
-- Conditions to clear an aircraft for landing -- Conditions to clear an aircraft for landing
local landing1 local landing1=false
if RAT.ATC.airport[name].Tlastclearance then if airport.Tlastclearance then
-- Landing if time is enough and less then two planes are on final. -- Landing if time is enough and less then two planes are on final.
landing1=(Tnow-RAT.ATC.airport[name].Tlastclearance > RAT.ATC.delay) and RAT.ATC.airport[name].Nonfinal < RAT.ATC.Nclearance landing1=(Tnow-airport.Tlastclearance > RAT.ATC.delay) and airport.Nonfinal < RAT.ATC.Nclearance
else
landing1=false
end end
-- No other aircraft is on final. -- No other aircraft is on final.
local landing2=RAT.ATC.airport[name].Nonfinal==0 local landing2=airport.Nonfinal==0
if not landing1 and not landing2 then if not landing1 and not landing2 then
-- Update holding time. -- Update holding time.
RAT.ATC.flight[flight].holding=Tnow-RAT.ATC.flight[flight].Tarrive flight.holding=Tnow-flight.Tarrive
-- Debug message. -- Debug message.
local text=string.format("ATC %s: Flight %s runway is busy. You are #%d of %d in landing queue. Your holding time is %i:%02d.", name, flight, qID, nqueue, RAT.ATC.flight[flight].holding/60, RAT.ATC.flight[flight].holding%60) local text=string.format("ATC %s: Flight %s runway is busy. You are #%d of %d in landing queue. Your holding time is %i:%02d.",
BASE:T(self.lid..text) airportname, flightname, qID, nqueue, flight.holding/60, flight.holding%60)
BASE:I(self.lid..text)
else else
local text=string.format("ATC %s: Flight %s was cleared for landing. Your holding time was %i:%02d.", name, flight, RAT.ATC.flight[flight].holding/60, RAT.ATC.flight[flight].holding%60) local text=string.format("ATC %s: Flight %s was cleared for landing. Your holding time was %i:%02d.",
BASE:T(self.lid..text) airportname, flightname, flight.holding/60, flight.holding%60)
BASE:I(self.lid..text)
-- Clear flight for landing. -- Clear flight for landing.
RAT:_ATCClearForLanding(name, flight) -- TODO: Global function
RAT:_ATCClearForLanding(airportname, flightname)
end end
@ -5898,49 +5966,63 @@ function RAT:_ATCCheck()
end end
-- Update queue of flights at all airports. -- Update queue of flights at all airports.
-- TODO: Global function
RAT:_ATCQueue() RAT:_ATCQueue()
end end
--- Giving landing clearance for aircraft by setting user flag. --- Giving landing clearance for aircraft by setting user flag.
-- @param #RAT self -- @param #RAT self
-- @param #string airport Name of destination airport. -- @param #string airportname Name of destination airport.
-- @param #string flight Group name of flight, which gets landing clearence. -- @param #string flightname Group name of flight, which gets landing clearence.
function RAT:_ATCClearForLanding(airport, flight) function RAT:_ATCClearForLanding(airportname, flightname)
-- Find FLIGHTGROUP in database.
local flightgroup=_DATABASE:FindOpsGroup(flightname) --Ops.FlightGroup#FLIGHTGROUP
if flightgroup then
-- Give clear to land signal.
flightgroup:ClearToLand()
local flight=RAT.ATC.flight[flightname] --#RAT.AtcFlight
-- Flight is cleared for landing. -- Flight is cleared for landing.
RAT.ATC.flight[flight].holding=RAT.ATC.onfinal flight.holding=RAT.ATC.onfinal
-- Airport runway is busy now.
RAT.ATC.airport[airport].busy=true
-- Flight which is landing.
RAT.ATC.airport[airport].onfinal[flight]=flight
-- Number of planes on final approach.
RAT.ATC.airport[airport].Nonfinal=RAT.ATC.airport[airport].Nonfinal+1
-- Last time an aircraft got landing clearance.
RAT.ATC.airport[airport].Tlastclearance=timer.getTime()
-- Current time. -- Current time.
RAT.ATC.flight[flight].Tonfinal=timer.getTime() flight.Tonfinal=timer.getTime()
-- Set user flag to 1 ==> stop condition for holding.
trigger.action.setUserFlag(flight, 1)
-- Get flag value. local airport=RAT.ATC.airport[airportname] --#RAT.AtcAirport
local flagvalue=trigger.misc.getUserFlag(flight)
-- Airport runway is busy now.
airport.busy=true
-- Flight which is landing.
airport.onfinal[flight]=flight
-- Number of planes on final approach.
airport.Nonfinal=airport.Nonfinal+1
-- Last time an aircraft got landing clearance.
airport.Tlastclearance=timer.getTime()
-- Debug message. -- Debug message.
BASE:T(RAT.id..string.format("ATC %s: Flight %s cleared for landing (flag=%d).", airport, flight, flagvalue)) BASE:I(RAT.id..string.format("ATC %s: Flight %s cleared for landing", airportname, flightname))
if string.find(flight,"#") then if string.find(flight,"#") then
flight = string.match(flight,"^(.+)#") flight = string.match(flight,"^(.+)#")
end end
local text=string.format("ATC %s: Flight %s you are cleared for landing.", airport, flight) local text=string.format("ATC %s: Flight %s you are cleared for landing.", airportname, flightname)
MESSAGE:New(text, 10):ToAllIf(RAT.ATC.messages) MESSAGE:New(text, 10):ToAllIf(RAT.ATC.messages)
else
BASE:E("Could not clear flight for landing!")
end
end end
--- Takes care of organisational stuff after a plane has landed. --- Takes care of organisational stuff after a plane has landed.
@ -5948,38 +6030,43 @@ end
-- @param #string name Group name of flight. -- @param #string name Group name of flight.
function RAT:_ATCFlightLanded(name) function RAT:_ATCFlightLanded(name)
if RAT.ATC.flight[name] then local flight=RAT.ATC.flight[name] --#RAT.AtcFlight
if flight then
-- Destination airport. -- Destination airport.
local dest=RAT.ATC.flight[name].destination local dest=flight.destination
-- Times for holding and final approach. -- Times for holding and final approach.
local Tnow=timer.getTime() local Tnow=timer.getTime()
local Tfinal=Tnow-RAT.ATC.flight[name].Tonfinal local Tfinal=Tnow-flight.Tonfinal
local Thold=RAT.ATC.flight[name].Tonfinal-RAT.ATC.flight[name].Tarrive local Thold=flight.Tonfinal-flight.Tarrive
local airport=RAT.ATC.airport[dest] --#RAT.AtcAirport
-- Airport is not busy any more. -- Airport is not busy any more.
RAT.ATC.airport[dest].busy=false airport.busy=false
-- No aircraft on final any more. -- No aircraft on final any more.
RAT.ATC.airport[dest].onfinal[name]=nil airport.onfinal[name]=nil
-- Decrease number of aircraft on final. -- Decrease number of aircraft on final.
RAT.ATC.airport[dest].Nonfinal=RAT.ATC.airport[dest].Nonfinal-1 airport.Nonfinal=airport.Nonfinal-1
-- Remove this flight from list of flights. -- Remove this flight from list of flights.
-- TODO: Global function
RAT:_ATCDelFlight(RAT.ATC.flight, name) RAT:_ATCDelFlight(RAT.ATC.flight, name)
-- Increase landing counter to monitor traffic. -- Increase landing counter to monitor traffic.
RAT.ATC.airport[dest].traffic=RAT.ATC.airport[dest].traffic+1 airport.traffic=airport.traffic+1
-- Number of planes landing per hour. -- Number of planes landing per hour.
local TrafficPerHour=RAT.ATC.airport[dest].traffic/(timer.getTime()-RAT.ATC.T0)*3600 local TrafficPerHour=aiport.traffic/(timer.getTime()-RAT.ATC.T0)*3600
-- Debug info -- Debug info
BASE:T(RAT.id..string.format("ATC %s: Flight %s landed. Tholding = %i:%02d, Tfinal = %i:%02d.", dest, name, Thold/60, Thold%60, Tfinal/60, Tfinal%60)) BASE:I(RAT.id..string.format("ATC %s: Flight %s landed. Tholding = %i:%02d, Tfinal = %i:%02d.", dest, name, Thold/60, Thold%60, Tfinal/60, Tfinal%60))
BASE:T(RAT.id..string.format("ATC %s: Number of flights still on final %d.", dest, RAT.ATC.airport[dest].Nonfinal)) BASE:I(RAT.id..string.format("ATC %s: Number of flights still on final %d.", dest, airport.Nonfinal))
BASE:T(RAT.id..string.format("ATC %s: Traffic report: Number of planes landed in total %d. Flights/hour = %3.2f.", dest, RAT.ATC.airport[dest].traffic, TrafficPerHour)) BASE:I(RAT.id..string.format("ATC %s: Traffic report: Number of planes landed in total %d. Flights/hour = %3.2f.", dest, airport.traffic, TrafficPerHour))
if string.find(name,"#") then if string.find(name,"#") then
name = string.match(name,"^(.+)#") name = string.match(name,"^(.+)#")

View File

@ -59,6 +59,7 @@
-- @field #boolean prohibitAB Disallow (true) or allow (false) AI to use the afterburner. -- @field #boolean prohibitAB Disallow (true) or allow (false) AI to use the afterburner.
-- @field #boolean jettisonEmptyTanks Allow (true) or disallow (false) AI to jettison empty fuel tanks. -- @field #boolean jettisonEmptyTanks Allow (true) or disallow (false) AI to jettison empty fuel tanks.
-- @field #boolean jettisonWeapons Allow (true) or disallow (false) AI to jettison weapons if in danger. -- @field #boolean jettisonWeapons Allow (true) or disallow (false) AI to jettison weapons if in danger.
-- @field #number holdtime Time [s] flight is holding before going on final. Set to nil for indefinitely.
-- --
-- @extends Ops.OpsGroup#OPSGROUP -- @extends Ops.OpsGroup#OPSGROUP
@ -273,6 +274,7 @@ function FLIGHTGROUP:New(group)
-- Holding flag. -- Holding flag.
self.flaghold=USERFLAG:New(string.format("%s_FlagHold", self.groupname)) self.flaghold=USERFLAG:New(string.format("%s_FlagHold", self.groupname))
self.flaghold:Set(0) self.flaghold:Set(0)
self.holdtime=2*60
-- Add FSM transitions. -- Add FSM transitions.
-- From State --> Event --> To State -- From State --> Event --> To State
@ -2098,7 +2100,7 @@ function FLIGHTGROUP:onafterSpawned(From, Event, To)
-- Debug info. -- Debug info.
if self.verbose>=1 then if self.verbose>=1 then
local text=string.format("Initialized Flight Group %s:\n", self.groupname) local text=string.format("Initialized Flight Group %s:\n", self.groupname)
text=text..string.format("Unit type = %s\n", self.actype) text=text..string.format("Unit type = %s\n", tostring(self.actype))
text=text..string.format("Speed max = %.1f Knots\n", UTILS.KmphToKnots(self.speedMax)) text=text..string.format("Speed max = %.1f Knots\n", UTILS.KmphToKnots(self.speedMax))
text=text..string.format("Range max = %.1f km\n", self.rangemax/1000) text=text..string.format("Range max = %.1f km\n", self.rangemax/1000)
text=text..string.format("Ceiling = %.1f feet\n", UTILS.MetersToFeet(self.ceiling)) text=text..string.format("Ceiling = %.1f feet\n", UTILS.MetersToFeet(self.ceiling))
@ -3199,7 +3201,7 @@ function FLIGHTGROUP:_LandAtAirbase(airbase, SpeedTo, SpeedHold, SpeedLand)
self.flaghold:Set(0) self.flaghold:Set(0)
-- Set holding time. -- Set holding time.
local holdtime=2*60 local holdtime=self.holdtime
if fc or self.airboss then if fc or self.airboss then
holdtime=nil holdtime=nil
end end

View File

@ -597,7 +597,7 @@ function OPSGROUP:New(group)
if units then if units then
local masterunit=units[1] --Wrapper.Unit#UNIT local masterunit=units[1] --Wrapper.Unit#UNIT
if unit then if masterunit then
-- Get Descriptors. -- Get Descriptors.
self.descriptors=masterunit:GetDesc() self.descriptors=masterunit:GetDesc()