Jump to content
Sign in to follow this  
meatball

Trigger based on number of alive groups with a certain name

Recommended Posts

Have an interesting challenge I'm trying to work out for a mission. I'm currently using an AI script that will spawn and despawn AI groups based on the location of the players. Those AI groups always have the group name "LVgroup##" where the ## will be an ID number.

Is there a simple way for me to set up a trigger to check to see if there are _any_ groups currently alive that have "LVgroup" as the first part of their name? I'd like to have one trigger that will fire when there are no "LVgroup" groups currently spawned, and another trigger that fires as soon as 1 "LVgroup" has spawned.

Share this post


Link to post
Share on other sites

I think this problem costs to many calculations to be helpful. But who cares about that right? So I'm guessing the groups are arbitrary and are only called when the trigger fires. So what I propose is to put the groups in array when they are spawned. This way you can make a array that consists of alive groups and basically remove them when the group is dead or the players are not in the right location. But I advise to only check to see if the group is alive every 30 seconds or so because trying to basically search a 2 dimensional array linearly will cause performance issues. Especially if you have lets say 7 groups that have spawned and you need to check all of them which will take some time. By doing this every 30 seconds will give the server a break from calculating the data you want. So when your array reaches size 0 this means there are no groups that are left alive.

lvArray = []; (when a group is spawned) lvArray set (count lvArray, units grpName);

So now you just have to check when the size of this array is 0 to spawn the next group.

_number = {alive _x}forEach lvArray; if(_number < 1) then {"spawn next group added it to lvArray"};

Now for the next part. You want to basically allocate and de-allocate units based on location of players.

Not a problem you could basically create a basic trigger to check if a unit inside the trigger, to easy.

"Each trigger's Condition block will be checked approximately twice every second for the duration of the mission." - http://community.bistudio.com/wiki/trigger

So while the players are outside the distance delete all the units in lvArray. Inside the trigger create the units.

Share this post


Link to post
Share on other sites

Maybe I should clarify a bit more. I'm currently using spunFin's AI Spawn Script pack, and three of his scripts there. I'm using 'militarize' to spawn defenders around certain objectives and 'simpleCache' to cache those militarize groups since there's a lot of objectives/groups. Each group is named "LVgroup##" where the ## is an ID number I can set in each militarize call. Then using simpleCache it will de-spawn/re-spawn those militarize groups based on how close the players are to the objectives. This all works fine.

Additionally, I'm using his 'ambientcombat' script which will spawn a certain number of 'ambient' enemy groups around the players location at all times. This let's me give the players the feeling like there's patrols in most areas. Sometimes they'll run into the ambient groups, sometimes they don't since I have ambient groups ranging out to over 1000m from the players. You can create markers and force the ambient combat groups to avoid certain areas, but I don't believe they actually despawn, they just range outside the 'avoid' marker area. You can also run a script to remove the ambient combat.

The problem occurs when players hit a major objective that has a good sized 'militarize' group there. The cache script will respawn that militarize group based there and between those AI, and the ambient AI that are floating around for ambientcombat, server FPS just tanks to the 10-15 FPS range and it almost becomes unplayable.

What I'd like to do is figure out a way that once I start running ambientcombat a trigger will watch for anytime the players get near an objective that has one of the militarize groups, (which I should be able to tell because the cache script will respawn that militarize group and there will now be groups in game named "LVgroup##"). When that trigger fires, it will run the script to remove the ambient combat. And then once the players clear the area (killing all the AI in that group) or move outside of the area (and the cache script de-spawns that militarize group), I can call the ambientcombat script again.

Edited by Meatball

Share this post


Link to post
Share on other sites

In the custom init parameter for the ambientCombat script. Do a check if the unit is lets say 1500 from the main objective. If that is true delete the unit. It's a very inefficient way of doing it but that is what I can come up with right now.

Share this post


Link to post
Share on other sites

Yeah, I don't think that will work just b/c there's multiple objectives and it's impossible to tell just what objective a player might be near. I really think the best way to handle is to do a check on whether or not at least one of those "LVgroups" is alive or !isnil or something to that effect, I'm just not sure how to check against part of a group name or a groupname but use wildcards.

If it was possible to do something like (count (units LVgroup**)) == 0) in a condition, where the ** were wildcards that would work I would think.

Edited by Meatball

Share this post


Link to post
Share on other sites

If you can't find a way to check the group name of the A.I. I think this is your next best option. Inefficient but who cares?

if(player distance obj1 < 1500 || player distance obj2 < 1500 || player distance obj3 < 1500) then {delete unit};

Share this post


Link to post
Share on other sites

Yeah, the other thing I was thinking was digging into the simplecache script and every time it spawns a group, increment a variable by 1 and every time it despawns a group, decrease a variable by 1. Then I can trigger against that variable being 0 or 1 to spawn/despawn ambient combat respectively.

Share this post


Link to post
Share on other sites
Yeah, I don't think that will work just b/c there's multiple objectives and it's impossible to tell just what objective a player might be near. I really think the best way to handle is to do a check on whether or not at least one of those "LVgroups" is alive or !isnil or something to that effect, I'm just not sure how to check against part of a group name or a groupname but use wildcards.

If it was possible to do something like (count (units LVgroup**)) == 0) in a condition, where the ** were wildcards that would work I would think.

I think your best shot is editing the code and once a unit is allocated add it to an array that you can check. The last position in the array should be the most recent group spawned.If the groups are spawned from the ambient combat script you can easily make an array to only contain the groups name LVgroup**.

---------- Post added at 16:17 ---------- Previous post was at 16:17 ----------

Yeah, the other thing I was thinking was digging into the simplecache script and every time it spawns a group, increment a variable by 1 and every time it despawns a group, decrease a variable by 1. Then I can trigger against that variable being 0 or 1 to spawn/despawn ambient combat respectively.
Now this is way more efficient I suggest you go this way.

Share this post


Link to post
Share on other sites

Ive only had a quick flick through the scripts but if your initiating the militarize with caching then you are providing param 11 ID which is the number these units will be recognised by.

e.g if param 11 is the number 10 then any units from this area will be known as LVgroup10 once spawned there is also a global variable you can check called LVgroup#spawned , where # is the ID , if this variable is true then the group is uncached and active else the variable is nil and they are currently despawned.

So knowing this information you can monitor the groups of these large zones where your worried about performance, keep a note of the ID's your using for this area and then use something like

_myIDsZone1 = [1,2,3,4]; //ID's for a zone

if (
 	{
		if ( !(isNil ("LVgroup"+(str _x)+"spawned") ) ) then { true } else { false };
	}count _myIDsZone1 == count _myIDsZone1
) then {

		//Stop ambient combat here!!

};

If all these groups become activate disable ambient combat.

OR for a trigger

(
	{
	if ( !(isNil ("LVgroup"+(str _x)+"spawned") ) ) then { true } else { false };
}count [1,2,3,4] == count [1,2,3,4]
)

OnAct : 
//Stop ambient combat here!!

Needs experimenting with but thats an option i see from a quick look through Spun's scripts.

Share this post


Link to post
Share on other sites

Since you spawn and despawn the groups, you have perfect control over them. Thus, you can add and remove them from a global array, instead of bothering with trying to figure out a way to refer to them by name. Simply, you can just iterate the array etc.

Share this post


Link to post
Share on other sites

He is not actually handling the spawning of the units, he is using someone else's script package to spawn them which does not return a direct reference to them, hence my above answer that is the closest i could find as a reference for anything the package spawns.

Share this post


Link to post
Share on other sites

If he edits the script and assign the units to a array. That way all units spawned from this one script will be in it.

Share this post


Link to post
Share on other sites

Thanks for all the help/feedback. I think I hit upon something that works last night and is pretty easy. Since the militarize scripts allow me to set custom init fields for the units I simply added a "miliTroops = group this;" to the custom init field in the militarize call which adds every unit that is spawned (or respawned) to that group.

I then simply set up two triggers, one watching for alive units in that group == 0 that spawns the ambient combat and another watching for alive units in that group >= 1 that despawns ambient combat.

({alive _x} count (units miliTroops)) == 0;  // Condition for trigger that spawns ambient combat.
({alive _x} count (units miliTroops)) >= 1;  // Condition for trigger that despawns ambient combat.

Seems to work great. As soon as the players get near a zone that was cached and the cache script respawns those militarize units, the trigger sees it and kills off the ambient combat and when the players leave the area or kill off all the enemy AI that were respawned, the other trigger sees it and starts ambient combat back up.

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
Sign in to follow this  

×