Jump to content

Recommended Posts

Posted

Hi,

 

I'm looking for a way to add or remove client slots in an ongoing mission using the mission editor conditions.

I was trying to use the group activate and deactive, but it doesn't work, I'm guessing because if the slot is not filled the object is not even spawned therefore there is nothing to deactivate, and same goes for activating, I had a late activation client plane, it was visible in the selection but coulnd't spawn with it, even after the group activate command ran on it.

 

I'd appriciate any insight on how to accomplish this using any means... sripting engine, mission editor, MIST?

 

Thanks,

Xcom

Posted

About the only way you can do it is to just have all of the slots there to begin with and periodically deactivate a group continuously when the conditions aren't met to allow it to exist.

 

Continuously> Client X is alive and Flag 1 is False> Group Deactivate or do script> if Unit.getByName('clientAircraftName') then

Unit.getByName('cientAircraftName'):destroy()

end

 

Once> whatever conditions> Set Flag 1 True

  • Like 1

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

Seems to be working great.

 

One more question, is there a way to do that if I start a continues trigger that deactivates a group, will not deactivate a group that is manned?

 

What heppends in the mission is that once an airbase is captured, the groups that have been spawned in that airbase are now disabled and thus any client that is flying those planes get despawned, I'm looking for a way to deactivate the group only after that manned flight is over either killed/destroyed or despawned.

 

I was thinking about something like -

 

local Group = 'groupname'

function checkman ()
if Group.isExist(Group) == true then
timer.scheduleFunction(checkman, nil, timer.getTime() + 1)
elseif
trigger.action.deactivateGroup(Group)
end
end

 

I'm fairly new to coding so I'd appriciate any help :)

Posted

Yeah something like that would work.

 

I would make two tables. One is a list of aircraft to despawn and the other is a table of all alive clients that would be effected by the script. I'd periodically iterate through the list to see if the players have despawned. Once the aircraft has despawned add it to the list of aircraft that will automatically deactivate.

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

I'm trying to figure out how to use tables to do this but can't seem to get it right.

I got something like this going -

 

local Group = "Gelendzhik Blue P-51D"

function checkman ()
for i=1,2,3,4,5 do
if Group.isExist(Group.." #00"..i) == true then
	local despawn(i) = Group.." #00"..i
elseif
	trigger.action.deactivateGroup(Group.." #00"..i)
end
end

function deactivateman()
for i=1,2,3,4,5 do
if not despawn(i) == NULL then
	trigger.action.deactivateGroup(despawn(i))
esleif
end
end


timer.scheduleFunction(deactivateman, nil, timer.getTime() + 3)
end

 

But I'm thinking I'm just messing it all up.

Got any examples on how to use the tables?

 

Thanks

Posted

This is a great website for learning lua: http://lua-users.org/wiki/TutorialDirectory

 

 

 

local listOfUnits = {'client1', 'client2'... etc}
local deactivateUnits = {}

function checkClients()
for index, name in pairs(listOfUnits) do
	if not Unit.getByName(name) then
		table.insert(deactivateUnits, name)
		table.remove(listOfUnits, index)
	end
end
if #deactivateUnits > 0 then
	for i = 1, #deactivateUnits do
		if Unit.getByName(deactivateUnits[i]) then
			Unit.getByName(deactivateUnits[i]):destroy()
		end
	end
end
timer.scheduleFunction(checkClients, nil, timer.getTime() + 3)
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)

Thanks Grimes.

 

I'm planning on doing the following:

using global tables in the initialization script -

 

BlueUnitsGelen = {'Gelendzhik Blue P-51D #001', 'Gelendzhik Blue P-51D #002','Gelendzhik Blue P-51D #003','Gelendzhik Blue P-51D #004','Gelendzhik Blue P-51D #005'}

RedUnitsGelen = {'Gelendzhik Red P-51D #001', 'Gelendzhik Red P-51D #002','Gelendzhik Red P-51D #003','Gelendzhik Red P-51D #004','Gelendzhik Red P-51D #005'}

BlueUnitsNovo = {'Novorossiysk Blue P-51D #001', 'Novorossiysk Blue P-51D #002','Novorossiysk Blue P-51D #003','Novorossiysk Blue P-51D #004'}

RedUnitsNovo = {'Novorossiysk Red P-51D #001', 'Novorossiysk Red P-51D #002','Novorossiysk Red P-51D #003','Novorossiysk Red P-51D #004'}

BlueUnitsKrymsk = {'Krymsk Blue P-51D #001', 'Krymsk Blue P-51D #002','Krymsk Blue P-51D #003','Krymsk Blue P-51D #004'}

RedUnitsKrymsk = {'Krymsk Red P-51D #001', 'Krymsk Red P-51D #002','Krymsk Red P-51D #003','Krymsk Red P-51D #004'}

BlueUnitsAnapa = {'Anapa Blue P-51D #001', 'Anapa Blue P-51D #002','Anapa Blue P-51D #003','Anapa Blue P-51D #004','Anapa Blue P-51D #005','Anapa Blue P-51D #006','Anapa Blue P-51D #007'}

RedUnitsAnapa = {'Anapa Red P-51D #001', 'Anapa Red P-51D #002','Anapa Red P-51D #003','Anapa Red P-51D #004','Anapa Red P-51D #005','Anapa Red P-51D #006','Anapa Red P-51D #007'}

 

 

 

And then using your function if a coalition has an aerodrome, switched condition is met -

 

checkClients(BlueUnitsGelen) --changes for each trigger to the correct table

local deactivateUnits = {}

 

function checkClients(TABLE)

for index, name in pairs(TABLE) do

if not Unit.getByName(name) then

table.insert(deactivateUnits, name)

table.remove(listOfUnits, index)

end

end

if #deactivateUnits > 0 then

for i = 1, #deactivateUnits do

if Unit.getByName(deactivateUnits) then

Unit.getByName(deactivateUnits):destroy()

end

end

end

timer.scheduleFunction(checkClients, nil, timer.getTime() + 1)

end

 

 

Now the issue is that if I want to keep the slots deactivated until the aerodrome is recaptured and the condition of the trigger would no longer be met, will the function stop if the condition of the trigger is no longer met?

Also one more thing, what exactly does this command do?

Unit.getByName(deactivateUnits):destroy()

 

I was thinking about using this -

trigger.action.deactivateGroup(deactivateUnits)

 

Thanks

Edited by xcom
Posted

Its basically the same thing. It just force despawns the object from the mission. You can make a whole city disappear if you know what you are doing. :)

 

The only difference is that I know 100% for sure that Object.destroy() works on clients. Unit.getByName('unit') inherits the Object class. Thus you can use Unit.getByName('name'):destroy().

 

I'd need to double check to see if trigger.action.deactivateGroup() works, but it should.

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)

Well it's not working, and I'm not sure exactly why.

 

What I did so far is -

loaded an initial script with the tables and the function (script attached)

 

did a trigger -

Continues - coalition has aerodrome - do script:

local TABLE = BlueUnitsGelen

local deactivateUnits = {}

checkClients()

 

 

I get a script error on the local TABLE = BlueUnitsGelen

I'm thinking it's something with the way I'm calling the function or using the global or local table.

 

Also, is it correct to run this function on a continues trigger?

My goal is that whoever is in a slot that spawned on the airfield will not get despawned but only the unspawned slot will be deactivated.

 

P.S - Grimes are you ever in the Hoggit TS? I can jump in there and just troubleshoot faster...

 

Thanks again.

 

 

 

EDIT -

This is the latest I'm trying to do and still not working, can you tell me what I'm doing wrong?

the script -

http://pastebin.com/8dqbxhJb

 

the error is attached as an image.

AirbaseCaptureDB.lua

error.thumb.jpg.114d263622f1056002a16c0db435c071.jpg

Edited by xcom
Posted

Updated the script to hold a function that will check which base has which coalition and then run the checkclients function correctly -

 

 

BlueGelendzhik = {"Gelendzhik Blue P-51D #001", "Gelendzhik Blue P-51D #002","Gelendzhik Blue P-51D #003","Gelendzhik Blue P-51D #004","Gelendzhik Blue P-51D #005"}

RedGelendzhik = {"Gelendzhik Red P-51D #001", "Gelendzhik Red P-51D #002","Gelendzhik Red P-51D #003","Gelendzhik Red P-51D #004","Gelendzhik Red P-51D #005"}

BlueNovorossiysk = {"Novorossiysk Blue P-51D #001", "Novorossiysk Blue P-51D #002","Novorossiysk Blue P-51D #003","Novorossiysk Blue P-51D #004"}

RedNovorossiysk = {"Novorossiysk Red P-51D #001", "Novorossiysk Red P-51D #002","Novorossiysk Red P-51D #003","Novorossiysk Red P-51D #004"}

BlueKrymsk = {"Krymsk Blue P-51D #001", "Krymsk Blue P-51D #002","Krymsk Blue P-51D #003","Krymsk Blue P-51D #004"}

RedKrymsk = {"Krymsk Red P-51D #001", "Krymsk Red P-51D #002","Krymsk Red P-51D #003","Krymsk Red P-51D #004"}

BlueAnapa = {"Anapa Blue P-51D #001", "Anapa Blue P-51D #002","Anapa Blue P-51D #003","Anapa Blue P-51D #004","Anapa Blue P-51D #005","Anapa Blue P-51D #006","Anapa Blue P-51D #007"}

RedAnapa = {"Anapa Red P-51D #001", "Anapa Red P-51D #002","Anapa Red P-51D #003","Anapa Red P-51D #004","Anapa Red P-51D #005","Anapa Red P-51D #006","Anapa Red P-51D #007"}

deactivateUnits = {}

Bases = {"Gelendzhik", "Novorossiysk", "Krymsk", "Anapa"}

 

 

function checkClients(TABLE)

for index, name in pairs(TABLE) do

if not Unit.getByName(name) then

table.insert(deactivateUnits, name)

trigger.action.outText("found unit for deactivation "..name, 1) --debug

end

end

if #deactivateUnits > 0 then

for i = 1, #deactivateUnits do

Unit.getByName(deactivateUnits):destroy()

trigger.action.outText("deactivating unit - "..deactivateUnits, 1) --debug

end

end

end

 

 

function checkairbase()

for index, name in pairs(Bases) do

if CoalitionObject.getCoalition(name) == "RED" then

checkClients("Red"..name)

elseif CoalitionObject.getCoalition(name) == "BLUE" then

checkClients("Blue"..name)

elseif CoalitionObject.getCoalition(name) == "NEUTRAL" then

checkClients("Blue"..name)

checkClients("Red"..name)

end

end

end

 

repeat

timer.scheduleFunction(checkairbase, nil, timer.getTime() + 1)

until #bases == 0

 

 

Obviously, not working :(

Could someone take a look at tell me whats wrong?

Posted

checkClients("Red"..name) is passing a string of the table name, but not the actual table itself. As a result the in pairs() is run on a string instead of a table. I almost think you should organize the unit listings as one bigger nested table in the format of:

 

clients = {
 ['red'] = {
   ['gelendzhik'] = {"Gelendzhik Red P-51D #001", "Gelendzhik Red P-51D #002","Gelendzhik Red P-51D #003","Gelendzhik Red P-51D #004","Gelendzhik Red P-51D #005"},
  etc...
 },
 ['blue'] = {
   ['gelendzhik'] = {"Gelendzhik Blue P-51D #001", "Gelendzhik Blue P-51D #002","Gelendzhik Blue P-51D #003","Gelendzhik Blue P-51D #004","Gelendzhik Blue P-51D #005"},
 etc...
 },
}

 

And then change the function to be something like...

function checkClients(coaName, airbase)

for index, name in pairs(clients[coaName][airbase]) do

 

Also I'd make sure to use string.lower() on the input values to make sure that the coalition returned equals 'red' and not 'RED' as those values are NOT the same when it comes to comparing strings.

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

Thanks Grimes,

 

I've used your suggestion with the big nested table.

The procedure I'll follow is -

Initialize the following script with the initialization script -

 

clients = {

['blue'] = {

['gelendzhik'] = {"Gelendzhik Blue P-51D #001", "Gelendzhik Blue P-51D #002","Gelendzhik Blue P-51D #003","Gelendzhik Blue P-51D #004","Gelendzhik Blue P-51D #005"},

['novorossiysk'] = {"Novorossiysk Blue P-51D #001", "Novorossiysk Blue P-51D #002","Novorossiysk Blue P-51D #003","Novorossiysk Blue P-51D #004"},

['krymsk'] = {"Krymsk Blue P-51D #001", "Krymsk Blue P-51D #002","Krymsk Blue P-51D #003","Krymsk Blue P-51D #004"},

['anapa'] = {"Anapa Blue P-51D #001", "Anapa Blue P-51D #002","Anapa Blue P-51D #003","Anapa Blue P-51D #004","Anapa Blue P-51D #005","Anapa Blue P-51D #006","Anapa Blue P-51D #007"},

},

['red'] = {

['gelendzhik'] = {"Gelendzhik Red P-51D #001", "Gelendzhik Red P-51D #002","Gelendzhik Red P-51D #003","Gelendzhik Red P-51D #004","Gelendzhik Red P-51D #005"},

['novorossiysk'] = {"Novorossiysk Red P-51D #001", "Novorossiysk Red P-51D #002","Novorossiysk Red P-51D #003","Novorossiysk Red P-51D #004"},

['krymsk'] = {"Krymsk Red P-51D #001", "Krymsk Red P-51D #002","Krymsk Red P-51D #003","Krymsk Red P-51D #004"},

['anapa'] = {"Anapa Red P-51D #001", "Anapa Red P-51D #002","Anapa Red P-51D #003","Anapa Red P-51D #004","Anapa Red P-51D #005","Anapa Red P-51D #006","Anapa Red P-51D #007"},

},

}

 

local deactivateUnits = {}

 

 

function checkClients(coaName, airbase)

for index, name in pairs(clients[coaName][airbase]) do

if not Unit.getByName(name) then

table.insert(deactivateUnits, name)

trigger.action.outText("found unit for deactivation "..name, 1) --debug

end

end

if #deactivateUnits > 0 then

for i = 1, #deactivateUnits do

Unit.getByName(deactivateUnits):destroy()

trigger.action.outText("deactivating unit - "..deactivateUnits, 1) --debug

end

end

end

 

 

 

After that I'll just call the correct function with the editor triggers -

Continues Action - Coalition has aerodrome - checkClients(coaName, airbase)

 

Hope this will work, I'll check it tonight when I get home.

Thanks again for the help Grimes:thumbup:

Posted (edited)

I'm getting the attached error.

 

It seems that the error is coming from the line -

Unit.getByName(deactivateUnits[i]):destroy()

 

Anyone got any idea what does it mean?

Can't really debug this one...

 

 

EDIT:

 

OK, it's working!

Only problem now is that the table deactivateUnits doesn't get units removed, meaning that if gelendzhik is captured by red, blue and red will still be in that table and thus they are all deactivated.

I tried adding table.remove(deacivateUnits, i) in the 2nd for loop, but i'm getting an error (attached).

 

The latest version -

http://pastebin.com/K9yYBbnd

error3.jpg.30883400adf52c10fc66e2171f85059a.jpg

Edited by xcom
Posted

What is the purpose of the if - line that throws the error? Is it to check if the unit exist? If so, try making it more explicit. Also try changing the for loop into a for pairs loop and then clearing the whole table, something like this:

for index, UnitToDeac in pairs(deactivateUnits) do
  if Unit.getByName(UnitToDeac) != nil then
       Unit.getByName(UnitToDeac):destroy()
  end
end
deactivateUnits = {}

As another check, you might make the deactivateUnits and clients tables global (remove the "local" part of the initialization) as Im not sure how the scoping works when running scripts between different triggers.

DCS AJS37 HACKERMAN

 

There will always be bugs. If everything is a priority nothing is.

Posted

The problem is the following:

You have a loop running for as many items as you have in the table. But while you are going through the table, you delete items from it, thus shortening it. Therefore, at some point, you will start referencing indices in the table that don't exist anymore, because the items have shifter further forward.

 

However, the fix is easy: Work the table back to front.

Just change the loop to:

 

for i = #deactivateUnits, 1, -1 do

 

You can also get rid of the if before that. If there is nothing in the table, the loop will not run, but that is only cosmetics

aka: Baron

[sIGPIC][/sIGPIC]

Posted

Thanks guys.

 

@RagnarDa

The point of the 2nd if is to wait until the slot has been activated and then deactive it, this is because until the slot has not been activated the returned value would be nil and thats why I had the previous error.

I tried it with the For in pairs, it doesn't return an error but it still doesn't work.

 

I then went on and searched this forum, found this -

http://forums.eagle.ru/showthread.php?t=107222&highlight=table.remove

 

@St3v3f

I just saw this solution in the above link, I'll try it again tonight.

 

 

Do you guys recommand to use the deactivateUnits table as global or local? does it even matter here?

Posted

Use local variables whenever you don't need them to be global. And I don't see the need for global here.

 

Only the function itself must be global (which you did), so you can call it from other triggers.

aka: Baron

[sIGPIC][/sIGPIC]

Posted

Well it does depend on wether the script is run in a global scope or not. If it is, anything local to the outermost scope would be global and the "local" part of an initialization would be unnecessary, or it is run in a non-global scope and variables local to the script would be inaccessible to other scripts. So in both cases you would want to use global variables.

DCS AJS37 HACKERMAN

 

There will always be bugs. If everything is a priority nothing is.

Posted

Also, sorry that my post from yesterday was so unclear (was very tired) but I was trying to get to the same point as st3v3f but had another solution. Did you try clearing the table _after_ you ran through it, like my example? Don't remember what made me abandon standard for - loops in Lua and replacing them with for pair() loops but I think there was a problem with their robustness. Might have been an earlier version of Lua.

DCS AJS37 HACKERMAN

 

There will always be bugs. If everything is a priority nothing is.

Posted (edited)

Just tested.

The error is gone but the effect is the same as if table.remove was not there.

 

I got 5 slots of each coalition in gelendzhik.

- at mission start gelendzhik is blue, blue slots are not getting deactivated & red slots are deactivated - works as expected.

- after red captures airfield, blue slots and red slots are getting deactivated - expected red slots to not be deactivated, only blue slots should be deactivated.

 

I think what is happening is that the deactivateUnits table still keeps the old values, the way I'm running this is with continues action while the aerodrome is captured, so if red has aerodrome blue slots are getting deactivated.

So I added the following after the last for ends -

for k in pairs(deactivateUnits) do
   deactivateUnits[k] = nil
end

 

This is so the function leaves the table deactivateUnits clean, doesn't seem to work.

RagnarDa, I also tried your way, same thing, the script stops working this way.

Edited by xcom
Posted

First, when looking at your previous pastebin I think the logic of the adding units to the deactivateUnits table is reversed. You're adding the units that doesn't exist, instead of the ones that do exist. Secondly, you don't need to go the way by adding the units to a table and then look through the table and destroy them. You could just destroy them in the first for loop, like this:

for index, name in pairs(clients[coaName][airbase]) do
       local _unit = Unit.getByName(name)
       if _unit != nil then
           _unit:destroy()
       end
   end

 

It would be *awesome* if you did make this into a dynamic script that could be put into any mission. It's a needed feature.

DCS AJS37 HACKERMAN

 

There will always be bugs. If everything is a priority nothing is.

Posted

I will definitly try to make this a dynamic script.

 

I think you missed something with the script logic, we have to first get the units that are NOT activated, meaning the units that have NOT spawned and only those units will be deactivated ONLY when someone spawns in with them, you cannot deactivate a unit that is not spawned in, you get the nil error.

 

This is the whole meaning of the script, it is done because I don't want to deactivate somoene who is currently flyin until he finishes his flight.

 

Otherwise I could just use the mission editors deactivate unit.

Posted

Ah! My bad. The way you thought about it was much better as not needing to destroy already airborne players.

 

My (new) guess as to why the slots get deactivated is because both triggers is running. Try changing them from continous into switched or something.

DCS AJS37 HACKERMAN

 

There will always be bugs. If everything is a priority nothing is.

Posted (edited)

Can't, need the units to keep getting deactivated, otherwise the slots would be free to take.

 

I was thinking of making the deactivateUnits table like the clients table and then just add to the relevant table, each coalition and airbase manages it's own, something like this -

 

local clients = {
 ['blue'] = {
   ['gelendzhik'] = {"Gelendzhik Blue P-51D #001", "Gelendzhik Blue P-51D #002","Gelendzhik Blue P-51D #003","Gelendzhik Blue P-51D #004","Gelendzhik Blue P-51D #005"},
   ['novorossiysk'] = {"Novorossiysk Blue P-51D #001", "Novorossiysk Blue P-51D #002","Novorossiysk Blue P-51D #003","Novorossiysk Blue P-51D #004"},
   ['krymsk'] = {"Krymsk Blue P-51D #001", "Krymsk Blue P-51D #002","Krymsk Blue P-51D #003","Krymsk Blue P-51D #004"},
   ['anapa'] = {"Anapa Blue P-51D #001", "Anapa Blue P-51D #002","Anapa Blue P-51D #003","Anapa Blue P-51D #004","Anapa Blue P-51D #005","Anapa Blue P-51D #006","Anapa Blue P-51D #007"},
 },
 ['red'] = {
   ['gelendzhik'] = {"Gelendzhik Red P-51D #001", "Gelendzhik Red P-51D #002","Gelendzhik Red P-51D #003","Gelendzhik Red P-51D #004","Gelendzhik Red P-51D #005"},
   ['novorossiysk'] = {"Novorossiysk Red P-51D #001", "Novorossiysk Red P-51D #002","Novorossiysk Red P-51D #003","Novorossiysk Red P-51D #004"},
   ['krymsk'] = {"Krymsk Red P-51D #001", "Krymsk Red P-51D #002","Krymsk Red P-51D #003","Krymsk Red P-51D #004"},
   ['anapa'] = {"Anapa Red P-51D #001", "Anapa Red P-51D #002","Anapa Red P-51D #003","Anapa Red P-51D #004","Anapa Red P-51D #005","Anapa Red P-51D #006","Anapa Red P-51D #007"},
 },
}

local deactivateUnits = {
 ['blue'] = {
   ['gelendzhik'] = {},
   ['novorossiysk'] = {},
   ['krymsk'] = {},
   ['anapa'] = {},
 },
 ['red'] = {
   ['gelendzhik'] = {},
   ['novorossiysk'] = {},
   ['krymsk'] = {},
   ['anapa'] = {},
 },
}

function checkClients(coaName, airbase)
for index, name in pairs(clients[coaName][airbase]) do
	if not Unit.getByName(name) then
		table.insert(deactivateUnits[coaName][airbase], name)
	end
end
   if #deactivateUnits[coaName][airbase] > 0 then
       for i = #deactivateUnits[coaName][airbase], 1, -1 do
		if Unit.getByName(deactivateUnits[coaName][airbase][i]) then
			Unit.getByName(deactivateUnits[coaName][airbase][i]):destroy()
			table.remove(deactivateUnits[coaName][airbase], i)
		end
	end
   end
end

 

Gonna check if it works.

 

EDIT -

 

Seems to be working as expected.

Gonna do some more tests, this 1 might be the one :)

Edited by xcom
  • Recently Browsing   0 members

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