Basically I'm creating a basic bridge server and don't want players to pick up arrows after they fire it. Essentially have the same arrow mechanics as Lunar and Minemen. There are multiple ways to approach this such as canceling pickup event and destroying the packet, but for performance sake, I'd like to just destroy the arrow once the it lands on a block. Any ideas on how to approach this?
Thanks! How would I check if the arrow lands on a block though? I've checked a few forum posts and examples, but none of them seemed helpful. EDIT: wait im dumb. mbmbmbmbmbmb Code:java @EventHandler public void onHit(ProjectileHitEvent event) { Projectile is = event.getEntity(); if (is instanceof Arrow) { Arrow arrow = (Arrow) is; if (arrow.isOnGround()) { } } }
ProjectileHitEvent should still fire even if the projectile hits a block or a player. Theoretically, you can track hit projectiles, put their UUIDs or something in a list, then another event handler (PlayerPickupItemEvent) should see if the UUID of the item being picked up exists within that list, if it does, remove it? Additional info (?): the event will fire once if the projectile is an egg, a snowball or an arrow (1.8), but it will keep firing if it's a fishing rod until you pull the rod back. If so, just listening to the event and and event.getEntity().remove() works.
@Xp10d3 Just get the arrow and check for nearby entities with a radius of 0 in the ProjectileHitEvent and if it hit a block then the list will be empty, it may still trigger if the arrow hits an item or something so just check if the entity in the list is an instance of a LivingEntity.
Alright; I'll try that. Thanks! I don't believe I can check if it hits a block (since #getHitBlock doesn't exist for 1.8 :C ), but that is helpful; thanks EDIT: Currently what I have: Code:java @EventHandler public void onHit(ProjectileHitEvent event) { if (event.getEntityType().equals(EntityType.ARROW)) { arrowUUID.add(event.getEntity().getUniqueId()); } }... @EventHandler public void onPickup(PlayerPickupItemEvent event) { Iterator<UUID> uuid = arrowUUID.iterator(); while (uuid.hasNext()) { UUID uuidD = uuid.next(); if (uuidD.equals(event.getItem().getUniqueId())) { event.setCancelled(true); event.getItem().remove(); uuid.remove(); } } }
@Xp10d3 I can't confirm that it will work with UUIDs as I stored them as Entities to test. And using an iterator is only advised if you're removing items at the same time as you're iterating through the list, but in this case, you only need to remove that exact item you have. Code:Java // Removes the item and it isn't necessary to check if that item exists in the list.list.remove(item)
Ah I see mb. Thanks. Well if it doesn't work I can prob just check if the item is an arrow specifically: Code:java if (event.getItem().equals(new ItemStack(Material.ARROW)) { event.setCancelled(true) event.removeItem();} or something similar
@Xp10d3 If you're creating a new ItemStack like that, it's not going to be return as true, ever. You're comparing an Item object to an ItemStack, worse is that the ItemStack is just freshly created. Your code was partly right, try this: Code:Java if (list.contains(item.getUniqueId())) { event.setCancelled(true); item.remove(); list.remove(item.getUniqueId());}
No, I am not saying use getHitBlock. I am saying that in the ProjectileHitEvent use e.getEntity().getNearbyEntities(0, 0, 0).isEmpty() and if that is true then the arrow hit a block, however if it is false then it hit an entity and the arrow is stuck on them, so just get the entity from the list and now you have it.
Sorry for the late reply; seems to work Code:java List<UUID> arrowUUID = new ArrayList<UUID>(); @EventHandler public void onHit(ProjectileHitEvent event) { if (event.getEntityType().equals(EntityType.ARROW)) { arrowUUID.add(event.getEntity().getUniqueId()); } } @EventHandler public void onPickup(PlayerPickupItemEvent event) { Iterator<UUID> uuid = arrowUUID.iterator(); while (uuid.hasNext()) { UUID uuidD = uuid.next(); if (uuidD.equals(event.getItem().getUniqueId())) { event.setCancelled(true); event.getItem().remove(); uuid.remove(); } } } Ah I see. I guess I could've done that. Thanks for the help anyways though