Solved Can't get a quite simple enchantment working

Discussion in 'Spigot Plugin Development' started by ZBLL, Jun 13, 2021.

Thread Status:
Not open for further replies.
  1. The point of the enchantment is simple: if a player wears an armor piece with the enchantment, then on death the killer gets damaged and yeeted. This is my code:
    Code (Java):

    @EventHandler
    public void onDeath(PlayerDeathEvent e) {
        Player killer = e.getEntity().getKiller(), player = e.getEntity();
        EntityEquipment eeq = null;
        if (killer.getEquipment() == null) eeq = null; else eeq = killer.getEquipment();
        Enchantment ench = Enchantment.getById(MYEHCNANTMENT.getId());
        if (eeq == null) return;
        if(
                (eeq.getHelmet() != null && eeq.getHelmet().getEnchantments().containsKey(ench)) ||
                        (eeq.getHelmet() != null && eeq.getChestplate().getEnchantments().containsKey(ench)) ||
                        (eeq.getHelmet() != null && eeq.getLeggings().getEnchantments().containsKey(ench)) ||
                        (eeq.getHelmet() != null && eeq.getBoots().getEnchantments().containsKey(ench))
        ) {//stuff}
     
    #1 ZBLL, Jun 13, 2021
    Last edited: Jun 14, 2021
  2. put sys out prints everywhere, also i think a better solution for checking for the enchantment would be a for loop, i might be wrong tho
     
  3. How would I implement a for loop with methods?
     
  4. Turns out it doesn't get to this line:
    Code (Java):

    if(
                (eeq.getHelmet() != null && eeq.getHelmet().getEnchantments().containsKey(ench)) ||
                        (eeq.getHelmet() != null && eeq.getChestplate().getEnchantments().containsKey(ench)) ||
                        (eeq.getHelmet() != null && eeq.getLeggings().getEnchantments().containsKey(ench)) ||
                        (eeq.getHelmet() != null && eeq.getBoots().getEnchantments().containsKey(ench))
        ) {
     
    To be more exact, it DOES get to it, but it seems like the checks don't succeed.
     
  5. Something like this should work, havent tested it.
    Code (Java):
    for (ItemStack armorPiece : player.getEquipment().getArmorContents()) {
                if (armorPiece != null && armorPiece.getEnchantments().containsKey(Enchantment.getByKey(new NamespacedKey(plugin, "enchantId")))) return true;
            }
            return false;
    EDIT: a better solution's down below ignore this
     
    #5 RoxioCZ, Jun 13, 2021
    Last edited: Jun 13, 2021
  6. lmao seems like u copied all the checks but didnt change the first condition in each line? its all checking helmet slot xd
     
    • Winner Winner x 1
  7. Oh my god lmfaoooooooooo
     
    • Funny Funny x 1
  8. took me a while to notice it lmfao
     
  9. By the way, make sure to check whether killer is null or not
     
    • Agree Agree x 2
  10. I gonna check that after writing this. But so far with this code it still doesn't go through the check - seems like it played chess for too long
    Code (Java):

    @EventHandler
    public void onDeath(PlayerDeathEvent e) {
        Player killer = e.getEntity().getKiller();
        Player player = e.getEntity();
        EntityEquipment eeq = null;
        if (killer.getEquipment() == null) eeq = null; else eeq = killer.getEquipment();
        Enchantment ench = Enchantment.getById(enchantment thingyyy);
        if (eeq == null) return;
        // TODO: CHANGE THE ENCHANTMENT NAME
        System.out.println("Reached point before checks");
        if(
                (eeq.getHelmet() != null && eeq.getHelmet().getEnchantments().containsKey(ench)) ||
                        (eeq.getChestplate() != null && eeq.getChestplate().getEnchantments().containsKey(ench)) ||
                        (eeq.getLeggings() != null && eeq.getLeggings().getEnchantments().containsKey(ench)) ||
                        (eeq.getBoots() != null && eeq.getBoots().getEnchantments().containsKey(ench))
        ) {
            System.out.println("Checks completed. Now what is going on here?..");
            killer.setVelocity(new Vector(8,6,2));
            killer.damage(floor(killer.getHealth()) / 4 * (new Random().nextInt(3) + 1));
        }
    }
     
    It only outputs the "Reached point before checks" and stops there.
     
  11. Just like @RoxioCZ pointed before, use loops to do that check
     
  12. So I rewrote it a little bit to make it break out of the loop if at least 1 piece contains the ench, and return if none do.
    Code (Java):

    for (ItemStack armorPiece : player.getEquipment().getArmorContents()) {
        if (armorPiece != null && armorPiece.getEnchantments().containsKey(ench)) break;
        return;
    }
     
    Let me test it.
     
  13. Nope, can't get past checks :(
     
  14. You could simplify this to:
    Code (Java):
    for (ItemStack armorPiece : player.getEquipment().getArmorContents()) {
        if (armorPiece == null || !armorPiece.getEnchantments().containsKey(ench)) return;
    }
     
    • Like Like x 1
  15. Can you try to change that enchantment with something else, like a default one? (don't forget to apply that default enchantment to your item)
     
  16. Still doesn't go through.
     
  17. This will early return out of the event handler if any piece doesn't have the enchantment.
    This is what you want if you want to see if any piece has the enchantment:

    Code (Java):
    var hasEnchant = Arrays.stream(player.getEquipment().getArmorContents())
       .filter(Objects::nonNull)
       .anyMatch(it -> it.containsEnchantment(enchant));

    if(!hasEnchant) return;
     
    • Winner Winner x 3
  18. I am pretty sure that I should use getEnchantments().containsKey() for custom enchants, but I'll try your approach with this little edit now. Thanks
     
  19. It works!! Thank you so much. I am going to test it with my 2 remaining armor enchants that, by a coincidence, don't work, and then close the thread.
     
  20. You are right, I thought he wants the whole armor to be enchanted, sorry @ZBLL
     
    • Friendly Friendly x 1
Thread Status:
Not open for further replies.