    001    package net.minecraft.src;
    002
    003    import cpw.mods.fml.common.Side;
    004    import cpw.mods.fml.common.asm.SideOnly;
    005    import java.util.HashMap;
    006    import java.util.Map;
    007
    008    public class TileEntity
    009    {
    010        /**
    011         * A HashMap storing string names of classes mapping to the actual java.lang.Class type.
    012         */
    013        private static Map nameToClassMap = new HashMap();
    014
    015        /**
    016         * A HashMap storing the classes and mapping to the string names (reverse of nameToClassMap).
    017         */
    018        private static Map classToNameMap = new HashMap();
    019
    020        /** The reference to the world. */
    021        public World worldObj;
    022
    023        /** The x coordinate of the tile entity. */
    024        public int xCoord;
    025
    026        /** The y coordinate of the tile entity. */
    027        public int yCoord;
    028
    029        /** The z coordinate of the tile entity. */
    030        public int zCoord;
    031        protected boolean tileEntityInvalid;
    032        public int blockMetadata = -1;
    033
    034        /** the Block type that this TileEntity is contained within */
    035        public Block blockType;
    036
    037        /**
    038         * Adds a new two-way mapping between the class and its string name in both hashmaps.
    039         */
    040        public static void addMapping(Class par0Class, String par1Str)
    041        {
    042            if (nameToClassMap.containsKey(par1Str))
    043            {
    044                throw new IllegalArgumentException("Duplicate id: " + par1Str);
    045            }
    046            else
    047            {
    048                nameToClassMap.put(par1Str, par0Class);
    049                classToNameMap.put(par0Class, par1Str);
    050            }
    051        }
    052
    053        /**
    054         * Sets the worldObj for this tileEntity.
    055         */
    056        public void setWorldObj(World par1World)
    057        {
    058            this.worldObj = par1World;
    059        }
    060
    061        @SideOnly(Side.CLIENT)
    062
    063        /**
    064         * Returns the worldObj for this tileEntity.
    065         */
    066        public World getWorldObj()
    067        {
    068            return this.worldObj;
    069        }
    070
    071        public boolean func_70309_m()
    072        {
    073            return this.worldObj != null;
    074        }
    075
    076        /**
    077         * Reads a tile entity from NBT.
    078         */
    079        public void readFromNBT(NBTTagCompound par1NBTTagCompound)
    080        {
    081            this.xCoord = par1NBTTagCompound.getInteger("x");
    082            this.yCoord = par1NBTTagCompound.getInteger("y");
    083            this.zCoord = par1NBTTagCompound.getInteger("z");
    084        }
    085
    086        /**
    087         * Writes a tile entity to NBT.
    088         */
    089        public void writeToNBT(NBTTagCompound par1NBTTagCompound)
    090        {
    091            String var2 = (String)classToNameMap.get(this.getClass());
    092
    093            if (var2 == null)
    094            {
    095                throw new RuntimeException(this.getClass() + " is missing a mapping! This is a bug!");
    096            }
    097            else
    098            {
    099                par1NBTTagCompound.setString("id", var2);
    100                par1NBTTagCompound.setInteger("x", this.xCoord);
    101                par1NBTTagCompound.setInteger("y", this.yCoord);
    102                par1NBTTagCompound.setInteger("z", this.zCoord);
    103            }
    104        }
    105
    106        /**
    107         * Allows the entity to update its state. Overridden in most subclasses, e.g. the mob spawner uses this to count
    108         * ticks and creates a new spawn inside its implementation.
    109         */
    110        public void updateEntity() {}
    111
    112        /**
    113         * Creates a new entity and loads its data from the specified NBT.
    114         */
    115        public static TileEntity createAndLoadEntity(NBTTagCompound par0NBTTagCompound)
    116        {
    117            TileEntity var1 = null;
    118
    119            try
    120            {
    121                Class var2 = (Class)nameToClassMap.get(par0NBTTagCompound.getString("id"));
    122
    123                if (var2 != null)
    124                {
    125                    var1 = (TileEntity)var2.newInstance();
    126                }
    127            }
    128            catch (Exception var3)
    129            {
    130                var3.printStackTrace();
    131            }
    132
    133            if (var1 != null)
    134            {
    135                var1.readFromNBT(par0NBTTagCompound);
    136            }
    137            else
    138            {
    139                System.out.println("Skipping TileEntity with id " + par0NBTTagCompound.getString("id"));
    140            }
    141
    142            return var1;
    143        }
    144
    145        /**
    146         * Returns block data at the location of this entity (client-only).
    147         */
    148        public int getBlockMetadata()
    149        {
    150            if (this.blockMetadata == -1)
    151            {
    152                this.blockMetadata = this.worldObj.getBlockMetadata(this.xCoord, this.yCoord, this.zCoord);
    153            }
    154
    155            return this.blockMetadata;
    156        }
    157
    158        /**
    159         * Called when an the contents of an Inventory change, usually
    160         */
    161        public void onInventoryChanged()
    162        {
    163            if (this.worldObj != null)
    164            {
    165                this.blockMetadata = this.worldObj.getBlockMetadata(this.xCoord, this.yCoord, this.zCoord);
    166                this.worldObj.updateTileEntityChunkAndDoNothing(this.xCoord, this.yCoord, this.zCoord, this);
    167            }
    168        }
    169
    170        @SideOnly(Side.CLIENT)
    171
    172        /**
    173         * Returns the square of the distance between this entity and the passed in coordinates.
    174         */
    175        public double getDistanceFrom(double par1, double par3, double par5)
    176        {
    177            double var7 = (double)this.xCoord + 0.5D - par1;
    178            double var9 = (double)this.yCoord + 0.5D - par3;
    179            double var11 = (double)this.zCoord + 0.5D - par5;
    180            return var7 * var7 + var9 * var9 + var11 * var11;
    181        }
    182
    183        @SideOnly(Side.CLIENT)
    184
    185        /**
    186         * Gets the block type at the location of this entity (client-only).
    187         */
    188        public Block getBlockType()
    189        {
    190            if (this.blockType == null)
    191            {
    192                this.blockType = Block.blocksList[this.worldObj.getBlockId(this.xCoord, this.yCoord, this.zCoord)];
    193            }
    194
    195            return this.blockType;
    196        }
    197
    198        /**
    199         * Overriden in a sign to provide the text.
    200         */
    201        public Packet getDescriptionPacket()
    202        {
    203            return null;
    204        }
    205
    206        /**
    207         * returns true if tile entity is invalid, false otherwise
    208         */
    209        public boolean isInvalid()
    210        {
    211            return this.tileEntityInvalid;
    212        }
    213
    214        /**
    215         * invalidates a tile entity
    216         */
    217        public void invalidate()
    218        {
    219            this.tileEntityInvalid = true;
    220        }
    221
    222        /**
    223         * validates a tile entity
    224         */
    225        public void validate()
    226        {
    227            this.tileEntityInvalid = false;
    228        }
    229
    230        /**
    231         * Called when a client event is received with the event number and argument, see World.sendClientEvent
    232         */
    233        public void receiveClientEvent(int par1, int par2) {}
    234
    235        /**
    236         * Causes the TileEntity to reset all it's cached values for it's container block, blockID, metaData and in the case
    237         * of chests, the adjcacent chest check
    238         */
    239        public void updateContainingBlockInfo()
    240        {
    241            this.blockType = null;
    242            this.blockMetadata = -1;
    243        }
    244
    245        static
    246        {
    247            addMapping(TileEntityFurnace.class, "Furnace");
    248            addMapping(TileEntityChest.class, "Chest");
    249            addMapping(TileEntityEnderChest.class, "EnderChest");
    250            addMapping(TileEntityRecordPlayer.class, "RecordPlayer");
    251            addMapping(TileEntityDispenser.class, "Trap");
    252            addMapping(TileEntitySign.class, "Sign");
    253            addMapping(TileEntityMobSpawner.class, "MobSpawner");
    254            addMapping(TileEntityNote.class, "Music");
    255            addMapping(TileEntityPiston.class, "Piston");
    256            addMapping(TileEntityBrewingStand.class, "Cauldron");
    257            addMapping(TileEntityEnchantmentTable.class, "EnchantTable");
    258            addMapping(TileEntityEndPortal.class, "Airportal");
    259        }
    260
    261        /**
    262         * Determines if this TileEntity requires update calls.
    263         * @return True if you want updateEntity() to be called, false if not
    264         */
    265        public boolean canUpdate()
    266        {
    267            return true;
    268        }
    269
    270        /**
    271         * Called when you receive a TileEntityData packet for the location this
    272         * TileEntity is currently in. On the client, the NetworkManager will always
    273         * be the remote server. On the server, it will be whomever is responsible for
    274         * sending the packet.
    275         *
    276         * @param net The NetworkManager the packet originated from
    277         * @param pkt The data packet
    278         */
    279        public void onDataPacket(NetworkManager net, Packet132TileEntityData pkt)
    280        {
    281        }
    282
    283        /**
    284         * Called when the chunk this TileEntity is on is Unloaded.
    285         */
    286        public void onChunkUnload()
    287        {
    288        }
    289
    290        /**
    291         *  @return The maximum distance between the player and the TileEntity at which the TileEntitySpecialRenderer will be called
    292         */
    293        public double getRenderDistance()
    294        {
    295            return 64;
    296        }
    297    }