diff --git a/Moose Development/Moose/Core/Zone.lua b/Moose Development/Moose/Core/Zone.lua index aa061a94f..19f3cbc12 100644 --- a/Moose Development/Moose/Core/Zone.lua +++ b/Moose Development/Moose/Core/Zone.lua @@ -645,6 +645,22 @@ function ZONE_RADIUS:GetRandomPointVec3( inner, outer ) end +--- Returns a @{Point#COORDINATE} object reflecting a random 3D location within the zone. +-- @param #ZONE_RADIUS self +-- @param #number inner (optional) Minimal distance from the center of the zone. Default is 0. +-- @param #number outer (optional) Maximal distance from the outer edge of the zone. Default is the radius of the zone. +-- @return Core.Point#COORDINATE +function ZONE_RADIUS:GetRandomCoordinate( inner, outer ) + self:F( self.ZoneName, inner, outer ) + + local Coordinate = COORDINATE:NewFromVec2( self:GetRandomVec2() ) + + self:T3( { Coordinate = Coordinate } ) + + return Coordinate +end + + --- @type ZONE -- @extends #ZONE_RADIUS @@ -1091,6 +1107,20 @@ function ZONE_POLYGON_BASE:GetRandomPointVec3() end +--- Return a @{Point#COORDINATE} object representing a random 3D point at landheight within the zone. +-- @param #ZONE_POLYGON_BASE self +-- @return Core.Point#COORDINATE +function ZONE_POLYGON_BASE:GetRandomCoordinate() + self:F2() + + local Coordinate = COORDINATE:NewFromVec2( self:GetRandomVec2() ) + + self:T2( Coordinate ) + + return Coordinate +end + + --- Get the bounding square the zone. -- @param #ZONE_POLYGON_BASE self -- @return #ZONE_POLYGON_BASE.BoundingSquare The bounding square. diff --git a/Moose Development/Moose/Wrapper/Controllable.lua b/Moose Development/Moose/Wrapper/Controllable.lua index bc15ea795..7047d5342 100644 --- a/Moose Development/Moose/Wrapper/Controllable.lua +++ b/Moose Development/Moose/Wrapper/Controllable.lua @@ -107,7 +107,7 @@ -- ### Tasks at Waypoints -- -- Special Task methods are available to set tasks at certain waypoints. --- The method @{#CONTROLLABLE.SetTaskAtWaypoint}() helps preparing a Route, embedding a Task at the Waypoint of the Route. +-- The method @{#CONTROLLABLE.SetTaskWaypoint}() helps preparing a Route, embedding a Task at the Waypoint of the Route. -- -- This creates a Task element, with an action to call a function as part of a Wrapped Task. -- @@ -1540,7 +1540,7 @@ function CONTROLLABLE:TaskEmbarkToTransport( Point, Radius ) end --- This creates a Task element, with an action to call a function as part of a Wrapped Task. --- This Task can then be embedded at a Waypoint by calling the method @{#CONTROLLABLE.SetTaskAtWaypoint}. +-- This Task can then be embedded at a Waypoint by calling the method @{#CONTROLLABLE.SetTaskWaypoint}. -- @param #CONTROLLABLE self -- @param #string FunctionString The function name embedded as a string that will be called. -- @param ... The variable arguments passed to the function when called! These arguments can be of any type! @@ -1579,7 +1579,7 @@ end -- -- local TaskRouteToZone = Vehicle:TaskFunction( "RouteToZone", RandomZone ) -- --- Vehicle:SetTaskAtWaypoint( Route, #Route, TaskRouteToZone ) -- Set for the given Route at Waypoint 2 the TaskRouteToZone. +-- Vehicle:SetTaskWaypoint( Route, #Route, TaskRouteToZone ) -- Set for the given Route at Waypoint 2 the TaskRouteToZone. -- -- Vehicle:Route( Route, math.random( 10, 20 ) ) -- Move after a random seconds to the Route. See the Route method for details. -- @@ -1633,6 +1633,130 @@ function CONTROLLABLE:TaskMission( TaskMission ) return DCSTask end + +do -- Patrol methods + + --- (GROUND) Patrol iteratively using the waypoints the for the (parent) group. + -- @param #CONTROLLABLE self + -- @return #CONTROLLABLE + function CONTROLLABLE:PatrolRoute() + + local PatrolGroup = self -- Wrapper.Group#GROUP + + if not self:IsInstanceOf( "GROUP" ) then + PatrolGroup = self:GetGroup() -- Wrapper.Group#GROUP + end + + self:E( { PatrolGroup = PatrolGroup:GetName() } ) + + if PatrolGroup:IsGround() then + + local Waypoints = PatrolGroup:GetTemplateRoutePoints() + + -- Calculate the new Route. + local FromCoord = PatrolGroup:GetCoordinate() + local From = FromCoord:WaypointGround( 120 ) + + table.insert( Waypoints, 1, From ) + + local TaskRoute = PatrolGroup:TaskFunction( "CONTROLLABLE.PatrolRoute" ) + + self:E({Waypoints = Waypoints}) + local Waypoint = Waypoints[#Waypoints] + PatrolGroup:SetTaskWaypoint( Waypoint, TaskRoute ) -- Set for the given Route at Waypoint 2 the TaskRouteToZone. + + PatrolGroup:Route( Waypoints ) -- Move after a random seconds to the Route. See the Route method for details. + end + end + + --- (GROUND) Patrol randomly to the waypoints the for the (parent) group. + -- A random waypoint will be picked and the group will move towards that point. + -- @param #CONTROLLABLE self + -- @return #CONTROLLABLE + function CONTROLLABLE:PatrolRouteRandom( Speed, Formation ) + + local PatrolGroup = self -- Wrapper.Group#GROUP + + if not self:IsInstanceOf( "GROUP" ) then + PatrolGroup = self:GetGroup() -- Wrapper.Group#GROUP + end + + self:E( { PatrolGroup = PatrolGroup:GetName() } ) + + if PatrolGroup:IsGround() then + + local Waypoints = PatrolGroup:GetTemplateRoutePoints() + local WaypointNumber = math.random( 1, #Waypoints ) + self:E( { WaypointNumber = WaypointNumber } ) + local Waypoint = Waypoints[WaypointNumber] -- Select random waypoint. + + -- Calculate the new Route. + local FromCoord = PatrolGroup:GetCoordinate() + + -- Select a random Zone and get the Coordinate of the new Zone. + local ToCoord = COORDINATE:NewFromVec2( { x = Waypoint.x + 10, y = Waypoint.y + 10 } ) + + -- Create a "ground route point", which is a "point" structure that can be given as a parameter to a Task + local Route = {} + Route[#Route+1] = FromCoord:WaypointGround( 0 ) + Route[#Route+1] = ToCoord:WaypointGround( Speed, Formation ) + + + local TaskRouteToZone = PatrolGroup:TaskFunction( "CONTROLLABLE.PatrolRouteRandom", Speed, Formation ) + + PatrolGroup:SetTaskWaypoint( Route[#Route], TaskRouteToZone ) -- Set for the given Route at Waypoint 2 the TaskRouteToZone. + + PatrolGroup:Route( Route, 2 ) -- Move after a random seconds to the Route. See the Route method for details. + end + end + + --- (GROUND) Patrol randomly to the waypoints the for the (parent) group. + -- A random waypoint will be picked and the group will move towards that point. + -- @param #CONTROLLABLE self + -- @return #CONTROLLABLE + function CONTROLLABLE:PatrolZones( ZoneList, Speed, Formation ) + + if not type( ZoneList ) == "table" then + ZoneList = { ZoneList } + end + + local PatrolGroup = self -- Wrapper.Group#GROUP + + if not self:IsInstanceOf( "GROUP" ) then + PatrolGroup = self:GetGroup() -- Wrapper.Group#GROUP + end + + self:E( { PatrolGroup = PatrolGroup:GetName() } ) + + if PatrolGroup:IsGround() then + + local Waypoints = PatrolGroup:GetTemplateRoutePoints() + local Waypoint = Waypoints[math.random( 1, #Waypoints )] -- Select random waypoint. + + -- Calculate the new Route. + local FromCoord = PatrolGroup:GetCoordinate() + + -- Select a random Zone and get the Coordinate of the new Zone. + local RandomZone = ZoneList[ math.random( 1, #ZoneList ) ] -- Core.Zone#ZONE + local ToCoord = RandomZone:GetRandomCoordinate( 10 ) + + -- Create a "ground route point", which is a "point" structure that can be given as a parameter to a Task + local Route = {} + Route[#Route+1] = FromCoord:WaypointGround( 120 ) + Route[#Route+1] = ToCoord:WaypointGround( Speed, Formation ) + + + local TaskRouteToZone = PatrolGroup:TaskFunction( "CONTROLLABLE.PatrolZones", ZoneList, Speed, Formation ) + + PatrolGroup:SetTaskWaypoint( Route[#Route], TaskRouteToZone ) -- Set for the given Route at Waypoint 2 the TaskRouteToZone. + + PatrolGroup:Route( Route, 2 ) -- Move after a random seconds to the Route. See the Route method for details. + end + end + +end + + --- Return a Misson task to follow a given route defined by Points. -- @param #CONTROLLABLE self -- @param #table Points A table of route points. diff --git a/Moose Development/Moose/Wrapper/Group.lua b/Moose Development/Moose/Wrapper/Group.lua index 1089224be..5c2f85f7c 100644 --- a/Moose Development/Moose/Wrapper/Group.lua +++ b/Moose Development/Moose/Wrapper/Group.lua @@ -938,10 +938,19 @@ end -- @return #table function GROUP:GetTemplate() local GroupName = self:GetName() - self:E( GroupName ) return _DATABASE:GetGroupTemplate( GroupName ) end +--- Returns the group template route.points[] (the waypoints) from the @{DATABASE} (_DATABASE object). +-- @param #GROUP self +-- @return #table +function GROUP:GetTemplateRoutePoints() + local GroupName = self:GetName() + return _DATABASE:GetGroupTemplate( GroupName ).route.points +end + + + --- Sets the controlled status in a Template. -- @param #GROUP self -- @param #boolean Controlled true is controlled, false is uncontrolled.