Solved Spawn Random Item With Random Enchantments

Discussion in 'Spigot Plugin Development' started by Anshu, Jul 3, 2021.

  1. Hello, I am working on a small Spigot Plugin and I got stuck here that I want to spawn random item with random enchantments at a specific location and I don't have any idea about this. Please give me answer with code and full explanation.

    Thank You!

    And don't mind if there is any mistake because I am Indian and I don't know English that perfect.
     
  2. I would do it like this (it's not really efficient but it works):
    Code (Java):

    Material[] materials = new Material[] { // materials that I want to use };
    Enchantment[] enchs = new Enchantment[] { // enchs that I want to use };
    Location loc = // your location

    randomMat = new Random().nextInt(materials.length); // random material out ot materials[]
    randomEnch = new Random.nextInt(enchs.length); // random material out of enchs[]
    randomLvl = new Random().nextInt(6); // assuming you want a random ench level

    ItemStack item = new ItemStack(materials[randomMat]); // creating itemstack with a material, taken from materials[], with index of randomMat
    item.addUnsafeEnchantment(enchs[randomEnch], randomLvl); // adding an enchantment from enchs[] with the index of randomEnch, and level of randomLvl

    loc.getWorld().dropItemNaturally(loc, item);
     
    There's probably a better way to do this, for example, iterate through the enchantments
     
    #2 ZBLL, Jul 3, 2021
    Last edited: Aug 11, 2021
    • Informative Informative x 2
    • Agree Agree x 1
  3. Also not all enchantments have max level of 5.
     
  4. And I think it's quite hard to get all enchantments, since they are not an enum, but just static fields in Enchant class. So my only idea is to make it using reflection.
     
  5. I don't understand. What is reflection?
     
  6. That's quite hard to explain. But look at the Enchantment class, as you can see, it is a class not an enum (Material is an enum for ex.). All the enchantments there are public static fields. That means, you can't get all of them in some kind of a collection (array, list) so you can loop through them. The only way to get them in a collection programmatically (not having 100 lines with every enchantment) would be using reflection. I will not explain what reflection is, you can look that up :) Java Reflection. It's basically inspecting code inside of code. So you can for example print name of the current method.
     
    • Optimistic Optimistic x 1
    • Agree Agree x 1
  7. Hey there! I thought, what a cool idea.
    I've made some code for you and commented what it does. It uses the Java 8 streams to make things work much nicer. See if you can figure out how it works and if not, post a reply of what is bugging your mind!
    Code (Java):

      Material[] mats = new Material[]{Material.DIAMOND_AXE, Material.DIAMOND_PICKAXE, Material.DIAMOND_SHOVEL, Material.DIAMOND_SWORD};
      Random rnd = new Random();
     
      public ItemStack getRndEnchItem() {
        Material chosen = mats[rnd.nextInt(mats.length)];
        ItemStack item = new ItemStack(chosen);

        Arrays.stream(Enchantment.values())
          .filter(ench -> ench.canEnchantItem(item)) //Gets only enchants that the item can have
        .forEach(ench ->
          item.addEnchantment(ench,rnd.nextInt(ench.getMaxLevel())) //Adds a random level enchant that is possible (if 0 the enchant is not added)
        );
       
        return item;
      }
    It works with all materials but be ware, that only some materials can be enchanted, e.g if you try to get a STONE_BRICKS then it wown't enchant it!
     
    • Like Like x 4
    • Agree Agree x 2
  8. Hello, First on first Thank You for your help. I understand everything except Arrays.stream function. Can you please explain me in a very understandable way and I don't what is ench in .filter(ench -> ench.canEnchantItem(item))

    Thank You Again.

    And as I write in this thread description I don't know English that perfect so if there is any mistake please don't mind.
     
    #10 Anshu, Jul 3, 2021
    Last edited: Jul 3, 2021
  9. Yup sure!
    Arrays.stream function converts the array of enchantments into a stream of enchantments. Its another collection type in Java. Examples of what it can do is here: Baeldung
    They are a very useful feature in java and it makes it so you can convert a collection into an iterable and use it easily. A stream is similar to a List or Itterable but with a lot more features.
     
    • Like Like x 1
    • Informative Informative x 1
  10. What is ench here?
     
  11. ench is a variable I created in order to filter out enchantments that can enchant the item.

    a --> true/false is a filter as it uses a variable (a) and gets a response, either true or false to see whether or not to filter the enchantment out.
     
    • Like Like x 1
  12. Lookup Java Lambdas ;)
     
    • Like Like x 2
  13. Sir, Is there any way to add more than one enchantments in a item?
     
  14. Sir, Sorry to say that I implemented this and it worked very well I got everything that I mentioned except gear
    like enchanted diamond sword and netherite armor.

    Please Help Me.

    Here is my code:

    Code (Text):
    Material[] materials = new Material[]{

                Material.DIAMOND_BLOCK, Material.DIAMOND_PICKAXE,
                Material.DIAMOND_AXE, Material.DIAMOND_SWORD,
                Material.DIAMOND_CHESTPLATE, Material.DIAMOND_HELMET,
                Material.DIAMOND_BOOTS, Material.DIAMOND_LEGGINGS,
                Material.NETHERITE_BLOCK, Material.NETHERITE_PICKAXE,
                Material.NETHERITE_AXE, Material.NETHERITE_SWORD,
                Material.NETHERITE_CHESTPLATE, Material.NETHERITE_HELMET,
                Material.NETHERITE_BOOTS, Material.NETHERITE_LEGGINGS,
                Material.BOW,Material.BAKED_POTATO,Material.ENCHANTED_GOLDEN_APPLE,
                Material.GOLDEN_APPLE,Material.GOLDEN_CARROT,Material.GOLD_BLOCK,
                Material.IRON_BLOCK,Material.OBSIDIAN,Material.ENDER_PEARL,
                Material.ENDER_EYE,Material.LAVA_BUCKET,Material.WATER_BUCKET,
                Material.END_PORTAL_FRAME,Material.VILLAGER_SPAWN_EGG,
                Material.ENDERMAN_SPAWN_EGG,Material.CHICKEN_SPAWN_EGG,
                Material.DIRT,Material.DIAMOND_HOE,Material.NETHERITE_HOE,
                Material.DIAMOND_SHOVEL,Material.NETHERITE_SHOVEL

        };
        Enchantment[] enchantments = new Enchantment[]{

                Enchantment.ARROW_DAMAGE,Enchantment.ARROW_INFINITE,
                Enchantment.ARROW_FIRE,Enchantment.ARROW_KNOCKBACK,
                Enchantment.CHANNELING,Enchantment.DAMAGE_ALL,
                Enchantment.DAMAGE_ARTHROPODS,Enchantment.DAMAGE_UNDEAD,
                Enchantment.DEPTH_STRIDER,Enchantment.DIG_SPEED,
                Enchantment.DURABILITY,Enchantment.FIRE_ASPECT,
                Enchantment.FROST_WALKER,Enchantment.IMPALING,
                Enchantment.KNOCKBACK,Enchantment.LOOT_BONUS_BLOCKS,
                Enchantment.LOOT_BONUS_MOBS,Enchantment.LOYALTY,
                Enchantment.LUCK,Enchantment.LURE,
                Enchantment.MENDING,Enchantment.MULTISHOT,
                Enchantment.OXYGEN,Enchantment.PIERCING,
                Enchantment.PROTECTION_ENVIRONMENTAL,Enchantment.PROTECTION_EXPLOSIONS,
                Enchantment.PROTECTION_FALL,Enchantment.PROTECTION_FIRE,
                Enchantment.PROTECTION_PROJECTILE,Enchantment.RIPTIDE,
                Enchantment.QUICK_CHARGE,Enchantment.SILK_TOUCH,
                Enchantment.SOUL_SPEED,Enchantment.SWEEPING_EDGE,
                Enchantment.THORNS,Enchantment.WATER_WORKER

        };

        Random random = new Random();

    Material mat = materials[random.nextInt(materials.length)];
    ItemStack item = new ItemStack(mat);

    Arrays.stream(Enchantment.values())
          .filter(enchantments ->
                  enchantments.canEnchantItem(item))
          .forEach(enchantments ->
                  item.addEnchantment(enchantments, random.nextInt(enchantments.getMaxLevel())));

    world.dropItemNaturally(location, item);
     
  15. I know, that's why I used addUnsafeEnchantment - it allows any level for any enchantment
     
    • Like Like x 1
  16. I know, but I think he wants have them like legal powers. You can use Enchantment#getMaxLevel();
     
    • Like Like x 1
  17. Try adding one to the enchantments:
    Code (Java):

                  item.addEnchantment(enchantments, random.nextInt(enchantments.getMaxLevel()+1)));
    Can you also show us your whole class as the code looks a bit messy? (use a paste bin), Thanks.
     
  18. Sir, Thank You. All my whole problem is solved. But, one thing can I generate a random integer between max int and min int.