**AUFTRAG**
- Added *invisible* and *immortal* options

**TARGET**
- Added `AddResource` function

**OPSGROUP**
- Added *invisible* and *immortal* options

**LEGION**
- Fixed bug in properties requirement

**COMMANDER**
- Added `AddTarget` function (still **WIP**)

**ARMYGROUP**
- Fixed routing bug after teleporting
This commit is contained in:
Frank 2022-05-23 23:11:23 +02:00
parent 06d509b5ac
commit 62725b1930
9 changed files with 448 additions and 32 deletions

View File

@ -63,7 +63,7 @@ ARMYGROUP = {
--- Army Group version. --- Army Group version.
-- @field #string version -- @field #string version
ARMYGROUP.version="0.7.3" ARMYGROUP.version="0.7.9"
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO list -- TODO list
@ -880,6 +880,12 @@ function ARMYGROUP:onafterSpawned(From, Event, To)
-- Set default EPLRS. -- Set default EPLRS.
self:SwitchEPLRS(self.option.EPLRS) self:SwitchEPLRS(self.option.EPLRS)
-- Set default Invisible.
self:SwitchInvisible(self.option.Invisible)
-- Set default Immortal.
self:SwitchImmortal(self.option.Immortal)
-- Set TACAN to default. -- Set TACAN to default.
self:_SwitchTACAN() self:_SwitchTACAN()
@ -943,6 +949,9 @@ function ARMYGROUP:onbeforeUpdateRoute(From, Event, To, n, N, Speed, Formation)
elseif self:IsHolding() then elseif self:IsHolding() then
self:T(self.lid.."Update route denied. Group is holding position!") self:T(self.lid.."Update route denied. Group is holding position!")
return false return false
elseif self:IsEngaging() then
self:T(self.lid.."Update route allowed. Group is engaging!")
return true
end end
-- Check for a current task. -- Check for a current task.
@ -960,7 +969,7 @@ function ARMYGROUP:onbeforeUpdateRoute(From, Event, To, n, N, Speed, Formation)
self:T2(self.lid.."Allowing update route for Task: ReconMission") self:T2(self.lid.."Allowing update route for Task: ReconMission")
elseif task.dcstask.id==AUFTRAG.SpecialTask.RELOCATECOHORT then elseif task.dcstask.id==AUFTRAG.SpecialTask.RELOCATECOHORT then
-- For relocate -- For relocate
self:T2(self.lid.."Allowing update route for Task: Relocate Cohort") self:T2(self.lid.."Allowing update route for Task: Relocate Cohort")
else else
local taskname=task and task.description or "No description" local taskname=task and task.description or "No description"
self:T(self.lid..string.format("WARNING: Update route denied because taskcurrent=%d>0! Task description = %s", self.taskcurrent, tostring(taskname))) self:T(self.lid..string.format("WARNING: Update route denied because taskcurrent=%d>0! Task description = %s", self.taskcurrent, tostring(taskname)))
@ -1117,7 +1126,7 @@ function ARMYGROUP:onafterUpdateRoute(From, Event, To, n, N, Speed, Formation)
self.speedWp=wp.speed self.speedWp=wp.speed
-- Debug output. -- Debug output.
if self.verbose>=10 then if self.verbose>=10 or true then
for i,_wp in pairs(waypoints) do for i,_wp in pairs(waypoints) do
local wp=_wp --Ops.OpsGroup#OPSGROUP.Waypoint local wp=_wp --Ops.OpsGroup#OPSGROUP.Waypoint

View File

@ -111,6 +111,9 @@
-- @field #number artyAngle Shooting angle in degrees (for Barrage). -- @field #number artyAngle Shooting angle in degrees (for Barrage).
-- --
-- @field #string alert5MissionType Alert 5 mission type. This is the mission type, the alerted assets will be able to carry out. -- @field #string alert5MissionType Alert 5 mission type. This is the mission type, the alerted assets will be able to carry out.
--
-- @field #table attributes Generalized attribute(s) of assets.
-- @field #table properties DCS attribute(s) of assets.
-- --
-- @field Ops.Chief#CHIEF chief The CHIEF managing this mission. -- @field Ops.Chief#CHIEF chief The CHIEF managing this mission.
-- @field Ops.Commander#COMMANDER commander The COMMANDER managing this mission. -- @field Ops.Commander#COMMANDER commander The COMMANDER managing this mission.
@ -168,6 +171,8 @@
-- @field #number optionRTBfuel RTB on out-of-fuel. -- @field #number optionRTBfuel RTB on out-of-fuel.
-- @field #number optionECM ECM. -- @field #number optionECM ECM.
-- @field #boolean optionEmission Emission is on or off. -- @field #boolean optionEmission Emission is on or off.
-- @field #boolean optionInvisible Invisible is on/off.
-- @field #boolean optionImmortal Immortal is on/off.
-- --
-- @extends Core.Fsm#FSM -- @extends Core.Fsm#FSM
@ -1763,7 +1768,7 @@ end
--- **[GROUND, NAVAL]** Create an ARTY mission. --- **[GROUND, NAVAL]** Create an ARTY mission.
-- @param #AUFTRAG self -- @param #AUFTRAG self
-- @param Core.Point#COORDINATE Target Center of the firing solution. -- @param Core.Point#COORDINATE Target Center of the firing solution.
-- @param #number Nshots Number of shots to be fired. Default 3. -- @param #number Nshots Number of shots to be fired. Default `#nil`.
-- @param #number Radius Radius of the shells in meters. Default 100 meters. -- @param #number Radius Radius of the shells in meters. Default 100 meters.
-- @param #number Altitude Altitude in meters. Can be used to setup a Barrage. Default `#nil`. -- @param #number Altitude Altitude in meters. Can be used to setup a Barrage. Default `#nil`.
-- @return #AUFTRAG self -- @return #AUFTRAG self
@ -2196,7 +2201,9 @@ function AUFTRAG:NewFromTarget(Target, MissionType)
elseif MissionType==AUFTRAG.Type.STRIKE then elseif MissionType==AUFTRAG.Type.STRIKE then
mission=self:NewSTRIKE(Target, Altitude) mission=self:NewSTRIKE(Target, Altitude)
elseif MissionType==AUFTRAG.Type.ARMORATTACK then elseif MissionType==AUFTRAG.Type.ARMORATTACK then
mission=self:NewARMORATTACK(Target,Speed) mission=self:NewARMORATTACK(Target, Speed)
elseif MissionType==AUFTRAG.Type.GROUNDATTACK then
mission=self:NewGROUNDATTACK(Target, Speed, Formation)
else else
return nil return nil
end end
@ -2970,6 +2977,36 @@ function AUFTRAG:SetEmission(OnOffSwitch)
return self return self
end end
--- Set invisibility setting for this mission.
-- @param #AUFTRAG self
-- @param #boolean OnOffSwitch If `true` or `nil`, invisible is on. If `false`, invisible is off.
-- @return #AUFTRAG self
function AUFTRAG:SetInvisible(OnOffSwitch)
if OnOffSwitch==nil then
self.optionInvisible=true
else
self.optionInvisible=OnOffSwitch
end
return self
end
--- Set immortality setting for this mission.
-- @param #AUFTRAG self
-- @param #boolean OnOffSwitch If `true` or `nil`, immortal is on. If `false`, immortal is off.
-- @return #AUFTRAG self
function AUFTRAG:SetImmortal(OnOffSwitch)
if OnOffSwitch==nil then
self.optionImmortal=true
else
self.optionImmortal=OnOffSwitch
end
return self
end
--- Set formation for this mission. --- Set formation for this mission.
-- @param #AUFTRAG self -- @param #AUFTRAG self
-- @param #number Formation Formation. -- @param #number Formation Formation.

View File

@ -24,6 +24,7 @@
-- @field #table legions Table of legions which are commanded. -- @field #table legions Table of legions which are commanded.
-- @field #table missionqueue Mission queue. -- @field #table missionqueue Mission queue.
-- @field #table transportqueue Transport queue. -- @field #table transportqueue Transport queue.
-- @field #table targetqueue Target queue.
-- @field #table rearmingZones Rearming zones. Each element is of type `#BRIGADE.SupplyZone`. -- @field #table rearmingZones Rearming zones. Each element is of type `#BRIGADE.SupplyZone`.
-- @field #table refuellingZones Refuelling zones. Each element is of type `#BRIGADE.SupplyZone`. -- @field #table refuellingZones Refuelling zones. Each element is of type `#BRIGADE.SupplyZone`.
-- @field #table capZones CAP zones. Each element is of type `#AIRWING.PatrolZone`. -- @field #table capZones CAP zones. Each element is of type `#AIRWING.PatrolZone`.
@ -125,6 +126,7 @@ COMMANDER = {
legions = {}, legions = {},
missionqueue = {}, missionqueue = {},
transportqueue = {}, transportqueue = {},
targetqueue = {},
rearmingZones = {}, rearmingZones = {},
refuellingZones = {}, refuellingZones = {},
capZones = {}, capZones = {},
@ -514,6 +516,55 @@ function COMMANDER:RemoveTransport(Transport)
return self return self
end end
--- Add target.
-- @param #COMMANDER self
-- @param Ops.Target#TARGET Target Target object to be added.
-- @return #COMMANDER self
function COMMANDER:AddTarget(Target)
if not self:IsTarget(Target) then
table.insert(self.targetqueue, Target)
end
return self
end
--- Check if a TARGET is already in the queue.
-- @param #COMMANDER self
-- @param Ops.Target#TARGET Target Target object to be added.
-- @return #boolean If `true`, target exists in the target queue.
function COMMANDER:IsTarget(Target)
for _,_target in pairs(self.targetqueue) do
local target=_target --Ops.Target#TARGET
if target.uid==Target.uid or target:GetName()==Target:GetName() then
return true
end
end
return false
end
--- Remove target from queue.
-- @param #COMMANDER self
-- @param Ops.Target#TARGET Target The target.
-- @return #COMMANDER self
function COMMANDER:RemoveTarget(Target)
for i,_target in pairs(self.targetqueue) do
local target=_target --Ops.Target#TARGET
if target.uid==Target.uid then
self:T(self.lid..string.format("Removing target %s from queue", Target.name))
table.remove(self.targetqueue, i)
break
end
end
return self
end
--- Add a rearming zone. --- Add a rearming zone.
-- @param #COMMANDER self -- @param #COMMANDER self
-- @param Core.Zone#ZONE RearmingZone Rearming zone. -- @param Core.Zone#ZONE RearmingZone Rearming zone.
@ -789,6 +840,9 @@ function COMMANDER:onafterStatus(From, Event, To)
local text=string.format("Status %s: Legions=%d, Missions=%d, Transports", fsmstate, #self.legions, #self.missionqueue, #self.transportqueue) local text=string.format("Status %s: Legions=%d, Missions=%d, Transports", fsmstate, #self.legions, #self.missionqueue, #self.transportqueue)
self:T(self.lid..text) self:T(self.lid..text)
end end
-- Check target queue and add missions.
self:CheckTargetQueue()
-- Check mission queue and assign one PLANNED mission. -- Check mission queue and assign one PLANNED mission.
self:CheckMissionQueue() self:CheckMissionQueue()
@ -1148,6 +1202,95 @@ end
-- Mission Functions -- Mission Functions
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- Check target queue and assign ONE valid target by adding it to the mission queue of the COMMANDER.
-- @param #COMMANDER self
function COMMANDER:CheckTargetQueue()
-- Number of missions.
local Ntargets=#self.targetqueue
-- Treat special cases.
if Ntargets==0 then
return nil
end
-- Check if total number of missions is reached.
local NoLimit=self:_CheckMissionLimit("Total")
if NoLimit==false then
return nil
end
-- Sort results table wrt prio and threatlevel.
local function _sort(a, b)
local taskA=a --Ops.Target#TARGET
local taskB=b --Ops.Target#TARGET
return (taskA.prio<taskB.prio) or (taskA.prio==taskB.prio and taskA.threatlevel0>taskB.threatlevel0)
end
table.sort(self.targetqueue, _sort)
-- Get the lowest importance value (lower means more important).
-- If a target with importance 1 exists, targets with importance 2 will not be assigned. Targets with no importance (nil) can still be selected.
local vip=math.huge
for _,_target in pairs(self.targetqueue) do
local target=_target --Ops.Target#TARGET
if target:IsAlive() and target.importance and target.importance<vip then
vip=target.importance
end
end
-- Loop over targets.
for _,_target in pairs(self.targetqueue) do
local target=_target --Ops.Target#TARGET
-- Is target still alive.
local isAlive=target:IsAlive()
-- Is this target important enough.
local isImportant=(target.importance==nil or target.importance<=vip)
-- Debug message.
local text=string.format("Target %s: Alive=%s, Threat=%s, Important=%s", target:GetName(), tostring(isAlive), tostring(isThreat), tostring(isImportant))
self:T2(self.lid..text)
-- Check that target is alive and not already a mission has been assigned.
if isAlive and isImportant then
for _,_resource in pairs(target.resources or {}) do
local resource=_resource --Ops.Target#TARGET.Resource
-- Mission type.
local missionType=resource.MissionType
if (not resource.mission) or resource.mission:IsOver() then
-- Debug info.
self:T2(self.lid..string.format("Target \"%s\" ==> Creating mission type %s: Nmin=%d, Nmax=%d", target:GetName(), missionType, resource.Nmin, resource.Nmax))
-- Create a mission.
local mission=AUFTRAG:NewFromTarget(target, missionType)
if mission then
mission:SetRequiredAssets(resource.Nmin, resource.Nmax)
mission:SetRequiredAttribute(resource.Attributes)
mission:SetRequiredProperty(resource.Properties)
resource.mission=mission
-- Add mission to queue.
self:AddMission(resource.mission)
end
end
end
end
end
end
--- Check mission queue and assign ONE planned mission. --- Check mission queue and assign ONE planned mission.
-- @param #COMMANDER self -- @param #COMMANDER self
function COMMANDER:CheckMissionQueue() function COMMANDER:CheckMissionQueue()

View File

@ -183,7 +183,7 @@ FLIGHTGROUP.RadioMessage = {
--- FLIGHTGROUP class version. --- FLIGHTGROUP class version.
-- @field #string version -- @field #string version
FLIGHTGROUP.version="0.7.3" FLIGHTGROUP.version="0.7.9"
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO list -- TODO list
@ -1549,6 +1549,12 @@ function FLIGHTGROUP:onafterSpawned(From, Event, To)
-- Set default EPLRS. -- Set default EPLRS.
self:SwitchEPLRS(self.option.EPLRS) self:SwitchEPLRS(self.option.EPLRS)
-- Set default Invisible.
self:SwitchInvisible(self.option.Invisible)
-- Set default Immortal.
self:SwitchImmortal(self.option.Immortal)
-- Set Formation -- Set Formation
self:SwitchFormation(self.option.Formation) self:SwitchFormation(self.option.Formation)

View File

@ -2246,7 +2246,7 @@ function LEGION.RecruitCohortAssets(Cohorts, MissionTypeRecruit, MissionTypeOpt,
local cohort=_cohort --Ops.Cohort#COHORT local cohort=_cohort --Ops.Cohort#COHORT
if Properties and #Properties>0 then if Properties and #Properties>0 then
for _,Property in pairs(Properties) do for _,Property in pairs(Properties) do
for _,property in pairs(cohort.properties) do for property,value in pairs(cohort.properties) do
if Property==property then if Property==property then
return true return true
end end
@ -2277,8 +2277,8 @@ function LEGION.RecruitCohortAssets(Cohorts, MissionTypeRecruit, MissionTypeOpt,
else else
return true return true
end end
end end
-- Loops over cohorts. -- Loops over cohorts.
for _,_cohort in pairs(Cohorts) do for _,_cohort in pairs(Cohorts) do
local cohort=_cohort --Ops.Cohort#COHORT local cohort=_cohort --Ops.Cohort#COHORT
@ -2329,7 +2329,7 @@ function LEGION.RecruitCohortAssets(Cohorts, MissionTypeRecruit, MissionTypeOpt,
end end
-- Debug info. -- Debug info.
cohort:T2(cohort.lid..string.format("State=%s: Capable=%s, InRange=%s, Refuel=%s, CanCarry=%s, Category=%s, Attribute=%s, Property=%s, Weapon=%s", cohort:I(cohort.lid..string.format("State=%s: Capable=%s, InRange=%s, Refuel=%s, CanCarry=%s, Category=%s, Attribute=%s, Property=%s, Weapon=%s",
cohort:GetState(), tostring(Capable), tostring(InRange), tostring(Refuel), tostring(CanCarry), tostring(RightCategory), tostring(RightAttribute), tostring(RightProperty), tostring(RightWeapon))) cohort:GetState(), tostring(Capable), tostring(InRange), tostring(Refuel), tostring(CanCarry), tostring(RightCategory), tostring(RightAttribute), tostring(RightProperty), tostring(RightWeapon)))
-- Check OnDuty, capable, in range and refueling type (if TANKER). -- Check OnDuty, capable, in range and refueling type (if TANKER).

View File

@ -90,7 +90,7 @@ NAVYGROUP = {
--- NavyGroup version. --- NavyGroup version.
-- @field #string version -- @field #string version
NAVYGROUP.version="0.7.3" NAVYGROUP.version="0.7.9"
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO list -- TODO list
@ -987,8 +987,17 @@ function NAVYGROUP:onafterSpawned(From, Event, To)
-- Set default Alarm State. -- Set default Alarm State.
self:SwitchAlarmstate(self.option.Alarm) self:SwitchAlarmstate(self.option.Alarm)
-- Set emission.
self:SwitchEmission(self.option.Emission)
-- Set default EPLRS. -- Set default EPLRS.
self:SwitchEPLRS(self.option.EPLRS) self:SwitchEPLRS(self.option.EPLRS)
-- Set default Invisible.
self:SwitchInvisible(self.option.Invisible)
-- Set default Immortal.
self:SwitchImmortal(self.option.Immortal)
-- Set TACAN beacon. -- Set TACAN beacon.
self:_SwitchTACAN() self:_SwitchTACAN()

View File

@ -308,6 +308,18 @@ OPSGROUP.TaskType={
-- @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. -- @field #number backupROE Rules of engagement that are restored once the task is over.
--- Option data.
-- @type OPSGROUP.Option
-- @field #number ROE Rule of engagement.
-- @field #number ROT Reaction on threat.
-- @field #number Alarm Alarm state.
-- @field #number Formation Formation.
-- @field #boolean EPLRS data link.
-- @field #boolean Disperse Disperse under fire.
-- @field #boolean Emission Emission on/off.
-- @field #boolean Invisible Invisible on/off.
-- @field #boolean Immortal Immortal on/off.
--- Beacon data. --- Beacon data.
-- @type OPSGROUP.Beacon -- @type OPSGROUP.Beacon
-- @field #number Channel Channel. -- @field #number Channel Channel.
@ -329,16 +341,6 @@ OPSGROUP.TaskType={
-- @field #number NumberGroup Group number. First number after name, e.g. "Uzi-**1**-1". -- @field #number NumberGroup Group number. First number after name, e.g. "Uzi-**1**-1".
-- @field #string NameSquad Name of the squad, e.g. "Uzi". -- @field #string NameSquad Name of the squad, e.g. "Uzi".
--- Option data.
-- @type OPSGROUP.Option
-- @field #number ROE Rule of engagement.
-- @field #number ROT Reaction on threat.
-- @field #number Alarm Alarm state.
-- @field #number Formation Formation.
-- @field #boolean EPLRS data link.
-- @field #boolean Disperse Disperse under fire.
-- @field #boolean Emission Emission on/off.
--- Weapon range data. --- Weapon range data.
-- @type OPSGROUP.WeaponData -- @type OPSGROUP.WeaponData
-- @field #number BitType Type of weapon. -- @field #number BitType Type of weapon.
@ -469,21 +471,21 @@ OPSGROUP.CargoStatus={
--- OpsGroup version. --- OpsGroup version.
-- @field #string version -- @field #string version
OPSGROUP.version="0.7.8" OPSGROUP.version="0.7.9"
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO list -- TODO list
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO: AI on/off. -- TODO: AI on/off.
-- TODO: Emission on/off.
-- TODO: Invisible/immortal.
-- TODO: F10 menu. -- TODO: F10 menu.
-- TODO: Add pseudo function. -- TODO: Add pseudo function.
-- TODO: Afterburner restrict. -- TODO: Afterburner restrict.
-- TODO: What more options? -- TODO: What more options?
-- TODO: Shot events? -- TODO: Shot events?
-- TODO: Marks to add waypoints/tasks on-the-fly. -- TODO: Marks to add waypoints/tasks on-the-fly.
-- DONE: Invisible/immortal.
-- DONE: Emission on/off
-- DONE: Damage? -- DONE: Damage?
-- DONE: Options EPLRS -- DONE: Options EPLRS
@ -4997,6 +4999,14 @@ function OPSGROUP:onafterMissionDone(From, Event, To, Mission)
if Mission.optionEmission then if Mission.optionEmission then
self:SwitchEmission() self:SwitchEmission()
end end
-- Invisible to default.
if Mission.optionInvisible then
self:SwitchInvisible()
end
-- Immortal to default.
if Mission.optionImmortal then
self:SwitchImmortal()
end
-- Formation to default. -- Formation to default.
if Mission.optionFormation and self:IsFlightgroup() then if Mission.optionFormation and self:IsFlightgroup() then
self:SwitchFormation() self:SwitchFormation()
@ -5103,9 +5113,13 @@ function OPSGROUP:RouteToMission(mission, delay)
self:MissionExecute(mission) self:MissionExecute(mission)
return return
end end
if self.speedMax<=3.6 or mission.teleport then
--self:ClearWaypoints()
end
-- ID of current waypoint. -- ID of current waypoint.
local uid=self:GetWaypointCurrent().uid local uid=self:GetWaypointCurrentUID()
-- Ingress waypoint coordinate where the mission is executed. -- Ingress waypoint coordinate where the mission is executed.
local waypointcoord=nil --Core.Point#COORDINATE local waypointcoord=nil --Core.Point#COORDINATE
@ -5113,6 +5127,8 @@ function OPSGROUP:RouteToMission(mission, delay)
-- Current coordinate of the group. -- Current coordinate of the group.
local currentcoord=self:GetCoordinate() local currentcoord=self:GetCoordinate()
currentcoord:MarkToAll(mission:GetName(),ReadOnly,Text)
-- Road connection. -- Road connection.
local roadcoord=currentcoord:GetClosestPointToRoad() local roadcoord=currentcoord:GetClosestPointToRoad()
@ -5173,6 +5189,7 @@ function OPSGROUP:RouteToMission(mission, delay)
-- Random coordinate. -- Random coordinate.
waypointcoord=targetzone:GetRandomCoordinate(nil , nil, surfacetypes) waypointcoord=targetzone:GetRandomCoordinate(nil , nil, surfacetypes)
waypointcoord:MarkToAll(mission:GetName(),ReadOnly,Text)
elseif mission.type==AUFTRAG.Type.ONGUARD or mission.type==AUFTRAG.Type.ARMOREDGUARD then elseif mission.type==AUFTRAG.Type.ONGUARD or mission.type==AUFTRAG.Type.ARMOREDGUARD then
--- ---
-- Guard -- Guard
@ -5237,7 +5254,7 @@ function OPSGROUP:RouteToMission(mission, delay)
waypointcoord=CarrierCoordinate:Translate(10000, heading-180):SetAltitude(2000) waypointcoord=CarrierCoordinate:Translate(10000, heading-180):SetAltitude(2000)
waypointcoord:MarkToAll("Recoverytanker",ReadOnly,Text) waypointcoord:MarkToAll("Recoverytanker")
else else
--- ---
@ -5466,9 +5483,17 @@ function OPSGROUP:_SetMissionOptions(mission)
self:SwitchEPLRS(mission.optionEPLRS) self:SwitchEPLRS(mission.optionEPLRS)
end end
-- Emission -- Emission
if mission.optionEPLRS then if mission.optionEmission then
self:SwitchEmission(mission.optionEmission) self:SwitchEmission(mission.optionEmission)
end end
-- Invisible
if mission.optionInvisible then
self:SwitchInvisible(mission.optionInvisible)
end
-- Immortal
if mission.optionImmortal then
self:SwitchImmortal(mission.optionImmortal)
end
-- Formation -- Formation
if mission.optionFormation and self:IsFlightgroup() then if mission.optionFormation and self:IsFlightgroup() then
self:SwitchFormation(mission.optionFormation) self:SwitchFormation(mission.optionFormation)
@ -6762,6 +6787,10 @@ function OPSGROUP:Teleport(Coordinate, Delay, NoPauseMission)
-- Set waypoint in air for flighgroups. -- Set waypoint in air for flighgroups.
if self:IsFlightgroup() then if self:IsFlightgroup() then
Template.route.points[1]=Coordinate:WaypointAir("BARO", COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.TurningPoint, 300, true, nil, nil, "Spawnpoint") Template.route.points[1]=Coordinate:WaypointAir("BARO", COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.TurningPoint, 300, true, nil, nil, "Spawnpoint")
elseif self:IsArmygroup() then
Template.route.points[1]=Coordinate:WaypointGround()
elseif self:IsNavygroup() then
Template.route.points[1]=Coordinate:WaypointNaval()
end end
-- Template units. -- Template units.
@ -10790,6 +10819,103 @@ function OPSGROUP:GetEmission()
return self.option.Emission or self.optionDefault.Emission return self.option.Emission or self.optionDefault.Emission
end end
--- Set the default invisible for the group.
-- @param #OPSGROUP self
-- @param #boolean OnOffSwitch If `true`, group is ivisible by default.
-- @return #OPSGROUP self
function OPSGROUP:SetDefaultInvisible(OnOffSwitch)
if OnOffSwitch==nil then
self.optionDefault.Invisible=true
else
self.optionDefault.Invisible=OnOffSwitch
end
return self
end
--- Switch invisibility on or off.
-- @param #OPSGROUP self
-- @param #boolean OnOffSwitch If `true` or `nil`, switch invisibliity on. If `false` invisibility switched off.
-- @return #OPSGROUP self
function OPSGROUP:SwitchInvisible(OnOffSwitch)
if self:IsAlive() or self:IsInUtero() then
if OnOffSwitch==nil then
self.option.Invisible=self.optionDefault.Invisible
else
self.option.Invisible=OnOffSwitch
end
if self:IsInUtero() then
self:T2(self.lid..string.format("Setting current INVISIBLE=%s when GROUP is SPAWNED", tostring(self.option.Invisible)))
else
self.group:SetCommandInvisible(self.option.Invisible)
self:T(self.lid..string.format("Setting current INVISIBLE=%s", tostring(self.option.Invisible)))
end
else
self:E(self.lid.."WARNING: Cannot switch Invisible! Group is not alive")
end
return self
end
--- Set the default immortal for the group.
-- @param #OPSGROUP self
-- @param #boolean OnOffSwitch If `true`, group is immortal by default.
-- @return #OPSGROUP self
function OPSGROUP:SetDefaultImmortal(OnOffSwitch)
if OnOffSwitch==nil then
self.optionDefault.Immortal=true
else
self.optionDefault.Immortal=OnOffSwitch
end
return self
end
--- Switch immortality on or off.
-- @param #OPSGROUP self
-- @param #boolean OnOffSwitch If `true` or `nil`, switch immortality on. If `false` immortality switched off.
-- @return #OPSGROUP self
function OPSGROUP:SwitchImmortal(OnOffSwitch)
if self:IsAlive() or self:IsInUtero() then
if OnOffSwitch==nil then
self.option.Immortal=self.optionDefault.Immortal
else
self.option.Immortal=OnOffSwitch
end
if self:IsInUtero() then
self:T2(self.lid..string.format("Setting current IMMORTAL=%s when GROUP is SPAWNED", tostring(self.option.Immortal)))
else
self.group:SetCommandImmortal(self.option.Immortal)
self:T(self.lid..string.format("Setting current IMMORTAL=%s", tostring(self.option.Immortal)))
end
else
self:E(self.lid.."WARNING: Cannot switch Immortal! Group is not alive")
end
return self
end
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- SETTINGS FUNCTIONS -- SETTINGS FUNCTIONS
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

View File

@ -2,8 +2,9 @@
-- --
-- **Main Features:** -- **Main Features:**
-- --
-- * Monitor if a zone is captured. -- * Monitor if a zone is captured
-- * Monitor if an airbase is captured. -- * Monitor if an airbase is captured
-- * Define conditions under which zones are captured/held
-- --
-- === -- ===
-- --
@ -79,6 +80,7 @@ OPSZONE.version="0.3.0"
-- ToDo list -- 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: Pause/unpause evaluations.
-- TODO: Capture time, i.e. time how long a single coalition has to be inside the zone to capture it. -- 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. -- TODO: Differentiate between ground attack and boming by air or arty.
@ -348,7 +350,7 @@ end
--- Set categories of units that can capture or hold the zone. See [DCS Class Unit](https://wiki.hoggitworld.com/view/DCS_Class_Unit). --- Set categories of units that can capture or hold the zone. See [DCS Class Unit](https://wiki.hoggitworld.com/view/DCS_Class_Unit).
-- @param #OPSZONE self -- @param #OPSZONE self
-- @param #table Categories Table of unit categories. Default `{Unit.Category.GROUND_UNIT}`. -- @param #table Categories Table of unit categories. Default `{Unit.Category.GROUND_UNIT}`.
-- @return #OPSZONE -- @return #OPSZONE self
function OPSZONE:SetUnitCategories(Categories) function OPSZONE:SetUnitCategories(Categories)
-- Ensure table. -- Ensure table.
@ -362,6 +364,32 @@ function OPSZONE:SetUnitCategories(Categories)
return self return self
end end
--- Set threat level threshold that the defending units must have to hold a zone.
-- The reason why you might want to set this is that unarmed units (*e.g.* fuel trucks) should not be able to hold a zone as they do not pose a threat.
-- @param #OPSZONE self
-- @param #number Threatlevel Threat level threshod. Default 0.
-- @return #OPSZONE self
function OPSZONE:SetThreatlevelDefinding(Threatlevel)
self.threatlevelDefending=Threatlevel or 0
return self
end
--- Set threat level threshold that the offending units must have to capture a zone.
-- The reason why you might want to set this is that unarmed units (*e.g.* fuel trucks) should not be able to capture a zone as they do not pose a threat.
-- @param #OPSZONE self
-- @param #number Threatlevel Threat level threshod. Default 0.
-- @return #OPSZONE self
function OPSZONE:SetThreatlevelOffending(Threatlevel)
self.threatlevelOffending=Threatlevel or 0
return self
end
--- Set whether *neutral* units can capture the zone. --- Set whether *neutral* units can capture the zone.
-- @param #OPSZONE self -- @param #OPSZONE self
-- @param #boolean CanCapture If `true`, neutral units can. -- @param #boolean CanCapture If `true`, neutral units can.

View File

@ -36,6 +36,7 @@
-- @field Ops.Auftrag#AUFTRAG mission Mission attached to this target. -- @field Ops.Auftrag#AUFTRAG mission Mission attached to this target.
-- @field Ops.Intelligence#INTEL.Contact contact Contact attached to this target. -- @field Ops.Intelligence#INTEL.Contact contact Contact attached to this target.
-- @field #boolean isDestroyed If true, target objects were destroyed. -- @field #boolean isDestroyed If true, target objects were destroyed.
-- @field #table resources Resource list.
-- @extends Core.Fsm#FSM -- @extends Core.Fsm#FSM
--- **It is far more important to be able to hit the target than it is to haggle over who makes a weapon or who pulls a trigger** -- Dwight D Eisenhower --- **It is far more important to be able to hit the target than it is to haggle over who makes a weapon or who pulls a trigger** -- Dwight D Eisenhower
@ -113,6 +114,16 @@ TARGET.ObjectStatus={
ALIVE="Alive", ALIVE="Alive",
DEAD="Dead", DEAD="Dead",
} }
--- Resource.
-- @type TARGET.Resource
-- @field #string MissionType Mission type, e.g. `AUFTRAG.Type.BAI`.
-- @field #number Nmin Min number of assets.
-- @field #number Nmax Max number of assets.
-- @field #table Attributes Generalized attribute, e.g. `{GROUP.Attribute.GROUND_INFANTRY}`.
-- @field #table Properties Properties ([DCS attributes](https://wiki.hoggitworld.com/view/DCS_enum_attributes)), e.g. `"Attack helicopters"` or `"Mobile AAA"`.
-- @field Ops.Auftrag#AUFTRAG mission Attached mission.
--- Target object. --- Target object.
-- @type TARGET.Object -- @type TARGET.Object
-- @field #number ID Target unique ID. -- @field #number ID Target unique ID.
@ -307,6 +318,53 @@ function TARGET:SetImportance(Importance)
return self return self
end end
--- Add mission type and number of required assets to resource.
-- @param #TARGET self
-- @param #string MissionType Mission Type.
-- @param #number Nmin Min number of required assets.
-- @param #number Nmax Max number of requried assets.
-- @param #table Attributes Generalized attribute(s).
-- @param #table Properties DCS attribute(s). Default `nil`.
-- @return #TARGET.Resource The resource table.
function TARGET:AddResource(MissionType, Nmin, Nmax, Attributes, Properties)
-- Ensure table.
if Attributes and type(Attributes)~="table" then
Attributes={Attributes}
end
-- Ensure table.
if Properties and type(Properties)~="table" then
Properties={Properties}
end
-- Create new resource table.
local resource={} --#TARGET.Resource
resource.MissionType=MissionType
resource.Nmin=Nmin or 1
resource.Nmax=Nmax or 1
resource.Attributes=Attributes or {}
resource.Properties=Properties or {}
-- Init resource table.
self.resources=self.resources or {}
-- Add to table.
table.insert(self.resources, resource)
-- Debug output.
if self.verbose>10 then
local text="Resource:"
for _,_r in pairs(self.resources) do
local r=_r --#TARGET.Resource
text=text..string.format("\nmission=%s, Nmin=%d, Nmax=%d, attribute=%s, properties=%s", r.MissionType, r.Nmin, r.Nmax, tostring(r.Attributes[1]), tostring(r.Properties[1]))
end
self:I(self.lid..text)
end
return resource
end
--- Check if TARGET is alive. --- Check if TARGET is alive.
-- @param #TARGET self -- @param #TARGET self
-- @return #boolean If true, target is alive. -- @return #boolean If true, target is alive.