Arrow get stuck in block when it gets fired from a block

Discussion in 'Plugin Development' started by bennie3211, Sep 9, 2014.

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

    bennie3211

    Hi bukkit,

    I've a little problem, I'm trying to add turrets in a mini game, but every time the arrow gets stuck inside the block where the turret shoot from. Can someone help me with this problem? This is the code I use so far:

    Code:java
    1. if (ammo > 0) {
    2.  
    3. turret.removeAmmo(1);
    4.  
    5. Vector direction = plLoc.add(0,1,0).toVector().subtract(loc.toVector().normalize());
    6. Vector v = plLoc.add(0,1,0).toVector().subtract(loc.toVector().multiply(1.0));
    7. Bukkit.getWorld(loc.getWorld().getName()).spawnArrow(loc.add(direction), v, (float) 2, turret.getAccuracy());
    8. }


    I've tried a lot of things, but adding height to the location (so it will spawn above the turret) doesn't give a nice shoot effect. Because it should get fired from the turret itself.

    Thnx!
     
  2. bennie3211 yes, over it will look not so good, but in front of it where is air should work fine and still look good
     
  3. Offline

    bennie3211

    Shmobi But if the turret is placed inside a cave (the turret is 2 high) and it has a block above it, the arrow will still spawn inside a block xD
     
  4. bennie3211 wait :O you got block 1 of your turret at position 0/0/0 and the second block at 0/1/0 and you try to fire your arrow at 0/1/1 it works. but if there is a block at 0/2/1 it does still spawn it into the block? am i right? (x/y/z)
     
  5. Offline

    bennie3211

    What I'm trying to do is to spawn the arrow outside the source block. The turret will be a fence, and on top of that a block (Wool but different colors to show the strength of it). The Wool block will be the source block that shoots the arrow to the player in the given activation radius. Now it spawns inside the wool block and gets stuck. What I want to create is that it will spawn the arrow outside the source block (wool block) 1 block to the right direction the arrow will be shot so it won't get stuck in the blocks anymore. Does anyone knows how and can explain it to me?

    Thnx!

    Up :) Someone who can help me with this?

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

    bennie3211

    Nobody that can help me? :( I'm still need help!
     
  7. Check the direction of your blocks - I suppose they have different block data -, and then add a corresponding offset to your location.
     
  8. Offline

    bennie3211

    adventuretc what do you mean? I have one block top of the 2 blocks that will be the turret. That's the location I have, then I check from that location the distance to all players and then shoot the arrow. So I think I or you see it wrong ;d
     
  9. Offline

    AlphaRLee

    bennie3211 Try getting the location of the target and the location of the turret. Then spawn your arrow from outside of your turret (on the side, not above). How to choose which side it comes out determines on your target's location. For example, if the target is south of the turret, then make the turret spawn the arrow at these coordinates: (turret.getX(), turret.getY(), turret.getZ() + 1). You probably will need between 4 and 8 if statements to make it work perfectly (unless if you can get some better technique).

    Hope this helps! :)
     
  10. Now I understand. You can get the difference vector between your turret and player, normalize it and then add it to your turret location.
    Looking at your code, I think it will work this way
    Code:java
    1. Vector direction = plLoc.add(0,1,0).toVector().subtract(loc.toVector()).normalize();
     
  11. Offline

    4thegame3

    what about if you make the turret a falling block witout physic?
    you will also able to rotate it
     
  12. Offline

    bennie3211

    4thegame3 I've never done that before, some tutorials for this?

    adventuretc what do you mean with add?

    AlphaRLee I tried this, and I got this for now:

    Code:java
    1. public Location getDirection(Location loc, Vector v) {
    2.  
    3. Location tempLoc = loc;
    4.  
    5. //midden boven
    6. if ((v.getX() > 0) && (v.getZ() > -1) && (v.getZ() < 1)) {
    7. System.out.println("Midden Boven");
    8. return tempLoc.add(1, 0, 0);
    9. }
    10.  
    11. //rechts boven
    12. if ((v.getX() > 0) && (v.getZ() > 1)) {
    13. System.out.println("Rechts Boven");
    14. return tempLoc.add(1, 0, 1);
    15. }
    16.  
    17. //midden rechts
    18. if ((v.getZ() > 0) && (v.getX() > -1) && (v.getX() < 1)) {
    19. System.out.println("Midden Rechts");
    20. return tempLoc.add(0, 0, 1);
    21. }
    22.  
    23. //rechts onder
    24. if ((v.getX() < 0) && (v.getZ() > 1)) {
    25. System.out.println("Rechts Onder");
    26. return tempLoc.add(-1, 0, 1);
    27. }
    28.  
    29. //midden onder
    30. if ((v.getX() < 0) && (v.getZ() > -1) && (v.getZ() < 1)) {
    31. System.out.println("Midden Onder");
    32. return tempLoc.add(-1, 0, 0);
    33. }
    34.  
    35. //links onder
    36. if ((v.getX() < 0) && (v.getZ() < -1)) {
    37. System.out.println("Links Onder");
    38. return tempLoc.add(-1, 0, -1);
    39. }
    40.  
    41. //midden links
    42. if ((v.getZ() < 0) && (v.getX() > -1) && (v.getX() < 1)) {
    43. System.out.println("Midden Links");
    44. return tempLoc.add(0, 0, -1);
    45. }
    46.  
    47. //links boven
    48. if ((v.getZ() < 0) && (v.getX() > 1)) {
    49. System.out.println("Links Boven");
    50. return tempLoc.add(1, 0, -1);
    51. }
    52.  
    53. System.out.println("NULLLLL");
    54.  
    55. return tempLoc;
    56. }

    *the language above (println()) is in dutch, sorry for that*

    But if I use this, it won't print the same message if I stand still. So I'm not sure what I'm doing wrong xD
     
  13. I meant this, the exact thing that you are already doing:
    Code:java
    1. loc.add(direction)

    Notice the difference between my previous post and your original code please.
     
  14. Offline

    SyTeck

    I used this code and it seems to be working very well, but I don't know if it is what you're looking for.

    Code:java
    1.  
    2. Location fireLoc = new Location(loc.getWorld(), loc.getX() + 1, loc.getY(), loc.getZ());
    3. fireLoc.add(new Vector().multiply(10));
    4.  
    5. Bukkit.getWorld(fireLoc.getWorld().getName()).spawnArrow(fireLoc, fireLoc.getDirection(), fireLoc.getYaw()-180, fireLoc.getPitch());
    6. Bukkit.broadcastMessage(ChatColor.GREEN+"Arrow fired!");
    7.  


    First I got the block which I wanted to shoot from and added 1 to X to make the arrow spawn outside the block. Then I added speed to it with Vector, and finally spawned the arrow and turned the angel of the shooting direction with 180 degrees so it doesn't shoot directly into the block it shoots from.
     
  15. Offline

    bennie3211

    SyTeck It has a range of 360 degree, So I need to check if the player is at the North, East, South or West side of the block that's shooting. So I'm not sure if that's gonna work :s
     
  16. Offline

    SyTeck

    You should at least try to find a formula for it and test it out. Your problem might be that it's shooting the arrow in the wrong direction.
     
  17. Offline

    bennie3211

    SyTeck adventuretc and others, I found a (the) bug that I can't solve, I'm trying to normalize the vector, and add that to the location, and from there I will spawn the arrow, but I can't solve the problem I'm facing right now. The vector that I normalize jumps from positive to negative values :s So if I println() the getX, getY and getZ values, it will jump from positive to negative and and vice versa :l This is the code I'm trying to debug:

    Code:java
    1. package test;
    2.  
    3. import java.text.DecimalFormat;
    4.  
    5. import org.bukkit.Bukkit;
    6. import org.bukkit.Location;
    7. import org.bukkit.entity.Player;
    8. import org.bukkit.event.EventHandler;
    9. import org.bukkit.event.Listener;
    10. import org.bukkit.event.block.BlockPlaceEvent;
    11. import org.bukkit.plugin.java.JavaPlugin;
    12. import org.bukkit.util.Vector;
    13.  
    14. public class Test extends JavaPlugin implements Listener {
    15.  
    16. public Location loc;
    17.  
    18. DecimalFormat f = new DecimalFormat("##.00");
    19.  
    20. public void onEnable() {
    21. Bukkit.getServer().getPluginManager().registerEvents(this, this);
    22. test();
    23. }
    24.  
    25. public void onDisable() {
    26.  
    27. }
    28.  
    29. @EventHandler
    30. public void onBlockPlace(BlockPlaceEvent event) {
    31. this.loc = event.getBlock().getLocation();
    32. }
    33.  
    34. public void test() {
    35.  
    36. for (Player pl : Bukkit.getOnlinePlayers()) {
    37.  
    38. if (loc == null) continue;
    39.  
    40. Vector v = pl.getLocation().toVector().subtract(loc.toVector()).normalize();
    41. Location newLoc = loc;
    42. newLoc.add(v);
    43.  
    44. System.out.println("============================");
    45. System.out.println("X: " + f.format(v.getX()) + " Y: " + f.format(v.getY()) + " Z: " + f.format(v.getZ()) + " || " + f.format(v.length()));
    46. System.out.println("X: " + f.format(loc.getX()) + " Y: " + f.format(loc.getY()) + " Z: " + f.format(loc.getZ()));
    47. System.out.println("============================");
    48. }
    49.  
    50. Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(this,
    51. new Runnable() {
    52. @Override
    53. public void run() {
    54. test();
    55. }
    56. }, 20);
    57. }
    58. }


    And what I get as output in console: http://g2f.nl/0tjrwlh

    The first line under the line of equals symbols is the vector x,y,z and the length of the vector that is always one because I did normalize(). And the line under that is the new location x,y,z when added the vector the the original location.

    PS: This is the only plugin I've running on the server.
     
  18. Lol, in the second line you are printing out the turret location yet it acts like the 'newLoc', strange.
     
    bennie3211 likes this.
  19. Offline

    bennie3211

    adventuretc If i remove everything, except the part of the calculating the vector and println the x,y,z from the vector, it works perfect :s It doesn't change from positive to negative and visa versa :l Can somone explain me what i'm doing wrong? Because when I added the full code back, and placed a block on the new created location, it was following the player like a 3d snake xD
     
Thread Status:
Not open for further replies.

Share This Page