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
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 )
return
end
@ -487,6 +487,7 @@ function AI_CARGO:onafterDeployed( Carrier, From, Event, To, DeployZone, Defend
self.Transporting = false
else
self:F( "Defending" )
end
end

View File

@ -276,9 +276,10 @@ function AI_CARGO_APC:onafterMonitor( APC, From, Event, To )
if self.CarrierCoordinate then
if self:IsTransporting() == true then
local Coordinate = APC:GetCoordinate()
if self:Is( "Unloaded" ) or self:Is( "Loaded" ) then
self.Zone:Scan( { Object.Category.UNIT } )
if self.Zone:IsAllInZoneOfCoalition( self.Coalition ) then
if self:Is( "Unloaded" ) or self:Is( "Following" ) then
if self:Is( "Unloaded" ) then
-- There are no enemies within combat radius. Load the CargoCarrier.
self:Load()
end
@ -288,7 +289,7 @@ function AI_CARGO_APC:onafterMonitor( APC, From, Event, To )
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
self:Follow()
--self:Follow()
end
self:F( "I am here" .. self:GetCurrentState() )
if self:Is( "Following" ) then
@ -313,6 +314,7 @@ function AI_CARGO_APC:onafterMonitor( APC, From, Event, To )
end
end
end
end
end
self.CarrierCoordinate = APC:GetCoordinate()
@ -456,6 +458,30 @@ function AI_CARGO_APC:onafterDeployed( 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

View File

@ -1143,7 +1143,7 @@ function AI_CARGO_DISPATCHER:onafterMonitor()
LargestLoadCapacity = LoadCapacity
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.
-- This will skip cargo which is too large to be able to be loaded by carriers
-- and will secure an efficient dispatching scheme.

View File

@ -20,9 +20,9 @@
do -- CARGO_GROUP
--- @type CARGO_GROUP
-- @extends Cargo.Cargo#CARGO_REPORTABLE
-- @field Core.Set#SET_CARGO CargoSet The collection of derived CARGO objects.
-- @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.
-- The cargo can be Loaded, UnLoaded, Boarded, UnBoarded to and from Carriers.
@ -291,29 +291,27 @@ do -- CARGO_GROUP
end
--- Enter Boarding State.
--- After Board Event.
-- @param #CARGO_GROUP self
-- @param #string Event
-- @param #string From
-- @param #string To
-- @param Wrapper.Unit#UNIT CargoCarrier
-- @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 } )
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(
function( Cargo, ... )
self:F( { "Board Unit", Cargo:GetName( ), Cargo:IsDestroyed(), Cargo.CargoObject:IsAlive() } )
Cargo:__Board( 1, CargoCarrier, NearRadius, ... )
end, ...
)
self:__Boarding( 1, CargoCarrier, NearRadius, ... )
end
self:__Boarding( -1, CargoCarrier, NearRadius, ... )
end
@ -323,15 +321,17 @@ do -- CARGO_GROUP
-- @param #string From
-- @param #string To
-- @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, ...} )
if From == "UnLoaded" then
-- For each Cargo object within the CARGO_GROUP, load each cargo to the CargoCarrier.
for CargoID, Cargo in pairs( self.CargoSet:GetSet() ) do
if not Cargo:IsDestroyed() then
Cargo:Load( CargoCarrier )
end
end
end
--self.CargoObject:Destroy()
self.CargoCarrier = CargoCarrier
@ -400,7 +400,7 @@ do -- CARGO_GROUP
-- @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:onenterUnBoarding( From, Event, To, ToPointVec2, NearRadius, ... )
function CARGO_GROUP:onafterUnBoard( From, Event, To, ToPointVec2, NearRadius, ... )
self:F( {From, Event, To, ToPointVec2, NearRadius } )
NearRadius = NearRadius or 25
@ -443,7 +443,7 @@ do -- CARGO_GROUP
-- @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:onleaveUnBoarding( From, Event, To, ToPointVec2, NearRadius, ... )
function CARGO_GROUP:onafterUnBoarding( From, Event, To, ToPointVec2, NearRadius, ... )
--self:F( { From, Event, To, ToPointVec2, NearRadius } )
--local NearRadius = NearRadius or 25
@ -464,7 +464,7 @@ do -- CARGO_GROUP
end
if UnBoarded then
return true
self:__UnLoad( 1, ToPointVec2, ... )
else
self:__UnBoarding( 1, ToPointVec2, NearRadius, ... )
end
@ -474,30 +474,13 @@ do -- CARGO_GROUP
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.
-- @param #CARGO_GROUP self
-- @param #string Event
-- @param #string From
-- @param #string To
-- @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 } )
if From == "Loaded" then
@ -507,7 +490,7 @@ do -- CARGO_GROUP
function( Cargo )
--Cargo:UnLoad( ToPointVec2 )
local RandomVec2=ToPointVec2:GetRandomPointVec2InRadius(20, 10)
Cargo:UnLoad( RandomVec2 )
Cargo:UnBoard( RandomVec2 )
end
)

View File

@ -233,6 +233,8 @@ do -- CARGO_UNIT
--self:F({Unit=self.CargoObject:GetName()})
-- A cargo unit can only be boarded if it is not dead
-- Only move the group to the carrier when the cargo is not in the air
-- (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
@ -272,7 +274,6 @@ do -- CARGO_UNIT
end
end
end
end
@ -286,19 +287,19 @@ do -- CARGO_UNIT
function CARGO_UNIT:onafterBoarding( From, Event, To, CargoCarrier, 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:IsAir() and not CargoCarrier:InAir()) or true then
local NearRadius = NearRadius or CargoCarrier:GetBoundingRadius( NearRadius ) + 5
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:__Boarding( -1, CargoCarrier, NearRadius, ... )
self.RunCount = self.RunCount + 1
else
self:__Boarding( 2, CargoCarrier, NearRadius, ... )
self:__Boarding( -2, CargoCarrier, NearRadius, ... )
self.RunCount = self.RunCount + 2
end
if self.RunCount >= 40 then

View File

@ -1975,6 +1975,24 @@ do -- Route methods
return nil
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.
-- @param #CONTROLLABLE self

View File

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