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 }