    001    package net.minecraft.tileentity;
    002
    003    import cpw.mods.fml.common.Side;
    004    import cpw.mods.fml.common.asm.SideOnly;
    005    import java.util.ArrayList;
    006    import java.util.Iterator;
    007    import java.util.List;
    008    import net.minecraft.block.Block;
    009    import net.minecraft.entity.Entity;
    010    import net.minecraft.nbt.NBTTagCompound;
    011    import net.minecraft.util.AxisAlignedBB;
    012    import net.minecraft.util.Facing;
    013
    014    public class TileEntityPiston extends TileEntity
    015    {
    016        private int storedBlockID;
    017        private int storedMetadata;
    018
    019        /** the side the front of the piston is on */
    020        private int storedOrientation;
    021
    022        /** if this piston is extending or not */
    023        private boolean extending;
    024        private boolean shouldHeadBeRendered;
    025        private float progress;
    026
    027        /** the progress in (de)extending */
    028        private float lastProgress;
    029        private List pushedObjects = new ArrayList();
    030
    031        public TileEntityPiston() {}
    032
    033        public TileEntityPiston(int par1, int par2, int par3, boolean par4, boolean par5)
    034        {
    035            this.storedBlockID = par1;
    036            this.storedMetadata = par2;
    037            this.storedOrientation = par3;
    038            this.extending = par4;
    039            this.shouldHeadBeRendered = par5;
    040        }
    041
    042        public int getStoredBlockID()
    043        {
    044            return this.storedBlockID;
    045        }
    046
    047        /**
    048         * Returns block data at the location of this entity (client-only).
    049         */
    050        public int getBlockMetadata()
    051        {
    052            return this.storedMetadata;
    053        }
    054
    055        /**
    056         * Returns true if a piston is extending
    057         */
    058        public boolean isExtending()
    059        {
    060            return this.extending;
    061        }
    062
    063        /**
    064         * Returns the orientation of the piston as an int
    065         */
    066        public int getPistonOrientation()
    067        {
    068            return this.storedOrientation;
    069        }
    070
    071        @SideOnly(Side.CLIENT)
    072        public boolean shouldRenderHead()
    073        {
    074            return this.shouldHeadBeRendered;
    075        }
    076
    077        /**
    078         * Get interpolated progress value (between lastProgress and progress) given the fractional time between ticks as an
    079         * argument.
    080         */
    081        public float getProgress(float par1)
    082        {
    083            if (par1 > 1.0F)
    084            {
    085                par1 = 1.0F;
    086            }
    087
    088            return this.lastProgress + (this.progress - this.lastProgress) * par1;
    089        }
    090
    091        private void updatePushedObjects(float par1, float par2)
    092        {
    093            if (this.extending)
    094            {
    095                par1 = 1.0F - par1;
    096            }
    097            else
    098            {
    099                --par1;
    100            }
    101
    102            AxisAlignedBB var3 = Block.pistonMoving.getAxisAlignedBB(this.worldObj, this.xCoord, this.yCoord, this.zCoord, this.storedBlockID, par1, this.storedOrientation);
    103
    104            if (var3 != null)
    105            {
    106                List var4 = this.worldObj.getEntitiesWithinAABBExcludingEntity((Entity)null, var3);
    107
    108                if (!var4.isEmpty())
    109                {
    110                    this.pushedObjects.addAll(var4);
    111                    Iterator var5 = this.pushedObjects.iterator();
    112
    113                    while (var5.hasNext())
    114                    {
    115                        Entity var6 = (Entity)var5.next();
    116                        var6.moveEntity((double)(par2 * (float)Facing.offsetsXForSide[this.storedOrientation]), (double)(par2 * (float)Facing.offsetsYForSide[this.storedOrientation]), (double)(par2 * (float)Facing.offsetsZForSide[this.storedOrientation]));
    117                    }
    118
    119                    this.pushedObjects.clear();
    120                }
    121            }
    122        }
    123
    124        @SideOnly(Side.CLIENT)
    125        public float getOffsetX(float par1)
    126        {
    127            return this.extending ? (this.getProgress(par1) - 1.0F) * (float)Facing.offsetsXForSide[this.storedOrientation] : (1.0F - this.getProgress(par1)) * (float)Facing.offsetsXForSide[this.storedOrientation];
    128        }
    129
    130        @SideOnly(Side.CLIENT)
    131        public float getOffsetY(float par1)
    132        {
    133            return this.extending ? (this.getProgress(par1) - 1.0F) * (float)Facing.offsetsYForSide[this.storedOrientation] : (1.0F - this.getProgress(par1)) * (float)Facing.offsetsYForSide[this.storedOrientation];
    134        }
    135
    136        @SideOnly(Side.CLIENT)
    137        public float getOffsetZ(float par1)
    138        {
    139            return this.extending ? (this.getProgress(par1) - 1.0F) * (float)Facing.offsetsZForSide[this.storedOrientation] : (1.0F - this.getProgress(par1)) * (float)Facing.offsetsZForSide[this.storedOrientation];
    140        }
    141
    142        /**
    143         * removes a pistons tile entity (and if the piston is moving, stops it)
    144         */
    145        public void clearPistonTileEntity()
    146        {
    147            if (this.lastProgress < 1.0F && this.worldObj != null)
    148            {
    149                this.lastProgress = this.progress = 1.0F;
    150                this.worldObj.removeBlockTileEntity(this.xCoord, this.yCoord, this.zCoord);
    151                this.invalidate();
    152
    153                if (this.worldObj.getBlockId(this.xCoord, this.yCoord, this.zCoord) == Block.pistonMoving.blockID)
    154                {
    155                    this.worldObj.setBlockAndMetadataWithNotify(this.xCoord, this.yCoord, this.zCoord, this.storedBlockID, this.storedMetadata);
    156                }
    157            }
    158        }
    159
    160        /**
    161         * Allows the entity to update its state. Overridden in most subclasses, e.g. the mob spawner uses this to count
    162         * ticks and creates a new spawn inside its implementation.
    163         */
    164        public void updateEntity()
    165        {
    166            this.lastProgress = this.progress;
    167
    168            if (this.lastProgress >= 1.0F)
    169            {
    170                this.updatePushedObjects(1.0F, 0.25F);
    171                this.worldObj.removeBlockTileEntity(this.xCoord, this.yCoord, this.zCoord);
    172                this.invalidate();
    173
    174                if (this.worldObj.getBlockId(this.xCoord, this.yCoord, this.zCoord) == Block.pistonMoving.blockID)
    175                {
    176                    this.worldObj.setBlockAndMetadataWithNotify(this.xCoord, this.yCoord, this.zCoord, this.storedBlockID, this.storedMetadata);
    177                }
    178            }
    179            else
    180            {
    181                this.progress += 0.5F;
    182
    183                if (this.progress >= 1.0F)
    184                {
    185                    this.progress = 1.0F;
    186                }
    187
    188                if (this.extending)
    189                {
    190                    this.updatePushedObjects(this.progress, this.progress - this.lastProgress + 0.0625F);
    191                }
    192            }
    193        }
    194
    195        /**
    196         * Reads a tile entity from NBT.
    197         */
    198        public void readFromNBT(NBTTagCompound par1NBTTagCompound)
    199        {
    200            super.readFromNBT(par1NBTTagCompound);
    201            this.storedBlockID = par1NBTTagCompound.getInteger("blockId");
    202            this.storedMetadata = par1NBTTagCompound.getInteger("blockData");
    203            this.storedOrientation = par1NBTTagCompound.getInteger("facing");
    204            this.lastProgress = this.progress = par1NBTTagCompound.getFloat("progress");
    205            this.extending = par1NBTTagCompound.getBoolean("extending");
    206        }
    207
    208        /**
    209         * Writes a tile entity to NBT.
    210         */
    211        public void writeToNBT(NBTTagCompound par1NBTTagCompound)
    212        {
    213            super.writeToNBT(par1NBTTagCompound);
    214            par1NBTTagCompound.setInteger("blockId", this.storedBlockID);
    215            par1NBTTagCompound.setInteger("blockData", this.storedMetadata);
    216            par1NBTTagCompound.setInteger("facing", this.storedOrientation);
    217            par1NBTTagCompound.setFloat("progress", this.lastProgress);
    218            par1NBTTagCompound.setBoolean("extending", this.extending);
    219        }
    220    }