Solved Checking if an entity is in an area in front of the player

Discussion in 'Plugin Development' started by Side8StarLite, Apr 16, 2017.

Thread Status:
Not open for further replies.
  1. Offline

    Side8StarLite

    Ok so I've been scratching my head at this for a while, because I haven't learned trig yet. I REPEAT I haven't learned trig yet.
    I have an effect that pushes entities back, sort of like a wind push, complete with particle effects. But my problem is in checking if the entity is in front of a player within a certain range.
    With pictures....
    yaw1.jpg
    But I also need it to check if it's in front depending on the player's yaw. That's where I'm stuck.
    yaw2.jpg
    Wherein the dotted lines are the margins of the effect.
    I've read up on sin cos and how to rotate coordinates. But I don't know how to incorporate this in here.
    Any help is appreciated :).
     
  2. Offline

    Zombie_Striker

    @Side8StarLite
    I don't think you need trig for this. Try the following:
    1. Get the difference in the X. Do this by getting the player's X and subtracting the entities X.
    2. Do the same for Z
    3. Set the entities velocity to be equal to X,0,Z.
    4. If you want it so entities closer to you move faster/further than one the rest, multiply the velocity by some value (e.g. 3), and divide by the distance between the two location (using Location1.distance(location2)).
     
  3. Offline

    Side8StarLite

    @Zombie_Striker
    #4 looks like a great idea :). But that would push back ALL entities nearby. I need it to apply only to entities in front of me. So if a sheep is behind me, it's safe.
     
  4. @Side8StarLite
    It seems that your problem is mostly working out points in relation to the player. If you get four points to outline a rectangle, it should be no problem checking if an entity is within that rectangle.

    To do this, we're going to have to use a slight bit trigonometry (you don't really need to understand the trigonometric functions, but it helps greatly in understanding what's actually being done). We want to obtain four points which will move along with the player as their yaw value changes. I find it easiest to look at the unit circle to get a grip of what's happening (Or even better, an interactive one):
    [​IMG]

    Let's start with the points directly left and right of the player. You might expect adding cos(yaw) and sin(yaw) to the player's coordinates would make a point straight infront of the player, but because of the weird way minecraft numbers its degrees, it actually goes left/right depending on if you add or subtract. So to get a point on either side of the player add cos(yaw) to the x value and sin(yaw) to the z value and the same thing but for subtraction to get point on the other side. If you feel that the distances are too short, you might want to multiply by some constant (5 or 6 is a good number to try).

    To get the other two points, we can reuse the points we already have, but add a bit of forward translation to it. To obtain this forward translation, we just get the values for cos(yaw + 90°) and sin(yaw + 90°) and add them to our already existing points to get two new ones which are in front of the player (again, multiply by some constant if the distances don't suit you). And there we have it!

    Just to prove my point, here's a little demo I made which constantly puts a rectangle in front of the player which rotates accordingly:
    [​IMG]
    In case it is of any help to you, here's the code for the above example (obviously doesn't fit exactly to your problem, but should give some hints):
    Code:java
    1. new BukkitRunnable() {
    2. @Override
    3. public void run() {
    4. double cos90 = -Math.cos(Math.toRadians(player.getLocation().getYaw() - 90));
    5. double sin90 = -Math.sin(Math.toRadians(player.getLocation().getYaw() - 90));
    6. Location firstLoc = player.getLocation().add(-Math.cos(Math.toRadians(player.getLocation().getYaw())) * 8, 1, -Math.sin(Math.toRadians(player.getLocation().getYaw())) * 8);
    7. firstLoc.add(cos90, 0, sin90);
    8. Location secondLoc = player.getLocation().add(Math.cos(Math.toRadians(player.getLocation().getYaw())) * 8, 1, Math.sin(Math.toRadians(player.getLocation().getYaw())) * 8);
    9. secondLoc.add(cos90, 0, sin90);
    10. drawLine(firstLoc, secondLoc, 0.2);
    11. Location thirdLoc = firstLoc.clone().add(cos90 * 6, 0, sin90 * 6);
    12. Location fourthLoc = secondLoc.clone().add(cos90 * 6, 0, sin90 * 6);
    13. drawLine(thirdLoc, fourthLoc, 0.2);
    14. drawLine(firstLoc, thirdLoc, 0.2);
    15. drawLine(secondLoc, fourthLoc, 0.2);
    16. }
    17. }.runTaskTimer(this, 0L, 5L);
    18.  
    19. public void drawLine(Location point1, Location point2, double space) {
    20. World world = point1.getWorld();
    21. Validate.isTrue(point2.getWorld().equals(world), "Lines cannot be in different worlds!");
    22. double distance = point1.distance(point2);
    23. Vector p1 = point1.toVector();
    24. Vector p2 = point2.toVector();
    25. Vector vector = p2.clone().subtract(p1).normalize();
    26. double length = 0;
    27. for (; length < distance; p1.add(vector.clone().multiply(space))) {
    28. world.spawnParticle(Particle.REDSTONE, p1.getX(), p1.getY(), p1.getZ(), 1);
    29. length += space;
    30. }
    31. }
     
  5. Offline

    Side8StarLite

    @AlvinB
    Wow! Thank you so much. Got it working now. The examples were terrific, thanks!
     
Thread Status:
Not open for further replies.

Share This Page