Hello fellow Modificationer! Today you will learn how to create a mob! I won't be creating some boring mob. I'm going to be creating soldiers! Much like the clay soldiers mod. Of course that mod is better but today, we'll be dissecting every single method I'm going to be adding and we'll get to the bottom of the soldiers! All their different colors and how they don't fight their own kind.
NOTE: I'm learning as I create this tutorial, so if I mess up, please bear with my stupidity! Also, I'll be leaving out imports and package header on all code. And also placing all code in spoilers
The Simple Setup
I'm going to be starting completely fresh! With a new mod! So. The first thing we need to do is create a mod class! For tutorial's sake, I'll name it MobTutorial
@Mod(modid = MobTutorial.Info.MODID, name = "Mob Tutorial", version = MobTutorial.Info.VERSION)
public class MobTutorial
{
@EventHandler
public void init(FMLInitializationEvent event)
{
}
public static class Info
{
public static final String MODID = "mobtutorial";
public static final String VERSION = "1.0";
}
}
Simple right! Now what I'll need is simply, an Entity class! Let's name it EntitySoldier and make it extend EntityCreature:
public class EntitySoldier extends EntityCreature
{
public EntitySoldier(World world)
{
super(world);
this.setSize(0.2F, 0.5F);
}
}
As you can see, this is extremely bare! We need to add stuff to it! BUT WAIT THERE'S MORE! We first need to register the mob and add all the difficult stuff so we can get a bit more creative! So first, we'll register it to the EntityRegistry using this method:
NOTE: We have to add that setSize() method so the rendering is proper.
I created this method, a while back to make registering entities easier. If you want to see the full code, I'm basing this all off: Click Here.
Now that we have that method, we can register our mob! Now we'll add this line to the init method of MobTutorial. Now that method will become into:
@EventHandler
public void init(FMLInitializationEvent event)
{
registerEntity(EntitySoldier.class, "Soldier", EnumCreatureType.creature);
}
The Simple Renderer
Now it's registered with the EntityRegistry. From here, it could go multiple ways.
I suggest creating the model and textures and all of that right now as we are going to be moving onto the entity's renderer. For this, we will need a client and server class. For that, start creating two classes.
Preferably name one (something)Client and the other (something)Common. I named my Mob Client and MobCommon. Now you will have to make MobClient extend MobCommon and all of it's methods. At the end, the two classes might look just like:
MobCommon:
public class MobCommon
{
public void registerRenderThings()
{
}
}
MobClient:
public class MobClient extends MobCommon
{
@Override
public void registerRenderThings()
{
}
}
Now from here, we will go and create the field for the proxies in our mod file. For this, we will have to go back into MobTutorial an add the following line:
@SidedProxy(clientSide = MobTutorial.Info.CLIENT_CLASS, serverSide = MobTutorial.Info.COMMON_CLASS)
public static MobCommon proxy;
Now I know, you'll get an error. To fix that error, hover over the error and do: Create constant "CLIENT_CLASS" in type Info. Now the same for the other error. You will have to point to the two Client and Common classes for this.
This might be difficult so to get the right string, you'll have to go to that class and get the package name. Copy it and add the class to the end of it.
So if my MobCommon class is in the com.mobtutorial.main package. The string will be that with the class at the end. Like so: "com.mobtutorial.main.MobCommon". Same for the MobClient! Hopefully that's not too confusing! Now you won't be getting any error for that now.
You might have been wondering why that registerRenderThings() method was there. This is where we will be using it!
In the MobTutorial class you'll have to add this after the entity registration line.
proxy.registerRenderThings();
This will call the method after registering the entity! Now we will going to MobClient and register the Renderer for the soldier. We will do this by adding this line into the method:
RenderingRegistry.registerEntityRenderingHandler(EntitySoldier.class, new RenderSoldier());
Again, you will be getting an error on the RenderSoldier. So hover over it and create that class. That class is very important! That's where we will determine how the entity looks. I have created a texture and also a model, feel free to use it for yourself!
The model class is: ModelSoldier.java
Now we have the RenderSoldier class, we will make it extend RenderLiving. This will require us to create a constructor with a Model and also a float which is the shadow size. Most of the time is going to be 0.5F.
The class will now look like:
public class RenderSoldier extends RenderLiving
{
public RenderSoldier()
{
super(new ModelSoldier(), 0.5F);
}
@Override
protected ResourceLocation getEntityTexture(Entity entity)
{
return null;
}
}
This is the simple Render class. You can simply, just have this and a ResourceLocation, but since we are going to have different colors of soldiers, we have to do a bit more work. Just for simplicity, I'm going to create another class called SoldierColors. This is a custom class, and you don't have to do it but here:
public enum SoldierColors
{
BLACK,
RED,
GREEN,
BROWN,
BLUE,
PURPLE,
CYAN,
SILVER,
GRAY,
PINK,
LIME,
YELLOW,
LIGHT_BLUE,
MAGENTA,
ORANGE,
WHITE;
public final String name;
public final int color;
private SoldierColors()
{
name = name().substring(0, 1).toUpperCase().replaceAll("_", " ") + name().substring(1).replaceAll("_", " ");
color = ItemDye.field_150922_c[ordinal()];
}
public static SoldierColors random()
{
return values()[new Random().nextInt(values().length)];
}
}
This is just all the vanilla dye colors and their names. Now we are going to finally add stuff to the EntitySoldier class! YAY!
The Entity's Color
This is very important! Listen (read) closely! Since, we will make it so that when you use the spawn egg, it will spawn a soldier with a random color. And since we will be using a random color upon spawn, we will have to sync the Server and Client!
OMG! Now, don't worry! Minecraft entities have a really cool thing that automatically can sync the Client and Server. This is the DataWatcher class! Every entity has a DataWatcher field. It's used by almost every single entity in Minecraft.
We will use it to set the color. First we will set it into the dataWatcher field using the entityInit() method. Like so:
@Override
protected void entityInit()
{
super.entityInit();
dataWatcher.addObject(29, new Integer(0));
}
Now we can alter this value and it will change on both Client and Server! To alter this value, we will create a set of Getter and Setters. This is done in the EntitySoldier class:
public void setColor(SoldierColors color)
{
dataWatcher.updateObject(29, new Integer(color.ordinal()));
}
public SoldierColors getColor()
{
return SoldierColors.values()[dataWatcher.getWatchableObjectInt(29)];
}
This will set the color and sync the server and client. We can also receive the color easily! This will be very helpful when were rendering the entity. We can easily color the entity!
Now we will set it up so that, when it's spawned with an egg, it set's a random color. For this, we will override the onSpawnWithEgg() method. Did you notice the random() method in the SoldierColors class? That will make it really easy to get a random color!
Now with all that information, we will now add in the method into the EntitySoldier class:
@Override
public IEntityLivingData onSpawnWithEgg(IEntityLivingData stuff)
{
setColor(SoldierColors.random());
return super.onSpawnWithEgg(stuff);
}
Really simple!
The Entity's AI
Now we will work on the entity's fighting and not attack the same color, be peaceful, and much more. Pretty much the entity's AI.
Wait! Let's not just jump into this and plan out what we need to do first: (will be done in order)
- Set the soldier's health
- Set the soldier's walking speed
- Save the soldier's color after quitting
- Fix the soldier's fighting AI to attack other colors only
- Make it so it's a one hit kill by the player
- Add random tasks that will make it run generic-like
Now that might look hard, but know this: It has been done before! Right? It's possible, if it wasn't, I wouldn't be writing this right now!
We could knock two things off this list with 6 lines! That is setting the entity's max health, and it's movement speed. Play around with these values.
It's pretty obvious, increasing the 0.3F will make the soldier faster.
Increasing the 10.0D will make the soldier's max health more. Each 1.0D is half a heart!
@Override
public void applyEntityAttributes()
{
super.applyEntityAttributes();
this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(10.0D);
this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.3F);
}
Now to save data when the player quits uses two separate methods that we have to override. You might have heard of NBTTagCompounds before. The two methods are:
@Override
public void readEntityFromNBT(NBTTagCompound nbt)
{
super.readEntityFromNBT(nbt);
setColor(SoldierColors.values()[nbt.getInteger("Color")]);
}
@Override
public void writeEntityToNBT(NBTTagCompound nbt)
{
super.writeEntityToNBT(nbt);
nbt.setInteger("Color", getColor().ordinal());
}
This will save the soldier's color and receive it when he loads the world up again!
This might be difficult but now we have to make it so the soldier only attacks it's own kind! There are two ways of going about this:
1. We could make it so when the soldier attacks a mob, it checks if it's a soldier and it's a different color. If not, it'll stop attacking.
2. We could make it look for soldiers of a different color to attack.
I will go over both ways.
NOTE: You could make sure it works and add both ways in, and it'll work a lot more efficiently! This is what I will be doing.
Now, to make it forget of a soldier, if it's a different color will require overriding the attackEntityAsMob() method. We could check if it's a soldier and if it's the same color.
It isn't very hard now. Like so:
@Override
public boolean attackEntityAsMob(Entity entity)
{
if (entity instanceof EntitySoldier)
{
if (((EntitySoldier) entity).getColor() == getColor()) return super.attackEntityAsMob(entity);
}
super.attackEntityAsMob(entity);
return entity.attackEntityFrom(DamageSource.causeMobDamage(this), 1);
}
Pretty straight forward right? If the attacker is a soldier and it's the same color, stop attacking!
The next way will require a few lines of code. First, will will add a task to the constructor
this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntitySoldier.class, 0, false, true, soldiers));
You'll get an error here. So you'll have to add this to the class. You might have noticed, it's the second task. This is because of something we have to add later.
This checks for nearby entities and if it's a soldier and NOT the same color, it'll return true for attacking.
Now this will work, and they will be restricted from attacking their own color
Now we have to make it so the player will kill it with one hit. This will require overriding the attackEntityFrom() method. This is called when the entity is attacked.
We will check if the attacker was a player, and if so, we will kill the soldier by multiplying the damage by the soldier's max health. Like this:
All the soldier does right now it just stand there until someone comes along and attacks it. Nothing else. We have to add some simple AI. Most of it is pretty self-explanatory
this.tasks.addTask(0, new EntityAISwimming(this));
this.tasks.addTask(1, new EntityAITempt(this, 1.0D, Items.paper, false));
this.tasks.addTask(4, new EntityAIAttackOnCollide(this, EntitySoldier.class, 1.0D, true));
this.tasks.addTask(5, new EntityAIMoveTowardsRestriction(this, 1.0D));
this.tasks.addTask(6, new EntityAIMoveThroughVillage(this, 1.0D, false));
this.tasks.addTask(7, new EntityAIWander(this, 1.0D));
this.tasks.addTask(8, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F));
this.tasks.addTask(8, new EntityAILookIdle(this));
this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, true));
Again, pretty understandable.
EntityAITempt means, if the player is holding paper in his hands, the soldier will follow the player, like wheat with a cow, or a carrot with a pig.
EntityAIAttackOnCollide means, if there's a soldier in the vicinity and meets the requirements for the mob selector, it will get to attacking
Now that's all done, what you need to do now is enable all of these tasks! This is done by overriding the method isAIEnabled(), We have to make it return true.
I made the method private, so if anyone just copies and pastes this, they won't know what to do here.
Just change the private to protected or public, and you're good to go.
private boolean isAIEnabled()
{
return true;
}
Now we are officially done with the EntitySoldier class, unless you would like to add something else yourself.
The Entity Rendering
Now we will have to go back to our RenderSoldier code so we can setup how the entity will be rendered.
After the super call, add the line:
setRenderPassModel(mainModel);
This will allow us to mess with renderPasses. The first thing we will do is give it a non-null resource location.
I created one to match the model. If you need it: soldier.png
With that, we will make a new ResourceLocation and point to the image:
Now we have a texture, we will want to color it. Since we did sync the client and server, we don't have to do any work for any network stuff.
By taking a look at the RenderSoldier so far. We will want to override a method that renders it. By adding the setRenderPassModel(mainModel) line we added to it, we'll be able to use the shouldRenderPass() method in the RenderSoldier.
This might involve some OpenGL stuff so if you don't care, feel free to skip some of it. BUT I HIGHLY SUGGEST CONTINUE READING IT
@Override
protected int shouldRenderPass(EntityLivingBase entity, int pass, float f)
{
return -1;
}
This will allow to render some stuff differently. If you want a good example of where and how this is used, I suggest reading the RenderPig class. It uses this method very nicely, and it's quite understandable.
So, we want to return something other that one if we want the model to render. So, we will do a check for the pass integer parameter.
@Override
protected int shouldRenderPass(EntityLivingBase entity, int pass, float f)
{
if (pass == 0)
{
Color color = new Color(((EntitySoldier) entity).getColor().color);
return 1;
}
return -1;
}
Now we will actually color the soldier in. We have the color from the soldier. Since it returns something other than -1, it will render the model.
Since OpenGL works with Colors in decimal form. We will have to alter all the values of this so we can get the correct color. For this, we will divide all the values by 255, and convert it to a float. Like this here:
@Override
protected int shouldRenderPass(EntityLivingBase entity, int pass, float f)
{
if (pass == 0)
{
Color color = new Color(((EntitySoldier) entity).getColor().color);
float r = color.getRed() / 255.0F;
float g = color.getGreen() / 255.0F;
float b = color.getBlue() / 255.0F;
float a = color.getAlpha() / 255.0F;
GL11.glColor4f(r, g, b, a);
return 1;
}
else return -1;
}
Simple, Red, Green, Blue, and Alpha, that isn't to big of an issue really.
That's it! Were done! Go ahead and run your game and enjoy your soldiers!
So far this is the major stuff they do: - Attack other soldiers of different colors - Render the correct color for each soldier - Sync the server and client with a few lines - Can easily be killed by the player - Set a random color when spawned from an egg - Follow you if you have paper in your hand
I will leave all the source code, here on this Github.
Feel free to Copy and Paste everything, AFTER READING IT ALL, OR ELSE, YOU'RE JUST MESSING YOURSELF UP!
Homework
If you manage to complete any of these, please post it below in the comments
- Create Items/Spawners (not eggs) for all the different soldier colors and also color the items.
Homework: - Create an Item that upon right clicking, kills all soldiers that are in a 10 block radius.
Here is the code you should add to your item:
@Override
public boolean onItemUse(ItemStack itemStack, EntityPlayer player, World world, int x, int y, int z, int side, float relativeX, float relativeY, float relativeZ) {
if(!world.isRemote){
int range = 5;
List soldiers = world.getEntitiesWithinAABB(EntitySoldier.class, AxisAlignedBB.getBoundingBox(x-range, y-range, z-range, x+range, y+range, z+range));
for(EntitySoldier soldier:soldiers){
soldier.setDead();
}
}
return true;
}
- Create an Item that upon right clicking, kills all soldiers that are in a 10 block radius.
- Add 10 more custom colors
- Upon death, make them drop their custom item
- Fix the model's head not turning correctly
- Add some special weapons that will allow them to take in more damage and/or deal more damage
Thanks for reading this tutorial and I hope that you learned a lot about customizing entities and giving them special attributes depending on a specific value. Feel free to comment, complain, or question down below, and I will check it out!
There's actually an AI that you can attach to your mob that allows it to be controlled by a player. I suggest looking into the EntityAIControlledByPlayer class and also the EntityPig class (where it's used) If this still isn't what you want your mob to do, I suggest creating your own EntityAI to handle it. Let me know if you want to know how to start on creating an AI or where to put the EntityAIControlledByPlayer code, let me know!
-
View User Profile
-
View Posts
-
Send Message
Curse PremiumNOTE: I'm learning as I create this tutorial, so if I mess up, please bear with my stupidity! Also, I'll be leaving out imports and package header on all code. And also placing all code in spoilers
The Simple Setup
@Mod(modid = MobTutorial.Info.MODID, name = "Mob Tutorial", version = MobTutorial.Info.VERSION) public class MobTutorial { @EventHandler public void init(FMLInitializationEvent event) { } public static class Info { public static final String MODID = "mobtutorial"; public static final String VERSION = "1.0"; } }Simple right! Now what I'll need is simply, an Entity class! Let's name it EntitySoldier and make it extend EntityCreature:
public class EntitySoldier extends EntityCreature { public EntitySoldier(World world) { super(world); this.setSize(0.2F, 0.5F); } }NOTE: We have to add that setSize() method so the rendering is proper.
Now that we have that method, we can register our mob! Now we'll add this line to the init method of MobTutorial. Now that method will become into:
@EventHandler public void init(FMLInitializationEvent event) { registerEntity(EntitySoldier.class, "Soldier", EnumCreatureType.creature); }The Simple Renderer
I suggest creating the model and textures and all of that right now as we are going to be moving onto the entity's renderer. For this, we will need a client and server class. For that, start creating two classes.
Preferably name one (something)Client and the other (something)Common. I named my Mob Client and MobCommon. Now you will have to make MobClient extend MobCommon and all of it's methods. At the end, the two classes might look just like:
public class MobCommon { public void registerRenderThings() { } }MobClient:public class MobClient extends MobCommon { @Override public void registerRenderThings() { } }Now I know, you'll get an error. To fix that error, hover over the error and do: Create constant "CLIENT_CLASS" in type Info. Now the same for the other error. You will have to point to the two Client and Common classes for this.
This might be difficult so to get the right string, you'll have to go to that class and get the package name. Copy it and add the class to the end of it.
So if my MobCommon class is in the com.mobtutorial.main package. The string will be that with the class at the end. Like so: "com.mobtutorial.main.MobCommon". Same for the MobClient! Hopefully that's not too confusing! Now you won't be getting any error for that now.
You might have been wondering why that registerRenderThings() method was there. This is where we will be using it!
In the MobTutorial class you'll have to add this after the entity registration line.
The model class is: ModelSoldier.java
Now we have the RenderSoldier class, we will make it extend RenderLiving. This will require us to create a constructor with a Model and also a float which is the shadow size. Most of the time is going to be 0.5F.
The class will now look like:
public class RenderSoldier extends RenderLiving { public RenderSoldier() { super(new ModelSoldier(), 0.5F); } @Override protected ResourceLocation getEntityTexture(Entity entity) { return null; } }public enum SoldierColors { BLACK, RED, GREEN, BROWN, BLUE, PURPLE, CYAN, SILVER, GRAY, PINK, LIME, YELLOW, LIGHT_BLUE, MAGENTA, ORANGE, WHITE; public final String name; public final int color; private SoldierColors() { name = name().substring(0, 1).toUpperCase().replaceAll("_", " ") + name().substring(1).replaceAll("_", " "); color = ItemDye.field_150922_c[ordinal()]; } public static SoldierColors random() { return values()[new Random().nextInt(values().length)]; } }The Entity's Color
OMG! Now, don't worry! Minecraft entities have a really cool thing that automatically can sync the Client and Server. This is the DataWatcher class! Every entity has a DataWatcher field. It's used by almost every single entity in Minecraft.
We will use it to set the color. First we will set it into the dataWatcher field using the entityInit() method. Like so:
@Override protected void entityInit() { super.entityInit(); dataWatcher.addObject(29, new Integer(0)); }public void setColor(SoldierColors color) { dataWatcher.updateObject(29, new Integer(color.ordinal())); } public SoldierColors getColor() { return SoldierColors.values()[dataWatcher.getWatchableObjectInt(29)]; }Now we will set it up so that, when it's spawned with an egg, it set's a random color. For this, we will override the onSpawnWithEgg() method. Did you notice the random() method in the SoldierColors class? That will make it really easy to get a random color!
Now with all that information, we will now add in the method into the EntitySoldier class:
@Override public IEntityLivingData onSpawnWithEgg(IEntityLivingData stuff) { setColor(SoldierColors.random()); return super.onSpawnWithEgg(stuff); }The Entity's AI
Wait! Let's not just jump into this and plan out what we need to do first: (will be done in order)
- Set the soldier's health
- Set the soldier's walking speed
- Save the soldier's color after quitting
- Fix the soldier's fighting AI to attack other colors only
- Make it so it's a one hit kill by the player
- Add random tasks that will make it run generic-like
Now that might look hard, but know this: It has been done before! Right? It's possible, if it wasn't, I wouldn't be writing this right now!
We could knock two things off this list with 6 lines! That is setting the entity's max health, and it's movement speed. Play around with these values.
It's pretty obvious, increasing the 0.3F will make the soldier faster.
Increasing the 10.0D will make the soldier's max health more. Each 1.0D is half a heart!
@Override public void applyEntityAttributes() { super.applyEntityAttributes(); this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(10.0D); this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.3F); }@Override public void readEntityFromNBT(NBTTagCompound nbt) { super.readEntityFromNBT(nbt); setColor(SoldierColors.values()[nbt.getInteger("Color")]); } @Override public void writeEntityToNBT(NBTTagCompound nbt) { super.writeEntityToNBT(nbt); nbt.setInteger("Color", getColor().ordinal()); }This might be difficult but now we have to make it so the soldier only attacks it's own kind! There are two ways of going about this:
1. We could make it so when the soldier attacks a mob, it checks if it's a soldier and it's a different color. If not, it'll stop attacking.
2. We could make it look for soldiers of a different color to attack.
I will go over both ways.
NOTE: You could make sure it works and add both ways in, and it'll work a lot more efficiently! This is what I will be doing.
Now, to make it forget of a soldier, if it's a different color will require overriding the attackEntityAsMob() method. We could check if it's a soldier and if it's the same color.
It isn't very hard now. Like so:
@Override public boolean attackEntityAsMob(Entity entity) { if (entity instanceof EntitySoldier) { if (((EntitySoldier) entity).getColor() == getColor()) return super.attackEntityAsMob(entity); } super.attackEntityAsMob(entity); return entity.attackEntityFrom(DamageSource.causeMobDamage(this), 1); }The next way will require a few lines of code. First, will will add a task to the constructor
private IEntitySelector soldiers = new IEntitySelector() { @Override public boolean isEntityApplicable(Entity entity) { return entity instanceof EntitySoldier && !((EntitySoldier) entity).getColor().equals(getColor()); } };Now this will work, and they will be restricted from attacking their own color
Now we have to make it so the player will kill it with one hit. This will require overriding the attackEntityFrom() method. This is called when the entity is attacked.
We will check if the attacker was a player, and if so, we will kill the soldier by multiplying the damage by the soldier's max health. Like this:
public boolean attackEntityFrom(DamageSource ds, float damage) { if(ds.getEntity() != null && ds.getEntity() instanceof EntityPlayer) { return super.attackEntityFrom(ds, this.getMaxHealth()); } return super.attackEntityFrom(ds, damage); }All the soldier does right now it just stand there until someone comes along and attacks it. Nothing else. We have to add some simple AI. Most of it is pretty self-explanatory
EntityAITempt means, if the player is holding paper in his hands, the soldier will follow the player, like wheat with a cow, or a carrot with a pig.
EntityAIAttackOnCollide means, if there's a soldier in the vicinity and meets the requirements for the mob selector, it will get to attacking
Now that's all done, what you need to do now is enable all of these tasks! This is done by overriding the method isAIEnabled(), We have to make it return true.
Just change the private to protected or public, and you're good to go.
private boolean isAIEnabled() { return true; }The Entity Rendering
After the super call, add the line:
I created one to match the model. If you need it: soldier.png
With that, we will make a new ResourceLocation and point to the image:
@Override protected ResourceLocation getEntityTexture(Entity soldier) { return new ResourceLocation(MobTutorial.Info.MODID + ":textures/entities/soldier.png"); }By taking a look at the RenderSoldier so far. We will want to override a method that renders it. By adding the setRenderPassModel(mainModel) line we added to it, we'll be able to use the shouldRenderPass() method in the RenderSoldier.
This might involve some OpenGL stuff so if you don't care, feel free to skip some of it. BUT I HIGHLY SUGGEST CONTINUE READING IT
@Override protected int shouldRenderPass(EntityLivingBase entity, int pass, float f) { return -1; }So, we want to return something other that one if we want the model to render. So, we will do a check for the pass integer parameter.
@Override protected int shouldRenderPass(EntityLivingBase entity, int pass, float f) { if (pass == 0) { Color color = new Color(((EntitySoldier) entity).getColor().color); return 1; } return -1; }Since OpenGL works with Colors in decimal form. We will have to alter all the values of this so we can get the correct color. For this, we will divide all the values by 255, and convert it to a float. Like this here:
@Override protected int shouldRenderPass(EntityLivingBase entity, int pass, float f) { if (pass == 0) { Color color = new Color(((EntitySoldier) entity).getColor().color); float r = color.getRed() / 255.0F; float g = color.getGreen() / 255.0F; float b = color.getBlue() / 255.0F; float a = color.getAlpha() / 255.0F; GL11.glColor4f(r, g, b, a); return 1; } else return -1; }That's it! Were done! Go ahead and run your game and enjoy your soldiers!
- Attack other soldiers of different colors
- Render the correct color for each soldier
- Sync the server and client with a few lines
- Can easily be killed by the player
- Set a random color when spawned from an egg
- Follow you if you have paper in your hand
I will leave all the source code, here on this Github.
Feel free to Copy and Paste everything, AFTER READING IT ALL, OR ELSE, YOU'RE JUST MESSING YOURSELF UP!
Homework
- Create Items/Spawners (not eggs) for all the different soldier colors and also color the items.
- Add 10 more custom colors
- Upon death, make them drop their custom item
- Fix the model's head not turning correctly
- Add some special weapons that will allow them to take in more damage and/or deal more damage
Thanks for reading this tutorial and I hope that you learned a lot about customizing entities and giving them special attributes depending on a specific value.
Feel free to comment, complain, or question down below, and I will check it out!
Hello!
-
View User Profile
-
View Posts
-
Send Message
Curse PremiumHello!
-
View User Profile
-
View Posts
-
Send Message
Curse PremiumHello!
-
View User Profile
-
View Posts
-
Send Message
Curse PremiumHello!