- Added new AUFTRAG type  CASENHANCED
- Improved capturing of OPSZONES by CHIEF
This commit is contained in:
Frank
2022-03-05 14:43:34 +01:00
parent f3d0d55a2f
commit 3557706e3a
7 changed files with 364 additions and 175 deletions
+65 -1
View File
@@ -384,6 +384,7 @@ _AUFTRAGSNR=0
-- @field #string ARMOREDGUARD On guard - with armored groups.
-- @field #string BARRAGE Barrage.
-- @field #string ARMORATTACK Armor attack.
-- @field #string CASENHANCED Enhanced CAS.
AUFTRAG.Type={
ANTISHIP="Anti Ship",
AWACS="AWACS",
@@ -416,6 +417,7 @@ AUFTRAG.Type={
ARMOREDGUARD="Armored Guard",
BARRAGE="Barrage",
ARMORATTACK="Armor Attack",
CASENHANCED="CAS Enhanced",
}
--- Mission status of an assigned group.
@@ -558,7 +560,7 @@ AUFTRAG.Category={
--- AUFTRAG class version.
-- @field #string version
AUFTRAG.version="0.8.2"
AUFTRAG.version="0.8.3"
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO list
@@ -1187,6 +1189,45 @@ function AUFTRAG:NewCAS(ZoneCAS, Altitude, Speed, Coordinate, Heading, Leg, Targ
return mission
end
--- **[AIR]** Create a CASENHANCED mission. Group(s) will go to the zone and patrol it randomly.
-- @param #AUFTRAG self
-- @param Core.Zone#ZONE CasZone The CAS zone.
-- @param #number Altitude Altitude in feet. Only for airborne units. Default 2000 feet ASL.
-- @param #number Speed Speed in knots.
-- @param #number RangeMax Max range in NM. Only detected targets within this radius from the group 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 `{"Helicopters", "Ground Units", "Light armed ships"}`.
-- @param Core.Set#SET_ZONE NoEngageZoneSet Set of zones in which targets are *not* engaged. Default is nowhere.
-- @return #AUFTRAG self
function AUFTRAG:NewCASENHANCED(CasZone, Altitude, Speed, RangeMax, NoEngageZoneSet, TargetTypes)
local mission=AUFTRAG:New(AUFTRAG.Type.CASENHANCED)
-- Ensure we got a ZONE and not just the zone name.
if type(CasZone)=="string" then
CasZone=ZONE:New(CasZone)
end
mission:_TargetFromObject(CasZone)
mission.missionTask=mission:GetMissionTaskforMissionType(AUFTRAG.Type.CASENHANCED)
mission:SetEngageDetected(RangeMax, TargetTypes or {"Helicopters", "Ground Units", "Light armed ships"}, CasZone, NoEngageZoneSet)
mission.optionROE=ENUMS.ROE.OpenFire
mission.optionROT=ENUMS.ROT.EvadeFire
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.AIRCRAFT}
mission.DCStask=mission:GetDCSMissionTask()
return mission
end
--- **[AIR]** Create a FACA mission.
-- @param #AUFTRAG self
-- @param Wrapper.Group#GROUP Target Target group. Must be a GROUP object.
@@ -1678,6 +1719,7 @@ function AUFTRAG:NewPATROLZONE(Zone, Speed, Altitude)
return mission
end
--- **[GROUND]** Create a ARMORATTACK mission. Armoured ground group(s) will go to the zone and attack.
-- @param #AUFTRAG self
-- @param Wrapper.Positionable#POSITIONABLE Target The target to attack. Can be a GROUP, UNIT or STATIC object.
@@ -4942,6 +4984,26 @@ function AUFTRAG:GetDCSMissionTask(TaskControllable)
DCStask.params=param
table.insert(DCStasks, DCStask)
elseif self.type==AUFTRAG.Type.CASENHANCED then
-------------------------
-- CAS ENHANCED Mission --
-------------------------
local DCStask={}
DCStask.id="PatrolZone"
-- We create a "fake" DCS task and pass the parameters to the FLIGHTGROUP.
local param={}
param.zone=self:GetObjective()
param.altitude=self.missionAltitude
param.speed=self.missionSpeed
DCStask.params=param
table.insert(DCStasks, DCStask)
elseif self.type==AUFTRAG.Type.ARMORATTACK then
@@ -5131,6 +5193,8 @@ function AUFTRAG:GetMissionTaskforMissionType(MissionType)
mtask=ENUMS.MissionTask.CAS
elseif MissionType==AUFTRAG.Type.PATROLZONE then
mtask=ENUMS.MissionTask.CAS
elseif MissionType==AUFTRAG.Type.CASENHANCED then
mtask=ENUMS.MissionTask.CAS
elseif MissionType==AUFTRAG.Type.ESCORT then
mtask=ENUMS.MissionTask.ESCORT
elseif MissionType==AUFTRAG.Type.FACA then
+41 -4
View File
@@ -103,7 +103,7 @@
--
-- Strategically important zones, which should be captured can be added via the @{#CHIEF.AddStrategicZone}() function.
--
-- If the zone is currently owned by another coalition and enemy ground troops are present in the zone, a CAS mission is lauchned.
-- If the zone is currently owned by another coalition and enemy ground troops are present in the zone, a CAS and an ARTY mission are lauchned, provided assets are available.
--
-- Once the zone is cleaned of enemy forces, ground (infantry) troops are send there. These require a transportation via helicopters.
-- So in order to deploy our own troops, infantry assets with `AUFTRAG.Type.ONGUARD` and helicopters with `AUFTRAG.Type.OPSTRANSPORT` need to be available.
@@ -1731,7 +1731,7 @@ function CHIEF:CheckOpsZoneQueue()
-- Has a patrol mission?
local hasMissionPatrol=stratzone.opszone:_FindMissions(self.coalition,AUFTRAG.Type.ONGUARD) or stratzone.opszone:_FindMissions(self.coalition,AUFTRAG.Type.ARMOREDGUARD)
-- Has a CAS mission?
local hasMissionCAS=stratzone.opszone:_FindMissions(self.coalition,AUFTRAG.Type.CAS)
local hasMissionCAS=stratzone.opszone:_FindMissions(self.coalition,AUFTRAG.Type.CASENHANCED)
-- Has a ARTY mission?
local hasMissionARTY=stratzone.opszone:_FindMissions(self.coalition,AUFTRAG.Type.ARTY)
@@ -1775,12 +1775,13 @@ function CHIEF:CheckOpsZoneQueue()
-- Recruite CAS assets.
local recruited=self:RecruitAssetsForZone(stratzone, AUFTRAG.Type.CAS, 1, 1)
local recruited=self:RecruitAssetsForZone(stratzone, AUFTRAG.Type.CASENHANCED, 1, 1)
-- Debug message.
self:T(self.lid..string.format("Zone is NOT empty ==> Recruit CAS assets=%s", tostring(recruited)))
end
if not hasMissionARTY then
-- Debug message.
@@ -1811,7 +1812,7 @@ function CHIEF:CheckOpsZoneQueue()
local hasMissionPATROL=stratzone.opszone:_FindMissions(self.coalition,AUFTRAG.Type.PATROLZONE)
-- Has a CAS mission?
local hasMissionCAS, CASMissions = stratzone.opszone:_FindMissions(self.coalition,AUFTRAG.Type.CAS)
local hasMissionCAS, CASMissions = stratzone.opszone:_FindMissions(self.coalition,AUFTRAG.Type.CASENHANCED)
local hasMissionARTY, ARTYMissions = stratzone.opszone:_FindMissions(self.coalition,AUFTRAG.Type.ARTY)
if ownercoalition==self.coalition and stratzone.opszone:IsEmpty() and hasMissionCAS then
@@ -2260,12 +2261,48 @@ function CHIEF:RecruitAssetsForZone(StratZone, MissionType, NassetsMin, NassetsM
-- Attach mission to ops zone.
StratZone.opszone:_AddMission(self.coalition, MissionType, mission)
-- Set ops zone to transport.
transport.opszone=StratZone.opszone
transport.chief=self
transport.commander=self.commander
return true
else
LEGION.UnRecruitAssets(assets)
return false
end
elseif MissionType==AUFTRAG.Type.CASENHANCED then
-- Create Patrol zone mission.
local caszone = StratZone.opszone.zone
local coord = caszone:GetCoordinate()
local height = UTILS.MetersToFeet(coord:GetLandHeight())+2500
local Speed = 200
if assets[1] then
if assets[1].speedmax then
Speed = UTILS.KmphToKnots(assets[1].speedmax * 0.7) or 200
end
end
--local mission=AUFTRAG:NewCAS(caszone,height,Speed,coord,math.random(0,359),Leg)
local mission=AUFTRAG:NewCASENHANCED(caszone, height, Speed)
-- Add assets to mission.
for _,asset in pairs(assets) do
mission:AddAsset(asset)
end
-- Assign mission to legions.
self:MissionAssign(mission, legions)
-- Attach mission to ops zone.
StratZone.opszone:_AddMission(self.coalition, MissionType, mission)
return true
elseif MissionType==AUFTRAG.Type.CAS then
-- Create Patrol zone mission.
+21 -19
View File
@@ -919,36 +919,38 @@ function COHORT:RecruitAssets(MissionType, Npayloads)
-- ARMY/NAVYGROUP combat ready?
---
-- Disable this for now as it can cause problems - at least with transport and cargo assets.
--self:I("Attribute is: "..asset.attribute)
if flightgroup:IsArmygroup() then
-- check for fighting assets
if asset.attribute == WAREHOUSE.Attribute.GROUND_ARTILLERY or
asset.attribute == WAREHOUSE.Attribute.GROUND_TANK or
asset.attribute == WAREHOUSE.Attribute.GROUND_INFANTRY or
asset.attribute == WAREHOUSE.Attribute.GROUND_AAA or
asset.attribute == WAREHOUSE.Attribute.GROUND_SAM
then
combatready=true
end
else
combatready=false
end
-- Not ready when rearming, retreating or returning!
if flightgroup:IsRearming() or flightgroup:IsRetreating() or flightgroup:IsReturning() then
combatready=false
end
end
-- Check transport/cargo for combat readyness!
-- Not ready when currently acting as ops transport carrier.
if flightgroup:IsLoading() or flightgroup:IsTransporting() or flightgroup:IsUnloading() or flightgroup:IsPickingup() or flightgroup:IsCarrier() then
combatready=false
end
end
-- Not ready when currently acting as ops transport cargo.
if flightgroup:IsCargo() or flightgroup:IsBoarding() or flightgroup:IsAwaitingLift() then
combatready=false
end
-- Disable this for now as it can cause problems - at least with transport and cargo assets.
--self:I("Attribute is: "..asset.attribute)
if flightgroup:IsArmygroup() then
-- check for fighting assets
if asset.attribute == WAREHOUSE.Attribute.GROUND_ARTILLERY or
asset.attribute == WAREHOUSE.Attribute.GROUND_TANK or
asset.attribute == WAREHOUSE.Attribute.GROUND_INFANTRY or
asset.attribute == WAREHOUSE.Attribute.GROUND_AAA or
asset.attribute == WAREHOUSE.Attribute.GROUND_SAM
then
combatready=true
end
else
combatready=false
end
-- This asset is "combatready".
if combatready then
self:T(self.lid.."Adding SPAWNED asset to ANOTHER mission as it is COMBATREADY")
+47 -8
View File
@@ -81,6 +81,10 @@ function LEGION:New(WarehouseName, LegionName)
-- Defaults:
-- TODO: What?
self:SetMarker(false)
-- Dead and crash events are handled via opsgroups.
self:UnHandleEvent(EVENTS.Crash)
self:UnHandleEvent(EVENTS.Dead)
-- Add FSM transitions.
-- From State --> Event --> To State
@@ -882,7 +886,18 @@ function LEGION:onafterTransportCancel(From, Event, To, Transport)
local cargos=Transport:GetCargoOpsGroups(false)
for _,_cargo in pairs(cargos) do
local cargo=_cargo --Ops.OpsGroup#OPSGROUP
-- Remover my lift.
cargo:_DelMyLift(Transport)
-- Legion of cargo group
local legion=cargo.legion
-- Add asset back to legion.
if legion then
legion:T(self.lid..string.format("Adding cargo group %s back to legion", cargo:GetName()))
legion:__AddAsset(0.1, cargo.group, 1)
end
end
-- Remove asset from mission.
@@ -993,7 +1008,7 @@ function LEGION:onafterNewAsset(From, Event, To, asset, assignment)
-- Debug text.
local text=string.format("New asset %s with assignment %s and request assignment %s", asset.spawngroupname, tostring(asset.assignment), tostring(assignment))
self:T3(self.lid..text)
self:T(self.lid..text)
-- Get cohort.
local cohort=self:_GetCohort(asset.assignment)
@@ -1061,6 +1076,8 @@ function LEGION:onafterNewAsset(From, Event, To, asset, assignment)
-- Asset is returned to the COHORT
---
self:T(self.lid..string.format("Asset returned to legion ==> calling LegionAssetReturned event"))
-- Trigger event.
self:LegionAssetReturned(cohort, asset)
@@ -1078,7 +1095,7 @@ end
-- @param Functional.Warehouse#WAREHOUSE.Assetitem Asset The asset that returned.
function LEGION:onafterLegionAssetReturned(From, Event, To, Cohort, Asset)
-- Debug message.
self:T(self.lid..string.format("Asset %s from Cohort %s returned! asset.assignment=\"%s\"", Asset.spawngroupname, Cohort.name, tostring(Asset.assignment)))
self:I(self.lid..string.format("Asset %s from Cohort %s returned! asset.assignment=\"%s\"", Asset.spawngroupname, Cohort.name, tostring(Asset.assignment)))
-- Stop flightgroup.
if Asset.flightgroup and not Asset.flightgroup:IsStopped() then
@@ -1246,7 +1263,7 @@ function LEGION:onafterAssetDead(From, Event, To, asset, request)
-- Remove group from the detection set of the CHIEF (INTEL).
if self.commander and self.commander.chief then
self.commander.chief.detectionset:RemoveGroupsByName({asset.spawngroupname})
end
end
-- Remove asset from mission is done via Mission:AssetDead() call from flightgroup onafterFlightDead function
-- Remove asset from squadron same
@@ -2396,12 +2413,34 @@ function LEGION.CalculateAssetMissionScore(asset, MissionType, TargetVec2, Inclu
-- Reduce score for legions that are futher away.
score=score-distance
-- Intercepts need to be carried out quickly. We prefer spawned assets.
--if MissionType==AUFTRAG.Type.INTERCEPT then
if asset.spawned then
score=score+25
-- Intercepts need to be carried out quickly. We prefer spawned assets.
if asset.spawned and asset.flightgroup and asset.flightgroup:IsAlive() then
local currmission=asset.flightgroup:GetMissionCurrent()
if currmission then
if currmission.type==AUFTRAG.Type.ALERT5 and currmission.alert5MissionType==MissionType then
-- Prefer assets that are on ALERT5 for this mission type.
score=score+25
elseif currmission==AUFTRAG.Type.GCICAP and MissionType==AUFTRAG.Type.INTERCEPT then
-- Prefer assets that are on GCICAP to perform INTERCEPTS
score=score+25
end
end
--end
if MissionType==AUFTRAG.Type.OPSTRANSPORT or MissionType==AUFTRAG.Type.AMMOSUPPLY or MissionType==AUFTRAG.Type.AWACS or MissionType==AUFTRAG.Type.FUELSUPPLY or MissionType==AUFTRAG.Type.TANKER then
-- TODO: need to check for missions that do not require ammo like transport, recon, awacs, tanker etc.
-- We better take a fresh asset. Sometimes spawned assets to something else, which is difficult to check.
score=score-10
else
-- Combat mission.
if asset.flightgroup:IsOutOfAmmo() then
-- Assets that are out of ammo are not considered.
score=score-1000
end
end
end
-- TRANSPORT specific.
if MissionType==AUFTRAG.Type.OPSTRANSPORT then
+49 -5
View File
@@ -3673,7 +3673,6 @@ function OPSGROUP:onafterTaskExecute(From, Event, To, Task)
-- BARRAGE is special!
if Task.dcstask.id==AUFTRAG.SpecialTask.BARRAGE then
env.info("FF Barrage")
local vec2=self:GetVec2()
local param=Task.dcstask.params
local heading=param.heading or math.random(1, 360)
@@ -4230,7 +4229,7 @@ function OPSGROUP:onafterMissionStart(From, Event, To, Mission)
-- IMMOBILE Group
---
env.info("FF Immobile GROUP")
--env.info("FF Immobile GROUP")
-- Add waypoint task. UpdateRoute is called inside.
local Clock=Mission.Tpush and UTILS.SecondsToClock(Mission.Tpush) or 5
@@ -5768,6 +5767,32 @@ function OPSGROUP:onafterElementInUtero(From, Event, To, Element)
end
--- On after "ElementDamaged" event.
-- @param #OPSGROUP self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
-- @param #OPSGROUP.Element Element The flight group element.
function OPSGROUP:onafterElementDamaged(From, Event, To, Element)
self:T(self.lid..string.format("Element damaged %s", Element.name))
if Element and Element.status~=OPSGROUP.ElementStatus.DEAD then
local lifepoints=Element.DCSunit:getLife()
local lifepoint0=Element.DCSunit:getLife0()
self:T(self.lid..string.format("Element life %s: %.2f/%.2f", Element.name, lifepoints, lifepoint0))
if lifepoints<=1.0 then
self:T(self.lid..string.format("Element %s life %.2f <= 1.0 ==> Destroyed!", Element.name, lifepoints))
self:ElementDestroyed(Element)
end
end
end
--- On after "ElementDestroyed" event.
-- @param #OPSGROUP self
-- @param #string From From state.
@@ -5802,10 +5827,18 @@ end
function OPSGROUP:onafterElementDead(From, Event, To, Element)
-- Debug info.
self:T(self.lid..string.format("Element dead %s at t=%.3f", Element.name, timer.getTime()))
self:I(self.lid..string.format("Element dead %s at t=%.3f", Element.name, timer.getTime()))
-- Set element status.
self:_UpdateStatus(Element, OPSGROUP.ElementStatus.DEAD)
if self.legion then
if not self:IsInUtero() then
local asset=self.legion:GetAssetByName(self.groupname)
local request=self.legion:GetRequestByID(asset.rid)
self.legion:_UnitDead(Element.unit, self.group, request)
end
end
-- Check if element was lasing and if so, switch to another unit alive to lase.
if self.spot.On and self.spot.element.name==Element.name then
@@ -6140,12 +6173,18 @@ function OPSGROUP:onafterDead(From, Event, To)
-- All elements were destroyed ==> Asset group is gone.
self.cohort:DelGroup(self.groupname)
end
if self.legion then
--self.legion:Get
--self.legion:AssetDead()
end
else
-- Not all assets were destroyed (despawn) ==> Add asset back to legion?
end
-- Stop in a sec.
--self:__Stop(-5)
-- Stop in 5 sec to give possible respawn attempts a chance.
if self.legion then
self:__Stop(-5)
end
end
--- On before "Stop" event.
@@ -6187,6 +6226,11 @@ function OPSGROUP:onafterStop(From, Event, To)
self:UnHandleEvent(EVENTS.Crash)
self.currbase=nil
end
for _,_mission in pairs(self.missionqueue) do
local mission=_mission --Ops.Auftrag#AUFTRAG
self:MissionCancel(mission)
end
-- Stop check timers.
self.timerCheckZone:Stop()
+29 -12
View File
@@ -57,6 +57,8 @@
-- @field #table statusLegion Transport status of all assigned LEGIONs.
-- @field #string statusCommander Staus of the COMMANDER.
-- @field Ops.Commander#COMMANDER commander Commander of the transport.
-- @field Ops.Chief#CHIEF chief Chief of the transport.
-- @field Ops.OpsZone#OPSZONE opszone OPS zone.
-- @field #table requestID The ID of the queued warehouse request. Necessary to cancel the request if the transport was cancelled before the request is processed.
--
-- @extends Core.Fsm#FSM
@@ -1305,7 +1307,7 @@ function OPSTRANSPORT:GetNcarrier()
return self.Ncarrier
end
--- Add asset to transport.
--- Add carrier asset to transport.
-- @param #OPSTRANSPORT self
-- @param Functional.Warehouse#WAREHOUSE.Assetitem Asset The asset to be added.
-- @param #OPSTRANSPORT.TransportZoneCombo TransportZoneCombo Transport zone combo.
@@ -1323,7 +1325,7 @@ function OPSTRANSPORT:AddAsset(Asset, TransportZoneCombo)
return self
end
--- Delete asset from mission.
--- Delete carrier asset from transport.
-- @param #OPSTRANSPORT self
-- @param Functional.Warehouse#WAREHOUSE.Assetitem Asset The asset to be removed.
-- @return #OPSTRANSPORT self
@@ -1736,12 +1738,12 @@ function OPSTRANSPORT:onafterDeadCarrierGroup(From, Event, To, OpsGroup)
-- Increase dead counter.
self.NcarrierDead=self.NcarrierDead+1
if #self.carriers==0 then
self:DeadCarrierAll()
end
-- Remove group from carrier list/table.
self:_DelCarrier(OpsGroup)
if #self.carriers==0 then
self:DeadCarrierAll()
end
end
--- On after "DeadCarrierAll" event.
@@ -1750,15 +1752,30 @@ end
-- @param #string Event Event.
-- @param #string To To state.
function OPSTRANSPORT:onafterDeadCarrierAll(From, Event, To)
self:I(self.lid..string.format("ALL Carrier OPSGROUPs are dead! Setting stage to PLANNED if not all cargo was delivered."))
self:I(self.lid..string.format("ALL Carrier OPSGROUPs are dead!"))
if self.opszone then
self:I(self.lid..string.format("Cancelling transport on CHIEF level"))
self.chief:TransportCancel(self)
--for _,_legion in pairs(self.legions) do
-- local legion=_legion --Ops.Legion#LEGION
-- legion:TransportCancel(self)
--end
else
-- Check if cargo was delivered.
self:_CheckDelivered()
-- Check if cargo was delivered.
self:_CheckDelivered()
-- Set state back to PLANNED if not delivered.
if not self:IsDelivered() then
self:Planned()
end
-- Set state back to PLANNED if not delivered.
if not self:IsDelivered() then
self:Planned()
end
end
--- On after "Cancel" event.