hugo_the_dwarf Posted August 7, 2014 Posted August 7, 2014 I'm trying to make a device that will slowly charge up and change it's physical appearance based on its current charge. However when it gets above a certain threshold (around 30 - 45) it messes up changing the blocks metadata and it's own charge resets to 0, then back again, it's just a mess. Block public class BlockItemGen extends BlockContainer { public BlockItemGen() { super(Material.iron); setHardness(5f); setResistance(10f); } private IIcon[] icons = new IIcon[8]; @Override public TileEntity createNewTileEntity(World var1, int var2) { return new TileEntityItemGenerator(); } @Override public int onBlockPlaced(World p_149660_1_, int p_149660_2_, int p_149660_3_, int p_149660_4_, int p_149660_5_, float p_149660_6_, float p_149660_7_, float p_149660_8_, int p_149660_9_) { return super.onBlockPlaced(p_149660_1_, p_149660_2_, p_149660_3_, p_149660_4_, p_149660_5_, p_149660_6_, p_149660_7_, p_149660_8_, 7); } @Override @SideOnly(Side.CLIENT) public void registerBlockIcons(IIconRegister ir) { for (int i = 0; i < icons.length;i++) { icons[i] = ir.registerIcon(Rot.MODID+":"+"itemGen_"+i+"_8"); } } @Override @SideOnly(Side.CLIENT) public IIcon getIcon(int p_149691_1_, int p_149691_2_) { if (p_149691_2_ >= 0 && p_149691_2_ <= 7) return icons[p_149691_2_]; else return icons[0]; } @Override public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int side, float hitX, float hitY, float hitZ) { if(!world.isRemote) { //FMLNetworkHandler.openGui(player, Main.instance, 0, world, x, y, z); } return true; } } TileEntity public class TileEntityItemGenerator extends TileEntity { private int MANA_CD = 55; private int ACTION_CD = 25; private int cd1 = ACTION_CD; private int cd2 = MANA_CD; private float mana = 0; private float manaCap = 160; private float manaCost = 45.5f; private int range = 7; private int flag = 3; private boolean updateBlock = true; @Override public void writeToNBT(NBTTagCompound nbtTag) { //super.writeToNBT(nbtTag); nbtTag.setFloat("itemGenMana", mana); nbtTag.setInteger("itemGenCd1", cd1); nbtTag.setInteger("itemGenCd2", cd2); } @Override public void readFromNBT(NBTTagCompound nbtTag) { //super.readFromNBT(nbtTag); mana = nbtTag.getFloat("itemGenMana"); cd1 = nbtTag.getInteger("itemGenCd1"); cd2 = nbtTag.getInteger("itemGenCd2"); } @Override public boolean canUpdate() { return true; } @Override public void updateEntity() { if (cd2 == 0 && mana <= manaCap) { cd2 = MANA_CD; if (mana < manaCap)mana += 5.2755f; float charge = ((mana / 2) / (80)) * 100; System.out.println("Charge: "+ charge); System.out.println("Mana: "+ mana+"/"+manaCap); updateBlock = true; if (charge >= 87.5 && getWorldObj().getBlockMetadata(xCoord, yCoord, zCoord) != 0 && updateBlock) { getWorldObj().setBlockMetadataWithNotify(xCoord, yCoord, zCoord, 0, flag); updateBlock = false; } else if(charge >= 75 && getWorldObj().getBlockMetadata(xCoord, yCoord, zCoord) != 1 && updateBlock) { getWorldObj().setBlockMetadataWithNotify(xCoord, yCoord, zCoord, 1, flag); updateBlock = false; } else if(charge >= 62.5 && getWorldObj().getBlockMetadata(xCoord, yCoord, zCoord) != 2 && updateBlock) { getWorldObj().setBlockMetadataWithNotify(xCoord, yCoord, zCoord, 2, flag); updateBlock = false; } else if(charge >= 50 && getWorldObj().getBlockMetadata(xCoord, yCoord, zCoord) != 3 && updateBlock) { getWorldObj().setBlockMetadataWithNotify(xCoord, yCoord, zCoord, 3, flag); updateBlock = false; } else if(charge >= 37.5 && getWorldObj().getBlockMetadata(xCoord, yCoord, zCoord) != 4 && updateBlock) { getWorldObj().setBlockMetadataWithNotify(xCoord, yCoord, zCoord, 4, flag); updateBlock = false; } else if(charge >= 25 && getWorldObj().getBlockMetadata(xCoord, yCoord, zCoord) != 5 && updateBlock) { getWorldObj().setBlockMetadataWithNotify(xCoord, yCoord, zCoord, 5, flag); updateBlock = false; } else if(charge >= 12.5 && getWorldObj().getBlockMetadata(xCoord, yCoord, zCoord) != 6 && updateBlock) { getWorldObj().setBlockMetadataWithNotify(xCoord, yCoord, zCoord, 6, flag); updateBlock = false; } else if(charge < 12.5 && getWorldObj().getBlockMetadata(xCoord, yCoord, zCoord) != 7 && updateBlock) { getWorldObj().setBlockMetadataWithNotify(xCoord, yCoord, zCoord, 7, flag); updateBlock = false; } System.out.println("----------"); } else cd2--; if (cd1 == 0) { if (mana >= manaCost) { cd1 = ACTION_CD; TileEntity te; for (int y = -range; y <= range; y++) { for (int x = -range; x <= range; x++) { for (int z = -range; z <= range; z++) { te = getWorldObj().getTileEntity(x + xCoord, y + yCoord, z + zCoord); if (te != null) { if (te instanceof TileEntityChest) { TileEntityChest tec = (TileEntityChest)te; for (int i = 0; i < tec.getSizeInventory(); i++) { if (tec.getStackInSlot(i) != null) { if (tec.getStackInSlot(i).stackSize < tec.getStackInSlot(i).getMaxStackSize()) { tec.getStackInSlot(i).stackSize++; mana -= manaCost; } if (tec.getStackInSlot(i).isItemDamaged()) { tec.getStackInSlot(i).setItemDamage(tec.getStackInSlot(i).getItemDamage() -1); mana -= 5f; } if (mana < manaCost)return; } } } } } } } } } else cd1--; } } Did I define them wrong? making the updates in the wrong places? Quote Currently updating my Mod to 1.10.2 https://bitbucket.org/hugo_the_dwarf/riseoftristram2016/src?at=master
hugo_the_dwarf Posted August 8, 2014 Author Posted August 8, 2014 Has how tileEntites work changed drastically since 1.6.4? Quote Currently updating my Mod to 1.10.2 https://bitbucket.org/hugo_the_dwarf/riseoftristram2016/src?at=master
jabelar Posted August 8, 2014 Posted August 8, 2014 In your tile entity, the if statements are suspiciously complicated. First of all I don't think you need to test what the metadata is in the if statements. It is okay to set the meta data even if it is already the same value. Perhaps you think it is better for performance but you're actually adding performance burden by testing for it before you know if you write it. In other words, writing it every time isn't any more burden than checking it every time. You should also be able to get rid of the whole updateBlock flag as well. The if else construct won't proceed to the else once it finds a true, and since you test for highest values first it should never fall through to the next one anyway. Next, since your meta test values are all 12.5 apart, you don't need any if statements at all! You can just set the metadata to be = 7 - charge / 12.5 (although you have to also round it and ensure it doesn't go below 0). So I think you can replace all that first part of your updateEntity() method with: if (cd2 == 0 && mana <= manaCap) { cd2 = MANA_CD; if (mana < manaCap)mana += 5.2755f; float charge = ((mana / 2) / (80)) * 100; System.out.println("Charge: "+ charge); System.out.println("Mana: "+ mana+"/"+manaCap); int metaData = (int) (7 - charge / 12.5); if (metaData < 0) { metaData = 0; } System.out.println("Metadatra: "+ metaData); getWorldObj().setBlockMetadataWithNotify(xCoord, yCoord, zCoord, metaData, flag); System.out.println("----------"); } else cd2--; Notice that I've also printed out the metadata value. I think it would be interesting to see if the console prints out the value you expect. If it doesn't print at all, then it means that the if statement isn't testing true. I'm not really sure what your cd2 and cd1 are supposed to represent, and I'm suspicious that there is still some logical error there. But anyway, simplify the code such as I explained above -- simpler code is easier to debug. And post the console output so we can understand which code paths are occurring. Quote Check out my tutorials here: http://jabelarminecraft.blogspot.com/
hugo_the_dwarf Posted August 8, 2014 Author Posted August 8, 2014 Ah that makes it easier, the reason why I had all those complicated else ifs (would have used a switch, but your way is much more compact and efficient), if you are wondering why I have cd1 & cd 2 (cooldown 1 and 2) is entities update every tick which is what, 100 ticks a second if not more or less. And this tileEntity looks for chests in a range (triple for loops) to try to increase or repair itemstacks (can see this being a issue with other mods the repair that is) and since it searches in a wide range and I'm thinking of server wise where there can be many players making many of these and I can see the system getting bogged down with 20+ entities updating every tick (lets say 100 per second) and that there are 30 entities. I'm sure the overhead will get over the top if 30 * 100 * (14 * 14 * 6), unless these run fairly low budget I just don't want these things to kill a server (PvP, Team Mod) Also watching my console I get this: Charge: 27.614689 Mana: 44.183502/160.0 Metadata: 4 ---------- Charge: 29.674688 Mana: 47.4795/160.0 Metadata: 4 ---------- now it's all fine and dandy, but this is from one update (only one entity in exsistance) it double updated, not only that I think the "writeNBT" is going nuts and activating randomly (which I think it should be doing?) it's also reading too, and for some reason it keeps resetting it's values (mana = 0, cd's) not only that it's also making its texture mess up (switching from one to the other meta instantly twice in one go) What the heck did I do? Quote Currently updating my Mod to 1.10.2 https://bitbucket.org/hugo_the_dwarf/riseoftristram2016/src?at=master
hugo_the_dwarf Posted August 9, 2014 Author Posted August 9, 2014 Fixed it, somehow the client was getting a version of the tileEntity messing it (update server, update client. Different values) so I just made the update work with (!getWorldObj.isRemote) and now renders fine with changing the textures. Thank you Jabelar for the code shortener. Quote Currently updating my Mod to 1.10.2 https://bitbucket.org/hugo_the_dwarf/riseoftristram2016/src?at=master
Recommended Posts
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.