AlliedModders

AlliedModders (https://forums.alliedmods.net/index.php)
-   Scripting Help (https://forums.alliedmods.net/forumdisplay.php?f=11)
-   -   is user in between (https://forums.alliedmods.net/showthread.php?t=92987)

whosyourdaddy 05-22-2009 23:37

is user in between
 
lets say i have 2 origins, origina[3] and originb[3], how can i check if a user is in between these 2 spots?

Hunter-Digital 05-22-2009 23:47

Re: is user in between
 
trace_line()
I never used it but it looks like it "shoots" a line from start to end and if it hits something it returns it, also I think it returns the origin that it hit the ent in 4th param
You should also check if the ent returned is a player... with if(1 <= ent <= 32) (replace 32 with your maxplayers var)

1st it's obvious, ignore an ent... I'm not sure about this but if you set it to 0 it might go through walls xD, -1 I think is the "don't ignore anything" setting... but as I said, never used it so I'm not sure, just assuming :P

You can also look at http://forums.alliedmods.net/showthread.php?p=663892 or http://forums.alliedmods.net/showthread.php?t=66564 for their laser break detecting method

Bugsy 05-22-2009 23:58

Re: is user in between
 
Try this

Param1 = Player to check
param2 = One of the outside origins
Param3 = The other outside origin

PHP Code:

public IsWithinid FloatfOrigin1[3] , FloatfOrigin2[3] )
{
    new 
FloatfOrigin[3];
    new 
FloatfDistWithin get_distance_ffOrigin1 fOrigin2 );
    
pevid pev_origin fOrigin );
    
    return ( ( 
fDistWithin get_distance_ffOrigin fOrigin1 ) ) && ( fDistWithin get_distance_ffOrigin fOrigin2 ) ) );


Or you can check origins manually:

param1 = The origin to check
param2 = One of the outside origins
Param3 = The other outside origin

Using float origins:
PHP Code:

public IsWithinFloatfOriginCheck[3] , FloatfOrigin1[3] , FloatfOrigin2[3] )
{
    new 
FloatfDistWithin get_distance_ffOrigin1 fOrigin2 );

    return ( ( 
fDistWithin get_distance_ffOriginCheck fOrigin1 ) ) && ( fDistWithin get_distance_ffOriginCheck fOrigin2 ) ) );


Non-float:
PHP Code:

public IsWithiniOriginCheck[3] , iOrigin1[3] , iOrigin2[3] )
{
    new 
iDistWithin get_distanceiOrigin1 iOrigin2 );

    return ( ( 
iDistWithin get_distanceiOriginCheck iOrigin1 ) ) && ( iDistWithin get_distanceiOriginCheck iOrigin2 ) ) );



Hunter-Digital 05-23-2009 00:10

Re: is user in between
 
My sugestions checks the two origins if there's anything between them
Bugsy's sugestions checks if the user is between the origins

Use wich one fits best in your case

whosyourdaddy 05-23-2009 00:36

Re: is user in between
 
the non float one isnt working correctly... i want it where they need to be exactly in between the 2 points no more than 85 units if u do get_distance with the origin and user origin

Bugsy 05-23-2009 00:40

Re: is user in between
 
It should work just as the float one does since it is 100% identical except uses ints instead of floats.

Ok so you want to check if player 1 is standing directly between player 2 and 3? Like, if you tried to draw a line from player 2 to player 3, you want it to hit player 1?

whosyourdaddy 05-23-2009 00:53

Re: is user in between
 
ya

Bugsy 05-23-2009 01:11

Re: is user in between
 
Try this, I am not sure if it will work though:

PHP Code:

public IsBetweenid FloatfOrigin1[3] , FloatfOrigin2[3] )
{
    
engfuncEngFunc_TraceLine fOrigin1 fOrigin2 DONT_IGNORE_MONSTERS )

    return ( (
get_tr2(0TR_pHit) == id) ? 0)



whosyourdaddy 05-23-2009 01:14

Re: is user in between
 
wont this work?
Code:

    if( iOrigin1[0] <= iOriginCheck[0] <= iOrigin2[0] && iOrigin1[1] <= iOriginCheck[1] <= iOrigin2[1] && iOrigin1[2] >= iOriginCheck[2] >= iOrigin2[2] )
my origin arent floats eather so ya..... and theres something wrong with my logic i just cant see it

also can i do like get_distance(origin1[1],origin2[1])

stupok 05-23-2009 04:10

Re: is user in between
 
Quote:

Originally Posted by whosyourdaddy (Post 832852)
wont this work?
Code:

    if( iOrigin1[0] <= iOriginCheck[0] <= iOrigin2[0] && iOrigin1[1] <= iOriginCheck[1] <= iOrigin2[1] && iOrigin1[2] >= iOriginCheck[2] >= iOrigin2[2] )

I don't think you understand what you're doing with this.

First, you should be consistent with your usage of '<='. You're using '>=' for the z dimension.

If you changed the '>=' to be consistent with the instances of '<=', then you'd be defining the boundaries of a box and checking if the player is inside this box. iOrigin1 is one corner of the box and iOrigin2 is the opposite corner of the box.

This is not your desired behavior.

Quote:

Originally Posted by whosyourdaddy (Post 832852)
my origin arent floats eather so ya..... and theres something wrong with my logic i just cant see it

Look these up:

IVecFVec()
FVecIVec()

There's no problem converting between floats and integers.

Quote:

Originally Posted by whosyourdaddy (Post 832852)
also can i do like get_distance(origin1[1],origin2[1])

No.

Code:

distance = abs( origin1[1] - orgin2[1] )
_____________________________________________ ______

You can use bugsy's code to run a traceline between the two points to see if it hits the player, but there are obvious limitations with this method. If there are obstacles along the traceline or if the origins are not located within the boundaries of the map, then it will fail.

I propose this simple test to see if the player is between the origins.

Code:
IsBetween(id, iPos1[3], iPos2[3]) {     new iPlayerPos[3]     get_user_origin(id, iPlayerPos)         new Float:fPlayerPos[3], Float:fPos1[3], Float:fPos2[3]     IVecFVec(iPlayerPos, fPlayerPos)     IVecFVec(iPos1, fPos1)     IVecFVec(iPos2, fPos2)         new Float:fPosVec[3], Float:fPlayerVec1[3], Float:fPlayerVec2[3]     xs_vec_sub(fPos1, fPos2, fPosVec)     xs_vec_normalize(fPosVec, fPosVec)         xs_vec_sub(fPos1, fPlayerPos, fPlayerVec1)     xs_vec_normalize(fPlayerVec1, fPlayerVec1)         xs_vec_sub(fPlayerPos, fPos2, fPlayerVec2)     xs_vec_normalize(fPlayerVec2, fPlayerVec2)         return !(xs_vec_dot(fPosVec, fPlayerVec1) < 0 || xs_vec_dot(fPosVec, fPlayerVec2) < 0) }

This checks the angle between vectors to determine if the player is between the two origins.

I'm assuming that your desired behavior is to detect if a player is between two planes. That is, two parallel (non-intersecting) planes with a space between them. If the player is in this space between the planes, then he is, according to you, "between the origins".

So, we get the vector between the two test origins, V0.
Next, we get the vector between the first test origin and the player, V1.
Next, we get the vector between the second test origin and the player, V2.

If the angle between V0 and V1 is greater than 90 degrees, then the player is not in the space between the parallel planes. The same relationship exists for V0 and V2.

In the code, I'm using the cosine of the angle (or dot product of the vectors) rather than the actual angle, because it's an unnecessary calculation to get the actual angle. If the cosine is < 0, then the angle is greater than 90.

I suspect this method will work for all cases, and my tests indicate that it works. However, don't trust me. Test it for yourself.

_____________________________________________ ________

There's another way. You can test for the "k value" of a point with respect to a plane. A plane's k value can be calculated by doing the dot product of a point on the plane with the planes normal. See here.

Anyways, here's the result:

Code:
IsBetween2(id, iPos1[3], iPos2[3]) {     new iPlayerPos[3]     get_user_origin(id, iPlayerPos)         new Float:fPlayerPos[3], Float:fPos1[3], Float:fPos2[3]     IVecFVec(iPlayerPos, fPlayerPos)     IVecFVec(iPos1, fPos1)     IVecFVec(iPos2, fPos2)         new Float:fNorm1[3], Float:fNorm2[3]     xs_vec_sub(fPos1, fPos2, fNorm2)     xs_vec_normalize(fNorm2, fNorm2)         xs_vec_sub(fPos2, fPos1, fNorm1)     xs_vec_normalize(fNorm1, fNorm1)         return !(xs_vec_dot(fPlayerPos, fNorm1) < xs_vec_dot(fPos1, fNorm1) || xs_vec_dot(fPlayerPos, fNorm2) < xs_vec_dot(fPos2, fNorm2)) }

It's slightly less code, I like it. The results for each function seem to agree, so you can use either one. I recommend the one with less code.


All times are GMT -4. The time now is 01:33.

Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.