Jump to content
Sign in to follow this  
dan3ko

Units random positioning without repeating position

Recommended Posts

Hello.

I'm making one of my first scripts and need some help.

The scenario is a CQC circuit, and need to spawn enemy units on specific spots (resolved). But at certain cases the two units spawns on the same spot and I didn't want this. My knowledge of scripting is very limited so I think in this site for searching help.

My code:

[color="#FF8040"][color="#1874CD"]_cnt[/color] [color="#8B3E2F"][b]=[/b][/color] [color="#191970"][b]createCenter[/b][/color] [color="#000000"]east[/color][color="#8B3E2F"][b];[/b][/color]
[color="#1874CD"]_room1[/color] [color="#8B3E2F"][b]=[/b][/color] [color="#8B3E2F"][b][[/b][/color][color="#7A7A7A"]"spot1"[/color][color="#8B3E2F"][b],[/b][/color][color="#7A7A7A"]"spot2"[/color][color="#8B3E2F"][b],[/b][/color][color="#7A7A7A"]"spot3"[/color][color="#8B3E2F"][b]][/b][/color] [color="#191970"][b]call[/b][/color] BIS_fnc_selectRandom[color="#8B3E2F"][b];[/b][/color]

grp1 [color="#8B3E2F"][b]=[/b][/color] [color="#191970"][b]createGroup[/b][/color] [color="#000000"]east[/color][color="#8B3E2F"][b];[/b][/color]
grp1 [color="#191970"][b]setBehaviour[/b][/color] [color="#7A7A7A"]"AWARE"[/color][color="#8B3E2F"][b];[/b][/color]
grp1 [color="#191970"][b]setCombatMode[/b][/color] [color="#7A7A7A"]"yellow"[/color][color="#8B3E2F"][b];[/b][/color]
[color="#7A7A7A"]"I_G_resistanceCommander_F"[/color] [color="#191970"][b]createUnit[/b][/color] [color="#8B3E2F"][b][[/b][/color] [color="#191970"][b]getMarkerPos[/b][/color] [color="#1874CD"]_room1[/color][color="#8B3E2F"][b],[/b][/color] grp1[color="#8B3E2F"][b],[/b][/color][color="#7A7A7A"]""[/color][color="#8B3E2F"][b],[/b][/color] [color="#FF0000"]0.6[/color][color="#8B3E2F"][b],[/b][/color] [color="#7A7A7A"]"corporal"[/color][color="#8B3E2F"][b]][/b][/color][color="#8B3E2F"][b];[/b][/color]

grp2 [color="#8B3E2F"][b]=[/b][/color] [color="#191970"][b]createGroup[/b][/color] [color="#000000"]east[/color][color="#8B3E2F"][b];[/b][/color]
grp2 [color="#191970"][b]setBehaviour[/b][/color] [color="#7A7A7A"]"AWARE"[/color][color="#8B3E2F"][b];[/b][/color]
grp2 [color="#191970"][b]setCombatMode[/b][/color] [color="#7A7A7A"]"yellow"[/color][color="#8B3E2F"][b];[/b][/color]
[color="#7A7A7A"]"I_G_resistanceCommander_F"[/color] [color="#191970"][b]createUnit[/b][/color] [color="#8B3E2F"][b][[/b][/color] [color="#191970"][b]getMarkerPos[/b][/color] [color="#1874CD"]_room1[/color][color="#8B3E2F"][b],[/b][/color] grp2[color="#8B3E2F"][b],[/b][/color][color="#7A7A7A"]""[/color][color="#8B3E2F"][b],[/b][/color] [color="#FF0000"]0.6[/color][color="#8B3E2F"][b],[/b][/color] [color="#7A7A7A"]"corporal"[/color][color="#8B3E2F"][b]][/b][/color][color="#8B3E2F"][b];[/b][/color]
[/color]

Thanks.

Edited by dan3ko

Share this post


Link to post
Share on other sites

_spots = ["spot1","spot2","spot3"];
_numberOfUnits = 2;//number of officers you want to spawn

for "_i" from 1 to (_numberOfUnits) step 1 do
{
if (count _spots < 1) exitWith {};
_grp = createGroup EAST;
_spot = _spots call BIS_fnc_selectRandom;
_unit = _grp createUnit ["I_G_resistanceCommander_F", getMarkerPos _spot, [], 0, "corporal"];
_grp setBehaviour "AWARE";
_grp setCombatMode "yellow";
_spots = _spots - [_spot];
};

EDIT: Fixed unit creation line

Edited by JShock

Share this post


Link to post
Share on other sites

Should be a bit more performant than JShock's solution. ;)

Correcly working version down below: Here

_spots = ["spot1","spot2","spot3"];
_numberOfUnits = 2;//number of officers you want to spawn
_spotsCount = count _spots;

if (_spotsCount < _numberOfUnits) then {_numberOfUnits = _spotsCount};

for "_i" from 1 to _numberOfUnits do
{
   _grp = createGroup EAST;
   _spotIndex = floor random _spotsCount;
   _spot = _spots select _spotIndex;
   _unit = "I_G_resistanceCommander_F" createUnit [ getMarkerPos _spot, _grp,"", 0.6, "corporal"];
   _grp setBehaviour "AWARE";
   _grp setCombatMode "yellow";
   _spots deleteAt _spotIndex;
   _spotsCount = _spotsCount - 1;
};
Edited by Heeeere's Johnny!

Share this post


Link to post
Share on other sites

Don't see how more lines of code is more performant? :)

Edited by JShock

Share this post


Link to post
Share on other sites

Wow, thank you very much. I hope to get to your level someday.:yay:

Share this post


Link to post
Share on other sites
https://community.bistudio.com/wiki/deleteAt

According to Heeeere's Johnny! it's considerably quicker using deleteat

I've not tested it yet but will do.

Right, because I've tested it and had the mentioned result (60 times faster than array substraction).

Don't see how more lines of code is more performant? :)

Because:

1. It's not repeatedly calling a function which counts the _spots array.

2. It's not repeatedly counting the array by checking if count _spots < 1 as that can be resolved before the loop.

3. It's using "deleteAt", which is by far the fastest way to delete elements from an array.

And finally, because that's the difference between "quick'n'dirrdy" and proper, performant coding. ;)

More lines does not automatically mean more work as e.g. a "count" can already cause a lot of work while being only one line.

Edited by Heeeere's Johnny!

Share this post


Link to post
Share on other sites

I try both and only spawns 1 unit. I try with more spots and more units but in all cases only spawns 1 unit. In the mission.sqm i have five markers named spot1, spot2, spot3, ... And a trigger to activate the script.

Share this post


Link to post
Share on other sites

Oh, my bad. Shouldn't have copied JShock's code right away. ^_^ This works fine for me:

[color=#FF8040][color=#1874CD]_spots[/color] [color=#8B3E2F][b]=[/b][/color] [color=#8B3E2F][b][[/b][/color][color=#7A7A7A]"spot1"[/color][color=#8B3E2F][b],[/b][/color][color=#7A7A7A]"spot2"[/color][color=#8B3E2F][b],[/b][/color][color=#7A7A7A]"spot3"[/color][color=#8B3E2F][b]][/b][/color][color=#8B3E2F][b];[/b][/color]
[color=#1874CD]_numberOfUnits[/color] [color=#8B3E2F][b]=[/b][/color] [color=#FF0000]2[/color][color=#8B3E2F][b];[/b][/color]
[color=#1874CD]_spotsCount[/color] [color=#8B3E2F][b]=[/b][/color] [color=#191970][b]count[/b][/color] [color=#1874CD]_spots[/color][color=#8B3E2F][b];[/b][/color]

[color=#191970][b]if[/b][/color] [color=#8B3E2F][b]([/b][/color][color=#1874CD]_spotsCount[/color] [color=#8B3E2F][b]<[/b][/color] [color=#1874CD]_numberOfUnits[/color][color=#8B3E2F][b])[/b][/color] [color=#191970][b]then[/b][/color] [color=#8B3E2F][b]{[/b][/color][color=#1874CD]_numberOfUnits[/color] [color=#8B3E2F][b]=[/b][/color] [color=#1874CD]_spotsCount[/color][color=#8B3E2F][b]}[/b][/color][color=#8B3E2F][b];[/b][/color]

[color=#191970][b]for[/b][/color] [color=#7A7A7A]"_i"[/color] [color=#191970][b]from[/b][/color] [color=#FF0000]1[/color] [color=#191970][b]to[/b][/color] [color=#1874CD]_numberOfUnits[/color] [color=#191970][b]do[/b][/color]
[color=#8B3E2F][b]{[/b][/color]
   [color=#1874CD]_grp[/color] [color=#8B3E2F][b]=[/b][/color] [color=#191970][b]createGroup[/b][/color] [color=#000000]east[/color][color=#8B3E2F][b];[/b][/color]
   [color=#1874CD]_spotIndex[/color] [color=#8B3E2F][b]=[/b][/color] [color=#191970][b]floor[/b][/color] [color=#191970][b]random[/b][/color] [color=#1874CD]_spotsCount[/color][color=#8B3E2F][b];[/b][/color]
   [color=#1874CD]_spot[/color] [color=#8B3E2F][b]=[/b][/color] [color=#1874CD]_spots[/color] [color=#191970][b]select[/b][/color] [color=#1874CD]_spotIndex[/color][color=#8B3E2F][b];[/b][/color]
   [color=#1874CD]_unit[/color] [color=#8B3E2F][b]=[/b][/color] [color=#1874CD]_grp[/color] [color=#191970][b]createUnit[/b][/color] [color=#8B3E2F][b][[/b][/color][color=#7A7A7A]"I_G_resistanceCommander_F"[/color][color=#8B3E2F][b],[/b][/color] [color=#191970][b]getMarkerPos[/b][/color] [color=#1874CD]_spot[/color][color=#8B3E2F][b],[/b][/color] [color=#8B3E2F][b][[/b][/color][color=#8B3E2F][b]][/b][/color][color=#8B3E2F][b],[/b][/color] [color=#FF0000]0[/color][color=#8B3E2F][b],[/b][/color] [color=#7A7A7A]"corporal"[/color][color=#8B3E2F][b]][/b][/color][color=#8B3E2F][b];[/b][/color]
   [color=#1874CD]_grp[/color] [color=#191970][b]setBehaviour[/b][/color] [color=#7A7A7A]"AWARE"[/color][color=#8B3E2F][b];[/b][/color]
   [color=#1874CD]_grp[/color] [color=#191970][b]setCombatMode[/b][/color] [color=#7A7A7A]"yellow"[/color][color=#8B3E2F][b];[/b][/color]
   [color=#1874CD]_spots[/color] [color=#191970][b]deleteAt[/b][/color] [color=#1874CD]_spotIndex[/color][color=#8B3E2F][b];[/b][/color]
   [color=#1874CD]_spotsCount[/color] [color=#8B3E2F][b]=[/b][/color] [color=#1874CD]_spotsCount[/color] [color=#8B3E2F][b]-[/b][/color] [color=#FF0000]1[/color][color=#8B3E2F][b];[/b][/color]
[color=#8B3E2F][b]}[/b][/color][color=#8B3E2F][b];[/b][/color][/color]

Kudos to Killzone_Kid for his SQF to BBCode Converter.

Be aware tho, that this code can only be used once since removing the markers from the array does not delete the markers themselves! If you want to delete the marker as well, use

[color=#FF8040][color=#191970][b]deleteMarker[/b][/color] [color=#1874CD]_spot[/color][color=#8B3E2F][b];[/b][/color][/color]

before the deleteAt line and after the for-loop, remove the potentially remaining markers with:

[color=#FF8040][color=#8B3E2F][b]{[/b][/color][color=#191970][b]deleteMarker[/b][/color] [color=#000000]_x[/color][color=#8B3E2F][b];[/b][/color][color=#8B3E2F][b]}[/b][/color] [color=#191970][b]forEach[/b][/color] [color=#1874CD]_spots[/color][color=#8B3E2F][b];[/b][/color][/color]

Edited by Heeeere's Johnny!

Share this post


Link to post
Share on other sites
Oh' date=' my bad. Shouldn't have copied JShock's code right away.[/quote']

And I shouldn't have copied his :p. Updated my code above as well.

Edited by JShock

Share this post


Link to post
Share on other sites

This is another method which completely removes the array manipulation except for an initial randomization.

_spots = ["spot1","spot2","spot3"];
_numberOfUnits = 2;
_shuffledArray = _spots call BIS_fnc_arrayShuffle;

for "_i" from 1 to _numberOfUnits do
{
   _grp = createGroup east;
   _spot = _shuffledArray select _i;
   _unit = _grp createUnit ["I_G_resistanceCommander_F", getMarkerPos _spot, [], 0, "corporal"];
   _grp setBehaviour "AWARE";
   _grp setCombatMode "yellow";
};

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  

×