Merge branch 'FF/MasterDevel'

This commit is contained in:
Frank 2023-02-12 11:49:13 +01:00
commit f11dbfa367
7 changed files with 580 additions and 39 deletions

View File

@ -88,6 +88,7 @@ DATABASE = {
WAREHOUSES = {},
FLIGHTGROUPS = {},
FLIGHTCONTROLS = {},
PATHLINES = {},
}
local _DATABASECoalition =
@ -244,7 +245,7 @@ function DATABASE:FindAirbase( AirbaseName )
end
do -- Zones
do -- Zones and Pathlines
--- Finds a @{Core.Zone} based on the zone name.
-- @param #DATABASE self
@ -267,7 +268,6 @@ do -- Zones
end
end
--- Deletes a @{Core.Zone} from the DATABASE based on the zone name.
-- @param #DATABASE self
-- @param #string ZoneName The name of the zone.
@ -277,6 +277,39 @@ do -- Zones
end
--- Adds a @{Core.Pathline} based on its name in the DATABASE.
-- @param #DATABASE self
-- @param #string PathlineName The name of the pathline
-- @param Core.Pathline#PATHLINE Pathline The pathline.
function DATABASE:AddPathline( PathlineName, Pathline )
if not self.PATHLINES[PathlineName] then
self.PATHLINES[PathlineName]=Pathline
end
end
--- Finds a @{Core.Pathline} by its name.
-- @param #DATABASE self
-- @param #string PathlineName The name of the Pathline.
-- @return Core.Pathline#PATHLINE The found PATHLINE.
function DATABASE:FindPathline( PathlineName )
local pathline = self.PATHLINES[PathlineName]
return pathline
end
--- Deletes a @{Core.Pathline} from the DATABASE based on its name.
-- @param #DATABASE self
-- @param #string PathlineName The name of the PATHLINE.
function DATABASE:DeletePathline( PathlineName )
self.PATHLINES[PathlineName]=nil
return self
end
--- Private method that registers new ZONE_BASE derived objects within the DATABASE Object.
-- @param #DATABASE self
-- @return #DATABASE self
@ -370,60 +403,148 @@ do -- Zones
-- Add zone to DB.
self:AddZone( ZoneName, Zone_Polygon )
end
end
-- Drawings as zones
if env.mission.drawings and env.mission.drawings.layers then
-- Loop over layers.
for layerID, layerData in pairs(env.mission.drawings.layers or {}) do
-- Loop over objects in layers.
for objectID, objectData in pairs(layerData.objects or {}) do
-- Check for polygon which has at least 4 points (we would need 3 but the origin seems to be there twice)
if objectData.polygonMode=="free" and objectData.points and #objectData.points>=4 then
if objectData.polygonMode and (objectData.polygonMode=="free") and objectData.points and #objectData.points>=4 then
---
-- Drawing: Polygon free
---
-- Name of the zone.
local ZoneName=objectData.name or "Unknown Drawing Zone"
local ZoneName=objectData.name or "Unknown free Polygon Drawing"
-- Reference point. All other points need to be translated by this.
local vec2={x=objectData.mapX, y=objectData.mapY}
-- Copy points array.
-- Debug stuff.
--local vec3={x=objectData.mapX, y=0, z=objectData.mapY}
--local coord=COORDINATE:NewFromVec2(vec2):MarkToAll("MapX, MapY")
--trigger.action.markToAll(id, "mapXY", vec3)
-- Copy points array.
local points=UTILS.DeepCopy(objectData.points)
-- Translate points.
for i,_point in pairs(points) do
local point=_point --DCS#Vec2
local point=_point --DCS#Vec2
points[i]=UTILS.Vec2Add(point, vec2)
end
end
-- Remove last point.
table.remove(points, #points)
-- Debug output
self:I(string.format("Register ZONE: %s (Polygon drawing with %d verticies)", ZoneName, #points))
self:I(string.format("Register ZONE: %s (Polygon (free) drawing with %d vertices)", ZoneName, #points))
-- Create new polygon zone.
local Zone=ZONE_POLYGON:NewFromPointsArray(ZoneName, points)
-- Set color.
Zone:SetColor({1, 0, 0}, 0.15)
-- Store in DB.
self.ZONENAMES[ZoneName] = ZoneName
-- Add zone.
self:AddZone(ZoneName, Zone)
end
end
self:AddZone(ZoneName, Zone)
-- Check for polygon which has at least 4 points (we would need 3 but the origin seems to be there twice)
elseif objectData.polygonMode and objectData.polygonMode=="rect" then
---
-- Drawing: Polygon rect
---
-- Name of the zone.
local ZoneName=objectData.name or "Unknown rect Polygon Drawing"
-- Reference point (center of the rectangle).
local vec2={x=objectData.mapX, y=objectData.mapY}
-- For a rectangular polygon drawing, we have the width (y) and height (x).
local w=objectData.width
local h=objectData.height
-- Create points from center using with and height (width for y and height for x is a bit confusing, but this is how ED implemented it).
local points={}
points[1]={x=vec2.x-h/2, y=vec2.y+w/2} --Upper left
points[2]={x=vec2.x+h/2, y=vec2.y+w/2} --Upper right
points[3]={x=vec2.x+h/2, y=vec2.y-w/2} --Lower right
points[4]={x=vec2.x-h/2, y=vec2.y-w/2} --Lower left
--local coord=COORDINATE:NewFromVec2(vec2):MarkToAll("MapX, MapY")
-- Debug output
self:I(string.format("Register ZONE: %s (Polygon (rect) drawing with %d vertices)", ZoneName, #points))
-- Create new polygon zone.
local Zone=ZONE_POLYGON:NewFromPointsArray(ZoneName, points)
-- Set color.
Zone:SetColor({1, 0, 0}, 0.15)
-- Store in DB.
self.ZONENAMES[ZoneName] = ZoneName
-- Add zone.
self:AddZone(ZoneName, Zone)
elseif objectData.lineMode and (objectData.lineMode=="segments" or objectData.lineMode=="segment" or objectData.lineMode=="free") and objectData.points and #objectData.points>=2 then
---
-- Drawing: Line (segments, segment or free)
---
-- Name of the zone.
local Name=objectData.name or "Unknown Line Drawing"
-- Reference point. All other points need to be translated by this.
local vec2={x=objectData.mapX, y=objectData.mapY}
-- Copy points array.
local points=UTILS.DeepCopy(objectData.points)
-- Translate points.
for i,_point in pairs(points) do
local point=_point --DCS#Vec2
points[i]=UTILS.Vec2Add(point, vec2)
end
-- Debug output
self:I(string.format("Register PATHLINE: %s (Line drawing with %d points)", Name, #points))
-- Create new polygon zone.
local Pathline=PATHLINE:NewFromVec2Array(Name, points)
-- Set color.
--Zone:SetColor({1, 0, 0}, 0.15)
-- Add zone.
self:AddPathline(Name,Pathline)
end
end
end
end
end
end -- zone
do -- Zone_Goal
@ -1040,7 +1161,7 @@ function DATABASE:_RegisterClients()
for ClientName, ClientTemplate in pairs( self.Templates.ClientsByName ) do
self:I(string.format("Register Client: %s", tostring(ClientName)))
local client=self:AddClient( ClientName )
client.SpawnCoord=COORDINATE:New(ClientTemplate.x, ClientTemplate.alt, ClientTemplate.y)
client.SpawnCoord=COORDINATE:New(ClientTemplate.x, ClientTemplate.alt, ClientTemplate.y)
end
return self
@ -1090,7 +1211,7 @@ end
function DATABASE:_RegisterAirbase(airbase)
if airbase then
-- Get the airbase name.
local DCSAirbaseName = airbase:getName()
@ -1719,7 +1840,7 @@ function DATABASE:_RegisterTemplates()
if obj_type_name ~= "static" and Template and Template.units and type(Template.units) == 'table' then --making sure again- this is a valid group
self:_RegisterGroupTemplate(Template, CoalitionSide, _DATABASECategory[string.lower(CategoryName)], CountryID)
self:_RegisterGroupTemplate(Template, CoalitionSide, _DATABASECategory[string.lower(CategoryName)], CountryID)
else

View File

@ -0,0 +1,370 @@
--- **Core** - Path from A to B.
--
-- **Main Features:**
--
-- * Path from A to B
-- * Arbitrary number of points
-- * Automatically from lines drawtool
--
-- ===
--
-- ### Author: **funkyfranky**
--
-- ===
-- @module Core.Pathline
-- @image CORE_Pathline.png
--- PATHLINE class.
-- @type PATHLINE
-- @field #string ClassName Name of the class.
-- @field #string lid Class id string for output to DCS log file.
-- @field #string name Name of the path line.
-- @field #table points List of 3D points defining the path.
-- @extends Core.Base#BASE
--- *The shortest distance between two points is a straight line.* -- Archimedes
--
-- ===
--
-- # The PATHLINE Concept
--
-- List of points defining a path from A to B. The pathline can consist of multiple points. Each point holds the information of its position, the surface type, the land height
-- and the water depth (if over sea).
--
-- Line drawings created in the mission editor are automatically registered as pathlines and stored in the MOOSE database.
-- They can be accessed with the @{#PATHLINE.FindByName) function.
--
-- # Constructor
--
-- The @{PATHLINE.New) function creates a new PATHLINE object. This does not hold any points. Points can be added with the @{#PATHLINE.AddPointFromVec2} and @{#PATHLINE.AddPointFromVec3}
--
-- For a given table of 2D or 3D positions, a new PATHLINE object can be created with the @{#PATHLINE.NewFromVec2Array} or @{#PATHLINE.NewFromVec3Array}, respectively.
--
-- # Line Drawings
--
-- The most convenient way to create a pathline is the draw panel feature in the DCS mission editor. You can select "Line" and then "Segments", "Segment" or "Free" to draw your lines.
-- These line drawings are then automatically added to the MOOSE database as PATHLINE objects and can be retrieved with the @{#PATHLINE.FindByName) function, where the name is the one
-- you specify in the draw panel.
--
-- # Mark on F10 map
--
-- The ponints of the PATHLINE can be marked on the F10 map with the @{#PATHLINE.MarkPoints}(`true`) function. The mark points contain information of the surface type, land height and
-- water depth.
--
-- To remove the marks, use @{#PATHLINE.MarkPoints}(`false`).
--
-- @field #PATHLINE
PATHLINE = {
ClassName = "PATHLINE",
lid = nil,
points = {},
}
--- Point of line.
-- @type PATHLINE.Point
-- @field DCS#Vec3 vec3 3D position.
-- @field DCS#Vec2 vec2 2D position.
-- @field #number surfaceType Surface type.
-- @field #number landHeight Land height in meters.
-- @field #number depth Water depth in meters.
-- @field #number markerID Marker ID.
--- PATHLINE class version.
-- @field #string version
PATHLINE.version="0.1.0"
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO list
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO: A lot...
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Constructor
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- Create a new PATHLINE object. Points need to be added later.
-- @param #PATHLINE self
-- @param #string Name Name of the path.
-- @return #PATHLINE self
function PATHLINE:New(Name)
-- Inherit everything from INTEL class.
local self=BASE:Inherit(self, BASE:New()) --#PATHLINE
self.name=Name or "Unknown Path"
self.lid=string.format("PATHLINE %s | ", Name)
return self
end
--- Create a new PATHLINE object from a given list of 2D points.
-- @param #PATHLINE self
-- @param #string Name Name of the pathline.
-- @param #table Vec2Array List of DCS#Vec2 points.
-- @return #PATHLINE self
function PATHLINE:NewFromVec2Array(Name, Vec2Array)
local self=PATHLINE:New(Name)
for i=1,#Vec2Array do
self:AddPointFromVec2(Vec2Array[i])
end
return self
end
--- Create a new PATHLINE object from a given list of 3D points.
-- @param #PATHLINE self
-- @param #string Name Name of the pathline.
-- @param #table Vec3Array List of DCS#Vec3 points.
-- @return #PATHLINE self
function PATHLINE:NewFromVec3Array(Name, Vec3Array)
local self=PATHLINE:New(Name)
for i=1,#Vec3Array do
self:AddPointFromVec3(Vec3Array[i])
end
return self
end
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- User functions
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- Find a pathline in the database.
-- @param #PATHLINE self
-- @param #string Name The name of the pathline.
-- @return #PATHLINE self
function PATHLINE:FindByName(Name)
local pathline = _DATABASE:FindPathline(Name)
return pathline
end
--- Add a point to the path from a given 2D position. The third dimension is determined from the land height.
-- @param #PATHLINE self
-- @param DCS#Vec2 Vec2 The 2D vector (x,y) to add.
-- @return #PATHLINE self
function PATHLINE:AddPointFromVec2(Vec2)
if Vec2 then
local point=self:_CreatePoint(Vec2)
table.insert(self.points, point)
end
return self
end
--- Add a point to the path from a given 3D position.
-- @param #PATHLINE self
-- @param DCS#Vec3 Vec3 The 3D vector (x,y) to add.
-- @return #PATHLINE self
function PATHLINE:AddPointFromVec3(Vec3)
if Vec3 then
local point=self:_CreatePoint(Vec3)
table.insert(self.points, point)
end
return self
end
--- Get name of pathline.
-- @param #PATHLINE self
-- @return #string Name of the pathline.
function PATHLINE:GetName()
return self.name
end
--- Get number of points.
-- @param #PATHLINE self
-- @return #number Number of points.
function PATHLINE:GetNumberOfPoints()
local N=#self.points
return N
end
--- Get points of pathline. Not that points are tables, that contain more information as just the 2D or 3D position but also the surface type etc.
-- @param #PATHLINE self
-- @return <#PATHLINE.Point> List of points.
function PATHLINE:GetPoints()
return self.points
end
--- Get 3D points of pathline.
-- @param #PATHLINE self
-- @return <DCS#Vec3> List of DCS#Vec3 points.
function PATHLINE:GetPoints3D()
local vecs={}
for _,_point in pairs(self.points) do
local point=_point --#PATHLINE.Point
table.insert(vecs, point.vec3)
end
return vecs
end
--- Get 2D points of pathline.
-- @param #PATHLINE self
-- @return <DCS#Vec2> List of DCS#Vec2 points.
function PATHLINE:GetPoints2D()
local vecs={}
for _,_point in pairs(self.points) do
local point=_point --#PATHLINE.Point
table.insert(vecs, point.vec2)
end
return vecs
end
--- Get COORDINATES of pathline. Note that COORDINATE objects are created when calling this function. That does involve deep copy calls and can have an impact on performance if done too often.
-- @param #PATHLINE self
-- @return <Core.Point#COORDINATE> List of COORDINATES points.
function PATHLINE:GetCoordinats()
local vecs={}
for _,_point in pairs(self.points) do
local point=_point --#PATHLINE.Point
local coord=COORDINATE:NewFromVec3(point.vec3)
end
return vecs
end
--- Get the n-th point of the pathline.
-- @param #PATHLINE self
-- @param #number n The index of the point. Default is the first point.
-- @return #PATHLINE.Point Point.
function PATHLINE:GetPointFromIndex(n)
local N=self:GetNumberOfPoints()
n=n or 1
local point=nil --#PATHLINE.Point
if n>=1 and n<=N then
point=self.point[n]
else
self:E(self.lid..string.format("ERROR: No point in pathline for N=%s", tostring(n)))
end
return point
end
--- Get the 3D position of the n-th point.
-- @param #PATHLINE self
-- @param #number n The n-th point.
-- @return DCS#VEC3 Position in 3D.
function PATHLINE:GetPoint3DFromIndex(n)
local point=self:GetPointFromIndex(n)
if point then
return point.vec3
end
return nil
end
--- Get the 2D position of the n-th point.
-- @param #PATHLINE self
-- @param #number n The n-th point.
-- @return DCS#VEC2 Position in 3D.
function PATHLINE:GetPoint2DFromIndex(n)
local point=self:GetPointFromIndex(n)
if point then
return point.vec2
end
return nil
end
--- Mark points on F10 map.
-- @param #PATHLINE self
-- @param #boolean Switch If `true` or nil, set marks. If `false`, remove marks.
-- @return <DCS#Vec3> List of DCS#Vec3 points.
function PATHLINE:MarkPoints(Switch)
for i,_point in pairs(self.points) do
local point=_point --#PATHLINE.Point
if Switch==false then
if point.markerID then
UTILS.RemoveMark(point.markerID, Delay)
end
else
if point.markerID then
UTILS.RemoveMark(point.markerID)
end
point.markerID=UTILS.GetMarkID()
local text=string.format("Pathline %s: Point #%d\nSurface Type=%d\nHeight=%.1f m\nDepth=%.1f m", self.name, i, point.surfaceType, point.landHeight, point.depth)
trigger.action.markToAll(point.markerID, text, point.vec3, "")
end
end
end
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Private functions
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- Get 3D points of pathline.
-- @param #PATHLINE self
-- @param DCS#Vec3 Vec Position vector. Can also be a DCS#Vec2 in which case the altitude at landheight is taken.
-- @return #PATHLINE.Point
function PATHLINE:_CreatePoint(Vec)
local point={} --#PATHLINE.Point
if Vec.z then
-- Given vec is 3D
point.vec3=UTILS.DeepCopy(Vec)
point.vec2={x=Vec.x, y=Vec.z}
else
-- Given vec is 2D
point.vec2=UTILS.DeepCopy(Vec)
point.vec3={x=Vec.x, y=land.getHeight(Vec), z=Vec.y}
end
-- Get surface type.
point.surfaceType=land.getSurfaceType(point.vec2)
-- Get land height and depth.
point.landHeight, point.depth=land.getSurfaceHeightWithSeabed(point.vec2)
point.markerID=nil
return point
end
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

View File

@ -193,21 +193,29 @@ do -- land
--- [Type of surface enumerator](https://wiki.hoggitworld.com/view/DCS_singleton_land)
-- @type land.SurfaceType
-- @field LAND
-- @field SHALLOW_WATER
-- @field WATER
-- @field ROAD
-- @field RUNWAY
-- @field LAND Land=1
-- @field SHALLOW_WATER Shallow water=2
-- @field WATER Water=3
-- @field ROAD Road=4
-- @field RUNWAY Runway=5
--- Returns altitude MSL of the point.
--- Returns the distance from sea level (y-axis) of a given vec2 point.
-- @function [parent=#land] getHeight
-- @param #Vec2 point point on the ground.
-- @return #Distance
-- @param #Vec2 point Point on the ground.
-- @return #number Height in meters.
--- Returns the surface height and depth of a point. Useful for checking if the path is deep enough to support a given ship.
-- Both values are positive. When checked over water at sea level the first value is always zero.
-- When checked over water at altitude, for example the reservoir of the Inguri Dam, the first value is the corresponding altitude the water level is at.
-- @function [parent=#land] getSurfaceHeightWithSeabed
-- @param #Vec2 point Position where to check.
-- @return #number Height in meters.
-- @return #number Depth in meters.
--- returns surface type at the given point.
--- Returns surface type at the given point.
-- @function [parent=#land] getSurfaceType
-- @param #Vec2 point Point on the land.
-- @return #land.SurfaceType
-- @return #number Enumerator value from `land.SurfaceType` (LAND=1, SHALLOW_WATER=2, WATER=3, ROAD=4, RUNWAY=5)
--- [DCS Singleton land](https://wiki.hoggitworld.com/view/DCS_singleton_land)
land = {} --#land

View File

@ -33,6 +33,7 @@ __Moose.Include( 'Scripts/Moose/Core/Goal.lua' )
__Moose.Include( 'Scripts/Moose/Core/Spot.lua' )
__Moose.Include( 'Scripts/Moose/Core/MarkerOps_Base.lua' )
__Moose.Include( 'Scripts/Moose/Core/TextAndSound.lua' )
__Moose.Include( 'Scripts/Moose/Core/Pathline.lua' )
__Moose.Include( 'Scripts/Moose/Wrapper/Object.lua' )
__Moose.Include( 'Scripts/Moose/Wrapper/Identifiable.lua' )

View File

@ -10180,6 +10180,28 @@ function AIRBOSS:_GetSternCoord()
return self.sterncoord
end
--- Get wire from draw argument.
-- @param #AIRBOSS self
-- @param Core.Point#COORDINATE Lcoord Landing position.
-- @return #number Trapped wire (1-4) or 99 if no wire was trapped.
function AIRBOSS:_GetWireFromDrawArg()
local wireArgs={}
wireArgs[1]=141
wireArgs[2]=142
wireArgs[3]=143
wireArgs[4]=144
for wire,drawArg in pairs(wireArgs) do
local value=self.carrier:GetDrawArgumentValue(drawArg)
if math.abs(value)>0.001 then
return wire
end
end
return 99
end
--- Get wire from landing position.
-- @param #AIRBOSS self
-- @param Core.Point#COORDINATE Lcoord Landing position.

View File

@ -967,6 +967,24 @@ function UNIT:GetDamageRelative()
return 1
end
--- Returns the current value for an animation argument on the external model of the given object.
-- Each model animation has an id tied to with different values representing different states of the model.
-- Animation arguments can be figured out by opening the respective 3d model in the modelviewer.
-- @param #UNIT self
-- @param #number AnimationArgument Number corresponding to the animated part of the unit.
-- @return #number Value of the animation argument [-1, 1]. If draw argument value is invalid for the unit in question a value of 0 will be returned.
function UNIT:GetDrawArgumentValue(AnimationArgument)
local DCSUnit = self:GetDCSObject()
if DCSUnit then
local value = DCSUnit:getDrawArgumentValue(AnimationArgument or 0)
return value
end
return 0
end
--- Returns the category of the #UNIT from descriptor. Returns one of
--
-- * Unit.Category.AIRPLANE

View File

@ -34,6 +34,7 @@ Core/MarkerOps_Base.lua
Core/Astar.lua
Core/Condition.lua
Core/TextAndSound.lua
Core/Pathline.lua
Wrapper/Object.lua
Wrapper/Identifiable.lua