package net.minecraft.tileentity;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import net.minecraft.block.Block;
import net.minecraft.block.TileEntityRecordPlayer;
import net.minecraft.crash.CrashReportCategory;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.INetworkManager;
import net.minecraft.network.packet.Packet;
import net.minecraft.network.packet.Packet132TileEntityData;
import net.minecraft.world.World;
public class TileEntity
{
/**
* A HashMap storing string names of classes mapping to the actual java.lang.Class type.
*/
private static Map nameToClassMap = new HashMap();
/**
* A HashMap storing the classes and mapping to the string names (reverse of nameToClassMap).
*/
private static Map classToNameMap = new HashMap();
/** The reference to the world. */
public World worldObj;
/** The x coordinate of the tile entity. */
public int xCoord;
/** The y coordinate of the tile entity. */
public int yCoord;
/** The z coordinate of the tile entity. */
public int zCoord;
protected boolean tileEntityInvalid;
public int blockMetadata = -1;
/** the Block type that this TileEntity is contained within */
public Block blockType;
/**
* Adds a new two-way mapping between the class and its string name in both hashmaps.
*/
public static void addMapping(Class par0Class, String par1Str)
{
if (nameToClassMap.containsKey(par1Str))
{
throw new IllegalArgumentException("Duplicate id: " + par1Str);
}
else
{
nameToClassMap.put(par1Str, par0Class);
classToNameMap.put(par0Class, par1Str);
}
}
@SideOnly(Side.CLIENT)
/**
* Returns the worldObj for this tileEntity.
*/
public World getWorldObj()
{
return this.worldObj;
}
/**
* Sets the worldObj for this tileEntity.
*/
public void setWorldObj(World par1World)
{
this.worldObj = par1World;
}
public boolean func_70309_m()
{
return this.worldObj != null;
}
/**
* Reads a tile entity from NBT.
*/
public void readFromNBT(NBTTagCompound par1NBTTagCompound)
{
this.xCoord = par1NBTTagCompound.getInteger("x");
this.yCoord = par1NBTTagCompound.getInteger("y");
this.zCoord = par1NBTTagCompound.getInteger("z");
}
/**
* Writes a tile entity to NBT.
*/
public void writeToNBT(NBTTagCompound par1NBTTagCompound)
{
String var2 = (String)classToNameMap.get(this.getClass());
if (var2 == null)
{
throw new RuntimeException(this.getClass() + " is missing a mapping! This is a bug!");
}
else
{
par1NBTTagCompound.setString("id", var2);
par1NBTTagCompound.setInteger("x", this.xCoord);
par1NBTTagCompound.setInteger("y", this.yCoord);
par1NBTTagCompound.setInteger("z", this.zCoord);
}
}
/**
* Allows the entity to update its state. Overridden in most subclasses, e.g. the mob spawner uses this to count
* ticks and creates a new spawn inside its implementation.
*/
public void updateEntity() {}
/**
* Creates a new entity and loads its data from the specified NBT.
*/
public static TileEntity createAndLoadEntity(NBTTagCompound par0NBTTagCompound)
{
TileEntity var1 = null;
Class var2 = null;
try
{
var2 = (Class)nameToClassMap.get(par0NBTTagCompound.getString("id"));
if (var2 != null)
{
var1 = (TileEntity)var2.newInstance();
}
}
catch (Exception var3)
{
var3.printStackTrace();
}
if (var1 != null)
{
try
{
var1.readFromNBT(par0NBTTagCompound);
}
catch (Exception e)
{
FMLLog.log(Level.SEVERE, e,
"A TileEntity %s(%s) has thrown an exception during loading, its state cannot be restored. Report this to the mod author",
par0NBTTagCompound.getString("id"), var2.getName());
var1 = null;
}
}
else
{
System.out.println("Skipping TileEntity with id " + par0NBTTagCompound.getString("id"));
}
return var1;
}
/**
* Returns block data at the location of this entity (client-only).
*/
public int getBlockMetadata()
{
if (this.blockMetadata == -1)
{
this.blockMetadata = this.worldObj.getBlockMetadata(this.xCoord, this.yCoord, this.zCoord);
}
return this.blockMetadata;
}
/**
* Called when an the contents of an Inventory change, usually
*/
public void onInventoryChanged()
{
if (this.worldObj != null)
{
this.blockMetadata = this.worldObj.getBlockMetadata(this.xCoord, this.yCoord, this.zCoord);
this.worldObj.updateTileEntityChunkAndDoNothing(this.xCoord, this.yCoord, this.zCoord, this);
}
}
@SideOnly(Side.CLIENT)
/**
* Returns the square of the distance between this entity and the passed in coordinates.
*/
public double getDistanceFrom(double par1, double par3, double par5)
{
double var7 = (double)this.xCoord + 0.5D - par1;
double var9 = (double)this.yCoord + 0.5D - par3;
double var11 = (double)this.zCoord + 0.5D - par5;
return var7 * var7 + var9 * var9 + var11 * var11;
}
@SideOnly(Side.CLIENT)
public double func_82115_m()
{
return 4096.0D;
}
/**
* Gets the block type at the location of this entity (client-only).
*/
public Block getBlockType()
{
if (this.blockType == null)
{
this.blockType = Block.blocksList[this.worldObj.getBlockId(this.xCoord, this.yCoord, this.zCoord)];
}
return this.blockType;
}
/**
* Overriden in a sign to provide the text.
*/
public Packet getDescriptionPacket()
{
return null;
}
/**
* returns true if tile entity is invalid, false otherwise
*/
public boolean isInvalid()
{
return this.tileEntityInvalid;
}
/**
* invalidates a tile entity
*/
public void invalidate()
{
this.tileEntityInvalid = true;
}
/**
* validates a tile entity
*/
public void validate()
{
this.tileEntityInvalid = false;
}
/**
* Called when a client event is received with the event number and argument, see World.sendClientEvent
*/
public void receiveClientEvent(int par1, int par2) {}
/**
* Causes the TileEntity to reset all it's cached values for it's container block, blockID, metaData and in the case
* of chests, the adjcacent chest check
*/
public void updateContainingBlockInfo()
{
this.blockType = null;
this.blockMetadata = -1;
}
public void func_85027_a(CrashReportCategory par1CrashReportCategory)
{
par1CrashReportCategory.addCrashSectionCallable("Name", new CallableTileEntityName(this));
CrashReportCategory.func_85068_a(par1CrashReportCategory, this.xCoord, this.yCoord, this.zCoord, this.blockType != null ? this.blockType.blockID : 0, this.blockMetadata);
}
static Map func_85028_t()
{
return classToNameMap;
}
static
{
addMapping(TileEntityFurnace.class, "Furnace");
addMapping(TileEntityChest.class, "Chest");
addMapping(TileEntityEnderChest.class, "EnderChest");
addMapping(TileEntityRecordPlayer.class, "RecordPlayer");
addMapping(TileEntityDispenser.class, "Trap");
addMapping(TileEntitySign.class, "Sign");
addMapping(TileEntityMobSpawner.class, "MobSpawner");
addMapping(TileEntityNote.class, "Music");
addMapping(TileEntityPiston.class, "Piston");
addMapping(TileEntityBrewingStand.class, "Cauldron");
addMapping(TileEntityEnchantmentTable.class, "EnchantTable");
addMapping(TileEntityEndPortal.class, "Airportal");
addMapping(TileEntityCommandBlock.class, "Control");
addMapping(TileEntityBeacon.class, "Beacon");
addMapping(TileEntitySkull.class, "Skull");
}
/**
* Determines if this TileEntity requires update calls.
* @return True if you want updateEntity() to be called, false if not
*/
public boolean canUpdate()
{
return true;
}
/**
* Called when you receive a TileEntityData packet for the location this
* TileEntity is currently in. On the client, the NetworkManager will always
* be the remote server. On the server, it will be whomever is responsible for
* sending the packet.
*
* @param net The NetworkManager the packet originated from
* @param pkt The data packet
*/
public void onDataPacket(INetworkManager net, Packet132TileEntityData pkt)
{
}
/**
* Called when the chunk this TileEntity is on is Unloaded.
*/
public void onChunkUnload()
{
}
/**
* Called from Chunk.setBlockIDWithMetadata, determines if this tile entity should be re-created when the ID, or Metadata changes.
* Use with caution as this will leave straggler TileEntities, or create conflicts with other TileEntities if not used properly.
*
* @param oldID The old ID of the block
* @param newID The new ID of the block (May be the same)
* @param oldMeta The old metadata of the block
* @param newMeta The new metadata of the block (May be the same)
* @param world Current world
* @param x X Postion
* @param y Y Position
* @param z Z Position
* @return True to remove the old tile entity, false to keep it in tact {and create a new one if the new values specify to}
*/
public boolean shouldRefresh(int oldID, int newID, int oldMeta, int newMeta, World world, int x, int y, int z)
{
return true;
}
}