mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
OPS
- Simplified asset selection by using just one routine for LEGION, COMMANDER and CHIEF
This commit is contained in:
parent
589ebd5bca
commit
9161cec238
@ -664,9 +664,6 @@ function CHIEF:onafterStatus(From, Event, To)
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Is this a threat?
|
|
||||||
local threat=contact.threatlevel>=self.threatLevelMin and contact.threatlevel<=self.threatLevelMax
|
|
||||||
|
|
||||||
--[[
|
--[[
|
||||||
local redalert=true
|
local redalert=true
|
||||||
if self.borderzoneset:Count()>0 then
|
if self.borderzoneset:Count()>0 then
|
||||||
@ -987,8 +984,11 @@ function CHIEF:CheckTargetQueue()
|
|||||||
for _,_target in pairs(self.targetqueue) do
|
for _,_target in pairs(self.targetqueue) do
|
||||||
local target=_target --Ops.Target#TARGET
|
local target=_target --Ops.Target#TARGET
|
||||||
|
|
||||||
|
-- Is this a threat?
|
||||||
|
local isThreat=target.threatlevel0>=self.threatLevelMin and target.threatlevel0<=self.threatLevelMax
|
||||||
|
|
||||||
-- Check that target is alive and not already a mission has been assigned.
|
-- Check that target is alive and not already a mission has been assigned.
|
||||||
if target:IsAlive() and (target.importance==nil or target.importance<=vip) and not target.mission then
|
if target:IsAlive() and (target.importance==nil or target.importance<=vip) and isThreat and not target.mission then
|
||||||
|
|
||||||
-- Check if this target is "valid", i.e. fits with the current strategy.
|
-- Check if this target is "valid", i.e. fits with the current strategy.
|
||||||
local valid=false
|
local valid=false
|
||||||
@ -1425,7 +1425,7 @@ function CHIEF:RecruitAssetsForTarget(Target, MissionType, NassetsMin, NassetsMa
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Now we have a long list with assets.
|
-- Now we have a long list with assets.
|
||||||
self:_OptimizeAssetSelection(Assets, MissionType, TargetVec2, false)
|
LEGION._OptimizeAssetSelection(self, Assets, MissionType, TargetVec2, false)
|
||||||
|
|
||||||
for _,_asset in pairs(Assets) do
|
for _,_asset in pairs(Assets) do
|
||||||
local asset=_asset --Functional.Warehouse#WAREHOUSE.Assetitem
|
local asset=_asset --Functional.Warehouse#WAREHOUSE.Assetitem
|
||||||
@ -1454,7 +1454,7 @@ function CHIEF:RecruitAssetsForTarget(Target, MissionType, NassetsMin, NassetsMa
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Now find the best asset for the given payloads.
|
-- Now find the best asset for the given payloads.
|
||||||
self:_OptimizeAssetSelection(Assets, MissionType, TargetVec2, true)
|
LEGION._OptimizeAssetSelection(self, Assets, MissionType, TargetVec2, true)
|
||||||
|
|
||||||
-- Number of assets. At most NreqMax.
|
-- Number of assets. At most NreqMax.
|
||||||
local Nassets=math.min(#Assets, NassetsMax)
|
local Nassets=math.min(#Assets, NassetsMax)
|
||||||
@ -1507,41 +1507,6 @@ function CHIEF:RecruitAssetsForTarget(Target, MissionType, NassetsMin, NassetsMa
|
|||||||
return nil, {}, {}
|
return nil, {}, {}
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Optimize chosen assets for the mission at hand.
|
|
||||||
-- @param #CHIEF self
|
|
||||||
-- @param #table assets Table of (unoptimized) assets.
|
|
||||||
-- @param #string MissionType MissionType for which the best assets are desired.
|
|
||||||
-- @param DCS#Vec2 TargetVec2 Target 2D vector.
|
|
||||||
-- @param #boolean includePayload If true, include the payload in the calulation if the asset has one attached.
|
|
||||||
function CHIEF:_OptimizeAssetSelection(assets, MissionType, TargetVec2, includePayload)
|
|
||||||
|
|
||||||
-- Calculate the mission score of all assets.
|
|
||||||
for _,_asset in pairs(assets) do
|
|
||||||
local asset=_asset --Functional.Warehouse#WAREHOUSE.Assetitem
|
|
||||||
asset.score=asset.legion:CalculateAssetMissionScore(asset, MissionType, TargetVec2, includePayload)
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Sort assets wrt to their mission score. Higher is better.
|
|
||||||
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.
|
|
||||||
return (assetA.score>assetB.score)
|
|
||||||
end
|
|
||||||
table.sort(assets, optimize)
|
|
||||||
|
|
||||||
-- Remove distance parameter.
|
|
||||||
local text=string.format("Optimized %d assets for %s mission (payload=%s):", #assets, MissionType, 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", asset.squadname, asset.spawngroupname, asset.score)
|
|
||||||
asset.score=nil
|
|
||||||
end
|
|
||||||
self:T2(self.lid..text)
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
@ -294,7 +294,7 @@ function COHORT:AddMissionCapability(MissionTypes, Performance)
|
|||||||
capability.MissionType=missiontype
|
capability.MissionType=missiontype
|
||||||
capability.Performance=Performance or 50
|
capability.Performance=Performance or 50
|
||||||
table.insert(self.missiontypes, capability)
|
table.insert(self.missiontypes, capability)
|
||||||
env.info("FF adding mission capability "..tostring(capability.MissionType))
|
self:T(self.lid..string.format("Adding mission capability %s, performance=%d", tostring(capability.MissionType), capability.Performance))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -829,13 +829,13 @@ function COHORT:RecruitAssets(MissionType, Npayloads)
|
|||||||
|
|
||||||
-- Check if the payload of this asset is compatible with the mission.
|
-- Check if the payload of this asset is compatible with the mission.
|
||||||
-- Note: we do not check the payload as an asset that is on a GCICAP mission should be able to do an INTERCEPT as well!
|
-- Note: we do not check the payload as an asset that is on a GCICAP mission should be able to do an INTERCEPT as well!
|
||||||
self:I(self.lid.."Adding asset on GCICAP mission for an INTERCEPT mission")
|
self:I(self.lid..string.format("Adding asset on GCICAP mission for an INTERCEPT mission"))
|
||||||
table.insert(assets, asset)
|
table.insert(assets, asset)
|
||||||
|
|
||||||
elseif self.legion:IsAssetOnMission(asset, AUFTRAG.Type.ALERT5) and self:CheckMissionCapability(MissionType, asset.payload.capabilities) then
|
elseif self.legion:IsAssetOnMission(asset, AUFTRAG.Type.ALERT5) and self:CheckMissionCapability(MissionType, asset.payload.capabilities) then
|
||||||
|
|
||||||
-- Check if the payload of this asset is compatible with the mission.
|
-- 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")
|
self:I(self.lid..string.format("Adding asset on ALERT 5 mission for %s mission", MissionType))
|
||||||
table.insert(assets, asset)
|
table.insert(assets, asset)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@ -775,8 +775,11 @@ function COMMANDER:RecruitAssets(Mission)
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Target position.
|
||||||
|
local TargetVec2=Mission.type~=AUFTRAG.Type.ALERT5 and Mission:GetTargetVec2() or nil
|
||||||
|
|
||||||
-- Now we have a long list with assets.
|
-- Now we have a long list with assets.
|
||||||
self:_OptimizeAssetSelection(Assets, Mission, false)
|
LEGION._OptimizeAssetSelection(self, Assets, Mission.type, TargetVec2, false)
|
||||||
|
|
||||||
for _,_asset in pairs(Assets) do
|
for _,_asset in pairs(Assets) do
|
||||||
local asset=_asset --Functional.Warehouse#WAREHOUSE.Assetitem
|
local asset=_asset --Functional.Warehouse#WAREHOUSE.Assetitem
|
||||||
@ -813,7 +816,7 @@ function COMMANDER:RecruitAssets(Mission)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Now find the best asset for the given payloads.
|
-- Now find the best asset for the given payloads.
|
||||||
self:_OptimizeAssetSelection(Assets, Mission, true)
|
LEGION._OptimizeAssetSelection(self, Assets, Mission.type, TargetVec2, true)
|
||||||
|
|
||||||
-- Get number of required assets.
|
-- Get number of required assets.
|
||||||
local Nassets=Mission:GetRequiredAssets(self)
|
local Nassets=Mission:GetRequiredAssets(self)
|
||||||
@ -867,43 +870,6 @@ function COMMANDER:RecruitAssets(Mission)
|
|||||||
return nil, {}
|
return nil, {}
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Optimize chosen assets for the mission at hand.
|
|
||||||
-- @param #COMMANDER self
|
|
||||||
-- @param #table assets Table of (unoptimized) assets.
|
|
||||||
-- @param Ops.Auftrag#AUFTRAG Mission Mission for which the best assets are desired.
|
|
||||||
-- @param #boolean includePayload If true, include the payload in the calulation if the asset has one attached.
|
|
||||||
function COMMANDER:_OptimizeAssetSelection(assets, Mission, includePayload)
|
|
||||||
|
|
||||||
-- Target position.
|
|
||||||
local TargetVec2=Mission.type~=AUFTRAG.Type.ALERT5 and Mission:GetTargetVec2() or nil
|
|
||||||
|
|
||||||
-- Calculate the mission score of all assets.
|
|
||||||
for _,_asset in pairs(assets) do
|
|
||||||
local asset=_asset --Functional.Warehouse#WAREHOUSE.Assetitem
|
|
||||||
asset.score=asset.legion:CalculateAssetMissionScore(asset, Mission, TargetVec2, includePayload)
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Sort assets wrt to their mission score. Higher is better.
|
|
||||||
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.
|
|
||||||
return (assetA.score>assetB.score)
|
|
||||||
end
|
|
||||||
table.sort(assets, optimize)
|
|
||||||
|
|
||||||
-- Remove distance parameter.
|
|
||||||
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", asset.squadname, asset.spawngroupname, asset.score)
|
|
||||||
asset.dist=nil
|
|
||||||
asset.score=nil
|
|
||||||
end
|
|
||||||
self:T2(self.lid..text)
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-- Transport Functions
|
-- Transport Functions
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
@ -1061,8 +1027,12 @@ function COMMANDER:RecruitAssetsForTransport(Transport)
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Target position.
|
||||||
|
local TargetVec2=Transport:GetDeployZone():GetVec2()
|
||||||
|
|
||||||
-- Now we have a long list with assets.
|
-- Now we have a long list with assets.
|
||||||
self:_OptimizeAssetSelectionForTransport(Assets, Transport)
|
LEGION._OptimizeAssetSelection(self, Assets, AUFTRAG.Type.OPSTRANSPORT, TargetVec2, false)
|
||||||
|
|
||||||
|
|
||||||
for _,_asset in pairs(Assets) do
|
for _,_asset in pairs(Assets) do
|
||||||
local asset=_asset --Functional.Warehouse#WAREHOUSE.Assetitem
|
local asset=_asset --Functional.Warehouse#WAREHOUSE.Assetitem
|
||||||
@ -1146,39 +1116,6 @@ function COMMANDER:RecruitAssetsForTransport(Transport)
|
|||||||
return nil, {}
|
return nil, {}
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Optimize chosen assets for the given transport.
|
|
||||||
-- @param #COMMANDER self
|
|
||||||
-- @param #table assets Table of (unoptimized) assets.
|
|
||||||
-- @param Ops.OpsTransport#OPSTRANSPORT Transport Transport assignment.
|
|
||||||
function COMMANDER:_OptimizeAssetSelectionForTransport(assets, Transport)
|
|
||||||
|
|
||||||
-- Calculate the mission score of all assets.
|
|
||||||
for _,_asset in pairs(assets) do
|
|
||||||
local asset=_asset --Functional.Warehouse#WAREHOUSE.Assetitem
|
|
||||||
asset.score=asset.legion:CalculateAssetTransportScore(asset, Transport)
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Sort assets wrt to their mission score. Higher is better.
|
|
||||||
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.
|
|
||||||
return (assetA.score>assetB.score)
|
|
||||||
end
|
|
||||||
table.sort(assets, optimize)
|
|
||||||
|
|
||||||
-- Remove distance parameter.
|
|
||||||
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", asset.squadname, asset.spawngroupname, asset.score)
|
|
||||||
asset.dist=nil
|
|
||||||
asset.score=nil
|
|
||||||
end
|
|
||||||
self:T2(self.lid..text)
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-- Resources
|
-- Resources
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|||||||
@ -1677,8 +1677,11 @@ function LEGION:RecruitAssets(Mission)
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Target position.
|
||||||
|
local TargetVec2=Mission.type~=AUFTRAG.Type.ALERT5 and Mission:GetTargetVec2() or nil
|
||||||
|
|
||||||
-- Now we have a long list with assets.
|
-- Now we have a long list with assets.
|
||||||
self:_OptimizeAssetSelection(Assets, Mission, false)
|
self:_OptimizeAssetSelection(Assets, Mission.type, TargetVec2, false)
|
||||||
|
|
||||||
-- If airwing, get the best payload available.
|
-- If airwing, get the best payload available.
|
||||||
if self:IsAirwing() then
|
if self:IsAirwing() then
|
||||||
@ -1713,7 +1716,7 @@ function LEGION:RecruitAssets(Mission)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Now find the best asset for the given payloads.
|
-- Now find the best asset for the given payloads.
|
||||||
self:_OptimizeAssetSelection(Assets, Mission, true)
|
self:_OptimizeAssetSelection(Assets, Mission.type, TargetVec2, true)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -1771,106 +1774,6 @@ function LEGION:RecruitAssets(Mission)
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Calculate the mission score of an asset.
|
|
||||||
-- @param #LEGION self
|
|
||||||
-- @param Functional.Warehouse#WAREHOUSE.Assetitem asset Asset
|
|
||||||
-- @param Ops.Auftrag#AUFTRAG Mission Mission for which the best assets are desired.
|
|
||||||
-- @param DCS#Vec2 TargetVec2 Target 2D vector.
|
|
||||||
-- @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, TargetVec2, includePayload)
|
|
||||||
|
|
||||||
-- Mission score.
|
|
||||||
local score=0
|
|
||||||
|
|
||||||
-- Prefer highly skilled assets.
|
|
||||||
if asset.skill==AI.Skill.AVERAGE then
|
|
||||||
score=score+0
|
|
||||||
elseif asset.skill==AI.Skill.GOOD then
|
|
||||||
score=score+10
|
|
||||||
elseif asset.skill==AI.Skill.HIGH then
|
|
||||||
score=score+20
|
|
||||||
elseif asset.skill==AI.Skill.EXCELLENT then
|
|
||||||
score=score+30
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Add mission performance to score.
|
|
||||||
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
|
|
||||||
|
|
||||||
-- 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 asset.spawned then
|
|
||||||
self:T(self.lid.."Adding 25 to asset because it is spawned")
|
|
||||||
score=score+25
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- 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.
|
|
||||||
-- Max speed of assets.
|
|
||||||
-- Fuel amount?
|
|
||||||
-- Range of assets?
|
|
||||||
|
|
||||||
return score
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Optimize chosen assets for the mission at hand.
|
|
||||||
-- @param #LEGION self
|
|
||||||
-- @param #table assets Table of (unoptimized) assets.
|
|
||||||
-- @param Ops.Auftrag#AUFTRAG Mission Mission for which the best assets are desired.
|
|
||||||
-- @param #boolean includePayload If true, include the payload in the calulation if the asset has one attached.
|
|
||||||
function LEGION:_OptimizeAssetSelection(assets, Mission, includePayload)
|
|
||||||
|
|
||||||
-- Target position.
|
|
||||||
local TargetVec2=Mission.type~=AUFTRAG.Type.ALERT5 and Mission:GetTargetVec2() or nil
|
|
||||||
|
|
||||||
-- Calculate the mission score of all assets.
|
|
||||||
for _,_asset in pairs(assets) do
|
|
||||||
local asset=_asset --Functional.Warehouse#WAREHOUSE.Assetitem
|
|
||||||
asset.score=self:CalculateAssetMissionScore(asset, Mission, TargetVec2, includePayload)
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Sort assets wrt to their mission score. Higher is better.
|
|
||||||
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.
|
|
||||||
return (assetA.score>assetB.score)
|
|
||||||
end
|
|
||||||
table.sort(assets, optimize)
|
|
||||||
|
|
||||||
-- Remove distance parameter.
|
|
||||||
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", asset.squadname, asset.spawngroupname, asset.score)
|
|
||||||
asset.dist=nil
|
|
||||||
asset.score=nil
|
|
||||||
end
|
|
||||||
self:T2(self.lid..text)
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-- Transport Functions
|
-- Transport Functions
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
@ -1939,8 +1842,11 @@ function LEGION:RecruitAssetsForTransport(Transport)
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Target is the deploy zone.
|
||||||
|
local TargetVec2=Transport:GetDeployZone():GetVec2()
|
||||||
|
|
||||||
-- Sort asset list. Best ones come first.
|
-- Sort asset list. Best ones come first.
|
||||||
self:_OptimizeAssetSelectionForTransport(Assets, Transport)
|
self:_OptimizeAssetSelection(Assets, AUFTRAG.Type.OPSTRANSPORT, TargetVec2, false)
|
||||||
|
|
||||||
-- If airwing, get the best payload available.
|
-- If airwing, get the best payload available.
|
||||||
if self:IsAirwing() then
|
if self:IsAirwing() then
|
||||||
@ -2025,46 +1931,18 @@ function LEGION:RecruitAssetsForTransport(Transport)
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
--- Optimize chosen assets for the mission at hand.
|
-- Optimization Functions
|
||||||
-- @param #LEGION self
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-- @param #table assets Table of (unoptimized) assets.
|
|
||||||
-- @param Ops.OpsTransport#OPSTRANSPORT Transport The transport.
|
|
||||||
function LEGION:_OptimizeAssetSelectionForTransport(assets, Transport)
|
|
||||||
|
|
||||||
-- Calculate the mission score of all assets.
|
|
||||||
for _,_asset in pairs(assets) do
|
|
||||||
local asset=_asset --Functional.Warehouse#WAREHOUSE.Assetitem
|
|
||||||
asset.score=self:CalculateAssetTransportScore(asset, Transport)
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Sort assets wrt to their mission score. Higher is better.
|
|
||||||
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.
|
|
||||||
return (assetA.score>assetB.score)
|
|
||||||
end
|
|
||||||
table.sort(assets, optimize)
|
|
||||||
|
|
||||||
-- Remove distance parameter.
|
|
||||||
local text=string.format("Optimized %d assets for transport:", #assets)
|
|
||||||
for i,Asset in pairs(assets) do
|
|
||||||
local asset=Asset --Functional.Warehouse#WAREHOUSE.Assetitem
|
|
||||||
text=text..string.format("\n%s %s: score=%d", asset.squadname, asset.spawngroupname, asset.score)
|
|
||||||
asset.dist=nil
|
|
||||||
asset.score=nil
|
|
||||||
end
|
|
||||||
self:T2(self.lid..text)
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Calculate the mission score of an asset.
|
--- Calculate the mission score of an asset.
|
||||||
-- @param #LEGION self
|
-- @param #LEGION self
|
||||||
-- @param Functional.Warehouse#WAREHOUSE.Assetitem asset Asset
|
-- @param Functional.Warehouse#WAREHOUSE.Assetitem asset Asset
|
||||||
-- @param Ops.OpsTransport#OPSTRANSPORT Transport The transport.
|
-- @param #string MissionType Mission type for which the best assets are desired.
|
||||||
|
-- @param DCS#Vec2 TargetVec2 Target 2D vector.
|
||||||
|
-- @param #boolean IncludePayload If `true`, include the payload in the calulation if the asset has one attached.
|
||||||
-- @return #number Mission score.
|
-- @return #number Mission score.
|
||||||
function LEGION:CalculateAssetTransportScore(asset, Transport)
|
function LEGION:CalculateAssetMissionScore(asset, MissionType, TargetVec2, IncludePayload)
|
||||||
|
|
||||||
-- Mission score.
|
-- Mission score.
|
||||||
local score=0
|
local score=0
|
||||||
@ -2081,13 +1959,15 @@ function LEGION:CalculateAssetTransportScore(asset, Transport)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Add mission performance to score.
|
-- Add mission performance to score.
|
||||||
score=score+asset.cohort:GetMissionPeformance(AUFTRAG.Type.OPSTRANSPORT)
|
score=score+asset.cohort:GetMissionPeformance(MissionType)
|
||||||
|
|
||||||
-- Target position.
|
-- Add payload performance to score.
|
||||||
local TargetVec2=Transport:GetDeployZone():GetVec2()
|
if IncludePayload and asset.payload then
|
||||||
|
score=score+LEGION.GetPayloadPeformance(self, asset.payload, MissionType)
|
||||||
|
end
|
||||||
|
|
||||||
-- Origin: We take the flightgroups position or the one of the legion.
|
-- Origin: We take the OPSGROUP position or the one of the legion.
|
||||||
local OrigVec2=asset.flightgroup and asset.flightgroup:GetVec2() or self:GetVec2()
|
local OrigVec2=asset.flightgroup and asset.flightgroup:GetVec2() or asset.legion:GetVec2()
|
||||||
|
|
||||||
-- Distance factor.
|
-- Distance factor.
|
||||||
local distance=0
|
local distance=0
|
||||||
@ -2101,18 +1981,63 @@ function LEGION:CalculateAssetTransportScore(asset, Transport)
|
|||||||
-- Reduce score for legions that are futher away.
|
-- Reduce score for legions that are futher away.
|
||||||
score=score-distance
|
score=score-distance
|
||||||
|
|
||||||
-- Add 1 score point for each 10 kg of cargo bay.
|
-- Intercepts need to be carried out quickly. We prefer spawned assets.
|
||||||
score=score+UTILS.Round(asset.cargobaymax/10, 0)
|
if MissionType==AUFTRAG.Type.INTERCEPT then
|
||||||
|
if asset.spawned then
|
||||||
--TODO: Check ALERT 5 for Transports.
|
self:T(self.lid.."Adding 25 to asset because it is spawned")
|
||||||
if asset.spawned then
|
score=score+25
|
||||||
self:T(self.lid.."Adding 25 to asset because it is spawned")
|
end
|
||||||
score=score+25
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- TRANSPORT specific.
|
||||||
|
if MissionType==AUFTRAG.Type.OPSTRANSPORT then
|
||||||
|
-- Add 1 score point for each 10 kg of cargo bay.
|
||||||
|
score=score+UTILS.Round(asset.cargobaymax/10, 0)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 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.
|
||||||
|
-- Max speed of assets.
|
||||||
|
-- Fuel amount?
|
||||||
|
-- Range of assets?
|
||||||
|
|
||||||
return score
|
return score
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Optimize chosen assets for the mission at hand.
|
||||||
|
-- @param #LEGION self
|
||||||
|
-- @param #table assets Table of (unoptimized) assets.
|
||||||
|
-- @param #string MissionType Mission type.
|
||||||
|
-- @param DCS#Vec2 TargetVec2 Target position as 2D vector.
|
||||||
|
-- @param #boolean IncludePayload If `true`, include the payload in the calulation if the asset has one attached.
|
||||||
|
function LEGION:_OptimizeAssetSelection(assets, MissionType, TargetVec2, IncludePayload)
|
||||||
|
|
||||||
|
-- Calculate the mission score of all assets.
|
||||||
|
for _,_asset in pairs(assets) do
|
||||||
|
local asset=_asset --Functional.Warehouse#WAREHOUSE.Assetitem
|
||||||
|
asset.score=LEGION.CalculateAssetMissionScore(self, asset, MissionType, TargetVec2, IncludePayload)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Sort assets wrt to their mission score. Higher is better.
|
||||||
|
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.
|
||||||
|
return (assetA.score>assetB.score)
|
||||||
|
end
|
||||||
|
table.sort(assets, optimize)
|
||||||
|
|
||||||
|
-- Remove distance parameter.
|
||||||
|
local text=string.format("Optimized %d assets for %s mission/transport (payload=%s):", #assets, MissionType, 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", asset.squadname, asset.spawngroupname, asset.score)
|
||||||
|
asset.score=nil
|
||||||
|
end
|
||||||
|
self:T2(self.lid..text)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-- Misc Functions
|
-- Misc Functions
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user