Odd behaviour regarding BlockReplacedState, BlockReplacedState.getBlock() and slabs

Discussion in 'Plugin Development' started by EraDKtor, Mar 17, 2011.

Thread Status:
Not open for further replies.
  1. Offline

    EraDKtor

    For my current plugin I need to know when a slab turns into a double slab which has caused me to fiddle around with BlockPlaceEvent.getBlockReplacedState() and BlockPlaceEvent.getBlockReplacedState().getBlock().

    While printing out some debug info to see how this event is processed I noticed an odd behaviour when I placed a different type of slab over an existing one.

    Allow me to explain:

    When I place a single stone block I get the following output:
    Code:
    [Action]: [MaterialID].[Metadata] at [Coordinates]
    Placed: 4.0 at X:-40 Y:66 Z:117
    
    ReplacedState: 0.0 at X:-40 Y:66 Z:117
    ReplacedStateBlock: 4.0 at X:-40 Y:66 Z:117
    I can see that I placed a stone (ID 4) and replaced air (ID 0). The getBlockReplacedState().getBlock() is stone again, I take it this is the new block at the BlockReplaceState location.


    When I place two stone slabs overeach other I get the following output:

    Code:
    (First slab)
    Placed: 44.0 at X:-40 Y:66 Z:115
    ReplacedState: 0.0 at X:-40 Y:66 Z:115
    ReplacedStateBlock: 44.0 at X:-40 Y:66 Z:115
    (Second slab)
    Placed: 0.0 at X:-40 Y:67 Z:115
    ReplacedState: 44.0 at X:-40 Y:66 Z:115
    ReplacedStateBlock: 43.0 at X:-40 Y:66 Z:115
    The first part is obvious: a stone slab replaces air. In the second part I see myself placing air at the location above the first slab (which would explain why you can't turn a single slab into a double slab when something is above it - you can't place the air). I also notice that I'm replacing a single slab (ID 44) one field below and that the getBlockReplacedState().getBlock() is now a double slab (ID 43) at the location where the single slab was replaced.


    However it becomes a bit odd when I place a different type of slab above the first one:

    Code:
    (first slab: stone)
    Placed: 44.0 at X:-40 Y:66 Z:113
    ReplacedState: 0.0 at X:-40 Y:66 Z:113
    ReplacedStateBlock: 44.0 at X:-40 Y:66 Z:113
    (second slab: cobblestone)
    Placed: 44.3 at X:-40 Y:67 Z:113
    ReplacedState: 44.0 at X:-40 Y:66 Z:113
    ReplacedStateBlock: 44.0 at X:-40 Y:66 Z:113
    According to the output I'm now placing a cobblestone slab above the first (which is what actually happens), yet I don't replace the air in the new location but the single stone slab below, that isn't actally modified. If I place a normal stone above the slab the behaviour is as expected:

    Code:
    (stone slab)
    Placed: 44.0 at X:-40 Y:66 Z:111
    ReplacedState: 0.0 at X:-40 Y:66 Z:111
    ReplacedStateBlock: 44.0 at X:-40 Y:66 Z:111
    (stone placed above)
    Placed: 4.0 at X:-40 Y:67 Z:111
    ReplacedState: 0.0 at X:-40 Y:67 Z:111
    ReplacedStateBlock: 4.0 at X:-40 Y:67 Z:111
    While this isn't exactly a problem for my plugin it still makes me wonder:

    Is this behaviour "normal" for minecraft or have I actually found a bug in bukkit?

    Edit: I forgot to mention: I'm running craftbukkit 516
    Edit2: Just tested it with craftbukkit 556 and bukkit 461 - same behaviour
     
  2. Offline

    eltorqiro

    I believe this is due to the way CraftBukkit is selecting what block to return as the replacedBlock. If you look in net.minecraft.server.ItemBlock.java you will see this at line 72 - see how it does not discriminate based on the block trying to be placed? This is probably a hangover from when there was only one type of halfblock

    Code:
    if (typeId == Block.SNOW.id || (typeId == Block.STEP.id && itemstack.id == Block.STEP.id && faceClicked == BlockFace.UP))
                    replacedBlock = blockClicked;
    What they should do here is add a check to make sure the itemstack data is the same as the blockClicked data, so that it doesn't cause the odd behaviour you are describing.

    EDIT: maybe like this - I think itemstack.damage stores the metadata for blocks? I think I read that somewhere a while ago, if so the below code should fix the problem.

    Code:
    if (typeId == Block.SNOW.id || (typeId == Block.STEP.id && itemstack.id == Block.STEP.id && faceClicked == BlockFace.UP && blockClicked.getData() == itemstack.damage))
        replacedBlock = blockClicked;
    
     
  3. Offline

    EraDKtor

    I see. I guess this would count as a "bug" of sorts then...
    Well it's not a big deal, for now I will just assume that no person in the right mind will walk around placing air.
     
  4. Offline

    eltorqiro

  5. Offline

    EraDKtor

    Your help is much appreciated.
    Shame on me - I didn't know where to report bugs [​IMG]
     
  6. Offline

    eltorqiro

    That's ok, that was my first one! :)
     
Thread Status:
Not open for further replies.

Share This Page