Загрузка...

Создание плагина на кастомного моба 1.17.1

Тема в разделе Серверы Minecraft создана пользователем erioxis 27 июл 2021. 1532 просмотра

Загрузка...
  1. erioxis
    erioxis Автор темы 27 июл 2021 Заблокирован(а) 4 9 мар 2020
    В этой теме я расскажу, как создать своего моба с помощью плагина
    На русском языке не видел гайды по этому

    Использовать буду ядро paper
    Оно использует плагины spigot, поэтому скачиваем еще spigot для создания плагина
    Не буду рассказывать основные вещи о создании плагинов и Java, думаю этой информации в интернете много

    Так начнем
    Для начало создаем пустой плагин или заходим уже в готовый
    Создаем класс для кастомного моба
    Например я буду делать зомби, который при смерти будет взрываться
    Делаю класс ExplosiveZombie.java
    Далее, нужно наследовать наш класс от класса моба, на основе которого будем делать моба, я возьму зомби
    public class ExplosiveZombie extends EntityZombie

    Классы сущностей обычно начинаются на Entity, поэтому можете написать Entity и там автозавершением кода смотреть, что там имеется
    Не забываем испортировать, то что нам нужно, например для зомби я импортировал его класс
    import net.minecraft.world.entity.monster.EntityZombie;


    Далее, начнем делать моба
    Сначала создадим конструктор для моба, с аргументов локации
    public ExplosiveZombie(Location loc)

    И прописываем конструктор зомби
    super(EntityTypes.be, ((CraftWorld) loc.getWorld()).getHandle());

    Тут при спавне зомби мы передаем в его конструктор тип и мир, EntityType.be - это тип сущности 'зомби'

    Теперь, будем делать самого моба
    this.setPosition(loc.getX(), loc.getY(), loc.getZ());

    В этой строке, при спавне устанавливаю ему позицию ту, что в получаем в аргументах конструктора

    Хочу, чтобы все взрывные зомби были мелкими
    this.setBaby(true);

    С помощью этой функции мы можем делать зомби либо мелким, либо взрослым

    Далее я хочу, чтобы над зомби было имя
    Сначало включаю его отображение
    this.setCustomNameVisible(true);

    И прописываю само имя
    Но, с обычным ентити зомби не получится это сделать
    Поэтому я должен получить класс зомби из ядра Bukkit, в этом api уже есть готовые функции под наши задачи
    Делаю переменную нашего моба типа CraftZombie и прописываю в ней функцию getBukkitEntity(), она получает сущность Bukkit из сущности из обычного майна
    CraftZombie cz = (CraftZombie) this.getBukkitEntity();


    Всё, теперь у нас есть сущность зомби из Bukkit

    cz.setCustomName("Explosive zombie");

    Здесь мы устанавливаем мобу имя

    Далее мне бы хотелось изменить ему хп
    Раньше можно было просто прописать setMaxHealth, но эту функцию убрали и теперь нужно менять макс хп с помощью атрибута
    Что такое атрибут?
    Атрибут это некая характеристика моба, например хп - это атрибут, и тд

    Для того чтобы изменить атрибут, мы сначала должны получить его, и потом менять
    cz.getAttribute(Attribute.GENERIC_MAX_HEALTH).setBaseValue(2);

    В этой строке я получил атрибут макс хп, и с помощтю setBaseValue поменял его
    Далее мы должны поменять не макс хп а просто хп, но по идеи оно должно само опустится, так как мы уменьшили макс значение
    Но на всякий я сам поставлю ему хп
    cz.setHealth(2);


    Далее, я бы хотел чтобы у нашего зомби был тнт на голове и паутинка в руках (типа это фитиль будет)

    Для начала мы должны создать сами предметы
    Делаются они с помощью ItemStack

    Создаем тнт
    ItemStack tnt = new ItemStack(Material.TNT);

    И паутинку
    ItemStack web = new ItemStack(Material.STRING);


    В Material прописаны все предметы, существующие в игре

    Далее, мы должны дать зомби эти предметы, как это сделать?
    Для начала мы должны получить инвентарь зомби, а точнее его снаряжение

    Делается это таким образом
    EntityEquipment zombieInv = cz.getEquipment();

    Теперь в этой переменной мы храним его предметы, броню и тд

    Теперь даем ему наши предметы

    Функция setItemInMainHand устанавливает предмет в левой руке
    А функция setHelmet надевает предмет на голову
    И да, вы можете на голову надеть на голову всё что угодно, даже кровать

    Вот код, выдачи ему предметов
    Код
    zombieInv.setHelmet(tnt);
    zombieInv.setItemInMainHand(web);
    [IMG]
    Строку с ScoreBoard разберем в конце

    Всё, у нас есть зомби со своим именем, снаряжением, атрибутами
    Но, я хочу сделать взрывного зомби, это сделаю я в конце, а для начала сделаем спавн моба

    Создаем слушатель 'EntitySpawnEvent'
    Этот эвент вызывается при спавне любой сущности

    Вот код спавна нашего моба, который я объясню вам
    Код
    public class SpawnEntity implements Listener{
    @EventHandler
    public void onSpawn(EntitySpawnEvent event)
    {
    boolean isSpawning = Bukkit.getPluginManager().getPlugin("ErioxisStuff").getConfig().getBoolean("isSpawning");
    if (isSpawning)
    {
    if (event.getEntity() instanceof Zombie)
    {
    if ((int) (Math.random() * 10) == 1)
    {
    event.setCancelled(true);

    ExplosiveZombie ezombie = new ExplosiveZombie(event.getLocation());

    WorldServer world = ((CraftWorld)event.getLocation().getWorld()).getHandle();
    world.addEntity(ezombie);

    Bukkit.getLogger().info(ezombie.getCustomName() + "spawned");
    return;
    }
    }
    }
    else
    {
    return;
    }
    }
    }


    И так
    Можете пропустить строки isSpawning, это я сделал для удобства, чтобы мог вкл и выкл спавн в конфиге

    Для начала я проверил зомби ли это
    if (event.getEntity() instanceof Zombie)

    Так как хочу, чтобы при спавне зомби он с шансом 10% заменился на взрывного

    if ((int) (Math.random() * 10) == 1)

    Тут чисто Java, просто шанс 10%

    Далее, если этот шанс выпадет, то отменяем эвент
    event.setCancelled(true);

    При отмене эвента с спавном, сущность не заспавнится

    Далее создаем переменную с нашим мобом
    ExplosiveZombie ezombie = new ExplosiveZombie(event.getLocation());


    У нас есть моб, но его еще не существует в мире, и мы его заспавним
    Код
    WorldServer world = ((CraftWorld)event.getLocation().getWorld()).getHandle();
    world.addEntity(ezombie);
    Тут, мы получили мир, где произошел эвент
    И в мире вызвали функцию addEntity, которая и создала сущность

    Далее для тестов, я выводил инфу
    Bukkit.getLogger().info(ezombie.getCustomName() + "spawned");


    И так, наш моб спавнится
    Но, он не взрывается, а я хочу чтобы после смерти он взрывался
    Как это сделать
    Я это сделал таким образом
    В игре есть ScoreBoard'ы там хранится разная информация, их часто юзают в режимах для вывода очков команды и тд
    У зомби я создал ScoreBoard
    И добавил туда тег 'explosivezombie'
    cz.addScoreboardTag("explosivezombie");


    Позже поймете зачем это

    Создаем новый слушатель эвентов, я для него сделал отдельный класс ExplosiveZombieEvents
    Там делаем слушатель 'EntityDeathEvent'
    Он вызывается при смерти сущности

    Далее
    Получаем того кто помер
    Entity e = event.getEntity();


    Получаем теги, думаю вы уже догадываетесь, что мы будем делать
    Set<String> etags = e.getScoreboardTags();


    Теперь перебираем его теги
    for (String tag : etags)


    Проверяем является ли этот тег тегом 'explosivezombie'
    if (tag == "explosivezombie")


    Всё, теперь при смерти взрывного зомби, игра слушатель поймет что это он

    Далее, дело за малым
    Осталось сделать взрыв
    event.getEntity().getWorld().createExplosion(event.getEntity().getLocation(), 1.0F);

    В этой длинной строке (которую мы можете сократить созданием новых переменных) я получил мир, где помер взрывной зомби, и создал там взрыв силой 1, в позиции смерти сущности
    Вы можете, задать любую силу взрыва, я выбрал наугад, 1 это очень мало, просто пукm который даже блоки не сломает

    Далее, для красоты я сделал частицы пламени при ударе по взрывному зомби
    Код
        @EventHandler
    public void onDamage(EntityDamageEvent event)
    {
    Entity e = event.getEntity();
    Set<String> etags = e.getScoreboardTags();
    Bukkit.getLogger().info(etags.toString());
    for (String tag : etags)
    {
    if (tag == "explosivezombie")
    {
    Location loc = e.getLocation();
    e.getWorld().spawnParticle(Particle.FLAME, loc.getX(), loc.getY(), loc.getZ(), 3);
    }
    }
    }
    Этот код очень похож на прошлый, но тут другой эвент и спавн частиц

    Вот и всё
    У нас есть плагин добавляющий нового моба
    Теперь экспортируем и кидаем в папку с плагинами

    Если кто-то хочет могу кинуть исходник моего тест плагина, где есть этот зомби и еще морозный зомби
    На этом мой гайд окончен
     
  2. ITishnik
    ITishnik 29 июл 2021 Я ебал 67 28 мар 2019
    Нихуя не понял, но очень интересно:finger_up:
     
Top