cklymowsky 1 Posted May 29, 2018 HI All, I've tried writing a script to spawn boats spread out along a shoreline (reliably in the water), but takes quite a while to spawn them reliably (up to a minute or more). Has anyone got a better script, better idea on how to do this or can suggest improvements to my script below? Quote player addAction ["<t color='#00ff00' t size='1' >CHAIN of BOATS spread 200m</t>", { _time = time; // spawn boats near nearest to position _posAndDistanceArray = []; _interations = 250; _sortArray = []; _distance1 = 0; _randomPosAroundPlayerinWater = [[[position player, 250]],["ground"]] call BIS_fnc_randomPos; if (({_x == 0} count _randomPosAroundPlayerinWater) == 2) exitWith {hint "NO POSITION NEAR WATER";uisleep 2;}; for "_i" from 1 to _interations do { _randomPosAroundPlayerinWater = [[[position player, 250]],["ground"]] call BIS_fnc_randomPos; _distance1 = round (player distance _randomPosAroundPlayerinWater); if ((abs (getTerrainHeightASL _randomPosAroundPlayerinWater) < 2) and ((abs getTerrainHeightASL _randomPosAroundPlayerinWater) > 1) ) then { _posAndDistanceArray pushBack [_distance1,_randomPosAroundPlayerinWater]; }; }; _posAndDistanceArray sort TRUE; _vehicleType = "B_Boat_Armed_01_minigun_F"; _closestWaterPos1 =[]; _veh = objNull; for "_i" from 0 to 1 do { _closestWaterPos1 = (_posAndDistanceArray select _i) select 1; _veh = createVehicle [_vehicleType, [_closestWaterPos1 select 0, _closestWaterPos1 select 1,0], [], 0, "NONE"]; _veh setDir (player getDir _closestWaterPos1); }; _time = time; // 200m _blackList = []; _blackList pushBack [_closestWaterPos1, 100]; _closestLandPos = [_closestWaterPos1,201,199,0,0,0.5,1,_blackList,[[0,0,0],[0,0,0]]] call BIS_fnc_findSafePos; _blackList pushBack [_closestLandPos, 100]; _posAndDistanceArray = []; for "_i" from 1 to 10 do { _timeOut = time +5; waitUntil { _randomPosAroundPlayerinWater = [[[[_closestLandPos select 0, _closestLandPos select 1,0], 40]],["ground"]] call BIS_fnc_randomPos; _distance1 = round (_closestLandPos distance _randomPosAroundPlayerinWater); (((abs (getTerrainHeightASL _randomPosAroundPlayerinWater) < 5) and ((abs getTerrainHeightASL _randomPosAroundPlayerinWater) > 1) ) or (_timeOut < time)) }; _posAndDistanceArray pushBack [_distance1,_randomPosAroundPlayerinWater]; }; _posAndDistanceArray sort TRUE; _closestWaterPos = (_posAndDistanceArray select 0) select 1; _veh = createVehicle ["B_G_Boat_Transport_01_F", [_closestWaterPos select 0, _closestWaterPos select 1,0], [], 0, "NONE"]; _veh setDir (_closestLandPos getDir _closestWaterPos); // 400m, 600m, 800m 1000m for "_i" from 1 to 4 do { _posAndDistanceArray = []; _closestLandPos = [_closestWaterPos,201,199,0,0,0.5,1,_blackList,[[0,0,0],[0,0,0]]] call BIS_fnc_findSafePos; _blackList pushBack [_closestLandPos, 100]; for "_i" from 1 to 10 do { _timeOut = time +5; waitUntil { _randomPosAroundPlayerinWater = [[[[_closestLandPos select 0, _closestLandPos select 1,0], 40]],["ground"]] call BIS_fnc_randomPos; _distance1 = round (_closestLandPos distance _randomPosAroundPlayerinWater); (((abs (getTerrainHeightASL _randomPosAroundPlayerinWater) < 5) and ((abs getTerrainHeightASL _randomPosAroundPlayerinWater) > 1) ) or (_timeOut < time)) }; _posAndDistanceArray pushBack [_distance1,_randomPosAroundPlayerinWater]; }; _posAndDistanceArray sort TRUE; _closestWaterPos = (_posAndDistanceArray select 0) select 1; _veh = createVehicle ["B_G_Boat_Transport_01_F", [_closestWaterPos select 0, _closestWaterPos select 1,0], [], 0, "NONE"]; _veh setDir (_closestLandPos getDir _closestWaterPos); }; _closestLandPos = [_closestWaterPos1,201,199,0,0,0.5,1,_blackList,[[0,0,0],[0,0,0]]] call BIS_fnc_findSafePos; _blackList pushBack [_closestLandPos, 100]; _posAndDistanceArray = []; for "_i" from 1 to 10 do { _timeOut = time +5; waitUntil { _randomPosAroundPlayerinWater = [[[[_closestLandPos select 0, _closestLandPos select 1,0], 40]],["ground"]] call BIS_fnc_randomPos; _distance1 = round (_closestLandPos distance _randomPosAroundPlayerinWater); (((abs (getTerrainHeightASL _randomPosAroundPlayerinWater) < 5) and ((abs getTerrainHeightASL _randomPosAroundPlayerinWater) > 1) ) or (_timeOut < time)) }; _posAndDistanceArray pushBack [_distance1,_randomPosAroundPlayerinWater]; }; _posAndDistanceArray sort TRUE; _closestWaterPos = (_posAndDistanceArray select 0) select 1; _veh = createVehicle ["B_G_Boat_Transport_01_F", [_closestWaterPos select 0, _closestWaterPos select 1,0], [], 0, "NONE"]; _veh setDir (_closestLandPos getDir _closestWaterPos); // 400m, 600m, 800m 1000m for "_i" from 1 to 4 do { _posAndDistanceArray = []; _closestLandPos = [_closestWaterPos,201,199,0,0,0.5,1,_blackList,[[0,0,0],[0,0,0]]] call BIS_fnc_findSafePos; _blackList pushBack [_closestLandPos, 100]; for "_i" from 1 to 10 do { _timeOut = time +5; waitUntil { _randomPosAroundPlayerinWater = [[[[_closestLandPos select 0, _closestLandPos select 1,0], 40]],["ground"]] call BIS_fnc_randomPos; _distance1 = round (_closestLandPos distance _randomPosAroundPlayerinWater); (((abs (getTerrainHeightASL _randomPosAroundPlayerinWater) < 5) and ((abs getTerrainHeightASL _randomPosAroundPlayerinWater) > 1) ) or (_timeOut < time)) }; _posAndDistanceArray pushBack [_distance1,_randomPosAroundPlayerinWater]; }; _posAndDistanceArray sort TRUE; _closestWaterPos = (_posAndDistanceArray select 0) select 1; _veh = createVehicle ["B_G_Boat_Transport_01_F", [_closestWaterPos select 0, _closestWaterPos select 1,0], [], 0, "NONE"]; _veh setDir (_closestLandPos getDir _closestWaterPos); }; hint format["_elapseTime: %1s", (time-_time)]; },"",10]; Share this post Link to post Share on other sites
barbolani 198 Posted May 29, 2018 You may unPBO Antistasi and you Will find under REINF\FIAaddVeh.sqf or garaje scripts some code for boat in wáter spawning. But I had more or less the same problema, sometimes boats spawn on land... Share this post Link to post Share on other sites
cklymowsky 1 Posted June 1, 2018 Thanks, I went with the following, it can create 12 boats spread apart along the shore line, most of the time. Sometimes it spawns them under water of on shore land despite being scripted not to. I may have to create a loop that check the status of each boat, and respawn it if it is on land or underwater. Quote // [/*center*/,/* minDist*/, /*maxDist*/, /*objDist*/, /*waterMode*/, /*maxGrad*/, /*shoreMode*/, /*blacklistPos*/, /*defaultPos*/] Beaks_fnc_moreBoats = { // Add spread of boats 400m, 600m, 800m 1000m _closestWaterPos = []; params [["_blackList", []], ["_closestWaterPos",[]], ["_boatTypeArray", []]]; _blackList pushBack [_closestWaterPos, 190]; _vehicleType = ""; for "_i" from 1 to 5 do { _vehicleType = (_boatTypeArray select 1) call BIS_fnc_selectRandom; _closestLandPos = [_closestWaterPos,201,199,0,0,0.5,1,_blackList,[[0,0,0],[0,0,0]]] call BIS_fnc_findSafePos; if !(({_x == 0} count _closestLandPos) == 3) then { _posAndDistanceArray = []; for "_i" from 1 to 25 do { _randomPosAroundPlayerinWater = [[[[_closestLandPos select 0, _closestLandPos select 1,0], 50]],["ground"]] call BIS_fnc_randomPos; _distance1 = round (_closestLandPos distance _randomPosAroundPlayerinWater); if ((abs getTerrainHeightASL _randomPosAroundPlayerinWater) > 1) then { _posAndDistanceArray pushBack [_distance1,_randomPosAroundPlayerinWater]; //_helper= createVehicle ["VR_3DSelector_01_incomplete_F", [_randomPosAroundPlayerinWater select 0, _randomPosAroundPlayerinWater select 1, 0], [], 0, "CAN_COLLIDE"]; }; }; _posAndDistanceArray sort TRUE; _countPosAndDistanceArray = count _posAndDistanceArray; _a = 0; _closestWaterPos = (_posAndDistanceArray select _a) select 1; waitUntil { if !(surfaceIsWater _closestWaterPos) then { _a = _a +1; _closestWaterPos = (_posAndDistanceArray select _a) select 1; }; ((surfaceIsWater _closestWaterPos) or (_a == _countPosAndDistanceArray)) }; _blackList pushBack [_closestWaterPos, 190]; if (surfaceIsWater _closestWaterPos) then { _veh = createVehicle [_vehicleType, [_closestWaterPos select 0, _closestWaterPos select 1,0], [], 0, "NONE"]; _veh setDir (_closestLandPos getDir _closestWaterPos); if ( (_vehicleType == "C_Scooter_Transport_01_F") or (_vehicleType == "C_Boat_Civil_01_F") )then { _closestWaterPos = (_posAndDistanceArray select 1) select 1; _veh = createVehicle [_vehicleType, [_closestWaterPos select 0, _closestWaterPos select 1,0], [], 0, "NONE"]; _veh setDir (_closestLandPos getDir _closestWaterPos); }; }; }; }; [_blackList, _closestWaterPos] }; Beaks_fnc_firstBoats = { // spawn 2 boats near nearest to position params [["_boatTypeArray", []], ["_pos",[],[[],objNull,""]]]; _pos = _pos call BIS_fnc_position; _posAndDistanceArray = []; _interations = 100; _distance1 = 0; _blackList = []; _randomPosAroundPlayerinWater = [[[_pos, 250]],["ground"]] call BIS_fnc_randomPos; if (({_x == 0} count _randomPosAroundPlayerinWater) == 2) exitWith {/*hint "NO POSITION NEAR WATER"*/}; for "_i" from 1 to _interations do { _randomPosAroundPlayerinWater = [[[_pos, 250]],["ground"]] call BIS_fnc_randomPos; _distance1 = round (_pos distance _randomPosAroundPlayerinWater); if ( ((abs getTerrainHeightASL _randomPosAroundPlayerinWater) > 1) and ((abs getTerrainHeightASL _randomPosAroundPlayerinWater) < 5) )then { _posAndDistanceArray pushBack [_distance1,_randomPosAroundPlayerinWater]; //_helper= createVehicle ["VR_3DSelector_01_incomplete_F", [_randomPosAroundPlayerinWater select 0, _randomPosAroundPlayerinWater select 1, 1], [], 0, "CAN_COLLIDE"]; }; }; _posAndDistanceArray sort TRUE; _countPosAndDistanceArray = count _posAndDistanceArray; _a = 0; _closestWaterStartingPoint =[]; _closestWaterStartingPoint = (_posAndDistanceArray select _a) select 1; _vehicleType = (_boatTypeArray select 0) call BIS_fnc_selectRandom; _veh = objNull; _addSecondBoat = FALSE; _closestLandPos = []; _closestWaterPos = []; for "_i" from 0 to 1 do { waitUntil { if (!(surfaceIsWater _closestWaterStartingPoint) or (_addSecondBoat) ) then { _a = _a +1; _closestWaterStartingPoint = (_posAndDistanceArray select _a) select 1; }; ((surfaceIsWater _closestWaterStartingPoint) or (_a == _countPosAndDistanceArray)) }; //if (surfaceIsWater _closestWaterStartingPoint) then { _veh = createVehicle [_vehicleType, [_closestWaterStartingPoint select 0, _closestWaterStartingPoint select 1,0], [], 0, "NONE"]; _veh setDir (_pos getDir _closestWaterStartingPoint); //}; _addSecondBoat = TRUE; }; for "_i" from 0 to 1 do { // Add spread of boats 200m, 400m, 600m, 800m 1000m AND on both sides with second loop _oneBoatOutputArray = [_blackList,_closestWaterStartingPoint, _boatTypeArray] call Beaks_fnc_moreBoats; }; }; player addAction ["<t color='#00ff00' t size='1' >CHAIN of BOATS spread 200m</t>", { _time = time; [[["O_Boat_Armed_01_hmg_F"],["C_Rubberboat","C_Boat_Civil_01_F","C_Boat_Transport_02_F","C_Scooter_Transport_01_F"]],player] call Beaks_fnc_firstBoats; hint format["_elapseTime: %1s", (time-_time)]; //hint format["_elapseTime: %1s \n\n _posAndDistanceArray: \n %2 \n\n select _a: \n %3", (time-_time), _posAndDistanceArray, (_posAndDistanceArray select _a)]; },"",10]; ///////////////////////////////////////////////////////////////////////////////////////////////////////////// player addAction ["<t color='#00ff00' t size='1' >DELETE</t>", { _time = time; {deleteVehicle _x}forEach vehicles; waitUntil { (count vehicles == 0) }; hint format["_elapseTime: %1s", (time-_time)]; },"",10]; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// Share this post Link to post Share on other sites
gokitty1199 225 Posted June 1, 2018 you can get various positions such as along roads/towns via the config of the map your on. check and see if theres one for something along the lines of where your looking for Share this post Link to post Share on other sites
cklymowsky 1 Posted June 1, 2018 2 minutes ago, gokitty1199 said: you can get various positions such as along roads/towns via the config of the map your on. check and see if theres one for something along the lines of where your looking for Thanks, but how do I find these? Currently I use "ground" in my script for blacklist areas: _randomPosAroundPlayerinWater = [[[_pos, 250]],["ground"]] call BIS_fnc_randomPos; Share this post Link to post Share on other sites
gokitty1199 225 Posted June 1, 2018 50 minutes ago, cklymowsky said: Thanks, but how do I find these? Currently I use "ground" in my script for blacklist areas: _randomPosAroundPlayerinWater = [[[_pos, 250]],["ground"]] call BIS_fnc_randomPos; go into editor and press esc and click configs and find cfgWorlds(i think) and start lookin Share this post Link to post Share on other sites
MKD3 27 Posted June 2, 2018 I had a bit of a play around from curiosity. Here's is a basic, find water position function I came up with. Not exactly what you want, but you might be able to use some of whats in it. //Number of positions private _boatCount = 10; //Settings private _minRange = 200; private _maxRange = 600; private _centrePos = getpos player; private _waterPosArray = []; //Generate Array for "_i" from 1 to _boatCount do { private _distance = floor random _maxRange; private _waterPos = [_centrePos, _minRange, _distance, 3, 2, 20, 0] call BIS_fnc_findSafePos; //Check if position is above water if (!(_waterPos isFlatEmpty [-1, -1, -1, -1, 2, false] isEqualTo [])) then { //Boat, not submarine _waterpos set [2, 0.5]; _waterPosArray pushback _waterpos; }; }; _waterPosArray; This is the sort of results I was getting, X being the centre and squares being the points. If it cant find anything, it returns an empty array. Good luck! Share this post Link to post Share on other sites
Rydygier 1317 Posted June 2, 2018 I'm using following solution based on selectBestPlaces in Pilgrimage to spawn a dozen or so boats around the map, additionally close to the piers etc. At times it may produce position colliding with a pier though, then boat lands on the pier (it wasn't so earlier, but required precision was apparently too high and could cause serious problems like CTD even): _boatSpots = []; _expression = "((waterDepth factor [1,1.4])/(1 + waterDepth)) * ((randomGen(houses factor [0.1,0.6]))/(1 + houses))"; _value = selectBestPlaces [_mapC,_rds,_expression,15,12]; { _boatSpots set [(count _boatSpots),_x select 0]; } foreach _value; However it's used under loadingScreen, don't know, how fast it would be on the simulation fly, but hopefully may give some inspiration at least. Share this post Link to post Share on other sites
barbolani 198 Posted June 4, 2018 Idea: What if you use this? https://community.bistudio.com/wiki/AGLToASL Pick a position which you know it's land as reference (position player). Make a loop of searching for psitions in several (at least 4) angles from the reference position in a distance of lets say 150 mts. If surfaceIsWater returns true, you know now there is wáter nearby and on which relative angle. Now we have to loop on that angle, increasing distances from the reference position. On each iteration you have the position in _pos: _pos set [2,0]; _posASL = AGLtoASL _pos; if (_posASL select 2 < 3) exitWith {hint "The wáter is 3mts Depth so here my boat wont get stuck";}; Untested, made while I'm bored at the office. Share this post Link to post Share on other sites