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

В разработке Плагин на выпадение спавнеров с определенным шансом

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

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

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

    Баллы:
    76
    Всем привет, написал плагин на выпадение спавнеров игроку с определенным шансом. Задумка следующая: игрок может получит спавнер, если сломал его алмазной или незеритовой киркой с шелковым касанием. Также установлены разные шансы для игроков с разными привилегиями. Хотел бы получить что-то вроде код-ревью. Может недочеты по стилю кода или еще какие-нибудь ошибки есть.
    Ссылка на код: https://pastebin.com/F65zQUHg
     
  2. Dymeth

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

    Баллы:
    98
    Имя в Minecraft:
    Dymeth
    Подправил твой код, вот, что конкретно я сделал:
    • Переименовал метод слушателя из BlockBreakedEvent в onBlockBreakEvent. Методы в Java всегда стоит назвать с маленькой буквы, это негласное правило. Помимо этого, на момент вызова события блок ещё не сломан - ты можешь отменить это действие. Поэтому использование Break в прошедшем времени не совсем корректно

    • Убрал каст BlockBreakEvent.getPlayer() к Player. Этот метод уде возвращает игрока

    • Вынес в отдельные переменные блок и предмет в руке игрока:
      PHP:
      Block block event.getBlock();
      ItemStack itemInMainHand player.getInventory().getItemInMainHand();
      Строки стали гораздо короче, читабельность увеличилась, меньше дублирования кода

    • Заменил
      PHP:
      itemInMainHand.getEnchantments().containsKey(Enchantment.SILK_TOUCH)
      на
      PHP:
      itemInMainHand.containsEnchantment(Enchantment.SILK_TOUCH)
    • Вынес некоторые условия в отдельные булин-флаги: validItem и validEnchant, благодаря чему удалось реорганизовать условия с целью сделать весь метод более читабельными:
      PHP:
      if (validItem && validEnchant) {
          ...
      } else {
          ...
      }

    • Избавился от лесенок условий: инвертировал условия и применил return, где условие не соблюдено:
      PHP:
      if (event.getBlock().getType() != Material.SPAWNER) return;
    • Изменил систему проверки прав. Честно говоря, я вообще не понял, как работает текущая система. Есть 4 разных права:
      blockBreaked.shogun - дает шанс выпадения 30%
      blockBreaked.samurai - дает шанс выпадения 100%
      blockBreaked.tramp и blockBreaked.default - позволяют получать сообщения о нехватке прав

      Зачем для вывода сообщения о нехватке прав проверять ещё какие-то права? Мне показалось это странным, поэтому избавился от blockBreaked.tramp и blockBreaked.default вовсе

    • Поменял местами проверку права и генерацию шанса, т.к. это более логично и проще читается:
      PHP:
      if ((player.hasPermission("blockBreaked.shogun") && (random.nextDouble() < chanceShogun))) {
    • Избавился от дублирования кода выдачи предмета. Так и читабельней, и не будет проблем, если решишь добавить предмету какие-то новые параметры. Раньше можно было добавить в одном месте и забыть про второе. А если таких мест будет 10 - вероятность ошибки возрастает существенно.

    • Чуть позже заметил ещё одну проблему в коде - если у игрока есть необходимые права, но не отработал шанс выпадения, то игрок всё равно получит ошибку "У вас должна быть как минимум привилегия...".
      Чтобы это исправить - пришлось ещё немного изменить логику условий. Благодаря этому ещё и появилась возможность сообщить игроку о неудачном шансе (не)выпадения

    Конечный код выглядит так:
    PHP:
    @EventHandler
    public void onBlockBreakEvent(BlockBreakEvent event) {
        
    Block block event.getBlock();
        if (
    block.getType() != Material.SPAWNER) return;

        
    Player player event.getPlayer();
        
    ItemStack itemInMainHand player.getInventory().getItemInMainHand();

        
    boolean validItem itemInMainHand.getType() == Material.DIAMOND_PICKAXE
            
    || itemInMainHand.getType() == Material.NETHERITE_PICKAXE;

        
    boolean validEnchant itemInMainHand.containsEnchantment(Enchantment.SILK_TOUCH);

        if (!
    validItem || !validEnchant) {
            
    player.sendMessage("§c§lЧтобы получить спавнер, у вас должна быть алмазная или незеритовая кирка с шелковым касанием!");
            return;
        }

        
    boolean dropItem false;
        if ((
    player.hasPermission("blockBreaked.shogun"))) {
            if ((
    random.nextDouble() < chanceShogun)) {
                
    dropItem true;
            }
        } else if ((
    player.hasPermission("blockBreaked.samurai"))) {
            if ((
    random.nextDouble() < chanceSamurai)) {
                
    dropItem true;
            }
        } else {
            
    player.sendMessage("§c§lУ вас должна быть как минимум привилегия §fꑴ §c§l для выпадения спавнеров!");
            return;
        }

        if (!
    dropItem) {
            
    player.sendMessage("§c§lНе повезло, блок не выпал :(");
            return;
        }

        
    ItemStack spawner = new ItemStack(block.getType(), 1);
        
    Location blockLocation block.getLocation();
        
    block.getWorld().dropItemNaturally(blockLocationspawner);
    }

    Помимо этого, я бы рекомендовал тебе добавить пользователям плагина возможность создавать свои собственные группы и шансы для них. Практически со 100% вероятностью такая потребность будет у пользователей твоего плагина. Заодно получишь опыт работы с Map
     
    Последнее редактирование: 10 окт 2023
  3. Автор темы
    Albert228

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

    Баллы:
    76
    Спасибо большое) Вообще, это личный плагин, не планирую его в общий доступ закидывать, поэтому решил не делать возможность создавать группы
     
  4. Автор темы
    Albert228

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

    Баллы:
    76
    Кстати, а что такое Map?
     
  5. Dymeth

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

    Баллы:
    98
    Имя в Minecraft:
    Dymeth
    Карта значений, в других языках часто называют словарём. Фактически это таблица ключ-знаение.
    В твоём случае можно было бы сделать что-то типа ключ - название группы, а значение - шанс выпадения спаунера.
    В интернете полно информации про Map и конкретно HashMap в Java, думаю разберёшься )
     
  6. Автор темы
    Albert228

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

    Баллы:
    76
    Понял, благодарю
     

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