Jump to content
Sign in to follow this  
surfer

Determine if unit is outside a building?

Recommended Posts

As the title says I would like to run a test for units that are not inside buildings. This is what I've got but it's far from being perfect:

{
if ((_x distance (nearestbuilding getpos _x)) > 10) then
	{
// get damaged by heavy rain etc.
}
} forEach allUnits;

Unfortunately this doesn't account if the building is small or large, so on small buildings 10 m from the center you're still standing inside. Vice versa for large buildings.

I'm sure there's a more elegant way. Thanks for sharing! :-)

Edited by Surfer

Share this post


Link to post
Share on other sites

You could use lineIntersectsObjs to draw a line from unit position to 20m above the units position and let the filter detect any buildings.

This way units will still get damaged when standing under a tree (doesn't really offer too much protection from rain etc.)

Might be what you're looking for.

Share this post


Link to post
Share on other sites

Thanks, Grumpy Old Man,

How would I have to adapt the below code to get it to work, please? I know the +[0,0,20] is adding to the end of the array which is wrong but don't know how to achieve what I want.

 if	(lineintersectsobjs [getpos _x, (getpos _x +[0,0,20])]) = nul then
	{
	hint "unit is outside building";
	};
} foreach allUnits;

Share this post


Link to post
Share on other sites

You'd want to use getposATL or ASL since both are way faster, especially when checking on multiple units.

As starting position you use:

getposATL _x;

Endposition:

[(getposATL _x select 0),(getposATL _x select 1),(getposATL _x select 2)+20];

Cheers

Share this post


Link to post
Share on other sites

Have you tried boundingbox on a house object, I haven't used that command in years but I think it's worth a look at

Share this post


Link to post
Share on other sites

@Grumpy Old Man, I think we are close but there's an error in this and I'm not experienced enough to find it. Can you help once more please?

 {
if	((lineintersectsobjs [getposATL _x, [(getposATL _x select 0),(getposATL _x select 1),(getposATL _x select 2)+20]]) == []) then
{
	// bad things coming if you didn't find shelter
	};
} foreach allunits;

Share this post


Link to post
Share on other sites

some time ago i put together a function to test something, maybe you can alter it to your purpose...

private ["_unitPos","_offsetASL","_X","_Y","_Z","_o","_objects","_result"];
// usage:   _unit call fIsUnitUnderRoof;
// returns objNull, or the house/object the unit is underneath
#define BEAM_LENGTH 10

_unitPos = getPosASL _this;
_offsetASL = _unitPos Distance (getPosATL _this); // TODO: for debugging, remove later
_unitPos Set [2, (_unitPos select 2) + 1.3]; // add something so the beam wont start at character feet where it could intersect with building stairs or furniture
_X = _unitPos select 0;
_Y = _unitPos select 1;
_Z = _unitPos select 2;
_o = objNull;
_result = objNull;

// Simplified calculation of triangle points offsets from the centroid (player pos)
// offset A = [    0,    -1]
// offset B = [-0.95, +0.65]
// offset C = [+0.95, +0.65]

_objects = lineIntersectsWith [[_X,_Y - 1,_Z], [_X,_Y - 1,_Z + BEAM_LENGTH], _this, _this, true]; // point A
drawLine3D [[_X,_Y - 1,_Z - _offsetASL], [_X,_Y - 1,_Z + BEAM_LENGTH - _offsetASL], [0,0,1,1]]; // TODO: for debugging, remove later
if (count _objects > 0) then {
_o = _objects select 0;
_objects = lineIntersectsWith [[_X - 0.95,_Y + 0.65,_Z], [_X - 0.95, _Y + 0.65, _Z + BEAM_LENGTH], _this, _this, true];  // point B
drawLine3D [[_X - 0.95,_Y + 0.65,_Z - _offsetASL], [_X - 0.95, _Y + 0.65, _Z + BEAM_LENGTH - _offsetASL], [0,0,1,1]]; // TODO: for debugging, remove later
if (count _objects > 0) then {
	if (_o == _objects select 0) then {
		_objects = lineIntersectsWith [[_X + 0.95,_Y + 0.65,_Z], [_X + 0.95, _Y + 0.65, _Z + BEAM_LENGTH], _this, _this, true];  // point C
		drawLine3D [[_X + 0.95,_Y + 0.65,_Z - _offsetASL], [_X + 0.95, _Y + 0.65, _Z + BEAM_LENGTH - _offsetASL], [0,0,1,1]]; // TODO: for debugging, remove later
		if (count _objects > 0) then {
			if (_o == _objects select 0) then {_result = _o};
		};
	};
};

};

drawLine3D [[_X, _Y -1, 0.1], [_X -0.95, _Y +0.65, 0.1], [0,0,1,10]]; // TODO: for debugging, remove later
drawLine3D [[_X -0.95, _Y +0.65, 0.1], [_X +0.95, _Y +0.65, 0.1], [0,0,1,1]]; // TODO: for debugging, remove later
drawLine3D [[_X, _Y -1, 0.1], [_X +0.95, _Y +0.65, 0.1], [0,0,1,1]]; // TODO: for debugging, remove later

_result

Share this post


Link to post
Share on other sites
@Grumpy Old Man, I think we are close but there's an error in this and I'm not experienced enough to find it. Can you help once more please?

 {
if	((lineintersectsobjs [getposATL _x, [(getposATL _x select 0),(getposATL _x select 1),(getposATL _x select 2)+20]]) == []) then
{
	// bad things coming if you didn't find shelter
	};
} foreach allunits;

Can you post the error?

Share this post


Link to post
Share on other sites

Don't know how to copy & paste from the error, so I'm writing it down:

|#| == type Array, expected Number in line 2

---------- Post added at 10:31 ---------- Previous post was at 10:28 ----------

Thanks Squeeze, I found some old code regarding boundigbox but I hoped there would be a more streamlined option.

Also thanks, 5133p39, but this code to me is just "$%&§$&"§%&/%/$%/$%/""§$", hehe :confused:

Share this post


Link to post
Share on other sites

Ah, as expected, the comparison (==) fails. Try (untested):

{
if (count(lineIntersectsObjs [(getposATL _x), [(getposATL _x select 0),(getposATL _x select 1),((getposATL _x select 2) + 20)]]) == 0) then {
	// bad things coming if you didn't find shelter
   };
} forEach allUnits;

Share this post


Link to post
Share on other sites

Remember to use ASL co-ordinatess else you will find your results are wrong. Either GetPosASL or ATLtoASL (GetPosATL #).

Have you tried boundingbox on a house object, I haven't used that command in years but I think it's worth a look at

I thought about suggesting that aswell Squeeze, trouble is on alot of houses the bounding area extends way past the model.

Share this post


Link to post
Share on other sites

Thanks to Larrow I've changed the getpos to ASL and now it works like a charm! It's not restricted to houses for cover but trees and roofs and probably a lot of other stuff all give cover which is absolutely fine for me. I'm super happy now! Thanks everybody! This community rocks!!!

Here's the working code:

{
if (count(lineIntersectsObjs [(getposASL _x), [(getposASL _x select 0),(getposASL _x select 1),((getposASL _x select 2) + 20)]]) == 0) then
{
	// bad things happening if you didn't find cover
   };
} forEach allUnits;

Edited by Surfer
  • Like 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
Sign in to follow this  

×