Check for Enchantment on Entity Trident

Discussion in 'Plugin Development' started by Smeary_Subset, Sep 23, 2022.

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

    Smeary_Subset

    How can I check to see if a thrown Trident projectile has an enchantment? In my minigame, I want to Tridents without the loyalty enchantment to be removed on hit, but not the ones with the Loyalty enchantment.

    Thanks,
    Smeary
     
  2. Offline

    Strahan

    The way I'd do it would be to create a NamespacedKey in the class then listen to ProjectileLaunchEvent. Check if the projectile is a trident; if not, return. Then I'd get the Player from the projectile's getShooter() and grab the item from their hand. If the ItemMeta doesn't have the loyalty enchant, return. Then lastly apply the NamespacedKey to the projectile's PersistentDataContainer (NOT to the item in hand!).

    Then listen to ProjectileHitEvent. If it doesn't have the key, return. Then after that just call remove on the projectile.
     
  3. Offline

    Smeary_Subset

    How do NamespacedKeys work? I've tried to figure it out and look it up in the java docs but honestly I just can't grasp them.
     
  4. Offline

    Strahan

    To make a key, you pass it an instance of your main class and a name. Then you can use the PersistentDataContainer#has method to check if it exists. You pass has the key and the data type you used when setting. So for the trident example, if it was all in the main class it'd be something like
    Code:
    class {
      private NamespacedKey wipeTrident = new NamespacedKey(this, "wipeTrident");
    
      @EventHandler
      public void onLaunch(ProjectileLaunchEvent e) {
       if (e.getEntity().getType() != EntityType.TRIDENT) return;
       if (!(e.getEntity().getShooter() instanceof Player)) return;
    
       Player p = (Player)e.getEntity().getShooter();
       ItemStack i = p.getInventory().getItemInMainHand();
       ItemMeta im = i.getItemMeta();
        if (im.hasEnchant(Enchantment.LOYALTY)) return;
    
        e.getEntity().getPersistentDataContainer().set(wipeTrident, PersistentDataType.INTEGER, 1);
      }
    
      @EventHandler
      public void onHit(ProjectileHitEvent e) {
        Projectile pj = e.getEntity();
        if (!pj.getPersistentDataContainer().has(wipeTrident, PersistentDataType.INTEGER)) return;
    
        pj.remove();
      }
    }
    So in the example, I first setup the key object then in the launch once I know it's a trident I wish to be disappeared upon landing, I apply the key with an int value of 1. The value is irrelevant, just something. Doesn't have to be int either. Then when the projectile hits, I check if it has that key set. If so, remove.

    That's basically it. Pretty straight forward.
     
Thread Status:
Not open for further replies.

Share This Page