SelectedUnit in RangeTool
Moderators: angster, RoryAndersonCDT, michaelm75au, MOD_Command
SelectedUnit in RangeTool
A smal question: is it possible to use the ScenEdit_SelectedUnits() in the Tool_Range. The first is a GuiD. If so what am I to use in the second part of the tool.
with regards
with regards
-
KnightHawk75
- Posts: 1850
- Joined: Thu Nov 15, 2018 7:24 pm
RE: SelectedUnit in RangeTool
yes.
Just grab the guid of the selected unit(s) for the first, the second param is either the guid of another unit you are ranging too, or a location table.
Example function you can use and adapt for your needs.
Just grab the guid of the selected unit(s) for the first, the second param is either the guid of another unit you are ranging too, or a location table.
Example function you can use and adapt for your needs.
Code: Select all
local function processUnitsForRangeAirandShip(toLocationOrUnitGuid)
local range;
local DestUnit;
if (type(toLocationOrUnitGuid) == 'table') then
DestUnit = nil;
else
DestUnit = ScenEdit_GetUnit({guid=toLocationOrUnitGuid});
end
local sUnits=ScenEdit_SelectedUnits(); --get the list.
Code: Select all
-- compile a list of all units and contacts.
local myTempTable = {}
if(sUnits.units ~=nil) then --validate it
for k,v in pairs(sUnits.units) do
table.insert(myTempTable,{name= v.name,guid = v.guid})
end
end
if(sUnits.contacts ~=nil) then
for k,v in pairs(sUnits.contacts) do
table.insert(myTempTable,{name= v.name,guid = v.guid})
end
end
sUnits = nil; --don't need it anymore.
Code: Select all
--now process the combined table of units and contacts.
if(#myTempTable > 0) then --if our temptable has more than 0 entries.
local u;
for k,v in pairs(myTempTable) do --loop though selected unit table
u = VP_GetUnit({guid=v.guid}); --get the unit via guid or contact guid. just used for example.
if((u ~=nil) and (u.type == 'Aircraft' or u.type=='Ship')) then --only attempt for aircraft or ships.
range = Tool_Range(v.guid, toLocationOrUnitGuid) --guid of selected unit, guid or location table of destination
-- .. do what you want here'ish.
if (DestUnit == nil) then --we are a location.
print(string.format( 'Range from %s to destination is %s ',tostring(v.name), tostring(range)));
else
print(string.format( 'Range from %s to unit %s is %s', tostring(v.name), tostring(DestUnit.name),tostring(range)));
end
end
u = nil; --clear before iterate
end --end for
end --end if
myTempTable = nil;
end
Code: Select all
-- call with either the destination unit guid or location table.
processUnitsForRangeAirandShip('4FH7PU-0HM3HVNP3NNLS')
processUnitsForRangeAirandShip({latitude='33.1991547589118', longitude='138.376876749942'})
prints in my sample of 1 aircraft, 1 ship and 1 sub selected and "A base" unit as the destination guid:
Range from 3MN-1 Bison B [Bomber] to unit A Base is 723.50629978241
Range from LUSV to unit A Base is 788.83927325605
Range from 3MN-1 Bison B [Bomber] to destination is 5984.4327076228
Range from LUSV to destination is 6093.4341254081
RE: SelectedUnit in RangeTool
thanks again. The whole LUA is still very compex for me to grasp. Gonna try tonight.
And again I have more questions, sorry. But could a result been inseted in a message via a special action? I'll also try tonight but probably won't have a clue.
with regards
And again I have more questions, sorry. But could a result been inseted in a message via a special action? I'll also try tonight but probably won't have a clue.
with regards
-
KnightHawk75
- Posts: 1850
- Joined: Thu Nov 15, 2018 7:24 pm
RE: SelectedUnit in RangeTool
Yup you could include the result in whatever you want, just note it's a float so tostring() it before using it as string. Yes the above it a slightly more complex example, but I included to show how it might be used while dealing with more than one selected units, and it has some basic error checking, and highlight some re-usability. The key answer to your question was 'v.guid' above, when dealing with a selectedUnits return table.
Here is another example,obviously you don't have to wrap things in a function but I do it out of habit so that I can reuse (copy pasta and tweak) stuff more easily and most of the time my things sit in global functions anyway, but that's another topic. This one sends a message if range is less than certain amount, and rounds the range to 2 digits after the decimal point before converting to string.
If you have a very specific thing you are trying to do just let me know can probably give you a very specific example relating to what it is you want. If you have any question about what a line does, or why it's there etc... just ask.
Sure change the lines print(...bla bla bla ) to ScenEdit_SpecialMessage(sidename, bla bla bla),"But could a result been inseted in a message via a special action?"
Here is another example,obviously you don't have to wrap things in a function but I do it out of habit so that I can reuse (copy pasta and tweak) stuff more easily and most of the time my things sit in global functions anyway, but that's another topic. This one sends a message if range is less than certain amount, and rounds the range to 2 digits after the decimal point before converting to string.
Code: Select all
local function rangeCheckLtSendMyMessage(UnitGuid,toLocationOrUnitGuid,NM,TheSide)
local range; --declare local var
local theMsg ='<p>Alert!</p><p>';
local u; --declare var for unit
if((NM == nil) or type(NM) ~= 'number') then NM=500; end --set a default if NM was left empty.
if((TheSide==nil) or type(TheSide) ~= 'string') then --validate TheSide parameter isn't empty.
print('rangeCheckLtSendMyMessage() Error: You are missing the side parameter. Aborting.');
return;
else
u = ScenEdit_GetUnit({guid=UnitGuid})
if (u ~=nil) then --make sure we were able to get the unit.
range = Tool_Range(UnitGuid, toLocationOrUnitGuid) --get the range as decimal number
if (range < NM) then --if range vale < NM parameter send message.
theMsg = theMsg .. string.format('Unit %s is %.2f nm from target unit or location.</p>', tostring(u.name), tostring(range)) --add to existing msg
ScenEdit_SpecialMessage(TheSide, theMsg,{latitude = u.latitude,longitude = u.longitude}); --send the msg
end
else --handle missing unit.
print('rangeCheckLtSendMyMessage() Error: unit no longer exists, or could not obtain unit.');
end
end
end --end func
Code: Select all
--now use it
--check if a certain specific unit is less than 500nm from my carrier.
--send msg if it is.
rangeCheckLtSendMyMessage( 'GUIDOF-SOURCEUNIT001', 'GUIDOF-MYCARRIER0005',500, 'RedSide' )
--check if any 'Aircraft' on an entire side are less than 300nm from my carrier.
--and send msg for each if they are.
local objSide = VP_GetSide({name='BlueSide'});
local filteredUnits = objSide:unitsBy('Aircraft');
if ((filteredUnits ~=nil) and #filteredUnits > 0) then --then we have some units.
for k,v in pairs(filteredUnits) do -- do a for-each on all units in the list.
rangeCheckLtSendMyMessage(v.guid,'GUIDOF-MYCARRIER0005',300,'RedSide');
end
end
filterUnits = nil; --explicitly release memory, just habit
objSide = nil; --explicitly release memory, just habit
RE: SelectedUnit in RangeTool
I'strugling. I put your text in the lua console including the first calling of the function. Got: ERROR: [string "Console"]:33: attempt to call a nil value (global 'processUnitsForRangeAirandShip')
Change the calling in processUnitsForRange('50PVO4-0HM3LUPQ3KCDV'). Got no reply in lua console.
Selected the unit that is Guid in the calling, got: Range from P 840 Holland to unit P 840 Holland is 0.0
The selected unit unit in the first try was an A/C of the Civilian side.
Sorry to ask again, not easy for me to fully understand the your text. Appriciate the help a lot.
with regards
Same question (I think), got the special message working it I put the whole text in. Should I do that in another way with less text in the special action or is this the way it is intended.
grts GJ
Change the calling in processUnitsForRange('50PVO4-0HM3LUPQ3KCDV'). Got no reply in lua console.
Selected the unit that is Guid in the calling, got: Range from P 840 Holland to unit P 840 Holland is 0.0
The selected unit unit in the first try was an A/C of the Civilian side.
Sorry to ask again, not easy for me to fully understand the your text. Appriciate the help a lot.
with regards
Same question (I think), got the special message working it I put the whole text in. Should I do that in another way with less text in the special action or is this the way it is intended.
grts GJ
-
KnightHawk75
- Posts: 1850
- Joined: Thu Nov 15, 2018 7:24 pm
RE: SelectedUnit in RangeTool
I renamed the function while testing the sample and in the cut paste forgot to grab the renamed first line it in the top of the post. ie... it read:
local function processUnitsForRange vs
local function processUnitsForRangeAirandShip
--
Very sorry, corrected now. re-paste post #1 sample function and you shouldn't get the nil value errors.
If the latter and you are not in God Mode, then yes then the guids of other sides will not be in the sUnits.units but in sUnits.contacts, and they're contact guids not unit guids, so it wouldn't print anything. If you want your code to handle that you'd also have to iterate though the selected units contacts table (sUnits.contacts), and use VP_GetUnit() to grab the unit since it will handle the contact guid to unit guid conversion for you.
I have updated post #1 one to now include it handling "contacts" as well your own "units". Also shows you how to build a combined list.
local function processUnitsForRange vs
local function processUnitsForRangeAirandShip
--
Very sorry, corrected now. re-paste post #1 sample function and you shouldn't get the nil value errors.
Well you wouldn't if nothing was selected or what was wasn't an aircraft or ship.Change the calling in processUnitsForRange('50PVO4-0HM3LUPQ3KCDV'). Got no reply in lua console.
Yes if you select the same unit as what you're ranging against you would logically get 0.0 as a range.Selected the unit that is Guid in the calling, got: Range from P 840 Holland to unit P 840 Holland is 0.0
Which is the first try, the one with the error or the one where you called processUnitsForRange('50PVO4-0HM3LUPQ3KCDV')The selected unit unit in the first try was an A/C of the Civilian side.
If the latter and you are not in God Mode, then yes then the guids of other sides will not be in the sUnits.units but in sUnits.contacts, and they're contact guids not unit guids, so it wouldn't print anything. If you want your code to handle that you'd also have to iterate though the selected units contacts table (sUnits.contacts), and use VP_GetUnit() to grab the unit since it will handle the contact guid to unit guid conversion for you.
I have updated post #1 one to now include it handling "contacts" as well your own "units". Also shows you how to build a combined list.
RE: SelectedUnit in RangeTool
Thanks again for you're help and time.
with regards
with regards
RE: SelectedUnit in RangeTool
Sorry to keep asking questions I'm more at sea sitting behind the sensors we simulate in the game than the LUA. But keep trying. If I load you're first post in the LUA console it works great.
Should I be able to first load the function (I think that are the 3 blocks of you're text) and than later only load the call function. My brainn would think I got the same reslut but it doesn't. Hoping you can and will explain why that is. (than I get a nil)
with regards
Should I be able to first load the function (I think that are the 3 blocks of you're text) and than later only load the call function. My brainn would think I got the same reslut but it doesn't. Hoping you can and will explain why that is. (than I get a nil)
with regards
RE: SelectedUnit in RangeTool
I tried the alert text in a event and that works nicely. I also tried to get an alert when that unit comes within the assigned distance. Made event with trigger every 5 seconds. Result is that I get the message every 5 seconds cause I had to make it repeatable. Would there be a way that it checks every 5 seconds untill the message is send and then the event goes to inactive?
with regards
with regards
-
KnightHawk75
- Posts: 1850
- Joined: Thu Nov 15, 2018 7:24 pm
RE: SelectedUnit in RangeTool
ORIGINAL: Parel803
Should I be able to first load the function (I think that are the 3 blocks of you're text) and than later only load the call function. My brainn would think I got the same reslut but it doesn't. Hoping you can and will explain why that is. (than I get a nil)
with regards
So if you remove the word local in front of the word function, yes you can just stick them in a script that runs on scene loadup, and it (they) will be accessible globally there after for you to reuse by just calling them from anywhere like in other lua scripts or special actions etc.
I tried the alert text in a event and that works nicely. I also tried to get an alert when that unit comes within the assigned distance. Made event with trigger every 5 seconds. Result is that I get the message every 5 seconds cause I had to make it repeatable. Would there be a way that it checks every 5 seconds untill the message is send and then the event goes to inactive?
with regards
You have two options there, with-in the event script itself after messaging the user you can disable the event itself. Another way is you can just have a global variable or stored value\marker in the scene itself control it.
for example:
Code: Select all
--Using Key's example
If ScenEdit_GetKeyValue("MyRepeatMarkerName") == '' then --it did not exist yet.
--....do my call to message the user...
--...now set the keyvalue so this part of the code never runs again.
ScenEdit_SetKeyValue("MyRepeatMarkerName","1") --set it to something.
end
--using the disable event example..
--...your code that you only want to run once here.
--...then disable the event.
ScenEdit_SetEvent("MyEventNameHere",{isActive=false}); --turn off this event from running again.
RE: SelectedUnit in RangeTool
KnightHawk,
thanks again, very nice to learn about it.
with regards
thanks again, very nice to learn about it.
with regards
-
KnightHawk75
- Posts: 1850
- Joined: Thu Nov 15, 2018 7:24 pm
RE: SelectedUnit in RangeTool
ORIGINAL: Parel803
KnightHawk,
thanks again, very nice to learn about it.
with regards
Glad to help. I'm not the best teacher but I'll do what I can, when I can.
RE: SelectedUnit in RangeTool
KnightHawk, teacher. Again a question if I may. I put in this as a function
function processUnitsForRangeAirandShip(toLocationOrUnitGuid)
local range;
local DestUnit;
if (type(toLocationOrUnitGuid) == 'table') then
DestUnit = nil;
else
DestUnit = ScenEdit_GetUnit({guid=toLocationOrUnitGuid});
end
local sUnits=ScenEdit_SelectedUnits(); --get the list.
-- compile a list of all units and contacts.
local myTempTable = {}
if(sUnits.units ~=nil) then --validate it
for k,v in pairs(sUnits.units) do
table.insert(myTempTable,{name= v.name,guid = v.guid})
end
end
if(sUnits.contacts ~=nil) then
for k,v in pairs(sUnits.contacts) do
table.insert(myTempTable,{name= v.name,guid = v.guid})
end
end
sUnits = nil; --don't need it anymore.
--now process the combined table of units and contacts.
if(#myTempTable > 0) then --if our temptable has more than 0 entries.
local u;
for k,v in pairs(myTempTable) do --loop though selected unit table
u = VP_GetUnit({guid=v.guid}); --get the unit via guid or contact guid. just used for example.
if((u ~=nil) and (u.type == 'Aircraft' or u.type=='Ship')) then --only attempt for aircraft or ships.
range = Tool_Range(v.guid, toLocationOrUnitGuid) --guid of selected unit, guid or location table of destination
-- .. do what you want here'ish.
if (DestUnit == nil) then --we are a location.
ScenEdit_SpecialMessage('Blue', string.format( 'Range from %s to destination is %s ',tostring(v.name), tostring(range)));
else
ScenEdit_SpecialMessage('Blue', string.format( 'Range from %s to unit %s is %s', tostring(DestUnit.name), tostring(v.name), tostring(range)));
end
end
u = nil; --clear before iterate
end --end for
end --end if
myTempTable = nil;
end
Then I put the function call in a special action. Got the correct message but also a error message. Can you with a quick look see what I did wrong? I changed position of the reporting unit and selected unit in the 'print' line.
with regards. My learning is more a trial and error (and asking help)
function processUnitsForRangeAirandShip(toLocationOrUnitGuid)
local range;
local DestUnit;
if (type(toLocationOrUnitGuid) == 'table') then
DestUnit = nil;
else
DestUnit = ScenEdit_GetUnit({guid=toLocationOrUnitGuid});
end
local sUnits=ScenEdit_SelectedUnits(); --get the list.
-- compile a list of all units and contacts.
local myTempTable = {}
if(sUnits.units ~=nil) then --validate it
for k,v in pairs(sUnits.units) do
table.insert(myTempTable,{name= v.name,guid = v.guid})
end
end
if(sUnits.contacts ~=nil) then
for k,v in pairs(sUnits.contacts) do
table.insert(myTempTable,{name= v.name,guid = v.guid})
end
end
sUnits = nil; --don't need it anymore.
--now process the combined table of units and contacts.
if(#myTempTable > 0) then --if our temptable has more than 0 entries.
local u;
for k,v in pairs(myTempTable) do --loop though selected unit table
u = VP_GetUnit({guid=v.guid}); --get the unit via guid or contact guid. just used for example.
if((u ~=nil) and (u.type == 'Aircraft' or u.type=='Ship')) then --only attempt for aircraft or ships.
range = Tool_Range(v.guid, toLocationOrUnitGuid) --guid of selected unit, guid or location table of destination
-- .. do what you want here'ish.
if (DestUnit == nil) then --we are a location.
ScenEdit_SpecialMessage('Blue', string.format( 'Range from %s to destination is %s ',tostring(v.name), tostring(range)));
else
ScenEdit_SpecialMessage('Blue', string.format( 'Range from %s to unit %s is %s', tostring(DestUnit.name), tostring(v.name), tostring(range)));
end
end
u = nil; --clear before iterate
end --end for
end --end if
myTempTable = nil;
end
Then I put the function call in a special action. Got the correct message but also a error message. Can you with a quick look see what I did wrong? I changed position of the reporting unit and selected unit in the 'print' line.
with regards. My learning is more a trial and error (and asking help)
- Attachments
-
- testDistance.jpg (224.37 KiB) Viewed 434 times
-
KnightHawk75
- Posts: 1850
- Joined: Thu Nov 15, 2018 7:24 pm
RE: SelectedUnit in RangeTool
First thing I see is in your special action you have an extra () after the function call.
Change that and let me know if all is well then.
Code: Select all
processUnitsForRangeAirandShip('Your guid here') ()
should be
processUnitsForRangeAirandShip('Your guid here');
RE: SelectedUnit in RangeTool
Thx that was it, bit stupid but nice if stuff works 
now to try the 5 sec stop.
thx again, regards GJ
now to try the 5 sec stop.
thx again, regards GJ
RE: SelectedUnit in RangeTool
I tried the SetEvent. This disables the event after first time fired. Probably logical but I got a inbound unit which is outside the given range at start.
So the first few 'scenario event fired' don't give the alert message.
Not sure if it's possible what I want but I like the event to run untill the actual 'alert' message is send.
Hope my writing makes some sense. Now to study on the key example.
with regards GJ
So the first few 'scenario event fired' don't give the alert message.
Not sure if it's possible what I want but I like the event to run untill the actual 'alert' message is send.
Hope my writing makes some sense. Now to study on the key example.
with regards GJ
RE: SelectedUnit in RangeTool
was thinking about enter area but disregarded it
-
KnightHawk75
- Posts: 1850
- Joined: Thu Nov 15, 2018 7:24 pm
RE: SelectedUnit in RangeTool
Shouldn't be a problem so long as the setEvent to inactive only triggers when the message is sent.ORIGINAL: Parel803
I tried the SetEvent. This disables the event after first time fired. Probably logical but I got a inbound unit which is outside the given range at start.
So the first few 'scenario event fired' don't give the alert message.
Not sure if it's possible what I want but I like the event to run untill the actual 'alert' message is send.
Hope my writing makes some sense. Now to study on the key example.
with regards GJ
An example of #1 tweaked for that.
Code: Select all
... clipped
range = Tool_Range(UnitGuid, toLocationOrUnitGuid) --get the range as decimal number
if (range < NM) then --if range vale < NM parameter send message.
theMsg = theMsg .. string.format('Unit %s is %.2f nm from target unit or location.</p>', tostring(u.name), tostring(range)) --add to existing msg
ScenEdit_SpecialMessage(TheSide, theMsg,{latitude = u.latitude,longitude = u.longitude}); --send the msg
ScenEdit_SetEvent("YourEventNameHere",{isActive=false}); --turn off this event from running again.
end
...clipped
RE: SelectedUnit in RangeTool
Thanks for youre time, gonna try.
with regards
with regards
RE: SelectedUnit in RangeTool
dear teacher, it works great.
Thx also for you're time and work
with regards GJ
Thx also for you're time and work
with regards GJ