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