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