Эта статья рассчитана на продвинутых пользователей умеющих делать простейшие моды для майнкрафта, и здесь я попытаюсь рассказать о том как сделать моба который будет вас защищать стоя на месте.
Итак начнем:
Создаем файл mod_BowMan.java в котором мы укажем блок спавна нашего защитника:
SLU писал(а):
package net.minecraft.src;
public class mod_BowMan extends BaseMod
{
public static final Block BowManEgg = (new BlockBowManEgg(164, 0)).setHardness(0.0F).setResistance(0.0F).setBlockName("BowManegg");
public mod_BowMan()
{
ModLoader.RegisterBlock(BowManEgg);
ModLoader.AddName(BowManEgg, "Bowman Egg");
BowManEgg.blockIndexInTexture = ModLoader.addOverride("/terrain.png", "/textures/bowmanegg.png");
ModLoader.AddRecipe(new ItemStack(BowManEgg, 1), new Object[] { "X", Character.valueOf('X'), Block.dirt});
ModLoader.RegisterEntityID(net.minecraft.src.EntityBowMan.class, "entityBowMan", ModLoader.getUniqueEntityId());
}
public String Version()
{
return "Guard Mob Tutorial by Perpetual Motion Team";
}
}
Теперь создаем файл EntityBowMan.java
Начало такое-же как и в создании нейтрала
SLU писал(а):
package net.minecraft.src;
import java.util.List;
import java.util.Random;
public class EntityBowMan extends EntityAnimal
{
public EntityBowMan(World world)
{
super(world);
texture = "/mob/char.png";
moveSpeed = 0.0F;
health = 50;
isImmuneToFire = true;
}
Но появляется пара новых строчек.
Скорость передвижения моба(0.7F - скорость игрока, 0.0F - моб стоит на месте), у нас будет лучник, поэтому скорость 0.
SLU писал(а):
moveSpeed = 0.0F;Жизни моба(1 жизнь - пол-сердца, у игрока 20 жизней).
SLU писал(а):
health = 50;Иммунитет к огню и к лаве
SLU писал(а):
isImmuneToFire = true;Теперь дописываем дальше:
Чтоб наш моб не пропадал.
SLU писал(а):
protected boolean canDespawn()
{
return false;
}
Теперь надо чтоб лучник находил врагов:
Здесь в каждую переменную типа list записывается данный о враждебных мобах.
SLU писал(а):
protected void updatePlayerActionState()
{
if(playerToAttack == null)
{
List list;
list = worldObj.getEntitiesWithinAABB(net.minecraft.src.EntityMob.class, AxisAlignedBB.getBoundingBoxFromPool(posX - 16.0D, posY - 4.0D, posZ - 16.0D, posX + 17.0D, posY + 5.0D, posZ + 17.0D));
if(list.isEmpty())
{
list = worldObj.getEntitiesWithinAABB(net.minecraft.src.EntityMob.class, AxisAlignedBB.getBoundingBoxFromPool(posX - 16.0D, posY - 12.0D, posZ - 16.0D, posX + 17.0D, posY - 4.0D, posZ + 17.0D));
if(list.isEmpty())
{
list = worldObj.getEntitiesWithinAABB(net.minecraft.src.EntityMob.class, AxisAlignedBB.getBoundingBoxFromPool(posX - 16.0D, posY - 20.0D, posZ - 16.0D, posX + 17.0D, posY - 12.0D, posZ + 17.0D));
}
}
if(!list.isEmpty())
{
setTarget((Entity)list.get(worldObj.rand.nextInt(list.size())));
}
}
super.updatePlayerActionState();
}
Теперь обрабатываем событие на атаку:
SLU писал(а):
protected void attackEntity(Entity entity, float f)
{
if(f < 240F)
{
double d = entity.posX - posX;
double d1 = entity.posZ - posZ;
if(attackTime == 0)
{
EntityArrow entityarrow = new EntityArrow(worldObj, this);
entityarrow.posY += 0.1999999761581421D;
double d2 = (entity.posY + (double)entity.getEyeHeight()) - 0.20000000298023224D - entityarrow.posY;
float f1 = MathHelper.sqrt_double(d * d + d1 * d1) * 0.2F;
worldObj.playSoundAtEntity(this, "random.bow", 1.0F, 1.0F / (rand.nextFloat() * 0.4F + 0.8F));
worldObj.entityJoinedWorld(entityarrow);
entityarrow.setArrowHeading(d, d2 + (double)f1, d1, 1.5F, 12F);
attackTime = 2;
}
rotationYaw = (float)((Math.atan2(d1, d) * 180D) / 3.1415927410125732D) - 90F;
hasAttacked = true;
}
}
Если умеете нормально программировать, то можете поменять здесь код на свою обработку.
А так объясню только 1 переменную:
Время до следующей атаки (у скелета время = 30, а у нас в 15 раз быстрее)
SLU писал(а):
attackTime = 2;И наконец дописываем концовку:
SLU писал(а):
protected String getLivingSound()
{
return "mob.skeleton";
}
protected String getHurtSound()
{
return "mob.skeletonhurt";
}
protected String getDeathSound()
{
return "mob.skeletondeath";
}
private int angerLevel;
private int randomSoundDelay;
}
Теперь нам надо сделать файл BlockBowManEgg.java:
SLU писал(а):
package net.minecraft.src;
import java.io.PrintStream;
import java.util.Random;
public class BlockBowManEgg extends Block
{
protected BlockBowManEgg(int i, int j)
{
super(i, j, Material.ground);
}
public int quantityDropped(Random random)
{
return 1;
}
public int tickRate()
{
return 30;
}
public void onBlockClicked(World world, int i, int j, int k, EntityPlayer entityplayer)
{
double d = i;
double d1 = j;
double d2 = k;
EntityBowMan entitybowman = new EntityBowMan(world);
entitybowman.setLocationAndAngles(d, d1, d2, world.rand.nextFloat() * 360F, 0.0F);
world.entityJoinedWorld(entitybowman);
}
}
Здесь все просто - по нажатию левой кнопкой мыши блок ломается (потому-что крепкость 0) и вызывает на это место лучника.
Остались только текстуры:
Текстура лучника - не требуется (в коде вписана стандартная текстура игрока).
Текстура bowmanegg.png - берем любой файл 16*16 и кидаем в папку textures в minecraft.jar с именем bowmanegg.png.
Ну вот стрелок и готов.