Event when arrow disappears in the void/setting arrow damage

Discussion in 'Spigot Help' started by Xeonmeister, Jul 1, 2018.

  1. Hi!
    So the thing is that i wanted to customize the damage of the power enchant on the bow, but i couldn't get the enchant level from the arrow when the damage happens. My solution is that when a player shoots a bow i put the arrow entity and the calculated damage value into a hashmap, and when the arrow hits i set the damage to the value stored in the hashmap. The problem is that i can only remove the arrow from the mentioned hashmap when they either hit a player or a block. I'd like to make a skypvp map so my problem is: all the arrows that miss even the ground and fall down into the void will remain in the hashmap creating some kind of memory leak over time.
    Is there an event for when an arrow disappears in the void?
    Or is there a better way of setting the arrow damage based on the power enchant of the bow it was shot from?
     
  2. Well for getting rid of the arrow you could try doing like an EntityDespawnEvent if there is one. I am not sure if that will work or not but it is worth a shot.

    I am not completely sure about the hashmap part. The first solution that comes to mind is an array list where you give an id to the arrow then give the arrow a damage amount. It may look like this in the array <id>:<damage> so you could have an array with those values then when the arrow hits the entity check what the id is and get the damage for it. That is one idea but it could be hard to implement.

    I could be wrong but you could just try to get the shooter of the arrow when it hits the player and gets the power of the bow at that instant rather than do all these savings of values. Of course, you would have to search the inventory for a bow in case they don't have the bow in their hand when the arrow hits the enemy.

    I may come up with a few other ideas later but those were just a few.
     
    • Like Like x 1
  3. You may want to check if the ProjectileHitEvent is fired when it hits the ground. None the less, you can use the Arrow#isOnGround function to check if... well, check if it's on the ground. If the above mentioned event is not fired, you could check every second whether there are arrow planted into the ground, and if so, remove them from the map.

    Though honestly, I wouldn't worry too much about a memory leak here. As mentioned earlier, the despawn event should at least fire. I would simply wait for that event and then remove the arrows. Having a few hundred items in a HashMap is not going to cause any issues. The last severe memory leak I had was caused by a collection that had (I believe) over 5 million entries. Might have been 50 million. I'm not sure, I fixed it long time ago, but it's safe to say a couple hundred arrows isn't gonna kill your server.

    You may however, want to create some kind of runnable that (every second) checks if the entity is still valid, if not, remove it from the map.
     
    • Like Like x 1
  4. What is problematic about the hashmap? It stores 2 values and I need 2 values and wanna get the dmg value based on the arrow entity (key).

    I know btw that this won't really cause a memory issue anyways but I don't like to leave flaws in my projects.
    I guess im gonna create a repeating task then to check if the entities are valid, thx for the tip. It's kinda like creating an inside garbage collector for that 1 hashmap.