M1ke_SK 230 Posted January 24, 2018 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
Grumpy Old Man 3540 Posted January 24, 2018 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
M1ke_SK 230 Posted January 24, 2018 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 :) 1 Share this post Link to post Share on other sites
Grumpy Old Man 3540 Posted January 24, 2018 Added a further solution, should be more efficient. Cheers Share this post Link to post Share on other sites
M1ke_SK 230 Posted January 24, 2018 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
davidoss 550 Posted January 24, 2018 Would be not even more efficient just get _amount of random indexes _houseArray first? Share this post Link to post Share on other sites
M1ke_SK 230 Posted January 24, 2018 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
davidoss 550 Posted January 24, 2018 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
mrcurry 470 Posted January 25, 2018 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
Grumpy Old Man 3540 Posted January 25, 2018 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 2 Share this post Link to post Share on other sites
AZCoder 921 Posted January 25, 2018 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
Grumpy Old Man 3540 Posted January 26, 2018 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