Merge pull request #1716 from FlightControl-Master/FF/Ops

OPS
This commit is contained in:
Frank 2022-04-20 21:51:09 +02:00 committed by GitHub
commit 04f60747d9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 399 additions and 95 deletions

View File

@ -5968,6 +5968,14 @@ function WAREHOUSE:_SpawnAssetAircraft(alias, asset, request, parking, uncontrol
_action=COORDINATE.WaypointAction.FromParkingAreaHot _action=COORDINATE.WaypointAction.FromParkingAreaHot
uncontrolled=false uncontrolled=false
end end
local airstart=asset.takeoffType and asset.takeoffType==COORDINATE.WaypointType.TurningPoint or false
if airstart then
_type=COORDINATE.WaypointType.TurningPoint
_action=COORDINATE.WaypointAction.TurningPoint
uncontrolled=false
end
-- Set route points. -- Set route points.
@ -5975,7 +5983,15 @@ function WAREHOUSE:_SpawnAssetAircraft(alias, asset, request, parking, uncontrol
-- Get flight path if the group goes to another warehouse by itself. -- Get flight path if the group goes to another warehouse by itself.
if request.toself then if request.toself then
local wp=self.airbase:GetCoordinate():WaypointAir("RADIO", _type, _action, 0, false, self.airbase, {}, "Parking")
local coord=self.airbase:GetCoordinate()
if airstart then
coord:SetAltitude(math.random(1000, 2000))
end
-- Single waypoint.
local wp=coord:WaypointAir("RADIO", _type, _action, 0, false, self.airbase, {}, "Parking")
template.route.points={wp} template.route.points={wp}
else else
template.route.points=self:_GetFlightplan(asset, self.airbase, request.warehouse.airbase) template.route.points=self:_GetFlightplan(asset, self.airbase, request.warehouse.airbase)
@ -5999,7 +6015,7 @@ function WAREHOUSE:_SpawnAssetAircraft(alias, asset, request, parking, uncontrol
else else
if #parking<#template.units then if #parking<#template.units and not airstart then
local text=string.format("ERROR: Not enough parking! Free parking = %d < %d aircraft to be spawned.", #parking, #template.units) local text=string.format("ERROR: Not enough parking! Free parking = %d < %d aircraft to be spawned.", #parking, #template.units)
self:_DebugMessage(text) self:_DebugMessage(text)
return nil return nil
@ -6021,14 +6037,25 @@ function WAREHOUSE:_SpawnAssetAircraft(alias, asset, request, parking, uncontrol
unit.x=coord.x unit.x=coord.x
unit.y=coord.z unit.y=coord.z
unit.alt=coord.y unit.alt=coord.y
if airstart then
unit.alt=math.random(1000, 2000)
end
unit.parking_id = nil unit.parking_id = nil
unit.parking = nil unit.parking = nil
else else
local coord=parking[i].Coordinate --Core.Point#COORDINATE local coord=nil --Core.Point#COORDINATE
local terminal=parking[i].TerminalID --#number local terminal=nil --#number
if airstart then
coord=self.airbase:GetCoordinate():SetAltitude(math.random(1000, 2000))
else
coord=parking[i].Coordinate
terminal=parking[i].TerminalID
end
if self.Debug then if self.Debug then
coord:MarkToAll(string.format("Spawnplace unit %s terminal %d.", unit.name, terminal)) coord:MarkToAll(string.format("Spawnplace unit %s terminal %d.", unit.name, terminal))

View File

@ -47,10 +47,14 @@
-- --
-- @field Ops.RescueHelo#RESCUEHELO rescuehelo The rescue helo. -- @field Ops.RescueHelo#RESCUEHELO rescuehelo The rescue helo.
-- @field Ops.RecoveryTanker#RECOVERYTANKER recoverytanker The recoverytanker. -- @field Ops.RecoveryTanker#RECOVERYTANKER recoverytanker The recoverytanker.
--
-- @field #string takeoffType Take of type.
-- @field #boolean despawnAfterLanding Aircraft are despawned after landing.
-- @field #boolean despawnAfterHolding Aircraft are despawned after holding.
-- --
-- @extends Ops.Legion#LEGION -- @extends Ops.Legion#LEGION
--- *I fly because it releases my mind from the tyranny of petty things* -- Antoine de Saint-Exupery --- *I fly because it releases my mind from the tyranny of petty things.* -- Antoine de Saint-Exupery
-- --
-- === -- ===
-- --
@ -171,14 +175,14 @@ AIRWING = {
--- AIRWING class version. --- AIRWING class version.
-- @field #string version -- @field #string version
AIRWING.version="0.9.1" AIRWING.version="0.9.2"
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- ToDo list -- ToDo list
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO: Check that airbase has enough parking spots if a request is BIG. -- TODO: Check that airbase has enough parking spots if a request is BIG.
-- TODO: Spawn in air ==> Needs WAREHOUSE update. -- DONE: Spawn in air ==> Needs WAREHOUSE update.
-- DONE: Spawn hot. -- DONE: Spawn hot.
-- DONE: Make special request to transfer squadrons to anther airwing (or warehouse). -- DONE: Make special request to transfer squadrons to anther airwing (or warehouse).
-- DONE: Add squadrons to warehouse. -- DONE: Add squadrons to warehouse.
@ -818,6 +822,77 @@ function AIRWING:SetAirboss(airboss)
return self return self
end end
--- Set takeoff type. All assets of this squadron will be spawned with cold (default) or hot engines.
-- Spawning on runways is not supported.
-- @param #AIRWING self
-- @param #string TakeoffType Take off type: "Cold" (default) or "Hot" with engines on or "Air" for spawning in air.
-- @return #AIRWING self
function AIRWING:SetTakeoffType(TakeoffType)
TakeoffType=TakeoffType or "Cold"
if TakeoffType:lower()=="hot" then
self.takeoffType=COORDINATE.WaypointType.TakeOffParkingHot
elseif TakeoffType:lower()=="cold" then
self.takeoffType=COORDINATE.WaypointType.TakeOffParking
elseif TakeoffType:lower()=="air" then
self.takeoffType=COORDINATE.WaypointType.TurningPoint
else
self.takeoffType=COORDINATE.WaypointType.TakeOffParking
end
return self
end
--- Set takeoff type cold (default). All assets of this squadron will be spawned with engines off (cold).
-- @param #AIRWING self
-- @return #AIRWING self
function AIRWING:SetTakeoffCold()
self:SetTakeoffType("Cold")
return self
end
--- Set takeoff type hot. All assets of this squadron will be spawned with engines on (hot).
-- @param #AIRWING self
-- @return #AIRWING self
function AIRWING:SetTakeoffHot()
self:SetTakeoffType("Hot")
return self
end
--- Set takeoff type air. All assets of this squadron will be spawned in air above the airbase.
-- @param #AIRWING self
-- @return #AIRWING self
function AIRWING:SetTakeoffAir()
self:SetTakeoffType("Air")
return self
end
--- Set despawn after landing. Aircraft will be despawned after the landing event.
-- Can help to avoid DCS AI taxiing issues.
-- @param #AIRWING self
-- @param #boolean Switch If `true` (default), activate despawn after landing.
-- @return #AIRWING self
function AIRWING:SetDespawnAfterLanding(Switch)
if Switch then
self.despawnAfterLanding=Switch
else
self.despawnAfterLanding=true
end
return self
end
--- Set despawn after holding. Aircraft will be despawned when they arrive at their holding position at the airbase.
-- Can help to avoid DCS AI taxiing issues.
-- @param #AIRWING self
-- @param #boolean Switch If `true` (default), activate despawn after landing.
-- @return #AIRWING self
function AIRWING:SetDespawnAfterHolding(Switch)
if Switch then
self.despawnAfterHolding=Switch
else
self.despawnAfterHolding=true
end
return self
end
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Start & Status -- Start & Status
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

View File

@ -64,7 +64,7 @@ ARMYGROUP = {
--- Army Group version. --- Army Group version.
-- @field #string version -- @field #string version
ARMYGROUP.version="0.7.2" ARMYGROUP.version="0.7.3"
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO list -- TODO list
@ -669,18 +669,50 @@ function ARMYGROUP:Status()
if alive~=nil then if alive~=nil then
if self.verbose>=1 then if self.verbose>=1 then
-- Number of elements.
local nelem=self:CountElements()
local Nelem=#self.elements
-- Get number of tasks and missions. -- Get number of tasks and missions.
local nTaskTot, nTaskSched, nTaskWP=self:CountRemainingTasks() local nTaskTot, nTaskSched, nTaskWP=self:CountRemainingTasks()
local nMissions=self:CountRemainingMissison() local nMissions=self:CountRemainingMissison()
local roe=self:GetROE() -- ROE and Alarm State.
local alarm=self:GetAlarmstate() local roe=self:GetROE() or -1
local als=self:GetAlarmstate() or -1
-- Waypoint stuff.
local wpidxCurr=self.currentwp
local wpuidCurr=self:GetWaypointUIDFromIndex(wpidxCurr) or 0
local wpidxNext=self:GetWaypointIndexNext() or 0
local wpuidNext=self:GetWaypointUIDFromIndex(wpidxNext) or 0
local wpN=#self.waypoints or 0
local wpF=tostring(self.passedfinalwp)
-- Speed.
local speed=UTILS.MpsToKnots(self.velocity or 0) local speed=UTILS.MpsToKnots(self.velocity or 0)
local speedEx=UTILS.MpsToKnots(self:GetExpectedSpeed()) local speedEx=UTILS.MpsToKnots(self:GetExpectedSpeed())
local formation=self.option.Formation or "unknown"
local ammo=self:GetAmmoTot()
-- Altitude.
local alt=self.position and self.position.y or 0
-- Heading in degrees.
local hdg=self.heading or 0
-- TODO: GetFormation function.
local formation=self.option.Formation or "unknown"
-- Life points.
local life=self.life or 0
-- Total ammo.
local ammo=self:GetAmmoTot().Total
-- Detected units.
local ndetected=self.detectionOn and tostring(self.detectedunits:Count()) or "OFF"
-- Get cargo weight.
local cargo=0 local cargo=0
for _,_element in pairs(self.elements) do for _,_element in pairs(self.elements) do
local element=_element --Ops.OpsGroup#OPSGROUP.Element local element=_element --Ops.OpsGroup#OPSGROUP.Element
@ -688,9 +720,9 @@ function ARMYGROUP:Status()
end end
-- Info text. -- Info text.
local text=string.format("%s [ROE-AS=%d-%d T/M=%d/%d]: Wp=%d/%d-->%d (final %s), Life=%.1f, Speed=%.1f (%d), Heading=%03d, Ammo=%d, Cargo=%.1f", local text=string.format("%s [%d/%d]: ROE/AS=%d/%d | T/M=%d/%d | Wp=%d[%d]-->%d[%d]/%d [%s] | Life=%.1f | v=%.1f (%d) | Hdg=%03d | Ammo=%d | Detect=%s | Cargo=%.1f",
fsmstate, roe, alarm, nTaskTot, nMissions, self.currentwp, #self.waypoints, self:GetWaypointIndexNext(), tostring(self.passedfinalwp), self.life or 0, speed, speedEx, self.heading or 0, ammo.Total, cargo) fsmstate, nelem, Nelem, roe, als, nTaskTot, nMissions, wpidxCurr, wpuidCurr, wpidxNext, wpuidNext, wpN, wpF, life, speed, speedEx, hdg, ammo, ndetected, cargo)
self:T(self.lid..text) self:I(self.lid..text)
end end
@ -844,6 +876,9 @@ function ARMYGROUP:onafterSpawned(From, Event, To)
-- Set default Alarm State. -- Set default Alarm State.
self:SwitchAlarmstate(self.option.Alarm) self:SwitchAlarmstate(self.option.Alarm)
-- Set emission.
self:SwitchEmission(self.option.Emission)
-- Set default EPLRS. -- Set default EPLRS.
self:SwitchEPLRS(self.option.EPLRS) self:SwitchEPLRS(self.option.EPLRS)
@ -1145,7 +1180,7 @@ function ARMYGROUP:onbeforeRearm(From, Event, To, Coordinate, Formation)
local allowed=true local allowed=true
-- Pause current mission. -- Pause current mission.
if self.currentmission and self.currentmission>0 then if self:IsOnMission() then
self:T(self.lid.."Rearm command but have current mission ==> Pausing mission!") self:T(self.lid.."Rearm command but have current mission ==> Pausing mission!")
self:PauseMission() self:PauseMission()
dt=-0.1 dt=-0.1

View File

@ -2303,7 +2303,7 @@ function AUFTRAG:SetTime(ClockStart, ClockStop)
return self return self
end end
--- Set time how low the mission is executed. Once this time limit has passed, the mission is cancelled. --- Set time how long the mission is executed. Once this time limit has passed, the mission is cancelled.
-- @param #AUFTRAG self -- @param #AUFTRAG self
-- @param #number Duration Duration in seconds. -- @param #number Duration Duration in seconds.
-- @return #AUFTRAG self -- @return #AUFTRAG self

View File

@ -2513,6 +2513,7 @@ function CHIEF:_GetMissionPerformanceFromTarget(Target)
-- Bomb runway. -- Bomb runway.
table.insert(missionperf, self:_CreateMissionPerformance(AUFTRAG.Type.BOMBRUNWAY, 100)) table.insert(missionperf, self:_CreateMissionPerformance(AUFTRAG.Type.BOMBRUNWAY, 100))
table.insert(missionperf, self:_CreateMissionPerformance(AUFTRAG.Type.ARTY, 30))
elseif static then elseif static then
@ -2520,10 +2521,10 @@ function CHIEF:_GetMissionPerformanceFromTarget(Target)
-- STATIC -- STATIC
--- ---
table.insert(missionperf, self:_CreateMissionPerformance(AUFTRAG.Type.BAI, 100)) table.insert(missionperf, self:_CreateMissionPerformance(AUFTRAG.Type.BAI, 100))
table.insert(missionperf, self:_CreateMissionPerformance(AUFTRAG.Type.BOMBING, 70)) table.insert(missionperf, self:_CreateMissionPerformance(AUFTRAG.Type.BOMBING, 70))
table.insert(missionperf, self:_CreateMissionPerformance(AUFTRAG.Type.BOMBCARPET, 50)) table.insert(missionperf, self:_CreateMissionPerformance(AUFTRAG.Type.BOMBCARPET, 50))
table.insert(missionperf, self:_CreateMissionPerformance(AUFTRAG.Type.ARTY, 30)) table.insert(missionperf, self:_CreateMissionPerformance(AUFTRAG.Type.ARTY, 30))
elseif scenery then elseif scenery then
@ -2531,10 +2532,10 @@ function CHIEF:_GetMissionPerformanceFromTarget(Target)
-- SCENERY -- SCENERY
--- ---
table.insert(missionperf, self:_CreateMissionPerformance(AUFTRAG.Type.STRIKE, 100)) table.insert(missionperf, self:_CreateMissionPerformance(AUFTRAG.Type.STRIKE, 100))
table.insert(missionperf, self:_CreateMissionPerformance(AUFTRAG.Type.BOMBING, 70)) table.insert(missionperf, self:_CreateMissionPerformance(AUFTRAG.Type.BOMBING, 70))
table.insert(missionperf, self:_CreateMissionPerformance(AUFTRAG.Type.BOMBCARPET, 50)) table.insert(missionperf, self:_CreateMissionPerformance(AUFTRAG.Type.BOMBCARPET, 50))
table.insert(missionperf, self:_CreateMissionPerformance(AUFTRAG.Type.ARTY, 30)) table.insert(missionperf, self:_CreateMissionPerformance(AUFTRAG.Type.ARTY, 30))
elseif coordinate then elseif coordinate then
@ -2542,9 +2543,9 @@ function CHIEF:_GetMissionPerformanceFromTarget(Target)
-- COORDINATE -- COORDINATE
--- ---
table.insert(missionperf, self:_CreateMissionPerformance(AUFTRAG.Type.BOMBING, 100)) table.insert(missionperf, self:_CreateMissionPerformance(AUFTRAG.Type.BOMBING, 100))
table.insert(missionperf, self:_CreateMissionPerformance(AUFTRAG.Type.BOMBCARPET, 50)) table.insert(missionperf, self:_CreateMissionPerformance(AUFTRAG.Type.BOMBCARPET, 50))
table.insert(missionperf, self:_CreateMissionPerformance(AUFTRAG.Type.ARTY, 30)) table.insert(missionperf, self:_CreateMissionPerformance(AUFTRAG.Type.ARTY, 30))
end end

View File

@ -83,7 +83,7 @@ COHORT = {
--- COHORT class version. --- COHORT class version.
-- @field #string version -- @field #string version
COHORT.version="0.3.0" COHORT.version="0.3.2"
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO list -- TODO list

View File

@ -51,7 +51,8 @@
-- @field #number Tparking Abs. mission time stamp when the group was spawned uncontrolled and is parking. -- @field #number Tparking Abs. mission time stamp when the group was spawned uncontrolled and is parking.
-- @field #table menu F10 radio menu. -- @field #table menu F10 radio menu.
-- @field #string controlstatus Flight control status. -- @field #string controlstatus Flight control status.
-- @field #boolean despawnAfterLanding If true, group is despawned after landed at an airbase. -- @field #boolean despawnAfterLanding If `true`, group is despawned after landed at an airbase.
-- @field #boolean despawnAfterHolding If `true`, group is despawned after reaching the holding point.
-- @field #number RTBRecallCount Number that counts RTB calls. -- @field #number RTBRecallCount Number that counts RTB calls.
-- --
-- @extends Ops.OpsGroup#OPSGROUP -- @extends Ops.OpsGroup#OPSGROUP
@ -182,7 +183,7 @@ FLIGHTGROUP.RadioMessage = {
--- FLIGHTGROUP class version. --- FLIGHTGROUP class version.
-- @field #string version -- @field #string version
FLIGHTGROUP.version="0.7.2" FLIGHTGROUP.version="0.7.3"
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO list -- TODO list
@ -522,6 +523,14 @@ function FLIGHTGROUP:SetDespawnAfterLanding()
return self return self
end end
--- Enable that the group is despawned after holding. This can be useful to avoid DCS taxi issues with other AI or players or jamming taxiways.
-- @param #FLIGHTGROUP self
-- @return #FLIGHTGROUP self
function FLIGHTGROUP:SetDespawnAfterHolding()
self.despawnAfterHolding=true
return self
end
--- Check if flight is parking. --- Check if flight is parking.
-- @param #FLIGHTGROUP self -- @param #FLIGHTGROUP self
@ -818,25 +827,63 @@ function FLIGHTGROUP:Status()
-- Short info. -- Short info.
if self.verbose>=1 then if self.verbose>=1 then
-- Number of elements.
local nelem=self:CountElements() local nelem=self:CountElements()
local Nelem=#self.elements local Nelem=#self.elements
-- Get number of tasks and missions.
local nTaskTot, nTaskSched, nTaskWP=self:CountRemainingTasks() local nTaskTot, nTaskSched, nTaskWP=self:CountRemainingTasks()
local nMissions=self:CountRemainingMissison() local nMissions=self:CountRemainingMissison()
local currT=self.taskcurrent or "None"
local currM=self.currentmission or "None" -- ROE and Alarm State.
local currW=self.currentwp or 0 local roe=self:GetROE() or -1
local nWp=self.waypoints and #self.waypoints or 0 local als=self:GetAlarmstate() or -1
-- Waypoint stuff.
local wpidxCurr=self.currentwp
local wpuidCurr=self:GetWaypointUIDFromIndex(wpidxCurr) or 0
local wpidxNext=self:GetWaypointIndexNext() or 0
local wpuidNext=self:GetWaypointUIDFromIndex(wpidxNext) or 0
local wpN=#self.waypoints or 0
local wpF=tostring(self.passedfinalwp)
-- Speed.
local speed=UTILS.MpsToKnots(self.velocity or 0)
local speedEx=UTILS.MpsToKnots(self:GetExpectedSpeed())
-- Altitude.
local alt=self.position and self.position.y or 0
-- Heading in degrees.
local hdg=self.heading or 0
-- TODO: GetFormation function.
local formation=self.option.Formation or "unknown"
-- Life points.
local life=self.life or 0
-- Total ammo.
local ammo=self:GetAmmoTot().Total
-- Detected units.
local ndetected=self.detectionOn and tostring(self.detectedunits:Count()) or "OFF"
-- Get cargo weight.
local cargo=0
for _,_element in pairs(self.elements) do
local element=_element --Ops.OpsGroup#OPSGROUP.Element
cargo=cargo+element.weightCargo
end
-- Home and destination base.
local home=self.homebase and self.homebase:GetName() or "unknown" local home=self.homebase and self.homebase:GetName() or "unknown"
local dest=self.destbase and self.destbase:GetName() or "unknown" local dest=self.destbase and self.destbase:GetName() or "unknown"
local fc=self.flightcontrol and self.flightcontrol.airbasename or "N/A"
local curr=self.currbase and self.currbase:GetName() or "N/A" local curr=self.currbase and self.currbase:GetName() or "N/A"
local ndetected=self.detectionOn and tostring(self.detectedunits:Count()) or "OFF" -- Info text.
local text=string.format("%s [%d/%d]: ROE/AS=%d/%d | T/M=%d/%d | Wp=%d[%d]-->%d[%d]/%d [%s] | Life=%.1f | v=%.1f (%d) | Hdg=%03d | Ammo=%d | Detect=%s | Cargo=%.1f | Base=%s [%s-->%s]",
local text=string.format("Status %s [%d/%d]: T/M=%d/%d [Current %s/%s] [%s], Waypoint=%d/%d [%s], Base=%s [%s-->%s]", fsmstate, nelem, Nelem, roe, als, nTaskTot, nMissions, wpidxCurr, wpuidCurr, wpidxNext, wpuidNext, wpN, wpF, life, speed, speedEx, hdg, ammo, ndetected, cargo, curr, home, dest)
fsmstate, nelem, Nelem,
nTaskTot, nMissions, currT, currM, tostring(self:HasTaskController()),
currW, nWp, tostring(self.passedfinalwp), curr, home, dest)
self:I(self.lid..text) self:I(self.lid..text)
end end
@ -1341,31 +1388,46 @@ function FLIGHTGROUP:onafterElementLanded(From, Event, To, Element, airbase)
-- Debug info. -- Debug info.
self:T2(self.lid..string.format("Element landed %s at %s airbase", Element.name, airbase and airbase:GetName() or "unknown")) self:T2(self.lid..string.format("Element landed %s at %s airbase", Element.name, airbase and airbase:GetName() or "unknown"))
-- Set element status.
self:_UpdateStatus(Element, OPSGROUP.ElementStatus.LANDED, airbase)
if self.despawnAfterLanding then -- Helos with skids land directly on parking spots.
if self.isHelo then
-- Despawn the element. local Spot=self:GetParkingSpot(Element, 10, airbase)
self:DespawnElement(Element)
else
-- Set element status.
self:_UpdateStatus(Element, OPSGROUP.ElementStatus.LANDED, airbase)
-- Helos with skids land directly on parking spots.
if self.isHelo then
local Spot=self:GetParkingSpot(Element, 10, airbase)
if Spot then
self:_SetElementParkingAt(Element, Spot)
self:_UpdateStatus(Element, OPSGROUP.ElementStatus.ARRIVED)
end
if Spot then
self:_SetElementParkingAt(Element, Spot)
self:_UpdateStatus(Element, OPSGROUP.ElementStatus.ARRIVED)
end end
end end
-- Despawn after landing.
if self.despawnAfterLanding then
if self.legion then
if airbase and self.legion.airbase and airbase.AirbaseName==self.legion.airbase.AirbaseName then
if self:IsLanded() then
-- Everybody landed ==> Return to legion. Will despawn the last one.
self:ReturnToLegion()
else
-- Despawn the element.
self:DespawnElement(Element)
end
end
else
-- Despawn the element.
self:DespawnElement(Element)
end
end
end end
--- On after "ElementArrived" event. --- On after "ElementArrived" event.
@ -1744,7 +1806,8 @@ function FLIGHTGROUP:onafterArrived(From, Event, To)
self:T(self.lid..string.format("Airwing asset group %s arrived ==> Adding asset back to stock of airwing %s", self.groupname, airwing.alias)) self:T(self.lid..string.format("Airwing asset group %s arrived ==> Adding asset back to stock of airwing %s", self.groupname, airwing.alias))
-- Add the asset back to the airwing. -- Add the asset back to the airwing.
airwing:AddAsset(self.group, 1) --airwing:AddAsset(self.group, 1)
self:ReturnToLegion(1)
elseif self.isLandingAtAirbase then elseif self.isLandingAtAirbase then
@ -2687,6 +2750,16 @@ function FLIGHTGROUP:onafterHolding(From, Event, To)
-- Set holding flag to 0 (just in case). -- Set holding flag to 0 (just in case).
self.flaghold:Set(0) self.flaghold:Set(0)
-- Despawn after holding.
if self.despawnAfterHolding then
if self.legion then
self:ReturnToLegion(1)
else
self:Despawn(1)
end
return
end
-- Holding time stamp. -- Holding time stamp.
self.Tholding=timer.getAbsTime() self.Tholding=timer.getAbsTime()

View File

@ -47,7 +47,7 @@ LEGION = {
--- LEGION class version. --- LEGION class version.
-- @field #string version -- @field #string version
LEGION.version="0.3.1" LEGION.version="0.3.2"
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- ToDo list -- ToDo list
@ -1229,7 +1229,7 @@ function LEGION:onafterNewAsset(From, Event, To, asset, assignment)
end end
-- Set takeoff type. -- Set takeoff type.
asset.takeoffType=cohort.takeoffType asset.takeoffType=cohort.takeoffType~=nil and cohort.takeoffType or self.takeoffType
-- Set parking IDs. -- Set parking IDs.
asset.parkingIDs=cohort.parkingIDs asset.parkingIDs=cohort.parkingIDs
@ -1335,6 +1335,7 @@ function LEGION:onafterAssetSpawned(From, Event, To, group, asset, request)
-- Did not return yet. -- Did not return yet.
asset.Treturned=nil asset.Treturned=nil
--- ---
-- Cohort -- Cohort
--- ---
@ -1360,7 +1361,7 @@ function LEGION:onafterAssetSpawned(From, Event, To, group, asset, request)
if cohort.fuellowRefuel then if cohort.fuellowRefuel then
flightgroup:SetFuelLowRefuel(cohort.fuellowRefuel) flightgroup:SetFuelLowRefuel(cohort.fuellowRefuel)
end end
-- Assignment. -- Assignment.
local assignment=request.assignment local assignment=request.assignment
@ -1379,6 +1380,16 @@ function LEGION:onafterAssetSpawned(From, Event, To, group, asset, request)
-- Get Mission (if any). -- Get Mission (if any).
local mission=self:GetMissionByID(uid) local mission=self:GetMissionByID(uid)
local despawnLanding=cohort.despawnAfterLanding~=nil and cohort.despawnAfterLanding or self.despawnAfterLanding
if despawnLanding then
flightgroup:SetDespawnAfterLanding()
end
local despawnHolding=cohort.despawnAfterHolding~=nil and cohort.despawnAfterHolding or self.despawnAfterHolding
if despawnHolding then
flightgroup:SetDespawnAfterHolding()
end
-- Add mission to flightgroup queue. -- Add mission to flightgroup queue.
if mission then if mission then

View File

@ -90,18 +90,18 @@ NAVYGROUP = {
--- NavyGroup version. --- NavyGroup version.
-- @field #string version -- @field #string version
NAVYGROUP.version="0.7.1" NAVYGROUP.version="0.7.3"
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO list -- TODO list
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO: Add RTZ.
-- TODO: Add Retreat. -- TODO: Add Retreat.
-- TODO: Add EngageTarget.
-- TODO: Submaries. -- TODO: Submaries.
-- TODO: Extend, shorten turn into wind windows. -- TODO: Extend, shorten turn into wind windows.
-- TODO: Skipper menu. -- TODO: Skipper menu.
-- DONE: Add EngageTarget.
-- DONE: Add RTZ.
-- DONE: Collision warning. -- DONE: Collision warning.
-- DONE: Detour, add temporary waypoint and resume route. -- DONE: Detour, add temporary waypoint and resume route.
-- DONE: Stop and resume route. -- DONE: Stop and resume route.
@ -790,17 +790,19 @@ function NAVYGROUP:Status(From, Event, To)
if alive~=nil then if alive~=nil then
if self.verbose>=1 then if self.verbose>=1 then
-- Number of elements.
local nelem=self:CountElements()
local Nelem=#self.elements
-- Get number of tasks and missions. -- Get number of tasks and missions.
local nTaskTot, nTaskSched, nTaskWP=self:CountRemainingTasks() local nTaskTot, nTaskSched, nTaskWP=self:CountRemainingTasks()
local nMissions=self:CountRemainingMissison() local nMissions=self:CountRemainingMissison()
local intowind=self:IsSteamingIntoWind() and UTILS.SecondsToClock(self.intowind.Tstop-timer.getAbsTime(), true) or "N/A"
local turning=tostring(self:IsTurning())
local alt=self.position and self.position.y or 0
local speed=UTILS.MpsToKnots(self.velocity or 0)
local speedExpected=UTILS.MpsToKnots(self:GetExpectedSpeed())
-- ROE and Alarm State.
local roe=self:GetROE() or -1
local als=self:GetAlarmstate() or -1
-- Waypoint stuff. -- Waypoint stuff.
local wpidxCurr=self.currentwp local wpidxCurr=self.currentwp
local wpuidCurr=self:GetWaypointUIDFromIndex(wpidxCurr) or 0 local wpuidCurr=self:GetWaypointUIDFromIndex(wpidxCurr) or 0
@ -808,16 +810,40 @@ function NAVYGROUP:Status(From, Event, To)
local wpuidNext=self:GetWaypointUIDFromIndex(wpidxNext) or 0 local wpuidNext=self:GetWaypointUIDFromIndex(wpidxNext) or 0
local wpN=#self.waypoints or 0 local wpN=#self.waypoints or 0
local wpF=tostring(self.passedfinalwp) local wpF=tostring(self.passedfinalwp)
local wpDist=UTILS.MetersToNM(self:GetDistanceToWaypoint() or 0)
local wpETA=UTILS.SecondsToClock(self:GetTimeToWaypoint() or 0, true)
-- Current ROE and alarm state. -- Speed.
local roe=self:GetROE() or 0 local speed=UTILS.MpsToKnots(self.velocity or 0)
local als=self:GetAlarmstate() or 0 local speedEx=UTILS.MpsToKnots(self:GetExpectedSpeed())
-- Altitude.
local alt=self.position and self.position.y or 0
-- Heading in degrees.
local hdg=self.heading or 0
-- Life points.
local life=self.life or 0
-- Total ammo.
local ammo=self:GetAmmoTot().Total
-- Detected units.
local ndetected=self.detectionOn and tostring(self.detectedunits:Count()) or "OFF"
-- Get cargo weight.
local cargo=0
for _,_element in pairs(self.elements) do
local element=_element --Ops.OpsGroup#OPSGROUP.Element
cargo=cargo+element.weightCargo
end
-- Into wind and turning status.
local intowind=self:IsSteamingIntoWind() and UTILS.SecondsToClock(self.intowind.Tstop-timer.getAbsTime(), true) or "N/A"
local turning=tostring(self:IsTurning())
-- Info text. -- Info text.
local text=string.format("%s [ROE=%d,AS=%d, T/M=%d/%d]: Wp=%d[%d]-->%d[%d] /%d [%s] Dist=%.1f NM ETA=%s - Speed=%.1f (%.1f) kts, Depth=%.1f m, Hdg=%03d, Turn=%s Collision=%d IntoWind=%s", local text=string.format("%s [%d/%d]: ROE/AS=%d/%d | T/M=%d/%d | Wp=%d[%d]-->%d[%d]/%d [%s] | Life=%.1f | v=%.1f (%d) | Hdg=%03d | Ammo=%d | Detect=%s | Cargo=%.1f | Turn=%s Collision=%d IntoWind=%s",
fsmstate, roe, als, nTaskTot, nMissions, wpidxCurr, wpuidCurr, wpidxNext, wpuidNext, wpN, wpF, wpDist, wpETA, speed, speedExpected, alt, self.heading or 0, turning, freepath, intowind) fsmstate, nelem, Nelem, roe, als, nTaskTot, nMissions, wpidxCurr, wpuidCurr, wpidxNext, wpuidNext, wpN, wpF, life, speed, speedEx, hdg, ammo, ndetected, cargo, turning, freepath, intowind)
self:I(self.lid..text) self:I(self.lid..text)
end end

View File

@ -1751,7 +1751,7 @@ end
function OPSGROUP:ReturnToLegion(Delay) function OPSGROUP:ReturnToLegion(Delay)
if Delay and Delay>0 then if Delay and Delay>0 then
self.scheduleIDDespawn=self:ScheduleOnce(Delay, OPSGROUP.ReturnToLegion, self) self:ScheduleOnce(Delay, OPSGROUP.ReturnToLegion, self)
else else
if self.legion then if self.legion then
@ -4115,7 +4115,7 @@ function OPSGROUP:onafterTaskDone(From, Event, To, Task)
--- ---
-- Mission Paused: Do nothing! Just set the current mission to nil so we can launch a new one. -- Mission Paused: Do nothing! Just set the current mission to nil so we can launch a new one.
--- ---
if self.currentmission and self.currentmission==Mission.auftragsnummer then if self:IsOnMission(Mission.auftragsnummer) then
self.currentmission=nil self.currentmission=nil
end end
-- Remove mission waypoints. -- Remove mission waypoints.
@ -4409,9 +4409,23 @@ end
--- Check if group is currently on a mission. --- Check if group is currently on a mission.
-- @param #OPSGROUP self -- @param #OPSGROUP self
-- @return #boolean If `true`, group is currently on a mission -- @param #number MissionUID (Optional) Check if group is currently on a mission with this UID. Default is to check for any current mission.
function OPSGROUP:IsOnMission() -- @return #boolean If `true`, group is currently on a mission.
return self.currentmission~=nil function OPSGROUP:IsOnMission(MissionUID)
if self.currentmission==nil then
-- No current mission.
return false
else
if MissionUID then
-- Return if on specific mission.
return MissionUID==self.currentmission
else
-- Is on any mission.
return true
end
end
-- Is on any mission.
return true
end end
--- On before "MissionStart" event. --- On before "MissionStart" event.
@ -4582,7 +4596,7 @@ end
-- @param Ops.Auftrag#AUFTRAG Mission The mission to be cancelled. -- @param Ops.Auftrag#AUFTRAG Mission The mission to be cancelled.
function OPSGROUP:onafterMissionCancel(From, Event, To, Mission) function OPSGROUP:onafterMissionCancel(From, Event, To, Mission)
if self.currentmission and Mission.auftragsnummer==self.currentmission then if self:IsOnMission(Mission.auftragsnummer) then
--- ---
-- Current Mission -- Current Mission
@ -4661,7 +4675,7 @@ function OPSGROUP:onafterMissionDone(From, Event, To, Mission)
Mission:SetGroupStatus(self, AUFTRAG.GroupStatus.DONE) Mission:SetGroupStatus(self, AUFTRAG.GroupStatus.DONE)
-- Set current mission to nil. -- Set current mission to nil.
if self.currentmission and Mission.auftragsnummer==self.currentmission then if self:IsOnMission(Mission.auftragsnummer) then
self.currentmission=nil self.currentmission=nil
end end
@ -6261,13 +6275,16 @@ function OPSGROUP:Teleport(Coordinate, Delay)
--Coordinate:MarkToAll("Teleport "..self.groupname) --Coordinate:MarkToAll("Teleport "..self.groupname)
-- Check if we have a mission running. -- Check if we have a mission running.
if self.currentmission>0 then if self:IsOnMission() then
self:T(self.lid.."Pausing current mission") self:T(self.lid.."Pausing current mission")
self:PauseMission() self:PauseMission()
end end
-- Get copy of template. -- Get copy of template.
local Template=UTILS.DeepCopy(self.template) --DCS#Template local Template=UTILS.DeepCopy(self.template) --DCS#Template
-- Set late activation of template to current state.
Template.lateActivation=self:IsLateActivated()
-- Template units. -- Template units.
local units=Template.units local units=Template.units

View File

@ -44,8 +44,10 @@
-- @field #table tacanChannel List of TACAN channels available to the squadron. -- @field #table tacanChannel List of TACAN channels available to the squadron.
-- @field #number radioFreq Radio frequency in MHz the squad uses. -- @field #number radioFreq Radio frequency in MHz the squad uses.
-- @field #number radioModu Radio modulation the squad uses. -- @field #number radioModu Radio modulation the squad uses.
-- @field #number takeoffType Take of type. -- @field #string takeoffType Take of type.
-- @field #table parkingIDs Parking IDs for this squadron. -- @field #table parkingIDs Parking IDs for this squadron.
-- @field #boolean despawnAfterLanding Aircraft are despawned after landing.
-- @field #boolean despawnAfterHolding Aircraft are despawned after holding.
-- @extends Ops.Cohort#COHORT -- @extends Ops.Cohort#COHORT
--- *It is unbelievable what a squadron of twelve aircraft did to tip the balance* -- Adolf Galland --- *It is unbelievable what a squadron of twelve aircraft did to tip the balance* -- Adolf Galland
@ -58,8 +60,6 @@
-- --
-- --
-- --
--
--
-- @field #SQUADRON -- @field #SQUADRON
SQUADRON = { SQUADRON = {
ClassName = "SQUADRON", ClassName = "SQUADRON",
@ -74,7 +74,7 @@ SQUADRON = {
--- SQUADRON class version. --- SQUADRON class version.
-- @field #string version -- @field #string version
SQUADRON.version="0.8.0" SQUADRON.version="0.8.1"
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO list -- TODO list
@ -147,7 +147,7 @@ end
--- Set takeoff type. All assets of this squadron will be spawned with cold (default) or hot engines. --- Set takeoff type. All assets of this squadron will be spawned with cold (default) or hot engines.
-- Spawning on runways is not supported. -- Spawning on runways is not supported.
-- @param #SQUADRON self -- @param #SQUADRON self
-- @param #string TakeoffType Take off type: "Cold" (default) or "Hot" with engines on. -- @param #string TakeoffType Take off type: "Cold" (default) or "Hot" with engines on or "Air" for spawning in air.
-- @return #SQUADRON self -- @return #SQUADRON self
function SQUADRON:SetTakeoffType(TakeoffType) function SQUADRON:SetTakeoffType(TakeoffType)
TakeoffType=TakeoffType or "Cold" TakeoffType=TakeoffType or "Cold"
@ -155,6 +155,8 @@ function SQUADRON:SetTakeoffType(TakeoffType)
self.takeoffType=COORDINATE.WaypointType.TakeOffParkingHot self.takeoffType=COORDINATE.WaypointType.TakeOffParkingHot
elseif TakeoffType:lower()=="cold" then elseif TakeoffType:lower()=="cold" then
self.takeoffType=COORDINATE.WaypointType.TakeOffParking self.takeoffType=COORDINATE.WaypointType.TakeOffParking
elseif TakeoffType:lower()=="air" then
self.takeoffType=COORDINATE.WaypointType.TurningPoint
else else
self.takeoffType=COORDINATE.WaypointType.TakeOffParking self.takeoffType=COORDINATE.WaypointType.TakeOffParking
end end
@ -177,6 +179,43 @@ function SQUADRON:SetTakeoffHot()
return self return self
end end
--- Set takeoff type air. All assets of this squadron will be spawned in air above the airbase.
-- @param #SQUADRON self
-- @return #SQUADRON self
function SQUADRON:SetTakeoffAir()
self:SetTakeoffType("Air")
return self
end
--- Set despawn after landing. Aircraft will be despawned after the landing event.
-- Can help to avoid DCS AI taxiing issues.
-- @param #SQUADRON self
-- @param #boolean Switch If `true` (default), activate despawn after landing.
-- @return #SQUADRON self
function SQUADRON:SetDespawnAfterLanding(Switch)
if Switch then
self.despawnAfterLanding=Switch
else
self.despawnAfterLanding=true
end
return self
end
--- Set despawn after holding. Aircraft will be despawned when they arrive at their holding position at the airbase.
-- Can help to avoid DCS AI taxiing issues.
-- @param #SQUADRON self
-- @param #boolean Switch If `true` (default), activate despawn after holding.
-- @return #SQUADRON self
function SQUADRON:SetDespawnAfterHolding(Switch)
if Switch then
self.despawnAfterHolding=Switch
else
self.despawnAfterHolding=true
end
return self
end
--- Set low fuel threshold. --- Set low fuel threshold.
-- @param #SQUADRON self -- @param #SQUADRON self
-- @param #number LowFuel Low fuel threshold in percent. Default 25. -- @param #number LowFuel Low fuel threshold in percent. Default 25.

View File

@ -809,7 +809,7 @@ function UTILS.BeaufortScale(speed)
return bn,bd return bn,bd
end end
--- Split string at seperators. C.f. http://stackoverflow.com/questions/1426954/split-string-in-lua --- Split string at seperators. C.f. [split-string-in-lua](http://stackoverflow.com/questions/1426954/split-string-in-lua).
-- @param #string str Sting to split. -- @param #string str Sting to split.
-- @param #string sep Speparator for split. -- @param #string sep Speparator for split.
-- @return #table Split text. -- @return #table Split text.