diff --git a/Moose Development/Moose/AI/AI_Cargo_Troops.lua b/Moose Development/Moose/AI/AI_Cargo_Troops.lua index 754409aeb..2051fa22d 100644 --- a/Moose Development/Moose/AI/AI_Cargo_Troops.lua +++ b/Moose Development/Moose/AI/AI_Cargo_Troops.lua @@ -24,19 +24,16 @@ AI_CARGO_TROOPS = { --- Creates a new AI_CARGO_TROOPS object. -- @param #AI_CARGO_TROOPS self +-- @param Wrapper.Unit#UNIT CargoCarrier +-- @param Cargo.CargoGroup#CARGO_GROUP CargoGroup +-- @param #number CombatRadius -- @return #AI_CARGO_TROOPS function AI_CARGO_TROOPS:New( CargoCarrier, CargoGroup, CombatRadius ) local self = BASE:Inherit( self, FSM_CONTROLLABLE:New( ) ) -- #AI_CARGO_TROOPS - self.CargoCarrier = CargoCarrier -- Wrapper.Unit#UNIT - self.CargoGroup = CargoGroup -- Core.Cargo#CARGO_GROUP + self.CargoGroup = CargoGroup -- Cargo.CargoGroup#CARGO_GROUP 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" ) @@ -50,14 +47,91 @@ function AI_CARGO_TROOPS:New( CargoCarrier, CargoGroup, CombatRadius ) self:AddTransition( "*", "Monitor", "*" ) self:AddTransition( "*", "Follow", "Following" ) self:AddTransition( "*", "Guard", "Guarding" ) + + self:AddTransition( "*", "Destroyed", "Destroyed" ) self:__Monitor( 1 ) - self:__Load( 1 ) + + self:SetCarrier( CargoCarrier ) return self 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. -- @param #AI_CARGO_TROOPS self -- @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() } ) - -- We check if the Cargo is near to the CargoCarrier. - if InfantryGroup:IsPartlyInZone( ZONE_UNIT:New( "Radius", CargoCarrier, 5 ) ) then + --if self:Is( "Following" ) then - -- The Cargo does not need to follow the Carrier. - Me:Guard() + if CargoCarrier:IsAlive() then + -- 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() } ) - - if InfantryGroup:IsAlive() then - + else + 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 @@ -132,6 +210,22 @@ function AI_CARGO_TROOPS:onafterMonitor( CargoCarrier, From, Event, To ) self:Follow() 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 self.CarrierCoordinate = CargoCarrier:GetCoordinate() end @@ -149,7 +243,7 @@ function AI_CARGO_TROOPS:onafterLoad( CargoCarrier, From, Event, To ) if CargoCarrier and CargoCarrier:IsAlive() then CargoCarrier:RouteStop() self:__Board( 10 ) - self.CargoGroup:Board( CargoCarrier, 100 ) + self.CargoGroup:Board( CargoCarrier, 10 ) end end diff --git a/Moose Development/Moose/Cargo/Cargo.lua b/Moose Development/Moose/Cargo/Cargo.lua index 2528b1b32..cacd5fa64 100644 --- a/Moose Development/Moose/Cargo/Cargo.lua +++ b/Moose Development/Moose/Cargo/Cargo.lua @@ -224,6 +224,7 @@ do -- CARGO Slingloadable = false, Moveable = false, Containable = false, + Reported = {}, } --- @type CARGO.CargoObjects @@ -235,12 +236,13 @@ do -- CARGO -- @param #string Type -- @param #string Name -- @param #number Weight + -- @param #number LoadRadius (optional) -- @param #number NearRadius (optional) -- @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 - self:F( { Type, Name, Weight } ) + self:F( { Type, Name, Weight, LoadRadius, NearRadius } ) self:SetStartState( "UnLoaded" ) self:AddTransition( { "UnLoaded", "Boarding" }, "Board", "Boarding" ) @@ -267,6 +269,9 @@ do -- CARGO self.Moveable = false self.Containable = false + self.LoadRadius = LoadRadius or 500 + self.NearRadius = NearRadius or 25 + self:SetDeployed( false ) self.CargoScheduler = SCHEDULER:New() @@ -320,7 +325,7 @@ do -- CARGO -- @param #CARGO self function CARGO:Destroy() if self.CargoObject then - self.CargoObject:Destroy() + self.CargoObject:Destroy( false ) end self:Destroyed() end @@ -379,6 +384,14 @@ do -- CARGO return self:Is( "Loaded" ) 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. -- @param #CARGO self -- @return #boolean true if unloaded @@ -405,8 +418,9 @@ do -- CARGO end end - --- Set the cargo as deployed + --- Set the cargo as deployed. -- @param #CARGO self + -- @param #boolean Deployed true if the cargo is to be deployed. false or nil otherwise. function CARGO:SetDeployed( Deployed ) self.Deployed = Deployed end @@ -507,7 +521,88 @@ do -- CARGO 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 - --- 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. -- @param #CARGO self -- @return Core.Point#POINT_VEC2 @@ -580,6 +651,85 @@ do -- CARGO self.Weight = Weight return self 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 @@ -600,16 +750,13 @@ do -- CARGO_REPRESENTABLE -- @param #string Type -- @param #string Name -- @param #number Weight - -- @param #number ReportRadius (optional) + -- @param #number LoadRadius (optional) -- @param #number NearRadius (optional) -- @return #CARGO_REPRESENTABLE - function CARGO_REPRESENTABLE:New( CargoObject, Type, Name, Weight, ReportRadius, NearRadius ) - local self = BASE:Inherit( self, CARGO:New( Type, Name, Weight ) ) -- #CARGO_REPRESENTABLE - self:F( { 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, LoadRadius, NearRadius ) ) -- #CARGO_REPRESENTABLE + self:F( { Type, Name, Weight, LoadRadius, NearRadius } ) - self.ReportRadius = ReportRadius or 500 - self.NearRadius = NearRadius or 25 - return self end @@ -661,14 +808,12 @@ do -- CARGO_REPORTABLE -- @param #string Type -- @param #string Name -- @param #number Weight - -- @param #number ReportRadius (optional) + -- @param #number LoadRadius (optional) -- @param #number NearRadius (optional) -- @return #CARGO_REPORTABLE - function CARGO_REPORTABLE:New( Type, Name, Weight, ReportRadius ) - local self = BASE:Inherit( self, CARGO:New( Type, Name, Weight ) ) -- #CARGO_REPORTABLE - self:F( { Type, Name, Weight, ReportRadius } ) - - self.ReportRadius = ReportRadius or 1000 + function CARGO_REPORTABLE:New( Type, Name, Weight, LoadRadius, NearRadius ) + local self = BASE:Inherit( self, CARGO:New( Type, Name, Weight, LoadRadius, NearRadius ) ) -- #CARGO_REPORTABLE + self:F( { Type, Name, Weight, LoadRadius, NearRadius } ) return self 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. function CARGO_REPORTABLE:MessageToGroup( Message, TaskGroup, Name ) - local Prefix = Name and "@ " .. Name .. ": " or "@ " .. TaskGroup:GetCallsign() .. ": " - Message = Prefix .. Message - MESSAGE:New( Message, 20, "Cargo: " .. self:GetName() ):ToGroup( TaskGroup ) + MESSAGE:New( Message, 20, "Cargo " .. self:GetName() ):ToGroup( TaskGroup ) 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 @@ -717,12 +853,12 @@ do -- CARGO_PACKAGE -- @param #string Type -- @param #string Name -- @param #number Weight --- @param #number ReportRadius (optional) +-- @param #number LoadRadius (optional) -- @param #number NearRadius (optional) -- @return #CARGO_PACKAGE -function CARGO_PACKAGE:New( CargoCarrier, Type, Name, Weight, ReportRadius, NearRadius ) - local self = BASE:Inherit( self, CARGO_REPRESENTABLE:New( CargoCarrier, Type, Name, Weight, ReportRadius, NearRadius ) ) -- #CARGO_PACKAGE - self:F( { 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, LoadRadius, NearRadius ) ) -- #CARGO_PACKAGE + self:F( { Type, Name, Weight, LoadRadius, NearRadius } ) self:T( CargoCarrier ) self.CargoCarrier = CargoCarrier diff --git a/Moose Development/Moose/Cargo/CargoCrate.lua b/Moose Development/Moose/Cargo/CargoCrate.lua index 1f083a010..44ef41af6 100644 --- a/Moose Development/Moose/Cargo/CargoCrate.lua +++ b/Moose Development/Moose/Cargo/CargoCrate.lua @@ -23,7 +23,7 @@ do -- CARGO_CRATE --- Models the behaviour of cargo crates, which can be slingloaded and boarded on helicopters. -- @type CARGO_CRATE - -- @extends #CARGO_REPRESENTABLE + -- @extends Cargo.Cargo#CARGO_REPRESENTABLE --- # CARGO\_CRATE class, extends @{#CARGO_REPRESENTABLE} -- @@ -42,11 +42,11 @@ do -- CARGO_CRATE -- @param Wrapper.Static#STATIC CargoStatic -- @param #string Type -- @param #string Name - -- @param #number ReportRadius (optional) + -- @param #number LoadRadius (optional) -- @param #number NearRadius (optional) -- @return #CARGO_CRATE - function CARGO_CRATE:New( CargoStatic, Type, Name, ReportRadius, NearRadius ) - local self = BASE:Inherit( self, CARGO_REPRESENTABLE:New( CargoStatic, Type, Name, nil, ReportRadius, NearRadius ) ) -- #CARGO_CRATE + function CARGO_CRATE:New( CargoStatic, Type, Name, LoadRadius, NearRadius ) + local self = BASE:Inherit( self, CARGO_REPRESENTABLE:New( CargoStatic, Type, Name, nil, LoadRadius, NearRadius ) ) -- #CARGO_CRATE self:F( { Type, Name, NearRadius } ) self.CargoObject = CargoStatic @@ -134,6 +134,27 @@ do -- CARGO_CRATE return false 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. -- @param #CARGO_CRATE self -- @return Core.Point#COORDINATE The current Coordinate of the first Cargo of the CargoGroup. @@ -188,28 +209,6 @@ do -- CARGO_CRATE 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. -- @param #CARGO_CRATE self function CARGO_CRATE:Respawn() diff --git a/Moose Development/Moose/Cargo/CargoGroup.lua b/Moose Development/Moose/Cargo/CargoGroup.lua index 2a5f8fee5..07806b45c 100644 --- a/Moose Development/Moose/Cargo/CargoGroup.lua +++ b/Moose Development/Moose/Cargo/CargoGroup.lua @@ -23,7 +23,7 @@ do -- 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 #string GroupName The name of the CargoGroup. @@ -45,12 +45,12 @@ do -- CARGO_GROUP -- @param Wrapper.Group#GROUP CargoGroup -- @param #string Type -- @param #string Name --- @param #number ReportRadius (optional) +-- @param #number LoadRadius (optional) -- @param #number NearRadius (optional) -- @return #CARGO_GROUP -function CARGO_GROUP:New( CargoGroup, Type, Name, ReportRadius ) - local self = BASE:Inherit( self, CARGO_REPORTABLE:New( Type, Name, 0, ReportRadius ) ) -- #CARGO_GROUP - self:F( { Type, Name, ReportRadius } ) +function CARGO_GROUP:New( CargoGroup, Type, Name, LoadRadius ) + local self = BASE:Inherit( self, CARGO_REPORTABLE:New( Type, Name, 0, LoadRadius ) ) -- #CARGO_GROUP + self:F( { Type, Name, LoadRadius } ) self.CargoSet = SET_CARGO:New() @@ -455,11 +455,11 @@ function CARGO_GROUP:OnEventCargoDead( EventData ) return nil 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 Core.Point#Coordinate Coordinate - -- @return #boolean true if the CargoGroup is within the reporting radius. - function CARGO_GROUP:IsInRadius( Coordinate ) + -- @return #boolean true if the Cargo Group is within the load radius. + function CARGO_GROUP:IsInLoadRadius( Coordinate ) self:F( { Coordinate } ) local Cargo = self.CargoSet:GetFirst() -- #CARGO @@ -473,7 +473,7 @@ function CARGO_GROUP:OnEventCargoDead( EventData ) end self:T( Distance ) - if Distance <= self.ReportRadius then + if Distance <= self.LoadRadius then return true else return false @@ -484,6 +484,31 @@ function CARGO_GROUP:OnEventCargoDead( EventData ) 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. -- @param #CARGO_GROUP self function CARGO_GROUP:Respawn() diff --git a/Moose Development/Moose/Cargo/CargoSlingload.lua b/Moose Development/Moose/Cargo/CargoSlingload.lua index a610e4b34..91f69f873 100644 --- a/Moose Development/Moose/Cargo/CargoSlingload.lua +++ b/Moose Development/Moose/Cargo/CargoSlingload.lua @@ -24,7 +24,7 @@ do -- CARGO_SLINGLOAD --- Models the behaviour of cargo crates, which can only be slingloaded. -- @type CARGO_SLINGLOAD - -- @extends #CARGO_REPRESENTABLE + -- @extends Cargo.Cargo#CARGO_REPRESENTABLE --- # CARGO\_CRATE class, extends @{#CARGO_REPRESENTABLE} -- @@ -42,11 +42,11 @@ do -- CARGO_SLINGLOAD -- @param Wrapper.Static#STATIC CargoStatic -- @param #string Type -- @param #string Name - -- @param #number ReportRadius (optional) + -- @param #number LoadRadius (optional) -- @param #number NearRadius (optional) -- @return #CARGO_SLINGLOAD - function CARGO_SLINGLOAD:New( CargoStatic, Type, Name, ReportRadius, NearRadius ) - local self = BASE:Inherit( self, CARGO_REPRESENTABLE:New( CargoStatic, Type, Name, nil, ReportRadius, NearRadius ) ) -- #CARGO_SLINGLOAD + function CARGO_SLINGLOAD:New( CargoStatic, Type, Name, LoadRadius, NearRadius ) + local self = BASE:Inherit( self, CARGO_REPRESENTABLE:New( CargoStatic, Type, Name, nil, LoadRadius, NearRadius ) ) -- #CARGO_SLINGLOAD self:F( { Type, Name, NearRadius } ) self.CargoObject = CargoStatic @@ -90,6 +90,28 @@ do -- CARGO_SLINGLOAD return false 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. -- @param #CARGO_SLINGLOAD self -- @return Core.Point#COORDINATE The current Coordinate of the first Cargo of the CargoGroup. @@ -144,28 +166,6 @@ do -- CARGO_SLINGLOAD 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. -- @param #CARGO_SLINGLOAD self function CARGO_SLINGLOAD:Respawn() diff --git a/Moose Development/Moose/Cargo/CargoUnit.lua b/Moose Development/Moose/Cargo/CargoUnit.lua index ba9c17f61..5ac185277 100644 --- a/Moose Development/Moose/Cargo/CargoUnit.lua +++ b/Moose Development/Moose/Cargo/CargoUnit.lua @@ -23,7 +23,7 @@ do -- CARGO_UNIT --- Models CARGO in the form of units, which can be boarded, unboarded, loaded, unloaded. -- @type CARGO_UNIT - -- @extends #CARGO_REPRESENTABLE + -- @extends Cargo.Cargo#CARGO_REPRESENTABLE --- # CARGO\_UNIT class, extends @{#CARGO_REPRESENTABLE} -- @@ -44,7 +44,7 @@ do -- CARGO_UNIT -- @param #string Type -- @param #string Name -- @param #number Weight - -- @param #number ReportRadius (optional) + -- @param #number LoadRadius (optional) -- @param #number NearRadius (optional) -- @return #CARGO_UNIT function CARGO_UNIT:New( CargoUnit, Type, Name, Weight, NearRadius ) @@ -82,42 +82,48 @@ do -- CARGO_UNIT if not self:IsDestroyed() then 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 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 + if CargoCarrier:IsAlive() then - local Points = {} - - -- From - Points[#Points+1] = FromPointVec2:WaypointGround( Speed, "Vee" ) - - -- To - Points[#Points+1] = ToPointVec2:WaypointGround( Speed, "Vee" ) + 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 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 @@ -225,7 +231,11 @@ do -- CARGO_UNIT local NearRadius = NearRadius or 25 self.CargoInAir = self.CargoObject:InAir() - + + local Desc = self.CargoObject:GetDesc() + local MaxSpeed = Desc.speedMaxOffRoad + local TypeName = Desc.typeName + self:T( self.CargoInAir ) -- 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 self:Load( CargoCarrier, NearRadius, ... ) else - local Speed = 90 - local Angle = 180 - local Distance = 5 + 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 = 5 + + NearRadius = NearRadius or 25 - NearRadius = NearRadius or 25 - - 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 ) - - 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( -1, CargoCarrier, NearRadius ) - self.RunCount = 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 ) + + 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( -1, CargoCarrier, NearRadius ) + self.RunCount = 0 + end end end diff --git a/Moose Development/Moose/Core/Set.lua b/Moose Development/Moose/Core/Set.lua index 939973fd1..58c24bcce 100644 --- a/Moose Development/Moose/Core/Set.lua +++ b/Moose Development/Moose/Core/Set.lua @@ -4131,6 +4131,19 @@ function SET_CARGO:New() --R2.1 return self 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. -- @param Core.Set#SET_CARGO self -- @param #string AddCargoNames A single name or an array of CARGO names. diff --git a/Moose Development/Moose/Core/Zone.lua b/Moose Development/Moose/Core/Zone.lua index 72317d2ba..8c05d8a14 100644 --- a/Moose Development/Moose/Core/Zone.lua +++ b/Moose Development/Moose/Core/Zone.lua @@ -603,6 +603,7 @@ function ZONE_RADIUS:Scan( ObjectCategories ) self.ScanData = {} self.ScanData.Coalitions = {} self.ScanData.Scenery = {} + self.ScanData.Units = {} local ZoneCoord = self:GetCoordinate() local ZoneRadius = self:GetRadius() @@ -625,6 +626,7 @@ function ZONE_RADIUS:Scan( ObjectCategories ) (ObjectCategory == Object.Category.STATIC and ZoneObject:isExist()) then local CoalitionDCSUnit = ZoneObject:getCoalition() self.ScanData.Coalitions[CoalitionDCSUnit] = true + self.ScanData.Units[ZoneObject] = ZoneObject self:F( { Name = ZoneObject:getName(), Coalition = CoalitionDCSUnit } ) end if ObjectCategory == Object.Category.SCENERY then @@ -643,6 +645,12 @@ function ZONE_RADIUS:Scan( ObjectCategories ) end +function ZONE_RADIUS:GetScannedUnits() + + return self.ScanData.Units +end + + function ZONE_RADIUS:CountScannedCoalitions() local Count = 0 diff --git a/Moose Development/Moose/Tasking/Task_CARGO.lua b/Moose Development/Moose/Tasking/Task_CARGO.lua index efb21f018..933413ebc 100644 --- a/Moose Development/Moose/Tasking/Task_CARGO.lua +++ b/Moose Development/Moose/Tasking/Task_CARGO.lua @@ -230,7 +230,7 @@ do -- TASK_CARGO Task.SetCargo:ForEachCargo( - --- @param Core.Cargo#CARGO Cargo + --- @param Cargo.Cargo#CARGO Cargo function( Cargo ) if Cargo:IsAlive() then @@ -250,7 +250,7 @@ do -- TASK_CARGO if Cargo:IsUnLoaded() then if CargoItemCount <= Task.CargoLimit then - if Cargo:IsInRadius( TaskUnit:GetPointVec2() ) then + if Cargo:IsInReportRadius( TaskUnit:GetPointVec2() ) then local NotInDeployZones = true for DeployZoneName, DeployZone in pairs( Task.DeployZones ) do if Cargo:IsInZone( DeployZone ) then @@ -260,23 +260,53 @@ do -- TASK_CARGO if NotInDeployZones then if not TaskUnit:InAir() 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 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 TaskUnit.Menu:SetTime( MenuTime ) + else + Cargo:ReportResetAll( TaskUnit:GetGroup() ) end end else MENU_GROUP_COMMAND:New( TaskUnit:GetGroup(), "Route to Pickup cargo " .. Cargo.Name, TaskUnit.Menu, self.MenuRouteToPickup, self, Cargo ):SetTime(MenuTime) TaskUnit.Menu:SetTime( MenuTime ) + Cargo:ReportResetAll( TaskUnit:GetGroup() ) 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 - if Cargo:IsLoaded() then + if Cargo:IsLoaded() == true and Cargo:IsLoadedInCarrier( TaskUnit ) == true then if not TaskUnit:InAir() then if Cargo:CanUnboard() == true then 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 ) - self:__SelectAction( -15 ) + self:__SelectAction( -1 ) end @@ -441,7 +471,7 @@ do -- TASK_CARGO self:F( { TaskUnit = TaskUnit, Task = Task and Task:GetClassNameAndID() } ) if self.Cargo:IsAlive() then - if self.Cargo:IsInRadius( TaskUnit:GetPointVec2() ) then + if self.Cargo:IsInLoadRadius( TaskUnit:GetPointVec2() ) then if TaskUnit:InAir() then self:__Land( -10, Action ) else @@ -465,7 +495,7 @@ do -- TASK_CARGO self:F( { TaskUnit = TaskUnit, Task = Task and Task:GetClassNameAndID() } ) if self.Cargo:IsAlive() then - if self.Cargo:IsInRadius( TaskUnit:GetPointVec2() ) then + if self.Cargo:IsInLoadRadius( TaskUnit:GetPointVec2() ) then if TaskUnit:InAir() then self:__Land( -0.1, Action ) else @@ -506,7 +536,7 @@ do -- TASK_CARGO end if self.Cargo:IsAlive() then - if self.Cargo:IsInRadius( TaskUnit:GetPointVec2() ) then + if self.Cargo:IsInLoadRadius( TaskUnit:GetPointVec2() ) then if TaskUnit:InAir() then --- ABORT the boarding. Split group if any and go back to select action. else @@ -649,26 +679,6 @@ do -- TASK_CARGO end end 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:__SelectAction( 1 ) @@ -739,7 +749,7 @@ do -- TASK_CARGO local ActRouteCargo = ProcessUnit:GetProcess( "RoutingToPickup", "RouteToPickupPoint" ) -- Actions.Act_Route#ACT_ROUTE_POINT ActRouteCargo:Reset() 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:Start() return self diff --git a/Moose Development/Moose/Wrapper/Controllable.lua b/Moose Development/Moose/Wrapper/Controllable.lua index 1847a16cd..f5b414e60 100644 --- a/Moose Development/Moose/Wrapper/Controllable.lua +++ b/Moose Development/Moose/Wrapper/Controllable.lua @@ -1892,7 +1892,7 @@ end -- @param #CONTROLLABLE self -- @return #CONTROLLABLE function CONTROLLABLE:RouteStop() - self:F2() + self:F("RouteStop") local CommandStop = self:CommandStopRoute( true ) self:SetCommand( CommandStop ) @@ -1903,7 +1903,7 @@ end -- @param #CONTROLLABLE self -- @return #CONTROLLABLE function CONTROLLABLE:RouteResume() - self:F2() + self:F("RouteResume") local CommandResume = self:CommandStopRoute( false ) self:SetCommand( CommandResume ) diff --git a/Moose Development/Moose/Wrapper/Group.lua b/Moose Development/Moose/Wrapper/Group.lua index 26062ea09..23fd5da1a 100644 --- a/Moose Development/Moose/Wrapper/Group.lua +++ b/Moose Development/Moose/Wrapper/Group.lua @@ -239,14 +239,17 @@ end -- 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. -- @param #GROUP self -function GROUP:Destroy() +-- @param #boolean GenerateEvent +function GROUP:Destroy( GenerateEvent ) self:F2( self.GroupName ) local DCSGroup = self:GetDCSObject() if DCSGroup then - for Index, UnitData in pairs( DCSGroup:getUnits() ) do - self:CreateEventCrash( timer.getTime(), UnitData ) + if not GenerateEvent then + for Index, UnitData in pairs( DCSGroup:getUnits() ) do + self:CreateEventCrash( timer.getTime(), UnitData ) + end end USERFLAG:New( self:GetName() ):Set( 100 ) DCSGroup:destroy() diff --git a/Moose Development/Moose/Wrapper/Identifiable.lua b/Moose Development/Moose/Wrapper/Identifiable.lua index baa83eedb..edd123665 100644 --- a/Moose Development/Moose/Wrapper/Identifiable.lua +++ b/Moose Development/Moose/Wrapper/Identifiable.lua @@ -229,6 +229,26 @@ function IDENTIFIABLE:GetDesc() return nil 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. -- @param #IDENTIFIABLE self -- @return #string The CallSign of the IDENTIFIABLE. diff --git a/Moose Development/Moose/Wrapper/Object.lua b/Moose Development/Moose/Wrapper/Object.lua index fc3c11126..29901fd4b 100644 --- a/Moose Development/Moose/Wrapper/Object.lua +++ b/Moose Development/Moose/Wrapper/Object.lua @@ -91,3 +91,5 @@ end + +