From c999389cda86d91ea07a8c39568ce8a62b1b838b Mon Sep 17 00:00:00 2001 From: FlightControl_Master Date: Mon, 23 Apr 2018 06:51:49 +0200 Subject: [PATCH] Handler for unloading too. --- Moose Development/Moose/AI/AI_Cargo_APC.lua | 268 ++++++-- .../Moose/AI/AI_Cargo_Helicopter.lua | 35 +- Moose Development/Moose/Cargo/Cargo.lua | 20 +- Moose Development/Moose/Cargo/CargoCrate.lua | 6 +- Moose Development/Moose/Cargo/CargoGroup.lua | 20 +- .../Moose/Cargo/CargoSlingload.lua | 8 +- Moose Development/Moose/Cargo/CargoUnit.lua | 2 +- Moose Development/Moose/Core/Database.lua | 20 +- Moose Development/Moose/Core/Point.lua | 14 +- .../Moose/Wrapper/Controllable.lua | 645 +++++++++--------- 10 files changed, 600 insertions(+), 438 deletions(-) diff --git a/Moose Development/Moose/AI/AI_Cargo_APC.lua b/Moose Development/Moose/AI/AI_Cargo_APC.lua index 2c34615cd..68ffc7046 100644 --- a/Moose Development/Moose/AI/AI_Cargo_APC.lua +++ b/Moose Development/Moose/AI/AI_Cargo_APC.lua @@ -24,18 +24,21 @@ AI_CARGO_APC = { --- Creates a new AI_CARGO_APC object. -- @param #AI_CARGO_APC self --- @param Wrapper.Unit#UNIT CargoCarrier --- @param Cargo.CargoGroup#CARGO_GROUP CargoGroup +-- @param Wrapper.Group#GROUP CargoCarrier +-- @param Core.Set#SET_CARGO CargoSet -- @param #number CombatRadius -- @return #AI_CARGO_APC -function AI_CARGO_APC:New( CargoCarrier, CargoGroup, CombatRadius ) +function AI_CARGO_APC:New( CargoCarrier, CargoSet, CombatRadius ) local self = BASE:Inherit( self, FSM_CONTROLLABLE:New() ) -- #AI_CARGO_APC - self.CargoGroup = CargoGroup -- Cargo.CargoGroup#CARGO_GROUP + self.CargoSet = CargoSet -- Core.Set#SET_CARGO self.CombatRadius = CombatRadius - self:SetStartState( "UnLoaded" ) + self:SetStartState( "Unloaded" ) + + self:AddTransition( "Unloaded", "Pickup", "*" ) + self:AddTransition( "Loaded", "Deploy", "*" ) self:AddTransition( "*", "Load", "Boarding" ) self:AddTransition( "Boarding", "Board", "Boarding" ) @@ -46,10 +49,85 @@ function AI_CARGO_APC:New( CargoCarrier, CargoGroup, CombatRadius ) self:AddTransition( "*", "Monitor", "*" ) self:AddTransition( "*", "Follow", "Following" ) - self:AddTransition( "*", "Guard", "Guarding" ) + self:AddTransition( "*", "Guard", "Unloaded" ) self:AddTransition( "*", "Destroyed", "Destroyed" ) + + --- Pickup Handler OnBefore for AI_CARGO_APC + -- @function [parent=#AI_CARGO_APC] OnBeforePickup + -- @param #AI_CARGO_APC self + -- @param #string From + -- @param #string Event + -- @param #string To + -- @param Core.Point#COORDINATE Coordinate + -- @return #boolean + + --- Pickup Handler OnAfter for AI_CARGO_APC + -- @function [parent=#AI_CARGO_APC] OnAfterPickup + -- @param #AI_CARGO_APC self + -- @param #string From + -- @param #string Event + -- @param #string To + -- @param Core.Point#COORDINATE Coordinate + + --- Pickup Trigger for AI_CARGO_APC + -- @function [parent=#AI_CARGO_APC] Pickup + -- @param #AI_CARGO_APC self + -- @param Core.Point#COORDINATE Coordinate + + --- Pickup Asynchronous Trigger for AI_CARGO_APC + -- @function [parent=#AI_CARGO_APC] __Pickup + -- @param #AI_CARGO_APC self + -- @param #number Delay + -- @param Core.Point#COORDINATE Coordinate + + --- Deploy Handler OnBefore for AI_CARGO_APC + -- @function [parent=#AI_CARGO_APC] OnBeforeDeploy + -- @param #AI_CARGO_APC self + -- @param #string From + -- @param #string Event + -- @param #string To + -- @param Core.Point#COORDINATE Coordinate + -- @return #boolean + + --- Deploy Handler OnAfter for AI_CARGO_APC + -- @function [parent=#AI_CARGO_APC] OnAfterDeploy + -- @param #AI_CARGO_APC self + -- @param #string From + -- @param #string Event + -- @param #string To + -- @param Core.Point#COORDINATE Coordinate + + --- Deploy Trigger for AI_CARGO_APC + -- @function [parent=#AI_CARGO_APC] Deploy + -- @param #AI_CARGO_APC self + -- @param Core.Point#COORDINATE Coordinate + + --- Deploy Asynchronous Trigger for AI_CARGO_APC + -- @function [parent=#AI_CARGO_APC] __Deploy + -- @param #AI_CARGO_APC self + -- @param Core.Point#COORDINATE Coordinate + -- @param #number Delay + + + --- Loaded Handler OnAfter for AI_CARGO_APC + -- @function [parent=#AI_CARGO_APC] OnAfterLoaded + -- @param #AI_CARGO_APC self + -- @param Wrapper.Group#GROUP APC + -- @param #string From + -- @param #string Event + -- @param #string To + + --- Unloaded Handler OnAfter for AI_CARGO_APC + -- @function [parent=#AI_CARGO_APC] OnAfterUnloaded + -- @param #AI_CARGO_APC self + -- @param Wrapper.Group#GROUP APC + -- @param #string From + -- @param #string Event + -- @param #string To + + self:__Monitor( 1 ) self:SetCarrier( CargoCarrier ) @@ -60,11 +138,11 @@ end --- Set the Carrier. -- @param #AI_CARGO_APC self --- @param Wrapper.Unit#UNIT CargoCarrier +-- @param Wrapper.Group#GROUP CargoCarrier -- @return #AI_CARGO_APC function AI_CARGO_APC:SetCarrier( CargoCarrier ) - self.CargoCarrier = CargoCarrier -- Wrapper.Unit#UNIT + self.CargoCarrier = CargoCarrier -- Wrapper.Group#GROUP self.CargoCarrier:SetState( self.CargoCarrier, "AI_CARGO_APC", self ) CargoCarrier:HandleEvent( EVENTS.Dead ) @@ -110,7 +188,7 @@ end -- @param #AI_CARGO_APC self -- @param Core.Point#COORDINATE Coordinate -- @param #number Radius --- @return Wrapper.Unit#UNIT NewCarrier +-- @return Wrapper.Group#GROUP NewCarrier function AI_CARGO_APC:FindCarrier( Coordinate, Radius ) local CoordinateZone = ZONE_RADIUS:New( "Zone" , Coordinate:GetVec2(), Radius ) @@ -122,11 +200,12 @@ function AI_CARGO_APC:FindCarrier( Coordinate, Radius ) local Attributes = NearUnit:GetDesc() self:F({Desc=Attributes}) if NearUnit:HasAttribute( "Trucks" ) then - self:SetCarrier( NearUnit ) - break + return NearUnit:GetGroup() end end end + + return nil end @@ -135,7 +214,7 @@ end --- Follow Infantry to the Carrier. -- @param #AI_CARGO_APC self -- @param #AI_CARGO_APC Me --- @param Wrapper.Unit#UNIT CargoCarrier +-- @param Wrapper.Group#GROUP CargoCarrier -- @param Wrapper.Group#GROUP InfantryGroup -- @return #AI_CARGO_APC function AI_CARGO_APC:FollowToCarrier( Me, CargoCarrier, InfantryGroup ) @@ -186,7 +265,7 @@ end --- @param #AI_CARGO_APC self --- @param Wrapper.Unit#UNIT CargoCarrier +-- @param Wrapper.Group#GROUP CargoCarrier function AI_CARGO_APC:onafterMonitor( CargoCarrier, From, Event, To ) self:F( { CargoCarrier, From, Event, To } ) @@ -195,32 +274,33 @@ function AI_CARGO_APC:onafterMonitor( CargoCarrier, From, Event, To ) local Coordinate = CargoCarrier:GetCoordinate() self.Zone:Scan( { Object.Category.UNIT } ) if self.Zone:IsAllInZoneOfCoalition( self.Coalition ) then - if self:Is( "Unloaded" ) or self:Is( "Guarding" ) or self:Is( "Following" ) then + if self:Is( "Unloaded" ) or self:Is( "Following" ) then -- There are no enemies within combat range. Load the CargoCarrier. - self:__Load( 1 ) + self:Load() end else if self:Is( "Loaded" ) then -- There are enemies within combat range. Unload the CargoCarrier. self:__Unload( 1 ) - end - end - if self:Is( "Guarding" ) then - if not self.CargoGroup:IsNear( CargoCarrier, 5 ) then - 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 + if self:Is( "Unloaded" ) then + if not self.Cargo:IsNear( CargoCarrier, 5 ) then + self:Follow() + end + end + if self:Is( "Following" ) then + local Distance = Coordinate:Get2DDistance( self.Cargo:GetCoordinate() ) + self:F( { Distance = Distance } ) + if Distance > 40 then + CargoCarrier:RouteStop() + self.CarrierStopped = true + else + if self.CarrierStopped then + if self.Cargo:IsNear( CargoCarrier, 10 ) then + CargoCarrier:RouteResume() + self.CarrierStopped = nil + end + end end end end @@ -236,66 +316,77 @@ end --- @param #AI_CARGO_APC self --- @param Wrapper.Unit#UNIT CargoCarrier -function AI_CARGO_APC:onafterLoad( CargoCarrier, From, Event, To ) - self:F( { CargoCarrier, From, Event, To } ) +-- @param Wrapper.Group#GROUP Carrier +function AI_CARGO_APC:onbeforeLoad( Carrier, From, Event, To ) + self:F( { Carrier, From, Event, To } ) - if CargoCarrier and CargoCarrier:IsAlive() then - CargoCarrier:RouteStop() - self:__Board( 10 ) - self.CargoGroup:Board( CargoCarrier, 10 ) + if Carrier and Carrier:IsAlive() then + for _, Cargo in pairs( self.CargoSet:GetSet() ) do + local Cargo = Cargo -- Cargo.Cargo#CARGO + self:F( Cargo ) + if Cargo:IsInLoadRadius( Carrier:GetCoordinate() ) then + self:F( "In radius" ) + Carrier:RouteStop() + self:__Board( 1, Cargo ) + Cargo:Board( Carrier:GetUnit(1), 25 ) + return true + end + end end + return false + end --- @param #AI_CARGO_APC self --- @param Wrapper.Unit#UNIT CargoCarrier -function AI_CARGO_APC:onafterBoard( CargoCarrier, From, Event, To ) - self:F( { CargoCarrier, From, Event, To } ) +-- @param Wrapper.Group#GROUP Carrier +function AI_CARGO_APC:onafterBoard( Carrier, From, Event, To, Cargo ) + self:F( { Carrier, From, Event, To, Cargo } ) - if CargoCarrier and CargoCarrier:IsAlive() then - self:F({ IsLoaded = self.CargoGroup:IsLoaded() } ) - if not self.CargoGroup:IsLoaded() then - self:__Board( 10 ) + if Carrier and Carrier:IsAlive() then + self:F({ IsLoaded = Cargo:IsLoaded() } ) + if not Cargo:IsLoaded() then + self:__Board( 10, Cargo ) else - self:__Loaded( 1 ) + self:__Loaded( 1, Cargo ) end end end --- @param #AI_CARGO_APC self --- @param Wrapper.Unit#UNIT CargoCarrier -function AI_CARGO_APC:onafterLoaded( CargoCarrier, From, Event, To ) - self:F( { CargoCarrier, From, Event, To } ) +-- @param Wrapper.Group#GROUP CargoCarrier +function AI_CARGO_APC:onafterLoaded( CargoCarrier, From, Event, To, Cargo ) + self:F( { CargoCarrier, From, Event, To, Cargo } ) if CargoCarrier and CargoCarrier:IsAlive() then CargoCarrier:RouteResume() + self.Cargo = Cargo end end --- @param #AI_CARGO_APC self --- @param Wrapper.Unit#UNIT CargoCarrier +-- @param Wrapper.Group#GROUP CargoCarrier function AI_CARGO_APC:onafterUnload( CargoCarrier, From, Event, To ) self:F( { CargoCarrier, From, Event, To } ) if CargoCarrier and CargoCarrier:IsAlive() then CargoCarrier:RouteStop() - self.CargoGroup:UnBoard( ) + self.Cargo:UnBoard() self:__Unboard( 10 ) end end --- @param #AI_CARGO_APC self --- @param Wrapper.Unit#UNIT CargoCarrier +-- @param Wrapper.Group#GROUP CargoCarrier function AI_CARGO_APC:onafterUnboard( CargoCarrier, From, Event, To ) self:F( { CargoCarrier, From, Event, To } ) if CargoCarrier and CargoCarrier:IsAlive() then - if not self.CargoGroup:IsUnLoaded() then + if not self.Cargo:IsUnLoaded() then self:__Unboard( 10 ) else self:__Unloaded( 1 ) @@ -305,7 +396,7 @@ function AI_CARGO_APC:onafterUnboard( CargoCarrier, From, Event, To ) end --- @param #AI_CARGO_APC self --- @param Wrapper.Unit#UNIT CargoCarrier +-- @param Wrapper.Group#GROUP CargoCarrier function AI_CARGO_APC:onafterUnloaded( CargoCarrier, From, Event, To ) self:F( { CargoCarrier, From, Event, To } ) @@ -319,13 +410,13 @@ end --- @param #AI_CARGO_APC self --- @param Wrapper.Unit#UNIT CargoCarrier +-- @param Wrapper.Group#GROUP CargoCarrier function AI_CARGO_APC:onafterFollow( CargoCarrier, From, Event, To ) self:F( { CargoCarrier, From, Event, To } ) self:F( "Follow" ) if CargoCarrier and CargoCarrier:IsAlive() then - self.CargoGroup.CargoSet:ForEach( + self.Cargo.CargoSet:ForEach( --- @param Core.Cargo#CARGO Cargo function( Cargo ) self:F( { "Follow", Cargo.CargoObject:GetName() } ) @@ -339,3 +430,66 @@ function AI_CARGO_APC:onafterFollow( CargoCarrier, From, Event, To ) end + +--- @param #AI_CARGO_APC +-- @param Wrapper.Group#GROUP Carrier +function AI_CARGO_APC._Pickup( Carrier ) + + Carrier:F( { "AI_CARGO_APC._Pickup:", Carrier:GetName() } ) + + if Carrier:IsAlive() then + Carrier:__Load( 1 ) + end +end + + +--- @param #AI_CARGO_APC +-- @param Wrapper.Group#GROUP Carrier +function AI_CARGO_APC._Deploy( Carrier ) + + Carrier:F( { "AI_CARGO_APC._Deploy:", Carrier:GetName() } ) + + if Carrier:IsAlive() then + Carrier:__Unload( 1 ) + end +end + + + +--- @param #AI_CARGO_APC self +-- @param Wrapper.Group#GROUP Carrier +-- @param From +-- @param Event +-- @param To +-- @param Core.Point#COORDINATE Coordinate +-- @param #number Speed +function AI_CARGO_APC:onafterPickup( Carrier, From, Event, To, Coordinate, Speed ) + + if Carrier and Carrier:IsAlive() then + + self.RoutePickup = true + + Carrier:RouteGroundOnRoad( Coordinate, Speed, 1 ) + end + +end + + +--- @param #AI_CARGO_APC self +-- @param Wrapper.Group#GROUP Carrier +-- @param From +-- @param Event +-- @param To +-- @param Core.Point#COORDINATE Coordinate +-- @param #number Speed +function AI_CARGO_APC:onafterDeploy( Carrier, From, Event, To, Coordinate, Speed ) + + if Carrier and Carrier:IsAlive() then + + self.RouteDeploy = true + + Carrier:RouteGroundOnRoad( Coordinate, Speed, 1 ) + end + +end + diff --git a/Moose Development/Moose/AI/AI_Cargo_Helicopter.lua b/Moose Development/Moose/AI/AI_Cargo_Helicopter.lua index 05afee6a4..ad502c322 100644 --- a/Moose Development/Moose/AI/AI_Cargo_Helicopter.lua +++ b/Moose Development/Moose/AI/AI_Cargo_Helicopter.lua @@ -24,7 +24,7 @@ AI_CARGO_HELICOPTER = { --- Creates a new AI_CARGO_HELICOPTER object. -- @param #AI_CARGO_HELICOPTER self --- @param Wrapper.Unit#UNIT Helicopter +-- @param Wrapper.Group#GROUP Helicopter -- @param Core.Set#SET_CARGO CargoSet -- @param #number CombatRadius -- @return #AI_CARGO_HELICOPTER @@ -116,13 +116,13 @@ end --- Set the Carrier. -- @param #AI_CARGO_HELICOPTER self --- @param Wrapper.Unit#UNIT Helicopter +-- @param Wrapper.Group#GROUP Helicopter -- @return #AI_CARGO_HELICOPTER function AI_CARGO_HELICOPTER:SetCarrier( Helicopter ) local AICargo = self - self.Helicopter = Helicopter -- Wrapper.Unit#UNIT + self.Helicopter = Helicopter -- Wrapper.Group#GROUP self.Helicopter:SetState( self.Helicopter, "AI_CARGO_HELICOPTER", self ) self.RoutePickup = false @@ -173,7 +173,7 @@ end -- @param #AI_CARGO_HELICOPTER self -- @param Core.Point#COORDINATE Coordinate -- @param #number Radius --- @return Wrapper.Unit#UNIT NewCarrier +-- @return Wrapper.Group#GROUP NewCarrier function AI_CARGO_HELICOPTER:FindCarrier( Coordinate, Radius ) local CoordinateZone = ZONE_RADIUS:New( "Zone" , Coordinate:GetVec2(), Radius ) @@ -183,18 +183,19 @@ function AI_CARGO_HELICOPTER:FindCarrier( Coordinate, Radius ) self:F({NearUnit=NearUnit}) if not NearUnit:GetState( NearUnit, "AI_CARGO_HELICOPTER" ) then local Attributes = NearUnit:GetDesc() - self:F({Desc=Attributes}) + self:F({Attributes=Attributes}) if NearUnit:HasAttribute( "Trucks" ) then - self:SetCarrier( NearUnit ) - break + return NearUnit:GetGroup() end end end + + return nil end --- @param #AI_CARGO_HELICOPTER self --- @param Wrapper.Unit#UNIT Helicopter +-- @param Wrapper.Group#GROUP Helicopter -- @param From -- @param Event -- @param To @@ -221,7 +222,7 @@ end --- @param #AI_CARGO_HELICOPTER self --- @param Wrapper.Unit#UNIT Helicopter +-- @param Wrapper.Group#GROUP Helicopter -- @param From -- @param Event -- @param To @@ -276,7 +277,7 @@ end --- @param #AI_CARGO_HELICOPTER self --- @param Wrapper.Unit#UNIT Helicopter +-- @param Wrapper.Group#GROUP Helicopter -- @param From -- @param Event -- @param To @@ -331,7 +332,7 @@ end --- @param #AI_CARGO_HELICOPTER self --- @param Wrapper.Unit#UNIT Helicopter +-- @param Wrapper.Group#GROUP Helicopter function AI_CARGO_HELICOPTER:onafterLoad( Helicopter, From, Event, To, Coordinate ) if Helicopter and Helicopter:IsAlive() then @@ -339,7 +340,7 @@ function AI_CARGO_HELICOPTER:onafterLoad( Helicopter, From, Event, To, Coordinat for _, Cargo in pairs( self.CargoSet:GetSet() ) do if Cargo:IsInLoadRadius( Coordinate ) then self:__Board( 5 ) - Cargo:Board( Helicopter, 25 ) + Cargo:Board( Helicopter:GetUnit(1), 25 ) self.Cargo = Cargo break end @@ -349,7 +350,7 @@ function AI_CARGO_HELICOPTER:onafterLoad( Helicopter, From, Event, To, Coordinat end --- @param #AI_CARGO_HELICOPTER self --- @param Wrapper.Unit#UNIT Helicopter +-- @param Wrapper.Group#GROUP Helicopter function AI_CARGO_HELICOPTER:onafterBoard( Helicopter, From, Event, To ) if Helicopter and Helicopter:IsAlive() then @@ -364,7 +365,7 @@ function AI_CARGO_HELICOPTER:onafterBoard( Helicopter, From, Event, To ) end --- @param #AI_CARGO_HELICOPTER self --- @param Wrapper.Unit#UNIT Helicopter +-- @param Wrapper.Group#GROUP Helicopter function AI_CARGO_HELICOPTER:onafterLoaded( Helicopter, From, Event, To ) if Helicopter and Helicopter:IsAlive() then @@ -374,7 +375,7 @@ end --- @param #AI_CARGO_HELICOPTER self --- @param Wrapper.Unit#UNIT Helicopter +-- @param Wrapper.Group#GROUP Helicopter function AI_CARGO_HELICOPTER:onafterUnload( Helicopter, From, Event, To ) if Helicopter and Helicopter:IsAlive() then @@ -385,7 +386,7 @@ function AI_CARGO_HELICOPTER:onafterUnload( Helicopter, From, Event, To ) end --- @param #AI_CARGO_HELICOPTER self --- @param Wrapper.Unit#UNIT Helicopter +-- @param Wrapper.Group#GROUP Helicopter function AI_CARGO_HELICOPTER:onafterUnboard( Helicopter, From, Event, To ) if Helicopter and Helicopter:IsAlive() then @@ -399,7 +400,7 @@ function AI_CARGO_HELICOPTER:onafterUnboard( Helicopter, From, Event, To ) end --- @param #AI_CARGO_HELICOPTER self --- @param Wrapper.Unit#UNIT Helicopter +-- @param Wrapper.Group#GROUP Helicopter function AI_CARGO_HELICOPTER:onafterUnloaded( Helicopter, From, Event, To ) if Helicopter and Helicopter:IsAlive() then diff --git a/Moose Development/Moose/Cargo/Cargo.lua b/Moose Development/Moose/Cargo/Cargo.lua index 446d58da4..6c2bbe033 100644 --- a/Moose Development/Moose/Cargo/Cargo.lua +++ b/Moose Development/Moose/Cargo/Cargo.lua @@ -566,14 +566,14 @@ do -- CARGO --- Check if Cargo is in the LoadRadius for the Cargo to be Boarded or Loaded. -- @param #CARGO self - -- @param Core.Point#Coordinate Coordinate + -- @param Core.Point#COORDINATE Coordinate -- @return #boolean true if the CargoGroup is within the loading radius. function CARGO:IsInLoadRadius( Coordinate ) self:F( { Coordinate, LoadRadius = self.LoadRadius } ) local Distance = 0 if self:IsUnLoaded() then - Distance = Coordinate:DistanceFromPointVec2( self.CargoObject:GetPointVec2() ) + Distance = Coordinate:Get2DDistance( self.CargoObject:GetCoordinate() ) self:T( Distance ) if Distance <= self.LoadRadius then return true @@ -586,14 +586,14 @@ do -- CARGO --- Check if the Cargo can report itself to be Boarded or Loaded. -- @param #CARGO self - -- @param Core.Point#Coordinate Coordinate + -- @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() ) + Distance = Coordinate:Get2DDistance( self.CargoObject:GetCoordinate() ) self:T( Distance ) if Distance <= self.LoadRadius then return true @@ -606,18 +606,18 @@ do -- CARGO --- Check if CargoCarrier is near the Cargo to be Loaded. -- @param #CARGO self - -- @param Core.Point#POINT_VEC2 PointVec2 + -- @param Core.Point#COORDINATE Coordinate -- @param #number NearRadius The radius when the cargo will board the Carrier (to avoid collision). -- @return #boolean - function CARGO:IsNear( PointVec2, NearRadius ) + function CARGO:IsNear( Coordinate, NearRadius ) --self:F( { PointVec2 = PointVec2, NearRadius = NearRadius } ) if self.CargoObject:IsAlive() then - --local Distance = PointVec2:DistanceFromPointVec2( self.CargoObject:GetPointVec2() ) + --local Distance = PointVec2:Get2DDistance( 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() ) + local Distance = Coordinate:Get2DDistance( self.CargoObject:GetCoordinate() ) --self:F( Distance ) if Distance <= NearRadius then @@ -979,9 +979,9 @@ end function CARGO_PACKAGE:IsNear( CargoCarrier ) self:F() - local CargoCarrierPoint = CargoCarrier:GetPointVec2() + local CargoCarrierPoint = CargoCarrier:GetCoordinate() - local Distance = CargoCarrierPoint:DistanceFromPointVec2( self.CargoCarrier:GetPointVec2() ) + local Distance = CargoCarrierPoint:Get2DDistance( self.CargoCarrier:GetCoordinate() ) self:T( Distance ) if Distance <= self.NearRadius then diff --git a/Moose Development/Moose/Cargo/CargoCrate.lua b/Moose Development/Moose/Cargo/CargoCrate.lua index 18c49a4db..7fc3a7293 100644 --- a/Moose Development/Moose/Cargo/CargoCrate.lua +++ b/Moose Development/Moose/Cargo/CargoCrate.lua @@ -166,14 +166,14 @@ do -- CARGO_CRATE --- Check if Cargo Crate is in the radius for the Cargo to be reported. -- @param #CARGO self - -- @param Core.Point#Coordinate Coordinate + -- @param Core.Point#COORDINATE Coordinate -- @return #boolean true if the Cargo Crate is within the report radius. function CARGO_CRATE:IsInReportRadius( Coordinate ) --self:F( { Coordinate, LoadRadius = self.LoadRadius } ) local Distance = 0 if self:IsUnLoaded() then - Distance = Coordinate:DistanceFromPointVec2( self.CargoObject:GetPointVec2() ) + Distance = Coordinate:Get2DDistance( self.CargoObject:GetCoordinate() ) --self:T( Distance ) if Distance <= self.LoadRadius then return true @@ -193,7 +193,7 @@ do -- CARGO_CRATE local Distance = 0 if self:IsUnLoaded() then - Distance = Coordinate:DistanceFromPointVec2( self.CargoObject:GetPointVec2() ) + Distance = Coordinate:Get2DDistance( self.CargoObject:GetCoordinate() ) --self:T( Distance ) if Distance <= self.NearRadius then return true diff --git a/Moose Development/Moose/Cargo/CargoGroup.lua b/Moose Development/Moose/Cargo/CargoGroup.lua index ab7addf54..d71c81a16 100644 --- a/Moose Development/Moose/Cargo/CargoGroup.lua +++ b/Moose Development/Moose/Cargo/CargoGroup.lua @@ -58,8 +58,9 @@ do -- CARGO_GROUP local WeightGroup = 0 - self.GroupName = CargoGroup:GetName() - self.CargoTemplate = UTILS.DeepCopy( _DATABASE:GetGroupTemplate( self.GroupName ) ) + local GroupName = CargoGroup:GetName() + local CargoName = GroupName:match("(.*)~CARGO") or GroupName + self.CargoTemplate = UTILS.DeepCopy( _DATABASE:GetGroupTemplate( GroupName ) ) CargoGroup:Destroy() @@ -67,11 +68,11 @@ do -- CARGO_GROUP for UnitID, UnitTemplate in pairs( self.CargoTemplate.units ) do local GroupTemplate = UTILS.DeepCopy( self.CargoTemplate ) - local GroupName = env.getValueDictByKey( GroupTemplate.name ) + --local GroupName = env.getValueDictByKey( GroupTemplate.name ) -- We create a new group object with one unit... -- First we prepare the template... - GroupTemplate.name = GroupName .. "#CARGO#" .. UnitID + GroupTemplate.name = CargoName .. "#CARGO#" .. UnitID GroupTemplate.groupId = nil GroupTemplate.units = {} GroupTemplate.units[1] = UnitTemplate @@ -442,7 +443,7 @@ do -- CARGO_GROUP --- Check if Cargo Group is in the radius for the Cargo to be Boarded. -- @param #CARGO_GROUP self - -- @param Core.Point#Coordinate Coordinate + -- @param Core.Point#COORDINATE Coordinate -- @return #boolean true if the Cargo Group is within the load radius. function CARGO_GROUP:IsInLoadRadius( Coordinate ) --self:F( { Coordinate } ) @@ -452,12 +453,12 @@ do -- CARGO_GROUP if Cargo then local Distance = 0 if Cargo:IsLoaded() then - Distance = Coordinate:DistanceFromPointVec2( Cargo.CargoCarrier:GetPointVec2() ) + Distance = Coordinate:Get2DDistance( Cargo.CargoCarrier:GetCoordinate() ) else - Distance = Coordinate:DistanceFromPointVec2( Cargo.CargoObject:GetPointVec2() ) + Distance = Coordinate:Get2DDistance( Cargo.CargoObject:GetCoordinate() ) end - --self:T( Distance ) + self:F( { Distance = Distance, LoadRadius = self.LoadRadius } ) if Distance <= self.LoadRadius then return true else @@ -480,9 +481,10 @@ do -- CARGO_GROUP local Cargo = self.CargoSet:GetFirst() -- #CARGO if Cargo then + self:F( { Cargo } ) local Distance = 0 if Cargo:IsUnLoaded() then - Distance = Coordinate:DistanceFromPointVec2( Cargo.CargoObject:GetPointVec2() ) + Distance = Coordinate:Get2DDistance( Cargo.CargoObject:GetCoordinate() ) --self:T( Distance ) if Distance <= self.LoadRadius then return true diff --git a/Moose Development/Moose/Cargo/CargoSlingload.lua b/Moose Development/Moose/Cargo/CargoSlingload.lua index 642fde94f..cb7898175 100644 --- a/Moose Development/Moose/Cargo/CargoSlingload.lua +++ b/Moose Development/Moose/Cargo/CargoSlingload.lua @@ -119,14 +119,14 @@ do -- CARGO_SLINGLOAD --- Check if Cargo Crate is in the radius for the Cargo to be reported. -- @param #CARGO_SLINGLOAD self - -- @param Core.Point#Coordinate Coordinate + -- @param Core.Point#COORDINATE Coordinate -- @return #boolean true if the Cargo Crate is within the report radius. function CARGO_SLINGLOAD:IsInReportRadius( Coordinate ) --self:F( { Coordinate, LoadRadius = self.LoadRadius } ) local Distance = 0 if self:IsUnLoaded() then - Distance = Coordinate:DistanceFromPointVec2( self.CargoObject:GetPointVec2() ) + Distance = Coordinate:Get2DDistance( self.CargoObject:GetCoordinate() ) if Distance <= self.LoadRadius then return true end @@ -138,14 +138,14 @@ do -- CARGO_SLINGLOAD --- 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 + -- @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() ) + Distance = Coordinate:Get2DDistance( self.CargoObject:GetCoordinate() ) if Distance <= self.NearRadius then return true end diff --git a/Moose Development/Moose/Cargo/CargoUnit.lua b/Moose Development/Moose/Cargo/CargoUnit.lua index 318852cb1..d28d113a7 100644 --- a/Moose Development/Moose/Cargo/CargoUnit.lua +++ b/Moose Development/Moose/Cargo/CargoUnit.lua @@ -49,7 +49,7 @@ do -- CARGO_UNIT -- @return #CARGO_UNIT function CARGO_UNIT:New( CargoUnit, Type, Name, Weight, NearRadius ) local self = BASE:Inherit( self, CARGO_REPRESENTABLE:New( CargoUnit, Type, Name, Weight, NearRadius ) ) -- #CARGO_UNIT - self:F( { Type, Name, Weight, NearRadius } ) + self:I( { Type, Name, Weight, NearRadius } ) self:T( CargoUnit ) self.CargoObject = CargoUnit diff --git a/Moose Development/Moose/Core/Database.lua b/Moose Development/Moose/Core/Database.lua index 262175514..6173a355b 100644 --- a/Moose Development/Moose/Core/Database.lua +++ b/Moose Development/Moose/Core/Database.lua @@ -284,7 +284,7 @@ do -- cargo TemplateName = env.getValueDictByKey( TemplateName ) - local Cargo = TemplateName:match( "#(CARGO)" ) + local Cargo = TemplateName:match( "~(CARGO)" ) return Cargo and Cargo == "CARGO" end @@ -293,6 +293,7 @@ do -- cargo -- @param #DATABASE self -- @return #DATABASE self function DATABASE:RegisterCargos() + for CargoGroupName, CargoGroup in pairs( self.GROUPS ) do if self:IsCargo( CargoGroupName ) then @@ -300,11 +301,12 @@ do -- cargo local CargoParam = CargoInfo and CargoInfo:match( "%((.*)%)") local CargoName = CargoGroupName:match("(.*)~CARGO") local Type = CargoParam and CargoParam:match( "T=([%a%d ]+),?") - local Name = CargoParam and CargoParam:match( "N=([%a%d]+),?") - local LoadRadius = CargoParam and CargoParam:match( "RR=([%a%d]+),?") - local NearRadius = CargoParam and CargoParam:match( "NR=([%a%d]+),?") + local Name = CargoParam and CargoParam:match( "N=([%a%d]+),?") or CargoName + local LoadRadius = CargoParam and tonumber( CargoParam:match( "RR=([%a%d]+),?") ) + local NearRadius = CargoParam and tonumber( CargoParam:match( "NR=([%a%d]+),?") ) - CARGO_GROUP:New( CargoGroup, Type, Name or CargoName, LoadRadius, NearRadius ) + self:F({"Register CargoGroup:",Type=Type,Name=Name,LoadRadius=LoadRadius,NearRadius=NearRadius}) + CARGO_GROUP:New( CargoGroup, Type, Name, LoadRadius, NearRadius ) end end @@ -315,15 +317,17 @@ do -- cargo local CargoName = CargoStaticName:match("(.*)~CARGO") local Type = CargoParam and CargoParam:match( "T=([%a%d ]+),?") local Category = CargoParam and CargoParam:match( "C=([%a%d ]+),?") - local Name = CargoParam and CargoParam:match( "N=([%a%d]+),?") + local Name = CargoParam and CargoParam:match( "N=([%a%d]+),?") or CargoName local LoadRadius = CargoParam and tonumber( CargoParam:match( "RR=([%a%d]+),?") ) local NearRadius = CargoParam and tonumber( CargoParam:match( "NR=([%a%d]+),?") ) if Category == "SLING" then - CARGO_SLINGLOAD:New( CargoStatic, Type, Name or CargoName, LoadRadius, NearRadius ) + self:F({"Register CargoSlingload:",Type=Type,Name=Name,LoadRadius=LoadRadius,NearRadius=NearRadius}) + CARGO_SLINGLOAD:New( CargoStatic, Type, Name, LoadRadius, NearRadius ) else if Category == "CRATE" then - CARGO_CRATE:New( CargoStatic, Type, Name or CargoName, LoadRadius, NearRadius ) + self:F({"Register CargoCrate:",Type=Type,Name=Name,LoadRadius=LoadRadius,NearRadius=NearRadius}) + CARGO_CRATE:New( CargoStatic, Type, Name, LoadRadius, NearRadius ) end end end diff --git a/Moose Development/Moose/Core/Point.lua b/Moose Development/Moose/Core/Point.lua index de1a81cfc..15d9cf436 100644 --- a/Moose Development/Moose/Core/Point.lua +++ b/Moose Development/Moose/Core/Point.lua @@ -274,21 +274,19 @@ do -- COORDINATE - --TODO: check this to replace - --- Calculate the distance from a reference @{DCSTypes#Vec2}. + --- Calculate the distance from a reference @{#COORDINATE}. -- @param #COORDINATE self - -- @param Dcs.DCSTypes#Vec2 Vec2Reference The reference @{DCSTypes#Vec2}. - -- @return Dcs.DCSTypes#Distance The distance from the reference @{DCSTypes#Vec2} in meters. - function COORDINATE:DistanceFromVec2( Vec2Reference ) - self:F2( Vec2Reference ) + -- @param #COORDINATE PointVec2Reference The reference @{#COORDINATE}. + -- @return Dcs.DCSTypes#Distance The distance from the reference @{#COORDINATE} in meters. + function COORDINATE:DistanceFromPointVec2( PointVec2Reference ) + self:F2( PointVec2Reference ) - local Distance = ( ( Vec2Reference.x - self.x ) ^ 2 + ( Vec2Reference.y - self.z ) ^2 ) ^0.5 + local Distance = ( ( PointVec2Reference.x - self.x ) ^ 2 + ( PointVec2Reference.z - self.z ) ^2 ) ^ 0.5 self:T2( Distance ) return Distance end - --- Add a Distance in meters from the COORDINATE orthonormal plane, with the given angle, and calculate the new COORDINATE. -- @param #COORDINATE self -- @param Dcs.DCSTypes#Distance Distance The Distance to be added in meters. diff --git a/Moose Development/Moose/Wrapper/Controllable.lua b/Moose Development/Moose/Wrapper/Controllable.lua index 0b68255c5..c63a94af8 100644 --- a/Moose Development/Moose/Wrapper/Controllable.lua +++ b/Moose Development/Moose/Wrapper/Controllable.lua @@ -1761,351 +1761,354 @@ function CONTROLLABLE:TaskRoute( Points ) return DCSTask end ---- (AIR + GROUND) Make the Controllable move to fly to a given point. --- @param #CONTROLLABLE self --- @param Dcs.DCSTypes#Vec3 Point The destination point in Vec3 format. --- @param #number Speed The speed to travel. --- @return #CONTROLLABLE self -function CONTROLLABLE:RouteToVec2( Point, Speed ) - self:F2( { Point, Speed } ) +do -- Route methods - local ControllablePoint = self:GetUnit( 1 ):GetVec2() - - local PointFrom = {} - PointFrom.x = ControllablePoint.x - PointFrom.y = ControllablePoint.y - PointFrom.type = "Turning Point" - PointFrom.action = "Turning Point" - PointFrom.speed = Speed - PointFrom.speed_locked = true - PointFrom.properties = { - ["vnav"] = 1, - ["scale"] = 0, - ["angle"] = 0, - ["vangle"] = 0, - ["steer"] = 2, - } - - - local PointTo = {} - PointTo.x = Point.x - PointTo.y = Point.y - PointTo.type = "Turning Point" - PointTo.action = "Fly Over Point" - PointTo.speed = Speed - PointTo.speed_locked = true - PointTo.properties = { - ["vnav"] = 1, - ["scale"] = 0, - ["angle"] = 0, - ["vangle"] = 0, - ["steer"] = 2, - } - - - local Points = { PointFrom, PointTo } - - self:T3( Points ) - - self:Route( Points ) - - return self -end - ---- (AIR + GROUND) Make the Controllable move to a given point. --- @param #CONTROLLABLE self --- @param Dcs.DCSTypes#Vec3 Point The destination point in Vec3 format. --- @param #number Speed The speed to travel. --- @return #CONTROLLABLE self -function CONTROLLABLE:RouteToVec3( Point, Speed ) - self:F2( { Point, Speed } ) - - local ControllableVec3 = self:GetUnit( 1 ):GetVec3() - - local PointFrom = {} - PointFrom.x = ControllableVec3.x - PointFrom.y = ControllableVec3.z - PointFrom.alt = ControllableVec3.y - PointFrom.alt_type = "BARO" - PointFrom.type = "Turning Point" - PointFrom.action = "Turning Point" - PointFrom.speed = Speed - PointFrom.speed_locked = true - PointFrom.properties = { - ["vnav"] = 1, - ["scale"] = 0, - ["angle"] = 0, - ["vangle"] = 0, - ["steer"] = 2, - } - - - local PointTo = {} - PointTo.x = Point.x - PointTo.y = Point.z - PointTo.alt = Point.y - PointTo.alt_type = "BARO" - PointTo.type = "Turning Point" - PointTo.action = "Fly Over Point" - PointTo.speed = Speed - PointTo.speed_locked = true - PointTo.properties = { - ["vnav"] = 1, - ["scale"] = 0, - ["angle"] = 0, - ["vangle"] = 0, - ["steer"] = 2, - } - - - local Points = { PointFrom, PointTo } - - self:T3( Points ) - - self:Route( Points ) - - return self -end - - - ---- Make the controllable to follow a given route. --- @param #CONTROLLABLE self --- @param #table Route A table of Route Points. --- @param #number DelaySeconds Wait for the specified seconds before executing the Route. --- @return #CONTROLLABLE The CONTROLLABLE. -function CONTROLLABLE:Route( Route, DelaySeconds ) - self:F2( Route ) - - local DCSControllable = self:GetDCSObject() - if DCSControllable then - local RouteTask = self:TaskRoute( Route ) -- Create a RouteTask, that will route the CONTROLLABLE to the Route. - self:SetTask( RouteTask, DelaySeconds or 1 ) -- Execute the RouteTask after the specified seconds (default is 1). - return self - end - - return nil -end - - ---- Stops the movement of the vehicle on the route. --- @param #CONTROLLABLE self --- @return #CONTROLLABLE -function CONTROLLABLE:RouteStop() - self:F("RouteStop") + --- (AIR + GROUND) Make the Controllable move to fly to a given point. + -- @param #CONTROLLABLE self + -- @param Dcs.DCSTypes#Vec3 Point The destination point in Vec3 format. + -- @param #number Speed The speed to travel. + -- @return #CONTROLLABLE self + function CONTROLLABLE:RouteToVec2( Point, Speed ) + self:F2( { Point, Speed } ) - local CommandStop = self:CommandStopRoute( true ) - self:SetCommand( CommandStop ) - -end - ---- Resumes the movement of the vehicle on the route. --- @param #CONTROLLABLE self --- @return #CONTROLLABLE -function CONTROLLABLE:RouteResume() - self:F("RouteResume") + local ControllablePoint = self:GetUnit( 1 ):GetVec2() - local CommandResume = self:CommandStopRoute( false ) - self:SetCommand( CommandResume ) - -end - ---- Make the GROUND Controllable to drive towards a specific point. --- @param #CONTROLLABLE self --- @param Core.Point#COORDINATE ToCoordinate A Coordinate to drive to. --- @param #number Speed (optional) Speed in km/h. The default speed is 999 km/h. --- @param #string Formation (optional) The route point Formation, which is a text string that specifies exactly the Text in the Type of the route point, like "Vee", "Echelon Right". --- @param #number DelaySeconds Wait for the specified seconds before executing the Route. --- @return #CONTROLLABLE The CONTROLLABLE. -function CONTROLLABLE:RouteGroundTo( ToCoordinate, Speed, Formation, DelaySeconds ) - - local FromCoordinate = self:GetCoordinate() - - local FromWP = FromCoordinate:WaypointGround() - local ToWP = ToCoordinate:WaypointGround( Speed, Formation ) - - self:Route( { FromWP, ToWP }, DelaySeconds ) - - return self -end - ---- Make the GROUND Controllable to drive towards a specific point using (only) roads. --- @param #CONTROLLABLE self --- @param Core.Point#COORDINATE ToCoordinate A Coordinate to drive to. --- @param #number Speed (optional) Speed in km/h. The default speed is 999 km/h. --- @param #number DelaySeconds Wait for the specified seconds before executing the Route. --- @return #CONTROLLABLE The CONTROLLABLE. -function CONTROLLABLE:RouteGroundOnRoad( ToCoordinate, Speed, DelaySeconds ) - - -- Current coordinate. - local FromCoordinate = self:GetCoordinate() - - -- Formation is set to on road. - local Formation="On Road" - - -- Path on road from current position to destination coordinate. - local path=FromCoordinate:GetPathOnRoad(ToCoordinate) - - -- Route, ground waypoints along roads. - local route={} - table.insert(route, FromCoordinate:WaypointGround(Speed, Formation)) - - -- Convert coordinates to ground waypoints and insert into table. - for _, coord in ipairs(path) do - table.insert(route, coord:WaypointGround(Speed, Formation)) - end - - -- Add the final coordinate because the final coordinate in path is last point on road. - local dist=ToCoordinate:Get2DDistance(path[#path]) - if dist>10 then - table.insert(route, ToCoordinate:WaypointGround(Speed, "Vee")) - end - - -- Route controllable to destination. - self:Route(route, DelaySeconds) - - return self -end - - ---- Make the AIR Controllable fly towards a specific point. --- @param #CONTROLLABLE self --- @param Core.Point#COORDINATE ToCoordinate A Coordinate to drive to. --- @param Core.Point#COORDINATE.RoutePointAltType AltType The altitude type. --- @param Core.Point#COORDINATE.RoutePointType Type The route point type. --- @param Core.Point#COORDINATE.RoutePointAction Action The route point action. --- @param #number Speed (optional) Speed in km/h. The default speed is 999 km/h. --- @param #number DelaySeconds Wait for the specified seconds before executing the Route. --- @return #CONTROLLABLE The CONTROLLABLE. -function CONTROLLABLE:RouteAirTo( ToCoordinate, AltType, Type, Action, Speed, DelaySeconds ) - - local FromCoordinate = self:GetCoordinate() - local FromWP = FromCoordinate:WaypointAir() - - local ToWP = ToCoordinate:WaypointAir( AltType, Type, Action, Speed ) - - self:Route( { FromWP, ToWP }, DelaySeconds ) - - return self -end - - ---- (AIR + GROUND) Route the controllable to a given zone. --- The controllable final destination point can be randomized. --- A speed can be given in km/h. --- A given formation can be given. --- @param #CONTROLLABLE self --- @param Core.Zone#ZONE Zone The zone where to route to. --- @param #boolean Randomize Defines whether to target point gets randomized within the Zone. --- @param #number Speed The speed. --- @param Base#FORMATION Formation The formation string. -function CONTROLLABLE:TaskRouteToZone( Zone, Randomize, Speed, Formation ) - self:F2( Zone ) - - local DCSControllable = self:GetDCSObject() - - if DCSControllable then - - local ControllablePoint = self:GetVec2() - local PointFrom = {} PointFrom.x = ControllablePoint.x PointFrom.y = ControllablePoint.y PointFrom.type = "Turning Point" - PointFrom.action = Formation or "Cone" - PointFrom.speed = 20 / 1.6 - - + PointFrom.action = "Turning Point" + PointFrom.speed = Speed + PointFrom.speed_locked = true + PointFrom.properties = { + ["vnav"] = 1, + ["scale"] = 0, + ["angle"] = 0, + ["vangle"] = 0, + ["steer"] = 2, + } + + local PointTo = {} - local ZonePoint - - if Randomize then - ZonePoint = Zone:GetRandomVec2() - else - ZonePoint = Zone:GetVec2() - end - - PointTo.x = ZonePoint.x - PointTo.y = ZonePoint.y + PointTo.x = Point.x + PointTo.y = Point.y PointTo.type = "Turning Point" - - if Formation then - PointTo.action = Formation - else - PointTo.action = "Cone" - end - - if Speed then - PointTo.speed = Speed - else - PointTo.speed = 20 / 1.6 - end - + PointTo.action = "Fly Over Point" + PointTo.speed = Speed + PointTo.speed_locked = true + PointTo.properties = { + ["vnav"] = 1, + ["scale"] = 0, + ["angle"] = 0, + ["vangle"] = 0, + ["steer"] = 2, + } + + local Points = { PointFrom, PointTo } - + self:T3( Points ) - + self:Route( Points ) - + return self end - - return nil -end - ---- (GROUND) Route the controllable to a given Vec2. --- A speed can be given in km/h. --- A given formation can be given. --- @param #CONTROLLABLE self --- @param #Vec2 Vec2 The Vec2 where to route to. --- @param #number Speed The speed. --- @param Base#FORMATION Formation The formation string. -function CONTROLLABLE:TaskRouteToVec2( Vec2, Speed, Formation ) - - local DCSControllable = self:GetDCSObject() - - if DCSControllable then - - local ControllablePoint = self:GetVec2() - + + --- (AIR + GROUND) Make the Controllable move to a given point. + -- @param #CONTROLLABLE self + -- @param Dcs.DCSTypes#Vec3 Point The destination point in Vec3 format. + -- @param #number Speed The speed to travel. + -- @return #CONTROLLABLE self + function CONTROLLABLE:RouteToVec3( Point, Speed ) + self:F2( { Point, Speed } ) + + local ControllableVec3 = self:GetUnit( 1 ):GetVec3() + local PointFrom = {} - PointFrom.x = ControllablePoint.x - PointFrom.y = ControllablePoint.y + PointFrom.x = ControllableVec3.x + PointFrom.y = ControllableVec3.z + PointFrom.alt = ControllableVec3.y + PointFrom.alt_type = "BARO" PointFrom.type = "Turning Point" - PointFrom.action = Formation or "Cone" - PointFrom.speed = 20 / 1.6 - - + PointFrom.action = "Turning Point" + PointFrom.speed = Speed + PointFrom.speed_locked = true + PointFrom.properties = { + ["vnav"] = 1, + ["scale"] = 0, + ["angle"] = 0, + ["vangle"] = 0, + ["steer"] = 2, + } + + local PointTo = {} - - PointTo.x = Vec2.x - PointTo.y = Vec2.y + PointTo.x = Point.x + PointTo.y = Point.z + PointTo.alt = Point.y + PointTo.alt_type = "BARO" PointTo.type = "Turning Point" - - if Formation then - PointTo.action = Formation - else - PointTo.action = "Cone" - end - - if Speed then - PointTo.speed = Speed - else - PointTo.speed = 60 / 3.6 - end - + PointTo.action = "Fly Over Point" + PointTo.speed = Speed + PointTo.speed_locked = true + PointTo.properties = { + ["vnav"] = 1, + ["scale"] = 0, + ["angle"] = 0, + ["vangle"] = 0, + ["steer"] = 2, + } + + local Points = { PointFrom, PointTo } - + self:T3( Points ) - + self:Route( Points ) - + return self end + + + + --- Make the controllable to follow a given route. + -- @param #CONTROLLABLE self + -- @param #table Route A table of Route Points. + -- @param #number DelaySeconds Wait for the specified seconds before executing the Route. + -- @return #CONTROLLABLE The CONTROLLABLE. + function CONTROLLABLE:Route( Route, DelaySeconds ) + self:F2( Route ) + + local DCSControllable = self:GetDCSObject() + if DCSControllable then + local RouteTask = self:TaskRoute( Route ) -- Create a RouteTask, that will route the CONTROLLABLE to the Route. + self:SetTask( RouteTask, DelaySeconds or 1 ) -- Execute the RouteTask after the specified seconds (default is 1). + return self + end + + return nil + end + + + --- Stops the movement of the vehicle on the route. + -- @param #CONTROLLABLE self + -- @return #CONTROLLABLE + function CONTROLLABLE:RouteStop() + self:F("RouteStop") + + local CommandStop = self:CommandStopRoute( true ) + self:SetCommand( CommandStop ) + + end + + --- Resumes the movement of the vehicle on the route. + -- @param #CONTROLLABLE self + -- @return #CONTROLLABLE + function CONTROLLABLE:RouteResume() + self:F("RouteResume") + + local CommandResume = self:CommandStopRoute( false ) + self:SetCommand( CommandResume ) + + end + + --- Make the GROUND Controllable to drive towards a specific point. + -- @param #CONTROLLABLE self + -- @param Core.Point#COORDINATE ToCoordinate A Coordinate to drive to. + -- @param #number Speed (optional) Speed in km/h. The default speed is 999 km/h. + -- @param #string Formation (optional) The route point Formation, which is a text string that specifies exactly the Text in the Type of the route point, like "Vee", "Echelon Right". + -- @param #number DelaySeconds Wait for the specified seconds before executing the Route. + -- @return #CONTROLLABLE The CONTROLLABLE. + function CONTROLLABLE:RouteGroundTo( ToCoordinate, Speed, Formation, DelaySeconds ) + + local FromCoordinate = self:GetCoordinate() + + local FromWP = FromCoordinate:WaypointGround() + local ToWP = ToCoordinate:WaypointGround( Speed, Formation ) + + self:Route( { FromWP, ToWP }, DelaySeconds ) + + return self + end + + --- Make the GROUND Controllable to drive towards a specific point using (only) roads. + -- @param #CONTROLLABLE self + -- @param Core.Point#COORDINATE ToCoordinate A Coordinate to drive to. + -- @param #number Speed (optional) Speed in km/h. The default speed is 999 km/h. + -- @param #number DelaySeconds Wait for the specified seconds before executing the Route. + -- @return #CONTROLLABLE The CONTROLLABLE. + function CONTROLLABLE:RouteGroundOnRoad( ToCoordinate, Speed, DelaySeconds ) + + -- Current coordinate. + local FromCoordinate = self:GetCoordinate() + + -- Formation is set to on road. + local Formation="On Road" + + -- Path on road from current position to destination coordinate. + local path=FromCoordinate:GetPathOnRoad(ToCoordinate) + + -- Route, ground waypoints along roads. + local route={} + table.insert(route, FromCoordinate:WaypointGround(Speed, Formation)) + + -- Convert coordinates to ground waypoints and insert into table. + for _, coord in ipairs(path) do + table.insert(route, coord:WaypointGround(Speed, Formation)) + end + + -- Add the final coordinate because the final coordinate in path is last point on road. + local dist=ToCoordinate:Get2DDistance(path[#path]) + if dist>10 then + table.insert(route, ToCoordinate:WaypointGround(Speed, "Vee")) + end + + -- Route controllable to destination. + self:Route(route, DelaySeconds) + + return self + end + + + --- Make the AIR Controllable fly towards a specific point. + -- @param #CONTROLLABLE self + -- @param Core.Point#COORDINATE ToCoordinate A Coordinate to drive to. + -- @param Core.Point#COORDINATE.RoutePointAltType AltType The altitude type. + -- @param Core.Point#COORDINATE.RoutePointType Type The route point type. + -- @param Core.Point#COORDINATE.RoutePointAction Action The route point action. + -- @param #number Speed (optional) Speed in km/h. The default speed is 999 km/h. + -- @param #number DelaySeconds Wait for the specified seconds before executing the Route. + -- @return #CONTROLLABLE The CONTROLLABLE. + function CONTROLLABLE:RouteAirTo( ToCoordinate, AltType, Type, Action, Speed, DelaySeconds ) + + local FromCoordinate = self:GetCoordinate() + local FromWP = FromCoordinate:WaypointAir() + + local ToWP = ToCoordinate:WaypointAir( AltType, Type, Action, Speed ) + + self:Route( { FromWP, ToWP }, DelaySeconds ) + + return self + end + + + --- (AIR + GROUND) Route the controllable to a given zone. + -- The controllable final destination point can be randomized. + -- A speed can be given in km/h. + -- A given formation can be given. + -- @param #CONTROLLABLE self + -- @param Core.Zone#ZONE Zone The zone where to route to. + -- @param #boolean Randomize Defines whether to target point gets randomized within the Zone. + -- @param #number Speed The speed. + -- @param Base#FORMATION Formation The formation string. + function CONTROLLABLE:TaskRouteToZone( Zone, Randomize, Speed, Formation ) + self:F2( Zone ) + + local DCSControllable = self:GetDCSObject() + + if DCSControllable then + + local ControllablePoint = self:GetVec2() + + local PointFrom = {} + PointFrom.x = ControllablePoint.x + PointFrom.y = ControllablePoint.y + PointFrom.type = "Turning Point" + PointFrom.action = Formation or "Cone" + PointFrom.speed = 20 / 1.6 + + + local PointTo = {} + local ZonePoint + + if Randomize then + ZonePoint = Zone:GetRandomVec2() + else + ZonePoint = Zone:GetVec2() + end + + PointTo.x = ZonePoint.x + PointTo.y = ZonePoint.y + PointTo.type = "Turning Point" + + if Formation then + PointTo.action = Formation + else + PointTo.action = "Cone" + end + + if Speed then + PointTo.speed = Speed + else + PointTo.speed = 20 / 1.6 + end + + local Points = { PointFrom, PointTo } + + self:T3( Points ) + + self:Route( Points ) + + return self + end + + return nil + end + + --- (GROUND) Route the controllable to a given Vec2. + -- A speed can be given in km/h. + -- A given formation can be given. + -- @param #CONTROLLABLE self + -- @param #Vec2 Vec2 The Vec2 where to route to. + -- @param #number Speed The speed. + -- @param Base#FORMATION Formation The formation string. + function CONTROLLABLE:TaskRouteToVec2( Vec2, Speed, Formation ) + + local DCSControllable = self:GetDCSObject() + + if DCSControllable then + + local ControllablePoint = self:GetVec2() + + local PointFrom = {} + PointFrom.x = ControllablePoint.x + PointFrom.y = ControllablePoint.y + PointFrom.type = "Turning Point" + PointFrom.action = Formation or "Cone" + PointFrom.speed = 20 / 1.6 + + + local PointTo = {} + + PointTo.x = Vec2.x + PointTo.y = Vec2.y + PointTo.type = "Turning Point" + + if Formation then + PointTo.action = Formation + else + PointTo.action = "Cone" + end + + if Speed then + PointTo.speed = Speed + else + PointTo.speed = 60 / 3.6 + end + + local Points = { PointFrom, PointTo } + + self:T3( Points ) + + self:Route( Points ) + + return self + end + + return nil + end - return nil -end - +end -- Route methods -- Commands