Jump to content

Recommended Posts

Posted

Ok I've run into a problem that I can't get around because I don't understand enough about arrays as tables. I will keep on looking but thought I would ask here in case someone can short circuit things for me.

 

So in simplified terms

 

On a LAND event in an event handler I put an entry in a table containing details of the unit that landed via table[#table + 1] = {blah blah}

 

In another function I am reading through the table and if the unit's absolute value of velocity is < 1 I am despawning it.

 

So

 

For i = 1,#table do

 

figure out absolute value of velocity

if absvel < 1

Unit:destroy()

end

end

 

Thing is over time this table will get bigger and bigger each time a unit lands. However if I do a table = nil or a table.remove(table, i) right after the destroy or even later in the function doing the despawns no further entries are written to the table by the LAND event. I assume that the pointers to the elements in the table are getting screwed up by the removal of the entry and so the next time a LAND happens and #table is evaluated it has problems.

 

Obviously I don't want the table to continue growing but I can't see how to remove the entry without breaking things.

 

Any advice or tips please?

 

Thanks,

Stonehouse

Posted

Iterate via in pairs. It has the benefit of iterating the whole table even if indexes are missed. I only really use for i = 1, x do iterators where I create the table locally and I am for certain that there aren't any empty values.

 

for index, unit in pairs(table) do

 

-- remove entry condition

table[index] = nil

end

The right man in the wrong place makes all the difference in the world.

Current Projects:  Grayflag ServerScripting Wiki

Useful Links: Mission Scripting Tools MIST-(GitHub) MIST-(Thread)

 SLMOD, Wiki wishlist, Mission Editing Wiki!, Mission Building Forum

Posted (edited)

Does that mean I need to insert the entry to the table differently too? Just thinking if the table is going to be missing indexes I am guessing #table + 1 won't work anymore? I guess that is also why when I deleted an entry like I first tried landing events wouldn't add an entry anymore?

 

Is that where I would use table.insert?

 

If the old entry looked like:

 

landedaircraftsING[#landedaircraftsING + 1] = {groupname = actuallandinggroupname, unit = landingunit, unitname = Unit.getName(landingunit)}

 

would the table.insert version look like

 

table.insert(landedaircraftsING, {groupname = actuallandinggroupname, unit = landingunit, unitname = Unit.getName(landingunit)})

 

<edit> or

table.insert(landedaircraftsING.groupname, actuallandinggroupname)

table.insert(landedaircraftsING.unit, landingunit)

table.insert(landedaircraftsING.unitname, Unit.getName(landingUnit))

 

thinking about it feel this is correct?

 

Thanks

Stonehouse

Edited by Stonehouse
Posted

If the old entry looked like:

 

landedaircraftsING[#landedaircraftsING + 1] = {groupname = actuallandinggroupname, unit = landingunit, unitname = Unit.getName(landingunit)}

 

would the table.insert version look like

 

table.insert(landedaircraftsING, {groupname = actuallandinggroupname, unit = landingunit, unitname = Unit.getName(landingunit)})

 

 

These are the same and would get the same results. The other thing you posted wouldn't work for the purpose of what you are doing.

 

The point of using in pairs is it can iterate any type of format and not just indexed numerically. So you could simply have the items indexed by unitName when they get added to the table...

 

landedaircraftsING[unitName] = {groupname = actuallandinggroupname, unit = landingunit}

The right man in the wrong place makes all the difference in the world.

Current Projects:  Grayflag ServerScripting Wiki

Useful Links: Mission Scripting Tools MIST-(GitHub) MIST-(Thread)

 SLMOD, Wiki wishlist, Mission Editing Wiki!, Mission Building Forum

Posted (edited)
.....

The point of using in pairs is it can iterate any type of format and not just indexed numerically. So you could simply have the items indexed by unitName when they get added to the table...

 

landedaircraftsING[unitName] = {groupname = actuallandinggroupname, unit = landingunit}

 

If doing this last version what does the for loop look like?

 

for unitName, ???? in pairs((landingaircraftsING) do

 

as I am understanding things the ???? is the value. In this case is it essentially anything I want which serves as a pointer to the table element?

 

So if for arguments sake I had

 

for unitName, landingircraft in pairs((landingaircraftsING) do

 

do I address the bits of separate info like

 

xyz = landingaircraft[unitName].groupname

abc = landingaircraft[unitName].unit

 

or

xyz = landingaircraft.groupname

abc = landingaircraft.unit

 

and finally

 

landingaircraftsING[unitName] = nil to remove a table entry or could I still use landingaircraft and achieve the same result because landingaircraft is a pointer to an element in landingaircraftsING? eg would landingaircraft = nil work to set the entry for landingaircraftsING[unitName] to nil

 

Have I got it right? The loop reads through the table returning each key (into unitName) and the entry (which is itself a table) into landingaircraft?

 

I've also seen snippets of code that do

 

for _,value in pairs(table) do

 

what is the significance of the _? or is it just a variable name like abc?

 

Sorry to ask you to act as bit of an instructor (or anyone else who might want to respond) but all the examples I have seen so far in lua reference manuals are so basic that it's very hard to take them up to the next level and they don't really explain just sort of say well here it is in three sentences, go forth and conquer. Only you find you've got a stage prop for a weapon when you try to use it in anger writing code.

 

Thanks,

Stonehouse

Edited by Stonehouse
Posted

The following code snippet would not change the table:

for unitName, landingaircraft in pairs(landingaircraftsING) do
   landingaircraft = nil -- this line would not delete anything from the table, landingaircraft is just another local variable that points to the same object as the table entry
end

 

This code snippet would delete all entries from the table:

for unitName, landingaircraft in pairs(landingaircraftsING) do
   landingaircraftsING[unitName] = nil -- set table entry to nil
end

 

If you see "_" used in a for loop, it is just a variable like any other -- the convention is to use it in place of a descriptive name when you do not care about that part of the key-value pair, i.e. the "_" variable should never be used inside the body of the loop.

Posted

Thanks Ian,

 

So just to be sure I take it from your second example then that

xyz = landingaircraftsING[unitName].groupname

abc = landingaircraftsING[unitName].unit

 

is the syntax that would set xyz and abc to groupname and unit respectively?

 

Cheers,

Stonehouse

Posted

On a LAND event in an event handler

 

Hi Stonehouse,

 

Can you give me an example of the syntax you have used for this event and its handler?

 

I want to detect if an AI group has landed.

Windows 10 64bit, Intel i7 6700K, 32GB Corsair 2400Mhz, 970 NVMe 500Gb SSD, GeForce 2080 super, HP Reverb, VKB GF PRO, Thrustmaster Warthog throttle, Thrustmaster Pendular rudders, Windows + DCS :thumbup:

 

My youtube channel

Posted

 

 

function arrivaltableINT:onEvent(event)

--CAP or GCI aircraft landing increase supply and get included in the list of landing aircraft for despawn

if (world.event.S_EVENT_LAND == event.id)

then

if event.initiator ~= nil

then

local landingunit = event.initiator

local ldesc = Unit.getDesc(landingunit)

local landingunitname = Unit.getName(landingunit)

blah

blah

end

 

 

 

 

You also need to tell DCS about your event handler (function needs to be defined first)

 

world.addEventHandler(arrivaltableINT) --trigger function arrivaltableINT on world event

 

I inherited the above myself from Snafu so there may be other ways of doing it, if you look in GCICAP you will see that same routine now also traps takeoffs and spawns if you wanted to see examples of those.

Posted

 

function arrivaltableINT:onEvent(event)

--CAP or GCI aircraft landing increase supply and get included in the list of landing aircraft for despawn

if (world.event.S_EVENT_LAND == event.id)

then

if event.initiator ~= nil

then

local landingunit = event.initiator

local ldesc = Unit.getDesc(landingunit)

local landingunitname = Unit.getName(landingunit)

blah

blah

end

 

 

 

 

You also need to tell DCS about your event handler (function needs to be defined first)

 

world.addEventHandler(arrivaltableINT) --trigger function arrivaltableINT on world event

 

I inherited the above myself from Snafu so there may be other ways of doing it, if you look in GCICAP you will see that same routine now also traps takeoffs and spawns if you wanted to see examples of those.

 

Awesome, thanks for getting back to me. I will have a play about and see if I can get the desired result.

Windows 10 64bit, Intel i7 6700K, 32GB Corsair 2400Mhz, 970 NVMe 500Gb SSD, GeForce 2080 super, HP Reverb, VKB GF PRO, Thrustmaster Warthog throttle, Thrustmaster Pendular rudders, Windows + DCS :thumbup:

 

My youtube channel

  • Recently Browsing   0 members

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