Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

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?

share|improve this question
2  
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. –  Josh Petrie Jun 28 '13 at 6:23
    
@JoshPetrie so there is really no way of doing this? –  Andrew Graber Jun 28 '13 at 6:29
2  
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. –  Josh Petrie Jun 28 '13 at 6:31
    
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. –  Andrew Graber Jun 28 '13 at 6:39

1 Answer 1

up vote 6 down vote accepted

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.

share|improve this answer
1  
Thanks! It works! –  Andrew Graber Jun 28 '13 at 18:52
    
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); } –  Kevin Reid Jun 29 '13 at 3:00
    
@KevinReid derp, you're right. I've been away from Java too long. –  Travis Christian Jul 1 '13 at 16:13
    
@AndrewGraber look at the above comments, they're important :P –  Pip Jul 1 '13 at 16:37

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.