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}