Jump to content
Sign in to follow this  
Handle1

How can I create an arbitrary position on the map?

Recommended Posts

I'd like to try something out, basically I want to create a position on the map using a script, and not within the Arma 3 Editor. I'd like to use this position as a place for AI to go to, or otherwise be used. I'd just like to be able to create positions using a script; so using the editor isn't necessary. Doing this would let me make my missions/mods dynamic.

Edited by Handle1
Added my last sentence

Share this post


Link to post
Share on other sites

Define what you mean by position?

Like: [0,0,0]

or a town, FOB, base, village, outpost?

Share this post


Link to post
Share on other sites

Like that, yes. Can I just create an array with the three positions and give it to a method such as doMove() ???

Share this post


Link to post
Share on other sites
Like that, yes. Can I just create an array with the three positions and give it to a method such as doMove() ???

You still didn't answer my question though are your talking position or are you talking about an array of different locations (town, FOB, outpost) that are randomly chosen for AI's to then get a waypoint to that location?

Share this post


Link to post
Share on other sites

Well there are numerous ways to get a position, not necessarily to create them.

Way #1, put markers down in the editor (or created via a script) at each place you want and name them then do something like the below:

_mrkArr = ["mrkName1","mrkName2","mrkName3"];

_rndMark = _mrkArr call BIS_fnc_selectRandom;

groupName move (getMarkerPos _rndMark);

Way #2, go into the editor and hover your mouse over the position you want, and in the bottom left hand corner of your screen you will see Grid: #### X: ###.### Y: ###.### Z:##.#, write down X, Y, & Z then input them into an array exampled below the picture:

UOxNumb.jpg

_mrkArr = [[X, Y, Z], [X, Y, Z], [X, Y, Z]];

_rndMark = _mrkArr call BIS_fnc_selectRandom;

groupName move _rndMark;

Way #3 & #4, you could use something like BIS_fnc_randomPos or BIS_fnc_findSafePos, to get a random position around a radius of the group, and then just set a move command to that position.

Share this post


Link to post
Share on other sites

Hi. Alternatively you could pull vanilla location's positions of the currently loaded world from the cfg. No markers or objects needed. Cheers.

private ["_locations","_position","_grp"];

_locations = [];
"
  _locations pushBack (getArray (_x >> 'position'));
  false
" configClasses (configFile >> "CfgWorlds" >> worldName >> "Names");

_position = _locations call bis_fnc_selectRandom;

_grp doMove _position;

Edited by Iceman77

Share this post


Link to post
Share on other sites

Ahh yeah. Could even combine the two. Get a random location >> selectbestPlaces

Share this post


Link to post
Share on other sites

Actually I did this, but thanks to JShocks' guidance I had a good idea of how to accomplish it!

_me = player; //Cache player
moveHere = getPos _me; ///Get position
moveX = moveHere select 0; //Place the positions in to separate variables
moveY = moveHere select 1;
moveZ = moveHere select 2;

_customPosition =  [moveX - 95, moveY - 50, moveZ ]; //Create a custom spot for the AI to be spawned
hint format ["Players position is: %1, %2, %3",moveX ,moveY ,moveZ]; 
sleep 1.5;
_grp = createGroup west; //Create a group to put them in
_newAI = []; //Array for the AI
for "_x" from 0 to 2 do
{
_newAI = _newAI + ["B_Soldier_F" createUnit [ _customPosition, _grp ] ]; //Create the AI and give them to the _newAI array
hint format ["New AI created."];
sleep 1.0;
};

_waypoint = [ (moveX + 95), (moveY + 55), moveZ]; //Do some arbitrary math with them and give the entire thing to _waypoint
hint format ["Waypoints position is at: %1, %2, %3", _waypoint select 0, _waypoint select 1, _waypoint select 2];
_grp move (_waypoint ); //Move all the AI to the pseudo-waypoint I just created
sleep 2.0;
hint "AI are moving to the waypoint.";

I do however think bestPlaces could be useful in the case of not knowing what may already exist where I want to spawn my AI. I should try that!

Edited by Handle1
Added last line

Share this post


Link to post
Share on other sites
Or use one of the less-known commands: https://community.bistudio.com/wiki/selectBestPlaces

That thing has some nifty features which can be quite useful in certain situations.

This looks really nice.

selectBestPlaces [_position, _radius, _expression, _precision, _sourcesCount]

example

myPlaces = selectBestPlaces [position player, 50, "meadow + 2*hills", 1, 5];

Could we use the below example from another post for example?

_camps_classes = _campGroup ["CampA","CampB","CampC","CampD","CampE","CampF "] call BIS_fnc_selectRandom;

_campGroup = [ (getMarkerPos _here), EAST (configfile >> "CfgGroups" >> "Empty" >> "Guerrilla" >> "Camps" >> (_camps_classes))] call BIS_fnc_spawnGroup;

_campGroup = selectBestPlaces [ (getMarkerPos _here), 20, "forest + trees", ?,?];

^^^^ If the 1st 3 are correct what would the last 2 be?

_precision: sample precision/ radius of the sample position (scalar, maybe in meter, but for sure this is no 0 to 1 range). Given a precision of zero, your game will probably halt for some time, most likely for ever for you basically try to divide by zero. I guess we divide the area by this sampling area the precision/radius defines. With a very low value, you may get a lot of "bestPlaces" very near to each other - the precision as min. probably. With a greater value the returned positions are much further apart from each other, though it looks like the min. distance isn't exactly the given precision interpreted as radius... But you get the idea.

_sourcesCount: number of best places returned (integer)

I don't get this ^^^^

Edited by JAndrews1

Share this post


Link to post
Share on other sites

Is the above possible? Not sure if that is set up correctly or if its even suppose to work that way. I have read the links but.....

Share this post


Link to post
Share on other sites

Precision is the value in meters and dictates how exact the measurement is being done, as far as I understand it.

If set to 1 the command will check if there's any "forest + trees" within 1m of the position.

Setting this to 80+ greatly increases the speed of the command while having no noticeable effect on the outcome (for whatever reason).

The last parameter is sourcesCount, returning an array of multiple positions that fit your input, I always had this set to 1.

As far as the spawning of prebuilt Camps goes you might wanna do an additional check for flat areas, like isFlatEmpty.

So you won't spawn parts of the camp inside nearby buildings/map objects.

Share this post


Link to post
Share on other sites

Although OP was solved, i throw this out there as another arbitrary position example that i use. Gets map config'd size, returns random non-water pos:

dsp_fnc_findSpawn = {
   _mapsize = getNumber (configFile >> "CfgWorlds" >> worldName >> "mapsize");
   _testpos = [(random _mapsize),(random _mapsize),0];
        while {surfaceIsWater [_testpos select 0,_testpos select 1]} do {_testpos = [random _mapsize,random _mapsize,0];};
   _testpos
};

The benefits for me are map interoperability, fast, and simple. while loop rarely runs more than once or twice.

Share this post


Link to post
Share on other sites

I had suggested something similar in post #7. Apparently they like need static references / positions / markers :eek:

Share this post


Link to post
Share on other sites

heh, i guess some methods are easier than others for some. for my script i needed positions that were potentially quite far from marked locations, or your method would have been perfect (middle of the desert in altis for example)

Share this post


Link to post
Share on other sites

Just so I understand this, it sounds like I should add an additional line to this and possible other tasks I am using to check for empty and flat. I just need to make sure I can set it up correctly. Here is my example.

_newPos = [getMarkerPos _markerCO, 0, 50, 10, 0, 20, 0] call BIS_fnc_findSafePos;

_markerCO isFlatEmpty [10,1,5,5,0,false,ignore];

_camps_classes = _campGroup ["CampA","CampB","CampC","CampD","CampE","CampF "] call BIS_fnc_selectRandom;

_campGroup = [ (getMarkerPos _markerCO), EAST (configfile >> "CfgGroups" >> "Empty" >> "Guerrilla" >> "Camps" >> (_camps_classes))] call BIS_fnc_spawnGroup;

secondly, is there a way I could also adjust the [x,y] offsetting from _newPos?

Edited by JAndrews1

Share this post


Link to post
Share on other sites

Firstly, isFlatEmpty returns an array with a flat and empty position nearest whatever object/marker, no different than like how BIS_fnc_findSafePos finds a safe position to spawn something. Basically what I'm saying is that you need to decide to use either findSafePos or isFlatEmpty, because using both is honestly redundant.

_newPos = [getMarkerPos _markerCO, 0, 50, 10, 0, 20, 0] call BIS_fnc_findSafePos;

//OR

_newPos = (getMarkerPos _markerCO) isFlatEmpty [10,1,5,5,0,false,nil];//ignore isn't an actual variable used, so it wouldn't work here, it needs an object, but since your using a marker we will set it to nil (not sure if that's correct though)

And then with the _newPos all you need to do to offset the x and y is to do something like the below:

_newOffsetPos = [((_newPos select 0) +5), ((_newPos select 1) +5), (_newPos select 2)];
//where the 5's you can adjust as needed

Share this post


Link to post
Share on other sites
Firstly, isFlatEmpty returns an array with a flat and empty position nearest whatever object/marker, no different than like how BIS_fnc_findSafePos finds a safe position to spawn something. Basically what I'm saying is that you need to decide to use either findSafePos or isFlatEmpty, because using both is honestly redundant.

_newPos = [getMarkerPos _markerCO, 0, 50, 10, 0, 20, 0] call BIS_fnc_findSafePos;

//OR

_newPos = (getMarkerPos _markerCO) isFlatEmpty [10,1,5,5,0,false,nil];//ignore isn't an actual variable used, so it wouldn't work here, it needs an object, but since your using a marker we will set it to nil (not sure if that's correct though)

And then with the _newPos all you need to do to offset the x and y is to do something like the below:

_newOffsetPos = [((_newPos select 0) +5), ((_newPos select 1) +5), (_newPos select 2)];
//where the 5's you can adjust as needed

hey thanks jshock, I have to ask cause I dont know. :banghead:

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  

×