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

Помогите Самописные зачарования

Тема в разделе "Разработка плагинов для новичков", создана пользователем TwentiethAutumn, 2 май 2019.

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

    TwentiethAutumn Новичок

    Баллы:
    6
    В процессе создания самописных зачарований столкнулся с небольшой проблемой. В основной программе происходит регистрация зачарования, но командой /enchant зачаровать не удается(пишет, что зачарование с таким ID отсутствует). При /reload'е же пишет, что зачарование с таким ID уже зарегистрировано. Обьясните, пожалуйста
    Upd1. Ошибок в консоли нет, Listener зачарования работает без ошибок. Так же можно выдать предмет с зачарованием.
    Upd2. Команда "/give 2dolboeba minecraft:diamond_sword 1 0 {ench:[{id:70,lvl:2}]}" тоже работает исправно (70 - id моего зачарования)
    Upd3. Если выдавать книгу, хранящую в себе зачарование, то стандартные зачарования работают корректно, а моим ничего нельзя зачаровать
    Upd4. Версия spigot'a - spigot-1.8.8-R0.1-SNAPSHOT-latest
    Код:
    package ru.Trash.main;
    
    import java.util.ArrayList;
    import java.util.logging.Logger;
    
    import org.bukkit.plugin.Plugin;
    import org.bukkit.plugin.PluginManager;
    import org.bukkit.plugin.java.JavaPlugin;
    
    import ru.Trash.enchantments.BackstabEnchantment;
    import ru.Trash.enchantments.EnchantmentTemplate;
    
    public class Main extends JavaPlugin{
        
        public static PluginManager pluginManager;
        public static Logger logger;
        public static Plugin plugin;
        
        public static BackstabEnchantment BACKSTAB;
        
        public static ArrayList<EnchantmentTemplate> enchantmentList;
        
        @Override
        public void onEnable()
        {
            logger = this.getLogger();
            pluginManager = this.getServer().getPluginManager();
            enchantmentList = new ArrayList<EnchantmentTemplate>();
            plugin = Main.getPlugin(Main.class);
            
            BACKSTAB = new BackstabEnchantment(70);
            //type enchantment init here
        }
    }
    
    
    Код:
    package ru.Trash.enchantments;
    
    import java.lang.reflect.Field;
    import java.util.Arrays;
    
    import org.bukkit.enchantments.Enchantment;
    import org.bukkit.enchantments.EnchantmentTarget;
    import org.bukkit.event.Listener;
    import org.*********ventory.ItemStack;
    
    import ru.Trash.main.Main;
    
    public class EnchantmentTemplate extends Enchantment {
    
        public EnchantmentTemplate(int id) {
            super(id);
            fix(this);
            // TODO Auto-generated constructor stub
        }
    
        @Override
        public boolean canEnchantItem(ItemStack arg0) {
            // TODO Auto-generated method stub
            return true;
        }
    
        @Override
        public boolean conflictsWith(Enchantment arg0) {
            // TODO Auto-generated method stub
            return false;
        }
    
        @Override
        public EnchantmentTarget getItemTarget() {
            // TODO Auto-generated method stub
            return null;
        }
    
        @Override
        public int getMaxLevel() {
            // TODO Auto-generated method stub
            return 0;
        }
    
        @Override
        public String getName() {
            // TODO Auto-generated method stub
            return null;
        }
    
        @Override
        public int getStartLevel() {
            // TODO Auto-generated method stub
            return 0;
        }
        
        public void setListener(Listener listener) {
            Main.pluginManager.registerEvents(listener, Main.plugin);
        }
        
        private void fix(EnchantmentTemplate ench) {
            try {
                Field f = Enchantment.class.getDeclaredField("acceptingNew");
                f.setAccessible(true);
                f.set(null, true);
                if(Arrays.asList(Enchantment.values()).contains(ench) == false){
                    Enchantment.registerEnchantment(ench);
                     Main.enchantmentList.add(this);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
    }
    
    Код:
    package ru.Trash.enchantments;
    
    import org.bukkit.enchantments.Enchantment;
    import org.bukkit.enchantments.EnchantmentTarget;
    import org.*********ventory.ItemStack;
    
    import ru.Trash.listeners.BackstabListener;
    
    public class BackstabEnchantment extends EnchantmentTemplate {
    
        public BackstabEnchantment(int id) {
            super(id);
            setListener(new BackstabListener());
            // TODO Auto-generated constructor stub
        }
        
        @Override
        public boolean canEnchantItem(ItemStack arg0) {
            // TODO Auto-generated method stub
            return true;
        }
    
        @Override
        public boolean conflictsWith(Enchantment arg0) {
            // TODO Auto-generated method stub
            return false;
        }
    
        @Override
        public EnchantmentTarget getItemTarget() {
            // TODO Auto-generated method stub
            return EnchantmentTarget.WEAPON;
        }
    
        @Override
        public int getMaxLevel() {
            // TODO Auto-generated method stub
            return 10;
        }
    
        @Override
        public String getName() {
            // TODO Auto-generated method stub
            return "Backstab";
        }
    
        @Override
        public int getStartLevel() {
            // TODO Auto-generated method stub
            return 0;
        }
        
        
    
    }
    
    Код:
    package ru.Trash.listeners;
    
    import org.bukkit.ChatColor;
    import org.bukkit.Material;
    import org.bukkit.entity.Entity;
    import org.bukkit.entity.Player;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.entity.EntityDamageByEntityEvent;
    import org.bukkit.event.player.PlayerJoinEvent;
    import org.*********ventory.ItemStack;
    
    import ru.Trash.main.Main;
    
    public class BackstabListener implements Listener {
        
        @EventHandler
        public void onPlayerJoin(PlayerJoinEvent event) {
            Main.logger.info("[BACKSTAB LISTENER] "+event.getPlayer().getName()+" HAS JOINED");
            ItemStack item = new ItemStack(Material.WOOD_SWORD);
            item.addEnchantment(Main.BACKSTAB, 1);
            event.getPlayer().getInventory().addItem(item);
            event.getPlayer().updateInventory();
        }
        
        @EventHandler
        public void onEntityDamageByEntityEvent(EntityDamageByEntityEvent event) {
            if(event.getDamager() instanceof Player) {
                Player p = (Player) event.getDamager();
                if(p.getItemInHand() != null && p.getItemInHand().getType() != Material.AIR) {
                    Entity e = event.getEntity();
                    if(p.getItemInHand().getItemMeta().hasEnchant(Main.BACKSTAB) && p.getLocation().getDirection().dot(e.getLocation().getDirection()) > 0) {
                        if(Math.random() <= 0.5){
                            e.sendMessage(ChatColor.RED + "[BACKSTAB LISTENER] Backstabbed");
                            p.sendMessage(ChatColor.GREEN + "[BACKSTAB LISTENER] Backstab");
                            event.setDamage(event.getDamage()*1.25);
                        }
                    }
                }
            }
        }
    }
    
     

    Вложения:

    • 1.png
      Размер файла:
      647,8 КБ
      Просмотров:
      15
    Последнее редактирование: 2 май 2019
  2. Dymeth

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

    Баллы:
    98
    Имя в Minecraft:
    Dymeth
    Если через гив всё выдаётся нормально - скорее всего, дело в команде энчант.
    Подозреваю, что она реализована каким-нибудь эссентиалсом. А в нем жёсткие списки материалов, энчантов и всего прочего.
    Короче говоря, для начала попробуй использовать /minecraft:enchant

    А по поводу ошибки, что энчант уже зареган - всегда проверяй перед регистрацией наличие зачарования. Если есть - ничего делать не потребуется
     
  3. Автор темы
    TwentiethAutumn

    TwentiethAutumn Новичок

    Баллы:
    6
    Проверка уже была, а /minecraft:enchant реагирует в точности так же, как и /enchant
    (There is no such enchantment with ID 70)

    Уже второй день пытаюсь решить данную проблему

    Upd1. Если выдавать книгу, хранящую в себе зачарование, то стандартные зачарования работают корректно, а моим ничего нельзя зачаровать
     

    Вложения:

    • 2.png
      Размер файла:
      350,1 КБ
      Просмотров:
      5
    Последнее редактирование: 2 май 2019
  4. alexandrage

    alexandrage Старожил Пользователь

    Баллы:
    173
    Код:
    package Example.stack;
    import java.lang.reflect.Field;
    import org.bukkit.NamespacedKey;
    import org.bukkit.enchantments.Enchantment;
    import org.bukkit.enchantments.EnchantmentTarget;
    import org.*********ventory.ItemStack;
    public class FaceEnchantment extends Enchantment {
        private NamespacedKey key;
        private int startLevel;
        private int maxLevel;
        public FaceEnchantment(NamespacedKey key, int startLevel, int maxLevel) {
            super(key);
            this.key = key;
            this.startLevel = startLevel;
            this.maxLevel = maxLevel;
            fix(this);
        }
        @Override
        public boolean canEnchantItem(ItemStack arg0) {
            return true;
        }
        @Override
        public boolean conflictsWith(Enchantment arg0) {
            return false;
        }
        @Override
        public EnchantmentTarget getItemTarget() {
            return null;
        }
        @Override
        public int getMaxLevel() {
            return maxLevel;
        }
        @Override
        public String getName() {
            return this.key.toString();
        }
        @Override
        public int getStartLevel() {
            return startLevel;
        }
        @Override
        public boolean isCursed() {
            return true;
        }
        @Override
        public boolean isTreasure() {
            return true;
        }
        private void fix(FaceEnchantment ench) {
            try {
                Field f = Enchantment.class.getDeclaredField("acceptingNew");
                f.setAccessible(true);
                f.set(null, true);
                Enchantment.registerEnchantment(ench);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    
     
    Последнее редактирование: 6 май 2019
  5. Автор темы
    TwentiethAutumn

    TwentiethAutumn Новичок

    Баллы:
    6
    Попробовал, не получилось. Проблема не решилась
    Upd1. Прикрепил вверху весь код
    Upd2. Помогите пожалуйста :c
     
    Последнее редактирование: 2 май 2019
  6. Energy warrior

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

    Баллы:
    76
    Это как?
     
  7. Автор темы
    TwentiethAutumn

    TwentiethAutumn Новичок

    Баллы:
    6
    /give 2dolboeba minecraft:enchanted_book {StoredEnchantments:[{id:70,lvl:2}]}
     
  8. Energy warrior

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

    Баллы:
    76
    А что хоть пишет то? Я чёт не догоняю как может не чариться?
     
  9. imDaniX

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

    Баллы:
    96
    Имя в Minecraft:
    imDaniX
    Быть может зачарование "отрезается", как если бы на одной книге были сила и острота - при зачаровании меча сила пропадет.
     
  10. Energy warrior

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

    Баллы:
    76
    У него зачар ни с чем не конфликтует.
     
  11. Автор темы
    TwentiethAutumn

    TwentiethAutumn Новичок

    Баллы:
    6
    Пишет, что зачарование на книге, но с помощью наковальни нельзя зачаровать ничего.
    Если таким же образом зачаровать на остроту, то можно зачаровать на наковальне
     
  12. Energy warrior

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

    Баллы:
    76
    Попробуй ловить ивент зачара, и если на предмете есть зачар, меняй ему лор на Backstrap II
     
  13. Автор темы
    TwentiethAutumn

    TwentiethAutumn Новичок

    Баллы:
    6
    Меня больше волнует то, что нельзя зачаровать командой /enchant .
    У меня уже был вариант, который работал с /enchant, но я не понял, почему команда перестала работать
     
  14. alexandrage

    alexandrage Старожил Пользователь

    Баллы:
    173
    Вот тебе решение для фейк чарок. Доделаешь там проверку, какие предметы можно чарить, какие нет.
    Код:
        @EventHandler
        public void on(InventoryClickEvent e) {
            Inventory inv = e.getClickedInventory();
            if (inv == null) {
                return;
            }
            if (inv instanceof AnvilInventory) {
                if (isFaceEnchantment(inv.getItem(2))) {
                    e.getWhoClicked().setItemOnCursor(inv.getItem(2));
                    inv.clear();
                    Player player = (Player) e.getWhoClicked();
                    player.playSound(player.getLocation(), Sound.BLOCK_ANVIL_USE, 1, 1);
                }
            }
        }
    
        @EventHandler
        public void on(PrepareAnvilEvent e) {
            ItemStack stack1 = e.getInventory().getItem(0);
            ItemStack stack2 = e.getInventory().getItem(1);
            if (isNull(stack1, stack2)) {
                return;
            }
            if (isFaceEnchantmentBook(stack2)) {
                ItemStack stack = stack1.clone();
                stack.addUnsafeEnchantments(stack2.getEnchantments());
                e.setResult(stack);
            }
        }
    
        public boolean isNull(ItemStack stack1, ItemStack stack2) {
            if (stack1 == null || stack2 == null) {
                return true;
            }
            return false;
        }
    
        public boolean isFaceEnchantmentBook(ItemStack stack2) {
            if (stack2.getType().equals(Material.ENCHANTED_BOOK)) {
                return isFaceEnchantment(stack2);
            }
            return false;
        }
    
        public boolean isFaceEnchantment(ItemStack stack) {
            if (stack == null) {
                return false;
            }
            Map<Enchantment, Integer> enchs = stack.getEnchantments();
            for (Entry<Enchantment, Integer> ench : enchs.entrySet()) {
                if (ench.getKey() instanceof FaceEnchantment) {
                    return true;
                }
            }
            return false;
        }
     
  15. Автор темы
    TwentiethAutumn

    TwentiethAutumn Новичок

    Баллы:
    6
    Хах, попробовал сделать, версия Spigot'a 1.9
    Выводил все зачарования, лежащие на книге в консоль. На картинке можно лицезреть, что при вложении в наковальню книги с кастомной чаркой вылетает "выход за границы", а при вложении остроты все происходит корректно

    Upd1. При смене ID зачарования с зачарованной книги "слетает" зачарование
    Upd2. С вами можно как-то связаться?
     

    Вложения:

    • 1.png
      Размер файла:
      647,8 КБ
      Просмотров:
      13
    Последнее редактирование: 5 май 2019
  16. Energy warrior

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

    Баллы:
    76
    Попробуй для начала перестать быть динозавром и перейти на версию повыше. И попробуй регистрировать не из листа а просто создать класс и всё.
     
  17. Автор темы
    TwentiethAutumn

    TwentiethAutumn Новичок

    Баллы:
    6
    Действительно не понимаю. Никаких ошибок, просто нельзя зачаровать на наковальне и все
     
  18. alexandrage

    alexandrage Старожил Пользователь

    Баллы:
    173
    Мой касяк, не там чарки с книги брал. Там с букметы идет.
     
  19. alexandrage

    alexandrage Старожил Пользователь

    Баллы:
    173
    Поправил.
    Код:
        @EventHandler
        public void on(PrepareAnvilEvent e) {
            AnvilInventory inv = e.getInventory();
            ItemStack stack1 = inv.getItem(0);
            ItemStack stack2 = inv.getItem(1);
            if (stack1!=null && isFaceEnchantmentBook(stack2)) {
                ItemStack stack = stack1.clone();
                EnchantmentStorageMeta meta = (EnchantmentStorageMeta) stack2.getItemMeta();
                stack.addUnsafeEnchantments(meta.getStoredEnchants());
                int cost = inv.getRepairCost();
                e.setResult(stack);
                if(cost==0) {
                    inv.setRepairCost(1);
                }
            }
            if (isFaceEnchantment(stack1)) {
                ItemStack result = e.getResult();
                if(result.getType().equals(Material.AIR)) {
                    return;
                }
                for (Entry<Enchantment, Integer> ench : stack1.getEnchantments().entrySet()) {
                    if (isFaceEnchantment(ench.getKey())) {
                        result.addUnsafeEnchantment(ench.getKey(), ench.getValue());
                    }
                }
            }
        }
    
        public boolean isFaceEnchantmentBook(ItemStack stack2) {
            if (stack2 == null) {
                return false;
            }
            if (stack2.getType().equals(Material.ENCHANTED_BOOK)) {
                EnchantmentStorageMeta meta = (EnchantmentStorageMeta) stack2.getItemMeta();
                Map<Enchantment, Integer> enchs = meta.getStoredEnchants();
                for (Entry<Enchantment, Integer> ench : enchs.entrySet()) {
                    if (ench.getKey() instanceof FaceEnchantment) {
                        return true;
                    }
                }
            }
            return false;
        }
    
        public boolean isFaceEnchantment(ItemStack stack) {
            if (stack == null) {
                return false;
            }
            Map<Enchantment, Integer> enchs = stack.getEnchantments();
            for (Entry<Enchantment, Integer> ench : enchs.entrySet()) {
                if (ench.getKey() instanceof FaceEnchantment) {
                    return true;
                }
            }
            return false;
        }
    
        public boolean isFaceEnchantment(Enchantment ench) {
            if (ench instanceof FaceEnchantment) {
                return true;
            }
            return false;
        }
     
    Последнее редактирование: 6 май 2019
  20. Автор темы
    TwentiethAutumn

    TwentiethAutumn Новичок

    Баллы:
    6
    Пк не потянет
    Спасибо, проблема решена
     

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