001    package net.minecraft.src;
002    
003    import net.minecraftforge.common.ForgeDirection;
004    import static net.minecraftforge.common.ForgeDirection.*;
005    
006    public class BlockLever extends Block
007    {
008        protected BlockLever(int par1, int par2)
009        {
010            super(par1, par2, Material.circuits);
011            this.setCreativeTab(CreativeTabs.tabRedstone);
012        }
013    
014        /**
015         * Returns a bounding box from the pool of bounding boxes (this means this box can change after the pool has been
016         * cleared to be reused)
017         */
018        public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4)
019        {
020            return null;
021        }
022    
023        /**
024         * Is this block (a) opaque and (b) a full 1m cube?  This determines whether or not to render the shared face of two
025         * adjacent blocks and also whether the player can attach torches, redstone wire, etc to this block.
026         */
027        public boolean isOpaqueCube()
028        {
029            return false;
030        }
031    
032        /**
033         * If this block doesn't render as an ordinary block it will return False (examples: signs, buttons, stairs, etc)
034         */
035        public boolean renderAsNormalBlock()
036        {
037            return false;
038        }
039    
040        /**
041         * The type of render function that is called for this block
042         */
043        public int getRenderType()
044        {
045            return 12;
046        }
047    
048        /**
049         * checks to see if you can place this block can be placed on that side of a block: BlockLever overrides
050         */
051        public boolean canPlaceBlockOnSide(World par1World, int par2, int par3, int par4, int par5)
052        {
053            ForgeDirection dir = ForgeDirection.getOrientation(par5);
054            return (dir == DOWN  && par1World.isBlockSolidOnSide(par2, par3 + 1, par4, DOWN )) ||
055                   (dir == UP    && par1World.isBlockSolidOnSide(par2, par3 - 1, par4, UP   )) ||
056                   (dir == NORTH && par1World.isBlockSolidOnSide(par2, par3, par4 + 1, NORTH)) ||
057                   (dir == SOUTH && par1World.isBlockSolidOnSide(par2, par3, par4 - 1, SOUTH)) ||
058                   (dir == WEST  && par1World.isBlockSolidOnSide(par2 + 1, par3, par4, WEST )) ||
059                   (dir == EAST  && par1World.isBlockSolidOnSide(par2 - 1, par3, par4, EAST ));
060        }
061    
062        /**
063         * Checks to see if its valid to put this block at the specified coordinates. Args: world, x, y, z
064         */
065        public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4)
066        {
067            return par1World.isBlockSolidOnSide(par2 - 1, par3, par4, EAST ) ||
068                   par1World.isBlockSolidOnSide(par2 + 1, par3, par4, WEST ) ||
069                   par1World.isBlockSolidOnSide(par2, par3, par4 - 1, SOUTH) ||
070                   par1World.isBlockSolidOnSide(par2, par3, par4 + 1, NORTH) ||
071                   par1World.isBlockSolidOnSide(par2, par3 - 1, par4, UP   ) ||
072                   par1World.isBlockSolidOnSide(par2, par3 + 1, par4, DOWN );
073        }
074    
075        /**
076         * called before onBlockPlacedBy by ItemBlock and ItemReed
077         */
078        public void updateBlockMetadata(World par1World, int par2, int par3, int par4, int par5, float par6, float par7, float par8)
079        {
080            int var9 = par1World.getBlockMetadata(par2, par3, par4);
081            int var10 = var9 & 8;
082            var9 &= 7;
083            var9 = -1;
084    
085            if (par5 == 0 && par1World.isBlockSolidOnSide(par2, par3 + 1, par4, DOWN))
086            {
087                var9 = par1World.rand.nextBoolean() ? 0 : 7;
088            }
089    
090            if (par5 == 1 && par1World.isBlockSolidOnSide(par2, par3 - 1, par4, UP))
091            {
092                var9 = 5 + par1World.rand.nextInt(2);
093            }
094    
095            if (par5 == 2 && par1World.isBlockSolidOnSide(par2, par3, par4 + 1, NORTH))
096            {
097                var9 = 4;
098            }
099    
100            if (par5 == 3 && par1World.isBlockSolidOnSide(par2, par3, par4 - 1, SOUTH))
101            {
102                var9 = 3;
103            }
104    
105            if (par5 == 4 && par1World.isBlockSolidOnSide(par2 + 1, par3, par4, WEST))
106            {
107                var9 = 2;
108            }
109    
110            if (par5 == 5 && par1World.isBlockSolidOnSide(par2 - 1, par3, par4, EAST))
111            {
112                var9 = 1;
113            }
114    
115            if (var9 == -1)
116            {
117                this.dropBlockAsItem(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4), 0);
118                par1World.setBlockWithNotify(par2, par3, par4, 0);
119            }
120            else
121            {
122                par1World.setBlockMetadataWithNotify(par2, par3, par4, var9 + var10);
123            }
124        }
125    
126        /**
127         * only used in ComponentScatteredFeatureJunglePyramid.addComponentParts"
128         */
129        public static int invertMetadata(int par0)
130        {
131            switch (par0)
132            {
133                case 0:
134                    return 0;
135                case 1:
136                    return 5;
137                case 2:
138                    return 4;
139                case 3:
140                    return 3;
141                case 4:
142                    return 2;
143                case 5:
144                    return 1;
145                default:
146                    return -1;
147            }
148        }
149    
150        /**
151         * Lets the block know when one of its neighbor changes. Doesn't know which neighbor changed (coordinates passed are
152         * their own) Args: x, y, z, neighbor blockID
153         */
154        public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5)
155        {
156            if (this.checkIfAttachedToBlock(par1World, par2, par3, par4))
157            {
158                int var6 = par1World.getBlockMetadata(par2, par3, par4) & 7;
159                boolean var7 = false;
160    
161                if (!par1World.isBlockSolidOnSide(par2 - 1, par3, par4, EAST) && var6 == 1)
162                {
163                    var7 = true;
164                }
165    
166                if (!par1World.isBlockSolidOnSide(par2 + 1, par3, par4, WEST) && var6 == 2)
167                {
168                    var7 = true;
169                }
170    
171                if (!par1World.isBlockSolidOnSide(par2, par3, par4 - 1, SOUTH) && var6 == 3)
172                {
173                    var7 = true;
174                }
175    
176                if (!par1World.isBlockSolidOnSide(par2, par3, par4 + 1, NORTH) && var6 == 4)
177                {
178                    var7 = true;
179                }
180    
181                if (!par1World.isBlockSolidOnSide(par2, par3 - 1, par4, UP) && var6 == 5)
182                {
183                    var7 = true;
184                }
185    
186                if (!par1World.isBlockSolidOnSide(par2, par3 - 1, par4, UP) && var6 == 6)
187                {
188                    var7 = true;
189                }
190    
191                if (!par1World.isBlockSolidOnSide(par2, par3 + 1, par4, DOWN) && var6 == 0)
192                {
193                    var7 = true;
194                }
195    
196                if (!par1World.isBlockSolidOnSide(par2, par3 + 1, par4, DOWN) && var6 == 7)
197                {
198                    var7 = true;
199                }
200    
201                if (var7)
202                {
203                    this.dropBlockAsItem(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4), 0);
204                    par1World.setBlockWithNotify(par2, par3, par4, 0);
205                }
206            }
207        }
208    
209        /**
210         * Checks if the block is attached to another block. If it is not, it returns false and drops the block as an item.
211         * If it is it returns true.
212         */
213        private boolean checkIfAttachedToBlock(World par1World, int par2, int par3, int par4)
214        {
215            if (!this.canPlaceBlockAt(par1World, par2, par3, par4))
216            {
217                this.dropBlockAsItem(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4), 0);
218                par1World.setBlockWithNotify(par2, par3, par4, 0);
219                return false;
220            }
221            else
222            {
223                return true;
224            }
225        }
226    
227        /**
228         * Updates the blocks bounds based on its current state. Args: world, x, y, z
229         */
230        public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4)
231        {
232            int var5 = par1IBlockAccess.getBlockMetadata(par2, par3, par4) & 7;
233            float var6 = 0.1875F;
234    
235            if (var5 == 1)
236            {
237                this.setBlockBounds(0.0F, 0.2F, 0.5F - var6, var6 * 2.0F, 0.8F, 0.5F + var6);
238            }
239            else if (var5 == 2)
240            {
241                this.setBlockBounds(1.0F - var6 * 2.0F, 0.2F, 0.5F - var6, 1.0F, 0.8F, 0.5F + var6);
242            }
243            else if (var5 == 3)
244            {
245                this.setBlockBounds(0.5F - var6, 0.2F, 0.0F, 0.5F + var6, 0.8F, var6 * 2.0F);
246            }
247            else if (var5 == 4)
248            {
249                this.setBlockBounds(0.5F - var6, 0.2F, 1.0F - var6 * 2.0F, 0.5F + var6, 0.8F, 1.0F);
250            }
251            else if (var5 != 5 && var5 != 6)
252            {
253                if (var5 == 0 || var5 == 7)
254                {
255                    var6 = 0.25F;
256                    this.setBlockBounds(0.5F - var6, 0.4F, 0.5F - var6, 0.5F + var6, 1.0F, 0.5F + var6);
257                }
258            }
259            else
260            {
261                var6 = 0.25F;
262                this.setBlockBounds(0.5F - var6, 0.0F, 0.5F - var6, 0.5F + var6, 0.6F, 0.5F + var6);
263            }
264        }
265    
266        /**
267         * Called when the block is clicked by a player. Args: x, y, z, entityPlayer
268         */
269        public void onBlockClicked(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer)
270        {
271            this.onBlockActivated(par1World, par2, par3, par4, par5EntityPlayer, 0, 0.0F, 0.0F, 0.0F);
272        }
273    
274        /**
275         * Called upon block activation (right click on the block.)
276         */
277        public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9)
278        {
279            if (par1World.isRemote)
280            {
281                return true;
282            }
283            else
284            {
285                int var10 = par1World.getBlockMetadata(par2, par3, par4);
286                int var11 = var10 & 7;
287                int var12 = 8 - (var10 & 8);
288                par1World.setBlockMetadataWithNotify(par2, par3, par4, var11 + var12);
289                par1World.markBlocksDirty(par2, par3, par4, par2, par3, par4);
290                par1World.playSoundEffect((double)par2 + 0.5D, (double)par3 + 0.5D, (double)par4 + 0.5D, "random.click", 0.3F, var12 > 0 ? 0.6F : 0.5F);
291                par1World.notifyBlocksOfNeighborChange(par2, par3, par4, this.blockID);
292    
293                if (var11 == 1)
294                {
295                    par1World.notifyBlocksOfNeighborChange(par2 - 1, par3, par4, this.blockID);
296                }
297                else if (var11 == 2)
298                {
299                    par1World.notifyBlocksOfNeighborChange(par2 + 1, par3, par4, this.blockID);
300                }
301                else if (var11 == 3)
302                {
303                    par1World.notifyBlocksOfNeighborChange(par2, par3, par4 - 1, this.blockID);
304                }
305                else if (var11 == 4)
306                {
307                    par1World.notifyBlocksOfNeighborChange(par2, par3, par4 + 1, this.blockID);
308                }
309                else if (var11 != 5 && var11 != 6)
310                {
311                    if (var11 == 0 || var11 == 7)
312                    {
313                        par1World.notifyBlocksOfNeighborChange(par2, par3 + 1, par4, this.blockID);
314                    }
315                }
316                else
317                {
318                    par1World.notifyBlocksOfNeighborChange(par2, par3 - 1, par4, this.blockID);
319                }
320    
321                return true;
322            }
323        }
324    
325        /**
326         * ejects contained items into the world, and notifies neighbours of an update, as appropriate
327         */
328        public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6)
329        {
330            if ((par6 & 8) > 0)
331            {
332                par1World.notifyBlocksOfNeighborChange(par2, par3, par4, this.blockID);
333                int var7 = par6 & 7;
334    
335                if (var7 == 1)
336                {
337                    par1World.notifyBlocksOfNeighborChange(par2 - 1, par3, par4, this.blockID);
338                }
339                else if (var7 == 2)
340                {
341                    par1World.notifyBlocksOfNeighborChange(par2 + 1, par3, par4, this.blockID);
342                }
343                else if (var7 == 3)
344                {
345                    par1World.notifyBlocksOfNeighborChange(par2, par3, par4 - 1, this.blockID);
346                }
347                else if (var7 == 4)
348                {
349                    par1World.notifyBlocksOfNeighborChange(par2, par3, par4 + 1, this.blockID);
350                }
351                else if (var7 != 5 && var7 != 6)
352                {
353                    if (var7 == 0 || var7 == 7)
354                    {
355                        par1World.notifyBlocksOfNeighborChange(par2, par3 + 1, par4, this.blockID);
356                    }
357                }
358                else
359                {
360                    par1World.notifyBlocksOfNeighborChange(par2, par3 - 1, par4, this.blockID);
361                }
362            }
363    
364            super.breakBlock(par1World, par2, par3, par4, par5, par6);
365        }
366    
367        /**
368         * Is this block powering the block on the specified side
369         */
370        public boolean isPoweringTo(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5)
371        {
372            return (par1IBlockAccess.getBlockMetadata(par2, par3, par4) & 8) > 0;
373        }
374    
375        /**
376         * Is this block indirectly powering the block on the specified side
377         */
378        public boolean isIndirectlyPoweringTo(World par1World, int par2, int par3, int par4, int par5)
379        {
380            int var6 = par1World.getBlockMetadata(par2, par3, par4);
381    
382            if ((var6 & 8) == 0)
383            {
384                return false;
385            }
386            else
387            {
388                int var7 = var6 & 7;
389                return var7 == 0 && par5 == 0 ? true : (var7 == 7 && par5 == 0 ? true : (var7 == 6 && par5 == 1 ? true : (var7 == 5 && par5 == 1 ? true : (var7 == 4 && par5 == 2 ? true : (var7 == 3 && par5 == 3 ? true : (var7 == 2 && par5 == 4 ? true : var7 == 1 && par5 == 5))))));
390            }
391        }
392    
393        /**
394         * Can this block provide power. Only wire currently seems to have this change based on its state.
395         */
396        public boolean canProvidePower()
397        {
398            return true;
399        }
400    }