Войти или зарегистрироваться
  • Вы находитесь в сообществе Rubukkit. Мы - администраторы серверов Minecraft, разрабатываем собственные плагины и переводим на различные языки плагины наших коллег из других стран.

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

indew

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


Код:
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;
    }

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

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

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

Назад
Верх