Jump to content
M1ke_SK

check if building position occupied

Recommended Posts

Hi fellow scripters,

 

I got a pickle for you. Got this code to garrison units in buildings.

 

Problem: units spawning on same position in building

 

Questions:

How check if building position occupied ?

How to prevent unit spawning on same building position?

 

Possible solutions:

- create "placeholder" on each position, replace it with unit, keep it under control with array and popOut

- store each building and each position in separate arrays. delete on usage

 

Looking for elegant solution.

 

I am open to suggestions as we all know in Arma we can do things from any direction.

_houseArray = [...];
_amount = 10;

for "_i" from 1 to _amount do
{
    _house = selectRandom _houseArray;
    _housePositions = _house buildingPos -1;
    _housePosition = selectRandom _housePositions;

    _unit = _group createUnit ["I_soldier_F", _housePosition, [], 0, "FORM"];
 
	sleep 0.5;
};

 

 

 

 

Share this post


Link to post
Share on other sites
45 minutes ago, M1ke_SK said:

Hi fellow scripters,

 

I got a pickle for you. Got this code to garrison units in buildings.

 

Problem: units spawning on same position in building

 

Questions:

How check if building position occupied ?

How to prevent unit spawning on same building position?

 

Possible solutions:

- create "placeholder" on each position, replace it with unit, keep it under control with array and popOut

- store each building and each position in separate arrays. delete on usage

 

Looking for elegant solution.

 

I am open to suggestions as we all know in Arma we can do things from any direction.


_houseArray = [...];
_amount = 10;

for "_i" from 1 to _amount do
{
    _house = selectRandom _houseArray;
    _housePositions = _house buildingPos -1;
    _housePosition = selectRandom _housePositions;

    _unit = _group createUnit ["I_soldier_F", _housePosition, [], 0, "FORM"];
 
	sleep 0.5;
};

 

 

 

 

 

Do you want to prevent spawning units multiple times on the same position? Use this:
 

_houseArray = [...];
_amount = 10;

for "_i" from 1 to _amount do
{
    _house = selectRandom _houseArray;
    _housePositions = _house buildingPos -1;
    _housePosition = selectRandom _housePositions;

	_usedPositions = _house getVariable ["TAG_fnc_usedPositions",[]];

	if !(_housePosition in _usedPositions) then {

    	_unit = _group createUnit ["I_soldier_F", _housePosition, [], 0, "FORM"];
		_usedPositions pushBackUnique _housePosition;
		_house setVariable ["TAG_fnc_usedPositions",_usedPositions];

	};
 
    sleep 0.5;
};

 

No idea on what your plan is, but it's way better to just pick a fixed amount of randomized positions beforehand, instead of trying to spawn on a position and having to check if it's free:

_houseArray = [...];
_amount = 10;
_allhousePositions = [];

//grab all positions from all houses
{

	_allhousePositions = _allhousePositions + (_x buildingPos -1);

} forEach _houseArray;


//pick proper amount of random positions, example: 10
for "_i" from 1 to _amount do {

if (_allhousePositions isEqualTo []) exitWith {systemchat "Not enough positions"};

_rndPos = selectRandom _allhousePositions;
_unit = _group createUnit ["I_soldier_F", _housePosition, [], 0, "FORM"];
_allhousePositions = _allhousePositions - _rndPos;


};

 

 

Cheers

Share this post


Link to post
Share on other sites
3 minutes ago, Grumpy Old Man said:

 

Do you want to prevent spawning units multiple times on the same position? Use this:
 


_houseArray = [...];
_amount = 10;

for "_i" from 1 to _amount do
{
    _house = selectRandom _houseArray;
    _housePositions = _house buildingPos -1;
    _housePosition = selectRandom _housePositions;

	_usedPositions = _house getVariable ["TAG_fnc_usedPositions",[]];

	if !(_housePosition in _usedPositions) then {

    	_unit = _group createUnit ["I_soldier_F", _housePosition, [], 0, "FORM"];
		_usedPositions pushBackUnique _housePosition;
		_house setVariable ["TAG_fnc_usedPositions",_usedPositions];

	};
 
    sleep 0.5;
};

Cheers

 

ok, so you utilized my  2nd "possible solution" - store each position in separate arrays. delete on usage

 

Code is not necessary, but thank you anyway :)

  • Like 1

Share this post


Link to post
Share on other sites
2 minutes ago, Grumpy Old Man said:

Added a further solution, should be more efficient.

 

Cheers

 

I see, so each _housePosition is unique? it has its own [x,y,z] coordinates ? Are they related to terrain or _house ?

Share this post


Link to post
Share on other sites

Would be not even more efficient just get _amount  of random indexes _houseArray  first?

Share this post


Link to post
Share on other sites
2 minutes ago, davidoss said:

Would be not even more efficient just get _amount  of random indexes _houseArray  first?

 

`_amount` is number of soldiers spawned

Share this post


Link to post
Share on other sites

I just saying that  if you unlucky enough you can have 10 units in one house

Share this post


Link to post
Share on other sites
12 hours ago, Grumpy Old Man said:

Added a further solution, should be more efficient.

 

Cheers

That is my preferred solution though I think using append / deleteAt instead you can squeeze a little more perf out of it. Especially if the dataset is large. 

Share this post


Link to post
Share on other sites
54 minutes ago, mrcurry said:

That is my preferred solution though I think using append / deleteAt instead you can squeeze a little more perf out of it. Especially if the dataset is large. 

 

Correct, was just a mere example, here a bit more fleshed out:

 

//build an array of all building positions within 5000m of the player:

GOM_list_allHouses = nearestTerrainObjects [player,["House"],5000,false,true];
GOM_list_allBuildingPositions = [];
GOM_list_allHouses apply {GOM_list_allBuildingPositions append (_x buildingPos -1)};

//now to pick a random amount out of them during mission runtime:

_tempPositions = GOM_list_allBuildingPositions;
_spawnPositions = [];
_amount = 10;
for "_i" from 1 to _amount do {

_spawnPositions pushBack (_tempPositions deleteAt random floor count _tempPositions);

};

hint str _spawnPositions;


//performance standing in the middle of Athira, Altis, 4184 houses, 12465 total positions:
Result:
0.0122 ms

Cycles:
10000/10000

Code:
 
_tempPositions = GOM_list_allBuildingPositions; 
_spawnPositions = []; 
_amount = 10; 
for "_i" from 1 to _amount do { 
 
_spawnPositions pushBack (_tempPositions deleteAt random floor count _tempPositions); 
 
};

Cheers

  • Like 2

Share this post


Link to post
Share on other sites

Love the use of the 'apply' command there, didn't know it existed until now.

Share this post


Link to post
Share on other sites
5 hours ago, AZCoder said:

Love the use of the 'apply' command there, didn't know it existed until now.

Apply is a real quality of life improving command, same as the changes to select.

 

Cheers

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

×