Jump to content
rübe

selectBestPlaces (do-it-yourself documentation)

Recommended Posts

Ruebe hello. I was hoping you could help me out a little. I am trying to create a mission with more randomization. I was pointed to this tread and have been reviewing it, but do not quite understand everything I just read...lol. What I would like to do is use this code to place random hostages in up to lets say 4 spots to be rescued and enemy defending them. I was trying something like this hoping to get mostly camps or bases.

_centerpos = getarray (configfile >> "CfgWorlds" >> worldName >> "centerPosition");
_size = getnumber (configfile >> "CfgWorlds" >> worldName >> "mapSize");
_pos = selectBestPlaces [_centerpos, _size,"(1 + hills) * (1 - meadow) * (1 + houses) * (1 - sea)",250,1];

"mrk1" setMarkerPos ((_pos select 0) select 0);

["mrk1",(floor(random 2)+2)] execVM "JSHK_hostage.sqf";

It places a marker down but it is in the corner of the map out in the ocean. The hostage script seems to run on that marker, but not to sure since they are out there.

Share this post


Link to post
Share on other sites
create a mission with more randomization.....to place random hostages in up to lets say 4 spots to be rescued and enemy defending them.

Place a ammo box on a runway. Name it box1 Place 3 markers on the runway. Group each marker with the box.

Every time you start the mission, the ammo box will start at one of 4 places at random. It will start either at its original location or on one of the markers.

Now you need the hostage to start on top of the box. . Name your hostage, hostage1. In the init of the hostage type hostage1 setPos (getPos box1)

The hostage will always start by standing on the box, at one of 4 places at random.

If you want to use an object smaller than a box, choose a skeet or maybe a coke can.

If you want the box, skeet or coke can to be invisible, in the init of the object, use a "hide" or "invisible" command. (Sorry I forget what it is off hand)

Share this post


Link to post
Share on other sites

Neat new trick to retrieve the lovliest beaches/coastal places (e.g. for coastal insertion positions) within a desired radius thanks to the new ambient parameter waterDepth and that neat factor operator:

"sea - waterDepth + (waterDepth factor [0.05, 0.5])"

Or in full:

private [
	"_pos", "_rad", "_expr", "_prec", "_src", "_places", "_n"
];

_pos = _this;
_rad = 1000;
_expr = "sea - waterDepth + (waterDepth factor [0.05, 0.5])";
_prec = 5;
_src = 20;

_places = selectBestPlaces[_pos, _rad, _expr, _prec, _src];
_n = count _places; // should equal _src

for [{_i = 0}, {_i < _n}, {_i = _i + 1}] do
{
	private ["_p", "_v", "_w"];
	_p = (_places select _i) select 0;
	_v = (_places select _i) select 1;

	/* _w = (selectBestPlaces[_p, 1, "waterDepth", 1, 1] select 0); */
	_w = _p call RUBE_sampleWaterDepth;

	[
		["position", _p],
		["type", "mil_dot"], // or maybe mil_start?
		["color", "ColorWEST"],
		["text", format["([%1] v=%2, wd=%3)", _i, _v, _w]] // or just diag_log/hint this
	] call RUBE_mapDrawMarker;
};

// followed by further filtering of returned costal positions (maxGradient? direct land-path to some target position, ...)
// and maybe a random selection

where RUBE_sampleWaterDepth is defined as:

/*
Author:
 rübe

Description:
 Samples and returns the water depth at the given position

Parameter(s):
 _this: sample position

Returns:
 scalar (in meter)
*/

private ["_sample"];

_sample = selectBestPlaces[_this, 1, "waterDepth", 1, 1];

if ((count _sample < 1)) exitWith
{
0
};

((_sample select 0) select 1)

...and RUBE_mapDrawMarker just puts a marker down (use diag_log for a quick test instead).

The expression "sea - waterDepth" works already, but isn't really good enough. While this finds reasonably good costal places, they're exactly where waterDepth is 0, so sometimes a bit too much inlands already. Furthermore most samples will end up with the same exact expression value, which isn't nice to work with/further process either (e.g. to sort and select from the n best ones...). That's where the factor operator comes into play: and we get positions at desired waterDepth (say knee-deep). Perfect!

This can be also easily used to check if a given location/city can be regarded as costal location/city (just look if all expression values of these samples are exactly zero; you will get _sourcesCount samples back anyways, even if inlands, w.r.t. the sample radius).

All in all, this should be really nice for any randomly/procedurally planned costal attack and similar scenarios. :yay:

Share this post


Link to post
Share on other sites

"sea - waterDepth + (waterDepth factor [0.05, 0.5])"

Tested this expression on stratis and weirdly enough it returned some positions near airstation mike, too funny, heh.

That's what surfaceisWater is there for I guess.

Just wanted to say that this thread is invaluable for everyone interested in making missions other than "go to that town, shoot everyone to win".

Cheers

Share this post


Link to post
Share on other sites

I've been peering at this all morning at not much is going in. A lot of the words are bouncing off my eyeballs. Would anyone be good enough to dumb it down rather more for me?  I have read the biki pages on selectbestplaces, ambient parameters and simple expression, so 1 line replies posting that link might not be helpful.

 

It's clearly very powerful and when used properly, very efficient and going to be essential in the mission I'm making so I do need to comprehend what it does and how to make it work usefully.

 

I'm struggling with the following parts;

 

The expression part of selectbestplaces, forest, waterdepth, meadow etc.. are they variables that return a number? The examples appear to be taking some of these and multiplying them or even subtracting them. I get it that this expression spits out a single value in the return array, but I can't work out quite *how*.

 

waterDepth for example. The ambient parameters page says it's zero to m, me being depth, but ffur's example on April 3rd 2014 seems to suggest it's 0 to 1.

 

Factor and interpolate. Yes, I have done searches but a search for factor returns a page with dozens of links from the cosmetician Max Factor to a Canadian Hip Hop band. Not much help to me. :)

 

Perhaps if I were to talk about what I'm trying to do and those in the know might explain the relevant bits of this statement? Examples with explanations might work best for my little brain.

 

Firstly I want to get a relatively flat beachy place for a beachhead. I'm currently using findsafepos which works just fine. Probably leave it as it is. It 'aint broken etc.

 

Secondly, I want to put the CUP ANZAC frigate just offshore from the beachhead. Close enough to be visible and useful (I plan to use it's weaponry in the arty module) but far enough away that it's in deep enough water to not be aground. Players won't be driving, or indeed, on it.

Share this post


Link to post
Share on other sites

I've done some more thinking and some more reading. Let me see if I've got this right. Specifically using waterdepth..

diag_log str (selectbestplaces [position dude, 6, "waterDepth", 1, 3])

Returns 3 positions within 6 meters of dude along with the water depth at those positions?

Share this post


Link to post
Share on other sites

And.... and...

 

The array is sorted. In my example, positions at the start of the array are shallower than the ones at the end.

 

Oh hang on... the radius... returning positions from dude out to radius... all the positions are on the radius?

Share this post


Link to post
Share on other sites

As I read that, I started searching for an 'easy' way to get quite sweet positions for MBTs and AA's. Of course, after I had written quite some code, I stumbled over the complete list for nearestTerrainObjects. As someone was searching for a way to get a forest border I thought I point in this direction, this way you can 'easily' get the nearest 'FOREST BORDER' around your objective. or lets say let a MBT guard a Main road. As always you it would be wise to have a  nice script around something like that, simply it is not the most performant solution. Maybe,  try something like rough Terrain sampling. 

 

Maybe this could help someone.

Regards

Share this post


Link to post
Share on other sites

I'm trying to find positions within the Tanoan jungle that are deep enough in so as to be around 200m from any jungle edge. In order to do this I tried using:

_bestPlaces = selectBestPlaces [_position,200,"(1 + meadow) * (1 + houses) * (1 + trees) * (1 - forest)",5,1];

KK's example on the wiki states:

Quote

The sole indication of successful search is expressionResult value when it is > 0.

 

So I went about testing this far into the jungle. However, all I get are positions within the jungle that don't always return 0 for expressionResult, and instead return anything between 0 and 1.xxxxxxe-007 I worked through different expression values but I couldn't get it figured out. I had thought that if a position didn't match the expression that the expressionResult would equal 0 (or that it would at least be < 1). I had also thought it possible that if no position was found that count _bestPlaces would return 0, due to no suitable positions being added to the returned array. Turns out I was wrong on both accounts.

 

I thought I'd gotten a good enough, albeit still basic, understanding of what was going on here but I feel like I've well and truly missed the mark here. What am I doing wrong here?

 

EDIT:

Never mind, a little bit more time available and I worked out what was required. expressionResult was returning different to what I thought it was (as posted by me above) or expected, and after playing around with it some more I discovered that when _position was in a position that matched either meadow/houses/grass then expressionResult would be > 2 (still not sure why it's 2, but it servers my purpose). Simple matter then to evaluate (expressionResult < 2).

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

×