Scan An Area for Units
Moderators: michaelm75au, angster, RoryAndersonCDT, MOD_Command
Scan An Area for Units
I am looking to create a hostage rescue scenario where rescue units will be inserted by air. In order to complete the scenario the player will have to pick up all the rescue team. I am trying to figure out a way to be able for the game to scan the AOE for any remaining units.
So the event trigger is set to "unit exits area". I need to create a script for the game to scan the AOE for any additional units. If none are present this will trigger the scenario end as the mission will be accomplished. If friends are still present the scenario will continue
In short, how do I make the game scan an area for friendly units?
So the event trigger is set to "unit exits area". I need to create a script for the game to scan the AOE for any additional units. If none are present this will trigger the scenario end as the mission will be accomplished. If friends are still present the scenario will continue
In short, how do I make the game scan an area for friendly units?
"We have met the enemy and they are ours" - Commodore O.H. Perry
- michaelm75au
- Posts: 12457
- Joined: Sat May 05, 2001 8:00 am
- Location: Melbourne, Australia
RE: Scan An Area for Units
Not sure of this but
Have an exit Event
Add (unit exits) trigger
Add a condition that checks to see if any of the units are still in the area (unit.inArea(...)), and return 'false' so event is cancelled
Have an exit Event
Add (unit exits) trigger
Add a condition that checks to see if any of the units are still in the area (unit.inArea(...)), and return 'false' so event is cancelled
Michael
RE: Scan An Area for Units
Yes, I see now how to do it. I am setting up an exclusion zone for the bad guys around the Area of Operation. Then setting up a condition to basically look for any good guys in the Exclusion Zone
Not having used conditions before, how do I get the lua script to return either "true" or "false" to the console so it knows if the event should proceed?
Not having used conditions before, how do I get the lua script to return either "true" or "false" to the console so it knows if the event should proceed?
"We have met the enemy and they are ours" - Commodore O.H. Perry
RE: Scan An Area for Units
So in full disclosure I attempted to clone this code from the SAM Response scenario by Zathred. However the code is not working
Here is what I wrote:
local badguys = VP_GetSide({Name='Bad Guys'})
local goodguys = VP_GetSide({Name='Good Guys'})
local c = VP_GetSide({goodguys.guid})
local AOO_Zone = badguys:getexclusionzone('Zone')
local z = AOEZone.area
local AOO_area = {}
for i,v in ipairs(z) do
table.insert(AOE_area, v.guid)
end
if (c ~= nil) then
for i,v in ipairs(c) do
if (v ~= nil and (v.type == 'Facility' and v.subtype == 'Mobile_Personnel')) then
local u = ScenEdit_GetUnit({guid=v.actualunitid})
if (v:inArea(AOEarea)) then
return false
end
end
return true
end
end
The Lua console tells me "it cannot find side" for one of the calls. Anyone who is more adept at Lua able to help me?
Here is what I wrote:
local badguys = VP_GetSide({Name='Bad Guys'})
local goodguys = VP_GetSide({Name='Good Guys'})
local c = VP_GetSide({goodguys.guid})
local AOO_Zone = badguys:getexclusionzone('Zone')
local z = AOEZone.area
local AOO_area = {}
for i,v in ipairs(z) do
table.insert(AOE_area, v.guid)
end
if (c ~= nil) then
for i,v in ipairs(c) do
if (v ~= nil and (v.type == 'Facility' and v.subtype == 'Mobile_Personnel')) then
local u = ScenEdit_GetUnit({guid=v.actualunitid})
if (v:inArea(AOEarea)) then
return false
end
end
return true
end
end
The Lua console tells me "it cannot find side" for one of the calls. Anyone who is more adept at Lua able to help me?
"We have met the enemy and they are ours" - Commodore O.H. Perry
RE: Scan An Area for Units
the 3rd line doesn't look right to me, it would be the same as line 2 as far as i can tell.
If line 3 is needed I think you need to have guid=goodguys.guid not just goodguys.guid.
Best way to trouble shoot is to take stuff out and use print statements to see if it is doing what you want, then build it up.
If line 3 is needed I think you need to have guid=goodguys.guid not just goodguys.guid.
Best way to trouble shoot is to take stuff out and use print statements to see if it is doing what you want, then build it up.
-
KnightHawk75
- Posts: 1850
- Joined: Thu Nov 15, 2018 7:24 pm
RE: Scan An Area for Units
So if I understand right you just want to know if all the good guys are out of the area at a give time right?
See attached sample scenario, choose a in editor. I threw all the code into a special action, move the units around and use the button to test results. When satisfied just copy it all into an lua action and create and event that fires however often you want the check done (or however else you chose to use it like in a condition), though I suggest 1min or more as it's a heavy function if a side has a ton of units of the type and\or subtype you're filtering though.
requires: 3 or more Reference points on Bad Guy's side (in the sample they are rp4,5,6,7 and part of a bad guy exclusion zone, but they don't have to be part of such). In fact you really don't even need RP's defined at all if you say want to just feed it a table of hard coded latitudes and longitudes points like
Code does not require any inarea triggers to exist or have fired on a unit, nor does it even use unit:inArea() as it has it's own inPolygon checking function which I find more reliable for this sort of thing.
Note when looking at the non-function code in the special action:
The last parameter to filter on subtype is optional, you can leave it blank or include the proper subtype code, 5002 is mobile personnel, 5001 is mobile vehicle,etc.
See attached sample scenario, choose a in editor. I threw all the code into a special action, move the units around and use the button to test results. When satisfied just copy it all into an lua action and create and event that fires however often you want the check done (or however else you chose to use it like in a condition), though I suggest 1min or more as it's a heavy function if a side has a ton of units of the type and\or subtype you're filtering though.
requires: 3 or more Reference points on Bad Guy's side (in the sample they are rp4,5,6,7 and part of a bad guy exclusion zone, but they don't have to be part of such). In fact you really don't even need RP's defined at all if you say want to just feed it a table of hard coded latitudes and longitudes points like
Code: Select all
r = {{latitude=0.0,longitude=0.0},{latitude=0.0,longitude=0.0},
{latitude=0.0,longitude=0.0},{latitude=0.0,longitude=0.0}} etc.
Note when looking at the non-function code in the special action:
Code: Select all
checkAreaForUnits('Good Guys',r,'Facility','5002')- Attachments
-
- Testbed_Go..uysArea2.zip
- (13.98 KiB) Downloaded 40 times
RE: Scan An Area for Units
Knighthawk75,
I am getting a DB error when trying to load your scenario
I am getting a DB error when trying to load your scenario
"We have met the enemy and they are ours" - Commodore O.H. Perry
- michaelm75au
- Posts: 12457
- Joined: Sat May 05, 2001 8:00 am
- Location: Melbourne, Australia
-
KnightHawk75
- Posts: 1850
- Joined: Thu Nov 15, 2018 7:24 pm
RE: Scan An Area for Units
ORIGINAL: vettim89
Knighthawk75,
I am getting a DB error when trying to load your scenario
It was saved with the latest beta CMO build 1142.2 and db 483. If you have that it should load, unless the upload got corrupted or something by I think Michael's comment suggests it loaded for him.
If you just want the text of the special action part (the meat) and not the whole scene I've attached it here in .txt doc, just copy and past into a repeatable Special Action. Pretty easy to recreate the rest, two sides 'Good Guys' 'Bad Guys', with Bad Guys having Refpoints named rp4,5,6,7 in square of whatever size you want. and throw a mobile-personnel, and some other non-mobile-personnel (for testing the unit type filtering) unit onto good guy side and press the SA to check if they're inside the rp's or not. If you're still on cmano the nuts of the code should still work as while I didn't test this specific script in cmano most of it was pulled from existing snippets that were from cmano days. Alternatively tell me DB version you want the sample in and I'll replicate it.
- Attachments
-
- FindIfUnit..UnitType.zip
- (1.62 KiB) Downloaded 49 times
RE: Scan An Area for Units
Wow. Just wow! That is amazingORIGINAL: KnightHawk75
ORIGINAL: vettim89
Knighthawk75,
I am getting a DB error when trying to load your scenario
It was saved with the latest beta CMO build 1142.2 and db 483. If you have that it should load, unless the upload got corrupted or something by I think Michael's comment suggests it loaded for him.
If you just want the text of the special action part (the meat) and not the whole scene I've attached it here in .txt doc, just copy and past into a repeatable Special Action. Pretty easy to recreate the rest, two sides 'Good Guys' 'Bad Guys', with Bad Guys having Refpoints named rp4,5,6,7 in square of whatever size you want. and throw a mobile-personnel, and some other non-mobile-personnel (for testing the unit type filtering) unit onto good guy side and press the SA to check if they're inside the rp's or not. If you're still on cmano the nuts of the code should still work as while I didn't test this specific script in cmano most of it was pulled from existing snippets that were from cmano days. Alternatively tell me DB version you want the sample in and I'll replicate it.
Give me a few days to incorporate it into my scenario and I will get back to you
"We have met the enemy and they are ours" - Commodore O.H. Perry
RE: Scan An Area for Units
First of all, Knighthawk, I tested your code and it worked perfectly. Thank you so much
But.....you knew there was going to be a but.....
to my chagrin, picking up a deployed unit does not qualify for activating the "unit leaves area" trigger.
Can anybody think of a work around? I was thinking about setting up an event trigger for real time that would just scan the Area of Operation say every 30 seconds. The event for that trigger could either be activated by another event within the game. Alternatively, I could instead create a Special Action. I am thinking special action would be the best way
Create a Special Action called "Exfil Complete". Once the player has all the units out of the AOO, they click on the action and the scan is run. If there are units still in the area a Message Box would pop up saying, "Friendly units still in AOO. Complete Exfil first" Otherwise the Special Action would trigger a points action and end the scenario
You more creative types might be able to come up with a more eloquent answer to the problem than this. Would love to hear suggestions
But.....you knew there was going to be a but.....
to my chagrin, picking up a deployed unit does not qualify for activating the "unit leaves area" trigger.
Can anybody think of a work around? I was thinking about setting up an event trigger for real time that would just scan the Area of Operation say every 30 seconds. The event for that trigger could either be activated by another event within the game. Alternatively, I could instead create a Special Action. I am thinking special action would be the best way
Create a Special Action called "Exfil Complete". Once the player has all the units out of the AOO, they click on the action and the scan is run. If there are units still in the area a Message Box would pop up saying, "Friendly units still in AOO. Complete Exfil first" Otherwise the Special Action would trigger a points action and end the scenario
You more creative types might be able to come up with a more eloquent answer to the problem than this. Would love to hear suggestions
"We have met the enemy and they are ours" - Commodore O.H. Perry
- michaelm75au
- Posts: 12457
- Joined: Sat May 05, 2001 8:00 am
- Location: Melbourne, Australia
RE: Scan An Area for Units
That is an interesting point. I'm assuming it is using the normal a/c 'pickup'....
Being picked up means the unit gets removed (is added as cargo).
I'll have to check this - drop/pickup units were created after the 'unit enters/exit' events. Whereas the 'drop' would activate the 'enter area' trigger, the 'pickup' removes the unit so the 'exit area' trigger would not have a unit to check.
I suppose you could have an 'exit' trigger on the unit doing the pickup, and put a check on event that it has 'cargo' of the 'picked up' unit. But this assumes you have some control over what units can do the picking up.
Being picked up means the unit gets removed (is added as cargo).
I'll have to check this - drop/pickup units were created after the 'unit enters/exit' events. Whereas the 'drop' would activate the 'enter area' trigger, the 'pickup' removes the unit so the 'exit area' trigger would not have a unit to check.
I suppose you could have an 'exit' trigger on the unit doing the pickup, and put a check on event that it has 'cargo' of the 'picked up' unit. But this assumes you have some control over what units can do the picking up.
Michael
-
KnightHawk75
- Posts: 1850
- Joined: Thu Nov 15, 2018 7:24 pm
RE: Scan An Area for Units
You're welcome, glad it was indeed what you were looking for.ORIGINAL: vettim89
First of all, Knighthawk, I tested your code and it worked perfectly. Thank you so much
But.....you knew there was going to be a but.....
to my chagrin, picking up a deployed unit does not qualify for activating the "unit leaves area" trigger.
...
Yeah I know, i messed around and noticed that myself.
I mean you could do both.
A event and trigger that fires when 'units in area'. - > first time script triggers it enables the special action for manual checking, also enables the event to check every 1\5 minutes, stores keyvalue of say 1 noting it's been activated (which you check at the start of the script for >=1),that way subsequent firing the trigger doesn't do anything.
The event that runs every 1min\5min - > after being enabled does it's check and if all units are out disables itself, then disables \ hides special action, and messages user congrats on successful exfil, updates keyvalue to 2 denoting mission complete.
The enabled SA code just executes the already existing action for the event, ie a one liner of ExecuteEventAction('thename'). That way you shouldn't have to duplicate\copy paste any code.
Doing both covers cases where a player can force a manual check, but also if they're not paying attention or on hyper speed or something it's handled for them in relatively short order, and if they walked away from the computer they come back to the pop-up (and even if suppressed they'll get the scenario-end one..I think). But sounds like for your case SA alone approach should be fine, the rest is overkill with the idea the player could be focused elsewhere.
---
I actually can think of one based off the fact units get deleted on pickup, but it's more error prone, more code, involves more session persistence keys and I think probably less performant than the above. kind of don't even want to mention it unless you really want me to. btw speaking of perf you can remove the gKHPrint function and replace all the lines that use it with simple print statements or comment them out, product of copy and pasting from elsewhere and not bothering to optimizing for this specific sample. [:)]
RE: Scan An Area for Units
I love this code. Thanks for sharing. Is there a way to check to see if there is any mobile personal OR mobile vehicle units left in the area? ie check for both types and if there are any of either type then the result is "A unit is still in the area". If there is 1 type but not the other type, the result is still "A unit is still in the area". Only if there are no units of either type would the result be "No units left in the area"
-
KnightHawk75
- Posts: 1850
- Joined: Thu Nov 15, 2018 7:24 pm
RE: Scan An Area for Units
I should actually re-work this now as it was written before the ~1146.x added additions in the side wrapper which has an inarea method (that effectively is same as inpolygon) and easier filtering options that let us pre-screen units better now.ORIGINAL: orca
I love this code. Thanks for sharing. Is there a way to check to see if there is any mobile personal OR mobile vehicle units left in the area? ie check for both types and if there are any of either type then the result is "A unit is still in the area". If there is 1 type but not the other type, the result is still "A unit is still in the area". Only if there are no units of either type would the result be "No units left in the area"
That said, yes of course, just change the code to do that instead.
If I understand the request, should just need to call it twice using an 'or'.
For example assuming you want any 5001 or 5002 to trigger true:
Code: Select all
-- user code here
local r = ScenEdit_GetReferencePoints({side="Bad Guys", area={"RP-4","RP-5","RP-6","RP-7"}})
local rval;
if (r ~=nil) then
if( checkAreaForUnits('Good Guys',r,'Facility','5002') == true or checkAreaForUnits('Good Guys',r,'Facility','5001') == true) then
print('A unit is still in the area');
else
print('No units left in area');
end
end
r = nil;
RE: Scan An Area for Units
Is there a way to check to see if a specific aircraft (not any type of aircraft- either by name or GUID) is at a "base" rather than in an area?
-
KnightHawk75
- Posts: 1850
- Joined: Thu Nov 15, 2018 7:24 pm
RE: Scan An Area for Units
ORIGINAL: orca
Is there a way to check to see if a specific aircraft (not any type of aircraft- either by name or GUID) is at a "base" rather than in an area?
A specific base, or do you just want to know if it's on the ground somewhere vs in the air?
If you just want to know if it's on the ground somewhere this will return false 99.9% of the time.
Code: Select all
-- Function to return true if a it's very likely a aircraft unit is currently in the air.
-- takes in unit wrapper of unit to check
-- returns true if conditions indicate it's in the air, otherwise false.
function gKH.Unit:isAircraftAirborne(u)
if ((u.condition_v == "Airborne") or u.condition_V == "RTB") or u.condition_V == "Landing_PreTouchdown" or
u.condition_V == "ManoeuveringToRefuel" or u.condition_V == "Refuelling " or u.condition_V == "OffloadingFuel" or
u.condition_V == "DeployingDippingSonar" or u.condition_V == "EmergencyLanding" or u.condition_V == "BVRAttack" or
u.condition_V == "BVRCrank" or u.condition_V == "Dogfight" or u.condition_V == "BVRDrag" or u.condition_V == "TransferringCargo" then
return true;
end
return false;
end
If you want to check a specific base if it contains a specific unit guid:
Code: Select all
-- Function to return true if a given unit wrapper currently contains the guid of a specific unit.
-- input u: The unit wrapper to check.
-- input theType: The string type unit to check "Aircraft or Boats".
-- input theGuid: The guid of the unit to search for.
-- returns: true|false
function gKH.Unit:checkForHostedUnitGuid(u,theType,theGuid)
fn = "gKH.Unit:checkForHostedUnitGuid(): ";
if (theType == nil) or type(theType) ~= "string" then theType = "Aircraft" end --default to Aircraft
if (theGuid == nil) or type(theGuid) ~= "string" or string.len(theGuid) < 20 then print(fn .. "Missing guid. aborting."); return false; end
if(u~=nil) then
local tmptable;
if (u.embarkedUnits ~= nil) and theType == "Aircraft" then
tmptable = u.embarkedUnits.Aircraft;
elseif (u.embarkedUnits ~= nil) and theType == "Boats" then
tmptable = u.embarkedUnits.Boats;
else
print(fn .. "Could not determine search type, try Aircraft or Boats. Aborting.")
return false;
end
Code: Select all
if (tmptable ~=nil ) and #tmptable > 0 then
for k = 1, #tmptable do
if(tmptable[k] == theGuid) then return true; end --found match
end
else
return false; -- no units to check.
end
return false; -- checked but no matches.
else
print(fn .. "Error: Unit wrapper missing, returning false")
return false;
end
end
print(gKH.Unit:checkForHostedUnitGuid(u,"Aircraft","4FH7PU-0HM4G1515A9H1")) -- returns true if that unit guid is hosted.
You may need to dummy up the gKH namespace (local or global your choice) before using either if you don't rename the functions, ie put the following at the top:
gKH = {}
gKH.Unit={}
