Jump to content

Recommended Posts

Posted

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 !

Posted

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)

Posted

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]

Posted

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

Posted

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.

Posted

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.

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.