diff --git a/src/main/java/me/unurled/sacredrealms/sr/components/item/Item.java b/src/main/java/me/unurled/sacredrealms/sr/components/item/Item.java index ceaa8b1..669c448 100644 --- a/src/main/java/me/unurled/sacredrealms/sr/components/item/Item.java +++ b/src/main/java/me/unurled/sacredrealms/sr/components/item/Item.java @@ -22,6 +22,7 @@ import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.persistence.PersistentDataContainer; import org.bukkit.persistence.PersistentDataType; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /* rarity * Description: blablabla @@ -207,6 +208,7 @@ public class Item { this.customModelData = customModelData; } + @Nullable public ItemStack toItemStack() { ItemStack item = new ItemStack(material); ItemMeta meta = item.getItemMeta(); diff --git a/src/main/java/me/unurled/sacredrealms/sr/components/item/ItemManager.java b/src/main/java/me/unurled/sacredrealms/sr/components/item/ItemManager.java index ee50c7a..2572df5 100644 --- a/src/main/java/me/unurled/sacredrealms/sr/components/item/ItemManager.java +++ b/src/main/java/me/unurled/sacredrealms/sr/components/item/ItemManager.java @@ -12,6 +12,7 @@ import org.bukkit.NamespacedKey; import org.bukkit.inventory.ItemStack; import org.bukkit.persistence.PersistentDataType; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; public class ItemManager extends Manager { public static final NamespacedKey ID = new NamespacedKey("sr", "id"); @@ -93,4 +94,12 @@ public class ItemManager extends Manager { public List getItemIDs() { return List.copyOf(items.keySet()); } + + @Nullable + public Item getRandomByRarityItem(@NotNull Rarity rarity) { + return items.values().stream() + .filter(item -> item.getRarity() == rarity) + .findAny() + .orElse(null); + } } diff --git a/src/main/java/me/unurled/sacredrealms/sr/components/item/Rarity.java b/src/main/java/me/unurled/sacredrealms/sr/components/item/Rarity.java index cb4c5c5..a83fde0 100644 --- a/src/main/java/me/unurled/sacredrealms/sr/components/item/Rarity.java +++ b/src/main/java/me/unurled/sacredrealms/sr/components/item/Rarity.java @@ -1,35 +1,69 @@ package me.unurled.sacredrealms.sr.components.item; +import java.util.Random; import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.TextColor; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; public enum Rarity { - COMMON("Common", "COMMON", 1, NamedTextColor.WHITE), - UNCOMMON("UnCommon", "UnCOMMON", 2, NamedTextColor.GREEN), - RARE("Rare", "RARE", 3, NamedTextColor.DARK_AQUA), - EPIC("Epic", "EPIC", 4, NamedTextColor.DARK_PURPLE), - LEGENDARY("Legendary", "LEGENDARY", 5, NamedTextColor.GOLD), - MYTHIC("Mythic", "MYTHIC", 6, NamedTextColor.LIGHT_PURPLE), - SPECIAL("Special", "SPECIAL", 7, NamedTextColor.RED), - UNIQUE("Unique", "UNIQUE", 8, NamedTextColor.YELLOW), + COMMON("Common", "COMMON", 1d, NamedTextColor.WHITE), + UNCOMMON("UnCommon", "UnCOMMON", 1_000d, NamedTextColor.GREEN), + RARE("Rare", "RARE", 10_000d, NamedTextColor.DARK_AQUA), + EPIC("Epic", "EPIC", 1_000_000d, NamedTextColor.DARK_PURPLE), + LEGENDARY("Legendary", "LEGENDARY", 100_000_000d, NamedTextColor.GOLD), + MYTHIC("Mythic", "MYTHIC", 1_000_000_000d, NamedTextColor.LIGHT_PURPLE), + SPECIAL("Special", "SPECIAL", 10_000_000_000d, NamedTextColor.RED), + UNIQUE("Unique", "UNIQUE", -1d, NamedTextColor.YELLOW), ADMIN( "aaAdminaa", "ADMIN", - 100, + -1d, NamedTextColor.DARK_RED); private final String name; private final String id; - private final Integer weight; + private final Double weight; private final TextColor color; - Rarity(String name, String id, Integer weight, TextColor color) { + Rarity(String name, String id, Double weight, TextColor color) { this.name = name; this.id = id; this.weight = weight; this.color = color; } + @Nullable + public static Rarity getByWeight(int weight) { + for (Rarity rarity : values()) { + if (rarity.getWeight() == weight) { + return rarity; + } + } + return null; + } + + @NotNull + public static Rarity getRandomRarity(double luck) { + // more weight equals less chance to get it + Random random = new Random(); + double randomValue = random.nextDouble() * (1.0 / (luck == 0 ? 1 : luck)); + + double cumulativeProbability = 0.0; + for (Rarity rarity : Rarity.values()) { + if (rarity.getWeight() == -1) { + continue; + } + + cumulativeProbability += 1.0 / rarity.getWeight(); + + if (randomValue <= cumulativeProbability) { + return rarity; + } + } + return Rarity.COMMON; + } + public String getName() { return name; } @@ -40,7 +74,7 @@ public enum Rarity { } @SuppressWarnings("unused") - public Integer getWeight() { + public Double getWeight() { return weight; } diff --git a/src/main/java/me/unurled/sacredrealms/sr/components/treasure/TreasureGenerator.java b/src/main/java/me/unurled/sacredrealms/sr/components/treasure/TreasureGenerator.java new file mode 100644 index 0000000..b15edbc --- /dev/null +++ b/src/main/java/me/unurled/sacredrealms/sr/components/treasure/TreasureGenerator.java @@ -0,0 +1,92 @@ +package me.unurled.sacredrealms.sr.components.treasure; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Random; +import me.unurled.sacredrealms.sr.components.attributes.Attribute; +import me.unurled.sacredrealms.sr.components.item.Item; +import me.unurled.sacredrealms.sr.components.item.ItemManager; +import me.unurled.sacredrealms.sr.components.item.Rarity; +import me.unurled.sacredrealms.sr.components.player.SRPlayer; +import me.unurled.sacredrealms.sr.managers.Manager; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; + +public class TreasureGenerator { + + public static final int TREASURE_SIZE = 27; + public static final int MIN_ITEMS = 1; + private static final int MAX_ITEMS = 10; + private static ItemManager im; + private static Random random; + + @Contract(pure = true) + public static @NotNull Treasure generateTreasure( + @NotNull Treasure treasure, @NotNull SRPlayer p) { + if (im == null) { + im = Manager.getInstance(ItemManager.class); + } + if (random == null) { + random = new Random(); + } + // generate the treasure based on player level + int level = p.getLevel(); + double luck = p.getAttribute(Attribute.LUCK); + + // the more level and luck the player has, the better the item he will get + // the item will have a random rarity + // max of 10 items + int nbItems = calculateNumberOfItems(luck, level); + + List items = new ArrayList<>(); + + for (int i = 0; i < nbItems; i++) { + // generate item + Rarity rarity = Rarity.getRandomRarity(luck); + Item item = im.getRandomByRarityItem(rarity); + ItemStack itemStack = null; + if (item != null) { + itemStack = item.toItemStack(); + } + if (itemStack == null) { + continue; + } + if (rarity.getWeight() < Rarity.EPIC.getWeight()) { + // cant have more than 1 + itemStack.setAmount(random.nextInt(17)); + } + // add item to treasure + items.add(itemStack); + } + treasure.setItems(addItemsRandomlyToChest(items)); + + return treasure; + } + + private static @NotNull Map addItemsRandomlyToChest( + @NotNull List items) { + List availableSlots = new ArrayList<>(); + for (int i = 0; i < TREASURE_SIZE; i++) { + availableSlots.add(i); + } + + Collections.shuffle(availableSlots); + Map itemsList = new HashMap<>(); + for (int i = 0; i < items.size(); i++) { + itemsList.put(availableSlots.get(i), items.get(i)); + } + return itemsList; + } + + private static int calculateNumberOfItems(double luck, int level) { + // Example formula to calculate the number of items based on luck and level + double modifiedLuck = Math.max(luck, 1); // Ensure luck is at least 1 to avoid division by zero + int baseItems = MIN_ITEMS + level; + int maxPossibleItems = (int) Math.min(MAX_ITEMS, baseItems + (modifiedLuck / 10000.0)); + return random.nextInt(maxPossibleItems - MIN_ITEMS + 1) + MIN_ITEMS; + } +} diff --git a/src/main/java/me/unurled/sacredrealms/sr/components/treasure/TreasureManager.java b/src/main/java/me/unurled/sacredrealms/sr/components/treasure/TreasureManager.java index c13ccb6..af87414 100644 --- a/src/main/java/me/unurled/sacredrealms/sr/components/treasure/TreasureManager.java +++ b/src/main/java/me/unurled/sacredrealms/sr/components/treasure/TreasureManager.java @@ -137,7 +137,6 @@ public class TreasureManager extends Manager { private void onTreasureOpen(PlayerInteractEvent e, Block clickedBlock) { // it is a chest, lets loop on all treasure and find if the clicked block is a treasure chest - for (Entry location : locations.entrySet()) { if (location.getValue().equals(clickedBlock.getLocation())) { // it is a treasure chest, lets open it @@ -147,13 +146,20 @@ public class TreasureManager extends Manager { p.sendMessage(textComp("An Error occurred contact an Admin.")); return; } - if (!p.hasPermission(treasure.getPermission())) { + if (treasure.getPermission() != null && !p.hasPermission(treasure.getPermission())) { p.sendMessage("You don't have permission to open this chest"); p.playSound(p.getLocation(), Sound.BLOCK_ANVIL_BREAK, 1f, 0.5f); e.setCancelled(true); return; } e.setCancelled(true); + // generate the treasure + PlayerManager pm = Manager.getInstance(PlayerManager.class); + SRPlayer sr = pm.getPlayer(p.getUniqueId()); + if (sr == null) { + return; + } + treasure = TreasureGenerator.generateTreasure(treasure, sr); p.openInventory(treasure.getInventory()); SRPlayer srPlayer = Manager.getInstance(PlayerManager.class).getPlayer(p.getUniqueId()); if (srPlayer != null) {