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.Random;
006    
007    public class BlockPortal extends BlockBreakable
008    {
009        public BlockPortal(int par1, int par2)
010        {
011            super(par1, par2, Material.portal, false);
012            this.setTickRandomly(true);
013        }
014    
015        /**
016         * Ticks the block if it's been scheduled
017         */
018        public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random)
019        {
020            super.updateTick(par1World, par2, par3, par4, par5Random);
021    
022            if (par1World.provider.isSurfaceWorld() && par5Random.nextInt(2000) < par1World.difficultySetting)
023            {
024                int var6;
025    
026                for (var6 = par3; !par1World.doesBlockHaveSolidTopSurface(par2, var6, par4) && var6 > 0; --var6)
027                {
028                    ;
029                }
030    
031                if (var6 > 0 && !par1World.isBlockNormalCube(par2, var6 + 1, par4))
032                {
033                    ItemMonsterPlacer.spawnCreature(par1World, 57, (double)par2 + 0.5D, (double)var6 + 1.1D, (double)par4 + 0.5D);
034                }
035            }
036        }
037    
038        /**
039         * Returns a bounding box from the pool of bounding boxes (this means this box can change after the pool has been
040         * cleared to be reused)
041         */
042        public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4)
043        {
044            return null;
045        }
046    
047        /**
048         * Updates the blocks bounds based on its current state. Args: world, x, y, z
049         */
050        public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4)
051        {
052            float var5;
053            float var6;
054    
055            if (par1IBlockAccess.getBlockId(par2 - 1, par3, par4) != this.blockID && par1IBlockAccess.getBlockId(par2 + 1, par3, par4) != this.blockID)
056            {
057                var5 = 0.125F;
058                var6 = 0.5F;
059                this.setBlockBounds(0.5F - var5, 0.0F, 0.5F - var6, 0.5F + var5, 1.0F, 0.5F + var6);
060            }
061            else
062            {
063                var5 = 0.5F;
064                var6 = 0.125F;
065                this.setBlockBounds(0.5F - var5, 0.0F, 0.5F - var6, 0.5F + var5, 1.0F, 0.5F + var6);
066            }
067        }
068    
069        /**
070         * Is this block (a) opaque and (b) a full 1m cube?  This determines whether or not to render the shared face of two
071         * adjacent blocks and also whether the player can attach torches, redstone wire, etc to this block.
072         */
073        public boolean isOpaqueCube()
074        {
075            return false;
076        }
077    
078        /**
079         * If this block doesn't render as an ordinary block it will return False (examples: signs, buttons, stairs, etc)
080         */
081        public boolean renderAsNormalBlock()
082        {
083            return false;
084        }
085    
086        /**
087         * Checks to see if this location is valid to create a portal and will return True if it does. Args: world, x, y, z
088         */
089        public boolean tryToCreatePortal(World par1World, int par2, int par3, int par4)
090        {
091            byte var5 = 0;
092            byte var6 = 0;
093    
094            if (par1World.getBlockId(par2 - 1, par3, par4) == Block.obsidian.blockID || par1World.getBlockId(par2 + 1, par3, par4) == Block.obsidian.blockID)
095            {
096                var5 = 1;
097            }
098    
099            if (par1World.getBlockId(par2, par3, par4 - 1) == Block.obsidian.blockID || par1World.getBlockId(par2, par3, par4 + 1) == Block.obsidian.blockID)
100            {
101                var6 = 1;
102            }
103    
104            if (var5 == var6)
105            {
106                return false;
107            }
108            else
109            {
110                if (par1World.getBlockId(par2 - var5, par3, par4 - var6) == 0)
111                {
112                    par2 -= var5;
113                    par4 -= var6;
114                }
115    
116                int var7;
117                int var8;
118    
119                for (var7 = -1; var7 <= 2; ++var7)
120                {
121                    for (var8 = -1; var8 <= 3; ++var8)
122                    {
123                        boolean var9 = var7 == -1 || var7 == 2 || var8 == -1 || var8 == 3;
124    
125                        if (var7 != -1 && var7 != 2 || var8 != -1 && var8 != 3)
126                        {
127                            int var10 = par1World.getBlockId(par2 + var5 * var7, par3 + var8, par4 + var6 * var7);
128    
129                            if (var9)
130                            {
131                                if (var10 != Block.obsidian.blockID)
132                                {
133                                    return false;
134                                }
135                            }
136                            else if (var10 != 0 && var10 != Block.fire.blockID)
137                            {
138                                return false;
139                            }
140                        }
141                    }
142                }
143    
144                par1World.editingBlocks = true;
145    
146                for (var7 = 0; var7 < 2; ++var7)
147                {
148                    for (var8 = 0; var8 < 3; ++var8)
149                    {
150                        par1World.setBlockWithNotify(par2 + var5 * var7, par3 + var8, par4 + var6 * var7, Block.portal.blockID);
151                    }
152                }
153    
154                par1World.editingBlocks = false;
155                return true;
156            }
157        }
158    
159        /**
160         * Lets the block know when one of its neighbor changes. Doesn't know which neighbor changed (coordinates passed are
161         * their own) Args: x, y, z, neighbor blockID
162         */
163        public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5)
164        {
165            byte var6 = 0;
166            byte var7 = 1;
167    
168            if (par1World.getBlockId(par2 - 1, par3, par4) == this.blockID || par1World.getBlockId(par2 + 1, par3, par4) == this.blockID)
169            {
170                var6 = 1;
171                var7 = 0;
172            }
173    
174            int var8;
175    
176            for (var8 = par3; par1World.getBlockId(par2, var8 - 1, par4) == this.blockID; --var8)
177            {
178                ;
179            }
180    
181            if (par1World.getBlockId(par2, var8 - 1, par4) != Block.obsidian.blockID)
182            {
183                par1World.setBlockWithNotify(par2, par3, par4, 0);
184            }
185            else
186            {
187                int var9;
188    
189                for (var9 = 1; var9 < 4 && par1World.getBlockId(par2, var8 + var9, par4) == this.blockID; ++var9)
190                {
191                    ;
192                }
193    
194                if (var9 == 3 && par1World.getBlockId(par2, var8 + var9, par4) == Block.obsidian.blockID)
195                {
196                    boolean var10 = par1World.getBlockId(par2 - 1, par3, par4) == this.blockID || par1World.getBlockId(par2 + 1, par3, par4) == this.blockID;
197                    boolean var11 = par1World.getBlockId(par2, par3, par4 - 1) == this.blockID || par1World.getBlockId(par2, par3, par4 + 1) == this.blockID;
198    
199                    if (var10 && var11)
200                    {
201                        par1World.setBlockWithNotify(par2, par3, par4, 0);
202                    }
203                    else
204                    {
205                        if ((par1World.getBlockId(par2 + var6, par3, par4 + var7) != Block.obsidian.blockID || par1World.getBlockId(par2 - var6, par3, par4 - var7) != this.blockID) && (par1World.getBlockId(par2 - var6, par3, par4 - var7) != Block.obsidian.blockID || par1World.getBlockId(par2 + var6, par3, par4 + var7) != this.blockID))
206                        {
207                            par1World.setBlockWithNotify(par2, par3, par4, 0);
208                        }
209                    }
210                }
211                else
212                {
213                    par1World.setBlockWithNotify(par2, par3, par4, 0);
214                }
215            }
216        }
217    
218        /**
219         * Returns the quantity of items to drop on block destruction.
220         */
221        public int quantityDropped(Random par1Random)
222        {
223            return 0;
224        }
225    
226        /**
227         * Triggered whenever an entity collides with this block (enters into the block). Args: world, x, y, z, entity
228         */
229        public void onEntityCollidedWithBlock(World par1World, int par2, int par3, int par4, Entity par5Entity)
230        {
231            if (par5Entity.ridingEntity == null && par5Entity.riddenByEntity == null)
232            {
233                par5Entity.setInPortal();
234            }
235        }
236    
237        @SideOnly(Side.CLIENT)
238    
239        /**
240         * Returns true if the given side of this block type should be rendered, if the adjacent block is at the given
241         * coordinates.  Args: blockAccess, x, y, z, side
242         */
243        public boolean shouldSideBeRendered(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5)
244        {
245            if (par1IBlockAccess.getBlockId(par2, par3, par4) == this.blockID)
246            {
247                return false;
248            }
249            else
250            {
251                boolean var6 = par1IBlockAccess.getBlockId(par2 - 1, par3, par4) == this.blockID && par1IBlockAccess.getBlockId(par2 - 2, par3, par4) != this.blockID;
252                boolean var7 = par1IBlockAccess.getBlockId(par2 + 1, par3, par4) == this.blockID && par1IBlockAccess.getBlockId(par2 + 2, par3, par4) != this.blockID;
253                boolean var8 = par1IBlockAccess.getBlockId(par2, par3, par4 - 1) == this.blockID && par1IBlockAccess.getBlockId(par2, par3, par4 - 2) != this.blockID;
254                boolean var9 = par1IBlockAccess.getBlockId(par2, par3, par4 + 1) == this.blockID && par1IBlockAccess.getBlockId(par2, par3, par4 + 2) != this.blockID;
255                boolean var10 = var6 || var7;
256                boolean var11 = var8 || var9;
257                return var10 && par5 == 4 ? true : (var10 && par5 == 5 ? true : (var11 && par5 == 2 ? true : var11 && par5 == 3));
258            }
259        }
260    
261        @SideOnly(Side.CLIENT)
262    
263        /**
264         * Returns which pass should this block be rendered on. 0 for solids and 1 for alpha
265         */
266        public int getRenderBlockPass()
267        {
268            return 1;
269        }
270    
271        @SideOnly(Side.CLIENT)
272    
273        /**
274         * A randomly called display update to be able to add particles or other items for display
275         */
276        public void randomDisplayTick(World par1World, int par2, int par3, int par4, Random par5Random)
277        {
278            if (par5Random.nextInt(100) == 0)
279            {
280                par1World.playSound((double)par2 + 0.5D, (double)par3 + 0.5D, (double)par4 + 0.5D, "portal.portal", 0.5F, par5Random.nextFloat() * 0.4F + 0.8F);
281            }
282    
283            for (int var6 = 0; var6 < 4; ++var6)
284            {
285                double var7 = (double)((float)par2 + par5Random.nextFloat());
286                double var9 = (double)((float)par3 + par5Random.nextFloat());
287                double var11 = (double)((float)par4 + par5Random.nextFloat());
288                double var13 = 0.0D;
289                double var15 = 0.0D;
290                double var17 = 0.0D;
291                int var19 = par5Random.nextInt(2) * 2 - 1;
292                var13 = ((double)par5Random.nextFloat() - 0.5D) * 0.5D;
293                var15 = ((double)par5Random.nextFloat() - 0.5D) * 0.5D;
294                var17 = ((double)par5Random.nextFloat() - 0.5D) * 0.5D;
295    
296                if (par1World.getBlockId(par2 - 1, par3, par4) != this.blockID && par1World.getBlockId(par2 + 1, par3, par4) != this.blockID)
297                {
298                    var7 = (double)par2 + 0.5D + 0.25D * (double)var19;
299                    var13 = (double)(par5Random.nextFloat() * 2.0F * (float)var19);
300                }
301                else
302                {
303                    var11 = (double)par4 + 0.5D + 0.25D * (double)var19;
304                    var17 = (double)(par5Random.nextFloat() * 2.0F * (float)var19);
305                }
306    
307                par1World.spawnParticle("portal", var7, var9, var11, var13, var15, var17);
308            }
309        }
310    
311        @SideOnly(Side.CLIENT)
312    
313        /**
314         * only called by clickMiddleMouseButton , and passed to inventory.setCurrentItem (along with isCreative)
315         */
316        public int idPicked(World par1World, int par2, int par3, int par4)
317        {
318            return 0;
319        }
320    }