Merge branch 'develop' into FF/Develop

This commit is contained in:
Frank 2018-10-24 21:47:52 +02:00
commit c354fecc6d
10 changed files with 299 additions and 195 deletions

View File

@ -635,7 +635,7 @@ end
--- @param Wrapper.Group#GROUP AIGroup
function AI_A2A.Resume( AIGroup, Fsm )
AIGroup:F( { "AI_A2A.Resume:", AIGroup:GetName() } )
AIGroup:I( { "AI_A2A.Resume:", AIGroup:GetName() } )
if AIGroup:IsAlive() then
Fsm:__RTB( 0.5 )
end

View File

@ -476,13 +476,12 @@ function AI_A2A_CAP:OnEventDead( EventData )
end
--- @param Wrapper.Group#GROUP AICap
function AI_A2A_CAP.Resume( AICap )
function AI_A2A_CAP.Resume( AICap, Fsm )
AICap:F( { "AI_A2A_CAP.Resume:", AICap:GetName() } )
AICap:I( { "AI_A2A_CAP.Resume:", AICap:GetName() } )
if AICap:IsAlive() then
local _AI_A2A = AICap:GetState( AICap, "AI_A2A" ) -- #AI_A2A
_AI_A2A:__Reset( 1 )
_AI_A2A:__Route( 5 )
Fsm:__Reset( 1 )
Fsm:__Route( 5 )
end
end

View File

@ -351,13 +351,12 @@ function AI_A2A_PATROL:onafterRoute( AIPatrol, From, Event, To )
end
--- @param Wrapper.Group#GROUP AIPatrol
function AI_A2A_PATROL.Resume( AIPatrol )
function AI_A2A_PATROL.Resume( AIPatrol, Fsm )
AIPatrol:F( { "AI_A2A_PATROL.Resume:", AIPatrol:GetName() } )
AIPatrol:I( { "AI_A2A_PATROL.Resume:", AIPatrol:GetName() } )
if AIPatrol:IsAlive() then
local _AI_A2A = AIPatrol:GetState( AIPatrol, "AI_A2A" ) -- AI.AI_A2A#AI_A2A
_AI_A2A:__Reset( 1 )
_AI_A2A:__Route( 5 )
Fsm:__Reset( 1 )
Fsm:__Route( 5 )
end
end

View File

@ -293,6 +293,80 @@ function AI_CARGO:onbeforeLoad( Carrier, From, Event, To, PickupZone )
end
--- On before Reload event.
-- @param #AI_CARGO self
-- @param Wrapper.Group#GROUP Carrier
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
-- @param Core.Zone#ZONE PickupZone (optional) The zone where the cargo will be picked up. The PickupZone can be nil, if there wasn't any PickupZoneSet provided.
function AI_CARGO:onbeforeReload( Carrier, From, Event, To )
self:F( { Carrier, From, Event, To } )
local Boarding = false
local LoadInterval = 2
local LoadDelay = 1
local Carrier_List = {}
local Carrier_Weight = {}
if Carrier and Carrier:IsAlive() then
for _, CarrierUnit in pairs( Carrier:GetUnits() ) do
local CarrierUnit = CarrierUnit -- Wrapper.Unit#UNIT
Carrier_List[#Carrier_List+1] = CarrierUnit
end
local Carrier_Count = #Carrier_List
local Carrier_Index = 1
local Loaded = false
for Cargo, CarrierUnit in pairs( self.Carrier_Cargo ) do
local Cargo = Cargo -- Cargo.Cargo#CARGO
self:F( { IsUnLoaded = Cargo:IsUnLoaded(), IsDeployed = Cargo:IsDeployed(), Cargo:GetName(), Carrier:GetName() } )
-- Try all Carriers, but start from the one according the Carrier_Index
for Carrier_Loop = 1, #Carrier_List do
local CarrierUnit = Carrier_List[Carrier_Index] -- Wrapper.Unit#UNIT
-- This counters loop through the available Carriers.
Carrier_Index = Carrier_Index + 1
if Carrier_Index > Carrier_Count then
Carrier_Index = 1
end
if Cargo:IsUnLoaded() and not Cargo:IsDeployed() then
Carrier:RouteStop()
Cargo:__Board( -LoadDelay, CarrierUnit )
self:__Board( LoadDelay, Cargo, CarrierUnit )
LoadDelay = LoadDelay + Cargo:GetCount() * LoadInterval
-- So now this CarrierUnit has Cargo that is being loaded.
-- This will be used further in the logic to follow and to check cargo status.
self.Carrier_Cargo[Cargo] = CarrierUnit
Boarding = true
Loaded = true
end
end
end
if not Loaded == true then
-- No loading happened, so we need to pickup something else.
self.Relocating = false
end
end
return Boarding
end
--- On after Board event.
-- @param #AI_CARGO self
-- @param Wrapper.Group#GROUP Carrier
@ -307,7 +381,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 +561,7 @@ function AI_CARGO:onafterDeployed( Carrier, From, Event, To, DeployZone, Defend
self.Transporting = false
else
self:F( "Defending" )
end
end

View File

@ -97,6 +97,7 @@ function AI_CARGO_APC:New( APC, CargoSet, CombatRadius )
self:AddTransition( "*", "Follow", "Following" )
self:AddTransition( "*", "Guard", "Unloaded" )
self:AddTransition( "*", "Home", "*" )
self:AddTransition( "*", "Reload", "Boarding" )
self:AddTransition( "*", "Destroyed", "Destroyed" )
@ -118,7 +119,6 @@ function AI_CARGO_APC:SetCarrier( CargoCarrier )
self.CargoCarrier:SetState( self.CargoCarrier, "AI_CARGO_APC", self )
CargoCarrier:HandleEvent( EVENTS.Dead )
CargoCarrier:HandleEvent( EVENTS.Hit )
function CargoCarrier:OnEventDead( EventData )
self:F({"dead"})
@ -132,18 +132,20 @@ function AI_CARGO_APC:SetCarrier( CargoCarrier )
end
end
end
function CargoCarrier:OnEventHit( EventData )
self:F({"hit"})
local AICargoTroops = self:GetState( self, "AI_CARGO_APC" )
if AICargoTroops then
self:F( { OnHitLoaded = AICargoTroops:Is( "Loaded" ) } )
if AICargoTroops:Is( "Loaded" ) or AICargoTroops:Is( "Boarding" ) then
-- There are enemies within combat radius. Unload the CargoCarrier.
AICargoTroops:Unload( false )
end
end
end
-- CargoCarrier:HandleEvent( EVENTS.Hit )
--
-- function CargoCarrier:OnEventHit( EventData )
-- self:F({"hit"})
-- local AICargoTroops = self:GetState( self, "AI_CARGO_APC" )
-- if AICargoTroops then
-- self:F( { OnHitLoaded = AICargoTroops:Is( "Loaded" ) } )
-- if AICargoTroops:Is( "Loaded" ) or AICargoTroops:Is( "Boarding" ) then
-- -- There are enemies within combat radius. Unload the CargoCarrier.
-- AICargoTroops:Unload( false )
-- end
-- end
-- end
self.Zone = ZONE_UNIT:New( self.CargoCarrier:GetName() .. "-Zone", self.CargoCarrier, self.CombatRadius )
self.Coalition = self.CargoCarrier:GetCoalition()
@ -276,34 +278,36 @@ function AI_CARGO_APC:onafterMonitor( APC, From, Event, To )
if self.CarrierCoordinate then
if self:IsTransporting() == true then
local Coordinate = APC:GetCoordinate()
self.Zone:Scan( { Object.Category.UNIT } )
if self.Zone:IsAllInZoneOfCoalition( self.Coalition ) then
if self:Is( "Unloaded" ) or self:Is( "Following" ) 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" ) or self:Is( "Loaded" ) then
self.Zone:Scan( { Object.Category.UNIT } )
if self.Zone:IsAllInZoneOfCoalition( self.Coalition ) then
if self:Is( "Unloaded" ) then
self:Follow()
-- There are no enemies within combat radius. Reload the CargoCarrier.
self:Reload()
end
self:F( "I am here" .. self:GetCurrentState() )
if self:Is( "Following" ) then
for Cargo, APCUnit in pairs( self.Carrier_Cargo ) do
local Cargo = Cargo -- Cargo.Cargo#CARGO
local APCUnit = APCUnit -- Wrapper.Unit#UNIT
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
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
--self:Follow()
end
self:F( "I am here" .. self:GetCurrentState() )
if self:Is( "Following" ) then
for Cargo, APCUnit in pairs( self.Carrier_Cargo ) do
local Cargo = Cargo -- Cargo.Cargo#CARGO
local APCUnit = APCUnit -- Wrapper.Unit#UNIT
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
@ -442,6 +446,45 @@ function AI_CARGO_APC:onafterDeploy( APC, From, Event, To, Coordinate, Speed, He
end
--- On after Unloaded event.
-- @param #AI_CARGO_APC self
-- @param Wrapper.Group#GROUP Carrier
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
-- @param #string Cargo.Cargo#CARGO Cargo Cargo object.
-- @param #boolean Deployed Cargo is deployed.
-- @param Core.Zone#ZONE DeployZone The zone wherein the cargo is deployed. This can be any zone type, like a ZONE, ZONE_GROUP, ZONE_AIRBASE.
function AI_CARGO_APC:onafterUnloaded( Carrier, From, Event, To, Cargo, CarrierUnit, DeployZone, Defend )
self:F( { Carrier, From, Event, To, DeployZone = DeployZone, Defend = Defend } )
self:GetParent( self, AI_CARGO_APC ).onafterUnloaded( self, Carrier, From, Event, To, Cargo, CarrierUnit, 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 = {}
local CargoGroup = Cargo.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
--- On after Deployed event.
-- @param #AI_CARGO_APC self
-- @param Wrapper.Group#GROUP Carrier

View File

@ -899,7 +899,7 @@ function AI_CARGO_DISPATCHER:onafterMonitor()
for CarrierGroupName, Carrier in pairs( self.SetCarrier:GetSet() ) do
local Carrier = Carrier -- Wrapper.Group#GROUP
if Carrier:IsAlive() == true then
if Carrier:IsAlive() ~= nil then
local AI_Cargo = self.AI_Cargo[Carrier]
if not AI_Cargo then
@ -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,29 @@ 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, ... )
Cargo:__Board( 1, CargoCarrier, NearRadius, ... )
end, ...
)
self:__Boarding( 1, CargoCarrier, NearRadius, ... )
end
-- 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() } )
local CargoGroup = Cargo.CargoObject --Wrapper.Group#GROUP
CargoGroup:OptionAlarmStateGreen()
Cargo:__Board( 1, CargoCarrier, NearRadius, ... )
end, ...
)
self:__Boarding( -1, CargoCarrier, NearRadius, ... )
end
@ -323,13 +323,15 @@ 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
Cargo:Load( CargoCarrier )
if not Cargo:IsDestroyed() then
Cargo:Load( CargoCarrier )
end
end
end
@ -360,7 +362,7 @@ do -- CARGO_GROUP
--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.
Boarded = false
end
@ -400,7 +402,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 +445,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 +466,7 @@ do -- CARGO_GROUP
end
if UnBoarded then
return true
self:__UnLoad( 1, ToPointVec2, ... )
else
self:__UnBoarding( 1, ToPointVec2, NearRadius, ... )
end
@ -474,30 +476,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 +492,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,46 +233,47 @@ do -- CARGO_UNIT
--self:F({Unit=self.CargoObject:GetName()})
-- 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
-- If NearRadius is given, then use the given NearRadius, otherwise calculate the NearRadius
-- based upon the Carrier bounding radius, which is calculated from the bounding rectangle on the Y axis.
local NearRadius = NearRadius or CargoCarrier:GetBoundingRadius() + 5
if self:IsNear( CargoCarrier:GetPointVec2(), NearRadius ) then
self:Load( CargoCarrier, NearRadius, ... )
else
if MaxSpeed and MaxSpeed == 0 or TypeName and TypeName == "Stinger comm" then
-- 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
-- If NearRadius is given, then use the given NearRadius, otherwise calculate the NearRadius
-- based upon the Carrier bounding radius, which is calculated from the bounding rectangle on the Y axis.
local NearRadius = NearRadius or CargoCarrier:GetBoundingRadius() + 5
if self:IsNear( CargoCarrier:GetPointVec2(), NearRadius ) then
self:Load( CargoCarrier, NearRadius, ... )
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 Angle = 180
local Distance = 0
local PointStartVec2 = self.CargoObject:GetPointVec2()
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 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
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
@ -286,53 +287,53 @@ 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, ... )
else
if self:IsNear( CargoCarrier:GetPointVec2(), 20 ) then
self:__Boarding( 1, CargoCarrier, NearRadius, ... )
self.RunCount = self.RunCount + 1
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, ... )
else
self:__Boarding( 2, CargoCarrier, NearRadius, ... )
self.RunCount = self.RunCount + 2
end
if self.RunCount >= 40 then
self.RunCount = 0
local Speed = 90
local Angle = 180
local Distance = 0
if self:IsNear( CargoCarrier:GetPointVec2(), 20 ) then
self:__Boarding( -1, CargoCarrier, NearRadius, ... )
self.RunCount = self.RunCount + 1
else
self:__Boarding( -2, CargoCarrier, NearRadius, ... )
self.RunCount = self.RunCount + 2
end
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()})
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 PointStartVec2 = self.CargoObject:GetPointVec2()
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 )
-- Set the CargoObject to state Green to ensure it is boarding!
self.CargoObject:OptionAlarmStateGreen()
local Points = {}
local PointStartVec2 = self.CargoObject:GetPointVec2()
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
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
self:E("Something is wrong")
end
@ -340,26 +341,6 @@ do -- CARGO_UNIT
end
--- Enter Boarding State.
-- @param #CARGO_UNIT self
-- @param #string Event
-- @param #string From
-- @param #string To
-- @param Wrapper.Unit#UNIT CargoCarrier
-- @param #number NearRadius Default 25 m.
function CARGO_UNIT:onenterBoarding( From, Event, To, CargoCarrier, NearRadius, ... )
--self:F( { From, Event, To, CargoCarrier.UnitName, NearRadius } )
local Speed = 90
local Angle = 180
local Distance = 5
if From == "UnLoaded" or From == "Boarding" then
end
end
--- Loaded State.
-- @param #CARGO_UNIT self
-- @param #string Event

View File

@ -2003,6 +2003,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
@ -2111,7 +2129,7 @@ do -- Route methods
FromCoordinate = FromCoordinate or self:GetCoordinate()
-- Get path and path length on road including the end points (From and To).
local PathOnRoad, LengthOnRoad=FromCoordinate:GetPathOnRoad(ToCoordinate, true)
local PathOnRoad, LengthOnRoad, GotPath =FromCoordinate:GetPathOnRoad(ToCoordinate, true)
-- Get the length only(!) on the road.
local _,LengthRoad=FromCoordinate:GetPathOnRoad(ToCoordinate, false)
@ -2123,7 +2141,7 @@ do -- Route methods
-- Calculate the direct distance between the initial and final points.
local LengthDirect=FromCoordinate:Get2DDistance(ToCoordinate)
if PathOnRoad then
if GotPath then
-- Off road part of the rout: Total=OffRoad+OnRoad.
LengthOffRoad=LengthOnRoad-LengthRoad
@ -2146,7 +2164,7 @@ do -- Route methods
local canroad=false
-- Check if a valid path on road could be found.
if PathOnRoad then
if GotPath and LengthDirect > 2000 then -- if the length of the movement is less than 1 km, drive directly.
-- Check whether the road is very long compared to direct path.
if LongRoad and Shortcut then

View File

@ -909,11 +909,15 @@ function UNIT:InAir()
-- Get DCS result of whether unit is in air or not.
local UnitInAir = DCSUnit:inAir()
-- Get unit category.
local UnitCategory = DCSUnit:getDesc().category
-- If DCS says that it is in air, check if this is really the case, since we might have landed on a building where inAir()=true but actually is not.
if UnitInAir==true then
-- If DCS says that it is in air, check if this is really the case, since we might have landed on a building where inAir()=true but actually is not.
-- This is a workaround since DCS currently does not acknoledge that helos land on buildings.
-- Note however, that the velocity check will fail if the ground is moving, e.g. on an aircraft carrier!
if UnitInAir==true and 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 Velocity = UTILS.VecNorm(VelocityVec3)
local Coordinate = DCSUnit:getPoint()
local LandHeight = land.getHeight( { x = Coordinate.x, y = Coordinate.z } )
@ -922,7 +926,7 @@ function UNIT:InAir()
UnitInAir = false
end
end
self:T3( UnitInAir )
return UnitInAir
end