From eb14fdc84bdb49d41828178d2708566c89a2873a Mon Sep 17 00:00:00 2001 From: Frank Date: Wed, 4 Sep 2019 16:57:01 +0200 Subject: [PATCH] Ops --- Moose Development/Moose/Core/Database.lua | 34 ++++ Moose Development/Moose/Core/Settings.lua | 97 +++++++---- Moose Development/Moose/Functional/RAT2.lua | 1 - Moose Development/Moose/Ops/FlightControl.lua | 18 +- Moose Development/Moose/Ops/FlightGroup.lua | 159 ++++++++++++++---- 5 files changed, 238 insertions(+), 71 deletions(-) diff --git a/Moose Development/Moose/Core/Database.lua b/Moose Development/Moose/Core/Database.lua index 312f94072..a5d5246de 100644 --- a/Moose Development/Moose/Core/Database.lua +++ b/Moose Development/Moose/Core/Database.lua @@ -81,6 +81,9 @@ DATABASE = { HITS = {}, DESTROYS = {}, ZONES = {}, + WAREHOUSES = {}, + FLIGHTGROUPS = {}, + FLIGHTCONTROLS = {}, } local _DATABASECoalition = @@ -1197,6 +1200,37 @@ end +--- Add a flight group to the data base. +-- @param #DATABASE self +-- @param Ops.FlightGroup#FLIGHTGROUP flightgroup +function DATABASE:AddFlightGroup(flightgroup) + self:F2( { flightgroup } ) + self.FLIGHTGROUPS[flightgroup.groupname]=flightgroup +end + +--- Get a flight group from the data base. +-- @param #DATABASE self +-- @param #string groupname Group name of the flight group. +-- @return Ops.FlightGroup#FLIGHTGROUP Flight group object. +function DATABASE:GetFlightGroup(groupname) + return self.FLIGHTGROUPS[groupname] +end + +--- Add a flight control to the data base. +-- @param #DATABASE self +-- @param Ops.FlightControl#FLIGHTCONTROL flightcontrol +function DATABASE:AddFlightControl(flightcontrol) + self:F2( { flightcontrol } ) + self.FLIGHTCONTROLS[flightcontrol.airbasename]=flightcontrol +end + +--- Get a flight control object from the data base. +-- @param #DATABASE self +-- @param #string airbasename Name of the associated airbase. +-- @return Ops.FlightControl#FLIGHTCONTROL The FLIGHTCONTROL object.s +function DATABASE:GetFlightControl(airbasename) + return self.FLIGHTCONTROLS[airbasename] +end --- @param #DATABASE self function DATABASE:_RegisterTemplates() diff --git a/Moose Development/Moose/Core/Settings.lua b/Moose Development/Moose/Core/Settings.lua index b68eaaeaa..efb789847 100644 --- a/Moose Development/Moose/Core/Settings.lua +++ b/Moose Development/Moose/Core/Settings.lua @@ -201,7 +201,7 @@ SETTINGS = { ClassName = "SETTINGS", ShowPlayerMenu = true, MenuShort = false, - staticmenu = true, + MenuStatic = true, } @@ -696,69 +696,106 @@ do -- SETTINGS local PlayerMenu = MENU_GROUP:New( PlayerGroup, 'Settings "' .. PlayerName .. '"' ) self.PlayerMenu = PlayerMenu - - local A2GCoordinateMenu = MENU_GROUP:New( PlayerGroup, "A2G Coordinate System", PlayerMenu ) + + ------ + -- A2G Coordinate System + ------ + + local text="A2G Coordinate System" + if self.MenuShort then + text="A2G Coordinates" + end + local A2GCoordinateMenu = MENU_GROUP:New( PlayerGroup, text, PlayerMenu ) - if not self:IsA2G_LL_DMS() or self.staticmenu then - MENU_GROUP_COMMAND:New( PlayerGroup, "Lat/Lon Degree Min Sec (LL DMS)", A2GCoordinateMenu, self.MenuGroupA2GSystem, self, PlayerUnit, PlayerGroup, PlayerName, "LL DMS" ) + if not self:IsA2G_LL_DMS() or self.MenuStatic then + local text="Lat/Lon Degree Min Sec (LL DMS)" + if self.MenuShort then + text="LL DMS" + end + MENU_GROUP_COMMAND:New( PlayerGroup, text, A2GCoordinateMenu, self.MenuGroupA2GSystem, self, PlayerUnit, PlayerGroup, PlayerName, "LL DMS" ) end - if not self:IsA2G_LL_DDM() or self.staticmenu then - MENU_GROUP_COMMAND:New( PlayerGroup, "Lat/Lon Degree Dec Min (LL DDM)", A2GCoordinateMenu, self.MenuGroupA2GSystem, self, PlayerUnit, PlayerGroup, PlayerName, "LL DDM" ) + if not self:IsA2G_LL_DDM() or self.MenuStatic then + local text="Lat/Lon Degree Dec Min (LL DDM)" + if self.MenuShort then + text="LL DDM" + end + MENU_GROUP_COMMAND:New( PlayerGroup, text, A2GCoordinateMenu, self.MenuGroupA2GSystem, self, PlayerUnit, PlayerGroup, PlayerName, "LL DDM" ) end - if self:IsA2G_LL_DDM() or self.staticmenu then - MENU_GROUP_COMMAND:New( PlayerGroup, "LL DDM Accuracy 1", A2GCoordinateMenu, self.MenuGroupLL_DDM_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 1 ) - MENU_GROUP_COMMAND:New( PlayerGroup, "LL DDM Accuracy 2", A2GCoordinateMenu, self.MenuGroupLL_DDM_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 2 ) - MENU_GROUP_COMMAND:New( PlayerGroup, "LL DDM Accuracy 3", A2GCoordinateMenu, self.MenuGroupLL_DDM_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 3 ) + if self:IsA2G_LL_DDM() or self.MenuStatic then + local submenu=A2GCoordinateMenu + if self.MenuStatic then + submenu = MENU_GROUP:New( PlayerGroup, "A2G LL DDM Accuracy", A2GCoordinateMenu ) + end + MENU_GROUP_COMMAND:New( PlayerGroup, "LL DDM Accuracy 1", submenu, self.MenuGroupLL_DDM_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 1 ) + MENU_GROUP_COMMAND:New( PlayerGroup, "LL DDM Accuracy 2", submenu, self.MenuGroupLL_DDM_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 2 ) + MENU_GROUP_COMMAND:New( PlayerGroup, "LL DDM Accuracy 3", submenu, self.MenuGroupLL_DDM_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 3 ) end - if not self:IsA2G_BR() or self.staticmenu then - MENU_GROUP_COMMAND:New( PlayerGroup, "Bearing, Range (BR)", A2GCoordinateMenu, self.MenuGroupA2GSystem, self, PlayerUnit, PlayerGroup, PlayerName, "BR" ) + if not self:IsA2G_BR() or self.MenuStatic then + local text="Bearing, Range (BR)" + if self.MenuShort then + text="BR" + end + MENU_GROUP_COMMAND:New( PlayerGroup, text, A2GCoordinateMenu, self.MenuGroupA2GSystem, self, PlayerUnit, PlayerGroup, PlayerName, "BR" ) end - if not self:IsA2G_MGRS() or self.staticmenu then + if not self:IsA2G_MGRS() or self.MenuStatic then MENU_GROUP_COMMAND:New( PlayerGroup, "Military Grid (MGRS)", A2GCoordinateMenu, self.MenuGroupA2GSystem, self, PlayerUnit, PlayerGroup, PlayerName, "MGRS" ) end - if self:IsA2G_MGRS() or self.staticmenu then - MENU_GROUP_COMMAND:New( PlayerGroup, "MGRS Accuracy 1", A2GCoordinateMenu, self.MenuGroupMGRS_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 1 ) - MENU_GROUP_COMMAND:New( PlayerGroup, "MGRS Accuracy 2", A2GCoordinateMenu, self.MenuGroupMGRS_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 2 ) - MENU_GROUP_COMMAND:New( PlayerGroup, "MGRS Accuracy 3", A2GCoordinateMenu, self.MenuGroupMGRS_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 3 ) - MENU_GROUP_COMMAND:New( PlayerGroup, "MGRS Accuracy 4", A2GCoordinateMenu, self.MenuGroupMGRS_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 4 ) - MENU_GROUP_COMMAND:New( PlayerGroup, "MGRS Accuracy 5", A2GCoordinateMenu, self.MenuGroupMGRS_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 5 ) + if self:IsA2G_MGRS() or self.MenuStatic then + local submenu=A2GCoordinateMenu + if self.MenuStatic then + submenu = MENU_GROUP:New( PlayerGroup, "A2G MGRS Accuracy", A2GCoordinateMenu ) + end + MENU_GROUP_COMMAND:New( PlayerGroup, "MGRS Accuracy 1", submenu, self.MenuGroupMGRS_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 1 ) + MENU_GROUP_COMMAND:New( PlayerGroup, "MGRS Accuracy 2", submenu, self.MenuGroupMGRS_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 2 ) + MENU_GROUP_COMMAND:New( PlayerGroup, "MGRS Accuracy 3", submenu, self.MenuGroupMGRS_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 3 ) + MENU_GROUP_COMMAND:New( PlayerGroup, "MGRS Accuracy 4", submenu, self.MenuGroupMGRS_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 4 ) + MENU_GROUP_COMMAND:New( PlayerGroup, "MGRS Accuracy 5", submenu, self.MenuGroupMGRS_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 5 ) end - local A2ACoordinateMenu = MENU_GROUP:New( PlayerGroup, "A2A Coordinate System", PlayerMenu ) + ------ + -- A2A Coordinates Menu + ------ + + -- Submenu. + local text="A2A Coordinate System" + if self.MenuShort then + text="A2A Coordinates" + end + local A2ACoordinateMenu = MENU_GROUP:New( PlayerGroup, text, PlayerMenu ) - if not self:IsA2A_LL_DMS() or self.staticmenu then + if not self:IsA2A_LL_DMS() or self.MenuStatic then MENU_GROUP_COMMAND:New( PlayerGroup, "Lat/Lon Degree Min Sec (LL DMS)", A2GCoordinateMenu, self.MenuGroupA2GSystem, self, PlayerUnit, PlayerGroup, PlayerName, "LL DMS" ) end - if not self:IsA2A_LL_DDM() or self.staticmenu then + if not self:IsA2A_LL_DDM() or self.MenuStatic then MENU_GROUP_COMMAND:New( PlayerGroup, "Lat/Lon Degree Dec Min (LL DDM)", A2GCoordinateMenu, self.MenuGroupA2GSystem, self, PlayerUnit, PlayerGroup, PlayerName, "LL DDM" ) end - if self:IsA2A_LL_DDM() or self.staticmenu then + if self:IsA2A_LL_DDM() or self.MenuStatic then MENU_GROUP_COMMAND:New( PlayerGroup, "LL DDM Accuracy 1", A2GCoordinateMenu, self.MenuGroupLL_DDM_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 1 ) MENU_GROUP_COMMAND:New( PlayerGroup, "LL DDM Accuracy 2", A2GCoordinateMenu, self.MenuGroupLL_DDM_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 2 ) MENU_GROUP_COMMAND:New( PlayerGroup, "LL DDM Accuracy 3", A2GCoordinateMenu, self.MenuGroupLL_DDM_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 3 ) end - if not self:IsA2A_BULLS() or self.staticmenu then + if not self:IsA2A_BULLS() or self.MenuStatic then MENU_GROUP_COMMAND:New( PlayerGroup, "Bullseye (BULLS)", A2ACoordinateMenu, self.MenuGroupA2ASystem, self, PlayerUnit, PlayerGroup, PlayerName, "BULLS" ) end - if not self:IsA2A_BRAA() or self.staticmenu then + if not self:IsA2A_BRAA() or self.MenuStatic then MENU_GROUP_COMMAND:New( PlayerGroup, "Bearing Range Altitude Aspect (BRAA)", A2ACoordinateMenu, self.MenuGroupA2ASystem, self, PlayerUnit, PlayerGroup, PlayerName, "BRAA" ) end - if not self:IsA2A_MGRS() or self.staticmenu then + if not self:IsA2A_MGRS() or self.MenuStatic then MENU_GROUP_COMMAND:New( PlayerGroup, "Military Grid (MGRS)", A2ACoordinateMenu, self.MenuGroupA2ASystem, self, PlayerUnit, PlayerGroup, PlayerName, "MGRS" ) end - if self:IsA2A_MGRS() or self.staticmenu then + if self:IsA2A_MGRS() or self.MenuStatic then MENU_GROUP_COMMAND:New( PlayerGroup, "MGRS Accuracy 1", A2ACoordinateMenu, self.MenuGroupMGRS_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 1 ) MENU_GROUP_COMMAND:New( PlayerGroup, "MGRS Accuracy 2", A2ACoordinateMenu, self.MenuGroupMGRS_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 2 ) MENU_GROUP_COMMAND:New( PlayerGroup, "MGRS Accuracy 3", A2ACoordinateMenu, self.MenuGroupMGRS_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 3 ) @@ -768,11 +805,11 @@ do -- SETTINGS local MetricsMenu = MENU_GROUP:New( PlayerGroup, "Measures and Weights System", PlayerMenu ) - if self:IsMetric() or self.staticmenu then + if self:IsMetric() or self.MenuStatic then MENU_GROUP_COMMAND:New( PlayerGroup, "Imperial (Miles,Feet)", MetricsMenu, self.MenuGroupMWSystem, self, PlayerUnit, PlayerGroup, PlayerName, false ) end - if self:IsImperial() or self.staticmenu then + if self:IsImperial() or self.MenuStatic then MENU_GROUP_COMMAND:New( PlayerGroup, "Metric (Kilometers,Meters)", MetricsMenu, self.MenuGroupMWSystem, self, PlayerUnit, PlayerGroup, PlayerName, true ) end diff --git a/Moose Development/Moose/Functional/RAT2.lua b/Moose Development/Moose/Functional/RAT2.lua index 7edfba927..1a13d368f 100644 --- a/Moose Development/Moose/Functional/RAT2.lua +++ b/Moose Development/Moose/Functional/RAT2.lua @@ -169,7 +169,6 @@ end -- @param #RATAC ratcraft Ratcraft to spawn. -- @param #table parking Parking data for this asset. -- @param #boolean uncontrolled Spawn aircraft in uncontrolled state. - -- @return Wrapper.Group#GROUP The spawned group or nil if the group could not be spawned. function RAT2:_SpawnRatcraft(ratcraft, departure, destination, parking, uncontrolled) diff --git a/Moose Development/Moose/Ops/FlightControl.lua b/Moose Development/Moose/Ops/FlightControl.lua index 72fda8f32..2652bd626 100644 --- a/Moose Development/Moose/Ops/FlightControl.lua +++ b/Moose Development/Moose/Ops/FlightControl.lua @@ -110,7 +110,6 @@ FLIGHTCONTROL.FlightState={ -- @field #number angelsmin Smallest holding altitude in angels. -- @field #number angelsmax Largest holding alitude in angels. - --- Parking spot data. -- @type FLIGHTCONTROL.ParkingSpot -- @field #number index Parking index. @@ -131,7 +130,7 @@ FLIGHTCONTROL.FlightState={ --- FlightControl class version. -- @field #string version -FLIGHTCONTROL.version="0.0.2" +FLIGHTCONTROL.version="0.0.3" ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- TODO list @@ -139,12 +138,16 @@ FLIGHTCONTROL.version="0.0.2" -- TODO: Add FARPS. -- TODO: Add helos. +-- TODO: Task me down option. +-- TODO: ATIS option. +-- TODO: ATC voice overs. +-- TODO: Check runways and clean up. ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- Constructor ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ---- Create a new FLIGHTCONTROL class object for a specific aircraft carrier unit. +--- Create a new FLIGHTCONTROL class object for an associated airbase. -- @param #FLIGHTCONTROL self -- @param #string airbasename Name of the airbase. -- @return #FLIGHTCONTROL self @@ -197,7 +200,7 @@ function FLIGHTCONTROL:New(airbasename) end ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --- User Fuctions +-- User API Functions ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --- Set runway. This clears all auto generated runways. @@ -245,7 +248,7 @@ end function FLIGHTCONTROL:onafterStart() -- Events are handled my MOOSE. - self:I(self.lid..string.format("Starting FLIGHTCONTROL v%s for airbase %s of type %d on map %s.", FLIGHTCONTROL.version, self.airbasename, self.airbasetype, self.theatre)) + self:I(self.lid..string.format("Starting FLIGHTCONTROL v%s for airbase %s of type %d on map %s", FLIGHTCONTROL.version, self.airbasename, self.airbasetype, self.theatre)) -- Handle events. self:HandleEvent(EVENTS.Birth) @@ -284,6 +287,7 @@ function FLIGHTCONTROL:onafterStatus() local text=string.format("State %s - Active Runway %03d - Free Parking %d", self:GetState(), runway.direction, nfree) self:I(self.lid..text) + -- Next status update in ~30 seconds. self:__Status(-30) end @@ -313,7 +317,7 @@ function FLIGHTCONTROL:_InitRunwayData() local hdg=c1:HeadingTo(c2) -- Debug info. - self:T(self.lid..string.format("Runway %d heading=%03d°", j, hdg)) + self:T(self.lid..string.format("Runway %d heading=%03d�", j, hdg)) -- Runway table. local runway={} --#FLIGHTCONTROL.Runway @@ -675,6 +679,7 @@ function FLIGHTCONTROL:_CheckParking() end end + -- Loop over all parking spots. for i,_spot in pairs(self.parking) do local spot=_spot --#FLIGHTCONTROL.ParkingSpot @@ -735,6 +740,7 @@ function FLIGHTCONTROL:_GetNextWaitingFight() if flight.holding~=nil and Tmarshal>=TmarshalMin then return flight end + end return nil diff --git a/Moose Development/Moose/Ops/FlightGroup.lua b/Moose Development/Moose/Ops/FlightGroup.lua index 66b00804e..197e2df02 100644 --- a/Moose Development/Moose/Ops/FlightGroup.lua +++ b/Moose Development/Moose/Ops/FlightGroup.lua @@ -4,7 +4,7 @@ -- -- * Monitor flight status of elements or entire group. -- * Monitor fuel and ammo status. --- * Sophisicated task queueing system. +-- * Sophisticated task queueing system. -- * Many additional events for each element and the whole group. -- -- @@ -84,6 +84,7 @@ FLIGHTGROUP = { --- Status of flight group element. -- @type FLIGHTGROUP.ElementStatus +-- @field #string INUTERO Element was not spawned yet or its status is unknown so far. -- @field #string SPAWNED Element was spawned into the world. -- @field #string PARKING Element is parking after spawned on ramp. -- @field #string TAXIING Element is taxiing after engine startup. @@ -92,6 +93,7 @@ FLIGHTGROUP = { -- @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. FLIGHTGROUP.ElementStatus={ + INUTERO="inutero", SPAWNED="spawned", PARKING="parking", TAXIING="taxiing", @@ -111,6 +113,8 @@ FLIGHTGROUP.ElementStatus={ -- @field Wrapper.Unit#UNIT unit Element unit object. -- @field Wrapper.Group#GROUP group Group object of the element. -- @field #string status Status, i.e. born, parking, taxiing. See @{#FLIGHTGROUP.ElementStatus}. +-- @field #table pylons Table of pylons. +-- @field #number damage Damage of element in percent. --- Flight group tasks. -- @type FLIGHTGROUP.Mission @@ -134,7 +138,7 @@ FLIGHTGROUP.Mission={ --- Flight group task status. -- @type FLIGHTGROUP.TaskStatus --- @field #string SCHEDULED Task is sheduled. +-- @field #string SCHEDULED Task is scheduled. -- @field #string EXECUTING Task is being executed. -- @field #string ACCOMPLISHED Task is accomplished. -- @field #string WAYPOINT Task is executed at a waypoint. @@ -146,7 +150,7 @@ FLIGHTGROUP.TaskStatus={ --- Flight group task status. -- @type FLIGHTGROUP.TaskType --- @field #string SCHEDULED Task is sheduled. +-- @field #string SCHEDULED Task is scheduled. -- @field #string EXECUTING Task is being executed. FLIGHTGROUP.TaskType={ SCHEDULED="scheduled", @@ -170,7 +174,7 @@ FLIGHTGROUP.TaskType={ --- FLIGHTGROUP class version. -- @field #string version -FLIGHTGROUP.version="0.0.8" +FLIGHTGROUP.version="0.0.9" ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- TODO list @@ -233,6 +237,7 @@ function FLIGHTGROUP:New(groupname) self:AddTransition("*", "RTB", "Returning") -- Group is returning to base. self:AddTransition("*", "Orbit", "Orbiting") -- Group is holding position. + self:AddTransition("*", "Hold", "Holding") -- Group is holding position. self:AddTransition("*", "PassingWaypoint", "*") -- Group passed a waypoint. @@ -307,22 +312,8 @@ function FLIGHTGROUP:New(groupname) BASE:TraceLevel(1) end - -- Check if the group is already alive and if so, add its elements. - -- TODO: move this to start? - local group=GROUP:FindByName(groupname) - if group and group:IsAlive() then - self.flightgroup=group - local units=group:GetUnits() - for _,_unit in pairs(units) do - local unit=_unit --Wrapper.Unit#UNIT - local element=self:AddElementByName(unit:GetName()) - - -- Trigger Spawned event. Delay a bit to start - self:__ElementSpawned(0.1, element) - - end - end + -- Init task counter. self.taskcurrent=0 self.taskcounter=0 @@ -336,7 +327,6 @@ end -- User functions ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - --- Add scheduled task. -- @param #FLIGHTGROUP self -- @param #string description Brief text describing the task, e.g. "Attack SAM". @@ -429,7 +419,6 @@ function FLIGHTGROUP:GetSquadron() return self.squadron end - --- Set low fuel threshold. Triggers event "FuelLow" and calls event function "OnAfterFuelLow". -- @param #FLIGHTGROUP self -- @param #number threshold Fuel threshold in percent. Default 25 %. @@ -475,6 +464,36 @@ function FLIGHTGROUP:GetName() return self.flightgroup:GetName() end +--- Get waypoint. +-- @param #FLIGHTGROUP self +-- @param #number indx Waypoint index. +-- @return #table Waypoint table. +function FLIGHTGROUP:GetWaypoint(indx) + return self.waypoints[indx] +end + +--- Get final waypoint. +-- @param #FLIGHTGROUP self +-- @return #table Waypoint table. +function FLIGHTGROUP:GetWaypointFinal() + return self.waypoints[#self.waypoints] +end + +--- Get next waypoint. +-- @param #FLIGHTGROUP self +-- @return #table Waypoint table. +function FLIGHTGROUP:GetWaypointNext() + local n=math.min(self.currentwp+1, #self.waypoints) + return self.waypoints[n] +end + +--- Get current waypoint. +-- @param #FLIGHTGROUP self +-- @return #table Waypoint table. +function FLIGHTGROUP:GetWaypointCurrent() + return self.waypoints[self.currentwp] +end + --- Check if flight is airborne. -- @param #FLIGHTGROUP self -- @return #boolean @@ -528,7 +547,6 @@ end -- Start & Status ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - --- On after Start event. Starts the FLIGHTGROUP FSM and event handlers. -- @param #FLIGHTGROUP self -- @param Wrapper.Group#GROUP Group Flight group. @@ -540,6 +558,21 @@ function FLIGHTGROUP:onafterStart(From, Event, To) -- Short info. local text=string.format("Starting flight group %s.", self.groupname) self:I(self.sid..text) + + -- Check if the group is already alive and if so, add its elements. + local group=GROUP:FindByName(self.groupname) + if group and group:IsAlive() then + self.flightgroup=group + local units=group:GetUnits() + for _,_unit in pairs(units) do + local unit=_unit --Wrapper.Unit#UNIT + local element=self:AddElementByName(unit:GetName()) + + -- Trigger Spawned event. Delay a bit to start. + self:__ElementSpawned(0.1, element) + + end + end -- Handle events: self:HandleEvent(EVENTS.Birth, self.OnEventBirth) @@ -551,8 +584,6 @@ function FLIGHTGROUP:onafterStart(From, Event, To) self:HandleEvent(EVENTS.Ejection, self.OnEventEjection) self:HandleEvent(EVENTS.Crash, self.OnEventCrash) - self.taskcounter=0 - -- Start the status monitoring. self:__FlightStatus(-1) end @@ -628,6 +659,7 @@ function FLIGHTGROUP:onafterFlightStatus(From, Event, To) self:ElementDead(element) end + -- Get ammo. local nammo=0 local nshells=0 local nrockets=0 @@ -742,8 +774,15 @@ function FLIGHTGROUP:OnEventBirth(EventData) local group=EventData.IniGroup local unitname=EventData.IniUnitName + -- Set group. self.flightgroup=self.flightgroup or EventData.IniGroup + + -- Set homebase if not already set. + if EventData.Place then + self.homebase=self.homebase or EventData.Place + end + -- Create element spawned event if not already present. if not self:_IsElement(unitname) then local element=self:AddElementByName(unitname) self:ElementSpawned(element) @@ -1369,8 +1408,6 @@ function FLIGHTGROUP:RouteRTB(RTBAirbase, Speed, Altitude) -- Set route points. Template.route.points=Points - -- Set modex for respawn. - --self.flightgroup:InitModex(self.modex) -- Respawn the group. self.flightgroup=self.flightgroup:Respawn(Template, true) @@ -1437,8 +1474,23 @@ function FLIGHTGROUP:AddElementByName(unitname) element.name=unitname element.unit=unit - element.status="unknown" + element.status=FLIGHTGROUP.ElementStatus.INUTERO element.group=unit:GetGroup() + + element.modex=element.unit:GetTemplate().onboard_num + element.skill=element.unit:GetTemplate().skill + element.pylons=element.unit:GetTemplatePylons() + element.fuelmass=element.unit:GetTemplatePayload().fuel + element.category=element.unit:GetCategory() + element.categoryname=element.unit:GetCategoryName() + element.callsign=element.unit:GetCallsign() + + if element.skill=="Client" or element.skill=="Player" then + element.ai=false + else + element.ai=true + end + table.insert(self.element, element) @@ -1466,6 +1518,33 @@ function FLIGHTGROUP:GetElementByName(unitname) return nil 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:GetDestinationFromWaypoints() + + local wp=self:GetWaypointFinal() + + 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 task description is unique. -- @param #FLIGHTGROUP self @@ -1554,6 +1633,9 @@ function FLIGHTGROUP:_UpdateRoute(n) table.insert(wp, self.waypoints[i]) end + -- Get destination airbase from waypoints. + self.destination=self:GetDestinationFromWaypoints() or self.destination + if #wp>0 then -- Route group to all defined waypoints remaining. @@ -1561,15 +1643,25 @@ function FLIGHTGROUP:_UpdateRoute(n) else + --- + -- No waypoints left + --- + -- Get destination or home airbase. local airbase=self.destination or self.homebase - if airbase then - -- Route flight home. - self:RTB(airbase) - else - -- Let flight orbit. - --self:Orbit(self.flightgroup:GetCoordinate(), UTILS.FeetToMeters(20000), self.flightgroup:GetSpeedMax()*0.4) + if self:IsAirborne() then + + -- TODO: check if no more scheduled tasks. + + if airbase then + -- Route flight to destination/home. + self:RTB(airbase) + else + -- Let flight orbit. + self:Orbit(self.flightgroup:GetCoordinate(), UTILS.FeetToMeters(20000), self.flightgroup:GetSpeedMax()*0.4) + end + end end @@ -1579,7 +1671,6 @@ end --- Initialize Mission Editor waypoints. -- @param #FLIGHTGROUP self --- @return #FLIGHTGROUP self function FLIGHTGROUP:_UpdateWaypointTasks() for i,wp in pairs(self.waypoints) do