This commit is contained in:
Sven Van de Velde 2016-08-11 09:01:47 +02:00
parent 9f37dde093
commit bdbb1ea018
6 changed files with 217 additions and 128 deletions

View File

@ -118,38 +118,28 @@ end
--- Board Cargo to a Carrier with a defined Speed. --- Board Cargo to a Carrier with a defined Speed.
-- @param #CARGO self -- @param #CARGO self
-- @param Unit#UNIT CargoCarrier -- @param Unit#UNIT CargoCarrier
-- @param #number Speed function CARGO:Board( CargoCarrier )
-- @param #number BoardDistance
-- @param #number Angle
function CARGO:Board( CargoCarrier, Speed, BoardDistance, LoadDistance, Angle )
self:F() self:F()
self:_NextEvent( self.FsmP.Board, CargoCarrier, Speed, BoardDistance, LoadDistance, Angle ) self:_NextEvent( self.FsmP.Board, CargoCarrier )
end end
--- UnBoard Cargo from a Carrier with a defined Speed. --- UnLoad Cargo from a Carrier.
-- @param #CARGO self -- @param #CARGO self
-- @param #number Speed function CARGO:UnLoad()
-- @param #number UnLoadDistance
-- @param #number UnBoardDistance
-- @param #number UnBoardRadius
-- @param #number Angle
function CARGO:UnBoard( Speed, UnLoadDistance, UnBoardDistance, UnBoardRadius, Angle )
self:F() self:F()
self:_NextEvent( self.FsmP.UnBoard, Speed, UnLoadDistance, UnBoardDistance, UnBoardRadius, Angle ) self:_NextEvent( self.FsmP.UnLoad )
end end
--- Check if CargoCarrier is near the Cargo to be Loaded. --- Check if CargoCarrier is near the Cargo to be Loaded.
-- @param #CARGO self -- @param #CARGO self
-- @param Unit#UNIT CargoCarrier -- @param Point#POINT_VEC2 PointVec2
-- @return #boolean -- @return #boolean
function CARGO:IsNear( CargoCarrier ) function CARGO:IsNear( PointVec2 )
self:F() self:F()
local CargoCarrierPoint = CargoCarrier:GetPointVec2() local Distance = PointVec2:DistanceFromPointVec2( self.CargoObject:GetPointVec2() )
local Distance = CargoCarrierPoint:DistanceFromPointVec2( self.CargoObject:GetPointVec2() )
self:T( Distance ) self:T( Distance )
if Distance <= self.NearRadius then if Distance <= self.NearRadius then
@ -260,23 +250,22 @@ function CARGO_UNIT:New( Mission, CargoUnit, Type, Name, Weight, ReportRadius, N
initial = 'UnLoaded', initial = 'UnLoaded',
events = { events = {
{ name = 'Board', from = 'UnLoaded', to = 'Boarding' }, { name = 'Board', from = 'UnLoaded', to = 'Boarding' },
{ name = 'Boarded', from = 'Boarding', to = 'Boarding' },
{ name = 'Load', from = 'Boarding', to = 'Loaded' }, { name = 'Load', from = 'Boarding', to = 'Loaded' },
{ name = 'UnLoad', from = 'Loaded', to = 'UnBoarding' },
{ name = 'UnBoard', from = 'UnBoarding', to = 'UnLoaded' },
{ name = 'Load', from = 'UnLoaded', to = 'Loaded' }, { name = 'Load', from = 'UnLoaded', to = 'Loaded' },
{ name = 'UnBoard', from = 'Loaded', to = 'UnBoarding' },
{ name = 'UnBoarded', from = 'UnBoarding', to = 'UnBoarding' },
{ name = 'UnLoad', from = 'UnBoarding', to = 'UnLoaded' },
{ name = 'UnLoad', from = 'Loaded', to = 'UnLoaded' },
}, },
callbacks = { callbacks = {
onBoard = self.OnBoard, onBoard = self.OnBoard,
onBoarded = self.OnBoarded,
onLoad = self.OnLoad, onLoad = self.OnLoad,
onUnBoard = self.OnUnBoard, onUnBoard = self.OnUnBoard,
onUnBoarded = self.OnUnBoarded,
onUnLoad = self.OnUnLoad, onUnLoad = self.OnUnLoad,
onLoaded = self.OnLoaded, onenterBoarding = self.EnterStateBoarding,
onUnLoaded = self.OnUnLoaded, onleaveBoarding = self.LeaveStateBoarding,
onenterLoaded = self.EnterStateLoaded,
onenterUnBoarding = self.EnterStateUnBoarding,
onleaveUnBoarding = self.LeaveStateUnBoarding,
onenterUnLoaded = self.EnterStateUnLoaded,
}, },
} ) } )
@ -285,14 +274,182 @@ function CARGO_UNIT:New( Mission, CargoUnit, Type, Name, Weight, ReportRadius, N
return self return self
end end
--- Board Event. --- Enter UnBoarding State.
-- @param #CARGO_UNIT self
-- @param StateMachine#STATEMACHINE_PROCESS FsmP
-- @param #string Event
-- @param #string From
-- @param #string To
-- @param Point#POINT_VEC2 ToPointVec2
function CARGO_UNIT:EnterStateUnBoarding( FsmP, Event, From, To, ToPointVec2 )
self:F()
local Angle = 180
local Speed = 10
local DeployDistance = 5
local RouteDistance = 60
if From == "Loaded" then
local CargoCarrierPointVec2 = self.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 CargoDeployPointVec2 = CargoCarrierPointVec2:Translate( DeployDistance, CargoDeployHeading )
local CargoRoutePointVec2 = CargoCarrierPointVec2:Translate( RouteDistance, CargoDeployHeading )
if not ToPointVec2 then
ToPointVec2 = CargoRoutePointVec2
end
local FromPointVec2 = CargoCarrierPointVec2
-- Respawn the group...
if self.CargoObject then
self.CargoObject:ReSpawn( CargoDeployPointVec2:GetVec3(), CargoDeployHeading )
self.CargoCarrier = nil
local Points = {}
Points[#Points+1] = FromPointVec2:RoutePointGround( Speed )
Points[#Points+1] = ToPointVec2:RoutePointGround( Speed )
local TaskRoute = self.CargoObject:TaskRoute( Points )
self.CargoObject:SetTask( TaskRoute, 1 )
end
end
end
--- Leave UnBoarding State.
-- @param #CARGO_UNIT self
-- @param StateMachine#STATEMACHINE_PROCESS FsmP
-- @param #string Event
-- @param #string From
-- @param #string To
-- @param Point#POINT_VEC2 ToPointVec2
function CARGO_UNIT:LeaveStateUnBoarding( FsmP, Event, From, To, ToPointVec2 )
self:F()
local Angle = 180
local Speed = 10
local Distance = 5
if From == "UnBoarding" then
if self:IsNear( ToPointVec2 ) then
return true
else
self:_NextEvent( FsmP.UnLoad, ToPointVec2 )
end
return false
end
end
--- Enter UnLoaded State.
-- @param #CARGO_UNIT self
-- @param StateMachine#STATEMACHINE_PROCESS FsmP
-- @param #string Event
-- @param #string From
-- @param #string To
function CARGO_UNIT:EnterStateUnLoaded( FsmP, Event, From, To, ToPointVec2 )
self:F()
local Angle = 180
local Speed = 10
local Distance = 5
if From == "Loaded" then
local StartPointVec2 = self.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 CargoDeployPointVec2 = StartPointVec2:Translate( Distance, CargoDeployHeading )
-- Respawn the group...
if self.CargoObject then
self.CargoObject:ReSpawn( ToPointVec2:GetVec3(), 0 )
self.CargoCarrier = nil
end
end
end
--- Enter Boarding State.
-- @param #CARGO_UNIT self -- @param #CARGO_UNIT self
-- @param StateMachine#STATEMACHINE_PROCESS FsmP -- @param StateMachine#STATEMACHINE_PROCESS FsmP
-- @param #string Event -- @param #string Event
-- @param #string From -- @param #string From
-- @param #string To -- @param #string To
-- @param Unit#UNIT CargoCarrier -- @param Unit#UNIT CargoCarrier
function CARGO_UNIT:OnBoard( FsmP, Event, From, To, CargoCarrier, Speed ) function CARGO_UNIT:EnterStateBoarding( FsmP, Event, From, To, CargoCarrier )
self:F()
local Speed = 10
local Angle = 180
local Distance = 5
if From == "UnLoaded" then
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:RoutePointGround( Speed )
Points[#Points+1] = CargoDeployPointVec2:RoutePointGround( Speed )
local TaskRoute = self.CargoObject:TaskRoute( Points )
self.CargoObject:SetTask( TaskRoute, 2 )
end
end
--- Leave Boarding State.
-- @param #CARGO_UNIT self
-- @param StateMachine#STATEMACHINE_PROCESS FsmP
-- @param #string Event
-- @param #string From
-- @param #string To
-- @param Unit#UNIT CargoCarrier
function CARGO_UNIT:LeaveStateBoarding( FsmP, Event, From, To, CargoCarrier )
self:F()
if self:IsNear( CargoCarrier:GetPointVec2() ) then
return true
else
self:_NextEvent( FsmP.Load, CargoCarrier )
end
return false
end
--- Loaded State.
-- @param #CARGO_UNIT self
-- @param StateMachine#STATEMACHINE_PROCESS FsmP
-- @param #string Event
-- @param #string From
-- @param #string To
-- @param Unit#UNIT CargoCarrier
function CARGO_UNIT:EnterStateLoaded( FsmP, Event, From, To, CargoCarrier )
self:F()
self.CargoCarrier = CargoCarrier
-- Only destroy the CargoObject is if there is a CargoObject (packages don't have CargoObjects).
if self.CargoObject then
self.CargoObject:Destroy()
end
end
--- Board Event.
-- @param #CARGO_UNIT self
-- @param StateMachine#STATEMACHINE_PROCESS FsmP
-- @param #string Event
-- @param #string From
-- @param #string To
function CARGO_UNIT:OnBoard( FsmP, Event, From, To, CargoCarrier )
self:F() self:F()
self.CargoInAir = self.CargoObject:InAir() self.CargoInAir = self.CargoObject:InAir()
@ -302,21 +459,9 @@ function CARGO_UNIT:OnBoard( FsmP, Event, From, To, CargoCarrier, Speed )
-- Only move the group to the carrier when the cargo is not in the air -- Only move the group to the carrier when the cargo is not in the air
-- (eg. cargo can be on a oil derrick, moving the cargo on the oil derrick will drop the cargo on the sea). -- (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 not self.CargoInAir then
self:_NextEvent( FsmP.Load, CargoCarrier )
local Points = {}
local PointStartVec2 = self.CargoObject:GetPointVec2()
local PointEndVec2 = CargoCarrier:GetPointVec2()
Points[#Points+1] = PointStartVec2:RoutePointGround( Speed )
Points[#Points+1] = PointEndVec2:RoutePointGround( Speed )
local TaskRoute = self.CargoObject:TaskRoute( Points )
self.CargoObject:SetTask( TaskRoute, 4 )
end end
self:_NextEvent( FsmP.Boarded, CargoCarrier )
end end
@ -343,12 +488,7 @@ end
-- @param #string Event -- @param #string Event
-- @param #string From -- @param #string From
-- @param #string To -- @param #string To
-- @param #number Speed function CARGO_UNIT:OnUnBoard( FsmP, Event, From, To )
-- @param #number UnLoadDistance
-- @param #number UnBoardDistance
-- @param #number Radius
-- @param #number Angle
function CARGO_UNIT:OnUnBoard( FsmP, Event, From, To, Speed, UnLoadDistance, UnBoardDistance, Radius, Angle )
self:F() self:F()
self.CargoInAir = self.CargoObject:InAir() self.CargoInAir = self.CargoObject:InAir()
@ -361,24 +501,10 @@ function CARGO_UNIT:OnUnBoard( FsmP, Event, From, To, Speed, UnLoadDistance, UnB
end end
self:_NextEvent( FsmP.UnBoarded, Speed, UnLoadDistance, UnBoardDistance, Radius, Angle ) self:_NextEvent( FsmP.UnLoad )
end end
--- UnBoarded Event.
-- @param #CARGO_UNIT self
-- @param StateMachine#STATEMACHINE_PROCESS FsmP
-- @param #string Event
-- @param #string From
-- @param #string To
-- @param Unit#UNIT CargoCarrier
function CARGO_UNIT:OnUnBoarded( FsmP, Event, From, To, Speed, UnLoadDistance, UnBoardDistance, Radius, Angle )
self:F()
self:_NextEvent( FsmP.UnLoad, Speed, UnLoadDistance, UnBoardDistance, Radius, Angle )
end
--- Load Event. --- Load Event.
-- @param #CARGO_UNIT self -- @param #CARGO_UNIT self
-- @param StateMachine#STATEMACHINE_PROCESS FsmP -- @param StateMachine#STATEMACHINE_PROCESS FsmP
@ -391,12 +517,6 @@ function CARGO_UNIT:OnLoad( FsmP, Event, From, To, CargoCarrier )
self:T( self.ClassName ) self:T( self.ClassName )
self.CargoCarrier = CargoCarrier
-- Only destroy the CargoObject is if there is a CargoObject (packages don't have CargoObjects).
if self.CargoObject then
self.CargoObject:Destroy()
end
end end
--- UnLoad Event. --- UnLoad Event.
@ -405,35 +525,9 @@ end
-- @param #string Event -- @param #string Event
-- @param #string From -- @param #string From
-- @param #string To -- @param #string To
-- @param #number Distance function CARGO_UNIT:OnUnLoad( FsmP, Event, From, To )
-- @param #number Angle
function CARGO_UNIT:OnUnLoad( FsmP, Event, From, To, Speed, UnLoadDistance, UnBoardDistance, Radius, Angle )
self:F() self:F()
local StartPointVec2 = self.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 CargoDeployPointVec2 = StartPointVec2:Translate( UnLoadDistance, CargoDeployHeading )
-- Respawn the group...
if self.CargoObject then
self.CargoObject:ReSpawn( CargoDeployPointVec2:GetVec3(), CargoDeployHeading )
local Points = {}
local StartPointVec2 = self.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 )
self:T( { CargoCarrierHeading, CargoDeployHeading } )
local CargoDeployPointVec2 = StartPointVec2:Translate( UnBoardDistance, CargoDeployHeading )
local CargoDeployPointVec2 = CargoDeployPointVec2:GetRandomPointVec2InRadius( Radius )
Points[#Points+1] = StartPointVec2:RoutePointGround( Speed )
Points[#Points+1] = CargoDeployPointVec2:RoutePointGround( Speed )
local TaskRoute = self.CargoObject:TaskRoute( Points )
self.CargoObject:SetTask( TaskRoute, 4 )
end
end end
end end

View File

@ -304,24 +304,6 @@ function POINT_VEC3:Get3DDistance( TargetPointVec3 )
return ( ( TargetVec3.x - SourceVec3.x ) ^ 2 + ( TargetVec3.y - SourceVec3.y ) ^ 2 + ( TargetVec3.z - SourceVec3.z ) ^ 2 ) ^ 0.5 return ( ( TargetVec3.x - SourceVec3.x ) ^ 2 + ( TargetVec3.y - SourceVec3.y ) ^ 2 + ( TargetVec3.z - SourceVec3.z ) ^ 2 ) ^ 0.5
end end
--- Add a Distance in meters from the POINT_VEC3 orthogonal plane, with the given angle, and calculate the new POINT_VEC3.
-- @param #POINT_VEC3 self
-- @param DCSTypes#Distance Distance The Distance to be added in meters.
-- @param DCSTypes#Angle Angle The Angle in degrees.
-- @return #POINT_VEC3 The new calculated POINT_VEC3.
function POINT_VEC3:Translate( Distance, Angle )
local SX = self:GetX()
local SY = self:GetY()
local Radians = Angle / 180 * math.pi
local TX = Distance * math.cos( Radians ) + SX
local TY = Distance * math.sin( Radians ) + SY
self:SetX( TX )
self:SetY( TY )
return self
end
--- Provides a Bearing / Range string --- Provides a Bearing / Range string
-- @param #POINT_VEC3 self -- @param #POINT_VEC3 self
-- @param #number AngleRadians The angle in randians -- @param #number AngleRadians The angle in randians
@ -580,9 +562,9 @@ POINT_VEC2 = {
function POINT_VEC2:New( x, y, LandHeightAdd ) function POINT_VEC2:New( x, y, LandHeightAdd )
local LandHeight = land.getHeight( { ["x"] = x, ["y"] = y } ) local LandHeight = land.getHeight( { ["x"] = x, ["y"] = y } )
if LandHeightAdd then
LandHeight = LandHeight + LandHeightAdd LandHeightAdd = LandHeightAdd or 0
end LandHeight = LandHeight + LandHeightAdd
local self = BASE:Inherit( self, POINT_VEC3:New( x, LandHeight, y ) ) local self = BASE:Inherit( self, POINT_VEC3:New( x, LandHeight, y ) )
@ -595,12 +577,10 @@ end
-- @return Point#POINT_VEC2 self -- @return Point#POINT_VEC2 self
function POINT_VEC2:NewFromVec2( Vec2, LandHeightAdd ) function POINT_VEC2:NewFromVec2( Vec2, LandHeightAdd )
local self = BASE:Inherit( self, BASE:New() )
local LandHeight = land.getHeight( Vec2 ) local LandHeight = land.getHeight( Vec2 )
if LandHeightAdd then
LandHeight = LandHeight + LandHeightAdd LandHeightAdd = LandHeightAdd or 0
end LandHeight = LandHeight + LandHeightAdd
local self = BASE:Inherit( self, POINT_VEC3:New( Vec2.x, LandHeight, Vec2.y ) ) local self = BASE:Inherit( self, POINT_VEC3:New( Vec2.x, LandHeight, Vec2.y ) )
self:F2( { Vec2.x, Vec2.y, LandHeightAdd } ) self:F2( { Vec2.x, Vec2.y, LandHeightAdd } )
@ -694,3 +674,20 @@ function POINT_VEC2:GetAltitudeText()
return '' return ''
end end
--- Add a Distance in meters from the POINT_VEC2 orthonormal plane, with the given angle, and calculate the new POINT_VEC2.
-- @param #POINT_VEC2 self
-- @param DCSTypes#Distance Distance The Distance to be added in meters.
-- @param DCSTypes#Angle Angle The Angle in degrees.
-- @return #POINT_VEC2 The new calculated POINT_VEC2.
function POINT_VEC2:Translate( Distance, Angle )
local SX = self:GetX()
local SY = self:GetY()
local Radians = Angle / 180 * math.pi
local TX = Distance * math.cos( Radians ) + SX
local TY = Distance * math.sin( Radians ) + SY
return POINT_VEC2:New( TX, TY )
end

View File

@ -1,5 +1,5 @@
local Mission = MISSION:New( "Pickup Cargo", "High", "Test for Cargo Pickup", coalition.side.RED ) local Mission = MISSION:New( "Transfer Cargo", "High", "Test for Cargo", coalition.side.RED )
local CargoEngineer = UNIT:FindByName( "Engineer" ) local CargoEngineer = UNIT:FindByName( "Engineer" )
local InfantryCargo = CARGO_UNIT:New( Mission, CargoEngineer, "Engineer", "Engineer Sven", "81", 2000, 25 ) local InfantryCargo = CARGO_UNIT:New( Mission, CargoEngineer, "Engineer", "Engineer Sven", "81", 2000, 25 )
@ -9,5 +9,5 @@ local CargoCarrier = UNIT:FindByName( "Carrier" )
-- This call will make the Cargo run to the CargoCarrier. -- This call will make the Cargo run to the CargoCarrier.
-- Upon arrival at the CargoCarrier, the Cargo will be Loaded into the Carrier. -- Upon arrival at the CargoCarrier, the Cargo will be Loaded into the Carrier.
-- This process is now fully automated. -- This process is now fully automated.
InfantryCargo:Board( CargoCarrier, 10 ) InfantryCargo:Board( CargoCarrier )

View File

@ -1,5 +1,5 @@
local Mission = MISSION:New( "Pickup Cargo", "High", "Test for Cargo Pickup", coalition.side.RED ) local Mission = MISSION:New( "Transfer Cargo", "High", "Test for Cargo", coalition.side.RED )
local CargoEngineer = UNIT:FindByName( "Engineer" ) local CargoEngineer = UNIT:FindByName( "Engineer" )
local InfantryCargo = CARGO_UNIT:New( Mission, CargoEngineer, "Engineer", "Engineer Sven", "81", 2000, 25 ) local InfantryCargo = CARGO_UNIT:New( Mission, CargoEngineer, "Engineer", "Engineer Sven", "81", 2000, 25 )
@ -10,6 +10,4 @@ local CargoCarrier = UNIT:FindByName( "Carrier" )
InfantryCargo:Load( CargoCarrier ) InfantryCargo:Load( CargoCarrier )
-- This will Unboard the Cargo from the Carrier. -- This will Unboard the Cargo from the Carrier.
-- The Cargo will run from the Carrier to a point in the NearRadius around the Carrier. InfantryCargo:UnLoad()
-- Unboard the Cargo with a speed of 10 km/h, go to 200 meters 180 degrees from the Carrier, iin a zone of 25 meters (NearRadius).
InfantryCargo:UnBoard( 10, 2, 20, 10, 180 )