1. Вы находитесь в сообществе Rubukkit. Мы - администраторы серверов Minecraft, разрабатываем собственные плагины и переводим на различные языки плагины наших коллег из других стран.
    Скрыть объявление
Скрыть объявление
В преддверии глобального обновления, мы проводим исследования, которые помогут нам сделать опыт пользования форумом ещё удобнее. Помогите нам, примите участие!

Помогите Кастомные чары

Тема в разделе "Разработка плагинов для новичков", создана пользователем indew, 24 янв 2025.

  1. Автор темы
    indew

    indew Ньюби

    Баллы:
    1
    Имя в Minecraft:
    2whyI
    Уже второй день пишу плагин, с кастомными чарами, проблема заключается в том что, я выдаю себе книжку с кастомными чарами из своего плагина, и через наковальню пытаюсь прокачать кирку, естественно оно мне не дает это сделать, суть плагина заключается кирках 3x3 и т.д, основная главная проблема то что через наковальню не могу ни как, прокачать кирку своими кастомными чарами, прошу помогите, чтобы эти круги ада закончились, через nms так же пробовал нечего не получилось, если что версия 1.16.5 paper/purpur
     
  2. tnt15x15

    tnt15x15 Участник Пользователь

    Баллы:
    36
    Это ваш плагин? Есть пример кода
     
  3. Автор темы
    indew

    indew Ньюби

    Баллы:
    1
    Имя в Minecraft:
    2whyI
    Да мой плагин


    Код:
    package me.ttcenchantments;
    
    
    import com.sk89q.worldedit.bukkit.BukkitAdapter;
    import com.sk89q.worldguard.WorldGuard;
    import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
    import com.sk89q.worldguard.protection.flags.Flags;
    import com.sk89q.worldguard.protection.flags.StateFlag;
    import com.sk89q.worldguard.protection.regions.RegionQuery;
    import org.bukkit.*;
    import org.bukkit.block.Block;
    import org.bukkit.block.BlockFace;
    import org.bukkit.command.Command;
    import org.bukkit.command.CommandSender;
    import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftItemStack;
    import org.bukkit.enchantments.Enchantment;
    import org.bukkit.entity.Player;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.block.Action;
    import org.bukkit.event.block.BlockBreakEvent;
    import org.bukkit.event.inventory.InventoryClickEvent;
    import org.bukkit.event.inventory.PrepareAnvilEvent;
    import org.bukkit.event.player.PlayerInteractEvent;
    import org.bukkit.event.player.PlayerItemConsumeEvent;
    import org.*********ventory.AnvilInventory;
    import org.*********ventory.ItemStack;
    import org.*********ventory.meta.BookMeta;
    import org.*********ventory.meta.EnchantmentStorageMeta;
    import org.*********ventory.meta.ItemMeta;
    import org.*********ventory.meta.Repairable;
    import org.bukkit.persistence.PersistentDataContainer;
    import org.bukkit.persistence.PersistentDataType;
    import org.bukkit.plugin.java.JavaPlugin;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Random;
    
    
    public final class TTCEnchantments extends JavaPlugin implements Listener {
    
        private static TTCEnchantments instance;
    
        private static final NamespacedKey CUSTOM_ENCHANTMENT_KEY = new NamespacedKey("yourplugin", "custom_enchantment");
    
        List<AWaitBreak> aWaitBreaks;
    
        public TTCEnchantments() {
            this.aWaitBreaks = new ArrayList<>();
        }
    
        private WorldGuardPlugin worldGuard;
    
        @Override
        public void onEnable() {
            instance = this;
            // Регистрируем события
            Bukkit.getPluginManager().registerEvents(this, this);
    
            getCommand("addcustomenchantbook").setExecutor(this);
        }
    
        public static TTCEnchantments getInstance() {
            return instance;
        }
    
        public static void addCustomEnchantmentToBook(ItemStack book) {
            if (book.getType() == Material.ENCHANTED_BOOK) {
                ItemMeta meta = book.getItemMeta();
                if (meta instanceof BookMeta) {
                    BookMeta bookMeta = (BookMeta) meta;
                    PersistentDataContainer container = bookMeta.getPersistentDataContainer();
                    // Добавляем кастомную чары с помощью PersistentDataContainer
                    container.set(CUSTOM_ENCHANTMENT_KEY, PersistentDataType.STRING, "UskorennayaShakhta");
                    book.setItemMeta(bookMeta); // Обновляем книгу с кастомной чары
                }
            }
        }
    
        @Override
        public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
            if (sender instanceof Player) {
                Player player = (Player) sender;
    
                // Шаг 1: Создаем книгу
                ItemStack book = new ItemStack(org.bukkit.Material.ENCHANTED_BOOK);
    
                // Шаг 2: Получаем метаданные книги
                EnchantmentStorageMeta meta = (EnchantmentStorageMeta) book.getItemMeta();
    
                if (meta != null) {
                    
                    meta.addStoredEnchant(CustomEnchantments.USKORENNAYA_SHAKHTA, 5, true); 
    
                    // Шаг 4: Устанавливаем кастомное имя для книги
                    meta.setDisplayName("Книга с Ускоренной Шахтой");
    
                    // Применяем метаданные к книге
                    book.setItemMeta(meta);
    
                    // Шаг 5: Выдаем книгу игроку
                    player.getInventory().addItem(book);
    
                    // Сообщение игроку
                    player.sendMessage("Вам была выдана книга с кастомной чарой!");
                }
                return true;
            }
            return false;
        }
    
        @Override
        public void onDisable() {
            // Логика при выключении плагина
        }
    
        public boolean canBuild(Player p, Location l) {
            RegionQuery query = WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery();
            com.sk89q.worldedit.util.Location loc = BukkitAdapter.adapt(l);
            if (!hasBypass(p, l))
                return query.testState(loc, WorldGuardPlugin.inst().wrapPlayer(p), new StateFlag[] { Flags.BUILD });
            return true;
        }
    
        private boolean hasBypass(Player p, Location l) {
            return false;
        }
    
        @EventHandler
        public void onBreak(BlockBreakEvent event) {
            Player player = event.getPlayer();
            ItemStack item = event.getPlayer().getItemInHand();
            if (player == null)
                return;
    
            if (this.aWaitBreaks == null) {
                Bukkit.getLogger().warning("Список aWaitBreaks не инициализирован!");
                return;
            }
    
            AWaitBreak aWaitBreak = AWaitBreak.get(player, this.aWaitBreaks);
            if (aWaitBreak == null)
                return;
            ItemStack itemInHand = player.getItemInHand();
            if (itemInHand == null)
                return;
            List<Block> blocks = getBlocks(aWaitBreak);
            int silkTouch = itemInHand.getEnchantmentLevel(Enchantment.SILK_TOUCH);
            int fortune = itemInHand.getEnchantmentLevel(Enchantment.LOOT_BONUS_BLOCKS);
            int durability = itemInHand.getEnchantmentLevel(Enchantment.DURABILITY);
            Random random = new Random();
            boolean isBroken = false;
            this.aWaitBreaks.remove(aWaitBreak);
            if (player.getFoodLevel() == 0)
                return;
            for (Block block : blocks) {
                if (player.getItemInHand().getType() == Material.DIAMOND_PICKAXE) {
                    if (!CustomEnchantment.hasCustomEnchantment(itemInHand))
                        return;
                    if (CustomEnchantment.hasCustomEnchantment(itemInHand)) {
                        if (!player.isOp() &&
                                !canBuild(player, event.getBlock().getLocation()))
                            return;
                        if (random.nextInt(100) < 100 / (1 + durability))
                            itemInHand.setDurability((short)(itemInHand.getDurability() + 1));
                        for (ItemStack is : getDrops((List<ItemStack>)block.getDrops(itemInHand), block, silkTouch, fortune))
                            player.getWorld().dropItemNaturally(block.getLocation(), is);
                        if (itemInHand.getDurability() >= itemInHand.getType().getMaxDurability()) {
                            isBroken = true;
                            player.getInventory().removeItem(new ItemStack[] { itemInHand });
                            break;
                        }
                        if (player.getGameMode() == GameMode.SURVIVAL) {
                            player.setExhaustion(player.getExhaustion() + 0.025F);
                            if (player.getExhaustion() >= 4.0F) {
                                if (player.getSaturation() >= 1.0F) {
                                    player.setSaturation(player.getSaturation() - 1.0F);
                                } else {
                                    player.setFoodLevel(player.getFoodLevel() - 1);
                                }
                                player.setExhaustion(0.0F);
                            }
                        }
                        block.setType(Material.AIR);
                    }
                    if (!isBroken)
                        player.setItemInHand(itemInHand);
                }
            }
        }
    
        @EventHandler
        public void onInteract(PlayerInteractEvent event) {
            if (aWaitBreaks == null) {
                aWaitBreaks = new ArrayList<>(); // Инициализация, если ещё не инициализировано
            }
            Player player = event.getPlayer();
            if (player == null)
                return;
            AWaitBreak aWaitBreak = AWaitBreak.get(player, this.aWaitBreaks);
            if (aWaitBreak != null)
                this.aWaitBreaks.remove(aWaitBreak);
            if (event.getAction() == Action.LEFT_CLICK_BLOCK)
                this.aWaitBreaks.add(new AWaitBreak(player, event.getClickedBlock(), event.getBlockFace()));
        }
    
        public List<Block> getBlocks(AWaitBreak aWaitBreak) {
            if (aWaitBreak.face == BlockFace.DOWN || aWaitBreak.face == BlockFace.UP)
                return getBlocks(aWaitBreak, 1, 0, 1);
            if (aWaitBreak.face == BlockFace.EAST || aWaitBreak.face == BlockFace.WEST)
                return getBlocks(aWaitBreak, 0, 1, 1);
            return getBlocks(aWaitBreak, 1, 1, 0);
        }
    
        public List<Block> getBlocks(AWaitBreak aWaitBreak, int x, int y, int z) {
            List<Block> blocks = new ArrayList<>();
            World world = aWaitBreak.player.getWorld();
            int bX = aWaitBreak.block.getX();
            int bY = aWaitBreak.block.getY();
            int bZ = aWaitBreak.block.getZ();
            for (int cX = -x; cX <= x; cX++) {
                for (int cY = -y; cY <= y; cY++) {
                    for (int cZ = -z; cZ <= z; cZ++) {
                        Block block = world.getBlockAt(bX + cX, bY + cY, bZ + cZ);
                        if (aWaitBreak.block != block &&
                                block.getType() != Material.AIR)
                            blocks.add(block);
                    }
                }
            }
            return blocks;
        }
    
        public static ItemStack getDrops(ItemStack naturally, Block block, int silk, int fortune) {
            if (silk == 1) {
                naturally.setAmount(1);
                if (block.getType() == Material.LEGACY_GLOWING_REDSTONE_ORE) {
                    naturally.setType(Material.REDSTONE_ORE);
                } else {
                    naturally.setType(block.getType());
                }
            } else {
                int chanceToExtra = 100 / (2 + fortune);
                Random random = new Random();
                if (block.getType() == Material.GLOWSTONE && fortune > 0) {
                    naturally.setAmount(4);
                } else if (block.getType() == Material.GRAVEL) {
                    if (fortune == 0) {
                        chanceToExtra = 10;
                    } else if (fortune == 1) {
                        chanceToExtra = 14;
                    } else if (fortune == 2) {
                        chanceToExtra = 25;
                    } else {
                        chanceToExtra = 100;
                    }
                    if (random.nextInt(100) < chanceToExtra) {
                        naturally.setType(Material.FLINT);
                    } else {
                        naturally.setType(Material.GRAVEL);
                    }
                    naturally.setAmount(1);
                } else {
                    int multiplier = 1;
                    for (int i = 1; i <= fortune + 1; i++) {
                        if (random.nextInt(100) < chanceToExtra)
                            multiplier = i;
                    }
                    naturally.setAmount(naturally.getAmount() * multiplier);
                }
            }
            return naturally;
        }
    
        public static List<ItemStack> getDrops(List<ItemStack> naturally, Block block, int silk, int fortune) {
            List<ItemStack> list = new ArrayList<>();
            if (silk == 1) {
                list.add(getDrops(naturally.get(0), block, silk, fortune));
            } else {
                for (ItemStack is : naturally)
                    list.add(getDrops(is, block, silk, fortune));
            }
            return list;
        }
    
    }
    
     
  4. Автор темы
    indew

    indew Ньюби

    Баллы:
    1
    Имя в Minecraft:
    2whyI
    javaw_FkbaZqv6MT.png
     
  5. tnt15x15

    tnt15x15 Участник Пользователь

    Баллы:
    36
    Не могу выяснить причину
     
  6. H4kt

    H4kt Активный участник Пользователь

    Баллы:
    61
    Имя в Minecraft:
    H4kt
    Скорее всего проблема в том, что твое зачарование не зарегистрировано в реестре.
    На старых версиях были костыльные способы регистрации через рефлексию, однако не уверен что они все еще работают.
    На более новых версиях у Paper появился способ взаимодействия с реестрами, однако работает он только для Paper палигнов.

    Используя paper плагин и мутацию реестра зачарование начинает работать как должно.
    Реализацию можно посмотреть тут.
    Screenshot 2025-02-02 at 6.15.34 PM.jpg
     
    Последнее редактирование: 2 фев 2025

Поделиться этой страницей