Posted December 17, 20168 yr I'm trying to make a block that stores a color value as NBT and then retrieves that color value and visualizes it in form of a block tint (Similarly to Openblocks' Canvas). When I place the block in the world it works, and gives the block the default color of 10000. But when I relog the world, all blocks are rendered black (color multiplier is 0) I looked at all the black blocks using an NBT editor, but they still have the same color value of 10000, that I gave them from the start. What is happening? TileEntity Class: package tschipp.buildingblocks.blocks.tileentity; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; public class TileEntityConcrete extends TileEntity { protected int color = 10000; @Override public void readFromNBT(NBTTagCompound tag) { super.readFromNBT(tag); this.markDirty(); this.color = tag.getInteger("color"); } @Override public NBTTagCompound writeToNBT(NBTTagCompound tag) { if (tag == null) { NBTTagCompound comp = new NBTTagCompound(); comp.setInteger("color", this.color); this.markDirty(); return super.writeToNBT(comp); } else { tag.setInteger("color", this.color); this.markDirty(); return super.writeToNBT(tag); } } public int getColor() { return this.color; } } Block Class: package tschipp.buildingblocks.blocks; import javax.annotation.Nullable; import net.minecraft.block.Block; import net.minecraft.block.ITileEntityProvider; import net.minecraft.block.material.MapColor; import net.minecraft.block.material.Material; import net.minecraft.block.state.IBlockState; import net.minecraft.client.renderer.color.IBlockColor; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumHand; 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; import tschipp.buildingblocks.blocks.tileentity.TileEntityConcrete; public class BlockConcrete extends Block implements ITileEntityProvider, IBlockColor{ public BlockConcrete(Material material) { super(material, MapColor.GRAY); this.setHardness(3.5F); this.setResistance(8F); } //FOR TESTING PURPOSES @Override public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand, @Nullable ItemStack heldItem, EnumFacing side, float hitX, float hitY, float hitZ) { if(!world.isRemote) { TileEntityConcrete tile = (TileEntityConcrete) world.getTileEntity(pos); NBTTagCompound tag = new NBTTagCompound(); tile.writeToNBT(tag); if(tag.hasKey("color")) { tag.setInteger("color", tag.getInteger("color") + 1000); System.out.println(tag.getInteger("color")); tile.readFromNBT(tag); world.scheduleBlockUpdate(pos, this, 1, 1); } else { tag.setInteger("color", 1000); tile.readFromNBT(tag); } } return true; } @Override public TileEntity createNewTileEntity(World worldIn, int meta) { return new TileEntityConcrete(); } @SideOnly(Side.CLIENT) @Override public int colorMultiplier(IBlockState state, IBlockAccess worldIn, BlockPos pos, int tintIndex) { TileEntityConcrete tile = (TileEntityConcrete) worldIn.getTileEntity(pos); NBTTagCompound tag = new NBTTagCompound(); tile.writeToNBT(tag); int color = tag.getInteger("color"); return color + 10000; } }
December 17, 20168 yr Don't implement ITileEntityProvider, just override the hasTileEntity and getTileEntity methods that are already present in the Block class. Also, why the fuck are you doing this: tile.writeToNBT(tag); int color = tag.getInteger("color"); return color + 10000; You have this available to you: public int getColor() { return this.color; } 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.
December 17, 20168 yr Author Don't implement ITileEntityProvider, just override the hasTileEntity and getTileEntity methods that are already present in the Block class. Also, why the fuck are you doing this: tile.writeToNBT(tag); int color = tag.getInteger("color"); return color + 10000; You have this available to you: public int getColor() { return this.color; } I used to use getColor, but I switched to this, trying to find why it isn't working. It makes no (visual) difference. Why shouldn't I implement ITileEntityProvider? Anyway, I did what you said but sadly it doesn't change anything
December 17, 20168 yr Why shouldn't I implement ITileEntityProvider? Anyway, I did what you said but sadly it doesn't change anything Because it's old. Its not needed any more. The new way is better. And no, that change won't fix your problem, but it's still better. 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.
December 17, 20168 yr Did you register your TileEntity ? Don't PM me with questions. They will be ignored! Make a thread on the appropriate board for support. 1.12 -> 1.13 primer by williewillus. 1.7.10 and older versions of Minecraft are no longer supported due to it's age! Update to the latest version for support. http://www.howoldisminecraft1710.today/
December 17, 20168 yr Author Did you register your TileEntity ? Yes, as I said, I was able to check it's values using McEdit
December 17, 20168 yr Author Why are you calling markDirty in writeToNbt and readFromNbt ? Do you know what that method does? What is that strange null handling in writeToNbt ? Why do you use NBT-hacks to set the color in onBlockActivated ? Just write a setter... You have not written any code to synchronize the color value to the client. Hence the client will not know the value. How would I go about synchronizing the color value with the client? Packets? I had this null check because it used to crash sometimes for some reason... I just thought that markDirty makes sure the values are saved.
December 19, 20168 yr Author I made some Changes, it sort of works now, the color of the block updates when right clicked and uses the correct color from NBT. But on re-entering the world all the blocks are still black. I debugged at colorMultiplier and found that the tileentity's tag is null. Why is that? The block gets recoloured correctly when right clicked, but it goes away on reloading the world. I might have a ton of unneccesary or stupid code everywhere, but please don't blame me, as it is my first time working with tile entities. Here is an image to make it a bit clearer what i'm trying to do. This is my current code: Block Class: package tschipp.buildingblocks.blocks; import java.util.Random; import javax.annotation.Nullable; import net.minecraft.block.Block; import net.minecraft.block.material.MapColor; import net.minecraft.block.material.Material; import net.minecraft.block.state.IBlockState; import net.minecraft.client.renderer.color.IBlockColor; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.play.server.SPacketUpdateTileEntity; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.BlockRenderLayer; import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumHand; 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; import tschipp.buildingblocks.blocks.tileentity.TileEntityConcrete; public class BlockConcrete extends Block implements IBlockColor{ public BlockConcrete(Material material) { super(material, MapColor.GRAY); this.setHardness(3.5F); this.setResistance(8F); this.setTickRandomly(true); } //FOR TESTING PURPOSES @Override public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand, @Nullable ItemStack heldItem, EnumFacing side, float hitX, float hitY, float hitZ) { if(!world.isRemote) { TileEntityConcrete tile = (TileEntityConcrete) world.getTileEntity(pos); NBTTagCompound tag = new NBTTagCompound(); tile.setColor(tile.getColor() + 1000); tile.writeToNBT(tag); if(player instanceof EntityPlayerMP) { ((EntityPlayerMP) player).connection.sendPacket(new SPacketUpdateTileEntity(pos, 0, tag)); } world.notifyBlockOfStateChange(pos, this); tile.markDirty(); } return true; } @Override public void updateTick(World world, BlockPos pos, IBlockState state, Random rand) { TileEntityConcrete tile = (TileEntityConcrete) world.getTileEntity(pos); NBTTagCompound tag = new NBTTagCompound(); tile.writeToNBT(tag); if(world.isRemote) { world.sendPacketToServer(new SPacketUpdateTileEntity(pos, -1, tag)); } } @Override public BlockRenderLayer getBlockLayer() { return BlockRenderLayer.CUTOUT_MIPPED; } @Override public boolean hasTileEntity(IBlockState state) { return true; } @Override public TileEntity createTileEntity(World world, IBlockState state) { return new TileEntityConcrete(); } @SideOnly(Side.CLIENT) @Override public int colorMultiplier(IBlockState state, IBlockAccess worldIn, BlockPos pos, int tintIndex) { TileEntityConcrete tile = (TileEntityConcrete) worldIn.getTileEntity(pos); int color = tile.getColor(); return color; } } Tile Entity Class: package tschipp.buildingblocks.blocks.tileentity; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.play.server.SPacketUpdateTileEntity; import net.minecraft.tileentity.TileEntity; public class TileEntityConcrete extends TileEntity { protected int color; @Override public void readFromNBT(NBTTagCompound tag) { super.readFromNBT(tag); this.color = tag.getInteger("color"); } @Override public NBTTagCompound writeToNBT(NBTTagCompound tag) { if (tag == null) { NBTTagCompound comp = new NBTTagCompound(); comp.setInteger("color", this.color); return super.writeToNBT(comp); } else { tag.setInteger("color", this.color); return super.writeToNBT(tag); } } @Override public SPacketUpdateTileEntity getUpdatePacket() { return new SPacketUpdateTileEntity(pos, -1, this.getUpdateTag()); } @Override public void onDataPacket(net.minecraft.network.NetworkManager net, net.minecraft.network.play.server.SPacketUpdateTileEntity pkt) { readFromNBT(pkt.getNbtCompound()); worldObj.markBlockRangeForRenderUpdate(this.pos, this.pos); } @Override public NBTTagCompound getUpdateTag() { NBTTagCompound tag = new NBTTagCompound(); tag.setInteger("color", this.getColor()); return tag; } @Override public boolean receiveClientEvent(int id, int type) { return true; } public int getColor() { return this.color; } public void setColor(int color) { this.color = color; } }
December 19, 20168 yr Is your TileEntity registered? VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect. Forge and vanilla BlockState generator.
December 19, 20168 yr Author Is your TileEntity registered? Yes. In my CommonProxy in preInit GameRegistry.registerTileEntity(TileEntityConcrete.class, "bbconcrete");
December 19, 20168 yr Is your TileEntity registered? Yes. In my CommonProxy in preInit GameRegistry.registerTileEntity(TileEntityConcrete.class, "bbconcrete"); Try sending the update packet, somewhere other than right click. VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect. Forge and vanilla BlockState generator.
December 19, 20168 yr Author Is your TileEntity registered? Yes. In my CommonProxy in preInit GameRegistry.registerTileEntity(TileEntityConcrete.class, "bbconcrete"); Try sending the update packet, somewhere other than right click. Where for example? I'm already trying to send it in the updateTick method, but that seems to do nothing.
December 19, 20168 yr Do you by any chance have the ClientProxy override preInit without calling super.preInit() , causing the TileEntity not to be registered on the client side? Don't PM me with questions. They will be ignored! Make a thread on the appropriate board for support. 1.12 -> 1.13 primer by williewillus. 1.7.10 and older versions of Minecraft are no longer supported due to it's age! Update to the latest version for support. http://www.howoldisminecraft1710.today/
December 19, 20168 yr Author Do you by any chance have the ClientProxy override preInit without calling super.preInit() , causing the TileEntity not to be registered on the client side? I don't think so. All my other Blocks work too. As I said earlier, I was able to see the TileEntity using Worldedit. Here is my ClientProxy just in case I am derping. public class ClientProxy extends CommonProxy { public void preInit(FMLPreInitializationEvent event) { super.preInit(event); } public void init(FMLInitializationEvent event) { super.init(event); ItemRenderRegister.registerItems(); BlockRenderRegister.registerBlocks(); Minecraft.getMinecraft().getBlockColors().registerBlockColorHandler(new BlockConcreteDyeable(Material.ROCK), MoreBlocks.concreteDyeable); } public void postInit(FMLPostInitializationEvent event) { super.postInit(event); } }
December 19, 20168 yr Is your TileEntity registered? Yes. In my CommonProxy in preInit GameRegistry.registerTileEntity(TileEntityConcrete.class, "bbconcrete"); Try sending the update packet, somewhere other than right click. Where for example? I'm already trying to send it in the updateTick method, but that seems to do nothing. You may be able to do that in the TileEntity#onLoad() method. VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect. Forge and vanilla BlockState generator.
December 19, 20168 yr Author I added this to my onLoad() method in my TileEntity class. @Override public void onLoad() { if(worldObj.isRemote) {this.worldObj.sendPacketToServer(getUpdatePacket());} } It just kicks me out of the world.
December 19, 20168 yr Don't send it to the server....you need to send it to the player/client. VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect. Forge and vanilla BlockState generator.
December 19, 20168 yr Author Don't send it to the server....you need to send it to the player/client. How do I do that? Also I did some more testing and noticed that the block's color gets reset even when the chunk gets unloaded...
December 19, 20168 yr Don't send it to the server....you need to send it to the player/client. How do I do that? Also I did some more testing and noticed that the block's color gets reset even when the chunk gets unloaded... World#playerEntities. I will let you decide what to do with that. But I will say that there should be an alternate way, that is internal. But I can't think of any reason as to why it is not functioning. Try setting a break point in your readFromNBT method. VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect. Forge and vanilla BlockState generator.
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.