diff --git a/Moose Development/Moose/Ops/Auftrag.lua b/Moose Development/Moose/Ops/Auftrag.lua index b3d25e27b..82786e869 100644 --- a/Moose Development/Moose/Ops/Auftrag.lua +++ b/Moose Development/Moose/Ops/Auftrag.lua @@ -2571,18 +2571,6 @@ function AUFTRAG:onafterAssetDead(From, Event, To, Asset) end end - - -- Asset belonged to an airwing. - if self.airwing then - - if self.Ncasualties==self.Nelements then - -- All elements were destroyed ==> Asset is gone. - self.airwing:RemoveAssetFromSquadron(Asset) - else - -- Not all assets were destroyed (despawn) ==> Add asset back to airwing. - self.airwing:AddAsset(Asset.flightgroup.group, 1) - end - end -- Delete asset from mission. self:DelAsset(Asset) diff --git a/Moose Development/Moose/Ops/FlightGroup.lua b/Moose Development/Moose/Ops/FlightGroup.lua index 886eee119..55d66f504 100644 --- a/Moose Development/Moose/Ops/FlightGroup.lua +++ b/Moose Development/Moose/Ops/FlightGroup.lua @@ -46,7 +46,7 @@ -- @field #boolean ishelo If true, the is a helicopter group. -- @field #number callsignName Callsign name. -- @field #number callsignNumber Callsign number. --- @field #number Ndestroyed Number of destroyed units. +-- @field #boolean despawnAfterLanding If true, group is despawned after landed at an airbase. -- -- @extends Ops.OpsGroup#OPSGROUP @@ -133,7 +133,6 @@ FLIGHTGROUP = { Tparking = nil, menu = nil, ishelo = nil, - Ndestroyed = 0, } @@ -497,6 +496,14 @@ function FLIGHTGROUP:SetFuelCriticalRTB(switch) return self end +--- Enable that the group is despawned after landing. This can be useful to avoid DCS taxi issues with other AI or players or jamming taxiways. +-- @param #FLIGHTGROUP self +-- @return #FLIGHTGROUP self +function FLIGHTGROUP:SetDespawnAfterLanding() + self.despawnAfterLanding=true + return self +end + --- Check if flight is parking. -- @param #FLIGHTGROUP self @@ -1557,6 +1564,10 @@ function FLIGHTGROUP:onafterLanded(From, Event, To, airbase) -- Add flight to taxiinb queue. self.flightcontrol:SetFlightStatus(self, FLIGHTCONTROL.FlightStatus.TAXIINB) end + + if self.despawnAfterLanding then + self:Despawn() + end end @@ -1602,6 +1613,18 @@ function FLIGHTGROUP:onafterDead(From, Event, To) self.flightcontrol:_RemoveFlight(self) self.flightcontrol=nil end + + if self.Ndestroyed==#self.elements then + if self.squadron then + -- All elements were destroyed ==> Asset group is gone. + self.squadron:DelGroup(self.groupname) + end + else + if self.airwing then + -- Not all assets were destroyed (despawn) ==> Add asset back to airwing. + self.airwing:AddAsset(self.group, 1) + end + end -- Call OPSGROUP function. self:GetParent(self).onafterDead(self, From, Event, To) @@ -2407,31 +2430,16 @@ function FLIGHTGROUP:onafterStop(From, Event, To) end -- Destroy group. No event is generated. - self.group:Destroy(false) + -- DISABLED for now. Should use :Despawn() or :Destroy() which then calls stop. + --self.group:Destroy(false) end - -- Handle events: - self:UnHandleEvent(EVENTS.Birth) - self:UnHandleEvent(EVENTS.EngineStartup) - self:UnHandleEvent(EVENTS.Takeoff) - self:UnHandleEvent(EVENTS.Land) - self:UnHandleEvent(EVENTS.EngineShutdown) - self:UnHandleEvent(EVENTS.PilotDead) - self:UnHandleEvent(EVENTS.Ejection) - self:UnHandleEvent(EVENTS.Crash) - self:UnHandleEvent(EVENTS.RemoveUnit) - - -- Stop check timers. - self.timerCheckZone:Stop() - self.timerQueueUpdate:Stop() - - -- Stop FSM scheduler. - self.CallScheduler:Clear() - -- Remove flight from data base. _DATABASE.FLIGHTGROUPS[self.groupname]=nil - - self:I(self.lid.."STOPPED! Unhandled events, cleared scheduler and removed from database.") + + + -- Call OPSGROUP function. + self:GetParent(self).onafterStop(self, From, Event, To) end ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- diff --git a/Moose Development/Moose/Ops/OpsGroup.lua b/Moose Development/Moose/Ops/OpsGroup.lua index 7fe4b81d5..1dbfccef9 100644 --- a/Moose Development/Moose/Ops/OpsGroup.lua +++ b/Moose Development/Moose/Ops/OpsGroup.lua @@ -40,7 +40,7 @@ -- @field #string attribute Generalized attribute. -- @field #number speedMax Max speed in km/h. -- @field #number speedCruise Cruising speed in km/h. --- @field #number speedWp Speed to the next waypoint in km/h. +-- @field #number speedWp Speed to the next waypoint in m/s. -- @field #boolean passedfinalwp Group has passed the final waypoint. -- @field #number wpcounter Running number counting waypoints. -- @field #boolean respawning Group is being respawned. @@ -51,6 +51,7 @@ -- @field #boolean groupinitialized If true, group parameters were initialized. -- @field #boolean detectionOn If true, detected units of the group are analyzed. -- @field Ops.Auftrag#AUFTRAG missionpaused Paused mission. +-- @field #number Ndestroyed Number of destroyed units. -- -- @field Core.Point#COORDINATE coordinate Current coordinate. -- @field Core.Point#COORDINATE position Position of the group at last status check. @@ -126,6 +127,7 @@ OPSGROUP = { tacan = {}, icls = {}, callsign = {}, + Ndestroyed = 0, } --- Status of group element. @@ -540,51 +542,73 @@ end --- Despawn the group. The whole group is despawned and (optionally) a "Remove Unit" event is generated for all current units of the group. -- @param #OPSGROUP self +-- @param #number Delay Delay in seconds before the group will be despawned. Default immediately. +-- @param #boolean NoEventRemoveUnit If true, no event "Remove Unit" is generated. -- @return #OPSGROUP self -function OPSGROUP:Despawn() +function OPSGROUP:Despawn(Delay, NoEventRemoveUnit) - local DCSGroup=self:GetDCSGroup() - - if DCSGroup then - - -- Destroy DCS group. - DCSGroup:destroy() - - -- Get all units. - local units=self:GetDCSUnits() + if Delay and Delay>0 then + self:ScheduleOnce(Delay, OPSGROUP.Despawn, self, 0, NoEventRemoveUnit) + else - -- Create a "Remove Unit" event. - local EventTime=timer.getTime() - for i=1,#units do - self:CreateEventRemoveUnit(EventTime, units[i]) + local DCSGroup=self:GetDCSGroup() + + if DCSGroup then + + -- Destroy DCS group. + DCSGroup:destroy() + + if not NoEventRemoveUnit then + + -- Get all units. + local units=self:GetDCSUnits() + + -- Create a "Remove Unit" event. + local EventTime=timer.getTime() + for i=1,#units do + self:CreateEventRemoveUnit(EventTime, units[i]) + end + + end end end return self end ---- Destroy group. The whole group is despawned and a "Unit Lost" event is generated for all current units. +--- Destroy group. The whole group is despawned and a *Unit Lost* for aircraft or *Dead* event for ground/naval units is generated for all current units. -- @param #OPSGROUP self +-- @param #number Delay Delay in seconds before the group will be destroyed. Default immediately. -- @return #OPSGROUP self -function OPSGROUP:Destroy() +function OPSGROUP:Destroy(Delay) - local DCSGroup=self:GetDCSGroup() - - if DCSGroup then - - self:I(self.lid.."Destroying group ") - - -- Destroy DCS group. - DCSGroup:destroy() - - -- Get all units. - local units=self:GetDCSUnits() - - -- Create a "Unit Lost" event. - local EventTime=timer.getTime() - for i=1,#units do - self:CreateEventUnitLost(EventTime, units[i]) + if Delay and Delay>0 then + self:ScheduleOnce(Delay, OPSGROUP.Destroy, self) + else + + local DCSGroup=self:GetDCSGroup() + + if DCSGroup then + + self:I(self.lid.."Destroying group") + + -- Destroy DCS group. + DCSGroup:destroy() + + -- Get all units. + local units=self:GetDCSUnits() + + -- Create a "Unit Lost" event. + local EventTime=timer.getTime() + for i=1,#units do + if self.isAircraft then + self:CreateEventUnitLost(EventTime, units[i]) + else + self:CreateEventDead(EventTime, units[i]) + end + end end + end return self @@ -2642,7 +2666,10 @@ function OPSGROUP:onafterElementDestroyed(From, Event, To, Element) mission:ElementDestroyed(self, Element) - end + end + + -- Increase counter. + self.Ndestroyed=self.Ndestroyed+1 -- Set element status. self:_UpdateStatus(Element, OPSGROUP.ElementStatus.DEAD) @@ -2687,6 +2714,39 @@ function OPSGROUP:onafterDead(From, Event, To) self:Stop() end +--- On after "Stop" event. +-- @param #OPSGROUP self +-- @param #string From From state. +-- @param #string Event Event. +-- @param #string To To state. +function OPSGROUP:onafterStop(From, Event, To) + + -- Handle events: + self:UnHandleEvent(EVENTS.Birth) + self:UnHandleEvent(EVENTS.EngineStartup) + self:UnHandleEvent(EVENTS.Takeoff) + self:UnHandleEvent(EVENTS.Land) + self:UnHandleEvent(EVENTS.EngineShutdown) + self:UnHandleEvent(EVENTS.PilotDead) + self:UnHandleEvent(EVENTS.Ejection) + self:UnHandleEvent(EVENTS.Crash) + self:UnHandleEvent(EVENTS.RemoveUnit) + + -- Stop check timers. + self.timerCheckZone:Stop() + self.timerQueueUpdate:Stop() + + -- Stop FSM scheduler. + self.CallScheduler:Clear() + + if self:IsAlive() then + self:E(self.lid.."WARNING: Group is still alive! Use OPSGROUP:Destroy() or OPSGROUP:Despawn() for a clean stop") + end + + -- Debug output. + self:I(self.lid.."STOPPED! Unhandled events, cleared scheduler and removed from database.") +end + ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- Internal Check Functions ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- diff --git a/Moose Development/Moose/Ops/Squadron.lua b/Moose Development/Moose/Ops/Squadron.lua index bb620d089..a9a7ce6ce 100644 --- a/Moose Development/Moose/Ops/Squadron.lua +++ b/Moose Development/Moose/Ops/Squadron.lua @@ -448,6 +448,22 @@ function SQUADRON:DelAsset(Asset) return self end +--- Remove airwing asset group from squadron. +-- @param #SQUADRON self +-- @param #string GroupName Name of the asset group. +-- @return #SQUADRON self +function SQUADRON:DelGroup(GroupName) + for i,_asset in pairs(self.assets) do + local asset=_asset --Ops.AirWing#AIRWING.SquadronAsset + if GroupName==asset.spawngroupname then + self:T2(self.lid..string.format("Removing asset %s", asset.spawngroupname)) + table.remove(self.assets, i) + break + end + end + return self +end + --- Get name of the squadron -- @param #SQUADRON self -- @return #string Name of the squadron. @@ -648,14 +664,14 @@ end -- @param #SQUADRON self function SQUADRON:_CheckAssetStatus() - if self.verbose>=2 then + if self.verbose>=2 and #self.assets>0 then local text="" for j,_asset in pairs(self.assets) do local asset=_asset --Ops.AirWing#AIRWING.SquadronAsset -- Text. - text=text..string.format("\n-[%d] %s (%s*%d): ", j, asset.spawngroupname, asset.unittype, asset.nunits) + text=text..string.format("\n[%d] %s (%s*%d): ", j, asset.spawngroupname, asset.unittype, asset.nunits) if asset.spawned then @@ -709,7 +725,7 @@ function SQUADRON:_CheckAssetStatus() text=text..string.format("In Stock") if self:IsRepaired(asset) then - text=text.." and Combat Ready" + text=text..", Combat Ready" else text=text..string.format(", Repaired in %d sec", self:GetRepairTime(asset))