Capture
This commit is contained in:
Frank 2022-12-30 22:08:27 +01:00
parent 3011d625b2
commit 67af073b95
7 changed files with 91 additions and 60 deletions

View File

@ -1935,7 +1935,7 @@ do -- SET_GROUP
for GroupID, GroupData in pairs( Set ) do -- For each GROUP in SET_GROUP
local group=GroupData --Wrapper.Group#GROUP
if Coalitions==nil or UTILS.IsAnyInTable(Coalitions, group:GetCoalition()) then
if group and group:IsAlive() and (Coalitions==nil or UTILS.IsAnyInTable(Coalitions, group:GetCoalition())) then
local coord=group:GetCoord()
@ -6255,18 +6255,18 @@ do -- SET_OPSZONE
--- Add an OPSZONE to set.
-- @param Core.Set#SET_OPSZONE self
-- @param Ops.OpsZone#OPSZONE Zone The OPSZONE object.
-- @return self
-- @return #SET_OPSZONE self
function SET_OPSZONE:AddZone( Zone )
self:Add( Zone:GetName(), Zone )
return self
end
end
--- Remove ZONEs from SET_OPSZONE.
-- @param Core.Set#SET_OPSZONE self
-- @param #table RemoveZoneNames A single name or an array of OPSZONE names.
-- @return self
-- @return #SET_OPSZONE self
function SET_OPSZONE:RemoveZonesByName( RemoveZoneNames )
local RemoveZoneNamesArray = (type( RemoveZoneNames ) == "table") and RemoveZoneNames or { RemoveZoneNames }
@ -6570,6 +6570,21 @@ do -- SET_OPSZONE
end
end
end
--- Start all opszones of the set.
-- @param #SET_OPSZONE self
-- @return #SET_OPSZONE self
function SET_OPSZONE:Start()
for _,_Zone in pairs( self:GetSet() ) do
local Zone = _Zone --Ops.OpsZone#OPSZONE
if Zone:IsStopped() then
Zone:Start()
end
end
return self
end
--- Validate if a coordinate is in one of the zones in the set.
-- Returns the ZONE object where the coordiante is located.
@ -6591,16 +6606,14 @@ do -- SET_OPSZONE
end
--- Get the closest OPSZONE from a given reference coordinate.
--- Get the closest OPSZONE from a given reference coordinate. Only started zones are considered.
-- @param #SET_OPSZONE self
-- @param Core.Point#COORDINATE Coordinate The reference coordinate from which the closest zone is determined.
-- @param #table Coalitions Only consider the given coalition(s), *e.g.* `{coaliton.side.RED}` to find the closest red zone.
-- @return Ops.OpsZone#OPSZONE The closest OPSZONE (if any).
-- @return #number Distance to ref coordinate in meters.
function SET_OPSZONE:GetClosestZone( Coordinate, Coalitions )
env.info("FF 100",showMessageBox)
Coalitions=UTILS.EnsureTable(Coalitions, true)
local dmin=math.huge --#number
@ -6611,22 +6624,12 @@ do -- SET_OPSZONE
local coal=opszone:GetOwner()
env.info("FF 200",showMessageBox)
env.info("In table="..tostring(UTILS.IsInTable(Coalitions, coal)))
BASE:I(Coalitions)
BASE:I(coal)
if Coalitions==nil or (Coalitions and UTILS.IsInTable(Coalitions, coal)) then
env.info("FF 300",showMessageBox)
if opszone:IsStarted() and (Coalitions==nil or (Coalitions and UTILS.IsInTable(Coalitions, coal))) then
-- Get 2D distance.
local d=opszone:GetZone():Get2DDistance(Coordinate)
if d<dmin then
env.info("FF 400",showMessageBox)
if d<dmin then
dmin=d
zmin=opszone
end

View File

@ -68,7 +68,7 @@ ARMYGROUP = {
--- Army Group version.
-- @field #string version
ARMYGROUP.version="0.8.0"
ARMYGROUP.version="0.9.0"
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO list
@ -293,7 +293,7 @@ function ARMYGROUP:New(group)
--- Triggers the FSM event "EngageTarget".
-- @function [parent=#ARMYGROUP] EngageTarget
-- @param #ARMYGROUP self
-- @param Wrapper.Group#GROUP Group the group to be engaged.
-- @param Ops.Target#TARGET Target The target to be engaged. Can also be a GROUP or UNIT object.
-- @param #number Speed Speed in knots.
-- @param #string Formation Formation used in the engagement.
@ -728,23 +728,16 @@ function ARMYGROUP:Status()
-- If mission, check if DCS task needs to be updated.
if mission and mission.updateDCSTask and mission:GetGroupStatus(self)==AUFTRAG.GroupStatus.EXECUTING then
if mission.type==AUFTRAG.Type.CAPTUREZONE then
-- Get task.
local Task=self:GetTaskByID(mission.auftragsnummer)
local opszone=Task.target --Ops.OpsZone#OPSZONE
env.info(string.format("FF Opszone %s owner=%s, engaging=%s", opszone:GetName(), opszone:GetOwnerName(), tostring(self:IsEngaging())))
local Task=mission:GetGroupWaypointTask(self)
-- Update task: Engage or get new zone.
self:_UpdateTask(Task, mission)
end
end
else
@ -1374,7 +1367,7 @@ function ARMYGROUP:onafterDetour(From, Event, To, Coordinate, Speed, Formation,
Speed=Speed or self:GetSpeedCruise()
-- ID of current waypoint.
local uid=self:GetWaypointCurrent().uid
local uid=self:GetWaypointCurrentUID()
-- Add waypoint after current.
local wp=self:AddWaypoint(Coordinate, Speed, uid, Formation, true)
@ -1497,7 +1490,7 @@ function ARMYGROUP:onafterRearm(From, Event, To, Coordinate, Formation)
self:T(self.lid..string.format("Group send to rearm"))
-- ID of current waypoint.
local uid=self:GetWaypointCurrent().uid
local uid=self:GetWaypointCurrentUID()
-- Add waypoint after current.
local wp=self:AddWaypoint(Coordinate, nil, uid, Formation, true)
@ -1690,7 +1683,7 @@ end
function ARMYGROUP:onafterRetreat(From, Event, To, Zone, Formation)
-- ID of current waypoint.
local uid=self:GetWaypointCurrent().uid
local uid=self:GetWaypointCurrentUID()
-- Get random coordinate of the zone.
local Coordinate=Zone:GetRandomCoordinate()
@ -1773,7 +1766,7 @@ end
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
-- @param Wrapper.Group#GROUP Group the group to be engaged.
-- @param Ops.Target#TARGET Target The target to be engaged. Can also be a group or unit.
-- @param #number Speed Attack speed in knots.
-- @param #string Formation Formation used in the engagement. Default `ENUMS.Formation.Vehicle.Vee`.
function ARMYGROUP:onafterEngageTarget(From, Event, To, Target, Speed, Formation)
@ -1840,7 +1833,7 @@ function ARMYGROUP:_UpdateEngageTarget()
self.engage.Coordinate:UpdateFromVec3(vec3)
-- ID of current waypoint.
local uid=self:GetWaypointCurrent().uid
local uid=self:GetWaypointCurrentUID()
-- Remove current waypoint
self:RemoveWaypointByID(self.engage.Waypoint.uid)

View File

@ -632,7 +632,7 @@ AUFTRAG.Category={
--- AUFTRAG class version.
-- @field #string version
AUFTRAG.version="0.9.8"
AUFTRAG.version="0.9.9"
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO list
@ -641,6 +641,7 @@ AUFTRAG.version="0.9.8"
-- TODO: Replace engageRange by missionRange. Here and in other classes. CTRL+H is your friend!
-- TODO: Mission success options damaged, destroyed.
-- TODO: F10 marker to create new missions.
-- DONE: Add Capture zone task.
-- DONE: Add orbit mission for moving anker points.
-- DONE: Add recovery tanker mission for boat ops.
-- DONE: Added auftrag category.
@ -1987,11 +1988,11 @@ function AUFTRAG:NewCAPTUREZONE(OpsZone, Coalition, Speed, Altitude, Formation)
mission.missionTask=mission:GetMissionTaskforMissionType(AUFTRAG.Type.CAPTUREZONE)
mission.optionROE=ENUMS.ROE.OpenFire
mission.optionROE=ENUMS.ROE.ReturnFire
mission.optionROT=ENUMS.ROT.PassiveDefense
mission.optionAlarm=ENUMS.AlarmState.Auto
mission.missionFraction=1.0
mission.missionFraction=0.1
mission.missionSpeed=Speed and UTILS.KnotsToKmph(Speed) or nil
mission.missionAltitude=Altitude and UTILS.FeetToMeters(Altitude) or nil

View File

@ -47,7 +47,7 @@ LEGION = {
--- LEGION class version.
-- @field #string version
LEGION.version="0.3.4"
LEGION.version="0.4.0"
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- ToDo list

View File

@ -500,7 +500,7 @@ OPSGROUP.CargoStatus={
--- OpsGroup version.
-- @field #string version
OPSGROUP.version="0.8.0"
OPSGROUP.version="0.9.0"
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO list
@ -4385,42 +4385,56 @@ function OPSGROUP:_UpdateTask(Task, Mission)
---
-- Task "CaptureZone" Mission.
-- Check if zone was captured or find new target to engage.
---
env.info("FF Update Task Capture zone")
-- Find the closest enemy group and engage!
-- Not enganging already.
if self:IsEngaging() then
self:T(self.lid..string.format("Engaging currently!"))
-- Group is currently engaging an enemy unit to capture the zone.
self:T2(self.lid..string.format("CaptureZone: Engaging currently!"))
else
-- Get enemy coalitions. We do not include neutrals.
local Coalitions=UTILS.GetCoalitionEnemy(self:GetCoalition(), false)
-- Current target object.
local zoneCurr=Task.target --Ops.OpsZone#OPSZONE
if zoneCurr then
self:T(self.lid..string.format("Current target zone=%s", zoneCurr:GetName()))
self:T(self.lid..string.format("Current target zone=%s owner=%s", zoneCurr:GetName(), zoneCurr:GetOwnerName()))
if zoneCurr:GetOwner()==self:GetCoalition() then
-- Current zone captured ==> Find next zone or call it a day!
-- Debug info.
self:T(self.lid..string.format("Zone %s captured ==> Task DONE!", zoneCurr:GetName()))
-- Task done.
self:TaskDone(Task)
else
-- Current zone NOT captured yet ==> Find Target
-- Debug info.
self:T(self.lid..string.format("Zone %s NOT captured!", zoneCurr:GetName()))
if Mission:GetGroupStatus(self)==AUFTRAG.GroupStatus.EXECUTING then
-- Debug info.
self:T(self.lid..string.format("Zone %s NOT captured and EXECUTING ==> Find target", zoneCurr:GetName()))
-- Get closest target.
local targetgroup=zoneCurr:GetScannedGroupSet():GetClosestGroup(self.coordinate, Coalitions)
if targetgroup then
-- Debug info.
self:T(self.lid..string.format("Zone %s NOT captured: engaging target %s", zoneCurr:GetName(), targetgroup:GetName()))
-- Engage target group.
self:EngageTarget(targetgroup)
else
@ -4428,10 +4442,11 @@ function OPSGROUP:_UpdateTask(Task, Mission)
self:E(self.lid..string.format("ERROR: Current zone not captured but no target group could be found. This should NOT happen!"))
end
end
end
else
self:T(self.lid..string.format("Zone %s NOT captured and NOT EXECUTING", zoneCurr:GetName()))
end
end
else
self:T(self.lid..string.format("NO Current target zone=%s"))
@ -4727,11 +4742,14 @@ function OPSGROUP:onafterTaskDone(From, Event, To, Task)
if Mission.type==AUFTRAG.Type.CAPTUREZONE and Mission:CountMissionTargets()>0 then
env.info("FF task done route to mission 1000")
self:RouteToMission(Mission)
return
-- Remove mission waypoints.
self:T(self.lid.."Remove mission waypoints")
self:_RemoveMissionWaypoints(Mission, false)
self:T(self.lid.."Task done ==> Route to mission for next opszone")
self:MissionStart(Mission)
return
end
-- Get egress waypoint uid.

View File

@ -86,16 +86,16 @@ OPSZONE = {
--- OPSZONE class version.
-- @field #string version
OPSZONE.version="0.3.2"
OPSZONE.version="0.4.0"
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- ToDo list
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO: Capturing based on (total) threat level threshold. Unarmed units do not pose a threat and should not be able to hold a zone.
-- TODO: Pause/unpause evaluations.
-- TODO: Capture time, i.e. time how long a single coalition has to be inside the zone to capture it.
-- TODO: Differentiate between ground attack and boming by air or arty.
-- DONE: Capture time, i.e. time how long a single coalition has to be inside the zone to capture it.
-- DONE: Capturing based on (total) threat level threshold. Unarmed units do not pose a threat and should not be able to hold a zone.
-- DONE: Can neutrals capture? No, since they are _neutral_!
-- DONE: Capture airbases.
-- DONE: Can statics capture or hold a zone? No, unless explicitly requested by mission designer.
@ -613,6 +613,22 @@ function OPSZONE:IsCoalition(Coalition)
return is
end
--- Check if zone is started (not stopped).
-- @param #OPSZONE self
-- @return #boolean If `true`, zone is started.
function OPSZONE:IsStarted()
local is=not self:IsStopped()
return is
end
--- Check if zone is stopped.
-- @param #OPSZONE self
-- @return #boolean If `true`, zone is stopped.
function OPSZONE:IsStopped()
local is=self:is("Stopped")
return is
end
--- Check if zone is guarded.
-- @param #OPSZONE self
-- @return #boolean If `true`, zone is guarded.

View File

@ -153,7 +153,7 @@ _TARGETID=0
--- TARGET class version.
-- @field #string version
TARGET.version="0.5.6"
TARGET.version="0.6.0"
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO list