Fixed custom drawings

This commit is contained in:
2026-08-17 11:11:25 +02:00
parent 52f97f7c92
commit 2c994eac9a
10 changed files with 198 additions and 51 deletions
+5 -5
View File
@@ -220,7 +220,7 @@ function CAP.getAsTasking(groupName, airbase, capZone, capConfig)
action = {
id = "Script",
params = {
command = "pcall(Spearhead.Events.PublishOnStation, \"" .. groupName .. "\")"
command = "pcall(GlobalCapCallBacks.PublishOnStation, \"" .. groupName .. "\")"
}
}
}
@@ -260,7 +260,7 @@ function CAP.getAsTasking(groupName, airbase, capZone, capConfig)
},
stopCondition = {
duration = durationBefore10,
condition = "return Spearhead.DcsUtil.NeedsRTBInTen(\"" .. groupName .. "\", 0.10)",
condition = "return GlobalCapCallBacks.NeedsRTBInTen(\"" .. groupName .. "\", 0.10)",
}
}
},
@@ -273,7 +273,7 @@ function CAP.getAsTasking(groupName, airbase, capZone, capConfig)
action = {
id = "Script",
params = {
command = "pcall(Spearhead.Events.PublishRTBInTen, \"" .. groupName .. "\")"
command = "pcall(GlobalCapCallBacks.PublishRTBInTen, \"" .. groupName .. "\")"
}
}
}
@@ -299,7 +299,7 @@ function CAP.getAsTasking(groupName, airbase, capZone, capConfig)
},
stopCondition = {
duration = durationAfter10,
condition = "return Spearhead.DcsUtil.IsBingoFuel(\"" .. groupName .. "\")",
condition = "return GlobalCapCallBacks.IsBingoFuel(\"" .. groupName .. "\", 0.10)",
}
}
},
@@ -312,7 +312,7 @@ function CAP.getAsTasking(groupName, airbase, capZone, capConfig)
action = {
id = "Script",
params = {
command = "pcall(Spearhead.Events.PublishRTB, \"" .. groupName .. "\")"
command = "pcall(GlobalCapCallBacks.PublishRTB, \"" .. groupName .. "\")"
}
}
}
@@ -0,0 +1,26 @@
local DcsUtil = require("classes.util.DcsUtil")
local Events = require("classes.spearhead_events")
GlobalCapCallBacks = {}
function GlobalCapCallBacks.IsBingoFuel(groupName, fuelPercent)
return DcsUtil.IsBingoFuel(groupName, fuelPercent)
end
function GlobalCapCallBacks.NeedsRTBInTen(groupName, fuelOffset)
return DcsUtil.NeedsRTBInTen(groupName, fuelOffset)
end
function GlobalCapCallBacks.PublishRTBInTen(groupName)
return Events.PublishRTBInTen(groupName)
end
function GlobalCapCallBacks.PublishRTB(groupName)
return Events.PublishRTB(groupName)
end
function GlobalCapCallBacks.PublishOnStation(groupName)
return Events.PublishOnStation(groupName)
end
@@ -247,7 +247,7 @@ function INTERCEPT.getInterceptTaskPoint(groupName, currentPoint, targetPoint, a
action = {
id = "Script",
params = {
command = "pcall(Spearhead.Events.PublishRTB, \"" .. groupName .. "\")"
command = "pcall(GlobalCapCallBacks.PublishRTB, \"" .. groupName .. "\")"
}
}
}
@@ -379,7 +379,7 @@ function INTERCEPT.getUnitInterceptTaskPoint(groupName, currentPoint, targetPosi
action = {
id = "Script",
params = {
command = "pcall(Spearhead.Events.PublishRTB, \"" .. groupName .. "\")"
command = "pcall(GlobalCapCallBacks.PublishRTB, \"" .. groupName .. "\")"
}
}
}
+2 -2
View File
@@ -189,7 +189,7 @@ function SWEEP.getAsTasking(groupName, airbase, capZone, capConfig)
action = {
id = "Script",
params = {
command = "pcall(Spearhead.Events.PublishOnStation, \"" .. groupName .. "\")"
command = "pcall(GlobalCapCallBacks.PublishOnStation, \"" .. groupName .. "\")"
}
}
}
@@ -270,7 +270,7 @@ function SWEEP.getAsTasking(groupName, airbase, capZone, capConfig)
action = {
id = "Script",
params = {
command = "pcall(Spearhead.Events.PublishRTB, \"" .. groupName .. "\")"
command = "pcall(GlobalCapCallBacks.PublishRTB, \"" .. groupName .. "\")"
}
}
}
+1 -1
View File
@@ -231,7 +231,7 @@ function Database.New(Logger)
for key, layer_object in pairs(layer.objects) do
if Util.startswith(layer_object.name, "drawing_", true) then
local object = layer_object --[[@as DrawingObject]]
local customDrawing = CustomDrawing.New(object)
local customDrawing = CustomDrawing.New(object, nil, self._logger.LogLevel)
table.insert(self._tables.CustomDrawings, customDrawing)
end
end
+6 -6
View File
@@ -92,7 +92,7 @@ do --setup route util
action = {
id = "Script",
params = {
command = "pcall(Spearhead.Events.PublishOnStation, \"" .. groupName .. "\")"
command = "pcall(GlobalCapCallBacks.PublishOnStation, \"" .. groupName .. "\")"
}
}
}
@@ -122,7 +122,7 @@ do --setup route util
},
stopCondition = {
duration = durationBefore10,
condition = "return Spearhead.DcsUtil.IsBingoFuel(\"" .. groupName .. "\", 0.10)",
condition = "return GlobalCapCallBacks.IsBingoFuel(\"" .. groupName .. "\", 0.10)",
}
}
},
@@ -135,7 +135,7 @@ do --setup route util
action = {
id = "Script",
params = {
command = "pcall(Spearhead.Events.PublishRTBInTen, \"" .. groupName .. "\")"
command = "pcall(GlobalCapCallBacks.PublishRTBInTen, \"" .. groupName .. "\")"
}
}
}
@@ -156,7 +156,7 @@ do --setup route util
},
stopCondition = {
duration = durationAfter10,
condition = "return Spearhead.DcsUtil.IsBingoFuel(\"" .. groupName .. "\")",
condition = "return GlobalCapCallBacks.IsBingoFuel(\"" .. groupName .. "\", 0.10)",
}
}
},
@@ -169,7 +169,7 @@ do --setup route util
action = {
id = "Script",
params = {
command = "pcall(Spearhead.Events.PublishRTB, \"" .. groupName .. "\")"
command = "pcall(GlobalCapCallBacks.PublishRTB, \"" .. groupName .. "\")"
}
}
}
@@ -375,7 +375,7 @@ do --setup route util
action = {
id = "Script",
params = {
command = "pcall(Spearhead.Events.PublishRTB, \"" ..
command = "pcall(GlobalCapCallBacks.PublishRTB, \"" ..
groupName .. "\")"
}
}
@@ -216,12 +216,15 @@ end
---@private
function GlobalStageManager:UpdateDrawings(stageNumber)
self.logger:debug("Updating custom drawings for stage number: " .. tostring(stageNumber))
local drawings = self.database:getCustomDrawings()
for _, drawing in pairs(drawings) do
local startStage, stopStage = drawing:GetStartAndStop()
if stageNumber >= startStage and stageNumber < stopStage then
self.logger:debug("Drawing " .. drawing:GetName() .. " is active for stage number: " .. tostring(stageNumber))
drawing:Draw()
else
self.logger:debug("Drawing " .. drawing:GetName() .. " is not active for stage number: " .. tostring(stageNumber))
drawing:Remove()
end
end
@@ -1,23 +1,27 @@
local DrawingHelper = require("classes.stageClasses.drawings.helper.DrawingHelper")
local Util = require("classes.util.Util")
local Logger = require("classes.util.Logger")
---@class CustomDrawing
---@field private _id integer?
---@field private _drawingObject DrawingObject
---@field private _startingStage number
---@field private _removeAtStage number
---@field private _logger Logger
local CustomDrawing = {}
CustomDrawing.__index = CustomDrawing
---@param drawingObject DrawingObject
---@param id integer?
---@param loglevel LogLevel
---@return CustomDrawing
function CustomDrawing.New(drawingObject, id)
function CustomDrawing.New(drawingObject, id, loglevel)
local self = setmetatable({}, CustomDrawing)
self._drawingObject = drawingObject
self._id = id
self._logger = Logger.new("CustomDrawing", loglevel)
local name = drawingObject.name
local split = Util.split_string(name or "", "_")
@@ -28,6 +32,11 @@ function CustomDrawing.New(drawingObject, id)
return self
end
---@return string
function CustomDrawing:GetName()
return self._drawingObject.name
end
---@return number start
---@return number stop
function CustomDrawing:GetStartAndStop()
@@ -35,11 +44,18 @@ function CustomDrawing:GetStartAndStop()
end
function CustomDrawing:Draw()
self._id = DrawingHelper.Draw(self._drawingObject)
self._logger:debug("Drawing custom drawing with ID " .. tostring(self._id))
if self._id ~= nil then
DrawingHelper.Remove(self._id)
end
self._id = DrawingHelper.Draw(self._drawingObject, self._logger)
end
function CustomDrawing:Remove()
if self._id ~= nil then
self._logger:debug("Removing custom drawing with ID " .. tostring(self._id))
DrawingHelper.Remove(self._id)
self._id = nil
end
@@ -1,25 +1,39 @@
local Util = require("classes.util.Util")
---@class DrawingHelper
local DrawingHelper = {}
DrawingHelper.__index = DrawingHelper
local customDrawingIdIncrementer = 4210
---@param object DrawingObject
---@param logger Logger?
---@return integer? id
function DrawingHelper.Draw(object)
function DrawingHelper.Draw(object, logger)
if object == nil then
if logger then
logger:warn("DrawingHelper.Draw called with nil object")
end
return nil
end
local id = DrawingHelper.GetAndAddId()
if logger then
logger:debug("Drawing object with ID " .. tostring(id) .. " and primitive type: " .. tostring(object.primitiveType))
end
if(object.primitiveType == "Polygon") then
DrawingHelper.DrawPolygon(object--[[@as Polygon]], id)
DrawingHelper.DrawPolygon(object--[[@as Polygon]], id, logger)
elseif(object.primitiveType == "Line") then
DrawingHelper.DrawLine(object--[[@as Line]], id)
DrawingHelper.DrawLine(object--[[@as Line]], id, logger)
elseif(object.primitiveType == "TextBox") then
DrawingHelper.DrawTextBox(object--[[@as TextBox]], id)
else
if logger then
logger:warn("Unknown primitive type: " .. tostring(object.primitiveType))
end
end
return id
@@ -36,16 +50,25 @@ end
---@param points Array<Vec3>
---@param fillColor table
---@param lineColor table
local function MarkupToAll(shapeID, drawID, points, fillColor, lineColor, lineStyle)
---@param lineStyle LineType
---@param lineThickness number
---@param logger Logger?
local function MarkupToAll(shapeID, drawID, points, fillColor, lineColor, lineStyle, lineThickness, logger)
if lineThickness == nil or lineThickness <= 0 then
lineStyle = 0
end
local functionString = "trigger.action.markupToAll(" .. shapeID .. ", -1, " .. drawID .. ","
for _, point in ipairs(points) do
for _, point in pairs(points) do
functionString = functionString .. " { x=" .. point.x .. ", y=0,z=" .. point.z .. "},"
end
functionString = functionString ..
"{ " .. lineColor[1] .. "," .. lineColor[2] .. "," .. lineColor[3] .. "," .. lineColor[4] .. "}, " ..
"{ " .. fillColor[1] .. "," .. fillColor[2] .. "," .. fillColor[3] .. "," .. fillColor[4] .. "}, " ..
lineStyle .. ")"
functionString = functionString .. "{0,1,0,1}, {0,1,0,1}, " .. lineStyle .. ")"
if logger then
logger:debug("Drawing complex drawing with ID " .. tostring(drawID) .. " and function string: " .. functionString)
end
---@diagnostic disable-next-line: deprecated
local f, err = loadstring(functionString)
@@ -55,12 +78,21 @@ local function MarkupToAll(shapeID, drawID, points, fillColor, lineColor, lineS
env.error("Something failed when drawing complex drawing" .. err)
end
if logger then
logger:debug("Drawing with fill color: " .. table.concat(fillColor, ",") .. " and line color: " .. table.concat(lineColor, ",") .. " and line style: " .. tostring(lineStyle) .. " and line thickness: " .. tostring(lineThickness))
end
trigger.action.setMarkupColorFill(drawID, fillColor)
trigger.action.setMarkupColor(drawID, lineColor)
trigger.action.setMarkupTypeLine(drawID, lineStyle)
end
---@private
---@param object Polygon
---@param id integer
function DrawingHelper.DrawPolygon(object, id)
---@param logger Logger?
function DrawingHelper.DrawPolygon(object, id, logger)
if object == nil then
return
end
@@ -75,11 +107,12 @@ function DrawingHelper.DrawPolygon(object, id)
end
---@param oval Oval
local function DrawOval(oval)
---@param logger Logger?
local function DrawOval(oval, logger)
---@type Array<Vec3>
local points = {}
local pointsNo = 30
local angleStep = (2 * math.pi) / points
local angleStep = (2 * math.pi) / pointsNo
local fillColor = DrawingHelper.ColorToColorTable(oval.fillColorString)
local color = DrawingHelper.ColorToColorTable(oval.colorString)
@@ -91,20 +124,37 @@ function DrawingHelper.DrawPolygon(object, id)
local y = oval.mapY + (oval.r2 * math.sin(angle))
table.insert(points, { x = x, y = 0, z = y } )
end
MarkupToAll(7, id, points, fillColor, color, lineStyle)
MarkupToAll(7, id, points, fillColor, color, lineStyle, oval.thickness, logger)
end
---@param free Free
local function DrawFree(free)
---@param logger Logger?
local function DrawFree(free, logger)
local fillColor = DrawingHelper.ColorToColorTable(free.fillColorString)
local color = DrawingHelper.ColorToColorTable(free.colorString)
local lineStyle = DrawingHelper.ToLineStyleInteger(free.style)
local points = {}
for _, point in ipairs(free.points) do
table.insert(points, { x = point.x, y = 0, z = point.y } )
local keys = {}
for k, _ in pairs(free.points) do
table.insert(keys, k)
end
MarkupToAll(7, id, points, fillColor, color, lineStyle)
table.sort(keys, function(a, b) return a < b end)
local points = {}
for _, k in ipairs(keys) do
local point = free.points[k]
local newPoint = { x = free.mapX + point.x, y = 0, z = free.mapY + point.y }
local firstPoint = points[1]
if firstPoint == nil or newPoint.x ~= firstPoint.x or newPoint.z ~= firstPoint.z then
logger:debug("Drawing free polygon point " .. tostring(k) .. ": " .. tostring(free.points[k].x) .. ", " .. tostring(free.points[k].y))
table.insert(points, newPoint)
end
end
MarkupToAll(7, id, points, fillColor, color, lineStyle, free.thickness, logger)
end
---@param rect Rect
@@ -116,38 +166,49 @@ function DrawingHelper.DrawPolygon(object, id)
local pointA = { x = rect.mapX, y = 0, z = rect.mapY }
local pointB = { x = rect.mapX + rect.width, y = 0, z = rect.mapY + rect.height }
trigger.action.rectToAll(-1, id, pointA, pointB, color, fillColor, lineStyle, true)
end
---@param arrow Arrow
local function DrawArrow(arrow)
---@param logger Logger?
local function DrawArrow(arrow, logger)
local fillColor = DrawingHelper.ColorToColorTable(arrow.fillColorString)
local color = DrawingHelper.ColorToColorTable(arrow.colorString)
local lineStyle = DrawingHelper.ToLineStyleInteger(arrow.style)
local startPoint = { x = arrow.mapX, y = 0, z = arrow.mapY }
if logger then
logger:debug("Drawing arrow with start point: " .. tostring(arrow.mapX) .. ", " .. tostring(arrow.mapY) .. " and angle: " .. tostring(arrow.angle) .. " and length: " .. tostring(arrow.length))
end
local endPoint = { x = arrow.mapX, y = 0, z = arrow.mapY }
local rad = math.rad(arrow.angle or 0)
local length = arrow.length or 100
local endPoint = { x = arrow.mapX + length * math.cos(rad), y = 0, z = arrow.mapY + length * math.sin(rad) }
local startPoint = { x = arrow.mapX - length * math.sin(rad), y = 0, z = arrow.mapY + length * math.cos(rad) }
trigger.action.arrowToAll(-1, id, startPoint, endPoint, color, fillColor, lineStyle, true)
end
if logger then
logger:debug("Drawing polygon with ID " .. tostring(id) .. " and polygon mode: " .. tostring(object.polygonMode))
end
if object.polygonMode == "circle" then
DrawCircle(object--[[@as Circle]])
elseif object.polygonMode == "oval" then
DrawOval(object--[[@as Oval]])
DrawOval(object--[[@as Oval]], logger)
elseif object.polygonMode == "free" then
DrawFree(object--[[@as Free]])
DrawFree(object--[[@as Free]], logger)
elseif object.polygonMode == "rect" then
DrawRect(object--[[@as Rect]])
elseif object.polygonMode == "arrow" then
DrawArrow(object--[[@as Arrow]])
DrawArrow(object--[[@as Arrow]], logger)
end
end
---@private
---@param object Line
---@param id integer
function DrawingHelper.DrawLine(object, id)
---@param logger Logger?
function DrawingHelper.DrawLine(object, id, logger)
---@type Array<Vec3>
local points = {}
@@ -158,7 +219,7 @@ function DrawingHelper.DrawLine(object, id)
local color = DrawingHelper.ColorToColorTable(object.colorString)
local lineStyle = DrawingHelper.ToLineStyleInteger(object.style)
MarkupToAll(1, id, points, color, color, lineStyle)
MarkupToAll(1, id, points, color, color, lineStyle, object.thickness, logger)
end
---@private
@@ -177,16 +238,14 @@ function DrawingHelper.Remove(id)
trigger.action.removeMark(id)
end
---@param hexStr string
---@return table
function DrawingHelper.ColorToColorTable(hexStr)
hexStr = hexStr:gsub("0x", "")
local a = tonumber(hexStr:sub(1, 2), 16) / 255
local r = tonumber(hexStr:sub(3, 4), 16) / 255
local g = tonumber(hexStr:sub(5, 6), 16) / 255
local b = tonumber(hexStr:sub(7, 8), 16) / 255
local r = tonumber(hexStr:sub(1, 2), 16) / 255
local g = tonumber(hexStr:sub(3, 4), 16) / 255
local b = tonumber(hexStr:sub(5, 6), 16) / 255
local a = tonumber(hexStr:sub(7, 8), 16) / 255
return { r, g , b , a }
end
+43
View File
@@ -297,6 +297,49 @@ do -- INIT UTIL
return false
end
---@param points Array<Vec3>
---@return Array<Vec3>
function UTIL.getConvexHull3d(points)
if #points == 0 then
return {}
end
---comment
---@param a Vec3
---@param b Vec3
---@param c Vec3
---@return boolean
local function ccw(a, b, c)
return (b.z - a.z) * (c.x - a.x) > (b.x - a.x) * (c.z - a.z)
end
table.sort(points, function(left, right)
return left.z < right.z
end)
local hull = {}
-- lower hull
for _, point in pairs(points) do
while #hull >= 2 and not ccw(hull[#hull - 1], hull[#hull], point) do
table.remove(hull, #hull)
end
table.insert(hull, point)
end
-- upper hull
local t = #hull + 1
for i = #points, 1, -1 do
local point = points[i]
while #hull >= t and not ccw(hull[#hull - 1], hull[#hull], point) do
table.remove(hull, #hull)
end
table.insert(hull, point)
end
table.remove(hull, #hull)
return hull
end
---comment
---@param points Array<Vec2> points
---@return Array<Vec2> hullPoints