This commit is contained in:
Frank 2020-08-14 18:09:13 +02:00
parent 200c1dac85
commit 32c9a59ff0
7 changed files with 143 additions and 37 deletions

View File

@ -550,7 +550,7 @@ end
-- @return #number Distance between the two nodes. -- @return #number Distance between the two nodes.
function ASTAR.DistRoad(nodeA, nodeB) function ASTAR.DistRoad(nodeA, nodeB)
local path, dist, gotpath=nodeA.coordinate:GetPathOnRoad(nodeB.coordinate,IncludeEndpoints,Railroad,MarkPath,SmokePath) local path, dist, gotpath=nodeA.coordinate:GetPathOnRoad(nodeB.coordinate, IncludeEndpoints, Railroad, MarkPath, SmokePath)
if gotpath then if gotpath then
return dist return dist

View File

@ -116,6 +116,7 @@ AIRWING = {
squadrons = {}, squadrons = {},
missionqueue = {}, missionqueue = {},
payloads = {}, payloads = {},
payloadcounter = 0,
pointsCAP = {}, pointsCAP = {},
pointsTANKER = {}, pointsTANKER = {},
pointsAWACS = {}, pointsAWACS = {},
@ -132,6 +133,7 @@ AIRWING = {
--- Payload data. --- Payload data.
-- @type AIRWING.Payload -- @type AIRWING.Payload
-- @field #number uid Unique payload ID.
-- @field #string unitname Name of the unit this pylon was extracted from. -- @field #string unitname Name of the unit this pylon was extracted from.
-- @field #string aircrafttype Type of aircraft, which can use this payload. -- @field #string aircrafttype Type of aircraft, which can use this payload.
-- @field #table capabilities Mission types and performances for which this payload can be used. -- @field #table capabilities Mission types and performances for which this payload can be used.
@ -309,7 +311,8 @@ function AIRWING:NewPayload(Unit, Npayloads, MissionTypes, Performance)
end end
-- Create payload. -- Create payload.
local payload={} --#AIRWING.Payload local payload={} --#AIRWING.Payload
payload.uid=self.payloadcounter
payload.unitname=Unit:GetName() payload.unitname=Unit:GetName()
payload.aircrafttype=Unit:GetTypeName() payload.aircrafttype=Unit:GetTypeName()
payload.pylons=Unit:GetTemplatePayload() payload.pylons=Unit:GetTemplatePayload()
@ -343,6 +346,9 @@ function AIRWING:NewPayload(Unit, Npayloads, MissionTypes, Performance)
-- Add payload -- Add payload
table.insert(self.payloads, payload) table.insert(self.payloads, payload)
-- Increase counter
self.payloadcounter=self.payloadcounter+1
return payload return payload
end end
@ -385,8 +391,9 @@ end
-- @param #AIRWING self -- @param #AIRWING self
-- @param #string UnitType The type of the unit. -- @param #string UnitType The type of the unit.
-- @param #string MissionType The mission type. -- @param #string MissionType The mission type.
-- @param #table Payloads Specific payloads only to be considered.
-- @return #AIRWING.Payload Payload table or *nil*. -- @return #AIRWING.Payload Payload table or *nil*.
function AIRWING:FetchPayloadFromStock(UnitType, MissionType) function AIRWING:FetchPayloadFromStock(UnitType, MissionType, Payloads)
-- Quick check if we have any payloads. -- Quick check if we have any payloads.
if not self.payloads or #self.payloads==0 then if not self.payloads or #self.payloads==0 then
@ -427,11 +434,25 @@ function AIRWING:FetchPayloadFromStock(UnitType, MissionType)
end end
end end
local function _checkPayloads(payload)
if Payloads then
for _,Payload in pairs(Payloads) do
if Payload.uid==payload.id then
return true
end
end
else
-- Payload was not specified.
return true
end
return false
end
-- Pre-selection: filter out only those payloads that are valid for the airframe and mission type and are available. -- Pre-selection: filter out only those payloads that are valid for the airframe and mission type and are available.
local payloads={} local payloads={}
for _,_payload in pairs(self.payloads) do for _,_payload in pairs(self.payloads) do
local payload=_payload --#AIRWING.Payload local payload=_payload --#AIRWING.Payload
if payload.aircrafttype==UnitType and self:CheckMissionCapability(MissionType, payload.capabilities) and payload.navail>0 then if payload.aircrafttype==UnitType and self:CheckMissionCapability(MissionType, payload.capabilities) and payload.navail>0 and _checkPayloads(payload) then
table.insert(payloads, payload) table.insert(payloads, payload)
end end
end end
@ -1119,6 +1140,15 @@ function AIRWING:_GetNextMission()
end end
table.sort(self.missionqueue, _sort) table.sort(self.missionqueue, _sort)
-- Look for first mission that is SCHEDULED.
local importance=math.huge
for _,_mission in pairs(self.missionqueue) do
local mission=_mission --Ops.Auftrag#AUFTRAG
if mission.importance<importance then
importance=mission.importance
end
end
-- Current time. -- Current time.
local time=timer.getAbsTime() local time=timer.getAbsTime()
@ -1127,7 +1157,7 @@ function AIRWING:_GetNextMission()
local mission=_mission --Ops.Auftrag#AUFTRAG local mission=_mission --Ops.Auftrag#AUFTRAG
-- Firstly, check if mission is due? -- Firstly, check if mission is due?
if mission:IsQueued() and mission:IsReadyToGo() then if mission:IsQueued() and mission:IsReadyToGo() and mission.importance<=importance then
-- Check if airwing can do the mission and gather required assets. -- Check if airwing can do the mission and gather required assets.
local can, assets=self:CanMission(mission) local can, assets=self:CanMission(mission)
@ -1146,7 +1176,7 @@ function AIRWING:_GetNextMission()
-- Get payload for the asset. -- Get payload for the asset.
if not asset.payload then if not asset.payload then
local payload=self:FetchPayloadFromStock(asset.unittype, mission.type) local payload=self:FetchPayloadFromStock(asset.unittype, mission.type, mission.payloads)
if payload then if payload then
asset.payload=payload asset.payload=payload
table.insert(gotpayload, asset.uid) table.insert(gotpayload, asset.uid)
@ -1832,8 +1862,9 @@ end
-- @param #AIRWING self -- @param #AIRWING self
-- @param #table MissionTypes Types on mission to be checked. Default *all* possible types `AUFTRAG.Type`. -- @param #table MissionTypes Types on mission to be checked. Default *all* possible types `AUFTRAG.Type`.
-- @param #table UnitTypes Types of units. -- @param #table UnitTypes Types of units.
-- @param #table Payloads Specific payloads to be counted only.
-- @return #number Count of available payloads in stock. -- @return #number Count of available payloads in stock.
function AIRWING:CountPayloadsInStock(MissionTypes, UnitTypes) function AIRWING:CountPayloadsInStock(MissionTypes, UnitTypes, Payloads)
if MissionTypes then if MissionTypes then
if type(MissionTypes)=="string" then if type(MissionTypes)=="string" then
@ -1860,6 +1891,20 @@ function AIRWING:CountPayloadsInStock(MissionTypes, UnitTypes)
end end
return false return false
end end
local function _checkPayloads(payload)
if Payloads then
for _,Payload in pairs(Payloads) do
if Payload.uid==payload.id then
return true
end
end
else
-- Payload was not specified.
return true
end
return false
end
local n=0 local n=0
for _,_payload in pairs(self.payloads) do for _,_payload in pairs(self.payloads) do
@ -1867,7 +1912,7 @@ function AIRWING:CountPayloadsInStock(MissionTypes, UnitTypes)
for _,MissionType in pairs(MissionTypes) do for _,MissionType in pairs(MissionTypes) do
if self:CheckMissionCapability(MissionType, payload.capabilities) and _checkUnitTypes(payload) then if self:CheckMissionCapability(MissionType, payload.capabilities) and _checkUnitTypes(payload) and _checkPayloads(payload) then
if payload.unlimited then if payload.unlimited then
-- Payload is unlimited. Return a BIG number. -- Payload is unlimited. Return a BIG number.
@ -1950,7 +1995,7 @@ end
-- @param #AIRWING self -- @param #AIRWING self
-- @param #table MissionTypes Types on mission to be checked. Default all. -- @param #table MissionTypes Types on mission to be checked. Default all.
-- @return #table Assets on pending requests. -- @return #table Assets on pending requests.
function AIRWING:GetAssetsOnMission(MissionTypes, IncludeQueued) function AIRWING:GetAssetsOnMission(MissionTypes)
local assets={} local assets={}
local Np=0 local Np=0
@ -2024,7 +2069,7 @@ function AIRWING:CanMission(Mission)
local unittypes=self:GetAircraftTypes(true, squadrons) local unittypes=self:GetAircraftTypes(true, squadrons)
-- Count all payloads in stock. -- Count all payloads in stock.
local Npayloads=self:CountPayloadsInStock(Mission.type, unittypes) local Npayloads=self:CountPayloadsInStock(Mission.type, unittypes, Mission.payloads)
if Npayloads<Mission.nassets then if Npayloads<Mission.nassets then
self:I(self.lid..string.format("INFO: Not enough PAYLOADS available! Got %d but need at least %d", Npayloads, Mission.nassets)) self:I(self.lid..string.format("INFO: Not enough PAYLOADS available! Got %d but need at least %d", Npayloads, Mission.nassets))
@ -2040,7 +2085,7 @@ function AIRWING:CanMission(Mission)
if can then if can then
-- Number of payloads available. -- Number of payloads available.
local Npayloads=self:CountPayloadsInStock(Mission.type, squadron.aircrafttype) local Npayloads=self:CountPayloadsInStock(Mission.type, squadron.aircrafttype, Mission.payloads)
local assets=squadron:RecruitAssets(Mission, Npayloads) local assets=squadron:RecruitAssets(Mission, Npayloads)

View File

@ -30,6 +30,7 @@
-- @field #string name Mission name. -- @field #string name Mission name.
-- @field #number prio Mission priority. -- @field #number prio Mission priority.
-- @field #boolean urgent Mission is urgent. Running missions with lower prio might be cancelled. -- @field #boolean urgent Mission is urgent. Running missions with lower prio might be cancelled.
-- @field #number importance Importance.
-- @field #number Tstart Mission start time in seconds. -- @field #number Tstart Mission start time in seconds.
-- @field #number Tstop Mission stop time in seconds. -- @field #number Tstop Mission stop time in seconds.
-- @field #number duration Mission duration in seconds. -- @field #number duration Mission duration in seconds.
@ -86,7 +87,8 @@
-- @field #number nassets Number of required assets by the Airwing. -- @field #number nassets Number of required assets by the Airwing.
-- @field #number requestID The ID of the queued warehouse request. Necessary to cancel the request if the mission was cancelled before the request is processed. -- @field #number requestID The ID of the queued warehouse request. Necessary to cancel the request if the mission was cancelled before the request is processed.
-- @field #boolean cancelContactLost If true, cancel mission if the contact is lost. -- @field #boolean cancelContactLost If true, cancel mission if the contact is lost.
-- @field #table squadrons User specifed airwing squadrons assigned for this mission. Only these will be considered for the job! -- @field #table squadrons User specified airwing squadrons assigned for this mission. Only these will be considered for the job!
-- @field #table payloads User specified airwing payloads for this mission. Only these will be considered for the job!
-- @field Ops.AirWing#AIRWING.PatrolData patroldata Patrol data. -- @field Ops.AirWing#AIRWING.PatrolData patroldata Patrol data.
-- --
-- @field #string missionTask Mission task. See `ENUMS.MissionTask`. -- @field #string missionTask Mission task. See `ENUMS.MissionTask`.
@ -1147,7 +1149,9 @@ function AUFTRAG:NewARTY(Target, Nshots, Radius)
mission.artyShots=Nshots or 3 mission.artyShots=Nshots or 3
mission.artyRadius=Radius or 100 mission.artyRadius=Radius or 100
mission.optionROE=ENUMS.ROE.OpenFire mission.optionROE=ENUMS.ROE.OpenFire -- Ground/naval need open fire!
mission.optionAlarm=0
mission.missionFraction=0.1 mission.missionFraction=0.1
mission.DCStask=mission:GetDCSMissionTask() mission.DCStask=mission:GetDCSMissionTask()
@ -1159,22 +1163,31 @@ end
-- @param #AUFTRAG self -- @param #AUFTRAG self
-- @param Ops.Target#TARGET Target The target. -- @param Ops.Target#TARGET Target The target.
-- @return #AUFTRAG self -- @return #AUFTRAG self
function AUFTRAG:NewTARGET(Target) function AUFTRAG:NewTargetAir(Target)
local mission=nil --#AUFTRAG local mission=nil --#AUFTRAG
self.engageTarget=Target
if Target.category==TARGET.Category.GROUND then if Target.category==TARGET.Category.GROUND then
elseif Target.category==TARGET.Category.AIRCRAFT then elseif Target.category==TARGET.Category.AIRCRAFT then
mission=AUFTRAG:NewINTERCEPT(Target)
elseif Target.category==TARGET.Category.AIRBASE then elseif Target.category==TARGET.Category.AIRBASE then
mission=AUFTRAG:NewBOMBRUNWAY(Airdrome,Altitude)
elseif Target.category==TARGET.Category.COORDINATE then elseif Target.category==TARGET.Category.COORDINATE then
end end
local mission=self:NewAUTO()
if mission then if mission then
mission:SetPriority(10, true) mission:SetPriority(10, true)
end end
@ -1288,7 +1301,7 @@ function AUFTRAG:NewAUTO(EngageGroup)
elseif auftrag==AUFTRAG.Type.ARTY then elseif auftrag==AUFTRAG.Type.ARTY then
mission=AUFTRAG:NewARTY(Target) mission=AUFTRAG:NewARTY(Target)
elseif auftrag==AUFTRAG.Type.AWACS then elseif auftrag==AUFTRAG.Type.AWACS then
mission=AUFTRAG:NewAWACS(Coordinate,Altitude,Speed,Heading,Leg) mission=AUFTRAG:NewAWACS(Coordinate, Altitude,Speed,Heading,Leg)
elseif auftrag==AUFTRAG.Type.BAI then elseif auftrag==AUFTRAG.Type.BAI then
mission=AUFTRAG:NewBAI(Target,Altitude) mission=AUFTRAG:NewBAI(Target,Altitude)
elseif auftrag==AUFTRAG.Type.BOMBING then elseif auftrag==AUFTRAG.Type.BOMBING then
@ -1336,20 +1349,6 @@ function AUFTRAG:NewAUTO(EngageGroup)
return mission return mission
end end
--- Create a mission to attack a group. Mission type is automatically chosen from the group category.
-- @param #AUFTRAG self
-- @param Ops.Target#TARGET Target Target to engage.
-- @return #AUFTRAG self
function AUFTRAG:NewTARGET(Target)
for _,_target in pairs(Target) do
local target=_target --Ops.Target#TARGET.Object
a=target.Object
end
return mission
end
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- User API Functions -- User API Functions
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
@ -1394,10 +1393,12 @@ end
-- @param #AUFTRAG self -- @param #AUFTRAG self
-- @param #number Prio Priority 1=high, 100=low. Default 50. -- @param #number Prio Priority 1=high, 100=low. Default 50.
-- @param #boolean Urgent If *true*, another running mission might be cancelled if it has a lower priority. -- @param #boolean Urgent If *true*, another running mission might be cancelled if it has a lower priority.
-- @param #number Importance Number 1-10. If missions with lower value are in the queue, these have to be finished first.
-- @return #AUFTRAG self -- @return #AUFTRAG self
function AUFTRAG:SetPriority(Prio, Urgent) function AUFTRAG:SetPriority(Prio, Urgent)
self.prio=Prio or 50 self.prio=Prio or 50
self.urgent=Urgent self.urgent=Urgent
self.importance=5
return self return self
end end
@ -1687,6 +1688,18 @@ function AUFTRAG:AssignSquadrons(Squadrons)
self.squadrons=Squadrons self.squadrons=Squadrons
end end
--- Set the required payload for this mission.
-- @param #AUFTRAG self
-- @param Ops.AirWing#AIRWING.Payload Required payload
-- @return #AUFTRAG self
function AUFTRAG:AddRequiredPayload(Payload)
self.payloads=self.payloads or {}
table.insert(self.payload, Payload)
end
--- Add a Ops group to the mission. --- Add a Ops group to the mission.
-- @param #AUFTRAG self -- @param #AUFTRAG self
@ -2875,12 +2888,24 @@ function AUFTRAG:GetMissionTypesText(MissionTypes)
return text return text
end end
--- Set the mission waypoint coordinate where the mission is executed. This is
-- @param #AUFTRAG self
-- @return Core.Point#COORDINATE Coordinate where the mission is executed.
-- @return #AUFTRAG self
function AUFTRAG:SetMissionWaypointCoord(Coordinate)
self.missionWaypointCoord=Coordinate
end
--- Get coordinate of target. First unit/group of the set is used. --- Get coordinate of target. First unit/group of the set is used.
-- @param #AUFTRAG self -- @param #AUFTRAG self
-- @param Wrapper.Group#GROUP group Group. -- @param Wrapper.Group#GROUP group Group.
-- @return Core.Point#COORDINATE Coordinate where the mission is executed. -- @return Core.Point#COORDINATE Coordinate where the mission is executed.
function AUFTRAG:GetMissionWaypointCoord(group) function AUFTRAG:GetMissionWaypointCoord(group)
if self.missionWaypointCoord then
return self.missionWaypointCoord
end
-- Create waypoint coordinate half way between us and the target. -- Create waypoint coordinate half way between us and the target.
local waypointcoord=group:GetCoordinate():GetIntermediateCoordinate(self:GetTargetCoordinate(), self.missionFraction) local waypointcoord=group:GetCoordinate():GetIntermediateCoordinate(self:GetTargetCoordinate(), self.missionFraction)
local alt=waypointcoord.y local alt=waypointcoord.y

View File

@ -1759,11 +1759,20 @@ function OPSGROUP:_GetNextMission()
-- Current time. -- Current time.
local time=timer.getAbsTime() local time=timer.getAbsTime()
-- Look for first mission that is SCHEDULED.
local importance=math.huge
for _,_mission in pairs(self.missionqueue) do
local mission=_mission --Ops.Auftrag#AUFTRAG
if mission.importance<importance then
importance=mission.importance
end
end
-- Look for first mission that is SCHEDULED. -- Look for first mission that is SCHEDULED.
for _,_mission in pairs(self.missionqueue) do for _,_mission in pairs(self.missionqueue) do
local mission=_mission --Ops.Auftrag#AUFTRAG local mission=_mission --Ops.Auftrag#AUFTRAG
if mission:GetGroupStatus(self)==AUFTRAG.Status.SCHEDULED and (mission:IsReadyToGo() or self.airwing) then if mission:GetGroupStatus(self)==AUFTRAG.Status.SCHEDULED and (mission:IsReadyToGo() or self.airwing) and mission.importance<=importance then
return mission return mission
end end
end end

View File

@ -758,11 +758,12 @@ end
--- Get assets for a mission. --- Get assets for a mission.
-- @param #SQUADRON self -- @param #SQUADRON self
-- @param Ops.Auftrag#AUFTRAG Mission The mission. -- @param Ops.Auftrag#AUFTRAG Mission The mission.
-- @param #number Nplayloads Number of payloads available.
-- @return #table Assets that can do the required mission. -- @return #table Assets that can do the required mission.
function SQUADRON:RecruitAssets(Mission) function SQUADRON:RecruitAssets(Mission, Npayloads)
-- Number of payloads available. -- Number of payloads available.
local Npayloads=self.airwing:CountPayloadsInStock(Mission.type, self.aircrafttype) Npayloads=Npayloads or self.airwing:CountPayloadsInStock(Mission.type, self.aircrafttype, Mission.payloads)
local assets={} local assets={}

View File

@ -4,7 +4,7 @@
-- --
-- * Manages target, number alive, life points, damage etc. -- * Manages target, number alive, life points, damage etc.
-- * Events when targets are damaged or destroyed -- * Events when targets are damaged or destroyed
-- * Various target objects: UNIT, GROUP, STATIC, SET_UNIT, AIRBASE, COORDINATE, SET_GROUP, SET_UNIT -- * Various target objects: UNIT, GROUP, STATIC, AIRBASE, COORDINATE, SET_GROUP, SET_UNIT
-- --
-- === -- ===
-- --
@ -114,7 +114,7 @@ TARGET.version="0.0.1"
-- TODO list -- TODO list
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO: Improve airwing selection. Mostly done! -- TODO: A lot.
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Constructor -- Constructor
@ -680,7 +680,7 @@ function TARGET:GetCoordinate()
end end
--- Get target category --- Get target category.
-- @param #TARGET self -- @param #TARGET self
-- @param #TARGET.Object Target Target object. -- @param #TARGET.Object Target Target object.
-- @return #TARGET.Category Target category. -- @return #TARGET.Category Target category.

View File

@ -1166,6 +1166,32 @@ end
do -- Is Zone methods do -- Is Zone methods
--- Check if any unit of a group is inside a @{Zone}.
-- @param #GROUP self
-- @param Core.Zone#ZONE_BASE Zone The zone to test.
-- @return #boolean Returns true if at least one unit is inside the zone or false if no unit is inside.
function GROUP:IsInZone( Zone )
if self:IsAlive() then
for UnitID, UnitData in pairs(self:GetUnits()) do
local Unit = UnitData -- Wrapper.Unit#UNIT
if Zone:IsVec3InZone(Unit:GetVec3()) then
return true -- At least one unit is in the zone. That is enough.
else
-- This one is not but another could be.
end
end
return false
end
return nil
end
--- Returns true if all units of the group are within a @{Zone}. --- Returns true if all units of the group are within a @{Zone}.
-- @param #GROUP self -- @param #GROUP self
-- @param Core.Zone#ZONE_BASE Zone The zone to test. -- @param Core.Zone#ZONE_BASE Zone The zone to test.