Author Topic: How would you detect if a player is within a certain range?  (Read 811 times)

I want to make an add-on. To make it, I need to know how to detect if a player is within a certain radius of a brick, say, 128 1x1 bricks.
Can somebody please say which function to use or how to do it?


%brickpos = %brick.getpoeition();
%playerpos = %player.getposition();
if(vectordist(%brickpos, %playerpos) > (128 / 2))
    doStuff()


%brickpos = %brick.getpoeition();
%playerpos = %player.getposition();
if(vectordist(%brickpos, %playerpos) > (128 / 2))
    doStuff()

128 / 2 ? Lol................


128 / 2 ? Lol................
To find the distance of 128 1x1 bricks in Torque units horizontally, you'd divide by two. (Or multiply by 0.5, same thing.)

A function using the same principle behind what Mold said:
Code: [Select]
function fxDTSBrick::PlayerWithinRange(%this, %player, %studs)
{
return vectorDist(%this.getPosition(), %player.getPosition()) <= %studs * 0.5;
}

You can also use initContainerRadiusSearch, but that's probably not nearly as efficient if you have the player and brick objects both already.
« Last Edit: August 14, 2012, 07:14:52 PM by otto-san »

-meaning-

Ahh, I thought he was just dividing it by 2 for no apparent reason lol..

Ahh, I thought he was just dividing it by 2 for no apparent reason lol..
Yeah, I had to look back at OP for a second too.

So in my case, I have the player object only.

I need the player(client) to search if the brick is within 128 horizontal units.
In essence, I want it to work kind of like the radio mod on RTB (though that's broken), where the client detects if a radio brick is within range.
So how would I use initContainerRadiusSearch to make the radio brick detect the client?
« Last Edit: August 14, 2012, 08:35:32 PM by hammereditor² »

So in my case, I have the player object only.

I need the player(client) to search if the brick is within 128 horizontal units.
In essence, I want it to work kind of like the radio mod on RTB (though that's broken), where the client detects if a radio brick is within range.
So how would I use initContainerRadiusSearch to make the radio brick detect the client?

There are a number of ways to do it, I don't know which one would be more efficient.

Code: [Select]
function Player::getSpecialBrickInRange(%this, %range)
{
initContainerRadiusSearch(%this.getPosition(), %range * 0.5, $TypeMasks::fxBrickObjectType);
for(%i = containerSearchNext(); isObject(%i); %i = containerSearchNext())
{
if(%i.isSpecial)
return %i;
}
return -1;
}
This could be one way of doing it, and you run that on any player you want to test with. Modify it as needed.
The issue with this is that it may lag with larger numbers of bricks, especially with high playercounts if you're doing something like radios.

Another way could be to log every brick that you would want to search with and compare distances with the function we made before.
Code: [Select]
for(%i = 0; %i < $allSpecialBricksCt; %i++)
{
%x = $allSpecialBricks[%i].PlayerWithinRange(%player, 128);
//do stuff if %x returns true/false
}
This could potentially also be bad if you have lots of special bricks, but really it just depends.

There are a number of ways to do it, I don't know which one would be more efficient.

Code: [Select]
function Player::getSpecialBrickInRange(%this, %range)
{
initContainerRadiusSearch(%this.getPosition(), %range * 0.5, $TypeMasks::fxBrickObjectType);
for(%i = containerSearchNext(); isObject(%i); %i = containerSearchNext())
{
if(%i.isSpecial)
return %i;
}
return -1;
}
This could be one way of doing it, and you run that on any player you want to test with. Modify it as needed.
The issue with this is that it may lag with larger numbers of bricks, especially with high playercounts if you're doing something like radios.

Another way could be to log every brick that you would want to search with and compare distances with the function we made before.
Code: [Select]
for(%i = 0; %i < $allSpecialBricksCt; %i++)
{
%x = $allSpecialBricks[%i].PlayerWithinRange(%player, 128);
//do stuff if %x returns true/false
}
This could potentially also be bad if you have lots of special bricks, but really it just depends.

Thank you. I'll try out both ways.
Well, it's better for me if this is resource-intensive on the server's side. I can't let the client have so much lag.

And also, I'm confused at how the first and second function work. I want to know how they work because I'll probably need to replace some of the code with my own stuff.

Edit: Never mind I got the second one but im still confused with the first, and how would you use the second one with that function you made before?
« Last Edit: August 14, 2012, 08:55:03 PM by hammereditor² »

Thank you. I'll try out both ways.
Well, it's better for me if this is resource-intensive on the server's side. I can't let the client have so much lag.

And also, I'm confused at how the first and second function work. I want to know how they work because I'll probably need to replace some of the code with my own stuff.
Right.

Code: [Select]
function Player::getSpecialBrickInRange(%this, %range)
{
initContainerRadiusSearch(%this.getPosition(), %range * 0.5, $TypeMasks::fxBrickObjectType); //Start a container search in the range we want with the player at the centre. Look only for objects that have the fxBrickObject typemask.
for(%i = containerSearchNext(); isObject(%i); %i = containerSearchNext()) //Start a loop with the first object the search finds. Keep going until it finds something that doesn't exist.
{
if(%i.isSpecial) //Is the object special?
return %i; //If so, return the object we found. This will only return the /first/ one it finds if there are multiple ones though. One potential issue with this.
}
return -1; //If the loop terminates, no objects are found, so return -1.
}

Code: [Select]
for(%i = 0; %i < $allSpecialBricksCt; %i++) //Begin searching through all our logged special bricks.
{
%x = $allSpecialBricks[%i].PlayerWithinRange(%player, 128); //For every brick, ask if the player we have is within range.
//do stuff if %x returns true/false
}
^This one isn't a function if that isn't obvious.


You can also replace the for loop in Player::getSpecialBrickInRange with while(isObject(%i = containerSearchNext())) if you want. They both should work just fine.

Well, it's better for me if this is resource-intensive on the server's side. I can't let the client have so much lag.
if the server starts running sluggishly, the client will also.
And also, I'm confused at how the first and second function work. I want to know how they work because I'll probably need to replace some of the code with my own stuff.

Edit: Never mind I got the second one but im still confused with the first, and how would you use the second one with that function you made before?
i'll comment it heavily
function Player::getSpecialBrickInRange(%this, %range) //define function, %this is the player we'll be searching from, %range is the max distance. in your case, you would call this: %player.getSpecialBrickInRange(64 128); because later on it handles the conversion to bricks automatically.
{
   initContainerRadiusSearch(%this.getPosition(), %range * 0.5, $TypeMasks::fxBrickObjectType); //this starts a container radius search with the center at the player's position, the radius converted from torque units to bricks (simply put in the number of bricks you want, it'll take care of the rest) and it only looks for bricks.
   for(%i = containerSearchNext(); isObject(%i); %i = containerSearchNext())
   { //%i = the first found object // if %i is an object, work with it. otherwise, end the search. // %i continue search
      if(%i.isSpecial) //if %i is the special brick (checking via isSpecial)...
         return %i; //return the id of the special brick
   }
   return -1; //otherwise, if we didn't find anything, return -1.
}


loving stuff OTTO

So this is all server-sided? I need it to be because it will link to a serverCmdMessageSent.
If there are multiple radio bricks within the range, then it seems to me like it will pick the first one.
« Last Edit: August 14, 2012, 09:15:42 PM by hammereditor² »

So this is all server-sided? I need it to be because it will link to a serverCmdMessageSent.
Yes, what they posted is server sided.

Okay, I'll try all this stuff out.