This commit is contained in:
Frank
2019-09-11 20:09:55 +02:00
parent af3bf7dece
commit a3067740a3
6 changed files with 385 additions and 216 deletions
+3 -3
View File
@@ -621,7 +621,7 @@ do -- SETTINGS
local text="Messages and Reports" local text="Messages and Reports"
if self.MenuShort then if self.MenuShort then
text="Messages" text="Messages & Reports"
end end
local MessagesMenu = MENU_GROUP:New( MenuGroup, text, SettingsMenu ):SetTime( MenuTime ) local MessagesMenu = MENU_GROUP:New( MenuGroup, text, SettingsMenu ):SetTime( MenuTime )
@@ -848,9 +848,9 @@ do -- SETTINGS
local text="Messages and Reports" local text="Messages and Reports"
if self.MenuShort then if self.MenuShort then
text="Messages" text="Messages & Reports"
end end
local MessagesMenu = MENU_GROUP:New( PlayerGroup, "Messages and Reports", PlayerMenu ) local MessagesMenu = MENU_GROUP:New( PlayerGroup, text, PlayerMenu )
local UpdateMessagesMenu = MENU_GROUP:New( PlayerGroup, "Update Messages", MessagesMenu ) local UpdateMessagesMenu = MENU_GROUP:New( PlayerGroup, "Update Messages", MessagesMenu )
MENU_GROUP_COMMAND:New( PlayerGroup, "Off", UpdateMessagesMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Update, 0 ) MENU_GROUP_COMMAND:New( PlayerGroup, "Off", UpdateMessagesMenu, self.MenuGroupMessageTimingsSystem, self, PlayerUnit, PlayerGroup, PlayerName, MESSAGE.Type.Update, 0 )
+60 -145
View File
@@ -1,4 +1,4 @@
--- **ATC** - (R2.5) - Manage recovery of aircraft at airdromes and FARPS. --- **OPS** - (R2.5) - Manage recovery of aircraft at airdromes and FARPS.
-- --
-- --
-- --
@@ -9,8 +9,8 @@
-- === -- ===
-- --
-- ### Author: **funkyfranky** -- ### Author: **funkyfranky**
-- @module ATC.FlightControl -- @module OPS.FlightControl
-- @image ATC_FlightControl.png -- @image OPS_FlightControl.png
--- FLIGHTCONTROL class. --- FLIGHTCONTROL class.
@@ -156,6 +156,9 @@ function FLIGHTCONTROL:New(airbasename)
BASE:TraceLevel(1) BASE:TraceLevel(1)
--self.dTstatus=0.1 --self.dTstatus=0.1
end end
-- Add to data base.
_DATABASE:AddFlightControl(self)
return self return self
end end
@@ -458,36 +461,6 @@ function FLIGHTCONTROL:OnEventTakeoff(EventData)
return return
end end
-- Get airbase name.
local airbasename=tostring(airbase:GetName())
-- Check if landed at this airbase.
if airbasename==self.airbasename then
-- AI always lands ==> remove unit from flight group and queues.
local flight=self:_ElementTookOff(unit)
if flight then
self:T(self.lid..string.format("Flight element %s took off.", EventData.IniUnitName))
-- Check if everybody is in the air.
local all=true
for _,_elem in pairs(flight.elements) do
local element=_elem --#FLIGHTCONTROL.FlightElement
if not element.tookoff then
all=false
end
end
-- Remove flight.
if all then
self:T(self.lid..string.format("Flight group %s took off.", flight.groupname))
self:_RemoveFlightFromQueue(self.Qtakeoff, flight)
end
end
end
end end
--- Event handler for event engine startup. --- Event handler for event engine startup.
@@ -506,17 +479,7 @@ function FLIGHTCONTROL:OnEventEngineStartup(EventData)
if not unit then if not unit then
return return
end end
-- Get flight element.
local element, idx, flight=self:_GetFlightElement(EventData.IniUnitName)
if element then
local parkingspot=self:_GetElementParkingSpot(element)
if parkingspot then
self:_AddFlightToTakeoffQueue(flight)
end
end
end end
--- Event handler for event engine shutdown. --- Event handler for event engine shutdown.
@@ -541,22 +504,12 @@ end
--- Event handler for event crash. --- Event handler for event crash.
-- @param #FLIGHTCONTROL self -- @param #FLIGHTCONTROL self
-- @param Core.Event#EVENTDATA EventData -- @param Core.Event#EVENTDATA EventData
function FLIGHTCONTROL:OnEventEngineCrash(EventData) function FLIGHTCONTROL:OnEventCrash(EventData)
self:F3({EvendData=EventData}) self:F3({EvendData=EventData})
self:T2(self.lid..string.format("CRASH: unit = %s", tostring(EventData.IniUnitName))) self:T2(self.lid..string.format("CRASH: unit = %s", tostring(EventData.IniUnitName)))
self:T2(self.lid..string.format("CRASH: group = %s", tostring(EventData.IniGroupName))) self:T2(self.lid..string.format("CRASH: group = %s", tostring(EventData.IniGroupName)))
-- Unit that took off.
local unit=EventData.IniUnit
-- Nil check for unit.
if not unit then
return
end
self:_RemoveFlightElement(EventData.IniUnitName)
end end
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
@@ -617,9 +570,7 @@ function FLIGHTCONTROL:_CheckParking()
for _,_element in pairs(_flight.elements) do for _,_element in pairs(_flight.elements) do
local element=_element --Ops.FlightGroup#FLIGHTGROUP.Element local element=_element --Ops.FlightGroup#FLIGHTGROUP.Element
local unit=element.unit if element.unit and element.unit:IsAlive() then
if unit and unit:IsAlive() then
-- Distance to parking spot. -- Distance to parking spot.
local dist=element.unit:GetCoordinate():Get3DDistance(spot.position) local dist=element.unit:GetCoordinate():Get3DDistance(spot.position)
@@ -632,7 +583,6 @@ function FLIGHTCONTROL:_CheckParking()
else else
self:E(self.lid..string.format("ERROR: Element %s is not alive any more!", element.unitname)) self:E(self.lid..string.format("ERROR: Element %s is not alive any more!", element.unitname))
self:_RemoveFlightElement(element.unitname)
end end
end end
@@ -651,19 +601,9 @@ function FLIGHTCONTROL:_GetNextWaitingFight()
for _,_flight in pairs(self.Qwaiting) do for _,_flight in pairs(self.Qwaiting) do
local flight=_flight --Ops.FlightGroup#FLIGHTGROUP local flight=_flight --Ops.FlightGroup#FLIGHTGROUP
-- Current stack. -- TODO: Sort by fuel, holding time.
local stack=flight.flag
-- Total marshal time in seconds. return flight
local Tmarshal=timer.getAbsTime()-flight.time
-- Min time in marshal stack.
local TmarshalMin=3*60 --Three minutes for human players.
-- Check if conditions are right.
if flight.holding~=nil and Tmarshal>=TmarshalMin then
return flight
end
end end
@@ -687,12 +627,12 @@ function FLIGHTCONTROL:_PrintQueue(queue, name)
local flight=_flight --Ops.FlightGroup#FLIGHTGROUP local flight=_flight --Ops.FlightGroup#FLIGHTGROUP
-- Gather info. -- Gather info.
local clock=UTILS.SecondsToClock(timer.getAbsTime()-flight.time) local clock="0:0" --UTILS.SecondsToClock(timer.getAbsTime()-flight.time)
local fuel=flight.group:GetFuelMin()*100 local fuel=flight.group:GetFuelMin()*100
local ai=tostring(flight.ai) local ai=tostring(flight.ai)
local actype=flight.actype local actype=tostring(flight.actype)
local holding=tostring(flight.holding) local holding=tostring(flight.holding)
local nunits=flight.nunits local nunits=flight.nunits or 1
-- Main info. -- Main info.
text=text..string.format("\n[%d] %s (%s*%d): ai=%s, timestamp=%s, fuel=%d, inzone=%s, holding=%s", text=text..string.format("\n[%d] %s (%s*%d): ai=%s, timestamp=%s, fuel=%d, inzone=%s, holding=%s",
@@ -700,11 +640,11 @@ function FLIGHTCONTROL:_PrintQueue(queue, name)
-- Elements info. -- Elements info.
for j,_element in pairs(flight.elements) do for j,_element in pairs(flight.elements) do
local element=_element --#FLIGHTCONTROL.FlightElement local element=_element --Ops.FlightGroup#FLIGHTGROUP.Element
local life=element.unit:GetLife() local life=element.unit:GetLife()
local life0=element.unit:GetLife0() local life0=element.unit:GetLife0()
text=text..string.format("\n (%d) %s (%s): ai=%s, parking=%s, recovered=%s, tookoff=%s, airborne=%s life=%.1f/%.1f", text=text..string.format("\n (%d) %s (%s): ai=%s, status=%s,, airborne=%s life=%.1f/%.1f",
j, element.onboard, element.unitname, tostring(element.ai), tostring(element.parking), tostring(element.recovered), tostring(element.tookoff), tostring(element.unit:InAir()), life, life0) j, tostring(element.modex), element.name, tostring(element.ai) ,tostring(element.status), tostring(element.unit:InAir()), life, life0)
end end
end end
end end
@@ -727,12 +667,13 @@ function FLIGHTCONTROL:_RemoveFlightFromQueue(queue, flight)
-- Check for name. -- Check for name.
if qflight.groupname==flight.groupname then if qflight.groupname==flight.groupname then
self:T(self.lid..string.format("Removing flight group %s from queue.", flight.groupname)) self:I(self.lid..string.format("Removing flight group %s from queue.", flight.groupname))
table.remove(queue, i) table.remove(queue, i)
return true, i return true, i
end end
end end
self:I(self.lid..string.format("Could NOT remove flight group %s from queue.", flight.groupname))
return false, nil return false, nil
end end
@@ -822,7 +763,7 @@ end
-- Flight and Element Functions -- Flight and Element Functions
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- Create a new flight group. Usually when a flight appears in the CCA. --- Create a new flight group.
-- @param #FLIGHTCONTROL self -- @param #FLIGHTCONTROL self
-- @param Wrapper.Group#GROUP group Aircraft group. -- @param Wrapper.Group#GROUP group Aircraft group.
-- @return Ops.FlightGroup#FLIGHTGROUP Flight group. -- @return Ops.FlightGroup#FLIGHTGROUP Flight group.
@@ -834,7 +775,20 @@ function FLIGHTCONTROL:_CreateFlightGroup(group)
end end
-- Debug info. -- Debug info.
self:T(self.lid..string.format("Creating new flight for group %s of aircraft type %s.", group:GetName(), group:GetTypeName())) self:I(self.lid..string.format("Creating new flight for group %s of aircraft type %s.", group:GetName(), group:GetTypeName()))
-- Get flightgroup from data base.
local flight=_DATABASE:GetFlightGroup(group:GetName())
-- If it does not exist yet, create one.
if not flight then
flight=FLIGHTGROUP:New(group:GetName())
flight:__Start(1)
end
flight:SetFlightControl(self)
--[[
-- New flight. -- New flight.
local flight={} --Ops.FlightGroup#FLIGHTGROUP local flight={} --Ops.FlightGroup#FLIGHTGROUP
@@ -887,6 +841,8 @@ function FLIGHTCONTROL:_CreateFlightGroup(group)
flight.onboard=self:_GetOnboardNumberPlayer(group) flight.onboard=self:_GetOnboardNumberPlayer(group)
end end
]]
-- Add to known flights. -- Add to known flights.
table.insert(self.flights, flight) table.insert(self.flights, flight)
@@ -958,24 +914,6 @@ function FLIGHTCONTROL:_GetFlightElement(unitname)
return nil, nil, nil return nil, nil, nil
end end
--- Remove element from flight.
-- @param #FLIGHTCONTROL self
-- @param #string unitname Name of the unit.
-- @return #boolean If true, element could be removed or nil otherwise.
function FLIGHTCONTROL:_RemoveFlightElement(unitname)
-- Get table index.
local element,idx, flight=self:_GetFlightElement(unitname)
if idx then
table.remove(flight.elements, idx)
return true
else
self:T("WARNING: Flight element could not be removed from flight group. Index=nil!")
return nil
end
end
--- Get parking spot of flight element. --- Get parking spot of flight element.
-- @param #FLIGHTCONTROL self -- @param #FLIGHTCONTROL self
-- @param Ops.FlightGroup#FLIGHTGROUP.Element element Element of flight group. -- @param Ops.FlightGroup#FLIGHTGROUP.Element element Element of flight group.
@@ -1040,12 +978,12 @@ function FLIGHTCONTROL:_CheckInbound()
local unit=_unit --Wrapper.Unit#UNIT local unit=_unit --Wrapper.Unit#UNIT
-- Necessary conditions to be met: -- Necessary conditions to be met:
local airborne=unit:IsAir() local aircraft=unit:IsAir()
local inzone=unit:IsInZone(self.zoneAirbase) local inzone=unit:IsInZone(self.zoneAirbase)
local friendly=self:GetCoalition()==unit:GetCoalition() local friendly=self:GetCoalition()==unit:GetCoalition()
-- Check if this an aircraft and that it is airborne and closing in. -- Check if this an aircraft and that it is inside the airbase zone and friendly.
if airborne and inzone and friendly then if aircraft and inzone and friendly then
local group=unit:GetGroup() local group=unit:GetGroup()
local groupname=group:GetName() local groupname=group:GetName()
@@ -1058,7 +996,7 @@ function FLIGHTCONTROL:_CheckInbound()
end end
end end
-- Find new flights that are inside CCA. -- Find new flights that are inside the airbase zone.
for groupname,_group in pairs(insideZone) do for groupname,_group in pairs(insideZone) do
local group=_group --Wrapper.Group#GROUP local group=_group --Wrapper.Group#GROUP
self:_CreateFlightGroup(group) self:_CreateFlightGroup(group)
@@ -1067,47 +1005,16 @@ function FLIGHTCONTROL:_CheckInbound()
for _,_flight in pairs(self.flights) do for _,_flight in pairs(self.flights) do
local flight=_flight --Ops.FlightGroup#FLIGHTGROUP local flight=_flight --Ops.FlightGroup#FLIGHTGROUP
local inzone=flight.group:IsCompletelyInZone(self.zoneAirbase) if flight and flight.destination and flight.destination:GetName()==self.airbasename then
if inzone and not flight.inzone then -- Send AI to orbit outside 10 NM zone and wait until the next Marshal stack is available.
flight.inzone=true
flight.dist0=flight.group:GetCoordinate():Get2DDistance(self:GetCoordinate())
end
-- Set currently in zone or not.
flight.inzone=inzone
end
for _,_flight in pairs(self.flights) do
local flight=_flight --Ops.FlightGroup#FLIGHTGROUP
--TODO: Check if aircraft has a landing waypoint for this airbase.
-- Get distance to carrier.
local dist=flight.group:GetCoordinate():Get2DDistance(self:GetCoordinate())
-- Close in distance. Is >0 if AC comes closer wrt to first detected distance d0.
local closein=flight.dist0-dist
-- TODO refine for current case.
-- Flight closed in.
if closein>UTILS.NMToMeters(5) and flight.group:IsAirborne(true) then
-- Debug info.
self:T3(self.lid..string.format("AI flight group %s closed in by %.1f NM", flight.groupname, UTILS.MetersToNM(closein)))
-- Send AI to orbit outside 10 NM zone and wait until the next Marshal stack is available.
if not (self:_InQueue(self.Qwaiting, flight.group) or self:_InQueue(self.Qlanding, flight.group)) then if not (self:_InQueue(self.Qwaiting, flight.group) or self:_InQueue(self.Qlanding, flight.group)) then
self:_WaitAI(flight, 1, true) self:_WaitAI(flight, 1, true)
end end
-- Break the loop to not have all flights at once! Spams the message screen.
break
end end
end end
end end
@@ -1124,6 +1031,17 @@ function FLIGHTCONTROL:_WaitAI(flight, stack, respawn)
-- Add AI flight to waiting queue. -- Add AI flight to waiting queue.
table.insert(self.Qwaiting, flight) table.insert(self.Qwaiting, flight)
-- Holding point.
local holding=self:_GetHoldingpoint(flight)
local altitude=holding.pos0.y
local angels=UTILS.MetersToFeet(altitude)/1000
flight:Hold(holding, altitude)
if true then
return
end
-- Flight group name. -- Flight group name.
local group=flight.group local group=flight.group
local groupname=flight.groupname local groupname=flight.groupname
@@ -1154,10 +1072,7 @@ function FLIGHTCONTROL:_WaitAI(flight, stack, respawn)
-- Task function when arriving at the holding zone. This will set flight.holding=true. -- Task function when arriving at the holding zone. This will set flight.holding=true.
local TaskHolding=flight.group:TaskFunction("FLIGHTCONTROL._ReachedHoldingZone", self, flight) local TaskHolding=flight.group:TaskFunction("FLIGHTCONTROL._ReachedHoldingZone", self, flight)
-- Holding point.
local holding=self:_GetHoldingpoint(flight)
local altitude=holding.pos0.y
local angels=UTILS.MetersToFeet(altitude)/1000
-- Set orbit task. -- Set orbit task.
local TaskOrbit=group:TaskOrbit(holding.pos0, altitude, speedOrbitMps, holding.pos1) local TaskOrbit=group:TaskOrbit(holding.pos0, altitude, speedOrbitMps, holding.pos1)
+286 -55
View File
@@ -40,6 +40,7 @@
-- @field #boolean fuelcriticalrtb RTB on critical fuel switch. -- @field #boolean fuelcriticalrtb RTB on critical fuel switch.
-- @field Ops.Squadron#SQUADRON squadron The squadron the flight group belongs to. -- @field Ops.Squadron#SQUADRON squadron The squadron the flight group belongs to.
-- @field Ops.FlightControl#FLIGHTCONTROL flightcontrol The flightcontrol handling this group. -- @field Ops.FlightControl#FLIGHTCONTROL flightcontrol The flightcontrol handling this group.
-- @field Core.UserFlag#USERFLAG flaghold Flag for holding.
-- @extends Core.Fsm#FSM -- @extends Core.Fsm#FSM
--- Be surprised! --- Be surprised!
@@ -81,6 +82,7 @@ FLIGHTGROUP = {
fuelcriticalrtb = false, fuelcriticalrtb = false,
squadron = nil, squadron = nil,
flightcontrol = nil, flightcontrol = nil,
flaghold = nil,
} }
@@ -90,7 +92,8 @@ FLIGHTGROUP = {
-- @field #string SPAWNED Element was spawned into the world. -- @field #string SPAWNED Element was spawned into the world.
-- @field #string PARKING Element is parking after spawned on ramp. -- @field #string PARKING Element is parking after spawned on ramp.
-- @field #string TAXIING Element is taxiing after engine startup. -- @field #string TAXIING Element is taxiing after engine startup.
-- @field #string AIRBORNE Element is airborne after take off. -- @field #string TAKEOFF Element took of after takeoff event.
-- @field #string AIRBORNE Element is airborne. Either after takeoff or after air start.
-- @field #string LANDED Element landed and is taxiing to its parking spot. -- @field #string LANDED Element landed and is taxiing to its parking spot.
-- @field #string ARRIVED Element arrived at its parking spot and shut down its engines. -- @field #string ARRIVED Element arrived at its parking spot and shut down its engines.
-- @field #string DEAD Element is dead after it crashed, pilot ejected or pilot dead events. -- @field #string DEAD Element is dead after it crashed, pilot ejected or pilot dead events.
@@ -99,6 +102,7 @@ FLIGHTGROUP.ElementStatus={
SPAWNED="spawned", SPAWNED="spawned",
PARKING="parking", PARKING="parking",
TAXIING="taxiing", TAXIING="taxiing",
TAKEOFF="takeoff",
AIRBORNE="airborne", AIRBORNE="airborne",
LANDED="landed", LANDED="landed",
ARRIVED="arrived", ARRIVED="arrived",
@@ -176,7 +180,7 @@ FLIGHTGROUP.TaskType={
--- FLIGHTGROUP class version. --- FLIGHTGROUP class version.
-- @field #string version -- @field #string version
FLIGHTGROUP.version="0.0.9" FLIGHTGROUP.version="0.1.0"
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO list -- TODO list
@@ -225,11 +229,11 @@ function FLIGHTGROUP:New(groupname)
-- Add FSM transitions. -- Add FSM transitions.
-- From State --> Event --> To State -- From State --> Event --> To State
self:AddTransition("Stopped", "Start", "Running") -- Start FSM. self:AddTransition("Stopped", "Start", "Running") -- Start FSM.
self:AddTransition("*", "FlightStatus", "*") -- FLIGHTGROUP status update. self:AddTransition("*", "FlightStatus", "*") -- FLIGHTGROUP status update.
self:AddTransition("*", "QueueUpdate", "*") -- Update task queue. self:AddTransition("*", "QueueUpdate", "*") -- Update task queue.
self:AddTransition("*", "DetectedUnit", "*") -- Add a newly detected unit to the detected units set. self:AddTransition("*", "DetectedUnit", "*") -- Add a newly detected unit to the detected units set.
@@ -260,6 +264,7 @@ function FLIGHTGROUP:New(groupname)
self:AddTransition("*", "ElementSpawned", "*") -- An element was spawned. self:AddTransition("*", "ElementSpawned", "*") -- An element was spawned.
self:AddTransition("*", "ElementParking", "*") -- An element was spawned. self:AddTransition("*", "ElementParking", "*") -- An element was spawned.
self:AddTransition("*", "ElementTaxiing", "*") -- An element spooled up the engines. self:AddTransition("*", "ElementTaxiing", "*") -- An element spooled up the engines.
self:AddTransition("*", "ElementTakeoff", "*") -- An element took off.
self:AddTransition("*", "ElementAirborne", "*") -- An element took off. self:AddTransition("*", "ElementAirborne", "*") -- An element took off.
self:AddTransition("*", "ElementLanded", "*") -- An element landed. self:AddTransition("*", "ElementLanded", "*") -- An element landed.
self:AddTransition("*", "ElementArrived", "*") -- An element arrived. self:AddTransition("*", "ElementArrived", "*") -- An element arrived.
@@ -270,6 +275,7 @@ function FLIGHTGROUP:New(groupname)
self:AddTransition("*", "FlightSpawned", "Spawned") -- The whole flight group was spawned. self:AddTransition("*", "FlightSpawned", "Spawned") -- The whole flight group was spawned.
self:AddTransition("*", "FlightParking", "Parking") -- The whole flight group is parking. self:AddTransition("*", "FlightParking", "Parking") -- The whole flight group is parking.
self:AddTransition("*", "FlightTaxiing", "Taxiing") -- The whole flight group is taxiing. self:AddTransition("*", "FlightTaxiing", "Taxiing") -- The whole flight group is taxiing.
self:AddTransition("*", "FlightTakeoff", "Airborne") -- The whole flight group is airborne.
self:AddTransition("*", "FlightAirborne", "Airborne") -- The whole flight group is airborne. self:AddTransition("*", "FlightAirborne", "Airborne") -- The whole flight group is airborne.
self:AddTransition("*", "FlightLanded", "Landed") -- The whole flight group has landed. self:AddTransition("*", "FlightLanded", "Landed") -- The whole flight group has landed.
self:AddTransition("*", "FlightArrived", "Arrived") -- The whole flight group has arrived. self:AddTransition("*", "FlightArrived", "Arrived") -- The whole flight group has arrived.
@@ -319,6 +325,9 @@ function FLIGHTGROUP:New(groupname)
self.taskcurrent=0 self.taskcurrent=0
self.taskcounter=0 self.taskcounter=0
self.flaghold=USERFLAG:New(string.format("%s_FlagHold", self.groupname))
self.flaghold:Set(0)
-- Add to data base. -- Add to data base.
_DATABASE:AddFlightGroup(self) _DATABASE:AddFlightGroup(self)
@@ -413,6 +422,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.squadron=squadron self.squadron=squadron
return self return self
end end
@@ -424,6 +434,23 @@ function FLIGHTGROUP:GetSquadron()
return self.squadron return self.squadron
end end
--- Set the FLIGHTCONTROL controlling this flight group.
-- @param #FLIGHTGROUP self
-- @param Ops.FlightControl#FLIGHTCONTROL flightcontrol The FLIGHTCONTROL object.
-- @return #FLIGHTGROUP self
function FLIGHTGROUP:SetFlightControl(flightcontrol)
self:I(self.sid..string.format("Setting FLIGHTCONTROL to airbase %s", flightcontrol.airbasename))
self.flightcontrol=flightcontrol
return self
end
--- Get the FLIGHTCONTROL controlling this flight group.
-- @param #FLIGHTGROUP self
-- @return Ops.FlightControl#FLIGHTCONTROL The FLIGHTCONTROL object.
function FLIGHTGROUP:GetFlightControl()
return self.flightcontrol
end
--- Set low fuel threshold. Triggers event "FuelLow" and calls event function "OnAfterFuelLow". --- Set low fuel threshold. Triggers event "FuelLow" and calls event function "OnAfterFuelLow".
-- @param #FLIGHTGROUP self -- @param #FLIGHTGROUP self
-- @param #number threshold Fuel threshold in percent. Default 25 %. -- @param #number threshold Fuel threshold in percent. Default 25 %.
@@ -608,7 +635,8 @@ function FLIGHTGROUP:onafterFlightStatus(From, Event, To)
self:_CheckDetectedUnits() self:_CheckDetectedUnits()
-- Short info. -- Short info.
local text=string.format("Flight status %s [%d/%d]. Task=%d/%d. Waypoint=%d/%d. Detected=%d", fsmstate, #self.elements, #self.elements, self.taskcurrent, #self.taskqueue, self.currentwp or 0, #self.waypoints or 0, self.detectedunits:Count()) 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 or 0, 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.sid..text)
-- Element status. -- Element status.
@@ -803,7 +831,7 @@ function FLIGHTGROUP:OnEventTakeOff(EventData)
if element then if element then
self:I(self.sid..string.format("EVENT: Element %s took off ==> airborne", element.name)) self:I(self.sid..string.format("EVENT: Element %s took off ==> airborne", element.name))
self:ElementAirborne(element) self:ElementTakeoff(element, EventData.Place)
end end
end end
@@ -833,7 +861,7 @@ function FLIGHTGROUP:OnEventLanding(EventData)
if element then if element then
self:I(self.sid..string.format("EVENT: Element %s landed at %s ==> landed", element.name, airbasename)) self:I(self.sid..string.format("EVENT: Element %s landed at %s ==> landed", element.name, airbasename))
self:ElementLanded(element, airbase) self:ElementLanded(element, airbase)
end end
end end
@@ -875,7 +903,7 @@ function FLIGHTGROUP:OnEventEngineShutdown(EventData)
else else
self:I(self.sid..string.format("Element %s shut down engines (bug is not alive) ==> dead", element.name)) self:I(self.sid..string.format("Element %s shut down engines (bug is not alive) ==> dead", element.name))
self:ElementDead(element) --self:ElementDead(element)
end end
@@ -959,6 +987,20 @@ function FLIGHTGROUP:onafterElementTaxiing(From, Event, To, Element)
self:_UpdateStatus(Element, FLIGHTGROUP.ElementStatus.TAXIING) self:_UpdateStatus(Element, FLIGHTGROUP.ElementStatus.TAXIING)
end end
--- On after "ElementTakeoff" event.
-- @param #FLIGHTGROUP self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
-- @param #FLIGHTGROUP.Element Element The flight group element.
-- @param Wrapper.Airbase#AIRBASE airbase The airbase if applicable or nil.
function FLIGHTGROUP:onafterElementTakeoff(From, Event, To, Element, airbase)
self:I(self.sid..string.format("Element airborne %s.", Element.name))
-- Set element status.
self:_UpdateStatus(Element, FLIGHTGROUP.ElementStatus.TAKEOFF, airbase)
end
--- On after "ElementAirborne" event. --- On after "ElementAirborne" event.
-- @param #FLIGHTGROUP self -- @param #FLIGHTGROUP self
-- @param #string From From state. -- @param #string From From state.
@@ -978,11 +1020,12 @@ end
-- @param #string Event Event. -- @param #string Event Event.
-- @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:onafterElementLanded(From, Event, To, Element) -- @param Wrapper.Airbase#AIRBASE airbase The airbase if applicable or nil.
function FLIGHTGROUP:onafterElementLanded(From, Event, To, Element, airbase)
self:I(self.sid..string.format("Element landed %s.", Element.name)) self:I(self.sid..string.format("Element landed %s.", Element.name))
-- Set element status. -- Set element status.
self:_UpdateStatus(Element, FLIGHTGROUP.ElementStatus.LANDED) self:_UpdateStatus(Element, FLIGHTGROUP.ElementStatus.LANDED, airbase)
end end
--- On after "ElementArrived" event. --- On after "ElementArrived" event.
@@ -998,6 +1041,19 @@ function FLIGHTGROUP:onafterElementArrived(From, Event, To, Element)
self:_UpdateStatus(Element, FLIGHTGROUP.ElementStatus.ARRIVED) self:_UpdateStatus(Element, FLIGHTGROUP.ElementStatus.ARRIVED)
end end
--- On after "ElementDead" event.
-- @param #FLIGHTGROUP self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
-- @param #FLIGHTGROUP.Element Element The flight group element.
function FLIGHTGROUP:onafterElementDead(From, Event, To, Element)
self:I(self.sid..string.format("Element dead %s.", Element.name))
-- Set element status.
self:_UpdateStatus(Element, FLIGHTGROUP.ElementStatus.DEAD)
end
--- On after "FlightSpawned" event. Sets the template, initializes the waypoints. --- On after "FlightSpawned" event. Sets the template, initializes the waypoints.
-- @param #FLIGHTGROUP self -- @param #FLIGHTGROUP self
@@ -1005,8 +1061,7 @@ end
-- @param #string From From state. -- @param #string From From state.
-- @param #string Event Event. -- @param #string Event Event.
-- @param #string To To state. -- @param #string To To state.
-- @param Wrapper.Group#GROUP Group The group object. function FLIGHTGROUP:onafterFlightSpawned(From, Event, To)
function FLIGHTGROUP:onafterFlightSpawned(From, Event, To, Group)
-- Get template of group. -- Get template of group.
self.template=self.group:GetTemplate() self.template=self.group:GetTemplate()
@@ -1014,8 +1069,48 @@ function FLIGHTGROUP:onafterFlightSpawned(From, Event, To, Group)
-- Init waypoints. -- Init waypoints.
self:_InitWaypoints() self:_InitWaypoints()
-- Update route.
self:_UpdateRoute(1)
-- Route flight group but now with passing waypoint tasks. -- Route flight group but now with passing waypoint tasks.
self.group:Route(self.waypoints) --self.group:Route(self.waypoints)
end
--- On after "FlightTaxiing" event.
-- @param #FLIGHTGROUP self
-- @param Wrapper.Group#GROUP Group Flight group.
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
function FLIGHTGROUP:onafterFlightTaxiing(From, Event, To)
self:I(self.sid..string.format("Flight is taxxing %s.", self.groupname))
-- TODO: need a better check for the airbase.
local airbase=self.group:GetCoordinate():GetClosestAirbase(nil, self.group:GetCoalition())
if self.flightcontrol and airbase and self.flightcontrol.airbasename==airbase:GetName() then
self.flightcontrol:_AddFlightToTakeoffQueue(self)
end
end
--- On after "FlightTakeoff" event.
-- @param #FLIGHTGROUP self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
-- @param Wrapper.Airbase#AIRBASE airbase The airbase the flight landed.
function FLIGHTGROUP:onafterFlightTakeoff(From, Event, To, airbase)
self:I(self.sid..string.format("Flight takeoff %s at %s.", self.groupname, airbase and airbase:GetName() or "unknown airbase"))
if self.flightcontrol and airbase and self.flightcontrol.airbasename==airbase:GetName() then
self.flightcontrol:_RemoveFlightFromQueue(self.flightcontrol.Qtakeoff, self)
end
-- Update
self:FlightAirborne(airbase)
--self:__QueueUpdate(-1)
end end
--- On after "FlightAirborne" event. --- On after "FlightAirborne" event.
@@ -1025,7 +1120,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:onafterFlightAirborne(From, Event, To, airbase) function FLIGHTGROUP:onafterFlightAirborne(From, Event, To, airbase)
self:I(self.sid..string.format("Flight airborne %s.", self.groupname)) self:I(self.sid..string.format("Flight airborne %s at %s.", self.groupname,airbase and airbase:GetName() or "unknown airbase"))
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.Qtakeoff, self) self.flightcontrol:_RemoveFlightFromQueue(self.flightcontrol.Qtakeoff, self)
@@ -1043,7 +1138,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:onafterFlightLanded(From, Event, To, airbase) function FLIGHTGROUP:onafterFlightLanded(From, Event, To, airbase)
self:I(self.sid..string.format("Flight landed %s.", self.groupname)) self:I(self.sid..string.format("Flight landed %s at %s.", self.groupname, airbase and airbase:GetName() or "unknown airbase"))
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) self.flightcontrol:_RemoveFlightFromQueue(self.flightcontrol.Qlanding, self)
@@ -1158,21 +1253,88 @@ end
-- @param #string From From state. -- @param #string From From state.
-- @param #string Event Event. -- @param #string Event Event.
-- @param #string To To state. -- @param #string To To state.
-- @param Core.Point#COORDINATE Coord Coordinate where to orbit. -- @param Wrapper.Airbase#AIRBASE airbase The airbase to hold at.
-- @param #number Altitude Altitude in meters. -- @param #number SpeedTo Speed used for travelling from current position to holding point in knots.
-- @param #number Speed Speed in km/h. -- @param #number SpeedHold Holding speed in knots.
function FLIGHTGROUP:onafterHold(From, Event, To, Coord, Altitude, Speed) function FLIGHTGROUP:onafterHold(From, Event, To, airbase, SpeedTo, SpeedHold)
-- Debug message. -- Debug message.
local text=string.format("Flight group set to hold at altitude %d m and speed %.1f km/h", Altitude, Speed) 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.sid..text)
self.group:ClearTasks() self.group:ClearTasks()
local Coord=airbase:GetZone():GetRandomCoordinate():SetAltitude(UTILS.FeetToMeters(6000))
if self.flightcontrol then
Coord=self.flightcontrol:_GetHoldingpoint(self)
end
local TaskOrbit=self.group:TaskOrbit(Coord, Altitude, UTILS.KmphToMps(Speed)) self.flaghold:Set(333)
local TaskArrived=self.group:TaskFunction("FLIGHTGROUP._ReachedHolding", self)
self.group:SetTask(TaskOrbit)
local wp=airbase:GetCoordinate():WaypointAir(nil , COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.FlyoverPoint,SpeedTo, true , nil, {}, "Holding Point")
local Task2Hold=self.group:TaskRoute(wp)
local TaskOrbit=self.group:TaskOrbit(Coord)
local TaskStop=self.group:TaskCondition(nil, self.flaghold.UserFlagName, 1)
--local TaskStop=self.group:TaskCondition(nil, nil, nil, nil, 30*60)
local wp=airbase:GetCoordinate():WaypointAirLanding(SpeedHold, airbase, {}, "Landing")
local TaskLand=self.group:TaskRoute(wp)
local TaskControlled=self.group:TaskControlled(TaskOrbit, TaskStop)
local TaskCombo=self.group:TaskCombo({Task2Hold, TaskArrived, TaskControlled, TaskLand})
local TaskCombo=self.group:TaskCombo({Task2Hold, TaskArrived, TaskLand})
--self.group:SetTask(TaskCombo)
local coordAB=airbase:GetCoordinate()
local wp={}
wp[1]=self.group:GetCoordinate():WaypointAir(nil, COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.FlyoverPoint,SpeedTo, true , nil, {}, "Current Pos")
wp[2]=coordAB:WaypointAir(nil, COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.FlyoverPoint,SpeedTo, true , nil, {TaskArrived, TaskControlled}, "Holding Point")
wp[3]=coordAB:Translate(50000, 270):WaypointAir(nil, COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.FlyoverPoint,SpeedTo, true , nil, {}, "Test 50 km")
wp[4]=coordAB:WaypointAirLanding(SpeedHold, airbase, {}, "Landing")
local respawn=true
if respawn then
-- Get group template.
local Template=self.group:GetTemplate()
-- Set route points.
Template.route.points=wp
MESSAGE:New("Respawning group"):ToAll()
--Respawn the group.
self.group=self.group:Respawn(Template, nil)
end
self.group:Route(wp, 0.1)
--self:RouteRTB(RTBAirbase,Speed,Altitude,TaskOverhead)
end
--- On after TaskPause event.
-- @param Wrapper.Group#GROUP group
-- @param #FLIGHTGROUP flightgroup
function FLIGHTGROUP._ReachedHolding(group, flightgroup)
env.info(string.format("FF group %s reached holding point", group:GetName()))
group:GetCoordinate():MarkToAll("Holding Point Reached")
--TODO: add flight to FC waiting queue.
flightgroup.flaghold:Set(666)
end end
--- On after TaskExecute event. --- On after TaskExecute event.
@@ -1187,6 +1349,11 @@ function FLIGHTGROUP:onafterTaskExecute(From, Event, To, Task)
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.sid..text)
-- Cancel current task if there is any.
if self.taskcurrent>0 then
self:TaskCancel()
end
-- Set current task. -- Set current task.
self.taskcurrent=Task.id self.taskcurrent=Task.id
@@ -1300,20 +1467,6 @@ function FLIGHTGROUP:onafterDetectedUnit(From, Event, To, Unit)
self.detectedunits:AddUnit(Unit) self.detectedunits:AddUnit(Unit)
end end
--- On after "ElementDead" event.
-- @param #FLIGHTGROUP self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
-- @param #FLIGHTGROUP.Element Element The flight group element.
function FLIGHTGROUP:onafterElementDead(From, Event, To, Element)
self:I(self.sid..string.format("Element dead %s.", Element.name))
-- Set element status.
self:_UpdateStatus(Element, FLIGHTGROUP.ElementStatus.DEAD)
end
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Task functions -- Task functions
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
@@ -1428,7 +1581,8 @@ end
-- @param Wrapper.Airbase#AIRBASE RTBAirbase -- @param Wrapper.Airbase#AIRBASE RTBAirbase
-- @param #number Speed Speed in km/h. -- @param #number Speed Speed in km/h.
-- @param #number Altitude Altitude in meters. -- @param #number Altitude Altitude in meters.
function FLIGHTGROUP:RouteRTB(RTBAirbase, Speed, Altitude) -- @param #table TaskOverhead Task to execute when reaching overhead waypoint.
function FLIGHTGROUP:RouteRTB(RTBAirbase, Speed, Altitude, TaskOverhead)
-- If speed is not given take 80% of max speed. -- If speed is not given take 80% of max speed.
local Speed=Speed or self.group:GetSpeedMax()*0.8 local Speed=Speed or self.group:GetSpeedMax()*0.8
@@ -1444,7 +1598,7 @@ function FLIGHTGROUP:RouteRTB(RTBAirbase, Speed, Altitude)
local PointFrom=coord:WaypointAirTurningPoint(nil, Speed, {}, "Current") local PointFrom=coord:WaypointAirTurningPoint(nil, Speed, {}, "Current")
-- Overhead pass. -- Overhead pass.
local PointOverhead=RTBAirbase:GetCoordinate():SetAltitude(Altitude or coord.y):WaypointAirTurningPoint(nil, Speed, {}, "Overhead Pass") local PointOverhead=RTBAirbase:GetCoordinate():SetAltitude(Altitude or coord.y):WaypointAirTurningPoint(nil, Speed, TaskOverhead, "Overhead Pass")
-- Landing waypoint. -- Landing waypoint.
local PointLanding=RTBAirbase:GetCoordinate():SetAltitude(20):WaypointAirLanding(Speed, RTBAirbase, {}, "Landing") local PointLanding=RTBAirbase:GetCoordinate():SetAltitude(20):WaypointAirLanding(Speed, RTBAirbase, {}, "Landing")
@@ -1458,12 +1612,29 @@ function FLIGHTGROUP:RouteRTB(RTBAirbase, Speed, Altitude)
-- Set route points. -- Set route points.
Template.route.points=Points Template.route.points=Points
-- Respawn the group. -- Respawn the group.
self.group=self.group:Respawn(Template, true) --self.group=self.group:Respawn(Template, true)
local TaskRTB=self.group:TaskRoute(Points)
--[[
self.taskcounter=self.taskcounter+1
local task={} --#FLIGHTGROUP.Task
task.dcstask=TaskRTB
task.description="RTB"
task.id=self.taskcounter
task.type=FLIGHTGROUP.TaskType.SCHEDULED
task.prio=0
task.time=timer.getAbsTime()
]]
self:AddTask("RTB", TaskRTB, 0)
self:TaskCancel()
-- Route the group or this will not work. -- Route the group or this will not work.
self.group:Route(Points, 1) --self.group:Route(Points, 1)
end end
@@ -1568,6 +1739,33 @@ function FLIGHTGROUP:GetElementByName(unitname)
return nil return nil
end end
--- Check if a unit is and element of the flightgroup.
-- @param #FLIGHTGROUP self
-- @return Wrapper.Airbase#AIRBASE Final destination airbase or #nil.
function FLIGHTGROUP:GetHomebaseFromWaypoints()
local wp=self:GetWaypoint(1)
if wp then
if wp and wp.action and wp.action==COORDINATE.WaypointAction.Landing then
-- Get airbase ID depending on airbase category.
local airbaseID=wp.airdromeId or wp.helipadId
local airbase=AIRBASE:FindByID(airbaseID)
return airbase
end
--TODO: Handle case where e.g. only one WP but that is not landing.
--TODO: Probably other cases need to be taken care of.
end
return nil
end
--- Check if a unit is and element of the flightgroup. --- Check if a unit is and element of the flightgroup.
-- @param #FLIGHTGROUP self -- @param #FLIGHTGROUP self
-- @return Wrapper.Airbase#AIRBASE Final destination airbase or #nil. -- @return Wrapper.Airbase#AIRBASE Final destination airbase or #nil.
@@ -1683,9 +1881,20 @@ function FLIGHTGROUP:_UpdateRoute(n)
table.insert(wp, self.waypoints[i]) table.insert(wp, self.waypoints[i])
end end
-- Get destination airbase from waypoints.
self.homebase=self:GetHomebaseFromWaypoints() or self.homebase
-- Get destination airbase from waypoints. -- Get destination airbase from waypoints.
self.destination=self:GetDestinationFromWaypoints() or self.destination self.destination=self:GetDestinationFromWaypoints() or self.destination
if self.destination and #wp>0 then
local wpoverhead=self.destination:GetCoordinate():WaypointAir(nil, COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.FlyoverPoint, 500, false, nil, {}, "Destination Overhead")
self:I(self.sid..string.format("Adding overhead waypoint as #%d", #wp))
table.insert(wp, #wp, wpoverhead)
end
self:I(self.sid..string.format("Updating route: #WP=%d homebase=%s destination=%s", #wp, self.homebase and self.homebase:GetName() or "unknown", self.destination and self.destination:GetName() or "unknown"))
if #wp>0 then if #wp>0 then
-- Route group to all defined waypoints remaining. -- Route group to all defined waypoints remaining.
@@ -1912,7 +2121,7 @@ function FLIGHTGROUP:_AllSimilarStatus(status)
return false return false
end end
elseif status==FLIGHTGROUP.ElementStatus.AIRBORNE then elseif status==FLIGHTGROUP.ElementStatus.TAKEOFF then
-- Element AIRBORNE: Check that the other are not stil SPAWNED, PARKING or TAXIING -- Element AIRBORNE: Check that the other are not stil SPAWNED, PARKING or TAXIING
if element.status~=status and if element.status~=status and
@@ -1922,6 +2131,17 @@ function FLIGHTGROUP:_AllSimilarStatus(status)
return false return false
end end
elseif status==FLIGHTGROUP.ElementStatus.AIRBORNE then
-- Element AIRBORNE: Check that the other are not stil SPAWNED, PARKING or TAXIING
if element.status~=status and
element.status==FLIGHTGROUP.ElementStatus.SPAWNED or
element.status==FLIGHTGROUP.ElementStatus.PARKING or
element.status==FLIGHTGROUP.ElementStatus.TAXIING or
element.status==FLIGHTGROUP.ElementStatus.TAKEOFF then
return false
end
elseif status==FLIGHTGROUP.ElementStatus.LANDED then elseif status==FLIGHTGROUP.ElementStatus.LANDED then
-- Element LANDED: check that the others are not stil AIRBORNE -- Element LANDED: check that the others are not stil AIRBORNE
@@ -1959,7 +2179,8 @@ end
-- @param #FLIGHTGROUP self -- @param #FLIGHTGROUP self
-- @param #FLIGHTGROUP.Element element Element. -- @param #FLIGHTGROUP.Element element Element.
-- @param #string newstatus New status of element -- @param #string newstatus New status of element
function FLIGHTGROUP:_UpdateStatus(element, newstatus) -- @param Wrapper.Airbase#AIRBASE airbase Airbase if applicable.
function FLIGHTGROUP:_UpdateStatus(element, newstatus, airbase)
-- Old status. -- Old status.
local oldstatus=element.status local oldstatus=element.status
@@ -1975,7 +2196,7 @@ function FLIGHTGROUP:_UpdateStatus(element, newstatus)
--- ---
if self:_AllSimilarStatus(newstatus) then if self:_AllSimilarStatus(newstatus) then
self:FlightSpawned(group) self:FlightSpawned()
end end
--[[ --[[
@@ -1992,7 +2213,7 @@ function FLIGHTGROUP:_UpdateStatus(element, newstatus)
--- ---
if self:_AllSimilarStatus(newstatus) then if self:_AllSimilarStatus(newstatus) then
self:FlightParking(group) self:FlightParking()
end end
elseif newstatus==FLIGHTGROUP.ElementStatus.TAXIING then elseif newstatus==FLIGHTGROUP.ElementStatus.TAXIING then
@@ -2001,7 +2222,17 @@ function FLIGHTGROUP:_UpdateStatus(element, newstatus)
--- ---
if self:_AllSimilarStatus(newstatus) then if self:_AllSimilarStatus(newstatus) then
self:FlightTaxiing(group) self:FlightTaxiing()
end
elseif newstatus==FLIGHTGROUP.ElementStatus.TAKEOFF then
---
-- TAKEOFF
---
if self:_AllSimilarStatus(newstatus) then
self:FlightTakeoff(airbase)
--TODO: also trigger Airborne() ?
end end
elseif newstatus==FLIGHTGROUP.ElementStatus.AIRBORNE then elseif newstatus==FLIGHTGROUP.ElementStatus.AIRBORNE then
@@ -2012,14 +2243,14 @@ function FLIGHTGROUP:_UpdateStatus(element, newstatus)
if self:_AllSimilarStatus(newstatus) then if self:_AllSimilarStatus(newstatus) then
if self:IsTaxiing() then if self:IsTaxiing() then
self:FlightAirborne(group) self:FlightAirborne()
elseif self:IsParking() then elseif self:IsParking() then
--self:FlightTaxiing(group) --self:FlightTaxiing(group)
self:FlightAirborne(group) self:FlightAirborne()
elseif self:IsSpawned() then elseif self:IsSpawned() then
--self:FlightParking(group) --self:FlightParking(group)
--self:FlightTaxiing(group) --self:FlightTaxiing(group)
self:FlightAirborne(group) self:FlightAirborne()
end end
end end
@@ -2041,10 +2272,10 @@ function FLIGHTGROUP:_UpdateStatus(element, newstatus)
if self:_AllSimilarStatus(newstatus) then if self:_AllSimilarStatus(newstatus) then
if self:IsLanded() then if self:IsLanded() then
self:FlightArrived(group) self:FlightArrived()
elseif self:IsAirborne() then elseif self:IsAirborne() then
self:FlightLanded(group) self:FlightLanded()
self:FlightArrived(group) self:FlightArrived()
end end
end end
@@ -2055,7 +2286,7 @@ function FLIGHTGROUP:_UpdateStatus(element, newstatus)
--- ---
if self:_AllSimilarStatus(newstatus) then if self:_AllSimilarStatus(newstatus) then
self:FlightDead(group) self:FlightDead()
end end
end end
+1 -1
View File
@@ -433,7 +433,7 @@ UTILS.tostringLL = function( lat, lon, acc, DMS)
secFrmtStr = '%02d' secFrmtStr = '%02d'
else else
local width = 3 + acc -- 01.310 - that's a width of 6, for example. Acc is limited to 2 for DMS! local width = 3 + acc -- 01.310 - that's a width of 6, for example. Acc is limited to 2 for DMS!
secFrmtStr = '%0' .. width .. '.' .. math.min(acc, 2) .. 'f' secFrmtStr = '%0' .. width .. '.' .. acc .. 'f'
end end
-- 024° 23' 12"N or 024° 23' 12.03"N -- 024° 23' 12"N or 024° 23' 12.03"N
@@ -442,12 +442,12 @@ end
--- Return a condition section for a controlled task. --- Return a condition section for a controlled task.
-- @param #CONTROLLABLE self -- @param #CONTROLLABLE self
-- @param DCS#Time time -- @param DCS#Time time DCS mission time.
-- @param #string userFlag -- @param #string userFlag Name of the user flag.
-- @param #boolean userFlagValue -- @param #boolean userFlagValue User flag value *true* or *false*. Could also be numeric, i.e. either 0=*false* or 1=*true*. Other numeric values don't work!
-- @param #string condition -- @param #string condition Lua string.
-- @param DCS#Time duration -- @param DCS#Time duration Duration in seconds.
-- @param #number lastWayPoint -- @param #number lastWayPoint Last waypoint.
-- return DCS#Task -- return DCS#Task
function CONTROLLABLE:TaskCondition( time, userFlag, userFlagValue, condition, duration, lastWayPoint ) function CONTROLLABLE:TaskCondition( time, userFlag, userFlagValue, condition, duration, lastWayPoint )
self:F2( { time, userFlag, userFlagValue, condition, duration, lastWayPoint } ) self:F2( { time, userFlag, userFlagValue, condition, duration, lastWayPoint } )
@@ -1079,8 +1079,8 @@ end
--- (AIR) Orbit at a position with at a given altitude and speed. Optionally, a race track pattern can be specified. --- (AIR) Orbit at a position with at a given altitude and speed. Optionally, a race track pattern can be specified.
-- @param #CONTROLLABLE self -- @param #CONTROLLABLE self
-- @param Core.Point#COORDINATE Coord Coordinate at which the CONTROLLABLE orbits. -- @param Core.Point#COORDINATE Coord Coordinate at which the CONTROLLABLE orbits.
-- @param #number Altitude Altitude in meters of the orbit pattern. -- @param #number Altitude Altitude in meters of the orbit pattern. Default y component of Coord.
-- @param #number Speed Speed [m/s] flying the orbit pattern. -- @param #number Speed Speed [m/s] flying the orbit pattern. Default 250 knots.
-- @param Core.Point#COORDINATE CoordRaceTrack (Optional) If this coordinate is specified, the CONTROLLABLE will fly a race-track pattern using this and the initial coordinate. -- @param Core.Point#COORDINATE CoordRaceTrack (Optional) If this coordinate is specified, the CONTROLLABLE will fly a race-track pattern using this and the initial coordinate.
-- @return #CONTROLLABLE self -- @return #CONTROLLABLE self
function CONTROLLABLE:TaskOrbit(Coord, Altitude, Speed, CoordRaceTrack) function CONTROLLABLE:TaskOrbit(Coord, Altitude, Speed, CoordRaceTrack)
@@ -1100,8 +1100,8 @@ function CONTROLLABLE:TaskOrbit(Coord, Altitude, Speed, CoordRaceTrack)
pattern = Pattern, pattern = Pattern,
point = P1, point = P1,
point2 = P2, point2 = P2,
speed = Speed, speed = Speed or UTILS.KnotsToMps(250),
altitude = Altitude, altitude = Altitude or Coord.y,
} }
} }
+25 -2
View File
@@ -1683,7 +1683,7 @@ function GROUP:Respawn( Template, Reset )
end end
end end
else -- Reset=false or nil elseif Reset==false then -- Reset=false or nil
-- Loop over template units. -- Loop over template units.
for UnitID, TemplateUnitData in pairs( Template.units ) do for UnitID, TemplateUnitData in pairs( Template.units ) do
@@ -1725,7 +1725,30 @@ function GROUP:Respawn( Template, Reset )
self:F( { UnitID, Template.units[UnitID], Template.units[UnitID] } ) self:F( { UnitID, Template.units[UnitID], Template.units[UnitID] } )
end end
end else
local units=self:GetUnits()
-- Loop over template units.
for UnitID, Unit in pairs(Template.units) do
for _,_unit in pairs(units) do
local unit=_unit --Wrapper.Unit#UNIT
if unit:GetName()==Unit.name then
local coord=unit:GetCoordinate()
local heading=unit:GetHeading()
Unit.x=coord.x
Unit.z=coord.y
Unit.alt=coord.alt
Unit.heading=math.rad(heading)
Unit.psi=-Unit.heading
end
end
end
end
end end