diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/SlimefunRegistry.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/SlimefunRegistry.java index ab8d41bd21..e626ed95b4 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/SlimefunRegistry.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/SlimefunRegistry.java @@ -11,6 +11,7 @@ import java.util.Set; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ThreadLocalRandom; import javax.annotation.Nonnull; @@ -38,7 +39,6 @@ import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; import io.github.thebusybiscuit.slimefun4.implementation.guide.CheatSheetSlimefunGuide; import io.github.thebusybiscuit.slimefun4.implementation.guide.SurvivalSlimefunGuide; - import me.mrCookieSlime.Slimefun.api.BlockInfoConfig; import me.mrCookieSlime.Slimefun.api.BlockStorage; import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset; @@ -282,6 +282,19 @@ public Set getBarteringDrops() { return barterDrops; } + /** + * Returns a shuffled snapshot of the current bartering drops to avoid + * iteration order bias when evaluating random chances. + * + * @return A shuffled List of bartering drops + */ + @Nonnull + public List getRandomizedBarteringDrops() { + List list = new ArrayList<>(barterDrops); + Collections.shuffle(list, ThreadLocalRandom.current()); + return list; + } + @Nonnull public Set getRadioactiveItems() { return radioactive; diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/entity/PiglinListener.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/entity/PiglinListener.java index bb153b299e..f91ad751b1 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/entity/PiglinListener.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/entity/PiglinListener.java @@ -1,6 +1,6 @@ package io.github.thebusybiscuit.slimefun4.implementation.listeners.entity; -import java.util.Set; +import java.util.List; import java.util.concurrent.ThreadLocalRandom; import javax.annotation.Nonnull; @@ -78,21 +78,12 @@ public void onInteract(PlayerInteractEntityEvent e) { @EventHandler public void onPiglinDropItem(EntityDropItemEvent e) { if (e.getEntity() instanceof Piglin) { - Set drops = Slimefun.getRegistry().getBarteringDrops(); - - /* - * NOTE: Getting a new random number each iteration because multiple items could have the same - * % chance to drop, and if one fails all items with that number will fail. - * Getting a new random number will allow multiple items with the same % chance to drop. - */ - + List drops = Slimefun.getRegistry().getRandomizedBarteringDrops(); + for (ItemStack is : drops) { SlimefunItem sfi = SlimefunItem.getByItem(is); - // Check the getBarteringLootChance and compare against a random number 0-100, - // if the random number is greater then replace the item. if (sfi instanceof PiglinBarterDrop piglinBarterDrop) { int chance = piglinBarterDrop.getBarteringLootChance(); - if (chance < 1 || chance >= 100) { sfi.warn("The Piglin Bartering chance must be between 1-99% on item: " + sfi.getId()); } else if (chance > ThreadLocalRandom.current().nextInt(100)) {