OPS AUFTRAG

- Added Alert 5 mission
- Added Fuel supply mission
- Added Ammo supply mission
This commit is contained in:
Frank 2021-09-08 11:49:27 +02:00
parent aecb92ccd3
commit b0c2e5409a
8 changed files with 456 additions and 172 deletions

View File

@ -43,8 +43,6 @@
--
-- ===
--
-- ![Banner Image](..\Presentations\OPS\AirWing\_Main.png)
--
-- # The AIRWING Concept
--
-- An AIRWING consists of multiple SQUADRONS. These squadrons "live" in a WAREHOUSE, i.e. a physical structure that is connected to an airbase (airdrome, FRAP or ship).

View File

@ -331,6 +331,10 @@ _AUFTRAGSNR=0
-- @field #string ARTY Fire at point.
-- @field #string PATROLZONE Patrol a zone.
-- @field #string OPSTRANSPORT Ops transport.
-- @field #string AMMOSUPPLY Ammo supply.
-- @field #string FUELSUPPLY Fuel supply.
-- @field #string ALERT5 Alert 5.
-- @field #string ONWATCH On watch.
AUFTRAG.Type={
ANTISHIP="Anti Ship",
AWACS="AWACS",
@ -356,6 +360,27 @@ AUFTRAG.Type={
ARTY="Fire At Point",
PATROLZONE="Patrol Zone",
OPSTRANSPORT="Ops Transport",
AMMOSUPPLY="Ammo Supply",
FUELSUPPLY="Fuel Supply",
ALERT5="Alert 5",
ONWATCH="On Watch",
}
--- Mission status of an assigned group.
-- @type AUFTRAG.GroupStatus
-- @field #string PATROLZONE Patrol zone task.
-- @field #string RECON Recon task
-- @field #string AMMOSUPPLY Ammo Supply.
-- @field #string FUELSUPPLY Fuel Supply.
-- @field #string ALERT5 Alert 5 task.
-- @field #string ONWATCH On Watch
AUFTRAG.SpecialTask={
PATROLZONE="PatrolZone",
RECON="ReconMission",
AMMOSUPPLY="Ammo Supply",
FUELSUPPLY="Fuel Supply",
ALERT5="Alert 5",
ONWATCH="On Watch",
}
--- Mission status.
@ -458,17 +483,17 @@ AUFTRAG.TargetType={
--- AUFTRAG class version.
-- @field #string version
AUFTRAG.version="0.7.1"
AUFTRAG.version="0.8.0"
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO list
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO: Replace engageRange by missionRange. Here and in other classes. CTRL+H is your friend!
-- TODO: Missions can be assigned to multiple legions.
-- TODO: Mission success options damaged, destroyed.
-- TODO: F10 marker to create new missions.
-- TODO: Add recovery tanker mission for boat ops.
-- DONE: Missions can be assigned to multiple legions.
-- DONE: Option to assign a specific payload for the mission (requires an AIRWING).
-- NOPE: Clone mission. How? Deepcopy? ==> Create a new auftrag.
-- DONE: Recon mission. What input? Set of coordinates?
@ -570,7 +595,7 @@ end
-- Create Missions
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- Create an ANTI-SHIP mission.
--- **[AIR]** Create an ANTI-SHIP mission.
-- @param #AUFTRAG self
-- @param Wrapper.Positionable#POSITIONABLE Target The target to attack. Can be passed as a @{Wrapper.Group#GROUP} or @{Wrapper.Unit#UNIT} object.
-- @param #number Altitude Engage altitude in feet. Default 2000 ft.
@ -598,7 +623,7 @@ function AUFTRAG:NewANTISHIP(Target, Altitude)
return mission
end
--- Create an ORBIT mission, which can be either a circular orbit or a race-track pattern.
--- **[AIR]** Create an ORBIT mission, which can be either a circular orbit or a race-track pattern.
-- @param #AUFTRAG self
-- @param Core.Point#COORDINATE Coordinate Where to orbit.
-- @param #number Altitude Orbit altitude in feet. Default is y component of `Coordinate`.
@ -640,7 +665,7 @@ function AUFTRAG:NewORBIT(Coordinate, Altitude, Speed, Heading, Leg)
return mission
end
--- Create an ORBIT mission, where the aircraft will go in a circle around the specified coordinate.
--- **[AIR]** Create an ORBIT mission, where the aircraft will go in a circle around the specified coordinate.
-- @param #AUFTRAG self
-- @param Core.Point#COORDINATE Coordinate Position where to orbit around.
-- @param #number Altitude Orbit altitude in feet. Default is y component of `Coordinate`.
@ -653,7 +678,7 @@ function AUFTRAG:NewORBIT_CIRCLE(Coordinate, Altitude, Speed)
return mission
end
--- Create an ORBIT mission, where the aircraft will fly a race-track pattern.
--- **[AIR]** Create an ORBIT mission, where the aircraft will fly a race-track pattern.
-- @param #AUFTRAG self
-- @param Core.Point#COORDINATE Coordinate Where to orbit.
-- @param #number Altitude Orbit altitude in feet. Default is y component of `Coordinate`.
@ -671,7 +696,7 @@ function AUFTRAG:NewORBIT_RACETRACK(Coordinate, Altitude, Speed, Heading, Leg)
return mission
end
--- Create a Ground Controlled CAP (GCICAP) mission. Flights with this task are considered for A2A INTERCEPT missions by the CHIEF class. They will perform a compat air patrol but not engage by
--- **[AIR]** Create a Ground Controlled CAP (GCICAP) mission. Flights with this task are considered for A2A INTERCEPT missions by the CHIEF class. They will perform a compat air patrol but not engage by
-- themselfs. They wait for the CHIEF to tell them whom to engage.
-- @param #AUFTRAG self
-- @param Core.Point#COORDINATE Coordinate Where to orbit.
@ -697,7 +722,7 @@ function AUFTRAG:NewGCICAP(Coordinate, Altitude, Speed, Heading, Leg)
return mission
end
--- Create a TANKER mission.
--- **[AIR]** Create a TANKER mission.
-- @param #AUFTRAG self
-- @param Core.Point#COORDINATE Coordinate Where to orbit.
-- @param #number Altitude Orbit altitude in feet. Default is y component of `Coordinate`.
@ -728,7 +753,7 @@ function AUFTRAG:NewTANKER(Coordinate, Altitude, Speed, Heading, Leg, RefuelSyst
return mission
end
--- Create a AWACS mission.
--- **[AIR]** Create a AWACS mission.
-- @param #AUFTRAG self
-- @param Core.Point#COORDINATE Coordinate Where to orbit. Altitude is also taken from the coordinate.
-- @param #number Altitude Orbit altitude in feet. Default is y component of `Coordinate`.
@ -758,7 +783,7 @@ end
--- Create an INTERCEPT mission.
--- **[AIR]** Create an INTERCEPT mission.
-- @param #AUFTRAG self
-- @param Wrapper.Positionable#POSITIONABLE Target The target to intercept. Can also be passed as simple @{Wrapper.Group#GROUP} or @{Wrapper.Unit#UNIT} object.
-- @return #AUFTRAG self
@ -779,7 +804,7 @@ function AUFTRAG:NewINTERCEPT(Target)
return mission
end
--- Create a CAP mission.
--- **[AIR]** Create a CAP mission.
-- @param #AUFTRAG self
-- @param Core.Zone#ZONE_RADIUS ZoneCAP Circular CAP zone. Detected targets in this zone will be engaged.
-- @param #number Altitude Altitude at which to orbit in feet. Default is 10,000 ft.
@ -819,7 +844,7 @@ function AUFTRAG:NewCAP(ZoneCAP, Altitude, Speed, Coordinate, Heading, Leg, Targ
return mission
end
--- Create a CAS mission.
--- **[AIR]** Create a CAS mission.
-- @param #AUFTRAG self
-- @param Core.Zone#ZONE_RADIUS ZoneCAS Circular CAS zone. Detected targets in this zone will be engaged.
-- @param #number Altitude Altitude at which to orbit. Default is 10,000 ft.
@ -859,7 +884,7 @@ function AUFTRAG:NewCAS(ZoneCAS, Altitude, Speed, Coordinate, Heading, Leg, Targ
return mission
end
--- Create a FACA mission.
--- **[AIR]** Create a FACA mission.
-- @param #AUFTRAG self
-- @param Wrapper.Group#GROUP Target Target group. Must be a GROUP object.
-- @param #string Designation Designation of target. See `AI.Task.Designation`. Default `AI.Task.Designation.AUTO`.
@ -894,7 +919,7 @@ function AUFTRAG:NewFACA(Target, Designation, DataLink, Frequency, Modulation)
end
--- Create a BAI mission.
--- **[AIR]** Create a BAI mission.
-- @param #AUFTRAG self
-- @param Wrapper.Positionable#POSITIONABLE Target The target to attack. Can be a GROUP, UNIT or STATIC object.
-- @param #number Altitude Engage altitude in feet. Default 2000 ft.
@ -922,7 +947,7 @@ function AUFTRAG:NewBAI(Target, Altitude)
return mission
end
--- Create a SEAD mission.
--- **[AIR]** Create a SEAD mission.
-- @param #AUFTRAG self
-- @param Wrapper.Positionable#POSITIONABLE Target The target to attack. Can be a GROUP or UNIT object.
-- @param #number Altitude Engage altitude in feet. Default 2000 ft.
@ -951,7 +976,7 @@ function AUFTRAG:NewSEAD(Target, Altitude)
return mission
end
--- Create a STRIKE mission. Flight will attack the closest map object to the specified coordinate.
--- **[AIR]** Create a STRIKE mission. Flight will attack the closest map object to the specified coordinate.
-- @param #AUFTRAG self
-- @param Core.Point#COORDINATE Target The target coordinate. Can also be given as a GROUP, UNIT, STATIC or TARGET object.
-- @param #number Altitude Engage altitude in feet. Default 2000 ft.
@ -979,7 +1004,7 @@ function AUFTRAG:NewSTRIKE(Target, Altitude)
return mission
end
--- Create a BOMBING mission. Flight will drop bombs a specified coordinate.
--- **[AIR]** Create a BOMBING mission. Flight will drop bombs a specified coordinate.
-- @param #AUFTRAG self
-- @param Core.Point#COORDINATE Target Target coordinate. Can also be specified as a GROUP, UNIT, STATIC or TARGET object.
-- @param #number Altitude Engage altitude in feet. Default 25000 ft.
@ -1011,7 +1036,7 @@ function AUFTRAG:NewBOMBING(Target, Altitude)
return mission
end
--- Create a BOMBRUNWAY mission.
--- **[AIR]** Create a BOMBRUNWAY mission.
-- @param #AUFTRAG self
-- @param Wrapper.Airbase#AIRBASE Airdrome The airbase to bomb. This must be an airdrome (not a FARP or ship) as these to not have a runway.
-- @param #number Altitude Engage altitude in feet. Default 25000 ft.
@ -1047,7 +1072,7 @@ function AUFTRAG:NewBOMBRUNWAY(Airdrome, Altitude)
return mission
end
--- Create a CARPET BOMBING mission.
--- **[AIR]** Create a CARPET BOMBING mission.
-- @param #AUFTRAG self
-- @param Core.Point#COORDINATE Target Target coordinate. Can also be specified as a GROUP, UNIT or STATIC object.
-- @param #number Altitude Engage altitude in feet. Default 25000 ft.
@ -1084,7 +1109,7 @@ function AUFTRAG:NewBOMBCARPET(Target, Altitude, CarpetLength)
end
--- Create an ESCORT (or FOLLOW) mission. Flight will escort another group and automatically engage certain target types.
--- **[AIR]** Create an ESCORT (or FOLLOW) mission. Flight will escort another group and automatically engage certain target types.
-- @param #AUFTRAG self
-- @param Wrapper.Group#GROUP EscortGroup The group to escort.
-- @param DCS#Vec3 OffsetVector A table with x, y and z components specifying the offset of the flight to the escorted group. Default {x=-100, y=0, z=200} for z=200 meters to the right, same alitude, x=100 meters behind.
@ -1114,7 +1139,7 @@ function AUFTRAG:NewESCORT(EscortGroup, OffsetVector, EngageMaxDistance, TargetT
return mission
end
--- Create a RESCUE HELO mission.
--- **[AIR ROTARY]** Create a RESCUE HELO mission.
-- @param #AUFTRAG self
-- @param Wrapper.Unit#UNIT Carrier The carrier unit.
-- @return #AUFTRAG self
@ -1136,7 +1161,7 @@ function AUFTRAG:NewRESCUEHELO(Carrier)
end
--- Create a TROOP TRANSPORT mission.
--- **[AIR ROTARY]** Create a TROOP TRANSPORT mission.
-- @param #AUFTRAG self
-- @param Core.Set#SET_GROUP TransportGroupSet The set group(s) to be transported.
-- @param Core.Point#COORDINATE DropoffCoordinate Coordinate where the helo will land drop off the the troops.
@ -1175,7 +1200,7 @@ function AUFTRAG:NewTROOPTRANSPORT(TransportGroupSet, DropoffCoordinate, PickupC
end
--- Create a OPS TRANSPORT mission.
--- **[AIR, GROUND, NAVAL]** Create a OPS TRANSPORT mission.
-- @param #AUFTRAG self
-- @param Core.Set#SET_GROUP CargoGroupSet The set group(s) to be transported.
-- @param Core.Zone#ZONE PickupZone Pick up zone
@ -1189,13 +1214,6 @@ function AUFTRAG:NewOPSTRANSPORT(CargoGroupSet, PickupZone, DeployZone)
mission:_TargetFromObject(mission.transportGroupSet)
--mission.transportPickup=PickupCoordinate or mission:GetTargetCoordinate()
--mission.transportDropoff=DropoffCoordinate
-- Debug.
--mission.transportPickup:MarkToAll("Pickup")
--mission.transportDropoff:MarkToAll("Drop off")
mission.opstransport=OPSTRANSPORT:New(CargoGroupSet, PickupZone, DeployZone)
function mission.opstransport:OnAfterExecuting(From, Event, To)
@ -1216,7 +1234,7 @@ function AUFTRAG:NewOPSTRANSPORT(CargoGroupSet, PickupZone, DeployZone)
end
--- Create an ARTY mission.
--- **[GROUND, NAVAL]** Create an ARTY mission.
-- @param #AUFTRAG self
-- @param Core.Point#COORDINATE Target Center of the firing solution.
-- @param #number Nshots Number of shots to be fired. Default 3.
@ -1246,7 +1264,7 @@ function AUFTRAG:NewARTY(Target, Nshots, Radius)
return mission
end
--- Create a PATROLZONE mission. Group(s) will go to the zone and patrol it randomly.
--- **[AIR, GROUND, NAVAL]** Create a PATROLZONE mission. Group(s) will go to the zone and patrol it randomly.
-- @param #AUFTRAG self
-- @param Core.Zone#ZONE Zone The patrol zone.
-- @param #number Speed Speed in knots.
@ -1276,7 +1294,7 @@ function AUFTRAG:NewPATROLZONE(Zone, Speed, Altitude)
return mission
end
--- Create a RECON mission.
--- **[AIR, GROUND, NAVAL]** Create a RECON mission.
-- @param #AUFTRAG self
-- @param Core.Set#SET_ZONE ZoneSet The recon zones.
-- @param #number Speed Speed in knots.
@ -1305,6 +1323,70 @@ function AUFTRAG:NewRECON(ZoneSet, Speed, Altitude, Adinfinitum, Randomly)
return mission
end
--- **[GROUND]** Create a AMMO SUPPLY mission.
-- @param #AUFTRAG self
-- @param Core.Zone#ZONE Zone The zone, where supply units go.
-- @return #AUFTRAG self
function AUFTRAG:NewAMMOSUPPLY(Zone)
local mission=AUFTRAG:New(AUFTRAG.Type.AMMOSUPPLY)
mission:_TargetFromObject(Zone)
mission.optionROE=ENUMS.ROE.WeaponHold
mission.optionAlarm=ENUMS.AlarmState.Auto
mission.missionFraction=0.9
mission.DCStask=mission:GetDCSMissionTask()
return mission
end
--- **[GROUND]** Create a FUEL SUPPLY mission.
-- @param #AUFTRAG self
-- @param Core.Zone#ZONE Zone The zone, where supply units go.
-- @return #AUFTRAG self
function AUFTRAG:NewFUELSUPPLY(Zone)
local mission=AUFTRAG:New(AUFTRAG.Type.FUELSUPPLY)
mission:_TargetFromObject(Zone)
mission.optionROE=ENUMS.ROE.WeaponHold
mission.optionAlarm=ENUMS.AlarmState.Auto
mission.missionFraction=0.9
mission.DCStask=mission:GetDCSMissionTask()
return mission
end
--- **[AIR]** Create an ALERT 5 mission.
-- @param #AUFTRAG self
-- @param #string MissionType Mission type `AUFTRAG.Type.XXX`.
-- @return #AUFTRAG self
function AUFTRAG:NewALERT5(MissionType)
local mission=AUFTRAG:New(AUFTRAG.Type.ALERT5)
--mission:_TargetFromObject(Coordinate)
mission.missionTask=self:GetMissionTaskforMissionType(MissionType)
mission.optionROE=ENUMS.ROE.WeaponHold
mission.optionROT=ENUMS.ROT.NoReaction
mission.alert5MissionType=MissionType
mission.missionFraction=0.0
mission.DCStask=mission:GetDCSMissionTask()
return mission
end
--- Create a mission to attack a group. Mission type is automatically chosen from the group category.
-- @param #AUFTRAG self
@ -3996,6 +4078,59 @@ function AUFTRAG:GetDCSMissionTask(TaskControllable)
DCStask.params=param
table.insert(DCStasks, DCStask)
elseif self.type==AUFTRAG.Type.AMMOSUPPLY then
-------------------------
-- AMMO SUPPLY Mission --
-------------------------
local DCStask={}
DCStask.id=AUFTRAG.SpecialTask.AMMOSUPPLY
-- We create a "fake" DCS task and pass the parameters to the OPSGROUP.
local param={}
param.zone=self:GetObjective()
DCStask.params=param
table.insert(DCStasks, DCStask)
elseif self.type==AUFTRAG.Type.FUELSUPPLY then
-------------------------
-- FUEL SUPPLY Mission --
-------------------------
local DCStask={}
DCStask.id=AUFTRAG.SpecialTask.FUELSUPPLY
-- We create a "fake" DCS task and pass the parameters to the OPSGROUP.
local param={}
param.zone=self:GetObjective()
DCStask.params=param
table.insert(DCStasks, DCStask)
elseif self.type==AUFTRAG.Type.ALERT5 then
---------------------
-- ALERT 5 Mission --
---------------------
local DCStask={}
DCStask.id=AUFTRAG.SpecialTask.ALERT5
-- We create a "fake" DCS task and pass the parameters to the OPSGROUP.
local param={}
DCStask.params=param
table.insert(DCStasks, DCStask)
else
self:E(self.lid..string.format("ERROR: Unknown mission task!"))
@ -4066,6 +4201,53 @@ function AUFTRAG:_GetDCSAttackTask(Target, DCStasks)
return DCStasks
end
--- Get DCS task table for an attack group or unit task.
-- @param #AUFTRAG self
-- @param #string MissionType Mission (AUFTAG) type.
-- @return #string DCS mission task for the auftrag type.
function AUFTRAG:GetMissionTaskforMissionType(MissionType)
local mtask=ENUMS.MissionTask.NOTHING
if MissionType==AUFTRAG.Type.ANTISHIP then
mtask=ENUMS.MissionTask.ANTISHIPSTRIKE
elseif MissionType==AUFTRAG.Type.AWACS then
mtask=ENUMS.MissionTask.AWACS
elseif MissionType==AUFTRAG.Type.BAI then
mtask=ENUMS.MissionTask.GROUNDATTACK
elseif MissionType==AUFTRAG.Type.BOMBCARPET then
mtask=ENUMS.MissionTask.GROUNDATTACK
elseif MissionType==AUFTRAG.Type.BOMBING then
mtask=ENUMS.MissionTask.GROUNDATTACK
elseif MissionType==AUFTRAG.Type.BOMBRUNWAY then
mtask=ENUMS.MissionTask.RUNWAYATTACK
elseif MissionType==AUFTRAG.Type.CAP then
mtask=ENUMS.MissionTask.CAP
elseif MissionType==AUFTRAG.Type.CAS then
mtask=ENUMS.MissionTask.CAS
elseif MissionType==AUFTRAG.Type.ESCORT then
mtask=ENUMS.MissionTask.ESCORT
elseif MissionType==AUFTRAG.Type.FACA then
mtask=ENUMS.MissionTask.AFAC
elseif MissionType==AUFTRAG.Type.FERRY then
mtask=ENUMS.MissionTask.NOTHING
elseif MissionType==AUFTRAG.Type.INTERCEPT then
mtask=ENUMS.MissionTask.INTERCEPT
elseif MissionType==AUFTRAG.Type.RECON then
mtask=ENUMS.MissionTask.RECONNAISSANCE
elseif MissionType==AUFTRAG.Type.SEAD then
mtask=ENUMS.MissionTask.SEAD
elseif MissionType==AUFTRAG.Type.STRIKE then
mtask=ENUMS.MissionTask.GROUNDATTACK
elseif MissionType==AUFTRAG.Type.TANKER then
mtask=ENUMS.MissionTask.REFUELING
elseif MissionType==AUFTRAG.Type.TROOPTRANSPORT then
mtask=ENUMS.MissionTask.TRANSPORT
end
return mtask
end
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

View File

@ -3,6 +3,8 @@
-- **Main Features:**
--
-- * Manage platoons
-- * Carry out ARTY and PATROLZONE missions (AUFTRAG)
-- * Define rearming zones
--
-- ===
--
@ -16,6 +18,8 @@
-- @type BRIGADE
-- @field #string ClassName Name of the class.
-- @field #number verbose Verbosity of output.
-- @field #table rearmingZones Rearming zones. Each element is of type `#BRIGADE.RearmingZone`.
-- @field Core.Set#SET_ZONE retreatZones Retreat zone set.
-- @extends Ops.Legion#LEGION
--- Be surprised!
@ -31,8 +35,14 @@
BRIGADE = {
ClassName = "BRIGADE",
verbose = 0,
rearmingZones = {},
}
--- Rearming Zone.
-- @type BRIGADE.RearmingZone
-- @field Core.Zone#ZONE zone The zone.
-- @field #boolean occupied If `true`, a rearming truck is present in the zone.
-- @field Wrapper.Marker#MARKER marker F10 marker.
--- BRIGADE class version.
-- @field #string version
@ -66,6 +76,9 @@ function BRIGADE:New(WarehouseName, BrigadeName)
-- Set some string id for output to DCS.log file.
self.lid=string.format("BRIGADE %s | ", self.alias)
-- Defaults
self:SetRetreatZones()
-- Add FSM transitions.
-- From State --> Event --> To State
@ -180,6 +193,49 @@ function BRIGADE:AddAssetToPlatoon(Platoon, Nassets)
return self
end
--- Define a set of retreat zones.
-- @param #BRIGADE self
-- @param Core.Set#SET_ZONE RetreatZoneSet Set of retreat zones.
-- @return #BRIGADE self
function BRIGADE:SetRetreatZones(RetreatZoneSet)
self.retreatZones=RetreatZoneSet or SET_ZONE:New()
return self
end
--- Add a retreat zone.
-- @param #BRIGADE self
-- @param Core.Zone#ZONE RetreatZone Retreat zone.
-- @return #BRIGADE self
function BRIGADE:AddRetreatZone(RetreatZone)
self.retreatZones:AddZone(RetreatZone)
return self
end
--- Get retreat zones.
-- @param #BRIGADE self
-- @return Core.Set#SET_ZONE Set of retreat zones.
function BRIGADE:GetRetreatZones()
return self.retreatZones
end
--- Add a patrol Point for CAP missions.
-- @param #BRIGADE self
-- @param Core.Zone#ZONE Rearming zone.
-- @return #AIRWING self
function BRIGADE:AddRearmingZone(RearmingZone)
local rearmingzone={} --#BRIGADE.RearmingZone
rearmingzone.zone=RearmingZone
rearmingzone.occupied=false
rearmingzone.marker=MARKER:New(rearmingzone.zone:GetCoordinate(), "Rearming Zone"):ToCoalition(self:GetCoalition())
table.insert(self.rearmingZones, rearmingzone)
return self
end
--- Get platoon by name.
-- @param #BRIGADE self
-- @param #string PlatoonName Name of the platoon.

View File

@ -818,6 +818,12 @@ function COHORT:RecruitAssets(Mission, Npayloads)
self:I(self.lid.."Adding asset on GCICAP mission for an INTERCEPT mission")
table.insert(assets, asset)
elseif self.legion:IsAssetOnMission(asset, AUFTRAG.Type.ALERT5) and self:CheckMissionCapability(Mission.Type, asset.payload.capabilities) then
-- Check if the payload of this asset is compatible with the mission.
self:I(self.lid.."Adding asset on ALERT 5 mission for XXX mission")
table.insert(assets, asset)
end
else

View File

@ -671,9 +671,13 @@ function COMMANDER:RecruitAssets(Mission)
-- First get payloads for aircraft types of squadrons.
for _,_cohort in pairs(legion.cohorts) do
local cohort=_cohort --Ops.Cohort#COHORT
if Npayloads[cohort.aircrafttype]==nil then
Npayloads[cohort.aircrafttype]=legion:IsAirwing() and legion:CountPayloadsInStock(Mission.type, cohort.aircrafttype, Mission.payloads) or 999
self:I(self.lid..string.format("Got Npayloads=%d for type=%s", Npayloads[cohort.aircrafttype], cohort.aircrafttype))
if Npayloads[cohort.aircrafttype]==nil then
local MissionType=Mission.type
if MissionType==AUFTRAG.Type.ALERT5 then
MissionType=Mission.alert5MissionType
end
Npayloads[cohort.aircrafttype]=legion:IsAirwing() and legion:CountPayloadsInStock(MissionType, cohort.aircrafttype, Mission.payloads) or 999
self:I(self.lid..string.format("Got N=%d payloads for mission type %s [%s]", Npayloads[cohort.aircrafttype], MissionType, cohort.aircrafttype))
end
end
@ -711,8 +715,16 @@ function COMMANDER:RecruitAssets(Mission)
-- Only assets that have no payload. Should be only spawned assets!
if not asset.payload then
-- Set mission type.
local MissionType=Mission.Type
-- Get a loadout for the actual mission this group is waiting for.
if Mission.type==AUFTRAG.Type.ALERT5 and Mission.alert5MissionType then
MissionType=Mission.alert5MissionType
end
-- Fetch payload for asset. This can be nil!
asset.payload=asset.legion:FetchPayloadFromStock(asset.unittype, Mission.type, Mission.payloads)
asset.payload=asset.legion:FetchPayloadFromStock(asset.unittype, MissionType, Mission.payloads)
end
@ -790,32 +802,6 @@ end
-- @param #boolean includePayload If true, include the payload in the calulation if the asset has one attached.
function COMMANDER:_OptimizeAssetSelection(assets, Mission, includePayload)
-- Get target position.
local TargetVec2=Mission:GetTargetVec2()
-- Calculate distance to mission target.
local distmin=math.huge
local distmax=0
for _,_asset in pairs(assets) do
local asset=_asset --Functional.Warehouse#WAREHOUSE.Assetitem
if asset.spawned then
local group=GROUP:FindByName(asset.spawngroupname)
asset.dist=UTILS.VecDist2D(group:GetVec2(), TargetVec2)
else
asset.dist=UTILS.VecDist2D(asset.legion:GetVec2(), TargetVec2)
end
if asset.dist<distmin then
distmin=asset.dist
end
if asset.dist>distmax then
distmax=asset.dist
end
end
-- Calculate the mission score of all assets.
for _,_asset in pairs(assets) do
local asset=_asset --Functional.Warehouse#WAREHOUSE.Assetitem
@ -826,10 +812,8 @@ function COMMANDER:_OptimizeAssetSelection(assets, Mission, includePayload)
local function optimize(a, b)
local assetA=a --Functional.Warehouse#WAREHOUSE.Assetitem
local assetB=b --Functional.Warehouse#WAREHOUSE.Assetitem
-- Higher score wins. If equal score ==> closer wins.
-- TODO: Need to include the distance in a smarter way!
return (assetA.score>assetB.score) or (assetA.score==assetB.score and assetA.dist<assetB.dist)
return (assetA.score>assetB.score)
end
table.sort(assets, optimize)
@ -837,7 +821,7 @@ function COMMANDER:_OptimizeAssetSelection(assets, Mission, includePayload)
local text=string.format("Optimized %d assets for %s mission (payload=%s):", #assets, Mission.type, tostring(includePayload))
for i,Asset in pairs(assets) do
local asset=Asset --Functional.Warehouse#WAREHOUSE.Assetitem
text=text..string.format("\n%s %s: score=%d, distance=%.1f km", asset.squadname, asset.spawngroupname, asset.score, asset.dist/1000)
text=text..string.format("\n%s %s: score=%d", asset.squadname, asset.spawngroupname, asset.score)
asset.dist=nil
asset.score=nil
end

View File

@ -2001,18 +2001,25 @@ function FLIGHTGROUP:onbeforeUpdateRoute(From, Event, To, n, N)
allowed=false
end
-- Check if group is uncontrolled. If so, the mission task cannot be set yet!
if allowed and self:IsUncontrolled() then
-- Not airborne yet. Try again in 5 sec.
self:T(self.lid.."Update route denied. Group is UNCONTROLLED ==> checking back in 5 sec")
trepeat=-5
self:T(self.lid.."Update route denied. Group is UNCONTROLLED!")
local mission=self:GetMissionCurrent()
if mission and mission.type==AUFTRAG.Type.ALERT5 then
trepeat=nil --Alert 5 is just waiting for the real mission. No need to try to update the route.
else
trepeat=-5
end
allowed=false
end
-- Requested waypoint index <1. Something is seriously wrong here!
if n and n<1 then
self:E(self.lid.."Update route denied because waypoint n<1!")
allowed=false
end
-- No current waypoint. Something is serously wrong!
if not self.currentwp then
self:E(self.lid.."Update route denied because self.currentwp=nil!")
allowed=false
@ -2025,9 +2032,10 @@ function FLIGHTGROUP:onbeforeUpdateRoute(From, Event, To, n, N)
allowed=false
end
-- Check for a current task.
if self.taskcurrent>0 then
--local task=self:GetTaskCurrent()
-- Get the current task. Must not be executing already.
local task=self:GetTaskByID(self.taskcurrent)
if task then
@ -2063,8 +2071,9 @@ function FLIGHTGROUP:onbeforeUpdateRoute(From, Event, To, n, N)
end
-- Debug info.
self:T2(self.lid..string.format("Onbefore Updateroute allowed=%s state=%s repeat in %s", tostring(allowed), self:GetState(), tostring(trepeat)))
self:T2(self.lid..string.format("Onbefore Updateroute in state %s: allowed=%s (repeat in %s)", self:GetState(), tostring(allowed), tostring(trepeat)))
-- Try again?
if trepeat then
self:__UpdateRoute(trepeat, n)
end

View File

@ -248,6 +248,11 @@ function LEGION:AddMission(Mission)
-- Add legion to mission.
Mission:AddLegion(self)
-- Set target for ALERT 5.
if Mission.type==AUFTRAG.Type.ALERT5 then
Mission:_TargetFromObject(self:GetCoordinate())
end
--[[
if Mission.opstransport then
Mission.opstransport:SetPickupZone(self.spawnzone)
@ -515,7 +520,8 @@ end
-- @param #boolean includePayload If true, include the payload in the calulation if the asset has one attached.
-- @return #number Mission score.
function LEGION:CalculateAssetMissionScore(asset, Mission, includePayload)
-- Mission score.
local score=0
-- Prefer highly skilled assets.
@ -530,39 +536,38 @@ function LEGION:CalculateAssetMissionScore(asset, Mission, includePayload)
end
-- Add mission performance to score.
local cohort=self:_GetCohortOfAsset(asset)
local missionperformance=cohort:GetMissionPeformance(Mission.type)
score=score+missionperformance
score=score+asset.cohort:GetMissionPeformance(Mission.Type)
-- Add payload performance to score.
if includePayload and asset.payload then
score=score+self:GetPayloadPeformance(asset.payload, Mission.type)
end
-- Target position.
local TargetVec2=Mission.type~=AUFTRAG.Type.ALERT5 and Mission:GetTargetVec2() or nil --Mission:GetTargetVec2()
-- Origin: We take the flightgroups position or the one of the legion.
local OrigVec2=asset.flightgroup and asset.flightgroup:GetVec2() or self:GetVec2()
-- Distance factor.
local distance=0
if TargetVec2 and OrigVec2 then
-- Distance in NM.
distance=UTILS.MetersToNM(UTILS.VecDist2D(OrigVec2, TargetVec2))
-- Round: 55 NM ==> 5.5 ==> 6, 63 NM ==> 6.3 ==> 6
distance=UTILS.Round(distance/10, 0)
end
-- Reduce score for legions that are futher away.
score=score-distance
-- Intercepts need to be carried out quickly. We prefer spawned assets.
if Mission.type==AUFTRAG.Type.INTERCEPT then
if Mission.type==AUFTRAG.Type.INTERCEPT then
if asset.spawned then
self:T(self.lid.."Adding 25 to asset because it is spawned")
score=score+25
end
end
-- Get coordinate of the target.
local coord=Mission:GetTargetCoordinate()
local dist=0
if coord then
-- Distance from legion to target.
local distance=UTILS.MetersToNM(coord:Get2DDistance(self:GetCoordinate()))
-- Round: 55 NM ==> 5.5 ==> 6, 63 NM ==> 6.3 ==> 6
dist=UTILS.Round(distance/10, 0)
end
-- Reduce score for legions that are futher away.
score=score-dist
-- TODO: This could be vastly improved. Need to gather ideas during testing.
-- Calculate ETA? Assets on orbit missions should arrive faster even if they are further away.
@ -580,33 +585,6 @@ end
-- @param #boolean includePayload If true, include the payload in the calulation if the asset has one attached.
function LEGION:_OptimizeAssetSelection(assets, Mission, includePayload)
local TargetVec2=Mission:GetTargetVec2()
local dStock=UTILS.VecDist2D(TargetVec2, self:GetVec2())
-- Calculate distance to mission target.
local distmin=math.huge
local distmax=0
for _,_asset in pairs(assets) do
local asset=_asset --Functional.Warehouse#WAREHOUSE.Assetitem
if asset.spawned then
local group=GROUP:FindByName(asset.spawngroupname)
asset.dist=UTILS.VecDist2D(group:GetVec2(), TargetVec2)
else
asset.dist=dStock
end
if asset.dist<distmin then
distmin=asset.dist
end
if asset.dist>distmax then
distmax=asset.dist
end
end
-- Calculate the mission score of all assets.
for _,_asset in pairs(assets) do
local asset=_asset --Functional.Warehouse#WAREHOUSE.Assetitem
@ -617,10 +595,8 @@ function LEGION:_OptimizeAssetSelection(assets, Mission, includePayload)
local function optimize(a, b)
local assetA=a --Functional.Warehouse#WAREHOUSE.Assetitem
local assetB=b --Functional.Warehouse#WAREHOUSE.Assetitem
-- Higher score wins. If equal score ==> closer wins.
-- TODO: Need to include the distance in a smarter way!
return (assetA.score>assetB.score) or (assetA.score==assetB.score and assetA.dist<assetB.dist)
return (assetA.score>assetB.score)
end
table.sort(assets, optimize)
@ -628,7 +604,7 @@ function LEGION:_OptimizeAssetSelection(assets, Mission, includePayload)
local text=string.format("Optimized %d assets for %s mission (payload=%s):", #assets, Mission.type, tostring(includePayload))
for i,Asset in pairs(assets) do
local asset=Asset --Functional.Warehouse#WAREHOUSE.Assetitem
text=text..string.format("\n%s %s: score=%d, distance=%.1f km", asset.squadname, asset.spawngroupname, asset.score, asset.dist/1000)
text=text..string.format("\n%s %s: score=%d", asset.squadname, asset.spawngroupname, asset.score)
asset.dist=nil
asset.score=nil
end
@ -679,15 +655,21 @@ function LEGION:onafterMissionRequest(From, Event, To, Mission)
-- Special Missions
---
local currM=asset.flightgroup:GetMissionCurrent()
-- Check if mission is INTERCEPT and asset is currently on GCI mission. If so, GCI is paused.
if Mission.type==AUFTRAG.Type.INTERCEPT then
local currM=asset.flightgroup:GetMissionCurrent()
if Mission.type==AUFTRAG.Type.INTERCEPT then
if currM and currM.type==AUFTRAG.Type.GCICAP then
self:I(self.lid..string.format("Pausing %s mission %s to send flight on intercept mission %s", currM.type, currM.name, Mission.name))
asset.flightgroup:PauseMission()
end
end
end
-- Cancel the current ALERT 5 mission.
if currM and currM.type==AUFTRAG.Type.ALERT5 then
asset.flightgroup:MissionCancel(currM)
end
-- Trigger event.
self:__OpsOnMission(5, asset.flightgroup, Mission)
@ -1680,9 +1662,13 @@ function LEGION:RecruitAssets(Mission)
-- First get payloads for aircraft types of squadrons.
for _,_cohort in pairs(self.cohorts) do
local cohort=_cohort --Ops.Cohort#COHORT
if Npayloads[cohort.aircrafttype]==nil then
Npayloads[cohort.aircrafttype]=self:IsAirwing() and self:CountPayloadsInStock(Mission.type, cohort.aircrafttype, Mission.payloads) or 999
self:I(self.lid..string.format("Got Npayloads=%d for type=%s",Npayloads[cohort.aircrafttype], cohort.aircrafttype))
if Npayloads[cohort.aircrafttype]==nil then
local MissionType=Mission.type
if MissionType==AUFTRAG.Type.ALERT5 then
MissionType=Mission.alert5MissionType
end
Npayloads[cohort.aircrafttype]=self:IsAirwing() and self:CountPayloadsInStock(MissionType, cohort.aircrafttype, Mission.payloads) or 999
self:I(self.lid..string.format("Got N=%d payloads for mission type=%s and unit type=%s", Npayloads[cohort.aircrafttype], MissionType, cohort.aircrafttype))
end
end
@ -1722,8 +1708,16 @@ function LEGION:RecruitAssets(Mission)
-- Only assets that have no payload. Should be only spawned assets!
if not asset.payload then
-- Set mission type.
local MissionType=Mission.Type
-- Get a loadout for the actual mission this group is waiting for.
if Mission.type==AUFTRAG.Type.ALERT5 and Mission.alert5MissionType then
MissionType=Mission.alert5MissionType
end
-- Fetch payload for asset. This can be nil!
asset.payload=self:FetchPayloadFromStock(asset.unittype, Mission.type, Mission.payloads)
asset.payload=self:FetchPayloadFromStock(asset.unittype, MissionType, Mission.payloads)
end

View File

@ -3373,6 +3373,29 @@ function OPSGROUP:onafterTaskExecute(From, Event, To, Task)
-- Set mission UID.
wp.missionUID=Mission and Mission.auftragsnummer or nil
elseif Task.dcstask.id==AUFTRAG.SpecialTask.AMMOSUPPLY or Task.dcstask.id==AUFTRAG.SpecialTask.FUELSUPPLY then
---
-- Task "Ammo Supply" or "Fuel Supply" mission.
---
-- Parameters.
local zone=Task.dcstask.params.zone --Core.Zone#ZONE
-- Random coordinate in zone.
local Coordinate=zone:GetRandomCoordinate()
-- Speed and altitude.
local Speed=UTILS.KmphToKnots(Task.dcstask.params.speed or self.speedCruise)
elseif Task.dcstask.id==AUFTRAG.SpecialTask.ALERT5 then
---
-- Task Alert 5 mission.
---
-- Just stay put on the airfield and wait until something happens.
else
-- If task is scheduled (not waypoint) set task.
@ -3463,7 +3486,13 @@ function OPSGROUP:onafterTaskCancel(From, Event, To, Task)
elseif Task.dcstask.id=="PatrolZone" then
done=true
elseif Task.dcstask.id=="ReconMission" then
done=true
done=true
elseif Task.dcstask.id==AUFTRAG.SpecialTask.AMMOSUPPLY then
done=true
elseif Task.dcstask.id==AUFTRAG.SpecialTask.FUELSUPPLY then
done=true
elseif Task.dcstask.id==AUFTRAG.SpecialTask.ALERT5 then
done=true
elseif stopflag==1 or (not self:IsAlive()) or self:IsDead() or self:IsStopped() then
-- Manual call TaskDone if setting flag to one was not successful.
done=true
@ -3829,8 +3858,8 @@ function OPSGROUP:onbeforeMissionStart(From, Event, To, Mission)
end
-- Startup group if it is uncontrolled.
if self:IsFlightgroup() and self:IsUncontrolled() then
-- Startup group if it is uncontrolled. Alert 5 aircraft will not be started though!
if self:IsFlightgroup() and self:IsUncontrolled() and Mission.type~=AUFTRAG.Type.ALERT5 then
self:StartUncontrolled(delay)
end
@ -3950,6 +3979,12 @@ function OPSGROUP:onafterMissionCancel(From, Event, To, Mission)
-- Current Mission
---
-- Alert 5 missoins dont have a task set, which could be cancelled.
if Mission.type==AUFTRAG.Type.ALERT5 then
self:MissionDone(Mission)
return
end
-- Get mission waypoint task.
local Task=Mission:GetGroupWaypointTask(self)
@ -4103,14 +4138,22 @@ function OPSGROUP:RouteToMission(mission, delay)
-- Debug info.
self:T(self.lid..string.format("Route To Mission"))
-- Catch dead or stopped groups.
if self:IsDead() or self:IsStopped() then
return
end
-- OPSTRANSPORT: Just add the ops transport to the queue.
if mission.type==AUFTRAG.Type.OPSTRANSPORT then
self:AddOpsTransport(mission.opstransport)
return
end
-- ALERT 5: Just set the mission to executing.
if mission.type==AUFTRAG.Type.ALERT5 then
self:MissionExecute(mission)
return
end
-- ID of current waypoint.
local uid=self:GetWaypointCurrent().uid
@ -4134,6 +4177,10 @@ function OPSGROUP:RouteToMission(mission, delay)
-- Special for Troop transport.
if mission.type==AUFTRAG.Type.TROOPTRANSPORT then
---
-- TROOP TRANSPORT
---
-- Refresh DCS task with the known controllable.
mission.DCStask=mission:GetDCSMissionTask(self.group)
@ -4221,39 +4268,7 @@ function OPSGROUP:RouteToMission(mission, delay)
---
-- Mission Specific Settings
---
-- ROE
if mission.optionROE then
self:SwitchROE(mission.optionROE)
end
-- ROT
if mission.optionROT then
self:SwitchROT(mission.optionROT)
end
-- Alarm state
if mission.optionAlarm then
self:SwitchAlarmstate(mission.optionAlarm)
end
-- EPLRS
if mission.optionEPLRS then
self:SwitchEPLRS(mission.optionEPLRS)
end
-- Formation
if mission.optionFormation and self:IsFlightgroup() then
self:SwitchFormation(mission.optionFormation)
end
-- Radio frequency and modulation.
if mission.radio then
self:SwitchRadio(mission.radio.Freq, mission.radio.Modu)
end
-- TACAN settings.
if mission.tacan then
self:SwitchTACAN(mission.tacan.Channel, mission.tacan.Morse, mission.tacan.BeaconName, mission.tacan.Band)
end
-- ICLS settings.
if mission.icls then
self:SwitchICLS(mission.icls.Channel, mission.icls.Morse, mission.icls.UnitName)
end
self:_SetMissionOptions(mission)
if self:IsArmygroup() then
self:Cruise(mission.missionSpeed and UTILS.KmphToKnots(mission.missionSpeed) or self:GetSpeedCruise())
@ -4266,6 +4281,46 @@ function OPSGROUP:RouteToMission(mission, delay)
end
end
--- Set mission specific options for ROE, Alarm state, etc.
-- @param #OPSGROUP self
-- @param Ops.Auftrag#AUFTRAG mission The mission table.
function OPSGROUP:_SetMissionOptions(mission)
-- ROE
if mission.optionROE then
self:SwitchROE(mission.optionROE)
end
-- ROT
if mission.optionROT then
self:SwitchROT(mission.optionROT)
end
-- Alarm state
if mission.optionAlarm then
self:SwitchAlarmstate(mission.optionAlarm)
end
-- EPLRS
if mission.optionEPLRS then
self:SwitchEPLRS(mission.optionEPLRS)
end
-- Formation
if mission.optionFormation and self:IsFlightgroup() then
self:SwitchFormation(mission.optionFormation)
end
-- Radio frequency and modulation.
if mission.radio then
self:SwitchRadio(mission.radio.Freq, mission.radio.Modu)
end
-- TACAN settings.
if mission.tacan then
self:SwitchTACAN(mission.tacan.Channel, mission.tacan.Morse, mission.tacan.BeaconName, mission.tacan.Band)
end
-- ICLS settings.
if mission.icls then
self:SwitchICLS(mission.icls.Channel, mission.icls.Morse, mission.icls.UnitName)
end
end
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Queue Update: Missions & Tasks
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------