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.List;
006 import java.util.Random;
007
008 public class BlockPistonExtension extends Block
009 {
010 /** The texture for the 'head' of the piston. Sticky or normal. */
011 private int headTexture = -1;
012
013 public BlockPistonExtension(int par1, int par2)
014 {
015 super(par1, par2, Material.piston);
016 this.setStepSound(soundStoneFootstep);
017 this.setHardness(0.5F);
018 }
019
020 @SideOnly(Side.CLIENT)
021 public void setHeadTexture(int par1)
022 {
023 this.headTexture = par1;
024 }
025
026 @SideOnly(Side.CLIENT)
027 public void clearHeadTexture()
028 {
029 this.headTexture = -1;
030 }
031
032 /**
033 * ejects contained items into the world, and notifies neighbours of an update, as appropriate
034 */
035 public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6)
036 {
037 super.breakBlock(par1World, par2, par3, par4, par5, par6);
038 int var7 = Facing.faceToSide[getDirectionMeta(par6)];
039 par2 += Facing.offsetsXForSide[var7];
040 par3 += Facing.offsetsYForSide[var7];
041 par4 += Facing.offsetsZForSide[var7];
042 int var8 = par1World.getBlockId(par2, par3, par4);
043
044 if (var8 == Block.pistonBase.blockID || var8 == Block.pistonStickyBase.blockID)
045 {
046 par6 = par1World.getBlockMetadata(par2, par3, par4);
047
048 if (BlockPistonBase.isExtended(par6))
049 {
050 Block.blocksList[var8].dropBlockAsItem(par1World, par2, par3, par4, par6, 0);
051 par1World.setBlockWithNotify(par2, par3, par4, 0);
052 }
053 }
054 }
055
056 /**
057 * From the specified side and block metadata retrieves the blocks texture. Args: side, metadata
058 */
059 public int getBlockTextureFromSideAndMetadata(int par1, int par2)
060 {
061 int var3 = getDirectionMeta(par2);
062 return par1 == var3 ? (this.headTexture >= 0 ? this.headTexture : ((par2 & 8) != 0 ? this.blockIndexInTexture - 1 : this.blockIndexInTexture)) : (var3 < 6 && par1 == Facing.faceToSide[var3] ? 107 : 108);
063 }
064
065 /**
066 * The type of render function that is called for this block
067 */
068 public int getRenderType()
069 {
070 return 17;
071 }
072
073 /**
074 * Is this block (a) opaque and (b) a full 1m cube? This determines whether or not to render the shared face of two
075 * adjacent blocks and also whether the player can attach torches, redstone wire, etc to this block.
076 */
077 public boolean isOpaqueCube()
078 {
079 return false;
080 }
081
082 /**
083 * If this block doesn't render as an ordinary block it will return False (examples: signs, buttons, stairs, etc)
084 */
085 public boolean renderAsNormalBlock()
086 {
087 return false;
088 }
089
090 /**
091 * Checks to see if its valid to put this block at the specified coordinates. Args: world, x, y, z
092 */
093 public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4)
094 {
095 return false;
096 }
097
098 /**
099 * checks to see if you can place this block can be placed on that side of a block: BlockLever overrides
100 */
101 public boolean canPlaceBlockOnSide(World par1World, int par2, int par3, int par4, int par5)
102 {
103 return false;
104 }
105
106 /**
107 * Returns the quantity of items to drop on block destruction.
108 */
109 public int quantityDropped(Random par1Random)
110 {
111 return 0;
112 }
113
114 /**
115 * if the specified block is in the given AABB, add its collision bounding box to the given list
116 */
117 public void addCollidingBlockToList(World par1World, int par2, int par3, int par4, AxisAlignedBB par5AxisAlignedBB, List par6List, Entity par7Entity)
118 {
119 int var8 = par1World.getBlockMetadata(par2, par3, par4);
120
121 switch (getDirectionMeta(var8))
122 {
123 case 0:
124 this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.25F, 1.0F);
125 super.addCollidingBlockToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity);
126 this.setBlockBounds(0.375F, 0.25F, 0.375F, 0.625F, 1.0F, 0.625F);
127 super.addCollidingBlockToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity);
128 break;
129 case 1:
130 this.setBlockBounds(0.0F, 0.75F, 0.0F, 1.0F, 1.0F, 1.0F);
131 super.addCollidingBlockToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity);
132 this.setBlockBounds(0.375F, 0.0F, 0.375F, 0.625F, 0.75F, 0.625F);
133 super.addCollidingBlockToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity);
134 break;
135 case 2:
136 this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 0.25F);
137 super.addCollidingBlockToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity);
138 this.setBlockBounds(0.25F, 0.375F, 0.25F, 0.75F, 0.625F, 1.0F);
139 super.addCollidingBlockToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity);
140 break;
141 case 3:
142 this.setBlockBounds(0.0F, 0.0F, 0.75F, 1.0F, 1.0F, 1.0F);
143 super.addCollidingBlockToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity);
144 this.setBlockBounds(0.25F, 0.375F, 0.0F, 0.75F, 0.625F, 0.75F);
145 super.addCollidingBlockToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity);
146 break;
147 case 4:
148 this.setBlockBounds(0.0F, 0.0F, 0.0F, 0.25F, 1.0F, 1.0F);
149 super.addCollidingBlockToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity);
150 this.setBlockBounds(0.375F, 0.25F, 0.25F, 0.625F, 0.75F, 1.0F);
151 super.addCollidingBlockToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity);
152 break;
153 case 5:
154 this.setBlockBounds(0.75F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
155 super.addCollidingBlockToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity);
156 this.setBlockBounds(0.0F, 0.375F, 0.25F, 0.75F, 0.625F, 0.75F);
157 super.addCollidingBlockToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity);
158 }
159
160 this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
161 }
162
163 /**
164 * Updates the blocks bounds based on its current state. Args: world, x, y, z
165 */
166 public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4)
167 {
168 int var5 = par1IBlockAccess.getBlockMetadata(par2, par3, par4);
169
170 switch (getDirectionMeta(var5))
171 {
172 case 0:
173 this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.25F, 1.0F);
174 break;
175 case 1:
176 this.setBlockBounds(0.0F, 0.75F, 0.0F, 1.0F, 1.0F, 1.0F);
177 break;
178 case 2:
179 this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 0.25F);
180 break;
181 case 3:
182 this.setBlockBounds(0.0F, 0.0F, 0.75F, 1.0F, 1.0F, 1.0F);
183 break;
184 case 4:
185 this.setBlockBounds(0.0F, 0.0F, 0.0F, 0.25F, 1.0F, 1.0F);
186 break;
187 case 5:
188 this.setBlockBounds(0.75F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
189 }
190 }
191
192 /**
193 * Lets the block know when one of its neighbor changes. Doesn't know which neighbor changed (coordinates passed are
194 * their own) Args: x, y, z, neighbor blockID
195 */
196 public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5)
197 {
198 int var6 = getDirectionMeta(par1World.getBlockMetadata(par2, par3, par4));
199 int var7 = par1World.getBlockId(par2 - Facing.offsetsXForSide[var6], par3 - Facing.offsetsYForSide[var6], par4 - Facing.offsetsZForSide[var6]);
200
201 if (var7 != Block.pistonBase.blockID && var7 != Block.pistonStickyBase.blockID)
202 {
203 par1World.setBlockWithNotify(par2, par3, par4, 0);
204 }
205 else
206 {
207 Block.blocksList[var7].onNeighborBlockChange(par1World, par2 - Facing.offsetsXForSide[var6], par3 - Facing.offsetsYForSide[var6], par4 - Facing.offsetsZForSide[var6], par5);
208 }
209 }
210
211 public static int getDirectionMeta(int par0)
212 {
213 return par0 & 7;
214 }
215
216 @SideOnly(Side.CLIENT)
217
218 /**
219 * only called by clickMiddleMouseButton , and passed to inventory.setCurrentItem (along with isCreative)
220 */
221 public int idPicked(World par1World, int par2, int par3, int par4)
222 {
223 return 0;
224 }
225 }