generate treasure on oppening
All checks were successful
Build / build (push) Successful in 2m47s

This commit is contained in:
unurled 2024-05-27 18:55:10 +02:00
parent 94e26dfef9
commit 22fa239f38
Signed by: unurled
GPG key ID: FDBC9CBE1F82423F
5 changed files with 157 additions and 14 deletions

View file

@ -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;
/* <b><color of the rarity>rarity
* <dark_gray>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();

View file

@ -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<String> 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);
}
}

View file

@ -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("<white>Common", "COMMON", 1, NamedTextColor.WHITE),
UNCOMMON("<green>UnCommon", "UnCOMMON", 2, NamedTextColor.GREEN),
RARE("<dark_aqua>Rare", "RARE", 3, NamedTextColor.DARK_AQUA),
EPIC("<dark_purple>Epic", "EPIC", 4, NamedTextColor.DARK_PURPLE),
LEGENDARY("<gold>Legendary", "LEGENDARY", 5, NamedTextColor.GOLD),
MYTHIC("<light_purple>Mythic", "MYTHIC", 6, NamedTextColor.LIGHT_PURPLE),
SPECIAL("<red>Special", "SPECIAL", 7, NamedTextColor.RED),
UNIQUE("<yellow>Unique", "UNIQUE", 8, NamedTextColor.YELLOW),
COMMON("<white>Common", "COMMON", 1d, NamedTextColor.WHITE),
UNCOMMON("<green>UnCommon", "UnCOMMON", 1_000d, NamedTextColor.GREEN),
RARE("<dark_aqua>Rare", "RARE", 10_000d, NamedTextColor.DARK_AQUA),
EPIC("<dark_purple>Epic", "EPIC", 1_000_000d, NamedTextColor.DARK_PURPLE),
LEGENDARY("<gold>Legendary", "LEGENDARY", 100_000_000d, NamedTextColor.GOLD),
MYTHIC("<light_purple>Mythic", "MYTHIC", 1_000_000_000d, NamedTextColor.LIGHT_PURPLE),
SPECIAL("<red>Special", "SPECIAL", 10_000_000_000d, NamedTextColor.RED),
UNIQUE("<yellow>Unique", "UNIQUE", -1d, NamedTextColor.YELLOW),
ADMIN(
"<color:#800000><obf>aa</obf><dark_red>Admin</dark_red><obf>aa</obf></color>",
"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;
}

View file

@ -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<ItemStack> 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<Integer, ItemStack> addItemsRandomlyToChest(
@NotNull List<ItemStack> items) {
List<Integer> availableSlots = new ArrayList<>();
for (int i = 0; i < TREASURE_SIZE; i++) {
availableSlots.add(i);
}
Collections.shuffle(availableSlots);
Map<Integer, ItemStack> 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;
}
}

View file

@ -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<Integer, Location> 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("<red>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) {