package net.minecraft.tileentity; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import net.minecraft.block.Block; import net.minecraft.entity.Entity; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.Facing; public class TileEntityPiston extends TileEntity { private int storedBlockID; private int storedMetadata; /** the side the front of the piston is on */ private int storedOrientation; /** if this piston is extending or not */ private boolean extending; private boolean shouldHeadBeRendered; private float progress; /** the progress in (de)extending */ private float lastProgress; private List pushedObjects = new ArrayList(); public TileEntityPiston() {} public TileEntityPiston(int par1, int par2, int par3, boolean par4, boolean par5) { this.storedBlockID = par1; this.storedMetadata = par2; this.storedOrientation = par3; this.extending = par4; this.shouldHeadBeRendered = par5; } public int getStoredBlockID() { return this.storedBlockID; } /** * Returns block data at the location of this entity (client-only). */ public int getBlockMetadata() { return this.storedMetadata; } /** * Returns true if a piston is extending */ public boolean isExtending() { return this.extending; } /** * Returns the orientation of the piston as an int */ public int getPistonOrientation() { return this.storedOrientation; } @SideOnly(Side.CLIENT) public boolean shouldRenderHead() { return this.shouldHeadBeRendered; } /** * Get interpolated progress value (between lastProgress and progress) given the fractional time between ticks as an * argument. */ public float getProgress(float par1) { if (par1 > 1.0F) { par1 = 1.0F; } return this.lastProgress + (this.progress - this.lastProgress) * par1; } private void updatePushedObjects(float par1, float par2) { if (this.extending) { par1 = 1.0F - par1; } else { --par1; } AxisAlignedBB var3 = Block.pistonMoving.getAxisAlignedBB(this.worldObj, this.xCoord, this.yCoord, this.zCoord, this.storedBlockID, par1, this.storedOrientation); if (var3 != null) { List var4 = this.worldObj.getEntitiesWithinAABBExcludingEntity((Entity)null, var3); if (!var4.isEmpty()) { this.pushedObjects.addAll(var4); Iterator var5 = this.pushedObjects.iterator(); while (var5.hasNext()) { Entity var6 = (Entity)var5.next(); var6.moveEntity((double)(par2 * (float)Facing.offsetsXForSide[this.storedOrientation]), (double)(par2 * (float)Facing.offsetsYForSide[this.storedOrientation]), (double)(par2 * (float)Facing.offsetsZForSide[this.storedOrientation])); } this.pushedObjects.clear(); } } } @SideOnly(Side.CLIENT) public float getOffsetX(float par1) { return this.extending ? (this.getProgress(par1) - 1.0F) * (float)Facing.offsetsXForSide[this.storedOrientation] : (1.0F - this.getProgress(par1)) * (float)Facing.offsetsXForSide[this.storedOrientation]; } @SideOnly(Side.CLIENT) public float getOffsetY(float par1) { return this.extending ? (this.getProgress(par1) - 1.0F) * (float)Facing.offsetsYForSide[this.storedOrientation] : (1.0F - this.getProgress(par1)) * (float)Facing.offsetsYForSide[this.storedOrientation]; } @SideOnly(Side.CLIENT) public float getOffsetZ(float par1) { return this.extending ? (this.getProgress(par1) - 1.0F) * (float)Facing.offsetsZForSide[this.storedOrientation] : (1.0F - this.getProgress(par1)) * (float)Facing.offsetsZForSide[this.storedOrientation]; } /** * removes a pistons tile entity (and if the piston is moving, stops it) */ public void clearPistonTileEntity() { if (this.lastProgress < 1.0F && this.worldObj != null) { this.lastProgress = this.progress = 1.0F; this.worldObj.removeBlockTileEntity(this.xCoord, this.yCoord, this.zCoord); this.invalidate(); if (this.worldObj.getBlockId(this.xCoord, this.yCoord, this.zCoord) == Block.pistonMoving.blockID) { this.worldObj.setBlockAndMetadataWithNotify(this.xCoord, this.yCoord, this.zCoord, this.storedBlockID, this.storedMetadata); } } } /** * Allows the entity to update its state. Overridden in most subclasses, e.g. the mob spawner uses this to count * ticks and creates a new spawn inside its implementation. */ public void updateEntity() { this.lastProgress = this.progress; if (this.lastProgress >= 1.0F) { this.updatePushedObjects(1.0F, 0.25F); this.worldObj.removeBlockTileEntity(this.xCoord, this.yCoord, this.zCoord); this.invalidate(); if (this.worldObj.getBlockId(this.xCoord, this.yCoord, this.zCoord) == Block.pistonMoving.blockID) { this.worldObj.setBlockAndMetadataWithNotify(this.xCoord, this.yCoord, this.zCoord, this.storedBlockID, this.storedMetadata); } } else { this.progress += 0.5F; if (this.progress >= 1.0F) { this.progress = 1.0F; } if (this.extending) { this.updatePushedObjects(this.progress, this.progress - this.lastProgress + 0.0625F); } } } /** * Reads a tile entity from NBT. */ public void readFromNBT(NBTTagCompound par1NBTTagCompound) { super.readFromNBT(par1NBTTagCompound); this.storedBlockID = par1NBTTagCompound.getInteger("blockId"); this.storedMetadata = par1NBTTagCompound.getInteger("blockData"); this.storedOrientation = par1NBTTagCompound.getInteger("facing"); this.lastProgress = this.progress = par1NBTTagCompound.getFloat("progress"); this.extending = par1NBTTagCompound.getBoolean("extending"); } /** * Writes a tile entity to NBT. */ public void writeToNBT(NBTTagCompound par1NBTTagCompound) { super.writeToNBT(par1NBTTagCompound); par1NBTTagCompound.setInteger("blockId", this.storedBlockID); par1NBTTagCompound.setInteger("blockData", this.storedMetadata); par1NBTTagCompound.setInteger("facing", this.storedOrientation); par1NBTTagCompound.setFloat("progress", this.lastProgress); par1NBTTagCompound.setBoolean("extending", this.extending); } }