Jump to content
cklymowsky

Spawning boats spread out along shoreline

Recommended Posts

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

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

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

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
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
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

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. 
u9Vac7Y.jpg

Good luck!
 

Share this post


Link to post
Share on other sites

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

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

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now

×