Jump to content

ME dynamic map drawings scripting


Go to solution Solved by ienatom,

Recommended Posts

Posted
5 minutes ago, Kanelbolle said:

Probably the the ID of the shape you are trying to change that is not correct.

Try to Hard code it:

 

local myzoneid = 1005
local dzvars = 
		 {
			id = myzoneid,
		 ignoreColor = true,
		 markForCoa = "all", 
		 color = {1,1,0,1},
		 fillColor = {255,255,0,.2},
		 lineType = 2,
		 readOnly = true,

		 }

mist.marker.drawZone("zonename", dzvars)
trigger.action.setMarkupColor(myzoneid , {0, 128, 255, .2} )

 

Not sure you can use the 12 in "{0, 128, 255, 12}"
As far as i know it is a value between 0 and 1

 

Yeah but then if I want to hard code the ID of the shape I need to know the one of the existing shape, which I don't right? Or is that script saying "hey, assign id 1005 to the shape named "zonename"?

I changed the value to decimal now

CPU: AMD Ryzen 7 5800X, RAM: 4x16GB G.Skill Trident Z Neo DDR4-3600 CL16, GPU: Gigabyte RX6800XT Aorus Master, MB: Gigabyte X570 Aorus ultra

My userfile content is available here (liveries, mods and whatnot)

Posted (edited)
43 minutes ago, ienatom said:

Yeah but then if I want to hard code the ID of the shape I need to know the one of the existing shape, which I don't right? Or is that script saying "hey, assign id 1005 to the shape named "zonename"?

I changed the value to decimal now

There are many ways to solve this. You can example make a table of all your zones and ID's.

 

zonesTbl = {} -- global table



local myzoneid = 1005 -- unique id
local myzonename = "CYPRUS NORTH" -- Zone name
local tmpzoneTbl = {} -- temporary table to store values
tmpzoneTbl.zonename = myzonename
tmpzoneTbl.markid = myzoneid
tmpzoneTbl.someotherinfo = "something"

local dzvars = 
		 {
			id = myzoneid,
		 ignoreColor = true,
		 markForCoa = "all", 
		 color = {1,1,0,1},
		 fillColor = {255,255,0,.2},
		 lineType = 2,
		 readOnly = true,

		 }

mist.marker.drawZone(tmpzoneTbl.zonename, dzvars)

zonesTbl[tmpzoneTbl.zonename] = tmpzoneTbl

 

Then if you want to change that marker for the zone later:

if (zonesTbl["CYPRUS NORTH"]) then -- check if the table has the KEY before trying to use a value from it.
trigger.action.setMarkupColor(zonesTbl["CYPRUS NORTH"].markid , {0, 128, 255, .2} )
end

This is just an example how you can do it.

Edited by Kanelbolle
Posted
19 minutes ago, Kanelbolle said:

There are many ways to solve this. You can example make a table of all your zones and ID's.

 

zonesTbl = {} -- global table



local myzoneid = 1005 -- unique id
local myzonename = "CYPRUS NORTH" -- Zone name
local tmpzoneTbl = {} -- temporary table to store values
tmpzoneTbl.zonename = myzonename
tmpzoneTbl.markid = myzoneid
tmpzoneTbl.someotherinfo = "something"

local dzvars = 
		 {
			id = myzoneid,
		 ignoreColor = true,
		 markForCoa = "all", 
		 color = {1,1,0,1},
		 fillColor = {255,255,0,.2},
		 lineType = 2,
		 readOnly = true,

		 }

mist.marker.drawZone(tmpzoneTbl.zonename, dzvars)

zonesTbl[tmpzoneTbl.zonename] = tmpzoneTbl

 

Then if you want to change that marker for the zone later:

if (zonesTbl["CYPRUS NORTH"]) then -- check if the table has the KEY before trying to use a value from it.
trigger.action.setMarkupColor(zonesTbl["CYPRUS NORTH"].markid , {0, 128, 255, .2} )
end

This is just an example how you can do it.

 

I tried forcing for example id 1005 but nothing is happening (as you suggested in your previuous reply). I also tried with various zoom levels on F10 and changing slot. I am losing hope 😂

 

CPU: AMD Ryzen 7 5800X, RAM: 4x16GB G.Skill Trident Z Neo DDR4-3600 CL16, GPU: Gigabyte RX6800XT Aorus Master, MB: Gigabyte X570 Aorus ultra

My userfile content is available here (liveries, mods and whatnot)

Posted
5 minutes ago, ienatom said:

I tried forcing for example id 1005 but nothing is happening (as you suggested in your previuous reply). I also tried with various zoom levels on F10 and changing slot. I am losing hope 😂

 

I might have an error in the code, have not tested it or am able to now.

But you can download my example mission here, it should work:
 

 

Posted
Just now, Kanelbolle said:

I might have an error in the code, have not tested it or am able to now.

But you can download my example mission here, it should work:
 

 

I had a look at your but it's creating a circle from scratch and not using an existing circle already drawn in the editor if I'm not mistaken. Also, I'm trying to use an existing free form shape instead. It will be very useful for other things I plan to do so thanks!

By the way, absolutely no worries if you cannot test it! I am glad you are taking the time to help me so again, thank you for the help. 😉

CPU: AMD Ryzen 7 5800X, RAM: 4x16GB G.Skill Trident Z Neo DDR4-3600 CL16, GPU: Gigabyte RX6800XT Aorus Master, MB: Gigabyte X570 Aorus ultra

My userfile content is available here (liveries, mods and whatnot)

Posted (edited)
22 minutes ago, ienatom said:

I had a look at your but it's creating a circle from scratch and not using an existing circle already drawn in the editor if I'm not mistaken. Also, I'm trying to use an existing free form shape instead. It will be very useful for other things I plan to do so thanks!

By the way, absolutely no worries if you cannot test it! I am glad you are taking the time to help me so again, thank you for the help. 😉

Glad i can help.

If you open the .miz file as a .ZIP file you can open the "mission" file inside. It will contain all your drawings and it's id's. Don't have an example to find it, but they are in there somewhere.

Or you can open the MIST script and find the function "mist.marker.getNextId()" and see how it checks for the next id. But this is hard if you don't know scripting.

But think you can get them all out with :

for key,value in pairs(mist.DBs.markList) do
   trigger.action.outText('- Mark ID: ' .. key , 120) -- To text window
   env.info('- Mark ID: ' .. key ) --To LOG file
end

 

Edited by Kanelbolle
  • Solution
Posted
7 minutes ago, Kanelbolle said:

Glad i can help.

If you open the .miz file as a .ZIP file you can open the "mission" file inside. It will contain all your drawings and it's id's. Don't have an example to find it, but they are in there somewhere.

Or you can open the MIST script and find the function "mist.marker.getNextId()" and see how it checks for the next id. But this is hard if you don't know scripting.

But think you can get them all out with :

for key,value in pairs(mist.DBs.markList) do
   trigger.action.outText('- Mark ID: ' .. key , 120) -- To text window
   env.info('- Mark ID: ' .. key ) --To LOG file
end

 

 

I'll have a look at that then!

In the meantime I tried what @cfrag suggested and it works well, although it's not ideal if you have a lot of polygons with a lot of vertices as you need to add A LOT of trigger points for your shapes.

CPU: AMD Ryzen 7 5800X, RAM: 4x16GB G.Skill Trident Z Neo DDR4-3600 CL16, GPU: Gigabyte RX6800XT Aorus Master, MB: Gigabyte X570 Aorus ultra

My userfile content is available here (liveries, mods and whatnot)

Posted
10 minutes ago, ienatom said:

although it's not ideal if you have a lot of polygons with a lot of vertices as you need to add A LOT of trigger points for your shapes

This may be a naïve question: you seem to use one trigger zone per vertex point. Wouldn't it be easier if you assembled your polys from quad zones - i.e. use multiple quad zones (four vertex points per trigger zone) to assemble more complex areas? It may not look as good, but it sure as heck would be much easier to maintain.

Posted

Had a look in the mission file and here is an example of a shape with it's ID

 

                    [61] = 
                    {
                        ["visible"] = true,
                        ["mapY"] = -377006.59612449,
                        ["primitiveType"] = "Polygon",
                        ["polygonMode"] = "free",
                        ["thickness"] = 10,
                        ["colorString"] = "0xff00007d",
                        ["name"] = "CYPRUS SOUTH",
                        ["mapX"] = -232028.82264409,
                        ["fillColorString"] = "0xff000014",
                        ["points"] = 
                        {
                            [6] = 
                            {
                                ["y"] = 15224.170096805,
                                ["x"] = 271638.47032932,
                            }, -- end of [6]
                            [2] = 
                            {
                                ["y"] = -1149.6427492402,
                                ["x"] = -1061.2086916062,
                            }, -- end of [2]
                            [3] = 
                            {
                                ["y"] = 86076.385372972,
                                ["x"] = -50729.000034843,
                            }, -- end of [3]
                            [1] = 
                            {
                                ["y"] = -1149.6427492402,
                                ["x"] = -1149.6427492402,
                            }, -- end of [1]
                            [4] = 
                            {
                                ["y"] = 202233.60168,
                                ["x"] = 106390.48659608,
                            }, -- end of [4]
                            [5] = 
                            {
                                ["y"] = 227612.13615673,
                                ["x"] = 217329.21873408,
                            }, -- end of [5]
                            [7] = 
                            {
                                ["y"] = -1149.6427492402,
                                ["x"] = -1149.6427492402,
                            }, -- end of [7]
                        }, -- end of ["points"]
                        ["layerName"] = "Common",
                        ["style"] = "dot",
                    }, -- end of [61]

It would be great if the coords of the shape could be called in the script instead of using 10000 trigger zones

CPU: AMD Ryzen 7 5800X, RAM: 4x16GB G.Skill Trident Z Neo DDR4-3600 CL16, GPU: Gigabyte RX6800XT Aorus Master, MB: Gigabyte X570 Aorus ultra

My userfile content is available here (liveries, mods and whatnot)

Posted
2 minutes ago, ienatom said:

It would be great if the coords of the shape could be called in the script instead of using 10000 trigger zones

That would be even better. I did not check - can these shapes be easily accessed (i.e. can you identify them from ME)? If so, the rest should be rather simple.

Posted
4 minutes ago, cfrag said:

That would be even better. I did not check - can these shapes be easily accessed (i.e. can you identify them from ME)? If so, the rest should be rather simple.

Yes all the shapes I inserted have a unique name and as you can see from my previous message, the ID can be identified opening the mission file inside the miz. At this point the question becomes: how do i define markupToAll so that it uses an existing shape as a "template"?

 

CPU: AMD Ryzen 7 5800X, RAM: 4x16GB G.Skill Trident Z Neo DDR4-3600 CL16, GPU: Gigabyte RX6800XT Aorus Master, MB: Gigabyte X570 Aorus ultra

My userfile content is available here (liveries, mods and whatnot)

Posted
Just now, ienatom said:

At this point the question becomes: how do i define markupToAll so that it uses an existing shape as a "template"?

Ah. Let me see if I can come up with a quick and dirty script that does that for you. Should be doable 🙂

 

  • Like 1
Posted
1 minute ago, cfrag said:

Ah. Let me see if I can come up with a quick and dirty script that does that for you. Should be doable 🙂

 

Thank man, if you want you can use that shape that I shared as a reference

CPU: AMD Ryzen 7 5800X, RAM: 4x16GB G.Skill Trident Z Neo DDR4-3600 CL16, GPU: Gigabyte RX6800XT Aorus Master, MB: Gigabyte X570 Aorus ultra

My userfile content is available here (liveries, mods and whatnot)

Posted

Well, that wasn't that difficult. Enclosed please find a small script that grabs a poly named polyName from a layer named layerName. Can return absolute map locations (default), or relative (point 1 based, as in mission).

Demo mission included.

image.png

image.png

null

Script to grab poly points (very verbose to catch errors): 

Spoiler

mxObjects = {}

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
 

script to query a polygon and print out all points

Spoiler

local points = mxObjects.getObjectFreePoly("Author", "ThisBPolygon")
trigger.action.outText("Points collected from poly:", 30)
for i=1, #points do
    trigger.action.outText("Point " .. i .. ": x=" .. points[i].x .. ", y = " .. points[i].y, 30)
end

demo mission

 

Freeform Polygon.miz

Posted (edited)
34 minutes ago, cfrag said:

Well, that wasn't that difficult. Enclosed please find a small script that grabs a poly named polyName from a layer named layerName. Can return absolute map locations (default), or relative (point 1 based, as in mission).

Demo mission included.

image.png

image.png

null

Script to grab poly points (very verbose to catch errors): 

  Hide contents

mxObjects = {}

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
 

script to query a polygon and print out all points

  Hide contents

local points = mxObjects.getObjectFreePoly("Author", "ThisBPolygon")
trigger.action.outText("Points collected from poly:", 30)
for i=1, #points do
    trigger.action.outText("Point " .. i .. ": x=" .. points[i].x .. ", y = " .. points[i].y, 30)
end

demo mission

 

Freeform Polygon.miz 11.55 kB · 1 download

Fantastic! So using this you could get absolute x and y positions for each polygon and insert them instead of triggers.

Is it also getting any other polygons and keep them "in store" so that you could call their position easily instead of writing point by point? Like:
local Polygon1points: {coordinates from your script}
And then 
trigger.action.markupToAll(7, -1, 1001, Polygon1points, {1, 0, 0, 0.5}, {1, 0, 0, 0.07}, 3)

Edited by ienatom

CPU: AMD Ryzen 7 5800X, RAM: 4x16GB G.Skill Trident Z Neo DDR4-3600 CL16, GPU: Gigabyte RX6800XT Aorus Master, MB: Gigabyte X570 Aorus ultra

My userfile content is available here (liveries, mods and whatnot)

Posted
2 minutes ago, ienatom said:

Is it also getting any other polygons and keep them "in store" so that you could call their position easily instead of writing point by point? Like:
local Polygon1points: {coordinates from your script}
And then 
trigger.action.markupToAll(7, -1, 1001, Polygon1points, {1, 0, 0, 0.5}, {1, 0, 0, 0.07}, 3)

Wouldn't that be nice. No, this is DCS, code engineering must wait outside. If I read the docs on markupToAll correct, you need to write out the parameters, meaning that you need to write a separate invocation for 3, 4, 5, 6, ... vertex polygons, probably along the lines of 

if #Polygon1Points = 3 then
	trigger.action.markupToAll(7, -1, id, Polygon1Points[1], Polygon1Points[2], Polygon1Points[3], lCol, fCol, 1)
elseif #Polygon1Points = 4 then 
	trigger.action.markupToAll(7, -1, id, Polygon1Points[1], Polygon1Points[2], Polygon1Points[3], Polygon1Points[4], lCol, fCol, 1)
elseif #Polygon1Points = 5 then 
	trigger.action.markupToAll(7, -1, id, Polygon1Points[1], Polygon1Points[2], Polygon1Points[3], Polygon1Points[4], Polygon1Points[5], lCol, fCol, 1)
elseif 
	...

The entire markup API looks a bit ad-hoc-assembled to me. Shudder. Of course, I'd be happy to be corrected. 🙂 

  • Like 1
Posted
1 minute ago, cfrag said:

Wouldn't that be nice. No, this is DCS, code engineering must wait outside. If I read the docs on markupToAll correct, you need to write out the parameters, meaning that you need to write a separate invocation for 3, 4, 5, 6, ... vertex polygons, probably along the lines of 

if #Polygon1Points = 3 then
	trigger.action.markupToAll(7, -1, id, Polygon1Points[1], Polygon1Points[2], Polygon1Points[3], lCol, fCol, 1)
elseif #Polygon1Points = 4 then 
	trigger.action.markupToAll(7, -1, id, Polygon1Points[1], Polygon1Points[2], Polygon1Points[3], Polygon1Points[4], lCol, fCol, 1)
elseif #Polygon1Points = 5 then 
	trigger.action.markupToAll(7, -1, id, Polygon1Points[1], Polygon1Points[2], Polygon1Points[3], Polygon1Points[4], Polygon1Points[5], lCol, fCol, 1)
elseif 
	...

The entire markup API looks a bit ad-hoc-assembled to me. Shudder. Of course, I'd be happy to be corrected. 🙂 

It would be nice indeed 😂 Thanks for the help man, at this point it would probably be easier to use trigger points, although the coords thing could be useful!

2 hours ago, cfrag said:

This may be a naïve question: you seem to use one trigger zone per vertex point. Wouldn't it be easier if you assembled your polys from quad zones - i.e. use multiple quad zones (four vertex points per trigger zone) to assemble more complex areas? It may not look as good, but it sure as heck would be much easier to maintain.

Regarding this, do you think you could use more than 1 quad zone to make up for a shaped polygon with a lot of vertices?

CPU: AMD Ryzen 7 5800X, RAM: 4x16GB G.Skill Trident Z Neo DDR4-3600 CL16, GPU: Gigabyte RX6800XT Aorus Master, MB: Gigabyte X570 Aorus ultra

My userfile content is available here (liveries, mods and whatnot)

Posted (edited)

Funny enough, for some reason now it doesn't fill all the shapes with the specified colors 😂

 

Cattura.PNG

Edited by ienatom

CPU: AMD Ryzen 7 5800X, RAM: 4x16GB G.Skill Trident Z Neo DDR4-3600 CL16, GPU: Gigabyte RX6800XT Aorus Master, MB: Gigabyte X570 Aorus ultra

My userfile content is available here (liveries, mods and whatnot)

Posted (edited)
3 hours ago, ienatom said:

Funny enough, for some reason now it doesn't fill all the shapes with the specified colors

That's a classic thing that nobody explains to you and simply expects you to know: it's a winding issue with polygons, to see if they are facing you or not. It's from 3D, and why it's applied here, nobody knows. Upshot is: if it's not filled, reverse the order of the vertices, so it's wound the other way around. 

If your vertex points were given a, b, c, d, e to the poly draw method, re-order them to e, d, c, b, a and they should now be filled in correctly. I suspect this to be another instance of haphazard coding, the mission stuff not being designed but slapped together, maybe even copied from sources not fully understood (note: not knowing the details, I'm not accusing ED here of shoddy workmanship, I merely voice my opinion that some parts of DCS look that way). 

So, reverse order, and with some luck, thou shalt see the innards of thine poly 🙂 

Edited by cfrag
  • Like 1
Posted
8 minutes ago, cfrag said:

That's a classic thing that nobody explains to you and simply expects you to know: it's a winding issue with polygons, to see if they are facing you or not. It's from 3D, and why it's applied here, nobody knows. Upshot is: if it's not filled, reverse the order of the vertices, so it's wound the other way around. 

If your vertex points were given a, b, c, d, e to the poly draw method, re-order them to e, d, c, b, a and they should now be filled in correctly. I suspect this to be another instance of haphazard coding, the mission stuff not being designed but slapped together, maybe even copied from sources not fully understood (note: not knowing the details, I'm not accusing ED here of shoddy workmanship, I merely voice my opinion that some parts of DCS look that way). 

So, reverse order, and with some luck, thou shalt see the innards of thine poly 🙂 

 

Thanks man 😂 This kind of things just make me laugh at this point.

I will reverse all the order but I guess if that's it the issue is now solved and the script works flawlessly. Thank you both for the help guys, really appreciated! 🫡

CPU: AMD Ryzen 7 5800X, RAM: 4x16GB G.Skill Trident Z Neo DDR4-3600 CL16, GPU: Gigabyte RX6800XT Aorus Master, MB: Gigabyte X570 Aorus ultra

My userfile content is available here (liveries, mods and whatnot)

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...