Jump to content

Recommended Posts

Posted

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;

} 

}

Posted

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

  • Like 1

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.

Posted

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 :(

Posted
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.

Posted

  • 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.

Posted

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.

 

rpSIefd.png

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


}

Posted

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.

Posted

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.

Posted

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/

Posted

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


}

}

Posted

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.

Posted

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.

Posted

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...

Posted

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.

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.