This commit is contained in:
Frank
2020-03-10 00:44:50 +01:00
parent 781ebc7a42
commit a477fc78bc
6 changed files with 196 additions and 78 deletions
@@ -1608,6 +1608,8 @@ WAREHOUSE = {
-- @field #boolean spawned If true, asset was spawned into the cruel world. If false, it is still in stock.
-- @field #string spawngroupname Name of the spawned group.
-- @field #boolean iscargo If true, asset is cargo. If false asset is transport. Nil if in stock.
-- @field #number rid The request ID of this asset.
-- @field #boolean arrived If true, asset arrived at its destination.
--- Item of the warehouse queue table.
-- @type WAREHOUSE.Queueitem
@@ -3747,12 +3749,6 @@ function WAREHOUSE:onafterAddAsset(From, Event, To, group, ngroups, forceattribu
if asset~=nil then
self:_DebugMessage(string.format("Warehouse %s: Adding KNOWN asset uid=%d with attribute=%s to stock.", self.alias, asset.uid, asset.attribute), 5)
-- Asset now belongs to this warehouse. Set warehouse ID.
asset.wid=self.uid
-- No request associated with this asset.
asset.rid=nil
-- Set livery.
if liveries then
if type(liveries)=="table" then
@@ -3761,13 +3757,20 @@ function WAREHOUSE:onafterAddAsset(From, Event, To, group, ngroups, forceattribu
asset.livery=liveries
end
end
-- Set skill.
asset.skill=skill or asset.skill
-- Asset now belongs to this warehouse. Set warehouse ID.
asset.wid=self.uid
-- No request associated with this asset.
asset.rid=nil
-- Asset is not spawned.
asset.spawned=false
asset.iscargo=nil
asset.arrived=nil
-- Add asset to stock.
table.insert(self.stock, asset)
@@ -4259,6 +4262,7 @@ function WAREHOUSE:onafterRequest(From, Event, To, Request)
-- Asset is transport.
_assetitem.spawned=false
_assetitem.iscargo=false
_assetitem.arrived=false
local spawngroup=nil --Wrapper.Group#GROUP
@@ -4675,6 +4679,28 @@ function WAREHOUSE:onafterUnloaded(From, Event, To, group)
end
end
--- On before "Arrived" event. Triggered when a group has arrived at its destination warehouse.
-- @param #WAREHOUSE self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
-- @param Wrapper.Group#GROUP group The group that was delivered.
function WAREHOUSE:onbeforeArrived(From, Event, To, group)
local asset=self:FindAssetInDB(group)
if asset then
if asset.arrived==true then
-- Asset already arrived (e.g. if multiple units trigger the event via landing).
return false
else
asset.arrived=true --ensure this is not called again from the same asset group.
return true
end
end
end
--- On after "Arrived" event. Triggered when a group has arrived at its destination warehouse.
-- The routine should be called by the warehouse sending this asset and not by the receiving warehouse.
-- It is checked if this asset is cargo (or self propelled) or transport. If it is cargo it is put into the stock of receiving warehouse.
@@ -4718,7 +4744,8 @@ function WAREHOUSE:onafterArrived(From, Event, To, group)
end
-- Increase number of cargo delivered and transports home.
local istransport=warehouse:_GroupIsTransport(group,request)
--local istransport=warehouse:_GroupIsTransport(group,request)
if istransport==true then
request.ntransporthome=request.ntransporthome+1
request.transportgroupset:Remove(group:GetName(), true)
@@ -5612,11 +5639,12 @@ function WAREHOUSE:_SpawnAssetAircraft(alias, asset, request, parking, uncontrol
if asset.payload then
unit.payload=asset.payload.pylons
env.info("FF payload")
self:I({playload=unit.payload})
self:I(asset)
self:I({playload=unit.payload})
else
env.info("FF No payload for asset!")
end
env.info("FF Asset info")
self:I(asset)
end
@@ -5916,7 +5944,7 @@ end
-- @param Wrapper.Group#GROUP group The group that arrived.
-- @param #number n Waypoint passed.
-- @param #number N Final waypoint.
function WAREHOUSE:_PassingWaypoint(group,n,N)
function WAREHOUSE:_PassingWaypoint(group, n, N)
self:T(self.lid..string.format("Group %s passing waypoint %d of %d!", tostring(group:GetName()), n, N))
-- Final waypoint reached.
@@ -6910,7 +6938,7 @@ function WAREHOUSE:_CheckRequestNow(request)
if not _enough then
local text=string.format("Warehouse %s: Request ID=%d denied! Not enough (cargo) assets currently available.", self.alias, request.uid)
self:_InfoMessage(text, 5)
text=string.format("Enough=%s, #_assets=%d, _nassets=%d, request.nasset=%s", tostring(_enough), #_assets,_nassets, tostring(request.nasset))
text=string.format("Enough=%s, #assets=%d, nassets=%d, request.nasset=%s", tostring(_enough), #_assets,_nassets, tostring(request.nasset))
self:T(self.lid..text)
return false
end
@@ -7830,18 +7858,15 @@ function WAREHOUSE:_FilterStock(stock, descriptor, attribute, nmax, mobile)
-- Count total number in stock.
local ntot=0
for _,_asset in ipairs(stock) do
local asset=_asset --#WAREHOUSE.Assetitem
for _,_rasset in pairs(attribute) do
local rasset=_rasset --#WAREHOUSE.Assetitem
for _,_rasset in pairs(attribute) do
local rasset=_rasset --#WAREHOUSE.Assetitem
for _,_asset in ipairs(stock) do
local asset=_asset --#WAREHOUSE.Assetitem
if rasset.uid==asset.uid then
table.insert(filtered, asset)
end
end
break
end
end
end
return filtered, #filtered, #filtered>=#attribute
+37 -23
View File
@@ -479,6 +479,10 @@ function AIRWING:onafterStatus(From, Event, To)
--self:CheckAWACS()
-- TODO: count payloads, count squadrons, count missions
local text=string.format("Status %s: missions=%d, payloads=%d, squads=%d", fsmstate, #self.missionqueue, #self.payloads, #self.squadrons)
self:I(self.lid..text)
------------------
-- Mission Info --
------------------
@@ -514,21 +518,14 @@ function AIRWING:onafterStatus(From, Event, To)
missiontext=string.format(" [%s (%s): status=%s]", mission.type, mission.name, mission.status)
end
text=text..string.format("\n -[%d] %s*%d: spawned=%s, mission=%s%s", j, typename, asset.nunits, spawned, tostring(self:IsAssetOnMission(asset)), missiontext)
local payload=asset.payload
if payload then
text=text.." payload "..table.concat(payload.missiontypes, ", ")
else
text=text.." NO payload!"
end
text=text..string.format("\n -[%d] %s*%d \"%s\": spawned=%s, mission=%s%s", j, typename, asset.nunits, asset.spawngroupname, spawned, tostring(self:IsAssetOnMission(asset)), missiontext)
local payload=asset.payload and table.concat(asset.payload.missiontypes, ", ") or "None"
text=text.." payload="..payload
end
end
self:I(self.lid..text)
--------------
-- Mission ---
--------------
@@ -651,14 +648,13 @@ function AIRWING:_GetNextMission()
-- Get payload for the asset.
asset.payload=self:FetchPayloadFromStock(asset.unittype, mission.type)
env.info("FF asset payload for mission "..mission.type)
self:I(asset.payload)
-- Should not happen as we just checked!
if not asset.payload then
self:E(self.lid.."ERROR: No payload for asset! This should not happen!")
end
-- Add asset to mission.
mission:AddAsset(asset)
end
@@ -763,6 +759,17 @@ function AIRWING:onafterMissionRequest(From, Event, To, Mission)
-- Add request to airwing warehouse.
if #Assetlist>0 then
--local text=string.format("Requesting assets for mission %s:", Mission.name)
for i,_asset in pairs(Assetlist) do
local asset=_asset --#AIRWING.SquadronAsset
-- Set asset to requested! Important so that new requests do not use this asset!
asset.requested=true
--text=text..string.format("\n[%d] %s spawned=%s type=%s payload=%s", i, asset.spawngroupname, tostring(asset.spawned), asset.unittype, asset.payload and table.concat(asset.payload.missiontypes, ", ") or "no payload!")
end
--self:I(self.lid..text)
-- Add request to airwing warehouse.
-- TODO: better Assignment string.
self:AddRequest(self, WAREHOUSE.Descriptor.ASSETLIST, Assetlist, #Assetlist, nil, nil, Mission.prio, tostring(Mission.auftragsnummer))
@@ -874,6 +881,9 @@ function AIRWING:onafterAssetSpawned(From, Event, To, group, asset, request)
-- Create a flight group.
asset.flightgroup=self:_CreateFlightGroup(asset)
-- Not requested any more.
asset.requested=nil
-- Get Mission (if any).
local mission=self:GetMissionByID(request.assignment)
@@ -1051,7 +1061,7 @@ function AIRWING:SquadronCanMission(Squadron, MissionType, Nassets)
-- Check if the payload of this asset is compatible with the mission.
if self:CheckMissionType(MissionType, asset.payload.missiontypes) then
-- TODO: Check if asset actually has weapons left. Difficult!
table.insert(assets, asset)
--table.insert(assets, asset)
end
end
@@ -1065,15 +1075,19 @@ function AIRWING:SquadronCanMission(Squadron, MissionType, Nassets)
if asset.spawned then
-- This asset is already spawned. Let's check if it has the right payload.
if self:CheckMissionType(MissionType, asset.payload.missiontypes) then
table.insert(assets, asset)
--table.insert(assets, asset)
end
else
-- Check if we got a payload and reserve it for this asset.
local payload=self:FetchPayloadFromStock(asset.unittype, MissionType)
if payload then
asset.payload=payload
table.insert(assets, asset)
if not asset.requested then
-- Check if we got a payload and reserve it for this asset.
local payload=self:FetchPayloadFromStock(asset.unittype, MissionType)
if payload then
asset.payload=payload
table.insert(assets, asset)
end
end
end
@@ -1215,7 +1229,7 @@ function AIRWING:CanMission(MissionType, Nassets)
for _,_asset in pairs(Assets) do
local asset=_asset --#AIRWING.SquadronAsset
-- Only unspawned payloads are returned.
if not asset.spawned then
if not asset.spawned and not asset.requested then
self:ReturnPayloadFromAsset(asset)
end
end
+30 -18
View File
@@ -62,6 +62,8 @@
-- @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 #number missionAltitude Mission altitude in meters.
--
-- @field #number optionROE ROE.
-- @field #number optionROT ROT.
-- @field #number optionCM Counter measures.
@@ -108,23 +110,23 @@ _AUFTRAGSNR=0
--- Mission types.
-- @type AUFTRAG.Type
-- @param #string ANTISHIP Anti-ship mission.
-- @param #string AWACS AWACS mission.
-- @param #string BAI Battlefield Air Interdiction.
-- @param #string BOMBING Bombing mission.
-- @param #string CAP Combat Air Patrol.
-- @param #string CAS Close Air Support.
-- @param #string ESCORT Escort mission.
-- @param #string FACA Forward AirController airborne mission.
-- @param #string FERRY Ferry flight mission.
-- @param #string INTERCEPT Intercept mission.
-- @param #string ORBIT Orbit mission.
-- @param #string PATROL Similar to CAP but no auto engage targets.
-- @param #string RECON Recon mission.
-- @param #string SEAD Suppression/destruction of enemy air defences.
-- @param #string STRIKE Strike mission.
-- @param #string TANKER Tanker mission.
-- @param #string TRANSPORT Transport mission.
-- @field #string ANTISHIP Anti-ship mission.
-- @field #string AWACS AWACS mission.
-- @field #string BAI Battlefield Air Interdiction.
-- @field #string BOMBING Bombing mission.
-- @field #string CAP Combat Air Patrol.
-- @field #string CAS Close Air Support.
-- @field #string ESCORT Escort mission.
-- @field #string FACA Forward AirController airborne mission.
-- @field #string FERRY Ferry flight mission.
-- @field #string INTERCEPT Intercept mission.
-- @field #string ORBIT Orbit mission.
-- @field #string PATROL Similar to CAP but no auto engage targets.
-- @field #string RECON Recon mission.
-- @field #string SEAD Suppression/destruction of enemy air defences.
-- @field #string STRIKE Strike mission.
-- @field #string TANKER Tanker mission.
-- @field #string TRANSPORT Transport mission.
AUFTRAG.Type={
ANTISHIP="Anti Ship",
AWACS="AWACS",
@@ -212,9 +214,10 @@ AUFTRAG.version="0.0.5"
-- TODO: Mission ROE and ROT
-- TODO: Mission formation, etc.
-- TODO: FSM events.
-- DONE: FSM events.
-- TODO: F10 marker functions that are updated on Status event.
-- TODO: Evaluate mission result ==> SUCCESS/FAILURE
-- TODO: NewAUTO() NewA2G NewA2A
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Constructor
@@ -542,6 +545,15 @@ function AUFTRAG:SetWeaponType(WeaponType)
return self
end
--- Set mission altitude.
-- @param #AUFTRAG self
-- @param #string Altitude Altitude in feet.
-- @return #AUFTRAG self
function AUFTRAG:SetMissionAltitude(Altitude)
self.missionAltitude=UTILS.FeetToMeters(Altitude)
return self
end
--- Set Rules of Engagement for this mission.
-- @param #AUFTRAG self
-- @param #number roe ROE
+8 -3
View File
@@ -2518,7 +2518,7 @@ end
-- @param #string Event Event.
-- @param #string To To state.
-- @param Wrapper.Airbase#AIRBASE airbase The airbase to hold at.
-- @param #number SpeedTo Speed used for traveling from current position to holding point in knots. Default 350 kts.
-- @param #number SpeedTo Speed used for traveling from current position to holding point in knots. Default 75% of max speed.
-- @param #number SpeedHold Holding speed in knots. Default 250 kts.
-- @param #number SpeedLand Landing speed in knots. Default 170 kts.
function FLIGHTGROUP:onafterRTB(From, Event, To, airbase, SpeedTo, SpeedHold, SpeedLand)
@@ -2526,7 +2526,7 @@ function FLIGHTGROUP:onafterRTB(From, Event, To, airbase, SpeedTo, SpeedHold, Sp
self:I(self.lid..string.format("RTB: event=%s: %s --> %s", Event, From, To))
-- Defaults:
SpeedTo=SpeedTo or 350
SpeedTo=SpeedTo or UTILS.KmphToKnots(self.speedmax*0.75)
SpeedHold=SpeedHold or 250
SpeedLand=SpeedLand or 170
@@ -3324,8 +3324,13 @@ function FLIGHTGROUP:RouteToMission(mission, delay)
-- Create waypoint coordinate half way between us and the target.
local targetcoord=mission:GetTargetCoordinate()
local flightcoord=self.group:GetCoordinate()
local flightcoord=self.group:GetCoordinate()
local waypointcoord=flightcoord:GetIntermediateCoordinate(targetcoord, 0.5)
-- Set altitude of mission waypoint.
if mission.missionAltitude then
waypointcoord.y=mission.missionAltitude
end
-- Add waypoint.
self:AddWaypointAir(waypointcoord, nextwaypoint, self.speedmax*0.8, false)
+60 -12
View File
@@ -17,7 +17,7 @@
-- @field #boolean Debug Debug mode. Messages to all about status.
-- @field #string lid Class id string for output to DCS log file.
-- @field #number coalition Coalition side number, e.g. coalition.side.RED.
-- @field #table filter Category filters.
-- @field #table filterCategory Category filters.
-- @field Core.Set#SET_ZONE acceptzoneset Set of accept zones. If defined, only contacts in these zones are considered.
-- @field Core.Set#SET_ZONE rejectzoneset Set of reject zones. Contacts in these zones are not considered.
-- @field #table Contacts Table of detected items.
@@ -41,7 +41,7 @@ INTEL = {
ClassName = "INTEL",
Debug = nil,
lid = nil,
filter = nil,
filterCategory = {},
detectionset = nil,
Contacts = {},
ContactsLost = {},
@@ -202,6 +202,32 @@ function INTEL:SetForgetTime(TimeInterval)
return self
end
--- Filter group categories. Valid categories are:
--
-- * Group.Category.AIRPLANE
-- * Group.Category.HELICOPTER
-- * Group.Category.GROUND
-- * Group.Category.SHIP
-- * Group.Category.TRAIN
--
-- @param #INTEL self
-- @param #table Categories Filter categories, e.g. {Group.Category.AIRPLANE, Group.Category.HELICOPTER}.
-- @return #INTEL self
function INTEL:SetFilterCategory(Categories)
if type(Categories)~="table" then
Categories={Categories}
end
self.filterCategory=Categories
local text="Filter categories: "
for _,category in pairs(self.filterCategory) do
text=text..string.format("%d,", category)
end
self:I(self.lid..text)
return self
end
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Start & Status
@@ -294,22 +320,44 @@ function INTEL:UpdateIntel()
local unit=_unit --Wrapper.Unit#UNIT
-- Check if unit is in any of the accept zones.
local inzone=false
for _,_zone in pairs(self.acceptzoneset.Set) do
local zone=_zone --Core.Zone#ZONE
if unit:IsInZone(zone) then
inzone=true
break
if self.acceptzoneset:Count()>0 then
local inzone=false
for _,_zone in pairs(self.acceptzoneset.Set) do
local zone=_zone --Core.Zone#ZONE
if unit:IsInZone(zone) then
inzone=true
break
end
end
-- Unit is not in accept zone ==> remove!
if not inzone then
table.insert(remove, unit:GetName())
end
end
-- Unit is not in accept zone ==> remove!
if not inzone then
table.insert(remove, unit:GetName())
end
-- Filter unit categories.
if #self.filterCategory>0 then
local unitcategory=unit:GetCategory()
local keepit=false
for _,filtercategory in pairs(self.filterCategory) do
if unitcategory==filtercategory then
keepit=true
break
end
end
if not keepit then
self:I(self.lid..string.format("Removing unit %s category=%d", unit:GetName(), unit:GetCategory()))
table.insert(remove, unit:GetName())
end
end
end
-- Remove filtered units.
for _,unitname in pairs(remove) do
DetectedSet:Remove(unitname, true)
end
--DetectedSet:RemoveUnitsByName(remove)
-- Create detected contacts.
+14
View File
@@ -756,6 +756,20 @@ function UNIT:GetDamageRelative()
return 1
end
--- Returns the category of the #UNIT.
-- @param #UNIT self
-- @return #number Unit category.
function UNIT:GetCategory()
self:F3( self.UnitName )
local DCSUnit = self:GetDCSObject()
if DCSUnit then
return DCSUnit:getDesc().category
end
return nil
end
--- Returns the category name of the #UNIT.
-- @param #UNIT self
-- @return #string Category name = Helicopter, Airplane, Ground Unit, Ship