Jump to content
Blitzen88

Questions/Help with AI garrison scripts

Recommended Posts

Greetings,

 

I am trying to expand my scripting knowledge by taking a look at existing AI garrison scripts.  After digging through a couple, I have a few questions I was hoping someone could explain to me.

 

1) How do you limit an array of building positions to positions contained within one building?

It seems like most garrison scripts gather an array of nearby objects (buildings/houses) and then use that array to gather building positions.  How can you limit the array to only use building positions from a single building before “considering” a different building?

 

For example, a script gathers building positions from buildings A, B, and C.  The script then places units in random positions from buildings A, B, and C.  However, how can you make the script fill up building A before considering spots from building B or C?  Ie, how can you fill buildings up one by one instead of considering building positions from all available buildings?

 

2) How do you filter out buildings that do not have a minimum number of positions?

 

How can you ignore buildings that have less than X number of positions?

 

3) How do you remove a building/position from the script if a friendly unit already occupies that position?

This is a difficult one for me to wrap my head around.  I understand that, once a unit has been placed in a position, that position can be removed from the array.  However, what if I have two squads executing the same building position script…how do you prevent them from randomly selecting the same building…?

 

Could you run a check on the building position to see if a friendly unit is within 2 meters of the position? If so, then remove that position?

Share this post


Link to post
Share on other sites
22 hours ago, Blitzen88 said:

1) How do you limit an array of building positions to positions contained within one building?

It seems like most garrison scripts gather an array of nearby objects (buildings/houses) and then use that array to gather building positions.  How can you limit the array to only use building positions from a single building before “considering” a different building?

 

For example, a script gathers building positions from buildings A, B, and C.  The script then places units in random positions from buildings A, B, and C.  However, how can you make the script fill up building A before considering spots from building B or C?  Ie, how can you fill buildings up one by one instead of considering building positions from all available buildings?

My idea would be to loop over the array of building positions, something like

private _buildings = /* code to get all buildings in the vicinity */;
private _buildingPositions = flatten (_buildings apply {_x call BIS_fnc_buildingPositions});
{
	_x moveTo (_buildinPositions select _forEachIndex);
} forEach units group player;

 

22 hours ago, Blitzen88 said:

2) How do you filter out buildings that do not have a minimum number of positions?

 

How can you ignore buildings that have less than X number of positions?

with the select command:

_houses = [_xpos,_ypos] nearObjects ["House", 20];
_housesWithAtLeast2BuildingPositions = _houses select {count (_x buildingPos -1) > 1};

 

22 hours ago, Blitzen88 said:

3) How do you remove a building/position from the script if a friendly unit already occupies that position?

This is a difficult one for me to wrap my head around.  I understand that, once a unit has been placed in a position, that position can be removed from the array.  However, what if I have two squads executing the same building position script…how do you prevent them from randomly selecting the same building…? 

 

Could you run a check on the building position to see if a friendly unit is within 2 meters of the position? If so, then remove that position?

Another time where sqf could make use of OOP. Anyway, you could track the taken positions in a variable with taken positions (in addition to the first code):

private _buildings = /* code to get all buildings in the vicinity */;
private _buildingPositions = _buildings apply {_x call BIS_fnc_buildingPositions};
_buildingPositions = flatten _buildingPositions; // makes the array 1D but keeps the positions in order
{
	private _pos = {
		if !(_x in TAG_takenPositions) exitWith {
			TAG_takenPositions pushBack _x;
			_x // assign this position to the _pos variable
		};
	} forEach _buildingPositions;
	_x moveTo _pos;
} forEach units group player;

All this code is just from the top of my head and not tested. You would also have to accomodate for edge cases, like no nearby buildings or not enough building positions.

  • Like 2

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

×