From 6305459056a7b586001bc1abbc8fdba0310f32d3 Mon Sep 17 00:00:00 2001 From: Frank Date: Tue, 10 Mar 2020 17:03:24 +0100 Subject: [PATCH] Ops --- Moose Development/Moose/Ops/AirWing.lua | 77 ++++-- Moose Development/Moose/Ops/Auftrag.lua | 258 +++++++++++++++++- Moose Development/Moose/Ops/FlightGroup.lua | 85 +++++- Moose Development/Moose/Ops/Intelligence.lua | 2 - Moose Development/Moose/Ops/Squadron.lua | 10 +- Moose Development/Moose/Ops/WingCommander.lua | 63 +---- 6 files changed, 409 insertions(+), 86 deletions(-) diff --git a/Moose Development/Moose/Ops/AirWing.lua b/Moose Development/Moose/Ops/AirWing.lua index 434e29d0e..03c76456d 100644 --- a/Moose Development/Moose/Ops/AirWing.lua +++ b/Moose Development/Moose/Ops/AirWing.lua @@ -417,18 +417,38 @@ function AIRWING:SetNumberAWACS(n) end ---- Add a patrol Point for CAP missions. +--- Create a new generic patrol point. -- @param #AIRWING self --- @param Core.Zone#ZONE AcceptZone Add a zone to the CAP zone set. --- @return #AIRWING self -function AIRWING:AddPatrolPointCAP(Coordinate, Heading, Leg, Speed) - +-- @param Core.Point#COORDINATE Coordinate Coordinate of the patrol point. +-- @param #number Heading Heading in degrees. +-- @param #number LegLength Length of race-track orbit in NM. +-- @param #number Altitude Orbit altitude in feet. +-- @param #number Speed Orbit speed in knots. +-- @return #AIRWING.PatrolData Patrol point table. +function AIRWING:NewPatrolPoint(Coordinate, Heading, LegLength, Altitude, Speed) + local cappoint={} --#AIRWING.PatrolData cappoint.coord=Coordinate cappoint.heading=Heading or 090 - cappoint.leg=Leg or 15 + cappoint.leg=LegLength or 15 + cappoint.altitude=Altitude cappoint.speed=Speed or 350 + return cappoint +end + +--- Add a patrol Point for CAP missions. +-- @param #AIRWING self +-- @param Core.Point#COORDINATE Coordinate Coordinate of the patrol point. +-- @param #number Heading Heading in degrees. +-- @param #number LegLength Length of race-track orbit in NM. +-- @param #number Altitude Orbit altitude in feet. +-- @param #number Speed Orbit speed in knots. +-- @return #AIRWING self +function AIRWING:AddPatrolPointCAP(Coordinate, Heading, LegLength, Altitude, Speed) + + local cappoint=self:NewPatrolPoint(Coordinate, Heading, LegLength, Speed, Altitude, LegLength) + table.insert(self.cappoints, cappoint) return self @@ -473,7 +493,7 @@ function AIRWING:onafterStatus(From, Event, To) local fsmstate=self:GetState() -- Check CAP missions. - --self:CheckCAP() + self:CheckCAP() --self:CheckTANKER() @@ -798,6 +818,9 @@ function AIRWING:onafterMissionCancel(From, Event, To, Mission) if flightgroup then flightgroup:MissionCancel(Mission) end + + -- Not requested any more (if it was). + asset.requested=nil end -- Remove queued request (if any). @@ -890,7 +913,7 @@ function AIRWING:onafterAssetSpawned(From, Event, To, group, asset, request) -- Add mission to flightgroup queue. if mission then - -- Add mission to flightgroup queue. + -- Add mission to flightgroup queue. asset.flightgroup:AddMission(mission) end @@ -916,7 +939,12 @@ function AIRWING:onafterAssetDead(From, Event, To, asset, request) -- Add group to the detection set of the WINGCOMMANDER. if self.wingcommander then self.wingcommander.detectionset:RemoveGroupsByName({asset.spawngroupname}) - end + end + + --TODO: remove asset from mission. + --local mission=self:GetAssetCurrentMission(asset) + + --TODO: remove asset from squadron. end @@ -1032,18 +1060,14 @@ end -- @return #boolean If true, Squadron can do that type of mission. Available assets are not checked. -- @return #table Assets that can do the required mission. function AIRWING:SquadronCanMission(Squadron, MissionType, Nassets) - - local cando=true + + -- Assets available for this mission. local assets={} -- WARNING: This assumes that all assets of the squad can do the same mission types! - -- TODO: we could make the mission type as a parameter of the assets! Then we can have heterogenious squads as well! - local gotit=self:CheckMissionType(MissionType, Squadron.missiontypes) + local cando=self:CheckMissionType(MissionType, Squadron.missiontypes) - if not gotit then - -- This squad cannot do this mission. - cando=false - else + if cando then for _,_asset in pairs(Squadron.assets) do local asset=_asset --#AIRWING.SquadronAsset @@ -1056,7 +1080,7 @@ function AIRWING:SquadronCanMission(Squadron, MissionType, Nassets) --- --TODO: This only checks if it has an ORBIT mission. It could have others as well! - if self:IsAssetOnMission(asset, AUFTRAG.Type.ORBIT) and MissionType~=AUFTRAG.Type.ORBIT then + if self:IsAssetOnMission(asset, AUFTRAG.Type.PATROL) and MissionType~=AUFTRAG.Type.PATROL then -- Check if the payload of this asset is compatible with the mission. if self:CheckMissionType(MissionType, asset.payload.missiontypes) then @@ -1137,6 +1161,23 @@ function AIRWING:IsAssetOnMission(asset, MissionTypes) end end + + -- Alternative: run over all missions and compare to mission assets. + for _,_mission in pairs(self.missionqueue) do + local mission=_mission --Ops.Auftrag#AUFTRAG + + if mission:IsNotOver() then + for _,_asset in pairs(mission.assets) do + local sqasset=_asset --#AIRWING.SquadronAsset + + if sqasset.uid==asset.uid then + return true + end + + end + end + + end return false end diff --git a/Moose Development/Moose/Ops/Auftrag.lua b/Moose Development/Moose/Ops/Auftrag.lua index 06fdf9378..4c6b7c5b0 100644 --- a/Moose Development/Moose/Ops/Auftrag.lua +++ b/Moose Development/Moose/Ops/Auftrag.lua @@ -64,6 +64,9 @@ -- -- @field #number missionAltitude Mission altitude in meters. -- +-- @field #number missionRepeated Number of times mission was repeated. +-- @field #number missionRepeatMax Number of times mission is repeated if failed. +-- -- @field #number optionROE ROE. -- @field #number optionROT ROT. -- @field #number optionCM Counter measures. @@ -252,6 +255,9 @@ function AUFTRAG:New(Type) self:SetPriority() self:SetMissionTime() + self.missionRepeated=0 + self.missionRepeatMax=1 + -- FMS start state is PLANNED. self:SetStartState(self.status) @@ -269,12 +275,22 @@ function AUFTRAG:New(Type) self:AddTransition("*", "Done", AUFTRAG.Status.DONE) -- All assets have reported that mission is done. self:AddTransition("*", "Cancel", AUFTRAG.Status.CANCELLED) -- Command to cancel the mission. - self:AddTransition("*", "Accomplished", AUFTRAG.Status.SUCCESS) + self:AddTransition("*", "Success", AUFTRAG.Status.SUCCESS) self:AddTransition("*", "Failed", AUFTRAG.Status.FAILED) self:AddTransition("*", "Status", "*") self:AddTransition("*", "Stop", "Stopped") + self:AddTransition("*", "Repeat", AUFTRAG.Status.PLANNED) + + self:AddTransition("*", "AssetDead", "*") + + --[[ + self:HandleEvent(EVENTS.PilotDead, self._UnitDead) + self:HandleEvent(EVENTS.Ejection, self._UnitDead) + self:HandleEvent(EVENTS.Crash, self._UnitDead) + ]] + self:__Status(-1) return self @@ -471,6 +487,69 @@ function AUFTRAG:NewBAI(TargetGroupSet) return mission end +--- Create a mission to attack a group. Mission type is automatically chosen from the group category. +-- @param #AUFTRAG self +-- @param Wrapper.Group#GROUP EngageGroup Group to be engaged. +-- @return #AUFTRAG self +function AUFTRAG:NewAUTO(EngageGroup) + + local mission=nil --#AUFTRAG + + local group=EngageGroup + + if group and group:IsAlive() then + + local category=group:GetCategory() + local attribute=group:GetAttribute() + local threatlevel=group:GetThreatLevel() + + if category==Group.Category.AIRPLANE or category==Group.Category.HELICOPTER then + + mission=AUFTRAG:NewINTERCEPT(group) + + elseif category==Group.Category.GROUND then + + --TODO: action depends on type + -- AA/SAM ==> SEAD + -- Tanks ==> + -- Artillery ==> + -- Infantry ==> + -- + + if attribute==GROUP.Attribute.GROUND_AAA or attribute==GROUP.Attribute.GROUND_SAM then + + --TODO: SEAD/DEAD + + end + + mission=AUFTRAG:NewBAI(group) + + + elseif category==Group.Category.SHIP then + + --TODO: ANTISHIP + + local TargetUnitSet=SET_UNIT:New() + + for _,_unit in pairs(group:GetUnits()) do + local unit=_unit --Wrapper.Unit#UNIT + if unit and unit:IsAlive() and unit:GetThreatLevel()>0 then + TargetUnitSet:AddUnit(unit) + end + end + + if TargetUnitSet:Count()>0 then + mission=AUFTRAG:NewANTISHIP(TargetUnitSet) + end + + end + end + + return mission +end + + + ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- User API Functions ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -545,6 +624,20 @@ function AUFTRAG:SetWeaponType(WeaponType) return self end +--- Set number of weapons to expend. +-- @param #AUFTRAG self +-- @param #number WeaponType Weapon type. Default is ENUMS.WeaponFlag.Auto +-- @return #AUFTRAG self +function AUFTRAG:SetWeaponExpend(WeaponExpend) + + self.engageWeaponExpend=WeaponExpend or "Auto" + + -- Update the DCS task parameter. + self.DCStask=self:GetDCSMissionTask() + + return self +end + --- Set mission altitude. -- @param #AUFTRAG self -- @param #string Altitude Altitude in feet. @@ -554,9 +647,9 @@ function AUFTRAG:SetMissionAltitude(Altitude) return self end ---- Set Rules of Engagement for this mission. +--- Set Rules of Engagement (ROE) for this mission. -- @param #AUFTRAG self --- @param #number roe ROE +-- @param #string roe Mision ROE. -- @return #AUFTRAG self function AUFTRAG:SetROE(roe) @@ -566,6 +659,18 @@ function AUFTRAG:SetROE(roe) end +--- Set Reaction on Threat (ROT) for this mission. +-- @param #AUFTRAG self +-- @param #string roe Mision ROT. +-- @return #AUFTRAG self +function AUFTRAG:SetROE(rot) + + self.optionROT=rot + + return self +end + + --- Add a flight group to the mission. -- @param #AUFTRAG self -- @param Ops.FlightGroup#FLIGHTGROUP FlightGroup The FLIGHTGROUP object. @@ -675,6 +780,10 @@ function AUFTRAG:onafterStatus(From, Event, To) self:Cancel() end + if self:IsNotOver() and #self.assets==0 then + self:Cancel() + end + -- Check if ALL flights are done with their mission. if self:IsNotOver() and self:CheckFlightsDone() then self:Done() @@ -695,12 +804,13 @@ function AUFTRAG:onafterStatus(From, Event, To) self:E(self.lid..string.format("ERROR: FSM state %s != %s mission status!", fsmstate, self.status)) end - -- Check if mission is OVER. if self:IsOver() then -- TODO: evaluate mission result. self.Ntargets>0 and Ntargets=? -- TODO: if failed, repeat mission, i.e. set status to PLANNED? if success, stop and remove from ALL queues. - self:Stop() + --self:Stop() + + self:Evaluate() else self:__Status(-30) end @@ -712,6 +822,12 @@ end function AUFTRAG:Evaluate() local Ntargets=self:CountMissionTargets() + + if self.Ntargets>Ntargets then + self:Failed() + else + self:Success() + end end @@ -801,6 +917,34 @@ function AUFTRAG:CheckFlightsDone() return done end +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +-- EVENT Functions +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +--- Flightgroup event function handling the crash of a unit. +-- @param #FLIGHTGROUP self +-- @param Core.Event#EVENTDATA EventData Event data. +function AUFTRAG:OnEventCrash(EventData) + + -- Check that this is the right group. + if EventData and EventData.IniGroup and EventData.IniUnit and EventData.IniGroupName and EventData.IniGroupName==self.groupname then + local unit=EventData.IniUnit + local group=EventData.IniGroup + local unitname=EventData.IniUnitName + + -- Get element. + local element=self:GetElementByName(unitname) + + if element then + self:T3(self.lid..string.format("EVENT: Element %s crashed ==> dead", element.name)) + self:ElementDead(element) + end + + end + +end + + ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- FSM Functions ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -879,6 +1023,35 @@ function AUFTRAG:onafterDone(From, Event, To) self:I(self.lid..string.format("New mission status=%s", self.status)) end +--- On after "AssetDead" event. +-- @param #AUFTRAG self +-- @param #string From From state. +-- @param #string Event Event. +-- @param #string To To state. +-- @param Ops.AirWing#AIRWING.SquadronAsset +function AUFTRAG:onafterAssetDead(From, Event, To, Asset) + + -- Delete asset from mission. + self:DelAsset(Asset) + + -- All assets dead? + if #self.assets==0 then + + if self:IsNotOver() then + + -- Mission failed. + self:Failed() + + else + + self:Stop() + + end + end + +end + + --- On after "Cancel" event. Cancells the mission. -- @param #AUFTRAG self -- @param #string From From state. @@ -905,6 +1078,61 @@ function AUFTRAG:onafterCancel(From, Event, To) end +--- On after "Failed" event. +-- @param #AUFTRAG self +-- @param #string From From state. +-- @param #string Event Event. +-- @param #string To To state. +function AUFTRAG:onafterFailed(From, Event, To) + + self.status=AUFTRAG.Status.FAILED + self:I(self.lid..string.format("New mission status=%s", self.status)) + + if self.missionRepeated>=self.missionRepeatMax then + + self:Stop() + + else + + -- Repeat mission. + self:Repeat() + + end + +end + + +--- On after "Repeat" event. +-- @param #AUFTRAG self +-- @param #string From From state. +-- @param #string Event Event. +-- @param #string To To state. +function AUFTRAG:onafterRepeat(From, Event, To) + + -- Increase repeat counter. + self.missionRepeated=self.missionRepeated+1 + + if self.wingcommander then + + elseif self.airwing then + + + end + +end + +--- On after "Success" event. +-- @param #AUFTRAG self +-- @param #string From From state. +-- @param #string Event Event. +-- @param #string To To state. +function AUFTRAG:onafterSuccess(From, Event, To) + + self.status=AUFTRAG.Status.SUCCESS + self:I(self.lid..string.format("New mission status=%s", self.status)) + +end + --- On after "Stop" event. Remove mission from AIRWING and FLIGHTGROUP mission queues. -- @param #AUFTRAG self -- @param #string From From state. @@ -914,6 +1142,8 @@ function AUFTRAG:onafterStop(From, Event, To) -- 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. + if self.wingcommander then end @@ -966,6 +1196,24 @@ function AUFTRAG:DelAsset(Asset) return self end +--- Get asset by its spawn group name. +-- @param #AUFTRAG self +-- @param #string Name Asset spawn group name. +-- @return Ops.AirWing#AIRWING.SquadronAsset +function AUFTRAG:GetAssetByName(Name) + + for i,_asset in pairs(self.assets or {}) do + local asset=_asset --Ops.AirWing#AIRWING.SquadronAsset + + if asset.spawngroupname==Name then + return asset + end + + end + + return nil +end + --- Count alive mission targets. -- @param #AUFTRAG self diff --git a/Moose Development/Moose/Ops/FlightGroup.lua b/Moose Development/Moose/Ops/FlightGroup.lua index 6bbadfb6c..fc87e4611 100644 --- a/Moose Development/Moose/Ops/FlightGroup.lua +++ b/Moose Development/Moose/Ops/FlightGroup.lua @@ -69,6 +69,12 @@ -- @field #number CallsignName Call sign name. -- @field #number CallsignNumber Call sign number. -- @field #boolean EPLRS If true, turn EPLRS data link on. +-- +-- @field #string ROEdefault Default ROE setting. +-- @field #string ROTdefault Default ROT setting. +-- @field #string ROEcurrent Current ROE setting. +-- @field #string ROTcurrent Current ROT setting. +-- -- @extends Core.Fsm#FSM --- *To invent an airplane is nothing. To build one is something. To fly is everything.* -- Otto Lilienthal @@ -313,6 +319,34 @@ FLIGHTGROUP.TaskType={ -- @field #number WaypointIndex Waypoint number at which the enroute task is added. +--- Rules of Engagement (ROE). +-- @type FLIGHTGROUP.ROE +-- @field #string RETURNFIRE +-- @field #string WEAPONFREE +-- @field #string WEAPONHOLD +FLIGHTGROUP.ROE={ + WEAPONFREE="weapon_free", + OPENFIREPRIO="open_fire_prio_designated", + OPENFIREDESIG="open_fire_only_designated", + RETURNFIRE="return_fire", + WEAPONHOLD="weapon_hold", +} + +--- Reaction on Threat (ROT). +-- @type FLIGHTGROUP.ROT +-- @field #string NOREACT No defensive actions will take place to counter threats. +-- @field #string PASSIVE AI will use jammers and other countermeasures in an attempt to defeat the threat. AI will not attempt a maneuver to defeat a threat. +-- @field #string EVADE AI will react by performing defensive maneuvers against incoming threats, AI will also use passive defense. +-- @field #string BYPASS aI will attempt to avoid enemy threat zones all together. This includes attempting to fly above or around threats. +-- @field #string ABORT If a threat is deemed severe enough the AI will abort its mission and return to base. +FLIGHTGROUP.ROT={ + NOREACT="no_reaction", + PASSIVE="weapon_free", + EVADE="return_fire", + BYPASS="bypass_and_escape", + ABORT="allow_abort_mission", +} + --- FLIGHTGROUP class version. -- @field #string version FLIGHTGROUP.version="0.3.4" @@ -1980,7 +2014,12 @@ function FLIGHTGROUP:onafterFlightSpawned(From, Event, To) self:T(self.lid..string.format("Flight spawned!")) -- F10 menu. - if not self.ai then + if self.ai then + + + + + else self.menu=self.menu or {} self.menu.atc=self.menu.atc or {} self.menu.atc.root=self.menu.atc.root or MENU_GROUP:New(self.group, "ATC") @@ -2148,7 +2187,17 @@ function FLIGHTGROUP:onafterFlightDead(From, Event, To) if self.flightcontrol then self.flightcontrol:_RemoveFlight(self) self.flightcontrol=nil - end + end + + for _,_mission in pairs(self.missionqueue) do + local mission=_mission --Ops.Auftrag#AUFTRAG + + local asset=mission:GetAssetByName(self.groupname) + if asset then + mission:AssetDead(asset) + end + + end -- Stop self:Stop() @@ -5186,6 +5235,38 @@ function FLIGHTGROUP:_GetTerminal(_attribute, _category) return _terminal end +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +-- OPTION FUNCTIONS +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +--- Set ROE for a group. +-- @param #FLIGHTGROUP self +-- @param #string roe ROE of group. Default is FLIGHTGROUP.ROE.HOLDFIRE. +function FLIGHTGROUP:SetOptionROE(roe) + if roe==FLIGHTGROUP.ROE.RETURNFIRE then + self.group:OptionROEReturnFire() + elseif roe==FLIGHTGROUP.ROE.WEAPONFREE then + self.group:OptionROEWeaponFree() + else + self.group:OptionROEHoldFire() + end + self.ROEcurrent=roe +end + + +--- Set ROT for a group. +-- @param #FLIGHTGROUP self +-- @param #string rot ROT of group. +function FLIGHTGROUP:SetOptionROT(rot) + if rot==FLIGHTGROUP.ROT.PASSIVE then + self.group:OptionROTPassiveDefense() + elseif self.rot==FLIGHTGROUP.ROT.NOREACT then + self.group:OptionROTEvadeFire() + else + self.group:OptionROTNoReaction() + end +end + ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- MENU FUNCTIONS diff --git a/Moose Development/Moose/Ops/Intelligence.lua b/Moose Development/Moose/Ops/Intelligence.lua index a84933280..645f20bf3 100644 --- a/Moose Development/Moose/Ops/Intelligence.lua +++ b/Moose Development/Moose/Ops/Intelligence.lua @@ -313,7 +313,6 @@ function INTEL:UpdateIntel() end -- TODO: Filter units from reject zones. - -- TODO: Filter unit types. -- TODO: Filter detection methods? local remove={} for _,_unit in pairs(DetectedSet.Set) do @@ -358,7 +357,6 @@ function INTEL:UpdateIntel() for _,unitname in pairs(remove) do DetectedSet:Remove(unitname, true) end - --DetectedSet:RemoveUnitsByName(remove) -- Create detected contacts. self:CreateDetectedItems(DetectedSet) diff --git a/Moose Development/Moose/Ops/Squadron.lua b/Moose Development/Moose/Ops/Squadron.lua index 75c5f3a72..5b314c385 100644 --- a/Moose Development/Moose/Ops/Squadron.lua +++ b/Moose Development/Moose/Ops/Squadron.lua @@ -64,19 +64,21 @@ SQUADRON.version="0.0.2" --- Create a new SQUADRON object and start the FSM. -- @param #SQUADRON self --- @param #string SquadName Name of the squadron, e.g. "VFA-37". --- @param #table tasks Table of squadron tasks, e.g. `{SQUADRON.Task.INTERCEPT, SQUADRON.Task.SEAD}`. +-- @param #string SquadronName Name of the squadron, e.g. "VFA-37". +-- @param #string TemplateGroupName Name of the template group. -- @return #SQUADRON self function SQUADRON:New(SquadronName, TemplateGroupName) -- Inherit everything from FSM class. local self=BASE:Inherit(self, FSM:New()) -- #SQUADRON + self.templatename=TemplateGroupName + --self.flightgroup=AIGroup - self.name=tostring(SquadronName) + self.name=tostring(SquadronName or TemplateGroupName) -- Set some string id for output to DCS.log file. - self.sid=string.format("SQUADRON %s | ", self.squadronname) + self.lid=string.format("SQUADRON %s | ", self.squadronname) -- Start State. self:SetStartState("Stopped") diff --git a/Moose Development/Moose/Ops/WingCommander.lua b/Moose Development/Moose/Ops/WingCommander.lua index fcf3e2863..0e2a54f9d 100644 --- a/Moose Development/Moose/Ops/WingCommander.lua +++ b/Moose Development/Moose/Ops/WingCommander.lua @@ -246,65 +246,18 @@ function WINGCOMMANDER:onafterStatus(From, Event, To) local contact=_contact --#WINGCOMMANDER.Contact local group=contact.group --Wrapper.Group#GROUP - if group and group:IsAlive() then + -- Create a mission based on group category. + local mission=AUFTRAG:NewAUTO(group) - local category=group:GetCategory() - local attribute=group:GetAttribute() - local threatlevel=group:GetThreatLevel() - - local mission=nil --Ops.Auftrag#AUFTRAG - - if category==Group.Category.AIRPLANE or category==Group.Category.HELICOPTER then - - mission=AUFTRAG:NewINTERCEPT(group) - - elseif category==Group.Category.GROUND then - - --TODO: action depends on type - -- AA/SAM ==> SEAD - -- Tanks ==> - -- Artillery ==> - -- Infantry ==> - -- - - if attribute==GROUP.Attribute.GROUND_AAA or attribute==GROUP.Attribute.GROUND_SAM then - - --TODO: SEAD/DEAD - - end - - mission=AUFTRAG:NewBAI(group) - - - elseif category==Group.Category.SHIP then - - --TODO: ANTISHIP - - local TargetUnitSet=SET_UNIT:New() - - for _,_unit in pairs(group:GetUnits()) do - local unit=_unit --Wrapper.Unit#UNIT - if unit and unit:IsAlive() and unit:GetThreatLevel()>0 then - TargetUnitSet:AddUnit(unit) - end - end - - if TargetUnitSet:Count()>0 then - mission=AUFTRAG:NewANTISHIP(TargetUnitSet) - end - - end - + + -- Add mission to queue. + if mission then + mission.nassets=1 + contact.mission=mission -- Add mission to queue. - if mission then - mission.nassets=1 - contact.mission=mission - self:AddMission(mission) - end - + self:AddMission(mission) end - end