Merge branch 'develop' into FF/Develop

This commit is contained in:
funkyfranky 2018-04-07 23:58:40 +02:00
commit e606ab1b8a
13 changed files with 570 additions and 245 deletions

View File

@ -24,19 +24,16 @@ AI_CARGO_TROOPS = {
--- Creates a new AI_CARGO_TROOPS object. --- Creates a new AI_CARGO_TROOPS object.
-- @param #AI_CARGO_TROOPS self -- @param #AI_CARGO_TROOPS self
-- @param Wrapper.Unit#UNIT CargoCarrier
-- @param Cargo.CargoGroup#CARGO_GROUP CargoGroup
-- @param #number CombatRadius
-- @return #AI_CARGO_TROOPS -- @return #AI_CARGO_TROOPS
function AI_CARGO_TROOPS:New( CargoCarrier, CargoGroup, CombatRadius ) function AI_CARGO_TROOPS:New( CargoCarrier, CargoGroup, CombatRadius )
local self = BASE:Inherit( self, FSM_CONTROLLABLE:New( ) ) -- #AI_CARGO_TROOPS local self = BASE:Inherit( self, FSM_CONTROLLABLE:New( ) ) -- #AI_CARGO_TROOPS
self.CargoCarrier = CargoCarrier -- Wrapper.Unit#UNIT self.CargoGroup = CargoGroup -- Cargo.CargoGroup#CARGO_GROUP
self.CargoGroup = CargoGroup -- Core.Cargo#CARGO_GROUP
self.CombatRadius = CombatRadius self.CombatRadius = CombatRadius
self.Zone = ZONE_UNIT:New( self.CargoCarrier:GetName() .. "-Zone", self.CargoCarrier, CombatRadius )
self.Coalition = self.CargoCarrier:GetCoalition()
self:SetControllable( CargoCarrier )
self:SetStartState( "UnLoaded" ) self:SetStartState( "UnLoaded" )
@ -50,14 +47,91 @@ function AI_CARGO_TROOPS:New( CargoCarrier, CargoGroup, CombatRadius )
self:AddTransition( "*", "Monitor", "*" ) self:AddTransition( "*", "Monitor", "*" )
self:AddTransition( "*", "Follow", "Following" ) self:AddTransition( "*", "Follow", "Following" )
self:AddTransition( "*", "Guard", "Guarding" ) self:AddTransition( "*", "Guard", "Guarding" )
self:AddTransition( "*", "Destroyed", "Destroyed" )
self:__Monitor( 1 ) self:__Monitor( 1 )
self:__Load( 1 )
self:SetCarrier( CargoCarrier )
return self return self
end end
--- Set the Carrier.
-- @param #AI_CARGO_TROOPS self
-- @param Wrapper.Unit#UNIT CargoCarrier
-- @return #AI_CARGO_TROOPS
function AI_CARGO_TROOPS:SetCarrier( CargoCarrier )
self.CargoCarrier = CargoCarrier -- Wrapper.Unit#UNIT
self.CargoCarrier:SetState( self.CargoCarrier, "AI_CARGO_TROOPS", self )
CargoCarrier:HandleEvent( EVENTS.Dead )
CargoCarrier:HandleEvent( EVENTS.Hit )
function CargoCarrier:OnEventDead( EventData )
self:F({"dead"})
local AICargoTroops = self:GetState( self, "AI_CARGO_TROOPS" )
self:F({AICargoTroops=AICargoTroops})
if AICargoTroops then
self:F({})
if not AICargoTroops:Is( "Loaded" ) then
-- There are enemies within combat range. Unload the CargoCarrier.
AICargoTroops:Destroyed()
end
end
end
function CargoCarrier:OnEventHit( EventData )
self:F({"hit"})
local AICargoTroops = self:GetState( self, "AI_CARGO_TROOPS" )
if AICargoTroops then
self:F( { OnHitLoaded = AICargoTroops:Is( "Loaded" ) } )
if AICargoTroops:Is( "Loaded" ) or AICargoTroops:Is( "Boarding" ) then
-- There are enemies within combat range. Unload the CargoCarrier.
AICargoTroops:Unload()
end
end
end
self.Zone = ZONE_UNIT:New( self.CargoCarrier:GetName() .. "-Zone", self.CargoCarrier, self.CombatRadius )
self.Coalition = self.CargoCarrier:GetCoalition()
self:SetControllable( CargoCarrier )
self:Guard()
return self
end
--- Find a free Carrier within a range.
-- @param #AI_CARGO_TROOPS self
-- @param Core.Point#COORDINATE Coordinate
-- @param #number Radius
-- @return Wrapper.Unit#UNIT NewCarrier
function AI_CARGO_TROOPS:FindCarrier( Coordinate, Radius )
local CoordinateZone = ZONE_RADIUS:New( "Zone" , Coordinate:GetVec2(), Radius )
CoordinateZone:Scan( { Object.Category.UNIT } )
for _, DCSUnit in pairs( CoordinateZone:GetScannedUnits() ) do
local NearUnit = UNIT:Find( DCSUnit )
self:F({NearUnit=NearUnit})
if not NearUnit:GetState( NearUnit, "AI_CARGO_TROOPS" ) then
local Attributes = NearUnit:GetDesc()
self:F({Desc=Attributes})
if NearUnit:HasAttribute( "Trucks" ) then
self:SetCarrier( NearUnit )
break
end
end
end
end
--- Follow Infantry to the Carrier. --- Follow Infantry to the Carrier.
-- @param #AI_CARGO_TROOPS self -- @param #AI_CARGO_TROOPS self
-- @param #AI_CARGO_TROOPS Me -- @param #AI_CARGO_TROOPS Me
@ -68,40 +142,44 @@ function AI_CARGO_TROOPS:FollowToCarrier( Me, CargoCarrier, InfantryGroup )
self:F( { self = self:GetClassNameAndID(), InfantryGroup = InfantryGroup:GetName() } ) self:F( { self = self:GetClassNameAndID(), InfantryGroup = InfantryGroup:GetName() } )
-- We check if the Cargo is near to the CargoCarrier. --if self:Is( "Following" ) then
if InfantryGroup:IsPartlyInZone( ZONE_UNIT:New( "Radius", CargoCarrier, 5 ) ) then
-- The Cargo does not need to follow the Carrier. if CargoCarrier:IsAlive() then
Me:Guard() -- We check if the Cargo is near to the CargoCarrier.
if InfantryGroup:IsPartlyInZone( ZONE_UNIT:New( "Radius", CargoCarrier, 5 ) ) then
else -- The Cargo does not need to follow the Carrier.
Me:Guard()
self:F( { InfantryGroup = InfantryGroup:GetName() } ) else
if InfantryGroup:IsAlive() then
self:F( { InfantryGroup = InfantryGroup:GetName() } ) self:F( { InfantryGroup = InfantryGroup:GetName() } )
local Waypoints = {}
-- Calculate the new Route.
local FromCoord = InfantryGroup:GetCoordinate()
local FromGround = FromCoord:WaypointGround( 10, "Diamond" )
self:F({FromGround=FromGround})
table.insert( Waypoints, FromGround )
local ToCoord = CargoCarrier:GetCoordinate()
local ToGround = ToCoord:WaypointGround( 10, "Diamond" )
self:F({ToGround=ToGround})
table.insert( Waypoints, ToGround )
local TaskRoute = InfantryGroup:TaskFunction( "AI_CARGO_TROOPS.FollowToCarrier", Me, CargoCarrier, InfantryGroup )
self:F({Waypoints = Waypoints})
local Waypoint = Waypoints[#Waypoints]
InfantryGroup:SetTaskWaypoint( Waypoint, TaskRoute ) -- Set for the given Route at Waypoint 2 the TaskRouteToZone.
InfantryGroup:Route( Waypoints, 1 ) -- Move after a random seconds to the Route. See the Route method for details. if InfantryGroup:IsAlive() then
self:F( { InfantryGroup = InfantryGroup:GetName() } )
local Waypoints = {}
-- Calculate the new Route.
local FromCoord = InfantryGroup:GetCoordinate()
local FromGround = FromCoord:WaypointGround( 10, "Diamond" )
self:F({FromGround=FromGround})
table.insert( Waypoints, FromGround )
local ToCoord = CargoCarrier:GetCoordinate():GetRandomCoordinateInRadius( 10, 5 )
local ToGround = ToCoord:WaypointGround( 10, "Diamond" )
self:F({ToGround=ToGround})
table.insert( Waypoints, ToGround )
local TaskRoute = InfantryGroup:TaskFunction( "AI_CARGO_TROOPS.FollowToCarrier", Me, CargoCarrier, InfantryGroup )
self:F({Waypoints = Waypoints})
local Waypoint = Waypoints[#Waypoints]
InfantryGroup:SetTaskWaypoint( Waypoint, TaskRoute ) -- Set for the given Route at Waypoint 2 the TaskRouteToZone.
InfantryGroup:Route( Waypoints, 1 ) -- Move after a random seconds to the Route. See the Route method for details.
end
end end
end end
end end
@ -132,6 +210,22 @@ function AI_CARGO_TROOPS:onafterMonitor( CargoCarrier, From, Event, To )
self:Follow() self:Follow()
end end
end end
if self:Is( "Following" ) then
local Distance = Coordinate:Get2DDistance( self.CargoGroup:GetCoordinate() )
self:F( { Distance = Distance } )
if Distance > 40 then
CargoCarrier:RouteStop()
self.CarrierStopped = true
else
if self.CarrierStopped then
if self.CargoGroup:IsNear( CargoCarrier, 10 ) then
CargoCarrier:RouteResume()
self.CarrierStopped = nil
end
end
end
end
end end
self.CarrierCoordinate = CargoCarrier:GetCoordinate() self.CarrierCoordinate = CargoCarrier:GetCoordinate()
end end
@ -149,7 +243,7 @@ function AI_CARGO_TROOPS:onafterLoad( CargoCarrier, From, Event, To )
if CargoCarrier and CargoCarrier:IsAlive() then if CargoCarrier and CargoCarrier:IsAlive() then
CargoCarrier:RouteStop() CargoCarrier:RouteStop()
self:__Board( 10 ) self:__Board( 10 )
self.CargoGroup:Board( CargoCarrier, 100 ) self.CargoGroup:Board( CargoCarrier, 10 )
end end
end end

View File

@ -224,6 +224,7 @@ do -- CARGO
Slingloadable = false, Slingloadable = false,
Moveable = false, Moveable = false,
Containable = false, Containable = false,
Reported = {},
} }
--- @type CARGO.CargoObjects --- @type CARGO.CargoObjects
@ -235,12 +236,13 @@ do -- CARGO
-- @param #string Type -- @param #string Type
-- @param #string Name -- @param #string Name
-- @param #number Weight -- @param #number Weight
-- @param #number LoadRadius (optional)
-- @param #number NearRadius (optional) -- @param #number NearRadius (optional)
-- @return #CARGO -- @return #CARGO
function CARGO:New( Type, Name, Weight ) --R2.1 function CARGO:New( Type, Name, Weight, LoadRadius, NearRadius ) --R2.1
local self = BASE:Inherit( self, FSM:New() ) -- #CARGO local self = BASE:Inherit( self, FSM:New() ) -- #CARGO
self:F( { Type, Name, Weight } ) self:F( { Type, Name, Weight, LoadRadius, NearRadius } )
self:SetStartState( "UnLoaded" ) self:SetStartState( "UnLoaded" )
self:AddTransition( { "UnLoaded", "Boarding" }, "Board", "Boarding" ) self:AddTransition( { "UnLoaded", "Boarding" }, "Board", "Boarding" )
@ -267,6 +269,9 @@ do -- CARGO
self.Moveable = false self.Moveable = false
self.Containable = false self.Containable = false
self.LoadRadius = LoadRadius or 500
self.NearRadius = NearRadius or 25
self:SetDeployed( false ) self:SetDeployed( false )
self.CargoScheduler = SCHEDULER:New() self.CargoScheduler = SCHEDULER:New()
@ -320,7 +325,7 @@ do -- CARGO
-- @param #CARGO self -- @param #CARGO self
function CARGO:Destroy() function CARGO:Destroy()
if self.CargoObject then if self.CargoObject then
self.CargoObject:Destroy() self.CargoObject:Destroy( false )
end end
self:Destroyed() self:Destroyed()
end end
@ -379,6 +384,14 @@ do -- CARGO
return self:Is( "Loaded" ) return self:Is( "Loaded" )
end end
--- Check if cargo is loaded.
-- @param #CARGO self
-- @param Wrapper.Unit#UNIT Carrier
-- @return #boolean true if loaded
function CARGO:IsLoadedInCarrier( Carrier )
return self.CargoCarrier and self.CargoCarrier:GetName() == Carrier:GetName()
end
--- Check if cargo is unloaded. --- Check if cargo is unloaded.
-- @param #CARGO self -- @param #CARGO self
-- @return #boolean true if unloaded -- @return #boolean true if unloaded
@ -405,8 +418,9 @@ do -- CARGO
end end
end end
--- Set the cargo as deployed --- Set the cargo as deployed.
-- @param #CARGO self -- @param #CARGO self
-- @param #boolean Deployed true if the cargo is to be deployed. false or nil otherwise.
function CARGO:SetDeployed( Deployed ) function CARGO:SetDeployed( Deployed )
self.Deployed = Deployed self.Deployed = Deployed
end end
@ -507,7 +521,88 @@ do -- CARGO
end end
--- Set the Load radius, which is the radius till when the Cargo can be loaded.
-- @param #CARGO self
-- @param #number LoadRadius The radius till Cargo can be loaded.
-- @return #CARGO
function CARGO:SetLoadRadius( LoadRadius )
self.LoadRadius = LoadRadius or 150
end
--- Get the Load radius, which is the radius till when the Cargo can be loaded.
-- @param #CARGO self
-- @return #number The radius till Cargo can be loaded.
function CARGO:GetLoadRadius()
return self.LoadRadius
end
--- Check if Cargo is in the LoadRadius for the Cargo to be Boarded or Loaded.
-- @param #CARGO self
-- @param Core.Point#Coordinate Coordinate
-- @return #boolean true if the CargoGroup is within the loading radius.
function CARGO:IsInLoadRadius( Coordinate )
self:F( { Coordinate } )
local Distance = 0
if self:IsUnLoaded() then
Distance = Coordinate:DistanceFromPointVec2( self.CargoObject:GetPointVec2() )
self:T( Distance )
if Distance <= self.LoadRadius then
return true
end
end
return false
end
--- Check if the Cargo can report itself to be Boarded or Loaded.
-- @param #CARGO self
-- @param Core.Point#Coordinate Coordinate
-- @return #boolean true if the Cargo can report itself.
function CARGO:IsInReportRadius( Coordinate )
self:F( { Coordinate } )
local Distance = 0
if self:IsUnLoaded() then
Distance = Coordinate:DistanceFromPointVec2( self.CargoObject:GetPointVec2() )
self:T( Distance )
if Distance <= self.LoadRadius then
return true
end
end
return false
end
--- Check if CargoCarrier is near the Cargo to be Loaded.
-- @param #CARGO self
-- @param Core.Point#POINT_VEC2 PointVec2
-- @param #number NearRadius The radius when the cargo will board the Carrier (to avoid collision).
-- @return #boolean
function CARGO:IsNear( PointVec2, NearRadius )
self:F2( { PointVec2 = PointVec2, NearRadius = NearRadius } )
if self.CargoObject:IsAlive() then
--local Distance = PointVec2:DistanceFromPointVec2( self.CargoObject:GetPointVec2() )
--self:F( { CargoObjectName = self.CargoObject:GetName() } )
--self:F( { CargoObjectVec2 = self.CargoObject:GetVec2() } )
--self:F( { PointVec2 = PointVec2:GetVec2() } )
local Distance = PointVec2:Get2DDistance( self.CargoObject:GetPointVec2() )
--self:F( Distance )
if Distance <= NearRadius then
self:F( { PointVec2 = PointVec2, NearRadius = NearRadius, IsNear = true } )
return true
end
end
self:F( { PointVec2 = PointVec2, NearRadius = NearRadius, IsNear = false } )
return false
end
@ -534,30 +629,6 @@ do -- CARGO
end end
--- Check if CargoCarrier is near the Cargo to be Loaded.
-- @param #CARGO self
-- @param Core.Point#POINT_VEC2 PointVec2
-- @param #number NearRadius The radius when the cargo will board the Carrier (to avoid collision).
-- @return #boolean
function CARGO:IsNear( PointVec2, NearRadius )
self:F( { PointVec2 = PointVec2, NearRadius = NearRadius } )
if self.CargoObject:IsAlive() then
--local Distance = PointVec2:DistanceFromPointVec2( self.CargoObject:GetPointVec2() )
self:F( { CargoObjectName = self.CargoObject:GetName() } )
self:F( { CargoObjectVec2 = self.CargoObject:GetVec2() } )
self:F( { PointVec2 = PointVec2:GetVec2() } )
local Distance = PointVec2:Get2DDistance( self.CargoObject:GetPointVec2() )
self:T( Distance )
if Distance <= NearRadius then
return true
end
end
return false
end
--- Get the current PointVec2 of the cargo. --- Get the current PointVec2 of the cargo.
-- @param #CARGO self -- @param #CARGO self
-- @return Core.Point#POINT_VEC2 -- @return Core.Point#POINT_VEC2
@ -580,6 +651,85 @@ do -- CARGO
self.Weight = Weight self.Weight = Weight
return self return self
end end
--- Send a CC message to a @{Group}.
-- @param #CARGO self
-- @param #string Message
-- @param Wrapper.Group#GROUP CarrierGroup The Carrier Group.
-- @param #sring Name (optional) The name of the Group used as a prefix for the message to the Group. If not provided, there will be nothing shown.
function CARGO:MessageToGroup( Message, CarrierGroup, Name )
MESSAGE:New( Message, 20, "Cargo " .. self:GetName() ):ToGroup( CarrierGroup )
end
--- Report to a Carrier Group.
-- @param #CARGO self
-- @param #string Action The string describing the action for the cargo.
-- @param Wrapper.Group#GROUP CarrierGroup The Carrier Group to send the report to.
-- @return #CARGO
function CARGO:Report( ReportText, Action, CarrierGroup )
if not self.Reported[CarrierGroup] or not self.Reported[CarrierGroup][Action] then
self.Reported[CarrierGroup] = {}
self.Reported[CarrierGroup][Action] = true
self:MessageToGroup( ReportText, CarrierGroup )
if self.ReportFlareColor then
if not self.Reported[CarrierGroup]["Flaring"] then
self:Flare( self.ReportFlareColor )
self.Reported[CarrierGroup]["Flaring"] = true
end
end
if self.ReportSmokeColor then
if not self.Reported[CarrierGroup]["Smoking"] then
self:Smoke( self.ReportSmokeColor )
self.Reported[CarrierGroup]["Smoking"] = true
end
end
end
end
--- Report to a Carrier Group with a Flaring signal.
-- @param #CARGO self
-- @param Utils#UTILS.FlareColor FlareColor the color of the flare.
-- @return #CARGO
function CARGO:ReportFlare( FlareColor )
self.ReportFlareColor = FlareColor
end
--- Report to a Carrier Group with a Smoking signal.
-- @param #CARGO self
-- @param Utils#UTILS.SmokeColor SmokeColor the color of the smoke.
-- @return #CARGO
function CARGO:ReportSmoke( SmokeColor )
self.ReportSmokeColor = SmokeColor
end
--- Reset the reporting for a Carrier Group.
-- @param #CARGO self
-- @param #string Action The string describing the action for the cargo.
-- @param Wrapper.Group#GROUP CarrierGroup The Carrier Group to send the report to.
-- @return #CARGO
function CARGO:ReportReset( Action, CarrierGroup )
self.Reported[CarrierGroup][Action] = nil
end
--- Reset all the reporting for a Carrier Group.
-- @param #CARGO self
-- @param Wrapper.Group#GROUP CarrierGroup The Carrier Group to send the report to.
-- @return #CARGO
function CARGO:ReportResetAll( CarrierGroup )
self.Reported[CarrierGroup] = nil
end
end -- CARGO end -- CARGO
@ -600,16 +750,13 @@ do -- CARGO_REPRESENTABLE
-- @param #string Type -- @param #string Type
-- @param #string Name -- @param #string Name
-- @param #number Weight -- @param #number Weight
-- @param #number ReportRadius (optional) -- @param #number LoadRadius (optional)
-- @param #number NearRadius (optional) -- @param #number NearRadius (optional)
-- @return #CARGO_REPRESENTABLE -- @return #CARGO_REPRESENTABLE
function CARGO_REPRESENTABLE:New( CargoObject, Type, Name, Weight, ReportRadius, NearRadius ) function CARGO_REPRESENTABLE:New( CargoObject, Type, Name, Weight, LoadRadius, NearRadius )
local self = BASE:Inherit( self, CARGO:New( Type, Name, Weight ) ) -- #CARGO_REPRESENTABLE local self = BASE:Inherit( self, CARGO:New( Type, Name, Weight, LoadRadius, NearRadius ) ) -- #CARGO_REPRESENTABLE
self:F( { Type, Name, Weight, ReportRadius, NearRadius } ) self:F( { Type, Name, Weight, LoadRadius, NearRadius } )
self.ReportRadius = ReportRadius or 500
self.NearRadius = NearRadius or 25
return self return self
end end
@ -661,14 +808,12 @@ do -- CARGO_REPORTABLE
-- @param #string Type -- @param #string Type
-- @param #string Name -- @param #string Name
-- @param #number Weight -- @param #number Weight
-- @param #number ReportRadius (optional) -- @param #number LoadRadius (optional)
-- @param #number NearRadius (optional) -- @param #number NearRadius (optional)
-- @return #CARGO_REPORTABLE -- @return #CARGO_REPORTABLE
function CARGO_REPORTABLE:New( Type, Name, Weight, ReportRadius ) function CARGO_REPORTABLE:New( Type, Name, Weight, LoadRadius, NearRadius )
local self = BASE:Inherit( self, CARGO:New( Type, Name, Weight ) ) -- #CARGO_REPORTABLE local self = BASE:Inherit( self, CARGO:New( Type, Name, Weight, LoadRadius, NearRadius ) ) -- #CARGO_REPORTABLE
self:F( { Type, Name, Weight, ReportRadius } ) self:F( { Type, Name, Weight, LoadRadius, NearRadius } )
self.ReportRadius = ReportRadius or 1000
return self return self
end end
@ -680,19 +825,10 @@ do -- CARGO_REPORTABLE
-- @param #sring Name (optional) The name of the Group used as a prefix for the message to the Group. If not provided, there will be nothing shown. -- @param #sring Name (optional) The name of the Group used as a prefix for the message to the Group. If not provided, there will be nothing shown.
function CARGO_REPORTABLE:MessageToGroup( Message, TaskGroup, Name ) function CARGO_REPORTABLE:MessageToGroup( Message, TaskGroup, Name )
local Prefix = Name and "@ " .. Name .. ": " or "@ " .. TaskGroup:GetCallsign() .. ": " MESSAGE:New( Message, 20, "Cargo " .. self:GetName() ):ToGroup( TaskGroup )
Message = Prefix .. Message
MESSAGE:New( Message, 20, "Cargo: " .. self:GetName() ):ToGroup( TaskGroup )
end end
--- Get the Report radius, which is the radius when the Cargo is reporting itself.
-- @param #CARGO_REPORTABLE self
-- @return #number The range till Cargo reports itself.
function CARGO_REPORTABLE:GetBoardingRange()
return self.ReportRadius
end
end end
@ -717,12 +853,12 @@ do -- CARGO_PACKAGE
-- @param #string Type -- @param #string Type
-- @param #string Name -- @param #string Name
-- @param #number Weight -- @param #number Weight
-- @param #number ReportRadius (optional) -- @param #number LoadRadius (optional)
-- @param #number NearRadius (optional) -- @param #number NearRadius (optional)
-- @return #CARGO_PACKAGE -- @return #CARGO_PACKAGE
function CARGO_PACKAGE:New( CargoCarrier, Type, Name, Weight, ReportRadius, NearRadius ) function CARGO_PACKAGE:New( CargoCarrier, Type, Name, Weight, LoadRadius, NearRadius )
local self = BASE:Inherit( self, CARGO_REPRESENTABLE:New( CargoCarrier, Type, Name, Weight, ReportRadius, NearRadius ) ) -- #CARGO_PACKAGE local self = BASE:Inherit( self, CARGO_REPRESENTABLE:New( CargoCarrier, Type, Name, Weight, LoadRadius, NearRadius ) ) -- #CARGO_PACKAGE
self:F( { Type, Name, Weight, ReportRadius, NearRadius } ) self:F( { Type, Name, Weight, LoadRadius, NearRadius } )
self:T( CargoCarrier ) self:T( CargoCarrier )
self.CargoCarrier = CargoCarrier self.CargoCarrier = CargoCarrier

View File

@ -23,7 +23,7 @@ do -- CARGO_CRATE
--- Models the behaviour of cargo crates, which can be slingloaded and boarded on helicopters. --- Models the behaviour of cargo crates, which can be slingloaded and boarded on helicopters.
-- @type CARGO_CRATE -- @type CARGO_CRATE
-- @extends #CARGO_REPRESENTABLE -- @extends Cargo.Cargo#CARGO_REPRESENTABLE
--- # CARGO\_CRATE class, extends @{#CARGO_REPRESENTABLE} --- # CARGO\_CRATE class, extends @{#CARGO_REPRESENTABLE}
-- --
@ -42,11 +42,11 @@ do -- CARGO_CRATE
-- @param Wrapper.Static#STATIC CargoStatic -- @param Wrapper.Static#STATIC CargoStatic
-- @param #string Type -- @param #string Type
-- @param #string Name -- @param #string Name
-- @param #number ReportRadius (optional) -- @param #number LoadRadius (optional)
-- @param #number NearRadius (optional) -- @param #number NearRadius (optional)
-- @return #CARGO_CRATE -- @return #CARGO_CRATE
function CARGO_CRATE:New( CargoStatic, Type, Name, ReportRadius, NearRadius ) function CARGO_CRATE:New( CargoStatic, Type, Name, LoadRadius, NearRadius )
local self = BASE:Inherit( self, CARGO_REPRESENTABLE:New( CargoStatic, Type, Name, nil, ReportRadius, NearRadius ) ) -- #CARGO_CRATE local self = BASE:Inherit( self, CARGO_REPRESENTABLE:New( CargoStatic, Type, Name, nil, LoadRadius, NearRadius ) ) -- #CARGO_CRATE
self:F( { Type, Name, NearRadius } ) self:F( { Type, Name, NearRadius } )
self.CargoObject = CargoStatic self.CargoObject = CargoStatic
@ -134,6 +134,27 @@ do -- CARGO_CRATE
return false return false
end end
--- Check if Cargo Crate is in the radius for the Cargo to be Boarded or Loaded.
-- @param #CARGO self
-- @param Core.Point#Coordinate Coordinate
-- @return #boolean true if the Cargo Crate is within the loading radius.
function CARGO_CRATE:IsInLoadRadius( Coordinate )
self:F( { Coordinate } )
local Distance = 0
if self:IsUnLoaded() then
Distance = Coordinate:DistanceFromPointVec2( self.CargoObject:GetPointVec2() )
self:T( Distance )
if Distance <= self.NearRadius then
return true
end
end
return false
end
--- Get the current Coordinate of the CargoGroup. --- Get the current Coordinate of the CargoGroup.
-- @param #CARGO_CRATE self -- @param #CARGO_CRATE self
-- @return Core.Point#COORDINATE The current Coordinate of the first Cargo of the CargoGroup. -- @return Core.Point#COORDINATE The current Coordinate of the first Cargo of the CargoGroup.
@ -188,28 +209,6 @@ do -- CARGO_CRATE
end end
--- Check if CargoGroup is in the ReportRadius for the Cargo to be Loaded.
-- @param #CARGO_CRATE self
-- @param Core.Point#Coordinate Coordinate
-- @return #boolean true if the CargoGroup is within the reporting radius.
function CARGO_CRATE:IsInRadius( Coordinate )
self:F( { Coordinate } )
local Distance = 0
if self:IsLoaded() then
Distance = Coordinate:DistanceFromPointVec2( self.CargoCarrier:GetPointVec2() )
else
Distance = Coordinate:DistanceFromPointVec2( self.CargoObject:GetPointVec2() )
end
self:T( Distance )
if Distance <= self.ReportRadius then
return true
else
return false
end
end
--- Respawn the CargoGroup. --- Respawn the CargoGroup.
-- @param #CARGO_CRATE self -- @param #CARGO_CRATE self
function CARGO_CRATE:Respawn() function CARGO_CRATE:Respawn()

View File

@ -23,7 +23,7 @@
do -- CARGO_GROUP do -- CARGO_GROUP
--- @type CARGO_GROUP --- @type CARGO_GROUP
-- @extends #CARGO_REPORTABLE -- @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.
@ -45,12 +45,12 @@ do -- CARGO_GROUP
-- @param Wrapper.Group#GROUP CargoGroup -- @param Wrapper.Group#GROUP CargoGroup
-- @param #string Type -- @param #string Type
-- @param #string Name -- @param #string Name
-- @param #number ReportRadius (optional) -- @param #number LoadRadius (optional)
-- @param #number NearRadius (optional) -- @param #number NearRadius (optional)
-- @return #CARGO_GROUP -- @return #CARGO_GROUP
function CARGO_GROUP:New( CargoGroup, Type, Name, ReportRadius ) function CARGO_GROUP:New( CargoGroup, Type, Name, LoadRadius )
local self = BASE:Inherit( self, CARGO_REPORTABLE:New( Type, Name, 0, ReportRadius ) ) -- #CARGO_GROUP local self = BASE:Inherit( self, CARGO_REPORTABLE:New( Type, Name, 0, LoadRadius ) ) -- #CARGO_GROUP
self:F( { Type, Name, ReportRadius } ) self:F( { Type, Name, LoadRadius } )
self.CargoSet = SET_CARGO:New() self.CargoSet = SET_CARGO:New()
@ -455,11 +455,11 @@ function CARGO_GROUP:OnEventCargoDead( EventData )
return nil return nil
end end
--- Check if CargoGroup is in the ReportRadius for the Cargo to be Loaded. --- Check if Cargo Group is in the radius for the Cargo to be Boarded.
-- @param #CARGO_GROUP self -- @param #CARGO_GROUP self
-- @param Core.Point#Coordinate Coordinate -- @param Core.Point#Coordinate Coordinate
-- @return #boolean true if the CargoGroup is within the reporting radius. -- @return #boolean true if the Cargo Group is within the load radius.
function CARGO_GROUP:IsInRadius( Coordinate ) function CARGO_GROUP:IsInLoadRadius( Coordinate )
self:F( { Coordinate } ) self:F( { Coordinate } )
local Cargo = self.CargoSet:GetFirst() -- #CARGO local Cargo = self.CargoSet:GetFirst() -- #CARGO
@ -473,7 +473,7 @@ function CARGO_GROUP:OnEventCargoDead( EventData )
end end
self:T( Distance ) self:T( Distance )
if Distance <= self.ReportRadius then if Distance <= self.LoadRadius then
return true return true
else else
return false return false
@ -484,6 +484,31 @@ function CARGO_GROUP:OnEventCargoDead( EventData )
end end
--- Check if Cargo Group is in the report radius.
-- @param #CARGO_GROUP self
-- @param Core.Point#Coordinate Coordinate
-- @return #boolean true if the Cargo Group is within the report radius.
function CARGO_GROUP:IsInReportRadius( Coordinate )
self:F( { Coordinate } )
local Cargo = self.CargoSet:GetFirst() -- #CARGO
if Cargo then
local Distance = 0
if Cargo:IsUnLoaded() then
Distance = Coordinate:DistanceFromPointVec2( Cargo.CargoObject:GetPointVec2() )
self:T( Distance )
if Distance <= self.LoadRadius then
return true
end
end
end
return nil
end
--- Respawn the CargoGroup. --- Respawn the CargoGroup.
-- @param #CARGO_GROUP self -- @param #CARGO_GROUP self
function CARGO_GROUP:Respawn() function CARGO_GROUP:Respawn()

View File

@ -24,7 +24,7 @@ do -- CARGO_SLINGLOAD
--- Models the behaviour of cargo crates, which can only be slingloaded. --- Models the behaviour of cargo crates, which can only be slingloaded.
-- @type CARGO_SLINGLOAD -- @type CARGO_SLINGLOAD
-- @extends #CARGO_REPRESENTABLE -- @extends Cargo.Cargo#CARGO_REPRESENTABLE
--- # CARGO\_CRATE class, extends @{#CARGO_REPRESENTABLE} --- # CARGO\_CRATE class, extends @{#CARGO_REPRESENTABLE}
-- --
@ -42,11 +42,11 @@ do -- CARGO_SLINGLOAD
-- @param Wrapper.Static#STATIC CargoStatic -- @param Wrapper.Static#STATIC CargoStatic
-- @param #string Type -- @param #string Type
-- @param #string Name -- @param #string Name
-- @param #number ReportRadius (optional) -- @param #number LoadRadius (optional)
-- @param #number NearRadius (optional) -- @param #number NearRadius (optional)
-- @return #CARGO_SLINGLOAD -- @return #CARGO_SLINGLOAD
function CARGO_SLINGLOAD:New( CargoStatic, Type, Name, ReportRadius, NearRadius ) function CARGO_SLINGLOAD:New( CargoStatic, Type, Name, LoadRadius, NearRadius )
local self = BASE:Inherit( self, CARGO_REPRESENTABLE:New( CargoStatic, Type, Name, nil, ReportRadius, NearRadius ) ) -- #CARGO_SLINGLOAD local self = BASE:Inherit( self, CARGO_REPRESENTABLE:New( CargoStatic, Type, Name, nil, LoadRadius, NearRadius ) ) -- #CARGO_SLINGLOAD
self:F( { Type, Name, NearRadius } ) self:F( { Type, Name, NearRadius } )
self.CargoObject = CargoStatic self.CargoObject = CargoStatic
@ -90,6 +90,28 @@ do -- CARGO_SLINGLOAD
return false return false
end end
--- Check if Cargo Slingload is in the radius for the Cargo to be Boarded or Loaded.
-- @param #CARGO_SLINGLOAD self
-- @param Core.Point#Coordinate Coordinate
-- @return #boolean true if the Cargo Slingload is within the loading radius.
function CARGO_SLINGLOAD:IsInLoadRadius( Coordinate )
self:F( { Coordinate } )
local Distance = 0
if self:IsUnLoaded() then
Distance = Coordinate:DistanceFromPointVec2( self.CargoObject:GetPointVec2() )
self:T( Distance )
if Distance <= self.NearRadius then
return true
end
end
return false
end
--- Get the current Coordinate of the CargoGroup. --- Get the current Coordinate of the CargoGroup.
-- @param #CARGO_SLINGLOAD self -- @param #CARGO_SLINGLOAD self
-- @return Core.Point#COORDINATE The current Coordinate of the first Cargo of the CargoGroup. -- @return Core.Point#COORDINATE The current Coordinate of the first Cargo of the CargoGroup.
@ -144,28 +166,6 @@ do -- CARGO_SLINGLOAD
end end
--- Check if CargoGroup is in the ReportRadius for the Cargo to be Loaded.
-- @param #CARGO_SLINGLOAD self
-- @param Core.Point#Coordinate Coordinate
-- @return #boolean true if the CargoGroup is within the reporting radius.
function CARGO_SLINGLOAD:IsInRadius( Coordinate )
self:F( { Coordinate } )
local Distance = 0
if self:IsLoaded() then
Distance = Coordinate:DistanceFromPointVec2( self.CargoCarrier:GetPointVec2() )
else
Distance = Coordinate:DistanceFromPointVec2( self.CargoObject:GetPointVec2() )
end
self:T( Distance )
if Distance <= self.ReportRadius then
return true
else
return false
end
end
--- Respawn the CargoGroup. --- Respawn the CargoGroup.
-- @param #CARGO_SLINGLOAD self -- @param #CARGO_SLINGLOAD self
function CARGO_SLINGLOAD:Respawn() function CARGO_SLINGLOAD:Respawn()

View File

@ -23,7 +23,7 @@ do -- CARGO_UNIT
--- Models CARGO in the form of units, which can be boarded, unboarded, loaded, unloaded. --- Models CARGO in the form of units, which can be boarded, unboarded, loaded, unloaded.
-- @type CARGO_UNIT -- @type CARGO_UNIT
-- @extends #CARGO_REPRESENTABLE -- @extends Cargo.Cargo#CARGO_REPRESENTABLE
--- # CARGO\_UNIT class, extends @{#CARGO_REPRESENTABLE} --- # CARGO\_UNIT class, extends @{#CARGO_REPRESENTABLE}
-- --
@ -44,7 +44,7 @@ do -- CARGO_UNIT
-- @param #string Type -- @param #string Type
-- @param #string Name -- @param #string Name
-- @param #number Weight -- @param #number Weight
-- @param #number ReportRadius (optional) -- @param #number LoadRadius (optional)
-- @param #number NearRadius (optional) -- @param #number NearRadius (optional)
-- @return #CARGO_UNIT -- @return #CARGO_UNIT
function CARGO_UNIT:New( CargoUnit, Type, Name, Weight, NearRadius ) function CARGO_UNIT:New( CargoUnit, Type, Name, Weight, NearRadius )
@ -82,42 +82,48 @@ do -- CARGO_UNIT
if not self:IsDestroyed() then if not self:IsDestroyed() then
local CargoCarrier = self.CargoCarrier -- Wrapper.Controllable#CONTROLLABLE local CargoCarrier = self.CargoCarrier -- Wrapper.Controllable#CONTROLLABLE
local CargoCarrierPointVec2 = CargoCarrier:GetPointVec2()
local CargoCarrierHeading = self.CargoCarrier:GetHeading() -- Get Heading of object in degrees.
local CargoDeployHeading = ( ( CargoCarrierHeading + Angle ) >= 360 ) and ( CargoCarrierHeading + Angle - 360 ) or ( CargoCarrierHeading + Angle )
local CargoRoutePointVec2 = CargoCarrierPointVec2:Translate( RouteDistance, CargoDeployHeading )
if CargoCarrier:IsAlive() then
-- if there is no ToPointVec2 given, then use the CargoRoutePointVec2
local FromDirectionVec3 = CargoCarrierPointVec2:GetDirectionVec3( ToPointVec2 or CargoRoutePointVec2 )
local FromAngle = CargoCarrierPointVec2:GetAngleDegrees(FromDirectionVec3)
local FromPointVec2 = CargoCarrierPointVec2:Translate( DeployDistance, FromAngle )
--local CargoDeployPointVec2 = CargoCarrierPointVec2:GetRandomCoordinateInRadius( 10, 5 )
ToPointVec2 = ToPointVec2 or CargoCarrierPointVec2:GetRandomCoordinateInRadius( NearRadius, DeployDistance )
-- Respawn the group...
if self.CargoObject then
self.CargoObject:ReSpawn( FromPointVec2:GetVec3(), CargoDeployHeading )
self:F( { "CargoUnits:", self.CargoObject:GetGroup():GetName() } )
self.CargoCarrier = nil
local Points = {} local CargoCarrierPointVec2 = CargoCarrier:GetPointVec2()
local CargoCarrierHeading = self.CargoCarrier:GetHeading() -- Get Heading of object in degrees.
-- From local CargoDeployHeading = ( ( CargoCarrierHeading + Angle ) >= 360 ) and ( CargoCarrierHeading + Angle - 360 ) or ( CargoCarrierHeading + Angle )
Points[#Points+1] = FromPointVec2:WaypointGround( Speed, "Vee" )
-- To
Points[#Points+1] = ToPointVec2:WaypointGround( Speed, "Vee" )
local TaskRoute = self.CargoObject:TaskRoute( Points )
self.CargoObject:SetTask( TaskRoute, 1 ) local CargoRoutePointVec2 = CargoCarrierPointVec2:Translate( RouteDistance, CargoDeployHeading )
self:__UnBoarding( 1, ToPointVec2, NearRadius )
-- if there is no ToPointVec2 given, then use the CargoRoutePointVec2
local FromDirectionVec3 = CargoCarrierPointVec2:GetDirectionVec3( ToPointVec2 or CargoRoutePointVec2 )
local FromAngle = CargoCarrierPointVec2:GetAngleDegrees(FromDirectionVec3)
local FromPointVec2 = CargoCarrierPointVec2:Translate( DeployDistance, FromAngle )
--local CargoDeployPointVec2 = CargoCarrierPointVec2:GetRandomCoordinateInRadius( 10, 5 )
ToPointVec2 = ToPointVec2 or CargoCarrierPointVec2:GetRandomCoordinateInRadius( NearRadius, DeployDistance )
-- Respawn the group...
if self.CargoObject then
self.CargoObject:ReSpawn( FromPointVec2:GetVec3(), CargoDeployHeading )
self:F( { "CargoUnits:", self.CargoObject:GetGroup():GetName() } )
self.CargoCarrier = nil
local Points = {}
-- From
Points[#Points+1] = FromPointVec2:WaypointGround( Speed, "Vee" )
-- To
Points[#Points+1] = ToPointVec2:WaypointGround( Speed, "Vee" )
local TaskRoute = self.CargoObject:TaskRoute( Points )
self.CargoObject:SetTask( TaskRoute, 1 )
self:__UnBoarding( 1, ToPointVec2, NearRadius )
end
else
-- the Carrier is dead. This cargo is dead too!
self:Destroyed()
end end
end end
end end
@ -225,7 +231,11 @@ do -- CARGO_UNIT
local NearRadius = NearRadius or 25 local NearRadius = NearRadius or 25
self.CargoInAir = self.CargoObject:InAir() self.CargoInAir = self.CargoObject:InAir()
local Desc = self.CargoObject:GetDesc()
local MaxSpeed = Desc.speedMaxOffRoad
local TypeName = Desc.typeName
self:T( self.CargoInAir ) self:T( self.CargoInAir )
-- Only move the group to the carrier when the cargo is not in the air -- Only move the group to the carrier when the cargo is not in the air
@ -234,28 +244,33 @@ do -- CARGO_UNIT
if self:IsNear( CargoCarrier:GetPointVec2(), NearRadius ) then if self:IsNear( CargoCarrier:GetPointVec2(), NearRadius ) then
self:Load( CargoCarrier, NearRadius, ... ) self:Load( CargoCarrier, NearRadius, ... )
else else
local Speed = 90 if MaxSpeed and MaxSpeed == 0 or TypeName and TypeName == "Stinger comm" then
local Angle = 180 self:Load( CargoCarrier, NearRadius, ... )
local Distance = 5 else
local Speed = 90
local Angle = 180
local Distance = 5
NearRadius = NearRadius or 25
NearRadius = NearRadius or 25 local CargoCarrierPointVec2 = CargoCarrier:GetPointVec2()
local CargoCarrierHeading = CargoCarrier:GetHeading() -- Get Heading of object in degrees.
local CargoCarrierPointVec2 = CargoCarrier:GetPointVec2() local CargoDeployHeading = ( ( CargoCarrierHeading + Angle ) >= 360 ) and ( CargoCarrierHeading + Angle - 360 ) or ( CargoCarrierHeading + Angle )
local CargoCarrierHeading = CargoCarrier:GetHeading() -- Get Heading of object in degrees. local CargoDeployPointVec2 = CargoCarrierPointVec2:Translate( Distance, CargoDeployHeading )
local CargoDeployHeading = ( ( CargoCarrierHeading + Angle ) >= 360 ) and ( CargoCarrierHeading + Angle - 360 ) or ( CargoCarrierHeading + Angle )
local CargoDeployPointVec2 = CargoCarrierPointVec2:Translate( Distance, CargoDeployHeading ) local Points = {}
local Points = {} local PointStartVec2 = self.CargoObject:GetPointVec2()
local PointStartVec2 = self.CargoObject:GetPointVec2() Points[#Points+1] = PointStartVec2:WaypointGround( Speed )
Points[#Points+1] = CargoDeployPointVec2:WaypointGround( Speed )
Points[#Points+1] = PointStartVec2:WaypointGround( Speed )
Points[#Points+1] = CargoDeployPointVec2:WaypointGround( Speed ) local TaskRoute = self.CargoObject:TaskRoute( Points )
self.CargoObject:SetTask( TaskRoute, 2 )
local TaskRoute = self.CargoObject:TaskRoute( Points ) self:__Boarding( -1, CargoCarrier, NearRadius )
self.CargoObject:SetTask( TaskRoute, 2 ) self.RunCount = 0
self:__Boarding( -1, CargoCarrier, NearRadius ) end
self.RunCount = 0
end end
end end

View File

@ -4131,6 +4131,19 @@ function SET_CARGO:New() --R2.1
return self return self
end end
--- (R2.1) Add CARGO to SET_CARGO.
-- @param Core.Set#SET_CARGO self
-- @param Cargo.Cargo#CARGO Cargo A single cargo.
-- @return self
function SET_CARGO:AddCargo( Cargo ) --R2.4
self:Add( Cargo:GetName(), Cargo )
return self
end
--- (R2.1) Add CARGOs to SET_CARGO. --- (R2.1) Add CARGOs to SET_CARGO.
-- @param Core.Set#SET_CARGO self -- @param Core.Set#SET_CARGO self
-- @param #string AddCargoNames A single name or an array of CARGO names. -- @param #string AddCargoNames A single name or an array of CARGO names.

View File

@ -603,6 +603,7 @@ function ZONE_RADIUS:Scan( ObjectCategories )
self.ScanData = {} self.ScanData = {}
self.ScanData.Coalitions = {} self.ScanData.Coalitions = {}
self.ScanData.Scenery = {} self.ScanData.Scenery = {}
self.ScanData.Units = {}
local ZoneCoord = self:GetCoordinate() local ZoneCoord = self:GetCoordinate()
local ZoneRadius = self:GetRadius() local ZoneRadius = self:GetRadius()
@ -625,6 +626,7 @@ function ZONE_RADIUS:Scan( ObjectCategories )
(ObjectCategory == Object.Category.STATIC and ZoneObject:isExist()) then (ObjectCategory == Object.Category.STATIC and ZoneObject:isExist()) then
local CoalitionDCSUnit = ZoneObject:getCoalition() local CoalitionDCSUnit = ZoneObject:getCoalition()
self.ScanData.Coalitions[CoalitionDCSUnit] = true self.ScanData.Coalitions[CoalitionDCSUnit] = true
self.ScanData.Units[ZoneObject] = ZoneObject
self:F( { Name = ZoneObject:getName(), Coalition = CoalitionDCSUnit } ) self:F( { Name = ZoneObject:getName(), Coalition = CoalitionDCSUnit } )
end end
if ObjectCategory == Object.Category.SCENERY then if ObjectCategory == Object.Category.SCENERY then
@ -643,6 +645,12 @@ function ZONE_RADIUS:Scan( ObjectCategories )
end end
function ZONE_RADIUS:GetScannedUnits()
return self.ScanData.Units
end
function ZONE_RADIUS:CountScannedCoalitions() function ZONE_RADIUS:CountScannedCoalitions()
local Count = 0 local Count = 0

View File

@ -230,7 +230,7 @@ do -- TASK_CARGO
Task.SetCargo:ForEachCargo( Task.SetCargo:ForEachCargo(
--- @param Core.Cargo#CARGO Cargo --- @param Cargo.Cargo#CARGO Cargo
function( Cargo ) function( Cargo )
if Cargo:IsAlive() then if Cargo:IsAlive() then
@ -250,7 +250,7 @@ do -- TASK_CARGO
if Cargo:IsUnLoaded() then if Cargo:IsUnLoaded() then
if CargoItemCount <= Task.CargoLimit then if CargoItemCount <= Task.CargoLimit then
if Cargo:IsInRadius( TaskUnit:GetPointVec2() ) then if Cargo:IsInReportRadius( TaskUnit:GetPointVec2() ) then
local NotInDeployZones = true local NotInDeployZones = true
for DeployZoneName, DeployZone in pairs( Task.DeployZones ) do for DeployZoneName, DeployZone in pairs( Task.DeployZones ) do
if Cargo:IsInZone( DeployZone ) then if Cargo:IsInZone( DeployZone ) then
@ -260,23 +260,53 @@ do -- TASK_CARGO
if NotInDeployZones then if NotInDeployZones then
if not TaskUnit:InAir() then if not TaskUnit:InAir() then
if Cargo:CanBoard() == true then if Cargo:CanBoard() == true then
MENU_GROUP_COMMAND:New( TaskUnit:GetGroup(), "Board cargo " .. Cargo.Name, TaskUnit.Menu, self.MenuBoardCargo, self, Cargo ):SetTime(MenuTime) if Cargo:IsInLoadRadius( TaskUnit:GetPointVec2() ) then
Cargo:Report( "Reporting for boarding at " .. Cargo:GetCoordinate():ToString( TaskUnit:GetGroup() ), "board", TaskUnit:GetGroup() )
MENU_GROUP_COMMAND:New( TaskUnit:GetGroup(), "Board cargo " .. Cargo.Name, TaskUnit.Menu, self.MenuBoardCargo, self, Cargo ):SetTime(MenuTime)
else
Cargo:Report( "Reporting at " .. Cargo:GetCoordinate():ToString( TaskUnit:GetGroup() ), "reporting", TaskUnit:GetGroup() )
end
else else
if Cargo:CanLoad() == true then if Cargo:CanLoad() == true then
MENU_GROUP_COMMAND:New( TaskUnit:GetGroup(), "Load cargo " .. Cargo.Name, TaskUnit.Menu, self.MenuLoadCargo, self, Cargo ):SetTime(MenuTime) if Cargo:IsInLoadRadius( TaskUnit:GetPointVec2() ) then
Cargo:Report( "Reporting for loading at " .. Cargo:GetCoordinate():ToString( TaskUnit:GetGroup() ), "load", TaskUnit:GetGroup() )
MENU_GROUP_COMMAND:New( TaskUnit:GetGroup(), "Load cargo " .. Cargo.Name, TaskUnit.Menu, self.MenuLoadCargo, self, Cargo ):SetTime(MenuTime)
else
Cargo:Report( "Reporting at " .. Cargo:GetCoordinate():ToString( TaskUnit:GetGroup() ), "reporting", TaskUnit:GetGroup() )
end
end end
end end
TaskUnit.Menu:SetTime( MenuTime ) TaskUnit.Menu:SetTime( MenuTime )
else
Cargo:ReportResetAll( TaskUnit:GetGroup() )
end end
end end
else else
MENU_GROUP_COMMAND:New( TaskUnit:GetGroup(), "Route to Pickup cargo " .. Cargo.Name, TaskUnit.Menu, self.MenuRouteToPickup, self, Cargo ):SetTime(MenuTime) MENU_GROUP_COMMAND:New( TaskUnit:GetGroup(), "Route to Pickup cargo " .. Cargo.Name, TaskUnit.Menu, self.MenuRouteToPickup, self, Cargo ):SetTime(MenuTime)
TaskUnit.Menu:SetTime( MenuTime ) TaskUnit.Menu:SetTime( MenuTime )
Cargo:ReportResetAll( TaskUnit:GetGroup() )
end end
end end
-- Cargo in deployzones are flagged as deployed.
for DeployZoneName, DeployZone in pairs( Task.DeployZones ) do
if Cargo:IsInZone( DeployZone ) then
if not Cargo:IsDeployed() then
Cargo:SetDeployed( true )
-- TODO:I need to find a more decent solution for this.
Task:E( { CargoDeployed = Task.CargoDeployed and "true" or "false" } )
Task:E( { CargoIsAlive = Cargo:IsAlive() and "true" or "false" } )
if Cargo:IsAlive() then
if Task.CargoDeployed then
Task:CargoDeployed( TaskUnit, Cargo, DeployZone )
end
end
end
end
end
end end
if Cargo:IsLoaded() then if Cargo:IsLoaded() == true and Cargo:IsLoadedInCarrier( TaskUnit ) == true then
if not TaskUnit:InAir() then if not TaskUnit:InAir() then
if Cargo:CanUnboard() == true then if Cargo:CanUnboard() == true then
MENU_GROUP_COMMAND:New( TaskUnit:GetGroup(), "Unboard cargo " .. Cargo.Name, TaskUnit.Menu, self.MenuUnboardCargo, self, Cargo ):SetTime(MenuTime) MENU_GROUP_COMMAND:New( TaskUnit:GetGroup(), "Unboard cargo " .. Cargo.Name, TaskUnit.Menu, self.MenuUnboardCargo, self, Cargo ):SetTime(MenuTime)
@ -303,7 +333,7 @@ do -- TASK_CARGO
TaskUnit.Menu:Remove( MenuTime ) TaskUnit.Menu:Remove( MenuTime )
self:__SelectAction( -15 ) self:__SelectAction( -1 )
end end
@ -441,7 +471,7 @@ do -- TASK_CARGO
self:F( { TaskUnit = TaskUnit, Task = Task and Task:GetClassNameAndID() } ) self:F( { TaskUnit = TaskUnit, Task = Task and Task:GetClassNameAndID() } )
if self.Cargo:IsAlive() then if self.Cargo:IsAlive() then
if self.Cargo:IsInRadius( TaskUnit:GetPointVec2() ) then if self.Cargo:IsInLoadRadius( TaskUnit:GetPointVec2() ) then
if TaskUnit:InAir() then if TaskUnit:InAir() then
self:__Land( -10, Action ) self:__Land( -10, Action )
else else
@ -465,7 +495,7 @@ do -- TASK_CARGO
self:F( { TaskUnit = TaskUnit, Task = Task and Task:GetClassNameAndID() } ) self:F( { TaskUnit = TaskUnit, Task = Task and Task:GetClassNameAndID() } )
if self.Cargo:IsAlive() then if self.Cargo:IsAlive() then
if self.Cargo:IsInRadius( TaskUnit:GetPointVec2() ) then if self.Cargo:IsInLoadRadius( TaskUnit:GetPointVec2() ) then
if TaskUnit:InAir() then if TaskUnit:InAir() then
self:__Land( -0.1, Action ) self:__Land( -0.1, Action )
else else
@ -506,7 +536,7 @@ do -- TASK_CARGO
end end
if self.Cargo:IsAlive() then if self.Cargo:IsAlive() then
if self.Cargo:IsInRadius( TaskUnit:GetPointVec2() ) then if self.Cargo:IsInLoadRadius( TaskUnit:GetPointVec2() ) then
if TaskUnit:InAir() then if TaskUnit:InAir() then
--- ABORT the boarding. Split group if any and go back to select action. --- ABORT the boarding. Split group if any and go back to select action.
else else
@ -649,26 +679,6 @@ do -- TASK_CARGO
end end
end end
TaskUnit:RemoveCargo( Cargo ) TaskUnit:RemoveCargo( Cargo )
local NotInDeployZones = true
for DeployZoneName, DeployZone in pairs( Task.DeployZones ) do
if Cargo:IsInZone( DeployZone ) then
NotInDeployZones = false
end
end
if NotInDeployZones == false then
Cargo:SetDeployed( true )
end
-- TODO:I need to find a more decent solution for this.
Task:E( { CargoDeployed = Task.CargoDeployed and "true" or "false" } )
Task:E( { CargoIsAlive = Cargo:IsAlive() and "true" or "false" } )
if Cargo:IsAlive() then
if Task.CargoDeployed then
Task:CargoDeployed( TaskUnit, Cargo, self.DeployZone )
end
end
self:Planned() self:Planned()
self:__SelectAction( 1 ) self:__SelectAction( 1 )
@ -739,7 +749,7 @@ do -- TASK_CARGO
local ActRouteCargo = ProcessUnit:GetProcess( "RoutingToPickup", "RouteToPickupPoint" ) -- Actions.Act_Route#ACT_ROUTE_POINT local ActRouteCargo = ProcessUnit:GetProcess( "RoutingToPickup", "RouteToPickupPoint" ) -- Actions.Act_Route#ACT_ROUTE_POINT
ActRouteCargo:Reset() ActRouteCargo:Reset()
ActRouteCargo:SetCoordinate( Cargo:GetCoordinate() ) ActRouteCargo:SetCoordinate( Cargo:GetCoordinate() )
ActRouteCargo:SetRange( Cargo:GetBoardingRange() ) ActRouteCargo:SetRange( Cargo:GetLoadRadius() )
ActRouteCargo:SetMenuCancel( TaskUnit:GetGroup(), "Cancel Routing to Cargo " .. Cargo:GetName(), TaskUnit.Menu ) ActRouteCargo:SetMenuCancel( TaskUnit:GetGroup(), "Cancel Routing to Cargo " .. Cargo:GetName(), TaskUnit.Menu )
ActRouteCargo:Start() ActRouteCargo:Start()
return self return self

View File

@ -1892,7 +1892,7 @@ end
-- @param #CONTROLLABLE self -- @param #CONTROLLABLE self
-- @return #CONTROLLABLE -- @return #CONTROLLABLE
function CONTROLLABLE:RouteStop() function CONTROLLABLE:RouteStop()
self:F2() self:F("RouteStop")
local CommandStop = self:CommandStopRoute( true ) local CommandStop = self:CommandStopRoute( true )
self:SetCommand( CommandStop ) self:SetCommand( CommandStop )
@ -1903,7 +1903,7 @@ end
-- @param #CONTROLLABLE self -- @param #CONTROLLABLE self
-- @return #CONTROLLABLE -- @return #CONTROLLABLE
function CONTROLLABLE:RouteResume() function CONTROLLABLE:RouteResume()
self:F2() self:F("RouteResume")
local CommandResume = self:CommandStopRoute( false ) local CommandResume = self:CommandStopRoute( false )
self:SetCommand( CommandResume ) self:SetCommand( CommandResume )

View File

@ -239,14 +239,17 @@ end
-- Note that this destroy method also raises a destroy event at run-time. -- Note that this destroy method also raises a destroy event at run-time.
-- So all event listeners will catch the destroy event of this DCS Group. -- So all event listeners will catch the destroy event of this DCS Group.
-- @param #GROUP self -- @param #GROUP self
function GROUP:Destroy() -- @param #boolean GenerateEvent
function GROUP:Destroy( GenerateEvent )
self:F2( self.GroupName ) self:F2( self.GroupName )
local DCSGroup = self:GetDCSObject() local DCSGroup = self:GetDCSObject()
if DCSGroup then if DCSGroup then
for Index, UnitData in pairs( DCSGroup:getUnits() ) do if not GenerateEvent then
self:CreateEventCrash( timer.getTime(), UnitData ) for Index, UnitData in pairs( DCSGroup:getUnits() ) do
self:CreateEventCrash( timer.getTime(), UnitData )
end
end end
USERFLAG:New( self:GetName() ):Set( 100 ) USERFLAG:New( self:GetName() ):Set( 100 )
DCSGroup:destroy() DCSGroup:destroy()

View File

@ -229,6 +229,26 @@ function IDENTIFIABLE:GetDesc()
return nil return nil
end end
--- Check if the Object has the attribute.
-- @param #IDENTIFIABLE self
-- @param #string AttributeName The attribute name.
-- @return #boolean true if the attribute exists.
-- @return #nil The DCS Identifiable is not existing or alive.
function IDENTIFIABLE:HasAttribute( AttributeName )
self:F2( self.IdentifiableName )
local DCSIdentifiable = self:GetDCSObject()
if DCSIdentifiable then
local IdentifiableHasAttribute = DCSIdentifiable:hasAttribute( AttributeName )
self:T2( IdentifiableHasAttribute )
return IdentifiableHasAttribute
end
self:F( self.ClassName .. " " .. self.IdentifiableName .. " not found!" )
return nil
end
--- Gets the CallSign of the IDENTIFIABLE, which is a blank by default. --- Gets the CallSign of the IDENTIFIABLE, which is a blank by default.
-- @param #IDENTIFIABLE self -- @param #IDENTIFIABLE self
-- @return #string The CallSign of the IDENTIFIABLE. -- @return #string The CallSign of the IDENTIFIABLE.

View File

@ -91,3 +91,5 @@ end