Initial
This commit is contained in:
@ -0,0 +1,19 @@
|
||||
// Return the closest position from array to the positionA.
|
||||
// In: [positionA,[array of positions]]
|
||||
// Out: positionB
|
||||
private ["_pA","_ps","_p1","_p2"];
|
||||
_pA = _this select 0;
|
||||
_ps = _this select 1;
|
||||
|
||||
_p1 = _ps select 0;
|
||||
|
||||
if (count _ps > 1) then {
|
||||
for "_i" from 1 to (count _ps - 1) do {
|
||||
_p2 = _ps select _i;
|
||||
if ((_p2 distance _pA) < (_p1 distance _pA)) then {
|
||||
_p1 = _p2;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
_p1
|
@ -0,0 +1,59 @@
|
||||
// In: marker
|
||||
// Out: array of positions
|
||||
private ["_area","_corners"];
|
||||
_area = _this;
|
||||
_corners = [];
|
||||
|
||||
// Center point
|
||||
private ["_center","_centerX","_centerY"];
|
||||
_center = getMarkerPos _area;
|
||||
_centerX = _center select 0;
|
||||
_centerY = _center select 1;
|
||||
|
||||
// Direction and make sure it's between 0 and 360.
|
||||
private ["_dir","_dirCos","_dirSin"];
|
||||
_dir = (markerDir _area) * -1;
|
||||
_dir = _dir % 360;
|
||||
_dirCos = cos _dir;
|
||||
_dirSin = sin _dir;
|
||||
|
||||
// Size
|
||||
private ["_size","_sizeX","_sizeY"];
|
||||
_size = getMarkerSize _area;
|
||||
_sizeX = _size select 0;
|
||||
_sizeY = _size select 1;
|
||||
|
||||
|
||||
private ["_cosX","_sinX","_cosY","_sinY","_addX","_addY","_subX","_subY"];
|
||||
_cosX = _dirCos * _sizeX;
|
||||
_sinX = _dirSin * _sizeX;
|
||||
_cosY = _dirCos * _sizeY;
|
||||
_sinY = _dirSin * _sizeY;
|
||||
|
||||
_addX = _cosX + _sinY;
|
||||
_addY = _sinX + _cosY;
|
||||
_subX = _cosX - _sinY;
|
||||
_subY = _sinX - _cosY;
|
||||
|
||||
private ["_posX","_posY"];
|
||||
// Bottom Left
|
||||
_posX = _centerX - _subX;
|
||||
_posY = _centerY - _addY;
|
||||
_corners set [0,[_posX,_posY]];
|
||||
|
||||
// Top Left
|
||||
_posX = _centerX - _addX;
|
||||
_posY = _centerY - _subY;
|
||||
_corners set [1,[_posX,_posY]];
|
||||
|
||||
// Top Right
|
||||
_posX = _centerX + _subX;
|
||||
_posY = _centerY + _addY;
|
||||
_corners set [2,[_posX,_posY]];
|
||||
|
||||
// Bottom Right
|
||||
_posX = _centerX + _addX;
|
||||
_posY = _centerY + _subY;
|
||||
_corners set [3,[_posX,_posY]];
|
||||
|
||||
_corners
|
@ -0,0 +1,30 @@
|
||||
// In: marker
|
||||
// Out: string (marker shape)
|
||||
|
||||
private ["_size","_x","_y","_ret"];
|
||||
_size = markersize _this;
|
||||
_x = _size select 0;
|
||||
_y = _size select 1;
|
||||
|
||||
_ret = "";
|
||||
|
||||
switch (tolower(markershape _this)) do {
|
||||
case "rectangle": {
|
||||
if (_x == _y) then {
|
||||
_ret = "SQUARE";
|
||||
} else {
|
||||
_ret = "RECTANGLE";
|
||||
};
|
||||
};
|
||||
case "ellipse": {
|
||||
if (_x == _y) then {
|
||||
_ret = "CIRCLE";
|
||||
} else {
|
||||
_ret = "ELLIPSE";
|
||||
};
|
||||
};
|
||||
case "icon": {
|
||||
_ret = "ICON";
|
||||
};
|
||||
};
|
||||
_ret
|
13
@DayZ_Epoch_Server/addons/dayz_server/DZAI/SHK_pos/shk_pos_fnc_getpos.sqf
Executable file
13
@DayZ_Epoch_Server/addons/dayz_server/DZAI/SHK_pos/shk_pos_fnc_getpos.sqf
Executable file
@ -0,0 +1,13 @@
|
||||
// In: [position,distance,direction]
|
||||
// Out: position
|
||||
private ["_pos","_dst","_dir","_orgX","_orgY","_posX","_posY"];
|
||||
_pos = _this select 0;
|
||||
_dst = _this select 1;
|
||||
_dir = _this select 2;
|
||||
|
||||
_orgX = _pos select 0;
|
||||
_orgY = _pos select 1;
|
||||
_posX = _orgX + (_dst * sin _dir);
|
||||
_posY = _orgY + (_dst * cos _dir);
|
||||
|
||||
[_posX,_posY,0]
|
@ -0,0 +1,26 @@
|
||||
// In: marker
|
||||
// Out: position
|
||||
|
||||
// Center point
|
||||
private ["_center","_centerX","_centerY"];
|
||||
_center = getMarkerPos _this;
|
||||
_centerX = _center select 0;
|
||||
_centerY = _center select 1;
|
||||
|
||||
// Size
|
||||
private ["_size"];
|
||||
_size = getMarkerSize _this;
|
||||
_size = _size select 0;
|
||||
|
||||
// Randomly pick a direction,
|
||||
private ["_dir","_posX","_posY","_rand","_pos"];
|
||||
_dir = random 360;
|
||||
_rand = sqrt random 1;
|
||||
_posX = (_size * (cos _dir)) * _rand;
|
||||
_posY = (_size * (sin _dir)) * _rand;
|
||||
_pos = [_posX,_posY];
|
||||
|
||||
_posX = _centerX + (_pos select 0);
|
||||
_posY = _centerY + (_pos select 1);
|
||||
|
||||
[_posX,_posY,0]
|
@ -0,0 +1,43 @@
|
||||
// In: ellipseMarker
|
||||
// Out: position
|
||||
|
||||
// Center point
|
||||
private ["_center","_centerX","_centerY"];
|
||||
_center = getMarkerPos _this;
|
||||
_centerX = _center select 0;
|
||||
_centerY = _center select 1;
|
||||
|
||||
// Direction and make sure it's between 0 and 360.
|
||||
private ["_dirMrk"];
|
||||
_dirMrk = (markerDir _this) * -1;
|
||||
_dirMrk = _dirMrk % 360;
|
||||
|
||||
// Size
|
||||
private ["_size","_sizeX","_sizeY"];
|
||||
_size = getMarkerSize _this;
|
||||
_sizeX = _size select 0;
|
||||
_sizeY = _size select 1;
|
||||
|
||||
// If B axis is longer than A, switch them and fix direction.
|
||||
if (_sizeX < _sizeY) then {
|
||||
_sizeX = _size select 1;
|
||||
_sizeY = _size select 0;
|
||||
_dirMrk = _dirMrk + 90;
|
||||
};
|
||||
|
||||
// Randomly pick a direction,
|
||||
private ["_dir","_posX","_posY","_rand","_pos"];
|
||||
_dir = random 360;
|
||||
_rand = sqrt random 1;
|
||||
_posX = (_sizeX * (cos _dir)) * _rand;
|
||||
_posY = (_sizeY * (sin _dir)) * _rand;
|
||||
_pos = [_posX,_posY];
|
||||
|
||||
if (_dirMrk != 0) then {
|
||||
_pos = [_pos,_dirMrk] call SHK_pos_fnc_rotatePosition;
|
||||
};
|
||||
|
||||
_posX = _centerX + (_pos select 0);
|
||||
_posY = _centerY + (_pos select 1);
|
||||
|
||||
[_posX,_posY,0]
|
@ -0,0 +1,37 @@
|
||||
// In: marker
|
||||
// Out: position
|
||||
|
||||
// Center point
|
||||
private ["_center","_centerX","_centerY"];
|
||||
_center = getMarkerPos _this;
|
||||
_centerX = _center select 0;
|
||||
_centerY = _center select 1;
|
||||
|
||||
// Size
|
||||
private ["_size","_sizeX","_sizeY"];
|
||||
_size = getMarkerSize _this;
|
||||
_sizeX = _size select 0;
|
||||
_sizeY = _size select 1;
|
||||
|
||||
// Direction and make sure it's between 0 and 360.
|
||||
private ["_dir","_dirCos","_dirSin"];
|
||||
_dir = (markerDir _this) * -1;
|
||||
_dir = _dir % 360;
|
||||
_dirCos = cos _dir;
|
||||
_dirSin = sin _dir;
|
||||
|
||||
private ["_rndX","_rndY","_posX","_posY"];
|
||||
// Select random X and Y
|
||||
_rndX = (random (_sizeX * 2)) - _sizeX;
|
||||
_rndY = (random (_sizeY * 2)) - _sizeY;
|
||||
|
||||
// If area is angled, shift X and Y
|
||||
if (_dir != 0) then {
|
||||
_posX = _centerX + (_dirCos * _rndX - _dirSin * _rndY);
|
||||
_posY = _centerY + (_dirSin * _rndX + _dirCos * _rndY);
|
||||
} else {
|
||||
_posX = _centerX + _rndX;
|
||||
_posY = _centerY + _rndY;
|
||||
};
|
||||
|
||||
[_posX,_posY,0]
|
@ -0,0 +1,36 @@
|
||||
// In: marker
|
||||
// Out: position
|
||||
|
||||
// Center point
|
||||
private ["_center","_centerX","_centerY"];
|
||||
_center = getMarkerPos _this;
|
||||
_centerX = _center select 0;
|
||||
_centerY = _center select 1;
|
||||
|
||||
// Size
|
||||
private ["_size"];
|
||||
_size = getMarkerSize _this;
|
||||
_size = _size select 0;
|
||||
|
||||
// Direction and make sure it's between 0 and 360.
|
||||
private ["_dir","_dirCos","_dirSin"];
|
||||
_dir = (markerDir _this) * -1;
|
||||
_dir = _dir % 360;
|
||||
_dirCos = cos _dir;
|
||||
_dirSin = sin _dir;
|
||||
|
||||
private ["_rndX","_rndY","_posX","_posY"];
|
||||
// Select random X and Y
|
||||
_rndX = (random (_size * 2)) - _size;
|
||||
_rndY = (random (_size * 2)) - _size;
|
||||
|
||||
// If area is angled, shift X and Y
|
||||
if (_dir != 0) then {
|
||||
_posX = _centerX + (_dirCos * _rndX - _dirSin * _rndY);
|
||||
_posY = _centerY + (_dirSin * _rndX + _dirCos * _rndY);
|
||||
} else {
|
||||
_posX = _centerX + _rndX;
|
||||
_posY = _centerY + _rndY;
|
||||
};
|
||||
|
||||
[_posX,_posY,0]
|
@ -0,0 +1,85 @@
|
||||
// In: [position,blackListMarker]
|
||||
// Out: boolean
|
||||
|
||||
private ["_pos","_area","_return"];
|
||||
_pos = _this select 0;
|
||||
_area = _this select 1;
|
||||
_return = false;
|
||||
|
||||
// Find corner positions of the rectangle
|
||||
private ["_dir"];
|
||||
_dir = markerDir _area;
|
||||
_dir = _dir % 360;
|
||||
|
||||
// Center point
|
||||
private ["_center","_centerX","_centerY"];
|
||||
_center = getMarkerPos _area;
|
||||
_centerX = _center select 0;
|
||||
_centerY = _center select 1;
|
||||
|
||||
private ["_shape"];
|
||||
_shape = _area call SHK_pos_fnc_getMarkerShape;
|
||||
|
||||
if (_shape == "ICON") then {
|
||||
// Icon has only one position, so if it equals to the given position, then it's blacklisted.
|
||||
if ([_pos,_center] call SHK_pos_fnc_isSamePosition) then {
|
||||
_return = true;
|
||||
};
|
||||
|
||||
// Markers that have an area.
|
||||
} else {
|
||||
if (_shape in ["RECTANGLE","SQUARE"]) then {
|
||||
private ["_corners"];
|
||||
_corners = _area call SHK_pos_fnc_getMarkerCorners;
|
||||
|
||||
// If rectangle is not axis-aligned.
|
||||
if (_dir % 90 != 0) then {
|
||||
// Add the point position to the array to have it shifted by the FOR below
|
||||
_corners set [4,_pos];
|
||||
|
||||
// Rotate each corner position so that the rectangle is aligned with x and y axises
|
||||
// Use origo as center while rotating, but for comparison shift positions back
|
||||
private ["_posCor","_posNew","_orgX","_orgY","_shiftedX","_shiftedY","_newX","_newY"];
|
||||
for "_i" from 0 to (count _corners - 1) do {
|
||||
_posCor = _corners select _i;
|
||||
|
||||
// Original coordinates
|
||||
_orgX = _posCor select 0;
|
||||
_orgY = _posCor select 1;
|
||||
|
||||
// Subtract the marker center coordinates from corner coordinates.
|
||||
// Rotation is done using origo (0,0) as anchor/centerpoint.
|
||||
_shiftedX = _orgX - _centerX;
|
||||
_shiftedY = _orgY - _centerY;
|
||||
|
||||
// Axis-aligned corner position
|
||||
_posNew = [[_shiftedX,_shiftedY],_dir] call SHK_pos_fnc_rotatePosition;
|
||||
|
||||
// Shift the aligned corner position back near to the original marker location.
|
||||
_newX = _posNew select 0;
|
||||
_newY = _posNew select 1;
|
||||
_newX = _newX + _centerX;
|
||||
_newY = _newY + _centerY;
|
||||
|
||||
_posCor = [_newX,_newY];
|
||||
|
||||
_corners set [_i,_posCor];
|
||||
};
|
||||
|
||||
// Point position
|
||||
_pos = _corners select 4;
|
||||
};
|
||||
|
||||
// Check if the position is within the marker area.
|
||||
_return = [_pos,_corners] call SHK_pos_fnc_isInRectangle;
|
||||
} else {
|
||||
if (_shape == "CIRCLE") then {
|
||||
_return = [_pos,_area] call SHK_pos_fnc_isInCircle;
|
||||
} else {
|
||||
_return = [_pos,_area] call SHK_pos_fnc_isInEllipse;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
_return
|
@ -0,0 +1,36 @@
|
||||
// In: [position,marker]
|
||||
// Out: boolean
|
||||
|
||||
private ["_pos","_area","_posX","_posY"];
|
||||
_pos = _this select 0;
|
||||
_area = _this select 1;
|
||||
|
||||
_posX = _pos select 0;
|
||||
_posY = _pos select 1;
|
||||
|
||||
// Center point
|
||||
private ["_center","_centerX","_centerY"];
|
||||
_center = getMarkerPos _area;
|
||||
_centerX = _center select 0;
|
||||
_centerY = _center select 1;
|
||||
|
||||
// Size
|
||||
private ["_size"];
|
||||
_size = getMarkerSize _area;
|
||||
_size = _size select 0;
|
||||
|
||||
// Difference in coordinates
|
||||
private ["_difX","_difY"];
|
||||
_difX = _posX - _centerX;
|
||||
_difY = _posY - _centerY;
|
||||
|
||||
private ["_return"];
|
||||
_return = false;
|
||||
|
||||
// If distance from center of marker to the given position is
|
||||
// smaller than the radius of the circle, then position is inside.
|
||||
if (sqrt((_difX * _difX) + (_difY * _difY)) < _size) then {
|
||||
_return = true;
|
||||
};
|
||||
|
||||
_return
|
@ -0,0 +1,54 @@
|
||||
// In: [position,ellipseMarker]
|
||||
// Out: boolean
|
||||
|
||||
private ["_pos","_area","_return"];
|
||||
_pos = _this select 0;
|
||||
_area = _this select 1;
|
||||
_return = false;
|
||||
|
||||
// Ellipse size
|
||||
private ["_size","_sizeX","_sizeY"];
|
||||
_size = getMarkerSize _area;
|
||||
_sizeX = _size select 0;
|
||||
_sizeY = _size select 1;
|
||||
|
||||
// Direction and make sure it's between 0 and 360.
|
||||
private ["_dir"];
|
||||
_dir = markerDir _area;
|
||||
_dir = _dir % 360;
|
||||
|
||||
// Ellipse center position
|
||||
private ["_center","_centerX","_centerY"];
|
||||
_center = getMarkerPos _area;
|
||||
_centerX = _center select 0;
|
||||
_centerY = _center select 1;
|
||||
|
||||
// If marker is not axis-aligned, rotate the dot position.
|
||||
if (_dir % 90 != 0) then {
|
||||
private ["_orgX","_orgY","_shiftedX","_shiftedY"];
|
||||
_orgX = _pos select 0;
|
||||
_orgY = _pos select 1;
|
||||
_shiftedX = _orgX - _centerX;
|
||||
_shiftedY = _orgY - _centerY;
|
||||
_pos = [[_shiftedX,_shiftedY],_dir] call SHK_pos_fnc_rotatePosition;
|
||||
_pos set [0,(_pos select 0) + _centerX];
|
||||
_pos set [1,(_pos select 1) + _centerY];
|
||||
};
|
||||
// Dot position
|
||||
private ["_posX","_posY"];
|
||||
_posX = _pos select 0;
|
||||
_posY = _pos select 1;
|
||||
|
||||
// Distance between dot and ellipse center
|
||||
private ["_dstX","_dstY"];
|
||||
_dstX = abs(_posX - _centerX);
|
||||
_dstY = abs(_posY - _centerY);
|
||||
|
||||
private ["_sum"];
|
||||
_sum = ((_dstX * _dstX)/(_sizeX * _sizeX)) + ((_dstY * _dstY)/(_sizeY * _sizeY));
|
||||
|
||||
if (_sum <= 1) then {
|
||||
_return = true;
|
||||
};
|
||||
|
||||
_return
|
@ -0,0 +1,26 @@
|
||||
// In: [pointPosition,corners]
|
||||
// Out: boolean
|
||||
private ["_pos","_corners","_return"];
|
||||
_pos = _this select 0;
|
||||
_corners = _this select 1;
|
||||
_return = false;
|
||||
|
||||
private ["_dotX","_dotY","_bottomLeft","_left","_bottom","_topRight","_right","_top"];
|
||||
_dotX = _pos select 0;
|
||||
_dotY = _pos select 1;
|
||||
|
||||
_bottomLeft = _corners select 0;
|
||||
_left = _bottomLeft select 0;
|
||||
_bottom = _bottomLeft select 1;
|
||||
|
||||
_topRight = _corners select 2;
|
||||
_right = _topRight select 0;
|
||||
_top = _topRight select 1;
|
||||
|
||||
// x is between left and right
|
||||
// y is between bottom and top
|
||||
if (_dotX >= _left && _dotX < _right && _dotY >= _bottom && _dotY < _top) then {
|
||||
_return = true;
|
||||
};
|
||||
|
||||
_return
|
@ -0,0 +1,16 @@
|
||||
// In: [array1,array2]
|
||||
// Out: boolean
|
||||
|
||||
private ["_p1","_p2","_return"];
|
||||
_p1 = _this select 0;
|
||||
_p2 = _this select 1;
|
||||
_return = true;
|
||||
|
||||
// Only compare X and Y coordinates, ignore Z.
|
||||
for "_i" from 0 to 1 do {
|
||||
if ((_p1 select _i) != (_p2 select _i)) exitwith {
|
||||
_return = false;
|
||||
};
|
||||
};
|
||||
|
||||
_return
|
@ -0,0 +1,13 @@
|
||||
// In: [position,direction]
|
||||
// Out: position
|
||||
private ["_pos","_dir","_orgX","_orgY","_newX","_newY"];
|
||||
_pos = _this select 0;
|
||||
_dir = _this select 1;
|
||||
|
||||
_orgX = _pos select 0;
|
||||
_orgY = _pos select 1;
|
||||
|
||||
_newX = (_orgX * (cos _dir)) - (_orgY * (sin _dir));
|
||||
_newY = (_orgX * (sin _dir)) + (_orgY * (cos _dir));
|
||||
|
||||
[_newX,_newY]
|
170
@DayZ_Epoch_Server/addons/dayz_server/DZAI/SHK_pos/shk_pos_getpos.sqf
Executable file
170
@DayZ_Epoch_Server/addons/dayz_server/DZAI/SHK_pos/shk_pos_getpos.sqf
Executable file
@ -0,0 +1,170 @@
|
||||
/* Select a random position based on anchor position, direction and distance.
|
||||
In: [position,distance,direction,water,road,emptySpace]
|
||||
Out: position
|
||||
*/
|
||||
private ["_org","_dst","_dir","_pos","_water","_road","_empty"];
|
||||
_org = _this select 0;
|
||||
_dst = _this select 1;
|
||||
_dir = if (count _this > 2) then {_this select 2} else {random 360};
|
||||
_water = if (count _this > 3) then {_this select 3} else {0};
|
||||
_road = if (count _this > 4) then {_this select 4} else {[0,200]};
|
||||
_empty = if (count _this > 5) then {_this select 5} else {[]};
|
||||
|
||||
// Object instead of position array given
|
||||
if (typename _org == "OBJECT") then {_org = getpos _org};
|
||||
|
||||
// Distance given as an array of min and max. Pick a random between them.
|
||||
if (typename _dst == "ARRAY") then {
|
||||
private ["_min","_max"];
|
||||
_min = _dst select 0;
|
||||
_max = _dst select 1;
|
||||
_dst = (_min + random(_max - _min));
|
||||
};
|
||||
|
||||
// Direction given as an array of min and max. Pick a random dir between them.
|
||||
if (typename _dir == "ARRAY") then {
|
||||
private ["_min","_max","_ang"];
|
||||
_min = _dir select 0;
|
||||
_max = _dir select 1;
|
||||
|
||||
_ang = _max - _min;
|
||||
|
||||
// Min bigger than max, can happen with directions around north
|
||||
if (_ang < 0) then { _ang = _ang + 360 };
|
||||
|
||||
_dir = (_min + random _ang);
|
||||
};
|
||||
|
||||
_pos = [_org,_dst,_dir] call SHK_pos_fnc_getPos;
|
||||
|
||||
// Water position
|
||||
if (typeName _water == "SCALAR") then {
|
||||
switch _water do {
|
||||
case 0: { // Water not allowed
|
||||
if (surfaceIsWater _pos) then {
|
||||
private ["_p","_d","_l"];
|
||||
_d = 0; _l = true;
|
||||
|
||||
// Search for a land position starting from the randomly picked position and
|
||||
// then going outwards from it in full circles in 20m steps.
|
||||
while {_d = _d + 20; _l && _d < 5000} do {
|
||||
for "_i" from 0 to 340 step 20 do {
|
||||
_p = [_pos,_d,_i] call SHK_pos_fnc_getpos;
|
||||
if (!surfaceIsWater _p) exitwith {_l = false};
|
||||
};
|
||||
};
|
||||
_pos = _p;
|
||||
};
|
||||
};
|
||||
case 1: { // Water allowed
|
||||
|
||||
};
|
||||
case 2: { // Only water allowed
|
||||
if !(surfaceIsWater _pos) then {
|
||||
private ["_p","_d","_l"];
|
||||
_d = 0; _l = true;
|
||||
|
||||
// Search for a water position starting from the randomly picked position and
|
||||
// then going outwards from it in full circles in 20m steps.
|
||||
while {_d = _d + 20; _l && _d < 5000} do {
|
||||
for "_i" from 0 to 340 step 20 do {
|
||||
_p = [_pos,_d,_i] call SHK_pos_fnc_getpos;
|
||||
if (surfaceIsWater _p) exitwith {_l = false};
|
||||
};
|
||||
};
|
||||
_pos = _p;
|
||||
};
|
||||
};
|
||||
};
|
||||
} else { // For backward compatibility
|
||||
// Water position is not allowed
|
||||
if !_water then {
|
||||
if (surfaceIsWater _pos) then {
|
||||
private ["_p","_d","_l"];
|
||||
_d = 0; _l = true;
|
||||
|
||||
// Search for a land position starting from the randomly picked position and
|
||||
// then going outwards from it in full circles in 20m steps.
|
||||
while {_d = _d + 20; _l && _d < 5000} do {
|
||||
for "_i" from 0 to 340 step 20 do {
|
||||
_p = [_pos,_d,_i] call SHK_pos_fnc_getpos;
|
||||
if (!surfaceIsWater _p) exitwith {_l = false};
|
||||
};
|
||||
};
|
||||
_pos = _p;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
// Road position.
|
||||
if (count _road > 0) then {
|
||||
if ((_road select 0) > 0) then {
|
||||
private ["_mode","_range","_roads","_cnt","_p","_p2"];
|
||||
_mode = _road select 0;
|
||||
_range = _road select 1;
|
||||
_roads = _pos nearroads _range;
|
||||
_cnt = count _roads;
|
||||
_p = [];
|
||||
|
||||
// Road position(s) found.
|
||||
if (_cnt > 0) then {
|
||||
_p = getpos (_roads select 0);
|
||||
|
||||
// Found more than one road position, return closest.
|
||||
if (_cnt > 1) then {
|
||||
for "_i" from 1 to (_cnt - 1) do {
|
||||
_p2 = getpos (_roads select _i);
|
||||
if ((_p2 distance _pos) < (_p distance _pos)) then {
|
||||
_p = _p2;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
switch _mode do {
|
||||
// Road position preferred but not forced.
|
||||
case 1: {
|
||||
if (count _p > 0) then {
|
||||
_pos = _p;
|
||||
};
|
||||
};
|
||||
// Only accept road position, return empty array if none found.
|
||||
case 2: {
|
||||
if (count _p > 0) then {
|
||||
_pos = _p;
|
||||
} else {
|
||||
_pos resize 0;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
// Find empty position
|
||||
private ["_dst","_veh","_p"];
|
||||
|
||||
_dst = 200;
|
||||
_veh = "";
|
||||
switch (typename _empty) do {
|
||||
case "OBJECT": { _veh = typeof _empty }; // Only vehicle given, use default distance
|
||||
case "SCALAR": {_dst = _empty;};
|
||||
case "ARRAY": {
|
||||
if (count _empty > 0) then {
|
||||
_dst = _empty select 0;
|
||||
_veh = _empty select 1;
|
||||
if (typename _veh == typename objNull) then { _veh = typeof _veh };
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
_p = [];
|
||||
if (count _pos > 0) then {_p = _pos findEmptyPosition [0,_dst,_veh];};
|
||||
|
||||
|
||||
// If an empty position is found, use it. Otherwise, return the original position.
|
||||
if (count _p > 0) then {
|
||||
_pos = _p;
|
||||
};
|
||||
|
||||
// Return position
|
||||
_pos
|
101
@DayZ_Epoch_Server/addons/dayz_server/DZAI/SHK_pos/shk_pos_getposmarker.sqf
Executable file
101
@DayZ_Epoch_Server/addons/dayz_server/DZAI/SHK_pos/shk_pos_getposmarker.sqf
Executable file
@ -0,0 +1,101 @@
|
||||
/* Select a random position from an area defined by a marker.
|
||||
In: [marker,water,blacklist,emptySpace]
|
||||
Out: position
|
||||
*/
|
||||
private ["_area","_water","_blist","_pos","_empty"];
|
||||
_area = _this select 0;
|
||||
_water = if (count _this > 1) then {_this select 1} else {0};
|
||||
_blist = if (count _this > 2) then {_this select 2} else {[]};
|
||||
_empty = if (count _this > 3) then {_this select 3} else {[]};
|
||||
_pos = [];
|
||||
|
||||
if (typename _blist == "STRING") then {_blist = [_blist]};
|
||||
|
||||
private ["_shape"];
|
||||
_shape = _area call SHK_pos_fnc_getMarkerShape;
|
||||
|
||||
// Limited loop so the script won't get stuck
|
||||
private ["_i","_exit"];
|
||||
_exit = false;
|
||||
for [{_i = 0}, {_i < 1000 && !_exit}, {_i = _i + 1}] do {
|
||||
|
||||
// Rectangle or Ellipse marker given?
|
||||
if (_shape in ["SQUARE","RECTANGLE"]) then {
|
||||
_pos = _area call SHK_pos_fnc_getPosFromRectangle;
|
||||
} else {
|
||||
_pos = _area call SHK_pos_fnc_getPosFromEllipse;
|
||||
};
|
||||
|
||||
// Find empty position
|
||||
private ["_dst","_veh","_p"];
|
||||
|
||||
_dst = 200;
|
||||
_veh = "";
|
||||
switch (typename _empty) do {
|
||||
case (typename objNull): { _veh = typeof _empty }; // Only vehicle given, use default distance
|
||||
case ("STRING"): { _veh = _empty };
|
||||
case (typename []): {
|
||||
if (count _empty > 0) then {
|
||||
_dst = _empty select 0;
|
||||
_veh = _empty select 1;
|
||||
if (typename _veh == typename objNull) then { _veh = typeof _veh };
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
_p = _pos findEmptyPosition [0,_dst,_veh];
|
||||
|
||||
// If an empty position is found, use it. Otherwise, return the original position.
|
||||
if (count _p > 0) then {
|
||||
_pos = _p;
|
||||
};
|
||||
|
||||
// Water position
|
||||
if (typeName _water == "SCALAR") then {
|
||||
switch _water do {
|
||||
|
||||
case 0: { // Water position is not allowed
|
||||
// Position is on land, try to exit script.
|
||||
if !(surfaceIsWater _pos) then {
|
||||
_exit = true;
|
||||
};
|
||||
};
|
||||
|
||||
case 1: { // Doesn't matter if position is on water or land.
|
||||
_exit = true;
|
||||
};
|
||||
|
||||
case 2: { // Only water position is allowed
|
||||
// Position is on water, try to exit script.
|
||||
if (surfaceIsWater _pos) then {
|
||||
_exit = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
} else { // For backward compatibility
|
||||
// Water position is not allowed
|
||||
if !_water then {
|
||||
// Position is on land, try to exit script.
|
||||
if !(surfaceIsWater _pos) then {
|
||||
_exit = true;
|
||||
};
|
||||
// Doesn't matter if position is on water or land.
|
||||
} else {
|
||||
_exit = true;
|
||||
};
|
||||
};
|
||||
|
||||
// Position is not allowed in blacklisted areas
|
||||
if (count _blist > 0 && _exit) then {
|
||||
// Check each blacklist marker
|
||||
{
|
||||
// If blacklisted, jump out of blacklist check and continue main loop.
|
||||
if ([_pos,_x] call SHK_pos_fnc_isBlacklisted) exitwith {
|
||||
_exit = false;
|
||||
};
|
||||
} foreach _blist;
|
||||
};
|
||||
};
|
||||
|
||||
// Return position
|
||||
_pos
|
105
@DayZ_Epoch_Server/addons/dayz_server/DZAI/SHK_pos/shk_pos_init.sqf
Executable file
105
@DayZ_Epoch_Server/addons/dayz_server/DZAI/SHK_pos/shk_pos_init.sqf
Executable file
@ -0,0 +1,105 @@
|
||||
/*
|
||||
SHK_pos
|
||||
|
||||
Version 0.24
|
||||
Author: Shuko (shuko@quakenet, miika@miikajarvinen.fi)
|
||||
Contributors: Cool=Azroul13, Hatifnat
|
||||
|
||||
Forum: http://forums.bistudio.com/showthread.php?162695-SHK_pos
|
||||
|
||||
Marker Based Selection
|
||||
Required Parameters:
|
||||
0 String Area marker's name.
|
||||
|
||||
Optional Parameters:
|
||||
1 Number Water position. Default is only land positions allowed.
|
||||
0 Find closest land. Search outwards 360 degrees (20 degree steps) and 20m steps.
|
||||
1 Allow water positions.
|
||||
2 Find only water positions.
|
||||
2 Array or String One or multiple blacklist area markers which are excluded from the main marker area.
|
||||
3 Array, Number, Object or Vehicle Type Force finding large enough empty position.
|
||||
0 Max range from the selection position to look for empty space. Default is 200.
|
||||
1 Vehicle or vehicle type to fit into an empty space.
|
||||
|
||||
Examples:
|
||||
[...,[300,heli]] Array with distance and vehicle object.
|
||||
[...,350] Only distance given
|
||||
[...,(typeof heli)] Only vehicle type given
|
||||
[...,heli] Only vehicle object given
|
||||
|
||||
Position Based Selection
|
||||
Required Parameters:
|
||||
0 Object or Position Anchor point from where the relative position is calculated from.
|
||||
1 Array or Number Distance from anchor.
|
||||
|
||||
Optional Parameters:
|
||||
2 Array of Number Direction from anchor. Default is random between 0 and 360.
|
||||
3 Number Water position. Default is only land positions allowed.
|
||||
0 Find closest land. Search outwards 360 degrees (20 degree steps) and 20m steps.
|
||||
1 Allow water positions.
|
||||
2 Find only water positions.
|
||||
4 Array Road positions.
|
||||
0 Number Road position forcing. Default is 0.
|
||||
0 Do not search for road positions.
|
||||
1 Find closest road position. Return the generated random position if none found.
|
||||
2 Find closest road position. Return empty array if none found.
|
||||
1 Number Road search range. Default is 200m.
|
||||
5 Array, Number, Object or Vehicle Type Force finding large enough empty position.
|
||||
0 Max range from the selection position to look for empty space. Default is 200.
|
||||
1 Vehicle or vehicle type to fit into an empty space.
|
||||
|
||||
Examples:
|
||||
[...,[300,heli]] Array with distance and vehicle object.
|
||||
[...,350] Only distance given
|
||||
[...,(typeof heli)] Only vehicle type given
|
||||
[...,heli] Only vehicle object given
|
||||
|
||||
Usage:
|
||||
Preprocess the file in init.sqf:
|
||||
call compile preprocessfile "SHK_pos\shk_pos_init.sqf";
|
||||
|
||||
Actually getting the position:
|
||||
pos = [parameters] call SHK_pos;
|
||||
*/
|
||||
// Functions
|
||||
SHK_pos_getPos = compile preprocessFileLineNumbers format ["%1\shk_pos\shk_pos_getpos.sqf",DZAI_directory];
|
||||
SHK_pos_getPosMarker = compile preprocessFileLineNumbers format ["%1\shk_pos\shk_pos_getposmarker.sqf",DZAI_directory];
|
||||
|
||||
// Sub functions
|
||||
SHK_pos_fnc_findClosestPosition = compile preprocessFileLineNumbers format ["%1\shk_pos\shk_pos_fnc_findclosestposition.sqf",DZAI_directory];
|
||||
SHK_pos_fnc_getMarkerCorners = compile preprocessFileLineNumbers format ["%1\shk_pos\shk_pos_fnc_getmarkercorners.sqf",DZAI_directory];
|
||||
SHK_pos_fnc_getMarkerShape = compile preprocessFileLineNumbers format ["%1\shk_pos\shk_pos_fnc_getmarkershape.sqf",DZAI_directory];
|
||||
SHK_pos_fnc_getPos = compile preprocessFileLineNumbers format ["%1\shk_pos\shk_pos_fnc_getpos.sqf",DZAI_directory];
|
||||
SHK_pos_fnc_getPosFromCircle = compile preprocessFileLineNumbers format ["%1\shk_pos\shk_pos_fnc_getposfromcircle.sqf",DZAI_directory];
|
||||
SHK_pos_fnc_getPosFromEllipse = compile preprocessFileLineNumbers format ["%1\shk_pos\shk_pos_fnc_getposfromellipse.sqf",DZAI_directory];
|
||||
SHK_pos_fnc_getPosFromRectangle = compile preprocessFileLineNumbers format ["%1\shk_pos\shk_pos_fnc_getposfromrectangle.sqf",DZAI_directory];
|
||||
SHK_pos_fnc_getPosFromSquare = compile preprocessFileLineNumbers format ["%1\shk_pos\shk_pos_fnc_getposfromsquare.sqf",DZAI_directory];
|
||||
SHK_pos_fnc_isBlacklisted = compile preprocessFileLineNumbers format ["%1\shk_pos\shk_pos_fnc_isblacklisted.sqf",DZAI_directory];
|
||||
SHK_pos_fnc_isInCircle = compile preprocessFileLineNumbers format ["%1\shk_pos\shk_pos_fnc_isincircle.sqf",DZAI_directory];
|
||||
SHK_pos_fnc_isInEllipse = compile preprocessFileLineNumbers format ["%1\shk_pos\shk_pos_fnc_isinellipse.sqf",DZAI_directory];
|
||||
SHK_pos_fnc_isInRectangle = compile preprocessFileLineNumbers format ["%1\shk_pos\shk_pos_fnc_isinrectangle.sqf",DZAI_directory];
|
||||
SHK_pos_fnc_isSamePosition = compile preprocessFileLineNumbers format ["%1\shk_pos\shk_pos_fnc_issameposition.sqf",DZAI_directory];
|
||||
SHK_pos_fnc_rotatePosition = compile preprocessFileLineNumbers format ["%1\shk_pos\shk_pos_fnc_rotateposition.sqf",DZAI_directory];
|
||||
|
||||
// Wrapper function
|
||||
// Decide which function to call based on parameters.
|
||||
SHK_pos = {
|
||||
private ["_pos"];
|
||||
_pos = [];
|
||||
|
||||
// Only marker is given as parameter
|
||||
if (typename _this == "STRING") then {
|
||||
_pos = [_this] call SHK_pos_getPosMarker;
|
||||
|
||||
// Parameter array
|
||||
} else {
|
||||
if (typename (_this select 0) == "STRING") then {
|
||||
_pos = _this call SHK_pos_getPosMarker;
|
||||
} else {
|
||||
_pos = _this call SHK_pos_getPos;
|
||||
};
|
||||
};
|
||||
|
||||
// Return position
|
||||
_pos
|
||||
};
|
Reference in New Issue
Block a user