В этой теме я расскажу, как создать своего моба с помощью плагина На русском языке не видел гайды по этому Использовать буду ядро 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); Код zombieInv.setHelmet(tnt); zombieInv.setItemInMainHand(web); Строку с 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; } } } Код 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); Код 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); } } } Код @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); } } } Этот код очень похож на прошлый, но тут другой эвент и спавн частиц Вот и всё У нас есть плагин добавляющий нового моба Теперь экспортируем и кидаем в папку с плагинами Если кто-то хочет могу кинуть исходник моего тест плагина, где есть этот зомби и еще морозный зомби На этом мой гайд окончен