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 }