Chapter 4. Entities

Now that you have a good understanding of how to make mods with event handlers, we can move on to other types of mods. The theme of Chapter 3 was explosions, which are fun, but this chapter’s theme will be entities. First, you will make pigs drop diamonds in addition to their normal drop of porkchops. Next, you will make all zombies receive diamond armor and a diamond axe when they spawn. Finally, you will allow creepers to spawn five reinforcements when they die.

Pigs Dropping Diamonds

Pigs are passive entities. They will follow you if you hold a carrot. You can also breed them with a carrot. You can even ride on them with a saddle and a carrot on a stick. When pigs die, they drop porkchops. Wouldn’t it be fun to make them drop diamonds or some other material instead? Let’s do that!

First, create an event handler class called PigsDroppingDiamonds. The method code you need to add is shown in Example 4-1.

Example 4-1. Pigs dropping diamonds method code
@SubscribeEvent
public void dropDiamonds(LivingDeathEvent event){ 1
	if (!(event.entity instanceof EntityPig)) { 2
		return;
	}

	Random random = new Random(); 3

	if (!event.entity.worldObj.isRemote) { 4
		event.entity.dropItem(Items.diamond, random.nextInt(3)); 5
	}
}
1

This method runs on a LivingDeathEvent, which happens when an entity dies.

2

If the entity is not a pig, the method returns.

3

This line creates a new variable of the name random and type Random. This is a Java class that generates random numbers.

4

If the world is not a client world, tested by the isRemote field, then the method continues. If this statement was not here, the pig would drop twice the number of items, but half of the items would be ghost items, and would be impossible to pick up.

5

dropItem is a method on the entity class that drops an item at the position of the entity. It takes two parameters: the first is the item to be dropped, and the second is the number of items to be dropped.

In this case, event.entity refers to the pig. Items is a Forge class that has the complete list of items in Minecraft. Items.diamond refers to the diamond item, as the name says. The nextInt() method gets a random number between 0 and the number before the parameter given, 2 in this case. This line then drops 0 to 2 diamond items when the pig dies.

The final code should look like Example 4-2.

Example 4-2. Pigs dropping diamonds final code
package org.devoxx4kids.forge.mods;

import java.util.Random;

import net.minecraft.entity.passive.EntityPig;
import net.minecraft.init.Items;
import net.minecraftforge.event.entity.living.LivingDeathEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;

public class PigsDroppingDiamonds {

	@SubscribeEvent
	public void dropDiamonds(LivingDeathEvent event){
		if (!(event.entity instanceof EntityPig)) {
			return;
		}

		Random random = new Random();

		if (!event.entity.worldObj.isRemote) {
			event.entity.dropItem(Items.diamond, random.nextInt(3));
		}
	}
}

Make sure to import everything, and import java.util.Random when you are importing the Random class.

Now, you are ready to try out your mod.

Run Minecraft by clicking the green arrow at the top and log in to your world. Spawn a pig by using a Spawn Pig item, and kill it by using a sword. You should see something like Figure 4-1.

mmwf 0401
Figure 4-1. A pig dropping a diamond

There are a variety of items in Minecraft. Instead of dropping diamonds, you can experiment with dropping some other items as well. You are limited, however, to items known to Forge. So delete diamond from the code, place your cursor right after Items. and press Ctrl-Space. This will show the list of Minecraft items that are known to Forge, as shown in Figure 4-2.

mmwf 0402
Figure 4-2. List of items in Forge

You can select any item that you wish, click the green arrow to run Minecraft, and your dead pig will then drop that particular item. For example, a pig dropping a potato is shown in Figure 4-3.

mmwf 0403
Figure 4-3. A pig dropping a potato

The brown splotch under the pig is the potato that it dropped.

Another twist to this mod involves dropping a block, instead of an item, when the pigs die. For example, change Items.diamond to Item.getItemFromBlock(Blocks.cobblestone) to drop a cobblestone instead of a diamond. You need the Item.getItemFromBlock() method because Blocks.cobblestone is a block, not an item, so it can’t be used in the method dropItem(). Item.getItemFromBlock() turns it into an ItemBlock, which is the item version of the block. A pig dropping a cobblestone is shown in Figure 4-4.

mmwf 0404
Figure 4-4. A pig dropping a cobblestone

Just as the complete list of items can be seen by placing the cursor after Items. and pressing Ctrl-Space, the complete list of blocks can be seen by placing the cursor right after Blocks. and using the same key sequence. This is shown in Figure 4-5.

Try dropping different items and blocks when the pig dies.

mmwf 0405
Figure 4-5. List of blocks in Forge

Any living entity such as a cow, iron golem, or skeleton fires a LivingDeathEvent as well. Change the first line in the dropDiamonds() method to check for that particular entity instead of EntityPig. For example, replace EntityPig with EntityIronGolem to change the items dropped on iron golem death. This will allow you to drop any item or block on the death of that entity.

Zombie Knights

Zombies are the most common hostile mobs in the game. They also drop many things (e.g., iron ingots and carrots), and they can pick up armor. This next mod will make zombies spawn with armor whenever they enter the world. They will also be given an axe. This way, zombies will be much stronger and harder to kill.

First, make an event handler class called ZombieKnights. Then, add the code shown in Example 4-3.

Example 4-3. Zombie knights method code
@SubscribeEvent
public void giveArmor(EntityJoinWorldEvent event){ 1
	if (!(event.entity instanceof EntityZombie)) { 2
		return;
	}

	EntityZombie zombie = (EntityZombie) event.entity; 3

	zombie.setCurrentItemOrArmor(0, new ItemStack(Items.diamond_axe)); 4
	zombie.setCurrentItemOrArmor(1, new ItemStack(Items.diamond_chestplate)); 5
	zombie.setCurrentItemOrArmor(2, new ItemStack(Items.diamond_leggings));
	zombie.setCurrentItemOrArmor(3, new ItemStack(Items.diamond_boots));
	zombie.setCurrentItemOrArmor(4, new ItemStack(Items.diamond_helmet));
}
1

This method runs on an EntityJoinWorldEvent, which happens when an entity is created.

2

If the entity is not a zombie, the method returns.

3

This line shows a good example of casting in Java. Before we understand the concept of casting, let’s first discuss inheritance.

Java allows a class to be derived from another class. A class that is derived from another class is called a subclass or a child class. The class from which the subclass is derived is called a superclass or a parent class. A child class inherits a parent class by using the extends Java keyword. So a child class is also known to extend the parent class.

For example, Animal could be a parent class, and Cat, Fish, and Bat could be child classes. Each animal knows how to eat, and that ability can be defined in the Animal class. However, each animal also has special abilities that separate them from the others (e.g., in our sample of animals, only cats can walk, only fish can swim, and only bats can fly). Those specific abilities can then be defined in their respective child classes.

A class can be derived from a class that is derived from another class, and so on, and ultimately derived from the topmost class, java.lang.Object. All the classes up to java.lang.Object are said to be in the parent hierarchy of the child class. This concept is commonly known as inheritance. A subclass inherits fields and methods of all the classes in the parent hierarchy.

Casting is taking an object and “turning it into” an object of a different type. Specifically, you can take an object from the parent hierarchy and cast it into an object of a more specific type.

In our case, Entity is in the parent hierarchy of EntityZombie. So after we’ve confirmed that the given entity is of the type EntityZombie, as done in 2, we can cast event.entity to EntityZombie. This will allow us to call all the methods from EntityZombie, of course, after casting. We are particularly looking for methods that give armor/items to the zombie.

Casting is done by specifying the more specific type in parentheses, ( and ), before the more generic type.

4

The setCurrentItemOrArmor method assigns an item or armor at a particular slot for the given entity. There are five available slots, starting with slot 0. The first slot is meant for an item that the entity will hold. This line gives the zombie a diamond axe in this slot.

5

The next four slots are meant for armor. This line and the three lines after it give the zombie full diamond armor in the armor slots: 1–4. Slot 1 is chestplate, slot 2 is leggings, slot 3 is boots, and slot 4 is helmet. You can put any kind of these armor in the appropriate slot, and in this mod, all the armor is diamond armor.

Import everything, and you should then be good to go.

The final code should look like Example 4-4.

Example 4-4. Zombie knights final code
package org.devoxx4kids.forge.mods;

import net.minecraft.entity.monster.EntityZombie;
import net.minecraft.entity.passive.EntityHorse;
import net.minecraft.init.Items;
import net.minecraft.item.ItemStack;
import net.minecraftforge.event.ServerChatEvent;
import net.minecraftforge.event.entity.EntityJoinWorldEvent;
import net.minecraftforge.event.entity.living.LivingHurtEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;

public class ZombieKnights {

    @SubscribeEvent
    public void giveArmor(EntityJoinWorldEvent event){
            if (!(event.entity instanceof EntityZombie)) {
                return;
            }

            EntityZombie zombie = (EntityZombie) event.entity;

            zombie.setCurrentItemOrArmor(0, new ItemStack(Items.diamond_axe));
            zombie.setCurrentItemOrArmor(1, new ItemStack(Items.diamond_chestplate));
            zombie.setCurrentItemOrArmor(2, new ItemStack(Items.diamond_leggings));
            zombie.setCurrentItemOrArmor(3, new ItemStack(Items.diamond_boots));
            zombie.setCurrentItemOrArmor(4, new ItemStack(Items.diamond_helmet));
    }
}

Run Minecraft by clicking the green arrow. Spawn a zombie, and it should have a diamond armor.

In Chapter 3, in the bouncing zombie tower picture, all the zombies had full diamond armor. This is because the player who took the screenshot was using the zombie knights and the exploding minecarts mods at the same time. An example of a zombie knight by itself is shown in Figure 4-6.

mmwf 0406
Figure 4-6. Zombie knight

Creeper Reinforcements

The final mod in this chapter will be about creepers. Creepers are probably the most famous hostile mob in Minecraft, even if they aren’t the most common one. A bit of interesting history about the creeper: its entity model (shape) was made when Notch accidentally inverted the model of a pig.

This mod will spawn five creepers when a creeper dies, making the game much harder. You won’t be able to just kill the creepers, but will instead have to trap them. If you make the mistake of killing them, five more will attack you.

Create an event handler class called CreeperReinforcements. The method code for it is shown in Example 4-5.

Example 4-5. Creeper reinforcements method code
@SubscribeEvent
public void spawnReinforcements(LivingDeathEvent event){ 1
	if (!(event.entity instanceof EntityCreeper)) { 2
		return;
	}

	for (int i = 0 ; i < 5 ; i++) { 3
		EntityCreeper creeper = new EntityCreeper(event.entity.worldObj); 4
		creeper.setLocationAndAngles(event.entity.posX, 5
			event.entity.posY,
			event.entity.posZ,
			0,
			0);
		if (!event.entity.worldObj.isRemote) { 6
			event.entity.worldObj.spawnEntityInWorld(creeper); 7
		}
	}
}
1

This method runs on a LivingDeathEvent, which happens when an entity dies.

2

If the entity is not a creeper, the method returns.

3

This line is the start of a for loop, another Java concept. A for loop is a way to repeat code until a certain condition is met. The general form of the for loop requires three values between the parentheses: the initialization, termination, and increment. These values are separated by semicolons. The initialization is run once, as the loop begins. The termination tells the loop when to stop; when the statement in this section becomes false, the loop stops. This statement is checked after each repetition of the code. The increment happens after each time a loop is completed. The code that is repeated every time is within the opening bracket after for (int i = 0 ; i < 5 ; i++) and the corresponding closing bracket two lines after event.entity.worldObj.spawnEntityInWorld(creeper);.

In this case, a new integer variable called i is made in the initialization and set to 0. The termination says to keep going until i is not less than 5. ++ is a new Java operator called an increment. This operator can be placed after an integer variable, and increments the value of the variable by 1. In our case, the increment says to increase i by 1 each time.

So when the loop starts out, i is set to 0 and the code inside the for loop is run once. After the completion of the first run, it is incremented by 1, so it is now equal to 1. Before the next run of the loop, the termination condition is checked. If it is false, then the loop is stopped and the next Java statement after the loop is executed. If it is true, then the loop is run once again, the value incremented, the termination checked, and so on.

This keeps going on until i is incremented to 5, at which point it is not less than 5, because it is equal to 5. The loop has run five times by now. Because the termination statement is false, the loop stops.

4

A new variable called creeper is created. This variable will store the creeper that should be spawned. Because it is inside the for loop, it will run five times.

5

This moves the creeper to the position of the dead creeper. It is also inside the for loop.

6

This if statement checks whether the world is remote (isRemote). Just as in the bigger TNT explosions mod, this is done so that the statement inside does not run twice. If this statement was not here, five regular creepers would spawn, but five creepers without AI would also spawn. If a mob does not have AI, it can’t move and can’t take any damage.

7

This spawns the creeper. Because this line and the surrounding if statement are in the for loop, they will run twice.

You have now finished your mod and can test it out in Minecraft. Spawn a creeper by using a Spawn Creeper item, and kill it with a diamond sword. Five more creepers should spawn. Figure 4-7 shows what happens if you spawn one creeper and constantly kill its offspring. You can also spawn an iron golem inside the area, and it will start killing creepers and making more for you. When one creeper explodes, a lot of creepers will die and make tons of creepers. The only way to get rid of them is by setting your game difficulty to peaceful.

mmwf 0407
Figure 4-7. Creeper infestation

Notice the gray items in the picture; those are the gunpowder items dropped upon creeper death. There are also a few experience orbs, which are dropped upon a mob’s death. All these creepers came from one creeper, which eventually multiplied on death.

Summary

In this chapter, you learned about entities and how you can mod them to make them more interesting. First, you made pigs drop diamonds. You also learned how different items and blocks can be dropped and how the same technique can be applied to other living entities. Armored zombies were created, and finally, you made creepers spawn reinforcements on death. Now that you know how to modify entities’ behavior, you can make cool mods like faster creepers, skeletons with swords, and flying pigs.

We discussed Java concepts like generating random numbers, using a for loop for repeating code until a condition was met, and using the increment operator. We also looked at inheritance and casting, two fundamental concepts that were applied in multiple places.

In the next chapter, you will learn about movement and how to mod the player’s movement.

Get Minecraft Modding with Forge now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.