First test mission with ZONE_POLYGON working!

This commit is contained in:
FlightControl
2016-06-05 00:03:27 +02:00
parent 2ac9e76f5c
commit d8790ad2f1
10 changed files with 1188 additions and 34729 deletions

View File

@@ -1,8 +0,0 @@
Include.File( "Group" )
Include.File( "Unit" )
local UnitAirPlaneAI = _DATABASE:FindUnit( "Airplane AI" )
UnitAirPlaneAI:FlareRed()

View File

@@ -526,6 +526,24 @@ end
-- Is Functions
--- Returns if all units of the group are within a @{Zone#ZONE}.
-- @param #GROUP self
-- @param Zone#ZONE_BASE Zone The zone to test.
-- @return #boolean Returns true if the Group is completely within the @{Zone#ZONE}
function GROUP:IsCompletelyInZone( Zone )
self:F2( { self.GroupName, Zone } )
for UnitID, UnitData in pairs( self:GetUnits() ) do
local Unit = UnitData -- Unit#UNIT
if Zone:IsPointVec3InZone( Unit:GetPointVec3() ) then
else
return false
end
end
return true
end
--- Returns if the group is of an air category.
-- If the group is a helicopter or a plane, then this method will return true, otherwise false.
-- @param #GROUP self
@@ -2488,7 +2506,7 @@ end
--- Returns a message for a coalition or a client.
-- @param #GROUP self
-- @param #string Message The message text
-- @param #Duration Duration The duration of the message.
-- @param DCSTypes#Duration Duration The duration of the message.
-- @return Message#MESSAGE
function GROUP:Message( Message, Duration )
self:F2( { Message, Duration } )
@@ -2505,7 +2523,7 @@ end
-- The message will appear in the message area. The message will begin with the callsign of the group and the type of the first unit sending the message.
-- @param #GROUP self
-- @param #string Message The message text
-- @param #Duration Duration The duration of the message.
-- @param DCSTypes#Duration Duration The duration of the message.
function GROUP:MessageToAll( Message, Duration )
self:F2( { Message, Duration } )
@@ -2521,7 +2539,7 @@ end
-- The message will appear in the message area. The message will begin with the callsign of the group and the type of the first unit sending the message.
-- @param #GROUP self
-- @param #string Message The message text
-- @param #Duration Duration The duration of the message.
-- @param DCSTYpes#Duration Duration The duration of the message.
function GROUP:MessageToRed( Message, Duration )
self:F2( { Message, Duration } )
@@ -2537,7 +2555,7 @@ end
-- The message will appear in the message area. The message will begin with the callsign of the group and the type of the first unit sending the message.
-- @param #GROUP self
-- @param #string Message The message text
-- @param #Duration Duration The duration of the message.
-- @param DCSTypes#Duration Duration The duration of the message.
function GROUP:MessageToBlue( Message, Duration )
self:F2( { Message, Duration } )
@@ -2553,7 +2571,7 @@ end
-- The message will appear in the message area. The message will begin with the callsign of the group and the type of the first unit sending the message.
-- @param #GROUP self
-- @param #string Message The message text
-- @param #Duration Duration The duration of the message.
-- @param DCSTypes#Duration Duration The duration of the message.
-- @param Client#CLIENT Client The client object receiving the message.
function GROUP:MessageToClient( Message, Duration, Client )
self:F2( { Message, Duration } )

View File

@@ -121,7 +121,7 @@ function SCHEDULER:_Scheduler()
self:T( { Status, Result } )
if Status and Status == true and Result and Result == true then
if Status and ( ( not Result ) or ( Result and Result ~= false ) ) then
if self.Repeat and ( not self.StopSeconds or ( self.StopSeconds and timer.getTime() <= self.StartTime + self.StopSeconds ) ) then
timer.scheduleFunction(
self._Scheduler,

View File

@@ -1,79 +1,346 @@
--- ZONE Classes
-- =============
-- This module contains the ZONE classes, inherited from @{Zone#ZONE_BASE}.
-- There are essentially two core functions that zones accomodate:
--
-- * Test if an object is within the zone boundaries.
-- * Provide the zone behaviour. Some zones are static, while others are moveable.
--
-- The object classes are using the zone classes to test the zone boundaries, which can take various forms:
--
-- * Test if completely within the zone.
-- * Test if partly within the zone (for @{Group#GROUP} objects).
-- * Test if not in the zone.
-- * Distance to the nearest intersecting point of the zone.
-- * Distance to the center of the zone.
-- * ...
--
-- Each of these ZONE classes have a zone name, and specific parameters defining the zone type:
--
-- * @{Zone#ZONE_BASE}: The ZONE_BASE class defining the base for all other zone classes.
-- * @{Zone#ZONE_RADIUS}: The ZONE_RADIUS class defined by a zone name, a location and a radius.
-- * @{Zone#ZONE}: The ZONE class, defined by the zone name as defined within the Mission Editor.
-- * @{Zone#ZONE_UNIT}: The ZONE_UNIT class defined by a zone around a @{Unit#UNIT} with a radius.
-- * @{Zone#ZONE_POLYGON}: The ZONE_POLYGON class defined by a sequence of @{Group#GROUP} waypoints within the Mission Editor, forming a polygon.
--
-- Polymorphic methods
-- ===================
-- Each zone implements two polymorphic functions defined in @{Zone#ZONE_BASE}:
--
-- * @{#ZONE_BASE.IsPointVec2InZone}: Returns if a location is within the zone.
-- * @{#ZONE_BASE.IsPointVec3InZone}: Returns if a point is within the zone.
--
-- @module Zone
-- @author FlightControl
Include.File( "Routines" )
Include.File( "Base" )
Include.File( "Message" )
--- The ZONE class
-- @type ZONE
-- @Extends Base#BASE
ZONE = {
ClassName="ZONE",
}
function ZONE:New( ZoneName )
local self = BASE:Inherit( self, BASE:New() )
self:F( ZoneName )
local Zone = trigger.misc.getZone( ZoneName )
if not Zone then
error( "Zone " .. ZoneName .. " does not exist." )
return nil
end
self.Zone = Zone
self.ZoneName = ZoneName
--- The ZONE_BASE class
-- @type ZONE_BASE
-- @Extends Base#BASE
ZONE_BASE = {
ClassName = "ZONE_BASE",
}
function ZONE_BASE:New( ZoneName )
local self = BASE:Inherit( self, BASE:New() )
self:F( ZoneName )
self.ZoneName = ZoneName
return self
end
--- Returns if a location is within the zone.
-- @param #ZONE_RADIUS self
-- @param DCSTypes#Vec2 PointVec2 The location to test.
-- @return #boolean true if the location is within the zone.
function ZONE_BASE:IsPointVec2InZone( PointVec2 )
self:F2( PointVec2 )
return false
end
--- Returns if a point is within the zone.
-- @param #ZONE_RADIUS self
-- @param DCSTypes#Vec3 PointVec3 The point to test.
-- @return #boolean true if the point is within the zone.
function ZONE_BASE:IsPointVec3InZone( PointVec3 )
self:F2( PointVec3 )
local InZone = self:IsPointVec2InZone( { x = PointVec3.x, y = PointVec3.z } )
return InZone
end
--- The ZONE_RADIUS class, defined by a zone name, a location and a radius.
-- @type ZONE_RADIUS
-- @field DCSTypes#Vec2 PointVec2 The current location of the zone.
-- @field DCSTypes#Distance Radius The radius of the zone.
-- @Extends Zone#ZONE_BASE
ZONE_RADIUS = {
ClassName="ZONE_RADIUS",
}
--- Constructor of ZONE_RADIUS, taking the zone name, the zone location and a radius.
-- @param #ZONE_RADIUS self
-- @param DCSTypes#Vec2 PointVec2 The location of the zone.
-- @param DCSTypes#Distance Radius The radius of the zone.
-- @return #ZONE_RADIUS
function ZONE_RADIUS:New( ZoneName, PointVec2, Radius )
local self = BASE:Inherit( self, ZONE_BASE:New( ZoneName ) )
self:F( { ZoneName, PointVec2, Radius } )
self.Radius = Radius
self.PointVec2 = PointVec2
return self
end
function ZONE:GetPointVec2()
self:F( self.ZoneName )
local Zone = trigger.misc.getZone( self.ZoneName )
local Point = { x = Zone.point.x, y = Zone.point.z }
--- Returns the radius of the zone.
-- @param #ZONE_RADIUS self
-- @return DCSTypes#Distance The radius of the zone.
function ZONE_RADIUS:GetRadius()
self:F2( self.ZoneName )
self:T( { Zone, Point } )
self:T2( { self.Radius } )
return self.Radius
end
--- Sets the radius of the zone.
-- @param #ZONE_RADIUS self
-- @param DCSTypes#Distance Radius The radius of the zone.
-- @return DCSTypes#Distance The radius of the zone.
function ZONE_RADIUS:SetRadius( Radius )
self:F2( self.ZoneName )
self.Radius = Radius
self:T2( { self.Radius } )
return self.Radius
end
--- Returns the location of the zone.
-- @param #ZONE_RADIUS self
-- @return DCSTypes#Vec2 The location of the zone.
function ZONE_RADIUS:GetPointVec2()
self:F2( self.ZoneName )
self:T2( { self.PointVec2 } )
return Point
return self.PointVec2
end
function ZONE:GetPointVec3( Height )
self:F( self.ZoneName )
local Zone = trigger.misc.getZone( self.ZoneName )
local Point = { x = Zone.point.x, y = land.getHeight( self:GetPointVec2() ) + Height, z = Zone.point.z }
self:T( { Zone, Point } )
--- Sets the location of the zone.
-- @param #ZONE_RADIUS self
-- @param DCSTypes#Vec2 PointVec2 The new location of the zone.
-- @return DCSTypes#Vec2 The new location of the zone.
function ZONE_RADIUS:SetPointVec2( PointVec2 )
self:F2( self.ZoneName )
return Point
self.PointVec2 = PointVec2
self:T2( { self.PointVec2 } )
return self.PointVec2
end
function ZONE:GetRandomPointVec2()
--- Returns the point of the zone.
-- @param #ZONE_RADIUS self
-- @param DCSTypes#Distance Height The height to add to the land height where the center of the zone is located.
-- @return DCSTypes#Vec3 The point of the zone.
function ZONE_RADIUS:GetPointVec3( Height )
self:F2( self.ZoneName )
local PointVec2 = self:GetPointVec2()
local PointVec3 = { x = PointVec2.x, y = land.getHeight( self:GetPointVec2() ) + Height, z = PointVec2.y }
self:T2( { PointVec3 } )
return PointVec3
end
--- Returns if a location is within the zone.
-- @param #ZONE_RADIUS self
-- @param DCSTypes#Vec2 PointVec2 The location to test.
-- @return #boolean true if the location is within the zone.
function ZONE_RADIUS:IsPointVec2InZone( PointVec2 )
self:F2( PointVec2 )
if (( PointVec2.x - self.PointVec2.x )^2 + ( PointVec2.y - self.PointVec2.y ) ^2 ) ^ 0.5 <= self.Radius then
return true
end
return false
end
--- Returns if a point is within the zone.
-- @param #ZONE_RADIUS self
-- @param DCSTypes#Vec3 PointVec3 The point to test.
-- @return #boolean true if the point is within the zone.
function ZONE_RADIUS:IsPointVec3InZone( PointVec3 )
self:F2( PointVec3 )
local InZone = self:IsPointVec3InZone( { x = PointVec3.x, y = PointVec3.z } )
return InZone
end
--- Returns a random location within the zone.
-- @param #ZONE_RADIUS self
-- @return DCSTypes#Vec2 The random location within the zone.
function ZONE_RADIUS:GetRandomPointVec2()
self:F( self.ZoneName )
local Point = {}
local Zone = trigger.misc.getZone( self.ZoneName )
local angle = math.random() * math.pi*2;
Point.x = Zone.point.x + math.cos( angle ) * math.random() * Zone.radius;
Point.y = Zone.point.z + math.sin( angle ) * math.random() * Zone.radius;
Point.x = self.PointVec2.x + math.cos( angle ) * math.random() * self.Radius;
Point.y = self.PointVec2.y + math.sin( angle ) * math.random() * self.Radius;
self:T( { Zone, Point } )
self:T( { Point } )
return Point
end
function ZONE:GetRadius()
self:F( self.ZoneName )
local Zone = trigger.misc.getZone( self.ZoneName )
self:T( { Zone } )
--- The ZONE class, defined by the zone name as defined within the Mission Editor. The location and the radius are automatically collected from the mission settings.
-- @type ZONE
-- @Extends Zone#ZONE_RADIUS
ZONE = {
ClassName="ZONE",
}
return Zone.radius
--- Constructor of ZONE, taking the zone name.
-- @param #ZONE self
-- @param #string ZoneName The name of the zone as defined within the mission editor.
-- @return #ZONE
function ZONE:New( ZoneName )
local Zone = trigger.misc.getZone( ZoneName )
if not Zone then
error( "Zone " .. ZoneName .. " does not exist." )
return nil
end
local self = BASE:Inherit( self, ZONE_RADIUS:New( ZoneName, { x = Zone.x, y = Zone.y }, Zone.radius ) )
self:F( ZoneName )
self.Zone = Zone
return self
end
--- The ZONE_UNIT class defined by a zone around a @{Unit#UNIT} with a radius.
-- @type ZONE_UNIT
-- @field Unit#UNIT ZoneUNIT
-- @Extends Zone#ZONE_RADIUS
ZONE_UNIT = {
ClassName="ZONE_UNIT",
}
--- Constructor to create a ZONE_UNIT instance, taking the zone name, a zone unit and a radius.
-- @param #ZONE_UNIT self
-- @param #string ZoneName Name of the zone.
-- @param Unit#UNIT ZoneUNIT The unit as the center of the zone.
-- @param DCSTypes#Distance Radius The radius of the zone.
-- @return #ZONE_UNIT self
function ZONE_UNIT:New( ZoneName, ZoneUNIT, Radius )
local self = BASE:Inherit( self, ZONE_RADIUS:New( ZoneName, ZoneUNIT:GetPointVec2(), Radius ) )
self:F( { ZoneName, ZoneUNIT:GetPointVec2(), Radius } )
self.ZoneUNIT = ZoneUNIT
return self
end
--- Returns the current location of the @{Unit#UNIT}.
-- @param #ZONE_UNIT self
-- @return DCSTypes#Vec2 The location of the zone based on the @{Unit#UNIT}location.
function ZONE_UNIT:GetPointVec2()
self:F( self.ZoneName )
local ZonePointVec2 = self.ZoneUNIT:GetPointVec2()
self:T( { ZonePointVec2 } )
return ZonePointVec2
end
--- The ZONE_POLYGON class defined by a sequence of @{Group#GROUP} waypoints within the Mission Editor, forming a polygon.
-- @type ZONE_POLYGON
-- @Extends Zone#ZONE_BASE
ZONE_POLYGON = {
ClassName="ZONE_POLYGON",
}
--- Constructor to create a ZONE_POLYGON instance, taking the zone name and the name of the @{Group#GROUP} defined within the Mission Editor.
-- The @{Group#GROUP} waypoints define the polygon corners. The first and the last point are automatically connected by ZONE_POLYGON.
-- @param #ZONE_POLYGON self
-- @param #string ZoneName Name of the zone.
-- @param Group#GROUP ZoneGroup The GROUP waypoints as defined within the Mission Editor define the polygon shape.
-- @return #ZONE_POLYGON self
function ZONE_POLYGON:New( ZoneName, ZoneGroup )
local self = BASE:Inherit( self, ZONE_BASE:New( ZoneName ) )
self:F( { ZoneName, ZoneGroup } )
local GroupPoints = ZoneGroup:GetTaskRoute()
local i = 0
self.Polygon = {}
for i = 1, #GroupPoints do
self.Polygon[i] = {}
self.Polygon[i].x = GroupPoints[i].x
self.Polygon[i].y = GroupPoints[i].y
end
return self
end
--- Returns if a location is within the zone.
-- @param #ZONE_POLYGON self
-- @param DCSTypes#Vec2 PointVec2 The location to test.
-- @return #boolean true if the location is within the zone.
function ZONE_POLYGON:IsPointVec2InZone( PointVec2 )
self:F2( PointVec2 )
local i
local j
local c = false
i = 1
j = #self.Polygon
while i < #self.Polygon do
j = i
i = i + 1
self:T( { i, j, self.Polygon[i], self.Polygon[j] } )
if ( ( ( self.Polygon[i].y > PointVec2.y ) ~= ( self.Polygon[j].y > PointVec2.y ) ) and
( PointVec2.x < ( self.Polygon[j].x - self.Polygon[i].x ) * ( PointVec2.y - self.Polygon[i].y ) / ( self.Polygon[j].y - self.Polygon[i].y ) + self.Polygon[i].x )
) then
c = not c
end
self:T( { "c = ", c } )
end
return c
end