Jump to content
Sign in to follow this  
Joe98

Selecting a marker at random

Recommended Posts

I place 100 markers on the map.

The markers are named: 1,2,3,…………98,99,100

I place a soldier on the map. In his init is a command:

this setpos getmarkerpos “1â€;

When the solder begins the mission he will always start on marker 1.

The idea is that he starts the mission on any 1 of the 100 markers selected at random. I have tried:

this setpos getmarkerpos "(round(random 100))";

However this does not work. Is there another command?

Share this post


Link to post
Share on other sites

This does it for me (if markers are named from "0" to "99"):

this setPos getMarkerPos str floor random 100;

Share this post


Link to post
Share on other sites

This works for 1 soldier thank you.

However if I have 2 or more soldiers they will never start on the same marker.

= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =

I found the solution!

Place 100 markers on the map numbered 0 - 99 as mentioned above

Place a box on the map and name it box1

Place a soldier on the map (you) and name him blue1

Place a second box on the map. In the init of the second box type:

box1 setPos getMarkerPos str floor random 100;

blue1 setpos getpos box1;

The commands are executed in that order. The box will start on a marker at random and then the soldier will start on the box.

As for soldier 2 (or more). Name him blue2. You don't want him to start on top of blue1 but you want him to start a few meters away.

In box 2 add a third command:

blue2 setPos [(getPos box1 select 0) + 2, (getPos box1 select 1) + 3]

In the command above one or both of the "+" symbols can be changed to "-" if you want. So blue2 can be made to start to the left or right and to the front or back of box1 by a given number of meters ( in this case 2 and 3).

Edited by Joe98

Share this post


Link to post
Share on other sites

[sorry, this turned a little extensive :)]

The sample I gave above does occasionally place several soldiers to the same marker (as well as disregard some markers at times) for me (perhaps you didn't test enough times?).

Note that in below, if copying any of the code directly to an unpreprocessed script (such as a unit's init field in the editor), you will need to remove the comments first.

You couldn't actually spawn soldiers "into" each other even if assigning them the exact same position (using setPos anyway; attachTo could be used to achieve something like that) as the game will automatically place them in a relatively safe/non-colliding location, however, if you wanted to space the units out when spawning, you could use in init.sqf -

soldierToRandomMarker = {
    private["_minRadius","_maxRadius","_markerPosition"];
    _minRadius = 5;
    _maxRadius = 10;
    _markerPosition = getMarkerPos str floor random 100;
    _this setPos [
         (_markerPosition select 0) + ((_minRadius + (_maxRadius - _minRadius))*(1 - random 2)),
         (_markerPosition select 1) + ((_minRadius + (_maxRadius - _minRadius))*(1 - random 2))
    ];
};

and in each relevant soldier's init -

this call soldierToRandomMarker;

Or (in each soldier's init; will require using the Functions Module;might take a (usually negligible) little instant longer than above, since it's got to wait for the module to start) -

0 = this spawn {
    waitUntil{!isNil "BIS_fnc_init"};//Since it's using the Functions Module
    _this setPos ([getMarkerPos str floor random 100,5,10,1,0,10,0] call BIS_fnc_findSafePos);
};

See BIS_fnc_findSafePos on Biki for argument details.

If you want the units to be just randomly placed in a general area (not specific areas, defined by the markers), you could set the "placement radius" in the editor for each soldier or set their positions with similar functions as given above (both the example code and BIS_fnc_findSafePos), using each soldier's editor-set position or a single central marker's position as the center point.

If the units are "generic" units (nothing changed about them in the editor or otherwise) you could spawn them in a script something like that (init.sqf; or a single unit's init will do just for testing) -

You'll first need a single marker at the center of the area you wish to spawn to (in the code below, referencing a marker called "spawnmarker").

soldierClasses = ["US_Soldier_MG_EP1","US_Soldier_Spotter_EP1",...];
//spawnMarkers = ["somemarker","someothermarker",...];//If using specific location markers

call {//Only to use temporary variables
    private["_count","_group"];
    _count = count soldierClasses;
    //_group = createGroup west;//If soldiers would be assigned to a single group (of BLUFOR) then this would be used with createUnit below
    for "_i" from 0 to 19 do {//Spawning 20 soldiers
         (createGroup west) createUnit [soldierClasses select floor random _c,getMarkerPos "spawnmarker",[],500,"NONE"];//creating all units within a circle of 500m radius around "spawnmarker"
         //or (createGroup west) createUnit [soldierClasses select floor random _c,[0,0,0],spawnMarkers,10,"NONE"];//If using spawnMarkers from above (creating within a circle of 10m radius at a random marker)
    };
};

If all the created soldiers are to be in the player's group, then use group player with the createUnit in above (assuming singleplayer).

If you wanted to use all the soldier-classes in the array once, instead of randomly choosing, you could use soldierClasses select _i instead of soldierClasses select floor random _c in above and adjust the soldierClassses array accordingly.

If you want to use specific units, then you can give them names (e.g. in the editor) like "mysoldier1","mysoldier2",... (the incrementing number is the important part) and loop through them as following (init.sqf) -

for "_i" from 0 to 19 do {
    (missionNamespace getVariable format["mysoldier%1",_i]) setPos getMarkerPos str floor random 100;
};

This allows to avoid having to type each soldier's init separately (note that the older createUnit syntax also allows defining init for the unit and can be used in similar cases).

You can reference the soldiers the same way for the other solutions as well, for brevity I demonstratively used the basic 100 marker-solution here.

Edited by geqqo
Just happened to notice that the soldierToRandomMarker function was somewhat flawed, also no more nil = ...

Share this post


Link to post
Share on other sites

The comments above miss a point.

Place 5 soldiers together on a map. Group them together.

All 5 should be set with: this setpos getpos box 1;

All 5 will begin on the box. When the mission starts they all walk to their correct position in the formation. Soldiers seem to be moving all over the place! Its like peak hour on the underground! Annoying!

I did a bunch of testing and learnt that soldier 2 will always move to a place 2 meters to my left and 2 meters behind. Soldier 3 will move to a position 2 meters to my right and 2 meters behind.

So for soldier 2, I assign him to begin 2 meters to the left of the box and 2 meters behind the box. And I carefully set the position of the other 4 soldiers.

When the mission starts everybody is in almost their exact position. Mission starts with silence.

Share this post


Link to post
Share on other sites

The simplest solution is a pain since you have so many markers. Group the group leader to each marker, and when game begins the group will randomly appear at one of the markers; but with a hundred markers? Wow, that's a lot of grouping to do.

I would think there should be a way of coding a forEach units group but it escapes me right now.

EDIT: Came up with this:

Give the team leader a name (i.e., "TL1").

Put this in the team leader's init field:

startPos = getMarkerPos str floor random 100; {_x setPos startPos} forEach units TL1;

The remaining problem is they all start crowded together since they all go to the same pos.

EDIT1: LoL geqqo, I incidentally found out why having marker "0" (as you pointed out) is rather important, without it you could spawn in the ocean at position [0,0,0]. -bloop!

Edited by OpusFmSPol
Opus went for a swim.

Share this post


Link to post
Share on other sites

Indeed, I presumed random placement the goal. You are describing the wedge formation, which is the default formation (see more here). I was hoping that maybe calling createUnit with "FORM" instead of "NONE" to fix this, but apparently it doesn't seem to (they still walk to the formation, instead of spawning to it).

In any case, as you probably know, typically spawning in formation would be achieved by placing the group leader correctly (in the sought direction/place) in the editor and the rest of the grouped units would be automatically placed accordingly. Positioning via script appears to need custom functionality to set their placement (if immediate formation is required) which you are effectively doing, by hand; to apply the wedge in any direction (in an automated fashion) you could call the following function where appropriate -

applyWedge = {//Argument: group (leader's direction and position will be used as reference)
    private["_dir","_leaderPos","_groupUnits","_a"];
    _dir = getDir leader _this;
    _leaderPos = getPos leader _this;
    _groupUnits = units _this;
    _this setFormDir _dir;
    for "_i" from 1 to ((count _groupUnits) - 1) do{//Starting from 1 since 0 is leader and the reference-point
         _a = if(_i % 2 == 0)then{-135}else{135};
         (_groupUnits select _i) setPos [
              (_leaderPos select 0) + ((floor ((_i - 1) / 2) + 1) * 6.5 * sin (_dir + _a)),
              (_leaderPos select 1) + ((floor ((_i - 1) / 2) + 1) * 6.5 * cos (_dir + _a))
         ];
    };
};

Even though according to the page I linked to above, wedge should be spacing units 5m out to both sides, I'm using the value of 6.5 in the above code since that seemed to spawn them most accurately in my brief testing.

EDIT:

Group the group leader to each marker, and when game begins the group will randomly appear at one of the markers

How would one go about grouping a unit to a marker (or do you simply mean placing the group-leader to the marker, without any actual linkage to the marker)?

Edited by geqqo
For anybody using the function as reference; modified to support dynamic direction changes (the setFormDir line)

Share this post


Link to post
Share on other sites
How would one go about grouping a unit to a marker (or do you simply mean placing the group-leader to the marker, without any actual linkage to the marker)?

Markers don't show unless Markers (F6) is active. If you know where a marker is and hover, its name will show; but generally you have to use (F6) and hover over the marker, then press Groups (F2) and drag to the team leader. it will group the marker to the leader. (F6) again, hover next marker, (F2), drag to leader again. When game starts, the group will spawn where placed, or spawn at the marker(s). Multiple markers can be used for random start points. MulleDK19 demonstrates it here starting at around the 5:20 mark:

But grouping the leader with 100 markers would be a serious pain.

Share this post


Link to post
Share on other sites

But grouping the leader with 100 markers would be a serious pain.

I started to group a box with 100 markers, found it a serious pain and started this thread.

Fortunately the solution is in posts 2 and 3 of this thread.

Thank you very much!

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  

×