Jump to content
iV - Ghost

Random buildingPos in a random building

Recommended Posts

I tried to create a box on a random buildingPos in a random building.

But till now it doesn't work...

 

fn_randomBox.sqf

// FIND RANDOM BUILDING POSITION
private ["_pos", "_types", "_radius", "_allBuildings", "_building", "_allBuildingPos", "_buildingDir", "_crate", "_crateType", "_varName", "_cargoType", "_cargoAmount", "_spawnPos"];

_pos = _this select 0;
_types = _this select 1;
_radius = _this select 2;
_crateType = _this select 3;
_varName = _this select 4;
_cargoType = _this select 5;
_cargoAmount = _this select 6;


// FIND RANDOM BUILDING POSITION
_allBuildings = nearestTerrainObjects [_pos, _types, _radius, false, true];
_building = selectRandom _allBuildings;
_allBuildingPos = _building buildingPos -1;
_spawnPos = selectRandom _allBuildingPos;



// RUN ON DEDICATED SERVER OR PLAYER HOST
if (isServer) then {

    // CREATE CRATE
    _crate = _crateType createVehicle _spawnPos;
    _buildingDir = getDir _building;
    _crate setDir _buildingDir;
	
	
    // CARGO
    clearWeaponCargoGlobal _crate;
    clearMagazineCargoGlobal _crate;
    clearItemCargoGlobal _crate;
    clearBackpackCargoGlobal _crate;
    _crate addMagazineCargoGlobal [_cargoType, _cargoAmount];
	
	
    // VARIABLENAME
    _crate setVehicleVarName _varName;
    missionNamespace setVariable [_varName, _crate];
    publicVariable _varName;
	
};

 

And this is in my task.sqf:

// CREATE BOX
[getMarkerPos "M_Exfil_Airbase_1", ["House"], 420, "Land_PlasticCase_01_medium_F", "Weaponry_Airbase_1", "ATMine_Range_Mag", 15] call iV_fnc_randomBox;

 

 

Share this post


Link to post
Share on other sites
_allBuildings = nearestTerrainObjects [_pos, _types, _radius, false, true];
_allPositions = [];
_allBuildings apply {_allPositions append (_x buildingPos -1)};
_rndPos = selectRandom _allPositions;

Should pick a random position out of all buildings, as long as there are buildings.

 

Cheers

Share this post


Link to post
Share on other sites

Just one thing, general comment, regardless of the GOM optimization:

 

private ["_pos", "_types", "_radius", "_allBuildings", "_building", "_allBuildingPos", "_buildingDir", "_crate", "_crateType", "_varName", "_cargoType", "_cargoAmount", "_spawnPos"];

_pos = _this select 0; _types = _this select 1; _radius = _this select 2; _crateType = _this select 3; _varName = _this select 4; _cargoType = _this select 5; _cargoAmount = _this select 6;

 

should be, simple as :

params ["_pos", "_types", "_radius", "_crateType", "_varName", "_cargoType", "_cargoAmount","_allBuildings", "_building", "_allBuildingPos", "_buildingDir", "_crate", "_spawnPos"];

 

In other words, all your <_this> selections must comply with their index! Then you can add local variables you want to declare,.. at the end.

  • Thanks 1

Share this post


Link to post
Share on other sites

The crate spawned on a pier (Land_Pier_F).

Is it a kind of "House"?

Share this post


Link to post
Share on other sites
1 hour ago, iV - Ghost said:

The crate spawned on a pier (Land_Pier_F).

Is it a kind of "House"?

Sure (with building positions btw)

Share this post


Link to post
Share on other sites

I had hoped that the "House" are only houses. Now I've tried it with...

 

// FIND RANDOM BUILDING POSITION
_allBuildings = nearestObjects [_pos, "Land_Cargo_House_V1_F", _radius];
_allBuildingPos = [];
_allBuildings apply {_allBuildingPos append (_x buildingPos -1)};
_spawnPos = selectRandom _allBuildingPos;

...but the box not standing inside the building. The box standing under!

 

 

My second problem is the direction. How can I get the getDir from the selected _spawnPos building?

Share this post


Link to post
Share on other sites
41 minutes ago, iV - Ghost said:

I had hoped that the "House" are only houses. Now I've tried it with...

 


// FIND RANDOM BUILDING POSITION
_allBuildings = nearestObjects [_pos, "Land_Cargo_House_V1_F", _radius];
_allBuildingPos = [];
_allBuildings apply {_allBuildingPos append (_x buildingPos -1)};
_spawnPos = selectRandom _allBuildingPos;

...but the box not standing inside the building. The box standing under!

 

 

My second problem is the direction. How can I get the getDir from the selected _spawnPos building?

The basic syntax of createvehicle creates the object at 2d position, use setposATL after spawning the box.

 

Cheers

  • Thanks 1

Share this post


Link to post
Share on other sites

Nice, the first problem is solved. Thx.

Any ideas how to get the direction of the _spanPos building?

 

Share this post


Link to post
Share on other sites
16 hours ago, iV - Ghost said:

Nice, the first problem is solved. Thx.

Any ideas how to get the direction of the _spanPos building?

 

Needs a different approach:

 

// FIND RANDOM BUILDING POSITION

//only grab buildings with positions, also needs an array of types, not a string as in your previous example
_allBuildings = (nearestObjects [_pos, ["Land_Cargo_House_V1_F"], _radius] select {_x buildingPos -1 != []});

_rndBuilding = selectRandom _allBuildings;

_rndPos = selectRandom (_rndBuilding buildingPos -1);
_dir = direction _rndBuilding;

Pretty basic stuff, really.

 

Cheers

  • Like 1
  • Thanks 1

Share this post


Link to post
Share on other sites

I'm getting a error:

 

Quote

...select {_x buildingPos -1 [%]!= []});

 

Type array, need string.

Share this post


Link to post
Share on other sites
21 minutes ago, iV - Ghost said:

I'm getting a error:

 

 

Type array, need string.

 

Change the line to:

_allBuildings = (nearestObjects [_pos, ["Land_Cargo_House_V1_F"], _radius] select {!(_x buildingPos -1 isEqualTo [])});

Cheers

  • Thanks 1

Share this post


Link to post
Share on other sites

Btw, don't wirte someArray != anotherarray   use:  ! (someArray isEqualTo anotherArray)

  • Thanks 1

Share this post


Link to post
Share on other sites

gents, i stumbled over this and was hoping u might be able to help me with my problem. i want to have the below script only spawn stuff at one of the available building positions but i do not understand what to change, any ideas?

 

I would assume it is this part:  "    _buildingPositions = [_x] call BIS_fnc_buildingPositions;" but not sure what to change..

 

here is my script:

 

 

_markerPos = getPos player;

_ItemArray = [
//common items, list 4x
"rvg_plasticBottleEmpty",
....
//rare items, list once
"rvg_sleepingBag_Blue",
"rvg_foldedTent",
"rvg_money",
"rvg_toolkit",
"rvg_Geiger",
"rvg_tire"
];

_itemBoxArray = [];

_houseArray = _markerPos nearObjects ["house",1200];

{
    _buildingPositions = [_x] call BIS_fnc_buildingPositions;
    {

     if(50>=random 100) then{ 
        _Item = _ItemArray select (floor (random (count _ItemArray)));
        _itemBox = "groundweaponholder" createVehicle [0,0,0];
        _itemBox setPos _x;
        _itemBox addItemCargo [_Item,1];
        _itemBoxArray = _itemBoxArray + [_itemBox];}
    } forEach _buildingPositions;
} forEach _houseArray;

sleep 900;
{
    deleteVehicle _x;
} forEach _itemBoxArray;

 

Share this post


Link to post
Share on other sites

@Grumpy Old Man This is great Grumpy, one question.

If i need to check if the position is already occupied, is the nearEntities command the best way to do it?

private _allBuildings = (nearestObjects [_markerpos, ["building"], 100] select {!(_x buildingPos -1 isEqualTo [])});

private _rndBuilding = selectRandom _allBuildings;

private _pos = selectRandom (_rndBuilding buildingPos -1);

private _nearestTargets = _pos nearEntities ["Man",1] select 0;

if (!isNil "_nearestTargets") then {
spawn units code;
};

 

Share this post


Link to post
Share on other sites
1 hour ago, Robustcolor said:

@Grumpy Old Man This is great Grumpy, one question.

If i need to check if the position is already occupied, is the nearEntities command the best way to do it?

 

While nearEntities is pretty fast and checks a sphere this will only work if the units are stationary on the building positions.

 

You could have 2 arrays, one holding all positions, and another one holding all occupied positions.

When you spawn a unit you can check if the position is already occupied, if not spawn a unit there and put the position into the occupied array.

You can free occupied positions either by a killed eventHandler or after a certain time, plenty of ways to go about this.

 

Cheers

Share this post


Link to post
Share on other sites

@Grumpy Old Man What's the big difference between these codes you provided here? Which one you suggest using when considering efficiency?

private _allBuildings = nearestObjects [_markerpos,["building"],100];
private _allBuildingPos = [];
_allBuildings apply {_allBuildingPos append (_x buildingPos -1)};
private _pos = selectRandom _allBuildingPos;

vs

private _allBuildings = (nearestObjects [_markerpos, ["building"], 100] select {!(_x buildingPos -1 isEqualTo [])});
private _rndBuilding = selectRandom _allBuildings;
private _pos = selectRandom (_rndBuilding buildingPos -1);

How does the isEqualTo work here? Is it necessary?

Share this post


Link to post
Share on other sites

Will this stack units on top of each other when spawned inside buildings? Grumpy talked about using 2 arrays, one more for storing occupied positions. How would it look like?

private _allBuildings = nearestObjects [_markerpos,["building"],100];
private _allBuildingPos = [];
_allBuildings apply {_allBuildingPos append (_x buildingPos -1)};
private _pos = selectRandom _allBuildingPos;

 

Share this post


Link to post
Share on other sites
14 hours ago, Robustcolor said:

Will this stack units on top of each other when spawned inside buildings? Grumpy talked about using 2 arrays, one more for storing occupied positions. How would it look like?


private _allBuildings = nearestObjects [_markerpos,["building"],100];
private _allBuildingPos = [];
_allBuildings apply {_allBuildingPos append (_x buildingPos -1)};
private _pos = selectRandom _allBuildingPos;

 

Why the excessive use of private?

 

You could approach it like this:

//init.sqf or where you think fits best
TAG_fnc_occupiedPositions = [];
TAG_fnc_availablePositions = [];

_allBuildings = nearestObjects [_markerpos,["building"],100];
_allBuildings apply {TAG_fnc_availablePositions append (_x buildingPos -1)};


//when spawning a unit
if !(TAG_fnc_availablePositions isEqualTo []) then {
	_posIndex = round random count TAG_fnc_availablePositions - 1;
	_pos = TAG_fnc_availablePositions # _posIndex;
	_unit = createGroup east createUnit [typeOf player,_pos];
	TAG_fnc_occupiedPositions pushBack (TAG_fnc_availablePositions deleteAt _posIndex);//move position to occupied array
	_unit setVariable ["TAG_fnc_spawnPosID",_posIndex];
	_unit addEventHandler ["Killed",{
		params ["_unit"];
		_posIndex = _unit getVariable ["TAG_fnc_spawnPosID",-1];
		TAG_fnc_availablePositions pushBack (TAG_fnc_occupiedPositions deleteAt _posIndex);
		diag_log format ["Unit died - Clearing position index %1",_posIndex];
	}];
} else {
	diag_log "Cancelled AI spawn - no more available positions"
};

Not tested and just quickly typed, should work though, adjust as you seem fit.

This will allow to only spawn one unit per position and locks the position until the unit has died.

Should get you started.

 

Cheers

  • Like 1

Share this post


Link to post
Share on other sites

I've been messing around abit with all these codes trying to figure out a better way to random select how many buildings that should append buildingpositions to the array since i know how many positions i need.


This is how it looks like now and it gives me 0.746ms. when testing the speed of it.

_allBuildings = player nearObjects ["building", 250];

 _allBuildingPos = [];

_allBuildings  apply {_allBuildingPos append (_x buildingPos -1)};

If i would try to select [0,15] of the positions and append the buildingPos it would give 0.193ms, but the problem is that those 0 - 15 is not randomized. Any clue how to solve it?

_allBuildings = player nearObjects ["building", 250];

 _allBuildingPos = [];

_allBuildings select [0,15] apply {_allBuildingPos append (_x buildingPos -1)};

 

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

×