Jump to content

[1.10.02] Blockstate Problem


TrekkieCub314

Recommended Posts

I have an item that is supposed to place a specific block when used.  These blocks should be changing their texture based on whether the block above them is the same kind as itself.  It seems I'm not doing this right, and I'm wondering if someone would be willing to help me out with this.  I'm somewhat new to block states and how to use them correctly.

 

[spoiler=Item]

package com.trekkiecub.oddsandends.items;

import java.util.List;

import com.trekkiecub.oddsandends.blocks.Block_Chain;
import com.trekkiecub.oddsandends.init.BlockInit;

import net.minecraft.block.Block;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.ActionResult;
import net.minecraft.util.EnumActionResult;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;

public class Item_Chain extends Item {

@Override
public EnumActionResult onItemUse(ItemStack stack, EntityPlayer playerIn, World worldIn, BlockPos pos, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ)
    {
	if (worldIn.getBlockState(pos).getBlock() == BlockInit.chain)
	{
		Block_Chain chain = (Block_Chain)worldIn.getBlockState(pos).getBlock();
		BlockPos nextChain = chain.canAddSegment(worldIn, pos);
		if (nextChain != null)
		{
			worldIn.setBlockState(nextChain, BlockInit.chain.getDefaultState());
			stack.stackSize--;
		}
	}
	if (facing != null && facing == EnumFacing.DOWN)
	{
		if (playerIn.canPlayerEdit(pos, facing, stack))
		{
			worldIn.setBlockState(pos.down(), BlockInit.chain.getDefaultState());
			stack.stackSize--;
		}
	}
        return EnumActionResult.PASS;
    }

@Override
public ActionResult<ItemStack> onItemRightClick(ItemStack itemStackIn, World worldIn, EntityPlayer playerIn, EnumHand hand)
    {
        return new ActionResult(EnumActionResult.PASS, itemStackIn);
    }

}

 

 

 

[spoiler=Block]

package com.trekkiecub.oddsandends.blocks;

import java.util.Random;

import com.trekkiecub.oddsandends.init.BlockInit;
import com.trekkiecub.oddsandends.init.ItemInit;

import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.block.properties.IProperty;
import net.minecraft.block.properties.PropertyBool;
import net.minecraft.block.properties.PropertyEnum;
import net.minecraft.block.state.BlockStateContainer;
import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.item.Item;
import net.minecraft.util.BlockRenderLayer;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.IStringSerializable;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;

public class Block_Chain extends Block {

public static final PropertyBool MID = PropertyBool.create("mid");

public Block_Chain(Material materialIn) {
	super(materialIn);
	this.setDefaultState(this.blockState.getBaseState().withProperty(MID, Boolean.valueOf(false)));
}

@Override
public boolean isOpaqueCube(IBlockState state)
    {
        return false;
    }

@Override
    public boolean isFullCube(IBlockState state)
    {
        return false;
    }
    
    @SideOnly(Side.CLIENT)
    public BlockRenderLayer getBlockLayer()
    {
        return BlockRenderLayer.CUTOUT;
    }

    @Override
public void neighborChanged(IBlockState state, World worldIn, BlockPos pos, Block blockIn)
{
	if (!this.canBlockStay(worldIn, pos))
	{
		worldIn.destroyBlock(pos, true);
	}
}

@Override
public IBlockState getActualState(IBlockState state, IBlockAccess worldIn, BlockPos pos)
{
	return state.withProperty(MID, isBottom((World) worldIn, pos));
}

public boolean isBottom(World worldIn, BlockPos pos)
{
	if (worldIn.getBlockState(pos.down()).getBlock() instanceof Block_Chain)
	{
		return false;
	}
	else
	{
		return true;
	}
}

@Override
public boolean canSilkHarvest()
{
	return false;
}

@Override
public Item getItemDropped(IBlockState state, Random rand, int fortune)
{
	boolean mid = state.getValue(MID);
	return (mid ? Items.APPLE : ItemInit.chain);
}

public boolean canBlockStay(World world, BlockPos pos)
{
	if (world.getBlockState(pos.up()).getBlock() == BlockInit.chain)
	{
		return true;
	}
	else if (world.getBlockState(pos.up()).isSideSolid(world, pos, EnumFacing.DOWN))
	{
		return true;
	}
	else
	{
		return false;
	}
}

public BlockPos canAddSegment(World worldIn, BlockPos pos)
{
	if (worldIn.getBlockState(pos.down()).getBlock() == Blocks.AIR)
	{
		if (pos.down().getY() > 0)
		{
			return pos.down();
		}
		else
		{
			return null;
		}
	}
	else if (worldIn.getBlockState(pos.down()).getBlock() instanceof Block_Chain)
	{
		return canAddSegment(worldIn, pos.down());
	}
	else
	{
		return null;
	}
}

@Override
protected BlockStateContainer createBlockState()
{
	return new BlockStateContainer(this, new IProperty[] {MID});
}

@Override
public int getMetaFromState(IBlockState state)
{
	return 0;
}
}

 

 

Link to comment
Share on other sites

Why does it seem that you're not doing it right? You haven't told us what happens versus what you expected. You haven't told us what you saw happening as you stepped through in the debugger. What's "not right"?

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

Hi

 

Perhaps your blockstates json is not correct.

 

You could check your getActualState by putting a breakpoint in there or alternatively System.out.println("state:" + actualState);

 

	@Override
public IBlockState getActualState(IBlockState state, IBlockAccess worldIn, BlockPos pos)
{
actualState = state.withProperty(MID, isBottom((World) worldIn, pos));
return actualState
}

 

 

Link to comment
Share on other sites

  • 2 weeks later...

Did you step through its execution? Did you see what was returned by isBottom? Did you step into withProperty to see what happened there?

 

If all those things went well, then post your blockstates json file.

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

I'm not sure how to step into the withProperty function of IBlockState in Eclipse (the option is grayed out, not sure what I'm supposed to do to fix this).  isBottom() is returning the correct values.

 

When I change the default value for the MID property, the block has the correct model and drops the correct item for the blockstate.  It seems the problem is one where the block's state isn't changing when I add a new block below it.  I thought the getActualState() function was supposed to let me do that, but it looks like I might need to do more to the block class.

 

Does anyone know what I'm doing wrong?

Link to comment
Share on other sites

I'm not sure how to step into the withProperty function of IBlockState in Eclipse...

You need to be running in debug mode. What did you try to do, and where did you set your breakpoint(s)? How much experience do you have with debugger tools?

 

the block's state isn't changing when I add a new block below it

Then you want to step through the neighbor change.

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

I actually have little experience with debugger tools.  Most coding I've done in college has been through a text editor and a console, and when I do use an IDE, I use it for error detection and code consistency.  What I usually do is I use text output to determine and isolate a problem.

 

I've been looking at the code for the vanilla BlockPane, and it looks like my code should work.  The only difference between BlockPane and Block_Chain was that getActualState was overriden in Block_Chain.  Removing the override did not change the outcome.

 

I'm doing some debugging now and it looks like BlockRendererDispatcher's renderBlock() is throwing an exception when it tries to set the state to the value returned from getActualBlockState().  This exception is caught and nothing happens afterward.  I'm not sure what's causing this, but it looks like the code was designed to smother the exception rather than help figure out what's going wrong.

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.



×
×
  • Create New...

Important Information

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