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