From f3a2cf728491312c813a6b02110ea6c13b37cab4 Mon Sep 17 00:00:00 2001 From: Frank Date: Fri, 15 Jan 2021 00:59:52 +0100 Subject: [PATCH] Patrol - Added `FLIGHTGROUP:SetEngageDetectedOn()` - AUFTRAG patrol zone. --- Moose Development/Moose/Ops/ArmyGroup.lua | 2 +- Moose Development/Moose/Ops/Auftrag.lua | 46 ++++- Moose Development/Moose/Ops/FlightGroup.lua | 177 ++++++++++++++++++-- Moose Development/Moose/Ops/OpsGroup.lua | 80 ++++++--- 4 files changed, 268 insertions(+), 37 deletions(-) diff --git a/Moose Development/Moose/Ops/ArmyGroup.lua b/Moose Development/Moose/Ops/ArmyGroup.lua index 28857197e..f27cd357a 100644 --- a/Moose Development/Moose/Ops/ArmyGroup.lua +++ b/Moose Development/Moose/Ops/ArmyGroup.lua @@ -830,7 +830,7 @@ function ARMYGROUP:onafterEngageTarget(From, Event, To, Target) end ---- On after "EngageTarget" event. +--- Update engage target. -- @param #ARMYGROUP self function ARMYGROUP:_UpdateEngageTarget() diff --git a/Moose Development/Moose/Ops/Auftrag.lua b/Moose Development/Moose/Ops/Auftrag.lua index b7e19f41c..2711c190a 100644 --- a/Moose Development/Moose/Ops/Auftrag.lua +++ b/Moose Development/Moose/Ops/Auftrag.lua @@ -315,6 +315,7 @@ _AUFTRAGSNR=0 -- @field #string TANKER Tanker mission. -- @field #string TROOPTRANSPORT Troop transport mission. -- @field #string ARTY Fire at point. +-- @field #string PATROLZONE Patrol a zone. AUFTRAG.Type={ ANTISHIP="Anti Ship", AWACS="AWACS", @@ -338,6 +339,7 @@ AUFTRAG.Type={ TANKER="Tanker", TROOPTRANSPORT="Troop Transport", ARTY="Fire At Point", + PATROLZONE="Patrol Zone", } --- Mission status. @@ -1191,6 +1193,28 @@ function AUFTRAG:NewARTY(Target, Nshots, Radius) return mission end +--- Create a PATROLZONE mission. Group(s) will go to the zone and patrol it randomly. +-- @param #AUFTRAG self +-- @param Core.Zone#ZONE Zone The patrol zone. +-- @return #AUFTRAG self +function AUFTRAG:NewPATROLZONE(Zone) + + local mission=AUFTRAG:New(AUFTRAG.Type.PATROLZONE) + + mission:_TargetFromObject(Zone) + + mission.optionROE=ENUMS.ROE.OpenFire + mission.optionROT=ENUMS.ROT.PassiveDefense + mission.optionAlarm=ENUMS.AlarmState.Auto + + mission.missionFraction=1.0 + + mission.DCStask=mission:GetDCSMissionTask() + + return mission +end + + --- Create a mission to attack a group. Mission type is automatically chosen from the group category. -- @param #AUFTRAG self -- @param Ops.Target#TARGET Target The target. @@ -2926,7 +2950,7 @@ end -- @param #AUFTRAG self -- @return Wrapper.Positionable#POSITIONABLE The target object. Could be many things. function AUFTRAG:GetObjective() - return self:GetTargetData().Target + return self:GetTargetData():GetObject() end --- Get type of target. @@ -3388,6 +3412,26 @@ function AUFTRAG:GetDCSMissionTask(TaskControllable) local DCStask=CONTROLLABLE.TaskFireAtPoint(nil, self:GetTargetVec2(), self.artyRadius, self.artyShots, self.engageWeaponType) table.insert(DCStasks, DCStask) + + elseif self.type==AUFTRAG.Type.PATROLZONE then + + ------------------------- + -- PATROL ZONE Mission -- + ------------------------- + + local DCStask={} + + DCStask.id="PatrolZone" + + -- We create a "fake" DCS task and pass the parameters to the FLIGHTGROUP. + local param={} + param.zonename=self:GetTargetName() + param.zone=self:GetObjective() + param.altitude=70 + + DCStask.params=param + + table.insert(DCStasks, DCStask) else self:E(self.lid..string.format("ERROR: Unknown mission task!")) diff --git a/Moose Development/Moose/Ops/FlightGroup.lua b/Moose Development/Moose/Ops/FlightGroup.lua index 1d64e7e22..5a8d8cc68 100644 --- a/Moose Development/Moose/Ops/FlightGroup.lua +++ b/Moose Development/Moose/Ops/FlightGroup.lua @@ -512,6 +512,41 @@ function FLIGHTGROUP:SetFuelCriticalRTB(switch) return self end +--- Enable to automatically engage detected targets. +-- @param #FLIGHTGROUP self +-- @param #number RangeMax Max range in NM. Only detected targets within this radius will be engaged. Default is 25 NM. +-- @param #table TargetTypes Types of target attributes that will be engaged. See [DCS enum attributes](https://wiki.hoggitworld.com/view/DCS_enum_attributes). Default "All". +-- @param Core.Set#SET_ZONE EngageZoneSet Set of zones in which targets are engaged. Default is anywhere. +-- @param Core.Set#SET_ZONE NoEngageZoneSet Set of zones in which targets are *not* engaged. Default is nowhere. +-- @return #OPSGROUP self +function FLIGHTGROUP:SetEngageDetectedOn(RangeMax, TargetTypes, EngageZoneSet, NoEngageZoneSet) + + if TargetTypes then + if type(TargetTypes)~="table" then + TargetTypes={TargetTypes} + end + else + TargetTypes={"All"} + end + + self.engagedetectedOn=true + self.engagedetectedRmax=UTILS.NMToMeters(RangeMax or 25) + self.engagedetectedTypes=TargetTypes + self.engagedetectedEngageZones=EngageZoneSet + self.engagedetectedNoEngageZones=NoEngageZoneSet + + return self +end + +--- Disable to automatically engage detected targets. +-- @param #FLIGHTGROUP self +-- @return #OPSGROUP self +function FLIGHTGROUP:SetEngageDetectedOff() + self.engagedetectedOn=false +end + + + --- Enable that the group is despawned after landing. This can be useful to avoid DCS taxi issues with other AI or players or jamming taxiways. -- @param #FLIGHTGROUP self -- @return #FLIGHTGROUP self @@ -976,6 +1011,87 @@ function FLIGHTGROUP:onafterStatus(From, Event, To) self:ClearToLand() end end + + if self:IsAirborne() and self.detectionOn and self.engagedetectedOn then + + env.info("FF check detected:") + + local targetgroup=nil --Wrapper.Group#GROUP + local targetdist=math.huge + + -- Loop over detected groups. + for _,_group in pairs(self.detectedgroups:GetSet()) do + local group=_group --Wrapper.Group#GROUP + + env.info("group "..group:GetName()) + + if group and group:IsAlive() then + + local targetcoord=group:GetCoordinate() + + local distance=targetcoord:Get2DDistance(self:GetCoordinate()) + + if distance<=self.engagedetectedRmax and distance Mission Done! local Mission=self:GetMissionByTaskID(Task.id) @@ -2324,6 +2336,11 @@ function OPSGROUP:onafterTaskDone(From, Event, To, Task) --Mission paused. Do nothing! end else + + if Task.description=="Engage_Target" then + self:Disengage() + end + self:T(self.lid.."Task Done but NO mission found ==> _CheckGroupDone in 1 sec") self:_CheckGroupDone(1) end @@ -2984,33 +3001,48 @@ end -- @param #string To To state. -- @param #OPSGROUP.Waypoint Waypoint Waypoint data passed. function OPSGROUP:onafterPassingWaypoint(From, Event, To, Waypoint) - - -- Apply tasks of this waypoint. - local ntasks=self:_SetWaypointTasks(Waypoint) - - -- Get waypoint index. - local wpindex=self:GetWaypointIndex(Waypoint.uid) - -- Final waypoint reached? - if wpindex==nil or wpindex==#self.waypoints then - - -- Set switch to true. - if not self.adinfinitum or #self.waypoints<=1 then - self.passedfinalwp=true - end + -- Get the current task. + local task=self:GetTaskCurrent() + + if task and task.id=="PatrolZone" then + + local zone=task.dcstask.params.zone --Core.Zone#ZONE + + local Coordinate=zone:GetRandomCoordinate() + FLIGHTGROUP.AddWaypoint(self,Coordinate, Speed, AfterWaypointWithID, Altitude, Updateroute) + + else + + -- Apply tasks of this waypoint. + local ntasks=self:_SetWaypointTasks(Waypoint) + + -- Get waypoint index. + local wpindex=self:GetWaypointIndex(Waypoint.uid) + + -- Final waypoint reached? + if wpindex==nil or wpindex==#self.waypoints then + + -- Set switch to true. + if not self.adinfinitum or #self.waypoints<=1 then + self.passedfinalwp=true + end + + end + + -- Check if all tasks/mission are done? + -- Note, we delay it for a second to let the OnAfterPassingwaypoint function to be executed in case someone wants to add another waypoint there. + if ntasks==0 then + self:_CheckGroupDone(0.1) + end + + -- Debug info. + local text=string.format("Group passed waypoint %s/%d ID=%d: final=%s detour=%s astar=%s", + tostring(wpindex), #self.waypoints, Waypoint.uid, tostring(self.passedfinalwp), tostring(Waypoint.detour), tostring(Waypoint.astar)) + self:T(self.lid..text) + end - - -- Check if all tasks/mission are done? - -- Note, we delay it for a second to let the OnAfterPassingwaypoint function to be executed in case someone wants to add another waypoint there. - if ntasks==0 then - self:_CheckGroupDone(0.1) - end - - -- Debug info. - local text=string.format("Group passed waypoint %s/%d ID=%d: final=%s detour=%s astar=%s", - tostring(wpindex), #self.waypoints, Waypoint.uid, tostring(self.passedfinalwp), tostring(Waypoint.detour), tostring(Waypoint.astar)) - self:T(self.lid..text) end