Posted November 11, 20168 yr I have a custom block and when I place it down the neighboring blocks became transparent. That's why I put @Override public boolean doesSideBlockRendering(final IBlockState state, final IBlockAccess world, final BlockPos pos, final EnumFacing face) { return false; } Into my block code, but now the surface of the neighboring blocks renders black. What did I do wrong?
November 11, 20168 yr Show all of your block's code. Likely (because you didn't explicitly state whether or not it is), your block's volume is less than 1³, because you can "see" the sides of the block facing this block. If so, your block is not a full block, and you should thus override isFullBlock(IBlockState) . Also previously known as eAndPi. "Pi, is there a station coming up where we can board your train of thought?" -Kronnn Published Mods: Underworld Handy links: Vic_'s Forge events Own WIP Tutorials.
November 11, 20168 yr Author Yeah, true, my block is not a full block. The code of my block: The abstract: package com.minecolonies.blocks; import com.minecolonies.colony.Colony; import com.minecolonies.colony.ColonyManager; import com.minecolonies.colony.buildings.AbstractBuilding; import com.minecolonies.creativetab.ModCreativeTabs; import com.minecolonies.lib.Constants; import com.minecolonies.tileentities.TileEntityColonyBuilding; import net.minecraft.block.Block; import net.minecraft.block.BlockHorizontal; import net.minecraft.block.ITileEntityProvider; import net.minecraft.block.material.Material; import net.minecraft.block.properties.PropertyDirection; import net.minecraft.block.state.BlockStateContainer; import net.minecraft.block.state.IBlockState; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemBlock; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.*; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraftforge.fml.common.registry.GameRegistry; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; /** * Abstract class for all minecolonies blocks. * <p> * The method {@link AbstractBlockHut#getName()} is abstract * <p> * All AbstractBlockHut[something] should extend this class */ public abstract class AbstractBlockHut extends Block implements ITileEntityProvider { public static final PropertyDirection FACING = BlockHorizontal.FACING; private static final float HARDNESS = 10F; private static final float RESISTANCE = Float.POSITIVE_INFINITY; protected int workingRange; /** * Constructor for a block using the minecolonies mod. * <p> * Registers the block, sets the creative tab, as well as the resistance and the hardness. */ public AbstractBlockHut() { super(Material.WOOD); initBlock(); } private void initBlock() { setRegistryName(getName()); setUnlocalizedName(Constants.MOD_ID.toLowerCase() + "." + getName()); setCreativeTab(ModCreativeTabs.MINECOLONIES); //Blast resistance for creepers etc. makes them explosion proof setResistance(RESISTANCE); //Hardness of 10 takes a long time to mine to not loose progress setHardness(HARDNESS); this.setDefaultState(this.blockState.getBaseState().withProperty(FACING, EnumFacing.NORTH)); GameRegistry.register(this); GameRegistry.register((new ItemBlock(this)).setRegistryName(this.getRegistryName())); } /** * Method to return the name of the block. * * @return Name of the block. */ public abstract String getName(); @NotNull @Override public TileEntity createNewTileEntity(World world, int meta) { //Creates a tile entity for our building return new TileEntityColonyBuilding(); } @Override public int getMetaFromState(@NotNull IBlockState state) { return state.getValue(FACING).getIndex(); } // ======================================================================= // ======================= Rendering & IBlockState ======================= // ======================================================================= // render as a solid block, we don't want transparency here @NotNull @Override @SideOnly(Side.CLIENT) public BlockRenderLayer getBlockLayer() { return BlockRenderLayer.SOLID; } @Override public boolean onBlockActivated( World worldIn, BlockPos pos, IBlockState state, EntityPlayer playerIn, EnumHand hand, @Nullable ItemStack heldItem, EnumFacing side, float hitX, float hitY, float hitZ) { /* If the world is client, open the gui of the building */ if (worldIn.isRemote) { @Nullable final AbstractBuilding.View building = ColonyManager.getBuildingView(pos); if (building != null) { building.openGui(); } } return true; } @Override public IBlockState onBlockPlaced(World worldIn, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, @Nullable EntityLivingBase placer) { @NotNull final EnumFacing enumFacing = (placer == null) ? EnumFacing.NORTH : EnumFacing.fromAngle(placer.rotationYaw); return this.getDefaultState().withProperty(FACING, enumFacing); } //We unfortunately have to implement these two, to rotate our blocks in the structures. @Override public IBlockState withRotation(final IBlockState state, final Rotation rot) { return state.withProperty(FACING, rot.rotate(state.getValue(FACING))); } @Override public IBlockState withMirror(final IBlockState state, final Mirror mirrorIn) { return state.withRotation(mirrorIn.toRotation((EnumFacing)state.getValue(FACING))); } /** * Event-Handler for placement of this block. * <p> * Override for custom logic. * * @param worldIn the word we are in * @param pos the position where the block was placed * @param state the state the placed block is in * @param placer the player placing the block * @param stack the itemstack from where the block was placed * @see Block#onBlockPlacedBy(World, BlockPos, IBlockState, EntityLivingBase, ItemStack) */ @Override public void onBlockPlacedBy(@NotNull World worldIn, @NotNull BlockPos pos, IBlockState state, EntityLivingBase placer, ItemStack stack) { super.onBlockPlacedBy(worldIn, pos, state, placer, stack); /* Only work on server side */ if (worldIn.isRemote) { return; } final TileEntity tileEntity = worldIn.getTileEntity(pos); if (placer instanceof EntityPlayer && tileEntity instanceof TileEntityColonyBuilding) { @NotNull final TileEntityColonyBuilding hut = (TileEntityColonyBuilding) tileEntity; @Nullable final Colony colony = ColonyManager.getColony(worldIn, hut.getPosition()); if (colony != null) { colony.addNewBuilding(hut); } } } @NotNull @Override protected BlockStateContainer createBlockState() { return new BlockStateContainer(this, FACING); } // ======================================================================= // ===================== END of Rendering & Meta-Data ==================== // ======================================================================= } the block itself: package com.minecolonies.blocks; import net.minecraft.block.state.IBlockState; import net.minecraft.util.EnumFacing; import net.minecraft.util.math.BlockPos; import net.minecraft.world.IBlockAccess; import org.jetbrains.annotations.NotNull; /** * Hut for the fisherman. * No different from {@link AbstractBlockHut} */ public class BlockHutFisherman extends AbstractBlockHut { protected BlockHutFisherman() { //No different from Abstract parent super(); } @NotNull @Override public String getName() { return "blockHutFisherman"; } @Override public boolean isFullBlock(final IBlockState state) { return false; } @Override public boolean doesSideBlockRendering(final IBlockState state, final IBlockAccess world, final BlockPos pos, final EnumFacing face) { return false; } } Even with "isFullBlock" -> false I have the problems with the black rendered surfaces.
November 11, 20168 yr You need to also override isOpaqueCube(IBlockState state). Also, do not implement ITileEntityProvider, Block itself has methods for that (hasTileEntity() and createTileEntity()).
November 11, 20168 yr Author Using: @Override public boolean isOpaqueCube(final IBlockState state) { return false; } @Override public boolean isFullBlock(final IBlockState state) { return false; } @Override public boolean doesSideBlockRendering(final IBlockState state, final IBlockAccess world, final BlockPos pos, final EnumFacing face) { return false; } Seems to have resolved it. I unfortunately, cannot change the tileEntityProvider thing because we would lose the stored tileEntities and that means that all our users would have to start over.
November 11, 20168 yr They won't lose there TileEntities because the blocks own method call the ones from ITileEntityProvider if the block implements that interface and hasTileEntity() automatically returns true in that case.
November 11, 20168 yr Author I tried to change it and we lost the related data. The tileEntity stays but the data which was stored to nbt in it will be changed.
November 11, 20168 yr That doesn't make any sense because the NBT data is stored in a map with the classname or the registration name of the tile entity as key.
November 11, 20168 yr Hi XFactHD Also, do not implement ITileEntityProvider, Block itself has methods for that (hasTileEntity() and createTileEntity()). Why do you say that? I think you're probably right that it's not necessary to implement ITileEntityProvider, but if Ray already has implemented it, why should (s)he change it? -TGG
November 11, 20168 yr Oh. I know why him removing ITileEntityProvider "erases his data." He doesn't have @Override marked and/or isn't dealing with the IDE error involved when he removes the interface. So he's not overriding the correct method, so when the game runs it treats the block as not having a TE. Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable. If you think this is the case, JUST REPORT ME. Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice. Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked. DO NOT PM ME WITH PROBLEMS. No help will be given.
November 12, 20168 yr Why do you say that? I think you're probably right that it's not necessary to implement ITileEntityProvider, but if Ray already has implemented it, why should (s)he change it?Because ITileEntityProvider is an outdated API. It will not give you the IBlockState , instead it will give you the raw metadata value, which is not very useful. So in other words, at some point in the future if Raycomms needs to know the IBlockState when creating his TileEntity, or if the ITileEntityProvider is removed, he will need to change it. To me that is a good reason to change it later, not now. Enough vanilla and forge stuff breaks at every upgrade that personally I don't think trying to get ahead of the curve is the best use of a developer's time. Having said that, I also agree that switching from ITileEntityProvider and overriding the two necessary methods in Block shouldn't break existing saves. @Draco I think you're probably right and @Override would show the problem @Override public TileEntity createTileEntity(World world, IBlockState state) @Override public boolean hasTileEntity(IBlockState state) -TGG
November 14, 20168 yr Oh. I know why him removing ITileEntityProvider "erases his data." He doesn't have @Override marked and/or isn't dealing with the IDE error involved when he removes the interface. So he's not overriding the correct method, so when the game runs it treats the block as not having a TE. I just got bitten by this while getting rid of ITileEntityProvider too, and I suspect I know what happened to Raycoms. I implemented hasTileEntity() and getTileEntity(), using @Override of course, and restarted my dev world, only to find my item routers no longer had tile entities at all. A bit of debugging showed that hasTileEntity() wasn't even being called. A little more investigation with my IDE shows that there are two hasTileEntity() methods: hasTileEntity() , and hasTileEntity(IBlockState state) . Of course, I'd overridden the no-args one, which is wrong. You need to override hasTileEntity(IBlockState state) . Getting it wrong is a subtle error, since your IDE won't flag this as an error at all. The code is syntactically fine, just incorrect. Once I fixed that, my item routers had tile entities again, but since the world had been restarted using the wrong code, the game - as you rightly noted - treated the blocks as having no tile entity, and removed any saved data for those from the world. After fixing the code, loading up another dev world that I previously made worked fine - all TE data was intact. Moral of this story: override hasTileEntity(IBlockState state) , not hasTileEntity() . That no-args version appears to be only called by TileEntityHopper, and just calls hasTileEntity(getDefaultState()) . Yucky.
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.