Author Topic: [Solved] Detect when a player gets within a certain distance to any other player  (Read 2062 times)

I'm making a gamemode where one player has a bomb, and when the player with the bomb gets close enough to any other player, the bomb is transferred to the new player. Note that the bomb should not be transferred if there are bricks with raycasting between the players.

Let me know if you have a better idea than mine for how to do this. I'm not sure if my way will lag the server.


My idea is to use %raycast = containerRaycast(%start,%end,%type,%ignore) in a loop that runs every 33 ms.
%start  will be the bomb-holder's position.
%end  will be every player in the minigame's position (looping through all minigame players)
%type  will be $TypeMasks::FxBrickObjectType (bricks with raycasting on)
%ignore  is an optional input and will not be used

As it loops through all minigame players, I'll check if %raycast == 0 (meaning that there are no bricks between the bomb-holder and the player).
If that's true, I can then check the distance between the bomb-holder and the player with VectorDist(%start , %end).
If that distance is low enough, the bomb will transfer to the new player.



Final code used:

Code: [Select]
%bomberPosition=$bomberClient.player.getHackPosition();
InitContainerRadiusSearch(%bomberPosition,3,$TypeMasks::PlayerObjectType);             //in a radius of 3 from the bomb-carrier, search for any other players
while(%targetObject=containerSearchNext())
{
if(%targetObject != $bomberClient.player)
{
%end = %targetObject.getHackPosition();
%type = $TypeMasks::FxBrickObjectType;
%raycast = containerRaycast(%bomberPosition,%end,%type);
if(firstWord(%raycast) == 0) //if true, there are no raycasting bricks between the 2 players
{

//set the new bomber
$bomberClient = %cl;

//de-activate the bomb for 9 seconds to allow for the previous bomb holder to escape
$bombActive = 0;
schedule(9000,0,activateBomb,0);
}
}
}
« Last Edit: June 26, 2016, 04:15:40 PM by Farad »

you could maybe make it more efficient by using a sphere container search on the bomb player instead of direct raycasts to every other player on a loop, and see if anyone even is in range before doing the direct raycasts to check for LOS.

you could maybe make it more efficient by using a sphere container search on the bomb player instead of direct raycasts to every other player on a loop, and see if anyone even is in range before doing the direct raycasts to check for LOS.
This. IIRC, this is what I did for my SCP 895 mod. Looping through an unknown amount of objects every 33ms is not recommended. Just loop through any detected objects instead.

Alright that works. Now I have another issue.

When using the containerRaycast, it will think there is a brick between the 2 players even if the brick is a plate, like below. To fix this, I think I could add some vertical distance to the starting position of the containerRaycast.

How do I add vertical distance to a player.getposition()?

« Last Edit: June 25, 2016, 09:58:39 PM by Farad »

%player.getHackPosition(); returns the center of the player.

you can optionally fire a raycast from getEyePoint to getEyePoint if you want to do visual LOS

getPosition returns the bottom of the player. if you still want to add a vertical distance to the position manually, use vectorAdd(%player.getPosition(), "0 0 1.4"); or something like that

This reference provided by garagegames covers math functions available by default in torque, including vector stuff.
« Last Edit: June 25, 2016, 11:56:07 PM by Conan »

Again, only backing up what Conan said here, but use getEyePoint for best results. Only thing that might not work then is that the players might not be detected if crouching. If you want to use a custom height, you can always just add or subtract from the player position along the z axis.

you could maybe make it more efficient by using a sphere container search on the bomb player instead of direct raycasts to every other player on a loop, and see if anyone even is in range before doing the direct raycasts to check for LOS.

Calling initContainer*Search actually builds a list of all objects found, containerSearchNext simply iterates through it. Running these often with a larger radius is a very bad idea.

Calling initContainer*Search actually builds a list of all objects found, containerSearchNext simply iterates through it. Running these often with a larger radius is a very bad idea.
i'm assuming he's using it for his pizza gamemode where people are on cars. assuming its more like a tag-style game, its unlikely a large number of players will all be in the same area at once to cause issues with this method.

unless, of course, the container search is significantly more taxing based on the size of the container, but i have reason to doubt that's the case unless your container is massive

if containersearch ends up being pretty laggy, faraday, you can stick with your original method; but instead of drawing the raycast first to determine LOS, check player distance first. its a less taxing operation.