z80cpu 37 Posted October 19, 2021 Hello! I am trying to obtain from 'run time', a means to get the highest point on ANY map. The closest thing (command) I have found is "getTerrainHeightASL'. But, I have to supply a position, which defeats doing this while a player is playing and I still would not know the highest spot on the map. I know I can get the x/y sizes, but I do not see anywhere to get the 'z' axis/data. What I am looking for is a way/command to do something like: MaxElev = BIS_fnc_GetHighestElevation; I could care less about the 'x/y' location, just the 'z'. I would like to do this to any map while the player is playing on said map. (i.e. an universal method/command) This is to create 'fog on demand' and at different height levels. For example, in order to create a 'mountain fog', I would have to know the max height, and then take 1/3 (as an example) from that max height (1000 max - 300), then plug that number into the 'setFog' command (0 setFog [x, y, 700]). No max height? It would be just guessing then and kinda lame. Any and all help is appreciated! Thanks! 🙂 Share this post Link to post Share on other sites
beno_83au 1369 Posted October 19, 2021 As far as I'm aware there's nothing that does this without checking positions unfortunately, like you've said. 1 Share this post Link to post Share on other sites
opusfmspol 278 Posted October 19, 2021 Most maps contain "Hill", "RockArea" or "Viewpoint" locations. nearestLocations can find them, and locationPosition returns [x,y,z], where z is -1 * getTerrainHeightASL at the location. Not a real answer I know, since there's no knowing a location would exist on the actual highest point of a particular map, but maybe something to ponder. 4 Share this post Link to post Share on other sites
M1ke_SK 230 Posted October 20, 2021 _max = 0; { _height = getTerrainHeightASL locationPosition _x; if (_height > _max) then { _max = _height; }; } count nearestLocations [[worldSize / 2, worldsize / 2, 0], ["Hill", "Mount"], (worldSize / 2) * sqrt 2]; hint format ["max: %1", _max]; 3 Share this post Link to post Share on other sites
z80cpu 37 Posted October 20, 2021 @beno_83au @opusfmspol @M1ke_SK - Thank you all. It is what I was afraid of. There is not a 'universal' method in getting the max height without an exact position being given, thus what I was wanting to avoid. Though I have not tried it, for those that might be interested, there IS a way to get this value, though I suspect it would not be too quick. You set up a 'For X' loop and inside of it, a 'For Y' loop (simply put) I get the x/y coords from the loop values, then get that section height. Store this value, advance the loop and repeat. Replace new height value when the new one is greater than the old value. Have it 'step' along at something checking every 10 meters or so... I suspect it would take a while to compute the whole map doing this. BUT, I would have the max height though. I might try it on Stratis for the fun of it sometime. When I do, I will be sure to report back to let ya know the outcome with the time results! While your method is 'innovating' @M1ke_SK, what if there were no hills/mountains? Just land like the the mid-west plains in the USA. There are 2 maps I know of, from ?Norway? that are basically flat. You method would not work on all maps, BUT it is a good idea though! 🙂 And we are on the 'same page' too with your method and mine in this post. Thank you all again! 🙂 Share this post Link to post Share on other sites
pierremgi 4817 Posted October 20, 2021 You can have a look at cfgWorlds reference. Don't bet too much on maxHillAltitude token because it's missing on most of the maps. But you could use it like this: _maxAlt = if (getNumber (configfile >> "CfgWorlds" >> worldName >> "maxHillsAltitude") >0) then [{getNumber (configfile >> "CfgWorlds" >> worldName >> "maxHillsAltitude")},{ <your code ending by the returned value>}]; Depending on what you intend to do, see also: fog tokens like startFogBase, haze tokens... in the link above. 1 Share this post Link to post Share on other sites
z80cpu 37 Posted October 21, 2021 @pierremgi - Thanks! I will give this a try. One thing I did try was my 'loop'. Strange results. When run on Altis, it reports back the max height as 33m LESS THAN the (from what I see) is the highest spot at 312m S/SW of ?Oreo? (not in ARMA now). And on Stratis at 'step 1', it was QUICK! Less than 1 second to run! Anybody got a reason for this? Test Loop Code: _size = worldSize / 2; _stepper = 5; _maxheight = 0; _height = 0; for "_xx" from 0 to _size step _stepper do { for "_yy" from 0 to _size step _stepper do { _height = getTerrainHeightASL [_xx,_yy]; if (_height > _maxheight) then {_maxheight = _height}; }; }; hint str _maxheight; I tried the step at 1 (takes about 1 min) and at 5 (as shown above) and I get basically the same answer - 33m LESS than the 312 shown on map and by the cursor info. Step 1 = 274m Step 5 = 278m Step 50 = 272m This makes no sense to me...Icould see and accpept 311, 310, 310.5, etc. 278m? BIG difference... 😉 The code does seem to work and 'step thru' every 'location' on the map. ???? Thanks for any insight and all the other help! 🙂 Share this post Link to post Share on other sites
Greenfist 1863 Posted October 21, 2021 _size = worldSize / 2;? That's half of the total length, so you're actually checking only one quarter of the map, right? 2 Share this post Link to post Share on other sites
mrcurry 493 Posted October 21, 2021 1 hour ago, z80cpu said: Anybody got a reason for this? You are only scanning the lower left quarter of the map. Use _size = worldSize; Resolution is going to be a problem, a way around that would be look for locations of type Mount, AFAIK they are generated at local high points by the BIS tools during the map creation process so are present on all maps, even flat ones. So something like this: Spoiler _highestASL = 0; _center = [ worldSize / 2, worldSize / 2 ]; { _h = getTerrainHeightASL position _x; if ( _h > _highestASL ) then { _highestASL = _h; }; } forEach nearestLocations [_center, ["Mount"], _center distance2D [0,0]]; 2 Share this post Link to post Share on other sites
Rydygier 1306 Posted October 21, 2021 An alternative - likely worse, than checking positions grid, but fun, could be casting dense (like every 5-10 m), map-wide but terrain-only horizontal LOS checks along one axis, starting "for sure too high", then going down with halving the altitude back (if no LOS detected) and forth (if LOS unobstructed) - bracketing of sorts - and narrowing checks down to those axis values, where was terrain obstacle detected... Once you get one coord this way, second one may be obtained in few ways, for example by bracketing down LOS ray ends at this coord. 1 1 Share this post Link to post Share on other sites
z80cpu 37 Posted October 23, 2021 @Greenfist, @mrcurry - hahahahahaha What a moron I was! You are CORRECT! I have no idea why I did that! I will correct and let ya know! What a duffus! @Rydygier - EXTREMELY INTERESTING! I never thought about doing that, but that SHOULD work! The only issue MIGHT be if some tree/building obstructs the view, the a 'false' reading would be returned. However, I think one could 'poll' this location somehow and ascertain if it was an object vs terrain. It should work, I am thinking that it may take a lot longer to compute this out. Regardless, quite interesting! Thanks again to you all! 😉 1 Share this post Link to post Share on other sites
Rydygier 1306 Posted October 23, 2021 Yeah, the main pro of such way is the fun of doing so. 🙂 LOS checks are heavy and when map wide? I wouldn't try to guess, how much, loading screen or without, but if you try such apporach, better prepare some eggs to fry them on that hot metal puddle, where your PC was once. Although terrain-only LOS checks could be not that heavy? BTW https://community.bistudio.com/wiki/terrainIntersect ignores any objects so there would be no false results due to that. 1 1 Share this post Link to post Share on other sites
z80cpu 37 Posted October 23, 2021 @beno_83au, @opusfmspol, @M1ke_SK, @pierremgi, @Greenfist, @mrcurry, @Rydygier OK! I got it! Using the CORRECT mapsize... 😉 I was able to make it work fairly quick. Here are the 'stats': Using a 25m 'resolution": Altis: Real Max Height = 350m - Detected @25m = 347m - Time: 3 seconds Tanoia: Real Max Height = 443m - Detected @25m = 439m - Time: 3 seconds Livonia: Real Max Height = 442m - Detected @25m = 441m - Time: 3 seconds Funny thing about the Livonia map, the height markers/text on the map are DEAD WRONG! You can see this by going to the bottom SW of the map where the only building/tower is and you will see it marked as 610m, move the cursor over it and the cursor show only 442m. So, I have 'solved/fixed' this question with yalls help and I do thank you for pointing out my stupid mistake! 🙂 If anybody would want the code, as it does have it uses as setting height for fog or flying things, it is below with some notation in it. It is in the SQF format. Again thank you all! 🙂 ***** // Gets Map Maximum Height Of Terrain // _MaxHeight will have the maximum height // _mx = maximum height 'x' coordinate // _my = maximum height 'y' coordinate // Do not want marker or hint? Delete line 'deletemarker' and ALL lines with 'MaxHeightMarker' (4) in them and delete the hintsilent line // Deletes old marker if present deleteMarker "MaxHight"; // This is the 'resolution' that you wish to scan for. The smaller the number, the longer it will take. Number is meters. If set to '7' for example, it will check height every 7 meters on the map. _stepper = 25; _Size = worldSize; _MaxHeight = 0; _Height = 0; _mx = 0; _my = 0; for "_xx" from 0 to _Size step _stepper do { for "_yy" from 0 to _Size step _stepper do { _Height = getTerrainHeightASL [_xx,_yy]; if (_Height > _MaxHeight) then {_MaxHeight = _Height; _mx = _xx; _my = _yy}; }; }; // Places Marker Once Done MaxHeightMarker = createmarker ["MaxHight",[_mx,_my,0]]; MaxHeightMarker setMarkerType "hd_dot"; MaxHeightMarker setMarkerColor "ColorBluFor"; MaxHeightMarker setMarkerText "Max Height"; // Shows Max Height Once Done hintsilent str _MaxHeight; 1 Share this post Link to post Share on other sites
pierremgi 4817 Posted October 23, 2021 Little code, perhaps faster for whole map. You can also find the highest point from a position/object within a range. MGI_elevatedCheck = compileFinal " params ['_pos','_radius','_factor']; private _posTest = ATLtoASL _pos; private _rangeSqr = _radius^2; private _bestHigh = _posTest select 2; if (isNil 'MGI_posRefHighPt') then { MGI_posRefHighPt = _pos; MGI_posRefHighRange = _rangeSqr }; private _n = round (_radius min worldSize / 10); _c = _radius / (sqrt (_n - 1)); for '_i' from _n^_factor to 0 step -1 do { _rho = _c * sqrt (_i + 0.5); _theta = 137.508 * (_i + 0.5); _ckPos = _posTest getPos [_rho,_theta]; call { if ((getTerrainHeightASL _ckPos) > _bestHigh && {_ckPos distanceSqr MGI_posRefHighPt < MGI_posRefHighRange}) exitWith { _pos = ASLtoATL _ckPos; _bestHigh = getTerrainHeightASL _ckPos }; }; }; _pos "; MGI_HighestPt = { params [["_pos",[worldSize /2,worldSize /2,0],[objNull,[]],[2,3]],["_range",worldSize/1.4]]; _pos = if (_pos isEqualType objnull) then [{getpos _pos},{_pos}]; _pos set [2,0]; private _posHigh = [_pos,_range,1.5] call MGI_elevatedCheck; _posHigh = [_posHigh,_range /20,1.6] call MGI_elevatedCheck; _mk = createMarker [str random 1, _posHigh]; _mk setMarkertype "mil_dot"; _mk setMarkerColor "colorBlue"; _posHigh }; use it as is: private _highestPt = call MGI_HighestPt; // whole map or even, highest position from player within 200 m: private _highestPt = [player,200] call MGI_HighestPt; // 200 around player placing the player above this point: _highestPt set [2, 1000]; player setPosASL _highestPt; _highestPt set [2, vectorMagnitude (_highestPt vectorDiff getPosVisual player)]; player setPosASL _highestPt; 2 1 Share this post Link to post Share on other sites
Jester504 109 Posted October 24, 2021 I would scan the whole map at 100m resolution, find the highest 10 points doing that, then scan 100x100 around those points at 5m resolution and take the highest point from those results. 1 1 Share this post Link to post Share on other sites
z80cpu 37 Posted November 4, 2021 @pierremgi, @Jester504 - Both interesting ideas (and good ones too). I suspect some might need to know the exact height, I think this might be 'over kill' for my purpose. I am just trying to get the 'approximate' mas height to set fog levels. Using my method above, with the 'resolution' set at 25m, I 'scan' most maps in less than 3 seconds. So the 'delay' is not bad. Actually, my code runs when the mod is loaded in automatically and I can not even tell it is running it is so quick. However, if someone was wanting to know the exact height, your above methods (both of you) would work. @Jester504 - Your method reminds me of the old 'shell sort algorithm', which is about as old as I am... 😉 See: https://en.wikipedia.org/wiki/Shellsort OR Google: shell sort algorithm Thanks for yalls help! 🙂 1 Share this post Link to post Share on other sites
Tankbuster 1741 Posted November 4, 2021 I load up each map my mission will run on, find the maximum altitude by looking for it, then store it in a variable. 🙂 Sometimes, coding something to find a value is not the best way. 2 Share this post Link to post Share on other sites
z80cpu 37 Posted November 4, 2021 @Tankbuster How do you 'look' for it? The ways mentioned above are the only ways to get the max height. So I am at a loss how you 'look at it'. I am also taking about automating this process. If you're talking about looking at the map, they can be WRONG. The Livonia map is one where the map has the wrong heights listed. See a post of mine from above stating this. These scripts are the only accurate way to get it. Map configs could be missing as well, so that is also useless, Also, what I was after was to know the max height on ANY map as quickly as possible. Start mission, I know height immediately. The player has to do nothing and the height is determined in less than 3 seconds with the player not even noticing that this is being done. 🙂 Share this post Link to post Share on other sites
Tankbuster 1741 Posted November 4, 2021 24 minutes ago, z80cpu said: @Tankbuster How do you 'look' for it? The ways mentioned above are the only ways to get the max height. So I am at a loss how you 'look at it'. I am also taking about automating this process. If you're talking about looking at the map, they can be WRONG. The Livonia map is one where the map has the wrong heights listed. See a post of mine from above stating this. These scripts are the only accurate way to get it. Map configs could be missing as well, so that is also useless, Also, what I was after was to know the max height on ANY map as quickly as possible. Start mission, I know height immediately. The player has to do nothing and the height is determined in less than 3 seconds with the player not even noticing that this is being done. 🙂 By running the game, opening the editor and looking for the highest peaks. You don't need to automate everything. The couple of minutes you spend getting this information manually will soon be much shorter than the 3 seconds every time it's played. When I've found what looks like the highest position from the editor map, spawn an entity there, run the mission and get it's z value. switch (worldName) do { case "Altis": {maxel = 350};// thronos case "Stratis": {maxel = 236};// camp maxwell case "Tanoa": {maxel = 443};// Mount Tanoa eastern rim ~ ~ }; Share this post Link to post Share on other sites
z80cpu 37 Posted November 9, 2021 @Tankbuster - While this may work, this is not want I was seeking. "...I would like to do this to any map while the player is playing on said map. (i.e. an universal method/command)..." No map editing, no looking, no modules, no extra scripts, no nothing except load a mission and go. If one is in the editor, one is not playing... 😉 Also, your method is very 'problematic' for a lot of 'flat maps'. And who will remember all the max heights for every map they have? And why should they when this data is used to set fog a different levels based on said heights? Yes, your method would work, but must be done for every map one plays one and must be 'remembered' so how. My method, which is listed above and does work, requires none of this and is almost instant as well as being 100% accurate. As stated in my original post, this is for a mod where the player can set fog at different levels based on the map's height...ANY MAP, instantly. I thank you for your time and effort in this though! 🙂 Share this post Link to post Share on other sites