Basically, I have my machine created and it all works great, except for one feature I have been trying to add. I want to be able to input a "circuit" to dictate whether a side can import or export. I have all the functionality set up except for a block specific texture update. I had it coded inside the block class (CarbonCondenser), but then it was updating ALL instances of my machine. So I thought to move it into the TileEntity for two reasons. First, a new instance is created each time a block is placed, so values changing should keep it separated, correct? Secondly, having it inside of there, I was now able to add 5 slots to put the items inside of and then check and change the texture based on which item is inside.
So what I have now is a slot (we'll say one for now, and I'll duplicate and change as needed for the other slots)
I want to check for an item in it (Completed already)
Then based on which of the two items, or no item, it will change the texture to 1 of three textures.
How do I access the textures of the block from inside the TileEntity?
private void ChangeTextures()
{
if (this.getStackInSlot(4).getItem() == Construct.circuitImport)
{
}
else if (this.getStackInSlot(4).getItem() == Construct.circuitExport)
{
}
else if (this.getStackInSlot(4).getItem() == null)
{
Override Block#getIcon(IWorldAccess world, int x, int y, int z, int side) and use the contents of the TileEntity at the specified coordinates to determine which icon to use for the specified side.
Make sure Block#getIcon(int side, int meta) still returns the appropriate default icon for when you don't have access to the Block's location (e.g. when it's an Item in an inventory).
If you need more advanced rendering based on the TileEntity's contents, you'll need to use a TileEntitySpecialRenderer.
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.
Override Block#getIcon(IWorldAccess world, int x, int y, int z, int side) and use the contents of the TileEntity at the specified coordinates to determine which icon to use for the specified side.
Make sure Block#getIcon(int side, int meta) still returns the appropriate default icon for when you don't have access to the Block's location (e.g. when it's an Item in an inventory).
If you need more advanced rendering based on the TileEntity's contents, you'll need to use a TileEntitySpecialRenderer.
1st: This method was coming up in-existent in both the block and tile entity. I'm not very good with internet coding help conventions so I don't know what you mean by the Block# <the #.
2nd: This I know is done from prior testing and directional placing. (I thiiiiink)
3rd: I don't think I'll need more advanced rendering, because proof of concept is there, I just cant separate the action between different machines instances.
I went ahead and re-created the methods for updating my block.
Now it works, except I ran into the same problem. When I update 1 block, it updates ALL of the same type of block. Here is the code relating to the updating... (I'm just calling the method in "onBlockActivated" for now just as a proof of concept)
Calling the method:
updateCircuitTextures((CarbonCondenser)world.getBlock(x, y, z), (TileEntityCarbonCondenser)world.getTileEntity(x, y, z), world, x, y, z);
Note- All of the code relating to change of texture is in the block class
The Method
private static void updateCircuitTextures(CarbonCondenser block, TileEntityCarbonCondenser tileentity, World world, int x, int y, int z)
{
CarbonCondenser condenser = block;
if (tileentity.getStackInSlot(4) != null)
{
if (tileentity.getStackInSlot(4).getItem() == Construct.circuitImport)
{
condenser.sTop = 1;
Minecraft.getMinecraft().renderGlobal.markBlockForRenderUpdate(x, y, z);
}
else if (tileentity.getStackInSlot(4).getItem() == Construct.circuitExport)
{
condenser.sTop = 2;
Minecraft.getMinecraft().renderGlobal.markBlockForRenderUpdate(x, y, z);
}
}
else
{
condenser.sTop = 0;
Minecraft.getMinecraft().renderGlobal.markBlockForRenderUpdate(x, y, z);
}
}
Note - I only have the top changing right now to keep the code simple while I iron out this probably simple problem.
How do I get it to individualize each carbon condenser?
I use the ClassName#memberName notation to refer to the instance method or field of ClassName called memberName. I use a dot instead of a hash when referring to a static method or field.
Don't store any information in your Block class unless it should be shared between all occurrences of that Block (only one instance of the class exists for each type of block). Use the metadata or the TileEntity to store information specific to an individual occurrence of the Block.
In Block#getIcon, use IBlockAccess#getTileEntity to get the TileEntity at the specified coordinates and then use it determine which circuit has been applied for the specified side.
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.
Awesome, kind of! I didn't even know you could replace the standard getIcon because eclipse was not finding the IBlockAccess version and I had to manually type it in before it recognized it. So pending I have all the data being stored appropriately inside the TileEntityCarbonCondenser class I have [it does, I've tested it with print statements], this is to replace the original .getIcon(int side, int meta) method inside my CarbonCondenser block class?
@Override
public IIcon getIcon(IBlockAccess block, int x, int y, int z, int side)
{
//Sets inventory icons
if (side == 3 && block.getBlockMetadata(x, y, z) == 0)
{
return this.sideFront;
}
if (side == block.getBlockMetadata(x, y, z))
{
return this.sideFront;
}
if (side != block.getBlockMetadata(x, y, z))
{
if (side == ((TileEntityCarbonCondenser)block.getTileEntity(x, y, z)).left)
{
if (((TileEntityCarbonCondenser)block.getTileEntity(x, y, z)).sLeft == 0)
{
return this.blockIcon;
}
else if (((TileEntityCarbonCondenser)block.getTileEntity(x, y, z)).sLeft == 1)
{
return this.sideImport;
}
else if (((TileEntityCarbonCondenser)block.getTileEntity(x, y, z)).sLeft == 2)
{
return this.sideExport;
}
}
}
return this.blockIcon;
}
I replaced it and the front and blank textures (.blockIcon) return correctly and are visible in game, however the circuit textures do not update at all. Did I place this in the right location?
EDIT- if the code is confusing, I use .sSide for a int between 0-2 which stores which texture to return, and I use .side as an int which gets the left, right, back, top, bottom orientation of the block compared to the direction it is facing, for easier upgrade placement.
Awesome, kind of! I didn't even know you could replace the standard getIcon because eclipse was not finding the IBlockAccess version and I had to manually type it in before it recognized it.
I replaced it and the front and blank textures (.blockIcon) return correctly and are visible in game, however the circuit textures do not update at all. Did I place this in the right location?
Also, to note for anyone who uses this article: Don't replace the .getIcon method, but instead just add in your block class the second one. In your regular .getIcon method, you need this for the inventory to load correctly (it appears the .getIcon with IBlockAccess overwrites it in game but not in the inventory)
@Override
public IIcon getIcon(int side, int meta)
{
// Sets inventory icons
if (side == 3 && meta == 0)
{
return this.sideFront;
}
else
{
return this.blockIcon;
}
}
My problem right now is solely rendering the changed sides. I have print statemented and even programmed the check if import or export for the hopper. Everything works fine. The textures just don't get updated at all on the block, but block.getBlockMetadata(x,y,z) DOES work because it updates the front and the blank sides. But when I put in items into the slots, it however, does not update the sides. I have checked where I store the side data and it DOES indeed work, so it is a rendering issue.
Try using World#markBlockForUpdate in the TileEntity when the circuits change. This should trigger a rendering update on the client.
You may also need to override TileEntity#getDescriptionPacket and TileEntity#onDataPacket to write to NBT on the server, send it to the client and then read it back on the client. I don't know very much about the networking system, but Chisel has an example using the vanilla update packet here.
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.
Thank you Choonster for all you have done, but it seems I still am having issues even after looking at the chisel packet stuff and this website on the exact same methods:
(Note - changing the 0 to a 1 in the return new S35PacketUpdateTileEntity(xCoord, yCoord, zCoord, 0, tag) does not work)
Here is what I have coded for the updating of the texture, if anyone else knows something about packets and getting this to work, it would be much appreciated!
Thank you Choonster for all you have done, but it seems I still am having issues even after looking at the chisel packet stuff and this website on the exact same methods:
(Note - changing the 0 to a 1 in the return new S35PacketUpdateTileEntity(xCoord, yCoord, zCoord, 0, tag) does not work)
Here is what I have coded for the updating of the texture, if anyone else knows something about packets and getting this to work, it would be much appreciated!
Thank you so much Choonster, you really pointed me in the right direction with that last post. The packet update is exactly what I needed. I had it implemented correctly, and it doesn't work without it, I just completely forgot to save my integers for the circuit sides in the NBT and load them. I'm really shaking my head for overlooking that part. But it still wouldn't have worked without you pointing me toward that packet trick from the Chisel2 mod and causing me to find that other article. Hopefully this helps others in the future. I do have 1 other slight problem, but I will post that in a new thread. It's related but kind of different.
Rollback Post to RevisionRollBack
Mod Author and Owner of Blockhole
Owner of other discontinued or status frozen work: LimpCraft2, LimpCore, InventoryCalculator, VillageTech, Bitto'Color.
Basically, I have my machine created and it all works great, except for one feature I have been trying to add. I want to be able to input a "circuit" to dictate whether a side can import or export. I have all the functionality set up except for a block specific texture update. I had it coded inside the block class (CarbonCondenser), but then it was updating ALL instances of my machine. So I thought to move it into the TileEntity for two reasons. First, a new instance is created each time a block is placed, so values changing should keep it separated, correct? Secondly, having it inside of there, I was now able to add 5 slots to put the items inside of and then check and change the texture based on which item is inside.
So what I have now is a slot (we'll say one for now, and I'll duplicate and change as needed for the other slots)
I want to check for an item in it (Completed already)
Then based on which of the two items, or no item, it will change the texture to 1 of three textures.
How do I access the textures of the block from inside the TileEntity?
private void ChangeTextures()
{
if (this.getStackInSlot(4).getItem() == Construct.circuitImport)
{
}
else if (this.getStackInSlot(4).getItem() == Construct.circuitExport)
{
}
else if (this.getStackInSlot(4).getItem() == null)
{
}
}
Mod Author and Owner of Blockhole
Owner of other discontinued or status frozen work: LimpCraft2, LimpCore, InventoryCalculator, VillageTech, Bitto'Color.
Override Block#getIcon(IWorldAccess world, int x, int y, int z, int side) and use the contents of the TileEntity at the specified coordinates to determine which icon to use for the specified side.
Make sure Block#getIcon(int side, int meta) still returns the appropriate default icon for when you don't have access to the Block's location (e.g. when it's an Item in an inventory).
If you need more advanced rendering based on the TileEntity's contents, you'll need to use a TileEntitySpecialRenderer.
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.
Ignore what was here before.
Mod Author and Owner of Blockhole
Owner of other discontinued or status frozen work: LimpCraft2, LimpCore, InventoryCalculator, VillageTech, Bitto'Color.
1st: This method was coming up in-existent in both the block and tile entity. I'm not very good with internet coding help conventions so I don't know what you mean by the Block# <the #.
2nd: This I know is done from prior testing and directional placing. (I thiiiiink)
3rd: I don't think I'll need more advanced rendering, because proof of concept is there, I just cant separate the action between different machines instances.
I went ahead and re-created the methods for updating my block.
Now it works, except I ran into the same problem. When I update 1 block, it updates ALL of the same type of block. Here is the code relating to the updating... (I'm just calling the method in "onBlockActivated" for now just as a proof of concept)
Calling the method:
updateCircuitTextures((CarbonCondenser)world.getBlock(x, y, z), (TileEntityCarbonCondenser)world.getTileEntity(x, y, z), world, x, y, z);
Note- All of the code relating to change of texture is in the block class
The Method
{
CarbonCondenser condenser = block;
if (tileentity.getStackInSlot(4) != null)
{
if (tileentity.getStackInSlot(4).getItem() == Construct.circuitImport)
{
condenser.sTop = 1;
Minecraft.getMinecraft().renderGlobal.markBlockForRenderUpdate(x, y, z);
}
else if (tileentity.getStackInSlot(4).getItem() == Construct.circuitExport)
{
condenser.sTop = 2;
Minecraft.getMinecraft().renderGlobal.markBlockForRenderUpdate(x, y, z);
}
}
else
{
condenser.sTop = 0;
Minecraft.getMinecraft().renderGlobal.markBlockForRenderUpdate(x, y, z);
}
}
Note - I only have the top changing right now to keep the code simple while I iron out this probably simple problem.
How do I get it to individualize each carbon condenser?
Mod Author and Owner of Blockhole
Owner of other discontinued or status frozen work: LimpCraft2, LimpCore, InventoryCalculator, VillageTech, Bitto'Color.
I use the ClassName#memberName notation to refer to the instance method or field of ClassName called memberName. I use a dot instead of a hash when referring to a static method or field.
Don't store any information in your Block class unless it should be shared between all occurrences of that Block (only one instance of the class exists for each type of block). Use the metadata or the TileEntity to store information specific to an individual occurrence of the Block.
In Block#getIcon, use IBlockAccess#getTileEntity to get the TileEntity at the specified coordinates and then use it determine which circuit has been applied for the specified side.
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.
Awesome, kind of! I didn't even know you could replace the standard getIcon because eclipse was not finding the IBlockAccess version and I had to manually type it in before it recognized it. So pending I have all the data being stored appropriately inside the TileEntityCarbonCondenser class I have [it does, I've tested it with print statements], this is to replace the original .getIcon(int side, int meta) method inside my CarbonCondenser block class?
public IIcon getIcon(IBlockAccess block, int x, int y, int z, int side)
{
//Sets inventory icons
if (side == 3 && block.getBlockMetadata(x, y, z) == 0)
{
return this.sideFront;
}
if (side == block.getBlockMetadata(x, y, z))
{
return this.sideFront;
}
if (side != block.getBlockMetadata(x, y, z))
{
if (side == ((TileEntityCarbonCondenser)block.getTileEntity(x, y, z)).left)
{
if (((TileEntityCarbonCondenser)block.getTileEntity(x, y, z)).sLeft == 0)
{
return this.blockIcon;
}
else if (((TileEntityCarbonCondenser)block.getTileEntity(x, y, z)).sLeft == 1)
{
return this.sideImport;
}
else if (((TileEntityCarbonCondenser)block.getTileEntity(x, y, z)).sLeft == 2)
{
return this.sideExport;
}
}
}
return this.blockIcon;
}
I replaced it and the front and blank textures (.blockIcon) return correctly and are visible in game, however the circuit textures do not update at all. Did I place this in the right location?
EDIT- if the code is confusing, I use .sSide for a int between 0-2 which stores which texture to return, and I use .side as an int which gets the left, right, back, top, bottom orientation of the block compared to the direction it is facing, for easier upgrade placement.
http://pastebin.com/b5CQ80FY
Mod Author and Owner of Blockhole
Owner of other discontinued or status frozen work: LimpCraft2, LimpCore, InventoryCalculator, VillageTech, Bitto'Color.
Also, to note for anyone who uses this article: Don't replace the .getIcon method, but instead just add in your block class the second one. In your regular .getIcon method, you need this for the inventory to load correctly (it appears the .getIcon with IBlockAccess overwrites it in game but not in the inventory)
@Override
public IIcon getIcon(int side, int meta)
{
// Sets inventory icons
if (side == 3 && meta == 0)
{
return this.sideFront;
}
else
{
return this.blockIcon;
}
}
EDIT**
http://pastebin.com/b5CQ80FY
My problem right now is solely rendering the changed sides. I have print statemented and even programmed the check if import or export for the hopper. Everything works fine. The textures just don't get updated at all on the block, but block.getBlockMetadata(x,y,z) DOES work because it updates the front and the blank sides. But when I put in items into the slots, it however, does not update the sides. I have checked where I store the side data and it DOES indeed work, so it is a rendering issue.
Mod Author and Owner of Blockhole
Owner of other discontinued or status frozen work: LimpCraft2, LimpCore, InventoryCalculator, VillageTech, Bitto'Color.
Try using World#markBlockForUpdate in the TileEntity when the circuits change. This should trigger a rendering update on the client.
You may also need to override TileEntity#getDescriptionPacket and TileEntity#onDataPacket to write to NBT on the server, send it to the client and then read it back on the client. I don't know very much about the networking system, but Chisel has an example using the vanilla update packet 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.
Thank you Choonster for all you have done, but it seems I still am having issues even after looking at the chisel packet stuff and this website on the exact same methods:
http://cazzar.net/tutorials/minecraft/Tile-Entity-Updates-The-Quick-and-Dirty-Method/
(Note - changing the 0 to a 1 in the return new S35PacketUpdateTileEntity(xCoord, yCoord, zCoord, 0, tag) does not work)
Here is what I have coded for the updating of the texture, if anyone else knows something about packets and getting this to work, it would be much appreciated!
Tile Entity - http://pastebin.com/WgqyHKu1
Block - http://pastebin.com/NtVFEDZ8
Mod Author and Owner of Blockhole
Owner of other discontinued or status frozen work: LimpCraft2, LimpCore, InventoryCalculator, VillageTech, Bitto'Color.
Thank you so much Choonster, you really pointed me in the right direction with that last post. The packet update is exactly what I needed. I had it implemented correctly, and it doesn't work without it, I just completely forgot to save my integers for the circuit sides in the NBT and load them. I'm really shaking my head for overlooking that part. But it still wouldn't have worked without you pointing me toward that packet trick from the Chisel2 mod and causing me to find that other article. Hopefully this helps others in the future. I do have 1 other slight problem, but I will post that in a new thread. It's related but kind of different.
Mod Author and Owner of Blockhole
Owner of other discontinued or status frozen work: LimpCraft2, LimpCore, InventoryCalculator, VillageTech, Bitto'Color.