OPS Chief

This commit is contained in:
Frank 2021-08-06 10:01:23 +02:00
parent 4a56c7523d
commit ed402e2f5f
5 changed files with 113 additions and 34 deletions

View File

@ -642,6 +642,7 @@ function AIRWING:RemoveMission(Mission)
local mission=_mission --Ops.Auftrag#AUFTRAG local mission=_mission --Ops.Auftrag#AUFTRAG
if mission.auftragsnummer==Mission.auftragsnummer then if mission.auftragsnummer==Mission.auftragsnummer then
mission.airwing=nil
table.remove(self.missionqueue, i) table.remove(self.missionqueue, i)
break break
end end

View File

@ -91,6 +91,7 @@
-- @field #number artyRadius Radius in meters. -- @field #number artyRadius Radius in meters.
-- @field #number artyShots Number of shots fired. -- @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.WingCommander#WINGCOMMANDER wingcommander The WINGCOMMANDER managing this mission.
-- @field Ops.AirWing#AIRWING airwing The assigned airwing. -- @field Ops.AirWing#AIRWING airwing The assigned airwing.
-- @field #table assets Airwing Assets assigned for this mission. -- @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 targetname=self:GetTargetName() or "unknown"
local airwing=self.airwing and self.airwing.alias or "N/A" 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. -- 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 end
-- Group info. -- Group info.
@ -2205,11 +2206,6 @@ function AUFTRAG:onafterStatus(From, Event, To)
-- Ready to evaluate mission outcome? -- Ready to evaluate mission outcome?
local ready2evaluate=self.Tover and Tnow-self.Tover>=self.dTevaluate or false 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. -- Check if mission is OVER (done or cancelled) and enough time passed to evaluate the result.
if self:IsOver() and ready2evaluate then if self:IsOver() and ready2evaluate then
-- Evaluate success or failure of the mission. -- Evaluate success or failure of the mission.
@ -2714,11 +2710,17 @@ function AUFTRAG:onafterCancel(From, Event, To)
-- Not necessary to delay the evaluaton?! -- Not necessary to delay the evaluaton?!
self.dTevaluate=0 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: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 elseif self.airwing then
@ -2729,7 +2731,7 @@ function AUFTRAG:onafterCancel(From, Event, To)
else 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 for _,_groupdata in pairs(self.groupdata) do
local groupdata=_groupdata --#AUFTRAG.GroupData local groupdata=_groupdata --#AUFTRAG.GroupData
@ -2832,7 +2834,15 @@ function AUFTRAG:onafterRepeat(From, Event, To)
if self.chief then 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 elseif self.wingcommander then
@ -2849,6 +2859,7 @@ function AUFTRAG:onafterRepeat(From, Event, To)
else else
self:E(self.lid.."ERROR: Mission can only be repeated by a CHIEF, WINGCOMMANDER or AIRWING! Stopping AUFTRAG") self:E(self.lid.."ERROR: Mission can only be repeated by a CHIEF, WINGCOMMANDER or AIRWING! Stopping AUFTRAG")
self:Stop() self:Stop()
return
end end
@ -2882,19 +2893,27 @@ end
-- @param #string To To state. -- @param #string To To state.
function AUFTRAG:onafterStop(From, Event, To) 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)) 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. -- 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 if self.wingcommander then
self.wingcommander:RemoveMission(self) self.wingcommander:RemoveMission(self)
end end
-- Remove mission from AIRWING queue.
if self.airwing then if self.airwing then
self.airwing:RemoveMission(self) self.airwing:RemoveMission(self)
end end
-- Remove mission from OPSGROUP queue
for _,_groupdata in pairs(self.groupdata) do for _,_groupdata in pairs(self.groupdata) do
local groupdata=_groupdata --#AUFTRAG.GroupData local groupdata=_groupdata --#AUFTRAG.GroupData
groupdata.opsgroup:RemoveMission(self) groupdata.opsgroup:RemoveMission(self)

View File

@ -17,6 +17,7 @@
-- @field #number verbose Verbosity level. -- @field #number verbose Verbosity level.
-- @field #string lid Class id string for output to DCS log file. -- @field #string lid Class id string for output to DCS log file.
-- @field #table missionqueue Mission queue. -- @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 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 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. -- @field Core.Set#SET_ZONE engagezoneset Set of zones where enemies are actively engaged.
@ -42,11 +43,12 @@
-- @field #CHIEF -- @field #CHIEF
CHIEF = { CHIEF = {
ClassName = "CHIEF", ClassName = "CHIEF",
Debug = nil, verbose = 0,
lid = nil, lid = nil,
wingcommander = nil, wingcommander = nil,
admiral = nil, admiral = nil,
general = nil, general = nil,
targetqueue = {},
missionqueue = {}, missionqueue = {},
borderzoneset = nil, borderzoneset = nil,
yellowzoneset = nil, yellowzoneset = nil,
@ -88,8 +90,6 @@ CHIEF.version="0.0.1"
-- @return #CHIEF self -- @return #CHIEF self
function CHIEF:New(AgentSet, Coalition) function CHIEF:New(AgentSet, Coalition)
AgentSet=AgentSet or SET_GROUP:New()
-- Inherit everything from INTEL class. -- Inherit everything from INTEL class.
local self=BASE:Inherit(self, INTEL:New(AgentSet, Coalition)) --#CHIEF 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("*", "AssignMissionAirforce", "*") -- Assign mission to a WINGCOMMANDER.
self:AddTransition("*", "AssignMissionNavy", "*") -- Assign mission to an ADMIRAL. self:AddTransition("*", "AssignMissionNavy", "*") -- Assign mission to an ADMIRAL.
self:AddTransition("*", "AssignMissionArmy", "*") -- Assign mission to a GENERAL. 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("*", "Defcon", "*") -- Change defence condition.
self:AddTransition("*", "DeclareWar", "*") -- Declare War. self:AddTransition("*", "DeclareWar", "*") -- Declare War.
------------------------ ------------------------
@ -253,6 +256,8 @@ end
-- @return #CHIEF self -- @return #CHIEF self
function CHIEF:AddMission(Mission) function CHIEF:AddMission(Mission)
Mission.chief=self
table.insert(self.missionqueue, Mission) table.insert(self.missionqueue, Mission)
return self return self
@ -269,6 +274,7 @@ function CHIEF:RemoveMission(Mission)
if mission.auftragsnummer==Mission.auftragsnummer then 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)) 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) table.remove(self.missionqueue, i)
break break
end end
@ -278,6 +284,18 @@ function CHIEF:RemoveMission(Mission)
return self return self
end 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. --- Set border zone set.
-- @param #CHIEF self -- @param #CHIEF self
-- @param Core.Set#SET_ZONE BorderZoneSet Set of zones, defining our borders. -- @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. -- Clean up missions where the contact was lost.
for _,_contact in pairs(self.ContactsLost) do 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 if contact.mission and contact.mission:IsNotOver() then
@ -389,7 +407,7 @@ function CHIEF:onafterStatus(From, Event, To)
-- Create missions for all new contacts. -- Create missions for all new contacts.
local Nred=0 ; local Nyellow=0 ; local Nengage=0 local Nred=0 ; local Nyellow=0 ; local Nengage=0
for _,_contact in pairs(self.Contacts) do 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 group=contact.group --Wrapper.Group#GROUP
local inred=self:CheckGroupInBorder(group) local inred=self:CheckGroupInBorder(group)
@ -455,9 +473,26 @@ function CHIEF:onafterStatus(From, Event, To)
-- Check mission queue and assign one PLANNED mission. -- Check mission queue and assign one PLANNED mission.
self:CheckMissionQueue() 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) 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 -- Contacts
--- ---
@ -466,7 +501,7 @@ function CHIEF:onafterStatus(From, Event, To)
if #self.Contacts>0 then if #self.Contacts>0 then
local text="Contacts:" local text="Contacts:"
for i,_contact in pairs(self.Contacts) do for i,_contact in pairs(self.Contacts) do
local contact=_contact --#CHIEF.Contact local contact=_contact --Ops.Intelligence#INTEL.Contact
local mtext="N/A" local mtext="N/A"
if contact.mission then if contact.mission then
mtext=string.format("Mission %s (%s) %s", contact.mission.name, contact.mission.type, contact.mission.status:upper()) 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 end
--- On after "CancelMission" event. --- On after "MissionCancel" event.
-- @param #CHIEF self -- @param #CHIEF self
-- @param #string From From state. -- @param #string From From state.
-- @param #string Event Event. -- @param #string Event Event.
-- @param #string To To state. -- @param #string To To state.
-- @param Ops.Auftrag#AUFTRAG Mission The mission. -- @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)) 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. -- Mission is still in planning stage. Should not have an airbase assigned ==> Just remove it form the queue.
self:RemoveMission(Mission) self:RemoveMission(Mission)
-- Remove Mission from WC queue.
if Mission.wingcommander then
Mission.wingcommander:RemoveMission(Mission)
end
else else
-- Airwing will cancel mission. -- Wingcommander will cancel mission.
if Mission.airwing then if Mission.wingcommander then
Mission.airwing:MissionCancel(Mission) Mission.wingcommander:MissionCancel(Mission)
end end
end end
@ -694,6 +734,24 @@ function CHIEF:CheckGroupInZones(group, zoneset)
return false return false
end 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. --- Check resources.
-- @param #CHIEF self -- @param #CHIEF self
-- @return #table -- @return #table

View File

@ -95,9 +95,9 @@ INTEL = {
ContactsUnknown = {}, ContactsUnknown = {},
Clusters = {}, Clusters = {},
clustercounter = 1, clustercounter = 1,
clusterradius = 15, clusterradius = 15,
clusteranalysis = true, clusteranalysis = true,
clustermarkers = false, clustermarkers = false,
prediction = 300, prediction = 300,
} }

View File

@ -77,7 +77,7 @@ function WINGCOMMANDER:New()
self:AddTransition("*", "Stop", "Stopped") -- Stop WC. self:AddTransition("*", "Stop", "Stopped") -- Stop WC.
self:AddTransition("*", "AssignMission", "*") -- Mission was assigned to an AIRWING. self:AddTransition("*", "AssignMission", "*") -- Mission was assigned to an AIRWING.
self:AddTransition("*", "CancelMission", "*") -- Cancel mission. self:AddTransition("*", "MissionCancel", "*") -- Cancel mission.
------------------------ ------------------------
--- Pseudo Functions --- --- Pseudo Functions ---
@ -162,6 +162,7 @@ function WINGCOMMANDER:RemoveMission(Mission)
if mission.auftragsnummer==Mission.auftragsnummer then 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)) 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) table.remove(self.missionqueue, i)
break break
end end
@ -272,13 +273,13 @@ function WINGCOMMANDER:onafterAssignMission(From, Event, To, Airwing, Mission)
end end
--- On after "CancelMission" event. --- On after "MissionCancel" event.
-- @param #WINGCOMMANDER self -- @param #WINGCOMMANDER self
-- @param #string From From state. -- @param #string From From state.
-- @param #string Event Event. -- @param #string Event Event.
-- @param #string To To state. -- @param #string To To state.
-- @param Ops.Auftrag#AUFTRAG Mission The mission. -- @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)) 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. -- Airwing will cancel mission.
if Mission.airwing then if Mission.airwing then
Mission.airwing:CancelMission(Mission) Mission.airwing:MissionCancel(Mission)
end end
end end