- Версия(и) Minecraft
- 1.12.2
Первым делом создадим главный класс мода(если не создали):
Дальше прокси:
И наконец-то самое интересное - МОБ!
Унаследуем его от EntityMob(к таким относятся Зомби, Скелет, Крипер и тд.)
Я планирую создать жалкое подобие Херобрина, который дамажит на рандомный урон:
Такс, моб есть, но нужно же сделать рендер(использую модель игрока, текстура Херобрина):
Осталась регистрация моба и рендера, для регистрации моба используем новый эвент
Но сначала надо создать EntityEntry, для этого используем
И собственно сама регистрация:
Теперь, если зайти в игру, и создать энтити, то увидим белый, ходячий куб, ведь рендер то мы не зарегистрировали!
Давайте исправим:
"НАШ РЕНДЕР ФЭКТОРИ" это внутренний статичный класс в
Также не забудьте зарегистрировать событие(я использую аннотацию
И класс целиком:
Закиньте текстуру в
Устали? Могу вас порадовать, всё готово, можете заходить, увидите Вашего моба =)
(Советую посмотреть эти классы: EntityZombie, EntitySkeleton, EntityCreeper, EntityAIBase)
P.s. прошу указать на ошибки, задавать вопросы)
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
Устали? Могу вас порадовать, всё готово, можете заходить, увидите Вашего моба =)
(Советую посмотреть эти классы: EntityZombie, EntitySkeleton, EntityCreeper, EntityAIBase)
P.s. прошу указать на ошибки, задавать вопросы)