Good version solving a few bugs and adding some new stuff.
This commit is contained in:
Frank 2021-08-24 23:10:38 +02:00
parent c6ebbc6122
commit 259b201e65
5 changed files with 185 additions and 94 deletions

View File

@ -225,6 +225,8 @@ do -- COORDINATE
-- @field #string FlyoverPoint Fly over point. -- @field #string FlyoverPoint Fly over point.
-- @field #string FromParkingArea From parking area. -- @field #string FromParkingArea From parking area.
-- @field #string FromParkingAreaHot From parking area hot. -- @field #string FromParkingAreaHot From parking area hot.
-- @field #string FromGroundAreaHot From ground area hot.
-- @field #string FromGroundArea From ground area.
-- @field #string FromRunway From runway. -- @field #string FromRunway From runway.
-- @field #string Landing Landing. -- @field #string Landing Landing.
-- @field #string LandingReFuAr Landing and refuel and rearm. -- @field #string LandingReFuAr Landing and refuel and rearm.
@ -233,6 +235,8 @@ do -- COORDINATE
FlyoverPoint = "Fly Over Point", FlyoverPoint = "Fly Over Point",
FromParkingArea = "From Parking Area", FromParkingArea = "From Parking Area",
FromParkingAreaHot = "From Parking Area Hot", FromParkingAreaHot = "From Parking Area Hot",
FromGroundAreaHot = "From Ground Area Hot",
FromGroundArea = "From Ground Area",
FromRunway = "From Runway", FromRunway = "From Runway",
Landing = "Landing", Landing = "Landing",
LandingReFuAr = "LandingReFuAr", LandingReFuAr = "LandingReFuAr",
@ -243,6 +247,7 @@ do -- COORDINATE
-- @field #string TakeOffParking Take of parking. -- @field #string TakeOffParking Take of parking.
-- @field #string TakeOffParkingHot Take of parking hot. -- @field #string TakeOffParkingHot Take of parking hot.
-- @field #string TakeOff Take off parking hot. -- @field #string TakeOff Take off parking hot.
-- @field #string TakeOffGroundHot Take of from ground hot.
-- @field #string TurningPoint Turning point. -- @field #string TurningPoint Turning point.
-- @field #string Land Landing point. -- @field #string Land Landing point.
-- @field #string LandingReFuAr Landing and refuel and rearm. -- @field #string LandingReFuAr Landing and refuel and rearm.
@ -250,9 +255,11 @@ do -- COORDINATE
TakeOffParking = "TakeOffParking", TakeOffParking = "TakeOffParking",
TakeOffParkingHot = "TakeOffParkingHot", TakeOffParkingHot = "TakeOffParkingHot",
TakeOff = "TakeOffParkingHot", TakeOff = "TakeOffParkingHot",
TakeOffGroundHot = "TakeOffGroundHot",
TakeOffGround = "TakeOffGround",
TurningPoint = "Turning Point", TurningPoint = "Turning Point",
Land = "Land", Land = "Land",
LandingReFuAr = "LandingReFuAr", LandingReFuAr = "LandingReFuAr",
} }

View File

@ -83,7 +83,7 @@ ARMYGROUP.version="0.7.0"
-- @param Wrapper.Group#GROUP group The GROUP object. Can also be given by its group name as `#string`. -- @param Wrapper.Group#GROUP group The GROUP object. Can also be given by its group name as `#string`.
-- @return #ARMYGROUP self -- @return #ARMYGROUP self
function ARMYGROUP:New(group) function ARMYGROUP:New(group)
-- First check if we already have an OPS group for this group. -- First check if we already have an OPS group for this group.
local og=_DATABASE:GetOpsGroup(group) local og=_DATABASE:GetOpsGroup(group)
if og then if og then
@ -91,6 +91,9 @@ function ARMYGROUP:New(group)
return og return og
end end
-- First set ARMYGROUP.
self.isArmygroup=true
-- Inherit everything from FSM class. -- Inherit everything from FSM class.
local self=BASE:Inherit(self, OPSGROUP:New(group)) -- #ARMYGROUP local self=BASE:Inherit(self, OPSGROUP:New(group)) -- #ARMYGROUP
@ -98,7 +101,6 @@ function ARMYGROUP:New(group)
self.lid=string.format("ARMYGROUP %s | ", self.groupname) self.lid=string.format("ARMYGROUP %s | ", self.groupname)
-- Defaults -- Defaults
self.isArmygroup=true
self:SetDefaultROE() self:SetDefaultROE()
self:SetDefaultAlarmstate() self:SetDefaultAlarmstate()
self:SetDetection() self:SetDetection()

View File

@ -208,6 +208,9 @@ function FLIGHTGROUP:New(group)
return og return og
end end
-- First set FLIGHTGROUP.
self.isFlightgroup=true
-- Inherit everything from FSM class. -- Inherit everything from FSM class.
local self=BASE:Inherit(self, OPSGROUP:New(group)) -- #FLIGHTGROUP local self=BASE:Inherit(self, OPSGROUP:New(group)) -- #FLIGHTGROUP
@ -215,7 +218,6 @@ function FLIGHTGROUP:New(group)
self.lid=string.format("FLIGHTGROUP %s | ", self.groupname) self.lid=string.format("FLIGHTGROUP %s | ", self.groupname)
-- Defaults -- Defaults
self.isFlightgroup=true
self:SetFuelLowThreshold() self:SetFuelLowThreshold()
self:SetFuelLowRTB() self:SetFuelLowRTB()
self:SetFuelCriticalThreshold() self:SetFuelCriticalThreshold()
@ -1853,6 +1855,9 @@ function FLIGHTGROUP:onafterArrived(From, Event, To)
-- Check what to do. -- Check what to do.
if airwing then if airwing then
-- Debug info.
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)
@ -2018,6 +2023,9 @@ function FLIGHTGROUP:onbeforeUpdateRoute(From, Event, To, n)
-- For patrol zone, we need to allow the update as we insert new waypoints. -- For patrol zone, we need to allow the update as we insert new waypoints.
elseif task.dcstask.id=="ReconMission" then elseif task.dcstask.id=="ReconMission" then
-- For recon missions, we need to allow the update as we insert new waypoints. -- For recon missions, we need to allow the update as we insert new waypoints.
elseif task.description and task.description=="Task_Land_At" then
-- We allow this
env.info("FF allowing update route for Task_Land_At")
else else
local taskname=task and task.description or "No description" local taskname=task and task.description or "No description"
self:E(self.lid..string.format("WARNING: Update route denied because taskcurrent=%d>0! Task description = %s", self.taskcurrent, tostring(taskname))) self:E(self.lid..string.format("WARNING: Update route denied because taskcurrent=%d>0! Task description = %s", self.taskcurrent, tostring(taskname)))
@ -2075,9 +2083,9 @@ function FLIGHTGROUP:onafterUpdateRoute(From, Event, To, n)
local waypointAction=COORDINATE.WaypointAction.TurningPoint local waypointAction=COORDINATE.WaypointAction.TurningPoint
if self:IsLanded() or self:IsLandedAt() or self:IsAirborne()==false then if self:IsLanded() or self:IsLandedAt() or self:IsAirborne()==false then
-- Had some issues with passing waypoint function of the next WP called too ealy when the type is TurningPoint. Setting it to TakeOff solved it! -- Had some issues with passing waypoint function of the next WP called too ealy when the type is TurningPoint. Setting it to TakeOff solved it!
waypointType=COORDINATE.WaypointType.TakeOff --waypointType=COORDINATE.WaypointType.TakeOff
env.info("FF takeoff type waypoint") waypointType=COORDINATE.WaypointType.TakeOffGroundHot
--waypointAction=COORDINATE.WaypointAction.FromParkingArea waypointAction=COORDINATE.WaypointAction.FromGroundAreaHot
end end
-- Set current waypoint or we get problem that the _PassingWaypoint function is triggered too early, i.e. right now and not when passing the next WP. -- Set current waypoint or we get problem that the _PassingWaypoint function is triggered too early, i.e. right now and not when passing the next WP.
@ -2097,10 +2105,12 @@ function FLIGHTGROUP:onafterUpdateRoute(From, Event, To, n)
self:T(self.lid..string.format("Updating route for WP #%d-%d [%s], homebase=%s destination=%s", n, #wp, self:GetState(), hb, db)) self:T(self.lid..string.format("Updating route for WP #%d-%d [%s], homebase=%s destination=%s", n, #wp, self:GetState(), hb, db))
-- Print waypoints. -- Print waypoints.
--[[
for i,w in pairs(wp) do for i,w in pairs(wp) do
env.info("FF waypoint index="..i) env.info("FF waypoint index="..i)
self:I(w) self:I(w)
end end
]]
if #wp>1 then if #wp>1 then
@ -2164,15 +2174,21 @@ end
-- @param #number waittime Time to wait if group is done. -- @param #number waittime Time to wait if group is done.
function FLIGHTGROUP:_CheckGroupDone(delay, waittime) function FLIGHTGROUP:_CheckGroupDone(delay, waittime)
-- FSM state.
local fsmstate=self:GetState()
if self:IsAlive() and self.isAI then if self:IsAlive() and self.isAI then
if delay and delay>0 then if delay and delay>0 then
-- Debug info.
self:T(self.lid..string.format("Check FLIGHTGROUP [state=%s] done in %.3f seconds...", fsmstate, delay))
-- Delayed call. -- Delayed call.
self:ScheduleOnce(delay, FLIGHTGROUP._CheckGroupDone, self) self:ScheduleOnce(delay, FLIGHTGROUP._CheckGroupDone, self)
else else
-- Debug info. -- Debug info.
self:T(self.lid.."Check FLIGHTGROUP done?") self:T(self.lid..string.format("Check FLIGHTGROUP [state=%s] done?", fsmstate))
-- First check if there is a paused mission that -- First check if there is a paused mission that
if self.missionpaused then if self.missionpaused then
@ -2188,7 +2204,7 @@ function FLIGHTGROUP:_CheckGroupDone(delay, waittime)
-- Group is ordered to land at an airbase. -- Group is ordered to land at an airbase.
if self.isLandingAtAirbase then if self.isLandingAtAirbase then
self:T(self.lid.."Landing at airbase! Group NOT done...") self:T(self.lid..string.format("Landing at airbase %s! Group NOT done...", self.isLandingAtAirbase:GetName()))
return return
end end
@ -2211,7 +2227,7 @@ function FLIGHTGROUP:_CheckGroupDone(delay, waittime)
self:T(self.lid..string.format("Remaining (final=%s): missions=%d, tasks=%d, transports=%d", tostring(self.passedfinalwp), nMissions, nTasks, nTransports)) self:T(self.lid..string.format("Remaining (final=%s): missions=%d, tasks=%d, transports=%d", tostring(self.passedfinalwp), nMissions, nTasks, nTransports))
-- Final waypoint passed? -- Final waypoint passed?
if self.passedfinalwp then if self:HasPassedFinalWaypoint() then
--- ---
-- Final Waypoint PASSED -- Final Waypoint PASSED
@ -2445,6 +2461,7 @@ function FLIGHTGROUP:_LandAtAirbase(airbase, 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) local text=string.format("Flight group set to hold at airbase %s. SpeedTo=%d, SpeedHold=%d, SpeedLand=%d", airbase:GetName(), SpeedTo, SpeedHold, SpeedLand)
self:T(self.lid..text) self:T(self.lid..text)
-- Holding altitude.
local althold=self.isHelo and 1000+math.random(10)*100 or math.random(4,10)*1000 local althold=self.isHelo and 1000+math.random(10)*100 or math.random(4,10)*1000
-- Holding points. -- Holding points.
@ -2481,11 +2498,13 @@ function FLIGHTGROUP:_LandAtAirbase(airbase, SpeedTo, SpeedHold, SpeedLand)
local h1=x1*math.tan(alpha) local h1=x1*math.tan(alpha)
local h2=x2*math.tan(alpha) local h2=x2*math.tan(alpha)
-- Get active runway.
local runway=airbase:GetActiveRunway() local runway=airbase:GetActiveRunway()
-- Set holding flag to 0=false. -- Set holding flag to 0=false.
self.flaghold:Set(0) self.flaghold:Set(0)
-- Set holding time.
local holdtime=2*60 local holdtime=2*60
if fc or self.airboss then if fc or self.airboss then
holdtime=nil holdtime=nil
@ -2557,14 +2576,14 @@ function FLIGHTGROUP:onbeforeWait(From, Event, To, Duration, Altitude, Speed)
local Tsuspend=nil local Tsuspend=nil
-- Check for a current task. -- Check for a current task.
if self.taskcurrent>0 then if self.taskcurrent>0 and not self:IsLandedAt() then
self:I(self.lid..string.format("WARNING: Got current task ==> WAIT event is suspended for 30 sec!")) self:I(self.lid..string.format("WARNING: Got current task ==> WAIT event is suspended for 30 sec!"))
Tsuspend=-30 Tsuspend=-30
allowed=false allowed=false
end end
-- Check for a current transport assignment. -- Check for a current transport assignment.
if self.cargoTransport then if self.cargoTransport and not self:IsLandedAt() then
self:I(self.lid..string.format("WARNING: Got current TRANSPORT assignment ==> WAIT event is suspended for 30 sec!")) self:I(self.lid..string.format("WARNING: Got current TRANSPORT assignment ==> WAIT event is suspended for 30 sec!"))
Tsuspend=-30 Tsuspend=-30
allowed=false allowed=false
@ -2604,14 +2623,6 @@ function FLIGHTGROUP:onafterWait(From, Event, To, Duration, Altitude, Speed)
--TODO: set ROE passive. introduce roe event/state/variable. --TODO: set ROE passive. introduce roe event/state/variable.
-- Orbit task.
local TaskOrbit=self.group:TaskOrbit(Coord, UTILS.FeetToMeters(Altitude), UTILS.KnotsToMps(Speed))
-- Orbit task.
local TaskFunction=self.group:TaskFunction("FLIGHTGROUP._FinishedWaiting", self)
local DCSTasks=self.group:TaskCombo({TaskOrbit, TaskFunction})
-- Orbit until flaghold=1 (true) but max 5 min if no FC is giving the landing clearance. -- Orbit until flaghold=1 (true) but max 5 min if no FC is giving the landing clearance.
local TaskOrbit = self.group:TaskOrbit(Coord, UTILS.FeetToMeters(Altitude), UTILS.KnotsToMps(Speed)) local TaskOrbit = self.group:TaskOrbit(Coord, UTILS.FeetToMeters(Altitude), UTILS.KnotsToMps(Speed))
local TaskStop = self.group:TaskCondition(nil, nil, nil, nil, Duration) local TaskStop = self.group:TaskCondition(nil, nil, nil, nil, Duration)
@ -2842,11 +2853,11 @@ end
-- @param #string Event Event. -- @param #string Event Event.
-- @param #string To To state. -- @param #string To To state.
-- @param Core.Point#COORDINATE Coordinate The coordinate where to land. Default is current position. -- @param Core.Point#COORDINATE Coordinate The coordinate where to land. Default is current position.
-- @param #number Duration The duration in seconds to remain on ground. Default 600 sec (10 min). -- @param #number Duration The duration in seconds to remain on ground. Default `nil` = forever.
function FLIGHTGROUP:onafterLandAt(From, Event, To, Coordinate, Duration) function FLIGHTGROUP:onafterLandAt(From, Event, To, Coordinate, Duration)
-- Duration. -- Duration.
Duration=Duration or 600 --Duration=Duration or 600
Coordinate=Coordinate or self:GetCoordinate() Coordinate=Coordinate or self:GetCoordinate()
@ -2855,7 +2866,7 @@ function FLIGHTGROUP:onafterLandAt(From, Event, To, Coordinate, Duration)
local Task=self:NewTaskScheduled(DCStask, 1, "Task_Land_At", 0) local Task=self:NewTaskScheduled(DCStask, 1, "Task_Land_At", 0)
self:TaskExecute(Task) self:TaskExecute(Task)
end end
--- On after "FuelLow" event. --- On after "FuelLow" event.
@ -3012,7 +3023,7 @@ function FLIGHTGROUP._FinishedWaiting(group, flightgroup)
flightgroup.dTwait=nil flightgroup.dTwait=nil
-- Trigger Holding event. -- Trigger Holding event.
flightgroup:_CheckGroupDone(1) flightgroup:_CheckGroupDone(0.1)
end end
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

View File

@ -114,6 +114,9 @@ function NAVYGROUP:New(group)
return og return og
end end
-- First set NAVYGROUP.
self.isNavygroup=true
-- Inherit everything from FSM class. -- Inherit everything from FSM class.
local self=BASE:Inherit(self, OPSGROUP:New(group)) -- #NAVYGROUP local self=BASE:Inherit(self, OPSGROUP:New(group)) -- #NAVYGROUP
@ -126,7 +129,6 @@ function NAVYGROUP:New(group)
self:SetDefaultAlarmstate() self:SetDefaultAlarmstate()
self:SetPatrolAdInfinitum(true) self:SetPatrolAdInfinitum(true)
self:SetPathfinding(false) self:SetPathfinding(false)
self.isNavygroup=true
-- Add FSM transitions. -- Add FSM transitions.
-- From State --> Event --> To State -- From State --> Event --> To State

View File

@ -18,6 +18,7 @@
-- @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 the group. -- @field #string groupname Name of the group.
-- @field Wrapper.Group#GROUP group Group object. -- @field Wrapper.Group#GROUP group Group object.
-- @field DCS#Controller controller The DCS controller of the group.
-- @field DCS#Template template Template table of the group. -- @field DCS#Template template Template table of the group.
-- @field #boolean isLateActivated Is the group late activated. -- @field #boolean isLateActivated Is the group late activated.
-- @field #boolean isUncontrolled Is the group uncontrolled. -- @field #boolean isUncontrolled Is the group uncontrolled.
@ -513,6 +514,10 @@ function OPSGROUP:New(group)
-- Set the template. -- Set the template.
self:_SetTemplate() self:_SetTemplate()
-- Set DCS group and controller.
self.dcsgroup=self:GetDCSGroup()
self.controller=self.dcsgroup:getController()
-- Init set of detected units. -- Init set of detected units.
self.detectedunits=SET_UNIT:New() self.detectedunits=SET_UNIT:New()
@ -521,6 +526,9 @@ function OPSGROUP:New(group)
-- Init inzone set. -- Init inzone set.
self.inzones=SET_ZONE:New() self.inzones=SET_ZONE:New()
-- Set Default altitude.
self:SetDefaultAltitude()
-- Laser. -- Laser.
self.spot={} self.spot={}
@ -555,7 +563,11 @@ function OPSGROUP:New(group)
self:AddTransition("*", "Destroyed", "*") -- The whole group is dead. self:AddTransition("*", "Destroyed", "*") -- The whole group is dead.
self:AddTransition("*", "Damaged", "*") -- Someone in the group took damage. self:AddTransition("*", "Damaged", "*") -- Someone in the group took damage.
self:AddTransition("*", "UpdateRoute", "*") -- Update route of group. Only if airborne. self:AddTransition("*", "UpdateRoute", "*") -- Update route of group.
self:AddTransition("*", "PassingWaypoint", "*") -- Group passed a waypoint.
self:AddTransition("*", "PassedFinalWaypoint", "*") -- Group passed the waypoint.
self:AddTransition("*", "GotoWaypoint", "*") -- Group switches to a specific waypoint.
self:AddTransition("*", "Wait", "*") -- Group will wait for further orders. self:AddTransition("*", "Wait", "*") -- Group will wait for further orders.
@ -569,9 +581,6 @@ function OPSGROUP:New(group)
self:AddTransition("*", "DetectedGroupKnown", "*") -- A known unit is still detected. self:AddTransition("*", "DetectedGroupKnown", "*") -- A known unit is still detected.
self:AddTransition("*", "DetectedGroupLost", "*") -- Group lost a detected target group. self:AddTransition("*", "DetectedGroupLost", "*") -- Group lost a detected target group.
self:AddTransition("*", "PassingWaypoint", "*") -- Group passed a waypoint.
self:AddTransition("*", "GotoWaypoint", "*") -- Group switches to a specific waypoint.
self:AddTransition("*", "OutOfAmmo", "*") -- Group is completely out of ammo. self:AddTransition("*", "OutOfAmmo", "*") -- Group is completely out of ammo.
self:AddTransition("*", "OutOfGuns", "*") -- Group is out of gun shells. self:AddTransition("*", "OutOfGuns", "*") -- Group is out of gun shells.
self:AddTransition("*", "OutOfRockets", "*") -- Group is out of rockets. self:AddTransition("*", "OutOfRockets", "*") -- Group is out of rockets.
@ -744,7 +753,37 @@ end
-- @param #OPSGROUP self -- @param #OPSGROUP self
-- @return #number Cruise speed (>0) in knots. -- @return #number Cruise speed (>0) in knots.
function OPSGROUP:GetSpeedCruise() function OPSGROUP:GetSpeedCruise()
return UTILS.KmphToKnots(self.speedCruise or self.speedMax*0.7) local speed=UTILS.KmphToKnots(self.speedCruise or self.speedMax*0.7)
return speed
end
--- Set default cruise altitude.
-- @param #OPSGROUP self
-- @param #number Altitude Altitude in feet. Default is 10,000 ft for airplanes and 1,000 feet for helicopters.
-- @return #OPSGROUP self
function OPSGROUP:SetDefaultAltitude(Altitude)
if Altitude then
self.altitudeCruise=UTILS.FeetToMeters(Altitude)
else
if self:IsFlightgroup() then
if self.isHelo then
self.altitudeCruise=UTILS.FeetToMeters(1000)
else
self.altitudeCruise=UTILS.FeetToMeters(10000)
end
else
self.altitudeCruise=0
end
end
return self
end
--- Get default cruise speed.
-- @param #OPSGROUP self
-- @return #number Cruise altitude in feet.
function OPSGROUP:GetCruiseAltitude()
local alt=UTILS.MetersToFeet(self.altitudeCruise)
return alt
end end
--- Set detection on or off. --- Set detection on or off.
@ -2469,8 +2508,8 @@ function OPSGROUP:OnEventBirth(EventData)
if element and element.status~=OPSGROUP.ElementStatus.SPAWNED then if element and element.status~=OPSGROUP.ElementStatus.SPAWNED then
-- Set element to spawned state. We need to delay this. -- Set element to spawned state.
self:__ElementSpawned(0.05, element) self:ElementSpawned(element)
end end
@ -2605,7 +2644,8 @@ function OPSGROUP:SetTask(DCSTask)
end end
-- Set task. -- Set task.
self.group:SetTask(DCSTask) --self.group:SetTask(DCSTask)
self.controller:setTask(DCSTask)
-- Debug info. -- Debug info.
local text=string.format("SETTING Task %s", tostring(DCSTask.id)) local text=string.format("SETTING Task %s", tostring(DCSTask.id))
@ -2629,7 +2669,8 @@ function OPSGROUP:PushTask(DCSTask)
if self:IsAlive() then if self:IsAlive() then
-- Push task. -- Push task.
self.group:PushTask(DCSTask) --self.group:PushTask(DCSTask)
self.controller:pushTask(DCSTask)
-- Debug info. -- Debug info.
local text=string.format("PUSHING Task %s", tostring(DCSTask.id)) local text=string.format("PUSHING Task %s", tostring(DCSTask.id))
@ -3165,8 +3206,8 @@ function OPSGROUP:onafterTaskExecute(From, Event, To, Task)
-- NOTE: I am pushing the task instead of setting it as it seems to keep the mission task alive. -- NOTE: I am pushing the task instead of setting it as it seems to keep the mission task alive.
-- There were issues that flights did not proceed to a later waypoint because the task did not finish until the fired missiles -- There were issues that flights did not proceed to a later waypoint because the task did not finish until the fired missiles
-- impacted (took rather long). Then the flight flew to the nearest airbase and one lost completely the control over the group. -- impacted (took rather long). Then the flight flew to the nearest airbase and one lost completely the control over the group.
--self:PushTask(TaskFinal) self:PushTask(TaskFinal)
self:SetTask(TaskFinal) --self:SetTask(TaskFinal)
elseif Task.type==OPSGROUP.TaskType.WAYPOINT then elseif Task.type==OPSGROUP.TaskType.WAYPOINT then
@ -3312,10 +3353,14 @@ function OPSGROUP:onafterTaskDone(From, Event, To, Task)
if Task.description=="Engage_Target" then if Task.description=="Engage_Target" then
self:Disengage() self:Disengage()
end end
if Task.description=="Task_Land_At" then
self:Wait(60, 100)
else
self:T(self.lid.."Task Done but NO mission found ==> _CheckGroupDone in 0 sec")
self:_CheckGroupDone()
end
--
self:T(self.lid.."Task Done but NO mission found ==> _CheckGroupDone in 0 sec")
self:_CheckGroupDone()
end end
end end
@ -3427,6 +3472,11 @@ function OPSGROUP:CountRemainingTransports()
N=N+1 N=N+1
end end
end end
-- In case we directly set the cargo transport (not in queue).
if N==0 and self.cargoTransport then
N=1
end
return N return N
end end
@ -4295,6 +4345,19 @@ function OPSGROUP:_SetWaypointTasks(Waypoint)
return #taskswp return #taskswp
end end
--- On after "PassedFinalWaypoint" event.
-- @param #OPSGROUP self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
function OPSGROUP:onafterPassedFinalWaypoint(From, Event, To)
self:T(self.lid..string.format("Group passed final waypoint"))
-- Check if group is done? No tasks mission running.
self:_CheckGroupDone()
end
--- On after "GotoWaypoint" event. Group will got to the given waypoint and execute its route from there. --- On after "GotoWaypoint" event. Group will got to the given waypoint and execute its route from there.
-- @param #OPSGROUP self -- @param #OPSGROUP self
-- @param #string From From state. -- @param #string From From state.
@ -5989,7 +6052,7 @@ function OPSGROUP:AddWeightCargo(UnitName, Weight)
-- For airborne units, we set the weight in game. -- For airborne units, we set the weight in game.
if self.isFlightgroup then if self.isFlightgroup then
trigger.action.setUnitInternalCargo(element.name, element.weightCargo) --https://wiki.hoggitworld.com/view/DCS_func_setUnitInternalCargo --trigger.action.setUnitInternalCargo(element.name, element.weightCargo) --https://wiki.hoggitworld.com/view/DCS_func_setUnitInternalCargo
end end
end end
@ -6202,8 +6265,8 @@ function OPSGROUP:onafterPickup(From, Event, To)
if airbaseCurrent then if airbaseCurrent then
-- Activate uncontrolled group. -- Activate uncontrolled group.
if self:IsParking() then if self:IsParking() and self:IsUncontrolled() then
self:StartUncontrolled() self:StartUncontrolled(1)
end end
else else
@ -6220,14 +6283,13 @@ function OPSGROUP:onafterPickup(From, Event, To)
--- ---
-- Activate uncontrolled group. -- Activate uncontrolled group.
if self:IsParking() then if self:IsParking() and self:IsUncontrolled() then
self:StartUncontrolled() self:StartUncontrolled(1)
end end
-- If this is a helo and no ZONE_AIRBASE was given, we make the helo land in the pickup zone. -- If this is a helo and no ZONE_AIRBASE was given, we make the helo land in the pickup zone.
Coordinate:SetAltitude(200) local waypoint=FLIGHTGROUP.AddWaypoint(self, Coordinate, nil, self:GetWaypointCurrent().uid, 200, false) ; waypoint.detour=1
local waypoint=FLIGHTGROUP.AddWaypoint(self, Coordinate) ; waypoint.detour=1
else else
self:E(self.lid.."ERROR: Carrier aircraft cannot land in Pickup zone! Specify a ZONE_AIRBASE as pickup zone") self:E(self.lid.."ERROR: Carrier aircraft cannot land in Pickup zone! Specify a ZONE_AIRBASE as pickup zone")
end end
@ -6486,12 +6548,6 @@ function OPSGROUP:onafterLoaded(From, Event, To)
-- Debug info. -- Debug info.
self:T(self.lid.."Carrier Loaded ==> Transport") self:T(self.lid.."Carrier Loaded ==> Transport")
-- Cancel landedAt task.
if self:IsFlightgroup() and self:IsLandedAt() then
local Task=self:GetTaskCurrent()
self:__TaskCancel(1, Task)
end
-- Order group to transport. -- Order group to transport.
self:__Transport(1) self:__Transport(1)
@ -6588,7 +6644,7 @@ function OPSGROUP:onafterTransport(From, Event, To)
if airbaseCurrent then if airbaseCurrent then
-- Activate uncontrolled group. -- Activate uncontrolled group.
if self:IsParking() then if self:IsParking() and self:IsUncontrolled() then
self:StartUncontrolled() self:StartUncontrolled()
end end
@ -6597,16 +6653,22 @@ function OPSGROUP:onafterTransport(From, Event, To)
self:LandAtAirbase(airbaseDeploy) self:LandAtAirbase(airbaseDeploy)
end end
elseif self.isHelo or self.isVTOL then elseif self.isHelo then
--- ---
-- Helo or VTOL can also land in a zone -- Helo can also land in a zone
--- ---
-- If this is a helo and no ZONE_AIRBASE was given, we make the helo land in the pickup zone. -- If this is a helo and no ZONE_AIRBASE was given, we make the helo land in the pickup zone.
Coordinate:MarkToAll("landing",ReadOnly,Text) local waypoint=FLIGHTGROUP.AddWaypoint(self, Coordinate, nil, self:GetWaypointCurrent().uid, 200, false) ; waypoint.detour=1
env.info("FF helo add waypoint detour")
local waypoint=FLIGHTGROUP.AddWaypoint(self, Coordinate, nil, self:GetWaypointCurrent().uid, 200) ; waypoint.detour=1 -- Cancel landedAt task. This should trigger Cruise once airborne.
if self:IsFlightgroup() and self:IsLandedAt() then
local Task=self:GetTaskCurrent()
--if Task and Task.description=="Task_Landed_At" then
self:__TaskCancel(5, Task)
--end
end
else else
self:E(self.lid.."ERROR: Carrier aircraft cannot land in Deploy zone! Specify a ZONE_AIRBASE as deploy zone") self:E(self.lid.."ERROR: Carrier aircraft cannot land in Deploy zone! Specify a ZONE_AIRBASE as deploy zone")
@ -7064,7 +7126,7 @@ function OPSGROUP:onafterBoard(From, Event, To, CarrierGroup, Carrier)
self:ClearWaypoints(self.currentwp+1) self:ClearWaypoints(self.currentwp+1)
if self.isArmygroup then if self.isArmygroup then
local waypoint=ARMYGROUP.AddWaypoint(self, Coordinate) ; waypoint.detour=1 local waypoint=ARMYGROUP.AddWaypoint(self, Coordinate, nil, nil, ENUMS.Formation.Vehicle.Diamond) ; waypoint.detour=1
self:Cruise() self:Cruise()
else else
local waypoint=NAVYGROUP.AddWaypoint(self, Coordinate) ; waypoint.detour=1 local waypoint=NAVYGROUP.AddWaypoint(self, Coordinate) ; waypoint.detour=1
@ -7344,7 +7406,7 @@ function OPSGROUP:_CheckGroupDone(delay)
-- Finite Patrol -- Finite Patrol
--- ---
if self.passedfinalwp then if self:HasPassedFinalWaypoint() then
--- ---
-- Passed FINAL waypoint -- Passed FINAL waypoint
@ -7758,20 +7820,6 @@ function OPSGROUP:_InitWaypoints(WpIndexMin, WpIndexMax)
self:_AddWaypoint(waypoint) self:_AddWaypoint(waypoint)
-- Add waypoint.
--[[
if self:IsFlightgroup() then
FLIGHTGROUP.AddWaypoint(self, coordinate, speedknots, index-1, Altitude, false)
elseif self:IsArmygroup() then
ARMYGROUP.AddWaypoint(self, coordinate, speedknots, index-1, Formation, false)
elseif self:IsNavygroup() then
NAVYGROUP.AddWaypoint(self, coordinate, speedknots, index-1, Depth, false)
else
-- Should not happen!
self:AddWaypoint(coordinate, speedknots, index-1, nil, false)
end
]]
end end
-- Debug info. -- Debug info.
@ -7822,25 +7870,15 @@ function OPSGROUP:Route(waypoints, delay)
if self:IsAlive() then if self:IsAlive() then
-- DCS task combo. -- Clear all DCS tasks.
local Tasks={} --self:ClearTasks()
self:ClearTasks(DCSTask)
-- Route (Mission) task. -- Route (Mission) task.
local TaskRoute=self.group:TaskRoute(waypoints) local TaskRoute=self.group:TaskRoute(waypoints)
table.insert(Tasks, TaskRoute)
-- TaskCombo of enroute and mission tasks.
local TaskCombo=self.group:TaskCombo(Tasks)
-- Set tasks.
if #Tasks>1 then
self:SetTask(TaskCombo)
else
self:SetTask(TaskRoute)
end
-- Set mission task.
self:SetTask(TaskRoute)
else else
self:E(self.lid.."ERROR: Group is not alive! Cannot route group.") self:E(self.lid.."ERROR: Group is not alive! Cannot route group.")
end end
@ -7947,6 +7985,10 @@ function OPSGROUP._PassingWaypoint(group, opsgroup, uid)
-- Trigger PassingWaypoint event. -- Trigger PassingWaypoint event.
if waypoint.temp then if waypoint.temp then
---
-- Temporary Waypoint
---
if opsgroup:IsNavygroup() or opsgroup:IsArmygroup() then if opsgroup:IsNavygroup() or opsgroup:IsArmygroup() then
--TODO: not sure if this works with FLIGHTGROUPS --TODO: not sure if this works with FLIGHTGROUPS
@ -7955,11 +7997,19 @@ function OPSGROUP._PassingWaypoint(group, opsgroup, uid)
elseif waypoint.astar then elseif waypoint.astar then
---
-- Pathfinding Waypoint
---
-- Cruise. -- Cruise.
opsgroup:Cruise() opsgroup:Cruise()
elseif waypoint.detour then elseif waypoint.detour then
---
-- Detour Waypoint
---
if opsgroup:IsRearming() then if opsgroup:IsRearming() then
-- Trigger Rearming event. -- Trigger Rearming event.
@ -7977,16 +8027,19 @@ function OPSGROUP._PassingWaypoint(group, opsgroup, uid)
elseif opsgroup:IsPickingup() then elseif opsgroup:IsPickingup() then
if opsgroup.isFlightgroup then if opsgroup:IsFlightgroup() then
-- Land at current pos and wait for 60 min max. -- Land at current pos and wait for 60 min max.
env.info("FF LandAt for Pickup") env.info("FF LandAt for Pickup")
opsgroup:LandAt(opsgroup:GetCoordinate(), 60*60) --opsgroup:LandAt(opsgroup:GetCoordinate(), 60*60)
opsgroup:LandAt(opsgroup.cargoTransport.pickupzone:GetCoordinate(), 60*60)
else else
-- Wait and load cargo. -- Wait and load cargo.
opsgroup:FullStop() opsgroup:FullStop()
opsgroup:__Loading(-5) opsgroup:__Loading(-5)
end end
elseif opsgroup:IsTransporting() then elseif opsgroup:IsTransporting() then
@ -8044,6 +8097,10 @@ function OPSGROUP._PassingWaypoint(group, opsgroup, uid)
end end
else else
---
-- Normal Route Waypoint
---
-- Check if the group is still pathfinding. -- Check if the group is still pathfinding.
if opsgroup.ispathfinding then if opsgroup.ispathfinding then
@ -8858,7 +8915,15 @@ function OPSGROUP:_AllSimilarStatus(status)
-- ALIVE -- ALIVE
---------- ----------
if status==OPSGROUP.ElementStatus.SPAWNED then if status==OPSGROUP.ElementStatus.INUTERO then
-- Element INUTERO: Check that ALL others are also INUTERO
if element.status~=status then
return false
end
elseif status==OPSGROUP.ElementStatus.SPAWNED then
-- Element SPAWNED: Check that others are not still IN UTERO -- Element SPAWNED: Check that others are not still IN UTERO
if element.status~=status and if element.status~=status and
@ -9568,6 +9633,10 @@ function OPSGROUP:_PassedFinalWaypoint(final, comment)
-- Debug info. -- Debug info.
self:T(self.lid..string.format("Passed final waypoint=%s [from %s]: comment \"%s\"", tostring(final), tostring(self.passedfinalwp), tostring(comment))) self:T(self.lid..string.format("Passed final waypoint=%s [from %s]: comment \"%s\"", tostring(final), tostring(self.passedfinalwp), tostring(comment)))
if final==true and not self.passedfinalwp then
self:PassedFinalWaypoint()
end
-- Set value. -- Set value.
self.passedfinalwp=final self.passedfinalwp=final
end end