Help with lineofsight / geometry I guess.

Discussion in 'Plugin Development' started by ferrago, May 5, 2014.

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

    ferrago

    I am trying to get all of the blocks in a line between the target location and the start location. More specifically I have two players, I am trying to get the locations of the most efficient line between those to players to play an effect, I am not quite sure how to do it.
     
  2. Offline

    DxDy

    Code:java
    1. Vector direction = posB.clone().subtract(posA).normalize();
    2.  
    3. Vector pointOnLine = posA.clone().add(direction * factor);
     
  3. Offline

    NathanWolf

  4. Offline

    ferrago

  5. Offline

    NathanWolf


    Code:
    BlockIterator iterator = new BlockIterator(player);
     
    while (iterator.hasNext()) {
      Block block = iterator.getNext();
      // Play your effect on the block
    }
     
  6. Offline

    ferrago

    It's semi working
    it's semi working like I want. Only problem is the line isn't nice and straight and typically goes past the final target, I am using the following,

    Code:
            BlockIterator iterator = new BlockIterator(hero.getPlayer(), 10);
            while (iterator.hasNext()) {
                Block block = iterator.next();
                Location trueloc = block.getLocation();
                trueloc.setY(trueloc.getY()+1);
                block.getWorld().playEffect(trueloc, Effect.CLOUD, 1);
                if (block.getLocation().distanceSquared(le.getLocation()) < 1) {
                    break;
                }
            }
    
    also it typically goes to their feet, thats why I am using the trueloc to make it 1 higher, but it still will start around torso and when it gets close to final target it drops to their feet and still typically goes past them by a block or 2.

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 8, 2016
  7. Offline

    Drkmaster83

    Is it an instant line or a over-time drawn line?
     
  8. Offline

    ferrago

    instant line,
     
  9. Offline

    Drkmaster83

    One moment... coding.

    I've conjured up this.

    Haven't tested it, but it uses the same base as my other delayed line drawer (that works with packets, btw).

    Edit: Updated link, for-loop had a return statement that will botch the whole thing. Changed it to 'continue'

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 8, 2016
  10. Offline

    ferrago

    Awesome thank you! I have been trying to figure this out for a while and just can't get anything that works the way I would like it to.

    It works for some effects but like cloud, and magic crit it seems to launch out in all directions

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 8, 2016
  11. Offline

    Drkmaster83

    There's a data parameter, I think... Otherwise, you can edit the method to add certain data if you don't want it to be in the parameter... but the overall line works, does it not?
     
  12. Offline

    ferrago

    I have gotten it to work with mob spawner flames, but for like magic crit and cloud, and flame it launches out in every direction. I am using 0 for the data value for all of them, I have no idea where data values would be with an explanation of what they do for which effects.

    do you know a list of data values?

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 8, 2016
  13. Offline

    Drkmaster83

    Sadly not, I know that Smoke has specified data values, otherwise, I think the higher the number, the faster it goes, perhaps try giving a floating-point number if it's allowed as the data?
     
  14. Offline

    coasterman10

    If you want to play an effect on a line directly between the two players, you should get the difference between their locations as a Vector and then pick several points along that vector to play an effect. It'll be much cleaner than using a line of sight block iterator that snaps everything to the blocks which ends up being a mess.
     
    NathanWolf likes this.
  15. Offline

    NathanWolf

    I'm assuming since you're asking here, you want to write this yourself and not use a Lib- but FWIW there is EffectsLib and also I have my own lib for this (MagicLib). If you want to just check out my code, feel free:

    https://github.com/elBukkit/MagicLi...s/mine/bukkit/effect/builtin/EffectTrail.java

    That one does exactly what you're trying to do, I think- I don't use a block iterator, just add a fixed distance from one point to the next, basically what coasterman10 just suggested.

    It may be a bit more complex than you need since it's part of a generic framework- there is also an EffectRing and EffectSingle (and I'm hoping to add a lot more variants).

    The EffectPlayers can do raw particles, Bukkit effects, Sounds, fireworks, or any combination thereof.
     
  16. Offline

    ferrago

    I am not going to lie I am pretty horrible with vectors, how would you do your method?
     
  17. Offline

    coasterman10

    Here's how you can get the difference between two players' locations as a vector:
    Code:java
    1. Player p1, p2; // Your two players
    2.  
    3. Vector v1 = p1.getLocation().toVector();
    4. Vector v2 = p2.getLocation().toVector();
    5.  
    6. // Subtract v1 from v2
    7. Vector diff = v2.subtract(v1);

    I should note that when you use subtract() on a vector, it actually changes the vector itself and just returns the same vector, so v1 is subtracted from v2 and put into v2. You may want to keep this in mind if you don't want a vector changed when you use subtract() on it, but here we don't really care about what happens to v1 or v2.

    Now that we have the two location vectors, we can divide up the difference into several sections and draw an effect at each point along the line. What we do is convert the difference into a unit vector, and then multiply that by the distance (in blocks) between each effect. We'll call the components dx, dy, and dz. These represent a small change over the difference line. We iterate over the length of this line, adding these components each time to a location, and then creating the effect at each of these locations.
    Code:java
    1. double dist = diff.length(); // Distance of the line;
    2.  
    3. // We want to work in increments of half a block, so we divide diff by its length
    4. // and then multiply by 0.5 to get increments of 0.5 block.
    5. double dx = (diff.getX() / dist) * 0.5;
    6. double dy = (diff.getY() / dist) * 0.5;
    7. double dz = (diff.getZ() / dist) * 0.5;
    8.  
    9. // Current position along the line where we will draw the effect.
    10. // Clone the first player's position and then add onto that each iteration.
    11. Location loc = p1.getLocation().clone();
    12.  
    13. for (double d = 0; d <= dist; d += 0.5) {
    14. loc.add(dx, dy, dz);
    15.  
    16. // Now we can create the effect at loc
    17. // ...
    18. }

    If any part confuses you, let me know and I will try to explain it in more depth.
     
    Flybelette likes this.
Thread Status:
Not open for further replies.

Share This Page