- 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

View File

@ -5452,6 +5452,55 @@ function WAREHOUSE:onafterAssetDead(From, Event, To, asset, request)
local text=string.format("Asset %s from request id=%d is dead!", asset.templatename, request.uid)
self:T(self.lid..text)
self:_DebugMessage(text)
-- Here I need to get rid of the #CARGO at the end to obtain the original name again!
local groupname=asset.spawngroupname --self:_GetNameWithOut(group)
-- Dont trigger a Remove event for the group sets.
local NoTriggerEvent=true
if request.transporttype==WAREHOUSE.TransportType.SELFPROPELLED then
---
-- Easy case: Group can simply be removed from the cargogroupset.
---
-- Remove dead group from cargo group set.
request.cargogroupset:Remove(groupname, NoTriggerEvent)
self:T(self.lid..string.format("Removed selfpropelled cargo %s: ncargo=%d.", groupname, request.cargogroupset:Count()))
else
---
-- Complicated case: Dead unit could be:
-- 1.) A Cargo unit (e.g. waiting to be picked up).
-- 2.) A Transport unit which itself holds cargo groups.
---
-- Check if this a cargo or transport group.
local istransport=not asset.iscargo --self:_GroupIsTransport(group, request)
if istransport==true then
-- Whole carrier group is dead. Remove it from the carrier group set.
request.transportgroupset:Remove(groupname, NoTriggerEvent)
self:T(self.lid..string.format("Removed transport %s: ntransport=%d", groupname, request.transportgroupset:Count()))
elseif istransport==false then
-- This must have been an alive cargo group that was killed outside the carrier, e.g. waiting to be transported or waiting to be put back.
-- Remove dead group from cargo group set.
request.cargogroupset:Remove(groupname, NoTriggerEvent)
self:T(self.lid..string.format("Removed transported cargo %s outside carrier: ncargo=%d", groupname, request.cargogroupset:Count()))
-- This as well?
--request.transportcargoset:RemoveCargosByName(RemoveCargoNames)
else
--self:E(self.lid..string.format("ERROR: Group %s is neither cargo nor transport!", group:GetName()))
end
end
end
@ -6556,7 +6605,8 @@ function WAREHOUSE:_OnEventCrashOrDead(EventData)
end
end
--self:I(self.lid..string.format("Warehouse %s captured event dead or crash or unit %s.", self.alias, tostring(EventData.IniUnitName)))
-- Debug info.
self:T2(self.lid..string.format("Warehouse %s captured event dead or crash or unit %s", self.alias, tostring(EventData.IniUnitName)))
-- Check if an asset unit was destroyed.
if EventData.IniGroup then
@ -6571,7 +6621,7 @@ function WAREHOUSE:_OnEventCrashOrDead(EventData)
if wid==self.uid then
-- Debug message.
self:T(self.lid..string.format("Warehouse %s captured event dead or crash of its asset unit %s.", self.alias, EventData.IniUnitName))
self:T(self.lid..string.format("Warehouse %s captured event dead or crash of its asset unit %s", self.alias, EventData.IniUnitName))
-- Loop over all pending requests and get the one belonging to this unit.
for _,request in pairs(self.pending) do
@ -6581,7 +6631,7 @@ function WAREHOUSE:_OnEventCrashOrDead(EventData)
if request.uid==rid then
-- Update cargo and transport group sets of this request. We need to know if this job is finished.
self:_UnitDead(EventData.IniUnit, request)
self:_UnitDead(EventData.IniUnit, EventData.IniGroup, request)
end
end
@ -6594,38 +6644,51 @@ end
-- This is important in order to determine if a job is done and can be removed from the (pending) queue.
-- @param #WAREHOUSE self
-- @param Wrapper.Unit#UNIT deadunit Unit that died.
-- @param Wrapper.Group#GROUP deadgroup Group of unit that died.
-- @param #WAREHOUSE.Pendingitem request Request that needs to be updated.
function WAREHOUSE:_UnitDead(deadunit, request)
function WAREHOUSE:_UnitDead(deadunit, deadgroup, request)
--env.info("FF unit dead "..deadunit:GetName())
-- Flare unit.
if self.Debug then
deadunit:FlareRed()
-- Find asset.
local asset=self:FindAssetInDB(deadgroup)
-- Find opsgroup.
local opsgroup=_DATABASE:FindOpsGroup(deadgroup)
local groupdead=false
if opsgroup then
if opsgroup:IsDead() then
groupdead=true
end
-- Group the dead unit belongs to.
local group=deadunit:GetGroup()
else
-- Number of alive units in group.
local nalive=group:CountAliveUnits()
local nalive=deadgroup:CountAliveUnits()
-- Whole group is dead?
local groupdead=true
if nalive>0 then
groupdead=false
else
groupdead=true
end
end
-- Here I need to get rid of the #CARGO at the end to obtain the original name again!
local unitname=self:_GetNameWithOut(deadunit)
local groupname=self:_GetNameWithOut(group)
local groupname=self:_GetNameWithOut(deadgroup)
-- Group is dead!
if groupdead then
self:T(self.lid..string.format("Group %s (transport=%s) is dead!", groupname, tostring(self:_GroupIsTransport(group,request))))
-- Debug output.
self:T(self.lid..string.format("Group %s (transport=%s) is dead!", groupname, tostring(self:_GroupIsTransport(deadgroup,request))))
if self.Debug then
group:SmokeWhite()
deadgroup:SmokeWhite()
end
-- Trigger AssetDead event.
local asset=self:FindAssetInDB(group)
self:AssetDead(asset, request)
end
@ -6633,19 +6696,7 @@ function WAREHOUSE:_UnitDead(deadunit, request)
-- Dont trigger a Remove event for the group sets.
local NoTriggerEvent=true
if request.transporttype==WAREHOUSE.TransportType.SELFPROPELLED then
---
-- Easy case: Group can simply be removed from the cargogroupset.
---
-- Remove dead group from cargo group set.
if groupdead==true then
request.cargogroupset:Remove(groupname, NoTriggerEvent)
self:T(self.lid..string.format("Removed selfpropelled cargo %s: ncargo=%d.", groupname, request.cargogroupset:Count()))
end
else
if not request.transporttype==WAREHOUSE.TransportType.SELFPROPELLED then
---
-- Complicated case: Dead unit could be:
@ -6653,10 +6704,7 @@ function WAREHOUSE:_UnitDead(deadunit, request)
-- 2.) A Transport unit which itself holds cargo groups.
---
-- Check if this a cargo or transport group.
local istransport=self:_GroupIsTransport(group,request)
if istransport==true then
if not asset.iscargo then
-- Get the carrier unit table holding the cargo groups inside this carrier.
local cargogroupnames=request.carriercargo[unitname]
@ -6671,25 +6719,8 @@ function WAREHOUSE:_UnitDead(deadunit, request)
end
-- Whole carrier group is dead. Remove it from the carrier group set.
if groupdead then
request.transportgroupset:Remove(groupname, NoTriggerEvent)
self:T(self.lid..string.format("Removed transport %s: ntransport=%d", groupname, request.transportgroupset:Count()))
end
elseif istransport==false then
-- This must have been an alive cargo group that was killed outside the carrier, e.g. waiting to be transported or waiting to be put back.
-- Remove dead group from cargo group set.
if groupdead==true then
request.cargogroupset:Remove(groupname, NoTriggerEvent)
self:T(self.lid..string.format("Removed transported cargo %s outside carrier: ncargo=%d", groupname, request.cargogroupset:Count()))
-- This as well?
--request.transportcargoset:RemoveCargosByName(RemoveCargoNames)
end
else
self:E(self.lid..string.format("ERROR: Group %s is neither cargo nor transport!", group:GetName()))
self:E(self.lid..string.format("ERROR: Group %s is neither cargo nor transport!", deadgroup:GetName()))
end
end
@ -8056,6 +8087,28 @@ end
-- @return #number Request ID.
function WAREHOUSE:_GetIDsFromGroup(group)
if group then
-- Group name
local groupname=group:GetName()
local wid, aid, rid=self:_GetIDsFromGroupName(groupname)
return wid,aid,rid
else
self:E("WARNING: Group not found in GetIDsFromGroup() function!")
end
end
--- Get warehouse id, asset id and request id from group name (alias).
-- @param #WAREHOUSE self
-- @param #string groupname Name of the group from which the info is gathered.
-- @return #number Warehouse ID.
-- @return #number Asset ID.
-- @return #number Request ID.
function WAREHOUSE:_GetIDsFromGroupName(groupname)
---@param #string text The text to analyse.
local function analyse(text)
@ -8085,13 +8138,9 @@ function WAREHOUSE:_GetIDsFromGroup(group)
return _wid,_aid,_rid
end
if group then
-- Group name
local name=group:GetName()
-- Get asset id from group name.
local wid,aid,rid=analyse(name)
local wid,aid,rid=analyse(groupname)
-- Get Asset.
local asset=self:GetAssetByID(aid)
@ -8103,75 +8152,12 @@ function WAREHOUSE:_GetIDsFromGroup(group)
end
-- Debug info
self:T3(self.lid..string.format("Group Name = %s", tostring(name)))
self:T3(self.lid..string.format("Group Name = %s", tostring(groupname)))
self:T3(self.lid..string.format("Warehouse ID = %s", tostring(wid)))
self:T3(self.lid..string.format("Asset ID = %s", tostring(aid)))
self:T3(self.lid..string.format("Request ID = %s", tostring(rid)))
return wid,aid,rid
else
self:E("WARNING: Group not found in GetIDsFromGroup() function!")
end
end
--- Get warehouse id, asset id and request id from group name (alias).
-- @param #WAREHOUSE self
-- @param Wrapper.Group#GROUP group The group from which the info is gathered.
-- @return #number Warehouse ID.
-- @return #number Asset ID.
-- @return #number Request ID.
function WAREHOUSE:_GetIDsFromGroupOLD(group)
---@param #string text The text to analyse.
local function analyse(text)
-- Get rid of #0001 tail from spawn.
local unspawned=UTILS.Split(text, "#")[1]
-- Split keywords.
local keywords=UTILS.Split(unspawned, "_")
local _wid=nil -- warehouse UID
local _aid=nil -- asset UID
local _rid=nil -- request UID
-- Loop over keys.
for _,keys in pairs(keywords) do
local str=UTILS.Split(keys, "-")
local key=str[1]
local val=str[2]
if key:find("WID") then
_wid=tonumber(val)
elseif key:find("AID") then
_aid=tonumber(val)
elseif key:find("RID") then
_rid=tonumber(val)
end
end
return _wid,_aid,_rid
end
if group then
-- Group name
local name=group:GetName()
-- Get ids
local wid,aid,rid=analyse(name)
-- Debug info
self:T3(self.lid..string.format("Group Name = %s", tostring(name)))
self:T3(self.lid..string.format("Warehouse ID = %s", tostring(wid)))
self:T3(self.lid..string.format("Asset ID = %s", tostring(aid)))
self:T3(self.lid..string.format("Request ID = %s", tostring(rid)))
return wid,aid,rid
else
self:E("WARNING: Group not found in GetIDsFromGroup() function!")
end
end
--- Filter stock assets by descriptor and attribute.

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.
@ -4943,6 +4985,26 @@ function AUFTRAG:GetDCSMissionTask(TaskControllable)
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

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.

View File

@ -919,20 +919,6 @@ function COHORT:RecruitAssets(MissionType, Npayloads)
-- ARMY/NAVYGROUP combat ready?
---
if flightgroup:IsRearming() or flightgroup:IsRetreating() or flightgroup:IsReturning() then
combatready=false
end
end
-- Check transport/cargo for combat readyness!
if flightgroup:IsLoading() or flightgroup:IsTransporting() or flightgroup:IsUnloading() or flightgroup:IsPickingup() or flightgroup:IsCarrier() then
combatready=false
end
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
@ -949,6 +935,22 @@ function COHORT:RecruitAssets(MissionType, Npayloads)
combatready=false
end
-- Not ready when rearming, retreating or returning!
if flightgroup:IsRearming() or flightgroup:IsRetreating() or flightgroup:IsReturning() then
combatready=false
end
end
-- 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
-- Not ready when currently acting as ops transport cargo.
if flightgroup:IsCargo() or flightgroup:IsBoarding() or flightgroup:IsAwaitingLift() then
combatready=false
end
-- This asset is "combatready".
if combatready then
self:T(self.lid.."Adding SPAWNED asset to ANOTHER mission as it is COMBATREADY")

View File

@ -82,6 +82,10 @@ function LEGION:New(WarehouseName, LegionName)
-- 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
self:AddTransition("*", "MissionRequest", "*") -- Add a (mission) request to the warehouse.
@ -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
@ -2397,11 +2414,33 @@ function LEGION.CalculateAssetMissionScore(asset, MissionType, TargetVec2, Inclu
score=score-distance
-- Intercepts need to be carried out quickly. We prefer spawned assets.
--if MissionType==AUFTRAG.Type.INTERCEPT then
if asset.spawned then
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

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,11 +5827,19 @@ 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.
@ -6188,6 +6227,11 @@ function OPSGROUP:onafterStop(From, Event, To)
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()
self.timerQueueUpdate:Stop()

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
-- Remove group from carrier list/table.
self:_DelCarrier(OpsGroup)
if #self.carriers==0 then
self:DeadCarrierAll()
end
-- Remove group from carrier list/table.
self:_DelCarrier(OpsGroup)
end
--- On after "DeadCarrierAll" event.
@ -1750,7 +1752,19 @@ 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()
@ -1759,6 +1773,9 @@ function OPSTRANSPORT:onafterDeadCarrierAll(From, Event, To)
if not self:IsDelivered() then
self:Planned()
end
end
end
--- On after "Cancel" event.