Создание своего моба

Создание своего моба

Нет прав для скачивания
Версия(и) Minecraft
1.12.2
Первым делом создадим главный класс мода(если не создали):
Java:
@Mod(modid = Main.ID, name = Main.NAME, version = Main.VERSION, acceptedMinecraftVersions = Main.MC_VERSION)
public class Main {

    public static final String ID = "tutorial";
    public static final String NAME = "Tutorial";
    public static final String VERSION = "0.1";
    public static final String MC_VERSION = "[1.12.2]";

    //Прокси
    @SidedProxy(clientSide = "com.zarak.tutorial.ClientProxy", serverSide = "com.zarak.tutorial.CommonProxy")
    public static CommonProxy proxy;

    //Объёкт мода
    @Mod.Instance(ID)
    public static Main instance;

    @Mod.EventHandler
    public void preInit(FMLPreInitializationEvent event)
    {
        // Преинициализация
        proxy.preInit(event);
    }

    @Mod.EventHandler
    public void init(FMLInitializationEvent event)
    {
        // Инициализация
        proxy.init(event);
    }

    @Mod.EventHandler
    public void postInit(FMLPostInitializationEvent event)
    {
        // Инициализация
        proxy.postInit(event);
    }
}
Дальше прокси:
Java:
public class CommonProxy {

    public void preInit(FMLPreInitializationEvent event)
    {

    }

    public void init(FMLInitializationEvent event)
    {

    }

    public void postInit(FMLPostInitializationEvent event) {

    }
}
Java:
public class ClientProxy extends CommonProxy {
    @Override
    public void preInit(FMLPreInitializationEvent event) {
        super.preInit(event);
    }

    @Override
    public void init(FMLInitializationEvent event) {
        super.init(event);
        EntityRegistry.initModels();
    }

    @Override
    public void postInit(FMLPostInitializationEvent event) {
        super.postInit(event);
    }
}
И наконец-то самое интересное - МОБ!
Унаследуем его от EntityMob(к таким относятся Зомби, Скелет, Крипер и тд.)
Я планирую создать жалкое подобие Херобрина, который дамажит на рандомный урон:
Java:
public class EntitySmallHerobrine extends EntityMob {
    //Наш доп. урон(ниже о нём)
    public static int ADD_DAMAGE = 15;

    /*Конструктор*/
    public EntitySmallHerobrine(World world) {
        super(world);
        setSize(0.6F, 1.98F);//Размер моба
    }

    /*Конструктор с установкой позиции*/
    public EntitySmallHerobrine(World world, double x, double y, double z) {
        super(world);
    setSize(0.6F, 1.98F);//Размер моба
        setPositionAndUpdate(x, y, z);
    }

    @Override
    protected void applyEntityAttributes() {
        /*Строчка ниже нужна для регистрации атрибутов(Макс. ХП, скорость, сила атаки, броня, скорость полёта и тд.)*/
        super.applyEntityAttributes();
        //Устанавливаем атрибуты
        this.getEntityAttribute(SharedMonsterAttributes.FOLLOW_RANGE).setBaseValue(35.0D);//Радиус слежки = 35 блоков
        this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.5D);//Скорость моба(для примера: скорось Зомби = 0.23D)
        this.getEntityAttribute(SharedMonsterAttributes.ATTACK_DAMAGE).setBaseValue(3.0D);//Урон существа = 1.5 сердечка(у сердечко = 2D)
        this.getEntityAttribute(SharedMonsterAttributes.ARMOR).setBaseValue(2.0D);//Броня моба(от неё зависит урон по мобу)
        this.getEntityAttribute(SharedMonsterAttributes.ARMOR_TOUGHNESS).setBaseValue(2.0D);//Отбрасивание моба(больше число меньше отбрасование)
    }

    @Override
    protected void initEntityAI() {
        /*Делаем интелект мобу
         * 1 параметр - приоритет
         * 2 параметр - дочерный класс от EntityAIBase
         */
        this.tasks.addTask(0, new EntityAISwimming(this));//Плавает ли моб
        this.tasks.addTask(1, new EntityAIAttackMelee(this, 1.0D, false));//Атака ближнего боя
        this.tasks.addTask(2, new EntityAIWander(this, 1.0D));//Моб путешествует
        this.tasks.addTask(3, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F));//Смотрит на EntityPlayer(игрок)
        this.tasks.addTask(4, new EntityAILookIdle(this));//Грубо говоря - ленивое поварачивание головы
        this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, true, new Class[]{EntityZombie.class, EntityPlayer.class}));//Охота за такими мобами: EntityZombie, EntityPlayer
    }

    @Override
    public boolean attackEntityAsMob(Entity entityIn) {
        /*Что происходит при атаке*/
        if (super.attackEntityAsMob(entityIn)) {//Проверка на атаку
            if (entityIn instanceof EntityLivingBase) {//Если это моб
                ((EntityLivingBase) entityIn).attackEntityAsMob(this);//Делаем последним ударившим нашего моба
                entityIn.attackEntityFrom(((EntityLivingBase) entityIn).getLastDamageSource(), rand.nextInt(ADD_DAMAGE));//Наносим доп. урон
            }
            return true;
        } else {
            return false;
        }
    }
    @Override
    public int getMaxSpawnedInChunk() {
        /*Сколько спавнится в чанке*/
        return 25;
    }
Такс, моб есть, но нужно же сделать рендер(использую модель игрока, текстура Херобрина):
Java:
public class RenderEntityHerobrine extends RenderLiving<EntitySmallHerobrine>{
    /*Расположение текстуры моба(создаём новую папку в текстурах, имя её entity, туда и кладём наши текстуры)*/
    private ResourceLocation mobTexture = new ResourceLocation(Main.ID+ ":textures/entity/skin_herobrine.png");

    /*
    Конструктор рендера,
    теперь о super:
        1 параметр - наш RenderManager,
        2 параметр - наша модель,
        3 параметр - размер тени(стандартно 0.5F)
    */
    public RenderEntityHerobrine(RenderManager manager) {
        super(manager, new ModelBiped(), 0.5F);
    }
    public static Factory FACTORY = new Factory();
    @Override
    @Nonnull
    protected ResourceLocation getEntityTexture(@Nonnull EntitySmallHerobrine entity) {
        /*Возвращаем текстуру моба*/
        return mobTexture;
    }
    /*--------->НАШ РЕНДЕР ФЭКТОРИ <---------*/
    public static class Factory implements IRenderFactory<EntitySmallHerobrine> {
        @Override
        public Render<? super EntitySmallHerobrine> createRenderFor(RenderManager manager) {
        /*И наконец-то из всего этого создаём рендер*/
            return new RenderEntityHerobrine(manager);
        }
    }
Осталась регистрация моба и рендера, для регистрации моба используем новый эвент RegistryEvent.Register<EntityEntry>
Но сначала надо создать EntityEntry, для этого используем
EntityEntryBuilder:

Java:
private static int ID = 0;//Для айди
public static EntityEntry SMALL_HEROBRINE = EntityEntryBuilder
        .create()//Создаём новый EntityEntry
        .entity(EntitySmallHerobrine.class)//Какой моб в EntityEntry
        .name("Small Herobrine")//Имя
        .id("small_herobrine", ID++)//Айди и имя регистрации
        .egg(0xff4040, 0xd891ef)//Цвет яйца, первое значение - фона, второе - "точек"(можно не добавлять)
        .tracker(64, 20, false)//Трекер моба(Первое значение - радиус для которого моб будет обновлятся, второе - частота обновлений за секунду, третье - будет ли отправляться пакет с обновление позиции игрокам)
        .build();//Устанавливаем параметры

И собственно сама регистрация:
Java:
    @SubscribeEvent
    public static void registryEntity(RegistryEvent.Register<EntityEntry> event) {
       /*Новая регистрация от форджа*/
        event.getRegistry().registerAll(
                SMALL_HEROBRINE
        );
    }
Теперь, если зайти в игру, и создать энтити, то увидим белый, ходячий куб, ведь рендер то мы не зарегистрировали!
Давайте исправим:
Java:
 @SideOnly(Side.CLIENT)//Только клиент
    public static void initModels() {
        /*Регистрируем рендер, 1 параметр = класс моба, 2 параметр = НАШ РЕНДЕР ФЭКТОРИ */
        RenderingRegistry.registerEntityRenderingHandler(EntitySmallHerobrine.class, RenderEntityHerobrine.FACTORY);
}
"НАШ РЕНДЕР ФЭКТОРИ" это внутренний статичный класс в RenderEntityHerobrine
Также не забудьте зарегистрировать событие(я использую аннотацию @Mod.EventBusSubscriber(modid = Main.ID)
И класс целиком:
Java:
@Mod.EventBusSubscriber(modid = Main.ID)//ОБЕЗАТЕЛЬНО! <-------------
public class EntityRegistry {

    @SideOnly(Side.CLIENT)//Только клиент
    public static void initModels() {
        /*Регистрируем рендер, 1 параметр = класс моба, 2 параметр = НАШ РЕНДЕР ФЭКТОРИ */
        RenderingRegistry.registerEntityRenderingHandler(EntitySmallHerobrine.class, RenderEntityHerobrine.FACTORY);
    }

    private static int ID = 0;//Для айди

    public static EntityEntry SMALL_HEROBRINE = EntityEntryBuilder
            .create()//Создаём новый EntityEntry
            .entity(EntitySmallHerobrine.class)//Какой моб в EntityEntry
            .name("Small Herobrine")//Имя
            .id("small_herobrine", ID++)//Айди и имя регистрации
            .egg(0xff4040, 0xd891ef)//Цвет яйца, первое значени фон, второе "точки"
            .tracker(160, 2, false)//Трекер моба
            .build();//Устанавливаем параметры

    @SubscribeEvent
    public static void registryEntity(RegistryEvent.Register<EntityEntry> event) {
       /*Новая регистрация от форджа*/
        event.getRegistry().registerAll(
                SMALL_HEROBRINE
        );
    }
}
Закиньте текстуру в assets/<modid>/textures/entity
Устали? Могу вас порадовать, всё готово, можете заходить, увидите Вашего моба =)
Безымянный.png

(Советую посмотреть эти классы: EntityZombie, EntitySkeleton, EntityCreeper, EntityAIBase)
P.s. прошу указать на ошибки, задавать вопросы)
Автор
Зарак
Скачивания
24
Просмотры
26,486
Первый выпуск
Обновление
Оценка
4.67 звёзд 6 оценок

Последние рецензии

Так себе. Во с кастомной моделькой и скелетной анимацией было бы круче.
Если бы тутор был бы на 1.5.2-1.7.10 был бы бред. Но это 1.12 и я учёл что 1.12 хлам и лучше туда не лезть xD
В общем тутор годный, удачи в дальнейшем!
Ну мне всё нравится.
Сверху