001 package net.minecraft.tileentity;
002
003 import cpw.mods.fml.relauncher.Side;
004 import cpw.mods.fml.relauncher.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 }