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