diff --git a/Moose Development/Moose/Ops/AirWing.lua b/Moose Development/Moose/Ops/AirWing.lua index 58e8ebb95..65e01063b 100644 --- a/Moose Development/Moose/Ops/AirWing.lua +++ b/Moose Development/Moose/Ops/AirWing.lua @@ -642,6 +642,7 @@ function AIRWING:RemoveMission(Mission) local mission=_mission --Ops.Auftrag#AUFTRAG if mission.auftragsnummer==Mission.auftragsnummer then + mission.airwing=nil table.remove(self.missionqueue, i) break end diff --git a/Moose Development/Moose/Ops/Auftrag.lua b/Moose Development/Moose/Ops/Auftrag.lua index de8f0e82b..faaab5881 100644 --- a/Moose Development/Moose/Ops/Auftrag.lua +++ b/Moose Development/Moose/Ops/Auftrag.lua @@ -91,6 +91,7 @@ -- @field #number artyRadius Radius in meters. -- @field #number artyShots Number of shots fired. -- +-- @field Ops.ChiefOfStaff#CHIEF chief The CHIEF managing this mission. -- @field Ops.WingCommander#WINGCOMMANDER wingcommander The WINGCOMMANDER managing this mission. -- @field Ops.AirWing#AIRWING airwing The assigned airwing. -- @field #table assets Airwing Assets assigned for this mission. @@ -2185,10 +2186,10 @@ function AUFTRAG:onafterStatus(From, Event, To) local targetname=self:GetTargetName() or "unknown" local airwing=self.airwing and self.airwing.alias or "N/A" - local commander=self.wingcommander and tostring(self.wingcommander.coalition) or "N/A" + local chief=self.chief and tostring(self.chief.coalition) or "N/A" -- Info message. - self:I(self.lid..string.format("Status %s: Target=%s, T=%s-%s, assets=%d, groups=%d, targets=%d, wing=%s, commander=%s", self.status, targetname, Cstart, Cstop, #self.assets, Ngroups, Ntargets, airwing, commander)) + self:I(self.lid..string.format("Status %s: Target=%s, T=%s-%s, assets=%d, groups=%d, targets=%d, wing=%s, chief=%s", self.status, targetname, Cstart, Cstop, #self.assets, Ngroups, Ntargets, airwing, chief)) end -- Group info. @@ -2204,11 +2205,6 @@ function AUFTRAG:onafterStatus(From, Event, To) -- Ready to evaluate mission outcome? local ready2evaluate=self.Tover and Tnow-self.Tover>=self.dTevaluate or false - - --env.info("FF Tover="..tostring(self.Tover)) - --if self.Tover then - -- env.info("FF Tnow-Tover="..tostring(Tnow-self.Tover)) - --end -- Check if mission is OVER (done or cancelled) and enough time passed to evaluate the result. if self:IsOver() and ready2evaluate then @@ -2714,11 +2710,17 @@ function AUFTRAG:onafterCancel(From, Event, To) -- Not necessary to delay the evaluaton?! self.dTevaluate=0 - if self.wingcommander then + if self.chief then + + self:T(self.lid..string.format("Chief will cancel the mission. Will wait for mission DONE before evaluation!")) + + self.chief:MissionCancel(self) + + elseif self.wingcommander then self:T(self.lid..string.format("Wingcommander will cancel the mission. Will wait for mission DONE before evaluation!")) - self.wingcommander:CancelMission(self) + self.wingcommander:MissionCancel(self) elseif self.airwing then @@ -2729,7 +2731,7 @@ function AUFTRAG:onafterCancel(From, Event, To) else - self:T(self.lid..string.format("No airwing or wingcommander. Attached flights will cancel the mission on their own. Will wait for mission DONE before evaluation!")) + self:T(self.lid..string.format("No airwing, wingcommander or chief. Attached flights will cancel the mission on their own. Will wait for mission DONE before evaluation!")) for _,_groupdata in pairs(self.groupdata) do local groupdata=_groupdata --#AUFTRAG.GroupData @@ -2831,8 +2833,16 @@ function AUFTRAG:onafterRepeat(From, Event, To) self.repeated=self.repeated+1 if self.chief then - - --TODO + + -- Remove mission from wingcommander because Cheif will assign it again. + if self.wingcommander then + self.wingcommander:RemoveMission(self) + end + + -- Remove mission from airwing because WC will assign it again but maybe to a different wing. + if self.airwing then + self.airwing:RemoveMission(self) + end elseif self.wingcommander then @@ -2849,6 +2859,7 @@ function AUFTRAG:onafterRepeat(From, Event, To) else self:E(self.lid.."ERROR: Mission can only be repeated by a CHIEF, WINGCOMMANDER or AIRWING! Stopping AUFTRAG") self:Stop() + return end @@ -2882,19 +2893,27 @@ end -- @param #string To To state. function AUFTRAG:onafterStop(From, Event, To) + -- Debug info. self:I(self.lid..string.format("STOPPED mission in status=%s. Removing missions from queues. Stopping CallScheduler!", self.status)) - - -- TODO: remove missions from queues in WINGCOMMANDER, AIRWING and FLIGHGROUPS! + -- TODO: Mission should be OVER! we dont want to remove running missions from any queues. + -- Remove mission from CHIEF queue. + if self.chief then + self.chief:RemoveMission(self) + end + + -- Remove mission from WINGCOMMANDER queue. if self.wingcommander then self.wingcommander:RemoveMission(self) end + -- Remove mission from AIRWING queue. if self.airwing then self.airwing:RemoveMission(self) end + -- Remove mission from OPSGROUP queue for _,_groupdata in pairs(self.groupdata) do local groupdata=_groupdata --#AUFTRAG.GroupData groupdata.opsgroup:RemoveMission(self) diff --git a/Moose Development/Moose/Ops/ChiefOfStaff.lua b/Moose Development/Moose/Ops/ChiefOfStaff.lua index 69f644aa4..fcb26abc6 100644 --- a/Moose Development/Moose/Ops/ChiefOfStaff.lua +++ b/Moose Development/Moose/Ops/ChiefOfStaff.lua @@ -17,6 +17,7 @@ -- @field #number verbose Verbosity level. -- @field #string lid Class id string for output to DCS log file. -- @field #table missionqueue Mission queue. +-- @field #table targetqueue Target queue. -- @field Core.Set#SET_ZONE borderzoneset Set of zones defining the border of our territory. -- @field Core.Set#SET_ZONE yellowzoneset Set of zones defining the extended border. Defcon is set to YELLOW if enemy activity is detected. -- @field Core.Set#SET_ZONE engagezoneset Set of zones where enemies are actively engaged. @@ -42,11 +43,12 @@ -- @field #CHIEF CHIEF = { ClassName = "CHIEF", - Debug = nil, + verbose = 0, lid = nil, wingcommander = nil, admiral = nil, general = nil, + targetqueue = {}, missionqueue = {}, borderzoneset = nil, yellowzoneset = nil, @@ -88,8 +90,6 @@ CHIEF.version="0.0.1" -- @return #CHIEF self function CHIEF:New(AgentSet, Coalition) - AgentSet=AgentSet or SET_GROUP:New() - -- Inherit everything from INTEL class. local self=BASE:Inherit(self, INTEL:New(AgentSet, Coalition)) --#CHIEF @@ -108,8 +108,11 @@ function CHIEF:New(AgentSet, Coalition) self:AddTransition("*", "AssignMissionAirforce", "*") -- Assign mission to a WINGCOMMANDER. self:AddTransition("*", "AssignMissionNavy", "*") -- Assign mission to an ADMIRAL. self:AddTransition("*", "AssignMissionArmy", "*") -- Assign mission to a GENERAL. - self:AddTransition("*", "CancelMission", "*") -- Cancel mission. + + self:AddTransition("*", "MissionCancel", "*") -- Cancel mission. + self:AddTransition("*", "Defcon", "*") -- Change defence condition. + self:AddTransition("*", "DeclareWar", "*") -- Declare War. ------------------------ @@ -253,6 +256,8 @@ end -- @return #CHIEF self function CHIEF:AddMission(Mission) + Mission.chief=self + table.insert(self.missionqueue, Mission) return self @@ -269,6 +274,7 @@ function CHIEF:RemoveMission(Mission) if mission.auftragsnummer==Mission.auftragsnummer then self:I(self.lid..string.format("Removing mission %s (%s) status=%s from queue", Mission.name, Mission.type, Mission.status)) + Mission.chief=nil table.remove(self.missionqueue, i) break end @@ -278,6 +284,18 @@ function CHIEF:RemoveMission(Mission) return self end +--- Add target. +-- @param #CHIEF self +-- @param Ops.Target#TARGET Target Target object to be added. +-- @return #CHIEF self +function CHIEF:AddTarget(Target) + + table.insert(self.targetqueue, Target) + + return self +end + + --- Set border zone set. -- @param #CHIEF self -- @param Core.Set#SET_ZONE BorderZoneSet Set of zones, defining our borders. @@ -371,7 +389,7 @@ function CHIEF:onafterStatus(From, Event, To) -- Clean up missions where the contact was lost. for _,_contact in pairs(self.ContactsLost) do - local contact=_contact --#INTEL.Contact + local contact=_contact --Ops.Intelligence#INTEL.Contact if contact.mission and contact.mission:IsNotOver() then @@ -389,7 +407,7 @@ function CHIEF:onafterStatus(From, Event, To) -- Create missions for all new contacts. local Nred=0 ; local Nyellow=0 ; local Nengage=0 for _,_contact in pairs(self.Contacts) do - local contact=_contact --#CHIEF.Contact + local contact=_contact --Ops.Intelligence#INTEL.Contact local group=contact.group --Wrapper.Group#GROUP local inred=self:CheckGroupInBorder(group) @@ -455,8 +473,25 @@ function CHIEF:onafterStatus(From, Event, To) -- Check mission queue and assign one PLANNED mission. self:CheckMissionQueue() - local text=string.format("Defcon=%s Missions=%d Contacts: Total=%d Yellow=%d Red=%d", self.Defcon, #self.missionqueue, #self.Contacts, Nyellow, Nred) + local text=string.format("Defcon=%s Missions=%d, Contacts: Total=%d Yellow=%d Red=%d", self.Defcon, #self.missionqueue, #self.Contacts, Nyellow, Nred) self:I(self.lid..text) + + --- + -- Target Queue + --- + + for _,_target in pairs(self.targetqueue) do + local target=_target --Ops.Target#TARGET + + if target:IsAlive() then + + if self:CheckTargetInZones(target, self.borderzoneset) then + + end + + end + + end --- -- Contacts @@ -466,7 +501,7 @@ function CHIEF:onafterStatus(From, Event, To) if #self.Contacts>0 then local text="Contacts:" for i,_contact in pairs(self.Contacts) do - local contact=_contact --#CHIEF.Contact + local contact=_contact --Ops.Intelligence#INTEL.Contact local mtext="N/A" if contact.mission then mtext=string.format("Mission %s (%s) %s", contact.mission.name, contact.mission.type, contact.mission.status:upper()) @@ -512,13 +547,13 @@ function CHIEF:onafterAssignMissionAirforce(From, Event, To, Mission) end ---- On after "CancelMission" event. +--- On after "MissionCancel" event. -- @param #CHIEF self -- @param #string From From state. -- @param #string Event Event. -- @param #string To To state. -- @param Ops.Auftrag#AUFTRAG Mission The mission. -function CHIEF:onafterCancelMission(From, Event, To, Mission) +function CHIEF:onafterMissionCancel(From, Event, To, Mission) self:I(self.lid..string.format("Cancelling mission %s (%s) in status %s", Mission.name, Mission.type, Mission.status)) @@ -527,11 +562,16 @@ function CHIEF:onafterCancelMission(From, Event, To, Mission) -- Mission is still in planning stage. Should not have an airbase assigned ==> Just remove it form the queue. self:RemoveMission(Mission) + -- Remove Mission from WC queue. + if Mission.wingcommander then + Mission.wingcommander:RemoveMission(Mission) + end + else - -- Airwing will cancel mission. - if Mission.airwing then - Mission.airwing:MissionCancel(Mission) + -- Wingcommander will cancel mission. + if Mission.wingcommander then + Mission.wingcommander:MissionCancel(Mission) end end @@ -694,6 +734,24 @@ function CHIEF:CheckGroupInZones(group, zoneset) return false end +--- Check if group is inside a zone. +-- @param #CHIEF self +-- @param Ops.Target#TARGET target The target. +-- @param Core.Set#SET_ZONE zoneset Set of zones. +-- @return #boolean If true, group is in any zone. +function CHIEF:CheckTargetInZones(target, zoneset) + + for _,_zone in pairs(zoneset.Set or {}) do + local zone=_zone --Core.Zone#ZONE + + if zone:IsCoordinateInZone(target:GetCoordinate()) then + return true + end + end + + return false +end + --- Check resources. -- @param #CHIEF self -- @return #table diff --git a/Moose Development/Moose/Ops/Intelligence.lua b/Moose Development/Moose/Ops/Intelligence.lua index aee683f96..36ed8e635 100644 --- a/Moose Development/Moose/Ops/Intelligence.lua +++ b/Moose Development/Moose/Ops/Intelligence.lua @@ -95,9 +95,9 @@ INTEL = { ContactsUnknown = {}, Clusters = {}, clustercounter = 1, - clusterradius = 15, - clusteranalysis = true, - clustermarkers = false, + clusterradius = 15, + clusteranalysis = true, + clustermarkers = false, prediction = 300, } diff --git a/Moose Development/Moose/Ops/WingCommander.lua b/Moose Development/Moose/Ops/WingCommander.lua index 78e6179fd..5074de99d 100644 --- a/Moose Development/Moose/Ops/WingCommander.lua +++ b/Moose Development/Moose/Ops/WingCommander.lua @@ -77,7 +77,7 @@ function WINGCOMMANDER:New() self:AddTransition("*", "Stop", "Stopped") -- Stop WC. self:AddTransition("*", "AssignMission", "*") -- Mission was assigned to an AIRWING. - self:AddTransition("*", "CancelMission", "*") -- Cancel mission. + self:AddTransition("*", "MissionCancel", "*") -- Cancel mission. ------------------------ --- Pseudo Functions --- @@ -162,6 +162,7 @@ function WINGCOMMANDER:RemoveMission(Mission) if mission.auftragsnummer==Mission.auftragsnummer then self:I(self.lid..string.format("Removing mission %s (%s) status=%s from queue", Mission.name, Mission.type, Mission.status)) + mission.wingcommander=nil table.remove(self.missionqueue, i) break end @@ -272,13 +273,13 @@ function WINGCOMMANDER:onafterAssignMission(From, Event, To, Airwing, Mission) end ---- On after "CancelMission" event. +--- On after "MissionCancel" event. -- @param #WINGCOMMANDER self -- @param #string From From state. -- @param #string Event Event. -- @param #string To To state. -- @param Ops.Auftrag#AUFTRAG Mission The mission. -function WINGCOMMANDER:onafterCancelMission(From, Event, To, Mission) +function WINGCOMMANDER:onafterMissionCancel(From, Event, To, Mission) self:I(self.lid..string.format("Cancelling mission %s (%s) in status %s", Mission.name, Mission.type, Mission.status)) @@ -291,7 +292,7 @@ function WINGCOMMANDER:onafterCancelMission(From, Event, To, Mission) -- Airwing will cancel mission. if Mission.airwing then - Mission.airwing:CancelMission(Mission) + Mission.airwing:MissionCancel(Mission) end end