Schalldampfer Posted November 27, 2019 Report Share Posted November 27, 2019 I modified the BIS_fnc_findSafePos to find the safe position in a circular area, which I use in my server. (The original one searches positions in a square area, which is different from the description in https://community.bistudio.com/wiki/BIS_fnc_findSafePos ) I need it because mission systems spawn missions at the edge of the map, which is too far from any players. Spoiler scriptName "Functions\misc\fn_findSafePos.sqf"; /* File: findSafePos.sqf Author: Joris-Jan van 't Land Edited by Schalldampfer Description: Function to retrieve and dynamic position in the world according to several parameters. Parameter(s): _this select 0: center position (Array) Note: passing [] (empty Array), the world's safePositionAnchor entry will be used. _this select 1: minimum distance from the center position (Number) _this select 2: maximum distance from the center position (Number) Note: passing -1, the world's safePositionRadius entry will be used. _this select 3: minimum distance from the nearest object (Number) _this select 4: water mode (Number) 0: cannot be in water 1: can either be in water or not 2: must be in water _this select 5: maximum terrain gradient (average altitude difference in meters - Number) _this select 6: shore mode (Number): 0: does not have to be at a shore 1: must be at a shore _this select 7: (optional) blacklist (Array of Arrays): (_this select 7) select X: Top-left and bottom-right coordinates of blacklisted area (Array) _this select 8: (optional) default positions (Array of Arrays): (_this select 8) select 0: default position on land (Array) (_this select 8) select 1: default position on water (Array) Returns: Coordinate array with a position solution. TODO: * Maybe allow passing several combinations of position, min and max dist ... so that you can avoid several things? * Interpretation of minDist / maxDist is wrong. It's not true distance that is used. Too bad? */ scopeName "main"; private ["_pos", "_minDist", "_maxDist", "_objDist", "_waterMode", "_maxGradient", "_shoreMode", "_defaultPos", "_blacklist"]; _pos = _this select 0; _minDist = _this select 1; _maxDist = _this select 2; _objDist = _this select 3; _waterMode = _this select 4; _maxGradient = _this select 5; _shoreMode = _this select 6; if (_shoreMode == 0) then {_shoreMode = false} else {_shoreMode = true}; _blacklist = []; if ((count _this) > 7) then { _blacklist = _this select 7; }; _defaultPos = []; if ((count _this) > 8) then { _defaultPos = _this select 8; }; //See if default world values should be used. if ((count _pos) == 0) then { _pos = getArray(configFile >> "CfgWorlds" >> worldName >> "safePositionAnchor"); }; if ((count _pos) == 0) exitWith {debugLog "Log: [findSafePos] No center position was passed!"; []}; //TODO: instead return defaults below. if (_maxDist == -1) then { _maxDist = getNumber(configFile >> "CfgWorlds" >> worldName >> "safePositionRadius"); }; //TODO: Validate parameters. private ["_newPos", "_posX", "_posY"]; _newPos = []; _posX = _pos select 0; _posY = _pos select 1; //Limit the amount of attempts at finding a good location. private ["_attempts"]; _attempts = 0; while {_attempts < 1000} do { private ["_newX", "_newY", "_testPos", "_rad", "_dist"]; _dist = _minDist + random (_maxDist - _minDist); _rad = random 360; _newX = _posX + _dist * (cos _rad); _newY = _posY + _dist * (sin _rad); _testPos = [_newX, _newY]; //Blacklist check. //TODO: Do not use function when the blacklist is empty? if (!([_testPos, _blacklist] call BIS_fnc_isPosBlacklisted)) then { if (!((count (_testPos isFlatEmpty [_objDist, 0, _maxGradient, _objDist max 5, _waterMode, _shoreMode, objNull])) == 0)) then { _newPos = _testPos; breakTo "main"; }; }; _attempts = _attempts + 1; }; //No position was found, use defaults. if ((count _newPos) == 0) then { if (_waterMode == 0) then { if ((count _defaultPos) > 0) then { _newPos = _defaultPos select 0; } else { //Use world Armory default position: _newPos = getArray(configFile >> "CfgWorlds" >> worldName >> "Armory" >> "positionStart"); }; } else { if ((count _defaultPos) > 1) then { _newPos = _defaultPos select 1; } else { //Use world Armory default water position: _newPos = getArray(configFile >> "CfgWorlds" >> worldName >> "Armory" >> "positionStartWater"); }; }; }; if ((count _newPos) == 0) then { //Still nothing was found, use world center positions. _newPos = getArray(configFile >> "CfgWorlds" >> worldName >> "centerPosition"); }; //diag_log format["BIS_fnc_findSafePos: %2 <- %1",_this,_newPos]; _newPos BIS_fnc_findSafePos = compile preprocessFileLineNumbers "\z\addons\dayz_server\compile\BIS_fnc\fn_findSafePos.sqf"; Reaper5150 and Th3-Hunter333 2 Link to comment Share on other sites More sharing options...
Recommended Posts
Please sign in to comment
You will be able to leave a comment after signing in
Sign In Now