This commit is contained in:
Frank
2020-03-20 01:00:45 +01:00
parent 1371445e94
commit 4991fc9cb4
8 changed files with 574 additions and 226 deletions
@@ -1773,7 +1773,7 @@ WAREHOUSE.version="1.0.0"
-- TODO: Add check if assets "on the move" are stationary. Can happen if ground units get stuck in buildings. If stationary auto complete transport by adding assets to request warehouse? Time? -- TODO: Add check if assets "on the move" are stationary. Can happen if ground units get stuck in buildings. If stationary auto complete transport by adding assets to request warehouse? Time?
-- TODO: Optimize findpathonroad. Do it only once (first time) and safe paths between warehouses similar to off-road paths. -- TODO: Optimize findpathonroad. Do it only once (first time) and safe paths between warehouses similar to off-road paths.
-- TODO: Spawn assets only virtually, i.e. remove requested assets from stock but do NOT spawn them ==> Interface to A2A dispatcher! Maybe do a negative sign on asset number? -- NOGO: Spawn assets only virtually, i.e. remove requested assets from stock but do NOT spawn them ==> Interface to A2A dispatcher! Maybe do a negative sign on asset number?
-- TODO: Make more examples: ARTY, CAP, ... -- TODO: Make more examples: ARTY, CAP, ...
-- TODO: Check also general requests like all ground. Is this a problem for self propelled if immobile units are among the assets? Check if transport. -- TODO: Check also general requests like all ground. Is this a problem for self propelled if immobile units are among the assets? Check if transport.
-- TODO: Handle the case when units of a group die during the transfer. -- TODO: Handle the case when units of a group die during the transfer.
@@ -2594,6 +2594,9 @@ end
-- @param #table ParkingIDs Table of numbers. -- @param #table ParkingIDs Table of numbers.
-- @return #WAREHOUSE self -- @return #WAREHOUSE self
function WAREHOUSE:SetParkingIDs(ParkingIDs) function WAREHOUSE:SetParkingIDs(ParkingIDs)
if type(ParkingIDs)~="table" then
ParkingIDs={ParkingIDs}
end
self.parkingIDs=ParkingIDs self.parkingIDs=ParkingIDs
return self return self
end end
@@ -5168,7 +5171,14 @@ function WAREHOUSE:onafterDestroyed(From, Event, To)
for k,_ in pairs(self.queue) do for k,_ in pairs(self.queue) do
self.queue[k]=nil self.queue[k]=nil
end end
for k,_ in pairs(self.stock) do for k,_ in pairs(self.stock) do
--self.stock[k]=nil
end
for k=#self.stock,1,-1 do
--local asset=self.stock[k] --#WAREHOUSE.Assetitem
--self:AssetDead(asset, nil)
self.stock[k]=nil self.stock[k]=nil
end end
+48 -3
View File
@@ -482,13 +482,34 @@ end
-- @return #AIRWING self -- @return #AIRWING self
function AIRWING:AddPatrolPointCAP(Coordinate, Heading, LegLength, Altitude, Speed) function AIRWING:AddPatrolPointCAP(Coordinate, Heading, LegLength, Altitude, Speed)
local cappoint=self:NewPatrolPoint(Coordinate, Heading, LegLength, Speed, Altitude, LegLength) local cappoint=self:NewPatrolPoint(Coordinate, Heading, LegLength, Altitude, Speed)
cappoint.coord:MarkToAll(string.format("CAP Point alt=%d", cappoint.altitude))
table.insert(self.pointsCAP, cappoint) table.insert(self.pointsCAP, cappoint)
return self return self
end end
--- Add a patrol Point for TANKER missions.
-- @param #AIRWING self
-- @param Core.Point#COORDINATE Coordinate Coordinate of the patrol point.
-- @param #number Heading Heading in degrees.
-- @param #number LegLength Length of race-track orbit in NM.
-- @param #number Altitude Orbit altitude in feet.
-- @param #number Speed Orbit speed in knots.
-- @return #AIRWING self
function AIRWING:AddPatrolPointTANKER(Coordinate, Heading, LegLength, Altitude, Speed)
local cappoint=self:NewPatrolPoint(Coordinate, Heading, LegLength, Altitude, Speed)
cappoint.coord:MarkToAll(string.format("Tanker Point alt=%d", cappoint.altitude))
table.insert(self.pointsTANKER, cappoint)
return self
end
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Start & Status -- Start & Status
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
@@ -583,10 +604,13 @@ function AIRWING:onafterStatus(From, Event, To)
local payload=asset.payload and table.concat(asset.payload.missiontypes, ", ") or "None" local payload=asset.payload and table.concat(asset.payload.missiontypes, ", ") or "None"
text=text.." payload="..payload text=text.." payload="..payload
text=text.." flight=" text=text..", flight: "
if asset.flightgroup and asset.flightgroup:IsAlive() then if asset.flightgroup and asset.flightgroup:IsAlive() then
local status=asset.flightgroup:GetState() local status=asset.flightgroup:GetState()
local fuel=asset.flightgroup:IsFuelLow() local fuelmin=asset.flightgroup:GetFuelMin()
local fuellow=asset.flightgroup:IsFuelLow()
text=text..string.format("%s fuel=%d (low=%s)", status, fuelmin, tostring(fuellow))
else else
text=text.."N/A" text=text.."N/A"
end end
@@ -1123,6 +1147,27 @@ function AIRWING:onafterAssetDead(From, Event, To, asset, request)
-- Remove asset from squadron same -- Remove asset from squadron same
end end
--- On after "Destroyed" event. Remove assets from squadrons. Stop squadrons. Remove airwing from wingcommander.
-- @param #AIRWING self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
function AIRWING:onafterDestroyed(From, Event, To)
for _,_squadron in pairs(self.squadrons) do
local squadron=_squadron --Ops.Squadron#SQUADRON
for _,_asset in pairs(squadron.assets) do
local asset=_asset
squadron:DelAsset(asset)
end
squadron:Stop()
end
-- Call parent warehouse function first.
self:GetParent(self).onafterDestroyed(self, From, Event, To)
end
--- On after "Request" event. --- On after "Request" event.
-- @param #AIRWING self -- @param #AIRWING self
+186 -80
View File
@@ -31,18 +31,18 @@
-- @field #table DCStask DCS task structure. -- @field #table DCStask DCS task structure.
-- @field #number Ntargets Number of mission targets. -- @field #number Ntargets Number of mission targets.
-- --
-- @field Core.Point#COORDINATE waypointcoord Coordinate of the waypoint task.
--
-- @field Core.Point#COORDINATE orbitCoord Coordinate where to orbit. -- @field Core.Point#COORDINATE orbitCoord Coordinate where to orbit.
-- @field #number orbitSpeed Orbit speed in m/s. -- @field #number orbitSpeed Orbit speed in m/s.
-- @field #number orbitHeading Orbit heading in degrees. -- @field #number orbitHeading Orbit heading in degrees.
-- @field #number orbitLeg Length of orbit leg in meters. -- @field #number orbitLeg Length of orbit leg in meters.
-- --
-- @field Core.Zone#ZONE_RADIUS engageZone *Circular* engagement zone. -- @field #AUFTRAG.TargetData engageTarget Target data to engage.
-- @field #table engageTargetTypes Table of target types that are engaged in the engagement zone.
-- @field Core.Point#COORDINATE engageCoord Coordinate of target location. -- @field Core.Point#COORDINATE engageCoord Coordinate of target location.
-- @field Core.Set#SET_GROUP engageTargetGroupset Set of target groups to attack. -- @field Core.Set#SET_GROUP engageTargetGroupset Set of target groups to attack.
-- @field Core.Set#SET_UNIT engageTargetUnitset Set of target units to attack. -- @field Core.Set#SET_UNIT engageTargetUnitset Set of target units to attack.
--
-- @field Core.Zone#ZONE_RADIUS engageZone *Circular* engagement zone.
-- @field #table engageTargetTypes Table of target types that are engaged in the engagement zone.
-- @field #number engageAltitude Engagement altitude in meters. -- @field #number engageAltitude Engagement altitude in meters.
-- @field #number engageDirection Engagement direction in degrees. -- @field #number engageDirection Engagement direction in degrees.
-- @field #number engageQuantity Number of times a target is engaged. -- @field #number engageQuantity Number of times a target is engaged.
@@ -187,21 +187,41 @@ AUFTRAG.Status={
FAILED="failed", FAILED="failed",
} }
--- FlightStatus --- Flight status.
-- @type AUFTRAG.FlightStatus -- @type AUFTRAG.FlightStatus
-- @field #string SCHEDULED Mission is scheduled in a FLIGHGROUP queue waiting to be started. -- @field #string SCHEDULED Mission is scheduled in a FLIGHGROUP queue waiting to be started.
-- @field #string STARTED Flightgroup started this mission but it is not executed yet. -- @field #string STARTED Flightgroup started this mission but it is not executed yet.
-- @field #string EXECUTING Flightgroup is executing this mission. -- @field #string EXECUTING Flightgroup is executing this mission.
-- @field #string PAUSED Flightgroup has paused this mission, e.g. for refuelling.
-- @field #string DONE Mission task of the flightgroup is done. -- @field #string DONE Mission task of the flightgroup is done.
-- @field #string CANCELLED Mission was cancelled. -- @field #string CANCELLED Mission was cancelled.
AUFTRAG.FlightStatus={ AUFTRAG.FlightStatus={
SCHEDULED="scheduled", SCHEDULED="scheduled",
STARTED="started", STARTED="started",
EXECUTING="executing", EXECUTING="executing",
PAUSED="paused",
DONE="done", DONE="done",
CANCELLED="cancelled", CANCELLED="cancelled",
} }
---
-- @type AUFTRAG.TargetType
-- @field #string GROUP Group target.
-- @field #string UNIT Unit target.
-- @field #string STATIC Static target.
-- @field #string COORDINATE Target coordinates.
AUFTRAG.TargetType={
GROUP="Group",
UNIT="Unit",
STATIC="Static",
COORDINATE="Coordinate",
}
---
-- @type AUFTRAG.TargetData
-- @field Wrapper.Positionable#POSITIONABLE Target Target Object.
-- @field #string Type Target type: "Group", "Unit", "Static", "Vec2"
--- Mission success. --- Mission success.
-- @type AUFTRAG.Success -- @type AUFTRAG.Success
-- @field #string ENGAGED Target was engaged. -- @field #string ENGAGED Target was engaged.
@@ -329,6 +349,8 @@ function AUFTRAG:NewANTISHIP(TargetUnitSet)
mission.missionTask=ENUMS.MissionTask.ANTISHIPSTRIKE mission.missionTask=ENUMS.MissionTask.ANTISHIPSTRIKE
mission.optionROE=ENUMS.ROE.OpenFire
mission.DCStask=mission:GetDCSMissionTask() mission.DCStask=mission:GetDCSMissionTask()
return mission return mission
@@ -356,8 +378,8 @@ function AUFTRAG:NewORBIT(Coordinate, Speed, Heading, Leg, Altitude)
end end
auftrag.missionAltitude=auftrag.orbitCoord.y*0.9 auftrag.missionAltitude=auftrag.orbitCoord.y*0.9
auftrag.missionFraction=0.9 auftrag.missionFraction=0.9
auftrag.optionROE=ENUMS.ROE.ReturnFire
auftrag.DCStask=auftrag:GetDCSMissionTask() auftrag.DCStask=auftrag:GetDCSMissionTask()
@@ -400,10 +422,11 @@ function AUFTRAG:NewTANKER(OrbitCoordinate, OrbitSpeed, Heading, Leg, Altitude,
-- Mission type PATROL. -- Mission type PATROL.
mission.type=AUFTRAG.Type.TANKER mission.type=AUFTRAG.Type.TANKER
mission.missionTask=ENUMS.MissionTask.REFUELING
mission.refuelSystem=RefuelSystem mission.refuelSystem=RefuelSystem
mission.missionTask=ENUMS.MissionTask.REFUELING
mission.optionROE=ENUMS.ROE.WeaponHold
mission.DCStask=mission:GetDCSMissionTask() mission.DCStask=mission:GetDCSMissionTask()
return mission return mission
@@ -426,6 +449,7 @@ function AUFTRAG:NewAWACS(OrbitCoordinate, OrbitSpeed, Heading, Leg, Altitude)
mission.type=AUFTRAG.Type.AWACS mission.type=AUFTRAG.Type.AWACS
mission.missionTask=ENUMS.MissionTask.AWACS mission.missionTask=ENUMS.MissionTask.AWACS
mission.optionROE=ENUMS.ROE.WeaponHold
mission.DCStask=mission:GetDCSMissionTask() mission.DCStask=mission:GetDCSMissionTask()
@@ -436,18 +460,17 @@ end
--- Create an INTERCEPT mission. --- Create an INTERCEPT mission.
-- @param #AUFTRAG self -- @param #AUFTRAG self
-- @param Core.Set#SET_GROUP TargetGroupSet The set of target groups to intercept. Can also be passed as a simple @{Wrapper.Group#GROUP} object. -- @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 -- @return #AUFTRAG self
function AUFTRAG:NewINTERCEPT(TargetGroupSet) function AUFTRAG:NewINTERCEPT(Target)
if TargetGroupSet:IsInstanceOf("GROUP") then
TargetGroupSet=SET_GROUP:New():AddGroup(TargetGroupSet)
end
local mission=AUFTRAG:New(AUFTRAG.Type.INTERCEPT) local mission=AUFTRAG:New(AUFTRAG.Type.INTERCEPT)
mission.engageTargetGroupset=TargetGroupSet mission.engageTarget=self:_TargetFromObject(Target)
mission.engageTargetGroupset:FilterDeads():FilterCrashes()
mission.missionTask=ENUMS.MissionTask.INTERCEPT
mission.missionFraction=0.1
mission.optionROE=ENUMS.ROE.OpenFire
mission.DCStask=mission:GetDCSMissionTask() mission.DCStask=mission:GetDCSMissionTask()
@@ -480,9 +503,10 @@ function AUFTRAG:NewCAP(OrbitCoordinate, OrbitSpeed, Heading, Leg, ZoneCAP, Targ
mission.engageZone=ZoneCAP or ZONE_RADIUS:New("CAP Zone", OrbitCoordinate:GetVec2(), mission.orbitLeg) mission.engageZone=ZoneCAP or ZONE_RADIUS:New("CAP Zone", OrbitCoordinate:GetVec2(), mission.orbitLeg)
mission.engageTargetTypes=TargetTypes or {"Air"} mission.engageTargetTypes=TargetTypes or {"Air"}
mission.DCStask=mission:GetDCSMissionTask()
mission.missionTask=ENUMS.MissionTask.CAP mission.missionTask=ENUMS.MissionTask.CAP
mission.optionROE=ENUMS.ROE.WeaponFree
mission.DCStask=mission:GetDCSMissionTask()
return mission return mission
end end
@@ -513,46 +537,47 @@ function AUFTRAG:NewCAS(OrbitCoordinate, OrbitSpeed, Heading, Leg, ZoneCAS, Targ
mission.engageZone=ZoneCAS or ZONE_RADIUS:New("CAS Zone", OrbitCoordinate:GetVec2(), Leg) mission.engageZone=ZoneCAS or ZONE_RADIUS:New("CAS Zone", OrbitCoordinate:GetVec2(), Leg)
mission.engageTargetTypes=TargetTypes or {"Helicopters", "Ground Units", "Light armed ships"} mission.engageTargetTypes=TargetTypes or {"Helicopters", "Ground Units", "Light armed ships"}
mission.DCStask=mission:GetDCSMissionTask()
mission.missionTask=ENUMS.MissionTask.CAS mission.missionTask=ENUMS.MissionTask.CAS
mission.optionROE=ENUMS.ROE.WeaponFree
mission.DCStask=mission:GetDCSMissionTask()
return mission return mission
end end
--- Create a BAI mission. --- Create a BAI mission.
-- @param #AUFTRAG self -- @param #AUFTRAG self
-- @param Core.Set#SET_Unit TargetGroupSet The set of target groups to attack. Instead of a SET an ordinary GROUP object can also be given if only a single group needs to be attacked. -- @param Wrapper.Positionable#POSITIONABLE Target The target to attack. Can be a GROUP, UNIT or STATIC object.
-- @return #AUFTRAG self -- @return #AUFTRAG self
function AUFTRAG:NewBAI(TargetGroupSet) function AUFTRAG:NewBAI(Target)
if TargetGroupSet:IsInstanceOf("GROUP") then
TargetGroupSet=SET_GROUP:New():AddGroup(TargetGroupSet)
end
local mission=AUFTRAG:New(AUFTRAG.Type.BAI) local mission=AUFTRAG:New(AUFTRAG.Type.BAI)
mission.engageTargetUnitset=TargetGroupSet mission.engageTarget=self:_TargetFromObject(Target)
mission.engageTargetUnitset:FilterDeads()
mission.missionTask=ENUMS.MissionTask.GROUNDATTACK --mission.engageTargetUnitset=TargetGroupSet
--mission.engageTargetUnitset:FilterDeads()
mission.engageWeaponType=2956984318 mission.engageWeaponType=ENUMS.WeaponFlag.AnyAG --2956984318
mission.engageWeaponExpend=AI.Task.WeaponExpend.ALL mission.engageWeaponExpend=AI.Task.WeaponExpend.ALL
mission.engageAsGroup=true mission.engageAsGroup=true
mission.missionTask=ENUMS.MissionTask.GROUNDATTACK
mission.missionAltitude=nil
mission.missionFraction=0.75 mission.missionFraction=0.75
mission.optionROE=ENUMS.ROE.OpenFire
mission.DCStask=mission:GetDCSMissionTask() mission.DCStask=mission:GetDCSMissionTask()
return mission return mission
end end
--- Create a STRIKE mission. Flight will attack a specified coordinate. --- Create a STRIKE mission. Flight will attack the closest map object to the specified coordinate.
-- @param #AUFTRAG self -- @param #AUFTRAG self
-- @param Core.Point#COORDINATE TargetCoordinate Target coordinate. -- @param Core.Point#COORDINATE TargetCoordinate Target coordinate.
-- @param #number Altitude Engage altitude in feet. Default 1000. -- @param #number Altitude Engage altitude in feet. Default 1000 ft.
-- @return #AUFTRAG self -- @return #AUFTRAG self
function AUFTRAG:NewSTRIKE(TargetCoordinate, Altitude) function AUFTRAG:NewSTRIKE(TargetCoordinate, Altitude)
@@ -560,12 +585,13 @@ function AUFTRAG:NewSTRIKE(TargetCoordinate, Altitude)
mission.engageCoord=TargetCoordinate mission.engageCoord=TargetCoordinate
mission.engageAltitude=UTILS.FeetToMeters(Altitude or 1000) mission.engageAltitude=UTILS.FeetToMeters(Altitude or 1000)
mission.engageWeaponType=ENUMS.WeaponFlag.AnyAG --2956984318
mission.engageWeaponExpend=AI.Task.WeaponExpend.ALL
mission.missionTask=ENUMS.MissionTask.GROUNDATTACK mission.missionTask=ENUMS.MissionTask.GROUNDATTACK
mission.missionAltitude=mission.engageAltitude
mission.engageWeaponType=2956984318 mission.missionFraction=0.75
mission.engageWeaponExpend=AI.Task.WeaponExpend.ALL mission.optionROE=ENUMS.ROE.OpenFire
mission.DCStask=mission:GetDCSMissionTask() mission.DCStask=mission:GetDCSMissionTask()
@@ -581,30 +607,31 @@ function AUFTRAG:NewBOMBING(TargetCoordinate, Altitude)
local mission=AUFTRAG:New(AUFTRAG.Type.BOMBING) local mission=AUFTRAG:New(AUFTRAG.Type.BOMBING)
-- DCS task options:
mission.engageCoord=TargetCoordinate mission.engageCoord=TargetCoordinate
mission.engageAltitude=UTILS.FeetToMeters(Altitude or 25000) mission.engageAltitude=UTILS.FeetToMeters(Altitude or 25000)
mission.missionAltitude=mission.engageAltitude
mission.missionFraction=0.3
mission.engageWeaponType=4030478 --2956984318 --ENUMS.WeaponFlag.AnyBomb mission.engageWeaponType=4030478 --2956984318 --ENUMS.WeaponFlag.AnyBomb
mission.engageWeaponExpend=AI.Task.WeaponExpend.ALL mission.engageWeaponExpend=AI.Task.WeaponExpend.ALL
mission.DCStask=mission:GetDCSMissionTask() -- Mission options:
mission.missionTask=ENUMS.MissionTask.GROUNDATTACK mission.missionTask=ENUMS.MissionTask.GROUNDATTACK
mission.missionAltitude=mission.engageAltitude*0.8
mission.missionFraction=0.3
mission.optionROE=ENUMS.ROE.OpenFire
-- Get DCS task.
mission.DCStask=mission:GetDCSMissionTask()
return mission return mission
end end
--- Create an ESCORT mission. Flight will escort another group and automatically engage certain target types. --- Create an ESCORT (or FOLLOW) mission. Flight will escort another group and automatically engage certain target types.
-- @param #AUFTRAG self -- @param #AUFTRAG self
-- @param Wrapper.Group#GROUP EscortGroup The group to escort. -- @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=200, y=0, z=-100} for 200 meters to the right, same alitude, 100 meters behind. -- @param DCS#Vec3 OffsetVector A table with x, y and z components specifying the offset of the flight to the escorted group. Default {x=200, y=0, z=-100} for 200 meters to the right, same alitude, 100 meters behind.
-- @param #number EngageMaxDistance Max engage distance of targets in meters. Default auto (*nil*). -- @param #number EngageMaxDistance Max engage distance of targets in meters. Default auto (*nil*).
-- @param #table TargetTypes Types of targets to engage automatically. Default is {"Air"}, i.e. all enemy airborne units. Set to {} for a simple "FOLLOW" mission. -- @param #table TargetTypes Types of targets to engage automatically. Default is {"Air"}, i.e. all enemy airborne units. Use an empty set {} for a simple "FOLLOW" mission.
-- @return #AUFTRAG self -- @return #AUFTRAG self
function AUFTRAG:NewESCORT(EscortGroup, OffsetVector, EngageMaxDistance, TargetTypes) function AUFTRAG:NewESCORT(EscortGroup, OffsetVector, EngageMaxDistance, TargetTypes)
@@ -615,11 +642,13 @@ function AUFTRAG:NewESCORT(EscortGroup, OffsetVector, EngageMaxDistance, TargetT
mission.engageMaxDistance=EngageMaxDistance mission.engageMaxDistance=EngageMaxDistance
mission.engageTargetTypes=TargetTypes or {"Air"} mission.engageTargetTypes=TargetTypes or {"Air"}
mission.missionTask=ENUMS.MissionTask.ESCORT
mission.missionFraction=0.1 mission.missionFraction=0.1
mission.DCStask=mission:GetDCSMissionTask() -- TODO: what's the best ROE here?
mission.optionROE=ENUMS.ROE.OpenFire
mission.missionTask=ENUMS.MissionTask.ESCORT mission.DCStask=mission:GetDCSMissionTask()
return mission return mission
end end
@@ -667,6 +696,9 @@ function AUFTRAG:NewAUTO(EngageGroup)
--TODO: ANTISHIP --TODO: ANTISHIP
mission=AUFTRAG:NewANTISHIP(group)
--[[
local TargetUnitSet=SET_UNIT:New() local TargetUnitSet=SET_UNIT:New()
for _,_unit in pairs(group:GetUnits()) do for _,_unit in pairs(group:GetUnits()) do
@@ -679,6 +711,7 @@ function AUFTRAG:NewAUTO(EngageGroup)
if TargetUnitSet:Count()>0 then if TargetUnitSet:Count()>0 then
mission=AUFTRAG:NewANTISHIP(TargetUnitSet) mission=AUFTRAG:NewANTISHIP(TargetUnitSet)
end end
]]
end end
end end
@@ -1467,6 +1500,24 @@ end
function AUFTRAG:CountMissionTargets() function AUFTRAG:CountMissionTargets()
local N=0 local N=0
if self.engageTarget then
if self.engageTarget.Type==AUFTRAG.TargetType.GROUP then
local target=self.engageTarget.Target --Wrapper.Group#GROUP
N=N+target:CountAliveUnits()
elseif self.engageTarget.Type==AUFTRAG.TargetType.UNIT then
if self.engageTarget.Target and self.engageTarget.Target:IsAlive() then
N=N+1
end
elseif self.engageTarget.Type==AUFTRAG.TargetType.GROUP then
local target=self.engageTarget.Target --Wrapper.Static#STATIC
if target and target:IsAlive() then
N=N+1
end
end
end
--[[
if self.engageTargetGroupset then if self.engageTargetGroupset then
--local n=self.engageTargetGroupset:CountAlive() --local n=self.engageTargetGroupset:CountAlive()
@@ -1491,6 +1542,8 @@ function AUFTRAG:CountMissionTargets()
N=N+n N=N+n
end end
]]
return N return N
end end
@@ -1513,6 +1566,17 @@ end
-- @return Core.Point#COORDINATE The target coordinate or nil. -- @return Core.Point#COORDINATE The target coordinate or nil.
function AUFTRAG:GetTargetCoordinate() function AUFTRAG:GetTargetCoordinate()
if self.engageTarget then
return self.engageTarget.Target:GetCoordinate()
elseif self.engageCoord then
return self.engageCoord
elseif self.orbitCoord then
return self.orbitCoord
elseif self.escortGroup then
return self.escortGroup:GetCoordinate()
end
--[[
if self.engageTargetGroupset then if self.engageTargetGroupset then
local group=self.engageTargetGroupset:GetFirst() --Wrapper.Group#GROUP local group=self.engageTargetGroupset:GetFirst() --Wrapper.Group#GROUP
if group and group:IsAlive() then if group and group:IsAlive() then
@@ -1530,6 +1594,7 @@ function AUFTRAG:GetTargetCoordinate()
elseif self.escortGroup then elseif self.escortGroup then
return self.escortGroup:GetCoordinate() return self.escortGroup:GetCoordinate()
end end
]]
return nil return nil
end end
@@ -1573,15 +1638,9 @@ function AUFTRAG:GetDCSMissionTask()
-- ANTISHIP Mission -- -- ANTISHIP Mission --
---------------------- ----------------------
for _,_unit in pairs(self.engageTargetUnitset:GetSet()) do local DCStask=self:_GetDCSAttackTask(self.engageTarget)
local TargetUnit=_unit
local DCStask=CONTROLLABLE.TaskAttackUnit(nil, TargetUnit, self.engageAltitude, self.WeaponExpend, self.engageQuantity, self.engageDirection, self.engageAltitude, self.engageWeaponType) table.insert(DCStasks, DCStask)
local DCStask=CONTROLLABLE.TaskAttackUnit(self,AttackUnit,GroupAttack,WeaponExpend,AttackQty,Direction,Altitude,WeaponType)
table.insert(DCStasks, DCStask)
end
elseif self.type==AUFTRAG.Type.AWACS then elseif self.type==AUFTRAG.Type.AWACS then
@@ -1600,25 +1659,10 @@ function AUFTRAG:GetDCSMissionTask()
-- BAI Mission -- -- BAI Mission --
----------------- -----------------
--[[ -- TODO: adjust tasks for group/unit attack! group attack also seems to now support the attack as group value. however, statics are only possible if attackunit.
for _,_group in pairs(self.engageTargetGroupset:GetSet()) do local DCStask=self:_GetDCSAttackTask(self.engageTarget)
local TargetGroup=_group
local DCStask=CONTROLLABLE.TaskAttackGroup(nil, TargetGroup, self.engageWeaponType, self.engageWeaponExpend, self.engageQuantity, self.engageDirection, self.engageAltitude) table.insert(DCStasks, DCStask)
local DCSTask=
table.insert(DCStasks, DCStask)
end
]]
for _,_unit in pairs(self.engageTargetUnitset:GetSet()) do
local TargetUnit=_unit
local DCStask=CONTROLLABLE.TaskAttackUnit(self, TargetUnit, self.engageAsGroup, self.engageWeaponExpend, self.engageQuantity, self.engageDirection, self.engageAltitude, self.engageWeaponType)
table.insert(DCStasks, DCStask)
end
elseif self.type==AUFTRAG.Type.BOMBING then elseif self.type==AUFTRAG.Type.BOMBING then
@@ -1686,13 +1730,9 @@ function AUFTRAG:GetDCSMissionTask()
-- INTERCEPT Mission -- -- INTERCEPT Mission --
----------------------- -----------------------
for _,group in pairs(self.engageTargetGroupset:GetSet()) do local DCStask=self:_GetDCSAttackTask(self.engageTarget)
local TargetGroup=group --Wrapper.Group#GROUP
local DCStask=CONTROLLABLE.TaskAttackGroup(nil, TargetGroup, self.engageWeaponType, self.engageWeaponExpend, self.engageQuantity, self.engageDirection, self.engageAltitude) table.insert(DCStasks, DCStask)
table.insert(DCStasks, DCStask)
end
elseif self.type==AUFTRAG.Type.ORBIT then elseif self.type==AUFTRAG.Type.ORBIT then
@@ -1716,6 +1756,16 @@ function AUFTRAG:GetDCSMissionTask()
-- RECON Mission -- -- RECON Mission --
------------------- -------------------
elseif self.type==AUFTRAG.Type.SEAD then
------------------
-- SEAD Mission --
------------------
local DCStask=self:_GetDCSAttackTask(self.engageTarget)
table.insert(DCStasks, DCStask)
elseif self.type==AUFTRAG.Type.STRIKE then elseif self.type==AUFTRAG.Type.STRIKE then
------------------- -------------------
@@ -1785,6 +1835,62 @@ function AUFTRAG:GetDCSMissionTask()
end end
--- Get DCS task table for an attack task.
-- @param #AUFTRAG self
-- @param #AUFTRAG.TargetData target Target data.
-- @return DCS#Task The DCS task table.
function AUFTRAG:_GetDCSAttackTask(target)
local DCStask=nil
if target.Type==AUFTRAG.TargetType.GROUP then
DCStask=CONTROLLABLE.TaskAttackGroup(nil, target.Target, self.engageWeaponType, self.engageWeaponExpend, self.engageQuantity, self.engageDirection, self.engageAltitude, self.engageAsGroup)
elseif target.Type==AUFTRAG.TargetType.UNIT or target.Type==AUFTRAG.TargetType.STATIC then
DCStask=CONTROLLABLE.TaskAttackUnit(nil, target.Target, self.engageAsGroup, self.WeaponExpend, self.engageQuantity, self.engageDirection, self.engageAltitude, self.engageWeaponType)
end
return DCStask
end
--- Create target data from a given object.
-- @param #AUFTRAG self
-- @param Wrapper.Positionable#POSITIONABLE Object The target GROUP, UNIT, STATIC.
-- @return #AUFTRAG.TargetData Target.
function AUFTRAG:_TargetFromObject(Object)
local target={} --#AUFTRAG.TargetData
-- The object.
target.Target=Object
if Object:IsInstanceOf("GROUP") then
target.Type=AUFTRAG.TargetType.GROUP
elseif Object:IsInstanceOf("UNIT") then
target.Type=AUFTRAG.TargetType.UNIT
elseif Object:IsInstanceOf("STATIC") then
target.Type=AUFTRAG.TargetType.STATIC
elseif Object:IsInstanceOf("COORDINATE") then
target.Type=AUFTRAG.TargetType.COORDINATE
else
self:E(self.lid.."ERROR: Unknown object given as target. Needs to be a GROUP, UNIT, STATIC or COORDINATE")
return nil
end
return target
end
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+213 -106
View File
@@ -18,6 +18,7 @@
-- @type FLIGHTGROUP -- @type FLIGHTGROUP
-- @field #string ClassName Name of the class. -- @field #string ClassName Name of the class.
-- @field #boolean Debug Debug mode. Messages to all about status. -- @field #boolean Debug Debug mode. Messages to all about status.
-- @field #number verbose Verbosity level. 0=silent.
-- @field #string lid Class id string for output to DCS log file. -- @field #string lid Class id string for output to DCS log file.
-- @field #string groupname Name of flight group. -- @field #string groupname Name of flight group.
-- @field Wrapper.Group#GROUP group Flight group object. -- @field Wrapper.Group#GROUP group Flight group object.
@@ -72,10 +73,12 @@
-- @field #number CallsignNumber Call sign number. -- @field #number CallsignNumber Call sign number.
-- @field #boolean EPLRS If true, turn EPLRS data link on. -- @field #boolean EPLRS If true, turn EPLRS data link on.
-- --
-- @field #string ROEdefault Default ROE setting. -- @field #string optionROEdefault Default ROE setting.
-- @field #string ROTdefault Default ROT setting. -- @field #string optionROTdefault Default ROT setting.
-- @field #string ROEcurrent Current ROE setting. -- @field #string optionROEcurrent Current ROE setting.
-- @field #string ROTcurrent Current ROT setting. -- @field #string optionROTcurrent Current ROT setting.
--
-- @field Ops.Auftrag#AUFTRAG missionpaused Paused mission.
-- --
-- @extends Core.Fsm#FSM -- @extends Core.Fsm#FSM
@@ -166,6 +169,7 @@
FLIGHTGROUP = { FLIGHTGROUP = {
ClassName = "FLIGHTGROUP", ClassName = "FLIGHTGROUP",
Debug = false, Debug = false,
verbose = 0,
lid = nil, lid = nil,
groupname = nil, groupname = nil,
group = nil, group = nil,
@@ -351,7 +355,7 @@ FLIGHTGROUP.ROT={
--- FLIGHTGROUP class version. --- FLIGHTGROUP class version.
-- @field #string version -- @field #string version
FLIGHTGROUP.version="0.3.6" FLIGHTGROUP.version="0.3.7"
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO list -- TODO list
@@ -412,6 +416,8 @@ function FLIGHTGROUP:New(groupname, autostart)
-- Defaults -- Defaults
self:SetFuelLowThreshold() self:SetFuelLowThreshold()
self:SetFuelCriticalThreshold() self:SetFuelCriticalThreshold()
self:SetDefaultROE()
self:SetDefaultROT()
-- Add FSM transitions. -- Add FSM transitions.
@@ -463,6 +469,8 @@ function FLIGHTGROUP:New(groupname, autostart)
self:AddTransition("*", "MissionStart", "*") -- Mission is started. self:AddTransition("*", "MissionStart", "*") -- Mission is started.
self:AddTransition("*", "MissionExecute", "*") -- Mission execution began. self:AddTransition("*", "MissionExecute", "*") -- Mission execution began.
self:AddTransition("*", "MissionCancel", "*") -- Cancel current mission. self:AddTransition("*", "MissionCancel", "*") -- Cancel current mission.
self:AddTransition("*", "PauseMission", "*") -- Pause the current mission.
self:AddTransition("*", "UnpauseMission", "*") -- Unpause the the paused mission.
self:AddTransition("*", "MissionDone", "*") -- Mission is over. self:AddTransition("*", "MissionDone", "*") -- Mission is over.
self:AddTransition("Airborne", "EngageTargets", "Engaging") -- Engage targets. self:AddTransition("Airborne", "EngageTargets", "Engaging") -- Engage targets.
@@ -581,16 +589,16 @@ function FLIGHTGROUP:AddTask(task, clock, description, prio, duration)
-- Task data structure. -- Task data structure.
local newtask={} --#FLIGHTGROUP.Task local newtask={} --#FLIGHTGROUP.Task
newtask.description=description
newtask.status=FLIGHTGROUP.TaskStatus.SCHEDULED newtask.status=FLIGHTGROUP.TaskStatus.SCHEDULED
newtask.dcstask=task newtask.dcstask=task
newtask.description=description or task.id
newtask.prio=prio or 50 newtask.prio=prio or 50
newtask.time=time newtask.time=time
newtask.id=self.taskcounter newtask.id=self.taskcounter
newtask.duration=duration newtask.duration=duration
newtask.waypoint=-1 newtask.waypoint=-1
newtask.type=FLIGHTGROUP.TaskType.SCHEDULED newtask.type=FLIGHTGROUP.TaskType.SCHEDULED
newtask.stopflag=USERFLAG:New(string.format("StopTaskFlag %d", newtask.id)) newtask.stopflag=USERFLAG:New(string.format("%s StopTaskFlag %d", self.groupname, newtask.id))
newtask.stopflag:Set(0) newtask.stopflag:Set(0)
-- Add to table. -- Add to table.
@@ -627,7 +635,7 @@ function FLIGHTGROUP:AddTaskWaypoint(task, waypointindex, description, prio, dur
newtask.time=0 newtask.time=0
newtask.waypoint=waypointindex or (self.currentwp and self.currentwp+1 or 2) newtask.waypoint=waypointindex or (self.currentwp and self.currentwp+1 or 2)
newtask.type=FLIGHTGROUP.TaskType.WAYPOINT newtask.type=FLIGHTGROUP.TaskType.WAYPOINT
newtask.stopflag=USERFLAG:New(string.format("StopTaskFlag %d", newtask.id)) newtask.stopflag=USERFLAG:New(string.format("%s StopTaskFlag %d", self.groupname, newtask.id))
newtask.stopflag:Set(0) newtask.stopflag:Set(0)
-- Add to table. -- Add to table.
@@ -976,11 +984,11 @@ function FLIGHTGROUP:IsHolding()
return self:Is("Holding") return self:Is("Holding")
end end
--- Check if flight is refueling. --- Check if flight is going for fuel.
-- @param #FLIGHTGROUP self -- @param #FLIGHTGROUP self
-- @return #boolean If true, flight is refueling. -- @return #boolean If true, flight is refueling.
function FLIGHTGROUP:IsRefueling() function FLIGHTGROUP:IsGoing4Fuel()
return self:Is("Refueling") return self:Is("Going4Fuel")
end end
--- Check if helo(!) flight is ordered to land at a specific point. --- Check if helo(!) flight is ordered to land at a specific point.
@@ -1045,10 +1053,10 @@ function FLIGHTGROUP:Activate(delay)
if self:IsAlive()==false then if self:IsAlive()==false then
if delay then if delay then
self:I(self.lid..string.format("Activating late activated group in %d seconds", delay)) self:T2(self.lid..string.format("Activating late activated group in %d seconds", delay))
self:ScheduleOnce(delay, FLIGHTGROUP.Activate, self) self:ScheduleOnce(delay, FLIGHTGROUP.Activate, self)
else else
self:I(self.lid.."Activating late activated group") self:T(self.lid.."Activating late activated group")
self.group:Activate() self.group:Activate()
end end
else else
@@ -1066,7 +1074,7 @@ function FLIGHTGROUP:StartUncontrolled(delay)
if self:IsAlive() then if self:IsAlive() then
--TODO: check Alive==true and Alive==false ==> Activate first --TODO: check Alive==true and Alive==false ==> Activate first
self:I(self.lid.."Starting uncontrolled group") self:T(self.lid.."Starting uncontrolled group")
self.group:StartUncontrolled(delay) self.group:StartUncontrolled(delay)
else else
self:E(self.lid.."ERROR: Could not start uncontrolled group as it is NOT alive (yet)!") self:E(self.lid.."ERROR: Could not start uncontrolled group as it is NOT alive (yet)!")
@@ -1081,7 +1089,25 @@ end
-- @return #FLIGHTGROUP self -- @return #FLIGHTGROUP self
function FLIGHTGROUP:SetTask(DCSTask) function FLIGHTGROUP:SetTask(DCSTask)
if self:IsAlive() then if self:IsAlive() then
self.group:SetTask(DCSTask, 1)
-- Inject enroute tasks.
if self.taskenroute and #self.taskenroute>0 then
if tostring(DCSTask.id)=="ComboTask" then
for _,task in pairs(self.taskenroute) do
table.insert(DCSTask.params.tasks, 1, task)
end
else
local tasks=UTILS.DeepCopy(self.taskenroute)
table.insert(tasks, DCSTask)
DCSTask=self.group.TaskCombo(self, tasks)
end
end
-- Set task
self.group:SetTask(DCSTask)
-- Debug info.
local text=string.format("SETTING Task %s", tostring(DCSTask.id)) local text=string.format("SETTING Task %s", tostring(DCSTask.id))
if tostring(DCSTask.id)=="ComboTask" then if tostring(DCSTask.id)=="ComboTask" then
for i,task in pairs(DCSTask.params.tasks) do for i,task in pairs(DCSTask.params.tasks) do
@@ -1138,7 +1164,7 @@ function FLIGHTGROUP:Route(waypoints)
-- Enroute tasks. -- Enroute tasks.
if self.taskenroute then if self.taskenroute then
for _,TaskEnroute in pairs(self.taskenroute) do for _,TaskEnroute in pairs(self.taskenroute) do
table.insert(Tasks, TaskEnroute) --table.insert(Tasks, TaskEnroute)
end end
end end
@@ -1227,7 +1253,7 @@ function FLIGHTGROUP:onafterStart(From, Event, To)
if group:IsAlive() then if group:IsAlive() then
-- Debug info. -- Debug info.
self:I(self.lid..string.format("Found EXISTING and ALIVE group %s at start with %d/%d units/elements", group:GetName(), #units, #self.elements)) self:T(self.lid..string.format("Found EXISTING and ALIVE group %s at start with %d/%d units/elements", group:GetName(), #units, #self.elements))
-- Trigger spawned event for all elements. -- Trigger spawned event for all elements.
for _,element in pairs(self.elements) do for _,element in pairs(self.elements) do
@@ -1237,7 +1263,7 @@ function FLIGHTGROUP:onafterStart(From, Event, To)
else else
-- Debug info. -- Debug info.
self:I(self.lid..string.format("Found EXISTING but LATE ACTIVATED group %s at start with %d/%d units/elements", group:GetName(), #units, #self.elements)) self:T(self.lid..string.format("Found EXISTING but LATE ACTIVATED group %s at start with %d/%d units/elements", group:GetName(), #units, #self.elements))
end end
end end
@@ -1343,7 +1369,9 @@ function FLIGHTGROUP:onafterFlightStatus(From, Event, To)
local text=string.format("Status %s [%d/%d]: Tasks=%d (%d,%d) Current=%d. Missions=%s. Waypoint=%d/%d. Detected=%d. Destination=%s, FC=%s", local text=string.format("Status %s [%d/%d]: Tasks=%d (%d,%d) Current=%d. Missions=%s. Waypoint=%d/%d. Detected=%d. Destination=%s, FC=%s",
fsmstate, #self.elements, #self.elements, nTaskTot, nTaskSched, nTaskWP, self.taskcurrent, nMissions, self.currentwp or 0, self.waypoints and #self.waypoints or 0, fsmstate, #self.elements, #self.elements, nTaskTot, nTaskSched, nTaskWP, self.taskcurrent, nMissions, self.currentwp or 0, self.waypoints and #self.waypoints or 0,
self.detectedunits:Count(), self.destbase and self.destbase:GetName() or "unknown", self.flightcontrol and self.flightcontrol.airbasename or "none") self.detectedunits:Count(), self.destbase and self.destbase:GetName() or "unknown", self.flightcontrol and self.flightcontrol.airbasename or "none")
self:I(self.lid..text) if self.verbose>0 then
self:I(self.lid..text)
end
-- Element status. -- Element status.
text="Elements:" text="Elements:"
@@ -1374,7 +1402,9 @@ function FLIGHTGROUP:onafterFlightStatus(From, Event, To)
if #self.elements==0 then if #self.elements==0 then
text=text.." none!" text=text.." none!"
end end
self:I(self.lid..text) if self.verbose>1 then
self:I(self.lid..text)
end
--- ---
-- Tasks -- Tasks
@@ -1408,7 +1438,7 @@ function FLIGHTGROUP:onafterFlightStatus(From, Event, To)
text=text..string.format("\n[%d] %s (%s): status=%s, waypoint=%d, started=%s, duration=%d, stopflag=%d", i, taskid, name, status, task.waypoint, started, duration, task.stopflag:Get()) text=text..string.format("\n[%d] %s (%s): status=%s, waypoint=%d, started=%s, duration=%d, stopflag=%d", i, taskid, name, status, task.waypoint, started, duration, task.stopflag:Get())
end end
end end
if #self.taskqueue>0 then if #self.taskqueue>0 and self.verbose>1 then
self:I(self.lid..text) self:I(self.lid..text)
end end
@@ -1418,10 +1448,9 @@ function FLIGHTGROUP:onafterFlightStatus(From, Event, To)
-- Current mission name. -- Current mission name.
local Mission=self:GetMissionByID(self.currentmission) local Mission=self:GetMissionByID(self.currentmission)
local mymission=Mission and Mission.name or "none"
-- Current status. -- Current status.
local text=string.format("Missions %d, Current: %s", self:CountRemainingMissison(), mymission) local text=string.format("Missions %d, Current: %s", self:CountRemainingMissison(), Mission and Mission.name or "none")
for i,_mission in pairs(self.missionqueue) do for i,_mission in pairs(self.missionqueue) do
local mission=_mission --Ops.Auftrag#AUFTRAG local mission=_mission --Ops.Auftrag#AUFTRAG
local Cstart= UTILS.SecondsToClock(mission.Tstart, true) local Cstart= UTILS.SecondsToClock(mission.Tstart, true)
@@ -1429,7 +1458,9 @@ function FLIGHTGROUP:onafterFlightStatus(From, Event, To)
text=text..string.format("\n[%d] %s (%s) status=%s (%s), Time=%s-%s, prio=%d targets=%d", text=text..string.format("\n[%d] %s (%s) status=%s (%s), Time=%s-%s, prio=%d targets=%d",
i, tostring(mission.name), mission.type, mission:GetFlightStatus(self), tostring(mission.status), Cstart, Cstop, mission.prio, mission:CountMissionTargets()) i, tostring(mission.name), mission.type, mission:GetFlightStatus(self), tostring(mission.status), Cstart, Cstop, mission.prio, mission:CountMissionTargets())
end end
self:I(self.lid..text) if self.verbose>0 then
self:I(self.lid..text)
end
--- ---
-- Fuel State -- Fuel State
@@ -1779,7 +1810,7 @@ function FLIGHTGROUP:OnEventEngineShutdown(EventData)
else else
self:T2(self.lid..string.format("EVENT: Element %s shut down engines but is NOT alive ==> waiting for crash event (==> dead)", element.name)) self:I(self.lid..string.format("EVENT: Element %s shut down engines but is NOT alive ==> waiting for crash event (==> dead)", element.name))
end end
@@ -1931,7 +1962,7 @@ function FLIGHTGROUP:onafterElementTaxiing(From, Event, To, Element)
end end
-- Debug info. -- Debug info.
self:I(self.lid..string.format("Element taxiing %s. Parking spot %s is now free", Element.name, TerminalID)) self:T(self.lid..string.format("Element taxiing %s. Parking spot %s is now free", Element.name, TerminalID))
-- Not parking any more. -- Not parking any more.
Element.parking=nil Element.parking=nil
@@ -1993,7 +2024,7 @@ end
-- @param Wrapper.Airbase#AIRBASE airbase The airbase, where the element arrived. -- @param Wrapper.Airbase#AIRBASE airbase The airbase, where the element arrived.
-- @param Wrapper.Airbase#AIRBASE.ParkingSpot Parking The Parking spot the element has. -- @param Wrapper.Airbase#AIRBASE.ParkingSpot Parking The Parking spot the element has.
function FLIGHTGROUP:onafterElementArrived(From, Event, To, Element, airbase, Parking) function FLIGHTGROUP:onafterElementArrived(From, Event, To, Element, airbase, Parking)
self:I(self.lid..string.format("Element arrived %s at %s airbase using parking spot %d", Element.name, airbase and airbase:GetName() or "unknown", Parking and Parking.TerminalID or -99)) self:T(self.lid..string.format("Element arrived %s at %s airbase using parking spot %d", Element.name, airbase and airbase:GetName() or "unknown", Parking and Parking.TerminalID or -99))
-- Get parking spot -- Get parking spot
@@ -2005,7 +2036,7 @@ function FLIGHTGROUP:onafterElementArrived(From, Event, To, Element, airbase, Pa
if Parking then if Parking then
if self.flightcontrol then if self.flightcontrol then
local spot=self.flightcontrol.parking[Parking.TerminalID] --Wrapper.Airbase#AIRBASE.ParkingSpot local spot=self.flightcontrol.parking[Parking.TerminalID] --Wrapper.Airbase#AIRBASE.ParkingSpot
self:I(self.lid..string.format("Element arrived %s at %s on parking spot %s reserved for %s", Element.name, Parking.AirbaseName, Parking.TerminalID, tostring(spot.Reserved))) self:T(self.lid..string.format("Element arrived %s at %s on parking spot %s reserved for %s", Element.name, Parking.AirbaseName, Parking.TerminalID, tostring(spot.Reserved)))
if spot.Reserved then if spot.Reserved then
if spot.Reserved==Element.name then if spot.Reserved==Element.name then
spot.Reserved=nil spot.Reserved=nil
@@ -2027,7 +2058,7 @@ end
-- @param #string To To state. -- @param #string To To state.
-- @param #FLIGHTGROUP.Element Element The flight group element. -- @param #FLIGHTGROUP.Element Element The flight group element.
function FLIGHTGROUP:onafterElementDead(From, Event, To, Element) function FLIGHTGROUP:onafterElementDead(From, Event, To, Element)
self:I(self.lid..string.format("Element dead %s.", Element.name)) self:T(self.lid..string.format("Element dead %s.", Element.name))
-- Not parking any more. -- Not parking any more.
Element.parking=nil Element.parking=nil
@@ -2046,9 +2077,18 @@ end
function FLIGHTGROUP:onafterFlightSpawned(From, Event, To) function FLIGHTGROUP:onafterFlightSpawned(From, Event, To)
self:T(self.lid..string.format("Flight spawned!")) self:T(self.lid..string.format("Flight spawned!"))
-- F10 menu. -- F10 menu.
if self.ai then if self.ai then
-- Set default options.
self:SetOptionROE()
self:SetOptionROT()
self.group:SetOption(AI.Option.Air.id.PROHIBIT_JETT, true)
self.group:SetOption(AI.Option.Air.id.PROHIBIT_AB, true)
self.group:SetOption(AI.Option.Air.id.RTB_ON_BINGO, false)
--self.group:SetOption(AI.Option.Air.id.RADAR_USING, AI.Option.Air.val.RADAR_USING.FOR_CONTINUOUS_SEARCH)
@@ -2345,7 +2385,7 @@ function FLIGHTGROUP:onafterUpdateRoute(From, Event, To, n)
-- Debug info. -- Debug info.
local hb=self.homebase and self.homebase:GetName() or "unknown" local hb=self.homebase and self.homebase:GetName() or "unknown"
local db=self.destbase and self.destbase:GetName() or "unknown" local db=self.destbase and self.destbase:GetName() or "unknown"
self:I(self.lid..string.format("Updating route for WP #%d-%d homebase=%s destination=%s", n, #wp, hb, db)) self:T(self.lid..string.format("Updating route for WP #%d-%d homebase=%s destination=%s", n, #wp, hb, db))
if #wp>1 then if #wp>1 then
@@ -2373,7 +2413,7 @@ end
-- @param #table Template The template used to respawn the group. -- @param #table Template The template used to respawn the group.
function FLIGHTGROUP:onafterRespawn(From, Event, To, Template) function FLIGHTGROUP:onafterRespawn(From, Event, To, Template)
self:I(self.lid.."Respawning group!") self:T(self.lid.."Respawning group!")
local template=UTILS.DeepCopy(Template or self.template) local template=UTILS.DeepCopy(Template or self.template)
@@ -2394,7 +2434,7 @@ end
-- @param #number N Final waypoint number. -- @param #number N Final waypoint number.
function FLIGHTGROUP:onafterPassingWaypoint(From, Event, To, n, N) function FLIGHTGROUP:onafterPassingWaypoint(From, Event, To, n, N)
local text=string.format("Flight passed waypoint %d/%d", n, N) local text=string.format("Flight passed waypoint %d/%d", n, N)
self:I(self.lid..text) self:T(self.lid..text)
MESSAGE:New(text, 30, "DEBUG"):ToAllIf(self.Debug) MESSAGE:New(text, 30, "DEBUG"):ToAllIf(self.Debug)
-- Get all waypoint tasks. -- Get all waypoint tasks.
@@ -2437,7 +2477,8 @@ function FLIGHTGROUP:onafterPassingWaypoint(From, Event, To, n, N)
-- Execute waypoint tasks. -- Execute waypoint tasks.
if #taskswp>0 then if #taskswp>0 then
self:PushTask(self.group:TaskCombo(taskswp)) --self:PushTask(self.group:TaskCombo(taskswp))
self:SetTask(self.group:TaskCombo(taskswp))
end end
-- Final AIR waypoint reached? -- Final AIR waypoint reached?
@@ -2613,7 +2654,7 @@ function FLIGHTGROUP:onafterRTB(From, Event, To, airbase, SpeedTo, SpeedHold, Sp
-- Debug message. -- Debug message.
local text=string.format("Flight group set to hold at airbase %s. SpeedTo=%d, SpeedHold=%d, SpeedLand=%d", airbase:GetName(), SpeedTo, SpeedHold, SpeedLand) local text=string.format("Flight group set to hold at airbase %s. SpeedTo=%d, SpeedHold=%d, SpeedLand=%d", airbase:GetName(), SpeedTo, SpeedHold, SpeedLand)
MESSAGE:New(text, 10, "DEBUG"):ToAllIf(self.Debug) MESSAGE:New(text, 10, "DEBUG"):ToAllIf(self.Debug)
self:I(self.lid..text) self:T(self.lid..text)
-- Holding points. -- Holding points.
@@ -2762,7 +2803,7 @@ function FLIGHTGROUP:onafterWait(From, Event, To, Coord, Altitude, Speed)
-- Debug message. -- Debug message.
local text=string.format("Flight group set to wait/orbit at altitude %d m and speed %.1f km/h", Altitude, Speed) local text=string.format("Flight group set to wait/orbit at altitude %d m and speed %.1f km/h", Altitude, Speed)
MESSAGE:New(text, 30, "DEBUG"):ToAllIf(self.Debug) MESSAGE:New(text, 30, "DEBUG"):ToAllIf(self.Debug)
self:I(self.lid..text) self:T(self.lid..text)
--TODO: set ROE passive. introduce roe event/state/variable. --TODO: set ROE passive. introduce roe event/state/variable.
@@ -2791,25 +2832,24 @@ function FLIGHTGROUP:onafterRefuel(From, Event, To, Coordinate)
--TODO: cancel current task --TODO: cancel current task
self:PauseMission()
-- Orbit task. -- Refueling task.
local TaskRefuel=self.group:TaskRefueling() local TaskRefuel=self.group:TaskRefueling()
local TaskFunction=self.group:TaskFunction("FLIGHTGROUP._FinishedRefuelling", self) local TaskFunction=self.group:TaskFunction("FLIGHTGROUP._FinishedRefuelling", self)
local DCSTasks={TaskRefuel, TaskFunction} local DCSTasks={TaskRefuel, TaskFunction}
local Speed=UTILS.KnotsToKmph(500) local Speed=UTILS.KnotsToKmph(300)
local wp0=self.group:GetCoordinate():WaypointAir("BARO", COORDINATE.WaypointType.TurningPoint, COORINATE.WaypointAction.TurningPoint, Speed, true) local coordinate=self.group:GetCoordinate()
local wp9=Coordinate:WaypointAir("BARO", COORDINATE.WaypointType.TurningPoint, COORINATE.WaypointAction.TurningPoint, Speed, true, nil, DCSTasks, "Refuel")
--local TaskCombo=self.group:TaskCombo({TaskFunction, TaskRefuel, TaskFunction}) Coordinate=Coordinate or coordinate:Translate(UTILS.NMToMeters(5), self.group:GetHeading(), true)
local wp0=coordinate:WaypointAir("BARO", COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.TurningPoint, Speed, true)
local wp9=Coordinate:WaypointAir("BARO", COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.TurningPoint, Speed, true, nil, DCSTasks, "Refuel")
self:Route({wp0, wp9}) self:Route({wp0, wp9})
-- Set task.
--self:SetTask(TaskCombo)
--self:PushTask(TaskCombo)
end end
--- On after "Refueled" event. --- On after "Refueled" event.
@@ -2823,7 +2863,11 @@ function FLIGHTGROUP:onafterRefueled(From, Event, To)
MESSAGE:New(text, 30, "DEBUG"):ToAllIf(self.Debug) MESSAGE:New(text, 30, "DEBUG"):ToAllIf(self.Debug)
self:I(self.lid..text) self:I(self.lid..text)
self:__UpdateRoute(-1) if self.missionpaused then
self:UnpauseMission()
else
self:__UpdateRoute(-1)
end
end end
@@ -2908,7 +2952,7 @@ end
-- @param #string To To state. -- @param #string To To state.
-- @param Wrapper.Unit#UNIT Unit The detected unit. -- @param Wrapper.Unit#UNIT Unit The detected unit.
function FLIGHTGROUP:onafterDetectedUnit(From, Event, To, Unit) function FLIGHTGROUP:onafterDetectedUnit(From, Event, To, Unit)
self:T(self.lid..string.format("Detected unit %s", Unit:GetName())) self:T2(self.lid..string.format("Detected unit %s", Unit:GetName()))
self.detectedunits:AddUnit(Unit) self.detectedunits:AddUnit(Unit)
end end
@@ -2987,7 +3031,7 @@ function FLIGHTGROUP:onafterFuelCritical(From, Event, To)
-- Route helo back home. It is respawned! But this is the only way to ensure that it actually lands at the airbase. -- Route helo back home. It is respawned! But this is the only way to ensure that it actually lands at the airbase.
local airbase=self.destbase or self.homebase local airbase=self.destbase or self.homebase
if airbase and self.fuelcriticalrtb then if airbase and self.fuelcriticalrtb and not self:IsGoing4Fuel() then
self:RTB(airbase) self:RTB(airbase)
--TODO: RTZ --TODO: RTZ
end end
@@ -3002,7 +3046,7 @@ end
-- @param Core.Zone#ZONE Zone The zone that the group entered. -- @param Core.Zone#ZONE Zone The zone that the group entered.
function FLIGHTGROUP:onafterEnterZone(From, Event, To, Zone) function FLIGHTGROUP:onafterEnterZone(From, Event, To, Zone)
local zonename=Zone and Zone:GetName() or "unknown" local zonename=Zone and Zone:GetName() or "unknown"
self:I(self.lid..string.format("Entered Zone %s", zonename)) self:T2(self.lid..string.format("Entered Zone %s", zonename))
self.inzones:Add(Zone:GetName(), Zone) self.inzones:Add(Zone:GetName(), Zone)
end end
@@ -3014,7 +3058,7 @@ end
-- @param Core.Zone#ZONE Zone The zone that the group entered. -- @param Core.Zone#ZONE Zone The zone that the group entered.
function FLIGHTGROUP:onafterLeaveZone(From, Event, To, Zone) function FLIGHTGROUP:onafterLeaveZone(From, Event, To, Zone)
local zonename=Zone and Zone:GetName() or "unknown" local zonename=Zone and Zone:GetName() or "unknown"
self:I(self.lid..string.format("Left Zone %s", zonename)) self:T2(self.lid..string.format("Left Zone %s", zonename))
self.inzones:Remove(zonename, true) self.inzones:Remove(zonename, true)
end end
@@ -3174,7 +3218,8 @@ function FLIGHTGROUP:onafterTaskExecute(From, Event, To, Task)
local TaskFinal=self.group:TaskCombo({TaskControlled, TaskDone}) local TaskFinal=self.group:TaskCombo({TaskControlled, TaskDone})
-- Set task for group. -- Set task for group.
self:PushTask(TaskFinal, 1) --self:PushTask(TaskFinal, 1)
self:SetTask(TaskFinal, 1)
end end
@@ -3267,7 +3312,7 @@ function FLIGHTGROUP:onafterTaskCancel(From, Event, To, Task)
local text=string.format("WARNING: No (current) task to cancel!") local text=string.format("WARNING: No (current) task to cancel!")
MESSAGE:New(text, 10, "DEBUG"):ToAllIf(self.Debug) MESSAGE:New(text, 10, "DEBUG"):ToAllIf(self.Debug)
self:I(self.lid..text) self:E(self.lid..text)
end end
@@ -3312,10 +3357,15 @@ function FLIGHTGROUP:onafterTaskDone(From, Event, To, Task)
-- Check if this task was the task of the current mission ==> Mission Done! -- Check if this task was the task of the current mission ==> Mission Done!
local Mission=self:GetMissionByTaskID(Task.id) local Mission=self:GetMissionByTaskID(Task.id)
local status=Mission:GetFlightStatus(self)
if Mission then if Mission then
env.info("FF Task Done ==> Mission Done!") if status~=AUFTRAG.FlightStatus.PAUSED then
self:MissionDone(Mission) env.info("FF Task Done ==> Mission Done!")
self:MissionDone(Mission)
else
--Mission paused. Do nothing!
end
else else
env.info("FF Task Done but NO mission found ==> _CheckFlightDone in 1 sec") env.info("FF Task Done but NO mission found ==> _CheckFlightDone in 1 sec")
self:_CheckFlightDone(1) self:_CheckFlightDone(1)
@@ -3339,7 +3389,8 @@ end
-- @param Ops.Auftrag#AUFTRAG Mission The mission table. -- @param Ops.Auftrag#AUFTRAG Mission The mission table.
function FLIGHTGROUP:onbeforeMissionStart(From, Event, To, Mission) function FLIGHTGROUP:onbeforeMissionStart(From, Event, To, Mission)
self:I(self.lid..string.format("Starting mission %s, FSM=%s, LateActivated=%s, UnControlled=%s", tostring(Mission.name), self:GetState(), tostring(self:IsLateActivated()), tostring(self:IsUncontrolled()))) -- Debug info.
self:T(self.lid..string.format("Starting mission %s, FSM=%s, LateActivated=%s, UnControlled=%s", tostring(Mission.name), self:GetState(), tostring(self:IsLateActivated()), tostring(self:IsUncontrolled())))
-- Delay for route to mission. Group needs to be activated and controlled. -- Delay for route to mission. Group needs to be activated and controlled.
local delay=0 local delay=0
@@ -3372,8 +3423,8 @@ end
function FLIGHTGROUP:onafterMissionStart(From, Event, To, Mission) function FLIGHTGROUP:onafterMissionStart(From, Event, To, Mission)
local text=string.format("Starting Mission %s", tostring(Mission.name)) local text=string.format("Starting Mission %s", tostring(Mission.name))
self:I(self.lid..text) self:T(self.lid..text)
MESSAGE:New(text, 120, "DEBUG"):ToAllIf(true) MESSAGE:New(text, 120, self.lid):ToAllIf(true)
-- Set current mission. -- Set current mission.
self.currentmission=Mission.auftragsnummer self.currentmission=Mission.auftragsnummer
@@ -3398,8 +3449,8 @@ end
function FLIGHTGROUP:onafterMissionExecute(From, Event, To, Mission) function FLIGHTGROUP:onafterMissionExecute(From, Event, To, Mission)
local text=string.format("Executing Mission %s", tostring(Mission.name)) local text=string.format("Executing Mission %s", tostring(Mission.name))
self:I(self.lid..text) self:T(self.lid..text)
MESSAGE:New(text, 120, "DEBUG"):ToAllIf(true) MESSAGE:New(text, 120, self.lid):ToAllIf(true)
-- Set flight mission status to EXECUTING. -- Set flight mission status to EXECUTING.
Mission:SetFlightStatus(self, AUFTRAG.FlightStatus.EXECUTING) Mission:SetFlightStatus(self, AUFTRAG.FlightStatus.EXECUTING)
@@ -3409,6 +3460,49 @@ function FLIGHTGROUP:onafterMissionExecute(From, Event, To, Mission)
end end
--- On after "PauseMission" event.
-- @param #FLIGHTGROUP self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
function FLIGHTGROUP:onafterPauseMission(From, Event, To)
local Mission=self:GetMissionCurrent()
if Mission then
-- Set flight mission status to EXECUTING.
Mission:SetFlightStatus(self, AUFTRAG.FlightStatus.PAUSED)
-- Get mission waypoint task.
local Task=Mission:GetFlightWaypointTask(self)
env.info(string.format("FF pausing current mission %s. Task=%s", tostring(Mission.name), tostring(Task and Task.description or "WTF")))
-- Cancelling the mission is actually cancelling the current task.
self:TaskCancel(Task)
-- Set mission to pause so we can unpause it later.
self.missionpaused=Mission
end
end
--- On after "UnpauseMission" event.
-- @param #FLIGHTGROUP self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
function FLIGHTGROUP:onafterUnpauseMission(From, Event, To)
self:MissionStart(self.missionpaused)
self.missionpaused=nil
end
--- On after "MissionCancel" event. Cancels the mission. --- On after "MissionCancel" event. Cancels the mission.
-- @param #FLIGHTGROUP self -- @param #FLIGHTGROUP self
-- @param #string From From state. -- @param #string From From state.
@@ -3456,7 +3550,10 @@ end
-- @param Ops.Auftrag#AUFTRAG Mission -- @param Ops.Auftrag#AUFTRAG Mission
function FLIGHTGROUP:onafterMissionDone(From, Event, To, Mission) function FLIGHTGROUP:onafterMissionDone(From, Event, To, Mission)
self:I(self.lid..string.format("Mission %s DONE!", Mission.name)) -- Debug info.
local text=string.format("Mission %s DONE!", Mission.name)
self:I(self.lid..text)
MESSAGE:New(text, 120, self.lid):ToAllIf(true)
-- Set Flight status. -- Set Flight status.
Mission:SetFlightStatus(self, AUFTRAG.FlightStatus.DONE) Mission:SetFlightStatus(self, AUFTRAG.FlightStatus.DONE)
@@ -3491,7 +3588,7 @@ function FLIGHTGROUP:RouteToMission(mission, delay)
-- Set altitude of mission waypoint. -- Set altitude of mission waypoint.
if mission.missionAltitude then if mission.missionAltitude then
waypointcoord.y=mission.missionAltitude waypointcoord.y=mission.missionAltitude
env.info("FF mission altitude [m]="..waypointcoord.y) env.info(string.format("FF mission altitude %d m = %d ft", waypointcoord.y, UTILS.MetersToFeet(waypointcoord.y)))
end end
-- Add enroute tasks. -- Add enroute tasks.
@@ -3513,10 +3610,15 @@ function FLIGHTGROUP:RouteToMission(mission, delay)
-- TODO: better marker text, mission.maker -- TODO: better marker text, mission.maker
--mission.marker=waypointcoord:MarkToCoalition(mission.name, self:GetCoalition(), true) --mission.marker=waypointcoord:MarkToCoalition(mission.name, self:GetCoalition(), true)
mission.marker=waypointcoord:MarkToAll(mission.name, true) mission.marker=waypointcoord:MarkToAll(string.format("%s %s %s", mission.name, mission.type, self.groupname), true)
--self:SetROE(mission.optionROE) if mission.optionROE then
self:SetOptionROE(mission.optionROE)
end
if mission.optionROT then
self:SetOptionROT(mission.optionROT)
end
end end
end end
@@ -3609,23 +3711,6 @@ function FLIGHTGROUP._DestinationOverhead(group, flightgroup, destination)
end end
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Option functions
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- Set ROE.
-- @param #FLIGHTGROUP self
-- @param #number roe ROE value.
-- @return #FLIGHTGROUP self
function FLIGHTGROUP:SetOptionROE(roe)
if self:IsAlive() then
self.group:SetOption(AI.Option.Air.id.ROE, AI.Option.Air.val.ROE.WEAPON_HOLD)
end
end
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Misc functions -- Misc functions
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
@@ -3740,7 +3825,7 @@ function FLIGHTGROUP:AddElementByName(unitname)
local text=string.format("Adding element %s: status=%s, skill=%s, modex=%s, fuelmass=%.1f, category=%d, categoryname=%s, callsign=%s, ai=%s", local text=string.format("Adding element %s: status=%s, skill=%s, modex=%s, fuelmass=%.1f, category=%d, categoryname=%s, callsign=%s, ai=%s",
element.name, element.status, element.skill, element.modex, element.fuelmass, element.category, element.categoryname, element.callsign, tostring(element.ai)) element.name, element.status, element.skill, element.modex, element.fuelmass, element.category, element.categoryname, element.callsign, tostring(element.ai))
self:I(self.lid..text) self:T(self.lid..text)
-- Add element to table. -- Add element to table.
table.insert(self.elements, element) table.insert(self.elements, element)
@@ -4204,7 +4289,7 @@ function FLIGHTGROUP:InitWaypoints(waypoints)
end end
-- Debug info. -- Debug info.
self:I(self.lid..string.format("Initializing %d waypoints. Homebase %s ==> %s Destination", #self.waypoints, self.homebase and self.homebase:GetName() or "unknown", self.destbase and self.destbase:GetName() or "uknown")) self:T(self.lid..string.format("Initializing %d waypoints. Homebase %s ==> %s Destination", #self.waypoints, self.homebase and self.homebase:GetName() or "unknown", self.destbase and self.destbase:GetName() or "uknown"))
-- Update route. -- Update route.
if #self.waypoints>0 then if #self.waypoints>0 then
@@ -4251,7 +4336,7 @@ function FLIGHTGROUP:AddWaypointAir(coordinate, wpnumber, speed, updateroute)
table.insert(self.waypoints, wpnumber, wp) table.insert(self.waypoints, wpnumber, wp)
-- Debug info. -- Debug info.
self:I(self.lid..string.format("Adding AIR waypoint #%d, speed=%.1f knots. Last waypoint passed was #%s. Total waypoints #%d", wpnumber, speed, self.currentwp, #self.waypoints)) self:T(self.lid..string.format("Adding AIR waypoint #%d, speed=%.1f knots. Last waypoint passed was #%s. Total waypoints #%d", wpnumber, speed, self.currentwp, #self.waypoints))
-- Shift all waypoint tasks after the inserted waypoint. -- Shift all waypoint tasks after the inserted waypoint.
for _,_task in pairs(self.taskqueue) do for _,_task in pairs(self.taskqueue) do
@@ -5201,7 +5286,7 @@ function FLIGHTGROUP:GetParking(airbase)
-- Safe parking using TO_AC from DCS result. -- Safe parking using TO_AC from DCS result.
if verysafe and parkingspot.TOAC then if verysafe and parkingspot.TOAC then
free=false free=false
self:I(self.lid..string.format("Parking spot %d is occupied by other aircraft taking off (TOAC).", parkingspot.TerminalID)) self:T2(self.lid..string.format("Parking spot %d is occupied by other aircraft taking off (TOAC).", parkingspot.TerminalID))
end end
-- Loop over all obstacles. -- Loop over all obstacles.
@@ -5235,7 +5320,7 @@ function FLIGHTGROUP:GetParking(airbase)
-- Add parkingspot for this element. -- Add parkingspot for this element.
table.insert(parking, parkingspot) table.insert(parking, parkingspot)
self:I(self.lid..string.format("Parking spot %d is free for element %s!", parkingspot.TerminalID, element.name)) self:T2(self.lid..string.format("Parking spot %d is free for element %s!", parkingspot.TerminalID, element.name))
-- Add the unit as obstacle so that this spot will not be available for the next unit. -- Add the unit as obstacle so that this spot will not be available for the next unit.
table.insert(obstacles, {coord=parkingspot.Coordinate, size=element.size, name=element.name, type="element"}) table.insert(obstacles, {coord=parkingspot.Coordinate, size=element.size, name=element.name, type="element"})
@@ -5246,7 +5331,7 @@ function FLIGHTGROUP:GetParking(airbase)
else else
-- Debug output for occupied spots. -- Debug output for occupied spots.
self:I(self.lid..string.format("Parking spot %d is occupied or not big enough!", parkingspot.TerminalID)) self:T2(self.lid..string.format("Parking spot %d is occupied or not big enough!", parkingspot.TerminalID))
--if self.Debug then --if self.Debug then
-- local coord=problem.coord --Core.Point#COORDINATE -- local coord=problem.coord --Core.Point#COORDINATE
-- local text=string.format("Obstacle blocking spot #%d is %s type %s with size=%.1f m and distance=%.1f m.", _termid, problem.name, problem.type, problem.size, problem.dist) -- local text=string.format("Obstacle blocking spot #%d is %s type %s with size=%.1f m and distance=%.1f m.", _termid, problem.name, problem.type, problem.size, problem.dist)
@@ -5260,7 +5345,7 @@ function FLIGHTGROUP:GetParking(airbase)
-- No parking spot for at least one asset :( -- No parking spot for at least one asset :(
if not gotit then if not gotit then
self:I(self.lid..string.format("WARNING: No free parking spot for element %s", element.name)) self:E(self.lid..string.format("WARNING: No free parking spot for element %s", element.name))
return nil return nil
end end
@@ -5371,32 +5456,54 @@ end
-- OPTION FUNCTIONS -- OPTION FUNCTIONS
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- Set ROE for a group. --- Set the default ROE for the group. This is the ROE state gets when the group is spawned or to which it defaults back after a mission.
-- @param #FLIGHTGROUP self -- @param #FLIGHTGROUP self
-- @param #string roe ROE of group. Default is FLIGHTGROUP.ROE.HOLDFIRE. -- @param #number roe ROE of group. Default is ENUMS.ROE.ReturnFire.
function FLIGHTGROUP:SetOptionROE(roe) -- @return #FLIGHTGROUP self
if roe==FLIGHTGROUP.ROE.RETURNFIRE then function FLIGHTGROUP:SetDefaultROE(roe)
self.group:OptionROEReturnFire() self.optionROEdefault=roe or ENUMS.ROE.ReturnFire
elseif roe==FLIGHTGROUP.ROE.WEAPONFREE then return self
self.group:OptionROEWeaponFree()
else
self.group:OptionROEHoldFire()
end
self.ROEcurrent=roe
end end
--- Set current ROE for the group.
--- Set ROT for a group.
-- @param #FLIGHTGROUP self -- @param #FLIGHTGROUP self
-- @param #string rot ROT of group. -- @param #string roe ROE of group. Default is the value defined by :SetDefaultROE().
function FLIGHTGROUP:SetOptionROT(rot) -- @return #FLIGHTGROUP self
if rot==FLIGHTGROUP.ROT.PASSIVE then function FLIGHTGROUP:SetOptionROE(roe)
self.group:OptionROTPassiveDefense() roe=roe or self.optionROEdefault
elseif self.rot==FLIGHTGROUP.ROT.NOREACT then if self:IsAlive() then
self.group:OptionROTEvadeFire() self.group:OptionROE(roe)
self.optionROEcurrent=roe
self:I(self.lid..string.format("Setting current ROE=%d (0=WeaponFree, 1=OpenFireWeaponFree, 2=OpenFire, 3=ReturnFire, 4=WeaponHold)", self.optionROEcurrent))
else else
self.group:OptionROTNoReaction() -- WARNING
end end
return self
end
--- Set the default ROT for the group. This is the ROT state gets when the group is spawned or to which it defaults back after a mission.
-- @param #FLIGHTGROUP self
-- @param #number roe ROE of group. Default is ENUMS.ROT.PassiveDefense.
-- @return #FLIGHTGROUP self
function FLIGHTGROUP:SetDefaultROT(roe)
self.optionROTdefault=roe or ENUMS.ROT.PassiveDefense
return self
end
--- Set ROT for the group.
-- @param #FLIGHTGROUP self
-- @param #string rot ROT of group. Default is the value defined by :SetDefaultROT().
-- @return #FLIGHTGROUP self
function FLIGHTGROUP:SetOptionROT(rot)
rot=rot or self.optionROTdefault
if self:IsAlive() then
self.group:OptionROT(rot)
self.optionROTcurrent=rot
self:I(self.lid..string.format("Setting current ROT=%d (0=NoReaction, 1=Passive, 2=Evade, 3=ByPass, 4=AllowAbort)", self.optionROTcurrent))
else
-- WARNING
end
return self
end end
+33 -6
View File
@@ -208,6 +208,32 @@ function INTEL:SetForgetTime(TimeInterval)
return self return self
end end
--- Filter unit categories. Valid categories are:
--
-- * Unit.Category.AIRPLANE
-- * Unit.Category.HELICOPTER
-- * Unit.Category.GROUND_UNIT
-- * Unit.Category.SHIP
-- * Unit.Category.STRUCTURE
--
-- @param #INTEL self
-- @param #table Categories Filter categories, e.g. {Unit.Category.AIRPLANE, Unit.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
--- Filter group categories. Valid categories are: --- Filter group categories. Valid categories are:
-- --
-- * Group.Category.AIRPLANE -- * Group.Category.AIRPLANE
@@ -219,14 +245,15 @@ end
-- @param #INTEL self -- @param #INTEL self
-- @param #table Categories Filter categories, e.g. {Group.Category.AIRPLANE, Group.Category.HELICOPTER}. -- @param #table Categories Filter categories, e.g. {Group.Category.AIRPLANE, Group.Category.HELICOPTER}.
-- @return #INTEL self -- @return #INTEL self
function INTEL:SetFilterCategory(Categories) function INTEL:FilterCategoryGroup(GroupCategories)
if type(Categories)~="table" then if type(GroupCategories)~="table" then
Categories={Categories} GroupCategories={GroupCategories}
end end
self.filterCategory=Categories
local text="Filter categories: " self.filterCategoryGroup=GroupCategories
for _,category in pairs(self.filterCategory) do
local text="Filter group categories: "
for _,category in pairs(self.filterCategoryGroup) do
text=text..string.format("%d,", category) text=text..string.format("%d,", category)
end end
self:I(self.lid..text) self:I(self.lid..text)
+6 -3
View File
@@ -126,7 +126,10 @@ function SQUADRON:New(TemplateGroupName, Ngroups, SquadronName)
-- Add FSM transitions. -- Add FSM transitions.
-- From State --> Event --> To State -- From State --> Event --> To State
self:AddTransition("Stopped", "Start", "Running") -- Start FSM. self:AddTransition("Stopped", "Start", "Running") -- Start FSM.
self:AddTransition("*", "Status", "*") -- SQUADRON status update self:AddTransition("*", "Status", "*") -- Status update.
self:AddTransition("Running", "Pause", "Paused") -- Pause squadron.
self:AddTransition("Paused", "Unpause", "Running") -- Unpause squadron.
self:AddTransition("*", "Stop", "Stopped") -- Stop squadron.
------------------------ ------------------------
@@ -315,7 +318,7 @@ end
-- @param #SQUADRON self -- @param #SQUADRON self
function SQUADRON:_CheckAssetStatus() function SQUADRON:_CheckAssetStatus()
for _,_assets in pairs(self.assets) do for _,_asset in pairs(self.assets) do
local asset=_asset --#SQUADRON.Flight local asset=_asset --#SQUADRON.Flight
flight.flightgroup:IsSpawned() flight.flightgroup:IsSpawned()
@@ -347,7 +350,7 @@ function SQUADRON:CanMission(Mission)
if Mission.refuelSystem and Mission.refuelSystem==self.tankerSystem then if Mission.refuelSystem and Mission.refuelSystem==self.tankerSystem then
-- Correct refueling system. -- Correct refueling system.
else else
env.info(string.format("wrong refuling system mi=%s ta=%s", tostring(Mission.refuelSystem), tostring(self.tankerSystem))) self:I(self.lid..string.format("wrong refuling system mi=%s ta=%s", tostring(Mission.refuelSystem), tostring(self.tankerSystem)))
cando=false cando=false
end end
+14 -13
View File
@@ -7,9 +7,6 @@
--- [DCS Enum world](https://wiki.hoggitworld.com/view/DCS_enum_world) --- [DCS Enum world](https://wiki.hoggitworld.com/view/DCS_enum_world)
-- @type ENUMS -- @type ENUMS
-- @field #ENUMS.ROE Rules Of Engagement.
-- @field #ENUMS.ROT Reation On Threat.
-- @field #ENUMS.WeaponFlag Weapon flags.
--- The world singleton contains functions centered around two different but extremely useful functions. --- The world singleton contains functions centered around two different but extremely useful functions.
-- * Events and event handlers are all governed within world. -- * Events and event handlers are all governed within world.
@@ -22,22 +19,24 @@ ENUMS = {}
--- Rules of Engagement. --- Rules of Engagement.
-- @type ENUMS.ROE -- @type ENUMS.ROE
ENUMS.ROE = { ENUMS.ROE = {
HoldFire = 1, WeaponFree=0,
ReturnFire = 2, OpenFireWeaponFree=1,
OpenFire = 3, OpenFire=2,
WeaponFree = 4 ReturnFire=3,
WeaponHold=4,
} }
--- Reaction On Thrat. --- Reaction On Threat.
-- @type ENUMS.ROT -- @type ENUMS.ROT
ENUMS.ROT = { ENUMS.ROT = {
NoReaction = 1, NoReaction=0,
PassiveDefense = 2, PassiveDefense=1,
EvadeFire = 3, EvadeFire=2,
Vertical = 4 ByPassAndEscape=3,
AllowAbortMission=4,
} }
--- Weapon types --- Weapon types.
-- @type ENUMS.WeaponFlag -- @type ENUMS.WeaponFlag
ENUMS.WeaponFlag={ ENUMS.WeaponFlag={
Auto=3221225470, --AnyWeapon (AnyBomb + AnyRocket + AnyMissile + Cannons) Auto=3221225470, --AnyWeapon (AnyBomb + AnyRocket + AnyMissile + Cannons)
@@ -67,6 +66,8 @@ ENUMS.WeaponFlag={
AnyRocket=30720 -- (LightRocket + MarkerRocket + CandleRocket + HeavyRocket) AnyRocket=30720 -- (LightRocket + MarkerRocket + CandleRocket + HeavyRocket)
} }
--- Mission tasks.
-- @type ENUMS.MissionTask
ENUMS.MissionTask={ ENUMS.MissionTask={
NOTHING="Nothing", NOTHING="Nothing",
AFAC="AFAC", AFAC="AFAC",
@@ -822,15 +822,16 @@ end
--- (AIR) Attack a Controllable. --- (AIR) Attack a Controllable.
-- @param #CONTROLLABLE self -- @param #CONTROLLABLE self
-- @param Wrapper.Controllable#CONTROLLABLE AttackGroup The Controllable to be attacked. -- @param Wrapper.Group#GROUP AttackGroup The Group to be attacked.
-- @param #number WeaponType (optional) Bitmask of weapon types those allowed to use. If parameter is not defined that means no limits on weapon usage. -- @param #number WeaponType (optional) Bitmask of weapon types those allowed to use. If parameter is not defined that means no limits on weapon usage.
-- @param DCS#AI.Task.WeaponExpend WeaponExpend (optional) Determines how much weapon will be released at each attack. If parameter is not defined the unit / controllable will choose expend on its own discretion. -- @param DCS#AI.Task.WeaponExpend WeaponExpend (optional) Determines how much weapon will be released at each attack. If parameter is not defined the unit / controllable will choose expend on its own discretion.
-- @param #number AttackQty (optional) This parameter limits maximal quantity of attack. The aicraft/controllable will not make more attack than allowed even if the target controllable not destroyed and the aicraft/controllable still have ammo. If not defined the aircraft/controllable will attack target until it will be destroyed or until the aircraft/controllable will run out of ammo. -- @param #number AttackQty (optional) This parameter limits maximal quantity of attack. The aicraft/controllable will not make more attack than allowed even if the target controllable not destroyed and the aicraft/controllable still have ammo. If not defined the aircraft/controllable will attack target until it will be destroyed or until the aircraft/controllable will run out of ammo.
-- @param DCS#Azimuth Direction (optional) Desired ingress direction from the target to the attacking aircraft. Controllable/aircraft will make its attacks from the direction. Of course if there is no way to attack from the direction due the terrain controllable/aircraft will choose another direction. -- @param DCS#Azimuth Direction (optional) Desired ingress direction from the target to the attacking aircraft. Controllable/aircraft will make its attacks from the direction. Of course if there is no way to attack from the direction due the terrain controllable/aircraft will choose another direction.
-- @param DCS#Distance Altitude (optional) Desired attack start altitude. Controllable/aircraft will make its attacks from the altitude. If the altitude is too low or too high to use weapon aircraft/controllable will choose closest altitude to the desired attack start altitude. If the desired altitude is defined controllable/aircraft will not attack from safe altitude. -- @param DCS#Distance Altitude (optional) Desired attack start altitude. Controllable/aircraft will make its attacks from the altitude. If the altitude is too low or too high to use weapon aircraft/controllable will choose closest altitude to the desired attack start altitude. If the desired altitude is defined controllable/aircraft will not attack from safe altitude.
-- @param #boolean AttackQtyLimit (optional) The flag determines how to interpret attackQty parameter. If the flag is true then attackQty is a limit on maximal attack quantity for "AttackGroup" and "AttackUnit" tasks. If the flag is false then attackQty is a desired attack quantity for "Bombing" and "BombingRunway" tasks. -- @param #boolean AttackQtyLimit (optional) The flag determines how to interpret attackQty parameter. If the flag is true then attackQty is a limit on maximal attack quantity for "AttackGroup" and "AttackUnit" tasks. If the flag is false then attackQty is a desired attack quantity for "Bombing" and "BombingRunway" tasks.
-- @param #boolean GroupAttack (Optional) If true, attack as group.
-- @return DCS#Task The DCS task structure. -- @return DCS#Task The DCS task structure.
function CONTROLLABLE:TaskAttackGroup( AttackGroup, WeaponType, WeaponExpend, AttackQty, Direction, Altitude, AttackQtyLimit ) function CONTROLLABLE:TaskAttackGroup( AttackGroup, WeaponType, WeaponExpend, AttackQty, Direction, Altitude, AttackQtyLimit, GroupAttack )
--self:F2( { self.ControllableName, AttackGroup, WeaponType, WeaponExpend, AttackQty, Direction, Altitude, AttackQtyLimit } ) --self:F2( { self.ControllableName, AttackGroup, WeaponType, WeaponExpend, AttackQty, Direction, Altitude, AttackQtyLimit } )
-- AttackGroup = { -- AttackGroup = {
@@ -857,9 +858,10 @@ function CONTROLLABLE:TaskAttackGroup( AttackGroup, WeaponType, WeaponExpend, At
attackQtyLimit = AttackQty and true or false, attackQtyLimit = AttackQty and true or false,
attackQty = AttackQty, attackQty = AttackQty,
directionEnabled = Direction and true or false, directionEnabled = Direction and true or false,
direction = Direction and math.rad(Direction) or nil, direction = Direction and math.rad(Direction) or 0,
altitudeEnabled = Altitude and true or false, altitudeEnabled = Altitude and true or false,
altitude = Altitude, altitude = Altitude,
groupAttack = GroupAttack and true or false,
}, },
} }
@@ -885,7 +887,7 @@ function CONTROLLABLE:TaskAttackUnit(AttackUnit, GroupAttack, WeaponExpend, Atta
groupAttack = GroupAttack and GroupAttack or false, groupAttack = GroupAttack and GroupAttack or false,
expend = WeaponExpend or "Auto", expend = WeaponExpend or "Auto",
directionEnabled = Direction and true or false, directionEnabled = Direction and true or false,
direction = Direction and math.rad(Direction) or nil, direction = Direction and math.rad(Direction) or 0,
altitudeEnabled = Altitude and true or false, altitudeEnabled = Altitude and true or false,
altitude = Altitude, altitude = Altitude,
attackQtyLimit = AttackQty and true or false, attackQtyLimit = AttackQty and true or false,
@@ -956,7 +958,7 @@ function CONTROLLABLE:TaskAttackMapObject( Vec2, GroupAttack, WeaponExpend, Atta
attackQtyLimit = AttackQty and true or false, attackQtyLimit = AttackQty and true or false,
attackQty = AttackQty, attackQty = AttackQty,
directionEnabled = Direction and true or false, directionEnabled = Direction and true or false,
direction = Direction, direction = Direction and math.rad(Direction) or 0,
altitudeEnabled = Altitude and true or false, altitudeEnabled = Altitude and true or false,
altitude = Altitude, altitude = Altitude,
weaponType = WeaponType or 1073741822, weaponType = WeaponType or 1073741822,
@@ -996,7 +998,7 @@ function CONTROLLABLE:TaskCarpetBombing(Vec2, GroupAttack, WeaponExpend, AttackQ
attackQtyLimit = AttackQty and true or false, attackQtyLimit = AttackQty and true or false,
attackQty = AttackQty, attackQty = AttackQty,
directionEnabled = Direction and true or false, directionEnabled = Direction and true or false,
direction = Direction and math.rad(Direction) or nil, direction = Direction and math.rad(Direction) or 0,
altitudeEnabled = Altitude and true or false, altitudeEnabled = Altitude and true or false,
altitude = Altitude, altitude = Altitude,
} }
@@ -2956,6 +2958,32 @@ function CONTROLLABLE:SetOption(OptionID, OptionValue)
return nil return nil
end end
--- Set option for Rules of Engagement (ROE).
-- @param Wrapper.Controllable#CONTROLLABLE self
-- @param #number ROEvalue ROE value. See ENUMS.ROE.
-- @return Wrapper.Controllable#CONTROLLABLE self
function CONTROLLABLE:OptionROE(ROEvalue)
local DCSControllable = self:GetDCSObject()
if DCSControllable then
local Controller = self:_GetController()
if self:IsAir() then
Controller:setOption(AI.Option.Air.id.ROE, ROEvalue )
elseif self:IsGround() then
Controller:setOption(AI.Option.Ground.id.ROE, ROEvalue )
elseif self:IsShip() then
Controller:setOption(AI.Option.Naval.id.ROE, ROEvalue )
end
return self
end
return nil
end
--- Can the CONTROLLABLE hold their weapons? --- Can the CONTROLLABLE hold their weapons?
-- @param #CONTROLLABLE self -- @param #CONTROLLABLE self
-- @return #boolean -- @return #boolean
@@ -3198,6 +3226,27 @@ function CONTROLLABLE:OptionROTNoReaction()
return nil return nil
end end
--- Set Reation On Threat behaviour.
-- @param #CONTROLLABLE self
-- @param #number ROTvalue ROT value. See ENUMS.ROT.
-- @return #CONTROLLABLE self
function CONTROLLABLE:OptionROT(ROTvalue)
self:F2( { self.ControllableName } )
local DCSControllable = self:GetDCSObject()
if DCSControllable then
local Controller = self:_GetController()
if self:IsAir() then
Controller:setOption( AI.Option.Air.id.REACTION_ON_THREAT, ROTvalue )
end
return self
end
return nil
end
--- Can the CONTROLLABLE evade using passive defenses? --- Can the CONTROLLABLE evade using passive defenses?
-- @param #CONTROLLABLE self -- @param #CONTROLLABLE self
-- @return #boolean -- @return #boolean