Posted May 22, 201510 yr Hello every body ! I have a problem with my custom door : when i right click on it (and open/close the door) it seems the attached tile entity is destroyed and respawn so it delete all the data saved in it... I don't know what to do... Here is my custom door block code public class ProtectedDoor extends BlockDoor implements ITileEntityProvider{ private final String name = "ProtectedDoor"; public ProtectedDoor() { super(Material.wood); GameRegistry.registerBlock(this, name); setUnlocalizedName(Test.MODID + "_" + name); setHardness(3f); setResistance(20f); setHarvestLevel("axe", 2); // TODO Auto-generated constructor stub } public String getName() { return name; } @Override public void onBlockClicked(World worldIn, BlockPos pos, EntityPlayer playerIn) { if(!worldIn.isRemote) { IBlockState state = worldIn.getBlockState(pos); BlockPos blockpos1 = state.getValue(HALF) == BlockDoor.EnumDoorHalf.LOWER ? pos : pos.down(); ProtectedTileEntity t = (ProtectedTileEntity) worldIn.getTileEntity(new BlockPos(blockpos1)); if(t != null) { t.setDatas(playerIn, worldIn); } } super.onBlockClicked(worldIn, pos, playerIn); } @Override public boolean onBlockActivated(World worldIn, BlockPos pos, IBlockState state, EntityPlayer playerIn, EnumFacing side, float hitX, float hitY, float hitZ) { BlockPos blockpos1 = state.getValue(HALF) == BlockDoor.EnumDoorHalf.LOWER ? pos : pos.down(); IBlockState iblockstate1 = pos.equals(blockpos1) ? state : worldIn.getBlockState(blockpos1); if (iblockstate1.getBlock() != this) { return false; } else { state = iblockstate1.cycleProperty(OPEN); ProtectedTileEntity t = (ProtectedTileEntity) worldIn.getTileEntity(new BlockPos(blockpos1)); if(t != null) { if(t.TryToOpen(playerIn, !((Boolean)state.getValue(OPEN)).booleanValue())) { worldIn.setBlockState(blockpos1, state, 2); worldIn.markBlockRangeForRenderUpdate(blockpos1, pos); worldIn.playAuxSFXAtEntity(playerIn, ((Boolean)state.getValue(OPEN)).booleanValue() ? 1003 : 1006, pos, 0); return true; } } } return false; } @Override @SideOnly(Side.CLIENT) public Item getItem(World worldIn, BlockPos pos) { return Item.getByNameOrId("shuyintestmod:"+ItemProtectedDoor.getName()); } @Override public Item getItemDropped(IBlockState state, Random rand, int fortune) { return state.getValue(HALF) == BlockDoor.EnumDoorHalf.UPPER ? null : Item.getByNameOrId("shuyintestmod:"+ItemProtectedDoor.getName()); } @Override public TileEntity createNewTileEntity(World worldIn, int meta) { // TODO Auto-generated method stub return new ProtectedTileEntity(); } } And my custom tile entity public class ProtectedTileEntity extends TileEntity{ private String owner=""; private String password=""; private int UUID = (new Random()).nextInt(10000); @Override public Packet getDescriptionPacket() { NBTTagCompound tagCompound = new NBTTagCompound(); newWriteNBT(tagCompound); return new net.minecraft.network.play.server.S35PacketUpdateTileEntity(this.pos, 1, tagCompound); } @Override public void onDataPacket(net.minecraft.network.NetworkManager net, net.minecraft.network.play.server.S35PacketUpdateTileEntity pkt) { newReadNBT(pkt.getNbtCompound()); } public void setDatas(EntityPlayer player, World world) { if(this.owner.equals("")) { this.owner = player.getDisplayNameString(); player.addChatMessage(new ChatComponentText("Proprietaire de la porte : " + this.owner)); world.markBlockForUpdate(pos); } if(player.inventory.getCurrentItem() != null) { ItemStack key = player.inventory.getCurrentItem(); if(key.getItem() instanceof MetalKey) { if(player.isSneaking() && player.getDisplayNameString().equals(owner)) { this.password = key.getDisplayName(); player.addChatMessage(new ChatComponentText("La serrure a ete changee : " + this.password)); world.markBlockForUpdate(pos); } } } } public boolean TryToOpen(EntityPlayer player, boolean open) { boolean creative = player.capabilities.isCreativeMode; boolean mauvaiseCle = false; if(player.inventory.getCurrentItem() != null) { ItemStack key = player.inventory.getCurrentItem(); if(key.getItem() instanceof MetalKey) { if(key.getDisplayName().equals(password)) { return true; } else { mauvaiseCle = true; } } } player.addChatMessage(new ChatComponentText("Proprietaire : " + this.owner + ", mdp : " + this.UUID)); if(password == "") return true; if(creative || open){ return true; } else{ if(!mauvaiseCle) player.addChatMessage(new ChatComponentText("La porte est fermee !")); else player.addChatMessage(new ChatComponentText("Ce n'est pas la bonne cle !")); return false; } } @Override public void readFromNBT(NBTTagCompound nbt) { super.readFromNBT(nbt); newReadNBT(nbt); System.out.println("reading protected datas : " + this.owner + " | " + this.password); } public void newWriteNBT(NBTTagCompound nbt) { nbt.setString("Owner", owner); nbt.setString("Password", password); } public void newReadNBT(NBTTagCompound nbt) { this.owner = nbt.getString("Owner"); this.password = nbt.getString("Password"); } @Override public void writeToNBT(NBTTagCompound nbt) { super.writeToNBT(nbt); newWriteNBT(nbt); System.out.println("saving protected datas : " + this.owner + " | " + this.password); } } If you find some mistake not in relation with my problem, don't hesitate to tell me about it ! Thanks in advance !
May 22, 201510 yr Author Okay, I didn't know this method ever exists ! I'll try this when I can ! Thanks !
May 23, 201510 yr Author So... It works very good ! thanks a lot ! I just have a problem with the playAuxSFXAtEntity which does not work server side... is there an equivalent ? (It will permit me to avoid using nbt synchronization between the client and the server tiles)
May 23, 201510 yr Author OKay, I understand now ! Thank you very much ! Here is the method I added in the custom tile entity as suggested from diesieben07: @Override public boolean shouldRefresh(World world, BlockPos pos, IBlockState oldState, IBlockState newSate) { if(newSate.getBlock() instanceof ProtectedDoor) { return false; } return true; } [/Code]
May 23, 201510 yr By default TileEntities are recreated even when metadata changes. To change this behavior override shouldRefresh in your TileEntity. In there you need to return if the change that occurred should cause your TE to be re-created (or deleted, if the new block/meta combo doesn't have a TileEntity anymore). In your case you'd probably always return false unless the new block is now different (this is important, otherwise your old TileEntity is never removed). This seems odd, since this behavior is exactly opposite of vanilla tile entities: public boolean shouldRefresh(World world, BlockPos pos, IBlockState oldState, IBlockState newState) { return !isVanilla || (oldState.getBlock() != newState.getBlock()); } What is the reasoning behind this choice of implementation? I would think that the majority of modded tile entities are modeled after vanilla tile entities in one way or another and would benefit just as much from having their data maintained by default. Would creating a 'base' mod TE class that overrides this to return just the getBlock() check have adverse consequences of some sort? What are some scenarios when one might want to re-create / destroy the tile entity? (should I ask this in a separate thread?) http://i.imgur.com/NdrFdld.png[/img]
May 24, 201510 yr The reasoning behind this is (probably) that many Mods use metadata for completely different Blocks (like different types of machines for example). One could argue for both sides, but one needs to be the default. Yes, I suppose one could. I would argue for maintaining vanilla behavior as the default, so modders know what to expect rather than having nasty surprises, but that's just my opinion. Glad I saw this topic or I would have no doubt been scratching my head later on down the road. http://i.imgur.com/NdrFdld.png[/img]
May 24, 201510 yr I would have to agree with coolAlias. 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.
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.