From d762e554653dfbb497b15a98e329788298def200 Mon Sep 17 00:00:00 2001 From: SimolZimol <70102430+SimolZimol@users.noreply.github.com> Date: Fri, 23 May 2025 21:23:57 +0200 Subject: [PATCH] modified: plugin.yml modified: src/main/java/com/simolzimol/levelcraft/LevelCraft.java new file: src/main/java/com/simolzimol/levelcraft/command/TestSmithChestCommand.java modified: src/main/java/com/simolzimol/levelcraft/listener/LootListener.java new file: src/main/java/com/simolzimol/levelcraft/listener/VillagerTradeListener.java --- plugin.yml | 5 +- .../com/simolzimol/levelcraft/LevelCraft.java | 3 + .../command/TestSmithChestCommand.java | 37 ++++++++ .../levelcraft/listener/LootListener.java | 86 +++++++++++++------ .../listener/VillagerTradeListener.java | 53 ++++++++++++ 5 files changed, 156 insertions(+), 28 deletions(-) create mode 100644 src/main/java/com/simolzimol/levelcraft/command/TestSmithChestCommand.java create mode 100644 src/main/java/com/simolzimol/levelcraft/listener/VillagerTradeListener.java diff --git a/plugin.yml b/plugin.yml index 3a016de..3ef6fda 100644 --- a/plugin.yml +++ b/plugin.yml @@ -3,4 +3,7 @@ main: com.simolzimol.levelcraft.LevelCraft version: 1.0 api-version: 1.21 author: SimolZimol -description: TEXT \ No newline at end of file +description: TEXT +commands: + testsmithchest: + description: Gibt dir eine Kiste \ No newline at end of file diff --git a/src/main/java/com/simolzimol/levelcraft/LevelCraft.java b/src/main/java/com/simolzimol/levelcraft/LevelCraft.java index 1a3d827..60c8b3c 100644 --- a/src/main/java/com/simolzimol/levelcraft/LevelCraft.java +++ b/src/main/java/com/simolzimol/levelcraft/LevelCraft.java @@ -8,6 +8,9 @@ public class LevelCraft extends JavaPlugin { getLogger().info("LevelCraft aktiviert!"); com.simolzimol.levelcraft.item.ItemUtil.init(this); getServer().getPluginManager().registerEvents(new com.simolzimol.levelcraft.listener.CraftListener(), this); + getServer().getPluginManager().registerEvents(new com.simolzimol.levelcraft.listener.LootListener(this), this); + getServer().getPluginManager().registerEvents(new com.simolzimol.levelcraft.listener.VillagerTradeListener(), this); + getCommand("testsmithchest").setExecutor(new com.simolzimol.levelcraft.command.TestSmithChestCommand()); } @Override diff --git a/src/main/java/com/simolzimol/levelcraft/command/TestSmithChestCommand.java b/src/main/java/com/simolzimol/levelcraft/command/TestSmithChestCommand.java new file mode 100644 index 0000000..a773e06 --- /dev/null +++ b/src/main/java/com/simolzimol/levelcraft/command/TestSmithChestCommand.java @@ -0,0 +1,37 @@ +package com.simolzimol.levelcraft.command; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.block.Chest; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.loot.LootTables; + +public class TestSmithChestCommand implements CommandExecutor { + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + if (!(sender instanceof Player player)) { + sender.sendMessage("Nur Spieler können diesen Befehl nutzen."); + return true; + } + + Location loc = player.getLocation(); + World world = loc.getWorld(); + Block block = world.getBlockAt(loc); + + // Setze Block zu Kiste + block.setType(Material.CHEST); + Chest chest = (Chest) block.getState(); + + // Setze den Schmied-Lootpool + chest.setLootTable(LootTables.VILLAGE_WEAPONSMITH.getLootTable()); + chest.update(); + + player.sendMessage("Kiste mit Schmied-Loot an deiner Position gespawnt!"); + return true; + } +} \ No newline at end of file diff --git a/src/main/java/com/simolzimol/levelcraft/listener/LootListener.java b/src/main/java/com/simolzimol/levelcraft/listener/LootListener.java index 389da1b..76ca68a 100644 --- a/src/main/java/com/simolzimol/levelcraft/listener/LootListener.java +++ b/src/main/java/com/simolzimol/levelcraft/listener/LootListener.java @@ -2,49 +2,81 @@ package com.simolzimol.levelcraft.listener; import com.simolzimol.levelcraft.item.ItemUtil; import com.simolzimol.levelcraft.item.Rarity; +import org.bukkit.Bukkit; +import org.bukkit.Material; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; -import org.bukkit.event.player.PlayerInteractEvent; -import org.bukkit.block.Block; -import org.bukkit.block.BlockState; -import org.bukkit.block.Container; +import org.bukkit.event.inventory.InventoryOpenEvent; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.persistence.PersistentDataType; +import org.bukkit.plugin.Plugin; +import java.util.EnumSet; import java.util.Random; +import java.util.Set; public class LootListener implements Listener { private final Random random = new Random(); + private final Plugin plugin; + + public LootListener(Plugin plugin) { + this.plugin = plugin; + } + + // Set mit allen erlaubten Typen (Waffen, Rüstung, Werkzeuge) + private static final Set ALLOWED = EnumSet.of( + // Schwerter + Material.WOODEN_SWORD, Material.STONE_SWORD, Material.IRON_SWORD, Material.GOLDEN_SWORD, Material.DIAMOND_SWORD, Material.NETHERITE_SWORD, + // Äxte + Material.WOODEN_AXE, Material.STONE_AXE, Material.IRON_AXE, Material.GOLDEN_AXE, Material.DIAMOND_AXE, Material.NETHERITE_AXE, + // Spitzhacken + Material.WOODEN_PICKAXE, Material.STONE_PICKAXE, Material.IRON_PICKAXE, Material.GOLDEN_PICKAXE, Material.DIAMOND_PICKAXE, Material.NETHERITE_PICKAXE, + // Schaufeln + Material.WOODEN_SHOVEL, Material.STONE_SHOVEL, Material.IRON_SHOVEL, Material.GOLDEN_SHOVEL, Material.DIAMOND_SHOVEL, Material.NETHERITE_SHOVEL, + // Hacken + Material.WOODEN_HOE, Material.STONE_HOE, Material.IRON_HOE, Material.GOLDEN_HOE, Material.DIAMOND_HOE, Material.NETHERITE_HOE, + // Rüstung + Material.LEATHER_HELMET, Material.LEATHER_CHESTPLATE, Material.LEATHER_LEGGINGS, Material.LEATHER_BOOTS, + Material.CHAINMAIL_HELMET, Material.CHAINMAIL_CHESTPLATE, Material.CHAINMAIL_LEGGINGS, Material.CHAINMAIL_BOOTS, + Material.IRON_HELMET, Material.IRON_CHESTPLATE, Material.IRON_LEGGINGS, Material.IRON_BOOTS, + Material.GOLDEN_HELMET, Material.GOLDEN_CHESTPLATE, Material.GOLDEN_LEGGINGS, Material.GOLDEN_BOOTS, + Material.DIAMOND_HELMET, Material.DIAMOND_CHESTPLATE, Material.DIAMOND_LEGGINGS, Material.DIAMOND_BOOTS, + Material.NETHERITE_HELMET, Material.NETHERITE_CHESTPLATE, Material.NETHERITE_LEGGINGS, Material.NETHERITE_BOOTS, + // Schilde + Material.SHIELD, + // Bogen, Armbrust, Dreizack + Material.BOW, Material.CROSSBOW, Material.TRIDENT + ); @EventHandler - public void onChestOpen(PlayerInteractEvent event) { - Block block = event.getClickedBlock(); - if (block == null) return; - BlockState state = block.getState(); - if (!(state instanceof Container container)) return; + public void onInventoryOpen(InventoryOpenEvent event) { + Inventory inv = event.getInventory(); - Inventory inv = container.getInventory(); - for (ItemStack item : inv.getContents()) { - if (item == null) continue; - // Nur Items mit Haltbarkeit (Waffen, Rüstung, Werkzeuge, Angel, ...) - if (item.getType().getMaxDurability() <= 0) continue; + String type = inv.getType().name(); + if (!(type.contains("CHEST") || type.contains("BARREL") || type.contains("SHULKER_BOX"))) return; - ItemMeta meta = item.getItemMeta(); - if (meta == null) continue; - // Prüfe, ob das Item bereits eine Seltenheit hat - if (meta.getPersistentDataContainer().has( - ItemUtil.getRarityKey(), PersistentDataType.INTEGER)) continue; + // Verzögere die Verarbeitung um 1 Tick, damit der Loot generiert wurde + Bukkit.getScheduler().runTaskLater(plugin, () -> { + for (ItemStack item : inv.getContents()) { + if (item == null) continue; + if (!ALLOWED.contains(item.getType())) continue; - // Rarity für Kisten-Loot: -1 bis 5 - int rarityValue = random.nextInt(7) - 1; // -1 bis 5 - if (rarityValue > 5) rarityValue = 5; - if (rarityValue < -1) rarityValue = -1; + ItemMeta meta = item.getItemMeta(); + if (meta == null) continue; + if (meta.getPersistentDataContainer().has(ItemUtil.getRarityKey(), PersistentDataType.INTEGER)) continue; - Rarity rarity = Rarity.fromValue(rarityValue); - ItemUtil.setRarity(item, rarity); - ItemUtil.assignUniqueId(item); - } + // Rarity für Kisten-Loot: -1 bis 5 + int rarityValue = random.nextInt(7) - 1; // -1 bis 5 + if (rarityValue > 5) rarityValue = 5; + if (rarityValue < -1) rarityValue = -1; + + Rarity rarity = Rarity.fromValue(rarityValue); + ItemUtil.setRarity(item, rarity); + ItemUtil.assignUniqueId(item); + item.setItemMeta(item.getItemMeta()); + } + }, 1L); // 1 Tick Verzögerung } } diff --git a/src/main/java/com/simolzimol/levelcraft/listener/VillagerTradeListener.java b/src/main/java/com/simolzimol/levelcraft/listener/VillagerTradeListener.java new file mode 100644 index 0000000..ecc4d65 --- /dev/null +++ b/src/main/java/com/simolzimol/levelcraft/listener/VillagerTradeListener.java @@ -0,0 +1,53 @@ +package com.simolzimol.levelcraft.listener; + +import com.simolzimol.levelcraft.item.ItemUtil; +import com.simolzimol.levelcraft.item.Rarity; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.InventoryOpenEvent; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.MerchantInventory; +import org.bukkit.inventory.MerchantRecipe; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.persistence.PersistentDataType; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +public class VillagerTradeListener implements Listener { + private final Random random = new Random(); + + @EventHandler + public void onVillagerTradeOpen(InventoryOpenEvent event) { + Inventory inv = event.getInventory(); + if (!(inv instanceof MerchantInventory merchantInventory)) return; + + // Neue Rezeptliste + List newRecipes = new ArrayList<>(); + for (MerchantRecipe recipe : merchantInventory.getMerchant().getRecipes()) { + ItemStack result = recipe.getResult().clone(); + ItemMeta meta = result.getItemMeta(); + if (meta != null && !meta.getPersistentDataContainer().has(ItemUtil.getRarityKey(), PersistentDataType.INTEGER)) { + // Nur Items mit Haltbarkeit (Waffen, Rüstung, Werkzeuge) + if (result.getType().getMaxDurability() > 0) { + int rarityValue = random.nextInt(7) - 1; // -1 bis 5 + if (rarityValue > 5) rarityValue = 5; + if (rarityValue < -1) rarityValue = -1; + Rarity rarity = Rarity.fromValue(rarityValue); + ItemUtil.setRarity(result, rarity); + ItemUtil.assignUniqueId(result); + } + } + // Neues Rezept mit gleichem Input, aber modifiziertem Output + MerchantRecipe newRecipe = new MerchantRecipe(result, recipe.getMaxUses()); + newRecipe.setIngredients(recipe.getIngredients()); + newRecipe.setExperienceReward(recipe.hasExperienceReward()); + newRecipe.setVillagerExperience(recipe.getVillagerExperience()); + newRecipe.setPriceMultiplier(recipe.getPriceMultiplier()); + newRecipes.add(newRecipe); + } + merchantInventory.getMerchant().setRecipes(newRecipes); + } +}