diff --git a/Moose Development/Moose/Functional/Warehouse.lua b/Moose Development/Moose/Functional/Warehouse.lua index 29afa533d..8e8ff9fb9 100644 --- a/Moose Development/Moose/Functional/Warehouse.lua +++ b/Moose Development/Moose/Functional/Warehouse.lua @@ -5611,6 +5611,11 @@ function WAREHOUSE:_SpawnAssetAircraft(alias, asset, request, parking, uncontrol if asset.payload then unit.payload=asset.payload.pylons + env.info("FF payload") + self:I({playload=unit.payload}) + self:I(asset) + else + env.info("FF No payload for asset!") end end diff --git a/Moose Development/Moose/Ops/AirWing.lua b/Moose Development/Moose/Ops/AirWing.lua index 85479930a..555be6d6c 100644 --- a/Moose Development/Moose/Ops/AirWing.lua +++ b/Moose Development/Moose/Ops/AirWing.lua @@ -652,8 +652,11 @@ function AIRWING:_GetNextMission() -- Get payload for the asset. asset.payload=self:FetchPayloadFromStock(asset.unittype, mission.type) + env.info("FF asset payload for mission "..mission.type) + self:I(asset.payload) + if not asset.payload then - self:E("No payload for asset! This should not happen!") + self:E(self.lid.."ERROR: No payload for asset! This should not happen!") end mission:AddAsset(asset) diff --git a/Moose Development/Moose/Ops/Auftrag.lua b/Moose Development/Moose/Ops/Auftrag.lua index ff8149248..a2d692cf7 100644 --- a/Moose Development/Moose/Ops/Auftrag.lua +++ b/Moose Development/Moose/Ops/Auftrag.lua @@ -60,6 +60,7 @@ -- @field #table assets Airwing Assets assigned for this mission. -- @field #number nassets Number of required assets by the Airwing. -- @field #number requestID The ID of the queued warehouse request. Necessary to cancel the request if the mission was cancelled before the request is processed. +-- @field #boolean cancelContactLost If true, cancel mission if the contact is lost. -- -- @field #number optionROE ROE. -- @field #number optionROT ROT. @@ -186,6 +187,12 @@ AUFTRAG.FlightStatus={ CANCELLED="cancelled", } +--- Mission success. +-- @type AUFTRAG.Success +-- @field #string ENGAGED Target was engaged. +-- @field #string DAMAGED Target was damaged. +-- @field #string DESTROYED Target was destroyed. + --- Flight specific data. Each flight subscribed to this mission has different data for this. -- @type AUFTRAG.FlightData -- @field Ops.FlightGroup#FLIGHTGROUP flightgroup The flight group. @@ -647,7 +654,7 @@ function AUFTRAG:onafterStatus(From, Event, To) local Nflights=self:CountFlightGroups() -- Cancel mission if stop time passed. - if self.Tstop and timer.getAbsTime()>self.Tstop then + if self.Tstop and timer.getAbsTime()>self.Tstop+10 then self:Cancel() end @@ -702,7 +709,12 @@ end -- @param Ops.FlightGroup#FLIGHTGROUP flightgroup The flight group. -- @param #string status New status. function AUFTRAG:SetFlightStatus(flightgroup, status) - self.flightdata[flightgroup.groupname].status=status + + if self:GetFlightStatus(flightgroup)==AUFTRAG.FlightStatus.CANCELLED and status==AUFTRAG.FlightStatus.DONE then + -- Do not overwrite a CANCELLED status with a DONE status. + else + self.flightdata[flightgroup.groupname].status=status + end -- Check if ALL flights are done with their mission. if self:IsNotOver() and self:CheckFlightsDone() then diff --git a/Moose Development/Moose/Ops/FlightGroup.lua b/Moose Development/Moose/Ops/FlightGroup.lua index df7c63315..9343758ed 100644 --- a/Moose Development/Moose/Ops/FlightGroup.lua +++ b/Moose Development/Moose/Ops/FlightGroup.lua @@ -1229,7 +1229,9 @@ function FLIGHTGROUP:onafterFlightStatus(From, Event, To) --- -- Check if group has detected any units. - self:_CheckDetectedUnits() + if self.DetectionON then + self:_CheckDetectedUnits() + end --- -- Parking @@ -1264,10 +1266,11 @@ function FLIGHTGROUP:onafterFlightStatus(From, Event, To) --- local nTaskTot, nTaskSched, nTaskWP=self:CountRemainingTasks() + local nMissions=self:CountRemainingMissison() -- Short info. - local text=string.format("Status %s [%d/%d]: Tasks=%d (%d,%d) Current=%d. Waypoint=%d/%d. Detected=%d. Destination=%s, FC=%s", - fsmstate, #self.elements, #self.elements, nTaskTot, nTaskSched, nTaskWP, self.taskcurrent, self.currentwp or 0, self.waypoints and #self.waypoints or 0, + local text=string.format("Status %s [%d/%d]: Tasks=%d (%d,%d) Current=%d. Missions=%s. Waypoint=%d/%d. Detected=%d. Destination=%s, FC=%s", + fsmstate, #self.elements, #self.elements, nTaskTot, nTaskSched, nTaskWP, self.taskcurrent, nMissions, self.currentwp or 0, self.waypoints and #self.waypoints or 0, self.detectedunits:Count(), self.destbase and self.destbase:GetName() or "unknown", self.flightcontrol and self.flightcontrol.airbasename or "none") self:I(self.lid..text) @@ -2197,6 +2200,17 @@ function FLIGHTGROUP:onbeforeUpdateRoute(From, Event, To, n) allowed=false end + if self.taskcurrent>0 then + self:I(self.lid.."FF update route denied because taskcurrent>0") + allowed=false + end + + if self.currentmission then + -- Not good, because mission will never start. Better only check if there is a current task! + --self:I(self.lid.."FF update route denied because currentmission~=nil") + --allowed=false + end + return allowed end @@ -2270,25 +2284,8 @@ function FLIGHTGROUP:onafterUpdateRoute(From, Event, To, n) -- No waypoints left --- - if self.passedfinalwp then - - self:I(self.lid.."UpdateRoute: Passed Final WP ==> RTB/RTZ/Wait!") - - -- Send flight to destination. NOTE that if there are still remaining tasks, the RTB call is delayed by 10 sec until all tasks are done. - if self.destbase then - self:I(self.lid.."UpdateRoute: Passed Final WP ==> RTB!") - self:__RTB(-1, self.destbase) - elseif self.destzone then - self:I(self.lid.."UpdateRoute: Passed Final WP ==> RTZ!") - self:__RTZ(-1, self.destzone) - else - self:I(self.lid.."UpdateRoute: Passed Final WP ==> Wait!") - self:__Wait(-1) - end - else - self:E(self.lid.."WARNING: No waypoints left. Dunno what to do!") - end - + self:_CheckFlightDone() + end end @@ -2371,28 +2368,71 @@ function FLIGHTGROUP:onafterPassingWaypoint(From, Event, To, n, N) -- Final AIR waypoint reached? if n==N then - --TODO: Find better way to RTB! - self:I(self.lid.."FF group passed final waypoint!") - + -- Set switch to true. self.passedfinalwp=true - if #taskswp==0 then - - if self.destbase then - self:__RTB(-1, self.destbase) - elseif self.destzone then - self:__RTZ(-1, self.destzone) - else - self:__Wait(-1) - self:E(self.lid.."ERROR: Reached final waypoint but no destination set! Don't know what to do?!") - end - - end + -- Check if all tasks/mission are done? If so, RTB or WAIT. + -- Note, we delay it for a second to let the OnAfterPassingwaypoint function to be executed in case someone wants to add another waypoint there. + self:_CheckFlightDone(1) end end +--- Check if flight is done, i.e. +-- +-- * passed the final waypoint, +-- * no current task +-- * no current mission +-- * number of remaining tasks is zero +-- * number of remaining missions is zero +-- +-- @param #FLIGHTGROUP self +-- @param #number delay Delay in seconds. +function FLIGHTGROUP:_CheckFlightDone(delay) + + if delay and delay>0 then + -- Delayed call. + self:ScheduleOnce(delay, FLIGHTGROUP._CheckFlightDone, self) + else + + local nTasks=self:CountRemainingTasks() + local nMissions=self:CountRemainingMissison() + + -- Final waypoint passed? + if self.passedfinalwp then + + -- Got current mission or task? + if self.currentmission==nil and self.taskcurrent==0 then + + -- Number of remaining tasks/missions? + if nTasks==0 and nMissions==0 then + + -- Send flight to destination. + if self.destbase then + self:I(self.lid.."Passed Final WP and No current and/or future missions/task ==> RTB!") + self:__RTB(-1, self.destbase) + elseif self.destzone then + self:I(self.lid.."Passed Final WP and No current and/or future missions/task ==> RTZ!") + self:__RTZ(-1, self.destzone) + else + self:I(self.lid.."Passed Final WP and NO Tasks/Missions left. No DestBase or DestZone ==> Wait!") + self:__Wait(-1) + end + + else + self:I(self.lid..string.format("Passed Final WP but Tasks=%d or Missions=%d left in the queue. Wait!", nTasks, nMissions)) + self:__Wait(-1) + end + else + self:I(self.lid..string.format("Passed Final WP but still have current Tasks or Missions left to do")) + end + else + self:I(self.lid.."Did NOT pass the final waypoint yet") + end + end +end + --- On after "GotoWaypoint" event. Group will got to the given waypoint and execute its route from there. -- @param #FLIGHTGROUP self -- @param #string From From state. @@ -2864,6 +2904,7 @@ function FLIGHTGROUP:_SortTaskQueue() end + --- Count the number of tasks that still pending in the queue. -- @param #FLIGHTGROUP self -- @return #number Total number of tasks remaining. @@ -2909,7 +2950,10 @@ function FLIGHTGROUP:CountRemainingMissison() -- Loop over mission queue. for _,_mission in pairs(self.missionqueue) do local mission=_mission --Ops.Auftrag#AUFTRAG - if mission.status~=AUFTRAG.Status.DONE then + + local status=mission:GetFlightStatus(self) + + if status~=AUFTRAG.FlightStatus.DONE and status~=AUFTRAG.FlightStatus.CANCELLED then N=N+1 end end @@ -2956,7 +3000,7 @@ function FLIGHTGROUP:onafterTaskExecute(From, Event, To, Task) else table.insert(DCStasks, Task.dcstask) end - + -- Combo task. local TaskCombo=self.group:TaskCombo(DCStasks) @@ -3110,12 +3154,17 @@ function FLIGHTGROUP:onafterTaskDone(From, Event, To, Task) -- Check if this task was the task of the current mission ==> Mission Done! local Mission=self:GetMissionByTaskID(Task.id) + + if Mission then self:MissionDone(Mission) + else + self:_CheckFlightDone(1) end -- Update route. This is necessary because of the route task being overwritten. But we want to fly to the remaining waypoints. - self:__UpdateRoute(-1) + -- TODO: Since TaskExecute does use PushTask now, it should not be necessary to update the route, right? + --self:__UpdateRoute(-1) end @@ -3208,6 +3257,10 @@ end -- @param Ops.Auftrag#AUFTRAG Mission The mission to be cancelled. function FLIGHTGROUP:onafterMissionCancel(From, Event, To, Mission) + -- Set missin flight status. + env.info("FF setting mission to cancelled") + Mission:SetFlightStatus(self, AUFTRAG.FlightStatus.CANCELLED) + if self.currentmission and Mission.auftragsnummer==self.currentmission then -- Get mission waypoint task. @@ -3227,14 +3280,13 @@ function FLIGHTGROUP:onafterMissionCancel(From, Event, To, Mission) else -- Not the current mission. - -- TODO: remove mission from queue? + -- TODO: remove mission from queue? + + -- Send flight RTB or WAIT if nothing left to do. + self:_CheckFlightDone() end - -- Set missin flight status. - env.info("FF setting mission to cancelled") - Mission:SetFlightStatus(self, AUFTRAG.FlightStatus.CANCELLED) - end --- On after "MissionDone" event. @@ -3250,6 +3302,9 @@ function FLIGHTGROUP:onafterMissionDone(From, Event, To, Mission) -- Set current mission to nil. self.currentmission=nil + + -- Check if flight is done. + self:_CheckFlightDone(1) end diff --git a/Moose Development/Moose/Ops/Intelligence.lua b/Moose Development/Moose/Ops/Intelligence.lua index 3d12cc309..c20407d5a 100644 --- a/Moose Development/Moose/Ops/Intelligence.lua +++ b/Moose Development/Moose/Ops/Intelligence.lua @@ -483,11 +483,28 @@ end -- @return #boolean If true, contact was not detected for at least *dTforget* seconds. function INTEL:CheckContactLost(Contact) + -- Group dead? + if Contact.group==nil or not Contact.group:IsAlive() then + return true + end + -- Time since last detected. local dT=timer.getAbsTime()-Contact.Tdetected + local dTforget=self.dTforget + if Contact.category==Group.Category.GROUND then + dTforget=60*60*2 -- 2 hours + elseif Contact.category==Group.Category.AIRPLANE then + dTforget=60*10 -- 10 min + elseif Contact.category==Group.Category.HELICOPTER then + dTforget=60*20 -- 20 min + elseif Contact.category==Group.Category.SHIP then + dTforget=60*60 -- 1 hour + elseif Contact.category==Group.Category.TRAIN then + dTforget=60*60 -- 1 hour + end - if dT>self.dTforget then + if dT>dTforget then return true else return false