- Added `FLIGHTGROUP:SetEngageDetectedOn()`
- AUFTRAG patrol zone.
This commit is contained in:
Frank 2021-01-15 00:59:52 +01:00
parent df79c765f8
commit f3a2cf7284
4 changed files with 268 additions and 37 deletions

View File

@ -830,7 +830,7 @@ function ARMYGROUP:onafterEngageTarget(From, Event, To, Target)
end end
--- On after "EngageTarget" event. --- Update engage target.
-- @param #ARMYGROUP self -- @param #ARMYGROUP self
function ARMYGROUP:_UpdateEngageTarget() function ARMYGROUP:_UpdateEngageTarget()

View File

@ -315,6 +315,7 @@ _AUFTRAGSNR=0
-- @field #string TANKER Tanker mission. -- @field #string TANKER Tanker mission.
-- @field #string TROOPTRANSPORT Troop transport mission. -- @field #string TROOPTRANSPORT Troop transport mission.
-- @field #string ARTY Fire at point. -- @field #string ARTY Fire at point.
-- @field #string PATROLZONE Patrol a zone.
AUFTRAG.Type={ AUFTRAG.Type={
ANTISHIP="Anti Ship", ANTISHIP="Anti Ship",
AWACS="AWACS", AWACS="AWACS",
@ -338,6 +339,7 @@ AUFTRAG.Type={
TANKER="Tanker", TANKER="Tanker",
TROOPTRANSPORT="Troop Transport", TROOPTRANSPORT="Troop Transport",
ARTY="Fire At Point", ARTY="Fire At Point",
PATROLZONE="Patrol Zone",
} }
--- Mission status. --- Mission status.
@ -1191,6 +1193,28 @@ function AUFTRAG:NewARTY(Target, Nshots, Radius)
return mission return mission
end 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. --- Create a mission to attack a group. Mission type is automatically chosen from the group category.
-- @param #AUFTRAG self -- @param #AUFTRAG self
-- @param Ops.Target#TARGET Target The target. -- @param Ops.Target#TARGET Target The target.
@ -2926,7 +2950,7 @@ end
-- @param #AUFTRAG self -- @param #AUFTRAG self
-- @return Wrapper.Positionable#POSITIONABLE The target object. Could be many things. -- @return Wrapper.Positionable#POSITIONABLE The target object. Could be many things.
function AUFTRAG:GetObjective() function AUFTRAG:GetObjective()
return self:GetTargetData().Target return self:GetTargetData():GetObject()
end end
--- Get type of target. --- Get type of target.
@ -3389,6 +3413,26 @@ function AUFTRAG:GetDCSMissionTask(TaskControllable)
table.insert(DCStasks, DCStask) 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 else
self:E(self.lid..string.format("ERROR: Unknown mission task!")) self:E(self.lid..string.format("ERROR: Unknown mission task!"))
return nil return nil

View File

@ -512,6 +512,41 @@ function FLIGHTGROUP:SetFuelCriticalRTB(switch)
return self return self
end 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. --- 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 -- @param #FLIGHTGROUP self
-- @return #FLIGHTGROUP self -- @return #FLIGHTGROUP self
@ -977,6 +1012,87 @@ function FLIGHTGROUP:onafterStatus(From, Event, To)
end end
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<targetdist then
-- Check type attribute.
local righttype=false
for _,attribute in pairs(self.engagedetectedTypes) do
if group:HasAttribute(attribute, false) then
righttype=true
break
end
end
-- We got the right type.
if righttype then
local insideEngage=true
local insideNoEngage=false
-- Check engage zones.
if self.engagedetectedEngageZones then
insideEngage=false
for _,_zone in pairs(self.engagedetectedEngageZones.Set) do
local zone=_zone --Core.Zone#ZONE
local inzone=zone:IsCoordinateInZone(targetcoord)
if inzone then
insideEngage=true
break
end
end
end
-- Check no engage zones.
if self.engagedetectedNoEngageZones then
for _,_zone in pairs(self.engagedetectedNoEngageZones.Set) do
local zone=_zone --Core.Zone#ZONE
local inzone=zone:IsCoordinateInZone(targetcoord)
if inzone then
insideNoEngage=true
break
end
end
end
-- If inside engage but not inside no engage zones.
if insideEngage and not insideNoEngage then
targetdist=distance
targetgroup=group
env.info("targetgroup "..group:GetName())
end
end
end
end
end
if targetgroup then
env.info("engage target! "..targetgroup:GetName())
self:EngageTargets(targetgroup)
end
end
-- Next check in ~30 seconds. -- Next check in ~30 seconds.
if not self:IsStopped() then if not self:IsStopped() then
@ -2383,23 +2499,62 @@ end
-- @param #string Event Event. -- @param #string Event Event.
-- @param #string To To state. -- @param #string To To state.
-- @param Core.Set#SET_UNIT TargetUnitSet -- @param Core.Set#SET_UNIT TargetUnitSet
function FLIGHTGROUP:onafterEngageTargets(From, Event, To, TargetUnitSet) function FLIGHTGROUP:onafterEngageTargets(From, Event, To, Target)
env.info("FF engage targets")
local DCStask=nil
if Target:IsInstanceOf("UNIT") then
elseif Target:IsInstanceOf("GROUP") then
env.info("FF engage targets GROUP!")
DCStask=self:GetGroup():TaskAttackGroup(Target, nil, nil, nil, nil, nil, nil, true)
elseif Target:IsInstanceOf("SET_UNIT") then
local DCSTasks={} local DCSTasks={}
for _,_unit in pairs(TargetUnitSet:GetSet()) do --detected by =HRP= Zero for _,_unit in pairs(Target:GetSet()) do --detected by =HRP= Zero
local unit=_unit --Wrapper.Unit#UNIT local unit=_unit --Wrapper.Unit#UNIT
local task=self.group:TaskAttackUnit(unit, true) local task=self:GetGroup():TaskAttackUnit(unit, true)
table.insert(DCSTasks) table.insert(DCSTasks)
end end
-- Task combo. -- Task combo.
local DCSTask=self.group:TaskCombo(DCSTasks) DCStask=self:GetGroup():TaskCombo(DCSTasks)
--TODO needs a task function that calls EngageDone or so event and updates the route again. elseif Target:IsInstanceOf("SET_GROUP") then
-- Lets try if pushtask actually leaves the remaining tasks untouched. else
self:SetTask(DCSTask)
end
-- Create new task.The description "Task_Engage" is checked.
local Task=self:NewTaskScheduled(DCStask, 1, "Task_Engage", 0)
-- Backup ROE setting.
Task.backupROE=self:GetROE()
-- Switch ROE to open fire
self:SwitchROE(ENUMS.ROE.OpenFire)
-- Execute task.
self:TaskExecute(Task)
end
--- On after "Disengage" event.
-- @param #FLIGHTGROUP self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
-- @param Core.Set#SET_UNIT TargetUnitSet
function FLIGHTGROUP:onafterDisengage(From, Event, To)
env.info("FF disengage targets")
end end

View File

@ -223,6 +223,7 @@ OPSGROUP.TaskType={
-- @field #number timestamp Abs. mission time, when task was started. -- @field #number timestamp Abs. mission time, when task was started.
-- @field #number waypoint Waypoint index if task is a waypoint task. -- @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. -- @field Core.UserFlag#USERFLAG stopflag If flag is set to 1 (=true), the task is stopped.
-- @field #number backupROE Rules of engagement that are restored once the task is over.
--- Enroute task. --- Enroute task.
-- @type OPSGROUP.EnrouteTask -- @type OPSGROUP.EnrouteTask
@ -2166,6 +2167,12 @@ function OPSGROUP:onafterTaskExecute(From, Event, To, Task)
-- Start formation FSM. -- Start formation FSM.
Task.formation:Start() Task.formation:Start()
elseif Task.dcstask.id=="PatrolZone" then
local Coordinate=Task.dcstask.params.zone:GetCoordinate()
FLIGHTGROUP.AddWaypoint(self, Coordinate, Speed, AfterWaypointWithID, Altitude)
else else
-- If task is scheduled (not waypoint) set task. -- If task is scheduled (not waypoint) set task.
@ -2310,6 +2317,11 @@ function OPSGROUP:onafterTaskDone(From, Event, To, Task)
-- Task status done. -- Task status done.
Task.status=OPSGROUP.TaskStatus.DONE Task.status=OPSGROUP.TaskStatus.DONE
-- Restore old ROE.
if Task.backupROE then
self:SwitchROE(Task.backupROE)
end
-- Check if this task was the task of the current mission ==> Mission Done! -- Check if this task was the task of the current mission ==> Mission Done!
local Mission=self:GetMissionByTaskID(Task.id) local Mission=self:GetMissionByTaskID(Task.id)
@ -2324,6 +2336,11 @@ function OPSGROUP:onafterTaskDone(From, Event, To, Task)
--Mission paused. Do nothing! --Mission paused. Do nothing!
end end
else 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:T(self.lid.."Task Done but NO mission found ==> _CheckGroupDone in 1 sec")
self:_CheckGroupDone(1) self:_CheckGroupDone(1)
end end
@ -2985,6 +3002,19 @@ end
-- @param #OPSGROUP.Waypoint Waypoint Waypoint data passed. -- @param #OPSGROUP.Waypoint Waypoint Waypoint data passed.
function OPSGROUP:onafterPassingWaypoint(From, Event, To, Waypoint) function OPSGROUP:onafterPassingWaypoint(From, Event, To, Waypoint)
-- 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. -- Apply tasks of this waypoint.
local ntasks=self:_SetWaypointTasks(Waypoint) local ntasks=self:_SetWaypointTasks(Waypoint)
@ -3012,6 +3042,8 @@ function OPSGROUP:onafterPassingWaypoint(From, Event, To, Waypoint)
tostring(wpindex), #self.waypoints, Waypoint.uid, tostring(self.passedfinalwp), tostring(Waypoint.detour), tostring(Waypoint.astar)) tostring(wpindex), #self.waypoints, Waypoint.uid, tostring(self.passedfinalwp), tostring(Waypoint.detour), tostring(Waypoint.astar))
self:T(self.lid..text) self:T(self.lid..text)
end
end end
--- Set tasks at this waypoint --- Set tasks at this waypoint