DML/modules/mxObjects.lua
Christian Franz c3ba1e7c05 Version 1.4.7
New bombsAway module
2023-11-02 12:36:51 +01:00

194 lines
5.4 KiB
Lua

mxObjects = {}
mxObjects.version = "1.0.0"
mxObjects.allObjects = {}
mxObjects.textBoxes = {}
mxObjects.miscObjects = {}
mxObjects.imperial = true
mxObjects.doubleLine = true
-- scan mission to set up object DB
function mxObjects.scanMissionData()
if not env.mission.drawings then
trigger.action.outText("+++mxO: Mission has no object layer", 30)
return
end
local drawings = env.mission.drawings
-- all drawings are in drawings[layer]
local layers = drawings["layers"]
if not layers then
trigger.action.outText("+++mxO: Mission has no layers in objects", 30)
return
end
-- each layer has a "name" field that identifies the layer, and
-- per layer there are the objects. Let's flatten the structure,
-- since object names are unique
local count = 0
for idx, aLayer in pairs(layers) do
local layerName = aLayer.name
local objects = aLayer.objects
-- scan objects in this layer
for idy, theObject in pairs (objects) do
local theData = dcsCommon.clone(theObject)
theData.dist = math.huge -- simply init field
-- make theData point-compatible, handle y<>z adapt
theData.x = theData.mapX -- set up x, y, z
if not theData.x then theData.x = 0 end
theData.y = 0
theData.z = theData.mapY
if not theData.z then theData.z = 0 end
if mxObjects.allObjects[theData.name] then
trigger.action.outText("+++mxO: name collision for drawing object named <" .. theData.name .. ">, skipped.", 30)
else
mxObjects.allObjects[theData.name] = theData
count = count + 1
-- sort into quick-access "type" slots
if theData.primitiveType == "TextBox" then
mxObjects.textBoxes[theData.name] = theData
else
mxObjects.miscObjects[theData.name] = theData
end
end
end
end
end
function mxObjects.sortObjectsInRelationTo(p, objects)
if not p then return nil end
-- calculate distance to all into new list
local disted = {}
for name, theData in pairs(objects) do
theData.dist = dcsCommon.dist(p, theData)
table.insert(disted, theData)
end
table.sort(disted,
function (e1, e2) return e1.dist < e2.dist end
)
return disted
end
function mxObjects.showNClosestTextObjectsToUnit(n, theUnit, numbered)
if numbered == nil then numbered = true end
local p = theUnit:getPoint()
local headingInDegrees = dcsCommon.getUnitHeadingDegrees(theUnit)
local theList = mxObjects.sortObjectsInRelationTo(p, mxObjects.textBoxes)
local msg = "\n"
if #theList < 1 then
msg = msg .. " NO OBJECTS "
else
if n > #theList then n = #theList end
for i = 1, n do
theObject = theList[i]
local dist = theObject.dist
units = "km"
if mxObjects.imperial then
dist = dist * 3.28084
dist = math.floor(dist * 0.0016457883895983) -- in 0.1 nautmil
units = "nm"
else
dist = math.floor(theObject.dist / 100) -- dekameters
end
dist = dist / 10
if numbered then
if i < 10 and n > 9 then
msg = msg .. "0"
end
msg = msg .. i .. ". "
end
-- show text
msg = msg .. theObject.text
-- bearing
local bea = dcsCommon.bearingInDegreesFromAtoB(p, theObject)
msg = msg .. " bearing " .. bea .. "°,"
-- get clock position
local clockPos = dcsCommon.clockPositionOfARelativeToB(theObject, p, headingInDegrees)
msg = msg .. " your " .. clockPos .. " o'clock, "
-- dist
msg = msg .. " " .. dist .. units
msg = msg .. "\n" -- add line feed
if mxObjects.doubleLine and (i < n) then msg = msg .. "\n" end
end
end
return msg
end
function mxObjects.getClosestTo(p, objects)
if not p then return nil, nil end
local closest = nil
local theDist = math.huge
for oName, theData in pairs (objects) do
end
end
function mxObjects.getObjectFreePoly(layerName, polyName, rel) -- omit rel to get absolute points, else pass 'true' to get relative to first point.
if not rel then rel = false end -- relative or absolute
if not env.mission.drawings then
trigger.action.outText("+++mxO: Mission has no drawings.", 30)
return {}
end
local drawings = env.mission.drawings
local layers = drawings["layers"]
if not layers then
trigger.action.outText("+++mxO: Mission has no layers in drawing", 30)
return {}
end
local theLayer = nil
for idx, aLayer in pairs(layers) do
if aLayer.name == layerName then
theLayer = aLayer
end
end
if not theLayer then
trigger.action.outText("+++mxO: No layer named <" .. layerName .. "> in Mission", 30)
return {}
end
local objects = theLayer.objects
if not objects then
trigger.action.outText("+++mxO: No objects in layer <" .. layerName .. ">", 30)
return {}
end
-- scan objects for a "free" mode poly with name polyName
for idx, theObject in pairs(objects) do
if theObject.polygonMode == "free" and theObject.name == polyName then
local poly = {}
for idp, thePoint in pairs(theObject.points) do
local p = {}
p.x = thePoint.x
p.y = thePoint.y
if not rel then
p.x = p.x + theObject.mapX
p.y = p.y + theObject.mapY
end
poly[idp] = p
end
return poly
end
end
trigger.action.outText("+++mxO: no polygon named <" .. polyName .. "> in layer <" ..layerName .. ">", 30)
return {}
end
function mxObjects.start()
mxObjects.scanMissionData()
trigger.action.outText("mxObjects v" .. mxObjects.version .. " loaded.", 30)
end
mxObjects.start()
--[[--
local theUnit = Unit.getByName("Bannok")
local msg = mxObjects.showNClosestTextObjectsToUnit(8, theUnit, numbered)
trigger.action.outText(msg, 30)
--]]--