Merge remote-tracking branch 'origin/master' into develop

This commit is contained in:
Applevangelist 2025-07-23 12:36:01 +02:00
commit edfe91274d
4 changed files with 117 additions and 1 deletions

View File

@ -3797,6 +3797,22 @@ do -- COORDINATE
function COORDINATE:GetRandomPointVec3InRadius( OuterRadius, InnerRadius ) function COORDINATE:GetRandomPointVec3InRadius( OuterRadius, InnerRadius )
return COORDINATE:NewFromVec3( self:GetRandomVec3InRadius( OuterRadius, InnerRadius ) ) return COORDINATE:NewFromVec3( self:GetRandomVec3InRadius( OuterRadius, InnerRadius ) )
end end
--- Search for clear zones in a given area. A powerful and efficient function using Disposition to find clear areas for spawning ground units avoiding trees, water and map scenery.
-- @param #number SearchRadius Radius of the search area.
-- @param #number PosRadius Required clear radius around each position.
-- @param #number NumPositions Number of positions to find.
-- @return #table A table of Core.Point#COORDINATE that are clear of map objects within the given PosRadius.
function COORDINATE:GetSimpleZones(SearchRadius, PosRadius, NumPositions)
local clearPositions = UTILS.GetSimpleZones(self:GetVec3(), SearchRadius, PosRadius, NumPositions)
local coords = {}
for _, pos in ipairs(clearPositions) do
local coord = COORDINATE:NewFromVec2(pos)
table.insert(coords, coord)
end
return coords
end
end end

View File

@ -1509,6 +1509,43 @@ function ZONE_RADIUS:IsVec3InZone( Vec3 )
return InZone return InZone
end end
--- Search for clear ground spawn zones within this zone. A powerful and efficient function using Disposition to find clear areas for spawning ground units avoiding trees, water and map scenery.
-- @param #number PosRadius Required clear radius around each position.
-- @param #number NumPositions Number of positions to find.
-- @return #table A table of DCS#Vec2 positions that are clear of map objects within the given PosRadius. nil if no clear positions are found.
function ZONE_RADIUS:GetClearZonePositions(PosRadius, NumPositions)
local clearPositions = UTILS.GetSimpleZones(self:GetVec3(), self:GetRadius(), PosRadius, NumPositions)
if clearPositions or #clearPositions > 0 then
local validZones = {}
for _, vec2 in pairs(clearPositions) do
if self:IsVec2InZone(vec2) then
table.insert(validZones, vec2)
end
end
if #validZones > 0 then
return validZones
end
end
return nil
end
--- Search for a random clear ground spawn coordinate within this zone. A powerful and efficient function using Disposition to find clear areas for spawning ground units avoiding trees, water and map scenery.
-- @param #number PosRadius (Optional) Required clear radius around each position. (Default is math.min(Radius/10, 200))
-- @param #number NumPositions (Optional) Number of positions to find. (Default 50)
-- @return Core.Point#COORDINATE A random coordinate for a clear zone. nil if no clear positions are found.
-- @return #number Assigned radius for the found zones. nil if no clear positions are found.
function ZONE_RADIUS:GetRandomClearZoneCoordinate(PosRadius, NumPositions)
local radius = PosRadius or math.min(self.Radius/10, 200)
local clearPositions = self:GetClearZonePositions(radius, NumPositions or 50)
if clearPositions or #clearPositions > 0 then
local randomPosition = clearPositions[math.random(1, #clearPositions)]
return COORDINATE:NewFromVec2(randomPosition), radius
end
return nil
end
--- Returns a random Vec2 location within the zone. --- Returns a random Vec2 location within the zone.
-- @param #ZONE_RADIUS self -- @param #ZONE_RADIUS self
-- @param #number inner (Optional) Minimal distance from the center of the zone. Default is 0. -- @param #number inner (Optional) Minimal distance from the center of the zone. Default is 0.

View File

@ -4630,3 +4630,13 @@ function UTILS.DestroyScenery(name, level)
net.dostring_in("mission",string.format("a_scenery_destruction_zone(%d, %d)", z.zoneId, level)) net.dostring_in("mission",string.format("a_scenery_destruction_zone(%d, %d)", z.zoneId, level))
end end
end end
--- Search for clear zones in a given area. A powerful and efficient function using Disposition to find clear areas for spawning ground units avoiding trees, water and map scenery.
-- @param DCS##Vec3 Center position vector for the search area.
-- @param #number SearchRadius Radius of the search area.
-- @param #number PosRadius Required clear radius around each position.
-- @param #number NumPositions Number of positions to find.
-- @return #table A table of DCS#Vec2 positions that are clear of map objects within the given PosRadius.
function UTILS.GetSimpleZones(Vec3, SearchRadius, PosRadius, NumPositions)
return Disposition.getSimpleZones(Vec3, SearchRadius, PosRadius, NumPositions)
end

View File

@ -1467,7 +1467,7 @@ function AIRBASE:Register(AirbaseName)
self.descriptors=self:GetDesc() self.descriptors=self:GetDesc()
-- Debug info. -- Debug info.
--self:I({airbase=AirbaseName, descriptors=self.descriptors}) --self:T({airbase=AirbaseName, descriptors=self.descriptors})
-- Category. -- Category.
self.category=self.descriptors and self.descriptors.category or Airbase.Category.AIRDROME self.category=self.descriptors and self.descriptors.category or Airbase.Category.AIRDROME
@ -2634,6 +2634,7 @@ function AIRBASE:_InitRunways(IncludeInverse)
--runway.name=string.format("%02d", tonumber(name)) --runway.name=string.format("%02d", tonumber(name))
runway.magheading=tonumber(runway.name)*10 runway.magheading=tonumber(runway.name)*10
runway.idx=runway.magheading
runway.heading=heading runway.heading=heading
runway.width=width or 0 runway.width=width or 0
runway.length=length or 0 runway.length=length or 0
@ -2946,6 +2947,7 @@ function AIRBASE:GetRunwayData(magvar, mark)
local runway={} --#AIRBASE.Runway local runway={} --#AIRBASE.Runway
runway.heading=hdg runway.heading=hdg
runway.idx=idx runway.idx=idx
runway.magheading=idx
runway.length=c1:Get2DDistance(c2) runway.length=c1:Get2DDistance(c2)
runway.position=c1 runway.position=c1
runway.endpoint=c2 runway.endpoint=c2
@ -2961,6 +2963,57 @@ function AIRBASE:GetRunwayData(magvar, mark)
-- Add runway. -- Add runway.
table.insert(runways, runway) table.insert(runways, runway)
end
-- Look for identical (parallel) runways, e.g. 03L and 03R at Nellis.
local rpairs={}
for i,_ri in pairs(runways) do
local ri=_ri --#AIRBASE.Runway
for j,_rj in pairs(runways) do
local rj=_rj --#AIRBASE.Runway
if i<j then
if ri.name==rj.name then
rpairs[i]=j
end
end
end
end
local function isLeft(a, b, c)
--return ((b.x - a.x)*(c.z - a.z) - (b.z - a.z)*(c.x - a.x)) > 0
return ((b.z - a.z)*(c.x - a.x) - (b.x - a.x)*(c.z - a.z)) > 0
end
for i,j in pairs(rpairs) do
local ri=runways[i] --#AIRBASE.Runway
local rj=runways[j] --#AIRBASE.Runway
-- Draw arrow.
--ri.center:ArrowToAll(rj.center)
local c0=ri.center
-- Vector in the direction of the runway.
local a=UTILS.VecTranslate(c0, 1000, ri.heading)
-- Vector from runway i to runway j.
local b=UTILS.VecSubstract(rj.center, ri.center)
b=UTILS.VecAdd(ri.center, b)
-- Check if rj is left of ri.
local left=isLeft(c0, a, b)
--env.info(string.format("Found pair %s: i=%d, j=%d, left==%s", ri.name, i, j, tostring(left)))
if left then
ri.isLeft=false
rj.isLeft=true
else
ri.isLeft=true
rj.isLeft=false
end
--break
end end
return runways return runways