#SCENERY, #SET_SCENERY

* Improvements
This commit is contained in:
Applevangelist 2022-10-19 12:37:24 +02:00
parent 0441acf101
commit 7bba5ec69e
4 changed files with 165 additions and 26 deletions

View File

@ -309,7 +309,7 @@ do -- Zones
self:I(string.format("Register ZONE: %s (Polygon, Quad)", ZoneName))
Zone=ZONE_POLYGON_BASE:New(ZoneName, ZoneData.verticies)
Zone=ZONE_POLYGON:NewFromPointsArray(ZoneName, ZoneData.verticies)
--for i,vec2 in pairs(ZoneData.verticies) do
-- local coord=COORDINATE:NewFromVec2(vec2)

View File

@ -6792,20 +6792,36 @@ do -- SET_SCENERY
-- mysceneryset = SET_SCENERY:New(ZoneSet)
function SET_SCENERY:New(ZoneSet)
local zoneset = {}
-- Inherits from BASE
local self = BASE:Inherit( self, SET_BASE:New( zoneset ) ) -- Core.Set#SET_SCENERY
local zonenames = {}
for _,_zone in pairs(ZoneSet.Set) do
table.insert(zonenames,_zone:GetName())
local zoneset = {}
-- Inherits from BASE
local self = BASE:Inherit( self, SET_BASE:New( zoneset ) ) -- Core.Set#SET_SCENERY
local zonenames = {}
if ZoneSet then
for _,_zone in pairs(ZoneSet.Set) do
--self:I("Zone type handed: "..tostring(_zone.ClassName))
table.insert(zonenames,_zone:GetName())
end
self:AddSceneryByName(zonenames)
end
return self
end
self:AddSceneryByName(zonenames)
return self
--- Creates a new SET_SCENERY object. Scenery is **not** auto-registered in the Moose database, there are too many objects on each map. Hence we need to find them first. For this we scan the zone.
-- @param #SET_SCENERY self
-- @param Core.Zone#ZONE Zone The zone to be scanned. Can be a ZONE_RADIUS (round) or a ZONE_POLYGON (e.g. Quad-Point)
-- @return #SET_SCENERY
function SET_SCENERY:NewFromZone(Zone)
local zone = Zone -- Core.Zone#ZONE_POLYGON
if type(Zone) == "string" then
zone = ZONE:FindByName(Zone)
end
zone:Scan({Object.Category.SCENERY})
return zone:GetScannedSetScenery()
end
--- Add SCENERY(s) to SET_SCENERY.
-- @param #SET_SCENERY self
-- @param #string AddScenery A single SCENERY.

View File

@ -934,6 +934,7 @@ function ZONE_RADIUS:Scan( ObjectCategories, UnitCategories )
self.ScanData = {}
self.ScanData.Coalitions = {}
self.ScanData.Scenery = {}
self.ScanData.SceneryTable = {}
self.ScanData.Units = {}
local ZoneCoord = self:GetCoordinate()
@ -996,8 +997,10 @@ function ZONE_RADIUS:Scan( ObjectCategories, UnitCategories )
if ObjectCategory == Object.Category.SCENERY then
local SceneryType = ZoneObject:getTypeName()
local SceneryName = ZoneObject:getName()
--BASE:I("SceneryType "..SceneryType.."SceneryName"..SceneryName)
self.ScanData.Scenery[SceneryType] = self.ScanData.Scenery[SceneryType] or {}
self.ScanData.Scenery[SceneryType][SceneryName] = SCENERY:Register( SceneryName, ZoneObject )
table.insert(self.ScanData.SceneryTable,self.ScanData.Scenery[SceneryType][SceneryName] )
self:T( { SCENERY = self.ScanData.Scenery[SceneryType][SceneryName] } )
end
@ -1137,11 +1140,29 @@ end
--- Get scanned scenery table
-- @param #ZONE_RADIUS self
-- @return #table Table of DCS scenery objects.
-- @return #table Structured object table: [type].[name].SCENERY
function ZONE_RADIUS:GetScannedScenery()
return self.ScanData.Scenery
end
--- Get table of scanned scenery objects
-- @param #ZONE_RADIUS self
-- @return #table Table of SCENERY objects.
function ZONE_RADIUS:GetScannedSceneryObjects()
return self.ScanData.SceneryTable
end
--- Get set of scanned scenery objects
-- @param #ZONE_RADIUS self
-- @return #table Table of Wrapper.Scenery#SCENERY scenery objects.
function ZONE_RADIUS:GetScannedSetScenery()
local scenery = SET_SCENERY:New()
local objects = self:GetScannedSceneryObjects()
for _,_obj in pairs (objects) do
scenery:AddScenery(_obj)
end
return scenery
end
--- Is All in Zone of Coalition?
-- Check if only the specifed coalition is inside the zone and noone else.
@ -2326,7 +2347,7 @@ function ZONE_POLYGON_BASE:Boundary(Coalition, Color, Radius, Alpha, Segments, C
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, true ):DrawZone(Coalition, Color, 1, Color, Alpha, nil, false)
--ZONE_RADIUS:New( "Zone", {x = PointX, y = PointY}, Radius ):DrawZone(Coalition, Color, 1, Color, Alpha, nil, true)
end
end
j = i
@ -2452,14 +2473,28 @@ function ZONE_POLYGON:Scan( ObjectCategories, UnitCategories )
self.ScanData = {}
self.ScanData.Coalitions = {}
self.ScanData.Scenery = {}
self.ScanData.SceneryTable = {}
self.ScanData.Units = {}
local vectors = self:GetBoundingSquare()
local minVec3 = {x=vectors.x1, y=0, z=vectors.y1}
local maxVec3 = {x=vectors.x2, y=0, z=vectors.y2}
local VolumeBox = {
id = world.VolumeType.BOX,
params = {
min = minVec3,
max = maxVec3
}
}
local function EvaluateZone( ZoneObject )
if ZoneObject then
local ObjectCategory = ZoneObject:getCategory()
if ( ObjectCategory == Object.Category.UNIT and ZoneObject:isExist() and ZoneObject:isActive() ) or (ObjectCategory == Object.Category.STATIC and ZoneObject:isExist()) then
local CoalitionDCSUnit = ZoneObject:getCoalition()
@ -2494,16 +2529,16 @@ function ZONE_POLYGON:Scan( ObjectCategories, UnitCategories )
end
end
--[[
-- no scenery possible at the moment
-- trying with box search
if ObjectCategory == Object.Category.SCENERY then
local SceneryType = ZoneObject:getTypeName()
local SceneryName = ZoneObject:getName()
self.ScanData.Scenery[SceneryType] = self.ScanData.Scenery[SceneryType] or {}
self.ScanData.Scenery[SceneryType][SceneryName] = SCENERY:Register( SceneryName, ZoneObject )
table.insert(self.ScanData.SceneryTable,self.ScanData.Scenery[SceneryType][SceneryName])
self:T( { SCENERY = self.ScanData.Scenery[SceneryType][SceneryName] } )
end
--]]
end
return true
@ -2529,6 +2564,18 @@ function ZONE_POLYGON:Scan( ObjectCategories, UnitCategories )
end
)
local searchscenery = false
for _,_type in pairs(ObjectCategories) do
if _type == Object.Category.SCENERY then
searchscenery = true
end
end
if searchscenery then
-- Search objects.
world.searchObjects({Object.Category.SCENERY}, VolumeBox, EvaluateZone )
end
end
--- Count the number of different coalitions inside the zone.
@ -2643,20 +2690,39 @@ function ZONE_POLYGON:GetScannedCoalition( Coalition )
end
end
--- Get scanned scenery type (currently not implemented in ZONE_POLYGON)
--- Get scanned scenery types
-- @param #ZONE_POLYGON self
-- @return #table Table of DCS scenery type objects.
function ZONE_POLYGON:GetScannedSceneryType( SceneryType )
return self.ScanData.Scenery[SceneryType]
end
--- Get scanned scenery table (currently not implemented in ZONE_POLYGON)
--- Get scanned scenery table
-- @param #ZONE_POLYGON self
-- @return #table Table of DCS scenery objects.
-- @return #table Table of Wrapper.Scenery#SCENERY scenery objects.
function ZONE_POLYGON:GetScannedSceneryObjects()
return self.ScanData.SceneryTable
end
--- Get scanned scenery table
-- @param #ZONE_POLYGON self
-- @return #table Structured table of [type].[name].Wrapper.Scenery#SCENERY scenery objects.
function ZONE_POLYGON:GetScannedScenery()
return self.ScanData.Scenery
end
--- Get scanned set of scenery objects
-- @param #ZONE_POLYGON self
-- @return #table Table of Wrapper.Scenery#SCENERY scenery objects.
function ZONE_POLYGON:GetScannedSetScenery()
local scenery = SET_SCENERY:New()
local objects = self:GetScannedSceneryObjects()
for _,_obj in pairs (objects) do
scenery:AddScenery(_obj)
end
return scenery
end
--- Is All in Zone of Coalition?
-- Check if only the specifed coalition is inside the zone and noone else.
-- @param #ZONE_POLYGON self

View File

@ -159,12 +159,69 @@ end
-- to find the correct object.
--@param #SCENERY self
--@param #string ZoneName The name of the scenery zone as created with a right-click on the map in the mission editor and select "assigned to...". Can be handed over as ZONE object.
--@return #SCENERY Scenery Object or `nil` if it cannot be found
--@return #SCENERY First found Scenery Object or `nil` if it cannot be found
function SCENERY:FindByZoneName( ZoneName )
local zone = ZoneName
local zone = ZoneName -- Core.Zone#ZONE
if type(ZoneName) == "string" then
zone = ZONE:FindByName(ZoneName)
zone = ZONE:FindByName(ZoneName)
end
local _id = zone:GetProperty('OBJECT ID')
return self:FindByName(_id, zone:GetCoordinate())
if not _id then
-- this zone has no object ID
BASE:E("**** Zone without object ID: "..ZoneName.." | Type: "..tostring(zone.ClassName))
if string.find(zone.ClassName,"POLYGON") then
zone:Scan({Object.Category.SCENERY})
local scanned = zone:GetScannedScenery()
for _,_scenery in (scanned) do
local scenery = _scenery -- Wrapper.Scenery#SCENERY
if scenery:IsAlive() then
return scenery
end
end
return nil
else
local coordinate = zone:GetCoordinate()
local scanned = coordinate:ScanScenery()
for _,_scenery in (scanned) do
local scenery = _scenery -- Wrapper.Scenery#SCENERY
if scenery:IsAlive() then
return scenery
end
end
return nil
end
else
return self:FindByName(_id, zone:GetCoordinate())
end
end
--- Scan and find all SCENERY objects from a zone by zone-name. Since SCENERY isn't registered in the Moose database (just too many objects per map), we need to do a scan first
-- to find the correct object.
--@param #SCENERY self
--@param #string ZoneName The name of the zone, can be handed as ZONE_RADIUS or ZONE_POLYGON object
--@return #table of SCENERY Objects, or `nil` if nothing found
function SCENERY:FindAllByZoneName( ZoneName )
local zone = ZoneName -- Core.Zone#ZONE_RADIUS
if type(ZoneName) == "string" then
zone = ZONE:FindByName(ZoneName)
end
local _id = zone:GetProperty('OBJECT ID')
if not _id then
-- this zone has no object ID
--BASE:E("**** Zone without object ID: "..ZoneName.." | Type: "..tostring(zone.ClassName))
zone:Scan({Object.Category.SCENERY})
local scanned = zone:GetScannedSceneryObjects()
if #scanned > 0 then
return scanned
else
return nil
end
else
local obj = self:FindByName(_id, zone:GetCoordinate())
if obj then
return {obj}
else
return nil
end
end
end