Search code examples
javaeventspluginsminecraftprojectile

How to detect a custom Crossbow in mainhand?


I am trying to detect the crossbow in the players hand (it is a cutom item), but only the bow (also a custom item) seems to be working the way I have it set up right now. Only the bow will show "fire" (and run the code properly) when I test each item.

    @EventHandler
public void playerBowShoot(EntityShootBowEvent e) {
    Entity entity = e.getEntity();
    Entity arrow = e.getProjectile();
    if (entity.getType().equals(EntityType.PLAYER)) {
        Player p = (Player) entity;
        if (p.getInventory().getItemInMainHand().getItemMeta().equals(Weapons.crossbow.getItemMeta())) {
            Bukkit.broadcastMessage("fire");
            arrow.setVelocity(p.getLocation().getDirection().multiply(100.0D));
        }
        if (p.getInventory().getItemInMainHand().getItemMeta().equals(Weapons.bow.getItemMeta())) {
            Bukkit.broadcastMessage("fire");
            arrow.setVelocity(p.getLocation().getDirection().multiply(100.0D));
        }

    }
}

Solution

  • You should not use the item meta to check the type, but getType() :

    @EventHandler
    public void playerBowShoot(EntityShootBowEvent e) {
        Entity entity = e.getEntity();
        Entity arrow = e.getProjectile();
        if (entity instanceof Player) {
            Player p = (Player) entity;
            ItemStack hand = p.getInventory().getItemInMainHand();
            if(hand == null) { // nothing in hand
            }  else if (hand.getType().equals(Material.CROSSBOW) && hand.getItemMeta().getDisplayName().equals(theNameOfTheCrossbow)) { // it's a crossbow
                Bukkit.broadcastMessage("fire");
                arrow.setVelocity(p.getLocation().getDirection().multiply(100.0D));
            }
        }
    }
    

    To check if it's the good item, you can:

    • Just check the type if you want to apply to all items
    • Check for custom names/lores/enchants etc...
    • Check is similar. Can't be used if the item can be damaged (for example with a sword with durability) or you should copy item, set same durability to check both with firstItem.isSimilar(secondItem)