Author Topic: Raycast Explosion  (Read 1749 times)

What would be the best way to make a container radius search, get the position that the search hit a brick, and then fire a raycast from that position to the center of the radius search?

I'm trying to detect the bricks that an explosion hits and then make sure that there's nothing in between the explosion and the bricks that it hits.

For every brick in the search, make a raycast from the center of your search to the center of the brick. If you hit the brick without hitting another brick first, add it to an array. After checking every brick, explode the ones in the array. I guess this should work pretty well

You'll probably have to overwrite some default functions to disable the default behavior of exploding everything, though (or just make the explosion have brick damage radius 0 to bypass default stuff)

Would there be any way to get the point that the radius search hit the brick and use that instead?
What I really need to know is how to calculate the angle at which to fire the raycast.




You see, the problem is that if you fire the raycast from the center of the brick then raycast 1 thinks that wall 2 is in the way, when it really isn't.

Never mind. It'll still work fine for my purposes. Enjoy the fancy picture.

instead of going to the center of the brick, you could try the center and all 8 corners
not perfect but might be a bit better

I believe there's a function which gets either the position or the distance to the thing the radius cast hit. I think its the distance though, but not sure.

Edit:

http://www-rohan.sdsu.edu/~stewart/GPGT/Appendix%20A%20-%20Quick%20References.pdf

No idea if this function is actually in BL though, or it might be renamed.
« Last Edit: October 23, 2015, 07:44:29 AM by boodals 2 »

That gives you only the distance of an object to the center of search though, which isn't really useful.

What I really need to know is how to calculate the angle at which to fire the raycast.

I don't think the engine has any function you can use for that. You'll need to get brick.getWorldBox() and then use an algorithm to find the closest point on a bounding box to another point.

Port wrote a simple add-on for this with players called script_obstructRadiusDamage, here is the function in which it does the checking:


function obstructRadiusDamageCheck(%pos, %col) {
   %b = %col.getHackPosition();
   %half = vectorSub(%b, %col.position);

   %a = vectorAdd(%col.position, vectorScale(%half, 0.1));
   %c = vectorAdd(%col.position, vectorScale(%half, 1.9));

   %mask = $TypeMasks::FxBrickObjectType;

   if (containerRayCast(%pos, %a, %mask) !$= 0) {
      if (containerRayCast(%pos, %b, %mask) !$= 0) {
         if (containerRayCast(%pos, %c, %mask) !$= 0) {
            return 0;
         }
      }
   }

   return 1;
}



Nothing to do with the topic.

Any thoughts on how to make this better? It's to prevent bricks from being planted on players. It's not 100% accurate.
Code: [Select]
%center = %brick.getPosition();

if(%data.brickSizeX >= %data.brickSizeY && %data.brickSizeX >= %data.brickSizeZ)
{
%radius = %data.brickSizeX;
}

else if(%data.brickSizeY >= %data.brickSizeX && %data.brickSizeY >= %data.brickSizeZ)
{
%radius = %data.brickSizeY;
}

else if(%data.brickSizeZ >= %data.brickSizeX && %data.brickSizeZ >= %data.brickSizeY)
{
%radius = %data.brickSizeZ;
}

initContainerRadiusSearch(%center, %radius * 3, $TypeMasks::PlayerObjectType);

while(isObject(%obj = containerSearchNext()))
{
if(%obj.getState() $= "Dead" || (%obj.getClassName() $= "AIPlayer" && !%obj.isSentry()))
{
continue;
}

//Find nearby players and fire a raycast from the center of the brick to each player, length of the raycast maxed out at the edges of the brick. If player is found, don't plant.

%end = %obj.getHackPosition();
%end = vectorClamp(%end, vectorSub(%center, 0.25 * (%data.brickSizeX / 2) SPC 0.25 * (%data.brickSizeY / 2) SPC 0.1 * (%data.brickSizeZ / 2)), vectorAdd(%center, 0.25 * (%data.brickSizeX / 2) SPC 0.25 * (%data.brickSizeY / 2) SPC 0.1 * (%data.brickSizeZ / 2)));

if(containerRayCast(%center, %end, $TypeMasks::PlayerObjectType) !$= 0)
{
messageClient(%client, 'MsgPlantError_Stuck', "");
%brick.trustCheckFailed();

return;
}
}
There's sometimes random spots on bricks where it doesn't detect you as inside it for some reason. And on some spots on some bricks it thinks you're inside it, when you're not.
« Last Edit: October 28, 2015, 01:52:58 PM by jes00 »

Why are you doing a radius search and raycasts? Make a box search for the world box of the ghost brick and check whether players are inside it.

Why are you doing a radius search and raycasts? Make a box search for the world box of the ghost brick and check whether players are inside it.
Because apparently box searches don't work right for players and vehicles.

Because apparently box searches don't work right for players and vehicles.
They do, but the standard player has a wrong world box.

You'll need to write a box overlap test function in ts and manually check whether every result of the search is actually inside the box.

You'll need to write a box overlap test function in ts and manually check whether every result of the search is actually inside the box.
What do you mean?

How would you check if any point of the player is inside the box and not just a single point?
« Last Edit: October 28, 2015, 04:36:00 PM by jes00 »

How would you check if any point of the player is inside the box and not just a single point?
Check all 3 axes separately. The size of a player is 1.4 x 1.4 x 2.9 tu multiplied by player scale, a crouched player is 1.4 x 1.4 x 1.16.

on x you check ((posx + 0.7 < lower bound x) || (posx - 0.7 > upper bound x))
on y you check ((posy + 0.7 < lower bound y) || (posy - 0.7 > upper bound y))
on z you check ((posz + 2.9 < lower bound z) || (posz > upper bound z))

If any of these is true, the player isn't in the box.
« Last Edit: October 28, 2015, 05:07:10 PM by Zeblote »