Jump to content

Recommended Posts

Posted

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;
}
}

 

 

Posted

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.

Posted

Sorry about that.

 

What should be happening is a chain block should change how it renders based on whether the block above it is a chain block as well.  So far, that's not working, and every chain block placed keeps its default block state and doesn't change when a new chain block is added.

Posted

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
}

 

 

Posted

You might want MID to be !isBottom

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.

  • 2 weeks later...
Posted

getActualState is running, but it appears the MID property is not being set or accessed correctly and I'm not sure what I'm doing wrong.  It doesn't matter whether I use the isBottom function as-is or negate it.

Posted

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.

Posted

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?

Posted

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.

Posted

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.

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.