diff --git a/Moose Development/Moose/Core/Zone.lua b/Moose Development/Moose/Core/Zone.lua index 653011b04..81d37269c 100644 --- a/Moose Development/Moose/Core/Zone.lua +++ b/Moose Development/Moose/Core/Zone.lua @@ -1600,6 +1600,7 @@ end -- ## Draw zone -- -- * @{#ZONE_POLYGON_BASE.DrawZone}(): Draws the zone on the F10 map. +-- * @{#ZONE_POLYGON_BASE.Boundary}(): Draw a frontier on the F10 map with small filled circles. -- -- -- @field #ZONE_POLYGON_BASE @@ -2051,6 +2052,45 @@ function ZONE_POLYGON_BASE:GetBoundingSquare() return { x1 = x1, y1 = y1, x2 = x2, y2 = y2 } end +--- Draw a frontier on the F10 map with small filled circles. +-- @param #ZONE_POLYGON_BASE self +-- @param #number Coalition (Optional) Coalition: All=-1, Neutral=0, Red=1, Blue=2. Default -1= All. +-- @param #table Color (Optional) RGB color table {r, g, b}, e.g. {1, 0, 0} for red. Default {1, 1, 1}= White. +-- @param #number Radius (Optional) Radius of the circles in meters. Default 1000. +-- @param #number Alpha (Optional) Alpha transparency [0,1]. Default 1. +-- @param #number Segments (Optional) Number of segments within boundary line. Default 10. +-- @param #boolean Closed (Optional) Link the last point with the first one to obtain a closed boundary. Default false +-- @return #ZONE_POLYGON_BASE self +function ZONE_POLYGON_BASE:Boundary(Coalition, Color, Radius, Alpha, Segments, Closed) + Coalition = Coalition or -1 + Color = Color or {1, 1, 1} + Radius = Radius or 1000 + Alpha = Alpha or 1 + Segments = Segments or 10 + Closed = Closed or false + local i = 1 + local j = #self._.Polygon + if (Closed) then + Limit = #self._.Polygon + 1 + else + Limit = #self._.Polygon + end + while i <= #self._.Polygon do + self:T( { i, j, self._.Polygon[i], self._.Polygon[j] } ) + if j ~= Limit then + local DeltaX = self._.Polygon[j].x - self._.Polygon[i].x + local DeltaY = self._.Polygon[j].y - self._.Polygon[i].y + for Segment = 0, Segments do + local PointX = self._.Polygon[i].x + ( Segment * DeltaX / Segments ) + local PointY = self._.Polygon[i].y + ( Segment * DeltaY / Segments ) + ZONE_RADIUS:New( "Zone", {x = PointX, y = PointY}, Radius ):DrawZone(Coalition, Color, 1, Color, Alpha, nil, true) + end + end + j = i + i = i + 1 + end + return self +end --- @type ZONE_POLYGON -- @extends #ZONE_POLYGON_BASE diff --git a/Moose Development/Moose/Wrapper/Controllable.lua b/Moose Development/Moose/Wrapper/Controllable.lua index 165835229..01e3867ba 100644 --- a/Moose Development/Moose/Wrapper/Controllable.lua +++ b/Moose Development/Moose/Wrapper/Controllable.lua @@ -1832,7 +1832,7 @@ end do -- Patrol methods - --- (GROUND) Patrol iteratively using the waypoints the for the (parent) group. + --- (GROUND) Patrol iteratively using the waypoints of the (parent) group. -- @param #CONTROLLABLE self -- @return #CONTROLLABLE function CONTROLLABLE:PatrolRoute() @@ -1851,8 +1851,27 @@ do -- Patrol methods -- Calculate the new Route. local FromCoord = PatrolGroup:GetCoordinate() - local From = FromCoord:WaypointGround( 120 ) - + + -- test for submarine + local depth = 0 + local IsSub = false + if PatrolGroup:IsShip() then + local navalvec3 = FromCoord:GetVec3() + if navalvec3.y < 0 then + depth = navalvec3.y + IsSub = true + end + end + + + local Waypoint = Waypoints[1] + local Speed = Waypoint.speed or (20 / 3.6) + local From = FromCoord:WaypointGround( Speed ) + + if IsSub then + From = FromCoord:WaypointNaval( Speed, Waypoint.alt ) + end + table.insert( Waypoints, 1, From ) local TaskRoute = PatrolGroup:TaskFunction( "CONTROLLABLE.PatrolRoute" ) @@ -1892,7 +1911,16 @@ do -- Patrol methods if ToWaypoint then FromWaypoint = ToWaypoint end - + -- test for submarine + local depth = 0 + local IsSub = false + if PatrolGroup:IsShip() then + local navalvec3 = FromCoord:GetVec3() + if navalvec3.y < 0 then + depth = navalvec3.y + IsSub = true + end + end -- Loop until a waypoint has been found that is not the same as the current waypoint. -- Otherwise the object zon't move or drive in circles and the algorithm would not do exactly -- what it is supposed to do, which is making groups drive around. @@ -1907,9 +1935,13 @@ do -- Patrol methods local ToCoord = COORDINATE:NewFromVec2( { x = Waypoint.x, y = Waypoint.y } ) -- 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( Speed, Formation ) - Route[#Route+1] = ToCoord:WaypointGround( Speed, Formation ) - + if IsSub then + Route[#Route+1] = FromCoord:WaypointNaval( Speed, depth ) + Route[#Route+1] = ToCoord:WaypointNaval( Speed, Waypoint.alt ) + else + Route[#Route+1] = FromCoord:WaypointGround( Speed, Formation ) + Route[#Route+1] = ToCoord:WaypointGround( Speed, Formation ) + end local TaskRouteToZone = PatrolGroup:TaskFunction( "CONTROLLABLE.PatrolRouteRandom", Speed, Formation, ToWaypoint ) @@ -1950,9 +1982,20 @@ do -- Patrol methods self:F( { PatrolGroup = PatrolGroup:GetName() } ) if PatrolGroup:IsGround() or PatrolGroup:IsShip() then - + -- Calculate the new Route. local FromCoord = PatrolGroup:GetCoordinate() + + -- test for submarine + local depth = 0 + local IsSub = false + if PatrolGroup:IsShip() then + local navalvec3 = FromCoord:GetVec3() + if navalvec3.y < 0 then + depth = navalvec3.y + IsSub = true + end + end -- Select a random Zone and get the Coordinate of the new Zone. local RandomZone = ZoneList[ math.random( 1, #ZoneList ) ] -- Core.Zone#ZONE @@ -1960,9 +2003,13 @@ do -- Patrol methods -- 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( Speed, Formation ) - Route[#Route+1] = ToCoord:WaypointGround( Speed, Formation ) - + if IsSub then + Route[#Route+1] = FromCoord:WaypointNaval( Speed, depth ) + Route[#Route+1] = ToCoord:WaypointNaval( Speed, depth ) + else + Route[#Route+1] = FromCoord:WaypointGround( Speed, Formation ) + Route[#Route+1] = ToCoord:WaypointGround( Speed, Formation ) + end local TaskRouteToZone = PatrolGroup:TaskFunction( "CONTROLLABLE.PatrolZones", ZoneList, Speed, Formation, DelayMin, DelayMax ) @@ -3770,10 +3817,30 @@ function CONTROLLABLE:OptionDisperseOnAttack(Seconds) local Controller = self:_GetController() if Controller then if self:IsGround() then - self:SetOption(AI.Option.GROUND.id.DISPERSE_ON_ATTACK, seconds) + self:SetOption(AI.Option.Ground.id.DISPERSE_ON_ATTACK, seconds) end end return self end return nil end + +--- Returns if the unit is a submarine. +-- @param #POSITIONABLE self +-- @return #boolean Submarines attributes result. +function POSITIONABLE:IsSubmarine() + self:F2() + + local DCSUnit = self:GetDCSObject() + + if DCSUnit then + local UnitDescriptor = DCSUnit:getDesc() + if UnitDescriptor.attributes["Submarines"] == true then + return true + else + return false + end + end + + return nil +end diff --git a/Moose Development/Moose/Wrapper/Positionable.lua b/Moose Development/Moose/Wrapper/Positionable.lua index 22dc87e33..86843e1c1 100644 --- a/Moose Development/Moose/Wrapper/Positionable.lua +++ b/Moose Development/Moose/Wrapper/Positionable.lua @@ -684,6 +684,27 @@ function POSITIONABLE:IsShip() end +--- Returns if the unit is a submarine. +-- @param #POSITIONABLE self +-- @return #boolean Submarines attributes result. +function POSITIONABLE:IsSubmarine() + self:F2() + + local DCSUnit = self:GetDCSObject() + + if DCSUnit then + local UnitDescriptor = DCSUnit:getDesc() + if UnitDescriptor.attributes["Submarines"] == true then + return true + else + return false + end + end + + return nil +end + + --- Returns true if the POSITIONABLE is in the air. -- Polymorphic, is overridden in GROUP and UNIT. -- @param Wrapper.Positionable#POSITIONABLE self @@ -817,8 +838,7 @@ end -- @return #number The velocity in knots. function POSITIONABLE:GetVelocityKNOTS() self:F2( self.PositionableName ) - local velmps=self:GetVelocityMPS() - return UTILS.MpsToKnots(velmps) + return UTILS.MpsToKnots(self:GetVelocityMPS()) end --- Returns the Angle of Attack of a positionable.