Jump to content

Breaking a block with subtypes


jeffryfisher

Recommended Posts

I think I have found a bug in vanilla MC 1.8 code (while using Forge b1450), but I don't like to think in that direction, so I have low confidence. I had the following client-side crash report:

 

---- Minecraft Crash Report ----
// Everything's going to plan. No, really, that was supposed to happen.

Time: 10/14/15 5:22 PM
Description: Unexpected error

java.lang.IllegalArgumentException: Cannot get property PropertyInteger{name=skin, clazz=class java.lang.Integer, values=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]} as it does not exist in BlockState{block=minecraft:air, properties=[]}
at net.minecraft.block.state.BlockState$StateImplementation.func_177229_b(BlockState.java:158)
at jrfwalls.classAbstractWall.func_176201_c(classAbstractWall.java:119)
at jrfwalls.classAnystoneWall.func_176195_g(classAnystoneWall.java:20)
at net.minecraft.item.ItemTool.func_179218_a(ItemTool.java:59)
at net.minecraft.item.ItemStack.func_179548_a(ItemStack.java:327)
at net.minecraft.client.multiplayer.PlayerControllerMP.func_178888_a(PlayerControllerMP.java:154)
at net.minecraft.client.multiplayer.PlayerControllerMP.func_180512_c(PlayerControllerMP.java:294)

Context:

 

My mod is a set of walls with 16 subtypes. When I break one of my walls, the game crashes on a call to getBlockHardness(World worldIn, BlockPos pos). ItemTool's call to getBlockHardness is inside onBlockDestroyed(). The crash report says that air does not have the property that my block uses to determine its subtype. It appears that the world has already replaced my wall with air before asking how hard it was.

 

Am I imagining things, or is this a bonafide Mojang bug? Class Block simply returns this.blockHardness without using world or pos. I can't find an example of a vanilla block type that overrides getBlockHardness, so as far as I can tell, nothing in vanilla actually uses world and pos. In pure vanilla, the bug may be hidden. Does that make world and pos into red herrings that should not be used?

 

My method:

  @Override
  public float getBlockHardness(World worldIn, BlockPos pos) {
    int meta = this.getMetaFromState (worldIn.getBlockState (pos));

    switch (meta) {                                 // Assign exotic hardnesses to some meta values
      case 6:
        return 0.7F;                                // Netherrack
      case 8:
        return 30.0F;                               // Obsidian
      case 15:
        return 1.5F;                                // End_stone; Todo: to become end_brick
      default:
        return super.blockHardness;
    }
  }

The debugger is a powerful and necessary tool in any IDE, so learn how to use it. You'll be able to tell us more and get better help here if you investigate your runtime problems in the debugger before posting.

Link to comment
Share on other sites

This does appear to be a vanilla bug.

 

On the client,

PlayerControllerMP#onPlayerDestroyBlock

calls

Block#removedByPlayer

(which sets the block to air) before calling

ItemStack#onBlockDestroyed

(which

ItemTool

calls

Block#getBlockHardness

from). On the server,

ItemInWorldManager#tryHarvestBlock

calls

ItemStack#onBlockDestroyed

before calling

Block#removedByPlayer

.

 

This means that the block still exists on the server when

Item#onBlockDestroyed

is called; but it's already been set to air on the client.

Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future.

Link to comment
Share on other sites

Nice traces; I saw several of those methods myself, but with full obfuscation in the crash report, I was unsure which were doing what where.

 

It looks like the hardness call is to determine whether to trigger an achievement or something. If that does not need to execute on the client side, then I may work around this bug by returning a default value when isAir == true. Then my walls can go back to having variable hardnesses for actual breaking.

The debugger is a powerful and necessary tool in any IDE, so learn how to use it. You'll be able to tell us more and get better help here if you investigate your runtime problems in the debugger before posting.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.