Falling blocks riding an arrow

Discussion in 'Plugin Development' started by Elytes, Dec 30, 2018.

  1. Offline

    Elytes

    Hi ! :)
    I'm working on a plugin for my server, but i'm stuck on something. I'm throwing an arrow with a block wich is riding it, but when my character view is over middle of the screen, the arrow just disapear and the block too. I think that's cause it's a falling block, but I don't know how to fix it.

    Here is the code :

    // Get the arrow launched from player.launchProjectile(Arrow.class)
    Arrow arrows = player.launchProjectile(Arrow.class);
    // Set custom name to the arrow to find it when it hit
    arrows.setCustomName(nomFleche);
    // Create a falling block of ice at the arrow's position
    FallingBlock block = arrows.getWorld().spawnFallingBlock(arrows.getLocation(), Material.ICE, (byte) 3);
    // Adding block to arrow
    arrows.addPassenger(block);
    // Setting velocity of the arrow to the block
    block.setVelocity(arrows.getVelocity());

    Pls tell me if you've got a fix :p
     
  2. Offline

    knokko

    @Elytes

    If the problem is that the player can no longer see the arrow, there is probably nothing you can do about it.
    If the problem is that the arrow truly disappears, you can probably prevent that by using arrow.setRemoveWhenFarAway(false) and block.setRemoveWhenFarAway(false).

    I haven't checked this though, but I think it will work.
     
  3. Offline

    Elytes

    Thanks for your answer, but setRemoveWhenFarAway seems only for livingentity :/
    I tried block.setGravity(false) too but it wont work
    The problem is that the code works when i look down, but when I look up, my arrow and my block disapear after few blocks :/
     
  4. Offline

    knokko

    @Elytes

    Could you shoot the arrow away, look down and fly to the place where it should land? I am wondering whether or not the arrow actually lands.
     
  5. Offline

    Elytes

    @knokko

    Okay, i just removed the line wich is removing the block and the arrow when they hit ground, and i just saw that when i'm looking up, the block and the arrow change direction to land on my character's head, so yeah, the arrow land, but not at the right place x)
    That's weird cause there is no additionnal vectors that can teleport this arrow on me, I think that's cause fallingblocks falls and when the arrow is going up, it cancel the event but using .setGravity(false) should correct it (in this case)
    Do you have any ideas ? ^^
     
    Last edited: Dec 31, 2018
  6. Offline

    knokko

    @Elytes

    What happens if you remove the line where you set the velocity of the block to the velocity of the arrow?
    And when you keep looking at the arrow?
    And when you don't spawn the block?
     
  7. Offline

    Elytes

    @knokko

    (my server's version is 1.13)
    Block velocity's line code is useless, with or without, it does the same thing
    When i don't spawn the block, the arrow's vector is perfect, like normally.
     
  8. Offline

    knokko

    @Elytes

    What happens when you spawn the falling block 10 blocks above the arrow instead of at the location of the arrow. (Still add the block as passenger.)

    And in the first post, you mentioned 'when my character view is over middle of the screen', so what happens when you keep looking at the same spot?
     
  9. Offline

    Elytes

    @knokko

    I added 10 blocks Y to block location, but the arrow still comming back cause the block teleport on arrow (arrows.addPassenger(block))
    If the player is looking down, the arrow will have a normal path, but if he is looking up, the arrow come back on him. So if i'm looking down every time, the arrow have a normal path and if i'm looking up, the arrow will come back every time ^^
     
    Last edited: Jan 1, 2019
  10. Offline

    Escad

    The issue is probably just that your block is spawned a quick moment after the arrow, causing it to block the arrow before it's added as a passenger.

    You're also using a deprecated method for spawning a falling block in 1.13. I think it's a good opportunity to use the World#spawn method. It takes a consumer as an argument and executes whatever is in it on the entity before it's spawned in the world. In other words, you can set it to be the passenger without it being there to get in the way first.
     
  11. Offline

    Elytes

    @Escad @knokko

    Anyway, with or without the deprecated method, with or without block that spawn after the arrow, it come back to the player, I'm pretty sure that's because it's a falling block so it's always attracted to the ground so you can't give it a velocity that makes it go up. For example, this works perfectly with a Player :

    Arrow arrow = player.launchProjectile(Arrow.class);
    arrow.addPassenger(player);

    What do you think about that "theory" ?
     
    Last edited: Jan 2, 2019
  12. Offline

    knokko

    @Elytes

    Your theory is possible, but there are more possibilities. You will need to do a little more research...

    I suggest you print the velocity of the arrow right after player.launchProjectile.
    (Use System.out.println(arrow.getVelocity()); )
    Also call it after adding the block as passenger and schedule a delayed task with the Bukkit Scheduler and call the method there as well.
    Tell me the results
     
  13. Offline

    Elytes

    @knokko

    While shooting up :


    With 0.001 second delay on the bukkit task runnable :

    On shoot : -2.321056616288035,1.873322629641121,0.2585090685619047
    After block: -2.321056616288035,1.873322629641121,0.2585090685619047
    BukkitRunnable: -2.297846072260475,1.8045894204650486,0.2559239803416202
    Hit ground : -2.297846072260475,1.8045894204650486,0.2559239803416202

    While shooting down :

    With 0.001 second delay on the bukkit task runnable :

    On shoot : 0.16668751615356675,-0.15264786308132502,3.013348751664032
    After block: 0.16668751615356675,-0.15264786308132502,3.013348751664032
    BukkitRunnable: 0.1650206425816871,-0.2011213866513333,2.9832152928849247
    BukkitRunnable: 0.16337043772962972,-0.24911017544792105,2.9533831684062335
    BukkitRunnable: 0.16173673491035534,-0.29661907681419963,2.923849364887828
    BukkitRunnable: 0.16011936910369348,-0.34365288961989565,2.8946108991229504
    BukkitRunnable: 0.15851817693967385,-0.3902163647460841,2.8656648177368815
    BukkitRunnable: 0.15693299668202426,-0.4363142055650746,2.8370081968886223
    BukkitRunnable: 0.1553636682118337,-0.48195106841549845,2.8086381419755546
    Hit ground : 0.1553636682118337,-0.48195106841549845,2.8086381419755546

    We've got 7 messages of the timer when we are looking down and only 1 when we are looking up
     
    Last edited: Jan 2, 2019
  14. Offline

    knokko

    @Elytes

    Your results are quite interesting:
    It looks like that your arrow instantly hits the ground when you shoot up.
    When you shoot down, the velocity of the arrow makes sense.

    Could you tell me what happens if you shoot horizontally?
     
  15. Offline

    Elytes

    @knokko

    On shoot : 0.05364204967571628,0.2870995704451856,2.9591602199230653
    After block : 0.05364204967571628,0.2870995704451856,2.9591602199230653
    BukkitRunnable: 0.053105629690529566,0.23422857673367053,2.9295686459445855
    BukkitRunnable: 0.05257457390007902,0.18188629245505356,2.9002729874236834
    BukkitRunnable: 0.05204882866246843,0.13006743052004782,2.871270285208605
    BukkitRunnable: 0.05152834087222006,0.07876675671020897,2.8425576097390866
    BukkitRunnable: 0.05101305795491041,0.027979089149227143,2.8141320607504374
    BukkitRunnable: 0.05050292786185973,-0.022300702220493802,2.785990766980588
    BukkitRunnable: 0.04999789906487459,-0.072077696156023,2.7581308858800604
    BukkitRunnable: 0.04949792055104297,-0.1213569206269073,2.7305496033248455
    BukkitRunnable: 0.0490029418175815,-0.1701433533230461,2.7032441333321473
    BukkitRunnable: 0.048512912866734155,-0.21844192215748715,2.676211717778971
    BukkitRunnable: 0.048027784200722005,-0.2662575057641948,2.6494496261235247
    BukkitRunnable: 0.047547506816743426,-0.3135949339908404,2.62295515512941
    BukkitRunnable: 0.047072032202024355,-0.36045898838666435,2.5967256285925653
    BukkitRunnable: 0.046601312328917996,-0.4068544026854606,2.570758397070945
    BukkitRunnable: 0.046135299650053564,-0.45278586328373,2.5450508376168983
    BukkitRunnable: 0.045673947093533535,-0.49825800971405326,2.5196003535122253
    Hit ground : 0.045673947093533535,-0.49825800971405326,2.5196003535122253

    We've got more messages (16) when we shoot horizontally, but if i shoot up a little bit more, the arrow will have the weird vector ^^

    example.png
     
  16. Offline

    knokko

    @Elytes

    What if you spawn the falling block like this?
    FallingBlock block = arrows.getWorld().spawnFallingBlock(arrows.getLocation().add(new Vector(0,10,0), Material.ICE, (byte) 3);

    It would make some sense if this would work.
     
  17. Offline

    Elytes

    @knokko

    // Creating arrow
    Arrow arrow = player.launchProjectile(Arrow.class);
    // Spawning the block
    FallingBlock block = arrows.getWorld().spawnFallingBlock(arrows.getLocation().add(new Vector(0,10,0)), Material.ICE, (byte) 3);
    // Adding block passenger
    arrows.addPassenger(block);

    It does the same thing, the arrow come back on my player
     
  18. Offline

    knokko

    @Elytes

    My best quess is that the falling block is blocking the arrow.

    If you don't need the arrow, you could simply set the velocity of the falling block to the velocity of the arrow without adding it as passenger and destroy the arrow.
    If the arrow is really necessary, we will have to get dirty...
     
  19. Offline

    Elytes

    @knokko

    The problem is that I need an event when the arrow hit something or someone

    @EventHandler
    public void ProjectileHit(ProjectileHitEvent event)
    {
    event.getHitEntity().addPotionEffect(new PotionEffect(PotionEffectType.SLOW, 30, 3));
    }

    And there is no event called when falling block hit something :/
     
  20. Offline

    KarimAKL

  21. Offline

    Elytes

    That could work by checking player at X radius from the event location, but that could be better if we could use an arrow, cause arrow got getShooter() method, and I need it to get informations from the shooter :/

    But thanks for the answer :)
     
  22. Offline

    knokko

    @Elytes

    You can use a (Hash)Map<UUID,UUID> to map the id of falling blocks to the id of its shooter.
     
  23. Offline

    Elytes

    @knokko

    Sure but it's getting loud for just a falling cube that can be shoot a lot of times :/
     
  24. Offline

    knokko

    @Elytes

    It's not much at all as long as you remove every block from the map as soon as they hit the ground. (If you keep them in the map, things will indeed go wrong someday...)
    Your code only acts when cubes are shot and when they land. I am not expecting that stuff to happen hundreds of times per second (and even that is a very small task for a computer).
     
  25. Offline

    Elytes

    @knokko

    Yeah i'll try it, but, removing cube from the hashmap wont remove events registered in the class no ? So these events will get called even if I remove the cube from the hashmap ?
     
  26. Offline

    knokko

    @Elytes

    Removing the cube from the hashmap will not automtically cancel all events. But, you can check in your events if it is still in the hashmap and ignore the event if it is not.
     
  27. Offline

    Elytes

    @knokko

    Yes so it takes a lot of processor cycles cause 1 condition everytime someone left click with a stick, that gonna be insane ^^ Even if they have 4 seconds cooldown between 2 shots, we could get 1k of useless events :/
     
  28. Offline

    knokko

    @Elytes

    If I understand the situation correctly, for every ice block that is fired, 2 events will be fired. (1 for shooting and 1 for hitting the ground).

    The events for falling blocks hitting the ground will be fired by bukkit anyway, whether or not you make use of it. You don't need to update the ice blocks 20 times per second, right? All you have to do is listen for the EntityChangeBlockEvent and check if it is a falling block that is in the hashmap.

    So what 1k events are you talking about?
     

Share This Page