mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
OPS
Capture Zone
This commit is contained in:
parent
30e6542887
commit
3011d625b2
@ -1919,6 +1919,41 @@ do -- SET_GROUP
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--- Get the closest group of the set with respect to a given reference coordinate. Optionally, only groups of given coalitions are considered in the search.
|
||||
-- @param #SET_GROUP self
|
||||
-- @param Core.Point#COORDINATE Coordinate Reference Coordinate from which the closest group is determined.
|
||||
-- @return Wrapper.Group#GROUP The closest group (if any).
|
||||
-- @return #number Distance in meters to the closest group.
|
||||
function SET_GROUP:GetClosestGroup(Coordinate, Coalitions)
|
||||
|
||||
local Set = self:GetSet()
|
||||
|
||||
local dmin=math.huge
|
||||
local gmin=nil
|
||||
|
||||
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
|
||||
|
||||
local coord=group:GetCoord()
|
||||
|
||||
-- Distance between ref. coordinate and group coordinate.
|
||||
local d=UTILS.VecDist3D(Coordinate, coord)
|
||||
|
||||
if d<dmin then
|
||||
dmin=d
|
||||
gmin=group
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
return gmin, dmin
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
do -- SET_UNIT
|
||||
|
||||
@ -720,6 +720,32 @@ function ARMYGROUP:Status()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- Get current mission (if any).
|
||||
local mission=self:GetMissionCurrent()
|
||||
|
||||
-- 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())))
|
||||
|
||||
-- Update task: Engage or get new zone.
|
||||
self:_UpdateTask(Task, mission)
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
else
|
||||
-- Check damage of elements and group.
|
||||
@ -1721,10 +1747,11 @@ function ARMYGROUP:onbeforeEngageTarget(From, Event, To, Target, Speed, Formatio
|
||||
return false
|
||||
end
|
||||
|
||||
-- Pause current mission.
|
||||
-- Get current mission.
|
||||
local mission=self:GetMissionCurrent()
|
||||
|
||||
if mission and mission.type~=AUFTRAG.Type.GROUNDATTACK then
|
||||
-- Pause current mission unless it uses the EngageTarget command.
|
||||
if mission and mission.type~=AUFTRAG.Type.GROUNDATTACK and mission.type~=AUFTRAG.Type.CAPTUREZONE then
|
||||
self:T(self.lid.."Engage command but have current mission ==> Pausing mission!")
|
||||
self:PauseMission()
|
||||
dt=-0.1
|
||||
@ -1804,8 +1831,8 @@ function ARMYGROUP:_UpdateEngageTarget()
|
||||
-- Distance to last known position of target.
|
||||
local dist=UTILS.VecDist3D(vec3, self.engage.Coordinate:GetVec3())
|
||||
|
||||
-- Check if target moved more than 100 meters.
|
||||
if dist>100 then
|
||||
-- Check if target moved more than 100 meters or we do not have line of sight.
|
||||
if dist>100 or not self:HasLoS(self.engage.Target:GetCoordinate()) then
|
||||
|
||||
--env.info("FF Update Engage Target Moved "..self.engage.Target:GetName())
|
||||
|
||||
@ -1824,7 +1851,7 @@ function ARMYGROUP:_UpdateEngageTarget()
|
||||
self.engage.Waypoint=self:AddWaypoint(intercoord, self.engage.Speed, uid, self.engage.Formation, true)
|
||||
|
||||
-- Set if we want to resume route after reaching the detour waypoint.
|
||||
self.engage.Waypoint.detour=0
|
||||
self.engage.Waypoint.detour=0
|
||||
|
||||
end
|
||||
|
||||
|
||||
@ -422,7 +422,8 @@ _AUFTRAGSNR=0
|
||||
-- @field #string AIRDEFENSE Air defense.
|
||||
-- @field #string EWR Early Warning Radar.
|
||||
-- @field #string RECOVERYTANKER Recovery tanker.
|
||||
-- @filed #string REARMING Rearming mission.
|
||||
-- @field #string REARMING Rearming mission.
|
||||
-- @field #string CAPTUREZONE Capture zone mission.
|
||||
-- @field #string NOTHING Nothing.
|
||||
AUFTRAG.Type={
|
||||
ANTISHIP="Anti Ship",
|
||||
@ -465,6 +466,7 @@ AUFTRAG.Type={
|
||||
EWR="Early Warning Radar",
|
||||
RECOVERYTANKER="Recovery Tanker",
|
||||
REARMING="Rearming",
|
||||
CAPTUREZONE="Capture Zone",
|
||||
NOTHING="Nothing",
|
||||
}
|
||||
|
||||
@ -487,6 +489,7 @@ AUFTRAG.Type={
|
||||
-- @field #string EWR Early Warning Radar.
|
||||
-- @field #string RECOVERYTANKER Recovery tanker.
|
||||
-- @field #string REARMING Rearming.
|
||||
-- @field #string CAPTUREZONE Capture OPS zone.
|
||||
-- @field #string NOTHING Nothing.
|
||||
AUFTRAG.SpecialTask={
|
||||
FORMATION="Formation",
|
||||
@ -507,6 +510,7 @@ AUFTRAG.SpecialTask={
|
||||
EWR="Early Warning Radar",
|
||||
RECOVERYTANKER="Recovery Tanker",
|
||||
REARMING="Rearming",
|
||||
CAPTUREZONE="Capture Zone",
|
||||
NOTHING="Nothing",
|
||||
}
|
||||
|
||||
@ -1964,6 +1968,51 @@ function AUFTRAG:NewPATROLZONE(Zone, Speed, Altitude, Formation)
|
||||
return mission
|
||||
end
|
||||
|
||||
--- **[AIR, GROUND, NAVAL]** Create a CAPTUREZONE mission. Group(s) will go to the zone and patrol it randomly.
|
||||
-- @param #AUFTRAG self
|
||||
-- @param Ops.OpsZone#OPSZONE OpsZone The OPS zone to capture.
|
||||
-- @param #number Coalition The coalition which should capture the zone for the mission to be successful.
|
||||
-- @param #number Speed Speed in knots.
|
||||
-- @param #number Altitude Altitude in feet. Only for airborne units. Default 2000 feet ASL.
|
||||
-- @param #string Formation Formation used by ground units during patrol. Default "Off Road".
|
||||
-- @return #AUFTRAG self
|
||||
function AUFTRAG:NewCAPTUREZONE(OpsZone, Coalition, Speed, Altitude, Formation)
|
||||
|
||||
local mission=AUFTRAG:New(AUFTRAG.Type.CAPTUREZONE)
|
||||
|
||||
|
||||
mission:_TargetFromObject(OpsZone)
|
||||
|
||||
mission.coalition=Coalition
|
||||
|
||||
mission.missionTask=mission:GetMissionTaskforMissionType(AUFTRAG.Type.CAPTUREZONE)
|
||||
|
||||
mission.optionROE=ENUMS.ROE.OpenFire
|
||||
mission.optionROT=ENUMS.ROT.PassiveDefense
|
||||
mission.optionAlarm=ENUMS.AlarmState.Auto
|
||||
|
||||
mission.missionFraction=1.0
|
||||
mission.missionSpeed=Speed and UTILS.KnotsToKmph(Speed) or nil
|
||||
mission.missionAltitude=Altitude and UTILS.FeetToMeters(Altitude) or nil
|
||||
|
||||
mission.categories={AUFTRAG.Category.ALL}
|
||||
|
||||
mission.DCStask=mission:GetDCSMissionTask()
|
||||
|
||||
mission.updateDCSTask=true
|
||||
|
||||
local params={}
|
||||
|
||||
params.formation=Formation or "Off Road"
|
||||
params.zone=mission:GetObjective()
|
||||
params.altitude=mission.missionAltitude
|
||||
params.speed=mission.missionSpeed
|
||||
|
||||
mission.DCStask.params=params
|
||||
|
||||
return mission
|
||||
end
|
||||
|
||||
|
||||
--- **[OBSOLETE]** Create a ARMORATTACK mission.
|
||||
-- ** Note that this is actually creating a GROUNDATTACK mission!**
|
||||
@ -4947,8 +4996,11 @@ function AUFTRAG:CountMissionTargets()
|
||||
|
||||
local N=0
|
||||
|
||||
-- Count specific coalitions.
|
||||
local Coalitions=self.coalition and UTILS.GetCoalitionEnemy(self.coalition, true) or nil
|
||||
|
||||
if self.engageTarget then
|
||||
N=self.engageTarget:CountTargets()
|
||||
N=self.engageTarget:CountTargets(Coalitions)
|
||||
end
|
||||
|
||||
return N
|
||||
@ -5013,9 +5065,13 @@ end
|
||||
|
||||
--- Get mission objective object. Could be many things depending on the mission type.
|
||||
-- @param #AUFTRAG self
|
||||
-- @param Core.Point#COORDINATE RefCoordinate (Optional) Reference coordinate from which the closest target is determined.
|
||||
-- @param #table Coalitions (Optional) Only consider targets of the given coalition(s).
|
||||
-- @return Wrapper.Positionable#POSITIONABLE The target object. Could be many things.
|
||||
function AUFTRAG:GetObjective()
|
||||
local objective=self:GetTargetData():GetObject()
|
||||
function AUFTRAG:GetObjective(RefCoordinate, Coalitions)
|
||||
|
||||
local objective=self:GetTargetData():GetObject(RefCoordinate, Coalitions)
|
||||
|
||||
return objective
|
||||
end
|
||||
|
||||
@ -5753,6 +5809,22 @@ function AUFTRAG:GetDCSMissionTask()
|
||||
DCStask.params=param
|
||||
|
||||
table.insert(DCStasks, DCStask)
|
||||
|
||||
elseif self.type==AUFTRAG.Type.CAPTUREZONE then
|
||||
|
||||
--------------------------
|
||||
-- CAPTURE ZONE Mission --
|
||||
--------------------------
|
||||
|
||||
local DCStask={}
|
||||
|
||||
DCStask.id=AUFTRAG.SpecialTask.CAPTUREZONE
|
||||
|
||||
-- We create a "fake" DCS task and pass the parameters to the FLIGHTGROUP.
|
||||
local param={}
|
||||
DCStask.params=param
|
||||
|
||||
table.insert(DCStasks, DCStask)
|
||||
|
||||
elseif self.type==AUFTRAG.Type.CASENHANCED then
|
||||
|
||||
|
||||
@ -335,6 +335,7 @@ OPSGROUP.TaskType={
|
||||
-- @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 #number backupROE Rules of engagement that are restored once the task is over.
|
||||
-- @field Ops.Target#TARGET target Target object.
|
||||
|
||||
--- Option data.
|
||||
-- @type OPSGROUP.Option
|
||||
@ -4091,12 +4092,13 @@ function OPSGROUP:onafterTaskExecute(From, Event, To, Task)
|
||||
|
||||
end
|
||||
|
||||
--- Push task.
|
||||
--- Update (DCS) task.
|
||||
-- @param #OPSGROUP self
|
||||
-- @param Ops.OpsGroup#OPSGROUP.Task Task The task.
|
||||
-- @param Ops.Auftrag#AUFTRAG Mission The mission.
|
||||
function OPSGROUP:_UpdateTask(Task, Mission)
|
||||
|
||||
local Mission=Mission or self:GetMissionByTaskID(self.taskcurrent)
|
||||
Mission=Mission or self:GetMissionByTaskID(self.taskcurrent)
|
||||
|
||||
if Task.dcstask.id==AUFTRAG.SpecialTask.FORMATION then
|
||||
|
||||
@ -4378,6 +4380,64 @@ function OPSGROUP:_UpdateTask(Task, Mission)
|
||||
end
|
||||
|
||||
wp.missionUID=Mission and Mission.auftragsnummer or nil
|
||||
|
||||
elseif Task.dcstask.id==AUFTRAG.SpecialTask.CAPTUREZONE then
|
||||
|
||||
---
|
||||
-- Task "CaptureZone" Mission.
|
||||
---
|
||||
|
||||
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!"))
|
||||
else
|
||||
|
||||
local Coalitions=UTILS.GetCoalitionEnemy(self:GetCoalition(), false)
|
||||
|
||||
local zoneCurr=Task.target --Ops.OpsZone#OPSZONE
|
||||
|
||||
if zoneCurr then
|
||||
|
||||
self:T(self.lid..string.format("Current target zone=%s", zoneCurr:GetName()))
|
||||
|
||||
if zoneCurr:GetOwner()==self:GetCoalition() then
|
||||
-- Current zone captured ==> Find next zone or call it a day!
|
||||
|
||||
self:T(self.lid..string.format("Zone %s captured ==> Task DONE!", zoneCurr:GetName()))
|
||||
|
||||
self:TaskDone(Task)
|
||||
|
||||
else
|
||||
-- Current zone NOT captured yet ==> Find Target
|
||||
|
||||
if Mission:GetGroupStatus(self)==AUFTRAG.GroupStatus.EXECUTING then
|
||||
|
||||
-- Get closest target.
|
||||
local targetgroup=zoneCurr:GetScannedGroupSet():GetClosestGroup(self.coordinate, Coalitions)
|
||||
|
||||
if targetgroup then
|
||||
|
||||
self:EngageTarget(targetgroup)
|
||||
|
||||
else
|
||||
-- Error Message.
|
||||
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("NO Current target zone=%s"))
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
else
|
||||
|
||||
@ -4662,9 +4722,18 @@ function OPSGROUP:onafterTaskDone(From, Event, To, Task)
|
||||
-- Check if mission is paused.
|
||||
if status~=AUFTRAG.GroupStatus.PAUSED then
|
||||
---
|
||||
-- Mission is NOT over ==> trigger done
|
||||
-- Mission is NOT over ==> trigger DONE
|
||||
---
|
||||
|
||||
if Mission.type==AUFTRAG.Type.CAPTUREZONE and Mission:CountMissionTargets()>0 then
|
||||
|
||||
env.info("FF task done route to mission 1000")
|
||||
self:RouteToMission(Mission)
|
||||
|
||||
return
|
||||
|
||||
end
|
||||
|
||||
-- Get egress waypoint uid.
|
||||
local EgressUID=Mission:GetGroupEgressWaypointUID(self)
|
||||
|
||||
@ -5496,6 +5565,13 @@ function OPSGROUP:RouteToMission(mission, delay)
|
||||
surfacetypes={land.SurfaceType.WATER, land.SurfaceType.SHALLOW_WATER}
|
||||
end
|
||||
|
||||
-- Get target object.
|
||||
local targetobject=mission:GetObjective(currentcoord, UTILS.GetCoalitionEnemy(self:GetCoalition(), true))
|
||||
|
||||
if targetobject then
|
||||
self:T(self.lid..string.format("Route to mission target object %s", targetobject:GetName()))
|
||||
end
|
||||
|
||||
-- Get ingress waypoint.
|
||||
if mission.opstransport and not mission.opstransport:IsCargoDelivered(self.groupname) then
|
||||
|
||||
@ -5526,7 +5602,7 @@ function OPSGROUP:RouteToMission(mission, delay)
|
||||
---
|
||||
|
||||
-- Get the zone.
|
||||
targetzone=mission.engageTarget:GetObject() --Core.Zone#ZONE
|
||||
targetzone=targetobject --Core.Zone#ZONE
|
||||
|
||||
-- Random coordinate.
|
||||
waypointcoord=targetzone:GetRandomCoordinate(nil , nil, surfacetypes)
|
||||
@ -5545,7 +5621,7 @@ function OPSGROUP:RouteToMission(mission, delay)
|
||||
---
|
||||
|
||||
-- Get the zone.
|
||||
targetzone=mission.engageTarget:GetObject() --Core.Zone#ZONE
|
||||
targetzone=targetobject --Core.Zone#ZONE
|
||||
|
||||
-- Random coordinate.
|
||||
waypointcoord=targetzone:GetRandomCoordinate(nil , nil, surfacetypes)
|
||||
@ -5555,7 +5631,8 @@ function OPSGROUP:RouteToMission(mission, delay)
|
||||
-- Hover
|
||||
---
|
||||
|
||||
local zone=mission.engageTarget:GetObject() --Core.Zone#ZONE
|
||||
local zone=targetobject --Core.Zone#ZONE
|
||||
|
||||
waypointcoord=zone:GetCoordinate()
|
||||
|
||||
elseif mission.type==AUFTRAG.Type.RELOCATECOHORT then
|
||||
@ -5580,6 +5657,15 @@ function OPSGROUP:RouteToMission(mission, delay)
|
||||
-- Navy group: Route into direction of the target.
|
||||
waypointcoord=currentcoord:GetIntermediateCoordinate(ToCoordinate, 0.05)
|
||||
end
|
||||
|
||||
elseif mission.type==AUFTRAG.Type.CAPTUREZONE then
|
||||
|
||||
-- Get the zone.
|
||||
targetzone=targetobject:GetZone()
|
||||
|
||||
-- Random coordinate.
|
||||
waypointcoord=targetzone:GetRandomCoordinate(nil , nil, surfacetypes)
|
||||
|
||||
|
||||
else
|
||||
---
|
||||
@ -5706,6 +5792,8 @@ function OPSGROUP:RouteToMission(mission, delay)
|
||||
-- Add waypoint task. UpdateRoute is called inside.
|
||||
local waypointtask=self:AddTaskWaypoint(mission.DCStask, waypoint, mission.name, mission.prio, mission.duration)
|
||||
waypointtask.ismission=true
|
||||
|
||||
waypointtask.target=targetobject
|
||||
|
||||
-- Set waypoint task.
|
||||
mission:SetGroupWaypointTask(self, waypointtask)
|
||||
@ -5766,7 +5854,7 @@ function OPSGROUP:RouteToMission(mission, delay)
|
||||
---
|
||||
-- Mission Specific Settings
|
||||
---
|
||||
self:_SetMissionOptions(mission)
|
||||
self:_SetMissionOptions(mission)
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
@ -84,6 +84,7 @@ TARGET = {
|
||||
-- @field #string COORDINATE Target is a COORDINATE.
|
||||
-- @field #string AIRBASE Target is an AIRBASE.
|
||||
-- @field #string ZONE Target is a ZONE object.
|
||||
-- @field #string OPSZONE Target is an OPSZONE object.
|
||||
TARGET.ObjectType={
|
||||
GROUP="Group",
|
||||
UNIT="Unit",
|
||||
@ -92,6 +93,7 @@ TARGET.ObjectType={
|
||||
COORDINATE="Coordinate",
|
||||
AIRBASE="Airbase",
|
||||
ZONE="Zone",
|
||||
OPSZONE="OpsZone"
|
||||
}
|
||||
|
||||
|
||||
@ -312,12 +314,18 @@ end
|
||||
-- * SET_SCENERY
|
||||
-- * SET_OPSGROUP
|
||||
-- * SET_ZONE
|
||||
-- * SET_OPSZONE
|
||||
--
|
||||
-- @param #TARGET self
|
||||
-- @param Wrapper.Positionable#POSITIONABLE Object The target UNIT, GROUP, STATIC, SCENERY, AIRBASE, COORDINATE, ZONE, SET_GROUP, SET_UNIT, SET_STATIC, SET_SCENERY, SET_ZONE
|
||||
function TARGET:AddObject(Object)
|
||||
|
||||
if Object:IsInstanceOf("SET_GROUP") or Object:IsInstanceOf("SET_UNIT") or Object:IsInstanceOf("SET_STATIC") or Object:IsInstanceOf("SET_SCENERY") or Object:IsInstanceOf("SET_OPSGROUP") then
|
||||
if Object:IsInstanceOf("SET_GROUP") or
|
||||
Object:IsInstanceOf("SET_UNIT") or
|
||||
Object:IsInstanceOf("SET_STATIC") or
|
||||
Object:IsInstanceOf("SET_SCENERY") or
|
||||
Object:IsInstanceOf("SET_OPSGROUP") or
|
||||
Object:IsInstanceOf("SET_OPSZONE") then
|
||||
|
||||
---
|
||||
-- Sets
|
||||
@ -981,6 +989,22 @@ function TARGET:_AddObject(Object)
|
||||
|
||||
target.Life0=1
|
||||
target.Life=1
|
||||
|
||||
elseif Object:IsInstanceOf("OPSZONE") then
|
||||
|
||||
|
||||
local zone=Object --Ops.OpsZone#OPSZONE
|
||||
Object=zone
|
||||
|
||||
target.Type=TARGET.ObjectType.OPSZONE
|
||||
target.Name=zone:GetName()
|
||||
|
||||
target.Coordinate=zone:GetCoordinate()
|
||||
|
||||
target.N0=target.N0+1
|
||||
|
||||
target.Life0=1
|
||||
target.Life=1
|
||||
|
||||
else
|
||||
self:E(self.lid.."ERROR: Unknown object type!")
|
||||
@ -1097,7 +1121,7 @@ function TARGET:GetTargetLife(Target)
|
||||
|
||||
return 1
|
||||
|
||||
elseif Target.Type==TARGET.ObjectType.ZONE then
|
||||
elseif Target.Type==TARGET.ObjectType.ZONE or Target.Type==TARGET.ObjectType.OPSZONE then
|
||||
|
||||
return 1
|
||||
|
||||
@ -1305,6 +1329,13 @@ function TARGET:GetTargetVec3(Target, Average)
|
||||
|
||||
local vec3=object:GetVec3()
|
||||
return vec3
|
||||
|
||||
elseif Target.Type==TARGET.ObjectType.OPSZONE then
|
||||
|
||||
local object=Target.Object --Ops.OpsZone#OPSZONE
|
||||
|
||||
local vec3=object:GetZone():GetVec3()
|
||||
return vec3
|
||||
|
||||
end
|
||||
|
||||
@ -1382,7 +1413,7 @@ function TARGET:GetTargetHeading(Target)
|
||||
-- A coordinate has no heading. Return 0.
|
||||
return 0
|
||||
|
||||
elseif Target.Type==TARGET.ObjectType.ZONE then
|
||||
elseif Target.Type==TARGET.ObjectType.ZONE or Target.Type==TARGET.ObjectType.OPSZONE then
|
||||
|
||||
local object=Target.Object --Core.Zone#ZONE
|
||||
|
||||
@ -1660,6 +1691,10 @@ function TARGET:GetTargetCategory(Target)
|
||||
elseif Target.Type==TARGET.ObjectType.ZONE then
|
||||
|
||||
return TARGET.Category.ZONE
|
||||
|
||||
elseif Target.Type==TARGET.ObjectType.OPSZONE then
|
||||
|
||||
return TARGET.Category.OPSZONE
|
||||
|
||||
else
|
||||
self:E("ERROR: unknown target category!")
|
||||
@ -1669,6 +1704,71 @@ function TARGET:GetTargetCategory(Target)
|
||||
end
|
||||
|
||||
|
||||
--- Get coalition of target object. If an object has no coalition (*e.g.* a coordinate) it is returned as neutral.
|
||||
-- @param #TARGET self
|
||||
-- @param #TARGET.Object Target Target object.
|
||||
-- @return #number Coalition number.
|
||||
function TARGET:GetTargetCoalition(Target)
|
||||
|
||||
|
||||
-- We take neutral for objects that do not have a coalition.
|
||||
local coal=coalition.side.NEUTRAL
|
||||
|
||||
|
||||
if Target.Type==TARGET.ObjectType.GROUP then
|
||||
|
||||
if Target.Object and Target.Object:IsAlive()~=nil then
|
||||
local object=Target.Object --Wrapper.Group#GROUP
|
||||
|
||||
coal=object:GetCoalition()
|
||||
|
||||
end
|
||||
|
||||
elseif Target.Type==TARGET.ObjectType.UNIT then
|
||||
|
||||
if Target.Object and Target.Object:IsAlive()~=nil then
|
||||
local object=Target.Object --Wrapper.Unit#UNIT
|
||||
|
||||
coal=object:GetCoalition()
|
||||
|
||||
end
|
||||
|
||||
elseif Target.Type==TARGET.ObjectType.STATIC then
|
||||
local object=Target.Object --Wrapper.Static#STATIC
|
||||
|
||||
coal=object:GetCoalition()
|
||||
|
||||
elseif Target.Type==TARGET.ObjectType.SCENERY then
|
||||
|
||||
-- Scenery has no coalition.
|
||||
|
||||
elseif Target.Type==TARGET.ObjectType.AIRBASE then
|
||||
local object=Target.Object --Wrapper.Airbase#AIRBASE
|
||||
|
||||
coal=object:GetCoalition()
|
||||
|
||||
elseif Target.Type==TARGET.ObjectType.COORDINATE then
|
||||
|
||||
-- Coordinate has no coalition.
|
||||
|
||||
elseif Target.Type==TARGET.ObjectType.ZONE then
|
||||
|
||||
-- Zone has no coalition.
|
||||
|
||||
elseif Target.Type==TARGET.ObjectType.OPSZONE then
|
||||
local object=Target.Object --Ops.OpsZone#OPSZONE
|
||||
|
||||
coal=object:GetOwner()
|
||||
|
||||
else
|
||||
self:E("ERROR: unknown target category!")
|
||||
end
|
||||
|
||||
|
||||
return coal
|
||||
end
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- Misc Functions
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
@ -1692,14 +1792,45 @@ end
|
||||
|
||||
--- Get the first target objective alive.
|
||||
-- @param #TARGET self
|
||||
-- @param Core.Point#COORDINATE RefCoordinate (Optional) Reference coordinate to determine the closest target objective.
|
||||
-- @param #table Coalitions (Optional) Only consider targets of the given coalition(s).
|
||||
-- @return #TARGET.Object The target objective.
|
||||
function TARGET:GetObjective()
|
||||
function TARGET:GetObjective(RefCoordinate, Coalitions)
|
||||
|
||||
for _,_target in pairs(self.targets) do
|
||||
local target=_target --#TARGET.Object
|
||||
if target.Status~=TARGET.ObjectStatus.DEAD then
|
||||
return target
|
||||
if RefCoordinate then
|
||||
|
||||
local dmin=math.huge
|
||||
local tmin=nil --#TARGET.Object
|
||||
|
||||
for _,_target in pairs(self.targets) do
|
||||
local target=_target --#TARGET.Object
|
||||
|
||||
if target.Status~=TARGET.ObjectStatus.DEAD and (Coalitions==nil or UTILS.IsInTable(UTILS.EnsureTable(Coalitions), self:GetTargetCoalition(target))) then
|
||||
|
||||
local vec3=self:GetTargetVec3(target)
|
||||
|
||||
local d=UTILS.VecDist3D(vec3, RefCoordinate)
|
||||
|
||||
if d<dmin then
|
||||
dmin=d
|
||||
tmin=target
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
return tmin
|
||||
else
|
||||
|
||||
for _,_target in pairs(self.targets) do
|
||||
local target=_target --#TARGET.Object
|
||||
if target.Status~=TARGET.ObjectStatus.DEAD and (Coalitions==nil or UTILS.IsInTable(UTILS.EnsureTable(Coalitions), self:GetTargetCoalition(target))) then
|
||||
return target
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
return nil
|
||||
@ -1707,10 +1838,13 @@ end
|
||||
|
||||
--- Get the first target object alive.
|
||||
-- @param #TARGET self
|
||||
-- @param Core.Point#COORDINATE RefCoordinate Reference coordinate to determine the closest target objective.
|
||||
-- @param #table Coalitions (Optional) Only consider targets of the given coalition(s).
|
||||
-- @return Wrapper.Positionable#POSITIONABLE The target object or nil.
|
||||
function TARGET:GetObject()
|
||||
function TARGET:GetObject(RefCoordinate, Coalitions)
|
||||
|
||||
local target=self:GetObjective()
|
||||
local target=self:GetObjective(RefCoordinate, Coalitions)
|
||||
|
||||
if target then
|
||||
return target.Object
|
||||
end
|
||||
@ -1721,8 +1855,9 @@ end
|
||||
--- Count alive objects.
|
||||
-- @param #TARGET self
|
||||
-- @param #TARGET.Object Target Target objective.
|
||||
-- @param #table Coalitions (Optional) Only count targets of the given coalition(s).
|
||||
-- @return #number Number of alive target objects.
|
||||
function TARGET:CountObjectives(Target)
|
||||
function TARGET:CountObjectives(Target, Coalitions)
|
||||
|
||||
local N=0
|
||||
|
||||
@ -1735,7 +1870,9 @@ function TARGET:CountObjectives(Target)
|
||||
for _,_unit in pairs(units or {}) do
|
||||
local unit=_unit --Wrapper.Unit#UNIT
|
||||
if unit and unit:IsAlive()~=nil and unit:GetLife()>1 then
|
||||
N=N+1
|
||||
if Coalitions==nil or UTILS.IsInTable(UTILS.EnsureTable(Coalitions), unit:GetCoalition()) then
|
||||
N=N+1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -1744,7 +1881,9 @@ function TARGET:CountObjectives(Target)
|
||||
local target=Target.Object --Wrapper.Unit#UNIT
|
||||
|
||||
if target and target:IsAlive()~=nil and target:GetLife()>1 then
|
||||
N=N+1
|
||||
if Coalitions==nil or UTILS.IsInTable(Coalitions, target:GetCoalition()) then
|
||||
N=N+1
|
||||
end
|
||||
end
|
||||
|
||||
elseif Target.Type==TARGET.ObjectType.STATIC then
|
||||
@ -1752,7 +1891,9 @@ function TARGET:CountObjectives(Target)
|
||||
local target=Target.Object --Wrapper.Static#STATIC
|
||||
|
||||
if target and target:IsAlive() then
|
||||
N=N+1
|
||||
if Coalitions==nil or UTILS.IsInTable(Coalitions, target:GetCoalition()) then
|
||||
N=N+1
|
||||
end
|
||||
end
|
||||
|
||||
elseif Target.Type==TARGET.ObjectType.SCENERY then
|
||||
@ -1763,8 +1904,12 @@ function TARGET:CountObjectives(Target)
|
||||
|
||||
elseif Target.Type==TARGET.ObjectType.AIRBASE then
|
||||
|
||||
local target=Target.Object --Wrapper.Airbase#AIRBASE
|
||||
|
||||
if Target.Status==TARGET.ObjectStatus.ALIVE then
|
||||
N=N+1
|
||||
if Coalitions==nil or UTILS.IsInTable(Coalitions, target:GetCoalition()) then
|
||||
N=N+1
|
||||
end
|
||||
end
|
||||
|
||||
elseif Target.Type==TARGET.ObjectType.COORDINATE then
|
||||
@ -1774,7 +1919,15 @@ function TARGET:CountObjectives(Target)
|
||||
elseif Target.Type==TARGET.ObjectType.ZONE then
|
||||
|
||||
-- No target we can check!
|
||||
|
||||
|
||||
elseif Target.Type==TARGET.ObjectType.OPSZONE then
|
||||
|
||||
local target=Target.Object --Ops.OpsZone#OPSZONE
|
||||
|
||||
if Coalitions==nil or UTILS.IsInTable(Coalitions, target:GetOwner()) then
|
||||
N=N+1
|
||||
end
|
||||
|
||||
else
|
||||
self:E(self.lid.."ERROR: Unknown target type! Cannot count targets")
|
||||
end
|
||||
@ -1784,15 +1937,16 @@ end
|
||||
|
||||
--- Count alive targets.
|
||||
-- @param #TARGET self
|
||||
-- @param #table Coalitions (Optional) Only count targets of the given coalition(s).
|
||||
-- @return #number Number of alive target objects.
|
||||
function TARGET:CountTargets()
|
||||
function TARGET:CountTargets(Coalitions)
|
||||
|
||||
local N=0
|
||||
|
||||
for _,_target in pairs(self.targets) do
|
||||
local Target=_target --#TARGET.Object
|
||||
|
||||
N=N+self:CountObjectives(Target)
|
||||
N=N+self:CountObjectives(Target, Coalitions)
|
||||
|
||||
end
|
||||
|
||||
|
||||
@ -1061,8 +1061,8 @@ function UTILS.Vec2Norm(a)
|
||||
end
|
||||
|
||||
--- Calculate the distance between two 2D vectors.
|
||||
-- @param DCS#Vec2 a Vector in 3D with x, y components.
|
||||
-- @param DCS#Vec2 b Vector in 3D with x, y components.
|
||||
-- @param DCS#Vec2 a Vector in 2D with x, y components.
|
||||
-- @param DCS#Vec2 b Vector in 2D with x, y components.
|
||||
-- @return #number Distance between the vectors.
|
||||
function UTILS.VecDist2D(a, b)
|
||||
|
||||
@ -1446,6 +1446,30 @@ function UTILS.GetCoalitionName(Coalition)
|
||||
|
||||
end
|
||||
|
||||
--- Get the enemy coalition for a given coalition.
|
||||
-- @param #number Coalition The coalition ID.
|
||||
-- @param #boolean Neutral Include neutral as enemy.
|
||||
-- @return #table Enemy coalition table.
|
||||
function UTILS.GetCoalitionEnemy(Coalition, Neutral)
|
||||
|
||||
local Coalitions={}
|
||||
if Coalition then
|
||||
if Coalition==coalition.side.RED then
|
||||
Coalitions={coalition.side.BLUE}
|
||||
elseif Coalition==coalition.side.BLUE then
|
||||
Coalitions={coalition.side.RED}
|
||||
elseif Coalition==coalition.side.NEUTRAL then
|
||||
Coalitions={coalition.side.RED, coalition.side.BLUE}
|
||||
end
|
||||
end
|
||||
|
||||
if Neutral then
|
||||
table.insert(Coalitions, coalition.side.NEUTRAL)
|
||||
end
|
||||
|
||||
return Coalitions
|
||||
end
|
||||
|
||||
--- Get the modulation name from its numerical value.
|
||||
-- @param #number Modulation The modulation enumerator number. Can be either 0 or 1.
|
||||
-- @return #string The modulation name, i.e. "AM"=0 or "FM"=1. Anything else will return "Unknown".
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user