Optimized the boarding and unboarding of cargo. fixed bug when in defence of APC, cargo would not be loaded. The boarding and unboarding has become much more stable now.

This commit is contained in:
FlightControl 2018-10-18 07:27:09 +02:00
parent 3c1547bd6c
commit 07d666b030
7 changed files with 187 additions and 151 deletions

View File

@ -307,7 +307,7 @@ function AI_CARGO:onafterBoard( Carrier, From, Event, To, Cargo, CarrierUnit, Pi
if Carrier and Carrier:IsAlive() then if Carrier and Carrier:IsAlive() then
self:F({ IsLoaded = Cargo:IsLoaded(), Cargo:GetName(), Carrier:GetName() } ) self:F({ IsLoaded = Cargo:IsLoaded(), Cargo:GetName(), Carrier:GetName() } )
if not Cargo:IsLoaded() then if not Cargo:IsLoaded() and not Cargo:IsDestroyed() then
self:__Board( -10, Cargo, CarrierUnit, PickupZone ) self:__Board( -10, Cargo, CarrierUnit, PickupZone )
return return
end end
@ -487,6 +487,7 @@ function AI_CARGO:onafterDeployed( Carrier, From, Event, To, DeployZone, Defend
self.Transporting = false self.Transporting = false
else else
self:F( "Defending" ) self:F( "Defending" )
end end
end end

View File

@ -276,34 +276,36 @@ function AI_CARGO_APC:onafterMonitor( APC, From, Event, To )
if self.CarrierCoordinate then if self.CarrierCoordinate then
if self:IsTransporting() == true then if self:IsTransporting() == true then
local Coordinate = APC:GetCoordinate() local Coordinate = APC:GetCoordinate()
self.Zone:Scan( { Object.Category.UNIT } ) if self:Is( "Unloaded" ) or self:Is( "Loaded" ) then
if self.Zone:IsAllInZoneOfCoalition( self.Coalition ) then self.Zone:Scan( { Object.Category.UNIT } )
if self:Is( "Unloaded" ) or self:Is( "Following" ) then if self.Zone:IsAllInZoneOfCoalition( self.Coalition ) then
-- There are no enemies within combat radius. Load the CargoCarrier.
self:Load()
end
else
if self:Is( "Loaded" ) then
-- There are enemies within combat radius. Unload the CargoCarrier.
self:__Unload( 1, nil, true ) -- The 2nd parameter is true, which means that the unload is for defending the carrier, not to deploy!
else
if self:Is( "Unloaded" ) then if self:Is( "Unloaded" ) then
self:Follow() -- There are no enemies within combat radius. Load the CargoCarrier.
self:Load()
end end
self:F( "I am here" .. self:GetCurrentState() ) else
if self:Is( "Following" ) then if self:Is( "Loaded" ) then
for Cargo, APCUnit in pairs( self.Carrier_Cargo ) do -- There are enemies within combat radius. Unload the CargoCarrier.
local Cargo = Cargo -- Cargo.Cargo#CARGO self:__Unload( 1, nil, true ) -- The 2nd parameter is true, which means that the unload is for defending the carrier, not to deploy!
local APCUnit = APCUnit -- Wrapper.Unit#UNIT else
if Cargo:IsAlive() then if self:Is( "Unloaded" ) then
if not Cargo:IsNear( APCUnit, 40 ) then --self:Follow()
APCUnit:RouteStop() end
self.CarrierStopped = true self:F( "I am here" .. self:GetCurrentState() )
else if self:Is( "Following" ) then
if self.CarrierStopped then for Cargo, APCUnit in pairs( self.Carrier_Cargo ) do
if Cargo:IsNear( APCUnit, 25 ) then local Cargo = Cargo -- Cargo.Cargo#CARGO
APCUnit:RouteResume() local APCUnit = APCUnit -- Wrapper.Unit#UNIT
self.CarrierStopped = nil if Cargo:IsAlive() then
if not Cargo:IsNear( APCUnit, 40 ) then
APCUnit:RouteStop()
self.CarrierStopped = true
else
if self.CarrierStopped then
if Cargo:IsNear( APCUnit, 25 ) then
APCUnit:RouteResume()
self.CarrierStopped = nil
end
end end
end end
end end
@ -455,6 +457,30 @@ function AI_CARGO_APC:onafterDeployed( APC, From, Event, To, DeployZone, Defend
self:__Guard( 0.1 ) self:__Guard( 0.1 )
self:GetParent( self, AI_CARGO_APC ).onafterDeployed( self, APC, From, Event, To, DeployZone, Defend ) self:GetParent( self, AI_CARGO_APC ).onafterDeployed( self, APC, From, Event, To, DeployZone, Defend )
-- If Defend == true then we need to scan for possible enemies within combat zone and engage only ground forces.
if Defend == true then
self.Zone:Scan( { Object.Category.UNIT } )
if not self.Zone:IsAllInZoneOfCoalition( self.Coalition ) then
-- OK, enemies nearby, now find the enemies and attack them.
local AttackUnits = self.Zone:GetScannedUnits() -- #list<DCS#Unit>
local Move = {}
for CargoId, CargoData in pairs( self.CargoSet:GetSet() ) do
local CargoGroup = CargoData.CargoObject -- Wrapper.Group#GROUP
Move[#Move+1] = CargoGroup:GetCoordinate():WaypointGround( 70, "Custom" )
for UnitId, AttackUnit in pairs( AttackUnits ) do
local MooseUnit = UNIT:Find( AttackUnit )
if MooseUnit:GetCoalition() ~= CargoGroup:GetCoalition() then
Move[#Move+1] = MooseUnit:GetCoordinate():WaypointGround( 70, "Line abreast" )
--MoveTo.Task = CargoGroup:TaskCombo( CargoGroup:TaskAttackUnit( MooseUnit, true ) )
self:F( { MooseUnit = MooseUnit:GetName(), CargoGroup = CargoGroup:GetName() } )
end
end
CargoGroup:RoutePush( Move, 0.1 )
end
end
end
end end

View File

@ -1143,7 +1143,7 @@ function AI_CARGO_DISPATCHER:onafterMonitor()
LargestLoadCapacity = LoadCapacity LargestLoadCapacity = LoadCapacity
end end
end end
-- So if there is aa carrier that has the required load capacity to load the total weight of the cargo, dispatch the carrier. -- So if there is a carrier that has the required load capacity to load the total weight of the cargo, dispatch the carrier.
-- Otherwise break and go to the next carrier. -- Otherwise break and go to the next carrier.
-- This will skip cargo which is too large to be able to be loaded by carriers -- This will skip cargo which is too large to be able to be loaded by carriers
-- and will secure an efficient dispatching scheme. -- and will secure an efficient dispatching scheme.

View File

@ -20,9 +20,9 @@
do -- CARGO_GROUP do -- CARGO_GROUP
--- @type CARGO_GROUP --- @type CARGO_GROUP
-- @extends Cargo.Cargo#CARGO_REPORTABLE
-- @field Core.Set#SET_CARGO CargoSet The collection of derived CARGO objects. -- @field Core.Set#SET_CARGO CargoSet The collection of derived CARGO objects.
-- @field #string GroupName The name of the CargoGroup. -- @field #string GroupName The name of the CargoGroup.
-- @extends Cargo.Cargo#CARGO_REPORTABLE
--- Defines a cargo that is represented by a @{Wrapper.Group} object within the simulator. --- Defines a cargo that is represented by a @{Wrapper.Group} object within the simulator.
-- The cargo can be Loaded, UnLoaded, Boarded, UnBoarded to and from Carriers. -- The cargo can be Loaded, UnLoaded, Boarded, UnBoarded to and from Carriers.
@ -291,29 +291,27 @@ do -- CARGO_GROUP
end end
--- Enter Boarding State. --- After Board Event.
-- @param #CARGO_GROUP self -- @param #CARGO_GROUP self
-- @param #string Event -- @param #string Event
-- @param #string From -- @param #string From
-- @param #string To -- @param #string To
-- @param Wrapper.Unit#UNIT CargoCarrier -- @param Wrapper.Unit#UNIT CargoCarrier
-- @param #number NearRadius If distance is smaller than this number, cargo is loaded into the carrier. -- @param #number NearRadius If distance is smaller than this number, cargo is loaded into the carrier.
function CARGO_GROUP:onenterBoarding( From, Event, To, CargoCarrier, NearRadius, ... ) function CARGO_GROUP:onafterBoard( From, Event, To, CargoCarrier, NearRadius, ... )
self:F( { CargoCarrier.UnitName, From, Event, To, NearRadius = NearRadius } ) self:F( { CargoCarrier.UnitName, From, Event, To, NearRadius = NearRadius } )
NearRadius = NearRadius or self.NearRadius NearRadius = NearRadius or self.NearRadius
if From == "UnLoaded" then -- For each Cargo object within the CARGO_GROUPED, route each object to the CargoLoadPointVec2
self.CargoSet:ForEach(
-- For each Cargo object within the CARGO_GROUPED, route each object to the CargoLoadPointVec2 function( Cargo, ... )
self.CargoSet:ForEach( self:F( { "Board Unit", Cargo:GetName( ), Cargo:IsDestroyed(), Cargo.CargoObject:IsAlive() } )
function( Cargo, ... ) Cargo:__Board( 1, CargoCarrier, NearRadius, ... )
Cargo:__Board( 1, CargoCarrier, NearRadius, ... ) end, ...
end, ... )
)
self:__Boarding( -1, CargoCarrier, NearRadius, ... )
self:__Boarding( 1, CargoCarrier, NearRadius, ... )
end
end end
@ -323,13 +321,15 @@ do -- CARGO_GROUP
-- @param #string From -- @param #string From
-- @param #string To -- @param #string To
-- @param Wrapper.Unit#UNIT CargoCarrier -- @param Wrapper.Unit#UNIT CargoCarrier
function CARGO_GROUP:onenterLoaded( From, Event, To, CargoCarrier, ... ) function CARGO_GROUP:onafterLoad( From, Event, To, CargoCarrier, ... )
--self:F( { From, Event, To, CargoCarrier, ...} ) --self:F( { From, Event, To, CargoCarrier, ...} )
if From == "UnLoaded" then if From == "UnLoaded" then
-- For each Cargo object within the CARGO_GROUP, load each cargo to the CargoCarrier. -- For each Cargo object within the CARGO_GROUP, load each cargo to the CargoCarrier.
for CargoID, Cargo in pairs( self.CargoSet:GetSet() ) do for CargoID, Cargo in pairs( self.CargoSet:GetSet() ) do
Cargo:Load( CargoCarrier ) if not Cargo:IsDestroyed() then
Cargo:Load( CargoCarrier )
end
end end
end end
@ -360,7 +360,7 @@ do -- CARGO_GROUP
--self:T( { Cargo:GetName(), Cargo.current } ) --self:T( { Cargo:GetName(), Cargo.current } )
if not Cargo:is( "Loaded" ) if not Cargo:is( "Loaded" )
and (not Cargo:is( "Destroyed" )) then -- If one or more units of a group defined as CARGO_GROUP died, the CARGO_GROUP:Board() command does not trigger the CARGO_GRUOP:OnEnterLoaded() function. and (not Cargo:is( "Destroyed" )) then -- If one or more units of a group defined as CARGO_GROUP died, the CARGO_GROUP:Board() command does not trigger the CARGO_GRUOP:OnEnterLoaded() function.
Boarded = false Boarded = false
end end
@ -400,7 +400,7 @@ do -- CARGO_GROUP
-- @param #string To -- @param #string To
-- @param Core.Point#POINT_VEC2 ToPointVec2 -- @param Core.Point#POINT_VEC2 ToPointVec2
-- @param #number NearRadius If distance is smaller than this number, cargo is loaded into the carrier. -- @param #number NearRadius If distance is smaller than this number, cargo is loaded into the carrier.
function CARGO_GROUP:onenterUnBoarding( From, Event, To, ToPointVec2, NearRadius, ... ) function CARGO_GROUP:onafterUnBoard( From, Event, To, ToPointVec2, NearRadius, ... )
self:F( {From, Event, To, ToPointVec2, NearRadius } ) self:F( {From, Event, To, ToPointVec2, NearRadius } )
NearRadius = NearRadius or 25 NearRadius = NearRadius or 25
@ -443,7 +443,7 @@ do -- CARGO_GROUP
-- @param #string To -- @param #string To
-- @param Core.Point#POINT_VEC2 ToPointVec2 -- @param Core.Point#POINT_VEC2 ToPointVec2
-- @param #number NearRadius If distance is smaller than this number, cargo is loaded into the carrier. -- @param #number NearRadius If distance is smaller than this number, cargo is loaded into the carrier.
function CARGO_GROUP:onleaveUnBoarding( From, Event, To, ToPointVec2, NearRadius, ... ) function CARGO_GROUP:onafterUnBoarding( From, Event, To, ToPointVec2, NearRadius, ... )
--self:F( { From, Event, To, ToPointVec2, NearRadius } ) --self:F( { From, Event, To, ToPointVec2, NearRadius } )
--local NearRadius = NearRadius or 25 --local NearRadius = NearRadius or 25
@ -464,7 +464,7 @@ do -- CARGO_GROUP
end end
if UnBoarded then if UnBoarded then
return true self:__UnLoad( 1, ToPointVec2, ... )
else else
self:__UnBoarding( 1, ToPointVec2, NearRadius, ... ) self:__UnBoarding( 1, ToPointVec2, NearRadius, ... )
end end
@ -474,30 +474,13 @@ do -- CARGO_GROUP
end end
--- UnBoard Event.
-- @param #CARGO_GROUP self
-- @param #string Event
-- @param #string From
-- @param #string To
-- @param Core.Point#POINT_VEC2 ToPointVec2
-- @param #number NearRadius If distance is smaller than this number, cargo is loaded into the carrier.
function CARGO_GROUP:onafterUnBoarding( From, Event, To, ToPointVec2, NearRadius, ... )
--self:F( { From, Event, To, ToPointVec2, NearRadius } )
--local NearRadius = NearRadius or 25
self:__UnLoad( 1, ToPointVec2, ... )
end
--- Enter UnLoaded State. --- Enter UnLoaded State.
-- @param #CARGO_GROUP self -- @param #CARGO_GROUP self
-- @param #string Event -- @param #string Event
-- @param #string From -- @param #string From
-- @param #string To -- @param #string To
-- @param Core.Point#POINT_VEC2 -- @param Core.Point#POINT_VEC2
function CARGO_GROUP:onenterUnLoaded( From, Event, To, ToPointVec2, ... ) function CARGO_GROUP:onafterUnLoad( From, Event, To, ToPointVec2, ... )
--self:F( { From, Event, To, ToPointVec2 } ) --self:F( { From, Event, To, ToPointVec2 } )
if From == "Loaded" then if From == "Loaded" then
@ -507,7 +490,7 @@ do -- CARGO_GROUP
function( Cargo ) function( Cargo )
--Cargo:UnLoad( ToPointVec2 ) --Cargo:UnLoad( ToPointVec2 )
local RandomVec2=ToPointVec2:GetRandomPointVec2InRadius(20, 10) local RandomVec2=ToPointVec2:GetRandomPointVec2InRadius(20, 10)
Cargo:UnLoad( RandomVec2 ) Cargo:UnBoard( RandomVec2 )
end end
) )

View File

@ -233,46 +233,47 @@ do -- CARGO_UNIT
--self:F({Unit=self.CargoObject:GetName()}) --self:F({Unit=self.CargoObject:GetName()})
-- Only move the group to the carrier when the cargo is not in the air -- A cargo unit can only be boarded if it is not dead
-- (eg. cargo can be on a oil derrick, moving the cargo on the oil derrick will drop the cargo on the sea).
if not self.CargoInAir then -- Only move the group to the carrier when the cargo is not in the air
-- If NearRadius is given, then use the given NearRadius, otherwise calculate the NearRadius -- (eg. cargo can be on a oil derrick, moving the cargo on the oil derrick will drop the cargo on the sea).
-- based upon the Carrier bounding radius, which is calculated from the bounding rectangle on the Y axis. if not self.CargoInAir then
local NearRadius = NearRadius or CargoCarrier:GetBoundingRadius() + 5 -- If NearRadius is given, then use the given NearRadius, otherwise calculate the NearRadius
if self:IsNear( CargoCarrier:GetPointVec2(), NearRadius ) then -- based upon the Carrier bounding radius, which is calculated from the bounding rectangle on the Y axis.
self:Load( CargoCarrier, NearRadius, ... ) local NearRadius = NearRadius or CargoCarrier:GetBoundingRadius() + 5
else if self:IsNear( CargoCarrier:GetPointVec2(), NearRadius ) then
if MaxSpeed and MaxSpeed == 0 or TypeName and TypeName == "Stinger comm" then
self:Load( CargoCarrier, NearRadius, ... ) self:Load( CargoCarrier, NearRadius, ... )
else else
if MaxSpeed and MaxSpeed == 0 or TypeName and TypeName == "Stinger comm" then
self:Load( CargoCarrier, NearRadius, ... )
else
local Speed = 90
local Angle = 180
local Distance = 0
local CargoCarrierPointVec2 = CargoCarrier:GetPointVec2()
local CargoCarrierHeading = CargoCarrier:GetHeading() -- Get Heading of object in degrees.
local CargoDeployHeading = ( ( CargoCarrierHeading + Angle ) >= 360 ) and ( CargoCarrierHeading + Angle - 360 ) or ( CargoCarrierHeading + Angle )
local CargoDeployPointVec2 = CargoCarrierPointVec2:Translate( Distance, CargoDeployHeading )
-- Set the CargoObject to state Green to ensure it is boarding!
self.CargoObject:OptionAlarmStateGreen()
local Points = {}
local Speed = 90 local PointStartVec2 = self.CargoObject:GetPointVec2()
local Angle = 180
local Distance = 0
local CargoCarrierPointVec2 = CargoCarrier:GetPointVec2() Points[#Points+1] = PointStartVec2:WaypointGround( Speed )
local CargoCarrierHeading = CargoCarrier:GetHeading() -- Get Heading of object in degrees. Points[#Points+1] = CargoDeployPointVec2:WaypointGround( Speed )
local CargoDeployHeading = ( ( CargoCarrierHeading + Angle ) >= 360 ) and ( CargoCarrierHeading + Angle - 360 ) or ( CargoCarrierHeading + Angle )
local CargoDeployPointVec2 = CargoCarrierPointVec2:Translate( Distance, CargoDeployHeading ) local TaskRoute = self.CargoObject:TaskRoute( Points )
self.CargoObject:SetTask( TaskRoute, 2 )
-- Set the CargoObject to state Green to ensure it is boarding! self:__Boarding( -5, CargoCarrier, NearRadius, ... )
self.CargoObject:OptionAlarmStateGreen() self.RunCount = 0
end
local Points = {}
local PointStartVec2 = self.CargoObject:GetPointVec2()
Points[#Points+1] = PointStartVec2:WaypointGround( Speed )
Points[#Points+1] = CargoDeployPointVec2:WaypointGround( Speed )
local TaskRoute = self.CargoObject:TaskRoute( Points )
self.CargoObject:SetTask( TaskRoute, 2 )
self:__Boarding( -5, CargoCarrier, NearRadius, ... )
self.RunCount = 0
end end
end end
end
end end
@ -286,53 +287,53 @@ do -- CARGO_UNIT
function CARGO_UNIT:onafterBoarding( From, Event, To, CargoCarrier, NearRadius, ... ) function CARGO_UNIT:onafterBoarding( From, Event, To, CargoCarrier, NearRadius, ... )
self:F( { From, Event, To, CargoCarrier:GetName(), NearRadius = NearRadius } ) self:F( { From, Event, To, CargoCarrier:GetName(), NearRadius = NearRadius } )
--self:F({Unit=self.CargoObject:GetName()}) self:F( { IsAlive=self.CargoObject:IsAlive() } )
if CargoCarrier and CargoCarrier:IsAlive() then -- and self.CargoObject and self.CargoObject:IsAlive() then if CargoCarrier and CargoCarrier:IsAlive() then -- and self.CargoObject and self.CargoObject:IsAlive() then
if (CargoCarrier:IsAir() and not CargoCarrier:InAir()) or true then if (CargoCarrier:IsAir() and not CargoCarrier:InAir()) or true then
local NearRadius = NearRadius or CargoCarrier:GetBoundingRadius( NearRadius ) + 5 local NearRadius = NearRadius or CargoCarrier:GetBoundingRadius( NearRadius ) + 5
if self:IsNear( CargoCarrier:GetPointVec2(), NearRadius ) then if self:IsNear( CargoCarrier:GetPointVec2(), NearRadius ) then
self:__Load( 1, CargoCarrier, ... ) self:__Load( -1, CargoCarrier, ... )
else
if self:IsNear( CargoCarrier:GetPointVec2(), 20 ) then
self:__Boarding( 1, CargoCarrier, NearRadius, ... )
self.RunCount = self.RunCount + 1
else else
self:__Boarding( 2, CargoCarrier, NearRadius, ... ) if self:IsNear( CargoCarrier:GetPointVec2(), 20 ) then
self.RunCount = self.RunCount + 2 self:__Boarding( -1, CargoCarrier, NearRadius, ... )
end self.RunCount = self.RunCount + 1
if self.RunCount >= 40 then else
self.RunCount = 0 self:__Boarding( -2, CargoCarrier, NearRadius, ... )
local Speed = 90 self.RunCount = self.RunCount + 2
local Angle = 180 end
local Distance = 0 if self.RunCount >= 40 then
self.RunCount = 0
local Speed = 90
local Angle = 180
local Distance = 0
--self:F({Unit=self.CargoObject:GetName()})
local CargoCarrierPointVec2 = CargoCarrier:GetPointVec2()
local CargoCarrierHeading = CargoCarrier:GetHeading() -- Get Heading of object in degrees.
local CargoDeployHeading = ( ( CargoCarrierHeading + Angle ) >= 360 ) and ( CargoCarrierHeading + Angle - 360 ) or ( CargoCarrierHeading + Angle )
local CargoDeployPointVec2 = CargoCarrierPointVec2:Translate( Distance, CargoDeployHeading )
--self:F({Unit=self.CargoObject:GetName()}) -- Set the CargoObject to state Green to ensure it is boarding!
self.CargoObject:OptionAlarmStateGreen()
local CargoCarrierPointVec2 = CargoCarrier:GetPointVec2()
local CargoCarrierHeading = CargoCarrier:GetHeading() -- Get Heading of object in degrees. local Points = {}
local CargoDeployHeading = ( ( CargoCarrierHeading + Angle ) >= 360 ) and ( CargoCarrierHeading + Angle - 360 ) or ( CargoCarrierHeading + Angle )
local CargoDeployPointVec2 = CargoCarrierPointVec2:Translate( Distance, CargoDeployHeading ) local PointStartVec2 = self.CargoObject:GetPointVec2()
-- Set the CargoObject to state Green to ensure it is boarding! Points[#Points+1] = PointStartVec2:WaypointGround( Speed, "Off road" )
self.CargoObject:OptionAlarmStateGreen() Points[#Points+1] = CargoDeployPointVec2:WaypointGround( Speed, "Off road" )
local Points = {} local TaskRoute = self.CargoObject:TaskRoute( Points )
self.CargoObject:SetTask( TaskRoute, 0.2 )
local PointStartVec2 = self.CargoObject:GetPointVec2() end
Points[#Points+1] = PointStartVec2:WaypointGround( Speed, "Off road" )
Points[#Points+1] = CargoDeployPointVec2:WaypointGround( Speed, "Off road" )
local TaskRoute = self.CargoObject:TaskRoute( Points )
self.CargoObject:SetTask( TaskRoute, 0.2 )
end end
else
self.CargoObject:MessageToGroup( "Cancelling Boarding... Get back on the ground!", 5, CargoCarrier:GetGroup(), self:GetName() )
self:CancelBoarding( CargoCarrier, NearRadius, ... )
self.CargoObject:SetCommand( self.CargoObject:CommandStopRoute( true ) )
end end
else
self.CargoObject:MessageToGroup( "Cancelling Boarding... Get back on the ground!", 5, CargoCarrier:GetGroup(), self:GetName() )
self:CancelBoarding( CargoCarrier, NearRadius, ... )
self.CargoObject:SetCommand( self.CargoObject:CommandStopRoute( true ) )
end
else else
self:E("Something is wrong") self:E("Something is wrong")
end end

View File

@ -1975,6 +1975,24 @@ do -- Route methods
return nil return nil
end end
--- Make the controllable to push follow a given route.
-- @param #CONTROLLABLE self
-- @param #table Route A table of Route Points.
-- @param #number DelaySeconds (Optional) Wait for the specified seconds before executing the Route. Default is one second.
-- @return #CONTROLLABLE The CONTROLLABLE.
function CONTROLLABLE:RoutePush( Route, DelaySeconds )
self:F2( Route )
local DCSControllable = self:GetDCSObject()
if DCSControllable then
local RouteTask = self:TaskRoute( Route ) -- Create a RouteTask, that will route the CONTROLLABLE to the Route.
self:PushTask( RouteTask, DelaySeconds or 1 ) -- Execute the RouteTask after the specified seconds (default is 1).
return self
end
return nil
end
--- Stops the movement of the vehicle on the route. --- Stops the movement of the vehicle on the route.
-- @param #CONTROLLABLE self -- @param #CONTROLLABLE self

View File

@ -908,16 +908,23 @@ function UNIT:InAir()
-- Implementation of workaround. The original code is below. -- Implementation of workaround. The original code is below.
-- This to simulate the landing on buildings. -- This to simulate the landing on buildings.
-- local UnitInAir = DCSUnit:inAir()
local UnitInAir = true local UnitInAir = true
local VelocityVec3 = DCSUnit:getVelocity()
local Velocity = ( VelocityVec3.x ^ 2 + VelocityVec3.y ^ 2 + VelocityVec3.z ^ 2 ) ^ 0.5 -- in meters / sec local UnitCategory = DCSUnit:getDesc().category
local Coordinate = DCSUnit:getPoint() if UnitCategory == Unit.Category.HELICOPTER then
local LandHeight = land.getHeight( { x = Coordinate.x, y = Coordinate.z } ) local VelocityVec3 = DCSUnit:getVelocity()
local Height = Coordinate.y - LandHeight local Velocity = ( VelocityVec3.x ^ 2 + VelocityVec3.y ^ 2 + VelocityVec3.z ^ 2 ) ^ 0.5 -- in meters / sec
if Velocity < 1 and Height <= 60 then local Coordinate = DCSUnit:getPoint()
UnitInAir = false local LandHeight = land.getHeight( { x = Coordinate.x, y = Coordinate.z } )
local Height = Coordinate.y - LandHeight
if Velocity < 1 and Height <= 60 then
UnitInAir = false
end
else
UnitInAir = DCSUnit:inAir()
end end
self:T3( UnitInAir ) self:T3( UnitInAir )
return UnitInAir return UnitInAir
end end