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

Плагин [FUN] AnimatedItems v1.0 - Анимированные картинки как на HyPixel [1.7.9-R0.1]

serega6531

Старожил
Девелопер
Пользователь
Баллы
173
AnimatedItems - Анимированные картинки как на HyPixel
Версия: 1.0

Этот плагин позволяет создать анимированные картинки при наведении на предмет. Анимация берётся из gif файла, лежащего в папке плагина, скорость настраивается в конфиге. Рекомендуемый размер изображения: 16x16 пикселей.

Переменные конфига:
  1. speed - long переменная. Задает время до смены картинки в тиках. (В секунде 20 тиков).
  2. slot - слот, в который выдаётся предмет при входе (панель снизу экрана - 1-8).
  3. title - название предмета.
  4. lore - текст над картинкой
  5. name - имя файла без .gif в конце.
  6. command - команда, которая должна выполняться при клике на предмет
Демонстрационное видео:

Скачать плагин

Особенности:
  • Анимированные картинки в описании предмета
  • Кастомные названия
  • Изменяемая скорость
Чейнджлог:
  1. Релиз плагина
  2. Добавил настройку названия предмета, текста перед картинкой. Добавил изменение слота предмета.
  3. Добавил возможность ставить команду на предмет.
 
Последнее редактирование:
Исходный код:
Код:
package ru.serega6531.AnimatedItems;

import ...

public class AnimatedItems extends JavaPlugin implements Listener {

    List<String>[] frames;
    int frame, slot;
    long speed = 5;
    String name, lore, command;
  
    Color[] colors = {
            new Color(0, 0, 0),
            new Color(0, 0, 170),
            new Color(0, 170, 0),
            new Color(0, 170, 170),
            new Color(170, 0, 0),
            new Color(170, 0, 170),
            new Color(255, 170, 0),
            new Color(170, 170, 170),
            new Color(85, 85, 85),
            new Color(85, 85, 255),
            new Color(85, 255, 85),
            new Color(85, 255, 255),
            new Color(255, 85, 85),
            new Color(255, 85, 255),
            new Color(255, 255, 85),
            new Color(255, 255, 255)
        };
  
    @EventHandler
    public void onJoin(PlayerJoinEvent e){
        giveBook(e.getPlayer());
    }
  
    /*@EventHandler
    public void onDrop(PlayerDropItemEvent e){
        if(e.getItemDrop().getItemStack().getItemMeta().getLore().contains("⬛")) e.setCancelled(true);
    }*/
  
    @EventHandler
    public void onClickInventory(InventoryClickEvent e){
        if(e.getSlot() == slot && e.getCurrentItem().getType() == Material.BOOK && command != null) {
            Bukkit.dispatchCommand((CommandSender) e.getWhoClicked(), command);
            e.setCancelled(true);
        }
    }
  
    @EventHandler
    public void onClick(PlayerInteractEvent e){
        if(e.getMaterial() == Material.BOOK && e.getPlayer().getInventory().getHeldItemSlot() == slot && command != null){
            Bukkit.dispatchCommand(e.getPlayer(), command);
        }
    }
  
    private void giveBook(Player player){
        ItemStack item = new ItemStack(Material.BOOK);
        ItemMeta meta = item.getItemMeta();
        meta.setDisplayName(name);
        item.setItemMeta(meta);
        player.getInventory().setItem(slot, item);
    }
  
    private BufferedImage[] getGIFFrames(File gif) throws IOException {
        ImageReader reader = ImageIO.getImageReadersBySuffix("GIF").next();
        ImageInputStream in = ImageIO.createImageInputStream(gif);
        reader.setInput(in);
        BufferedImage[] images = new BufferedImage[reader.getNumImages(true)];
        for (int i = 0, count = reader.getNumImages(true); i < count; i++){
           images[i] = reader.read(i);
        }
        return images;
    }
  
    @SuppressWarnings("unchecked")
    public void onEnable() {
        getDataFolder().mkdirs();
        File file = new File(getDataFolder(), getConfig().getString("name", "image") + ".gif");
        speed = getConfig().getLong("speed", 5L);
        slot = getConfig().getInt("slot", 8);
        name = getConfig().getString("title", "Name of item");
        lore = getConfig().getString("lore", "Lore of item");
        command = getConfig().getString("command");
        if(!file.exists()){
            getLogger().warning("No " + file.getName() + " in plugin directory.");
            Bukkit.getPluginManager().disablePlugin(this);
            return;
        }
        Bukkit.getPluginManager().registerEvents(this, this);
        try {
            BufferedImage[] fr = getGIFFrames(file);
            frames = (List<String>[])new List[fr.length];
            for(int i = 0; i < fr.length; i++){
                frames[i] = frameAsStringList(fr[i]);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        Bukkit.getServer().getScheduler().scheduleSyncRepeatingTask(this, new Runnable() {
            @Override
            public void run() {
                for(Player player : Bukkit.getOnlinePlayers()){
                    ItemStack item = player.getInventory().getItem(slot);
                    if(item != null && Material.BOOK.equals(item.getType())){
                        ItemMeta meta = item.getItemMeta();
                        meta.setLore(frames[frame]);
                        item.setItemMeta(meta);
                        player.getInventory().setItem(slot, item);
                        if(frame < frames.length - 1) frame++; else frame = 0;
                    }
                }
            }
        }, 0L, speed);
    }
  
    private List<String> frameAsStringList(BufferedImage frame){
        List<String> result = new ArrayList<String>();
        result.add(lore);
        String string = "";
      
        for(int i = 0; i < frame.getWidth(); i++){
            for(int j = 0; j < frame.getHeight(); j++){
                string += colorToChatColor(new Color(frame.getRGB(j, i))) + "⬛";
            }
            result.add(string);
            string = "";
        }
      
        return result;
    }
  
    private ChatColor colorToChatColor(Color color){
        if(color.getAlpha() < 128) return ChatColor.WHITE;
      
        double fi, f_min=1000000;
        int i, index = 0;
      
        for(i = 0; i < colors.length; i++){
          fi = getDistance(color, colors[i]);
          if(fi < f_min){
            index = i;
            f_min = fi;
          }
       }

        return ChatColor.values()[index];
    }
  
    private double getDistance(Color c1, Color c2){
        int r, g, b;
      
        r = c2.getRed() - c1.getRed();
        g = c2.getGreen() - c1.getGreen();
        b = c2.getBlue() - c1.getBlue();
      
        return 30 * r * r + 59 * g * g +  11 * b * b;
    }
  
}
 
Последнее редактирование:
serega6531, вот за исходный код спасибо, порадовал <3
PS. Можешь какой-либо пример скинуть? Лень гифку найти ;D
 
serega6531, вот за исходный код спасибо, порадовал <3
PS. Можешь какой-либо пример скинуть? Лень гифку найти ;D
Завтра могу
serega6531, вот за исходный код спасибо, порадовал <3
PS. Можешь какой-либо пример скинуть? Лень гифку найти ;D
Вот, 3 рандомных favicon'а
 
Последнее редактирование:
Чёто на вид код говно какое-то, щас присмотрюсь внимательно и скажу что лучше поменять.
Первое что броилось в глаза это то строкам фрейма лучше храниться в LinkedList, а не ArrayList, хотя это не сильно принципиально, ибо всё равно фреймы загружаются в память один раз, но выглядит всё равно как говно. Да и лучше бы сами фреймы хранил в обычном массиве.
Плюс я так понимаю игроку сразу выдаётся книга в 5м слоте и она обновляется постоянно, не очень функционально получается.
 
Знаю, потом добавлю выбор слота и текст для lore.
Чёто на вид код говно какое-то, щас присмотрюсь внимательно и скажу что лучше поменять.
Первое что броилось в глаза это то строкам фрейма лучше храниться в LinkedList, а не ArrayList, хотя это не сильно принципиально, ибо всё равно фреймы загружаются в память один раз, но выглядит всё равно как говно. Да и лучше бы сами фреймы хранил в обычном массиве.
Плюс я так понимаю игроку сразу выдаётся книга в 5м слоте и она обновляется постоянно, не очень функционально получается.
А в чём преимущество LinkedList перед ArrayList?
 
Знаю, потом добавлю выбор слота и текст для lore.

А в чём преимущество LinkedList перед ArrayList?
Не тратишь память на пустые элементы, не наткнёшья на ресайзинг при добавлении элемента, не тратишь время на проверку пора ли ресайзится, быстрее итерация.
Впрочем в твоём случае важным пожалуй является то что элементы фрейма хранятся наиболее оптимально в таком случае и не более того. Хотя при малом количестве элементов надо ещё смотреть.

Кстати об итерации по фреймам, она сделана совершенно глупо, и ArrayList для списка фреймов совершенно не нужен, ибо ты знаешь количество фреймов заранее, благодаря чему можно сразу выделить массив нужного размера.
 
Не тратишь память на пустые элементы, не наткнёшья на ресайзинг при добавлении элемента, не тратишь время на проверку пора ли ресайзится, быстрее итерация.
Впрочем в твоём случае важным пожалуй является то что элементы фрейма хранятся наиболее оптимально в таком случае и не более того. Хотя при малом количестве элементов надо ещё смотреть.

Кстати об итерации по фреймам, она сделана совершенно глупо, и ArrayList для списка фреймов совершенно не нужен, ибо ты знаешь количество фреймов заранее, благодаря чему можно сразу выделить массив нужного размера.
Сделаю массив.
Залил новую версию по той же ссылке, обновил код. Нужен человек, который снимет видеодемонстрацию плагина.
@Shevchik, как вам работа с массивом? Что ещё поправить?
 
Lol, ради прикола написать плагин, чтобы другому показать, что это легко - в этом весь РБ:D
Кстати, вы можете записать демонстрационное видео для меня? У меня с этим будут проблемы.
 
Вряд ли, мне винду снова переустанавливать нужно, эта корявая:(
А мне такое не грозит:D
f53f251b2b0730f3425f79609cd80356.png
 
Не работает у меня, при запуске сервера создается только папка AnimatedItems, конфиги в ней не создаются, папка остается пустой. По команде /plugins плагин в списке не отображается. Spigot 1.7.9. Никаких ошибок в консоли не возникает
 
Не работает у меня, при запуске сервера создается только папка AnimatedItems, конфиги в ней не создаются, папка остается пустой. По команде /plugins плагин в списке не отображается. Spigot 1.7.9. Никаких ошибок в консоли не возникает
Возникает, смотрите внимательно.
No image.gif in plugin directory.
Можешь скриншоты выложить?
Плагина?
 
Есть возможность наложить команду на предмет?
Можно сделать плагин, проверяющий название и содержание lore, и тогда выполняющий команду.
Добавил демонстрационное видео. Спасибо @BeLkA за него.
 

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

Назад
Верх