Merge branch 'develop' into FF/Develop

This commit is contained in:
funkyfranky 2018-08-23 17:24:18 +02:00
commit 448110de08
15 changed files with 633 additions and 255 deletions

View File

@ -96,7 +96,7 @@ function AI_CARGO_APC:New( APC, CargoSet, CombatRadius )
self:AddTransition( "Loaded", "Deploy", "*" )
self:AddTransition( "*", "Load", "Boarding" )
self:AddTransition( "Boarding", "Board", "Boarding" )
self:AddTransition( { "Boarding", "Loaded" }, "Board", "Boarding" )
self:AddTransition( "Boarding", "Loaded", "Loaded" )
self:AddTransition( "Loaded", "Unload", "Unboarding" )
self:AddTransition( "Unboarding", "Unboard", "Unboarding" )
@ -195,8 +195,12 @@ function AI_CARGO_APC:New( APC, CargoSet, CombatRadius )
self:__Monitor( 1 )
self:SetCarrier( APC )
for _, APCUnit in pairs( APC:GetUnits() ) do
APCUnit:SetCargoBayWeightLimit()
end
self.Transporting = false
self.Relocating = false
@ -412,7 +416,6 @@ function AI_CARGO_APC:onbeforeLoad( APC, From, Event, To )
self:F( { APC, From, Event, To } )
local Boarding = false
self.BoardingCount = 0
if APC and APC:IsAlive() then
self.APC_Cargo = {}
@ -424,16 +427,25 @@ function AI_CARGO_APC:onbeforeLoad( APC, From, Event, To )
if Cargo:IsUnLoaded() and not Cargo:IsDeployed() then
if Cargo:IsInLoadRadius( APCUnit:GetCoordinate() ) then
self:F( { "In radius", APCUnit:GetName() } )
APC:RouteStop()
--Cargo:Ungroup()
Cargo:Board( APCUnit, 25 )
self:__Board( 1, Cargo )
Boarding = true
-- So now this APCUnit has Cargo that is being loaded.
-- This will be used further in the logic to follow and to check cargo status.
self.APC_Cargo[APCUnit] = Cargo
break
local CargoBayFreeWeight = APCUnit: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 --and CargoBayFreeVolume > CargoVolume then
APC:RouteStop()
--Cargo:Ungroup()
Cargo:Board( APCUnit, 25 )
self:__Board( 1, Cargo )
-- So now this APCUnit has Cargo that is being loaded.
-- This will be used further in the logic to follow and to check cargo status.
self.APC_Cargo[APCUnit] = Cargo
Boarding = true
break
end
end
end
end
@ -459,7 +471,31 @@ function AI_CARGO_APC:onafterBoard( APC, From, Event, To, Cargo )
if not Cargo:IsLoaded() then
self:__Board( 10, Cargo )
else
self:__Loaded( 1 )
for _, APCUnit in pairs( APC:GetUnits() ) do
local APCUnit = APCUnit -- Wrapper.Unit#UNIT
for _, Cargo in pairs( self.CargoSet:GetSet() ) do
local Cargo = Cargo -- Cargo.Cargo#CARGO
if Cargo:IsUnLoaded() then
if Cargo:IsInLoadRadius( APCUnit:GetCoordinate() ) then
local CargoBayFreeWeight = APCUnit: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 --and CargoBayFreeVolume > CargoVolume then
Cargo:Board( APCUnit, 25 )
self:__Board( 10, Cargo )
-- So now this APCUnit has Cargo that is being loaded.
-- This will be used further in the logic to follow and to check cargo status.
self.APC_Cargo[APCUnit] = Cargo
return
end
end
end
end
end
self:__Loaded( 5, Cargo )
end
end
@ -472,7 +508,7 @@ end
-- @param #string Event Event.
-- @param #string To To state.
-- @return #boolean Cargo loaded.
function AI_CARGO_APC:onbeforeLoaded( APC, From, Event, To )
function AI_CARGO_APC:onbeforeLoaded( APC, From, Event, To, Cargo )
self:F( { APC, From, Event, To } )
local Loaded = true
@ -485,7 +521,6 @@ function AI_CARGO_APC:onbeforeLoaded( APC, From, Event, To )
Loaded = false
end
end
end
if Loaded == true then
@ -497,6 +532,9 @@ function AI_CARGO_APC:onbeforeLoaded( APC, From, Event, To )
end
--- On after Unload event.
-- @param #AI_CARGO_APC self
-- @param Wrapper.Group#GROUP APC
@ -512,9 +550,12 @@ function AI_CARGO_APC:onafterUnload( APC, From, Event, To, Deployed )
local APCUnit = APCUnit -- Wrapper.Unit#UNIT
APC:RouteStop()
for _, Cargo in pairs( APCUnit:GetCargo() ) do
Cargo:UnBoard()
self:__Unboard( 10, Cargo, Deployed )
end
if Cargo:IsLoaded() then
Cargo:UnBoard()
Cargo:SetDeployed( true )
self:__Unboard( 10, Cargo, Deployed )
end
end
end
end
@ -535,6 +576,17 @@ function AI_CARGO_APC:onafterUnboard( APC, From, Event, To, Cargo, Deployed )
if not Cargo:IsUnLoaded() then
self:__Unboard( 10, Cargo, Deployed )
else
for _, APCUnit in pairs( APC:GetUnits() ) do
local APCUnit = APCUnit -- Wrapper.Unit#UNIT
for _, Cargo in pairs( APCUnit:GetCargo() ) do
if Cargo:IsLoaded() then
Cargo:UnBoard()
Cargo:SetDeployed( true )
self:__Unboard( 10, Cargo, Deployed )
return
end
end
end
self:__Unloaded( 1, Cargo, Deployed )
end
end
@ -560,22 +612,16 @@ function AI_CARGO_APC:onbeforeUnloaded( APC, From, Event, To, Cargo, Deployed )
if APC and APC:IsAlive() then
for _, APCUnit in pairs( APC:GetUnits() ) do
local APCUnit = APCUnit -- Wrapper.Unit#UNIT
local CargoCheck = self.APC_Cargo[APCUnit]
if CargoCheck then
self:F( { CargoCheck:GetName(), IsUnLoaded = CargoCheck:IsUnLoaded() } )
if CargoCheck:IsUnLoaded() == false then
AllUnloaded = false
break
end
local IsEmpty = APCUnit:IsCargoEmpty()
self:I({ IsEmpty = IsEmpty })
if not IsEmpty then
AllUnloaded = false
break
end
end
if AllUnloaded == true then
if Deployed == true then
for APCUnit, Cargo in pairs( self.APC_Cargo ) do
local Cargo = Cargo -- Cargo.Cargo#CARGO
Cargo:SetDeployed( true )
end
self.APC_Cargo = {}
end
self:Guard()
@ -588,6 +634,21 @@ function AI_CARGO_APC:onbeforeUnloaded( APC, From, Event, To, Cargo, Deployed )
end
--- On after Unloaded event.
-- @param #AI_CARGO_APC self
-- @param Wrapper.Group#GROUP APC
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
-- @param #string Cargo.Cargo#CARGO Cargo Cargo object.
-- @param #boolean Deployed Cargo is deployed.
-- @return #boolean All cargo unloaded.
function AI_CARGO_APC:onafterUnloaded( APC, From, Event, To, Cargo, Deployed )
self:F( { APC, From, Event, To, Cargo:GetName(), Deployed = Deployed } )
self.Transporting = false
end
--- On after Follow event.
-- @param #AI_CARGO_APC self
@ -633,7 +694,6 @@ function AI_CARGO_APC._Deploy( APC, self )
if APC:IsAlive() then
self:Unload( true )
self.Transporting = false
self.Relocating = false
end
end

View File

@ -34,15 +34,15 @@ function AI_CARGO_AIRPLANE:New( Airplane, CargoSet )
self:SetStartState( "Unloaded" )
self:AddTransition( "Unloaded", "Pickup", "*" )
self:AddTransition( { "Unloaded", "Loaded" }, "Pickup", "*" )
self:AddTransition( "Loaded", "Deploy", "*" )
self:AddTransition( "Unloaded", "Load", "Boarding" )
self:AddTransition( { "Unloaded", "Boarding" }, "Load", "Boarding" )
self:AddTransition( "Boarding", "Board", "Boarding" )
self:AddTransition( "Boarding", "Loaded", "Loaded" )
self:AddTransition( "Loaded", "Unload", "Unboarding" )
self:AddTransition( "Unboarding", "Unboard", "Unboarding" )
self:AddTransition( "Unboarding", "Unloaded", "Unloaded" )
self:AddTransition( "Unboarding" , "Unloaded", "Unloaded" )
self:AddTransition( "*", "Landed", "*" )
self:AddTransition( "*", "Home" , "*" )
@ -128,6 +128,10 @@ function AI_CARGO_AIRPLANE:New( Airplane, CargoSet )
-- Set carrier.
self:SetCarrier( Airplane )
Airplane:SetCargoBayWeightLimit()
self.Relocating = true
return self
end
@ -188,7 +192,7 @@ function AI_CARGO_AIRPLANE:SetCarrier( Airplane )
function Airplane:OnEventEngineShutdown( EventData )
self:F("Calling")
AICargo.Relocating = false
AICargo:Landed( self.Airplane )
end
@ -233,8 +237,6 @@ end
function AI_CARGO_AIRPLANE:onafterLanded( Airplane, From, Event, To )
self:F({Airplane, From, Event, To})
self:F({IsAlive=Airplane:IsAlive()})
self:F({RoutePickup=self.RoutePickup})
if Airplane and Airplane:IsAlive()~=nil then
@ -243,12 +245,15 @@ function AI_CARGO_AIRPLANE:onafterLanded( Airplane, From, Event, To )
env.info("FF load airplane "..Airplane:GetName())
self:Load( Airplane:GetCoordinate() )
self.RoutePickup = false
self.Relocating = true
end
-- Aircraft was send to this airbase to deploy troops. Initiate unloading.
if self.RouteDeploy == true then
self:Unload()
self.RouteDeploy = false
self.Transporting = false
self.Relocating = false
end
end
@ -341,8 +346,7 @@ function AI_CARGO_AIRPLANE:onafterDeploy( Airplane, From, Event, To, Airbase, Sp
-- Set destination airbase for next :Route() command.
self.Airbase = Airbase
-- Unclear?!
self.Transporting = false
self.Transporting = true
self.Relocating = false
end
@ -358,17 +362,21 @@ end
-- @param Wrapper.Point#COORDINATE Coordinate Place where the cargo is guided to if it is inside the load radius.
function AI_CARGO_AIRPLANE:onafterLoad( Airplane, From, Event, To, Coordinate )
if Airplane and Airplane:IsAlive()~=nil then
if Airplane and Airplane:IsAlive() ~= nil then
for _,_Cargo in pairs( self.CargoSet:GetSet() ) do
self:F({_Cargo:GetName()})
local Cargo=_Cargo --Cargo.Cargo#CARGO
local InRadius = Cargo:IsInLoadRadius( Coordinate )
if InRadius then
self:__Board( 5 )
Cargo:Board( Airplane, 25 )
self.Cargo = Cargo
break
-- Is there a cargo still unloaded?
if Cargo:IsUnLoaded() == true then
self:__Board( 5, Cargo )
Cargo:Board( Airplane, 25 )
break
end
end
end
@ -382,14 +390,48 @@ end
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
function AI_CARGO_AIRPLANE:onafterBoard( Airplane, From, Event, To )
function AI_CARGO_AIRPLANE:onafterBoard( Airplane, From, Event, To, Cargo )
if Airplane and Airplane:IsAlive() then
self:F({ IsLoaded = self.Cargo:IsLoaded() } )
if not self.Cargo:IsLoaded() then
self:__Board( 10 )
self:F({ IsLoaded = Cargo:IsLoaded() } )
if not Cargo:IsLoaded() then
self:__Board( 10, Cargo )
else
self:__Loaded( 1 )
-- Check if another cargo can be loaded into the airplane.
for _,_Cargo in pairs( self.CargoSet:GetSet() ) do
self:F({_Cargo:GetName()})
local Cargo =_Cargo --Cargo.Cargo#CARGO
-- Is there a cargo still unloaded?
if Cargo:IsUnLoaded() == true then
-- Only when the cargo is within load radius.
local InRadius = Cargo:IsInLoadRadius( Airplane:GetCoordinate() )
if InRadius then
local CargoBayFreeWeight = Airplane:GetCargoBayFreeWeight()
--local CargoBayFreeVolume = Airplane:GetCargoBayFreeVolume()
local CargoWeight = Cargo:GetWeight()
--local CargoVolume = Cargo:GetVolume()
-- Only when there is space within the bay to load the next cargo item!
if CargoBayFreeWeight > CargoWeight then --and CargoBayFreeVolume > CargoVolume then
-- ok, board.
self:__Load( 5, Airplane:GetCoordinate() )
-- And start the boarding loop for the AI_CARGO_AIRPLANE object until the cargo is boarded.
--Cargo:Board( Airplane, 25 )
return
end
end
end
end
self:__Loaded( 1, Cargo )
end
end
@ -401,13 +443,14 @@ end
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
function AI_CARGO_AIRPLANE:onafterLoaded( Airplane, From, Event, To )
function AI_CARGO_AIRPLANE:onafterLoaded( Airplane, From, Event, To, Cargo )
env.info("FF troops loaded into cargo plane")
if Airplane and Airplane:IsAlive() then
self:F( { "Transporting" } )
self.Transporting = true -- This will only be executed when there is no cargo boarded anymore. The dispatcher will then kick-off the deploy cycle!
end
end
@ -420,8 +463,19 @@ end
function AI_CARGO_AIRPLANE:onafterUnload( Airplane, From, Event, To )
if Airplane and Airplane:IsAlive() then
self.Cargo:UnBoard()
self:__Unboard( 10 )
local Cargos = Airplane:GetCargo()
for CargoID, Cargo in pairs( Cargos ) do
local Angle = 180
local CargoCarrierHeading = Airplane:GetHeading() -- Get Heading of object in degrees.
local CargoDeployHeading = ( ( CargoCarrierHeading + Angle ) >= 360 ) and ( CargoCarrierHeading + Angle - 360 ) or ( CargoCarrierHeading + Angle )
self:T( { CargoCarrierHeading, CargoDeployHeading } )
local CargoDeployCoordinate = Airplane:GetPointVec2():Translate( 150, CargoDeployHeading )
Cargo:UnBoard( CargoDeployCoordinate )
Cargo:SetDeployed( true )
self:__Unboard( 10, Cargo )
end
end
end
@ -432,16 +486,32 @@ end
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
function AI_CARGO_AIRPLANE:onafterUnboard( Airplane, From, Event, To )
function AI_CARGO_AIRPLANE:onafterUnboard( Airplane, From, Event, To, Cargo )
self:E( { "Unboard", Cargo } )
if Airplane and Airplane:IsAlive() then
if not self.Cargo:IsUnLoaded() then
self:__Unboard( 10 )
if not Cargo:IsUnLoaded() then
self:__Unboard( 10, Cargo )
else
self:__Unloaded( 1 )
local Cargos = Airplane:GetCargo()
for CargoID, Cargo in pairs( Cargos ) do
if Cargo:IsLoaded() then
local Angle = 180
local CargoCarrierHeading = Airplane:GetHeading() -- Get Heading of object in degrees.
local CargoDeployHeading = ( ( CargoCarrierHeading + Angle ) >= 360 ) and ( CargoCarrierHeading + Angle - 360 ) or ( CargoCarrierHeading + Angle )
self:T( { CargoCarrierHeading, CargoDeployHeading } )
local CargoDeployCoordinate = Airplane:GetPointVec2():Translate( 150, CargoDeployHeading )
Cargo:UnBoard( CargoDeployCoordinate )
Cargo:SetDeployed( true )
self:__Unboard( 10, Cargo )
return
end
end
self:__Unloaded( 1, Cargo )
end
end
end
--- On after Unloaded event. Cargo has been unloaded, i.e. the unboarding process is finished.
@ -450,12 +520,15 @@ end
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
function AI_CARGO_AIRPLANE:onafterUnloaded( Airplane, From, Event, To )
-- @param Cargo.Cargo#CARGO Cargo
function AI_CARGO_AIRPLANE:onafterUnloaded( Airplane, From, Event, To, Cargo )
self:E( { "Unloaded", Cargo } )
if Airplane and Airplane:IsAlive() then
self.Airplane = Airplane
self.Transporting = false -- This will only be executed when there is no cargo onboard anymore. The dispatcher will then kick-off the pickup cycle!
end
end
--- Route the airplane from one airport or it's current position to another airbase.

View File

@ -405,8 +405,9 @@ function AI_CARGO_DISPATCHER:onafterMonitor()
-- The Pickup sequence ...
-- Check if this Carrier need to go and Pickup something...
self:I( { IsTransporting = AI_Cargo:IsTransporting() } )
if AI_Cargo:IsTransporting() == false then
-- So, if the cargo bay is not full yet with cargo to be loaded ...
self:I( { IsRelocating = AI_Cargo:IsRelocating(), IsTransporting = AI_Cargo:IsTransporting() } )
if AI_Cargo:IsRelocating() == false and AI_Cargo:IsTransporting() == false then
-- ok, so there is a free Carrier
-- now find the first cargo that is Unloaded
@ -415,7 +416,7 @@ function AI_CARGO_DISPATCHER:onafterMonitor()
for CargoName, Cargo in pairs( self.SetCargo:GetSet() ) do
local Cargo = Cargo -- Cargo.Cargo#CARGO
self:F( { Cargo = Cargo:GetName(), UnLoaded = Cargo:IsUnLoaded(), Deployed = Cargo:IsDeployed(), PickupCargo = self.PickupCargo[Carrier] ~= nil } )
if Cargo:IsUnLoaded() and not Cargo:IsDeployed() then
if Cargo:IsUnLoaded() == true and Cargo:IsDeployed() == false then
local CargoCoordinate = Cargo:GetCoordinate()
local CoordinateFree = true
for CarrierPickup, Coordinate in pairs( self.PickupCargo ) do
@ -567,14 +568,13 @@ function AI_CARGO_DISPATCHER:OnAfterLoaded( From, Event, To, Carrier, Cargo )
end
if self.DeployAirbasesSet then
local DeployAirbase = self.DeployAirbasesSet:GetRandomAirbase()
self.AI_Cargo[Carrier]:Deploy( DeployAirbase, math.random( self.DeployMinSpeed, self.DeployMaxSpeed ) )
if self.AI_Cargo[Carrier]:IsTransporting() == true then
local DeployAirbase = self.DeployAirbasesSet:GetRandomAirbase()
self.AI_Cargo[Carrier]:Deploy( DeployAirbase, math.random( self.DeployMinSpeed, self.DeployMaxSpeed ) )
end
end
self.PickupCargo[Carrier] = nil
end

View File

@ -101,7 +101,7 @@ AI_CARGO_DISPATCHER_APC = {
-- SetDeployZone = SET_ZONE:New():FilterPrefixes( "Deploy" ):FilterStart()
-- AICargoDispatcher = AI_CARGO_DISPATCHER_APC:New( SetAPC, SetCargo, SetDeployZone, 500 )
--
function AI_CARGO_DISPATCHER_APC:NewWithZones( SetAPC, SetCargo, SetDeployZone, CombatRadius )
function AI_CARGO_DISPATCHER_APC:New( SetAPC, SetCargo, SetDeployZone, CombatRadius )
local self = BASE:Inherit( self, AI_CARGO_DISPATCHER:NewWithZones( SetAPC, SetCargo, SetDeployZone ) ) -- #AI_CARGO_DISPATCHER_APC

View File

@ -20,7 +20,8 @@
-- @field #AI_CARGO_HELICOPTER
AI_CARGO_HELICOPTER = {
ClassName = "AI_CARGO_HELICOPTER",
Coordinate = nil -- Core.Point#COORDINATE,
Coordinate = nil, -- Core.Point#COORDINATE,
Helicopter_Cargo = {},
}
AI_CARGO_QUEUE = {}
@ -43,7 +44,7 @@ function AI_CARGO_HELICOPTER:New( Helicopter, CargoSet )
self:AddTransition( "Unloaded", "Pickup", "*" )
self:AddTransition( "Loaded", "Deploy", "*" )
self:AddTransition( "Unloaded", "Load", "Boarding" )
self:AddTransition( { "Unloaded", "Loading" }, "Load", "Boarding" )
self:AddTransition( "Boarding", "Board", "Boarding" )
self:AddTransition( "Boarding", "Loaded", "Loaded" )
self:AddTransition( "Loaded", "Unload", "Unboarding" )
@ -146,6 +147,13 @@ function AI_CARGO_HELICOPTER:New( Helicopter, CargoSet )
end
)
for _, HelicopterUnit in pairs( Helicopter:GetUnits() ) do
HelicopterUnit:SetCargoBayWeightLimit()
end
self.Relocating = false
self.Transporting = false
self:SetCarrier( Helicopter )
return self
@ -382,24 +390,30 @@ function AI_CARGO_HELICOPTER:onbeforeLoad( Helicopter, From, Event, To)
self.BoardingCount = 0
if Helicopter and Helicopter:IsAlive() then
self.Helicopter_Cargo = {}
for _, HelicopterUnit in pairs( Helicopter:GetUnits() ) do
local HelicopterUnit = HelicopterUnit -- Wrapper.Unit#UNIT
for _, Cargo in pairs( self.CargoSet:GetSet() ) do
local Cargo = Cargo -- Cargo.Cargo#CARGO
self:F( { IsUnLoaded = Cargo:IsUnLoaded() } )
if Cargo:IsUnLoaded() then
if Cargo:IsUnLoaded() and not Cargo:IsDeployed() then
if Cargo:IsInLoadRadius( HelicopterUnit:GetCoordinate() ) then
self:F( { "In radius", HelicopterUnit:GetName() } )
--Cargo:Ungroup()
Cargo:Board( HelicopterUnit, 25 )
self:__Board( 1, Cargo )
Boarding = true
-- So now this APCUnit has Cargo that is being loaded.
-- This will be used further in the logic to follow and to check cargo status.
self.Helicopter_Cargo[HelicopterUnit] = Cargo
break
local CargoBayFreeWeight = HelicopterUnit: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 --and CargoBayFreeVolume > CargoVolume then
--Cargo:Ungroup()
Cargo:Board( HelicopterUnit, 25 )
self:__Board( 1, Cargo )
self.Helicopter_Cargo[HelicopterUnit] = Cargo
Boarding = true
break
end
end
end
end
@ -426,13 +440,65 @@ function AI_CARGO_HELICOPTER:onafterBoard( Helicopter, From, Event, To, Cargo )
if not Cargo:IsLoaded() then
self:__Board( 10, Cargo )
else
self:__Loaded( 1, Cargo )
for _, HelicopterUnit in pairs( Helicopter:GetUnits() ) do
local HelicopterUnit = HelicopterUnit -- Wrapper.Unit#UNIT
for _, Cargo in pairs( self.CargoSet:GetSet() ) do
local Cargo = Cargo -- Cargo.Cargo#CARGO
if Cargo:IsUnLoaded() then
if Cargo:IsInLoadRadius( HelicopterUnit:GetCoordinate() ) then
local CargoBayFreeWeight = HelicopterUnit: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 --and CargoBayFreeVolume > CargoVolume then
Cargo:Board( HelicopterUnit, 25 )
self:__Board( 10, Cargo )
self.Helicopter_Cargo[HelicopterUnit] = Cargo
return
end
end
end
end
end
self:__Loaded( 1, Cargo ) -- Will only be executed when no more cargo is boarded.
end
end
end
--- On before Loaded event. Check if cargo is loaded.
--- On before Loaded event.
-- @param #AI_CARGO_HELICOPTER self
-- @param Wrapper.Group#GROUP Helicopter
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
-- @return #boolean Cargo loaded.
function AI_CARGO_HELICOPTER:onbeforeLoaded( Helicopter, From, Event, To, Cargo )
self:F( { Helicopter, From, Event, To } )
local Loaded = true
if Helicopter and Helicopter:IsAlive() then
for HelicopterUnit, Cargo in pairs( self.Helicopter_Cargo ) do
local Cargo = Cargo -- Cargo.Cargo#CARGO
self:F( { IsLoaded = Cargo:IsLoaded(), IsDestroyed = Cargo:IsDestroyed(), Cargo:GetName(), Helicopter:GetName() } )
if not Cargo:IsLoaded() and not Cargo:IsDestroyed() then
Loaded = false
end
end
end
return Loaded
end
--- On after Loaded event. Check if cargo is loaded.
-- @param #AI_CARGO_HELICOPTER self
-- @param Wrapper.Group#GROUP Helicopter
-- @param #string From From state.
@ -440,24 +506,12 @@ end
-- @param #string To To state.
-- @param Cargo.Cargo#CARGO Cargo Cargo object.
-- @return #boolean Cargo is loaded.
function AI_CARGO_HELICOPTER:onbeforeLoaded( Helicopter, From, Event, To, Cargo )
function AI_CARGO_HELICOPTER:onafterLoaded( Helicopter, From, Event, To, Cargo )
self:F( { Helicopter, From, Event, To, Cargo } )
local Loaded = true
if Helicopter and Helicopter:IsAlive() then
for HelicopterUnit, Cargo in pairs( self.Helicopter_Cargo ) do
local Cargo = Cargo -- Cargo.Cargo#CARGO
self:F( { IsLoaded = Cargo:IsLoaded(), IsDestroyed = Cargo:IsDestroyed() } )
if not Cargo:IsLoaded() and not Cargo:IsDestroyed() then
Loaded = false
end
end
self.Transporting = true
end
return Loaded
end
@ -473,9 +527,11 @@ function AI_CARGO_HELICOPTER:onafterUnload( Helicopter, From, Event, To, Deploye
for _, HelicopterUnit in pairs( Helicopter:GetUnits() ) do
local HelicopterUnit = HelicopterUnit -- Wrapper.Unit#UNIT
for _, Cargo in pairs( HelicopterUnit:GetCargo() ) do
Cargo:UnBoard()
Cargo:SetDeployed( true )
self:__Unboard( 10, Cargo, Deployed )
if Cargo:IsLoaded() then
Cargo:UnBoard()
Cargo:SetDeployed( true )
self:__Unboard( 10, Cargo, Deployed )
end
end
end
end
@ -497,6 +553,17 @@ function AI_CARGO_HELICOPTER:onafterUnboard( Helicopter, From, Event, To, Cargo,
if not Cargo:IsUnLoaded() then
self:__Unboard( 10, Cargo, Deployed )
else
for _, HelicopterUnit in pairs( Helicopter:GetUnits() ) do
local HelicopterUnit = HelicopterUnit -- Wrapper.Unit#UNIT
for _, Cargo in pairs( HelicopterUnit:GetCargo() ) do
if Cargo:IsLoaded() then
Cargo:UnBoard()
Cargo:SetDeployed( true )
self:__Unboard( 10, Cargo, Deployed )
return
end
end
end
self:__Unloaded( 1, Cargo, Deployed )
end
end
@ -521,21 +588,16 @@ function AI_CARGO_HELICOPTER:onbeforeUnloaded( Helicopter, From, Event, To, Carg
if Helicopter and Helicopter:IsAlive() then
for _, HelicopterUnit in pairs( Helicopter:GetUnits() ) do
local CargoCheck = self.Helicopter_Cargo[HelicopterUnit] -- Cargo.Cargo#CARGO
if CargoCheck then
self:F( { CargoCheck:GetName(), IsUnLoaded = CargoCheck:IsUnLoaded() } )
if CargoCheck:IsUnLoaded() == false then
local IsEmpty = HelicopterUnit:IsCargoEmpty()
self:I({ IsEmpty = IsEmpty })
if not IsEmpty then
AllUnloaded = false
break
end
end
end
if AllUnloaded == true then
if Deployed == true then
for HelicopterUnit, Cargo in pairs( self.Helicopter_Cargo ) do
local Cargo = Cargo -- Cargo.Cargo#CARGO
end
self.Helicopter_Cargo = {}
end
self.Helicopter = Helicopter

View File

@ -779,7 +779,8 @@ do -- CARGO
local Distance = 0
if self:IsUnLoaded() then
Distance = Coordinate:Get2DDistance( self.CargoObject:GetCoordinate() )
local CargoCoordinate = self.CargoObject:GetCoordinate()
Distance = Coordinate:Get2DDistance( CargoCoordinate )
self:T( Distance )
if Distance <= self.LoadRadius then
return true
@ -810,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).
@ -875,6 +876,13 @@ do -- CARGO
return self.CargoObject:GetCoordinate()
end
--- Get the weight of the cargo.
-- @param #CARGO self
-- @return #number Weight The weight in kg.
function CARGO:GetWeight()
return self.Weight
end
--- Set the weight of the cargo.
-- @param #CARGO self
-- @param #number Weight The weight in kg.
@ -884,6 +892,22 @@ do -- CARGO
return self
end
--- Get the volume of the cargo.
-- @param #CARGO self
-- @return #number Volume The volume in kg.
function CARGO:GetVolume()
return self.Volume
end
--- Set the volume of the cargo.
-- @param #CARGO self
-- @param #number Volume The volume in kg.
-- @return #CARGO
function CARGO:SetVolume( Volume )
self.Volume = Volume
return self
end
--- Send a CC message to a @{Wrapper.Group}.
-- @param #CARGO self
-- @param #string Message
@ -997,13 +1021,27 @@ do -- CARGO_REPRESENTABLE
-- @param #CARGO_REPRESENTABLE self
-- @param #string Type
-- @param #string Name
-- @param #number Weight
-- @param #number LoadRadius (optional)
-- @param #number NearRadius (optional)
-- @return #CARGO_REPRESENTABLE
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 } )
function CARGO_REPRESENTABLE:New( CargoObject, Type, Name, LoadRadius, NearRadius )
local self = BASE:Inherit( self, CARGO:New( Type, Name, 0, LoadRadius, NearRadius ) ) -- #CARGO_REPRESENTABLE
self:F( { Type, Name, LoadRadius, NearRadius } )
local Desc = CargoObject:GetDesc()
self:I( { Desc = Desc } )
local Weight = math.random( 80, 120 )
if Desc then
Weight = Desc.massEmpty
end
self:SetWeight( Weight )
-- local Box = CargoUnit:GetBoundingBox()
-- local VolumeUnit = ( Box.max.x - Box.min.x ) * ( Box.max.y - Box.min.y ) * ( Box.max.z - Box.min.z )
-- self:I( { VolumeUnit = VolumeUnit, WeightUnit = WeightUnit } )
--self:SetVolume( VolumeUnit )
return self
end

View File

@ -73,6 +73,7 @@ do -- CARGO_GROUP
self:SetDeployed( false )
local WeightGroup = 0
local VolumeGroup = 0
self.CargoGroup:Destroy()
@ -88,7 +89,7 @@ do -- CARGO_GROUP
for UnitID, UnitTemplate in pairs( self.CargoTemplate.units ) do
UnitTemplate.name = UnitTemplate.name .. "#CARGO"
local CargoUnitName = UnitTemplate.name
local CargoUnitName = UnitTemplate.name
self.CargoUnitTemplate[CargoUnitName] = UnitTemplate
GroupTemplate.units[#GroupTemplate.units+1] = self.CargoUnitTemplate[CargoUnitName]
@ -96,20 +97,29 @@ do -- CARGO_GROUP
-- And we register the spawned unit as part of the CargoSet.
local Unit = UNIT:Register( CargoUnitName )
--local WeightUnit = Unit:GetDesc().massEmpty
--WeightGroup = WeightGroup + WeightUnit
local CargoUnit = CARGO_UNIT:New( Unit, Type, CargoUnitName, 10, LoadRadius, NearRadius )
self.CargoSet:Add( CargoUnitName, CargoUnit )
end
-- Then we register the new group in the database
self.CargoGroup = GROUP:NewTemplate( GroupTemplate, GroupTemplate.CoalitionID, GroupTemplate.CategoryID, GroupTemplate.CountryID)
self.CargoGroup = GROUP:NewTemplate( GroupTemplate, GroupTemplate.CoalitionID, GroupTemplate.CategoryID, GroupTemplate.CountryID )
-- Now we spawn the new group based on the template created.
self.CargoObject = _DATABASE:Spawn( GroupTemplate )
for CargoUnitID, CargoUnit in pairs( self.CargoObject:GetUnits() ) do
local CargoUnitName = CargoUnit:GetName()
local Cargo = CARGO_UNIT:New( CargoUnit, Type, CargoUnitName, LoadRadius, NearRadius )
self.CargoSet:Add( CargoUnitName, Cargo )
WeightGroup = WeightGroup + Cargo:GetWeight()
--VolumeGroup = VolumeGroup + VolumeUnit
end
self:SetWeight( WeightGroup )
self.CargoLimit = 10
self:T( { "Weight Cargo", WeightGroup } )
@ -490,8 +500,6 @@ do -- CARGO_GROUP
-- @return Core.Point#COORDINATE The current Coordinate of the first Cargo of the CargoGroup.
-- @return #nil There is no valid Cargo in the CargoGroup.
function CARGO_GROUP:GetCoordinate()
self:F()
local Cargo = self:GetFirstAlive() -- Cargo.Cargo#CARGO
if Cargo then
@ -625,12 +633,19 @@ do -- CARGO_GROUP
if Cargo then
local Distance = 0
local CargoCoordinate
if Cargo:IsLoaded() then
Distance = Coordinate:Get2DDistance( Cargo.CargoCarrier:GetCoordinate() )
CargoCoordinate = Cargo.CargoCarrier:GetCoordinate()
else
Distance = Coordinate:Get2DDistance( Cargo.CargoObject:GetCoordinate() )
CargoCoordinate = Cargo.CargoObject:GetCoordinate()
end
-- if CargoCoordinate then
Distance = Coordinate:Get2DDistance( CargoCoordinate )
-- else
-- return false
-- end
self:F( { Distance = Distance, LoadRadius = self.LoadRadius } )
if Distance <= self.LoadRadius then
return true

View File

@ -42,9 +42,9 @@ do -- CARGO_UNIT
-- @param #number LoadRadius (optional)
-- @param #number NearRadius (optional)
-- @return #CARGO_UNIT
function CARGO_UNIT:New( CargoUnit, Type, Name, Weight, LoadRadius, NearRadius )
local self = BASE:Inherit( self, CARGO_REPRESENTABLE:New( CargoUnit, Type, Name, Weight, LoadRadius, NearRadius ) ) -- #CARGO_UNIT
self:I( { Type, Name, Weight, LoadRadius, NearRadius } )
function CARGO_UNIT:New( CargoUnit, Type, Name, LoadRadius, NearRadius )
local self = BASE:Inherit( self, CARGO_REPRESENTABLE:New( CargoUnit, Type, Name, LoadRadius, NearRadius ) ) -- #CARGO_UNIT
self:I( { Type, Name, LoadRadius, NearRadius } )
self:T( CargoUnit )
self.CargoObject = CargoUnit
@ -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

View File

@ -374,14 +374,15 @@ do -- cargo
-- @return #DATABASE self
function DATABASE:_RegisterCargos()
local Groups = UTILS.DeepCopy( self.GROUPS ) -- This is a very important statement. CARGO_GROUP:New creates a new _DATABASE.GROUP entry, which will confuse the loop. I searched 4 hours on this to find the bug!
for CargoGroupName, CargoGroup in pairs( self.GROUPS ) do
for CargoGroupName, CargoGroup in pairs( Groups ) do
self:I( { Cargo = CargoGroupName } )
if self:IsCargo( CargoGroupName ) then
local CargoInfo = CargoGroupName:match("~CARGO(.*)")
local CargoParam = CargoInfo and CargoInfo:match( "%((.*)%)")
local CargoName1 = CargoGroupName:match("(.*)~CARGO%(.*%)")
local CargoName2 = CargoGroupName:match(".*~CARGO%(.*%)(.*)")
self:E({CargoName1 = CargoName1, CargoName2 = CargoName2 })
local CargoName = CargoName1 .. ( CargoName2 or "" )
local Type = CargoParam and CargoParam:match( "T=([%a%d ]+),?")
local Name = CargoParam and CargoParam:match( "N=([%a%d]+),?") or CargoName
@ -459,7 +460,7 @@ end
function DATABASE:AddGroup( GroupName )
if not self.GROUPS[GroupName] then
self:E( { "Add GROUP:", GroupName } )
self:I( { "Add GROUP:", GroupName } )
self.GROUPS[GroupName] = GROUP:Register( GroupName )
end
@ -471,7 +472,7 @@ end
function DATABASE:AddPlayer( UnitName, PlayerName )
if PlayerName then
self:E( { "Add player for unit:", UnitName, PlayerName } )
self:I( { "Add player for unit:", UnitName, PlayerName } )
self.PLAYERS[PlayerName] = UnitName
self.PLAYERUNITS[PlayerName] = self:FindUnit( UnitName )
self.PLAYERSJOINED[PlayerName] = PlayerName
@ -483,7 +484,7 @@ end
function DATABASE:DeletePlayer( UnitName, PlayerName )
if PlayerName then
self:E( { "Clean player:", PlayerName } )
self:I( { "Clean player:", PlayerName } )
self.PLAYERS[PlayerName] = nil
self.PLAYERUNITS[PlayerName] = nil
end
@ -750,7 +751,7 @@ function DATABASE:_RegisterPlayers()
local UnitName = UnitData:getName()
local PlayerName = UnitData:getPlayerName()
if not self.PLAYERS[PlayerName] then
self:E( { "Add player for unit:", UnitName, PlayerName } )
self:I( { "Add player for unit:", UnitName, PlayerName } )
self:AddPlayer( UnitName, PlayerName )
end
end
@ -773,13 +774,13 @@ function DATABASE:_RegisterGroupsAndUnits()
if DCSGroup:isExist() then
local DCSGroupName = DCSGroup:getName()
self:E( { "Register Group:", DCSGroupName } )
self:I( { "Register Group:", DCSGroupName } )
self:AddGroup( DCSGroupName )
for DCSUnitId, DCSUnit in pairs( DCSGroup:getUnits() ) do
local DCSUnitName = DCSUnit:getName()
self:E( { "Register Unit:", DCSUnitName } )
self:I( { "Register Unit:", DCSUnitName } )
self:AddUnit( DCSUnitName )
end
else
@ -788,6 +789,11 @@ function DATABASE:_RegisterGroupsAndUnits()
end
end
self:I("Groups:")
for GroupName, Group in pairs( self.GROUPS ) do
self:I( { "Group:", GroupName } )
end
return self
end
@ -798,7 +804,7 @@ end
function DATABASE:_RegisterClients()
for ClientName, ClientTemplate in pairs( self.Templates.ClientsByName ) do
self:E( { "Register Client:", ClientName } )
self:I( { "Register Client:", ClientName } )
self:AddClient( ClientName )
end
@ -809,14 +815,14 @@ end
function DATABASE:_RegisterStatics()
local CoalitionsData = { GroupsRed = coalition.getStaticObjects( coalition.side.RED ), GroupsBlue = coalition.getStaticObjects( coalition.side.BLUE ) }
self:E( { Statics = CoalitionsData } )
self:I( { Statics = CoalitionsData } )
for CoalitionId, CoalitionData in pairs( CoalitionsData ) do
for DCSStaticId, DCSStatic in pairs( CoalitionData ) do
if DCSStatic:isExist() then
local DCSStaticName = DCSStatic:getName()
self:E( { "Register Static:", DCSStaticName } )
self:I( { "Register Static:", DCSStaticName } )
self:AddStatic( DCSStaticName )
else
self:E( { "Static does not exist: ", DCSStatic } )
@ -836,7 +842,7 @@ function DATABASE:_RegisterAirbases()
local DCSAirbaseName = DCSAirbase:getName()
self:E( { "Register Airbase:", DCSAirbaseName, DCSAirbase:getID() } )
self:I( { "Register Airbase:", DCSAirbaseName, DCSAirbase:getID() } )
self:AddAirbase( DCSAirbaseName )
end
end
@ -866,9 +872,8 @@ function DATABASE:_EventOnBirth( Event )
Event.IniUnit = self:FindUnit( Event.IniDCSUnitName )
Event.IniGroup = self:FindGroup( Event.IniDCSGroupName )
local PlayerName = Event.IniUnit:GetPlayerName()
self:E( { "PlayerName:", PlayerName } )
if PlayerName then
self:E( { "Player Joined:", PlayerName } )
self:I( { "Player Joined:", PlayerName } )
if not self.PLAYERS[PlayerName] then
self:AddPlayer( Event.IniUnitName, PlayerName )
end
@ -937,7 +942,7 @@ function DATABASE:_EventOnPlayerLeaveUnit( Event )
if Event.IniObjectCategory == 1 then
local PlayerName = Event.IniUnit:GetPlayerName()
if PlayerName and self.PLAYERS[PlayerName] then
self:E( { "Player Left:", PlayerName } )
self:I( { "Player Left:", PlayerName } )
local Settings = SETTINGS:Set( PlayerName )
Settings:RemovePlayerMenu( Event.IniUnit )
self:DeletePlayer( Event.IniUnit, PlayerName )

View File

@ -723,7 +723,7 @@ do -- Event Creation
-- @param #EVENT self
-- @param AI.AI_Cargo#AI_CARGO Cargo The Cargo created.
function EVENT:CreateEventNewCargo( Cargo )
self:F( { Cargo } )
self:I( { Cargo } )
local Event = {
id = EVENTS.NewCargo,

View File

@ -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

View File

@ -121,13 +121,16 @@ GROUPTEMPLATE.Takeoff = {
-- @return #GROUP self
function GROUP:NewTemplate( GroupTemplate, CoalitionSide, CategoryID, CountryID )
local GroupName = GroupTemplate.name
_DATABASE:_RegisterGroupTemplate( GroupTemplate, CoalitionSide, CategoryID, CountryID, GroupName )
self = BASE:Inherit( self, CONTROLLABLE:New( GroupName ) )
self:F2( GroupName )
local self = BASE:Inherit( self, CONTROLLABLE:New( GroupName ) )
self.GroupName = GroupName
_DATABASE:AddGroup( GroupName )
if not _DATABASE.GROUPS[GroupName] then
_DATABASE.GROUPS[GroupName] = self
end
self:SetEventPriority( 4 )
return self
end
@ -140,7 +143,6 @@ end
-- @return #GROUP self
function GROUP:Register( GroupName )
local self = BASE:Inherit( self, CONTROLLABLE:New( GroupName ) ) -- #GROUP
self:F( GroupName )
self.GroupName = GroupName
self:SetEventPriority( 4 )

View File

@ -216,7 +216,7 @@ end
function IDENTIFIABLE:GetDesc()
self:F2( self.IdentifiableName )
local DCSIdentifiable = self:GetDCSObject()
local DCSIdentifiable = self:GetDCSObject() -- DCS#Object
if DCSIdentifiable then
local IdentifiableDesc = DCSIdentifiable:getDesc()

View File

@ -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.
@ -798,56 +867,148 @@ function POSITIONABLE:GetLaserCode() --R2.1
return self.LaserCode
end
--- Add cargo.
-- @param #POSITIONABLE self
-- @param Core.Cargo#CARGO Cargo
-- @return #POSITIONABLE
function POSITIONABLE:AddCargo( Cargo )
self.__.Cargo[Cargo] = Cargo
return self
end
do -- Cargo
--- Get all contained cargo.
-- @param #POSITIONABLE self
-- @return #POSITIONABLE
function POSITIONABLE:GetCargo()
return self.__.Cargo
end
--- Remove cargo.
-- @param #POSITIONABLE self
-- @param Core.Cargo#CARGO Cargo
-- @return #POSITIONABLE
function POSITIONABLE:RemoveCargo( Cargo )
self.__.Cargo[Cargo] = nil
return self
end
--- Returns if carrier has given cargo.
-- @param #POSITIONABLE self
-- @return Core.Cargo#CARGO Cargo
function POSITIONABLE:HasCargo( Cargo )
return self.__.Cargo[Cargo]
end
--- Clear all cargo.
-- @param #POSITIONABLE self
function POSITIONABLE:ClearCargo()
self.__.Cargo = {}
end
--- Get cargo item count.
-- @param #POSITIONABLE self
-- @return Core.Cargo#CARGO Cargo
function POSITIONABLE:CargoItemCount()
local ItemCount = 0
for CargoName, Cargo in pairs( self.__.Cargo ) do
ItemCount = ItemCount + Cargo:GetCount()
--- Add cargo.
-- @param #POSITIONABLE self
-- @param Core.Cargo#CARGO Cargo
-- @return #POSITIONABLE
function POSITIONABLE:AddCargo( Cargo )
self.__.Cargo[Cargo] = Cargo
return self
end
return ItemCount
end
--- Get all contained cargo.
-- @param #POSITIONABLE self
-- @return #POSITIONABLE
function POSITIONABLE:GetCargo()
return self.__.Cargo
end
--- Remove cargo.
-- @param #POSITIONABLE self
-- @param Core.Cargo#CARGO Cargo
-- @return #POSITIONABLE
function POSITIONABLE:RemoveCargo( Cargo )
self.__.Cargo[Cargo] = nil
return self
end
--- Returns if carrier has given cargo.
-- @param #POSITIONABLE self
-- @return Core.Cargo#CARGO Cargo
function POSITIONABLE:HasCargo( Cargo )
return self.__.Cargo[Cargo]
end
--- Clear all cargo.
-- @param #POSITIONABLE self
function POSITIONABLE:ClearCargo()
self.__.Cargo = {}
end
--- Is cargo bay empty.
-- @param #POSITIONABLE self
function POSITIONABLE:IsCargoEmpty()
local IsEmpty = true
for _, Cargo in pairs( self.__.Cargo ) do
IsEmpty = false
break
end
return IsEmpty
end
--- Get cargo item count.
-- @param #POSITIONABLE self
-- @return Core.Cargo#CARGO Cargo
function POSITIONABLE:CargoItemCount()
local ItemCount = 0
for CargoName, Cargo in pairs( self.__.Cargo ) do
ItemCount = ItemCount + Cargo:GetCount()
end
return ItemCount
end
-- --- Get Cargo Bay Free Volume in m3.
-- -- @param #POSITIONABLE self
-- -- @return #number CargoBayFreeVolume
-- function POSITIONABLE:GetCargoBayFreeVolume()
-- local CargoVolume = 0
-- for CargoName, Cargo in pairs( self.__.Cargo ) do
-- CargoVolume = CargoVolume + Cargo:GetVolume()
-- end
-- return self.__.CargoBayVolumeLimit - CargoVolume
-- end
--
--- Get Cargo Bay Free Weight in kg.
-- @param #POSITIONABLE self
-- @return #number CargoBayFreeWeight
function POSITIONABLE:GetCargoBayFreeWeight()
local CargoWeight = 0
for CargoName, Cargo in pairs( self.__.Cargo ) do
CargoWeight = CargoWeight + Cargo:GetWeight()
end
return self.__.CargoBayWeightLimit - CargoWeight
end
-- --- Get Cargo Bay Volume Limit in m3.
-- -- @param #POSITIONABLE self
-- -- @param #number VolumeLimit
-- function POSITIONABLE:SetCargoBayVolumeLimit( VolumeLimit )
-- self.__.CargoBayVolumeLimit = VolumeLimit
-- end
--- Get Cargo Bay Weight Limit in kg.
-- @param #POSITIONABLE self
-- @param #number WeightLimit
function POSITIONABLE:SetCargoBayWeightLimit( WeightLimit )
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.
-- @param #POSITIONABLE self

View File

@ -878,51 +878,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