[HowTo] Search for objects within a certain radius of a location

Author Topic: [HowTo] Search for objects within a certain radius of a location  (Read 3230 times)

rudyman

  • Guest
There are 2 ways to detect objects near a location.

The first way is by using containerRayCast(), but it only finds objects it hits when casting a linear ray from a point.

The second way searches all the way around a location within a certain radius, and this is by using the initContainerRadiusSearch() method.

I'm gunna use the second way in this tutorial, as it's a bit more useful.

Let's say you wanted to make a local chat server command to message all players within a 15 unit radius of the speaker.
Start off by making your server command:
Code: [Select]
function serverCmdLocalChat(%client,%message)
{
%position=%client.player.position;
}

So we have the player's position... now let's search for nearby players.
We'll use this command:
InitContainerRadiusSearch(%position,15,$TypeMasks::PlayerObjectType);

As you can see, there are 3 arguments.
The first is the starting position, which we already defined.
The second is the radius in which we want to search, we're using 15.

The third is the object type we want to detect. Since we only want to message players (we don't want to message an interior object, etc.), we want to use the PlayerObjectType type mask.

Now let's loop through the objects we detect.
Code: [Select]
function serverCmdLocalChat(%client,%message)
{
%position=%client.player.position;
InitContainerRadiusSearch(%position,15,$TypeMasks::PlayerObjectType);
$LocalMsgString='%1 says, \c5\"%2\"';
while((%targetObject=containerSearchNext()) !$= 0)
{
%client=%targetObject.client;
messageClient(%client,'',$LocalMsgString,%client.name,%msg);
}
}
« Last Edit: March 10, 2007, 09:33:04 AM by rudyman »

Code: [Select]
$radiusmasstimes = 20;
function serverCmdsetradiuspower(%client, %num) {
if(%client.isadmin || %client.issuperadmin) {
  if(%num != $radiusmasstimes) {
    if(%num <= 100 || %num >= 1) {
      $radiusmasstimes = %num;
      chatmessageall(%client, '\c4Radius impulse power is now: \c3%1\c4.', %num);
    }
    else if(%num <= 0 || strlwr(%num) $= "off") {
      $radiusmasstimes = 0;
      chatmessageall(%client, '\c4Radius impulse power is now \c3OFF\c4.');
    }
    else if(strlwr(%num) $= "default") {
      $radiusmasstimes = 20;
      chatmessageall(%client, '\c4Radius impulse power is now: \c320\c4.');
    }
    else {
      messageclient(%client, '\c4Please choose a number between 1 and 100. Zero and under is off. So is typing "off". Typing "default" makes the impulse default.');
    }
  }
}
}
function serverCmdradiusimpulse(%client) {
   if($radiusmasstimes == 0) {
     messageclient(%client, '\c5Radius impulse is \c0OFF\c5.');
     return;
   }
   %sourceObject = %client.player;
   %position = %sourceObject.gettransform();
   InitContainerRadiusSearch(%position, 15, $TypeMasks::ShapeBaseObjectType | $TypeMasks::ProjectileDataObjectType | $TypeMasks::VehicleObjectType);
   %halfRadius = 15 / 2;
   while ((%targetObject = containerSearchNext()) != 0) {
      if(%targetObject != %sourceObject) {
      %coverage = calcExplosionCoverage(%position, %targetObject, $TypeMasks::InteriorObjectType | $TypeMasks::TerrainObjectType | $TypeMasks::ForceFieldObjectType);
      if (%coverage == 0)
         continue;
      %dist = containerSearchCurrRadiusDist();
      %distScale = (%dist < %halfRadius)? 1.0:
      1.0 - ((%dist - %halfRadius) / %halfRadius);
      %impulse = %targetObject.getDataBlock().mass * $radiusmasstimes;
      %impulseVec = VectorSub(%targetObject.getWorldBoxCenter(), %position);
      %impulseVec = VectorNormalize(%impulseVec);
      %impulseVec = VectorScale(%impulseVec, %impulse * %distScale);
      if(%targetobject.client.frozen == 1)
serverCmdFreezeMe(%targetobject.client);
  if(%targetobject.client.sitting == 1)
serverCmdsitMe(%targetobject.client);
      %targetObject.applyImpulse(%position, %impulseVec);
      }
   }
}
Made that long ago....never got to test it in retail, as when I tried to no one was joining and when people do join, I forget to try it :/