diff --git a/Moose Development/Moose/Functional/Warehouse.lua b/Moose Development/Moose/Functional/Warehouse.lua index 11b0b1ee0..82a832172 100644 --- a/Moose Development/Moose/Functional/Warehouse.lua +++ b/Moose Development/Moose/Functional/Warehouse.lua @@ -3971,7 +3971,7 @@ end -- @param #string Event Event. -- @param #string To To state. -- @param #WAREHOUSE.Assetitem asset The asset that has just been added. --- @parma #string assignment The (optional) assignment for the asset. +-- @param #string assignment The (optional) assignment for the asset. function WAREHOUSE:onafterNewAsset(From, Event, To, asset, assignment) self:T(self.wid..string.format("New asset %s id=%d with assignment %s.", tostring(asset.templatename), asset.uid, tostring(assignment))) end diff --git a/Moose Development/Moose/Ops/AirWing.lua b/Moose Development/Moose/Ops/AirWing.lua index 0edfdb2c0..4f414ecfb 100644 --- a/Moose Development/Moose/Ops/AirWing.lua +++ b/Moose Development/Moose/Ops/AirWing.lua @@ -41,7 +41,7 @@ AIRWING = { taskqueue = {}, } ---- Squadron +--- Squadron data. -- @type AIRWING.Squadron -- @field #string name Name of the squadron. -- @field #table assets Assets of the squadron. @@ -55,43 +55,36 @@ AIRWING = { -- @field #string typename Type name of group. -- @field #table menu The squadron menu entries. +--- Squadron asset. +-- @type AIRWING.SquadronAsset +-- @field #boolean assigned Assigned to mission. +-- @extends Functional.Warehouse#WAREHOUSE.Assetitem ---- Squadron tasks. --- @type AIRWING.Task --- @param #string INTERCEPT Intercept task. --- @param #string CAP Combat Air Patrol task.s --- @param #string BAI Battlefield Air Interdiction task. --- @param #string SEAD Suppression/destruction of enemy air defences. --- @param #string STRIKE Strike task. --- @param #string AWACS AWACS task. --- @param #string TANKER Tanker task. -AIRWING.Task={ - INTERCEPT="Intercept", - CAP="CAP", - BAI="BAI", - SEAD="SEAD", - STRIKE="Strike", - CAS="CAS", - AWACS="AWACS", - TANKER="Tanker", -} +--- Mission types. +-- @type AIRWING.MissionType +-- @extends Ops.FlightGroup#FLIGHTGROUP.MissionType ---- Mission. +--- Mission data. -- @type AIRWING.Mission -- @field #string type Mission type. -- @field #string squadname Name of the assigned squadron. -- @field #number nassets Number of required assets. -- @field #string status Mission status. +-- @extends Ops.FlightGroup#FLIGHTGROUP.Mission --- AIRWING class version. -- @field #string version AIRWING.version="0.0.5" ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --- TODO list +-- ToDo list ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --- TODO: A lot! +-- TODO: Add squadrons to warehouse. +-- TODO: Make special request to transfer squadrons to anther airwing (or warehouse). +-- TODO: Build mission queue. +-- TODO: Find way to start missions. +-- TODO: Check if missions are accomplished. ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- Constructor @@ -124,7 +117,7 @@ function AIRWING:New(warehousename, airwingname) -- From State --> Event --> To State self:AddTransition("*", "AirwingStatus", "*") -- AIRWING status update. - self:AddTransition("*", "NewMission", "*") -- Request CAP flight. + self:AddTransition("*", "AddMission", "*") -- Add a new mission. self:AddTransition("*", "RequestCAP", "*") -- Request CAP flight. self:AddTransition("*", "RequestIntercept", "*") -- Request Intercept. @@ -152,11 +145,11 @@ function AIRWING:New(warehousename, airwingname) -- @param #AIRWING self -- @param #number delay Delay in seconds. - --- Triggers the FSM event "SkipperStatus". + --- Triggers the FSM event "AirwingStatus". -- @function [parent=#AIRWING] AirwingStatus -- @param #AIRWING self - --- Triggers the FSM event "SkipperStatus" after a delay. + --- Triggers the FSM event "AirwingStatus" after a delay. -- @function [parent=#AIRWING] __AirwingStatus -- @param #AIRWING self -- @param #number delay Delay in seconds. @@ -250,6 +243,85 @@ function AIRWING:GetSquadron(SquadronName) return self.squadrons[SquadronName] end +--- Check if there is a squadron that can execute a given mission type. Optionally, the number of required assets can be specified. +-- @param #AIRWING self +-- @param #AIRWING.Squaron Squadron The Squadron. +-- @param #string MissionType Type of mission. +-- @param #number Nassets Number of required assets for the mission. Use *nil* or 0 for none. Then only the general capability is checked. +-- @return #boolean If true, Squadron can do that type of mission. Available assets are not checked. +-- @return #number Number of available assets. +function AIRWING:SquadronCanMission(Squadron, MissionType, Nassets) + + local cando=false + local n=0 + + local gotit=false + for _,canmission in pairs(Squadron.capability) do + if canmission==MissionType then + gotit=true + break + end + end + + if not gotit then + -- This squad cannot do this mission. + cando=false + n=0 + else + + for _,_asset in pairs(Squadron.assets) do + local asset=_asset --#AIRWING.SquadronAsset + + -- TODO: Check if on mission etc. + if not asset.spawned then + n=n+1 + end + + end + + end + + -- Check if required assets are present. + if Nassets then + if Nassets=mission.Tstart and self:CanMission(mission.type, mission.nassets) then + return mission + end + end + + return nil +end + ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- FSM Events ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ---- On after "SelfRequest" event. +--- On after "NewAsset" event. -- @param #AIRWING self +-- @param #string From From state. +-- @param #string Event Event. +-- @param #string To To state. +-- @param Functional.Warehouse#WAREHOUSE.Assetitem asset The asset that has just been added. +-- @param #string assignment The (optional) assignment for the asset. function AIRWING:onafterNewAsset(From, Event, To, asset, assignment) -- Call parent warehouse function first. @@ -343,29 +468,69 @@ function AIRWING:onafterNewAsset(From, Event, To, asset, assignment) end +--- On before "NewAsset" event. +-- @param #AIRWING self +-- @param #string From From state. +-- @param #string Event Event. +-- @param #string To To state. +-- @param #AIRWING.Mission Mission +-- @return #boolean Allowed transition? +function AIRWING:onbeforeAddMission(From, Event, To, Mission) + + local allowed=true + + -- Check if any squadron can to this type of mission. + -- TODO: well, could be that new squadrons with the capability are added at a later time. + local cando=self:CanMission(Mission.type) + if not cando then + allowed=false + end + + return allowed +end + +--- On after "NewAsset" event. +-- @param #AIRWING self +-- @param #string From From state. +-- @param #string Event Event. +-- @param #string To To state. +-- @param #AIRWING.Mission Mission +function AIRWING:onafterAddMission(From, Event, To, Mission) + + -- Add Mission to queue. + table.insert(self.Qmission, Mission) + +end + + --- On after "SelfRequest" event. -- @param #AIRWING self -function AIRWING:onafterSelfRequest(From, Event, To, Groupset, Request) - local request=Request --Functional.Warehouse#WAREHOUSE.Pendingitem - local groupset=Groupset --Core.Set#SET_GROUP - +-- @param #string From From state. +-- @param #string Event Event. +-- @param #string To To state. +-- @param Core.Set#SET_GROUP groupset The set of asset groups that was delivered to the warehouse itself. +-- @param Functional.Warehouse#WAREHOUSE.Pendingitem request Pending self request. +function AIRWING:onafterSelfRequest(From, Event, To, groupset, request) -- Call parent warehouse function first. - self:GetParent(self).onafterSelfRequest(self, From, Event, To, Groupset, Request) + self:GetParent(self).onafterSelfRequest(self, From, Event, To, groupset, request) for _,_asset in pairs(request.assets) do local asset=_asset --Functional.Warehouse#WAREHOUSE.Assetitem - local a=asset.cargobay end - if Request.assignment==AIRWING.Task.CAP then + if request.assignment==AIRWING.Task.CAP then for _,_group in pairs(groupset:GetSet()) do local group=_group --Wrapper.Group#GROUP - self:LaunchCAP(group, coordinate, altitude, leg, speed, heading) + local fg=FLIGHTGROUP:New(group:GetName()) + + fg:AddMission(request.mission) + + --self:LaunchCAP(group, coordinate, altitude, leg, speed, heading) end end diff --git a/Moose Development/Moose/Ops/FlightGroup.lua b/Moose Development/Moose/Ops/FlightGroup.lua index 330a62e9a..9b8c6b149 100644 --- a/Moose Development/Moose/Ops/FlightGroup.lua +++ b/Moose Development/Moose/Ops/FlightGroup.lua @@ -300,7 +300,7 @@ FLIGHTGROUP.TaskType={ -- @field #number waypoint Waypoint index if task is a waypoint task. -- @field Core.UserFlag#USERFLAG stopflag If flag is set to 1 (=true), the task is stopped. ---- Flight group missions. +--- Mission types. -- @type FLIGHTGROUP.MissionType -- @param #string INTERCEPT Intercept task. -- @param #string CAP Combat Air Patrol task. @@ -322,6 +322,20 @@ FLIGHTGROUP.MissionType={ TRANSPORT="Transport", } +--- Mission status. +-- @type FLIGHTGROUP.MissionStatus +-- @field #string SCHEDULED Mission is scheduled. +-- @field #string EXECUTING Mission is being executed. +-- @field #string ASSIGNED Mission was assigned. +-- @field #string ACCOMPLISHED Mission is accomplished. +FLIGHTGROUP.MissionStatus={ + SCHEDULED="scheduled", + EXECUTING="executing", + ASSIGNED="assigned", + ACCOMPLISHED="accomplished", + FAILED="failed", +} + --- Generic mission. -- @type FLIGHTGROUP.Mission -- @field #string type Mission Type. @@ -330,6 +344,9 @@ FLIGHTGROUP.MissionType={ -- @field #number Tstart Mission start time in seconds. -- @field #number Tstop Mission stop time in seconds. -- @field #number duration Mission duration in seconds. +-- @field #table DCStask DCS task structure. +-- @field #FLIGHTGROUP.Task Waypoint task. +-- @field #number waypoint Waypoint number. --- CAP mission. -- @type FLIGHTGROUP.MissionCAP @@ -1081,7 +1098,7 @@ end -- @param #FLIGHTGROUP self -- @param #table waypoints Table of waypoints. -- @return #FLIGHTGROUP.MissionCAP -function FLIGHTGROUP:CreateMissionCAP() +function FLIGHTGROUP:CreateMissionCAP(MissionType, Zone, Altitude, SpeedOrbit) local mission={} --#FLIGHTGROUP.MissionCAP @@ -2977,13 +2994,13 @@ function FLIGHTGROUP:onafterMissionStart(From, Event, To, Mission) end ---- On after "MissionAccomplished" event. +--- On after "MissionDone" event. -- @param #FLIGHTGROUP self -- @param #string From From state. -- @param #string Event Event. -- @param #string To To state. -- @param #FLIGHTGROUP.Mission Mission -function FLIGHTGROUP:onafterMissionAccomplished(From, Event, To, Mission) +function FLIGHTGROUP:onafterMissionDone(From, Event, To, Mission) Mission.status=FLIGHTGROUP.MissionStatus.ACCOMPLISHED self.currentmission=nil @@ -3026,14 +3043,14 @@ function FLIGHTGROUP:_GetNextMission() return nil end ---- Route group to mission. Also sets the +--- Route group to mission. -- @param #FLIGHTGROUP self -- @param #FLIGHTGROUP.Mission mission The mission table. -- @param #number delay Delay in seconds. function FLIGHTGROUP:RouteToMission(mission, delay) if delay and delay>0 then - -- Delay call. + -- Delayed call. self:ScheduleOnce(delay, FLIGHTGROUP.RouteToMission, self, mission) else @@ -3643,8 +3660,9 @@ end -- @param Core.Point#COORDINATE coordinate The coordinate of the waypoint. Use COORDINATE:SetAltitude(altitude) to define the altitude. -- @param #number wpnumber Waypoint number. Default at the end. -- @param #number speed Speed in knots. Default 350 kts. +-- @param #boolean updateroute If true or nil, call UpdateRoute. If false, no call. -- @return #FLIGHTGROUP self -function FLIGHTGROUP:AddWaypointAir(coordinate, wpnumber, speed) +function FLIGHTGROUP:AddWaypointAir(coordinate, wpnumber, speed, updateroute) -- Waypoint number. --TODO: by default add after last AIR waypoint! Last WP could be landing... @@ -3672,9 +3690,19 @@ function FLIGHTGROUP:AddWaypointAir(coordinate, wpnumber, speed) task.waypoint=task.waypoint+1 end end + + -- Shift all mission waypoints after the inserted waypoint. + for _,_mission in pairs(self.missionqueue) do + local mission=_mission --#FLIGHTGROUP.Mission + if mission.status==FLIGHTGROUP.MissonStatus.SCHEDULED and mission.waypoint>=wpnumber then + mission.waypoint=mission.waypoint+1 + end + end -- Update route. - self:__UpdateRoute(-1) + if updateroute==nil or updateroute==true then + self:__UpdateRoute(-1) + end return self end