mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
OPS FC
- Improved holding point
This commit is contained in:
@@ -2505,8 +2505,17 @@ function AUFTRAG:GetRequiredAssets(Legion)
|
|||||||
--if Legion and self.Nassets[Legion.alias] then
|
--if Legion and self.Nassets[Legion.alias] then
|
||||||
-- N=self.Nassets[Legion.alias]
|
-- N=self.Nassets[Legion.alias]
|
||||||
--end
|
--end
|
||||||
|
|
||||||
|
local Nmin=self.NassetsMin
|
||||||
|
local Nmax=self.NassetsMax
|
||||||
|
|
||||||
|
if self.type==AUFTRAG.Type.RELOCATECOHORT then
|
||||||
|
local cohort=self.DCStask.params.cohort --Ops.Cohort#COHORT
|
||||||
|
Nmin=#cohort.assets
|
||||||
|
Nmax=Nmin
|
||||||
|
end
|
||||||
|
|
||||||
return self.NassetsMin, self.NassetsMax
|
return Nmin, Nmax
|
||||||
end
|
end
|
||||||
|
|
||||||
--- **[LEGION, COMMANDER, CHIEF]** Define how many assets are required that escort the mission assets.
|
--- **[LEGION, COMMANDER, CHIEF]** Define how many assets are required that escort the mission assets.
|
||||||
|
|||||||
@@ -32,13 +32,14 @@
|
|||||||
-- @field #table clients Table with all clients spawning at this airbase.
|
-- @field #table clients Table with all clients spawning at this airbase.
|
||||||
-- @field Ops.ATIS#ATIS atis ATIS object.
|
-- @field Ops.ATIS#ATIS atis ATIS object.
|
||||||
-- @field #number activerwyno Number of active runway.
|
-- @field #number activerwyno Number of active runway.
|
||||||
-- @field #number atcfreq ATC radio frequency.
|
-- @field #number frequency ATC radio frequency in MHz.
|
||||||
-- @field Core.RadioQueue#RADIOQUEUE atcradio ATC radio queue.
|
-- @field #number modulation ATC radio modulation, *e.g.* `radio.modulation.AM`.
|
||||||
-- @field #number Nlanding 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.
|
||||||
-- @field Core.Spawn#SPAWN parkingGuard Parking guard spawner.
|
-- @field Core.Spawn#SPAWN parkingGuard Parking guard spawner.
|
||||||
-- @field #table holdingpoints Holding points.
|
-- @field #table holdingpoints Holding points.
|
||||||
|
-- @field #number hpcounter Counter for holding zones.
|
||||||
-- @field Sound.SRS#MSRS msrsTower Moose SRS wrapper.
|
-- @field Sound.SRS#MSRS msrsTower Moose SRS wrapper.
|
||||||
-- @field Sound.SRS#MSRS msrsPilot Moose SRS wrapper.
|
-- @field Sound.SRS#MSRS msrsPilot Moose SRS wrapper.
|
||||||
-- @extends Core.Fsm#FSM
|
-- @extends Core.Fsm#FSM
|
||||||
@@ -66,6 +67,7 @@
|
|||||||
-- * As soon as AI aircraft taxi or land, we completely loose control. All is governed by the internal DCS AI logic.
|
-- * As soon as AI aircraft taxi or land, we completely loose control. All is governed by the internal DCS AI logic.
|
||||||
-- * We have no control over the active runway or which runway is used by the AI if there are multiple.
|
-- * We have no control over the active runway or which runway is used by the AI if there are multiple.
|
||||||
-- * Only one player/client per group as we can create menus only for a group and not for a specific unit.
|
-- * Only one player/client per group as we can create menus only for a group and not for a specific unit.
|
||||||
|
-- * Only FLIGHTGROUPS are controlled.
|
||||||
--
|
--
|
||||||
--
|
--
|
||||||
-- @field #FLIGHTCONTROL
|
-- @field #FLIGHTCONTROL
|
||||||
@@ -91,10 +93,14 @@ FLIGHTCONTROL = {
|
|||||||
dTlanding = nil,
|
dTlanding = nil,
|
||||||
Nparkingspots = nil,
|
Nparkingspots = nil,
|
||||||
holdingpoints = {},
|
holdingpoints = {},
|
||||||
|
hpcounter = 0,
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Holding point. Contains holding stacks.
|
--- Holding point. Contains holding stacks.
|
||||||
-- @type FLIGHTCONTROL.HoldingPoint
|
-- @type FLIGHTCONTROL.HoldingPoint
|
||||||
|
-- @field Core.Zone#ZONE arrivalzone Zone where aircraft should arrive.
|
||||||
|
-- @field #number uid Unique ID.
|
||||||
|
-- @field #string name Name of the zone, which is <zonename>-<uid>.
|
||||||
-- @field Core.Point#COORDINATE pos0 First position of racetrack holding point.
|
-- @field Core.Point#COORDINATE pos0 First position of racetrack holding point.
|
||||||
-- @field Core.Point#COORDINATE pos1 Second position of racetrack holding point.
|
-- @field Core.Point#COORDINATE pos1 Second position of racetrack holding point.
|
||||||
-- @field #number angelsmin Smallest holding altitude in angels.
|
-- @field #number angelsmin Smallest holding altitude in angels.
|
||||||
@@ -107,6 +113,7 @@ FLIGHTCONTROL = {
|
|||||||
-- @field #number angels Holding altitude in Angels.
|
-- @field #number angels Holding altitude in Angels.
|
||||||
-- @field Core.Point#COORDINATE pos0 First position of racetrack holding point.
|
-- @field Core.Point#COORDINATE pos0 First position of racetrack holding point.
|
||||||
-- @field Core.Point#COORDINATE pos1 Second position of racetrack holding point.
|
-- @field Core.Point#COORDINATE pos1 Second position of racetrack holding point.
|
||||||
|
-- @field #number heading Heading.
|
||||||
|
|
||||||
--- Player menu data.
|
--- Player menu data.
|
||||||
-- @type FLIGHTCONTROL.PlayerMenu
|
-- @type FLIGHTCONTROL.PlayerMenu
|
||||||
@@ -149,18 +156,6 @@ FLIGHTCONTROL.FlightStatus={
|
|||||||
-- @field #number width Width of runway in meters.
|
-- @field #number width Width of runway in meters.
|
||||||
-- @field Core.Point#COORDINATE position Position of runway start.
|
-- @field Core.Point#COORDINATE position Position of runway start.
|
||||||
|
|
||||||
--- Sound file data.
|
|
||||||
-- @type FLIGHTCONTROL.Soundfile
|
|
||||||
-- @field #string filename Name of the file
|
|
||||||
-- @field #number duration Duration in seconds.
|
|
||||||
|
|
||||||
--- Sound files.
|
|
||||||
-- @type FLIGHTCONTROL.Sound
|
|
||||||
-- @field #FLIGHTCONTROL.Soundfile ActiveRunway
|
|
||||||
FLIGHTCONTROL.Sound = {
|
|
||||||
ActiveRunway={filename="ActiveRunway.ogg", duration=0.99},
|
|
||||||
}
|
|
||||||
|
|
||||||
--- FlightControl class version.
|
--- FlightControl class version.
|
||||||
-- @field #string version
|
-- @field #string version
|
||||||
FLIGHTCONTROL.version="0.5.0"
|
FLIGHTCONTROL.version="0.5.0"
|
||||||
@@ -169,10 +164,9 @@ FLIGHTCONTROL.version="0.5.0"
|
|||||||
-- TODO list
|
-- TODO list
|
||||||
--
|
--
|
||||||
|
|
||||||
-- TODO:
|
-- TODO: Support airwings. Dont give clearance for Alert5 or if mission has not started.
|
||||||
-- TODO: Switch to enable/disable AI messages.
|
-- TODO: Switch to enable/disable AI messages.
|
||||||
-- TODO: Improve TTS messages.
|
-- TODO: Improve TTS messages.
|
||||||
-- DONE: Add SRS TTS.
|
|
||||||
-- TODO: Define holding zone.
|
-- TODO: Define holding zone.
|
||||||
-- TODO: Add helos.
|
-- TODO: Add helos.
|
||||||
-- TODO: Talk me down option.
|
-- TODO: Talk me down option.
|
||||||
@@ -180,6 +174,7 @@ FLIGHTCONTROL.version="0.5.0"
|
|||||||
-- TODO: ATC voice overs.
|
-- TODO: ATC voice overs.
|
||||||
-- TODO: Check runways and clean up.
|
-- TODO: Check runways and clean up.
|
||||||
-- TODO: Accept and forbit parking spots.
|
-- TODO: Accept and forbit parking spots.
|
||||||
|
-- DONE: Add SRS TTS.
|
||||||
-- DONE: Add parking guard.
|
-- DONE: Add parking guard.
|
||||||
-- NOGO: Add FARPS?
|
-- NOGO: Add FARPS?
|
||||||
-- DONE: Interface with FLIGHTGROUP.
|
-- DONE: Interface with FLIGHTGROUP.
|
||||||
@@ -354,6 +349,12 @@ function FLIGHTCONTROL:AddHoldingPoint(ArrivalZone, Heading, Length, Flightlevel
|
|||||||
|
|
||||||
hp.arrivalzone=ArrivalZone
|
hp.arrivalzone=ArrivalZone
|
||||||
|
|
||||||
|
self.hpcounter=self.hpcounter+1
|
||||||
|
|
||||||
|
hp.uid=self.hpcounter
|
||||||
|
|
||||||
|
hp.name=string.format("%s-%d", ArrivalZone:GetName(), hp.uid)
|
||||||
|
|
||||||
hp.pos0=ArrivalZone:GetCoordinate()
|
hp.pos0=ArrivalZone:GetCoordinate()
|
||||||
|
|
||||||
Length=UTILS.NMToMeters(Length or 15)
|
Length=UTILS.NMToMeters(Length or 15)
|
||||||
@@ -1859,7 +1860,7 @@ end
|
|||||||
--- Player calls inbound.
|
--- Player calls inbound.
|
||||||
-- @param #FLIGHTCONTROL self
|
-- @param #FLIGHTCONTROL self
|
||||||
-- @param #string groupname Name of the flight group.
|
-- @param #string groupname Name of the flight group.
|
||||||
function FLIGHTCONTROL:_PlayerInbound(groupname)
|
function FLIGHTCONTROL:_PlayerRequestInbound(groupname)
|
||||||
|
|
||||||
-- Get flight group.
|
-- Get flight group.
|
||||||
local flight=_DATABASE:GetOpsGroup(groupname) --Ops.FlightGroup#FLIGHTGROUP
|
local flight=_DATABASE:GetOpsGroup(groupname) --Ops.FlightGroup#FLIGHTGROUP
|
||||||
@@ -1877,6 +1878,15 @@ function FLIGHTCONTROL:_PlayerInbound(groupname)
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Call sign.
|
||||||
|
local callsign=flight:GetCallsignName()
|
||||||
|
|
||||||
|
-- Pilot calls inbound for landing.
|
||||||
|
local text=string.format("%s, %s, inbound for landing", self.alias, callsign)
|
||||||
|
|
||||||
|
-- Radio message.
|
||||||
|
self:TransmissionPilot(text, flight)
|
||||||
|
|
||||||
-- Distance from player to airbase.
|
-- Distance from player to airbase.
|
||||||
local dist=flight:GetCoordinate():Get2DDistance(self:GetCoordinate())
|
local dist=flight:GetCoordinate():Get2DDistance(self:GetCoordinate())
|
||||||
|
|
||||||
@@ -1889,12 +1899,12 @@ function FLIGHTCONTROL:_PlayerInbound(groupname)
|
|||||||
self:SetFlightStatus(flight, FLIGHTCONTROL.FlightStatus.INBOUND)
|
self:SetFlightStatus(flight, FLIGHTCONTROL.FlightStatus.INBOUND)
|
||||||
|
|
||||||
-- Get holding point.
|
-- Get holding point.
|
||||||
local stack=self:_GetHoldingpoint(flight)
|
local stack=self:_GetHoldingpoint(flight)
|
||||||
|
|
||||||
if stack then
|
if stack then
|
||||||
|
|
||||||
-- Set flight.
|
-- Set flight.
|
||||||
stack.flightgroup=self
|
stack.flightgroup=flight
|
||||||
|
|
||||||
-- Stack.
|
-- Stack.
|
||||||
flight.stack=stack
|
flight.stack=stack
|
||||||
@@ -1911,10 +1921,11 @@ function FLIGHTCONTROL:_PlayerInbound(groupname)
|
|||||||
local dist=UTILS.MetersToNM(distance)
|
local dist=UTILS.MetersToNM(distance)
|
||||||
|
|
||||||
-- Message text.
|
-- Message text.
|
||||||
local text=string.format("Roger, Fly heading %03d for %d nautical miles and report status when entering the holding pattern", heading, dist)
|
local text=string.format("%s, %s, roger, fly heading %03d for %d nautical miles, hold at angels %d. Report status when entering the pattern",
|
||||||
|
callsign, self.alias, heading, dist, stack.angels)
|
||||||
|
|
||||||
-- Send message.
|
-- Send message.
|
||||||
self:TransmissionTower(text, flight)
|
self:TransmissionTower(text, flight, 15)
|
||||||
|
|
||||||
else
|
else
|
||||||
self:E(self.lid..string.format("WARNING: Could not get holding stack for flight %s", flight:GetName()))
|
self:E(self.lid..string.format("WARNING: Could not get holding stack for flight %s", flight:GetName()))
|
||||||
@@ -1926,7 +1937,7 @@ function FLIGHTCONTROL:_PlayerInbound(groupname)
|
|||||||
local text=string.format("Negative, you have to be withing 50 nautical miles of the airbase to request inbound!")
|
local text=string.format("Negative, you have to be withing 50 nautical miles of the airbase to request inbound!")
|
||||||
|
|
||||||
-- Send message.
|
-- Send message.
|
||||||
self:TransmissionTower(text)
|
self:TextMessageToFlight(text, flight, 10)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1935,7 +1946,56 @@ function FLIGHTCONTROL:_PlayerInbound(groupname)
|
|||||||
local text=string.format("Negative, you must be AIRBORNE to call INBOUND!")
|
local text=string.format("Negative, you must be AIRBORNE to call INBOUND!")
|
||||||
|
|
||||||
-- Send message.
|
-- Send message.
|
||||||
self:TransmissionTower(text)
|
self:TextMessageToFlight(text, flight, 10)
|
||||||
|
end
|
||||||
|
|
||||||
|
else
|
||||||
|
MESSAGE:New(string.format("Cannot find flight group %s.", tostring(groupname)), 5):ToAll()
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Player calls inbound.
|
||||||
|
-- @param #FLIGHTCONTROL self
|
||||||
|
-- @param #string groupname Name of the flight group.
|
||||||
|
function FLIGHTCONTROL:_PlayerAbortInbound(groupname)
|
||||||
|
|
||||||
|
-- Get flight group.
|
||||||
|
local flight=_DATABASE:GetOpsGroup(groupname) --Ops.FlightGroup#FLIGHTGROUP
|
||||||
|
|
||||||
|
if flight then
|
||||||
|
|
||||||
|
if flight:IsInbound() and self:IsControlling(flight) then
|
||||||
|
|
||||||
|
-- Call sign.
|
||||||
|
local callsign=flight:GetCallsignName()
|
||||||
|
|
||||||
|
-- Pilot calls inbound for landing.
|
||||||
|
local text=string.format("%s, %s, abort inbound", self.alias, callsign)
|
||||||
|
|
||||||
|
-- Radio message.
|
||||||
|
self:TransmissionPilot(text, flight)
|
||||||
|
|
||||||
|
-- Add flight to inbound queue.
|
||||||
|
self:_RemoveFlight(flight)
|
||||||
|
|
||||||
|
-- Set flight.
|
||||||
|
flight.stack.flightgroup=nil
|
||||||
|
flight.stack=nil
|
||||||
|
|
||||||
|
-- Message text.
|
||||||
|
local text=string.format("%s, %s, roger, have a nice day!", callsign, self.alias)
|
||||||
|
|
||||||
|
-- Send message.
|
||||||
|
self:TransmissionTower(text, flight, 15)
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
-- Error you are not airborne!
|
||||||
|
local text=string.format("Negative, you must be INBOUND and CONTROLLED by us!")
|
||||||
|
|
||||||
|
-- Send message.
|
||||||
|
self:TextMessageToFlight(text, flight, 10)
|
||||||
end
|
end
|
||||||
|
|
||||||
else
|
else
|
||||||
@@ -2273,7 +2333,7 @@ end
|
|||||||
--- Get element of flight from its unit name.
|
--- Get element of flight from its unit name.
|
||||||
-- @param #FLIGHTCONTROL self
|
-- @param #FLIGHTCONTROL self
|
||||||
-- @param #string unitname Name of the unit.
|
-- @param #string unitname Name of the unit.
|
||||||
-- @return #FLIGHTCONTROL.FlightElement Element of the flight or nil.
|
-- @return Ops.OpsGroup#OPSGROUP.Element Element of the flight or nil.
|
||||||
-- @return #number Element index or nil.
|
-- @return #number Element index or nil.
|
||||||
-- @return Ops.FlightGroup#FLIGHTGROUP The Flight group or nil.
|
-- @return Ops.FlightGroup#FLIGHTGROUP The Flight group or nil.
|
||||||
function FLIGHTCONTROL:_GetFlightElement(unitname)
|
function FLIGHTCONTROL:_GetFlightElement(unitname)
|
||||||
@@ -2292,7 +2352,7 @@ function FLIGHTCONTROL:_GetFlightElement(unitname)
|
|||||||
|
|
||||||
-- Loop over all elements in flight group.
|
-- Loop over all elements in flight group.
|
||||||
for i,_element in pairs(flight.elements) do
|
for i,_element in pairs(flight.elements) do
|
||||||
local element=_element --#FLIGHTCONTROL.FlightElement
|
local element=_element --Ops.OpsGroup#OPSGROUP.Element
|
||||||
|
|
||||||
if element.unit:GetName()==unitname then
|
if element.unit:GetName()==unitname then
|
||||||
return element, i, flight
|
return element, i, flight
|
||||||
@@ -2448,11 +2508,18 @@ function FLIGHTCONTROL:_GetHoldingpoint(flight)
|
|||||||
|
|
||||||
]]
|
]]
|
||||||
|
|
||||||
|
-- Debug message.
|
||||||
|
self:T(self.lid..string.format("Getting holding point for flight %s", flight:GetName()))
|
||||||
|
|
||||||
for i,_hp in pairs(self.holdingpoints) do
|
for i,_hp in pairs(self.holdingpoints) do
|
||||||
local holdingpoint=_hp --#FLIGHTCONTROL.HoldingPoint
|
local holdingpoint=_hp --#FLIGHTCONTROL.HoldingPoint
|
||||||
|
|
||||||
|
self:T(self.lid..string.format("Checking holding point %s", holdingpoint.name))
|
||||||
|
|
||||||
for j,_stack in pairs(holdingpoint.stacks) do
|
for j,_stack in pairs(holdingpoint.stacks) do
|
||||||
local stack=_stack --#FLIGHTCONTROL.HoldingStack
|
local stack=_stack --#FLIGHTCONTROL.HoldingStack
|
||||||
|
local name=stack.flightgroup and stack.flightgroup:GetName() or "empty"
|
||||||
|
self:T(self.lid..string.format("Stack %d: %s", j, name))
|
||||||
if not stack.flightgroup then
|
if not stack.flightgroup then
|
||||||
return stack
|
return stack
|
||||||
end
|
end
|
||||||
@@ -2467,17 +2534,6 @@ end
|
|||||||
-- Radio Functions
|
-- Radio Functions
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
--- Transmission via RADIOQUEUE.
|
|
||||||
-- @param #FLIGHTCONTROL self
|
|
||||||
-- @param #FLIGHTCONTROL.Soundfile sound FLIGHTCONTROL sound object.
|
|
||||||
-- @param #number interval Interval in seconds after the last transmission finished.
|
|
||||||
-- @param #string subtitle Subtitle of the transmission.
|
|
||||||
-- @param #string path Path to sound file. Default self.soundpath.
|
|
||||||
function FLIGHTCONTROL:Transmission2(sound, interval, subtitle, path)
|
|
||||||
self.radioqueue:NewTransmission(sound.filename, sound.duration, path or self.soundpath, nil, interval, subtitle, self.subduration)
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
--- Radio transmission from tower.
|
--- Radio transmission from tower.
|
||||||
-- @param #FLIGHTCONTROL self
|
-- @param #FLIGHTCONTROL self
|
||||||
-- @param #string Text The text to transmit.
|
-- @param #string Text The text to transmit.
|
||||||
|
|||||||
@@ -713,8 +713,17 @@ function FLIGHTGROUP:ClearToLand(Delay)
|
|||||||
else
|
else
|
||||||
|
|
||||||
if self:IsHolding() then
|
if self:IsHolding() then
|
||||||
|
|
||||||
|
-- Set flag.
|
||||||
self:T(self.lid..string.format("Clear to land ==> setting holding flag to 1 (true)"))
|
self:T(self.lid..string.format("Clear to land ==> setting holding flag to 1 (true)"))
|
||||||
self.flaghold:Set(1)
|
self.flaghold:Set(1)
|
||||||
|
|
||||||
|
-- Clear holding stack.
|
||||||
|
if self.stack then
|
||||||
|
self.stack.flightgroup=nil
|
||||||
|
self.stack=nil
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -2536,12 +2545,16 @@ function FLIGHTGROUP:_LandAtAirbase(airbase, SpeedTo, SpeedHold, SpeedLand)
|
|||||||
|
|
||||||
-- Do we have a flight control?
|
-- Do we have a flight control?
|
||||||
local fc=_DATABASE:GetFlightControl(airbase:GetName())
|
local fc=_DATABASE:GetFlightControl(airbase:GetName())
|
||||||
|
|
||||||
if fc then
|
if fc then
|
||||||
|
|
||||||
-- Get holding point from flight control.
|
-- Get holding point from flight control.
|
||||||
local HoldingPoint=fc:_GetHoldingpoint(self)
|
local HoldingPoint=fc:_GetHoldingpoint(self)
|
||||||
|
|
||||||
if HoldingPoint then
|
if HoldingPoint then
|
||||||
|
|
||||||
|
HoldingPoint.flightgroup=self
|
||||||
|
self.stack=HoldingPoint
|
||||||
|
|
||||||
-- Race track points.
|
-- Race track points.
|
||||||
p0=HoldingPoint.pos0
|
p0=HoldingPoint.pos0
|
||||||
@@ -2553,6 +2566,8 @@ function FLIGHTGROUP:_LandAtAirbase(airbase, SpeedTo, SpeedHold, SpeedLand)
|
|||||||
p1:MarkToAll(string.format("%s: Holding point P1, alt=%d meters", self:GetName(), p0.y))
|
p1:MarkToAll(string.format("%s: Holding point P1, alt=%d meters", self:GetName(), p0.y))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Set flightcontrol for this flight.
|
-- Set flightcontrol for this flight.
|
||||||
@@ -2809,6 +2824,7 @@ function FLIGHTGROUP:onafterHolding(From, Event, To)
|
|||||||
-- Holding time stamp.
|
-- Holding time stamp.
|
||||||
self.Tholding=timer.getAbsTime()
|
self.Tholding=timer.getAbsTime()
|
||||||
|
|
||||||
|
-- Debug message.
|
||||||
local text=string.format("Flight group %s is HOLDING now", self.groupname)
|
local text=string.format("Flight group %s is HOLDING now", self.groupname)
|
||||||
self:T(self.lid..text)
|
self:T(self.lid..text)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user