From bf903c0cc71eade75171e20d3b35183199cc8ad6 Mon Sep 17 00:00:00 2001 From: FlightControl Date: Wed, 22 Aug 2018 20:41:37 +0200 Subject: [PATCH] New weight driven limits logic for cargo to load multiple cargo. Fixed near range issue for carriers. now the infantry disappearance range for boarding is calculated by the carrier bounding range, which is derived from the bounding rectangle on the Y-axis. The near range parameter can still be provided and will be interpreted as the loading range for static cargo objects! --- Moose Development/Moose/AI/AI_Cargo_APC.lua | 37 +----- .../Moose/AI/AI_Cargo_Airplane.lua | 5 +- .../Moose/AI/AI_Cargo_Helicopter.lua | 4 +- Moose Development/Moose/Cargo/Cargo.lua | 2 +- Moose Development/Moose/Cargo/CargoUnit.lua | 11 +- .../Moose/Tasking/Task_CARGO.lua | 15 ++- .../Moose/Wrapper/Positionable.lua | 121 +++++++++++++++++- Moose Development/Moose/Wrapper/Unit.lua | 44 ------- 8 files changed, 134 insertions(+), 105 deletions(-) diff --git a/Moose Development/Moose/AI/AI_Cargo_APC.lua b/Moose Development/Moose/AI/AI_Cargo_APC.lua index acf565f81..c1c871cdd 100644 --- a/Moose Development/Moose/AI/AI_Cargo_APC.lua +++ b/Moose Development/Moose/AI/AI_Cargo_APC.lua @@ -197,42 +197,7 @@ function AI_CARGO_APC:New( APC, CargoSet, CombatRadius ) self:SetCarrier( APC ) for _, APCUnit in pairs( APC:GetUnits() ) do - local Desc = APCUnit:GetDesc() - - local VolumeUnit = ( Desc.box.max.x - Desc.box.min.x ) * ( Desc.box.max.y - Desc.box.min.y ) * ( Desc.box.max.z - Desc.box.min.z ) - - local Weights = { - ["M1126 Stryker ICV"] = 9, - ["M-113"] = 9, - ["AAV7"] = 25, - ["M2A1_halftrack"] = 9, - ["BMD-1"] = 9, - ["BMP-1"] = 8, - ["BMP-2"] = 7, - ["BMP-3"] = 8, - ["Boman"] = 25, - ["BTR-80"] = 9, - ["BTR_D"] = 12, - ["Cobra"] = 8, - ["LAV-25"] = 6, - ["M-2 Bradley"] = 6, - ["M1043 HMMWV Armament"] = 4, - ["M1045 HMMWV TOW"] = 4, - ["M1126 Stryker ICV"] = 9, - ["M1134 Stryker ATGM"] = 9, - ["Marder"] = 6, - ["MCV-80"] = 9, - ["MLRS FDDM"] = 4, - ["MTLB"] = 25, - ["TPZ"] = 10, - } - - local CargoBayWeightLimit = ( Weights[Desc.typeName] or 0 ) * 70 - - APCUnit:SetCargoBayWeightLimit( CargoBayWeightLimit ) - --Airplane:SetCargoBayVolumeLimit( 15 ) - - self:F( {TypeName = Desc.typeName, Desc = Desc, WeightLimit = CargoBayWeightLimit } ) + APCUnit:SetCargoBayWeightLimit() end self.Transporting = false diff --git a/Moose Development/Moose/AI/AI_Cargo_Airplane.lua b/Moose Development/Moose/AI/AI_Cargo_Airplane.lua index 638211643..1d5d1e398 100644 --- a/Moose Development/Moose/AI/AI_Cargo_Airplane.lua +++ b/Moose Development/Moose/AI/AI_Cargo_Airplane.lua @@ -128,10 +128,7 @@ function AI_CARGO_AIRPLANE:New( Airplane, CargoSet ) -- Set carrier. self:SetCarrier( Airplane ) - local Desc = Airplane:GetUnit(1):GetDesc() - self:F({Desc=Desc}) - Airplane:SetCargoBayWeightLimit( Desc.massMax - ( Desc.massEmpty + Desc.fuelMassMax ) ) - --Airplane:SetCargoBayVolumeLimit( 15 ) + Airplane:SetCargoBayWeightLimit() self.Relocating = true diff --git a/Moose Development/Moose/AI/AI_Cargo_Helicopter.lua b/Moose Development/Moose/AI/AI_Cargo_Helicopter.lua index 1341129f6..0148e9c79 100644 --- a/Moose Development/Moose/AI/AI_Cargo_Helicopter.lua +++ b/Moose Development/Moose/AI/AI_Cargo_Helicopter.lua @@ -146,9 +146,7 @@ function AI_CARGO_HELICOPTER:New( Helicopter, CargoSet ) ) for _, HelicopterUnit in pairs( Helicopter:GetUnits() ) do - local Desc = HelicopterUnit:GetDesc() - self:F({Desc=Desc}) - HelicopterUnit:SetCargoBayWeightLimit( Desc.massMax - ( Desc.massEmpty + Desc.fuelMassMax ) ) + HelicopterUnit:SetCargoBayWeightLimit() end self.Relocating = false diff --git a/Moose Development/Moose/Cargo/Cargo.lua b/Moose Development/Moose/Cargo/Cargo.lua index 3311a1bff..82015511e 100644 --- a/Moose Development/Moose/Cargo/Cargo.lua +++ b/Moose Development/Moose/Cargo/Cargo.lua @@ -811,7 +811,7 @@ do -- CARGO end - --- Check if CargoCarrier is near the Cargo to be Loaded. + --- Check if CargoCarrier is near the coordinate within NearRadius. -- @param #CARGO self -- @param Core.Point#COORDINATE Coordinate -- @param #number NearRadius The radius when the cargo will board the Carrier (to avoid collision). diff --git a/Moose Development/Moose/Cargo/CargoUnit.lua b/Moose Development/Moose/Cargo/CargoUnit.lua index 90eceeda9..da9c73f2b 100644 --- a/Moose Development/Moose/Cargo/CargoUnit.lua +++ b/Moose Development/Moose/Cargo/CargoUnit.lua @@ -226,8 +226,6 @@ do -- CARGO_UNIT function CARGO_UNIT:onafterBoard( From, Event, To, CargoCarrier, NearRadius, ... ) self:F( { From, Event, To, CargoCarrier, NearRadius } ) - local NearRadius = NearRadius or 25 - self.CargoInAir = self.CargoObject:InAir() local Desc = self.CargoObject:GetDesc() @@ -239,6 +237,9 @@ do -- CARGO_UNIT -- Only move the group to the carrier when the cargo is not in the air -- (eg. cargo can be on a oil derrick, moving the cargo on the oil derrick will drop the cargo on the sea). if not self.CargoInAir then + -- If NearRadius is given, then use the given NearRadius, otherwise calculate the NearRadius + -- based upon the Carrier bounding radius, which is calculated from the bounding rectangle on the Y axis. + local NearRadius = CargoCarrier:GetBoundingRadius( NearRadius ) if self:IsNear( CargoCarrier:GetPointVec2(), NearRadius ) then self:Load( CargoCarrier, NearRadius, ... ) else @@ -250,8 +251,6 @@ do -- CARGO_UNIT local Angle = 180 local Distance = 5 - 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 ) @@ -302,8 +301,6 @@ do -- CARGO_UNIT local Angle = 180 local Distance = 5 - 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 ) @@ -349,8 +346,6 @@ do -- CARGO_UNIT local Angle = 180 local Distance = 5 - local NearRadius = NearRadius or 25 - if From == "UnLoaded" or From == "Boarding" then end diff --git a/Moose Development/Moose/Tasking/Task_CARGO.lua b/Moose Development/Moose/Tasking/Task_CARGO.lua index fd1d60ef7..ae4ebc7b8 100644 --- a/Moose Development/Moose/Tasking/Task_CARGO.lua +++ b/Moose Development/Moose/Tasking/Task_CARGO.lua @@ -589,6 +589,12 @@ do -- TASK_CARGO Fsm:AddTransition( "Rejected", "Reject", "Aborted" ) Fsm:AddTransition( "Failed", "Fail", "Failed" ) + for _, Group in pairs( SetGroup:GetSet() ) do + for __, Unit in pairs( Group:GetUnits() ) do + local Unit = Unit -- Wrapper.Unit#UNIT + Unit:SetCargoBayWeightLimit() + end + end ---- @param #FSM_PROCESS self -- @param Wrapper.Unit#UNIT TaskUnit @@ -610,7 +616,6 @@ do -- TASK_CARGO local TaskUnitName = TaskUnit:GetName() local MenuTime = Task:InitTaskControlMenu( TaskUnit ) local MenuControl = Task:GetTaskControlMenu( TaskUnit ) - local CargoItemCount = TaskUnit:CargoItemCount() Task.SetCargo:ForEachCargo( @@ -635,7 +640,13 @@ do -- TASK_CARGO local TaskGroup = TaskUnit:GetGroup() if Cargo:IsUnLoaded() then - if CargoItemCount < 1 then + local CargoBayFreeWeight = TaskUnit:GetCargoBayFreeWeight() + local CargoWeight = Cargo:GetWeight() + + self:F({CargoBayFreeWeight=CargoBayFreeWeight}) + + -- Only when there is space within the bay to load the next cargo item! + if CargoBayFreeWeight > CargoWeight then if Cargo:IsInReportRadius( TaskUnit:GetPointVec2() ) then local NotInDeployZones = true for DeployZoneName, DeployZone in pairs( Task.DeployZones ) do diff --git a/Moose Development/Moose/Wrapper/Positionable.lua b/Moose Development/Moose/Wrapper/Positionable.lua index 287338c2b..b0200fd24 100644 --- a/Moose Development/Moose/Wrapper/Positionable.lua +++ b/Moose Development/Moose/Wrapper/Positionable.lua @@ -243,7 +243,7 @@ end --- Get the bounding box of the underlying POSITIONABLE DCS Object. -- @param #POSITIONABLE self --- @return DCS#Distance The bounding box of the POSITIONABLE. +-- @return DCS#Box3 The bounding box of the POSITIONABLE. -- @return #nil The POSITIONABLE is not existing or alive. function POSITIONABLE:GetBoundingBox() --R2.1 self:F2() @@ -264,6 +264,29 @@ function POSITIONABLE:GetBoundingBox() --R2.1 end +--- Get the bounding radius of the underlying POSITIONABLE DCS Object. +-- @param #POSITIONABLE self +-- @return DCS#Distance The bounding radius of the POSITIONABLE. +-- @return #nil The POSITIONABLE is not existing or alive. +function POSITIONABLE:GetBoundingRadius() + self:F2() + + local Box = self:GetBoundingBox() + + + if Box then + local X = Box.max.x - Box.min.x + local Z = Box.max.z - Box.min.z + local CX = X / 2 + local CZ = Z / 2 + return math.max( CX, CZ ) + end + + BASE:E( { "Cannot GetBoundingRadius", Positionable = self, Alive = self:IsAlive() } ) + + return nil +end + --- Returns the altitude of the POSITIONABLE. -- @param Wrapper.Positionable#POSITIONABLE self -- @return DCS#Distance The altitude of the POSITIONABLE. @@ -323,7 +346,7 @@ end --- Returns the POSITIONABLE heading in degrees. -- @param Wrapper.Positionable#POSITIONABLE self --- @return #number The POSTIONABLE heading +-- @return #number The POSITIONABLE heading -- @return #nil The POSITIONABLE is not existing or alive. function POSITIONABLE:GetHeading() local DCSPositionable = self:GetDCSObject() @@ -347,6 +370,52 @@ function POSITIONABLE:GetHeading() return nil end +-- Is Methods + +--- Returns if the unit is of an air category. +-- If the unit is a helicopter or a plane, then this method will return true, otherwise false. +-- @param #POSITIONABLE self +-- @return #boolean Air category evaluation result. +function POSITIONABLE:IsAir() + self:F2() + + local DCSUnit = self:GetDCSObject() + + if DCSUnit then + local UnitDescriptor = DCSUnit:getDesc() + self:T3( { UnitDescriptor.category, Unit.Category.AIRPLANE, Unit.Category.HELICOPTER } ) + + local IsAirResult = ( UnitDescriptor.category == Unit.Category.AIRPLANE ) or ( UnitDescriptor.category == Unit.Category.HELICOPTER ) + + self:T3( IsAirResult ) + return IsAirResult + end + + return nil +end + +--- Returns if the unit is of an ground category. +-- If the unit is a ground vehicle or infantry, this method will return true, otherwise false. +-- @param #POSITIONABLE self +-- @return #boolean Ground category evaluation result. +function POSITIONABLE:IsGround() + self:F2() + + local DCSUnit = self:GetDCSObject() + + if DCSUnit then + local UnitDescriptor = DCSUnit:getDesc() + self:T3( { UnitDescriptor.category, Unit.Category.GROUND_UNIT } ) + + local IsGroundResult = ( UnitDescriptor.category == Unit.Category.GROUND_UNIT ) + + self:T3( IsGroundResult ) + return IsGroundResult + end + + return nil +end + --- Returns true if the POSITIONABLE is in the air. -- Polymorphic, is overridden in GROUP and UNIT. @@ -895,12 +964,50 @@ do -- Cargo -- @param #POSITIONABLE self -- @param #number WeightLimit function POSITIONABLE:SetCargoBayWeightLimit( WeightLimit ) - self.__.CargoBayWeightLimit = WeightLimit - end - - - + if WeightLimit then + self.__.CargoBayWeightLimit = WeightLimit + else + -- If weightlimit is not provided, we will calculate it depending on the type of unit. + + -- When an airplane or helicopter, we calculate the weightlimit based on the descriptor. + if self:IsAir() then + local Desc = self:GetDesc() + self:F({Desc=Desc}) + self.__.CargoBayWeightLimit = Desc.massMax - ( Desc.massEmpty + Desc.fuelMassMax ) + else + local Desc = self:GetDesc() + local Weights = { + ["M1126 Stryker ICV"] = 9, + ["M-113"] = 9, + ["AAV7"] = 25, + ["M2A1_halftrack"] = 9, + ["BMD-1"] = 9, + ["BMP-1"] = 8, + ["BMP-2"] = 7, + ["BMP-3"] = 8, + ["Boman"] = 25, + ["BTR-80"] = 9, + ["BTR_D"] = 12, + ["Cobra"] = 8, + ["LAV-25"] = 6, + ["M-2 Bradley"] = 6, + ["M1043 HMMWV Armament"] = 4, + ["M1045 HMMWV TOW"] = 4, + ["M1126 Stryker ICV"] = 9, + ["M1134 Stryker ATGM"] = 9, + ["Marder"] = 6, + ["MCV-80"] = 9, + ["MLRS FDDM"] = 4, + ["MTLB"] = 25, + ["TPZ"] = 10, + } + + local CargoBayWeightLimit = ( Weights[Desc.typeName] or 0 ) * 70 + self.__.CargoBayWeightLimit = CargoBayWeightLimit + end + end + end end --- Cargo --- Signal a flare at the position of the POSITIONABLE. diff --git a/Moose Development/Moose/Wrapper/Unit.lua b/Moose Development/Moose/Wrapper/Unit.lua index 753b842f4..059a0266c 100644 --- a/Moose Development/Moose/Wrapper/Unit.lua +++ b/Moose Development/Moose/Wrapper/Unit.lua @@ -854,51 +854,7 @@ end --- Is methods ---- Returns if the unit is of an air category. --- If the unit is a helicopter or a plane, then this method will return true, otherwise false. --- @param #UNIT self --- @return #boolean Air category evaluation result. -function UNIT:IsAir() - self:F2() - - local DCSUnit = self:GetDCSObject() - - if DCSUnit then - local UnitDescriptor = DCSUnit:getDesc() - self:T3( { UnitDescriptor.category, Unit.Category.AIRPLANE, Unit.Category.HELICOPTER } ) - - local IsAirResult = ( UnitDescriptor.category == Unit.Category.AIRPLANE ) or ( UnitDescriptor.category == Unit.Category.HELICOPTER ) - - self:T3( IsAirResult ) - return IsAirResult - end - - return nil -end - ---- Returns if the unit is of an ground category. --- If the unit is a ground vehicle or infantry, this method will return true, otherwise false. --- @param #UNIT self --- @return #boolean Ground category evaluation result. -function UNIT:IsGround() - self:F2() - - local DCSUnit = self:GetDCSObject() - - if DCSUnit then - local UnitDescriptor = DCSUnit:getDesc() - self:T3( { UnitDescriptor.category, Unit.Category.GROUND_UNIT } ) - - local IsGroundResult = ( UnitDescriptor.category == Unit.Category.GROUND_UNIT ) - - self:T3( IsGroundResult ) - return IsGroundResult - end - - return nil -end --- Returns if the unit is a friendly unit. -- @param #UNIT self