    001package net.minecraft.block;
    002
    003import cpw.mods.fml.relauncher.Side;
    004import cpw.mods.fml.relauncher.SideOnly;
    005import java.util.Random;
    006import net.minecraft.block.material.Material;
    007import net.minecraft.entity.Entity;
    008import net.minecraft.item.ItemMonsterPlacer;
    009import net.minecraft.util.AxisAlignedBB;
    010import net.minecraft.world.IBlockAccess;
    011import net.minecraft.world.World;
    012
    013public 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, false);
    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}