3
\$\begingroup\$

I'm creating Minecraft mod with a pickaxe that takes away experience when you break a block. The method for taking away experience from a player is addExperience on EntityPlayer, so I need to get an instance of EntityPlayer for the player using my pickaxe when the pickaxe breaks a block, so that I can remove the appropriate amount of experience.

My pickaxe class currently looks like this:

public class ExperiencePickaxe extends ItemPickaxe {

public ExperiencePickaxe(int ItemID, EnumToolMaterial material){
    super(ItemID, material);
}

public boolean onBlockDestroyed(ItemStack par1ItemStack, World par2World, int par3, int par4, int par5, int par6, EntityLiving par7EntityLiving)
{
    if ((double)Block.blocksList[par3].getBlockHardness(par2World, par4, par5, par6) != 0.0D)
    {
        EntityPlayer e = new EntityPlayer(); // create an instance
        e.addExperience(-1);
    }

    return true;
}
}

Obviously, I cannot actually create a new EntityPlayer since it is an abstract class. How can I get access to the player using my pickaxe?

\$\endgroup\$
4
  • 2
    \$\begingroup\$ You cannot create an instance of an abstract class; the question you actually asked is not game-development related. I've edited your question to reflect what I believe you actually mean to ask based on what you're trying to do. I would recommend you do some reading on what the semantics of abstract classes and static members are in object-oriented programming, as well. \$\endgroup\$
    – user1430
    Commented Jun 28, 2013 at 6:23
  • \$\begingroup\$ @JoshPetrie so there is really no way of doing this? \$\endgroup\$ Commented Jun 28, 2013 at 6:29
  • 2
    \$\begingroup\$ There's no way to create an instance of an abstract class, no. That's part of the definition of 'abstract class.' However, you don't actually want to do that: you want to get the EntityPlayer object that represents the player who just swung your axe, and subtract some experience from that player. That is probably doable (but requires more knowledge of the Minecraft API than I have; I've never used it). That's why I changed your question to reflect that. \$\endgroup\$
    – user1430
    Commented Jun 28, 2013 at 6:31
  • \$\begingroup\$ So I will just wait for someone with more Minecraft knowledge to come along and help me out. I will check back in the morning. \$\endgroup\$ Commented Jun 28, 2013 at 6:39

1 Answer 1

8
\$\begingroup\$

I'm going to assume you're using the Forge API, given the parameters you listed.

EntityLiving is an abstract type representing living entities like players and mobs. When it is passed into your block break event, it indicates the entity which broke the block. It's not guaranteed to be a player, so you need to try to cast it to the subtype that represents a player:

if( par7EntityLiving instanceof EntityPlayer ) {
  EntityPlayer player = (EntityPlayer) par7EntityLiving;
  player.addExperience(-1);
  // OR
  player.addExperienceLevel(-1);
}

If the instanceof check fails, then the parameter did not represent an EntityPlayer object and the block break was caused by something else.

\$\endgroup\$
3
  • \$\begingroup\$ This code and explanation of casting is incorrect. If the object is not an EntityPlayer then the cast will throw a ClassCastException, crashing the game. Instead, use instanceof to check before casting: if (par7EntityLiving instanceof Player) { ((EntityPlayer)player).addExperienceLevel(-1); } \$\endgroup\$
    – Kevin Reid
    Commented Jun 29, 2013 at 3:00
  • \$\begingroup\$ @KevinReid derp, you're right. I've been away from Java too long. \$\endgroup\$
    – WildWeazel
    Commented Jul 1, 2013 at 16:13
  • \$\begingroup\$ @AndrewGraber look at the above comments, they're important :P \$\endgroup\$
    – Pip
    Commented Jul 1, 2013 at 16:37

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .