I want to have a block property of EnumFacing, store its value in a TileEntity, and change the block's model through getActualState. My code is basically as follows:
public abstract class BlockDevice extends Block {
public static final PropertyBool ACTIVE = PropertyBool.create("active");
(Really sorry for the formatting; `Insert a code block` was taking 2 millennia to load [ty Twitch])
Where IFacing is an interface for Tiles that just has a getter and setter for facing, and the other I*Facing interfaces are just for identifying the axis of rotation range for a block. I figure this should work, but whenever I place my block in the world, it just faces the default direction stored in the Tile, which for me is NORTH. What am I doing wrong?
Does your TileEntity sync its EnumFacing field to the client in the update tag and packet?
There's no point in calling World#setBlockState with the actual state of a block, since only properties that are stored in metadata have their values stored in the chunk. Any properties whose values are set in Block#getActualState will be ignored by World#setBlockState/World#getBlockState. Forge's documentation has a page on block states (including an explanation of actual states) here.
There's no need to check for null before an instanceof check, instanceof will simply return false if the value is null.
In future, please use Gist or Pastebin to post logs/crash reports (if applicable) and code with syntax highlighting. To get syntax highlighting on Gist, give each file the appropriate extension (.java for Java code). To get syntax highlighting on Pastebin, select the language from the dropdown at the bottom of the page.
It's much easier to read code with proper formatting and syntax highlighting. The code formatting here is pretty bad even when it works.
Rollback Post to RevisionRollBack
Chisel Facades: For all your decorative pipe-hiding needs.
Please don't PM me to ask for help or to join your mod development team. Asking your question in a public thread preserves it for people who are having the same problem in the future. I'm not interested in developing mods with people.
1. To your question, yes. The Tile class I generally extend can be found here.
2. I did read that documentation. Granted I skimmed most of the things not pertaining to the actual state, believing my understanding was firm enough already. The last noted point on that page is why I decided to test calling getActualState(). If making that call isn't what I'm supposed to do, what will properly update my block?
3. Great tip, thanks!
4. Will do! Glad to know I'm not the only one to have suffered in silence this long.
Could you link a Block and TileEntity pair that stores the facing in the TileEntity and uses Block#getActualState to set an EnumFacing property from this?
The closest I can see is BlockInfuser/TileEntityInfuser, but BlockInfuser doesn't override Block#getActualState.
I have some working examples of Blocks that set an EnumFacing property from a TileEntity here:
Chisel Facades: For all your decorative pipe-hiding needs.
Please don't PM me to ask for help or to join your mod development team. Asking your question in a public thread preserves it for people who are having the same problem in the future. I'm not interested in developing mods with people.
Using your technique works perfectly, thanks! Whenever I try to use my MTile to store the EnumFacing value, it doesn't seem to work. Using the tile class you provided it works. Do you see anything wrong w/ MTile? The class works, as it handles literally every other tile in the mod. I suppose I can just create a separate MTileDevice for blocks w/ these properties, but I'd like to solve the issue.
EDIT: Never mind I got it working! Here's the result. Just a quick question. How do I fix my inventory rendering? In your models you don't have any "inventory": [{ ... }] declarations, and my models render with the front opposite and active.
I want to have a block property of EnumFacing, store its value in a TileEntity, and change the block's model through getActualState. My code is basically as follows:
public abstract class BlockDevice extends Block {
public static final PropertyBool ACTIVE = PropertyBool.create("active");
@Override
public IBlockState getActualState(IBlockState state, IBlockAccess world, BlockPos pos) {
IBlockState defaultState = getDefaultState();
TileEntity tile = world.getTileEntity(pos);
if (tile != null && tile instanceof IFacing) {
IFacing orientable = (IFacing) tile;
if (this instanceof IDirectionalFacing) {
if (orientable.getFacing().getAxis() == EnumFacing.Axis.Y) {
int horizontalIndex = orientable.getFacing().getIndex();
orientable.setFacing(EnumFacing.getHorizontal(horizontalIndex));
}
defaultState.withProperty(IDirectionalFacing.FACING, orientable.getFacing());
}
if (this instanceof IHorizontalFacing) {
defaultState.withProperty(IHorizontalFacing.FACING, orientable.getFacing());
}
}
return defaultState.withProperty(ACTIVE, false);
}
@Override
protected BlockStateContainer createBlockState() {
BlockStateContainer variantContainer = super.createBlockState();
IBlockState baseState = variantContainer.getBaseState();
List properties = new ArrayList();
if (hasVariants()) {
properties.addAll(variantContainer.getProperties());
}
if (this instanceof IDirectionalFacing) {
properties.add(IDirectionalFacing.FACING);
}
if (this instanceof IHorizontalFacing) {
properties.add(IHorizontalFacing.FACING);
}
properties.add(ACTIVE);
return properties.isEmpty() ? super.createBlockState() : new BlockStateContainer(this, properties.toArray(new IProperty[properties.size()]));
}
@Override
public IBlockState getStateForPlacement(World world, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer) {
IBlockState defaultState = getDefaultState();
if (this instanceof IHorizontalFacing) {
defaultState.withProperty(IHorizontalFacing.FACING, placer.isSneaking() ? placer.getHorizontalFacing() : placer.getHorizontalFacing().getOpposite());
}
if (this instanceof IDirectionalFacing) {
defaultState.withProperty(IDirectionalFacing.FACING, placer.isSneaking() ? EnumFacing.getDirectionFromEntityLiving(pos, placer).getOpposite() : EnumFacing.getDirectionFromEntityLiving(pos, placer));
}
return defaultState.withProperty(ACTIVE, false);
}
/*public void updateFacing(World world, BlockPos pos, EnumFacing face) {
if (this instanceof IDirectionalFacing || this instanceof IHorizontalFacing) {
if (face == BlockStateManager.getFacing(world.getBlockState(pos))) {
return;
}
if (this instanceof IHorizontalFacing && face.getHorizontalIndex() >= 0) {
world.setBlockState(pos, world.getBlockState(pos).withProperty(IHorizontalFacing.FACING, face), 3);
}
if (this instanceof IDirectionalFacing) {
world.setBlockState(pos, world.getBlockState(pos).withProperty(IDirectionalFacing.FACING, face), 3);
}
}
}*/
@Override
public void onBlockPlacedBy(World world, BlockPos pos, IBlockState state, EntityLivingBase placer, ItemStack stack) {
TileEntity tile = world.getTileEntity(pos);
if (tile != null && tile instanceof IFacing) {
IFacing orientable = (IFacing) tile;
orientable.setFacing(EnumFacing.getDirectionFromEntityLiving(pos, placer));
world.setBlockState(pos, getActualState(state, world, pos), 3);
}
}
}
(Really sorry for the formatting; `Insert a code block` was taking 2 millennia to load [ty Twitch])
Where IFacing is an interface for Tiles that just has a getter and setter for facing, and the other I*Facing interfaces are just for identifying the axis of rotation range for a block. I figure this should work, but whenever I place my block in the world, it just faces the default direction stored in the Tile, which for me is NORTH. What am I doing wrong?
Does your TileEntity sync its EnumFacing field to the client in the update tag and packet?
There's no point in calling World#setBlockState with the actual state of a block, since only properties that are stored in metadata have their values stored in the chunk. Any properties whose values are set in Block#getActualState will be ignored by World#setBlockState/World#getBlockState. Forge's documentation has a page on block states (including an explanation of actual states) here.
There's no need to check for null before an instanceof check, instanceof will simply return false if the value is null.
In future, please use Gist or Pastebin to post logs/crash reports (if applicable) and code with syntax highlighting. To get syntax highlighting on Gist, give each file the appropriate extension (.java for Java code). To get syntax highlighting on Pastebin, select the language from the dropdown at the bottom of the page.
It's much easier to read code with proper formatting and syntax highlighting. The code formatting here is pretty bad even when it works.
Chisel Facades: For all your decorative pipe-hiding needs.
Please don't PM me to ask for help or to join your mod development team. Asking your question in a public thread preserves it for people who are having the same problem in the future. I'm not interested in developing mods with people.
Answers and questions per sentence/paragraph:
1. To your question, yes. The Tile class I generally extend can be found here.
2. I did read that documentation. Granted I skimmed most of the things not pertaining to the actual state, believing my understanding was firm enough already. The last noted point on that page is why I decided to test calling getActualState(). If making that call isn't what I'm supposed to do, what will properly update my block?
3. Great tip, thanks!
4. Will do! Glad to know I'm not the only one to have suffered in silence this long.
Could you link a Block and TileEntity pair that stores the facing in the TileEntity and uses Block#getActualState to set an EnumFacing property from this?
The closest I can see is BlockInfuser/TileEntityInfuser, but BlockInfuser doesn't override Block#getActualState.
I have some working examples of Blocks that set an EnumFacing property from a TileEntity here:
Chisel Facades: For all your decorative pipe-hiding needs.
Please don't PM me to ask for help or to join your mod development team. Asking your question in a public thread preserves it for people who are having the same problem in the future. I'm not interested in developing mods with people.
Using your technique works perfectly, thanks! Whenever I try to use my MTile to store the EnumFacing value, it doesn't seem to work. Using the tile class you provided it works. Do you see anything wrong w/ MTile? The class works, as it handles literally every other tile in the mod. I suppose I can just create a separate MTileDevice for blocks w/ these properties, but I'd like to solve the issue.
EDIT: Never mind I got it working! Here's the result. Just a quick question. How do I fix my inventory rendering? In your models you don't have any "inventory": [{ ... }] declarations, and my models render with the front opposite and active.